pi-mega-compact 0.8.14 → 0.8.16

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 (89) hide show
  1. package/README.md +51 -463
  2. package/dist/extensions/dashboard-client/src/hooks/useApi.js +51 -0
  3. package/dist/extensions/dashboard-client/src/hooks/useSSE.js +63 -0
  4. package/dist/extensions/dashboard-server/html.js +15 -2
  5. package/dist/extensions/mega-cache-replay.test.js +4 -2
  6. package/dist/extensions/mega-compact-s38.test.js +317 -0
  7. package/dist/extensions/mega-compact.js +14 -0
  8. package/dist/extensions/mega-compact.test.js +37 -8
  9. package/dist/extensions/mega-config.js +5 -0
  10. package/dist/extensions/mega-events/agent-handlers.js +184 -4
  11. package/dist/extensions/mega-events/context-handler.js +35 -2
  12. package/dist/extensions/mega-events/error-classifier.js +118 -0
  13. package/dist/extensions/mega-events.js +1 -0
  14. package/dist/extensions/mega-runtime/state.js +82 -0
  15. package/dist/extensions/mega-runtime/state.test.js +37 -0
  16. package/dist/extensions/mega-runtime/widget.js +6 -2
  17. package/dist/extensions/mega-runtime/widget.test.js +47 -0
  18. package/dist/extensions/mega-teamrun.test.js +14 -1
  19. package/extensions/dashboard-client/dist/assets/{AchievementTiles-BH26e95w.js → AchievementTiles-BozP_h3c.js} +2 -2
  20. package/extensions/dashboard-client/dist/assets/{AchievementTiles-BH26e95w.js.map → AchievementTiles-BozP_h3c.js.map} +1 -1
  21. package/extensions/dashboard-client/dist/assets/{AchievementsTab-B94wvRV_.js → AchievementsTab-DKgqx1RQ.js} +2 -2
  22. package/extensions/dashboard-client/dist/assets/{AchievementsTab-B94wvRV_.js.map → AchievementsTab-DKgqx1RQ.js.map} +1 -1
  23. package/extensions/dashboard-client/dist/assets/{CacheTab-DPmw3NHR.js → CacheTab-CPvso4-0.js} +2 -2
  24. package/extensions/dashboard-client/dist/assets/{CacheTab-DPmw3NHR.js.map → CacheTab-CPvso4-0.js.map} +1 -1
  25. package/extensions/dashboard-client/dist/assets/ConfigTab-DXD7zbqy.js +2 -0
  26. package/extensions/dashboard-client/dist/assets/ConfigTab-DXD7zbqy.js.map +1 -0
  27. package/extensions/dashboard-client/dist/assets/{EventsTab-B5PicfFw.js → EventsTab-BGeuYvM3.js} +2 -2
  28. package/extensions/dashboard-client/dist/assets/{EventsTab-B5PicfFw.js.map → EventsTab-BGeuYvM3.js.map} +1 -1
  29. package/extensions/dashboard-client/dist/assets/{GameTab-CsVwp78a.js → GameTab-Qj19W1Y-.js} +2 -2
  30. package/extensions/dashboard-client/dist/assets/{GameTab-CsVwp78a.js.map → GameTab-Qj19W1Y-.js.map} +1 -1
  31. package/extensions/dashboard-client/dist/assets/{MetricsTab-Cf72UewX.js → MetricsTab-DA27vA95.js} +2 -2
  32. package/extensions/dashboard-client/dist/assets/{MetricsTab-Cf72UewX.js.map → MetricsTab-DA27vA95.js.map} +1 -1
  33. package/extensions/dashboard-client/dist/assets/{OverviewTab-Dh6aG3gy.js → OverviewTab-lVGR1Jl_.js} +2 -2
  34. package/extensions/dashboard-client/dist/assets/{OverviewTab-Dh6aG3gy.js.map → OverviewTab-lVGR1Jl_.js.map} +1 -1
  35. package/extensions/dashboard-client/dist/assets/{ReposTab-HXf2dorl.js → ReposTab-_HNR3qYj.js} +2 -2
  36. package/extensions/dashboard-client/dist/assets/{ReposTab-HXf2dorl.js.map → ReposTab-_HNR3qYj.js.map} +1 -1
  37. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-kUnoospE.js → TimeSavedCard-B7aPcBMs.js} +2 -2
  38. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-kUnoospE.js.map → TimeSavedCard-B7aPcBMs.js.map} +1 -1
  39. package/extensions/dashboard-client/dist/assets/{index-DMntLu-8.js → index-B2JJExE9.js} +3 -3
  40. package/extensions/dashboard-client/dist/assets/{index-DMntLu-8.js.map → index-B2JJExE9.js.map} +1 -1
  41. package/extensions/dashboard-client/dist/index.html +1 -1
  42. package/extensions/dashboard-client/src/styles/base.css +2 -1
  43. package/extensions/dashboard-client/src/tabs/ConfigTab.tsx +19 -2
  44. package/extensions/dashboard-server/html.ts +15 -2
  45. package/extensions/mega-cache-replay.test.ts +3 -3
  46. package/extensions/mega-compact-s38.test.ts +330 -0
  47. package/extensions/mega-compact.test.ts +41 -13
  48. package/extensions/mega-compact.ts +14 -0
  49. package/extensions/mega-config.ts +24 -0
  50. package/extensions/mega-dashboard.ts +7 -0
  51. package/extensions/mega-events/agent-handlers.ts +179 -5
  52. package/extensions/mega-events/context-handler.ts +31 -2
  53. package/extensions/mega-events/error-classifier.ts +109 -0
  54. package/extensions/mega-events.ts +1 -0
  55. package/extensions/mega-runtime/helpers.ts +5 -0
  56. package/extensions/mega-runtime/state.test.ts +33 -0
  57. package/extensions/mega-runtime/state.ts +81 -1
  58. package/extensions/mega-runtime/widget.test.ts +48 -0
  59. package/extensions/mega-runtime/widget.ts +6 -2
  60. package/extensions/mega-teamrun.test.ts +13 -1
  61. package/package.json +4 -1
  62. package/dist/extensions/dashboard-server/helpers.js +0 -37
  63. package/dist/extensions/dashboard-server/html/all-repos-tab.js +0 -26
  64. package/dist/extensions/dashboard-server/html/body-open.js +0 -23
  65. package/dist/extensions/dashboard-server/html/current-repo-tab.js +0 -130
  66. package/dist/extensions/dashboard-server/html/head-open.js +0 -16
  67. package/dist/extensions/dashboard-server/html/high-score-tab.js +0 -25
  68. package/dist/extensions/dashboard-server/html/repo-detail-modal.js +0 -26
  69. package/dist/extensions/dashboard-server/html/script.js +0 -259
  70. package/dist/extensions/dashboard-server/html/styles.js +0 -103
  71. package/dist/extensions/dashboard-server/html/summary-tab.js +0 -19
  72. package/dist/extensions/dashboard-server/html-template.js +0 -41
  73. package/dist/src/store/sqlite/connection.js +0 -35
  74. package/dist/src/store/sqlite/index-store.js +0 -167
  75. package/dist/src/store/sqlite/memory.js +0 -54
  76. package/dist/src/store/sqlite/minhash-lsh.js +0 -47
  77. package/dist/src/store/sqlite/sessions.js +0 -39
  78. package/dist/src/store/sqlite/transaction.js +0 -19
  79. package/dist/src/vectorStore/add.js +0 -260
  80. package/dist/src/vectorStore/dedup.js +0 -52
  81. package/dist/src/vectorStore/index.js +0 -10
  82. package/dist/src/vectorStore/queries.js +0 -83
  83. package/dist/src/vectorStore/search.js +0 -95
  84. package/dist/src/vectorStore/session.js +0 -19
  85. package/dist/src/vectorStore/store.js +0 -105
  86. package/dist/src/vectorStore/types.js +0 -6
  87. package/dist/src/vectorStore/utils.js +0 -23
  88. package/extensions/dashboard-client/dist/assets/ConfigTab-C3g3smRL.js +0 -2
  89. package/extensions/dashboard-client/dist/assets/ConfigTab-C3g3smRL.js.map +0 -1
package/README.md CHANGED
@@ -1,503 +1,91 @@
1
1
  # pi-mega-compact
2
2
 
3
- A **layered, local, vector-backed context compressor** for the
4
- [pi coding agent](https://github.com/earendil-works/pi). It compacts long
5
- sessions into a **local SQLite store** and offers **deduped inline recall** — all
6
- running **locally inside the extension**, with **no remote MCP server** and
7
- **zero network calls at runtime** (PREVENT-PI-004).
8
-
9
- > **Status - v0.7.9.** Storage uses the built-in `node:sqlite` backend
10
- > (`DatabaseSync`, Node >=22.13): zero native build step, fully local, and zero
11
- > network at runtime. See [RELEASE_NOTES.md](RELEASE_NOTES.md) for the full
12
- > changelog.
13
-
14
- ---
3
+ A local context compressor for the [pi coding agent](https://github.com/earendil-works/pi). Keeps long sessions running without overflowing the context window. All on your machine — no cloud, no API calls, no telemetry.
15
4
 
16
5
  ## Features
17
6
 
18
- - **Local & private** - everything stays on your disk. No telemetry, no API key, no MCP server, no cloud. The only network surface is an optional localhost dashboard you open yourself.
19
- - **Two-layer compaction** - a non-destructive live summary every LLM call, plus durable checkpoints that relieve context mid-run (not just at the end).
20
- - **Vector store + dedup** - each checkpoint is embedded and stored locally; an L0->L2 + RAPTOR cascade collapses duplicate work so storage and recall stay lean.
21
- - **Automatic recall** - the most relevant checkpoints are re-inlined on resume or branch switch; cross-repo memory-RAG augments a thin store with decisions from other repos.
22
- - **Live dashboard** - a localhost-only view of token usage, store stats, savings, per-repo activity, and an **Active Repos tab** that shows every currently-open session (last 30 minutes) side by side — so running multiple sessions at once is visible in one place.
23
- - **Database maintenance** - `/mega-db-*` commands plus best-effort auto-maintenance on session start.
24
-
25
- ## Table of contents
26
-
27
- - [Overview](#overview)
28
- - [How it works](#how-it-works)
29
- - [Installation](#installation)
30
- - [Usage](#usage)
31
- - [Configuration](#configuration)
32
- - [Dashboard](#dashboard)
33
- - [Architecture](#architecture)
34
- - [Development](#development)
35
- - [Testing & bug reports](#testing--bug-reports)
36
- - [Acknowledgements](#acknowledgements)
37
- - [License](#license)
38
-
39
- ## Overview
40
-
41
- pi's context window is finite. When a session gets long — especially a team run
42
- with sub-agents — pi-mega-compact keeps it going without overflowing:
43
-
44
- 1. **Watches one signal.** A single live `pressure = currentTokens / effectiveThreshold`
45
- drives everything — the tier label, how aggressively the live trim drops
46
- context, and how often durable memory is reviewed. `effectiveThreshold` is
47
- `tierPct × contextWindow` (a **% of the model's context window**), so the
48
- trim fires below pi's native ~80% auto-compaction for any model size. As
49
- context fills, the whole system reacts together; as it's relieved, it backs off.
50
- 2. **Compacts in two layers.** On every LLM call it returns a **live, compacted
51
- view** (the model sees a summary + recent anchor, non-destructively). And it
52
- persists a durable **checkpoint** — and, at each agent settle during a team
53
- run, fires pi's **native durable trim** so the on-disk transcript is actually
54
- truncated (context relieves mid-run, and resume reloads the trimmed transcript
55
- instead of a 150k window).
56
- 3. **Stores** each checkpoint in a **local vector database** (SQLite) with an
57
- embedding, so similar regions are found later and **duplicate work is never
58
- stored twice**.
59
- 4. **Recalls** the right context automatically — same-repo checkpoints on resume,
60
- plus **cross-repo memory-RAG**: decisions you saved in one repo are inlined as
61
- context when you start a session in another.
62
-
63
- Everything lives on **your disk**. No telemetry, no API, no MCP server, no cloud.
64
- The only optional network surface is a **user-triggered localhost dashboard** you
65
- open yourself.
66
-
67
- ### Why "mega"?
68
-
69
- The compaction pipeline is a **Trident** — three deterministic stages
70
- (supersede → collapse → cluster) that run over your conversation before anything
71
- is persisted. The checkpoint it produces is small (a summary + key decisions +
72
- next steps + files touched), so the same session that would otherwise overflow
73
- its window keeps going on a fraction of the tokens. On top of the Trident, a
74
- single pressure signal orchestrates the live trim, the durable trim, and memory
75
- review as one coherent system rather than four independent triggers.
76
-
77
- ---
78
-
79
- ## How it works
80
-
81
- ```
82
- Layer 5 Recall / Inline ONE local vector store → 3 entry points, 1 dedup engine
83
- Layer 4 Persist / Checkpoint compactSession() → embed + store in SQLite (chkpt_xxx)
84
- Layer 3 Cluster (vectorize) local vector index → semantic dedup + recall
85
- Layer 2 Collapse (summarize) summarizeMessages() heuristic + agent summary on /mega-compact
86
- Layer 1 Supersede (prune) drop obsolete file-reads / superseded turns (zero cost)
87
- ─────────────────────────────────────────────────────────────────────────
88
- Trigger context → token fast-gate → autoCompactCheck → live trim (per call)
89
- Durable agent_end (idle + over threshold) → ctx.compact() → session_before_compact
90
- supplies the summary; pi truncates the transcript (relieves context)
91
- Live context handler returns { messages:[summary, …recent] } — model sees a
92
- compacted window every LLM call; the on-disk transcript is untouched
93
- Marker insert compact-marker; dedupe so repeated triggers cost ~0 tokens
94
- ```
95
-
96
- **One store, three ways to read it back — one dedup engine:**
97
-
98
- | Entry point | Trigger | Behavior |
99
- | --- | --- | --- |
100
- | **Auto-inline** (Layer 5) | `session_start` / `session_tree` | Resume → `recallAndInline(source:"resume")` prepends the most relevant checkpoints, deduped against current context. |
101
- | **On-demand recall** | `/mega-recall [query]` | Semantic search the store, dedupe, and inline the top-K. |
102
- | **Dedup sentinel** | every compact | A lightweight `mega-compact-marker` entry lets auto-inline and recall skip re-injecting / re-vectorizing already-present regions. |
103
-
104
- **The dedup cascade** (shared across all entry points) collapses redundant work
105
- so storage and recall stay lean:
106
-
107
- - **L0 — exact:** SHA-256 content hash + region hash + summary hash. Identical (or
108
- whitespace/casing-normalized) regions collapse to one row.
109
- - **L1 — near-dup:** MinHash signatures + LSH bucketing + trigram verification
110
- catch one-word rewordings that L0 misses.
111
- - **L2 — semantic:** cosine over the embedding collapses paraphrases; MMR
112
- diversifies retrieval so a cluster of near-hits yields distinct results.
113
- - **RAPTOR — pre-compression tree** (shadow mode by default): a hierarchical
114
- summary tree over checkpoints, built + logged but not served until promoted.
115
-
116
- Every tier is gated by its own feature flag (see [Configuration](#configuration)).
117
- A tier can be put in `MARK_ONLY` (record the decision, don't collapse) as a safe
118
- partial-rollout or auto-degrade state.
119
-
120
- ### Embedding (two modes, both local)
7
+ - **Auto-compaction** watches context pressure and compacts in the background before you hit the ceiling
8
+ - **Two-layer compaction** live trim on every LLM call (model sees a smaller window) + durable checkpoints persisted to SQLite
9
+ - **Semantic dedup** — three-stage pipeline (exact hash MinHash/LSH cosine) collapses redundant work so nothing is stored twice
10
+ - **Cross-repo recall** decisions saved in one repo surface when you start a session in another
11
+ - **Durable memory** auto-reviews conversation every 10 turns, writes decisions/facts/preferences to SQLite, injects them as RAG context on recall
12
+ - **Fully local** SQLite + trigram embedder by default. Bring your own localhost embedder (ONNX, Ollama, TEI) for better semantic matching
13
+ - **Team-run aware** — fires native durable trim at agent settle during sub-agent runs, so context relieves mid-run not just at the end
14
+ - **Dashboard** optional localhost-only live dashboard with token gauge, store stats, and event stream
121
15
 
122
- The default embedder is **`TrigramEmbedder`** — a deterministic hashed trigram
123
- bag (512-dim, L2-normalized), **zero dependencies, instant, fully offline**. It
124
- is heuristic-strength, which is the right bar for "inline the right checkpoint,"
125
- not production RAG.
126
-
127
- **Optional: bring-your-own (BYO) localhost embedder.** Set
128
- `MEGACOMPACT_EMBEDDING_URL` to a **localhost/127.0.0.1** endpoint you run
129
- yourself (local ONNX/TEI/llamafile/Ollama-embeddings). The extension talks to it
130
- from `src/httpEmbedder.ts` (loopback-only — a remote host is rejected at config
131
- time, preserving PREVENT-PI-004). Compacted content never leaves the machine and
132
- no model ships with the extension. See `src/httpEmbedder.ts` for the
133
- OpenAI-style contract and the `MEGACOMPACT_EMBEDDING_KEY` / `MEGACOMPACT_EMBEDDING_HEADERS`
134
- / `MEGACOMPACT_EMBEDDING_DIM` options.
135
-
136
- > **Note on MiniLM:** a `MEGACOMPACT_MINILM` flag exists in `src/config/dedup.ts`
137
- > but defaults to **off**, and the MiniLM (all-MiniLM-L6-v2) ONNX embedder was
138
- > prototyped then deliberately **not shipped** (async-vs-sync conflict with the
139
- > synchronous VectorStore, second native dep, no free semantic win without a
140
- > network call). The `Embedder` interface remains the seam — inject a local
141
- > embedder (e.g. via your own `MEGACOMPACT_EMBEDDING_URL`) instead.
142
-
143
- ---
144
-
145
- ## Installation
146
-
147
- > **Full step-by-step guide** (pi + OpenClaw + every command + troubleshooting):
148
- > [`docs/INSTALL_AND_USAGE.md`](docs/INSTALL_AND_USAGE.md).
149
-
150
- ### Requirements
151
-
152
- - **Node >= 22.13** (the synchronous `node:sqlite` backend requires it; see
153
- `engines.node`). No native module is compiled — the store is a Node built-in.
154
- - No network call and no API key are needed at runtime (PREVENT-PI-004).
155
- - A pi coding agent install with package support (`pi install` / `pi update
156
- --extensions`). npm-installed packages are auto-discovered via the package's
157
- `pi` manifest entry; local checkouts load from `~/.pi/agent/extensions/`.
158
-
159
- ### Install from npm (recommended)
160
-
161
- pi installs extensions as **packages**. `pi install npm:<pkg>` writes an
162
- `npm:` source into your pi config's `packages` array; pi then auto-discovers the
163
- extension from the package's own `"pi": { "extensions": [...] }` manifest entry
164
- — **no manual `settings.json` edit is needed**.
16
+ ## Install
165
17
 
166
18
  ```bash
167
- pi install npm:pi-mega-compact # first time: adds to packages + installs
168
- pi update --extensions # thereafter: pulls the latest published version
19
+ pi install npm:pi-mega-compact
169
20
  ```
170
21
 
171
- `pi update --extensions` refreshes every `npm:` entry in `packages` (including on
172
- other devices that share this config). The package ships both the TypeScript
173
- source (which pi loads directly) and the compiled `dist/`, so nothing else needs
174
- building.
175
-
176
- > **Tip — keep the spec unpinned.** Use `npm:pi-mega-compact`, not
177
- > `npm:pi-mega-compact@0.5.1`. Version-pinned specs are *skipped* by
178
- > `pi update --extensions`, so a pin would freeze you on that release. The
179
- > installed version is always visible in the toolbar widget (`⚡ <tier> vX.Y.Z`)
180
- > and via `/mega-status`.
181
-
182
- > **From a git checkout (development only).** To hack on the extension, clone and
183
- > build locally, then symlink it into pi's extensions dir — but this bypasses the
184
- > package manager, so it is NOT updated by `pi update --extensions`. Convert to the
185
- > npm package (above) before shipping. The bundled `./install.sh` helper does the
186
- > symlink + config edit (needs `jq`).
187
- >
188
- > ```bash
189
- > git clone https://github.com/TheArchitectit/pi-mega-compact.git \
190
- > ~/.pi/agent/extensions/pi-mega-compact
191
- > cd ~/.pi/agent/extensions/pi-mega-compact
192
- > npm install && npm run build
193
- > ```
22
+ That's it. `pi update --extensions` pulls updates going forward.
194
23
 
195
- > **No tarballs — ever.** Distribution and updates go through `npm publish` +
196
- > `pi update --extensions` **only**. Never build or rely on a `.tgz` (`npm pack`):
197
- > a tarball bypasses pi's package manager and does not propagate to other devices.
198
- > To validate a real install, bump the version, `npm publish`, then
199
- > `pi update --extensions` on the device. (`.gitignore` rejects `*.tgz` so one can't
200
- > be committed by accident.)
201
-
202
- ### Storage
203
-
204
- pi-mega-compact uses a dual local backend — **zero network, no native build step**:
205
-
206
- - **`node:sqlite`** (`DatabaseSync`, Node ≥22.13 built-in) — the synchronous source of truth for checkpoints, session state, and the dedup index. No dependency, no install script, survives pi's `install-scripts` block.
207
- - **PGlite + `@electric-sql/pglite-pgvector`** (WASM Postgres + HNSW `vector_cosine_ops`) — an optional, best-effort async vector index for **cross-repo recall** at `~/.pi/mega-compact-vector`. It holds both checkpoint embeddings and durable-memory embeddings, so decisions saved in one repo are findable from another. The sync store stays authoritative; the index degrades to the sync per-session scan on any failure.
208
-
209
- Kill-switch: `MEGACOMPACT_PGLITE_DISABLED=1` fully disables the PGlite index (falls back to sync scan). Requires Node ≥22.13 (`engines.node`).
210
-
211
- ### Cross-repo recall
212
-
213
- On resume, recall augments from other repos' checkpoints when this repo's store is thin; `/mega-recall --cross-repo` searches all repos via the HNSW index. Cross-repo hits use a stricter cosine floor (`MEGACOMPACT_CROSSREPO_COSINE`, default 0.90) and are labeled with their source repo. A machine-wide injected-set (`~/.mega-compact-index/index.sqlite`) prevents re-injecting the same foreign checkpoint.
214
-
215
- ### Memory
216
-
217
- pi-mega-compact auto-reviews the conversation every 10 turns (the cadence shortens as pressure climbs) and writes durable `decision`/`fact`/`preference` memories to SQLite (local, hallucination-guarded). Relevant memories are injected as RAG context on recall (capped, deduped). **Cross-repo memory-RAG (S24):** every memory write is mirrored into the PGlite/HNSW index, so when same-repo recall is thin the system augments with the nearest memories from *other* repos (stricter `MEGACOMPACT_CROSSREPO_COSINE` floor, deduped against what's already in view). Manual: `/mega-memory save|list|forget` (or `/m`).
218
-
219
- ### Uninstall
24
+ <details>
25
+ <summary>From source (development)</summary>
220
26
 
221
27
  ```bash
222
- pi uninstall npm:pi-mega-compact # removes from settings.packages + the npm tree
223
- # or, to keep the config entry but drop the package:
224
- npm uninstall pi-mega-compact
28
+ git clone https://github.com/TheArchitectit/pi-mega-compact.git \
29
+ ~/.pi/agent/extensions/pi-mega-compact
30
+ cd ~/.pi/agent/extensions/pi-mega-compact
31
+ npm install && npm run build
225
32
  ```
226
33
 
227
- If you symlinked it into pi's extensions dir (dev only), also remove that link:
228
-
229
- ```bash
230
- rm -f ~/.pi/agent/extensions/pi-mega-compact
231
- ```
232
-
233
- ---
34
+ The bundled `./install.sh` helper does the symlink + config edit (needs `jq`).
35
+ </details>
234
36
 
235
37
  ## Usage
236
38
 
237
- Once installed and registered, pi-mega-compact runs **automatically** you don't
238
- have to drive it. Past the context threshold it compacts in the background and
239
- drops a checkpoint; on resume it re-inlines the relevant ones silently.
240
-
241
- The commands (slash commands inside pi):
242
-
243
- ### Commands
244
-
245
- | Command | Description |
246
- | --- | --- |
247
- | `/mega-compact [summary...]` | Manually compact the current session. A summary arg is used verbatim; otherwise the COLLAPSE heuristics build one. Persists a `chkpt_xxx`. |
248
- | `/mega-compact off` | Disable auto-compaction for this session. |
249
- | `/mega-status` | Show config + current context usage + store stats (checkpoint count, dedup rate, tokens saved) + the **installed version**. |
250
- | `/mega-recall [query]` | Semantic-search the local store, dedupe against the current window, and inline the top-K relevant checkpoints. No query → uses your latest message. `--cross-repo` searches all repos. |
251
- | `/mega-memory save <text>` / `save <category> <text>` / `list` / `search <query>` / `forget <text>` / `consolidate` | Manage durable memories (decisions, facts, preferences) written by auto-review and recalled as RAG context. Also `/m` shortform. |
252
- | `/mega-restore <chkpt\|recent>` | Re-inject a checkpoint's verbatim original region into context. |
253
- | `/mega-history` | List this session's checkpoints (id, date, files, tokens). |
254
- | `/mega-view <chkpt\|recent>` | Show a checkpoint's verbatim original region. |
255
- | `/mega-help` | Explain the toolbar widget terms (live tier, gate, dedup, tokens saved). |
256
- | `/mega-compat-check` | Detect extension conflicts (duplicate commands / overlapping handlers) across installed pi extensions. |
257
- | `/mega-db-stats` | Show mega-compact SQLite DB stats: table row counts, disk footprint (db + WAL + SHM), page count, freelist %, WAL frames. Read-only; safe any time. |
258
- | `/mega-db-prune [days]` | DELETE `raw_transcript` + `checkpoint_epochs` rows older than N days (default 30) + orphan `dedup_mirror` rows. Reports deleted counts + reclaimed bytes. |
259
- | `/mega-db-vacuum` | `VACUUM` the DB (rebuild pages, reclaim freelist). Heavy: briefly doubles disk usage. |
260
- | `/mega-db-check` | `PRAGMA integrity_check` + `wal_checkpoint(TRUNCATE)`. Fold the WAL into the main file and verify DB health. Use after a crash. |
261
- | `/mega-db-reconcile` | Fix `dedup_mirror.ref_count` drift vs actual `raw_transcript` refs, delete orphan dedup rows, backfill missing `content_ref`. Run after `/mega-db-prune` or a crash. |
262
- | `/mega-dashboard [open]` | Start the **localhost-only** live dashboard and open it in a browser (token gauge, store stats, live event stream, per-repo + All-repos/Summary views, cross-repo drift). |
263
- | `/mega-dashboard-status` | Report dashboard server status (port / url / live). |
264
- | `/mega-dashboard-stop` | Stop the dashboard server. |
265
-
266
- ### The tier system
267
-
268
- The **tier** you see in the toolbar and dashboard is a *live pressure band* (`low` → `medium` → `high` → `ultra` → `mega`) that climbs automatically as your context window fills and falls back as it's relieved — it is driven by `currentTokens / effectiveThreshold`, not a manual setting. The base compaction *threshold* is set by `MEGACOMPACT_TIER` at startup as a **% of the model context window** (`low` 50% · `medium` 60% · `high` 70% · `ultra` 70% · `mega` 75%; default `low`) — the fire point is `tierPct × contextWindow`, so it always lands below pi's native ~80% auto-compaction (any model size). The old static token amounts (50k/100k/200k/1M/10M) are now only the boot fallback used before the first context event reports a window. `/mega-tier` was removed in v0.7.6. Higher pressure also deepens the live trim and reviews durable memory more often — the whole system reacts as one.
269
-
270
- ### Live stats widget
271
-
272
- Above the pi editor the extension shows a compact widget:
273
-
274
- ```
275
- ⚡ high·low v0.7.9 │ 142k/200k tokens (71%) │ 3 chkpts │ 🤖 2 agents │ turn 5
276
- ◐ armed │ dedup: 92% │ saved: 45k tok
277
- ```
278
-
279
- - **Version** — the installed npm version (read from `package.json` at runtime),
280
- so the widget always reflects what `pi update --extensions` last pulled. If
281
- this looks stale after an update, restart the dashboard server / pi session.
282
- - **Tier** — active compaction tier (low/medium/high/ultra/mega)
283
- - **Token usage** — current / max context window and %
284
- - **Checkpoints** — persisted checkpoints for the session
285
- - **Trigger state** — ○ idle, ◐ armed, ● ready
286
- - **Dedup hit rate** — % of checkpoints collapsed as duplicates
287
- - **Active agents / turn** — sub-agent count and conversation turn (when > 0)
288
-
289
- > **DB housekeeping** — `/mega-db-stats` / `prune` / `vacuum` / `check` / `reconcile`
290
- > give you manual control over the SQLite store. In addition, a best-effort
291
- > **auto-maintenance** pass runs on `session_start`: it prunes rows older than
292
- > 30d, checkpoints the WAL if it's over 10 MB, and VACUUMs if the DB is over
293
- > 100 MB AND the freelist is >20% of pages. It never blocks session start and
294
- > logs a one-line summary to the diagnostic log. (v0.7.6+)
295
-
296
- ---
297
-
298
- ## Configuration (env-backed)
299
-
300
- All defaults are in `src/config/dedup.ts` (single source of truth). Set env vars
301
- before starting pi.
302
-
303
- ### Core settings
304
-
305
- | Variable | Default | Meaning |
306
- | --- | --- | --- |
307
- | `MEGACOMPACT_FAST_GATE_PCT` | `70` | Context-usage % that arms the auto-trigger. Defaults to the tier's % of window (`tierPct*100`): low 50 · med 60 · high 70 · ultra 70 · mega 75. Override raises the arming floor. |
308
- | `MEGACOMPACT_TIER` | `low` | Named trigger preset — sets the compaction threshold as a **% of the model context window**: `low`(50%) `medium`(60%) `high`(70%) `ultra`(70%) `mega`(75%). Fire point = `tierPct × contextWindow`, so it always fires below pi's native ~80% auto-compaction (any model size). The old static token amounts (50k/100k/200k/1M/10M) are now only the **boot fallback** used before the first context event reports a window. Default `low`. |
309
- | `MEGACOMPACT_THRESHOLD_TOKENS` | *(tier default)* | Explicit **absolute** token budget (the `custom` tier). Overrides `MEGACOMPACT_TIER` when set and is **never percent-scaled** — use this to pin an exact token fire point regardless of model window. |
310
- | `MEGACOMPACT_ANCHOR_USER_MESSAGES` | `3` | Never drop the most recent N user messages (anchor floor). |
311
- | `MEGACOMPACT_PRESERVE_RECENT` | `4` | Preserve the most recent N messages verbatim. |
312
- | `MEGACOMPACT_AUTO` | `true` | Enable the auto-trigger. |
313
- | `MEGACOMPACT_AUTO_INLINE` | `true` | Auto-inline on resume / branch. |
314
- | `MEGACOMPACT_AUTO_INLINE_K` | `3` | Top-K checkpoints to auto-inline. |
315
- | `MEGACOMPACT_DEDUP_SIM` | `0.90` | Cosine threshold to collapse near-dupes. |
316
- | `MEGACOMPACT_STATE_DIR` | *(none — per-repo default)* | Override the store location. By default state is per-repo at `<repo>/.pi/mega-compact/`; this env var forces a single explicit dir (used as the fallback for non-git cwds). |
317
-
318
- ### Dedup pipeline flags
39
+ Once installed, it runs automatically. Past the context threshold it compacts in the background. On resume, it re-inlines relevant checkpoints silently.
319
40
 
320
- These gate the L0/L1/L2/RAPTOR dedup tiers. Defaults reproduce the all-active
321
- behavior. `MARK_ONLY_*` tiers run + record their decision but never
322
- collapse (safe partial-rollout / auto-degrade state).
41
+ Key commands:
323
42
 
324
- | Variable | Default | Meaning |
325
- | --- | --- | --- |
326
- | `MEGACOMPACT_L0_ENABLED` | `true` | L0 exact content-hash dedup. |
327
- | `MEGACOMPACT_L1_ENABLED` | `true` | L1 MinHash/LSH near-dup verification. |
328
- | `MEGACOMPACT_L2_ENABLED` | `true` | L2 semantic cosine dedup + MMR retrieval diversity. |
329
- | `MEGACOMPACT_RAPTOR_ENABLED` | `false` | RAPTOR pre-compression tree (**shadow mode by default** — builds + logs, does not serve retrieval). |
330
- | `MEGACOMPACT_MARK_ONLY_L0` | `false` | L0: record, don't collapse. |
331
- | `MEGACOMPACT_MARK_ONLY_L1` | `false` | L1: record, don't collapse. |
332
- | `MEGACOMPACT_MARK_ONLY_L2` | `false` | L2: record, don't collapse. |
333
- | `MEGACOMPACT_MINILM` | `false` | MiniLM embedder flag — **off; not shipped** (see Embedding). BYO via `MEGACOMPACT_EMBEDDING_URL`. |
334
- | `MEGACOMPACT_EMBEDDING_URL` | *(unset)* | BYO localhost embedder endpoint (loopback-only; enables `HttpEmbedder`). |
335
- | `MEGACOMPACT_L2_THRESHOLD` | `0.85` | L2 cosine firing point (trigram-honest; set higher for semantic backends). |
336
- | `MEGACOMPACT_L1_JACCARD` | `0.8` | L1 MinHash/LSH near-dup Jaccard threshold. |
337
- | `MEGACOMPACT_MMR_LAMBDA` | `0.5` | MMR retrieval-diversity weight (λ·relevance − (1−λ)·maxSim). |
338
- | `MEGACOMPACT_SEMDEDUP_COSINE` | `0.95` | Offline SemDeDup pair threshold → `dedup_status='removed'`. |
339
- | `MEGACOMPACT_FP_RATE_L0` | `0.01` | L0 false-positive alert threshold (auto → MARK_ONLY). |
340
- | `MEGACOMPACT_FP_RATE_L1L2` | `0.05` | L1/L2 false-positive alert threshold (auto → MARK_ONLY). |
341
- | `MEGACOMPACT_ALERT_WINDOW_MS` | `600000` | FP-rate rolling window (10 min). |
342
- | `MEGACOMPACT_P95_BUDGET_MS` | `100` | Per-tier p95 latency budget; canary auto-disables on breach. |
43
+ - `/mega-compact` manually compact the current session
44
+ - `/mega-status` show context usage, store stats, version
45
+ - `/mega-recall [query]` semantic search the store, `--cross-repo` for all repos
46
+ - `/mega-memory save|list|search|forget` manage durable memories
47
+ - `/mega-dashboard` start the localhost dashboard
343
48
 
344
- See `docs/DEDUP_RUNBOOK.md` for incident response (SEV tiers, first-15-min
345
- checklist, MARK_ONLY degrade) and `docs/RETENTION_POLICY.md` for TTL / soft-delete
346
- / VACUUM.
49
+ Full command reference: [`docs/COMMANDS.md`](docs/COMMANDS.md)
347
50
 
348
- ### Continuity & memory
51
+ ## Configuration
349
52
 
350
- | Variable | Default | Meaning |
351
- | --- | --- | --- |
352
- | `MEGACOMPACT_LEGACY_DURABLE_TRIM` | `false` | Restore the legacy auto-trigger (`ctx.compact()` stops the agent). One-release rollback; default uses live context-event trim + pi native auto-compaction (compact-and-continue). |
353
- | `MEGACOMPACT_CROSSREPO_ENABLED` | `true` | Cross-repo recall on resume + `/mega-recall --cross-repo` (HNSW index over every repo). |
354
- | `MEGACOMPACT_CROSSREPO_COSINE` | `0.90` | Stricter cosine floor for cross-repo hits (vs `0.85` same-repo). |
355
- | `MEGACOMPACT_MEMORY_AUTO_REVIEW` | `true` | Auto-review the conversation every `MEGACOMPACT_MEMORY_REVIEW_INTERVAL` turns → durable memories. |
356
- | `MEGACOMPACT_MEMORY_REVIEW_INTERVAL` | `10` | Turns between auto-review cycles. |
357
- | `MEGACOMPACT_PGLITE_DISABLED` | *(unset — index on)* | Kill-switch for the PGlite/HNSW cross-repo index; set `1`/`true` to disable (falls back to sync per-session scan). |
53
+ Set env vars before starting pi. Defaults are in `src/config/dedup.ts`.
358
54
 
359
- ## Dashboard
55
+ | Variable | Default | Description |
56
+ |---|---|---|
57
+ | `MEGACOMPACT_TIER` | `low` | Threshold as % of context window (low=50%, medium=60%, high=70%) |
58
+ | `MEGACOMPACT_AUTO` | `true` | Enable auto-compaction |
59
+ | `MEGACOMPACT_DEDUP_SIM` | `0.90` | Cosine threshold for near-dup collapse |
60
+ | `MEGACOMPACT_CROSSREPO_ENABLED` | `true` | Cross-repo recall on resume |
61
+ | `MEGACOMPACT_EMBEDDING_URL` | _(unset)_ | BYO localhost embedder endpoint |
360
62
 
361
- The localhost-only dashboard (started with `/mega-dashboard`) is a single-page
362
- app served from a detached child process on `127.0.0.1` (random port in
363
- 9320–9329). Every API is read-only — the server never writes the index or your
364
- store. It reads the machine-wide `repo_registry`
365
- (`~/.mega-compact-index/index.sqlite`) plus the current repo's own `node:sqlite`
366
- store.
367
-
368
- ### Tabs
369
-
370
- - **Current repo** — the live single-session view: context-window gauge, trigger
371
- status, the Vector Store (checkpoints / dropped / kept / freed / injected /
372
- dedup / collapsed), the repo-wide aggregate, the Data Safety card, the live
373
- Model & Cost Savings card, and crew/agent activity.
374
- - **All repos** — a machine-wide table aggregated from `repo_registry`
375
- (`GET /api/index`): one row per repo with checkpoints, tokens saved,
376
- compressed-originals, last-compacted, and active model. Each row opens a
377
- per-repo detail modal. Currently-open sessions are badged **active** (see
378
- below).
379
- - **Summary** — machine-wide header tiles plus a **savings-by-model** table
380
- (tokens in/out/freed, context window, $ saved) grouped by the model you were
381
- running.
382
-
383
- ### Active Repos tab
384
-
385
- The dashboard has a dedicated **Active Repos** tab that lists every server /
386
- session seen within the **last 30 minutes**, each with its live tier,
387
- context %, and session state. It is backed by `GET /api/servers`, which walks
388
- the machine-wide `repo_registry`, reads each repo's per-process
389
- `dashboard.json` snapshot, and returns one row per currently-open session —
390
- so 1–6 sessions running at once are visible together in a single table instead
391
- of only the single current-repo view. Each row shows that repo's live
392
- cache-hit / compaction / time-saved totals (see below).
393
-
394
- The older **All repos** view and `GET /api/summary` still surface an
395
- `activeRepos` count, and `GET /api/repos?active=Nh` filters to repos seen
396
- within the last *N* hours (e.g. `?active=24h`, hour-granular) for the
397
- longer-window cross-repo table.
398
-
399
- ### Metrics (DB-backed, durable)
400
-
401
- The dashboard's cumulative **Cache hits**, **Compactions**, and **Estimated
402
- time saved** cards are backed by **SQLite `meta` counters**
403
- (`compact_count`, `recall_injected`, `cache_hit_tokens_saved`, plus the
404
- existing `tokens_saved` / `deduped`), not the per-process `dashboard.json`
405
- snapshot. Because they live in the repo's `node:sqlite` store, the totals are
406
- **durable across session restarts** and travel with the repo's state dir —
407
- `dashboard.json` is now just the live per-process view that feeds the Active
408
- Repos rows. The cards show:
409
-
410
- - **Cache hits** = dedup collapses (`deduped`) + recall re-injections
411
- (`recall_injected`) — as **current session** and **repo-wide total**.
412
- - **Compactions** = current session (`checkpointCount`) + repo-wide total
413
- (`compact_count` from `meta`).
414
- - **Estimated time saved** = compact time saved + cache-hit time saved, derived
415
- from tokens ÷ ~2k tok/s and labeled `est.`, as current session + total.
416
-
417
- ### Localhost API
418
-
419
- `GET /api/snapshot` (current-repo live state),
420
- `/api/servers` (**Active Repos** — sessions active in the last 30 min, with
421
- tier / context % / state / live cache-hit & compaction totals),
422
- `/api/index` (all repos), `/api/repos` (with `?active=Nh` filter), `/api/summary`
423
- (header tiles + `activeRepos`), `/api/drift` (cross-repo drift: stale /
424
- compaction-lag / model-churn — read-only), `/api/events` (SSE live event stream),
425
- and `/api/version`.
426
-
427
- ### Data safety
428
-
429
- Every compacted region is kept verbatim (compressed);
430
- the Data Safety card shows regions retained, compressed-originals bytes, dedup
431
- duplicates, and permanently-deleted bytes (**always 0**). Nothing is permanently
432
- deleted — any region is restorable.
433
-
434
- ---
63
+ Full config reference: [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md)
435
64
 
436
65
  ## Architecture
437
66
 
438
67
  ```
439
- extensions/mega-compact.ts pi extension entry; wires src/ into pi lifecycle
440
- extensions/mega-trim.ts live context-event trim (compact-and-continue, no abort)
441
- extensions/mega-conflict-cmds.ts extension-conflict detector (/mega-compat-check)
442
- extensions/dashboard-server.ts localhost dashboard (HTML + snapshot/version/drift APIs)
443
- src/adapt.ts the single pi↔engine message adapter (index-aligned)
444
- src/engine.ts Layer 4: compactSession() Trident pipeline + recall()
445
- src/vectorStore.ts Layer 3: local vector DB (add/search/dedupe + near-dup)
446
- src/embedder.ts default TrigramEmbedder (deterministic, 512-dim)
447
- src/httpEmbedder.ts BYO localhost embedder seam (MEGACOMPACT_EMBEDDING_URL)
448
- src/store/sqlite.ts the "one store" — node:sqlite context_chunks + session_state (FTS5 trigram)
449
- src/store/vectorIndex.ts async PGlite/HNSW cross-repo vector index (redundant, best-effort)
450
- src/store/migrate.ts JSON → SQLite migration (legacy .checkpoints.json.gz retained)
451
- src/store/backfill.ts resumable backfill orchestrator (L0/L1/L2/RAPTOR)
452
- src/memory.ts durable memories (decision/fact/preference) + auto-review
453
- src/memoryOps.ts memory apply/consolidate ops
454
- src/memoryRecall.ts memory recall + auto-inline (RAG context)
455
- src/driftDetection.ts cross-repo drift report (stale/idle/compaction-lag/model-churn)
456
- src/monitoring.ts local events.log + dashboard.json metrics + FP alerts
457
- src/canary.ts sequential L0→L1→L2→RAPTOR rollout, auto-disable on p95 breach
458
- src/config/dedup.ts single source of truth for ALL dedup tier flags + thresholds
459
- src/store.ts state dir + JSON DR helpers + compression re-exports
460
- src/compact.ts Layer 2: summarize / merge / autoCompactCheck
461
- src/supersede.ts Layer 1: obsolete file-read pruning
462
- src/boundary.ts drop-boundary guards (anchor floor + tool-pair)
463
- src/tokens.ts deterministic token estimator
464
- src/types.ts engine-internal types
68
+ extensions/ Pi entry points (mega-compact, mega-trim, dashboard)
69
+ src/engine.ts Trident pipeline (supersede collapse → cluster)
70
+ src/vectorStore.ts Local vector DB (add/search/dedupe)
71
+ src/compact.ts Summarize / merge / auto-compact
72
+ src/memory.ts Durable memories + auto-review
73
+ src/store/sqlite.ts node:sqlite store (Node ≥22.13)
74
+ src/store/vectorIndex.ts PGlite/HNSW cross-repo index
465
75
  ```
466
76
 
467
- The `src/` directory is **pi-agnostic** and fully unit-tested (`node --test`).
468
- The extension entry adapts between the engine and pi's runtime types.
469
-
470
- ---
77
+ Detailed architecture: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
471
78
 
472
79
  ## Development
473
80
 
474
81
  ```bash
475
- npm run build # tsc
476
- npm test # build + node --test on dist/**/*.test.js (407 tests)
477
- npm run lint # tsc --noEmit + guardrails-scan
478
- npm run guardrails # regression_check + guardrails-scan
82
+ npm run build # TypeScript compile
83
+ npm test # Build + 353 tests
84
+ npm run lint # Type check + guardrails scan
479
85
  ```
480
86
 
481
- The agent-guardrails suite (Four Laws, scope, secrets, regression) gates every
482
- change.
483
-
484
- ---
485
-
486
- ## Testing & bug reports
487
-
488
- Full QA instructions — environment setup, the manual test checklist, what to
489
- include in a bug report, and known limitations — live in
490
- [`TESTER_GUIDE.md`](TESTER_GUIDE.md). Open issues at
491
- [github.com/TheArchitectit/pi-mega-compact/issues](https://github.com/TheArchitectit/pi-mega-compact/issues).
492
-
493
- ---
494
-
495
- ## Acknowledgements
496
-
497
- Algorithmic reference (reimplemented in TypeScript, not vendored): memory-mcp
498
- (`MemoryCompactor` / `compact.py`), claw-code (`trident.rs` / `compact.rs`), and
499
- neuralwatt-mcr (pi-extension mechanics). Attribution as design sources only.
87
+ Testing guide: [`TESTER_GUIDE.md`](TESTER_GUIDE.md)
500
88
 
501
89
  ## License
502
90
 
503
- [BSD-2-Clause](./LICENSE)
91
+ BSD-2-Clause
@@ -0,0 +1,51 @@
1
+ /**
2
+ * dashboard-client/src/hooks/useApi.ts — Generic data fetching hook.
3
+ *
4
+ * Provides typed fetch with retry, stale detection, and error handling.
5
+ * SPRINT-B1: basic fetch. SPRINT-D1: retry + stale.
6
+ */
7
+ import { useState, useEffect, useCallback, useRef } from 'react';
8
+ // SPRINT-D1-REMAINING: integrate retryWithBackoff from utils/retry.ts.
9
+ // SPRINT-D1-REMAINING: integrate staleness detection from utils/staleness.ts.
10
+ // SPRINT-T1-REMAINING: add Authorization header when auth token present.
11
+ export function useApi(fetchFn, options = {}) {
12
+ const { pollInterval = 0, maxRetries = 0 } = options;
13
+ const [data, setData] = useState(null);
14
+ const [error, setError] = useState(null);
15
+ const [loading, setLoading] = useState(true);
16
+ const [lastFetchedAt, setLastFetchedAt] = useState(null);
17
+ const mountedRef = useRef(true);
18
+ const doFetch = useCallback(async () => {
19
+ setLoading(true);
20
+ setError(null);
21
+ try {
22
+ const result = await fetchFn();
23
+ if (mountedRef.current) {
24
+ setData(result);
25
+ setLastFetchedAt(Date.now());
26
+ }
27
+ }
28
+ catch (err) {
29
+ if (mountedRef.current) {
30
+ setError(err instanceof Error ? err : new Error(String(err)));
31
+ }
32
+ }
33
+ finally {
34
+ if (mountedRef.current) {
35
+ setLoading(false);
36
+ }
37
+ }
38
+ }, [fetchFn]);
39
+ useEffect(() => {
40
+ mountedRef.current = true;
41
+ doFetch();
42
+ return () => { mountedRef.current = false; };
43
+ }, [doFetch]);
44
+ useEffect(() => {
45
+ if (pollInterval <= 0)
46
+ return;
47
+ const timer = setInterval(doFetch, pollInterval);
48
+ return () => clearInterval(timer);
49
+ }, [doFetch, pollInterval]);
50
+ return { data, error, loading, refetch: doFetch, lastFetchedAt };
51
+ }