Commits
First real dogfooding feedback:
- new daily journal page silently required an app restart to appear: check_journal_rollover only ran as a side effect of render(), and GPUI doesn't repaint on a frame timer, only in response to input, so a window left open past midnight never noticed. Added a self-rescheduling background timer (60s) independent of interaction.
- added a calendar picker (Ctrl+Shift+C or the header button): month grid, click a day to jump to/create its journal page, bolds days with existing entries, highlights today. Also serves as a manual escape hatch for #1.
- added clickable back/forward buttons in the header for mouse-driven navigation, alongside the existing Alt+Left/Alt+Right
- README.md: build/run, graph directory format, keyboard reference, query language reference with examples, documented deviations from spec
- design.md: D3 rewritten to reflect gpui-component removal; Risks section updated; new Reconciliation section
- performance pass finding: cold start at 100k blocks is ~1.5-2s using the real GraphIndex::rebuild + SearchIndex (not Spike S3's simplified stand-in), over the original ~1s budget — documented as a known gap, not fixed (personal-notebook scale is expected to stay well under 100k blocks)
8.1 (week-long dogfood checkpoint) intentionally left unchecked — requires real usage over time.
- Ctrl+Shift+Q toggles the focused block into/out of a query block (persisted as a 'query' property, not special content syntax)
- hand-rolled Scheme tokenizer (scheme_highlight.rs) for syntax highlighting + multi-line matching-paren indication in BlockEditor; documented the tree-sitter-vs-hand-rolled tradeoff in design.md
- debounced background evaluation via eval_query, off the UI thread (background OS thread + oneshot channel awaited from a foreground gpui::Task), with a per-block generation counter guarding stale results
- outline-slice and sortable-table result rendering, Markdown-formatted (not raw source), indented and visually distinct from ordinary rows
Fixes along the way:
- query_eval_generation was a single global counter; scheduling one query block's lazy eval could invalidate another block's in-flight debounced eval as 'stale', permanently stranding an error result since an error still counts as a cached result and skips the lazy-retry path. Made per-block.
- result list items now render through the Markdown pipeline instead of showing raw source
- fixed result indentation (missing the fold-column allowance every row reserves) and the result background (was using padding, which paints under itself, instead of margin, which actually moves the box) so the result reads as an inset card nested under the query, not a full-width block flush with it
Phase 7 (Query Blocks UI) complete: 7.1-7.5.
- dedicated 'Similar' panel below backlinks, refreshed on every focus change, using GraphIndex-based lexical similarity (excludes self/ancestors/descendants) with the same highlighted-snippet rendering as search
- resolves design.md's 'Similar-blocks UX' open question in favor of a panel over an inline footer, reusing the backlinks/search pattern instead of teaching every row renderer a second footer kind
Phase 6 (Journal & Navigation) complete: 6.1-6.8.
- Ctrl+F overlay: type to search, ranked results with <b>-highlighted snippets, up/down to select, enter/click to jump into the containing page
- SearchIndex kept fresh incrementally at each edit site (commit/split/merge), full rebuild on the rarer structural events (rollover, page materialization)
- render snippets by hand-parsing tantivy's <b> markup into bold/plain spans, unescaping the 5 entities htmlescape::encode_minimal emits (including the easy-to-miss hex ' for apostrophes)
- Ctrl+K fuzzy switcher over pages, tags, and journal-date shortcuts
- widen View::Node from TreeID to NodeId so tags/dates are navigable like pages (fixes following an uncreated [[Page]] or #tag reference being a dead end)
- resolve_date() unifies 'today'-style shortcuts with the actual journal page so they never diverge into two nodes
- root_focus fallback so app-level shortcuts (Ctrl+K, zoom, back/forward) still dispatch on a Tag/Date view with no editable row focused
- '+ Create page' / Ctrl+Enter materializes a real page from an uncreated tag/page/date view
- dedupe quick-open results by target node; drop the '#' prefix for NodeId::Tag display since it may equally be an uncreated page
- journal timeline home view with date-rollover handling and empty-page suppression
- Ctrl+Enter follow-reference; Alt+Left/Right navigation history
- backlinks panel grouped by containing page
- Ctrl+./Ctrl+, block zoom with ancestor breadcrumb
- fix invisible/unclickable empty blocks (zero-height Markdown rows) and the page-title-as-block corruption bug it caused (Enter/Backspace on a page root could fragment or delete pages)
- replace uniform_list with gpui::list for correct variable-height rows; align bullet/fold marker to first line
First real dogfooding feedback:
- new daily journal page silently required an app restart to appear: check_journal_rollover only ran as a side effect of render(), and GPUI doesn't repaint on a frame timer, only in response to input, so a window left open past midnight never noticed. Added a self-rescheduling background timer (60s) independent of interaction.
- added a calendar picker (Ctrl+Shift+C or the header button): month grid, click a day to jump to/create its journal page, bolds days with existing entries, highlights today. Also serves as a manual escape hatch for #1.
- added clickable back/forward buttons in the header for mouse-driven navigation, alongside the existing Alt+Left/Alt+Right
- README.md: build/run, graph directory format, keyboard reference, query language reference with examples, documented deviations from spec
- design.md: D3 rewritten to reflect gpui-component removal; Risks section updated; new Reconciliation section
- performance pass finding: cold start at 100k blocks is ~1.5-2s using the real GraphIndex::rebuild + SearchIndex (not Spike S3's simplified stand-in), over the original ~1s budget — documented as a known gap, not fixed (personal-notebook scale is expected to stay well under 100k blocks)
8.1 (week-long dogfood checkpoint) intentionally left unchecked — requires real usage over time.
- Ctrl+Shift+Q toggles the focused block into/out of a query block (persisted as a 'query' property, not special content syntax)
- hand-rolled Scheme tokenizer (scheme_highlight.rs) for syntax highlighting + multi-line matching-paren indication in BlockEditor; documented the tree-sitter-vs-hand-rolled tradeoff in design.md
- debounced background evaluation via eval_query, off the UI thread (background OS thread + oneshot channel awaited from a foreground gpui::Task), with a per-block generation counter guarding stale results
- outline-slice and sortable-table result rendering, Markdown-formatted (not raw source), indented and visually distinct from ordinary rows
Fixes along the way:
- query_eval_generation was a single global counter; scheduling one query block's lazy eval could invalidate another block's in-flight debounced eval as 'stale', permanently stranding an error result since an error still counts as a cached result and skips the lazy-retry path. Made per-block.
- result list items now render through the Markdown pipeline instead of showing raw source
- fixed result indentation (missing the fold-column allowance every row reserves) and the result background (was using padding, which paints under itself, instead of margin, which actually moves the box) so the result reads as an inset card nested under the query, not a full-width block flush with it
Phase 7 (Query Blocks UI) complete: 7.1-7.5.
- dedicated 'Similar' panel below backlinks, refreshed on every focus change, using GraphIndex-based lexical similarity (excludes self/ancestors/descendants) with the same highlighted-snippet rendering as search
- resolves design.md's 'Similar-blocks UX' open question in favor of a panel over an inline footer, reusing the backlinks/search pattern instead of teaching every row renderer a second footer kind
Phase 6 (Journal & Navigation) complete: 6.1-6.8.
- Ctrl+F overlay: type to search, ranked results with <b>-highlighted snippets, up/down to select, enter/click to jump into the containing page
- SearchIndex kept fresh incrementally at each edit site (commit/split/merge), full rebuild on the rarer structural events (rollover, page materialization)
- render snippets by hand-parsing tantivy's <b> markup into bold/plain spans, unescaping the 5 entities htmlescape::encode_minimal emits (including the easy-to-miss hex ' for apostrophes)
- Ctrl+K fuzzy switcher over pages, tags, and journal-date shortcuts
- widen View::Node from TreeID to NodeId so tags/dates are navigable like pages (fixes following an uncreated [[Page]] or #tag reference being a dead end)
- resolve_date() unifies 'today'-style shortcuts with the actual journal page so they never diverge into two nodes
- root_focus fallback so app-level shortcuts (Ctrl+K, zoom, back/forward) still dispatch on a Tag/Date view with no editable row focused
- '+ Create page' / Ctrl+Enter materializes a real page from an uncreated tag/page/date view
- dedupe quick-open results by target node; drop the '#' prefix for NodeId::Tag display since it may equally be an uncreated page
- journal timeline home view with date-rollover handling and empty-page suppression
- Ctrl+Enter follow-reference; Alt+Left/Right navigation history
- backlinks panel grouped by containing page
- Ctrl+./Ctrl+, block zoom with ancestor breadcrumb
- fix invisible/unclickable empty blocks (zero-height Markdown rows) and the page-title-as-block corruption bug it caused (Enter/Backspace on a page root could fragment or delete pages)
- replace uniform_list with gpui::list for correct variable-height rows; align bullet/fold marker to first line