Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/agents/formats/claude-code/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,20 @@ entry type are grouped under it.
| Field | Defined in |
|--------------------------------|------------|
| `agentId` | [jsonl-envelope.md](jsonl-envelope.md), [entry-types.md §Sidechains](entry-types.md#sidechains) |
| `agentName` | [entry-types.md](entry-types.md) |
| `aiTitle` | [entry-types.md](entry-types.md) |
| `attachment` | [jsonl-envelope.md](jsonl-envelope.md), [entry-types.md](entry-types.md) |
| `atis` | [entry-types.md](entry-types.md) |
| `cache_creation` / `cache_*_input_tokens` | [usage.md](usage.md) |
| `caller` (on `tool_use`) | [messages.md](messages.md) |
| `compactMetadata` | [entry-types.md](entry-types.md), [session-chains.md](session-chains.md) |
| `content` (envelope, on `queue-operation`) | [entry-types.md](entry-types.md) |
| `content` (inside `message` / `tool_result`) | [messages.md](messages.md) |
| `customTitle` | [entry-types.md](entry-types.md) |
| `cwd` | [jsonl-envelope.md](jsonl-envelope.md), [writing-compatible-jsonl.md](writing-compatible-jsonl.md) |
| `durationMs` | [entry-types.md](entry-types.md) |
| `entrypoint` | [jsonl-envelope.md](jsonl-envelope.md) |
| `frameUrl` / `path` / `title` (on `frame-link`) | [entry-types.md](entry-types.md) |
| `gitBranch` | [jsonl-envelope.md](jsonl-envelope.md) |
| `hookCount` / `hookInfos` / `hookErrors` | [jsonl-envelope.md](jsonl-envelope.md) |
| `id` (inside `message`) | [messages.md](messages.md) |
Expand All @@ -124,11 +129,14 @@ entry type are grouped under it.
| `message` | [messages.md](messages.md) |
| `messageCount` (envelope) | [entry-types.md](entry-types.md) |
| `messageId` | [jsonl-envelope.md](jsonl-envelope.md), [entry-types.md](entry-types.md), [known-issues.md](known-issues.md) |
| `mode` | [entry-types.md](entry-types.md) |
| `model` (inside `message`) | [messages.md](messages.md) |
| `operation` | [entry-types.md](entry-types.md) |
| `parentUuid` | [jsonl-envelope.md](jsonl-envelope.md), [known-issues.md](known-issues.md) |
| `permissionMode` | [entry-types.md](entry-types.md), [writing-compatible-jsonl.md](writing-compatible-jsonl.md) |
| `prNumber` / `prUrl` / `prRepository` | [entry-types.md](entry-types.md) |
| `preventedContinuation` | [jsonl-envelope.md](jsonl-envelope.md) |
| `relocatedCwd` | [entry-types.md](entry-types.md), [writing-compatible-jsonl.md](writing-compatible-jsonl.md) |
| `requestId` | [jsonl-envelope.md](jsonl-envelope.md) |
| `role` | [messages.md](messages.md) |
| `server_tool_use` | [usage.md](usage.md) |
Expand Down Expand Up @@ -156,6 +164,7 @@ entry type are grouped under it.
| `userType` | [jsonl-envelope.md](jsonl-envelope.md) |
| `uuid` | [jsonl-envelope.md](jsonl-envelope.md) |
| `version` | [jsonl-envelope.md](jsonl-envelope.md) |
| `worktreeSession` | [entry-types.md](entry-types.md), [writing-compatible-jsonl.md](writing-compatible-jsonl.md) |

For the mapping from these JSON keys to Rust fields in
`ConversationEntry`, see the parser-surface table in
Expand Down
134 changes: 134 additions & 0 deletions docs/agents/formats/claude-code/entry-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ a large fraction of the file.
| `permission-mode` | no | no | Records the active permission mode. |
| `queue-operation` | no | no | Enqueue/dequeue of a typed-ahead message while an assistant turn is in flight. |
| `last-prompt` | no | no | Cached last user prompt. |
| `ai-title` | no | no | Generated session title. |
| `custom-title` | no | no | Explicitly set session title. |
| `agent-name` | no | no | Agent name for the session. |
| `mode` | no | no | Active mode. Only `"normal"` observed. |
| `atis-latch` | no | no | Opaque latch value. Purpose unknown. |
| `pr-link` | no | no | Pull request linked to the session. |
| `frame-link` | no | no | Frame URL linked to a local file. |
| `relocated` | no | no | New working directory for the session. |
| `worktree-state` | no | no | Git worktree the session is in; `null` after it leaves. |
| `summary` | no | no | Conversation summary. May live in a different JSONL file than the conversation it describes. |
| `compact_boundary` | no (usually) | yes | Marks an autocompaction event. Also appears as `system.subtype` in some versions. |
| `progress` | no | yes | Long-running tool progress event. Should be skipped when reconstructing a transcript. |
Expand Down Expand Up @@ -297,6 +306,131 @@ Cached last user prompt, for resume / history purposes:

---

## Session metadata lines

The line types below share one shape: `type`, `sessionId`, and one
payload key. None carries `uuid`, `timestamp` (except where noted),
`cwd`, or `parentUuid`. All are observed in a local store spanning
client versions 2.1.215 – 2.1.245; the first version that writes each
one is not known.

### `ai-title`

Generated session title. Rewritten as the session progresses.

```json
{"type": "ai-title", "aiTitle": "Fix the flaky test", "sessionId": "..."}
```

### `custom-title`

Explicitly set session title.

```json
{"type": "custom-title", "customTitle": "config-export", "sessionId": "..."}
```

### `agent-name`

Agent name for the session. In observed data it carries the same value
as the session's `custom-title`.

```json
{"type": "agent-name", "agentName": "config-export", "sessionId": "..."}
```

### `mode`

Active mode. Only `"normal"` is observed.

```json
{"type": "mode", "mode": "normal", "sessionId": "..."}
```

### `atis-latch`

Opaque latch value. `atis` is an empty string, a 16-character hex
string, or a ~190-character string. Its purpose is unknown.

```json
{"type": "atis-latch", "atis": "", "sessionId": "..."}
```

### `pr-link`

Pull request linked to the session. Carries a `timestamp`.

```json
{
"type": "pr-link",
"sessionId": "...",
"prNumber": 233,
"prUrl": "https://github.com/owner/repo/pull/233",
"prRepository": "owner/repo",
"timestamp": "2026-08-25T15:10:16.000Z"
}
```

### `frame-link`

Frame URL linked to a local file. Carries a `timestamp`. One sample
observed.

```json
{
"type": "frame-link",
"sessionId": "...",
"path": "/home/user/project/design.html",
"frameUrl": "https://...",
"title": "...",
"timestamp": "2026-08-25T15:10:16.000Z"
}
```

### `relocated`

New working directory for the session. `relocatedCwd` is an absolute
path.

```json
{"type": "relocated", "relocatedCwd": "/home/user/project", "sessionId": "..."}
```

### `worktree-state`

Git worktree the session is in. `worktreeSession` is an object on
entry and `null` after the session leaves the worktree.

```json
{
"type": "worktree-state",
"sessionId": "...",
"worktreeSession": {
"originalCwd": "/home/user/project",
"preEnterOriginalCwd": "/home/user/project",
"worktreePath": "/home/user/project/.claude/worktrees/topic",
"worktreeName": "topic",
"worktreeBranch": "user/topic",
"originalBranch": "main",
"originalHeadCommit": "b31f2c5...",
"sessionId": "..."
}
}
```

`originalBranch` and `originalHeadCommit` appear when the worktree was
created for the session. `enteredExisting: true` replaces them when
the session entered a worktree that already existed. The three path
fields are absolute. `worktreeSession.sessionId` equals the line's
`sessionId` in every observed sample.

A writer that moves a session to another directory or renames it must
decide what to do with `relocatedCwd`, the three `worktreeSession`
paths, and the inner `sessionId`. See
[writing-compatible-jsonl.md](writing-compatible-jsonl.md).

---

## `summary`

Conversation summary entries. Minimal shape:
Expand Down
9 changes: 7 additions & 2 deletions docs/agents/formats/claude-code/format-changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ later than") unless the note says otherwise.
## Format-revision stamp

This reference tracks Claude Code **2.1.x**. First-hand samples span
client versions 2.1.37, 2.1.90, 2.1.110, and 2.1.112. Reference
revision: **2026-04-23**.
client versions 2.1.37, 2.1.90, 2.1.110, and 2.1.112, plus a local
store spanning 2.1.215 – 2.1.245. Reference revision: **2026-08-25**.

---

Expand Down Expand Up @@ -58,6 +58,11 @@ See [jsonl-envelope.md](jsonl-envelope.md) for field definitions.
| `queue-operation` (typed-ahead message enqueue/dequeue)| 2.1.x+ (origin unclear) |
| `progress` (streaming tool output) | 2.1.x+ (origin unclear) |
| `last-prompt` | 2.1.x+ (origin unclear) |
| `ai-title`, `mode` | Observed across 2.1.215 – 2.1.245; origin unclear |
| `relocated`, `worktree-state` | Observed from 2.1.218 |
| `custom-title`, `agent-name`, `pr-link` | Observed from 2.1.220 |
| `frame-link` | Observed at 2.1.231 (1 sample) |
| `atis-latch` | Observed from 2.1.235 |
| `compact_boundary` as top-level `type` | Newer variant; coexists with older `type: "system"` + `subtype: "compact_boundary"` |
| `system.subtype` values: `turn_duration`, `stop_hook_summary`, `task_started`/`task_progress`/`task_notification` | 2.1.x+ (origin unclear) |

Expand Down
11 changes: 10 additions & 1 deletion docs/agents/formats/claude-code/jsonl-envelope.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Every envelope field we have observed, in rough order of prominence:
| Field | Shape | Notes |
|----------------|----------------------------|-------|
| `type` | string | Discriminant. Values in [entry-types.md](entry-types.md). Present on **every** line. |
| `uuid` | UUIDv4 string | Per-entry ID. Empty string (`""`) or absent on some metadata entries (`permission-mode`, `queue-operation`, `last-prompt`, `file-history-snapshot`). |
| `uuid` | UUIDv4 string | Per-entry ID. Empty string (`""`) or absent on some metadata entries (`permission-mode`, `queue-operation`, `last-prompt`, `file-history-snapshot`, and the session metadata lines in [entry-types.md](entry-types.md)). |
| `timestamp` | ISO-8601 string | e.g. `"2026-04-02T13:59:26.313Z"`. Millisecond precision. Absent on pure-metadata entries. |
| `sessionId` | UUIDv4 string | Usually equals the filename stem. On continuation files, the first real entry carries the **previous** session's ID — see [session-chains.md](session-chains.md). |
| `parentUuid` | UUIDv4 string \| `null` | Prior entry in the conversation DAG. `null` for the first entry of a session and for `compact_boundary` entries (which use `logicalParentUuid` instead). |
Expand Down Expand Up @@ -77,6 +77,15 @@ Every envelope field we have observed, in rough order of prominence:
| `operation` | string | `queue-operation` | `"enqueue"` / `"dequeue"`. |
| `content` | string | `queue-operation` | Queued message text. **Conflicts in name with `message.content`** — distinguish by entry `type`. |
| `lastPrompt` | string | `last-prompt` | Cached last user prompt. |
| `aiTitle` | string | `ai-title` | Generated session title. |
| `customTitle` | string | `custom-title` | Explicitly set session title. |
| `agentName` | string | `agent-name` | Agent name for the session. |
| `mode` | string | `mode` | Only `"normal"` observed. |
| `atis` | string | `atis-latch` | Opaque. Empty, 16 hex characters, or ~190 characters. |
| `prNumber` / `prUrl` / `prRepository` | number / URL / `owner/repo` | `pr-link` | Pull request linked to the session. |
| `frameUrl` / `path` / `title` | URL / absolute path / string | `frame-link` | Frame URL linked to a local file. |
| `relocatedCwd` | absolute path | `relocated` | New working directory for the session. |
| `worktreeSession` | object \| `null` | `worktree-state` | `{originalCwd, preEnterOriginalCwd, worktreePath, worktreeName, worktreeBranch, sessionId, …}`. See [entry-types.md](entry-types.md). |
| `subtype` | string | `system`, `compact_boundary` | Discriminant within metadata entries. See [entry-types.md](entry-types.md). |
| `durationMs` | number | `system` (turn_duration) | Milliseconds the assistant turn took. |
| `messageCount` | number | `system` (turn_duration) | Number of messages in the turn. |
Expand Down
8 changes: 7 additions & 1 deletion docs/agents/formats/claude-code/writing-compatible-jsonl.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ directory name under `projects/`. If you place a file in
entries, Claude Code's behavior is inconsistent — the session may
appear but tool invocations may fail.

Two metadata lines carry absolute paths under other keys:
`relocated.relocatedCwd`, and `originalCwd`, `preEnterOriginalCwd`,
and `worktreePath` inside `worktree-state.worktreeSession`. How the
loader uses them on resume is not known. A writer that moves a session
to another directory decides for each whether to rewrite it.

## Strong conventions

Real Claude Code entries always carry these envelope fields. The
Expand All @@ -79,7 +85,7 @@ downstream tools may behave oddly without them:
| `cwd` | Used for git/branch context and to validate project alignment. |
| `version` | Claude Code client version string. |
| `gitBranch` | Current branch; **empty string**, not null, when cwd isn't a repo. |
| `sessionId` | Must match the file's session UUID (or be a bridge entry — see below). |
| `sessionId` | Must match the file's session UUID (or be a bridge entry — see below). `worktree-state` lines carry a second copy in `worktreeSession.sessionId`; keep both equal. |
| `uuid` | UUIDv4 per entry. |
| `timestamp` | ISO-8601 with millisecond precision. |
| `parentUuid` | The prior entry's `uuid` (or `null` for the first entry). |
Expand Down
Loading