- Add icon (string|null) and color (string|null) to VaultEntry interface
- Update Rust VaultEntry struct and frontmatter parsing to read icon/color
- Add icon/color to SKIP_KEYS so they don't appear as relationships
- Set mock data: Recipe type → cooking-pot/orange, Book type → book-open/green
- Update all test files with the new required fields
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Four frames added to design/color-icon-for-types.pen:
1. Right-click context menu on sidebar section group headers
2. Icon & color picker popover (color swatches + icon grid)
3. Sidebar with custom icons & colors applied
4. Frontmatter persistence model (icon/color in type YAML)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Blob URLs are session-scoped and don't survive page reloads — images
would break on Cmd+Shift+R. Now uploadFile awaits save_image (which
persists to vault/attachments/) and returns a convertFileSrc asset URL
that the Tauri webview can resolve indefinitely.
- Editor.tsx: await save_image → convertFileSrc for Tauri mode;
FileReader.readAsDataURL fallback for browser dev mode
- tauri.conf.json: enable assetProtocol with scope ["**"]
- mock-tauri.ts: save_image returns a plausible file path
- E2E test: expect data: URLs in browser dev mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The uploadFile callback was converting images to data URLs via FileReader,
which caused images to get stuck on "Loading..." in the editor. Switched
to URL.createObjectURL() which returns a lightweight blob URL immediately.
The Tauri vault-save path is now fully fire-and-forget so it never blocks
the URL return.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Tab navigation: Cmd+Option+Left/Right (Tauri), Cmd+Shift+Left/Right (browser)
- Note list navigation: Cmd+Option+Up/Down moves through visible notes
- Navigating notes replaces the current tab content (no new tab opened)
- Wraps around at list boundaries
- New useKeyboardNavigation hook detects Tauri vs browser environment
- Extracted loadNoteContent and replaceTabWithEntry helpers to reduce
complexity in useNoteActions
- Exported filterEntries, sortByModified, buildRelationshipGroups from
NoteList for reuse in keyboard navigation
Note: useNoteActions (30→31 CC) and App (143→153 LOC) show minimal
degradation on pre-existing code health issues.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two frames showing tab switching shortcuts (Cmd+Opt+Left/Right in Tauri,
Cmd+Shift+Left/Right in browser) and note list navigation (Cmd+Opt+Up/Down
replaces current tab).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Verifies that the slash menu Image option works and that no
upload-related errors occur when inserting an image block.
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>
6 Playwright tests covering the full flow:
- Create Type dialog opens from + button on Types section
- Create button disabled when name is empty
- Creating a type adds it to sidebar and opens it in editor
- Custom types appear in Create Note dialog type selector
- Can create instances of custom types
- Cancel closes dialog without side effects
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Core implementation:
- CreateTypeDialog: simple dialog with name field for creating new types
- handleCreateType in useNoteActions: creates Type documents in type/ folder
- Dynamic sidebar sections: custom types (Recipe, Book, etc.) appear as new
sidebar sections after built-in ones, each with a + button for instances
- Updated CreateNoteDialog: accepts custom types, shows them with blue accent
- handleCreateNote now supports custom types (folder = lowercased type name)
Product decisions:
- The + on Types section opens CreateTypeDialog (not CreateNoteDialog)
- Custom type sections use FileText icon and blue accent color by default
- Section labels are pluralized (e.g., "Recipes", "Books")
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The BlockNote editor container (.bn-container) had no explicit width,
so it sized based on content. With short or empty document titles,
the editor collapsed to a very small width.
Fix: set width: 100% on .bn-container and .bn-editor so the editor
always fills available space. Added margin: 0 auto on .bn-editor to
keep the 760px text column centered.
Also adds an E2E test verifying editor width stays above 300px.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add mock data for two user-created types (Recipe, Book) plus example
instances (Pasta Carbonara, Designing Data-Intensive Applications).
This enables testing the create-new-types feature in the browser.
Also fix pre-existing test: Sidebar.test expected 7 section groups
but there are 8 (Types was added but test count wasn't updated).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three wireframe sections:
1. Create Type Dialog — simple modal with name field, triggered by + on Types section
2. Dynamic Sidebar Sections — custom types auto-appear as new sidebar sections
3. Updated Create Note Dialog — type selector includes custom types with blue accent
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Test that + buttons render for all 7 section groups
- Test that clicking + calls onCreateType with correct type
- Test that + buttons are hidden when callback not provided
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Each sidebar section header (Projects, People, Topics, etc.) now shows
a + button on hover. Clicking it opens the CreateNoteDialog pre-filled
with that section's type, so users can quickly create new items without
manually selecting the type.
- Add defaultType prop to CreateNoteDialog for pre-selecting type
- Add onCreateType callback to Sidebar with hover-visible + button
- Wire up in App.tsx with unified openCreateDialog handler
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Accept string | null in typeColors functions (matches VaultEntry.isA type)
- Add missing snippet/relationships fields to test mock entries
- Remove unused imports (AIChatPanel in App, cn in Editor)
- Fix Promise type cast in Editor.tsx tryParseMarkdownToBlocks
- Fix null coalescing in Inspector resolveRefType return
- Remove unused container variable in NoteList test
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Type is a special relationship handled separately by the sidebar,
so it should not appear as one of the generic relationship groups
in the note list entity view. Added case-insensitive filter to
exclude the "type" key from the otherKeys loop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Node.js MCP server with 5 vault tools:
- open_note / read_note: read markdown file content
- create_note: create new note with frontmatter and title
- search_notes: search by title or content substring
- append_to_note: append text to existing note
Uses @modelcontextprotocol/sdk with stdio transport.
VAULT_PATH env var configures the vault directory.
10 passing tests covering all operations.
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>