@remnic/plugin-codex 10.0.40 → 10.0.41

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "remnic",
3
3
  "description": "Universal memory for AI agents — automatic recall, observation, and cross-agent knowledge sharing",
4
- "version": "10.0.40",
4
+ "version": "10.0.41",
5
5
  "author": {
6
6
  "name": "Joshua Warren",
7
7
  "url": "https://github.com/joshuaswarren"
@@ -114,7 +114,7 @@ function cursorPath(home, sessionId) {
114
114
  test("session-start: healthy server returns recall context with codingContext cleared outside a repo", async () => {
115
115
  const home = mkHome();
116
116
  const { server, port, calls } = await startServer((req, res, body) => {
117
- if (req.url === "/engram/v1/health") return res.writeHead(200).end("ok");
117
+ if (req.url === "/engram/v1/live") return res.writeHead(200).end("ok");
118
118
  if (req.url === "/engram/v1/recall") {
119
119
  return res.writeHead(200, { "Content-Type": "application/json" }).end(
120
120
  JSON.stringify({ context: "remembered preferences", count: 3, mode: "auto" }),
@@ -144,7 +144,7 @@ test("session-start: falls back to minimal mode when full recall fails", async (
144
144
  const home = mkHome();
145
145
  let recallHits = 0;
146
146
  const { server, port, calls } = await startServer((req, res) => {
147
- if (req.url === "/engram/v1/health") return res.writeHead(200).end("ok");
147
+ if (req.url === "/engram/v1/live") return res.writeHead(200).end("ok");
148
148
  if (req.url === "/engram/v1/recall") {
149
149
  recallHits += 1;
150
150
  if (recallHits === 1) return res.writeHead(500).end("boom");
@@ -168,7 +168,7 @@ test("session-start: falls back to minimal mode when full recall fails", async (
168
168
  test("session-start: no token → guidance message, no recall call", async () => {
169
169
  const home = mkHome();
170
170
  const { server, port, calls } = await startServer((req, res) => {
171
- if (req.url === "/engram/v1/health") return res.writeHead(200).end("ok");
171
+ if (req.url === "/engram/v1/live") return res.writeHead(200).end("ok");
172
172
  res.writeHead(200).end("{}");
173
173
  });
174
174
  try {
@@ -710,7 +710,7 @@ test("pre-compact: REMNIC_NAMESPACE attaches a namespace to the flush (#1571)",
710
710
  test("session-start: REMNIC_DAEMON_URL routes recall to the remote base URL (#1571)", async () => {
711
711
  const home = mkHome();
712
712
  const { server, port, calls } = await startServer((req, res) => {
713
- if (req.url === "/engram/v1/health") return res.writeHead(200).end("ok");
713
+ if (req.url === "/engram/v1/live") return res.writeHead(200).end("ok");
714
714
  if (req.url === "/engram/v1/recall") {
715
715
  return res.writeHead(200, { "Content-Type": "application/json" }).end(
716
716
  JSON.stringify({ context: "remote recall", count: 1, mode: "auto" }),
@@ -1066,7 +1066,7 @@ test("session-start: a path-prefixed REMNIC_DAEMON_URL routes under the prefix (
1066
1066
  // plugin-pi's daemon-URL + route concatenation).
1067
1067
  const home = mkHome();
1068
1068
  const { server, port, calls } = await startServer((req, res) => {
1069
- if (req.url === "/remnic/engram/v1/health") return res.writeHead(200).end("ok");
1069
+ if (req.url === "/remnic/engram/v1/live") return res.writeHead(200).end("ok");
1070
1070
  if (req.url === "/remnic/engram/v1/recall") {
1071
1071
  return res.writeHead(200, { "Content-Type": "application/json" }).end(
1072
1072
  JSON.stringify({ context: "prefixed recall", count: 1, mode: "auto" }),
@@ -1091,7 +1091,7 @@ test("session-start: a path-prefixed REMNIC_DAEMON_URL routes under the prefix (
1091
1091
  "recall honored the /remnic path prefix",
1092
1092
  );
1093
1093
  assert.ok(
1094
- calls.some((c) => c.url === "/remnic/engram/v1/health"),
1094
+ calls.some((c) => c.url === "/remnic/engram/v1/live"),
1095
1095
  "health check honored the /remnic path prefix",
1096
1096
  );
1097
1097
  } finally {
@@ -1106,7 +1106,7 @@ test("session-start: REMNIC_NAMESPACE scopes the recall body (#1571 review, pari
1106
1106
  // install recalls from the default key while observing to the namespaced key.
1107
1107
  const home = mkHome();
1108
1108
  const { server, port, calls } = await startServer((req, res) => {
1109
- if (req.url === "/engram/v1/health") return res.writeHead(200).end("ok");
1109
+ if (req.url === "/engram/v1/live") return res.writeHead(200).end("ok");
1110
1110
  if (req.url === "/engram/v1/recall") {
1111
1111
  return res.writeHead(200, { "Content-Type": "application/json" }).end(
1112
1112
  JSON.stringify({ context: "namespaced recall", count: 1, mode: "auto" }),
@@ -1160,7 +1160,7 @@ test("pre-compact: REMNIC_PRECOMPACT_LOCK_RETRIES=0 still takes a FREE lock (doe
1160
1160
  });
1161
1161
 
1162
1162
  // ── daemon auth: health probe + canonical env credentials ──────────────────
1163
- // An auth-gated daemon 401s EVERY route, including /engram/v1/health. An
1163
+ // An auth-gated daemon 401s EVERY route, including /engram/v1/live. An
1164
1164
  // unauthenticated probe therefore makes the hook report "daemon not running"
1165
1165
  // and skip recall/observe entirely. The credential itself has to be findable:
1166
1166
  // the documented standalone-server setup authenticates the daemon with
@@ -1170,7 +1170,7 @@ test("pre-compact: REMNIC_PRECOMPACT_LOCK_RETRIES=0 still takes a FREE lock (doe
1170
1170
  function authServer() {
1171
1171
  const seen = { health: "unset", recall: "unset" };
1172
1172
  return startServer((req, res) => {
1173
- if (req.url === "/engram/v1/health") {
1173
+ if (req.url === "/engram/v1/live") {
1174
1174
  seen.health = req.headers.authorization || null;
1175
1175
  return res.writeHead(200).end("ok");
1176
1176
  }
@@ -366,34 +366,48 @@ function run(config) {
366
366
  // ignore) and green-light a probe whose recall then 401s.
367
367
  //
368
368
  // When the daemon has an auth token configured, every route — including
369
- // /engram/v1/health — returns 401 to unauthenticated requests, so an
369
+ // /engram/v1/live — returns 401 to unauthenticated requests, so an
370
370
  // unauthenticated probe makes the hook wrongly report "daemon not running"
371
371
  // and skip recall/observe. Unauthenticated daemons ignore the header.
372
+ //
373
+ // One aggregate budget: readiness-gated /engram/v1/live first, and only a
374
+ // 404 (daemon predating the live route) retries the legacy diagnostic
375
+ // /engram/v1/health with the remaining time. 401/503 are final answers.
376
+ // Diagnostic health can outlive this liveness probe's deadline, which is
377
+ // why the gate probes liveness at all (#3257).
372
378
  function httpHealthy(timeoutMs, token) {
373
379
  if (DAEMON_URL === null) return Promise.resolve(false);
374
380
  const transport = DAEMON_URL.protocol === "https:" ? https : http;
375
- return new Promise((resolve) => {
381
+ const headers = token ? { Authorization: `Bearer ${token}` } : {};
382
+ const deadline = Date.now() + timeoutMs;
383
+ const probe = (path, budget) => new Promise((resolve) => {
376
384
  const req = transport.request(
377
385
  {
378
386
  protocol: DAEMON_URL.protocol,
379
387
  hostname: DAEMON_URL.hostname,
380
388
  port: DAEMON_URL.port || (DAEMON_URL.protocol === "https:" ? 443 : 80),
381
- path: DAEMON_BASE_PATH + "/engram/v1/health",
389
+ path: DAEMON_BASE_PATH + path,
382
390
  method: "GET",
383
- headers: token ? { Authorization: `Bearer ${token}` } : {},
391
+ headers,
384
392
  },
385
393
  (res) => {
386
394
  res.resume();
387
- resolve(res.statusCode >= 200 && res.statusCode < 300);
395
+ resolve(res.statusCode || 0);
388
396
  },
389
397
  );
390
- req.on("error", () => resolve(false));
391
- req.setTimeout(timeoutMs, () => {
398
+ req.on("error", () => resolve(0));
399
+ req.setTimeout(budget, () => {
392
400
  req.destroy();
393
- resolve(false);
401
+ resolve(0);
394
402
  });
395
403
  req.end();
396
404
  });
405
+ return probe("/engram/v1/live", timeoutMs).then((status) => {
406
+ if (status !== 404) return status >= 200 && status < 300;
407
+ const remaining = deadline - Date.now();
408
+ if (remaining <= 0) return false;
409
+ return probe("/engram/v1/health", remaining).then((legacy) => legacy >= 200 && legacy < 300);
410
+ });
397
411
  }
398
412
 
399
413
  // ── git coding-context (mirrors @remnic/core git-context.ts) ───────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/plugin-codex",
3
- "version": "10.0.40",
3
+ "version": "10.0.41",
4
4
  "description": "Remnic memory plugin for Codex CLI — hooks, skills, MCP integration",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -30,6 +30,6 @@
30
30
  ".mcp.json"
31
31
  ],
32
32
  "dependencies": {
33
- "@remnic/core": "^10.0.40"
33
+ "@remnic/core": "^10.0.41"
34
34
  }
35
35
  }