Context
Session transcripts live under /root/.claude/projects/<worktree-slug>/*.jsonl on each host. kill keeps them (that's why usage survives kills), but delete removes the registry record so the transcripts — while still on disk under a now-orphaned slug — become unreachable from the hub, and their usage disappears from all dashboard totals and the history chart.
Problem
- Deleting a session silently deletes its visible history: the all-time cost tiles and the history page lose those days retroactively, so fleet totals aren't stable over time.
- There's no way to save a record of what an agent did — the conversation, decisions, and diffs — before removing the session. For anything worth auditing later ("why did the agent change this?"), the transcript is the only artifact and it's effectively lost on delete.
Proposal
- Export endpoint: a hub route (
GET /api/agents/<host>/sessions/<id>/transcript) that fetches the session's transcript JSONLs from the agent. The heartbeat channel is wrong for bulk data; the reverse tunnel already carries arbitrary byte streams per channel, so a small file-serving sidecar (or an extension of the existing loopback ttyd pattern — a tiny local HTTP endpoint the tunnel can bridge to) fits the existing architecture. Offer raw JSONL plus a rendered-markdown option.
- Archive on delete: before
delete() removes the record, the agent snapshots {registry record, final usage_report(), git log of the branch} into an ~/.agenthub/archive/<id>.json. Cheap, bounded, and makes delete reversible in the "what was that?" sense even if the full transcript isn't kept.
- Durable usage: fold the final
usage_report() into the hub's persisted state on delete so historical cost data stops disappearing (see also the durable-usage-history issue — this is the agent-side half).
Touchpoints
agent/hub-agent.py — delete() archive step, transcript serving
agent-hub/server.js — export route over the tunnel
agent-hub/public/index.html — export action on the card; delete confirm copy mentions what is/isn't kept
Context
Session transcripts live under
/root/.claude/projects/<worktree-slug>/*.jsonlon each host.killkeeps them (that's why usage survives kills), butdeleteremoves the registry record so the transcripts — while still on disk under a now-orphaned slug — become unreachable from the hub, and their usage disappears from all dashboard totals and the history chart.Problem
Proposal
GET /api/agents/<host>/sessions/<id>/transcript) that fetches the session's transcript JSONLs from the agent. The heartbeat channel is wrong for bulk data; the reverse tunnel already carries arbitrary byte streams per channel, so a small file-serving sidecar (or an extension of the existing loopback ttyd pattern — a tiny local HTTP endpoint the tunnel can bridge to) fits the existing architecture. Offer raw JSONL plus a rendered-markdown option.delete()removes the record, the agent snapshots{registry record, final usage_report(), git log of the branch}into an~/.agenthub/archive/<id>.json. Cheap, bounded, and makes delete reversible in the "what was that?" sense even if the full transcript isn't kept.usage_report()into the hub's persisted state on delete so historical cost data stops disappearing (see also the durable-usage-history issue — this is the agent-side half).Touchpoints
agent/hub-agent.py—delete()archive step, transcript servingagent-hub/server.js— export route over the tunnelagent-hub/public/index.html— export action on the card; delete confirm copy mentions what is/isn't kept