memhouse 0.8.0 → 0.11.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.
- package/README.md +84 -47
- package/bin/memhouse.js +993 -89
- package/editors/antigravity.js +7 -15
- package/editors/cursor.js +18 -24
- package/editors/goose.js +9 -21
- package/editors/index.js +19 -70
- package/editors/opencode.js +6 -15
- package/editors/sqlite.js +74 -0
- package/editors/windsurf.js +3 -3
- package/editors/zed.js +10 -15
- package/memhouse/COMPETITION.md +9 -5
- package/memhouse/DESIGN.md +37 -12
- package/memhouse/RESUME-AND-UPDATE.md +7 -10
- package/memhouse/delivery/AGENT-INSTALL-PROMPT.md +10 -2
- package/memhouse/delivery/AGENT-INSTALL.md +56 -32
- package/memhouse/delivery/PROMPT.md +37 -13
- package/memhouse/delivery/kernel-install.md +4 -4
- package/memhouse/delivery/plugin/.claude-plugin/plugin.json +14 -5
- package/memhouse/delivery/plugin/skills/ask/SKILL.md +112 -0
- package/memhouse/delivery/plugin/skills/hello/SKILL.md +76 -0
- package/memhouse/delivery/plugin/skills/invite/SKILL.md +65 -0
- package/memhouse/delivery/plugin/skills/search/SKILL.md +1 -1
- package/memhouse/delivery/plugin/skills/sessions/SKILL.md +3 -3
- package/memhouse/delivery/plugin/skills/share/SKILL.md +130 -0
- package/memhouse/delivery/plugin/skills/sql/SKILL.md +34 -11
- package/memhouse/delivery/plugin/skills/status/SKILL.md +114 -0
- package/memhouse/delivery/plugin/skills/users/SKILL.md +97 -0
- package/memhouse/house/HOUSE.md +40 -5
- package/memhouse/house/house.js +191 -10
- package/memhouse/house/migrate.js +277 -0
- package/memhouse/house/migrations/0100-epoch-key.js +68 -0
- package/memhouse/house/schema.sql.tpl +96 -25
- package/memhouse/self-update.js +4 -4
- package/memhouse/service.js +7 -2
- package/memhouse/shipper/ship.js +471 -131
- package/package.json +3 -6
package/README.md
CHANGED
|
@@ -1,19 +1,31 @@
|
|
|
1
1
|
# memhouse
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
**Claude Code deletes your transcripts after 30 days.** (`cleanupPeriodDays`,
|
|
4
|
+
default 30 — session files are removed at startup.) Measured on the machine this
|
|
5
|
+
was built on: months of daily use, and the oldest surviving local transcript was
|
|
6
|
+
nine days old. Every problem you solved before that exists nowhere — unless
|
|
7
|
+
something durable was keeping it.
|
|
8
|
+
|
|
9
|
+
memhouse is that something. It reads the session transcripts your editors already
|
|
10
|
+
write to disk — **17 of them**: Claude Code, Codex, Cursor, Zed, Copilot, Gemini
|
|
11
|
+
CLI and the rest — parses them locally, and ships typed rows into a ClickHouse
|
|
12
|
+
**you own**. Nothing is proxied, intercepted, or sent to anyone's cloud. Then you
|
|
13
|
+
can search every past session, see what it cost, resume the conversation that
|
|
14
|
+
solved this before, and let an agent query its own history.
|
|
15
|
+
|
|
16
|
+
And every row says where it came from, in a way no client can fake: `user_id` is
|
|
17
|
+
stamped **by the server** (`MATERIALIZED currentUser()`, async inserts pinned off
|
|
18
|
+
so the stamp cannot be skipped) and `host` is a fingerprint minted once per
|
|
19
|
+
install. A team pointed at one house is a team memory with real attribution — not
|
|
20
|
+
a label somebody's client claimed.
|
|
8
21
|
|
|
9
22
|
```bash
|
|
10
|
-
npm install -g memhouse
|
|
23
|
+
npm install -g memhouse
|
|
11
24
|
memhouse onboard
|
|
12
25
|
```
|
|
13
26
|
|
|
14
|
-
That is the whole install. `onboard` finds your
|
|
15
|
-
and starts the dashboard.
|
|
16
|
-
[below](#the-allow-scripts-flag).
|
|
27
|
+
That is the whole install — no flags, nothing to compile. `onboard` finds your
|
|
28
|
+
editors, sets up a house, ships, and starts the dashboard.
|
|
17
29
|
|
|
18
30
|
**On most Linux distros that first line needs `sudo`.** A distro-packaged Node puts
|
|
19
31
|
its global prefix under `/usr`, which you do not own, so npm stops with `EACCES`.
|
|
@@ -22,7 +34,7 @@ Ubuntu machine:
|
|
|
22
34
|
|
|
23
35
|
```bash
|
|
24
36
|
ls -ld "$(npm prefix -g)" # root-owned? use sudo. Owned by you? do NOT — see EACCES below
|
|
25
|
-
sudo npm install -g memhouse
|
|
37
|
+
sudo npm install -g memhouse
|
|
26
38
|
```
|
|
27
39
|
|
|
28
40
|
If the prefix is yours (Homebrew, fnm, nvm, volta), `sudo` is the wrong fix and
|
|
@@ -64,7 +76,7 @@ memhouse update [--check] upgrade, restart daemons, check the s
|
|
|
64
76
|
memhouse start | stop dashboard + shipper as daemons
|
|
65
77
|
memhouse service install | uninstall survive a reboot
|
|
66
78
|
memhouse deploy --local | --down stand up (or remove) a local house
|
|
67
|
-
memhouse plugins install claude /
|
|
79
|
+
memhouse plugins install claude /mem:search, :sessions, :sql —
|
|
68
80
|
into every Claude Code config dir found
|
|
69
81
|
memhouse prompt memory snippet for an agent's system prompt
|
|
70
82
|
memhouse prompt --install an install prompt, rendered for this machine
|
|
@@ -77,7 +89,7 @@ an agent — so an agent can install its own memory unattended.
|
|
|
77
89
|
config directory on the machine** — `~/.claude`, whatever `CLAUDE_CONFIG_DIR` points
|
|
78
90
|
at, and each Kommander-style playbook under `~/.claude-playbooks/`. All are selected by
|
|
79
91
|
default; answer with numbers to narrow it, or pass `--target DIR` for exactly one.
|
|
80
|
-
Installing into just the default config is how `/
|
|
92
|
+
Installing into just the default config is how `/mem:search` ends up missing from
|
|
81
93
|
the instance you actually work in, silently, since a missing skill never announces
|
|
82
94
|
itself.
|
|
83
95
|
|
|
@@ -149,13 +161,11 @@ memhouse update # upgrade, restart the daemons, check the house schem
|
|
|
149
161
|
memhouse update --check # compare versions, change nothing
|
|
150
162
|
```
|
|
151
163
|
|
|
152
|
-
A bare `npm i -g memhouse@latest` does
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
checkout it rebuilds `public/` — otherwise `git pull` serves you the previous release's
|
|
158
|
-
dashboard forever.
|
|
164
|
+
A bare `npm i -g memhouse@latest` does half the job. It does not restart the daemons,
|
|
165
|
+
which keep parsing with the code they booted with (a shipper here once ran 1d16h out of
|
|
166
|
+
a directory that had been *moved*); and it does not check whether your house predates a
|
|
167
|
+
room the new shipper needs. `update` does both, and from a checkout it rebuilds
|
|
168
|
+
`public/` — otherwise `git pull` serves you the previous release's dashboard forever.
|
|
159
169
|
|
|
160
170
|
The daemons also notice on their own: each one compares the installed version against
|
|
161
171
|
what it booted with and hands over — exiting under systemd/launchd so the supervisor
|
|
@@ -189,45 +199,62 @@ which is also why joining a ClickHouse someone else runs (a kernel's, a team's)
|
|
|
189
199
|
no negotiation beyond a database and a credential. Housemates are collaborators;
|
|
190
200
|
groups that should not see each other get separate houses.
|
|
191
201
|
|
|
192
|
-
###
|
|
202
|
+
### The house never destroys what it cannot rebuild
|
|
193
203
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
the shipper itself wrote (`origin='ship'`). Anything you imported from an older
|
|
197
|
-
house, another product, or a machine that no longer exists survives a re-ship.
|
|
204
|
+
**The shipper is insert-only.** It runs no `DELETE`, no `TRUNCATE`, no mutation of any
|
|
205
|
+
kind, so no privilege it holds can lose you a row.
|
|
198
206
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
207
|
+
That is not free, because ReplacingMergeTree is a dedupe engine, not a diff engine: a
|
|
208
|
+
re-parse yielding *fewer* messages leaves the old higher-`seq` rows with nothing written
|
|
209
|
+
over them. The shipper used to delete the session's rows first to clear that tail — and
|
|
210
|
+
a shorter re-parse has two indistinguishable causes. Either an adapter bug was fixed and
|
|
211
|
+
the extra rows are junk, or Claude Code **compacted** the transcript, or the retention
|
|
212
|
+
window (`cleanupPeriodDays`, 30 days by default) took it. In the last two cases the house
|
|
213
|
+
holds the only surviving copy, and the delete destroyed it.
|
|
203
214
|
|
|
204
|
-
|
|
205
|
-
A session's metadata has a single current version, and keying it on origin gives the
|
|
206
|
-
same session two rows, which makes every rollup count its messages twice.
|
|
215
|
+
So rows carry an `epoch`: which parse of the session they belong to.
|
|
207
216
|
|
|
208
|
-
|
|
209
|
-
|
|
217
|
+
- **Nothing changed** (the common case, including ordinary growth): same epoch, rows
|
|
218
|
+
dedupe exactly as before, no extra storage.
|
|
219
|
+
- **Shorter, or rewritten at a position the house already holds**: the new parse goes to
|
|
220
|
+
`epoch + 1`. The old one stays complete and readable. You pay storage only when the old
|
|
221
|
+
rows are irreplaceable.
|
|
210
222
|
|
|
211
|
-
|
|
223
|
+
Reads show one parse per session — the newest — so counts, tokens and cost are unchanged.
|
|
224
|
+
`/mem:sql` and any hand-written query should filter the same way; the skill carries
|
|
225
|
+
the clause.
|
|
226
|
+
|
|
227
|
+
**Imported history is protected the same way.** `origin` says who wrote a row, and it is
|
|
228
|
+
in the sorting key of `messages` and `tool_calls`, so ReplacingMergeTree cannot collapse
|
|
229
|
+
an imported row against a shipped one. Anything you imported from an older house, another
|
|
230
|
+
product, or a machine that no longer exists survives every re-ship. `sessions` is the
|
|
231
|
+
deliberate exception — one row per session, no `origin` and no `epoch` in its key, because
|
|
232
|
+
a session's metadata has a single current version and a second row makes every rollup
|
|
233
|
+
count its messages twice.
|
|
212
234
|
|
|
213
|
-
|
|
235
|
+
The shipper verifies the sorting keys before it writes and refuses if they are wrong, so
|
|
236
|
+
an old house cannot be corrupted by a new shipper. `memhouse migrate-rooms` rebuilds it:
|
|
237
|
+
copy, atomic swap, and the old room kept as `<room>_pre_epoch` for you to drop. The house
|
|
238
|
+
records the move in `house_events`, and `memhouse doctor` reads it back.
|
|
214
239
|
|
|
215
|
-
|
|
216
|
-
of SQLite files, and `better-sqlite3` builds its native binding from an install
|
|
217
|
-
script. npm 12 blocks install scripts by default, so without the flag those five
|
|
218
|
-
read nothing and you ship a partial history.
|
|
240
|
+
## Troubleshooting
|
|
219
241
|
|
|
220
|
-
|
|
221
|
-
language-server RPC and touches SQLite only to read a usage key, so a dead binding
|
|
222
|
-
costs it numbers, not sessions. `editors/index.js` has the real list.)
|
|
242
|
+
### An editor reads zero sessions
|
|
223
243
|
|
|
224
|
-
|
|
225
|
-
|
|
244
|
+
Five adapters — **cursor, zed, opencode, goose, antigravity** — read sessions out of
|
|
245
|
+
SQLite files. That used to mean `better-sqlite3`, whose native binding is built by
|
|
246
|
+
an npm install script; npm 12 blocks install scripts by default, so a plain install left
|
|
247
|
+
all five reading nothing and the fix was a flag
|
|
248
|
+
(`--allow-scripts=better-sqlite3`) you had to re-type on every upgrade. SQLite is
|
|
249
|
+
`node:sqlite` now — part of Node — so that failure class is gone along with the flag.
|
|
226
250
|
|
|
227
|
-
|
|
251
|
+
What can still go wrong is one store at a time: a `state.vscdb` locked by a running
|
|
252
|
+
editor, a corrupt file, a schema a new editor release changed. None of it is silent —
|
|
253
|
+
`memhouse discover` and `memhouse doctor` both name the skipped adapter and say why,
|
|
254
|
+
and the other sixteen keep working.
|
|
228
255
|
|
|
229
256
|
```bash
|
|
230
|
-
npx
|
|
257
|
+
npx -y memhouse discover # no flags here either
|
|
231
258
|
```
|
|
232
259
|
|
|
233
260
|
### `EACCES` on install
|
|
@@ -262,7 +289,7 @@ A rootless podman house has the same problem for the same reason, and
|
|
|
262
289
|
## Working from a checkout
|
|
263
290
|
|
|
264
291
|
```bash
|
|
265
|
-
npm install #
|
|
292
|
+
npm install # two runtime deps, no build step
|
|
266
293
|
node bin/memhouse.js …
|
|
267
294
|
npm test # syntax gate + unit checks
|
|
268
295
|
```
|
|
@@ -293,6 +320,16 @@ In constellation terms (`TERMINOLOGY.md`) memhouse is an **agency**: a **house**
|
|
|
293
320
|
alone would hold; the shipper is what makes it act. It competes with
|
|
294
321
|
memory-house; if it wins, it becomes memory-house v4.
|
|
295
322
|
|
|
323
|
+
## What's supported
|
|
324
|
+
|
|
325
|
+
| Surface | Status |
|
|
326
|
+
|---|---|
|
|
327
|
+
| macOS | primary — developed and driven here daily |
|
|
328
|
+
| Linux | real — installs, ships, `service install` (systemd `--user`), rootless podman `deploy --local`; exercised on Debian and Ubuntu machines |
|
|
329
|
+
| Windows | **untested** — the adapters declare Windows paths but no one has run a single install; treat it as unknown until this row changes |
|
|
330
|
+
| ClickHouse | 25.11 and 26.x, both in CI; 26.2+ needs no flags, 25.x needs the text-index flag the shipper already passes |
|
|
331
|
+
| Node | **≥ 24** — SQLite comes from `node:sqlite`, which is stable in 24. It works flagless on 22.13+ but prints `ExperimentalWarning` on every command (measured on v22.23.2), and Node 20 is past EOL. There is no native dependency and no build step at any version. |
|
|
332
|
+
|
|
296
333
|
## Heritage & license
|
|
297
334
|
|
|
298
335
|
Built on [agentlytics](https://github.com/f/agentlytics) by Fatih Kadir Akın (MIT)
|