memhouse 0.16.0 → 0.17.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 +1 -1
- package/bin/memhouse.js +270 -22
- package/memhouse/delivery/AGENT-INSTALL-PROMPT.md +2 -2
- package/memhouse/delivery/AGENT-INSTALL.md +2 -2
- package/memhouse/delivery/PROMPT.md +15 -9
- package/memhouse/delivery/plugin/.claude-plugin/plugin.json +2 -2
- package/memhouse/delivery/plugin/reference/HOUSE.md +154 -0
- package/memhouse/delivery/plugin/skills/access/SKILL.md +148 -0
- package/memhouse/delivery/plugin/skills/admin/SKILL.md +29 -0
- package/memhouse/delivery/plugin/skills/house/SKILL.md +99 -0
- package/memhouse/delivery/plugin/skills/recall/SKILL.md +119 -0
- package/memhouse/delivery/plugin/skills/sql/SKILL.md +73 -194
- package/memhouse/flags.js +1 -0
- package/memhouse/share.js +64 -0
- package/package.json +1 -1
- package/memhouse/delivery/plugin/skills/ask/SKILL.md +0 -131
- package/memhouse/delivery/plugin/skills/hello/SKILL.md +0 -121
- package/memhouse/delivery/plugin/skills/invite/SKILL.md +0 -130
- package/memhouse/delivery/plugin/skills/search/SKILL.md +0 -186
- package/memhouse/delivery/plugin/skills/sessions/SKILL.md +0 -164
- package/memhouse/delivery/plugin/skills/share/SKILL.md +0 -130
- package/memhouse/delivery/plugin/skills/status/SKILL.md +0 -139
- package/memhouse/delivery/plugin/skills/users/SKILL.md +0 -97
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: status
|
|
3
|
-
description: Show the state of the memory system — what the house holds (sessions, messages, tokens per editor), how fresh it is, its schema generation and migration state, and every machine writing into it. Use when the user asks "is my memory working", "how much is stored", "when did it last ship", "what's in the house", "which machines are shipping", or before debugging why a search found nothing.
|
|
4
|
-
user-invocable: true
|
|
5
|
-
argument-hint: ""
|
|
6
|
-
allowed-tools: Bash
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# /mem:status — the state of the memory system
|
|
10
|
-
|
|
11
|
-
**Invoking this skill IS the request. Run the report immediately — connect, run the four
|
|
12
|
-
sections below, and present the summary. There are no arguments and nothing to clarify;
|
|
13
|
-
do not describe this skill or ask what to check.** (Driven live, a model did exactly
|
|
14
|
-
that: it summarized the file and asked "is there something specific?" — a status command
|
|
15
|
-
that answers with a question has failed.)
|
|
16
|
-
|
|
17
|
-
One report, four sections: what the house holds, how fresh it is, what generation it is
|
|
18
|
-
at, and who writes into it. Read-only; nothing here changes anything.
|
|
19
|
-
|
|
20
|
-
## Connection
|
|
21
|
-
|
|
22
|
-
**Never print this file or the variables in it.** No `cat "$MH_ENV"`, no `env | grep
|
|
23
|
-
MEMHOUSE`, no `set -x` around these commands. Anything you print becomes part of a
|
|
24
|
-
transcript that memhouse itself ships into the house.
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
MH_ENV="${MEMHOUSE_HOME:-$HOME/.memhouse}/env"
|
|
28
|
-
_u=${MEMHOUSE_URL-}; _s=${MEMHOUSE_USER-}; _p=${MEMHOUSE_PASSWORD-}; _d=${MEMHOUSE_DB-}
|
|
29
|
-
set -a; [ -f "$MH_ENV" ] && . "$MH_ENV"; set +a
|
|
30
|
-
[ -n "$_u" ] && MEMHOUSE_URL=$_u; [ -n "$_s" ] && MEMHOUSE_USER=$_s
|
|
31
|
-
[ -n "$_p" ] && MEMHOUSE_PASSWORD=$_p; [ -n "$_d" ] && MEMHOUSE_DB=$_d
|
|
32
|
-
if [ -z "${MEMHOUSE_URL:-}" ] || [ -z "${MEMHOUSE_USER:-}" ]; then
|
|
33
|
-
echo "no memhouse house configured — nothing in $MH_ENV and no MEMHOUSE_URL/MEMHOUSE_USER set." >&2
|
|
34
|
-
echo "Run: memhouse install" >&2
|
|
35
|
-
exit 1
|
|
36
|
-
fi
|
|
37
|
-
|
|
38
|
-
curl -sS --fail-with-body --user "$MEMHOUSE_USER:${MEMHOUSE_PASSWORD:-}" \
|
|
39
|
-
--data-binary @- "$MEMHOUSE_URL/?database=${MEMHOUSE_DB:-$MEMHOUSE_USER}&final=1&join_use_nulls=1&readonly=1" <<'SQL'
|
|
40
|
-
<the query>
|
|
41
|
-
FORMAT PrettyCompact
|
|
42
|
-
SQL
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## The report — run these, then summarize
|
|
46
|
-
|
|
47
|
-
**1. What the house holds** — per editor, CURRENT parses only (the rooms retain
|
|
48
|
-
superseded parses; an unfiltered count over-reports on any compacted session):
|
|
49
|
-
|
|
50
|
-
```sql
|
|
51
|
-
SELECT source,
|
|
52
|
-
uniqExact(session_id) AS sessions,
|
|
53
|
-
count() AS messages,
|
|
54
|
-
sum(input_tokens + output_tokens + cache_read_tokens + cache_write_tokens) AS tokens
|
|
55
|
-
FROM messages
|
|
56
|
-
WHERE origin != 'ship'
|
|
57
|
-
OR (session_id, user_id, epoch) IN (
|
|
58
|
-
SELECT session_id, user_id, max(epoch) FROM messages
|
|
59
|
-
WHERE origin = 'ship' GROUP BY session_id, user_id)
|
|
60
|
-
GROUP BY source ORDER BY sessions DESC
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
**2. Freshness and coverage** — when the archive starts, ends, and last received:
|
|
64
|
-
|
|
65
|
-
```sql
|
|
66
|
-
SELECT formatDateTime(min(ts), '%Y-%m-%d') AS oldest,
|
|
67
|
-
formatDateTime(max(ts), '%Y-%m-%d %H:%i') AS newest,
|
|
68
|
-
formatDateTime(max(ingested_at), '%Y-%m-%d %H:%i') AS last_ingest
|
|
69
|
-
FROM messages
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
A `last_ingest` hours old with the user actively working means the shipper is not
|
|
73
|
-
running — say so and point at `memhouse status` / `memhouse start` on that machine.
|
|
74
|
-
|
|
75
|
-
**3. Generation and migration state** — the house's record of itself (absent on a
|
|
76
|
-
pre-0.10 house; that absence is itself the answer: say the house predates the record):
|
|
77
|
-
|
|
78
|
-
```sql
|
|
79
|
-
SELECT key, value FROM house_meta FINAL
|
|
80
|
-
WHERE key IN ('schema_version', 'min_writer_schema') ORDER BY key
|
|
81
|
-
```
|
|
82
|
-
```sql
|
|
83
|
-
SELECT id, argMax(status, event_at) AS status,
|
|
84
|
-
formatDateTime(max(event_at), '%Y-%m-%d %H:%i') AS at
|
|
85
|
-
FROM house_events WHERE kind = 'migration' GROUP BY id ORDER BY at DESC LIMIT 3
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
A `pending` here with nothing running means an interrupted migration — name
|
|
89
|
-
`memhouse migrate` (it refuses stale leftovers legibly rather than clobbering them).
|
|
90
|
-
|
|
91
|
-
**4. The fleet** — every machine writing into this house, from the DATA (a pre-0.10
|
|
92
|
-
writer records nothing about itself, so rows-without-record is the finding):
|
|
93
|
-
|
|
94
|
-
```sql
|
|
95
|
-
SELECT user_id, host, count() AS rows,
|
|
96
|
-
formatDateTime(max(ingested_at), '%Y-%m-%d %H:%i') AS last_write
|
|
97
|
-
FROM messages GROUP BY user_id, host ORDER BY last_write DESC
|
|
98
|
-
```
|
|
99
|
-
```sql
|
|
100
|
-
SELECT key, value FROM house_meta FINAL
|
|
101
|
-
WHERE key LIKE 'client_version:%' OR key LIKE 'client_schema:%' OR key LIKE 'last_ship:%'
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
Match `client_*:<member>@<host>` against the data rows. A `(user_id, host)` pair with
|
|
105
|
-
rows but NO `client_*` record is a **pre-0.10 memhouse still writing** — flag it: its
|
|
106
|
-
re-ships delete retained parses, and the fixes are upgrade it or (as admin)
|
|
107
|
-
`REVOKE ALTER DELETE, ALTER UPDATE ON <db>.* FROM <member>`.
|
|
108
|
-
|
|
109
|
-
**5. Client freshness** — is the installed memhouse behind the published release? This is a
|
|
110
|
-
shell check, not SQL (it reads the local binary and the npm registry, no house involved):
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
INSTALLED=$(memhouse version 2>/dev/null | head -1 | tr -d '[:space:]')
|
|
114
|
-
LATEST=$(curl -sS -m 5 https://registry.npmjs.org/memhouse/latest 2>/dev/null | sed -n 's/.*"version":"\([^"]*\)".*/\1/p')
|
|
115
|
-
echo "installed=${INSTALLED:-unknown} latest=${LATEST:-unknown}"
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Compare the two as `MAJOR.MINOR.PATCH`. Report freshness, and size the nudge to the gap:
|
|
119
|
-
|
|
120
|
-
- **up to date** (installed ≥ latest) — one line: "client 0.X.Y, current."
|
|
121
|
-
- **small gap** (same major+minor, a patch or two behind) — a gentle note: "a newer patch
|
|
122
|
-
0.X.Z is out; `memhouse update` when convenient."
|
|
123
|
-
- **big gap** (latest MAJOR or MINOR is ahead, or many patches) — surface it prominently and
|
|
124
|
-
**offer to update**: "your memhouse is 0.A.B but 0.C.D is released — run **`memhouse
|
|
125
|
-
update`** to upgrade; it also refreshes the `/mem:*` plugin, then `/reload-plugins`."
|
|
126
|
-
- either side **unknown** (no binary on PATH, or the registry did not answer) — say which,
|
|
127
|
-
don't guess. A plugin-only install with no CLI can't self-update; point at
|
|
128
|
-
`npm i -g memhouse`.
|
|
129
|
-
|
|
130
|
-
Never run `memhouse update` yourself — it restarts daemons and may migrate the house.
|
|
131
|
-
Offer the command; the pilot runs it.
|
|
132
|
-
|
|
133
|
-
## Presenting it
|
|
134
|
-
|
|
135
|
-
Lead with one line of verdict ("healthy: N sessions across M editors, last ingest X
|
|
136
|
-
minutes ago" — or the one thing wrong). Then the per-editor table, then anything from
|
|
137
|
-
sections 3–5 that needs action. A **big version gap (section 5) is an action** — put the
|
|
138
|
-
`memhouse update` offer near the top, not buried. Skip empty sections; do not pad. If the
|
|
139
|
-
house is unreachable, say which URL refused and stop — never guess another endpoint.
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: users
|
|
3
|
-
description: Show the people around your memory — who writes into your house and from which machines, which other houses on this ClickHouse you can read, and who can read yours. Use when the user asks "who can see my memory", "whose memory can I see", "which houses are on this server", "who else ships here", or before/after sharing with /mem:share.
|
|
4
|
-
user-invocable: true
|
|
5
|
-
argument-hint: ""
|
|
6
|
-
allowed-tools: Bash
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# /mem:users — who is around your memory
|
|
10
|
-
|
|
11
|
-
**Invoking this skill IS the request. Run the report immediately and present it; there
|
|
12
|
-
are no arguments and nothing to clarify.** Read-only throughout.
|
|
13
|
-
|
|
14
|
-
Throughout, `<your-db>` is the live `$MEMHOUSE_DB` and `<your-user>` the live
|
|
15
|
-
`$MEMHOUSE_USER` — take both from the connection environment, never from the
|
|
16
|
-
conversation or from examples.
|
|
17
|
-
|
|
18
|
-
Answers three questions, best-effort by design: ClickHouse shows a credential only what
|
|
19
|
-
it may see, so on someone else's server some sections legitimately come back thin — say
|
|
20
|
-
what could not be seen rather than guessing.
|
|
21
|
-
|
|
22
|
-
## Connection
|
|
23
|
-
|
|
24
|
-
**Never print this file or the variables in it.** No `cat "$MH_ENV"`, no `env | grep
|
|
25
|
-
MEMHOUSE`, no `set -x` around these commands.
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
MH_ENV="${MEMHOUSE_HOME:-$HOME/.memhouse}/env"
|
|
29
|
-
_u=${MEMHOUSE_URL-}; _s=${MEMHOUSE_USER-}; _p=${MEMHOUSE_PASSWORD-}; _d=${MEMHOUSE_DB-}
|
|
30
|
-
set -a; [ -f "$MH_ENV" ] && . "$MH_ENV"; set +a
|
|
31
|
-
[ -n "$_u" ] && MEMHOUSE_URL=$_u; [ -n "$_s" ] && MEMHOUSE_USER=$_s
|
|
32
|
-
[ -n "$_p" ] && MEMHOUSE_PASSWORD=$_p; [ -n "$_d" ] && MEMHOUSE_DB=$_d
|
|
33
|
-
if [ -z "${MEMHOUSE_URL:-}" ] || [ -z "${MEMHOUSE_USER:-}" ]; then
|
|
34
|
-
echo "no memhouse house configured — nothing in $MH_ENV and no MEMHOUSE_URL/MEMHOUSE_USER set." >&2
|
|
35
|
-
echo "Run: memhouse install" >&2
|
|
36
|
-
exit 1
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
|
-
curl -sS --fail-with-body --user "$MEMHOUSE_USER:${MEMHOUSE_PASSWORD:-}" \
|
|
40
|
-
--data-binary @- "$MEMHOUSE_URL/?database=${MEMHOUSE_DB:-$MEMHOUSE_USER}&readonly=1" <<'SQL'
|
|
41
|
-
<the query>
|
|
42
|
-
FORMAT PrettyCompact
|
|
43
|
-
SQL
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## The report
|
|
47
|
-
|
|
48
|
-
**1. Who writes into YOUR house** — members × machines, from the data (same ground truth
|
|
49
|
-
as /mem:status's fleet):
|
|
50
|
-
|
|
51
|
-
```sql
|
|
52
|
-
SELECT user_id AS member, host AS machine, count() AS rows,
|
|
53
|
-
formatDateTime(max(ingested_at), '%Y-%m-%d %H:%i') AS last_write
|
|
54
|
-
FROM messages GROUP BY user_id, host ORDER BY last_write DESC
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**2. Whose memory YOU can read** — every database your credential reaches is one someone
|
|
58
|
-
gave you (or your own):
|
|
59
|
-
|
|
60
|
-
```sql
|
|
61
|
-
SHOW DATABASES
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Drop `system`, `information_schema`, `INFORMATION_SCHEMA`, `default` unless they hold
|
|
65
|
-
rooms. For each OTHER house listed, it is readable because of a grant — one line each:
|
|
66
|
-
`house 'polat' — readable (shared with you); query it as polat.messages`.
|
|
67
|
-
|
|
68
|
-
**3. Who can read YOURS** — from the house's own share record (`system.grants` needs
|
|
69
|
-
privileges a member does not hold, so the record /mem:share keeps is the readable
|
|
70
|
-
source; an admin-issued grant will not appear in it, and the report should say so):
|
|
71
|
-
|
|
72
|
-
```sql
|
|
73
|
-
SELECT substring(key, 7) AS user, value AS state
|
|
74
|
-
FROM house_meta FINAL WHERE key LIKE 'share:%' ORDER BY key
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
`granted …` = a live read window (`/mem:share`); `revoked …` = closed. If the caller IS
|
|
78
|
-
privileged, prefer the authoritative form:
|
|
79
|
-
`SELECT user_name, groupUniqArray(access_type) FROM system.grants WHERE database = '<your-db>' AND user_name != '<your-user>' GROUP BY user_name`
|
|
80
|
-
— try it first, fall back to the record on refusal.
|
|
81
|
-
|
|
82
|
-
**4. Every user on the server** — usually admin-only; try it, and if refused say
|
|
83
|
-
"(full user list needs admin — showing only what this credential can see)":
|
|
84
|
-
|
|
85
|
-
```sql
|
|
86
|
-
SELECT name FROM system.users ORDER BY name
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## Presenting it
|
|
90
|
-
|
|
91
|
-
Four short sections in that order, each with its one-line meaning ("2 machines ship into
|
|
92
|
-
your house", "you can read polat's memory", "yigit can read yours — read-only", …).
|
|
93
|
-
Empty section three means "no shares made through /mem:share" — and ONLY that. The
|
|
94
|
-
record cannot see an admin-issued grant, so never promise "nobody can read your memory"
|
|
95
|
-
from an empty ledger; say "no shares recorded through this skill — the authoritative
|
|
96
|
-
check is the admin's system.grants query" and print it. Point at `/mem:share <user>` /
|
|
97
|
-
`/mem:share revoke <user>` for changes.
|