Commit Graph

46 Commits

Author SHA1 Message Date
Luca Rossi
2907bc592e feat: status property — Notion-style dropdown with color chips (#97)
* fix: resolve search panel freeze by making search_vault async

The search_vault Tauri command was synchronous (fn, not async fn),
blocking the main thread for 30+ seconds during hybrid/semantic
search on large vaults (9200+ files). This caused the macOS beachball.

Changes:
- Make search_vault async with tokio::spawn_blocking (runs qmd off main thread)
- Cache collection name per vault path (avoid repeated qmd collection list calls)
- Cancel inflight searches and debounce timers when panel closes
- Add regression test for stale result cancellation on panel close

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* design: add status property dropdown wireframes

Three frames: closed pill state, open dropdown with suggested/vault
statuses, and custom status creation flow.

Also bump flaky NoteList 9000-entry test timeout from 15s to 30s.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: replace status text edit with Notion-style dropdown

- Extract STATUS_STYLES to shared statusStyles.ts utility
- New StatusDropdown component: filterable popover with colored pills
- StatusPill reusable component for consistent status chip rendering
- Vault-wide status aggregation from entries prop
- Dropdown shows "From vault" and "Suggested" sections
- Custom status creation via type-and-Enter
- Escape/backdrop click cancels without saving
- Keyboard navigation (ArrowUp/Down + Enter)
- 22 new tests covering dropdown behavior + integration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: cargo fmt

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 12:40:27 +00:00
Luca Rossi
cb8efa7b0f fix: resolve custom type color and icon in all autocomplete contexts (#84)
* 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>
2026-02-26 03:05:22 +00:00
Luca Rossi
c85e343dd9 feat: smart property display — type-aware rendering with display mode override (#83)
* design: add smart property display wireframes

Frames: date picker, boolean toggle, status badge, display mode override dropdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: smart property display — type-aware rendering with display mode override

- Add property type auto-detection (date, boolean, status, url, text) based on value content and property name
- Date properties (ISO strings) show as friendly format (e.g. "Mar 31, 2026") with native date picker on click
- Boolean properties show as toggle buttons
- Status properties auto-detected from key name or known status values, rendered as colored badges
- Each property gets a display mode override dropdown (visible on hover) to force a specific display type
- Display mode overrides persist across sessions via localStorage
- Add mock data with date/boolean fields for testing
- 36 new tests covering type detection, date formatting, localStorage persistence, and UI rendering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:12:40 +00:00
lucaronin
2c8befab93 fix: make backlinks update reactively when wikilinks are added or removed
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>
2026-02-25 18:07:04 +01:00
lucaronin
6b0ee4bf12 test: add tests for @mention autocomplete
- 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>
2026-02-25 16:31:45 +01:00
lucaronin
4fd1d97ac1 feat: add @mention autocomplete for Person entries
- 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>
2026-02-25 16:31:45 +01:00
Luca Rossi
ca9ede51d5 fix: relation chips now show type color instead of default blue (#68)
* fix: relation chips now display correct type color instead of default blue

Root cause: resolveRef matched entries by path/filename only, while
wiki-links used findEntryByTarget (title, filename, aliases). When a
wikilink target used the note title (differing from filename), resolveRef
failed → null type → default blue.

Changes:
- resolveRef now calls findEntryByTarget first (title/alias match)
- Default color for typeless notes changed from blue to neutral grey
- TypeSelector passes custom color key from Type entries
- DynamicPropertiesPanel refactored to reduce cyclomatic complexity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* design: add before/after visual for relations type color fix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add task completion summary

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:02:33 +00:00
Luca Rossi
a8692d021e Merge pull request #61 from refactoringhq/task/command-palette
feat: command palette (Cmd+K) — quick actions and navigation
2026-02-25 00:05:11 +01:00
Luca Rossi
c4be44ffca Merge pull request #60 from refactoringhq/task/autocomplete-flat-list
feat: flat list autocomplete with type badge
2026-02-25 00:05:07 +01:00
lucaronin
af0492b82e fix: exclude title heading and wikilinks from word count
countWords() was including the title line (# Heading) in the count,
inflating it by ~2-3 words. Now strips the first H1 heading and
[[wikilinks]] before counting, so only body prose is tallied.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:03:44 +01:00
lucaronin
3f79d1631b fix: use Tauri opener plugin for URL property clicks
Replace window.open() with Tauri's opener plugin (openUrl) so that
clicking a URL property in the Properties panel opens the system
browser instead of failing silently or triggering edit mode.

- Install @tauri-apps/plugin-opener (npm + Cargo + capabilities)
- Add openExternalUrl() utility with Tauri/browser fallback
- Add stopPropagation to prevent accidental edit mode activation
- Add double-click guard (500ms debounce via ref)
- Update tests to mock openExternalUrl instead of window.open
- Add explicit test that URL click does not trigger onStartEdit

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:02:09 +01:00
lucaronin
154aab5098 test: add command palette and fuzzy match tests
Tests for CommandPalette component (rendering, filtering, keyboard
navigation, grouped results, shortcuts display), useCommandRegistry
hook (contextual actions, archive toggle, git availability), fuzzyMatch
utility, and Cmd+K shortcut.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:43:58 +01:00
lucaronin
765f26c3e5 feat: replace grouped autocomplete with flat list and type badge
Switch wiki-link autocomplete from BlockNote's default grouped suggestion
menu to a custom flat list sorted by relevance. Each item shows the note
type (with its accent color) discretely on the right side. Reduce
MAX_RESULTS from 20 to 10 for a cleaner, more focused list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:42:09 +01:00
lucaronin
5d24fdaef3 feat: add command palette with Cmd+K shortcut
Raycast-style command palette with fuzzy search across all app actions.
Groups commands by category (Navigation, Note, Git, View, Settings)
with keyboard shortcuts displayed inline. Contextual actions (trash,
archive, save) are only available when a note is open.

Extracts fuzzyMatch into shared utility for reuse.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:41:54 +01:00
Luca Rossi
7ed9e30299 fix: deduplicate autocomplete suggestions and disambiguate same-title notes (#54)
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>
2026-02-24 22:12:35 +00:00
lucaronin
4c6bc91971 feat: expand icon picker with ~290 icons, search, and scrollable grid
- Extract icon registry to src/utils/iconRegistry.ts with 290 curated Phosphor icons
- Add real-time search field that filters icons by name substring
- Show "No icons found" empty state when search yields no results
- Scrollable icon grid (240px max height) for browsing all icons
- Add teal and pink accent colors to the palette (8 total)
- Widen popover from 264px to 280px for better search field fit
- Update tests: search filtering, empty state, icon count validation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:36:11 +01:00
lucaronin
dd9b306100 feat: make URL properties clickable with hover underline
- Add UrlValue component: click opens in browser, pencil icon for edit
- URL detection via isUrlValue() (http/https URLs + bare domains)
- URL normalization: prepends https:// to bare domains
- Malformed URLs silently ignored (no open attempt)
- Long URLs truncated visually but full URL opens on click
- Edit mode via pencil icon or keyboard (Enter/Escape/blur)
- 22 new tests covering detection, normalization, and component behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:46:18 +01:00
lucaronin
3adf785f86 Merge remote-tracking branch 'origin/main' into task/wikilink-autocomplete 2026-02-24 13:01:33 +01:00
lucaronin
d2c8d25add fix: exclude YAML frontmatter from word count in Inspector panel
The DynamicPropertiesPanel had a local countWords that used a regex
(/^---[\s\S]*?---/) which could match dashes inside frontmatter values,
leaving part of the frontmatter in the body and inflating the count.

Replace with the canonical countWords from utils/wikilinks.ts which uses
splitFrontmatter (line-based indexOf) and correctly finds the closing
delimiter on its own line.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 12:46:21 +01:00
lucaronin
ec06d5ad7e fix: require 2+ chars before showing wikilink autocomplete, limit to 20 results
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>
2026-02-24 12:46:19 +01:00
lucaronin
b8c3a7302c refactor: extract wikilink utils to src/utils/wikilink.ts, fix NoteList useMemo deps
- Move wikilinkTarget/wikilinkDisplay from InspectorPanels.tsx to src/utils/wikilink.ts
  (fixes react-refresh/only-export-components lint error — non-component exports
  must live in utility files, not component files)
- Remove unused modifiedFiles from useNoteListData deps array and interface
  (fixes react-hooks/exhaustive-deps warning — was in dep array but not used)
2026-02-23 21:55:57 +01:00
Luca Rossi
17e11669cb Merge pull request #26 from refactoringhq/task/wikilink-colorati
feat: color wikilinks by destination note type
2026-02-23 21:02:43 +01:00
lucaronin
7c0111b53d test: add tests for local vault picker options
- StatusBar: 6 new tests for open local folder, create new vault options
- vault-dialog: 3 tests for pickFolder browser fallback behavior
- Rust lib: 3 tests for create_vault_dir (new dir, nested, existing)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:01:42 +01:00
lucaronin
171436243a feat: add local vault options to vault picker
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>
2026-02-23 21:01:42 +01:00
lucaronin
3d35eaff20 feat: color wikilinks by destination note type
Wikilinks in the editor now show the accent color of the target note's
type (Project=red, Person=yellow, Topic=green, etc.) instead of always
being blue. Broken links (target not found) show muted text with a
dashed underline.

- Extract wikilink color resolution to src/utils/wikilinkColors.ts
- Use getTypeColor from typeColors.ts (single source of truth)
- Support alias and pipe-syntax matching in findEntryByTarget
- Add wikilink--broken CSS class for non-existent targets
- Add 17 unit tests covering all color resolution cases
- Update mock data with wikilinks to various note types + broken link

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 20:44:30 +01:00
lucaronin
180ade7734 fix: implement auto-save for editor content
The editor was not persisting changes to disk. Edits would be lost
when closing and reopening a note.

Changes:
- Add save_note_content Tauri command (Rust) with read-only file check
- Add save_note_content mock handler for browser testing
- Add useAutoSave hook with 500ms debounce and flush-on-tab-switch
- Wire up BlockNote onChange → markdown serialization → auto-save
- Add restoreWikilinksInBlocks utility (reverse of injectWikilinks)
  to convert wikilink nodes back to [[target]] before markdown export
- Extract shared walkBlocks helper to eliminate code duplication
- Suppress onChange during programmatic content swaps (tab switching)
- 12 new frontend tests + 5 new Rust tests (all 469 + 174 passing)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 14:48:21 +01:00
lucaronin
d14f6f59bd fix: resolve all ESLint errors (lint now exits 0)
- useAppKeyboard: move all logic inside useEffect, fixes refs-in-render
  and no-unused-expressions for view mode shortcut handler
- SettingsPanel: refactor to inner component to fix setState-in-effect;
  remove unused maskKey function
- NoteList: remove re-exports (consumers import from noteListHelpers directly);
  fix no-unused-expressions in toggleGroup; eslint-disable for Icon-in-render
- useNoteActions: eslint-disable tabsRef.current assignment (valid pattern)
- Test files: fix no-explicit-any in useKeyboardNavigation, useSettings,
  useVaultLoader, wikilinks tests; update NoteList.test import path
2026-02-23 08:53:43 +01:00
lucaronin
b91aded1ba feat: add sort direction (asc/desc) to note list sorting
- Add SortDirection type and SortConfig interface to noteListHelpers
- getSortComparator now accepts optional direction parameter
- SortDropdown shows ↑/↓ arrow buttons per option in the menu
- Button label shows current direction arrow (ArrowUp/ArrowDown)
- Persistence updated to store {option, direction} with backward compat
  for old string-only preferences
- Default directions: modified/created=desc, title/status=asc
- Status sort tiebreaker always uses newest-first regardless of direction

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 08:35:30 +01:00
lucaronin
077330ec18 fix: resolve pre-existing TS errors in wikilinks.test.ts
Added AnyBlock type alias to cast injectWikilinks() return type in tests.
The function returns unknown[] but tests access .content, .props, .text
properties — this was already broken before this branch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 08:34:14 +01:00
lucaronin
659ca5990f fix: resolve all ESLint errors, enforce lint in CI 2026-02-22 14:31:02 +01:00
lucaronin
8cb382e3a3 fix: resolve React hooks/compiler ESLint errors
- Wrap ref assignments in useEffect to fix refs-during-render in
  useTabManagement, useKeyboardNavigation, and Editor
- Rewrite useAppKeyboard to define keyMap inside useEffect, eliminating
  ref access during render
- Add eslint-disable for react-hooks/set-state-in-effect on legitimate
  dialog reset patterns (CommitDialog, CreateNoteDialog, CreateTypeDialog,
  QuickOpenPalette, AIChatPanel, useVaultLoader)
- Add eslint-disable for react-hooks/static-components on icon lookups
  (NoteItem, NoteList PinnedCard) — stateless icon components from a
  static map
- Add eslint-disable for react-hooks/purity on Date.now() in
  NoteItem TrashDateLine — intentionally memoized on trashedAt
- Remove unused `model` param from buildSystemPrompt (ai-chat.ts) and
  update callers
- Fix exhaustive-deps: suppress vault object dep in App.tsx git history
  effect (vault object is unstable, loadGitHistory is the real dep)
- Remove unused `modifiedFiles` from useNoteListData params and caller
- Add missing `ref` to Sidebar useOutsideClick deps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 14:06:51 +01:00
lucaronin
8e49af2c0e fix: replace no-explicit-any with proper types
- 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>
2026-02-22 13:10:26 +01:00
lucaronin
a77d5ff451 fix: simple ESLint errors — regex, unused vars, unused expressions
- eslint.config.js: ignore coverage/ directory (generated files)
- frontmatter.ts: no-regex-spaces — use {2} instead of literal spaces
- wikilinks.ts: no-useless-escape — remove unnecessary \[ escape
- ai-chat.ts: remove unused _model param from getContextLimit
- noteListHelpers.ts: remove unused _modifiedFiles param from filterEntries
- NoteList.tsx: replace ternary expression statement with if/else
- useTabManagement.ts: remove stale eslint-disable-next-line comment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 13:08:16 +01:00
lucaronin
63c3bc3b1f test: add wikilinks.ts unit tests — preProcess, inject, splitFrontmatter, countWords
22 tests covering:
- preProcessWikilinks: single/multiple/pipe alias/nested wikilinks
- injectWikilinks: text expansion, nested children, no-content blocks
- splitFrontmatter: with/without frontmatter, unclosed frontmatter
- countWords: with frontmatter, markdown stripping, empty/whitespace

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 12:02:29 +01:00
lucaronin
65d1c753ef refactor: improve code health across 6 more files
- DynamicPropertiesPanel.tsx: extract PropertyValueCell, TypeRow, AddPropertyForm (9.06 → 9.68)
- useKeyboardNavigation.ts: extract classifyShortcut and useLatestRef (9.09 → 9.63)
- frontmatter.ts: extract parseScalar, parseInlineArray, isBlockScalar helpers (9.24 → 9.6)
- StatusBar.tsx: extract VaultMenu and VaultMenuItem components (9.23 → 10.0)
- useVaultLoader.ts: extract tauriCall helper and loadVaultData (9.35 → 10.0)
- useNoteActions.ts: extract resolveNewNote, resolveNewType, executeFrontmatterOp (9.22 → 9.38)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 10:55:45 +01:00
lucaronin
af94280e4d refactor: decompose NoteList into focused components and extract helpers
Break up NoteListInner (cc=61, 331 LoC, score 6.94) into:
- NoteItem: extracted item rendering component (score 9.63)
- SortDropdown: extracted into own file (score 9.68)
- noteListHelpers.ts: all utility functions (score 10.0)
  - GroupBuilder class replaces 5-arg addResolvedGroup
  - filterEntries split into filterByKind/filterByFilterType
- PinnedCard: unified entity/type document cards
- RelationshipGroupSection: extracted group rendering
- NoteList.tsx: orchestration only (score 8.79)

NoteListInner reduced from cc=61 to cc=23, 331 → 105 LoC.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 10:18:05 +01:00
lucaronin
b1e15dd5ea feat: implement icon & color customization for types
- Add TypeCustomizePopover component with color swatches (6 accent colors)
  and icon grid (35 curated Phosphor icons)
- Add right-click context menu on sidebar section group headers with
  "Customize icon & color…" option
- Sidebar renders custom icons/colors from type entry frontmatter
- NoteList uses custom icons/colors for type badges and pinned cards
- Wire up onCustomizeType in App.tsx to update type frontmatter
- Add updateEntry to useVaultLoader for instant in-memory updates
- Add --accent-orange-light CSS variable
- typeColors utility now accepts optional custom color key overrides

Product decision: Built-in types can also be customized (override their
defaults), not just custom types. The picker is a simple popover that
appears after right-click → "Customize icon & color…".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:27:33 +01:00
lucaronin
5f2a6495db feat: AI chat panel 2026-02-21 10:38:41 +01:00
lucaronin
388160998f Merge task/create-from-sidebar: Create new items from sidebar 2026-02-21 09:17:30 +01:00
lucaronin
6fd145702e fix: resolve pre-existing TypeScript build errors
- 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>
2026-02-20 23:49:22 +01:00
lucaronin
bca6b3c8e8 docs: AI chat architecture + fix pre-existing build errors
Update docs/ARCHITECTURE.md with:
- AI Chat system architecture (context picker, streaming, MCP)
- WebSocket bridge protocol
- New files listing and data flow diagrams
- Updated tech stack table

Update mock-tauri.ts with richer AI chat mock responses
(context-aware summarize, expand, grammar responses).

Fix pre-existing TypeScript build errors:
- Add missing snippet/relationships to test VaultEntry fixtures
- Fix string|null → string type mismatches in Sidebar, NoteList, Inspector
- Remove unused imports (cn in Editor, AIChatPanel in App)
- Fix tryParseMarkdownToBlocks Promise cast

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 23:07:10 +01:00
lucaronin
f4ca64f229 feat(ai-chat): context picker + Anthropic API
Rewrite AIChatPanel with:
- Context picker: current note auto-added, search to add more notes,
  removable context pills, token estimation badge
- Real Anthropic API integration via Vite dev server proxy (SSE streaming)
- API key stored in localStorage, configurable via dialog
- Model selector: Haiku 3.5, Sonnet 4, Opus 4
- Mock fallback when no API key is configured
- Extracted useAIChat hook and ai-chat utilities for clean separation

Decision: Using Vite middleware proxy for dev mode to avoid CORS issues
with direct browser-to-Anthropic calls. Phase 2 will add Rust backend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:52:56 +01:00
lucaronin
2a564578a8 feat(ui): add Type color, icon, and sidebar section group
- Add Type to color maps (accent-blue) in typeColors.ts
- Add StackSimple icon for Type in NoteList, Inspector, and Sidebar
- Add "Types" section group to sidebar navigation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:45:54 +01:00
lucaronin
952d8afd05 feat: add shared type color utility for note type→color mapping
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:16:47 +01:00
lucaronin
f9d9bdabf7 refactor: decompose Inspector.tsx into EditableValue, DynamicPropertiesPanel, and frontmatter utils 2026-02-17 12:12:32 +01:00
lucaronin
e805970c17 refactor: extract wikilink utils and DiffView from Editor.tsx 2026-02-17 12:08:03 +01:00