* feat: show metadata subtitle (date + word count) instead of snippet
Replace the note list subtitle with a compact metadata summary showing
relative date and word count (e.g. "2d ago · 342 words") instead of
the first paragraph of note content. Adds word_count to VaultEntry on
the Rust backend, computed during vault scan.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: cargo fmt formatting
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: resolve custom type color and icon in all autocomplete contexts
Custom types (e.g., Evergreen, Recipe) appeared grey in wikilink [[,
@-mention, Cmd+P, and search autocompletes because getTypeColor() was
called without the custom color key from the Type document.
Root causes:
- Editor.tsx: getTypeColor(group) missing typeEntryMap[group]?.color
- useNoteSearch.ts: getTypeColor(e.isA) missing custom color lookup
- SearchPanel.tsx: type badge had no color styling at all
Fixes:
- Extract buildTypeEntryMap to shared utility in typeColors.ts
- Pass custom color key in all autocomplete code paths
- Add type icon (Phosphor) to the left of each result in NoteSearchList
- Add TypeIcon to WikilinkSuggestionItem and NoteAutocomplete
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add design file for autocomplete type color fix
Shows the fixed state: type icon on the left, colored type badge on
the right, untyped notes neutral grey with no icon.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: show type label for all notes in wiki-link autocomplete
Notes with the default 'Note' type (isA: null) had noteType set to
undefined, hiding their type label. Now every note always shows its
type in the autocomplete dropdown.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* design: add wiki-autocomplete-type-fix wireframe
Shows the fixed autocomplete dropdown where every note displays its
type label, including default "Note" types in muted color.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Backlinks previously relied on scanning allContent (raw markdown), which
was empty in Tauri mode until notes were explicitly saved. Now outgoing
wikilink targets are extracted during Rust vault scan and stored on
VaultEntry. The frontend useBacklinks hook uses this indexed data, and
outgoingLinks update in real-time on content change.
- Add extract_outgoing_links() in Rust parsing + outgoing_links field on VaultEntry
- Add extractOutgoingLinks() TypeScript utility for real-time updates
- Rewrite useBacklinks to use outgoingLinks instead of scanning raw content
- Add cache version invalidation to force rescan on format change
- Extract useEditorSaveWithLinks hook to keep App.tsx under code health threshold
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 8 unit tests for filterPersonMentions utility
- 6 integration tests for @ trigger in Editor component
- Verifies Person-only filtering, wikilink insertion, type badges
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Type @ in editor to trigger person-specific autocomplete
- Filters vault entries to show only Person type notes
- Inserts standard [[Person Name]] wikilink on selection
- Lower query threshold (1 char vs 2) since person list is smaller
- Add 3 more Person entries to mock data for testing
- Reuses existing WikilinkSuggestionMenu component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BlockNote's SuggestionMenu uses item.title as React key, causing duplicate
rendering and broken arrow-key navigation when multiple notes share the
same title. Fix by:
- Adding path-based deduplication to filter out duplicate entries
- Disambiguating same-title notes with parent folder name (e.g. "Standup (work)")
- Deduplicating aliases within each item (filename vs entry.aliases overlap)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
New notes created in-session show a green dot; existing notes with
uncommitted git changes show an orange dot. Saving a new note clears
the green dot; git commit clears the orange dot.
Introduces NoteStatus type ('new' | 'modified' | 'clean'), extracts
useNewNoteTracker hook and resolveNoteStatus pure function, and adds
onNoteSaved callback to useEditorSave for clearing new-note tracking.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The autocomplete menu for wiki-links was opening immediately on typing
'[[', processing all 9000+ vault entries and causing a visible freeze.
- Extract preFilterWikilinks utility with MIN_QUERY_LENGTH=2 gate
- Pre-filter entries with case-insensitive substring match before
creating expensive onItemClick closures
- Cap results at MAX_RESULTS=20 after BlockNote's filterSuggestionItems
- Add comprehensive tests for the utility and Editor integration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Test mocks: use { children?: React.ReactNode } and Record<string, unknown>
- Editor.tsx: use unknown[] for BlockNote block arrays
- wikilinks.ts: add BlockLike/InlineItem interfaces for block processing
- useMcpBridge.ts: use unknown for resolve/reject and Record<string, unknown>
- ai-chat.ts: use unknown catch + instanceof Error check
- mock-tauri.ts: type messages array, use Record<string, unknown> for args
(keep one targeted eslint-disable for heterogeneous handler map)
- vite.config.ts: use http.IncomingMessage/ServerResponse, typed messages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add `order: number | null` to VaultEntry (TS) and VaultEntry (Rust)
- Add order to Frontmatter struct and SKIP_KEYS in vault.rs
- Update all mock Type documents with order values (0-10)
- Add order: null to all non-Type mock entries and test fixtures
- Install @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add unit test verifying content blocks are applied via deferred microtask
(not synchronously in useEffect). Convert debug E2E test into a proper
regression test that checks editor content appears after clicking a note
and no flushSync errors are logged.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added filterEntries tests: trash excluded from all/section/topic/archived,
trash filter returns only trashed entries
- Added NoteList render tests: trash header, TRASHED badge, 30-day warning
banner, empty trash state
- Updated all test files with trashed/trashedAt fields on VaultEntry mocks
- Updated useNoteActions to include trashed/trashedAt on new entries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
Fix null-safety issues (string | null → string), add missing VaultEntry
fields in test fixtures, remove unused imports, and fix type assertion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The single BlockNote editor instance was calling replaceBlocks before the
editor was mounted in the DOM, causing content swaps to silently fail.
Now tracks mount state via editor.onMount() and defers content swaps
until the editor is ready. Also guards against stale async parses when
the user switches tabs before markdown parsing completes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Empty state rendering with keyboard shortcut hints
- Tab bar rendering and switching between tabs
- Close tab interaction
- Breadcrumb bar with note type, title, and word count
- New note button in tab bar
- BlockNote editor rendering
- Modified indicator and diff toggle button
- Inspector panel integration