agentel 0.2.8 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,7 @@ All supported sources are normalized into the same archive shape before write:
17
17
  - `cwd`: working directory if the source exposes one or agentlog can infer one.
18
18
  - `repoCanonical`: git remote key from `cwd`, such as `github.com/org/repo`.
19
19
  - `scopeCanonical`: non-repo storage scope for sessions without a reliable
20
- working directory, such as `claude-desktop/uncategorized`.
20
+ working directory, such as `claude-cowork/uncategorized`.
21
21
  - `messages`: normalized `user`, `assistant`, `system`, or `tool` messages with
22
22
  ISO timestamps.
23
23
  - `sourcePath`: local source file, directory, database, or export file.
@@ -59,6 +59,44 @@ usage is preserved separately and repeated provider request ids are counted once
59
59
  which avoids inflating Claude Code/Desktop sessions that repeat the same request
60
60
  usage across assistant text and tool-call rows.
61
61
 
62
+ Session metadata stores compact `toolUsage` summaries derived from canonical
63
+ `tool.called`/`tool.completed` events so global and project stats can aggregate
64
+ most-used tools without rereading transcripts. Existing archives without that
65
+ field need a clean reimport/rebuild before most-used tool stats are complete;
66
+ the web stats layer does not reread event files in the request path.
67
+
68
+ Archive schema v6 adds import-time summaries for work and durable context.
69
+ `outputTokenWork`
70
+ classifies assistant output tokens into `text`, `toolUse`, `reasoning`, and
71
+ `unknown` buckets when message usage and message shape support it; mixed
72
+ text/tool messages are counted as `unknown` instead of being split by a hidden
73
+ heuristic. `outcomes` stores lightweight counts for edit tool calls, unique
74
+ files touched by edit tools, and durable knowledge captures such as `AGENTS.md`,
75
+ `CLAUDE.md`, provider memory files, skill definitions, project rules, and
76
+ planning/decision docs. Canonical events v5 additionally emits `memory.read`,
77
+ `memory.write`, and `memory.loaded` events for memory-file activity, and
78
+ `outcomes` records `memoryReads`, `memoryWrites`, and `memoryLoads` separately
79
+ from generic edit/tool counts. The stats API aggregates these fields into daily
80
+ rows for output job-mix charts and tokens-per-meaningful-event ratios. Older
81
+ archives should be rebuilt or reimported for coverage; the viewer does not scan
82
+ old transcripts to recover these fields.
83
+ View schema v9 carries those memory events through the compact browser payload
84
+ and renders memory-file reads, writes, and loads as memory activity rather than
85
+ ordinary file diff cards.
86
+
87
+ Spend charts are derived from actual provider/export `costUsd` values when
88
+ available, otherwise from a versioned model-pricing table and known token
89
+ directions. Tokens that cannot be priced confidently remain in unpriced coverage
90
+ fields rather than being multiplied by a single blended rate. Estimated spend
91
+ payloads carry pricing source/version metadata from `src/pricing.js`, while
92
+ provider-reported cost stays labeled as actual. The stats API also emits a
93
+ 30-day usage summary for the web viewer: latest-day spend/tokens/prompts,
94
+ 7-day spend, 30-day spend/tokens/prompts/sessions, and the top known model in
95
+ that window. Browser stats payloads are range-shaped: the default response
96
+ includes all-time scalar totals, the visible chart window, and the rolling
97
+ activity heatmap; older activity years and all-time daily breakdowns are fetched
98
+ on demand instead of being bundled into every first load.
99
+
62
100
  When provider token usage is missing, message-level estimates use visible text
63
101
  length plus visible tool-call summaries at roughly four characters per token.
64
102
  The generic archive estimate is stored as `metadata.tokenEstimate` on each
@@ -84,6 +122,12 @@ own SDK aggregate fields plus `split_stats.sdk`, and the web view renders an SDK
84
122
  jobs card and heatmap. This keeps high-volume batch automation searchable and
85
123
  auditable without letting it swamp interactive usage stats.
86
124
 
125
+ Subagent child sessions are also excluded from primary stats by default. Parent
126
+ sessions keep compact subagent run metadata and provider-level thread counters,
127
+ while child sessions remain direct-addressable for transcript inspection and can
128
+ be included by the web stats Subagents toggle or other explicit
129
+ subagent-inclusive stats/search paths.
130
+
87
131
  Cursor sessions that still lack provider-reported usage get a separate
88
132
  `estimatedUsage` metadata field instead of synthetic `usage`. The estimate uses
89
133
  empirical per-assistant-turn Cursor rates by model family, with visible
@@ -99,11 +143,26 @@ agentlog update --yes
99
143
  ```
100
144
 
101
145
  `agentlog update` preserves config preferences, redaction settings, web account
102
- labels, manually imported ChatGPT/Claude.ai archive objects, source histories,
146
+ labels, manually imported ChatGPT/Claude.ai archive objects, local archive
147
+ objects whose original source files are no longer present, source histories,
103
148
  and recall integrations. It removes derived local agent archive/import/index
104
- state and reimports configured local sources. The default rebuild window is
105
- `imports.updateSince`, saved from the initial backfill or explicit all-source
106
- imports, falling back to `all` for legacy configs. The watcher's rolling
149
+ state and reimports configured local sources. Sessions whose source transcripts
150
+ have already been cleaned up by the source application are restored from the
151
+ previous agentlog archive instead of being silently dropped, and update/doctor
152
+ report a source/provider/sourceType breakdown for those preserved unavailable
153
+ sessions. When the preserved session is an old Claude Code archive with an
154
+ Agentlog raw backup, restore the source transcript explicitly before a clean
155
+ reimport:
156
+
157
+ ```sh
158
+ agentlog repair claude-code-backups --dry-run
159
+ agentlog repair claude-code-backups --yes
160
+ agentlog update --yes --since all --sources claude
161
+ ```
162
+
163
+ The default rebuild window is `imports.updateSince`, saved from the initial
164
+ backfill or explicit all-source imports, falling back to `all` for legacy configs.
165
+ The watcher's rolling
107
166
  `imports.defaultSinceDays` is not used by `agentlog update`; `--since` still
108
167
  overrides it for one run. Manual web exports only need to be
109
168
  imported again from the original export file when those chat archives themselves
@@ -142,13 +201,16 @@ agentlog does not blindly copy entire source directories.
142
201
  ## Canonical Events
143
202
 
144
203
  `events.jsonl` is the provider-independent archive/search substrate. It uses
145
- schema version `agentlog.events.v2` and these event kinds:
204
+ schema version `agentlog.events.v5` and these event kinds:
146
205
 
147
206
  - `session.started`
148
207
  - `prompt.submitted`
149
208
  - `response.generated`
150
209
  - `tool.called`
151
210
  - `tool.completed`
211
+ - `memory.read`
212
+ - `memory.write`
213
+ - `memory.loaded`
152
214
 
153
215
  Agentlog intentionally ports only the portable Forge idea here: canonical
154
216
  prompt/response/tool events with parser versions. It does not port Forge's
@@ -161,10 +223,12 @@ events add viewer-facing display metadata:
161
223
 
162
224
  - `metadata.toolCalls[]`: `id`, `name`, `displayName`, `category`, `title`,
163
225
  `status`, `argument`, `rawInputSummary`, `inputPreview`, `target`, `icon`,
164
- `categoryLabel`, and `provider`.
226
+ `categoryLabel`, `provider`, and optional `structuredPatch` hunks when the
227
+ source exposes line-aware unified diffs.
165
228
  - `metadata.toolResult`: `id`, `name`, `provider`, `kind`, `title`, `summary`,
166
- `output`, `lineCount`, `collapsed`, `category`, `categoryLabel`, `icon`, and
167
- optional `status`.
229
+ `output`, `lineCount`, `collapsed`, `category`, `categoryLabel`, `icon`,
230
+ optional `status`, and optional provider diff hunks such as
231
+ `structuredPatch`.
168
232
 
169
233
  `tool.completed.parentEventId` links to the matching `tool.called` event when a
170
234
  provider exposes stable ids or matching tool names. When those are absent,
@@ -173,6 +237,9 @@ such as Devin CLI still preserve the call/result relationship.
173
237
 
174
238
  The viewer reads canonical events or normalized metadata first. Text patterns
175
239
  such as `Grep(...)` are legacy fallback only.
240
+ For memory-file activity, the viewer follows the canonical
241
+ `tool.called -> tool.completed -> memory.*` chain and labels the visible tool
242
+ card as a memory read/write/load instead of a generic read or edit.
176
243
 
177
244
  Provider-generated context sometimes appears in upstream logs as `role: user`.
178
245
  Agentlog preserves those records in transcripts, but reclassifies known shapes
@@ -200,36 +267,49 @@ package-prefixed scheme.
200
267
 
201
268
  | Source type | Version |
202
269
  | --- | --- |
203
- | `codex-cli-history` | `0.2.8.0` |
204
- | `codex-desktop-history` | `0.2.8.0` |
205
- | `codex-sdk-history` | `0.2.8.0` |
206
- | `cli-history` | `0.2.8.0` |
207
- | `claude-sdk-history` | `0.2.8.0` |
208
- | `claude-code-desktop-metadata` | `0.2.8.0` |
209
- | `claude-workspace-desktop` | `0.2.8.0` |
210
- | `cursor-workspace-sqlite` | `0.2.8.0` |
211
- | `cursor-global-sqlite` | `0.2.8.0` |
212
- | `cursor-raw-sqlite-salvage` | `0.2.8.0` |
213
- | `cursor-agent-transcripts` | `0.2.8.0` |
214
- | `devin-cli-history` | `0.2.8.0` |
215
- | `gemini-cli-history` | `0.2.8.0` |
216
- | `cline-task-history` | `0.2.8.0` |
217
- | `opencode-cli-history` | `0.2.8.0` |
218
- | `opencode-cli-sqlite-history` | `0.2.8.0` |
219
- | `opencode-desktop-history` | `0.2.8.0` |
220
- | `opencode-desktop-sqlite-history` | `0.2.8.0` |
221
- | `opencode-web-sqlite-history` | `0.2.8.0` |
222
- | `opencode-history` | `0.2.8.0` |
223
- | `opencode-sqlite-history` | `0.2.8.0` |
224
- | `aider-chat-history` | `0.2.8.0` |
225
- | `antigravity-history` | `0.2.8.0` |
226
- | `antigravity-trajectory-summary` | `0.2.8.0` |
227
- | `windsurf-trajectory-export` | `0.2.8.0` |
228
- | `web-chat-export` | `0.2.8.0` |
229
- | `chatgpt-export` | `0.2.8.0` |
230
- | `claude-web-export` | `0.2.8.0` |
231
- | `claude-web-memory` | `0.2.8.0` |
232
- | `import` | `0.2.8.0` |
270
+ | `codex-cli-history` | `0.3.1.0` |
271
+ | `codex-desktop-history` | `0.3.1.0` |
272
+ | `codex-sdk-history` | `0.3.1.0` |
273
+ | `cli-history` | `0.3.1.0` |
274
+ | `claude-sdk-history` | `0.3.1.0` |
275
+ | `claude-code-desktop-metadata` | `0.3.1.0` |
276
+ | `claude-workspace-desktop` | `0.3.1.0` |
277
+ | `cursor-workspace-sqlite` | `0.3.1.0` |
278
+ | `cursor-global-sqlite` | `0.3.1.0` |
279
+ | `cursor-raw-sqlite-salvage` | `0.3.1.0` |
280
+ | `cursor-agent-transcripts` | `0.3.1.0` |
281
+ | `devin-cli-history` | `0.3.1.0` |
282
+ | `devin-desktop-acp-events` | `0.3.1.0` |
283
+ | `copilot-cli-history` | `0.3.1.0` |
284
+ | `factory-droid-history` | `0.3.1.0` |
285
+ | `grok-build-history` | `0.3.1.0` |
286
+ | `pi-cli-history` | `0.3.1.0` |
287
+ | `gemini-cli-history` | `0.3.1.0` |
288
+ | `cline-task-history` | `0.3.1.0` |
289
+ | `opencode-cli-history` | `0.3.1.0` |
290
+ | `opencode-cli-sqlite-history` | `0.3.1.0` |
291
+ | `opencode-desktop-history` | `0.3.1.0` |
292
+ | `opencode-desktop-sqlite-history` | `0.3.1.0` |
293
+ | `opencode-web-sqlite-history` | `0.3.1.0` |
294
+ | `opencode-history` | `0.3.1.0` |
295
+ | `opencode-sqlite-history` | `0.3.1.0` |
296
+ | `aider-chat-history` | `0.3.1.0` |
297
+ | `antigravity-history` | `0.3.1.0` |
298
+ | `antigravity-transcript-log` | `0.3.1.0` |
299
+ | `antigravity-cli-transcript-log` | `0.3.1.0` |
300
+ | `antigravity-cli-brain` | `0.3.1.0` |
301
+ | `antigravity-ide-transcript-log` | `0.3.1.0` |
302
+ | `antigravity-ide-brain` | `0.3.1.0` |
303
+ | `antigravity-summary-proto` | `0.3.1.0` |
304
+ | `antigravity-trajectory-summary` | `0.3.1.0` |
305
+ | `windsurf-cascade-brain` | `0.3.1.0` |
306
+ | `windsurf-cascade-protobuf` | `0.3.1.0` |
307
+ | `windsurf-trajectory-export` | `0.3.1.0` |
308
+ | `web-chat-export` | `0.3.1.0` |
309
+ | `chatgpt-export` | `0.3.1.0` |
310
+ | `claude-web-export` | `0.3.1.0` |
311
+ | `claude-web-memory` | `0.3.1.0` |
312
+ | `import` | `0.3.1.0` |
233
313
 
234
314
  `cursor-sqlite-history` and `antigravity-brain` are compatibility aliases for
235
315
  older labels. Fingerprints include the parser version prefix, so changing the
@@ -243,21 +323,25 @@ back to sessions for CLI/skill compatibility. Archives without `events.jsonl`
243
323
  remain searchable through transcript/markdown fallback, and missing
244
324
  `conversation.md` files are materialized from transcripts when needed.
245
325
  The web session API reads pre-baked `view.json` for the default readable pane.
246
- When the raw Markdown source view is requested, the browser asks for a
247
- Markdown-only payload instead of downloading the full transcript again. Browser
248
- session payloads compact duplicated tool output and use ETag revalidation so
326
+ `view.json` is a display cache, not the source of truth: it keeps transcript
327
+ message content visible but omits duplicated tool-output bodies from structured
328
+ metadata and canonical-event text so very long sessions can still be written and
329
+ loaded. The full redacted transcript and canonical events remain in
330
+ `transcript.jsonl` and `events.jsonl`. When the raw Markdown source view is
331
+ requested, the browser asks for a Markdown-only payload instead of downloading
332
+ the full transcript again. Browser session payloads use ETag revalidation so
249
333
  revisits and live refresh checks can avoid reparsing unchanged transcripts.
250
- The local BM25 JSON index stores term postings plus document metadata for
251
- compatibility. A SQLite FTS5 sidecar stores the same chunks for interactive
252
- search so browser, terminal, and MCP recall queries do not parse a large JSON
253
- index in short-lived search processes. Index format bumps trigger a rebuild from
254
- existing `transcript.jsonl` and `events.jsonl`; they do not require reparsing
255
- provider source files. The web search endpoint is optimized for typing: it uses
256
- the compatible warm FTS/index when present, skips obsolete or stale indexes
257
- rather than parsing/rebuilding inline, and does not scan every rendered Markdown
258
- archive as a fallback. Terminal and MCP recall search also avoid synchronous
259
- rebuilds and BM25 JSON parses, then fall back to the bounded Markdown search for
260
- legacy archives or misses.
334
+ The normal local index rebuild writes a small JSON summary plus a SQLite FTS5
335
+ sidecar for browser, terminal, and MCP recall queries. The older full BM25 JSON
336
+ index still exists for explicit compatibility callers, but routine update and
337
+ rebuild flows avoid generating that large serialized object. Index format bumps
338
+ trigger a rebuild from existing `transcript.jsonl` and `events.jsonl`; they do
339
+ not require reparsing provider source files. The web search endpoint is
340
+ optimized for typing: it uses the compatible warm FTS/index when present, skips
341
+ obsolete or stale indexes rather than parsing/rebuilding inline, and does not
342
+ scan every rendered Markdown archive as a fallback. Terminal and MCP recall
343
+ search also avoid synchronous rebuilds and BM25 JSON parses, then fall back to
344
+ the bounded Markdown search for legacy archives or misses.
261
345
 
262
346
  Recall quality has deterministic tests in `test/recall-eval.test.js` with
263
347
  fixtures under `test/fixtures/recall-evals.json`. Add a fixture when a vague
@@ -268,25 +352,33 @@ real-world query should reliably find a representative archived session.
268
352
  The setup UI, import defaults, and history source filters use this grouped order:
269
353
 
270
354
  1. OpenAI: Codex CLI, Codex Desktop, Codex SDK jobs, ChatGPT
271
- 2. Anthropic: Claude Code CLI, Claude Code Desktop, Claude Workspace,
355
+ 2. Anthropic: Claude Code CLI, Claude Code Desktop, Claude Cowork,
272
356
  Claude.ai, Claude SDK jobs
273
- 3. Google: Gemini CLI, Antigravity
274
- 4. Cognition: Devin CLI
275
- 5. Other: Cursor, Cline, OpenCode CLI, OpenCode Desktop, OpenCode Web, Aider
357
+ 3. Google: Gemini CLI, Antigravity CLI, Antigravity 2.0, Antigravity IDE
358
+ 4. Cognition: Devin CLI, Devin Desktop, Windsurf
359
+ 5. GitHub: GitHub Copilot CLI
360
+ 6. Factory: Factory Droid
361
+ 7. xAI: Grok Build
362
+ 8. Other: Cursor, pi, Cline, OpenCode CLI, OpenCode Desktop, OpenCode Web, Aider
276
363
 
277
364
  `agentlog import --source all` uses the default import order from
278
365
  `src/sources.js`: `codex-cli`, `codex-desktop`, `claude`,
279
- `claude-code-desktop`, `claude-workspace`, `gemini-cli`, `antigravity`,
280
- `devin-cli`, `cursor`, `cline`, `opencode-cli`, `opencode-desktop`,
366
+ `claude-code-desktop`, `claude-cowork`, `gemini-cli`, `antigravity-cli`, `antigravity`,
367
+ `antigravity-ide`, `devin-cli`, `devin-desktop`, `windsurf`, `copilot-cli`, `factory`, `grok-build`,
368
+ `cursor`, `pi`, `cline`, `opencode-cli`, `opencode-desktop`,
281
369
  `opencode-web`, `aider`. Codex SDK jobs and Claude SDK jobs are intentionally
282
- opt-in. Windsurf local cache scanning is disabled for now because current
283
- Cascade transcripts are encrypted binary stores, but downloaded trajectory
284
- Markdown exports are importable with an explicit path.
285
-
286
- The background watcher polls the watcher source list selected near the end of
287
- `agentlog init`. New configs still support `imports.autoDiscoverSources=true`,
288
- but init now records the chosen watcher list exactly by setting
289
- `imports.autoDiscoverSources=false`.
370
+ opt-in. Windsurf local imports are intentionally partial: readable Cascade plan
371
+ artifacts are archived when present, matching Cascade protobuf files are
372
+ preserved as raw sources, and downloaded trajectory Markdown remains the stable
373
+ full transcript path.
374
+
375
+ The background watcher covers the watcher source list selected near the end of
376
+ `agentlog init`. Sources with watchable history roots (`src/source-watch.js`)
377
+ import a few seconds after a filesystem event and are otherwise re-polled on a
378
+ 15-minute heartbeat; sources without watch roots poll every 30 seconds with a
379
+ 5-minute idle cadence. New configs still support
380
+ `imports.autoDiscoverSources=true`, but init now records the chosen watcher
381
+ list exactly by setting `imports.autoDiscoverSources=false`.
290
382
 
291
383
  Supervisor imports use `imports.defaultSinceDays` as a rolling window. Cursor
292
384
  SQLite store scans and raw recovery are disabled in supervisor ticks, so old
@@ -349,7 +441,7 @@ stable local command for the archived source.
349
441
  | Claude Code CLI | `claude -r <session-id>` | Uses the Claude Code JSONL session id. |
350
442
  | Devin CLI | `devin -r <session-id>` | agentlog archives these as `devin-<session-id>` and strips that prefix for the resume command, for example `devin -r selective-lotus`. |
351
443
  | Claude Code Desktop | No stable local resume command known. | Use Claude's own desktop/history surface or `agentlog show <session-id>`. |
352
- | Claude Workspace | No stable local resume command known. | Workspace/local-agent session ids are not known to be accepted by Claude Code's CLI resume flag. |
444
+ | Claude Cowork | No stable local resume command known. | Cowork/local-agent session ids are not known to be accepted by Claude Code's CLI resume flag. |
353
445
  | Claude SDK jobs | No interactive resume command. | These are programmatic/batch runs. |
354
446
  | ChatGPT export | No local resume command. | Official exports are imported snapshots. |
355
447
  | Claude.ai export | No local resume command. | Official exports are imported snapshots. |
@@ -409,6 +501,10 @@ viewer renders those runs inline and opens the child transcript in the same
409
501
  subagent modal used for Claude Code. Existing Codex archives need a full
410
502
  reimport, for example `agentlog import --source codex-desktop --since all`, to
411
503
  gain the child-session links.
504
+ Subagent child sessions remain archived as direct-addressable session records so
505
+ the modal, raw archive, and direct `agentlog show <child-id>` path can load the
506
+ full transcript, but normal history lists, stats, and search hide
507
+ `*_subagent` sessions unless an explicit subagent-inclusive path opts in.
412
508
 
413
509
  The rollout JSONL parser captures readable `response_item` reasoning summaries,
414
510
  Codex `event_msg` assistant/user messages, task and compaction markers, local
@@ -553,6 +649,12 @@ Tool calls and results are normalized into the shared
553
649
  `metadata.toolCalls[]`, `metadata.toolResult`, and `metadata.usage` shapes.
554
650
  Bash or shell tool calls that invoke `apply_patch` are reclassified as edit
555
651
  calls and retain the patch text under `arguments.diff`.
652
+ Claude Code `Edit`/`Write` results also preserve provider `structuredPatch`
653
+ hunks with absolute line starts so the web viewer can render numbered diffs.
654
+ Existing Claude archives need a source reimport to gain this field; run
655
+ `agentlog import --source claude --since all` and repeat for
656
+ `claude-code-desktop`, `claude-cowork`, or `claude-sdk` if those sources are
657
+ enabled.
556
658
  Tool results are matched back to prior `tool_use` ids when possible so result
557
659
  cards inherit the tool name instead of displaying only the raw tool-use id.
558
660
  Remote Control lifecycle records are also converted into provider-generated
@@ -584,7 +686,10 @@ keeps compact run metadata, prompts, result previews, model names, usage totals,
584
686
  and tool counts; the child session carries the full normalized transcript and
585
687
  preserves both the JSONL and any sibling `.meta.json` file in raw storage. The
586
688
  web viewer renders run summaries inline at their transcript timestamps and links
587
- to the child session instead of dumping every subagent run at the top.
689
+ to the child session instead of dumping every subagent run at the top. Child run
690
+ sessions are direct-addressable archive records, but normal history lists,
691
+ stats, and search hide `*_subagent` sessions unless subagents are explicitly
692
+ included.
588
693
 
589
694
  When the Claude desktop app has a matching
590
695
  `~/Library/Application Support/Claude/claude-code-sessions/**/local_*.json`
@@ -649,33 +754,41 @@ when present.
649
754
 
650
755
  Discovery scans the Claude app storage once, but the user-facing source rows are
651
756
  split by kind. `claude-code-desktop` is the Claude Code desktop-launch metadata
652
- path; `claude-workspace` is Claude app local-agent/workspace mode. The older
653
- generic `claude-desktop` aggregate is kept only as a compatibility import
654
- selector and is not shown as a separate discovery row.
757
+ path; `claude-cowork` is Claude app Cowork/local-agent mode. The older
758
+ `claude-workspace` selector is accepted as an alias, and the generic
759
+ `claude-desktop` aggregate is kept only as a compatibility import selector and
760
+ is not shown as a separate discovery row.
655
761
 
656
762
  Working directory attribution comes from `originCwd`, then `cwd`, then the first
657
763
  existing folder in `userSelectedFolders`. If no existing directory is available,
658
764
  the session is archived under `claude-code-desktop/uncategorized` instead of
659
765
  being assigned to whatever repo agentlog happens to run from.
660
766
 
661
- ## Claude Workspace
767
+ ## Claude Cowork
662
768
 
663
- - Import selector: `claude-workspace`
769
+ - Import selector: `claude-cowork` (`claude-workspace` is accepted as a legacy alias)
664
770
  - Provider: `claude_desktop`
665
771
  - Source type: `claude-workspace-desktop`
666
772
  - Primary store:
667
773
  `~/Library/Application Support/Claude/local-agent-mode-sessions/local_*.json`
668
774
  - Audit transcript path:
669
775
  `~/Library/Application Support/Claude/local-agent-mode-sessions/local_<id>/audit.jsonl`
670
- - Fallback scope: `claude-desktop/uncategorized`
776
+ - Fallback scope: `claude-cowork/uncategorized`
671
777
 
672
- Claude Workspace uses the same parser as Claude Code Desktop but reads from the
778
+ Claude Cowork uses the same parser as Claude Code Desktop but reads from the
673
779
  Claude app local-agent mode directory. `audit.jsonl` is preferred when present.
674
- Metadata fallback imports the initial prompt and selected folder context.
780
+ Metadata fallback imports the initial prompt and selected folder context. The
781
+ session-level `model` in the local-agent metadata is recorded as authoritative
782
+ `modelUsage`; audit `tool_use` rows are normalized back to that session model so
783
+ internal tool orchestration does not appear as an extra user-visible model.
675
784
 
676
785
  As with Claude Code Desktop, repo attribution only happens when an existing
677
- working directory can be found. Otherwise the archive is intentionally
678
- uncategorized.
786
+ project directory can be found. Claude's synthetic `/sessions/...` and
787
+ `local-agent-mode-sessions/.../outputs` directories are ignored; selected user
788
+ folders are preferred before falling back to the Cowork uncategorized scope.
789
+ Existing archives with the old `claude-desktop/uncategorized` fallback or
790
+ synthetic cwd attribution should be rebuilt with a full reimport, for example
791
+ `agentlog import --source claude-cowork --since all`.
679
792
 
680
793
  ## Claude.ai Export
681
794
 
@@ -752,41 +865,135 @@ Gemini archives need `agentlog import --source gemini-cli --since all` after
752
865
  this parser bump to populate those titles. When Gemini shutdown interaction
753
866
  summaries appear in structured history, they are parsed into session metadata
754
867
  for tool-call counts, timing, model usage, and resume commands instead of being
755
- inserted into the chat transcript. Markdown
756
- files are split into messages by role headings such as
868
+ inserted into the chat transcript.
869
+
870
+ Gemini CLI subagents stored under
871
+ `~/.gemini/tmp/<project>/chats/<parent-session-id>/<agent-id>.jsonl` are
872
+ imported as child sessions with `conversationKind = "gemini_subagent"` and
873
+ `parentComposerId` set to the parent Gemini session id. Parent `invoke_agent`
874
+ tool calls preserve agent id/name, prompt, status, and progress/result summaries
875
+ when those fields are present, and the parent session gets
876
+ `metadata.sessionSummary.geminiSubagentRuns`. Re-run
877
+ `agentlog import --source gemini-cli --since all` to populate normalized Gemini
878
+ subagent links in existing archives.
879
+
880
+ Markdown files are split into messages by role headings such as
757
881
  `# User`, `# Assistant`, or bold role labels. The working directory comes from
758
882
  parsed cwd fields or Gemini tmp `.project_root` metadata. If no working
759
883
  directory can be resolved, the session is archived under
760
884
  `gemini-cli/uncategorized`.
761
885
 
886
+ ## Antigravity CLI
887
+
888
+ - Import selector: `antigravity-cli`
889
+ - Provider: `antigravity_cli` (separate from the desktop app's `antigravity`)
890
+ - Source types: `antigravity-cli-transcript-log`, `antigravity-cli-brain`
891
+ - Primary transcript store:
892
+ `~/.gemini/antigravity-cli/brain/*/.system_generated/logs/transcript_full.jsonl`
893
+ (untruncated), falling back to `transcript.jsonl` (truncates long tool
894
+ outputs and marks them with `truncated_fields`)
895
+ - Workspace attribution: `~/.gemini/antigravity-cli/history.jsonl` (one
896
+ `{display, timestamp, workspace}` line per user prompt)
897
+ - Binary conversation store preserved but not decoded:
898
+ `~/.gemini/antigravity-cli/conversations/*.pb`
899
+ - Environment overrides: `AGENTLOG_ANTIGRAVITY_CLI_HOME_DIR`
900
+
901
+ The Antigravity CLI (Google's Gemini CLI successor, May 2026) reuses the
902
+ desktop brain/conversations layout under its own home, so the importer reuses
903
+ the whole desktop pipeline with the home redirected and CLI-specific source
904
+ types. Transcript logs do not record the workspace, and deriving cwd from file
905
+ links in responses can land on a subdirectory, so the prompt history file is
906
+ the authoritative cwd source — it is matched by first-user-message text and
907
+ nearest timestamp, and intentionally excluded from sourceFiles because it
908
+ grows with every prompt and would churn session fingerprints. The desktop
909
+ app's Electron state DB is never read for CLI sessions, and CLI/desktop
910
+ conversation ids are distinct UUIDs, so the two sources do not collide.
911
+
912
+ The transcript logs carry no model field or token usage. The only model
913
+ signal is `<USER_SETTINGS_CHANGE>` text injected into USER_INPUT events
914
+ ("The user changed setting \`Model Selection\` from X to Y."); the parser
915
+ tracks these changes, stamps the active model onto subsequent
916
+ PLANNER_RESPONSE messages, and records all observed models in
917
+ `sessionSummary.modelUsage`. This also applies to desktop Antigravity
918
+ transcript logs.
919
+
920
+ ## Antigravity IDE
921
+
922
+ - Import selector: `antigravity-ide`
923
+ - Provider: `antigravity_ide`
924
+ - Source types: `antigravity-ide-transcript-log`, `antigravity-ide-brain`
925
+ - Primary store: `~/.gemini/antigravity-ide/` (same brain/conversations layout
926
+ as the 2.0 app)
927
+ - Environment overrides: `AGENTLOG_ANTIGRAVITY_IDE_HOME_DIR`
928
+
929
+ The Antigravity IDE split off from the 2.0 agent platform but kept the same
930
+ data layout, and its home starts as a migration copy of the 2.0 home. The
931
+ importer therefore drops conversations whose 2.0 copy is byte-identical or at
932
+ least as fresh; the IDE only owns conversations it created or continued after
933
+ the split. IDE session ids are prefixed `antigravity-ide-` because migrated
934
+ conversation ids collide with 2.0's. The IDE's own knowledge/implicit memory
935
+ stores are covered by memory backup under provider `antigravity_ide`.
936
+
762
937
  ## Antigravity
763
938
 
764
939
  - Import selector: `antigravity`
765
940
  - Provider: `antigravity`
766
- - Source types: `antigravity-brain`, `antigravity-trajectory-summary`
767
- - Primary readable store: `~/.gemini/antigravity/brain/*`
941
+ - Source types: `antigravity-transcript-log`, `antigravity-brain`,
942
+ `antigravity-summary-proto`, `antigravity-trajectory-summary`
943
+ - Primary transcript store:
944
+ `~/.gemini/antigravity/brain/*/.system_generated/logs/transcript.jsonl`
945
+ - Legacy readable store: `~/.gemini/antigravity/brain/*`
946
+ - Summary protobuf store: `~/.gemini/antigravity/agyhub_summaries_proto.pb`
768
947
  - Partial metadata store:
769
948
  `Application Support/Antigravity/User/globalStorage/state.vscdb`
770
- - Binary store counted but not decoded:
949
+ - Binary conversation store preserved but not decoded:
771
950
  `~/.gemini/antigravity/conversations/*.pb`
772
951
 
773
- agentlog imports readable Markdown artifacts from each task directory. Recognized
774
- artifact names are `task.md`, `implementation_plan.md`, `walkthrough.md`, and
775
- `plan.md`. Each artifact becomes an assistant message with a heading naming the
776
- artifact. Timestamps come from artifact file mtimes.
777
-
778
- When a conversation has no readable Markdown artifacts, agentlog also imports
779
- Antigravity trajectory summaries from the app's VS Code-style global state DB.
780
- Those summaries preserve the conversation id, visible prompt/title, timestamps,
781
- and workspace path when present. They are marked as partial summaries and do not
782
- claim to be full transcripts. The global state DB is referenced in the raw
783
- manifest but not copied, since it can contain auth-bearing settings.
784
-
785
- The importer tries to infer a working directory from `file://...` links inside
786
- the Markdown artifacts or trajectory summary. If none can be inferred, it
787
- archives under `antigravity/uncategorized`. Binary protobuf transcripts are
788
- counted in discovery details but not imported as conversation messages yet.
789
- Antigravity token usage is therefore not populated from the current local stores.
952
+ agentlog ranks Antigravity sources by fidelity and keeps one archive per
953
+ conversation id: transcript logs first, then readable brain Markdown artifacts,
954
+ then `agyhub_summaries_proto.pb`, then the legacy state DB summary row, then a
955
+ binary-only discovery placeholder if no readable source exists. This keeps the
956
+ v1 archive contract simple while still preserving the lower-fidelity evidence.
957
+
958
+ Transcript logs import user messages, planner responses, system/error/history
959
+ messages, and tool-like step outputs from `.system_generated/logs/transcript.jsonl`.
960
+ Older `.system_generated/logs/overview.txt` files are also discovered; JSONL
961
+ events are parsed when present, and plain overview text is imported as a partial
962
+ assistant summary. Matching `conversations/<id>.pb` files are copied into the
963
+ raw archive manifest for the session, but are not parsed into messages because
964
+ they are not a stable plain protobuf transcript format.
965
+
966
+ When transcript logs contain `INVOKE_SUBAGENT` steps, agentlog links the spawned
967
+ Antigravity conversation id back to the parent. The child transcript is imported
968
+ as a normal direct-addressable session with `conversationKind =
969
+ "antigravity_subagent"` and `parentComposerId` set to the parent conversation
970
+ id, while the parent gets `metadata.sessionSummary.antigravitySubagentRuns`.
971
+ The web viewer displays those runs with the same subagent card/modal path used
972
+ for Claude, Codex, and Cursor child sessions. Default history/search paths hide
973
+ `*_subagent` child sessions unless subagents are explicitly included.
974
+
975
+ Readable Markdown artifacts remain supported as the legacy Antigravity CLI path.
976
+ Recognized artifact names are `task.md`, `implementation_plan.md`,
977
+ `walkthrough.md`, and `plan.md`. Each artifact becomes an assistant message with
978
+ a heading naming the artifact. If a summary protobuf or state DB summary exists
979
+ for the same conversation id, agentlog uses it to fill title, timestamps, and
980
+ workspace metadata while keeping the Markdown artifact as the imported content.
981
+
982
+ `agyhub_summaries_proto.pb` and the VS Code-style global state DB row both
983
+ produce partial summary sessions. They preserve conversation id, visible
984
+ prompt/title, timestamps, step count, and workspace path when present, and are
985
+ marked as partial summaries so they do not claim to be full transcripts. The
986
+ global state DB is referenced in the raw manifest but not copied, since it can
987
+ contain auth-bearing settings.
988
+
989
+ The importer tries to infer a working directory from summary metadata,
990
+ `CWD:` lines, and `file://...` links in Antigravity content. If none can be
991
+ inferred, it archives under `antigravity/uncategorized`. Antigravity token usage
992
+ is not populated from the current local stores.
993
+
994
+ Existing Antigravity archives created before transcript-log and summary-protobuf
995
+ support should be rebuilt with `agentlog import --source antigravity --since all`
996
+ so the archive uses the new source ranking and raw protobuf preservation.
790
997
 
791
998
  ## Devin CLI
792
999
 
@@ -828,6 +1035,53 @@ attribution follows the project directory Devin was launched from.
828
1035
  If `message_nodes` contains no importable messages, agentlog falls back to
829
1036
  `prompt_history` so at least direct user prompts can be archived.
830
1037
 
1038
+ Devin spawns subagents through the `run_subagent` tool (built-in profiles
1039
+ `subagent_explore` / `subagent_general`, plus custom `AGENT.md` profiles).
1040
+ agentlog records each spawn in the parent's
1041
+ `sessionSummary.devinSubagentRuns` with the profile, prompt preview, and
1042
+ foreground/background mode. When the tool arguments expose a child session id
1043
+ that matches another imported Devin session, the child is marked
1044
+ `conversationKind = "devin_subagent"` with `parentComposerId` pointing at the
1045
+ parent, so it collapses out of top-level lists like other `*_subagent`
1046
+ sessions. Spawns without a resolvable child still produce run entries with
1047
+ status `spawned`. Re-run `agentlog import --source devin-cli --since all` to
1048
+ populate links in existing archives.
1049
+
1050
+ ## Devin Desktop
1051
+
1052
+ - Import selector: `devin-desktop`
1053
+ - Provider: `devin`
1054
+ - Source type: `devin-desktop-acp-events`
1055
+ - Event logs on macOS:
1056
+ `~/Library/Application Support/Devin/User/acp-events/*.ndjson`
1057
+ - Metadata/index DB on macOS:
1058
+ `~/Library/Application Support/Devin/User/globalStorage/state.vscdb`
1059
+ - Linux/Windows app roots follow the same VS Code/Electron layout under
1060
+ `~/.config/Devin` or `%APPDATA%\Devin`.
1061
+ - Overrides:
1062
+ - `AGENTLOG_DEVIN_DESKTOP_APP_SUPPORT_DIR` points at an alternate Devin app
1063
+ support root.
1064
+ - `AGENTLOG_DEVIN_DESKTOP_ACP_EVENTS_DIR` points directly at an ACP event log
1065
+ directory.
1066
+ - `AGENTLOG_DEVIN_DESKTOP_GLOBAL_STORAGE_DB` points at one explicit
1067
+ `state.vscdb`.
1068
+
1069
+ Devin Desktop writes ACP session event logs as UUID-named NDJSON files and keeps
1070
+ the session id to UUID mapping in `ItemTable['windsurf.acp.eventLog.index']`.
1071
+ The key prefix is inherited from Windsurf, but agentlog treats this as a Devin
1072
+ Desktop source and imports only `acp/devin-cli/*` and `acp/devin-cloud/*`
1073
+ sessions under provider `devin`. Cascade/Windsurf history remains the separate
1074
+ `windsurf` source.
1075
+
1076
+ The importer joins streamed `user_message_chunk`, `agent_message_chunk`, and
1077
+ `agent_thought_chunk` rows. Devin thinking is preserved as supplementary
1078
+ assistant messages with `summaryKind=thinking`. ACP `tool_call` and
1079
+ `tool_call_update` rows are normalized into `metadata.toolCalls[]` and
1080
+ `metadata.toolResult`, and `usage_update` rows are aggregated into
1081
+ `sessionSummary.usage` for stats. The global state DB is used as an index but is
1082
+ recorded as a raw reference rather than copied into every session raw folder
1083
+ because it can contain auth/session material.
1084
+
831
1085
  ## Cursor
832
1086
 
833
1087
  - Import selector: `cursor`
@@ -980,12 +1234,31 @@ for `tool_calls`, `toolCalls`, `toolResults`, command outputs, edit records,
980
1234
  diff records, model/status/request metadata, and token usage. When no
981
1235
  per-message timestamp exists, it uses the source file's mtime with stable
982
1236
  millisecond offsets so imports do not get stamped with the time of import.
1237
+ Transcript folders under
1238
+ `agent-transcripts/<parent-composer-id>/subagents/<subagent-id>` are imported as
1239
+ child sessions with `conversationKind = "cursor_subagent"` and
1240
+ `parentComposerId` set to the parent composer id. When the parent transcript is
1241
+ available in the same import, agentlog also attaches compact run metadata to the
1242
+ parent as `metadata.sessionSummary.cursorSubagentRuns`, and the web viewer shows
1243
+ those runs inline with a link to the child transcript. Existing Cursor transcript
1244
+ archives need a full reimport, for example
1245
+ `agentlog import --source cursor --since all`, to gain the normalized subagent
1246
+ metadata. As with Codex and Claude Code child runs, those child session records
1247
+ are direct-addressable but hidden from normal history lists, stats, and search
1248
+ unless subagents are explicitly included.
983
1249
 
984
1250
  Cursor project slugs are decoded back to local paths when possible. For example,
985
1251
  `Users-alex-Documents-GitHub-spring-next` resolves to
986
- `/Users/alex/Documents/GitHub/spring-next` if that directory exists. If no
987
- working directory can be resolved for a newer transcript, it archives under
988
- `cursor/uncategorized` instead of assigning the session to the current repo.
1252
+ `/Users/alex/Documents/GitHub/spring-next` if that directory exists. Newer
1253
+ agent-transcript imports prefer explicit paths in the transcript itself (tool
1254
+ arguments, command text, and nested metadata) before falling back to that slug,
1255
+ so a transcript stored under a stale Cursor project directory can still be
1256
+ attributed to the repository it actually read or edited. Existing Cursor
1257
+ transcript archives with stale project-slug attribution need a full reimport,
1258
+ for example `agentlog import --source cursor --since all`, to regenerate their
1259
+ metadata and archive location. If no working directory can be resolved for a
1260
+ newer transcript, it archives under `cursor/uncategorized` instead of assigning
1261
+ the session to the current repo.
989
1262
 
990
1263
  ## Cline
991
1264
 
@@ -1022,6 +1295,19 @@ supplementary assistant event. Those tool calls carry unified diff text or
1022
1295
  old/new string payloads so the web viewer can render the edits inline while the
1023
1296
  original checkpoint files remain in raw backups.
1024
1297
 
1298
+ Cline spawn linking distinguishes two tool shapes. Explicit subagent tools
1299
+ (`subagent`, `run_subagent`, `spawn_subagent`) mark the spawned task as
1300
+ `conversationKind = "cline_subagent"` with `parentComposerId` set to the
1301
+ parent task id. The `new_task` tool is a context handoff: the new task replaces
1302
+ the old one rather than running under it, so the child stays a top-level
1303
+ session but is still linked to the parent (`parentComposerId` plus
1304
+ `sessionSummary.clineSpawnedBy`) and listed in the parent's
1305
+ `sessionSummary.clineSubagentRuns`. Children are resolved by explicit task id
1306
+ when the arguments carry one, else by matching the handoff context against the
1307
+ child task's first user message inside a 30-minute window, else by an
1308
+ unambiguous single task started within a few minutes of the call. Ambiguous
1309
+ spawns produce run entries with status `spawned` and no link.
1310
+
1025
1311
  ## OpenCode
1026
1312
 
1027
1313
  - Import selectors: `opencode-cli`, `opencode-desktop`, `opencode-web`, or `opencode` for all three
@@ -1079,6 +1365,15 @@ preservation keeps the original database byte-for-byte. Because the database is
1079
1365
  multi-session source, raw preservation stores it as a shared raw source instead
1080
1366
  of duplicating the same file into every session archive.
1081
1367
 
1368
+ OpenCode subagent sessions are linked from the structured `session.parent_id`
1369
+ field. Child sessions are imported as `conversationKind = "opencode_subagent"`
1370
+ with `parentComposerId` set to the raw OpenCode parent session id, and the parent
1371
+ gets `metadata.sessionSummary.opencodeSubagentRuns`. Task-tool metadata such as
1372
+ `subagent_type`, `prompt`, `description`, and child `sessionId` is preserved when
1373
+ present so the web viewer can show the same subagent run cards used for other
1374
+ providers. Existing OpenCode archives should be rebuilt with `agentlog import
1375
+ --source opencode --since all` to populate normalized subagent links.
1376
+
1082
1377
  agentlog also reads OpenCode's JSON session store directly. Sessions provide the
1083
1378
  archive id and project id; message and part files provide role text, reasoning
1084
1379
  text, tool calls, and tool outputs. Tool parts are normalized into
@@ -1099,6 +1394,106 @@ When `session_diff/<session-id>.json` is present, agentlog adds a supplementary
1099
1394
  edit tool call with the diff payload. Unified diff text is rendered inline in
1100
1395
  the history web UI, and the original diff JSON remains in the raw archive.
1101
1396
 
1397
+ ## GitHub Copilot CLI
1398
+
1399
+ - Import selector: `copilot-cli`
1400
+ - Provider: `copilot`
1401
+ - Source type: `copilot-cli-history`
1402
+ - Primary store: `~/.copilot/session-state/<session-uuid>/events.jsonl`
1403
+ - Metadata sidecar: `workspace.yaml` (flat scalars: id, name, cwd, git_root,
1404
+ repository, branch, created_at, updated_at); `plan.md` preserved as a source
1405
+ file when present
1406
+ - Environment overrides: `AGENTLOG_COPILOT_SESSION_STATE_DIR`,
1407
+ `AGENTLOG_COPILOT_HOME`, `COPILOT_HOME`
1408
+
1409
+ Each events.jsonl line is `{type, data, id, timestamp, parentId}`. agentlog maps
1410
+ `user.message`/`assistant.message` to messages, `tool.execution_start` to
1411
+ assistant tool calls (arguments may arrive as a JSON string and are re-parsed),
1412
+ `tool.execution_complete` to tool results, and `session.model_change`,
1413
+ `session.compaction_complete`, and `subagent.started/completed` to system
1414
+ messages. Session-level usage comes from the `session.shutdown` event, which is
1415
+ only written for cleanly ended sessions on CLI 0.0.422+: per-model
1416
+ `modelMetrics` token splits are aggregated into `sessionSummary.usage` and
1417
+ `modelUsage`, with premium requests, AI credits (`totalNanoAiu` / 1e9), code
1418
+ change counters, and `session.task_complete` summaries recorded under
1419
+ `sessionSummary.copilotCli`. The `session-store.db` SQLite database is a
1420
+ rebuildable index of the same data and is not read. Older
1421
+ `~/.copilot/history-session-state/` legacy sessions are not imported.
1422
+
1423
+ ## Factory Droid
1424
+
1425
+ - Import selector: `factory`
1426
+ - Provider: `factory`
1427
+ - Source type: `factory-droid-history`
1428
+ - Primary store: `~/.factory/sessions/<cwd-slug>/<session-uuid>.jsonl`, plus the
1429
+ legacy flat layout `~/.factory/sessions/<session-uuid>.jsonl`
1430
+ - Metadata sidecar: `<session-uuid>.settings.json`
1431
+ - Environment overrides: `AGENTLOG_FACTORY_SESSIONS_DIR`, `FACTORY_HOME_OVERRIDE`
1432
+
1433
+ Transcripts require a `session_start` header line carrying id, title, owner, and
1434
+ cwd. `message` lines wrap Anthropic-style content blocks: text, thinking
1435
+ (stored as `metadata.thinking`), tool_use (assistant tool calls), and
1436
+ tool_result (tool messages). Block keys drift between snake_case and camelCase
1437
+ across droid versions (`tool_use_id` vs `toolUseId`), and both are accepted.
1438
+ File-op tool results that carry `diffLines` with per-line old/new line numbers
1439
+ are converted to `structuredPatch` hunks. `todo_state` lines and unknown types
1440
+ are skipped. The same session id can exist in both legacy and per-project
1441
+ layouts after migration; the newer file by mtime wins. There is no per-message
1442
+ token usage on disk — the sidecar's aggregate `tokenUsage` becomes
1443
+ `sessionSummary.usage`, with model (BYOK `custom:`/`[Provider]` wrappers
1444
+ stripped for `modelUsage`), reasoning effort, autonomy mode, Factory credits,
1445
+ archive state, and subagent attribution (`decompSessionType`,
1446
+ `callingSessionId`, `childInclusiveTokenUsageBySessionId`) recorded under
1447
+ `sessionSummary.factoryDroid`.
1448
+
1449
+ ## Grok Build
1450
+
1451
+ - Import selector: `grok-build`
1452
+ - Provider: `grok`
1453
+ - Source type: `grok-build-history`
1454
+ - Primary store: `~/.grok/sessions/<percent-encoded-cwd>/<session-id>/updates.jsonl`
1455
+ - Metadata sidecars: `summary.json`, `signals.json`; `events.jsonl` and
1456
+ `plan.md` preserved as source files when present
1457
+ - Environment overrides: `AGENTLOG_GROK_SESSIONS_DIR`, `AGENTLOG_GROK_HOME`,
1458
+ `GROK_HOME`
1459
+
1460
+ updates.jsonl lines are ACP (Agent Client Protocol) JSON-RPC `session/update`
1461
+ notifications. Streaming chunks (`user_message_chunk`, `agent_message_chunk`,
1462
+ `agent_thought_chunk`) are concatenated into whole messages; `tool_call`
1463
+ becomes an assistant tool call and `tool_call_update` with completed/failed
1464
+ status becomes a tool result; `plan` and `current_mode_update` become system
1465
+ messages. The cwd comes from percent-decoding the parent directory name. Token
1466
+ telemetry is a cumulative `_meta.totalTokens` counter that can rewind during
1467
+ streaming, so the maximum observed value is recorded as an authoritative
1468
+ session total. `signals.json` rollups (turn count, context tokens, models used,
1469
+ session duration) land under `sessionSummary.grokBuild`. The old unofficial
1470
+ superagent grok-cli also uses `~/.grok` but stores transcripts in
1471
+ `~/.grok/grok.db` SQLite; it is a different product and is not imported.
1472
+
1473
+ ## pi
1474
+
1475
+ - Import selector: `pi`
1476
+ - Provider: `pi`
1477
+ - Source type: `pi-cli-history`
1478
+ - Primary store: `~/.pi/agent/sessions/--<encoded-cwd>--/<timestamp>_<session-id>.jsonl`
1479
+ - Environment overrides: `AGENTLOG_PI_SESSION_DIR`,
1480
+ `PI_CODING_AGENT_SESSION_DIR`, `PI_CODING_AGENT_DIR`
1481
+
1482
+ pi session files start with a `session` header line (id, timestamp, cwd; v1
1483
+ headers also carry provider/modelId, v3 adds `parentSession` fork lineage).
1484
+ Entries form a tree via `id`/`parentId`; agentlog imports all entries in file
1485
+ order, including abandoned branches, and preserves the ids as
1486
+ `providerMessageId`/`parentMessageId`. Assistant messages carry per-message
1487
+ usage with token splits and dollar cost (`usage.cost.total` →
1488
+ `metadata.usage.costUsd`); `toolResult` messages become tool messages;
1489
+ `bashExecution` (`!` commands) become a user message plus a shell tool result
1490
+ with exit code. `model_change`, `thinking_level_change`, `compaction`,
1491
+ `branch_summary`, and `custom_message` entries become system messages;
1492
+ `custom` extension state and `label` entries are skipped. Note that custom
1493
+ `--session-dir` configurations store files flat rather than in per-cwd
1494
+ subdirectories; both layouts are scanned. The oh-my-pi fork uses `~/.omp` with
1495
+ a diverged schema and is not covered by this importer.
1496
+
1102
1497
  ## Aider
1103
1498
 
1104
1499
  - Import selector: `aider`
@@ -1135,18 +1530,39 @@ backups.
1135
1530
 
1136
1531
  - Import selector: `windsurf`
1137
1532
  - Provider: `windsurf`
1138
- - Source types: `windsurf-trajectory-export`, `windsurf-cascade-brain`
1533
+ - Source types: `windsurf-trajectory-export`, `windsurf-cascade-brain`,
1534
+ `windsurf-cascade-protobuf`
1139
1535
  - Explicit export import: `agentlog import windsurf <downloaded-trajectory.md>`
1140
1536
  or `agentlog import windsurf <folder-of-trajectories>`
1537
+ - Repair-stub import: `agentlog import windsurf --claim <token>
1538
+ <downloaded-trajectory.md>`
1141
1539
  - Primary readable store: `~/.codeium/windsurf/brain/*`
1142
- - Binary store counted but not decoded: `~/.codeium/windsurf/cascade/*.pb`
1143
- - Status: encrypted local cache scanning is disabled from setup, default imports,
1144
- and history filters; downloaded trajectory Markdown exports are importable
1145
-
1146
- Windsurf local cache scanning is currently disabled. Current Cascade sessions
1147
- are written as encrypted binary stores, so agentlog can detect session IDs and
1148
- workspace metadata but cannot archive readable conversation text from those
1149
- local files.
1540
+ - Binary store preserved/counted but not decoded:
1541
+ `~/.codeium/windsurf/cascade/*.pb`
1542
+ - Metadata cache: Windsurf global state `ItemTable['windsurf.acp.metadataCache']`
1543
+ in `~/Library/Application Support/Windsurf/User/globalStorage/state.vscdb`
1544
+ and backups
1545
+ - Environment overrides: `AGENTLOG_WINDSURF_HOME_DIR`,
1546
+ `AGENTLOG_CODEIUM_HOME_DIR`, `AGENTLOG_WINDSURF_BRAIN_DIR`,
1547
+ `AGENTLOG_WINDSURF_CASCADE_DIR`, `AGENTLOG_WINDSURF_GLOBAL_STORAGE_DB`,
1548
+ `AGENTLOG_WINDSURF_APP_SUPPORT_DIR`
1549
+
1550
+ Windsurf local imports are partial. Current Cascade sessions keep the full
1551
+ conversation body in high-entropy binary protobuf files, so agentlog preserves
1552
+ matching `cascade/<conversation-id>.pb` files as raw sources but does not decode
1553
+ them into transcript messages. When `brain/<conversation-id>/plan.md`,
1554
+ `task.md`, `implementation_plan.md`, or `walkthrough.md` exists, each readable
1555
+ artifact is archived as an assistant message and the matching metadata/pb files
1556
+ are preserved in the session raw folder.
1557
+
1558
+ Agentlog also reads Windsurf's ACP metadata cache from global storage to attach
1559
+ titles, working directories, created timestamps, and updated timestamps to local
1560
+ Cascade session IDs. Protobuf-only conversations are archived as zero-message
1561
+ repair stubs when there is no readable brain artifact. The stubs preserve the
1562
+ raw `.pb`, show up in the web viewer with a deterministic `ws-...` repair token,
1563
+ and produce no canonical events, so normal history search and MCP recall do not
1564
+ index them as transcript content. The state DB is referenced in raw metadata but
1565
+ not copied because it can contain auth tokens.
1150
1566
 
1151
1567
  Windsurf's "Download trajectory" action produces Markdown headed
1152
1568
  `# Cascade Chat Conversation`. Agentlog imports those files explicitly with
@@ -1155,21 +1571,31 @@ provider transcript surface: `### User Input` sections become user messages,
1155
1571
  `### Planner Response` / assistant-like sections become assistant messages, and
1156
1572
  the original Markdown file is preserved in raw backups.
1157
1573
 
1574
+ When a web-viewer repair stub corresponds to the export, copy its token and run
1575
+ `agentlog import windsurf --claim <token> <downloaded-trajectory.md>`. Claimed
1576
+ imports replace the zero-message stub with the full Markdown transcript under
1577
+ the same `windsurf-<conversation-id>` archive id.
1578
+
1158
1579
  Bulk export tools that automate Windsurf's hidden "Download trajectory" button
1159
1580
  can write many `*.md` files into one directory. Agentlog intentionally treats
1160
- that directory as user-selected export input rather than scanning Windsurf's
1161
- encrypted cache: run `agentlog import windsurf ~/windsurf-cascade-export` after
1162
- the bulk exporter finishes.
1581
+ that directory as user-selected export input rather than local cache recovery:
1582
+ run `agentlog import windsurf ~/windsurf-cascade-export` after the bulk exporter
1583
+ finishes.
1163
1584
 
1164
- The older experimental helper can still read Markdown artifacts from Windsurf
1165
- Cascade brain directories when present. Recognized artifact names are `plan.md`,
1166
- `task.md`, `implementation_plan.md`, and `walkthrough.md`. Each artifact becomes
1167
- an assistant message with a heading naming the artifact. Timestamps come from
1168
- file mtimes.
1585
+ The local importer reads Markdown artifacts from Windsurf Cascade brain
1586
+ directories when present. Recognized artifact names are `plan.md`, `task.md`,
1587
+ `implementation_plan.md`, and `walkthrough.md`. Each artifact becomes an
1588
+ assistant message with a heading naming the artifact. Timestamps come from file
1589
+ mtimes.
1169
1590
 
1170
1591
  The importer tries to infer a working directory from `file://...` links in the
1171
1592
  Markdown. If none can be inferred, it archives under `windsurf/uncategorized`.
1172
- Binary Cascade protobuf stores are counted in discovery details but not decoded.
1593
+ Binary Cascade protobuf stores are counted in discovery details and preserved
1594
+ when they match an imported brain artifact or a repair stub, but not decoded. If
1595
+ import warnings name partial Windsurf conversations, use Download trajectory for
1596
+ a stable full transcript, or reopen the conversation in Windsurf and send
1597
+ `/recall` or a short message if a newer Windsurf build starts writing readable
1598
+ artifacts, then rerun `agentlog import --source windsurf --since all`.
1173
1599
 
1174
1600
  ## Collector And Live Monitoring
1175
1601
 
@@ -1195,8 +1621,13 @@ as importing transcript history.
1195
1621
 
1196
1622
  - ChatGPT and Claude.ai are import-by-export only; agentlog does not read their
1197
1623
  desktop app local stores.
1198
- - Windsurf encrypted cache scanning is disabled; downloaded trajectory Markdown
1199
- exports are supported.
1624
+ - Windsurf local imports are partial; downloaded trajectory Markdown exports are
1625
+ the supported path for stable full Cascade transcripts.
1626
+ - Windsurf has no subagent linking: Cascade conversation bodies are undecoded
1627
+ protobufs and the ACP metadata cache exposes no parent/child or spawn fields,
1628
+ so there is nothing to parse into `windsurf_subagent` sessions today. The
1629
+ viewer accepts `sessionSummary.windsurfSubagentRuns` so runs render if a
1630
+ future Windsurf build exposes spawn metadata.
1200
1631
  - Antigravity protobuf transcripts are counted but not decoded.
1201
1632
  - Cursor older `state.vscdb` stores are best-effort because Cursor has changed
1202
1633
  local storage layouts over time.