Commit Graph

1176 Commits

Author SHA1 Message Date
lucaronin
d9fd65c926 fix: read owner/cadence from properties in ai-context
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 02:01:05 +01:00
lucaronin
9aa16b8eb4 refactor: remove owner/cadence from Frontmatter, source created_at from filesystem
Remove owner, cadence, created_at, and created_time as hardcoded fields from
the Frontmatter struct — they don't drive app logic and belong in generic
properties. Owner and cadence values now flow through to the properties map
(including single-element array unwrapping). Creation date is sourced from
filesystem metadata (birthtime on macOS) instead of frontmatter.

Also fixes title extraction: add H1 heading extraction to extract_title()
(priority: frontmatter title → H1 → filename slug). Previously titles fell
back directly to filename when no frontmatter title was set.

StringOrList is retained for scalar Frontmatter fields as a defensive measure:
YAML values can arrive as single-element arrays (e.g. Status: [Active]) which
would cause entire deserialization to fail without it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 01:56:33 +01:00
lucaronin
ddbbebbb67 feat: add emoji icon picker for notes stored in frontmatter
Every note can now have an optional emoji icon (frontmatter `icon` field).
The icon is displayed in the editor header, note list, search results,
and Quick Open. Includes command palette commands "Set Note Icon" and
"Remove Note Icon", plus full test coverage (Vitest + Playwright).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 22:42:55 +01:00
lucaronin
0897cc5d95 docs: update CLAUDE.md — CodeScene threshold 9.2/9.2, fix port/finish-signal for no-worktree workflow 2026-03-17 22:01:26 +01:00
lucaronin
dec9fe6412 docs: add Kent Beck Test Desiderata to TDD section in CLAUDE.md 2026-03-17 21:35:47 +01:00
lucaronin
4cfd31fe53 style: rustfmt formatting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 17:14:35 +01:00
lucaronin
c02584fd86 fix: remove unused import and dead code from title sync refactor
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 17:08:07 +01:00
lucaronin
0ac8ad8dff test: Playwright smoke test for title/filename sync + update docs
- 3 smoke tests: new note title, open note title display, rename atomicity
- Updated ABSTRACTIONS.md: title/filename sync section, title in semantic fields
- Updated ARCHITECTURE.md: title_sync.rs module, sync_note_title command

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:59:04 +01:00
lucaronin
77b6961cb9 feat: TypeScript calls sync_note_title on note open
- handleSelectNote syncs title frontmatter before loading content
- handleSelectNoteWithSync reloads entry after open to update display title
- Added sync_note_title to mock handlers
- Fixed rapid-switching test to flush sync microtask

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:52:23 +01:00
lucaronin
9112a24fcb feat: title/filename sync on note open + always write title in rename
- New sync_title_on_open function: detects desync between title frontmatter
  and filename, corrects it (filename wins as source of truth)
- Registered sync_note_title Tauri command
- rename_note now always writes title to frontmatter (not just when present)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:45:30 +01:00
lucaronin
663e9563b2 refactor: extract_title reads from frontmatter title, not H1
Title is now sourced from the `title` frontmatter field with filename-
derived fallback (slug_to_title). H1 headings are treated as body content.
Added `title` to Frontmatter struct and SKIP_KEYS. Made title_to_slug
pub(super) for reuse across vault submodules.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 16:41:49 +01:00
lucaronin
e74d0e46c8 fix: rustfmt formatting in mod_tests.rs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:10:06 +01:00
lucaronin
7976d9f2c8 refactor: extract vault/mod.rs into submodules — fix CodeScene hotspot health
vault/mod.rs was 1820 lines with duplicated code already extracted to
entry.rs, frontmatter.rs, file.rs but never wired up. Slim mod.rs to
delegate to submodules. Score: 7.85 → 10.0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:07:29 +01:00
lucaronin
3890960b8a style: rustfmt repair_vault tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 14:32:17 +01:00
lucaronin
ee9af1eb43 fix: repair vault now flattens type folders and migrates legacy frontmatter
Repair Vault command now runs flatten_vault() and migrate_is_a_to_type()
before restoring themes and config, ensuring vaults adopt flat structure.
Also fixes config.md type definition to use `type: Type` instead of
legacy `Is A: Type`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 14:32:17 +01:00
lucaronin
edc4911eaf Merge remote-tracking branch 'origin/main' into task/image-drop-overlay-fix
# Conflicts:
#	tests/smoke/changing-type-data-corruption.spec.ts
#	tests/smoke/fix-note-filename-on-rename.spec.ts
#	tests/smoke/move-note-to-type-folder.spec.ts
2026-03-17 13:55:34 +01:00
lucaronin
4d61774a70 fix: smoke tests skip Theme entries in note list to avoid type selector issues
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:50:11 +01:00
lucaronin
164b76d35c fix: resolve demo vault path relative to project root — fix smoke test failures
DEFAULT_VAULTS was hard-coded to the main repo path, causing the Vault API
to read stale/duplicate files when running from worktrees. Now uses Vite's
define to inject the correct path at build time. Also fix theme heading
titles (remove redundant "Theme" suffix) and make smoke tests resilient
to Theme-type notes appearing first in the note list.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 13:14:56 +01:00
lucaronin
f9e89e4616 fix: make CodeScene pre-push gate informational — remote API lags local changes
The remote CodeScene API only updates after push + re-analysis, creating a
chicken-and-egg blocking loop. The local pre_commit_code_health_safeguard
already validates code health before commit. Pre-push now reports remote
scores for visibility without blocking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:26:34 +01:00
lucaronin
4a69fc1c9c fix: correct CodeScene API key in pre-push hook — use code_health not average_code_health
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:18:20 +01:00
lucaronin
bc4e637cdd style: rustfmt seed.rs and getting_started.rs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:09:28 +01:00
lucaronin
bb9fef9f77 refactor: improve code health for vault/mod.rs and Editor.tsx — fix CodeScene hotspot score
Extract scan_vault helpers (is_md_file, try_parse_md, scan_root_md_files, scan_protected_folders)
to eliminate deep nesting and reduce cyclomatic complexity. Break up large assertion blocks in tests.
Extract useEditorSetup and useRawModeWithFlush hooks from Editor component to reduce complexity.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:07:33 +01:00
lucaronin
db0589c99d fix: update Repair Vault for flat vault structure — no theme/ or config/ dirs
Theme vault notes now live at root as default-theme.md, dark-theme.md,
minimal-theme.md instead of in theme/ subdirectory. AGENTS.md holds full
content at root instead of stub+config/agents.md pattern. Adds migration
for legacy theme/ and config/ directories on startup and repair.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 12:06:09 +01:00
lucaronin
07a6ef0970 feat: persist editor mode (raw/preview) across note switches
Editor mode is now stored as a global preference in VaultConfig instead of
being tracked per-tab. Toggling raw mode persists across tab switches and
app restarts via the editor_mode field in config/ui.config.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 11:41:35 +01:00
lucaronin
af46c0499a style: rustfmt vault mod.rs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:38:47 +01:00
lucaronin
6371e80f06 fix: uniform StringOrList normalization for all frontmatter string fields
Replace per-field Option<String> with Option<StringOrList> for all string
fields in the Frontmatter struct (owner, cadence, status, icon, color,
sidebar_label, template, sort, view, trashed_at, created_at, created_time).

Previously, fields like Owner stored as YAML arrays (e.g. `Owner: [Luca]`)
caused serde to fail the entire Frontmatter deserialization, defaulting all
fields to None — including is_a, which broke the type badge display.

Now all string fields use StringOrList with into_scalar() normalization:
- Single-element array → unwrap to scalar
- Multi-element array → take first element
- Scalar → unchanged
- Empty array → None
- Absent → None

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 10:37:16 +01:00
lucaronin
fb825828f7 refactor: extract welcome/loading screens in App.tsx — reduce main component complexity 2026-03-17 07:16:49 +01:00
lucaronin
427672cf4e test: add Playwright smoke test for split-usenoteactions refactoring
Covers note creation via Cmd+N, unique naming, note selection, and
inspector rendering. Also documents frontmatterOps in ARCHITECTURE.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 23:52:43 +01:00
lucaronin
56b0a86f03 test: add unit tests for useNoteCreation and useNoteRename hooks
39 tests for useNoteCreation covering creation, daily notes, templates,
optimistic revert, and unsaved cleanup. 12 tests for useNoteRename
covering rename operations, toast messages, and error handling.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 23:52:42 +01:00
lucaronin
71ccae1c70 refactor: extract frontmatterOps, update imports for useNoteCreation/useNoteRename split
useNoteActions.ts reduced from 213 to 125 lines by extracting frontmatter
helpers into frontmatterOps.ts and removing re-exports. Consumers now
import directly from the extracted modules.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 23:52:42 +01:00
lucaronin
54e769fc21 style: rustfmt vault mod.rs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 20:29:39 +01:00
lucaronin
f5d0bd0c7b fix: add missing VaultEntry fields (belongs_to, status, owner, cadence)
The vault module split left the mod.rs VaultEntry struct missing fields
that were added in entry.rs but never wired in. Adds the missing fields,
populates them from frontmatter, adds status/owner/cadence to SKIP_KEYS,
and fixes conflicting test expectations from the incomplete merge.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 20:20:58 +01:00
lucaronin
49ab91541f fix: use contains() instead of iter().any() for clippy manual_contains
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 19:45:57 +01:00
lucaronin
22d002c1c6 refactor: split NoteList.tsx god component into focused modules
Extract 7 sub-modules under components/note-list/:
- PinnedCard.tsx, RelationshipGroupSection.tsx, TrashWarningBanner.tsx
- NoteListHeader.tsx, NoteListViews.tsx
- noteListHooks.ts, noteListUtils.ts

NoteList.tsx reduced from 579 → 95 lines. No behavior changes.
All 2152 unit tests pass, 80%+ coverage, lint + typecheck clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 19:36:00 +01:00
lucaronin
9f81a00347 Resolve merge conflict: keep split vault module from origin/main 2026-03-16 19:25:49 +01:00
lucaronin
b5eb781d14 style: apply rustfmt to mod_tests.rs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 19:03:14 +01:00
lucaronin
c921403825 fix: resolve clippy warnings from vault module split
Remove unused HashMap import from mod.rs, use contains() instead of
iter().any() in frontmatter.rs, add HashMap import to test module.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 19:03:14 +01:00
lucaronin
6b6bd4693e refactor: split vault/mod.rs monolith into entry, frontmatter, file modules
Extract VaultEntry struct to entry.rs (64 lines), YAML parsing to
frontmatter.rs (323 lines), and file I/O helpers to file.rs (59 lines).
Tests moved to mod_tests.rs. mod.rs reduced from 1679 to 189 lines,
now purely orchestration (parse_md_file, reload_entry, scan_vault).

All 612 tests pass, public API unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 19:03:14 +01:00
lucaronin
6520e366c8 fix: clippy manual_contains lint in vault frontmatter filter
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 18:33:13 +01:00
lucaronin
cd0152c0a4 refactor: split useNoteActions into useNoteCreation + useNoteRename — CodeScene 7.92→9.38
Extract note creation (CRUD, daily notes, types, optimistic persistence) into
useNoteCreation and rename operations into useNoteRename. useNoteActions now
composes both hooks plus frontmatter/navigation logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 18:31:33 +01:00
lucaronin
144a621b3e fix: frontmatter parsing fails when unknown fields have list values
The Frontmatter struct deserialization failed completely when any unknown
field had a list value (e.g. Owner: [Luca], Cadence: [Weekly]) because
serde expected a string but got an array. This caused unwrap_or_default()
to return all-None, losing type/status/archived for ~7000+ notes.

Two fixes:
1. Filter parse_frontmatter input to only known keys, preventing unknown
   fields from causing deserialization failures
2. Change Owner and Cadence to StringOrList to handle both formats
2026-03-16 17:12:58 +01:00
lucaronin
a12ad57699 fix: flat vault type resolution — remove type/ prefix from links and protected folders
- Type relationship links: [[type/essay]] → [[essay]] (matches flat vault structure)
- PROTECTED_FOLDERS / KEEP_FOLDERS: only attachments, _themes, assets
- TypeSelector navigation: type/slug → slug
- Updated all 14 affected test files
- All 612 Rust tests + 2151 frontend tests pass
2026-03-16 16:19:24 +01:00
Luca Rossi
3fb7cf6a56 refactor: split DynamicPropertiesPanel into focused sub-components — reduce 699-line catch-all (#197)
Extract PropertyValueCells, TypeSelector, and AddPropertyForm into dedicated
files. Move shared display-mode constants to utils/propertyTypes to satisfy
react-refresh lint rule. All tests pass, no behavior change.

Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 07:25:40 +01:00
lucaronin
23d04172c4 feat: ensure .DS_Store in .gitignore for all new vaults
Extract ensure_gitignore from init_repo so it can be reused by
clone_repo (GitHub "Create New" flow) and repair_vault. New vaults
created via any path now get .DS_Store excluded by default.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 05:36:45 +01:00
lucaronin
1932b35c92 fix: cargo fmt formatting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 05:06:24 +01:00
lucaronin
ede51e26a3 fix: correct reloadVault type in useFlatVaultMigration
Accept Promise<unknown> instead of Promise<void> to match the actual
reloadVault return type (Promise<VaultEntry[]>).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 05:06:24 +01:00
lucaronin
7f1f81c031 test: add Playwright smoke tests for flat vault migration
Covers: TitleField visibility, filename indicator on focus, no
migration banner when vault is flat, CSS rule hiding H1 in editor.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 05:06:24 +01:00
lucaronin
d9e25be5a6 docs: update ARCHITECTURE.md and ABSTRACTIONS.md for flat vault
- scan_vault now scans root + protected folders only (no deep recursion)
- vault_health_check command detects stray files and title mismatches
- Wikilink resolution: multi-pass with filename stem priority
- TitleField: dedicated title UI above editor, H1 hidden via CSS
- Migration banner: detects subfolders on vault open, offers flatten

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 05:06:24 +01:00
lucaronin
a8989e1445 feat: add migration wizard for flat vault
On vault load, detects files in non-protected subfolders via
vault_health_check. Shows an amber banner offering to flatten them
to the vault root. After migration, reloads the vault automatically.
The banner can be dismissed without migrating.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 05:06:24 +01:00
lucaronin
db94b8b3a0 feat: add dedicated TitleField above editor
Adds a TitleField component between the breadcrumb bar and BlockNote
editor that serves as the primary title editing surface. The H1 block
inside BlockNote is hidden via CSS. The title field:
- Shows the note title in a prominent input field
- Displays the expected filename when it differs from the current one
- Triggers onTitleSync on blur/Enter to rename the file
- Responds to laputa:focus-editor selectTitle events for new notes
- Reverts on Escape or empty input

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 05:06:24 +01:00