somtum 1.0.0 → 1.2.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 +357 -87
- package/dist/cli/config_cmd.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +10 -1
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/hook.d.ts.map +1 -1
- package/dist/cli/hook.js +31 -2
- package/dist/cli/hook.js.map +1 -1
- package/dist/cli/index.js +17 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/serve.d.ts +8 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +115 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/stats.d.ts.map +1 -1
- package/dist/cli/stats.js +14 -0
- package/dist/cli/stats.js.map +1 -1
- package/dist/core/extractor.d.ts +1 -1
- package/dist/core/extractor.d.ts.map +1 -1
- package/dist/core/extractor.js +1 -3
- package/dist/core/extractor.js.map +1 -1
- package/dist/dashboard/index.html +1602 -0
- package/dist/hooks/post_session.d.ts.map +1 -1
- package/dist/hooks/post_session.js +57 -22
- package/dist/hooks/post_session.js.map +1 -1
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
**Local-first memory and prompt-cache layer for Claude Code.**
|
|
4
4
|
|
|
5
|
+
[**Landing Page & Demo**](https://riz007.github.io/somtum/)
|
|
6
|
+
|
|
5
7
|
[](https://opensource.org/licenses/MIT)
|
|
6
8
|
[](https://www.npmjs.com/package/somtum)
|
|
7
9
|
|
|
@@ -18,6 +20,8 @@ Zero-config: one `somtum init` in an existing Claude Code project and every sess
|
|
|
18
20
|
- [Requirements](#requirements)
|
|
19
21
|
- [Install](#install)
|
|
20
22
|
- [Quickstart](#quickstart)
|
|
23
|
+
- [Verifying the setup](#verifying-the-setup)
|
|
24
|
+
- [Dashboard](#dashboard)
|
|
21
25
|
- [CLI Reference](#cli-reference)
|
|
22
26
|
- [MCP Server](#mcp-server)
|
|
23
27
|
- [Storage Layout](#storage-layout)
|
|
@@ -99,17 +103,17 @@ LLM agents like Claude Code typically start every session with a "blank slate."
|
|
|
99
103
|
## Requirements
|
|
100
104
|
|
|
101
105
|
- **Node 20+**
|
|
102
|
-
- **
|
|
103
|
-
- **`ANTHROPIC_API_KEY`** — used by the capture hook to summarise session transcripts via Claude Haiku, and optionally by the `index` and `hybrid` retrieval strategies
|
|
106
|
+
- **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.
|
|
104
110
|
|
|
105
111
|
---
|
|
106
112
|
|
|
107
113
|
## Install
|
|
108
114
|
|
|
109
|
-
### From npm / yarn / pnpm
|
|
110
|
-
|
|
111
115
|
```bash
|
|
112
|
-
# npm
|
|
116
|
+
# npm (recommended for global install)
|
|
113
117
|
npm install -g somtum
|
|
114
118
|
|
|
115
119
|
# yarn
|
|
@@ -123,8 +127,6 @@ Or as a project dependency:
|
|
|
123
127
|
|
|
124
128
|
```bash
|
|
125
129
|
npm install somtum
|
|
126
|
-
yarn add somtum
|
|
127
|
-
pnpm add somtum
|
|
128
130
|
```
|
|
129
131
|
|
|
130
132
|
### From source
|
|
@@ -134,64 +136,173 @@ git clone https://github.com/riz007/somtum
|
|
|
134
136
|
cd somtum
|
|
135
137
|
pnpm install
|
|
136
138
|
pnpm build
|
|
137
|
-
# Optional: link globally
|
|
138
139
|
pnpm link --global
|
|
139
140
|
```
|
|
140
141
|
|
|
141
142
|
### Native module note
|
|
142
143
|
|
|
143
|
-
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
|
|
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.
|
|
144
145
|
|
|
145
146
|
---
|
|
146
147
|
|
|
147
148
|
## Quickstart
|
|
148
149
|
|
|
150
|
+
### Step 1 — Set your Anthropic API key in your shell profile
|
|
151
|
+
|
|
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.
|
|
153
|
+
|
|
154
|
+
Add to `~/.zshrc` (or `~/.bashrc`, `~/.bash_profile`):
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
export ANTHROPIC_API_KEY="sk-ant-..."
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Then reload your shell:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
source ~/.zshrc # or open a new terminal
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Confirm it's available:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
echo $ANTHROPIC_API_KEY # should print your key
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Step 2 — Install inside a Claude Code project
|
|
173
|
+
|
|
174
|
+
Run this from the **root of the project you work in with Claude Code**:
|
|
175
|
+
|
|
149
176
|
```bash
|
|
150
|
-
# 1. Inside an existing Claude Code project:
|
|
151
177
|
somtum init
|
|
178
|
+
```
|
|
179
|
+
|
|
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.
|
|
152
181
|
|
|
153
|
-
|
|
154
|
-
# Use Claude Code as normal — observations are captured at session end.
|
|
182
|
+
To enable all features at once:
|
|
155
183
|
|
|
156
|
-
|
|
184
|
+
```bash
|
|
185
|
+
somtum init --all
|
|
186
|
+
# Installs:
|
|
187
|
+
# - SessionEnd capture hook (memory extraction)
|
|
188
|
+
# - UserPromptSubmit cache hook (prompt cache lookup)
|
|
189
|
+
# - PreToolUse file-gating hook (file read summaries)
|
|
190
|
+
# - MCP server in .mcp.json (Claude can call recall/remember tools)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Step 3 — Use Claude Code normally
|
|
194
|
+
|
|
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).
|
|
196
|
+
|
|
197
|
+
### Step 4 — Check your memory
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# How many observations were captured?
|
|
201
|
+
somtum stats
|
|
202
|
+
|
|
203
|
+
# Search memory
|
|
157
204
|
somtum search "auth jwt rotation"
|
|
158
205
|
somtum search "why we use pnpm" --strategy hybrid
|
|
159
206
|
|
|
160
|
-
#
|
|
161
|
-
somtum
|
|
207
|
+
# Open the visual dashboard
|
|
208
|
+
somtum serve
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
If `somtum stats` shows `memories 0` after a session, see [Troubleshooting](#troubleshooting).
|
|
212
|
+
|
|
213
|
+
### Step 5 — Diagnose any issues
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
somtum doctor
|
|
217
|
+
```
|
|
218
|
+
|
|
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.
|
|
220
|
+
|
|
221
|
+
---
|
|
162
222
|
|
|
163
|
-
|
|
223
|
+
## Verifying the setup
|
|
224
|
+
|
|
225
|
+
After your **first** Claude Code session ends:
|
|
226
|
+
|
|
227
|
+
**1. Check the hook log**
|
|
228
|
+
|
|
229
|
+
Every hook run appends a timestamped line to `~/.somtum/hook.log`:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
cat ~/.somtum/hook.log
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
A successful run looks like:
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
2026-04-30T10:15:42.123Z [post_session] starting
|
|
239
|
+
2026-04-30T10:15:44.891Z [post_session] ok — inserted=4 cache=2 summaries=1
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
A failed run with a missing API key looks like:
|
|
243
|
+
|
|
244
|
+
```
|
|
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
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**2. Check stats**
|
|
250
|
+
|
|
251
|
+
```bash
|
|
164
252
|
somtum stats
|
|
253
|
+
```
|
|
254
|
+
|
|
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).
|
|
165
256
|
|
|
166
|
-
|
|
257
|
+
**3. Run doctor**
|
|
258
|
+
|
|
259
|
+
```bash
|
|
167
260
|
somtum doctor
|
|
168
261
|
```
|
|
169
262
|
|
|
170
|
-
|
|
263
|
+
All checks should show `✓`. The `api_key` and `hooks_installed` checks are the two most commonly failing.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Dashboard
|
|
268
|
+
|
|
269
|
+
Somtum includes a visual memory browser you can open at any time:
|
|
171
270
|
|
|
172
271
|
```bash
|
|
173
|
-
somtum
|
|
174
|
-
#
|
|
175
|
-
# - SessionEnd capture hook
|
|
176
|
-
# - UserPromptSubmit prompt-cache hook
|
|
177
|
-
# - PreToolUse file-gating hook
|
|
178
|
-
# - MCP server registration in .mcp.json
|
|
272
|
+
somtum serve
|
|
273
|
+
# Opens http://localhost:3000 in your browser
|
|
179
274
|
```
|
|
180
275
|
|
|
276
|
+
The dashboard provides:
|
|
277
|
+
|
|
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.
|
|
281
|
+
- **Forget button** — soft-delete any memory directly from the browser.
|
|
282
|
+
|
|
283
|
+
Options:
|
|
284
|
+
|
|
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.
|
|
291
|
+
|
|
181
292
|
---
|
|
182
293
|
|
|
183
|
-
## CLI
|
|
294
|
+
## CLI Reference
|
|
184
295
|
|
|
185
296
|
### Setup
|
|
186
297
|
|
|
187
|
-
| Command | Description
|
|
188
|
-
| --------------------------- |
|
|
189
|
-
| `somtum init` | Install the SessionEnd capture hook
|
|
190
|
-
| `somtum init --cache` | Also install the UserPromptSubmit cache hook
|
|
191
|
-
| `somtum init --file-gating` | Also install the PreToolUse file-gating hook
|
|
192
|
-
| `somtum init --all` | Install all hooks + MCP server
|
|
193
|
-
| `somtum init --force` | Reinstall even if hooks already present
|
|
194
|
-
| `somtum doctor` | Check DB health, migrations, hooks, breakeven ratio |
|
|
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 |
|
|
195
306
|
|
|
196
307
|
### Memory
|
|
197
308
|
|
|
@@ -204,6 +315,17 @@ somtum init --all
|
|
|
204
315
|
| `somtum forget <id>` | Soft-delete an observation |
|
|
205
316
|
| `somtum edit <id>` | Open an observation body in `$EDITOR` |
|
|
206
317
|
| `somtum rebuild` | Regenerate `index.md` from all observations |
|
|
318
|
+
| `somtum reindex` | Recompute embeddings (after a model change) |
|
|
319
|
+
|
|
320
|
+
### Stats & Visibility
|
|
321
|
+
|
|
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 |
|
|
207
329
|
|
|
208
330
|
### Data management
|
|
209
331
|
|
|
@@ -217,19 +339,12 @@ somtum init --all
|
|
|
217
339
|
| `somtum purge --older-than 30d` | Hard-delete soft-deleted entries older than 30 days |
|
|
218
340
|
| `somtum purge --older-than 30d --dry-run` | Preview without deleting |
|
|
219
341
|
|
|
220
|
-
###
|
|
342
|
+
### Stats & visibility
|
|
221
343
|
|
|
222
344
|
| Command | Description |
|
|
223
345
|
| ---------------- | ------------------------------------------- |
|
|
224
346
|
| `somtum reindex` | Embed observations that are missing vectors |
|
|
225
347
|
|
|
226
|
-
### Stats
|
|
227
|
-
|
|
228
|
-
| Command | Description |
|
|
229
|
-
| --------------------- | ------------------------------------------------- |
|
|
230
|
-
| `somtum stats` | Tokens saved, cache hit rate, retrieval breakdown |
|
|
231
|
-
| `somtum stats --json` | Machine-readable JSON output |
|
|
232
|
-
|
|
233
348
|
### Configuration
|
|
234
349
|
|
|
235
350
|
| Command | Description |
|
|
@@ -247,7 +362,7 @@ somtum init --all
|
|
|
247
362
|
| `somtum sync push` | Export and scp observations to remote |
|
|
248
363
|
| `somtum sync pull` | scp from remote and merge into local DB |
|
|
249
364
|
|
|
250
|
-
Remote configured in config: `somtum config set sync.remote "user@host:/path/.somtum/projects/<id>"`
|
|
365
|
+
Remote configured in config: `somtum config set sync.remote "user@host:/path/.somtum/projects/<id>"`
|
|
251
366
|
Somtum uses hostname-aware syncing to prevent data loss when using multiple devices.
|
|
252
367
|
|
|
253
368
|
---
|
|
@@ -256,12 +371,33 @@ Somtum uses hostname-aware syncing to prevent data loss when using multiple devi
|
|
|
256
371
|
|
|
257
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:
|
|
258
373
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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 |
|
|
382
|
+
|
|
383
|
+
Every MCP response includes a `tokens` field so Claude can account for retrieval cost.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
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
|
+
```
|
|
265
401
|
|
|
266
402
|
---
|
|
267
403
|
|
|
@@ -270,6 +406,7 @@ Somtum includes a [Model Context Protocol (MCP)](https://modelcontextprotocol.io
|
|
|
270
406
|
```
|
|
271
407
|
~/.somtum/
|
|
272
408
|
├── config.json ← global config (overridden by project config)
|
|
409
|
+
├── hook.log ← timestamped log of every hook execution
|
|
273
410
|
└── projects/
|
|
274
411
|
└── <project_id>/
|
|
275
412
|
├── db.sqlite ← source of truth (SQLite WAL)
|
|
@@ -279,6 +416,8 @@ Somtum includes a [Model Context Protocol (MCP)](https://modelcontextprotocol.io
|
|
|
279
416
|
└── <ulid>.md ← per-observation markdown files
|
|
280
417
|
```
|
|
281
418
|
|
|
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.
|
|
420
|
+
|
|
282
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.
|
|
283
422
|
|
|
284
423
|
---
|
|
@@ -297,7 +436,7 @@ Global config lives at `~/.somtum/config.json`. Per-project config at `.somtum/c
|
|
|
297
436
|
"cache": {
|
|
298
437
|
"enabled": true,
|
|
299
438
|
"fuzzy_match": true,
|
|
300
|
-
"fuzzy_threshold": 0.92, //
|
|
439
|
+
"fuzzy_threshold": 0.92, // raise to 0.95 once you have signal
|
|
301
440
|
"max_entries": 10000,
|
|
302
441
|
"ttl_days": 90,
|
|
303
442
|
},
|
|
@@ -361,17 +500,18 @@ somtum reindex # embed existing observations
|
|
|
361
500
|
|
|
362
501
|
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.
|
|
363
502
|
|
|
364
|
-
The breakeven ratio (`tokens_saved / tokens_spent`) measures whether extraction cost is paying off. A ratio below 1.
|
|
503
|
+
The breakeven ratio (`tokens_saved / tokens_spent`) measures whether extraction cost is paying off. A ratio below 1.5× triggers a warning in `somtum stats` and `somtum doctor`.
|
|
365
504
|
|
|
366
505
|
---
|
|
367
506
|
|
|
368
507
|
## Performance
|
|
369
508
|
|
|
370
|
-
| Scenario | p95 budget
|
|
371
|
-
| --------------------------------------- |
|
|
372
|
-
| `UserPromptSubmit` hook at 1k memories | 150 ms
|
|
373
|
-
| `UserPromptSubmit` hook at 10k memories | 300 ms
|
|
374
|
-
| Exact cache hash lookup | —
|
|
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 |
|
|
375
515
|
|
|
376
516
|
Run benchmarks yourself:
|
|
377
517
|
|
|
@@ -391,38 +531,49 @@ pnpm test:golden # retrieval recall@k per strategy
|
|
|
391
531
|
pnpm test:bench # hot-path latency benchmarks
|
|
392
532
|
pnpm lint # eslint
|
|
393
533
|
pnpm fmt # prettier
|
|
394
|
-
pnpm build # tsc + copy migrations → dist/
|
|
534
|
+
pnpm build # tsc + copy migrations + copy dashboard → dist/
|
|
395
535
|
```
|
|
396
536
|
|
|
397
537
|
### Project layout
|
|
398
538
|
|
|
399
539
|
```
|
|
400
540
|
src/
|
|
401
|
-
cli/
|
|
541
|
+
cli/
|
|
542
|
+
index.ts # commander CLI entry point
|
|
543
|
+
init.ts # somtum init — installs hooks + MCP config
|
|
544
|
+
serve.ts # somtum serve — local dashboard server
|
|
545
|
+
stats.ts # somtum stats
|
|
546
|
+
doctor.ts # somtum doctor — health checks
|
|
547
|
+
hook.ts # internal: dispatches hook events by name
|
|
548
|
+
search.ts / show.ts / forget.ts / edit.ts
|
|
549
|
+
export.ts / import.ts / purge.ts / sync.ts / rebuild.ts / reindex.ts
|
|
550
|
+
config_cmd.ts
|
|
402
551
|
core/
|
|
403
|
-
db.ts
|
|
404
|
-
store.ts
|
|
405
|
-
cache.ts
|
|
406
|
-
retriever/
|
|
407
|
-
extractor.ts
|
|
408
|
-
index_gen.ts
|
|
409
|
-
memory_files.ts
|
|
410
|
-
retrieval_stats.ts
|
|
411
|
-
embeddings.ts
|
|
412
|
-
privacy.ts
|
|
413
|
-
tokens.ts
|
|
552
|
+
db.ts # SQLite setup, migration runner
|
|
553
|
+
store.ts # MemoryStore — CRUD for observations
|
|
554
|
+
cache.ts # PromptCache — exact + fuzzy lookup
|
|
555
|
+
retriever/ # bm25, embeddings, hybrid, index, factory
|
|
556
|
+
extractor.ts # session transcript → observations (Claude Haiku)
|
|
557
|
+
index_gen.ts # renders index.md (incremental past 1k obs)
|
|
558
|
+
memory_files.ts # writes memories/<YYYY-MM>/<ulid>.md
|
|
559
|
+
retrieval_stats.ts
|
|
560
|
+
embeddings.ts # Embedder interface + encode/decode utils
|
|
561
|
+
privacy.ts # redact() — runs on every capture
|
|
562
|
+
tokens.ts # gpt-tokenizer wrapper
|
|
414
563
|
hooks/
|
|
415
|
-
post_session.ts
|
|
416
|
-
pre_prompt.ts
|
|
417
|
-
pre_read.ts
|
|
418
|
-
mcp/
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
564
|
+
post_session.ts # SessionEnd: extract → store → index → log
|
|
565
|
+
pre_prompt.ts # UserPromptSubmit: cache lookup
|
|
566
|
+
pre_read.ts # PreToolUse: file gating
|
|
567
|
+
mcp/ # MCP server + tool implementations
|
|
568
|
+
dashboard/
|
|
569
|
+
index.html # single-page dashboard (served by somtum serve)
|
|
570
|
+
config.ts # global + project config merge
|
|
571
|
+
index.ts # public API for embedding Somtum
|
|
572
|
+
src/db/migrations/ # NNN_name.sql migration files
|
|
422
573
|
test/
|
|
423
|
-
golden/
|
|
424
|
-
bench/
|
|
425
|
-
fixtures/
|
|
574
|
+
golden/ # per-strategy retrieval golden sets
|
|
575
|
+
bench/ # hot-path latency benchmarks
|
|
576
|
+
fixtures/ # synthetic session transcripts
|
|
426
577
|
```
|
|
427
578
|
|
|
428
579
|
### Adding a new observation kind
|
|
@@ -441,36 +592,155 @@ test/
|
|
|
441
592
|
|
|
442
593
|
---
|
|
443
594
|
|
|
444
|
-
...
|
|
445
|
-
|
|
446
595
|
## Troubleshooting
|
|
447
596
|
|
|
597
|
+
### `somtum stats` shows `memories 0` after a session
|
|
598
|
+
|
|
599
|
+
This almost always means the hook ran but extraction failed. Check the log first:
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
cat ~/.somtum/hook.log
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
Common causes:
|
|
606
|
+
|
|
607
|
+
**`ANTHROPIC_API_KEY` not set in shell profile**
|
|
608
|
+
|
|
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.
|
|
610
|
+
|
|
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
|
+
```
|
|
623
|
+
|
|
624
|
+
**Hook not installed in the right directory**
|
|
625
|
+
|
|
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.
|
|
627
|
+
|
|
628
|
+
Fix: run `somtum init` from the same directory you use to launch Claude Code.
|
|
629
|
+
|
|
630
|
+
```bash
|
|
631
|
+
cd ~/my-project
|
|
632
|
+
somtum init
|
|
633
|
+
claude # must be launched from ~/my-project
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
**Short or trivial session**
|
|
637
|
+
|
|
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.
|
|
649
|
+
|
|
650
|
+
---
|
|
651
|
+
|
|
652
|
+
### `somtum serve` opens the browser but shows "Connection refused"
|
|
653
|
+
|
|
654
|
+
This was a bug fixed in v1.1.0. Upgrade:
|
|
655
|
+
|
|
656
|
+
```bash
|
|
657
|
+
npm install -g somtum@latest
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
If you installed from source, rebuild:
|
|
661
|
+
|
|
662
|
+
```bash
|
|
663
|
+
pnpm build
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
---
|
|
667
|
+
|
|
668
|
+
### `somtum serve` — port already in use
|
|
669
|
+
|
|
670
|
+
If port 3000 is busy, use `--port`:
|
|
671
|
+
|
|
672
|
+
```bash
|
|
673
|
+
somtum serve --port 3001
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
---
|
|
677
|
+
|
|
678
|
+
### Agent appears to keep running after session ends
|
|
679
|
+
|
|
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+:
|
|
681
|
+
|
|
682
|
+
```bash
|
|
683
|
+
somtum --version
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
And check the log for any long-running operations:
|
|
687
|
+
|
|
688
|
+
```bash
|
|
689
|
+
tail -20 ~/.somtum/hook.log
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
---
|
|
693
|
+
|
|
694
|
+
|
|
448
695
|
### Installation fails (node-gyp / better-sqlite3)
|
|
449
696
|
|
|
450
|
-
If you see errors related to building `better-sqlite3`, ensure
|
|
697
|
+
If you see errors related to building `better-sqlite3`, ensure build tools are installed:
|
|
451
698
|
|
|
452
699
|
- **macOS:** `xcode-select --install`
|
|
453
700
|
- **Ubuntu/Debian:** `sudo apt-get install build-essential python3`
|
|
454
701
|
- **Windows:** `npm install --global --production windows-build-tools`
|
|
455
702
|
|
|
456
|
-
|
|
703
|
+
---
|
|
704
|
+
|
|
705
|
+
### Embeddings are slow or the model won't download
|
|
706
|
+
|
|
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.
|
|
708
|
+
|
|
709
|
+
If you are on an air-gapped machine or prefer not to use embeddings, disable them:
|
|
457
710
|
|
|
458
|
-
|
|
711
|
+
```bash
|
|
712
|
+
somtum config set retrieval.embeddings.enabled false
|
|
713
|
+
somtum config set retrieval.strategy bm25
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
BM25 retrieval works fully offline and is fast at any reasonable corpus size.
|
|
717
|
+
|
|
718
|
+
---
|
|
459
719
|
|
|
460
720
|
### Claude isn't using the memories
|
|
461
721
|
|
|
462
|
-
|
|
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:
|
|
723
|
+
|
|
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"_
|
|
727
|
+
|
|
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:
|
|
729
|
+
|
|
730
|
+
```
|
|
731
|
+
See ~/.somtum/projects/<project_id>/index.md for prior session learnings.
|
|
732
|
+
```
|
|
463
733
|
|
|
464
734
|
---
|
|
465
735
|
|
|
466
736
|
## Contributing
|
|
467
737
|
|
|
468
|
-
Contributions are welcome!
|
|
738
|
+
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for the guide.
|
|
469
739
|
|
|
470
|
-
**Important
|
|
740
|
+
**Important:** This project uses `changesets` for versioning. Every PR must include a changeset file generated by running `pnpm changeset`.
|
|
471
741
|
|
|
472
742
|
---
|
|
473
743
|
|
|
474
744
|
## License
|
|
475
745
|
|
|
476
|
-
Licensed under the
|
|
746
|
+
Licensed under the [MIT License](LICENSE).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config_cmd.js","sourceRoot":"","sources":["../../src/cli/config_cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,uBAAuB,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"config_cmd.js","sourceRoot":"","sources":["../../src/cli/config_cmd.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/doctor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,CAoKnE;AAED,wBAAsB,aAAa,CACjC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
|
package/dist/cli/doctor.js
CHANGED
|
@@ -113,7 +113,16 @@ export function runDoctor(opts = {}) {
|
|
|
113
113
|
? `enabled (model: ${config.retrieval.embeddings.model}) — run \`somtum reindex\` to embed missing`
|
|
114
114
|
: 'disabled (set retrieval.embeddings.enabled=true to enable)',
|
|
115
115
|
});
|
|
116
|
-
// 11.
|
|
116
|
+
// 11. ANTHROPIC_API_KEY present
|
|
117
|
+
const apiKey = process.env['ANTHROPIC_API_KEY'];
|
|
118
|
+
checks.push({
|
|
119
|
+
name: 'api_key',
|
|
120
|
+
ok: Boolean(apiKey && apiKey.trim().length > 0),
|
|
121
|
+
detail: apiKey && apiKey.trim().length > 0
|
|
122
|
+
? 'ANTHROPIC_API_KEY is set'
|
|
123
|
+
: 'ANTHROPIC_API_KEY is not set — the SessionEnd hook needs it to extract observations. Set it in your shell profile (e.g. export ANTHROPIC_API_KEY=sk-ant-...).',
|
|
124
|
+
});
|
|
125
|
+
// 12. Hook files in .claude/settings.json
|
|
117
126
|
const settingsPath = join(cwd, '.claude', 'settings.json');
|
|
118
127
|
if (existsSync(settingsPath)) {
|
|
119
128
|
try {
|