@remnic/core 9.69.96 → 9.69.98

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 (136) hide show
  1. package/dist/access-admin-ops-surface.js +9 -9
  2. package/dist/access-authorization-probe.js +10 -10
  3. package/dist/access-boundary.js +9 -9
  4. package/dist/access-cli.js +34 -34
  5. package/dist/access-extraction-force-flush.js +9 -9
  6. package/dist/access-http-briefing.js +10 -10
  7. package/dist/access-http-query.js +9 -9
  8. package/dist/access-http.d.ts.map +1 -1
  9. package/dist/access-http.js +28 -28
  10. package/dist/access-identity-continuity-surface.js +9 -9
  11. package/dist/access-lcm-surface.js +9 -9
  12. package/dist/access-mcp.js +16 -16
  13. package/dist/access-namespace-preflight.js +9 -9
  14. package/dist/access-observe-write-category.js +6 -6
  15. package/dist/access-observe-write-surface.js +9 -9
  16. package/dist/access-offline-manifest.js +5 -5
  17. package/dist/access-operations-batch.js +10 -10
  18. package/dist/access-operations.js +15 -15
  19. package/dist/access-recall-concurrency.js +9 -9
  20. package/dist/access-recall-response.js +9 -9
  21. package/dist/access-recall-surface.js +9 -9
  22. package/dist/access-schema.js +5 -5
  23. package/dist/access-service.js +9 -9
  24. package/dist/access-surface-catalog.js +11 -11
  25. package/dist/active-recall.js +5 -5
  26. package/dist/adapters/claude-code.js +2 -2
  27. package/dist/adapters/codex.js +2 -2
  28. package/dist/adapters/hermes.js +2 -2
  29. package/dist/adapters/index.js +6 -6
  30. package/dist/adapters/registry.js +6 -6
  31. package/dist/adapters/replit.js +2 -2
  32. package/dist/adapters/types.d.ts +2 -0
  33. package/dist/adapters/types.d.ts.map +1 -1
  34. package/dist/adapters/types.js +1 -1
  35. package/dist/{chunk-F23U5YE7.js → chunk-2KB7TTAP.js} +12 -10
  36. package/dist/chunk-2KB7TTAP.js.map +1 -0
  37. package/dist/{chunk-J64TK33U.js → chunk-3JKYQBLC.js} +5 -4
  38. package/dist/{chunk-J64TK33U.js.map → chunk-3JKYQBLC.js.map} +1 -1
  39. package/dist/{chunk-MSAI3Q7D.js → chunk-3QH4NT72.js} +2 -2
  40. package/dist/{chunk-P62DSJUK.js → chunk-3RMJLDMS.js} +4 -4
  41. package/dist/{chunk-KNI4SGQE.js → chunk-3SNJMRC7.js} +7 -7
  42. package/dist/{chunk-WHIGRW7T.js → chunk-4HUMF74S.js} +2 -2
  43. package/dist/{chunk-U36GYZ2P.js → chunk-55NZVUNI.js} +2 -2
  44. package/dist/{chunk-UG5V3Z3R.js → chunk-6MWPIWPF.js} +3 -3
  45. package/dist/{chunk-OEBUAC3O.js → chunk-76GQBIVX.js} +2 -2
  46. package/dist/{chunk-RSUYKGGZ.js → chunk-7RKSJVOQ.js} +5 -4
  47. package/dist/{chunk-RSUYKGGZ.js.map → chunk-7RKSJVOQ.js.map} +1 -1
  48. package/dist/{chunk-4NSLQ7EU.js → chunk-ANPRNTPT.js} +3 -3
  49. package/dist/{chunk-4NSLQ7EU.js.map → chunk-ANPRNTPT.js.map} +1 -1
  50. package/dist/{chunk-6BG364RN.js → chunk-AWEHMKIO.js} +2 -2
  51. package/dist/{chunk-AF5PW35O.js → chunk-FQJ4YXJO.js} +2 -2
  52. package/dist/{chunk-42NQ7AVG.js → chunk-HCAGBFE7.js} +5 -4
  53. package/dist/{chunk-42NQ7AVG.js.map → chunk-HCAGBFE7.js.map} +1 -1
  54. package/dist/{chunk-KYOZ5E6V.js → chunk-HDOWMJKD.js} +2 -2
  55. package/dist/{chunk-ANGZWYL2.js → chunk-I7BRU753.js} +3 -3
  56. package/dist/{chunk-MZAH3CBT.js → chunk-IKWD4VP7.js} +2 -2
  57. package/dist/{chunk-HQCUUVG2.js → chunk-J3GJ23IP.js} +19 -12
  58. package/dist/chunk-J3GJ23IP.js.map +1 -0
  59. package/dist/{chunk-3BTHXB7Z.js → chunk-JAQXKNQV.js} +2 -2
  60. package/dist/{chunk-AXGJMDBS.js → chunk-KO4X4WRJ.js} +2 -2
  61. package/dist/{chunk-VOZNBQNL.js → chunk-LBU623X7.js} +2 -2
  62. package/dist/{chunk-5S7SNRSJ.js → chunk-N6GYEWFQ.js} +2 -2
  63. package/dist/{chunk-7RXCMVFQ.js → chunk-NJAIR57U.js} +1 -1
  64. package/dist/{chunk-7RXCMVFQ.js.map → chunk-NJAIR57U.js.map} +1 -1
  65. package/dist/{chunk-PH2V7EXZ.js → chunk-NWXGLTWN.js} +2 -2
  66. package/dist/{chunk-R5B3OWI4.js → chunk-OYQAYIGE.js} +7 -7
  67. package/dist/{chunk-A3K2KKSG.js → chunk-PYYQCHJC.js} +2 -2
  68. package/dist/{chunk-GXETU7AE.js → chunk-QVYXXOTR.js} +7 -7
  69. package/dist/{chunk-TMSXWOBZ.js → chunk-SI36RWC3.js} +5 -4
  70. package/dist/{chunk-TMSXWOBZ.js.map → chunk-SI36RWC3.js.map} +1 -1
  71. package/dist/{chunk-NSKXRTVZ.js → chunk-ST4IBSPL.js} +2 -2
  72. package/dist/{chunk-SMLKHXPF.js → chunk-UKWQSPUU.js} +2 -2
  73. package/dist/{chunk-IVEHY2VT.js → chunk-VQEOBVF2.js} +4 -4
  74. package/dist/{chunk-YHZWVDP7.js → chunk-YHDA3DSO.js} +2 -2
  75. package/dist/{chunk-C6HPNPNK.js → chunk-ZK4XGNJ3.js} +4 -4
  76. package/dist/{chunk-ZQTYWSO3.js → chunk-ZNEA255W.js} +2 -2
  77. package/dist/cli.js +32 -32
  78. package/dist/config.js +5 -5
  79. package/dist/deep-recall-http-glue.js +6 -6
  80. package/dist/external-wiki-access.js +10 -10
  81. package/dist/index.js +34 -34
  82. package/dist/memory-browse-operations.js +10 -10
  83. package/dist/offline-sync-changeset-generations.js +3 -3
  84. package/dist/offline-sync-embedding-generation.js +2 -2
  85. package/dist/offline-sync-exclude-globs.d.ts +1 -0
  86. package/dist/offline-sync-exclude-globs.d.ts.map +1 -1
  87. package/dist/offline-sync-exclude-globs.js +1 -1
  88. package/dist/offline-sync-snapshot-stream.js +5 -5
  89. package/dist/offline-sync.js +4 -4
  90. package/dist/operator-toolkit.js +6 -6
  91. package/dist/orchestrator.js +34 -34
  92. package/dist/recall-navigation-operations.js +10 -10
  93. package/dist/recall-navigation.js +9 -9
  94. package/dist/resume-bundles.js +6 -6
  95. package/dist/support-passport/index.js +12 -12
  96. package/package.json +2 -2
  97. package/src/access-http-adapter-namespace.test.ts +217 -0
  98. package/src/access-http.ts +8 -0
  99. package/src/adapters/claude-code.ts +4 -4
  100. package/src/adapters/codex.ts +3 -3
  101. package/src/adapters/grok-opencode.test.ts +2 -0
  102. package/src/adapters/grok.ts +3 -3
  103. package/src/adapters/hermes.ts +3 -3
  104. package/src/adapters/opencode.ts +3 -3
  105. package/src/adapters/replit.ts +3 -3
  106. package/src/adapters/types.ts +2 -0
  107. package/src/offline-sync-exclude-globs.ts +3 -2
  108. package/src/offline-sync.test.ts +12 -0
  109. package/dist/chunk-F23U5YE7.js.map +0 -1
  110. package/dist/chunk-HQCUUVG2.js.map +0 -1
  111. /package/dist/{chunk-MSAI3Q7D.js.map → chunk-3QH4NT72.js.map} +0 -0
  112. /package/dist/{chunk-P62DSJUK.js.map → chunk-3RMJLDMS.js.map} +0 -0
  113. /package/dist/{chunk-KNI4SGQE.js.map → chunk-3SNJMRC7.js.map} +0 -0
  114. /package/dist/{chunk-WHIGRW7T.js.map → chunk-4HUMF74S.js.map} +0 -0
  115. /package/dist/{chunk-U36GYZ2P.js.map → chunk-55NZVUNI.js.map} +0 -0
  116. /package/dist/{chunk-UG5V3Z3R.js.map → chunk-6MWPIWPF.js.map} +0 -0
  117. /package/dist/{chunk-OEBUAC3O.js.map → chunk-76GQBIVX.js.map} +0 -0
  118. /package/dist/{chunk-6BG364RN.js.map → chunk-AWEHMKIO.js.map} +0 -0
  119. /package/dist/{chunk-AF5PW35O.js.map → chunk-FQJ4YXJO.js.map} +0 -0
  120. /package/dist/{chunk-KYOZ5E6V.js.map → chunk-HDOWMJKD.js.map} +0 -0
  121. /package/dist/{chunk-ANGZWYL2.js.map → chunk-I7BRU753.js.map} +0 -0
  122. /package/dist/{chunk-MZAH3CBT.js.map → chunk-IKWD4VP7.js.map} +0 -0
  123. /package/dist/{chunk-3BTHXB7Z.js.map → chunk-JAQXKNQV.js.map} +0 -0
  124. /package/dist/{chunk-AXGJMDBS.js.map → chunk-KO4X4WRJ.js.map} +0 -0
  125. /package/dist/{chunk-VOZNBQNL.js.map → chunk-LBU623X7.js.map} +0 -0
  126. /package/dist/{chunk-5S7SNRSJ.js.map → chunk-N6GYEWFQ.js.map} +0 -0
  127. /package/dist/{chunk-PH2V7EXZ.js.map → chunk-NWXGLTWN.js.map} +0 -0
  128. /package/dist/{chunk-R5B3OWI4.js.map → chunk-OYQAYIGE.js.map} +0 -0
  129. /package/dist/{chunk-A3K2KKSG.js.map → chunk-PYYQCHJC.js.map} +0 -0
  130. /package/dist/{chunk-GXETU7AE.js.map → chunk-QVYXXOTR.js.map} +0 -0
  131. /package/dist/{chunk-NSKXRTVZ.js.map → chunk-ST4IBSPL.js.map} +0 -0
  132. /package/dist/{chunk-SMLKHXPF.js.map → chunk-UKWQSPUU.js.map} +0 -0
  133. /package/dist/{chunk-IVEHY2VT.js.map → chunk-VQEOBVF2.js.map} +0 -0
  134. /package/dist/{chunk-YHZWVDP7.js.map → chunk-YHDA3DSO.js.map} +0 -0
  135. /package/dist/{chunk-C6HPNPNK.js.map → chunk-ZK4XGNJ3.js.map} +0 -0
  136. /package/dist/{chunk-ZQTYWSO3.js.map → chunk-ZNEA255W.js.map} +0 -0
@@ -228,7 +228,7 @@ import {
228
228
  runTimelinePublishCli,
229
229
  screenCandidateFact,
230
230
  summarizeVaultPublish
231
- } from "./chunk-R5B3OWI4.js";
231
+ } from "./chunk-OYQAYIGE.js";
232
232
  import {
233
233
  RoutingRulesStore
234
234
  } from "./chunk-TBUEE7XF.js";
@@ -258,7 +258,7 @@ import {
258
258
  import {
259
259
  runNamespaceMaintenanceFanout,
260
260
  summarizeNamespaceMaintenanceHealth
261
- } from "./chunk-OEBUAC3O.js";
261
+ } from "./chunk-76GQBIVX.js";
262
262
  import {
263
263
  planNamespaceMaintenance
264
264
  } from "./chunk-WTZQM74L.js";
@@ -329,7 +329,7 @@ import {
329
329
  embeddingsFromCosineHits,
330
330
  normalizeConnectorScope,
331
331
  runSeedGraduationPass
332
- } from "./chunk-U36GYZ2P.js";
332
+ } from "./chunk-55NZVUNI.js";
333
333
  import {
334
334
  compileCorrectionRule,
335
335
  correctionsFilePath,
@@ -367,7 +367,7 @@ import {
367
367
  } from "./chunk-QW27DOHG.js";
368
368
  import {
369
369
  MeetingsInputError
370
- } from "./chunk-HQCUUVG2.js";
370
+ } from "./chunk-J3GJ23IP.js";
371
371
  import {
372
372
  WearablesInputError,
373
373
  describeErrorForOperator
@@ -394,7 +394,7 @@ import {
394
394
  detectPassiveCorrections,
395
395
  renderSessionExperiencePreview,
396
396
  scoreSessionExperienceForPrompt
397
- } from "./chunk-GXETU7AE.js";
397
+ } from "./chunk-QVYXXOTR.js";
398
398
  import {
399
399
  importCapsule
400
400
  } from "./chunk-ZHXSOMYH.js";
@@ -754,7 +754,7 @@ import {
754
754
  } from "./chunk-N4PYB235.js";
755
755
  import {
756
756
  storageBackedIndexStoreIo
757
- } from "./chunk-AXGJMDBS.js";
757
+ } from "./chunk-KO4X4WRJ.js";
758
758
  import {
759
759
  assertIsDirectoryNotSymlink,
760
760
  assertRealpathInsideRoot
@@ -31096,4 +31096,4 @@ export {
31096
31096
  qmdStartupCollectionChecksWithTimeout,
31097
31097
  Orchestrator
31098
31098
  };
31099
- //# sourceMappingURL=chunk-KNI4SGQE.js.map
31099
+ //# sourceMappingURL=chunk-3SNJMRC7.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineOperation
3
- } from "./chunk-GXETU7AE.js";
3
+ } from "./chunk-QVYXXOTR.js";
4
4
  import {
5
5
  EngramAccessInputError
6
6
  } from "./chunk-3MUKQQ7A.js";
@@ -71,4 +71,4 @@ defineOperation({
71
71
  })
72
72
  })
73
73
  });
74
- //# sourceMappingURL=chunk-WHIGRW7T.js.map
74
+ //# sourceMappingURL=chunk-4HUMF74S.js.map
@@ -141,7 +141,7 @@ import {
141
141
  } from "./chunk-7RJUVTVF.js";
142
142
  import {
143
143
  parseOfflineSyncExcludes
144
- } from "./chunk-4NSLQ7EU.js";
144
+ } from "./chunk-ANPRNTPT.js";
145
145
  import {
146
146
  excludeSupportPassportPrivateMemories
147
147
  } from "./chunk-PWPIERBM.js";
@@ -5515,4 +5515,4 @@ export {
5515
5515
  VALID_MEMORY_CATEGORIES,
5516
5516
  parseConfig
5517
5517
  };
5518
- //# sourceMappingURL=chunk-U36GYZ2P.js.map
5518
+ //# sourceMappingURL=chunk-55NZVUNI.js.map
@@ -21,7 +21,7 @@ import {
21
21
  defineOperation,
22
22
  parseNamespacePreflightWriteOp,
23
23
  resolveAuthorizedNamespaceWritablePreflight
24
- } from "./chunk-GXETU7AE.js";
24
+ } from "./chunk-QVYXXOTR.js";
25
25
  import {
26
26
  parseSharedWriteOutputControls
27
27
  } from "./chunk-IFBSZGW3.js";
@@ -36,7 +36,7 @@ import {
36
36
  recallRequestSchema,
37
37
  retainedCategoryAlias,
38
38
  suggestionSubmitRequestSchema
39
- } from "./chunk-3BTHXB7Z.js";
39
+ } from "./chunk-JAQXKNQV.js";
40
40
  import {
41
41
  enforceNamespaceAllowList,
42
42
  tokenCapabilityStore
@@ -603,4 +603,4 @@ defineOperation({ name: "graph_events", description: "SSE graph events.", schema
603
603
  defineOperation({ name: "chat_message", description: "Chat message.", schema: strictSchema({ message: S.str, chatSessionId: S.str }), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
604
604
  defineOperation({ name: "chat_events", description: "SSE chat events.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { stream: "sse" } }) });
605
605
  defineOperation({ name: "adapters_status", description: "Adapter registry metadata (issue #1850 round 5). Marker op: the HTTP transport builds the response from its own adapterRegistry, but the op still must be registered so it appears in listRegisteredOperations and enforceTokenOp can gate it for scoped tokens.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
606
- //# sourceMappingURL=chunk-UG5V3Z3R.js.map
606
+ //# sourceMappingURL=chunk-6MWPIWPF.js.map
@@ -38,7 +38,7 @@ import {
38
38
  } from "./chunk-YBPYIAA5.js";
39
39
  import {
40
40
  parseConfig
41
- } from "./chunk-U36GYZ2P.js";
41
+ } from "./chunk-55NZVUNI.js";
42
42
  import {
43
43
  readAggregateExtractionWatermark
44
44
  } from "./chunk-R36IBI2M.js";
@@ -1683,4 +1683,4 @@ export {
1683
1683
  runBenchmarkRecall,
1684
1684
  runOperatorRepair
1685
1685
  };
1686
- //# sourceMappingURL=chunk-OEBUAC3O.js.map
1686
+ //# sourceMappingURL=chunk-76GQBIVX.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  headerValue
3
- } from "./chunk-7RXCMVFQ.js";
3
+ } from "./chunk-NJAIR57U.js";
4
4
 
5
5
  // src/adapters/codex.ts
6
6
  var CodexAdapter = class {
@@ -15,9 +15,10 @@ var CodexAdapter = class {
15
15
  }
16
16
  resolveIdentity(context) {
17
17
  const mcpSessionId = headerValue(context.headers, "mcp-session-id");
18
- const namespace = headerValue(context.headers, "x-engram-namespace") || "codex";
18
+ const namespaceHeader = headerValue(context.headers, "x-engram-namespace");
19
19
  return {
20
- namespace,
20
+ namespace: namespaceHeader ?? "codex",
21
+ namespaceExplicit: namespaceHeader !== void 0,
21
22
  principal: "codex",
22
23
  sessionKey: mcpSessionId ?? context.sessionKey,
23
24
  adapterId: this.id
@@ -28,4 +29,4 @@ var CodexAdapter = class {
28
29
  export {
29
30
  CodexAdapter
30
31
  };
31
- //# sourceMappingURL=chunk-RSUYKGGZ.js.map
32
+ //# sourceMappingURL=chunk-7RKSJVOQ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapters/codex.ts"],"sourcesContent":["import { headerValue, type AdapterContext, type EngramAdapter, type ResolvedIdentity } from \"./types.js\";\n\n/**\n * Codex CLI adapter.\n *\n * Detection: Codex CLI sends clientInfo.name = \"codex-mcp-client\" and\n * clientInfo.title = \"Codex\" in the MCP initialize handshake. It does\n * NOT send agent names, session IDs, or project context automatically.\n *\n * For Streamable HTTP transport, Codex supports custom headers via\n * http_headers in ~/.codex/config.toml:\n * [mcp_servers.engram]\n * url = \"http://localhost:4318/mcp\"\n * http_headers = { \"X-Engram-Namespace\" = \"my-project\" }\n *\n * Principal overrides are intentionally handled only by the HTTP server's\n * trustPrincipalHeader gate. Adapters must not independently trust\n * X-Engram-Principal.\n *\n * Codex also sends a custom \"sandbox_state\" RPC notification after\n * init with sandbox policy info (read-only/writable paths).\n */\nexport class CodexAdapter implements EngramAdapter {\n readonly id = \"codex\";\n\n matches(context: AdapterContext): boolean {\n // Primary: MCP clientInfo from initialize handshake (exact match)\n if (context.clientInfo?.name === \"codex-mcp-client\") return true;\n\n // Also match on clientInfo name containing \"codex\" for forward compat\n const clientName = context.clientInfo?.name?.toLowerCase() ?? \"\";\n if (clientName.includes(\"codex\") && clientName !== \"codex-mcp-client\") return true;\n\n // Fallback: user-configured client identifier header\n const clientId = headerValue(context.headers, \"x-engram-client-id\");\n if (clientId?.toLowerCase() === \"codex\") return true;\n\n return false;\n }\n\n resolveIdentity(context: AdapterContext): ResolvedIdentity {\n // MCP session ID (standard MCP header, server-assigned)\n const mcpSessionId = headerValue(context.headers, \"mcp-session-id\");\n\n // Namespace: explicit header > default\n const namespace = headerValue(context.headers, \"x-engram-namespace\")\n || \"codex\";\n\n return {\n namespace,\n principal: \"codex\",\n sessionKey: mcpSessionId ?? context.sessionKey,\n adapterId: this.id,\n };\n }\n}\n"],"mappings":";;;;;AAsBO,IAAM,eAAN,MAA4C;AAAA,EACxC,KAAK;AAAA,EAEd,QAAQ,SAAkC;AAExC,QAAI,QAAQ,YAAY,SAAS,mBAAoB,QAAO;AAG5D,UAAM,aAAa,QAAQ,YAAY,MAAM,YAAY,KAAK;AAC9D,QAAI,WAAW,SAAS,OAAO,KAAK,eAAe,mBAAoB,QAAO;AAG9E,UAAM,WAAW,YAAY,QAAQ,SAAS,oBAAoB;AAClE,QAAI,UAAU,YAAY,MAAM,QAAS,QAAO;AAEhD,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,SAA2C;AAEzD,UAAM,eAAe,YAAY,QAAQ,SAAS,gBAAgB;AAGlE,UAAM,YAAY,YAAY,QAAQ,SAAS,oBAAoB,KAC9D;AAEL,WAAO;AAAA,MACL;AAAA,MACA,WAAW;AAAA,MACX,YAAY,gBAAgB,QAAQ;AAAA,MACpC,WAAW,KAAK;AAAA,IAClB;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/adapters/codex.ts"],"sourcesContent":["import { headerValue, type AdapterContext, type EngramAdapter, type ResolvedIdentity } from \"./types.js\";\n\n/**\n * Codex CLI adapter.\n *\n * Detection: Codex CLI sends clientInfo.name = \"codex-mcp-client\" and\n * clientInfo.title = \"Codex\" in the MCP initialize handshake. It does\n * NOT send agent names, session IDs, or project context automatically.\n *\n * For Streamable HTTP transport, Codex supports custom headers via\n * http_headers in ~/.codex/config.toml:\n * [mcp_servers.engram]\n * url = \"http://localhost:4318/mcp\"\n * http_headers = { \"X-Engram-Namespace\" = \"my-project\" }\n *\n * Principal overrides are intentionally handled only by the HTTP server's\n * trustPrincipalHeader gate. Adapters must not independently trust\n * X-Engram-Principal.\n *\n * Codex also sends a custom \"sandbox_state\" RPC notification after\n * init with sandbox policy info (read-only/writable paths).\n */\nexport class CodexAdapter implements EngramAdapter {\n readonly id = \"codex\";\n\n matches(context: AdapterContext): boolean {\n // Primary: MCP clientInfo from initialize handshake (exact match)\n if (context.clientInfo?.name === \"codex-mcp-client\") return true;\n\n // Also match on clientInfo name containing \"codex\" for forward compat\n const clientName = context.clientInfo?.name?.toLowerCase() ?? \"\";\n if (clientName.includes(\"codex\") && clientName !== \"codex-mcp-client\") return true;\n\n // Fallback: user-configured client identifier header\n const clientId = headerValue(context.headers, \"x-engram-client-id\");\n if (clientId?.toLowerCase() === \"codex\") return true;\n\n return false;\n }\n\n resolveIdentity(context: AdapterContext): ResolvedIdentity {\n // MCP session ID (standard MCP header, server-assigned)\n const mcpSessionId = headerValue(context.headers, \"mcp-session-id\");\n\n // Namespace: explicit header > default\n const namespaceHeader = headerValue(context.headers, \"x-engram-namespace\");\n\n return {\n namespace: namespaceHeader ?? \"codex\",\n namespaceExplicit: namespaceHeader !== undefined,\n principal: \"codex\",\n sessionKey: mcpSessionId ?? context.sessionKey,\n adapterId: this.id,\n };\n }\n}\n"],"mappings":";;;;;AAsBO,IAAM,eAAN,MAA4C;AAAA,EACxC,KAAK;AAAA,EAEd,QAAQ,SAAkC;AAExC,QAAI,QAAQ,YAAY,SAAS,mBAAoB,QAAO;AAG5D,UAAM,aAAa,QAAQ,YAAY,MAAM,YAAY,KAAK;AAC9D,QAAI,WAAW,SAAS,OAAO,KAAK,eAAe,mBAAoB,QAAO;AAG9E,UAAM,WAAW,YAAY,QAAQ,SAAS,oBAAoB;AAClE,QAAI,UAAU,YAAY,MAAM,QAAS,QAAO;AAEhD,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,SAA2C;AAEzD,UAAM,eAAe,YAAY,QAAQ,SAAS,gBAAgB;AAGlE,UAAM,kBAAkB,YAAY,QAAQ,SAAS,oBAAoB;AAEzE,WAAO;AAAA,MACL,WAAW,mBAAmB;AAAA,MAC9B,mBAAmB,oBAAoB;AAAA,MACvC,WAAW;AAAA,MACX,YAAY,gBAAgB,QAAQ;AAAA,MACpC,WAAW,KAAK;AAAA,IAClB;AAAA,EACF;AACF;","names":[]}
@@ -74,11 +74,11 @@ function globToRegExp(glob) {
74
74
  if (ch === "*") {
75
75
  if (glob[i + 1] === "*") {
76
76
  if (glob[i + 2] === "/") {
77
- source += "(?:.*/)?";
77
+ source += "(?:[\\s\\S]*/)?";
78
78
  i += 2;
79
79
  continue;
80
80
  }
81
- source += ".*";
81
+ source += "[\\s\\S]*";
82
82
  i += 1;
83
83
  continue;
84
84
  }
@@ -134,4 +134,4 @@ export {
134
134
  compileOfflineSyncExcludeGlobs,
135
135
  parseOfflineSyncExcludes
136
136
  };
137
- //# sourceMappingURL=chunk-4NSLQ7EU.js.map
137
+ //# sourceMappingURL=chunk-ANPRNTPT.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/offline-sync-exclude-globs.ts"],"sourcesContent":["// Issue #1786: node-local runtime state that each node rebuilds from synced\n// records. Pushing these wastes bandwidth, corrupts the remote's live state\n// dir, and trips the large-file push retry loop on a live SQLite database.\n// Extracted from offline-sync.ts (issue #1995) so the god-file line-count\n// ratchet does not grow when the list gains entries; behavior is unchanged.\n/**\n * Directory-name prefix for the transient plaintext staging dir the CLI offline\n * decrypt path (`offline-storage-io.ts`) creates under the memory root when it\n * must materialize a decrypted secure-store file before hashing/pushing (#2033\n * P1). Shared here so the hard-exclude glob below and the CLI's `mkdtemp` prefix\n * can never drift apart: a crash-orphaned staging dir must NEVER be enumerated\n * into an offline snapshot, or decrypted secure-store plaintext would leak into\n * the remote push.\n */\nexport const OFFLINE_DECRYPT_STAGING_DIR_PREFIX = \".remnic-offline-decrypt-\";\n\nexport const DEFAULT_OFFLINE_SYNC_EXCLUDE_GLOBS: readonly string[] = [\n // Leading `**/` matches zero or more segments, so each pattern covers both\n // the root `state/` dir AND per-namespace `namespaces/<ns>/state/` dirs\n // (Cursor review on PR #1793: multi-namespace deployments previously kept\n // pushing their namespaced live sqlite files).\n \"**/state/*.sqlite\",\n \"**/state/*.sqlite-*\",\n \"**/state/index_tags.json\",\n \"**/state/entity-mention-index.json\",\n \"**/state/memory-governance/runs/**\",\n // Rotated recall-impression archives (issue #1910). The active\n // recall_impressions.jsonl stays remote-authoritative; only the .1..N\n // archives and the .lock are node-local and never pushed/hashed.\n \"**/state/recall_impressions.jsonl.*\",\n // Durable recall-impression pending spill directory (issue #2033). Node-local:\n // an impression spills a per-event file here when its rotation lock cannot be\n // acquired, and the next lock holder folds them back into the synced active\n // recall_impressions.jsonl. The `.*` glob above matches the directory name but\n // not its children, so exclude the contents explicitly.\n \"**/state/recall_impressions.jsonl.pending.d/**\",\n // Durable lifecycle-append pending spill directory (issue #2033). Node-local:\n // an append spills a per-event file here when it cannot get the ledger lock,\n // and the next lock holder folds them back into the synced\n // memory-lifecycle-ledger.jsonl. Pushing them would duplicate rows remotely.\n // The offline-sync snapshot entrypoints drain this queue first (access-service\n // `drainPendingLifecycleForSync` -> `StorageManager.drainPendingMemoryLifecycleEventsForSync`),\n // aborting the snapshot when durable rows cannot be folded, so excluding the\n // dir never silently drops append-only lifecycle history (promotions/imports).\n \"**/state/memory-lifecycle-ledger.jsonl.pending.d/**\",\n // The active lifecycle ledger lock is node-local and must never be\n // transferred to another node during an offline snapshot.\n \"**/state/memory-lifecycle-ledger.jsonl.lock\",\n // Transient plaintext decrypt staging (issue #2033 P1). The CLI offline\n // decrypt path materializes a decrypted secure-store file under an owner-only\n // `<OFFLINE_DECRYPT_STAGING_DIR_PREFIX>*` dir before hashing/pushing, removing\n // it in a `finally`. A hard crash between create and cleanup would otherwise\n // let a later snapshot walk `<prefix>*/content` and push decrypted secure-store\n // plaintext to the remote. Exclude the dir and its contents unconditionally so\n // a crash-orphan can never be enumerated into a snapshot; the leading `**/`\n // matches the root-level dir (zero segments) and any nested placement.\n \"**/.remnic-offline-decrypt-*/**\",\n // Embedding-index transaction leftovers (issue #3146, PR #3148). The\n // identity-replacement backup (`embeddings.pre-replace.tmp`) can hold a\n // full obsolete generation and `embeddings.staging.tmp-*` holds a\n // partially staged one; both are node-local recovery state that must\n // never be enumerated into a snapshot. The demoted legacy recovery file\n // (`embeddings.json.pre-migration.tmp-*`) is likewise node-local.\n \"**/state/embeddings.pre-replace.tmp/**\",\n \"**/state/embeddings.staging.tmp-*/**\",\n \"**/state/embeddings.json.pre-migration.tmp-*\",\n \"**/namespaces/*/state/embeddings.pre-replace.tmp/**\",\n \"**/namespaces/*/state/embeddings.staging.tmp-*/**\",\n \"**/namespaces/*/state/embeddings.json.pre-migration.tmp-*\",\n];\n\n\nconst DEFAULT_OFFLINE_SYNC_EXCLUDE_REGEXPS: readonly RegExp[] =\n DEFAULT_OFFLINE_SYNC_EXCLUDE_GLOBS.map((glob) => globToRegExp(glob));\n\n/**\n * Precompiled-once default-exclude check for the snapshot enumeration hot\n * path (Kilo review, PR #1793). Moved here from offline-sync.ts with the\n * glob list so the two can never drift (issue #1995).\n */\nexport function matchesOfflineSyncDefaultExclude(relPosix: string): boolean {\n for (const regexp of DEFAULT_OFFLINE_SYNC_EXCLUDE_REGEXPS) {\n if (regexp.test(relPosix)) return true;\n }\n return false;\n}\n\nexport function globToRegExp(glob: string): RegExp {\n if (typeof glob !== \"string\" || glob.length === 0) {\n throw new Error(\"offlineSyncExcludes entry must be a non-empty string\");\n }\n if (glob.includes(\"\\0\")) {\n throw new Error(\"offlineSyncExcludes entry must not contain NUL bytes\");\n }\n let source = \"\";\n for (let i = 0; i < glob.length; i += 1) {\n const ch = glob[i];\n if (ch === \"*\") {\n if (glob[i + 1] === \"*\") {\n // `**` is cross-segment wherever it appears:\n // leading `**/` -> zero or more whole segments\n // `/**` at end -> everything under the directory\n // `a/**/b` -> any depth between segments\n // (Cursor review on PR #1793: trailing `scratch/**` must match\n // nested `scratch/a/b.md`, matching the offline-mode guide.)\n if (glob[i + 2] === \"/\") {\n source += \"(?:.*/)?\";\n i += 2;\n continue;\n }\n source += \".*\";\n i += 1;\n continue;\n }\n source += \"[^/]*\";\n continue;\n }\n if (ch === \"?\") {\n source += \"[^/]\";\n continue;\n }\n if (ch === \"/\") {\n source += \"/\";\n continue;\n }\n source += ch.replace(/[\\\\^$.+()|{}\\[\\]]/g, \"\\\\$&\");\n }\n return new RegExp(`^${source}$`);\n}\n\nexport function compileOfflineSyncExcludeGlobs(\n globs: readonly unknown[],\n): RegExp[] {\n const out: RegExp[] = [];\n for (const entry of globs) {\n if (typeof entry !== \"string\" || entry.length === 0) {\n throw new Error(\"offlineSyncExcludes must contain only non-empty strings\");\n }\n out.push(globToRegExp(entry));\n }\n return out;\n}\n\n/**\n * Validate the operator-supplied offline-sync exclude list (#1786).\n * Rejects loudly instead of silently defaulting (CLAUDE.md rule 39):\n * a misspelled key value must fail config parse, not be ignored.\n * Lives next to the glob compiler so config.ts only carries the call.\n */\nexport function parseOfflineSyncExcludes(raw: unknown): string[] {\n if (raw === undefined || raw === null) return [];\n if (!Array.isArray(raw)) {\n throw new Error(\n `offlineSyncExcludes must be an array of non-empty glob strings; got ${typeof raw}`,\n );\n }\n for (const entry of raw) {\n if (typeof entry !== \"string\" || entry.trim().length === 0) {\n throw new Error(\n \"offlineSyncExcludes must contain only non-empty glob strings\",\n );\n }\n }\n const globs = raw.map((entry) => (entry as string).trim());\n // Compile-check every glob now so a bad pattern fails at parse time\n // rather than mid-sync. compileOfflineSyncExcludeGlobs throws with a\n // per-entry message.\n compileOfflineSyncExcludeGlobs(globs);\n return globs;\n}\n"],"mappings":";AAcO,IAAM,qCAAqC;AAE3C,IAAM,qCAAwD;AAAA;AAAA;AAAA;AAAA;AAAA,EAKnE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA;AAAA;AAAA,EAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,IAAM,uCACJ,mCAAmC,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC;AAO9D,SAAS,iCAAiC,UAA2B;AAC1E,aAAW,UAAU,sCAAsC;AACzD,QAAI,OAAO,KAAK,QAAQ,EAAG,QAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEO,SAAS,aAAa,MAAsB;AACjD,MAAI,OAAO,SAAS,YAAY,KAAK,WAAW,GAAG;AACjD,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACA,MAAI,KAAK,SAAS,IAAI,GAAG;AACvB,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACA,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,UAAM,KAAK,KAAK,CAAC;AACjB,QAAI,OAAO,KAAK;AACd,UAAI,KAAK,IAAI,CAAC,MAAM,KAAK;AAOvB,YAAI,KAAK,IAAI,CAAC,MAAM,KAAK;AACvB,oBAAU;AACV,eAAK;AACL;AAAA,QACF;AACA,kBAAU;AACV,aAAK;AACL;AAAA,MACF;AACA,gBAAU;AACV;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,gBAAU;AACV;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,gBAAU;AACV;AAAA,IACF;AACA,cAAU,GAAG,QAAQ,sBAAsB,MAAM;AAAA,EACnD;AACA,SAAO,IAAI,OAAO,IAAI,MAAM,GAAG;AACjC;AAEO,SAAS,+BACd,OACU;AACV,QAAM,MAAgB,CAAC;AACvB,aAAW,SAAS,OAAO;AACzB,QAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;AACnD,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC3E;AACA,QAAI,KAAK,aAAa,KAAK,CAAC;AAAA,EAC9B;AACA,SAAO;AACT;AAQO,SAAS,yBAAyB,KAAwB;AAC/D,MAAI,QAAQ,UAAa,QAAQ,KAAM,QAAO,CAAC;AAC/C,MAAI,CAAC,MAAM,QAAQ,GAAG,GAAG;AACvB,UAAM,IAAI;AAAA,MACR,uEAAuE,OAAO,GAAG;AAAA,IACnF;AAAA,EACF;AACA,aAAW,SAAS,KAAK;AACvB,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,WAAW,GAAG;AAC1D,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,IAAI,CAAC,UAAW,MAAiB,KAAK,CAAC;AAIzD,iCAA+B,KAAK;AACpC,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../src/offline-sync-exclude-globs.ts"],"sourcesContent":["// Issue #1786: node-local runtime state that each node rebuilds from synced\n// records. Pushing these wastes bandwidth, corrupts the remote's live state\n// dir, and trips the large-file push retry loop on a live SQLite database.\n// Extracted from offline-sync.ts (issue #1995) so the god-file line-count\n// ratchet does not grow when the list gains entries; behavior is unchanged.\n/**\n * Directory-name prefix for the transient plaintext staging dir the CLI offline\n * decrypt path (`offline-storage-io.ts`) creates under the memory root when it\n * must materialize a decrypted secure-store file before hashing/pushing (#2033\n * P1). Shared here so the hard-exclude glob below and the CLI's `mkdtemp` prefix\n * can never drift apart: a crash-orphaned staging dir must NEVER be enumerated\n * into an offline snapshot, or decrypted secure-store plaintext would leak into\n * the remote push.\n */\nexport const OFFLINE_DECRYPT_STAGING_DIR_PREFIX = \".remnic-offline-decrypt-\";\n\nexport const DEFAULT_OFFLINE_SYNC_EXCLUDE_GLOBS: readonly string[] = [\n // Leading `**/` matches zero or more segments, so each pattern covers both\n // the root `state/` dir AND per-namespace `namespaces/<ns>/state/` dirs\n // (Cursor review on PR #1793: multi-namespace deployments previously kept\n // pushing their namespaced live sqlite files).\n \"**/state/*.sqlite\",\n \"**/state/*.sqlite-*\",\n \"**/state/index_tags.json\",\n \"**/state/entity-mention-index.json\",\n \"**/state/memory-governance/runs/**\",\n // Rotated recall-impression archives (issue #1910). The active\n // recall_impressions.jsonl stays remote-authoritative; only the .1..N\n // archives and the .lock are node-local and never pushed/hashed.\n \"**/state/recall_impressions.jsonl.*\",\n // Durable recall-impression pending spill directory (issue #2033). Node-local:\n // an impression spills a per-event file here when its rotation lock cannot be\n // acquired, and the next lock holder folds them back into the synced active\n // recall_impressions.jsonl. The `.*` glob above matches the directory name but\n // not its children, so exclude the contents explicitly.\n \"**/state/recall_impressions.jsonl.pending.d/**\",\n // Durable lifecycle-append pending spill directory (issue #2033). Node-local:\n // an append spills a per-event file here when it cannot get the ledger lock,\n // and the next lock holder folds them back into the synced\n // memory-lifecycle-ledger.jsonl. Pushing them would duplicate rows remotely.\n // The offline-sync snapshot entrypoints drain this queue first (access-service\n // `drainPendingLifecycleForSync` -> `StorageManager.drainPendingMemoryLifecycleEventsForSync`),\n // aborting the snapshot when durable rows cannot be folded, so excluding the\n // dir never silently drops append-only lifecycle history (promotions/imports).\n \"**/state/memory-lifecycle-ledger.jsonl.pending.d/**\",\n // The active lifecycle ledger lock is node-local and must never be\n // transferred to another node during an offline snapshot.\n \"**/state/memory-lifecycle-ledger.jsonl.lock\",\n // Transient plaintext decrypt staging (issue #2033 P1). The CLI offline\n // decrypt path materializes a decrypted secure-store file under an owner-only\n // `<OFFLINE_DECRYPT_STAGING_DIR_PREFIX>*` dir before hashing/pushing, removing\n // it in a `finally`. A hard crash between create and cleanup would otherwise\n // let a later snapshot walk `<prefix>*/content` and push decrypted secure-store\n // plaintext to the remote. Exclude the dir and its contents unconditionally so\n // a crash-orphan can never be enumerated into a snapshot; the leading `**/`\n // matches the root-level dir (zero segments) and any nested placement.\n \"**/.remnic-offline-decrypt-*/**\",\n // Embedding-index transaction leftovers (issue #3146, PR #3148). The\n // identity-replacement backup (`embeddings.pre-replace.tmp`) can hold a\n // full obsolete generation and `embeddings.staging.tmp-*` holds a\n // partially staged one; both are node-local recovery state that must\n // never be enumerated into a snapshot. The demoted legacy recovery file\n // (`embeddings.json.pre-migration.tmp-*`) is likewise node-local.\n \"**/state/embeddings.pre-replace.tmp/**\",\n \"**/state/embeddings.staging.tmp-*/**\",\n \"**/state/embeddings.json.pre-migration.tmp-*\",\n \"**/namespaces/*/state/embeddings.pre-replace.tmp/**\",\n \"**/namespaces/*/state/embeddings.staging.tmp-*/**\",\n \"**/namespaces/*/state/embeddings.json.pre-migration.tmp-*\",\n];\n\n\nconst DEFAULT_OFFLINE_SYNC_EXCLUDE_REGEXPS: readonly RegExp[] =\n DEFAULT_OFFLINE_SYNC_EXCLUDE_GLOBS.map((glob) => globToRegExp(glob));\n\n/**\n * Precompiled-once default-exclude check for the snapshot enumeration hot\n * path (Kilo review, PR #1793). Moved here from offline-sync.ts with the\n * glob list so the two can never drift (issue #1995).\n */\nexport function matchesOfflineSyncDefaultExclude(relPosix: string): boolean {\n for (const regexp of DEFAULT_OFFLINE_SYNC_EXCLUDE_REGEXPS) {\n if (regexp.test(relPosix)) return true;\n }\n return false;\n}\n\nexport function globToRegExp(glob: string): RegExp {\n if (typeof glob !== \"string\" || glob.length === 0) {\n throw new Error(\"offlineSyncExcludes entry must be a non-empty string\");\n }\n if (glob.includes(\"\\0\")) {\n throw new Error(\"offlineSyncExcludes entry must not contain NUL bytes\");\n }\n let source = \"\";\n for (let i = 0; i < glob.length; i += 1) {\n const ch = glob[i];\n if (ch === \"*\") {\n if (glob[i + 1] === \"*\") {\n // `**` is cross-segment wherever it appears:\n // leading `**/` -> zero or more whole segments\n // `/**` at end -> everything under the directory\n // `a/**/b` -> any depth between segments\n // (Cursor review on PR #1793: trailing `scratch/**` must match\n // nested `scratch/a/b.md`, matching the offline-mode guide.)\n if (glob[i + 2] === \"/\") {\n source += \"(?:[\\\\s\\\\S]*/)?\";\n i += 2;\n continue;\n }\n source += \"[\\\\s\\\\S]*\";\n i += 1;\n continue;\n }\n source += \"[^/]*\";\n continue;\n }\n if (ch === \"?\") {\n source += \"[^/]\";\n continue;\n }\n if (ch === \"/\") {\n source += \"/\";\n continue;\n }\n source += ch.replace(/[\\\\^$.+()|{}\\[\\]]/g, \"\\\\$&\");\n }\n return new RegExp(`^${source}$`);\n}\n\n/** Match relative POSIX paths: `*` stays within a segment; `**` crosses separators and matches every path alone. */\nexport function compileOfflineSyncExcludeGlobs(\n globs: readonly unknown[],\n): RegExp[] {\n const out: RegExp[] = [];\n for (const entry of globs) {\n if (typeof entry !== \"string\" || entry.length === 0) {\n throw new Error(\"offlineSyncExcludes must contain only non-empty strings\");\n }\n out.push(globToRegExp(entry));\n }\n return out;\n}\n\n/**\n * Validate the operator-supplied offline-sync exclude list (#1786).\n * Rejects loudly instead of silently defaulting (CLAUDE.md rule 39):\n * a misspelled key value must fail config parse, not be ignored.\n * Lives next to the glob compiler so config.ts only carries the call.\n */\nexport function parseOfflineSyncExcludes(raw: unknown): string[] {\n if (raw === undefined || raw === null) return [];\n if (!Array.isArray(raw)) {\n throw new Error(\n `offlineSyncExcludes must be an array of non-empty glob strings; got ${typeof raw}`,\n );\n }\n for (const entry of raw) {\n if (typeof entry !== \"string\" || entry.trim().length === 0) {\n throw new Error(\n \"offlineSyncExcludes must contain only non-empty glob strings\",\n );\n }\n }\n const globs = raw.map((entry) => (entry as string).trim());\n // Compile-check every glob now so a bad pattern fails at parse time\n // rather than mid-sync. compileOfflineSyncExcludeGlobs throws with a\n // per-entry message.\n compileOfflineSyncExcludeGlobs(globs);\n return globs;\n}\n"],"mappings":";AAcO,IAAM,qCAAqC;AAE3C,IAAM,qCAAwD;AAAA;AAAA;AAAA;AAAA;AAAA,EAKnE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA;AAAA;AAAA,EAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,IAAM,uCACJ,mCAAmC,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC;AAO9D,SAAS,iCAAiC,UAA2B;AAC1E,aAAW,UAAU,sCAAsC;AACzD,QAAI,OAAO,KAAK,QAAQ,EAAG,QAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEO,SAAS,aAAa,MAAsB;AACjD,MAAI,OAAO,SAAS,YAAY,KAAK,WAAW,GAAG;AACjD,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACA,MAAI,KAAK,SAAS,IAAI,GAAG;AACvB,UAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AACA,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,UAAM,KAAK,KAAK,CAAC;AACjB,QAAI,OAAO,KAAK;AACd,UAAI,KAAK,IAAI,CAAC,MAAM,KAAK;AAOvB,YAAI,KAAK,IAAI,CAAC,MAAM,KAAK;AACvB,oBAAU;AACV,eAAK;AACL;AAAA,QACF;AACA,kBAAU;AACV,aAAK;AACL;AAAA,MACF;AACA,gBAAU;AACV;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,gBAAU;AACV;AAAA,IACF;AACA,QAAI,OAAO,KAAK;AACd,gBAAU;AACV;AAAA,IACF;AACA,cAAU,GAAG,QAAQ,sBAAsB,MAAM;AAAA,EACnD;AACA,SAAO,IAAI,OAAO,IAAI,MAAM,GAAG;AACjC;AAGO,SAAS,+BACd,OACU;AACV,QAAM,MAAgB,CAAC;AACvB,aAAW,SAAS,OAAO;AACzB,QAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;AACnD,YAAM,IAAI,MAAM,yDAAyD;AAAA,IAC3E;AACA,QAAI,KAAK,aAAa,KAAK,CAAC;AAAA,EAC9B;AACA,SAAO;AACT;AAQO,SAAS,yBAAyB,KAAwB;AAC/D,MAAI,QAAQ,UAAa,QAAQ,KAAM,QAAO,CAAC;AAC/C,MAAI,CAAC,MAAM,QAAQ,GAAG,GAAG;AACvB,UAAM,IAAI;AAAA,MACR,uEAAuE,OAAO,GAAG;AAAA,IACnF;AAAA,EACF;AACA,aAAW,SAAS,KAAK;AACvB,QAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,WAAW,GAAG;AAC1D,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,IAAI,CAAC,UAAW,MAAiB,KAAK,CAAC;AAIzD,iCAA+B,KAAK;AACpC,SAAO;AACT;","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-A7AISUJI.js";
4
4
  import {
5
5
  deepRecallRequestSchema
6
- } from "./chunk-3BTHXB7Z.js";
6
+ } from "./chunk-JAQXKNQV.js";
7
7
  import {
8
8
  EngramAccessInputError
9
9
  } from "./chunk-3MUKQQ7A.js";
@@ -40,4 +40,4 @@ async function respondDeepRecall(req, res, respondJson, readJsonBody, service, s
40
40
  export {
41
41
  respondDeepRecall
42
42
  };
43
- //# sourceMappingURL=chunk-6BG364RN.js.map
43
+ //# sourceMappingURL=chunk-AWEHMKIO.js.map
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-2JRB3Z5N.js";
12
12
  import {
13
13
  iterateOfflineSyncSnapshotFileRecords
14
- } from "./chunk-IVEHY2VT.js";
14
+ } from "./chunk-VQEOBVF2.js";
15
15
  import {
16
16
  createPersistedSupportPassportPrivateFileExclusion
17
17
  } from "./chunk-PWPIERBM.js";
@@ -250,4 +250,4 @@ export {
250
250
  retainExcludedClassifications,
251
251
  createOfflineSyncManifestStream
252
252
  };
253
- //# sourceMappingURL=chunk-AF5PW35O.js.map
253
+ //# sourceMappingURL=chunk-FQJ4YXJO.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  headerValue
3
- } from "./chunk-7RXCMVFQ.js";
3
+ } from "./chunk-NJAIR57U.js";
4
4
 
5
5
  // src/adapters/hermes.ts
6
6
  var HermesAdapter = class {
@@ -15,9 +15,10 @@ var HermesAdapter = class {
15
15
  }
16
16
  resolveIdentity(context) {
17
17
  const sessionId = headerValue(context.headers, "x-hermes-session-id");
18
- const namespace = headerValue(context.headers, "x-engram-namespace") || "hermes";
18
+ const namespaceHeader = headerValue(context.headers, "x-engram-namespace");
19
19
  return {
20
- namespace,
20
+ namespace: namespaceHeader ?? "hermes",
21
+ namespaceExplicit: namespaceHeader !== void 0,
21
22
  principal: "hermes-agent",
22
23
  sessionKey: sessionId ?? context.sessionKey,
23
24
  adapterId: this.id
@@ -28,4 +29,4 @@ var HermesAdapter = class {
28
29
  export {
29
30
  HermesAdapter
30
31
  };
31
- //# sourceMappingURL=chunk-42NQ7AVG.js.map
32
+ //# sourceMappingURL=chunk-HCAGBFE7.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/adapters/hermes.ts"],"sourcesContent":["import { headerValue, type AdapterContext, type EngramAdapter, type ResolvedIdentity } from \"./types.js\";\n\n/**\n * Hermes Agent adapter.\n *\n * Detection: Hermes supports both MCP (via config.yaml mcp_servers)\n * and a dedicated MemoryProvider plugin protocol (Python). The MCP\n * client name is not yet publicly documented, so detection uses:\n *\n * 1. X-Hermes-Session-Id header — confirmed in v0.7.0 API server\n * 2. User-configured headers in Hermes MCP config:\n * mcp_servers:\n * engram:\n * url: \"http://localhost:4318/mcp\"\n * headers:\n * X-Engram-Client-Id: \"hermes\"\n * X-Engram-Namespace: \"my-profile\"\n * 3. MCP clientInfo name containing \"hermes\" (for forward compat)\n *\n * Hermes profiles isolate agent state under ~/.hermes/profiles/<name>/.\n * Each profile can map to a separate Engram namespace via the\n * X-Engram-Namespace header.\n *\n * For deeper integration, Hermes v0.7.0+ supports MemoryProvider\n * plugins (Python protocol with initialize/enrich_turn/sync_turn/\n * shutdown). A Python Engram MemoryProvider plugin would be the\n * optimal integration path — see docs/integration/hermes-setup.md.\n */\nexport class HermesAdapter implements EngramAdapter {\n readonly id = \"hermes\";\n\n matches(context: AdapterContext): boolean {\n // Confirmed header from Hermes v0.7.0 API server\n if (headerValue(context.headers, \"x-hermes-session-id\")) return true;\n\n // User-configured client identifier header\n const clientId = headerValue(context.headers, \"x-engram-client-id\");\n if (clientId?.toLowerCase() === \"hermes\") return true;\n\n // MCP clientInfo (for forward compat when Hermes documents its name)\n const clientName = context.clientInfo?.name?.toLowerCase() ?? \"\";\n if (clientName.includes(\"hermes\")) return true;\n\n return false;\n }\n\n resolveIdentity(context: AdapterContext): ResolvedIdentity {\n const sessionId = headerValue(context.headers, \"x-hermes-session-id\");\n\n const namespace = headerValue(context.headers, \"x-engram-namespace\")\n || \"hermes\";\n\n return {\n namespace,\n principal: \"hermes-agent\",\n sessionKey: sessionId ?? context.sessionKey,\n adapterId: this.id,\n };\n }\n}\n"],"mappings":";;;;;AA4BO,IAAM,gBAAN,MAA6C;AAAA,EACzC,KAAK;AAAA,EAEd,QAAQ,SAAkC;AAExC,QAAI,YAAY,QAAQ,SAAS,qBAAqB,EAAG,QAAO;AAGhE,UAAM,WAAW,YAAY,QAAQ,SAAS,oBAAoB;AAClE,QAAI,UAAU,YAAY,MAAM,SAAU,QAAO;AAGjD,UAAM,aAAa,QAAQ,YAAY,MAAM,YAAY,KAAK;AAC9D,QAAI,WAAW,SAAS,QAAQ,EAAG,QAAO;AAE1C,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,SAA2C;AACzD,UAAM,YAAY,YAAY,QAAQ,SAAS,qBAAqB;AAEpE,UAAM,YAAY,YAAY,QAAQ,SAAS,oBAAoB,KAC9D;AAEL,WAAO;AAAA,MACL;AAAA,MACA,WAAW;AAAA,MACX,YAAY,aAAa,QAAQ;AAAA,MACjC,WAAW,KAAK;AAAA,IAClB;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/adapters/hermes.ts"],"sourcesContent":["import { headerValue, type AdapterContext, type EngramAdapter, type ResolvedIdentity } from \"./types.js\";\n\n/**\n * Hermes Agent adapter.\n *\n * Detection: Hermes supports both MCP (via config.yaml mcp_servers)\n * and a dedicated MemoryProvider plugin protocol (Python). The MCP\n * client name is not yet publicly documented, so detection uses:\n *\n * 1. X-Hermes-Session-Id header — confirmed in v0.7.0 API server\n * 2. User-configured headers in Hermes MCP config:\n * mcp_servers:\n * engram:\n * url: \"http://localhost:4318/mcp\"\n * headers:\n * X-Engram-Client-Id: \"hermes\"\n * X-Engram-Namespace: \"my-profile\"\n * 3. MCP clientInfo name containing \"hermes\" (for forward compat)\n *\n * Hermes profiles isolate agent state under ~/.hermes/profiles/<name>/.\n * Each profile can map to a separate Engram namespace via the\n * X-Engram-Namespace header.\n *\n * For deeper integration, Hermes v0.7.0+ supports MemoryProvider\n * plugins (Python protocol with initialize/enrich_turn/sync_turn/\n * shutdown). A Python Engram MemoryProvider plugin would be the\n * optimal integration path — see docs/integration/hermes-setup.md.\n */\nexport class HermesAdapter implements EngramAdapter {\n readonly id = \"hermes\";\n\n matches(context: AdapterContext): boolean {\n // Confirmed header from Hermes v0.7.0 API server\n if (headerValue(context.headers, \"x-hermes-session-id\")) return true;\n\n // User-configured client identifier header\n const clientId = headerValue(context.headers, \"x-engram-client-id\");\n if (clientId?.toLowerCase() === \"hermes\") return true;\n\n // MCP clientInfo (for forward compat when Hermes documents its name)\n const clientName = context.clientInfo?.name?.toLowerCase() ?? \"\";\n if (clientName.includes(\"hermes\")) return true;\n\n return false;\n }\n\n resolveIdentity(context: AdapterContext): ResolvedIdentity {\n const sessionId = headerValue(context.headers, \"x-hermes-session-id\");\n\n const namespaceHeader = headerValue(context.headers, \"x-engram-namespace\");\n\n return {\n namespace: namespaceHeader ?? \"hermes\",\n namespaceExplicit: namespaceHeader !== undefined,\n principal: \"hermes-agent\",\n sessionKey: sessionId ?? context.sessionKey,\n adapterId: this.id,\n };\n }\n}\n"],"mappings":";;;;;AA4BO,IAAM,gBAAN,MAA6C;AAAA,EACzC,KAAK;AAAA,EAEd,QAAQ,SAAkC;AAExC,QAAI,YAAY,QAAQ,SAAS,qBAAqB,EAAG,QAAO;AAGhE,UAAM,WAAW,YAAY,QAAQ,SAAS,oBAAoB;AAClE,QAAI,UAAU,YAAY,MAAM,SAAU,QAAO;AAGjD,UAAM,aAAa,QAAQ,YAAY,MAAM,YAAY,KAAK;AAC9D,QAAI,WAAW,SAAS,QAAQ,EAAG,QAAO;AAE1C,WAAO;AAAA,EACT;AAAA,EAEA,gBAAgB,SAA2C;AACzD,UAAM,YAAY,YAAY,QAAQ,SAAS,qBAAqB;AAEpE,UAAM,kBAAkB,YAAY,QAAQ,SAAS,oBAAoB;AAEzE,WAAO;AAAA,MACL,WAAW,mBAAmB;AAAA,MAC9B,mBAAmB,oBAAoB;AAAA,MACvC,WAAW;AAAA,MACX,YAAY,aAAa,QAAQ;AAAA,MACjC,WAAW,KAAK;AAAA,IAClB;AAAA,EACF;AACF;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SUPPORT_PASSPORT_DRAFT_MAX_CONTENT_CHARACTERS,
3
3
  SUPPORT_PASSPORT_DRAFT_MAX_MEMORIES
4
- } from "./chunk-GXETU7AE.js";
4
+ } from "./chunk-QVYXXOTR.js";
5
5
  import {
6
6
  SUPPORT_PASSPORT_SOURCE_MEMORY_ID_MAX_LENGTH
7
7
  } from "./chunk-PWPIERBM.js";
@@ -343,4 +343,4 @@ export {
343
343
  parseSupportPassportModelJob,
344
344
  SupportPassportModelBridge
345
345
  };
346
- //# sourceMappingURL=chunk-KYOZ5E6V.js.map
346
+ //# sourceMappingURL=chunk-HDOWMJKD.js.map
@@ -46,7 +46,7 @@ import {
46
46
  } from "./chunk-2FLFJTCI.js";
47
47
  import {
48
48
  getOperation
49
- } from "./chunk-GXETU7AE.js";
49
+ } from "./chunk-QVYXXOTR.js";
50
50
  import {
51
51
  WHO_KNOWS_MCP_TOOLS
52
52
  } from "./chunk-VBNA2JEN.js";
@@ -55,7 +55,7 @@ import {
55
55
  } from "./chunk-PO7NXNGC.js";
56
56
  import {
57
57
  validateRequest
58
- } from "./chunk-3BTHXB7Z.js";
58
+ } from "./chunk-JAQXKNQV.js";
59
59
  import {
60
60
  assertOperationAllowed,
61
61
  capabilityAllowsOp,
@@ -4023,4 +4023,4 @@ export {
4023
4023
  MCP_MIGRATED_OPERATIONS,
4024
4024
  EngramMcpServer
4025
4025
  };
4026
- //# sourceMappingURL=chunk-ANGZWYL2.js.map
4026
+ //# sourceMappingURL=chunk-I7BRU753.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineOperation
3
- } from "./chunk-GXETU7AE.js";
3
+ } from "./chunk-QVYXXOTR.js";
4
4
  import {
5
5
  EngramAccessInputError
6
6
  } from "./chunk-3MUKQQ7A.js";
@@ -92,4 +92,4 @@ defineOperation({
92
92
  };
93
93
  }
94
94
  });
95
- //# sourceMappingURL=chunk-MZAH3CBT.js.map
95
+ //# sourceMappingURL=chunk-IKWD4VP7.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-V7IZKJI3.js";
4
4
  import {
5
5
  AdapterRegistry
6
- } from "./chunk-F23U5YE7.js";
6
+ } from "./chunk-2KB7TTAP.js";
7
7
  import {
8
8
  WriteRateLimiter
9
9
  } from "./chunk-TB6CBZ5V.js";
@@ -18,13 +18,13 @@ import {
18
18
  } from "./chunk-3HSRWJTC.js";
19
19
  import {
20
20
  respondDeepRecall
21
- } from "./chunk-6BG364RN.js";
21
+ } from "./chunk-AWEHMKIO.js";
22
22
  import {
23
23
  handleSupportPassportOwnerHttp
24
- } from "./chunk-ZQTYWSO3.js";
24
+ } from "./chunk-ZNEA255W.js";
25
25
  import {
26
26
  buildSupportPassportPublicRequestHandler
27
- } from "./chunk-VOZNBQNL.js";
27
+ } from "./chunk-LBU623X7.js";
28
28
  import {
29
29
  handleMcpGetSse
30
30
  } from "./chunk-SRT6SHVZ.js";
@@ -37,10 +37,10 @@ import {
37
37
  processChatMessage,
38
38
  sessionBelongsToPrincipal,
39
39
  subscribeChatTranscript
40
- } from "./chunk-ANGZWYL2.js";
40
+ } from "./chunk-I7BRU753.js";
41
41
  import {
42
42
  RelayMissionStoreError
43
- } from "./chunk-P62DSJUK.js";
43
+ } from "./chunk-3RMJLDMS.js";
44
44
  import {
45
45
  executeResolution,
46
46
  isValidResolutionVerb
@@ -64,7 +64,7 @@ import {
64
64
  } from "./chunk-BCGMG2RD.js";
65
65
  import {
66
66
  respondBriefingHttp
67
- } from "./chunk-NSKXRTVZ.js";
67
+ } from "./chunk-ST4IBSPL.js";
68
68
  import {
69
69
  maybeHandleLifecycleFlush
70
70
  } from "./chunk-2BPPGNAQ.js";
@@ -75,11 +75,11 @@ import {
75
75
  authorizationProbeNamespaces,
76
76
  authorizationProbeRequiresPrincipalNamespace,
77
77
  probeOperationAuthorization
78
- } from "./chunk-YHZWVDP7.js";
78
+ } from "./chunk-YHDA3DSO.js";
79
79
  import {
80
80
  getOperation,
81
81
  resolveQueryNamespaceWritablePreflight
82
- } from "./chunk-GXETU7AE.js";
82
+ } from "./chunk-QVYXXOTR.js";
83
83
  import {
84
84
  handleWhoKnowsHttpQuery
85
85
  } from "./chunk-VBNA2JEN.js";
@@ -94,7 +94,7 @@ import {
94
94
  } from "./chunk-QLK3SL7Q.js";
95
95
  import {
96
96
  validateRequest
97
- } from "./chunk-3BTHXB7Z.js";
97
+ } from "./chunk-JAQXKNQV.js";
98
98
  import {
99
99
  peerManifestRevision
100
100
  } from "./chunk-N7QV3CMX.js";
@@ -109,7 +109,7 @@ import {
109
109
  OFFLINE_SYNC_APPLY_MAX_BODY_BYTES,
110
110
  OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES,
111
111
  OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES
112
- } from "./chunk-IVEHY2VT.js";
112
+ } from "./chunk-VQEOBVF2.js";
113
113
  import {
114
114
  isDefaultReviewNamespace,
115
115
  listPairs,
@@ -118,6 +118,9 @@ import {
118
118
  import {
119
119
  isRecallDisclosure
120
120
  } from "./chunk-RKDSELA3.js";
121
+ import {
122
+ resolveNamespaceCapabilities
123
+ } from "./chunk-2EMROIXS.js";
121
124
  import {
122
125
  projectTagProjectId
123
126
  } from "./chunk-3Q3N35W7.js";
@@ -1071,6 +1074,10 @@ var EngramAccessHttpServer = class extends ReviewDeckAccessHttpBase {
1071
1074
  principal = adapterIdentity.principal;
1072
1075
  }
1073
1076
  namespace = adapterIdentity.namespace;
1077
+ const config = this.service.configRef;
1078
+ if (adapterIdentity.namespaceExplicit === false && !(config && resolveNamespaceCapabilities(config).namespaces)) {
1079
+ namespace = void 0;
1080
+ }
1074
1081
  sessionKey = adapterIdentity.sessionKey;
1075
1082
  }
1076
1083
  const result = { principal, namespace, sessionKey };
@@ -3557,4 +3564,4 @@ export {
3557
3564
  resolveDefaultAdminConsolePublicDir,
3558
3565
  EngramAccessHttpServer
3559
3566
  };
3560
- //# sourceMappingURL=chunk-HQCUUVG2.js.map
3567
+ //# sourceMappingURL=chunk-J3GJ23IP.js.map