Commit Graph

129 Commits

Author SHA1 Message Date
lucaronin
692bc8edc4 feat: move properties icon to toolbar when inspector panel is closed 2026-02-21 13:16:31 +01:00
lucaronin
fb31c78efd feat: move properties icon to toolbar when panel is closed
When the inspector panel is collapsed, the SlidersHorizontal icon now
appears inline with the other BreadcrumbBar toolbar icons (search, diff,
cursor, AI, more) with no visual separator. The collapsed Inspector
sidebar is no longer rendered — clicking the toolbar icon reopens it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 13:16:05 +01:00
lucaronin
cdf203de1a fix: use stable asset URLs for image uploads (blob URL fix) 2026-02-21 13:08:29 +01:00
lucaronin
deea70a098 fix: use stable asset URLs for image uploads instead of ephemeral blob URLs
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>
2026-02-21 13:06:04 +01:00
lucaronin
e02db50533 fix: use blob URLs for image uploads instead of data URLs
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>
2026-02-21 11:00:41 +01:00
lucaronin
827ec42d6c feat: add keyboard navigation between tabs and notes
- 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>
2026-02-21 10:50:50 +01:00
lucaronin
5f2a6495db feat: AI chat panel 2026-02-21 10:38:41 +01:00
lucaronin
4b843f94f6 feat: Allow to create new types 2026-02-21 10:32:36 +01:00
lucaronin
db1da4430e fix: wire up BlockNote uploadFile to enable image uploads in editor
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>
2026-02-21 10:07:02 +01:00
lucaronin
5ec9af98c5 test: add tests for create type dialog and dynamic sidebar sections
- CreateTypeDialog: 8 tests covering open/close, validation, submit, cancel
- Sidebar dynamic sections: 5 tests covering custom type rendering,
  instance display, + button behavior, and built-in type deduplication

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 09:42:45 +01:00
lucaronin
170de2a7e0 feat: implement create new type feature
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>
2026-02-21 09:41:46 +01:00
lucaronin
4e4cffe6a3 fix: ensure editor has full width regardless of title/content length
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>
2026-02-21 09:39:37 +01:00
lucaronin
e739ae0028 feat: add custom type mock data (Recipe, Book) with instances
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>
2026-02-21 09:38:55 +01:00
lucaronin
388160998f Merge task/create-from-sidebar: Create new items from sidebar 2026-02-21 09:17:30 +01:00
lucaronin
f0c5461fba test: add tests for sidebar + button create-from-type feature
- 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>
2026-02-20 23:50:12 +01:00
lucaronin
89e5a2eb79 feat: add + button to sidebar section groups for quick note creation
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>
2026-02-20 23:49: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
53558c2cbe fix(notelist): exclude Type from relationship groups
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>
2026-02-20 23:43:39 +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
2286385244 fix: resolve TypeScript build errors across components
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>
2026-02-20 22:02:04 +01:00
lucaronin
9a2f7f0370 feat(inspector): make Type property a clickable navigation chip
The Type field in the Inspector's properties panel is now a colored
clickable chip (styled like relationship chips) that navigates to the
type document when clicked. The "Type" key is also excluded from the
relationships panel to avoid duplication.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:49:55 +01:00
lucaronin
d0370731a6 feat(notelist): add Instances group for type documents in entity view
When viewing a type document (e.g., type/project.md) in entity view,
show an "Instances" relationship group listing all entries of that
type. For example, the Project type document shows all projects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:48:15 +01:00
lucaronin
05c840d6cf feat(notelist): pin type document at top in section group view
When viewing a section group (e.g., Projects), the corresponding type
document (type/project.md) is now pinned at the top of the NoteList
as a prominent card. Clicking it navigates to the type document.
Instances of that type are listed below.

This makes the type document the entry point for each category,
reinforcing the "types are files" mental model.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:47:42 +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
1050a10403 refactor: extract BreadcrumbBar component from Editor.tsx
Moves breadcrumb bar with action icons into a dedicated memoized
component. Editor.tsx now scores 10.0 code health.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:58:14 +01:00
lucaronin
647421b3a7 refactor: extract TabBar component from Editor.tsx
Reduces Editor component LoC by ~80 lines and lowers cyclomatic
complexity. TabBar is now a memoized presentational component.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:57:03 +01:00
lucaronin
399b8b58a0 feat: add mock AI chat panel
Replaces Inspector panel when activated via Sparkle button in editor
info bar. Includes context pills, message list with typing indicator,
quick action pills (Summarize/Expand/Fix grammar), model selector,
and mock responses with 1200ms delay. E2E test covers full flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 16:06:51 +01:00
lucaronin
0053eb3009 feat: UI polish — typography, layout, and sidebar fixes
- font-mono-label: font-weight 500, remove letter-spacing
- NoteList: move timestamp below snippet in note items
- Sidebar: add border-r with sidebar-border color
- ResizeHandle: overlap sidebar border with -ml-1 (no visible gap)
- Sidebar items: text-muted-foreground for inactive group items
- NoteList: uniform 14px vertical padding across all note items
- NoteList header: fixed height 45px to match tab bar
2026-02-18 10:52:01 +01:00
lucaronin
b4d6dc8d55 feat: remove redundant RELATIONSHIPS heading from Inspector
The relationship groups (BELONGS_TO, RELATED_TO, etc.) are self-evident;
an extra section heading was visual clutter. Removed from both the active
Inspector and EmptyInspector.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 22:48:20 +01:00
lucaronin
6643b8db8f feat: remove duplicate PROPERTIES section heading from Inspector
The panel title already says "Properties" — the section heading was
redundant. Removed from both DynamicPropertiesPanel and EmptyInspector.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 22:47:49 +01:00
lucaronin
c68b60c207 feat: color-code Inspector relationship items with type icons
Relationship and backlink items now use getTypeColor/getTypeLightColor
for text and background colors based on the linked note's type. Text
type labels replaced with Phosphor icons matching the NoteList/Sidebar
icon mapping (Wrench=Project, Tag=Topic, Users=Person, etc.).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:59:15 +01:00
lucaronin
6c63abc9c5 feat: reduce font weight of sidebar entity items to 400
Section group headers and nav items stay at font-weight 500 (medium).
Individual entity items under sections now use font-weight 400 (normal)
to create better visual hierarchy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:57:31 +01:00
lucaronin
45a6d8800a feat: move timestamp below title in NoteList items
Title now takes full width on top, with timestamp displayed below
in 10px muted text, followed by the snippet. Applies to both flat
list and context view items.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:56:41 +01:00
lucaronin
f30733932a feat: apply IBM Plex Mono to labels per design spec
Update NoteList group headers (RELATED NOTES, EVENTS, etc.) to use
font-mono-label class with bg-muted background bar per design.

Update Inspector section titles (Properties, Relationships, Backlinks,
History) and property labels (Type, Status, Modified, Words) to use
font-mono-overline class. Update status badge to IBM Plex Mono with
border-radius 16px per design spec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:41:15 +01:00
lucaronin
2c4808851f fix: remove unused constants and fix BACKLINKS_KEY reference
Removes unused GROUP_PRIORITY and BACKLINKS_KEY constants, replaces
the reference with a string literal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:17:03 +01:00
lucaronin
63768d0a6b fix: handle wikilink aliases in resolveRefs and refsMatch
Strips the |display-text alias from wikilinks before matching (e.g.
[[essay/foo|Foo]] now correctly resolves to essay/foo.md). This was
preventing the Has, Topics, and other relationship groups from resolving
entries whose wikilink references included aliases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:16:19 +01:00
lucaronin
7da76688d2 feat: use generic relationships map in NoteList context view
Updates buildRelationshipGroups to use the new relationships map from
VaultEntry instead of only belongsTo/relatedTo. Now shows Has, Topics,
and all other wikilink-containing frontmatter fields as groups. Group
order: Has, Children, Events, Topics, other fields alphabetically,
Referenced By, Backlinks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:11:01 +01:00
lucaronin
f0a8f7d014 feat: implement context view in NoteList
When a note is selected from the sidebar (entity selection), NoteList
now shows a context view instead of a flat list:

- Prominent top card with type-colored background, bold title, snippet,
  timestamp, and type icon
- Grouped relationship sections (Children, Events, Referenced By,
  Belongs To, Related To, Backlinks) with collapse/expand chevrons
- Backlinks detected by scanning allContent for wikilink references
- Groups show ALL-CAPS headers with count and CaretDown/CaretRight toggle
- Normal flat list shown when sidebar selection is "All Notes"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:47:38 +01:00
lucaronin
484f0672b0 feat: add type icons to NoteList items
Add a small (14px) Phosphor icon in the top-right corner of each note
item, colored by type using getTypeColor(). Uses the same icon mapping
as Sidebar: Wrench=Project, Flask=Experiment, Target=Responsibility,
ArrowsClockwise=Procedure, Users=Person, CalendarBlank=Event,
Tag=Topic, FileText=Note (default).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:45:34 +01:00
lucaronin
1c0bb2a71c feat: remove type filter pills from NoteList
Remove the filter pills row ("All 12", "Projects 1", etc.) and all
associated filtering logic (typeFilter state, typeCounts memo, displayed
memo, TYPE_PILLS constant). The note list now always shows all notes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:44:03 +01:00
lucaronin
2eb0705f00 feat: show type label on relationship items in Inspector
Each related note in the Relationships section now displays the note
title on the left and the type label on the right.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:21:20 +01:00
lucaronin
3939ba1e97 feat: increase Inspector section spacing to 16px with flex gap
Replace individual mb-4 margins with a flex column gap-4 on the
container, ensuring consistent 16px spacing between Inspector sections.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:20:26 +01:00
lucaronin
444dd03ca6 refactor: use shared getTypeColor utility in Sidebar
Replace inline color strings in SECTION_GROUPS and the string-replace
hack for light colors with the shared typeColors utility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:18:41 +01:00
lucaronin
0f49886f4e feat: use dynamic type colors for active filter pills
Active filter pills now show the accent color matching the type they
represent, instead of hardcoded blue.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:17:50 +01:00
lucaronin
ebc77002d2 feat: use dynamic type colors for selected note in NoteList
The selected note's border-left and background now reflect the note's
type color instead of hardcoded blue.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 18:17:21 +01:00
lucaronin
02ff193988 fix: handle sync return from tryParseMarkdownToBlocks
The method returns blocks directly (not a Promise) in the current
BlockNote version, causing 'then is not a function' error.
2026-02-17 18:04:18 +01:00
lucaronin
408e23f572 fix: use prosemirrorView check for editor mount and simplify content swap 2026-02-17 18:00:18 +01:00
lucaronin
91659ad56b fix: editor content not displaying after single-instance refactor
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>
2026-02-17 17:56:57 +01:00
lucaronin
b239de3719 fix: prevent crash when opening notes
Move setActiveTabPath after tab content is loaded to prevent Editor's
useEffect from firing before the tab exists in the tabs array. Add
try/catch around editor.replaceBlocks for defensive error handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 17:52:10 +01:00