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.
Files changed (45) hide show
  1. package/AGENTS.md +194 -0
  2. package/CHANGELOG.md +970 -0
  3. package/README.md +54 -423
  4. package/SECURITY.md +68 -0
  5. package/bin/memhouse.js +202 -92
  6. package/docs/README.md +46 -0
  7. package/docs/guides/admin-password.md +95 -0
  8. package/docs/guides/configuration.md +109 -0
  9. package/docs/guides/daemons.md +53 -0
  10. package/docs/guides/install.md +128 -0
  11. package/docs/guides/invite.md +87 -0
  12. package/docs/guides/operate.md +112 -0
  13. package/docs/guides/search-and-resume.md +95 -0
  14. package/docs/guides/share.md +102 -0
  15. package/docs/guides/storage.md +90 -0
  16. package/docs/guides/troubleshooting.md +78 -0
  17. package/docs/guides/uninstall.md +35 -0
  18. package/docs/guides/update.md +68 -0
  19. package/docs/releases/README.md +10 -0
  20. package/docs/releases/v0.18.10.md +226 -0
  21. package/docs/tutorials/01-first-house.md +132 -0
  22. package/docs/tutorials/02-join-a-house.md +91 -0
  23. package/docs/tutorials/03-share-your-memory.md +96 -0
  24. package/examples/01-local-one-machine/README.md +99 -0
  25. package/examples/01-local-one-machine/run.sh +61 -0
  26. package/examples/02-existing-clickhouse/README.md +121 -0
  27. package/examples/02-existing-clickhouse/run.sh +71 -0
  28. package/examples/03-team-house/README.md +129 -0
  29. package/examples/03-team-house/run.sh +124 -0
  30. package/examples/04-self-hosted-team/.env.example +22 -0
  31. package/examples/04-self-hosted-team/README.md +187 -0
  32. package/examples/04-self-hosted-team/compose.yml +158 -0
  33. package/examples/04-self-hosted-team/smoke.sh +113 -0
  34. package/examples/README.md +42 -0
  35. package/examples/fixtures/README.md +24 -0
  36. package/examples/fixtures/make-sessions.js +63 -0
  37. package/memhouse/admin-secret.js +81 -0
  38. package/memhouse/delivery/plugin/.claude-plugin/plugin.json +1 -1
  39. package/memhouse/deploy.js +4 -2
  40. package/memhouse/flags.js +4 -4
  41. package/memhouse/provision.js +12 -3
  42. package/memhouse/server/queries.js +18 -4
  43. package/memhouse/server/server.js +9 -1
  44. package/memhouse/service.js +5 -0
  45. 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