agentel 0.2.4 → 0.2.6

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.
package/README.md CHANGED
@@ -9,8 +9,8 @@ Core capabilities:
9
9
  - markdown-primary, redacted local archive under `~/.agentlog/data/agentlog/`
10
10
  - canonical event JSONL alongside each transcript for provider-independent search
11
11
  - canonical repo keying from git remotes, first commits, or path hashes
12
- - Codex CLI, Codex Desktop, ChatGPT export, Claude Code CLI, Claude Code
13
- Desktop, Claude Workspace, Claude.ai export, Gemini CLI, Antigravity,
12
+ - Codex CLI, Codex Desktop, Codex SDK jobs, ChatGPT export, Claude Code CLI,
13
+ Claude Code Desktop, Claude Workspace, Claude.ai export, Gemini CLI, Antigravity,
14
14
  Devin CLI, and Cursor imports
15
15
  - event-first `agentlog history` search with markdown/transcript fallback
16
16
  - `agentlog-recall` MCP stdio server exposing `search_past_sessions`
@@ -41,7 +41,7 @@ ref for repeatable installs:
41
41
  ```sh
42
42
  npm install -g brianlzhou/agentlog
43
43
  # or
44
- npm install -g brianlzhou/agentlog#v0.2.4
44
+ npm install -g brianlzhou/agentlog#v0.2.6
45
45
  agentlog init
46
46
  ```
47
47
 
@@ -77,6 +77,8 @@ npm test
77
77
  AGENTLOG_HOME=/tmp/agentlog-demo node ./bin/agentlog.js init --yes --skip-import --no-autostart --no-claude --no-recall --no-telemetry
78
78
  AGENTLOG_HOME=/tmp/agentlog-demo node ./bin/agentlog.js import --source codex-cli --since 30d
79
79
  AGENTLOG_HOME=/tmp/agentlog-demo node ./bin/agentlog.js import --source codex-desktop --since all
80
+ AGENTLOG_HOME=/tmp/agentlog-demo node ./bin/agentlog.js import chatgpt
81
+ AGENTLOG_HOME=/tmp/agentlog-demo node ./bin/agentlog.js import claude-web
80
82
  AGENTLOG_HOME=/tmp/agentlog-demo node ./bin/agentlog.js import chatgpt ~/Downloads/chatgpt-export.zip --username you@example.com
81
83
  AGENTLOG_HOME=/tmp/agentlog-demo node ./bin/agentlog.js import claude-web ~/Downloads/claude-export --username you --display-name "Personal Claude"
82
84
  AGENTLOG_HOME=/tmp/agentlog-demo node ./bin/agentlog.js import --source claude --since 30d
@@ -219,7 +221,7 @@ build step. Archives still keep stable `path:<hash>` keys for folders without
219
221
  git identity, but the UI displays the local path.
220
222
 
221
223
  Provider filters use one stable order: OpenAI (`codex-cli`, `codex-desktop`,
222
- `chatgpt`), Anthropic (`claude`, `claude-code-desktop`, `claude-workspace`,
224
+ `codex-sdk`, `chatgpt`), Anthropic (`claude`, `claude-code-desktop`, `claude-workspace`,
223
225
  `claude-web`, `claude-sdk`), Google (`gemini-cli`, `antigravity`), Cognition
224
226
  (`devin-cli`), then other local tools (`cursor`, `cline`, `opencode`,
225
227
  `aider`).
@@ -234,7 +236,7 @@ still run `agentlog import --source all` for a one-time catch-up,
234
236
  `agentlog watcher login enable` later. The default
235
237
  watcher choices are Codex CLI, Codex Desktop, Claude Code CLI, Claude Code
236
238
  Desktop, Claude Workspace, Gemini CLI, Antigravity, Devin CLI, Cursor, Cline,
237
- OpenCode, and Aider. New configs still support
239
+ OpenCode CLI, OpenCode Desktop, OpenCode Web, and Aider. New configs still support
238
240
  `imports.autoDiscoverSources=true`, but init records the chosen watcher list
239
241
  exactly by setting `imports.autoDiscoverSources=false`.
240
242
  Cursor raw SQLite recovery is intentionally left to explicit imports such as
@@ -363,22 +365,28 @@ For large multi-session stores such as Cursor SQLite, the per-session raw
363
365
  manifest may reference one shared copy under `raw-sources/` instead of copying
364
366
  the same database into every session folder.
365
367
 
366
- `events.jsonl` uses the local `agentlog.events.v1` canonical event shape:
368
+ `events.jsonl` uses the local `agentlog.events.v2` canonical event shape:
367
369
  `session.started`, `prompt.submitted`, `response.generated`, `tool.called`, and
368
- `tool.completed`. Parser versions are stamped by source type so importer output
369
- changes can trigger reimport with a new fingerprint. Recall/search builds a
370
- keyword index over event text first and falls back to transcript/markdown for
371
- legacy archives without events. The local search index stores compact term
372
- postings for CLI compatibility plus a SQLite FTS5 sidecar for fast web
373
- queries; when either index format changes, `agentlog history` and `agentlog
374
- index` rebuild it from archived transcripts/events without a full source
370
+ `tool.completed`; completed tool events link back to the matching call when the
371
+ source exposes stable ids or matching names. Parser versions are stamped by
372
+ source type so importer output changes can trigger reimport with a new
373
+ fingerprint. Recall/search builds a keyword index over event text first and
374
+ falls back to transcript/markdown for legacy archives without events. The local
375
+ search index stores compact term postings for CLI compatibility plus a SQLite
376
+ FTS5 sidecar for fast web queries; when either index format changes,
377
+ `agentlog history` and `agentlog index` rebuild it from archived
378
+ transcripts/events without a full source
375
379
  reimport. The web viewer avoids doing that rebuild on a keystroke so a large
376
380
  old index, or a full-archive Markdown fallback, cannot block interactive
377
381
  search.
378
382
 
379
383
  Stats are import-time metadata, not viewer-time transcript repair. Archive
380
384
  metadata stores message counts, user-message counts, token usage, and models for
381
- each session, and the web stats view reads those fields directly. Cursor sessions
385
+ each session, and the web stats view reads those fields directly. Codex SDK and
386
+ Claude SDK batch jobs are kept out of primary activity totals, streaks, folder
387
+ rankings, and provider/model charts; the stats payload and web view expose them
388
+ as a separate SDK jobs section so high-volume automation does not drown out
389
+ interactive work. Cursor sessions
382
390
  without provider-reported token usage can also carry separately labeled
383
391
  `estimatedUsage`, which the stats view includes while reporting estimated token
384
392
  coverage. ChatGPT and Claude.ai exports without provider usage get estimated
@@ -388,10 +396,12 @@ parts. During pre-v1 development, if those stats fields or parser semantics
388
396
  change, rebuild the local archive with
389
397
  `agentlog update --yes --since all`.
390
398
 
391
- ChatGPT and Claude.ai web exports are imported manually from an official `.zip`,
392
- an unzipped export folder, or a direct JSON file. These imports are stored as
393
- local scoped web-chat archives and displayed through virtual conversation roots
394
- such as `[chatgpt]conversations/<account-id>` and
399
+ ChatGPT and Claude.ai are manual export providers. Run `agentlog import chatgpt`
400
+ or `agentlog import claude-web` for current export instructions; after the
401
+ provider emails a download link, pass the official `.zip`, unzipped export
402
+ folder, or direct JSON file back to agentlog. These imports are stored as local
403
+ scoped web-chat archives and displayed through virtual conversation roots such
404
+ as `[chatgpt]conversations/<account-id>` and
395
405
  `[claude]conversations/<account-id>/<project>`. The importer records account
396
406
  metadata in `~/.agentlog/state/web-accounts.json`; use
397
407
  `agentlog import accounts list` to inspect mappings and
@@ -471,15 +481,15 @@ local stores.
471
481
  After discovery, init offers a checkbox-style source picker. Rows marked `[x]`
472
482
  are selected; type one or more row numbers, such as `1 3 8`, to toggle sources
473
483
  on or off, then press Enter with no input to accept the current selection.
474
- Claude SDK jobs are shown as a separate opt-in source because batch SDK traffic
475
- can exceed interactive sessions. The selected sources are saved in config and
476
- used by later `agentlog import --source all` runs unless `--sources` is provided
477
- explicitly.
484
+ Codex SDK jobs and Claude SDK jobs are shown as separate opt-in sources because
485
+ batch SDK traffic can exceed interactive sessions. The selected sources are
486
+ saved in config and used by later `agentlog import --source all` runs unless
487
+ `--sources` is provided explicitly.
478
488
 
479
489
  Default init sources:
480
490
 
481
491
  - Codex CLI sessions and Codex Desktop sessions from Codex state, shown as
482
- separate toggles
492
+ separate toggles; Codex SDK jobs are available as an opt-in batch source
483
493
  - Claude Code CLI transcripts from `~/.claude/projects`
484
494
  - Claude Code Desktop metadata and Claude Workspace/local-agent sessions from
485
495
  the Claude app data, shown as separate toggles
@@ -493,7 +503,7 @@ Default init sources:
493
503
  to same-project workspace sessions, duplicate prefix pruning, and newer
494
504
  `~/.cursor/projects/<project>/agent-transcripts` files
495
505
  - Cline task folders from VS Code/JetBrains globalStorage, including checkpoint diffs when present
496
- - OpenCode JSON session/message/part storage under `~/.local/share/opencode`
506
+ - OpenCode CLI/core SQLite and project JSON storage under `~/.local/share/opencode`, plus OpenCode Desktop app storage and Web sessions when present
497
507
  - Aider repo-local `.aider.chat.history.md` transcripts, with `.aider.llm.history`
498
508
  model/usage enrichment, `.aider.input.history` backups, and matching auto-commit diffs
499
509
 
@@ -528,9 +538,12 @@ The same choices can be run directly:
528
538
 
529
539
  ```sh
530
540
  agentlog import --source all --since all
531
- agentlog import --sources codex-cli,codex-desktop,claude,claude-code-desktop,claude-workspace,gemini-cli,antigravity,devin-cli,cursor,cline,opencode,aider --since all
541
+ agentlog import --sources codex-cli,codex-desktop,claude,claude-code-desktop,claude-workspace,gemini-cli,antigravity,devin-cli,cursor,cline,opencode-cli,opencode-desktop,opencode-web,aider --since all
532
542
  agentlog import --source codex-desktop --since 90d
533
543
  agentlog import --source codex-cli --since 30d
544
+ agentlog import --source codex-sdk --since all
545
+ agentlog import chatgpt
546
+ agentlog import claude-web
534
547
  agentlog import chatgpt ~/Downloads/chatgpt-export.zip --username you@example.com
535
548
  agentlog import claude-web ~/Downloads/claude-export --username you --display-name "Personal Claude"
536
549
  agentlog import --source claude --since 30d
@@ -99,11 +99,12 @@ low-signal filtering.
99
99
  Exports:
100
100
 
101
101
  - `CANONICAL_EVENT_SCHEMA_VERSION`: current event schema id,
102
- `agentlog.events.v1`.
102
+ `agentlog.events.v2`.
103
103
  - `EVENT_KINDS`: constants for `session.started`, `prompt.submitted`,
104
104
  `response.generated`, `tool.called`, and `tool.completed`.
105
105
  - `normalizeSessionEvents(session, messages, options)`: maps transcript
106
- messages into canonical events.
106
+ messages into canonical events and links `tool.completed` events to matching
107
+ `tool.called` parents.
107
108
  - `messageToCanonicalEvents(message, session, options)`: maps one message into
108
109
  zero or more canonical events.
109
110
  - `stableEventId(sessionId, messageIndex, kind, ordinal, content)`: creates a
@@ -219,7 +220,9 @@ Command handlers:
219
220
  - `integrationsCommand(args, env)`: canonical integration command group for
220
221
  recall surfaces.
221
222
  - `mcpCommand(args, flags, env)`: canonical MCP server command group.
222
- - `importCommand(args, flags, env)`: imports local sources or web export files.
223
+ - `importCommand(args, flags, env)`: imports local sources and downloaded web
224
+ export files, or prints manual ChatGPT/Claude.ai export instructions when no
225
+ web export path is supplied.
223
226
  - `recallCommand(args, env)`: handles recall server/install/show/reindex flows.
224
227
  - `showRecallSession(sessionId, env)`: prints a session through the recall path.
225
228
  - `showCommand(sessionId, flags, env)`: prints, opens, or JSON-serializes a
@@ -555,9 +558,9 @@ Import dispatch and generic providers:
555
558
  Desktop/Workspace metadata and audit sessions.
556
559
  - `matchesImportedSessionRepo(session, repo, wantedRepos)`: checks repo filters
557
560
  for sessions with repo or scope attribution.
558
- - `importCodexProvider(provider, since, options, env)`: imports Codex CLI or
559
- Desktop threads from state DB, rollout files, and Codex supplementary
560
- summaries when available.
561
+ - `importCodexProvider(provider, since, options, env)`: imports Codex CLI,
562
+ Desktop, or opt-in exec/SDK threads from state DB, rollout files, and Codex
563
+ supplementary summaries when available.
561
564
  - `importCursorProvider(provider, since, options, env)`: imports Cursor SQLite
562
565
  and Cursor project transcript sessions; supervisor calls set
563
566
  `cursorRecovery=false` to skip raw SQLite salvage/backfill.
@@ -581,7 +584,10 @@ Generic parsing helpers:
581
584
  shapes.
582
585
  - `extractClaudeMessagesFromEvent(event, provider, context)`: Claude Code/SDK
583
586
  JSONL parser for text, thinking, tool calls/results, model, request id, and
584
- usage metadata, including `apply_patch` shell calls promoted to edit diffs.
587
+ usage metadata, including lineage fields, agent/slug/tool-use ids, MCP
588
+ structured content, API error metadata, richer Claude usage extras, Remote
589
+ Control lifecycle context messages, tool result name repair from prior
590
+ `tool_use` ids, and `apply_patch` shell calls promoted to edit diffs.
585
591
  - `updateClaudeParseContext(event, provider, context)`: keeps Claude model,
586
592
  session, and cwd context while parsing JSONL records.
587
593
  - `extractCodexSummaryMessage(event, provider)`: extracts readable Codex
@@ -599,6 +605,8 @@ Generic parsing helpers:
599
605
  summary for tool-call metadata.
600
606
  - `normalizeWebConversations(provider, data)`: normalizes web export
601
607
  conversations.
608
+ - `webExportInstructions(source)`: returns the provider-specific manual export
609
+ instruction payload used by ChatGPT and Claude.ai import commands.
602
610
  - `chatgptMessages(conversation)`: parses ChatGPT export conversation nodes
603
611
  and attaches provider or estimated message usage.
604
612
  - `claudeMessages(conversation)`: parses Claude.ai export messages, separating
@@ -610,8 +618,8 @@ Discovery and summary helpers:
610
618
 
611
619
  - `summarizeFiles(files)`: counts files, projects, and oldest mtime.
612
620
  - `summarizeCodex(env, source)`: summary wrapper for Codex threads.
613
- - `summarizeCodexThreads(allThreads, source)`: summarizes Codex CLI/Desktop
614
- counts.
621
+ - `summarizeCodexThreads(allThreads, source)`: summarizes Codex CLI/Desktop or
622
+ opt-in exec/SDK counts.
615
623
  - `summarizeClaude()`: summarizes Claude Code CLI files.
616
624
  - `summarizeClaudeScan(scan)`: formats Claude scan results.
617
625
  - `summarizeClaudeSdk()`: summarizes Claude SDK job files.
@@ -643,7 +651,8 @@ Source location and file helpers:
643
651
  - `scanClaudeProjectFiles(options)`: scans and classifies Claude project JSONL.
644
652
  - `isClaudeConversationFile(file)`: tests whether a Claude file is interactive.
645
653
  - `classifyClaudeFile(file)`: classifies Claude JSONL as conversation, SDK job,
646
- or other.
654
+ or other; Remote Control `sdk-cli` transcripts with Remote Control deferred
655
+ tool names are kept with interactive Claude Code conversations.
647
656
  - `readInitialLines(file, maxLines, maxBytes)`: reads a bounded prefix of a
648
657
  large JSONL file.
649
658
  - `readCodexThreads(env)`: queries Codex state DB for top-level threads and
@@ -790,13 +799,13 @@ Cline helpers:
790
799
 
791
800
  OpenCode helpers:
792
801
 
793
- - `openCodeDatabaseFiles(env)`: resolves normalized OpenCode `opencode.db`
802
+ - `openCodeDatabaseFiles(env, options)`: resolves normalized OpenCode `opencode.db`
794
803
  files from data-root defaults and database override env vars.
795
- - `openCodeStorageRoots(env)`: resolves global and project-scoped OpenCode
804
+ - `openCodeStorageRoots(env, options)`: resolves global and project-scoped OpenCode
796
805
  `storage` directories, plus override env vars.
797
806
  - `readOpenCodeSqliteSessionsFromDb(dbPath)`: reads the `session`, `message`,
798
807
  `part`, and `project` tables from `opencode.db` and emits
799
- `opencode-sqlite-history` sessions.
808
+ desktop or explicitly configured SQLite sessions.
800
809
  - `openCodeSessionFiles(root)`: finds session JSON files.
801
810
  - `openCodeMessageSessionIds(root)`: finds message-only OpenCode session
802
811
  directories when session metadata is missing.
@@ -77,6 +77,13 @@ without a specific archived model group as `claude-unknown`, because the model
77
77
  family is still known. Favorite-model stats still use known archived model
78
78
  metadata.
79
79
 
80
+ SDK source types (`codex-sdk-history` and `claude-sdk-history`) are excluded from
81
+ the primary stats totals, daily activity, streaks, folder rankings, and
82
+ provider/model/company charts by default. The stats payload still exposes their
83
+ own SDK aggregate fields plus `split_stats.sdk`, and the web view renders an SDK
84
+ jobs card and heatmap. This keeps high-volume batch automation searchable and
85
+ auditable without letting it swamp interactive usage stats.
86
+
80
87
  Cursor sessions that still lack provider-reported usage get a separate
81
88
  `estimatedUsage` metadata field instead of synthetic `usage`. The estimate uses
82
89
  empirical per-assistant-turn Cursor rates by model family, with visible
@@ -130,7 +137,7 @@ agentlog does not blindly copy entire source directories.
130
137
  ## Canonical Events
131
138
 
132
139
  `events.jsonl` is the provider-independent archive/search substrate. It uses
133
- schema version `agentlog.events.v1` and these event kinds:
140
+ schema version `agentlog.events.v2` and these event kinds:
134
141
 
135
142
  - `session.started`
136
143
  - `prompt.submitted`
@@ -150,9 +157,14 @@ events add viewer-facing display metadata:
150
157
  - `metadata.toolCalls[]`: `id`, `name`, `displayName`, `category`, `title`,
151
158
  `status`, `argument`, `rawInputSummary`, `inputPreview`, `target`, `icon`,
152
159
  `categoryLabel`, and `provider`.
153
- - `metadata.toolResult`: `provider`, `kind`, `title`, `summary`, `output`,
154
- `lineCount`, `collapsed`, `category`, `categoryLabel`, `icon`, and optional
155
- `status`.
160
+ - `metadata.toolResult`: `id`, `name`, `provider`, `kind`, `title`, `summary`,
161
+ `output`, `lineCount`, `collapsed`, `category`, `categoryLabel`, `icon`, and
162
+ optional `status`.
163
+
164
+ `tool.completed.parentEventId` links to the matching `tool.called` event when a
165
+ provider exposes stable ids or matching tool names. When those are absent,
166
+ canonical event derivation falls back to the next unmatched tool call so streams
167
+ such as Devin CLI still preserve the call/result relationship.
156
168
 
157
169
  The viewer reads canonical events or normalized metadata first. Text patterns
158
170
  such as `Grep(...)` are legacy fallback only.
@@ -183,30 +195,36 @@ package-prefixed scheme.
183
195
 
184
196
  | Source type | Version |
185
197
  | --- | --- |
186
- | `codex-cli-history` | `0.2.4.0` |
187
- | `codex-desktop-history` | `0.2.4.0` |
188
- | `cli-history` | `0.2.4.0` |
189
- | `claude-sdk-history` | `0.2.4.0` |
190
- | `claude-code-desktop-metadata` | `0.2.4.0` |
191
- | `claude-workspace-desktop` | `0.2.4.0` |
192
- | `cursor-workspace-sqlite` | `0.2.4.0` |
193
- | `cursor-global-sqlite` | `0.2.4.0` |
194
- | `cursor-raw-sqlite-salvage` | `0.2.4.0` |
195
- | `cursor-agent-transcripts` | `0.2.4.0` |
196
- | `devin-cli-history` | `0.2.4.0` |
197
- | `gemini-cli-history` | `0.2.4.0` |
198
- | `cline-task-history` | `0.2.4.0` |
199
- | `opencode-history` | `0.2.4.0` |
200
- | `opencode-sqlite-history` | `0.2.4.0` |
201
- | `aider-chat-history` | `0.2.4.0` |
202
- | `antigravity-history` | `0.2.4.0` |
203
- | `antigravity-trajectory-summary` | `0.2.4.0` |
204
- | `windsurf-trajectory-export` | `0.2.4.0` |
205
- | `web-chat-export` | `0.2.4.0` |
206
- | `chatgpt-export` | `0.2.4.0` |
207
- | `claude-web-export` | `0.2.4.0` |
208
- | `claude-web-memory` | `0.2.4.0` |
209
- | `import` | `0.2.4.0` |
198
+ | `codex-cli-history` | `0.2.6.0` |
199
+ | `codex-desktop-history` | `0.2.6.0` |
200
+ | `codex-sdk-history` | `0.2.6.0` |
201
+ | `cli-history` | `0.2.6.0` |
202
+ | `claude-sdk-history` | `0.2.6.0` |
203
+ | `claude-code-desktop-metadata` | `0.2.6.0` |
204
+ | `claude-workspace-desktop` | `0.2.6.0` |
205
+ | `cursor-workspace-sqlite` | `0.2.6.0` |
206
+ | `cursor-global-sqlite` | `0.2.6.0` |
207
+ | `cursor-raw-sqlite-salvage` | `0.2.6.0` |
208
+ | `cursor-agent-transcripts` | `0.2.6.0` |
209
+ | `devin-cli-history` | `0.2.6.0` |
210
+ | `gemini-cli-history` | `0.2.6.0` |
211
+ | `cline-task-history` | `0.2.6.0` |
212
+ | `opencode-cli-history` | `0.2.6.0` |
213
+ | `opencode-cli-sqlite-history` | `0.2.6.0` |
214
+ | `opencode-desktop-history` | `0.2.6.0` |
215
+ | `opencode-desktop-sqlite-history` | `0.2.6.0` |
216
+ | `opencode-web-sqlite-history` | `0.2.6.0` |
217
+ | `opencode-history` | `0.2.6.0` |
218
+ | `opencode-sqlite-history` | `0.2.6.0` |
219
+ | `aider-chat-history` | `0.2.6.0` |
220
+ | `antigravity-history` | `0.2.6.0` |
221
+ | `antigravity-trajectory-summary` | `0.2.6.0` |
222
+ | `windsurf-trajectory-export` | `0.2.6.0` |
223
+ | `web-chat-export` | `0.2.6.0` |
224
+ | `chatgpt-export` | `0.2.6.0` |
225
+ | `claude-web-export` | `0.2.6.0` |
226
+ | `claude-web-memory` | `0.2.6.0` |
227
+ | `import` | `0.2.6.0` |
210
228
 
211
229
  `cursor-sqlite-history` and `antigravity-brain` are compatibility aliases for
212
230
  older labels. Fingerprints include the parser version prefix, so changing the
@@ -244,20 +262,21 @@ real-world query should reliably find a representative archived session.
244
262
 
245
263
  The setup UI, import defaults, and history source filters use this grouped order:
246
264
 
247
- 1. OpenAI: Codex CLI, Codex Desktop, ChatGPT
265
+ 1. OpenAI: Codex CLI, Codex Desktop, Codex SDK jobs, ChatGPT
248
266
  2. Anthropic: Claude Code CLI, Claude Code Desktop, Claude Workspace,
249
267
  Claude.ai, Claude SDK jobs
250
268
  3. Google: Gemini CLI, Antigravity
251
269
  4. Cognition: Devin CLI
252
- 5. Other: Cursor, Cline, OpenCode, Aider
270
+ 5. Other: Cursor, Cline, OpenCode CLI, OpenCode Desktop, OpenCode Web, Aider
253
271
 
254
272
  `agentlog import --source all` uses the default import order from
255
273
  `src/sources.js`: `codex-cli`, `codex-desktop`, `claude`,
256
274
  `claude-code-desktop`, `claude-workspace`, `gemini-cli`, `antigravity`,
257
- `devin-cli`, `cursor`, `cline`, `opencode`, `aider`. Claude SDK jobs are
258
- intentionally opt-in. Windsurf local cache scanning is disabled for now because
259
- current Cascade transcripts are encrypted binary stores, but downloaded
260
- trajectory Markdown exports are importable with an explicit path.
275
+ `devin-cli`, `cursor`, `cline`, `opencode-cli`, `opencode-desktop`,
276
+ `opencode-web`, `aider`. Codex SDK jobs and Claude SDK jobs are intentionally
277
+ opt-in. Windsurf local cache scanning is disabled for now because current
278
+ Cascade transcripts are encrypted binary stores, but downloaded trajectory
279
+ Markdown exports are importable with an explicit path.
261
280
 
262
281
  The background watcher polls the watcher source list selected near the end of
263
282
  `agentlog init`. New configs still support `imports.autoDiscoverSources=true`,
@@ -321,6 +340,7 @@ stable local command for the archived source.
321
340
  | --- | --- | --- |
322
341
  | Codex CLI | `codex resume <session-id>` | Uses the Codex thread id from `~/.codex/state_5.sqlite`. |
323
342
  | Codex Desktop | `codex resume <session-id>` | Uses the same Codex thread id. Codex decides whether the resumed session opens in the terminal flow. |
343
+ | Codex SDK jobs | No interactive resume command. | These are Codex `exec`/SDK-style batch runs. |
324
344
  | Claude Code CLI | `claude -r <session-id>` | Uses the Claude Code JSONL session id. |
325
345
  | 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`. |
326
346
  | Claude Code Desktop | No stable local resume command known. | Use Claude's own desktop/history surface or `agentlog show <session-id>`. |
@@ -383,17 +403,38 @@ rollout parser as Codex CLI. The only distinction is the `threads.source` value.
383
403
  This is why the web source dropdown can split Codex CLI and Codex Desktop even
384
404
  though both archive under the same `codex` provider.
385
405
 
406
+ ## Codex SDK Jobs
407
+
408
+ - Import selector: `codex-sdk`
409
+ - Provider: `codex`
410
+ - Source type: `codex-sdk-history`
411
+ - Primary store: `~/.codex/state_5.sqlite`
412
+ - Session files: rollout paths referenced by the `threads` table
413
+ - Source split: `threads.source = "exec"`
414
+ - Overrides: same as Codex CLI
415
+
416
+ Codex SDK jobs use the same rollout parser as Codex CLI/Desktop, but they are
417
+ shown as a separate opt-in source because `codex exec` batch traffic can produce
418
+ hundreds or thousands of short prompt/response sessions. They are useful for
419
+ programmatic jobs such as Siftly bookmark enrichment and Polymarket vote
420
+ labeling, but should not be silently mixed into the default interactive import.
421
+ When imported, these sessions remain searchable, but the stats view keeps them
422
+ in the separate SDK jobs aggregate instead of primary interactive totals.
423
+
386
424
  ## ChatGPT Export
387
425
 
388
- - Import command: `agentlog import chatgpt --file <path> [--scope local|team]`
426
+ - Instructions command: `agentlog import chatgpt`
427
+ - Import command: `agentlog import chatgpt <path> [--scope local|team]`
389
428
  - Provider: `chatgpt`
390
429
  - Source type: `chatgpt-export`
391
430
  - Source file: ChatGPT JSON export or ZIP containing a JSON export
392
431
  - Default archive scope: `chatgpt`
393
432
 
394
- ChatGPT is not scanned automatically from a desktop app. The user provides an
395
- official export file. ZIP imports prefer `conversations.json`, then another JSON
396
- file with `chat` in the name, then the first JSON file in the ZIP.
433
+ ChatGPT is not scanned automatically from a desktop app. The import command
434
+ without a path prints official export instructions for OpenAI's Privacy Portal
435
+ and ChatGPT Data Controls. The user then provides the downloaded official export
436
+ file. ZIP imports prefer `conversations.json`, then another JSON file with
437
+ `chat` in the name, then the first JSON file in the ZIP.
397
438
 
398
439
  For OpenAI export mappings, agentlog reads each node message, normalizes
399
440
  `author.role`, extracts `content.parts`, and uses `create_time` or `update_time`
@@ -413,17 +454,66 @@ usage as estimated.
413
454
  Claude Code CLI files are discovered under `~/.claude/projects`. Each JSONL file
414
455
  is classified before import. A file is treated as an interactive conversation
415
456
  when the initial records include `type = "user"` or `type = "assistant"` with a
416
- `message` object and no `entrypoint = "sdk-cli"`.
457
+ `message` object and no `entrypoint = "sdk-cli"`. Remote Control transcripts
458
+ also use `entrypoint = "sdk-cli"`, but include a deferred tool delta with
459
+ Remote Control tool names such as `RemoteTrigger`, `TaskOutput`, `TaskStop`,
460
+ `PushNotification`, `AskUserQuestion`, task tools, cron tools, or monitor tools;
461
+ those are imported as interactive Claude Code conversations rather than SDK
462
+ jobs.
417
463
 
418
464
  The Claude-specific JSONL parser extracts session ids, titles, cwd fields,
419
465
  message roles, text content, timestamps, assistant thinking summaries,
420
466
  `tool_use` calls, `tool_result` outputs, model, request id, stop status, and
421
- token usage. Tool calls and results are normalized into the shared
467
+ token usage. It also preserves Claude JSONL lineage fields (`uuid`,
468
+ `parentUuid`, `logicalParentUuid`, `leafUuid`, `promptId`,
469
+ `sourceToolAssistantUUID`, `sourceToolUseID`, `parentToolUseID`, `toolUseID`,
470
+ `agentId`, `slug`, `isSidechain`), execution metadata (`entrypoint`,
471
+ `userType`, Claude Code version, git branch, permission mode), attribution skill,
472
+ MCP structured-content metadata, API error metadata, Remote Control
473
+ queue/tool-surface summaries, and richer usage extras such as service tier,
474
+ speed, server-tool usage, and cache creation detail.
475
+ Tool calls and results are normalized into the shared
422
476
  `metadata.toolCalls[]`, `metadata.toolResult`, and `metadata.usage` shapes.
423
477
  Bash or shell tool calls that invoke `apply_patch` are reclassified as edit
424
- calls and retain the patch text under `arguments.diff`. Repo attribution is
425
- computed from the parsed `cwd`; if no cwd is present the session is archived
426
- under an uncategorized provider scope.
478
+ calls and retain the patch text under `arguments.diff`.
479
+ Tool results are matched back to prior `tool_use` ids when possible so result
480
+ cards inherit the tool name instead of displaying only the raw tool-use id.
481
+ Remote Control lifecycle records are also converted into provider-generated
482
+ system/context messages for queue operations, deferred tool catalog changes,
483
+ MCP instruction updates, skill listings, nested memories, queued commands,
484
+ command permissions, edited text files, date changes, max-turn notices,
485
+ file-history snapshots, hook progress, and stop-hook summaries. These messages
486
+ carry compact metadata and previews rather than copying large attachment bodies;
487
+ the byte-perfect source records remain in the raw archive. Session summaries
488
+ also include Remote Control attachment counts/details, available tool names,
489
+ MCP server names, queue timing/content, agent ids, slugs, API error counts, and
490
+ MCP structured-content counts.
491
+
492
+ When the Claude desktop app has a matching
493
+ `~/Library/Application Support/Claude/claude-code-sessions/**/local_*.json`
494
+ record with `cliSessionId`, the CLI importer uses that sidecar's generated
495
+ `title` and `originCwd` while preserving both the transcript and sidecar in raw
496
+ archive storage. This is the source of Claude's readable auto names such as
497
+ "Fix cursor import paths handling"; the transcript JSONL itself may only contain
498
+ the user prompt ("Can you fix these?"). Without a sidecar title, the importer
499
+ uses Claude JSONL `ai-title` events when present, then falls back to the first
500
+ real user prompt. Repo attribution uses sidecar
501
+ `originCwd` when available, otherwise the parsed `cwd`; Claude-created
502
+ `.claude/worktrees/<name>` directories are attributed to their parent project
503
+ when that project still exists, even if the temporary worktree has been deleted.
504
+ The original worktree path remains stored as `cwd`. If no cwd is present the
505
+ session is archived under an uncategorized provider scope.
506
+
507
+ A sanitized subset of sidecar metadata is also copied into
508
+ `metadata.sessionSummary.claudeCodeSidecar`: the app/CLI session ids, title
509
+ source, cwd/origin cwd, worktree path/name, branch names, created/last-activity
510
+ timestamps, model/effort, permission modes, completed turn count, archive state,
511
+ enabled MCP tool count, MCP server names, and sidecar source path. The sidecar
512
+ `model` also contributes to normalized `models[]` through `sessionSummary`
513
+ model usage. Full MCP configuration remains available only through raw
514
+ preservation rather than promoted metadata. After this parser behavior changes,
515
+ run `agentlog update --yes --since all` or `agentlog import claude --since all`
516
+ to rebuild existing local Claude Code archives.
427
517
 
428
518
  ## Claude SDK Jobs
429
519
 
@@ -439,7 +529,8 @@ sessions. agentlog separates them by scanning the initial JSONL records for
439
529
  batch runs can be much higher volume than interactive sessions.
440
530
 
441
531
  When imported, SDK jobs use the same Claude-specific JSONL parser as Claude Code
442
- CLI but archive under `claude_sdk`.
532
+ CLI but archive under `claude_sdk`. Stats keep them in the separate SDK jobs
533
+ aggregate instead of primary interactive totals.
443
534
 
444
535
  ## Claude Code Desktop
445
536
 
@@ -491,16 +582,18 @@ uncategorized.
491
582
 
492
583
  ## Claude.ai Export
493
584
 
494
- - Import command: `agentlog import claude-web --file <path> [--scope local|team]`
585
+ - Instructions command: `agentlog import claude-web`
586
+ - Import command: `agentlog import claude-web <path> [--scope local|team]`
495
587
  - Provider: `claude_web`
496
588
  - Source types: `claude-web-export`, `claude-web-memory`
497
589
  - Source file: Claude.ai JSON export or ZIP containing a JSON export
498
590
  - Default archive scope: `claude_web`
499
591
 
500
- Claude.ai is not scanned automatically from the desktop app. The user provides
501
- an official export file. agentlog reads `chat_messages`, `messages`, or
502
- `children`, normalizes sender/role fields, extracts text content, and uses
503
- `created_at`, `updated_at`, or `timestamp`.
592
+ Claude.ai is not scanned automatically from the desktop app. The import command
593
+ without a path prints official export instructions for Claude Settings >
594
+ Privacy. The user then provides the downloaded official export file. agentlog
595
+ reads `chat_messages`, `messages`, or `children`, normalizes sender/role fields,
596
+ extracts text content, and uses `created_at`, `updated_at`, or `timestamp`.
504
597
  For official `conversations.json` exports, the top-level conversation `summary`
505
598
  is archived as both `sessionSummary.summary` and a supplementary transcript row.
506
599
  Assistant messages prefer structured `content[]` parts over the legacy top-level
@@ -526,7 +619,7 @@ are marked `recovered-time-unknown` in history views instead of being displayed
526
619
  as if they happened at import time. This keeps project folders from implying
527
620
  that account-level conversations were reliably tagged to Claude projects when
528
621
  the export did not preserve that relationship. Re-run
529
- `agentlog import claude-web --file <path>` after importing an export that
622
+ `agentlog import claude-web <path>` after importing an export that
530
623
  contains conversation project ids or after Claude web parser semantics change.
531
624
 
532
625
  Like ChatGPT export imports, Claude.ai imports are scope-based by default because
@@ -834,18 +927,25 @@ original checkpoint files remain in raw backups.
834
927
 
835
928
  ## OpenCode
836
929
 
837
- - Import selector: `opencode`
930
+ - Import selectors: `opencode-cli`, `opencode-desktop`, `opencode-web`, or `opencode` for all three
838
931
  - Provider: `opencode`
839
932
  - Source types:
840
- - `opencode-sqlite-history` for the normalized `opencode.db` store
841
- - `opencode-history` for the JSON `storage/` layout
842
- - Primary data root: `~/.local/share/opencode`
843
- - Alternate macOS data root: `~/Library/Application Support/opencode`
844
- - Additional desktop roots:
933
+ - `opencode-cli-history` for CLI JSON `storage/` sessions
934
+ - `opencode-cli-sqlite-history` for the CLI/core normalized `~/.local/share/opencode/opencode.db` store
935
+ - `opencode-desktop-history` for desktop/app JSON `storage/` sessions
936
+ - `opencode-desktop-sqlite-history` for the desktop/app normalized `opencode.db` store
937
+ - `opencode-web-sqlite-history` for web sessions in the shared normalized SQLite store
938
+ - `opencode-history` and `opencode-sqlite-history` for older or explicitly configured archives
939
+ - CLI data root: `~/.local/share/opencode`
940
+ - Desktop/app data roots:
941
+ - `~/Library/Application Support/ai.opencode.desktop`
942
+ - `~/Library/Application Support/opencode`
845
943
  - `~/.local/share/ai.opencode.app`
846
944
  - `~/Library/Application Support/ai.opencode.app`
847
945
  - SQLite database:
848
- - `opencode.db`
946
+ - CLI/core root: `~/.local/share/opencode/opencode.db`
947
+ - desktop/app roots: `opencode.db`
948
+ - explicit overrides only: `AGENTLOG_OPENCODE_DB`, `AGENTLOG_OPENCODE_DATABASE`, `OPENCODE_DB`, or `AGENTLOG_OPENCODE_DATA_DIR`
849
949
  - Storage roots:
850
950
  - `~/.local/share/opencode/storage`
851
951
  - `~/.local/share/opencode/project/<project-slug>/storage`
@@ -862,8 +962,17 @@ original checkpoint files remain in raw backups.
862
962
  - `AGENTLOG_OPENCODE_STORAGE_DIR` or `AGENTLOG_OPENCODE_STORAGE_ROOTS`
863
963
  points directly at one or more `storage` directories.
864
964
 
865
- agentlog first reads OpenCode's normalized SQLite store when `opencode.db` is
866
- present. The `session`, `message`, `part`, and `project` tables provide session
965
+ agentlog reads OpenCode's normalized SQLite store from the shared core
966
+ `~/.local/share/opencode/opencode.db` root, desktop/app roots, or when a
967
+ database is explicitly configured. The shared core database can contain sessions
968
+ created by Desktop, CLI, and Web clients, so agentlog classifies each SQLite
969
+ session row individually. Desktop sessions are identified by session ids in
970
+ OpenCode Desktop sidecar state such as `ai.opencode.desktop/*.dat`; sub-sessions
971
+ inherit Desktop classification from a Desktop parent. CLI sessions are
972
+ identified by session-level `agent` or `model` metadata. Remaining non-`local`
973
+ shared core rows are labeled as Web sessions. Rows without reliable client
974
+ evidence stay on the legacy `opencode-sqlite-history` source type. The
975
+ `session`, `message`, `part`, and `project` tables provide session
867
976
  metadata, working directory, user/assistant messages, reasoning text, tool
868
977
  calls, tool outputs, model/provider ids, cost, and token usage. Because the
869
978
  database is a multi-session source, raw preservation stores it as a shared raw
@@ -879,7 +988,11 @@ If a session metadata file is missing but `storage/message/<session-id>/` and
879
988
  session from those message and part files.
880
989
 
881
990
  When both SQLite and JSON records exist for the same OpenCode session id,
882
- agentlog prefers `opencode-sqlite-history` and merges the raw source file list.
991
+ agentlog prefers SQLite source types such as `opencode-cli-sqlite-history`
992
+ and merges the raw source file list.
993
+ After this source handling change, run `agentlog import --source opencode
994
+ --since all` or `agentlog update --yes --since all` to rebuild existing local
995
+ OpenCode archives with the corrected CLI/Desktop/Web split.
883
996
 
884
997
  When `session_diff/<session-id>.json` is present, agentlog adds a supplementary
885
998
  edit tool call with the diff payload. Unified diff text is rendered inline in
package/docs/release.md CHANGED
@@ -30,7 +30,6 @@ npm run smoke:pack
30
30
  - selected docs
31
31
  - `README.md`
32
32
  - `LICENSE`
33
- - `agentlog-spec.md`
34
33
  - `package.json`
35
34
 
36
35
  It should not include local settings, test fixtures, `.git`, `.claude`, logs,
@@ -65,5 +64,5 @@ After tagging and pushing the release, sanity-check both public install forms:
65
64
 
66
65
  ```sh
67
66
  npm install -g agentel
68
- npm install -g brianlzhou/agentlog#v0.2.4
67
+ npm install -g brianlzhou/agentlog#v0.2.6
69
68
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentel",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Local-first archive and recall layer for agent coding sessions.",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
package/src/archive.js CHANGED
@@ -1060,7 +1060,7 @@ function ensureConversationMarkdown(session, env = process.env) {
1060
1060
  return conversationPath;
1061
1061
  }
1062
1062
 
1063
- const VIEW_SCHEMA_VERSION = 2;
1063
+ const VIEW_SCHEMA_VERSION = 3;
1064
1064
 
1065
1065
  function sessionViewPathFromMetadata(metadataPath) {
1066
1066
  if (!metadataPath) return "";