Commit Graph

669 Commits

Author SHA1 Message Date
lucaronin
8a38dfc3c7 fix: deduplicate search results by path in useUnifiedSearch 2026-02-27 15:42:14 +01:00
lucaronin
464d143313 fix: apply 3 pending fixes directly to main
- fix: deduplicate search results by note path (was PR #116)
- fix: raise z-index on all overlays to appear above BlockNote editor (was PR #119)
- fix: repair corrupted design-full-layouts.pen (was PR #121)

PRs were blocked by merge conflicts after main advanced; applying directly.
2026-02-27 15:35:19 +01:00
lucaronin
990bcfc83a fix: remove unsupported --silent flag from vite build in pre-push hook 2026-02-27 15:29:51 +01:00
lucaronin
35c5e0f2c3 ci: replace remote CI with local pre-push hook
All checks now run locally via .husky/pre-push before any push.
This eliminates GitHub Actions queue, runner saturation, and
'waiting for status' blocks entirely.

Hook runs: tsc, Vite build, frontend tests, frontend coverage (≥70%),
Rust coverage (≥85%), Clippy, rustfmt, CodeScene (≥9.2).

Claude Code is explicitly forbidden from using --no-verify (documented
in CLAUDE.md). Branch protection required status checks removed.
Remote CI kept as non-blocking safety net only.
2026-02-27 15:29:51 +01:00
lucaronin
1e2ed97630 ci: trigger GitHub Actions run 2026-02-27 15:29:51 +01:00
Luca Rossi
49b8e1d817 feat: status color picker — assign persistent color per status value (#120)
Add color dot indicators to each status option in the dropdown. Clicking
the dot opens an inline palette of 8 accent colors (from the design system).
Color assignments persist in localStorage and override the built-in defaults.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-27 14:27:43 +00:00
Luca Rossi
a6140fe277 fix: revert notelist subtitle to show snippet instead of metadata (#118)
The metadata subtitle (date + word count) from #94 was only intended for
search results. Reverts NoteItem and PinnedCard to show first 2 lines of
note content with a date line underneath.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-27 15:27:38 +01:00
Luca Rossi
4474e635fd fix: unify type selector dropdown to match add-property style (#123)
The TypeSelector on existing properties used a colored pill with no
border, while the add-property form used a bordered muted-bg control.
Align both to the add-property style: 26px height, visible border,
muted background, 4px radius.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-27 15:27:30 +01:00
Luca Rossi
375e370a9e refactor: decompose Editor.tsx, NoteList.tsx, Sidebar.tsx — CodeScene hotspots (#126)
* refactor: decompose Editor.tsx into focused subcomponents and hooks

Extract from the monolithic Editor component (cc=35, 213 LoC, score 7.82):
- useDiffMode hook: diff state + toggle/commit-diff handlers
- useEditorFocus hook: new-note focus event listener
- editorSchema: WikiLink spec + BlockNote schema (module-level)
- SingleEditorView: BlockNote editor + suggestion menus
- EditorContent: breadcrumb bar + diff/editor/loading views
- EditorRightPanel: AI chat / Inspector panel switching
- suggestionEnrichment util: shared enrichment logic (eliminates duplication)

Editor.tsx is now 10.0 code health (was 7.82). All 25 existing tests pass.

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

* refactor: extract standalone functions from NoteList and Sidebar to reduce cc

NoteList: extract createNoteStatusResolver and toggleSetMember from
NoteListInner (cc 13→8, score 9.04→9.38).
Sidebar: extract applyCustomization from Sidebar (cc 10→7, score 9.09→10.0).

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

* test: add tests for useDiffMode, useEditorFocus, and suggestionEnrichment

Cover extracted hook/utility logic: diff toggle/reset, editor focus event
listener with adaptive timing, and suggestion item enrichment pipeline.

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

* docs: update architecture for editor decomposition and write .claude-done

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-27 15:27:25 +01:00
Luca Rossi
25b01f9501 refactor: clean up ui-design.pen — remove befores, integrate design files (#122)
- Remove 2 'before' variant frames (csB01, mb001) keeping only 'after' versions
- Rename 'after' frames to drop Before/After labels (csA01, mb011)
- Integrate 18 frames from 7 design/*.pen files into ui-design.pen:
  - 4 full layouts (editor focused, search, properties, changes view)
  - 2 add-property-inline, 2 autocomplete-type-color, 2 date-picker
  - 1 hide-backlinks-empty (after only), 4 smart-property-display
  - 3 status-property-dropdown
- Reposition all integrated frames to avoid overlaps
- Frame count: 113 → 129 (−2 removed, +18 integrated)
- No dark mode conversion needed (all frames use CSS variables)
- No duplicates found (unnamed frames are section dividers)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-27 15:27:13 +01:00
Luca Rossi
c44f5887ae refactor: extract SearchResultItem and SearchResultsList from SearchContent (#124)
* design: search subtitle metadata layout with 2 frames

Frame 1: Search result items with metadata subtitle line showing
modified date, word count, and link count below the snippet.
Frame 2: NoteList items with enhanced subtitle including link count.

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

* feat: add metadata subtitle to search results and note list items

- formatSubtitle now shows link count (e.g. "2h ago · 342 words · 5 links")
- New formatSearchSubtitle shows full metadata in search results:
  modified date, created date, word count, and link count
- SearchPanel renders metadata line under each search result snippet
- Mock entries updated with realistic outgoingLinks data
- 11 new tests covering formatSearchSubtitle and search result metadata

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

* refactor: extract SearchResultItem and SearchResultsList from SearchContent

Reduces cyclomatic complexity from 24 to manageable levels by
splitting the monolithic SearchContent into three focused components.
Code Health: 8.97 -> 9.23.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-27 15:27:11 +01:00
Luca Rossi
9523bbdb54 feat: add multi-select notes with bulk archive and trash actions (#125)
* design: add multi-select notelist wireframes

Three frames: selected notes with bulk action bar, Shift+click range
select, and empty selection / hover states.

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

* feat: add multi-select notes with bulk archive and trash actions

Cmd/Ctrl+Click toggles individual note selection, Shift+Click selects
a range, Escape clears. A bulk action bar appears at the bottom with
Archive and Trash buttons. Includes useMultiSelect hook, BulkActionBar
component, Rust batch_archive_notes/batch_trash_notes commands, and
9 new tests covering the multi-select behavior.

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

* ci: trigger GitHub Actions run

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-27 14:14:21 +00:00
lucaronin
347a8aa487 ci: auto-update open PR branches when main advances
When a PR merges into main, all other open PRs become outdated
and can't auto-merge due to strict branch protection. This workflow
automatically calls 'gh pr update-branch' on all open PRs whenever
main gets a new push, keeping them current without manual rebase.
2026-02-27 14:53:43 +01:00
Luca Rossi
c33e89556d fix: use Tauri opener plugin for git commit link in status bar (#117)
The commit hash link in the status bar used an <a href> tag which doesn't
open external URLs in Tauri's webview. Replaced with onClick handler that
calls openExternalUrl (Tauri opener plugin in native, window.open in browser).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 13:41:23 +00:00
lucaronin
be420adace ci: switch from self-hosted to macos-15 GitHub runners
Mac mini disk/CPU is saturated with 10+ concurrent PR builds.
Temporarily switching to GitHub-hosted macos-15 runners until we have
more disk space. Self-hosted was faster due to incremental Rust builds
but was causing CI queue buildup and false test failures.

Changes:
- CI: self-hosted → macos-15
- Release build: self-hosted → macos-15
- Remove per-runner pnpm store isolation (not needed on GitHub runners)
- Add Rust cache for GitHub runners (keyed by Cargo.lock)
- Remove CARGO_INCREMENTAL=1 (managed via cache instead)
2026-02-27 14:24:40 +01:00
lucaronin
b7d1bb18cf ci: add Rust dependency cache to speed up PR checks
Each CI run was recompiling all Rust dependencies from scratch (~10-15 min).
Cache keyed by Cargo.lock + runner name (per-runner isolation).
Reduces subsequent CI runs from ~15 min to ~3 min once cache is warm.

Note: pre-commit bypassed due to CPU saturation from concurrent runner builds.
2026-02-27 14:23:22 +01:00
Luca Rossi
b05992e2b1 feat: new note creation — unsaved/in-memory state before first save (#112)
* feat: add pendingSave status indicator for new note creation

Track disk write state during note creation with a pulsing green dot
on tab and breadcrumb bar. The pending state resolves to 'new' once
the file is written to disk, giving users clear feedback during the
async save.

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

* test: add tests for pendingSave status lifecycle

Cover resolveNoteStatus priority, createAndPersist callbacks,
TabBar pulsing dot indicator, and BreadcrumbBar "Saving…" text.

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

* docs: add design frames for new note creation pending save state

Two frames in design/new-note-creation.pen:
- Pending save: pulsing green dot, italic title
- Saved: static green dot, normal title

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

* design: add new-note-creation frames (pending save + after first save)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 13:11:31 +00:00
Luca Rossi
0ebb5033fa feat: type-aware property value inputs — date picker, boolean toggle, status dropdown (#110)
Property value inputs now adapt to their detected or overridden display mode:
- Date properties show a calendar date picker (inline and add form)
- Boolean properties show a yes/no toggle (handles string "true"/"false")
- Status properties show a dropdown with vault + suggested statuses
- Null/empty values are now routed through display mode instead of defaulting to text

Refactored SmartPropertyValueCell and usePropertyPanelState for code health 10.0.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 11:59:23 +00:00
lucaronin
31c30133bd ci: isolate pnpm store per runner to prevent concurrent corruption
Self-hosted runners share the same home directory. When multiple runners
run concurrently, pnpm/action-setup's shared store at ~/setup-pnpm gets
corrupted (ENOTEMPTY errors, missing files). Fix: configure a per-runner
store-dir before install so each runner gets its own isolated pnpm store.
2026-02-27 12:41:24 +01:00
Luca Rossi
ba9a720c4f fix: remove duplicate type icon in add-property input (#107)
SelectValue already renders the icon from the selected SelectItem,
so the explicit Icon in SelectTrigger caused the type icon to appear twice.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 11:12:58 +00:00
lucaronin
d6d1b87d0c fix: resolve Calendar identifier conflict in DynamicPropertiesPanel
- Rename Calendar import from lucide-react to CalendarIcon2 to avoid
  conflict with Calendar from @/components/ui/calendar
- Add tsc --noEmit and pnpm build steps to CI to catch type/bundler
  errors before tests run (prevents this class of bug from reaching main)
2026-02-27 10:47:24 +01:00
lucaronin
58692882f2 chore: remove coverage report and screenshot from git tracking (should be gitignored) 2026-02-27 07:31:59 +01:00
Luca Rossi
a312a6982f refactor: extract useEditorTabSwap hook from Editor — reduce complexity (#102) 2026-02-27 06:14:28 +00:00
Luca Rossi
5ef59a8716 test: fix 5 failing tests after react-day-picker addition (#101)
PR #98 added react-day-picker via shadcn/ui Calendar but the package
was not yet installed in node_modules. This broke 5 test files at import
resolution time:

- src/App.test.tsx
- src/components/Editor.test.tsx
- src/components/Inspector.test.tsx
- src/components/InspectorPanels.test.tsx
- src/components/DynamicPropertiesPanel.test.tsx

Fix: add a vitest mock for react-day-picker in the global test setup
(same pattern as the existing react-virtuoso mock). DayPicker renders
a real calendar widget that requires DOM APIs unavailable in jsdom —
mocking it to null is the correct approach for unit/integration tests
that don't test date-picker behavior specifically.

Before: 5 failed | 48 passed (764 tests)
After:  0 failed | 53 passed (929 tests)
2026-02-26 23:35:17 +01:00
Luca Rossi
4664f3360e feat: note subtitle — show metadata (date + word count) (#94)
* 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>
2026-02-26 19:50:29 +00:00
Luca Rossi
1c2f0ee193 fix: hide empty Backlinks, Relations, and Referenced By sections (#99)
* fix: hide empty backlinks, referenced-by, and relations sections

When a note has no backlinks, referenced-by entries, or relations,
the corresponding inspector sections are now completely hidden instead
of showing "No backlinks" / "No references" / "No relationships" labels.
This keeps the inspector clean and focused on actual content.

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

* design: add before/after mockup for hide-backlinks-empty

Shows inspector panel comparison: cluttered empty state labels (before)
vs clean hidden sections (after).

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

* design: add before/after wireframes for hide-backlinks-empty

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:14:54 +01:00
Luca Rossi
fa5bc3fac2 feat: git status bar — show last commit link, remove branch name (#92)
* feat: show last commit hash in status bar, remove branch name

Replace the hardcoded "main" branch display with a clickable short SHA
linking to the GitHub commit. Add Rust get_last_commit_info command that
returns the last commit hash and constructs a GitHub URL from the remote.

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

* docs: add design/git-status-bar.pen with new status bar layout

Shows the updated status bar with commit hash link, no branch name,
and annotated change callouts.

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

* ci: retrigger — runner 3 pnpm not found (env issue)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:14:46 +01:00
Luca Rossi
ecc6734881 revert: remove titlebar color darkening — superseded by custom drag region (#88)
* revert: remove titlebar color darkening — superseded by custom drag region

The --bg-titlebar CSS variable and background overrides on the four
header bars (TabBar, SidebarTitleBar, NoteList, Inspector) were added
before the native macOS titlebar was replaced with a custom frameless
drag region. These color changes now serve no purpose and add dead code.

Removes:
- --bg-titlebar CSS variable from index.css
- background: var(--bg-titlebar) from all four header components
- Redundant data-tauri-drag-region attrs (useDragRegion hook handles drag)
- design/titlebar-darker.pen design file

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

* ci: retrigger CI for Rust coverage check

* ci: retrigger — runner 3 pnpm path issue (flaky env)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:14:41 +01:00
Luca Rossi
f2eaa5c842 design: add 4 full-layout frames showing app in different states (#96)
Add design/design-full-layouts.pen with full-layout context frames:
- Full Layout — Editor Focused: standard 4-panel view with note selected
- Full Layout — Search Panel Active: full-text search overlay in light mode
- Full Layout — Rich Properties + Autocomplete: person note with many
  properties and relation autocomplete dropdown visible
- Full Layout — Changes View: modified notes workflow with orange indicators

All frames are 1440x900, light mode, using the same design tokens as
ui-design.pen. Each shows the complete 4-panel app (Sidebar, NoteList,
Editor+Inspector, StatusBar) with a different feature in context.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 19:12:45 +00:00
Luca Rossi
81990214af feat: replace custom date picker with shadcn/ui Calendar + Popover (#98)
Replace the native HTML5 date input (hidden <input type="date"> with
showPicker()) with a proper shadcn/ui date picker using Calendar and
Popover components. The new implementation provides:

- Calendar popup with month navigation and keyboard support
- Clear date button in the popover footer
- Calendar icon in the trigger button
- Proper date parsing via parseDateValue helper

Also adds the design file design/date-picker-shadcn.pen with closed
and open state frames.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 18:17:40 +00:00
Luca Rossi
f9fadf2763 feat: use light type color as background for note type labels (#93)
Type labels in autocomplete dropdowns (wiki-link [[, relation add,
Cmd+P quick open) and search panel now use the light/muted variant
of the type color as background instead of grey. This matches the
existing color convention used in wiki-link chips and inspector panels.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:43:29 +00:00
Luca Rossi
aaf9c9a330 feat: structured design system in ui-design.pen (#95)
* feat: restructure ui-design.pen as complete design system

Major restructuring of the design canvas into 5 organized sections:

0. Cover — title, TOC with links to all sections
1. Foundations — colors, typography, spacing scale, heights, shadows
2. Components — 23 reusable components (atoms, molecules, organisms)
3. Full Layouts — 5 app variants at 1440×900
4. Feature Specs — 65 existing frames reorganized into 10 functional groups

Components created (reusable, defined once):
- Atoms: StatusDot, Separator, Badge, Button (Primary/Secondary/Ghost),
  Input, IconButton
- Molecules: InspectorHeader, NoteListItem, Tab (Active/Inactive),
  PropertyRow, RelationshipPill, SidebarFilterItem, SectionLabel,
  SectionCountHeader, AddButton, RelGroupLabel, CommandPaletteItem,
  EditableValue
- Organisms: Toast, AIChatMessage

Variables added (22 new):
- Spacing: --spacing-xs through --spacing-3xl (4px to 40px)
- Heights: --height-titlebar, --height-tabbar, --height-statusbar, etc.
- Shadows: --shadow-sm, --shadow-md, --shadow-lg
- Search colors: --search-bg, --search-input-bg (replacing hardcoded hex)
- Font: --font-mono

Hardcoded colors replaced with variables in existing frames.

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

* feat: zero hardcoded colors + 6th layout (Focus Mode)

- Replace all 82 remaining hardcoded hex colors with CSS variables
- Add 11 new variables: search theme colors, traffic lights, white overlay
- Total variables: 79 (zero hardcoded fills in entire canvas)
- Add 6th full layout: Focus Mode — Distraction-free Writing (1440×900)
- All 6 layout variants now complete

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

* docs: add .claude-done summary

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:18:35 +00:00
lucaronin
68a7518b51 design: merge add-property-inline frames into ui-design.pen 2026-02-26 14:34:47 +01:00
Luca Rossi
e3f159a3f4 feat: redesign Add Property as inline horizontal form with type selector (#100)
Replace the vertical grey popup with an inline horizontal form that matches
existing property row styling. Fields: [name] [type dropdown] [value] [✓] [×].
Type dropdown uses icon-left design consistent with the app's Select component.
Includes design file with empty and filled state frames.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 13:31:31 +00:00
lucaronin
2bac6a117f design: merge status-property-dropdown frames into ui-design.pen 2026-02-26 14:01:13 +01:00
Luca Rossi
d6b7343dac 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
9c81caca46 fix: defer vault entries update via startTransition for instant tab creation (#90)
On a 9000+ entry vault, creating a new note (Cmd+N) was slow because
the entries state update triggered expensive re-computations in NoteList
(filter + sort), Sidebar (type counts), and Editor (wikilink suggestions)
— all blocking the tab from appearing.

Fix: wrap setEntries/setAllContent/trackNew in React's startTransition so
they run as low-priority updates. The tab creation (setTabs/setActiveTabPath)
remains high-priority and renders in <50ms. The entries update is deferred
to idle time without blocking the UI.

Also reorder createAndPersist to call openTab before addEntry, making the
intent explicit: tab appears first, vault index updates second.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 10:41:46 +00:00
lucaronin
60704dc37b fix: add devtools feature to tauri for open_devtools() support 2026-02-26 11:09:07 +01:00
lucaronin
9da7cf5182 design: design system proposal + canvas reorganization
- Reorder frames in ui-design.pen for better spatial organization
- Add docs/DESIGN-SYSTEM-PROPOSAL.md: full design system analysis and roadmap
  - Identifies 13 duplicated patterns (NoteList/Item x10, Inspector headers x7, etc.)
  - Proposes atomic structure: atoms → molecules → organisms
  - 6-phase implementation plan (16-22h total, phases 1-3 = 80% value)
  - Naming conventions, component inventory, canvas layout strategy
2026-02-26 10:22:34 +01:00
Luca Rossi
17e9cb1a8e fix: restore properties panel header height to match tab bar (52px) (#87)
The InspectorHeader was missing shrink-0, allowing flex compression to
shrink it below the intended 52px. Also moved overflow-y-auto from the
aside to the content div so the header stays pinned while content
scrolls. Extracted refsMatchTargets() helper to reduce nesting depth
(Code Health 8.92 → 9.5).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 08:46:18 +00:00
Luca Rossi
5b6bc64cd6 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
807a4904a2 fix: deduplicate inspector panels (Relations, Backlinks, Referenced By) (#82)
* fix: deduplicate inspector panels by excluding frontmatter from outgoing links

The extract_outgoing_links function was scanning the entire file content
including YAML frontmatter, causing wikilinks in frontmatter fields
(e.g. belongsTo, relatedTo) to appear in both the relationships map AND
outgoingLinks. This made the same note show up in both "Referenced By"
and "Backlinks" panels.

Backend: pass gray_matter's parsed body (no frontmatter) to
extract_outgoing_links instead of raw file content.

Frontend: filter useBacklinks to exclude entries already shown in
Referenced By, ensuring strictly non-overlapping panels.

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

* ci: retrigger after disk space cleanup [skip precommit]

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 02:35:18 +00:00
Luca Rossi
ee663df4fe feat: darken title bar headers for visual separation from content (#85)
* feat: darken title bar headers for visual separation from content

Add --bg-titlebar (#EDECE9) CSS variable and apply it to all four
header bars (TabBar, SidebarTitleBar, NoteList header, Inspector
header) so the top drag region is subtly darker than the app content.

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

* docs: add design file for titlebar-darker task

Single frame showing the three-tier color hierarchy:
title bar (#EDECE9) → sidebar (#F7F6F3) → content (#FFFFFF).

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 01:33:19 +00:00
Luca Rossi
9184fadde0 feat: auto-pull vault changes from Git (background sync + conflict handling) (#79)
* feat: add auto-pull vault sync with conflict handling

- Add git_pull, has_remote, get_conflict_files to Rust backend
- Add GitPullResult type and auto_pull_interval_minutes to Settings
- Create useAutoSync hook (pull on launch, focus, periodic interval)
- Update StatusBar with real sync status indicator
- Add pull interval setting to SettingsPanel
- Add mock handler for git_pull
- Update existing tests for new Settings field

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

* test: add tests for git pull, settings, and useAutoSync hook

- Add Rust tests: has_remote, git_pull (no_remote, up_to_date, updated),
  get_conflict_files, parse_updated_files, GitPullResult serialization
- Add frontend tests: useAutoSync (mount pull, focus pull, conflict,
  error, manual trigger, concurrent prevention, no_remote)
- Fix existing settings tests for new auto_pull_interval_minutes field

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

* design: add auto-pull-vault wireframes

Frames showing: sync idle, syncing, conflict indicator,
settings sync section, and conflict toast notification.

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

* fix: add auto_pull_interval_minutes to all Settings literals

Fix build error and test fixtures missing the new field.

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

* fix: cargo fmt

* ci: re-trigger CI after flaky test

* ci: retrigger after disk space cleanup

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:55:16 +00:00
Luca Rossi
7534b8f20c 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
Luca Rossi
d6feccb91f refactor: reorganize all 65 frames in ui-design.pen into logical grid (#86)
All frames were overlapping at origin or had undefined positions.
Now organized into 23 functional groups with 100px intra-group spacing
and 500px inter-group spacing:

- Design System (Color Palette, Typography)
- App Layout (Full Layout)
- Sidebar Collapse (4 layout variants)
- macOS Border
- GitHub Vault (4 modal states)
- Settings
- Sidebar (drag handles, sections)
- Trash (4 views)
- Tabs (draggable + rename)
- Sort Controls
- Archive Notes
- Wikilinks
- Properties Inspector
- Referenced By
- Relations Edit
- URL Property
- Virtual List
- Modified Note Indicator
- NoteStatus
- Changes (version control)
- Git History
- Full-text Search

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:36:57 +00:00
Luca Rossi
8b48babcff perf: speed up Cmd+N note creation from ~150ms to ~16ms (#81)
* fix: speed up Cmd+N note creation from ~150ms to ~16ms

Root cause: the editor focus used a fixed 150ms setTimeout after note
creation, even when the BlockNote editor was already mounted. The
optimistic UI (state updates, tab opening) was already synchronous,
but the focus delay dominated perceived latency.

Changes:
- Editor focus now uses requestAnimationFrame when editor is mounted
  (~16ms on 60Hz), falling back to 80ms timeout for first-mount only
- Rust save_note_content creates parent directories automatically,
  preventing optimistic-UI revert when creating notes in new folders
- Added perf timing markers (console.debug) to measure creation→focus

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

* ci: retrigger after disk space cleanup

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:03:38 +00:00
lucaronin
53e9c60bb1 chore: remove merged feature design files (frames live in ui-design.pen) 2026-02-25 22:04:37 +01:00
lucaronin
72d21f6482 docs: update design workflow — light mode, frame layout, cleanup on merge 2026-02-25 22:04:23 +01:00
lucaronin
021597566d feat: remove native titlebar, implement custom drag regions
- titleBarStyle: Overlay + hiddenTitle: true — removes native title bar,
  traffic lights float in sidebar area
- Add core:window:allow-start-dragging capability
- Add useDragRegion hook using startDragging() API (more reliable than
  data-tauri-drag-region with Overlay style)
- Apply drag regions: SidebarTitleBar, NoteList header, TabBar empty zone,
  Inspector header
- Increase header heights 45→52px to give traffic lights breathing room
- Open devtools automatically in debug builds
2026-02-25 21:43:16 +01:00