Commit Graph

63 Commits

Author SHA1 Message Date
lucaronin
b0b6a4f4cd feat: add regex mode for view filters 2026-04-07 22:51:23 +02:00
lucaronin
9cc3bcf758 feat: customize inbox note list columns 2026-04-07 20:31:08 +02:00
lucaronin
d50f3479dc feat: H1-as-title — title resolution, TitleField hiding, breadcrumb filename
- Rust: extract_title now prioritizes H1 > frontmatter > filename
- Rust: add has_h1 field to VaultEntry for frontend TitleField control
- Frontend: hide TitleField + icon picker when note has H1 in body
- Frontend: breadcrumb shows filename stem instead of display title
- Frontend: new notes use untitled-{type}-{timestamp}.md, no title in frontmatter
- CSS: only hide first H1 in BlockNote when TitleField is visible
- Updated all tests for new title resolution and note creation behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 13:08:17 +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
de8a246521 feat: remove AI Provider Keys section from Settings
The OpenAI and Google AI key fields were unused — no feature reads them.
Removes the UI section, KeyField component, and all related state/storage
code across frontend (types, hooks, mock handlers, tests) and Rust backend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 01:34:30 +02:00
lucaronin
49d7353f2d refactor: replace relationship-based inbox logic with _organized property
Inbox now uses an explicit _organized frontmatter property instead of
inferring organization from relationships. This is simpler and gives
users direct control over inbox membership.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 20:45:25 +02:00
lucaronin
8d90b8489b feat: add type-specific property chips in note list
Parse _list_properties_display from type file frontmatter and render
property/relationship values as chips below note snippets. Add a
SlidersHorizontal config popover in the note list header (sectionGroup
views only) with checkboxes and drag-to-reorder via dnd-kit. Changes
are saved back to the type file's frontmatter immediately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:52:54 +02:00
lucaronin
0be1060d81 fix: remove Update channel from Settings, keep only Release channel
Update channel (Stable/Canary) was redundant since builds are flat.
Removed the UI dropdown, canary update logic in useUpdater, and
update_channel field from Settings type (TS + Rust). Release channel
(Alpha/Beta/Stable) remains as the sole selector.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:11:26 +02:00
lucaronin
05a4194159 feat: release channels (alpha/beta/stable) via PostHog feature flags
- Add `release_channel` to Settings (Rust + TypeScript)
- Add channel selector in Settings panel (alpha/beta/stable)
- Pass `release_channel` as PostHog person property on identify
- Add `isFeatureEnabled()` helper: alpha always true, beta/stable
  use PostHog flags with hardcoded fallback defaults
- Update `useFeatureFlag` to delegate to PostHog-backed evaluation
  (localStorage overrides still work for dev/QA)
- Create ADR-0042 (supersedes ADR-0017)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:22:28 +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
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
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
5fe18c017c 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
lucaronin
9df41c3287 refactor: remove Anthropic API integration, CLI agent only (ADR-0028)
Remove AIChatPanel, useAIChat hook, Rust ai_chat command, and
anthropic_key from settings. AI is now exclusively via Claude CLI
subprocess (AiPanel). Simplifies codebase and eliminates API key
management for users. ADR-0027 superseded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 15:05:56 +02:00
lucaronin
bfbc9d49d1 revert: remove pinned properties feature
Reverts commits d263e43, ae2260c, 473239b, aaa4691, cd7a570, 3cd097d.
Removes PinnedPropertiesBar, usePinnedProperties hook, Rust backend
for _pinned_properties, and all related tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:20:31 +01:00
lucaronin
2799d8f0a6 feat: add canary release channel and local feature flags
Add update_channel setting (stable/canary) to Settings with UI toggle.
Stable channel uses Tauri updater plugin; canary fetches latest-canary.json
and opens GitHub release page for manual download. Add useFeatureFlag()
hook with localStorage overrides and compile-time defaults (no remote
dependencies). Add release-canary.yml CI workflow for canary branch builds.
Update stable workflow to preserve latest-canary.json on GH Pages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 17:51:33 +01:00
lucaronin
d7166ea993 feat: add telemetry consent fields to Settings (Rust + TypeScript)
New fields: telemetry_consent, crash_reporting_enabled, analytics_enabled,
anonymous_id. All Option/null by default for backward compatibility with
existing settings.json files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 16:05:13 +01:00
lucaronin
cd7a570240 feat: add Rust backend for pinned properties + refactor hook complexity
- Add PinnedPropertyConfig struct to VaultEntry (Rust)
- Extract _pinned_properties from YAML frontmatter (key:icon format)
- Filter underscore-prefixed system properties from properties/relationships
- Bump vault cache version to 9
- Refactor usePinnedProperties hook (cc 15→8) for CodeScene compliance
- Add 6 Rust tests for pinned properties extraction
- Add pinnedProperties field to TypeScript VaultEntry interface
- Wire _pinned_properties mapping in frontmatterOps entry patch

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 10:37:52 +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
fdf8af288f fix: store ui.config.md at vault root instead of config/ directory
Repair Vault was creating config/ui.config.md inside a config/ subdirectory.
All vault config files should live at vault root (flat structure). Changed
config_path() to point to vault root, added migrate_ui_config_to_root() for
legacy migration, and wired it into both startup and repair_vault flows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 21:00:19 +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
8155b940a4 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
lucaronin
7db3c2f00a 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
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
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
902a545c23 feat: surface actionable push error messages in frontend
Update commitWithPush to parse GitPushResult from backend and show
specific messages (rejected, auth, network) instead of generic
"push failed". Tests verify rejected + network error scenarios.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 00:31:46 +01:00
lucaronin
95f6c05053 refactor: remove Favorites and Untagged from sidebar
- Remove Favorites NavItem, Star icon import, go-favorites command
- Remove Untagged NavItem, TagSimple icon import
- Remove favorites from SidebarFilter union type
- Update tests: Sidebar.test.tsx, useMenuEvents.test.ts, App.test.tsx
- Remove GO_FAVORITES constant and menu item from menu.rs
2026-03-06 23:19:37 +01:00
lucaronin
4df386d310 refactor: remove hidden_sections from VaultConfig and delete useSectionVisibility
Sidebar section visibility is now controlled entirely by the `visible`
property on Type notes. Removes all hidden_sections references from
Rust struct, TypeScript interface, config migration, mock data, and tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 21:41:00 +01:00
lucaronin
f7ac01ad1f feat: filter sidebar sections by Type entry visible property
Replace useSectionVisibility hook with direct filtering on
typeEntryMap[type]?.visible !== false. Add onToggleTypeVisibility
callback prop. Tests updated to verify visible:false hides sections.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 21:33:47 +01:00
lucaronin
559c585a08 feat: add Pulse — vault activity feed showing git commit history
Adds a new Pulse sidebar section that shows chronological git commit
history for the vault. Commits are grouped by day with message, time,
short hash (clickable GitHub link when remote configured), file list
with add/modify/delete status icons, and summary badges. Clicking a
file opens the note in the editor. Disabled with tooltip for non-git
vaults. Accessible via sidebar click or "Go to Pulse" command palette.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:27:29 +01:00
lucaronin
6b13120fa6 feat: move vault UI config from localStorage to vault files
Add VaultConfig infrastructure (store, hook, migration) that persists
zoom, view mode, section visibility, tag/status colors, and property
display modes to config/ui.config.md in the vault instead of localStorage.

- New vaultConfigStore module with subscribe/notify pattern
- useVaultConfig hook loads config via Tauri, binds store, runs migration
- One-time silent migration from localStorage on first load
- Config type excluded from note search and unified search
- All hooks/utils updated to read/write through vault config store
- Tests updated to use vault config store instead of localStorage mocks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:26:21 +01:00
lucaronin
a966b2cc65 feat: reorganize menu bar with Go, Note, and Vault menus
Add missing command palette commands to menu bar and reorganize into
logical groups: File, Edit, View, Go, Note, Vault, Window. New menus
expose navigation filters, note actions, vault management, themes, and
git operations. Context-sensitive items (archive, trash, diff, raw
editor, commit, conflicts) are greyed out when not applicable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 14:34:03 +01:00
lucaronin
4499fe0ca3 feat: persist note list sort preference in type file frontmatter
Sort preferences for each type's note list are now stored in the type
file's frontmatter (e.g. `sort: modified:desc` in `type/person.md`)
instead of localStorage. This makes preferences portable with the vault
and versionable in git.

- Add `sort` field to Rust Frontmatter/VaultEntry and TS VaultEntry
- NoteList reads sort from type entry's frontmatter when viewing a type
- Sort changes write to type file via update_frontmatter
- Silent migration from localStorage on first access per type
- Relationship group sorts still use localStorage (no type file)
- Fallback to `modified:desc` when no sort preference exists

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 12:18:40 +01:00
Luca Rossi
851e482ab7 feat: sort picker shows custom frontmatter properties (#185)
The sort dropdown now discovers all scalar properties (string, number,
boolean, date) across notes in the current list and shows them below a
separator after the built-in options. Properties that no longer exist
in the current list are gracefully handled by falling back to Modified.

Rust backend extracts custom properties during vault scan so they are
available on every VaultEntry without loading file content on demand.

Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 02:31:18 +01:00
lucaronin
7169634dc3 wip: themes-editable — theme management system WIP (13 files, 1014 insertions) 2026-03-02 23:06:12 +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
Luca Rossi
ee6972113a feat: allow custom sidebar label for type sections (#165)
* feat: allow custom sidebar label for type sections

- Adds sidebarLabel field to vault type config (Rust + frontend)
- Overrides auto-pluralization with user-defined label in sidebar
- Tests updated to cover custom label display

* fix: add missing sidebarLabel field to buildNewEntry and bulk mock generator

---------

Co-authored-by: Test <test@test.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-02 02:01:21 +01:00
Luca Rossi
cae821ef4c feat: vault-native theming system with live reload (#154)
* feat: add theming system design file with 3 frames

Design frames for Settings > Appearance panel, Command Palette
theme switching, and live theme editing flow visualization.

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

* feat: add Rust backend for vault-native theming system

Theme files live in _themes/*.json with colors, typography, and spacing
sections. Vault-level settings (.laputa/settings.json) store the active
theme. Built-in themes (default, dark, minimal) are seeded on vault
creation. All 6 Tauri commands registered: list_themes, get_theme,
get_vault_settings, save_vault_settings, set_active_theme, create_theme.

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

* feat: add frontend theme engine, settings UI, and command palette integration

Wire up useThemeManager hook to load themes via Tauri IPC, apply CSS
custom properties to :root, and support switching/creating themes.
Add Appearance section to Settings panel with color swatches and theme
cards. Register theme switch and create commands in the command registry.

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

* fix: use .to_string() instead of format! for string literal (clippy)

* style: cargo fmt on theme.rs

---------

Co-authored-by: Test <test@test.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:05:14 +01:00
Laputa App
30ca211bb0 feat: in-memory unsaved state for new notes (Cmd+N)
New notes created via Cmd+N now stay in memory until the user
explicitly saves with Cmd+S. This eliminates the disk-write
blocking delay and lets the cursor appear instantly.

- Add 'unsaved' to NoteStatus; blue dot + italic title in tab bar
- useUnsavedTracker in useVaultLoader manages unsaved path set
- useNoteActions skips persist on create, cleans up on close
- useEditorSave accepts unsavedFallback for first-save scenario
- App.tsx wires tracking via contentChangeRef + clearUnsaved

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 18:23:28 +01:00
Luca Rossi
6baa7795df feat: new note creation — unsaved/in-memory state before first save (#112)
* feat: add pendingSave status indicator for new note creation

Track disk write state during note creation with a pulsing green dot
on tab and breadcrumb bar. The pending state resolves to 'new' once
the file is written to disk, giving users clear feedback during the
async save.

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

* test: add tests for pendingSave status lifecycle

Cover resolveNoteStatus priority, createAndPersist callbacks,
TabBar pulsing dot indicator, and BreadcrumbBar "Saving…" text.

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

* docs: add design frames for new note creation pending save state

Two frames in design/new-note-creation.pen:
- Pending save: pulsing green dot, italic title
- Saved: static green dot, normal title

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

* design: add new-note-creation frames (pending save + after first save)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 13:11:31 +00:00
Luca Rossi
8e5cbb2a34 feat: note subtitle — show metadata (date + word count) (#94)
* feat: show metadata subtitle (date + word count) instead of snippet

Replace the note list subtitle with a compact metadata summary showing
relative date and word count (e.g. "2d ago · 342 words") instead of
the first paragraph of note content. Adds word_count to VaultEntry on
the Rust backend, computed during vault scan.

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

* fix: cargo fmt formatting

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 19:50:29 +00:00
Luca Rossi
ba2c1e5b4b feat: git status bar — show last commit link, remove branch name (#92)
* feat: show last commit hash in status bar, remove branch name

Replace the hardcoded "main" branch display with a clickable short SHA
linking to the GitHub commit. Add Rust get_last_commit_info command that
returns the last commit hash and constructs a GitHub URL from the remote.

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

* docs: add design/git-status-bar.pen with new status bar layout

Shows the updated status bar with commit hash link, no branch name,
and annotated change callouts.

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

* ci: retrigger — runner 3 pnpm not found (env issue)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 20:14:46 +01:00
Luca Rossi
369ecdc009 feat: auto-pull vault changes from Git (background sync + conflict handling) (#79)
* feat: add auto-pull vault sync with conflict handling

- Add git_pull, has_remote, get_conflict_files to Rust backend
- Add GitPullResult type and auto_pull_interval_minutes to Settings
- Create useAutoSync hook (pull on launch, focus, periodic interval)
- Update StatusBar with real sync status indicator
- Add pull interval setting to SettingsPanel
- Add mock handler for git_pull
- Update existing tests for new Settings field

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

* test: add tests for git pull, settings, and useAutoSync hook

- Add Rust tests: has_remote, git_pull (no_remote, up_to_date, updated),
  get_conflict_files, parse_updated_files, GitPullResult serialization
- Add frontend tests: useAutoSync (mount pull, focus pull, conflict,
  error, manual trigger, concurrent prevention, no_remote)
- Fix existing settings tests for new auto_pull_interval_minutes field

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

* design: add auto-pull-vault wireframes

Frames showing: sync idle, syncing, conflict indicator,
settings sync section, and conflict toast notification.

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

* fix: add auto_pull_interval_minutes to all Settings literals

Fix build error and test fixtures missing the new field.

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

* fix: cargo fmt

* ci: re-trigger CI after flaky test

* ci: retrigger after disk space cleanup

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:55:16 +00:00
lucaronin
2c8befab93 fix: make backlinks update reactively when wikilinks are added or removed
Backlinks previously relied on scanning allContent (raw markdown), which
was empty in Tauri mode until notes were explicitly saved. Now outgoing
wikilink targets are extracted during Rust vault scan and stored on
VaultEntry. The frontend useBacklinks hook uses this indexed data, and
outgoingLinks update in real-time on content change.

- Add extract_outgoing_links() in Rust parsing + outgoing_links field on VaultEntry
- Add extractOutgoingLinks() TypeScript utility for real-time updates
- Rewrite useBacklinks to use outgoingLinks instead of scanning raw content
- Add cache version invalidation to force rescan on format change
- Extract useEditorSaveWithLinks hook to keep App.tsx under code health threshold

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 18:07:04 +01:00
Luca Rossi
2903196da6 feat: full-text search with qmd backend and SearchPanel UI (Cmd+Shift+F) (#64)
* feat: add search backend (qmd CLI) and design file

- Add search.rs: qmd integration for keyword (BM25), semantic (vsearch),
  and hybrid search modes via CLI JSON output
- Register search_vault Tauri command in lib.rs
- Design file with 3 frames: empty, results, no-results states
- Fix pre-existing test failures: install @tauri-apps/plugin-opener,
  add mock in test setup

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

* feat: add SearchPanel UI with Cmd+Shift+F shortcut

- SearchPanel component: full-text search overlay with keyword/semantic
  mode toggle, debounced search (200ms), arrow key navigation, result
  count + elapsed time display, note type badges from vault entries
- Cmd+Shift+F shortcut registered in useAppKeyboard
- Mock search_vault handler in mock-tauri for browser dev mode
- SearchResult/SearchResponse types in types.ts
- Tests: 15 new tests for SearchPanel + 2 for keyboard shortcut
- scrollIntoView mock in test setup for jsdom compatibility

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

* fix: correct SearchPanel imports for Tauri/browser dual-mode

Use invoke from @tauri-apps/api/core and mockInvoke from mock-tauri
with a searchCall wrapper, fixing the TypeScript build error.

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

* fix: make test_detect_collection_fallback robust when qmd not installed

* fix: reset localStorage between App tests to prevent view mode state leak

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 16:09:50 +00:00
lucaronin
4f03751da5 feat: distinguish new notes (green dot) from modified notes (orange dot)
New notes created in-session show a green dot; existing notes with
uncommitted git changes show an orange dot. Saving a new note clears
the green dot; git commit clears the orange dot.

Introduces NoteStatus type ('new' | 'modified' | 'clean'), extracts
useNewNoteTracker hook and resolveNoteStatus pure function, and adds
onNoteSaved callback to useEditorSave for clearing new-note tracking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:02:22 +01:00
lucaronin
7b02dc1f9d feat: add Changes view for pending modifications
Clicking "N pending" in the status bar or the "Changes" nav item in
the sidebar shows a filtered list of notes with uncommitted changes.
The view updates in real-time as files are saved or committed.

- Add 'changes' filter to SidebarSelection type
- Make StatusBar "N pending" indicator clickable
- Add "Changes" NavItem in sidebar (visible when modifiedCount > 0)
- Filter NoteList by modifiedFiles paths for changes view
- Show "No pending changes" empty state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:32:23 +01:00
lucaronin
2a831e69c6 feat: replace GitHub token field with OAuth device flow login
- Add github_username to Settings type (Rust + TS)
- Add device flow commands: github_device_flow_start, github_device_flow_poll, github_get_user
- Replace manual token KeyField with "Login with GitHub" OAuth button
- Show connected state with username after successful OAuth
- Add disconnect functionality to clear OAuth token
- Update mock-tauri.ts with device flow mock handlers
- Update all tests for new Settings shape

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:06:46 +01:00
lucaronin
6e4119c28b feat: add Rust backend for GitHub vault operations
New github.rs module with three commands:
- github_list_repos: lists user's repos via GitHub API (paginated)
- github_create_repo: creates a new repo with auto_init
- clone_repo: git clone with HTTPS+token auth, configures remote

Also extends Settings with github_token field (Rust + TypeScript),
and adds GithubRepo type to shared types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 08:34:14 +01:00
lucaronin
8b67ae53d4 feat: settings panel UI with API key management
- SettingsPanel modal component with masked key fields + reveal/clear
- useSettings hook reads/writes config via Tauri invoke
- Mock handlers for get_settings/save_settings in mock-tauri
- Settings type added to types.ts
- StatusBar gear icon opens settings (was disabled placeholder)
- Cmd+, keyboard shortcut opens settings
- Anthropic key synced to localStorage for AIChatPanel compatibility

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