musememory 1.10.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 +47 -10
- package/dist/index.js +1907 -183
- 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;
|
|
@@ -5292,6 +5304,30 @@ var sqliteDriver = "none";
|
|
|
5292
5304
|
var init_sqlite = () => {};
|
|
5293
5305
|
|
|
5294
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
|
+
});
|
|
5295
5331
|
import { resolve } from "node:path";
|
|
5296
5332
|
import { readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync5, renameSync, unlinkSync, mkdirSync as mkdirSync7, existsSync as existsSync10 } from "node:fs";
|
|
5297
5333
|
import { join as join7 } from "node:path";
|
|
@@ -9058,18 +9094,48 @@ var init_hook = __esm(() => {
|
|
|
9058
9094
|
// src/cli/upgrade.ts
|
|
9059
9095
|
var exports_upgrade = {};
|
|
9060
9096
|
__export(exports_upgrade, {
|
|
9097
|
+
DEFAULT_PANDA_FRAMES: () => DEFAULT_PANDA_FRAMES,
|
|
9061
9098
|
detectPackageManager: () => detectPackageManager,
|
|
9062
9099
|
executePackageUpgrade: () => executePackageUpgrade,
|
|
9100
|
+
formatPandaProgressBar: () => formatPandaProgressBar,
|
|
9063
9101
|
formatProgressBar: () => formatProgressBar,
|
|
9064
9102
|
getLatestNpmVersion: () => getLatestNpmVersion,
|
|
9065
9103
|
getUpgradeMilestones: () => getUpgradeMilestones,
|
|
9066
9104
|
handleUpgradeCommand: () => handleUpgradeCommand,
|
|
9067
9105
|
playGamifiedLoader: () => playGamifiedLoader,
|
|
9106
|
+
playPandaLoader: () => playPandaLoader,
|
|
9068
9107
|
repairInstallation: () => repairInstallation
|
|
9069
9108
|
});
|
|
9070
9109
|
import { execSync as execSync2 } from "node:child_process";
|
|
9071
9110
|
import { existsSync as existsSync22, mkdirSync as mkdirSync13, writeFileSync as writeFileSync11 } from "node:fs";
|
|
9072
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
|
+
}
|
|
9073
9139
|
function formatProgressBar(percent, width = 20) {
|
|
9074
9140
|
const p = Math.max(0, Math.min(100, percent));
|
|
9075
9141
|
const filledCount = Math.round(p / 100 * width);
|
|
@@ -9150,36 +9216,110 @@ function getUpgradeMilestones() {
|
|
|
9150
9216
|
}
|
|
9151
9217
|
];
|
|
9152
9218
|
}
|
|
9153
|
-
async function
|
|
9154
|
-
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;
|
|
9155
9223
|
const total = steps.length;
|
|
9156
|
-
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
`
|
|
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;
|
|
9161
9236
|
for (let i = 0;i < total; i++) {
|
|
9162
9237
|
const step = steps[i];
|
|
9163
|
-
const
|
|
9164
|
-
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;
|
|
9165
9242
|
if (isTTY) {
|
|
9166
|
-
|
|
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}...`);
|
|
9167
9265
|
} else {
|
|
9168
|
-
|
|
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
|
+
`);
|
|
9169
9275
|
}
|
|
9170
9276
|
try {
|
|
9171
9277
|
await step.action();
|
|
9172
9278
|
} catch (err) {
|
|
9173
|
-
|
|
9174
|
-
|
|
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);
|
|
9175
9292
|
}
|
|
9176
9293
|
if (isTTY) {
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
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));
|
|
9180
9305
|
}
|
|
9181
9306
|
}
|
|
9182
|
-
|
|
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
|
+
}
|
|
9183
9323
|
}
|
|
9184
9324
|
async function repairInstallation(options = {}) {
|
|
9185
9325
|
const root = options.workspaceRoot || process.cwd();
|
|
@@ -9338,12 +9478,20 @@ async function handleUpgradeCommand({ flags }) {
|
|
|
9338
9478
|
`);
|
|
9339
9479
|
return 0;
|
|
9340
9480
|
}
|
|
9481
|
+
var DEFAULT_PANDA_FRAMES, playGamifiedLoader;
|
|
9341
9482
|
var init_upgrade = __esm(() => {
|
|
9342
9483
|
init_root();
|
|
9343
9484
|
init_user();
|
|
9344
9485
|
init_connect();
|
|
9345
9486
|
init_graph();
|
|
9346
9487
|
init_hook();
|
|
9488
|
+
DEFAULT_PANDA_FRAMES = [
|
|
9489
|
+
"ʕ•ᴥ•ʔ",
|
|
9490
|
+
"ʕ •ᴥ•ʔ",
|
|
9491
|
+
"ʕ-ᴥ-ʔ",
|
|
9492
|
+
"ʕ•ᴥ•ʔノ"
|
|
9493
|
+
];
|
|
9494
|
+
playGamifiedLoader = playPandaLoader;
|
|
9347
9495
|
});
|
|
9348
9496
|
|
|
9349
9497
|
// node_modules/ajv/dist/compile/codegen/code.js
|
|
@@ -17058,6 +17206,8 @@ var init_retrieval2 = __esm(() => {
|
|
|
17058
17206
|
});
|
|
17059
17207
|
|
|
17060
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";
|
|
17061
17211
|
function exportSnapshot(store) {
|
|
17062
17212
|
const entries = list(store);
|
|
17063
17213
|
return {
|
|
@@ -17106,6 +17256,106 @@ function importSnapshot(store, snapshot, options = {}) {
|
|
|
17106
17256
|
}
|
|
17107
17257
|
return { imported, skipped, errors };
|
|
17108
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
|
+
}
|
|
17109
17359
|
var init_snapshot = __esm(() => {
|
|
17110
17360
|
init_store();
|
|
17111
17361
|
init_schema();
|
|
@@ -26698,8 +26948,8 @@ var init_loops = __esm(() => {
|
|
|
26698
26948
|
});
|
|
26699
26949
|
|
|
26700
26950
|
// src/distill.ts
|
|
26701
|
-
import { existsSync as
|
|
26702
|
-
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";
|
|
26703
26953
|
function fixTokens(e) {
|
|
26704
26954
|
const bag = tokenBag(e.title, 2);
|
|
26705
26955
|
mergeBag(bag, tokenBag((e.tags ?? []).join(" "), 2));
|
|
@@ -26710,7 +26960,7 @@ function distillSkills(store, workspaceRoot, options = {}) {
|
|
|
26710
26960
|
const report = { created: [], skippedExisting: [], clustersBelowThreshold: 0 };
|
|
26711
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));
|
|
26712
26962
|
const clusters = clusterByTokenOverlap(fixes, fixTokens, 0.5);
|
|
26713
|
-
const skillsDir = options.skillsDir ??
|
|
26963
|
+
const skillsDir = options.skillsDir ?? join28(workspaceRoot, ".agents", "skills");
|
|
26714
26964
|
for (const cluster of clusters) {
|
|
26715
26965
|
if (cluster.length < minCount) {
|
|
26716
26966
|
report.clustersBelowThreshold++;
|
|
@@ -26718,9 +26968,9 @@ function distillSkills(store, workspaceRoot, options = {}) {
|
|
|
26718
26968
|
}
|
|
26719
26969
|
const topic = dominantTopicTokens(cluster.map((e) => e.title));
|
|
26720
26970
|
const slug = slugifyId(topic.join("-") || "skill");
|
|
26721
|
-
const dir =
|
|
26971
|
+
const dir = join28(skillsDir, slug);
|
|
26722
26972
|
const memberIds = cluster.map((e) => e.id);
|
|
26723
|
-
if (
|
|
26973
|
+
if (existsSync31(dir)) {
|
|
26724
26974
|
report.skippedExisting.push({ slug, members: memberIds });
|
|
26725
26975
|
continue;
|
|
26726
26976
|
}
|
|
@@ -26730,10 +26980,10 @@ function distillSkills(store, workspaceRoot, options = {}) {
|
|
|
26730
26980
|
throw new Error(`Secret detected in generated SKILL.md for '${slug}': ${secrets.join(", ")}`);
|
|
26731
26981
|
}
|
|
26732
26982
|
if (!options.dryRun) {
|
|
26733
|
-
|
|
26734
|
-
|
|
26983
|
+
mkdirSync19(dir, { recursive: true });
|
|
26984
|
+
writeFileSync17(join28(dir, "SKILL.md"), md, "utf8");
|
|
26735
26985
|
}
|
|
26736
|
-
report.created.push({ slug, path:
|
|
26986
|
+
report.created.push({ slug, path: join28(dir, "SKILL.md"), members: memberIds });
|
|
26737
26987
|
}
|
|
26738
26988
|
return report;
|
|
26739
26989
|
}
|
|
@@ -26772,6 +27022,183 @@ var init_distill = __esm(() => {
|
|
|
26772
27022
|
init_consolidate();
|
|
26773
27023
|
});
|
|
26774
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
|
+
|
|
26775
27202
|
// src/verify.ts
|
|
26776
27203
|
import { execFile } from "node:child_process";
|
|
26777
27204
|
function runCommand(command, cwd, timeoutSec) {
|
|
@@ -26858,6 +27285,178 @@ ${result.stderr}`.trim().slice(0, 2000)
|
|
|
26858
27285
|
}
|
|
26859
27286
|
return result;
|
|
26860
27287
|
}
|
|
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
|
+
}
|
|
26861
27460
|
var init_verify = __esm(() => {
|
|
26862
27461
|
init_store();
|
|
26863
27462
|
init_audit();
|
|
@@ -27071,14 +27670,14 @@ var init_schema2 = __esm(() => {
|
|
|
27071
27670
|
});
|
|
27072
27671
|
|
|
27073
27672
|
// src/settings/loader.ts
|
|
27074
|
-
import { existsSync as
|
|
27075
|
-
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";
|
|
27076
27675
|
function getSettingsFilePath(memoryDir) {
|
|
27077
|
-
return
|
|
27676
|
+
return join31(memoryDir, "settings.json");
|
|
27078
27677
|
}
|
|
27079
27678
|
function loadSettings(memoryDir) {
|
|
27080
27679
|
const filePath = getSettingsFilePath(memoryDir);
|
|
27081
|
-
if (!
|
|
27680
|
+
if (!existsSync34(filePath)) {
|
|
27082
27681
|
return {
|
|
27083
27682
|
version: 1,
|
|
27084
27683
|
global: JSON.parse(JSON.stringify(DEFAULT_SETTINGS)),
|
|
@@ -27086,7 +27685,7 @@ function loadSettings(memoryDir) {
|
|
|
27086
27685
|
};
|
|
27087
27686
|
}
|
|
27088
27687
|
try {
|
|
27089
|
-
const raw =
|
|
27688
|
+
const raw = readFileSync28(filePath, "utf8");
|
|
27090
27689
|
const parsed = JSON.parse(raw);
|
|
27091
27690
|
return {
|
|
27092
27691
|
version: parsed.version || 1,
|
|
@@ -27102,9 +27701,9 @@ function loadSettings(memoryDir) {
|
|
|
27102
27701
|
}
|
|
27103
27702
|
}
|
|
27104
27703
|
function saveSettings(store, memoryDir) {
|
|
27105
|
-
|
|
27704
|
+
mkdirSync22(memoryDir, { recursive: true });
|
|
27106
27705
|
const filePath = getSettingsFilePath(memoryDir);
|
|
27107
|
-
|
|
27706
|
+
writeFileSync20(filePath, JSON.stringify(store, null, 2), "utf8");
|
|
27108
27707
|
}
|
|
27109
27708
|
function getSettings(memoryDir) {
|
|
27110
27709
|
return loadSettings(memoryDir).global;
|
|
@@ -27211,88 +27810,592 @@ var init_settings2 = __esm(() => {
|
|
|
27211
27810
|
init_settings();
|
|
27212
27811
|
});
|
|
27213
27812
|
|
|
27214
|
-
// src/
|
|
27215
|
-
|
|
27216
|
-
|
|
27217
|
-
|
|
27218
|
-
|
|
27219
|
-
|
|
27220
|
-
|
|
27221
|
-
|
|
27222
|
-
|
|
27223
|
-
|
|
27224
|
-
|
|
27225
|
-
|
|
27226
|
-
|
|
27227
|
-
|
|
27228
|
-
|
|
27229
|
-
|
|
27230
|
-
|
|
27231
|
-
|
|
27232
|
-
|
|
27233
|
-
|
|
27234
|
-
|
|
27235
|
-
|
|
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
|
+
}
|
|
27236
27838
|
}
|
|
27839
|
+
return Array.from(promptMap.values());
|
|
27237
27840
|
}
|
|
27238
|
-
function
|
|
27239
|
-
const
|
|
27240
|
-
|
|
27241
|
-
|
|
27242
|
-
|
|
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;
|
|
27243
27854
|
}
|
|
27244
|
-
function
|
|
27245
|
-
|
|
27246
|
-
|
|
27247
|
-
|
|
27248
|
-
|
|
27249
|
-
|
|
27250
|
-
|
|
27251
|
-
|
|
27252
|
-
|
|
27253
|
-
|
|
27254
|
-
|
|
27255
|
-
|
|
27256
|
-
|
|
27257
|
-
|
|
27258
|
-
|
|
27259
|
-
|
|
27260
|
-
|
|
27261
|
-
|
|
27262
|
-
|
|
27263
|
-
|
|
27264
|
-
|
|
27265
|
-
|
|
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
|
|
27266
27892
|
};
|
|
27267
27893
|
}
|
|
27268
27894
|
}
|
|
27269
|
-
|
|
27270
|
-
|
|
27271
|
-
|
|
27272
|
-
|
|
27273
|
-
|
|
27895
|
+
return {
|
|
27896
|
+
name,
|
|
27897
|
+
title: name,
|
|
27898
|
+
description: "",
|
|
27899
|
+
template: content.trim()
|
|
27900
|
+
};
|
|
27274
27901
|
}
|
|
27275
|
-
function
|
|
27276
|
-
const
|
|
27277
|
-
|
|
27278
|
-
|
|
27279
|
-
|
|
27280
|
-
|
|
27281
|
-
|
|
27282
|
-
|
|
27283
|
-
|
|
27284
|
-
|
|
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;
|
|
27285
27930
|
}
|
|
27286
|
-
var
|
|
27287
|
-
|
|
27288
|
-
|
|
27289
|
-
|
|
27290
|
-
|
|
27291
|
-
|
|
27292
|
-
|
|
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
|
+
];
|
|
27293
28000
|
});
|
|
27294
|
-
|
|
27295
|
-
|
|
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
|
+
|
|
28317
|
+
// src/plasticity.ts
|
|
28318
|
+
var exports_plasticity = {};
|
|
28319
|
+
__export(exports_plasticity, {
|
|
28320
|
+
getAssociatedMemories: () => getAssociatedMemories,
|
|
28321
|
+
getHebbianAssociationWeight: () => getHebbianAssociationWeight,
|
|
28322
|
+
loadHebbianGraph: () => loadHebbianGraph,
|
|
28323
|
+
recordCoActivation: () => recordCoActivation,
|
|
28324
|
+
saveHebbianGraph: () => saveHebbianGraph
|
|
28325
|
+
});
|
|
28326
|
+
import { existsSync as existsSync38, readFileSync as readFileSync32, writeFileSync as writeFileSync24 } from "node:fs";
|
|
28327
|
+
import { join as join35 } from "node:path";
|
|
28328
|
+
function getPlasticityPath(memoryDir) {
|
|
28329
|
+
return join35(memoryDir, "hebbian-plasticity.json");
|
|
28330
|
+
}
|
|
28331
|
+
function loadHebbianGraph(memoryDir) {
|
|
28332
|
+
const p = getPlasticityPath(memoryDir);
|
|
28333
|
+
if (!existsSync38(p))
|
|
28334
|
+
return {};
|
|
28335
|
+
try {
|
|
28336
|
+
return JSON.parse(readFileSync32(p, "utf8"));
|
|
28337
|
+
} catch {
|
|
28338
|
+
return {};
|
|
28339
|
+
}
|
|
28340
|
+
}
|
|
28341
|
+
function saveHebbianGraph(memoryDir, graph) {
|
|
28342
|
+
const p = getPlasticityPath(memoryDir);
|
|
28343
|
+
try {
|
|
28344
|
+
writeFileSync24(p, JSON.stringify(graph, null, 2), "utf8");
|
|
28345
|
+
} catch {}
|
|
28346
|
+
}
|
|
28347
|
+
function recordCoActivation(memoryIds, memoryDir) {
|
|
28348
|
+
const ids = Array.from(new Set(memoryIds.filter(Boolean)));
|
|
28349
|
+
if (ids.length < 2)
|
|
28350
|
+
return;
|
|
28351
|
+
const graph = loadHebbianGraph(memoryDir);
|
|
28352
|
+
const now = new Date().toISOString();
|
|
28353
|
+
for (let i = 0;i < ids.length; i++) {
|
|
28354
|
+
const src = ids[i];
|
|
28355
|
+
if (!graph[src])
|
|
28356
|
+
graph[src] = {};
|
|
28357
|
+
for (let j = 0;j < ids.length; j++) {
|
|
28358
|
+
if (i === j)
|
|
28359
|
+
continue;
|
|
28360
|
+
const tgt = ids[j];
|
|
28361
|
+
const existing = graph[src][tgt];
|
|
28362
|
+
const prevWeight = existing ? existing.weight : 0;
|
|
28363
|
+
const prevCount = existing ? existing.count : 0;
|
|
28364
|
+
const newWeight = Math.min(1, Math.round((prevWeight + 0.05) * 1000) / 1000);
|
|
28365
|
+
graph[src][tgt] = {
|
|
28366
|
+
weight: newWeight,
|
|
28367
|
+
count: prevCount + 1,
|
|
28368
|
+
lastActivated: now
|
|
28369
|
+
};
|
|
28370
|
+
}
|
|
28371
|
+
}
|
|
28372
|
+
saveHebbianGraph(memoryDir, graph);
|
|
28373
|
+
}
|
|
28374
|
+
function getHebbianAssociationWeight(sourceId, targetId, memoryDir) {
|
|
28375
|
+
const graph = loadHebbianGraph(memoryDir);
|
|
28376
|
+
return graph[sourceId]?.[targetId]?.weight ?? 0;
|
|
28377
|
+
}
|
|
28378
|
+
function getAssociatedMemories(sourceId, memoryDir) {
|
|
28379
|
+
const graph = loadHebbianGraph(memoryDir);
|
|
28380
|
+
const targets = graph[sourceId];
|
|
28381
|
+
if (!targets)
|
|
28382
|
+
return [];
|
|
28383
|
+
return Object.entries(targets).map(([targetId, edge]) => ({
|
|
28384
|
+
targetId,
|
|
28385
|
+
weight: edge.weight,
|
|
28386
|
+
count: edge.count
|
|
28387
|
+
})).sort((a, b) => b.weight - a.weight);
|
|
28388
|
+
}
|
|
28389
|
+
var init_plasticity = () => {};
|
|
28390
|
+
|
|
28391
|
+
// src/compress.ts
|
|
28392
|
+
var exports_compress = {};
|
|
28393
|
+
__export(exports_compress, {
|
|
28394
|
+
compressPromptContext: () => compressPromptContext,
|
|
28395
|
+
estimateTokens: () => estimateTokens
|
|
28396
|
+
});
|
|
28397
|
+
function estimateTokens(text) {
|
|
28398
|
+
if (!text || text.trim().length === 0)
|
|
27296
28399
|
return 0;
|
|
27297
28400
|
return Math.max(1, Math.ceil(text.length / 4));
|
|
27298
28401
|
}
|
|
@@ -27329,8 +28432,8 @@ __export(exports_drift, {
|
|
|
27329
28432
|
scanCodeDriftFromDiff: () => scanCodeDriftFromDiff
|
|
27330
28433
|
});
|
|
27331
28434
|
import { execSync as execSync3 } from "node:child_process";
|
|
27332
|
-
import { existsSync as
|
|
27333
|
-
import { join as
|
|
28435
|
+
import { existsSync as existsSync39 } from "node:fs";
|
|
28436
|
+
import { join as join36, isAbsolute as isAbsolute2 } from "node:path";
|
|
27334
28437
|
function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
|
|
27335
28438
|
const root = workspaceRoot || process.cwd();
|
|
27336
28439
|
const normalizedChanged = new Set(changedFiles.map((f) => f.trim().replace(/^[\.\/]+/, "")).filter(Boolean));
|
|
@@ -27344,8 +28447,8 @@ function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
|
|
|
27344
28447
|
const norm = p.trim().replace(/^[\.\/]+/, "");
|
|
27345
28448
|
const matched = Array.from(normalizedChanged).find((cf) => cf === norm || cf.endsWith(`/${norm}`) || norm.endsWith(`/${cf}`));
|
|
27346
28449
|
if (matched) {
|
|
27347
|
-
const fullPath = isAbsolute2(p) ? p :
|
|
27348
|
-
const exists =
|
|
28450
|
+
const fullPath = isAbsolute2(p) ? p : join36(root, p);
|
|
28451
|
+
const exists = existsSync39(fullPath);
|
|
27349
28452
|
drifted.push({
|
|
27350
28453
|
memoryId: entry.id,
|
|
27351
28454
|
title: entry.title,
|
|
@@ -27419,12 +28522,13 @@ var init_drift = __esm(() => {
|
|
|
27419
28522
|
// src/mcp.ts
|
|
27420
28523
|
var exports_mcp = {};
|
|
27421
28524
|
__export(exports_mcp, {
|
|
28525
|
+
createServer: () => createServer2,
|
|
27422
28526
|
runMcpServer: () => runMcpServer
|
|
27423
28527
|
});
|
|
27424
28528
|
import { basename } from "node:path";
|
|
27425
|
-
|
|
27426
|
-
const
|
|
27427
|
-
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);
|
|
27428
28532
|
const store = openStore(memoryDir);
|
|
27429
28533
|
function resolveStoreForRequest(a) {
|
|
27430
28534
|
const dir = a?.dir || a?.workspace || a?.project_dir || a?.cwd;
|
|
@@ -27472,7 +28576,8 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
27472
28576
|
type: { type: "string" },
|
|
27473
28577
|
status: { type: "string" },
|
|
27474
28578
|
verified: { type: "boolean" },
|
|
27475
|
-
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)" }
|
|
27476
28581
|
}
|
|
27477
28582
|
}
|
|
27478
28583
|
},
|
|
@@ -28048,6 +29153,173 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
28048
29153
|
},
|
|
28049
29154
|
required: ["text"]
|
|
28050
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>/",
|
|
29218
|
+
inputSchema: {
|
|
29219
|
+
type: "object",
|
|
29220
|
+
properties: {
|
|
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"]
|
|
29226
|
+
}
|
|
29227
|
+
},
|
|
29228
|
+
{
|
|
29229
|
+
name: "memory_freeze_list",
|
|
29230
|
+
description: "List recorded frozen execution snapshots in .memory/runs/",
|
|
29231
|
+
inputSchema: {
|
|
29232
|
+
type: "object",
|
|
29233
|
+
properties: {
|
|
29234
|
+
dir: { type: "string", description: "Optional project workspace directory path" }
|
|
29235
|
+
}
|
|
29236
|
+
}
|
|
29237
|
+
},
|
|
29238
|
+
{
|
|
29239
|
+
name: "memory_prompt_list",
|
|
29240
|
+
description: "List available structured prompt templates in .memory/prompts/",
|
|
29241
|
+
inputSchema: {
|
|
29242
|
+
type: "object",
|
|
29243
|
+
properties: {
|
|
29244
|
+
dir: { type: "string", description: "Optional project workspace directory path" }
|
|
29245
|
+
}
|
|
29246
|
+
}
|
|
29247
|
+
},
|
|
29248
|
+
{
|
|
29249
|
+
name: "memory_prompt_get",
|
|
29250
|
+
description: "Get prompt template by name",
|
|
29251
|
+
inputSchema: {
|
|
29252
|
+
type: "object",
|
|
29253
|
+
properties: {
|
|
29254
|
+
name: { type: "string" },
|
|
29255
|
+
dir: { type: "string", description: "Optional project workspace directory path" }
|
|
29256
|
+
},
|
|
29257
|
+
required: ["name"]
|
|
29258
|
+
}
|
|
29259
|
+
},
|
|
29260
|
+
{
|
|
29261
|
+
name: "memory_prompt_run",
|
|
29262
|
+
description: "Render prompt template with variable substitution and live memory context injection",
|
|
29263
|
+
inputSchema: {
|
|
29264
|
+
type: "object",
|
|
29265
|
+
properties: {
|
|
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"]
|
|
29271
|
+
}
|
|
29272
|
+
},
|
|
29273
|
+
{
|
|
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",
|
|
29276
|
+
inputSchema: {
|
|
29277
|
+
type: "object",
|
|
29278
|
+
properties: {
|
|
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"]
|
|
29285
|
+
}
|
|
29286
|
+
},
|
|
29287
|
+
{
|
|
29288
|
+
name: "memory_loop_record",
|
|
29289
|
+
description: "Record an iteration round in the multi-agent Gauntlet Iteration Ledger (.memory/iterations.jsonl)",
|
|
29290
|
+
inputSchema: {
|
|
29291
|
+
type: "object",
|
|
29292
|
+
properties: {
|
|
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" }
|
|
29299
|
+
},
|
|
29300
|
+
required: ["iteration_index", "critic_verdict", "largest_fix_identified", "test_results"]
|
|
29301
|
+
}
|
|
29302
|
+
},
|
|
29303
|
+
{
|
|
29304
|
+
name: "memory_loop_status",
|
|
29305
|
+
description: "Inspect multi-round iteration status, plateau warnings, and regression signals",
|
|
29306
|
+
inputSchema: {
|
|
29307
|
+
type: "object",
|
|
29308
|
+
properties: {
|
|
29309
|
+
dir: { type: "string", description: "Optional project workspace directory path" }
|
|
29310
|
+
}
|
|
29311
|
+
}
|
|
29312
|
+
},
|
|
29313
|
+
{
|
|
29314
|
+
name: "memory_verify_strict",
|
|
29315
|
+
description: "Execute Strict Integrity & Health Gate: audits zero secrets, referential link integrity, wikilinks, orphaned candidates, and claim sources",
|
|
29316
|
+
inputSchema: {
|
|
29317
|
+
type: "object",
|
|
29318
|
+
properties: {
|
|
29319
|
+
max_candidate_days: { type: "number" },
|
|
29320
|
+
dir: { type: "string", description: "Optional project workspace directory path" }
|
|
29321
|
+
}
|
|
29322
|
+
}
|
|
28051
29323
|
}
|
|
28052
29324
|
]
|
|
28053
29325
|
}));
|
|
@@ -28075,7 +29347,17 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
28075
29347
|
});
|
|
28076
29348
|
} catch {}
|
|
28077
29349
|
}
|
|
28078
|
-
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, {
|
|
28079
29361
|
limit: typeof a.limit === "number" ? a.limit : 5,
|
|
28080
29362
|
tokenBudget: typeof a.token_budget === "number" ? a.token_budget : undefined,
|
|
28081
29363
|
project: a.project ? String(a.project) : undefined,
|
|
@@ -28558,6 +29840,99 @@ Path: ${item.path}`,
|
|
|
28558
29840
|
const result = compressPromptContext2(text, { level });
|
|
28559
29841
|
return toolResult(result);
|
|
28560
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
|
+
}
|
|
28561
29936
|
default:
|
|
28562
29937
|
return toolError(`unknown tool ${name}`);
|
|
28563
29938
|
}
|
|
@@ -28565,6 +29940,10 @@ Path: ${item.path}`,
|
|
|
28565
29940
|
return toolError(err instanceof Error ? err.message : String(err));
|
|
28566
29941
|
}
|
|
28567
29942
|
});
|
|
29943
|
+
return server;
|
|
29944
|
+
}
|
|
29945
|
+
async function runMcpServer() {
|
|
29946
|
+
const server = createServer2();
|
|
28568
29947
|
const transport = new StdioServerTransport;
|
|
28569
29948
|
await server.connect(transport);
|
|
28570
29949
|
process.stdin.resume();
|
|
@@ -28614,6 +29993,14 @@ var init_mcp = __esm(() => {
|
|
|
28614
29993
|
init_entities();
|
|
28615
29994
|
init_pageindex();
|
|
28616
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();
|
|
28617
30004
|
});
|
|
28618
30005
|
|
|
28619
30006
|
// src/daemon.ts
|
|
@@ -28621,15 +30008,15 @@ var exports_daemon = {};
|
|
|
28621
30008
|
__export(exports_daemon, {
|
|
28622
30009
|
startHub: () => startHub
|
|
28623
30010
|
});
|
|
28624
|
-
import { createServer as
|
|
28625
|
-
import { existsSync as
|
|
28626
|
-
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";
|
|
28627
30014
|
import { watch } from "node:fs";
|
|
28628
30015
|
function startHub(port, memoryDir) {
|
|
28629
30016
|
const clients = new Set;
|
|
28630
30017
|
const watchers = [];
|
|
28631
30018
|
let debounceTimer = null;
|
|
28632
|
-
const server =
|
|
30019
|
+
const server = createServer3((req, res) => {
|
|
28633
30020
|
if (req.method === "GET" && req.url?.startsWith("/events")) {
|
|
28634
30021
|
res.writeHead(200, {
|
|
28635
30022
|
"content-type": "text/event-stream",
|
|
@@ -28689,7 +30076,7 @@ data: ${JSON.stringify(event)}
|
|
|
28689
30076
|
return clients.size;
|
|
28690
30077
|
}
|
|
28691
30078
|
if (memoryDir) {
|
|
28692
|
-
const memoriesDir =
|
|
30079
|
+
const memoriesDir = join37(memoryDir, "memories");
|
|
28693
30080
|
const armDebounced = (type2) => {
|
|
28694
30081
|
if (debounceTimer)
|
|
28695
30082
|
clearTimeout(debounceTimer);
|
|
@@ -28698,17 +30085,17 @@ data: ${JSON.stringify(event)}
|
|
|
28698
30085
|
}, DEBOUNCE_MS);
|
|
28699
30086
|
};
|
|
28700
30087
|
try {
|
|
28701
|
-
if (
|
|
30088
|
+
if (existsSync40(memoriesDir)) {
|
|
28702
30089
|
watchers.push(watch(memoriesDir, () => armDebounced("memory.changed")));
|
|
28703
30090
|
}
|
|
28704
|
-
const currentMd =
|
|
28705
|
-
if (
|
|
30091
|
+
const currentMd = join37(memoryDir, "CURRENT.md");
|
|
30092
|
+
if (existsSync40(currentMd)) {
|
|
28706
30093
|
watchers.push(watch(currentMd, () => armDebounced("constraints.changed")));
|
|
28707
30094
|
}
|
|
28708
30095
|
} catch {}
|
|
28709
30096
|
}
|
|
28710
30097
|
return new Promise((resolve3) => {
|
|
28711
|
-
server.listen(port, () => {
|
|
30098
|
+
server.listen(port, "127.0.0.1", () => {
|
|
28712
30099
|
const address = server.address();
|
|
28713
30100
|
const actualPort = typeof address === "object" && address ? address.port : port;
|
|
28714
30101
|
resolve3({
|
|
@@ -28735,19 +30122,19 @@ var DEBOUNCE_MS = 300;
|
|
|
28735
30122
|
var init_daemon = () => {};
|
|
28736
30123
|
|
|
28737
30124
|
// src/cli/ecosystem.ts
|
|
28738
|
-
import { join as
|
|
28739
|
-
import { existsSync 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";
|
|
28740
30127
|
import { homedir as homedir7 } from "node:os";
|
|
28741
30128
|
function ensureProjectAgentInstructions(targetDir) {
|
|
28742
|
-
const agentsMdPath =
|
|
28743
|
-
if (
|
|
30129
|
+
const agentsMdPath = join38(targetDir, "AGENTS.md");
|
|
30130
|
+
if (existsSync41(agentsMdPath)) {
|
|
28744
30131
|
try {
|
|
28745
|
-
const existing =
|
|
30132
|
+
const existing = readFileSync33(agentsMdPath, "utf8");
|
|
28746
30133
|
if (existing.includes("<!-- agentmemory:start -->")) {
|
|
28747
30134
|
const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
|
|
28748
|
-
|
|
30135
|
+
writeFileSync25(agentsMdPath, updated, "utf8");
|
|
28749
30136
|
} else if (!existing.includes("<!-- musememory:start -->") && !existing.includes("Muse Memory")) {
|
|
28750
|
-
|
|
30137
|
+
writeFileSync25(agentsMdPath, `${existing.trim()}
|
|
28751
30138
|
|
|
28752
30139
|
${MUSE_MEMORY_DIRECTIVE}
|
|
28753
30140
|
`, "utf8");
|
|
@@ -28758,23 +30145,23 @@ ${MUSE_MEMORY_DIRECTIVE}
|
|
|
28758
30145
|
|
|
28759
30146
|
${MUSE_MEMORY_DIRECTIVE}
|
|
28760
30147
|
`;
|
|
28761
|
-
|
|
30148
|
+
writeFileSync25(agentsMdPath, initialContent, "utf8");
|
|
28762
30149
|
}
|
|
28763
30150
|
}
|
|
28764
30151
|
async function handleInstallCommand({ positional, flags }) {
|
|
28765
30152
|
const isGlobal = flags["global"] === "true" || flags["g"] === "true";
|
|
28766
|
-
const targetDir = positional[0] ?
|
|
28767
|
-
const memoryDir = isGlobal ? getGlobalMemoryDir() :
|
|
30153
|
+
const targetDir = positional[0] ? join38(process.cwd(), positional[0]) : process.cwd();
|
|
30154
|
+
const memoryDir = isGlobal ? getGlobalMemoryDir() : join38(targetDir, ".memory");
|
|
28768
30155
|
const globalDir = getGlobalMemoryDir();
|
|
28769
|
-
|
|
28770
|
-
|
|
28771
|
-
const currentPath =
|
|
28772
|
-
if (!
|
|
28773
|
-
|
|
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
|
|
28774
30161
|
`, "utf8");
|
|
28775
30162
|
}
|
|
28776
30163
|
const globalUserPath = userFilePath(globalDir);
|
|
28777
|
-
if (!
|
|
30164
|
+
if (!existsSync41(globalUserPath)) {
|
|
28778
30165
|
const { promptSingleSelect: promptSingleSelect2 } = await Promise.resolve().then(() => (init_prompt(), exports_prompt));
|
|
28779
30166
|
const archetypeOptions = [
|
|
28780
30167
|
{ id: "developer", label: "Software Engineer / Developer", hint: "Code-first, direct, strict typing" },
|
|
@@ -28790,13 +30177,13 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
28790
30177
|
if (!isGlobal) {
|
|
28791
30178
|
ensureProjectAgentInstructions(targetDir);
|
|
28792
30179
|
}
|
|
28793
|
-
const globalAgentsMd =
|
|
28794
|
-
if (
|
|
30180
|
+
const globalAgentsMd = join38(homedir7(), ".agents", "AGENTS.md");
|
|
30181
|
+
if (existsSync41(globalAgentsMd)) {
|
|
28795
30182
|
try {
|
|
28796
|
-
const existing =
|
|
30183
|
+
const existing = readFileSync33(globalAgentsMd, "utf8");
|
|
28797
30184
|
if (existing.includes("<!-- agentmemory:start -->")) {
|
|
28798
30185
|
const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
|
|
28799
|
-
|
|
30186
|
+
writeFileSync25(globalAgentsMd, updated, "utf8");
|
|
28800
30187
|
}
|
|
28801
30188
|
} catch {}
|
|
28802
30189
|
}
|
|
@@ -28857,11 +30244,11 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
28857
30244
|
return 0;
|
|
28858
30245
|
}
|
|
28859
30246
|
async function promptOrNotifyGitHook(targetDir, autoInstall = false) {
|
|
28860
|
-
const gitDir =
|
|
28861
|
-
if (!
|
|
30247
|
+
const gitDir = join38(targetDir, ".git");
|
|
30248
|
+
if (!existsSync41(gitDir))
|
|
28862
30249
|
return false;
|
|
28863
|
-
const hookPath =
|
|
28864
|
-
const isInstalled =
|
|
30250
|
+
const hookPath = join38(gitDir, "hooks", "pre-commit");
|
|
30251
|
+
const isInstalled = existsSync41(hookPath) && readFileSync33(hookPath, "utf8").includes("memory harvest-auto");
|
|
28865
30252
|
if (isInstalled)
|
|
28866
30253
|
return true;
|
|
28867
30254
|
if (autoInstall) {
|
|
@@ -28917,7 +30304,7 @@ async function handleUninstallCommand({ positional, flags }) {
|
|
|
28917
30304
|
action: async () => {
|
|
28918
30305
|
if (purge) {
|
|
28919
30306
|
const ctx = requireRoot(flags);
|
|
28920
|
-
if (ctx &&
|
|
30307
|
+
if (ctx && existsSync41(ctx.memoryDir) && !dryRun) {
|
|
28921
30308
|
const { rmSync: rmSync3 } = await import("node:fs");
|
|
28922
30309
|
rmSync3(ctx.memoryDir, { recursive: true, force: true });
|
|
28923
30310
|
}
|
|
@@ -28949,13 +30336,13 @@ async function handleUninstallCommand({ positional, flags }) {
|
|
|
28949
30336
|
}
|
|
28950
30337
|
async function handleInitCommand({ positional, flags }) {
|
|
28951
30338
|
const isGlobal = flags["global"] === "true";
|
|
28952
|
-
const targetDir = positional[0] ?
|
|
30339
|
+
const targetDir = positional[0] ? join38(process.cwd(), positional[0]) : process.cwd();
|
|
28953
30340
|
const memoryDirName = flags["legacy"] === "true" ? ".musememory" : ".memory";
|
|
28954
|
-
const memoryDir = isGlobal ? getGlobalMemoryDir() :
|
|
28955
|
-
|
|
28956
|
-
const currentPath =
|
|
28957
|
-
if (!
|
|
28958
|
-
|
|
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
|
|
28959
30346
|
`, "utf8");
|
|
28960
30347
|
}
|
|
28961
30348
|
if (!isGlobal) {
|
|
@@ -29246,8 +30633,8 @@ var init_ecosystem = __esm(() => {
|
|
|
29246
30633
|
});
|
|
29247
30634
|
|
|
29248
30635
|
// src/agentcontract.ts
|
|
29249
|
-
import { existsSync as
|
|
29250
|
-
import { join as
|
|
30636
|
+
import { existsSync as existsSync42 } from "node:fs";
|
|
30637
|
+
import { join as join39 } from "node:path";
|
|
29251
30638
|
function parseAgentMemoryContract(markdown) {
|
|
29252
30639
|
if (!markdown || !markdown.startsWith("---"))
|
|
29253
30640
|
return null;
|
|
@@ -29279,17 +30666,17 @@ function parseAgentMemoryContract(markdown) {
|
|
|
29279
30666
|
function resolveAgentFile(nameOrPath, workspaceRoot) {
|
|
29280
30667
|
if (!nameOrPath)
|
|
29281
30668
|
return null;
|
|
29282
|
-
if (
|
|
30669
|
+
if (existsSync42(nameOrPath))
|
|
29283
30670
|
return nameOrPath;
|
|
29284
30671
|
const candidates = [
|
|
29285
|
-
|
|
29286
|
-
|
|
30672
|
+
join39(workspaceRoot, ".agents", `${nameOrPath}.md`),
|
|
30673
|
+
join39(workspaceRoot, ".memory", "agents", `${nameOrPath}.md`)
|
|
29287
30674
|
];
|
|
29288
30675
|
const home = process.env.HOME;
|
|
29289
30676
|
if (home)
|
|
29290
|
-
candidates.push(
|
|
30677
|
+
candidates.push(join39(home, ".config", "opencode", "agents", `${nameOrPath}.md`));
|
|
29291
30678
|
for (const c of candidates) {
|
|
29292
|
-
if (
|
|
30679
|
+
if (existsSync42(c))
|
|
29293
30680
|
return c;
|
|
29294
30681
|
}
|
|
29295
30682
|
return null;
|
|
@@ -29299,8 +30686,8 @@ var init_agentcontract = __esm(() => {
|
|
|
29299
30686
|
});
|
|
29300
30687
|
|
|
29301
30688
|
// src/cli/retrieval.ts
|
|
29302
|
-
import { existsSync as
|
|
29303
|
-
import { join as
|
|
30689
|
+
import { existsSync as existsSync43, readFileSync as readFileSync34 } from "node:fs";
|
|
30690
|
+
import { join as join40 } from "node:path";
|
|
29304
30691
|
async function handleContextCommand({ positional, flags }) {
|
|
29305
30692
|
let agentTypes;
|
|
29306
30693
|
let agentTags;
|
|
@@ -29308,7 +30695,7 @@ async function handleContextCommand({ positional, flags }) {
|
|
|
29308
30695
|
const file = resolveAgentFile(flags["for-agent"], flags["dir"] ?? process.cwd());
|
|
29309
30696
|
if (!file)
|
|
29310
30697
|
return usageError(`--for-agent: cannot resolve agent '${flags["for-agent"]}'`);
|
|
29311
|
-
const contract = parseAgentMemoryContract(
|
|
30698
|
+
const contract = parseAgentMemoryContract(readFileSync34(file, "utf8"));
|
|
29312
30699
|
if (contract) {
|
|
29313
30700
|
agentTypes = contract.types;
|
|
29314
30701
|
agentTags = contract.tags;
|
|
@@ -29326,6 +30713,26 @@ async function handleContextCommand({ positional, flags }) {
|
|
|
29326
30713
|
if (depth && depth !== "L1" && depth !== "L2" && depth !== "L3") {
|
|
29327
30714
|
return usageError("--depth must be one of L1|L2|L3");
|
|
29328
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
|
+
}
|
|
29329
30736
|
if (depth) {
|
|
29330
30737
|
const formatted = formatPromptContext(ctx.store, ctx.memoryDir, query, {
|
|
29331
30738
|
limit,
|
|
@@ -29448,7 +30855,7 @@ async function handleHarvestCommand({ positional, flags }) {
|
|
|
29448
30855
|
const project = flags["project"];
|
|
29449
30856
|
if (!project)
|
|
29450
30857
|
return usageError("harvest requires --project");
|
|
29451
|
-
const rawText =
|
|
30858
|
+
const rawText = existsSync43(target) ? readFileSync34(target, "utf8") : target;
|
|
29452
30859
|
const created = harvestMemories(ctx.store, {
|
|
29453
30860
|
text: rawText,
|
|
29454
30861
|
project,
|
|
@@ -29484,8 +30891,8 @@ async function handleSearchTranscriptCommand({ positional, flags }) {
|
|
|
29484
30891
|
const filePath = positional[1];
|
|
29485
30892
|
if (!query)
|
|
29486
30893
|
return usageError("search-transcript requires <query> [file.jsonl]");
|
|
29487
|
-
const targetFile = filePath ? filePath.startsWith("/") ? filePath :
|
|
29488
|
-
if (!
|
|
30894
|
+
const targetFile = filePath ? filePath.startsWith("/") ? filePath : join40(process.cwd(), filePath) : join40(process.cwd(), "transcript.jsonl");
|
|
30895
|
+
if (!existsSync43(targetFile)) {
|
|
29489
30896
|
return fail(`error: transcript file not found: ${targetFile}`);
|
|
29490
30897
|
}
|
|
29491
30898
|
const windowSize = flags["window"] ? parseInt(flags["window"], 10) : 2;
|
|
@@ -29501,7 +30908,7 @@ async function handleReindexCommand({ flags }) {
|
|
|
29501
30908
|
const { rebuildIndex: rebuildIndex2, saveIndex: saveIndex2 } = await Promise.resolve().then(() => (init_vector(), exports_vector));
|
|
29502
30909
|
const index = rebuildIndex2(ctx.store);
|
|
29503
30910
|
saveIndex2(index, ctx.memoryDir);
|
|
29504
|
-
console.log(`indexed ${Object.keys(index.entries).length} entries -> ${
|
|
30911
|
+
console.log(`indexed ${Object.keys(index.entries).length} entries -> ${join40(ctx.memoryDir, "index.json")}`);
|
|
29505
30912
|
return 0;
|
|
29506
30913
|
}
|
|
29507
30914
|
async function handleHookCommand({ positional, flags }) {
|
|
@@ -29535,6 +30942,7 @@ async function handleHarvestAutoCommand({ flags }) {
|
|
|
29535
30942
|
}
|
|
29536
30943
|
var init_retrieval3 = __esm(() => {
|
|
29537
30944
|
init_retrieval();
|
|
30945
|
+
init_tiered();
|
|
29538
30946
|
init_vector();
|
|
29539
30947
|
init_retrieval2();
|
|
29540
30948
|
init_harvest();
|
|
@@ -29892,7 +31300,7 @@ var init_entities2 = __esm(() => {
|
|
|
29892
31300
|
});
|
|
29893
31301
|
|
|
29894
31302
|
// src/cli/settings.ts
|
|
29895
|
-
import { writeFileSync as
|
|
31303
|
+
import { writeFileSync as writeFileSync26, readFileSync as readFileSync35 } from "node:fs";
|
|
29896
31304
|
function handleSettingsCommand(parsed) {
|
|
29897
31305
|
const ctx = requireRoot(parsed.flags);
|
|
29898
31306
|
if (!ctx)
|
|
@@ -29974,7 +31382,7 @@ function handleSettingsCommand(parsed) {
|
|
|
29974
31382
|
const out = parsed.flags.out;
|
|
29975
31383
|
const json2 = exportSettings(memoryDir);
|
|
29976
31384
|
if (out) {
|
|
29977
|
-
|
|
31385
|
+
writeFileSync26(out, json2, "utf8");
|
|
29978
31386
|
console.log(`Exported settings to ${out}`);
|
|
29979
31387
|
} else {
|
|
29980
31388
|
console.log(json2);
|
|
@@ -29988,7 +31396,7 @@ function handleSettingsCommand(parsed) {
|
|
|
29988
31396
|
return 2;
|
|
29989
31397
|
}
|
|
29990
31398
|
try {
|
|
29991
|
-
const raw =
|
|
31399
|
+
const raw = readFileSync35(file, "utf8");
|
|
29992
31400
|
importSettings(memoryDir, raw);
|
|
29993
31401
|
console.log(`Successfully imported settings from ${file}`);
|
|
29994
31402
|
return 0;
|
|
@@ -30011,16 +31419,16 @@ var init_nudge = __esm(() => {
|
|
|
30011
31419
|
});
|
|
30012
31420
|
|
|
30013
31421
|
// src/routines.ts
|
|
30014
|
-
import { readFileSync as
|
|
30015
|
-
import { join as
|
|
31422
|
+
import { readFileSync as readFileSync36, existsSync as existsSync44 } from "node:fs";
|
|
31423
|
+
import { join as join41 } from "node:path";
|
|
30016
31424
|
function routinesPath(memoryDir) {
|
|
30017
|
-
return
|
|
31425
|
+
return join41(memoryDir, "routines.yaml");
|
|
30018
31426
|
}
|
|
30019
31427
|
function loadRoutines(memoryDir) {
|
|
30020
31428
|
const p = routinesPath(memoryDir);
|
|
30021
|
-
if (!
|
|
31429
|
+
if (!existsSync44(p))
|
|
30022
31430
|
return { routines: {} };
|
|
30023
|
-
const doc2 = yaml.load(
|
|
31431
|
+
const doc2 = yaml.load(readFileSync36(p, "utf8"), { schema: yaml.JSON_SCHEMA }) ?? {};
|
|
30024
31432
|
const routines = doc2.routines ?? {};
|
|
30025
31433
|
for (const [name, r] of Object.entries(routines)) {
|
|
30026
31434
|
if (!r || typeof r.schedule !== "string" || !r.schedule.trim()) {
|
|
@@ -30058,7 +31466,7 @@ var init_routines = __esm(() => {
|
|
|
30058
31466
|
});
|
|
30059
31467
|
|
|
30060
31468
|
// src/cli/lifecycle.ts
|
|
30061
|
-
import { writeFileSync as
|
|
31469
|
+
import { writeFileSync as writeFileSync27, readFileSync as readFileSync37, existsSync as existsSync45 } from "node:fs";
|
|
30062
31470
|
async function handleProposeCommand({ positional, flags }) {
|
|
30063
31471
|
const ctx = requireRoot(flags);
|
|
30064
31472
|
if (!ctx)
|
|
@@ -30207,7 +31615,7 @@ async function handleExportCommand({ flags }) {
|
|
|
30207
31615
|
const snapshot = exportSnapshot(ctx.store);
|
|
30208
31616
|
const outPath = flags["out"];
|
|
30209
31617
|
if (outPath) {
|
|
30210
|
-
|
|
31618
|
+
writeFileSync27(outPath, JSON.stringify(snapshot, null, 2), "utf8");
|
|
30211
31619
|
console.log(`exported ${snapshot.total} memories to ${outPath}`);
|
|
30212
31620
|
} else {
|
|
30213
31621
|
console.log(JSON.stringify(snapshot, null, 2));
|
|
@@ -30221,9 +31629,9 @@ async function handleImportCommand({ positional, flags }) {
|
|
|
30221
31629
|
const file = positional[0];
|
|
30222
31630
|
if (!file)
|
|
30223
31631
|
return usageError("import requires <file.json>");
|
|
30224
|
-
if (!
|
|
31632
|
+
if (!existsSync45(file))
|
|
30225
31633
|
return fail(`error: file ${file} does not exist`);
|
|
30226
|
-
const raw = JSON.parse(
|
|
31634
|
+
const raw = JSON.parse(readFileSync37(file, "utf8"));
|
|
30227
31635
|
const res = importSnapshot(ctx.store, raw, { overwrite: flags["overwrite"] === "true" });
|
|
30228
31636
|
if (res.errors.length > 0) {
|
|
30229
31637
|
console.error(`import encountered errors:`);
|
|
@@ -30513,9 +31921,31 @@ async function handleVerifyCommand({ positional, flags }) {
|
|
|
30513
31921
|
const ctx = requireRoot(flags);
|
|
30514
31922
|
if (!ctx)
|
|
30515
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
|
+
}
|
|
30516
31946
|
const id = positional[0];
|
|
30517
31947
|
if (!id)
|
|
30518
|
-
return usageError("verify requires <id>");
|
|
31948
|
+
return usageError("verify requires <id> or --strict");
|
|
30519
31949
|
const timeout = flags["timeout"] ? parseInt(flags["timeout"], 10) : undefined;
|
|
30520
31950
|
const result = await verifyEntry(ctx.store, ctx.root, ctx.memoryDir, id, { timeout });
|
|
30521
31951
|
if (result.stdout?.trim())
|
|
@@ -30568,6 +31998,275 @@ var init_lifecycle = __esm(() => {
|
|
|
30568
31998
|
init_shared();
|
|
30569
31999
|
});
|
|
30570
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
|
+
|
|
30571
32270
|
// src/cli.ts
|
|
30572
32271
|
var exports_cli = {};
|
|
30573
32272
|
__export(exports_cli, {
|
|
@@ -30706,6 +32405,22 @@ async function main(argv) {
|
|
|
30706
32405
|
return handleEntitiesCommand(parsed);
|
|
30707
32406
|
case "settings":
|
|
30708
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);
|
|
30709
32424
|
default:
|
|
30710
32425
|
console.error(`Error: unknown command "${cmd}"`);
|
|
30711
32426
|
return 2;
|
|
@@ -30741,11 +32456,19 @@ Core Memory Lifecycle Commands:
|
|
|
30741
32456
|
routine run <name> Execute a routine's steps from .memory/routines.yaml
|
|
30742
32457
|
routine install [name] Print crontab line(s) for routines (user installs; no system mutation)
|
|
30743
32458
|
distill [--min-count N] [--dry-run] Distill recurring fix patterns into .agents/skills/ folders
|
|
30744
|
-
verify <id> [--timeout S]
|
|
32459
|
+
verify <id> [--timeout S] [--strict] Execute test_command or run full strict integrity gate
|
|
30745
32460
|
briefing [--limit N] Executive summary of active and stale memories
|
|
30746
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
|
+
|
|
30747
32470
|
Context & Retrieval Commands:
|
|
30748
|
-
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
|
|
30749
32472
|
search <query> [--limit N] [--token-budget N] [--hybrid] [--tree] Scored token retrieval (hybrid: vector+BM25, tree: hierarchical reasoning)
|
|
30750
32473
|
reindex Rebuild the local vector index (.memory/index.json) for hybrid search
|
|
30751
32474
|
recall [query] Search active/confirmed memories with filters
|
|
@@ -30791,6 +32514,7 @@ var init_cli = __esm(() => {
|
|
|
30791
32514
|
init_entities2();
|
|
30792
32515
|
init_settings3();
|
|
30793
32516
|
init_lifecycle();
|
|
32517
|
+
init_evolution();
|
|
30794
32518
|
});
|
|
30795
32519
|
|
|
30796
32520
|
// bin/memory.ts
|