@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
package/src/qmd.test.ts CHANGED
@@ -189,6 +189,7 @@ test("parseConfig exposes qmd 2.5 integration defaults and opt-in auto upgrade",
189
189
  assert.equal(defaults.qmdChunkStrategy, "auto");
190
190
  assert.equal(defaults.qmdQueryRerankEnabled, true);
191
191
  assert.equal(defaults.qmdCandidateLimit, undefined);
192
+ assert.equal(defaults.qmdIndexName, undefined);
192
193
 
193
194
  const configured = parseConfig({
194
195
  qmdAutoUpgradeEnabled: "true",
@@ -204,15 +204,15 @@ export function filePathAad(filePath: string, memoryDir?: string): Buffer {
204
204
  * @param key 32-byte AES-256 key, or null when the store is locked.
205
205
  * @param memoryDir Memory root for path-bound AAD. Should be absolute.
206
206
  */
207
- export async function readMaybeEncryptedFile(
207
+ export async function readMaybeEncryptedFileBuffer(
208
208
  filePath: string,
209
209
  key: Buffer | null,
210
210
  memoryDir?: string,
211
- ): Promise<string> {
211
+ ): Promise<Buffer> {
212
212
  const buf = await readFile(filePath);
213
213
  if (!isEncryptedFile(buf)) {
214
- // Plain UTF-8 file — legacy or unencrypted store.
215
- return buf.toString("utf8");
214
+ // Plain file — legacy or unencrypted store.
215
+ return buf;
216
216
  }
217
217
  // Encrypted — key required.
218
218
  if (key === null) {
@@ -222,8 +222,15 @@ export async function readMaybeEncryptedFile(
222
222
  );
223
223
  }
224
224
  const aad = filePathAad(filePath, memoryDir);
225
- const plain = decryptFileBody(buf, key, aad);
226
- return plain.toString("utf8");
225
+ return decryptFileBody(buf, key, aad);
226
+ }
227
+
228
+ export async function readMaybeEncryptedFile(
229
+ filePath: string,
230
+ key: Buffer | null,
231
+ memoryDir?: string,
232
+ ): Promise<string> {
233
+ return (await readMaybeEncryptedFileBuffer(filePath, key, memoryDir)).toString("utf8");
227
234
  }
228
235
 
229
236
  export interface WriteMaybeEncryptedFileOptions {
@@ -251,7 +258,7 @@ export interface WriteMaybeEncryptedFileOptions {
251
258
  */
252
259
  export async function writeMaybeEncryptedFile(
253
260
  filePath: string,
254
- content: string,
261
+ content: string | Buffer,
255
262
  key: Buffer | null,
256
263
  options: WriteMaybeEncryptedFileOptions = {},
257
264
  memoryDir?: string,
package/src/storage.ts CHANGED
@@ -11,6 +11,7 @@ import { createVersion as createPageVersion, type VersioningConfig, type Version
11
11
  import {
12
12
  SecureStoreLockedError,
13
13
  isEncryptedFile,
14
+ readMaybeEncryptedFileBuffer,
14
15
  readMaybeEncryptedFile,
15
16
  writeMaybeEncryptedFile,
16
17
  } from "./secure-store/secure-fs.js";
@@ -1058,6 +1059,14 @@ export class ContentHashIndex {
1058
1059
  return this.hashes.size;
1059
1060
  }
1060
1061
 
1062
+ /** Clear all loaded hashes so the next save rewrites the index from scratch. */
1063
+ clear(): void {
1064
+ if (this.hashes.size > 0) {
1065
+ this.hashes.clear();
1066
+ }
1067
+ this.dirty = true;
1068
+ }
1069
+
1061
1070
  /** Persist index to disk if changed. */
1062
1071
  async save(): Promise<void> {
1063
1072
  if (!this.dirty) return;
@@ -2478,6 +2487,55 @@ export class StorageManager {
2478
2487
  private writeStorageSecureFile(filePath: string, content: string): Promise<void> {
2479
2488
  return writeMaybeEncryptedFile(filePath, content, this.resolveWriteKey(), {}, this.baseDir);
2480
2489
  }
2490
+
2491
+ private assertManagedStoragePath(filePath: string, method: string): string {
2492
+ const resolved = path.resolve(filePath);
2493
+ const base = path.resolve(this.baseDir);
2494
+ const rel = path.relative(base, resolved);
2495
+ if (rel === "" || rel === ".." || rel.startsWith(`..${path.sep}`) || path.isAbsolute(rel)) {
2496
+ throw new Error(`${method}: file path escapes memory dir`);
2497
+ }
2498
+ return resolved;
2499
+ }
2500
+
2501
+ async readOfflineSyncFile(filePath: string): Promise<Buffer> {
2502
+ const target = this.assertManagedStoragePath(filePath, "storage.readOfflineSyncFile");
2503
+ return readMaybeEncryptedFileBuffer(target, this._secureStoreKey, this.baseDir);
2504
+ }
2505
+
2506
+ async writeOfflineSyncFile(filePath: string, content: Buffer): Promise<void> {
2507
+ const target = this.assertManagedStoragePath(filePath, "storage.writeOfflineSyncFile");
2508
+ await writeMaybeEncryptedFile(target, content, this.resolveWriteKey(), {}, this.baseDir);
2509
+ await this.invalidateAfterOfflineSyncMutation(target);
2510
+ }
2511
+
2512
+ async deleteOfflineSyncFile(filePath: string): Promise<void> {
2513
+ const target = this.assertManagedStoragePath(filePath, "storage.deleteOfflineSyncFile");
2514
+ await unlink(target).catch((error: unknown) => {
2515
+ if (isErrnoCode(error, "ENOENT")) return;
2516
+ throw error;
2517
+ });
2518
+ await this.invalidateAfterOfflineSyncMutation(target);
2519
+ }
2520
+
2521
+ private async invalidateAfterOfflineSyncMutation(filePath: string): Promise<void> {
2522
+ this.invalidateAllMemoriesCache();
2523
+ invalidateCachedEntities(this.baseDir);
2524
+ this.invalidateKnowledgeIndexCache();
2525
+ this.factHashIndexAuthoritative = false;
2526
+ await unlink(this.factHashIndexReadyPath).catch((error: unknown) => {
2527
+ if (isErrnoCode(error, "ENOENT")) return;
2528
+ throw error;
2529
+ });
2530
+ if (filePath.includes(`${path.sep}cold${path.sep}`)) {
2531
+ this.invalidateColdMemoriesCache();
2532
+ }
2533
+ if (filePath.includes(`${path.sep}artifacts${path.sep}`)) {
2534
+ this.bumpArtifactWriteVersion();
2535
+ }
2536
+ this.bumpMemoryStatusVersion();
2537
+ }
2538
+
2481
2539
  createContentHashIndex(): ContentHashIndex {
2482
2540
  return new ContentHashIndex(
2483
2541
  this.stateDir,
@@ -2577,6 +2635,7 @@ export class StorageManager {
2577
2635
  }
2578
2636
 
2579
2637
  const factHashIndex = await this.getFactHashIndex();
2638
+ factHashIndex.clear();
2580
2639
  const existing = await this.readAllMemories();
2581
2640
  let legacyRecovered = 0;
2582
2641
  for (const memory of existing) {