Commit Graph

24 Commits

Author SHA1 Message Date
lucaronin
2fb14f4c35 fix: disambiguate sidebar type visibility by vault 2026-05-24 14:18:17 +02:00
lucaronin
7709ad1002 fix: recover missing note frontmatter writes 2026-05-23 14:41:11 +02:00
lucaronin
5965d5f23f fix: clear codacy object injection highs 2026-05-07 20:54:32 +02:00
lucaronin
41ee40d427 fix(type-actions): handle type filename collisions 2026-05-06 14:30:03 +02:00
lucaronin
11655c0283 fix: harden inbox auto-advance merge 2026-04-24 14:35:54 +02:00
lucaronin
d0c3a6b889 refactor: remove Trash system — delete is now permanent with confirm modal
Remove all vestiges of the abandoned Trash system: trashed/trashedAt fields
from types, frontmatter parsing, sidebar filtering, editor banners, inspector
components, mock data, and all related tests. Delete is already permanent via
useDeleteActions with a confirmation dialog. Notes with trashed:true in
existing vault frontmatter are now treated as normal notes (the flag is
ignored by the parser).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 12:21:56 +02:00
lucaronin
1145f4a572 feat: add organized toggle to breadcrumb bar and command palette
- CheckCircle button in breadcrumb bar toggles _organized property
- Green filled icon when organized, gray outline when not
- Command palette: "Mark as Organized" / "Mark as Unorganized"
- _organized hidden from Properties panel
- Handler follows favorite toggle pattern with optimistic updates

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 20:54:16 +02:00
lucaronin
cd3747c33a feat: implement PostHog event tracking plan
Add trackEvent() calls for all user actions in the tracking plan:
- Vault: vault_opened (with has_git, note_count), vault_switched
- Notes: note_created (with has_type, creation_path), note_deleted,
  note_trashed, note_archived, note_favorited, note_unfavorited
- Git: commit_made, sync_triggered
- Search: search_used
- Editor: raw_mode_toggled, wikilink_inserted
- Types & Views: type_created, view_created
- Telemetry: telemetry_opted_in, telemetry_opted_out

All events gated by PostHog initialization (only fires when opted in).
No PII in any event properties — counts, booleans, and enums only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 20:42:43 +02:00
lucaronin
55352c0afd feat: normalize system properties to _archived, _trashed, _trashed_at
Write operations now use underscore-prefixed canonical keys (_archived,
_trashed, _trashed_at). Read operations accept both old keys (Archived,
archived, Trashed, trashed, Trashed at, trashed_at) and new keys via
serde aliases, ensuring backward compatibility without migration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 19:32:48 +02:00
lucaronin
0889d747fe feat: add favorites section with star button, frontmatter persistence, and drag-to-reorder
Adds FAVORITES sidebar section backed by _favorite and _favorite_index
frontmatter properties. Star button in breadcrumb bar toggles favorite
state. Drag-to-reorder updates _favorite_index on all affected notes.
Section auto-hides when empty.

ADR 0038 documents the decision to use frontmatter for portability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:44:23 +02:00
lucaronin
f94d8c63c8 fix: remove trashed/archived fields from frontmatter on restore instead of setting false
Previously restore/unarchive set `Trashed: false` / `archived: false` in
frontmatter. Now uses handleDeleteProperty to remove the fields entirely,
keeping frontmatter clean as if the note was never trashed/archived.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 14:29:06 +01:00
lucaronin
fc77ce6e11 fix: sync raw editor + suppress toast overwrite on trash/archive actions
Two bugs fixed:
1. CodeMirror raw editor didn't reflect frontmatter changes (e.g. Trashed: true)
   after trash/archive because useCodeMirror only used content as initial state.
   Added content-sync effect with external-sync guard to prevent infinite loops.
2. Entry actions (trash/archive/restore/unarchive) showed "Property updated" toast
   instead of contextual message because runFrontmatterAndApply overwrote it.
   Added silent option to suppress toast when caller manages its own feedback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 13:32:07 +01:00
lucaronin
d8b61dd62f feat: optimize note open and trash/archive latency
Latency root causes:
1. handleSelectNote/handleReplaceActiveTab awaited IPC before updating
   activeTabPath — zero visual feedback for 50-200ms file I/O
2. Trash/archive called updateEntry AFTER two sequential IPC calls —
   note stayed visible in list for 100-400ms

Optimizations:
- Content prefetch cache: hover on NoteItem and keyboard arrow
  navigation pre-load note content via IPC. When user clicks, content is
  already in memory — eliminates the IPC round-trip entirely.
- Optimistic trash/archive/restore/unarchive: updateEntry runs
  immediately, frontmatter writes happen async. On failure, UI rolls
  back and shows error toast.
- Rapid-switch safety: sequence counter (navSeqRef) ensures only the
  latest navigation sets activeTabPath — prevents stale content flash
  when user clicks multiple notes in quick succession.
- Prefetch cache cleared on vault reload to prevent stale content after
  external edits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 13:28:46 +01:00
lucaronin
010d2c3949 fix: disk-first writes in useEntryActions, document three-layer model
Move updateEntry() calls after handleUpdateFrontmatter/handleDeleteProperty
in handleCustomizeType, handleRenameSection, and handleToggleTypeVisibility
so React state only updates after the disk write succeeds. This prevents
state-disk divergence when writes fail.

Expand ARCHITECTURE.md "Three representations, one authority" section with
ownership rules, invariants table, and recovery mechanisms. Add
reload_vault_entry to the commands table (62 total).

Add Playwright smoke test for Reload Vault in Cmd+K palette.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 00:52:56 +01:00
lucaronin
12fe4978ab fix: auto-save unsaved notes before trash/archive
Flush unsaved editor content to disk before any trash or archive
operation (both single-note and bulk) so body edits are never silently
dropped when only frontmatter is updated.

- Add flushEditorContent utility that checks pending content ref, then
  falls back to comparing tab content with last-saved state
- Add onBeforeAction callback to useEntryActions, called before
  handleTrashNote and handleArchiveNote
- Wire flushBeforeAction in App.tsx using refs for stable closures
- Add error handling in useBulkActions so one failed save doesn't
  block remaining notes
- Extract findOrCreateType helper to reduce useEntryActions complexity
- Export persistContent from useSaveNote for reuse

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:52:08 +01:00
lucaronin
0d4ca63ec8 fix: auto-save structural UI changes to disk immediately
Structural changes (sidebar visibility, label, order, template, icon/color)
now auto-create missing Type entries and call onFrontmatterPersisted to
refresh git status, so changes appear in git diff without user intervention.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 11:06:10 +01:00
lucaronin
7a7ba6086a fix: refresh Changes panel after trash/archive operations
Trash, archive, restore, and unarchive wrote frontmatter to disk but
never called loadModifiedFiles, so the change didn't appear in the
Changes panel until the next manual refresh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 23:01:05 +01:00
lucaronin
48c3bd11aa feat: add handleToggleTypeVisibility to useEntryActions
Toggle visible property on Type note frontmatter: sets visible:false
to hide, deletes visible property to show (defaults to visible).
Wire up in App.tsx via onToggleTypeVisibility prop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 21:35:18 +01:00
lucaronin
f3d197a3b0 fix: trashed notes reappear after restart due to frontmatter key casing mismatch
Frontend wrote `trashed` (lowercase) but Rust parser expected `Trashed`
(title-case via serde rename). On restart, the lowercase key didn't match,
defaulted to false, and trashed notes reappeared.

- Frontend: use title-case keys (Trashed, Trashed at) matching vault convention
- Rust: add serde aliases for lowercase keys (backward compat with already-written files)
- Add regression tests for both title-case and lowercase parsing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 10:00:56 +01:00
lucaronin
05c6863119 feat: add Rename section to sidebar context menu
- Add handleRenameSection to useEntryActions: writes/deletes 'sidebar label'
  frontmatter key on the Type note with optimistic in-memory update
- Add InlineRenameInput to SidebarParts: autoFocus input rendered in-place
  of section title, submits on Enter/blur, cancels on Escape
- Add 'Rename section…' as first item in sidebar section context menu
- Wire onRenameSection from App.tsx through Sidebar props
- Add 10 new tests (4 unit, 6 component) covering the full rename flow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 23:17:36 +01:00
Luca Rossi
8aee1315d9 fix: customize icon & color works for types without Type entry (#173)
Types without a dedicated Type definition note in the vault silently
failed to save icon/color customizations. Both applyCustomization
(Sidebar) and handleCustomizeType (useEntryActions) returned early
when no Type entry existed. Also fixed a race condition where two
concurrent handleUpdateFrontmatter calls could overwrite each other.

Changes:
- useNoteActions: add createTypeEntrySilent for headless Type file creation
- useEntryActions: auto-create Type entry when missing, serialize writes
- Sidebar: applyCustomization proceeds with defaults when no Type entry
- App: wire createTypeEntrySilent into useEntryActions config

Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 11:22:03 +01:00
Luca Rossi
986965a28f feat: note templates per type (💡 Note templates per tipo) (#170)
* feat: add template field to type entries and template-aware note creation

- Rust: add template field to Frontmatter, VaultEntry, SKIP_KEYS
- Rust: support YAML block scalar (|) for multi-line strings in frontmatter
- Rust: fix value continuation detection to handle block scalars properly
- TypeScript: add template to VaultEntry, buildNewEntry, frontmatterToEntryPatch
- Add DEFAULT_TEMPLATES for Project, Person, Responsibility, Experiment
- resolveNewNote/buildNoteContent accept optional template parameter
- handleCreateNote and handleCreateNoteImmediate look up type template
- Tests for all new behavior (Rust + TypeScript)

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

* feat: wire template UI through Sidebar and App, add TypeCustomizePopover template section

- Add template textarea with debounced save to TypeCustomizePopover
- Wire handleUpdateTypeTemplate through useEntryActions → Sidebar → App
- Add useDebouncedCallback hook for 500ms template save debounce
- Add tests for handleUpdateTypeTemplate and TypeCustomizePopover template UI
- Create design/note-templates.pen placeholder

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

* fix: useRef type arg + template field in bulk mock entries

* style: rustfmt

---------

Co-authored-by: Test <test@test.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-03-02 08:37:06 +01:00
lucaronin
5bbd1469e2 fix: resolve TypeScript build errors in refactored code and test mocks
- Remove unused cn import from NoteList.tsx
- Fix SidebarSelection type narrowing in NoteList entity view
- Fix SortableSection onToggle type in Sidebar Omit type
- Fix TypeRow isA prop to accept null
- Align useEntryActions handleUpdateFrontmatter value type
- Add missing trashed/trashedAt/order to test mock VaultEntry objects

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 11:00:07 +01:00
lucaronin
54fe2793fc refactor: reduce complexity in App, DiffView, Editor, InspectorPanels, NoteList
- App.tsx: extract useEntryActions hook and useLayoutPanels hook (8.92 → 9.28)
- DiffView.tsx: extract classifyDiffLine and DiffLine component (9.09 → 10.0)
- Editor.tsx: extract findEntryByTarget and lookupColorForEntry (9.09 → 10.0)
- InspectorPanels.tsx: extract entryStatusTitle and StatusSuffix (8.87 → 10.0)
- NoteList.tsx: extract EntityView, ListView, useNoteListData (8.79 → 9.68)

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