feat(stats): add GET /stats endpoint with per-agent/repo/day aggregates #127
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!127
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev/123"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #123.
Dev pushed this branch at 12:34; container died at exit 137 before it could open the PR (same silent-disappearance pattern as before). Opening on its behalf so the review loop can run normally.
Summary
src/task-store.ts) persists finalized tasks fromonFinish+handleCancel, growing beyond the 50-task in-memory cap.GET /statsendpoint aggregating cost, turns, success-rate per agent / repo / day over a configurable window.Files
src/task-store.ts(new, 347 loc)src/stats.test.ts(new, 522 loc)src/main.ts(+55 loc)Test plan
bun test— dev ran its own local test pass before pushcurl /statsreturns aggregatesNote: PR was opened by me (claude-desktop) on dev's behalf after the 137 crash, so I can't self-approve — posting my review as a comment instead.
Reviewed against #123 AC line-by-line:
Endpoint + response shape — matches the spec exactly.
window/agent/repoparams wired; unknownwindowfalls back to30d;success_rateexcludes cancelled from the denominator (denominator-zero returns 0, not NaN) and documented in the endpoint docstring.SQLite schema — indexes on
finished_at,agent,repokeep the 30d aggregation bounded.INSERT OR REPLACEmakespersistTaskidempotent for re-entry. Parametrised queries throughout.agent_typecolumn added beyond the AC's listed columns — needed forby_agent.type, correct call.Wiring —
persistTaskfires from bothonFinishandhandleCancel, so success/failure/cancelled all land in the table. In-memory 50-task cap preserved for SSE.Tests — 19 tests pass, covering every edge case the AC enumerated (empty window, all-cancelled → 0, single-task, non-existent-agent filter, invalid window param, 7d/30d/all windows, by_day ordering).
Docs — README
/statssection with query-param table + response example; CLAUDE.md module table splitstorage.ts/task-store.tswith accurate one-liners.Pre-existing repo issues, not blockers for this PR
bunx tsc --noEmitfails onsrc/dashboard-browser.test.ts(cannot findhappy-domtypes). Reproduces onmainbefore this branch lands — shipped with PR #121. Worth a follow-up ticket but not a blocker.Nits (non-blocking)
task-store.tsreadsCLAUDE_HOOKS_STATE_DIRdirectly rather than reusingdb.ts's resolver. Equivalent behaviour, one-line duplication.LGTM from my side — would approve if I could. Leaving the PR open for the
revieweragent for a formal verdict.709364bef738bac0926a