Commit graph

91 commits

Author SHA1 Message Date
delibae
4bd5bf3bc8 style: fix biome formatting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:42:03 +09:00
delibae
da2f76c51a chore: fix lint warnings, bump version to 1.0.7
- Remove unused imports (hasPdfData, contentGeneration, lastCompiledGenerations)
- Bump version 1.0.6 → 1.0.7

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:39:49 +09:00
delibae
63483a2d2c feat: subprocess tectonic, editor shortcuts, and UX improvements
- 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>
2026-03-17 02:38:56 +09:00
delibae
16d636592a fix: update quickstart URL to include locale path
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 01:53:04 +09:00
delibae
a10afacd6c fix: improve Linux AppImage compatibility and login reliability
- 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>
2026-03-17 01:11:02 +09:00
delibae
95c4072ec1 chore: fix all lint and formatting issues (biome check)
- Fix unused imports and variables
- Apply biome formatting (template literals, semicolons, line width)
- Fix a11y issues (label associations, anchor content)
- Fix Node.js import protocol (node:fs, node:path)
- Use self.onmessage in web worker

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 17:04:36 +09:00
Minsoo Kim
ea04d34bb4
Merge pull request #63 from delibae/feat/debug-and-black-screen-fix
fix: black screen on app switch + debug infrastructure
2026-03-16 16:47:20 +09:00
delibae
2480715f22 fix: macOS WKWebView black screen on focus restore & bump v1.0.5
- 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>
2026-03-16 16:40:10 +09:00
Minsoo Kim
585c631a86 fix: debug window log sync, auto-scroll, and IPC efficiency
- Fix echo loop: only debug window listens for debug-log-entry events
- Gate emit on _debugWindowConnected flag (no IPC when debug window closed)
- Simplify bulk sync: replace buffer on open instead of timestamp dedup
- Auto-scroll: use instant behavior, only scroll when already at bottom
- Fix systemInfo useEffect to run once ([] deps instead of [systemInfo])
2026-03-16 16:31:54 +09:00
Minsoo Kim
363b8c3482 refactor: separate debug window, cross-window log sync, simplify
- 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>
2026-03-16 16:31:54 +09:00
Minsoo Kim
cc5011b98a feat: add structured logging, debug panel, and bug report generation
Add comprehensive debugging infrastructure:

- Structured log store (Zustand ring buffer, 2000 entries) with
  level/source filtering and auto-forwarding warn/error to Rust stderr
- createLogger() factory replacing ad-hoc console.log("[prefix]") calls
  across 16 files (claude-event, pdf-viewer, mupdf, sidebar, etc.)
- Debug panel UI (Cmd+Shift+D) with Logs/System/Visibility tabs
- Bug report generator collecting logs, system info, GPU renderer,
  and visibility events into copyable JSON
- "Copy Debug Info" button on error fallback screen
- get_system_info Tauri command for OS/arch/version data
2026-03-16 16:31:53 +09:00
Minsoo Kim
db97ea59ad fix: resolve black screen on app switch (macOS M1)
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
2026-03-16 16:31:53 +09:00
delibae
2f3276a80e feat: inline update UI on home screen, gitignore gen/schemas (v1.0.2)
- Replace toast-based updater with inline version badge on home screen
- Show version + check/update/progress states directly in ProjectPicker
- Move Toaster to App level for workspace toast support
- Remove auto-generated Tauri schemas from git tracking
- Bump to v1.0.2

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 15:26:21 +09:00
delibae
15b0a24103 fix: move Toaster to App level, add version display, set v1.0.1
Toaster was only in WorkspaceWithClaude so update toasts didn't show
on the home screen. Moved to App level. Also shows version on home.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 15:03:54 +09:00
delibae
4dfe6b1946 feat: show app version on home screen, bump to v1.0.2
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 14:47:11 +09:00
delibae
08e54f263d feat: add auto-updater and fix macOS black screen on focus loss (v1.0.1)
- 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>
2026-03-16 13:16:39 +09:00
Hanjin Bae
a3a2282dd6
fix: adjust titlebar height for Windows overlay mode (#42)
Reduce from 32px to 12px — 32px was too much padding, pushing content
too far from the top edge.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 03:46:40 +09:00
Hanjin Bae
32397bb611
fix: show folder name only in sidebar on Windows (#41)
projectRoot.split("/") didn't handle Windows backslash paths, causing
the full path (C:\Users\...\project) to display in the sidebar header.
Now splits on both / and \ so only the folder name is shown.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 03:37:19 +09:00
Hanjin Bae
d32c732c36
fix: Windows titlebar, installer fixes, and responsive PDF toolbar (#40)
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>
2026-03-16 03:16:02 +09:00
Hanjin Bae
ebcb190d7a
fix: detect missing Git for Windows and guide users to install it (#37)
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>
2026-03-16 00:27:15 +09:00
delibae
6cafe39baf fix: standardize default file name to main.tex across the application 2026-03-14 21:12:23 +09:00
delibae
1068869a45 feat: enhance editor CLI resolution on macOS and improve file creation logic 2026-03-14 18:36:13 +09:00
delibae
792b6dc58f fix: address Copilot review — update comments and add binary extension tests
- Update IGNORED_EXTENSIONS comment from "LaTeX build artifacts" to reflect
  that it now includes general non-editable/binary files
- Update getFileType comment to match the broader scope of ignored extensions
- Add test coverage for representative binary extensions (.docx, .xlsx, .hwp,
  .accdb, .zip, .exe, .mp3, .mp4, .psd, .sqlite, .dll, .pptx)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:08:42 +09:00
GunwoongP
13f32a2437 fix: exclude binary file types from project file tree
Add 40+ binary extensions (.hwp, .docx, .xlsx, .accdb, .zip, .exe,
media files, etc.) to IGNORED_EXTENSIONS so they are filtered out
during directory scanning. These files cannot be meaningfully edited
in the text editor and would only cause unnecessary I/O and memory
usage when present in a project folder.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 14:45:46 +09:00
Minsoo Kim
dc306eaebe fix: resolve merge conflicts, prevent recompile recursion, and improve test isolation
- 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>
2026-03-12 11:14:06 +09:00
Minsoo Kim
2459067e77 fix: resolve PDF white-screen crash, nul-byte spawn error, and dropped recompiles
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>
2026-03-11 02:53:24 +09:00
delibae
4b07d7443b fix: address Copilot review — optimize stat calls and support large image preview
Only call stat() for image/other file types during project scan to avoid
unnecessary I/O overhead on tex/bib/style/pdf files. Use convertFileSrc
(asset URL) as fallback in ImagePreview when dataUrl is not available,
so large images are viewable without loading them entirely into memory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 01:31:46 +09:00
Hanjin Bae
4a95160984
Update apps/desktop/src/components/workspace/editor/latex-editor.tsx
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-11 01:20:41 +09:00
Hanjin Bae
e37afc5a2a
Update apps/desktop/src/lib/latex-compiler.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-11 01:20:10 +09:00
GunwoongP
8340d9e29d feat: lazy-load large files to prevent editor slowdown
Skip auto-loading files > 1 MB during project open. Large non-essential
files (e.g., .jsonl training data) show a VS Code-style "Open Anyway"
prompt instead of being read into memory immediately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 00:54:54 +09:00
GunwoongP
dcb20b779e fix: handle missing .tex file gracefully instead of hardcoded fallback
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>
2026-03-10 23:12:22 +09:00
Minsoo Kim
0d59255edb feat: add PDF page navigation, folder deletion, and dirty file indicator
- Add Page Up/Down buttons and editable page indicator to PDF preview toolbar
- Track current visible page via scroll with rAF throttling
- Implement proper recursive folder deletion in sidebar and document store
- Replace text asterisk with blue dot indicator for modified files in sidebar
- Extract shared scrollToPage helper to deduplicate scroll math in pdf-viewer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 22:08:58 +09:00
Minsoo Kim
3cea905569 refactor: replace custom ErrorBoundary with react-error-boundary
Remove duplicated error-boundary.tsx in favor of upstream's
react-error-boundary library already in package.json.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:21:51 +09:00
Minsoo Kim
2e083a3a19 feat: keep-alive PDF viewers and per-file state preservation on switch
Keep PdfViewer instances mounted (visibility:hidden) instead of
unmounting on file switch, so canvas/scroll state is preserved
instantly. Also cache editor cursor+scroll and PDF zoom per file.

- Keep-alive up to 5 PdfViewer instances with LRU eviction
- Save/restore scrollTop via isActive prop on visibility toggle
- Per-file editor cursor + scroll cache (editorStateCache)
- Per-root PDF zoom + fitMode cache (zoomCache)
- Gate IntersectionObserver on isActive to avoid work for hidden viewers
- Extract scrollToPageEl helper to deduplicate scroll-retry logic
- Deduplicate getOrOpenDocument to reuse getCachedDocument
- Clear all caches on project close

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:20:19 +09:00
Minsoo Kim
2a315f5bf7 fix: address review findings and fix structured clone error
- Fix non-reactive getState() in render path → use activeFile?.id
- Replace linear cache scan with cache.get() O(1) lookup
- Remove redundant fingerprint field from CachedDoc
- Parallelize clearDocCache() with Promise.all
- Revert buffer.slice() optimization — always copy to avoid structured
  clone errors from non-transferable Tauri buffers and prevent pdfCache
  corruption from ArrayBuffer detachment
- Add clearScrollPositionCache() on project close to prevent memory leak

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:20:19 +09:00
Minsoo Kim
84b8f2339a feat: optimize PDF loading with LRU doc cache, scroll caching, and eager import
- Add PDF document LRU cache (max 5 open docs) with fingerprint-based identity check
- Skip MuPDF close/reopen cycle when switching to already-cached PDF
- Remove lazy() import for PdfViewer to eliminate Suspense flash
- Cache scroll position per root file and restore on file switch
- Clear doc cache on project close

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:20:19 +09:00
Minsoo Kim
5f4c446e8e fix: add error boundaries and stability improvements to prevent white screen crashes
- Add global ErrorBoundary with error details UI (stack trace, copy button)
- Wrap PdfViewer Suspense with ErrorBoundary for graceful PDF crash recovery
- Add 30s timeout to MuPDF worker calls to prevent infinite hangs
- Add unhandled promise rejection handler in main.tsx

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:19:52 +09:00
delibae
e0986f060e feat: add aria-labels for accessibility improvements in various components 2026-03-10 20:31:58 +09:00
delibae
bd18e75f3c fix: improve error handling in various components and ensure root element exists 2026-03-10 20:27:00 +09:00
delibae
cad77ba71b feat: add ErrorBoundary with fallback component for better error handling 2026-03-10 20:17:35 +09:00
Hanjin Bae
9e89bd8f31
Merge pull request #9 from vv137/fix/multi-tex-compile
feat: multi-tex compilation with per-root PDF caching
2026-03-10 16:29:16 +09:00
Minsoo Kim
b7fe28cda8 fix: clear compileErrorCache when error is null to prevent stale errors
setCompileError only updated compileErrorCache when setting an error,
but never cleared the cache entry when error was null. This caused stale
errors to resurface on tab switches via setActiveFile.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:30:50 +09:00
Minsoo Kim
33c87837aa refactor: use shared compile helpers and fix efficiency issues
- Replace 4 inline compile-target-resolution blocks with resolveCompileTarget()
- Replace 4 inline error formatting expressions with formatCompileError()
- Remove direct resolveTexRoot imports from consumer files
- Skip unnecessary Map copies in setPdfData when no rootFileId
- Eliminate double resolveTexRoot call in deleteFile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:13:59 +09:00
Minsoo Kim
fb7e753c08 refactor: extract resolveCompileTarget and formatCompileError helpers
Consolidate duplicated compile-target resolution and error formatting
logic into shared functions in latex-compiler.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:13:46 +09:00
Minsoo Kim
37f687f082 feat: use root resolution and per-root compile guards
Update all compilation sites to resolve the root file before compiling
and check per-root generation instead of a single project-wide guard.

- latex-editor: read isCompiling from store to avoid stale closures
- pdf-preview: read all guard values from store, add Compile button
  to empty placeholder view
- use-claude-events: resolve root for auto-compile after Claude edits
- All sites pass rootFileId to setPdfData/setCompileError for caching

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:04:24 +09:00
Minsoo Kim
0df2d1e524 feat: add per-root PDF cache and % !TEX root support
Replace single pdfData/lastCompiledGeneration with per-root-file Maps
so multiple .tex documents can each have their own cached PDF.

- Add pdfCache, compileErrorCache, lastCompiledGenerations Maps
- Add resolveTexRoot() to parse % !TEX root magic comments
- setActiveFile swaps displayed PDF from cache on file switch
- setPdfData/setCompileError update both cache and display
- Add migrateCacheKey helper for rename/move operations
- Cache cleanup on deleteFile, migration on renameFile/moveFile
- Reset all caches on openProject/closeProject

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:04:15 +09:00
Minsoo Kim
60c3f20c82 feat: add Fit to Width and Fit to Height PDF zoom options
Add dynamic fit modes at the top of the zoom dropdown that auto-recalculate
scale on window/container resize and persist during scroll. Manual zoom
actions (buttons, wheel, keyboard, percentage select) clear fit mode.
Also fix bouncy scroll arrow by switching dropdown to popper positioning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:08:47 +09:00
delibae
f0706ea4c1 feat: enhance slash command picker with fuzzy search and skill previews
- 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.
2026-03-07 15:43:33 +09:00
delibae
bfb02d4f5c feat: Enhance Claude installation process and permissions handling
- 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.
2026-03-06 19:23:41 +09:00
GunwoongP
47d8723ce7 fix: Windows build fixes and session resume crash
- README: add CXXFLAGS=/std:c++17 env var for MSVC (ICU 78+ requires
  C++17, but MSVC uses /std:c++17 instead of -std=c++17)
- README: fix vcpkg triplet to x64-windows-static-md (tectonic expects
  static-md linkage, not dynamic x64-windows)
- .cargo/config.toml: clarify that macOS defaults are overridden by
  user env vars on Windows/Linux (force=false)
- tool-widgets: fix TodoWrite widget crash when input.todos is not an
  array (e.g. malformed session history), use Array.isArray guard
- chat-messages: add nullish coalescing fallback for messages store
  selector to prevent crashes during session transitions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 19:16:21 +09:00