Support a conversation format
Capture and restore the native sessions of a CLI agent you add to Outpost.
Choose the storage format
Section titled “Choose the storage format”A custom CLI adapter can expose its native session storage through storage. Outpost then uses it to capture conversations after turns, restore them in another sandbox and archive them through a transport. Choose the helper that matches how your CLI saves sessions.
| The CLI keeps | Building block | Built-in stores using it | Host copy |
|---|---|---|---|
| One JSONL transcript per conversation | createTranscriptConversations(layout) | Claude Code, Codex | The path your layout returns |
| One directory per session | createSessionBundleConversations(profile) | Copilot, Kimi | .outpost/conversations/<format>/<id>.json |
Describe a transcript layout
Section titled “Describe a transcript layout”The layout tells Outpost where the transcript lives on the host and in the sandbox. This adapter for a fictional mycli resumes with --resume <id> and reports its session ID in a session event.
Host functions receive your home directory, or conversationHome when you set it. remoteSearchRoot receives the agent home in the sandbox, and remotePath the SandboxLease.
API reference: TranscriptConversationLayout.
Follow the workspace path
Section titled “Follow the workspace path”Transcripts record the directory the CLI ran in. Capture rewrites every cwd field equal to the first recorded cwd (or payload.cwd) to the host repository path. Restoration rewrites them to the workspace of the new sandbox, so the CLI resumes in the right directory.
Pack a session directory
Section titled “Pack a session directory”createSessionBundleConversations() packs a session directory into one JSON bundle. A Node.js script run in the sandbox does the packing; restoration unpacks the bundle in the new sandbox.
API reference: SessionBundleProfile.
Restoration writes every file to a staging directory first. An existing session with the same ID moves to .outpost-recovery/ in the CLI home before the new one takes its place.
Write the in-sandbox functions
Section titled “Write the in-sandbox functions”validate, bucket and relocate run in the sandbox from their source text, not in your process.
- Expressions only: Write an arrow function or a
functionexpression. A method is rejected when the store is created. - Self-contained: Use the arguments,
helpers.join,helpers.sha256and JavaScript built-ins. An import or a variable from your module fails when the function runs. - Return values:
validatereturns an error message orundefined.relocatereturns the new text; throwing aborts the restoration and keeps the existing session. - Buckets:
bucketis required withbuckets: true.
Keep the format stable
Section titled “Keep the format stable”format names the conversation records, the transport keys and the host directories. A store refuses to restore a record captured under another format, so renaming it strands earlier conversations.
Built-in presets accept a replacement store through their conversations option. Its format must match the agent ("claude", "codex"…), otherwise the harness fails when created. A custom ConversationStore without format is accepted as is.
Archive through a transport
Section titled “Archive through a transport”Wrap the native store to archive every capture, as for a built-in agent: createTransportConversations(storage, { transporter, namespace }). Conversations shows the full setup with a shared transport.
Limits
Section titled “Limits”- Bundle size: A session bundle holds at most 64 MiB and 4,096 files.
- Refused entries: Symlinks, and files that change during capture, fail the capture with code
session. - Node.js in the sandbox: Session bundles run a Node.js script, so the sandbox image must provide
node. - Regular expressions:
includeandexcludecannot use thegoryflag. - Transcript files: The host search and child transcripts only consider
.jsonlfiles. A child transcript that fails to capture only logs a warning. - Transport:
createTransportConversations()needs a store with aformat. - Conversation IDs: Only letters, digits,
_and-are accepted.
API: createTranscriptConversations · TranscriptConversationLayout · createSessionBundleConversations · SessionBundleProfile · SessionBundleHelpers · NativeConversationStore · createTransportConversations · AgentAdapter.