musememory 1.9.0 → 1.11.0

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 (3) hide show
  1. package/README.md +48 -10
  2. package/dist/index.js +2314 -270
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -68,6 +68,13 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
68
68
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
69
69
 
70
70
  // src/secrets.ts
71
+ var exports_secrets = {};
72
+ __export(exports_secrets, {
73
+ SECRET_RULES: () => SECRET_RULES,
74
+ hasSecret: () => hasSecret,
75
+ redactSecrets: () => redactSecrets,
76
+ scanSecrets: () => scanSecrets
77
+ });
71
78
  function scanSecrets(text) {
72
79
  if (!text || typeof text !== "string")
73
80
  return [];
@@ -79,6 +86,11 @@ function scanSecrets(text) {
79
86
  }
80
87
  return matches;
81
88
  }
89
+ function hasSecret(text) {
90
+ if (!text || typeof text !== "string")
91
+ return false;
92
+ return SECRET_RULES.some((rule) => rule.pattern.test(text));
93
+ }
82
94
  function redactSecrets(text) {
83
95
  if (!text || typeof text !== "string")
84
96
  return text;
@@ -4857,7 +4869,24 @@ function extractHarvestUnits(text) {
4857
4869
  continue;
4858
4870
  }
4859
4871
  const speakerStripped = trimmed.replace(/^(?:user|assistant|human|system|agent|client|developer)\s*[:\-\u2013]\s*/i, "");
4860
- const typeMatch = speakerStripped.match(/^(?:#{1,6}\s+|[-*]\s+)?\*{0,2}(fix|failure|decision|architecture|constraint|operation|preference|discovery|outcome|root cause|learned|rule)\*{0,2}\s*[:\-\u2013]\s*(.*)$/i);
4872
+ const typeMatch = speakerStripped.match(/^(?:#{1,6}\s+|[-*]\s+)?\*{0,2}(fix|failure|decision|architecture|constraint|operation|preference|discovery|outcome|root cause|learned|rule|solution|resolution|workaround|hard rule|policy)\*{0,2}\s*[:\-\u2013]\s*(.*)$/i);
4873
+ let naturalType = null;
4874
+ let naturalContent = "";
4875
+ if (!typeMatch) {
4876
+ if (/\b(?:resolved|fixed|patched|worked around)\s+(?:the\s+)?([^.\n]+)/i.test(speakerStripped)) {
4877
+ naturalType = "fix";
4878
+ naturalContent = speakerStripped;
4879
+ } else if (/\b(?:decided|chose|selected|agreed)\s+to\s+([^.\n]+)/i.test(speakerStripped)) {
4880
+ naturalType = "decision";
4881
+ naturalContent = speakerStripped;
4882
+ } else if (/\b(?:must\s+always|must\s+never|never\s+commit|you\s+must\s+never|do\s+not\s+allow)\s+([^.\n]+)/i.test(speakerStripped)) {
4883
+ naturalType = "constraint";
4884
+ naturalContent = speakerStripped;
4885
+ } else if (/\b(?:user\s+prefers|prefers\s+using|prefers\s+to)\s+([^.\n]+)/i.test(speakerStripped)) {
4886
+ naturalType = "preference";
4887
+ naturalContent = speakerStripped;
4888
+ }
4889
+ }
4861
4890
  if (typeMatch) {
4862
4891
  flush();
4863
4892
  const rawTag = typeMatch[1].toLowerCase();
@@ -4866,6 +4895,11 @@ function extractHarvestUnits(text) {
4866
4895
  if (currentTitle) {
4867
4896
  currentBuffer.push(currentTitle);
4868
4897
  }
4898
+ } else if (naturalType && naturalContent) {
4899
+ flush();
4900
+ currentType = naturalType;
4901
+ currentTitle = naturalContent.slice(0, 80);
4902
+ currentBuffer.push(naturalContent);
4869
4903
  } else if (trimmed.match(/^(?:user|assistant|human|system|agent|client|developer)\s*[:\-\u2013]/i)) {
4870
4904
  flush();
4871
4905
  } else if (currentType !== null) {
@@ -4879,16 +4913,21 @@ function normalizeHarvestType(raw) {
4879
4913
  switch (raw) {
4880
4914
  case "fix":
4881
4915
  case "root cause":
4916
+ case "solution":
4917
+ case "resolution":
4918
+ case "workaround":
4882
4919
  return "fix";
4883
4920
  case "failure":
4884
4921
  return "failure";
4885
4922
  case "decision":
4886
4923
  case "outcome":
4887
4924
  case "rule":
4925
+ case "policy":
4888
4926
  return "decision";
4889
4927
  case "architecture":
4890
4928
  return "architecture";
4891
4929
  case "constraint":
4930
+ case "hard rule":
4892
4931
  return "constraint";
4893
4932
  case "operation":
4894
4933
  return "operation";
@@ -5265,6 +5304,30 @@ var sqliteDriver = "none";
5265
5304
  var init_sqlite = () => {};
5266
5305
 
5267
5306
  // src/store.ts
5307
+ var exports_store = {};
5308
+ __export(exports_store, {
5309
+ addConstraint: () => addConstraint,
5310
+ confirm: () => confirm,
5311
+ deleteEntry: () => deleteEntry,
5312
+ extractEntryText: () => extractEntryText,
5313
+ fileForId: () => fileForId,
5314
+ get: () => get2,
5315
+ getStorageLayout: () => getStorageLayout,
5316
+ harvestMemories: () => harvestMemories,
5317
+ link: () => link2,
5318
+ list: () => list,
5319
+ listIds: () => listIds,
5320
+ makeId: () => makeId,
5321
+ markStale: () => markStale,
5322
+ markSuperseded: () => markSuperseded,
5323
+ nowIso: () => nowIso2,
5324
+ openStore: () => openStore,
5325
+ propose: () => propose,
5326
+ reject: () => reject,
5327
+ save: () => save,
5328
+ slugifyId: () => slugifyId,
5329
+ supersede: () => supersede
5330
+ });
5268
5331
  import { resolve } from "node:path";
5269
5332
  import { readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync5, renameSync, unlinkSync, mkdirSync as mkdirSync7, existsSync as existsSync10 } from "node:fs";
5270
5333
  import { join as join7 } from "node:path";
@@ -9031,18 +9094,48 @@ var init_hook = __esm(() => {
9031
9094
  // src/cli/upgrade.ts
9032
9095
  var exports_upgrade = {};
9033
9096
  __export(exports_upgrade, {
9097
+ DEFAULT_PANDA_FRAMES: () => DEFAULT_PANDA_FRAMES,
9034
9098
  detectPackageManager: () => detectPackageManager,
9035
9099
  executePackageUpgrade: () => executePackageUpgrade,
9100
+ formatPandaProgressBar: () => formatPandaProgressBar,
9036
9101
  formatProgressBar: () => formatProgressBar,
9037
9102
  getLatestNpmVersion: () => getLatestNpmVersion,
9038
9103
  getUpgradeMilestones: () => getUpgradeMilestones,
9039
9104
  handleUpgradeCommand: () => handleUpgradeCommand,
9040
9105
  playGamifiedLoader: () => playGamifiedLoader,
9106
+ playPandaLoader: () => playPandaLoader,
9041
9107
  repairInstallation: () => repairInstallation
9042
9108
  });
9043
9109
  import { execSync as execSync2 } from "node:child_process";
9044
9110
  import { existsSync as existsSync22, mkdirSync as mkdirSync13, writeFileSync as writeFileSync11 } from "node:fs";
9045
9111
  import { join as join19 } from "node:path";
9112
+ function formatPandaProgressBar(percent, width = 20, options = {}) {
9113
+ const p = Math.max(0, Math.min(100, percent));
9114
+ const trailChar = options.trailChar ?? "━";
9115
+ const trackChar = options.trackChar ?? "─";
9116
+ const target = options.target;
9117
+ const frame = options.frame ?? 0;
9118
+ let pandaChar = "ʕ•ᴥ•ʔ";
9119
+ if (Array.isArray(options.panda) && options.panda.length > 0) {
9120
+ pandaChar = options.panda[frame % options.panda.length];
9121
+ } else if (typeof options.panda === "string") {
9122
+ pandaChar = options.panda;
9123
+ }
9124
+ const pos = Math.round(p / 100 * width);
9125
+ const trail = trailChar.repeat(pos);
9126
+ let empty = "";
9127
+ if (target) {
9128
+ if (pos >= width) {
9129
+ empty = target;
9130
+ } else {
9131
+ const remaining = width - pos;
9132
+ empty = trackChar.repeat(remaining) + target;
9133
+ }
9134
+ } else {
9135
+ empty = trackChar.repeat(Math.max(0, width - pos));
9136
+ }
9137
+ return `[${trail}${pandaChar}${empty}] ${Math.round(p)}%`;
9138
+ }
9046
9139
  function formatProgressBar(percent, width = 20) {
9047
9140
  const p = Math.max(0, Math.min(100, percent));
9048
9141
  const filledCount = Math.round(p / 100 * width);
@@ -9123,36 +9216,110 @@ function getUpgradeMilestones() {
9123
9216
  }
9124
9217
  ];
9125
9218
  }
9126
- async function playGamifiedLoader(steps, options = {}) {
9127
- const isTTY = process.stdout.isTTY;
9219
+ async function playPandaLoader(steps, options = {}) {
9220
+ const stream = options.stream ?? process.stdout;
9221
+ const isTTY = options.isTTY ?? (typeof stream.isTTY === "boolean" ? stream.isTTY : process.stdout.isTTY ?? false);
9222
+ const width = options.width ?? 20;
9128
9223
  const total = steps.length;
9129
- console.log(`
9130
- ┌──────────────────────────────────────────────────────────────────┐`);
9131
- console.log(`│ \uD83E\uDDE0 MUSE MEMORY · ${options.title || "SYSTEM LEVEL-UP & RECOVERY MATRIX"} │`);
9132
- console.log(`└──────────────────────────────────────────────────────────────────┘
9133
- `);
9224
+ const tickIntervalMs = options.tickIntervalMs ?? 60;
9225
+ const target = options.target;
9226
+ const panda = options.panda ?? DEFAULT_PANDA_FRAMES;
9227
+ const cleanTitle = options.title || "SYSTEM LEVEL-UP & RECOVERY MATRIX";
9228
+ const titleLine = `
9229
+ ┌──────────────────────────────────────────────────────────────────┐
9230
+ │ \uD83E\uDDE0 MUSE MEMORY · ${cleanTitle.padEnd(46)}│
9231
+ └──────────────────────────────────────────────────────────────────┘
9232
+ `;
9233
+ stream.write(titleLine);
9234
+ let frameIndex = 0;
9235
+ let currentPercent = 0;
9134
9236
  for (let i = 0;i < total; i++) {
9135
9237
  const step = steps[i];
9136
- const percent = Math.round((i + 1) / total * 100);
9137
- const bar = formatProgressBar(percent, 24);
9238
+ const targetPercent = Math.round((i + 1) / total * 100);
9239
+ const stepStartPercent = Math.round(i / total * 100);
9240
+ currentPercent = stepStartPercent;
9241
+ let timer = null;
9138
9242
  if (isTTY) {
9139
- process.stdout.write(` ${bar} ⚡ LEVEL ${step.level}: ${step.title}...\r`);
9243
+ timer = setInterval(() => {
9244
+ frameIndex++;
9245
+ if (currentPercent < targetPercent - 1) {
9246
+ currentPercent += Math.max(0.5, (targetPercent - currentPercent) * 0.15);
9247
+ }
9248
+ const bar2 = formatPandaProgressBar(Math.round(currentPercent), width, {
9249
+ panda,
9250
+ frame: frameIndex,
9251
+ target,
9252
+ trailChar: options.trailChar,
9253
+ trackChar: options.trackChar
9254
+ });
9255
+ stream.write(`\r\x1B[K ${bar2} \uD83D\uDC3E [${i + 1}/${total}] ${step.title}...`);
9256
+ }, tickIntervalMs);
9257
+ const bar = formatPandaProgressBar(stepStartPercent, width, {
9258
+ panda,
9259
+ frame: frameIndex,
9260
+ target,
9261
+ trailChar: options.trailChar,
9262
+ trackChar: options.trackChar
9263
+ });
9264
+ stream.write(`\r\x1B[K ${bar} \uD83D\uDC3E [${i + 1}/${total}] ${step.title}...`);
9140
9265
  } else {
9141
- console.log(` ${bar} ⚡ LEVEL ${step.level}: ${step.title}`);
9266
+ const bar = formatPandaProgressBar(targetPercent, width, {
9267
+ panda,
9268
+ frame: i,
9269
+ target,
9270
+ trailChar: options.trailChar,
9271
+ trackChar: options.trackChar
9272
+ });
9273
+ stream.write(` ${bar} \uD83D\uDC3E [${i + 1}/${total}] ${step.title}
9274
+ `);
9142
9275
  }
9143
9276
  try {
9144
9277
  await step.action();
9145
9278
  } catch (err) {
9146
- console.log(`
9147
- [!] Warning during step "${step.title}": ${err.message || err}`);
9279
+ if (timer)
9280
+ clearInterval(timer);
9281
+ if (isTTY) {
9282
+ stream.write(`
9283
+ [!] Warning during step "${step.title}": ${err.message || err}
9284
+ `);
9285
+ } else {
9286
+ stream.write(` [!] Warning during step "${step.title}": ${err.message || err}
9287
+ `);
9288
+ }
9289
+ } finally {
9290
+ if (timer)
9291
+ clearInterval(timer);
9148
9292
  }
9149
9293
  if (isTTY) {
9150
- await new Promise((r) => setTimeout(r, 60));
9151
- process.stdout.write(` ${bar} ✓ LEVEL ${step.level}: ${step.title} [OK]
9152
- `);
9294
+ currentPercent = targetPercent;
9295
+ frameIndex++;
9296
+ const bar = formatPandaProgressBar(targetPercent, width, {
9297
+ panda,
9298
+ frame: frameIndex,
9299
+ target,
9300
+ trailChar: options.trailChar,
9301
+ trackChar: options.trackChar
9302
+ });
9303
+ stream.write(`\r\x1B[K ${bar} ✓ [${i + 1}/${total}] ${step.title} [OK]`);
9304
+ await new Promise((r) => setTimeout(r, 40));
9153
9305
  }
9154
9306
  }
9155
- console.log();
9307
+ const finalBar = formatPandaProgressBar(100, width, {
9308
+ panda,
9309
+ frame: frameIndex,
9310
+ target: target ?? "\uD83C\uDF8B",
9311
+ trailChar: options.trailChar,
9312
+ trackChar: options.trackChar
9313
+ });
9314
+ if (isTTY) {
9315
+ stream.write(`\r\x1B[K ${finalBar} ✨ [${total}/${total}] Complete!
9316
+
9317
+ `);
9318
+ } else {
9319
+ stream.write(` ${finalBar} ✨ [${total}/${total}] Complete!
9320
+
9321
+ `);
9322
+ }
9156
9323
  }
9157
9324
  async function repairInstallation(options = {}) {
9158
9325
  const root = options.workspaceRoot || process.cwd();
@@ -9311,12 +9478,20 @@ async function handleUpgradeCommand({ flags }) {
9311
9478
  `);
9312
9479
  return 0;
9313
9480
  }
9481
+ var DEFAULT_PANDA_FRAMES, playGamifiedLoader;
9314
9482
  var init_upgrade = __esm(() => {
9315
9483
  init_root();
9316
9484
  init_user();
9317
9485
  init_connect();
9318
9486
  init_graph();
9319
9487
  init_hook();
9488
+ DEFAULT_PANDA_FRAMES = [
9489
+ "ʕ•ᴥ•ʔ",
9490
+ "ʕ •ᴥ•ʔ",
9491
+ "ʕ-ᴥ-ʔ",
9492
+ "ʕ•ᴥ•ʔノ"
9493
+ ];
9494
+ playGamifiedLoader = playPandaLoader;
9320
9495
  });
9321
9496
 
9322
9497
  // node_modules/ajv/dist/compile/codegen/code.js
@@ -15746,19 +15921,265 @@ var init_schema = __esm(() => {
15746
15921
  import_ajv = __toESM(require_ajv(), 1);
15747
15922
  });
15748
15923
 
15924
+ // src/harvester.ts
15925
+ var exports_harvester = {};
15926
+ __export(exports_harvester, {
15927
+ discoverAgentTranscripts: () => discoverAgentTranscripts,
15928
+ getHarvestedTranscriptLedger: () => getHarvestedTranscriptLedger,
15929
+ getStandardAgentTranscriptDirs: () => getStandardAgentTranscriptDirs,
15930
+ handleLearnCommand: () => handleLearnCommand,
15931
+ harvestAllAgentTranscripts: () => harvestAllAgentTranscripts,
15932
+ saveHarvestedTranscriptLedger: () => saveHarvestedTranscriptLedger
15933
+ });
15934
+ import {
15935
+ existsSync as existsSync24,
15936
+ readFileSync as readFileSync20,
15937
+ writeFileSync as writeFileSync12,
15938
+ readdirSync as readdirSync8,
15939
+ statSync as statSync8,
15940
+ mkdirSync as mkdirSync14,
15941
+ openSync,
15942
+ readSync,
15943
+ closeSync
15944
+ } from "node:fs";
15945
+ import { join as join21, dirname as dirname5 } from "node:path";
15946
+ import { homedir as homedir5 } from "node:os";
15947
+ import { createHash as createHash2 } from "node:crypto";
15948
+ function getStandardAgentTranscriptDirs(home = homedir5()) {
15949
+ return [
15950
+ join21(home, ".gemini", "antigravity-cli", "brain"),
15951
+ join21(home, ".config", "opencode", "transcripts"),
15952
+ join21(home, ".local", "share", "opencode", "transcripts"),
15953
+ join21(home, ".claude", "transcripts"),
15954
+ join21(home, ".claude", "projects"),
15955
+ join21(home, ".config", "LIFEOS", "runtime", "transcripts"),
15956
+ join21(home, ".hermes", "sessions"),
15957
+ join21(home, ".hermes", "transcripts"),
15958
+ join21(home, ".config", "goose", "sessions"),
15959
+ join21(home, ".codex", "sessions"),
15960
+ join21(home, ".config", "Cursor", "User", "workspaceStorage"),
15961
+ join21(process.cwd(), ".memory", "inbox"),
15962
+ join21(process.cwd(), ".logs")
15963
+ ];
15964
+ }
15965
+ function findJsonlFilesInDir(dir, maxDepth = 4, currentDepth = 0, out = []) {
15966
+ if (currentDepth > maxDepth || !existsSync24(dir))
15967
+ return out;
15968
+ let entries;
15969
+ try {
15970
+ entries = readdirSync8(dir, { withFileTypes: true });
15971
+ } catch {
15972
+ return out;
15973
+ }
15974
+ for (const e of entries) {
15975
+ if (e.name === "node_modules" || e.name === ".git" || e.name === "dist" || e.name === "processed" || e.name === "chunks" || e.name === ".cache" || e.name === ".tmp" || e.name.startsWith("tmp")) {
15976
+ continue;
15977
+ }
15978
+ const full = join21(dir, e.name);
15979
+ if (e.isDirectory()) {
15980
+ findJsonlFilesInDir(full, maxDepth, currentDepth + 1, out);
15981
+ } else if (e.isFile() && e.name.endsWith(".jsonl")) {
15982
+ if (!e.name.match(/^\d{8}\.jsonl$/) && e.name !== "transcript_full.jsonl") {
15983
+ out.push(full);
15984
+ }
15985
+ }
15986
+ }
15987
+ return out;
15988
+ }
15989
+ function discoverAgentTranscripts(options = {}) {
15990
+ const dirs = options.searchRoots && options.searchRoots.length > 0 ? options.searchRoots : getStandardAgentTranscriptDirs();
15991
+ const found = new Set;
15992
+ for (const d of dirs) {
15993
+ if (existsSync24(d)) {
15994
+ try {
15995
+ const stat = statSync8(d);
15996
+ if (stat.isDirectory()) {
15997
+ const files = findJsonlFilesInDir(d);
15998
+ for (const f of files)
15999
+ found.add(f);
16000
+ } else if (stat.isFile() && d.endsWith(".jsonl")) {
16001
+ found.add(d);
16002
+ }
16003
+ } catch {}
16004
+ }
16005
+ }
16006
+ const sorted = Array.from(found).sort((a, b) => {
16007
+ try {
16008
+ return statSync8(b).mtimeMs - statSync8(a).mtimeMs;
16009
+ } catch {
16010
+ return 0;
16011
+ }
16012
+ });
16013
+ if (options.maxFiles && options.maxFiles > 0) {
16014
+ return sorted.slice(0, options.maxFiles);
16015
+ }
16016
+ return sorted;
16017
+ }
16018
+ function getHarvestedTranscriptLedger(memoryDir) {
16019
+ const ledgerPath = join21(memoryDir, "harvested-transcripts.json");
16020
+ if (!existsSync24(ledgerPath))
16021
+ return {};
16022
+ try {
16023
+ const raw = readFileSync20(ledgerPath, "utf8");
16024
+ return JSON.parse(raw);
16025
+ } catch {
16026
+ return {};
16027
+ }
16028
+ }
16029
+ function saveHarvestedTranscriptLedger(memoryDir, ledger) {
16030
+ const ledgerPath = join21(memoryDir, "harvested-transcripts.json");
16031
+ const dir = dirname5(ledgerPath);
16032
+ if (!existsSync24(dir))
16033
+ mkdirSync14(dir, { recursive: true });
16034
+ writeFileSync12(ledgerPath, JSON.stringify(ledger, null, 2) + `
16035
+ `, "utf8");
16036
+ }
16037
+ function harvestAllAgentTranscripts(store, options = {}) {
16038
+ const memoryDir = options.memoryDir || join21(process.cwd(), ".memory");
16039
+ const ledger = getHarvestedTranscriptLedger(memoryDir);
16040
+ const files = discoverAgentTranscripts({
16041
+ searchRoots: options.searchRoots,
16042
+ maxFiles: options.maxFiles || 50
16043
+ });
16044
+ const result = {
16045
+ harvestedFilesCount: 0,
16046
+ totalFilesScanned: files.length,
16047
+ memoriesImported: 0,
16048
+ openLoopsDetected: 0,
16049
+ processedFiles: [],
16050
+ errors: []
16051
+ };
16052
+ for (const filePath of files) {
16053
+ try {
16054
+ const stat = statSync8(filePath);
16055
+ const prevEntry = ledger[filePath];
16056
+ if (!options.force && prevEntry && prevEntry.mtimeMs === stat.mtimeMs) {
16057
+ continue;
16058
+ }
16059
+ let content = "";
16060
+ if (stat.size > 2 * 1024 * 1024) {
16061
+ const fd = openSync(filePath, "r");
16062
+ const bufferSize = 512 * 1024;
16063
+ const buffer = Buffer.alloc(bufferSize);
16064
+ const position = Math.max(0, stat.size - bufferSize);
16065
+ const bytesRead = readSync(fd, buffer, 0, bufferSize, position);
16066
+ closeSync(fd);
16067
+ content = buffer.toString("utf8", 0, bytesRead);
16068
+ } else {
16069
+ content = readFileSync20(filePath, "utf8");
16070
+ }
16071
+ const contentHash = createHash2("sha256").update(content).digest("hex").slice(0, 16);
16072
+ if (!options.force && prevEntry && prevEntry.hash === contentHash) {
16073
+ continue;
16074
+ }
16075
+ let inferredProject = options.project;
16076
+ if (!inferredProject) {
16077
+ if (filePath.includes("/Projects/github/") || filePath.includes("/Projects/")) {
16078
+ const m = filePath.match(/\/Projects\/(?:github\/)?([^/]+)/);
16079
+ if (m)
16080
+ inferredProject = m[1];
16081
+ }
16082
+ }
16083
+ if (!inferredProject)
16084
+ inferredProject = "default";
16085
+ const importRes = importTranscript(store, content, {
16086
+ project: inferredProject,
16087
+ confirmed: options.confirmed === true,
16088
+ source: `auto_harvester:${filePath}`
16089
+ });
16090
+ ledger[filePath] = {
16091
+ mtimeMs: stat.mtimeMs,
16092
+ hash: contentHash,
16093
+ importedCount: importRes.imported,
16094
+ openLoopsCount: importRes.openLoops.length,
16095
+ harvestedAt: new Date().toISOString()
16096
+ };
16097
+ if (importRes.imported > 0 || importRes.openLoops.length > 0) {
16098
+ result.harvestedFilesCount++;
16099
+ result.memoriesImported += importRes.imported;
16100
+ result.openLoopsDetected += importRes.openLoops.length;
16101
+ result.processedFiles.push({
16102
+ path: filePath,
16103
+ imported: importRes.imported,
16104
+ openLoops: importRes.openLoops.length
16105
+ });
16106
+ recordAuditEvent(memoryDir, {
16107
+ operation: "transcript_import",
16108
+ entry_id: filePath,
16109
+ actor: "auto-harvester",
16110
+ details: {
16111
+ imported: importRes.imported,
16112
+ open_loops: importRes.openLoops.length,
16113
+ inferred_project: inferredProject
16114
+ }
16115
+ });
16116
+ }
16117
+ if (importRes.errors.length > 0) {
16118
+ result.errors.push(...importRes.errors.map((e) => `${filePath}: ${e}`));
16119
+ }
16120
+ } catch (err) {
16121
+ result.errors.push(`${filePath}: ${err.message || err}`);
16122
+ }
16123
+ }
16124
+ saveHarvestedTranscriptLedger(memoryDir, ledger);
16125
+ return result;
16126
+ }
16127
+ async function handleLearnCommand({ flags }) {
16128
+ const ctx = requireRoot(flags);
16129
+ if (!ctx)
16130
+ return 1;
16131
+ const isConfirmed = flags["confirmed"] === "true" || flags["confirm"] === "true";
16132
+ const force = flags["force"] === "true";
16133
+ const project = flags["project"];
16134
+ const maxFiles = flags["max"] ? parseInt(flags["max"], 10) : 50;
16135
+ console.log(`[Auto-Learner] Probing workstation for active AI agent transcripts...`);
16136
+ const res = harvestAllAgentTranscripts(ctx.store, {
16137
+ memoryDir: ctx.memoryDir,
16138
+ confirmed: isConfirmed,
16139
+ force,
16140
+ project,
16141
+ maxFiles
16142
+ });
16143
+ console.log(`[Auto-Learner] Scanned ${res.totalFilesScanned} agent transcript files.`);
16144
+ if (res.harvestedFilesCount === 0) {
16145
+ console.log(`✓ Up to date. 0 new un-harvested turns found (all transcripts indexed).`);
16146
+ return 0;
16147
+ }
16148
+ console.log(`
16149
+ \uD83C\uDF89 Distilled ${res.memoriesImported} new memories and ${res.openLoopsDetected} open loops from ${res.harvestedFilesCount} transcript(s):`);
16150
+ for (const p of res.processedFiles) {
16151
+ console.log(` * ${p.path} -> +${p.imported} memories, +${p.openLoops} loops`);
16152
+ }
16153
+ if (res.errors.length > 0) {
16154
+ console.log(`
16155
+ ⚠️ Warnings / Redactions during harvest:`);
16156
+ for (const err of res.errors.slice(0, 5)) {
16157
+ console.log(` - ${err}`);
16158
+ }
16159
+ }
16160
+ console.log(`
16161
+ \uD83D\uDCA1 Open 'memory ui' or run 'memory stats' to view your newly indexed cognitive graph.`);
16162
+ return 0;
16163
+ }
16164
+ var init_harvester = __esm(() => {
16165
+ init_harvest();
16166
+ init_audit();
16167
+ init_shared();
16168
+ });
16169
+
15749
16170
  // src/doctor.ts
15750
16171
  var exports_doctor = {};
15751
16172
  __export(exports_doctor, {
15752
16173
  printDoctorReport: () => printDoctorReport,
15753
16174
  runDoctor: () => runDoctor
15754
16175
  });
15755
- import { existsSync as existsSync24, statSync as statSync8, readFileSync as readFileSync20 } from "node:fs";
15756
- import { join as join21 } from "node:path";
15757
- import { homedir as homedir5 } from "node:os";
16176
+ import { existsSync as existsSync25, statSync as statSync9, readFileSync as readFileSync21 } from "node:fs";
16177
+ import { join as join22 } from "node:path";
16178
+ import { homedir as homedir6 } from "node:os";
15758
16179
  async function runDoctor(targetDir, options = {}) {
15759
- const home = homedir5();
15760
- const storagePath = options.global ? getGlobalMemoryDir() : findOrCreateProjectRoot(targetDir || process.cwd())?.memoryDir || join21(home, ".memory");
15761
- const isInitialized = existsSync24(storagePath);
16180
+ const home = homedir6();
16181
+ const storagePath = options.global ? getGlobalMemoryDir() : findOrCreateProjectRoot(targetDir || process.cwd())?.memoryDir || join22(home, ".memory");
16182
+ const isInitialized = existsSync25(storagePath);
15762
16183
  let currentMdExists = false;
15763
16184
  let currentMdLines = 0;
15764
16185
  let totalEntries = 0;
@@ -15776,10 +16197,10 @@ async function runDoctor(targetDir, options = {}) {
15776
16197
  let secretLeaksCount = 0;
15777
16198
  let brokenLinksCount = 0;
15778
16199
  if (isInitialized) {
15779
- const currentPath = join21(storagePath, "CURRENT.md");
15780
- if (existsSync24(currentPath)) {
16200
+ const currentPath = join22(storagePath, "CURRENT.md");
16201
+ if (existsSync25(currentPath)) {
15781
16202
  currentMdExists = true;
15782
- const content = readFileSync20(currentPath, "utf8");
16203
+ const content = readFileSync21(currentPath, "utf8");
15783
16204
  currentMdLines = content.split(`
15784
16205
  `).filter((l) => l.trim().length > 0).length;
15785
16206
  }
@@ -15800,21 +16221,21 @@ async function runDoctor(targetDir, options = {}) {
15800
16221
  valid = false;
15801
16222
  }
15802
16223
  }
15803
- const auditPath = join21(storagePath, "audit.jsonl");
16224
+ const auditPath = join22(storagePath, "audit.jsonl");
15804
16225
  let auditExists = false;
15805
16226
  let auditCount = 0;
15806
16227
  let auditSize = 0;
15807
16228
  let lastEvent;
15808
- if (existsSync24(auditPath)) {
16229
+ if (existsSync25(auditPath)) {
15809
16230
  auditExists = true;
15810
16231
  try {
15811
- const stat = statSync8(auditPath);
16232
+ const stat = statSync9(auditPath);
15812
16233
  auditSize = stat.size;
15813
16234
  const trail = getAuditTrail(storagePath, { limit: 1 });
15814
16235
  if (trail.length > 0) {
15815
16236
  lastEvent = `${trail[0].operation} on ${trail[0].entry_id} (${trail[0].timestamp})`;
15816
16237
  }
15817
- const raw = readFileSync20(auditPath, "utf8");
16238
+ const raw = readFileSync21(auditPath, "utf8");
15818
16239
  auditCount = raw.split(`
15819
16240
  `).filter((l) => l.trim().length > 0).length;
15820
16241
  } catch {}
@@ -15823,6 +16244,11 @@ async function runDoctor(targetDir, options = {}) {
15823
16244
  const installed = agents.filter((a) => a.installed);
15824
16245
  const connected = installed.filter((a) => a.connected);
15825
16246
  const unwired = installed.filter((a) => !a.connected);
16247
+ const { discoverAgentTranscripts: discoverAgentTranscripts2, getHarvestedTranscriptLedger: getHarvestedTranscriptLedger2 } = await Promise.resolve().then(() => (init_harvester(), exports_harvester));
16248
+ const discoveredFiles = discoverAgentTranscripts2();
16249
+ const ledger = getHarvestedTranscriptLedger2(storagePath);
16250
+ const harvestedFiles = Object.keys(ledger);
16251
+ const unharvestedCount = discoveredFiles.filter((f) => !ledger[f]).length;
15826
16252
  const memBin = findBinary("memory", home) || findBinary("musememory", home);
15827
16253
  const bunVer = typeof globalThis.Bun !== "undefined" ? globalThis.Bun.version : undefined;
15828
16254
  return {
@@ -15856,6 +16282,11 @@ async function runDoctor(targetDir, options = {}) {
15856
16282
  connectedList: connected.map((a) => a.name),
15857
16283
  unwiredList: unwired.map((a) => a.name)
15858
16284
  },
16285
+ transcripts: {
16286
+ discoveredCount: discoveredFiles.length,
16287
+ harvestedCount: harvestedFiles.length,
16288
+ unharvestedCount
16289
+ },
15859
16290
  runtime: {
15860
16291
  nodeVersion: process.version,
15861
16292
  bunVersion: bunVer,
@@ -15913,6 +16344,16 @@ function printDoctorReport(report) {
15913
16344
  console.log(` -> Run 'memory connect --all' or 'npx musememory connect --all' to wire them.`);
15914
16345
  }
15915
16346
  console.log(`
16347
+ [AUTO-LEARNER] Agent Chat Transcripts & Distillation:`);
16348
+ console.log(` Discovered Transcripts on Disk: ${report.transcripts.discoveredCount}`);
16349
+ console.log(` Harvested / Indexed: ${report.transcripts.harvestedCount}`);
16350
+ if (report.transcripts.unharvestedCount > 0) {
16351
+ console.log(` [!] New Un-Harvested Chats: ${report.transcripts.unharvestedCount}`);
16352
+ console.log(` -> Run 'memory learn' or 'memory sync-chats' to auto-distill learnings from recent AI interactions.`);
16353
+ } else {
16354
+ console.log(` [OK] All discovered chat transcripts are synchronized.`);
16355
+ }
16356
+ console.log(`
15916
16357
  [RUNTIME] Runtime & CLI Execution:`);
15917
16358
  console.log(` Node.js: ${report.runtime.nodeVersion}${report.runtime.bunVersion ? ` | Bun: v${report.runtime.bunVersion}` : ""}`);
15918
16359
  if (report.runtime.globalBinaryFound) {
@@ -15940,27 +16381,27 @@ var init_doctor = __esm(() => {
15940
16381
  });
15941
16382
 
15942
16383
  // src/retrieval/tree-index.ts
15943
- import { existsSync as existsSync25, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14, rmSync } from "node:fs";
15944
- import { join as join22 } from "node:path";
16384
+ import { existsSync as existsSync26, readFileSync as readFileSync22, writeFileSync as writeFileSync13, mkdirSync as mkdirSync15, rmSync } from "node:fs";
16385
+ import { join as join23 } from "node:path";
15945
16386
  function tokenize2(text) {
15946
16387
  if (!text || typeof text !== "string")
15947
16388
  return [];
15948
16389
  return text.toLowerCase().match(/[a-z0-9]+/g) ?? [];
15949
16390
  }
15950
16391
  function indexDir(memoryDir) {
15951
- return join22(memoryDir, "tree-index");
16392
+ return join23(memoryDir, "tree-index");
15952
16393
  }
15953
16394
  function partitionDir(idxDir, project, type2) {
15954
- return join22(idxDir, project, type2);
16395
+ return join23(idxDir, project, type2);
15955
16396
  }
15956
16397
  function shardFilePath(pDir, shardId) {
15957
- return join22(pDir, `${shardId}.json`);
16398
+ return join23(pDir, `${shardId}.json`);
15958
16399
  }
15959
16400
  function partitionIndexFilePath(pDir) {
15960
- return join22(pDir, "index.json");
16401
+ return join23(pDir, "index.json");
15961
16402
  }
15962
16403
  function globalIndexFilePath(idxDir) {
15963
- return join22(idxDir, "index.json");
16404
+ return join23(idxDir, "index.json");
15964
16405
  }
15965
16406
  function nowIso3() {
15966
16407
  return new Date().toISOString();
@@ -16050,7 +16491,7 @@ function countNodes(node) {
16050
16491
  function buildTreeIndex(store, memoryDir, config = {}) {
16051
16492
  const cfg = { ...DEFAULT_CONFIG, ...config };
16052
16493
  const allMemories = list(store).filter((e) => e.status === "confirmed");
16053
- mkdirSync14(indexDir(memoryDir), { recursive: true });
16494
+ mkdirSync15(indexDir(memoryDir), { recursive: true });
16054
16495
  if (allMemories.length === 0) {
16055
16496
  const emptyIndex = {
16056
16497
  version: 1,
@@ -16059,7 +16500,7 @@ function buildTreeIndex(store, memoryDir, config = {}) {
16059
16500
  totalMemories: 0,
16060
16501
  builtAt: nowIso3()
16061
16502
  };
16062
- writeFileSync12(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(emptyIndex, null, 2), "utf8");
16503
+ writeFileSync13(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(emptyIndex, null, 2), "utf8");
16063
16504
  return emptyIndex;
16064
16505
  }
16065
16506
  const groups = new Map;
@@ -16077,7 +16518,7 @@ function buildTreeIndex(store, memoryDir, config = {}) {
16077
16518
  for (const [key, memories] of groups) {
16078
16519
  const [project, type2] = key.split("|");
16079
16520
  const pDir = partitionDir(indexDir(memoryDir), project, type2);
16080
- mkdirSync14(pDir, { recursive: true });
16521
+ mkdirSync15(pDir, { recursive: true });
16081
16522
  const maxShardSize = cfg.shardThreshold || 1e4;
16082
16523
  const finalShards = [];
16083
16524
  const memoryChunks = [];
@@ -16138,9 +16579,9 @@ function buildTreeIndex(store, memoryDir, config = {}) {
16138
16579
  partitions[`${project}|${type2}`] = partition;
16139
16580
  totalIndexNodes += partitionNodes;
16140
16581
  totalIndexMemories += partitionMemories;
16141
- writeFileSync12(partitionIndexFilePath(pDir), JSON.stringify(partition, null, 2), "utf8");
16582
+ writeFileSync13(partitionIndexFilePath(pDir), JSON.stringify(partition, null, 2), "utf8");
16142
16583
  for (const shard of finalShards) {
16143
- writeFileSync12(shardFilePath(pDir, shard.id), JSON.stringify(shard, null, 2), "utf8");
16584
+ writeFileSync13(shardFilePath(pDir, shard.id), JSON.stringify(shard, null, 2), "utf8");
16144
16585
  }
16145
16586
  }
16146
16587
  const index = {
@@ -16150,15 +16591,15 @@ function buildTreeIndex(store, memoryDir, config = {}) {
16150
16591
  totalMemories: totalIndexMemories,
16151
16592
  builtAt: nowIso3()
16152
16593
  };
16153
- writeFileSync12(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(index, null, 2), "utf8");
16594
+ writeFileSync13(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(index, null, 2), "utf8");
16154
16595
  return index;
16155
16596
  }
16156
16597
  function loadTreeIndex(memoryDir) {
16157
16598
  const path = globalIndexFilePath(indexDir(memoryDir));
16158
- if (!existsSync25(path))
16599
+ if (!existsSync26(path))
16159
16600
  return null;
16160
16601
  try {
16161
- const data = JSON.parse(readFileSync21(path, "utf8"));
16602
+ const data = JSON.parse(readFileSync22(path, "utf8"));
16162
16603
  return data.version === 1 ? data : null;
16163
16604
  } catch {
16164
16605
  return null;
@@ -16303,10 +16744,10 @@ __export(exports_vector, {
16303
16744
  saveIndex: () => saveIndex,
16304
16745
  termFrequencies: () => termFrequencies
16305
16746
  });
16306
- import { existsSync as existsSync26, readFileSync as readFileSync22, writeFileSync as writeFileSync13, mkdirSync as mkdirSync15 } from "node:fs";
16307
- import { join as join23 } from "node:path";
16747
+ import { existsSync as existsSync27, readFileSync as readFileSync23, writeFileSync as writeFileSync14, mkdirSync as mkdirSync16 } from "node:fs";
16748
+ import { join as join24 } from "node:path";
16308
16749
  function indexFilePath(memoryDir) {
16309
- return join23(memoryDir, "index.json");
16750
+ return join24(memoryDir, "index.json");
16310
16751
  }
16311
16752
  function hashTrigram(tri) {
16312
16753
  let h = 2166136261;
@@ -16353,16 +16794,16 @@ function rebuildIndex(store) {
16353
16794
  return index;
16354
16795
  }
16355
16796
  function saveIndex(index, memoryDir) {
16356
- if (!existsSync26(memoryDir))
16357
- mkdirSync15(memoryDir, { recursive: true });
16358
- writeFileSync13(indexFilePath(memoryDir), JSON.stringify(index), "utf8");
16797
+ if (!existsSync27(memoryDir))
16798
+ mkdirSync16(memoryDir, { recursive: true });
16799
+ writeFileSync14(indexFilePath(memoryDir), JSON.stringify(index), "utf8");
16359
16800
  }
16360
16801
  function loadIndex(memoryDir) {
16361
16802
  const p = indexFilePath(memoryDir);
16362
- if (!existsSync26(p))
16803
+ if (!existsSync27(p))
16363
16804
  return null;
16364
16805
  try {
16365
- const parsed = JSON.parse(readFileSync22(p, "utf8"));
16806
+ const parsed = JSON.parse(readFileSync23(p, "utf8"));
16366
16807
  return parsed.version === 1 ? parsed : null;
16367
16808
  } catch {
16368
16809
  return null;
@@ -16434,8 +16875,8 @@ var init_vector = __esm(() => {
16434
16875
  });
16435
16876
 
16436
16877
  // src/pageindex/engine.ts
16437
- import { existsSync as existsSync27, mkdirSync as mkdirSync16, readFileSync as readFileSync23, writeFileSync as writeFileSync14, rmSync as rmSync2, readdirSync as readdirSync9 } from "node:fs";
16438
- import { join as join24 } from "node:path";
16878
+ import { existsSync as existsSync28, mkdirSync as mkdirSync17, readFileSync as readFileSync24, writeFileSync as writeFileSync15, rmSync as rmSync2, readdirSync as readdirSync10 } from "node:fs";
16879
+ import { join as join25 } from "node:path";
16439
16880
  function slugify2(text) {
16440
16881
  return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 50);
16441
16882
  }
@@ -16512,9 +16953,9 @@ function buildPageIndex(content, options) {
16512
16953
  root: rootNode
16513
16954
  };
16514
16955
  if (options.memoryDir && !options.dryRun) {
16515
- const dir = join24(options.memoryDir, "pageindex", project);
16516
- mkdirSync16(dir, { recursive: true });
16517
- writeFileSync14(join24(dir, `${indexId}.json`), JSON.stringify(doc, null, 2), "utf8");
16956
+ const dir = join25(options.memoryDir, "pageindex", project);
16957
+ mkdirSync17(dir, { recursive: true });
16958
+ writeFileSync15(join25(dir, `${indexId}.json`), JSON.stringify(doc, null, 2), "utf8");
16518
16959
  }
16519
16960
  return doc;
16520
16961
  }
@@ -16578,29 +17019,29 @@ function searchPageIndex(doc, options) {
16578
17019
  };
16579
17020
  }
16580
17021
  function loadPageIndex(memoryDir, project, indexId) {
16581
- const filePath = join24(memoryDir, "pageindex", project, `${indexId}.json`);
16582
- if (!existsSync27(filePath))
17022
+ const filePath = join25(memoryDir, "pageindex", project, `${indexId}.json`);
17023
+ if (!existsSync28(filePath))
16583
17024
  return null;
16584
17025
  try {
16585
- return JSON.parse(readFileSync23(filePath, "utf8"));
17026
+ return JSON.parse(readFileSync24(filePath, "utf8"));
16586
17027
  } catch {
16587
17028
  return null;
16588
17029
  }
16589
17030
  }
16590
17031
  function listPageIndexes(memoryDir, project) {
16591
- const base = join24(memoryDir, "pageindex");
16592
- if (!existsSync27(base))
17032
+ const base = join25(memoryDir, "pageindex");
17033
+ if (!existsSync28(base))
16593
17034
  return [];
16594
17035
  const results = [];
16595
- const projects = project ? [project] : readdirSync9(base);
17036
+ const projects = project ? [project] : readdirSync10(base);
16596
17037
  for (const p of projects) {
16597
- const pDir = join24(base, p);
16598
- if (!existsSync27(pDir))
17038
+ const pDir = join25(base, p);
17039
+ if (!existsSync28(pDir))
16599
17040
  continue;
16600
- for (const f of readdirSync9(pDir)) {
17041
+ for (const f of readdirSync10(pDir)) {
16601
17042
  if (f.endsWith(".json")) {
16602
17043
  try {
16603
- results.push(JSON.parse(readFileSync23(join24(pDir, f), "utf8")));
17044
+ results.push(JSON.parse(readFileSync24(join25(pDir, f), "utf8")));
16604
17045
  } catch {}
16605
17046
  }
16606
17047
  }
@@ -16608,8 +17049,8 @@ function listPageIndexes(memoryDir, project) {
16608
17049
  return results;
16609
17050
  }
16610
17051
  function deletePageIndex(memoryDir, project, indexId) {
16611
- const base = join24(memoryDir, "pageindex");
16612
- if (!existsSync27(base))
17052
+ const base = join25(memoryDir, "pageindex");
17053
+ if (!existsSync28(base))
16613
17054
  return { deletedCount: 0 };
16614
17055
  let count = 0;
16615
17056
  if (!project && !indexId) {
@@ -16617,14 +17058,14 @@ function deletePageIndex(memoryDir, project, indexId) {
16617
17058
  return { deletedCount: 1 };
16618
17059
  }
16619
17060
  if (project && !indexId) {
16620
- const pDir = join24(base, project);
16621
- if (existsSync27(pDir)) {
17061
+ const pDir = join25(base, project);
17062
+ if (existsSync28(pDir)) {
16622
17063
  rmSync2(pDir, { recursive: true, force: true });
16623
17064
  count++;
16624
17065
  }
16625
17066
  } else if (project && indexId) {
16626
- const file = join24(base, project, `${indexId}.json`);
16627
- if (existsSync27(file)) {
17067
+ const file = join25(base, project, `${indexId}.json`);
17068
+ if (existsSync28(file)) {
16628
17069
  rmSync2(file, { force: true });
16629
17070
  count++;
16630
17071
  }
@@ -16637,13 +17078,13 @@ var init_engine2 = __esm(() => {
16637
17078
  });
16638
17079
 
16639
17080
  // src/retrieval/engine.ts
16640
- import { existsSync as existsSync28 } from "node:fs";
16641
- import { join as join25 } from "node:path";
17081
+ import { existsSync as existsSync29 } from "node:fs";
17082
+ import { join as join26 } from "node:path";
16642
17083
 
16643
17084
  class RetrievalEngine {
16644
17085
  static search(store, memoryDir, query, options = {}) {
16645
17086
  const mode = options.mode ?? "auto";
16646
- if (mode === "pageindex" || options.docPath && existsSync28(options.docPath)) {
17087
+ if (mode === "pageindex" || options.docPath && existsSync29(options.docPath)) {
16647
17088
  try {
16648
17089
  const docs = listPageIndexes(memoryDir, options.project);
16649
17090
  if (docs.length > 0) {
@@ -16670,8 +17111,8 @@ class RetrievalEngine {
16670
17111
  }
16671
17112
  } catch {}
16672
17113
  }
16673
- const treeDir = join25(memoryDir, "tree");
16674
- const hasTree = existsSync28(treeDir);
17114
+ const treeDir = join26(memoryDir, "tree");
17115
+ const hasTree = existsSync29(treeDir);
16675
17116
  const allEntries = list(store);
16676
17117
  if (mode === "tree" || mode === "auto" && hasTree && allEntries.length >= 500) {
16677
17118
  try {
@@ -16709,7 +17150,7 @@ class RetrievalEngine {
16709
17150
  } catch {}
16710
17151
  }
16711
17152
  const vecPath = indexFilePath(memoryDir);
16712
- const hasVec = existsSync28(vecPath);
17153
+ const hasVec = existsSync29(vecPath);
16713
17154
  if (mode === "hybrid" || mode === "auto" && hasVec && allEntries.length > 100) {
16714
17155
  try {
16715
17156
  const hybridResults = hybridSearch(store, memoryDir, query, {
@@ -16765,6 +17206,8 @@ var init_retrieval2 = __esm(() => {
16765
17206
  });
16766
17207
 
16767
17208
  // src/snapshot.ts
17209
+ import { existsSync as existsSync30, readFileSync as readFileSync25, writeFileSync as writeFileSync16, mkdirSync as mkdirSync18, readdirSync as readdirSync11 } from "node:fs";
17210
+ import { join as join27, relative as relative2 } from "node:path";
16768
17211
  function exportSnapshot(store) {
16769
17212
  const entries = list(store);
16770
17213
  return {
@@ -16813,6 +17256,106 @@ function importSnapshot(store, snapshot, options = {}) {
16813
17256
  }
16814
17257
  return { imported, skipped, errors };
16815
17258
  }
17259
+ function freezeExecutionSnapshot(options) {
17260
+ const { workspaceRoot, memoryDir } = options;
17261
+ const runId = options.runId ?? `run_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
17262
+ const timestamp2 = new Date().toISOString();
17263
+ let task = options.task;
17264
+ if (existsSync30(task)) {
17265
+ try {
17266
+ task = readFileSync25(task, "utf-8").trim();
17267
+ } catch {}
17268
+ }
17269
+ let gitCommit;
17270
+ try {
17271
+ const { execSync: execSync3 } = __require("node:child_process");
17272
+ gitCommit = execSync3("git rev-parse HEAD", { cwd: workspaceRoot, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
17273
+ } catch {
17274
+ gitCommit = undefined;
17275
+ }
17276
+ const currentPath = join27(memoryDir, "CURRENT.md");
17277
+ let constraints = [];
17278
+ if (existsSync30(currentPath)) {
17279
+ const currentContent = readFileSync25(currentPath, "utf-8");
17280
+ constraints = currentContent.split(`
17281
+ `).map((l) => l.trim()).filter((l) => l.startsWith("- ") || l.startsWith("* ")).map((l) => l.replace(/^[-*]\s+/, ""));
17282
+ }
17283
+ const { createHash: createHash3 } = __require("node:crypto");
17284
+ const entries = options.store ? list(options.store) : [];
17285
+ const memory_hashes = entries.map((e) => {
17286
+ const contentToHash = `${e.id}
17287
+ ${e.title}
17288
+ ${e.content}
17289
+ ${e.status}
17290
+ ${e.type ?? ""}`;
17291
+ const hash = createHash3("sha256").update(contentToHash).digest("hex");
17292
+ return {
17293
+ id: e.id,
17294
+ title: e.title,
17295
+ type: e.type,
17296
+ hash
17297
+ };
17298
+ });
17299
+ const file_inventory = [];
17300
+ function scanDir(dir, base) {
17301
+ if (!existsSync30(dir))
17302
+ return;
17303
+ const items = readdirSync11(dir, { withFileTypes: true });
17304
+ for (const item of items) {
17305
+ if (item.name === "node_modules" || item.name === ".git" || item.name === ".memory")
17306
+ continue;
17307
+ const fullPath = join27(dir, item.name);
17308
+ const relPath = relative2(base, fullPath);
17309
+ if (item.isDirectory()) {
17310
+ scanDir(fullPath, base);
17311
+ } else {
17312
+ file_inventory.push(relPath);
17313
+ }
17314
+ }
17315
+ }
17316
+ scanDir(workspaceRoot, workspaceRoot);
17317
+ const snapshot = {
17318
+ run_id: runId,
17319
+ task,
17320
+ timestamp: timestamp2,
17321
+ git_commit: gitCommit,
17322
+ constraints,
17323
+ memory_hashes,
17324
+ file_inventory,
17325
+ metadata: options.metadata
17326
+ };
17327
+ const safeRunId = runId.replace(/[^a-zA-Z0-9_\-\.]/g, "_");
17328
+ const runDir = join27(memoryDir, "runs", safeRunId);
17329
+ mkdirSync18(runDir, { recursive: true });
17330
+ writeFileSync16(join27(runDir, "snapshot.json"), JSON.stringify(snapshot, null, 2), "utf-8");
17331
+ return snapshot;
17332
+ }
17333
+ function loadExecutionSnapshot(memoryDir, runId) {
17334
+ const safeRunId = runId.replace(/[^a-zA-Z0-9_\-\.]/g, "_");
17335
+ const snapshotPath = join27(memoryDir, "runs", safeRunId, "snapshot.json");
17336
+ if (!existsSync30(snapshotPath))
17337
+ return null;
17338
+ try {
17339
+ return JSON.parse(readFileSync25(snapshotPath, "utf-8"));
17340
+ } catch {
17341
+ return null;
17342
+ }
17343
+ }
17344
+ function listExecutionSnapshots(memoryDir) {
17345
+ const runsDir = join27(memoryDir, "runs");
17346
+ if (!existsSync30(runsDir))
17347
+ return [];
17348
+ const entries = readdirSync11(runsDir, { withFileTypes: true });
17349
+ const snapshots = [];
17350
+ for (const entry of entries) {
17351
+ if (entry.isDirectory()) {
17352
+ const snap = loadExecutionSnapshot(memoryDir, entry.name);
17353
+ if (snap)
17354
+ snapshots.push(snap);
17355
+ }
17356
+ }
17357
+ return snapshots.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
17358
+ }
16816
17359
  var init_snapshot = __esm(() => {
16817
17360
  init_store();
16818
17361
  init_schema();
@@ -26405,8 +26948,8 @@ var init_loops = __esm(() => {
26405
26948
  });
26406
26949
 
26407
26950
  // src/distill.ts
26408
- import { existsSync as existsSync29, mkdirSync as mkdirSync17, writeFileSync as writeFileSync15 } from "node:fs";
26409
- import { join as join26 } from "node:path";
26951
+ import { existsSync as existsSync31, mkdirSync as mkdirSync19, writeFileSync as writeFileSync17 } from "node:fs";
26952
+ import { join as join28 } from "node:path";
26410
26953
  function fixTokens(e) {
26411
26954
  const bag = tokenBag(e.title, 2);
26412
26955
  mergeBag(bag, tokenBag((e.tags ?? []).join(" "), 2));
@@ -26417,7 +26960,7 @@ function distillSkills(store, workspaceRoot, options = {}) {
26417
26960
  const report = { created: [], skippedExisting: [], clustersBelowThreshold: 0 };
26418
26961
  const fixes = list(store).filter((e) => e.status === "confirmed" && e.type === "fix").sort((a, b) => Date.parse(a.created_at) - Date.parse(b.created_at));
26419
26962
  const clusters = clusterByTokenOverlap(fixes, fixTokens, 0.5);
26420
- const skillsDir = options.skillsDir ?? join26(workspaceRoot, ".agents", "skills");
26963
+ const skillsDir = options.skillsDir ?? join28(workspaceRoot, ".agents", "skills");
26421
26964
  for (const cluster of clusters) {
26422
26965
  if (cluster.length < minCount) {
26423
26966
  report.clustersBelowThreshold++;
@@ -26425,9 +26968,9 @@ function distillSkills(store, workspaceRoot, options = {}) {
26425
26968
  }
26426
26969
  const topic = dominantTopicTokens(cluster.map((e) => e.title));
26427
26970
  const slug = slugifyId(topic.join("-") || "skill");
26428
- const dir = join26(skillsDir, slug);
26971
+ const dir = join28(skillsDir, slug);
26429
26972
  const memberIds = cluster.map((e) => e.id);
26430
- if (existsSync29(dir)) {
26973
+ if (existsSync31(dir)) {
26431
26974
  report.skippedExisting.push({ slug, members: memberIds });
26432
26975
  continue;
26433
26976
  }
@@ -26437,10 +26980,10 @@ function distillSkills(store, workspaceRoot, options = {}) {
26437
26980
  throw new Error(`Secret detected in generated SKILL.md for '${slug}': ${secrets.join(", ")}`);
26438
26981
  }
26439
26982
  if (!options.dryRun) {
26440
- mkdirSync17(dir, { recursive: true });
26441
- writeFileSync15(join26(dir, "SKILL.md"), md, "utf8");
26983
+ mkdirSync19(dir, { recursive: true });
26984
+ writeFileSync17(join28(dir, "SKILL.md"), md, "utf8");
26442
26985
  }
26443
- report.created.push({ slug, path: join26(dir, "SKILL.md"), members: memberIds });
26986
+ report.created.push({ slug, path: join28(dir, "SKILL.md"), members: memberIds });
26444
26987
  }
26445
26988
  return report;
26446
26989
  }
@@ -26479,6 +27022,183 @@ var init_distill = __esm(() => {
26479
27022
  init_consolidate();
26480
27023
  });
26481
27024
 
27025
+ // src/provenance.ts
27026
+ var exports_provenance = {};
27027
+ __export(exports_provenance, {
27028
+ addSource: () => addSource,
27029
+ findSources: () => findSources,
27030
+ getSource: () => getSource,
27031
+ getSourcesFilePath: () => getSourcesFilePath,
27032
+ listSources: () => listSources,
27033
+ loadSources: () => loadSources,
27034
+ saveSources: () => saveSources
27035
+ });
27036
+ import { existsSync as existsSync32, readFileSync as readFileSync26, writeFileSync as writeFileSync18, mkdirSync as mkdirSync20 } from "node:fs";
27037
+ import { join as join29 } from "node:path";
27038
+ function getSourcesFilePath(memoryDir) {
27039
+ return join29(memoryDir, "sources.json");
27040
+ }
27041
+ function loadSources(memoryDir) {
27042
+ const filePath = getSourcesFilePath(memoryDir);
27043
+ if (!existsSync32(filePath)) {
27044
+ return [];
27045
+ }
27046
+ try {
27047
+ const raw = readFileSync26(filePath, "utf-8");
27048
+ const parsed = JSON.parse(raw);
27049
+ return Array.isArray(parsed) ? parsed : [];
27050
+ } catch {
27051
+ return [];
27052
+ }
27053
+ }
27054
+ function saveSources(memoryDir, sources) {
27055
+ mkdirSync20(memoryDir, { recursive: true });
27056
+ const filePath = getSourcesFilePath(memoryDir);
27057
+ writeFileSync18(filePath, JSON.stringify(sources, null, 2), "utf-8");
27058
+ }
27059
+ function addSource(memoryDir, input) {
27060
+ const textToScan = `${input.title}
27061
+ ${input.url}
27062
+ ${input.excerpt ?? ""}
27063
+ ${input.author ?? ""}`;
27064
+ const secrets = scanSecrets(textToScan);
27065
+ if (secrets.length > 0) {
27066
+ throw new Error(`Vibeguard: Detected secret in source data: ${secrets.join(", ")}`);
27067
+ }
27068
+ const sources = loadSources(memoryDir);
27069
+ const id = input.id ?? `src_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
27070
+ const retrieved_at = input.retrieved_at ?? new Date().toISOString();
27071
+ const sourceEntry = {
27072
+ id,
27073
+ url: input.url,
27074
+ title: input.title,
27075
+ source_type: input.source_type ?? "documentation",
27076
+ excerpt: input.excerpt,
27077
+ author: input.author,
27078
+ retrieved_at,
27079
+ metadata: input.metadata
27080
+ };
27081
+ const existingIdx = sources.findIndex((s) => s.id === id);
27082
+ if (existingIdx >= 0) {
27083
+ sources[existingIdx] = sourceEntry;
27084
+ } else {
27085
+ sources.push(sourceEntry);
27086
+ }
27087
+ saveSources(memoryDir, sources);
27088
+ return sourceEntry;
27089
+ }
27090
+ function getSource(memoryDir, id) {
27091
+ const sources = loadSources(memoryDir);
27092
+ return sources.find((s) => s.id === id) ?? null;
27093
+ }
27094
+ function listSources(memoryDir, filter) {
27095
+ let sources = loadSources(memoryDir);
27096
+ if (filter?.source_type) {
27097
+ const st = filter.source_type.toLowerCase();
27098
+ sources = sources.filter((s) => s.source_type.toLowerCase() === st);
27099
+ }
27100
+ if (filter?.query && filter.query.trim()) {
27101
+ const q = filter.query.toLowerCase().trim();
27102
+ sources = sources.filter((s) => s.title.toLowerCase().includes(q) || s.url.toLowerCase().includes(q) || s.excerpt && s.excerpt.toLowerCase().includes(q) || s.author && s.author.toLowerCase().includes(q));
27103
+ }
27104
+ return sources;
27105
+ }
27106
+ function findSources(memoryDir, query) {
27107
+ return listSources(memoryDir, { query });
27108
+ }
27109
+ var init_provenance = __esm(() => {
27110
+ init_secrets();
27111
+ });
27112
+
27113
+ // src/claims.ts
27114
+ var exports_claims = {};
27115
+ __export(exports_claims, {
27116
+ findClaims: () => findClaims,
27117
+ getClaim: () => getClaim,
27118
+ getClaimsFilePath: () => getClaimsFilePath,
27119
+ listClaims: () => listClaims,
27120
+ loadClaims: () => loadClaims,
27121
+ recordClaim: () => recordClaim,
27122
+ saveClaims: () => saveClaims
27123
+ });
27124
+ import { existsSync as existsSync33, readFileSync as readFileSync27, writeFileSync as writeFileSync19, mkdirSync as mkdirSync21 } from "node:fs";
27125
+ import { join as join30 } from "node:path";
27126
+ function getClaimsFilePath(memoryDir) {
27127
+ return join30(memoryDir, "claims.json");
27128
+ }
27129
+ function loadClaims(memoryDir) {
27130
+ const filePath = getClaimsFilePath(memoryDir);
27131
+ if (!existsSync33(filePath)) {
27132
+ return [];
27133
+ }
27134
+ try {
27135
+ const raw = readFileSync27(filePath, "utf-8");
27136
+ const parsed = JSON.parse(raw);
27137
+ return Array.isArray(parsed) ? parsed : [];
27138
+ } catch {
27139
+ return [];
27140
+ }
27141
+ }
27142
+ function saveClaims(memoryDir, claims) {
27143
+ mkdirSync21(memoryDir, { recursive: true });
27144
+ const filePath = getClaimsFilePath(memoryDir);
27145
+ writeFileSync19(filePath, JSON.stringify(claims, null, 2), "utf-8");
27146
+ }
27147
+ function recordClaim(memoryDir, input) {
27148
+ const textToScan = `${input.claim}
27149
+ ${input.notes ?? ""}`;
27150
+ const secrets = scanSecrets(textToScan);
27151
+ if (secrets.length > 0) {
27152
+ throw new Error(`Vibeguard: Detected secret in claim: ${secrets.join(", ")}`);
27153
+ }
27154
+ const claims = loadClaims(memoryDir);
27155
+ const id = input.id ?? `clm_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
27156
+ const created_at = input.created_at ?? new Date().toISOString();
27157
+ const claimEntry = {
27158
+ id,
27159
+ claim: input.claim,
27160
+ confidence_tag: input.confidence_tag ?? "INFER",
27161
+ source_ids: input.source_ids ?? [],
27162
+ memory_ids: input.memory_ids ?? [],
27163
+ notes: input.notes,
27164
+ created_at,
27165
+ verified: input.verified ?? false
27166
+ };
27167
+ const existingIdx = claims.findIndex((c) => c.id === id);
27168
+ if (existingIdx >= 0) {
27169
+ claims[existingIdx] = claimEntry;
27170
+ } else {
27171
+ claims.push(claimEntry);
27172
+ }
27173
+ saveClaims(memoryDir, claims);
27174
+ return claimEntry;
27175
+ }
27176
+ function getClaim(memoryDir, id) {
27177
+ const claims = loadClaims(memoryDir);
27178
+ return claims.find((c) => c.id === id) ?? null;
27179
+ }
27180
+ function listClaims(memoryDir, filter) {
27181
+ let claims = loadClaims(memoryDir);
27182
+ if (filter?.confidence_tag) {
27183
+ const tag = filter.confidence_tag.toUpperCase();
27184
+ claims = claims.filter((c) => c.confidence_tag.toUpperCase() === tag);
27185
+ }
27186
+ if (filter?.verified !== undefined) {
27187
+ claims = claims.filter((c) => !!c.verified === filter.verified);
27188
+ }
27189
+ if (filter?.query && filter.query.trim()) {
27190
+ const q = filter.query.toLowerCase().trim();
27191
+ claims = claims.filter((c) => c.claim.toLowerCase().includes(q) || c.notes && c.notes.toLowerCase().includes(q));
27192
+ }
27193
+ return claims;
27194
+ }
27195
+ function findClaims(memoryDir, query) {
27196
+ return listClaims(memoryDir, { query });
27197
+ }
27198
+ var init_claims = __esm(() => {
27199
+ init_secrets();
27200
+ });
27201
+
26482
27202
  // src/verify.ts
26483
27203
  import { execFile } from "node:child_process";
26484
27204
  function runCommand(command, cwd, timeoutSec) {
@@ -26565,41 +27285,213 @@ ${result.stderr}`.trim().slice(0, 2000)
26565
27285
  }
26566
27286
  return result;
26567
27287
  }
26568
- var init_verify = __esm(() => {
26569
- init_store();
26570
- init_audit();
26571
- });
26572
-
26573
- // src/sessions.ts
26574
- var init_sessions = __esm(() => {
26575
- init_governor();
26576
- });
26577
- // src/entities/index.ts
26578
- var init_entities = __esm(() => {
26579
- init_extractor();
26580
- });
26581
- // src/pageindex/index.ts
26582
- var init_pageindex = __esm(() => {
26583
- init_engine2();
26584
- });
26585
- // src/settings/defaults.ts
26586
- var DEFAULT_SETTINGS;
26587
- var init_defaults = __esm(() => {
26588
- DEFAULT_SETTINGS = {
26589
- version: 1,
26590
- retrieval: {
26591
- defaultMode: "hybrid",
26592
- defaultTokenBudget: 2000,
26593
- defaultDisclosureDepth: "L2",
26594
- treeMaxDepth: 5,
26595
- enableLLMReasoning: false,
26596
- hybridVectorWeight: 0.5,
26597
- hybridTreeWeight: 0.5
26598
- },
26599
- wiki: {
26600
- autoCompile: false,
26601
- compileIntervalMinutes: 60,
26602
- minClusterSize: 3,
27288
+ function verifyStrictIntegrity(store, memoryDir, workspaceRoot, options = {}) {
27289
+ const { existsSync: existsSync34, readFileSync: readFileSync28, readdirSync: readdirSync12 } = __require("node:fs");
27290
+ const { join: join31 } = __require("node:path");
27291
+ const { scanSecrets: scanSecrets2 } = (init_secrets(), __toCommonJS(exports_secrets));
27292
+ const { list: list2 } = (init_store(), __toCommonJS(exports_store));
27293
+ const { loadSources: loadSources2 } = (init_provenance(), __toCommonJS(exports_provenance));
27294
+ const { loadClaims: loadClaims2 } = (init_claims(), __toCommonJS(exports_claims));
27295
+ const checks4 = [];
27296
+ const entries = list2(store);
27297
+ const entryMap = new Map(entries.map((e) => [e.id, e]));
27298
+ const secretErrors = [];
27299
+ for (const e of entries) {
27300
+ const text = `${e.title}
27301
+ ${e.content}
27302
+ ${(e.tags ?? []).join(" ")}`;
27303
+ const found = scanSecrets2(text);
27304
+ if (found.length > 0) {
27305
+ secretErrors.push(`Secret detected in memory ${e.id}: ${found.join(", ")}`);
27306
+ }
27307
+ }
27308
+ const currentPath = join31(memoryDir, "CURRENT.md");
27309
+ if (existsSync34(currentPath)) {
27310
+ const found = scanSecrets2(readFileSync28(currentPath, "utf-8"));
27311
+ if (found.length > 0)
27312
+ secretErrors.push(`Secret detected in CURRENT.md: ${found.join(", ")}`);
27313
+ }
27314
+ const userPath = join31(memoryDir, "USER.md");
27315
+ if (existsSync34(userPath)) {
27316
+ const found = scanSecrets2(readFileSync28(userPath, "utf-8"));
27317
+ if (found.length > 0)
27318
+ secretErrors.push(`Secret detected in USER.md: ${found.join(", ")}`);
27319
+ }
27320
+ checks4.push({
27321
+ name: "zero_secret_leakage",
27322
+ passed: secretErrors.length === 0,
27323
+ message: secretErrors.length === 0 ? "Zero secret credentials detected" : `Found ${secretErrors.length} leaked secret(s)`,
27324
+ errors: secretErrors.length > 0 ? secretErrors : undefined
27325
+ });
27326
+ const refErrors = [];
27327
+ for (const e of entries) {
27328
+ if (e.supersedes) {
27329
+ const targets = Array.isArray(e.supersedes) ? e.supersedes : [e.supersedes];
27330
+ for (const t of targets) {
27331
+ if (t && !entryMap.has(t)) {
27332
+ refErrors.push(`Entry ${e.id} references non-existent supersedes ID: ${t}`);
27333
+ }
27334
+ }
27335
+ }
27336
+ if (e.superseded_by) {
27337
+ const targets = Array.isArray(e.superseded_by) ? e.superseded_by : [e.superseded_by];
27338
+ for (const t of targets) {
27339
+ if (t && !entryMap.has(t)) {
27340
+ refErrors.push(`Entry ${e.id} references non-existent superseded_by ID: ${t}`);
27341
+ }
27342
+ }
27343
+ }
27344
+ if (e.related_memory_ids) {
27345
+ for (const r of e.related_memory_ids) {
27346
+ if (!entryMap.has(r)) {
27347
+ refErrors.push(`Entry ${e.id} references non-existent related memory ID: ${r}`);
27348
+ }
27349
+ }
27350
+ }
27351
+ }
27352
+ checks4.push({
27353
+ name: "referential_integrity",
27354
+ passed: refErrors.length === 0,
27355
+ message: refErrors.length === 0 ? "All graph links resolve cleanly" : `Found ${refErrors.length} broken reference(s)`,
27356
+ errors: refErrors.length > 0 ? refErrors : undefined
27357
+ });
27358
+ const claimErrors = [];
27359
+ const sources = loadSources2(memoryDir);
27360
+ const sourceIds = new Set(sources.map((s) => s.id));
27361
+ const claims = loadClaims2(memoryDir);
27362
+ for (const c of claims) {
27363
+ if (c.source_ids) {
27364
+ for (const sid of c.source_ids) {
27365
+ if (!sourceIds.has(sid)) {
27366
+ claimErrors.push(`Claim ${c.id} references missing source ID: ${sid}`);
27367
+ }
27368
+ }
27369
+ }
27370
+ if (c.memory_ids) {
27371
+ for (const mid of c.memory_ids) {
27372
+ if (!entryMap.has(mid)) {
27373
+ claimErrors.push(`Claim ${c.id} references missing memory ID: ${mid}`);
27374
+ }
27375
+ }
27376
+ }
27377
+ }
27378
+ checks4.push({
27379
+ name: "claim_sources",
27380
+ passed: claimErrors.length === 0,
27381
+ message: claimErrors.length === 0 ? "All claims mapped to valid sources" : `Found ${claimErrors.length} unmapped claim reference(s)`,
27382
+ errors: claimErrors.length > 0 ? claimErrors : undefined
27383
+ });
27384
+ const wikiErrors = [];
27385
+ const wikiDir = join31(memoryDir, "wiki");
27386
+ if (existsSync34(wikiDir)) {
27387
+ let collectSlugs = function(dir) {
27388
+ const items = readdirSync12(dir, { withFileTypes: true });
27389
+ for (const it of items) {
27390
+ const full = join31(dir, it.name);
27391
+ if (it.isDirectory()) {
27392
+ collectSlugs(full);
27393
+ } else if (it.name.endsWith(".md")) {
27394
+ knownSlugs.add(it.name.replace(/\.md$/, "").toLowerCase());
27395
+ const { relative: relative3 } = __require("node:path");
27396
+ knownSlugs.add(relative3(wikiDir, full).replace(/\.md$/, "").toLowerCase());
27397
+ }
27398
+ }
27399
+ }, scanWikilinks = function(dir) {
27400
+ const items = readdirSync12(dir, { withFileTypes: true });
27401
+ for (const it of items) {
27402
+ const full = join31(dir, it.name);
27403
+ if (it.isDirectory()) {
27404
+ scanWikilinks(full);
27405
+ } else if (it.name.endsWith(".md")) {
27406
+ const content = readFileSync28(full, "utf-8");
27407
+ const matches = content.matchAll(/\[\[([a-zA-Z0-9_\-\./ ]+?)(?:\|[^\r\n\]]+)?\]\]/g);
27408
+ for (const m of matches) {
27409
+ const rawTarget = m[1].trim().toLowerCase();
27410
+ if (!rawTarget || rawTarget.startsWith("type:") || rawTarget.startsWith("tag:") || rawTarget.length <= 1) {
27411
+ continue;
27412
+ }
27413
+ if (!knownSlugs.has(rawTarget)) {
27414
+ wikiErrors.push(`Wikilink [[${m[1]}]] in ${it.name} does not resolve to any wiki page.`);
27415
+ }
27416
+ }
27417
+ }
27418
+ }
27419
+ };
27420
+ const knownSlugs = new Set;
27421
+ collectSlugs(wikiDir);
27422
+ for (const id of entryMap.keys()) {
27423
+ knownSlugs.add(id.toLowerCase());
27424
+ }
27425
+ scanWikilinks(wikiDir);
27426
+ }
27427
+ checks4.push({
27428
+ name: "wikilink_resolution",
27429
+ passed: wikiErrors.length === 0,
27430
+ message: wikiErrors.length === 0 ? "All wikilinks resolve cleanly" : `Found ${wikiErrors.length} broken wikilink(s)`,
27431
+ errors: wikiErrors.length > 0 ? wikiErrors : undefined
27432
+ });
27433
+ const candidateErrors = [];
27434
+ const maxDays = options.maxCandidateDays ?? 90;
27435
+ const cutoff = Date.now() - maxDays * 86400000;
27436
+ for (const e of entries) {
27437
+ if (e.status === "candidate") {
27438
+ const created = new Date(e.created_at).getTime();
27439
+ if (!isNaN(created) && created < cutoff) {
27440
+ candidateErrors.push(`Candidate memory ${e.id} ("${e.title}") has been orphaned for > ${maxDays} days without review.`);
27441
+ }
27442
+ }
27443
+ }
27444
+ checks4.push({
27445
+ name: "candidate_retention",
27446
+ passed: candidateErrors.length === 0,
27447
+ message: candidateErrors.length === 0 ? "No orphaned candidates" : `Found ${candidateErrors.length} orphaned candidate(s)`,
27448
+ errors: candidateErrors.length > 0 ? candidateErrors : undefined
27449
+ });
27450
+ const failedChecks = checks4.filter((c) => !c.passed).length;
27451
+ const passedChecks = checks4.filter((c) => c.passed).length;
27452
+ return {
27453
+ ok: failedChecks === 0,
27454
+ totalChecks: checks4.length,
27455
+ passedChecks,
27456
+ failedChecks,
27457
+ checks: checks4
27458
+ };
27459
+ }
27460
+ var init_verify = __esm(() => {
27461
+ init_store();
27462
+ init_audit();
27463
+ });
27464
+
27465
+ // src/sessions.ts
27466
+ var init_sessions = __esm(() => {
27467
+ init_governor();
27468
+ });
27469
+ // src/entities/index.ts
27470
+ var init_entities = __esm(() => {
27471
+ init_extractor();
27472
+ });
27473
+ // src/pageindex/index.ts
27474
+ var init_pageindex = __esm(() => {
27475
+ init_engine2();
27476
+ });
27477
+ // src/settings/defaults.ts
27478
+ var DEFAULT_SETTINGS;
27479
+ var init_defaults = __esm(() => {
27480
+ DEFAULT_SETTINGS = {
27481
+ version: 1,
27482
+ retrieval: {
27483
+ defaultMode: "hybrid",
27484
+ defaultTokenBudget: 2000,
27485
+ defaultDisclosureDepth: "L2",
27486
+ treeMaxDepth: 5,
27487
+ enableLLMReasoning: false,
27488
+ hybridVectorWeight: 0.5,
27489
+ hybridTreeWeight: 0.5
27490
+ },
27491
+ wiki: {
27492
+ autoCompile: false,
27493
+ compileIntervalMinutes: 60,
27494
+ minClusterSize: 3,
26603
27495
  clusteringThreshold: 0.5,
26604
27496
  conceptOverlapThreshold: 0.3,
26605
27497
  includeTypes: ["fix", "decision", "architecture", "operation", "failure", "constraint", "preference", "discovery"],
@@ -26778,14 +27670,14 @@ var init_schema2 = __esm(() => {
26778
27670
  });
26779
27671
 
26780
27672
  // src/settings/loader.ts
26781
- import { existsSync as existsSync30, mkdirSync as mkdirSync18, readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "node:fs";
26782
- import { join as join27 } from "node:path";
27673
+ import { existsSync as existsSync34, mkdirSync as mkdirSync22, readFileSync as readFileSync28, writeFileSync as writeFileSync20 } from "node:fs";
27674
+ import { join as join31 } from "node:path";
26783
27675
  function getSettingsFilePath(memoryDir) {
26784
- return join27(memoryDir, "settings.json");
27676
+ return join31(memoryDir, "settings.json");
26785
27677
  }
26786
27678
  function loadSettings(memoryDir) {
26787
27679
  const filePath = getSettingsFilePath(memoryDir);
26788
- if (!existsSync30(filePath)) {
27680
+ if (!existsSync34(filePath)) {
26789
27681
  return {
26790
27682
  version: 1,
26791
27683
  global: JSON.parse(JSON.stringify(DEFAULT_SETTINGS)),
@@ -26793,7 +27685,7 @@ function loadSettings(memoryDir) {
26793
27685
  };
26794
27686
  }
26795
27687
  try {
26796
- const raw = readFileSync24(filePath, "utf8");
27688
+ const raw = readFileSync28(filePath, "utf8");
26797
27689
  const parsed = JSON.parse(raw);
26798
27690
  return {
26799
27691
  version: parsed.version || 1,
@@ -26809,9 +27701,9 @@ function loadSettings(memoryDir) {
26809
27701
  }
26810
27702
  }
26811
27703
  function saveSettings(store, memoryDir) {
26812
- mkdirSync18(memoryDir, { recursive: true });
27704
+ mkdirSync22(memoryDir, { recursive: true });
26813
27705
  const filePath = getSettingsFilePath(memoryDir);
26814
- writeFileSync16(filePath, JSON.stringify(store, null, 2), "utf8");
27706
+ writeFileSync20(filePath, JSON.stringify(store, null, 2), "utf8");
26815
27707
  }
26816
27708
  function getSettings(memoryDir) {
26817
27709
  return loadSettings(memoryDir).global;
@@ -26918,6 +27810,510 @@ var init_settings2 = __esm(() => {
26918
27810
  init_settings();
26919
27811
  });
26920
27812
 
27813
+ // src/prompts.ts
27814
+ import { existsSync as existsSync35, readFileSync as readFileSync29, writeFileSync as writeFileSync21, mkdirSync as mkdirSync23, readdirSync as readdirSync12 } from "node:fs";
27815
+ import { join as join32 } from "node:path";
27816
+ function getPromptsDir(memoryDir) {
27817
+ if (!memoryDir)
27818
+ return null;
27819
+ return join32(memoryDir, "prompts");
27820
+ }
27821
+ function listPrompts(memoryDir) {
27822
+ const promptMap = new Map;
27823
+ for (const bp of BUILTIN_PROMPTS) {
27824
+ promptMap.set(bp.name, bp);
27825
+ }
27826
+ const dir = getPromptsDir(memoryDir);
27827
+ if (dir && existsSync35(dir)) {
27828
+ const files = readdirSync12(dir).filter((f) => f.endsWith(".md"));
27829
+ for (const file of files) {
27830
+ const name = file.replace(/\.md$/, "");
27831
+ const fullPath = join32(dir, file);
27832
+ try {
27833
+ const raw = readFileSync29(fullPath, "utf-8");
27834
+ const parsed = parsePromptFile(name, raw);
27835
+ promptMap.set(name, parsed);
27836
+ } catch {}
27837
+ }
27838
+ }
27839
+ return Array.from(promptMap.values());
27840
+ }
27841
+ function getPrompt(memoryDir, name) {
27842
+ const safeName = name.replace(/[^a-zA-Z0-9_\-\.]/g, "_");
27843
+ const dir = getPromptsDir(memoryDir);
27844
+ if (dir) {
27845
+ const filePath = join32(dir, `${safeName}.md`);
27846
+ if (existsSync35(filePath)) {
27847
+ try {
27848
+ const raw = readFileSync29(filePath, "utf-8");
27849
+ return parsePromptFile(name, raw);
27850
+ } catch {}
27851
+ }
27852
+ }
27853
+ return BUILTIN_PROMPTS.find((p) => p.name === name) ?? null;
27854
+ }
27855
+ function parsePromptFile(name, content) {
27856
+ if (content.startsWith("---")) {
27857
+ const parts = content.split("---");
27858
+ if (parts.length >= 3) {
27859
+ const yamlBlock = parts[1];
27860
+ const template = parts.slice(2).join("---").trim();
27861
+ let title = name;
27862
+ let description = "";
27863
+ const variables = [];
27864
+ const tags = [];
27865
+ for (const line of yamlBlock.split(`
27866
+ `)) {
27867
+ const trimmed = line.trim();
27868
+ if (trimmed.startsWith("title:"))
27869
+ title = trimmed.replace("title:", "").trim();
27870
+ if (trimmed.startsWith("description:"))
27871
+ description = trimmed.replace("description:", "").trim();
27872
+ if (trimmed.startsWith("variables:")) {
27873
+ const match = trimmed.match(/\[(.*?)\]/);
27874
+ if (match) {
27875
+ variables.push(...match[1].split(",").map((v) => v.trim()).filter(Boolean));
27876
+ }
27877
+ }
27878
+ if (trimmed.startsWith("tags:")) {
27879
+ const match = trimmed.match(/\[(.*?)\]/);
27880
+ if (match) {
27881
+ tags.push(...match[1].split(",").map((t) => t.trim()).filter(Boolean));
27882
+ }
27883
+ }
27884
+ }
27885
+ return {
27886
+ name,
27887
+ title,
27888
+ description,
27889
+ template,
27890
+ variables: variables.length > 0 ? variables : undefined,
27891
+ tags: tags.length > 0 ? tags : undefined
27892
+ };
27893
+ }
27894
+ }
27895
+ return {
27896
+ name,
27897
+ title: name,
27898
+ description: "",
27899
+ template: content.trim()
27900
+ };
27901
+ }
27902
+ function renderPrompt(memoryDir, name, args = {}, contextData = {}) {
27903
+ const prompt = getPrompt(memoryDir, name);
27904
+ if (!prompt) {
27905
+ throw new Error(`Prompt template "${name}" not found`);
27906
+ }
27907
+ let text = prompt.template;
27908
+ const nowStr = args.date ?? new Date().toISOString().split("T")[0];
27909
+ text = text.replace(/\{\{date\}\}/g, nowStr);
27910
+ text = text.replace(/\{\{focus\}\}/g, args.focus ?? "General Development");
27911
+ text = text.replace(/\{\{project\}\}/g, args.project ?? "core");
27912
+ text = text.replace(/\{\{target\}\}/g, args.target ?? "release");
27913
+ text = text.replace(/\{\{period\}\}/g, args.period ?? "current sprint");
27914
+ if (memoryDir) {
27915
+ const currentPath = join32(memoryDir, "CURRENT.md");
27916
+ let currentConstraints = "*(None recorded)*";
27917
+ if (existsSync35(currentPath)) {
27918
+ currentConstraints = readFileSync29(currentPath, "utf-8").trim();
27919
+ }
27920
+ text = text.replace(/\{\{current_constraints\}\}/g, currentConstraints);
27921
+ text = text.replace(/\{\{overdue_items\}\}/g, contextData.overdue_items ?? "*(No overdue items)*");
27922
+ text = text.replace(/\{\{recent_discoveries\}\}/g, contextData.recent_discoveries ?? "*(None recorded)*");
27923
+ text = text.replace(/\{\{arch_memories\}\}/g, contextData.arch_memories ?? "*(See .memory/memories/)*");
27924
+ }
27925
+ for (const [key, val] of Object.entries(args)) {
27926
+ const regex = new RegExp(`\\{\\{${key}\\}\\}`, "g");
27927
+ text = text.replace(regex, val);
27928
+ }
27929
+ return text;
27930
+ }
27931
+ var BUILTIN_PROMPTS;
27932
+ var init_prompts = __esm(() => {
27933
+ BUILTIN_PROMPTS = [
27934
+ {
27935
+ name: "morning-standup",
27936
+ title: "Morning Cognitive Standup & Invariant Briefing",
27937
+ description: "Gathers overdue items, active constraints, and recent session discoveries.",
27938
+ variables: ["date", "focus"],
27939
+ tags: ["standup", "planning", "governance"],
27940
+ template: `### Morning Cognitive Standup Briefing
27941
+ Date: {{date}}
27942
+ Focus: {{focus}}
27943
+
27944
+ #### 1. Active Working Constraints (CURRENT.md)
27945
+ {{current_constraints}}
27946
+
27947
+ #### 2. Overdue & Due-Soon Action Items
27948
+ {{overdue_items}}
27949
+
27950
+ #### 3. Recent Discoveries & Fixes
27951
+ {{recent_discoveries}}
27952
+
27953
+ #### Strategic Question:
27954
+ What is the highest-leverage task to execute today that satisfies all active invariants?`
27955
+ },
27956
+ {
27957
+ name: "drift-audit",
27958
+ title: "CodeGraph AST Drift Audit",
27959
+ description: "Compares CodeGraph AST symbols against confirmed architectural memories.",
27960
+ variables: ["project"],
27961
+ tags: ["ast", "drift", "audit"],
27962
+ template: `### AST Symbol Drift Audit
27963
+ Project: {{project}}
27964
+
27965
+ #### 1. Confirmed Architectural Memories & Referenced Symbols
27966
+ {{arch_memories}}
27967
+
27968
+ #### 2. AST Drift Status
27969
+ Scan workspace codebase symbols against memory references. Flag any symbols that were renamed, deleted, or signature-changed without corresponding memory updates.`
27970
+ },
27971
+ {
27972
+ name: "pre-publish-audit",
27973
+ title: "Pre-Publish & Delivery Gate Audit",
27974
+ description: "Scans diffs for secrets, unverified claims, and broken references.",
27975
+ variables: ["target"],
27976
+ tags: ["security", "claims", "verification"],
27977
+ template: `### Pre-Publish Delivery Gate Audit
27978
+ Target: {{target}}
27979
+
27980
+ 1. **Vibeguard Secret Check**: Zero API keys, private tokens, or connection strings in code or documentation.
27981
+ 2. **Claim Ledger Verification**: All claims tagged with [RAW], [FETCH], [SEARCH], or [INFER] must have valid source references.
27982
+ 3. **Wikilink & Reference Integrity**: Verify that all interlinked concepts and memory IDs resolve cleanly.
27983
+ 4. **Test Suite Status**: Confirm all unit and integration tests pass with 0 failures.`
27984
+ },
27985
+ {
27986
+ name: "sprint-compounding",
27987
+ title: "Sprint Knowledge Compounding & Wiki Synthesis",
27988
+ description: "Clusters candidate memories and triggers wiki compilation.",
27989
+ variables: ["period"],
27990
+ tags: ["compounding", "wiki", "synthesis"],
27991
+ template: `### Sprint Knowledge Compounding
27992
+ Period: {{period}}
27993
+
27994
+ 1. Review candidate memories and cluster related insights.
27995
+ 2. Promote verified candidates to confirmed status.
27996
+ 3. Mark superseded and decaying entries as stale.
27997
+ 4. Compile Obsidian-compatible wiki concept pages and update .memory/HOT.md working memory cache.`
27998
+ }
27999
+ ];
28000
+ });
28001
+
28002
+ // src/compounding/temporal.ts
28003
+ import { existsSync as existsSync36, readFileSync as readFileSync30, writeFileSync as writeFileSync22, mkdirSync as mkdirSync24 } from "node:fs";
28004
+ import { join as join33 } from "node:path";
28005
+ function getPeriodKey(dateInput, period) {
28006
+ const date4 = typeof dateInput === "string" ? new Date(dateInput) : dateInput;
28007
+ const year = date4.getUTCFullYear();
28008
+ const month = date4.getUTCMonth() + 1;
28009
+ if (period === "month") {
28010
+ return `${year}-${String(month).padStart(2, "0")}`;
28011
+ }
28012
+ if (period === "quarter") {
28013
+ const q = Math.ceil(month / 3);
28014
+ return `${year}-Q${q}`;
28015
+ }
28016
+ const target = new Date(date4.valueOf());
28017
+ const dayNr = (date4.getUTCDay() + 6) % 7;
28018
+ target.setUTCDate(target.getUTCDate() - dayNr + 3);
28019
+ const firstThursday = target.valueOf();
28020
+ target.setUTCMonth(0, 1);
28021
+ if (target.getUTCDay() !== 4) {
28022
+ target.setUTCMonth(0, 1 + (4 - target.getUTCDay() + 7) % 7);
28023
+ }
28024
+ const weekNumber = 1 + Math.ceil((firstThursday - target.valueOf()) / 604800000);
28025
+ return `${year}-W${String(weekNumber).padStart(2, "0")}`;
28026
+ }
28027
+ function compileHotCache(store, memoryDir) {
28028
+ const currentPath = join33(memoryDir, "CURRENT.md");
28029
+ let constraintsBlock = "*(No active constraints)*";
28030
+ if (existsSync36(currentPath)) {
28031
+ constraintsBlock = readFileSync30(currentPath, "utf-8").trim();
28032
+ }
28033
+ const entries = list(store);
28034
+ const confirmed = entries.filter((e) => e.status === "confirmed" || e.status === "active");
28035
+ const archEntries = confirmed.filter((e) => e.type === "architecture").slice(0, 5);
28036
+ const fixEntries = confirmed.filter((e) => e.type === "fix").slice(0, 5);
28037
+ const prefEntries = confirmed.filter((e) => e.type === "preference").slice(0, 5);
28038
+ const lines = [
28039
+ "# HOT Working Memory Cache",
28040
+ `> **Last Compiled**: ${new Date().toISOString()}`,
28041
+ "",
28042
+ "## 1. Active Constraints & Invariants (CURRENT.md)",
28043
+ constraintsBlock,
28044
+ "",
28045
+ "## 2. Key Architecture Invariants"
28046
+ ];
28047
+ if (archEntries.length === 0) {
28048
+ lines.push("*(No confirmed architectural memories)*");
28049
+ } else {
28050
+ for (const e of archEntries) {
28051
+ lines.push(`- **${e.title}** (\`${e.id}\`): ${e.content.slice(0, 140)}...`);
28052
+ }
28053
+ }
28054
+ lines.push("", "## 3. High-Priority Fixes & Workarounds");
28055
+ if (fixEntries.length === 0) {
28056
+ lines.push("*(No confirmed bug fixes)*");
28057
+ } else {
28058
+ for (const e of fixEntries) {
28059
+ lines.push(`- **${e.title}** (\`${e.id}\`): ${e.content.slice(0, 140)}...`);
28060
+ }
28061
+ }
28062
+ if (prefEntries.length > 0) {
28063
+ lines.push("", "## 4. Key Developer Preferences");
28064
+ for (const e of prefEntries) {
28065
+ lines.push(`- **${e.title}**: ${e.content.slice(0, 140)}...`);
28066
+ }
28067
+ }
28068
+ const hotContent = lines.join(`
28069
+ `) + `
28070
+ `;
28071
+ const hotPath = join33(memoryDir, "HOT.md");
28072
+ mkdirSync24(memoryDir, { recursive: true });
28073
+ writeFileSync22(hotPath, hotContent, "utf-8");
28074
+ return hotPath;
28075
+ }
28076
+ function rollupTemporal(store, options) {
28077
+ const { memoryDir, period } = options;
28078
+ const targetDate = options.date ?? new Date;
28079
+ const periodKey = getPeriodKey(targetDate, period);
28080
+ let entries = list(store).filter((e) => e.status === "confirmed" || e.status === "active" || e.status === "candidate");
28081
+ if (options.project) {
28082
+ entries = entries.filter((e) => e.project === options.project);
28083
+ }
28084
+ const arch = entries.filter((e) => e.type === "architecture");
28085
+ const fixes = entries.filter((e) => e.type === "fix");
28086
+ const decisions = entries.filter((e) => e.type === "decision");
28087
+ const discoveries = entries.filter((e) => e.type === "discovery");
28088
+ const periodLabel = period === "week" ? "Weekly Synthesis" : period === "month" ? "Monthly Synthesis" : "Quarterly Synthesis";
28089
+ const lines = [
28090
+ `# ${periodLabel}: ${periodKey}`,
28091
+ `> **Compounding Window**: ${periodKey} | **Evaluated Memories**: ${entries.length} | **Generated**: ${new Date().toISOString()}`,
28092
+ "",
28093
+ "## \uD83C\uDFDB️ System Architecture & Invariants"
28094
+ ];
28095
+ if (arch.length === 0) {
28096
+ lines.push("*(No architectural changes in this period)*");
28097
+ } else {
28098
+ for (const a of arch) {
28099
+ lines.push(`- **${a.title}** (\`${a.id}\`) [${a.status}]`);
28100
+ lines.push(` ${a.content}`);
28101
+ }
28102
+ }
28103
+ lines.push("", "## \uD83D\uDEE0️ Resolved Fixes & Incident Workarounds");
28104
+ if (fixes.length === 0) {
28105
+ lines.push("*(No fixes recorded in this period)*");
28106
+ } else {
28107
+ for (const f of fixes) {
28108
+ lines.push(`- **${f.title}** (\`${f.id}\`)`);
28109
+ lines.push(` ${f.content}`);
28110
+ }
28111
+ }
28112
+ lines.push("", "## \uD83D\uDCA1 Key Decisions & Discoveries");
28113
+ const combined = [...decisions, ...discoveries];
28114
+ if (combined.length === 0) {
28115
+ lines.push("*(No new decisions or discoveries)*");
28116
+ } else {
28117
+ for (const d of combined) {
28118
+ lines.push(`- **${d.title}** (\`${d.id}\`)`);
28119
+ lines.push(` ${d.content}`);
28120
+ }
28121
+ }
28122
+ const summary = `Compiled ${entries.length} memories into ${periodKey} rollup.`;
28123
+ lines.push("", "---", `*Generated by Muse Memory Temporal Compounding Engine*`);
28124
+ const rollupDir = join33(memoryDir, "wiki", "rollups");
28125
+ mkdirSync24(rollupDir, { recursive: true });
28126
+ const filePath = join33(rollupDir, `${periodKey}.md`);
28127
+ writeFileSync22(filePath, lines.join(`
28128
+ `) + `
28129
+ `, "utf-8");
28130
+ const hotMdPath = compileHotCache(store, memoryDir);
28131
+ return {
28132
+ filePath,
28133
+ periodKey,
28134
+ summary,
28135
+ entriesCount: entries.length,
28136
+ hotMdPath
28137
+ };
28138
+ }
28139
+ var init_temporal = __esm(() => {
28140
+ init_store();
28141
+ });
28142
+
28143
+ // src/iterations.ts
28144
+ import { existsSync as existsSync37, readFileSync as readFileSync31, appendFileSync as appendFileSync2, writeFileSync as writeFileSync23, mkdirSync as mkdirSync25 } from "node:fs";
28145
+ import { join as join34 } from "node:path";
28146
+ function getIterationsFilePath(memoryDir) {
28147
+ return join34(memoryDir, "iterations.jsonl");
28148
+ }
28149
+ function recordIteration(memoryDir, input) {
28150
+ const textToScan = `${input.largest_fix_identified}
28151
+ ${input.test_results}`;
28152
+ const secrets = scanSecrets(textToScan);
28153
+ if (secrets.length > 0) {
28154
+ throw new Error(`Vibeguard: Detected secret in iteration record: ${secrets.join(", ")}`);
28155
+ }
28156
+ const entry = {
28157
+ iteration_index: input.iteration_index,
28158
+ critic_verdict: input.critic_verdict,
28159
+ largest_fix_identified: input.largest_fix_identified,
28160
+ test_results: input.test_results,
28161
+ diff_hash: input.diff_hash,
28162
+ timestamp: input.timestamp ?? new Date().toISOString(),
28163
+ metadata: input.metadata
28164
+ };
28165
+ mkdirSync25(memoryDir, { recursive: true });
28166
+ const filePath = getIterationsFilePath(memoryDir);
28167
+ appendFileSync2(filePath, JSON.stringify(entry) + `
28168
+ `, "utf-8");
28169
+ return entry;
28170
+ }
28171
+ function listIterations(memoryDir) {
28172
+ const filePath = getIterationsFilePath(memoryDir);
28173
+ if (!existsSync37(filePath)) {
28174
+ return [];
28175
+ }
28176
+ try {
28177
+ const raw = readFileSync31(filePath, "utf-8");
28178
+ return raw.split(`
28179
+ `).map((l) => l.trim()).filter(Boolean).map((l) => JSON.parse(l));
28180
+ } catch {
28181
+ return [];
28182
+ }
28183
+ }
28184
+ function clearIterations(memoryDir) {
28185
+ const filePath = getIterationsFilePath(memoryDir);
28186
+ if (existsSync37(filePath)) {
28187
+ writeFileSync23(filePath, "", "utf-8");
28188
+ }
28189
+ }
28190
+ function detectIterationStatus(memoryDir) {
28191
+ const iterations = listIterations(memoryDir);
28192
+ if (iterations.length === 0) {
28193
+ return {
28194
+ totalIterations: 0,
28195
+ isPlateaued: false,
28196
+ isRegressed: false,
28197
+ consecutiveFailures: 0,
28198
+ recommendation: "No active iteration loops recorded."
28199
+ };
28200
+ }
28201
+ const last = iterations[iterations.length - 1];
28202
+ let consecutiveFailures = 0;
28203
+ for (let i = iterations.length - 1;i >= 0; i--) {
28204
+ if (iterations[i].critic_verdict !== "pass") {
28205
+ consecutiveFailures++;
28206
+ } else {
28207
+ break;
28208
+ }
28209
+ }
28210
+ const isRegressed = last.critic_verdict === "regressed";
28211
+ let isPlateaued = last.critic_verdict === "plateaued" || consecutiveFailures >= 3;
28212
+ if (!isPlateaued && iterations.length >= 2) {
28213
+ const prev = iterations[iterations.length - 2];
28214
+ if (last.diff_hash && prev.diff_hash && last.diff_hash === prev.diff_hash) {
28215
+ isPlateaued = true;
28216
+ }
28217
+ }
28218
+ let recommendation = "Proceed with next improvement iteration.";
28219
+ if (isRegressed) {
28220
+ recommendation = "Revert last change immediately: regression detected in test results.";
28221
+ } else if (isPlateaued) {
28222
+ recommendation = "Halt iteration loop: Plateau detected (no improvement or repeated state). Human review required.";
28223
+ } else if (last.critic_verdict === "pass") {
28224
+ recommendation = "Loop passed: All criteria and tests verified. Ready to ship.";
28225
+ }
28226
+ return {
28227
+ totalIterations: iterations.length,
28228
+ lastVerdict: last.critic_verdict,
28229
+ isPlateaued,
28230
+ isRegressed,
28231
+ consecutiveFailures,
28232
+ recommendation
28233
+ };
28234
+ }
28235
+ var init_iterations = __esm(() => {
28236
+ init_secrets();
28237
+ });
28238
+
28239
+ // src/retrieval/tiered.ts
28240
+ function queryTieredContext(store, memoryDir, query = "", options = {}) {
28241
+ const tier = options.tier ?? 2;
28242
+ if (tier === 2) {
28243
+ return formatPromptContext(store, memoryDir, query, options);
28244
+ }
28245
+ const queryResult = queryContext(store, query, options);
28246
+ const constraints = memoryDir ? syncConstraints(memoryDir, store) : [];
28247
+ const userProfile = getUserProfile(memoryDir, { query });
28248
+ const coreBlock = formatCoreBlock(memoryDir);
28249
+ if (tier === 0) {
28250
+ const parts2 = [];
28251
+ parts2.push("### Memory Manifest (Tier 0)");
28252
+ if (queryResult.results.length === 0) {
28253
+ parts2.push("*(No matching memories)*");
28254
+ } else {
28255
+ for (const item of queryResult.results) {
28256
+ const t = item.entry.type ? `[${item.entry.type}] ` : "";
28257
+ parts2.push(`- \`${item.entry.id}\` ${t}${item.entry.title}`);
28258
+ }
28259
+ }
28260
+ const markdown2 = parts2.join(`
28261
+ `);
28262
+ const totalTokensUsed2 = Math.ceil(markdown2.length / 4);
28263
+ return {
28264
+ markdown: markdown2,
28265
+ entries: queryResult.results,
28266
+ totalTokensUsed: totalTokensUsed2,
28267
+ constraints,
28268
+ userProfile
28269
+ };
28270
+ }
28271
+ const parts = [];
28272
+ if (userProfile) {
28273
+ parts.push("### User Profile & Preferences (USER.md)");
28274
+ parts.push(userProfile);
28275
+ parts.push("");
28276
+ }
28277
+ if (coreBlock) {
28278
+ parts.push("### Core Memory (CORE.md)");
28279
+ parts.push(coreBlock);
28280
+ parts.push("");
28281
+ }
28282
+ if (constraints.length > 0) {
28283
+ parts.push("### Active Working Constraints (CURRENT.md)");
28284
+ for (const c of constraints) {
28285
+ parts.push(`- ${c}`);
28286
+ }
28287
+ parts.push("");
28288
+ }
28289
+ parts.push("### Domain Routing Invariants (Tier 1)");
28290
+ if (queryResult.results.length === 0) {
28291
+ parts.push("*(No matching invariant routes)*");
28292
+ } else {
28293
+ for (const item of queryResult.results) {
28294
+ const t = item.entry.type ? `[${item.entry.type}] ` : "";
28295
+ const tags = item.entry.tags && item.entry.tags.length > 0 ? ` (tags: ${item.entry.tags.join(", ")})` : "";
28296
+ parts.push(`- \`${item.entry.id}\` ${t}${item.entry.title}${tags}`);
28297
+ }
28298
+ }
28299
+ const markdown = parts.join(`
28300
+ `);
28301
+ const totalTokensUsed = Math.ceil(markdown.length / 4);
28302
+ return {
28303
+ markdown,
28304
+ entries: queryResult.results,
28305
+ totalTokensUsed,
28306
+ constraints,
28307
+ userProfile
28308
+ };
28309
+ }
28310
+ var init_tiered = __esm(() => {
28311
+ init_retrieval();
28312
+ init_governor();
28313
+ init_user();
28314
+ init_core();
28315
+ });
28316
+
26921
28317
  // src/plasticity.ts
26922
28318
  var exports_plasticity = {};
26923
28319
  __export(exports_plasticity, {
@@ -26927,17 +28323,17 @@ __export(exports_plasticity, {
26927
28323
  recordCoActivation: () => recordCoActivation,
26928
28324
  saveHebbianGraph: () => saveHebbianGraph
26929
28325
  });
26930
- import { existsSync as existsSync31, readFileSync as readFileSync25, writeFileSync as writeFileSync17 } from "node:fs";
26931
- import { join as join28 } from "node:path";
28326
+ import { existsSync as existsSync38, readFileSync as readFileSync32, writeFileSync as writeFileSync24 } from "node:fs";
28327
+ import { join as join35 } from "node:path";
26932
28328
  function getPlasticityPath(memoryDir) {
26933
- return join28(memoryDir, "hebbian-plasticity.json");
28329
+ return join35(memoryDir, "hebbian-plasticity.json");
26934
28330
  }
26935
28331
  function loadHebbianGraph(memoryDir) {
26936
28332
  const p = getPlasticityPath(memoryDir);
26937
- if (!existsSync31(p))
28333
+ if (!existsSync38(p))
26938
28334
  return {};
26939
28335
  try {
26940
- return JSON.parse(readFileSync25(p, "utf8"));
28336
+ return JSON.parse(readFileSync32(p, "utf8"));
26941
28337
  } catch {
26942
28338
  return {};
26943
28339
  }
@@ -26945,7 +28341,7 @@ function loadHebbianGraph(memoryDir) {
26945
28341
  function saveHebbianGraph(memoryDir, graph) {
26946
28342
  const p = getPlasticityPath(memoryDir);
26947
28343
  try {
26948
- writeFileSync17(p, JSON.stringify(graph, null, 2), "utf8");
28344
+ writeFileSync24(p, JSON.stringify(graph, null, 2), "utf8");
26949
28345
  } catch {}
26950
28346
  }
26951
28347
  function recordCoActivation(memoryIds, memoryDir) {
@@ -27036,8 +28432,8 @@ __export(exports_drift, {
27036
28432
  scanCodeDriftFromDiff: () => scanCodeDriftFromDiff
27037
28433
  });
27038
28434
  import { execSync as execSync3 } from "node:child_process";
27039
- import { existsSync as existsSync32 } from "node:fs";
27040
- import { join as join29, isAbsolute as isAbsolute2 } from "node:path";
28435
+ import { existsSync as existsSync39 } from "node:fs";
28436
+ import { join as join36, isAbsolute as isAbsolute2 } from "node:path";
27041
28437
  function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
27042
28438
  const root = workspaceRoot || process.cwd();
27043
28439
  const normalizedChanged = new Set(changedFiles.map((f) => f.trim().replace(/^[\.\/]+/, "")).filter(Boolean));
@@ -27051,8 +28447,8 @@ function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
27051
28447
  const norm = p.trim().replace(/^[\.\/]+/, "");
27052
28448
  const matched = Array.from(normalizedChanged).find((cf) => cf === norm || cf.endsWith(`/${norm}`) || norm.endsWith(`/${cf}`));
27053
28449
  if (matched) {
27054
- const fullPath = isAbsolute2(p) ? p : join29(root, p);
27055
- const exists = existsSync32(fullPath);
28450
+ const fullPath = isAbsolute2(p) ? p : join36(root, p);
28451
+ const exists = existsSync39(fullPath);
27056
28452
  drifted.push({
27057
28453
  memoryId: entry.id,
27058
28454
  title: entry.title,
@@ -27126,12 +28522,13 @@ var init_drift = __esm(() => {
27126
28522
  // src/mcp.ts
27127
28523
  var exports_mcp = {};
27128
28524
  __export(exports_mcp, {
28525
+ createServer: () => createServer2,
27129
28526
  runMcpServer: () => runMcpServer
27130
28527
  });
27131
28528
  import { basename } from "node:path";
27132
- async function runMcpServer() {
27133
- const targetDir = process.env.MUSE_MEMORY_PROJECT_DIR || process.env.PROJECT_ROOT || process.cwd();
27134
- const { root, memoryDir } = findOrCreateProjectRoot(targetDir);
28529
+ function createServer2(targetDir) {
28530
+ const resolvedTarget = targetDir || process.env.MUSE_MEMORY_PROJECT_DIR || process.env.PROJECT_ROOT || process.cwd();
28531
+ const { root, memoryDir } = findOrCreateProjectRoot(resolvedTarget);
27135
28532
  const store = openStore(memoryDir);
27136
28533
  function resolveStoreForRequest(a) {
27137
28534
  const dir = a?.dir || a?.workspace || a?.project_dir || a?.cwd;
@@ -27179,7 +28576,8 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
27179
28576
  type: { type: "string" },
27180
28577
  status: { type: "string" },
27181
28578
  verified: { type: "boolean" },
27182
- depth: { type: "string", enum: ["L1", "L2", "L3"], description: "Progressive disclosure tier: L1 = id+title lines, L2 = title+content+tags (default), L3 = full raw entry" }
28579
+ depth: { type: "string", enum: ["L1", "L2", "L3"], description: "Progressive disclosure tier: L1 = id+title lines, L2 = title+content+tags (default), L3 = full raw entry" },
28580
+ tier: { type: "number", description: "Deterministic retrieval tier: 0 (manifest index), 1 (routing set), 2 (bounded bodies, default)" }
27183
28581
  }
27184
28582
  }
27185
28583
  },
@@ -27646,97 +29044,265 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
27646
29044
  }
27647
29045
  },
27648
29046
  {
27649
- name: "memory_entities_search",
27650
- description: "List extracted entities by type or project",
29047
+ name: "memory_entities_search",
29048
+ description: "List extracted entities by type or project",
29049
+ inputSchema: {
29050
+ type: "object",
29051
+ properties: {
29052
+ type: { type: "string", enum: ["person", "product", "organization", "file", "concept"], description: "Filter by entity type" },
29053
+ project: { type: "string", description: "Filter by project" }
29054
+ }
29055
+ }
29056
+ },
29057
+ {
29058
+ name: "memory_pageindex_index",
29059
+ description: "Build a PageIndex-style hierarchical tree index from document/text for reasoning-based retrieval",
29060
+ inputSchema: {
29061
+ type: "object",
29062
+ properties: {
29063
+ content: { type: "string", description: "Document text content (max 10MB)" },
29064
+ project: { type: "string", description: "Project to associate the index with" },
29065
+ title: { type: "string", description: "Optional title for the index" },
29066
+ maxDepth: { type: "number", description: "Max tree depth (default: 5)" },
29067
+ dryRun: { type: "boolean", description: "Preview without persisting" }
29068
+ },
29069
+ required: ["content", "project"]
29070
+ }
29071
+ },
29072
+ {
29073
+ name: "memory_pageindex_search",
29074
+ description: "Search a PageIndex tree index with reasoning-based retrieval",
29075
+ inputSchema: {
29076
+ type: "object",
29077
+ properties: {
29078
+ indexId: { type: "string", description: "Tree index ID to search" },
29079
+ query: { type: "string", description: "Search query" },
29080
+ project: { type: "string", description: "Project scope" },
29081
+ tokenBudget: { type: "number", description: "Maximum token budget" },
29082
+ maxDepth: { type: "number", description: "Max search depth" }
29083
+ },
29084
+ required: ["indexId", "query"]
29085
+ }
29086
+ },
29087
+ {
29088
+ name: "memory_pageindex_import",
29089
+ description: "Import PageIndex search results/insights as memory entries",
29090
+ inputSchema: {
29091
+ type: "object",
29092
+ properties: {
29093
+ indexId: { type: "string", description: "Tree index ID" },
29094
+ query: { type: "string", description: "Search query" },
29095
+ project: { type: "string", description: "Project scope" },
29096
+ type: { type: "string", description: "Memory type (default: discovery)" },
29097
+ confirmed: { type: "boolean", description: "Auto-confirm imported entries" }
29098
+ },
29099
+ required: ["indexId", "query", "project"]
29100
+ }
29101
+ },
29102
+ {
29103
+ name: "memory_disconnect_pageindex",
29104
+ description: "Disconnect PageIndex MCP tools and remove associated indexes",
29105
+ inputSchema: {
29106
+ type: "object",
29107
+ properties: {
29108
+ indexId: { type: "string", description: "Specific index to remove, or omit for all" },
29109
+ project: { type: "string", description: "Project scope" }
29110
+ }
29111
+ }
29112
+ },
29113
+ {
29114
+ name: "memory_settings_get",
29115
+ description: "Read unified global or project configuration settings",
29116
+ inputSchema: {
29117
+ type: "object",
29118
+ properties: {
29119
+ project: { type: "string", description: "Optional project scope override" }
29120
+ }
29121
+ }
29122
+ },
29123
+ {
29124
+ name: "memory_settings_set",
29125
+ description: "Update unified global or project configuration settings",
29126
+ inputSchema: {
29127
+ type: "object",
29128
+ properties: {
29129
+ settings: { type: "object", description: "Settings object to merge" },
29130
+ project: { type: "string", description: "Optional project scope override" }
29131
+ },
29132
+ required: ["settings"]
29133
+ }
29134
+ },
29135
+ {
29136
+ name: "memory_drift",
29137
+ description: "Scan the local Git workspace for modified or deleted code files and AST symbols referenced by memories. Flags drifted memories for re-verification or supersession.",
29138
+ inputSchema: {
29139
+ type: "object",
29140
+ properties: {
29141
+ dir: { type: "string", description: "Optional project workspace directory path" }
29142
+ }
29143
+ }
29144
+ },
29145
+ {
29146
+ name: "memory_compress",
29147
+ description: "Compress formatted prompt context losslessly, stripping header whitespace and boilerplate while preserving all architectural facts.",
29148
+ inputSchema: {
29149
+ type: "object",
29150
+ properties: {
29151
+ text: { type: "string", description: "Markdown prompt context to compress" },
29152
+ level: { type: "string", enum: ["light", "aggressive"], description: "Compression aggressiveness level" }
29153
+ },
29154
+ required: ["text"]
29155
+ }
29156
+ },
29157
+ {
29158
+ name: "memory_source_add",
29159
+ description: "Record external documentation, research paper, RFC, or URL into the provenance Source Ledger",
29160
+ inputSchema: {
29161
+ type: "object",
29162
+ properties: {
29163
+ url: { type: "string" },
29164
+ title: { type: "string" },
29165
+ source_type: { type: "string", description: "Source classification: primary | secondary | documentation | rfc | repo | article" },
29166
+ excerpt: { type: "string", description: "Key quote or summary excerpt from source" },
29167
+ author: { type: "string", description: "Author or organization" },
29168
+ dir: { type: "string", description: "Optional project workspace directory path" }
29169
+ },
29170
+ required: ["url", "title"]
29171
+ }
29172
+ },
29173
+ {
29174
+ name: "memory_source_list",
29175
+ description: "List recorded external sources in the Source Ledger",
29176
+ inputSchema: {
29177
+ type: "object",
29178
+ properties: {
29179
+ source_type: { type: "string" },
29180
+ query: { type: "string" },
29181
+ dir: { type: "string", description: "Optional project workspace directory path" }
29182
+ }
29183
+ }
29184
+ },
29185
+ {
29186
+ name: "memory_claim_record",
29187
+ description: "Record an evidence-backed claim into the Claim Ledger connected to sources and confidence tags ([RAW], [FETCH], [SEARCH], [INFER])",
29188
+ inputSchema: {
29189
+ type: "object",
29190
+ properties: {
29191
+ claim: { type: "string" },
29192
+ confidence_tag: { type: "string", enum: ["RAW", "FETCH", "SEARCH", "INFER"], description: "Confidence level: RAW (locally verified), FETCH (authoritative URL), SEARCH (synthesized search), INFER (agent deduction)" },
29193
+ source_ids: { type: "array", items: { type: "string" } },
29194
+ memory_ids: { type: "array", items: { type: "string" } },
29195
+ notes: { type: "string" },
29196
+ verified: { type: "boolean" },
29197
+ dir: { type: "string", description: "Optional project workspace directory path" }
29198
+ },
29199
+ required: ["claim"]
29200
+ }
29201
+ },
29202
+ {
29203
+ name: "memory_claim_list",
29204
+ description: "List recorded claims in the Claim Ledger",
29205
+ inputSchema: {
29206
+ type: "object",
29207
+ properties: {
29208
+ confidence_tag: { type: "string", enum: ["RAW", "FETCH", "SEARCH", "INFER"] },
29209
+ query: { type: "string" },
29210
+ verified: { type: "boolean" },
29211
+ dir: { type: "string", description: "Optional project workspace directory path" }
29212
+ }
29213
+ }
29214
+ },
29215
+ {
29216
+ name: "memory_freeze_run",
29217
+ description: "Capture an immutable execution snapshot (active task, file inventory, git SHA, CURRENT constraints, memory SHA-256 hashes) in .memory/runs/<run-id>/",
27651
29218
  inputSchema: {
27652
29219
  type: "object",
27653
29220
  properties: {
27654
- type: { type: "string", enum: ["person", "product", "organization", "file", "concept"], description: "Filter by entity type" },
27655
- project: { type: "string", description: "Filter by project" }
27656
- }
29221
+ task: { type: "string", description: "Task description or path to task markdown file" },
29222
+ run_id: { type: "string", description: "Optional unique run identifier" },
29223
+ dir: { type: "string", description: "Optional project workspace directory path" }
29224
+ },
29225
+ required: ["task"]
27657
29226
  }
27658
29227
  },
27659
29228
  {
27660
- name: "memory_pageindex_index",
27661
- description: "Build a PageIndex-style hierarchical tree index from document/text for reasoning-based retrieval",
29229
+ name: "memory_freeze_list",
29230
+ description: "List recorded frozen execution snapshots in .memory/runs/",
27662
29231
  inputSchema: {
27663
29232
  type: "object",
27664
29233
  properties: {
27665
- content: { type: "string", description: "Document text content (max 10MB)" },
27666
- project: { type: "string", description: "Project to associate the index with" },
27667
- title: { type: "string", description: "Optional title for the index" },
27668
- maxDepth: { type: "number", description: "Max tree depth (default: 5)" },
27669
- dryRun: { type: "boolean", description: "Preview without persisting" }
27670
- },
27671
- required: ["content", "project"]
29234
+ dir: { type: "string", description: "Optional project workspace directory path" }
29235
+ }
27672
29236
  }
27673
29237
  },
27674
29238
  {
27675
- name: "memory_pageindex_search",
27676
- description: "Search a PageIndex tree index with reasoning-based retrieval",
29239
+ name: "memory_prompt_list",
29240
+ description: "List available structured prompt templates in .memory/prompts/",
27677
29241
  inputSchema: {
27678
29242
  type: "object",
27679
29243
  properties: {
27680
- indexId: { type: "string", description: "Tree index ID to search" },
27681
- query: { type: "string", description: "Search query" },
27682
- project: { type: "string", description: "Project scope" },
27683
- tokenBudget: { type: "number", description: "Maximum token budget" },
27684
- maxDepth: { type: "number", description: "Max search depth" }
27685
- },
27686
- required: ["indexId", "query"]
29244
+ dir: { type: "string", description: "Optional project workspace directory path" }
29245
+ }
27687
29246
  }
27688
29247
  },
27689
29248
  {
27690
- name: "memory_pageindex_import",
27691
- description: "Import PageIndex search results/insights as memory entries",
29249
+ name: "memory_prompt_get",
29250
+ description: "Get prompt template by name",
27692
29251
  inputSchema: {
27693
29252
  type: "object",
27694
29253
  properties: {
27695
- indexId: { type: "string", description: "Tree index ID" },
27696
- query: { type: "string", description: "Search query" },
27697
- project: { type: "string", description: "Project scope" },
27698
- type: { type: "string", description: "Memory type (default: discovery)" },
27699
- confirmed: { type: "boolean", description: "Auto-confirm imported entries" }
29254
+ name: { type: "string" },
29255
+ dir: { type: "string", description: "Optional project workspace directory path" }
27700
29256
  },
27701
- required: ["indexId", "query", "project"]
29257
+ required: ["name"]
27702
29258
  }
27703
29259
  },
27704
29260
  {
27705
- name: "memory_disconnect_pageindex",
27706
- description: "Disconnect PageIndex MCP tools and remove associated indexes",
29261
+ name: "memory_prompt_run",
29262
+ description: "Render prompt template with variable substitution and live memory context injection",
27707
29263
  inputSchema: {
27708
29264
  type: "object",
27709
29265
  properties: {
27710
- indexId: { type: "string", description: "Specific index to remove, or omit for all" },
27711
- project: { type: "string", description: "Project scope" }
27712
- }
29266
+ name: { type: "string" },
29267
+ args: { type: "object", description: "Key-value pairs for prompt template variables" },
29268
+ dir: { type: "string", description: "Optional project workspace directory path" }
29269
+ },
29270
+ required: ["name"]
27713
29271
  }
27714
29272
  },
27715
29273
  {
27716
- name: "memory_settings_get",
27717
- description: "Read unified global or project configuration settings",
29274
+ name: "memory_rollup",
29275
+ description: "Multi-scale temporal compounding: aggregate atomic memories into weekly, monthly, or quarterly synthesis wiki pages and update HOT.md cache",
27718
29276
  inputSchema: {
27719
29277
  type: "object",
27720
29278
  properties: {
27721
- project: { type: "string", description: "Optional project scope override" }
27722
- }
29279
+ period: { type: "string", enum: ["week", "month", "quarter"] },
29280
+ date: { type: "string", description: "Optional target date (YYYY-MM-DD)" },
29281
+ project: { type: "string" },
29282
+ dir: { type: "string", description: "Optional project workspace directory path" }
29283
+ },
29284
+ required: ["period"]
27723
29285
  }
27724
29286
  },
27725
29287
  {
27726
- name: "memory_settings_set",
27727
- description: "Update unified global or project configuration settings",
29288
+ name: "memory_loop_record",
29289
+ description: "Record an iteration round in the multi-agent Gauntlet Iteration Ledger (.memory/iterations.jsonl)",
27728
29290
  inputSchema: {
27729
29291
  type: "object",
27730
29292
  properties: {
27731
- settings: { type: "object", description: "Settings object to merge" },
27732
- project: { type: "string", description: "Optional project scope override" }
29293
+ iteration_index: { type: "number" },
29294
+ critic_verdict: { type: "string", enum: ["pass", "fail", "regressed", "plateaued"] },
29295
+ largest_fix_identified: { type: "string" },
29296
+ test_results: { type: "string" },
29297
+ diff_hash: { type: "string" },
29298
+ dir: { type: "string", description: "Optional project workspace directory path" }
27733
29299
  },
27734
- required: ["settings"]
29300
+ required: ["iteration_index", "critic_verdict", "largest_fix_identified", "test_results"]
27735
29301
  }
27736
29302
  },
27737
29303
  {
27738
- name: "memory_drift",
27739
- description: "Scan the local Git workspace for modified or deleted code files and AST symbols referenced by memories. Flags drifted memories for re-verification or supersession.",
29304
+ name: "memory_loop_status",
29305
+ description: "Inspect multi-round iteration status, plateau warnings, and regression signals",
27740
29306
  inputSchema: {
27741
29307
  type: "object",
27742
29308
  properties: {
@@ -27745,15 +29311,14 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
27745
29311
  }
27746
29312
  },
27747
29313
  {
27748
- name: "memory_compress",
27749
- description: "Compress formatted prompt context losslessly, stripping header whitespace and boilerplate while preserving all architectural facts.",
29314
+ name: "memory_verify_strict",
29315
+ description: "Execute Strict Integrity & Health Gate: audits zero secrets, referential link integrity, wikilinks, orphaned candidates, and claim sources",
27750
29316
  inputSchema: {
27751
29317
  type: "object",
27752
29318
  properties: {
27753
- text: { type: "string", description: "Markdown prompt context to compress" },
27754
- level: { type: "string", enum: ["light", "aggressive"], description: "Compression aggressiveness level" }
27755
- },
27756
- required: ["text"]
29319
+ max_candidate_days: { type: "number" },
29320
+ dir: { type: "string", description: "Optional project workspace directory path" }
29321
+ }
27757
29322
  }
27758
29323
  }
27759
29324
  ]
@@ -27782,7 +29347,17 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
27782
29347
  });
27783
29348
  } catch {}
27784
29349
  }
27785
- const formatted = formatPromptContext(activeStore, activeMemoryDir, queryStr, {
29350
+ const tierOpt = typeof a.tier === "number" ? a.tier : undefined;
29351
+ const formatted = tierOpt !== undefined ? queryTieredContext(activeStore, activeMemoryDir, queryStr, {
29352
+ limit: typeof a.limit === "number" ? a.limit : 5,
29353
+ tokenBudget: typeof a.token_budget === "number" ? a.token_budget : undefined,
29354
+ project: a.project ? String(a.project) : undefined,
29355
+ includeSuperseded: false,
29356
+ type: a.type ? String(a.type) : undefined,
29357
+ status: a.status ? String(a.status) : undefined,
29358
+ verified: a.verified === true,
29359
+ tier: tierOpt
29360
+ }) : formatPromptContext(activeStore, activeMemoryDir, queryStr, {
27786
29361
  limit: typeof a.limit === "number" ? a.limit : 5,
27787
29362
  tokenBudget: typeof a.token_budget === "number" ? a.token_budget : undefined,
27788
29363
  project: a.project ? String(a.project) : undefined,
@@ -27798,6 +29373,12 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
27798
29373
  recordCoActivation2(formatted.entries.map((e) => e.entry.id), activeMemoryDir);
27799
29374
  } catch {}
27800
29375
  }
29376
+ if (activeMemoryDir) {
29377
+ try {
29378
+ const { harvestAllAgentTranscripts: harvestAllAgentTranscripts2 } = await Promise.resolve().then(() => (init_harvester(), exports_harvester));
29379
+ harvestAllAgentTranscripts2(activeStore, { memoryDir: activeMemoryDir, maxFiles: 3 });
29380
+ } catch {}
29381
+ }
27801
29382
  let finalMarkdown = formatted.markdown;
27802
29383
  if (a.compress === true) {
27803
29384
  const { compressPromptContext: compressPromptContext2 } = await Promise.resolve().then(() => exports_compress);
@@ -27890,9 +29471,18 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
27890
29471
  }
27891
29472
  }
27892
29473
  case "memory_harvest": {
29474
+ if (a.all === true || a.auto === true || !a.text) {
29475
+ const { harvestAllAgentTranscripts: harvestAllAgentTranscripts2 } = await Promise.resolve().then(() => (init_harvester(), exports_harvester));
29476
+ const harvestRes = harvestAllAgentTranscripts2(activeStore, {
29477
+ memoryDir: activeMemoryDir,
29478
+ confirmed: a.confirmed === true,
29479
+ project: a.project ? String(a.project) : undefined
29480
+ });
29481
+ return toolResult(harvestRes);
29482
+ }
27893
29483
  const created = harvestMemories(activeStore, {
27894
29484
  text: String(a.text),
27895
- project: String(a.project),
29485
+ project: String(a.project || "default"),
27896
29486
  confirmed: a.confirmed === true
27897
29487
  });
27898
29488
  return toolResult({ harvested_count: created.length, entries: created });
@@ -28250,6 +29840,99 @@ Path: ${item.path}`,
28250
29840
  const result = compressPromptContext2(text, { level });
28251
29841
  return toolResult(result);
28252
29842
  }
29843
+ case "memory_source_add": {
29844
+ const source = addSource(activeMemoryDir, {
29845
+ url: String(a.url),
29846
+ title: String(a.title),
29847
+ source_type: a.source_type ? String(a.source_type) : undefined,
29848
+ excerpt: a.excerpt ? String(a.excerpt) : undefined,
29849
+ author: a.author ? String(a.author) : undefined
29850
+ });
29851
+ return toolResult(source);
29852
+ }
29853
+ case "memory_source_list": {
29854
+ const sources = listSources(activeMemoryDir, {
29855
+ query: a.query ? String(a.query) : undefined,
29856
+ source_type: a.source_type ? String(a.source_type) : undefined
29857
+ });
29858
+ return toolResult(sources);
29859
+ }
29860
+ case "memory_claim_record": {
29861
+ const claim = recordClaim(activeMemoryDir, {
29862
+ claim: String(a.claim),
29863
+ confidence_tag: a.confidence_tag,
29864
+ source_ids: Array.isArray(a.source_ids) ? a.source_ids.map(String) : undefined,
29865
+ memory_ids: Array.isArray(a.memory_ids) ? a.memory_ids.map(String) : undefined,
29866
+ notes: a.notes ? String(a.notes) : undefined,
29867
+ verified: a.verified === true
29868
+ });
29869
+ return toolResult(claim);
29870
+ }
29871
+ case "memory_claim_list": {
29872
+ const claims = listClaims(activeMemoryDir, {
29873
+ confidence_tag: a.confidence_tag ? String(a.confidence_tag) : undefined,
29874
+ query: a.query ? String(a.query) : undefined,
29875
+ verified: typeof a.verified === "boolean" ? a.verified : undefined
29876
+ });
29877
+ return toolResult(claims);
29878
+ }
29879
+ case "memory_freeze_run": {
29880
+ const snapshot = freezeExecutionSnapshot({
29881
+ workspaceRoot: activeRoot,
29882
+ memoryDir: activeMemoryDir,
29883
+ task: String(a.task),
29884
+ runId: a.run_id ? String(a.run_id) : undefined,
29885
+ store: activeStore
29886
+ });
29887
+ return toolResult(snapshot);
29888
+ }
29889
+ case "memory_freeze_list": {
29890
+ const snapshots = listExecutionSnapshots(activeMemoryDir);
29891
+ return toolResult(snapshots);
29892
+ }
29893
+ case "memory_prompt_list": {
29894
+ const prompts = listPrompts(activeMemoryDir);
29895
+ return toolResult(prompts);
29896
+ }
29897
+ case "memory_prompt_get": {
29898
+ const prompt = getPrompt(activeMemoryDir, String(a.name));
29899
+ if (!prompt)
29900
+ return toolError(`Prompt template "${a.name}" not found`);
29901
+ return toolResult(prompt);
29902
+ }
29903
+ case "memory_prompt_run": {
29904
+ const rendered = renderPrompt(activeMemoryDir, String(a.name), a.args ?? {});
29905
+ return toolResult({ rendered });
29906
+ }
29907
+ case "memory_rollup": {
29908
+ const res = rollupTemporal(activeStore, {
29909
+ memoryDir: activeMemoryDir,
29910
+ period: a.period ?? "week",
29911
+ date: a.date ? String(a.date) : undefined,
29912
+ project: a.project ? String(a.project) : undefined
29913
+ });
29914
+ return toolResult(res);
29915
+ }
29916
+ case "memory_loop_record": {
29917
+ const entry = recordIteration(activeMemoryDir, {
29918
+ iteration_index: Number(a.iteration_index) || 1,
29919
+ critic_verdict: String(a.critic_verdict),
29920
+ largest_fix_identified: String(a.largest_fix_identified),
29921
+ test_results: String(a.test_results),
29922
+ diff_hash: a.diff_hash ? String(a.diff_hash) : undefined
29923
+ });
29924
+ return toolResult(entry);
29925
+ }
29926
+ case "memory_loop_status": {
29927
+ const status = detectIterationStatus(activeMemoryDir);
29928
+ return toolResult(status);
29929
+ }
29930
+ case "memory_verify_strict": {
29931
+ const report = verifyStrictIntegrity(activeStore, activeMemoryDir, activeRoot, {
29932
+ maxCandidateDays: typeof a.max_candidate_days === "number" ? a.max_candidate_days : undefined
29933
+ });
29934
+ return toolResult(report);
29935
+ }
28253
29936
  default:
28254
29937
  return toolError(`unknown tool ${name}`);
28255
29938
  }
@@ -28257,6 +29940,10 @@ Path: ${item.path}`,
28257
29940
  return toolError(err instanceof Error ? err.message : String(err));
28258
29941
  }
28259
29942
  });
29943
+ return server;
29944
+ }
29945
+ async function runMcpServer() {
29946
+ const server = createServer2();
28260
29947
  const transport = new StdioServerTransport;
28261
29948
  await server.connect(transport);
28262
29949
  process.stdin.resume();
@@ -28306,6 +29993,14 @@ var init_mcp = __esm(() => {
28306
29993
  init_entities();
28307
29994
  init_pageindex();
28308
29995
  init_settings2();
29996
+ init_provenance();
29997
+ init_claims();
29998
+ init_snapshot();
29999
+ init_prompts();
30000
+ init_temporal();
30001
+ init_iterations();
30002
+ init_verify();
30003
+ init_tiered();
28309
30004
  });
28310
30005
 
28311
30006
  // src/daemon.ts
@@ -28313,15 +30008,15 @@ var exports_daemon = {};
28313
30008
  __export(exports_daemon, {
28314
30009
  startHub: () => startHub
28315
30010
  });
28316
- import { createServer as createServer2 } from "node:http";
28317
- import { existsSync as existsSync33 } from "node:fs";
28318
- import { join as join30 } from "node:path";
30011
+ import { createServer as createServer3 } from "node:http";
30012
+ import { existsSync as existsSync40 } from "node:fs";
30013
+ import { join as join37 } from "node:path";
28319
30014
  import { watch } from "node:fs";
28320
30015
  function startHub(port, memoryDir) {
28321
30016
  const clients = new Set;
28322
30017
  const watchers = [];
28323
30018
  let debounceTimer = null;
28324
- const server = createServer2((req, res) => {
30019
+ const server = createServer3((req, res) => {
28325
30020
  if (req.method === "GET" && req.url?.startsWith("/events")) {
28326
30021
  res.writeHead(200, {
28327
30022
  "content-type": "text/event-stream",
@@ -28381,7 +30076,7 @@ data: ${JSON.stringify(event)}
28381
30076
  return clients.size;
28382
30077
  }
28383
30078
  if (memoryDir) {
28384
- const memoriesDir = join30(memoryDir, "memories");
30079
+ const memoriesDir = join37(memoryDir, "memories");
28385
30080
  const armDebounced = (type2) => {
28386
30081
  if (debounceTimer)
28387
30082
  clearTimeout(debounceTimer);
@@ -28390,17 +30085,17 @@ data: ${JSON.stringify(event)}
28390
30085
  }, DEBOUNCE_MS);
28391
30086
  };
28392
30087
  try {
28393
- if (existsSync33(memoriesDir)) {
30088
+ if (existsSync40(memoriesDir)) {
28394
30089
  watchers.push(watch(memoriesDir, () => armDebounced("memory.changed")));
28395
30090
  }
28396
- const currentMd = join30(memoryDir, "CURRENT.md");
28397
- if (existsSync33(currentMd)) {
30091
+ const currentMd = join37(memoryDir, "CURRENT.md");
30092
+ if (existsSync40(currentMd)) {
28398
30093
  watchers.push(watch(currentMd, () => armDebounced("constraints.changed")));
28399
30094
  }
28400
30095
  } catch {}
28401
30096
  }
28402
30097
  return new Promise((resolve3) => {
28403
- server.listen(port, () => {
30098
+ server.listen(port, "127.0.0.1", () => {
28404
30099
  const address = server.address();
28405
30100
  const actualPort = typeof address === "object" && address ? address.port : port;
28406
30101
  resolve3({
@@ -28427,19 +30122,19 @@ var DEBOUNCE_MS = 300;
28427
30122
  var init_daemon = () => {};
28428
30123
 
28429
30124
  // src/cli/ecosystem.ts
28430
- import { join as join31 } from "node:path";
28431
- import { existsSync as existsSync34, mkdirSync as mkdirSync19, writeFileSync as writeFileSync18, readFileSync as readFileSync26 } from "node:fs";
28432
- import { homedir as homedir6 } from "node:os";
30125
+ import { join as join38 } from "node:path";
30126
+ import { existsSync as existsSync41, mkdirSync as mkdirSync26, writeFileSync as writeFileSync25, readFileSync as readFileSync33 } from "node:fs";
30127
+ import { homedir as homedir7 } from "node:os";
28433
30128
  function ensureProjectAgentInstructions(targetDir) {
28434
- const agentsMdPath = join31(targetDir, "AGENTS.md");
28435
- if (existsSync34(agentsMdPath)) {
30129
+ const agentsMdPath = join38(targetDir, "AGENTS.md");
30130
+ if (existsSync41(agentsMdPath)) {
28436
30131
  try {
28437
- const existing = readFileSync26(agentsMdPath, "utf8");
30132
+ const existing = readFileSync33(agentsMdPath, "utf8");
28438
30133
  if (existing.includes("<!-- agentmemory:start -->")) {
28439
30134
  const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
28440
- writeFileSync18(agentsMdPath, updated, "utf8");
30135
+ writeFileSync25(agentsMdPath, updated, "utf8");
28441
30136
  } else if (!existing.includes("<!-- musememory:start -->") && !existing.includes("Muse Memory")) {
28442
- writeFileSync18(agentsMdPath, `${existing.trim()}
30137
+ writeFileSync25(agentsMdPath, `${existing.trim()}
28443
30138
 
28444
30139
  ${MUSE_MEMORY_DIRECTIVE}
28445
30140
  `, "utf8");
@@ -28450,23 +30145,23 @@ ${MUSE_MEMORY_DIRECTIVE}
28450
30145
 
28451
30146
  ${MUSE_MEMORY_DIRECTIVE}
28452
30147
  `;
28453
- writeFileSync18(agentsMdPath, initialContent, "utf8");
30148
+ writeFileSync25(agentsMdPath, initialContent, "utf8");
28454
30149
  }
28455
30150
  }
28456
30151
  async function handleInstallCommand({ positional, flags }) {
28457
30152
  const isGlobal = flags["global"] === "true" || flags["g"] === "true";
28458
- const targetDir = positional[0] ? join31(process.cwd(), positional[0]) : process.cwd();
28459
- const memoryDir = isGlobal ? getGlobalMemoryDir() : join31(targetDir, ".memory");
30153
+ const targetDir = positional[0] ? join38(process.cwd(), positional[0]) : process.cwd();
30154
+ const memoryDir = isGlobal ? getGlobalMemoryDir() : join38(targetDir, ".memory");
28460
30155
  const globalDir = getGlobalMemoryDir();
28461
- mkdirSync19(join31(memoryDir, "memories"), { recursive: true });
28462
- mkdirSync19(join31(globalDir, "memories"), { recursive: true });
28463
- const currentPath = join31(memoryDir, "CURRENT.md");
28464
- if (!existsSync34(currentPath)) {
28465
- writeFileSync18(currentPath, `# Active Project Constraints
30156
+ mkdirSync26(join38(memoryDir, "memories"), { recursive: true });
30157
+ mkdirSync26(join38(globalDir, "memories"), { recursive: true });
30158
+ const currentPath = join38(memoryDir, "CURRENT.md");
30159
+ if (!existsSync41(currentPath)) {
30160
+ writeFileSync25(currentPath, `# Active Project Constraints
28466
30161
  `, "utf8");
28467
30162
  }
28468
30163
  const globalUserPath = userFilePath(globalDir);
28469
- if (!existsSync34(globalUserPath)) {
30164
+ if (!existsSync41(globalUserPath)) {
28470
30165
  const { promptSingleSelect: promptSingleSelect2 } = await Promise.resolve().then(() => (init_prompt(), exports_prompt));
28471
30166
  const archetypeOptions = [
28472
30167
  { id: "developer", label: "Software Engineer / Developer", hint: "Code-first, direct, strict typing" },
@@ -28482,13 +30177,13 @@ async function handleInstallCommand({ positional, flags }) {
28482
30177
  if (!isGlobal) {
28483
30178
  ensureProjectAgentInstructions(targetDir);
28484
30179
  }
28485
- const globalAgentsMd = join31(homedir6(), ".agents", "AGENTS.md");
28486
- if (existsSync34(globalAgentsMd)) {
30180
+ const globalAgentsMd = join38(homedir7(), ".agents", "AGENTS.md");
30181
+ if (existsSync41(globalAgentsMd)) {
28487
30182
  try {
28488
- const existing = readFileSync26(globalAgentsMd, "utf8");
30183
+ const existing = readFileSync33(globalAgentsMd, "utf8");
28489
30184
  if (existing.includes("<!-- agentmemory:start -->")) {
28490
30185
  const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
28491
- writeFileSync18(globalAgentsMd, updated, "utf8");
30186
+ writeFileSync25(globalAgentsMd, updated, "utf8");
28492
30187
  }
28493
30188
  } catch {}
28494
30189
  }
@@ -28549,11 +30244,11 @@ async function handleInstallCommand({ positional, flags }) {
28549
30244
  return 0;
28550
30245
  }
28551
30246
  async function promptOrNotifyGitHook(targetDir, autoInstall = false) {
28552
- const gitDir = join31(targetDir, ".git");
28553
- if (!existsSync34(gitDir))
30247
+ const gitDir = join38(targetDir, ".git");
30248
+ if (!existsSync41(gitDir))
28554
30249
  return false;
28555
- const hookPath = join31(gitDir, "hooks", "pre-commit");
28556
- const isInstalled = existsSync34(hookPath) && readFileSync26(hookPath, "utf8").includes("memory harvest-auto");
30250
+ const hookPath = join38(gitDir, "hooks", "pre-commit");
30251
+ const isInstalled = existsSync41(hookPath) && readFileSync33(hookPath, "utf8").includes("memory harvest-auto");
28557
30252
  if (isInstalled)
28558
30253
  return true;
28559
30254
  if (autoInstall) {
@@ -28609,7 +30304,7 @@ async function handleUninstallCommand({ positional, flags }) {
28609
30304
  action: async () => {
28610
30305
  if (purge) {
28611
30306
  const ctx = requireRoot(flags);
28612
- if (ctx && existsSync34(ctx.memoryDir) && !dryRun) {
30307
+ if (ctx && existsSync41(ctx.memoryDir) && !dryRun) {
28613
30308
  const { rmSync: rmSync3 } = await import("node:fs");
28614
30309
  rmSync3(ctx.memoryDir, { recursive: true, force: true });
28615
30310
  }
@@ -28641,13 +30336,13 @@ async function handleUninstallCommand({ positional, flags }) {
28641
30336
  }
28642
30337
  async function handleInitCommand({ positional, flags }) {
28643
30338
  const isGlobal = flags["global"] === "true";
28644
- const targetDir = positional[0] ? join31(process.cwd(), positional[0]) : process.cwd();
30339
+ const targetDir = positional[0] ? join38(process.cwd(), positional[0]) : process.cwd();
28645
30340
  const memoryDirName = flags["legacy"] === "true" ? ".musememory" : ".memory";
28646
- const memoryDir = isGlobal ? getGlobalMemoryDir() : join31(targetDir, memoryDirName);
28647
- mkdirSync19(join31(memoryDir, "memories"), { recursive: true });
28648
- const currentPath = join31(memoryDir, "CURRENT.md");
28649
- if (!existsSync34(currentPath)) {
28650
- writeFileSync18(currentPath, `# Active Project Constraints
30341
+ const memoryDir = isGlobal ? getGlobalMemoryDir() : join38(targetDir, memoryDirName);
30342
+ mkdirSync26(join38(memoryDir, "memories"), { recursive: true });
30343
+ const currentPath = join38(memoryDir, "CURRENT.md");
30344
+ if (!existsSync41(currentPath)) {
30345
+ writeFileSync25(currentPath, `# Active Project Constraints
28651
30346
  `, "utf8");
28652
30347
  }
28653
30348
  if (!isGlobal) {
@@ -28823,6 +30518,13 @@ async function handleUiCommand({ flags }) {
28823
30518
  if (!ctx)
28824
30519
  return 1;
28825
30520
  const port = flags["port"] ? parseInt(flags["port"], 10) : 2222;
30521
+ try {
30522
+ const { harvestAllAgentTranscripts: harvestAllAgentTranscripts2 } = await Promise.resolve().then(() => (init_harvester(), exports_harvester));
30523
+ const harvestRes = harvestAllAgentTranscripts2(ctx.store, { memoryDir: ctx.memoryDir });
30524
+ if (harvestRes.harvestedFilesCount > 0) {
30525
+ console.log(`[UI Auto-Sync] Distilled ${harvestRes.memoriesImported} new memories from ${harvestRes.harvestedFilesCount} agent transcript(s).`);
30526
+ }
30527
+ } catch {}
28826
30528
  const { startUiServer: startUiServer2 } = await Promise.resolve().then(() => (init_ui(), exports_ui));
28827
30529
  const srv = await startUiServer2({
28828
30530
  port,
@@ -28931,8 +30633,8 @@ var init_ecosystem = __esm(() => {
28931
30633
  });
28932
30634
 
28933
30635
  // src/agentcontract.ts
28934
- import { existsSync as existsSync35 } from "node:fs";
28935
- import { join as join32 } from "node:path";
30636
+ import { existsSync as existsSync42 } from "node:fs";
30637
+ import { join as join39 } from "node:path";
28936
30638
  function parseAgentMemoryContract(markdown) {
28937
30639
  if (!markdown || !markdown.startsWith("---"))
28938
30640
  return null;
@@ -28964,17 +30666,17 @@ function parseAgentMemoryContract(markdown) {
28964
30666
  function resolveAgentFile(nameOrPath, workspaceRoot) {
28965
30667
  if (!nameOrPath)
28966
30668
  return null;
28967
- if (existsSync35(nameOrPath))
30669
+ if (existsSync42(nameOrPath))
28968
30670
  return nameOrPath;
28969
30671
  const candidates = [
28970
- join32(workspaceRoot, ".agents", `${nameOrPath}.md`),
28971
- join32(workspaceRoot, ".memory", "agents", `${nameOrPath}.md`)
30672
+ join39(workspaceRoot, ".agents", `${nameOrPath}.md`),
30673
+ join39(workspaceRoot, ".memory", "agents", `${nameOrPath}.md`)
28972
30674
  ];
28973
30675
  const home = process.env.HOME;
28974
30676
  if (home)
28975
- candidates.push(join32(home, ".config", "opencode", "agents", `${nameOrPath}.md`));
30677
+ candidates.push(join39(home, ".config", "opencode", "agents", `${nameOrPath}.md`));
28976
30678
  for (const c of candidates) {
28977
- if (existsSync35(c))
30679
+ if (existsSync42(c))
28978
30680
  return c;
28979
30681
  }
28980
30682
  return null;
@@ -28984,8 +30686,8 @@ var init_agentcontract = __esm(() => {
28984
30686
  });
28985
30687
 
28986
30688
  // src/cli/retrieval.ts
28987
- import { existsSync as existsSync36, readFileSync as readFileSync27 } from "node:fs";
28988
- import { join as join33 } from "node:path";
30689
+ import { existsSync as existsSync43, readFileSync as readFileSync34 } from "node:fs";
30690
+ import { join as join40 } from "node:path";
28989
30691
  async function handleContextCommand({ positional, flags }) {
28990
30692
  let agentTypes;
28991
30693
  let agentTags;
@@ -28993,7 +30695,7 @@ async function handleContextCommand({ positional, flags }) {
28993
30695
  const file = resolveAgentFile(flags["for-agent"], flags["dir"] ?? process.cwd());
28994
30696
  if (!file)
28995
30697
  return usageError(`--for-agent: cannot resolve agent '${flags["for-agent"]}'`);
28996
- const contract = parseAgentMemoryContract(readFileSync27(file, "utf8"));
30698
+ const contract = parseAgentMemoryContract(readFileSync34(file, "utf8"));
28997
30699
  if (contract) {
28998
30700
  agentTypes = contract.types;
28999
30701
  agentTags = contract.tags;
@@ -29011,6 +30713,26 @@ async function handleContextCommand({ positional, flags }) {
29011
30713
  if (depth && depth !== "L1" && depth !== "L2" && depth !== "L3") {
29012
30714
  return usageError("--depth must be one of L1|L2|L3");
29013
30715
  }
30716
+ if (flags["tier"] !== undefined) {
30717
+ const tierNum = parseInt(flags["tier"], 10);
30718
+ if (tierNum !== 0 && tierNum !== 1 && tierNum !== 2) {
30719
+ return usageError("--tier must be 0, 1, or 2");
30720
+ }
30721
+ const tiered = queryTieredContext(ctx.store, ctx.memoryDir, query, {
30722
+ limit,
30723
+ tokenBudget: tokenBudget ?? (flags["budget"] ? parseInt(flags["budget"], 10) : undefined),
30724
+ project: flags["project"],
30725
+ includeSuperseded: false,
30726
+ type: flags["type"],
30727
+ types: agentTypes,
30728
+ tags: agentTags,
30729
+ status: flags["status"],
30730
+ verified: flags["verified"] === "true",
30731
+ tier: tierNum
30732
+ });
30733
+ console.log(tiered.markdown);
30734
+ return 0;
30735
+ }
29014
30736
  if (depth) {
29015
30737
  const formatted = formatPromptContext(ctx.store, ctx.memoryDir, query, {
29016
30738
  limit,
@@ -29133,7 +30855,7 @@ async function handleHarvestCommand({ positional, flags }) {
29133
30855
  const project = flags["project"];
29134
30856
  if (!project)
29135
30857
  return usageError("harvest requires --project");
29136
- const rawText = existsSync36(target) ? readFileSync27(target, "utf8") : target;
30858
+ const rawText = existsSync43(target) ? readFileSync34(target, "utf8") : target;
29137
30859
  const created = harvestMemories(ctx.store, {
29138
30860
  text: rawText,
29139
30861
  project,
@@ -29169,8 +30891,8 @@ async function handleSearchTranscriptCommand({ positional, flags }) {
29169
30891
  const filePath = positional[1];
29170
30892
  if (!query)
29171
30893
  return usageError("search-transcript requires <query> [file.jsonl]");
29172
- const targetFile = filePath ? filePath.startsWith("/") ? filePath : join33(process.cwd(), filePath) : join33(process.cwd(), "transcript.jsonl");
29173
- if (!existsSync36(targetFile)) {
30894
+ const targetFile = filePath ? filePath.startsWith("/") ? filePath : join40(process.cwd(), filePath) : join40(process.cwd(), "transcript.jsonl");
30895
+ if (!existsSync43(targetFile)) {
29174
30896
  return fail(`error: transcript file not found: ${targetFile}`);
29175
30897
  }
29176
30898
  const windowSize = flags["window"] ? parseInt(flags["window"], 10) : 2;
@@ -29186,7 +30908,7 @@ async function handleReindexCommand({ flags }) {
29186
30908
  const { rebuildIndex: rebuildIndex2, saveIndex: saveIndex2 } = await Promise.resolve().then(() => (init_vector(), exports_vector));
29187
30909
  const index = rebuildIndex2(ctx.store);
29188
30910
  saveIndex2(index, ctx.memoryDir);
29189
- console.log(`indexed ${Object.keys(index.entries).length} entries -> ${join33(ctx.memoryDir, "index.json")}`);
30911
+ console.log(`indexed ${Object.keys(index.entries).length} entries -> ${join40(ctx.memoryDir, "index.json")}`);
29190
30912
  return 0;
29191
30913
  }
29192
30914
  async function handleHookCommand({ positional, flags }) {
@@ -29220,6 +30942,7 @@ async function handleHarvestAutoCommand({ flags }) {
29220
30942
  }
29221
30943
  var init_retrieval3 = __esm(() => {
29222
30944
  init_retrieval();
30945
+ init_tiered();
29223
30946
  init_vector();
29224
30947
  init_retrieval2();
29225
30948
  init_harvest();
@@ -29577,7 +31300,7 @@ var init_entities2 = __esm(() => {
29577
31300
  });
29578
31301
 
29579
31302
  // src/cli/settings.ts
29580
- import { writeFileSync as writeFileSync19, readFileSync as readFileSync28 } from "node:fs";
31303
+ import { writeFileSync as writeFileSync26, readFileSync as readFileSync35 } from "node:fs";
29581
31304
  function handleSettingsCommand(parsed) {
29582
31305
  const ctx = requireRoot(parsed.flags);
29583
31306
  if (!ctx)
@@ -29659,7 +31382,7 @@ function handleSettingsCommand(parsed) {
29659
31382
  const out = parsed.flags.out;
29660
31383
  const json2 = exportSettings(memoryDir);
29661
31384
  if (out) {
29662
- writeFileSync19(out, json2, "utf8");
31385
+ writeFileSync26(out, json2, "utf8");
29663
31386
  console.log(`Exported settings to ${out}`);
29664
31387
  } else {
29665
31388
  console.log(json2);
@@ -29673,7 +31396,7 @@ function handleSettingsCommand(parsed) {
29673
31396
  return 2;
29674
31397
  }
29675
31398
  try {
29676
- const raw = readFileSync28(file, "utf8");
31399
+ const raw = readFileSync35(file, "utf8");
29677
31400
  importSettings(memoryDir, raw);
29678
31401
  console.log(`Successfully imported settings from ${file}`);
29679
31402
  return 0;
@@ -29696,16 +31419,16 @@ var init_nudge = __esm(() => {
29696
31419
  });
29697
31420
 
29698
31421
  // src/routines.ts
29699
- import { readFileSync as readFileSync29, existsSync as existsSync37 } from "node:fs";
29700
- import { join as join34 } from "node:path";
31422
+ import { readFileSync as readFileSync36, existsSync as existsSync44 } from "node:fs";
31423
+ import { join as join41 } from "node:path";
29701
31424
  function routinesPath(memoryDir) {
29702
- return join34(memoryDir, "routines.yaml");
31425
+ return join41(memoryDir, "routines.yaml");
29703
31426
  }
29704
31427
  function loadRoutines(memoryDir) {
29705
31428
  const p = routinesPath(memoryDir);
29706
- if (!existsSync37(p))
31429
+ if (!existsSync44(p))
29707
31430
  return { routines: {} };
29708
- const doc2 = yaml.load(readFileSync29(p, "utf8"), { schema: yaml.JSON_SCHEMA }) ?? {};
31431
+ const doc2 = yaml.load(readFileSync36(p, "utf8"), { schema: yaml.JSON_SCHEMA }) ?? {};
29709
31432
  const routines = doc2.routines ?? {};
29710
31433
  for (const [name, r] of Object.entries(routines)) {
29711
31434
  if (!r || typeof r.schedule !== "string" || !r.schedule.trim()) {
@@ -29743,7 +31466,7 @@ var init_routines = __esm(() => {
29743
31466
  });
29744
31467
 
29745
31468
  // src/cli/lifecycle.ts
29746
- import { writeFileSync as writeFileSync20, readFileSync as readFileSync30, existsSync as existsSync38 } from "node:fs";
31469
+ import { writeFileSync as writeFileSync27, readFileSync as readFileSync37, existsSync as existsSync45 } from "node:fs";
29747
31470
  async function handleProposeCommand({ positional, flags }) {
29748
31471
  const ctx = requireRoot(flags);
29749
31472
  if (!ctx)
@@ -29892,7 +31615,7 @@ async function handleExportCommand({ flags }) {
29892
31615
  const snapshot = exportSnapshot(ctx.store);
29893
31616
  const outPath = flags["out"];
29894
31617
  if (outPath) {
29895
- writeFileSync20(outPath, JSON.stringify(snapshot, null, 2), "utf8");
31618
+ writeFileSync27(outPath, JSON.stringify(snapshot, null, 2), "utf8");
29896
31619
  console.log(`exported ${snapshot.total} memories to ${outPath}`);
29897
31620
  } else {
29898
31621
  console.log(JSON.stringify(snapshot, null, 2));
@@ -29906,9 +31629,9 @@ async function handleImportCommand({ positional, flags }) {
29906
31629
  const file = positional[0];
29907
31630
  if (!file)
29908
31631
  return usageError("import requires <file.json>");
29909
- if (!existsSync38(file))
31632
+ if (!existsSync45(file))
29910
31633
  return fail(`error: file ${file} does not exist`);
29911
- const raw = JSON.parse(readFileSync30(file, "utf8"));
31634
+ const raw = JSON.parse(readFileSync37(file, "utf8"));
29912
31635
  const res = importSnapshot(ctx.store, raw, { overwrite: flags["overwrite"] === "true" });
29913
31636
  if (res.errors.length > 0) {
29914
31637
  console.error(`import encountered errors:`);
@@ -30198,9 +31921,31 @@ async function handleVerifyCommand({ positional, flags }) {
30198
31921
  const ctx = requireRoot(flags);
30199
31922
  if (!ctx)
30200
31923
  return 1;
31924
+ if (flags["strict"] === "true" || positional[0] === "--strict" || flags["all"] === "true") {
31925
+ const report = verifyStrictIntegrity(ctx.store, ctx.memoryDir, ctx.root);
31926
+ console.log(`=== Muse Memory Strict Integrity Audit ===`);
31927
+ for (const c of report.checks) {
31928
+ const statusIcon = c.passed ? "✓" : "✗";
31929
+ console.log(`${statusIcon} ${c.name}: ${c.message}`);
31930
+ if (c.errors && c.errors.length > 0) {
31931
+ for (const err of c.errors) {
31932
+ console.error(` - ${err}`);
31933
+ }
31934
+ }
31935
+ }
31936
+ if (report.ok) {
31937
+ console.log(`
31938
+ [pass] Strict Verification Passed (${report.passedChecks}/${report.totalChecks} gates clean)`);
31939
+ return 0;
31940
+ } else {
31941
+ console.error(`
31942
+ [fail] Strict Verification Failed (${report.failedChecks}/${report.totalChecks} gates violated)`);
31943
+ return 1;
31944
+ }
31945
+ }
30201
31946
  const id = positional[0];
30202
31947
  if (!id)
30203
- return usageError("verify requires <id>");
31948
+ return usageError("verify requires <id> or --strict");
30204
31949
  const timeout = flags["timeout"] ? parseInt(flags["timeout"], 10) : undefined;
30205
31950
  const result = await verifyEntry(ctx.store, ctx.root, ctx.memoryDir, id, { timeout });
30206
31951
  if (result.stdout?.trim())
@@ -30253,6 +31998,275 @@ var init_lifecycle = __esm(() => {
30253
31998
  init_shared();
30254
31999
  });
30255
32000
 
32001
+ // src/cli/evolution.ts
32002
+ async function handleSourceCommand({ positional, flags }) {
32003
+ const ctx = requireRoot(flags);
32004
+ if (!ctx)
32005
+ return 1;
32006
+ const sub = positional[0] ?? "list";
32007
+ if (sub === "add") {
32008
+ const url = positional[1];
32009
+ if (!url)
32010
+ return usageError("source add requires <url>");
32011
+ const title = flags["title"] || positional[2] || url;
32012
+ try {
32013
+ const source = addSource(ctx.memoryDir, {
32014
+ url,
32015
+ title,
32016
+ source_type: flags["type"] || "documentation",
32017
+ excerpt: flags["excerpt"],
32018
+ author: flags["author"]
32019
+ });
32020
+ console.log(`Recorded source ${source.id}: "${source.title}" (${source.url})`);
32021
+ return 0;
32022
+ } catch (err) {
32023
+ console.error(`Error adding source: ${err instanceof Error ? err.message : String(err)}`);
32024
+ return 1;
32025
+ }
32026
+ }
32027
+ if (sub === "show" || sub === "get") {
32028
+ const id = positional[1];
32029
+ if (!id)
32030
+ return usageError("source show requires <id>");
32031
+ const source = getSource(ctx.memoryDir, id);
32032
+ if (!source) {
32033
+ console.error(`Source ${id} not found`);
32034
+ return 1;
32035
+ }
32036
+ console.log(JSON.stringify(source, null, 2));
32037
+ return 0;
32038
+ }
32039
+ const query = flags["query"] || (sub === "find" ? positional[1] : undefined);
32040
+ const sources = listSources(ctx.memoryDir, {
32041
+ source_type: flags["type"],
32042
+ query
32043
+ });
32044
+ if (sources.length === 0) {
32045
+ console.log("*(No sources found)*");
32046
+ return 0;
32047
+ }
32048
+ console.log(`Found ${sources.length} source(s):`);
32049
+ for (const s of sources) {
32050
+ console.log(`- [${s.id}] (${s.source_type}) ${s.title} — ${s.url}`);
32051
+ if (s.excerpt)
32052
+ console.log(` "${s.excerpt}"`);
32053
+ }
32054
+ return 0;
32055
+ }
32056
+ async function handleClaimCommand({ positional, flags }) {
32057
+ const ctx = requireRoot(flags);
32058
+ if (!ctx)
32059
+ return 1;
32060
+ const sub = positional[0] ?? "list";
32061
+ if (sub === "record" || sub === "add") {
32062
+ const claimText = positional.slice(1).join(" ") || flags["claim"];
32063
+ if (!claimText || !claimText.trim())
32064
+ return usageError("claim record requires <claim text>");
32065
+ const sourceIds = flags["sources"] || flags["source_ids"] ? (flags["sources"] || flags["source_ids"]).split(",").map((s) => s.trim()).filter(Boolean) : undefined;
32066
+ const memoryIds = flags["memories"] || flags["memory_ids"] ? (flags["memories"] || flags["memory_ids"]).split(",").map((s) => s.trim()).filter(Boolean) : undefined;
32067
+ try {
32068
+ const claim = recordClaim(ctx.memoryDir, {
32069
+ claim: claimText.trim(),
32070
+ confidence_tag: flags["confidence"] || "INFER",
32071
+ source_ids: sourceIds,
32072
+ memory_ids: memoryIds,
32073
+ notes: flags["notes"],
32074
+ verified: flags["verified"] === "true"
32075
+ });
32076
+ console.log(`Recorded claim ${claim.id} [${claim.confidence_tag}]: "${claim.claim}"`);
32077
+ return 0;
32078
+ } catch (err) {
32079
+ console.error(`Error recording claim: ${err instanceof Error ? err.message : String(err)}`);
32080
+ return 1;
32081
+ }
32082
+ }
32083
+ if (sub === "show" || sub === "get") {
32084
+ const id = positional[1];
32085
+ if (!id)
32086
+ return usageError("claim show requires <id>");
32087
+ const claim = getClaim(ctx.memoryDir, id);
32088
+ if (!claim) {
32089
+ console.error(`Claim ${id} not found`);
32090
+ return 1;
32091
+ }
32092
+ console.log(JSON.stringify(claim, null, 2));
32093
+ return 0;
32094
+ }
32095
+ const query = flags["query"] || (sub === "find" ? positional[1] : undefined);
32096
+ const claims = listClaims(ctx.memoryDir, {
32097
+ confidence_tag: flags["confidence"],
32098
+ query
32099
+ });
32100
+ if (claims.length === 0) {
32101
+ console.log("*(No claims found)*");
32102
+ return 0;
32103
+ }
32104
+ console.log(`Found ${claims.length} claim(s):`);
32105
+ for (const c of claims) {
32106
+ const sources = c.source_ids && c.source_ids.length > 0 ? ` (sources: ${c.source_ids.join(", ")})` : "";
32107
+ console.log(`- [${c.id}] [${c.confidence_tag}] ${c.claim}${sources}`);
32108
+ }
32109
+ return 0;
32110
+ }
32111
+ async function handleFreezeCommand({ positional, flags }) {
32112
+ const ctx = requireRoot(flags);
32113
+ if (!ctx)
32114
+ return 1;
32115
+ const sub = positional[0];
32116
+ if (sub === "list") {
32117
+ const snapshots = listExecutionSnapshots(ctx.memoryDir);
32118
+ console.log(`Found ${snapshots.length} execution snapshot(s):`);
32119
+ for (const s of snapshots) {
32120
+ console.log(`- [${s.run_id}] (${s.timestamp}) ${s.task.slice(0, 60)}...`);
32121
+ }
32122
+ return 0;
32123
+ }
32124
+ if (sub === "show") {
32125
+ const runId = positional[1];
32126
+ if (!runId)
32127
+ return usageError("freeze show requires <run-id>");
32128
+ const snap2 = loadExecutionSnapshot(ctx.memoryDir, runId);
32129
+ if (!snap2) {
32130
+ console.error(`Snapshot ${runId} not found`);
32131
+ return 1;
32132
+ }
32133
+ console.log(JSON.stringify(snap2, null, 2));
32134
+ return 0;
32135
+ }
32136
+ const task = flags["task"] || positional.join(" ");
32137
+ if (!task || !task.trim()) {
32138
+ return usageError("freeze requires --task <task.md|text>");
32139
+ }
32140
+ const snap = freezeExecutionSnapshot({
32141
+ workspaceRoot: ctx.root,
32142
+ memoryDir: ctx.memoryDir,
32143
+ task: task.trim(),
32144
+ runId: flags["run-id"],
32145
+ store: ctx.store
32146
+ });
32147
+ console.log(`Frozen execution snapshot [${snap.run_id}] with ${snap.memory_hashes.length} memories and ${snap.file_inventory.length} workspace files.`);
32148
+ return 0;
32149
+ }
32150
+ async function handlePromptCommand({ positional, flags }) {
32151
+ const ctx = requireRoot(flags);
32152
+ const memoryDir = ctx?.memoryDir;
32153
+ const sub = positional[0] ?? "list";
32154
+ if (sub === "list") {
32155
+ const prompts = listPrompts(memoryDir);
32156
+ console.log(`Available Prompt Templates (${prompts.length}):`);
32157
+ for (const p of prompts) {
32158
+ console.log(`- **${p.name}**: ${p.title} — ${p.description}`);
32159
+ }
32160
+ return 0;
32161
+ }
32162
+ if (sub === "show") {
32163
+ const name = positional[1];
32164
+ if (!name)
32165
+ return usageError("prompt show requires <name>");
32166
+ const prompt = getPrompt(memoryDir, name);
32167
+ if (!prompt) {
32168
+ console.error(`Prompt template "${name}" not found`);
32169
+ return 1;
32170
+ }
32171
+ console.log(JSON.stringify(prompt, null, 2));
32172
+ return 0;
32173
+ }
32174
+ if (sub === "run") {
32175
+ const name = positional[1];
32176
+ if (!name)
32177
+ return usageError("prompt run requires <name>");
32178
+ const args = {};
32179
+ if (flags["args"]) {
32180
+ for (const pair of flags["args"].split(",")) {
32181
+ const [k, v] = pair.split("=");
32182
+ if (k && v)
32183
+ args[k.trim()] = v.trim();
32184
+ }
32185
+ }
32186
+ try {
32187
+ const rendered = renderPrompt(memoryDir, name, args);
32188
+ console.log(rendered);
32189
+ return 0;
32190
+ } catch (err) {
32191
+ console.error(`Error running prompt: ${err instanceof Error ? err.message : String(err)}`);
32192
+ return 1;
32193
+ }
32194
+ }
32195
+ return usageError("prompt command requires list|show|run");
32196
+ }
32197
+ async function handleRollupCommand({ positional, flags }) {
32198
+ const ctx = requireRoot(flags);
32199
+ if (!ctx)
32200
+ return 1;
32201
+ const period = flags["period"] || positional[0] || "week";
32202
+ if (period !== "week" && period !== "month" && period !== "quarter") {
32203
+ return usageError("--period must be week, month, or quarter");
32204
+ }
32205
+ try {
32206
+ const res = rollupTemporal(ctx.store, {
32207
+ memoryDir: ctx.memoryDir,
32208
+ period,
32209
+ date: flags["date"],
32210
+ project: flags["project"]
32211
+ });
32212
+ const periodLabel = period === "week" ? "weekly" : period === "month" ? "monthly" : "quarterly";
32213
+ console.log(`Compiled ${periodLabel} rollup (${res.periodKey}) to ${res.filePath} (${res.entriesCount} memories).`);
32214
+ return 0;
32215
+ } catch (err) {
32216
+ console.error(`Error during rollup: ${err instanceof Error ? err.message : String(err)}`);
32217
+ return 1;
32218
+ }
32219
+ }
32220
+ async function handleLoopCommand({ positional, flags }) {
32221
+ const ctx = requireRoot(flags);
32222
+ if (!ctx)
32223
+ return 1;
32224
+ const sub = positional[0] ?? "status";
32225
+ if (sub === "record" || sub === "add") {
32226
+ const index = parseInt(flags["index"] ?? positional[1] ?? "1", 10) || 1;
32227
+ const verdict = flags["verdict"] || "fail";
32228
+ const fix = flags["fix"] || positional.slice(2).join(" ") || "No description";
32229
+ const tests = flags["tests"] || "Unspecified";
32230
+ try {
32231
+ const entry = recordIteration(ctx.memoryDir, {
32232
+ iteration_index: index,
32233
+ critic_verdict: verdict,
32234
+ largest_fix_identified: fix,
32235
+ test_results: tests,
32236
+ diff_hash: flags["diff-hash"] || flags["diff_hash"]
32237
+ });
32238
+ console.log(`Recorded iteration #${entry.iteration_index} [${entry.critic_verdict}]: ${entry.largest_fix_identified}`);
32239
+ return 0;
32240
+ } catch (err) {
32241
+ console.error(`Error recording iteration: ${err instanceof Error ? err.message : String(err)}`);
32242
+ return 1;
32243
+ }
32244
+ }
32245
+ if (sub === "clear") {
32246
+ clearIterations(ctx.memoryDir);
32247
+ console.log("Cleared iteration ledger.");
32248
+ return 0;
32249
+ }
32250
+ const status = detectIterationStatus(ctx.memoryDir);
32251
+ console.log(`Iteration Loop Status:
32252
+ - Total iterations: ${status.totalIterations}
32253
+ - Last verdict: ${status.lastVerdict ?? "none"}
32254
+ - Consecutive failures: ${status.consecutiveFailures}
32255
+ - Plateau detected: ${status.isPlateaued ? "YES" : "No"}
32256
+ - Regression detected: ${status.isRegressed ? "YES" : "No"}
32257
+ - Recommendation: ${status.recommendation}`);
32258
+ return 0;
32259
+ }
32260
+ var init_evolution = __esm(() => {
32261
+ init_shared();
32262
+ init_provenance();
32263
+ init_claims();
32264
+ init_snapshot();
32265
+ init_prompts();
32266
+ init_temporal();
32267
+ init_iterations();
32268
+ });
32269
+
30256
32270
  // src/cli.ts
30257
32271
  var exports_cli = {};
30258
32272
  __export(exports_cli, {
@@ -30316,6 +32330,9 @@ async function main(argv) {
30316
32330
  return handleSearchTranscriptCommand(parsed);
30317
32331
  case "harvest":
30318
32332
  return handleHarvestCommand(parsed);
32333
+ case "learn":
32334
+ case "sync-chats":
32335
+ return handleLearnCommand(parsed);
30319
32336
  case "harvest-auto":
30320
32337
  return handleHarvestAutoCommand(parsed);
30321
32338
  case "hook":
@@ -30388,6 +32405,22 @@ async function main(argv) {
30388
32405
  return handleEntitiesCommand(parsed);
30389
32406
  case "settings":
30390
32407
  return handleSettingsCommand(parsed);
32408
+ case "source":
32409
+ case "sources":
32410
+ return handleSourceCommand(parsed);
32411
+ case "claim":
32412
+ case "claims":
32413
+ return handleClaimCommand(parsed);
32414
+ case "freeze":
32415
+ return handleFreezeCommand(parsed);
32416
+ case "prompt":
32417
+ case "prompts":
32418
+ return handlePromptCommand(parsed);
32419
+ case "rollup":
32420
+ return handleRollupCommand(parsed);
32421
+ case "loop":
32422
+ case "iterations":
32423
+ return handleLoopCommand(parsed);
30391
32424
  default:
30392
32425
  console.error(`Error: unknown command "${cmd}"`);
30393
32426
  return 2;
@@ -30423,11 +32456,19 @@ Core Memory Lifecycle Commands:
30423
32456
  routine run <name> Execute a routine's steps from .memory/routines.yaml
30424
32457
  routine install [name] Print crontab line(s) for routines (user installs; no system mutation)
30425
32458
  distill [--min-count N] [--dry-run] Distill recurring fix patterns into .agents/skills/ folders
30426
- verify <id> [--timeout S] Execute a fix entry's test_command; exit 0 promotes + independently verifies
32459
+ verify <id> [--timeout S] [--strict] Execute test_command or run full strict integrity gate
30427
32460
  briefing [--limit N] Executive summary of active and stale memories
30428
32461
 
32462
+ Evidence, Provenance & Cognitive Governance:
32463
+ source [add|list|show] Manage external documentation and URLs in provenance Source Ledger
32464
+ claim [record|list|show] Record verifiable claims with confidence tags ([RAW], [FETCH], [SEARCH], [INFER])
32465
+ freeze --task <task> [--run-id R] Capture immutable execution snapshot with file inventory & sha-256 hashes
32466
+ prompt [list|show|run <name>] Manage and run structured prompt templates with live context injection
32467
+ rollup --period week|month|quarter Multi-scale temporal compounding & HOT.md working cache generation
32468
+ loop [record|status|clear] Gauntlet iteration ledger & plateau/regression detector
32469
+
30429
32470
  Context & Retrieval Commands:
30430
- context [query] [--limit N] [--token-budget N] [--depth L1|L2|L3] Top-ranked prompt injection context
32471
+ context [query] [--limit N] [--token-budget N] [--depth L1|L2|L3] [--tier 0|1|2] Top-ranked prompt context
30431
32472
  search <query> [--limit N] [--token-budget N] [--hybrid] [--tree] Scored token retrieval (hybrid: vector+BM25, tree: hierarchical reasoning)
30432
32473
  reindex Rebuild the local vector index (.memory/index.json) for hybrid search
30433
32474
  recall [query] Search active/confirmed memories with filters
@@ -30449,6 +32490,7 @@ Ecosystem, Migration & Connectivity:
30449
32490
  agents / detect-agents Scan workstation for 80+ coding agent platforms
30450
32491
  detect Scan machine for 24+ external memory formats
30451
32492
  migrate [--from P] [--all] Ingest external memories with state preservation & secret scrubbing
32493
+ learn / sync-chats [--confirm] Auto-discover and harvest memories from all agent chats across machine
30452
32494
  harvest <file|text> --project P Distill conversation transcripts into structured memory units
30453
32495
  harvest-auto [--from <glob>] [--project P] Harvest inbox transcripts as candidates and archive them
30454
32496
  hook install --git Install the harvester as a git pre-commit hook (never clobbers)
@@ -30465,12 +32507,14 @@ var init_cli = __esm(() => {
30465
32507
  init_shared();
30466
32508
  init_ecosystem();
30467
32509
  init_upgrade();
32510
+ init_harvester();
30468
32511
  init_retrieval3();
30469
32512
  init_persona();
30470
32513
  init_wiki2();
30471
32514
  init_entities2();
30472
32515
  init_settings3();
30473
32516
  init_lifecycle();
32517
+ init_evolution();
30474
32518
  });
30475
32519
 
30476
32520
  // bin/memory.ts