memhouse 0.3.1 → 0.3.2
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 +19 -0
- package/editors/zed.js +55 -6
- package/mem-house/delivery/AGENT-INSTALL.md +18 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,6 +42,25 @@ install scripts by default, so without the flag those five read nothing and you
|
|
|
42
42
|
silently ship a partial history. `memhouse discover` and `memhouse doctor` both
|
|
43
43
|
say so when the binding is missing.
|
|
44
44
|
|
|
45
|
+
If that install fails with `EACCES`, `sudo` is the right answer for only one of the
|
|
46
|
+
two causes, and the thing that tells them apart is **who owns the prefix root** —
|
|
47
|
+
not the path, and not the failing file. The path proves nothing: Homebrew's prefix
|
|
48
|
+
is `/usr/local` on Intel and `/opt/homebrew` on Apple Silicon, and is yours in both
|
|
49
|
+
cases. The failing file proves nothing either: an earlier `sudo npm` leaves
|
|
50
|
+
root-owned files *inside* a prefix that is still yours.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
ls -ld "$(npm prefix -g)" # the prefix ROOT — this is the deciding one
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- **Prefix root owned by `root`** — a genuinely system-managed Node (distro
|
|
57
|
+
packages under `/usr`). Re-run with `sudo`.
|
|
58
|
+
- **Prefix root owned by you** — the prefix is yours (Homebrew, fnm, nvm, volta),
|
|
59
|
+
so whatever root-owned file npm tripped on is a stray from an earlier `sudo npm`.
|
|
60
|
+
Another `sudo` adds more of them. Repair just that path:
|
|
61
|
+
`sudo chown -R "$(id -u):$(id -g)" <the path npm named>`. The same applies to the
|
|
62
|
+
cache (`~/.npm`).
|
|
63
|
+
|
|
45
64
|
To try it without installing, npx takes the same flag — it has to come before the
|
|
46
65
|
package name:
|
|
47
66
|
|
package/editors/zed.js
CHANGED
|
@@ -81,6 +81,44 @@ function queryDb(sql) {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
// Zed's `threads` schema varies by version: `worktree_branch` exists in some builds
|
|
85
|
+
// and not others, and older builds lack `created_at`. Naming a column that is not
|
|
86
|
+
// there fails the WHOLE query with "no such column", which cost every Zed thread on
|
|
87
|
+
// this machine — silently, until the adapter started reporting. So ask the table what
|
|
88
|
+
// it has rather than assuming. Cached: the schema cannot change while we scan.
|
|
89
|
+
let threadColumns = null;
|
|
90
|
+
function getThreadColumns() {
|
|
91
|
+
if (threadColumns) return threadColumns;
|
|
92
|
+
if (!fs.existsSync(THREADS_DB)) return new Set();
|
|
93
|
+
try {
|
|
94
|
+
const db = new Database(THREADS_DB, { readonly: true });
|
|
95
|
+
const cols = db.prepare('PRAGMA table_info(threads)').all().map((r) => r.name);
|
|
96
|
+
db.close();
|
|
97
|
+
// PRAGMA on a missing or renamed table SUCCEEDS with zero rows rather than
|
|
98
|
+
// throwing. Left unreported, that would cache an empty set, return no sessions,
|
|
99
|
+
// and look exactly like an unused Zed install — the same silent whole-adapter
|
|
100
|
+
// drop this function exists to end. Do not cache it either: the next scan should
|
|
101
|
+
// look again rather than inherit the verdict.
|
|
102
|
+
if (cols.length === 0) {
|
|
103
|
+
adapterErrors.record('zed', new Error('threads table missing or unreadable — incompatible Zed schema'), THREADS_DB);
|
|
104
|
+
return new Set();
|
|
105
|
+
}
|
|
106
|
+
threadColumns = new Set(cols);
|
|
107
|
+
return threadColumns;
|
|
108
|
+
} catch (e) {
|
|
109
|
+
adapterErrors.record('zed', e, THREADS_DB);
|
|
110
|
+
return new Set();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// index.js calls this between passes of a long-running `ship --loop`. Without it the
|
|
115
|
+
// column set would be fixed for the life of the process, so a Zed upgrade mid-run
|
|
116
|
+
// would keep querying a column that no longer exists — or keep ignoring one newly
|
|
117
|
+
// added — until someone restarted the shipper.
|
|
118
|
+
function resetCache() {
|
|
119
|
+
threadColumns = null;
|
|
120
|
+
}
|
|
121
|
+
|
|
84
122
|
function queryBlob(id) {
|
|
85
123
|
if (!fs.existsSync(THREADS_DB)) return null;
|
|
86
124
|
try {
|
|
@@ -103,22 +141,33 @@ function queryBlob(id) {
|
|
|
103
141
|
const name = 'zed';
|
|
104
142
|
|
|
105
143
|
function getChats() {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
144
|
+
const cols = getThreadColumns();
|
|
145
|
+
if (cols.size === 0) return [];
|
|
146
|
+
|
|
147
|
+
// Only these are relied on. Anything else is taken when the build provides it.
|
|
148
|
+
const select = ['id', 'summary', 'updated_at', 'data_type', 'length(data) as data_size', 'parent_id'];
|
|
149
|
+
const hasBranch = cols.has('worktree_branch');
|
|
150
|
+
const hasCreated = cols.has('created_at');
|
|
151
|
+
if (hasBranch) select.push('worktree_branch');
|
|
152
|
+
if (hasCreated) select.push('created_at');
|
|
153
|
+
|
|
154
|
+
const rows = queryDb(`SELECT ${select.join(', ')} FROM threads ORDER BY updated_at DESC`);
|
|
109
155
|
|
|
110
156
|
return rows.map(row => ({
|
|
111
157
|
source: 'zed',
|
|
112
158
|
composerId: row.id,
|
|
113
159
|
name: row.summary || null,
|
|
114
|
-
|
|
160
|
+
// created_at when the build has it. Falling back to updated_at is not a
|
|
161
|
+
// creation time — it just keeps the field non-null on builds that lack it.
|
|
162
|
+
createdAt: (hasCreated && row.created_at) ? new Date(row.created_at).getTime()
|
|
163
|
+
: (row.updated_at ? new Date(row.updated_at).getTime() : null),
|
|
115
164
|
lastUpdatedAt: row.updated_at ? new Date(row.updated_at).getTime() : null,
|
|
116
165
|
mode: 'thread',
|
|
117
166
|
folder: null,
|
|
118
167
|
encrypted: false,
|
|
119
168
|
bubbleCount: 0,
|
|
120
169
|
_dataType: row.data_type,
|
|
121
|
-
_gitBranch: row.worktree_branch,
|
|
170
|
+
_gitBranch: hasBranch ? row.worktree_branch : null,
|
|
122
171
|
}));
|
|
123
172
|
}
|
|
124
173
|
|
|
@@ -226,4 +275,4 @@ function getMCPServers() {
|
|
|
226
275
|
return results;
|
|
227
276
|
}
|
|
228
277
|
|
|
229
|
-
module.exports = { name, labels, getChats, getMessages, getMCPServers };
|
|
278
|
+
module.exports = { name, labels, getChats, getMessages, getMCPServers, resetCache };
|
|
@@ -17,6 +17,24 @@ the install script that builds the native binding. Without it those five silentl
|
|
|
17
17
|
return zero sessions and you ship a partial history. Verify with step 4 —
|
|
18
18
|
`memhouse discover` names any adapter it had to skip.
|
|
19
19
|
|
|
20
|
+
On `EACCES`, decide by **who owns the prefix root**. Not the path — Homebrew's
|
|
21
|
+
prefix is `/usr/local` on Intel and `/opt/homebrew` on Apple Silicon and is
|
|
22
|
+
user-owned in both. Not the failing file either — an earlier `sudo npm` leaves
|
|
23
|
+
root-owned files inside a prefix that is still the user's, and judging by those
|
|
24
|
+
misreads it as system-managed.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
ls -ld "$(npm prefix -g)" # the prefix ROOT decides
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Prefix root owned by `root` → a system-managed Node; re-run as
|
|
31
|
+
`sudo npm install -g memhouse --allow-scripts=better-sqlite3`.
|
|
32
|
+
|
|
33
|
+
Prefix root owned by the current user → the prefix is theirs (Homebrew, fnm, nvm,
|
|
34
|
+
volta), so the root-owned file npm tripped on is a stray from an earlier `sudo npm`
|
|
35
|
+
and another `sudo` adds more. Repair that path instead:
|
|
36
|
+
`sudo chown -R "$(id -u):$(id -g)" <path npm named>` (same for `~/.npm`).
|
|
37
|
+
|
|
20
38
|
From a checkout instead (contributors): `npm install --no-audit --no-fund` in the
|
|
21
39
|
repo root — its `allowScripts` field already covers the binding — then substitute
|
|
22
40
|
`node bin/memhouse.js` for `memhouse` below.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memhouse",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "memhouse — agent conversation memory across 17 editors: parse-on-client shippers, a typed ClickHouse store, kernel-agency install, and the agentlytics dashboard",
|
|
5
5
|
"main": "bin/memhouse.js",
|
|
6
6
|
"bin": {
|