@remnic/core 1.1.13 → 1.1.15

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 (130) hide show
  1. package/dist/access-cli.js +34 -33
  2. package/dist/access-cli.js.map +1 -1
  3. package/dist/access-http.d.ts +2 -1
  4. package/dist/access-http.js +15 -14
  5. package/dist/access-mcp.d.ts +2 -1
  6. package/dist/access-mcp.js +14 -13
  7. package/dist/access-schema.d.ts +22 -5
  8. package/dist/access-schema.js +7 -5
  9. package/dist/{access-service-DcCDmNYC.d.ts → access-service-BCMine1s.d.ts} +21 -1
  10. package/dist/access-service.d.ts +2 -1
  11. package/dist/access-service.js +12 -11
  12. package/dist/briefing.js +4 -4
  13. package/dist/causal-consolidation.js +5 -5
  14. package/dist/{chunk-VNO6ZJ35.js → chunk-2PRLKQAH.js} +5 -5
  15. package/dist/{chunk-M23FSH32.js → chunk-5D2G67ZQ.js} +53 -6
  16. package/dist/chunk-5D2G67ZQ.js.map +1 -0
  17. package/dist/{chunk-EFJ3MQ4V.js → chunk-65HQPW6O.js} +2 -2
  18. package/dist/{chunk-GA454ALV.js → chunk-AAX3SUM3.js} +39 -39
  19. package/dist/{chunk-QQUAB63I.js → chunk-BEB4GUU5.js} +2 -2
  20. package/dist/{chunk-WZYKANL3.js → chunk-BNATB54A.js} +4 -4
  21. package/dist/{chunk-KUJVMMZQ.js → chunk-C7DGCHJE.js} +2 -2
  22. package/dist/{chunk-PR5FBTFU.js → chunk-CYFQJMUV.js} +5 -5
  23. package/dist/{chunk-KLAO5DGL.js → chunk-G7JBLD65.js} +3 -3
  24. package/dist/chunk-GSP6ZKOY.js +769 -0
  25. package/dist/chunk-GSP6ZKOY.js.map +1 -0
  26. package/dist/{chunk-CQZRLNMV.js → chunk-HJ2WMBFB.js} +42 -4
  27. package/dist/chunk-HJ2WMBFB.js.map +1 -0
  28. package/dist/{chunk-ME6ESPZU.js → chunk-IG5VGHYB.js} +2 -2
  29. package/dist/{chunk-7AAT6G4Q.js → chunk-IOAY54RF.js} +57 -5
  30. package/dist/chunk-IOAY54RF.js.map +1 -0
  31. package/dist/{chunk-XVZ7B3HG.js → chunk-JFEH2LZM.js} +2 -2
  32. package/dist/{chunk-JLFA7DQG.js → chunk-M3AA636B.js} +2 -2
  33. package/dist/{chunk-P4NEIHUT.js → chunk-MS3ULOZF.js} +2 -2
  34. package/dist/{chunk-7IASACLB.js → chunk-NOHC2L57.js} +2 -2
  35. package/dist/{chunk-6RVI47ZR.js → chunk-NTUNYIF7.js} +5 -5
  36. package/dist/{chunk-CK5NTM2S.js → chunk-OGROP7ZN.js} +2 -2
  37. package/dist/{chunk-MT25YHYH.js → chunk-OJRKZLZ4.js} +5 -5
  38. package/dist/{chunk-2F2W355T.js → chunk-QA2ZAPBU.js} +4 -4
  39. package/dist/{chunk-MC26UJIM.js → chunk-QLKBF3TI.js} +2 -2
  40. package/dist/{chunk-YNJHCGDT.js → chunk-SH5S7XYD.js} +8 -5
  41. package/dist/chunk-SH5S7XYD.js.map +1 -0
  42. package/dist/{chunk-VW676BEI.js → chunk-V7WH7DEM.js} +2 -2
  43. package/dist/{chunk-A2XUIMJ3.js → chunk-VWFIQOTJ.js} +11 -2
  44. package/dist/chunk-VWFIQOTJ.js.map +1 -0
  45. package/dist/{chunk-PU63GXWS.js → chunk-W7DK3CYM.js} +2 -2
  46. package/dist/{chunk-TFO23QT4.js → chunk-XKLD5OK4.js} +4 -4
  47. package/dist/{chunk-I5V2VDIW.js → chunk-YCVWX2NF.js} +2 -2
  48. package/dist/{chunk-UXHQAFNA.js → chunk-ZPXYWTN5.js} +4 -4
  49. package/dist/{chunk-CHEL3SKB.js → chunk-ZYRMKWVW.js} +27 -27
  50. package/dist/{chunk-GGKRUQOO.js → chunk-ZYVPLJ4T.js} +4 -4
  51. package/dist/{cli-D3VpkVwB.d.ts → cli-B71zQ6XK.d.ts} +1 -1
  52. package/dist/cli.d.ts +3 -2
  53. package/dist/cli.js +35 -34
  54. package/dist/compounding/engine.js +4 -4
  55. package/dist/connectors/codex-materialize-runner.js +4 -4
  56. package/dist/connectors/index.js +4 -4
  57. package/dist/conversation-index/backend.js +2 -2
  58. package/dist/entity-retrieval.js +4 -4
  59. package/dist/index.d.ts +4 -3
  60. package/dist/index.js +90 -58
  61. package/dist/index.js.map +1 -1
  62. package/dist/lcm/engine.js +2 -2
  63. package/dist/lcm/index.js +5 -5
  64. package/dist/maintenance/memory-governance.js +4 -4
  65. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -4
  66. package/dist/maintenance/rebuild-memory-projection.js +5 -5
  67. package/dist/mcp-memory-inspector-app.d.ts +2 -1
  68. package/dist/namespaces/migrate.js +10 -10
  69. package/dist/namespaces/search.js +5 -5
  70. package/dist/namespaces/storage.js +4 -4
  71. package/dist/offline-sync.d.ts +136 -0
  72. package/dist/offline-sync.js +41 -0
  73. package/dist/offline-sync.js.map +1 -0
  74. package/dist/operator-toolkit.js +13 -13
  75. package/dist/orchestrator.js +24 -24
  76. package/dist/search/factory.js +4 -4
  77. package/dist/search/index.js +6 -6
  78. package/dist/secure-store/index.d.ts +1 -15
  79. package/dist/secure-store/index.js +2 -2
  80. package/dist/semantic-consolidation.js +5 -5
  81. package/dist/semantic-rule-promotion.js +4 -4
  82. package/dist/semantic-rule-verifier.js +4 -4
  83. package/dist/storage.d.ts +7 -0
  84. package/dist/storage.js +3 -3
  85. package/dist/transfer/backup.js +2 -2
  86. package/dist/transfer/capsule-export.js +4 -4
  87. package/dist/transfer/capsule-import.js +3 -3
  88. package/dist/transfer/import-sqlite.js +2 -2
  89. package/dist/verified-recall.js +4 -4
  90. package/package.json +1 -1
  91. package/src/access-http.test.ts +216 -0
  92. package/src/access-http.ts +54 -0
  93. package/src/access-schema.ts +18 -0
  94. package/src/access-service.ts +76 -0
  95. package/src/index.ts +33 -0
  96. package/src/offline-sync.test.ts +521 -0
  97. package/src/offline-sync.ts +998 -0
  98. package/src/qmd.test.ts +1 -0
  99. package/src/secure-store/secure-fs.ts +14 -7
  100. package/src/storage.ts +59 -0
  101. package/dist/chunk-7AAT6G4Q.js.map +0 -1
  102. package/dist/chunk-A2XUIMJ3.js.map +0 -1
  103. package/dist/chunk-CQZRLNMV.js.map +0 -1
  104. package/dist/chunk-M23FSH32.js.map +0 -1
  105. package/dist/chunk-YNJHCGDT.js.map +0 -1
  106. /package/dist/{chunk-VNO6ZJ35.js.map → chunk-2PRLKQAH.js.map} +0 -0
  107. /package/dist/{chunk-EFJ3MQ4V.js.map → chunk-65HQPW6O.js.map} +0 -0
  108. /package/dist/{chunk-GA454ALV.js.map → chunk-AAX3SUM3.js.map} +0 -0
  109. /package/dist/{chunk-QQUAB63I.js.map → chunk-BEB4GUU5.js.map} +0 -0
  110. /package/dist/{chunk-WZYKANL3.js.map → chunk-BNATB54A.js.map} +0 -0
  111. /package/dist/{chunk-KUJVMMZQ.js.map → chunk-C7DGCHJE.js.map} +0 -0
  112. /package/dist/{chunk-PR5FBTFU.js.map → chunk-CYFQJMUV.js.map} +0 -0
  113. /package/dist/{chunk-KLAO5DGL.js.map → chunk-G7JBLD65.js.map} +0 -0
  114. /package/dist/{chunk-ME6ESPZU.js.map → chunk-IG5VGHYB.js.map} +0 -0
  115. /package/dist/{chunk-XVZ7B3HG.js.map → chunk-JFEH2LZM.js.map} +0 -0
  116. /package/dist/{chunk-JLFA7DQG.js.map → chunk-M3AA636B.js.map} +0 -0
  117. /package/dist/{chunk-P4NEIHUT.js.map → chunk-MS3ULOZF.js.map} +0 -0
  118. /package/dist/{chunk-7IASACLB.js.map → chunk-NOHC2L57.js.map} +0 -0
  119. /package/dist/{chunk-6RVI47ZR.js.map → chunk-NTUNYIF7.js.map} +0 -0
  120. /package/dist/{chunk-CK5NTM2S.js.map → chunk-OGROP7ZN.js.map} +0 -0
  121. /package/dist/{chunk-MT25YHYH.js.map → chunk-OJRKZLZ4.js.map} +0 -0
  122. /package/dist/{chunk-2F2W355T.js.map → chunk-QA2ZAPBU.js.map} +0 -0
  123. /package/dist/{chunk-MC26UJIM.js.map → chunk-QLKBF3TI.js.map} +0 -0
  124. /package/dist/{chunk-VW676BEI.js.map → chunk-V7WH7DEM.js.map} +0 -0
  125. /package/dist/{chunk-PU63GXWS.js.map → chunk-W7DK3CYM.js.map} +0 -0
  126. /package/dist/{chunk-TFO23QT4.js.map → chunk-XKLD5OK4.js.map} +0 -0
  127. /package/dist/{chunk-I5V2VDIW.js.map → chunk-YCVWX2NF.js.map} +0 -0
  128. /package/dist/{chunk-UXHQAFNA.js.map → chunk-ZPXYWTN5.js.map} +0 -0
  129. /package/dist/{chunk-CHEL3SKB.js.map → chunk-ZYRMKWVW.js.map} +0 -0
  130. /package/dist/{chunk-GGKRUQOO.js.map → chunk-ZYVPLJ4T.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  StorageManager
3
- } from "./chunk-7AAT6G4Q.js";
3
+ } from "./chunk-IOAY54RF.js";
4
4
 
5
5
  // src/semantic-rule-promotion.ts
6
6
  function normalizeRuleWhitespace(value) {
@@ -132,4 +132,4 @@ async function promoteSemanticRuleFromMemory(options) {
132
132
  export {
133
133
  promoteSemanticRuleFromMemory
134
134
  };
135
- //# sourceMappingURL=chunk-XVZ7B3HG.js.map
135
+ //# sourceMappingURL=chunk-JFEH2LZM.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-KJTKLXTH.js";
4
4
  import {
5
5
  StorageManager
6
- } from "./chunk-7AAT6G4Q.js";
6
+ } from "./chunk-IOAY54RF.js";
7
7
  import {
8
8
  buildLifecycleEventsForMemory,
9
9
  sortMemoryLifecycleEvents
@@ -59,4 +59,4 @@ async function rebuildMemoryLifecycleLedger(options) {
59
59
  export {
60
60
  rebuildMemoryLifecycleLedger
61
61
  };
62
- //# sourceMappingURL=chunk-JLFA7DQG.js.map
62
+ //# sourceMappingURL=chunk-M3AA636B.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-NZL6GGQE.js";
4
4
  import {
5
5
  StorageManager
6
- } from "./chunk-7AAT6G4Q.js";
6
+ } from "./chunk-IOAY54RF.js";
7
7
  import {
8
8
  getCachedEpisodeMap,
9
9
  setCachedEpisodeMap
@@ -105,4 +105,4 @@ async function searchVerifiedEpisodes(options) {
105
105
  export {
106
106
  searchVerifiedEpisodes
107
107
  };
108
- //# sourceMappingURL=chunk-P4NEIHUT.js.map
108
+ //# sourceMappingURL=chunk-MS3ULOZF.js.map
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  compareEntityTimestamps,
6
6
  normalizeEntityName
7
- } from "./chunk-7AAT6G4Q.js";
7
+ } from "./chunk-IOAY54RF.js";
8
8
  import {
9
9
  sanitizeMemoryContent
10
10
  } from "./chunk-FVQJYWH7.js";
@@ -593,4 +593,4 @@ export {
593
593
  entityIndexVersion,
594
594
  entityRecentTranscriptLookbackHours
595
595
  };
596
- //# sourceMappingURL=chunk-7IASACLB.js.map
596
+ //# sourceMappingURL=chunk-NOHC2L57.js.map
@@ -1,3 +1,6 @@
1
+ import {
2
+ NoopSearchBackend
3
+ } from "./chunk-NJ3MJQZX.js";
1
4
  import {
2
5
  OramaBackend
3
6
  } from "./chunk-XVVIG67A.js";
@@ -13,12 +16,9 @@ import {
13
16
  import {
14
17
  MeilisearchBackend
15
18
  } from "./chunk-TMQLARTH.js";
16
- import {
17
- NoopSearchBackend
18
- } from "./chunk-NJ3MJQZX.js";
19
19
  import {
20
20
  createConversationIndexBackend
21
- } from "./chunk-PR5FBTFU.js";
21
+ } from "./chunk-CYFQJMUV.js";
22
22
  import {
23
23
  FaissConversationIndexAdapter
24
24
  } from "./chunk-FJ43PRLT.js";
@@ -156,4 +156,4 @@ export {
156
156
  createConversationSearchBackend,
157
157
  createConversationIndexRuntime
158
158
  };
159
- //# sourceMappingURL=chunk-6RVI47ZR.js.map
159
+ //# sourceMappingURL=chunk-NTUNYIF7.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  decryptMemoryDirToPlaintext,
3
3
  migrateMemoryDirToEncrypted
4
- } from "./chunk-YNJHCGDT.js";
4
+ } from "./chunk-SH5S7XYD.js";
5
5
  import {
6
6
  buildHeaderFromPassphrase,
7
7
  deriveKeyFromHeader,
@@ -451,4 +451,4 @@ export {
451
451
  renderStatusReport,
452
452
  createPassphraseReader
453
453
  };
454
- //# sourceMappingURL=chunk-CK5NTM2S.js.map
454
+ //# sourceMappingURL=chunk-OGROP7ZN.js.map
@@ -1,9 +1,9 @@
1
- import {
2
- namespaceCollectionName
3
- } from "./chunk-PU63GXWS.js";
4
1
  import {
5
2
  NamespaceStorageRouter
6
- } from "./chunk-QQUAB63I.js";
3
+ } from "./chunk-BEB4GUU5.js";
4
+ import {
5
+ namespaceCollectionName
6
+ } from "./chunk-W7DK3CYM.js";
7
7
  import {
8
8
  isSafeRouteNamespace
9
9
  } from "./chunk-U3PN77QT.js";
@@ -138,4 +138,4 @@ export {
138
138
  verifyNamespaces,
139
139
  runNamespaceMigration
140
140
  };
141
- //# sourceMappingURL=chunk-MT25YHYH.js.map
141
+ //# sourceMappingURL=chunk-OJRKZLZ4.js.map
@@ -1,12 +1,12 @@
1
- import {
2
- encryptCapsuleFile
3
- } from "./chunk-KNKUID7G.js";
4
1
  import {
5
2
  CAPSULE_ID_PATTERN,
6
3
  CapsuleBlockSchema,
7
4
  ExportBundleV2Schema,
8
5
  ExportManifestV2Schema
9
6
  } from "./chunk-WEHSQBFR.js";
7
+ import {
8
+ encryptCapsuleFile
9
+ } from "./chunk-KNKUID7G.js";
10
10
  import {
11
11
  CAPSULE_SCHEMA_VERSION,
12
12
  EXPORT_FORMAT
@@ -253,4 +253,4 @@ export {
253
253
  exportCapsule,
254
254
  isValidCapsuleSince
255
255
  };
256
- //# sourceMappingURL=chunk-2F2W355T.js.map
256
+ //# sourceMappingURL=chunk-QA2ZAPBU.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  StorageManager
3
- } from "./chunk-7AAT6G4Q.js";
3
+ } from "./chunk-IOAY54RF.js";
4
4
  import {
5
5
  getCachedRuleMemories,
6
6
  setCachedRuleMemories
@@ -115,4 +115,4 @@ async function searchVerifiedSemanticRules(options) {
115
115
  export {
116
116
  searchVerifiedSemanticRules
117
117
  };
118
- //# sourceMappingURL=chunk-MC26UJIM.js.map
118
+ //# sourceMappingURL=chunk-QLKBF3TI.js.map
@@ -69,10 +69,10 @@ function filePathAad(filePath, memoryDir) {
69
69
  }
70
70
  return Buffer.from(rel, "utf8");
71
71
  }
72
- async function readMaybeEncryptedFile(filePath, key, memoryDir) {
72
+ async function readMaybeEncryptedFileBuffer(filePath, key, memoryDir) {
73
73
  const buf = await readFile(filePath);
74
74
  if (!isEncryptedFile(buf)) {
75
- return buf.toString("utf8");
75
+ return buf;
76
76
  }
77
77
  if (key === null) {
78
78
  throw new SecureStoreLockedError(
@@ -80,8 +80,10 @@ async function readMaybeEncryptedFile(filePath, key, memoryDir) {
80
80
  );
81
81
  }
82
82
  const aad = filePathAad(filePath, memoryDir);
83
- const plain = decryptFileBody(buf, key, aad);
84
- return plain.toString("utf8");
83
+ return decryptFileBody(buf, key, aad);
84
+ }
85
+ async function readMaybeEncryptedFile(filePath, key, memoryDir) {
86
+ return (await readMaybeEncryptedFileBuffer(filePath, key, memoryDir)).toString("utf8");
85
87
  }
86
88
  async function writeMaybeEncryptedFile(filePath, content, key, options = {}, memoryDir) {
87
89
  const { mode = 384, atomic = true } = options;
@@ -301,9 +303,10 @@ export {
301
303
  encryptFileBody,
302
304
  decryptFileBody,
303
305
  filePathAad,
306
+ readMaybeEncryptedFileBuffer,
304
307
  readMaybeEncryptedFile,
305
308
  writeMaybeEncryptedFile,
306
309
  migrateMemoryDirToEncrypted,
307
310
  decryptMemoryDirToPlaintext
308
311
  };
309
- //# sourceMappingURL=chunk-YNJHCGDT.js.map
312
+ //# sourceMappingURL=chunk-SH5S7XYD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/secure-store/secure-fs.ts"],"sourcesContent":["/**\n * Transparent file-level encryption for the secure-store module.\n *\n * Issue #690 (PR 3/4) — storage.ts integration layer.\n *\n * This module sits between the raw filesystem and StorageManager.\n * Every memory file is either:\n * - a plain UTF-8 text file (legacy, back-compat), or\n * - a REMNIC-ENC sealed file (AES-256-GCM, see format below).\n *\n * On-disk format\n * --------------\n * Encrypted files begin with a 9-byte magic header:\n *\n * REMNIC-ENC (7 ASCII bytes)\n * VER (1 byte, currently 0x01)\n * FLAGS (1 byte, reserved, must be 0x00)\n *\n * Followed immediately by a `seal()` envelope from `cipher.ts`:\n *\n * [VERSION:1][SALT:16][IV:12][AUTHTAG:16][CIPHERTEXT:...]\n *\n * The magic header makes encrypted files sniffable without attempting\n * a full `open()` call and gives operators a clear signal that the\n * file cannot be read by opening it in an editor.\n *\n * AAD\n * ---\n * The file path relative to the memory root is bound as Associated\n * Authenticated Data (AAD) on both encrypt and decrypt. This means\n * moving or renaming an encrypted file without re-encrypting it will\n * cause auth-tag failure on the next read — the file is tied to its\n * path. Callers that move files must re-encrypt them.\n *\n * Back-compat\n * -----------\n * `readMaybeEncryptedFile` transparently handles both formats: if the\n * file does NOT start with the magic bytes, it is returned as-is (plain\n * text). This lets an operator migrate incrementally: newly-written\n * files are encrypted while existing files continue to be read in plain\n * form until `migrateMemoryDirToEncrypted` is run.\n *\n * Naming: `secure-fs.ts` (not `vault-fs.ts`) — see `kdf.ts` naming note.\n */\n\nimport { lstat, mkdir, readFile, readdir, rename, unlink, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { generateSalt, open, seal } from \"./cipher.js\";\n\n// ---------------------------------------------------------------------------\n// Error classes\n// ---------------------------------------------------------------------------\n\n/**\n * Thrown when a read is attempted but the keyring entry for this\n * store is absent (i.e. `secure-store unlock` has not been run\n * since the last daemon start).\n */\nexport class SecureStoreLockedError extends Error {\n constructor(message = \"secure-store is locked — run `remnic secure-store unlock` to decrypt\") {\n super(message);\n this.name = \"SecureStoreLockedError\";\n }\n}\n\n/**\n * Thrown when `open()` fails because the auth tag does not validate.\n * This covers both wrong-key and tampered-ciphertext scenarios —\n * intentionally indistinguishable from the caller's perspective.\n */\nexport class SecureStoreDecryptError extends Error {\n constructor(message = \"secure-store decryption failed — wrong key or tampered ciphertext\") {\n super(message);\n this.name = \"SecureStoreDecryptError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Magic header\n// ---------------------------------------------------------------------------\n\n/** Magic bytes: the ASCII string \"REMNIC-ENC\" (10 bytes). */\nexport const MAGIC_BYTES = Buffer.from(\"REMNIC-ENC\", \"ascii\");\n\n/** Current on-disk version byte. */\nexport const FILE_FORMAT_VERSION = 0x01;\n\n/** Reserved flags byte — must be 0x00. */\nexport const FILE_FORMAT_FLAGS = 0x00;\n\n/** Total size of the magic header prefix (magic + version + flags). */\nexport const MAGIC_HEADER_SIZE = MAGIC_BYTES.length + 2; // 12 bytes\n\n// ---------------------------------------------------------------------------\n// Detection\n// ---------------------------------------------------------------------------\n\n/**\n * Return true iff `buf` begins with the REMNIC-ENC magic header.\n * Does not validate the envelope; just identifies the format.\n */\nexport function isEncryptedFile(buf: Uint8Array): boolean {\n if (buf.length < MAGIC_HEADER_SIZE) return false;\n const b = Buffer.isBuffer(buf) ? buf : Buffer.from(buf);\n return b.subarray(0, MAGIC_BYTES.length).equals(MAGIC_BYTES);\n}\n\n// ---------------------------------------------------------------------------\n// Encrypt / decrypt file body\n// ---------------------------------------------------------------------------\n\n/**\n * Encrypt `plain` (UTF-8 content of a memory file) and return a\n * Buffer ready to write to disk.\n *\n * @param plain Plain-text file content (UTF-8 string or Buffer).\n * @param key 32-byte AES-256 key from the keyring.\n * @param aad Optional associated data — defaults to empty if omitted.\n * Callers should pass the file path relative to memoryDir\n * so the ciphertext is bound to its location.\n */\nexport function encryptFileBody(plain: string | Buffer, key: Buffer, aad?: Buffer): Buffer {\n const plainBuf = typeof plain === \"string\" ? Buffer.from(plain, \"utf8\") : plain;\n const salt = generateSalt();\n const envelope = seal(key, salt, plainBuf, aad ? { aad } : {});\n\n const header = Buffer.alloc(MAGIC_HEADER_SIZE);\n MAGIC_BYTES.copy(header, 0);\n header.writeUInt8(FILE_FORMAT_VERSION, MAGIC_BYTES.length);\n header.writeUInt8(FILE_FORMAT_FLAGS, MAGIC_BYTES.length + 1);\n\n return Buffer.concat([header, envelope]);\n}\n\n/**\n * Decrypt a buffer produced by `encryptFileBody` and return the\n * original UTF-8 content.\n *\n * Throws `SecureStoreDecryptError` on auth failure (wrong key or\n * tampered ciphertext). Throws a plain `Error` for structural problems\n * (truncated buffer, wrong magic, unsupported version).\n */\nexport function decryptFileBody(buf: Buffer, key: Buffer, aad?: Buffer): Buffer {\n if (!isEncryptedFile(buf)) {\n throw new Error(\"decryptFileBody: buffer does not start with REMNIC-ENC magic header\");\n }\n const version = buf.readUInt8(MAGIC_BYTES.length);\n if (version !== FILE_FORMAT_VERSION) {\n throw new Error(\n `decryptFileBody: unsupported file format version ${version} (this build supports ${FILE_FORMAT_VERSION})`,\n );\n }\n const flags = buf.readUInt8(MAGIC_BYTES.length + 1);\n if (flags !== FILE_FORMAT_FLAGS) {\n throw new Error(`decryptFileBody: unknown flags byte 0x${flags.toString(16).padStart(2, \"0\")}`);\n }\n const envelope = buf.subarray(MAGIC_HEADER_SIZE);\n try {\n return open(key, envelope, aad ? { aad } : {});\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new SecureStoreDecryptError(\n `secure-store decryption failed: ${msg}`,\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// Path → AAD helper\n// ---------------------------------------------------------------------------\n\n/**\n * Build the AAD buffer for a file at `filePath` relative to\n * `memoryDir`. The AAD binds the ciphertext to its path so a\n * file cannot be silently relocated without re-encryption.\n *\n * When `memoryDir` is supplied and `filePath` is absolute, the\n * relative sub-path is used. Otherwise `filePath` is used verbatim.\n */\nexport function filePathAad(filePath: string, memoryDir?: string): Buffer {\n let rel = filePath;\n if (memoryDir && path.isAbsolute(filePath)) {\n rel = path.relative(memoryDir, filePath);\n }\n return Buffer.from(rel, \"utf8\");\n}\n\n// ---------------------------------------------------------------------------\n// High-level read / write helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Read a file from `filePath`.\n *\n * - If the file is plaintext (no magic header), return its content\n * as-is — back-compat with unencrypted stores.\n * - If the file is encrypted AND `key` is provided, decrypt and return\n * the plaintext content.\n * - If the file is encrypted AND `key` is null, throw\n * `SecureStoreLockedError`.\n *\n * @param filePath Absolute path to the file.\n * @param key 32-byte AES-256 key, or null when the store is locked.\n * @param memoryDir Memory root for path-bound AAD. Should be absolute.\n */\nexport async function readMaybeEncryptedFileBuffer(\n filePath: string,\n key: Buffer | null,\n memoryDir?: string,\n): Promise<Buffer> {\n const buf = await readFile(filePath);\n if (!isEncryptedFile(buf)) {\n // Plain file — legacy or unencrypted store.\n return buf;\n }\n // Encrypted — key required.\n if (key === null) {\n throw new SecureStoreLockedError(\n `secure-store is locked — cannot read encrypted file at ${filePath}. ` +\n \"Run `remnic secure-store unlock` to decrypt.\",\n );\n }\n const aad = filePathAad(filePath, memoryDir);\n return decryptFileBody(buf, key, aad);\n}\n\nexport async function readMaybeEncryptedFile(\n filePath: string,\n key: Buffer | null,\n memoryDir?: string,\n): Promise<string> {\n return (await readMaybeEncryptedFileBuffer(filePath, key, memoryDir)).toString(\"utf8\");\n}\n\nexport interface WriteMaybeEncryptedFileOptions {\n /**\n * File mode bits. Default 0o600 (owner read/write only).\n * Applied only on create; existing files inherit their existing mode.\n */\n mode?: number;\n /**\n * If true, write atomically via a temp file + rename (CLAUDE.md gotcha #54).\n * Default true.\n */\n atomic?: boolean;\n}\n\n/**\n * Write `content` to `filePath`.\n *\n * - If `key` is provided and non-null, encrypt the content first.\n * - If `key` is null, write the content as plain UTF-8 (unencrypted store).\n *\n * Writes atomically: content is written to a `.tmp-<pid>-<ts>` file\n * first, then renamed into place (CLAUDE.md gotcha #54 — never delete\n * before write).\n */\nexport async function writeMaybeEncryptedFile(\n filePath: string,\n content: string | Buffer,\n key: Buffer | null,\n options: WriteMaybeEncryptedFileOptions = {},\n memoryDir?: string,\n): Promise<void> {\n const { mode = 0o600, atomic = true } = options;\n await mkdir(path.dirname(filePath), { recursive: true });\n\n let data: Buffer | string;\n if (key !== null) {\n const aad = filePathAad(filePath, memoryDir);\n data = encryptFileBody(content, key, aad);\n } else {\n data = content;\n }\n\n if (atomic) {\n const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;\n try {\n await writeFile(tempPath, data, { mode });\n await rename(tempPath, filePath);\n } catch (err) {\n // Best-effort cleanup of the temp file.\n try {\n await unlink(tempPath);\n } catch {\n // ignore\n }\n throw err;\n }\n } else {\n await writeFile(filePath, data, { mode });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Migration\n// ---------------------------------------------------------------------------\n\nexport interface MigrateResult {\n /** Number of files successfully encrypted. */\n encrypted: number;\n /** Number of files already encrypted (skipped). */\n skipped: number;\n /** Files that failed to encrypt (path → error message). */\n errors: Array<{ filePath: string; error: string }>;\n}\n\nexport interface DecryptResult {\n /** Number of files successfully decrypted back to plaintext. */\n decrypted: number;\n /** Number of files already plaintext (skipped). */\n skipped: number;\n /** Files that failed to decrypt (path → error message). */\n errors: Array<{ filePath: string; error: string }>;\n}\n\n/**\n * Walk `dir` recursively, find encryptable storage-managed files that are not\n * yet encrypted, and re-write them as encrypted files under `key`.\n *\n * Safety rules per CLAUDE.md gotchas #54 and #25:\n * 1. A page-version snapshot is taken (via `createVersion`) BEFORE\n * each overwrite so the plaintext version is preserved in history.\n * Since this module has no direct access to `page-versioning.ts`\n * internals, callers who have page-versioning configured should\n * pass `onBeforeEncrypt` to take the snapshot.\n * 2. The new encrypted content is written to a temp file first,\n * then renamed atomically — never deleted before written.\n * 3. If encryption of any file fails, the error is recorded and the\n * original file is left intact (partial migration is safe).\n *\n * @param dir Absolute path to the memory directory.\n * @param key 32-byte AES-256 key.\n * @param onBeforeEncrypt Optional callback invoked before encrypting\n * each file. Can be used to take page-version\n * snapshots. Errors here are non-fatal.\n */\nexport async function migrateMemoryDirToEncrypted(\n dir: string,\n key: Buffer,\n onBeforeEncrypt?: (filePath: string) => Promise<void>,\n): Promise<MigrateResult> {\n const result: MigrateResult = { encrypted: 0, skipped: 0, errors: [] };\n\n const files = await collectEncryptableStorageFiles(dir);\n for (const filePath of files) {\n try {\n const buf = await readFile(filePath);\n if (isEncryptedFile(buf)) {\n result.skipped++;\n continue;\n }\n // Call optional pre-encryption hook (e.g. page-version snapshot).\n if (onBeforeEncrypt) {\n try {\n await onBeforeEncrypt(filePath);\n } catch {\n // Non-fatal — continue with encryption even if snapshot fails.\n }\n }\n const content = buf.toString(\"utf8\");\n const aad = filePathAad(filePath, storageAadRootForFile(filePath, dir));\n const encrypted = encryptFileBody(content, key, aad);\n\n // Atomic write: temp → rename (gotcha #54).\n const tempPath = `${filePath}.enc-tmp-${process.pid}-${Date.now()}`;\n try {\n await writeFile(tempPath, encrypted, { mode: 0o600 });\n await rename(tempPath, filePath);\n result.encrypted++;\n } catch (writeErr) {\n // Clean up temp file, leave original intact.\n try {\n const { unlink } = await import(\"node:fs/promises\");\n await unlink(tempPath);\n } catch {\n // ignore\n }\n throw writeErr;\n }\n } catch (err) {\n result.errors.push({\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return result;\n}\n\n/**\n * Walk `dir` recursively, find storage-managed encrypted files, and\n * re-write them as plaintext under the same paths.\n *\n * This is the reversible counterpart to {@link migrateMemoryDirToEncrypted}.\n * It only touches files under the same storage-managed roots, skips\n * plaintext files, skips symlinks, excludes `.secure-store/`, and writes\n * each plaintext replacement via temp-file + rename so a per-file failure\n * leaves the ciphertext intact.\n */\nexport async function decryptMemoryDirToPlaintext(\n dir: string,\n key: Buffer,\n): Promise<DecryptResult> {\n const result: DecryptResult = { decrypted: 0, skipped: 0, errors: [] };\n\n const files = await collectStorageManagedFiles(dir, isDecryptableStoragePath);\n for (const filePath of files) {\n try {\n const buf = await readFile(filePath);\n if (!isEncryptedFile(buf)) {\n result.skipped++;\n continue;\n }\n\n const aad = filePathAad(filePath, storageAadRootForFile(filePath, dir));\n const plaintext = decryptFileBody(buf, key, aad);\n const tempPath = `${filePath}.dec-tmp-${process.pid}-${Date.now()}`;\n try {\n await writeFile(tempPath, plaintext, { mode: 0o600 });\n await rename(tempPath, filePath);\n result.decrypted++;\n } catch (writeErr) {\n try {\n await unlink(tempPath);\n } catch {\n // ignore cleanup errors; original ciphertext is still intact.\n }\n throw writeErr;\n }\n } catch (err) {\n result.errors.push({\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively collect files under `dir` that are read through the\n * storage-layer secure-store helpers, excluding symlinked entries and\n * `.secure-store/` metadata.\n */\nasync function collectEncryptableStorageFiles(dir: string, rootDir = dir): Promise<string[]> {\n return collectStorageManagedFiles(dir, isEncryptableStoragePath, rootDir);\n}\n\n/**\n * Recursively collect regular files under storage-managed roots, excluding\n * symlinked entries and `.secure-store/` metadata. This broader collector is\n * used by the decrypt/disable path so future encrypted sidecars can be\n * restored without requiring extension-specific logic.\n */\nasync function collectStorageManagedFiles(\n dir: string,\n includeFile: (filePath: string, rootDir: string) => boolean,\n rootDir = dir,\n): Promise<string[]> {\n const results: string[] = [];\n let names: string[];\n try {\n names = await readdir(dir, { encoding: \"utf8\" });\n } catch {\n return results;\n }\n for (const name of names) {\n if (name.startsWith(\".secure-store\")) continue;\n const full = path.join(dir, name);\n let isDir = false;\n let isFile = false;\n try {\n const s = await lstat(full);\n if (s.isSymbolicLink()) continue;\n isDir = s.isDirectory();\n isFile = s.isFile();\n } catch {\n continue;\n }\n if (isDir) {\n const sub = await collectStorageManagedFiles(full, includeFile, rootDir);\n results.push(...sub);\n } else if (isFile && includeFile(full, rootDir)) {\n results.push(full);\n }\n }\n return results;\n}\n\nfunction isEncryptableStoragePath(filePath: string, rootDir: string): boolean {\n const rel = path.relative(rootDir, filePath);\n if (rel === \"\" || rel.startsWith(\"..\") || path.isAbsolute(rel)) return false;\n const normalized = normalizeStorageRelativePath(rel);\n if (normalized === \"profile.md\") return true;\n if (isEncryptableStateSidecar(normalized)) return true;\n if (isEncryptableSummarySidecar(normalized)) return true;\n const firstSegment = normalized.split(\"/\", 1)[0];\n return ENCRYPTABLE_MARKDOWN_STORAGE_ROOTS.has(firstSegment) && normalized.endsWith(\".md\");\n}\n\nfunction isDecryptableStoragePath(filePath: string, rootDir: string): boolean {\n if (isEncryptableStoragePath(filePath, rootDir)) return true;\n const rel = path.relative(rootDir, filePath);\n if (rel === \"\" || rel.startsWith(\"..\") || path.isAbsolute(rel)) return false;\n const normalized = normalizeStorageRelativePath(rel);\n const firstSegment = normalized.split(\"/\", 1)[0];\n return DECRYPTABLE_SIDECAR_ROOTS.has(firstSegment);\n}\n\nfunction normalizeStorageRelativePath(rel: string): string {\n const normalized = rel.split(path.sep).join(\"/\");\n const parts = normalized.split(\"/\");\n if (parts[0] === \"namespaces\" && parts.length >= 3) {\n return parts.slice(2).join(\"/\");\n }\n return normalized;\n}\n\nfunction storageAadRootForFile(filePath: string, rootDir: string): string {\n const rel = path.relative(rootDir, filePath);\n if (rel === \"\" || rel.startsWith(\"..\") || path.isAbsolute(rel)) return rootDir;\n const parts = rel.split(path.sep);\n if (parts[0] === \"namespaces\" && parts.length >= 3 && parts[1]) {\n return path.join(rootDir, \"namespaces\", parts[1]);\n }\n return rootDir;\n}\n\nconst ENCRYPTABLE_MARKDOWN_STORAGE_ROOTS = new Set([\n \"facts\",\n \"corrections\",\n \"procedures\",\n \"reasoning-traces\",\n \"artifacts\",\n \"archive\",\n \"entities\",\n \"identity\",\n]);\n\nconst ENCRYPTABLE_STATE_SIDECARS = new Set([\n \"state/behavior-signals.jsonl\",\n \"state/buffer-surprise-ledger.jsonl\",\n \"state/buffer.json\",\n \"state/compression-guideline-draft-state.json\",\n \"state/compression-guideline-state.json\",\n \"state/compression-guidelines.draft.md\",\n \"state/compression-guidelines.md\",\n \"state/entity-synthesis-queue.json\",\n \"state/fact-hashes.txt\",\n \"state/memory-actions.jsonl\",\n \"state/memory-lifecycle-ledger.jsonl\",\n \"state/meta.json\",\n \"state/reextract-jobs.jsonl\",\n \"state/topics.json\",\n]);\n\nfunction isEncryptableStateSidecar(normalized: string): boolean {\n return ENCRYPTABLE_STATE_SIDECARS.has(normalized);\n}\n\nfunction isEncryptableSummarySidecar(normalized: string): boolean {\n return normalized.startsWith(\"summaries/\") && normalized.endsWith(\".json\");\n}\n\nconst DECRYPTABLE_SIDECAR_ROOTS = new Set([\n \"state\",\n \"indexes\",\n \"index\",\n \"provenance\",\n]);\n"],"mappings":"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","names":["unlink"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  StorageManager,
3
3
  normalizeEntityName
4
- } from "./chunk-7AAT6G4Q.js";
4
+ } from "./chunk-IOAY54RF.js";
5
5
  import {
6
6
  readEnvVar,
7
7
  resolveHomeDir
@@ -824,4 +824,4 @@ export {
824
824
  resolveBriefingSaveDir,
825
825
  briefingFilename
826
826
  };
827
- //# sourceMappingURL=chunk-VW676BEI.js.map
827
+ //# sourceMappingURL=chunk-V7WH7DEM.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isValidCapsuleSince
3
- } from "./chunk-2F2W355T.js";
3
+ } from "./chunk-QA2ZAPBU.js";
4
4
  import {
5
5
  CAPSULE_ID_PATTERN
6
6
  } from "./chunk-WEHSQBFR.js";
@@ -246,6 +246,13 @@ var capsuleImportRequestSchema = z.object({
246
246
  var capsuleListRequestSchema = z.object({
247
247
  namespace: namespaceSchema
248
248
  });
249
+ var offlineSyncApplyRequestSchema = z.object({
250
+ namespace: namespaceSchema,
251
+ changeset: z.unknown()
252
+ }).refine((value) => value.changeset !== void 0 && value.changeset !== null, {
253
+ message: "changeset is required",
254
+ path: ["changeset"]
255
+ });
249
256
  var nullableOptional = (schema) => schema.optional().nullable().transform((value) => value ?? void 0);
250
257
  var actionConfidenceRuleSchema = z.object({
251
258
  kind: z.enum(ACTION_CONFIDENCE_RULE_KINDS),
@@ -293,6 +300,7 @@ var schemas = {
293
300
  capsuleExport: capsuleExportRequestSchema,
294
301
  capsuleImport: capsuleImportRequestSchema,
295
302
  capsuleList: capsuleListRequestSchema,
303
+ offlineSyncApply: offlineSyncApplyRequestSchema,
296
304
  actionConfidence: actionConfidenceRequestSchema
297
305
  };
298
306
  function validateRequest(schemaName, body) {
@@ -335,7 +343,8 @@ export {
335
343
  capsuleExportRequestSchema,
336
344
  capsuleImportRequestSchema,
337
345
  capsuleListRequestSchema,
346
+ offlineSyncApplyRequestSchema,
338
347
  actionConfidenceRequestSchema,
339
348
  validateRequest
340
349
  };
341
- //# sourceMappingURL=chunk-A2XUIMJ3.js.map
350
+ //# sourceMappingURL=chunk-VWFIQOTJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/access-schema.ts"],"sourcesContent":["// Request/response schema validation for the Remnic HTTP API.\n// Uses zod for runtime validation — returns structured 400 errors with\n// field-level detail so consumers get clear feedback on malformed requests.\n\nimport { z } from \"zod\";\nimport {\n ACTION_CONFIDENCE_CONTEXT_READINESS,\n ACTION_CONFIDENCE_RISK_CATEGORIES,\n ACTION_CONFIDENCE_RULE_KINDS,\n} from \"./action-confidence.js\";\nimport { isValidCapsuleSince } from \"./transfer/capsule-export.js\";\nimport { CAPSULE_ID_PATTERN } from \"./transfer/types.js\";\n\n// ---------------------------------------------------------------------------\n// Error formatting\n// ---------------------------------------------------------------------------\n\nexport interface SchemaValidationError {\n error: string;\n code: \"validation_error\";\n details: Array<{ field: string; message: string }>;\n}\n\nexport function formatZodError(error: z.ZodError): SchemaValidationError {\n return {\n error: \"request validation failed\",\n code: \"validation_error\",\n details: error.issues.map((issue) => ({\n field: issue.path.join(\".\") || \"(root)\",\n message: issue.message,\n })),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Shared fields\n// ---------------------------------------------------------------------------\n\nconst namespaceSchema = z.string().trim().max(256).optional();\nconst sessionKeySchema = z.string().trim().min(1).max(512).optional();\nconst idempotencyKeySchema = z.string().trim().min(1).max(256).optional();\nconst dryRunSchema = z.boolean().optional();\nconst schemaVersionSchema = z.number().int().optional();\n\n// ---------------------------------------------------------------------------\n// Recall\n// ---------------------------------------------------------------------------\n\n/**\n * Coding-agent context (issue #569). Optional payload that connectors may\n * ship with a recall request so the project/branch namespace overlay\n * applies to that recall. All fields are validated per CLAUDE.md #51 —\n * empty-string projectId / rootPath is rejected, not silently accepted.\n */\nexport const codingContextSchema = z\n .object({\n projectId: z.string().trim().min(1, \"codingContext.projectId is required\").max(128),\n branch: z.string().trim().max(256).nullable(),\n rootPath: z.string().trim().min(1, \"codingContext.rootPath is required\").max(1024),\n defaultBranch: z.string().trim().max(256).nullable(),\n })\n .nullable();\n\n/**\n * Recall disclosure depth (issue #677). Mirrors the `RecallDisclosure`\n * type in `types.ts` — keep these in sync. Default-application happens\n * inside `EngramAccessService.recall()`; the schema only accepts/rejects.\n * Invalid values throw a structured 400 instead of silently defaulting,\n * per CLAUDE.md rule 51.\n */\nexport const recallDisclosureSchema = z.enum([\"chunk\", \"section\", \"raw\"]);\n\n/**\n * Tag-match semantics (issue #689). `any` (default when `tags` is provided\n * and `tagMatch` is omitted) admits a result when it carries at least one\n * of the filter tags. `all` requires every filter tag to be present.\n * Schema rejects unknown values up front — never silently defaults\n * (CLAUDE.md rule 51).\n */\nexport const tagMatchSchema = z.enum([\"any\", \"all\"]);\n\nexport const recallRequestSchema = z.object({\n query: z.string().min(1, \"query is required\"),\n sessionKey: sessionKeySchema,\n namespace: namespaceSchema,\n topK: z.number().int().min(0).max(200).optional(),\n mode: z.enum([\"auto\", \"no_recall\", \"minimal\", \"full\", \"graph_mode\"]).optional(),\n includeDebug: z.boolean().optional(),\n idempotencyKey: idempotencyKeySchema,\n disclosure: recallDisclosureSchema.optional(),\n codingContext: codingContextSchema.optional(),\n /** Working directory for auto git-context resolution (issue #569). */\n cwd: z.string().trim().min(1, \"cwd must be non-empty when provided\").max(2048).optional(),\n /**\n * Arbitrary project tag for non-git-based project scoping (issue #569).\n * Creates a coding context with `projectId: \"tag:<projectTag>\"`.\n */\n projectTag: z.string().trim().min(1, \"projectTag must be non-empty when provided\").max(256).optional(),\n /**\n * Historical recall pin (issue #680). ISO 8601 timestamp. The\n * schema only enforces the basic shape; the access service runs\n * `Date.parse` and emits a structured 400 on malformed input\n * (CLAUDE.md rule 51).\n */\n asOf: z.string().trim().min(1, \"asOf must be a non-empty ISO 8601 timestamp\").max(64).optional(),\n /**\n * Free-form recall tag filter (issue #689). When provided, recall results\n * whose frontmatter `tags` do not match the filter are removed before the\n * response is returned. Comparison is case-sensitive exact match.\n */\n tags: z.array(z.string().trim().min(1).max(256)).max(50).optional(),\n /**\n * Match mode for `tags` (issue #689). Defaults to `\"any\"` when `tags` is\n * provided and `tagMatch` is omitted. Ignored when `tags` is absent.\n */\n tagMatch: tagMatchSchema.optional(),\n /**\n * Include graph edges below `graphTraversalConfidenceFloor` for diagnostic\n * recall traversal (issue #681). Defaults to false.\n */\n includeLowConfidence: z.boolean().optional(),\n});\n\nexport const recallExplainRequestSchema = z.object({\n sessionKey: sessionKeySchema,\n namespace: namespaceSchema,\n});\n\n/**\n * Standalone \"set coding context\" request. Used by the HTTP endpoint\n * `POST /engram/v1/coding-context` and the MCP `remnic.set_coding_context`\n * tool (PR 7). `codingContext: null` clears the attached context.\n */\nexport const setCodingContextRequestSchema = z.object({\n sessionKey: z.string().trim().min(1, \"sessionKey is required\").max(512),\n codingContext: codingContextSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Observe\n// ---------------------------------------------------------------------------\n\nconst messageSchema = z.object({\n role: z.enum([\"user\", \"assistant\"]),\n content: z.string().min(1, \"message content must be non-empty\"),\n sourceFormat: z\n .enum([\"openai\", \"anthropic\", \"openclaw\", \"pi\", \"lossless-claw\", \"remnic\"])\n .nullable()\n .optional(),\n rawContent: z.unknown().nullable().optional(),\n parts: z\n .array(\n z.object({\n ordinal: z.number().int().min(0).nullable().optional(),\n kind: z.enum([\n \"text\",\n \"tool_call\",\n \"tool_result\",\n \"patch\",\n \"file_read\",\n \"file_write\",\n \"step_start\",\n \"step_finish\",\n \"snapshot\",\n \"retry\",\n ]),\n payload: z.record(z.string(), z.unknown()),\n toolName: z.string().nullable().optional(),\n tool_name: z.string().nullable().optional(),\n filePath: z.string().nullable().optional(),\n file_path: z.string().nullable().optional(),\n createdAt: z.string().nullable().optional(),\n created_at: z.string().nullable().optional(),\n }),\n )\n .nullable()\n .optional(),\n});\n\nexport const observeRequestSchema = z.object({\n sessionKey: z.string().trim().min(1, \"sessionKey is required\").max(512),\n messages: z.array(messageSchema).min(1, \"messages must be a non-empty array\"),\n namespace: namespaceSchema,\n skipExtraction: z.boolean().optional(),\n /** Working directory for auto git-context resolution (issue #569). */\n cwd: z.string().trim().min(1, \"cwd must be non-empty when provided\").max(2048).optional(),\n /**\n * Arbitrary project tag for non-git-based project scoping (issue #569).\n * Creates a coding context with `projectId: \"tag:<projectTag>\"`.\n */\n projectTag: z.string().trim().min(1, \"projectTag must be non-empty when provided\").max(256).optional(),\n});\n\n// ---------------------------------------------------------------------------\n// Memory store / suggestion submit\n// ---------------------------------------------------------------------------\n\nconst writeContentSchema = z.string().min(1, \"content is required\").max(50000);\nconst categorySchema = z\n .enum([\n \"fact\", \"preference\", \"correction\", \"entity\", \"decision\",\n \"relationship\", \"principle\", \"commitment\", \"moment\", \"skill\", \"rule\", \"procedure\",\n \"reasoning_trace\",\n ])\n .optional();\nconst confidenceSchema = z.number().min(0).max(1).optional();\nconst tagsSchema = z.array(z.string().max(256)).max(50).optional();\nconst entityRefSchema = z.string().trim().max(512).optional();\nconst ttlSchema = z.string().trim().max(128).optional();\nconst sourceReasonSchema = z.string().trim().max(2000).optional();\n\nexport const memoryStoreRequestSchema = z.object({\n schemaVersion: schemaVersionSchema,\n idempotencyKey: idempotencyKeySchema,\n dryRun: dryRunSchema,\n sessionKey: sessionKeySchema,\n content: writeContentSchema,\n category: categorySchema,\n confidence: confidenceSchema,\n namespace: namespaceSchema,\n tags: tagsSchema,\n entityRef: entityRefSchema,\n ttl: ttlSchema,\n sourceReason: sourceReasonSchema,\n});\n\nexport const suggestionSubmitRequestSchema = memoryStoreRequestSchema;\n\n// ---------------------------------------------------------------------------\n// Review disposition\n// ---------------------------------------------------------------------------\n\nexport const reviewDispositionRequestSchema = z.object({\n memoryId: z.string().trim().min(1, \"memoryId is required\"),\n status: z.enum([\n \"active\", \"pending_review\", \"quarantined\", \"rejected\", \"superseded\", \"archived\",\n ]),\n reasonCode: z.string().trim().min(1, \"reasonCode is required\"),\n namespace: namespaceSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Trust-zone promote\n// ---------------------------------------------------------------------------\n\nexport const trustZonePromoteRequestSchema = z.object({\n recordId: z.string().trim().min(1, \"recordId is required\"),\n targetZone: z.enum([\"working\", \"trusted\"], {\n errorMap: () => ({ message: \"targetZone must be 'working' or 'trusted'\" }),\n }),\n promotionReason: z.string().trim().min(1, \"promotionReason is required\"),\n recordedAt: z.string().trim().optional(),\n summary: z.string().trim().max(5000).optional(),\n dryRun: dryRunSchema,\n namespace: namespaceSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Trust-zone demo-seed\n// ---------------------------------------------------------------------------\n\nexport const trustZoneDemoSeedRequestSchema = z.object({\n scenario: z.string().trim().max(256).optional(),\n recordedAt: z.string().trim().optional(),\n dryRun: dryRunSchema,\n namespace: namespaceSchema,\n});\n\n// ---------------------------------------------------------------------------\n// LCM search\n// ---------------------------------------------------------------------------\n\nexport const lcmSearchRequestSchema = z.object({\n query: z.string().min(1, \"query is required\"),\n sessionKey: sessionKeySchema,\n namespace: namespaceSchema,\n limit: z.number().int().min(1).max(100).optional(),\n});\n\nexport const lcmCompactionFlushRequestSchema = z.object({\n sessionKey: z.string().trim().min(1, \"sessionKey is required\").max(512),\n namespace: namespaceSchema,\n});\n\nexport const lcmCompactionRecordRequestSchema = z.object({\n sessionKey: z.string().trim().min(1, \"sessionKey is required\").max(512),\n namespace: namespaceSchema,\n tokensBefore: z.number().int().min(0, \"tokensBefore must be a non-negative integer\"),\n tokensAfter: z.number().int().min(0, \"tokensAfter must be a non-negative integer\"),\n});\n\n// ---------------------------------------------------------------------------\n// Day summary\n// ---------------------------------------------------------------------------\n\nexport const daySummaryRequestSchema = z.object({\n memories: z.string().max(100000).optional(),\n sessionKey: sessionKeySchema,\n namespace: namespaceSchema,\n});\n\n// ---------------------------------------------------------------------------\n// Capsule export\n// ---------------------------------------------------------------------------\n\nconst capsuleTopLevelSegmentSchema = z\n .string()\n .trim()\n .min(1)\n .max(128)\n .refine(\n (value) => !value.includes(\"/\") && !value.includes(\"\\\\\"),\n \"must be a top-level directory name without path separators\",\n );\n\nconst capsulePeerIdSchema = z\n .string()\n .trim()\n .min(1)\n .max(256)\n .refine(\n (value) => value !== \".\" && value !== \"..\" && !value.includes(\"/\") && !value.includes(\"\\\\\"),\n \"must be a plain peer id without path separators\",\n );\n\nconst capsuleIsoSinceSchema = z\n .string()\n .trim()\n .min(1, \"since must be a non-empty ISO 8601 timestamp\")\n .max(128)\n .refine(\n isValidCapsuleSince,\n \"since must be a valid ISO 8601 timestamp with no calendar overflow\",\n );\n\nexport const capsuleExportRequestSchema = z\n .object({\n name: z\n .string()\n .trim()\n .min(1, \"name is required\")\n .max(64, \"name must be 64 characters or fewer\")\n .regex(\n CAPSULE_ID_PATTERN,\n \"name must be alphanumeric with single dashes (no spaces, no leading/trailing dashes)\",\n ),\n namespace: namespaceSchema,\n since: capsuleIsoSinceSchema.optional(),\n includeKinds: z.array(capsuleTopLevelSegmentSchema).max(50).optional(),\n peerIds: z.array(capsulePeerIdSchema).max(100).optional(),\n includeTranscripts: z.boolean().optional(),\n encrypt: z.boolean().optional(),\n });\n\nexport const capsuleImportRequestSchema = z\n .object({\n archivePath: z.string().trim().min(1, \"archivePath is required\").max(4096),\n namespace: namespaceSchema,\n mode: z.enum([\"skip\", \"overwrite\", \"fork\"]).optional(),\n });\n\nexport const capsuleListRequestSchema = z\n .object({\n namespace: namespaceSchema,\n });\n\n// ---------------------------------------------------------------------------\n// Offline sync\n// ---------------------------------------------------------------------------\n\nexport const offlineSyncApplyRequestSchema = z\n .object({\n namespace: namespaceSchema,\n changeset: z.unknown(),\n })\n .refine((value) => value.changeset !== undefined && value.changeset !== null, {\n message: \"changeset is required\",\n path: [\"changeset\"],\n });\n\n// ---------------------------------------------------------------------------\n// Action confidence\n// ---------------------------------------------------------------------------\n\nconst nullableOptional = <T extends z.ZodTypeAny>(schema: T) =>\n schema.optional().nullable().transform((value) => value ?? undefined);\n\nconst actionConfidenceRuleSchema = z\n .object({\n kind: z.enum(ACTION_CONFIDENCE_RULE_KINDS),\n description: nullableOptional(z.string().trim().min(1).max(2000)),\n matched: nullableOptional(z.boolean()),\n })\n .strict();\n\nconst actionConfidenceMemorySchema = z\n .object({\n source: nullableOptional(z.string().trim().min(1).max(256)),\n created: nullableOptional(z.string().trim().min(1).max(128)),\n updated: nullableOptional(z.string().trim().min(1).max(128)),\n scope: nullableOptional(z.string().trim().min(1).max(512)),\n userContextScopes: nullableOptional(z.array(z.string().trim().min(1).max(128)).max(50)),\n retrievalReason: nullableOptional(z.string().trim().min(1).max(2000)),\n confidence: nullableOptional(z.number().min(0).max(1)),\n stale: nullableOptional(z.boolean()),\n corrected: nullableOptional(z.boolean()),\n correctionState: nullableOptional(z.enum([\"none\", \"correction\", \"superseded\", \"disputed\", \"forgotten\"])),\n safeToUse: nullableOptional(z.boolean()),\n safety: nullableOptional(z.enum([\"safe\", \"requires-review\", \"blocked\"])),\n safetyReasons: nullableOptional(z.array(z.string().trim().min(1).max(1000)).max(50)),\n })\n .strict();\n\nexport const actionConfidenceRequestSchema = z\n .object({\n intendedAction: nullableOptional(z.string().trim().min(1).max(1000)),\n confidence: nullableOptional(z.number().min(0).max(1)),\n risk: nullableOptional(z.enum(ACTION_CONFIDENCE_RISK_CATEGORIES)),\n contextReadiness: nullableOptional(z.enum(ACTION_CONFIDENCE_CONTEXT_READINESS)),\n currentContextScopes: nullableOptional(z.array(z.string().trim().min(1).max(128)).max(50)),\n userRules: nullableOptional(z.array(actionConfidenceRuleSchema).max(100)),\n retrievedMemories: nullableOptional(z.array(actionConfidenceMemorySchema).max(200)),\n })\n .strict();\n\n// ---------------------------------------------------------------------------\n// Inferred types\n// ---------------------------------------------------------------------------\n\nexport type RecallRequest = z.infer<typeof recallRequestSchema>;\nexport type RecallExplainRequest = z.infer<typeof recallExplainRequestSchema>;\nexport type SetCodingContextRequest = z.infer<typeof setCodingContextRequestSchema>;\nexport type ObserveRequest = z.infer<typeof observeRequestSchema>;\nexport type MemoryStoreRequest = z.infer<typeof memoryStoreRequestSchema>;\nexport type SuggestionSubmitRequest = z.infer<typeof suggestionSubmitRequestSchema>;\nexport type ReviewDispositionRequest = z.infer<typeof reviewDispositionRequestSchema>;\nexport type TrustZonePromoteRequest = z.infer<typeof trustZonePromoteRequestSchema>;\nexport type TrustZoneDemoSeedRequest = z.infer<typeof trustZoneDemoSeedRequestSchema>;\nexport type LcmSearchRequest = z.infer<typeof lcmSearchRequestSchema>;\nexport type LcmCompactionFlushRequest = z.infer<typeof lcmCompactionFlushRequestSchema>;\nexport type LcmCompactionRecordRequest = z.infer<typeof lcmCompactionRecordRequestSchema>;\nexport type DaySummaryRequest = z.infer<typeof daySummaryRequestSchema>;\nexport type CapsuleExportRequest = z.infer<typeof capsuleExportRequestSchema>;\nexport type CapsuleImportRequest = z.infer<typeof capsuleImportRequestSchema>;\nexport type CapsuleListRequest = z.infer<typeof capsuleListRequestSchema>;\nexport type OfflineSyncApplyRequest = z.infer<typeof offlineSyncApplyRequestSchema>;\nexport type ActionConfidenceRequest = z.infer<typeof actionConfidenceRequestSchema>;\n\n// ---------------------------------------------------------------------------\n// Validation helper\n// ---------------------------------------------------------------------------\n\nexport type SchemaName =\n | \"recall\"\n | \"recallExplain\"\n | \"setCodingContext\"\n | \"observe\"\n | \"memoryStore\"\n | \"suggestionSubmit\"\n | \"reviewDisposition\"\n | \"trustZonePromote\"\n | \"trustZoneDemoSeed\"\n | \"lcmSearch\"\n | \"lcmCompactionFlush\"\n | \"lcmCompactionRecord\"\n | \"daySummary\"\n | \"capsuleExport\"\n | \"capsuleImport\"\n | \"capsuleList\"\n | \"offlineSyncApply\"\n | \"actionConfidence\";\n\nexport type SchemaTypeFor<N extends SchemaName> =\n N extends \"recall\" ? RecallRequest\n : N extends \"recallExplain\" ? RecallExplainRequest\n : N extends \"setCodingContext\" ? SetCodingContextRequest\n : N extends \"observe\" ? ObserveRequest\n : N extends \"memoryStore\" ? MemoryStoreRequest\n : N extends \"suggestionSubmit\" ? SuggestionSubmitRequest\n : N extends \"reviewDisposition\" ? ReviewDispositionRequest\n : N extends \"trustZonePromote\" ? TrustZonePromoteRequest\n : N extends \"trustZoneDemoSeed\" ? TrustZoneDemoSeedRequest\n : N extends \"lcmSearch\" ? LcmSearchRequest\n : N extends \"lcmCompactionFlush\" ? LcmCompactionFlushRequest\n : N extends \"lcmCompactionRecord\" ? LcmCompactionRecordRequest\n : N extends \"daySummary\" ? DaySummaryRequest\n : N extends \"capsuleExport\" ? CapsuleExportRequest\n : N extends \"capsuleImport\" ? CapsuleImportRequest\n : N extends \"capsuleList\" ? CapsuleListRequest\n : N extends \"offlineSyncApply\" ? OfflineSyncApplyRequest\n : N extends \"actionConfidence\" ? ActionConfidenceRequest\n : never;\n\nconst schemas: Record<SchemaName, z.ZodTypeAny> = {\n recall: recallRequestSchema,\n recallExplain: recallExplainRequestSchema,\n setCodingContext: setCodingContextRequestSchema,\n observe: observeRequestSchema,\n memoryStore: memoryStoreRequestSchema,\n suggestionSubmit: suggestionSubmitRequestSchema,\n reviewDisposition: reviewDispositionRequestSchema,\n trustZonePromote: trustZonePromoteRequestSchema,\n trustZoneDemoSeed: trustZoneDemoSeedRequestSchema,\n lcmSearch: lcmSearchRequestSchema,\n lcmCompactionFlush: lcmCompactionFlushRequestSchema,\n lcmCompactionRecord: lcmCompactionRecordRequestSchema,\n daySummary: daySummaryRequestSchema,\n capsuleExport: capsuleExportRequestSchema,\n capsuleImport: capsuleImportRequestSchema,\n capsuleList: capsuleListRequestSchema,\n offlineSyncApply: offlineSyncApplyRequestSchema,\n actionConfidence: actionConfidenceRequestSchema,\n};\n\n/**\n * Validate a request body against the named schema.\n * Returns `{ success: true, data }` on pass or\n * `{ success: false, error }` on failure with field-level detail.\n */\nexport function validateRequest<T = unknown>(\n schemaName: SchemaName,\n body: unknown,\n): { success: true; data: T } | { success: false; error: SchemaValidationError } {\n const schema = schemas[schemaName];\n if (!schema) {\n return {\n success: false,\n error: {\n error: `unknown schema: ${schemaName}`,\n code: \"validation_error\",\n details: [],\n },\n };\n }\n const result = schema.safeParse(body);\n if (result.success) {\n return { success: true, data: result.data as T };\n }\n return { success: false, error: formatZodError(result.error) };\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createSearchBackend
3
- } from "./chunk-6RVI47ZR.js";
3
+ } from "./chunk-NTUNYIF7.js";
4
4
 
5
5
  // src/namespaces/search.ts
6
6
  function namespaceCollectionName(baseCollection, namespace, options) {
@@ -171,4 +171,4 @@ export {
171
171
  namespaceCollectionName,
172
172
  NamespaceSearchRouter
173
173
  };
174
- //# sourceMappingURL=chunk-PU63GXWS.js.map
174
+ //# sourceMappingURL=chunk-W7DK3CYM.js.map
@@ -1,10 +1,10 @@
1
- import {
2
- SQLITE_SCHEMA_VERSION
3
- } from "./chunk-Z734BLO3.js";
4
1
  import {
5
2
  parseConflictPolicy,
6
3
  validateManifestRecords
7
4
  } from "./chunk-3JXBXXM2.js";
5
+ import {
6
+ SQLITE_SCHEMA_VERSION
7
+ } from "./chunk-Z734BLO3.js";
8
8
  import {
9
9
  openBetterSqlite3
10
10
  } from "./chunk-3HPAPHUK.js";
@@ -85,4 +85,4 @@ async function importSqlite(opts) {
85
85
  export {
86
86
  importSqlite
87
87
  };
88
- //# sourceMappingURL=chunk-TFO23QT4.js.map
88
+ //# sourceMappingURL=chunk-XKLD5OK4.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runPostConsolidationMaterialize
3
- } from "./chunk-ME6ESPZU.js";
3
+ } from "./chunk-IG5VGHYB.js";
4
4
  import {
5
5
  discoverMemoryExtensions,
6
6
  renderExtensionsBlock,
@@ -216,4 +216,4 @@ export {
216
216
  buildExtensionsBlockForConsolidation,
217
217
  materializeAfterSemanticConsolidation
218
218
  };
219
- //# sourceMappingURL=chunk-I5V2VDIW.js.map
219
+ //# sourceMappingURL=chunk-YCVWX2NF.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  listNamespaces
3
- } from "./chunk-MT25YHYH.js";
3
+ } from "./chunk-OJRKZLZ4.js";
4
4
  import {
5
5
  runConsolidationProvenanceCheck
6
6
  } from "./chunk-5HRY2WRF.js";
@@ -36,13 +36,13 @@ import {
36
36
  import {
37
37
  listMemoryGovernanceRuns,
38
38
  readMemoryGovernanceRunArtifact
39
- } from "./chunk-EFJ3MQ4V.js";
39
+ } from "./chunk-65HQPW6O.js";
40
40
  import {
41
41
  analyzeGraphHealth
42
42
  } from "./chunk-RK2Y4XOM.js";
43
43
  import {
44
44
  StorageManager
45
- } from "./chunk-7AAT6G4Q.js";
45
+ } from "./chunk-IOAY54RF.js";
46
46
  import {
47
47
  lintWorkspaceFiles
48
48
  } from "./chunk-DM2T26WE.js";
@@ -1314,4 +1314,4 @@ export {
1314
1314
  runBenchmarkRecall,
1315
1315
  runOperatorRepair
1316
1316
  };
1317
- //# sourceMappingURL=chunk-UXHQAFNA.js.map
1317
+ //# sourceMappingURL=chunk-ZPXYWTN5.js.map
@@ -12,25 +12,25 @@ import {
12
12
  } from "./chunk-TK4UEOSK.js";
13
13
  import {
14
14
  importSqlite
15
- } from "./chunk-TFO23QT4.js";
16
- import {
17
- backupMemoryDir
18
- } from "./chunk-7OZ53EXP.js";
19
- import {
20
- exportJsonBundle
21
- } from "./chunk-GIF42EW3.js";
22
- import {
23
- exportSqlite
24
- } from "./chunk-66DHUKLO.js";
15
+ } from "./chunk-XKLD5OK4.js";
25
16
  import {
26
17
  detectImportFormat
27
18
  } from "./chunk-DOM4GKSW.js";
28
19
  import {
29
20
  importJsonBundle
30
21
  } from "./chunk-W4L6CZKA.js";
22
+ import {
23
+ backupMemoryDir
24
+ } from "./chunk-7OZ53EXP.js";
25
+ import {
26
+ exportJsonBundle
27
+ } from "./chunk-GIF42EW3.js";
31
28
  import {
32
29
  exportMarkdownBundle
33
30
  } from "./chunk-6H2TESSP.js";
31
+ import {
32
+ exportSqlite
33
+ } from "./chunk-66DHUKLO.js";
34
34
  import {
35
35
  TailscaleHelper
36
36
  } from "./chunk-TKWGAOLV.js";
@@ -44,12 +44,12 @@ import {
44
44
  } from "./chunk-TPMQ3G6Z.js";
45
45
  import {
46
46
  rebuildMemoryLifecycleLedger
47
- } from "./chunk-JLFA7DQG.js";
47
+ } from "./chunk-M3AA636B.js";
48
48
  import {
49
49
  rebuildMemoryProjection,
50
50
  repairMemoryProjection,
51
51
  verifyMemoryProjection
52
- } from "./chunk-KLAO5DGL.js";
52
+ } from "./chunk-G7JBLD65.js";
53
53
  import {
54
54
  rebuildObservations
55
55
  } from "./chunk-PZIAX57I.js";
@@ -64,7 +64,7 @@ import {
64
64
  } from "./chunk-TMM4S4IJ.js";
65
65
  import {
66
66
  promoteSemanticRuleFromMemory
67
- } from "./chunk-XVZ7B3HG.js";
67
+ } from "./chunk-JFEH2LZM.js";
68
68
  import {
69
69
  resolveAgentAccessAuthToken
70
70
  } from "./chunk-MXC3AP5I.js";
@@ -92,12 +92,12 @@ import {
92
92
  runOperatorInventory,
93
93
  runOperatorRepair,
94
94
  runOperatorSetup
95
- } from "./chunk-UXHQAFNA.js";
95
+ } from "./chunk-ZPXYWTN5.js";
96
96
  import {
97
97
  listNamespaces,
98
98
  runNamespaceMigration,
99
99
  verifyNamespaces
100
- } from "./chunk-MT25YHYH.js";
100
+ } from "./chunk-OJRKZLZ4.js";
101
101
  import {
102
102
  GraphDashboardServer
103
103
  } from "./chunk-ZPKBYX2F.js";
@@ -108,6 +108,9 @@ import {
108
108
  import {
109
109
  RoutingRulesStore
110
110
  } from "./chunk-LUDTDZLK.js";
111
+ import {
112
+ searchVerifiedEpisodes
113
+ } from "./chunk-MS3ULOZF.js";
111
114
  import {
112
115
  getUtilityLearningStatus,
113
116
  learnUtilityPromotionWeights
@@ -116,15 +119,12 @@ import {
116
119
  getUtilityTelemetryStatus,
117
120
  recordUtilityTelemetryEvent
118
121
  } from "./chunk-3QKK7QOS.js";
119
- import {
120
- searchVerifiedEpisodes
121
- } from "./chunk-P4NEIHUT.js";
122
122
  import {
123
123
  ThreadingManager
124
124
  } from "./chunk-W4RVMTHR.js";
125
125
  import {
126
126
  searchVerifiedSemanticRules
127
- } from "./chunk-MC26UJIM.js";
127
+ } from "./chunk-QLKBF3TI.js";
128
128
  import {
129
129
  getWorkProductLedgerStatus,
130
130
  recordWorkProductLedgerEntry,
@@ -196,13 +196,13 @@ import {
196
196
  } from "./chunk-NGAVDO7E.js";
197
197
  import {
198
198
  EngramAccessHttpServer
199
- } from "./chunk-CQZRLNMV.js";
199
+ } from "./chunk-HJ2WMBFB.js";
200
200
  import {
201
201
  EngramMcpServer
202
- } from "./chunk-WZYKANL3.js";
202
+ } from "./chunk-BNATB54A.js";
203
203
  import {
204
204
  EngramAccessService
205
- } from "./chunk-M23FSH32.js";
205
+ } from "./chunk-5D2G67ZQ.js";
206
206
  import {
207
207
  WorkStorage
208
208
  } from "./chunk-WELDCG6C.js";
@@ -224,7 +224,7 @@ import {
224
224
  readMemoryGovernanceRunArtifact,
225
225
  restoreMemoryGovernanceRun,
226
226
  runMemoryGovernance
227
- } from "./chunk-EFJ3MQ4V.js";
227
+ } from "./chunk-65HQPW6O.js";
228
228
  import {
229
229
  selectRouteRule,
230
230
  validateRouteTarget
@@ -232,13 +232,13 @@ import {
232
232
  import {
233
233
  analyzeGraphHealth
234
234
  } from "./chunk-RK2Y4XOM.js";
235
- import {
236
- parseIsoOffsetTimestamp
237
- } from "./chunk-P7FMDTKL.js";
238
235
  import {
239
236
  RECALL_DISCLOSURE_LEVELS,
240
237
  isRecallDisclosure
241
238
  } from "./chunk-Q7P4WJDP.js";
239
+ import {
240
+ parseIsoOffsetTimestamp
241
+ } from "./chunk-P7FMDTKL.js";
242
242
  import {
243
243
  expandTildePath
244
244
  } from "./chunk-QRNI5JBH.js";
@@ -6755,4 +6755,4 @@ export {
6755
6755
  resolveMemoryDirForNamespace,
6756
6756
  registerCli
6757
6757
  };
6758
- //# sourceMappingURL=chunk-CHEL3SKB.js.map
6758
+ //# sourceMappingURL=chunk-ZYRMKWVW.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  createVersion
3
3
  } from "./chunk-FAAFWE4G.js";
4
+ import {
5
+ parseExportBundle
6
+ } from "./chunk-WEHSQBFR.js";
4
7
  import {
5
8
  decryptCapsuleFileInMemory,
6
9
  isEncryptedCapsuleFile
7
10
  } from "./chunk-KNKUID7G.js";
8
- import {
9
- parseExportBundle
10
- } from "./chunk-WEHSQBFR.js";
11
11
  import {
12
12
  assertIsDirectoryNotSymlink,
13
13
  assertRealpathInsideRoot,
@@ -225,4 +225,4 @@ function mintForkId(capsuleId, originalId, now) {
225
225
  export {
226
226
  importCapsule
227
227
  };
228
- //# sourceMappingURL=chunk-GGKRUQOO.js.map
228
+ //# sourceMappingURL=chunk-ZYVPLJ4T.js.map