@remnic/core 9.25.5 → 9.25.7

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 (45) hide show
  1. package/dist/access-admin-ops-surface.d.ts +2 -2
  2. package/dist/access-authorization-probe.d.ts +2 -2
  3. package/dist/access-boundary.d.ts +2 -2
  4. package/dist/access-cli.js +1 -1
  5. package/dist/access-http.d.ts +2 -2
  6. package/dist/access-identity-continuity-surface.d.ts +1 -1
  7. package/dist/access-lcm-surface.d.ts +2 -2
  8. package/dist/access-mcp.d.ts +2 -2
  9. package/dist/access-observe-write-surface.d.ts +2 -2
  10. package/dist/access-operations.d.ts +5 -5
  11. package/dist/access-recall-concurrency.d.ts +2 -2
  12. package/dist/access-recall-response.d.ts +2 -2
  13. package/dist/access-recall-surface.d.ts +2 -2
  14. package/dist/access-schema.d.ts +76 -76
  15. package/dist/{access-service-BJQ22URi.d.ts → access-service-CIdWkP6J.d.ts} +1 -1
  16. package/dist/access-service.d.ts +2 -2
  17. package/dist/access-surface-catalog.d.ts +2 -2
  18. package/dist/bootstrap.d.ts +1 -1
  19. package/dist/{chunk-FR75B4UU.js → chunk-KZVPTJNZ.js} +334 -647
  20. package/dist/chunk-KZVPTJNZ.js.map +1 -0
  21. package/dist/{cli-1W7cNjJJ.d.ts → cli-Da5kesWC.d.ts} +2 -2
  22. package/dist/cli.d.ts +3 -3
  23. package/dist/explicit-capture.d.ts +1 -1
  24. package/dist/index.d.ts +392 -392
  25. package/dist/index.js +1 -1
  26. package/dist/mcp-memory-inspector-app.d.ts +2 -2
  27. package/dist/{orchestrator-BtA1wC5K.d.ts → orchestrator-CFJ_TG6D.d.ts} +15 -10
  28. package/dist/orchestrator.d.ts +1 -1
  29. package/dist/orchestrator.js +1 -1
  30. package/dist/schemas.d.ts +76 -76
  31. package/dist/shared-context/manager.d.ts +8 -8
  32. package/dist/transfer/types.d.ts +66 -66
  33. package/package.json +2 -2
  34. package/src/meetings/recall-exclusion.test.ts +4 -2
  35. package/src/orchestration/generic-recall-paths.ts +119 -0
  36. package/src/orchestration/namespace-read-fanout.ts +0 -12
  37. package/src/orchestration/orchestrator-helpers.ts +0 -35
  38. package/src/orchestration/recall-internal.ts +6 -6
  39. package/src/orchestration/recall-search-pipeline.test.ts +194 -28
  40. package/src/orchestration/recall-search-pipeline.ts +39 -89
  41. package/src/orchestrator.ts +5 -17
  42. package/src/recall-cold-deadline.test.ts +11 -13
  43. package/src/testing/subjects/generic-recall-paths.test.ts +157 -0
  44. package/dist/chunk-FR75B4UU.js.map +0 -1
  45. package/src/recall/archive-scoring.ts +0 -544
@@ -614,7 +614,7 @@ import {
614
614
  } from "./chunk-3WCASNQZ.js";
615
615
 
616
616
  // src/orchestrator.ts
617
- import path16 from "path";
617
+ import path17 from "path";
618
618
  import { createHash as createHash8 } from "crypto";
619
619
 
620
620
  // src/orchestration/tier-migration-coordinator.ts
@@ -2106,7 +2106,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
2106
2106
  namespaces,
2107
2107
  {
2108
2108
  readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
2109
- readMemoryFrontmatter: async (path31, preferredNamespace) => {
2109
+ readMemoryFrontmatter: async (path32, preferredNamespace) => {
2110
2110
  if (!fallbackReader) {
2111
2111
  for (const ns of namespaces) {
2112
2112
  try {
@@ -2118,7 +2118,7 @@ var RecallRerankCoordinator = class _RecallRerankCoordinator {
2118
2118
  }
2119
2119
  if (!fallbackReader) return null;
2120
2120
  const memory = await this.readQmdResultMemory(
2121
- path31,
2121
+ path32,
2122
2122
  fallbackReader,
2123
2123
  namespaces,
2124
2124
  preferredNamespace
@@ -3033,18 +3033,9 @@ function isActivityDigestPath(filePath, memoryRoot) {
3033
3033
  }
3034
3034
  return ACTIVITY_DIGEST_ANYWHERE.test(filePath);
3035
3035
  }
3036
- function isGenericRecallExcludedPath(filePath, memoryRoot) {
3037
- return isArtifactMemoryPath(filePath) || isActivityDigestPath(filePath, memoryRoot) || isMeetingRecordPath(filePath);
3038
- }
3039
3036
  function buildCompressionGuidelinesMarkdown2(events, generatedAtIso = (/* @__PURE__ */ new Date()).toISOString()) {
3040
3037
  return buildCompressionGuidelinesMarkdown(events, generatedAtIso);
3041
3038
  }
3042
- function filterRecallCandidates(candidates, options) {
3043
- const scopedByNamespace = options.namespacesEnabled ? candidates.filter(
3044
- (r) => options.recallNamespaces.includes(r.namespace ?? options.resolveNamespace(r.path))
3045
- ) : candidates;
3046
- return scopedByNamespace.filter((r) => !isGenericRecallExcludedPath(r.path, options.memoryRoot)).slice(0, Math.max(0, options.limit));
3047
- }
3048
3039
  function applyQueryAwareCandidateFilter(candidates, candidatePaths) {
3049
3040
  if (!candidatePaths) return candidates;
3050
3041
  if (candidatePaths.size === 0) return [];
@@ -6238,7 +6229,7 @@ var ExtractionPersistCoordinator = class {
6238
6229
  // src/orchestration/recall-internal.ts
6239
6230
  import { createHash as createHash5 } from "crypto";
6240
6231
  import { readFile as readFile2, stat, unlink } from "fs/promises";
6241
- import path7 from "path";
6232
+ import path8 from "path";
6242
6233
 
6243
6234
  // src/orchestration/graph-recall-coordinator.ts
6244
6235
  import { createHash as createHash4 } from "crypto";
@@ -6590,6 +6581,57 @@ ${preview}${suffix}`;
6590
6581
  ${blocks.join("\n\n")}`;
6591
6582
  }
6592
6583
 
6584
+ // src/orchestration/generic-recall-paths.ts
6585
+ import path7 from "path";
6586
+ var CATEGORY_MEMORY_ROOTS = Object.fromEntries(
6587
+ ALL_CATEGORY_DIRS.map((directory) => [directory, true])
6588
+ );
6589
+ var RESERVED_ARCHIVE_ROOTS = { archive: true, namespaces: true };
6590
+ function isQmdCollectionPrefix(prefix, collection, source) {
6591
+ if (typeof collection !== "string" || collection.length === 0) return false;
6592
+ if (prefix.startsWith(`${collection}--`)) return true;
6593
+ if (prefix !== collection) return false;
6594
+ if (source === "qmd") return true;
6595
+ return !Object.hasOwn(CATEGORY_MEMORY_ROOTS, prefix) && !Object.hasOwn(RESERVED_ARCHIVE_ROOTS, prefix);
6596
+ }
6597
+ function normalizeQmdUriPath(relativePath, source) {
6598
+ if (source !== "qmd" || !relativePath.startsWith("qmd://")) return relativePath;
6599
+ try {
6600
+ const parsed = new URL(relativePath);
6601
+ if (parsed.protocol !== "qmd:" || !parsed.hostname) return relativePath;
6602
+ const collection = decodeURIComponent(parsed.hostname);
6603
+ const pathname = decodeURIComponent(parsed.pathname.replace(/^\/+/, ""));
6604
+ return pathname ? `${collection}/${pathname}` : collection;
6605
+ } catch {
6606
+ return relativePath;
6607
+ }
6608
+ }
6609
+ function stripQmdCollectionPrefix(relativePath, policy, source) {
6610
+ const normalized = path7.posix.normalize(normalizeQmdUriPath(relativePath, source).replace(/\\/g, "/"));
6611
+ const slashIndex = normalized.indexOf("/");
6612
+ if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return normalized;
6613
+ const prefix = normalized.slice(0, slashIndex);
6614
+ const matchesHotCollection = isQmdCollectionPrefix(prefix, policy.qmdCollection, source);
6615
+ const matchesColdCollection = isQmdCollectionPrefix(prefix, policy.qmdColdCollection, source);
6616
+ return matchesHotCollection || matchesColdCollection ? normalized.slice(slashIndex + 1) : normalized;
6617
+ }
6618
+ function isTopLevelArchivePath(filePath, policy = {}, source = "filesystem") {
6619
+ const isAbsolutePath = path7.isAbsolute(filePath);
6620
+ const relative = policy.memoryDir && isAbsolutePath ? path7.relative(policy.memoryDir, path7.resolve(filePath)) : filePath;
6621
+ const normalized = !isAbsolutePath ? stripQmdCollectionPrefix(relative, policy, source) : relative;
6622
+ return /^(?:archive|namespaces[\\/][^\\/]+[\\/]archive)(?:[\\/]|$)/i.test(normalized);
6623
+ }
6624
+ function isGenericRecallExcludedPath(filePath, policy = {}, source = "filesystem") {
6625
+ return isArtifactMemoryPath(filePath) || isActivityDigestPath(filePath, policy.memoryDir) || isTopLevelArchivePath(filePath, policy, source) || isMeetingRecordPath(filePath);
6626
+ }
6627
+ function filterRecallCandidates(candidates, options) {
6628
+ const pathPolicy = options.pathPolicy ?? (options.memoryRoot === void 0 ? void 0 : { memoryDir: options.memoryRoot });
6629
+ const scopedByNamespace = options.namespacesEnabled ? candidates.filter(
6630
+ (r) => options.recallNamespaces.includes(r.namespace ?? options.resolveNamespace(r.path))
6631
+ ) : candidates;
6632
+ return scopedByNamespace.filter((r) => !isGenericRecallExcludedPath(r.path, pathPolicy, "qmd")).slice(0, Math.max(0, options.limit));
6633
+ }
6634
+
6593
6635
  // src/orchestration/recall-internal.ts
6594
6636
  var RecallInternalCoordinator = class {
6595
6637
  constructor(deps) {
@@ -6811,7 +6853,7 @@ var RecallInternalCoordinator = class {
6811
6853
  const graphExpandedResultPaths = /* @__PURE__ */ new Set();
6812
6854
  const graphSourceLabelsForPath = (resultPath) => {
6813
6855
  const labels = [];
6814
- const normalizedPath = resultPath.split(path7.sep).join("/");
6856
+ const normalizedPath = resultPath.split(path8.sep).join("/");
6815
6857
  const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
6816
6858
  if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
6817
6859
  if (graphExpandedResultPaths.has(resultPath))
@@ -6972,7 +7014,7 @@ var RecallInternalCoordinator = class {
6972
7014
  profileStorageNamespaces.map((namespace) => this.deps.storageRouter.storageFor(namespace))
6973
7015
  );
6974
7016
  const emptyProfileStorage = new Proxy(
6975
- { dir: path7.join(this.deps.config.memoryDir, ".empty-scope-profile") },
7017
+ { dir: path8.join(this.deps.config.memoryDir, ".empty-scope-profile") },
6976
7018
  {
6977
7019
  get(target, prop) {
6978
7020
  if (prop in target) return target[prop];
@@ -8454,11 +8496,11 @@ ${formatted}`;
8454
8496
  if (!resolveRecallAuxiliaryCapabilities(this.deps.config).compactionReset) return null;
8455
8497
  const workspaceDir = compactionWorkspaceDir || this.deps.config.workspaceDir || defaultWorkspaceDir();
8456
8498
  const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
8457
- const signalPath = path7.join(
8499
+ const signalPath = path8.join(
8458
8500
  workspaceDir,
8459
8501
  `.compaction-reset-signal-${safeSessionKey}`
8460
8502
  );
8461
- const bootPath = path7.join(workspaceDir, "BOOT.md");
8503
+ const bootPath = path8.join(workspaceDir, "BOOT.md");
8462
8504
  try {
8463
8505
  const signalStat = await stat(signalPath).catch(() => null);
8464
8506
  if (!signalStat) return null;
@@ -9387,7 +9429,7 @@ ${tmtNode.summary}`
9387
9429
  if (resolveNamespaceCapabilities(this.deps.config).namespaces) {
9388
9430
  memoryResults = memoryResults.filter((r) => recallNamespaces.includes(r.namespace ?? this.deps.namespaceFromPath(r.path)));
9389
9431
  }
9390
- memoryResults = memoryResults.filter((r) => !isGenericRecallExcludedPath(r.path, this.deps.config.memoryDir));
9432
+ memoryResults = memoryResults.filter((r) => !isGenericRecallExcludedPath(r.path, this.deps.config, "qmd"));
9391
9433
  const isFullModeGraphAssist = graphCaps.multiGraphMemory && caps.graphAssistInFullMode && recallMode === "full" && memoryResults.length >= Math.max(1, this.deps.config.graphAssistMinSeedResults ?? 3);
9392
9434
  const shouldRunGraphExpansion = recallMode === "graph_mode" || isFullModeGraphAssist;
9393
9435
  const graphShadowEvalEnabled = isFullModeGraphAssist && resolveRecallEnhancementCapabilities(this.deps.config).graphAssistShadowEval === true;
@@ -9493,6 +9535,7 @@ ${tmtNode.summary}`
9493
9535
  }
9494
9536
  }
9495
9537
  }
9538
+ memoryResults = memoryResults.filter((r) => !isGenericRecallExcludedPath(r.path, this.deps.config, "qmd"));
9496
9539
  const qmdBoostInput = await this.deps.filterSearchResultsForRecall(
9497
9540
  memoryResults,
9498
9541
  void 0,
@@ -9673,7 +9716,7 @@ ${tmtNode.summary}`
9673
9716
  recallNamespaces,
9674
9717
  resolveNamespace: (p) => this.deps.namespaceFromPath(p),
9675
9718
  limit: embeddingFetchLimit,
9676
- memoryRoot: this.deps.config.memoryDir
9719
+ pathPolicy: this.deps.config
9677
9720
  }
9678
9721
  );
9679
9722
  const boostedScoped = await this.deps.boostSearchResults(
@@ -9848,7 +9891,7 @@ ${tmtNode.summary}`
9848
9891
  recallNamespaces,
9849
9892
  resolveNamespace: (p) => this.deps.namespaceFromPath(p),
9850
9893
  limit: embeddingFetchLimit,
9851
- memoryRoot: this.deps.config.memoryDir
9894
+ pathPolicy: this.deps.config
9852
9895
  }
9853
9896
  );
9854
9897
  const boostedScoped = await this.deps.boostSearchResults(
@@ -9937,7 +9980,7 @@ ${tmtNode.summary}`
9937
9980
  const asOfActive = typeof asOfMs === "number" && Number.isFinite(asOfMs);
9938
9981
  const activeMemories = memories.filter(
9939
9982
  (m) => {
9940
- if (isGenericRecallExcludedPath(m.path, this.deps.config.memoryDir)) return false;
9983
+ if (isGenericRecallExcludedPath(m.path, this.deps.config)) return false;
9941
9984
  const status = m.frontmatter.status;
9942
9985
  if (!status || status === "active") return true;
9943
9986
  if (status === "superseded") {
@@ -10611,310 +10654,7 @@ ${tmtNode.summary}`
10611
10654
 
10612
10655
  // src/orchestration/recall-search-pipeline.ts
10613
10656
  import { createHash as createHash6 } from "crypto";
10614
- import path8 from "path";
10615
-
10616
- // src/recall/archive-scoring.ts
10617
- import os2 from "os";
10618
- import { Worker } from "worker_threads";
10619
- function scoreArchiveMemories(items, tokens) {
10620
- if (items.length === 0 || tokens.length === 0) return [];
10621
- const scored = [];
10622
- for (const item of items) {
10623
- const haystack = [item.content, item.category, ...item.tags].join(" ").toLowerCase();
10624
- let hits = 0;
10625
- for (const token of tokens) {
10626
- if (haystack.includes(token)) hits += 1;
10627
- }
10628
- if (hits === 0) continue;
10629
- scored.push({
10630
- docid: item.id,
10631
- path: item.path,
10632
- score: hits / tokens.length,
10633
- snippet: item.content.slice(0, 400).replace(/\n/g, " ")
10634
- });
10635
- }
10636
- return scored;
10637
- }
10638
- function memoryFileToScoreItem(memory) {
10639
- return {
10640
- id: memory.frontmatter.id,
10641
- path: memory.path,
10642
- content: memory.content,
10643
- category: memory.frontmatter.category,
10644
- tags: memory.frontmatter.tags ?? []
10645
- };
10646
- }
10647
- var SyncArchiveScoring = class {
10648
- async score(items, tokens, abortSignal) {
10649
- if (items.length === 0 || tokens.length === 0) return [];
10650
- if (abortSignal?.aborted) return [];
10651
- const CHUNK = 500;
10652
- if (items.length <= CHUNK) return scoreArchiveMemories(items, tokens);
10653
- const results = [];
10654
- for (let i = 0; i < items.length; i += CHUNK) {
10655
- if (abortSignal?.aborted) return [];
10656
- const scored = scoreArchiveMemories(items.slice(i, i + CHUNK), tokens);
10657
- for (const r of scored) results.push(r);
10658
- }
10659
- return results;
10660
- }
10661
- };
10662
- var WORKER_SOURCE = String.raw`
10663
- const { parentPort } = require('node:worker_threads');
10664
-
10665
- function scoreArchiveMemories(items, tokens) {
10666
- if (items.length === 0 || tokens.length === 0) return [];
10667
- var scored = [];
10668
- for (var i = 0; i < items.length; i++) {
10669
- var item = items[i];
10670
- var haystack = [item.content, item.category].concat(item.tags || []).join(' ').toLowerCase();
10671
- var hits = 0;
10672
- for (var j = 0; j < tokens.length; j++) {
10673
- if (haystack.indexOf(tokens[j]) !== -1) hits++;
10674
- }
10675
- if (hits === 0) continue;
10676
- scored.push({
10677
- docid: item.id,
10678
- path: item.path,
10679
- score: hits / tokens.length,
10680
- snippet: item.content.slice(0, 400).replace(/\n/g, ' '),
10681
- });
10682
- }
10683
- return scored;
10684
- }
10685
-
10686
- if (parentPort) {
10687
- parentPort.on('message', function(task) {
10688
- try {
10689
- var results = scoreArchiveMemories(task.items, task.tokens);
10690
- parentPort.postMessage({ ok: true, results: results });
10691
- } catch (err) {
10692
- parentPort.postMessage({ ok: false, error: err && err.message ? err.message : String(err) });
10693
- }
10694
- });
10695
- }
10696
- `;
10697
- function defaultPoolSize() {
10698
- const cpus = typeof os2.availableParallelism === "function" ? os2.availableParallelism() : os2.cpus().length;
10699
- return Math.max(1, Math.min(Math.max(1, cpus - 1), 8));
10700
- }
10701
- var DISPATCH_TIMEOUT_MS = 12e4;
10702
- var ArchiveScoringWorkerPool = class {
10703
- targetSize;
10704
- workers = [];
10705
- idle = [];
10706
- waiters = [];
10707
- terminated = false;
10708
- busy = 0;
10709
- /**
10710
- * Workers currently checked out and scoring — NOT callers waiting in line.
10711
- * A caller parked in `acquire()` is queued, not running, so this is the only
10712
- * honest measure of real task overlap: with a size-1 pool it never exceeds 1
10713
- * no matter how many callers are queued behind it.
10714
- */
10715
- get busyWorkers() {
10716
- return this.busy;
10717
- }
10718
- constructor(size = defaultPoolSize()) {
10719
- this.targetSize = Math.max(1, size);
10720
- }
10721
- async run(task, abortSignal) {
10722
- if (this.terminated) throw new Error("archive-scoring pool terminated");
10723
- const worker = await this.acquire(abortSignal);
10724
- if (abortSignal?.aborted) {
10725
- this.release(worker);
10726
- return [];
10727
- }
10728
- let abandoned = false;
10729
- this.busy += 1;
10730
- try {
10731
- return await this.dispatch(worker, task, abortSignal, () => {
10732
- abandoned = true;
10733
- });
10734
- } finally {
10735
- this.busy -= 1;
10736
- if (abandoned) this.retireWorker(worker);
10737
- else this.release(worker);
10738
- }
10739
- }
10740
- async terminate() {
10741
- if (this.terminated) return;
10742
- this.terminated = true;
10743
- const queued = this.waiters;
10744
- this.waiters = [];
10745
- for (const w of queued) w.reject(new Error("archive-scoring pool terminated"));
10746
- const all = [...this.workers];
10747
- this.workers = [];
10748
- this.idle = [];
10749
- await Promise.allSettled(all.map((w) => w.terminate()));
10750
- }
10751
- async acquire(abortSignal) {
10752
- const idle = this.idle.pop();
10753
- if (idle) return idle;
10754
- if (this.workers.length < this.targetSize) return this.spawn();
10755
- return new Promise((resolve, reject) => {
10756
- const entry = { resolve, reject };
10757
- this.waiters.push(entry);
10758
- if (!abortSignal) return;
10759
- const onAbort = () => {
10760
- const idx = this.waiters.indexOf(entry);
10761
- if (idx !== -1) this.waiters.splice(idx, 1);
10762
- reject(new Error("archive-scoring acquire aborted"));
10763
- };
10764
- if (abortSignal.aborted) {
10765
- onAbort();
10766
- return;
10767
- }
10768
- abortSignal.addEventListener("abort", onAbort, { once: true });
10769
- });
10770
- }
10771
- release(worker) {
10772
- const next = this.waiters.shift();
10773
- if (next) {
10774
- next.resolve(worker);
10775
- } else if (!this.terminated) {
10776
- this.idle.push(worker);
10777
- } else {
10778
- void worker.terminate();
10779
- }
10780
- }
10781
- /** Terminate a worker that may still be busy, then spawn a replacement
10782
- * if a waiter is queued. */
10783
- retireWorker(worker) {
10784
- const idx = this.workers.indexOf(worker);
10785
- if (idx !== -1) this.workers.splice(idx, 1);
10786
- void worker.terminate();
10787
- const next = this.waiters.shift();
10788
- if (next) next.resolve(this.spawn());
10789
- }
10790
- spawn() {
10791
- const worker = new Worker(WORKER_SOURCE, { eval: true });
10792
- worker.unref();
10793
- this.workers.push(worker);
10794
- return worker;
10795
- }
10796
- dispatch(worker, task, abortSignal, onAbandon) {
10797
- return new Promise((resolve, reject) => {
10798
- let settled = false;
10799
- const timer = setTimeout(() => {
10800
- if (settled) return;
10801
- settled = true;
10802
- cleanup();
10803
- onAbandon();
10804
- log.debug(`archive-scoring dispatch timed out after ${DISPATCH_TIMEOUT_MS}ms \u2014 falling back to sync`);
10805
- reject(new Error(`archive-scoring dispatch timed out after ${DISPATCH_TIMEOUT_MS}ms`));
10806
- }, DISPATCH_TIMEOUT_MS);
10807
- const onMessage = (reply) => {
10808
- if (settled) return;
10809
- settled = true;
10810
- cleanup();
10811
- if (reply.ok) resolve(reply.results);
10812
- else reject(new Error(reply.error));
10813
- };
10814
- const onError = (err) => {
10815
- if (settled) return;
10816
- settled = true;
10817
- cleanup();
10818
- onAbandon();
10819
- reject(err);
10820
- };
10821
- const onExit = (code) => {
10822
- if (settled) return;
10823
- settled = true;
10824
- cleanup();
10825
- onAbandon();
10826
- reject(new Error(`archive-scoring worker exited with code ${code}`));
10827
- };
10828
- const onAbort = () => {
10829
- if (settled) return;
10830
- settled = true;
10831
- cleanup();
10832
- onAbandon();
10833
- resolve([]);
10834
- };
10835
- const cleanup = () => {
10836
- clearTimeout(timer);
10837
- worker.off("message", onMessage);
10838
- worker.off("error", onError);
10839
- worker.off("exit", onExit);
10840
- abortSignal?.removeEventListener("abort", onAbort);
10841
- };
10842
- worker.on("message", onMessage);
10843
- worker.on("error", onError);
10844
- worker.on("exit", onExit);
10845
- abortSignal?.addEventListener("abort", onAbort, { once: true });
10846
- worker.postMessage(task);
10847
- });
10848
- }
10849
- };
10850
- var OffThreadArchiveScoring = class {
10851
- pool = null;
10852
- poolFailed = false;
10853
- syncFallback = new SyncArchiveScoring();
10854
- constructor(poolSize) {
10855
- if (poolSize !== void 0) {
10856
- this.pool = new ArchiveScoringWorkerPool(poolSize);
10857
- }
10858
- }
10859
- /** Workers currently scoring; 0 when no pool has been created yet. */
10860
- get busyWorkers() {
10861
- return this.pool?.busyWorkers ?? 0;
10862
- }
10863
- async score(items, tokens, abortSignal) {
10864
- if (items.length === 0 || tokens.length === 0) return [];
10865
- if (abortSignal?.aborted) return [];
10866
- if (this.pool === null && !this.poolFailed) {
10867
- try {
10868
- this.pool = new ArchiveScoringWorkerPool();
10869
- } catch (err) {
10870
- this.poolFailed = true;
10871
- log.debug(`archive-scoring: worker pool unavailable, using sync fallback \u2014 ${err.message}`);
10872
- }
10873
- }
10874
- if (this.pool !== null) {
10875
- const dispatchStart = Date.now();
10876
- try {
10877
- const task = {
10878
- items,
10879
- tokens
10880
- };
10881
- const results = await this.pool.run(task, abortSignal);
10882
- if (abortSignal?.aborted) return [];
10883
- return results;
10884
- } catch (err) {
10885
- if (abortSignal?.aborted) return [];
10886
- if (Date.now() - dispatchStart > DISPATCH_TIMEOUT_MS * 0.5) return [];
10887
- log.debug(`archive-scoring: worker dispatch failed, using sync fallback \u2014 ${err.message}`);
10888
- }
10889
- }
10890
- return this.syncFallback.score(items, tokens, abortSignal);
10891
- }
10892
- /** @internal — terminate the underlying pool (tests / shutdown). */
10893
- async terminate() {
10894
- if (this.pool !== null) {
10895
- await this.pool.terminate();
10896
- this.pool = null;
10897
- }
10898
- }
10899
- };
10900
- var defaultStrategy = null;
10901
- function getDefaultArchiveScoring() {
10902
- if (defaultStrategy === null) {
10903
- defaultStrategy = new OffThreadArchiveScoring();
10904
- }
10905
- return defaultStrategy;
10906
- }
10907
- async function disposeDefaultArchiveScoring() {
10908
- if (defaultStrategy !== null) {
10909
- const strategy = defaultStrategy;
10910
- defaultStrategy = null;
10911
- if (strategy instanceof OffThreadArchiveScoring) {
10912
- await strategy.terminate();
10913
- }
10914
- }
10915
- }
10916
-
10917
- // src/orchestration/recall-search-pipeline.ts
10657
+ import path9 from "path";
10918
10658
  var RecallSearchPipelineCoordinator = class {
10919
10659
  constructor(deps) {
10920
10660
  this.deps = deps;
@@ -11041,23 +10781,16 @@ var RecallSearchPipelineCoordinator = class {
11041
10781
  const scopedSeedResults = queryAwarePrefilter.candidatePaths?.size ? await this.deps.searchScopedMemoryCandidates(
11042
10782
  queryAwarePrefilter.candidatePaths,
11043
10783
  prompt,
11044
- // Overfetch the FULL scoped candidate set BEFORE the generic-recall
11045
- // exclusion `filterRecallCandidates` applies below (L464). Capping to
11046
- // `qmdFetchLimit` here lets excluded paths (artifacts, activity digests,
11047
- // meeting records) consume the caller's budget and drop legitimate hits
11048
- // with no refill — the hot-path mirror of the archive-fallback fix. The
11049
- // candidate set is an already-bounded prefilter, so its size is the
11050
- // natural ceiling; the post-exclusion cap is applied by filterRecallCandidates.
10784
+ // Exclude dedicated surfaces before capping the bounded prefilter set.
11051
10785
  queryAwarePrefilter.candidatePaths.size,
11052
10786
  { allowArchived: options.collection !== void 0 }
11053
10787
  ) : [];
11054
- const recallable = (r) => !isGenericRecallExcludedPath(r.path, this.deps.config.memoryDir);
10788
+ const recallable = (r) => !isGenericRecallExcludedPath(r.path, this.deps.config, "qmd");
11055
10789
  let fetchLimit = Math.max(qmdFetchLimit, qmdHybridFetchLimit);
11056
10790
  const maxFetchLimit = Math.min(
11057
10791
  320,
11058
10792
  Math.max(fetchLimit, qmdFetchLimit * 5)
11059
10793
  );
11060
- const MAX_ATTEMPTS = 2;
11061
10794
  const qmdRecallBudgetMs = this.deps.config.recallEnrichmentDeadlineMs ?? 25e3;
11062
10795
  const qmdRecallBudgetEnabled = qmdRecallBudgetMs > 0;
11063
10796
  const startedAtMs = Date.now();
@@ -11080,7 +10813,7 @@ var RecallSearchPipelineCoordinator = class {
11080
10813
  recallNamespaces: options.recallNamespaces,
11081
10814
  resolveNamespace: options.resolveNamespace,
11082
10815
  limit: qmdFetchLimit,
11083
- memoryRoot: this.deps.config.memoryDir
10816
+ pathPolicy: this.deps.config
11084
10817
  });
11085
10818
  const emitDebugSnapshot = async (results, currentFetchLimit) => {
11086
10819
  if (!options.onDebugSnapshot) return;
@@ -11109,7 +10842,7 @@ var RecallSearchPipelineCoordinator = class {
11109
10842
  await emitDebugSnapshot([], fetchLimit);
11110
10843
  return [];
11111
10844
  }
11112
- for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {
10845
+ for (; ; ) {
11113
10846
  throwIfRecallAborted(options.abortSignal);
11114
10847
  if (qmdRecallBudgetEnabled && Date.now() - startedAtMs >= qmdRecallBudgetMs) {
11115
10848
  break;
@@ -11145,7 +10878,11 @@ var RecallSearchPipelineCoordinator = class {
11145
10878
  lastHybridTopUpUsed = false;
11146
10879
  lastHybridTopUpSkippedReason = void 0;
11147
10880
  let mergedResults = primaryResults;
11148
- if (primaryResults.length < qmdFetchLimit && (!qmdRecallBudgetEnabled || Date.now() - startedAtMs < qmdRecallBudgetMs)) {
10881
+ const primaryRecallableCount = primaryResults.filter(recallable).length;
10882
+ const primaryIncludesArchivePath = primaryResults.some(
10883
+ (result) => isTopLevelArchivePath(result.path, this.deps.config, "qmd")
10884
+ );
10885
+ if (primaryRecallableCount < qmdFetchLimit && (primaryResults.length < qmdFetchLimit || primaryIncludesArchivePath) && (!qmdRecallBudgetEnabled || Date.now() - startedAtMs < qmdRecallBudgetMs)) {
11149
10886
  if (debugSearchOptions?.intent) {
11150
10887
  lastHybridTopUpSkippedReason = "intent_hint_active";
11151
10888
  } else if (this.deps.config.qmdSearchStrategy === "lex") {
@@ -11194,7 +10931,7 @@ var RecallSearchPipelineCoordinator = class {
11194
10931
  recallNamespaces: options.recallNamespaces,
11195
10932
  resolveNamespace: options.resolveNamespace,
11196
10933
  limit: fetchLimit,
11197
- memoryRoot: this.deps.config.memoryDir
10934
+ pathPolicy: this.deps.config
11198
10935
  });
11199
10936
  if (filteredResults.length >= qmdFetchLimit) {
11200
10937
  const capped2 = filteredResults.slice(0, qmdFetchLimit);
@@ -11204,11 +10941,7 @@ var RecallSearchPipelineCoordinator = class {
11204
10941
  if (filteredResults.length > bestFiltered.length) {
11205
10942
  bestFiltered = filteredResults;
11206
10943
  }
11207
- if (mergedResults.length === 0) {
11208
- await emitDebugSnapshot(filteredResults, fetchLimit);
11209
- return filteredResults;
11210
- }
11211
- if (mergedResults.length < fetchLimit && filteredResults.length > 0) {
10944
+ if (primaryResults.length < fetchLimit) {
11212
10945
  await emitDebugSnapshot(filteredResults, fetchLimit);
11213
10946
  return filteredResults;
11214
10947
  }
@@ -11229,7 +10962,7 @@ var RecallSearchPipelineCoordinator = class {
11229
10962
  if (hits.length === 0) return [];
11230
10963
  const results = [];
11231
10964
  for (const hit of hits) {
11232
- const fullPath = path8.isAbsolute(hit.path) ? hit.path : path8.join(this.deps.config.memoryDir, hit.path);
10965
+ const fullPath = path9.isAbsolute(hit.path) ? hit.path : path9.join(this.deps.config.memoryDir, hit.path);
11233
10966
  const memory = await this.deps.storage.readMemoryByPath(fullPath);
11234
10967
  if (!memory) continue;
11235
10968
  results.push({
@@ -11242,52 +10975,21 @@ var RecallSearchPipelineCoordinator = class {
11242
10975
  return results;
11243
10976
  }
11244
10977
  /**
11245
- * Long-term fallback retrieval.
11246
- * Searches archived memories only, and is invoked only when hot recall returns zero hits.
10978
+ * Cold fallback retains qualifying query-aware candidates. Archive records
10979
+ * belong to dedicated surfaces and never re-enter generic recall.
11247
10980
  */
11248
- async searchLongTermArchiveFallback(prompt, recallNamespaces, limit, queryAwarePrefilter, abortSignal) {
10981
+ async searchQueryAwareFallback(prompt, limit, queryAwarePrefilter, abortSignal) {
11249
10982
  throwIfRecallAborted(abortSignal);
11250
10983
  const cappedLimit = Math.max(0, limit);
11251
- if (cappedLimit === 0) return [];
11252
- if (queryAwarePrefilter?.candidatePaths?.size === 0) return [];
10984
+ if (cappedLimit === 0 || queryAwarePrefilter?.candidatePaths?.size === 0) return [];
11253
10985
  const candidatePaths = queryAwarePrefilter?.candidatePaths;
11254
10986
  const scopedSeedResults = (candidatePaths?.size ? await this.deps.searchScopedMemoryCandidates(
11255
10987
  candidatePaths,
11256
10988
  prompt,
11257
- // Overfetch the FULL scoped candidate set BEFORE the generic-recall
11258
- // exclusion below. Capping to `cappedLimit` first lets excluded paths
11259
- // (artifacts, activity digests, meeting records) consume the caller's
11260
- // budget and drop legitimate hits with no refill — e.g. a prefilter of
11261
- // [meetingRecord, facts/a.md] at limit 1 would return nothing. The
11262
- // candidate set is an already-bounded prefilter, so its size is the
11263
- // natural ceiling; the post-exclusion cap is applied below.
11264
10989
  candidatePaths.size,
11265
10990
  { allowArchived: true }
11266
- ) : []).filter((result) => !isGenericRecallExcludedPath(result.path, this.deps.config.memoryDir));
11267
- if (scopedSeedResults.length >= cappedLimit) {
11268
- return scopedSeedResults.slice(0, cappedLimit);
11269
- }
11270
- const tokens = Array.from(new Set(tokenizeRecallQuery(prompt)));
11271
- if (tokens.length === 0) return scopedSeedResults;
11272
- throwIfRecallAborted(abortSignal);
11273
- const archivedMemories = await this.deps.readArchivedMemoriesForNamespaces(recallNamespaces);
11274
- if (archivedMemories.length === 0) return scopedSeedResults;
11275
- throwIfRecallAborted(abortSignal);
11276
- const scoring = getDefaultArchiveScoring();
11277
- const scoredResults = await scoring.score(archivedMemories.map(memoryFileToScoreItem), tokens, abortSignal);
11278
- throwIfRecallAborted(abortSignal);
11279
- const scored = scoredResults.map((r) => ({
11280
- docid: r.docid,
11281
- path: r.path,
11282
- score: r.score,
11283
- snippet: r.snippet
11284
- }));
11285
- return dedupeResultsByNamespace(
11286
- [...scopedSeedResults, ...scored],
11287
- this.deps.namespaceFromPath,
11288
- cappedLimit,
11289
- { filter: (result) => !isGenericRecallExcludedPath(result.path, this.deps.config.memoryDir) }
11290
- );
10991
+ ) : []).filter((result) => !isGenericRecallExcludedPath(result.path, this.deps.config, "qmd"));
10992
+ return scopedSeedResults.slice(0, cappedLimit);
11291
10993
  }
11292
10994
  async applyColdFallbackPipeline(options) {
11293
10995
  const caps = options.caps ?? resolveCapabilities(this.deps.config);
@@ -11400,18 +11102,17 @@ var RecallSearchPipelineCoordinator = class {
11400
11102
  }
11401
11103
  if (longTerm.length === 0) {
11402
11104
  longTerm = await runColdStepWithinDeadline(
11403
- "archive scan",
11105
+ "query-aware fallback",
11404
11106
  [],
11405
- (stepSignal) => this.deps.searchLongTermArchiveFallback(
11107
+ (stepSignal) => this.deps.searchQueryAwareFallback(
11406
11108
  options.prompt,
11407
- options.recallNamespaces,
11408
11109
  options.recallResultLimit,
11409
11110
  options.queryAwarePrefilter,
11410
11111
  stepSignal
11411
11112
  )
11412
11113
  );
11413
11114
  if (longTerm.length > 0) {
11414
- log.debug("cold-tier recall source=archive-scan");
11115
+ log.debug("cold-tier recall source=query-aware-fallback");
11415
11116
  }
11416
11117
  }
11417
11118
  if (longTerm.length === 0) return [];
@@ -11424,7 +11125,7 @@ var RecallSearchPipelineCoordinator = class {
11424
11125
  const storage = await this.deps.storageRouter.storageFor(namespace);
11425
11126
  const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
11426
11127
  if (!storageDir) continue;
11427
- const recallRoot = path8.resolve(storageDir);
11128
+ const recallRoot = path9.resolve(storageDir);
11428
11129
  if (seenRecallRoots.has(recallRoot)) continue;
11429
11130
  seenRecallRoots.add(recallRoot);
11430
11131
  recallRoots.push(recallRoot);
@@ -11448,8 +11149,8 @@ var RecallSearchPipelineCoordinator = class {
11448
11149
  if (resolvedCold) scopedResults.push(resolvedCold.result);
11449
11150
  continue;
11450
11151
  }
11451
- if (path8.isAbsolute(result.path)) {
11452
- if (recallRoots.some((recallRoot) => isPathInsideStorageRoot(recallRoot, path8.resolve(result.path)))) {
11152
+ if (path9.isAbsolute(result.path)) {
11153
+ if (recallRoots.some((recallRoot) => isPathInsideStorageRoot(recallRoot, path9.resolve(result.path)))) {
11453
11154
  scopedResults.push(result);
11454
11155
  }
11455
11156
  continue;
@@ -11458,7 +11159,7 @@ var RecallSearchPipelineCoordinator = class {
11458
11159
  }
11459
11160
  results = scopedResults;
11460
11161
  }
11461
- results = results.filter((r) => !isGenericRecallExcludedPath(r.path, this.deps.config.memoryDir));
11162
+ results = results.filter((r) => !isGenericRecallExcludedPath(r.path, this.deps.config, "qmd"));
11462
11163
  if (results.length === 0) return [];
11463
11164
  const isFullModeGraphAssist = resolveQmdCapabilities(this.deps.config).qmdTierParityGraph && graphCaps.multiGraphMemory && caps.graphAssistInFullMode && options.recallMode === "full" && results.length >= Math.max(1, this.deps.config.graphAssistMinSeedResults ?? 3);
11464
11165
  const shouldRunGraphExpansion = resolveQmdCapabilities(this.deps.config).qmdTierParityGraph && (options.recallMode === "graph_mode" || isFullModeGraphAssist);
@@ -11472,6 +11173,9 @@ var RecallSearchPipelineCoordinator = class {
11472
11173
  });
11473
11174
  results = merged;
11474
11175
  }
11176
+ results = results.filter(
11177
+ (result) => !isGenericRecallExcludedPath(result.path, this.deps.config, "qmd")
11178
+ );
11475
11179
  const boostInput = await this.deps.filterSearchResultsForRecall(
11476
11180
  results,
11477
11181
  void 0,
@@ -12469,7 +12173,7 @@ var TurnIngestionCoordinator = class {
12469
12173
 
12470
12174
  // src/orchestration/recall-introspection.ts
12471
12175
  import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
12472
- import path10 from "path";
12176
+ import path11 from "path";
12473
12177
 
12474
12178
  // src/taxonomy/default-taxonomy.ts
12475
12179
  var DEFAULT_TAXONOMY = {
@@ -12592,7 +12296,7 @@ function generateResolverDocument(taxonomy) {
12592
12296
 
12593
12297
  // src/taxonomy/taxonomy-loader.ts
12594
12298
  import { readFile as readFile3, mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
12595
- import path9 from "path";
12299
+ import path10 from "path";
12596
12300
  var TAXONOMY_DIR = ".taxonomy";
12597
12301
  var TAXONOMY_FILE = "taxonomy.json";
12598
12302
  var MAX_SLUG_LENGTH = 32;
@@ -12690,7 +12394,7 @@ function validateTaxonomy(taxonomy) {
12690
12394
  }
12691
12395
  }
12692
12396
  async function loadTaxonomy(memoryDir) {
12693
- const taxonomyPath = path9.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
12397
+ const taxonomyPath = path10.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
12694
12398
  let raw;
12695
12399
  try {
12696
12400
  raw = await readFile3(taxonomyPath, "utf-8");
@@ -12740,16 +12444,16 @@ async function loadTaxonomy(memoryDir) {
12740
12444
  }
12741
12445
  async function saveTaxonomy(memoryDir, taxonomy) {
12742
12446
  validateTaxonomy(taxonomy);
12743
- const dir = path9.join(memoryDir, TAXONOMY_DIR);
12447
+ const dir = path10.join(memoryDir, TAXONOMY_DIR);
12744
12448
  await mkdir4(dir, { recursive: true });
12745
- const filePath = path9.join(dir, TAXONOMY_FILE);
12449
+ const filePath = path10.join(dir, TAXONOMY_FILE);
12746
12450
  await writeFile4(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
12747
12451
  }
12748
12452
  function getTaxonomyDir(memoryDir) {
12749
- return path9.join(memoryDir, TAXONOMY_DIR);
12453
+ return path10.join(memoryDir, TAXONOMY_DIR);
12750
12454
  }
12751
12455
  function getTaxonomyFilePath(memoryDir) {
12752
- return path9.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
12456
+ return path10.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
12753
12457
  }
12754
12458
 
12755
12459
  // src/orchestration/recall-introspection.ts
@@ -12773,7 +12477,7 @@ var RecallIntrospectionCoordinator = class {
12773
12477
  }
12774
12478
  async getLastGraphRecallSnapshot(namespace) {
12775
12479
  const storage = await this.deps.getStorage(namespace);
12776
- const snapshotPath = path10.join(
12480
+ const snapshotPath = path11.join(
12777
12481
  storage.dir,
12778
12482
  "state",
12779
12483
  "last_graph_recall.json"
@@ -12812,7 +12516,7 @@ var RecallIntrospectionCoordinator = class {
12812
12516
  }
12813
12517
  async getLastIntentSnapshot(namespace) {
12814
12518
  const storage = await this.deps.getStorage(namespace);
12815
- const snapshotPath = path10.join(storage.dir, "state", "last_intent.json");
12519
+ const snapshotPath = path11.join(storage.dir, "state", "last_intent.json");
12816
12520
  try {
12817
12521
  const raw = await readFile4(snapshotPath, "utf-8");
12818
12522
  const parsed = JSON.parse(raw);
@@ -12845,7 +12549,7 @@ var RecallIntrospectionCoordinator = class {
12845
12549
  }
12846
12550
  async getLastQmdRecallSnapshot(namespace) {
12847
12551
  const storage = await this.deps.getStorage(namespace);
12848
- const snapshotPath = path10.join(
12552
+ const snapshotPath = path11.join(
12849
12553
  storage.dir,
12850
12554
  "state",
12851
12555
  "last_qmd_recall.json"
@@ -13135,12 +12839,12 @@ var RecallIntrospectionCoordinator = class {
13135
12839
  }
13136
12840
  async recordLastIntentSnapshot(options) {
13137
12841
  try {
13138
- const snapshotPath = path10.join(
12842
+ const snapshotPath = path11.join(
13139
12843
  options.storage.dir,
13140
12844
  "state",
13141
12845
  "last_intent.json"
13142
12846
  );
13143
- await mkdir5(path10.dirname(snapshotPath), { recursive: true });
12847
+ await mkdir5(path11.dirname(snapshotPath), { recursive: true });
13144
12848
  await writeFile5(
13145
12849
  snapshotPath,
13146
12850
  JSON.stringify(options.snapshot, null, 2),
@@ -13152,12 +12856,12 @@ var RecallIntrospectionCoordinator = class {
13152
12856
  }
13153
12857
  async recordLastQmdRecallSnapshot(options) {
13154
12858
  try {
13155
- const snapshotPath = path10.join(
12859
+ const snapshotPath = path11.join(
13156
12860
  options.storage.dir,
13157
12861
  "state",
13158
12862
  "last_qmd_recall.json"
13159
12863
  );
13160
- await mkdir5(path10.dirname(snapshotPath), { recursive: true });
12864
+ await mkdir5(path11.dirname(snapshotPath), { recursive: true });
13161
12865
  await writeFile5(
13162
12866
  snapshotPath,
13163
12867
  JSON.stringify(options.snapshot, null, 2),
@@ -13172,8 +12876,8 @@ var RecallIntrospectionCoordinator = class {
13172
12876
  const stateDir = await this.deps.resolveStateDirForNamespace(
13173
12877
  options.namespace
13174
12878
  );
13175
- const snapshotPath = path10.join(stateDir, "last_intent.json");
13176
- await mkdir5(path10.dirname(snapshotPath), { recursive: true });
12879
+ const snapshotPath = path11.join(stateDir, "last_intent.json");
12880
+ await mkdir5(path11.dirname(snapshotPath), { recursive: true });
13177
12881
  await writeFile5(
13178
12882
  snapshotPath,
13179
12883
  JSON.stringify(options.snapshot, null, 2),
@@ -13187,7 +12891,7 @@ var RecallIntrospectionCoordinator = class {
13187
12891
 
13188
12892
  // src/orchestration/orchestrator-init.ts
13189
12893
  import { readdir as readdir2, stat as stat2, unlink as unlink2 } from "fs/promises";
13190
- import path11 from "path";
12894
+ import path12 from "path";
13191
12895
  var OrchestratorInitCoordinator = class {
13192
12896
  constructor(deps) {
13193
12897
  this.deps = deps;
@@ -13283,7 +12987,7 @@ var OrchestratorInitCoordinator = class {
13283
12987
  const files = await readdir2(wsDir).catch(() => []);
13284
12988
  for (const f of files) {
13285
12989
  if (!f.startsWith(".compaction-reset-signal-")) continue;
13286
- const fp = path11.join(wsDir, f);
12990
+ const fp = path12.join(wsDir, f);
13287
12991
  const s = await stat2(fp).catch(() => null);
13288
12992
  if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
13289
12993
  await unlink2(fp).catch(() => {
@@ -13635,7 +13339,7 @@ var OrchestratorInitCoordinator = class {
13635
13339
  };
13636
13340
 
13637
13341
  // src/orchestration/persistence-index.ts
13638
- import path12 from "path";
13342
+ import path13 from "path";
13639
13343
  var PersistenceIndexCoordinator = class {
13640
13344
  constructor(deps) {
13641
13345
  this.deps = deps;
@@ -13821,7 +13525,7 @@ var PersistenceIndexCoordinator = class {
13821
13525
  const allMems = allMemsForGraph ?? [];
13822
13526
  for (const m of allMems) {
13823
13527
  if (m.frontmatter.entityRef === entityRef) {
13824
- const rel = path12.relative(storage.dir, m.path);
13528
+ const rel = path13.relative(storage.dir, m.path);
13825
13529
  if (rel !== memoryRelPath) entitySiblings.push(rel);
13826
13530
  }
13827
13531
  }
@@ -13970,7 +13674,7 @@ var PersistenceIndexCoordinator = class {
13970
13674
 
13971
13675
  // src/orchestration/workspace-ops.ts
13972
13676
  import { lstat, mkdir as mkdir6, readFile as readFile5, readdir as readdir3, realpath, writeFile as writeFile6 } from "fs/promises";
13973
- import path13 from "path";
13677
+ import path14 from "path";
13974
13678
 
13975
13679
  // src/maintenance/pattern-reinforcement.ts
13976
13680
  function patternReinforcementKey(content) {
@@ -15869,8 +15573,8 @@ var MeetingsService = class {
15869
15573
  // src/orchestration/workspace-ops.ts
15870
15574
  var MEETINGS_BUILD_DEBOUNCE_MS = 5e3;
15871
15575
  function matchesMemoryPath(candidatePath, requestedPath, memoryDir) {
15872
- const normalizedCandidate = path13.resolve(candidatePath);
15873
- return normalizedCandidate === path13.resolve(requestedPath) || normalizedCandidate === path13.resolve(memoryDir, requestedPath);
15576
+ const normalizedCandidate = path14.resolve(candidatePath);
15577
+ return normalizedCandidate === path14.resolve(requestedPath) || normalizedCandidate === path14.resolve(memoryDir, requestedPath);
15874
15578
  }
15875
15579
  function accessTrackingPathCandidates(storageDir, memoryPath) {
15876
15580
  const candidates = qmdResultPathCandidates(storageDir, memoryPath);
@@ -15878,12 +15582,12 @@ function accessTrackingPathCandidates(storageDir, memoryPath) {
15878
15582
  if (!parts) return candidates;
15879
15583
  candidates.push(
15880
15584
  ...qmdResultPathCandidates(storageDir, parts.relativePath),
15881
- ...qmdResultPathCandidates(path13.join(storageDir, "cold"), parts.relativePath)
15585
+ ...qmdResultPathCandidates(path14.join(storageDir, "cold"), parts.relativePath)
15882
15586
  );
15883
15587
  return [...new Set(candidates)];
15884
15588
  }
15885
15589
  function canonicalMemoryPath(memoryPath, memoryDir) {
15886
- return path13.resolve(path13.isAbsolute(memoryPath) ? memoryPath : path13.resolve(memoryDir, memoryPath));
15590
+ return path14.resolve(path14.isAbsolute(memoryPath) ? memoryPath : path14.resolve(memoryDir, memoryPath));
15887
15591
  }
15888
15592
  var WorkspaceOpsCoordinator = class {
15889
15593
  constructor(deps) {
@@ -15965,15 +15669,15 @@ var WorkspaceOpsCoordinator = class {
15965
15669
  this.deps.lastFileHygieneRunAtMs = now;
15966
15670
  if (hygiene.rotateEnabled) {
15967
15671
  for (const rel of hygiene.rotatePaths) {
15968
- const abs = path13.isAbsolute(rel) ? rel : path13.join(this.deps.config.workspaceDir, rel);
15672
+ const abs = path14.isAbsolute(rel) ? rel : path14.join(this.deps.config.workspaceDir, rel);
15969
15673
  try {
15970
15674
  const raw = await readFile5(abs, "utf-8");
15971
15675
  if (raw.length > hygiene.rotateMaxBytes) {
15972
- const archiveDir = path13.join(
15676
+ const archiveDir = path14.join(
15973
15677
  this.deps.config.workspaceDir,
15974
15678
  hygiene.archiveDir
15975
15679
  );
15976
- const base = path13.basename(abs);
15680
+ const base = path14.basename(abs);
15977
15681
  const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
15978
15682
  const { newContent } = await rotateMarkdownFileToArchive({
15979
15683
  filePath: abs,
@@ -15998,8 +15702,8 @@ var WorkspaceOpsCoordinator = class {
15998
15702
  log.warn(w.message);
15999
15703
  }
16000
15704
  if (hygiene.warningsLogEnabled && warnings.length > 0) {
16001
- const fp = path13.join(this.deps.config.memoryDir, hygiene.warningsLogPath);
16002
- await mkdir6(path13.dirname(fp), { recursive: true });
15705
+ const fp = path14.join(this.deps.config.memoryDir, hygiene.warningsLogPath);
15706
+ await mkdir6(path14.dirname(fp), { recursive: true });
16003
15707
  const stamp = (/* @__PURE__ */ new Date()).toISOString();
16004
15708
  const block = `
16005
15709
 
@@ -16039,7 +15743,7 @@ var WorkspaceOpsCoordinator = class {
16039
15743
  for (const categoryDir of RECALL_FALLBACK_DIRS) {
16040
15744
  if (memoryRootReal === null) break;
16041
15745
  for (const date of datesToScan) {
16042
- const dateDir = path13.join(storage.dir, categoryDir, date);
15746
+ const dateDir = path14.join(storage.dir, categoryDir, date);
16043
15747
  try {
16044
15748
  const dirStat = await lstat(dateDir);
16045
15749
  if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
@@ -16048,7 +15752,7 @@ var WorkspaceOpsCoordinator = class {
16048
15752
  for (const entry of entries) {
16049
15753
  if (entry.isSymbolicLink()) continue;
16050
15754
  if (!entry.name.endsWith(".md")) continue;
16051
- const fullPath = path13.join(dateDir, entry.name);
15755
+ const fullPath = path14.join(dateDir, entry.name);
16052
15756
  try {
16053
15757
  assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);
16054
15758
  const raw = await readFile5(fullPath, "utf-8");
@@ -16070,7 +15774,7 @@ var WorkspaceOpsCoordinator = class {
16070
15774
  facts.push({
16071
15775
  path: fullPath,
16072
15776
  frontmatter: {
16073
- id: fm.id || path13.basename(entry.name, ".md"),
15777
+ id: fm.id || path14.basename(entry.name, ".md"),
16074
15778
  category: fm.category || "fact",
16075
15779
  created,
16076
15780
  updated: fm.updated || created,
@@ -16093,13 +15797,13 @@ var WorkspaceOpsCoordinator = class {
16093
15797
  return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
16094
15798
  });
16095
15799
  const hourlySummaries = [];
16096
- const hourlyBaseDir = path13.join(storage.dir, "summaries", "hourly");
15800
+ const hourlyBaseDir = path14.join(storage.dir, "summaries", "hourly");
16097
15801
  try {
16098
15802
  const sessionKeys = await readdir3(hourlyBaseDir, { withFileTypes: true });
16099
15803
  for (const sk of sessionKeys) {
16100
15804
  if (!sk.isDirectory()) continue;
16101
15805
  for (const date of datesToScan) {
16102
- const summaryFile = path13.join(hourlyBaseDir, sk.name, `${date}.md`);
15806
+ const summaryFile = path14.join(hourlyBaseDir, sk.name, `${date}.md`);
16103
15807
  try {
16104
15808
  const raw = await readFile5(summaryFile, "utf-8");
16105
15809
  const filtered = filterHourlySummaryMarkdownForLocalDay(
@@ -16563,18 +16267,18 @@ ${reflectionsContent.trim()}
16563
16267
  // src/orchestration/namespace-read-fanout.ts
16564
16268
  import { existsSync, readFileSync } from "fs";
16565
16269
  import { stat as stat3 } from "fs/promises";
16566
- import path15 from "path";
16270
+ import path16 from "path";
16567
16271
 
16568
16272
  // src/orchestration/orchestrator-namespace-scope.ts
16569
- import path14 from "path";
16273
+ import path15 from "path";
16570
16274
  function computeSemanticDedupScope(targetStorage, config) {
16571
16275
  if (!resolveNamespaceCapabilities(config).namespaces) return {};
16572
- const memoryDir = path14.resolve(config.memoryDir);
16573
- const storageDir = path14.resolve(targetStorage.dir);
16276
+ const memoryDir = path15.resolve(config.memoryDir);
16277
+ const storageDir = path15.resolve(targetStorage.dir);
16574
16278
  if (storageDir === memoryDir) {
16575
16279
  return { pathExcludePrefixes: ["namespaces/"] };
16576
16280
  }
16577
- let rel = path14.relative(memoryDir, storageDir);
16281
+ let rel = path15.relative(memoryDir, storageDir);
16578
16282
  if (!rel || rel.startsWith("..")) {
16579
16283
  log.debug(
16580
16284
  `semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
@@ -16627,7 +16331,7 @@ var NamespaceReadFanoutCoordinator = class {
16627
16331
  loadNamespaceStorageDirHintsFromCatalog() {
16628
16332
  if (this.deps.namespaceStorageDirHintsLoaded || !this.deps.namespaceCatalog.enabled) return;
16629
16333
  this.deps.namespaceStorageDirHintsLoaded = true;
16630
- const catalogPath = path15.join(this.deps.config.memoryDir, "state", "namespaces.jsonl");
16334
+ const catalogPath = path16.join(this.deps.config.memoryDir, "state", "namespaces.jsonl");
16631
16335
  if (!existsSync(catalogPath)) return;
16632
16336
  let body;
16633
16337
  try {
@@ -16664,7 +16368,7 @@ var NamespaceReadFanoutCoordinator = class {
16664
16368
  if (!this.deps.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
16665
16369
  continue;
16666
16370
  }
16667
- const resolvedStorageDir = path15.resolve(record.storageDir);
16371
+ const resolvedStorageDir = path16.resolve(record.storageDir);
16668
16372
  const current = preferredByStorageDir.get(resolvedStorageDir);
16669
16373
  preferredByStorageDir.set(
16670
16374
  resolvedStorageDir,
@@ -16845,12 +16549,12 @@ var NamespaceReadFanoutCoordinator = class {
16845
16549
  }
16846
16550
  async resolveStateDirForNamespace(namespace) {
16847
16551
  if (!resolveNamespaceCapabilities(this.deps.config).namespaces) {
16848
- return path15.join(this.deps.config.memoryDir, "state");
16552
+ return path16.join(this.deps.config.memoryDir, "state");
16849
16553
  }
16850
16554
  if (namespace !== this.deps.config.defaultNamespace) {
16851
- return path15.join(this.deps.config.memoryDir, "namespaces", namespace, "state");
16555
+ return path16.join(this.deps.config.memoryDir, "namespaces", namespace, "state");
16852
16556
  }
16853
- const candidate = path15.join(
16557
+ const candidate = path16.join(
16854
16558
  this.deps.config.memoryDir,
16855
16559
  "namespaces",
16856
16560
  this.deps.config.defaultNamespace
@@ -16858,11 +16562,11 @@ var NamespaceReadFanoutCoordinator = class {
16858
16562
  try {
16859
16563
  const candidateStat = await stat3(candidate);
16860
16564
  if (candidateStat.isDirectory()) {
16861
- return path15.join(candidate, "state");
16565
+ return path16.join(candidate, "state");
16862
16566
  }
16863
16567
  } catch {
16864
16568
  }
16865
- return path15.join(this.deps.config.memoryDir, "state");
16569
+ return path16.join(this.deps.config.memoryDir, "state");
16866
16570
  }
16867
16571
  namespaceFromPath(p) {
16868
16572
  if (!resolveNamespaceCapabilities(this.deps.config).namespaces) return this.deps.config.defaultNamespace;
@@ -16893,16 +16597,6 @@ var NamespaceReadFanoutCoordinator = class {
16893
16597
  );
16894
16598
  return lists.flat();
16895
16599
  }
16896
- async readArchivedMemoriesForNamespaces(namespaces) {
16897
- const uniq = Array.from(new Set(namespaces.filter(Boolean)));
16898
- const lists = await Promise.all(
16899
- uniq.map(async (ns) => {
16900
- const sm = await this.deps.storageRouter.storageFor(ns);
16901
- return sm.readArchivedMemories();
16902
- })
16903
- );
16904
- return lists.flat();
16905
- }
16906
16600
  };
16907
16601
 
16908
16602
  // src/orchestration/recall-entry.ts
@@ -17805,7 +17499,6 @@ var Orchestrator = class {
17805
17499
  if (this.conversationQmd && this.conversationQmd !== this.qmd) {
17806
17500
  await this.conversationQmd.dispose?.();
17807
17501
  }
17808
- await disposeDefaultArchiveScoring();
17809
17502
  } finally {
17810
17503
  if (bufferFlushError !== void 0) {
17811
17504
  log.warn(
@@ -17916,7 +17609,7 @@ var Orchestrator = class {
17916
17609
  const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
17917
17610
  if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
17918
17611
  if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
17919
- const resolvedStorageDir = path16.resolve(storageDir);
17612
+ const resolvedStorageDir = path17.resolve(storageDir);
17920
17613
  let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
17921
17614
  if (!hints) {
17922
17615
  hints = /* @__PURE__ */ new Set();
@@ -17927,21 +17620,21 @@ var Orchestrator = class {
17927
17620
  storageDirMatchesNamespaceHint(namespace, storageDir) {
17928
17621
  const ns = normalizeNamespaceIdentity(namespace);
17929
17622
  if (!ns) return false;
17930
- const resolvedStorageDir = path16.resolve(storageDir);
17931
- const resolvedMemoryDir = path16.resolve(this.config.memoryDir);
17623
+ const resolvedStorageDir = path17.resolve(storageDir);
17624
+ const resolvedMemoryDir = path17.resolve(this.config.memoryDir);
17932
17625
  const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
17933
17626
  if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
17934
- const resolvedNamespacesDir = path16.join(resolvedMemoryDir, "namespaces");
17627
+ const resolvedNamespacesDir = path17.join(resolvedMemoryDir, "namespaces");
17935
17628
  if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
17936
- const rawRoot = path16.resolve(resolvedNamespacesDir, ns);
17937
- const tokenRoot = path16.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
17629
+ const rawRoot = path17.resolve(resolvedNamespacesDir, ns);
17630
+ const tokenRoot = path17.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
17938
17631
  return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
17939
17632
  }
17940
17633
  namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
17941
- if (resolvedStorageDir === path16.resolve(this.config.memoryDir)) {
17634
+ if (resolvedStorageDir === path17.resolve(this.config.memoryDir)) {
17942
17635
  return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
17943
17636
  }
17944
- const leaf = path16.basename(resolvedStorageDir);
17637
+ const leaf = path17.basename(resolvedStorageDir);
17945
17638
  const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
17946
17639
  if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
17947
17640
  if (record.namespace === leaf) return 1;
@@ -18077,7 +17770,7 @@ var Orchestrator = class {
18077
17770
  StorageManager.setScopedCacheInvalidationDefault(config.memoryDir, scopedCacheInvalidationEnabled);
18078
17771
  this.profiler = new ProfilingCollector({
18079
17772
  enabled: resolvePipelineProcessingCapabilities(this.config).profiling,
18080
- storageDir: config.profilingStorageDir || path16.join(config.memoryDir, "profiling"),
17773
+ storageDir: config.profilingStorageDir || path17.join(config.memoryDir, "profiling"),
18081
17774
  maxTraces: config.profilingMaxTraces
18082
17775
  });
18083
17776
  this.namespaceCatalog = new NamespaceCatalog(config);
@@ -18164,7 +17857,7 @@ var Orchestrator = class {
18164
17857
  this.compounding = resolveConsolidationCapabilities(config).compounding ? new CompoundingEngine(config, this.storage) : void 0;
18165
17858
  this.buffer = new SmartBuffer(config, this.storage);
18166
17859
  this.transcript = new TranscriptManager(config);
18167
- this.conversationIndexDir = path16.join(
17860
+ this.conversationIndexDir = path17.join(
18168
17861
  config.memoryDir,
18169
17862
  "conversation-index",
18170
17863
  "chunks"
@@ -18311,7 +18004,7 @@ var Orchestrator = class {
18311
18004
  saveContentHashIndexes: () => this.saveContentHashIndexes()
18312
18005
  });
18313
18006
  this.threading = new ThreadingManager(
18314
- path16.join(config.memoryDir, "threads"),
18007
+ path17.join(config.memoryDir, "threads"),
18315
18008
  config.threadingGapMinutes
18316
18009
  );
18317
18010
  const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
@@ -18844,7 +18537,7 @@ ${doc.content}` : doc.content,
18844
18537
  if (!paths) return null;
18845
18538
  const scoped = /* @__PURE__ */ new Set();
18846
18539
  for (const memoryPath of paths) {
18847
- if (!memoryPath || isGenericRecallExcludedPath(memoryPath, this.config.memoryDir)) continue;
18540
+ if (!memoryPath || isGenericRecallExcludedPath(memoryPath, this.config, "qmd")) continue;
18848
18541
  if (resolveNamespaceCapabilities(this.config).namespaces && !recallNamespaces.includes(this.namespaceFromPath(memoryPath))) {
18849
18542
  continue;
18850
18543
  }
@@ -19471,10 +19164,9 @@ ${doc.content}` : doc.content,
19471
19164
  limit
19472
19165
  );
19473
19166
  }
19474
- async searchLongTermArchiveFallback(prompt, recallNamespaces, limit, queryAwarePrefilter, abortSignal) {
19475
- return this.recallSearchPipelineCoordinator.searchLongTermArchiveFallback(
19167
+ async searchQueryAwareFallback(prompt, limit, queryAwarePrefilter, abortSignal) {
19168
+ return this.recallSearchPipelineCoordinator.searchQueryAwareFallback(
19476
19169
  prompt,
19477
- recallNamespaces,
19478
19170
  limit,
19479
19171
  queryAwarePrefilter,
19480
19172
  abortSignal
@@ -19671,11 +19363,6 @@ ${doc.content}` : doc.content,
19671
19363
  namespaces
19672
19364
  );
19673
19365
  }
19674
- async readArchivedMemoriesForNamespaces(namespaces) {
19675
- return this.namespaceReadFanoutCoordinator.readArchivedMemoriesForNamespaces(
19676
- namespaces
19677
- );
19678
- }
19679
19366
  };
19680
19367
 
19681
19368
  // src/relay/mission-fixture.ts
@@ -20423,9 +20110,9 @@ function readStructuralSymbol(entry) {
20423
20110
  const rec = entry;
20424
20111
  const symbol = typeof rec.symbol === "string" ? rec.symbol.trim() : "";
20425
20112
  if (!symbol) return null;
20426
- const path31 = typeof rec.path === "string" && rec.path.length > 0 ? rec.path : void 0;
20113
+ const path32 = typeof rec.path === "string" && rec.path.length > 0 ? rec.path : void 0;
20427
20114
  const kind = typeof rec.kind === "string" && rec.kind.length > 0 ? rec.kind : void 0;
20428
- const item = path31 !== void 0 && kind !== void 0 ? { symbol, path: path31, kind } : path31 !== void 0 ? { symbol, path: path31 } : kind !== void 0 ? { symbol, kind } : { symbol };
20115
+ const item = path32 !== void 0 && kind !== void 0 ? { symbol, path: path32, kind } : path32 !== void 0 ? { symbol, path: path32 } : kind !== void 0 ? { symbol, kind } : { symbol };
20429
20116
  return item;
20430
20117
  }
20431
20118
  function classifySpawnError(err) {
@@ -20499,7 +20186,7 @@ var DEFAULT_GRACE_PERIOD_DAYS = 7;
20499
20186
 
20500
20187
  // src/binary-lifecycle/backend.ts
20501
20188
  import fsp from "fs/promises";
20502
- import path17 from "path";
20189
+ import path18 from "path";
20503
20190
  var FilesystemBackend = class {
20504
20191
  type = "filesystem";
20505
20192
  basePath;
@@ -20507,19 +20194,19 @@ var FilesystemBackend = class {
20507
20194
  if (!basePath || basePath.trim().length === 0) {
20508
20195
  throw new Error("FilesystemBackend requires a non-empty basePath");
20509
20196
  }
20510
- this.basePath = path17.resolve(basePath);
20197
+ this.basePath = path18.resolve(basePath);
20511
20198
  }
20512
20199
  resolveRemotePath(remotePath) {
20513
- const resolved = path17.isAbsolute(remotePath) ? path17.resolve(remotePath) : path17.resolve(this.basePath, remotePath);
20514
- const relative = path17.relative(this.basePath, resolved);
20515
- if (relative === ".." || relative.startsWith(`..${path17.sep}`) || path17.isAbsolute(relative)) {
20200
+ const resolved = path18.isAbsolute(remotePath) ? path18.resolve(remotePath) : path18.resolve(this.basePath, remotePath);
20201
+ const relative = path18.relative(this.basePath, resolved);
20202
+ if (relative === ".." || relative.startsWith(`..${path18.sep}`) || path18.isAbsolute(relative)) {
20516
20203
  throw new Error(`FilesystemBackend remotePath escapes basePath: ${JSON.stringify(remotePath)}`);
20517
20204
  }
20518
20205
  return resolved;
20519
20206
  }
20520
20207
  isInsideBase(candidate, realBase) {
20521
- const relative = path17.relative(realBase, candidate);
20522
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path17.sep}`) && !path17.isAbsolute(relative);
20208
+ const relative = path18.relative(realBase, candidate);
20209
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path18.sep}`) && !path18.isAbsolute(relative);
20523
20210
  }
20524
20211
  async realBasePathIfExists() {
20525
20212
  try {
@@ -20548,13 +20235,13 @@ var FilesystemBackend = class {
20548
20235
  }
20549
20236
  async ensureSafeParentDirectory(dest) {
20550
20237
  const realBase = await this.ensureBaseDirectory();
20551
- const destDir = path17.dirname(dest);
20552
- const relativeDir = path17.relative(this.basePath, destDir);
20553
- const segments = relativeDir === "" ? [] : relativeDir.split(path17.sep);
20238
+ const destDir = path18.dirname(dest);
20239
+ const relativeDir = path18.relative(this.basePath, destDir);
20240
+ const segments = relativeDir === "" ? [] : relativeDir.split(path18.sep);
20554
20241
  let current = this.basePath;
20555
20242
  for (const segment of segments) {
20556
20243
  if (segment === "." || segment === "") continue;
20557
- current = path17.join(current, segment);
20244
+ current = path18.join(current, segment);
20558
20245
  try {
20559
20246
  const stat5 = await fsp.lstat(current);
20560
20247
  if (stat5.isSymbolicLink()) {
@@ -20582,13 +20269,13 @@ var FilesystemBackend = class {
20582
20269
  if (realBase === null) {
20583
20270
  return null;
20584
20271
  }
20585
- const destDir = path17.dirname(dest);
20586
- const relativeDir = path17.relative(this.basePath, destDir);
20587
- const segments = relativeDir === "" ? [] : relativeDir.split(path17.sep);
20272
+ const destDir = path18.dirname(dest);
20273
+ const relativeDir = path18.relative(this.basePath, destDir);
20274
+ const segments = relativeDir === "" ? [] : relativeDir.split(path18.sep);
20588
20275
  let current = this.basePath;
20589
20276
  for (const segment of segments) {
20590
20277
  if (segment === "." || segment === "") continue;
20591
- current = path17.join(current, segment);
20278
+ current = path18.join(current, segment);
20592
20279
  let stat5;
20593
20280
  try {
20594
20281
  stat5 = await fsp.lstat(current);
@@ -20636,7 +20323,7 @@ var FilesystemBackend = class {
20636
20323
  return dest;
20637
20324
  }
20638
20325
  async upload(localPath, remotePath) {
20639
- if (path17.isAbsolute(remotePath)) {
20326
+ if (path18.isAbsolute(remotePath)) {
20640
20327
  throw new Error(`FilesystemBackend upload remotePath must be relative: ${JSON.stringify(remotePath)}`);
20641
20328
  }
20642
20329
  const dest = this.resolveRemotePath(remotePath);
@@ -20709,7 +20396,7 @@ function createBackend(cfg) {
20709
20396
 
20710
20397
  // src/binary-lifecycle/scanner.ts
20711
20398
  import fsp2 from "fs/promises";
20712
- import path18 from "path";
20399
+ import path19 from "path";
20713
20400
  import crypto from "crypto";
20714
20401
  function matchesPatterns(filename, patterns) {
20715
20402
  const lower = filename.toLowerCase();
@@ -20734,8 +20421,8 @@ async function scanForBinaries(memoryDir, config, manifest) {
20734
20421
  return;
20735
20422
  }
20736
20423
  for (const entry of entries) {
20737
- const fullPath = path18.join(dir, entry.name);
20738
- const relativePath = path18.relative(memoryDir, fullPath).split(path18.sep).join("/");
20424
+ const fullPath = path19.join(dir, entry.name);
20425
+ const relativePath = path19.relative(memoryDir, fullPath).split(path19.sep).join("/");
20739
20426
  if (entry.isDirectory()) {
20740
20427
  if (entry.name === ".binary-lifecycle") continue;
20741
20428
  await walk(fullPath);
@@ -20775,15 +20462,15 @@ async function hashFile(filePath) {
20775
20462
 
20776
20463
  // src/binary-lifecycle/manifest.ts
20777
20464
  import fsp3 from "fs/promises";
20778
- import path19 from "path";
20465
+ import path20 from "path";
20779
20466
  import crypto2 from "crypto";
20780
20467
  var MANIFEST_DIR = ".binary-lifecycle";
20781
20468
  var MANIFEST_FILE = "manifest.json";
20782
20469
  function manifestDir(memoryDir) {
20783
- return path19.join(memoryDir, MANIFEST_DIR);
20470
+ return path20.join(memoryDir, MANIFEST_DIR);
20784
20471
  }
20785
20472
  function manifestPath(memoryDir) {
20786
- return path19.join(memoryDir, MANIFEST_DIR, MANIFEST_FILE);
20473
+ return path20.join(memoryDir, MANIFEST_DIR, MANIFEST_FILE);
20787
20474
  }
20788
20475
  async function readManifest(memoryDir) {
20789
20476
  const filePath = manifestPath(memoryDir);
@@ -20835,12 +20522,12 @@ function emptyManifest() {
20835
20522
 
20836
20523
  // src/binary-lifecycle/pipeline.ts
20837
20524
  import fsp4 from "fs/promises";
20838
- import path20 from "path";
20525
+ import path21 from "path";
20839
20526
  import crypto3 from "crypto";
20840
20527
  function isRecallCorpusMarkdown(mdPath, memoryDir) {
20841
- const rel = path20.relative(memoryDir, mdPath);
20842
- if (rel.startsWith("..") || path20.isAbsolute(rel)) return false;
20843
- const top = rel.split(path20.sep)[0];
20528
+ const rel = path21.relative(memoryDir, mdPath);
20529
+ if (rel.startsWith("..") || path21.isAbsolute(rel)) return false;
20530
+ const top = rel.split(path21.sep)[0];
20844
20531
  return RECALL_FALLBACK_DIRS.includes(top);
20845
20532
  }
20846
20533
  async function hashFile2(filePath) {
@@ -20864,13 +20551,13 @@ function escapeRegex(s) {
20864
20551
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
20865
20552
  }
20866
20553
  function resolveManifestAssetPath(memoryDir, originalPath) {
20867
- if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") || path20.isAbsolute(originalPath) || path20.win32.isAbsolute(originalPath)) {
20554
+ if (originalPath.length === 0 || originalPath.includes("\0") || originalPath.includes("\\") || path21.isAbsolute(originalPath) || path21.win32.isAbsolute(originalPath)) {
20868
20555
  return null;
20869
20556
  }
20870
- const memoryRoot = path20.resolve(memoryDir);
20871
- const fullPath = path20.resolve(memoryRoot, originalPath);
20872
- const relative = path20.relative(memoryRoot, fullPath);
20873
- if (relative === "" || relative === ".." || relative.startsWith(`..${path20.sep}`) || path20.isAbsolute(relative)) {
20557
+ const memoryRoot = path21.resolve(memoryDir);
20558
+ const fullPath = path21.resolve(memoryRoot, originalPath);
20559
+ const relative = path21.relative(memoryRoot, fullPath);
20560
+ if (relative === "" || relative === ".." || relative.startsWith(`..${path21.sep}`) || path21.isAbsolute(relative)) {
20874
20561
  return null;
20875
20562
  }
20876
20563
  return fullPath;
@@ -20881,7 +20568,7 @@ function validateBinaryLifecycleConfig(config) {
20881
20568
  }
20882
20569
  }
20883
20570
  function remotePathForAsset(backend, relPath) {
20884
- const normalized = relPath.split(path20.sep).join("/");
20571
+ const normalized = relPath.split(path21.sep).join("/");
20885
20572
  if (backend.type === "filesystem") {
20886
20573
  return `.binary-lifecycle/mirrors/${normalized}`;
20887
20574
  }
@@ -20894,11 +20581,11 @@ async function stageMirror(memoryDir, newPaths, backend, assets, log2, dryRun) {
20894
20581
  let mirrored = 0;
20895
20582
  const errors = [];
20896
20583
  for (const relPath of newPaths) {
20897
- const fullPath = path20.join(memoryDir, relPath);
20584
+ const fullPath = path21.join(memoryDir, relPath);
20898
20585
  try {
20899
20586
  const stat5 = await fsp4.stat(fullPath);
20900
20587
  const contentHash = await hashFile2(fullPath);
20901
- const ext = path20.extname(relPath);
20588
+ const ext = path21.extname(relPath);
20902
20589
  const mimeType = guessMimeType(ext);
20903
20590
  const remotePath = remotePathForAsset(backend, relPath);
20904
20591
  let backendLocation = remotePath;
@@ -21101,10 +20788,10 @@ async function countRemainingLocalReferences(memoryDir, asset, assetAbsolute, md
21101
20788
  return { remaining, errors };
21102
20789
  }
21103
20790
  function markdownReferencePattern(asset, assetAbsolute, mdPath) {
21104
- const mdDir = path20.dirname(mdPath);
20791
+ const mdDir = path21.dirname(mdPath);
21105
20792
  const candidates = /* @__PURE__ */ new Set();
21106
20793
  const addCandidate = (candidate) => {
21107
- const normalized = candidate.split(path20.sep).join("/");
20794
+ const normalized = candidate.split(path21.sep).join("/");
21108
20795
  if (normalized.length === 0) return;
21109
20796
  candidates.add(normalized);
21110
20797
  const isParentTraversal = normalized === ".." || normalized.startsWith("../");
@@ -21112,10 +20799,10 @@ function markdownReferencePattern(asset, assetAbsolute, mdPath) {
21112
20799
  candidates.add(`./${normalized}`);
21113
20800
  }
21114
20801
  };
21115
- addCandidate(path20.relative(mdDir, assetAbsolute));
21116
- const originalPath = asset.originalPath.split(path20.sep).join("/");
21117
- const originalAsFileRelative = path20.resolve(mdDir, ...originalPath.split("/"));
21118
- if (path20.resolve(originalAsFileRelative) === path20.resolve(assetAbsolute)) {
20802
+ addCandidate(path21.relative(mdDir, assetAbsolute));
20803
+ const originalPath = asset.originalPath.split(path21.sep).join("/");
20804
+ const originalAsFileRelative = path21.resolve(mdDir, ...originalPath.split("/"));
20805
+ if (path21.resolve(originalAsFileRelative) === path21.resolve(assetAbsolute)) {
21119
20806
  addCandidate(originalPath);
21120
20807
  }
21121
20808
  addCandidate(`/${originalPath}`);
@@ -21211,7 +20898,7 @@ async function findMarkdownFiles(dir) {
21211
20898
  return;
21212
20899
  }
21213
20900
  for (const entry of entries) {
21214
- const full = path20.join(current, entry.name);
20901
+ const full = path21.join(current, entry.name);
21215
20902
  if (entry.isDirectory()) {
21216
20903
  if (entry.name === ".binary-lifecycle") continue;
21217
20904
  await walk(full);
@@ -21286,7 +20973,7 @@ async function runBinaryLifecyclePipeline(memoryDir, config, backend, log2, opts
21286
20973
 
21287
20974
  // src/projection/index.ts
21288
20975
  import fs from "fs";
21289
- import path21 from "path";
20976
+ import path22 from "path";
21290
20977
  var VALID_PROJECTION_CATEGORIES = new Set(ALL_CATEGORY_KEYS);
21291
20978
  async function generateContextTree(options) {
21292
20979
  const startTime = Date.now();
@@ -21301,8 +20988,8 @@ async function generateContextTree(options) {
21301
20988
  let nodesGenerated = 0;
21302
20989
  let nodesSkipped = 0;
21303
20990
  const categoryCounts = {};
21304
- const resolvedMemoryDir = path21.resolve(memoryDir);
21305
- const resolvedOutputDir = path21.resolve(outputDir);
20991
+ const resolvedMemoryDir = path22.resolve(memoryDir);
20992
+ const resolvedOutputDir = path22.resolve(outputDir);
21306
20993
  const requestedCategories = validateProjectionCategories(filterCategories);
21307
20994
  const realMemoryDir = assertSafeMemoryRoot(resolvedMemoryDir);
21308
20995
  assertNotSymlink(resolvedOutputDir, "context tree outputDir");
@@ -21340,7 +21027,7 @@ async function generateContextTree(options) {
21340
21027
  }
21341
21028
  }
21342
21029
  if (includeEntities) {
21343
- const entitiesDir = path21.join(memoryDir, "entities");
21030
+ const entitiesDir = path22.join(memoryDir, "entities");
21344
21031
  if (fs.existsSync(entitiesDir)) {
21345
21032
  assertSafeInputRoot(realMemoryDir, entitiesDir, "entities root");
21346
21033
  categoryCounts["entity"] = 0;
@@ -21352,7 +21039,7 @@ async function generateContextTree(options) {
21352
21039
  continue;
21353
21040
  }
21354
21041
  const content = fs.readFileSync(filePath, "utf8");
21355
- const fileName = path21.basename(filePath, ".md");
21042
+ const fileName = path22.basename(filePath, ".md");
21356
21043
  const node = projectEntityNode(fileName, content);
21357
21044
  const outputPath = resolveContainedOutputPath(realOutputDir, "entities", `${fileName}.md`);
21358
21045
  writeProjectedContent(realOutputDir, outputPath, node.content);
@@ -21364,7 +21051,7 @@ async function generateContextTree(options) {
21364
21051
  }
21365
21052
  const shouldIncludeQuestions = includeQuestions && (requestedCategories === void 0 || requestedCategories.includes("question"));
21366
21053
  if (shouldIncludeQuestions) {
21367
- const questionsDir = path21.join(memoryDir, "questions");
21054
+ const questionsDir = path22.join(memoryDir, "questions");
21368
21055
  if (fs.existsSync(questionsDir)) {
21369
21056
  assertSafeInputRoot(realMemoryDir, questionsDir, "questions root");
21370
21057
  categoryCounts["question"] = 0;
@@ -21405,8 +21092,8 @@ async function generateContextTree(options) {
21405
21092
  };
21406
21093
  }
21407
21094
  function isPathInside(root, candidate) {
21408
- const relative = path21.relative(root, candidate);
21409
- return relative === "" || !relative.startsWith("..") && !path21.isAbsolute(relative);
21095
+ const relative = path22.relative(root, candidate);
21096
+ return relative === "" || !relative.startsWith("..") && !path22.isAbsolute(relative);
21410
21097
  }
21411
21098
  function assertNotSymlink(targetPath, label) {
21412
21099
  try {
@@ -21443,12 +21130,12 @@ function assertSafeInputRoot(realMemoryDir, targetPath, label) {
21443
21130
  }
21444
21131
  function assertSafeOutputTarget(realOutputDir, outputPath) {
21445
21132
  let current = realOutputDir;
21446
- const relative = path21.relative(realOutputDir, outputPath);
21447
- if (relative.startsWith("..") || path21.isAbsolute(relative)) {
21133
+ const relative = path22.relative(realOutputDir, outputPath);
21134
+ if (relative.startsWith("..") || path22.isAbsolute(relative)) {
21448
21135
  throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
21449
21136
  }
21450
- for (const segment of relative.split(path21.sep).filter(Boolean)) {
21451
- current = path21.join(current, segment);
21137
+ for (const segment of relative.split(path22.sep).filter(Boolean)) {
21138
+ current = path22.join(current, segment);
21452
21139
  try {
21453
21140
  const stat5 = fs.lstatSync(current);
21454
21141
  if (stat5.isSymbolicLink()) {
@@ -21478,17 +21165,17 @@ function validateProjectionCategories(categories) {
21478
21165
  return validated;
21479
21166
  }
21480
21167
  function resolveContainedOutputPath(outputRoot, ...segments) {
21481
- const resolved = path21.resolve(outputRoot, ...segments);
21482
- const relative = path21.relative(outputRoot, resolved);
21483
- if (relative === "" || !relative.startsWith("..") && !path21.isAbsolute(relative)) {
21168
+ const resolved = path22.resolve(outputRoot, ...segments);
21169
+ const relative = path22.relative(outputRoot, resolved);
21170
+ if (relative === "" || !relative.startsWith("..") && !path22.isAbsolute(relative)) {
21484
21171
  return resolved;
21485
21172
  }
21486
21173
  throw new Error(`context tree output path escapes outputDir: ${segments.join("/")}`);
21487
21174
  }
21488
21175
  function writeProjectedContent(realOutputDir, outputPath, generatedContent) {
21489
21176
  assertSafeOutputTarget(realOutputDir, outputPath);
21490
- fs.mkdirSync(path21.dirname(outputPath), { recursive: true });
21491
- const realParent = fs.realpathSync(path21.dirname(outputPath));
21177
+ fs.mkdirSync(path22.dirname(outputPath), { recursive: true });
21178
+ const realParent = fs.realpathSync(path22.dirname(outputPath));
21492
21179
  if (!isPathInside(realOutputDir, realParent)) {
21493
21180
  throw new Error(`context tree output path escapes outputDir: ${outputPath}`);
21494
21181
  }
@@ -21527,7 +21214,7 @@ function walkR(dir, realMemoryDir) {
21527
21214
  const results = [];
21528
21215
  function walk(directory) {
21529
21216
  for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
21530
- const fullPath = path21.join(directory, entry.name);
21217
+ const fullPath = path22.join(directory, entry.name);
21531
21218
  if (entry.isSymbolicLink()) {
21532
21219
  throw new Error(`context tree input path contains symlink: ${fullPath}`);
21533
21220
  }
@@ -21580,13 +21267,13 @@ function extractBody(content) {
21580
21267
  }
21581
21268
  function projectNode(filePath, category, fm, rawContent) {
21582
21269
  const body = extractBody(rawContent);
21583
- const fileName = path21.basename(filePath, ".md");
21584
- const dateDir = path21.basename(path21.dirname(filePath));
21270
+ const fileName = path22.basename(filePath, ".md");
21271
+ const dateDir = path22.basename(path22.dirname(filePath));
21585
21272
  let relPath;
21586
21273
  if (/^\d{4}-\d{2}-\d{2}$/.test(dateDir)) {
21587
- relPath = path21.join(category, dateDir, `${fileName}.md`);
21274
+ relPath = path22.join(category, dateDir, `${fileName}.md`);
21588
21275
  } else {
21589
- relPath = path21.join(category, `${fileName}.md`);
21276
+ relPath = path22.join(category, `${fileName}.md`);
21590
21277
  }
21591
21278
  const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
21592
21279
  const md = `# ${fm.id}
@@ -21632,7 +21319,7 @@ function projectEntityNode(fileName, content) {
21632
21319
  ${content}
21633
21320
  `;
21634
21321
  return {
21635
- path: path21.join("entities", `${fileName}.md`),
21322
+ path: path22.join("entities", `${fileName}.md`),
21636
21323
  category: "entity",
21637
21324
  title: fileName,
21638
21325
  content: md,
@@ -21685,7 +21372,7 @@ function generateIndex(categoryCounts, outputDir) {
21685
21372
 
21686
21373
  // src/onboarding/index.ts
21687
21374
  import fs2 from "fs";
21688
- import path22 from "path";
21375
+ import path23 from "path";
21689
21376
  var LANGUAGE_RULES = [
21690
21377
  {
21691
21378
  language: "TypeScript",
@@ -21787,7 +21474,7 @@ function onboard(options) {
21787
21474
  maxDepth = 6,
21788
21475
  excludeDirs = []
21789
21476
  } = options;
21790
- const directory = path22.resolve(options.directory ?? process.cwd());
21477
+ const directory = path23.resolve(options.directory ?? process.cwd());
21791
21478
  let rootStat;
21792
21479
  try {
21793
21480
  rootStat = fs2.statSync(directory);
@@ -21829,7 +21516,7 @@ function walkDir(root, exclude, maxDepth) {
21829
21516
  }
21830
21517
  for (const entry of entries) {
21831
21518
  if (exclude.has(entry.name)) continue;
21832
- const fullPath = path22.join(dir, entry.name);
21519
+ const fullPath = path23.join(dir, entry.name);
21833
21520
  if (entry.isDirectory()) {
21834
21521
  walk(fullPath, depth + 1);
21835
21522
  } else if (entry.isFile()) {
@@ -21844,11 +21531,11 @@ function detectLanguages(files, root) {
21844
21531
  const results = [];
21845
21532
  const extCounts = /* @__PURE__ */ new Map();
21846
21533
  for (const f of files) {
21847
- const ext = path22.extname(f).toLowerCase();
21534
+ const ext = path23.extname(f).toLowerCase();
21848
21535
  if (ext) extCounts.set(ext, (extCounts.get(ext) ?? 0) + 1);
21849
21536
  }
21850
21537
  const rootFiles = new Set(
21851
- files.filter((f) => path22.dirname(f) === root).map((f) => path22.basename(f))
21538
+ files.filter((f) => path23.dirname(f) === root).map((f) => path23.basename(f))
21852
21539
  );
21853
21540
  for (const rule of LANGUAGE_RULES) {
21854
21541
  const evidence = [];
@@ -21892,7 +21579,7 @@ function detectLanguages(files, root) {
21892
21579
  }
21893
21580
  function detectShape(files, root) {
21894
21581
  const rootFiles = new Set(
21895
- files.filter((f) => path22.dirname(f) === root).map((f) => path22.basename(f))
21582
+ files.filter((f) => path23.dirname(f) === root).map((f) => path23.basename(f))
21896
21583
  );
21897
21584
  const rootDirs = /* @__PURE__ */ new Set();
21898
21585
  try {
@@ -21903,7 +21590,7 @@ function detectShape(files, root) {
21903
21590
  }
21904
21591
  const evidence = [];
21905
21592
  if (rootFiles.has("package.json")) {
21906
- const pkg = readJsonSafe(path22.join(root, "package.json"));
21593
+ const pkg = readJsonSafe(path23.join(root, "package.json"));
21907
21594
  if (pkg?.workspaces) {
21908
21595
  evidence.push("package.json has workspaces");
21909
21596
  return { shape: "monorepo", evidence };
@@ -21917,13 +21604,13 @@ function detectShape(files, root) {
21917
21604
  evidence.push("workspace manifest found");
21918
21605
  return { shape: "workspace", evidence };
21919
21606
  }
21920
- const cargoToml = readTomlWorkspace(path22.join(root, "Cargo.toml"));
21607
+ const cargoToml = readTomlWorkspace(path23.join(root, "Cargo.toml"));
21921
21608
  if (cargoToml) {
21922
21609
  evidence.push("Cargo.toml has workspace");
21923
21610
  return { shape: "workspace", evidence };
21924
21611
  }
21925
21612
  if (rootFiles.has("package.json")) {
21926
- const pkg = readJsonSafe(path22.join(root, "package.json"));
21613
+ const pkg = readJsonSafe(path23.join(root, "package.json"));
21927
21614
  if (pkg?.exports || pkg?.main) {
21928
21615
  if (pkg?.bin) {
21929
21616
  evidence.push("package.json has bin");
@@ -21957,8 +21644,8 @@ function discoverDocs(files, root) {
21957
21644
  { pattern: /^\.editorconfig$/i, kind: "config" }
21958
21645
  ];
21959
21646
  for (const filePath of files) {
21960
- const basename = path22.basename(filePath).toLowerCase();
21961
- const relPath = path22.relative(root, filePath);
21647
+ const basename = path23.basename(filePath).toLowerCase();
21648
+ const relPath = path23.relative(root, filePath);
21962
21649
  let kind;
21963
21650
  for (const { pattern, kind: k } of docPatterns) {
21964
21651
  if (pattern.test(basename)) {
@@ -21970,7 +21657,7 @@ function discoverDocs(files, root) {
21970
21657
  kind = "docs";
21971
21658
  }
21972
21659
  if (!kind && (basename.endsWith(".md") || basename.endsWith(".mdx"))) {
21973
- if (path22.dirname(relPath) === "." || isUnderDocsDir(relPath)) {
21660
+ if (path23.dirname(relPath) === "." || isUnderDocsDir(relPath)) {
21974
21661
  kind = "docs";
21975
21662
  }
21976
21663
  }
@@ -21991,7 +21678,7 @@ function discoverDocs(files, root) {
21991
21678
  return docs;
21992
21679
  }
21993
21680
  function isUnderDocsDir(relPath) {
21994
- const parts = relPath.split(path22.sep);
21681
+ const parts = relPath.split(path23.sep);
21995
21682
  return parts[0] === "docs" || parts[0] === "doc" || parts[0] === "documentation";
21996
21683
  }
21997
21684
  function buildPlan(languages, shape, docs, _root) {
@@ -22035,7 +21722,7 @@ function readTomlWorkspace(filePath) {
22035
21722
 
22036
21723
  // src/curation/index.ts
22037
21724
  import fs3 from "fs";
22038
- import path23 from "path";
21725
+ import path24 from "path";
22039
21726
  import crypto4 from "crypto";
22040
21727
  async function curate(options) {
22041
21728
  const startTime = Date.now();
@@ -22126,12 +21813,12 @@ function resolveTargets(targetPath) {
22126
21813
  const extensions = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
22127
21814
  function walk(dir) {
22128
21815
  for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
22129
- const fullPath = path23.join(dir, entry.name);
21816
+ const fullPath = path24.join(dir, entry.name);
22130
21817
  if (entry.isDirectory()) {
22131
21818
  if (entry.name !== "node_modules" && entry.name !== ".git") {
22132
21819
  walk(fullPath);
22133
21820
  }
22134
- } else if (extensions.has(path23.extname(entry.name).toLowerCase())) {
21821
+ } else if (extensions.has(path24.extname(entry.name).toLowerCase())) {
22135
21822
  results.push(fullPath);
22136
21823
  }
22137
21824
  }
@@ -22140,12 +21827,12 @@ function resolveTargets(targetPath) {
22140
21827
  return results;
22141
21828
  }
22142
21829
  function resolveProvenanceRoot(targetPath) {
22143
- const resolvedTarget = path23.resolve(targetPath);
21830
+ const resolvedTarget = path24.resolve(targetPath);
22144
21831
  const stat5 = fs3.statSync(resolvedTarget);
22145
- return stat5.isFile() ? path23.dirname(resolvedTarget) : resolvedTarget;
21832
+ return stat5.isFile() ? path24.dirname(resolvedTarget) : resolvedTarget;
22146
21833
  }
22147
21834
  function extractStatements(content, filePath, projectRoot, source, sourceFileHash, categoryOverride, confidence, entityRef, tags) {
22148
- const relativePath = path23.relative(projectRoot, path23.resolve(filePath)) || path23.basename(filePath);
21835
+ const relativePath = path24.relative(projectRoot, path24.resolve(filePath)) || path24.basename(filePath);
22149
21836
  const statements = [];
22150
21837
  const now = (/* @__PURE__ */ new Date()).toISOString();
22151
21838
  const paragraphs = content.split(/\n{2,}/).map((p) => p.trim()).filter((p) => p.length > 20 && p.length < 2e3);
@@ -22239,7 +21926,7 @@ function loadExistingMemories(memoryDir) {
22239
21926
  if (!fs3.existsSync(memoryDir)) return result;
22240
21927
  const dirs = ALL_CATEGORY_DIRS;
22241
21928
  for (const dir of dirs) {
22242
- const fullDir = path23.join(memoryDir, dir);
21929
+ const fullDir = path24.join(memoryDir, dir);
22243
21930
  if (!fs3.existsSync(fullDir)) continue;
22244
21931
  walkFiles(fullDir, (filePath) => {
22245
21932
  const content = readFileSafe(filePath);
@@ -22261,10 +21948,10 @@ function writeStatement(stmt, memoryDir) {
22261
21948
  const now = /* @__PURE__ */ new Date();
22262
21949
  const dateDir = now.toISOString().split("T")[0];
22263
21950
  const categoryDir = getCategoryDir(memoryDir, stmt.category);
22264
- const dir = path23.join(categoryDir, dateDir);
21951
+ const dir = path24.join(categoryDir, dateDir);
22265
21952
  fs3.mkdirSync(dir, { recursive: true });
22266
21953
  const fileName = `${stmt.category}-${Date.now()}-${stmt.id.slice(0, 8)}.md`;
22267
- const filePath = path23.join(dir, fileName);
21954
+ const filePath = path24.join(dir, fileName);
22268
21955
  const frontmatter = [
22269
21956
  "---",
22270
21957
  `id: ${stmt.id}`,
@@ -22332,7 +22019,7 @@ function extractBody2(content) {
22332
22019
  }
22333
22020
  function walkFiles(dir, callback) {
22334
22021
  for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
22335
- const fullPath = path23.join(dir, entry.name);
22022
+ const fullPath = path24.join(dir, entry.name);
22336
22023
  if (entry.isDirectory()) {
22337
22024
  walkFiles(fullPath, callback);
22338
22025
  } else if (entry.name.endsWith(".md")) {
@@ -22343,7 +22030,7 @@ function walkFiles(dir, callback) {
22343
22030
 
22344
22031
  // src/dedup/index.ts
22345
22032
  import fs4 from "fs";
22346
- import path24 from "path";
22033
+ import path25 from "path";
22347
22034
  import crypto5 from "crypto";
22348
22035
  var DEFAULT_DEDUP_THRESHOLD = 0.85;
22349
22036
  var DEFAULT_MAX_LOAD = 1e4;
@@ -22485,7 +22172,7 @@ function loadMemories(memoryDir, categories, maxLoad = 1e4) {
22485
22172
  const memoryRootReal = fs4.realpathSync(memoryDir);
22486
22173
  for (const category of allCategories) {
22487
22174
  if (result.length >= maxLoad) break;
22488
- const dir = path24.join(memoryDir, category);
22175
+ const dir = path25.join(memoryDir, category);
22489
22176
  if (!fs4.existsSync(dir)) continue;
22490
22177
  const categoryStat = fs4.lstatSync(dir);
22491
22178
  if (categoryStat.isSymbolicLink()) {
@@ -22546,15 +22233,15 @@ function extractBody3(content) {
22546
22233
  return match ? match[1].trim() : content.trim();
22547
22234
  }
22548
22235
  function assertPathInsideRoot2(rootReal, targetReal, sourcePath) {
22549
- const rel = path24.relative(rootReal, targetReal);
22550
- if (rel === "" || !rel.startsWith("..") && !path24.isAbsolute(rel)) {
22236
+ const rel = path25.relative(rootReal, targetReal);
22237
+ if (rel === "" || !rel.startsWith("..") && !path25.isAbsolute(rel)) {
22551
22238
  return;
22552
22239
  }
22553
22240
  throw new Error(`Refusing to scan memory path outside root: ${sourcePath}`);
22554
22241
  }
22555
22242
  function walkMdFiles(dir, memoryRootReal, categoryRootReal, callback) {
22556
22243
  for (const entry of fs4.readdirSync(dir, { withFileTypes: true })) {
22557
- const fullPath = path24.join(dir, entry.name);
22244
+ const fullPath = path25.join(dir, entry.name);
22558
22245
  const entryStat = fs4.lstatSync(fullPath);
22559
22246
  if (entryStat.isSymbolicLink()) {
22560
22247
  throw new Error(`Refusing to scan symlinked memory path: ${fullPath}`);
@@ -22572,7 +22259,7 @@ function walkMdFiles(dir, memoryRootReal, categoryRootReal, callback) {
22572
22259
 
22573
22260
  // src/review/index.ts
22574
22261
  import fs5 from "fs";
22575
- import path25 from "path";
22262
+ import path26 from "path";
22576
22263
  var DEFAULT_CONFIDENCE_THRESHOLD = 0.7;
22577
22264
  function realMemoryRoot(memoryDir) {
22578
22265
  try {
@@ -22584,8 +22271,8 @@ function realMemoryRoot(memoryDir) {
22584
22271
  }
22585
22272
  }
22586
22273
  function isPathInside2(rootReal, candidateReal) {
22587
- const relative = path25.relative(rootReal, candidateReal);
22588
- return relative === "" || !!relative && !relative.startsWith("..") && !path25.isAbsolute(relative);
22274
+ const relative = path26.relative(rootReal, candidateReal);
22275
+ return relative === "" || !!relative && !relative.startsWith("..") && !path26.isAbsolute(relative);
22589
22276
  }
22590
22277
  function isSafeDirectory(rootReal, dir) {
22591
22278
  try {
@@ -22628,7 +22315,7 @@ function listReviewItems(options) {
22628
22315
  if (filterReason && item.reviewReason !== filterReason) return;
22629
22316
  items.push(item);
22630
22317
  };
22631
- const suggestionsDir = path25.join(memoryDir, "suggestions");
22318
+ const suggestionsDir = path26.join(memoryDir, "suggestions");
22632
22319
  if (!isLimitReached() && fs5.existsSync(suggestionsDir) && isSafeDirectory(rootReal, suggestionsDir)) {
22633
22320
  walkMd(rootReal, suggestionsDir, (filePath, content) => {
22634
22321
  if (isLimitReached()) return true;
@@ -22649,7 +22336,7 @@ function listReviewItems(options) {
22649
22336
  return isLimitReached();
22650
22337
  });
22651
22338
  }
22652
- const reviewDir = path25.join(memoryDir, "review");
22339
+ const reviewDir = path26.join(memoryDir, "review");
22653
22340
  if (!isLimitReached() && fs5.existsSync(reviewDir) && isSafeDirectory(rootReal, reviewDir)) {
22654
22341
  walkMd(rootReal, reviewDir, (filePath, content) => {
22655
22342
  if (isLimitReached()) return true;
@@ -22674,7 +22361,7 @@ function listReviewItems(options) {
22674
22361
  const categories = ALL_CATEGORY_DIRS;
22675
22362
  for (const category of categories) {
22676
22363
  if (isLimitReached()) break;
22677
- const dir = path25.join(memoryDir, category);
22364
+ const dir = path26.join(memoryDir, category);
22678
22365
  if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
22679
22366
  walkMd(rootReal, dir, (filePath, content) => {
22680
22367
  if (isLimitReached()) return true;
@@ -22754,8 +22441,8 @@ function approveItem(memoryDir, itemId, options) {
22754
22441
  const targetDir = getCategoryDir(memoryDir, category);
22755
22442
  const dateDir = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
22756
22443
  ensureSafeDirectory(rootReal, targetDir);
22757
- const outputPath = path25.join(targetDir, dateDir, path25.basename(found.filePath));
22758
- ensureSafeDirectory(rootReal, path25.dirname(outputPath));
22444
+ const outputPath = path26.join(targetDir, dateDir, path26.basename(found.filePath));
22445
+ ensureSafeDirectory(rootReal, path26.dirname(outputPath));
22759
22446
  const promotedPath = writeFileWithoutClobber(outputPath, updatedContent, itemId);
22760
22447
  fs5.unlinkSync(found.filePath);
22761
22448
  return {
@@ -22813,13 +22500,13 @@ function findReviewFileById(memoryDir, id, options = {}) {
22813
22500
  const rootReal = realMemoryRoot(memoryDir);
22814
22501
  if (!rootReal) return null;
22815
22502
  for (const loc of ["suggestions", "review"]) {
22816
- const dir = path25.join(memoryDir, loc);
22503
+ const dir = path26.join(memoryDir, loc);
22817
22504
  if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
22818
22505
  const found = findFileById(rootReal, dir, id);
22819
22506
  if (found) return { filePath: found, location: "queue" };
22820
22507
  }
22821
22508
  for (const category of ALL_CATEGORY_DIRS) {
22822
- const dir = path25.join(memoryDir, category);
22509
+ const dir = path26.join(memoryDir, category);
22823
22510
  if (!fs5.existsSync(dir) || !isSafeDirectory(rootReal, dir)) continue;
22824
22511
  const found = findFileById(rootReal, dir, id, (fm) => isLowConfidenceReviewCandidate(fm, options));
22825
22512
  if (found) return { filePath: found, location: "category" };
@@ -22895,10 +22582,10 @@ function readFileSafe3(filePath) {
22895
22582
  }
22896
22583
  }
22897
22584
  function writeFileWithoutClobber(basePath, content, discriminator) {
22898
- const parsed = path25.parse(basePath);
22585
+ const parsed = path26.parse(basePath);
22899
22586
  const safeDiscriminator = sanitizeFilePart(discriminator);
22900
22587
  for (let attempt = 0; attempt < 1e3; attempt++) {
22901
- const candidate = attempt === 0 ? basePath : path25.join(
22588
+ const candidate = attempt === 0 ? basePath : path26.join(
22902
22589
  parsed.dir,
22903
22590
  `${parsed.name}-${safeDiscriminator}${attempt === 1 ? "" : `-${attempt}`}${parsed.ext || ".md"}`
22904
22591
  );
@@ -22954,7 +22641,7 @@ function extractBody4(content) {
22954
22641
  function walkMd(rootReal, dir, callback) {
22955
22642
  if (!isSafeDirectory(rootReal, dir)) return false;
22956
22643
  for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
22957
- const fullPath = path25.join(dir, entry.name);
22644
+ const fullPath = path26.join(dir, entry.name);
22958
22645
  if (entry.isSymbolicLink()) continue;
22959
22646
  if (entry.isDirectory()) {
22960
22647
  if (walkMd(rootReal, fullPath, callback)) return true;
@@ -22969,7 +22656,7 @@ function walkMdPaths(rootReal, dir) {
22969
22656
  const results = [];
22970
22657
  if (!isSafeDirectory(rootReal, dir)) return results;
22971
22658
  for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
22972
- const fullPath = path25.join(dir, entry.name);
22659
+ const fullPath = path26.join(dir, entry.name);
22973
22660
  if (entry.isSymbolicLink()) continue;
22974
22661
  if (entry.isDirectory()) {
22975
22662
  results.push(...walkMdPaths(rootReal, fullPath));
@@ -22982,7 +22669,7 @@ function walkMdPaths(rootReal, dir) {
22982
22669
 
22983
22670
  // src/sync/index.ts
22984
22671
  import fs6 from "fs";
22985
- import path26 from "path";
22672
+ import path27 from "path";
22986
22673
  import crypto6 from "crypto";
22987
22674
  var DEFAULT_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt", ".mdx", ".rst"]);
22988
22675
  var DEFAULT_EXCLUDE2 = /* @__PURE__ */ new Set([
@@ -23004,7 +22691,7 @@ function syncChanges(options) {
23004
22691
  } = options;
23005
22692
  const extSet = new Set(extensions);
23006
22693
  const excludeSet = /* @__PURE__ */ new Set([...DEFAULT_EXCLUDE2, ...excludeDirs]);
23007
- const stateFilePath = options.stateFile ?? path26.join(memoryDir, ".sync-state.json");
22694
+ const stateFilePath = options.stateFile ?? path27.join(memoryDir, ".sync-state.json");
23008
22695
  const prevState = loadState(stateFilePath);
23009
22696
  const currentFiles = scanFiles(sourceDir, extSet, excludeSet);
23010
22697
  const changes = computeDiff(currentFiles, prevState.fileHashes, sourceDir);
@@ -23020,7 +22707,7 @@ function syncChanges(options) {
23020
22707
  for (const [relPath, hash] of Object.entries(currentFiles)) {
23021
22708
  newState.fileHashes[relPath] = hash;
23022
22709
  }
23023
- fs6.mkdirSync(path26.dirname(stateFilePath), { recursive: true });
22710
+ fs6.mkdirSync(path27.dirname(stateFilePath), { recursive: true });
23024
22711
  fs6.writeFileSync(stateFilePath, JSON.stringify(newState, null, 2));
23025
22712
  }
23026
22713
  return {
@@ -23086,13 +22773,13 @@ function scanFiles(root, extensions, exclude) {
23086
22773
  }
23087
22774
  for (const entry of entries) {
23088
22775
  if (exclude.has(entry.name)) continue;
23089
- const fullPath = path26.join(dir, entry.name);
22776
+ const fullPath = path27.join(dir, entry.name);
23090
22777
  if (entry.isDirectory()) {
23091
22778
  walk(fullPath);
23092
22779
  } else if (entry.isFile()) {
23093
- const ext = path26.extname(entry.name).toLowerCase();
22780
+ const ext = path27.extname(entry.name).toLowerCase();
23094
22781
  if (!extensions.has(ext)) continue;
23095
- const relPath = path26.relative(root, fullPath);
22782
+ const relPath = path27.relative(root, fullPath);
23096
22783
  try {
23097
22784
  const content = fs6.readFileSync(fullPath, "utf8");
23098
22785
  result[relPath] = hashContent3(content);
@@ -23107,7 +22794,7 @@ function scanFiles(root, extensions, exclude) {
23107
22794
  function computeDiff(current, previous, sourceDir) {
23108
22795
  const changes = [];
23109
22796
  for (const [relPath, hash] of Object.entries(current)) {
23110
- const fullPath = path26.join(sourceDir, relPath);
22797
+ const fullPath = path27.join(sourceDir, relPath);
23111
22798
  if (!(relPath in previous)) {
23112
22799
  let size = 0;
23113
22800
  try {
@@ -23140,7 +22827,7 @@ function computeDiff(current, previous, sourceDir) {
23140
22827
  for (const relPath of Object.keys(previous)) {
23141
22828
  if (!(relPath in current)) {
23142
22829
  changes.push({
23143
- filePath: path26.join(sourceDir, relPath),
22830
+ filePath: path27.join(sourceDir, relPath),
23144
22831
  relativePath: relPath,
23145
22832
  type: "deleted",
23146
22833
  currentHash: "",
@@ -23170,20 +22857,20 @@ function hashContent3(content) {
23170
22857
  import { spawnSync } from "child_process";
23171
22858
  import crypto7 from "crypto";
23172
22859
  import fs7 from "fs";
23173
- import path27 from "path";
22860
+ import path28 from "path";
23174
22861
  var MANIFEST_VERSION = 1;
23175
22862
  var MANIFEST_LOCK_STALE_MS = 3e4;
23176
22863
  var MANIFEST_LOCK_TIMEOUT_MS = MANIFEST_LOCK_STALE_MS + 1e4;
23177
22864
  var MANIFEST_LOCK_SLEEP_MS = 20;
23178
22865
  function normalizeSpaceMemoryDir(memoryDir) {
23179
- return path27.resolve(memoryDir);
22866
+ return path28.resolve(memoryDir);
23180
22867
  }
23181
22868
  function getSpacesDir(baseDir) {
23182
22869
  const homeDir = baseDir ?? resolveHomeDir();
23183
- return path27.join(homeDir, ".config", "engram", "spaces");
22870
+ return path28.join(homeDir, ".config", "engram", "spaces");
23184
22871
  }
23185
22872
  function getManifestPath(baseDir) {
23186
- return path27.join(getSpacesDir(baseDir), "manifest.json");
22873
+ return path28.join(getSpacesDir(baseDir), "manifest.json");
23187
22874
  }
23188
22875
  function loadManifest(baseDir, memoryDirOverride) {
23189
22876
  if (fs7.existsSync(getManifestPath(baseDir))) {
@@ -23230,9 +22917,9 @@ function readManifestUnlocked(baseDir, memoryDirOverride, options = {}) {
23230
22917
  }
23231
22918
  function saveManifestUnlocked(manifest, baseDir) {
23232
22919
  const manifestPath2 = getManifestPath(baseDir);
23233
- const manifestDir2 = path27.dirname(manifestPath2);
22920
+ const manifestDir2 = path28.dirname(manifestPath2);
23234
22921
  fs7.mkdirSync(manifestDir2, { recursive: true });
23235
- const tempPath = path27.join(manifestDir2, `.manifest.${process.pid}.${Date.now()}.${crypto7.randomUUID()}.tmp`);
22922
+ const tempPath = path28.join(manifestDir2, `.manifest.${process.pid}.${Date.now()}.${crypto7.randomUUID()}.tmp`);
23236
22923
  try {
23237
22924
  fs7.writeFileSync(tempPath, `${JSON.stringify(manifest, null, 2)}
23238
22925
  `, { flag: "wx" });
@@ -23247,7 +22934,7 @@ function saveManifestUnlocked(manifest, baseDir) {
23247
22934
  }
23248
22935
  function withManifestLock(baseDir, operation) {
23249
22936
  const lockDir = `${getManifestPath(baseDir)}.lock`;
23250
- fs7.mkdirSync(path27.dirname(lockDir), { recursive: true });
22937
+ fs7.mkdirSync(path28.dirname(lockDir), { recursive: true });
23251
22938
  const lockOwner = acquireManifestLock(lockDir);
23252
22939
  try {
23253
22940
  return operation();
@@ -23273,7 +22960,7 @@ function acquireManifestLock(lockDir) {
23273
22960
  try {
23274
22961
  fs7.mkdirSync(lockDir, { recursive: false });
23275
22962
  try {
23276
- fs7.writeFileSync(path27.join(lockDir, "owner"), `${owner}
22963
+ fs7.writeFileSync(path28.join(lockDir, "owner"), `${owner}
23277
22964
  `, { flag: "wx" });
23278
22965
  } catch (error) {
23279
22966
  fs7.rmSync(lockDir, { recursive: true, force: true });
@@ -23303,7 +22990,7 @@ function acquireManifestLock(lockDir) {
23303
22990
  }
23304
22991
  function releaseManifestLock(lockDir, owner) {
23305
22992
  try {
23306
- const ownerPath = path27.join(lockDir, "owner");
22993
+ const ownerPath = path28.join(lockDir, "owner");
23307
22994
  if (fs7.readFileSync(ownerPath, "utf8").trim() === owner) {
23308
22995
  fs7.rmSync(lockDir, { recursive: true, force: true });
23309
22996
  }
@@ -23319,7 +23006,7 @@ function removeStaleManifestLock(lockDir) {
23319
23006
  try {
23320
23007
  fs7.mkdirSync(reclaimDir, { recursive: false });
23321
23008
  try {
23322
- fs7.writeFileSync(path27.join(reclaimDir, "owner"), `${reclaimOwner}
23009
+ fs7.writeFileSync(path28.join(reclaimDir, "owner"), `${reclaimOwner}
23323
23010
  `, { flag: "wx" });
23324
23011
  } catch (error) {
23325
23012
  fs7.rmSync(reclaimDir, { recursive: true, force: true });
@@ -23394,7 +23081,7 @@ function readManifestLockSnapshot(lockDir) {
23394
23081
  throw error;
23395
23082
  }
23396
23083
  try {
23397
- const owner = fs7.readFileSync(path27.join(lockDir, "owner"), "utf8").trim();
23084
+ const owner = fs7.readFileSync(path28.join(lockDir, "owner"), "utf8").trim();
23398
23085
  return { mtimeMs: stat5.mtimeMs, owner };
23399
23086
  } catch (error) {
23400
23087
  if (error.code === "ENOENT") {
@@ -23466,8 +23153,8 @@ function sleepSync(ms) {
23466
23153
  }
23467
23154
  function createPersonalSpace(baseDir, memoryDirOverride) {
23468
23155
  const homeDir = baseDir ?? resolveHomeDir();
23469
- const standalonePath = path27.join(homeDir, ".engram", "memory");
23470
- const openclawPath = path27.join(homeDir, ".openclaw", "workspace", "memory", "local");
23156
+ const standalonePath = path28.join(homeDir, ".engram", "memory");
23157
+ const openclawPath = path28.join(homeDir, ".openclaw", "workspace", "memory", "local");
23471
23158
  const memoryDir = memoryDirOverride ?? readEnvVar("REMNIC_MEMORY_DIR") ?? readEnvVar("ENGRAM_MEMORY_DIR") ?? (fs7.existsSync(standalonePath) ? standalonePath : fs7.existsSync(openclawPath) ? openclawPath : standalonePath);
23472
23159
  const normalizedMemoryDir = normalizeSpaceMemoryDir(memoryDir);
23473
23160
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -23496,7 +23183,7 @@ function createSpace(options) {
23496
23183
  const id = options.name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-");
23497
23184
  const now = (/* @__PURE__ */ new Date()).toISOString();
23498
23185
  const memoryDir = normalizeSpaceMemoryDir(
23499
- options.memoryDir ?? path27.join(getSpacesDir(options.baseDir), id, "memory")
23186
+ options.memoryDir ?? path28.join(getSpacesDir(options.baseDir), id, "memory")
23500
23187
  );
23501
23188
  const space = updateManifest(options.baseDir, (manifest) => {
23502
23189
  if (manifest.spaces.some((s) => s.id === id)) {
@@ -23717,14 +23404,14 @@ function mergeSpaces(sourceSpaceId, targetSpaceId, options) {
23717
23404
  };
23718
23405
  }
23719
23406
  function getAuditLog(baseDir) {
23720
- const auditPath = path27.join(getSpacesDir(baseDir), "audit.jsonl");
23407
+ const auditPath = path28.join(getSpacesDir(baseDir), "audit.jsonl");
23721
23408
  if (!fs7.existsSync(auditPath)) return [];
23722
23409
  const lines = fs7.readFileSync(auditPath, "utf8").trim().split("\n");
23723
23410
  return lines.filter((l) => l.trim()).map((l) => JSON.parse(l));
23724
23411
  }
23725
23412
  function appendAudit(entry, baseDir) {
23726
- const auditPath = path27.join(getSpacesDir(baseDir), "audit.jsonl");
23727
- fs7.mkdirSync(path27.dirname(auditPath), { recursive: true });
23413
+ const auditPath = path28.join(getSpacesDir(baseDir), "audit.jsonl");
23414
+ fs7.mkdirSync(path28.dirname(auditPath), { recursive: true });
23728
23415
  const full = {
23729
23416
  id: crypto7.randomUUID(),
23730
23417
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -23756,8 +23443,8 @@ function copyMemories(sourceDir, targetDir, options) {
23756
23443
  continue;
23757
23444
  }
23758
23445
  const content = fs7.readFileSync(sourcePath, "utf8");
23759
- const relativePath = path27.relative(sourceRoot, sourceRealPath);
23760
- const targetPath = path27.resolve(targetRoot, relativePath);
23446
+ const relativePath = path28.relative(sourceRoot, sourceRealPath);
23447
+ const targetPath = path28.resolve(targetRoot, relativePath);
23761
23448
  if (!isPathInsideRoot(targetPath, targetRoot)) {
23762
23449
  skipped++;
23763
23450
  continue;
@@ -23799,8 +23486,8 @@ function copyMemories(sourceDir, targetDir, options) {
23799
23486
  skipped++;
23800
23487
  continue;
23801
23488
  }
23802
- fs7.mkdirSync(path27.dirname(targetPath), { recursive: true });
23803
- const targetParentRealPath = safeRealpath(path27.dirname(targetPath));
23489
+ fs7.mkdirSync(path28.dirname(targetPath), { recursive: true });
23490
+ const targetParentRealPath = safeRealpath(path28.dirname(targetPath));
23804
23491
  if (!targetParentRealPath || !isPathInsideRoot(targetParentRealPath, targetRoot)) {
23805
23492
  skipped++;
23806
23493
  continue;
@@ -23818,7 +23505,7 @@ function walkMd2(dir) {
23818
23505
  const results = [];
23819
23506
  function walk(d) {
23820
23507
  for (const entry of fs7.readdirSync(d, { withFileTypes: true })) {
23821
- const fullPath = path27.join(d, entry.name);
23508
+ const fullPath = path28.join(d, entry.name);
23822
23509
  if (entry.isSymbolicLink()) {
23823
23510
  continue;
23824
23511
  }
@@ -23847,8 +23534,8 @@ function safeRealpath(filePath) {
23847
23534
  }
23848
23535
  }
23849
23536
  function isPathInsideRoot(candidatePath, rootPath) {
23850
- const relative = path27.relative(rootPath, candidatePath);
23851
- return relative === "" || !relative.startsWith("..") && !path27.isAbsolute(relative);
23537
+ const relative = path28.relative(rootPath, candidatePath);
23538
+ return relative === "" || !relative.startsWith("..") && !path28.isAbsolute(relative);
23852
23539
  }
23853
23540
  function parseSimpleFrontmatter(content) {
23854
23541
  const match = content.match(/^---\n([\s\S]*?)\n---/);
@@ -23968,22 +23655,22 @@ var REMNIC_RECALL_DECISION_RULES = `## When to Use Recall vs Direct Read
23968
23655
 
23969
23656
  // src/memory-extension/codex-publisher.ts
23970
23657
  import fs8 from "fs";
23971
- import os3 from "os";
23972
- import path28 from "path";
23658
+ import os2 from "os";
23659
+ import path29 from "path";
23973
23660
  var REMNIC_EXTENSION_DIR_NAME = "remnic";
23974
23661
  function resolveEnvHome(env) {
23975
23662
  if (env === void 0) return resolveHomeDir();
23976
- return env.HOME?.trim() || env.USERPROFILE?.trim() || os3.homedir();
23663
+ return env.HOME?.trim() || env.USERPROFILE?.trim() || os2.homedir();
23977
23664
  }
23978
23665
  function expandTildeWithHome(input, homeDir) {
23979
23666
  if (input === "~") return homeDir;
23980
23667
  if (input.startsWith("~/") || input.startsWith("~\\")) {
23981
- return path28.join(homeDir, input.slice(2));
23668
+ return path29.join(homeDir, input.slice(2));
23982
23669
  }
23983
23670
  return input;
23984
23671
  }
23985
23672
  function normalizeHostRoot(input, homeDir) {
23986
- return path28.resolve(expandTildeWithHome(input.trim(), homeDir));
23673
+ return path29.resolve(expandTildeWithHome(input.trim(), homeDir));
23987
23674
  }
23988
23675
  var CodexMemoryExtensionPublisher = class {
23989
23676
  hostId = "codex";
@@ -23997,12 +23684,12 @@ var CodexMemoryExtensionPublisher = class {
23997
23684
  async resolveExtensionRoot(env) {
23998
23685
  const homeDir = resolveEnvHome(env);
23999
23686
  const codexHomeInput = env === void 0 ? readEnvVar("CODEX_HOME")?.trim() : env.CODEX_HOME?.trim();
24000
- const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) : path28.resolve(homeDir, ".codex");
24001
- return path28.join(codexHome, "memories_extensions", REMNIC_EXTENSION_DIR_NAME);
23687
+ const codexHome = codexHomeInput ? normalizeHostRoot(codexHomeInput, homeDir) : path29.resolve(homeDir, ".codex");
23688
+ return path29.join(codexHome, "memories_extensions", REMNIC_EXTENSION_DIR_NAME);
24002
23689
  }
24003
23690
  async isHostAvailable() {
24004
23691
  try {
24005
- const home = readEnvVar("CODEX_HOME")?.trim() || path28.join(resolveHomeDir(), ".codex");
23692
+ const home = readEnvVar("CODEX_HOME")?.trim() || path29.join(resolveHomeDir(), ".codex");
24006
23693
  return fs8.existsSync(home);
24007
23694
  } catch {
24008
23695
  return false;
@@ -24053,7 +23740,7 @@ When running inside the Codex phase-2 consolidation sandbox:
24053
23740
  }
24054
23741
  async publish(ctx) {
24055
23742
  const extensionRoot = await this.resolveExtensionRoot();
24056
- const instructionsPath = path28.join(extensionRoot, "instructions.md");
23743
+ const instructionsPath = path29.join(extensionRoot, "instructions.md");
24057
23744
  const filesWritten = [];
24058
23745
  const skipped = [];
24059
23746
  ctx.log.info(`Publishing Codex memory extension to ${extensionRoot}`);
@@ -24429,7 +24116,7 @@ async function generateActivityMemories(date, digestBody, config, deps) {
24429
24116
  // src/session-summaries/index.ts
24430
24117
  import { createHash as createHash9 } from "crypto";
24431
24118
  import { lstat as lstat2, mkdir as mkdir7, readFile as readFile6, readdir as readdir4, rename, rm, stat as stat4, writeFile as writeFile7 } from "fs/promises";
24432
- import path29 from "path";
24119
+ import path30 from "path";
24433
24120
 
24434
24121
  // src/session-summaries/adapters.ts
24435
24122
  var VALID_ROLES = /* @__PURE__ */ new Set(["user", "assistant", "tool", "system", "other"]);
@@ -24934,7 +24621,7 @@ function shortHash(value, length = 16) {
24934
24621
  async function listTranscriptFiles(root, maxFiles) {
24935
24622
  const out = [];
24936
24623
  let truncated = false;
24937
- const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${path29.sep}` : entryName;
24624
+ const entrySortKey = (entryName, isDirectory) => isDirectory ? `${entryName}${path30.sep}` : entryName;
24938
24625
  async function visit(dir) {
24939
24626
  if (truncated) return;
24940
24627
  const entries = (await readdir4(dir, { withFileTypes: true })).sort(
@@ -24944,13 +24631,13 @@ async function listTranscriptFiles(root, maxFiles) {
24944
24631
  if (truncated) return;
24945
24632
  if (entry.name.startsWith(".")) continue;
24946
24633
  if (entry.isSymbolicLink()) continue;
24947
- const fullPath = path29.join(dir, entry.name);
24634
+ const fullPath = path30.join(dir, entry.name);
24948
24635
  if (entry.isDirectory()) {
24949
24636
  await visit(fullPath);
24950
24637
  continue;
24951
24638
  }
24952
24639
  if (!entry.isFile()) continue;
24953
- const ext = path29.extname(entry.name).toLowerCase();
24640
+ const ext = path30.extname(entry.name).toLowerCase();
24954
24641
  if (!SUPPORTED_EXTENSIONS.has(ext)) continue;
24955
24642
  out.push(fullPath);
24956
24643
  if (out.length > maxFiles) {
@@ -24977,7 +24664,7 @@ function normalizeInputDir(inputDir) {
24977
24664
  if (typeof inputDir !== "string" || inputDir.trim().length === 0) {
24978
24665
  throw new Error("inputDir must be a non-empty string");
24979
24666
  }
24980
- return path29.resolve(expandTildePath(inputDir.trim()));
24667
+ return path30.resolve(expandTildePath(inputDir.trim()));
24981
24668
  }
24982
24669
  function initRoleCounts() {
24983
24670
  return {
@@ -25134,11 +24821,11 @@ async function collectLocalSessionSummaries(options) {
25134
24821
  continue;
25135
24822
  }
25136
24823
  seenFileHashes.add(fileHash);
25137
- const fileExtension = path29.extname(filePath).toLowerCase();
24824
+ const fileExtension = path30.extname(filePath).toLowerCase();
25138
24825
  const parsed = await adapter.parseFile(
25139
24826
  {
25140
24827
  content,
25141
- fileName: path29.basename(filePath),
24828
+ fileName: path30.basename(filePath),
25142
24829
  fileExtension,
25143
24830
  fileRef: fileHash
25144
24831
  },
@@ -25194,7 +24881,7 @@ async function collectLocalSessionSummaries(options) {
25194
24881
  }
25195
24882
  async function readRedactionConfig(pathLike) {
25196
24883
  if (!pathLike) return void 0;
25197
- const raw = await readFile6(path29.resolve(expandTildePath(pathLike)), "utf-8");
24884
+ const raw = await readFile6(path30.resolve(expandTildePath(pathLike)), "utf-8");
25198
24885
  const parsed = JSON.parse(raw);
25199
24886
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
25200
24887
  throw new Error("redaction config must be a JSON object");
@@ -25207,15 +24894,15 @@ function toJsonl(drafts) {
25207
24894
  }
25208
24895
  function defaultDraftOutputPath(memoryDir, generatedAt) {
25209
24896
  const stamp = generatedAt.replace(/[:.]/g, "-");
25210
- return path29.join(
25211
- path29.resolve(expandTildePath(memoryDir)),
24897
+ return path30.join(
24898
+ path30.resolve(expandTildePath(memoryDir)),
25212
24899
  "state",
25213
24900
  "session-summary-drafts",
25214
24901
  `session-summaries-${stamp}.jsonl`
25215
24902
  );
25216
24903
  }
25217
24904
  async function writeDrafts(filePath, drafts) {
25218
- await mkdir7(path29.dirname(filePath), { recursive: true });
24905
+ await mkdir7(path30.dirname(filePath), { recursive: true });
25219
24906
  const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
25220
24907
  try {
25221
24908
  await writeFile7(tempPath, toJsonl(drafts), "utf-8");
@@ -25233,7 +24920,7 @@ async function runLocalSessionSummaryCliCommand(options) {
25233
24920
  });
25234
24921
  const wroteFiles = [];
25235
24922
  if (options.output) {
25236
- const outputPath = path29.resolve(expandTildePath(options.output));
24923
+ const outputPath = path30.resolve(expandTildePath(options.output));
25237
24924
  await writeDrafts(outputPath, report.drafts);
25238
24925
  wroteFiles.push(outputPath);
25239
24926
  }
@@ -25268,19 +24955,19 @@ async function runLocalSessionSummaryCliCommand(options) {
25268
24955
 
25269
24956
  // src/transfer/capsule-fork.ts
25270
24957
  import { lstat as lstat3, mkdir as mkdir8, readFile as readFile7, realpath as realpath2, writeFile as writeFile8 } from "fs/promises";
25271
- import path30 from "path";
24958
+ import path31 from "path";
25272
24959
  async function forkCapsule(opts) {
25273
24960
  validateForkId(opts.forkId);
25274
- const rootAbs = path30.resolve(opts.targetRoot);
24961
+ const rootAbs = path31.resolve(opts.targetRoot);
25275
24962
  await assertIsDirectoryNotSymlink(rootAbs, "forkCapsule", "targetRoot");
25276
- const forkDirAbs = path30.join(rootAbs, "forks", opts.forkId);
24963
+ const forkDirAbs = path31.join(rootAbs, "forks", opts.forkId);
25277
24964
  const forkEntryExists = await pathEntryExists(forkDirAbs);
25278
24965
  if (forkEntryExists) {
25279
24966
  throw new Error(
25280
24967
  `forkCapsule: fork path already exists \u2014 forkId "${opts.forkId}" is already in use at: ${forkDirAbs}`
25281
24968
  );
25282
24969
  }
25283
- const archiveAbs = path30.resolve(opts.sourceArchive);
24970
+ const archiveAbs = path31.resolve(opts.sourceArchive);
25284
24971
  const importResult = await importCapsule({
25285
24972
  archivePath: archiveAbs,
25286
24973
  root: rootAbs,
@@ -25302,10 +24989,10 @@ async function forkCapsule(opts) {
25302
24989
  importedRecords: importResult.imported.length,
25303
24990
  skippedRecords: importResult.skipped.length
25304
24991
  };
25305
- const lineagePath = path30.join(forkDirAbs, "lineage.json");
24992
+ const lineagePath = path31.join(forkDirAbs, "lineage.json");
25306
24993
  const rootReal = await realpath2(rootAbs);
25307
24994
  await assertRealpathInsideRoot(rootReal, lineagePath, `forks/${opts.forkId}/lineage.json`, "forkCapsule");
25308
- await mkdir8(path30.dirname(lineagePath), { recursive: true });
24995
+ await mkdir8(path31.dirname(lineagePath), { recursive: true });
25309
24996
  await writeFile8(lineagePath, JSON.stringify(lineage, null, 2) + "\n", "utf-8");
25310
24997
  return {
25311
24998
  archivePath: archiveAbs,
@@ -25319,11 +25006,11 @@ async function readForkLineage(targetRoot, forkId) {
25319
25006
  if (typeof forkId !== "string" || forkId.length === 0 || forkId.length > 64 || !CAPSULE_ID_PATTERN.test(forkId)) {
25320
25007
  return null;
25321
25008
  }
25322
- const rootAbs = path30.resolve(targetRoot);
25009
+ const rootAbs = path31.resolve(targetRoot);
25323
25010
  const rootReal = await realpath2(rootAbs).catch(() => rootAbs);
25324
- const lineagePath = path30.join(rootReal, "forks", forkId, "lineage.json");
25325
- const rel = path30.relative(rootReal, lineagePath);
25326
- if (rel.startsWith("..") || path30.isAbsolute(rel)) {
25011
+ const lineagePath = path31.join(rootReal, "forks", forkId, "lineage.json");
25012
+ const rel = path31.relative(rootReal, lineagePath);
25013
+ if (rel.startsWith("..") || path31.isAbsolute(rel)) {
25327
25014
  return null;
25328
25015
  }
25329
25016
  if (!await isLineagePathContained(rootReal, lineagePath)) {
@@ -25364,19 +25051,19 @@ async function pathEntryExists(absPath) {
25364
25051
  async function isLineagePathContained(rootReal, lineagePath) {
25365
25052
  let existing = lineagePath;
25366
25053
  const suffix = [];
25367
- while (existing !== path30.dirname(existing)) {
25054
+ while (existing !== path31.dirname(existing)) {
25368
25055
  const st = await lstat3(existing).catch(() => null);
25369
25056
  if (st !== null) break;
25370
- suffix.unshift(path30.basename(existing));
25371
- existing = path30.dirname(existing);
25057
+ suffix.unshift(path31.basename(existing));
25058
+ existing = path31.dirname(existing);
25372
25059
  }
25373
25060
  const existingReal = await realpath2(existing).catch(() => existing);
25374
- const targetReal = suffix.length > 0 ? path30.join(existingReal, ...suffix) : existingReal;
25375
- const rel = path30.relative(rootReal, targetReal);
25061
+ const targetReal = suffix.length > 0 ? path31.join(existingReal, ...suffix) : existingReal;
25062
+ const rel = path31.relative(rootReal, targetReal);
25376
25063
  if (rel === "") return true;
25377
25064
  if (rel === "..") return false;
25378
- if (rel.startsWith(`..${path30.sep}`)) return false;
25379
- if (path30.isAbsolute(rel)) return false;
25065
+ if (rel.startsWith(`..${path31.sep}`)) return false;
25066
+ if (path31.isAbsolute(rel)) return false;
25380
25067
  return true;
25381
25068
  }
25382
25069
 
@@ -25398,7 +25085,6 @@ export {
25398
25085
  splitTurnsBySourceValidAt,
25399
25086
  isArtifactMemoryPath,
25400
25087
  buildCompressionGuidelinesMarkdown2 as buildCompressionGuidelinesMarkdown,
25401
- filterRecallCandidates,
25402
25088
  applyQueryAwareCandidateFilter,
25403
25089
  tokenizeRecallQuery,
25404
25090
  shouldFilterLifecycleRecallCandidate,
@@ -25531,6 +25217,7 @@ export {
25531
25217
  mergeGraphExpandedResults,
25532
25218
  graphPathRelativeToStorage,
25533
25219
  blendGraphExpandedRecallScore,
25220
+ filterRecallCandidates,
25534
25221
  Orchestrator
25535
25222
  };
25536
- //# sourceMappingURL=chunk-FR75B4UU.js.map
25223
+ //# sourceMappingURL=chunk-KZVPTJNZ.js.map