Session resume and transcripts
This page maps the local session and transcript surfaces visible in the extracted cli.js.
Source anchors
| Semantic alias | Source | Approximate location | String or symbol | Meaning |
|---|---|---|---|---|
| LocalJsonlTranscriptSource | cli.js | line ~11, byte 0xd67c | transcriptSource:"local-jsonl" | Default local transcript source classification. |
| ProjectStateRoot | cli.js | line ~143, byte 0xf20f0 | projects | Config/project root helper under the Claude config directory. |
| SessionJsonlLookup | cli.js | line ~143, byte 0xf231e | ${H}.jsonl | JSONL transcript filename lookup helper. |
| CurrentSessionJsonlPath | cli.js | line ~486, byte 0x30ac74 | ${v$()}.jsonl | Current session JSONL transcript path. |
| SessionDiscovery | cli.js | line ~2773, byte 0x79c004 | async function jHH(H,$) | Latest/resume session discovery helper. |
| SessionRestore | cli.js | line ~9514, byte 0xc8b160 | async function OG8(H,$,q) | Session restore path. |
| ContinueFlag | cli.js | line ~19525, byte 0xdc114e | -c, --continue | Continue most recent conversation. |
| ResumeFlag | cli.js | line ~19525, byte 0xdc11af | -r, --resume [value] | Resume by ID or picker/search term. |
| ForkSessionFlag | cli.js | line ~19525, byte 0xdc1235 | --fork-session | Resume into a new session ID. |
| NoSessionPersistenceFlag | cli.js | line ~19525, byte 0xdc16e9 | --no-session-persistence | Disables transcript writes and resume. |
| ResumeSessionAtGuard | cli.js | line ~19324, byte 0xda33e5 | --resume-session-at requires --resume | Headless resume validation. |
| RewindFilesResumeGuard | cli.js | line ~19325, byte 0xda3455 | --rewind-files requires --resume | Rewind validation. |
Local transcript flow
flowchart TD Start[Start mode] --> Choice{resume input?} Choice -->|none| Fresh[Fresh session id] Choice -->|--continue| Latest[Latest-session discovery] Choice -->|--resume| Resolve[Discovery / picker / exact id] Latest --> Restore[Session restore] Resolve --> Restore Fresh --> Loop[Runtime loop] Restore --> Loop Loop --> Jsonl[session-id.jsonl] Jsonl --> Future[future --continue / --resume]Session flags
| Surface | Runtime role |
|---|---|
--continue / -c | Loads the most recent conversation in the current directory. |
--resume [value] / -r | Resumes by explicit ID or opens a search/picker path when ambiguous. |
--from-pr | Classified as a resume-like start in Uzq. |
--session-id <uuid> | Uses a specific session ID, with validation and incompatibility checks in SDK/bridge paths. |
--fork-session | Resumes into a new session ID rather than mutating the original. |
--no-session-persistence | Disables transcript writes and therefore future resume. |
--resume-session-at <message id> | Truncates resumed context to an assistant message in print mode. |
--rewind-files <user-message-id> | Restores files to the state at a user message and exits. |
Persistence interpretation
The local-jsonl and ${sessionId}.jsonl anchors show that local sessions are durable JSONL transcript files. SessionDiscovery and SessionRestore then form the semantic pair for session discovery and restore. The root action routes --continue, --resume, PR resume, remote/teleport branches, and picker fallback into these restoration surfaces before entering InteractiveSessionLoop or HeadlessRunner.
Edge cases
--resume-session-atand--rewind-filesrequire--resume.--rewind-filesis a standalone operation and cannot be used with a prompt.--no-session-persistenceexplicitly prevents saving and resuming.- Resuming may warn when permission mode differs from the saved session.
Restore internals
This section reconstructs how resume/continue state is loaded and transformed before re-entering the runtime loop. The core pair is SessionDiscovery (find/load a resumable session) and SessionRestore (apply restored state into the current runtime envelope).
Additional anchors
| Semantic alias | Source | Approximate location | String or symbol | Meaning |
|---|---|---|---|---|
| LiveSessionFilter | cli.js | line ~2773, byte 0x79c060 | listAllLiveSessions | Used to filter out live non-interactive sessions during latest-session lookup. |
| TranscriptPathLoadBranch | cli.js | line ~2773, byte 0x79c18c | kI7($) | Transcript-path based load branch. |
| SessionIdLoadBranch | cli.js | line ~2773, byte 0x79c1ca | JJ$(H) | Session-ID/string based load branch. |
| ResumeHookMessage | cli.js | line ~2773, byte 0x79c3a0 | Rm("resume" | Resume hook/system messages are appended to restored messages. |
| DeferredToolResumeState | cli.js | line ~2773, byte 0x79c430 | turnInterruptionState, deferredToolUse | Resume returns interruption and deferred-tool metadata. |
| ForkSessionRestore | cli.js | line ~9514, byte 0xc8b1b0 | forkSession | Forking changes which session/bridge/worktree fields are reused. |
| PermissionModeTransition | cli.js | line ~9514, byte 0xc8b350 | transitionPermissionMode | Restored permission mode is transitioned into current permission context. |
| InterruptedTurnResumeGate | cli.js | line ~9514, byte 0xc8b5a0 | CLAUDE_CODE_RESUME_INTERRUPTED_TURN | Optional interrupted-turn auto-resume gate. |
| TranscriptGoalRestore | cli.js | line ~9514, byte 0xc8b740 | restoreGoalFromTranscript | Restores goal-like state from transcript messages. |
Session discovery: finding and normalizing a session
SessionDiscovery supports several inputs:
| Input shape | Branch | Meaning |
|---|---|---|
H === undefined | latest-session lookup | Loads candidate sessions and filters out live non-interactive session IDs from listAllLiveSessions. |
| transcript path supplied | TranscriptPathLoadBranch | Loads messages/session ID from an explicit transcript path. |
| string value | SessionIdLoadBranch | Resolves a session by ID/string. |
object H | direct object branch | Uses an already-loaded session-like object. |
After loading, SessionDiscovery normalizes and enriches the result by resolving the session ID, mapping/validating the transcript path, loading messages and marking them as resume input, looking for deferred tool state, calling a resume hook, and returning a large state object.
Session discovery return state families
| State family | Returned fields |
|---|---|
| Conversation | messages, turnInterruptionState, deferredToolUse, sessionId, fullPath |
| File/history | fileHistorySnapshots, attributionSnapshots, contentReplacements |
| Context collapse | contextCollapseCommits, contextCollapseSnapshot |
| Agent identity | agentName, agentColor, agentSetting, customTitle, aiTitle, tag, mode |
| Permission/isolation | permissionMode, isolationLatch |
| Worktree/PR | worktreeSession, prNumber, prUrl, prRepository |
| Bridge/remote | bridgeSessionId, bridgeLastSeq |
Resume is not simply replaying chat messages — it rehydrates a broad runtime envelope.
Session restore: applying restored state
flowchart TD Loaded[SessionDiscovery loaded state] --> Fork{forkSession?} Fork -->|no| Reuse[reuse session id / transcript dir / bridge/worktree] Fork -->|yes| Strip[strip worktree and bridge session fields] Reuse --> ResolveAgent[resolve agent definition] Strip --> ResolveAgent ResolveAgent --> Permission[transition restored permission mode] Permission --> Model[restore main-loop model] Model --> Attribution[restore attribution and standalone agent context] Attribution --> Interrupted[optional interrupted-turn auto-resume] Interrupted --> Goal[restoreGoalFromTranscript] Goal --> InitialState[return restored initialState]Key mechanics:
- Session reuse versus fork. Non-fork restores set the active session ID and transcript directory; forked restores intentionally clear
worktreeSession,bridgeSessionId, andbridgeLastSeqbefore applying state. - Content replacement handling. Forked sessions with
contentReplacementsapply those replacements separately. - Agent resolution.
xyH(...)resolves restored agent settings against current main-thread and available agent definitions. - Permission transition. If a restored permission mode exists,
transitionPermissionModemerges it into the currenttoolPermissionContext; failures are logged with[sessionRestore]. - Model restore.
Sa5(...)can restore the main-loop model;IG(...)applies it when present. - Bridge restore. Non-fork sessions with bridge metadata can re-enable the REPL bridge unless the current initial state is outbound-only.
- Interrupted turn. With
CLAUDE_CODE_RESUME_INTERRUPTED_TURNset and aninterrupted_promptturn-interruption kind, the runtime re-injects the interrupted user message as the initial message. - Goal restore.
restoreGoalFromTranscriptrebuilds goal-like state from transcript messages before returning.
Failure behavior
SessionDiscovery records session_resume feature markers. If no session is found it marks not_found and returns null. If loading fails it marks load_failed, reports the error, and rethrows.
Implementation takeaways
- Resume is a state rehydration pipeline, not just JSONL replay.
- Forking is explicit and strips bridge/worktree continuity to avoid mutating the original session lineage.
- Permission mode and model state are restored through transition helpers, not blindly copied.
- Remote/bridge continuity is preserved only when compatible with the current runtime initial state.
Related docs
Created and maintained by Yingting Huang.