somtum 1.2.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,9 +7,9 @@
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 captures and 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. It also caches repeated prompt→response pairs so identical (or near-identical) prompts never hit the model twice.
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.
11
11
 
12
- Zero-config: one `somtum init` in an existing Claude Code project and every session end is captured automatically. No server, no cloud account, no mandatory tuning.
12
+ Zero-config: one `somtum init` and every session end is captured automatically. No server, no cloud account, no mandatory tuning.
13
13
 
14
14
  ---
15
15
 
@@ -37,18 +37,81 @@ Zero-config: one `somtum init` in an existing Claude Code project and every sess
37
37
 
38
38
  ## Why Somtum?
39
39
 
40
- LLM agents like Claude Code typically start every session with a "blank slate." This leads to:
40
+ LLM agents like Claude Code start every session with a blank slate. That leads to:
41
41
 
42
- - **Repetitive Explanations:** Having to re-explain architectural choices or local conventions.
43
- - **Regressions:** Claude might suggest a fix you've already tried and discarded.
44
- - **Context Waste:** Large codebases eat up tokens just to "set the scene."
42
+ - **Repetitive context** — re-explaining the same architectural choices every session
43
+ - **Regressions** — Claude suggests a fix you already tried and discarded
44
+ - **Token waste** — reading large files just to "set the scene"
45
45
 
46
- **Somtum gives Claude a long-term memory.** It ensures that once a decision is made or a bug is fixed, it stays "remembered" across all future sessions without bloating your context window.
46
+ **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.
47
+
48
+ ### What a session looks like with Somtum
49
+
50
+ ```
51
+ Without Somtum With Somtum
52
+ ──────────────────── ──────────────────────────────────────
53
+ Session 1: "We use pnpm Session 1: same work
54
+ because of workspace
55
+ hoisting"
56
+
57
+ Session 2: Claude suggests Session 2: Claude already knows about
58
+ npm, you correct it pnpm, the auth decisions, and the
59
+ again bugfixes from last week
60
+ ```
47
61
 
48
62
  ---
49
63
 
50
64
  ## How it works
51
65
 
66
+ 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 and injected back into context the next time you ask something related.
67
+
68
+ ### Memory lifecycle
69
+
70
+ ```mermaid
71
+ sequenceDiagram
72
+ participant You
73
+ participant Claude Code
74
+ participant Somtum Hook
75
+ participant SQLite DB
76
+
77
+ You->>Claude Code: Work on project (coding, debugging, decisions)
78
+ Claude Code->>Somtum Hook: SessionEnd fires automatically
79
+ Somtum Hook->>Claude Code: Extract observations via Haiku
80
+ Somtum Hook->>SQLite DB: Store memories locally
81
+
82
+ Note over You,SQLite DB: Next session
83
+
84
+ You->>Claude Code: Ask about the project
85
+ Claude Code->>SQLite DB: recall() via MCP tool
86
+ SQLite DB-->>Claude Code: Relevant past decisions & fixes
87
+ Claude Code-->>You: Answer informed by prior sessions
88
+ ```
89
+
90
+ ### What gets captured — a concrete example
91
+
92
+ You work a session debugging an auth bug and refactoring a module. At session end, Somtum extracts something like:
93
+
94
+ ```json
95
+ [
96
+ {
97
+ "kind": "bugfix",
98
+ "title": "JWT refresh loop caused by missing expiry check",
99
+ "body": "The refresh token loop was triggered because we checked token.exp < Date.now() instead of token.exp < Date.now() / 1000. Unix timestamps are in seconds, not milliseconds.",
100
+ "files": ["src/auth/refresh.ts"]
101
+ },
102
+ {
103
+ "kind": "decision",
104
+ "title": "Use pnpm workspaces — npm hoisting breaks shared types",
105
+ "body": "Switched from npm to pnpm because npm's hoisting puts shared type packages in the wrong node_modules scope, breaking type inference across packages.",
106
+ "files": ["package.json", "pnpm-workspace.yaml"]
107
+ }
108
+ ]
109
+ ```
110
+
111
+ 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.
112
+
113
+ ### Architecture
114
+
52
115
  ```
53
116
  ┌─────────────────────────────────────────────────────────────┐
54
117
  │ Claude Code / Agent │
@@ -60,8 +123,7 @@ LLM agents like Claude Code typically start every session with a "blank slate."
60
123
  │ │ │ │
61
124
  │ UserPromptSubmit ──┼─────────┼▶ cache_lookup │
62
125
  │ SessionEnd ────────┼─────────┼▶ recall / get │
63
- │ PreCompact ────────┼─────────┼▶ remember / forget │
64
- │ PreToolUse (Read) ─┼─────────┼▶ stats │
126
+ │ PreToolUse (Read) ─┼─────────┼▶ remember / forget │
65
127
  └──────────┬──────────┘ └──────────┬───────────┘
66
128
  │ │
67
129
  ▼ ▼
@@ -71,10 +133,10 @@ LLM agents like Claude Code typically start every session with a "blank slate."
71
133
  │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
72
134
  │ │ PromptCache │ │ MemoryStore │ │ Retriever │ │
73
135
  │ │ │ │ │ │ │ │
74
- │ │ exact hash │ │ observations │ │ bm25 (FTS5) │ │
136
+ │ │ exact hash │ │ observations │ │ bm25 (default) │ │
75
137
  │ │ fuzzy embed │ │ + embeddings │ │ embeddings │ │
76
- │ │ fingerprint │ │ + redaction │ │ index (Haiku) │ │
77
- │ │ invalidation │ │ │ │ hybrid (default)│ │
138
+ │ │ fingerprint │ │ + redaction │ │ index │ │
139
+ │ │ invalidation │ │ │ │ hybrid │ │
78
140
  │ └──────────────┘ └──────────────┘ └──────────────────┘ │
79
141
  └─────────────────────────────────┬───────────────────────────┘
80
142
  │
@@ -89,14 +151,16 @@ LLM agents like Claude Code typically start every session with a "blank slate."
89
151
  └─────────────────────────┘
90
152
  ```
91
153
 
92
- ### Three retrieval strategies — all first-class
154
+ ### Retrieval strategies
155
+
156
+ | Strategy | How it works | Best for | Cost |
157
+ |---|---|---|---|
158
+ | **`bm25`** | Keyword search over title + body + tags (SQLite FTS5 — no external dependencies) | Exact terms, offline setups | Near-zero |
159
+ | **`embeddings`** | Semantic similarity using a 30 MB local model (bge-small-en-v1.5, runs fully in-process) | "What did we decide about auth?" style queries | ~5 ms at 10k memories |
160
+ | **`index`** | Sends a compact memory catalog to Haiku; the model picks relevant IDs | Paraphrased or fuzzy queries | 1 Haiku API call |
161
+ | **`hybrid`** | BM25 + embeddings results merged and re-ranked by Haiku | General case (best recall) | BM25 + embeddings + 1 Haiku call |
93
162
 
94
- | Strategy | How it works | Best for | Cost |
95
- | ------------------------ | ---------------------------------------------------------------- | ---------------------------------------- | ----------------------------------- |
96
- | **`bm25`** | SQLite FTS5 lexical search over title + body + tags | Keyword queries, offline-forever setups | Near-zero |
97
- | **`embeddings`** | Cosine similarity over 384-dim vectors (bge-small-en-v1.5, ONNX) | Semantic queries, large corpora | ~30 MB model, ~5 ms at 10k memories |
98
- | **`index`** | Compact catalog sent to Haiku; model picks relevant IDs | Paraphrased queries, zero-embedding mode | 1 Haiku call per query |
99
- | **`hybrid`** _(default)_ | BM25 top-50 ∪ embeddings top-50 → RRF blend → Haiku rerank | General case | BM25 + embeddings + 1 Haiku call |
163
+ **Default is `bm25`** — works offline, no setup. Enable `hybrid` once you have embeddings downloaded.
100
164
 
101
165
  ---
102
166
 
@@ -104,16 +168,14 @@ LLM agents like Claude Code typically start every session with a "blank slate."
104
168
 
105
169
  - **Node 20+**
106
170
  - **Claude Code** — Somtum hooks into Claude Code's `SessionEnd`, `UserPromptSubmit`, and `PreToolUse` events
107
- - **`ANTHROPIC_API_KEY`** — used by the capture hook to summarise session transcripts via Claude Haiku, and optionally by the `index` and `hybrid` retrieval strategies. **Must be exported in your shell profile** (see [Quickstart](#quickstart) — step 1 explains why)
108
-
109
- > `pnpm` is only required if building from source. Global npm/yarn installs have no pnpm dependency.
171
+ - **`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**.
110
172
 
111
173
  ---
112
174
 
113
175
  ## Install
114
176
 
115
177
  ```bash
116
- # npm (recommended for global install)
178
+ # npm (recommended)
117
179
  npm install -g somtum
118
180
 
119
181
  # yarn
@@ -141,58 +203,58 @@ pnpm link --global
141
203
 
142
204
  ### Native module note
143
205
 
144
- Somtum uses [`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3), which contains a native C++ addon. On most platforms (macOS, Linux x64/arm64, Windows x64) a prebuilt binary is downloaded automatically. On Alpine Linux / musl or unusual architectures the addon compiles from source — `python`, `make`, and `gcc` must be available. If the install fails with a node-gyp error, install those build tools and retry.
206
+ Somtum uses [`better-sqlite3`](https://github.com/WiseLibs/better-sqlite3), which contains a native C++ addon. On most platforms (macOS, Linux x64/arm64, Windows x64) a prebuilt binary is downloaded automatically. On Alpine Linux / musl or unusual architectures, the addon compiles from source — `python`, `make`, and `gcc` must be available. If the install fails with a node-gyp error, install those build tools and retry.
145
207
 
146
208
  ---
147
209
 
148
210
  ## Quickstart
149
211
 
150
- ### Step 1 — Set your Anthropic API key in your shell profile
212
+ ### Step 1 — Choose your extraction backend
151
213
 
152
- > **This is the most important step.** When a Claude Code session ends, the `SessionEnd` hook runs as a subprocess launched by Claude Code. That subprocess inherits its environment from the shell that _started_ Claude Code — not from the current terminal window. If the key is only `export`-ed in an interactive session, the hook will not see it and extraction will silently fail.
214
+ Somtum needs to call a Claude model at session end to extract observations. Pick one:
153
215
 
154
- Add to `~/.zshrc` (or `~/.bashrc`, `~/.bash_profile`):
216
+ **Option A: Claude Code subscription (no extra setup)**
155
217
 
156
- ```bash
157
- export ANTHROPIC_API_KEY="sk-ant-..."
158
- ```
218
+ 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.
219
+
220
+ **Option B: Direct Anthropic API key (optional — faster, lets you pick the model)**
159
221
 
160
- Then reload your shell:
222
+ Add to `~/.zshrc` (or `~/.bashrc`):
161
223
 
162
224
  ```bash
163
- source ~/.zshrc # or open a new terminal
225
+ export ANTHROPIC_API_KEY="sk-ant-..."
164
226
  ```
165
227
 
166
- Confirm it's available:
228
+ Then reload:
167
229
 
168
230
  ```bash
169
- echo $ANTHROPIC_API_KEY # should print your key
231
+ source ~/.zshrc
170
232
  ```
171
233
 
234
+ > 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.
235
+
172
236
  ### Step 2 — Install inside a Claude Code project
173
237
 
174
- Run this from the **root of the project you work in with Claude Code**:
238
+ Run this from the **root of the project you work on with Claude Code**:
175
239
 
176
240
  ```bash
177
241
  somtum init
178
242
  ```
179
243
 
180
- This writes a `SessionEnd` hook into `.claude/settings.json` in the current directory. Claude Code reads that file automatically when you open a session from the same directory.
181
-
182
- To enable all features at once:
244
+ To enable all features at once (recommended):
183
245
 
184
246
  ```bash
185
247
  somtum init --all
186
248
  # Installs:
187
249
  # - SessionEnd capture hook (memory extraction)
188
250
  # - UserPromptSubmit cache hook (prompt cache lookup)
189
- # - PreToolUse file-gating hook (file read summaries)
251
+ # - PreToolUse file-gating hook (large file summarization)
190
252
  # - MCP server in .mcp.json (Claude can call recall/remember tools)
191
253
  ```
192
254
 
193
255
  ### Step 3 — Use Claude Code normally
194
256
 
195
- 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 so it never blocks you).
257
+ 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).
196
258
 
197
259
  ### Step 4 — Check your memory
198
260
 
@@ -216,7 +278,7 @@ If `somtum stats` shows `memories 0` after a session, see [Troubleshooting](#tro
216
278
  somtum doctor
217
279
  ```
218
280
 
219
- This checks your API key, DB health, hook installation, migrations, cache, and breakeven ratio. It will tell you exactly what is misconfigured and how to fix it.
281
+ This checks your API key, DB health, hook installation, migrations, cache, and breakeven ratio — with specific fix instructions for each failing check.
220
282
 
221
283
  ---
222
284
 
@@ -226,24 +288,29 @@ After your **first** Claude Code session ends:
226
288
 
227
289
  **1. Check the hook log**
228
290
 
229
- Every hook run appends a timestamped line to `~/.somtum/hook.log`:
230
-
231
291
  ```bash
232
292
  cat ~/.somtum/hook.log
233
293
  ```
234
294
 
235
- A successful run looks like:
295
+ A successful run:
296
+
297
+ ```
298
+ 2026-04-30T10:15:42.123Z [post_session] starting
299
+ 2026-04-30T10:15:44.891Z [post_session] ok — inserted=4 cache=2 summaries=1
300
+ ```
301
+
302
+ Using the `claude` CLI fallback (no API key):
236
303
 
237
304
  ```
238
305
  2026-04-30T10:15:42.123Z [post_session] starting
306
+ 2026-04-30T10:15:42.124Z [post_session] ANTHROPIC_API_KEY not set — will use claude CLI fallback
239
307
  2026-04-30T10:15:44.891Z [post_session] ok — inserted=4 cache=2 summaries=1
240
308
  ```
241
309
 
242
- A failed run with a missing API key looks like:
310
+ Neither backend available:
243
311
 
244
312
  ```
245
- 2026-04-30T10:15:42.123Z [post_session] WARN: ANTHROPIC_API_KEY not set — extraction will fail
246
- 2026-04-30T10:15:42.131Z [post_session] ERROR: 401 authentication_error
313
+ 2026-04-30T10:15:42.123Z [post_session] ERROR: Neither ANTHROPIC_API_KEY nor the claude CLI is available.
247
314
  ```
248
315
 
249
316
  **2. Check stats**
@@ -252,7 +319,7 @@ A failed run with a missing API key looks like:
252
319
  somtum stats
253
320
  ```
254
321
 
255
- You should see `memories` > 0 after a substantive session. Short test sessions may yield 0 observations if there is nothing worth extracting (Claude Code did not make decisions, fix bugs, or learn anything the extractor considers durable).
322
+ You should see `memories > 0` after a substantive session. Short or trivial sessions (no decisions, no bug fixes) correctly return 0 — the extractor only keeps durable observations.
256
323
 
257
324
  **3. Run doctor**
258
325
 
@@ -266,28 +333,24 @@ All checks should show `✓`. The `api_key` and `hooks_installed` checks are the
266
333
 
267
334
  ## Dashboard
268
335
 
269
- Somtum includes a visual memory browser you can open at any time:
270
-
271
336
  ```bash
272
337
  somtum serve
273
- # Opens http://localhost:3000 in your browser
338
+ # Opens http://localhost:3000
274
339
  ```
275
340
 
276
- The dashboard provides:
341
+ The dashboard has four views:
277
342
 
278
- - **Memory browser** — searchable, filterable list of all captured observations. Supports BM25, hybrid, and embeddings strategies live. Click any memory to see its full body, files touched, and tags.
279
- - **Knowledge graph** — vis-network graph where nodes are memories and edges connect memories that share files or tags. Clicking a node opens the detail panel.
280
- - **Analytics** — kind breakdown, cache hit rate, retrieval strategy usage, and top-referenced files.
343
+ - **Memory browser** — searchable, filterable list of all captured observations. Switch between BM25, hybrid, and embeddings strategies live. Click any memory to see its full body, files, and tags.
344
+ - **Knowledge graph** — nodes are memories, edges connect memories that share files or tags. Click a node to open it in the detail panel.
345
+ - **Analytics** — kind breakdown, cache hit rate, retrieval strategy usage, top-referenced files.
281
346
  - **Forget button** — soft-delete any memory directly from the browser.
282
347
 
283
- Options:
348
+ | Flag | Default | Description |
349
+ |---|---|---|
350
+ | `--port <n>` | 3000 | Listen on a custom port |
351
+ | `--no-open` | — | Start server without opening the browser |
284
352
 
285
- | Flag | Description |
286
- | ------------ | -------------------------------------- |
287
- | `--port <n>` | Listen on a custom port (default 3000) |
288
- | `--no-open` | Don't auto-open the browser |
289
-
290
- Press `Ctrl-C` to stop the server.
353
+ Press `Ctrl-C` to stop.
291
354
 
292
355
  ---
293
356
 
@@ -295,169 +358,171 @@ Press `Ctrl-C` to stop the server.
295
358
 
296
359
  ### Setup
297
360
 
298
- | Command | Description |
299
- | --------------------------- | ------------------------------------------------------------ |
300
- | `somtum init` | Install the SessionEnd capture hook |
301
- | `somtum init --cache` | Also install the UserPromptSubmit cache hook |
302
- | `somtum init --file-gating` | Also install the PreToolUse file-gating hook |
303
- | `somtum init --all` | Install all hooks + MCP server |
304
- | `somtum init --force` | Reinstall even if hooks already present |
305
- | `somtum doctor` | Check DB health, migrations, hooks, API key, breakeven ratio |
361
+ | Command | Description |
362
+ |---|---|
363
+ | `somtum init` | Install the SessionEnd capture hook |
364
+ | `somtum init --cache` | Also install the UserPromptSubmit cache hook |
365
+ | `somtum init --file-gating` | Also install the PreToolUse file-gating hook |
366
+ | `somtum init --all` | Install all hooks + MCP server |
367
+ | `somtum init --force` | Reinstall even if hooks already present |
368
+ | `somtum doctor` | Check DB health, migrations, hooks, API key, breakeven ratio |
306
369
 
307
370
  ### Memory
308
371
 
309
- | Command | Description |
310
- | --------------------------------------- | ------------------------------------------------ |
311
- | `somtum search <query>` | Search observations (default: `hybrid` strategy) |
312
- | `somtum search <query> --strategy bm25` | Force a specific retrieval strategy |
313
- | `somtum search <query> -k 16` | Return more results |
314
- | `somtum show <id>` | Print the full body of an observation |
315
- | `somtum forget <id>` | Soft-delete an observation |
316
- | `somtum edit <id>` | Open an observation body in `$EDITOR` |
317
- | `somtum rebuild` | Regenerate `index.md` from all observations |
318
- | `somtum reindex` | Recompute embeddings (after a model change) |
372
+ | Command | Description |
373
+ |---|---|
374
+ | `somtum search <query>` | Search observations (default: `bm25` strategy) |
375
+ | `somtum search <query> --strategy hybrid` | Force a specific retrieval strategy |
376
+ | `somtum search <query> -k 16` | Return more results |
377
+ | `somtum show <id>` | Print the full body of an observation |
378
+ | `somtum remember` | Manually store an observation |
379
+ | `somtum forget <id>` | Soft-delete an observation |
380
+ | `somtum edit <id>` | Open an observation body in `$EDITOR` |
381
+ | `somtum rebuild` | Regenerate `index.md` from all observations |
382
+ | `somtum reindex` | Recompute embeddings (after enabling embeddings or changing model) |
319
383
 
320
384
  ### Stats & Visibility
321
385
 
322
- | Command | Description |
323
- | ------------------------- | ------------------------------------------------- |
324
- | `somtum stats` | Tokens saved, cache hit rate, retrieval breakdown |
325
- | `somtum stats --json` | Machine-readable JSON output |
326
- | `somtum serve` | Open the visual dashboard in the browser |
327
- | `somtum serve --port <n>` | Use a custom port (default 3000) |
328
- | `somtum serve --no-open` | Start server without opening the browser |
329
-
330
- ### Data management
331
-
332
- | Command | Description |
333
- | ------------------------------------------------- | --------------------------------------------------- |
334
- | `somtum export` | Export observations to stdout as JSON |
335
- | `somtum export --format jsonl --output obs.jsonl` | Export as JSONL file |
336
- | `somtum export --format markdown` | Export as readable Markdown |
337
- | `somtum export --include-deleted` | Include soft-deleted entries |
338
- | `somtum import <file>` | Import observations from JSON or JSONL |
339
- | `somtum purge --older-than 30d` | Hard-delete soft-deleted entries older than 30 days |
340
- | `somtum purge --older-than 30d --dry-run` | Preview without deleting |
341
-
342
- ### Stats & visibility
343
-
344
- | Command | Description |
345
- | ---------------- | ------------------------------------------- |
346
- | `somtum reindex` | Embed observations that are missing vectors |
386
+ | Command | Description |
387
+ |---|---|
388
+ | `somtum stats` | Tokens saved, cache hit rate, retrieval breakdown |
389
+ | `somtum stats --json` | Machine-readable JSON output |
390
+ | `somtum serve` | Open the visual dashboard in the browser |
391
+ | `somtum serve --port <n>` | Use a custom port (default 3000) |
392
+ | `somtum serve --no-open` | Start server without opening the browser |
393
+
394
+ ### Data Management
395
+
396
+ | Command | Description |
397
+ |---|---|
398
+ | `somtum export` | Export observations to stdout as JSON |
399
+ | `somtum export --format jsonl --output obs.jsonl` | Export as JSONL file |
400
+ | `somtum export --format markdown` | Export as readable Markdown |
401
+ | `somtum export --include-deleted` | Include soft-deleted entries |
402
+ | `somtum import <file>` | Import observations from JSON or JSONL |
403
+ | `somtum purge --older-than 30d` | Hard-delete soft-deleted entries older than 30 days |
404
+ | `somtum purge --older-than 30d --dry-run` | Preview without deleting |
347
405
 
348
406
  ### Configuration
349
407
 
350
- | Command | Description |
351
- | -------------------------------------------------------------- | --------------------------------- |
352
- | `somtum config get` | Print the full resolved config |
353
- | `somtum config get retrieval.strategy` | Read a single key (dot-separated) |
354
- | `somtum config set retrieval.strategy hybrid` | Write to `.somtum/config.json` |
355
- | `somtum config set retrieval.embeddings.enabled true --global` | Write to `~/.somtum/config.json` |
408
+ | Command | Description |
409
+ |---|---|
410
+ | `somtum config get` | Print the full resolved config |
411
+ | `somtum config get retrieval.strategy` | Read a single key (dot-separated) |
412
+ | `somtum config set retrieval.strategy hybrid` | Write to `.somtum/config.json` |
413
+ | `somtum config set retrieval.embeddings.enabled true --global` | Write to `~/.somtum/config.json` |
356
414
 
357
415
  ### Sync
358
416
 
359
- | Command | Description |
360
- | -------------------- | ----------------------------------------- |
417
+ | Command | Description |
418
+ |---|---|
361
419
  | `somtum sync status` | Compare local vs remote observation count |
362
- | `somtum sync push` | Export and scp observations to remote |
363
- | `somtum sync pull` | scp from remote and merge into local DB |
420
+ | `somtum sync push` | Export and scp observations to remote |
421
+ | `somtum sync pull` | scp from remote and merge into local DB |
422
+
423
+ Set your remote: `somtum config set sync.remote "user@host:/path/.somtum/projects/<id>"`
364
424
 
365
- Remote configured in config: `somtum config set sync.remote "user@host:/path/.somtum/projects/<id>"`
366
- Somtum uses hostname-aware syncing to prevent data loss when using multiple devices.
425
+ Somtum uses hostname-aware syncing — merging observations from multiple machines without data loss.
367
426
 
368
427
  ---
369
428
 
370
429
  ## MCP Server
371
430
 
372
- Somtum includes a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server. When you run `somtum init --all`, it registers tools that Claude can use autonomously:
431
+ When you run `somtum init --all`, Somtum registers an MCP server that Claude can call autonomously during a session:
373
432
 
374
- | Tool | What Claude can do with it |
375
- | -------------- | ---------------------------------------------------------------------- |
376
- | `recall` | Search memories by natural language when unsure about a project detail |
377
- | `get` | Retrieve the full body of specific observations by ID |
378
- | `remember` | Manually store an observation from within a session |
379
- | `cache_lookup` | Check the prompt cache directly |
380
- | `forget` | Soft-delete an observation |
381
- | `stats` | Report on tokens saved, cache hit rate, and corpus size |
433
+ | Tool | What Claude does with it |
434
+ |---|---|
435
+ | `recall` | Searches memories when unsure about a project detail |
436
+ | `get` | Retrieves the full body of specific observations by ID |
437
+ | `remember` | Stores an observation manually from within a session |
438
+ | `cache_lookup` | Checks the prompt cache directly |
439
+ | `forget` | Soft-deletes an observation |
440
+ | `stats` | Reports tokens saved, cache hit rate, and corpus size |
382
441
 
383
442
  Every MCP response includes a `tokens` field so Claude can account for retrieval cost.
384
443
 
385
444
  ---
386
445
 
387
- ## Dashboard
388
-
389
- `somtum serve` opens a local web dashboard at `http://localhost:3000`:
390
-
391
- - **Memory browser** — search across all observations using BM25, hybrid, or embedding-based retrieval; filter by kind (decision, bugfix, learning, command, file_summary); forget memories directly from the UI.
392
- - **Knowledge graph** — vis-network graph where nodes are observations, edges represent shared files or tags. Clicking a node selects the memory in the list and vice versa.
393
- - **Analytics tab** — kind breakdown, token ROI (saved vs. spent), cache hit rate + entry count, retrieval strategy usage, and top files by reference count.
394
- - **Stat bar** — live counts for total memories, tokens saved, tokens spent, ROI ratio, and cache hit %.
395
-
396
- ```bash
397
- somtum serve # opens on port 3000
398
- somtum serve --port 4000 # custom port
399
- somtum serve --no-open # don't auto-open the browser
400
- ```
401
-
402
- ---
403
-
404
- ## Storage layout
446
+ ## Storage Layout
405
447
 
406
448
  ```
407
449
  ~/.somtum/
408
- ├── config.json ← global config (overridden by project config)
450
+ ├── config.json ← global config (merged with project config)
409
451
  ├── hook.log ← timestamped log of every hook execution
410
452
  └── projects/
411
453
  └── <project_id>/
412
454
  ├── db.sqlite ← source of truth (SQLite WAL)
413
- ├── index.md ← regenerated human-readable mirror
455
+ ├── index.md ← human-readable mirror (regenerated)
414
456
  └── memories/
415
457
  └── YYYY-MM/
416
458
  └── <ulid>.md ← per-observation markdown files
417
459
  ```
418
460
 
419
- The project ID is derived from the git remote URL (if present) or the directory path — the same project always maps to the same ID regardless of which machine you're on, as long as the remote URL matches.
461
+ The project ID is derived from the git remote URL (or directory path if no remote). The same project maps to the same ID across machines as long as the remote URL matches.
420
462
 
421
- SQLite is the source of truth. `index.md` and `memories/*.md` are derived mirrors regenerated on each capture. Edit observations with `somtum edit <id>`, not by hand.
463
+ SQLite is the source of truth. Edit observations with `somtum edit <id>`, not by hand.
422
464
 
423
465
  ---
424
466
 
425
467
  ## Configuration
426
468
 
427
- Global config lives at `~/.somtum/config.json`. Per-project config at `.somtum/config.json` — project values override global ones (deep merge).
469
+ Global config lives at `~/.somtum/config.json`. Per-project config at `.somtum/config.json` overrides it (deep merge).
470
+
471
+ ### Most common settings
472
+
473
+ ```bash
474
+ # Enable semantic (embedding-based) search — downloads a 30 MB model once
475
+ somtum config set retrieval.embeddings.enabled true
476
+ somtum reindex
477
+
478
+ # Switch to hybrid retrieval (BM25 + embeddings + rerank) for best recall
479
+ somtum config set retrieval.strategy hybrid
480
+
481
+ # Use LLM-based retrieval (no embeddings required, costs one Haiku call per query)
482
+ somtum config set retrieval.index.enabled true
483
+ somtum config set retrieval.strategy index
484
+
485
+ # Intercept large file reads and summarize them (reduces context bloat)
486
+ somtum config set file_gating.enabled true
487
+
488
+ # Limit observations extracted per session (default: 10)
489
+ somtum config set extraction.max_observations_per_session 5
490
+ ```
491
+
492
+ ### Full config reference
428
493
 
429
494
  ```jsonc
430
495
  {
431
496
  "extraction": {
432
497
  "model": "claude-haiku-4-5-20251001",
433
498
  "trigger": ["SessionEnd", "PreCompact"],
434
- "max_observations_per_session": 10,
499
+ "max_observations_per_session": 10
435
500
  },
436
501
  "cache": {
437
502
  "enabled": true,
438
503
  "fuzzy_match": true,
439
504
  "fuzzy_threshold": 0.92, // raise to 0.95 once you have signal
440
505
  "max_entries": 10000,
441
- "ttl_days": 90,
506
+ "ttl_days": 90
442
507
  },
443
508
  "retrieval": {
444
- "strategy": "hybrid", // bm25 | embeddings | index | hybrid
509
+ "strategy": "bm25", // bm25 | embeddings | index | hybrid
445
510
  "k": 8,
446
511
  "rerank_model": "claude-haiku-4-5-20251001",
447
512
  "bm25": { "enabled": true },
448
513
  "embeddings": {
449
514
  "enabled": false, // set true to download the 30 MB ONNX model
450
- "model": "Xenova/bge-small-en-v1.5",
515
+ "model": "Xenova/bge-small-en-v1.5"
451
516
  },
452
517
  "index": {
453
518
  "enabled": false, // set true to use Haiku as the retriever
454
- "model": "claude-haiku-4-5-20251001",
455
- },
519
+ "model": "claude-haiku-4-5-20251001"
520
+ }
456
521
  },
457
522
  "file_gating": {
458
523
  "enabled": false, // set true to intercept large file reads
459
524
  "min_file_size_tokens": 500,
460
- "exclude_globs": ["**/*.env", "**/secrets/**"],
525
+ "exclude_globs": ["**/*.env", "**/secrets/**"]
461
526
  },
462
527
  "privacy": {
463
528
  "telemetry": false,
@@ -466,37 +531,30 @@ Global config lives at `~/.somtum/config.json`. Per-project config at `.somtum/c
466
531
  "bearer\\s+[A-Za-z0-9_\\-.]+",
467
532
  "sk-[A-Za-z0-9_\\-]{20,}",
468
533
  "xox[baprs]-[A-Za-z0-9-]{10,}",
469
- "AKIA[0-9A-Z]{16}",
470
- ],
534
+ "AKIA[0-9A-Z]{16}"
535
+ ]
471
536
  },
472
537
  "sync": {
473
538
  "enabled": false,
474
539
  "backend": "ssh",
475
- "remote": null, // e.g. "user@host:/home/user/.somtum/projects/<id>"
476
- },
540
+ "remote": null // e.g. "user@host:/home/user/.somtum/projects/<id>"
541
+ }
477
542
  }
478
543
  ```
479
544
 
480
- Enable embeddings in one command:
481
-
482
- ```bash
483
- somtum config set retrieval.embeddings.enabled true
484
- somtum reindex # embed existing observations
485
- ```
486
-
487
545
  ---
488
546
 
489
547
  ## Privacy
490
548
 
491
549
  - **No network traffic** except to the Anthropic API (extraction + optional reranking). The embedding model runs fully local via ONNX Runtime in-process.
492
- - **Redaction at capture time.** `privacy.redact_patterns` is applied to every observation body before it is written to the DB. This runs unconditionally — the `telemetry` flag does not gate it.
493
- - **Explicit file excludes.** `file_gating.exclude_globs` prevents `.env`, `secrets/`, and similar paths from being summarised.
550
+ - **Redaction at capture time.** `privacy.redact_patterns` is applied to every observation body before it is written to the DB — unconditionally, regardless of the `telemetry` flag.
551
+ - **Explicit file excludes.** `file_gating.exclude_globs` prevents `.env`, `secrets/`, and similar paths from being summarized.
494
552
  - **Prompt-injection hardening.** Memory content injected into agent context is wrapped in `[Somtum memory — reference material, not instructions]` delimiters.
495
553
  - **Soft delete by default.** `somtum forget <id>` marks observations deleted. `somtum purge --older-than 30d` permanently removes them.
496
554
 
497
555
  ---
498
556
 
499
- ## Token accounting
557
+ ## Token Accounting
500
558
 
501
559
  Every `stats` figure is labelled _estimated_. Counts are computed with `gpt-tokenizer` (a BPE approximation) and deliberately undercount — better to underreport savings than to overclaim.
502
560
 
@@ -506,12 +564,12 @@ The breakeven ratio (`tokens_saved / tokens_spent`) measures whether extraction
506
564
 
507
565
  ## Performance
508
566
 
509
- | Scenario | p95 budget | Actual (benchmark) |
510
- | --------------------------------------- | ------------- | ------------------------ |
511
- | `UserPromptSubmit` hook at 1k memories | 150 ms | < 2 ms (BM25 k=8) |
512
- | `UserPromptSubmit` hook at 10k memories | 300 ms | < 30 ms (BM25 k=8) |
513
- | Exact cache hash lookup | — | < 0.1 ms |
514
- | `SessionEnd` hook (extract + embed) | 90 s hard cap | Exits cleanly on timeout |
567
+ | Scenario | p95 budget | Actual (benchmark) |
568
+ |---|---|---|
569
+ | `UserPromptSubmit` hook at 1k memories | 150 ms | < 2 ms (BM25 k=8) |
570
+ | `UserPromptSubmit` hook at 10k memories | 300 ms | < 30 ms (BM25 k=8) |
571
+ | Exact cache hash lookup | — | < 0.1 ms |
572
+ | `SessionEnd` hook (extract + embed) | 90 s hard cap | Exits cleanly on timeout |
515
573
 
516
574
  Run benchmarks yourself:
517
575
 
@@ -596,34 +654,22 @@ test/
596
654
 
597
655
  ### `somtum stats` shows `memories 0` after a session
598
656
 
599
- This almost always means the hook ran but extraction failed. Check the log first:
657
+ Check the hook log first:
600
658
 
601
659
  ```bash
602
660
  cat ~/.somtum/hook.log
603
661
  ```
604
662
 
605
- Common causes:
606
-
607
- **`ANTHROPIC_API_KEY` not set in shell profile**
663
+ **`claude` CLI not found and no `ANTHROPIC_API_KEY` set**
608
664
 
609
- The most common cause. The hook runs as a subprocess of Claude Code and inherits the environment from the shell that launched Claude Code. If you only `export`-ed the key in the current terminal session (not in `.zshrc` / `.bashrc`), the hook won't see it.
665
+ - If you use Claude Code: run `which claude` — if nothing prints, reinstall Claude Code or add its binary to your `PATH`.
666
+ - 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.
610
667
 
611
- Fix:
612
-
613
- ```bash
614
- # Add to ~/.zshrc or ~/.bashrc
615
- echo 'export ANTHROPIC_API_KEY="sk-ant-..."' >> ~/.zshrc
616
- source ~/.zshrc
617
-
618
- # Confirm it's set
619
- echo $ANTHROPIC_API_KEY
620
-
621
- # Then open a new Claude session
622
- ```
668
+ Run `somtum doctor` — the `api_key` check tells you exactly which backend is available.
623
669
 
624
670
  **Hook not installed in the right directory**
625
671
 
626
- `somtum init` writes the hook to `.claude/settings.json` in the directory where you ran it. If you run Claude Code from a _different_ directory, it reads a different (or absent) settings file.
672
+ `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.
627
673
 
628
674
  Fix: run `somtum init` from the same directory you use to launch Claude Code.
629
675
 
@@ -635,17 +681,7 @@ claude # must be launched from ~/my-project
635
681
 
636
682
  **Short or trivial session**
637
683
 
638
- If the session didn't contain any decisions, bug fixes, or learnings (e.g. you just asked Claude to say hello), the extractor correctly returns 0 observations.
639
-
640
- Try a real working session, then re-check.
641
-
642
- **Run `somtum doctor`** for a full diagnostic:
643
-
644
- ```bash
645
- somtum doctor
646
- ```
647
-
648
- It checks the API key, hook installation, DB health, embeddings, breakeven ratio, and more, with specific fix instructions for each failing check.
684
+ If the session had no decisions, bug fixes, or learnings (e.g. you just asked Claude to say hello), the extractor correctly returns 0 observations.
649
685
 
650
686
  ---
651
687
 
@@ -667,8 +703,6 @@ pnpm build
667
703
 
668
704
  ### `somtum serve` — port already in use
669
705
 
670
- If port 3000 is busy, use `--port`:
671
-
672
706
  ```bash
673
707
  somtum serve --port 3001
674
708
  ```
@@ -677,24 +711,18 @@ somtum serve --port 3001
677
711
 
678
712
  ### Agent appears to keep running after session ends
679
713
 
680
- The `SessionEnd` hook has a hard 90-second timeout — it cannot block Claude Code indefinitely. If sessions appear stuck immediately after installing Somtum, verify you are on v1.1.0+:
714
+ The `SessionEnd` hook has a hard 90-second timeout. If sessions appear stuck, verify you are on v1.1.0+:
681
715
 
682
716
  ```bash
683
717
  somtum --version
684
- ```
685
-
686
- And check the log for any long-running operations:
687
-
688
- ```bash
689
718
  tail -20 ~/.somtum/hook.log
690
719
  ```
691
720
 
692
721
  ---
693
722
 
694
-
695
723
  ### Installation fails (node-gyp / better-sqlite3)
696
724
 
697
- If you see errors related to building `better-sqlite3`, ensure build tools are installed:
725
+ Ensure build tools are installed:
698
726
 
699
727
  - **macOS:** `xcode-select --install`
700
728
  - **Ubuntu/Debian:** `sudo apt-get install build-essential python3`
@@ -704,28 +732,28 @@ If you see errors related to building `better-sqlite3`, ensure build tools are i
704
732
 
705
733
  ### Embeddings are slow or the model won't download
706
734
 
707
- The first `somtum reindex` downloads a ~30 MB ONNX model (`bge-small-en-v1.5`) from Hugging Face. This requires internet access and may be slow on first run. Subsequent runs use the cached model.
735
+ The first `somtum reindex` downloads a ~30 MB ONNX model from Hugging Face. This requires internet access and may be slow. Subsequent runs use the cached model.
708
736
 
709
- If you are on an air-gapped machine or prefer not to use embeddings, disable them:
737
+ On an air-gapped machine or if you prefer not to use embeddings:
710
738
 
711
739
  ```bash
712
740
  somtum config set retrieval.embeddings.enabled false
713
741
  somtum config set retrieval.strategy bm25
714
742
  ```
715
743
 
716
- BM25 retrieval works fully offline and is fast at any reasonable corpus size.
744
+ BM25 works fully offline and is fast at any corpus size.
717
745
 
718
746
  ---
719
747
 
720
748
  ### Claude isn't using the memories
721
749
 
722
- If you are using the MCP server (`somtum init --all`), Claude will automatically call `recall` when it's uncertain about project details. If it's not happening:
750
+ If you are using the MCP server (`somtum init --all`), Claude calls `recall` automatically when uncertain about project details. If it's not happening:
723
751
 
724
- 1. Confirm `.mcp.json` exists in your project root: `cat .mcp.json`
725
- 2. Restart Claude Code so it picks up the new MCP config
726
- 3. Try prompting Claude explicitly: _"Check your Somtum memory for anything related to our auth setup"_
752
+ 1. Confirm `.mcp.json` exists: `cat .mcp.json`
753
+ 2. Restart Claude Code to pick up the MCP config
754
+ 3. Prompt explicitly: _"Check your Somtum memory for anything related to our auth setup"_
727
755
 
728
- If you are not using the MCP server, memories are injected via the `index.md` file — add it to your CLAUDE.md or Claude Code context with:
756
+ If you are not using the MCP server, memories are injected via `index.md`. Reference it in your CLAUDE.md:
729
757
 
730
758
  ```
731
759
  See ~/.somtum/projects/<project_id>/index.md for prior session learnings.
@@ -735,7 +763,7 @@ See ~/.somtum/projects/<project_id>/index.md for prior session learnings.
735
763
 
736
764
  ## Contributing
737
765
 
738
- Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for the guide.
766
+ Contributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for the guide.
739
767
 
740
768
  **Important:** This project uses `changesets` for versioning. Every PR must include a changeset file generated by running `pnpm changeset`.
741
769