- Isolate tectonic compilation in subprocess to prevent font cache
assertion crash on retry (fixes#67)
- Fix unreachable pattern warning in lib.rs by merging duplicate
WindowEvent::Focused match arms
- Add editor shortcuts: Cmd+B (bold), Cmd+I (italic), Cmd+/ (comment)
- Add Tab/Shift-Tab indent support in CodeMirror editor
- Fix WebKit rendering artifacts with translateZ(0) on .cm-scroller
- Force recompile on button click and Cmd+Enter (skip generation check)
- Add minimum 500ms compile spinner for visual feedback
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add sanitize_appimage_env() to restore original LD_LIBRARY_PATH/PATH
when spawning child processes from AppImage (fixes xdg-open, curl)
- Pass DISPLAY, WAYLAND_DISPLAY, XDG_*, DBUS_SESSION_BUS_ADDRESS to
child processes for Linux desktop integration
- Add stdin(Stdio::null()) to install_claude_cli to prevent interactive
prompt hangs
- Add 120s timeout to login_claude to prevent indefinite hang when
browser fails to open
- Show "Setup Guide" link to code.claude.com/docs/quickstart on login
failure
- Keep releases as draft in CI workflow for manual publish
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add dual workaround for WKWebView failing to repaint after returning
from background (1px resize nudge + DOM reflow)
- Use version-free download links in landing page
- Resolve app version dynamically from Tauri in sidebar
- Bump version to 1.0.5
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Debug panel is now a separate Tauri window (survives main window
black screen) opened via Cmd+Shift+D or open_debug_window command
- Cross-window log bridging via Tauri events: main window emits
entries, debug window receives them + bulk sync on open
- Log store uses mutable ring buffer + version counter instead of
array spread per log; caches localStorage debug flag
- Debounce app-visibility-restored (200ms) to coalesce duplicate
visibilitychange + Tauri Focused events
- Single getImageData(2x2) call in isCanvasBlank instead of 3x 1x1
- Extract shared getGpuRenderer (cached), SystemInfo type,
getVisibilityLogs into log-store.ts
- Event name constants (APP_VISIBILITY_RESTORED)
- Remove debug UI from error-fallback.tsx and App.tsx
- Fix misplaced import in document-store.ts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add visibility/focus recovery to prevent black screen when returning
from another app. When macOS reclaims GPU/WebView resources during app
switching, canvas contexts are silently invalidated. This adds:
- visibilitychange + Tauri Focused event listeners in main.tsx
- Canvas blank detection and auto-re-render in mupdf-page.tsx
- IntersectionObserver reconnection via focusGen in pdf-viewer.tsx
- MuPDF worker error recovery and resetMupdfClient() in mupdf-client.ts
- Cmd+Shift+D debug panel keyboard shortcut
- lib.rs: #[allow(unused_mut)] on builder (mut only needed on macOS)
- claude.rs: move CommandExt import to module level with #[cfg(windows)]
- claude.rs: #[allow(unused_variables)] on home (used only on Unix)
- claude.rs: add #[cfg(not(windows))] to Unix-only dir helper functions
- uv.rs: move CommandExt import to module level with #[cfg(windows)]
- skills.rs: fix unreachable Ok(()) after #[cfg] return branches
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add tauri-plugin-updater with signed update artifacts
- Add backgroundThrottling: disabled to prevent WKWebView black screen
- Add update check UI with toast notifications (sonner)
- Update build scripts to generate latest.json for GitHub Releases
- Add multi-platform CI workflow (macOS/Linux/Windows) with draft releases
- Bump version to 1.0.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Changes missed from PR #37 squash merge:
- Set --titlebar-height to 32px on Windows (was 0px, content hidden
behind native overlay titlebar)
- Add ExecutionPolicy Bypass to PowerShell installers (uv + Claude Code)
- Add ~/.local/bin/uv.exe to Windows uv binary search paths
- PDF toolbar: Export/History as icon-only buttons, Capture & Ask text
hidden on narrow panels via container query
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Setting the dock icon in setup() caused SIGBUS on first launch from
signed release binaries due to Gatekeeper App Translocation interfering
with ImageIO plugin initialization.
Moved set_macos_app_icon() to RunEvent::Ready, which fires after the
app is fully initialized — matching Tauri's own approach for dev icons.
Closes#38
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Windows users without Git for Windows see "Install Claude Code" loop
because Claude Code requires git-bash but the app never checks for it.
Now check_claude_status reports missing_git on Windows, and the setup UI
shows a dedicated "Git for Windows Required" screen with a download link
and re-check button.
Also adds Windows-essential env vars to uv installer and improves the
CI workflow to support manual release_tag input.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add CREATE_NO_WINDOW flag to all child process spawns on Windows to
prevent blank console windows from flashing (claude.rs: 4 sites,
uv.rs: 5 sites)
- Fix claude.exe detection: native installer path check now uses .exe
extension on Windows (~/.local/bin/claude.exe)
- Fix PATH separator in install_claude_cli: use ";" on Windows instead
of hardcoded ":"
- Add strip_ansi() to filter terminal escape sequences ([?2026h] etc.)
from install/login output streamed to the frontend UI
- Fix slash_commands.rs path splitting to handle Windows backslashes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Resolve git merge conflict markers in latex-editor.tsx compileRef
- Use setTimeout for pending recompile to prevent unbounded call stack recursion
- Add clearPdfBytesCache() in test beforeEach for proper test isolation
- Use existing `state` variable instead of redundant getState() calls
- Log when strip_nul actually strips nul bytes for diagnostics
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three interconnected issues caused degraded UX:
1. **White-screen crash**: Large PDF `Uint8Array` buffers (often 5-20MB) stored
directly in Zustand state caused React to diff them on every render. This
triggered excessive memory pressure and eventual WebView white-screen crashes,
especially with multi-root projects keeping a `pdfCache` Map in state.
2. **"nul byte found in provided data" spawn error**: Clipboard artifacts or
encoding issues could introduce interior nul bytes into Claude CLI arguments,
causing `Command::spawn()` to fail on macOS/Linux (which use C strings
internally).
3. **Silently dropped recompiles**: When a compile was requested while another
was already running (`isCompiling === true`), the request was silently
discarded. This meant edits made during compilation never triggered a
follow-up compile.
- Replaced `pdfData: Uint8Array | null` and `pdfCache: Map<string, Uint8Array>`
in Zustand with an external module-level `_pdfBytesCache` Map.
- Added a `pdfRevision` counter in state that increments whenever PDF bytes
change, triggering React re-renders without diffing the actual buffer.
- Exposed `getPdfBytes()`, `getCurrentPdfBytes()`, `hasPdfData()`, and
`clearPdfBytesCache()` as direct accessors for components.
- Added `migratePdfBytesKey()` helper to deduplicate cache re-keying logic
used by `renameFile` and `moveFile`.
- Conditional `pdfRevision` bumping in `setActiveFile` — only bumps when the
PDF root actually changes, avoiding unnecessary re-renders on tab switches
within the same root.
- `setPdfData(null)` no longer copies `compileErrorCache`/`lastCompiledGenerations`
Maps since it doesn't need to modify them.
- Added `strip_nul()` using `Cow<str>` for zero-allocation fast path when no
nul bytes are present (the common case).
- Applied to program, args, cwd, and inherited PATH in `create_command()`.
- Added structured error logging on spawn failure with tab ID for debugging.
- Added `pendingRecompile` boolean to document store.
- When `isCompiling` is true and a compile is requested, sets
`pendingRecompile = true` instead of silently returning.
- After compilation finishes (in `finally` block), checks `pendingRecompile`
and triggers a follow-up compile if queued.
- Applied consistently in latex-editor, pdf-preview, and use-claude-events.
- Added `js_log` IPC command for frontend → stderr logging that survives
white-screen crashes.
- Added PDF size logging in `compile_latex` for monitoring.
- Updated test state shape (`pdfRevision` instead of `pdfData`, added
`pendingRecompile`).
- Fixed `setActiveFile` test: cursor position is preserved (editor manages
per-file cursor cache), not reset to 0.
- Updated `setPdfData` test to use `getCurrentPdfBytes()` accessor.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On Windows, claude.cmd is an npm wrapper that breaks when arguments
contain special characters (quotes, &, |, etc.) because cmd.exe
interprets them. Instead, resolve the .cmd to the underlying
node_modules/@anthropic-ai/claude-code/cli.js and invoke node directly.
This fixes "batch file arguments are invalid" errors on Windows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
resolveCompileTarget now returns null when no .tex file exists in the
project, instead of falling back to a hardcoded "document.tex" path.
All 4 call sites (editor, pdf-preview, claude-events) check for null
and show a descriptive error. Rust backend also validates file existence
before attempting Tectonic compilation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dropbox/iCloud can keep files as online-only placeholders with 0 bytes
on disk. When sync_source_files copies these, the build dir gets empty
files, causing 'Unable to load picture or PDF file' errors.
Force-read 0-byte files to trigger cloud download before copying.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added fuzzy search functionality to improve command matching and scoring.
- Introduced a new tab for skills in the slash command picker.
- Implemented a preview panel for skills, displaying detailed content.
- Updated command icons to include new skill-related icons.
- Refactored command filtering and sorting logic to accommodate new features.
- Created comprehensive tests for fuzzy search scoring and command ranking.
- Updated Tectonic build configuration for local macOS development.
- Modified git2 dependency to use vendored-libgit2 feature.
- Improved the `find_claude_binary` function to check for native installation paths first.
- Added functions to ensure required directories for Claude are created and writable, with elevation handling on macOS.
- Updated `install_claude_cli` to ensure necessary directories exist before installation.
- Refactored scientific skills installation to include directory permission checks and logging.
- Enhanced error handling and logging during installation processes.
- Improved UI components for displaying installation progress and logs.
- Added tests for new directory handling functions and installation logic.
- Updated LaTeX template for poster presentation with improved formatting and content.
- Implemented image cropping feature in ImagePreview component with interactive selection and resizing handles.
- Added crop mode toggle in EditorToolbar for image files.
- Enhanced PDF rendering by fetching all page sizes in one call instead of individually.
- Optimized image rendering using createImageBitmap to improve performance.
- Introduced content generation tracking in document store to prevent unnecessary recompiles.
- Updated various components to support new cropping functionality and improved user experience.
- Implemented UvSetupDialog component for managing Python virtual environments.
- Added state management for uv installation status using zustand.
- Integrated event listeners for installation completion and status checking.
- Enhanced ImagePreview component with pinch-to-zoom and keyboard shortcuts for scaling.
- Updated LatexEditor to reset image scale when switching files.
- Created EnvironmentSection in Sidebar for displaying Python and skills status.
- Added scientific report template to template registry.
- Refactored PDF loading to improve performance and user experience.
- Added ChatTabBar component for managing multiple chat tabs.
- Integrated tab switching functionality with keyboard shortcuts (Ctrl+Tab, Ctrl+T, Ctrl+W).
- Enhanced ChatComposer to save and restore drafts based on active tab.
- Updated ClaudeChatDrawer to include ChatTabBar and manage streaming state across tabs.
- Refactored useClaudeEvents to handle events per tab, allowing concurrent streaming.
- Modified ClaudeChatStore to support tab-specific state management, including creating, closing, and switching tabs.
Set up Vitest with jsdom environment and Tauri mocks for frontend testing.
Add 44 frontend tests covering Zustand stores (claude-chat, project, proposed-changes,
template) and lib utilities (template-registry, file type classification).
Add 48 Rust unit tests across zotero (OAuth helpers), slash_commands (markdown parsing),
latex (error extraction, SyncTeX parsing), and claude (session dir encoding, message
title cleaning). Update README with test commands.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added Tectonic as a dependency for LaTeX compilation in Cargo.toml.
- Created Entitlements.plist for macOS app sandboxing and security permissions.
- Refactored latex.rs to utilize Tectonic for PDF generation, removing legacy compilation logic.
- Updated compile_latex function to handle Tectonic's processing and error handling.
- Enhanced synctex editing functionality to read and parse synctex data correctly.
- Modified project-wizard and template-preview components to improve project creation prompts.
- Adjusted tauri.conf.json to include entitlements for macOS and set minimum system version.
- Cleaned up unused code and improved overall code readability and maintainability.
- Remove OpenSSL dependency by disabling git2 default features (only local ops needed)
- Remove non-existent hidden_title() call from WebviewWindowBuilder
- Upgrade tauri-action v0 → v1 for artifact detection fixes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Implement slash command system with Rust backend (YAML frontmatter parsing)
and React picker UI for project/user-scoped commands
- Add model selector (Sonnet/Opus/Haiku/OpusPlan) and effort level control
(Low/Medium/High) to chat composer
- Extract common Claude CLI args and add configurable effort level support
- Add per-project compilation locks to prevent concurrent LaTeX builds
- Fix empty document compilation with \AtEndDocument{\null} injection
- Improve chat UX with smooth auto-scroll and updated placeholder
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Simplified environment variable handling in `create_command` to prevent nested session detection.
- Improved logging in `spawn_claude_process` for better debugging of stdout and stderr streams.
- Updated `execute_claude_code`, `continue_claude_code`, and `resume_claude_code` to accept optional model parameters.
- Introduced a new `ThinkingWidget` to display thinking status in chat messages.
- Enhanced `ChatMessages` component to manage auto-scrolling behavior and display streaming indicators.
- Updated `useClaudeEvents` to maintain session-specific state and improve message handling.
- Added keyboard shortcut for toggling capture mode (Cmd+X / Ctrl+X).
- Modified `ContentBlock` interface to include new "thinking" message type.
- Improved error handling and logging throughout the Claude chat store.
- Added ProjectWizard component to guide users through project creation.
- Integrated template selection with predefined LaTeX templates.
- Implemented folder selection and file creation logic for new projects.
- Updated ProjectPicker to launch the ProjectWizard instead of direct project creation.
- Enhanced user experience with improved UI elements and tooltips.
- Added keyboard shortcut for creating new windows.
- Updated global styles for macOS titlebar compatibility.
- Refactored existing components for better structure and maintainability.
- Added dnd-kit for drag-and-drop interactions in the sidebar.
- Integrated native OS file drop handling using Tauri's onDragDropEvent.
- Enhanced file and folder movement logic to support drag-and-drop.
- Updated sidebar to display active drag items with a drag overlay.
- Introduced Droppable components for root and folder targets.
- Improved file type handling to include PDF files.
- Added unique filename generation for imported files to avoid conflicts.
- Implemented history snapshots before and after Claude edits.
- Created a new history store for managing snapshots and diffs.
- Updated document store to support file and folder movement.
- Added ZoteroPanel and ZoteroHeader components for managing Zotero collections.
- Implemented OAuth and API key authentication for Zotero integration.
- Created a new store (zotero-store) to manage Zotero state and sync collections.
- Introduced functions for fetching collections, importing, and syncing data with Zotero API.
- Refactored Sidebar component to include resizable sections for Files, Outline, and Zotero.
- Enhanced document-store to handle .bib file creation and updates based on Zotero data.
- Added utility functions for API interactions and data parsing.
- Added `useProposedChangesStore` to track changes made by Claude.
- Integrated proposed change registration in `useClaudeEvents` for LaTeX file modifications.
- Updated `handleComplete` to refresh files and auto-recompile if LaTeX files were modified.
- Enhanced `document-store` to support folder creation and file import functionality.
- Improved file type detection in `fs.ts` to include style files and ignore LaTeX build artifacts.
- Created a new `synctexEdit` function in `latex-compiler.ts` for synchronization with LaTeX edits.
- Updated project overview documentation to reflect new features and architecture.
- Removed outdated assistant UI components and dependencies from package.json and pnpm-lock.yaml.
- Introduced new Claude chat components including ChatComposer, ChatMessages, and ClaudeChatDrawer for enhanced user interaction.
- Updated App component to utilize the new Claude chat functionality, replacing the previous assistant UI.
- Added markdown rendering capabilities for chat messages and tool widgets to improve content display.
- Enhanced the overall structure and organization of the chat-related components for better maintainability.
- Updated package.json to modify the development script for the desktop application.
- Added a loading screen in index.html with CSS for better user experience during app initialization.
- Enhanced the App component to trigger a callback when the app is ready, allowing the loading screen to be hidden.
- Integrated sidecar management in the Tauri application to handle development and production environments.
- Introduced new icons and configuration files for the Tauri setup, including capability schemas and permissions.
- Added a check for port availability in the desktop-sidecar to prevent conflicts during startup.
- Updated package.json to include new filters for development scripts and added built dependencies for pnpm.
- Introduced a new desktop application with essential files including index.html, package.json, and configuration files (postcss, tsconfig, vite).
- Added core components for the desktop app, including App, ProjectPicker, AssistantPanel, and UI elements like Button, Input, and DropdownMenu.
- Integrated Tauri plugins for file handling and dialog interactions.
- Enhanced Turbo configuration to include additional output paths for builds.
- Updated pnpm-lock.yaml to reflect new dependencies and versions for the desktop application.