somtum 2.2.0 → 3.0.0

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.
Files changed (81) hide show
  1. package/README.md +66 -78
  2. package/dist/agents/claude_code.d.ts +3 -0
  3. package/dist/agents/claude_code.d.ts.map +1 -0
  4. package/dist/agents/claude_code.js +112 -0
  5. package/dist/agents/claude_code.js.map +1 -0
  6. package/dist/agents/codex.d.ts +3 -0
  7. package/dist/agents/codex.d.ts.map +1 -0
  8. package/dist/agents/codex.js +173 -0
  9. package/dist/agents/codex.js.map +1 -0
  10. package/dist/agents/index.d.ts +7 -0
  11. package/dist/agents/index.d.ts.map +1 -0
  12. package/dist/agents/index.js +24 -0
  13. package/dist/agents/index.js.map +1 -0
  14. package/dist/agents/shared.d.ts +3 -0
  15. package/dist/agents/shared.d.ts.map +1 -0
  16. package/dist/agents/shared.js +18 -0
  17. package/dist/agents/shared.js.map +1 -0
  18. package/dist/agents/types.d.ts +11 -0
  19. package/dist/agents/types.d.ts.map +1 -0
  20. package/dist/agents/types.js +2 -0
  21. package/dist/agents/types.js.map +1 -0
  22. package/dist/cli/doctor.d.ts.map +1 -1
  23. package/dist/cli/doctor.js +41 -56
  24. package/dist/cli/doctor.js.map +1 -1
  25. package/dist/cli/hook.d.ts.map +1 -1
  26. package/dist/cli/hook.js +2 -5
  27. package/dist/cli/hook.js.map +1 -1
  28. package/dist/cli/index.js +3 -1
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/cli/init.d.ts +19 -0
  31. package/dist/cli/init.d.ts.map +1 -1
  32. package/dist/cli/init.js +40 -31
  33. package/dist/cli/init.js.map +1 -1
  34. package/dist/cli/init_codex.d.ts +12 -0
  35. package/dist/cli/init_codex.d.ts.map +1 -0
  36. package/dist/cli/init_codex.js +53 -0
  37. package/dist/cli/init_codex.js.map +1 -0
  38. package/dist/cli/suggest_claude_md.js.map +1 -1
  39. package/dist/cli/ui.d.ts +1 -1
  40. package/dist/cli/ui.d.ts.map +1 -1
  41. package/dist/cli/ui.js +1 -1
  42. package/dist/cli/ui.js.map +1 -1
  43. package/dist/core/cache.d.ts +5 -0
  44. package/dist/core/cache.d.ts.map +1 -1
  45. package/dist/core/cache.js +17 -0
  46. package/dist/core/cache.js.map +1 -1
  47. package/dist/core/db.d.ts.map +1 -1
  48. package/dist/core/db.js +9 -0
  49. package/dist/core/db.js.map +1 -1
  50. package/dist/core/extractor.d.ts +1 -0
  51. package/dist/core/extractor.d.ts.map +1 -1
  52. package/dist/core/extractor.js +93 -47
  53. package/dist/core/extractor.js.map +1 -1
  54. package/dist/core/llm_backend.d.ts +7 -0
  55. package/dist/core/llm_backend.d.ts.map +1 -0
  56. package/dist/core/llm_backend.js +44 -0
  57. package/dist/core/llm_backend.js.map +1 -0
  58. package/dist/core/memory_files.d.ts.map +1 -1
  59. package/dist/core/memory_files.js +2 -3
  60. package/dist/core/memory_files.js.map +1 -1
  61. package/dist/core/schema.d.ts +14 -4
  62. package/dist/core/schema.d.ts.map +1 -1
  63. package/dist/core/schema.js +4 -0
  64. package/dist/core/schema.js.map +1 -1
  65. package/dist/core/transcript.d.ts.map +1 -1
  66. package/dist/core/transcript.js +14 -77
  67. package/dist/core/transcript.js.map +1 -1
  68. package/dist/dashboard/index.html +1 -1
  69. package/dist/hooks/post_session.d.ts +5 -5
  70. package/dist/hooks/post_session.d.ts.map +1 -1
  71. package/dist/hooks/post_session.js +48 -38
  72. package/dist/hooks/post_session.js.map +1 -1
  73. package/dist/hooks/pre_prompt.d.ts +5 -0
  74. package/dist/hooks/pre_prompt.d.ts.map +1 -1
  75. package/dist/hooks/pre_prompt.js +60 -8
  76. package/dist/hooks/pre_prompt.js.map +1 -1
  77. package/dist/index.d.ts +1 -1
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +1 -1
  80. package/dist/index.js.map +1 -1
  81. package/package.json +6 -2
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  <img src="./assets/logo.png" width="500" alt="Somtum Logo">
2
2
 
3
- **Local-first memory and prompt-cache layer for Claude Code.**
3
+ **Local-first memory and prompt-cache layer for coding agents: Claude Code and Codex.**
4
4
 
5
5
  [**Docs**](https://riz007.github.io/somtum/) · [**npm**](https://www.npmjs.com/package/somtum)
6
6
 
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
8
  [![npm version](https://badge.fury.io/js/somtum.svg)](https://www.npmjs.com/package/somtum)
9
9
 
10
- Somtum (Thai: ส้มตำ) is named after the vibrant, shredded green papaya salad. Just like its namesake, Somtum blends durable observations from your Claude Code sessions — decisions, bugfixes, learnings, file summaries — stores them in a local SQLite database, and injects the relevant ones back into context the next time you work on the same project.
10
+ Somtum (Thai: ส้มตำ) is named after the vibrant, shredded green papaya salad. Just like its namesake, Somtum blends durable observations from your Claude Code and Codex sessions — decisions, bugfixes, learnings, file summaries — stores them in a local SQLite database, and injects the relevant ones back into context the next time you work on the same project.
11
11
 
12
12
  Zero-config: one `somtum init` and every session end is captured automatically. No server, no cloud account, no mandatory tuning.
13
13
 
@@ -33,6 +33,8 @@ Zero-config: one `somtum init` and every session end is captured automatically.
33
33
  - [Troubleshooting](#troubleshooting)
34
34
  - [License](#license)
35
35
 
36
+ > **v3.0.0** — Codex support (`somtum init --agent codex`) · selectable extraction backends incl. Codex CLI and GLM · fixes silently lost sessions and oversized extraction calls · [upgrade guide](https://riz007.github.io/somtum/guide/upgrading-v3)
37
+ >
36
38
  > **v2.0.0** — Global DB (`~/.somtum/global.db`) · cross-project workspace recall · memory deduplication (`superseded_by`) · `--show-superseded` on `somtum list` · stats instrumentation fix · dashboard dark-mode redesign
37
39
  >
38
40
  > **v1.5.0** — Multi-page VitePress docs site · `somtum list` · `somtum reset` · `somtum forget --all` · embeddings timeout safety · config crash-resilience · `injection.max_chars` wired up · warm-start race fix · auth-error hints
@@ -43,13 +45,13 @@ Zero-config: one `somtum init` and every session end is captured automatically.
43
45
 
44
46
  ## Why Somtum?
45
47
 
46
- LLM agents like Claude Code start every session with a blank slate. That leads to:
48
+ Coding agents like Claude Code and Codex start every session with a blank slate. That leads to:
47
49
 
48
50
  - **Repetitive context** — re-explaining the same architectural choices every session
49
- - **Regressions** — Claude suggests a fix you already tried and discarded
51
+ - **Regressions** — the agent suggests a fix you already tried and discarded
50
52
  - **Token waste** — reading large files just to "set the scene"
51
53
 
52
- **Somtum gives Claude a long-term memory.** Once a decision is made or a bug is fixed, it's remembered across all future sessions — without bloating your context window.
54
+ **Somtum gives your coding agent a long-term memory.** Once a decision is made or a bug is fixed, it's remembered across all future sessions, in Claude Code and Codex alike, without bloating your context window.
53
55
 
54
56
  ### What a session looks like with Somtum
55
57
 
@@ -69,13 +71,13 @@ Session 2: Claude suggests Session 2: Claude already knows about
69
71
 
70
72
  ## How it works
71
73
 
72
- At the end of each Claude Code session, Somtum reads the session transcript and asks Claude Haiku to extract the parts worth keeping — decisions, bug fixes, things learned. Those observations are stored locally in SQLite. **On every subsequent prompt**, Somtum automatically retrieves the most relevant memories and injects them into context — no manual recall needed.
74
+ At the end of each Claude Code or Codex session, Somtum reads the session transcript and asks a small model to extract the parts worth keeping — decisions, bug fixes, things learned. Those observations are stored locally in SQLite. **On every subsequent prompt**, Somtum automatically retrieves the most relevant memories and injects them into context — no manual recall needed.
73
75
 
74
76
  ### Memory lifecycle
75
77
 
76
78
  ```
77
79
  ┌─────────────────────────────────────────────────────────────┐
78
- │ Claude Code Session │
80
+ │ Claude Code or Codex session │
79
81
  │ │
80
82
  │ you code · debug · review · make decisions │
81
83
  └──────────────────────────────┬──────────────────────────────┘
@@ -134,13 +136,13 @@ You work a session debugging an auth bug and refactoring a module. At session en
134
136
  ]
135
137
  ```
136
138
 
137
- Next session, when you ask "why are we using pnpm?" or touch `src/auth/refresh.ts`, Claude finds these memories and already has the context.
139
+ Next session, when you ask "why are we using pnpm?" or touch `src/auth/refresh.ts`, the agent gets these memories and already has the context.
138
140
 
139
141
  ### Architecture
140
142
 
141
143
  ```
142
144
  ┌─────────────────────────────────────────────────────────────┐
143
- │ Claude Code / Agent │
145
+ │ Claude Code / Codex / MCP client │
144
146
  └──────────┬──────────────────────────────┬───────────────────┘
145
147
  │ hooks │ MCP tools
146
148
  ▼ ▼
@@ -206,8 +208,13 @@ Next session, when you ask "why are we using pnpm?" or touch `src/auth/refresh.t
206
208
  ## Requirements
207
209
 
208
210
  - **Node 20+**
209
- - **Claude Code** — Somtum hooks into Claude Code's `SessionEnd`, `UserPromptSubmit`, and `PreToolUse` events
210
- - **`ANTHROPIC_API_KEY`** _(optional)_ — if set, Somtum uses the Anthropic API directly for extraction. If not set, Somtum falls back to the `claude` CLI that ships with Claude Code, so **no separate API key is required for Claude Code subscribers**.
211
+ - **Claude Code or Codex** — Somtum hooks into their `SessionEnd`, `PreCompact` and `UserPromptSubmit` events. Both agents share one memory store per project.
212
+ - **An extraction backend**, picked automatically in this order:
213
+ 1. `ANTHROPIC_API_KEY`, or `ANTHROPIC_AUTH_TOKEN` + `ANTHROPIC_BASE_URL` for Anthropic-compatible providers such as GLM
214
+ 2. the `claude` CLI (Claude Code subscribers need no separate key)
215
+ 3. the `codex` CLI (ChatGPT/Codex subscribers need no separate key)
216
+
217
+ Override with `somtum config set extraction.backend anthropic|claude-cli|codex-cli`.
211
218
 
212
219
  ---
213
220
 
@@ -239,69 +246,47 @@ Somtum uses [`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3), whic
239
246
 
240
247
  ## Quickstart
241
248
 
242
- ### Before you begin — pick your setup
243
-
244
- **Using Claude Code (subscription)?**
245
- You do not need an API key. Somtum calls the `claude` CLI that ships with Claude Code.
246
- Confirm it is installed: `which claude`
247
- If nothing prints, reinstall Claude Code or add its binary to your PATH.
248
-
249
- **Using the Anthropic API directly?**
250
- Add your key to your shell profile (not just the current terminal tab):
251
-
252
- ```bash
253
- # Add to ~/.zshrc or ~/.bashrc
254
- export ANTHROPIC_API_KEY="sk-ant-..."
255
- source ~/.zshrc
256
- ```
257
-
258
- Both paths work. Most Claude Code users should use Option A.
259
-
260
- ---
261
-
262
- ### Step 1 — Choose your extraction backend
249
+ ### Step 1 — Check your extraction backend
263
250
 
264
- Somtum needs to call a Claude model at session end to extract observations. Pick one:
251
+ At the end of each session Somtum asks a small model to pull out what's worth remembering. It uses the first backend available, so most people need to do nothing:
265
252
 
266
- **Option A: Claude Code subscription (no extra setup)**
253
+ | You have | Backend used |
254
+ | --- | --- |
255
+ | `ANTHROPIC_API_KEY` in your shell profile | Anthropic API (Haiku) |
256
+ | `ANTHROPIC_AUTH_TOKEN` + `ANTHROPIC_BASE_URL` (GLM or another Anthropic-compatible provider) | that provider |
257
+ | Claude Code installed (`which claude` prints a path) | `claude` CLI, on your subscription |
258
+ | Codex installed (`which codex` prints a path) | `codex` CLI, on your ChatGPT plan |
267
259
 
268
- If you already have Claude Code installed, you're done. Somtum calls `claude --print` automatically when no API key is present. Skip to Step 2.
260
+ > Keys must be in your shell profile, not just exported in an open terminal tab. Hooks inherit the environment of the shell that _started_ the agent.
269
261
 
270
- **Option B: Direct Anthropic API key (optional — faster, lets you pick the model)**
262
+ ### Step 2 — Install in your project
271
263
 
272
- Add to `~/.zshrc` (or `~/.bashrc`):
273
-
274
- ```bash
275
- export ANTHROPIC_API_KEY="sk-ant-..."
276
- ```
264
+ Run from the **root of the project you open in your agent**.
277
265
 
278
- Then reload:
266
+ **Claude Code**
279
267
 
280
268
  ```bash
281
- source ~/.zshrc
269
+ somtum init --all
270
+ # Installs:
271
+ # - SessionEnd + PreCompact capture hooks (memory extraction)
272
+ # - UserPromptSubmit hook (auto-inject + prompt cache)
273
+ # - PreToolUse file-gating hook (large file summarization)
274
+ # - MCP server in .mcp.json (recall/remember tools)
282
275
  ```
283
276
 
284
- > The key must be in your shell profile, not just exported in an open terminal tab. The `SessionEnd` hook inherits the environment of the shell that _started_ Claude Code — not the current terminal.
277
+ > Use `--all`. A plain `somtum init` installs only the capture hooks: memories are saved but not injected, and the agent sees them only if it calls the MCP `recall` tool.
285
278
 
286
- ### Step 2 — Install inside a Claude Code project
287
-
288
- Run this from the **root of the project you work on with Claude Code**:
279
+ **Codex** (or both, on the same project; they share one memory store):
289
280
 
290
281
  ```bash
291
- somtum init
292
- ```
293
-
294
- To enable all features at once (recommended):
295
-
296
- ```bash
297
- somtum init --all
282
+ somtum init --agent codex
298
283
  # Installs:
299
- # - SessionEnd capture hook (memory extraction)
300
- # - UserPromptSubmit cache hook (prompt cache lookup)
301
- # - PreToolUse file-gating hook (large file summarization)
302
- # - MCP server in .mcp.json (Claude can call recall/remember tools)
284
+ # - .codex/hooks.json SessionEnd + PreCompact capture, UserPromptSubmit injection
285
+ # - .codex/config.toml [mcp_servers.somtum]
303
286
  ```
304
287
 
288
+ Codex only loads project-level config for trusted projects. Sessions are read from `~/.codex/sessions` (or `$CODEX_HOME/sessions`).
289
+
305
290
  ### Step 3 — Verify your setup
306
291
 
307
292
  Run doctor immediately after init to confirm everything is connected:
@@ -312,14 +297,14 @@ somtum doctor
312
297
 
313
298
  All checks should show `✓`. The two most important are:
314
299
 
315
- - **`api_key`** — confirms Somtum has a way to call Claude for extraction
316
- - **`hooks_installed`** — confirms the SessionEnd hook is registered
300
+ - **`extraction_backend`** — confirms Somtum has a model to extract memories with
301
+ - **`hooks_installed`** — confirms hooks are registered for Claude Code, Codex, or both
317
302
 
318
303
  Do not start your first session until all checks pass. Each failing check shows an inline fix command.
319
304
 
320
- ### Step 4 — Use Claude Code normally
305
+ ### Step 4 — Use your agent normally
321
306
 
322
- Open a Claude Code session **from the same directory** where you ran `somtum init`. Work as you normally would. When the session ends, the hook extracts observations automatically in the background (capped at 90 seconds).
307
+ Open Claude Code or Codex **from the same directory** where you ran `somtum init`. Work as you normally would. When the session ends, the hook extracts observations automatically in the background (capped at 90 seconds).
323
308
 
324
309
  ### Step 5 — Check your memory
325
310
 
@@ -341,7 +326,7 @@ If `somtum stats` shows `memories 0` after a session, see [Troubleshooting](#tro
341
326
 
342
327
  ## Verifying the setup
343
328
 
344
- After your **first** Claude Code session ends:
329
+ After your **first** session ends:
345
330
 
346
331
  **1. Check the hook log**
347
332
 
@@ -356,18 +341,16 @@ A successful run:
356
341
  2026-04-30T10:15:44.891Z [post_session] ok — inserted=4 superseded=1 cache=2 summaries=1
357
342
  ```
358
343
 
359
- Using the `claude` CLI fallback (no API key):
344
+ Each run also logs which backend it used:
360
345
 
361
346
  ```
362
- 2026-04-30T10:15:42.123Z [post_session] starting
363
- 2026-04-30T10:15:42.124Z [post_session] ANTHROPIC_API_KEY not set — will use claude CLI fallback
364
- 2026-04-30T10:15:44.891Z [post_session] ok — inserted=4 superseded=1 cache=2 summaries=1
347
+ 2026-04-30T10:15:42.124Z [post_session] extraction backend: claude-cli
365
348
  ```
366
349
 
367
350
  Neither backend available:
368
351
 
369
352
  ```
370
- 2026-04-30T10:15:42.123Z [post_session] ERROR: Neither ANTHROPIC_API_KEY nor the claude CLI is available.
353
+ 2026-04-30T10:15:42.123Z [post_session] ERROR: No extraction backend: set ANTHROPIC_API_KEY (or ANTHROPIC_AUTH_TOKEN + ANTHROPIC_BASE_URL), or install the claude or codex CLI.
371
354
  ```
372
355
 
373
356
  **2. Check stats**
@@ -496,9 +479,9 @@ Somtum uses hostname-aware syncing — merging observations from multiple machin
496
479
 
497
480
  ## MCP Server
498
481
 
499
- When you run `somtum init --all`, Somtum registers an MCP server that Claude can call autonomously during a session:
482
+ When you run `somtum init --all` (Claude Code) or `somtum init --agent codex`, Somtum registers an MCP server the agent can call on its own during a session. Any other MCP client can use it too: point it at `somtum mcp` over stdio.
500
483
 
501
- | Tool | What Claude does with it |
484
+ | Tool | What the agent does with it |
502
485
  | ------------------- | --------------------------------------------------------------------------------------------------------------- |
503
486
  | `recall` | Searches memories when unsure about a project detail. Merges project + global DB results. Accepts `strategy` |
504
487
  | `get` | Retrieves full observation bodies by ID. Checks global DB if not found in project DB. Bumps `last_confirmed_at` |
@@ -509,7 +492,7 @@ When you run `somtum init --all`, Somtum registers an MCP server that Claude can
509
492
  | `forget` | Soft-deletes an observation |
510
493
  | `stats` | Reports tokens saved, cache hit rate, false-hit count, corpus size, and `global_memories` count |
511
494
 
512
- Every MCP response includes a `tokens` field so Claude can account for retrieval cost.
495
+ Every MCP response includes a `tokens` field so the agent can account for retrieval cost.
513
496
 
514
497
  ### Memory scope
515
498
 
@@ -581,6 +564,10 @@ somtum config set file_gating.enabled false
581
564
  # Limit observations extracted per session (default: 10)
582
565
  somtum config set extraction.max_observations_per_session 5
583
566
 
567
+ # Pin the extraction backend (default: auto) and the model codex exec uses
568
+ somtum config set extraction.backend codex-cli
569
+ somtum config set extraction.codex_model <model>
570
+
584
571
  # Control automatic memory injection on every prompt (default: on)
585
572
  somtum config set injection.enabled false # turn off auto-inject
586
573
  somtum config set injection.k 5 # inject more memories (default: 3)
@@ -725,7 +712,8 @@ src/
725
712
  store.ts # MemoryStore — CRUD for observations
726
713
  cache.ts # PromptCache — exact + fuzzy lookup
727
714
  retriever/ # bm25, embeddings, hybrid, index, factory
728
- extractor.ts # session transcript → observations (Claude Haiku)
715
+ extractor.ts # session transcript → observations
716
+ llm_backend.ts # picks the extraction backend
729
717
  index_gen.ts # renders index.md (incremental past 1k obs)
730
718
  memory_files.ts # writes memories/<YYYY-MM>/<ulid>.md
731
719
  retrieval_stats.ts
@@ -774,18 +762,18 @@ Check the hook log first:
774
762
  cat ~/.somtum/hook.log
775
763
  ```
776
764
 
777
- **`claude` CLI not found and no `ANTHROPIC_API_KEY` set**
765
+ **No extraction backend**
778
766
 
779
- - If you use Claude Code: run `which claude` — if nothing prints, reinstall Claude Code or add its binary to your `PATH`.
780
- - If you prefer the direct API: add `export ANTHROPIC_API_KEY="sk-ant-..."` to `~/.zshrc` and `source ~/.zshrc`. Must be in your profile, not just exported in the current terminal tab.
767
+ - Claude Code users: run `which claude`. Codex users: run `which codex`. If nothing prints, install the CLI or add it to your `PATH`.
768
+ - API users: add `export ANTHROPIC_API_KEY="sk-ant-..."` to `~/.zshrc` and `source ~/.zshrc`. It must be in your profile, not just exported in the current terminal tab.
781
769
 
782
- Run `somtum doctor` — the `api_key` check tells you exactly which backend is available.
770
+ Run `somtum doctor`: the `extraction_backend` check shows which backend will be used.
783
771
 
784
772
  **Hook not installed in the right directory**
785
773
 
786
- `somtum init` writes the hook to `.claude/settings.json` in the directory where you ran it. If you launch Claude Code from a different directory, it reads a different settings file.
774
+ `somtum init` writes hooks into the directory where you ran it (`.claude/settings.json` or `.codex/hooks.json`). If you launch the agent from a different directory, it reads different settings.
787
775
 
788
- Fix: run `somtum init` from the same directory you use to launch Claude Code.
776
+ Fix: run `somtum init` from the same directory you launch the agent from.
789
777
 
790
778
  ```bash
791
779
  cd ~/my-project
@@ -0,0 +1,3 @@
1
+ import type { AgentAdapter } from './types.js';
2
+ export declare const claudeCode: AgentAdapter;
3
+ //# sourceMappingURL=claude_code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude_code.d.ts","sourceRoot":"","sources":["../../src/agents/claude_code.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAiH/C,eAAO,MAAM,UAAU,EAAE,YAKxB,CAAC"}
@@ -0,0 +1,112 @@
1
+ import { truncateToolInput, truncateToolResult } from './shared.js';
2
+ const FILE_TOOL_NAMES = new Set(['Read', 'Edit', 'Write', 'NotebookEdit']);
3
+ // Claude Code transcripts deliver tool results as user-role messages whose
4
+ // content is tool_result blocks. Those are not real user prompts: treating
5
+ // them as such splits prompt→response pairs at every tool call and pollutes
6
+ // the cache. Detect them so they can be reclassified as role 'tool'.
7
+ function isToolResultContent(content) {
8
+ if (!Array.isArray(content))
9
+ return false;
10
+ let sawToolResult = false;
11
+ for (const block of content) {
12
+ if (block == null || typeof block !== 'object')
13
+ continue;
14
+ const t = block.type;
15
+ if (t === 'tool_result')
16
+ sawToolResult = true;
17
+ else if (t === 'text')
18
+ return false;
19
+ }
20
+ return sawToolResult;
21
+ }
22
+ function extractFilesFromBlock(block) {
23
+ if (block == null || typeof block !== 'object')
24
+ return [];
25
+ const b = block;
26
+ if (b.type !== 'tool_use' || b.name === undefined)
27
+ return [];
28
+ if (!FILE_TOOL_NAMES.has(b.name))
29
+ return [];
30
+ const input = b.input;
31
+ const p = input?.file_path ?? input?.notebook_path;
32
+ return typeof p === 'string' && p.length > 0 ? [p] : [];
33
+ }
34
+ function coerceContent(content) {
35
+ if (typeof content === 'string')
36
+ return { text: content, files: [] };
37
+ if (Array.isArray(content)) {
38
+ const files = [];
39
+ const text = content
40
+ .map((block) => {
41
+ if (block == null)
42
+ return '';
43
+ if (typeof block === 'string')
44
+ return block;
45
+ if (typeof block === 'object' &&
46
+ 'text' in block &&
47
+ typeof block.text === 'string') {
48
+ return block.text;
49
+ }
50
+ if (typeof block === 'object' &&
51
+ 'type' in block &&
52
+ block.type === 'tool_use') {
53
+ const b = block;
54
+ files.push(...extractFilesFromBlock(block));
55
+ return `[tool_use ${b.name ?? ''} ${truncateToolInput(JSON.stringify(b.input ?? {}))}]`;
56
+ }
57
+ if (typeof block === 'object' &&
58
+ 'type' in block &&
59
+ block.type === 'tool_result') {
60
+ const b = block;
61
+ return `[tool_result ${truncateToolResult(coerceContent(b.content).text)}]`;
62
+ }
63
+ return '';
64
+ })
65
+ .filter((s) => s.length > 0)
66
+ .join('\n');
67
+ return { text, files };
68
+ }
69
+ return { text: '', files: [] };
70
+ }
71
+ function parse(raw) {
72
+ const lines = raw.split(/\r?\n/).filter((l) => l.trim().length > 0);
73
+ const turns = [];
74
+ for (const line of lines) {
75
+ let obj;
76
+ try {
77
+ obj = JSON.parse(line);
78
+ }
79
+ catch {
80
+ continue;
81
+ }
82
+ // Meta lines (caveats, command wrappers) and sidechain (subagent) turns
83
+ // are not part of the main conversation.
84
+ if (obj.isMeta === true || obj.isSidechain === true)
85
+ continue;
86
+ let role = (obj.message?.role ?? obj.role ?? obj.type ?? 'user');
87
+ if (role !== 'user' && role !== 'assistant' && role !== 'system' && role !== 'tool')
88
+ continue;
89
+ const content = obj.message?.content ?? obj.content;
90
+ if (role === 'user' && isToolResultContent(content))
91
+ role = 'tool';
92
+ const { text, files } = coerceContent(content);
93
+ if (text.length === 0)
94
+ continue;
95
+ const turn = { role, text };
96
+ if (obj.timestamp)
97
+ turn.timestamp = obj.timestamp;
98
+ if (files.length > 0)
99
+ turn.files_touched = files;
100
+ turns.push(turn);
101
+ }
102
+ return turns;
103
+ }
104
+ // Claude Code is the fallback format: generic {role, content} JSONL parses
105
+ // correctly through it, so detect() accepts anything.
106
+ export const claudeCode = {
107
+ id: 'claude-code',
108
+ name: 'Claude Code',
109
+ detect: () => true,
110
+ parse,
111
+ };
112
+ //# sourceMappingURL=claude_code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude_code.js","sourceRoot":"","sources":["../../src/agents/claude_code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AgentAdapter } from './types.js';
2
+ export declare const codex: AgentAdapter;
3
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/agents/codex.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA6K/C,eAAO,MAAM,KAAK,EAAE,YAMnB,CAAC"}
@@ -0,0 +1,173 @@
1
+ import { existsSync, readdirSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { truncateToolInput, truncateToolResult } from './shared.js';
5
+ // User-role blocks Codex injects itself: environment, AGENTS.md, permissions,
6
+ // app state. Most are one <snake_case> tag wrapping the whole block, and new
7
+ // ones keep appearing, so match that shape as well as the known prefixes.
8
+ const INJECTED_PREFIXES = ['# AGENTS.md instructions', '<permissions'];
9
+ const INJECTED_TAG_BLOCK = /^<([a-z]+(?:_[a-z]+)+)>[\s\S]*<\/\1>$/;
10
+ // IDE extensions wrap the prompt as "# Context from my IDE setup: ...
11
+ // ## My request for Codex:\n<prompt>". The heading text varies by version.
12
+ const IDE_CONTEXT_PREFIX = '# Context from my IDE setup';
13
+ const IDE_REQUEST_MARKER = /^## My request[^\n]*:\n/m;
14
+ const PATCH_FILE_LINE = /^\*\*\* (?:Add|Update|Delete) File: (.+)$/gm;
15
+ function userText(blocks) {
16
+ const parts = [];
17
+ for (const b of blocks) {
18
+ const text = b.text?.trim();
19
+ if (!text)
20
+ continue;
21
+ if (INJECTED_PREFIXES.some((p) => text.startsWith(p)))
22
+ continue;
23
+ if (INJECTED_TAG_BLOCK.test(text))
24
+ continue;
25
+ if (text.startsWith(IDE_CONTEXT_PREFIX)) {
26
+ const m = IDE_REQUEST_MARKER.exec(text);
27
+ if (m)
28
+ parts.push(text.slice(m.index + m[0].length).trim());
29
+ continue;
30
+ }
31
+ parts.push(text);
32
+ }
33
+ return parts.join('\n');
34
+ }
35
+ function assistantText(blocks) {
36
+ return blocks
37
+ .map((b) => b.text ?? '')
38
+ .filter((t) => t.length > 0)
39
+ .join('\n');
40
+ }
41
+ function asText(value) {
42
+ if (typeof value === 'string')
43
+ return value;
44
+ if (value === undefined || value === null)
45
+ return '';
46
+ return JSON.stringify(value);
47
+ }
48
+ function patchedFiles(patch) {
49
+ return [...patch.matchAll(PATCH_FILE_LINE)].map((m) => m[1].trim());
50
+ }
51
+ // Guardian reviews and other subagent threads get their own rollout file.
52
+ // They are Codex talking to itself, not the user's session.
53
+ function isSubagentSession(meta) {
54
+ const threadSource = meta['thread_source'];
55
+ if (typeof threadSource === 'string' && threadSource !== 'user')
56
+ return true;
57
+ return typeof meta['source'] === 'object' && meta['source'] !== null;
58
+ }
59
+ function toTurn(line) {
60
+ const p = line.payload ?? {};
61
+ let turn = null;
62
+ switch (p['type']) {
63
+ case 'message': {
64
+ const blocks = (Array.isArray(p['content']) ? p['content'] : []);
65
+ if (p['role'] === 'user') {
66
+ const text = userText(blocks);
67
+ if (text)
68
+ turn = { role: 'user', text };
69
+ }
70
+ else if (p['role'] === 'assistant') {
71
+ const text = assistantText(blocks);
72
+ if (text)
73
+ turn = { role: 'assistant', text };
74
+ }
75
+ break;
76
+ }
77
+ case 'function_call':
78
+ turn = {
79
+ role: 'assistant',
80
+ text: `[tool_use ${asText(p['name'])} ${truncateToolInput(asText(p['arguments']))}]`,
81
+ };
82
+ break;
83
+ case 'custom_tool_call': {
84
+ const input = asText(p['input']);
85
+ turn = {
86
+ role: 'assistant',
87
+ text: `[tool_use ${asText(p['name'])} ${truncateToolInput(input)}]`,
88
+ };
89
+ if (p['name'] === 'apply_patch') {
90
+ const files = patchedFiles(input);
91
+ if (files.length > 0)
92
+ turn.files_touched = files;
93
+ }
94
+ break;
95
+ }
96
+ case 'function_call_output':
97
+ case 'custom_tool_call_output':
98
+ turn = { role: 'tool', text: `[tool_result ${truncateToolResult(asText(p['output']))}]` };
99
+ break;
100
+ }
101
+ if (turn && line.timestamp)
102
+ turn.timestamp = line.timestamp;
103
+ return turn;
104
+ }
105
+ function parse(raw) {
106
+ const turns = [];
107
+ for (const lineText of raw.split(/\r?\n/)) {
108
+ if (lineText.trim().length === 0)
109
+ continue;
110
+ let line;
111
+ try {
112
+ line = JSON.parse(lineText);
113
+ }
114
+ catch {
115
+ continue;
116
+ }
117
+ if (line.type === 'session_meta' && isSubagentSession(line.payload ?? {}))
118
+ return [];
119
+ if (line.type !== 'response_item')
120
+ continue;
121
+ const turn = toTurn(line);
122
+ if (turn)
123
+ turns.push(turn);
124
+ }
125
+ return turns;
126
+ }
127
+ function detect(raw) {
128
+ const nl = raw.indexOf('\n');
129
+ const firstLine = (nl === -1 ? raw : raw.slice(0, nl)).trim();
130
+ try {
131
+ const obj = JSON.parse(firstLine);
132
+ return ((obj.type === 'session_meta' || obj.type === 'response_item') &&
133
+ typeof obj.payload === 'object');
134
+ }
135
+ catch {
136
+ return false;
137
+ }
138
+ }
139
+ function sessionsDir() {
140
+ return join(process.env['CODEX_HOME'] ?? join(homedir(), '.codex'), 'sessions');
141
+ }
142
+ // Codex hooks may send transcript_path: null. Rollout filenames end in the
143
+ // session id, so search the date folders newest-first.
144
+ function findTranscript(sessionId) {
145
+ const root = sessionsDir();
146
+ if (!existsSync(root))
147
+ return null;
148
+ const suffix = `${sessionId}.jsonl`;
149
+ const newestFirst = (dir) => readdirSync(dir).sort().reverse();
150
+ try {
151
+ for (const y of newestFirst(root)) {
152
+ for (const m of newestFirst(join(root, y))) {
153
+ for (const d of newestFirst(join(root, y, m))) {
154
+ const hit = readdirSync(join(root, y, m, d)).find((f) => f.endsWith(suffix));
155
+ if (hit)
156
+ return join(root, y, m, d, hit);
157
+ }
158
+ }
159
+ }
160
+ }
161
+ catch {
162
+ return null;
163
+ }
164
+ return null;
165
+ }
166
+ export const codex = {
167
+ id: 'codex',
168
+ name: 'Codex',
169
+ detect,
170
+ parse,
171
+ findTranscript,
172
+ };
173
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/agents/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { AgentAdapter, AgentId } from './types.js';
2
+ export type { AgentAdapter, AgentId } from './types.js';
3
+ export { AGENT_IDS } from './types.js';
4
+ export declare function getAgent(id: AgentId): AgentAdapter;
5
+ export declare function detectAgent(raw: string): AgentAdapter;
6
+ export declare function findTranscript(sessionId: string): string | null;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAIxD,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMvC,wBAAgB,QAAQ,CAAC,EAAE,EAAE,OAAO,GAAG,YAAY,CAIlD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAErD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM/D"}