Add "Open local folder" and "Create new vault" options to the vault
picker dropdown. Uses tauri-plugin-dialog for native folder picker
in Tauri mode, falls back to prompt() in browser mode.
- Rust: add tauri-plugin-dialog, create_vault_dir command
- Frontend: pickFolder utility, StatusBar UI, App.tsx handlers
- Mock: create_vault_dir mock handler for browser testing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Install @tauri-apps/plugin-updater + plugin-process (npm + cargo)
- Configure tauri.conf.json: updater endpoint pointing to GitHub Releases,
signing pubkey, createUpdaterArtifacts enabled
- Register updater + process plugins in Rust (desktop-only, #[cfg(desktop)])
- Add updater:default + process:default capabilities
- Add useUpdater hook: checks for updates 3s after startup, shows native
confirm dialog, downloads+installs+relaunches on accept
- Silently catches errors so update failures never block the app
- Add comprehensive tests for the useUpdater hook (5 test cases)
Product decision: Using window.confirm() for the update dialog rather than
a custom React modal. This keeps the implementation simple and the native
dialog is appropriate for a system-level action like app restart. Can be
upgraded to a custom UI later if desired.
Private key generated at ~/.tauri/laputa.key — NOT committed.
For CI: set TAURI_SIGNING_PRIVATE_KEY + TAURI_SIGNING_PRIVATE_KEY_PASSWORD
as GitHub Secrets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend implementation for renaming a note:
- Updates H1 heading and title frontmatter to new name
- Renames file using slugified new title
- Scans all vault .md files and replaces [[OldTitle]] → [[NewTitle]]
in both content and frontmatter (preserves pipe aliases)
- Returns new path and count of updated files
Well-factored with extracted helpers: build_wikilink_pattern,
replace_wikilinks_in_content, collect_md_files, update_h1_title,
update_note_title_in_content, frontmatter_has_title_key, to_path_stem.
All 147 tests pass including 7 new rename tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds purge_trash(vault_path) that scans all .md files, reads the
"Trashed at" frontmatter date, and deletes files older than 30 days.
Registered as a Tauri command and called automatically on app startup
(defaults to ~/Laputa vault). Includes 7 tests covering boundary
conditions, nested dirs, and datetime formats.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The editor's useCreateBlockNote was missing the uploadFile callback,
so BlockNote had no handler for image uploads (drag-drop, paste, or
toolbar button). Images now convert to data URLs for immediate display.
In Tauri mode, uploaded images are also persisted to the vault's
attachments/ directory via a new save_image backend command.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Tauri command for AI chat via reqwest:
- ai_chat module with send_chat() using Anthropic Messages API
- ANTHROPIC_API_KEY from environment variable
- Proper error handling for missing key, API errors, parse failures
- Unit tests for request building and response extraction
- Mock handler added to mock-tauri.ts for browser testing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Scaffold Vite + React + TypeScript frontend
- Add Tauri v2 backend with Rust
- Implement list_vault command: recursively scans .md files, parses
YAML frontmatter (Is A, aliases, Belongs to, Related to, Status,
Owner, Cadence), extracts title from H1 or filename
- 10 passing Rust tests for frontmatter parsing and vault scanning
- Configure Vitest and Playwright (test infrastructure)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>