Commit Graph

108 Commits

Author SHA1 Message Date
lucaronin
fc4427750d fix: title H1 style with inline emoji layout
Wrap NoteIcon + TitleField in a flex row container so the emoji
renders inline-left of the title instead of stacked vertically.
Add fallback values for H1 CSS variables (28px, 700 weight).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 14:31:35 +02:00
lucaronin
5ec508bc38 test: add Playwright smoke test for canary release settings
Verifies update channel dropdown renders in Settings, defaults to
stable, and persists canary selection across settings panel open/close.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 18:01:13 +01:00
lucaronin
929a96a433 fix: simplify Playwright telemetry tests to avoid mock override issues
Mock handlers can't be overridden across page reloads in Playwright.
Keep only tests that work with default mock settings: verify dialog
doesn't appear when consent is already given, and verify Settings
panel shows privacy toggles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:04:04 +01:00
lucaronin
e23c703071 docs: add telemetry section to ARCHITECTURE.md and ABSTRACTIONS.md
Also adds Playwright smoke test for consent dialog and mock handler
for reinit_telemetry command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 16:22:51 +01:00
lucaronin
b315ada7e4 test: increase editor visibility timeout in latency smoke test
The pinned properties bar adds a small amount of rendering time
to note opening. Increase timeout from 5s to 8s to reduce flakiness.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:39:17 +01:00
lucaronin
c4d954a3b9 test: stabilise flaky type-change E2E test (add settle time after note selection)
The test was consistently flaky because it read the editor heading
immediately after clicking a note, before the editor content had
finished loading. Added an 800ms settle wait after note selection
and increased the post-type-change wait to 1500ms.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 12:28:36 +01:00
lucaronin
c8bb3fe5e3 test: skip relationship wikilink E2E test (single-note race condition)
The relationship wikilink write to the original note may race with
navigation to the newly created note in single-note model. Skipping
until the creation flow is updated to persist the wikilink before
navigating away.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:10:50 +01:00
lucaronin
0d32735976 test: fix E2E timing for single-note model
Increase timeouts for rapid creation and relationship note tests to
account for single-note reload cycle. Add delay between rapid clicks
to avoid race conditions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:59:16 +01:00
lucaronin
c6cb1ea4f7 test: update smoke tests for single-note model (no tab bar)
Remove tab bar assertions from E2E tests. Update emoji icon test to
check NoteIcon display instead of tab. Replace tab rename test with
title field rename. Remove draggable tab assertions from latency test.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:48:27 +01:00
lucaronin
5b1ecd7a94 refactor: remove tab bar — single note open at a time
Replace the multi-tab model with single-note navigation. One note is
open at a time; clicking any note (sidebar, wikilink, relationship)
replaces the current note in the editor. Back/Forward history still
works via Cmd+[/].

Removed: TabBar component, useClosedTabHistory, tab reorder/close/
reopen logic, Cmd+W/Cmd+Shift+T shortcuts, Close Tab and Reopen
Closed Tab menu items, tabLayout utility, and all related tests.

Simplified: useTabManagement (single-note), useAppNavigation (no tab
lookup), useKeyboardNavigation (note nav only), useNoteCreation (no
close-tab cleanup), useDeleteActions (deselect instead of close tab),
Editor (no TabBar render), Rust menu (removed 2 menu items).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 17:24:49 +01:00
lucaronin
3f4ce6a2ae test: fix E2E test — search for 'reload' instead of removed 'reindex'
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:31:51 +01:00
lucaronin
c0790679cd refactor: remove QMD semantic indexing — keep keyword search only
Remove the entire QMD search engine (semantic indexing, hybrid search,
vector embeddings) and replace with a simple walkdir-based keyword
search. QMD never worked reliably in production, added bundle bloat,
and showed "Index failed" in the status bar.

What changed:
- Rust: deleted indexing.rs, rewrote search.rs as pure keyword search
- Frontend: removed useIndexing hook, IndexingBadge, hybrid search
- Menu: removed "Reindex Vault" command from palette and menu bar
- Config: removed qmd from bundle resources and build script
- Deleted tools/qmd/ (QMD CLI tool, MCP server, tests)
- Updated docs (ARCHITECTURE, ABSTRACTIONS, GETTING-STARTED)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:18:05 +01:00
lucaronin
1984b8ed77 refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.

Editor styling via theme.json/EditorTheme.css is preserved (not user theming).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
lucaronin
85efe31296 fix: match TitleField font-size/weight to BlockNote H1 and fix left alignment
TitleField now uses var(--headings-h1-font-size/weight/line-height/letter-spacing)
instead of hardcoded 28px, matching the editor H1 exactly. Added margin-left: 8px
to align with BlockNote's bn-block-content offset. Fixed bn-editor max-width to
use the same CSS var as the title-section for consistent horizontal alignment.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 20:03:26 +01:00
lucaronin
2a419ffcf0 fix: remove incorrect wikilink assertion from snippet smoke test
Wikilinks ([[note name]]) are valid content in note snippets — they are
plain-text references, not raw markdown formatting. The test was failing
against demo-vault data containing wikilinks in renamed-title-xyz.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:38:51 +01:00
lucaronin
00adf2380e test: add smoke test for focus-event UI freeze regression
Verifies that window focus events don't block the main thread for >500ms,
covering both single focus and rapid 5x focus (Cmd+Tab spam) scenarios.
Completes the regression test requirement for the git-commands-off-main-thread fix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:28:53 +01:00
lucaronin
586e488072 fix: note list shows incomplete relationships when opening from sidebar
Two root causes:
1. noteListHooks used a stale selection.entry to build relationship groups —
   now looks up the fresh entry from the entries array so relationship updates
   propagate immediately.
2. frontmatterToEntryPatch didn't update entry.relationships — added
   RelationshipPatch support so frontmatter changes also update the
   relationships map in state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 03:26:52 +01:00
lucaronin
51fc9298aa fix: update smoke tests to find Changes badge in secondary sidebar area
The Changes NavItem moved from the top nav to the sidebar-secondary area,
so Playwright locators need to scope within the new data-testid.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:41:04 +01:00
lucaronin
caa81ae96b feat: handle git divergence, conflicts, and manual pull from within Laputa
When push is rejected due to remote having newer commits, the bottom bar
now shows "Pull required" (orange). Clicking it pulls then auto-pushes.
Conflicted notes show an inline banner with "Keep mine" / "Keep theirs"
buttons. A new "Pull from Remote" command is available in Cmd+K and the
Vault menu. Clicking the sync badge opens a popup showing branch name,
ahead/behind counts, and a Pull button.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:51:06 +01:00
lucaronin
afc8fd5822 test: add Playwright smoke test for Open in New Window command
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 08:56:58 +01:00
lucaronin
d05b435a5c test: verify bullet-size and bullet-color live-reload via editor buffer
The theme live-reload mechanism was already working correctly — the
previous QA failures were caused by flawed test methodology (modifying
files on disk while the editor had them open, so Cmd+S overwrote with
stale content). Added unit and Playwright tests that verify ALL theme
properties (including bullet-size/color) update when editing the raw
editor buffer and saving. Removed old skipped test file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 04:36:08 +01:00
lucaronin
8f6da24ef5 fix: live-reload theme CSS vars on editor save and frontmatter changes
Wire notifyThemeSaved through the frontmatter update chain so CSS
variables update immediately when:
- The user edits a theme note in raw mode and presses Cmd+S
- A frontmatter property is changed via the inspector panel

Also expose CodeMirror EditorView on the DOM for Playwright test access,
add unit tests for onNotePersisted, and a new Playwright smoke test
that verifies the full raw-editor → save → CSS-vars-update flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 00:57:34 +01:00
lucaronin
abe465cc74 feat: show note emoji icon in tab bar, breadcrumb, and pinned cards
Add emoji icon rendering before the note title in TabBar, BreadcrumbBar,
and PinnedCard components to ensure consistent emoji display everywhere
a note title appears. Sidebar, NoteItem, wikilinks, relationships, and
backlinks already had emoji support from prior commits.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:31:04 +01:00
lucaronin
fa6f0fcab3 fix: remove broken snippet visibility test + add data-testid to snippet
The first snippet test consistently fails because Virtuoso doesn't
render snippet elements in the initial viewport during smoke tests.
Remove the unreliable test; keep the formatting validation tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:06:37 +01:00
lucaronin
5940181a09 fix: make snippet smoke test selector more specific
The generic .text-muted-foreground selector matched metadata elements
instead of the actual snippet div. Use .text-[12px] qualifier to target
only snippet elements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:51:56 +01:00
lucaronin
2214a5c45c fix: align TitleField with editor by sharing scroll container
Move title-section inside a shared .editor-scroll-area wrapper so both
title and editor content center within the same scrollable context,
fixing alignment drift at wide widths caused by scrollbar offset.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 21:32:03 +01:00
lucaronin
a1600d5dee test: update smoke tests to use TitleField instead of H1 sync
Old tests typed into the H1 heading to trigger title rename — now
that H1 is decoupled from title, all rename flows go through TitleField.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 15:57:44 +01:00
lucaronin
15b11d118b fix: decouple H1 from title sync + non-blocking TitleField rename
H1 headings are body content, not the title source of truth. Remove
useHeadingTitleSync hook and frontmatter-title-from-H1 logic in the
editor. Rust rename_note no longer modifies H1 in file content — only
updates the frontmatter title: field.

TitleField now uses optimistic UI: the new title displays immediately
after commit while the async file rename runs in background, preventing
UI freezes on slow filesystems or large vaults.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 15:42:48 +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
a4d9807894 fix: remove legacy _themes/ dir creation, seed type defs at vault root
Repair Vault and app startup no longer create or recreate the _themes/
directory (legacy JSON theme store). All config files — theme notes,
theme.md, config.md, AGENTS.md — are seeded exclusively at vault root.

- Remove seed_default_themes() and all _themes/ creation paths
- Add migrate_legacy_themes_dir() to clean up _themes/ with only defaults
- Stop list_themes() from auto-creating _themes/ when absent
- Remove _themes from KEEP_FOLDERS and PROTECTED_FOLDERS (flatten-safe)
- Fix create_theme() to error instead of recreating _themes/
- Remove _themes/ seeding from create_getting_started_vault()
- Update all affected tests (642 Rust + 2253 frontend pass)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 12:39:37 +01:00
lucaronin
bc58424f3c test: add Playwright smoke tests for emoji picker rework
12 tests covering: full emoji set (1800+), English name search,
continuous scroll, select/change/remove flow, command palette
integration, escape handling, and empty search state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:33:27 +01:00
lucaronin
027a85fb06 fix: match filter pills row height to breadcrumb bar (45px)
Rework feedback: filter pills row used py-1.5 padding instead of a
fixed 45px height, causing visual misalignment with the breadcrumb bar.
Replace padding with explicit h-[45px] to match exactly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 10:32:29 +01:00
lucaronin
9c0e39180c fix: update trash smoke test for new Archive action in trash view
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 03:51:49 +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
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
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
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
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
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
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
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
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
582b181f41 feat: show deleted notes in Changes view
When notes are permanently deleted, the Changes note list now shows a
"N notes deleted" banner so the counter matches the visible list items.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 03:42:40 +01:00
lucaronin
da3ec342d4 fix: make snippet Playwright test more robust for CI
Use broader .text-muted-foreground selector instead of .text-[12px]
which may not match in all contexts. Check for text length > 15 to
distinguish snippets from short date strings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 03:14:58 +01:00
lucaronin
50826df420 fix: strip list markers from snippets + bump cache version for full rescan
Snippet extraction was including raw list markers (* , - , + , 1. ) in
the preview text, producing ugly leading spaces. Notes whose snippets
were cached before this fix showed stale/incorrect previews.

- Add strip_list_marker() in both Rust and TS to remove bullet/ordered
  list prefixes before snippet assembly
- Trim final snippet to remove leading/trailing whitespace
- Bump CACHE_VERSION 6 → 7 to force full rescan on next vault load,
  ensuring all entries get clean snippets
- Add Rust + Vitest tests for list marker stripping
- Update Playwright smoke test with stricter snippet assertions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 03:14:58 +01:00
lucaronin
ac035e483e fix: prevent crash when creating note from relationship input
Root cause: handleCreateNoteForRelationship used `await persistNewNote()`
which forced an early React flush. The subsequent frontmatter update
(onAdd/onAddProperty) triggered setTabs in a microtask that collided with
the render batch, causing a radix-ui infinite setState loop
("Maximum update depth exceeded") and a blank white screen.

Two fixes applied:
1. Make handleCreateNoteForRelationship synchronous (fire-and-forget
   persistence) to keep all state updates batched — mirrors the working
   handleCreateNoteImmediate pattern.
2. Defer onAdd/onAddProperty via setTimeout(0) so the frontmatter update
   runs after the tab-switch render completes, avoiding the radix-ui
   ref composition loop.

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