@remnic/cli 9.69.56 → 9.69.57

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 (2) hide show
  1. package/dist/index.js +657 -166
  2. package/package.json +32 -32
package/dist/index.js CHANGED
@@ -1,3 +1,10 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
1
8
  // src/enrichment-persist.ts
2
9
  import { composeSalvagedEnvelope } from "@remnic/core/salvage-envelope";
3
10
  async function persistEnrichmentCandidate(storage, entityName, candidate) {
@@ -480,8 +487,8 @@ function resetLegacyDatasetWarningState() {
480
487
 
481
488
  // src/index.ts
482
489
  import fs32 from "fs";
483
- import os3 from "os";
484
- import path22 from "path";
490
+ import os4 from "os";
491
+ import path23 from "path";
485
492
  import { createHash as createHash6 } from "crypto";
486
493
  import { writeFile as fsWriteFile } from "fs/promises";
487
494
  import * as childProcess2 from "child_process";
@@ -569,6 +576,8 @@ import {
569
576
  StorageManager as StorageManager4,
570
577
  parseXrayCliOptions,
571
578
  renderXray,
579
+ parseWhyCliOptions,
580
+ renderRecallWhy,
572
581
  extractWhoKnowsRawArgs,
573
582
  parseWhoKnowsCliOptions,
574
583
  renderWhoKnows,
@@ -3296,13 +3305,13 @@ async function planLocalNamespaceCensus(args) {
3296
3305
  citationTemplate: args.citationTemplate,
3297
3306
  cachedFiles: identityCache.size > 0 ? [...identityCache.values()] : priorFiles,
3298
3307
  readFile: async (file) => {
3299
- const readFile4 = io.readFile;
3300
- if (!readFile4) {
3308
+ const readFile5 = io.readFile;
3309
+ if (!readFile5) {
3301
3310
  manifestReadFailed = true;
3302
3311
  throw new Error("offline storage cannot read reconciliation manifest files");
3303
3312
  }
3304
3313
  try {
3305
- return await readFile4({
3314
+ return await readFile5({
3306
3315
  root: rootDir,
3307
3316
  path: file.path,
3308
3317
  filePath: path6.join(rootDir, file.path)
@@ -7684,6 +7693,355 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
7684
7693
  }
7685
7694
  }
7686
7695
 
7696
+ // src/report.ts
7697
+ import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync4, readdirSync as readdirSync2, statSync as statSync2, writeFileSync } from "fs";
7698
+ import { readFile as readFile3 } from "fs/promises";
7699
+ import os2 from "os";
7700
+ import path16 from "path";
7701
+ var REPORT_ALLOWED_CONFIG_FIELDS = Object.freeze([
7702
+ "qmdEnabled",
7703
+ "qmdAutoEmbedEnabled",
7704
+ "qmdDaemonEnabled",
7705
+ "qmdColdTierEnabled",
7706
+ "qmdTierMigrationEnabled",
7707
+ "qmdTierAutoBackfillEnabled",
7708
+ "qmdMaintenanceEnabled",
7709
+ "debug",
7710
+ "identityEnabled",
7711
+ "injectQuestions",
7712
+ "consolidateEveryN",
7713
+ "maxMemoryTokens",
7714
+ "commitmentDecayDays"
7715
+ ]);
7716
+ var SIZE_BUCKETS = Object.freeze([
7717
+ { label: "< 1 KB", max: 1024 },
7718
+ { label: "1 KB \u2013 10 KB", max: 10 * 1024 },
7719
+ { label: "10 KB \u2013 100 KB", max: 100 * 1024 },
7720
+ { label: "100 KB \u2013 1 MB", max: 1024 * 1024 },
7721
+ { label: "1 MB \u2013 10 MB", max: 10 * 1024 * 1024 },
7722
+ { label: "10 MB \u2013 100 MB", max: 100 * 1024 * 1024 },
7723
+ { label: "100 MB \u2013 1 GB", max: 1024 * 1024 * 1024 },
7724
+ { label: "> 1 GB", max: Infinity }
7725
+ ]);
7726
+ function sizeBucket(bytes) {
7727
+ if (!Number.isFinite(bytes) || bytes < 0) return SIZE_BUCKETS[0].label;
7728
+ for (const bucket of SIZE_BUCKETS) {
7729
+ if (bytes <= bucket.max) return bucket.label;
7730
+ }
7731
+ return SIZE_BUCKETS[SIZE_BUCKETS.length - 1].label;
7732
+ }
7733
+ function sizeOfStore(dir) {
7734
+ try {
7735
+ const { execSync: execSync2 } = __require("child_process");
7736
+ const output = execSync2(`du -sb "${dir}" 2>/dev/null || echo 0`, {
7737
+ encoding: "utf-8",
7738
+ timeout: 5e3
7739
+ });
7740
+ const match = output.match(/^(\d+)/);
7741
+ return match ? Number(match[1]) : 0;
7742
+ } catch {
7743
+ return 0;
7744
+ }
7745
+ }
7746
+ function countMemories(dir) {
7747
+ try {
7748
+ let count = 0;
7749
+ const walk = (d) => {
7750
+ for (const entry of readdirSync2(d)) {
7751
+ const full = path16.join(d, entry);
7752
+ const st = statSync2(full);
7753
+ if (st.isDirectory()) walk(full);
7754
+ else if (entry.endsWith(".md")) count++;
7755
+ }
7756
+ };
7757
+ walk(dir);
7758
+ return count;
7759
+ } catch {
7760
+ return 0;
7761
+ }
7762
+ }
7763
+ function findConfigPath() {
7764
+ const candidates = [
7765
+ path16.join(os2.homedir(), ".config", "remnic", "config.json"),
7766
+ path16.join(os2.homedir(), ".config", "openclaw", "openclaw.json"),
7767
+ path16.join(os2.homedir(), ".openclaw", "config.json")
7768
+ ];
7769
+ for (const p of candidates) {
7770
+ if (existsSync4(p)) return p;
7771
+ }
7772
+ return void 0;
7773
+ }
7774
+ function findMemoryDir(configPath) {
7775
+ if (configPath) {
7776
+ try {
7777
+ const raw = JSON.parse(readFileSync4(configPath, "utf-8"));
7778
+ const cfg = raw?.plugins?.["remnic"] ?? raw?.plugins?.["openclaw-engram"] ?? {};
7779
+ if (typeof cfg.memoryDir === "string") return cfg.memoryDir;
7780
+ } catch {
7781
+ }
7782
+ }
7783
+ return path16.join(os2.homedir(), ".remnic", "memory");
7784
+ }
7785
+ function extractConfigShape(rawConfig) {
7786
+ const result = {};
7787
+ for (const key of Object.getOwnPropertyNames(rawConfig)) {
7788
+ if (!Object.hasOwn(rawConfig, key)) continue;
7789
+ if (!REPORT_ALLOWED_CONFIG_FIELDS.includes(key)) continue;
7790
+ const value = rawConfig[key];
7791
+ if (typeof value === "boolean" || typeof value === "number") {
7792
+ result[key] = value;
7793
+ } else if (typeof value === "string" && ["alpha", "beta", "stable"].includes(value)) {
7794
+ result[key] = value;
7795
+ }
7796
+ }
7797
+ return result;
7798
+ }
7799
+ function runDoctorChecks() {
7800
+ const checks = [];
7801
+ const nodeMajor = Number.parseInt(process.version.slice(1).split(".")[0], 10);
7802
+ checks.push({ name: "Node.js version", ok: nodeMajor >= 22 });
7803
+ const configPath = findConfigPath();
7804
+ checks.push({ name: "Config file", ok: configPath !== void 0 });
7805
+ const memoryDir = findMemoryDir(configPath);
7806
+ try {
7807
+ mkdirSync(memoryDir, { recursive: true });
7808
+ checks.push({ name: "Memory directory", ok: true });
7809
+ } catch {
7810
+ checks.push({ name: "Memory directory", ok: false });
7811
+ }
7812
+ const openclawPath = path16.join(os2.homedir(), ".config", "openclaw", "openclaw.json");
7813
+ checks.push({ name: "OpenClaw config file", ok: existsSync4(openclawPath) });
7814
+ return checks;
7815
+ }
7816
+ var PUBLIC_BENCHMARK_IDS = Object.freeze([
7817
+ "ama-bench",
7818
+ "memory-arena",
7819
+ "amemgym",
7820
+ "longmemeval",
7821
+ "locomo",
7822
+ "beam",
7823
+ "personamem",
7824
+ "membench",
7825
+ "memoryagentbench",
7826
+ "taxonomy-accuracy",
7827
+ "extraction-judge-calibration",
7828
+ "extraction-span-mode",
7829
+ "enrichment-fidelity",
7830
+ "entity-consolidation",
7831
+ "page-versioning",
7832
+ "retrieval-personalization",
7833
+ "retrieval-temporal",
7834
+ "retrieval-direct-answer",
7835
+ "retrieval-graph",
7836
+ "retrieval-reasoning-trace",
7837
+ "coding-recall",
7838
+ "procedural-recall",
7839
+ "say-once",
7840
+ "ingestion-entity-recall",
7841
+ "ingestion-schema-completeness",
7842
+ "ingestion-backlink-f1",
7843
+ "ingestion-setup-friction",
7844
+ "ingestion-citation-accuracy",
7845
+ "assistant-morning-brief",
7846
+ "assistant-meeting-prep",
7847
+ "assistant-next-best-action",
7848
+ "assistant-synthesis",
7849
+ "buffer-surprise-trigger",
7850
+ "contradiction-detection",
7851
+ "retention-aged-dataset",
7852
+ "memcorrect-v1",
7853
+ "bounded-memory-contracts",
7854
+ "staged-memory-synthetic-v1"
7855
+ ]);
7856
+ var PUBLIC_METRIC_KEYS = Object.freeze([
7857
+ "recall",
7858
+ "precision",
7859
+ "f1",
7860
+ "exact_match",
7861
+ "category_match",
7862
+ "keyword_overlap",
7863
+ "high_confidence",
7864
+ "latencyMs",
7865
+ "tokens",
7866
+ "cost",
7867
+ "qrel_at_1",
7868
+ "qrel_at_3",
7869
+ "qrel_at_5",
7870
+ "qrel_at_10",
7871
+ "bleu",
7872
+ "rouge",
7873
+ "support",
7874
+ "completeness"
7875
+ ]);
7876
+ var METRIC_KEY_PATTERN = /^[a-z0-9][a-z0-9._-]{0,63}$/;
7877
+ function summarizeBenchScorecard(raw) {
7878
+ if (typeof raw !== "object" || raw === null) return void 0;
7879
+ const summary = {};
7880
+ const rawId = readBenchmarkId(raw);
7881
+ if (rawId !== void 0) {
7882
+ summary.benchmarkId = PUBLIC_BENCHMARK_IDS.includes(rawId) ? rawId : "custom";
7883
+ }
7884
+ const tasks = readNested(raw, "results", "tasks") ?? readOwn(raw, "tasks");
7885
+ if (Array.isArray(tasks)) summary.taskCount = tasks.length;
7886
+ const aggregates = readNested(raw, "results", "aggregates") ?? readOwn(raw, "scores");
7887
+ const scores = extractNumericScores(aggregates);
7888
+ if (scores !== void 0) summary.scores = scores;
7889
+ return Object.keys(summary).length > 0 ? summary : void 0;
7890
+ }
7891
+ function readOwn(source, key) {
7892
+ return Object.hasOwn(source, key) ? source[key] : void 0;
7893
+ }
7894
+ function readNested(source, ...path24) {
7895
+ let current = source;
7896
+ for (const key of path24) {
7897
+ if (typeof current !== "object" || current === null) return void 0;
7898
+ if (!Object.hasOwn(current, key)) return void 0;
7899
+ current = current[key];
7900
+ }
7901
+ return current;
7902
+ }
7903
+ function readBenchmarkId(raw) {
7904
+ const metaId = readNested(raw, "meta", "benchmark");
7905
+ if (typeof metaId === "string" && metaId.length > 0) return metaId;
7906
+ const bench = readOwn(raw, "benchmark");
7907
+ if (typeof bench === "object" && bench !== null) {
7908
+ const id = readOwn(bench, "id");
7909
+ if (typeof id === "string" && id.length > 0) return id;
7910
+ }
7911
+ return void 0;
7912
+ }
7913
+ function extractNumericScores(source) {
7914
+ if (typeof source !== "object" || source === null) return void 0;
7915
+ const scores = {};
7916
+ for (const key of Object.getOwnPropertyNames(source)) {
7917
+ if (!Object.hasOwn(source, key)) continue;
7918
+ if (!PUBLIC_METRIC_KEYS.includes(key)) continue;
7919
+ if (!METRIC_KEY_PATTERN.test(key)) continue;
7920
+ const value = readOwn(source, key);
7921
+ if (typeof value === "number" && Number.isFinite(value)) {
7922
+ scores[key] = value;
7923
+ continue;
7924
+ }
7925
+ if (typeof value === "object" && value !== null) {
7926
+ const mean = readOwn(value, "mean");
7927
+ if (typeof mean === "number" && Number.isFinite(mean)) scores[key] = mean;
7928
+ }
7929
+ }
7930
+ return Object.keys(scores).length > 0 ? scores : void 0;
7931
+ }
7932
+ async function buildReport(options = {}) {
7933
+ const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
7934
+ const platform = { os: os2.platform(), arch: os2.arch(), node: process.version };
7935
+ let remnicVersion = "unknown";
7936
+ try {
7937
+ const pkgPath = __require.resolve("@remnic/core/package.json");
7938
+ const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
7939
+ remnicVersion = pkg.version ?? "unknown";
7940
+ } catch {
7941
+ }
7942
+ const doctor = runDoctorChecks();
7943
+ let configShape = {};
7944
+ try {
7945
+ const configPath = findConfigPath();
7946
+ if (configPath) {
7947
+ const raw = JSON.parse(readFileSync4(configPath, "utf-8"));
7948
+ const remnicCfg = raw?.plugins?.["remnic"] ?? raw?.plugins?.["openclaw-engram"] ?? {};
7949
+ configShape = extractConfigShape(remnicCfg);
7950
+ }
7951
+ } catch {
7952
+ }
7953
+ const memoryDir = findMemoryDir(findConfigPath());
7954
+ const totalMemories = countMemories(memoryDir);
7955
+ const storeBytes = sizeOfStore(memoryDir);
7956
+ const sizeBucketLabel = sizeBucket(storeBytes);
7957
+ let benchScorecard;
7958
+ if (options.includeBench) {
7959
+ const scorecardPath = path16.join(os2.homedir(), ".remnic", "reports", "bench-scorecard.json");
7960
+ try {
7961
+ const raw = JSON.parse(await readFile3(scorecardPath, "utf-8"));
7962
+ benchScorecard = summarizeBenchScorecard(raw);
7963
+ } catch {
7964
+ }
7965
+ }
7966
+ return {
7967
+ schemaVersion: "1",
7968
+ generatedAt,
7969
+ platform,
7970
+ remnicVersion,
7971
+ doctor,
7972
+ configShape,
7973
+ storeScale: { totalMemories, sizeBucket: sizeBucketLabel },
7974
+ ...benchScorecard !== void 0 ? { benchScorecard } : {}
7975
+ };
7976
+ }
7977
+ function renderReportMarkdown(report) {
7978
+ const lines = [
7979
+ "## Remnic Diagnostic Report",
7980
+ "",
7981
+ `Generated: ${report.generatedAt}`,
7982
+ `Version: ${report.remnicVersion}`,
7983
+ `Platform: ${report.platform.os} ${report.platform.arch} (Node ${report.platform.node})`,
7984
+ "",
7985
+ "### Doctor Checks",
7986
+ "",
7987
+ "| Check | Status |",
7988
+ "| --- | --- |"
7989
+ ];
7990
+ for (const check of report.doctor) {
7991
+ lines.push(`| ${check.name} | ${check.ok ? "Pass" : "Fail"} |`);
7992
+ }
7993
+ lines.push("", "### Config Shape (allow-list only)", "");
7994
+ const keys = Object.getOwnPropertyNames(report.configShape).sort();
7995
+ lines.push("| Field | Value |");
7996
+ lines.push("| --- | --- |");
7997
+ for (const key of keys) {
7998
+ lines.push(`| ${key} | ${JSON.stringify(report.configShape[key])} |`);
7999
+ }
8000
+ lines.push("", "### Store Scale", "");
8001
+ lines.push("| Metric | Value |");
8002
+ lines.push("| --- | --- |");
8003
+ lines.push(`| Total memories | ${report.storeScale.totalMemories} |`);
8004
+ lines.push(`| Store size | ${report.storeScale.sizeBucket} |`);
8005
+ if (report.benchScorecard !== void 0) {
8006
+ lines.push("", "### Bench Scorecard", "");
8007
+ lines.push("```json");
8008
+ lines.push(JSON.stringify(report.benchScorecard, null, 2));
8009
+ lines.push("```");
8010
+ }
8011
+ lines.push("", "---", "", "**Privacy:** This report contains only the fields listed above.");
8012
+ lines.push("No secrets, paths, hostnames, or personal data are included.");
8013
+ lines.push("", "To file an issue, paste the above into a new GitHub issue at:");
8014
+ lines.push("https://github.com/joshuaswarren/remnic/issues/new");
8015
+ return lines.join("\n");
8016
+ }
8017
+ function renderReportJson(report) {
8018
+ return JSON.stringify(report, null, 2);
8019
+ }
8020
+ async function cmdReport(options = {}) {
8021
+ const reportDir = path16.join(os2.homedir(), ".remnic", "reports");
8022
+ mkdirSync(reportDir, { recursive: true });
8023
+ const report = await buildReport({ includeBench: options.includeBench });
8024
+ const dateStr = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10).replace(/-/g, "");
8025
+ const mdPath = path16.join(reportDir, `report-${dateStr}.md`);
8026
+ const jsonPath = path16.join(reportDir, `report-${dateStr}.json`);
8027
+ const md = renderReportMarkdown(report);
8028
+ const json = renderReportJson(report);
8029
+ writeFileSync(mdPath, md, "utf-8");
8030
+ writeFileSync(jsonPath, json, "utf-8");
8031
+ if (options.json) {
8032
+ console.log(json);
8033
+ } else {
8034
+ console.log(md);
8035
+ }
8036
+ console.log(`
8037
+ Report saved to:
8038
+ ${mdPath}
8039
+ ${jsonPath}`);
8040
+ console.log("\nTo file an issue, run:");
8041
+ console.log(` gh issue create --title "Remnic diagnostic report ${dateStr}" --body-file "${mdPath}"`);
8042
+ console.log("\nOr paste the report at: https://github.com/joshuaswarren/remnic/issues/new");
8043
+ }
8044
+
7687
8045
  // src/remote-daemon.ts
7688
8046
  import fs28 from "fs";
7689
8047
  import { readCompatEnv } from "@remnic/core";
@@ -7936,13 +8294,58 @@ async function remoteRecallXray(daemon, request) {
7936
8294
  }
7937
8295
  return { snapshotFound: false };
7938
8296
  }
8297
+ async function remoteRecallWhy(daemon, request) {
8298
+ const params = new URLSearchParams({ q: request.query });
8299
+ if (request.expect !== void 0 && request.expect.length > 0) {
8300
+ params.set("expect", request.expect);
8301
+ }
8302
+ if (request.namespace !== void 0 && request.namespace.length > 0) {
8303
+ params.set("namespace", request.namespace);
8304
+ }
8305
+ if (request.sessionKey !== void 0 && request.sessionKey.length > 0) {
8306
+ params.set("session", request.sessionKey);
8307
+ }
8308
+ let response;
8309
+ try {
8310
+ response = await daemonFetch(
8311
+ daemon.baseUrl,
8312
+ `engram/v1/recall/why?${params.toString()}`,
8313
+ daemon.token,
8314
+ 1e4
8315
+ );
8316
+ } catch (err) {
8317
+ if (isTransportError(err)) throw unreachableError(daemon.baseUrl);
8318
+ throw err;
8319
+ }
8320
+ if (response.status === 401) {
8321
+ throw new Error(
8322
+ `token rejected by remnic-server at ${daemon.baseUrl} (HTTP 401). Update server.authToken or REMNIC_AUTH_TOKEN to match the remote daemon.`
8323
+ );
8324
+ }
8325
+ if (!response.ok) {
8326
+ throw new Error(`remnic-server returned HTTP ${response.status} ${response.statusText}`);
8327
+ }
8328
+ let payload;
8329
+ try {
8330
+ payload = await response.json();
8331
+ } catch {
8332
+ throw new Error("remnic-server returned a non-JSON response");
8333
+ }
8334
+ if (payload !== null && typeof payload === "object" && !Array.isArray(payload)) {
8335
+ const record2 = payload;
8336
+ if (record2.reportFound === true && record2.report !== null && typeof record2.report === "object") {
8337
+ return { reportFound: true, report: record2.report };
8338
+ }
8339
+ }
8340
+ return { reportFound: false };
8341
+ }
7939
8342
 
7940
8343
  // src/daemon-service.ts
7941
8344
  import fs29 from "fs";
7942
- import path16 from "path";
8345
+ import path17 from "path";
7943
8346
  import * as childProcess from "child_process";
7944
8347
  import { fileURLToPath as fileURLToPath5 } from "url";
7945
- var thisModuleDir = path16.dirname(fileURLToPath5(import.meta.url));
8348
+ var thisModuleDir = path17.dirname(fileURLToPath5(import.meta.url));
7946
8349
  function launchdLoadPlist(plistPath, processApi = childProcess) {
7947
8350
  processApi.execFileSync("launchctl", ["load", "-w", plistPath], { stdio: "pipe" });
7948
8351
  }
@@ -7950,7 +8353,7 @@ function launchdUnloadPlist(plistPath, processApi = childProcess) {
7950
8353
  processApi.execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
7951
8354
  }
7952
8355
  function resolveServerBinDetails(options = {}) {
7953
- const existsSync4 = options.existsSync ?? fs29.existsSync;
8356
+ const existsSync5 = options.existsSync ?? fs29.existsSync;
7954
8357
  const findCommandOnPath2 = options.findCommandOnPath ?? findCommandOnPath;
7955
8358
  const moduleDir = options.moduleDir ?? thisModuleDir;
7956
8359
  const packageResolve = options.packageResolve ?? resolveImportSpecifier;
@@ -7964,8 +8367,8 @@ function resolveServerBinDetails(options = {}) {
7964
8367
  });
7965
8368
  } catch {
7966
8369
  }
7967
- const workspaceServerBin = path16.resolve(moduleDir, "../../remnic-server/bin/remnic-server.js");
7968
- const workspaceDistIndex = path16.resolve(moduleDir, "../../remnic-server/dist/index.js");
8370
+ const workspaceServerBin = path17.resolve(moduleDir, "../../remnic-server/bin/remnic-server.js");
8371
+ const workspaceDistIndex = path17.resolve(moduleDir, "../../remnic-server/dist/index.js");
7969
8372
  candidates.push(
7970
8373
  {
7971
8374
  path: workspaceServerBin,
@@ -7986,15 +8389,15 @@ function resolveServerBinDetails(options = {}) {
7986
8389
  });
7987
8390
  }
7988
8391
  candidates.push({
7989
- path: path16.resolve(moduleDir, "../../remnic-server/src/index.ts"),
8392
+ path: path17.resolve(moduleDir, "../../remnic-server/src/index.ts"),
7990
8393
  source: "workspace-source"
7991
8394
  });
7992
- const selected = candidates.find((candidate) => isCandidateReady(candidate, existsSync4)) ?? candidates.find((candidate) => existsSync4(candidate.path)) ?? candidates[0] ?? {
7993
- path: path16.resolve(moduleDir, "../../remnic-server/dist/index.js"),
8395
+ const selected = candidates.find((candidate) => isCandidateReady(candidate, existsSync5)) ?? candidates.find((candidate) => existsSync5(candidate.path)) ?? candidates[0] ?? {
8396
+ path: path17.resolve(moduleDir, "../../remnic-server/dist/index.js"),
7994
8397
  source: "workspace-dist"
7995
8398
  };
7996
- const exists = existsSync4(selected.path);
7997
- const requiredExists = selected.requiredPath ? existsSync4(selected.requiredPath) : true;
8399
+ const exists = existsSync5(selected.path);
8400
+ const requiredExists = selected.requiredPath ? existsSync5(selected.requiredPath) : true;
7998
8401
  const { requiredPath: _requiredPath, ...publicSelected } = selected;
7999
8402
  return {
8000
8403
  ...publicSelected,
@@ -8002,14 +8405,14 @@ function resolveServerBinDetails(options = {}) {
8002
8405
  loadableByNode: exists && requiredExists && !selected.path.endsWith(".ts")
8003
8406
  };
8004
8407
  }
8005
- function isCandidateReady(candidate, existsSync4) {
8006
- return existsSync4(candidate.path) && (candidate.requiredPath ? existsSync4(candidate.requiredPath) : true);
8408
+ function isCandidateReady(candidate, existsSync5) {
8409
+ return existsSync5(candidate.path) && (candidate.requiredPath ? existsSync5(candidate.requiredPath) : true);
8007
8410
  }
8008
8411
  function resolveServerBin(options = {}) {
8009
8412
  return resolveServerBinDetails(options).path;
8010
8413
  }
8011
8414
  function readVerifiedDaemonPid(options) {
8012
- const readFileSync5 = options.readFileSync ?? fs29.readFileSync;
8415
+ const readFileSync6 = options.readFileSync ?? fs29.readFileSync;
8013
8416
  const unlinkSync = options.unlinkSync ?? fs29.unlinkSync;
8014
8417
  const processKill = options.processKill ?? process.kill;
8015
8418
  const platform = options.platform ?? process.platform;
@@ -8017,7 +8420,7 @@ function readVerifiedDaemonPid(options) {
8017
8420
  for (const file of options.pidFiles) {
8018
8421
  let pid;
8019
8422
  try {
8020
- pid = parseDaemonPid(readFileSync5(file, "utf8"));
8423
+ pid = parseDaemonPid(readFileSync6(file, "utf8"));
8021
8424
  } catch {
8022
8425
  continue;
8023
8426
  }
@@ -8045,7 +8448,7 @@ function readVerifiedDaemonPid(options) {
8045
8448
  }
8046
8449
  function doesProcessCommandLookLikeRemnicDaemon(command, expectedServerBin) {
8047
8450
  const normalizedCommand = command.trim();
8048
- const normalizedExpected = path16.resolve(expandTilde(expectedServerBin));
8451
+ const normalizedExpected = path17.resolve(expandTilde(expectedServerBin));
8049
8452
  return normalizedCommand.includes(normalizedExpected) || /(?:^|\s|[/\\])(?:remnic-server|engram-server)(?:\.js)?(?:\s|$)/.test(normalizedCommand) || /@remnic[/\\]server[/\\]/.test(normalizedCommand) || /packages[/\\]remnic-server[/\\](?:bin[/\\]remnic-server\.js|dist[/\\]index\.js|src[/\\]index\.ts)/.test(normalizedCommand);
8050
8453
  }
8051
8454
  function parseDaemonPid(raw) {
@@ -8110,9 +8513,9 @@ function removePidFileBestEffort(file, unlinkSync) {
8110
8513
  }
8111
8514
  }
8112
8515
  function inspectLaunchdPlist(plistPath, options = {}) {
8113
- const existsSync4 = options.existsSync ?? fs29.existsSync;
8114
- const readFileSync5 = options.readFileSync ?? fs29.readFileSync;
8115
- if (!existsSync4(plistPath)) {
8516
+ const existsSync5 = options.existsSync ?? fs29.existsSync;
8517
+ const readFileSync6 = options.readFileSync ?? fs29.readFileSync;
8518
+ if (!existsSync5(plistPath)) {
8116
8519
  return {
8117
8520
  installed: false,
8118
8521
  ok: true,
@@ -8122,7 +8525,7 @@ function inspectLaunchdPlist(plistPath, options = {}) {
8122
8525
  }
8123
8526
  let content;
8124
8527
  try {
8125
- content = readFileSync5(plistPath, "utf8");
8528
+ content = readFileSync6(plistPath, "utf8");
8126
8529
  } catch {
8127
8530
  return {
8128
8531
  installed: true,
@@ -8150,7 +8553,7 @@ function inspectLaunchdPlist(plistPath, options = {}) {
8150
8553
  };
8151
8554
  }
8152
8555
  const expandedServerArg = expandTilde(serverArg);
8153
- if (!path16.isAbsolute(expandedServerArg)) {
8556
+ if (!path17.isAbsolute(expandedServerArg)) {
8154
8557
  return {
8155
8558
  installed: true,
8156
8559
  ok: false,
@@ -8158,7 +8561,7 @@ function inspectLaunchdPlist(plistPath, options = {}) {
8158
8561
  remediation: "Run `remnic daemon install` so launchd uses an absolute Remnic server path."
8159
8562
  };
8160
8563
  }
8161
- if (!existsSync4(expandedServerArg)) {
8564
+ if (!existsSync5(expandedServerArg)) {
8162
8565
  return {
8163
8566
  installed: true,
8164
8567
  ok: false,
@@ -8222,8 +8625,8 @@ function normalizeResolvedPath(resolved) {
8222
8625
  return resolved;
8223
8626
  }
8224
8627
  function packageServerBinFromEntry(packageEntry) {
8225
- if (path16.basename(packageEntry) === "index.js" && path16.basename(path16.dirname(packageEntry)) === "dist") {
8226
- return path16.join(path16.dirname(path16.dirname(packageEntry)), "bin", "remnic-server.js");
8628
+ if (path17.basename(packageEntry) === "index.js" && path17.basename(path17.dirname(packageEntry)) === "dist") {
8629
+ return path17.join(path17.dirname(path17.dirname(packageEntry)), "bin", "remnic-server.js");
8227
8630
  }
8228
8631
  return packageEntry;
8229
8632
  }
@@ -8297,8 +8700,8 @@ import {
8297
8700
  } from "@remnic/core";
8298
8701
 
8299
8702
  // src/import-bundle-detect.ts
8300
- import { lstatSync as lstatSync3, readdirSync as readdirSync2, readFileSync as readFileSync4 } from "fs";
8301
- import path17 from "path";
8703
+ import { lstatSync as lstatSync3, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "fs";
8704
+ import path18 from "path";
8302
8705
  function detectBundleEntries(bundleDir, options = {}) {
8303
8706
  const readdir4 = options.readdirImpl ?? defaultReaddir;
8304
8707
  const readFileImpl = options.readFileImpl ?? defaultReadFile;
@@ -8329,7 +8732,7 @@ function detectBundleEntries(bundleDir, options = {}) {
8329
8732
  for (const filePath of roots) {
8330
8733
  if (seenFiles.has(filePath)) continue;
8331
8734
  seenFiles.add(filePath);
8332
- const name = path17.basename(filePath);
8735
+ const name = path18.basename(filePath);
8333
8736
  const match = classifyFile(name, filePath, readFileImpl);
8334
8737
  if (match) entries.push(match);
8335
8738
  }
@@ -8367,7 +8770,7 @@ function collectCandidatePaths(root, readdir4, isDirectory2, isRegularFile) {
8367
8770
  return;
8368
8771
  }
8369
8772
  for (const entry of entries) {
8370
- const full = path17.join(dir, entry);
8773
+ const full = path18.join(dir, entry);
8371
8774
  if (isDirectory2(full)) {
8372
8775
  walk(full, depth + 1);
8373
8776
  } else if (isRegularFile(full)) {
@@ -8416,10 +8819,10 @@ function disambiguateConversations(filePath, readFileImpl) {
8416
8819
  return "chatgpt";
8417
8820
  }
8418
8821
  function defaultReaddir(dir) {
8419
- return readdirSync2(dir);
8822
+ return readdirSync3(dir);
8420
8823
  }
8421
8824
  function defaultReadFile(p) {
8422
- return readFileSync4(p, "utf-8");
8825
+ return readFileSync5(p, "utf-8");
8423
8826
  }
8424
8827
  function defaultIsDirectory(p) {
8425
8828
  try {
@@ -8923,7 +9326,7 @@ async function cmdCapture(rest, io) {
8923
9326
 
8924
9327
  // src/import-lossless-claw-cmd.ts
8925
9328
  import fs31 from "fs";
8926
- import path18 from "path";
9329
+ import path19 from "path";
8927
9330
  import {
8928
9331
  applyLcmSchema,
8929
9332
  ensureLcmStateDir,
@@ -9073,7 +9476,7 @@ async function cmdImportLosslessClaw(argv, io, deps = {}) {
9073
9476
  let destDb;
9074
9477
  try {
9075
9478
  if (parsed.dryRun) {
9076
- const lcmPath = path18.join(memoryDir, "state", "lcm.sqlite");
9479
+ const lcmPath = path19.join(memoryDir, "state", "lcm.sqlite");
9077
9480
  if (fs31.existsSync(lcmPath)) {
9078
9481
  destDb = mod.openExistingLcmDatabaseReadOnly(lcmPath);
9079
9482
  } else {
@@ -9193,9 +9596,9 @@ function printBenchComparisonSummary(comparison, baseline, candidate) {
9193
9596
  }
9194
9597
 
9195
9598
  // src/bench-coding-commands.ts
9196
- import { lstat as lstat3, readFile as readFile3, realpath as realpath2, stat as stat2 } from "fs/promises";
9197
- import os2 from "os";
9198
- import path19 from "path";
9599
+ import { lstat as lstat3, readFile as readFile4, realpath as realpath2, stat as stat2 } from "fs/promises";
9600
+ import os3 from "os";
9601
+ import path20 from "path";
9199
9602
  var UINT32_MAX = 4294967295;
9200
9603
  var FROZEN_GENERATOR_SEED = 81;
9201
9604
  var FROZEN_TASK_COUNT = 30;
@@ -9205,7 +9608,7 @@ var FROZEN_MAX_STEPS = 12;
9205
9608
  var FROZEN_MAX_TOOL_CALLS = 8;
9206
9609
  var FROZEN_MAX_OUTPUT_CHARS = 16384;
9207
9610
  var MAX_OUTPUT_BYTES = 16384;
9208
- var DEFAULT_REPEATED_FAILURE_OUTPUT_DIR = path19.join(
9611
+ var DEFAULT_REPEATED_FAILURE_OUTPUT_DIR = path20.join(
9209
9612
  resolveHomeDir(),
9210
9613
  ".remnic",
9211
9614
  "bench",
@@ -9539,7 +9942,7 @@ function parseBenchCodingArgs(args) {
9539
9942
  throw new Error(`unknown bench coding subcommand ${args[0]}`);
9540
9943
  }
9541
9944
  function normalizeCommandPaths(command) {
9542
- const resolve3 = (value) => path19.resolve(expandTilde(value));
9945
+ const resolve3 = (value) => path20.resolve(expandTilde(value));
9543
9946
  if (command.kind === "repo-generate") {
9544
9947
  return { ...command, outputDir: resolve3(command.outputDir) };
9545
9948
  }
@@ -9570,23 +9973,23 @@ function normalizeCommandPaths(command) {
9570
9973
  return command;
9571
9974
  }
9572
9975
  async function canonicalProspectivePath(value) {
9573
- let candidate = path19.resolve(value);
9976
+ let candidate = path20.resolve(value);
9574
9977
  const missingSegments = [];
9575
9978
  while (true) {
9576
9979
  try {
9577
- return path19.join(await realpath2(candidate), ...missingSegments.reverse());
9980
+ return path20.join(await realpath2(candidate), ...missingSegments.reverse());
9578
9981
  } catch (error) {
9579
9982
  if (error.code !== "ENOENT") throw error;
9580
- const parent = path19.dirname(candidate);
9983
+ const parent = path20.dirname(candidate);
9581
9984
  if (parent === candidate) throw error;
9582
- missingSegments.push(path19.basename(candidate));
9985
+ missingSegments.push(path20.basename(candidate));
9583
9986
  candidate = parent;
9584
9987
  }
9585
9988
  }
9586
9989
  }
9587
9990
  function isSameOrDescendant(candidate, root) {
9588
- const relative2 = path19.relative(root, candidate);
9589
- return relative2 === "" || relative2 !== ".." && !relative2.startsWith(`..${path19.sep}`) && !path19.isAbsolute(relative2);
9991
+ const relative2 = path20.relative(root, candidate);
9992
+ return relative2 === "" || relative2 !== ".." && !relative2.startsWith(`..${path20.sep}`) && !path20.isAbsolute(relative2);
9590
9993
  }
9591
9994
  async function pathExists(value) {
9592
9995
  try {
@@ -9605,7 +10008,7 @@ async function assertSafeBenchmarkOutput(outputDir) {
9605
10008
  const configured = process.env[variable]?.trim();
9606
10009
  if (!configured) continue;
9607
10010
  const memoryRoot = await canonicalProspectivePath(
9608
- path19.resolve(expandTilde(configured))
10011
+ path20.resolve(expandTilde(configured))
9609
10012
  );
9610
10013
  if (isSameOrDescendant(canonicalOutput, memoryRoot)) {
9611
10014
  throw new Error(refusal);
@@ -9613,10 +10016,10 @@ async function assertSafeBenchmarkOutput(outputDir) {
9613
10016
  }
9614
10017
  let candidate = canonicalOutput;
9615
10018
  while (true) {
9616
- const hasProfile = await pathExists(path19.join(candidate, "profile.md"));
9617
- const hasMemoryData = await pathExists(path19.join(candidate, "facts")) || await pathExists(path19.join(candidate, "entities")) || await pathExists(path19.join(candidate, "state"));
10019
+ const hasProfile = await pathExists(path20.join(candidate, "profile.md"));
10020
+ const hasMemoryData = await pathExists(path20.join(candidate, "facts")) || await pathExists(path20.join(candidate, "entities")) || await pathExists(path20.join(candidate, "state"));
9618
10021
  if (hasProfile && hasMemoryData) throw new Error(refusal);
9619
- const parent = path19.dirname(candidate);
10022
+ const parent = path20.dirname(candidate);
9620
10023
  if (parent === candidate) break;
9621
10024
  candidate = parent;
9622
10025
  }
@@ -9628,7 +10031,7 @@ async function assertSafeBenchmarkOutput(outputDir) {
9628
10031
  async function assertH6StatsRunDirectory(runDir, commandName = "stats") {
9629
10032
  try {
9630
10033
  const parsed = JSON.parse(
9631
- await readFile3(path19.join(runDir, "run.json"), "utf8")
10034
+ await readFile4(path20.join(runDir, "run.json"), "utf8")
9632
10035
  );
9633
10036
  if (parsed.schemaVersion !== 1 || typeof parsed.runId !== "string" || parsed.runId.length === 0 || typeof parsed.suiteVersion !== "string" || !parsed.suiteVersion.startsWith("h6-failure-gate-v1-")) {
9634
10037
  throw new Error("invalid H6 metadata");
@@ -9638,7 +10041,7 @@ async function assertH6StatsRunDirectory(runDir, commandName = "stats") {
9638
10041
  }
9639
10042
  }
9640
10043
  function sanitizeOutput(output) {
9641
- const home = os2.homedir();
10044
+ const home = os3.homedir();
9642
10045
  const safe = home.length > 1 ? output.replaceAll(home, "~") : output;
9643
10046
  if (Buffer.byteLength(safe, "utf8") <= MAX_OUTPUT_BYTES) return safe.trimEnd();
9644
10047
  const bounded = Buffer.from(safe, "utf8").subarray(0, MAX_OUTPUT_BYTES - 32).toString("utf8");
@@ -9687,7 +10090,7 @@ async function runRepoVerification(command, bench) {
9687
10090
  if (command.directory === void 0) {
9688
10091
  dataset = await requireFunction(bench, "loadCommittedH6BenchmarkDataset")();
9689
10092
  } else {
9690
- const serialized = await readFile3(path19.join(command.directory, "dataset.json"), "utf8").catch(
10093
+ const serialized = await readFile4(path20.join(command.directory, "dataset.json"), "utf8").catch(
9691
10094
  () => void 0
9692
10095
  );
9693
10096
  if (serialized === void 0) {
@@ -9815,8 +10218,8 @@ async function cmdBenchCoding(args) {
9815
10218
  }
9816
10219
 
9817
10220
  // src/bench-security-commands.ts
9818
- import path20 from "path";
9819
- var DEFAULT_OUTPUT_DIR = path20.join(
10221
+ import path21 from "path";
10222
+ var DEFAULT_OUTPUT_DIR = path21.join(
9820
10223
  resolveHomeDir(),
9821
10224
  ".remnic",
9822
10225
  "bench",
@@ -9969,7 +10372,7 @@ ${BENCH_SECURITY_USAGE}`);
9969
10372
  }
9970
10373
 
9971
10374
  // src/bench-research-commands.ts
9972
- import path21 from "path";
10375
+ import path22 from "path";
9973
10376
  function emit(result) {
9974
10377
  if (result.output) {
9975
10378
  console.log(result.output);
@@ -9987,7 +10390,7 @@ async function runBenchResearchCommand(parsed) {
9987
10390
  emit(
9988
10391
  await runAttributeCliCommand({
9989
10392
  runRef: parsed.runRef,
9990
- resultsDir: parsed.resultsDir ?? path21.join(resolveHomeDir(), ".remnic", "bench", "results"),
10393
+ resultsDir: parsed.resultsDir ?? path22.join(resolveHomeDir(), ".remnic", "bench", "results"),
9991
10394
  memoryDir: parsed.memoryDir,
9992
10395
  qmdPath: parsed.qmdPath,
9993
10396
  collection: parsed.collection,
@@ -10257,14 +10660,14 @@ registerPublisher("hermes", () => new HermesMemoryExtensionPublisher());
10257
10660
  registerPublisher("pi", () => new LazyPluginPiPublisher("pi", (mod) => mod.PiMemoryExtensionPublisher));
10258
10661
  registerPublisher("omp", () => new LazyPluginPiPublisher("omp", (mod) => mod.OmpMemoryExtensionPublisher));
10259
10662
  registerPublisher("prime-agent", () => new LazyPluginPiPublisher("prime-agent", (mod) => mod.PrimeAgentMemoryExtensionPublisher));
10260
- var PID_DIR = path22.join(resolveHomeDir(), ".remnic");
10261
- var LEGACY_PID_DIR = path22.join(resolveHomeDir(), ".engram");
10262
- var PID_FILE = path22.join(PID_DIR, "server.pid");
10263
- var LEGACY_PID_FILE = path22.join(LEGACY_PID_DIR, "server.pid");
10264
- var LOG_FILE = path22.join(PID_DIR, "server.log");
10265
- var LEGACY_LOG_FILE = path22.join(LEGACY_PID_DIR, "server.log");
10266
- var CLI_MODULE_DIR = path22.dirname(fileURLToPath6(import.meta.url));
10267
- var CLI_REPO_ROOT2 = path22.resolve(CLI_MODULE_DIR, "../../..");
10663
+ var PID_DIR = path23.join(resolveHomeDir(), ".remnic");
10664
+ var LEGACY_PID_DIR = path23.join(resolveHomeDir(), ".engram");
10665
+ var PID_FILE = path23.join(PID_DIR, "server.pid");
10666
+ var LEGACY_PID_FILE = path23.join(LEGACY_PID_DIR, "server.pid");
10667
+ var LOG_FILE = path23.join(PID_DIR, "server.log");
10668
+ var LEGACY_LOG_FILE = path23.join(LEGACY_PID_DIR, "server.log");
10669
+ var CLI_MODULE_DIR = path23.dirname(fileURLToPath6(import.meta.url));
10670
+ var CLI_REPO_ROOT2 = path23.resolve(CLI_MODULE_DIR, "../../..");
10268
10671
  var OPENCLAW_GATEWAY_LABEL = "ai.openclaw.gateway";
10269
10672
  var CLI_SUCCESS_EXIT_GRACE_MS = 5e3;
10270
10673
  var CLI_OUTPUT_FLUSH_GRACE_MS = 250;
@@ -10443,12 +10846,12 @@ async function resolveKnownBenchmarkIds() {
10443
10846
  return knownIds;
10444
10847
  }
10445
10848
  function resolveBenchOutputDir() {
10446
- return path22.join(resolveHomeDir(), ".remnic", "bench", "results");
10849
+ return path23.join(resolveHomeDir(), ".remnic", "bench", "results");
10447
10850
  }
10448
10851
  async function launchBenchUi(resultsDir) {
10449
- const benchUiDir = path22.join(CLI_REPO_ROOT2, "packages", "bench-ui");
10852
+ const benchUiDir = path23.join(CLI_REPO_ROOT2, "packages", "bench-ui");
10450
10853
  const pnpmCmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
10451
- if (!fs32.existsSync(path22.join(benchUiDir, "package.json"))) {
10854
+ if (!fs32.existsSync(path23.join(benchUiDir, "package.json"))) {
10452
10855
  console.error("ERROR: @remnic/bench-ui is not available in this checkout.");
10453
10856
  process.exit(1);
10454
10857
  }
@@ -10475,11 +10878,11 @@ async function launchBenchUi(resultsDir) {
10475
10878
  });
10476
10879
  }
10477
10880
  function resolveDatasetDownloadScriptPath() {
10478
- const bundled = path22.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
10881
+ const bundled = path23.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
10479
10882
  if (fs32.existsSync(bundled)) {
10480
10883
  return bundled;
10481
10884
  }
10482
- return path22.join(CLI_REPO_ROOT2, "packages", "remnic-cli", "assets", "download-datasets.sh");
10885
+ return path23.join(CLI_REPO_ROOT2, "packages", "remnic-cli", "assets", "download-datasets.sh");
10483
10886
  }
10484
10887
  function runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, jsonMode) {
10485
10888
  const stdio = jsonMode ? ["inherit", process.stderr, "inherit"] : "inherit";
@@ -10785,12 +11188,12 @@ async function exportBenchPackageResult(parsed) {
10785
11188
  process.exit(1);
10786
11189
  }
10787
11190
  const result = await loadBenchmarkResult(summary.path);
10788
- const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(path22.dirname(summary.path), result.meta.id) : void 0;
11191
+ const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(path23.dirname(summary.path), result.meta.id) : void 0;
10789
11192
  const rendered = renderBenchmarkResultExport(result, parsed.format, {
10790
11193
  ...reportCardProvenance ? { reportCardProvenance } : {}
10791
11194
  });
10792
11195
  if (parsed.output) {
10793
- fs32.mkdirSync(path22.dirname(parsed.output), { recursive: true });
11196
+ fs32.mkdirSync(path23.dirname(parsed.output), { recursive: true });
10794
11197
  fs32.writeFileSync(parsed.output, rendered);
10795
11198
  console.log(`Exported ${summary.id} as ${parsed.format} to ${parsed.output}`);
10796
11199
  return;
@@ -10812,7 +11215,7 @@ async function manageBenchDatasets(parsed) {
10812
11215
  return {
10813
11216
  benchmark: benchmarkId,
10814
11217
  downloaded: discovered !== void 0,
10815
- path: discovered ? discovered.dir : path22.join(datasetRoot, benchmarkId),
11218
+ path: discovered ? discovered.dir : path23.join(datasetRoot, benchmarkId),
10816
11219
  source: discovered?.source ?? "canonical"
10817
11220
  };
10818
11221
  });
@@ -10847,7 +11250,7 @@ async function manageBenchDatasets(parsed) {
10847
11250
  runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, parsed.json === true);
10848
11251
  downloaded.push({
10849
11252
  benchmark: benchmarkId,
10850
- path: path22.join(datasetRoot, benchmarkId)
11253
+ path: path23.join(datasetRoot, benchmarkId)
10851
11254
  });
10852
11255
  }
10853
11256
  if (parsed.json) {
@@ -10986,10 +11389,10 @@ async function calibrateBenchJudges(parsed, rawArgs) {
10986
11389
  }
10987
11390
  const bench = await loadBenchModule();
10988
11391
  const resultsDir = expandTilde(
10989
- parsed.resultsDir ?? path22.join(resolveHomeDir(), ".remnic", "bench", "results")
11392
+ parsed.resultsDir ?? path23.join(resolveHomeDir(), ".remnic", "bench", "results")
10990
11393
  );
10991
11394
  const calibrationDir = expandTilde(
10992
- parsed.calibrationDir ?? path22.join(resolveHomeDir(), ".remnic", "bench", "calibration")
11395
+ parsed.calibrationDir ?? path23.join(resolveHomeDir(), ".remnic", "bench", "calibration")
10993
11396
  );
10994
11397
  const stored = await bench.listBenchmarkResults(resultsDir);
10995
11398
  const allForBenchmark = stored.filter((entry) => entry.benchmark === benchmarkId);
@@ -11548,9 +11951,9 @@ async function loadPublishedPromotionHelpers() {
11548
11951
  const benchModule = await loadBenchModule();
11549
11952
  return {
11550
11953
  async promoteArtifactsToPublished(args) {
11551
- const { mkdirSync, readFileSync: readFileSync5, writeFileSync } = await import("fs");
11552
- const path23 = await import("path");
11553
- mkdirSync(args.publishedOutDir, { recursive: true });
11954
+ const { mkdirSync: mkdirSync2, readFileSync: readFileSync6, writeFileSync: writeFileSync2 } = await import("fs");
11955
+ const path24 = await import("path");
11956
+ mkdirSync2(args.publishedOutDir, { recursive: true });
11554
11957
  if (args.artifactPaths.length === 0) {
11555
11958
  console.warn(
11556
11959
  `[bench published] No artifacts produced for ${args.benchmarkId}; nothing to promote.`
@@ -11558,7 +11961,7 @@ async function loadPublishedPromotionHelpers() {
11558
11961
  return;
11559
11962
  }
11560
11963
  for (const artifactPath of args.artifactPaths) {
11561
- const raw = readFileSync5(artifactPath, "utf8");
11964
+ const raw = readFileSync6(artifactPath, "utf8");
11562
11965
  const parsedUnknown = JSON.parse(raw);
11563
11966
  const parsedObj = parsedUnknown !== null && typeof parsedUnknown === "object" && !Array.isArray(parsedUnknown) ? parsedUnknown : {};
11564
11967
  const gitShaShort = (parsedObj.meta?.gitSha ?? "unknown").slice(0, 7);
@@ -11566,13 +11969,13 @@ async function loadPublishedPromotionHelpers() {
11566
11969
  const modelSlug = args.model.replace(/[^a-zA-Z0-9_.-]/g, "-");
11567
11970
  const rawProfile = parsedObj.config?.runtimeProfile;
11568
11971
  const profileSlug = typeof rawProfile === "string" && rawProfile.length > 0 ? `-${rawProfile.replace(/[^a-zA-Z0-9_.-]/g, "-")}` : "";
11569
- const target = path23.join(
11972
+ const target = path24.join(
11570
11973
  args.publishedOutDir,
11571
11974
  `${today}-${args.benchmarkId}-${modelSlug}${profileSlug}-${gitShaShort}.json`
11572
11975
  );
11573
- writeFileSync(target, raw, "utf8");
11976
+ writeFileSync2(target, raw, "utf8");
11574
11977
  console.log(
11575
- `[bench published] Promoted ${path23.basename(artifactPath)} \u2192 ${target}`
11978
+ `[bench published] Promoted ${path24.basename(artifactPath)} \u2192 ${target}`
11576
11979
  );
11577
11980
  }
11578
11981
  void benchModule;
@@ -11679,7 +12082,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
11679
12082
  const previousCodexDiagnosticsDir = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV];
11680
12083
  const previousCodexDiagnosticsMode = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_MODE_ENV];
11681
12084
  if (!previousCodexDiagnosticsDir) {
11682
- process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] = path22.join(
12085
+ process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] = path23.join(
11683
12086
  outputDir,
11684
12087
  "codex-cli-diagnostics"
11685
12088
  );
@@ -11829,7 +12232,7 @@ async function preparePersistedJudgeCalibrationAttachment(benchModule, benchmark
11829
12232
  );
11830
12233
  }
11831
12234
  const calibrationDir = expandTilde(
11832
- calibrationBinding.calibrationDir ?? path22.join(resolveHomeDir(), ".remnic", "bench", "calibration")
12235
+ calibrationBinding.calibrationDir ?? path23.join(resolveHomeDir(), ".remnic", "bench", "calibration")
11833
12236
  );
11834
12237
  const state = await benchModule.loadJudgeCalibrationState?.(benchmarkId, calibrationDir);
11835
12238
  if (!state) {
@@ -12311,7 +12714,7 @@ async function resolvePackageBenchRuntime(benchModule, parsed, runtimeProfile) {
12311
12714
  );
12312
12715
  }
12313
12716
  function normalizeMemoryDirPath(memoryDir) {
12314
- return path22.resolve(expandTilde(memoryDir));
12717
+ return path23.resolve(expandTilde(memoryDir));
12315
12718
  }
12316
12719
  function resolveMemoryDir() {
12317
12720
  const configMemoryDir = (() => {
@@ -12324,9 +12727,9 @@ function resolveMemoryDir() {
12324
12727
  return normalizeMemoryDirPath(remnicCfg.memoryDir);
12325
12728
  }
12326
12729
  const home = resolveHomeDir();
12327
- const standalonePath = path22.join(home, ".remnic", "memory");
12328
- const legacyStandalonePath = path22.join(home, ".engram", "memory");
12329
- const openclawPath = path22.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
12730
+ const standalonePath = path23.join(home, ".remnic", "memory");
12731
+ const legacyStandalonePath = path23.join(home, ".engram", "memory");
12732
+ const openclawPath = path23.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
12330
12733
  if (fs32.existsSync(standalonePath)) return standalonePath;
12331
12734
  if (fs32.existsSync(legacyStandalonePath)) return legacyStandalonePath;
12332
12735
  return openclawPath;
@@ -12375,21 +12778,21 @@ function resolveFlagStrict(args, flag) {
12375
12778
  var REMNIC_OPENCLAW_LEGACY_PLUGIN_ID = "openclaw-engram";
12376
12779
  function resolveOpenclawStateDir() {
12377
12780
  const configuredStateDir = process.env.OPENCLAW_STATE_DIR?.trim();
12378
- return configuredStateDir ? path22.resolve(expandTilde(configuredStateDir)) : path22.join(resolveHomeDir(), ".openclaw");
12781
+ return configuredStateDir ? path23.resolve(expandTilde(configuredStateDir)) : path23.join(resolveHomeDir(), ".openclaw");
12379
12782
  }
12380
12783
  var DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR = [
12381
12784
  process.env.OPENCLAW_CONFIG_PATH,
12382
12785
  process.env.OPENCLAW_ENGRAM_CONFIG_PATH,
12383
- path22.join(resolveOpenclawStateDir(), "openclaw.json")
12786
+ path23.join(resolveOpenclawStateDir(), "openclaw.json")
12384
12787
  ].filter(Boolean);
12385
12788
  function resolveOpenclawConfigPath(cliPath) {
12386
- if (cliPath) return path22.resolve(expandTilde(cliPath));
12789
+ if (cliPath) return path23.resolve(expandTilde(cliPath));
12387
12790
  const envPath = process.env.OPENCLAW_CONFIG_PATH || process.env.OPENCLAW_ENGRAM_CONFIG_PATH;
12388
- if (envPath) return path22.resolve(expandTilde(envPath));
12791
+ if (envPath) return path23.resolve(expandTilde(envPath));
12389
12792
  for (const candidate of DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR) {
12390
12793
  if (fs32.existsSync(candidate)) return candidate;
12391
12794
  }
12392
- return path22.join(resolveOpenclawStateDir(), "openclaw.json");
12795
+ return path23.join(resolveOpenclawStateDir(), "openclaw.json");
12393
12796
  }
12394
12797
  function readOpenclawConfig(configPath) {
12395
12798
  if (!fs32.existsSync(configPath)) return {};
@@ -12448,10 +12851,10 @@ function buildRemnicOpenclawHooksPolicy(legacyHooks, existingHooks) {
12448
12851
  function resolveOpenclawInstallMemoryDir(args) {
12449
12852
  const existingMemoryDir = (typeof args.existingNewEntryConfig.memoryDir === "string" ? args.existingNewEntryConfig.memoryDir : void 0) || (args.migrateLegacy && typeof args.legacyConfigToMerge.memoryDir === "string" ? args.legacyConfigToMerge.memoryDir : void 0);
12450
12853
  if (args.requestedMemoryDir) {
12451
- return path22.resolve(expandTilde(args.requestedMemoryDir));
12854
+ return path23.resolve(expandTilde(args.requestedMemoryDir));
12452
12855
  }
12453
12856
  if (existingMemoryDir) {
12454
- return path22.resolve(expandTilde(existingMemoryDir));
12857
+ return path23.resolve(expandTilde(existingMemoryDir));
12455
12858
  }
12456
12859
  return args.fallbackMemoryDir;
12457
12860
  }
@@ -12469,21 +12872,21 @@ function resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir) {
12469
12872
  if (!config || typeof config !== "object" || Array.isArray(config)) continue;
12470
12873
  const memoryDir = config.memoryDir;
12471
12874
  if (typeof memoryDir === "string" && memoryDir.trim().length > 0) {
12472
- return path22.resolve(expandTilde(memoryDir));
12875
+ return path23.resolve(expandTilde(memoryDir));
12473
12876
  }
12474
12877
  }
12475
12878
  return fallbackMemoryDir;
12476
12879
  }
12477
12880
  function resolveOpenclawPluginDir(cliPath) {
12478
- if (cliPath) return path22.resolve(expandTilde(cliPath));
12881
+ if (cliPath) return path23.resolve(expandTilde(cliPath));
12479
12882
  return resolveOpenclawManagedPluginDir();
12480
12883
  }
12481
12884
  function resolveOpenclawManagedPluginDir() {
12482
- return path22.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
12885
+ return path23.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
12483
12886
  }
12484
12887
  function resolveOpenclawLegacyPluginDir(cliPath) {
12485
- if (cliPath) return path22.resolve(expandTilde(cliPath));
12486
- return path22.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID);
12888
+ if (cliPath) return path23.resolve(expandTilde(cliPath));
12889
+ return path23.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID);
12487
12890
  }
12488
12891
  function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
12489
12892
  const yyyy = now.getFullYear().toString();
@@ -12496,7 +12899,7 @@ function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
12496
12899
  }
12497
12900
  function backupPathIfPresent(sourcePath, backupPath) {
12498
12901
  if (!fs32.existsSync(sourcePath)) return false;
12499
- fs32.mkdirSync(path22.dirname(backupPath), { recursive: true });
12902
+ fs32.mkdirSync(path23.dirname(backupPath), { recursive: true });
12500
12903
  fs32.cpSync(sourcePath, backupPath, { recursive: true });
12501
12904
  return true;
12502
12905
  }
@@ -12515,7 +12918,7 @@ function restartOpenclawGateway() {
12515
12918
  });
12516
12919
  }
12517
12920
  function cmdInit() {
12518
- const configPath = path22.join(process.cwd(), "remnic.config.json");
12921
+ const configPath = path23.join(process.cwd(), "remnic.config.json");
12519
12922
  if (fs32.existsSync(configPath)) {
12520
12923
  console.log(`Config already exists: ${configPath}`);
12521
12924
  return;
@@ -12523,7 +12926,7 @@ function cmdInit() {
12523
12926
  const template = {
12524
12927
  remnic: {
12525
12928
  openaiApiKey: "${OPENAI_API_KEY}",
12526
- memoryDir: path22.join(process.cwd(), ".remnic", "memory"),
12929
+ memoryDir: path23.join(process.cwd(), ".remnic", "memory"),
12527
12930
  memoryOsPreset: "balanced"
12528
12931
  },
12529
12932
  server: {
@@ -12585,7 +12988,7 @@ async function cmdStatus(json) {
12585
12988
  console.log(`Remnic server: running${pid ? ` (pid ${pid})` : ""}`);
12586
12989
  await printHealthCheck(resolveDaemonBaseUrl(resolveConfigPath()), resolveStatusProbeToken());
12587
12990
  }
12588
- async function oauthFetch(method, path23, token, body) {
12991
+ async function oauthFetch(method, path24, token, body) {
12589
12992
  const controller = new AbortController();
12590
12993
  const timeoutId = setTimeout(() => controller.abort(), 5e3);
12591
12994
  try {
@@ -12604,7 +13007,7 @@ async function oauthFetch(method, path23, token, body) {
12604
13007
  if (body !== void 0) {
12605
13008
  init.body = JSON.stringify(body);
12606
13009
  }
12607
- const response = await fetch(`${resolveDaemonBaseUrl(resolveConfigPath())}${path23}`, init);
13010
+ const response = await fetch(`${resolveDaemonBaseUrl(resolveConfigPath())}${path24}`, init);
12608
13011
  if (response.status === 401) {
12609
13012
  throw new Error(
12610
13013
  "operator token rejected by remnic-server (HTTP 401). Update `server.authToken` or `REMNIC_AUTH_TOKEN` to match the running daemon."
@@ -13154,6 +13557,82 @@ function xrayCliIo(recallXray) {
13154
13557
  stdout: (line) => console.log(line)
13155
13558
  };
13156
13559
  }
13560
+ function extractWhyRawArgs(rest) {
13561
+ const VALUE_FLAGS = /* @__PURE__ */ new Set(["--format", "--expect", "--namespace", "--session", "--out"]);
13562
+ const positional = [];
13563
+ const options = {};
13564
+ for (let i = 0; i < rest.length; i++) {
13565
+ const token = rest[i];
13566
+ if (token.startsWith("--")) {
13567
+ if (!VALUE_FLAGS.has(token)) {
13568
+ throw new Error(
13569
+ `Unknown flag ${JSON.stringify(token)}. Supported flags: --format, --expect, --namespace, --session, --out.`
13570
+ );
13571
+ }
13572
+ const next = rest[i + 1];
13573
+ if (next === void 0 || next.startsWith("--")) {
13574
+ throw new Error(
13575
+ `${token} requires a value. Provide it as \`${token} <value>\`, not as a bare flag.`
13576
+ );
13577
+ }
13578
+ options[token.slice(2)] = next;
13579
+ i++;
13580
+ continue;
13581
+ }
13582
+ positional.push(token);
13583
+ }
13584
+ return { rawQuery: positional.join(" "), options };
13585
+ }
13586
+ async function runWhyCommand(rest, io) {
13587
+ const { rawQuery, options } = extractWhyRawArgs(rest);
13588
+ const parsed = parseWhyCliOptions(rawQuery, options);
13589
+ const response = await io.recallWhy({
13590
+ query: parsed.query,
13591
+ ...parsed.expect !== void 0 ? { expect: parsed.expect } : {},
13592
+ ...parsed.session !== void 0 ? { sessionKey: parsed.session } : {},
13593
+ ...parsed.namespace !== void 0 ? { namespace: parsed.namespace } : {}
13594
+ });
13595
+ if (!response.reportFound || response.report === void 0) {
13596
+ throw new Error(
13597
+ "recall diagnosis unavailable: the requested namespace is not readable by this caller"
13598
+ );
13599
+ }
13600
+ const rendered = renderRecallWhy(response.report, parsed.format);
13601
+ if (parsed.outPath !== void 0) {
13602
+ await io.writeFile(expandTildePath(parsed.outPath), rendered);
13603
+ } else {
13604
+ io.stdout(rendered);
13605
+ }
13606
+ }
13607
+ async function cmdWhy(rest) {
13608
+ const { rawQuery, options } = extractWhyRawArgs(rest);
13609
+ parseWhyCliOptions(rawQuery, options);
13610
+ const remote = resolveRemoteDaemon(resolveConfigPath());
13611
+ if (remote) {
13612
+ await runWhyCommand(rest, whyCliIo((request) => remoteRecallWhy(remote, request)));
13613
+ return;
13614
+ }
13615
+ initLogger5();
13616
+ const configPath = resolveConfigPath();
13617
+ const raw = fs32.existsSync(configPath) ? JSON.parse(fs32.readFileSync(configPath, "utf8")) : {};
13618
+ const config = parseConfig17(resolveRemnicConfigRecord16(raw));
13619
+ const orchestrator = new Orchestrator11(config);
13620
+ await orchestrator.initialize();
13621
+ await orchestrator.deferredReady;
13622
+ const service = new EngramAccessService2(orchestrator);
13623
+ try {
13624
+ await runWhyCommand(rest, whyCliIo((request) => service.recallWhy(request)));
13625
+ } finally {
13626
+ orchestrator.abortDeferredInit();
13627
+ }
13628
+ }
13629
+ function whyCliIo(recallWhy) {
13630
+ return {
13631
+ recallWhy,
13632
+ writeFile: (filePath, data) => fsWriteFile(filePath, data, "utf8"),
13633
+ stdout: (line) => console.log(line)
13634
+ };
13635
+ }
13157
13636
  async function runWhoKnowsCommand(rest, io) {
13158
13637
  const { topic, options } = extractWhoKnowsRawArgs(rest);
13159
13638
  const parsed = parseWhoKnowsCliOptions(topic, options);
@@ -13222,7 +13701,7 @@ async function cmdVersions(rest) {
13222
13701
  console.error("Usage: remnic versions list <page-path>");
13223
13702
  process.exit(1);
13224
13703
  }
13225
- const absPath = path22.resolve(pagePath);
13704
+ const absPath = path23.resolve(pagePath);
13226
13705
  const history = await listVersions(absPath, versioningConfig, memDir);
13227
13706
  if (json) {
13228
13707
  console.log(JSON.stringify(history, null, 2));
@@ -13247,7 +13726,7 @@ async function cmdVersions(rest) {
13247
13726
  console.error("Usage: remnic versions show <page-path> <version-id>");
13248
13727
  process.exit(1);
13249
13728
  }
13250
- const absPath = path22.resolve(pagePath);
13729
+ const absPath = path23.resolve(pagePath);
13251
13730
  try {
13252
13731
  const content = await getVersion(absPath, versionId, versioningConfig, memDir);
13253
13732
  console.log(content);
@@ -13265,7 +13744,7 @@ async function cmdVersions(rest) {
13265
13744
  console.error("Usage: remnic versions diff <page-path> <v1> <v2>");
13266
13745
  process.exit(1);
13267
13746
  }
13268
- const absPath = path22.resolve(pagePath);
13747
+ const absPath = path23.resolve(pagePath);
13269
13748
  try {
13270
13749
  const diffOutput = await diffVersions(absPath, v1, v2, versioningConfig, memDir);
13271
13750
  console.log(diffOutput);
@@ -13282,7 +13761,7 @@ async function cmdVersions(rest) {
13282
13761
  console.error("Usage: remnic versions revert <page-path> <version-id>");
13283
13762
  process.exit(1);
13284
13763
  }
13285
- const absPath = path22.resolve(pagePath);
13764
+ const absPath = path23.resolve(pagePath);
13286
13765
  try {
13287
13766
  const version = await revertToVersion(absPath, versionId, versioningConfig, void 0, memDir);
13288
13767
  if (json) {
@@ -13322,7 +13801,7 @@ async function cmdEnrich(rest) {
13322
13801
  const subcommand = rest[0];
13323
13802
  if (subcommand === "audit") {
13324
13803
  const memoryDir2 = expandTilde(config.memoryDir);
13325
- const auditDir2 = path22.join(memoryDir2, "enrichment");
13804
+ const auditDir2 = path23.join(memoryDir2, "enrichment");
13326
13805
  const sinceFlag = resolveFlag(rest.slice(1), "--since");
13327
13806
  const entries = await readAuditLog(auditDir2, sinceFlag ?? void 0);
13328
13807
  if (entries.length === 0) {
@@ -13447,7 +13926,7 @@ Registered providers:`);
13447
13926
  return;
13448
13927
  }
13449
13928
  const memoryDir = expandTilde(config.memoryDir);
13450
- const auditDir = path22.join(memoryDir, "enrichment");
13929
+ const auditDir = path23.join(memoryDir, "enrichment");
13451
13930
  let totalPersisted = 0;
13452
13931
  for (const result of results) {
13453
13932
  for (const candidate of result.acceptedCandidates) {
@@ -13570,7 +14049,7 @@ Root: ${root}`);
13570
14049
  const validNames = new Set(extensions.map((e) => e.name));
13571
14050
  let errors = 0;
13572
14051
  for (const entry of entries) {
13573
- const entryPath = path22.join(root, entry);
14052
+ const entryPath = path23.join(root, entry);
13574
14053
  try {
13575
14054
  if (!fs32.statSync(entryPath).isDirectory()) continue;
13576
14055
  } catch {
@@ -13701,7 +14180,7 @@ ${section}
13701
14180
  const saveDir = resolveBriefingSaveDir(config.briefing.saveDir);
13702
14181
  fs32.mkdirSync(saveDir, { recursive: true });
13703
14182
  const filename = briefingFilename(new Date(result.window.to), format);
13704
- const filePath = path22.join(saveDir, filename);
14183
+ const filePath = path23.join(saveDir, filename);
13705
14184
  fs32.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
13706
14185
  console.error(`Saved briefing: ${filePath}`);
13707
14186
  } catch (err) {
@@ -13857,7 +14336,7 @@ async function cmdDoctor() {
13857
14336
  const rawMemoryDir = entryConfig?.memoryDir;
13858
14337
  const configuredMemoryDir = typeof rawMemoryDir === "string" ? rawMemoryDir : void 0;
13859
14338
  if (configuredMemoryDir) {
13860
- const resolvedMemDir = path22.resolve(expandTilde(configuredMemoryDir));
14339
+ const resolvedMemDir = path23.resolve(expandTilde(configuredMemoryDir));
13861
14340
  let memDirOk = false;
13862
14341
  let memDirDetail = `${resolvedMemDir} (not found)`;
13863
14342
  let memDirRemediation = `Run \`remnic openclaw install --memory-dir "${resolvedMemDir}"\` to create the directory.`;
@@ -14070,7 +14549,7 @@ async function cmdMigrate(json, rollback) {
14070
14549
  console.log(` Rollback: ${result.rollbackCommand}`);
14071
14550
  }
14072
14551
  function cmdOnboard(dirPath, json) {
14073
- const directory = path22.resolve(dirPath || process.cwd());
14552
+ const directory = path23.resolve(dirPath || process.cwd());
14074
14553
  const result = onboard({ directory });
14075
14554
  if (json) {
14076
14555
  console.log(JSON.stringify(result, null, 2));
@@ -14089,7 +14568,7 @@ Suggested namespace: ${result.plan.suggestedNamespace}`);
14089
14568
  async function cmdCurate(targetPath, json) {
14090
14569
  const memoryDir = resolveMemoryDir();
14091
14570
  const result = await curate({
14092
- targetPath: path22.resolve(targetPath),
14571
+ targetPath: path23.resolve(targetPath),
14093
14572
  memoryDir,
14094
14573
  source: "curation",
14095
14574
  checkDuplicates: true,
@@ -14218,8 +14697,8 @@ async function cmdSync(action, rest, json) {
14218
14697
  }
14219
14698
  }
14220
14699
  function localOfflineSourceId(memoryDir) {
14221
- const host = os3.hostname() || "unknown-host";
14222
- const dirHash = createHash6("sha256").update(path22.resolve(memoryDir)).digest("hex").slice(0, 16);
14700
+ const host = os4.hostname() || "unknown-host";
14701
+ const dirHash = createHash6("sha256").update(path23.resolve(memoryDir)).digest("hex").slice(0, 16);
14223
14702
  return `remnic-local:${host}:${dirHash}`;
14224
14703
  }
14225
14704
  function normalizeOfflineRemoteUrl(raw) {
@@ -14628,10 +15107,10 @@ var OFFLINE_SYNC_CONTENT_MISSING_RETRY_MAX = 3;
14628
15107
  var OFFLINE_SYNC_CONTENT_MISSING_RETRY_DELAY_MS = 250;
14629
15108
  var OfflineRemoteFileChangedError = class extends Error {
14630
15109
  path;
14631
- constructor(path23) {
14632
- super(`remote file changed while fetching offline content: ${path23}`);
15110
+ constructor(path24) {
15111
+ super(`remote file changed while fetching offline content: ${path24}`);
14633
15112
  this.name = "OfflineRemoteFileChangedError";
14634
- this.path = path23;
15113
+ this.path = path24;
14635
15114
  }
14636
15115
  };
14637
15116
  function isOfflineRemoteFileChangedError(error) {
@@ -14892,7 +15371,7 @@ async function pushOfflineFileContentFromChunkReader(args) {
14892
15371
  }
14893
15372
  const hash = createHash6("sha256");
14894
15373
  const chunks = args.readFileChunks({
14895
- root: path22.resolve(args.memoryDir),
15374
+ root: path23.resolve(args.memoryDir),
14896
15375
  path: args.file.path,
14897
15376
  filePath,
14898
15377
  chunkSize: OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES
@@ -16006,7 +16485,7 @@ Environment fallbacks:
16006
16485
  REMNIC_OFFLINE_TOKEN > REMNIC_AUTH_TOKEN > ENGRAM_AUTH_TOKEN.`);
16007
16486
  return;
16008
16487
  }
16009
- const memoryDir = path22.resolve(expandTilde(resolveRequiredValueFlag(rest, "--memory-dir") ?? resolveMemoryDir()));
16488
+ const memoryDir = path23.resolve(expandTilde(resolveRequiredValueFlag(rest, "--memory-dir") ?? resolveMemoryDir()));
16010
16489
  const namespace = resolveRequiredValueFlag(rest, "--namespace");
16011
16490
  const includeTranscripts = !hasFlag(rest, "--no-transcripts");
16012
16491
  const stateOverride = resolveRequiredValueFlag(rest, "--state");
@@ -16027,7 +16506,7 @@ Environment fallbacks:
16027
16506
  const remoteUrl = needsRemote ? resolveOfflineRemoteUrl(rest) : resolveOptionalOfflineRemoteUrl(rest);
16028
16507
  const knownAction = needsRemote || action === "status";
16029
16508
  const token = knownAction ? resolveOfflineToken(rest) : void 0;
16030
- const statePath = statePathExplicit ? path22.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
16509
+ const statePath = statePathExplicit ? path23.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
16031
16510
  if (action === "prepare") {
16032
16511
  if (!remoteUrl || !token || !statePath) throw new Error("offline prepare requires remote URL and token");
16033
16512
  fs32.mkdirSync(memoryDir, { recursive: true });
@@ -16209,11 +16688,11 @@ Environment fallbacks:
16209
16688
  failures: result.largeFilePushFailures
16210
16689
  });
16211
16690
  largeFileFailureCounts = advanced.counts;
16212
- for (const path23 of advanced.newlySkipped) {
16213
- if (skippedLargeFiles.has(path23)) continue;
16214
- skippedLargeFiles.add(path23);
16691
+ for (const path24 of advanced.newlySkipped) {
16692
+ if (skippedLargeFiles.has(path24)) continue;
16693
+ skippedLargeFiles.add(path24);
16215
16694
  console.warn(
16216
- `offline sync: permanently skipping ${path23} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
16695
+ `offline sync: permanently skipping ${path24} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
16217
16696
  );
16218
16697
  }
16219
16698
  const pulled = result.pull ? result.pull.upserted + result.pull.deleted : 0;
@@ -16228,11 +16707,11 @@ Environment fallbacks:
16228
16707
  failures: error.failures
16229
16708
  });
16230
16709
  largeFileFailureCounts = advanced.counts;
16231
- for (const path23 of advanced.newlySkipped) {
16232
- if (skippedLargeFiles.has(path23)) continue;
16233
- skippedLargeFiles.add(path23);
16710
+ for (const path24 of advanced.newlySkipped) {
16711
+ if (skippedLargeFiles.has(path24)) continue;
16712
+ skippedLargeFiles.add(path24);
16234
16713
  console.warn(
16235
- `offline sync: permanently skipping ${path23} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
16714
+ `offline sync: permanently skipping ${path24} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
16236
16715
  );
16237
16716
  }
16238
16717
  }
@@ -16373,7 +16852,7 @@ async function cmdConnectors(action, rest, json) {
16373
16852
  const connectorDaemonUrl = typeof effectiveConnectorConfig.remnicDaemonUrl === "string" && effectiveConnectorConfig.remnicDaemonUrl.trim().length > 0 ? effectiveConnectorConfig.remnicDaemonUrl.trim() : void 0;
16374
16853
  const pubResult = await pub.publish({
16375
16854
  config: { memoryDir, namespace: connectorNamespace, daemonUrl: connectorDaemonUrl },
16376
- skillsRoot: path22.join(memoryDir, "skills"),
16855
+ skillsRoot: path23.join(memoryDir, "skills"),
16377
16856
  rollbackTokenEntry: preInstallTokenEntry,
16378
16857
  log: { info: console.log, warn: console.warn, error: console.error }
16379
16858
  });
@@ -16733,15 +17212,15 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
16733
17212
  }
16734
17213
  const manifest = generateMarketplaceManifest();
16735
17214
  await writeMarketplaceManifest(outputDir, manifest);
16736
- const outPath = path22.join(outputDir, "marketplace.json");
17215
+ const outPath = path23.join(outputDir, "marketplace.json");
16737
17216
  if (json) {
16738
17217
  console.log(JSON.stringify({ status: "generated", path: outPath }, null, 2));
16739
17218
  } else {
16740
17219
  console.log(`Generated marketplace.json at ${outPath}`);
16741
17220
  }
16742
17221
  } else if (subAction === "validate") {
16743
- const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path22.join(process.cwd(), "marketplace.json");
16744
- const resolved = path22.resolve(targetPath);
17222
+ const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path23.join(process.cwd(), "marketplace.json");
17223
+ const resolved = path23.resolve(targetPath);
16745
17224
  if (!fs32.existsSync(resolved)) {
16746
17225
  console.error(`File not found: ${resolved}`);
16747
17226
  process.exit(1);
@@ -17157,7 +17636,7 @@ async function cmdBench(rest) {
17157
17636
  }
17158
17637
  const completeCount = prevStatus.benchmarks.filter((b) => b.status === "complete").length;
17159
17638
  const failedCount = prevStatus.benchmarks.filter((b) => b.status === "failed").length;
17160
- printBenchStatusLine(parsed.json, `Resuming from: ${path22.basename(latestStatusPath)}`);
17639
+ printBenchStatusLine(parsed.json, `Resuming from: ${path23.basename(latestStatusPath)}`);
17161
17640
  printBenchStatusLine(parsed.json, ` Previous run: ${prevStatus.startedAt}`);
17162
17641
  printBenchStatusLine(parsed.json, ` Benchmarks: ${prevStatus.benchmarks.length} total, ${completeCount} complete, ${failedCount} failed`);
17163
17642
  const before = selectedBenchmarks.length;
@@ -17322,9 +17801,9 @@ Options:
17322
17801
  );
17323
17802
  process.exit(1);
17324
17803
  } else {
17325
- fixturePath = path22.resolve(expandTilde(fixturePathRaw));
17804
+ fixturePath = path23.resolve(expandTilde(fixturePathRaw));
17326
17805
  }
17327
- const outPath = path22.resolve(expandTilde(outPathRaw));
17806
+ const outPath = path23.resolve(expandTilde(outPathRaw));
17328
17807
  const benchModule = await loadBenchModule();
17329
17808
  const runner = benchModule.runProceduralAblationCli;
17330
17809
  if (typeof runner !== "function") {
@@ -17343,7 +17822,7 @@ Options:
17343
17822
  );
17344
17823
  console.log(`wrote ${outPath}`);
17345
17824
  }
17346
- var LOGS_DIR = path22.join(PID_DIR, "logs");
17825
+ var LOGS_DIR = path23.join(PID_DIR, "logs");
17347
17826
  var LAUNCHD_PLIST_PATHS = launchdPlistPaths(resolveHomeDir());
17348
17827
  var [LAUNCHD_PLIST_PATH] = LAUNCHD_PLIST_PATHS;
17349
17828
  var SYSTEMD_UNIT_PATHS = systemdUnitPaths(resolveHomeDir());
@@ -17420,7 +17899,7 @@ function selectLaunchdInspection(openclawPluginModeConfigured) {
17420
17899
  for (const plistPath of LAUNCHD_PLIST_PATHS.slice(1)) {
17421
17900
  const legacy = inspectLaunchdPlist(plistPath);
17422
17901
  if (!legacy.installed) continue;
17423
- const label = path22.basename(plistPath, ".plist");
17902
+ const label = path23.basename(plistPath, ".plist");
17424
17903
  return legacy.ok ? {
17425
17904
  ...legacy,
17426
17905
  warn: true,
@@ -17454,10 +17933,10 @@ function daemonInstall() {
17454
17933
  const vars = { HOME: home, NODE_PATH: nodePath, REMNIC_SERVER_BIN: serverBin };
17455
17934
  fs32.mkdirSync(LOGS_DIR, { recursive: true });
17456
17935
  if (isMacOS()) {
17457
- const templatePath = path22.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
17936
+ const templatePath = path23.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
17458
17937
  const template = fs32.readFileSync(templatePath, "utf8");
17459
17938
  const plist = renderTemplate(template, vars);
17460
- fs32.mkdirSync(path22.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
17939
+ fs32.mkdirSync(path23.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
17461
17940
  fs32.writeFileSync(LAUNCHD_PLIST_PATH, plist);
17462
17941
  try {
17463
17942
  launchdLoadPlist(LAUNCHD_PLIST_PATH);
@@ -17474,10 +17953,10 @@ function daemonInstall() {
17474
17953
  console.log(` RunAtLoad: true, KeepAlive: true`);
17475
17954
  console.log(` Logs: ${LOGS_DIR}/daemon.log`);
17476
17955
  } else if (isLinux()) {
17477
- const templatePath = path22.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
17956
+ const templatePath = path23.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
17478
17957
  const template = fs32.readFileSync(templatePath, "utf8");
17479
17958
  const unit = renderTemplate(template, vars);
17480
- fs32.mkdirSync(path22.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
17959
+ fs32.mkdirSync(path23.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
17481
17960
  fs32.writeFileSync(SYSTEMD_UNIT_PATH, unit);
17482
17961
  try {
17483
17962
  childProcess2.execSync("systemctl --user daemon-reload", { stdio: "pipe" });
@@ -17976,7 +18455,7 @@ Clean complete: cleaned=${result.cleaned}`
17976
18455
  }
17977
18456
  async function cmdOpenclawInstall(opts) {
17978
18457
  const configPath = resolveOpenclawConfigPath(opts.configPath);
17979
- const fallbackMemoryDir = path22.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
18458
+ const fallbackMemoryDir = path23.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
17980
18459
  console.log(`OpenClaw config: ${configPath}`);
17981
18460
  const existingConfig = readOpenclawConfig(configPath);
17982
18461
  const { plugins, entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
@@ -18079,7 +18558,7 @@ Remove it first and re-run, or choose a different path with --memory-dir.`
18079
18558
  fs32.mkdirSync(memoryDir, { recursive: true });
18080
18559
  console.log(`Created memory directory: ${memoryDir}`);
18081
18560
  }
18082
- const configDir = path22.dirname(configPath);
18561
+ const configDir = path23.dirname(configPath);
18083
18562
  if (!fs32.existsSync(configDir)) {
18084
18563
  fs32.mkdirSync(configDir, { recursive: true });
18085
18564
  }
@@ -18108,12 +18587,12 @@ async function cmdOpenclawUpgrade(opts) {
18108
18587
  const pluginDir = resolveOpenclawPluginDir(opts.pluginDir);
18109
18588
  const managedTargetDir = resolveOpenclawManagedPluginDir();
18110
18589
  const legacyPluginDirForBackup = opts.legacyPluginDirForBackup ? resolveOpenclawLegacyPluginDir(opts.legacyPluginDirForBackup) : void 0;
18111
- const fallbackMemoryDir = path22.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
18590
+ const fallbackMemoryDir = path23.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
18112
18591
  const packageSpec = buildOpenclawManagedUpgradePackageSpec(opts.version);
18113
18592
  const configExistedBefore = fs32.existsSync(configPath);
18114
18593
  const existingConfig = readOpenclawConfig(configPath);
18115
18594
  const { entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
18116
- const preservedMemoryDir = opts.memoryDir ? path22.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
18595
+ const preservedMemoryDir = opts.memoryDir ? path23.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
18117
18596
  console.log(`OpenClaw config: ${configPath}`);
18118
18597
  console.log(`Plugin dir: ${pluginDir}`);
18119
18598
  if (legacyPluginDirForBackup) {
@@ -18121,7 +18600,7 @@ async function cmdOpenclawUpgrade(opts) {
18121
18600
  }
18122
18601
  console.log(`Memory dir: ${preservedMemoryDir}`);
18123
18602
  console.log(`Package spec: ${packageSpec}`);
18124
- console.log(`Backup root: ${path22.join(resolveOpenclawStateDir(), "backups")}`);
18603
+ console.log(`Backup root: ${path23.join(resolveOpenclawStateDir(), "backups")}`);
18125
18604
  const plannedActions = [
18126
18605
  `backup openclaw.json and the existing ${REMNIC_OPENCLAW_PLUGIN_ID} extension`,
18127
18606
  ...legacyPluginDirForBackup ? [`backup the existing ${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID} extension without modifying it`] : [],
@@ -18159,9 +18638,9 @@ async function cmdOpenclawUpgrade(opts) {
18159
18638
  assertDirectoryPathOrMissing(legacyPluginDirForBackup, "Legacy OpenClaw plugin dir");
18160
18639
  }
18161
18640
  const backupDir = createOpenclawUpgradeBackupDir();
18162
- const configBackupPath = path22.join(backupDir, "openclaw.json");
18163
- const pluginBackupDir = path22.join(backupDir, "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
18164
- const legacyPluginBackupDir = legacyPluginDirForBackup ? path22.join(backupDir, "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID) : void 0;
18641
+ const configBackupPath = path23.join(backupDir, "openclaw.json");
18642
+ const pluginBackupDir = path23.join(backupDir, "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
18643
+ const legacyPluginBackupDir = legacyPluginDirForBackup ? path23.join(backupDir, "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID) : void 0;
18165
18644
  const backupNotes = [];
18166
18645
  if (backupPathIfPresent(configPath, configBackupPath)) {
18167
18646
  backupNotes.push(`+ Backed up config to ${configBackupPath}`);
@@ -18211,7 +18690,7 @@ async function cmdOpenclawUpgrade(opts) {
18211
18690
  const managedRollbackDir = publishedInstallError ? publishedInstallError.managedRollbackDir : installResult?.managedRollbackDir;
18212
18691
  const managedRollbackTargetDir = publishedInstallError?.managedRollbackTargetDir ?? installResult?.managedRollbackTargetDir ?? managedTargetDir;
18213
18692
  const requiresHostManagedRestore = publishedInstallError?.requiresHostManagedRestore ?? installResult?.requiresHostManagedRestore ?? false;
18214
- const managedRollbackSharesPluginDir = managedRollbackDir && path22.resolve(managedRollbackTargetDir) === path22.resolve(pluginDir);
18693
+ const managedRollbackSharesPluginDir = managedRollbackDir && path23.resolve(managedRollbackTargetDir) === path23.resolve(pluginDir);
18215
18694
  const pluginRollbackDir = managedRollbackSharesPluginDir ? requiresHostManagedRestore ? rollbackDir : rollbackDir ?? managedRollbackDir : rollbackDir;
18216
18695
  const shouldRestorePlugin = Boolean(
18217
18696
  installResult && !requiresHostManagedRestore || pluginRollbackDir || publishedInstallError?.shouldRestoreBackup
@@ -18268,7 +18747,7 @@ async function cmdOpenclawUpgrade(opts) {
18268
18747
  rollbackErrors.push(error);
18269
18748
  }
18270
18749
  if (pendingConfigRestoreError) rollbackErrors.push(pendingConfigRestoreError);
18271
- if (managedRollbackDir && path22.resolve(managedRollbackTargetDir) !== path22.resolve(pluginDir) && !requiresHostManagedRestore) {
18750
+ if (managedRollbackDir && path23.resolve(managedRollbackTargetDir) !== path23.resolve(pluginDir) && !requiresHostManagedRestore) {
18272
18751
  try {
18273
18752
  rollbackNotes.push(
18274
18753
  ...rollbackOpenclawUpgrade({
@@ -18334,9 +18813,9 @@ async function cmdOpenclawMigrateEngram(opts) {
18334
18813
  console.log(" - Re-apply any local source patches to the new package only after verifying the published build.");
18335
18814
  }
18336
18815
  function createOpenclawUpgradeBackupDir() {
18337
- const backupsRoot = path22.join(resolveOpenclawStateDir(), "backups");
18816
+ const backupsRoot = path23.join(resolveOpenclawStateDir(), "backups");
18338
18817
  fs32.mkdirSync(backupsRoot, { recursive: true });
18339
- return fs32.mkdtempSync(path22.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
18818
+ return fs32.mkdtempSync(path23.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
18340
18819
  }
18341
18820
  async function cmdTaxonomy(rest) {
18342
18821
  initLogger5();
@@ -18378,8 +18857,8 @@ async function cmdTaxonomy(rest) {
18378
18857
  const doc = generateResolverDocument(taxonomy);
18379
18858
  console.log(doc);
18380
18859
  if (config.taxonomyAutoGenResolver) {
18381
- const resolverPath = path22.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
18382
- fs32.mkdirSync(path22.dirname(resolverPath), { recursive: true });
18860
+ const resolverPath = path23.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
18861
+ fs32.mkdirSync(path23.dirname(resolverPath), { recursive: true });
18383
18862
  fs32.writeFileSync(resolverPath, doc);
18384
18863
  console.error(`Written: ${resolverPath}`);
18385
18864
  }
@@ -18425,7 +18904,7 @@ async function cmdTaxonomy(rest) {
18425
18904
  console.log(`Added category "${id}" (${name}).`);
18426
18905
  if (config.taxonomyAutoGenResolver) {
18427
18906
  const doc = generateResolverDocument(taxonomy);
18428
- const resolverPath = path22.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
18907
+ const resolverPath = path23.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
18429
18908
  fs32.writeFileSync(resolverPath, doc);
18430
18909
  console.error(`Regenerated: ${resolverPath}`);
18431
18910
  }
@@ -18456,7 +18935,7 @@ async function cmdTaxonomy(rest) {
18456
18935
  console.log(`Removed category "${id}".`);
18457
18936
  if (config.taxonomyAutoGenResolver) {
18458
18937
  const doc = generateResolverDocument(taxonomy);
18459
- const resolverPath = path22.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
18938
+ const resolverPath = path23.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
18460
18939
  fs32.writeFileSync(resolverPath, doc);
18461
18940
  console.error(`Regenerated: ${resolverPath}`);
18462
18941
  }
@@ -18738,7 +19217,7 @@ async function runTrainingExport(args, stdout = process.stdout) {
18738
19217
  );
18739
19218
  }
18740
19219
  const formatted = adapter.formatRecords(records);
18741
- const outDir = path22.dirname(args.output);
19220
+ const outDir = path23.dirname(args.output);
18742
19221
  fs32.mkdirSync(outDir, { recursive: true });
18743
19222
  const tmpPath = `${args.output}.tmp-${process.pid}-${Date.now()}`;
18744
19223
  fs32.writeFileSync(tmpPath, formatted, "utf-8");
@@ -18794,6 +19273,9 @@ async function main(argv = process.argv.slice(2)) {
18794
19273
  case "xray":
18795
19274
  await cmdXray(rest);
18796
19275
  break;
19276
+ case "why":
19277
+ await cmdWhy(rest);
19278
+ break;
18797
19279
  case "who-knows":
18798
19280
  await cmdWhoKnows(rest);
18799
19281
  break;
@@ -18806,6 +19288,9 @@ async function main(argv = process.argv.slice(2)) {
18806
19288
  case "doctor":
18807
19289
  await cmdDoctor();
18808
19290
  break;
19291
+ case "report":
19292
+ await cmdReport({ json: rest.includes("--json"), includeBench: rest.includes("--include-bench") });
19293
+ break;
18809
19294
  case "config":
18810
19295
  cmdConfig();
18811
19296
  break;
@@ -18861,7 +19346,7 @@ async function main(argv = process.argv.slice(2)) {
18861
19346
  case "tree": {
18862
19347
  const subAction = rest[0];
18863
19348
  const json = rest.includes("--json");
18864
- const outputDir = resolveFlag(rest, "--output") ?? path22.join(process.cwd(), ".remnic", "context-tree");
19349
+ const outputDir = resolveFlag(rest, "--output") ?? path23.join(process.cwd(), ".remnic", "context-tree");
18865
19350
  const categoriesFlag = resolveFlag(rest, "--categories");
18866
19351
  const categories = categoriesFlag ? categoriesFlag.split(",") : void 0;
18867
19352
  const maxPerCategoryRaw = resolveFlag(rest, "--max-per-category");
@@ -18938,7 +19423,7 @@ async function main(argv = process.argv.slice(2)) {
18938
19423
  console.error(`Context tree not found at ${treeDir}. Run 'remnic tree generate' first.`);
18939
19424
  process.exit(1);
18940
19425
  }
18941
- const indexPath = path22.join(treeDir, "INDEX.md");
19426
+ const indexPath = path23.join(treeDir, "INDEX.md");
18942
19427
  if (!fs32.existsSync(indexPath)) {
18943
19428
  console.error(`INDEX.md missing in ${treeDir}. Tree may be corrupt \u2014 regenerate.`);
18944
19429
  process.exit(1);
@@ -19365,6 +19850,10 @@ Usage:
19365
19850
  remnic xray <query> [--format text|markdown|json] [--budget <chars>] [--namespace <ns>] [--out <path>]
19366
19851
  Run a recall with X-ray capture and print the unified snapshot
19367
19852
  (tier + audit + MMR + filters). Part of #570. Text output by default.
19853
+ remnic why <query> [--expect <id|substring>] [--format markdown|json] [--namespace <ns>] [--session <key>] [--out <path>]
19854
+ Diagnose why a query did NOT recall what you expected (#3033). Prints
19855
+ per-stage candidate counts and drop reasons; with --expect, names the
19856
+ exact stage that dropped that memory plus a remediation hint.
19368
19857
  remnic who-knows <topic> [--limit N] [--json] [--namespace <ns>] Rank entities by topic expertise
19369
19858
  remnic wearables <status|check|sync|transcript|search|memories|speakers|corrections>
19370
19859
  Wearable transcript sources (Limitless / Bee / Omi): pull + clean +
@@ -19547,6 +20036,7 @@ export {
19547
20036
  chunkOfflineChangesetApplyBatches,
19548
20037
  chunkOfflineFileContentBatches,
19549
20038
  directHydrateLargeOfflineFiles,
20039
+ extractWhyRawArgs,
19550
20040
  extractXrayRawArgs,
19551
20041
  fetchOfflineSnapshot,
19552
20042
  formatOfflineLargeFilePushFailureMessage,
@@ -19581,6 +20071,7 @@ export {
19581
20071
  runOfflineSyncOnce,
19582
20072
  runTrainingExport,
19583
20073
  runWhoKnowsCommand,
20074
+ runWhyCommand,
19584
20075
  runXrayCommand,
19585
20076
  shouldDirectHydrateOfflineFile,
19586
20077
  stripConfigArgv,