@mingxy/cerebro-claude-code 0.3.12 → 0.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.claude-plugin/marketplace.json +0 -0
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.mcp.json +0 -0
  4. package/README.md +0 -0
  5. package/config.json +0 -0
  6. package/hooks/apply-dream.mjs +0 -0
  7. package/hooks/common.mjs +18 -7
  8. package/hooks/common.sh +0 -0
  9. package/hooks/dream.mjs +0 -0
  10. package/hooks/flush-detached.mjs +0 -0
  11. package/hooks/hooks.json +0 -0
  12. package/hooks/post-compact.mjs +0 -0
  13. package/hooks/pre-compact.mjs +0 -0
  14. package/hooks/recall-approve.mjs +0 -0
  15. package/hooks/session-end.mjs +0 -0
  16. package/hooks/session-start.mjs +0 -0
  17. package/hooks/stop.mjs +0 -0
  18. package/hooks/user-prompt-submit.mjs +0 -0
  19. package/package.json +1 -1
  20. package/scripts/memory-profile.sh +0 -0
  21. package/scripts/memory-save.sh +0 -0
  22. package/scripts/memory-search.sh +0 -0
  23. package/scripts/web-server.mjs +12 -2
  24. package/skills/apply-dream/SKILL.md +0 -0
  25. package/skills/dream/SKILL.md +0 -0
  26. package/skills/memory-profile/SKILL.md +0 -0
  27. package/skills/memory-save/SKILL.md +0 -0
  28. package/skills/memory-search/SKILL.md +0 -0
  29. package/tests/common.test.mjs +0 -0
  30. package/tests/hooks.test.mjs +0 -0
  31. package/tests/test_smoke.sh +0 -0
  32. package/web/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  33. package/web/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  34. package/web/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  35. package/web/assets/index-BITUpTtU.js +0 -0
  36. package/web/assets/index-DVguCuEA.css +0 -0
  37. package/web/assets/index-zOJZZn-i.js +0 -0
  38. package/web/favicon.svg +0 -0
  39. package/web/icons.svg +0 -0
  40. package/web/index.html +0 -0
File without changes
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cerebro",
3
3
  "description": "Persistent memory for Claude Code — memories survive across sessions, projects, and machines",
4
- "version": "0.3.12",
4
+ "version": "0.3.13",
5
5
  "author": {
6
6
  "name": "mingxy-cerebro",
7
7
  "email": "hi@cerebro.dev"
package/.mcp.json CHANGED
File without changes
package/README.md CHANGED
File without changes
package/config.json CHANGED
File without changes
File without changes
package/hooks/common.mjs CHANGED
@@ -283,15 +283,26 @@ export function countLiveCC() {
283
283
  // Kill a stale web-server daemon so a fresh one can bind (rebirth on every
284
284
  // session start — no version sniffing). pid verified via /proc cmdline to
285
285
  // survive pid reuse; non-Linux (no /proc) degrades to no-op.
286
- export function killStaleWebServer() {
286
+ export function killStaleWebServer(port = 5212) {
287
+ const pids = new Set();
288
+ // Path 1: port occupant via ss — catches zcode's web-server.js too (it never
289
+ // writes our PID_FILE; left alive it starves our spawn via EADDRINUSE and the
290
+ // port stays with a daemon that has no .live liveness model).
287
291
  try {
288
- const pid = parseInt(readFileSync(WEB_PID_FILE, "utf-8").trim(), 10);
289
- if (!pid || pid === process.pid) return;
290
- const cmdline = readFileSync(`/proc/${pid}/cmdline`, "utf-8");
291
- if (!cmdline.includes("web-server.mjs")) return; // not ours — don't touch
292
- process.kill(pid, "SIGTERM");
293
- setTimeout(() => { try { process.kill(pid, "SIGKILL"); } catch {} }, 500).unref();
292
+ const out = execSync(`ss -ltnpH 'sport = :${port}'`, { timeout: 2000 }).toString();
293
+ for (const m of out.matchAll(/pid=(\d+)/g)) pids.add(parseInt(m[1], 10));
294
294
  } catch {}
295
+ // Path 2: our own PID_FILE (the .mjs daemon writes it at listen-time).
296
+ try { pids.add(parseInt(readFileSync(WEB_PID_FILE, "utf-8").trim(), 10)); } catch {}
297
+ for (const pid of pids) {
298
+ if (!pid || pid === process.pid || Number.isNaN(pid)) continue;
299
+ try {
300
+ const cmdline = readFileSync(`/proc/${pid}/cmdline`, "utf-8");
301
+ if (!/web-server\.m?js/.test(cmdline)) continue; // not a cerebro web-server — don't touch
302
+ process.kill(pid, "SIGTERM");
303
+ setTimeout(() => { try { process.kill(pid, "SIGKILL"); } catch {} }, 500).unref();
304
+ } catch {}
305
+ }
295
306
  }
296
307
 
297
308
  // ─── Compact result handoff (PostCompact → SessionStart:compact) ─────────────
package/hooks/common.sh CHANGED
File without changes
package/hooks/dream.mjs CHANGED
File without changes
File without changes
package/hooks/hooks.json CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/hooks/stop.mjs CHANGED
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mingxy/cerebro-claude-code",
3
- "version": "0.3.12",
3
+ "version": "0.3.13",
4
4
  "description": "Persistent memory for Claude Code — memories survive across sessions, projects, and machines",
5
5
  "author": {
6
6
  "name": "mingxy-cerebro",
File without changes
File without changes
File without changes
@@ -83,7 +83,12 @@ function serveFile(res, filePath) {
83
83
  }
84
84
 
85
85
  const indexPath = path.join(WEB_DIR, "index.html");
86
+ // Traffic timestamp — any request refreshes it; the watchdog's idle escape
87
+ // hatch (below) uses it to survive with zero CC sessions while the UI is in use.
88
+ let lastActivity = Date.now();
86
89
  const server = http.createServer((req, res) => {
90
+ lastActivity = Date.now(); // traffic = the UI is in use; feeds the idle escape hatch
91
+
87
92
  if (req.url === "/health" || req.url === "/health/") {
88
93
  res.writeHead(200, { ...COMMON, "Content-Type": "application/json" });
89
94
  res.end(JSON.stringify({ status: "ok", service: "cerebro", port: PORT }));
@@ -133,9 +138,14 @@ server.listen(PORT, "127.0.0.1", () => {
133
138
  // CC main pid. Sweep on an interval, kill(pid, 0) each, sweep stale ones.
134
139
  // Zero CC sessions alive → count down the grace window → self-exit. Survives
135
140
  // killed terminals (no SessionEnd needed) — refcount bookkeeping is gone.
141
+ // Traffic escape hatch: zcode reuses this daemon and keeps it alive by pinging
142
+ // /health at every turn-end; an open web panel polls too. Requests mean
143
+ // someone is using the UI — survive with zero live CC sessions until traffic
144
+ // stops for IDLE_MS (mirrors the zcode daemon's idle semantics).
136
145
  const SESSIONS_DIR = path.join(process.env.HOME || process.env.USERPROFILE || "", ".config/cerebro/sessions");
137
146
  const GRACE_MS = parseInt(process.env.OMEM_WEB_GRACE_MS || "", 10) || 60_000;
138
147
  const WATCH_MS = parseInt(process.env.OMEM_WEB_WATCH_MS || "", 10) || 60_000;
148
+ const IDLE_MS = parseInt(process.env.OMEM_WEB_IDLE_MS || "", 10) || 300_000;
139
149
  let zeroSince = 0; // 0 = CC alive (or unknown)
140
150
 
141
151
  setInterval(() => {
@@ -153,10 +163,10 @@ setInterval(() => {
153
163
  }
154
164
  }
155
165
  } catch {} // dir missing = no CC session ever
156
- if (alive > 0) { zeroSince = 0; return; }
166
+ if (alive > 0 || Date.now() - lastActivity < IDLE_MS) { zeroSince = 0; return; }
157
167
  if (!zeroSince) zeroSince = Date.now();
158
168
  if (Date.now() - zeroSince >= GRACE_MS) {
159
- console.log(`[cerebro web-server] no CC sessions alive for ${GRACE_MS / 1000}s, self-exiting`);
169
+ console.log(`[cerebro web-server] no CC sessions or traffic for ${IDLE_MS / 1000}s, self-exiting`);
160
170
  try { fs.unlinkSync(PID_FILE); } catch {}
161
171
  process.exit(0);
162
172
  }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/web/favicon.svg CHANGED
File without changes
package/web/icons.svg CHANGED
File without changes
package/web/index.html CHANGED
File without changes