memhouse 0.18.8 → 0.18.10
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/AGENTS.md +194 -0
- package/CHANGELOG.md +970 -0
- package/README.md +54 -423
- package/SECURITY.md +68 -0
- package/bin/memhouse.js +202 -92
- package/docs/README.md +46 -0
- package/docs/guides/admin-password.md +95 -0
- package/docs/guides/configuration.md +109 -0
- package/docs/guides/daemons.md +53 -0
- package/docs/guides/install.md +128 -0
- package/docs/guides/invite.md +87 -0
- package/docs/guides/operate.md +112 -0
- package/docs/guides/search-and-resume.md +95 -0
- package/docs/guides/share.md +102 -0
- package/docs/guides/storage.md +90 -0
- package/docs/guides/troubleshooting.md +78 -0
- package/docs/guides/uninstall.md +35 -0
- package/docs/guides/update.md +68 -0
- package/docs/releases/README.md +10 -0
- package/docs/releases/v0.18.10.md +226 -0
- package/docs/tutorials/01-first-house.md +132 -0
- package/docs/tutorials/02-join-a-house.md +91 -0
- package/docs/tutorials/03-share-your-memory.md +96 -0
- package/examples/01-local-one-machine/README.md +99 -0
- package/examples/01-local-one-machine/run.sh +61 -0
- package/examples/02-existing-clickhouse/README.md +121 -0
- package/examples/02-existing-clickhouse/run.sh +71 -0
- package/examples/03-team-house/README.md +129 -0
- package/examples/03-team-house/run.sh +124 -0
- package/examples/04-self-hosted-team/.env.example +22 -0
- package/examples/04-self-hosted-team/README.md +187 -0
- package/examples/04-self-hosted-team/compose.yml +158 -0
- package/examples/04-self-hosted-team/smoke.sh +113 -0
- package/examples/README.md +42 -0
- package/examples/fixtures/README.md +24 -0
- package/examples/fixtures/make-sessions.js +63 -0
- package/memhouse/admin-secret.js +81 -0
- package/memhouse/delivery/plugin/.claude-plugin/plugin.json +1 -1
- package/memhouse/deploy.js +4 -2
- package/memhouse/flags.js +4 -4
- package/memhouse/provision.js +12 -3
- package/memhouse/server/queries.js +18 -4
- package/memhouse/server/server.js +9 -1
- package/memhouse/service.js +5 -0
- package/package.json +10 -2
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Tutorial 1: your first house
|
|
2
|
+
|
|
3
|
+
One machine, about ten minutes. At the end, every coding-agent session on this machine
|
|
4
|
+
is in a ClickHouse you own. You can see them in a dashboard, search them, and ask an agent
|
|
5
|
+
about them.
|
|
6
|
+
|
|
7
|
+
**You need:**
|
|
8
|
+
|
|
9
|
+
- Node 24 or newer;
|
|
10
|
+
- docker or podman, for the local ClickHouse;
|
|
11
|
+
- at least one editor that has written sessions: Claude Code, Codex, Cursor, Zed, and so on.
|
|
12
|
+
|
|
13
|
+
## 1. Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g memhouse
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
On a distro-packaged Node (Linux, global prefix under `/usr`) this needs `sudo`. On
|
|
20
|
+
Homebrew, nvm, fnm or volta it must not have it. [The install guide](../guides/install.md#eacces-on-install)
|
|
21
|
+
tells the two apart.
|
|
22
|
+
|
|
23
|
+
## 2. See what is on this machine
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
memhouse discover
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This is a read-only preflight. It lists every editor it found, how many sessions each one
|
|
30
|
+
holds, the directories it watches, and any ClickHouse it can reach. Nothing is written
|
|
31
|
+
anywhere.
|
|
32
|
+
|
|
33
|
+
## 3. Stand up a house
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
memhouse deploy --local
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This does four things:
|
|
40
|
+
|
|
41
|
+
1. It starts ClickHouse in a container bound to `127.0.0.1:8123`, so only this machine
|
|
42
|
+
can reach it. The data lives in a named volume.
|
|
43
|
+
2. It creates two users. `memhouse_root` administers the house. A **member** named after
|
|
44
|
+
your OS user (`polat`, say) ships your sessions, and holds one grant: `mem.polat_*`.
|
|
45
|
+
Your rooms are `mem.polat_sessions`, `mem.polat_messages`, `mem.polat_tool_calls`, and
|
|
46
|
+
so on.
|
|
47
|
+
3. It writes both credentials to `~/.memhouse/env`, mode 600. A local house is the one
|
|
48
|
+
case where the admin credential is kept, so that `memhouse invite` works later with
|
|
49
|
+
no flags.
|
|
50
|
+
4. It installs against the house and ships everything once.
|
|
51
|
+
|
|
52
|
+
Already have a ClickHouse? Skip this step and use `memhouse onboard`, which asks for
|
|
53
|
+
it. See [the install guide](../guides/install.md).
|
|
54
|
+
|
|
55
|
+
## 4. Check it worked
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
memhouse status
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Look for a connection check mark, row counts in your rooms, and a recent "last shipped"
|
|
62
|
+
time. `memhouse doctor` goes further. It checks the whole pipeline and names anything
|
|
63
|
+
skipped.
|
|
64
|
+
|
|
65
|
+
## 5. Keep it shipping, and open the dashboard
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
memhouse start
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This starts two background daemons. The shipper runs an incremental pass every five
|
|
72
|
+
minutes. The dashboard runs at **http://localhost:4640**: sessions, cost by model and
|
|
73
|
+
editor, tool calls, and which machine wrote what.
|
|
74
|
+
|
|
75
|
+
Those daemons do not survive a reboot. To make them permanent:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
memhouse service install # systemd --user on Linux, a LaunchAgent on macOS
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 6. Find something
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
memhouse search "connection refused"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Each hit names the session, its project and its date. Reopen one:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
memhouse resume claude-code:6b1f…
|
|
91
|
+
# cd /path/to/project && claude --resume 6b1f…
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`resume` **prints** the command rather than running it. You see the directory and the id
|
|
95
|
+
before anything opens.
|
|
96
|
+
|
|
97
|
+
## 7. Let your agents remember
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
memhouse plugins install claude
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
This installs five skills into every Claude Code config directory it finds. You choose
|
|
104
|
+
which ones; all are selected by default. In any Claude Code session afterwards:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
/mem:recall how did I fix the ClickHouse auth error last month?
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The agent searches your house, reads the sessions that match, answers from them, and
|
|
111
|
+
cites the sessions it used. `/mem:house` reports the state of the house.
|
|
112
|
+
|
|
113
|
+
## What you have now
|
|
114
|
+
|
|
115
|
+
- `~/.memhouse/env` holds the connection and both credentials. Never paste it anywhere.
|
|
116
|
+
- `~/.memhouse/host.json` holds this machine's identity. Every row it ships carries it.
|
|
117
|
+
- A ClickHouse container with your memory in a named volume.
|
|
118
|
+
|
|
119
|
+
## Undo it
|
|
120
|
+
|
|
121
|
+
- `memhouse uninstall` stops everything and keeps the house.
|
|
122
|
+
- `memhouse deploy --down` removes the container **and its volume**, which **deletes the
|
|
123
|
+
memory**.
|
|
124
|
+
|
|
125
|
+
See [Uninstall](../guides/uninstall.md).
|
|
126
|
+
|
|
127
|
+
## Next
|
|
128
|
+
|
|
129
|
+
- [Tutorial 2](02-join-a-house.md): join a team's house instead of running your own.
|
|
130
|
+
- [Configuration](../guides/configuration.md): ship only some editors or directories.
|
|
131
|
+
- [How memory is stored](../guides/storage.md): what a room holds, and why nothing is
|
|
132
|
+
ever deleted to make room.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Tutorial 2: join a team's house
|
|
2
|
+
|
|
3
|
+
Someone runs a house and invited you. They gave you a file named `invite-<you>.env`. At the
|
|
4
|
+
end of this tutorial your sessions ship into your own rooms in their house, under a
|
|
5
|
+
password only you know.
|
|
6
|
+
|
|
7
|
+
**You need:**
|
|
8
|
+
|
|
9
|
+
- Node 24 or newer;
|
|
10
|
+
- the invite file, received over a trusted channel: croc, a password manager, or a USB
|
|
11
|
+
stick. Not chat or email. **The file contains a password.**
|
|
12
|
+
|
|
13
|
+
## 1. Install memhouse
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g memhouse
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
On Linux with a distro-packaged Node, prefix with `sudo`. See
|
|
20
|
+
[the install guide](../guides/install.md#eacces-on-install).
|
|
21
|
+
|
|
22
|
+
## 2. Install from the invite
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
memhouse install --env invite-<you>.env
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This reads the house's address, your member name and a starting password from the file.
|
|
29
|
+
It then connects, checks that you can write to your rooms, and ships every session on
|
|
30
|
+
this machine. Your rooms already exist and are named for you: `mem.<you>_messages`,
|
|
31
|
+
`mem.<you>_sessions`, and so on. You hold one grant, on `mem.<you>_*`, and nothing else in
|
|
32
|
+
the database.
|
|
33
|
+
|
|
34
|
+
Then it **offers to change the password** to one only this machine knows. Say yes. The
|
|
35
|
+
person who invited you set the starting password, and once you rotate it, theirs stops
|
|
36
|
+
working. Then it deletes the invite file, which is spent.
|
|
37
|
+
|
|
38
|
+
Scripted, with no terminal: `--yes` rotates without asking.
|
|
39
|
+
|
|
40
|
+
## 3. Check who you are
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
memhouse whoami
|
|
44
|
+
memhouse status
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`whoami` names the credential in use and what it may do. You should be a **member**,
|
|
48
|
+
not an administrator. `status` shows the connection, your row counts and freshness.
|
|
49
|
+
|
|
50
|
+
## 4. Keep shipping
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
memhouse start # shipper + dashboard, until the next reboot
|
|
54
|
+
memhouse service install # or: survive reboots (systemd --user / LaunchAgent)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Your dashboard is at http://localhost:4640. It reads the house, so it shows your
|
|
58
|
+
sessions from every machine you install on, not just this one.
|
|
59
|
+
|
|
60
|
+
## 5. More machines
|
|
61
|
+
|
|
62
|
+
Every machine you own ships into the same rooms, and the `host` column tells them apart.
|
|
63
|
+
The invite file is spent, so set up the next machine from this one's env file:
|
|
64
|
+
|
|
65
|
+
1. Copy `~/.memhouse/env` to the new machine over a trusted channel, to any path, say
|
|
66
|
+
`~/mh.env`. It holds your connection and your new password.
|
|
67
|
+
2. On the new machine, install from that copy:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
memhouse install --env ~/mh.env
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This installs and then deletes the copy. It does not offer to rotate: only an invite
|
|
74
|
+
file does, and rotating here would lock out your first machine.
|
|
75
|
+
|
|
76
|
+
Do not copy `~/.memhouse/host.json`. It is the first machine's identity, and each machine
|
|
77
|
+
mints its own.
|
|
78
|
+
|
|
79
|
+
## 6. Read your teammates' memory
|
|
80
|
+
|
|
81
|
+
Not yet. Nobody can read your rooms, and you cannot read theirs, until someone runs
|
|
82
|
+
`memhouse share`. [Tutorial 3](03-share-your-memory.md) covers it from both sides.
|
|
83
|
+
|
|
84
|
+
## When something goes wrong
|
|
85
|
+
|
|
86
|
+
- **`Authentication failed`** right after install: the inviter may have re-issued your
|
|
87
|
+
invite, or you rotated and another machine still has the old password. `memhouse passwd`
|
|
88
|
+
sets a new one; then update the other machines.
|
|
89
|
+
- **`invite file … no such file`**: check the path. The file is deleted only after a
|
|
90
|
+
successful install.
|
|
91
|
+
- Anything else: `memhouse doctor`, then [Troubleshooting](../guides/troubleshooting.md).
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Tutorial 3: share your memory
|
|
2
|
+
|
|
3
|
+
Two members of one house: `alice` and `bob`. Each owns their rooms, and neither can read
|
|
4
|
+
the other's. In this tutorial, alice lets bob read one project's history, then everything,
|
|
5
|
+
then takes it back. Bob reads it from his own agent.
|
|
6
|
+
|
|
7
|
+
**You need:** two members of the same house. If you have one house of your own, see
|
|
8
|
+
[Invite members](../guides/invite.md) to add a second.
|
|
9
|
+
|
|
10
|
+
## 1. Alice shares one project
|
|
11
|
+
|
|
12
|
+
On alice's machine:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
memhouse share bob --only project=memhouse
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
What this does:
|
|
19
|
+
|
|
20
|
+
- grants bob `SELECT` on exactly three of alice's rooms: `alice_sessions`,
|
|
21
|
+
`alice_messages` and `alice_tool_calls`;
|
|
22
|
+
- adds row policies so that, in those rooms, bob sees only rows where
|
|
23
|
+
`project = 'memhouse'`.
|
|
24
|
+
|
|
25
|
+
Bob gets nothing else. Alice's stats tables, `meta` and `events` stay closed to him, as
|
|
26
|
+
does any room alice gains later.
|
|
27
|
+
|
|
28
|
+
Other scopes work the same way:
|
|
29
|
+
|
|
30
|
+
- `session=…`
|
|
31
|
+
- `host=…`
|
|
32
|
+
- `source=…` (an editor, as stored: `claude-code`, `codex`, …)
|
|
33
|
+
- `folder=…`
|
|
34
|
+
- `since=…` and `until=…` (dates)
|
|
35
|
+
|
|
36
|
+
Before it creates the first policy, `share` checks how the server treats readers that
|
|
37
|
+
have no policy of their own: alice, and anyone with a full share. On some server
|
|
38
|
+
configurations, a table's first row policy blinds those readers to every row. On such a
|
|
39
|
+
server, `share` refuses rather than lock alice out of her own rooms.
|
|
40
|
+
|
|
41
|
+
## 2. Bob reads it
|
|
42
|
+
|
|
43
|
+
Bob's credential can now see three of alice's rooms. From any ClickHouse client, or
|
|
44
|
+
`/mem:sql` in bob's agent:
|
|
45
|
+
|
|
46
|
+
```sql
|
|
47
|
+
SELECT project, count() FROM mem.alice_messages GROUP BY project
|
|
48
|
+
-- one row: memhouse
|
|
49
|
+
|
|
50
|
+
SELECT count() FROM mem.alice_session_stats
|
|
51
|
+
-- refused: bob holds no grant on it
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
A query that strays outside the scope returns nothing, or is refused for the tables bob
|
|
55
|
+
was never granted. It never returns more than the scope.
|
|
56
|
+
|
|
57
|
+
## 3. Alice widens it to everything
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
memhouse share bob
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
A **full share** with no `--only`. Bob can now read all of `mem.alice_*`, including the
|
|
64
|
+
stats, `meta` (alice's other share records among it) and `events`. The command says so
|
|
65
|
+
when it runs. Use a full share for someone you would hand your laptop to.
|
|
66
|
+
|
|
67
|
+
Going back from full to scoped is the same `--only` command. It takes the wildcard grant
|
|
68
|
+
back first, so a failure part-way leaves bob with less access, never more.
|
|
69
|
+
|
|
70
|
+
## 4. See who can read what
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
memhouse share --list
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This prints memhouse's own record of the shares: each user, full or scoped, and the scope.
|
|
77
|
+
A grant someone made by hand in SQL does not appear.
|
|
78
|
+
|
|
79
|
+
## 5. Take it back
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
memhouse share bob --revoke
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This withdraws the grants first, then drops the row policies. If the revoke is refused
|
|
86
|
+
part-way, the policies stay, so bob never ends up with an unfiltered share.
|
|
87
|
+
|
|
88
|
+
## What sharing cannot do
|
|
89
|
+
|
|
90
|
+
- **Recall what was already read.** Bob may have copied rows while he could read them.
|
|
91
|
+
- **Write.** A share is read-only. Only alice writes into alice's rooms.
|
|
92
|
+
- **End with a password change.** Grants belong to the user, not the password. To cut
|
|
93
|
+
bob off, revoke.
|
|
94
|
+
|
|
95
|
+
More detail, including what a full share exposes and why scoped shares are table by
|
|
96
|
+
table: [Share and revoke](../guides/share.md).
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# 01 — one machine
|
|
2
|
+
|
|
3
|
+
The smallest memhouse: one person, one laptop, a ClickHouse in a local container. It shows
|
|
4
|
+
the whole loop — a house, a shipping pass, the rows in it, a search that finds a past
|
|
5
|
+
conversation — in about a minute.
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
1. `memhouse deploy --local` starts ClickHouse in Docker or Podman, bound to `127.0.0.1`
|
|
10
|
+
only, with a generated password. It creates two accounts: an administrator, and **you**
|
|
11
|
+
as a member who holds `mem.<you>_*` and nothing else. Both credentials go into the
|
|
12
|
+
memhouse home's `env` file (mode 600); nothing is typed or shown.
|
|
13
|
+
2. It installs memhouse against that house and starts a background shipper.
|
|
14
|
+
3. `memhouse ship` runs one pass in the foreground.
|
|
15
|
+
4. `memhouse status` shows what the house holds; `memhouse search` finds a session.
|
|
16
|
+
|
|
17
|
+
The script ships two made-up sessions from [`../fixtures`](../fixtures/), never yours, and
|
|
18
|
+
works in its own home (`~/.memhouse-example-01`), so an install you already have is left
|
|
19
|
+
alone.
|
|
20
|
+
|
|
21
|
+
## Needs
|
|
22
|
+
|
|
23
|
+
- Node.js 24 or newer, and `npm install -g memhouse`
|
|
24
|
+
- Docker or Podman, and port 8123 free (or set `HOUSE_PORT`)
|
|
25
|
+
- No earlier `memhouse deploy --local` on this machine. The container and volume names are
|
|
26
|
+
fixed (`memhouse-clickhouse`, `memhouse-data`), so a second local house refuses to start.
|
|
27
|
+
If you have one, you already have this example's result; try [02](../02-existing-clickhouse/).
|
|
28
|
+
|
|
29
|
+
## Run
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
./run.sh
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
| Variable | Default | |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `MEMHOUSE_BIN` | `memhouse` | the command to run, e.g. `node ~/memhouse/bin/memhouse.js` |
|
|
38
|
+
| `EXAMPLE_HOME` | `~/.memhouse-example-01` | this example's memhouse home |
|
|
39
|
+
| `HOUSE_PORT` | `8123` | the local port ClickHouse binds |
|
|
40
|
+
|
|
41
|
+
## What you should see
|
|
42
|
+
|
|
43
|
+
Trimmed from a run on a Linux VM with Docker, ClickHouse 26.7 and memhouse 0.18.9:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
== 1. a house: ClickHouse in a container, bound to loopback, plus the install
|
|
47
|
+
✓ ClickHouse starting via docker on http://localhost:8123 (loopback only)
|
|
48
|
+
✓ ClickHouse ready
|
|
49
|
+
✓ member 'polat' holds mem.polat_* and nothing else; 'memhouse_root' administers the house
|
|
50
|
+
✓ rooms for 'polat': polat_sessions, polat_messages, polat_tool_calls
|
|
51
|
+
✓ installed
|
|
52
|
+
✓ shipper started in the background (pid 617049) — loading your history now
|
|
53
|
+
|
|
54
|
+
== 2. one shipping pass
|
|
55
|
+
[memhouse] shipped 2 sessions (0 skipped) → 6 msg rows, 2 tool rows in 0.7s
|
|
56
|
+
|
|
57
|
+
== 3. what the house holds
|
|
58
|
+
✓ connected: http://localhost:8123 / mem as polat
|
|
59
|
+
✓ house: 2 sessions, 6 messages (freshest ingest 2026-10-07 21:08:06 UTC)
|
|
60
|
+
✓ fleet: 1 active writer(s)
|
|
61
|
+
polat@testbed-7edeca38 0.18.9 last ship 0m ago
|
|
62
|
+
✓ shipper: running — daemon (pid 617049)
|
|
63
|
+
|
|
64
|
+
== 4. find a past conversation
|
|
65
|
+
claude-code:421460e4-5e66-4c1c-afa4-f1b198c28c25 claude-code alpha 2026-10-07 19:07 (1 hit)
|
|
66
|
+
The deploy fails with ClickHouse error ACCESS_DENIED on INSERT. Why?
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Three messages per session in the house, not four: the tool result is folded into the
|
|
70
|
+
tool call it answers.
|
|
71
|
+
|
|
72
|
+
To look around, start the dashboard in the example's home (pick another port if 4640 is
|
|
73
|
+
taken by a real install):
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
MEMHOUSE_HOME=~/.memhouse-example-01 MEMHOUSE_PORT=4641 memhouse start
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Teardown
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
./run.sh --teardown
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Stops the shipper (by the pid memhouse recorded), removes the container **and its data
|
|
86
|
+
volume**, and deletes the example's home.
|
|
87
|
+
|
|
88
|
+
## For real
|
|
89
|
+
|
|
90
|
+
The same thing with your own sessions is two commands, in your default home:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npm install -g memhouse
|
|
94
|
+
memhouse deploy --local
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Every editor memhouse knows is read (`memhouse discover` lists what it finds first). Then
|
|
98
|
+
`memhouse start` for the dashboard and `memhouse plugins install claude` to give your agents
|
|
99
|
+
`/mem:recall` and the other skills.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Example 01 — one person, one machine.
|
|
3
|
+
#
|
|
4
|
+
# A house in a local container, two made-up sessions shipped into it, then read back.
|
|
5
|
+
# Runs in its own memhouse home, so an install you already have is never touched.
|
|
6
|
+
#
|
|
7
|
+
# ./run.sh build it and show it
|
|
8
|
+
# ./run.sh --teardown stop the shipper, remove the container and its volume, delete the home
|
|
9
|
+
#
|
|
10
|
+
# Environment (all optional):
|
|
11
|
+
# MEMHOUSE_BIN the memhouse command (default: memhouse)
|
|
12
|
+
# EXAMPLE_HOME where this example's install lives (default: ~/.memhouse-example-01)
|
|
13
|
+
# HOUSE_PORT the local port ClickHouse binds (default: 8123)
|
|
14
|
+
set -euo pipefail
|
|
15
|
+
|
|
16
|
+
HERE=$(cd "$(dirname "$0")" && pwd)
|
|
17
|
+
MH=${MEMHOUSE_BIN:-memhouse}
|
|
18
|
+
mh() { $MH "$@"; }
|
|
19
|
+
|
|
20
|
+
# Only this example's home speaks. An exported credential from another install would
|
|
21
|
+
# otherwise outrank the home's own env file (flags > MEMHOUSE_* > env file).
|
|
22
|
+
unset MEMHOUSE_URL MEMHOUSE_USER MEMHOUSE_PASSWORD MEMHOUSE_DB MEMHOUSE_ADMIN_USER MEMHOUSE_ADMIN_PASSWORD
|
|
23
|
+
export MEMHOUSE_HOME=${EXAMPLE_HOME:-$HOME/.memhouse-example-01}
|
|
24
|
+
HOUSE_PORT=${HOUSE_PORT:-8123}
|
|
25
|
+
|
|
26
|
+
if [ "${1:-}" = "--teardown" ]; then
|
|
27
|
+
mh stop || true
|
|
28
|
+
mh deploy --down --yes
|
|
29
|
+
rm -rf "$MEMHOUSE_HOME"
|
|
30
|
+
echo "example 01 removed"
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
mkdir -p "$MEMHOUSE_HOME"
|
|
35
|
+
|
|
36
|
+
# Made-up sessions, and nothing else: the shipper reads only this directory.
|
|
37
|
+
FIX="$MEMHOUSE_HOME/example-sessions"
|
|
38
|
+
if [ ! -d "$FIX/projects" ]; then
|
|
39
|
+
echo "== writing two made-up Claude Code sessions to $FIX"
|
|
40
|
+
node "$HERE/../fixtures/make-sessions.js" "$FIX" me alpha beta
|
|
41
|
+
fi
|
|
42
|
+
export MEMHOUSE_EDITORS=claude MEMHOUSE_CLAUDE_ROOTS="$FIX"
|
|
43
|
+
|
|
44
|
+
echo "== 1. a house: ClickHouse in a container, bound to loopback, plus the install"
|
|
45
|
+
mh deploy --local --house-port "$HOUSE_PORT"
|
|
46
|
+
|
|
47
|
+
echo
|
|
48
|
+
echo "== 2. one shipping pass (deploy also started a background shipper; this one is in the foreground)"
|
|
49
|
+
mh ship
|
|
50
|
+
|
|
51
|
+
echo
|
|
52
|
+
echo "== 3. what the house holds"
|
|
53
|
+
mh status
|
|
54
|
+
|
|
55
|
+
echo
|
|
56
|
+
echo "== 4. find a past conversation"
|
|
57
|
+
mh search ACCESS_DENIED
|
|
58
|
+
|
|
59
|
+
echo
|
|
60
|
+
echo "Done. Open the dashboard: MEMHOUSE_HOME=$MEMHOUSE_HOME $MH start (then http://localhost:4640)"
|
|
61
|
+
echo "Remove everything: $0 --teardown"
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# 02 — an existing ClickHouse
|
|
2
|
+
|
|
3
|
+
You already run ClickHouse — a server of your own, your company's cluster, or ClickHouse
|
|
4
|
+
Cloud — and want memhouse to keep its house there. You hold an account on it that can
|
|
5
|
+
create users. This example builds a **member** account with it, installs as that member,
|
|
6
|
+
and keeps only the member's credential on disk.
|
|
7
|
+
|
|
8
|
+
## What it does
|
|
9
|
+
|
|
10
|
+
1. `memhouse whoami --admin` checks that the admin credential really can create users and
|
|
11
|
+
grant, before anything is changed.
|
|
12
|
+
2. `memhouse install --admin-user …` creates the member (default: your login name), grants
|
|
13
|
+
it `mem.<member>_*` and nothing else, creates its rooms, and verifies the install by
|
|
14
|
+
connecting **as the member**. The admin credential is used for this one command and not
|
|
15
|
+
saved (add `--keep-admin` if this machine should be able to invite people later).
|
|
16
|
+
3. `memhouse ship --ensure-schema` creates any room or stat table that is missing — safe to
|
|
17
|
+
re-run, and the thing to run after an upgrade that adds one — then `memhouse ship`
|
|
18
|
+
ships two made-up sessions.
|
|
19
|
+
4. `memhouse whoami` and `memhouse status` show the credential this machine now keeps and
|
|
20
|
+
what the house holds.
|
|
21
|
+
|
|
22
|
+
## Needs
|
|
23
|
+
|
|
24
|
+
- Node.js 24 or newer, and `npm install -g memhouse`
|
|
25
|
+
- The ClickHouse HTTP endpoint, e.g. `https://ch.example.com:8443` (ClickHouse Cloud:
|
|
26
|
+
the HTTPS endpoint from the console). memhouse's CI runs on ClickHouse 25.11 and 26.7.
|
|
27
|
+
- An account that can create users and databases and grant what it holds. A server's
|
|
28
|
+
first administrator qualifies: the `default` user of a fresh server, or the user the
|
|
29
|
+
Docker image creates with `CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1`. Step 1 tells you
|
|
30
|
+
whether yours does before anything changes.
|
|
31
|
+
- The admin password where a tool can lend it to one command. It never goes on a command
|
|
32
|
+
line: `ps` and shell history would keep it.
|
|
33
|
+
|
|
34
|
+
## Run
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
export MEMHOUSE_URL=https://ch.example.com:8443
|
|
38
|
+
export MEMHOUSE_ADMIN_USER=default
|
|
39
|
+
with-secret MEMHOUSE_ADMIN_PASSWORD=keychain:clickhouse-admin -- ./run.sh
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
No secret tool? Read it into this shell without echo:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
read -rs MEMHOUSE_ADMIN_PASSWORD && export MEMHOUSE_ADMIN_PASSWORD
|
|
46
|
+
./run.sh
|
|
47
|
+
unset MEMHOUSE_ADMIN_PASSWORD
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Variable | Default | |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `MEMHOUSE_URL` | (required) | the ClickHouse HTTP(S) endpoint |
|
|
53
|
+
| `MEMHOUSE_ADMIN_USER` | (required) | the account that creates the member |
|
|
54
|
+
| `MEMHOUSE_ADMIN_PASSWORD` | (required) | its password, lent by a secret tool |
|
|
55
|
+
| `MEMBER` | your login name | the member to create |
|
|
56
|
+
| `MEMHOUSE_BIN` | `memhouse` | the command to run |
|
|
57
|
+
| `EXAMPLE_HOME` | `~/.memhouse-example-02` | this example's memhouse home |
|
|
58
|
+
|
|
59
|
+
The same install without the script, giving the password on stdin instead of the
|
|
60
|
+
environment:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
printf '%s' "$PASSWORD" | memhouse install --url "$MEMHOUSE_URL" --admin-user default \
|
|
64
|
+
--member alice --admin-password-file - --yes
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## What you should see
|
|
68
|
+
|
|
69
|
+
Trimmed from a run against ClickHouse 26.7.1.1315 with memhouse 0.18.9 (the test endpoint is shown as `ch.example.com`):
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
== 1. whoami --admin: is this credential really an administrator?
|
|
73
|
+
✓ admin at https://ch.example.com:8443 — administrator
|
|
74
|
+
credential from: MEMHOUSE_ADMIN_* environment
|
|
75
|
+
may create users: yes
|
|
76
|
+
|
|
77
|
+
== 2. install: build member 'polat' with the admin credential, then verify as the member
|
|
78
|
+
✓ created ClickHouse user 'polat'
|
|
79
|
+
✓ granted 'polat' mem.polat_* — their rooms and nothing else; async_insert pinned
|
|
80
|
+
✓ verified as 'polat' with the member credential
|
|
81
|
+
✓ installed
|
|
82
|
+
the admin credential was used for this install and not saved. To invite later:
|
|
83
|
+
with-secret MEMHOUSE_ADMIN_PASSWORD=<reference> -- memhouse invite <name> --url … --admin-user admin
|
|
84
|
+
|
|
85
|
+
== 3. make sure every room and stat table exists, then ship once
|
|
86
|
+
[memhouse] schema ensured (5 statements)
|
|
87
|
+
[memhouse] shipped 2 sessions (0 skipped) → 6 msg rows, 2 tool rows in 0.2s
|
|
88
|
+
|
|
89
|
+
== 4. whoami: the credential this machine keeps, and what it may do
|
|
90
|
+
✓ polat at https://ch.example.com:8443 — member
|
|
91
|
+
may create users: no
|
|
92
|
+
|
|
93
|
+
== 5. status
|
|
94
|
+
✓ house: 2 sessions, 6 messages
|
|
95
|
+
✓ fleet: 1 active writer(s)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Step 2 generates the member password and writes it only to the home's `env` file (mode
|
|
99
|
+
600). From 0.18.10 no command prints it; earlier versions showed it once on this step.
|
|
100
|
+
|
|
101
|
+
## Teardown
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
./run.sh --teardown
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Deletes the example's home. The member and its rooms stay in the house: dropping them is
|
|
108
|
+
an administrator's decision. As the admin:
|
|
109
|
+
|
|
110
|
+
```sql
|
|
111
|
+
DROP USER polat;
|
|
112
|
+
-- then each of mem.polat_sessions, _messages, _tool_calls, _meta, _events,
|
|
113
|
+
-- _session_stats, _session_model_stats, _session_tool_stats
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## For real
|
|
117
|
+
|
|
118
|
+
Leave out the two fixture flags (`--editors claude --claude-roots …`) and the
|
|
119
|
+
`EXAMPLE_HOME`, and every editor on the machine ships into the house. Your other machines
|
|
120
|
+
join the same rooms by installing with the same member credential (`memhouse install --url
|
|
121
|
+
… --user <member> --password …`, or an invite file — see [03](../03-team-house/)).
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Example 02 — point memhouse at a ClickHouse you already run.
|
|
3
|
+
#
|
|
4
|
+
# The admin credential builds a member account (rooms mem.<member>_*, one grant on exactly
|
|
5
|
+
# those), the install is verified AS that member, and the admin credential is then dropped:
|
|
6
|
+
# what stays on disk is the member's. The admin password never touches the command line.
|
|
7
|
+
#
|
|
8
|
+
# with-secret MEMHOUSE_ADMIN_PASSWORD=<reference> -- ./run.sh
|
|
9
|
+
# ./run.sh --teardown stop anything this home started and delete the home
|
|
10
|
+
#
|
|
11
|
+
# Environment:
|
|
12
|
+
# MEMHOUSE_URL required the ClickHouse HTTP endpoint, e.g. https://ch.example.com:8443
|
|
13
|
+
# MEMHOUSE_ADMIN_USER required an account that can create users and grant
|
|
14
|
+
# MEMHOUSE_ADMIN_PASSWORD required its password — lent by with-secret, never typed into argv
|
|
15
|
+
# MEMBER optional the member to create (default: your login name)
|
|
16
|
+
# MEMHOUSE_BIN optional the memhouse command (default: memhouse)
|
|
17
|
+
# EXAMPLE_HOME optional where this install lives (default: ~/.memhouse-example-02)
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
HERE=$(cd "$(dirname "$0")" && pwd)
|
|
21
|
+
MH=${MEMHOUSE_BIN:-memhouse}
|
|
22
|
+
mh() { $MH "$@"; }
|
|
23
|
+
export MEMHOUSE_HOME=${EXAMPLE_HOME:-$HOME/.memhouse-example-02}
|
|
24
|
+
|
|
25
|
+
if [ "${1:-}" = "--teardown" ]; then
|
|
26
|
+
mh stop || true
|
|
27
|
+
rm -rf "$MEMHOUSE_HOME"
|
|
28
|
+
echo "example 02 home removed. The member and its rooms stay in the house; dropping them is an admin's call."
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
: "${MEMHOUSE_URL:?set MEMHOUSE_URL to your ClickHouse HTTP endpoint}"
|
|
33
|
+
: "${MEMHOUSE_ADMIN_USER:?set MEMHOUSE_ADMIN_USER to an account that can create users}"
|
|
34
|
+
: "${MEMHOUSE_ADMIN_PASSWORD:?lend it with: with-secret MEMHOUSE_ADMIN_PASSWORD=<reference> -- $0}"
|
|
35
|
+
# A login name like "first.last" is not a ClickHouse user name memhouse accepts.
|
|
36
|
+
MEMBER=${MEMBER:-$(id -un | tr -c 'A-Za-z0-9_\n' '_' | sed 's/^[^A-Za-z]*//')}
|
|
37
|
+
# Only the admin variables and the URL come from outside. A member credential exported
|
|
38
|
+
# by some other install would outrank this home's env file.
|
|
39
|
+
unset MEMHOUSE_USER MEMHOUSE_PASSWORD MEMHOUSE_DB
|
|
40
|
+
|
|
41
|
+
mkdir -p "$MEMHOUSE_HOME"
|
|
42
|
+
FIX="$MEMHOUSE_HOME/example-sessions"
|
|
43
|
+
[ -d "$FIX/projects" ] || node "$HERE/../fixtures/make-sessions.js" "$FIX" "$MEMBER" alpha beta >/dev/null
|
|
44
|
+
|
|
45
|
+
echo "== 1. whoami --admin: is this credential really an administrator?"
|
|
46
|
+
mh whoami --admin
|
|
47
|
+
|
|
48
|
+
echo
|
|
49
|
+
echo "== 2. install: build member '$MEMBER' with the admin credential, then verify as the member"
|
|
50
|
+
# --editors/--claude-roots keep this example to the made-up sessions above. Drop both to
|
|
51
|
+
# ship your real ones. --no-ship: nothing runs in the background; step 3 ships once.
|
|
52
|
+
mh install --url "$MEMHOUSE_URL" --admin-user "$MEMHOUSE_ADMIN_USER" --member "$MEMBER" \
|
|
53
|
+
--editors claude --claude-roots "$FIX" --yes --no-ship
|
|
54
|
+
|
|
55
|
+
# From here on the member credential in the env file is the only one in play.
|
|
56
|
+
unset MEMHOUSE_ADMIN_USER MEMHOUSE_ADMIN_PASSWORD
|
|
57
|
+
|
|
58
|
+
echo
|
|
59
|
+
echo "== 3. make sure every room and stat table exists, then ship once"
|
|
60
|
+
# --ensure-schema only creates what is missing, as the member, and ships nothing; it is
|
|
61
|
+
# safe to re-run, and the thing to run after an upgrade that adds a table.
|
|
62
|
+
mh ship --ensure-schema
|
|
63
|
+
mh ship
|
|
64
|
+
|
|
65
|
+
echo
|
|
66
|
+
echo "== 4. whoami: the credential this machine keeps, and what it may do"
|
|
67
|
+
mh whoami
|
|
68
|
+
|
|
69
|
+
echo
|
|
70
|
+
echo "== 5. status"
|
|
71
|
+
mh status
|