memhouse 0.17.0 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +109 -30
  2. package/bin/memhouse.js +555 -202
  3. package/editors/antigravity.js +2 -0
  4. package/editors/claude.js +3 -1
  5. package/editors/codebuff.js +2 -0
  6. package/editors/codex.js +4 -1
  7. package/editors/commandcode.js +2 -1
  8. package/editors/copilot-jetbrains.js +2 -1
  9. package/editors/copilot.js +2 -1
  10. package/editors/cursor-agent.js +2 -1
  11. package/editors/cursor.js +2 -0
  12. package/editors/gemini.js +2 -1
  13. package/editors/goose.js +2 -1
  14. package/editors/index.js +8 -1
  15. package/editors/kiro.js +3 -2
  16. package/editors/opencode.js +2 -1
  17. package/editors/scope.js +126 -0
  18. package/editors/vscode.js +2 -0
  19. package/editors/zed.js +2 -1
  20. package/memhouse/DESIGN.md +31 -8
  21. package/memhouse/binding.js +81 -0
  22. package/memhouse/channel.js +50 -0
  23. package/memhouse/delivery/AGENT-INSTALL-PROMPT.md +2 -1
  24. package/memhouse/delivery/AGENT-INSTALL.md +1 -1
  25. package/memhouse/delivery/INVITATION.md.tpl +147 -0
  26. package/memhouse/delivery/PROMPT.md +6 -5
  27. package/memhouse/delivery/kernel-install.md +4 -2
  28. package/memhouse/delivery/plugin/.claude-plugin/plugin.json +1 -1
  29. package/memhouse/delivery/plugin/reference/HOUSE.md +38 -12
  30. package/memhouse/delivery/plugin/skills/access/SKILL.md +9 -9
  31. package/memhouse/delivery/plugin/skills/admin/SKILL.md +1 -1
  32. package/memhouse/delivery/plugin/skills/house/SKILL.md +18 -2
  33. package/memhouse/flags.js +5 -4
  34. package/memhouse/house/HOUSE.md +25 -11
  35. package/memhouse/house/house.js +110 -27
  36. package/memhouse/house/migrate.js +7 -6
  37. package/memhouse/house/relocate.js +2 -2
  38. package/memhouse/house/schema.sql.tpl +3 -3
  39. package/memhouse/invitefile.js +38 -0
  40. package/memhouse/provision.js +100 -0
  41. package/memhouse/shipper/ship.js +87 -28
  42. package/package.json +1 -1
package/README.md CHANGED
@@ -9,9 +9,12 @@ something durable was keeping it.
9
9
  memhouse is that something. It reads the session transcripts your editors already
10
10
  write to disk — **17 of them**: Claude Code, Codex, Cursor, Zed, Copilot, Gemini
11
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.
12
+ **you choose**: a container on this laptop, a box you run, your company's cluster,
13
+ or ClickHouse Cloud. memhouse runs no service of its own — there is no memhouse
14
+ cloud to sign up for and nothing is proxied through anyone — so the account is
15
+ yours and the data is wherever you decided to put it. Then you can search every
16
+ past session, see what it cost, resume the conversation that solved this before,
17
+ and let an agent query its own history.
15
18
 
16
19
  And every row says where it came from, in a way no client can fake: `user_id` is
17
20
  stamped **by the server** (`MATERIALIZED currentUser()`, async inserts pinned off
@@ -72,19 +75,27 @@ container engine, install one of the two.
72
75
  memhouse onboard | install | setup | discover | doctor | uninstall | reset
73
76
  memhouse ship [--full|--loop N] | search <terms> | stats | status
74
77
  memhouse resume <session-id> print the command that reopens a session
75
- memhouse update [--check] upgrade, restart daemons, check the schema
78
+ memhouse update [--check] [--channel TAG] upgrade along the channel this install follows,
79
+ restart daemons, check the schema
76
80
  memhouse start | stop dashboard + shipper as daemons
77
81
  memhouse service install | uninstall survive a reboot
78
82
  memhouse deploy --local | --down stand up (or remove) a local house
79
83
  memhouse invite <name> mint a member + house, hand them one env file
84
+ memhouse members [--db X] who is in a house, and what each can reach
85
+ memhouse whoami [--admin] which credential is in play, and what it may do
86
+ memhouse instance which memhouse this is: home, binary, house, rooms, scope, bindings
87
+ memhouse rooms what your rooms are actually called
88
+ memhouse share <user> [--only …|--revoke|--list]
89
+ let a housemate read yours, in whole or in part
90
+ memhouse sessions-query print the session rollup SQL
80
91
  memhouse passwd rotate this member's password
81
92
  memhouse migrate | migrate-rooms [--dry-run] [--yes]
82
93
  run whatever this house still needs
83
94
  memhouse relocate --to <url> copy this house to a new ClickHouse, then repoint
84
95
  memhouse nightly [--out DIR] build an installable tarball from this checkout
85
- memhouse plugins install claude 9 skills — ask, hello, invite, search,
86
- sessions, share, sql, status, users — into
87
- every Claude Code config dir found
96
+ memhouse plugins install claude 5 skills — house, recall, sql, access,
97
+ admin — into every Claude Code config
98
+ dir found
88
99
  memhouse prompt memory snippet for an agent's system prompt
89
100
  memhouse prompt --install an install prompt, rendered for this machine
90
101
  ```
@@ -108,6 +119,62 @@ Config resolves: flags → `MEMHOUSE_*` env → `$MEMHOUSE_HOME/env` (default
108
119
  commands that read or write memory refuse and say so rather than guessing
109
120
  `localhost:8123`, which on a lot of machines is a real house belonging to someone else.
110
121
 
122
+ ## Which sessions ship
123
+
124
+ Everything on the machine, by default: every adapter, from wherever that editor keeps its
125
+ sessions. `memhouse discover` prints what each adapter is watching and the variable that
126
+ moves it:
127
+
128
+ ```
129
+ Watched directories (override with the variable shown, in the env file):
130
+ claude ~/.claude, ~/.claude-playbooks/kommander, … [MEMHOUSE_CLAUDE_ROOTS]
131
+ codex ~/.codex [MEMHOUSE_CODEX_ROOTS]
132
+ gemini-cli ~/.gemini [MEMHOUSE_GEMINI_CLI_ROOTS]
133
+ cursor ~/Library/Application Support/Cursor/User, … [built-in]
134
+ ```
135
+
136
+ Two kinds of line in the env file narrow it, or `--editors` / `--claude-roots` at install:
137
+
138
+ ```
139
+ MEMHOUSE_EDITORS='claude'
140
+ MEMHOUSE_CLAUDE_ROOTS='~/.claude-playbooks/kommander-chaos'
141
+ ```
142
+
143
+ `MEMHOUSE_EDITORS` names the adapters to run. `MEMHOUSE_<EDITOR>_ROOTS` replaces one
144
+ adapter's location: the adapter's name upper-cased, dashes to underscores. Claude is the
145
+ one adapter with many roots (every Claude Code config directory), so its list may hold
146
+ several; every other adapter has one store, so one path. Adapters marked `[built-in]`
147
+ resolve a platform app-data directory and cannot be moved yet.
148
+
149
+ An adapter name or a directory that does not exist is refused and reported against that
150
+ adapter, never shipped from the default instead: a typo that quietly shipped nothing would
151
+ look like a working install with an empty house, and one that quietly shipped the wrong
152
+ store would be worse.
153
+
154
+ ## Channels
155
+
156
+ `memhouse update` follows the npm dist-tag the install came from, not `latest` by
157
+ reflex. A house published under another tag — `npm publish --tag team`, so one team can
158
+ run a newer layout without every other house being dragged along — installs with
159
+ `npm install -g memhouse@team`, and `update` keeps it there. The channel is inferred from
160
+ the installed version; pin it with `MEMHOUSE_CHANNEL='team'` in the env file or
161
+ `memhouse update --channel team`, which writes the same line. A tarball or checkout
162
+ build sits on no tag and is never auto-updated; `update --check` says so and names the
163
+ way forward. An invite from a house on a channel carries it, so the invitee follows it
164
+ too.
165
+
166
+ ## Instances
167
+
168
+ An instance is a home: an env file naming a house, the daemons shipping to it, and the
169
+ playbooks whose sessions it ships (`MEMHOUSE_CLAUDE_ROOTS`). A machine can run several,
170
+ each under its own `MEMHOUSE_HOME`, on different channels. `plugins install claude` from an
171
+ instance installs into exactly the playbooks that instance ships and **binds** them: it
172
+ writes `MEMHOUSE_HOME` and `MEMHOUSE_BIN` into each playbook's `settings.json` `env`, which
173
+ Claude Code applies to every session there. So the `/mem:*` skills in a bound playbook read
174
+ that instance's house and run that instance's binary, whatever the shell they were started
175
+ from had. `plugins list` shows the binding; `plugins remove` takes it out. Everything else
176
+ in `settings.json` is left as it was.
177
+
111
178
  ## Going back into a session
112
179
 
113
180
  `search` finds the conversation; `resume` hands you back into it.
@@ -184,30 +251,43 @@ immediate.
184
251
 
185
252
  ## How your memory is stored
186
253
 
187
- **A house is a database; its rooms are three shared tables.** `sessions`, `messages`
188
- and `tool_calls` live in whatever database you point at — your own name by default
189
- (`polat.messages`), a team's (`team_a.messages`), even `default`. Everyone in the
190
- house writes into the same tables with their own credential, and every row says where
191
- it came from: `user_id`, stamped by the server (`MATERIALIZED currentUser()`, with
192
- async inserts pinned off so the stamp cannot be skipped), and `host`, the machine's
193
- install fingerprint.
254
+ **A house is a database; its rooms are tables.** `sessions`, `messages` and `tool_calls`
255
+ hold your turns. Every row says where it came from: `user_id`, stamped by the server
256
+ (`MATERIALIZED currentUser()`, with async inserts pinned off so the stamp cannot be
257
+ skipped), and `host`, the machine's install fingerprint. `WHERE user_id = 'alice'` is one
258
+ person; `WHERE host = '…'` is one machine. Neither is forgeable from the client.
259
+
260
+ **Your rooms are named for you, and one grant covers them.** Every member of a house holds
261
+ `GRANT … ON mem.<name>_* TO <name>`: their own rooms, present and future, and nothing else
262
+ in the database. That is the whole access model, and it is the same on a laptop, a team's
263
+ server, or a kernel:
264
+
265
+ | | rooms | the member holds |
266
+ |---|---|---|
267
+ | alone on your laptop | `mem.polat_*` | one grant on `mem.polat_*` |
268
+ | a team on one server | `mem.polat_*`, `mem.alice_*`, … | each their own |
269
+
270
+ A colleague can read their isolation back with `SHOW GRANTS` in one line, which is the
271
+ property this rests on. There is no row policy to trust and no database-wide grant to
272
+ worry about: `ALL ON mem.*` would cover rooms created later, which is how two people in one
273
+ database once became a leak, so memhouse never issues it — not to a member, not to you.
194
274
 
195
- `WHERE user_id = 'alice'` is one person. `WHERE host = '…'` is one machine. No filter
196
- is the whole house — which is exactly what a team dashboard wants.
275
+ Standalone is a team of one. `memhouse deploy --local` creates the house with an admin
276
+ credential (`memhouse_root`) and a member named after your OS user, keeps both in the env
277
+ file, and ships as the member. Inviting a colleague later is `memhouse invite <name>`; the
278
+ admin credential is already there.
197
279
 
198
- Sharing is not a feature bolted on top; it IS the house. A team makes a database,
199
- grants each person `ALL` on it, and their shippers all write into the same rooms:
280
+ Reading across everyone is a `UNION ALL` over the rooms you hold:
200
281
 
201
282
  ```sql
202
- CREATE DATABASE team_a;
203
- CREATE USER alice IDENTIFIED BY '…';
204
- GRANT ALL ON team_a.* TO alice; -- repeat per housemate
283
+ SELECT user_id, count() FROM mem.polat_messages GROUP BY user_id
284
+ UNION ALL
285
+ SELECT user_id, count() FROM mem.alice_messages GROUP BY user_id
205
286
  ```
206
287
 
207
- `ALL` on your own house reaches nothing outside it — the database is the boundary,
208
- which is also why joining a ClickHouse someone else runs (a kernel's, a team's) needs
209
- no negotiation beyond a database and a credential. Housemates are collaborators;
210
- groups that should not see each other get separate houses.
288
+ An operator with an admin credential reads every room; a member reads the ones they own
289
+ plus whatever was shared with them, and naming a room they do not hold is an error rather
290
+ than a silent omission.
211
291
 
212
292
  ### The house never destroys what it cannot rebuild
213
293
 
@@ -245,7 +325,7 @@ count its messages twice.
245
325
  The shipper verifies the sorting keys before it writes and refuses if they are wrong, so
246
326
  an old house cannot be corrupted by a new shipper. `memhouse migrate-rooms` rebuilds it:
247
327
  copy, atomic swap, and the old room kept as `<room>_pre_epoch` for you to drop. The house
248
- records the move in `house_events`, and `memhouse doctor` reads it back.
328
+ records the move in `events`, and `memhouse doctor` reads it back.
249
329
 
250
330
  ## Upgrading
251
331
 
@@ -341,10 +421,9 @@ and are not part of `npm test`.
341
421
  | `agency/` | the earlier agentlytics-agency wrap — prior art, not how memhouse works |
342
422
  | `TERMINOLOGY.md` | the constellation terminology canon |
343
423
 
344
- Deeper reading: `memhouse/DESIGN.md` (the four bets),
345
- `memhouse/per-member/INSTALL.md` (the three install paths and every refusal),
346
- `memhouse/per-member/SCHEMA.md`, `memhouse/delivery/kernel-install.md`,
347
- `memhouse/COMPETITION.md`.
424
+ Deeper reading: `memhouse/DESIGN.md` (the bets, and why the room layout has moved three
425
+ times), `memhouse/house/HOUSE.md` (the layout and the schema), `SECURITY.md` (what
426
+ holds, and what does not), `memhouse/delivery/kernel-install.md`, `memhouse/COMPETITION.md`.
348
427
 
349
428
  Deferred designs (captured, not yet built): `docs/design/host-repoint-reconciliation.md`
350
429
  — what should happen when the shipper is repointed at a new, empty host (house identity,