Commit Graph

144 Commits

Author SHA1 Message Date
Test
f8d080e678 feat: add body content filter for Views (contains/does not contain)
Adds 'body' as a built-in filter field that searches note snippet text
(case-insensitive). Visually separated from property fields in the
FilterBuilder dropdown with a separator. Combines with other filters via AND.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 16:13:21 +02:00
Test
9db5f5cbed fix: add listPropertiesDisplay to remaining VaultEntry literals
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 13:05:39 +02:00
Test
62af7a3d6e fix: parse date strings in view filter before/after operators
Date properties are stored as YAML strings (e.g. "2024-03-15"), not
Unix timestamps. Parse string values via Date.parse so before/after
operators work correctly. Also handles numeric Unix timestamps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 04:07:11 +02:00
Test
4a48833dbc fix: use substring match for contains/not_contains on relationship fields
Plain text values now use substring matching on wikilink stems so
"Monday" matches [[Monday Ideas]], [[Monday Recap]], etc. Wikilink
syntax values ([[...]]) still use exact stem matching. any_of/none_of
remain exact match only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 02:18:40 +02:00
Test
ab3de7eecd fix: parse numeric YAML values as numbers so _favorite_index persists
parseScalar() returned all non-boolean values as strings, causing
contentToEntryPatch() to map _favorite_index: 2 → favoriteIndex: null
(typeof "2" !== "number"). Every editor autosave then reset the
in-memory favorite index, breaking drag-to-reorder persistence.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 18:40:18 +02:00
Test
284af17483 feat: show all files in folder view, open text files in raw editor, gray out binary
Vault scanner now includes all files (not just .md). Each VaultEntry has a
fileKind field ("markdown", "text", or "binary") that controls how the
frontend handles it:

- Folder view shows all file kinds; other views (All Notes, type sections)
  continue to show only markdown files
- Text files (.yml, .json, .txt, .py, etc.) open in the raw CodeMirror editor
- Binary files (.png, .jpg, .pdf, etc.) appear grayed out and are not clickable
- Non-markdown files use filename as title, skip frontmatter parsing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 17:38:09 +02:00
Test
6946aad139 feat: add custom views frontend — types, sidebar section, filter evaluation
Add ViewDefinition/ViewFile types, extend SidebarSelection with 'view'
kind. Client-side filter evaluation in viewFilters.ts with full operator
support. VIEWS section in sidebar (hidden when empty). Wire view loading
through useVaultLoader, NoteList, and filterEntries pipeline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:09:43 +02:00
Test
33db64822d 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
Test
e823243a3b fix: prevent BlockNote from altering list markers and inserting HTML entities
BlockNote's serializer outputs `*` for bullet lists and inserts `&#x20;`
HTML entities around inline code within bold text. Both cause meaningless
git diffs. Fix by post-processing in compactMarkdown:
- Normalize `*` bullet markers to `-` (standard convention)
- Decode HTML entities like `&#x20;` back to literal characters
- Skip normalization inside fenced code blocks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:49:28 +02:00
Test
6640e74a74 fix: address folder tree QA feedback — recursive filtering, folder creation, path display, remove flatten banner
1. Folder selection now recursively includes notes from subfolders
2. + button creates a new folder with inline rename (Tauri command + UI)
3. Note list items show full path when note is in a subdirectory
4. Remove flat vault migration banner and all related code (Rust commands,
   hook, component, smoke test) — subfolders are now first-class

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:29:24 +02:00
Test
c0fed9c5c0 fix: wikilink autocomplete uses relative path, prevent silent rename
Bug 1: Wikilink autocomplete now always inserts the vault-relative path
as the target (e.g. [[docs/adr/0001-tauri-stack|Title]]) instead of
just the filename. This ensures wikilinks are unambiguous and resolve
correctly across subfolders after reload.

Bug 2: unique_dest_path now excludes the source file from collision
checks, preventing false positives where a note's own file is treated
as a naming conflict (causing silent -2 suffix renames).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 18:15:17 +02:00
Test
e3e60a2815 feat: subfolder support — path-based wikilink resolution and cross-folder backlinks
- resolveEntry: add path-suffix matching so [[docs/adr/0031-foo]] resolves
  to entries in subdirectories (Pass 1, before filename match)
- Inspector backlinks: replace hardcoded /Laputa/ regex with generic
  path-suffix matching via targetMatchesEntry helper
- Autocomplete preFilter: also match against file path so searching
  subfolder names (e.g. "adr") surfaces nested notes
- Add relativePathStem utility for vault-relative path extraction

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:47:54 +02:00
Test
093f1bc9dc test: add folder tree and filtering tests; docs: ADR-0033
Add FolderTree component tests (render, expand, collapse, select,
highlight) and folder filtering tests in noteListHelpers (path
matching, sibling exclusion, archive/trash filtering).

ADR-0033 documents the decision to scan all subdirectories and
expose folder tree navigation, superseding ADR-0006's scanning
constraint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:19:31 +02:00
Test
46a08c6f43 feat: show Initialize/Invalid properties prompts for notes without frontmatter
Properties panel now detects frontmatter state (valid/empty/none/invalid):
- No frontmatter: shows "Initialize properties" button that adds type+title
- Invalid YAML: shows warning with "Fix in editor" button (toggles raw mode)
- Valid frontmatter: unchanged behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:07:39 +02:00
Test
eb7a45adf9 feat: scan subdirectories and expose folder tree for sidebar
Extend the Rust vault scanner to index .md files in all visible
subdirectories (hidden dirs excluded). Add FolderNode struct and
list_vault_folders Tauri command that returns the directory tree.
On the frontend, add FolderNode type, extend SidebarSelection with
{ kind: 'folder'; path: string }, and add isInFolder() filtering
in noteListHelpers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:06:11 +02:00
Test
6b0bb5173c feat: pre-populate commit dialog with heuristic message from git diff
Generate a commit message from modified files (e.g. "Update winter-2026"
or "Update 12 notes") and pre-fill the CommitDialog textarea so users can
commit immediately or edit the suggestion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 16:30:54 +02:00
Test
adfceb3c70 fix: Properties panel — hash-based tag colors, single-item tags, chip consistency
- Single-item tag arrays (e.g. Tags: [Has Pic]) now render as pills instead
  of plain text: detectPropertyType checks key patterns before value type
- Tags get deterministic hash-based colors (one color per tag name) instead
  of all-blue default — manual overrides still take precedence
- All chips (Type, Status, Date, Tags) share consistent sizing: 12px font,
  rounded-md, matching padding
- Type label font-size matches other property labels (was 10px, now 12px)
- Tag add button is solid muted pill instead of dashed circle

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 22:04:37 +02:00
Test
c4960e8ee7 refactor: reduce complexity in parsing.rs and noteListHelpers.ts (gate: 9.31 → 9.33)
Refactored two files to improve code health:

1. src-tauri/src/vault/parsing.rs (7.9 → 8.54, +0.64)
   - Extracted helper functions to reduce nesting in strip_markdown_chars
     (process_wikilink, extract_wikilink_display, process_markdown_link)
   - Refactored strip_list_marker to eliminate bumpy road pattern
     (strip_unordered_marker, strip_ordered_marker)

2. src/utils/noteListHelpers.ts (9.28 → 10.0, +0.72)
   - Reduced cyclomatic complexity in isInboxEntry from 15 to ~4
     (hasAnyValidLinks, hasValidBodyLinks, hasValidFrontmatterLinks)
   - Extracted complex conditional into wasCreatedBeforeLastModification

Gate threshold raised: 9.31 → 9.33 (conservative, pending CodeScene re-analysis)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 07:10:06 +01:00
Test
c4136d69b4 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
Test
ecbb94ae83 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
Test
a6b2454184 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
Test
c6fa1f48cb feat: add filter pills (Open/Archived/Trashed) to All Notes view
Reuses the existing FilterPills component and sub-filter mechanism from
sectionGroup views. Adds countAllByFilter helper for counting across all
entry types and extends filterByKind to support subFilter for the 'all'
filter. Bulk actions automatically adapt based on active pill. Switching
pills resets multi-selection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:03:17 +01:00
Test
36f43c1ae0 fix: note list resolves relationships by title/alias matching unified resolveEntry
resolveRefs() and refsMatch() in noteListHelpers used a simple 2-pass
matching (path stem + filename stem), while the Inspector used the unified
resolveEntry() with 4-pass resolution (filename, alias, title, humanized
title). Notes matched only by title or alias were silently dropped from the
note list, causing incomplete relationship groups.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:03:50 +01:00
Test
135fe62d21 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
Test
7b0b31455b fix: use lowercase titleBarStyle for Tauri v2 WebviewWindow
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 08:48:20 +01:00
Test
7c16ebd065 feat: open note in new window (Cmd+Shift+Click / Cmd+Shift+O)
Add multi-window support: notes can be opened in dedicated secondary
Tauri windows with editor-only layout (no sidebar, no note list).

Triggers: Cmd+Shift+Click on notes, Cmd+K → "Open in New Window",
Cmd+Shift+O shortcut, Note → "Open in New Window" menu bar item.

Secondary windows have their own auto-save, theme, and wikilink
navigation. Closing a secondary window does not affect the main window.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 08:47:25 +01:00
Test
bc55231baa feat: add Inbox sidebar section showing unlinked notes
Inbox shows notes without valid outgoing relationships (body wikilinks
or frontmatter refs), helping users find captured but unorganized notes.
Includes time-period filter pills (This week/month/quarter/All time),
Cmd+K command, and macOS menu bar entry. Broken wikilinks (targeting
non-existent notes) are not counted as relationships.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 06:41:40 +01:00
Test
975931ec6d fix: show Note type in sidebar instead of excluding it as default/fallback
Note was explicitly excluded from collectActiveTypes() via `e.isA !== 'Note'`.
Removed the exclusion so Note appears like any other type. Untyped entries
(isA === null) now count as Note in both type collection and section filtering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 02:50:46 +01:00
Test
70ab40538f fix: show all relationships for topics in note list
Topics used a separate 'topic' selection kind that only showed reverse
relatedTo matches. Now topics use 'entity' kind like all other types,
going through buildRelationshipGroups to show all frontmatter
relationships, children, events, referenced-by, and backlinks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 23:29:39 +01:00
Test
e3d3331bbc feat: full Unicode emoji picker with name search and continuous scroll
Replace curated ~270 emoji subset with full Unicode set (1900+) via
unicode-emoji-json. Emoji search now works by English name (e.g.
"rocket" → 🚀). All emojis visible in continuous scroll with sticky
category headers and icon-based quick-nav tabs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:31:13 +01:00
Test
c85e3b4f2f feat: add filter pills (Open/Archived/Trashed) with count badges to note list
When viewing a type in the sidebar, the note list now shows filter pills
below the header to switch between Open, Archived, and Trashed notes.
Each pill shows a count badge. Bulk actions are context-aware: Trashed
filter offers Restore/Archive/Delete permanently, Archived filter offers
Unarchive/Trash. Cmd+K commands added for switching filters.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 03:43:23 +01:00
Test
e1c545220f 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
Test
e6b3278fea 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
Test
76de05e9b3 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
Test
fa49251459 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
Test
08668854b9 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
5a081b06d4 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
Test
38021d231d refactor: reorder wikilink resolution for flat vault
Multi-pass resolution now prioritizes filename stem (strongest) over
alias over title. Removes path-based matching (e.path.endsWith). Legacy
path-style targets like "person/alice" still work by extracting the
last segment "alice" and matching by filename/title.

This matches the flat vault convention where filename IS the note's
identity — filename stem is always slugify(title).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 05:06:24 +01:00
Test
23b632ac9f fix: fall back to sub-heading text when snippet has no paragraph content
Notes with only headings/rules after H1 (e.g. project templates, daily
notes) previously showed empty snippets. Now extract_snippet collects
sub-heading text as fallback. Also hides the snippet div when empty to
avoid blank gaps in the note list. Bumps cache version to 8 for rescan.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 04:42:31 +01:00
Test
ee556aa004 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
Test
b3126044e8 refactor: flatten vault structure — simplify migration API and flatten demo vault
- Simplify flatten_vault API to return usize instead of MigrationResult struct
- Add KEEP_FOLDERS: attachments/ and _themes/ alongside type/, config/, theme/
- Use HashSet for collision tracking in unique_filename
- Update wikilinks from path-based [[folder/slug]] to title-based [[slug]]
- Clean up empty directories after flattening
- Flatten demo-vault-v2: move all notes from type-based subfolders to root
- Update smoke tests for flat vault structure
- Remove migrate_to_flat_vault from repair_vault (one-time migration only)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 23:40:47 +01:00
Test
b2bb7cf661 feat: title = filename — wikilink resolution + slug collision detection
- Wikilink resolution order: filename stem (primary) → alias → title (fallback)
- Slug collision detection: auto-suffix (-2, -3, etc.) on note creation
- Add slugCollides utility for frontend collision checking
- resolveNewNote accepts entries param for collision-aware creation
- Title editing via H1 heading already triggers file rename (existing flow)
- Update docs/ARCHITECTURE.md with migrate_to_flat_vault command

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 19:50:22 +01:00
Test
7c72494efb fix: write all theme.json defaults to vault theme frontmatter
Previously, only UI chrome colours and 3 editor vars were written to
theme note frontmatter. CSS vars like --lists-bullet-size, --headings-h1-font-size,
etc. remained unset, so EditorTheme.css rules had no effect.

- Expand DEFAULT_VAULT_THEME_VARS from 46 to 140 entries, covering every
  property from theme.json (editor, headings, lists, checkboxes, inline
  styles, code blocks, blockquote, table, horizontal rule, colors)
- Fix missing px suffix on editor-font-size and editor-max-width
- Add missing semantic vars: bg-card, text-tertiary
- Refactor built-in vault themes from const strings to generated functions
  with per-theme colour overrides (DRY, all themes get editor properties)
- Quote var() references in frontmatter to prevent YAML parse issues
- Add regression tests for create_vault_theme and seed_vault_themes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:28:23 +01:00
Test
55519e53ad fix: update note list snippet on save so all notes show preview
The snippet was extracted once at vault load time (Rust backend) and
never updated when content was saved. Notes created or edited during
a session showed stale/empty snippets until the next app restart.

Added extractSnippet() to the frontend (mirroring Rust logic) and
wired it into useEditorSaveWithLinks so snippet + wordCount are
updated alongside outgoingLinks on every save.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 22:38:25 +01:00
Test
c499ef30f0 fix: case-insensitive type entry lookup + Playwright smoke test
buildTypeEntryMap now stores both original title and lowercase key so
isA: 'config' matches type entry titled 'Config'. Adds Playwright smoke
test that blocks the vault API to test against mock data fixtures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:24:51 +01:00
Test
b3bf2bf76e fix: sidebar section header reflects type icon, color, and label
- Add GearSix icon ('gear-six') to icon registry — was missing, causing
  Config type to show FileText fallback instead of its configured icon
- Add 'gray' to ACCENT_COLORS palette with CSS variables — was missing,
  causing Config type color to fall back to muted foreground
- Extract sidebar section logic to utils/sidebarSections.ts for testability
- Add Config type + instance to mock entries for browser dev mode
- Add tests: icon resolution, gray color, sidebar section builder

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:24:51 +01:00
Test
0ee6e76d10 fix: post-process BlockNote serializer to remove extra blank lines
blocksToMarkdownLossy() inserts blank lines between every block, making
tight lists loose and polluting git history. Add compactMarkdown() that
collapses inter-list-item blanks and excessive blank line runs while
preserving code blocks and intentional paragraph spacing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 19:38:05 +01:00
Test
61760c4a41 fix: unify wikilink resolution and disambiguate duplicate titles
- Create resolveEntry() in wikilink.ts: single case-insensitive resolution
  function that handles title, alias, filename stem, path suffix, and
  pipe syntax matching
- Replace findEntryByTarget (case-sensitive) and entryMatchesTarget
  (hardcoded /Laputa/ path) with unified resolveEntry
- Fix attachClickHandlers to insert path|title pipe syntax when multiple
  candidates share the same title (disambiguation)
- Update ai-context.ts resolveTarget to use unified resolution
- Add comprehensive tests for resolveEntry and disambiguation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 19:12:05 +01:00
Test
90bf73524c fix: bump cache version + handle Yes/No in TS frontmatter parser
Root cause: commit 4743537 added a custom Rust deserializer for
Archived/Trashed Yes/No strings but did not bump CACHE_VERSION.
Existing vaults had stale cached entries with archived: false from the
old parser, and since the cache version (5) matched, stale values were
served without re-parsing from disk.

- Bump CACHE_VERSION 5 → 6 to force full rescan on next vault load
- Add Yes/No handling to TypeScript parseScalar (Inspector display)
- Add integration tests: cached vault path with Archived/Trashed: Yes
- Add stale cache version invalidation test
- Add frontmatter.test.ts for TS Yes/No boolean parsing
- Add Playwright smoke test for archived note filtering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:07:22 +01:00
Test
60fd4d9ade fix: embed conversation history in AI agent chat messages
The AI chat panel (AiPanel → useAiAgent) was sending each message as a
standalone request with no prior context. Root cause: useAiAgent.sendMessage
called streamClaudeAgent with raw text, never embedding history.

- Add agentMessagesToChatHistory() to convert AiAgentMessage[] to ChatMessage[]
- Embed trimmed history in each agent request via formatMessageWithHistory
- Use messagesRef/statusRef to avoid stale closures in async callbacks
- Also fix useAIChat (dead code path) with same ref pattern
- Update mock layers to detect history presence for testability
- Add Playwright smoke tests verifying history accumulates and resets

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:21:49 +01:00