All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
-
Storage adapter:
DiskDriverseam,DiskAdapter(injected driver), 4 newtrachyte-fsops (delete/list/exists/mkdir) + IPC commands, vitest harness for@trachyte/core -
Vault manager: real
VaultManager(open/create/adopt/listwith vault-layout validation, typedVaultError, current-vault state); dir-awareMemoryAdapter(directory tracking, immediate-childrenlistFiles); vitest for all methods -
Settings service:
SettingsService(load/savewith.bak(last-known-good fallback), runtime schema validation,schema_versionstamping + version gate);isSettingstype guard; sharedjoinPathpath util (now used byVaultManagertoo) -
External file-change reload: debounced
ExternalChangeReloader(file:changed/file:createdtriggers a reload after a 100 ms quiet window);watch_vaultIPC now relaysnotifyevents to the frontend via thetrachyte://fs-eventTauri event -
Minimal open-vault / open-note demo in
Home.tsx: type a vault path, open a note, watch external edits sync into the editor -
Vault path resolution:
home_dirIPC command (dirs) +resolveHomePathin core —~/and relative vault paths now resolve to absolute paths anywhere on disk -
trachyte doctordev-tools:doctorIPC command (vault validity + missing dirs/files +schema_versionvalue), core aggregator (buildDoctorReport/settingsValidityreusingisSettings), and aDoctorPanelopened via the sidebar "Run doctor" button orCtrl+Shift+D -
trachyte-dbSQLite bootstrap:Databasewrapper (open → pragmas → migrate) withPRAGMA journal_mode=WAL/synchronous=NORMAL/foreign_keys=ON; schema v1 (files/headings/tags/backlinkswithON DELETE CASCADE); FTS5 mirror tablecontent_fts(porter tokenizer) +search; BLAKE3hash_content; versioned migration runner (PRAGMA user_version, one tx per migration) -
trachyte-dbIPC exposure:index_search/index_insert_filecommands (per-call open of<vault>/.trachyte/index.db),IpcError::InvalidQueryfor malformed FTS5 queries,IpcError::Db, typedipc/db.tswrapper -
Event-driven
Indexerin core (upsert/delete/rename on vault events + startup sweep that converges missed events);IndexDriverseam +MemoryIndexDriver(test default) andtauriIndexDriverin the app;extractIndexContentfrontmatter strip;IndexedFileMeta/IndexEventtypes; write commandsindex_upsert_file/index_delete_file/index_list_files+ typedipc/db.tswrappers -
Transactional
Indexer.rebuild()(single-tx wipe-and-rebuild intrachyte-db, deletes corrupt<vault>/.trachyte/index.db*first);index_rebuildIPC command;IndexDriver/MemoryIndexDriver/tauriIndexDriverrebuildsupport; "Rebuild index" button inDoctorPanel;Indexernow wired into the app (started on vault open, disposed on close);insert_file/upsert_fileare transactional (files row + FTS refresh in one tx) -
Core search service (
SearchService.search(query)returning typedHit[]from the index only, never parses MD at query time); filename + content submodes with disjoint, deduplicated hits (filename ranked first);IndexDriver/MemoryIndexDriver/tauriIndexDrivergainsearch(memory substring / existingindex_searchIPC);normalizeQuery; vitest specs + 10k-note p95 < 50 ms perf check -
Search UI:
SearchPalettemodal (Ctrl+Shift+F+ sidebar "Search" button) with a hand-rolled focus trap,role=dialog/aria-modal="true", listbox/option semantics viaaria-activedescendant/aria-selected, keyboard nav (arrows/Enter/Escape/Tabwrap) and submode badges;useSearchhook (150 ms debounce, stale-response guard, injectableSearchServicefor tests); desktop test harness (vitest + jsdom + testing-library + axe-core) with functional specs and an axe smoke test -
Wikilinks + block refs in CM6:
wikilinks()extension ([[target]]highlighted, title-first +path//.mdescape-hatch resolution, resolved vs faint-unresolved styling, click-to-open note viahandleWikilinkClick);blockRefs()extension (^idline-end definitions decorated,#^iddecoded in link targets);CodeMirrorEditorgainslinks/onOpenLinkprops (resolution data injected from the app — editor stays Tauri-free);Home.tsxbuilds the title→path index fromVaultManager.list()and wires link navigation; first@trachyte/editorvitest harness (resolver + wikilink extension specs) -
Link/heading/tag data layer: MD parser extracts
[[wikilinks]](char-offset positions),#headings, and#tags;Indexerpersists them to theheadings/tags/backlinkstables via the newIndexDriver.storeExtractedmethod;IndexDriver.backlinks(vaultPath, target)query returns source notes + char positions (Ruststore_extracted/list_backlinks, IPCindex_store_extracted/index_list_backlinks, desktop wrappers); wikilink resolver relocated into core and shared with the editor -
BacklinksPane: right-hand pane showing backlinks for the open note with click-to-navigate
-
Wikilink block references:
[[note#^blockId]]now scrolls to the^blockIdline in the target note -
Editor
scrollToPosprop for programmatic scrolling to character positions -
Fixed duplicate
Ctrl+Shift+Dkeydown handler in Home.tsx
- CI Hardening for
ci.ymlnow checks inside app/desktop to confirm build ablility
- Vault creation no longer lands inside the app's working tree (
apps/desktop/src-tauri/…), which causedtauri devrebuilds to restart the window and wipe the open vault/note state - External-change reloader no longer unsubscribes itself under React StrictMode (idempotent
start()/dispose()lifecycle) - Doctor panel layout: "Rebuild index" button and its result no longer render inside the header row (was breaking the
flexheader layout) - Doctor panel modal a11y: focus trap (Tab wraps close ⇄ rebuild),
Escapeto close, auto-focus on open, accessible name viaaria-labelledby Home.tsx: index rebuild no longer uses theindexer!non-null assertion