engramx 2.0.2 → 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 (35) hide show
  1. package/CHANGELOG.md +271 -0
  2. package/README.md +161 -17
  3. package/dist/{aider-context-BC5R2ZTA.js → aider-context-6IDE3R7U.js} +1 -1
  4. package/dist/check-2Z3MPZEJ.js +12 -0
  5. package/dist/{chunk-PEH54LYC.js → chunk-645NBY6L.js} +42 -5
  6. package/dist/chunk-73IBCRFI.js +215 -0
  7. package/dist/{chunk-SJT7VS2G.js → chunk-B4UOE64J.js} +46 -11
  8. package/dist/chunk-FKY6HIT2.js +99 -0
  9. package/dist/{chunk-533LR4I7.js → chunk-G4U3QOOW.js} +13 -97
  10. package/dist/chunk-RJC6RNXJ.js +1405 -0
  11. package/dist/chunk-RM2TBOVW.js +121 -0
  12. package/dist/chunk-SMU4WR3D.js +187 -0
  13. package/dist/{chunk-C6GBUOAL.js → chunk-VLTWBTQ7.js} +14 -15
  14. package/dist/chunk-XVYE4OX2.js +232 -0
  15. package/dist/chunk-ZUC6OXSL.js +178 -0
  16. package/dist/cli.js +818 -1533
  17. package/dist/{core-6IY5L6II.js → core-77F2BVYV.js} +2 -2
  18. package/dist/{cursor-mdc-GJ7E5LDD.js → cursor-mdc-EEO7PYZ3.js} +1 -1
  19. package/dist/{exporter-GWU2GF23.js → exporter-ZYJ4WM2F.js} +1 -1
  20. package/dist/{importer-V62NGZRK.js → importer-4UWQDH4W.js} +1 -1
  21. package/dist/index.js +3 -3
  22. package/dist/install-YVMVCFQW.js +121 -0
  23. package/dist/mcp-client-ROOJF76V.js +9 -0
  24. package/dist/mcp-config-QD4NPVXB.js +12 -0
  25. package/dist/{migrate-UKCO6BUU.js → migrate-KJ5K5NWO.js} +1 -1
  26. package/dist/notify-5POGKMRX.js +36 -0
  27. package/dist/{plugin-loader-STTGYIL5.js → plugin-loader-SQQB6V74.js} +69 -23
  28. package/dist/report-C3GTM3HY.js +12 -0
  29. package/dist/resolver-H7GXVP73.js +21 -0
  30. package/dist/serve.js +5 -4
  31. package/dist/{server-KUG7U6SG.js → server-2ZQKXJ5M.js} +74 -4
  32. package/dist/{windsurf-rules-C7SVDHBL.js → windsurf-rules-XF7MYF6J.js} +1 -1
  33. package/dist/wizard-UH27IO4I.js +274 -0
  34. package/package.json +3 -2
  35. package/dist/{tuner-KFNNGKG3.js → tuner-Y2YENAZC.js} +3 -3
package/CHANGELOG.md CHANGED
@@ -4,6 +4,277 @@ All notable changes to engram are documented here. Format based on
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning follows
5
5
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [Unreleased]
8
+
9
+ ## [3.0.0] — 2026-04-24 — "Spine"
10
+
11
+ The biggest engramx release since v1.0. One meticulous release, not a
12
+ staircase — per the decision log at `~/Desktop/Projects/Engram/00-strategy/decisions/`
13
+ (single-release-vs-staircase + engramx-canonical-brand).
14
+
15
+ Headline: engramx becomes the **extensible context spine**. Any MCP
16
+ server plugs in via a 10-line plugin file; every provider's output is
17
+ budget-weighted, mistake-boosted, and streamed progressively via SSE;
18
+ the mistakes moat grows two new capabilities (bi-temporal validity +
19
+ pre-mortem warnings); `engram gen` emits both `CLAUDE.md` AND `AGENTS.md`
20
+ by default. **Real-world benchmark: 89.1% measured savings** on engramx's
21
+ own 87-file sample (committed report in `bench/results/`).
22
+
23
+ Contributor credit: [@mechtar-ru](https://github.com/mechtar-ru) for PR #6
24
+ (OOM fixes on large codebases — cherry-picked with preserved authorship).
25
+
26
+ ### Added — v3.0 "Spine" track
27
+
28
+ **Pillar 1 — Capabilities to add to it (extensibility foundation)**
29
+ - **Generic MCP-client aggregator** (`src/providers/mcp-client.ts`). Spawn or HTTP-connect to any MCP server, cache tool lists, call tools with timeout + retry, normalize into `ProviderContext`. Config at `~/.engram/mcp-providers.json`. Per-provider budgets, graceful degradation, process shutdown hooks. Uses `@modelcontextprotocol/sdk` v1.29 behind an internal abstraction so future SDK v2 migration is a single-file swap. Stdio transport ships; HTTP path stubbed pending post-3.0 Host/Origin hardening integration.
30
+ - **Provider plugin contract v2** (`src/providers/plugin-loader.ts`). Plugins declaring an `mcpConfig` instead of a custom `resolve()` are auto-wrapped via `createMcpProvider()`. Classic plugins with hand-rolled `resolve()` still work unchanged. Custom `resolve()` wins if both are present. 10-line plugins are now possible.
31
+ - **Budget-weighted resolver + mistakes-boost reranking** (`src/providers/resolver.ts`). Per-provider token budgets enforced as a backstop even if a provider ignores its contract. Results whose content mentions a known-mistake label get confidence × 1.5 (capped at 1.0) — boost breaks ties within a priority tier without overriding priority across tiers. Case-insensitive label matching.
32
+
33
+ **Pillar 2 — Save proper context**
34
+ - **Anthropic Auto-Memory bridge** (`src/providers/anthropic-memory.ts`). Reads Claude Code's auto-managed `~/.claude/projects/<encoded>/memory/MEMORY.md` index, surfaces entries scored against the current file's basename / imports / path segments. Tier 1, runs under 10 ms, max 1 MB hard-cap on index size. Override via `ENGRAM_ANTHROPIC_MEMORY_PATH` for tests + advanced users. Inserted at `PROVIDER_PRIORITY[3]` between mistakes and mempalace.
35
+ - **Streaming partial context packets via SSE** (`/context/stream?file=<path>` endpoint + `resolveRichPacketStreaming()` generator). Emit one SSE frame per provider as it resolves. Matches MCP SEP-1699: every frame carries an `id:` for `Last-Event-ID` resumption on reconnect. Client disconnect mid-stream aborts the generator cleanly. Inherits existing auth + Host + Origin guards.
36
+ - **Serena plugin reference** at `docs/plugins/examples/serena-plugin.mjs` (10-line mcpConfig plugin — install instructions in `docs/plugins/README.md`).
37
+
38
+ **Pillar 3 — Really help users (mistakes moat)**
39
+ - **Bi-temporal validity on mistake nodes**: schema migration 8 adds `valid_until` and `invalidated_by_commit` columns plus a partial index `idx_nodes_validity`. Mistakes whose `validUntil` is in the past are filtered out by the `engram:mistakes` provider. Backward-compatible: legacy rows without the columns keep firing (NULL = still valid).
40
+ - **Pre-mortem mistake-guard** (`src/intercept/handlers/mistake-guard.ts`). Opt-in via `ENGRAM_MISTAKE_GUARD=1` (permissive: warns via `additionalContext`) or `=2` (strict: denies the tool call). Matches Edit/Write against the file's mistake nodes via indexed `getNodesByFile`; matches Bash against `metadata.commandPattern` substrings and `sourceFile` mentions in the command. Respects the bi-temporal filter. Zero overhead when unset.
41
+
42
+ **Hygiene / ecosystem**
43
+ - `engram gen` emits BOTH `CLAUDE.md` AND `AGENTS.md` by default (Linux Foundation universal agent-instructions standard; adopted by Codex CLI, Cursor, Windsurf, Copilot, Junie, Antigravity). Explicit `--target=claude|cursor|agents` preserves single-file behavior.
44
+ - README opens with **"What engramx is not"** section — disarms collision with Go-Engram (Gentleman-Programming/engram), DeepSeek's "Engram" paper (Jan 2026), and MemPalace in the first 30 seconds of any new visitor read.
45
+ - PR #6 (`@mechtar-ru`) cherry-picked ourselves with preserved authorship: `MAX_DEPTH=100` in ast-miner's directory walk, `MAX_FILES_PER_COMMIT=50` in git-miner's co-change analysis, expanded default skip dirs. Dead-code cleanup of duplicate `DEFAULT_EXCLUDED_DIRS` / `loadEngramIgnore` that had shipped alongside v2.1's newer `DEFAULT_SKIP_DIRS` / `loadIgnorePatterns`. Closes issue #5.
46
+
47
+ ### Proof — real-world benchmark (new, committed)
48
+
49
+ `bench/real-world.ts` runs the full resolver pipeline against the repo's own source tree and compares rich-packet tokens to raw-file-read tokens. Latest run (2026-04-24, 100-file scale-out, 87 files actually sampled after skip rules):
50
+
51
+ | Metric | Value |
52
+ |---|---|
53
+ | Baseline tokens (raw Read of every file) | 163,122 |
54
+ | engramx tokens (rich packets) | 17,722 |
55
+ | Aggregate savings | **89.1%** |
56
+ | Median per-file savings | 84.2% |
57
+ | Files where engramx saved tokens | 85 of 87 |
58
+ | Best case (`src/cli.ts`) | 98.4% (18,820 → 306) |
59
+
60
+ Reproducible by anyone, on any project: `npx tsx bench/real-world.ts --project . --files 50`.
61
+
62
+ ### Changed
63
+
64
+ - `autogen()` return type: `{ file: string }` → `{ files: string[] }` (single caller in `cli.ts` updated). Consumers of the programmatic API who called `result.file` must read `result.files[0]` instead (or use `--target` to keep single-file semantics).
65
+ - `PROVIDER_PRIORITY` gains `anthropic:memory` at index 3 — downstream test that hard-coded the array order was updated.
66
+ - `MIGRATIONS` (src/db/migrate.ts): extended from `Record<number, string>` to `Record<number, string | ((db) => void)>` so migrations that need non-idempotent DDL (like `ALTER TABLE ADD COLUMN`) can guard with `PRAGMA table_info` checks.
67
+ - README badge updates: tests 640 → 876, providers 8 → 9, savings 88.1% → 90.8%.
68
+
69
+ ### Migration
70
+
71
+ **v2.1 → v3.0 is schema-migration-required and automatic**: first open of your existing `.engram/graph.db` triggers migration 8. A `.bak-v7` backup is written alongside. Legacy mistake rows survive unchanged (NULL `validUntil` = still valid). Verified on a simulated v2.1 DB during release audit.
72
+
73
+ **API consumers of `autogen()`** must update call sites: `result.file` (single string) → `result.files` (array). CLI callers are unaffected.
74
+
75
+ ### Tests
76
+
77
+ 771 → 876 passing (+105 new). CI green Ubuntu+Windows × Node 20+22. TypeScript `--noEmit` clean, lint clean.
78
+
79
+ ## [2.1.0] — 2026-04-21 — "Reliability + Zero-Friction Install"
80
+
81
+ First release in the v2.1 / v2.2 / v3.0 elevation trilogy. Design spec
82
+ at `docs/superpowers/specs/2026-04-20-engram-elevation-trilogy-design.md`.
83
+
84
+ Headline: `engram setup` is the new one-command first-run flow. Users
85
+ go from `npm install -g engramx` to a working Sentinel hook + indexed
86
+ graph in under 30 seconds. `engram doctor` reports component health
87
+ with remediation hints. `engram update` ships future hotfixes to every
88
+ install without surprise — passive notify, zero telemetry, one-command
89
+ upgrade. Plus fixes for issue #11 (AST/LSP path bug in flattened
90
+ bundles) and issue #14's Bash-ops half (auto-reindex on `rm`/`mv`/
91
+ `git rm` via an opt-in PostToolUse gate).
92
+
93
+ Contributor credit this release: [@gabiudrescu](https://github.com/gabiudrescu)
94
+ for PR #13 (reindex CLI + `install-hook --auto-reindex`), PR #12
95
+ (watcher prune on delete/rename), and the original v2.0.2 security
96
+ disclosure. [@ttessarolo](https://github.com/ttessarolo) for precise
97
+ forensics + suggested fix on issue #11.
98
+
99
+ ### Added — v2.1 "Reliability + Zero-Friction Install" track
100
+
101
+ - **`engram update`** — one-command self-upgrade.
102
+ Passive notify on every `engram *` invocation when a newer version is
103
+ available (cached, at most one line on stderr, throttled to a 7-day
104
+ registry check). Manual trigger detects the package manager that owns
105
+ the engram install (npm / pnpm / yarn / bun via install-path markers)
106
+ and shells out to its global-upgrade command. `--check` for dry-probe,
107
+ `--force` to bypass the 7-day throttle, `--dry-run` to print the
108
+ upgrade command without executing it, `--manager <mgr>` override.
109
+ Zero telemetry: the only network call is an anonymous GET to
110
+ `registry.npmjs.org/engramx/latest`. `ENGRAM_NO_UPDATE_CHECK=1` and
111
+ `$CI` disable the entire subsystem. Addresses the "1,300 weekly
112
+ downloads, 10/day organic, near-zero hotfix reach" problem.
113
+
114
+ - **`engram doctor`** — component health report with remediation hints.
115
+ Wraps existing probes (HTTP, LSP, AST, IDE adapters) plus four new
116
+ checks: engram version freshness, `.engram/graph.db` presence,
117
+ Sentinel hook installation, IDE adapter count. Each check emits
118
+ severity (ok / warn / fail) + detail + optional remediation. Exit
119
+ code reflects overall severity (0 ok, 1 warn, 2 fail) so `doctor`
120
+ is CI-friendly. `--verbose` shows remediation hints; `--json` /
121
+ `--export` emits redacted JSON for bug-report attachment
122
+ (`projectRoot` intentionally omitted — can contain usernames).
123
+
124
+ - **`engram setup`** — zero-friction first-run wizard. One command for
125
+ "go from cloned repo to working engram in under 30 seconds."
126
+ Runs `init` (if `.engram/graph.db` missing) → `install-hook` (with
127
+ prompted scope, `local` default) → detects IDE adapters (Cursor,
128
+ Windsurf, Continue.dev, Aider) and suggests the matching `gen-*`
129
+ command for each → finishes with a `doctor` summary. Each step is
130
+ idempotent. `--yes` runs with defaults; `--dry-run` prints intent
131
+ without acting; `--scope` controls the install-hook scope. Drops
132
+ install-to-first-value from 4 commands to 1.
133
+
134
+ - **`engram init --with-hook`** — shorthand for `init` followed by
135
+ `install-hook` (local scope, idempotent). The #1 thing every user
136
+ does after `init` was `install-hook`; now it's one step.
137
+
138
+ - **First-run hint.** On any `engram` subcommand invoked in a repo
139
+ lacking `.engram/graph.db`, print one line on stderr:
140
+ `💡 First time in this repo? Run 'engram setup' for a zero-friction install.`
141
+ Throttled via `~/.engram/first-run-shown` (fires once per machine,
142
+ not per repo). Silenced in `$CI`, under `ENGRAM_NO_UPDATE_CHECK=1`,
143
+ and under the JSON-stdout commands (`intercept`, `cursor-intercept`,
144
+ `hud-label`, `setup`, `init`, `update`, `doctor`) so neither
145
+ pollutes the hook protocol.
146
+
147
+ - **Bash PostToolUse parser for auto-reindex** — closes half of
148
+ [#14](https://github.com/NickCirv/engram/issues/14).
149
+ `src/intercept/handlers/bash-postool.ts` parses file-mutating Bash
150
+ commands (`rm`, `mv`, `cp`, `git rm`, `git mv`, single-redirect
151
+ `<cmd> > <dst>`) into `FileOp { action, path }` records. Strict
152
+ parser: globs, pipes, subshells, command-substitution, directory
153
+ ops, and `touch` all pass through untouched. Wired into the
154
+ PostToolUse observer path in `handlers/post-tool.ts` — on Bash
155
+ PostToolUse events, each op is handed to `syncFile()` fire-and-forget.
156
+ Gated by `ENGRAM_AUTO_REINDEX=1` opt-in until
157
+ [#13](https://github.com/NickCirv/engram/pull/13)'s install-hook
158
+ `--auto-reindex` flag lands; that flag will toggle the env gate
159
+ implicitly.
160
+
161
+ ### Fixed — v2.1 reliability
162
+
163
+ - **AST grammar detection in flattened bundles**
164
+ ([#11](https://github.com/NickCirv/engram/issues/11) partial).
165
+ When `tsup`/`esbuild` flattens chunks to `engramx/dist/chunk-*.js`,
166
+ `import.meta.url` resolves to `engramx/dist` and the previous
167
+ candidates (`../grammars` and `../../dist/grammars`) both missed the
168
+ actual grammar dir. Added `join(here, "grammars")` as the first
169
+ candidate; dev-time layout (`src/intercept/`) still works via the
170
+ third candidate. Thanks [@ttessarolo](https://github.com/ttessarolo).
171
+
172
+ - **LSP socket candidate coverage**
173
+ ([#11](https://github.com/NickCirv/engram/issues/11) partial).
174
+ `checkLsp` was looking for two socket names while
175
+ `lsp-connection.ts::candidateSockets()` probes six. Synced the list
176
+ so HUD availability matches actual provider availability. Kept
177
+ `.engram/lsp-available` as an explicit user opt-in marker for
178
+ back-compat.
179
+
180
+ ### Fixed
181
+
182
+ - **Locale-independent number formatting across the codebase.** All 10
183
+ `Number.prototype.toLocaleString()` callsites in `src/cli.ts`,
184
+ `src/serve.ts`, `src/dashboard.ts`, and `src/intercept/stats.ts` have
185
+ been migrated to a shared `formatThousands()` helper in
186
+ `src/graph/render-utils.ts`. Two wins:
187
+
188
+ 1. **Deterministic performance.** First-call ICU init on Windows Node
189
+ has been observed to take multiple seconds in GitHub Actions VMs,
190
+ flaking tests at the 5000ms default timeout (seen on
191
+ `tests/intercept/stats.test.ts > formatStatsSummary` post-merge on
192
+ `9f99f5b`). The regex-based helper runs in microseconds with no
193
+ ICU dependency.
194
+ 2. **Locale independence.** `toLocaleString()` emits `"1,234"` on
195
+ en-US but `"1.234"` on de-DE and `"1 234"` on fr-FR, giving users
196
+ running engram in non-US shells inconsistent output. All CLI +
197
+ MCP server + dashboard numbers now render with commas regardless
198
+ of system locale.
199
+
200
+ Added `tests/render-utils.test.ts > formatThousands` — 6 tests
201
+ covering single-digit, multi-group, negative, and locale-stable cases.
202
+ Also added `vitest.config.ts` with CI-only `retry: 1` +
203
+ `testTimeout: 15000ms` as defense-in-depth against other cold-worker
204
+ flakes.
205
+
206
+ - **`engram watch` now prunes graph nodes when watched files are deleted
207
+ or renamed** ([#9](https://github.com/NickCirv/engram/issues/9),
208
+ [#12](https://github.com/NickCirv/engram/pull/12)). Previously the
209
+ watcher only subscribed to `change` events, silently ignoring the
210
+ `rename` events that `fs.watch` fires for create/unlink across all
211
+ platforms. Deletions left stale nodes in the graph until the next
212
+ `engram init`; renames produced duplicate nodes under the old and new
213
+ `sourceFile` paths. Thanks [@gabiudrescu](https://github.com/gabiudrescu).
214
+
215
+ ### Added
216
+
217
+ - **`syncFile(absPath, root)`** exported from `src/watcher.ts` — the shared
218
+ "exists → reindex; gone (and was indexed) → prune" primitive reused by
219
+ the upcoming `engram reindex` CLI subcommand ([#8](https://github.com/NickCirv/engram/issues/8)).
220
+ Returns a discriminated `SyncResult` (`indexed` | `pruned` | `skipped`).
221
+ - **`GraphStore.countBySourceFile(relPath)`** — noise-reduction gate so
222
+ `onDelete` only fires for files the graph actually indexed.
223
+ - **`onDelete` callback on `WatchOptions`** — fires with `(filePath, prunedCount)`
224
+ when the watcher prunes a deleted file's nodes.
225
+ - **`× <path> pruned (N nodes)`** log line in `engram watch`, distinct from
226
+ the existing green `↻` reindex line.
227
+ - **`gen-cursor --watch`, `gen-aider --watch`, `gen-windsurfrules --watch`**
228
+ now regenerate their output files on source-file delete (not just on
229
+ reindex), so generated artifacts no longer keep stale references to
230
+ deleted sources.
231
+ - **`engram reindex <file>` CLI subcommand**
232
+ ([#8](https://github.com/NickCirv/engram/issues/8)) — re-indexes a
233
+ single file into the knowledge graph. The missing primitive for per-
234
+ edit freshness: Claude Code PostToolUse hooks, editor plugins, and CI
235
+ can now keep the graph in sync without running a long-lived watcher.
236
+ Reuses `syncFile()` so semantics match `engram watch`: exists →
237
+ reindex; missing-but-previously-indexed → prune; unsupported ext or
238
+ ignored directory → silent exit 0 (safe to fire on every edit). On
239
+ success prints a single line `engram: reindexed <file> (<N> nodes)`
240
+ (or `pruned`) using locale-stable `formatThousands`. `--verbose`
241
+ surfaces stack traces; default error output is a single stderr line.
242
+ Missing graph exits 1 with `engram: no graph found at <root>. Run
243
+ 'engram init' first.`, matching `engram watch`.
244
+ - **`formatReindexLine(result, displayPath)`** exported from
245
+ `src/watcher.ts` — pure formatter shared by the new subcommand. Returns
246
+ `null` for skipped results so callers stay silent.
247
+ - **`engram reindex-hook` subcommand + `engram install-hook --auto-reindex`**
248
+ ([#8](https://github.com/NickCirv/engram/issues/8), opt-in auto-wire).
249
+ `reindex-hook` reads Claude Code's PostToolUse payload from stdin and
250
+ re-indexes `tool_input.file_path` via the shared `syncFile()` primitive.
251
+ Contract: ALWAYS exits 0 — malformed JSON, missing fields, non-project
252
+ `cwd`, and all internal errors resolve to a silent no-op so the hook
253
+ can never fail Claude Code's tool cycle. `install-hook --auto-reindex`
254
+ appends a second PostToolUse entry with matcher `Edit|Write|MultiEdit`
255
+ calling `engram reindex-hook`; off by default so existing users aren't
256
+ surprised. The new entry is recognized by `isEngramHookEntry()` so
257
+ `engram uninstall-hook` strips it alongside the primary intercept
258
+ entries. Idempotent — reinstalling with `--auto-reindex` is a no-op
259
+ when the entry already exists.
260
+ - **`runReindexHook(payload)`** exported from `src/watcher.ts` — the
261
+ pure async handler behind the `reindex-hook` subcommand. Validates
262
+ payload shape, resolves project root from `cwd`, delegates to
263
+ `syncFile`. Swallows every error.
264
+ - **`buildReindexHookEntry()` + `ENGRAM_REINDEX_HOOK_MATCHER`
265
+ (`"Edit|Write|MultiEdit"`) + `DEFAULT_ENGRAM_REINDEX_HOOK_COMMAND`
266
+ (`"engram reindex-hook"`)** exported from `src/intercept/installer.ts`
267
+ — the data primitives for the optional entry. Added
268
+ `InstallOptions.autoReindex` and `InstallResult.autoReindexAdded` to
269
+ thread the opt-in through the existing installer surface.
270
+
271
+ ### Notes
272
+
273
+ - Directory deletion (`rm -rf src/foo`) is intentionally not handled by the
274
+ watcher — `fs.watch` fires a single rename event on the directory path
275
+ with no per-file information. A full `engram init` handles that case
276
+ today; per-file directory-prefix pruning is tracked for v2.2.
277
+
7
278
  ## [2.0.2] — 2026-04-18 — Security hotfix: HTTP server auth & CORS
8
279
 
9
280
  **This is a security release. Upgrade immediately if you run `engram server`
package/README.md CHANGED
@@ -1,5 +1,34 @@
1
1
  <p align="center">
2
- <img src="assets/banner.png" alt="engram — AI coding memory" width="100%">
2
+ <img src="assets/banner-v3.png" alt="EngramXthe cached context spine for AI coding agents (v3.0 'Spine')" width="100%">
3
+ </p>
4
+
5
+ <!-- ============================================================
6
+ 24-second product showcase (Hyperframes-rendered MP4 + WebM).
7
+ Source: docs/demos/showcase.html · scenes drive both the
8
+ live HTML player and this MP4. Edit scene-table.md to change.
9
+ If the MP4 isn't rendered yet, GitHub gracefully shows the
10
+ poster image and links to the live HTML player.
11
+ ============================================================ -->
12
+ <p align="center">
13
+ <video src="https://raw.githubusercontent.com/NickCirv/engram/main/docs/demos/showcase.mp4"
14
+ controls
15
+ muted
16
+ playsinline
17
+ poster="docs/demos/poster.svg"
18
+ width="100%">
19
+ <a href="docs/demos/showcase.html">
20
+ <img src="docs/demos/poster.svg" alt="engram — 24-second showcase (click to open the live HTML player)" width="100%">
21
+ </a>
22
+ </video>
23
+ </p>
24
+
25
+ <p align="center">
26
+ <sub>
27
+ <a href="docs/install.html"><strong>Install Page</strong></a> ·
28
+ <a href="docs/demos/showcase.html"><strong>Live Demo</strong></a> ·
29
+ <a href="docs/demos/scene-table.md"><strong>Scene Table</strong></a> ·
30
+ rendered with <a href="https://github.com/heygen-com/hyperframes">Hyperframes</a>
31
+ </sub>
3
32
  </p>
4
33
 
5
34
  <p align="center">
@@ -18,33 +47,96 @@
18
47
  <a href="https://www.npmjs.com/package/engramx"><img src="https://img.shields.io/npm/v/engramx?color=blue" alt="npm version"></a>
19
48
  <img src="https://img.shields.io/badge/license-Apache%202.0-blue" alt="License">
20
49
  <img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen" alt="Node">
21
- <img src="https://img.shields.io/badge/tests-640%20passing-brightgreen" alt="Tests">
22
- <img src="https://img.shields.io/badge/providers-8%20%2B%20plugins-blue" alt="8 Providers + plugins">
23
- <img src="https://img.shields.io/badge/token%20savings-88.1%25%20measured-orange" alt="88% Proven Savings">
50
+ <img src="https://img.shields.io/badge/tests-876%20passing-brightgreen" alt="Tests">
51
+ <img src="https://img.shields.io/badge/providers-9%20%2B%20plugins-blue" alt="9 Providers + plugins">
52
+ <img src="https://img.shields.io/badge/token%20savings-90.8%25%20measured-orange" alt="90.8% measured savings">
24
53
  <img src="https://img.shields.io/badge/native%20deps-zero-green" alt="Zero native deps">
25
54
  <img src="https://img.shields.io/badge/LLM%20cost-$0-green" alt="Zero LLM cost">
26
55
  </p>
27
56
 
28
57
  ---
29
58
 
30
- > **v2.0 "Ecosystem" shipped 2026-04-17** — web dashboard at `engram ui`, 3-layer memory cache (23μs/op at 99% hit rate), provider plugin system (`~/.engram/plugins/*.mjs`), `engram cache` CLI, schema rollback with automatic backup, incremental re-indexing (78% faster on large repos), auto-bundled tree-sitter grammars, Windsurf + Neovim + Emacs integrations. See [CHANGELOG.md](CHANGELOG.md) for the full diff.
59
+ > **EngramX v3.0 "Spine" shipped 2026-04-24** — the biggest release since v1.0. The spine is now **extensible**: any MCP server becomes an EngramX provider via a 10-line plugin file. **Pre-mortem mistake-guard** warns before you repeat a bug. **Bi-temporal mistake memory** refactored-away mistakes stop firing. **Anthropic Auto-Memory bridge** reads Claude Code's own consolidated memory. **SSE-streaming** packets render progressively. `engram gen` dual-emits `AGENTS.md` + `CLAUDE.md` by default. **89.1% measured real-world token savings** on 87 source files reproducible in one command. 878 tests, CI green on Ubuntu + Windows × Node 20 + 22. Zero cloud, zero telemetry. See [CHANGELOG.md](CHANGELOG.md) for the full diff.
31
60
 
32
61
  ---
33
62
 
34
- # The context spine for AI coding agents.
63
+ # EngramX — the cached context spine for AI coding agents.
64
+
65
+ Your AI coding agent keeps re-reading the same files. Every `Read`, every `Edit`, every `cat` re-pays for context you've already paid for.
66
+
67
+ **EngramX is the spine.** It intercepts every file read at the tool boundary, answers from a pre-assembled context packet held in **three layers of cache** — a knowledge graph the agent has already "paid" to build, a per-provider SQLite cache of external lookups, and an in-memory LRU of recent queries — and hands the agent a single ~500-token response instead of a raw file.
35
68
 
36
- engram intercepts every file read your AI agent makes and replaces it with a pre-assembled context packet structure, decisions, git history, library docs, and known issues from 8 providers, delivered in a single ~500-token response. The agent gets what it needs without reading the file. You stop paying for context you've already paid for.
69
+ The agent gets what it needs. You stop paying for context you've already paid for. And **every plugin you add elevates the savings further** Serena for LSP symbols, GitHub MCP for issue context, Sentry MCP for production errors, Supabase / Neon for schema. Each one closes another context leak the agent would otherwise burn tokens researching.
37
70
 
38
- This is not a tool the agent calls. It hooks at the Claude Code tool boundary. Every `Read`, `Edit`, `Write`, and `cat` is intercepted automatically.
71
+ **Measured savings on a reproducible benchmark: 89.1%.** Not estimated. 85 of 87 real source files saved tokens. Best case 98.4% (18,820 tokens 306).
72
+
73
+ ### One command to everything
39
74
 
40
75
  ```bash
41
76
  npm install -g engramx
42
77
  cd ~/my-project
43
- engram init
44
- engram install-hook
78
+ engram setup
79
+ ```
80
+
81
+ That's the install. `engram setup` runs `engram init` (builds the graph), `engram install-hook` (wires the Sentinel into your AI tool), detects your IDE, dual-emits `AGENTS.md` + `CLAUDE.md`, then runs `engram doctor` to verify everything green. Under 30 seconds on most projects. Works in Claude Code, Cursor, Codex CLI, Windsurf, GitHub Copilot Chat, JetBrains Junie, Aider, Zed, Continue — any agent that reads `AGENTS.md` or uses MCP.
82
+
83
+ The **next session** you open starts with the spine pre-loaded: project brief already in context, file reads intercepted, a live HUD showing cumulative savings, bi-temporal mistakes waiting to warn you, and any plugins you've added already answering their domains.
84
+
85
+ ---
86
+
87
+ ## I'm not a developer — what does this actually do?
88
+
89
+ Short answer: **your AI coding assistant stops charging you for the same information twice.**
90
+
91
+ Long answer:
92
+
93
+ 1. You ask your AI assistant (Claude Code, Cursor, Codex, whatever) to help with a file.
94
+ 2. The assistant tries to read that file. Normally it reads the whole thing, pays for every byte in tokens, and throws most of it away.
95
+ 3. EngramX catches the read, answers with a cached summary (the 50–200 lines the agent actually needs, plus context from your git history, past mistakes, library docs, and anything else useful), and lets the agent work from that.
96
+ 4. Your monthly AI bill drops. Multi-hour sessions stop hitting rate limits. The agent stops re-introducing bugs you already fixed — because EngramX remembers what broke.
97
+
98
+ It runs on your laptop. It doesn't send your code anywhere. It's Apache 2.0. There's no account, no login, no cloud. You install it once and forget it's there.
99
+
100
+ **Want even bigger savings?** Install a plugin. Each one closes a different context leak — see [Plugins multiply the savings](#plugins-multiply-the-savings) below. Drop a 10-line `.mjs` file in `~/.engram/plugins/` and the next session uses it.
101
+
102
+ ---
103
+
104
+ ## Proof, not promises
105
+
106
+ Everything above is measured, not estimated. `bench/real-world.ts` runs the full resolver against real files in this repo and compares the rich-packet token cost to the raw-file-read cost. Reproducible in one command on any project.
107
+
108
+ Latest run (2026-04-24, 87 source files — full report at [`bench/results/real-world-2026-04-24.md`](bench/results/real-world-2026-04-24.md)):
109
+
110
+ | Metric | Value |
111
+ |---|---|
112
+ | Baseline tokens (87 files read raw) | **163,122** |
113
+ | engramx tokens (rich packets) | **17,722** |
114
+ | Aggregate savings | **89.1%** |
115
+ | Median per-file savings | 84.2% |
116
+ | Files where engramx saved tokens | 85 of 87 |
117
+ | Best case (`src/cli.ts`) | 98.4% (18,820 → 306) |
118
+
119
+ Reproduce on your own code:
120
+
121
+ ```bash
122
+ cd your-project
123
+ engram init # first-time setup for this project
124
+ npx tsx /path/to/engram/bench/real-world.ts --project . --files 50
45
125
  ```
46
126
 
47
- That's the full setup. The next Claude Code session starts with a project brief already loaded, file reads intercepted, and a live HUD showing cumulative savings.
127
+ The bench writes a JSON + Markdown report per run into `bench/results/`. Small projects score lower; dense structural projects score higher. It's real arithmetic on your files — you can audit every number.
128
+
129
+ ---
130
+
131
+ ## What engramx is not
132
+
133
+ The "engram" name is contested. To save you a search:
134
+
135
+ - **Not Go-Engram** ([Gentleman-Programming/engram](https://github.com/Gentleman-Programming/engram)) — different project, Go binary, salience-gated chat memory. Ships under `engram` (without the `x`).
136
+ - **Not DeepSeek's "Engram" paper** — January 2026 academic work on conditional memory. Research artifact, not a product.
137
+ - **Not MemPalace** — adjacent positioning ("knowledge-graph memory," "method-of-loci"), but conversational memory, not code-structural.
138
+
139
+ `engramx` is specifically: **a local-first context spine for AI coding agents that hooks into your IDE's tool boundary, indexes your code via tree-sitter + LSP, remembers past mistakes, and assembles ~500-token context packets in place of raw file reads.** Open source, Apache 2.0, single npm install.
48
140
 
49
141
  ---
50
142
 
@@ -99,6 +191,14 @@ See also the **Sessions** tab (cumulative breakdown + sparkline) in [`assets/scr
99
191
 
100
192
  ## Benchmark
101
193
 
194
+ engramx ships with two benchmarks — use whichever fits your workflow.
195
+
196
+ ### Real-world bench (new in v3.0, preferred)
197
+
198
+ `npx tsx bench/real-world.ts --project . --files 50` runs the full resolver against real files in any project and outputs exact token numbers. See the [Proof](#proof-not-promises) section above for the reproducible 89.1% result on engramx itself.
199
+
200
+ ### Structured task bench (CI regression)
201
+
102
202
  Measured across 10 structured coding tasks against a baseline of reading the relevant files directly. No synthetic data. No cherry-picked queries.
103
203
 
104
204
  | Task | Baseline (tokens) | engram (tokens) | Savings |
@@ -115,28 +215,46 @@ Measured across 10 structured coding tasks against a baseline of reading the rel
115
215
  | task-10-cross-file-flow | 12,800 | 1,400 | 89.1% |
116
216
  | **Aggregate** | **7,130** | **845** | **88.1%** |
117
217
 
118
- Run the benchmark yourself: `engram bench` or `engram stress-test` for the full suite.
218
+ Run it yourself: `npx tsx bench/runner.ts` (structured fixtures) or `npx tsx bench/real-world.ts` (live resolver on real files).
219
+
220
+ ---
221
+
222
+ ## Plugins multiply the savings
223
+
224
+ The 89.1% number is engramx with its 9 built-in providers. Every MCP server you plug in closes another context gap the agent would otherwise burn tokens researching. And because every provider is budget-capped and the resolver is budget-weighted + mistakes-boost reranked, more plugins = more *relevant* context without packet bloat.
225
+
226
+ | Plugin | Closes this gap | Install |
227
+ |---|---|---|
228
+ | **Serena** (LSP symbols, 20+ languages) | Cross-file references engramx's AST can't resolve precisely — kills the grep-then-read loop | `cp docs/plugins/examples/serena-plugin.mjs ~/.engram/plugins/` |
229
+ | **GitHub MCP** (issues, PRs, commits) | Recent PR discussion & issue history for the file being edited | `engram plugin install github` |
230
+ | **Sentry MCP** (production errors) | "What broke in prod for this file" — cuts the open-dashboard → paste-trace loop | `engram plugin install sentry` |
231
+ | **Supabase / Neon** (schema, RLS) | Database schema context when editing queries / migrations / ORM models | `engram plugin install supabase` |
232
+ | **Context7** (library docs) | Always-current API surface for your actual imports | shipped as a built-in |
233
+ | **Anthropic Auto-Memory** | Claude Code's own consolidated project memory | shipped — auto-detected when `~/.claude/projects/…/memory/MEMORY.md` exists |
234
+
235
+ Writing a plugin is **~10 lines** — see [`docs/plugins/README.md`](docs/plugins/README.md) for the full spec + examples.
119
236
 
120
237
  ---
121
238
 
122
239
  ## What It Does
123
240
 
124
- engram sits between your AI agent and the filesystem. When the agent reads a file, engram checks its knowledge graph. If the file is covered with sufficient confidence, it blocks the read and injects a compact context packet instead. The packet is assembled from up to 8 providers in parallel, all pre-cached at session start.
241
+ engram sits between your AI agent and the filesystem. When the agent reads a file, engram checks its knowledge graph. If the file is covered with sufficient confidence, it blocks the read and injects a compact context packet instead. The packet is assembled from up to 9 built-in providers plus any plugins you've added, all pre-cached at session start.
125
242
 
126
- **The 8 providers:**
243
+ **The 9 built-in providers (v3.0):**
127
244
 
128
245
  | Provider | Source | Confidence | Latency |
129
246
  |----------|--------|:-----------:|:-------:|
130
247
  | `engram:ast` | Tree-sitter parse (10 languages) | 1.0 | <50ms |
131
248
  | `engram:structure` | Regex heuristics (fallback) | 0.85 | <50ms |
132
- | `engram:mistakes` | Past failure nodes from graph | — | <10ms |
249
+ | `engram:mistakes` | Past failure nodes (bi-temporal stale mistakes filtered out) | — | <10ms |
250
+ | `anthropic:memory` | Claude Code's auto-managed `MEMORY.md` index (v3.0) | 0.85 | <10ms |
133
251
  | `engram:git` | Co-change patterns, churn, authorship | — | <100ms |
134
252
  | `mempalace` | Decisions, learnings, project context | — | <5ms cached |
135
253
  | `context7` | Library API docs for detected imports | — | <5ms cached |
136
254
  | `obsidian` | Project notes, architecture docs | — | <5ms cached |
137
255
  | `engram:lsp` | Live diagnostics captured as mistake nodes | — | on-event |
138
256
 
139
- External providers cache into SQLite at SessionStart. Per-read resolution is a cache lookup, not a live call. If a provider is unavailable it is skipped silently — you always get at least the structural summary.
257
+ External providers cache into SQLite at SessionStart. Per-read resolution is a cache lookup, not a live call. If a provider is unavailable it is skipped silently — you always get at least the structural summary. **Plus: any MCP server becomes a provider via a 10-line plugin file** — see [Plugins multiply the savings](#plugins-multiply-the-savings) above.
140
258
 
141
259
  **The 9 hook handlers:**
142
260
 
@@ -175,10 +293,23 @@ npm install -g engramx
175
293
 
176
294
  Requires Node.js 20+. Zero native dependencies. No build tools. Local SQLite via sql.js WASM — no Rust, no Python, no system libs.
177
295
 
296
+ > **Prefer a designed walkthrough?** Open [**docs/install.html**](docs/install.html) — three-step install, benefits matrix, IDE coverage, FAQ. Local file, opens in any browser. Brand-matched terminal-mono aesthetic.
297
+
178
298
  ---
179
299
 
180
300
  ## Quickstart
181
301
 
302
+ **One command, zero friction:**
303
+
304
+ ```bash
305
+ cd ~/my-project
306
+ engram setup # init + install-hook + adapter detect + doctor
307
+ ```
308
+
309
+ `engram setup` runs the whole first-run flow interactively (or pass `-y` for defaults, `--dry-run` to preview). It is idempotent — safe to re-run, and skips any step already done.
310
+
311
+ <sub>Prefer the individual commands?</sub>
312
+
182
313
  ```bash
183
314
  cd ~/my-project
184
315
  engram init # scan codebase → .engram/graph.db (~40ms, 0 tokens)
@@ -186,6 +317,16 @@ engram install-hook # wire the Sentinel into Claude Code
186
317
  engram ui # open the web dashboard in your browser
187
318
  ```
188
319
 
320
+ **Diagnostics + self-update:**
321
+
322
+ ```bash
323
+ engram doctor # component health + remediation hints (0=ok, 1=warn, 2=fail)
324
+ engram update # check + upgrade via detected pkg manager (no telemetry)
325
+ engram update --check # check only, dry-probe the registry
326
+ ```
327
+
328
+ Set `ENGRAM_NO_UPDATE_CHECK=1` to disable the passive "newer version available" hint on every CLI invocation. `$CI` does the same automatically.
329
+
189
330
  Open a Claude Code session. When the agent reads a well-covered file you will see a system-reminder with the structural summary instead of file contents. After the session:
190
331
 
191
332
  ```bash
@@ -210,7 +351,7 @@ engram hooks install # auto-rebuild graph on every git commit
210
351
  |------|-------------|-------------|
211
352
  | Graph only | `engram init` | CLI queries, MCP server, `engram gen` for CLAUDE.md |
212
353
  | + Sentinel | `engram install-hook` | Automatic Read interception, Edit warnings, session briefs, HUD |
213
- | + Context Spine | Configure providers.json | Rich packets from all 8 providers per read |
354
+ | + Context Spine | Configure providers.json | Rich packets from 9 built-ins + any MCP plugin per read |
214
355
  | + Skills index | `engram init --with-skills` | Graph includes your `~/.claude/skills/` |
215
356
  | + Git hooks | `engram hooks install` | Graph rebuilds on every commit, stays current |
216
357
  | + HTTP server | `engram server --http` | REST API on port 7337 for external tooling |
@@ -275,6 +416,7 @@ engram install-hook # default: .claude/settings.local.json (git
275
416
  engram install-hook --scope project # .claude/settings.json (committed)
276
417
  engram install-hook --scope user # ~/.claude/settings.json (global)
277
418
  engram install-hook --dry-run # preview changes without writing
419
+ engram install-hook --auto-reindex # also keep the graph fresh after every Edit/Write/MultiEdit (#8)
278
420
  ```
279
421
 
280
422
  **Kill switch (if anything goes wrong):**
@@ -336,6 +478,8 @@ engram hook-enable # remove kill switch
336
478
 
337
479
  ```bash
338
480
  engram watch [path] # live file watcher — incremental re-index on save
481
+ engram reindex <file> # re-index one file (editor/hook/CI primitive, issue #8)
482
+ engram reindex-hook # PostToolUse hook entry point (reads JSON from stdin, always exits 0)
339
483
  engram dashboard [path] # live terminal dashboard
340
484
  engram hud-label [path] # JSON label for Claude HUD --extra-cmd integration
341
485
  engram hooks install # install post-commit + post-checkout git hooks
@@ -7,7 +7,7 @@ function buildSection(heading, lines) {
7
7
  return [`## ${heading}`, "", ...lines, ""].join("\n");
8
8
  }
9
9
  async function generateAiderContext(projectRoot) {
10
- const { getStore } = await import("./core-6IY5L6II.js");
10
+ const { getStore } = await import("./core-77F2BVYV.js");
11
11
  const store = await getStore(projectRoot);
12
12
  try {
13
13
  const allNodes = store.getAllNodes();
@@ -0,0 +1,12 @@
1
+ import {
2
+ cachePath,
3
+ checkForUpdate,
4
+ isNewer,
5
+ optedOut
6
+ } from "./chunk-RM2TBOVW.js";
7
+ export {
8
+ cachePath,
9
+ checkForUpdate,
10
+ isNewer,
11
+ optedOut
12
+ };