[FEATURE] Allow stream-json session binding after process start
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
In --input-format stream-json mode, session identity can only be selected when the process starts, using --resume. If a CLI starts without --resume, a session_id on the first user message does not load that session's transcript; the CLI creates a new session instead.
This prevents a pre-initialized CLI from being reused for different sessions. For example, a generic VM snapshot can contain an initialized CLI waiting on stdin, but it cannot contain a specific session identity. Resuming a session therefore requires discarding the restored process and spawning another CLI with --resume.
sequenceDiagram
participant Host
participant VM
participant CLI as Restored CLI
participant CLI2 as New CLI
Host->>VM: restore generic snapshot
Host->>VM: hydrate transcript and workspace
Note over CLI: initialized, but cannot bind session
Host->>CLI2: spawn with --resume
CLI2->>CLI2: initialize again
Host->>CLI2: send first message
Proposed Solution
Allow an unbound stream-json process to bind to an existing session from its input stream. Either:
- Honor
session_idon the first incoming user message. - Add a
resumecontrol_requestaccepting a session id or transcript path.
Expected behavior:
- A first user message with
session_idloads that transcript and continues the session. - A first user message without
session_idstarts a fresh session. - A leading
control_requestis handled normally. - Explicit
--resumeand--continueflags remain authoritative. - A missing transcript fails using the existing
--resumebehavior. - Binding only the initial session is sufficient; mid-stream switching is not required.
sequenceDiagram
participant Host
participant CLI as Restored, initialized CLI
Host->>CLI: hydrate transcript and workspace
Host->>CLI: first message with session_id
CLI->>CLI: load transcript and bind session
CLI-->>Host: continue prior conversation
Alternative Solutions
The supported workaround is to spawn another CLI with --resume, which loses the benefit of restoring an initialized process.
We currently patch the vendored Bun executable instead:
- Extract the embedded
cli.js. - Inject logic immediately before
loadInitialMessages. - Read the first structured input message.
- Use its
session_idas the resume target when applicable. - Requeue the consumed message on every path.
Requeueing is important: otherwise a message without session_id, or a leading control_request, is silently consumed. The patch works, but it is tied to minified identifiers and must preserve the embedded bundle's exact byte length, making it brittle across releases.
Comparable protocols support late binding directly:
- Codex app-server:
thread/resume - pi RPC mode:
switch_session
Priority
Medium - Would be very helpful
Feature Category
CLI commands and flags
Use Case Example
- Build one generic VM snapshot containing a CLI initialized and waiting on stream-json stdin.
- Restore that snapshot when a session resumes.
- Hydrate the session transcript and workspace into the VM.
- Send the first user message with the existing
session_id. - Continue the prior conversation without spawning another CLI.
Additional Context
Measurements on Claude Code 2.1.220:
| Operation | Initialization time |
|---|---:|
| Spawn, then send first message | ~0.74s |
| Send first message to initialized CLI | ~0.07s |
An initialized CLI used about 344 MiB RSS in the same test. The primary benefit is avoiding a new process and initialization cycle for every resumed session.