agentel 0.2.0 → 0.2.2

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.
@@ -27,18 +27,22 @@ All supported sources are normalized into the same archive shape before write:
27
27
  - `events`: provider-independent canonical events generated from transcript
28
28
  messages and structured tool metadata.
29
29
  - stats metadata: `messageCount`, `userMessageCount`, aggregate `usage`, and
30
- `models` are computed while writing the archive.
31
-
32
- Before writing, message content is redacted by `src/redaction.js`. The redacted
33
- transcript is written to `conversation.md`, `transcript.jsonl`, and
34
- `events.jsonl`. Unredacted original source files are copied or referenced from
35
- `session=<id>.raw/` with a manifest. Large multi-session stores such as Cursor
36
- SQLite use a shared raw-source copy under `raw-sources/`, with each session raw
37
- manifest pointing at that shared file instead of duplicating the same database
38
- hundreds of times. The optional reveal cache stores the unredacted normalized
39
- JSONL when enabled and when the session is repo-scoped. Reimports are skipped by
40
- fingerprint unless the source file changes or the importer fingerprint version
41
- changes.
30
+ `models` are computed while writing the archive. Each transcript message also
31
+ gets `metadata.tokenEstimate` when visible text or tool-call text can be
32
+ counted.
33
+
34
+ Redaction is opt-in. When `~/.agentlog/redaction.yaml` has `enabled: true`,
35
+ message content and structured metadata strings are redacted by
36
+ `src/redaction.js` before writing `conversation.md`, `transcript.jsonl`, and
37
+ `events.jsonl`. Use `agentlog redact init` to create the config, then toggle
38
+ built-in detectors under `built_ins`. Original source files are copied or
39
+ referenced from `session=<id>.raw/` with a manifest. Large multi-session stores
40
+ such as Cursor SQLite use a shared raw-source copy under `raw-sources/`, with
41
+ each session raw manifest pointing at that shared file instead of duplicating
42
+ the same database hundreds of times. The optional reveal cache stores the
43
+ unredacted normalized JSONL when enabled and when the session is repo-scoped.
44
+ Reimports are skipped by fingerprint unless the source file changes or the
45
+ importer fingerprint version changes.
42
46
  Use `agentlog import --source cursor --since all --explain-skips` to print
43
47
  Cursor skip reasons for one run. Add `--json` to inspect `skipReasons` counts
44
48
  and `skippedItems[]` with session ids, source types, paths, and titles.
@@ -55,15 +59,46 @@ usage is preserved separately and repeated provider request ids are counted once
55
59
  which avoids inflating Claude Code/Desktop sessions that repeat the same request
56
60
  usage across assistant text and tool-call rows.
57
61
 
62
+ When provider token usage is missing, message-level estimates use visible text
63
+ length plus visible tool-call summaries at roughly four characters per token.
64
+ The generic archive estimate is stored as `metadata.tokenEstimate` on each
65
+ message and is not treated as provider-reported `metadata.usage`. ChatGPT and
66
+ Claude.ai export importers additionally populate estimated `metadata.usage` from
67
+ their native message parts so stats can count chat input/output at import time.
68
+
69
+ Provider, model-company, and model breakdowns are emitted directly in the stats
70
+ payload. Daily and folder buckets retain provider splits, inferred model-company
71
+ splits, and primary-model splits so the web viewer can switch between provider,
72
+ company, and model charts without reparsing transcripts. The company dimension
73
+ means the model maker, such as OpenAI, Anthropic, Google, Cognition, or
74
+ Windsurf. Model-routing clients such as Cursor group under unknown when their
75
+ archived metadata does not identify the actual model. Claude.ai export sessions
76
+ without a specific archived model group as `claude-unknown`, because the model
77
+ family is still known. Favorite-model stats still use known archived model
78
+ metadata.
79
+
80
+ Cursor sessions that still lack provider-reported usage get a separate
81
+ `estimatedUsage` metadata field instead of synthetic `usage`. The estimate uses
82
+ empirical per-assistant-turn Cursor rates by model family, with visible
83
+ transcript context as a lower bound, and the stats payload reports how much of
84
+ the token total is estimated via `total_estimated_tokens` / `tokens_estimated`.
85
+ ChatGPT and Claude.ai web exports get estimated per-message `metadata.usage`
86
+ when provider usage is absent; those estimates are native message-part totals
87
+ split as non-assistant input, assistant output, and Claude thinking output, not
88
+ reconstructed billing context windows.
89
+
58
90
  ```sh
59
- agentlog reset --yes
60
- agentlog init
61
- agentlog import --source all --since all
91
+ agentlog update --yes --since all
62
92
  ```
63
93
 
64
- `agentlog reset` removes agentlog state and archive objects only; it does not
65
- delete source application histories such as Cursor, Codex, Claude, Gemini, or
66
- Devin logs.
94
+ `agentlog update` preserves config preferences, redaction settings, web account
95
+ labels, source histories, and recall integrations. It removes derived local
96
+ archive/import/index state and reimports configured local sources. Manual web
97
+ exports still need to be imported again from the original export file when those
98
+ archives need to be rebuilt. `agentlog reset` is the heavier path: it removes
99
+ agentlog state and archive objects, including config, while still leaving source
100
+ application histories such as Cursor, Codex, Claude, Gemini, or Devin logs
101
+ untouched.
67
102
 
68
103
  Archive paths are grouped by repo or scope:
69
104
 
@@ -136,40 +171,42 @@ context headers, and interruption markers.
136
171
 
137
172
  ## Parser Versions
138
173
 
139
- Parser versions live in `src/parser-versions.js`. They are semantic-version
140
- strings. The first npm release uses `1.0.0` as the parser baseline for every
141
- source type.
142
-
143
- After release, bump the affected source type in the same change whenever parser
144
- output changes for the same raw input: message roles, timestamps, tool-call
145
- metadata, tool-result metadata, source classification, fingerprints, or
146
- canonical event text. Use patch bumps for narrow correctness fixes, minor bumps
147
- for additive parser enrichment, and major bumps for source identity,
148
- fingerprint, archive-contract, or meaningfully incompatible output changes.
174
+ Parser versions live in `src/parser-versions.js`. They are package-prefixed
175
+ four-part strings: `<package-version>.<source-suffix>`. During development,
176
+ bump the affected source suffix whenever parser output changes for the same raw
177
+ input: message roles, timestamps, tool-call metadata, tool-result metadata,
178
+ source classification, fingerprints, or canonical event text. When cutting a
179
+ new package release, the package version supplies the new baseline, so suffixes
180
+ can reset to `0` unless parser output changes again during that package cycle.
181
+ Legacy three-part parser versions are treated as older than the current
182
+ package-prefixed scheme.
149
183
 
150
184
  | Source type | Version |
151
185
  | --- | --- |
152
- | `codex-cli-history` | `1.0.0` |
153
- | `codex-desktop-history` | `1.0.0` |
154
- | `cli-history` | `1.0.0` |
155
- | `claude-sdk-history` | `1.0.0` |
156
- | `claude-code-desktop-metadata` | `1.0.0` |
157
- | `claude-workspace-desktop` | `1.0.0` |
158
- | `cursor-workspace-sqlite` | `1.0.0` |
159
- | `cursor-global-sqlite` | `1.0.0` |
160
- | `cursor-raw-sqlite-salvage` | `1.0.0` |
161
- | `cursor-agent-transcripts` | `1.0.0` |
162
- | `devin-cli-history` | `1.0.0` |
163
- | `gemini-cli-history` | `1.0.0` |
164
- | `cline-task-history` | `1.0.0` |
165
- | `opencode-history` | `1.0.0` |
166
- | `aider-chat-history` | `1.0.0` |
167
- | `antigravity-history` | `1.0.0` |
168
- | `web-chat-export` | `1.0.0` |
169
- | `chatgpt-export` | `1.0.0` |
170
- | `claude-web-export` | `1.0.0` |
171
- | `claude-web-memory` | `1.0.0` |
172
- | `import` | `1.0.0` |
186
+ | `codex-cli-history` | `0.2.2.0` |
187
+ | `codex-desktop-history` | `0.2.2.0` |
188
+ | `cli-history` | `0.2.2.0` |
189
+ | `claude-sdk-history` | `0.2.2.0` |
190
+ | `claude-code-desktop-metadata` | `0.2.2.0` |
191
+ | `claude-workspace-desktop` | `0.2.2.0` |
192
+ | `cursor-workspace-sqlite` | `0.2.2.0` |
193
+ | `cursor-global-sqlite` | `0.2.2.0` |
194
+ | `cursor-raw-sqlite-salvage` | `0.2.2.0` |
195
+ | `cursor-agent-transcripts` | `0.2.2.0` |
196
+ | `devin-cli-history` | `0.2.2.0` |
197
+ | `gemini-cli-history` | `0.2.2.0` |
198
+ | `cline-task-history` | `0.2.2.0` |
199
+ | `opencode-history` | `0.2.2.0` |
200
+ | `opencode-sqlite-history` | `0.2.2.0` |
201
+ | `aider-chat-history` | `0.2.2.0` |
202
+ | `antigravity-history` | `0.2.2.0` |
203
+ | `antigravity-trajectory-summary` | `0.2.2.0` |
204
+ | `windsurf-trajectory-export` | `0.2.2.0` |
205
+ | `web-chat-export` | `0.2.2.0` |
206
+ | `chatgpt-export` | `0.2.2.0` |
207
+ | `claude-web-export` | `0.2.2.0` |
208
+ | `claude-web-memory` | `0.2.2.0` |
209
+ | `import` | `0.2.2.0` |
173
210
 
174
211
  `cursor-sqlite-history` and `antigravity-brain` are compatibility aliases for
175
212
  older labels. Fingerprints include the parser version prefix, so changing the
@@ -182,6 +219,22 @@ version makes reimport replace stale archive copies.
182
219
  back to sessions for CLI/skill compatibility. Archives without `events.jsonl`
183
220
  remain searchable through transcript/markdown fallback, and missing
184
221
  `conversation.md` files are materialized from transcripts when needed.
222
+ The web session API reads pre-baked `view.json` for the default readable pane.
223
+ When the raw Markdown source view is requested, the browser asks for a
224
+ Markdown-only payload instead of downloading the full transcript again. Browser
225
+ session payloads compact duplicated tool output and use ETag revalidation so
226
+ revisits and live refresh checks can avoid reparsing unchanged transcripts.
227
+ The local BM25 JSON index stores term postings plus document metadata for
228
+ compatibility. A SQLite FTS5 sidecar stores the same chunks for interactive
229
+ search so browser, terminal, and MCP recall queries do not parse a large JSON
230
+ index in short-lived search processes. Index format bumps trigger a rebuild from
231
+ existing `transcript.jsonl` and `events.jsonl`; they do not require reparsing
232
+ provider source files. The web search endpoint is optimized for typing: it uses
233
+ the compatible warm FTS/index when present, skips obsolete or stale indexes
234
+ rather than parsing/rebuilding inline, and does not scan every rendered Markdown
235
+ archive as a fallback. Terminal and MCP recall search also avoid synchronous
236
+ rebuilds and BM25 JSON parses, then fall back to the bounded Markdown search for
237
+ legacy archives or misses.
185
238
 
186
239
  Recall quality has deterministic tests in `test/recall-eval.test.js` with
187
240
  fixtures under `test/fixtures/recall-evals.json`. Add a fixture when a vague
@@ -202,10 +255,11 @@ The setup UI, import defaults, and history source filters use this grouped order
202
255
  `src/sources.js`: `codex-cli`, `codex-desktop`, `claude`,
203
256
  `claude-code-desktop`, `claude-workspace`, `gemini-cli`, `antigravity`,
204
257
  `devin-cli`, `cursor`, `cline`, `opencode`, `aider`. Claude SDK jobs are
205
- intentionally opt-in. Windsurf is disabled for now because current Cascade
206
- transcripts are encrypted binary stores.
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.
207
261
 
208
- The background supervisor polls the watcher source list selected near the end of
262
+ The background watcher polls the watcher source list selected near the end of
209
263
  `agentlog init`. New configs still support `imports.autoDiscoverSources=true`,
210
264
  but init now records the chosen watcher list exactly by setting
211
265
  `imports.autoDiscoverSources=false`.
@@ -333,7 +387,7 @@ though both archive under the same `codex` provider.
333
387
 
334
388
  - Import command: `agentlog import chatgpt --file <path> [--scope local|team]`
335
389
  - Provider: `chatgpt`
336
- - Source type: `web-chat-export`
390
+ - Source type: `chatgpt-export`
337
391
  - Source file: ChatGPT JSON export or ZIP containing a JSON export
338
392
  - Default archive scope: `chatgpt`
339
393
 
@@ -344,7 +398,10 @@ file with `chat` in the name, then the first JSON file in the ZIP.
344
398
  For OpenAI export mappings, agentlog reads each node message, normalizes
345
399
  `author.role`, extracts `content.parts`, and uses `create_time` or `update_time`
346
400
  as the timestamp. Web imports are scope-based by default because they generally
347
- do not have a reliable local working directory.
401
+ do not have a reliable local working directory. Since official exports do not
402
+ usually include usage, the importer archives estimated per-message
403
+ `metadata.usage` from native message content and marks the resulting session
404
+ usage as estimated.
348
405
 
349
406
  ## Claude Code CLI
350
407
 
@@ -444,6 +501,15 @@ Claude.ai is not scanned automatically from the desktop app. The user provides
444
501
  an official export file. agentlog reads `chat_messages`, `messages`, or
445
502
  `children`, normalizes sender/role fields, extracts text content, and uses
446
503
  `created_at`, `updated_at`, or `timestamp`.
504
+ For official `conversations.json` exports, the top-level conversation `summary`
505
+ is archived as both `sessionSummary.summary` and a supplementary transcript row.
506
+ Assistant messages prefer structured `content[]` parts over the legacy top-level
507
+ `text` field so thinking/redacted-thinking parts are separated into
508
+ supplementary `summaryKind=thinking` rows and the visible assistant answer stays
509
+ clean.
510
+ When usage is absent, chat messages get estimated `metadata.usage` from native
511
+ message parts. Claude thinking/redacted-thinking parts contribute
512
+ `reasoningOutputTokens`; visible assistant text remains `outputTokens`.
447
513
 
448
514
  Project-file conversations are imported as project-scoped sessions. Top-level
449
515
  conversation exports are assigned to a project only when Claude includes an
@@ -454,11 +520,14 @@ those conversations remain under the account-level chat scope.
454
520
 
455
521
  Memory exports are grouped under the synthetic `memory` chat folder instead of
456
522
  the original project folder. Root memory is titled `Claude Memory`; project
457
- memory is titled `Claude Project Memory: <project name>`. This keeps project
458
- folders from implying that account-level conversations were reliably tagged to
459
- Claude projects when the export did not preserve that relationship. Re-run
523
+ memory is titled `Claude Project Memory: <project name>`. Claude memory exports
524
+ do not include reliable memory creation/update timestamps, so memory sessions
525
+ are marked `recovered-time-unknown` in history views instead of being displayed
526
+ as if they happened at import time. This keeps project folders from implying
527
+ that account-level conversations were reliably tagged to Claude projects when
528
+ the export did not preserve that relationship. Re-run
460
529
  `agentlog import claude-web --file <path>` after importing an export that
461
- contains conversation project ids or after memory parser semantics change.
530
+ contains conversation project ids or after Claude web parser semantics change.
462
531
 
463
532
  Like ChatGPT export imports, Claude.ai imports are scope-based by default because
464
533
  the export does not reliably describe a local repo.
@@ -483,9 +552,17 @@ JSON and JSONL files use a Gemini-specific parser for `role` / `parts` content,
483
552
  native Gemini CLI `type: "user"` / `type: "gemini"` content records, `model`
484
553
  role normalization, `functionCall`, `functionResponse`, direct tool call/result
485
554
  shapes, nested native `toolCalls[].result` entries, shell/code execution parts,
486
- usage metadata, and checkpoint or restore events. Gemini tmp prompt logs and
487
- chat JSONL sidecars with the same session id are coalesced so prompt-only
488
- `logs.json` files do not overwrite richer assistant/tool transcripts. Markdown
555
+ usage metadata, topic context title updates, and checkpoint or restore events.
556
+ Gemini tmp prompt logs can contain multiple sessions, so agentlog splits them by
557
+ session id before coalescing matching prompt-only logs with richer chat JSONL
558
+ sidecars. When Gemini `Update Topic Context` tool calls include a `title`,
559
+ agentlog stores the latest topic title in session metadata so the web viewer and
560
+ history lists can display it instead of a timestamp-like filename. Existing
561
+ Gemini archives need `agentlog import --source gemini-cli --since all` after
562
+ this parser bump to populate those titles. When Gemini shutdown interaction
563
+ summaries appear in structured history, they are parsed into session metadata
564
+ for tool-call counts, timing, model usage, and resume commands instead of being
565
+ inserted into the chat transcript. Markdown
489
566
  files are split into messages by role headings such as
490
567
  `# User`, `# Assistant`, or bold role labels. The working directory comes from
491
568
  parsed cwd fields or Gemini tmp `.project_root` metadata. If no working
@@ -496,8 +573,10 @@ directory can be resolved, the session is archived under
496
573
 
497
574
  - Import selector: `antigravity`
498
575
  - Provider: `antigravity`
499
- - Source type: `antigravity-brain`
576
+ - Source types: `antigravity-brain`, `antigravity-trajectory-summary`
500
577
  - Primary readable store: `~/.gemini/antigravity/brain/*`
578
+ - Partial metadata store:
579
+ `Application Support/Antigravity/User/globalStorage/state.vscdb`
501
580
  - Binary store counted but not decoded:
502
581
  `~/.gemini/antigravity/conversations/*.pb`
503
582
 
@@ -506,10 +585,18 @@ artifact names are `task.md`, `implementation_plan.md`, `walkthrough.md`, and
506
585
  `plan.md`. Each artifact becomes an assistant message with a heading naming the
507
586
  artifact. Timestamps come from artifact file mtimes.
508
587
 
588
+ When a conversation has no readable Markdown artifacts, agentlog also imports
589
+ Antigravity trajectory summaries from the app's VS Code-style global state DB.
590
+ Those summaries preserve the conversation id, visible prompt/title, timestamps,
591
+ and workspace path when present. They are marked as partial summaries and do not
592
+ claim to be full transcripts. The global state DB is referenced in the raw
593
+ manifest but not copied, since it can contain auth-bearing settings.
594
+
509
595
  The importer tries to infer a working directory from `file://...` links inside
510
- the Markdown artifacts. If none can be inferred, it archives under
511
- `antigravity/uncategorized`. Binary protobuf transcripts are counted in
512
- discovery details but not imported as conversation messages yet.
596
+ the Markdown artifacts or trajectory summary. If none can be inferred, it
597
+ archives under `antigravity/uncategorized`. Binary protobuf transcripts are
598
+ counted in discovery details but not imported as conversation messages yet.
599
+ Antigravity token usage is therefore not populated from the current local stores.
513
600
 
514
601
  ## Devin CLI
515
602
 
@@ -537,6 +624,12 @@ Devin's `metadata.extensions["chisel/tool_call_content"]` is used for small
537
624
  display metadata (`title`, `status`, `kind`, and tool id) while arguments are
538
625
  stored as redaction-aware summaries.
539
626
 
627
+ Assistant nodes preserve Devin's per-generation token metrics from
628
+ `chat_message.metadata.metrics`, including input, output, cache creation, and
629
+ cache read token counts. Re-run `agentlog import --source devin-cli --since all`
630
+ after upgrading from older parser versions to populate these stats in existing Devin
631
+ archives.
632
+
540
633
  Timestamps come from `sessions.created_at`, `sessions.last_activity_at`, and
541
634
  per-node `created_at` values. Devin currently stores these as Unix seconds.
542
635
  The working directory comes from `sessions.working_directory`, so repo
@@ -576,7 +669,14 @@ assistant messages, appends terminal/file-selection context, and uses bubble
576
669
  timestamps when present. Cursor tool call, tool result, usage, model, status,
577
670
  request id, composer id, and edit/diff-like records are normalized into the
578
671
  shared `metadata.toolCalls[]`, `metadata.toolResult`, and `metadata.usage`
579
- shapes when those fields appear in the stored blobs.
672
+ shapes when those fields appear in the stored blobs. Cursor `tokenCount`
673
+ objects are treated as split usage: `inputTokens` and `outputTokens` map to the
674
+ standard in/out buckets, while Cursor cache aliases such as
675
+ `cacheReadInputTokens` map to `cacheInputTokens`. If a Cursor session has no
676
+ provider-reported token usage, agentlog stores rough `estimatedUsage` for stats
677
+ only. The estimate is based on measured Cursor per-turn medians by model family,
678
+ not transcript length alone; measured `usage` remains reserved for
679
+ provider-reported values.
580
680
 
581
681
  When an old Cursor workspace has no full `bubbles` transcript but still has
582
682
  composer headers plus `aiService` prompt/generation breadcrumbs, agentlog imports
@@ -599,17 +699,26 @@ header/conversation list, loading only the matching bubble rows when needed,
599
699
  ordering bubbles by that list, and using the composer-level timestamps instead of
600
700
  Cursor's migrated bubble timestamps. This is the path that recovers old Cursor UI
601
701
  conversations whose workspace `state.vscdb` now only shows selected composer ids
602
- or prompt history.
702
+ or prompt history. When the composer stores a concrete non-`default`
703
+ `modelConfig`, agentlog applies that model to assistant bubbles that do not carry
704
+ their own model metadata; `default` is intentionally ignored because it is a
705
+ preference pointer rather than the model used at generation time.
603
706
 
604
707
  When the global composer record omits a workspace folder, agentlog cross-checks
605
708
  workspace `composer.composerData` and chat state for the same composer id and
606
709
  uses that workspace folder for repo attribution. It also mines absolute paths
607
- from Cursor bubble context, including object keys such as nested
710
+ from Cursor bubble context, including top-level selections, object keys such as nested
608
711
  `context.mentions.fileSelections["file:///..."]`, `relevantFiles`,
609
712
  `attachedFolders`, workspace URIs, and recently viewed files. When old file
610
713
  paths in the bubble context no longer exist, cwd inference walks up to the
611
714
  nearest existing parent so the session can still resolve to the repo.
612
715
 
716
+ Cursor assistant and bubble records are parsed for visible text, tool calls,
717
+ tool results, token usage, selected model, selected files, terminal selections,
718
+ suggested code blocks, and diff histories. Tool calls and results are normalized
719
+ from common Cursor shapes into the same canonical tool metadata used by the web
720
+ viewer.
721
+
613
722
  During dedupe, richer Cursor sources win over fallback sources. Newer project
614
723
  agent transcripts rank highest, global `cursorDiskKV` composer records rank
615
724
  above workspace SQLite, and `aiService` prompt/apply history ranks as a
@@ -727,8 +836,16 @@ original checkpoint files remain in raw backups.
727
836
 
728
837
  - Import selector: `opencode`
729
838
  - Provider: `opencode`
730
- - Source type: `opencode-history`
839
+ - Source types:
840
+ - `opencode-sqlite-history` for the normalized `opencode.db` store
841
+ - `opencode-history` for the JSON `storage/` layout
731
842
  - Primary data root: `~/.local/share/opencode`
843
+ - Alternate macOS data root: `~/Library/Application Support/opencode`
844
+ - Additional desktop roots:
845
+ - `~/.local/share/ai.opencode.app`
846
+ - `~/Library/Application Support/ai.opencode.app`
847
+ - SQLite database:
848
+ - `opencode.db`
732
849
  - Storage roots:
733
850
  - `~/.local/share/opencode/storage`
734
851
  - `~/.local/share/opencode/project/<project-slug>/storage`
@@ -740,14 +857,29 @@ original checkpoint files remain in raw backups.
740
857
  - `storage/project/<project-id>.json`
741
858
  - Overrides:
742
859
  - `AGENTLOG_OPENCODE_DATA_DIR` overrides the data root.
860
+ - `AGENTLOG_OPENCODE_DB`, `AGENTLOG_OPENCODE_DATABASE`, or `OPENCODE_DB`
861
+ points directly at one or more SQLite databases.
743
862
  - `AGENTLOG_OPENCODE_STORAGE_DIR` or `AGENTLOG_OPENCODE_STORAGE_ROOTS`
744
863
  points directly at one or more `storage` directories.
745
864
 
746
- agentlog reads OpenCode's JSON session store directly. Sessions provide the
865
+ agentlog first reads OpenCode's normalized SQLite store when `opencode.db` is
866
+ present. The `session`, `message`, `part`, and `project` tables provide session
867
+ metadata, working directory, user/assistant messages, reasoning text, tool
868
+ calls, tool outputs, model/provider ids, cost, and token usage. Because the
869
+ database is a multi-session source, raw preservation stores it as a shared raw
870
+ source instead of duplicating the same file into every session archive.
871
+
872
+ agentlog also reads OpenCode's JSON session store directly. Sessions provide the
747
873
  archive id and project id; message and part files provide role text, reasoning
748
874
  text, tool calls, and tool outputs. Tool parts are normalized into
749
875
  `metadata.toolCalls[]` and `metadata.toolResult` records so the web viewer can
750
876
  render them with the same cards used for Codex, Claude, Devin, and Cursor.
877
+ If a session metadata file is missing but `storage/message/<session-id>/` and
878
+ `storage/part/<message-id>/` files remain, agentlog reconstructs a best-effort
879
+ session from those message and part files.
880
+
881
+ 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.
751
883
 
752
884
  When `session_diff/<session-id>.json` is present, agentlog adds a supplementary
753
885
  edit tool call with the diff payload. Unified diff text is rendered inline in
@@ -789,14 +921,31 @@ backups.
789
921
 
790
922
  - Import selector: `windsurf`
791
923
  - Provider: `windsurf`
792
- - Source type: `windsurf-cascade-brain`
924
+ - Source types: `windsurf-trajectory-export`, `windsurf-cascade-brain`
925
+ - Explicit export import: `agentlog import windsurf <downloaded-trajectory.md>`
926
+ or `agentlog import windsurf <folder-of-trajectories>`
793
927
  - Primary readable store: `~/.codeium/windsurf/brain/*`
794
928
  - Binary store counted but not decoded: `~/.codeium/windsurf/cascade/*.pb`
795
- - Status: disabled from setup, default imports, and history filters
796
-
797
- Windsurf support is currently disabled. Current Cascade sessions are written as
798
- encrypted binary stores, so agentlog can detect session IDs and workspace
799
- metadata but cannot archive readable conversation text from the local files.
929
+ - Status: encrypted local cache scanning is disabled from setup, default imports,
930
+ and history filters; downloaded trajectory Markdown exports are importable
931
+
932
+ Windsurf local cache scanning is currently disabled. Current Cascade sessions
933
+ are written as encrypted binary stores, so agentlog can detect session IDs and
934
+ workspace metadata but cannot archive readable conversation text from those
935
+ local files.
936
+
937
+ Windsurf's "Download trajectory" action produces Markdown headed
938
+ `# Cascade Chat Conversation`. Agentlog imports those files explicitly with
939
+ `agentlog import windsurf <path>`. The export is treated as a normalized
940
+ provider transcript surface: `### User Input` sections become user messages,
941
+ `### Planner Response` / assistant-like sections become assistant messages, and
942
+ the original Markdown file is preserved in raw backups.
943
+
944
+ Bulk export tools that automate Windsurf's hidden "Download trajectory" button
945
+ can write many `*.md` files into one directory. Agentlog intentionally treats
946
+ that directory as user-selected export input rather than scanning Windsurf's
947
+ encrypted cache: run `agentlog import windsurf ~/windsurf-cascade-export` after
948
+ the bulk exporter finishes.
800
949
 
801
950
  The older experimental helper can still read Markdown artifacts from Windsurf
802
951
  Cascade brain directories when present. Recognized artifact names are `plan.md`,
@@ -810,10 +959,15 @@ Binary Cascade protobuf stores are counted in discovery details but not decoded.
810
959
 
811
960
  ## Collector And Live Monitoring
812
961
 
813
- `agentlog start` runs the supervisor. The current supervisor periodically imports
814
- the watcher source list selected during init and can run archive sync. The
815
- collector path accepts OTLP JSON and stores telemetry payloads under the archive
816
- telemetry directory.
962
+ `agentlog watcher start` runs the supervisor, which is agentlog's local background
963
+ watcher. It periodically imports the watcher source list selected during init
964
+ and can run archive sync. If a user opts out of starting the watcher at login
965
+ by unchecking `Start watcher at login` or running `agentlog init --no-autostart`,
966
+ agentlog still works in manual mode: `agentlog import --source all` performs a
967
+ one-time catch-up, `agentlog watcher start` watches until stopped, and
968
+ `agentlog watcher login enable` can install the login item later. The collector path
969
+ accepts OTLP JSON and stores telemetry payloads under the archive telemetry
970
+ directory.
817
971
  For Cursor, the supervisor handles incremental logs going forward; explicit
818
972
  full imports handle raw SQLite recovery/backfill.
819
973
 
@@ -827,7 +981,8 @@ as importing transcript history.
827
981
 
828
982
  - ChatGPT and Claude.ai are import-by-export only; agentlog does not read their
829
983
  desktop app local stores.
830
- - Windsurf is disabled because Cascade protobuf transcripts appear encrypted.
984
+ - Windsurf encrypted cache scanning is disabled; downloaded trajectory Markdown
985
+ exports are supported.
831
986
  - Antigravity protobuf transcripts are counted but not decoded.
832
987
  - Cursor older `state.vscdb` stores are best-effort because Cursor has changed
833
988
  local storage layouts over time.
package/docs/release.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Release Checklist
2
2
 
3
- Use this checklist before publishing the `agentlogs` npm package.
3
+ Use this checklist before publishing the `agentel` npm package.
4
4
 
5
5
  ## Prerequisites
6
6
 
7
- - Confirm the npm publishing account can publish `agentlogs`.
7
+ - Confirm the npm publishing account can publish `agentel`.
8
8
  - Confirm `https://github.com/brianlzhou/agentlog` is reachable for GitHub
9
9
  shorthand installs such as `npm install -g brianlzhou/agentlog`.
10
10
  - Use Node.js 20 or newer.
@@ -43,7 +43,7 @@ home/config directories:
43
43
 
44
44
  ```sh
45
45
  agentlog help
46
- agentlogs help
46
+ agentel help
47
47
  agentlog init --yes --skip-import --no-autostart --no-claude --no-recall --no-telemetry
48
48
  agentlog doctor --json
49
49
  ```
@@ -53,17 +53,17 @@ agentlog doctor --json
53
53
  When the checks pass, publish from a clean working tree:
54
54
 
55
55
  ```sh
56
- npm publish --access public
56
+ npm publish
57
57
  ```
58
58
 
59
59
  For the first public release, use npm 2FA or trusted publishing. The package
60
- name is plural (`agentlogs`) so it can coexist with the singular CLI command.
60
+ name is `agentel` so it can coexist with the singular CLI command.
61
61
  Keep the `agentlog` binary for normal usage; the package also ships an
62
- `agentlogs` binary alias so `npx agentlogs init` works.
62
+ `agentel` binary alias so `npx agentel init` works.
63
63
 
64
64
  After tagging and pushing the release, sanity-check both public install forms:
65
65
 
66
66
  ```sh
67
- npm install -g agentlogs
68
- npm install -g brianlzhou/agentlog#v0.2.0
67
+ npm install -g agentel
68
+ npm install -g brianlzhou/agentlog#v0.2.2
69
69
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentel",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Local-first archive and recall layer for agent coding sessions.",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
@@ -29,9 +29,9 @@
29
29
  "recall"
30
30
  ],
31
31
  "bin": {
32
- "agentlog": "./bin/agentlog.js",
33
- "agentlog-recall": "./bin/agentlog-recall.js",
34
- "agentel": "./bin/agentlog.js"
32
+ "agentlog": "bin/agentlog.js",
33
+ "agentlog-recall": "bin/agentlog-recall.js",
34
+ "agentel": "bin/agentlog.js"
35
35
  },
36
36
  "files": [
37
37
  "bin/",
@@ -46,6 +46,7 @@
46
46
  "scripts": {
47
47
  "prepack": "npm run check && npm test",
48
48
  "pack:dry": "npm pack --dry-run",
49
+ "prepare:update": "node scripts/prepare-update.js",
49
50
  "smoke:pack": "node scripts/smoke-pack.js",
50
51
  "test": "node --test",
51
52
  "check": "node scripts/check-syntax.js"