Match the note list header height (52px) across all panel headers for
consistent horizontal alignment. Previously breadcrumb bar, inspector
header, and AI panel header were 45px.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verifies that searching "Writing" in Quick Open shows the exact title
match first, followed by prefix matches. Also adds Refactoring test
entries to mock data and demo vault.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In Tauri mode, allContent is {} (empty) until a note is explicitly
saved. The previous mergeTabContent fix enriched allContent with tab
content, but the indirection was fragile. This fix passes the active
tab's content directly to buildContextSnapshot as activeNoteContent,
which takes priority over allContent[path]. This ensures the AI always
receives the note body regardless of allContent state.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
detectFileOperation silently failed when tool input was undefined (timing
issues with NDJSON event ordering). Added onVaultChanged callback as fallback:
when Write/Edit/Bash tools complete but specific file can't be determined,
vault.reloadVault() is triggered. Also added safety net in onDone handler.
Threaded onVaultChanged through AiPanel → EditorRightPanel → Editor → App.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
AiPanel.handleNavigateWikilink was double-resolving: it resolved the
wikilink target to an entry path, then passed the path to onOpenNote
which is notes.handleNavigateWikilink (expects a title-based target).
The path didn't match any entry's title, so navigation silently failed.
Fix: pass the wikilink target string directly to onOpenNote, letting
the parent's handleNavigateWikilink do the resolution.
Also enhanced the Playwright smoke test to verify click → tab opens.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- System prompts instruct AI to use [[Note Title]] wikilink syntax
- preprocessWikilinks converts [[Target]] to markdown links
- Custom urlTransform allows wikilink:// scheme through sanitizer
- Click handler resolves target via findEntryByTarget and opens note
- Styled as colored chips matching primary accent
- Works in both AiPanel (agent) and AIChatPanel (legacy chat)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove --tools "" restriction so the agent has native bash/read/write/edit
access. Set vault path as working directory for the subprocess.
Simplify MCP to 4 Laputa-specific tools (search_notes, get_vault_context,
get_note, open_note) — everything else is handled by native tools.
Add file operation detection from Write/Edit tool calls to auto-open
created notes and refresh modified notes in the UI. Enhanced tool call
labels show bash commands, file paths, and note names.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Render [[wikilink]] reference pills inside sent message bubbles
with type-colored badges; clicking a pill opens the note
- Add noteList (filtered note list titles, max 100) and noteListFilter
to the structured context snapshot sent to the AI
- Thread noteList/noteListFilter from App → Editor → EditorRightPanel → AiPanel
- Store references in AiAgentMessage for display in chat history
- Add tests for reference pill rendering and noteList context
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move Escape handler from input onKeyDown to a window-level listener
scoped to the panel, so it works even when input is disabled during
AI response. When agent is active, focus transfers to the panel
container; when idle, focus returns to the input.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When AI Chat panel mounts (via Cmd+I), the input field now receives
focus automatically so users can type immediately without clicking.
Pressing Escape in the input closes the panel.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Cmd+I toggles AI panel with context from the active note
- Context bar shows note title in AI panel when a note is open
- useAiAgent accepts optional contextPrompt used as system prompt
- ai-context.ts extracts structured context from note + related entries
- Updated AiPanel, EditorRightPanel, App, useAppCommands, useCommandRegistry
- 1292 frontend tests pass, coverage 78.96%
Co-authored-by: Test <test@test.com>
* feat: add claude CLI subprocess backend for AI panels
Add claude_cli.rs module that spawns the local `claude` CLI as a
subprocess instead of calling the Anthropic API directly. This removes
the need for users to configure an API key — the CLI uses the user's
existing Claude authentication.
- find_claude_binary(): discovers claude in PATH or common locations
- check_cli(): returns install/version status for the frontend
- run_chat_stream(): spawns claude -p with stream-json for chat panel
- run_agent_stream(): spawns claude with MCP vault tools for agent panel
- Parses stream-json NDJSON events and emits typed Tauri events
- Remove http:default capability (no longer calling APIs from frontend)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: replace Anthropic API with Claude CLI for AI chat and agent panels
Remove direct Anthropic API calls and the entire tool-use loop from the frontend.
Both AI Chat and AI Agent panels now delegate to the `claude` CLI subprocess via
Tauri commands, streaming NDJSON events back to the UI.
Key changes:
- ai-chat.ts / ai-agent.ts: replace SSE/API streaming with Tauri invoke + listen
- useAIChat / useAiAgent hooks: simplified to use CLI streaming callbacks
- AIChatPanel / AiPanel: remove API key dialogs, model selectors, undo support
- SettingsPanel: remove Anthropic key field (no longer needed)
- claude_cli.rs: add comprehensive tests (37 total, 90% coverage)
- mock-handlers: replace ai_chat with check_claude_cli / stream_claude_* stubs
- Net -432 lines across 17 files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add --verbose flag to claude CLI subprocess args
* chore: exclude search.rs and lib.rs from coverage (qmd integration + Tauri setup)
---------
Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>