@remnic/core 9.3.641 → 9.3.643

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.
@@ -37,14 +37,19 @@ function buildChatGptMemoryInspectorActionRequest(input, recall, xray) {
37
37
  }
38
38
  function buildChatGptMemoryInspectorResult(input, recall, xray, actionConfidence) {
39
39
  const xrayUnavailable = xray === null;
40
- const matchXrayResult = buildXrayResultMatcher(xray);
40
+ const allowUnverifiedPreview = input.allowUnverifiedPreview === true;
41
+ const matchXrayResult = buildXrayResultMatcher(xray, recall.results);
41
42
  const matchedXrayResults = recall.results.map(matchXrayResult);
43
+ const hasBlockedSameId = buildBlockedSameIdMatcher(xray);
42
44
  const memories = recall.results.slice(0, 8).map((summary) => {
43
45
  const xrayResult = matchXrayResult(summary);
44
46
  const provenance = xrayResult?.provenance;
45
- const unverified = !xrayUnavailable && provenance === void 0;
46
- const blocked = provenance?.safety === "blocked";
47
- const preview = xrayUnavailable ? "Preview withheld: X-ray provenance was unavailable for this recall." : unverified ? "Preview withheld: X-ray provenance was missing for this memory." : blocked ? "Preview withheld: this memory is blocked in the current context." : summary.preview;
47
+ const blockedByAmbiguousSameId = !xrayUnavailable && xrayResult === void 0 && hasBlockedSameId(summary.id);
48
+ const blocked = provenance?.safety === "blocked" || blockedByAmbiguousSameId;
49
+ const unverified = !xrayUnavailable && provenance === void 0 && !blockedByAmbiguousSameId;
50
+ const preview = xrayUnavailable ? allowUnverifiedPreview ? summary.preview : "Preview withheld: X-ray provenance was unavailable for this recall." : blocked ? "Preview withheld: this memory is blocked in the current context." : unverified ? allowUnverifiedPreview ? summary.preview : "Preview withheld: X-ray provenance was missing for this memory." : summary.preview;
51
+ const fallbackSafety = blockedByAmbiguousSameId ? "blocked" : xrayUnavailable || unverified ? allowUnverifiedPreview ? "requires-review" : "blocked" : void 0;
52
+ const fallbackSafetyReason = xrayUnavailable ? "X-ray provenance was unavailable for this recall." : blockedByAmbiguousSameId ? "An unmatched X-ray row with this memory id was blocked." : "X-ray provenance was missing for this memory.";
48
53
  return {
49
54
  id: summary.id,
50
55
  path: summary.path,
@@ -59,15 +64,25 @@ function buildChatGptMemoryInspectorResult(input, recall, xray, actionConfidence
59
64
  confidence: provenance?.confidence,
60
65
  stale: provenance?.stale,
61
66
  corrected: provenance?.corrected,
62
- safeToUse: provenance?.safeToUse ?? (unverified ? false : void 0),
63
- safety: provenance?.safety ?? (unverified ? "blocked" : void 0),
64
- safetyReasons: provenance?.safetyReasons ?? (unverified ? ["X-ray provenance was missing for this memory."] : []),
67
+ safeToUse: provenance?.safeToUse ?? (xrayUnavailable || unverified || blockedByAmbiguousSameId ? false : void 0),
68
+ safety: provenance?.safety ?? fallbackSafety,
69
+ safetyReasons: provenance?.safetyReasons ?? (xrayUnavailable || unverified || blockedByAmbiguousSameId ? [fallbackSafetyReason] : []),
65
70
  userContextScopes: provenance?.userContextScopes ?? []
66
71
  };
67
72
  });
68
73
  const blockedCount = matchedXrayResults.filter((result) => result?.provenance?.safety === "blocked").length;
69
- const missingProvenanceCount = xrayUnavailable ? 0 : matchedXrayResults.filter((result) => result?.provenance === void 0).length;
70
- const safeRecallPreview = xrayUnavailable ? "Recall preview withheld: X-ray provenance was unavailable, so memory safety could not be verified." : blockedCount > 0 || missingProvenanceCount > 0 ? formatUnsafeRecallPreview(blockedCount, missingProvenanceCount) : truncate(recall.context, 1500);
74
+ const ambiguousBlockedCount = recall.results.filter(
75
+ (summary, index) => matchedXrayResults[index] === void 0 && hasBlockedSameId(summary.id)
76
+ ).length;
77
+ const missingProvenanceCount = xrayUnavailable ? 0 : matchedXrayResults.filter(
78
+ (result, index) => result?.provenance === void 0 && !(result === void 0 && hasBlockedSameId(recall.results[index]?.id ?? ""))
79
+ ).length;
80
+ const totalBlockedCount = blockedCount + ambiguousBlockedCount;
81
+ const safeRecallPreview = xrayUnavailable ? allowUnverifiedPreview ? `Unverified recall preview: X-ray provenance was unavailable, so memory safety could not be verified.
82
+
83
+ ${truncate(recall.context, 1500)}` : "Recall preview withheld: X-ray provenance was unavailable, so memory safety could not be verified." : totalBlockedCount > 0 || missingProvenanceCount > 0 ? totalBlockedCount > 0 || !allowUnverifiedPreview ? formatUnsafeRecallPreview(totalBlockedCount, missingProvenanceCount) : `Unverified recall preview: ${missingProvenanceCount} retrieved ${memoryNoun(missingProvenanceCount)} ${isAre(missingProvenanceCount)} missing X-ray provenance.
84
+
85
+ ${truncate(recall.context, 1500)}` : truncate(recall.context, 1500);
71
86
  const primaryMemoryId = memories[0]?.id ?? "<memory-id>";
72
87
  return {
73
88
  app: {
@@ -264,7 +279,7 @@ function buildRecallProvenances(recall, xray) {
264
279
  if (xray === null) {
265
280
  return recall.results.map(missingRecallProvenance);
266
281
  }
267
- const matchXrayResult = buildXrayResultMatcher(xray);
282
+ const matchXrayResult = buildXrayResultMatcher(xray, recall.results);
268
283
  return recall.results.map((summary) => {
269
284
  const result = matchXrayResult(summary);
270
285
  if (result === void 0) {
@@ -273,20 +288,36 @@ function buildRecallProvenances(recall, xray) {
273
288
  return result.provenance ?? missingProvenance(result);
274
289
  });
275
290
  }
276
- function buildXrayResultMatcher(xray) {
291
+ function buildXrayResultMatcher(xray, recallResults) {
277
292
  const xrayById = /* @__PURE__ */ new Map();
293
+ const xrayIdCounts = /* @__PURE__ */ new Map();
294
+ const recallIdCounts = /* @__PURE__ */ new Map();
278
295
  const xrayByPath = /* @__PURE__ */ new Map();
296
+ for (const summary of recallResults) {
297
+ recallIdCounts.set(summary.id, (recallIdCounts.get(summary.id) ?? 0) + 1);
298
+ }
279
299
  for (const result of xray?.results ?? []) {
280
300
  xrayById.set(result.memoryId, result);
301
+ xrayIdCounts.set(result.memoryId, (xrayIdCounts.get(result.memoryId) ?? 0) + 1);
281
302
  xrayByPath.set(result.path, result);
282
303
  }
283
304
  return (summary) => {
284
305
  if (summary.path) {
285
- return xrayByPath.get(summary.path);
306
+ const pathMatch = xrayByPath.get(summary.path);
307
+ if (pathMatch) return pathMatch;
286
308
  }
287
- return xrayById.get(summary.id);
309
+ return xrayIdCounts.get(summary.id) === 1 && recallIdCounts.get(summary.id) === 1 ? xrayById.get(summary.id) : void 0;
288
310
  };
289
311
  }
312
+ function buildBlockedSameIdMatcher(xray) {
313
+ const blockedIds = /* @__PURE__ */ new Set();
314
+ for (const result of xray?.results ?? []) {
315
+ if (result.provenance?.safety === "blocked") {
316
+ blockedIds.add(result.memoryId);
317
+ }
318
+ }
319
+ return (memoryId) => blockedIds.has(memoryId);
320
+ }
290
321
  function missingProvenance(result) {
291
322
  return {
292
323
  source: "unknown",
@@ -368,4 +399,4 @@ export {
368
399
  buildChatGptMemoryInspectorResult,
369
400
  REMNIC_CHATGPT_MEMORY_INSPECTOR_WIDGET_HTML
370
401
  };
371
- //# sourceMappingURL=chunk-6L46YAEZ.js.map
402
+ //# sourceMappingURL=chunk-T4WDJPEZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp-memory-inspector-app.ts"],"sourcesContent":["import type { EngramAccessRecallResponse } from \"./access-service.js\";\nimport type { ActionConfidenceRequest } from \"./access-schema.js\";\nimport type { RecallXrayResult, RecallXraySnapshot } from \"./recall-xray.js\";\nimport type { ActionConfidenceResult } from \"./action-confidence.js\";\nimport type { RetrievedMemoryProvenance } from \"./memory-provenance.js\";\n\nexport const REMNIC_CHATGPT_MEMORY_INSPECTOR_TOOL =\n \"engram.chatgpt_memory_inspector\" as const;\nexport const REMNIC_CHATGPT_MEMORY_INSPECTOR_CANONICAL_TOOL =\n \"remnic.chatgpt_memory_inspector\" as const;\nexport const REMNIC_CHATGPT_MEMORY_INSPECTOR_WIDGET_URI =\n \"ui://remnic/memory-inspector.v1.html\" as const;\nexport const REMNIC_CHATGPT_MEMORY_INSPECTOR_MIME_TYPE =\n \"text/html;profile=mcp-app\" as const;\n\nexport interface RemnicChatGptMemoryInspectorInput {\n query: string;\n sessionKey?: string;\n namespace?: string;\n currentContextScopes?: string[];\n allowUnverifiedPreview?: boolean;\n}\n\nexport interface RemnicChatGptMemoryCard {\n id: string;\n path?: string;\n category?: string;\n status?: string;\n preview?: string;\n servedBy?: string;\n score?: number;\n source?: string;\n scope?: string;\n retrievalReason?: string;\n confidence?: number;\n stale?: boolean;\n corrected?: boolean;\n safeToUse?: boolean;\n safety?: string;\n safetyReasons: string[];\n userContextScopes: string[];\n}\n\nexport interface RemnicChatGptMemoryInspectorResult {\n app: {\n name: \"Remnic Memory Inspector\";\n resourceUri: typeof REMNIC_CHATGPT_MEMORY_INSPECTOR_WIDGET_URI;\n archetype: \"vanilla-widget\";\n };\n query: string;\n sessionKey?: string;\n namespace: string;\n safeRecallPreview: string;\n memoryCount: number;\n memoryIds: string[];\n memories: RemnicChatGptMemoryCard[];\n actionConfidence: ActionConfidenceResult;\n affordances: Array<{\n id: \"why\" | \"correct\" | \"forget\" | \"scope\";\n label: string;\n followUpPrompt: string;\n }>;\n guidance: {\n correctionTool: \"remnic.suggestion_submit\";\n forgetTool: \"remnic.memory_action_apply\";\n scopeTool: \"remnic.memory_action_apply\";\n note: string;\n };\n}\n\nexport function buildChatGptMemoryInspectorActionRequest(\n input: RemnicChatGptMemoryInspectorInput,\n recall: EngramAccessRecallResponse,\n xray: RecallXraySnapshot | null,\n): ActionConfidenceRequest {\n const provenances = buildRecallProvenances(recall, xray);\n const hasUnsafeOrMissingProvenance = provenances.some(\n (provenance) => provenance.safeToUse === false || provenance.safety === \"blocked\",\n ) || provenances.length < recall.count;\n\n const request: ActionConfidenceRequest = {\n intendedAction: `Use Remnic memory to answer: ${input.query}`,\n risk: \"medium\",\n contextReadiness:\n recall.count > 0 && !hasUnsafeOrMissingProvenance ? \"sufficient\" : \"partial\",\n retrievedMemories: provenances.map((provenance) => ({\n source: provenance.source,\n created: provenance.created,\n updated: provenance.updated,\n scope: provenance.scope,\n userContextScopes: provenance.userContextScopes,\n retrievalReason: provenance.retrievalReason,\n confidence: provenance.confidence,\n stale: provenance.stale,\n corrected: provenance.corrected,\n correctionState: provenance.correctionState,\n safeToUse: provenance.safeToUse,\n safety: provenance.safety,\n safetyReasons: provenance.safetyReasons,\n })),\n };\n const confidence = provenances.length > 0\n ? average(provenances.map((provenance) => provenance.confidence ?? 0.5))\n : undefined;\n if (confidence !== undefined) request.confidence = confidence;\n if (input.currentContextScopes !== undefined) {\n request.currentContextScopes = input.currentContextScopes;\n }\n return request;\n}\n\nexport function buildChatGptMemoryInspectorResult(\n input: RemnicChatGptMemoryInspectorInput,\n recall: EngramAccessRecallResponse,\n xray: RecallXraySnapshot | null,\n actionConfidence: ActionConfidenceResult,\n): RemnicChatGptMemoryInspectorResult {\n const xrayUnavailable = xray === null;\n const allowUnverifiedPreview = input.allowUnverifiedPreview === true;\n const matchXrayResult = buildXrayResultMatcher(xray, recall.results);\n const matchedXrayResults = recall.results.map(matchXrayResult);\n const hasBlockedSameId = buildBlockedSameIdMatcher(xray);\n\n const memories = recall.results.slice(0, 8).map((summary) => {\n const xrayResult = matchXrayResult(summary);\n const provenance = xrayResult?.provenance;\n const blockedByAmbiguousSameId = !xrayUnavailable\n && xrayResult === undefined\n && hasBlockedSameId(summary.id);\n const blocked = provenance?.safety === \"blocked\" || blockedByAmbiguousSameId;\n const unverified = !xrayUnavailable && provenance === undefined && !blockedByAmbiguousSameId;\n const preview = xrayUnavailable\n ? allowUnverifiedPreview\n ? summary.preview\n : \"Preview withheld: X-ray provenance was unavailable for this recall.\"\n : blocked\n ? \"Preview withheld: this memory is blocked in the current context.\"\n : unverified\n ? allowUnverifiedPreview\n ? summary.preview\n : \"Preview withheld: X-ray provenance was missing for this memory.\"\n : summary.preview;\n const fallbackSafety = blockedByAmbiguousSameId\n ? \"blocked\"\n : xrayUnavailable || unverified\n ? allowUnverifiedPreview\n ? \"requires-review\"\n : \"blocked\"\n : undefined;\n const fallbackSafetyReason = xrayUnavailable\n ? \"X-ray provenance was unavailable for this recall.\"\n : blockedByAmbiguousSameId\n ? \"An unmatched X-ray row with this memory id was blocked.\"\n : \"X-ray provenance was missing for this memory.\";\n return {\n id: summary.id,\n path: summary.path,\n category: summary.category,\n status: summary.status,\n preview,\n servedBy: xrayResult?.servedBy,\n score: xrayResult?.scoreDecomposition.final,\n source: provenance?.source,\n scope: provenance?.scope,\n retrievalReason: provenance?.retrievalReason,\n confidence: provenance?.confidence,\n stale: provenance?.stale,\n corrected: provenance?.corrected,\n safeToUse: provenance?.safeToUse\n ?? (xrayUnavailable || unverified || blockedByAmbiguousSameId ? false : undefined),\n safety: provenance?.safety ?? fallbackSafety,\n safetyReasons: provenance?.safetyReasons\n ?? (\n xrayUnavailable || unverified || blockedByAmbiguousSameId\n ? [fallbackSafetyReason]\n : []\n ),\n userContextScopes: provenance?.userContextScopes ?? [],\n };\n });\n const blockedCount = matchedXrayResults\n .filter((result) => result?.provenance?.safety === \"blocked\")\n .length;\n const ambiguousBlockedCount = recall.results\n .filter((summary, index) =>\n matchedXrayResults[index] === undefined && hasBlockedSameId(summary.id)\n )\n .length;\n const missingProvenanceCount = xrayUnavailable\n ? 0\n : matchedXrayResults\n .filter((result, index) =>\n result?.provenance === undefined\n && !(result === undefined && hasBlockedSameId(recall.results[index]?.id ?? \"\"))\n )\n .length;\n const totalBlockedCount = blockedCount + ambiguousBlockedCount;\n const safeRecallPreview = xrayUnavailable\n ? allowUnverifiedPreview\n ? `Unverified recall preview: X-ray provenance was unavailable, so memory safety could not be verified.\\n\\n${truncate(recall.context, 1_500)}`\n : \"Recall preview withheld: X-ray provenance was unavailable, so memory safety could not be verified.\"\n : totalBlockedCount > 0 || missingProvenanceCount > 0\n ? totalBlockedCount > 0 || !allowUnverifiedPreview\n ? formatUnsafeRecallPreview(totalBlockedCount, missingProvenanceCount)\n : `Unverified recall preview: ${missingProvenanceCount} retrieved ${memoryNoun(missingProvenanceCount)} ${isAre(missingProvenanceCount)} missing X-ray provenance.\\n\\n${truncate(recall.context, 1_500)}`\n : truncate(recall.context, 1_500);\n\n const primaryMemoryId = memories[0]?.id ?? \"<memory-id>\";\n return {\n app: {\n name: \"Remnic Memory Inspector\",\n resourceUri: REMNIC_CHATGPT_MEMORY_INSPECTOR_WIDGET_URI,\n archetype: \"vanilla-widget\",\n },\n query: recall.query || input.query,\n ...(input.sessionKey ? { sessionKey: input.sessionKey } : {}),\n namespace: recall.namespace,\n safeRecallPreview,\n memoryCount: recall.count,\n memoryIds: recall.memoryIds,\n memories,\n actionConfidence,\n affordances: [\n {\n id: \"why\",\n label: \"Why retrieved\",\n followUpPrompt:\n `Explain why Remnic retrieved memory ${primaryMemoryId} for \"${input.query}\" using its provenance, score, safety, and retrieval reason.`,\n },\n {\n id: \"correct\",\n label: \"Correct\",\n followUpPrompt:\n `Help me correct memory ${primaryMemoryId}. Draft a replacement or correction and use remnic.suggestion_submit with dryRun first.`,\n },\n {\n id: \"forget\",\n label: \"Forget\",\n followUpPrompt:\n `Help me forget or quarantine memory ${primaryMemoryId}. Ask me to confirm before using any destructive or persistent Remnic action.`,\n },\n {\n id: \"scope\",\n label: \"Scope\",\n followUpPrompt:\n `Help me scope memory ${primaryMemoryId} so it is only used in the right context. Prefer a dry-run Remnic action before any persistent change.`,\n },\n ],\n guidance: {\n correctionTool: \"remnic.suggestion_submit\",\n forgetTool: \"remnic.memory_action_apply\",\n scopeTool: \"remnic.memory_action_apply\",\n note:\n \"The demo only proposes correction, forget, and scoping flows. The widget sends follow-up prompts; persistent changes still require an explicit tool call and user confirmation.\",\n },\n };\n}\n\nexport const REMNIC_CHATGPT_MEMORY_INSPECTOR_WIDGET_HTML = `\n<div id=\"root\" class=\"remnic-app\">Loading Remnic memory inspector...</div>\n<style>\n :root {\n color-scheme: light dark;\n --bg: #f8faf8;\n --panel: #ffffff;\n --text: #17201b;\n --muted: #56635b;\n --line: #d8e0da;\n --accent: #2f7d57;\n --warn: #9a5b14;\n --bad: #9c2b2b;\n }\n @media (prefers-color-scheme: dark) {\n :root {\n --bg: #101512;\n --panel: #18201b;\n --text: #edf4ef;\n --muted: #a8b6ad;\n --line: #304036;\n --accent: #75c79a;\n --warn: #e0ad63;\n --bad: #f08a8a;\n }\n }\n body { margin: 0; background: var(--bg); color: var(--text); font: 14px/1.45 system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; }\n .remnic-app { padding: 14px; display: grid; gap: 12px; }\n .header, .section, .memory { background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 12px; }\n .title { font-size: 16px; font-weight: 650; margin: 0; }\n .muted { color: var(--muted); }\n .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px; }\n .pill { display: inline-flex; align-items: center; gap: 4px; border: 1px solid var(--line); border-radius: 999px; padding: 2px 8px; margin: 2px 4px 2px 0; color: var(--muted); }\n .safe { color: var(--accent); }\n .review { color: var(--warn); }\n .blocked { color: var(--bad); }\n .memory { display: grid; gap: 8px; }\n .memory-title { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; font-weight: 650; }\n .preview { white-space: pre-wrap; overflow-wrap: anywhere; }\n .actions { display: flex; flex-wrap: wrap; gap: 8px; }\n button { border: 1px solid var(--line); background: transparent; color: var(--text); border-radius: 6px; padding: 6px 9px; font: inherit; cursor: pointer; }\n button:hover { border-color: var(--accent); }\n pre { white-space: pre-wrap; overflow-wrap: anywhere; margin: 0; color: var(--muted); }\n</style>\n<script>\n const root = document.getElementById(\"root\");\n\n function escapeHtml(value) {\n return String(value ?? \"\").replace(/[&<>\"']/g, (char) => ({\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&#39;\",\n }[char]));\n }\n\n function statusClass(value) {\n if (value === \"blocked\" || value === false) return \"blocked\";\n if (value === \"requires-review\") return \"review\";\n return \"safe\";\n }\n\n function followUp(prompt) {\n if (window.openai?.sendFollowUpMessage) {\n window.openai.sendFollowUpMessage({ prompt, scrollToBottom: true });\n return;\n }\n window.parent.postMessage({\n jsonrpc: \"2.0\",\n method: \"ui/message\",\n params: {\n role: \"user\",\n content: [{ type: \"text\", text: prompt }],\n },\n }, \"*\");\n }\n\n function actionButtons(actions) {\n return (actions ?? []).map((action) =>\n '<button type=\"button\" data-prompt=\"' + escapeHtml(action.followUpPrompt) + '\">' +\n escapeHtml(action.label) +\n '</button>'\n ).join(\"\");\n }\n\n function render(payload) {\n const data = payload?.structuredContent ?? payload ?? window.openai?.toolOutput ?? {};\n const confidence = data.actionConfidence ?? {};\n const memories = Array.isArray(data.memories) ? data.memories : [];\n root.innerHTML = [\n '<section class=\"header\">',\n '<p class=\"title\">Remnic Memory Inspector</p>',\n '<div class=\"muted\">' + escapeHtml(data.query ?? \"No query\") + '</div>',\n '<div class=\"grid\">',\n '<div><strong>Namespace</strong><br><span class=\"muted\">' + escapeHtml(data.namespace ?? \"default\") + '</span></div>',\n '<div><strong>Decision</strong><br><span class=\"' + statusClass(confidence.decision) + '\">' + escapeHtml(confidence.decision ?? \"unknown\") + '</span></div>',\n '<div><strong>Memories</strong><br><span class=\"muted\">' + escapeHtml(data.memoryCount ?? memories.length) + '</span></div>',\n '</div>',\n '</section>',\n '<section class=\"section\">',\n '<strong>Safe recall preview</strong>',\n '<pre>' + escapeHtml(data.safeRecallPreview ?? \"\") + '</pre>',\n '</section>',\n '<section class=\"section actions\">',\n actionButtons(data.affordances),\n '</section>',\n memories.map((memory) => [\n '<article class=\"memory\">',\n '<div class=\"memory-title\"><span>' + escapeHtml(memory.id) + '</span><span class=\"' + statusClass(memory.safety) + '\">' + escapeHtml(memory.safety ?? \"safe\") + '</span></div>',\n '<div class=\"preview\">' + escapeHtml(memory.preview ?? \"\") + '</div>',\n '<div>',\n '<span class=\"pill\">source ' + escapeHtml(memory.source ?? \"unknown\") + '</span>',\n '<span class=\"pill\">scope ' + escapeHtml(memory.scope ?? \"unknown\") + '</span>',\n '<span class=\"pill\">reason ' + escapeHtml(memory.retrievalReason ?? memory.servedBy ?? \"unknown\") + '</span>',\n '<span class=\"pill\">confidence ' + escapeHtml(memory.confidence ?? \"n/a\") + '</span>',\n '</div>',\n '<div class=\"muted\">' + escapeHtml((memory.safetyReasons ?? []).join(\"; \")) + '</div>',\n '</article>',\n ].join(\"\")).join(\"\"),\n ].join(\"\");\n\n root.querySelectorAll(\"button[data-prompt]\").forEach((button) => {\n button.addEventListener(\"click\", () => followUp(button.getAttribute(\"data-prompt\") ?? \"\"));\n });\n }\n\n render(window.openai?.toolOutput);\n\n window.addEventListener(\"message\", (event) => {\n if (event.source !== window.parent) return;\n const message = event.data;\n if (!message || message.jsonrpc !== \"2.0\") return;\n if (message.method === \"ui/notifications/tool-result\") {\n render(message.params);\n }\n }, { passive: true });\n\n window.addEventListener(\"openai:set_globals\", (event) => {\n render(event.detail?.globals?.toolOutput ?? window.openai?.toolOutput);\n }, { passive: true });\n</script>\n`.trim();\n\nfunction average(values: number[]): number | undefined {\n if (values.length === 0) return undefined;\n return values.reduce((sum, value) => sum + value, 0) / values.length;\n}\n\nfunction buildRecallProvenances(\n recall: EngramAccessRecallResponse,\n xray: RecallXraySnapshot | null,\n): RetrievedMemoryProvenance[] {\n if (xray === null) {\n return recall.results.map(missingRecallProvenance);\n }\n const matchXrayResult = buildXrayResultMatcher(xray, recall.results);\n return recall.results.map((summary) => {\n const result = matchXrayResult(summary);\n if (result === undefined) {\n return missingXrayResultProvenance(summary);\n }\n return result.provenance ?? missingProvenance(result);\n });\n}\n\nfunction buildXrayResultMatcher(\n xray: RecallXraySnapshot | null,\n recallResults: EngramAccessRecallResponse[\"results\"],\n): (summary: EngramAccessRecallResponse[\"results\"][number]) => RecallXrayResult | undefined {\n const xrayById = new Map<string, RecallXrayResult>();\n const xrayIdCounts = new Map<string, number>();\n const recallIdCounts = new Map<string, number>();\n const xrayByPath = new Map<string, RecallXrayResult>();\n for (const summary of recallResults) {\n recallIdCounts.set(summary.id, (recallIdCounts.get(summary.id) ?? 0) + 1);\n }\n for (const result of xray?.results ?? []) {\n xrayById.set(result.memoryId, result);\n xrayIdCounts.set(result.memoryId, (xrayIdCounts.get(result.memoryId) ?? 0) + 1);\n xrayByPath.set(result.path, result);\n }\n return (summary) => {\n if (summary.path) {\n const pathMatch = xrayByPath.get(summary.path);\n if (pathMatch) return pathMatch;\n }\n return xrayIdCounts.get(summary.id) === 1 && recallIdCounts.get(summary.id) === 1\n ? xrayById.get(summary.id)\n : undefined;\n };\n}\n\nfunction buildBlockedSameIdMatcher(\n xray: RecallXraySnapshot | null,\n): (memoryId: string) => boolean {\n const blockedIds = new Set<string>();\n for (const result of xray?.results ?? []) {\n if (result.provenance?.safety === \"blocked\") {\n blockedIds.add(result.memoryId);\n }\n }\n return (memoryId) => blockedIds.has(memoryId);\n}\n\nfunction missingProvenance(result: RecallXrayResult): RetrievedMemoryProvenance {\n return {\n source: \"unknown\",\n scope: \"unknown\",\n userContextScopes: [],\n retrievalReason: `X-ray provenance missing for ${result.memoryId || result.path}`,\n confidence: 0,\n stale: false,\n corrected: false,\n correctionState: \"none\",\n safeToUse: false,\n safety: \"blocked\",\n safetyReasons: [\"X-ray provenance was missing for this memory.\"],\n };\n}\n\nfunction missingXrayResultProvenance(\n summary: EngramAccessRecallResponse[\"results\"][number],\n): RetrievedMemoryProvenance {\n return {\n source: \"unknown\",\n scope: \"unknown\",\n userContextScopes: [],\n retrievalReason: `X-ray result missing for ${summary.path || summary.id}`,\n confidence: 0,\n stale: false,\n corrected: false,\n correctionState: \"none\",\n safeToUse: false,\n safety: \"blocked\",\n safetyReasons: [\"X-ray result was missing for this recalled memory.\"],\n };\n}\n\nfunction missingRecallProvenance(\n summary: EngramAccessRecallResponse[\"results\"][number],\n): RetrievedMemoryProvenance {\n return {\n source: \"unknown\",\n scope: \"unknown\",\n userContextScopes: [],\n retrievalReason: `X-ray provenance unavailable for ${summary.id || summary.path}`,\n confidence: 0,\n stale: false,\n corrected: false,\n correctionState: \"none\",\n safeToUse: false,\n safety: \"blocked\",\n safetyReasons: [\"X-ray provenance was unavailable for this recall.\"],\n };\n}\n\nfunction formatUnsafeRecallPreview(\n blockedCount: number,\n missingProvenanceCount: number,\n): string {\n const reasons: string[] = [];\n if (blockedCount > 0) {\n reasons.push(`${blockedCount} retrieved ${memoryNoun(blockedCount)} ${isAre(blockedCount)} blocked`);\n }\n if (missingProvenanceCount > 0) {\n reasons.push(\n `${missingProvenanceCount} retrieved ${memoryNoun(missingProvenanceCount)} ${isAre(missingProvenanceCount)} missing X-ray provenance`,\n );\n }\n return `Recall preview withheld: ${joinReasons(reasons)} in the current context.`;\n}\n\nfunction memoryNoun(count: number): string {\n return count === 1 ? \"memory\" : \"memories\";\n}\n\nfunction isAre(count: number): string {\n return count === 1 ? \"is\" : \"are\";\n}\n\nfunction joinReasons(reasons: string[]): string {\n if (reasons.length <= 1) return reasons[0] ?? \"memory safety could not be verified\";\n return `${reasons.slice(0, -1).join(\", \")} and ${reasons[reasons.length - 1]}`;\n}\n\nfunction truncate(value: string, maxChars: number): string {\n if (value.length <= maxChars) return value;\n return `${value.slice(0, Math.max(0, maxChars - 3))}...`;\n}\n"],"mappings":"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","names":[]}
package/dist/cli.js CHANGED
@@ -89,7 +89,7 @@ import {
89
89
  runWorkProductStatusCliCommand,
90
90
  runWorkProjectCliCommand,
91
91
  runWorkTaskCliCommand
92
- } from "./chunk-ACNU2UBF.js";
92
+ } from "./chunk-2GCNTHRA.js";
93
93
  import "./chunk-MC4FJXPA.js";
94
94
  import "./chunk-LQHDIS7L.js";
95
95
  import "./chunk-7F7Z6MOS.js";
@@ -164,7 +164,7 @@ import "./chunk-Z5LAYHGJ.js";
164
164
  import "./chunk-LBJBNWS2.js";
165
165
  import "./chunk-HQ6NIBL6.js";
166
166
  import "./chunk-OADWQ5CR.js";
167
- import "./chunk-6DDBW2V4.js";
167
+ import "./chunk-S2SEPLLA.js";
168
168
  import "./chunk-SEDEKFYQ.js";
169
169
  import "./chunk-2QSZNTDO.js";
170
170
  import "./chunk-RSUYKGGZ.js";
@@ -173,8 +173,8 @@ import "./chunk-TMSXWOBZ.js";
173
173
  import "./chunk-J64TK33U.js";
174
174
  import "./chunk-7RXCMVFQ.js";
175
175
  import "./chunk-7WV3F5DQ.js";
176
- import "./chunk-5IDVOWBE.js";
177
- import "./chunk-6L46YAEZ.js";
176
+ import "./chunk-GJSNDJHR.js";
177
+ import "./chunk-T4WDJPEZ.js";
178
178
  import "./chunk-D24OXEPB.js";
179
179
  import "./chunk-AK4DSORQ.js";
180
180
  import "./chunk-GDASG7NC.js";
package/dist/index.d.ts CHANGED
@@ -2257,6 +2257,133 @@ interface WearablesCliIo {
2257
2257
  */
2258
2258
  declare function runWearablesCliCommand(service: WearablesService, args: string[], io: WearablesCliIo): Promise<number>;
2259
2259
 
2260
+ type LocalSessionRole = "user" | "assistant" | "tool" | "system" | "other";
2261
+ interface LocalSessionTurn {
2262
+ role: LocalSessionRole;
2263
+ content: string;
2264
+ timestamp?: string;
2265
+ sessionKey?: string;
2266
+ sourceId?: string;
2267
+ metadata?: Record<string, unknown>;
2268
+ }
2269
+ interface LocalSessionParseWarning {
2270
+ code: string;
2271
+ message: string;
2272
+ fileRef?: string;
2273
+ line?: number;
2274
+ }
2275
+ interface LocalSessionParsedFile {
2276
+ turns: LocalSessionTurn[];
2277
+ warnings: LocalSessionParseWarning[];
2278
+ }
2279
+ interface LocalSessionAdapterInput {
2280
+ content: string;
2281
+ fileName: string;
2282
+ fileExtension: string;
2283
+ fileRef: string;
2284
+ }
2285
+ interface LocalSessionAdapterOptions {
2286
+ strict?: boolean;
2287
+ }
2288
+ interface LocalSessionSourceAdapter {
2289
+ id: string;
2290
+ parseFile(input: LocalSessionAdapterInput, options?: LocalSessionAdapterOptions): LocalSessionParsedFile | Promise<LocalSessionParsedFile>;
2291
+ }
2292
+ interface RedactionRuleConfig {
2293
+ name: string;
2294
+ pattern: string;
2295
+ flags?: string;
2296
+ replacement?: string;
2297
+ }
2298
+ interface RedactionConfig {
2299
+ disableDefaults?: boolean;
2300
+ rules?: RedactionRuleConfig[];
2301
+ }
2302
+ interface CompiledRedactionRule {
2303
+ name: string;
2304
+ pattern: RegExp;
2305
+ replacement: string;
2306
+ }
2307
+ interface RedactionReport {
2308
+ applied: number;
2309
+ ruleNames: string[];
2310
+ }
2311
+ interface SessionSummaryExcerpt {
2312
+ role: LocalSessionRole;
2313
+ text: string;
2314
+ timestamp?: string;
2315
+ }
2316
+ interface SessionSummaryDraft {
2317
+ schemaVersion: 1;
2318
+ draftId: string;
2319
+ generatedAt: string;
2320
+ sourceAdapter: string;
2321
+ sourceSessionRef: string;
2322
+ sourceFileCount: number;
2323
+ sourceFileRefs: Array<{
2324
+ hash: string;
2325
+ extension: string;
2326
+ }>;
2327
+ firstTimestamp?: string;
2328
+ lastTimestamp?: string;
2329
+ turnCount: number;
2330
+ roles: Record<LocalSessionRole, number>;
2331
+ summary: string;
2332
+ redaction: {
2333
+ enabled: boolean;
2334
+ applied: number;
2335
+ ruleNames: string[];
2336
+ };
2337
+ excerpts?: SessionSummaryExcerpt[];
2338
+ metadata: {
2339
+ storesRawTranscript: false;
2340
+ storesLocalPaths: false;
2341
+ storesSourceSessionKey: false;
2342
+ };
2343
+ }
2344
+ interface CollectLocalSessionSummariesOptions {
2345
+ inputDir: string;
2346
+ source?: string;
2347
+ strict?: boolean;
2348
+ redactionConfig?: RedactionConfig;
2349
+ includeRedactedExcerpts?: boolean;
2350
+ maxFiles?: number;
2351
+ maxSessions?: number;
2352
+ now?: Date;
2353
+ }
2354
+ interface LocalSessionSummaryReport {
2355
+ generatedAt: string;
2356
+ source: string;
2357
+ filesScanned: number;
2358
+ filesParsed: number;
2359
+ turnsParsed: number;
2360
+ sessionsSummarized: number;
2361
+ warnings: LocalSessionParseWarning[];
2362
+ drafts: SessionSummaryDraft[];
2363
+ wroteFiles: string[];
2364
+ }
2365
+ interface LocalSessionSummaryCliOptions extends CollectLocalSessionSummariesOptions {
2366
+ memoryDir?: string;
2367
+ output?: string;
2368
+ write?: boolean;
2369
+ redactionConfigPath?: string;
2370
+ stdout?: Pick<NodeJS.WritableStream, "write">;
2371
+ }
2372
+
2373
+ declare function registerLocalSessionSourceAdapter(adapter: LocalSessionSourceAdapter): void;
2374
+ declare function getLocalSessionSourceAdapter(id: string | undefined): LocalSessionSourceAdapter | undefined;
2375
+ declare function listLocalSessionSourceAdapters(): string[];
2376
+
2377
+ declare const DEFAULT_REDACTION_RULES: readonly CompiledRedactionRule[];
2378
+ declare function compileRedactionRules(config?: RedactionConfig): CompiledRedactionRule[];
2379
+ declare function redactSessionSummaryText(text: string, rules: readonly CompiledRedactionRule[]): {
2380
+ text: string;
2381
+ report: RedactionReport;
2382
+ };
2383
+
2384
+ declare function collectLocalSessionSummaries(options: CollectLocalSessionSummariesOptions): Promise<LocalSessionSummaryReport>;
2385
+ declare function runLocalSessionSummaryCliCommand(options: LocalSessionSummaryCliOptions): Promise<LocalSessionSummaryReport>;
2386
+
2260
2387
  /**
2261
2388
  * Training-data export types.
2262
2389
  *
@@ -2446,4 +2573,4 @@ declare function forkCapsule(opts: ForkCapsuleOptions): Promise<ForkCapsuleResul
2446
2573
  */
2447
2574
  declare function readForkLineage(targetRoot: string, forkId: string): Promise<ForkLineage | null>;
2448
2575
 
2449
- export { type AuditEntry, type BinaryAssetRecord, type BinaryAssetStatus, type BinaryLifecycleConfig, type BinaryLifecycleManifest, type BinaryStorageBackend, type BinaryStorageBackendConfig, ClaudeCodeMemoryExtensionPublisher, type CleanupResult, CodexMemoryExtensionPublisher, type CodingNamespaceOverlay, type CodingScopeDescription, type CompiledCorrectionRule, type ConflictEntry, type ContradictionOptions, type ContradictionPair, type ContradictionResult$1 as CurateContradictionResult, type DuplicateResult as CurateDuplicateResult, type CurateOptions, type CurateResult, type CuratedStatement, DEFAULT_GRACE_PERIOD_DAYS, DEFAULT_MAX_BINARY_SIZE_BYTES, DEFAULT_SCAN_PATTERNS, DEFAULT_TAXONOMY, type DedupOptions, type DedupResult, DiscoveredExtension, type DocFile, type DriveChange, type DriveChangesPage, type DriveFileMetadata, type DuplicatePair, type FileChange, FilesystemBackend, type ForkCapsuleOptions, type ForkCapsuleResult, type ForkLineage, GOOGLE_DRIVE_CONNECTOR_ID, GOOGLE_DRIVE_CURSOR_KIND, DEFAULT_POLL_INTERVAL_MS as GOOGLE_DRIVE_DEFAULT_POLL_INTERVAL_MS, type GenerateOptions, type GenerateResult, type GitContext, type GitInvoker, type GoogleDriveClient, type GoogleDriveClientFactory, type GoogleDriveConnectorConfig, type GoogleDriveSyncResult, HermesMemoryExtensionPublisher, type IngestionPlan, KNOWN_WEARABLE_SOURCE_IDS, type LanguageInfo, LiveConnector, LiveConnectorRegistry, LiveConnectorRegistryError, MemoryCategory, type MemoryEntry, type MemoryExtensionPublisher, type MergeResult, NOTION_CONNECTOR_ID, NOTION_CURSOR_KIND, NOTION_DEFAULT_POLL_INTERVAL_MS, NoneBackend, type NotionConnectorConfig, type OnboardOptions, type OnboardResult, PUBLISHERS, type PipelineResult, PluginConfig, type ProjectShape, type ProvenanceEntry, type PublishContext, type PublishResult, type PublisherCapabilities, REDACTION_PLACEHOLDER, REMNIC_CITATION_FORMAT, REMNIC_MCP_TOOL_INVENTORY, REMNIC_RECALL_DECISION_RULES, REMNIC_SEMANTIC_OVERVIEW, ResolverDecision, type ReviewAction, type ReviewCandidate, type ReviewContext, type ReviewItem, type ReviewListResult, type ReviewOptions, type ReviewResult, type Space, type SpaceKind, type SpaceManifest, type SpacePromoteResult, type SpacePullResult, type SpacePushResult, type SpaceShareResult, type SpaceSwitchResult, SpeakerRegistry, type StatementProvenance, StorageManager, SyncIncrementalResult, type SyncOptions, type SyncResult, type SyncState, Taxonomy, TokenEntry, type TrainingExportAdapter, type TrainingExportOptions, type TrainingExportRecord, type TreeNode, WEARABLES_DIR_NAME, WearableCleanupSettings, type WearableConnectorFactory, type WearableConnectorFactoryOptions, type WearableConnectorRegistration, WearableConversation, WearableCorrectionRule, WearableDayTranscript, WearableDayTranscriptMeta, WearableSourceConnector, WearableSourceSettings, type WearableSourceSyncState, type WearableSyncStateFile, type WearablesCliIo, WearablesConfig, WearablesInputError, WearablesService, applyCorrections, applyOffTheRecord, branchNamespaceName, buildProcedureMarkdownBody, buildProcedureRecallSection, cleanConversation, clearTrainingExportAdapters, clearWearableConnectors, collapseImmediateRepeats, compileCorrectionRule, compileCorrectionRules, compileRedactionPatterns, composeDayTranscriptBody, composeDayTranscriptMeta, convertMemoriesToRecords, correctionsFilePath, createBackend, createGoogleDriveConnector, createNotionConnector, createSpace, curate, defaultGoogleDriveClientFactory, defaultWearableCleanupSettings, defaultWearableSourceSettings, defaultWearablesConfig, deleteSpace, describeCodingScope, describeErrorForOperator, emptyManifest, emptySyncState, ensureBuiltInWearableConnectors, expandTildePath, findContradictions, findDuplicates, forkCapsule, generateContextTree, generateResolverDocument, getActiveSpace, getAuditLog, getManifestPath, getSpacesDir, getTaxonomyDir, getTaxonomyFilePath, getTrainingExportAdapter, getWearableConnector, hashTranscriptBody, hostIdForConnector, isLowQualitySegment, isReviewPrompt, isValidTranscriptDate, listReviewItems, listSpaces, listTrainingExportAdapters, listWearableConnectors, loadCorrectionsFile, loadManifest, loadSyncState, loadTaxonomy, manifestDir, manifestPath, matchesPatterns, mergeSpaces, normalizeOriginUrl, onboard, packReviewContext, parseDayTranscript, parseFlexibleIsoTimestamp, parseIsoOffsetTimestamp, parseIsoUtcTimestamp, parseProcedureStepsFromBody, parseTouchedFiles, parseWearablesConfig, performReview, projectNamespaceName, promoteSpace, publisherFor, publisherForConnector, pullFromSpace, pushToSpace, rankReviewCandidates, readForkLineage, readManifest, redactText, registerPublisher, registerTrainingExportAdapter, registerWearableConnector, renderExtensionsBlock, renderExtensionsFooter, resolveCategory, resolveCodingNamespaceOverlay, resolveGitContext, runBinaryLifecyclePipeline, runWearablesCliCommand, saveCorrectionsFile, saveManifest, saveSyncState, saveTaxonomy, scanForBinaries, serializeDayTranscript, shareSpace, stableHash, stripFillerTokens, switchSpace, syncChanges, syncStateFilePath, updateSourceSyncState, validateGoogleDriveConfig, validateNotionConfig, validateSlug, validateTaxonomy, watchForChanges, writeManifest };
2576
+ export { type AuditEntry, type BinaryAssetRecord, type BinaryAssetStatus, type BinaryLifecycleConfig, type BinaryLifecycleManifest, type BinaryStorageBackend, type BinaryStorageBackendConfig, ClaudeCodeMemoryExtensionPublisher, type CleanupResult, CodexMemoryExtensionPublisher, type CodingNamespaceOverlay, type CodingScopeDescription, type CollectLocalSessionSummariesOptions, type CompiledCorrectionRule, type CompiledRedactionRule, type ConflictEntry, type ContradictionOptions, type ContradictionPair, type ContradictionResult$1 as CurateContradictionResult, type DuplicateResult as CurateDuplicateResult, type CurateOptions, type CurateResult, type CuratedStatement, DEFAULT_GRACE_PERIOD_DAYS, DEFAULT_MAX_BINARY_SIZE_BYTES, DEFAULT_REDACTION_RULES, DEFAULT_SCAN_PATTERNS, DEFAULT_TAXONOMY, type DedupOptions, type DedupResult, DiscoveredExtension, type DocFile, type DriveChange, type DriveChangesPage, type DriveFileMetadata, type DuplicatePair, type FileChange, FilesystemBackend, type ForkCapsuleOptions, type ForkCapsuleResult, type ForkLineage, GOOGLE_DRIVE_CONNECTOR_ID, GOOGLE_DRIVE_CURSOR_KIND, DEFAULT_POLL_INTERVAL_MS as GOOGLE_DRIVE_DEFAULT_POLL_INTERVAL_MS, type GenerateOptions, type GenerateResult, type GitContext, type GitInvoker, type GoogleDriveClient, type GoogleDriveClientFactory, type GoogleDriveConnectorConfig, type GoogleDriveSyncResult, HermesMemoryExtensionPublisher, type IngestionPlan, KNOWN_WEARABLE_SOURCE_IDS, type LanguageInfo, LiveConnector, LiveConnectorRegistry, LiveConnectorRegistryError, type LocalSessionAdapterInput, type LocalSessionAdapterOptions, type LocalSessionParseWarning, type LocalSessionParsedFile, type LocalSessionRole, type LocalSessionSourceAdapter, type LocalSessionSummaryCliOptions, type LocalSessionSummaryReport, type LocalSessionTurn, MemoryCategory, type MemoryEntry, type MemoryExtensionPublisher, type MergeResult, NOTION_CONNECTOR_ID, NOTION_CURSOR_KIND, NOTION_DEFAULT_POLL_INTERVAL_MS, NoneBackend, type NotionConnectorConfig, type OnboardOptions, type OnboardResult, PUBLISHERS, type PipelineResult, PluginConfig, type ProjectShape, type ProvenanceEntry, type PublishContext, type PublishResult, type PublisherCapabilities, REDACTION_PLACEHOLDER, REMNIC_CITATION_FORMAT, REMNIC_MCP_TOOL_INVENTORY, REMNIC_RECALL_DECISION_RULES, REMNIC_SEMANTIC_OVERVIEW, type RedactionConfig, type RedactionReport, type RedactionRuleConfig, ResolverDecision, type ReviewAction, type ReviewCandidate, type ReviewContext, type ReviewItem, type ReviewListResult, type ReviewOptions, type ReviewResult, type SessionSummaryDraft, type SessionSummaryExcerpt, type Space, type SpaceKind, type SpaceManifest, type SpacePromoteResult, type SpacePullResult, type SpacePushResult, type SpaceShareResult, type SpaceSwitchResult, SpeakerRegistry, type StatementProvenance, StorageManager, SyncIncrementalResult, type SyncOptions, type SyncResult, type SyncState, Taxonomy, TokenEntry, type TrainingExportAdapter, type TrainingExportOptions, type TrainingExportRecord, type TreeNode, WEARABLES_DIR_NAME, WearableCleanupSettings, type WearableConnectorFactory, type WearableConnectorFactoryOptions, type WearableConnectorRegistration, WearableConversation, WearableCorrectionRule, WearableDayTranscript, WearableDayTranscriptMeta, WearableSourceConnector, WearableSourceSettings, type WearableSourceSyncState, type WearableSyncStateFile, type WearablesCliIo, WearablesConfig, WearablesInputError, WearablesService, applyCorrections, applyOffTheRecord, branchNamespaceName, buildProcedureMarkdownBody, buildProcedureRecallSection, cleanConversation, clearTrainingExportAdapters, clearWearableConnectors, collapseImmediateRepeats, collectLocalSessionSummaries, compileCorrectionRule, compileCorrectionRules, compileRedactionPatterns, compileRedactionRules, composeDayTranscriptBody, composeDayTranscriptMeta, convertMemoriesToRecords, correctionsFilePath, createBackend, createGoogleDriveConnector, createNotionConnector, createSpace, curate, defaultGoogleDriveClientFactory, defaultWearableCleanupSettings, defaultWearableSourceSettings, defaultWearablesConfig, deleteSpace, describeCodingScope, describeErrorForOperator, emptyManifest, emptySyncState, ensureBuiltInWearableConnectors, expandTildePath, findContradictions, findDuplicates, forkCapsule, generateContextTree, generateResolverDocument, getActiveSpace, getAuditLog, getLocalSessionSourceAdapter, getManifestPath, getSpacesDir, getTaxonomyDir, getTaxonomyFilePath, getTrainingExportAdapter, getWearableConnector, hashTranscriptBody, hostIdForConnector, isLowQualitySegment, isReviewPrompt, isValidTranscriptDate, listLocalSessionSourceAdapters, listReviewItems, listSpaces, listTrainingExportAdapters, listWearableConnectors, loadCorrectionsFile, loadManifest, loadSyncState, loadTaxonomy, manifestDir, manifestPath, matchesPatterns, mergeSpaces, normalizeOriginUrl, onboard, packReviewContext, parseDayTranscript, parseFlexibleIsoTimestamp, parseIsoOffsetTimestamp, parseIsoUtcTimestamp, parseProcedureStepsFromBody, parseTouchedFiles, parseWearablesConfig, performReview, projectNamespaceName, promoteSpace, publisherFor, publisherForConnector, pullFromSpace, pushToSpace, rankReviewCandidates, readForkLineage, readManifest, redactSessionSummaryText, redactText, registerLocalSessionSourceAdapter, registerPublisher, registerTrainingExportAdapter, registerWearableConnector, renderExtensionsBlock, renderExtensionsFooter, resolveCategory, resolveCodingNamespaceOverlay, resolveGitContext, runBinaryLifecyclePipeline, runLocalSessionSummaryCliCommand, runWearablesCliCommand, saveCorrectionsFile, saveManifest, saveSyncState, saveTaxonomy, scanForBinaries, serializeDayTranscript, shareSpace, stableHash, stripFillerTokens, switchSpace, syncChanges, syncStateFilePath, updateSourceSyncState, validateGoogleDriveConfig, validateNotionConfig, validateSlug, validateTaxonomy, watchForChanges, writeManifest };