|
| 1 | +# Claude Code: Session Continuation between CLI and Agents SDK |
| 2 | + |
| 3 | +Continue a conversation started in the Claude Code CLI using the TypeScript or Python Agents SDK, and vice versa. Sessions are stored as JSONL files on disk and are fully interchangeable between surfaces. |
| 4 | + |
| 5 | +## How sessions work |
| 6 | + |
| 7 | +Every Claude Code conversation is persisted to: |
| 8 | + |
| 9 | +``` |
| 10 | +~/.claude/projects/<encoded-cwd>/<session-id>.jsonl |
| 11 | +``` |
| 12 | + |
| 13 | +- `<encoded-cwd>` is the working directory with non-alphanumeric characters replaced by `-` (e.g. `/home/user/project` → `-home-user-project`) |
| 14 | +- `<session-id>` is a UUID assigned when the session starts |
| 15 | +- The file is plain JSONL — one JSON object per line containing user messages, assistant responses, tool calls, and metadata |
| 16 | + |
| 17 | +Both the CLI (`claude`) and the Agents SDK (`@anthropic-ai/claude-agent-sdk`) read and write to the same files, making sessions fully portable between them. |
| 18 | + |
| 19 | +## Getting a session ID |
| 20 | + |
| 21 | +### From the CLI |
| 22 | + |
| 23 | +Use `--output-format json` with print mode to get structured output: |
| 24 | + |
| 25 | +```bash |
| 26 | +echo "hello" | claude -p --output-format json |
| 27 | +``` |
| 28 | + |
| 29 | +The response includes `session_id`: |
| 30 | + |
| 31 | +```json |
| 32 | +{ |
| 33 | + "type": "result", |
| 34 | + "session_id": "93bc0449-4ff1-474a-bc36-876654f935c2", |
| 35 | + "result": "..." |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +In interactive mode, the session ID is shown in the UI and can also be retrieved via `--resume` (which lists recent sessions when called without an argument). |
| 40 | + |
| 41 | +### From the SDK |
| 42 | + |
| 43 | +The session ID is available on every `result` message: |
| 44 | + |
| 45 | +```typescript |
| 46 | +import { query } from "@anthropic-ai/claude-agent-sdk"; |
| 47 | + |
| 48 | +for await (const msg of query({ prompt: "hello", options: { cwd: "/tmp" } })) { |
| 49 | + if (msg.type === "result") { |
| 50 | + console.log(msg.session_id); // "93bc0449-..." |
| 51 | + } |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +## Reading session data (SDK) |
| 56 | + |
| 57 | +### List sessions |
| 58 | + |
| 59 | +```typescript |
| 60 | +import { listSessions } from "@anthropic-ai/claude-agent-sdk"; |
| 61 | + |
| 62 | +const sessions = await listSessions({ dir: "/path/to/project", limit: 10 }); |
| 63 | +// [{ sessionId, summary, lastModified, fileSize, firstPrompt, gitBranch, cwd, createdAt }] |
| 64 | +``` |
| 65 | + |
| 66 | +### Get session info |
| 67 | + |
| 68 | +```typescript |
| 69 | +import { getSessionInfo } from "@anthropic-ai/claude-agent-sdk"; |
| 70 | + |
| 71 | +const info = await getSessionInfo("93bc0449-...", { dir: "/tmp" }); |
| 72 | +// { sessionId, summary, lastModified, firstPrompt, gitBranch, cwd, createdAt, ... } |
| 73 | +``` |
| 74 | + |
| 75 | +### Get session messages |
| 76 | + |
| 77 | +```typescript |
| 78 | +import { getSessionMessages } from "@anthropic-ai/claude-agent-sdk"; |
| 79 | + |
| 80 | +const messages = await getSessionMessages("93bc0449-...", { dir: "/tmp" }); |
| 81 | +for (const m of messages) { |
| 82 | + console.log(m.message.role, m.message.content); |
| 83 | +} |
| 84 | +``` |
| 85 | + |
| 86 | +## Continuing a session |
| 87 | + |
| 88 | +### CLI → SDK |
| 89 | + |
| 90 | +Start a session in the CLI, then resume it from the SDK: |
| 91 | + |
| 92 | +```bash |
| 93 | +# 1. Start a session in the CLI |
| 94 | +cd /tmp |
| 95 | +echo "remember the code word is BANANA" | claude -p --output-format json |
| 96 | +# → session_id: "93bc0449-..." |
| 97 | +``` |
| 98 | + |
| 99 | +```typescript |
| 100 | +// 2. Continue from the SDK |
| 101 | +import { query } from "@anthropic-ai/claude-agent-sdk"; |
| 102 | + |
| 103 | +for await (const msg of query({ |
| 104 | + prompt: "What was the code word?", |
| 105 | + options: { |
| 106 | + resume: "93bc0449-4ff1-474a-bc36-876654f935c2", |
| 107 | + cwd: "/tmp", |
| 108 | + }, |
| 109 | +})) { |
| 110 | + if (msg.type === "result") { |
| 111 | + console.log(msg.result); // "BANANA" |
| 112 | + console.log(msg.session_id === "93bc0449-..."); // true — same session |
| 113 | + } |
| 114 | +} |
| 115 | +``` |
| 116 | + |
| 117 | +### SDK → CLI |
| 118 | + |
| 119 | +Start a session from the SDK, then resume it in the CLI: |
| 120 | + |
| 121 | +```typescript |
| 122 | +// 1. Start from the SDK |
| 123 | +let sessionId: string; |
| 124 | +for await (const msg of query({ prompt: "hello", options: { cwd: "/tmp" } })) { |
| 125 | + if (msg.type === "result") sessionId = msg.session_id; |
| 126 | +} |
| 127 | +``` |
| 128 | + |
| 129 | +```bash |
| 130 | +# 2. Resume from the CLI |
| 131 | +cd /tmp |
| 132 | +claude -r "93bc0449-4ff1-474a-bc36-876654f935c2" |
| 133 | +``` |
| 134 | + |
| 135 | +### Continue most recent session |
| 136 | + |
| 137 | +Instead of passing a specific session ID, continue the most recent session in a directory: |
| 138 | + |
| 139 | +```typescript |
| 140 | +// SDK |
| 141 | +query({ prompt: "follow up", options: { continue: true, cwd: "/tmp" } }); |
| 142 | +``` |
| 143 | + |
| 144 | +```bash |
| 145 | +# CLI |
| 146 | +claude -c |
| 147 | +``` |
| 148 | + |
| 149 | +### Fork a session |
| 150 | + |
| 151 | +Branch off a session into a new one (preserves the original): |
| 152 | + |
| 153 | +```typescript |
| 154 | +query({ |
| 155 | + prompt: "try a different approach", |
| 156 | + options: { |
| 157 | + resume: "93bc0449-...", |
| 158 | + forkSession: true, |
| 159 | + cwd: "/tmp", |
| 160 | + }, |
| 161 | +}); |
| 162 | +``` |
| 163 | + |
| 164 | +```bash |
| 165 | +claude -r "93bc0449-..." --fork-session |
| 166 | +``` |
| 167 | + |
| 168 | +## Important constraints |
| 169 | + |
| 170 | +- **`cwd` must match** — sessions are keyed by working directory. If you started a session in `/tmp`, you must resume with `cwd: "/tmp"`. |
| 171 | +- **Sessions are local** — stored on the filesystem, not synced across machines. To transfer a session, copy the `.jsonl` file. |
| 172 | +- **Git worktrees share sessions** — all worktrees in the same git repo share a single session directory. |
| 173 | + |
| 174 | +## SDK packages |
| 175 | + |
| 176 | +| Language | Package | |
| 177 | +| ---------- | -------------------------------- | |
| 178 | +| TypeScript | `@anthropic-ai/claude-agent-sdk` | |
| 179 | +| Python | `claude-agent-sdk` | |
| 180 | + |
| 181 | +## Reference |
| 182 | + |
| 183 | +- [CLI reference](https://docs.anthropic.com/en/docs/claude-code/cli-reference) |
| 184 | +- [SDK sessions documentation](https://docs.anthropic.com/en/docs/claude-code/sdk/sessions) |
0 commit comments