Skip to content

feat(web): add health/stats view to the web UI - #416

Merged
EyJunge1 merged 6 commits into
tickernelz:mainfrom
Phototonic:issue-VOX-272-artful-salamander
Oct 18, 2026
Merged

EyJunge1 merged 6 commits into
tickernelz:mainfrom
Phototonic:issue-VOX-272-artful-salamander

Conversation

@Phototonic

@Phototonic Phototonic commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds a read-only health/stats view to the web UI so memory-system health is visible day-to-day instead of requiring manual log/DB audits.

  • Extends GET /api/stats (existing total/byScope/byType unchanged) with:
    • per-shard health: actual memory count vs registered vector count, active flag, file presence, newest/oldest memory timestamps, and a same-tag duplication proxy
    • active user-profile summary: version, per-type item counts, last analyzed
    • a 14-day daily series parsed from the plugin's structured logs: captures, skipped captures, profile/compaction injections, and errors bucketed by message prefix (e.g. Turso ready gate failed, listMemories)
    • log parsing is lazy per request and cached per file by size+mtime; each line is attributed to a day by its own timestamp, so rotation artifacts (opencode-mem.log.old, multi-day live files) are handled
    • per-section degradation: a failing database (e.g. a corrupted WAL) is surfaced as an error field instead of failing the whole endpoint
  • New Stats tab at /stats (sidebar entry, routing, translations for en/de/zh/ar/tr/nl) rendering overview cards, the 14-day activity table with expandable error buckets, and a shard diagnostics table with mismatch/missing-file warnings
  • Sim mode (OPENCODE_MEM_SIM=1 bun run web:dev) now serves a representative stats fixture so the tab is developable without a live store

No new writes anywhere; capture/injection behavior untouched.

Screenshots

Desktop viewport captures (1945 × 1650), using demo data.

Stats tab, dark theme

Light theme

Stats tab, light theme

Expanded error bucket

The 63-error day is expanded to show its message buckets.

Stats tab, expanded error buckets

Test plan

  • Exercised the change locally

  • Noted any follow-up or known limitations

  • New tests/stats-log-parsing.test.ts (parser fixtures, including real incident log signatures: Turso ready gate failed WAL short-reads, Failed to load skills for OpenCode registration, listMemories: error) and tests/stats-service.test.ts (temp fixture DBs: shard aggregation, duplicate-tag counting, zero-filled 14-day series, missing-profile degradation)

  • bun run check (format + lint + typecheck) passes; bun run web:build passes (svelte-check 0 errors / 0 warnings)

  • Full bun test: 777 pass / 4 skip; the 3 failures reproduce on a clean main checkout in this Linux environment before this change (Bun.build resolution in plugin-bundle-boundary, one macOS-shaped config default assertion, one profile-confidence scheduler test) — no new failures introduced

  • Visual check of the Stats tab against the sim fixture: degradation states, count-mismatch and missing-file warnings, and error-bucket expansion all render

Known limitations: the same-tag count is a deliberately weak duplication proxy (a real near-duplicate rate needs an embedding similarity pass); log-based counters only cover days whose rotated log files still exist (rotation retains 30 days).

Checklist

  • Branch is based on main
  • bun test passes (3 pre-existing failures on main in this environment, noted above)
  • bun run typecheck passes
  • bun run check passes (format + lint + typecheck)
  • Docs / README updated

Extend GET /api/stats with per-shard memory health (counts, newest/oldest
ages, same-tag duplication proxy, file/registration mismatch), an active
user-profile summary, and a 14-day activity series parsed from the
plugin's structured logs (captures, skips, profile/compaction injections,
errors bucketed by message). Add a Stats tab rendering it, with per-section
degradation so the view keeps reporting during database incidents.
Read-only: no new writes or capture/injection behavior changes.
The stats aggregation test creates two shards, inserts three vectors,
and runs the full handleStats walk in one it(). On the windows-latest
runner that exceeds bun's default 5s per-test timeout; the timeout runs
afterEach cleanup while the walk is still in flight, so per-shard reads
fail against the deleted temp dir and the orphaned assertions report
total 0. Give the test the same 30s budget plugin-bundle-boundary uses.
@EyJunge1 EyJunge1 assigned EyJunge1 and Phototonic and unassigned EyJunge1 Oct 18, 2026
@EyJunge1 EyJunge1 added the enhancement New feature or request label Oct 18, 2026
@EyJunge1
EyJunge1 self-requested a review October 18, 2026 11:11
@EyJunge1

Copy link
Copy Markdown
Collaborator

cool feature

Keep ownership probes cheap with ?probe=1, commit shard totals only after a
full walk succeeds, hard-fail shard listing for explorer totals, and align
the sim fixture total with memories.json.
Screenshots in .github/pics are unnecessary; keep the Stats section as text.
@EyJunge1
EyJunge1 merged commit 6bbbcc9 into tickernelz:main Oct 18, 2026
7 checks passed
@EyJunge1 EyJunge1 mentioned this pull request Oct 18, 2026
5 of 8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants