Implement foreign session resume (Claude, Codex, Cursor) #198
- AtlantisPleb opened this issue 2d ago
-
A Author 2d ago Discovery half landed on main as OpenAgentsInc/openagents b0b5658cb1 (WAL receipt seq 77), and it answers this issue's open architectural question with working code: the Rust path wins, as a sandboxed WASM plugin rather than a vendored crate or a TypeScript rewrite.
plugins/foreign-sessions is a Rust guest on the owned PDK that mounts ~/.claude and ~/.codex read-only and returns session metadata only. The host grew one narrow capability for it — openagents.list_dir, mount-indexed so a two-mount scanner never wonders which root answered, with the same containment as reads (relative paths only, lexical .. check, symlink refusal by lstat, realpath containment, 500-entry bound with a truncation flag) — plus ~ and absolute mount roots that must exist and be directories at load. Guest bounds sit atop host bounds: 50 results, 200 reads, 1500 listings, 5000 candidates. Fail-soft throughout: missing stores reported, malformed and symlinked entries skipped and counted, and files over the 1 MiB read bound reported from listing metadata with metadata_truncated rather than raising the bound (435 of 1195 local Claude files exceed it — ordinary, not exceptional).
Demo on this machine: a live model turn in coder --plain called foreign_sessions and tabulated real recent sessions, including the session that built the feature. Direct invoke scanned 2,684 files across 203 directories, 0 skipped, well inside the 10-second budget. Tests: 26 cargo (15 fake-host scanner, 11 PDK) and 40 vitest including escape attempts for .., absolute paths, symlinked directories, and bad mount indices; all four wasm artifacts rebuilt byte-reproducibly with digests repinned.
Deliberately deferred and recorded in the plugin README: Codex SQLite state files and Cursor (the wasm-sqlite spike is the known risk), and the resume/import half — continuing a foreign session inside OpenAgents. Per the grok-build lesson this issue cites, that half must be a typed adapter with a source digest and a loss report, never a skill prompt masquerading as lossless resume. This issue stays open for it.
-
A Author 2d ago Both halves are now shipped.
The scanner landed earlier as plugins/foreign-sessions, a packet-v0 WASM guest that reads ~/.claude and ~/.codex through read-only confined mounts and reports session metadata only — source, session id, working directory, mtime, size, record count — bounded on age, file sizes, read counts, and candidates, and fail-soft on anything missing or malformed.
The picker landed on monorepo main in b4cefc3a43: packages/openagents-cli/src/coder-foreign-resume.ts builds the bounded, filtered scan request, keeps the sessions whose working directory is the current project, renders them newest first, and prints source, session id, directory, age, record count, and the exact resume command. Those commands are the real ones, checked against claude --help and codex --help on this machine:
claude --resume <id>andcodex resume <id>— a test asserting a nonexistentcodex continuesubcommand was corrected in review.The posture holds: metadata only, never writes to the foreign tool's state, no foreign credential read, bounds unchanged from the plugin, and a scan that hits a bound says so rather than letting a short list read as an empty one. 796 CLI tests green.
Cursor is not covered — neither the plugin nor the picker reads Cursor state, so that part of the issue's title remains if you want it.
- closed this as completed 2d ago
Summary
Build an OpenAgents equivalent of the
/resume-claude,/resume-codex, and/resume-cursorslash commands in thegrokCLI. These commands let a user pick up a recent session from another coding agent and continue it inside OpenAgents.Source reference
grok-buildimplements this in:crates/codegen/xai-grok-foreign-sessions/src/lib.rs— bounded metadata-only scannercrates/codegen/xai-grok-foreign-sessions/src/claude.rs— reads~/.claude*.jsonlsession filescrates/codegen/xai-grok-foreign-sessions/src/codex/mod.rs— reads~/.codex/state_{N}.sqliteand~/.codex/sessions/rolloutscrates/codegen/xai-grok-pager/src/app/foreign_sessions.rs— TUI mapping toresume-claude,resume-codex,resume-cursorskillsThe scanners are read-only, sandboxed to an
ApprovedRoot, and bounded (max age, file sizes, candidate counts). They never write to the foreign tool's state.What to build
Open architectural question
The implementing agent should evaluate two paths and decide which is best:
grok-buildso that OpenAgents can use them directlyThe preferred direction is to find a way to use Rust crates, because re-implementing the SQLite parsing, zstd rollout decoding, and path sandboxing in TypeScript is error-prone and duplicates work.
Security constraints
Because this code reads the user's foreign agent state, it must be treated as untrusted-input handling:
Acceptance criteria
/resume-claude,/resume-codex, and/resume-cursorequivalents, or a unified/resumepicker, are functional