The upstream billion-context ships a session export command (bili export) built on acp-kernel's prune() renderer. The Pi adapter (billion-context-pi) does not port this capability — sessions compressed inside Pi cannot be exported as a readable handoff document. This issue tracks restoring feature parity.
What upstream has
src/export.ts (~175 lines) plus a CLI command:
bili export # list persisted sessions (id/title/label/tokens/blocks)
bili export <session-id|label> # render handoff markdown
bili export <id> --output handoff.md # write to file
bili export <id> --full # full original messages instead of folded view
Key behaviors worth preserving:
- Folded view by default — uses acp-kernel's
prune(messages, state) to render the conversation exactly as the model saw it: compressed ranges are replaced by their block summaries ([Compressed conversation section] placeholders), never the raw messages.
--full mode — renders every original message: from the v3 conversation snapshot when available, otherwise falls back to the blockContents cache (v2 sessions).
- v2 fallback — sessions without a persisted snapshot still export block summaries (with originals only under
--full), plus an explicit note when nothing is recoverable.
- Handoff semantics — the rendered document ends with guidance to paste the block summaries into a new session to continue without the proxy.
Why this matters for the Pi adapter
- Sessions managed by the adapter are currently opaque after the fact — there is no way to produce a human-readable, fold-aware snapshot of a compressed conversation.
- The handoff document is the only mechanism to migrate context between different hosts or to a fresh session without the proxy.
prune() already lives in acp-kernel (which Pi pins and bundles); only the consumer code (export.ts + CLI wiring) is missing.
Proposed scope
- Port
export.ts (listSessions / exportSession / renderHandoff) to the Pi source tree.
- Wire the
export command into the Pi CLI (or expose it as a tool/command if Pi has no CLI surface — adapter-appropriate integration).
- Keep both output modes (
--output to file and stdout return) and the --full flag.
- Preserve the v2 fallback path so older persisted sessions remain exportable.
Acceptance criteria
References
- Upstream:
src/export.ts, src/cli.ts (export command parsing)
- Kernel dependency:
acp-kernel src/prune.ts (prune, stripOrphaned*, summaryMessageId)
The upstream billion-context ships a session
exportcommand (bili export) built on acp-kernel'sprune()renderer. The Pi adapter (billion-context-pi) does not port this capability — sessions compressed inside Pi cannot be exported as a readable handoff document. This issue tracks restoring feature parity.What upstream has
src/export.ts(~175 lines) plus a CLI command:Key behaviors worth preserving:
prune(messages, state)to render the conversation exactly as the model saw it: compressed ranges are replaced by their block summaries ([Compressed conversation section]placeholders), never the raw messages.--fullmode — renders every original message: from the v3 conversation snapshot when available, otherwise falls back to theblockContentscache (v2 sessions).--full), plus an explicit note when nothing is recoverable.Why this matters for the Pi adapter
prune()already lives inacp-kernel(which Pi pins and bundles); only the consumer code (export.ts+ CLI wiring) is missing.Proposed scope
export.ts(listSessions / exportSession / renderHandoff) to the Pi source tree.exportcommand into the Pi CLI (or expose it as a tool/command if Pi has no CLI surface — adapter-appropriate integration).--outputto file and stdout return) and the--fullflag.Acceptance criteria
exportwith no selector lists persisted sessions with title/label/tokens/blocks.export <id>renders the folded view (block summaries in place of compressed ranges, in conversation order).export <id> --fullrenders original messages from the snapshot/blockContents cache.--outputwrites the markdown file; without it the document is returned to stdout.References
src/export.ts,src/cli.ts(exportcommand parsing)acp-kernelsrc/prune.ts(prune,stripOrphaned*,summaryMessageId)