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.
- package/README.md +48 -10
- package/dist/index.js +2314 -270
- 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
|
|
9127
|
-
const
|
|
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
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
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
|
|
9137
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9147
|
-
|
|
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
|
-
|
|
9151
|
-
|
|
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
|
-
|
|
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
|
|
15756
|
-
import { join as
|
|
15757
|
-
import { homedir as
|
|
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 =
|
|
15760
|
-
const storagePath = options.global ? getGlobalMemoryDir() : findOrCreateProjectRoot(targetDir || process.cwd())?.memoryDir ||
|
|
15761
|
-
const isInitialized =
|
|
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 =
|
|
15780
|
-
if (
|
|
16200
|
+
const currentPath = join22(storagePath, "CURRENT.md");
|
|
16201
|
+
if (existsSync25(currentPath)) {
|
|
15781
16202
|
currentMdExists = true;
|
|
15782
|
-
const content =
|
|
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 =
|
|
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 (
|
|
16229
|
+
if (existsSync25(auditPath)) {
|
|
15809
16230
|
auditExists = true;
|
|
15810
16231
|
try {
|
|
15811
|
-
const stat =
|
|
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 =
|
|
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
|
|
15944
|
-
import { join as
|
|
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
|
|
16392
|
+
return join23(memoryDir, "tree-index");
|
|
15952
16393
|
}
|
|
15953
16394
|
function partitionDir(idxDir, project, type2) {
|
|
15954
|
-
return
|
|
16395
|
+
return join23(idxDir, project, type2);
|
|
15955
16396
|
}
|
|
15956
16397
|
function shardFilePath(pDir, shardId) {
|
|
15957
|
-
return
|
|
16398
|
+
return join23(pDir, `${shardId}.json`);
|
|
15958
16399
|
}
|
|
15959
16400
|
function partitionIndexFilePath(pDir) {
|
|
15960
|
-
return
|
|
16401
|
+
return join23(pDir, "index.json");
|
|
15961
16402
|
}
|
|
15962
16403
|
function globalIndexFilePath(idxDir) {
|
|
15963
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16582
|
+
writeFileSync13(partitionIndexFilePath(pDir), JSON.stringify(partition, null, 2), "utf8");
|
|
16142
16583
|
for (const shard of finalShards) {
|
|
16143
|
-
|
|
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
|
-
|
|
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 (!
|
|
16599
|
+
if (!existsSync26(path))
|
|
16159
16600
|
return null;
|
|
16160
16601
|
try {
|
|
16161
|
-
const data = JSON.parse(
|
|
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
|
|
16307
|
-
import { join as
|
|
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
|
|
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 (!
|
|
16357
|
-
|
|
16358
|
-
|
|
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 (!
|
|
16803
|
+
if (!existsSync27(p))
|
|
16363
16804
|
return null;
|
|
16364
16805
|
try {
|
|
16365
|
-
const parsed = JSON.parse(
|
|
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
|
|
16438
|
-
import { join as
|
|
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 =
|
|
16516
|
-
|
|
16517
|
-
|
|
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 =
|
|
16582
|
-
if (!
|
|
17022
|
+
const filePath = join25(memoryDir, "pageindex", project, `${indexId}.json`);
|
|
17023
|
+
if (!existsSync28(filePath))
|
|
16583
17024
|
return null;
|
|
16584
17025
|
try {
|
|
16585
|
-
return JSON.parse(
|
|
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 =
|
|
16592
|
-
if (!
|
|
17032
|
+
const base = join25(memoryDir, "pageindex");
|
|
17033
|
+
if (!existsSync28(base))
|
|
16593
17034
|
return [];
|
|
16594
17035
|
const results = [];
|
|
16595
|
-
const projects = project ? [project] :
|
|
17036
|
+
const projects = project ? [project] : readdirSync10(base);
|
|
16596
17037
|
for (const p of projects) {
|
|
16597
|
-
const pDir =
|
|
16598
|
-
if (!
|
|
17038
|
+
const pDir = join25(base, p);
|
|
17039
|
+
if (!existsSync28(pDir))
|
|
16599
17040
|
continue;
|
|
16600
|
-
for (const f of
|
|
17041
|
+
for (const f of readdirSync10(pDir)) {
|
|
16601
17042
|
if (f.endsWith(".json")) {
|
|
16602
17043
|
try {
|
|
16603
|
-
results.push(JSON.parse(
|
|
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 =
|
|
16612
|
-
if (!
|
|
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 =
|
|
16621
|
-
if (
|
|
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 =
|
|
16627
|
-
if (
|
|
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
|
|
16641
|
-
import { join as
|
|
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 &&
|
|
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 =
|
|
16674
|
-
const hasTree =
|
|
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 =
|
|
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
|
|
26409
|
-
import { join as
|
|
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 ??
|
|
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 =
|
|
26971
|
+
const dir = join28(skillsDir, slug);
|
|
26429
26972
|
const memberIds = cluster.map((e) => e.id);
|
|
26430
|
-
if (
|
|
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
|
-
|
|
26441
|
-
|
|
26983
|
+
mkdirSync19(dir, { recursive: true });
|
|
26984
|
+
writeFileSync17(join28(dir, "SKILL.md"), md, "utf8");
|
|
26442
26985
|
}
|
|
26443
|
-
report.created.push({ slug, path:
|
|
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
|
-
|
|
26569
|
-
|
|
26570
|
-
|
|
26571
|
-
});
|
|
26572
|
-
|
|
26573
|
-
|
|
26574
|
-
|
|
26575
|
-
|
|
26576
|
-
|
|
26577
|
-
|
|
26578
|
-
|
|
26579
|
-
|
|
26580
|
-
}
|
|
26581
|
-
|
|
26582
|
-
|
|
26583
|
-
|
|
26584
|
-
|
|
26585
|
-
|
|
26586
|
-
|
|
26587
|
-
|
|
26588
|
-
|
|
26589
|
-
|
|
26590
|
-
|
|
26591
|
-
|
|
26592
|
-
|
|
26593
|
-
|
|
26594
|
-
|
|
26595
|
-
|
|
26596
|
-
|
|
26597
|
-
|
|
26598
|
-
|
|
26599
|
-
|
|
26600
|
-
|
|
26601
|
-
|
|
26602
|
-
|
|
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
|
|
26782
|
-
import { join as
|
|
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
|
|
27676
|
+
return join31(memoryDir, "settings.json");
|
|
26785
27677
|
}
|
|
26786
27678
|
function loadSettings(memoryDir) {
|
|
26787
27679
|
const filePath = getSettingsFilePath(memoryDir);
|
|
26788
|
-
if (!
|
|
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 =
|
|
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
|
-
|
|
27704
|
+
mkdirSync22(memoryDir, { recursive: true });
|
|
26813
27705
|
const filePath = getSettingsFilePath(memoryDir);
|
|
26814
|
-
|
|
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
|
|
26931
|
-
import { join as
|
|
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
|
|
28329
|
+
return join35(memoryDir, "hebbian-plasticity.json");
|
|
26934
28330
|
}
|
|
26935
28331
|
function loadHebbianGraph(memoryDir) {
|
|
26936
28332
|
const p = getPlasticityPath(memoryDir);
|
|
26937
|
-
if (!
|
|
28333
|
+
if (!existsSync38(p))
|
|
26938
28334
|
return {};
|
|
26939
28335
|
try {
|
|
26940
|
-
return JSON.parse(
|
|
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
|
-
|
|
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
|
|
27040
|
-
import { join as
|
|
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 :
|
|
27055
|
-
const exists =
|
|
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
|
-
|
|
27133
|
-
const
|
|
27134
|
-
const { root, memoryDir } = findOrCreateProjectRoot(
|
|
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
|
-
|
|
27655
|
-
|
|
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: "
|
|
27661
|
-
description: "
|
|
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
|
-
|
|
27666
|
-
|
|
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: "
|
|
27676
|
-
description: "
|
|
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
|
-
|
|
27681
|
-
|
|
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: "
|
|
27691
|
-
description: "
|
|
29249
|
+
name: "memory_prompt_get",
|
|
29250
|
+
description: "Get prompt template by name",
|
|
27692
29251
|
inputSchema: {
|
|
27693
29252
|
type: "object",
|
|
27694
29253
|
properties: {
|
|
27695
|
-
|
|
27696
|
-
|
|
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: ["
|
|
29257
|
+
required: ["name"]
|
|
27702
29258
|
}
|
|
27703
29259
|
},
|
|
27704
29260
|
{
|
|
27705
|
-
name: "
|
|
27706
|
-
description: "
|
|
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
|
-
|
|
27711
|
-
|
|
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: "
|
|
27717
|
-
description: "
|
|
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
|
-
|
|
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: "
|
|
27727
|
-
description: "
|
|
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
|
-
|
|
27732
|
-
|
|
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: ["
|
|
29300
|
+
required: ["iteration_index", "critic_verdict", "largest_fix_identified", "test_results"]
|
|
27735
29301
|
}
|
|
27736
29302
|
},
|
|
27737
29303
|
{
|
|
27738
|
-
name: "
|
|
27739
|
-
description: "
|
|
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: "
|
|
27749
|
-
description: "
|
|
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
|
-
|
|
27754
|
-
|
|
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
|
|
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
|
|
28317
|
-
import { existsSync as
|
|
28318
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
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 (
|
|
30088
|
+
if (existsSync40(memoriesDir)) {
|
|
28394
30089
|
watchers.push(watch(memoriesDir, () => armDebounced("memory.changed")));
|
|
28395
30090
|
}
|
|
28396
|
-
const currentMd =
|
|
28397
|
-
if (
|
|
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
|
|
28431
|
-
import { existsSync as
|
|
28432
|
-
import { homedir as
|
|
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 =
|
|
28435
|
-
if (
|
|
30129
|
+
const agentsMdPath = join38(targetDir, "AGENTS.md");
|
|
30130
|
+
if (existsSync41(agentsMdPath)) {
|
|
28436
30131
|
try {
|
|
28437
|
-
const existing =
|
|
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
|
-
|
|
30135
|
+
writeFileSync25(agentsMdPath, updated, "utf8");
|
|
28441
30136
|
} else if (!existing.includes("<!-- musememory:start -->") && !existing.includes("Muse Memory")) {
|
|
28442
|
-
|
|
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
|
-
|
|
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] ?
|
|
28459
|
-
const memoryDir = isGlobal ? getGlobalMemoryDir() :
|
|
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
|
-
|
|
28462
|
-
|
|
28463
|
-
const currentPath =
|
|
28464
|
-
if (!
|
|
28465
|
-
|
|
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 (!
|
|
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 =
|
|
28486
|
-
if (
|
|
30180
|
+
const globalAgentsMd = join38(homedir7(), ".agents", "AGENTS.md");
|
|
30181
|
+
if (existsSync41(globalAgentsMd)) {
|
|
28487
30182
|
try {
|
|
28488
|
-
const existing =
|
|
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
|
-
|
|
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 =
|
|
28553
|
-
if (!
|
|
30247
|
+
const gitDir = join38(targetDir, ".git");
|
|
30248
|
+
if (!existsSync41(gitDir))
|
|
28554
30249
|
return false;
|
|
28555
|
-
const hookPath =
|
|
28556
|
-
const isInstalled =
|
|
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 &&
|
|
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] ?
|
|
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() :
|
|
28647
|
-
|
|
28648
|
-
const currentPath =
|
|
28649
|
-
if (!
|
|
28650
|
-
|
|
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
|
|
28935
|
-
import { join as
|
|
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 (
|
|
30669
|
+
if (existsSync42(nameOrPath))
|
|
28968
30670
|
return nameOrPath;
|
|
28969
30671
|
const candidates = [
|
|
28970
|
-
|
|
28971
|
-
|
|
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(
|
|
30677
|
+
candidates.push(join39(home, ".config", "opencode", "agents", `${nameOrPath}.md`));
|
|
28976
30678
|
for (const c of candidates) {
|
|
28977
|
-
if (
|
|
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
|
|
28988
|
-
import { join as
|
|
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(
|
|
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 =
|
|
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 :
|
|
29173
|
-
if (!
|
|
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 -> ${
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
|
29700
|
-
import { join as
|
|
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
|
|
31425
|
+
return join41(memoryDir, "routines.yaml");
|
|
29703
31426
|
}
|
|
29704
31427
|
function loadRoutines(memoryDir) {
|
|
29705
31428
|
const p = routinesPath(memoryDir);
|
|
29706
|
-
if (!
|
|
31429
|
+
if (!existsSync44(p))
|
|
29707
31430
|
return { routines: {} };
|
|
29708
|
-
const doc2 = yaml.load(
|
|
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
|
|
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
|
-
|
|
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 (!
|
|
31632
|
+
if (!existsSync45(file))
|
|
29910
31633
|
return fail(`error: file ${file} does not exist`);
|
|
29911
|
-
const raw = JSON.parse(
|
|
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]
|
|
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
|
|
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
|