@massu/core 1.16.2 → 1.16.3

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.
@@ -49,16 +49,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
49
49
  ));
50
50
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
51
51
 
52
- // src/lib/memory-path.ts
53
- function encodeMemoryDirName(projectRoot) {
54
- return projectRoot.replace(/\//g, "-");
55
- }
56
- var init_memory_path = __esm({
57
- "src/lib/memory-path.ts"() {
58
- "use strict";
59
- }
60
- });
61
-
62
52
  // src/credentials.ts
63
53
  import { homedir } from "os";
64
54
  import { resolve } from "path";
@@ -127,6 +117,345 @@ var init_credentials = __esm({
127
117
  }
128
118
  });
129
119
 
120
+ // src/lib/fileLock.ts
121
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
122
+ import { dirname } from "path";
123
+ import * as lockfile from "proper-lockfile";
124
+ function readLockHolderPid(lockPath) {
125
+ try {
126
+ const raw = readFileSync2(`${lockPath}.pid`, "utf-8").trim();
127
+ const pid = Number.parseInt(raw, 10);
128
+ if (!Number.isFinite(pid) || pid <= 0) return null;
129
+ return pid;
130
+ } catch {
131
+ return null;
132
+ }
133
+ }
134
+ function busyWaitSync(ms) {
135
+ if (typeof SharedArrayBuffer === "undefined" || typeof Atomics === "undefined") {
136
+ throw new Error(
137
+ `withFileLockSync requires SharedArrayBuffer + Atomics for its retry-loop wait. This Node runtime does not provide them \u2014 refusing to fall back to a CPU spinloop. If you hit this in a sandboxed serverless env, the fix is to perform the lock-protected operation in a host runtime that supports Atomics.`
138
+ );
139
+ }
140
+ const sab = new SharedArrayBuffer(4);
141
+ const view = new Int32Array(sab);
142
+ Atomics.wait(view, 0, 0, ms);
143
+ }
144
+ function withFileLockSync(lockPath, fn, opts = {}) {
145
+ mkdirSync2(dirname(lockPath), { recursive: true });
146
+ const staleMs = opts.staleMs ?? 3e4;
147
+ const blockMs = opts.retries === 0 ? 0 : opts.blockMs ?? 3e4;
148
+ const pollIntervalMs = opts.pollIntervalMs ?? 100;
149
+ const now = opts.now ?? Date.now;
150
+ const sleep = opts.sleep ?? busyWaitSync;
151
+ const makeBusyError = opts.errorFactory ?? ((path, pid, retrySeconds, code) => new FileLockBusyError(path, pid, retrySeconds, code));
152
+ let release = null;
153
+ const deadline = now() + blockMs;
154
+ for (; ; ) {
155
+ try {
156
+ release = lockfile.lockSync(lockPath, {
157
+ stale: staleMs,
158
+ retries: 0,
159
+ realpath: false
160
+ });
161
+ try {
162
+ writeFileSync2(`${lockPath}.pid`, String(process.pid), "utf-8");
163
+ } catch {
164
+ }
165
+ break;
166
+ } catch (err) {
167
+ const e = err;
168
+ const code = e.code;
169
+ if (code !== "ELOCKED" && code !== "EBUSY") {
170
+ throw err;
171
+ }
172
+ if (now() >= deadline) {
173
+ const holderPid = readLockHolderPid(lockPath);
174
+ const remainingMs = Math.max(0, deadline - now());
175
+ const retryAfterSeconds = blockMs === 0 ? Math.round(staleMs / 1e3) : Math.round(remainingMs / 1e3);
176
+ throw makeBusyError(lockPath, holderPid, retryAfterSeconds, code);
177
+ }
178
+ sleep(pollIntervalMs);
179
+ }
180
+ }
181
+ try {
182
+ return fn();
183
+ } finally {
184
+ try {
185
+ if (release) release();
186
+ } catch {
187
+ }
188
+ try {
189
+ rmSync2(`${lockPath}.pid`, { force: true });
190
+ } catch {
191
+ }
192
+ }
193
+ }
194
+ var FileLockBusyError;
195
+ var init_fileLock = __esm({
196
+ "src/lib/fileLock.ts"() {
197
+ "use strict";
198
+ FileLockBusyError = class extends Error {
199
+ constructor(lockPath, holderPid, retryAfterSeconds, causeCode) {
200
+ const pidPart = holderPid != null ? `(PID=${holderPid})` : "(PID=unknown)";
201
+ super(`File lock at ${lockPath} held by another process ${pidPart} \u2014 try again in ${retryAfterSeconds}s`);
202
+ this.lockPath = lockPath;
203
+ this.holderPid = holderPid;
204
+ this.retryAfterSeconds = retryAfterSeconds;
205
+ this.causeCode = causeCode;
206
+ this.name = "FileLockBusyError";
207
+ }
208
+ lockPath;
209
+ holderPid;
210
+ retryAfterSeconds;
211
+ causeCode;
212
+ };
213
+ }
214
+ });
215
+
216
+ // src/lib/sqlite-loader.ts
217
+ import { createRequire } from "module";
218
+ import { spawnSync } from "child_process";
219
+ import { accessSync, appendFileSync, chmodSync as chmodSync2, constants as fsConstants, existsSync as existsSync2, mkdirSync as mkdirSync3 } from "fs";
220
+ import { dirname as dirname2, join } from "path";
221
+ function isNativeAbiError(err) {
222
+ const code = err?.code;
223
+ if (code === "ERR_DLOPEN_FAILED") return true;
224
+ const msg = err instanceof Error ? err.message : String(err);
225
+ return /NODE_MODULE_VERSION/.test(msg) || /was compiled against a different Node\.js version/.test(msg) || /ERR_DLOPEN_FAILED/.test(msg) || /\.node\b/.test(msg) && /dlopen|invalid ELF|mach-o|image not found|no such file|not a valid Win32/i.test(msg);
226
+ }
227
+ function loadBetterSqlite3(opts = {}) {
228
+ if (_testCtor) return _testCtor;
229
+ if (opts.fresh) bustNativeCache();
230
+ return req("better-sqlite3");
231
+ }
232
+ function bustNativeCache() {
233
+ try {
234
+ const cache = req.cache;
235
+ if (!cache) return;
236
+ for (const key of Object.keys(cache)) {
237
+ if (/better[-_]sqlite3|better_sqlite3\.node|[\\/]bindings[\\/]/.test(key)) {
238
+ delete cache[key];
239
+ }
240
+ }
241
+ } catch {
242
+ }
243
+ }
244
+ function openDatabase(dbPath, opts = {}) {
245
+ const { selfHeal: selfHealOpt = true, ...ctorOpts } = opts;
246
+ const selfHeal = selfHealOpt && process.env.MASSU_HOOK_RUNTIME !== "1";
247
+ const Ctor = loadBetterSqlite3();
248
+ try {
249
+ return new Ctor(dbPath, ctorOpts);
250
+ } catch (err) {
251
+ if (!isNativeAbiError(err)) {
252
+ throw err;
253
+ }
254
+ if (!selfHeal) {
255
+ recordHealEvent({ phase: "skipped", reason: "self-heal-disabled", abiTo: process.versions.modules });
256
+ throw new MemoryEngineUnusableError("abi-mismatch", detailOf(err));
257
+ }
258
+ const result = (_testHeal ?? attemptNativeHeal)(err);
259
+ if (!result.healed && !result.contended) {
260
+ throw new MemoryEngineUnusableError(result.reason ?? "heal-failed", result.detail ?? detailOf(err));
261
+ }
262
+ try {
263
+ const FreshCtor = loadBetterSqlite3({ fresh: true });
264
+ return new FreshCtor(dbPath, ctorOpts);
265
+ } catch (retryErr) {
266
+ throw new MemoryEngineUnusableError("heal-failed", detailOf(retryErr));
267
+ }
268
+ }
269
+ }
270
+ function attemptNativeHeal(err) {
271
+ const start = Date.now();
272
+ const abiTo = process.versions.modules;
273
+ const abiFrom = parseAbiFrom(err);
274
+ let pkgDir;
275
+ try {
276
+ pkgDir = dirname2(req.resolve("better-sqlite3/package.json"));
277
+ } catch {
278
+ recordHealEvent({ phase: "skipped", reason: "not-resolvable", abiFrom, abiTo });
279
+ return { healed: false, reason: "missing", abiFrom, abiTo, detail: "better-sqlite3 not resolvable" };
280
+ }
281
+ if (!isWritable(pkgDir)) {
282
+ recordHealEvent({ phase: "skipped", reason: "dir-not-writable", abiFrom, abiTo });
283
+ return { healed: false, reason: "heal-failed", abiFrom, abiTo, detail: `install dir not writable: ${pkgDir}` };
284
+ }
285
+ recordHealEvent({ phase: "attempt", reason: "abi-mismatch", abiFrom, abiTo });
286
+ try {
287
+ return withFileLockSync(
288
+ join(credentialsDir(), "native-heal.lock"),
289
+ () => runRebuild(pkgDir, abiFrom, abiTo, start),
290
+ { blockMs: 6e4, staleMs: 3e5 }
291
+ );
292
+ } catch (lockErr) {
293
+ const detail = lockErr instanceof Error ? lockErr.message : String(lockErr);
294
+ recordHealEvent({ phase: "failed", reason: "heal-failed", abiFrom, abiTo, detail: `lock: ${detail}` });
295
+ return { healed: false, contended: true, reason: "heal-failed", abiFrom, abiTo, detail: `heal lock contended: ${detail}` };
296
+ }
297
+ }
298
+ function runRebuild(pkgDir, abiFrom, abiTo, start) {
299
+ try {
300
+ const FreshCtor = loadBetterSqlite3({ fresh: true });
301
+ new FreshCtor(":memory:").close();
302
+ const res2 = {
303
+ healed: true,
304
+ abiFrom,
305
+ abiTo,
306
+ durationMs: Date.now() - start,
307
+ detail: "already healed by a concurrent process"
308
+ };
309
+ recordHealEvent({ phase: "success", reason: "already-healed", abiFrom, abiTo, durationMs: res2.durationMs });
310
+ return res2;
311
+ } catch (probeErr) {
312
+ if (!isNativeAbiError(probeErr)) {
313
+ return { healed: false, reason: "heal-failed", abiFrom, abiTo, durationMs: Date.now() - start, detail: detailOf(probeErr) };
314
+ }
315
+ }
316
+ const prebuildBin = resolveLocalBin(pkgDir, "prebuild-install");
317
+ if (prebuildBin) {
318
+ const r = spawnSync(process.execPath, [prebuildBin], {
319
+ cwd: pkgDir,
320
+ encoding: "utf-8",
321
+ timeout: 12e4
322
+ });
323
+ if (r.status === 0) {
324
+ const res2 = { healed: true, method: "prebuild-install", abiFrom, abiTo, durationMs: Date.now() - start };
325
+ recordHealEvent({ phase: "success", reason: "abi-mismatch", ...res2 });
326
+ return res2;
327
+ }
328
+ }
329
+ const gypBin = resolveNodeGypBin();
330
+ if (gypBin && hasCompiler()) {
331
+ const r = spawnSync(process.execPath, [gypBin, "rebuild", "--release"], {
332
+ cwd: pkgDir,
333
+ encoding: "utf-8",
334
+ timeout: 3e5
335
+ });
336
+ if (r.status === 0) {
337
+ const res2 = { healed: true, method: "node-gyp", abiFrom, abiTo, durationMs: Date.now() - start };
338
+ recordHealEvent({ phase: "success", reason: "abi-mismatch", ...res2 });
339
+ return res2;
340
+ }
341
+ }
342
+ const res = {
343
+ healed: false,
344
+ reason: "heal-failed",
345
+ abiFrom,
346
+ abiTo,
347
+ durationMs: Date.now() - start,
348
+ detail: prebuildBin ? "prebuild-install failed; node-gyp fallback unavailable or failed" : "no prebuild-install bin resolvable"
349
+ };
350
+ recordHealEvent({ phase: "failed", reason: "heal-failed", abiFrom, abiTo, durationMs: res.durationMs });
351
+ return res;
352
+ }
353
+ function recordHealEvent(event) {
354
+ try {
355
+ const rec = {
356
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
357
+ node: process.versions.node,
358
+ platform: process.platform,
359
+ arch: process.arch,
360
+ ...event
361
+ };
362
+ const dir = credentialsDir();
363
+ mkdirSync3(dir, { recursive: true });
364
+ const file = join(dir, "native-heal-events.jsonl");
365
+ appendFileSync(file, JSON.stringify(rec) + "\n", "utf-8");
366
+ try {
367
+ chmodSync2(file, 384);
368
+ } catch {
369
+ }
370
+ } catch {
371
+ }
372
+ }
373
+ function parseAbiFrom(err) {
374
+ const msg = err instanceof Error ? err.message : String(err ?? "");
375
+ const m = /NODE_MODULE_VERSION (\d+)/.exec(msg);
376
+ if (m && /^\d+$/.test(m[1])) return m[1];
377
+ return void 0;
378
+ }
379
+ function detailOf(err) {
380
+ const msg = err instanceof Error ? err.message : String(err);
381
+ return msg.slice(0, 300);
382
+ }
383
+ function isWritable(dir) {
384
+ try {
385
+ accessSync(dir, fsConstants.W_OK);
386
+ return true;
387
+ } catch {
388
+ return false;
389
+ }
390
+ }
391
+ function resolveLocalBin(pkgDir, name) {
392
+ const candidates = [
393
+ join(pkgDir, "node_modules", ".bin", name),
394
+ // nested install
395
+ join(pkgDir, "..", ".bin", name),
396
+ // hoisted (node_modules/.bin)
397
+ join(pkgDir, "..", "..", "node_modules", ".bin", name)
398
+ // workspace hoist
399
+ ];
400
+ for (const c of candidates) {
401
+ if (existsSync2(c)) return c;
402
+ }
403
+ return void 0;
404
+ }
405
+ function resolveNodeGypBin() {
406
+ try {
407
+ return req.resolve("node-gyp/bin/node-gyp.js");
408
+ } catch {
409
+ return void 0;
410
+ }
411
+ }
412
+ function hasCompiler() {
413
+ for (const cc of ["cc", "clang", "gcc"]) {
414
+ try {
415
+ const r = spawnSync(cc, ["--version"], { encoding: "utf-8", timeout: 5e3 });
416
+ if (r.status === 0) return true;
417
+ } catch {
418
+ }
419
+ }
420
+ return false;
421
+ }
422
+ var req, NATIVE_DB_REMEDY, MemoryEngineUnusableError, _testCtor, _testHeal;
423
+ var init_sqlite_loader = __esm({
424
+ "src/lib/sqlite-loader.ts"() {
425
+ "use strict";
426
+ init_credentials();
427
+ init_fileLock();
428
+ req = createRequire(import.meta.url);
429
+ NATIVE_DB_REMEDY = "Run 'massu heal' to rebuild the database engine for your Node version, then restart your MCP client / Claude Code.";
430
+ MemoryEngineUnusableError = class extends Error {
431
+ reason;
432
+ remedy;
433
+ detail;
434
+ constructor(reason, detail) {
435
+ super(
436
+ `Massu memory engine is unusable (${reason}). ${NATIVE_DB_REMEDY}` + (detail ? ` [${detail}]` : "")
437
+ );
438
+ this.name = "MemoryEngineUnusableError";
439
+ this.reason = reason;
440
+ this.remedy = NATIVE_DB_REMEDY;
441
+ this.detail = detail;
442
+ }
443
+ };
444
+ _testCtor = null;
445
+ _testHeal = null;
446
+ }
447
+ });
448
+
449
+ // src/lib/memory-path.ts
450
+ function encodeMemoryDirName(projectRoot) {
451
+ return projectRoot.replace(/\//g, "-");
452
+ }
453
+ var init_memory_path = __esm({
454
+ "src/lib/memory-path.ts"() {
455
+ "use strict";
456
+ }
457
+ });
458
+
130
459
  // src/config-memory-schema.ts
131
460
  import { z } from "zod";
132
461
  var MemoryConfigSchema;
@@ -266,8 +595,8 @@ var init_config_memory_schema = __esm({
266
595
  });
267
596
 
268
597
  // src/config.ts
269
- import { resolve as resolve2, dirname } from "path";
270
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
598
+ import { resolve as resolve2, dirname as dirname3 } from "path";
599
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
271
600
  import { homedir as homedir2 } from "os";
272
601
  import { parse as parseYaml } from "yaml";
273
602
  import { z as z2 } from "zod";
@@ -275,22 +604,22 @@ function findProjectRoot() {
275
604
  const cwd = process.cwd();
276
605
  let dir = cwd;
277
606
  while (true) {
278
- if (existsSync2(resolve2(dir, "massu.config.yaml"))) {
607
+ if (existsSync3(resolve2(dir, "massu.config.yaml"))) {
279
608
  return dir;
280
609
  }
281
- const parent = dirname(dir);
610
+ const parent = dirname3(dir);
282
611
  if (parent === dir) break;
283
612
  dir = parent;
284
613
  }
285
614
  dir = cwd;
286
615
  while (true) {
287
- if (existsSync2(resolve2(dir, "package.json"))) {
616
+ if (existsSync3(resolve2(dir, "package.json"))) {
288
617
  return dir;
289
618
  }
290
- if (existsSync2(resolve2(dir, ".git"))) {
619
+ if (existsSync3(resolve2(dir, ".git"))) {
291
620
  return dir;
292
621
  }
293
- const parent = dirname(dir);
622
+ const parent = dirname3(dir);
294
623
  if (parent === dir) break;
295
624
  dir = parent;
296
625
  }
@@ -307,8 +636,8 @@ function getConfig() {
307
636
  const root = getProjectRoot();
308
637
  const configPath = resolve2(root, "massu.config.yaml");
309
638
  let rawYaml = {};
310
- if (existsSync2(configPath)) {
311
- const content = readFileSync2(configPath, "utf-8");
639
+ if (existsSync3(configPath)) {
640
+ const content = readFileSync3(configPath, "utf-8");
312
641
  rawYaml = parseYaml(content) ?? {};
313
642
  }
314
643
  const result = RawConfigSchema.safeParse(rawYaml);
@@ -389,9 +718,13 @@ Hint: run \`massu config refresh\` to regenerate a valid config or fix the liste
389
718
  const resolvedEndpoint = resolveEndpoint({ configEndpoint: _config.cloud?.endpoint });
390
719
  if (resolvedKey.apiKey) {
391
720
  _config.cloud = {
392
- enabled: true,
393
721
  sync: { memory: true, analytics: true, audit: true },
394
722
  ..._config.cloud,
723
+ // Spread FIRST, then decide `enabled`, so a workspace that declares a `cloud:`
724
+ // block only to tune `requestTimeoutMs` does not disable its own sync. An
725
+ // EXPLICIT `enabled: false` is still honoured; `undefined` (not stated) means
726
+ // "a key resolved, so turn it on". (plan-2026-07-20-cloud-sync-timeout)
727
+ enabled: _config.cloud?.enabled ?? true,
395
728
  apiKey: resolvedKey.apiKey,
396
729
  endpoint: resolvedEndpoint
397
730
  };
@@ -611,9 +944,22 @@ var init_config = __esm({
611
944
  })).default([])
612
945
  }).optional();
613
946
  CloudConfigSchema = z2.object({
614
- enabled: z2.boolean().default(false),
947
+ // OPTIONAL, not `.default(false)`. A zod default is indistinguishable from an
948
+ // explicit value once parsed, so `.default(false)` meant that merely declaring a
949
+ // `cloud:` block (to set any OTHER key) silently produced `enabled: false`, which
950
+ // then overrode the `enabled: true` auto-enable below via object spread — turning
951
+ // cloud sync OFF as a side effect of tuning it. `undefined` now means "not stated",
952
+ // and the auto-enable preserves it. (plan-2026-07-20-cloud-sync-timeout)
953
+ enabled: z2.boolean().optional(),
615
954
  apiKey: z2.string().optional(),
616
955
  endpoint: z2.string().optional(),
956
+ // Per-request POST budget for the `/sync` ingest. cloud-sync.ts reads this
957
+ // (`(cloud as { requestTimeoutMs?: number }).requestTimeoutMs`) but it was ABSENT
958
+ // from this schema, and zod strips unknown keys — so the knob was unreachable from
959
+ // massu.config.yaml and the default could never be tuned. Measured 2026-07-20: a
960
+ // 423-observation payload takes ~9.2s against the live ingest. Capped at
961
+ // SYNC_DEADLINE_MS (20s) since the overall deadline clamps each attempt anyway.
962
+ requestTimeoutMs: z2.number().int().positive().max(2e4).optional(),
617
963
  sync: z2.object({
618
964
  memory: z2.boolean().default(true),
619
965
  analytics: z2.boolean().default(true),
@@ -850,27 +1196,26 @@ var init_memory_vector = __esm({
850
1196
  });
851
1197
 
852
1198
  // src/db-backup.ts
853
- import Database from "better-sqlite3";
854
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync, statSync, unlinkSync, copyFileSync, rmSync as rmSync2 } from "fs";
855
- import { resolve as resolve3, join, basename, dirname as dirname2 } from "path";
1199
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readdirSync, statSync, unlinkSync, copyFileSync, rmSync as rmSync3 } from "fs";
1200
+ import { resolve as resolve3, join as join2, basename, dirname as dirname4 } from "path";
856
1201
  import { homedir as homedir3 } from "os";
857
1202
  function dbBackupsRoot(home = homedir3()) {
858
1203
  return resolve3(home, ".massu", "db-backups");
859
1204
  }
860
1205
  function projectBackupDir(projectRoot, home = homedir3()) {
861
1206
  const slug = basename(projectRoot).replace(/[^A-Za-z0-9._-]/g, "_") || "project";
862
- return join(dbBackupsRoot(home), slug);
1207
+ return join2(dbBackupsRoot(home), slug);
863
1208
  }
864
1209
  function backupStamp(nowMs) {
865
1210
  return new Date(nowMs).toISOString().replace(/[:.]/g, "-");
866
1211
  }
867
1212
  function listDbBackups(projectRoot, home = homedir3()) {
868
1213
  const dir = projectBackupDir(projectRoot, home);
869
- if (!existsSync3(dir)) return [];
1214
+ if (!existsSync4(dir)) return [];
870
1215
  const out = [];
871
1216
  for (const f of readdirSync(dir)) {
872
1217
  if (!f.endsWith(".db")) continue;
873
- const p = join(dir, f);
1218
+ const p = join2(dir, f);
874
1219
  const st = statSync(p);
875
1220
  const db = f.replace(/-\d{4}-\d{2}-\d{2}T.*$/, "");
876
1221
  out.push({ db, path: p, bytes: st.size, mtimeMs: st.mtimeMs });
@@ -883,13 +1228,13 @@ function hasFreshDbBackup(projectRoot, dbPath, nowMs = Date.now(), home = homedi
883
1228
  if (backups.length === 0) return false;
884
1229
  const newest = backups[0];
885
1230
  if (nowMs - newest.mtimeMs > FRESH_WINDOW_MS) return false;
886
- if (existsSync3(dbPath) && statSync(dbPath).mtimeMs > newest.mtimeMs) return false;
1231
+ if (existsSync4(dbPath) && statSync(dbPath).mtimeMs > newest.mtimeMs) return false;
887
1232
  return true;
888
1233
  }
889
1234
  function integrityOk(dbPath) {
890
1235
  let db = null;
891
1236
  try {
892
- db = new Database(dbPath, { readonly: true });
1237
+ db = openDatabase(dbPath, { readonly: true });
893
1238
  const rows = db.pragma("integrity_check");
894
1239
  return rows.length === 1 && rows[0].integrity_check === "ok";
895
1240
  } catch {
@@ -902,16 +1247,16 @@ function integrityOk(dbPath) {
902
1247
  }
903
1248
  }
904
1249
  function backupDb(projectRoot, dbPath, nowMs = Date.now(), home = homedir3()) {
905
- if (!existsSync3(dbPath)) {
1250
+ if (!existsSync4(dbPath)) {
906
1251
  throw new DbBackupError(`cannot back up a database that does not exist: ${dbPath}`);
907
1252
  }
908
1253
  const dir = projectBackupDir(projectRoot, home);
909
- mkdirSync2(dir, { recursive: true });
1254
+ mkdirSync4(dir, { recursive: true });
910
1255
  const name = basename(dbPath, ".db");
911
- const dest = join(dir, `${name}-${backupStamp(nowMs)}.db`);
1256
+ const dest = join2(dir, `${name}-${backupStamp(nowMs)}.db`);
912
1257
  let src = null;
913
1258
  try {
914
- src = new Database(dbPath, { readonly: true });
1259
+ src = openDatabase(dbPath, { readonly: true });
915
1260
  src.exec(`VACUUM INTO '${dest.replace(/'/g, "''")}'`);
916
1261
  } catch (err) {
917
1262
  throw new DbBackupError(
@@ -950,7 +1295,7 @@ function pruneDbBackups(projectRoot, dbName, keep = DEFAULT_RETENTION, home = ho
950
1295
  }
951
1296
  function backupBeforeSchemaChange(projectRoot, dbPath, onError, nowMs = Date.now(), home = homedir3()) {
952
1297
  try {
953
- if (!existsSync3(dbPath)) return null;
1298
+ if (!existsSync4(dbPath)) return null;
954
1299
  if (hasFreshDbBackup(projectRoot, dbPath, nowMs, home)) return null;
955
1300
  return backupDb(projectRoot, dbPath, nowMs, home);
956
1301
  } catch (err) {
@@ -962,6 +1307,7 @@ var DEFAULT_RETENTION, FRESH_WINDOW_MS, DbBackupError;
962
1307
  var init_db_backup = __esm({
963
1308
  "src/db-backup.ts"() {
964
1309
  "use strict";
1310
+ init_sqlite_loader();
965
1311
  DEFAULT_RETENTION = 5;
966
1312
  FRESH_WINDOW_MS = 24 * 60 * 60 * 1e3;
967
1313
  DbBackupError = class extends Error {
@@ -1074,21 +1420,21 @@ var init_rule_candidate_store = __esm({
1074
1420
  });
1075
1421
 
1076
1422
  // src/hooks/lib/hook-failure-signal.ts
1077
- import { appendFileSync, mkdirSync as mkdirSync3, existsSync as existsSync4 } from "fs";
1078
- import { join as join2, dirname as dirname3 } from "path";
1423
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync5, existsSync as existsSync5 } from "fs";
1424
+ import { join as join3, dirname as dirname5 } from "path";
1079
1425
  function resolveFailureLogPath() {
1080
1426
  const explicit = process.env.MASSU_HOOK_FAILURE_LOG;
1081
1427
  if (explicit) return explicit;
1082
1428
  let dir = process.cwd();
1083
1429
  for (let i = 0; i < 12; i++) {
1084
- if (existsSync4(join2(dir, ".massu")) || existsSync4(join2(dir, "massu.config.yaml"))) {
1085
- return join2(dir, ".massu", "hook-failures.jsonl");
1430
+ if (existsSync5(join3(dir, ".massu")) || existsSync5(join3(dir, "massu.config.yaml"))) {
1431
+ return join3(dir, ".massu", "hook-failures.jsonl");
1086
1432
  }
1087
- const parent = dirname3(dir);
1433
+ const parent = dirname5(dir);
1088
1434
  if (parent === dir) break;
1089
1435
  dir = parent;
1090
1436
  }
1091
- return join2(process.cwd(), ".massu", "hook-failures.jsonl");
1437
+ return join3(process.cwd(), ".massu", "hook-failures.jsonl");
1092
1438
  }
1093
1439
  function recordHookFailure(hook, error, context) {
1094
1440
  const record = {
@@ -1101,8 +1447,8 @@ function recordHookFailure(hook, error, context) {
1101
1447
  let wroteSomething = false;
1102
1448
  try {
1103
1449
  const path = resolveFailureLogPath();
1104
- mkdirSync3(dirname3(path), { recursive: true });
1105
- appendFileSync(path, JSON.stringify(record) + "\n", "utf-8");
1450
+ mkdirSync5(dirname5(path), { recursive: true });
1451
+ appendFileSync2(path, JSON.stringify(record) + "\n", "utf-8");
1106
1452
  wroteSomething = true;
1107
1453
  } catch {
1108
1454
  }
@@ -1145,9 +1491,9 @@ var init_hook_failure_signal = __esm({
1145
1491
  });
1146
1492
 
1147
1493
  // src/memory-embedder-tokenizer.ts
1148
- import { readFileSync as readFileSync3 } from "fs";
1494
+ import { readFileSync as readFileSync4 } from "fs";
1149
1495
  function loadVocab(vocabPath) {
1150
- const lines = readFileSync3(vocabPath, "utf-8").split("\n");
1496
+ const lines = readFileSync4(vocabPath, "utf-8").split("\n");
1151
1497
  const vocab = /* @__PURE__ */ new Map();
1152
1498
  for (let i = 0; i < lines.length; i++) {
1153
1499
  const tok = lines[i].replace(/\r$/, "");
@@ -1267,9 +1613,9 @@ var init_memory_embedder_tokenizer = __esm({
1267
1613
 
1268
1614
  // src/memory-embedder.ts
1269
1615
  import { fileURLToPath } from "url";
1270
- import { dirname as dirname4, join as join3 } from "path";
1271
- import { existsSync as existsSync5 } from "fs";
1272
- import { createRequire } from "module";
1616
+ import { dirname as dirname6, join as join4 } from "path";
1617
+ import { existsSync as existsSync6 } from "fs";
1618
+ import { createRequire as createRequire2 } from "module";
1273
1619
  function getActiveEmbedModel() {
1274
1620
  return _activeModel;
1275
1621
  }
@@ -1290,21 +1636,21 @@ function embeddingsDisabled() {
1290
1636
  }
1291
1637
  function resolveModelDir() {
1292
1638
  try {
1293
- let dir = dirname4(fileURLToPath(import.meta.url));
1639
+ let dir = dirname6(fileURLToPath(import.meta.url));
1294
1640
  let root = null;
1295
1641
  for (let i = 0; i < 8; i++) {
1296
- if (existsSync5(join3(dir, "package.json"))) {
1642
+ if (existsSync6(join4(dir, "package.json"))) {
1297
1643
  root = dir;
1298
1644
  break;
1299
1645
  }
1300
- const parent = dirname4(dir);
1646
+ const parent = dirname6(dir);
1301
1647
  if (parent === dir) break;
1302
1648
  dir = parent;
1303
1649
  }
1304
1650
  if (!root) return null;
1305
1651
  for (const rel of ["dist/embedder", "assets/embedder"]) {
1306
- const candidate = join3(root, rel);
1307
- if (existsSync5(join3(candidate, "model_quantized.onnx"))) return candidate;
1652
+ const candidate = join4(root, rel);
1653
+ if (existsSync6(join4(candidate, "model_quantized.onnx"))) return candidate;
1308
1654
  }
1309
1655
  return null;
1310
1656
  } catch {
@@ -1313,9 +1659,9 @@ function resolveModelDir() {
1313
1659
  }
1314
1660
  function resolveWasmDir() {
1315
1661
  try {
1316
- const req = createRequire(import.meta.url);
1317
- const main2 = req.resolve(ORT_PKG);
1318
- return dirname4(main2);
1662
+ const req2 = createRequire2(import.meta.url);
1663
+ const main2 = req2.resolve(ORT_PKG);
1664
+ return dirname6(main2);
1319
1665
  } catch {
1320
1666
  return null;
1321
1667
  }
@@ -1335,8 +1681,8 @@ async function getSession() {
1335
1681
  ort.env.wasm.proxy = false;
1336
1682
  ort.env.wasm.wasmPaths = wasmDir.endsWith("/") ? wasmDir : wasmDir + "/";
1337
1683
  _ortTensor = ort.Tensor;
1338
- const modelPath = join3(modelDir, "model_quantized.onnx");
1339
- const vocabPath = join3(modelDir, "vocab.txt");
1684
+ const modelPath = join4(modelDir, "model_quantized.onnx");
1685
+ const vocabPath = join4(modelDir, "vocab.txt");
1340
1686
  _vocab = loadVocab(vocabPath);
1341
1687
  const session = await ort.InferenceSession.create(modelPath, {
1342
1688
  executionProviders: ["wasm"],
@@ -1673,9 +2019,8 @@ __export(memory_db_exports, {
1673
2019
  upsertObservationEmbedding: () => upsertObservationEmbedding,
1674
2020
  usageWarmupElapsed: () => usageWarmupElapsed
1675
2021
  });
1676
- import Database2 from "better-sqlite3";
1677
- import { dirname as dirname5, basename as basename2 } from "path";
1678
- import { existsSync as existsSync6, mkdirSync as mkdirSync4 } from "fs";
2022
+ import { dirname as dirname7, basename as basename2 } from "path";
2023
+ import { existsSync as existsSync7, mkdirSync as mkdirSync6 } from "fs";
1679
2024
  function sanitizeFts5Query(raw) {
1680
2025
  const trimmed = raw.trim();
1681
2026
  if (!trimmed) return '""';
@@ -1691,12 +2036,12 @@ function sanitizeFts5QueryOr(raw) {
1691
2036
  }
1692
2037
  function getMemoryDb() {
1693
2038
  const dbPath = getResolvedPaths().memoryDbPath;
1694
- const dir = dirname5(dbPath);
1695
- if (!existsSync6(dir)) {
1696
- mkdirSync4(dir, { recursive: true });
2039
+ const dir = dirname7(dbPath);
2040
+ if (!existsSync7(dir)) {
2041
+ mkdirSync6(dir, { recursive: true });
1697
2042
  }
1698
- const preExisting = existsSync6(dbPath);
1699
- const db = new Database2(dbPath);
2043
+ const preExisting = existsSync7(dbPath);
2044
+ const db = openDatabase(dbPath);
1700
2045
  db.pragma("journal_mode = WAL");
1701
2046
  db.pragma("foreign_keys = ON");
1702
2047
  const onDisk = db.pragma("user_version", { simple: true });
@@ -3402,6 +3747,7 @@ var MEMORY_SCHEMA_VERSION, TOOL_COST_EVENTS_RETENTION_DAYS, MAX_DRAFT_TEXT_LEN,
3402
3747
  var init_memory_db = __esm({
3403
3748
  "src/memory-db.ts"() {
3404
3749
  "use strict";
3750
+ init_sqlite_loader();
3405
3751
  init_config();
3406
3752
  init_memory_vector();
3407
3753
  init_db_backup();
@@ -3423,20 +3769,20 @@ var init_memory_db = __esm({
3423
3769
 
3424
3770
  // src/lib/safe-write.ts
3425
3771
  import {
3426
- writeFileSync as writeFileSync2,
3772
+ writeFileSync as writeFileSync3,
3427
3773
  renameSync,
3428
3774
  openSync,
3429
3775
  fsyncSync,
3430
3776
  closeSync,
3431
- existsSync as existsSync7,
3777
+ existsSync as existsSync8,
3432
3778
  realpathSync,
3433
3779
  unlinkSync as unlinkSync2,
3434
- accessSync,
3780
+ accessSync as accessSync2,
3435
3781
  statSync as statSync2,
3436
- chmodSync as chmodSync2,
3782
+ chmodSync as chmodSync3,
3437
3783
  constants
3438
3784
  } from "fs";
3439
- import { dirname as dirname6, resolve as resolve5, relative, isAbsolute, basename as basename3, sep } from "path";
3785
+ import { dirname as dirname8, resolve as resolve5, relative, isAbsolute, basename as basename3, sep } from "path";
3440
3786
  import { createHash as createHash2 } from "crypto";
3441
3787
  function assertContainedIn(rootDir, candidate, opts = {}) {
3442
3788
  if (candidate.includes("\0")) {
@@ -3468,8 +3814,8 @@ function isContainedIn(rootDir, candidate, opts = {}) {
3468
3814
  if (rel === "" && !opts.allowRoot) return false;
3469
3815
  if (rel.startsWith("..") || isAbsolute(rel)) return false;
3470
3816
  let probe = abs;
3471
- while (!existsSync7(probe) && probe.length > 1) {
3472
- const parent = dirname6(probe);
3817
+ while (!existsSync8(probe) && probe.length > 1) {
3818
+ const parent = dirname8(probe);
3473
3819
  if (parent === probe) break;
3474
3820
  probe = parent;
3475
3821
  }
@@ -3486,17 +3832,17 @@ function isContainedIn(rootDir, candidate, opts = {}) {
3486
3832
  return !realRel.startsWith("..") && !isAbsolute(realRel);
3487
3833
  }
3488
3834
  function atomicWriteFileSync(destPath, contents) {
3489
- const dir = dirname6(destPath);
3835
+ const dir = dirname8(destPath);
3490
3836
  const tmp = resolve5(dir, `.${basename3(destPath)}.massu-tmp-${process.pid}`);
3491
3837
  let destMode;
3492
- if (existsSync7(destPath)) {
3493
- accessSync(destPath, constants.W_OK);
3838
+ if (existsSync8(destPath)) {
3839
+ accessSync2(destPath, constants.W_OK);
3494
3840
  destMode = statSync2(destPath).mode & 511;
3495
3841
  }
3496
3842
  let fd;
3497
3843
  try {
3498
- writeFileSync2(tmp, contents, "utf-8");
3499
- if (destMode !== void 0) chmodSync2(tmp, destMode);
3844
+ writeFileSync3(tmp, contents, "utf-8");
3845
+ if (destMode !== void 0) chmodSync3(tmp, destMode);
3500
3846
  fd = openSync(tmp, "r+");
3501
3847
  fsyncSync(fd);
3502
3848
  closeSync(fd);
@@ -3510,7 +3856,7 @@ function atomicWriteFileSync(destPath, contents) {
3510
3856
  }
3511
3857
  }
3512
3858
  try {
3513
- if (existsSync7(tmp)) unlinkSync2(tmp);
3859
+ if (existsSync8(tmp)) unlinkSync2(tmp);
3514
3860
  } catch {
3515
3861
  }
3516
3862
  throw err;
@@ -3589,7 +3935,7 @@ var init_safe_write = __esm({
3589
3935
 
3590
3936
  // src/memory-authorship.ts
3591
3937
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
3592
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync8, mkdirSync as mkdirSync5, chmodSync as chmodSync3, statSync as statSync3 } from "fs";
3938
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync9, mkdirSync as mkdirSync7, chmodSync as chmodSync4, statSync as statSync3 } from "fs";
3593
3939
  import { homedir as homedir4 } from "os";
3594
3940
  import { resolve as resolve6 } from "path";
3595
3941
  function renderKeyPath(home = homedir4()) {
@@ -3598,8 +3944,8 @@ function renderKeyPath(home = homedir4()) {
3598
3944
  function readRenderKey(home = homedir4()) {
3599
3945
  const p = renderKeyPath(home);
3600
3946
  try {
3601
- if (!existsSync8(p)) return void 0;
3602
- const raw = readFileSync4(p);
3947
+ if (!existsSync9(p)) return void 0;
3948
+ const raw = readFileSync5(p);
3603
3949
  if (raw.length !== 32) return void 0;
3604
3950
  return raw;
3605
3951
  } catch {
@@ -3612,15 +3958,15 @@ function ensureRenderKey(home = homedir4()) {
3612
3958
  const p = renderKeyPath(home);
3613
3959
  try {
3614
3960
  const dir = resolve6(home, ".massu");
3615
- mkdirSync5(dir, { recursive: true, mode: 448 });
3961
+ mkdirSync7(dir, { recursive: true, mode: 448 });
3616
3962
  try {
3617
- chmodSync3(dir, 448);
3963
+ chmodSync4(dir, 448);
3618
3964
  } catch {
3619
3965
  }
3620
3966
  const key = randomBytes(32);
3621
- writeFileSync3(p, key, { mode: 384 });
3967
+ writeFileSync4(p, key, { mode: 384 });
3622
3968
  try {
3623
- chmodSync3(p, 384);
3969
+ chmodSync4(p, 384);
3624
3970
  } catch {
3625
3971
  }
3626
3972
  return key;
@@ -3665,105 +4011,9 @@ var init_memory_authorship = __esm({
3665
4011
  }
3666
4012
  });
3667
4013
 
3668
- // src/lib/fileLock.ts
3669
- import { mkdirSync as mkdirSync6, readFileSync as readFileSync5, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
3670
- import { dirname as dirname7 } from "path";
3671
- import * as lockfile from "proper-lockfile";
3672
- function readLockHolderPid(lockPath) {
3673
- try {
3674
- const raw = readFileSync5(`${lockPath}.pid`, "utf-8").trim();
3675
- const pid = Number.parseInt(raw, 10);
3676
- if (!Number.isFinite(pid) || pid <= 0) return null;
3677
- return pid;
3678
- } catch {
3679
- return null;
3680
- }
3681
- }
3682
- function busyWaitSync(ms) {
3683
- if (typeof SharedArrayBuffer === "undefined" || typeof Atomics === "undefined") {
3684
- throw new Error(
3685
- `withFileLockSync requires SharedArrayBuffer + Atomics for its retry-loop wait. This Node runtime does not provide them \u2014 refusing to fall back to a CPU spinloop. If you hit this in a sandboxed serverless env, the fix is to perform the lock-protected operation in a host runtime that supports Atomics.`
3686
- );
3687
- }
3688
- const sab = new SharedArrayBuffer(4);
3689
- const view = new Int32Array(sab);
3690
- Atomics.wait(view, 0, 0, ms);
3691
- }
3692
- function withFileLockSync(lockPath, fn, opts = {}) {
3693
- mkdirSync6(dirname7(lockPath), { recursive: true });
3694
- const staleMs = opts.staleMs ?? 3e4;
3695
- const blockMs = opts.retries === 0 ? 0 : opts.blockMs ?? 3e4;
3696
- const pollIntervalMs = opts.pollIntervalMs ?? 100;
3697
- const now = opts.now ?? Date.now;
3698
- const sleep = opts.sleep ?? busyWaitSync;
3699
- const makeBusyError = opts.errorFactory ?? ((path, pid, retrySeconds, code) => new FileLockBusyError(path, pid, retrySeconds, code));
3700
- let release = null;
3701
- const deadline = now() + blockMs;
3702
- for (; ; ) {
3703
- try {
3704
- release = lockfile.lockSync(lockPath, {
3705
- stale: staleMs,
3706
- retries: 0,
3707
- realpath: false
3708
- });
3709
- try {
3710
- writeFileSync4(`${lockPath}.pid`, String(process.pid), "utf-8");
3711
- } catch {
3712
- }
3713
- break;
3714
- } catch (err) {
3715
- const e = err;
3716
- const code = e.code;
3717
- if (code !== "ELOCKED" && code !== "EBUSY") {
3718
- throw err;
3719
- }
3720
- if (now() >= deadline) {
3721
- const holderPid = readLockHolderPid(lockPath);
3722
- const remainingMs = Math.max(0, deadline - now());
3723
- const retryAfterSeconds = blockMs === 0 ? Math.round(staleMs / 1e3) : Math.round(remainingMs / 1e3);
3724
- throw makeBusyError(lockPath, holderPid, retryAfterSeconds, code);
3725
- }
3726
- sleep(pollIntervalMs);
3727
- }
3728
- }
3729
- try {
3730
- return fn();
3731
- } finally {
3732
- try {
3733
- if (release) release();
3734
- } catch {
3735
- }
3736
- try {
3737
- rmSync3(`${lockPath}.pid`, { force: true });
3738
- } catch {
3739
- }
3740
- }
3741
- }
3742
- var FileLockBusyError;
3743
- var init_fileLock = __esm({
3744
- "src/lib/fileLock.ts"() {
3745
- "use strict";
3746
- FileLockBusyError = class extends Error {
3747
- constructor(lockPath, holderPid, retryAfterSeconds, causeCode) {
3748
- const pidPart = holderPid != null ? `(PID=${holderPid})` : "(PID=unknown)";
3749
- super(`File lock at ${lockPath} held by another process ${pidPart} \u2014 try again in ${retryAfterSeconds}s`);
3750
- this.lockPath = lockPath;
3751
- this.holderPid = holderPid;
3752
- this.retryAfterSeconds = retryAfterSeconds;
3753
- this.causeCode = causeCode;
3754
- this.name = "FileLockBusyError";
3755
- }
3756
- lockPath;
3757
- holderPid;
3758
- retryAfterSeconds;
3759
- causeCode;
3760
- };
3761
- }
3762
- });
3763
-
3764
4014
  // src/memory-index-region.ts
3765
- import { readFileSync as readFileSync6, existsSync as existsSync9 } from "fs";
3766
- import { dirname as dirname8, join as join4 } from "path";
4015
+ import { readFileSync as readFileSync6, existsSync as existsSync10 } from "fs";
4016
+ import { dirname as dirname9, join as join5 } from "path";
3767
4017
  function parseRegion(content) {
3768
4018
  const begins = countOccurrences(content, BEGIN_SENTINEL);
3769
4019
  const ends = countOccurrences(content, END_SENTINEL);
@@ -3849,7 +4099,7 @@ function assertOutsideRegionUnchanged(pre, post) {
3849
4099
  }
3850
4100
  }
3851
4101
  function memoryIndexLockPath(memoryDir) {
3852
- return join4(dirname8(memoryDir), ".massu-memory-index.lock");
4102
+ return join5(dirname9(memoryDir), ".massu-memory-index.lock");
3853
4103
  }
3854
4104
  function withMemoryIndexLock(memoryDir, fn) {
3855
4105
  return withFileLockSync(memoryIndexLockPath(memoryDir), fn, {
@@ -3861,7 +4111,7 @@ function withMemoryIndexLock(memoryDir, fn) {
3861
4111
  });
3862
4112
  }
3863
4113
  function readMemoryIndex(indexPath) {
3864
- if (!existsSync9(indexPath)) return void 0;
4114
+ if (!existsSync10(indexPath)) return void 0;
3865
4115
  try {
3866
4116
  return readFileSync6(indexPath, "utf8");
3867
4117
  } catch {
@@ -3900,11 +4150,11 @@ var init_memory_index_region = __esm({
3900
4150
  });
3901
4151
 
3902
4152
  // src/rule-candidate-snapshot.ts
3903
- import { existsSync as existsSync10, readFileSync as readFileSync7, writeFileSync as writeFileSync5, unlinkSync as unlinkSync3 } from "fs";
4153
+ import { existsSync as existsSync11, readFileSync as readFileSync7, writeFileSync as writeFileSync5, unlinkSync as unlinkSync3 } from "fs";
3904
4154
  function takeSnapshots(paths) {
3905
4155
  const out = /* @__PURE__ */ new Map();
3906
4156
  for (const p of paths) {
3907
- if (existsSync10(p)) out.set(p, readFileSync7(p, "utf-8"));
4157
+ if (existsSync11(p)) out.set(p, readFileSync7(p, "utf-8"));
3908
4158
  else out.set(p, null);
3909
4159
  }
3910
4160
  return out;
@@ -3914,7 +4164,7 @@ function restoreSnapshots(snapshot) {
3914
4164
  for (const [path, content] of snapshot) {
3915
4165
  try {
3916
4166
  if (content === null) {
3917
- if (existsSync10(path)) unlinkSync3(path);
4167
+ if (existsSync11(path)) unlinkSync3(path);
3918
4168
  } else {
3919
4169
  writeFileSync5(path, content, "utf-8");
3920
4170
  }
@@ -3931,8 +4181,8 @@ var init_rule_candidate_snapshot = __esm({
3931
4181
  });
3932
4182
 
3933
4183
  // src/memory-file-ingest.ts
3934
- import { readFileSync as readFileSync9, existsSync as existsSync12, readdirSync as readdirSync2 } from "fs";
3935
- import { join as join6 } from "path";
4184
+ import { readFileSync as readFileSync9, existsSync as existsSync13, readdirSync as readdirSync2 } from "fs";
4185
+ import { join as join7 } from "path";
3936
4186
  import { parse as parseYaml2 } from "yaml";
3937
4187
  import { basename as pathBasename } from "path";
3938
4188
  import { createHash as createHash3 } from "crypto";
@@ -4038,7 +4288,7 @@ function upsertMemoryFileMirror(db, f) {
4038
4288
  return "inserted";
4039
4289
  }
4040
4290
  function ingestMemoryFile(db, sessionId, filePath) {
4041
- if (!existsSync12(filePath)) return "skipped";
4291
+ if (!existsSync13(filePath)) return "skipped";
4042
4292
  const content = readFileSync9(filePath, "utf-8");
4043
4293
  if (Buffer.byteLength(content, "utf-8") > MAX_MEMORY_FILE_BYTES) {
4044
4294
  process.stderr.write(
@@ -4109,21 +4359,21 @@ ${body}` : body;
4109
4359
  }
4110
4360
  function backfillMemoryFiles(db, memoryDir, sessionId) {
4111
4361
  const stats = { inserted: 0, updated: 0, skipped: 0, total: 0 };
4112
- if (!existsSync12(memoryDir)) return stats;
4362
+ if (!existsSync13(memoryDir)) return stats;
4113
4363
  const files = readdirSync2(memoryDir).filter(
4114
4364
  (f) => f.endsWith(".md") && f !== "MEMORY.md"
4115
4365
  );
4116
4366
  stats.total = files.length;
4117
4367
  const sid = sessionId ?? `backfill-${Date.now()}`;
4118
4368
  for (const file of files) {
4119
- const result = ingestMemoryFile(db, sid, join6(memoryDir, file));
4369
+ const result = ingestMemoryFile(db, sid, join7(memoryDir, file));
4120
4370
  stats[result]++;
4121
4371
  }
4122
4372
  return stats;
4123
4373
  }
4124
4374
  function reconcileMemoryFileObservations(db, memoryDir, sessionId) {
4125
4375
  try {
4126
- if (!existsSync12(memoryDir)) return 0;
4376
+ if (!existsSync13(memoryDir)) return 0;
4127
4377
  let entries;
4128
4378
  try {
4129
4379
  entries = readdirSync2(memoryDir);
@@ -4135,7 +4385,7 @@ function reconcileMemoryFileObservations(db, memoryDir, sessionId) {
4135
4385
  for (const file of files) {
4136
4386
  liveNames.add(stripMdExtension(file));
4137
4387
  try {
4138
- const content = readFileSync9(join6(memoryDir, file), "utf-8");
4388
+ const content = readFileSync9(join7(memoryDir, file), "utf-8");
4139
4389
  const fm = readMemoryFileFrontmatter(content);
4140
4390
  if (fm && typeof fm.name === "string" && fm.name) liveNames.add(fm.name);
4141
4391
  } catch {
@@ -4289,15 +4539,15 @@ var init_memory_render_path = __esm({
4289
4539
  });
4290
4540
 
4291
4541
  // src/memory-tombstones.ts
4292
- import { readFileSync as readFileSync11, appendFileSync as appendFileSync2, existsSync as existsSync14 } from "fs";
4293
- import { join as join8 } from "path";
4542
+ import { readFileSync as readFileSync11, appendFileSync as appendFileSync3, existsSync as existsSync15 } from "fs";
4543
+ import { join as join9 } from "path";
4294
4544
  function tombstoneLedgerPath(memoryDir) {
4295
- return join8(memoryDir, TOMBSTONE_LEDGER);
4545
+ return join9(memoryDir, TOMBSTONE_LEDGER);
4296
4546
  }
4297
4547
  function readTombstones(memoryDir) {
4298
4548
  const out = /* @__PURE__ */ new Map();
4299
4549
  const p = tombstoneLedgerPath(memoryDir);
4300
- if (!existsSync14(p)) return out;
4550
+ if (!existsSync15(p)) return out;
4301
4551
  let raw;
4302
4552
  try {
4303
4553
  raw = readFileSync11(p, "utf8");
@@ -4368,15 +4618,15 @@ var init_memory_llm = __esm({
4368
4618
  // src/memory-backup.ts
4369
4619
  import {
4370
4620
  readdirSync as readdirSync3,
4371
- mkdirSync as mkdirSync9,
4621
+ mkdirSync as mkdirSync10,
4372
4622
  copyFileSync as copyFileSync2,
4373
4623
  statSync as statSync4,
4374
- existsSync as existsSync15,
4624
+ existsSync as existsSync16,
4375
4625
  rmSync as rmSync4,
4376
4626
  readFileSync as readFileSync12
4377
4627
  } from "fs";
4378
4628
  import { homedir as homedir6 } from "os";
4379
- import { join as join9, resolve as resolve7 } from "path";
4629
+ import { join as join10, resolve as resolve7 } from "path";
4380
4630
  function backupsRoot(home = homedir6()) {
4381
4631
  return resolve7(home, ".massu", "memory-backups");
4382
4632
  }
@@ -4384,10 +4634,10 @@ function backupStamp2(nowMs) {
4384
4634
  return new Date(nowMs).toISOString().replace(/:/g, "-");
4385
4635
  }
4386
4636
  function newestMtimeMs(dir) {
4387
- if (!existsSync15(dir)) return 0;
4637
+ if (!existsSync16(dir)) return 0;
4388
4638
  let newest = 0;
4389
4639
  for (const entry of readdirSync3(dir)) {
4390
- const p = join9(dir, entry);
4640
+ const p = join10(dir, entry);
4391
4641
  try {
4392
4642
  const st = statSync4(p);
4393
4643
  if (st.isFile() && st.mtimeMs > newest) newest = st.mtimeMs;
@@ -4399,10 +4649,10 @@ function newestMtimeMs(dir) {
4399
4649
  }
4400
4650
  function listBackups(home = homedir6()) {
4401
4651
  const root = backupsRoot(home);
4402
- if (!existsSync15(root)) return [];
4652
+ if (!existsSync16(root)) return [];
4403
4653
  const out = [];
4404
4654
  for (const stamp of readdirSync3(root)) {
4405
- const dir = join9(root, stamp);
4655
+ const dir = join10(root, stamp);
4406
4656
  try {
4407
4657
  const st = statSync4(dir);
4408
4658
  if (!st.isDirectory()) continue;
@@ -4420,21 +4670,21 @@ function hasFreshBackup(memoryDir, home = homedir6()) {
4420
4670
  return backups[0].createdMs >= newestChange;
4421
4671
  }
4422
4672
  function takeBackup(memoryDir, nowMs, home = homedir6(), retention = DEFAULT_RETENTION2) {
4423
- if (!existsSync15(memoryDir)) {
4673
+ if (!existsSync16(memoryDir)) {
4424
4674
  throw new BackupError(`memory directory does not exist: ${memoryDir}`);
4425
4675
  }
4426
4676
  const stamp = backupStamp2(nowMs);
4427
- const dir = join9(backupsRoot(home), stamp);
4677
+ const dir = join10(backupsRoot(home), stamp);
4428
4678
  try {
4429
- mkdirSync9(dir, { recursive: true, mode: 448 });
4679
+ mkdirSync10(dir, { recursive: true, mode: 448 });
4430
4680
  for (const entry of readdirSync3(memoryDir)) {
4431
- const srcPath = join9(memoryDir, entry);
4681
+ const srcPath = join10(memoryDir, entry);
4432
4682
  try {
4433
4683
  if (!statSync4(srcPath).isFile()) continue;
4434
4684
  } catch {
4435
4685
  continue;
4436
4686
  }
4437
- copyFileSync2(srcPath, join9(dir, entry));
4687
+ copyFileSync2(srcPath, join10(dir, entry));
4438
4688
  }
4439
4689
  } catch (err) {
4440
4690
  throw new BackupError(`backup failed: ${err.message}`);
@@ -4499,8 +4749,8 @@ __export(memory_renderer_exports, {
4499
4749
  renderMemoryFiles: () => renderMemoryFiles,
4500
4750
  stripFrontmatter: () => stripFrontmatter
4501
4751
  });
4502
- import { existsSync as existsSync16, readFileSync as readFileSync13 } from "fs";
4503
- import { join as join10 } from "path";
4752
+ import { existsSync as existsSync17, readFileSync as readFileSync13 } from "fs";
4753
+ import { join as join11 } from "path";
4504
4754
  import { homedir as homedir7 } from "os";
4505
4755
  import { createHash as createHash5 } from "crypto";
4506
4756
  function renderMemoryFiles(db, candidates, opts) {
@@ -4514,7 +4764,7 @@ function renderMemoryFiles(db, candidates, opts) {
4514
4764
  const audit = opts.audit ?? (() => {
4515
4765
  });
4516
4766
  const { memoryDir } = opts;
4517
- if (!existsSync16(memoryDir)) {
4767
+ if (!existsSync17(memoryDir)) {
4518
4768
  return EMPTY("no_memory_dir");
4519
4769
  }
4520
4770
  try {
@@ -4582,7 +4832,7 @@ function renderLocked(db, candidates, o) {
4582
4832
  refusals.push({ name: c.name, reason: "tombstoned" });
4583
4833
  continue;
4584
4834
  }
4585
- if (existsSync16(absPath)) {
4835
+ if (existsSync17(absPath)) {
4586
4836
  const existing = readFileSync13(absPath, "utf8");
4587
4837
  const fm = readMemoryFileFrontmatter(existing);
4588
4838
  const storeRow = db.prepare(
@@ -4632,7 +4882,7 @@ function renderLocked(db, candidates, o) {
4632
4882
  return EMPTY("backup_failed");
4633
4883
  }
4634
4884
  }
4635
- const indexPath = o.indexPath ?? join10(memoryDir, "MEMORY.md");
4885
+ const indexPath = o.indexPath ?? join11(memoryDir, "MEMORY.md");
4636
4886
  const targets = [...planned.map((p) => p.absPath), indexPath];
4637
4887
  const snapshot = takeSnapshots(targets);
4638
4888
  let bytesWritten = 0;
@@ -4996,12 +5246,12 @@ var init_manifest_registry = __esm({
4996
5246
  });
4997
5247
 
4998
5248
  // src/detect/package-detector.ts
4999
- import { readFileSync as readFileSync14, existsSync as existsSync17, statSync as statSync5, lstatSync, readdirSync as readdirSync4 } from "fs";
5000
- import { join as join11, relative as relative2 } from "path";
5249
+ import { readFileSync as readFileSync14, existsSync as existsSync18, statSync as statSync5, lstatSync, readdirSync as readdirSync4 } from "fs";
5250
+ import { join as join12, relative as relative2 } from "path";
5001
5251
  import { parse as parseToml } from "smol-toml";
5002
5252
  function safeRead(path) {
5003
5253
  try {
5004
- if (!existsSync17(path)) return null;
5254
+ if (!existsSync18(path)) return null;
5005
5255
  const ls = lstatSync(path);
5006
5256
  if (ls.isSymbolicLink()) return null;
5007
5257
  const st = statSync5(path);
@@ -5037,7 +5287,7 @@ function parsePackageJson(path, directory, root, warnings) {
5037
5287
  const peer = Object.keys(
5038
5288
  pkg.peerDependencies ?? {}
5039
5289
  );
5040
- const hasTs = deps.includes("typescript") || devDeps.includes("typescript") || existsSync17(join11(directory, "tsconfig.json"));
5290
+ const hasTs = deps.includes("typescript") || devDeps.includes("typescript") || existsSync18(join12(directory, "tsconfig.json"));
5041
5291
  const language = hasTs ? "typescript" : "javascript";
5042
5292
  const scripts = Object.keys(
5043
5293
  pkg.scripts ?? {}
@@ -5463,8 +5713,8 @@ function detectManifestsInDir(dir, root, warnings) {
5463
5713
  let dirEntries = null;
5464
5714
  for (const entry of getManifestRegistry2()) {
5465
5715
  if (!entry.pattern.startsWith("*")) {
5466
- const path = join11(dir, entry.pattern);
5467
- if (!existsSync17(path)) continue;
5716
+ const path = join12(dir, entry.pattern);
5717
+ if (!existsSync18(path)) continue;
5468
5718
  const m = entry.parse(path, dir, root, warnings);
5469
5719
  if (m !== null) out.push(m);
5470
5720
  } else {
@@ -5477,8 +5727,8 @@ function detectManifestsInDir(dir, root, warnings) {
5477
5727
  }
5478
5728
  for (const fname of dirEntries) {
5479
5729
  if (!matchManifestPattern2(fname, entry.pattern)) continue;
5480
- const path = join11(dir, fname);
5481
- if (!existsSync17(path)) continue;
5730
+ const path = join12(dir, fname);
5731
+ if (!existsSync18(path)) continue;
5482
5732
  const m = entry.parse(path, dir, root, warnings);
5483
5733
  if (m !== null) out.push(m);
5484
5734
  }
@@ -5488,7 +5738,7 @@ function detectManifestsInDir(dir, root, warnings) {
5488
5738
  }
5489
5739
  function listSubdirs(dir) {
5490
5740
  try {
5491
- return readdirSync4(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_DIRS.has(e.name)).map((e) => join11(dir, e.name));
5741
+ return readdirSync4(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_DIRS.has(e.name)).map((e) => join12(dir, e.name));
5492
5742
  } catch {
5493
5743
  return [];
5494
5744
  }
@@ -5498,8 +5748,8 @@ function detectPackageManifests(projectRoot) {
5498
5748
  const manifests = [];
5499
5749
  manifests.push(...detectManifestsInDir(projectRoot, projectRoot, warnings));
5500
5750
  for (const ws of WORKSPACE_DIRS) {
5501
- const wsRoot = join11(projectRoot, ws);
5502
- if (!existsSync17(wsRoot)) continue;
5751
+ const wsRoot = join12(projectRoot, ws);
5752
+ if (!existsSync18(wsRoot)) continue;
5503
5753
  for (const sub of listSubdirs(wsRoot)) {
5504
5754
  manifests.push(...detectManifestsInDir(sub, projectRoot, warnings));
5505
5755
  for (const sub2 of listSubdirs(sub)) {
@@ -11678,13 +11928,13 @@ var init_source_dir_detector = __esm({
11678
11928
  });
11679
11929
 
11680
11930
  // src/detect/monorepo-detector.ts
11681
- import { readFileSync as readFileSync15, existsSync as existsSync18, statSync as statSync6, lstatSync as lstatSync2, readdirSync as readdirSync5 } from "fs";
11682
- import { join as join12, relative as relative3 } from "path";
11931
+ import { readFileSync as readFileSync15, existsSync as existsSync19, statSync as statSync6, lstatSync as lstatSync2, readdirSync as readdirSync5 } from "fs";
11932
+ import { join as join13, relative as relative3 } from "path";
11683
11933
  import { parse as parseYaml3 } from "yaml";
11684
11934
  import { parse as parseToml2 } from "smol-toml";
11685
11935
  function safeReadText(path) {
11686
11936
  try {
11687
- if (!existsSync18(path)) return null;
11937
+ if (!existsSync19(path)) return null;
11688
11938
  const ls = lstatSync2(path);
11689
11939
  if (ls.isSymbolicLink()) return null;
11690
11940
  const st = statSync6(path);
@@ -11696,20 +11946,20 @@ function safeReadText(path) {
11696
11946
  }
11697
11947
  function firstManifestIn(dir) {
11698
11948
  for (const m of MANIFEST_PRIORITY) {
11699
- if (existsSync18(join12(dir, m))) return m;
11949
+ if (existsSync19(join13(dir, m))) return m;
11700
11950
  }
11701
11951
  return null;
11702
11952
  }
11703
11953
  function manifestName(dir, manifest) {
11704
11954
  try {
11705
11955
  if (manifest === "package.json") {
11706
- const raw = safeReadText(join12(dir, "package.json"));
11956
+ const raw = safeReadText(join13(dir, "package.json"));
11707
11957
  if (!raw) return null;
11708
11958
  const pkg = JSON.parse(raw);
11709
11959
  return typeof pkg.name === "string" ? pkg.name : null;
11710
11960
  }
11711
11961
  if (manifest === "pyproject.toml") {
11712
- const raw = safeReadText(join12(dir, "pyproject.toml"));
11962
+ const raw = safeReadText(join13(dir, "pyproject.toml"));
11713
11963
  if (!raw) return null;
11714
11964
  const toml = parseToml2(raw);
11715
11965
  const project = toml.project;
@@ -11720,7 +11970,7 @@ function manifestName(dir, manifest) {
11720
11970
  return null;
11721
11971
  }
11722
11972
  if (manifest === "Cargo.toml") {
11723
- const raw = safeReadText(join12(dir, "Cargo.toml"));
11973
+ const raw = safeReadText(join13(dir, "Cargo.toml"));
11724
11974
  if (!raw) return null;
11725
11975
  const toml = parseToml2(raw);
11726
11976
  const pkg = toml.package;
@@ -11728,7 +11978,7 @@ function manifestName(dir, manifest) {
11728
11978
  return null;
11729
11979
  }
11730
11980
  if (manifest === "go.mod") {
11731
- const raw = safeReadText(join12(dir, "go.mod"));
11981
+ const raw = safeReadText(join13(dir, "go.mod"));
11732
11982
  if (!raw) return null;
11733
11983
  for (const line of raw.split(/\r?\n/)) {
11734
11984
  const trimmed = line.trim();
@@ -11752,7 +12002,7 @@ function pkgFromDir(root, dir) {
11752
12002
  }
11753
12003
  function listSubdirs2(dir) {
11754
12004
  try {
11755
- return readdirSync5(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_DIRS2.has(e.name)).map((e) => join12(dir, e.name));
12005
+ return readdirSync5(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_DIRS2.has(e.name)).map((e) => join13(dir, e.name));
11756
12006
  } catch {
11757
12007
  return [];
11758
12008
  }
@@ -11760,8 +12010,8 @@ function listSubdirs2(dir) {
11760
12010
  function genericWorkspaces(root) {
11761
12011
  const out = [];
11762
12012
  for (const parent of CONVENTIONAL_WORKSPACE_PARENTS) {
11763
- const p = join12(root, parent);
11764
- if (!existsSync18(p)) continue;
12013
+ const p = join13(root, parent);
12014
+ if (!existsSync19(p)) continue;
11765
12015
  for (const sub of listSubdirs2(p)) {
11766
12016
  const pkg = pkgFromDir(root, sub);
11767
12017
  if (pkg) out.push(pkg);
@@ -11770,7 +12020,7 @@ function genericWorkspaces(root) {
11770
12020
  return out;
11771
12021
  }
11772
12022
  function detectYarnWorkspaces(root) {
11773
- const raw = safeReadText(join12(root, "package.json"));
12023
+ const raw = safeReadText(join13(root, "package.json"));
11774
12024
  if (!raw) return null;
11775
12025
  let pkg;
11776
12026
  try {
@@ -11785,7 +12035,7 @@ function detectYarnWorkspaces(root) {
11785
12035
  return expandWorkspaceGlobs(root, globs);
11786
12036
  }
11787
12037
  function detectPnpmWorkspaces(root) {
11788
- const raw = safeReadText(join12(root, "pnpm-workspace.yaml"));
12038
+ const raw = safeReadText(join13(root, "pnpm-workspace.yaml"));
11789
12039
  if (!raw) return null;
11790
12040
  try {
11791
12041
  const parsed = parseYaml3(raw);
@@ -11801,8 +12051,8 @@ function expandWorkspaceGlobs(root, globs) {
11801
12051
  for (const pattern of globs) {
11802
12052
  const parts = pattern.split("/");
11803
12053
  if (parts.length === 2 && (parts[1] === "*" || parts[1] === "**")) {
11804
- const parent = join12(root, parts[0]);
11805
- if (!existsSync18(parent)) continue;
12054
+ const parent = join13(root, parts[0]);
12055
+ if (!existsSync19(parent)) continue;
11806
12056
  for (const sub of listSubdirs2(parent)) {
11807
12057
  const pkg = pkgFromDir(root, sub);
11808
12058
  if (pkg && !seen.has(pkg.path)) {
@@ -11812,8 +12062,8 @@ function expandWorkspaceGlobs(root, globs) {
11812
12062
  }
11813
12063
  continue;
11814
12064
  }
11815
- const direct = join12(root, pattern);
11816
- if (existsSync18(direct)) {
12065
+ const direct = join13(root, pattern);
12066
+ if (existsSync19(direct)) {
11817
12067
  const pkg = pkgFromDir(root, direct);
11818
12068
  if (pkg && !seen.has(pkg.path)) {
11819
12069
  seen.add(pkg.path);
@@ -11824,16 +12074,16 @@ function expandWorkspaceGlobs(root, globs) {
11824
12074
  return out;
11825
12075
  }
11826
12076
  function hasTurbo(root) {
11827
- return existsSync18(join12(root, "turbo.json"));
12077
+ return existsSync19(join13(root, "turbo.json"));
11828
12078
  }
11829
12079
  function hasNx(root) {
11830
- return existsSync18(join12(root, "nx.json"));
12080
+ return existsSync19(join13(root, "nx.json"));
11831
12081
  }
11832
12082
  function hasLerna(root) {
11833
- return existsSync18(join12(root, "lerna.json"));
12083
+ return existsSync19(join13(root, "lerna.json"));
11834
12084
  }
11835
12085
  function hasBazel(root) {
11836
- return existsSync18(join12(root, "WORKSPACE")) || existsSync18(join12(root, "WORKSPACE.bazel")) || existsSync18(join12(root, "MODULE.bazel"));
12086
+ return existsSync19(join13(root, "WORKSPACE")) || existsSync19(join13(root, "WORKSPACE.bazel")) || existsSync19(join13(root, "MODULE.bazel"));
11837
12087
  }
11838
12088
  function detectMonorepo(projectRoot) {
11839
12089
  const nested = [];
@@ -12024,8 +12274,8 @@ var init_vr_command_map = __esm({
12024
12274
  });
12025
12275
 
12026
12276
  // src/detect/domain-inferrer.ts
12027
- import { existsSync as existsSync19, readdirSync as readdirSync6 } from "fs";
12028
- import { join as join13 } from "path";
12277
+ import { existsSync as existsSync20, readdirSync as readdirSync6 } from "fs";
12278
+ import { join as join14 } from "path";
12029
12279
  function titleCase(s) {
12030
12280
  if (!s) return s;
12031
12281
  return s.split(/[-_\s]+/).filter(Boolean).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
@@ -12045,8 +12295,8 @@ function topLevelSrcSubdirs(root, sourceDirs) {
12045
12295
  const effective = sourceDirs.length > 0 ? sourceDirs : ["src"];
12046
12296
  const seen = /* @__PURE__ */ new Set();
12047
12297
  for (const rel of effective) {
12048
- const abs = join13(root, rel);
12049
- if (!existsSync19(abs)) continue;
12298
+ const abs = join14(root, rel);
12299
+ if (!existsSync20(abs)) continue;
12050
12300
  try {
12051
12301
  for (const e of readdirSync6(abs, { withFileTypes: true })) {
12052
12302
  if (!e.isDirectory()) continue;
@@ -12133,8 +12383,8 @@ var init_domain_inferrer = __esm({
12133
12383
  });
12134
12384
 
12135
12385
  // src/detect/regex-fallback.ts
12136
- import { existsSync as existsSync20, readdirSync as readdirSync7, readFileSync as readFileSync16, statSync as statSync7 } from "fs";
12137
- import { resolve as resolve8, join as join14, basename as basename4 } from "path";
12386
+ import { existsSync as existsSync21, readdirSync as readdirSync7, readFileSync as readFileSync16, statSync as statSync7 } from "fs";
12387
+ import { resolve as resolve8, join as join15, basename as basename4 } from "path";
12138
12388
  function introspectPython(detection, projectRoot) {
12139
12389
  const sourceDir = resolveSourceDir(detection, "python", projectRoot);
12140
12390
  if (!sourceDir) return null;
@@ -12301,9 +12551,9 @@ function resolveSourceDir(detection, lang, projectRoot) {
12301
12551
  if (list.length > 0) {
12302
12552
  const first = list[0];
12303
12553
  const abs = resolve8(projectRoot, first);
12304
- return existsSync20(abs) ? abs : null;
12554
+ return existsSync21(abs) ? abs : null;
12305
12555
  }
12306
- return existsSync20(projectRoot) ? projectRoot : null;
12556
+ return existsSync21(projectRoot) ? projectRoot : null;
12307
12557
  }
12308
12558
  function sampleFiles(dir, nameRegex, pathFilter) {
12309
12559
  const out = [];
@@ -12323,7 +12573,7 @@ function sampleFiles(dir, nameRegex, pathFilter) {
12323
12573
  if (entry === "__pycache__") continue;
12324
12574
  if (entry === "venv" || entry === ".venv") continue;
12325
12575
  if (entry === "dist" || entry === "build") continue;
12326
- const child = join14(path, entry);
12576
+ const child = join15(path, entry);
12327
12577
  let st;
12328
12578
  try {
12329
12579
  st = statSync7(child);
@@ -12727,8 +12977,8 @@ init_memory_db();
12727
12977
 
12728
12978
  // src/team-rule-sync.ts
12729
12979
  init_config();
12730
- import { existsSync as existsSync11, writeFileSync as writeFileSync6, unlinkSync as unlinkSync4, mkdirSync as mkdirSync7 } from "fs";
12731
- import { join as join5, dirname as dirname9 } from "path";
12980
+ import { existsSync as existsSync12, writeFileSync as writeFileSync6, unlinkSync as unlinkSync4, mkdirSync as mkdirSync8 } from "fs";
12981
+ import { join as join6, dirname as dirname10 } from "path";
12732
12982
 
12733
12983
  // src/license.ts
12734
12984
  init_config();
@@ -13125,7 +13375,7 @@ async function pullTeamPromotions(db, opts = {}) {
13125
13375
  result.revoked_handled += 1;
13126
13376
  continue;
13127
13377
  }
13128
- if (existsSync11(candidatePath) || alreadyApplied(db, p.prompt_hash)) {
13378
+ if (existsSync12(candidatePath) || alreadyApplied(db, p.prompt_hash)) {
13129
13379
  result.skipped += 1;
13130
13380
  continue;
13131
13381
  }
@@ -13161,7 +13411,7 @@ function isValidWirePromotion(p) {
13161
13411
  return typeof r.prompt_hash === "string" && PROMPT_HASH_RE.test(r.prompt_hash) && typeof r.destination === "string" && typeof r.draft_text === "string" && typeof r.promoted_by === "string" && typeof r.promoted_at === "string";
13162
13412
  }
13163
13413
  function sidecarPath(projectRoot, promptHash) {
13164
- return join5(projectRoot, ".massu", "rule-candidates", `${promptHash}.json`);
13414
+ return join6(projectRoot, ".massu", "rule-candidates", `${promptHash}.json`);
13165
13415
  }
13166
13416
  function alreadyApplied(db, promptHash) {
13167
13417
  try {
@@ -13175,7 +13425,7 @@ function alreadyApplied(db, promptHash) {
13175
13425
  }
13176
13426
  }
13177
13427
  function handleRevocation(db, projectRoot, candidatePath, promptHash) {
13178
- if (existsSync11(candidatePath)) {
13428
+ if (existsSync12(candidatePath)) {
13179
13429
  try {
13180
13430
  unlinkSync4(candidatePath);
13181
13431
  } catch {
@@ -13223,8 +13473,8 @@ function materializeCandidate(db, projectRoot, candidatePath, p, orgId) {
13223
13473
  draft_text: p.draft_text,
13224
13474
  ...p.review_attestation !== void 0 ? { publisher_review_attestation: p.review_attestation } : {}
13225
13475
  };
13226
- const dir = dirname9(candidatePath);
13227
- if (!existsSync11(dir)) mkdirSync7(dir, { recursive: true });
13476
+ const dir = dirname10(candidatePath);
13477
+ if (!existsSync12(dir)) mkdirSync8(dir, { recursive: true });
13228
13478
  writeFileSync6(candidatePath, JSON.stringify(sidecar, null, 2), "utf-8");
13229
13479
  try {
13230
13480
  shareObservation(db, p.promoted_by, getProjectName(), "rule_promotion", promptText, {
@@ -13279,22 +13529,23 @@ function failSync(db, reason) {
13279
13529
  // src/hooks/session-start.ts
13280
13530
  init_memory_file_ingest();
13281
13531
  init_config();
13282
- import { readFileSync as readFileSync17, existsSync as existsSync21 } from "fs";
13283
- import { join as join15, resolve as resolve9 } from "path";
13532
+ init_sqlite_loader();
13533
+ import { readFileSync as readFileSync17, existsSync as existsSync22 } from "fs";
13534
+ import { join as join16, resolve as resolve9 } from "path";
13284
13535
  import { parse as parseYaml4 } from "yaml";
13285
13536
 
13286
13537
  // src/capability-advisor.ts
13287
13538
  import { createHash as createHash4 } from "crypto";
13288
- import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "fs";
13539
+ import { existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync10, writeFileSync as writeFileSync7 } from "fs";
13289
13540
  import { homedir as homedir5 } from "os";
13290
- import { dirname as dirname10, join as join7 } from "path";
13541
+ import { dirname as dirname11, join as join8 } from "path";
13291
13542
  function advisorStatePath(home = homedir5()) {
13292
- return join7(home, ".massu", "advisor-state.json");
13543
+ return join8(home, ".massu", "advisor-state.json");
13293
13544
  }
13294
13545
  function readAdvisorState(home) {
13295
13546
  try {
13296
13547
  const p = advisorStatePath(home);
13297
- if (!existsSync13(p)) return {};
13548
+ if (!existsSync14(p)) return {};
13298
13549
  return JSON.parse(readFileSync10(p, "utf-8"));
13299
13550
  } catch {
13300
13551
  return {};
@@ -13303,7 +13554,7 @@ function readAdvisorState(home) {
13303
13554
  function writeAdvisorState(state, home) {
13304
13555
  try {
13305
13556
  const p = advisorStatePath(home);
13306
- mkdirSync8(dirname10(p), { recursive: true });
13557
+ mkdirSync9(dirname11(p), { recursive: true });
13307
13558
  writeFileSync7(p, JSON.stringify(state, null, 2), { mode: 384 });
13308
13559
  } catch {
13309
13560
  }
@@ -13457,7 +13708,7 @@ var localModelAdvisor = {
13457
13708
  init_consolidation_config();
13458
13709
 
13459
13710
  // src/lib/pidLiveness.ts
13460
- import { spawnSync } from "child_process";
13711
+ import { spawnSync as spawnSync2 } from "child_process";
13461
13712
  function isPidAlive(pid, opts = {}) {
13462
13713
  if (!Number.isFinite(pid) || pid <= 0) return false;
13463
13714
  const platform = opts.platformOverride ?? process.platform;
@@ -13482,7 +13733,7 @@ function checkPosix(pid, killOverride) {
13482
13733
  }
13483
13734
  function checkWindows(pid) {
13484
13735
  try {
13485
- const res = spawnSync("tasklist", ["/FI", `PID eq ${pid}`, "/NH"], {
13736
+ const res = spawnSync2("tasklist", ["/FI", `PID eq ${pid}`, "/NH"], {
13486
13737
  encoding: "utf-8",
13487
13738
  windowsHide: true
13488
13739
  });
@@ -13665,9 +13916,8 @@ async function buildContext(db, sessionId, source, tokenBudget, taskId) {
13665
13916
  }
13666
13917
  try {
13667
13918
  const knowledgeDbPath = getResolvedPaths().knowledgeDbPath;
13668
- if (existsSync21(knowledgeDbPath)) {
13669
- const Database3 = (await import("better-sqlite3")).default;
13670
- const kdb = new Database3(knowledgeDbPath, { readonly: true });
13919
+ if (existsSync22(knowledgeDbPath)) {
13920
+ const kdb = openDatabase(knowledgeDbPath, { readonly: true, selfHeal: false });
13671
13921
  try {
13672
13922
  const stats = kdb.prepare(
13673
13923
  "SELECT COUNT(*) as doc_count, MAX(indexed_at) as last_indexed FROM knowledge_documents"
@@ -13729,8 +13979,8 @@ function estimateTokens(text) {
13729
13979
  }
13730
13980
  async function getGitBranch() {
13731
13981
  try {
13732
- const { spawnSync: spawnSync2 } = await import("child_process");
13733
- const result = spawnSync2("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
13982
+ const { spawnSync: spawnSync3 } = await import("child_process");
13983
+ const result = spawnSync3("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
13734
13984
  encoding: "utf-8",
13735
13985
  timeout: 5e3
13736
13986
  });
@@ -13756,7 +14006,7 @@ async function buildDriftBanner() {
13756
14006
  if (process.env.MASSU_DRIFT_QUIET === "1") return "";
13757
14007
  if (watcherIsLiveAndFresh()) return "";
13758
14008
  const configPath = resolve9(process.cwd(), "massu.config.yaml");
13759
- if (!existsSync21(configPath)) return "";
14009
+ if (!existsSync22(configPath)) return "";
13760
14010
  const content = readFileSync17(configPath, "utf-8");
13761
14011
  const parsed = parseYaml4(content);
13762
14012
  if (!parsed || typeof parsed !== "object") return "";
@@ -13800,8 +14050,8 @@ function getMemoryDir() {
13800
14050
  }
13801
14051
  function loadCorrectionsPreventionRules() {
13802
14052
  try {
13803
- const correctionsPath = join15(getResolvedPaths().memoryDir, "corrections.md");
13804
- if (!existsSync21(correctionsPath)) return [];
14053
+ const correctionsPath = join16(getResolvedPaths().memoryDir, "corrections.md");
14054
+ if (!existsSync22(correctionsPath)) return [];
13805
14055
  return parseCorrectionRules(readFileSync17(correctionsPath, "utf-8"));
13806
14056
  } catch (_e) {
13807
14057
  return [];
@@ -13810,7 +14060,7 @@ function loadCorrectionsPreventionRules() {
13810
14060
  function readWatchStateRaw(cwd) {
13811
14061
  try {
13812
14062
  const path = resolve9(cwd, ".massu", "watch-state.json");
13813
- if (!existsSync21(path)) return null;
14063
+ if (!existsSync22(path)) return null;
13814
14064
  const obj = JSON.parse(readFileSync17(path, "utf-8"));
13815
14065
  if (!obj || typeof obj !== "object") return null;
13816
14066
  return obj;