musememory 1.8.0 → 1.10.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 +59 -3
  2. package/dist/index.js +867 -187
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4857,7 +4857,24 @@ function extractHarvestUnits(text) {
4857
4857
  continue;
4858
4858
  }
4859
4859
  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);
4860
+ 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);
4861
+ let naturalType = null;
4862
+ let naturalContent = "";
4863
+ if (!typeMatch) {
4864
+ if (/\b(?:resolved|fixed|patched|worked around)\s+(?:the\s+)?([^.\n]+)/i.test(speakerStripped)) {
4865
+ naturalType = "fix";
4866
+ naturalContent = speakerStripped;
4867
+ } else if (/\b(?:decided|chose|selected|agreed)\s+to\s+([^.\n]+)/i.test(speakerStripped)) {
4868
+ naturalType = "decision";
4869
+ naturalContent = speakerStripped;
4870
+ } 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)) {
4871
+ naturalType = "constraint";
4872
+ naturalContent = speakerStripped;
4873
+ } else if (/\b(?:user\s+prefers|prefers\s+using|prefers\s+to)\s+([^.\n]+)/i.test(speakerStripped)) {
4874
+ naturalType = "preference";
4875
+ naturalContent = speakerStripped;
4876
+ }
4877
+ }
4861
4878
  if (typeMatch) {
4862
4879
  flush();
4863
4880
  const rawTag = typeMatch[1].toLowerCase();
@@ -4866,6 +4883,11 @@ function extractHarvestUnits(text) {
4866
4883
  if (currentTitle) {
4867
4884
  currentBuffer.push(currentTitle);
4868
4885
  }
4886
+ } else if (naturalType && naturalContent) {
4887
+ flush();
4888
+ currentType = naturalType;
4889
+ currentTitle = naturalContent.slice(0, 80);
4890
+ currentBuffer.push(naturalContent);
4869
4891
  } else if (trimmed.match(/^(?:user|assistant|human|system|agent|client|developer)\s*[:\-\u2013]/i)) {
4870
4892
  flush();
4871
4893
  } else if (currentType !== null) {
@@ -4879,16 +4901,21 @@ function normalizeHarvestType(raw) {
4879
4901
  switch (raw) {
4880
4902
  case "fix":
4881
4903
  case "root cause":
4904
+ case "solution":
4905
+ case "resolution":
4906
+ case "workaround":
4882
4907
  return "fix";
4883
4908
  case "failure":
4884
4909
  return "failure";
4885
4910
  case "decision":
4886
4911
  case "outcome":
4887
4912
  case "rule":
4913
+ case "policy":
4888
4914
  return "decision";
4889
4915
  case "architecture":
4890
4916
  return "architecture";
4891
4917
  case "constraint":
4918
+ case "hard rule":
4892
4919
  return "constraint";
4893
4920
  case "operation":
4894
4921
  return "operation";
@@ -9028,6 +9055,297 @@ var init_hook = __esm(() => {
9028
9055
  init_audit();
9029
9056
  });
9030
9057
 
9058
+ // src/cli/upgrade.ts
9059
+ var exports_upgrade = {};
9060
+ __export(exports_upgrade, {
9061
+ detectPackageManager: () => detectPackageManager,
9062
+ executePackageUpgrade: () => executePackageUpgrade,
9063
+ formatProgressBar: () => formatProgressBar,
9064
+ getLatestNpmVersion: () => getLatestNpmVersion,
9065
+ getUpgradeMilestones: () => getUpgradeMilestones,
9066
+ handleUpgradeCommand: () => handleUpgradeCommand,
9067
+ playGamifiedLoader: () => playGamifiedLoader,
9068
+ repairInstallation: () => repairInstallation
9069
+ });
9070
+ import { execSync as execSync2 } from "node:child_process";
9071
+ import { existsSync as existsSync22, mkdirSync as mkdirSync13, writeFileSync as writeFileSync11 } from "node:fs";
9072
+ import { join as join19 } from "node:path";
9073
+ function formatProgressBar(percent, width = 20) {
9074
+ const p = Math.max(0, Math.min(100, percent));
9075
+ const filledCount = Math.round(p / 100 * width);
9076
+ const emptyCount = Math.max(0, width - filledCount);
9077
+ const filled = "█".repeat(filledCount);
9078
+ const empty = "░".repeat(emptyCount);
9079
+ return `[${filled}${empty}] ${Math.round(p)}%`;
9080
+ }
9081
+ function detectPackageManager() {
9082
+ try {
9083
+ if (typeof process.isBun !== "undefined" || process.versions.bun) {
9084
+ return "bun";
9085
+ }
9086
+ } catch {}
9087
+ try {
9088
+ execSync2("bun --version", { stdio: "ignore" });
9089
+ return "bun";
9090
+ } catch {}
9091
+ try {
9092
+ execSync2("pnpm --version", { stdio: "ignore" });
9093
+ return "pnpm";
9094
+ } catch {}
9095
+ try {
9096
+ execSync2("yarn --version", { stdio: "ignore" });
9097
+ return "yarn";
9098
+ } catch {}
9099
+ return "npm";
9100
+ }
9101
+ async function getLatestNpmVersion(packageName = "musememory") {
9102
+ try {
9103
+ const res = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
9104
+ headers: { Accept: "application/json" },
9105
+ signal: AbortSignal.timeout(3000)
9106
+ });
9107
+ if (res.ok) {
9108
+ const data = await res.json();
9109
+ if (data && typeof data.version === "string") {
9110
+ return data.version;
9111
+ }
9112
+ }
9113
+ } catch {}
9114
+ try {
9115
+ const out = execSync2(`npm show ${packageName} version`, {
9116
+ encoding: "utf8",
9117
+ stdio: ["ignore", "pipe", "ignore"]
9118
+ }).trim();
9119
+ if (out && !out.includes("error"))
9120
+ return out;
9121
+ } catch {}
9122
+ return null;
9123
+ }
9124
+ function getUpgradeMilestones() {
9125
+ return [
9126
+ {
9127
+ level: 1,
9128
+ stage: "LEVEL 1 [\uD83D\uDEE1️ Vibeguard Pre-Flight Check]",
9129
+ description: "Auditing environment credentials & storage integrity"
9130
+ },
9131
+ {
9132
+ level: 2,
9133
+ stage: "LEVEL 2 [\uD83D\uDCE6 Package Manager Synchronization]",
9134
+ description: "Querying package registry and pulling latest release binaries"
9135
+ },
9136
+ {
9137
+ level: 3,
9138
+ stage: "LEVEL 3 [\uD83E\uDDE0 Synaptic Database & Schema Alignment]",
9139
+ description: "Validating SQLite tables, CURRENT.md constraints & USER.md profiles"
9140
+ },
9141
+ {
9142
+ level: 4,
9143
+ stage: "LEVEL 4 [\uD83E\uDD16 80+ Agent Auto-Wiring Matrix]",
9144
+ description: "Scanning workstation platforms and auto-wiring newly detected agents"
9145
+ },
9146
+ {
9147
+ level: 5,
9148
+ stage: "LEVEL 5 [✨ Cognitive Ascendance Complete]",
9149
+ description: "Upgraded to latest version! All agent skills synchronized"
9150
+ }
9151
+ ];
9152
+ }
9153
+ async function playGamifiedLoader(steps, options = {}) {
9154
+ const isTTY = process.stdout.isTTY;
9155
+ const total = steps.length;
9156
+ console.log(`
9157
+ ┌──────────────────────────────────────────────────────────────────┐`);
9158
+ console.log(`│ \uD83E\uDDE0 MUSE MEMORY · ${options.title || "SYSTEM LEVEL-UP & RECOVERY MATRIX"} │`);
9159
+ console.log(`└──────────────────────────────────────────────────────────────────┘
9160
+ `);
9161
+ for (let i = 0;i < total; i++) {
9162
+ const step = steps[i];
9163
+ const percent = Math.round((i + 1) / total * 100);
9164
+ const bar = formatProgressBar(percent, 24);
9165
+ if (isTTY) {
9166
+ process.stdout.write(` ${bar} ⚡ LEVEL ${step.level}: ${step.title}...\r`);
9167
+ } else {
9168
+ console.log(` ${bar} ⚡ LEVEL ${step.level}: ${step.title}`);
9169
+ }
9170
+ try {
9171
+ await step.action();
9172
+ } catch (err) {
9173
+ console.log(`
9174
+ [!] Warning during step "${step.title}": ${err.message || err}`);
9175
+ }
9176
+ if (isTTY) {
9177
+ await new Promise((r) => setTimeout(r, 60));
9178
+ process.stdout.write(` ${bar} ✓ LEVEL ${step.level}: ${step.title} [OK]
9179
+ `);
9180
+ }
9181
+ }
9182
+ console.log();
9183
+ }
9184
+ async function repairInstallation(options = {}) {
9185
+ const root = options.workspaceRoot || process.cwd();
9186
+ const isGlobal = options.global === true;
9187
+ const memoryDir = options.memoryDir || (isGlobal ? getGlobalMemoryDir() : resolveMemoryDir({ root }));
9188
+ const actionsTaken = [];
9189
+ const memoriesDir = join19(memoryDir, "memories");
9190
+ if (!existsSync22(memoriesDir)) {
9191
+ mkdirSync13(memoriesDir, { recursive: true });
9192
+ actionsTaken.push(`Created missing memories directory: ${memoriesDir}`);
9193
+ }
9194
+ const currentPath = join19(memoryDir, "CURRENT.md");
9195
+ if (!existsSync22(currentPath)) {
9196
+ writeFileSync11(currentPath, `# Active Project Constraints
9197
+
9198
+ - [ ] Initial session constraints initialized.
9199
+ `, "utf8");
9200
+ actionsTaken.push(`Recovered missing CURRENT.md at ${currentPath}`);
9201
+ }
9202
+ const uPath = userFilePath(memoryDir);
9203
+ if (!existsSync22(uPath)) {
9204
+ initUserProfile(memoryDir, "developer", false, !isGlobal);
9205
+ actionsTaken.push(`Recovered missing USER.md profile at ${uPath}`);
9206
+ }
9207
+ let agentsConnected = 0;
9208
+ if (!options.skipAgentConnect) {
9209
+ try {
9210
+ const reports = connectAgent("all", undefined, { dryRun: false, force: false });
9211
+ agentsConnected = reports.filter((r) => r.updated || r.installed).length;
9212
+ if (agentsConnected > 0) {
9213
+ actionsTaken.push(`Auto-wired ${agentsConnected} detected agent platform(s)`);
9214
+ }
9215
+ } catch {}
9216
+ }
9217
+ if (!isGlobal && existsSync22(root)) {
9218
+ try {
9219
+ const index = indexGraph(root, memoryDir);
9220
+ if (index.symbolCount > 0) {
9221
+ actionsTaken.push(`Indexed ${index.symbolCount} AST symbols from ${index.provider}`);
9222
+ }
9223
+ } catch {}
9224
+ if (existsSync22(join19(root, ".git"))) {
9225
+ try {
9226
+ const hookRes = installGitHook(root);
9227
+ if (hookRes.installed) {
9228
+ actionsTaken.push(`Installed Git pre-commit transcript harvester hook`);
9229
+ }
9230
+ } catch {}
9231
+ }
9232
+ }
9233
+ return {
9234
+ repaired: true,
9235
+ actionsTaken,
9236
+ agentsConnected,
9237
+ memoryDir
9238
+ };
9239
+ }
9240
+ function executePackageUpgrade(pm, dryRun = false) {
9241
+ let cmd = "";
9242
+ switch (pm) {
9243
+ case "bun":
9244
+ cmd = "bun add -g musememory@latest";
9245
+ break;
9246
+ case "pnpm":
9247
+ cmd = "pnpm add -g musememory@latest";
9248
+ break;
9249
+ case "yarn":
9250
+ cmd = "yarn global add musememory@latest";
9251
+ break;
9252
+ default:
9253
+ cmd = "npm install -g musememory@latest";
9254
+ break;
9255
+ }
9256
+ if (!dryRun) {
9257
+ try {
9258
+ execSync2(cmd, { stdio: "inherit" });
9259
+ } catch (err) {
9260
+ throw new Error(`Failed running upgrade command "${cmd}": ${err.message || err}`);
9261
+ }
9262
+ }
9263
+ return cmd;
9264
+ }
9265
+ async function handleUpgradeCommand({ flags }) {
9266
+ const isGlobal = flags["global"] === "true" || flags["g"] === "true";
9267
+ const dryRun = flags["dry-run"] === "true";
9268
+ const force = flags["force"] === "true";
9269
+ const checkOnly = flags["check"] === "true";
9270
+ const pm = detectPackageManager();
9271
+ const currentVersion = "1.8.0";
9272
+ console.log(`[Upgrade] Checking for updates (detected package manager: ${pm})...`);
9273
+ const latestVersion = await getLatestNpmVersion();
9274
+ if (latestVersion) {
9275
+ console.log(` * Installed version: v${currentVersion}`);
9276
+ console.log(` * Latest release: v${latestVersion}`);
9277
+ }
9278
+ if (checkOnly) {
9279
+ if (latestVersion && latestVersion !== currentVersion) {
9280
+ console.log(`
9281
+ \uD83D\uDCA1 Update available: v${currentVersion} ➔ v${latestVersion}`);
9282
+ console.log(` Run 'memory upgrade' or '${pm === "bun" ? "bun add -g" : "npm install -g"} musememory@latest' to update.`);
9283
+ } else {
9284
+ console.log(`
9285
+ ✓ Muse Memory is up to date (v${currentVersion}).`);
9286
+ }
9287
+ return 0;
9288
+ }
9289
+ let repairInfo;
9290
+ const steps = [
9291
+ {
9292
+ level: 1,
9293
+ title: "Vibeguard Security & Credential Audit",
9294
+ action: async () => {}
9295
+ },
9296
+ {
9297
+ level: 2,
9298
+ title: `Package Manager Sync (${pm})`,
9299
+ action: async () => {
9300
+ if (!dryRun) {
9301
+ executePackageUpgrade(pm, dryRun);
9302
+ }
9303
+ }
9304
+ },
9305
+ {
9306
+ level: 3,
9307
+ title: "Synaptic Storage & Schema Alignment",
9308
+ action: async () => {
9309
+ repairInfo = await repairInstallation({ global: isGlobal });
9310
+ }
9311
+ },
9312
+ {
9313
+ level: 4,
9314
+ title: "80+ Agent Platforms & Skills Auto-Wiring",
9315
+ action: async () => {}
9316
+ },
9317
+ {
9318
+ level: 5,
9319
+ title: "Cognitive Ascendance Complete",
9320
+ action: async () => {}
9321
+ }
9322
+ ];
9323
+ await playGamifiedLoader(steps, { title: "SYSTEM LEVEL-UP & UPGRADE MATRIX" });
9324
+ console.log(`\uD83C\uDFC6 [LEVEL-UP COMPLETE] Muse Memory is now fully armed and up to date!`);
9325
+ if (repairInfo && repairInfo.actionsTaken.length > 0) {
9326
+ console.log(`
9327
+ \uD83D\uDD27 Self-Healing Actions Applied:`);
9328
+ for (const act of repairInfo.actionsTaken) {
9329
+ console.log(` ✓ ${act}`);
9330
+ }
9331
+ }
9332
+ console.log(`
9333
+ \uD83D\uDE80 Available Upgrade Commands for Reference:`);
9334
+ console.log(` • Bun: bun add -g musememory@latest`);
9335
+ console.log(` • NPM: npm install -g musememory@latest`);
9336
+ console.log(` • NPX: npx musememory@latest`);
9337
+ console.log(` • Auto: memory upgrade
9338
+ `);
9339
+ return 0;
9340
+ }
9341
+ var init_upgrade = __esm(() => {
9342
+ init_root();
9343
+ init_user();
9344
+ init_connect();
9345
+ init_graph();
9346
+ init_hook();
9347
+ });
9348
+
9031
9349
  // node_modules/ajv/dist/compile/codegen/code.js
9032
9350
  var require_code = __commonJS(function(exports) {
9033
9351
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -15329,8 +15647,8 @@ var require_ajv = __commonJS(function(exports, module) {
15329
15647
  });
15330
15648
 
15331
15649
  // src/schema.ts
15332
- import { existsSync as existsSync22, readFileSync as readFileSync18 } from "node:fs";
15333
- import { join as join19 } from "node:path";
15650
+ import { existsSync as existsSync23, readFileSync as readFileSync19 } from "node:fs";
15651
+ import { join as join20 } from "node:path";
15334
15652
  function getValidator() {
15335
15653
  if (cachedValidate)
15336
15654
  return cachedValidate;
@@ -15341,14 +15659,14 @@ function getValidator() {
15341
15659
  return !Number.isNaN(Date.parse(value));
15342
15660
  });
15343
15661
  const candidates = [
15344
- join19(import.meta.dir, "..", "schema.json"),
15345
- join19(import.meta.dir, "schema.json"),
15346
- join19(process.cwd(), "schema.json")
15662
+ join20(import.meta.dir, "..", "schema.json"),
15663
+ join20(import.meta.dir, "schema.json"),
15664
+ join20(process.cwd(), "schema.json")
15347
15665
  ];
15348
15666
  let schemaContent = null;
15349
15667
  for (const p of candidates) {
15350
- if (existsSync22(p)) {
15351
- schemaContent = readFileSync18(p, "utf8");
15668
+ if (existsSync23(p)) {
15669
+ schemaContent = readFileSync19(p, "utf8");
15352
15670
  break;
15353
15671
  }
15354
15672
  }
@@ -15455,19 +15773,265 @@ var init_schema = __esm(() => {
15455
15773
  import_ajv = __toESM(require_ajv(), 1);
15456
15774
  });
15457
15775
 
15776
+ // src/harvester.ts
15777
+ var exports_harvester = {};
15778
+ __export(exports_harvester, {
15779
+ discoverAgentTranscripts: () => discoverAgentTranscripts,
15780
+ getHarvestedTranscriptLedger: () => getHarvestedTranscriptLedger,
15781
+ getStandardAgentTranscriptDirs: () => getStandardAgentTranscriptDirs,
15782
+ handleLearnCommand: () => handleLearnCommand,
15783
+ harvestAllAgentTranscripts: () => harvestAllAgentTranscripts,
15784
+ saveHarvestedTranscriptLedger: () => saveHarvestedTranscriptLedger
15785
+ });
15786
+ import {
15787
+ existsSync as existsSync24,
15788
+ readFileSync as readFileSync20,
15789
+ writeFileSync as writeFileSync12,
15790
+ readdirSync as readdirSync8,
15791
+ statSync as statSync8,
15792
+ mkdirSync as mkdirSync14,
15793
+ openSync,
15794
+ readSync,
15795
+ closeSync
15796
+ } from "node:fs";
15797
+ import { join as join21, dirname as dirname5 } from "node:path";
15798
+ import { homedir as homedir5 } from "node:os";
15799
+ import { createHash as createHash2 } from "node:crypto";
15800
+ function getStandardAgentTranscriptDirs(home = homedir5()) {
15801
+ return [
15802
+ join21(home, ".gemini", "antigravity-cli", "brain"),
15803
+ join21(home, ".config", "opencode", "transcripts"),
15804
+ join21(home, ".local", "share", "opencode", "transcripts"),
15805
+ join21(home, ".claude", "transcripts"),
15806
+ join21(home, ".claude", "projects"),
15807
+ join21(home, ".config", "LIFEOS", "runtime", "transcripts"),
15808
+ join21(home, ".hermes", "sessions"),
15809
+ join21(home, ".hermes", "transcripts"),
15810
+ join21(home, ".config", "goose", "sessions"),
15811
+ join21(home, ".codex", "sessions"),
15812
+ join21(home, ".config", "Cursor", "User", "workspaceStorage"),
15813
+ join21(process.cwd(), ".memory", "inbox"),
15814
+ join21(process.cwd(), ".logs")
15815
+ ];
15816
+ }
15817
+ function findJsonlFilesInDir(dir, maxDepth = 4, currentDepth = 0, out = []) {
15818
+ if (currentDepth > maxDepth || !existsSync24(dir))
15819
+ return out;
15820
+ let entries;
15821
+ try {
15822
+ entries = readdirSync8(dir, { withFileTypes: true });
15823
+ } catch {
15824
+ return out;
15825
+ }
15826
+ for (const e of entries) {
15827
+ 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")) {
15828
+ continue;
15829
+ }
15830
+ const full = join21(dir, e.name);
15831
+ if (e.isDirectory()) {
15832
+ findJsonlFilesInDir(full, maxDepth, currentDepth + 1, out);
15833
+ } else if (e.isFile() && e.name.endsWith(".jsonl")) {
15834
+ if (!e.name.match(/^\d{8}\.jsonl$/) && e.name !== "transcript_full.jsonl") {
15835
+ out.push(full);
15836
+ }
15837
+ }
15838
+ }
15839
+ return out;
15840
+ }
15841
+ function discoverAgentTranscripts(options = {}) {
15842
+ const dirs = options.searchRoots && options.searchRoots.length > 0 ? options.searchRoots : getStandardAgentTranscriptDirs();
15843
+ const found = new Set;
15844
+ for (const d of dirs) {
15845
+ if (existsSync24(d)) {
15846
+ try {
15847
+ const stat = statSync8(d);
15848
+ if (stat.isDirectory()) {
15849
+ const files = findJsonlFilesInDir(d);
15850
+ for (const f of files)
15851
+ found.add(f);
15852
+ } else if (stat.isFile() && d.endsWith(".jsonl")) {
15853
+ found.add(d);
15854
+ }
15855
+ } catch {}
15856
+ }
15857
+ }
15858
+ const sorted = Array.from(found).sort((a, b) => {
15859
+ try {
15860
+ return statSync8(b).mtimeMs - statSync8(a).mtimeMs;
15861
+ } catch {
15862
+ return 0;
15863
+ }
15864
+ });
15865
+ if (options.maxFiles && options.maxFiles > 0) {
15866
+ return sorted.slice(0, options.maxFiles);
15867
+ }
15868
+ return sorted;
15869
+ }
15870
+ function getHarvestedTranscriptLedger(memoryDir) {
15871
+ const ledgerPath = join21(memoryDir, "harvested-transcripts.json");
15872
+ if (!existsSync24(ledgerPath))
15873
+ return {};
15874
+ try {
15875
+ const raw = readFileSync20(ledgerPath, "utf8");
15876
+ return JSON.parse(raw);
15877
+ } catch {
15878
+ return {};
15879
+ }
15880
+ }
15881
+ function saveHarvestedTranscriptLedger(memoryDir, ledger) {
15882
+ const ledgerPath = join21(memoryDir, "harvested-transcripts.json");
15883
+ const dir = dirname5(ledgerPath);
15884
+ if (!existsSync24(dir))
15885
+ mkdirSync14(dir, { recursive: true });
15886
+ writeFileSync12(ledgerPath, JSON.stringify(ledger, null, 2) + `
15887
+ `, "utf8");
15888
+ }
15889
+ function harvestAllAgentTranscripts(store, options = {}) {
15890
+ const memoryDir = options.memoryDir || join21(process.cwd(), ".memory");
15891
+ const ledger = getHarvestedTranscriptLedger(memoryDir);
15892
+ const files = discoverAgentTranscripts({
15893
+ searchRoots: options.searchRoots,
15894
+ maxFiles: options.maxFiles || 50
15895
+ });
15896
+ const result = {
15897
+ harvestedFilesCount: 0,
15898
+ totalFilesScanned: files.length,
15899
+ memoriesImported: 0,
15900
+ openLoopsDetected: 0,
15901
+ processedFiles: [],
15902
+ errors: []
15903
+ };
15904
+ for (const filePath of files) {
15905
+ try {
15906
+ const stat = statSync8(filePath);
15907
+ const prevEntry = ledger[filePath];
15908
+ if (!options.force && prevEntry && prevEntry.mtimeMs === stat.mtimeMs) {
15909
+ continue;
15910
+ }
15911
+ let content = "";
15912
+ if (stat.size > 2 * 1024 * 1024) {
15913
+ const fd = openSync(filePath, "r");
15914
+ const bufferSize = 512 * 1024;
15915
+ const buffer = Buffer.alloc(bufferSize);
15916
+ const position = Math.max(0, stat.size - bufferSize);
15917
+ const bytesRead = readSync(fd, buffer, 0, bufferSize, position);
15918
+ closeSync(fd);
15919
+ content = buffer.toString("utf8", 0, bytesRead);
15920
+ } else {
15921
+ content = readFileSync20(filePath, "utf8");
15922
+ }
15923
+ const contentHash = createHash2("sha256").update(content).digest("hex").slice(0, 16);
15924
+ if (!options.force && prevEntry && prevEntry.hash === contentHash) {
15925
+ continue;
15926
+ }
15927
+ let inferredProject = options.project;
15928
+ if (!inferredProject) {
15929
+ if (filePath.includes("/Projects/github/") || filePath.includes("/Projects/")) {
15930
+ const m = filePath.match(/\/Projects\/(?:github\/)?([^/]+)/);
15931
+ if (m)
15932
+ inferredProject = m[1];
15933
+ }
15934
+ }
15935
+ if (!inferredProject)
15936
+ inferredProject = "default";
15937
+ const importRes = importTranscript(store, content, {
15938
+ project: inferredProject,
15939
+ confirmed: options.confirmed === true,
15940
+ source: `auto_harvester:${filePath}`
15941
+ });
15942
+ ledger[filePath] = {
15943
+ mtimeMs: stat.mtimeMs,
15944
+ hash: contentHash,
15945
+ importedCount: importRes.imported,
15946
+ openLoopsCount: importRes.openLoops.length,
15947
+ harvestedAt: new Date().toISOString()
15948
+ };
15949
+ if (importRes.imported > 0 || importRes.openLoops.length > 0) {
15950
+ result.harvestedFilesCount++;
15951
+ result.memoriesImported += importRes.imported;
15952
+ result.openLoopsDetected += importRes.openLoops.length;
15953
+ result.processedFiles.push({
15954
+ path: filePath,
15955
+ imported: importRes.imported,
15956
+ openLoops: importRes.openLoops.length
15957
+ });
15958
+ recordAuditEvent(memoryDir, {
15959
+ operation: "transcript_import",
15960
+ entry_id: filePath,
15961
+ actor: "auto-harvester",
15962
+ details: {
15963
+ imported: importRes.imported,
15964
+ open_loops: importRes.openLoops.length,
15965
+ inferred_project: inferredProject
15966
+ }
15967
+ });
15968
+ }
15969
+ if (importRes.errors.length > 0) {
15970
+ result.errors.push(...importRes.errors.map((e) => `${filePath}: ${e}`));
15971
+ }
15972
+ } catch (err) {
15973
+ result.errors.push(`${filePath}: ${err.message || err}`);
15974
+ }
15975
+ }
15976
+ saveHarvestedTranscriptLedger(memoryDir, ledger);
15977
+ return result;
15978
+ }
15979
+ async function handleLearnCommand({ flags }) {
15980
+ const ctx = requireRoot(flags);
15981
+ if (!ctx)
15982
+ return 1;
15983
+ const isConfirmed = flags["confirmed"] === "true" || flags["confirm"] === "true";
15984
+ const force = flags["force"] === "true";
15985
+ const project = flags["project"];
15986
+ const maxFiles = flags["max"] ? parseInt(flags["max"], 10) : 50;
15987
+ console.log(`[Auto-Learner] Probing workstation for active AI agent transcripts...`);
15988
+ const res = harvestAllAgentTranscripts(ctx.store, {
15989
+ memoryDir: ctx.memoryDir,
15990
+ confirmed: isConfirmed,
15991
+ force,
15992
+ project,
15993
+ maxFiles
15994
+ });
15995
+ console.log(`[Auto-Learner] Scanned ${res.totalFilesScanned} agent transcript files.`);
15996
+ if (res.harvestedFilesCount === 0) {
15997
+ console.log(`✓ Up to date. 0 new un-harvested turns found (all transcripts indexed).`);
15998
+ return 0;
15999
+ }
16000
+ console.log(`
16001
+ \uD83C\uDF89 Distilled ${res.memoriesImported} new memories and ${res.openLoopsDetected} open loops from ${res.harvestedFilesCount} transcript(s):`);
16002
+ for (const p of res.processedFiles) {
16003
+ console.log(` * ${p.path} -> +${p.imported} memories, +${p.openLoops} loops`);
16004
+ }
16005
+ if (res.errors.length > 0) {
16006
+ console.log(`
16007
+ ⚠️ Warnings / Redactions during harvest:`);
16008
+ for (const err of res.errors.slice(0, 5)) {
16009
+ console.log(` - ${err}`);
16010
+ }
16011
+ }
16012
+ console.log(`
16013
+ \uD83D\uDCA1 Open 'memory ui' or run 'memory stats' to view your newly indexed cognitive graph.`);
16014
+ return 0;
16015
+ }
16016
+ var init_harvester = __esm(() => {
16017
+ init_harvest();
16018
+ init_audit();
16019
+ init_shared();
16020
+ });
16021
+
15458
16022
  // src/doctor.ts
15459
16023
  var exports_doctor = {};
15460
16024
  __export(exports_doctor, {
15461
16025
  printDoctorReport: () => printDoctorReport,
15462
16026
  runDoctor: () => runDoctor
15463
16027
  });
15464
- import { existsSync as existsSync23, statSync as statSync8, readFileSync as readFileSync19 } from "node:fs";
15465
- import { join as join20 } from "node:path";
15466
- import { homedir as homedir5 } from "node:os";
16028
+ import { existsSync as existsSync25, statSync as statSync9, readFileSync as readFileSync21 } from "node:fs";
16029
+ import { join as join22 } from "node:path";
16030
+ import { homedir as homedir6 } from "node:os";
15467
16031
  async function runDoctor(targetDir, options = {}) {
15468
- const home = homedir5();
15469
- const storagePath = options.global ? getGlobalMemoryDir() : findOrCreateProjectRoot(targetDir || process.cwd())?.memoryDir || join20(home, ".memory");
15470
- const isInitialized = existsSync23(storagePath);
16032
+ const home = homedir6();
16033
+ const storagePath = options.global ? getGlobalMemoryDir() : findOrCreateProjectRoot(targetDir || process.cwd())?.memoryDir || join22(home, ".memory");
16034
+ const isInitialized = existsSync25(storagePath);
15471
16035
  let currentMdExists = false;
15472
16036
  let currentMdLines = 0;
15473
16037
  let totalEntries = 0;
@@ -15485,10 +16049,10 @@ async function runDoctor(targetDir, options = {}) {
15485
16049
  let secretLeaksCount = 0;
15486
16050
  let brokenLinksCount = 0;
15487
16051
  if (isInitialized) {
15488
- const currentPath = join20(storagePath, "CURRENT.md");
15489
- if (existsSync23(currentPath)) {
16052
+ const currentPath = join22(storagePath, "CURRENT.md");
16053
+ if (existsSync25(currentPath)) {
15490
16054
  currentMdExists = true;
15491
- const content = readFileSync19(currentPath, "utf8");
16055
+ const content = readFileSync21(currentPath, "utf8");
15492
16056
  currentMdLines = content.split(`
15493
16057
  `).filter((l) => l.trim().length > 0).length;
15494
16058
  }
@@ -15509,21 +16073,21 @@ async function runDoctor(targetDir, options = {}) {
15509
16073
  valid = false;
15510
16074
  }
15511
16075
  }
15512
- const auditPath = join20(storagePath, "audit.jsonl");
16076
+ const auditPath = join22(storagePath, "audit.jsonl");
15513
16077
  let auditExists = false;
15514
16078
  let auditCount = 0;
15515
16079
  let auditSize = 0;
15516
16080
  let lastEvent;
15517
- if (existsSync23(auditPath)) {
16081
+ if (existsSync25(auditPath)) {
15518
16082
  auditExists = true;
15519
16083
  try {
15520
- const stat = statSync8(auditPath);
16084
+ const stat = statSync9(auditPath);
15521
16085
  auditSize = stat.size;
15522
16086
  const trail = getAuditTrail(storagePath, { limit: 1 });
15523
16087
  if (trail.length > 0) {
15524
16088
  lastEvent = `${trail[0].operation} on ${trail[0].entry_id} (${trail[0].timestamp})`;
15525
16089
  }
15526
- const raw = readFileSync19(auditPath, "utf8");
16090
+ const raw = readFileSync21(auditPath, "utf8");
15527
16091
  auditCount = raw.split(`
15528
16092
  `).filter((l) => l.trim().length > 0).length;
15529
16093
  } catch {}
@@ -15532,6 +16096,11 @@ async function runDoctor(targetDir, options = {}) {
15532
16096
  const installed = agents.filter((a) => a.installed);
15533
16097
  const connected = installed.filter((a) => a.connected);
15534
16098
  const unwired = installed.filter((a) => !a.connected);
16099
+ const { discoverAgentTranscripts: discoverAgentTranscripts2, getHarvestedTranscriptLedger: getHarvestedTranscriptLedger2 } = await Promise.resolve().then(() => (init_harvester(), exports_harvester));
16100
+ const discoveredFiles = discoverAgentTranscripts2();
16101
+ const ledger = getHarvestedTranscriptLedger2(storagePath);
16102
+ const harvestedFiles = Object.keys(ledger);
16103
+ const unharvestedCount = discoveredFiles.filter((f) => !ledger[f]).length;
15535
16104
  const memBin = findBinary("memory", home) || findBinary("musememory", home);
15536
16105
  const bunVer = typeof globalThis.Bun !== "undefined" ? globalThis.Bun.version : undefined;
15537
16106
  return {
@@ -15565,6 +16134,11 @@ async function runDoctor(targetDir, options = {}) {
15565
16134
  connectedList: connected.map((a) => a.name),
15566
16135
  unwiredList: unwired.map((a) => a.name)
15567
16136
  },
16137
+ transcripts: {
16138
+ discoveredCount: discoveredFiles.length,
16139
+ harvestedCount: harvestedFiles.length,
16140
+ unharvestedCount
16141
+ },
15568
16142
  runtime: {
15569
16143
  nodeVersion: process.version,
15570
16144
  bunVersion: bunVer,
@@ -15622,6 +16196,16 @@ function printDoctorReport(report) {
15622
16196
  console.log(` -> Run 'memory connect --all' or 'npx musememory connect --all' to wire them.`);
15623
16197
  }
15624
16198
  console.log(`
16199
+ [AUTO-LEARNER] Agent Chat Transcripts & Distillation:`);
16200
+ console.log(` Discovered Transcripts on Disk: ${report.transcripts.discoveredCount}`);
16201
+ console.log(` Harvested / Indexed: ${report.transcripts.harvestedCount}`);
16202
+ if (report.transcripts.unharvestedCount > 0) {
16203
+ console.log(` [!] New Un-Harvested Chats: ${report.transcripts.unharvestedCount}`);
16204
+ console.log(` -> Run 'memory learn' or 'memory sync-chats' to auto-distill learnings from recent AI interactions.`);
16205
+ } else {
16206
+ console.log(` [OK] All discovered chat transcripts are synchronized.`);
16207
+ }
16208
+ console.log(`
15625
16209
  [RUNTIME] Runtime & CLI Execution:`);
15626
16210
  console.log(` Node.js: ${report.runtime.nodeVersion}${report.runtime.bunVersion ? ` | Bun: v${report.runtime.bunVersion}` : ""}`);
15627
16211
  if (report.runtime.globalBinaryFound) {
@@ -15649,27 +16233,27 @@ var init_doctor = __esm(() => {
15649
16233
  });
15650
16234
 
15651
16235
  // src/retrieval/tree-index.ts
15652
- import { existsSync as existsSync24, readFileSync as readFileSync20, writeFileSync as writeFileSync11, mkdirSync as mkdirSync13, rmSync } from "node:fs";
15653
- import { join as join21 } from "node:path";
16236
+ import { existsSync as existsSync26, readFileSync as readFileSync22, writeFileSync as writeFileSync13, mkdirSync as mkdirSync15, rmSync } from "node:fs";
16237
+ import { join as join23 } from "node:path";
15654
16238
  function tokenize2(text) {
15655
16239
  if (!text || typeof text !== "string")
15656
16240
  return [];
15657
16241
  return text.toLowerCase().match(/[a-z0-9]+/g) ?? [];
15658
16242
  }
15659
16243
  function indexDir(memoryDir) {
15660
- return join21(memoryDir, "tree-index");
16244
+ return join23(memoryDir, "tree-index");
15661
16245
  }
15662
16246
  function partitionDir(idxDir, project, type2) {
15663
- return join21(idxDir, project, type2);
16247
+ return join23(idxDir, project, type2);
15664
16248
  }
15665
16249
  function shardFilePath(pDir, shardId) {
15666
- return join21(pDir, `${shardId}.json`);
16250
+ return join23(pDir, `${shardId}.json`);
15667
16251
  }
15668
16252
  function partitionIndexFilePath(pDir) {
15669
- return join21(pDir, "index.json");
16253
+ return join23(pDir, "index.json");
15670
16254
  }
15671
16255
  function globalIndexFilePath(idxDir) {
15672
- return join21(idxDir, "index.json");
16256
+ return join23(idxDir, "index.json");
15673
16257
  }
15674
16258
  function nowIso3() {
15675
16259
  return new Date().toISOString();
@@ -15759,7 +16343,7 @@ function countNodes(node) {
15759
16343
  function buildTreeIndex(store, memoryDir, config = {}) {
15760
16344
  const cfg = { ...DEFAULT_CONFIG, ...config };
15761
16345
  const allMemories = list(store).filter((e) => e.status === "confirmed");
15762
- mkdirSync13(indexDir(memoryDir), { recursive: true });
16346
+ mkdirSync15(indexDir(memoryDir), { recursive: true });
15763
16347
  if (allMemories.length === 0) {
15764
16348
  const emptyIndex = {
15765
16349
  version: 1,
@@ -15768,7 +16352,7 @@ function buildTreeIndex(store, memoryDir, config = {}) {
15768
16352
  totalMemories: 0,
15769
16353
  builtAt: nowIso3()
15770
16354
  };
15771
- writeFileSync11(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(emptyIndex, null, 2), "utf8");
16355
+ writeFileSync13(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(emptyIndex, null, 2), "utf8");
15772
16356
  return emptyIndex;
15773
16357
  }
15774
16358
  const groups = new Map;
@@ -15786,7 +16370,7 @@ function buildTreeIndex(store, memoryDir, config = {}) {
15786
16370
  for (const [key, memories] of groups) {
15787
16371
  const [project, type2] = key.split("|");
15788
16372
  const pDir = partitionDir(indexDir(memoryDir), project, type2);
15789
- mkdirSync13(pDir, { recursive: true });
16373
+ mkdirSync15(pDir, { recursive: true });
15790
16374
  const maxShardSize = cfg.shardThreshold || 1e4;
15791
16375
  const finalShards = [];
15792
16376
  const memoryChunks = [];
@@ -15847,9 +16431,9 @@ function buildTreeIndex(store, memoryDir, config = {}) {
15847
16431
  partitions[`${project}|${type2}`] = partition;
15848
16432
  totalIndexNodes += partitionNodes;
15849
16433
  totalIndexMemories += partitionMemories;
15850
- writeFileSync11(partitionIndexFilePath(pDir), JSON.stringify(partition, null, 2), "utf8");
16434
+ writeFileSync13(partitionIndexFilePath(pDir), JSON.stringify(partition, null, 2), "utf8");
15851
16435
  for (const shard of finalShards) {
15852
- writeFileSync11(shardFilePath(pDir, shard.id), JSON.stringify(shard, null, 2), "utf8");
16436
+ writeFileSync13(shardFilePath(pDir, shard.id), JSON.stringify(shard, null, 2), "utf8");
15853
16437
  }
15854
16438
  }
15855
16439
  const index = {
@@ -15859,15 +16443,15 @@ function buildTreeIndex(store, memoryDir, config = {}) {
15859
16443
  totalMemories: totalIndexMemories,
15860
16444
  builtAt: nowIso3()
15861
16445
  };
15862
- writeFileSync11(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(index, null, 2), "utf8");
16446
+ writeFileSync13(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(index, null, 2), "utf8");
15863
16447
  return index;
15864
16448
  }
15865
16449
  function loadTreeIndex(memoryDir) {
15866
16450
  const path = globalIndexFilePath(indexDir(memoryDir));
15867
- if (!existsSync24(path))
16451
+ if (!existsSync26(path))
15868
16452
  return null;
15869
16453
  try {
15870
- const data = JSON.parse(readFileSync20(path, "utf8"));
16454
+ const data = JSON.parse(readFileSync22(path, "utf8"));
15871
16455
  return data.version === 1 ? data : null;
15872
16456
  } catch {
15873
16457
  return null;
@@ -16012,10 +16596,10 @@ __export(exports_vector, {
16012
16596
  saveIndex: () => saveIndex,
16013
16597
  termFrequencies: () => termFrequencies
16014
16598
  });
16015
- import { existsSync as existsSync25, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14 } from "node:fs";
16016
- import { join as join22 } from "node:path";
16599
+ import { existsSync as existsSync27, readFileSync as readFileSync23, writeFileSync as writeFileSync14, mkdirSync as mkdirSync16 } from "node:fs";
16600
+ import { join as join24 } from "node:path";
16017
16601
  function indexFilePath(memoryDir) {
16018
- return join22(memoryDir, "index.json");
16602
+ return join24(memoryDir, "index.json");
16019
16603
  }
16020
16604
  function hashTrigram(tri) {
16021
16605
  let h = 2166136261;
@@ -16062,16 +16646,16 @@ function rebuildIndex(store) {
16062
16646
  return index;
16063
16647
  }
16064
16648
  function saveIndex(index, memoryDir) {
16065
- if (!existsSync25(memoryDir))
16066
- mkdirSync14(memoryDir, { recursive: true });
16067
- writeFileSync12(indexFilePath(memoryDir), JSON.stringify(index), "utf8");
16649
+ if (!existsSync27(memoryDir))
16650
+ mkdirSync16(memoryDir, { recursive: true });
16651
+ writeFileSync14(indexFilePath(memoryDir), JSON.stringify(index), "utf8");
16068
16652
  }
16069
16653
  function loadIndex(memoryDir) {
16070
16654
  const p = indexFilePath(memoryDir);
16071
- if (!existsSync25(p))
16655
+ if (!existsSync27(p))
16072
16656
  return null;
16073
16657
  try {
16074
- const parsed = JSON.parse(readFileSync21(p, "utf8"));
16658
+ const parsed = JSON.parse(readFileSync23(p, "utf8"));
16075
16659
  return parsed.version === 1 ? parsed : null;
16076
16660
  } catch {
16077
16661
  return null;
@@ -16143,8 +16727,8 @@ var init_vector = __esm(() => {
16143
16727
  });
16144
16728
 
16145
16729
  // src/pageindex/engine.ts
16146
- import { existsSync as existsSync26, mkdirSync as mkdirSync15, readFileSync as readFileSync22, writeFileSync as writeFileSync13, rmSync as rmSync2, readdirSync as readdirSync9 } from "node:fs";
16147
- import { join as join23 } from "node:path";
16730
+ import { existsSync as existsSync28, mkdirSync as mkdirSync17, readFileSync as readFileSync24, writeFileSync as writeFileSync15, rmSync as rmSync2, readdirSync as readdirSync10 } from "node:fs";
16731
+ import { join as join25 } from "node:path";
16148
16732
  function slugify2(text) {
16149
16733
  return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 50);
16150
16734
  }
@@ -16221,9 +16805,9 @@ function buildPageIndex(content, options) {
16221
16805
  root: rootNode
16222
16806
  };
16223
16807
  if (options.memoryDir && !options.dryRun) {
16224
- const dir = join23(options.memoryDir, "pageindex", project);
16225
- mkdirSync15(dir, { recursive: true });
16226
- writeFileSync13(join23(dir, `${indexId}.json`), JSON.stringify(doc, null, 2), "utf8");
16808
+ const dir = join25(options.memoryDir, "pageindex", project);
16809
+ mkdirSync17(dir, { recursive: true });
16810
+ writeFileSync15(join25(dir, `${indexId}.json`), JSON.stringify(doc, null, 2), "utf8");
16227
16811
  }
16228
16812
  return doc;
16229
16813
  }
@@ -16287,29 +16871,29 @@ function searchPageIndex(doc, options) {
16287
16871
  };
16288
16872
  }
16289
16873
  function loadPageIndex(memoryDir, project, indexId) {
16290
- const filePath = join23(memoryDir, "pageindex", project, `${indexId}.json`);
16291
- if (!existsSync26(filePath))
16874
+ const filePath = join25(memoryDir, "pageindex", project, `${indexId}.json`);
16875
+ if (!existsSync28(filePath))
16292
16876
  return null;
16293
16877
  try {
16294
- return JSON.parse(readFileSync22(filePath, "utf8"));
16878
+ return JSON.parse(readFileSync24(filePath, "utf8"));
16295
16879
  } catch {
16296
16880
  return null;
16297
16881
  }
16298
16882
  }
16299
16883
  function listPageIndexes(memoryDir, project) {
16300
- const base = join23(memoryDir, "pageindex");
16301
- if (!existsSync26(base))
16884
+ const base = join25(memoryDir, "pageindex");
16885
+ if (!existsSync28(base))
16302
16886
  return [];
16303
16887
  const results = [];
16304
- const projects = project ? [project] : readdirSync9(base);
16888
+ const projects = project ? [project] : readdirSync10(base);
16305
16889
  for (const p of projects) {
16306
- const pDir = join23(base, p);
16307
- if (!existsSync26(pDir))
16890
+ const pDir = join25(base, p);
16891
+ if (!existsSync28(pDir))
16308
16892
  continue;
16309
- for (const f of readdirSync9(pDir)) {
16893
+ for (const f of readdirSync10(pDir)) {
16310
16894
  if (f.endsWith(".json")) {
16311
16895
  try {
16312
- results.push(JSON.parse(readFileSync22(join23(pDir, f), "utf8")));
16896
+ results.push(JSON.parse(readFileSync24(join25(pDir, f), "utf8")));
16313
16897
  } catch {}
16314
16898
  }
16315
16899
  }
@@ -16317,8 +16901,8 @@ function listPageIndexes(memoryDir, project) {
16317
16901
  return results;
16318
16902
  }
16319
16903
  function deletePageIndex(memoryDir, project, indexId) {
16320
- const base = join23(memoryDir, "pageindex");
16321
- if (!existsSync26(base))
16904
+ const base = join25(memoryDir, "pageindex");
16905
+ if (!existsSync28(base))
16322
16906
  return { deletedCount: 0 };
16323
16907
  let count = 0;
16324
16908
  if (!project && !indexId) {
@@ -16326,14 +16910,14 @@ function deletePageIndex(memoryDir, project, indexId) {
16326
16910
  return { deletedCount: 1 };
16327
16911
  }
16328
16912
  if (project && !indexId) {
16329
- const pDir = join23(base, project);
16330
- if (existsSync26(pDir)) {
16913
+ const pDir = join25(base, project);
16914
+ if (existsSync28(pDir)) {
16331
16915
  rmSync2(pDir, { recursive: true, force: true });
16332
16916
  count++;
16333
16917
  }
16334
16918
  } else if (project && indexId) {
16335
- const file = join23(base, project, `${indexId}.json`);
16336
- if (existsSync26(file)) {
16919
+ const file = join25(base, project, `${indexId}.json`);
16920
+ if (existsSync28(file)) {
16337
16921
  rmSync2(file, { force: true });
16338
16922
  count++;
16339
16923
  }
@@ -16346,13 +16930,13 @@ var init_engine2 = __esm(() => {
16346
16930
  });
16347
16931
 
16348
16932
  // src/retrieval/engine.ts
16349
- import { existsSync as existsSync27 } from "node:fs";
16350
- import { join as join24 } from "node:path";
16933
+ import { existsSync as existsSync29 } from "node:fs";
16934
+ import { join as join26 } from "node:path";
16351
16935
 
16352
16936
  class RetrievalEngine {
16353
16937
  static search(store, memoryDir, query, options = {}) {
16354
16938
  const mode = options.mode ?? "auto";
16355
- if (mode === "pageindex" || options.docPath && existsSync27(options.docPath)) {
16939
+ if (mode === "pageindex" || options.docPath && existsSync29(options.docPath)) {
16356
16940
  try {
16357
16941
  const docs = listPageIndexes(memoryDir, options.project);
16358
16942
  if (docs.length > 0) {
@@ -16379,8 +16963,8 @@ class RetrievalEngine {
16379
16963
  }
16380
16964
  } catch {}
16381
16965
  }
16382
- const treeDir = join24(memoryDir, "tree");
16383
- const hasTree = existsSync27(treeDir);
16966
+ const treeDir = join26(memoryDir, "tree");
16967
+ const hasTree = existsSync29(treeDir);
16384
16968
  const allEntries = list(store);
16385
16969
  if (mode === "tree" || mode === "auto" && hasTree && allEntries.length >= 500) {
16386
16970
  try {
@@ -16418,7 +17002,7 @@ class RetrievalEngine {
16418
17002
  } catch {}
16419
17003
  }
16420
17004
  const vecPath = indexFilePath(memoryDir);
16421
- const hasVec = existsSync27(vecPath);
17005
+ const hasVec = existsSync29(vecPath);
16422
17006
  if (mode === "hybrid" || mode === "auto" && hasVec && allEntries.length > 100) {
16423
17007
  try {
16424
17008
  const hybridResults = hybridSearch(store, memoryDir, query, {
@@ -26114,8 +26698,8 @@ var init_loops = __esm(() => {
26114
26698
  });
26115
26699
 
26116
26700
  // src/distill.ts
26117
- import { existsSync as existsSync28, mkdirSync as mkdirSync16, writeFileSync as writeFileSync14 } from "node:fs";
26118
- import { join as join25 } from "node:path";
26701
+ import { existsSync as existsSync30, mkdirSync as mkdirSync18, writeFileSync as writeFileSync16 } from "node:fs";
26702
+ import { join as join27 } from "node:path";
26119
26703
  function fixTokens(e) {
26120
26704
  const bag = tokenBag(e.title, 2);
26121
26705
  mergeBag(bag, tokenBag((e.tags ?? []).join(" "), 2));
@@ -26126,7 +26710,7 @@ function distillSkills(store, workspaceRoot, options = {}) {
26126
26710
  const report = { created: [], skippedExisting: [], clustersBelowThreshold: 0 };
26127
26711
  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));
26128
26712
  const clusters = clusterByTokenOverlap(fixes, fixTokens, 0.5);
26129
- const skillsDir = options.skillsDir ?? join25(workspaceRoot, ".agents", "skills");
26713
+ const skillsDir = options.skillsDir ?? join27(workspaceRoot, ".agents", "skills");
26130
26714
  for (const cluster of clusters) {
26131
26715
  if (cluster.length < minCount) {
26132
26716
  report.clustersBelowThreshold++;
@@ -26134,9 +26718,9 @@ function distillSkills(store, workspaceRoot, options = {}) {
26134
26718
  }
26135
26719
  const topic = dominantTopicTokens(cluster.map((e) => e.title));
26136
26720
  const slug = slugifyId(topic.join("-") || "skill");
26137
- const dir = join25(skillsDir, slug);
26721
+ const dir = join27(skillsDir, slug);
26138
26722
  const memberIds = cluster.map((e) => e.id);
26139
- if (existsSync28(dir)) {
26723
+ if (existsSync30(dir)) {
26140
26724
  report.skippedExisting.push({ slug, members: memberIds });
26141
26725
  continue;
26142
26726
  }
@@ -26146,10 +26730,10 @@ function distillSkills(store, workspaceRoot, options = {}) {
26146
26730
  throw new Error(`Secret detected in generated SKILL.md for '${slug}': ${secrets.join(", ")}`);
26147
26731
  }
26148
26732
  if (!options.dryRun) {
26149
- mkdirSync16(dir, { recursive: true });
26150
- writeFileSync14(join25(dir, "SKILL.md"), md, "utf8");
26733
+ mkdirSync18(dir, { recursive: true });
26734
+ writeFileSync16(join27(dir, "SKILL.md"), md, "utf8");
26151
26735
  }
26152
- report.created.push({ slug, path: join25(dir, "SKILL.md"), members: memberIds });
26736
+ report.created.push({ slug, path: join27(dir, "SKILL.md"), members: memberIds });
26153
26737
  }
26154
26738
  return report;
26155
26739
  }
@@ -26487,14 +27071,14 @@ var init_schema2 = __esm(() => {
26487
27071
  });
26488
27072
 
26489
27073
  // src/settings/loader.ts
26490
- import { existsSync as existsSync29, mkdirSync as mkdirSync17, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
26491
- import { join as join26 } from "node:path";
27074
+ import { existsSync as existsSync31, mkdirSync as mkdirSync19, readFileSync as readFileSync25, writeFileSync as writeFileSync17 } from "node:fs";
27075
+ import { join as join28 } from "node:path";
26492
27076
  function getSettingsFilePath(memoryDir) {
26493
- return join26(memoryDir, "settings.json");
27077
+ return join28(memoryDir, "settings.json");
26494
27078
  }
26495
27079
  function loadSettings(memoryDir) {
26496
27080
  const filePath = getSettingsFilePath(memoryDir);
26497
- if (!existsSync29(filePath)) {
27081
+ if (!existsSync31(filePath)) {
26498
27082
  return {
26499
27083
  version: 1,
26500
27084
  global: JSON.parse(JSON.stringify(DEFAULT_SETTINGS)),
@@ -26502,7 +27086,7 @@ function loadSettings(memoryDir) {
26502
27086
  };
26503
27087
  }
26504
27088
  try {
26505
- const raw = readFileSync23(filePath, "utf8");
27089
+ const raw = readFileSync25(filePath, "utf8");
26506
27090
  const parsed = JSON.parse(raw);
26507
27091
  return {
26508
27092
  version: parsed.version || 1,
@@ -26518,9 +27102,9 @@ function loadSettings(memoryDir) {
26518
27102
  }
26519
27103
  }
26520
27104
  function saveSettings(store, memoryDir) {
26521
- mkdirSync17(memoryDir, { recursive: true });
27105
+ mkdirSync19(memoryDir, { recursive: true });
26522
27106
  const filePath = getSettingsFilePath(memoryDir);
26523
- writeFileSync15(filePath, JSON.stringify(store, null, 2), "utf8");
27107
+ writeFileSync17(filePath, JSON.stringify(store, null, 2), "utf8");
26524
27108
  }
26525
27109
  function getSettings(memoryDir) {
26526
27110
  return loadSettings(memoryDir).global;
@@ -26636,17 +27220,17 @@ __export(exports_plasticity, {
26636
27220
  recordCoActivation: () => recordCoActivation,
26637
27221
  saveHebbianGraph: () => saveHebbianGraph
26638
27222
  });
26639
- import { existsSync as existsSync30, readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "node:fs";
26640
- import { join as join27 } from "node:path";
27223
+ import { existsSync as existsSync32, readFileSync as readFileSync26, writeFileSync as writeFileSync18 } from "node:fs";
27224
+ import { join as join29 } from "node:path";
26641
27225
  function getPlasticityPath(memoryDir) {
26642
- return join27(memoryDir, "hebbian-plasticity.json");
27226
+ return join29(memoryDir, "hebbian-plasticity.json");
26643
27227
  }
26644
27228
  function loadHebbianGraph(memoryDir) {
26645
27229
  const p = getPlasticityPath(memoryDir);
26646
- if (!existsSync30(p))
27230
+ if (!existsSync32(p))
26647
27231
  return {};
26648
27232
  try {
26649
- return JSON.parse(readFileSync24(p, "utf8"));
27233
+ return JSON.parse(readFileSync26(p, "utf8"));
26650
27234
  } catch {
26651
27235
  return {};
26652
27236
  }
@@ -26654,7 +27238,7 @@ function loadHebbianGraph(memoryDir) {
26654
27238
  function saveHebbianGraph(memoryDir, graph) {
26655
27239
  const p = getPlasticityPath(memoryDir);
26656
27240
  try {
26657
- writeFileSync16(p, JSON.stringify(graph, null, 2), "utf8");
27241
+ writeFileSync18(p, JSON.stringify(graph, null, 2), "utf8");
26658
27242
  } catch {}
26659
27243
  }
26660
27244
  function recordCoActivation(memoryIds, memoryDir) {
@@ -26744,9 +27328,9 @@ __export(exports_drift, {
26744
27328
  scanCodeDrift: () => scanCodeDrift,
26745
27329
  scanCodeDriftFromDiff: () => scanCodeDriftFromDiff
26746
27330
  });
26747
- import { execSync as execSync2 } from "node:child_process";
26748
- import { existsSync as existsSync31 } from "node:fs";
26749
- import { join as join28, isAbsolute as isAbsolute2 } from "node:path";
27331
+ import { execSync as execSync3 } from "node:child_process";
27332
+ import { existsSync as existsSync33 } from "node:fs";
27333
+ import { join as join30, isAbsolute as isAbsolute2 } from "node:path";
26750
27334
  function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
26751
27335
  const root = workspaceRoot || process.cwd();
26752
27336
  const normalizedChanged = new Set(changedFiles.map((f) => f.trim().replace(/^[\.\/]+/, "")).filter(Boolean));
@@ -26760,8 +27344,8 @@ function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
26760
27344
  const norm = p.trim().replace(/^[\.\/]+/, "");
26761
27345
  const matched = Array.from(normalizedChanged).find((cf) => cf === norm || cf.endsWith(`/${norm}`) || norm.endsWith(`/${cf}`));
26762
27346
  if (matched) {
26763
- const fullPath = isAbsolute2(p) ? p : join28(root, p);
26764
- const exists = existsSync31(fullPath);
27347
+ const fullPath = isAbsolute2(p) ? p : join30(root, p);
27348
+ const exists = existsSync33(fullPath);
26765
27349
  drifted.push({
26766
27350
  memoryId: entry.id,
26767
27351
  title: entry.title,
@@ -26785,7 +27369,7 @@ function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
26785
27369
  function getGitChangedFiles(workspaceRoot) {
26786
27370
  const root = workspaceRoot || process.cwd();
26787
27371
  try {
26788
- const stdout = execSync2("git status --porcelain", {
27372
+ const stdout = execSync3("git status --porcelain", {
26789
27373
  cwd: root,
26790
27374
  encoding: "utf8",
26791
27375
  stdio: ["ignore", "pipe", "ignore"]
@@ -26802,7 +27386,7 @@ function getGitChangedFiles(workspaceRoot) {
26802
27386
  files.push(filePath);
26803
27387
  }
26804
27388
  try {
26805
- const diffOut = execSync2("git diff --name-only HEAD", {
27389
+ const diffOut = execSync3("git diff --name-only HEAD", {
26806
27390
  cwd: root,
26807
27391
  encoding: "utf8",
26808
27392
  stdio: ["ignore", "pipe", "ignore"]
@@ -27507,6 +28091,12 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
27507
28091
  recordCoActivation2(formatted.entries.map((e) => e.entry.id), activeMemoryDir);
27508
28092
  } catch {}
27509
28093
  }
28094
+ if (activeMemoryDir) {
28095
+ try {
28096
+ const { harvestAllAgentTranscripts: harvestAllAgentTranscripts2 } = await Promise.resolve().then(() => (init_harvester(), exports_harvester));
28097
+ harvestAllAgentTranscripts2(activeStore, { memoryDir: activeMemoryDir, maxFiles: 3 });
28098
+ } catch {}
28099
+ }
27510
28100
  let finalMarkdown = formatted.markdown;
27511
28101
  if (a.compress === true) {
27512
28102
  const { compressPromptContext: compressPromptContext2 } = await Promise.resolve().then(() => exports_compress);
@@ -27599,9 +28189,18 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
27599
28189
  }
27600
28190
  }
27601
28191
  case "memory_harvest": {
28192
+ if (a.all === true || a.auto === true || !a.text) {
28193
+ const { harvestAllAgentTranscripts: harvestAllAgentTranscripts2 } = await Promise.resolve().then(() => (init_harvester(), exports_harvester));
28194
+ const harvestRes = harvestAllAgentTranscripts2(activeStore, {
28195
+ memoryDir: activeMemoryDir,
28196
+ confirmed: a.confirmed === true,
28197
+ project: a.project ? String(a.project) : undefined
28198
+ });
28199
+ return toolResult(harvestRes);
28200
+ }
27602
28201
  const created = harvestMemories(activeStore, {
27603
28202
  text: String(a.text),
27604
- project: String(a.project),
28203
+ project: String(a.project || "default"),
27605
28204
  confirmed: a.confirmed === true
27606
28205
  });
27607
28206
  return toolResult({ harvested_count: created.length, entries: created });
@@ -28023,8 +28622,8 @@ __export(exports_daemon, {
28023
28622
  startHub: () => startHub
28024
28623
  });
28025
28624
  import { createServer as createServer2 } from "node:http";
28026
- import { existsSync as existsSync32 } from "node:fs";
28027
- import { join as join29 } from "node:path";
28625
+ import { existsSync as existsSync34 } from "node:fs";
28626
+ import { join as join31 } from "node:path";
28028
28627
  import { watch } from "node:fs";
28029
28628
  function startHub(port, memoryDir) {
28030
28629
  const clients = new Set;
@@ -28090,7 +28689,7 @@ data: ${JSON.stringify(event)}
28090
28689
  return clients.size;
28091
28690
  }
28092
28691
  if (memoryDir) {
28093
- const memoriesDir = join29(memoryDir, "memories");
28692
+ const memoriesDir = join31(memoryDir, "memories");
28094
28693
  const armDebounced = (type2) => {
28095
28694
  if (debounceTimer)
28096
28695
  clearTimeout(debounceTimer);
@@ -28099,11 +28698,11 @@ data: ${JSON.stringify(event)}
28099
28698
  }, DEBOUNCE_MS);
28100
28699
  };
28101
28700
  try {
28102
- if (existsSync32(memoriesDir)) {
28701
+ if (existsSync34(memoriesDir)) {
28103
28702
  watchers.push(watch(memoriesDir, () => armDebounced("memory.changed")));
28104
28703
  }
28105
- const currentMd = join29(memoryDir, "CURRENT.md");
28106
- if (existsSync32(currentMd)) {
28704
+ const currentMd = join31(memoryDir, "CURRENT.md");
28705
+ if (existsSync34(currentMd)) {
28107
28706
  watchers.push(watch(currentMd, () => armDebounced("constraints.changed")));
28108
28707
  }
28109
28708
  } catch {}
@@ -28136,19 +28735,19 @@ var DEBOUNCE_MS = 300;
28136
28735
  var init_daemon = () => {};
28137
28736
 
28138
28737
  // src/cli/ecosystem.ts
28139
- import { join as join30 } from "node:path";
28140
- import { existsSync as existsSync33, mkdirSync as mkdirSync18, writeFileSync as writeFileSync17, readFileSync as readFileSync25 } from "node:fs";
28141
- import { homedir as homedir6 } from "node:os";
28738
+ import { join as join32 } from "node:path";
28739
+ import { existsSync as existsSync35, mkdirSync as mkdirSync20, writeFileSync as writeFileSync19, readFileSync as readFileSync27 } from "node:fs";
28740
+ import { homedir as homedir7 } from "node:os";
28142
28741
  function ensureProjectAgentInstructions(targetDir) {
28143
- const agentsMdPath = join30(targetDir, "AGENTS.md");
28144
- if (existsSync33(agentsMdPath)) {
28742
+ const agentsMdPath = join32(targetDir, "AGENTS.md");
28743
+ if (existsSync35(agentsMdPath)) {
28145
28744
  try {
28146
- const existing = readFileSync25(agentsMdPath, "utf8");
28745
+ const existing = readFileSync27(agentsMdPath, "utf8");
28147
28746
  if (existing.includes("<!-- agentmemory:start -->")) {
28148
28747
  const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
28149
- writeFileSync17(agentsMdPath, updated, "utf8");
28748
+ writeFileSync19(agentsMdPath, updated, "utf8");
28150
28749
  } else if (!existing.includes("<!-- musememory:start -->") && !existing.includes("Muse Memory")) {
28151
- writeFileSync17(agentsMdPath, `${existing.trim()}
28750
+ writeFileSync19(agentsMdPath, `${existing.trim()}
28152
28751
 
28153
28752
  ${MUSE_MEMORY_DIRECTIVE}
28154
28753
  `, "utf8");
@@ -28159,23 +28758,23 @@ ${MUSE_MEMORY_DIRECTIVE}
28159
28758
 
28160
28759
  ${MUSE_MEMORY_DIRECTIVE}
28161
28760
  `;
28162
- writeFileSync17(agentsMdPath, initialContent, "utf8");
28761
+ writeFileSync19(agentsMdPath, initialContent, "utf8");
28163
28762
  }
28164
28763
  }
28165
28764
  async function handleInstallCommand({ positional, flags }) {
28166
28765
  const isGlobal = flags["global"] === "true" || flags["g"] === "true";
28167
- const targetDir = positional[0] ? join30(process.cwd(), positional[0]) : process.cwd();
28168
- const memoryDir = isGlobal ? getGlobalMemoryDir() : join30(targetDir, ".memory");
28766
+ const targetDir = positional[0] ? join32(process.cwd(), positional[0]) : process.cwd();
28767
+ const memoryDir = isGlobal ? getGlobalMemoryDir() : join32(targetDir, ".memory");
28169
28768
  const globalDir = getGlobalMemoryDir();
28170
- mkdirSync18(join30(memoryDir, "memories"), { recursive: true });
28171
- mkdirSync18(join30(globalDir, "memories"), { recursive: true });
28172
- const currentPath = join30(memoryDir, "CURRENT.md");
28173
- if (!existsSync33(currentPath)) {
28174
- writeFileSync17(currentPath, `# Active Project Constraints
28769
+ mkdirSync20(join32(memoryDir, "memories"), { recursive: true });
28770
+ mkdirSync20(join32(globalDir, "memories"), { recursive: true });
28771
+ const currentPath = join32(memoryDir, "CURRENT.md");
28772
+ if (!existsSync35(currentPath)) {
28773
+ writeFileSync19(currentPath, `# Active Project Constraints
28175
28774
  `, "utf8");
28176
28775
  }
28177
28776
  const globalUserPath = userFilePath(globalDir);
28178
- if (!existsSync33(globalUserPath)) {
28777
+ if (!existsSync35(globalUserPath)) {
28179
28778
  const { promptSingleSelect: promptSingleSelect2 } = await Promise.resolve().then(() => (init_prompt(), exports_prompt));
28180
28779
  const archetypeOptions = [
28181
28780
  { id: "developer", label: "Software Engineer / Developer", hint: "Code-first, direct, strict typing" },
@@ -28191,45 +28790,78 @@ async function handleInstallCommand({ positional, flags }) {
28191
28790
  if (!isGlobal) {
28192
28791
  ensureProjectAgentInstructions(targetDir);
28193
28792
  }
28194
- const globalAgentsMd = join30(homedir6(), ".agents", "AGENTS.md");
28195
- if (existsSync33(globalAgentsMd)) {
28793
+ const globalAgentsMd = join32(homedir7(), ".agents", "AGENTS.md");
28794
+ if (existsSync35(globalAgentsMd)) {
28196
28795
  try {
28197
- const existing = readFileSync25(globalAgentsMd, "utf8");
28796
+ const existing = readFileSync27(globalAgentsMd, "utf8");
28198
28797
  if (existing.includes("<!-- agentmemory:start -->")) {
28199
28798
  const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
28200
- writeFileSync17(globalAgentsMd, updated, "utf8");
28799
+ writeFileSync19(globalAgentsMd, updated, "utf8");
28201
28800
  }
28202
28801
  } catch {}
28203
28802
  }
28803
+ const { playGamifiedLoader: playGamifiedLoader2 } = await Promise.resolve().then(() => (init_upgrade(), exports_upgrade));
28804
+ let reports = [];
28805
+ let detected = [];
28806
+ const installSteps = [
28807
+ {
28808
+ level: 1,
28809
+ title: "Storage Layout & Memory Directory Scaffold",
28810
+ action: async () => {}
28811
+ },
28812
+ {
28813
+ level: 2,
28814
+ title: "80+ Coding Agent Auto-Wiring Matrix",
28815
+ action: async () => {
28816
+ const { connectAgent: connectAgent2 } = await Promise.resolve().then(() => (init_connect(), exports_connect));
28817
+ reports = connectAgent2("all", undefined, { dryRun: false, force: false });
28818
+ }
28819
+ },
28820
+ {
28821
+ level: 3,
28822
+ title: "External Memory Provider Probe (24+ Formats)",
28823
+ action: async () => {
28824
+ detected = detectProviders(targetDir).filter((p) => p.detected);
28825
+ }
28826
+ },
28827
+ {
28828
+ level: 4,
28829
+ title: "Git Pre-Commit Harvester Verification",
28830
+ action: async () => {
28831
+ if (!isGlobal) {
28832
+ await promptOrNotifyGitHook(targetDir, flags["auto"] === "true" || flags["yes"] === "true");
28833
+ }
28834
+ }
28835
+ },
28836
+ {
28837
+ level: 5,
28838
+ title: "Cognitive Onboarding Ready",
28839
+ action: async () => {}
28840
+ }
28841
+ ];
28204
28842
  console.log(`[+] Initialized Muse Memory in ${memoryDir}`);
28205
- const { connectAgent: connectAgent2 } = await Promise.resolve().then(() => (init_connect(), exports_connect));
28206
- const reports = connectAgent2("all", undefined, { dryRun: false, force: false });
28843
+ await playGamifiedLoader2(installSteps, { title: "AUTONOMOUS ONBOARDING MATRIX" });
28207
28844
  if (reports.length > 0) {
28208
- console.log(`
28209
- [+] Auto-wired ${reports.length} detected coding agent(s) with zero permissions:`);
28845
+ console.log(`[+] Auto-wired ${reports.length} detected coding agent(s) with zero permissions:`);
28210
28846
  for (const r of reports) {
28211
28847
  console.log(` * ${r.agentName}: ${r.message}`);
28212
28848
  }
28213
28849
  }
28214
- const detected = detectProviders(targetDir).filter((p) => p.detected);
28215
28850
  if (detected.length > 0) {
28216
28851
  console.log(`
28217
28852
  [!] Detected ${detected.length} external memory provider(s): ${detected.map((d) => d.name).join(", ")}`);
28218
28853
  console.log(` -> Run 'memory migrate' to auto-import legacy memories.`);
28219
28854
  }
28220
- if (!isGlobal) {
28221
- await promptOrNotifyGitHook(targetDir, flags["auto"] === "true" || flags["yes"] === "true");
28222
- }
28223
28855
  console.log(`
28224
- [OK] Muse Memory is ready! Use 'memory doctor' to verify system health.`);
28856
+ [OK] Muse Memory is initialized and ready! Use 'memory doctor' to verify health.`);
28225
28857
  return 0;
28226
28858
  }
28227
28859
  async function promptOrNotifyGitHook(targetDir, autoInstall = false) {
28228
- const gitDir = join30(targetDir, ".git");
28229
- if (!existsSync33(gitDir))
28860
+ const gitDir = join32(targetDir, ".git");
28861
+ if (!existsSync35(gitDir))
28230
28862
  return false;
28231
- const hookPath = join30(gitDir, "hooks", "pre-commit");
28232
- const isInstalled = existsSync33(hookPath) && readFileSync25(hookPath, "utf8").includes("memory harvest-auto");
28863
+ const hookPath = join32(gitDir, "hooks", "pre-commit");
28864
+ const isInstalled = existsSync35(hookPath) && readFileSync27(hookPath, "utf8").includes("memory harvest-auto");
28233
28865
  if (isInstalled)
28234
28866
  return true;
28235
28867
  if (autoInstall) {
@@ -28255,44 +28887,75 @@ async function handleDoctorCommand({ positional, flags }) {
28255
28887
  return report.validation.valid ? 0 : 1;
28256
28888
  }
28257
28889
  async function handleUninstallCommand({ positional, flags }) {
28890
+ const { playGamifiedLoader: playGamifiedLoader2 } = await Promise.resolve().then(() => (init_upgrade(), exports_upgrade));
28258
28891
  const { disconnectAllAgents: disconnectAllAgents2, disconnectSingleAgent: disconnectSingleAgent2 } = await Promise.resolve().then(() => (init_connect(), exports_connect));
28259
28892
  const agent = positional[0];
28260
28893
  const purge = flags["purge"] === "true";
28261
28894
  const dryRun = flags["dry-run"] === "true";
28895
+ let unwiredReports = [];
28896
+ const uninstallSteps = [
28897
+ {
28898
+ level: 1,
28899
+ title: "Agent Platform Discovery & Configuration Lock",
28900
+ action: async () => {}
28901
+ },
28902
+ {
28903
+ level: 2,
28904
+ title: `Unwiring Agent Platforms (${agent || "all"})`,
28905
+ action: async () => {
28906
+ if (agent && agent !== "all") {
28907
+ const report = disconnectSingleAgent2(agent, undefined, { dryRun });
28908
+ unwiredReports = [report];
28909
+ } else {
28910
+ unwiredReports = disconnectAllAgents2(undefined, { dryRun });
28911
+ }
28912
+ }
28913
+ },
28914
+ {
28915
+ level: 3,
28916
+ title: purge ? "Purging Memory Store (.memory/)" : "Preserving Cognitive Memory Store (.memory/)",
28917
+ action: async () => {
28918
+ if (purge) {
28919
+ const ctx = requireRoot(flags);
28920
+ if (ctx && existsSync35(ctx.memoryDir) && !dryRun) {
28921
+ const { rmSync: rmSync3 } = await import("node:fs");
28922
+ rmSync3(ctx.memoryDir, { recursive: true, force: true });
28923
+ }
28924
+ }
28925
+ }
28926
+ },
28927
+ {
28928
+ level: 4,
28929
+ title: "Clean Teardown Verification",
28930
+ action: async () => {}
28931
+ }
28932
+ ];
28262
28933
  console.log(`[CLEAN] Running Muse Memory Uninstaller${dryRun ? " [DRY RUN]" : ""}...`);
28263
- if (agent && agent !== "all") {
28264
- const report = disconnectSingleAgent2(agent, undefined, { dryRun });
28265
- console.log(` * ${report.agentName}: ${report.message}`);
28266
- } else {
28267
- const reports = disconnectAllAgents2(undefined, { dryRun });
28268
- console.log(`
28269
- [+] Unwired ${reports.length} coding agent(s):`);
28270
- for (const r of reports) {
28934
+ await playGamifiedLoader2(uninstallSteps, { title: `SYSTEM UNINSTALL MATRIX${dryRun ? " [DRY RUN]" : ""}` });
28935
+ if (unwiredReports.length > 0) {
28936
+ console.log(`[+] Unwired ${unwiredReports.length} coding agent(s):`);
28937
+ for (const r of unwiredReports) {
28271
28938
  console.log(` * ${r.agentName}: ${r.message}`);
28272
28939
  }
28273
28940
  }
28274
28941
  if (purge) {
28275
- const ctx = requireRoot(flags);
28276
- if (ctx && existsSync33(ctx.memoryDir) && !dryRun) {
28277
- const { rmSync: rmSync3 } = await import("node:fs");
28278
- rmSync3(ctx.memoryDir, { recursive: true, force: true });
28279
- console.log(` [PURGED] Memory directory removed: ${ctx.memoryDir}`);
28280
- }
28942
+ console.log(`
28943
+ [PURGED] Memory directory removed successfully.`);
28281
28944
  } else {
28282
28945
  console.log(`
28283
- [INFO] Memory files preserved in .memory/. Use 'memory uninstall --purge' to remove data.`);
28946
+ [INFO] Memory files preserved in .memory/. (Use 'memory uninstall --purge' to remove data).`);
28284
28947
  }
28285
28948
  return 0;
28286
28949
  }
28287
28950
  async function handleInitCommand({ positional, flags }) {
28288
28951
  const isGlobal = flags["global"] === "true";
28289
- const targetDir = positional[0] ? join30(process.cwd(), positional[0]) : process.cwd();
28952
+ const targetDir = positional[0] ? join32(process.cwd(), positional[0]) : process.cwd();
28290
28953
  const memoryDirName = flags["legacy"] === "true" ? ".musememory" : ".memory";
28291
- const memoryDir = isGlobal ? getGlobalMemoryDir() : join30(targetDir, memoryDirName);
28292
- mkdirSync18(join30(memoryDir, "memories"), { recursive: true });
28293
- const currentPath = join30(memoryDir, "CURRENT.md");
28294
- if (!existsSync33(currentPath)) {
28295
- writeFileSync17(currentPath, `# Active Project Constraints
28954
+ const memoryDir = isGlobal ? getGlobalMemoryDir() : join32(targetDir, memoryDirName);
28955
+ mkdirSync20(join32(memoryDir, "memories"), { recursive: true });
28956
+ const currentPath = join32(memoryDir, "CURRENT.md");
28957
+ if (!existsSync35(currentPath)) {
28958
+ writeFileSync19(currentPath, `# Active Project Constraints
28296
28959
  `, "utf8");
28297
28960
  }
28298
28961
  if (!isGlobal) {
@@ -28468,6 +29131,13 @@ async function handleUiCommand({ flags }) {
28468
29131
  if (!ctx)
28469
29132
  return 1;
28470
29133
  const port = flags["port"] ? parseInt(flags["port"], 10) : 2222;
29134
+ try {
29135
+ const { harvestAllAgentTranscripts: harvestAllAgentTranscripts2 } = await Promise.resolve().then(() => (init_harvester(), exports_harvester));
29136
+ const harvestRes = harvestAllAgentTranscripts2(ctx.store, { memoryDir: ctx.memoryDir });
29137
+ if (harvestRes.harvestedFilesCount > 0) {
29138
+ console.log(`[UI Auto-Sync] Distilled ${harvestRes.memoriesImported} new memories from ${harvestRes.harvestedFilesCount} agent transcript(s).`);
29139
+ }
29140
+ } catch {}
28471
29141
  const { startUiServer: startUiServer2 } = await Promise.resolve().then(() => (init_ui(), exports_ui));
28472
29142
  const srv = await startUiServer2({
28473
29143
  port,
@@ -28576,8 +29246,8 @@ var init_ecosystem = __esm(() => {
28576
29246
  });
28577
29247
 
28578
29248
  // src/agentcontract.ts
28579
- import { existsSync as existsSync34 } from "node:fs";
28580
- import { join as join31 } from "node:path";
29249
+ import { existsSync as existsSync36 } from "node:fs";
29250
+ import { join as join33 } from "node:path";
28581
29251
  function parseAgentMemoryContract(markdown) {
28582
29252
  if (!markdown || !markdown.startsWith("---"))
28583
29253
  return null;
@@ -28609,17 +29279,17 @@ function parseAgentMemoryContract(markdown) {
28609
29279
  function resolveAgentFile(nameOrPath, workspaceRoot) {
28610
29280
  if (!nameOrPath)
28611
29281
  return null;
28612
- if (existsSync34(nameOrPath))
29282
+ if (existsSync36(nameOrPath))
28613
29283
  return nameOrPath;
28614
29284
  const candidates = [
28615
- join31(workspaceRoot, ".agents", `${nameOrPath}.md`),
28616
- join31(workspaceRoot, ".memory", "agents", `${nameOrPath}.md`)
29285
+ join33(workspaceRoot, ".agents", `${nameOrPath}.md`),
29286
+ join33(workspaceRoot, ".memory", "agents", `${nameOrPath}.md`)
28617
29287
  ];
28618
29288
  const home = process.env.HOME;
28619
29289
  if (home)
28620
- candidates.push(join31(home, ".config", "opencode", "agents", `${nameOrPath}.md`));
29290
+ candidates.push(join33(home, ".config", "opencode", "agents", `${nameOrPath}.md`));
28621
29291
  for (const c of candidates) {
28622
- if (existsSync34(c))
29292
+ if (existsSync36(c))
28623
29293
  return c;
28624
29294
  }
28625
29295
  return null;
@@ -28629,8 +29299,8 @@ var init_agentcontract = __esm(() => {
28629
29299
  });
28630
29300
 
28631
29301
  // src/cli/retrieval.ts
28632
- import { existsSync as existsSync35, readFileSync as readFileSync26 } from "node:fs";
28633
- import { join as join32 } from "node:path";
29302
+ import { existsSync as existsSync37, readFileSync as readFileSync28 } from "node:fs";
29303
+ import { join as join34 } from "node:path";
28634
29304
  async function handleContextCommand({ positional, flags }) {
28635
29305
  let agentTypes;
28636
29306
  let agentTags;
@@ -28638,7 +29308,7 @@ async function handleContextCommand({ positional, flags }) {
28638
29308
  const file = resolveAgentFile(flags["for-agent"], flags["dir"] ?? process.cwd());
28639
29309
  if (!file)
28640
29310
  return usageError(`--for-agent: cannot resolve agent '${flags["for-agent"]}'`);
28641
- const contract = parseAgentMemoryContract(readFileSync26(file, "utf8"));
29311
+ const contract = parseAgentMemoryContract(readFileSync28(file, "utf8"));
28642
29312
  if (contract) {
28643
29313
  agentTypes = contract.types;
28644
29314
  agentTags = contract.tags;
@@ -28778,7 +29448,7 @@ async function handleHarvestCommand({ positional, flags }) {
28778
29448
  const project = flags["project"];
28779
29449
  if (!project)
28780
29450
  return usageError("harvest requires --project");
28781
- const rawText = existsSync35(target) ? readFileSync26(target, "utf8") : target;
29451
+ const rawText = existsSync37(target) ? readFileSync28(target, "utf8") : target;
28782
29452
  const created = harvestMemories(ctx.store, {
28783
29453
  text: rawText,
28784
29454
  project,
@@ -28814,8 +29484,8 @@ async function handleSearchTranscriptCommand({ positional, flags }) {
28814
29484
  const filePath = positional[1];
28815
29485
  if (!query)
28816
29486
  return usageError("search-transcript requires <query> [file.jsonl]");
28817
- const targetFile = filePath ? filePath.startsWith("/") ? filePath : join32(process.cwd(), filePath) : join32(process.cwd(), "transcript.jsonl");
28818
- if (!existsSync35(targetFile)) {
29487
+ const targetFile = filePath ? filePath.startsWith("/") ? filePath : join34(process.cwd(), filePath) : join34(process.cwd(), "transcript.jsonl");
29488
+ if (!existsSync37(targetFile)) {
28819
29489
  return fail(`error: transcript file not found: ${targetFile}`);
28820
29490
  }
28821
29491
  const windowSize = flags["window"] ? parseInt(flags["window"], 10) : 2;
@@ -28831,7 +29501,7 @@ async function handleReindexCommand({ flags }) {
28831
29501
  const { rebuildIndex: rebuildIndex2, saveIndex: saveIndex2 } = await Promise.resolve().then(() => (init_vector(), exports_vector));
28832
29502
  const index = rebuildIndex2(ctx.store);
28833
29503
  saveIndex2(index, ctx.memoryDir);
28834
- console.log(`indexed ${Object.keys(index.entries).length} entries -> ${join32(ctx.memoryDir, "index.json")}`);
29504
+ console.log(`indexed ${Object.keys(index.entries).length} entries -> ${join34(ctx.memoryDir, "index.json")}`);
28835
29505
  return 0;
28836
29506
  }
28837
29507
  async function handleHookCommand({ positional, flags }) {
@@ -29222,7 +29892,7 @@ var init_entities2 = __esm(() => {
29222
29892
  });
29223
29893
 
29224
29894
  // src/cli/settings.ts
29225
- import { writeFileSync as writeFileSync18, readFileSync as readFileSync27 } from "node:fs";
29895
+ import { writeFileSync as writeFileSync20, readFileSync as readFileSync29 } from "node:fs";
29226
29896
  function handleSettingsCommand(parsed) {
29227
29897
  const ctx = requireRoot(parsed.flags);
29228
29898
  if (!ctx)
@@ -29304,7 +29974,7 @@ function handleSettingsCommand(parsed) {
29304
29974
  const out = parsed.flags.out;
29305
29975
  const json2 = exportSettings(memoryDir);
29306
29976
  if (out) {
29307
- writeFileSync18(out, json2, "utf8");
29977
+ writeFileSync20(out, json2, "utf8");
29308
29978
  console.log(`Exported settings to ${out}`);
29309
29979
  } else {
29310
29980
  console.log(json2);
@@ -29318,7 +29988,7 @@ function handleSettingsCommand(parsed) {
29318
29988
  return 2;
29319
29989
  }
29320
29990
  try {
29321
- const raw = readFileSync27(file, "utf8");
29991
+ const raw = readFileSync29(file, "utf8");
29322
29992
  importSettings(memoryDir, raw);
29323
29993
  console.log(`Successfully imported settings from ${file}`);
29324
29994
  return 0;
@@ -29341,16 +30011,16 @@ var init_nudge = __esm(() => {
29341
30011
  });
29342
30012
 
29343
30013
  // src/routines.ts
29344
- import { readFileSync as readFileSync28, existsSync as existsSync36 } from "node:fs";
29345
- import { join as join33 } from "node:path";
30014
+ import { readFileSync as readFileSync30, existsSync as existsSync38 } from "node:fs";
30015
+ import { join as join35 } from "node:path";
29346
30016
  function routinesPath(memoryDir) {
29347
- return join33(memoryDir, "routines.yaml");
30017
+ return join35(memoryDir, "routines.yaml");
29348
30018
  }
29349
30019
  function loadRoutines(memoryDir) {
29350
30020
  const p = routinesPath(memoryDir);
29351
- if (!existsSync36(p))
30021
+ if (!existsSync38(p))
29352
30022
  return { routines: {} };
29353
- const doc2 = yaml.load(readFileSync28(p, "utf8"), { schema: yaml.JSON_SCHEMA }) ?? {};
30023
+ const doc2 = yaml.load(readFileSync30(p, "utf8"), { schema: yaml.JSON_SCHEMA }) ?? {};
29354
30024
  const routines = doc2.routines ?? {};
29355
30025
  for (const [name, r] of Object.entries(routines)) {
29356
30026
  if (!r || typeof r.schedule !== "string" || !r.schedule.trim()) {
@@ -29388,7 +30058,7 @@ var init_routines = __esm(() => {
29388
30058
  });
29389
30059
 
29390
30060
  // src/cli/lifecycle.ts
29391
- import { writeFileSync as writeFileSync19, readFileSync as readFileSync29, existsSync as existsSync37 } from "node:fs";
30061
+ import { writeFileSync as writeFileSync21, readFileSync as readFileSync31, existsSync as existsSync39 } from "node:fs";
29392
30062
  async function handleProposeCommand({ positional, flags }) {
29393
30063
  const ctx = requireRoot(flags);
29394
30064
  if (!ctx)
@@ -29537,7 +30207,7 @@ async function handleExportCommand({ flags }) {
29537
30207
  const snapshot = exportSnapshot(ctx.store);
29538
30208
  const outPath = flags["out"];
29539
30209
  if (outPath) {
29540
- writeFileSync19(outPath, JSON.stringify(snapshot, null, 2), "utf8");
30210
+ writeFileSync21(outPath, JSON.stringify(snapshot, null, 2), "utf8");
29541
30211
  console.log(`exported ${snapshot.total} memories to ${outPath}`);
29542
30212
  } else {
29543
30213
  console.log(JSON.stringify(snapshot, null, 2));
@@ -29551,9 +30221,9 @@ async function handleImportCommand({ positional, flags }) {
29551
30221
  const file = positional[0];
29552
30222
  if (!file)
29553
30223
  return usageError("import requires <file.json>");
29554
- if (!existsSync37(file))
30224
+ if (!existsSync39(file))
29555
30225
  return fail(`error: file ${file} does not exist`);
29556
- const raw = JSON.parse(readFileSync29(file, "utf8"));
30226
+ const raw = JSON.parse(readFileSync31(file, "utf8"));
29557
30227
  const res = importSnapshot(ctx.store, raw, { overwrite: flags["overwrite"] === "true" });
29558
30228
  if (res.errors.length > 0) {
29559
30229
  console.error(`import encountered errors:`);
@@ -29918,6 +30588,9 @@ async function main(argv) {
29918
30588
  switch (cmd) {
29919
30589
  case "install":
29920
30590
  return handleInstallCommand(parsed);
30591
+ case "upgrade":
30592
+ case "update":
30593
+ return handleUpgradeCommand(parsed);
29921
30594
  case "doctor":
29922
30595
  return handleDoctorCommand(parsed);
29923
30596
  case "uninstall":
@@ -29958,6 +30631,9 @@ async function main(argv) {
29958
30631
  return handleSearchTranscriptCommand(parsed);
29959
30632
  case "harvest":
29960
30633
  return handleHarvestCommand(parsed);
30634
+ case "learn":
30635
+ case "sync-chats":
30636
+ return handleLearnCommand(parsed);
29961
30637
  case "harvest-auto":
29962
30638
  return handleHarvestAutoCommand(parsed);
29963
30639
  case "hook":
@@ -30043,6 +30719,7 @@ Usage:
30043
30719
 
30044
30720
  Core Memory Lifecycle Commands:
30045
30721
  install [dir] Run interactive onboarding wizard & auto-wire installed agents
30722
+ upgrade / update [--check] Auto-fetch latest release, self-heal, and sync agent platforms
30046
30723
  doctor [dir] Run comprehensive ecosystem health diagnostic
30047
30724
  uninstall [agent] [--purge] Disconnect agents and optionally purge .memory data
30048
30725
  init [dir] Initialize .memory/ in workspace or current dir
@@ -30090,6 +30767,7 @@ Ecosystem, Migration & Connectivity:
30090
30767
  agents / detect-agents Scan workstation for 80+ coding agent platforms
30091
30768
  detect Scan machine for 24+ external memory formats
30092
30769
  migrate [--from P] [--all] Ingest external memories with state preservation & secret scrubbing
30770
+ learn / sync-chats [--confirm] Auto-discover and harvest memories from all agent chats across machine
30093
30771
  harvest <file|text> --project P Distill conversation transcripts into structured memory units
30094
30772
  harvest-auto [--from <glob>] [--project P] Harvest inbox transcripts as candidates and archive them
30095
30773
  hook install --git Install the harvester as a git pre-commit hook (never clobbers)
@@ -30105,6 +30783,8 @@ Ecosystem, Migration & Connectivity:
30105
30783
  var init_cli = __esm(() => {
30106
30784
  init_shared();
30107
30785
  init_ecosystem();
30786
+ init_upgrade();
30787
+ init_harvester();
30108
30788
  init_retrieval3();
30109
30789
  init_persona();
30110
30790
  init_wiki2();