- Page size reduced from 30 → 20 commits per fetch
- Backend: add `skip` param to get_vault_pulse (git log --skip)
→ true pagination instead of re-fetching everything
- Frontend: IntersectionObserver sentinel at bottom of feed
→ auto-loads next page when user scrolls near end
- Append-only updates (no full re-render on load more)
- Add IntersectionObserver mock to test setup
jsdom@28's JSDOMDispatcher passes an onError handler incompatible with
Node 22's bundled undici, causing InvalidArgumentError (UND_ERR_INVALID_ARG)
on CI. Stubbing globalThis.fetch prevents the dispatcher from being invoked.
The previous uncaughtException handler was insufficient — it caught the wrong
error code and didn't handle unhandled rejections.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Re-add useSortable listeners that were removed in the realignment
refactor. The entire section header row is now the drag target (no
visible handle icon needed). PointerSensor's distance:5 constraint
ensures clicks for collapse/expand don't conflict with drag.
Also suppress pre-existing undici WebSocket ERR_INVALID_ARG_TYPE in
test setup (jsdom Event ≠ Node Event incompatibility).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tabs now dynamically reduce their max-width when the total width exceeds
the TabBar container, similar to browser tab behavior. Uses a
ResizeObserver on the tab area to calculate per-tab max-width as
min(360, containerWidth / tabCount), floored at 60px minimum.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PR #98 added react-day-picker via shadcn/ui Calendar but the package
was not yet installed in node_modules. This broke 5 test files at import
resolution time:
- src/App.test.tsx
- src/components/Editor.test.tsx
- src/components/Inspector.test.tsx
- src/components/InspectorPanels.test.tsx
- src/components/DynamicPropertiesPanel.test.tsx
Fix: add a vitest mock for react-day-picker in the global test setup
(same pattern as the existing react-virtuoso mock). DayPicker renders
a real calendar widget that requires DOM APIs unavailable in jsdom —
mocking it to null is the correct approach for unit/integration tests
that don't test date-picker behavior specifically.
Before: 5 failed | 48 passed (764 tests)
After: 0 failed | 53 passed (929 tests)
* 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>
Replace require('react') with ESM imports of createElement and types
from React. This fixes the TS2591 error in tsc build for setup.ts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the direct .map() rendering in ListView with react-virtuoso's
Virtuoso component. This ensures only visible items are in the DOM,
making the list performant with 9000+ notes.
Key changes:
- ListView now uses <Virtuoso> with data prop and overscan={200}
- PinnedCard and TrashWarningBanner rendered as Virtuoso Header component
- Empty state still renders without virtualization (no items to virtualize)
- mock-tauri.ts now generates 9000 bulk entries for testing
- Test setup mocks react-virtuoso for JSDOM compatibility
Product decision: EntityView (relationship groups) is NOT virtualized
because relationship groups are typically small (<100 items). Only the
flat ListView needed virtualization since it can contain 9000+ items.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Scaffold Vite + React + TypeScript frontend
- Add Tauri v2 backend with Rust
- Implement list_vault command: recursively scans .md files, parses
YAML frontmatter (Is A, aliases, Belongs to, Related to, Status,
Owner, Cadence), extracts title from H1 or filename
- 10 passing Rust tests for frontmatter parsing and vault scanning
- Configure Vitest and Playwright (test infrastructure)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>