In a previous post, I documented the 27 fields in Claude Desktop’s Cowork session manifest files. That post ended with an explicit gap: “The session JSON contains metadata, configuration, and user decisions, but not the full conversation transcript. There are no message arrays, no assistant responses, no tool call logs.”
This post fills that gap. The transcripts exist, they’re on disk in plain JSONL, and the path to them can be derived from three fields in the manifest. There’s also an audit log with per-session cost data that I haven’t seen documented anywhere.
How I found this
Every community tool for extracting Claude conversations targets ~/.claude/projects/. That’s where Claude Code CLI and VS Code store their JSONL transcripts, and tools like claude-conversation-extractor, claude-code-transcripts, and claude-history all look there.
But Cowork doesn’t write to ~/.claude/projects/. If you only search that path, you’ll find your CLI and VS Code sessions but miss every Cowork conversation.
The base directory, local-agent-mode-sessions/, isn’t a secret. GitHub issue #24534 confirmed it, and several community posts reference it. What was missing was the path from that base directory down to the actual JSONL transcript files, and the mapping from manifest fields to file locations. I traced that by enumerating the directory trees of all 195 Cowork sessions on my machine and matching them against their manifest fields.
The result, in March: a three-field mapping that resolved every manifest to its transcript with a 100% hit rate across all sessions that had successfully started.
Updated September 30, 2026. The path below stopped working for new sessions in spring 2026. On my machine it finds every Cowork transcript from sessions started in February and March, 23 of the 41 started in April, and none of the 109 started in May and June [measured 2026-09-30, each session’s start time in its manifest]. The transcripts weren’t lost, they moved. Newer sessions explains the change and gives a rule that finds all of them.
Where the transcripts actually live
On Windows, the full path to a Cowork conversation transcript from February or March 2026 is:
%AppData%\Claude\local-agent-mode-sessions\<org-id>\<user-id>\<sessionId>\.claude\projects\-sessions-<processName>\<cliSessionId>.jsonl
Breaking that down:
| Segment | Source | Example |
|---|---|---|
%AppData%\Claude\local-agent-mode-sessions\ | Fixed base path | C:\Users\Bryce\AppData\Roaming\Claude\local-agent-mode-sessions\ |
<org-id>\ | Organization UUID | e633e2fd-bc86-46af-91ae-069658732371\ |
<user-id>\ | User UUID | e9941c22-54c5-42dc-b970-4713ba9f6109\ |
<sessionId>\ | Manifest’s sessionId field | local_7876b7f6-7ea3-4d3e-a128-38fe1e18266e\ |
.claude\projects\ | Standard Claude Code internal structure | |
-sessions-<processName>\ | VM working directory, encoded | -sessions-charming-adoring-darwin\ |
<cliSessionId>.jsonl | Manifest’s cliSessionId field | 4368fcb8-373d-4ba7-9952-3beee2a56818.jsonl |
On macOS, the base path is ~/Library/Application Support/Claude/local-agent-mode-sessions/. This is corroborated by multiple GitHub issues and community posts, though I’ve only verified the full internal transcript path on Windows.
Note on directory names: In March, GitHub issues #29373 and #27463 described local-agent-mode-sessions being renamed to claude-code-sessions, with migration bugs on both platforms. Both directories exist on my machine, but they hold different things. As of September 30, 2026, every Cowork session I have is under local-agent-mode-sessions, and claude-code-sessions holds the sessions from Claude Desktop’s Code tab, whose manifests carry fields like branch and worktreePath and none of Cowork’s VM fields [measured 2026-09-30].
The manifest-to-transcript mapping
Three fields from the session manifest (local_<sessionId>.json) give you the transcript path:
sessionId: names the session data directoryprocessName: encodes as theprojects/subdirectory name (the VM’scwdwas always/sessions/<processName>, which encodes to-sessions-<processName>). Newer sessions use the manifest’scwdfield instead: see Newer sessions.cliSessionId: names the JSONL transcript file
Validation results across 195 sessions, March 2026:
- 181 sessions have a
cliSessionIdand a matching JSONL at the predicted path, a 100% hit rate - 14 manifests lack
cliSessionIdentirely. These are failed or aborted sessions where the VM was created but the Claude Code process never started (0 seconds duration, emptyprojects/directories) - 0 JSONL files at unexpected paths
- 0 orphaned data directories without manifests
- 0 orphaned manifests without data directories
Newer sessions use a different folder
In late April 2026, the working directory Cowork gives Claude Code changed, and the transcript folder name changed with it. On my machine the last session in the old layout started on April 20 and the first in the new one on April 21 [measured 2026-09-30]. Two manifest fields show it. cwd is the working directory Claude Code ran in; every session I have carries it. hostLoopMode is newer: it’s missing or false on the older sessions and true on every session in the new layout.
On the older sessions, cwd is /sessions/<processName> inside the VM, which is why the folder name was -sessions-<processName>. On the newer ones, cwd is a folder on your own disk: the session’s outputs folder, inside its session data directory. The folder name under .claude\projects\ is that Windows path with every character that isn’t a letter or a digit replaced by -:
...\<sessionId>\.claude\projects\C--Users-<you>-AppData-Roaming-Claude-local-agent-mode-sessions-<org-id>-<user-id>-local-<uuid>-outputs\<cliSessionId>.jsonl
So the rule that covers both eras is to read cwd from the manifest, replace each character that isn’t a letter or digit with -, and use that as the folder name. Across all 400 Cowork sessions on my machine that have a cliSessionId, from February 11 to June 3, 2026, that rule finds the transcript every time: 273 in the old layout and 127 in the new one [measured 2026-09-30].
One limit, which I read in the current Claude Code rather than hit: if the encoded name is longer than 200 characters, Claude Code keeps the first 200 and adds a hyphen and a short hash. The newer folder name is 183 characters plus the length of your profile folder’s name under C:\Users\ [derived from this machine’s 188], so a name of 18 characters or more pushes it over. If yours does, match the folder on its first 200 characters.
The simpler route skips the encoding. Every one of my 400 sessions has exactly one folder under .claude\projects\, so <sessionId>\.claude\projects\*\<cliSessionId>.jsonl finds the transcript in either layout, truncated or not [measured 2026-09-30]. Read everything in that folder, though: three of my sessions from late March and April hold seven more full transcripts beside the one cliSessionId names.
The rest of the layout didn’t change. Every newer session still has its audit.jsonl at the session data root, and subagent transcripts still sit in a subagents folder next to the main transcript.
I haven’t checked this against a Cowork session made on the current Claude Desktop 2.x release, because my last Cowork session was on June 3. If yours doesn’t match, the manifest’s cwd is the first thing I’d look at.
Important: sessionId and cliSessionId are not the same thing. sessionId uses a local_ prefix and identifies the Cowork session. cliSessionId is a bare UUID that identifies the Claude Code CLI process running inside the VM. The transcript file is named after the CLI session, not the Cowork session.
What’s in the transcripts
The JSONL format shares the same core structure as Claude Code CLI transcripts. Each line is a JSON object with a type field.
Line types observed across 195 sessions, March 2026 (not re-checked since):
| Type | Description | Cowork | CLI |
|---|---|---|---|
assistant | Claude’s responses (content, tool_use, tool_result blocks) | Yes | Yes |
user | User messages and tool results | Yes | Yes |
system | System messages, compaction metadata | Yes | Yes |
queue-operation | Enqueue/dequeue operations | Yes | Yes |
progress | Streaming token progress updates | No | Yes |
file-history-snapshot | File edit undo snapshots | No | Yes |
pr-link | GitHub PR URLs | No | Yes |
Field-level differences on shared types:
- On
assistantlines: Cowork addserrorandisApiErrorMessagefields (not present in CLI) - On
userlines: Cowork addssourceToolUseID; CLI hastodosinstead
In March, tools that parse Claude Code CLI JSONL would mostly have worked on Cowork transcripts, but they’d have missed the Cowork-specific fields and wouldn’t have seen progress, file-history-snapshot, or pr-link lines. Check your own before relying on that for newer sessions.
The audit log
Every Cowork session has an audit.jsonl file at the session data root (not inside .claude/):
%AppData%\Claude\local-agent-mode-sessions\<org-id>\<user-id>\<sessionId>\audit.jsonl
This is Cowork-only. 195 audit.jsonl files found in Cowork sessions, 0 found anywhere in ~/.claude/.
The audit log has a different schema from the conversation transcript:
| Line Type | What it contains |
|---|---|
system (subtype: init) | Session initialization: cwd, tools, model, MCP servers, plugins, skills, slash commands, permission mode, Claude Code version, agents |
assistant | Simplified assistant messages with _audit_timestamp |
user | Simplified user messages with _audit_timestamp |
tool_use_summary | Aggregated summaries of tool use sequences |
result | Session cost data: total_cost_usd, duration_ms, duration_api_ms, num_turns, usage, stop_reason, modelUsage |
rate_limit_event | Rate limit information |
The result lines are the most interesting: they contain actual dollar costs per session. Sample data from real sessions:
| Session | Cost | Duration | Turns |
|---|---|---|---|
| ShopForge QA Review | $11.61 | 57 min | 174 |
| Review customer persona research | $8.64 | 14 min | 88 |
| Plan next project priorities | $6.85 | 16 min | 105 |
| Compare image quality | $6.34 | 17 min | 108 |
| Plan next steps forward | $2.60 | 5 min | 53 |
| Review storage usage | $1.59 | 4 min | 45 |
Failed sessions (the 14 without cliSessionId) produce no result lines.
Subagent transcripts
Cowork frequently spawns subagents. Their transcripts live at:
...\<encoded cwd>\<cliSessionId>\subagents\agent-<id>.jsonl
Quantified across 195 sessions:
- 98 sessions (50.3%) spawn at least one subagent
- Range: 1–35 subagents per session
- Mean: 4.9, Median: 3
- 11 sessions spawned 10+ subagents
- Subagent JSONL uses the same schema as the main transcript (typically just a few lines per agent)
- No per-subagent audit.jsonl; cost data is only at the session level
A gap in community tooling
The existing tools for extracting Claude conversations (claude-conversation-extractor, claude-code-transcripts, claude-history) correctly target ~/.claude/projects/ for CLI sessions. That’s where Claude Code CLI and VS Code write their transcripts, and those tools work well for that data.
The gap is that Cowork’s separate storage path isn’t covered. If you use both Claude Code CLI and Cowork through the Desktop app, these tools will find one half of your sessions and miss the other.
The source of the confusion: Claude Desktop has both a “Code” tab and a “Cowork” tab. The Code tab runs Claude Code against host directories and writes transcripts to ~/.claude/projects/<encoded-host-path>/. Cowork runs Claude Code inside an isolated VM and writes transcripts to %AppData%\Claude\local-agent-mode-sessions/. GitHub issue #29801, which reports both apps “reading the same .jsonl file from ~/.claude/projects/”, was testing Claude Code through the Desktop app’s Code tab, not Cowork.
Other things that don’t exist where you’d expect:
history.jsonl: frequently referenced as a global session index at~/.claude/history.jsonl. Does not exist on Windows with Claude Code 2.1.64. Either deprecated or was never created by the Desktop app (vs. CLI).sessions-index.json: exists but only for CLI projects, and only in 2 of 9 project directories on the tested machine. Not present in Cowork sessions. Appears to be generated on-demand (e.g., when/resumeis used).
The complete storage map
| Layer | Location (Windows) | Contents | Cowork | CLI |
|---|---|---|---|---|
| Session manifest | %AppData%\Claude\local-agent-mode-sessions\...\local_<id>.json | Config, metadata, system prompt, PII (27+ fields) | Yes | No |
| Conversation transcript | ...\local_<id>\.claude\projects\<encoded cwd>\<cliId>.jsonl (-sessions-<name> before late April 2026) | Full message history, tool calls, responses | Yes | No |
| Subagent transcripts | ...\<cliId>\subagents\agent-<id>.jsonl | Per-subagent conversations | Yes | No |
| Audit log | ...\local_<id>\audit.jsonl | Timeline with costs, durations, rate limits | Yes | No |
| CLI transcript | ~\.claude\projects\<encoded-cwd>\<session>.jsonl | Full message history (+ progress, snapshots) | No | Yes |
| CLI session index | ~\.claude\projects\<encoded-cwd>\sessions-index.json | Session metadata (sparse, on-demand) | No | Partial |
What this means
Between this post and the session manifest schema, you now have a complete map of every file Cowork writes to disk: manifests, transcripts, subagent logs, and audit trails with per-session costs. Enough to build your own session browser, cost tracker, or conversation exporter.
This format is undocumented and can change at any time. This investigation was conducted on Windows with Claude Desktop v1.1.4498 running Claude Code 2.1.64 inside the Cowork VM, across 195 sessions spanning February 11 to March 10, 2026. I re-checked the transcript paths on September 30, 2026 against the 400 sessions I’d built up by June 3. The published JSON Schema covers the session manifest fields from the previous post.
If you’re building tools against this data, also see the posts on the scheduled task startup bug and the file upload permission fix, which both document Cowork behaviors that affect how sessions are created and what they contain.
Revision log
What changed on this page and how it was checked
2026-09-30. Re-ran the path mapping against every Cowork session on my machine: 414 manifests, 400 with a cliSessionId, from February 11 to June 3, 2026.
- Added Newer sessions. The March path finds 273 of the 400 transcripts. All 127 misses are newer sessions with
hostLoopModeset, whose transcript folder is named after the manifest’scwd. Encodingcwdfinds all 400. - Marked the original path and validation as March 2026 results. They were right for the sessions they measured, so I left the numbers alone.
- Added the 200-character limit on folder names, read from Claude Code’s code. None of my folder names reaches it.
- Added the one-folder shortcut and the seven extra transcripts in three sessions from late March and April.
- Dated the line-type table and the parser note to March, since I didn’t re-run them.
- Updated the subagent path to the encoded-
cwdfolder, matching the storage map. - Rewrote the directory-name note. On my machine,
claude-code-sessionsholds Code tab sessions, not renamed Cowork ones. - Updated the storage map to the rule that covers both layouts.
What I didn’t verify: I have no Cowork sessions made after June 3, so nothing here is checked against the current Claude Desktop 2.x release. I didn’t re-run the transcript line-type and subagent counts either; those are still the March figures.