Commit Graph

1410 Commits

Author SHA1 Message Date
lucaronin
0fb115bbe1 feat: show vault-relative path below title in editor
Notes in subdirectories now display their vault-relative path
(e.g. docs/adr/0001-tauri-stack.md) as small muted text below
the title field. Root-level notes show no path. Note list entries
do not display any path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 19:02:42 +02:00
lucaronin
cd39070569 fix: remove H1 heading from new note editor body
Title is already shown as a separate UI element above the editor,
so the H1 in the body was a visual duplicate. New notes now have
an empty editor body. Daily notes and type entries also no longer
get an H1 inserted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:29:02 +02:00
lucaronin
ccf1b8517e fix: apply rustfmt formatting to vault scanner code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 17:39:55 +02:00
lucaronin
d037272741 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
lucaronin
c7f857f24b fix: use is_some_and instead of map_or for clippy compliance
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:13:38 +02:00
lucaronin
620515ecea 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
lucaronin
a34274db25 feat: add custom views backend — YAML parser, filter engine, Tauri commands
Introduce `.laputa/views/*.yml` for user-defined filtered note lists.
Rust backend: serde_yaml parsing, recursive AND/OR filter evaluation
with 10 operators (equals, contains, any_of, is_empty, before/after,
etc.), wikilink stem matching, and file CRUD. Three Tauri commands:
list_views, save_view_cmd, delete_view_cmd.

ADR 0040 documents the architecture.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:57:22 +02:00
lucaronin
927e0e11e7 fix: show note title instead of filename in search results
Search results now display the VaultEntry title (from frontmatter)
when available, falling back to the filename-based title from the
search backend when no VaultEntry match is found.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:30:15 +02:00
lucaronin
d65bea0552 fix: apply rustfmt formatting to git dates code
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:03:41 +02:00
lucaronin
30f8820a29 feat: use git history for note creation/modification dates
Replace unreliable filesystem ctime/mtime with git log timestamps.
A single batch `git log` walks the full commit history to extract
created_at (oldest commit) and modified_at (newest commit) for each
.md file. Falls back to filesystem dates for non-git vaults and
uncommitted files. Cache version bumped to 10 for full rescan.

ADR 0039 documents the decision.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 15:00:22 +02:00
lucaronin
292f751461 fix: add favorite/favoriteIndex to all VaultEntry mock data
The tsc -b build (stricter than --noEmit) requires all VaultEntry
fields to be present in mock-entries.ts and useNoteCreation.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:48:05 +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
c85d12ab55 refactor: remove expand/collapse from sidebar type sections
Type sections are now flat rows — clicking selects the section and loads
the note list. Removed chevrons, inline child lists, and "+" buttons.
Added note count chip to each section header. FOLDERS section expand/
collapse is unchanged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 14:11:59 +02:00
lucaronin
fd24777a51 fix: refresh folder tree after creating a new folder
reloadVault() only reloaded entries, not folders — new folders didn't
appear in the sidebar until app reload. Add reloadFolders() to
useVaultLoader and call it from handleCreateFolder.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 13:47:50 +02:00
lucaronin
57b89fc871 fix: reassign AI panel shortcut from Cmd+I to Cmd+Option+I
Cmd+I is the standard italic shortcut in text editors. The AI panel
was overriding it, breaking italic formatting. Reassigned to
Cmd+Option+I (CmdOrCtrl+Alt+I in Tauri menu) which is free.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:28:04 +02:00
lucaronin
49aff89de4 feat: pre-assign type when creating note from type section
When the user clicks "+" in the note list while a type section is
selected (e.g. Projects), the new note now gets that type pre-set in
its frontmatter. Previously, all notes were created as generic "Note"
type regardless of the selected section.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 10:06:40 +02:00
lucaronin
c64a3e5d52 fix: use percentage heights instead of 100vh to fix status bar visibility in native app
With titleBarStyle: "Overlay" in Tauri, 100vh in WKWebView includes the
overlaid title bar area, making the app-shell taller than the visible
viewport. The 30px StatusBar (including the Commit button) was pushed
below the visible area and clipped by overflow:hidden. Using height:100%
chains from html→body→#root→app-shell to correctly constrain to the
visible viewport.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 09:45:10 +02:00
lucaronin
a353509038 fix: reduce editor minimum width and padding at narrow sizes
Halve the editor min-width from 800px to 400px so the window can be
resized narrower. Add a container query that reduces horizontal padding
from 40px to 16px when the editor panel is under 600px wide, keeping
content readable without wasting space on padding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 02:29:05 +02:00
lucaronin
a525eca980 fix: make commit button always visible in status bar
The commit button was inside ChangesBadge which returned null when
modifiedCount was 0, hiding the button entirely. Extract it into a
standalone CommitButton component that is always visible in the
status bar with a "Commit" text label for discoverability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 23:17:43 +02:00
lucaronin
06bde75d72 fix: rustfmt formatting for fallback YAML parser
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 22:42:45 +02:00
lucaronin
ba056a628b fix: vault scanner fallback parser for malformed YAML frontmatter
Files with malformed YAML (e.g. Notion exports containing unescaped
double quotes inside double-quoted strings) caused gray_matter to return
Pod::Null instead of a parsed Hash. This silently reset all frontmatter
fields to defaults, making trashed/archived notes appear in Inbox.

Add a line-by-line fallback parser that extracts simple key:value pairs
when gray_matter fails, so critical fields (Trashed, Archived, type)
are never lost. Bump cache version to 9 to force rescan.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 22:40:25 +02:00
lucaronin
3cefc75ec3 fix: remove overflow:hidden from status bar to prevent commit button clipping
The commit button inside ChangesBadge was being clipped by overflow:hidden
on the left status bar div when many badges were visible or at high zoom.
Removing the overflow constraint ensures the commit button is always visible.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 16:04:04 +02:00
lucaronin
13e02813a3 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
lucaronin
37f32de292 fix: rustfmt formatting for create_vault_folder
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 15:33:13 +02:00
lucaronin
01fdadf425 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
lucaronin
1488f6eb08 fix: vault selection dropdown hidden behind sidebar
Add position: relative and zIndex: 10 to the StatusBar footer to
establish a proper stacking context, so the vault menu dropdown
(zIndex: 1000) renders above the sidebar instead of behind it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:48:58 +02:00
lucaronin
8a17421000 chore: update ui-design.pen 2026-04-01 11:14:57 +02:00
lucaronin
81f999597c chore: fix CodeScene ratchet thresholds to match remote API scores
Remote CodeScene scores (9.60/9.37) were below over-ratcheted thresholds
(9.84/9.38). Floor thresholds to actual remote values.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 10:48:01 +02:00
lucaronin
4eca9ca8fd fix: prevent infinite render loop when creating notes
updateEntry's .map() always returned a new array even when no entry matched,
causing unnecessary state changes. During note creation, addEntry uses
startTransition (deferred) while markContentPending calls updateEntry
synchronously — the entry doesn't exist yet, so the no-op .map() produced a
new reference that cascaded into "Maximum update depth exceeded" (which
surfaced as React error #185 in the production WKWebView build).

The fix makes updateEntry bail out (return prev) when no entry was changed,
preventing the spurious state update. Also removes the defensive try-catch
from the previous fix attempt and cleans up an unnecessary setToastMessage
dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 10:33:40 +02:00
lucaronin
8365186b7e fix: active section badge shows primary background instead of gray
The inline badgeStyle (background: var(--muted)) was overriding the
Tailwind activeBadgeClassName (bg-primary) because inline styles have
higher specificity. Fixed by not falling back to badgeStyle when
activeBadgeClassName is provided and the item is active.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 18:50:02 +02:00
lucaronin
10c4d79c83 fix: add error handling to createNoteImmediate to prevent crashes
Wraps the note creation flow in try-catch so errors in title
generation, template resolution, or tab opening are logged to
console instead of crashing the app.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 18:34:44 +02:00
lucaronin
fa37f6ad9e 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
lucaronin
06485d517c fix: eliminate scroll stutter and fix breadcrumb shadow consistency
Replace React state (useState + re-render) with direct DOM manipulation
for the breadcrumb title visibility. IntersectionObserver now toggles a
data-title-hidden attribute on the bar element, and CSS handles shadow
+ title visibility. This avoids re-rendering the heavy BlockNote editor
on every scroll intersection change.

Fixes: shadow always appears when title is hidden (CSS-driven, no race),
scroll is smooth (zero React re-renders during scroll).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:48:52 +02:00
lucaronin
f8d94c3097 fix: prevent status bar overflow from hiding commit button
The left div in the status bar had no width constraint, causing items
at the end (commit button, Pulse) to overflow behind the right div
when the window is narrow or zoom is high.

Fixes:
- Add flex:1 + minWidth:0 + overflow:hidden to the left div
- Add flexShrink:0 to the right div so it stays visible
- Move ChangesBadge (with commit button) before SyncBadge so it
  appears earlier and is less likely to be clipped

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:30:10 +02:00
lucaronin
e7c7c49dc0 fix: use floor instead of round in CodeScene ratchet
round(9.8457, 2) → 9.85 which exceeds the actual score, causing
the threshold to be unreachable. Use math.floor to truncate instead:
9.8457 → 9.84, 9.3884 → 9.38.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 17:01:03 +02:00
lucaronin
e19476b069 chore: ratchet CodeScene thresholds to 9.85/9.39 2026-03-31 16:59:41 +02:00
lucaronin
997fa477bf chore: round down CodeScene thresholds to match actual scores
Actual scores are 9.8457/9.3884 — previous thresholds 9.85/9.39
were above the actual values due to rounding up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 16:44:44 +02:00
lucaronin
b9dd9eb9dc fix: normalize property row and chip heights for consistent layout
All chips (type, status, date, tags, boolean, color, text, URL) now use
h-6 (24px) with inline-flex + items-center, and PropertyRow has min-h-7
(28px) so every row aligns regardless of property type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 16:30:22 +02:00
lucaronin
1e71869395 chore: ratchet CodeScene thresholds to 9.85/9.39 2026-03-31 14:28:14 +02:00
lucaronin
407d78c066 chore: fix ratchet thresholds — round down to match actual scores
The auto-ratchet rounded 9.845→9.85 and 9.388→9.39, creating thresholds
higher than the actual scores. Fix by rounding down.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 14:13:53 +02:00
lucaronin
4022129481 style: cargo fmt — fix pre-existing Rust formatting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:54:18 +02:00
lucaronin
5a791d8a26 test: add Playwright + Vitest tests for raw editor type propagation
Verifies that editing the type field in the raw editor (Cmd+\) immediately
updates the Properties panel type selector without navigation or reload.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:51:48 +02:00
lucaronin
e1efcf63e0 fix: propagate frontmatter changes from raw editor to vault entries
When editing type/status/color/icon in the raw editor (Cmd+\), changes
now immediately flow into the reactive VaultEntry state, updating the
Properties panel, note list, and sidebar without save/reload.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:32:55 +02:00
lucaronin
f89904620a docs: task not done until git push succeeds — fix pre-push failures before marking done 2026-03-31 12:27:53 +02:00
lucaronin
44f59432c0 fix: use next_back() instead of last() on DoubleEndedIterator (clippy) 2026-03-31 12:23:28 +02:00
lucaronin
93b83007eb feat: detect external file renames and offer wikilink update via banner
When the app regains focus, checks git diff for renames (--diff-filter=R).
If renamed .md files are found, shows a non-blocking banner with "Update
wikilinks" and "Ignore" buttons. The update reuses the existing vault-wide
wikilink replacement logic from rename.rs.

New Tauri commands: detect_renames, update_wikilinks_for_renames.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:58:32 +02:00
lucaronin
3ede96a437 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
lucaronin
4dd30c53b9 feat: move filter chips to bottom of note list with gradient fade
Move FilterPills and InboxFilterPills from the top (below header) to
a floating position at the bottom of the note list. When position is
"bottom", pills are absolutely positioned with a gradient background
(transparent → card color) to create a "floating above content"
effect. Pills are centered with gap-2 and wrap to multiple lines.
Matches the ui-design.pen "Filter Pills Bar" frame.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:38:13 +02:00
lucaronin
5db92fa94c fix: remove duplicate invoke import in App.tsx
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:32:23 +02:00
lucaronin
e693ac2b21 feat: show blocking modal when vault has no git repo, offer auto-init
When opening a vault without a .git directory, a blocking modal prevents
app use until the user either creates a repository (git init + add +
commit) or chooses another vault. The check runs via is_git_repo Tauri
command; browser mode fails open.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 11:30:39 +02:00