Sweeper: prune old session JSONL files in $CLAUDE_CONFIG_DIR/projects/ #131
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
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks#131
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
User story
As the operator, I want the sweeper to delete old session-history JSONL files under
~/.config/claude-hooks/agent-env/<agent>/projects/<cwd>/<uuid>.jsonlso that disk usage for per-agent session state stays bounded over time.Context
PR #125 landed the rw bind that makes Claude Code actually persist session history on disk. Every dispatch now writes a JSONL file. The files are never deleted — per-agent disk usage will grow linearly with dispatch count.
The sweeper (
src/sweeper.ts) already handles cache-clone pruning, stale worktrees, and expired sessions. This story extends it with a pass that deletes session JSONLs whosemtimeis older than N days.Acceptance criteria
Sweeper pass
src/sweeper.ts(or a newsrc/sweeper-sessions.tsif cleaner) that walks every agent'sprojects/bind-source dir and deletes*.jsonlfiles older than the TTL./statsdefault window, so everything visible on the stats tab is still resumable.config/agents.jsontop-levelsession_history_ttl_days: N. Absent → default.runSweepentry point (same as storage pass), so both the periodic 6 h timer and thePOST /sweepdashboard button trigger it.runSweepresult shape so thePOST /sweepresponse surfaces it (e.g.{ sessions_pruned: N }).Safety
sessions.jsonstore (~/.local/state/claude-hooks/sessions.json). Read it once up front; skip any file whose basename UUID matches a stored id, regardless of age.listResolvedAgents()— skips agents withcontainer.enabled: false.Tests
src/sweeper.test.tsextension: seed a tempprojects/<cwd>/<uuid>.jsonltree with a mix of fresh + expired + sessions-json-referenced files; assert only the expired, non-referenced ones are deleted.session_history_ttl_daysoverride resolves from config.Docs
CLAUDE.mdSweeper row updated to mention session-history pruning.Out of scope
last_accessedtimestamp instead ofmtime—mtimeis good enough (Claude CLIappends to the file on every turn, bumpingmtime).References
src/sweeper.ts— existing sweep pass.src/sessions.ts— session-store to read for the "don't-delete live ids" guard.~/.config/claude-hooks/agent-env/<agent>/projects/<encoded-cwd>/<uuid>.jsonl.Dependencies
main.