Skip to content

feat(sessions): add export and import subcommands to move sessions between machines#321

Open
mvanhorn wants to merge 1 commit into
openclaw:mainfrom
mvanhorn:feat/acpx-sessions-export-import
Open

feat(sessions): add export and import subcommands to move sessions between machines#321
mvanhorn wants to merge 1 commit into
openclaw:mainfrom
mvanhorn:feat/acpx-sessions-export-import

Conversation

@mvanhorn
Copy link
Copy Markdown

Summary

  • Adds acpx sessions export <name> --output <path> and acpx sessions import <archive>. Export writes a self-contained portable JSON archive with format_version, agent, cwd_relative (normalized to home), full session state, and the per-session NDJSON history. Import generates a fresh record_id, rewrites cwd against the destination machine's home (or --cwd override), and preserves agent + state + history.
  • Closes the roadmap item: "Session export/import -- Move sessions between machines" from docs/2026-02-19-acp-coverage-roadmap.md.
  • Export refuses to run when the session is locked by a live queue owner (exit 2, code: "session-locked"). Run acpx sessions close first. Imports always get a fresh record_id, so re-importing to the source machine never collides with the original entry.
  • Plain JSON. No tarball, no streaming archive library, no new runtime deps. The session state schema is preserved verbatim from docs/2026-02-27-acpx-session-model.md.

Why this matters

acpx persists sessions per cwd in ~/.acpx/sessions/<record_id>.json. Once a session exists it survives across invocations, but it does not survive across machines. Moving an in-progress debug session from laptop to workstation, or sharing a session for a postmortem, requires manually copying the session JSON plus its sidecar .stream.lock and history files — and the absolute paths embedded inside (cwd, log file references) need rewriting for the destination.

Three concrete use cases this unlocks:

  • Laptop → workstation handoff. Mid-flight agent debugging, hand off without re-prompting.
  • Postmortem session sharing. Send debug.json to a teammate. They acpx sessions import debug.json and have your exact session.
  • Debugging recordings. Capture an unusual session, archive it, replay/inspect later.
# Source machine:
acpx sessions export debug-session --output debug.json

# Destination machine:
acpx sessions import debug.json --name debug-on-workstation

Demo

Simulated demo:

acpx sessions export/import demo

The demo shows the laptop-to-workstation handoff: export on the laptop produces debug.json with record_id, agent, cwd_relative, history-event count, and format_version. Import on the workstation generates a new record_id, rewrites cwd against the destination's home directory, preserves agent + history, and records the imported_from provenance.

Testing

  • corepack pnpm typecheck
  • corepack pnpm lint (oxlint + oxfmt + flow-schema-terms + persisted-key-casing all clean)
  • corepack pnpm test — 671 tests pass; new src/session/__tests__/export-import.test.ts covers:
    • round-trip: export → delete → import preserves agent, state, history (record_id changes, by design)
    • history NDJSON events round-trip
    • --cwd <path> on import rewrites the destination cwd
    • export on a locked session fails with code: "session-locked", exit 2
    • import on wrong format_version fails with a clear error naming the supported version
    • import generates a new record_id even when the source record_id already exists locally

…tween machines

acpx sessions export <name> --output <path> writes a self-contained
portable archive: format_version, agent, cwd (normalized relative to
home), session state, and history. acpx sessions import <archive>
reverses it: generates a fresh record_id, rewrites cwd against the
destination machine's home (or --cwd override), preserves agent and
state and history.

Export refuses to run when the session is locked by a live queue owner
(error: session-locked, exit 2) -- close the session first with
acpx sessions close. Import generates a new record_id even when the
source record_id already exists locally so re-importing to the source
machine doesn't collide.

Closes the 'Session export/import' item from the ACP coverage roadmap
(docs/2026-02-19-acp-coverage-roadmap.md).

Use cases: laptop -> workstation handoff for in-progress agent work,
postmortem session sharing with teammates, debugging recordings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant