@remnic/core 9.3.651 → 9.3.653

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 (90) hide show
  1. package/dist/access-cli.js +10 -10
  2. package/dist/access-http.d.ts +3 -2
  3. package/dist/access-http.js +12 -12
  4. package/dist/access-mcp.d.ts +3 -2
  5. package/dist/access-mcp.js +11 -11
  6. package/dist/access-schema.d.ts +3 -0
  7. package/dist/access-schema.js +1 -1
  8. package/dist/{access-service-DIZRHQ7Q.d.ts → access-service-CdJFd3_b.d.ts} +23 -2
  9. package/dist/access-service.d.ts +3 -2
  10. package/dist/access-service.js +9 -9
  11. package/dist/bootstrap.d.ts +2 -1
  12. package/dist/briefing.js +1 -1
  13. package/dist/{chunk-QT4THOLT.js → chunk-2DGQLOOM.js} +1 -1
  14. package/dist/chunk-2DGQLOOM.js.map +1 -0
  15. package/dist/{chunk-FOVPSMGI.js → chunk-7WEB3FLJ.js} +2 -2
  16. package/dist/{chunk-IJHLC5CH.js → chunk-BNFRL6QW.js} +31 -21
  17. package/dist/{chunk-IJHLC5CH.js.map → chunk-BNFRL6QW.js.map} +1 -1
  18. package/dist/{chunk-SLYD3AH4.js → chunk-E3J6O6N7.js} +177 -5
  19. package/dist/chunk-E3J6O6N7.js.map +1 -0
  20. package/dist/{chunk-MF32AL7N.js → chunk-EW52H5EM.js} +4 -4
  21. package/dist/{chunk-WJK75OCH.js → chunk-GI45G4BK.js} +2 -2
  22. package/dist/{chunk-76QTEJ2Q.js → chunk-JBHXMCYN.js} +2 -2
  23. package/dist/{chunk-4PTKFBST.js → chunk-JVRPJ7D4.js} +126 -26
  24. package/dist/chunk-JVRPJ7D4.js.map +1 -0
  25. package/dist/{chunk-TQUWNX7C.js → chunk-JX2RINDR.js} +2 -2
  26. package/dist/{chunk-RSS2KWN6.js → chunk-NOBL7OUP.js} +14 -6
  27. package/dist/chunk-NOBL7OUP.js.map +1 -0
  28. package/dist/{chunk-I4COC5XW.js → chunk-PYWNNF2I.js} +47 -9
  29. package/dist/chunk-PYWNNF2I.js.map +1 -0
  30. package/dist/{chunk-RKN5J4RO.js → chunk-QQHIQ7JD.js} +6 -6
  31. package/dist/{chunk-5WSDHTBO.js → chunk-SPMZZUEJ.js} +8 -5
  32. package/dist/chunk-SPMZZUEJ.js.map +1 -0
  33. package/dist/{chunk-4HYSMH7D.js → chunk-UAU5U5ML.js} +3 -2
  34. package/dist/chunk-UAU5U5ML.js.map +1 -0
  35. package/dist/{chunk-LFTLXOFX.js → chunk-WTI35CVJ.js} +2 -2
  36. package/dist/{chunk-6UKL6IXM.js → chunk-YM3LR4LS.js} +5 -5
  37. package/dist/{cli-BG4ybtJr.d.ts → cli-DDo7Qgs-.d.ts} +2 -2
  38. package/dist/cli.d.ts +4 -3
  39. package/dist/cli.js +15 -15
  40. package/dist/explicit-capture.d.ts +2 -1
  41. package/dist/index.d.ts +5 -4
  42. package/dist/index.js +16 -16
  43. package/dist/mcp-memory-inspector-app.d.ts +3 -2
  44. package/dist/namespaces/migrate.js +8 -8
  45. package/dist/namespaces/search.d.ts +18 -1
  46. package/dist/namespaces/search.js +7 -7
  47. package/dist/operator-toolkit.js +9 -9
  48. package/dist/{orchestrator-CX-oqwJq.d.ts → orchestrator-8fTZsa0y.d.ts} +2 -0
  49. package/dist/orchestrator.d.ts +2 -1
  50. package/dist/orchestrator.js +9 -9
  51. package/dist/qmd.d.ts +2 -1
  52. package/dist/qmd.js +2 -2
  53. package/dist/schemas.d.ts +22 -22
  54. package/dist/search/factory.js +6 -6
  55. package/dist/search/index.js +6 -6
  56. package/dist/search/lancedb-backend.js +2 -2
  57. package/dist/search/meilisearch-backend.js +2 -2
  58. package/dist/search/orama-backend.js +2 -2
  59. package/dist/search/port.d.ts +6 -0
  60. package/dist/search/port.js +1 -1
  61. package/dist/transfer/types.d.ts +12 -12
  62. package/package.json +1 -1
  63. package/src/access-mcp.test.ts +70 -1
  64. package/src/access-mcp.ts +12 -2
  65. package/src/access-schema.ts +1 -0
  66. package/src/access-service-health.test.ts +402 -0
  67. package/src/access-service.ts +274 -2
  68. package/src/briefing.test.ts +70 -0
  69. package/src/briefing.ts +30 -20
  70. package/src/namespaces/search.test.ts +258 -3
  71. package/src/namespaces/search.ts +184 -30
  72. package/src/orchestrator.ts +11 -1
  73. package/src/qmd.test.ts +102 -0
  74. package/src/qmd.ts +54 -7
  75. package/src/search/port.ts +6 -0
  76. package/dist/chunk-4HYSMH7D.js.map +0 -1
  77. package/dist/chunk-4PTKFBST.js.map +0 -1
  78. package/dist/chunk-5WSDHTBO.js.map +0 -1
  79. package/dist/chunk-I4COC5XW.js.map +0 -1
  80. package/dist/chunk-QT4THOLT.js.map +0 -1
  81. package/dist/chunk-RSS2KWN6.js.map +0 -1
  82. package/dist/chunk-SLYD3AH4.js.map +0 -1
  83. /package/dist/{chunk-FOVPSMGI.js.map → chunk-7WEB3FLJ.js.map} +0 -0
  84. /package/dist/{chunk-MF32AL7N.js.map → chunk-EW52H5EM.js.map} +0 -0
  85. /package/dist/{chunk-WJK75OCH.js.map → chunk-GI45G4BK.js.map} +0 -0
  86. /package/dist/{chunk-76QTEJ2Q.js.map → chunk-JBHXMCYN.js.map} +0 -0
  87. /package/dist/{chunk-TQUWNX7C.js.map → chunk-JX2RINDR.js.map} +0 -0
  88. /package/dist/{chunk-RKN5J4RO.js.map → chunk-QQHIQ7JD.js.map} +0 -0
  89. /package/dist/{chunk-LFTLXOFX.js.map → chunk-WTI35CVJ.js.map} +0 -0
  90. /package/dist/{chunk-6UKL6IXM.js.map → chunk-YM3LR4LS.js.map} +0 -0
@@ -6,10 +6,10 @@ import {
6
6
  } from "./chunk-7WV3F5DQ.js";
7
7
  import {
8
8
  EngramMcpServer
9
- } from "./chunk-RSS2KWN6.js";
9
+ } from "./chunk-NOBL7OUP.js";
10
10
  import {
11
11
  EngramAccessInputError
12
- } from "./chunk-SLYD3AH4.js";
12
+ } from "./chunk-E3J6O6N7.js";
13
13
  import {
14
14
  projectTagProjectId
15
15
  } from "./chunk-MMJANTJX.js";
@@ -30,7 +30,7 @@ import {
30
30
  } from "./chunk-2ODBA7MQ.js";
31
31
  import {
32
32
  validateRequest
33
- } from "./chunk-4HYSMH7D.js";
33
+ } from "./chunk-UAU5U5ML.js";
34
34
  import {
35
35
  OFFLINE_SYNC_APPLY_MAX_BODY_BYTES,
36
36
  OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES,
@@ -2023,4 +2023,4 @@ function positiveIntQueryParam(value, label) {
2023
2023
  export {
2024
2024
  EngramAccessHttpServer
2025
2025
  };
2026
- //# sourceMappingURL=chunk-MF32AL7N.js.map
2026
+ //# sourceMappingURL=chunk-EW52H5EM.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-ORGWWNJG.js";
4
4
  import {
5
5
  namespaceCollectionName
6
- } from "./chunk-4PTKFBST.js";
6
+ } from "./chunk-JVRPJ7D4.js";
7
7
  import {
8
8
  namespaceIdentityFromToken,
9
9
  namespaceIdentityToken
@@ -204,4 +204,4 @@ export {
204
204
  verifyNamespaces,
205
205
  runNamespaceMigration
206
206
  };
207
- //# sourceMappingURL=chunk-WJK75OCH.js.map
207
+ //# sourceMappingURL=chunk-GI45G4BK.js.map
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-CINZGPSJ.js";
8
8
  import {
9
9
  resolveEnsureCollectionArgs
10
- } from "./chunk-QT4THOLT.js";
10
+ } from "./chunk-2DGQLOOM.js";
11
11
  import {
12
12
  log
13
13
  } from "./chunk-2ODBA7MQ.js";
@@ -605,4 +605,4 @@ export {
605
605
  resolveOramaCollectionDbFilePath,
606
606
  OramaBackend
607
607
  };
608
- //# sourceMappingURL=chunk-76QTEJ2Q.js.map
608
+ //# sourceMappingURL=chunk-JBHXMCYN.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createSearchBackend
3
- } from "./chunk-6UKL6IXM.js";
3
+ } from "./chunk-YM3LR4LS.js";
4
4
  import {
5
5
  namespaceIdentityToken,
6
6
  normalizeNamespaceIdentity
@@ -125,6 +125,50 @@ var NamespaceSearchRouter = class {
125
125
  const record = await this.backendRecordFor(namespace, execution);
126
126
  return record.collectionState;
127
127
  }
128
+ async healthForNamespace(namespace, execution) {
129
+ const key = namespace.trim() || this.config.defaultNamespace;
130
+ const record = await this.createBackendRecordFor(
131
+ key,
132
+ execution,
133
+ {
134
+ autoCreateCollection: false,
135
+ abortAsUnavailable: true,
136
+ failOpenMissingGuardedCollection: false
137
+ }
138
+ );
139
+ try {
140
+ const liveRecord = await this.liveCachedRecordForHealth(key, record, execution);
141
+ const diagnosticBackend = liveRecord?.backend ?? record.backend;
142
+ const versionStatus = "getVersionStatus" in diagnosticBackend && typeof diagnosticBackend.getVersionStatus === "function" ? diagnosticBackend.getVersionStatus() : null;
143
+ const daemonMode = daemonModeForBackend(diagnosticBackend);
144
+ const collectionState = liveRecord?.collectionState === "missing" ? "missing" : record.collectionState;
145
+ return {
146
+ collection: record.collection,
147
+ memoryDir: record.memoryDir,
148
+ available: liveRecord?.available ?? record.available,
149
+ collectionState,
150
+ debugStatus: diagnosticBackend.debugStatus(),
151
+ installedVersion: versionStatus?.installedVersion ?? null,
152
+ supportedVersion: versionStatus?.supportedVersion ?? null,
153
+ supported: versionStatus?.supported ?? null,
154
+ upgradeAvailable: versionStatus?.upgradeAvailable ?? null,
155
+ doctorAvailable: versionStatus?.capabilities?.doctor ?? null,
156
+ daemonMode
157
+ };
158
+ } finally {
159
+ const dispose = record.backend.dispose;
160
+ await dispose?.call(record.backend);
161
+ }
162
+ }
163
+ async liveCachedRecordForHealth(key, disposableRecord, execution) {
164
+ const pending = this.cache.get(key);
165
+ if (!pending) return null;
166
+ const cachedRecord = await awaitWithAbort(pending, execution?.signal).catch(() => null);
167
+ if (!cachedRecord) return null;
168
+ if (cachedRecord.collection !== disposableRecord.collection) return null;
169
+ if (cachedRecord.memoryDir !== disposableRecord.memoryDir) return null;
170
+ return cachedRecord;
171
+ }
128
172
  /** Clear cached backend records so the next access re-probes availability. */
129
173
  clearCache() {
130
174
  this.cache.clear();
@@ -146,25 +190,54 @@ var NamespaceSearchRouter = class {
146
190
  const key = namespace.trim() || this.config.defaultNamespace;
147
191
  const existing = this.cache.get(key);
148
192
  if (existing) return await existing;
149
- const pending = (async () => {
150
- const storage = await this.storageRouter.storageFor(key);
151
- const useLegacyDefaultCollection = key === this.config.defaultNamespace && storage.dir === this.config.memoryDir;
152
- const filtersNestedNamespaces = this.config.namespacesEnabled === true && useLegacyDefaultCollection;
153
- const rootHostEmbeddingScope = this.config.hostEmbeddingProviderScope ?? this.config.memoryDir;
154
- const scopedConfig = {
155
- ...this.config,
156
- memoryDir: storage.dir,
157
- hostEmbeddingProviderScope: rootHostEmbeddingScope,
158
- qmdCollection: namespaceCollectionName(this.config.qmdCollection, key, {
159
- defaultNamespace: this.config.defaultNamespace,
160
- useLegacyDefaultCollection
161
- })
162
- };
163
- const backend = this.createBackend(scopedConfig);
164
- const available = await backend.probe().catch(() => false);
165
- const collectionState = available ? await this.collectionStateForBackend(backend, storage.dir, scopedConfig.qmdCollection, {
166
- skipAutoCreate: filtersNestedNamespaces,
167
- execution
193
+ const pending = this.createBackendRecordFor(key, execution, {
194
+ autoCreateCollection: true,
195
+ abortAsUnavailable: false,
196
+ failOpenMissingGuardedCollection: true
197
+ }).catch((error) => {
198
+ this.cache.delete(key);
199
+ throw error;
200
+ });
201
+ this.cache.set(key, pending);
202
+ return await pending;
203
+ }
204
+ async createBackendRecordFor(namespace, execution, options) {
205
+ const key = namespace.trim() || this.config.defaultNamespace;
206
+ const storage = await this.storageRouter.storageFor(key);
207
+ const useLegacyDefaultCollection = key === this.config.defaultNamespace && storage.dir === this.config.memoryDir;
208
+ const filtersNestedNamespaces = this.config.namespacesEnabled === true && useLegacyDefaultCollection;
209
+ const rootHostEmbeddingScope = this.config.hostEmbeddingProviderScope ?? this.config.memoryDir;
210
+ const scopedConfig = {
211
+ ...this.config,
212
+ memoryDir: storage.dir,
213
+ hostEmbeddingProviderScope: rootHostEmbeddingScope,
214
+ qmdCollection: namespaceCollectionName(this.config.qmdCollection, key, {
215
+ defaultNamespace: this.config.defaultNamespace,
216
+ useLegacyDefaultCollection
217
+ })
218
+ };
219
+ const backend = this.createBackend(scopedConfig);
220
+ try {
221
+ const availabilityProbe = options.autoCreateCollection || typeof backend.checkAvailability !== "function" ? backend.probe() : backend.checkAvailability({ signal: execution?.signal });
222
+ const available = await awaitWithAbort(availabilityProbe, execution?.signal).catch((error) => {
223
+ if (error instanceof NamespaceSearchAbortError && !options.abortAsUnavailable) {
224
+ throw error;
225
+ }
226
+ return false;
227
+ });
228
+ const collectionState = available ? await awaitWithAbort(
229
+ this.collectionStateForBackend(backend, storage.dir, scopedConfig.qmdCollection, {
230
+ autoCreate: options.autoCreateCollection,
231
+ failOpenMissingGuardedCollection: options.failOpenMissingGuardedCollection,
232
+ skipAutoCreate: filtersNestedNamespaces,
233
+ execution
234
+ }),
235
+ execution?.signal
236
+ ).catch((error) => {
237
+ if (error instanceof NamespaceSearchAbortError && !options.abortAsUnavailable) {
238
+ throw error;
239
+ }
240
+ return "unknown";
168
241
  }) : "unknown";
169
242
  return {
170
243
  backend,
@@ -174,19 +247,43 @@ var NamespaceSearchRouter = class {
174
247
  collectionState,
175
248
  filtersNestedNamespaces
176
249
  };
177
- })();
178
- this.cache.set(key, pending);
179
- return await pending;
250
+ } catch (error) {
251
+ const dispose = backend.dispose;
252
+ if (dispose) {
253
+ await Promise.resolve(dispose.call(backend)).catch(() => {
254
+ });
255
+ }
256
+ throw error;
257
+ }
180
258
  }
181
259
  async collectionStateForBackend(backend, memoryDir, collection, options) {
182
- if (options.skipAutoCreate) {
260
+ if (!options.autoCreate || options.skipAutoCreate) {
183
261
  if (!backend.checkCollection) return "unknown";
184
262
  const collectionState = await backend.checkCollection(collection, options.execution).catch(() => "unknown");
185
- return collectionState === "missing" ? "unknown" : collectionState;
263
+ return options.failOpenMissingGuardedCollection && collectionState === "missing" ? "unknown" : collectionState;
186
264
  }
187
265
  return await backend.ensureCollection(memoryDir, collection, options.execution).catch(() => "unknown");
188
266
  }
189
267
  };
268
+ var NamespaceSearchAbortError = class extends Error {
269
+ constructor() {
270
+ super("operation aborted");
271
+ }
272
+ };
273
+ function awaitWithAbort(operation, signal) {
274
+ if (!signal) return operation;
275
+ if (signal.aborted) return Promise.reject(new NamespaceSearchAbortError());
276
+ return new Promise((resolve, reject) => {
277
+ const onAbort = () => {
278
+ signal.removeEventListener("abort", onAbort);
279
+ reject(new NamespaceSearchAbortError());
280
+ };
281
+ signal.addEventListener("abort", onAbort, { once: true });
282
+ operation.then(resolve, reject).finally(() => {
283
+ signal.removeEventListener("abort", onAbort);
284
+ });
285
+ });
286
+ }
190
287
  function filterNamespaceSubtreeResults(record, results) {
191
288
  if (!record.filtersNestedNamespaces) return results;
192
289
  return results.filter(
@@ -201,6 +298,9 @@ function backendSearchLimit(record, maxResults) {
201
298
  NESTED_NAMESPACE_FILTER_OVERFETCH_MIN
202
299
  );
203
300
  }
301
+ function daemonModeForBackend(backend) {
302
+ return "isDaemonMode" in backend && typeof backend.isDaemonMode === "function" ? backend.isDaemonMode() === true : null;
303
+ }
204
304
  function pathIsInsideNamespaceSubtree(memoryDir, collection, resultPath) {
205
305
  if (!resultPath) return false;
206
306
  const normalizedResultPath = normalizeQmdResultPath(resultPath, collection);
@@ -257,4 +357,4 @@ export {
257
357
  namespaceCollectionName,
258
358
  NamespaceSearchRouter
259
359
  };
260
- //# sourceMappingURL=chunk-4PTKFBST.js.map
360
+ //# sourceMappingURL=chunk-JVRPJ7D4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/namespaces/search.ts"],"sourcesContent":["import path from \"node:path\";\nimport type { PluginConfig, QmdSearchResult } from \"../types.js\";\nimport type {\n SearchBackend,\n SearchExecutionOptions,\n SearchQueryOptions,\n} from \"../search/port.js\";\nimport { createSearchBackend } from \"../search/factory.js\";\nimport { namespaceIdentityToken, normalizeNamespaceIdentity } from \"./identity.js\";\n\nconst NESTED_NAMESPACE_FILTER_OVERFETCH_FACTOR = 4;\nconst NESTED_NAMESPACE_FILTER_OVERFETCH_MIN = 50;\n\nexport function namespaceCollectionName(\n baseCollection: string,\n namespace: string,\n options?: {\n defaultNamespace?: string;\n useLegacyDefaultCollection?: boolean;\n },\n): string {\n const trimmed = normalizeNamespaceIdentity(namespace);\n const defaultNamespace = normalizeNamespaceIdentity(options?.defaultNamespace ?? \"\") || \"default\";\n if (\n options?.useLegacyDefaultCollection === true &&\n trimmed === defaultNamespace\n ) {\n return baseCollection;\n }\n\n return `${baseCollection}--${namespaceIdentityToken(trimmed || defaultNamespace)}`;\n}\n\ntype StorageRouterLike = {\n storageFor(namespace: string): Promise<{ dir: string }>;\n};\n\ntype NamespaceBackendRecord = {\n backend: SearchBackend;\n collection: string;\n memoryDir: string;\n available: boolean;\n collectionState: CollectionState;\n filtersNestedNamespaces: boolean;\n};\n\nexport type CollectionState = \"present\" | \"missing\" | \"unknown\" | \"skipped\";\n\nexport interface NamespaceSearchHealth {\n collection: string;\n memoryDir: string;\n available: boolean;\n collectionState: CollectionState;\n debugStatus: string;\n installedVersion: string | null;\n supportedVersion: string | null;\n supported: boolean | null;\n upgradeAvailable: boolean | null;\n doctorAvailable: boolean | null;\n daemonMode: boolean | null;\n}\n\ntype NamespaceScopedSearchConfig = PluginConfig & {\n hostEmbeddingProviderScope?: string;\n};\n\ntype BackendRecordOptions = {\n autoCreateCollection: boolean;\n abortAsUnavailable: boolean;\n failOpenMissingGuardedCollection: boolean;\n};\n\nexport class NamespaceSearchRouter {\n private readonly cache = new Map<string, Promise<NamespaceBackendRecord>>();\n\n constructor(\n private readonly config: PluginConfig,\n private readonly storageRouter: StorageRouterLike,\n private readonly createBackend: (config: PluginConfig) => SearchBackend = createSearchBackend,\n ) {}\n\n async collectionForNamespace(namespace: string): Promise<string> {\n return (await this.backendRecordFor(namespace)).collection;\n }\n\n async searchAcrossNamespaces(options: {\n query: string;\n namespaces: string[];\n maxResults?: number;\n mode?: \"search\" | \"hybrid\" | \"bm25\" | \"vector\";\n searchOptions?: SearchQueryOptions;\n execution?: SearchExecutionOptions;\n }): Promise<QmdSearchResult[]> {\n const query = options.query.trim();\n if (!query) return [];\n const maxResults = Math.max(0, Math.floor(options.maxResults ?? this.config.qmdMaxResults));\n if (maxResults === 0) return [];\n\n const method = options.mode ?? \"search\";\n const namespaces = Array.from(new Set(options.namespaces.map((value) => value.trim()).filter(Boolean)));\n if (namespaces.length === 0) return [];\n\n const resultsByNamespace = await Promise.all(\n namespaces.map(async (namespace) => {\n const record = await this.backendRecordFor(namespace);\n if (!record.available || record.collectionState === \"missing\") {\n return { namespace, results: [] as QmdSearchResult[] };\n }\n const backendLimit = backendSearchLimit(record, maxResults);\n let results: QmdSearchResult[];\n switch (method) {\n case \"hybrid\":\n results = await record.backend.hybridSearch(\n query,\n record.collection,\n backendLimit,\n options.execution,\n );\n break;\n case \"bm25\":\n results = await record.backend.bm25Search(\n query,\n record.collection,\n backendLimit,\n options.execution,\n );\n break;\n case \"vector\":\n results = await record.backend.vectorSearch(\n query,\n record.collection,\n backendLimit,\n options.execution,\n );\n break;\n default:\n results = await record.backend.search(\n query,\n record.collection,\n backendLimit,\n options.searchOptions,\n options.execution,\n );\n break;\n }\n results = filterNamespaceSubtreeResults(record, results);\n return { namespace, results };\n }),\n );\n\n return mergeNamespaceSearchResults(resultsByNamespace, maxResults);\n }\n\n /**\n * Update all namespace backends.\n * Returns the number of backends for which an update was attempted\n * (i.e., available and collection present). Callers can treat 0 as a\n * signal that no backend was eligible — useful for success-verification in\n * startup-sync when namespacesEnabled is true.\n */\n async updateNamespaces(\n namespaces: string[],\n execution?: SearchExecutionOptions,\n ): Promise<number> {\n const unique = Array.from(new Set(namespaces.map((value) => value.trim()).filter(Boolean)));\n const eligible = (await Promise.all(\n unique.map(async (namespace) => {\n const record = await this.backendRecordFor(namespace);\n return record.available && record.collectionState !== \"missing\"\n ? record\n : null;\n }),\n )).filter((record): record is NamespaceBackendRecord => record !== null);\n\n const globalRecord = eligible.find((record) => record.backend.updatesAllCollections?.() === true);\n const scopedRecords = globalRecord\n ? eligible.filter((record) => record.backend.updatesAllCollections?.() !== true)\n : eligible;\n\n await Promise.all([\n globalRecord ? globalRecord.backend.update(execution) : Promise.resolve(),\n ...scopedRecords.map((record) => record.backend.update(execution)),\n ]);\n\n return (globalRecord ? 1 : 0) + scopedRecords.length;\n }\n\n async embedNamespaces(namespaces: string[]): Promise<void> {\n const unique = Array.from(new Set(namespaces.map((value) => value.trim()).filter(Boolean)));\n await Promise.all(\n unique.map(async (namespace) => {\n const record = await this.backendRecordFor(namespace);\n if (!record.available || record.collectionState === \"missing\") return;\n await record.backend.embed();\n }),\n );\n }\n\n async ensureNamespaceCollection(\n namespace: string,\n execution?: SearchExecutionOptions,\n ): Promise<\"present\" | \"missing\" | \"unknown\" | \"skipped\"> {\n const record = await this.backendRecordFor(namespace, execution);\n return record.collectionState;\n }\n\n async healthForNamespace(\n namespace: string,\n execution?: SearchExecutionOptions,\n ): Promise<NamespaceSearchHealth> {\n const key = namespace.trim() || this.config.defaultNamespace;\n const record = await this.createBackendRecordFor(\n key,\n execution,\n {\n autoCreateCollection: false,\n abortAsUnavailable: true,\n failOpenMissingGuardedCollection: false,\n },\n );\n try {\n const liveRecord = await this.liveCachedRecordForHealth(key, record, execution);\n const diagnosticBackend = liveRecord?.backend ?? record.backend;\n const versionStatus =\n \"getVersionStatus\" in diagnosticBackend &&\n typeof diagnosticBackend.getVersionStatus === \"function\"\n ? diagnosticBackend.getVersionStatus()\n : null;\n const daemonMode = daemonModeForBackend(diagnosticBackend);\n const collectionState =\n liveRecord?.collectionState === \"missing\"\n ? \"missing\"\n : record.collectionState;\n\n return {\n collection: record.collection,\n memoryDir: record.memoryDir,\n available: liveRecord?.available ?? record.available,\n collectionState,\n debugStatus: diagnosticBackend.debugStatus(),\n installedVersion: versionStatus?.installedVersion ?? null,\n supportedVersion: versionStatus?.supportedVersion ?? null,\n supported: versionStatus?.supported ?? null,\n upgradeAvailable: versionStatus?.upgradeAvailable ?? null,\n doctorAvailable: versionStatus?.capabilities?.doctor ?? null,\n daemonMode,\n };\n } finally {\n const dispose = (record.backend as { dispose?: () => void | Promise<void> }).dispose;\n await dispose?.call(record.backend);\n }\n }\n\n private async liveCachedRecordForHealth(\n key: string,\n disposableRecord: NamespaceBackendRecord,\n execution?: SearchExecutionOptions,\n ): Promise<NamespaceBackendRecord | null> {\n const pending = this.cache.get(key);\n if (!pending) return null;\n const cachedRecord = await awaitWithAbort(pending, execution?.signal).catch(() => null);\n if (!cachedRecord) return null;\n if (cachedRecord.collection !== disposableRecord.collection) return null;\n if (cachedRecord.memoryDir !== disposableRecord.memoryDir) return null;\n return cachedRecord;\n }\n\n /** Clear cached backend records so the next access re-probes availability. */\n clearCache(): void {\n this.cache.clear();\n }\n\n /** Release any per-namespace backend handles held by cached records. */\n async dispose(): Promise<void> {\n const pendingRecords = Array.from(this.cache.values());\n this.cache.clear();\n const settled = await Promise.allSettled(pendingRecords);\n await Promise.allSettled(\n settled.flatMap((entry) => {\n if (entry.status !== \"fulfilled\") return [];\n const dispose = (entry.value.backend as { dispose?: () => void | Promise<void> }).dispose;\n return dispose ? [dispose.call(entry.value.backend)] : [];\n }),\n );\n }\n\n private async backendRecordFor(\n namespace: string,\n execution?: SearchExecutionOptions,\n ): Promise<NamespaceBackendRecord> {\n const key = namespace.trim() || this.config.defaultNamespace;\n const existing = this.cache.get(key);\n if (existing) return await existing;\n\n const pending = this.createBackendRecordFor(key, execution, {\n autoCreateCollection: true,\n abortAsUnavailable: false,\n failOpenMissingGuardedCollection: true,\n }).catch((error) => {\n this.cache.delete(key);\n throw error;\n });\n\n this.cache.set(key, pending);\n return await pending;\n }\n\n private async createBackendRecordFor(\n namespace: string,\n execution: SearchExecutionOptions | undefined,\n options: BackendRecordOptions,\n ): Promise<NamespaceBackendRecord> {\n const key = namespace.trim() || this.config.defaultNamespace;\n const storage = await this.storageRouter.storageFor(key);\n const useLegacyDefaultCollection =\n key === this.config.defaultNamespace && storage.dir === this.config.memoryDir;\n const filtersNestedNamespaces =\n this.config.namespacesEnabled === true && useLegacyDefaultCollection;\n const rootHostEmbeddingScope =\n (this.config as NamespaceScopedSearchConfig).hostEmbeddingProviderScope ??\n this.config.memoryDir;\n const scopedConfig: NamespaceScopedSearchConfig = {\n ...this.config,\n memoryDir: storage.dir,\n hostEmbeddingProviderScope: rootHostEmbeddingScope,\n qmdCollection: namespaceCollectionName(this.config.qmdCollection, key, {\n defaultNamespace: this.config.defaultNamespace,\n useLegacyDefaultCollection,\n }),\n };\n\n const backend = this.createBackend(scopedConfig);\n try {\n const availabilityProbe =\n options.autoCreateCollection || typeof backend.checkAvailability !== \"function\"\n ? backend.probe()\n : backend.checkAvailability({ signal: execution?.signal });\n const available = await awaitWithAbort(availabilityProbe, execution?.signal).catch((error) => {\n if (error instanceof NamespaceSearchAbortError && !options.abortAsUnavailable) {\n throw error;\n }\n return false;\n });\n const collectionState = available\n ? await awaitWithAbort(\n this.collectionStateForBackend(backend, storage.dir, scopedConfig.qmdCollection, {\n autoCreate: options.autoCreateCollection,\n failOpenMissingGuardedCollection: options.failOpenMissingGuardedCollection,\n skipAutoCreate: filtersNestedNamespaces,\n execution,\n }),\n execution?.signal,\n ).catch((error) => {\n if (error instanceof NamespaceSearchAbortError && !options.abortAsUnavailable) {\n throw error;\n }\n return \"unknown\" as const;\n })\n : \"unknown\";\n return {\n backend,\n collection: scopedConfig.qmdCollection,\n memoryDir: storage.dir,\n available,\n collectionState,\n filtersNestedNamespaces,\n };\n } catch (error) {\n const dispose = (backend as { dispose?: () => void | Promise<void> }).dispose;\n if (dispose) {\n await Promise.resolve(dispose.call(backend)).catch(() => {});\n }\n throw error;\n }\n }\n\n private async collectionStateForBackend(\n backend: SearchBackend,\n memoryDir: string,\n collection: string,\n options: {\n autoCreate: boolean;\n failOpenMissingGuardedCollection: boolean;\n skipAutoCreate: boolean;\n execution?: SearchExecutionOptions;\n },\n ): Promise<CollectionState> {\n if (!options.autoCreate || options.skipAutoCreate) {\n if (!backend.checkCollection) return \"unknown\";\n const collectionState = await backend\n .checkCollection(collection, options.execution)\n .catch(() => \"unknown\" as const);\n return options.failOpenMissingGuardedCollection && collectionState === \"missing\"\n ? \"unknown\"\n : collectionState;\n }\n return await backend.ensureCollection(memoryDir, collection, options.execution).catch(() => \"unknown\" as const);\n }\n}\n\nclass NamespaceSearchAbortError extends Error {\n constructor() {\n super(\"operation aborted\");\n }\n}\n\nfunction awaitWithAbort<T>(operation: Promise<T>, signal?: AbortSignal): Promise<T> {\n if (!signal) return operation;\n if (signal.aborted) return Promise.reject(new NamespaceSearchAbortError());\n\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(new NamespaceSearchAbortError());\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n operation.then(resolve, reject).finally(() => {\n signal.removeEventListener(\"abort\", onAbort);\n });\n });\n}\n\nfunction filterNamespaceSubtreeResults(\n record: NamespaceBackendRecord,\n results: QmdSearchResult[],\n): QmdSearchResult[] {\n if (!record.filtersNestedNamespaces) return results;\n return results.filter((result) =>\n !pathIsInsideNamespaceSubtree(record.memoryDir, record.collection, result.path)\n );\n}\n\nfunction backendSearchLimit(\n record: NamespaceBackendRecord,\n maxResults: number,\n): number {\n if (!record.filtersNestedNamespaces) return maxResults;\n return Math.max(\n maxResults,\n maxResults * NESTED_NAMESPACE_FILTER_OVERFETCH_FACTOR,\n NESTED_NAMESPACE_FILTER_OVERFETCH_MIN,\n );\n}\n\nfunction daemonModeForBackend(backend: SearchBackend): boolean | null {\n return \"isDaemonMode\" in backend && typeof backend.isDaemonMode === \"function\"\n ? backend.isDaemonMode() === true\n : null;\n}\n\nfunction pathIsInsideNamespaceSubtree(\n memoryDir: string,\n collection: string,\n resultPath: string | undefined,\n): boolean {\n if (!resultPath) return false;\n const normalizedResultPath = normalizeQmdResultPath(resultPath, collection);\n const memoryRoot = path.resolve(memoryDir);\n const namespacesRoot = path.join(memoryRoot, \"namespaces\");\n const candidate = path.isAbsolute(normalizedResultPath)\n ? path.normalize(normalizedResultPath)\n : path.resolve(memoryRoot, normalizedResultPath);\n const relative = path.relative(namespacesRoot, candidate);\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\nfunction normalizeQmdResultPath(resultPath: string, collection: string): string {\n let value = resultPath.trim();\n if (value.startsWith(\"qmd://\")) {\n try {\n const parsed = new URL(value);\n if (parsed.protocol === \"qmd:\" && parsed.hostname === collection) {\n value = decodeURIComponent(parsed.pathname.replace(/^\\/+/, \"\"));\n }\n } catch {\n const remainder = value.slice(\"qmd://\".length);\n const slashIndex = remainder.indexOf(\"/\");\n if (slashIndex !== -1) {\n value = remainder.slice(slashIndex + 1);\n }\n }\n }\n\n const collectionPrefix = `${collection}/`;\n if (value.startsWith(collectionPrefix)) {\n value = value.slice(collectionPrefix.length);\n }\n return value;\n}\n\nfunction mergeNamespaceSearchResults(\n lists: Array<{ namespace: string; results: QmdSearchResult[] }>,\n maxResults: number,\n): QmdSearchResult[] {\n const merged = new Map<string, QmdSearchResult>();\n\n for (const { namespace, results } of lists) {\n for (const result of results) {\n const key = `${namespace}\\0${result.path || result.docid}`;\n const existing = merged.get(key);\n if (!existing) {\n merged.set(key, result);\n continue;\n }\n if (result.score > existing.score) {\n merged.set(key, {\n ...result,\n snippet: existing.snippet || result.snippet || \"\",\n });\n }\n }\n }\n\n return [...merged.values()]\n .sort((a, b) => b.score - a.score)\n .slice(0, maxResults);\n}\n"],"mappings":"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","names":[]}
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-CINZGPSJ.js";
8
8
  import {
9
9
  resolveEnsureCollectionArgs
10
- } from "./chunk-QT4THOLT.js";
10
+ } from "./chunk-2DGQLOOM.js";
11
11
  import {
12
12
  log
13
13
  } from "./chunk-2ODBA7MQ.js";
@@ -245,4 +245,4 @@ function isMeilisearchIndexNotFoundError(err) {
245
245
  export {
246
246
  MeilisearchBackend
247
247
  };
248
- //# sourceMappingURL=chunk-TQUWNX7C.js.map
248
+ //# sourceMappingURL=chunk-JX2RINDR.js.map
@@ -11,13 +11,16 @@ import {
11
11
  } from "./chunk-D24OXEPB.js";
12
12
  import {
13
13
  EngramAccessInputError
14
- } from "./chunk-SLYD3AH4.js";
14
+ } from "./chunk-E3J6O6N7.js";
15
15
  import {
16
16
  projectTagProjectId
17
17
  } from "./chunk-MMJANTJX.js";
18
18
  import {
19
19
  validateBriefingFormat
20
- } from "./chunk-IJHLC5CH.js";
20
+ } from "./chunk-BNFRL6QW.js";
21
+ import {
22
+ resolvePrincipal
23
+ } from "./chunk-UZYLX7M6.js";
21
24
  import {
22
25
  expandTildePath
23
26
  } from "./chunk-EYIEWJNI.js";
@@ -26,7 +29,7 @@ import {
26
29
  } from "./chunk-JUC24CTX.js";
27
30
  import {
28
31
  validateRequest
29
- } from "./chunk-4HYSMH7D.js";
32
+ } from "./chunk-UAU5U5ML.js";
30
33
 
31
34
  // src/access-mcp.ts
32
35
  import { readFile } from "fs/promises";
@@ -104,7 +107,7 @@ var STRICT_MCP_SCHEMA_KEYS = {
104
107
  "projectTag"
105
108
  ],
106
109
  capsuleImport: ["archivePath", "namespace", "mode", "passphrase", "cwd", "projectTag"],
107
- capsuleList: ["namespace", "cwd", "projectTag"]
110
+ capsuleList: ["namespace", "sessionKey", "cwd", "projectTag"]
108
111
  };
109
112
  var MCP_GIT_CONTEXT_SCHEMA_PROPS_SCOPED = {
110
113
  cwd: {
@@ -701,6 +704,10 @@ var EngramMcpServer = class {
701
704
  type: "object",
702
705
  properties: {
703
706
  namespace: { type: "string" },
707
+ sessionKey: {
708
+ type: "string",
709
+ description: "Optional session key used to derive namespace principal when no trusted transport principal is present."
710
+ },
704
711
  ...MCP_GIT_CONTEXT_SCHEMA_PROPS_IGNORED
705
712
  },
706
713
  additionalProperties: false
@@ -2407,9 +2414,10 @@ ${body}`;
2407
2414
  }
2408
2415
  case "engram.capsule_list": {
2409
2416
  const body = parseMcpRequest("capsuleList", args);
2417
+ const requestPrincipal = effectivePrincipal ?? (body.sessionKey && this.service.configRef ? resolvePrincipal(body.sessionKey, this.service.configRef) : void 0);
2410
2418
  return this.service.capsuleList({
2411
2419
  namespace: body.namespace,
2412
- principal: effectivePrincipal
2420
+ principal: requestPrincipal
2413
2421
  });
2414
2422
  }
2415
2423
  case "engram.memory_governance_run":
@@ -3102,4 +3110,4 @@ ${body}`;
3102
3110
  export {
3103
3111
  EngramMcpServer
3104
3112
  };
3105
- //# sourceMappingURL=chunk-RSS2KWN6.js.map
3113
+ //# sourceMappingURL=chunk-NOBL7OUP.js.map