musememory 2.2.0 → 2.3.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/.agents/context/current.md +9 -2
- package/.agents/context/product.md +2 -1
- package/.agents/skills/muse-current/SKILL.md +47 -17
- package/README.md +30 -50
- package/dist/index.js +857 -215
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4594,6 +4594,18 @@ function formatPromptContext(store, memoryDir, query = "", options = {}) {
|
|
|
4594
4594
|
}
|
|
4595
4595
|
parts.push("");
|
|
4596
4596
|
}
|
|
4597
|
+
const currentData = memoryDir ? parseCurrentFile(memoryDir) : null;
|
|
4598
|
+
if (currentData?.workstreams && currentData.workstreams.length > 0) {
|
|
4599
|
+
const activeWs = currentData.workstreams.filter((w) => w.status === "IN-PROGRESS" || w.status === "BLOCKED");
|
|
4600
|
+
if (activeWs.length > 0) {
|
|
4601
|
+
parts.push("### Active Concurrent Agent Workstreams (CURRENT.md)");
|
|
4602
|
+
for (const w of activeWs) {
|
|
4603
|
+
const scope = w.targetScope ? ` | Target: \`${w.targetScope}\`` : "";
|
|
4604
|
+
parts.push(`- Agent \`${w.agent}\` [${w.status}]: ${w.task}${scope} (Active: ${w.lastActive})`);
|
|
4605
|
+
}
|
|
4606
|
+
parts.push("");
|
|
4607
|
+
}
|
|
4608
|
+
}
|
|
4597
4609
|
const handoff = memoryDir ? getSessionHandoff(memoryDir) : null;
|
|
4598
4610
|
if (handoff && (handoff.status === "IN-PROGRESS" || handoff.task || handoff.lastQuery)) {
|
|
4599
4611
|
parts.push("### Active In-Flight Context & Session Handoff (CURRENT.md)");
|
|
@@ -4891,38 +4903,83 @@ function currentFilePath(memoryDir) {
|
|
|
4891
4903
|
function parseCurrentFile(memoryDir) {
|
|
4892
4904
|
const p = currentFilePath(memoryDir);
|
|
4893
4905
|
if (!existsSync6(p))
|
|
4894
|
-
return { constraints: [], handoff: null };
|
|
4906
|
+
return { constraints: [], handoff: null, workstreams: [] };
|
|
4895
4907
|
const raw = readFileSync5(p, "utf8");
|
|
4896
4908
|
const lines = raw.split(`
|
|
4897
4909
|
`);
|
|
4898
4910
|
const constraints = [];
|
|
4911
|
+
const workstreams = [];
|
|
4899
4912
|
let inConstraintsSection = false;
|
|
4900
4913
|
let inHandoffSection = false;
|
|
4914
|
+
let inWorkstreamsSection = false;
|
|
4901
4915
|
const handoffLines = [];
|
|
4902
4916
|
for (const line of lines) {
|
|
4903
4917
|
const trimmed = line.trim();
|
|
4904
|
-
if (trimmed.startsWith("## Active Working Invariants") || trimmed.startsWith("## Active Constraints")) {
|
|
4918
|
+
if (trimmed.startsWith("## Active Working Invariants") || trimmed.startsWith("## Active Working Constraints") || trimmed.startsWith("## Active Constraints") || trimmed.startsWith("## \uD83D\uDD12 Active Working Invariants")) {
|
|
4905
4919
|
inConstraintsSection = true;
|
|
4906
4920
|
inHandoffSection = false;
|
|
4921
|
+
inWorkstreamsSection = false;
|
|
4922
|
+
continue;
|
|
4923
|
+
}
|
|
4924
|
+
if (trimmed.startsWith("## \uD83E\uDD16 Active Concurrent Agent Workstreams") || trimmed.startsWith("## Concurrent Agent Workstreams") || trimmed.startsWith("## Active Workstreams")) {
|
|
4925
|
+
inConstraintsSection = false;
|
|
4926
|
+
inHandoffSection = false;
|
|
4927
|
+
inWorkstreamsSection = true;
|
|
4907
4928
|
continue;
|
|
4908
4929
|
}
|
|
4909
|
-
if (trimmed.startsWith("## Active Work In Progress") || trimmed.startsWith("## In-Flight Session State") || trimmed.startsWith("## Session Handoff")) {
|
|
4930
|
+
if (trimmed.startsWith("## Active Work In Progress") || trimmed.startsWith("## In-Flight Session State") || trimmed.startsWith("## Session Handoff") || trimmed.startsWith("## ⚡ Active Work In Progress")) {
|
|
4910
4931
|
inConstraintsSection = false;
|
|
4911
4932
|
inHandoffSection = true;
|
|
4933
|
+
inWorkstreamsSection = false;
|
|
4912
4934
|
continue;
|
|
4913
4935
|
}
|
|
4914
|
-
if (trimmed.startsWith("# ")) {
|
|
4936
|
+
if (trimmed.startsWith("# ") || trimmed.startsWith("> ") || trimmed.startsWith("---")) {
|
|
4915
4937
|
continue;
|
|
4916
4938
|
}
|
|
4917
|
-
if (
|
|
4918
|
-
|
|
4939
|
+
if (inWorkstreamsSection) {
|
|
4940
|
+
if (trimmed.startsWith("##")) {
|
|
4941
|
+
inWorkstreamsSection = false;
|
|
4942
|
+
} else if (trimmed.startsWith("|")) {
|
|
4943
|
+
const cells = trimmed.split("|").map((c) => c.trim()).filter((_, idx, arr) => idx > 0 && idx < arr.length - 1);
|
|
4944
|
+
if (cells.length >= 3 && !cells[0].includes("---") && !cells[1].toLowerCase().includes("status")) {
|
|
4945
|
+
const agent = cells[0].replace(/[`*]/g, "").trim();
|
|
4946
|
+
const statusRaw = cells[1].replace(/[\[\]`*]/g, "").trim().toUpperCase();
|
|
4947
|
+
const status = statusRaw === "COMPLETED" || statusRaw === "BLOCKED" || statusRaw === "WAITING_REVIEW" ? statusRaw : "IN-PROGRESS";
|
|
4948
|
+
const task = cells[2].trim();
|
|
4949
|
+
const scope = cells[3] ? cells[3].replace(/[`*()]/g, "").trim() : undefined;
|
|
4950
|
+
const lastActive = cells[4] ? cells[4].trim() : new Date().toISOString();
|
|
4951
|
+
if (agent && task) {
|
|
4952
|
+
workstreams.push({
|
|
4953
|
+
agent,
|
|
4954
|
+
status,
|
|
4955
|
+
task,
|
|
4956
|
+
targetScope: scope && scope !== "all" ? scope : undefined,
|
|
4957
|
+
lastActive
|
|
4958
|
+
});
|
|
4959
|
+
}
|
|
4960
|
+
}
|
|
4961
|
+
}
|
|
4962
|
+
} else if (inHandoffSection) {
|
|
4963
|
+
if (trimmed.startsWith("##")) {
|
|
4964
|
+
inHandoffSection = false;
|
|
4965
|
+
} else {
|
|
4966
|
+
handoffLines.push(line);
|
|
4967
|
+
}
|
|
4919
4968
|
} else if (inConstraintsSection) {
|
|
4920
|
-
if (trimmed.
|
|
4921
|
-
|
|
4969
|
+
if (trimmed.startsWith("##")) {
|
|
4970
|
+
inConstraintsSection = false;
|
|
4971
|
+
} else if (trimmed.length > 0 && !trimmed.startsWith("#") && !trimmed.startsWith("*(") && !trimmed.startsWith("(*")) {
|
|
4972
|
+
const cleaned = trimmed.replace(/^-\s+/, "");
|
|
4973
|
+
if (isValidConstraintLine(cleaned)) {
|
|
4974
|
+
constraints.push(cleaned);
|
|
4975
|
+
}
|
|
4922
4976
|
}
|
|
4923
|
-
} else if (!inConstraintsSection && !inHandoffSection) {
|
|
4924
|
-
|
|
4925
|
-
|
|
4977
|
+
} else if (!inConstraintsSection && !inHandoffSection && !inWorkstreamsSection) {
|
|
4978
|
+
const hasSections = lines.some((l) => l.trim().startsWith("## "));
|
|
4979
|
+
if (!hasSections && trimmed.length > 0 && !trimmed.startsWith("#") && !trimmed.startsWith("*(") && !trimmed.startsWith("(*") && !trimmed.startsWith("|")) {
|
|
4980
|
+
if (isValidConstraintLine(trimmed)) {
|
|
4981
|
+
constraints.push(trimmed.replace(/^-\s+/, ""));
|
|
4982
|
+
}
|
|
4926
4983
|
}
|
|
4927
4984
|
}
|
|
4928
4985
|
}
|
|
@@ -4978,14 +5035,22 @@ function parseCurrentFile(memoryDir) {
|
|
|
4978
5035
|
};
|
|
4979
5036
|
}
|
|
4980
5037
|
}
|
|
4981
|
-
return { constraints, handoff };
|
|
5038
|
+
return { constraints, handoff, workstreams };
|
|
4982
5039
|
}
|
|
4983
5040
|
function writeCurrentFile(memoryDir, data) {
|
|
4984
5041
|
const p = currentFilePath(memoryDir);
|
|
4985
5042
|
mkdirSync5(memoryDir, { recursive: true });
|
|
4986
|
-
const parts = [
|
|
4987
|
-
|
|
4988
|
-
|
|
5043
|
+
const parts = [
|
|
5044
|
+
`# Active Project Constraints & In-Flight Context
|
|
5045
|
+
`,
|
|
5046
|
+
"> **Operational Guidelines**:",
|
|
5047
|
+
"> - **For Humans**: Single-pane executive summary of active hard constraints and in-flight agent tasks. Zero verbose logs or transient filler.",
|
|
5048
|
+
`> - **For AI Agents**: Mandatory grounding rules (never violate active constraints) and concurrent workstream awareness (check what other agents are touching before editing files).
|
|
5049
|
+
`,
|
|
5050
|
+
`---
|
|
5051
|
+
`
|
|
5052
|
+
];
|
|
5053
|
+
parts.push("## \uD83D\uDD12 Active Working Invariants & Hard Constraints");
|
|
4989
5054
|
if (data.constraints.length === 0) {
|
|
4990
5055
|
parts.push(`*(No active hard constraints)*
|
|
4991
5056
|
`);
|
|
@@ -4995,8 +5060,19 @@ function writeCurrentFile(memoryDir, data) {
|
|
|
4995
5060
|
}
|
|
4996
5061
|
parts.push("");
|
|
4997
5062
|
}
|
|
5063
|
+
if (data.workstreams && data.workstreams.length > 0) {
|
|
5064
|
+
parts.push("## \uD83E\uDD16 Active Concurrent Agent Workstreams");
|
|
5065
|
+
parts.push("| Agent / Session ID | Status | Active Task | Target Scope / Files | Last Active |");
|
|
5066
|
+
parts.push("| :--- | :--- | :--- | :--- | :--- |");
|
|
5067
|
+
for (const ws of data.workstreams) {
|
|
5068
|
+
const statusTag = `[${ws.status || "IN-PROGRESS"}]`;
|
|
5069
|
+
const scope = ws.targetScope ? `\`${ws.targetScope}\`` : "*(all)*";
|
|
5070
|
+
parts.push(`| \`${ws.agent}\` | ${statusTag} | ${ws.task} | ${scope} | ${ws.lastActive} |`);
|
|
5071
|
+
}
|
|
5072
|
+
parts.push("");
|
|
5073
|
+
}
|
|
4998
5074
|
if (data.handoff) {
|
|
4999
|
-
parts.push("## Active Work In Progress (Real-Time Session Handoff)");
|
|
5075
|
+
parts.push("## ⚡ Active Work In Progress (Real-Time Session Handoff)");
|
|
5000
5076
|
parts.push(`- **Status**: [${data.handoff.status}]`);
|
|
5001
5077
|
if (data.handoff.agent)
|
|
5002
5078
|
parts.push(`- **Active Agent**: ${data.handoff.agent}`);
|
|
@@ -5042,12 +5118,61 @@ function updateSessionHandoff(memoryDir, update) {
|
|
|
5042
5118
|
progress: progressMerged,
|
|
5043
5119
|
discoveries: discoveriesMerged
|
|
5044
5120
|
};
|
|
5121
|
+
const workstreams = current.workstreams ? [...current.workstreams] : [];
|
|
5122
|
+
if (updated.agent && (updated.task || updated.lastQuery)) {
|
|
5123
|
+
const wsIdx = workstreams.findIndex((w) => updated.sessionId && w.sessionId === updated.sessionId || w.agent.toLowerCase() === updated.agent.toLowerCase());
|
|
5124
|
+
const wsEntry = {
|
|
5125
|
+
agent: updated.agent,
|
|
5126
|
+
sessionId: updated.sessionId,
|
|
5127
|
+
task: updated.task || updated.lastQuery || "Active task",
|
|
5128
|
+
status: updated.status || "IN-PROGRESS",
|
|
5129
|
+
lastActive: now,
|
|
5130
|
+
lastInstruction: updated.lastQuery
|
|
5131
|
+
};
|
|
5132
|
+
if (wsIdx >= 0) {
|
|
5133
|
+
workstreams[wsIdx] = { ...workstreams[wsIdx], ...wsEntry };
|
|
5134
|
+
} else {
|
|
5135
|
+
workstreams.push(wsEntry);
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5045
5138
|
writeCurrentFile(memoryDir, {
|
|
5046
5139
|
constraints: current.constraints,
|
|
5047
|
-
handoff: updated
|
|
5140
|
+
handoff: updated,
|
|
5141
|
+
workstreams
|
|
5048
5142
|
});
|
|
5049
5143
|
return updated;
|
|
5050
5144
|
}
|
|
5145
|
+
function registerAgentWorkstream(memoryDir, workstream) {
|
|
5146
|
+
const current = parseCurrentFile(memoryDir);
|
|
5147
|
+
const now = new Date().toISOString();
|
|
5148
|
+
const workstreams = current.workstreams ? [...current.workstreams] : [];
|
|
5149
|
+
const entry = {
|
|
5150
|
+
agent: workstream.agent,
|
|
5151
|
+
sessionId: workstream.sessionId,
|
|
5152
|
+
task: workstream.task,
|
|
5153
|
+
targetScope: workstream.targetScope,
|
|
5154
|
+
status: workstream.status || "IN-PROGRESS",
|
|
5155
|
+
lastActive: workstream.lastActive || now,
|
|
5156
|
+
lastInstruction: workstream.lastInstruction
|
|
5157
|
+
};
|
|
5158
|
+
const idx = workstreams.findIndex((w) => entry.sessionId && w.sessionId === entry.sessionId || w.agent.toLowerCase() === entry.agent.toLowerCase());
|
|
5159
|
+
if (idx >= 0) {
|
|
5160
|
+
workstreams[idx] = { ...workstreams[idx], ...entry, lastActive: now };
|
|
5161
|
+
} else {
|
|
5162
|
+
workstreams.push(entry);
|
|
5163
|
+
}
|
|
5164
|
+
const nowMs = Date.now();
|
|
5165
|
+
const pruned = workstreams.filter((w) => {
|
|
5166
|
+
if (w.status === "COMPLETED") {
|
|
5167
|
+
const activeMs = Date.parse(w.lastActive) || 0;
|
|
5168
|
+
return nowMs - activeMs < 48 * 3600 * 1000;
|
|
5169
|
+
}
|
|
5170
|
+
return true;
|
|
5171
|
+
});
|
|
5172
|
+
current.workstreams = pruned;
|
|
5173
|
+
writeCurrentFile(memoryDir, current);
|
|
5174
|
+
return pruned;
|
|
5175
|
+
}
|
|
5051
5176
|
function getSessionHandoff(memoryDir) {
|
|
5052
5177
|
return parseCurrentFile(memoryDir).handoff;
|
|
5053
5178
|
}
|
|
@@ -5062,6 +5187,15 @@ function markSessionCompleted(memoryDir, summary) {
|
|
|
5062
5187
|
if (summary) {
|
|
5063
5188
|
current.handoff.task = `[COMPLETED] ${summary}`;
|
|
5064
5189
|
}
|
|
5190
|
+
if (current.workstreams && current.handoff.agent) {
|
|
5191
|
+
const ws = current.workstreams.find((w) => w.agent.toLowerCase() === current.handoff.agent.toLowerCase());
|
|
5192
|
+
if (ws) {
|
|
5193
|
+
ws.status = "COMPLETED";
|
|
5194
|
+
ws.lastActive = now;
|
|
5195
|
+
if (summary)
|
|
5196
|
+
ws.task = `[COMPLETED] ${summary}`;
|
|
5197
|
+
}
|
|
5198
|
+
}
|
|
5065
5199
|
writeCurrentFile(memoryDir, current);
|
|
5066
5200
|
}
|
|
5067
5201
|
function getCurrent2(memoryDir) {
|
|
@@ -5079,6 +5213,27 @@ function setCurrent(memoryDir, text, project = "default") {
|
|
|
5079
5213
|
}
|
|
5080
5214
|
return current.constraints;
|
|
5081
5215
|
}
|
|
5216
|
+
function isValidConstraintLine(text) {
|
|
5217
|
+
const trimmed = text.trim();
|
|
5218
|
+
if (trimmed.length < 5 || trimmed.length > 300)
|
|
5219
|
+
return false;
|
|
5220
|
+
if (trimmed.includes(`
|
|
5221
|
+
`))
|
|
5222
|
+
return false;
|
|
5223
|
+
if (/expect\(/i.test(trimmed) || /Ran\s+\d+\s+tests/i.test(trimmed))
|
|
5224
|
+
return false;
|
|
5225
|
+
if (trimmed.startsWith("Showing lines") || trimmed.startsWith("Created At:") || trimmed.startsWith("File Path:"))
|
|
5226
|
+
return false;
|
|
5227
|
+
if (trimmed.startsWith("MODEL PLANNER_RESPONSE") || trimmed.startsWith("</SYSTEM_MESSAGE>"))
|
|
5228
|
+
return false;
|
|
5229
|
+
if (trimmed.includes("<truncated") || trimmed.includes("User: That worked"))
|
|
5230
|
+
return false;
|
|
5231
|
+
if (trimmed.startsWith("total ") || /^\d+:\s+/.test(trimmed) || /^\d+\s*\|\s*/.test(trimmed))
|
|
5232
|
+
return false;
|
|
5233
|
+
if (trimmed.startsWith("The following code has been modified") || trimmed.startsWith("The above content does NOT"))
|
|
5234
|
+
return false;
|
|
5235
|
+
return true;
|
|
5236
|
+
}
|
|
5082
5237
|
function syncConstraints(memoryDir, store, pruneContents = []) {
|
|
5083
5238
|
const entries = list(store);
|
|
5084
5239
|
const activeConstraintMemories = entries.filter((e) => e.type === "constraint" && (e.status === "active" || e.status === "confirmed"));
|
|
@@ -5090,24 +5245,42 @@ Stale:`)[0].split(`
|
|
|
5090
5245
|
Superseded:`)[0].trim()).filter(Boolean);
|
|
5091
5246
|
const current = parseCurrentFile(memoryDir);
|
|
5092
5247
|
const keptManual = [];
|
|
5248
|
+
const seenNorms = new Set;
|
|
5093
5249
|
for (const c of current.constraints) {
|
|
5250
|
+
if (!isValidConstraintLine(c))
|
|
5251
|
+
continue;
|
|
5094
5252
|
if (pruneContents.some((p) => c.includes(p)))
|
|
5095
5253
|
continue;
|
|
5096
5254
|
if (inactiveConstraintContents.some((ic) => ic.length > 0 && (c.includes(ic) || ic.includes(c))))
|
|
5097
5255
|
continue;
|
|
5256
|
+
const norm = c.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
5257
|
+
if (seenNorms.has(norm))
|
|
5258
|
+
continue;
|
|
5259
|
+
seenNorms.add(norm);
|
|
5098
5260
|
keptManual.push(c);
|
|
5099
5261
|
}
|
|
5100
5262
|
const resultConstraints = [...keptManual];
|
|
5101
5263
|
for (const m of activeConstraintMemories) {
|
|
5102
5264
|
const rawContent = m.content.trim();
|
|
5103
|
-
if (
|
|
5104
|
-
|
|
5265
|
+
if (rawContent.length < 5)
|
|
5266
|
+
continue;
|
|
5267
|
+
let constraintText = rawContent;
|
|
5268
|
+
if (rawContent.includes(`
|
|
5269
|
+
`) || rawContent.length > 300) {
|
|
5270
|
+
const firstLine = rawContent.split(`
|
|
5271
|
+
`)[0].trim().replace(/^[-*#0-9.:\s|]+/, "");
|
|
5272
|
+
constraintText = firstLine.length >= 10 && firstLine.length <= 300 ? firstLine : m.title.replace(/^[-*#0-9.:\s|]+/, "").slice(0, 200).trim();
|
|
5273
|
+
}
|
|
5274
|
+
const norm = constraintText.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
5275
|
+
if (constraintText.length >= 5 && isValidConstraintLine(constraintText) && !resultConstraints.some((c) => c.toLowerCase().replace(/[^a-z0-9]/g, "").includes(norm))) {
|
|
5276
|
+
const stamp = `[${m.created_at || new Date().toISOString()}] (${m.project}) ${constraintText}`;
|
|
5105
5277
|
resultConstraints.push(stamp);
|
|
5106
5278
|
}
|
|
5107
5279
|
}
|
|
5108
5280
|
writeCurrentFile(memoryDir, {
|
|
5109
5281
|
constraints: resultConstraints,
|
|
5110
|
-
handoff: current.handoff
|
|
5282
|
+
handoff: current.handoff,
|
|
5283
|
+
workstreams: current.workstreams
|
|
5111
5284
|
});
|
|
5112
5285
|
return resultConstraints;
|
|
5113
5286
|
}
|
|
@@ -5303,6 +5476,9 @@ class WorkspaceGovernor {
|
|
|
5303
5476
|
static checkpointSession(memoryDir, update) {
|
|
5304
5477
|
return updateSessionHandoff(memoryDir, update);
|
|
5305
5478
|
}
|
|
5479
|
+
static registerWorkstream(memoryDir, workstream) {
|
|
5480
|
+
return registerAgentWorkstream(memoryDir, workstream);
|
|
5481
|
+
}
|
|
5306
5482
|
static completeSession(memoryDir, summary) {
|
|
5307
5483
|
markSessionCompleted(memoryDir, summary);
|
|
5308
5484
|
}
|
|
@@ -5720,6 +5896,8 @@ function openDatabase(dbPath) {
|
|
|
5720
5896
|
rawDb = new Database(dbPath, { create: true });
|
|
5721
5897
|
rawDb.run("PRAGMA journal_mode = WAL;");
|
|
5722
5898
|
rawDb.run("PRAGMA synchronous = NORMAL;");
|
|
5899
|
+
rawDb.run("PRAGMA busy_timeout = 5000;");
|
|
5900
|
+
rawDb.run("PRAGMA foreign_keys = ON;");
|
|
5723
5901
|
rawDb.run("PRAGMA cache_size = -64000;");
|
|
5724
5902
|
rawDb.run("PRAGMA mmap_size = 268435456;");
|
|
5725
5903
|
rawDb.run("PRAGMA temp_store = MEMORY;");
|
|
@@ -5758,6 +5936,8 @@ function openDatabase(dbPath) {
|
|
|
5758
5936
|
rawDb = new DatabaseSync(dbPath);
|
|
5759
5937
|
rawDb.exec("PRAGMA journal_mode = WAL;");
|
|
5760
5938
|
rawDb.exec("PRAGMA synchronous = NORMAL;");
|
|
5939
|
+
rawDb.exec("PRAGMA busy_timeout = 5000;");
|
|
5940
|
+
rawDb.exec("PRAGMA foreign_keys = ON;");
|
|
5761
5941
|
rawDb.exec("PRAGMA cache_size = -64000;");
|
|
5762
5942
|
rawDb.exec("PRAGMA mmap_size = 268435456;");
|
|
5763
5943
|
rawDb.exec("PRAGMA temp_store = MEMORY;");
|
|
@@ -6709,19 +6889,52 @@ function list(store, filters) {
|
|
|
6709
6889
|
if (cached)
|
|
6710
6890
|
return cached;
|
|
6711
6891
|
}
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6892
|
+
let entries = [];
|
|
6893
|
+
if (store.db) {
|
|
6894
|
+
entries = listMemories(store.db, filters);
|
|
6895
|
+
if (existsSync10(store.dir)) {
|
|
6896
|
+
const dbIds = new Set(entries.map((e) => e.id));
|
|
6897
|
+
const diskFiles = readdirSync2(store.dir);
|
|
6898
|
+
for (const f of diskFiles) {
|
|
6899
|
+
if (f.endsWith(".yaml")) {
|
|
6900
|
+
const diskId = f.slice(0, -5);
|
|
6901
|
+
if (!dbIds.has(diskId)) {
|
|
6902
|
+
const externalEntry = get(store, diskId);
|
|
6903
|
+
if (externalEntry) {
|
|
6904
|
+
try {
|
|
6905
|
+
insertOrReplaceMemory(store.db, externalEntry);
|
|
6906
|
+
} catch {}
|
|
6907
|
+
let matches = true;
|
|
6908
|
+
if (filters?.project && externalEntry.project !== filters.project)
|
|
6909
|
+
matches = false;
|
|
6910
|
+
if (filters?.type && externalEntry.type !== filters.type)
|
|
6911
|
+
matches = false;
|
|
6912
|
+
if (filters?.status && externalEntry.status !== filters.status)
|
|
6913
|
+
matches = false;
|
|
6914
|
+
if (matches)
|
|
6915
|
+
entries.push(externalEntry);
|
|
6916
|
+
}
|
|
6917
|
+
}
|
|
6918
|
+
}
|
|
6919
|
+
}
|
|
6920
|
+
}
|
|
6921
|
+
} else {
|
|
6922
|
+
const ids = listIds(store);
|
|
6923
|
+
entries = ids.map((id) => get(store, id)).filter((e) => e !== null);
|
|
6924
|
+
if (filters?.project)
|
|
6925
|
+
entries = entries.filter((e) => e.project === filters.project);
|
|
6926
|
+
if (filters?.type)
|
|
6927
|
+
entries = entries.filter((e) => e.type === filters.type);
|
|
6928
|
+
if (filters?.status)
|
|
6929
|
+
entries = entries.filter((e) => e.status === filters.status);
|
|
6930
|
+
}
|
|
6721
6931
|
if (store.cache) {
|
|
6722
|
-
store.cache.setQuery(cacheKey,
|
|
6932
|
+
store.cache.setQuery(cacheKey, entries, undefined, dirMtime);
|
|
6933
|
+
for (const e of entries) {
|
|
6934
|
+
store.cache.setEntry(e);
|
|
6935
|
+
}
|
|
6723
6936
|
}
|
|
6724
|
-
return
|
|
6937
|
+
return entries;
|
|
6725
6938
|
}
|
|
6726
6939
|
function extractEntryText(entry) {
|
|
6727
6940
|
const parts = [
|
|
@@ -6756,7 +6969,9 @@ function save(store, entry, options = {}) {
|
|
|
6756
6969
|
try {
|
|
6757
6970
|
mtimeMs = statSync(file).mtimeMs;
|
|
6758
6971
|
} catch {}
|
|
6759
|
-
} catch {
|
|
6972
|
+
} catch (err) {
|
|
6973
|
+
console.warn(`[WARN] Dual-write YAML failed for memory '${entry.id}':`, err instanceof Error ? err.message : String(err));
|
|
6974
|
+
}
|
|
6760
6975
|
if (store.cache) {
|
|
6761
6976
|
store.cache.setEntry(entry, undefined, mtimeMs);
|
|
6762
6977
|
}
|
|
@@ -20574,77 +20789,97 @@ async function reconcileCodeAnchors(store, options = {}) {
|
|
|
20574
20789
|
let repairedEntriesCount = 0;
|
|
20575
20790
|
let staleEntriesCount = 0;
|
|
20576
20791
|
const details = [];
|
|
20577
|
-
|
|
20578
|
-
|
|
20579
|
-
|
|
20580
|
-
|
|
20581
|
-
|
|
20582
|
-
|
|
20583
|
-
|
|
20584
|
-
const
|
|
20585
|
-
|
|
20586
|
-
|
|
20587
|
-
|
|
20588
|
-
const
|
|
20589
|
-
|
|
20590
|
-
|
|
20591
|
-
|
|
20592
|
-
|
|
20593
|
-
|
|
20594
|
-
|
|
20595
|
-
|
|
20596
|
-
|
|
20597
|
-
|
|
20598
|
-
|
|
20792
|
+
const inTx = !dryRun && !!store.db;
|
|
20793
|
+
if (inTx) {
|
|
20794
|
+
try {
|
|
20795
|
+
store.db.exec("BEGIN TRANSACTION;");
|
|
20796
|
+
} catch {}
|
|
20797
|
+
}
|
|
20798
|
+
try {
|
|
20799
|
+
for (const entry of entries) {
|
|
20800
|
+
if (!entry.anchors || entry.anchors.length === 0)
|
|
20801
|
+
continue;
|
|
20802
|
+
totalAuditedEntries++;
|
|
20803
|
+
const survivingAnchors = [];
|
|
20804
|
+
const entryOrphaned = [];
|
|
20805
|
+
const entryDrifted = [];
|
|
20806
|
+
const actionsTaken = [];
|
|
20807
|
+
let entryModified = false;
|
|
20808
|
+
for (const anchor of entry.anchors) {
|
|
20809
|
+
totalAnchors++;
|
|
20810
|
+
const verification = verifyCodeAnchor(root, anchor);
|
|
20811
|
+
if (verification.status === "valid") {
|
|
20812
|
+
validCount++;
|
|
20813
|
+
survivingAnchors.push(anchor);
|
|
20814
|
+
} else if (verification.status === "drifted") {
|
|
20815
|
+
driftedCount++;
|
|
20816
|
+
entryDrifted.push(`${anchor.file_path}${anchor.symbol_name ? `::${anchor.symbol_name}` : ""}`);
|
|
20817
|
+
if (updateHashes && verification.current_hash) {
|
|
20818
|
+
if (!dryRun) {
|
|
20819
|
+
anchor.structural_hash = verification.current_hash;
|
|
20820
|
+
anchor.verified_at = new Date().toISOString();
|
|
20821
|
+
}
|
|
20822
|
+
entryModified = true;
|
|
20823
|
+
actionsTaken.push(`Updated structural hash for drifted anchor '${anchor.id}'`);
|
|
20599
20824
|
}
|
|
20600
|
-
entryModified = true;
|
|
20601
|
-
actionsTaken.push(`Updated structural hash for drifted anchor '${anchor.id}'`);
|
|
20602
|
-
}
|
|
20603
|
-
survivingAnchors.push(anchor);
|
|
20604
|
-
} else {
|
|
20605
|
-
orphanedCount++;
|
|
20606
|
-
entryOrphaned.push(`${anchor.file_path}${anchor.symbol_name ? `::${anchor.symbol_name}` : ""}`);
|
|
20607
|
-
if (prune) {
|
|
20608
|
-
entryModified = true;
|
|
20609
|
-
prunedAnchorsCount++;
|
|
20610
|
-
actionsTaken.push(`Pruned orphaned anchor '${anchor.id}' (${verification.drift_details || "code deleted"})`);
|
|
20611
|
-
} else {
|
|
20612
20825
|
survivingAnchors.push(anchor);
|
|
20826
|
+
} else {
|
|
20827
|
+
orphanedCount++;
|
|
20828
|
+
entryOrphaned.push(`${anchor.file_path}${anchor.symbol_name ? `::${anchor.symbol_name}` : ""}`);
|
|
20829
|
+
if (prune) {
|
|
20830
|
+
entryModified = true;
|
|
20831
|
+
prunedAnchorsCount++;
|
|
20832
|
+
actionsTaken.push(`Pruned orphaned anchor '${anchor.id}' (${verification.drift_details || "code deleted"})`);
|
|
20833
|
+
} else {
|
|
20834
|
+
survivingAnchors.push(anchor);
|
|
20835
|
+
}
|
|
20613
20836
|
}
|
|
20614
20837
|
}
|
|
20615
|
-
|
|
20616
|
-
|
|
20617
|
-
|
|
20618
|
-
|
|
20619
|
-
actionsTaken.push(`Marked memory '${entry.id}' as stale (all code anchors orphaned)`);
|
|
20620
|
-
}
|
|
20621
|
-
if (!dryRun) {
|
|
20622
|
-
entry.anchors = survivingAnchors.length > 0 ? survivingAnchors : undefined;
|
|
20623
|
-
if ((!entry.anchors || entry.anchors.length === 0) && markStale2 && entry.status === "confirmed") {
|
|
20624
|
-
entry.status = "stale";
|
|
20625
|
-
entry.stale_reason = "All associated code anchors were orphaned and pruned";
|
|
20838
|
+
if (prune && entryModified) {
|
|
20839
|
+
if ((!survivingAnchors || survivingAnchors.length === 0) && markStale2 && entry.status === "confirmed") {
|
|
20840
|
+
staleEntriesCount++;
|
|
20841
|
+
actionsTaken.push(`Marked memory '${entry.id}' as stale (all code anchors orphaned)`);
|
|
20626
20842
|
}
|
|
20627
|
-
|
|
20628
|
-
|
|
20843
|
+
if (!dryRun) {
|
|
20844
|
+
entry.anchors = survivingAnchors.length > 0 ? survivingAnchors : undefined;
|
|
20845
|
+
if ((!entry.anchors || entry.anchors.length === 0) && markStale2 && entry.status === "confirmed") {
|
|
20846
|
+
entry.status = "stale";
|
|
20847
|
+
entry.stale_reason = "All associated code anchors were orphaned and pruned";
|
|
20848
|
+
}
|
|
20849
|
+
entry.updated_at = new Date().toISOString();
|
|
20850
|
+
save(store, entry);
|
|
20851
|
+
}
|
|
20852
|
+
repairedEntriesCount++;
|
|
20853
|
+
} else if (updateHashes && entryModified) {
|
|
20854
|
+
if (!dryRun) {
|
|
20855
|
+
entry.anchors = survivingAnchors.length > 0 ? survivingAnchors : undefined;
|
|
20856
|
+
entry.updated_at = new Date().toISOString();
|
|
20857
|
+
save(store, entry);
|
|
20858
|
+
}
|
|
20859
|
+
repairedEntriesCount++;
|
|
20629
20860
|
}
|
|
20630
|
-
|
|
20631
|
-
|
|
20632
|
-
|
|
20633
|
-
|
|
20634
|
-
|
|
20635
|
-
|
|
20861
|
+
if (entryOrphaned.length > 0 || entryDrifted.length > 0 || actionsTaken.length > 0) {
|
|
20862
|
+
details.push({
|
|
20863
|
+
entryId: entry.id,
|
|
20864
|
+
title: entry.title,
|
|
20865
|
+
actionsTaken,
|
|
20866
|
+
orphanedAnchors: entryOrphaned,
|
|
20867
|
+
driftedAnchors: entryDrifted
|
|
20868
|
+
});
|
|
20636
20869
|
}
|
|
20637
|
-
repairedEntriesCount++;
|
|
20638
20870
|
}
|
|
20639
|
-
if (
|
|
20640
|
-
|
|
20641
|
-
|
|
20642
|
-
|
|
20643
|
-
|
|
20644
|
-
|
|
20645
|
-
|
|
20646
|
-
|
|
20871
|
+
if (inTx) {
|
|
20872
|
+
try {
|
|
20873
|
+
store.db.exec("COMMIT;");
|
|
20874
|
+
} catch {}
|
|
20875
|
+
}
|
|
20876
|
+
} catch (err) {
|
|
20877
|
+
if (inTx) {
|
|
20878
|
+
try {
|
|
20879
|
+
store.db.exec("ROLLBACK;");
|
|
20880
|
+
} catch {}
|
|
20647
20881
|
}
|
|
20882
|
+
throw err;
|
|
20648
20883
|
}
|
|
20649
20884
|
if (!dryRun && store.memoryDir && (prunedAnchorsCount > 0 || staleEntriesCount > 0)) {
|
|
20650
20885
|
recordAuditEvent(store.memoryDir, {
|
|
@@ -21969,6 +22204,253 @@ var init_mesh = __esm(() => {
|
|
|
21969
22204
|
init_contracts();
|
|
21970
22205
|
});
|
|
21971
22206
|
|
|
22207
|
+
// src/optimize.ts
|
|
22208
|
+
var exports_optimize = {};
|
|
22209
|
+
__export(exports_optimize, {
|
|
22210
|
+
isJunkFragment: () => isJunkFragment,
|
|
22211
|
+
isTestNoise: () => isTestNoise,
|
|
22212
|
+
maybeAutoOptimize: () => maybeAutoOptimize,
|
|
22213
|
+
optimizeStore: () => optimizeStore,
|
|
22214
|
+
readOptimizationMetadata: () => readOptimizationMetadata,
|
|
22215
|
+
shouldAutoOptimize: () => shouldAutoOptimize,
|
|
22216
|
+
touchActivity: () => touchActivity,
|
|
22217
|
+
writeOptimizationMetadata: () => writeOptimizationMetadata
|
|
22218
|
+
});
|
|
22219
|
+
import { existsSync as existsSync39, readFileSync as readFileSync33, writeFileSync as writeFileSync19, statSync as statSync14 } from "node:fs";
|
|
22220
|
+
import { join as join36 } from "node:path";
|
|
22221
|
+
function getMetaPath(memoryDir) {
|
|
22222
|
+
return join36(memoryDir, META_FILE_NAME);
|
|
22223
|
+
}
|
|
22224
|
+
function readOptimizationMetadata(memoryDir) {
|
|
22225
|
+
const metaPath = getMetaPath(memoryDir);
|
|
22226
|
+
if (!existsSync39(metaPath)) {
|
|
22227
|
+
return {
|
|
22228
|
+
last_optimized_at: new Date(0).toISOString(),
|
|
22229
|
+
last_activity_at: new Date().toISOString(),
|
|
22230
|
+
total_optimizations: 0
|
|
22231
|
+
};
|
|
22232
|
+
}
|
|
22233
|
+
try {
|
|
22234
|
+
const raw = readFileSync33(metaPath, "utf8");
|
|
22235
|
+
return JSON.parse(raw);
|
|
22236
|
+
} catch {
|
|
22237
|
+
return {
|
|
22238
|
+
last_optimized_at: new Date(0).toISOString(),
|
|
22239
|
+
last_activity_at: new Date().toISOString(),
|
|
22240
|
+
total_optimizations: 0
|
|
22241
|
+
};
|
|
22242
|
+
}
|
|
22243
|
+
}
|
|
22244
|
+
function writeOptimizationMetadata(memoryDir, meta) {
|
|
22245
|
+
const metaPath = getMetaPath(memoryDir);
|
|
22246
|
+
try {
|
|
22247
|
+
writeFileSync19(metaPath, JSON.stringify(meta, null, 2), "utf8");
|
|
22248
|
+
} catch {}
|
|
22249
|
+
}
|
|
22250
|
+
function touchActivity(memoryDir) {
|
|
22251
|
+
try {
|
|
22252
|
+
const meta = readOptimizationMetadata(memoryDir);
|
|
22253
|
+
meta.last_activity_at = new Date().toISOString();
|
|
22254
|
+
writeOptimizationMetadata(memoryDir, meta);
|
|
22255
|
+
} catch {}
|
|
22256
|
+
}
|
|
22257
|
+
function shouldAutoOptimize(memoryDir, options = {}) {
|
|
22258
|
+
const meta = readOptimizationMetadata(memoryDir);
|
|
22259
|
+
const now = Date.now();
|
|
22260
|
+
const daysThreshold = options.daysIntervalThreshold ?? 7;
|
|
22261
|
+
const daysMs = daysThreshold * 24 * 60 * 60 * 1000;
|
|
22262
|
+
const hoursThreshold = options.inactivityHoursThreshold ?? 48;
|
|
22263
|
+
const hoursMs = hoursThreshold * 60 * 60 * 1000;
|
|
22264
|
+
const lastOpt = Date.parse(meta.last_optimized_at) || 0;
|
|
22265
|
+
const lastAct = Date.parse(meta.last_activity_at) || now;
|
|
22266
|
+
if (now - lastOpt >= daysMs) {
|
|
22267
|
+
return {
|
|
22268
|
+
shouldRun: true,
|
|
22269
|
+
reason: `Scheduled ${daysThreshold}-day cadence reached (${Math.round((now - lastOpt) / (24 * 3600 * 1000))}d since last run)`
|
|
22270
|
+
};
|
|
22271
|
+
}
|
|
22272
|
+
if (now - lastAct >= hoursMs && now - lastOpt >= hoursMs) {
|
|
22273
|
+
return {
|
|
22274
|
+
shouldRun: true,
|
|
22275
|
+
reason: `Inactivity threshold reached (${Math.round((now - lastAct) / (3600 * 1000))}h idle)`
|
|
22276
|
+
};
|
|
22277
|
+
}
|
|
22278
|
+
return { shouldRun: false };
|
|
22279
|
+
}
|
|
22280
|
+
function isTestNoise(entry) {
|
|
22281
|
+
if (entry.status === "confirmed" && entry.verification?.level === "user-confirmed") {
|
|
22282
|
+
return false;
|
|
22283
|
+
}
|
|
22284
|
+
const text = `${entry.title} ${entry.content}`;
|
|
22285
|
+
return /error:\s*expect\(/i.test(text) || /expect\([^)]+\)\.toBe/i.test(text) || /expect\([^)]+\)\.toEqual/i.test(text) || /expect\([^)]+\)\.toBeGreaterThan/i.test(text) || /expect\(received\)/i.test(text) || /at\s+<anonymous>\s+\([^)]+\.test\.(ts|js)/i.test(text) || /Ran\s+\d+\s+tests\s+across/i.test(text) || /\.test\.(ts|js):\d+:\d+/i.test(text) || /TypeError:\s*store\./i.test(text) || /AssertionError:/i.test(text) || /✗\s+Universal Agent Transcript/i.test(text) || /\b\d+\s+pass\s+\d+\s+fail\b/i.test(text) || /✓\s+[^\n]+\[\d+\.?\d*ms\]/i.test(text);
|
|
22286
|
+
}
|
|
22287
|
+
function isJunkFragment(entry) {
|
|
22288
|
+
const title = (entry.title || "").trim();
|
|
22289
|
+
const content = (entry.content || "").trim();
|
|
22290
|
+
if (content.length <= 5 && (/^['"]?[0-9]+['"]?$/.test(title) || title === "+" || title === "-" || title === "|" || title === ">-")) {
|
|
22291
|
+
return true;
|
|
22292
|
+
}
|
|
22293
|
+
if (content.includes("The following code has been modified") || content.includes("The above content does NOT show the entire file contents") || content.includes("MODEL PLANNER_RESPONSE") || content.includes("</SYSTEM_MESSAGE>") || content.split(`
|
|
22294
|
+
`).length > 50 && content.includes("Completed At:") || content.includes("<truncated") || content.includes("expect(") && /expect\([^)]+\)\.toBe/i.test(content)) {
|
|
22295
|
+
return true;
|
|
22296
|
+
}
|
|
22297
|
+
if (entry.status === "confirmed")
|
|
22298
|
+
return false;
|
|
22299
|
+
if (title === "1" || title === "+" || title === "-" || title === "|" || title === ">-") {
|
|
22300
|
+
return true;
|
|
22301
|
+
}
|
|
22302
|
+
if (/^['"]?[0-9]+['"]?$/.test(title)) {
|
|
22303
|
+
return true;
|
|
22304
|
+
}
|
|
22305
|
+
if (content.length < 15) {
|
|
22306
|
+
return true;
|
|
22307
|
+
}
|
|
22308
|
+
if (content.includes("create mode 100644") || content.includes("File Path: `file://") || content.includes("Showing lines ")) {
|
|
22309
|
+
return true;
|
|
22310
|
+
}
|
|
22311
|
+
return false;
|
|
22312
|
+
}
|
|
22313
|
+
function optimizeStore(store, options = {}) {
|
|
22314
|
+
const startTime = Date.now();
|
|
22315
|
+
const memoryDir = options.memoryDir || store.memoryDir || ".memory";
|
|
22316
|
+
if (!options.force) {
|
|
22317
|
+
const autoCheck = shouldAutoOptimize(memoryDir, {
|
|
22318
|
+
inactivityHoursThreshold: options.inactivityHoursThreshold,
|
|
22319
|
+
daysIntervalThreshold: options.daysIntervalThreshold
|
|
22320
|
+
});
|
|
22321
|
+
if (!autoCheck.shouldRun) {
|
|
22322
|
+
return {
|
|
22323
|
+
timestamp: new Date().toISOString(),
|
|
22324
|
+
totalBefore: 0,
|
|
22325
|
+
totalAfter: 0,
|
|
22326
|
+
prunedNoise: 0,
|
|
22327
|
+
prunedJunk: 0,
|
|
22328
|
+
prunedDuplicates: 0,
|
|
22329
|
+
totalPruned: 0,
|
|
22330
|
+
spaceReclaimedBytes: 0,
|
|
22331
|
+
vacuumExecuted: false,
|
|
22332
|
+
skippedReason: "Optimization thresholds not met (7-day cadence or 48-hour inactivity)",
|
|
22333
|
+
durationMs: Date.now() - startTime
|
|
22334
|
+
};
|
|
22335
|
+
}
|
|
22336
|
+
}
|
|
22337
|
+
const allEntries = list(store, options.project ? { project: options.project } : undefined);
|
|
22338
|
+
const totalBefore = allEntries.length;
|
|
22339
|
+
const getDbSize = () => {
|
|
22340
|
+
try {
|
|
22341
|
+
const dbPath = join36(memoryDir, "memory.db");
|
|
22342
|
+
if (existsSync39(dbPath)) {
|
|
22343
|
+
return statSync14(dbPath).size;
|
|
22344
|
+
}
|
|
22345
|
+
} catch {}
|
|
22346
|
+
return 0;
|
|
22347
|
+
};
|
|
22348
|
+
const dbSizeBefore = getDbSize();
|
|
22349
|
+
const toDeleteNoise = [];
|
|
22350
|
+
const toDeleteJunk = [];
|
|
22351
|
+
const toDeleteDuplicates = [];
|
|
22352
|
+
const seenHashes = new Map;
|
|
22353
|
+
for (const entry of allEntries) {
|
|
22354
|
+
if (entry.status !== "confirmed" && isTestNoise(entry)) {
|
|
22355
|
+
toDeleteNoise.push(entry.id);
|
|
22356
|
+
continue;
|
|
22357
|
+
}
|
|
22358
|
+
if (isJunkFragment(entry)) {
|
|
22359
|
+
toDeleteJunk.push(entry.id);
|
|
22360
|
+
continue;
|
|
22361
|
+
}
|
|
22362
|
+
if (entry.status === "candidate") {
|
|
22363
|
+
const normKey = `${normalizeText(entry.title)}|${normalizeText(entry.content.slice(0, 120))}`;
|
|
22364
|
+
if (seenHashes.has(normKey)) {
|
|
22365
|
+
toDeleteDuplicates.push(entry.id);
|
|
22366
|
+
} else {
|
|
22367
|
+
seenHashes.set(normKey, entry.id);
|
|
22368
|
+
}
|
|
22369
|
+
}
|
|
22370
|
+
}
|
|
22371
|
+
const totalPruned = toDeleteNoise.length + toDeleteJunk.length + toDeleteDuplicates.length;
|
|
22372
|
+
if (!options.dryRun) {
|
|
22373
|
+
if (store.db) {
|
|
22374
|
+
try {
|
|
22375
|
+
store.db.exec("BEGIN TRANSACTION;");
|
|
22376
|
+
} catch {}
|
|
22377
|
+
}
|
|
22378
|
+
for (const id of toDeleteNoise) {
|
|
22379
|
+
deleteEntry(store, id, "Automated optimize: pruned test assertion noise");
|
|
22380
|
+
}
|
|
22381
|
+
for (const id of toDeleteJunk) {
|
|
22382
|
+
deleteEntry(store, id, "Automated optimize: pruned junk fragment");
|
|
22383
|
+
}
|
|
22384
|
+
for (const id of toDeleteDuplicates) {
|
|
22385
|
+
deleteEntry(store, id, "Automated optimize: pruned duplicate candidate");
|
|
22386
|
+
}
|
|
22387
|
+
if (store.db) {
|
|
22388
|
+
try {
|
|
22389
|
+
store.db.exec("COMMIT;");
|
|
22390
|
+
} catch {}
|
|
22391
|
+
}
|
|
22392
|
+
if (store.db) {
|
|
22393
|
+
try {
|
|
22394
|
+
store.db.exec("VACUUM;");
|
|
22395
|
+
store.db.exec("PRAGMA optimize;");
|
|
22396
|
+
} catch {}
|
|
22397
|
+
}
|
|
22398
|
+
try {
|
|
22399
|
+
syncConstraints(memoryDir, store);
|
|
22400
|
+
} catch {}
|
|
22401
|
+
}
|
|
22402
|
+
const dbSizeAfter = getDbSize();
|
|
22403
|
+
const spaceReclaimedBytes = Math.max(0, dbSizeBefore - dbSizeAfter);
|
|
22404
|
+
const remainingEntries = list(store, options.project ? { project: options.project } : undefined);
|
|
22405
|
+
const totalAfter = options.dryRun ? totalBefore - totalPruned : remainingEntries.length;
|
|
22406
|
+
const report = {
|
|
22407
|
+
timestamp: new Date().toISOString(),
|
|
22408
|
+
totalBefore,
|
|
22409
|
+
totalAfter,
|
|
22410
|
+
prunedNoise: toDeleteNoise.length,
|
|
22411
|
+
prunedJunk: toDeleteJunk.length,
|
|
22412
|
+
prunedDuplicates: toDeleteDuplicates.length,
|
|
22413
|
+
totalPruned,
|
|
22414
|
+
spaceReclaimedBytes,
|
|
22415
|
+
vacuumExecuted: !options.dryRun && !!store.db,
|
|
22416
|
+
durationMs: Date.now() - startTime
|
|
22417
|
+
};
|
|
22418
|
+
if (!options.dryRun) {
|
|
22419
|
+
recordAuditEvent(memoryDir, {
|
|
22420
|
+
operation: "optimize",
|
|
22421
|
+
entry_id: "store",
|
|
22422
|
+
project: options.project || "all",
|
|
22423
|
+
actor: "system:optimizer",
|
|
22424
|
+
reason: `Optimized store: pruned ${totalPruned} items, reclaimed ${spaceReclaimedBytes} bytes`
|
|
22425
|
+
});
|
|
22426
|
+
const meta = readOptimizationMetadata(memoryDir);
|
|
22427
|
+
meta.last_optimized_at = report.timestamp;
|
|
22428
|
+
meta.last_activity_at = report.timestamp;
|
|
22429
|
+
meta.total_optimizations = (meta.total_optimizations || 0) + 1;
|
|
22430
|
+
meta.last_report = report;
|
|
22431
|
+
writeOptimizationMetadata(memoryDir, meta);
|
|
22432
|
+
}
|
|
22433
|
+
return report;
|
|
22434
|
+
}
|
|
22435
|
+
function maybeAutoOptimize(store, memoryDir) {
|
|
22436
|
+
const dir = memoryDir || store.memoryDir || ".memory";
|
|
22437
|
+
const check = shouldAutoOptimize(dir);
|
|
22438
|
+
if (!check.shouldRun)
|
|
22439
|
+
return null;
|
|
22440
|
+
try {
|
|
22441
|
+
return optimizeStore(store, { memoryDir: dir, force: true });
|
|
22442
|
+
} catch {
|
|
22443
|
+
return null;
|
|
22444
|
+
}
|
|
22445
|
+
}
|
|
22446
|
+
var META_FILE_NAME = "optimization_meta.json";
|
|
22447
|
+
var init_optimize = __esm(() => {
|
|
22448
|
+
init_store();
|
|
22449
|
+
init_dedup();
|
|
22450
|
+
init_audit();
|
|
22451
|
+
init_governor();
|
|
22452
|
+
});
|
|
22453
|
+
|
|
21972
22454
|
// src/ui.ts
|
|
21973
22455
|
var exports_ui = {};
|
|
21974
22456
|
__export(exports_ui, {
|
|
@@ -22268,6 +22750,42 @@ function startUiServer(opts) {
|
|
|
22268
22750
|
}
|
|
22269
22751
|
return;
|
|
22270
22752
|
}
|
|
22753
|
+
if (pathname === "/api/optimize" && req.method === "POST") {
|
|
22754
|
+
try {
|
|
22755
|
+
const { optimizeStore: optimizeStore2 } = await Promise.resolve().then(() => (init_optimize(), exports_optimize));
|
|
22756
|
+
const body = await parseJsonBody(req);
|
|
22757
|
+
const report = optimizeStore2(opts.store, {
|
|
22758
|
+
memoryDir: opts.memoryDir,
|
|
22759
|
+
project: body.project ? String(body.project) : undefined,
|
|
22760
|
+
dryRun: body.dryRun === true,
|
|
22761
|
+
force: body.force !== false
|
|
22762
|
+
});
|
|
22763
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
22764
|
+
res.end(JSON.stringify({ success: true, report }));
|
|
22765
|
+
} catch (err) {
|
|
22766
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
22767
|
+
res.end(JSON.stringify({ error: String(err) }));
|
|
22768
|
+
}
|
|
22769
|
+
return;
|
|
22770
|
+
}
|
|
22771
|
+
if (pathname === "/api/optimize/status" && req.method === "GET") {
|
|
22772
|
+
try {
|
|
22773
|
+
const { readOptimizationMetadata: readOptimizationMetadata2, shouldAutoOptimize: shouldAutoOptimize2 } = await Promise.resolve().then(() => (init_optimize(), exports_optimize));
|
|
22774
|
+
const meta = readOptimizationMetadata2(opts.memoryDir);
|
|
22775
|
+
const autoCheck = shouldAutoOptimize2(opts.memoryDir);
|
|
22776
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
22777
|
+
res.end(JSON.stringify({
|
|
22778
|
+
success: true,
|
|
22779
|
+
meta,
|
|
22780
|
+
shouldAutoOptimize: autoCheck.shouldRun,
|
|
22781
|
+
autoOptimizeReason: autoCheck.reason
|
|
22782
|
+
}));
|
|
22783
|
+
} catch (err) {
|
|
22784
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
22785
|
+
res.end(JSON.stringify({ error: String(err) }));
|
|
22786
|
+
}
|
|
22787
|
+
return;
|
|
22788
|
+
}
|
|
22271
22789
|
const workspaceRoot = opts.store.layout?.root || getStorageLayout(opts.memoryDir).root;
|
|
22272
22790
|
if (pathname === "/api/health" && req.method === "GET") {
|
|
22273
22791
|
try {
|
|
@@ -22769,6 +23287,10 @@ var MAX_BODY_SIZE, EMBEDDED_HTML = `<!DOCTYPE html>
|
|
|
22769
23287
|
<span class="refresh-icon" id="refreshIcon">\uD83D\uDD04</span>
|
|
22770
23288
|
<span id="refreshLabel">Refresh</span>
|
|
22771
23289
|
</button>
|
|
23290
|
+
<button class="btn-icon btn-optimize" id="optimizeBtn" onclick="optimizeStoreDashboard()" title="Clean test noise, prune junk, deduplicate candidates, and defragment SQLite storage">
|
|
23291
|
+
<span class="optimize-icon" id="optimizeIcon">⚡</span>
|
|
23292
|
+
<span id="optimizeLabel">Optimize</span>
|
|
23293
|
+
</button>
|
|
22772
23294
|
<div class="status-badge"><div class="status-dot"></div>[LIVE] Active</div>
|
|
22773
23295
|
<button class="btn-icon" onclick="exportDataHtml()">⬇ Export HTML</button>
|
|
22774
23296
|
</div>
|
|
@@ -23230,6 +23752,40 @@ var MAX_BODY_SIZE, EMBEDDED_HTML = `<!DOCTYPE html>
|
|
|
23230
23752
|
}
|
|
23231
23753
|
}
|
|
23232
23754
|
|
|
23755
|
+
async function optimizeStoreDashboard() {
|
|
23756
|
+
const icon = document.getElementById('optimizeIcon');
|
|
23757
|
+
const label = document.getElementById('optimizeLabel');
|
|
23758
|
+
const btn = document.getElementById('optimizeBtn');
|
|
23759
|
+
if (icon) icon.classList.add('spinning');
|
|
23760
|
+
if (label) label.textContent = 'Optimizing...';
|
|
23761
|
+
if (btn) btn.disabled = true;
|
|
23762
|
+
|
|
23763
|
+
try {
|
|
23764
|
+
const res = await fetch('/api/optimize', {
|
|
23765
|
+
method: 'POST',
|
|
23766
|
+
headers: { 'Content-Type': 'application/json' },
|
|
23767
|
+
body: JSON.stringify({ force: true }),
|
|
23768
|
+
});
|
|
23769
|
+
const data = await res.json();
|
|
23770
|
+
if (!data.success) throw new Error(data.error || 'Optimization failed');
|
|
23771
|
+
const rep = data.report;
|
|
23772
|
+
await loadData();
|
|
23773
|
+
const formatBytes = (b) => {
|
|
23774
|
+
if (b >= 1024 * 1024) return (b / (1024 * 1024)).toFixed(1) + ' MB';
|
|
23775
|
+
if (b >= 1024) return (b / 1024).toFixed(1) + ' KB';
|
|
23776
|
+
return b + ' B';
|
|
23777
|
+
};
|
|
23778
|
+
const spaceMsg = rep.spaceReclaimedBytes > 0 ? ' Reclaimed ' + formatBytes(rep.spaceReclaimedBytes) + '.' : '';
|
|
23779
|
+
flash('⚡ Optimization Complete! Pruned ' + rep.totalPruned + ' items (' + rep.prunedNoise + ' noise, ' + rep.prunedJunk + ' junk, ' + rep.prunedDuplicates + ' dupes).' + spaceMsg);
|
|
23780
|
+
} catch (err) {
|
|
23781
|
+
flash('Optimization failed: ' + (err && err.message ? err.message : String(err)), true);
|
|
23782
|
+
} finally {
|
|
23783
|
+
if (icon) icon.classList.remove('spinning');
|
|
23784
|
+
if (label) label.textContent = 'Optimize';
|
|
23785
|
+
if (btn) btn.disabled = false;
|
|
23786
|
+
}
|
|
23787
|
+
}
|
|
23788
|
+
|
|
23233
23789
|
async function loadData() {
|
|
23234
23790
|
try {
|
|
23235
23791
|
if (window.STANDALONE_DATA) {
|
|
@@ -32537,8 +33093,8 @@ var init_loops = __esm(() => {
|
|
|
32537
33093
|
});
|
|
32538
33094
|
|
|
32539
33095
|
// src/distill.ts
|
|
32540
|
-
import { existsSync as
|
|
32541
|
-
import { join as
|
|
33096
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync21, writeFileSync as writeFileSync20 } from "node:fs";
|
|
33097
|
+
import { join as join37 } from "node:path";
|
|
32542
33098
|
function fixTokens(e) {
|
|
32543
33099
|
const bag = tokenBag(e.title, 2);
|
|
32544
33100
|
mergeBag(bag, tokenBag((e.tags ?? []).join(" "), 2));
|
|
@@ -32549,7 +33105,7 @@ function distillSkills(store, workspaceRoot, options = {}) {
|
|
|
32549
33105
|
const report = { created: [], skippedExisting: [], clustersBelowThreshold: 0 };
|
|
32550
33106
|
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));
|
|
32551
33107
|
const clusters = clusterByTokenOverlap(fixes, fixTokens, 0.5);
|
|
32552
|
-
const skillsDir = options.skillsDir ??
|
|
33108
|
+
const skillsDir = options.skillsDir ?? join37(workspaceRoot, ".agents", "skills");
|
|
32553
33109
|
for (const cluster of clusters) {
|
|
32554
33110
|
if (cluster.length < minCount) {
|
|
32555
33111
|
report.clustersBelowThreshold++;
|
|
@@ -32557,9 +33113,9 @@ function distillSkills(store, workspaceRoot, options = {}) {
|
|
|
32557
33113
|
}
|
|
32558
33114
|
const topic = dominantTopicTokens(cluster.map((e) => e.title));
|
|
32559
33115
|
const slug = slugifyId(topic.join("-") || "skill");
|
|
32560
|
-
const dir =
|
|
33116
|
+
const dir = join37(skillsDir, slug);
|
|
32561
33117
|
const memberIds = cluster.map((e) => e.id);
|
|
32562
|
-
if (
|
|
33118
|
+
if (existsSync40(dir)) {
|
|
32563
33119
|
report.skippedExisting.push({ slug, members: memberIds });
|
|
32564
33120
|
continue;
|
|
32565
33121
|
}
|
|
@@ -32570,9 +33126,9 @@ function distillSkills(store, workspaceRoot, options = {}) {
|
|
|
32570
33126
|
}
|
|
32571
33127
|
if (!options.dryRun) {
|
|
32572
33128
|
mkdirSync21(dir, { recursive: true });
|
|
32573
|
-
|
|
33129
|
+
writeFileSync20(join37(dir, "SKILL.md"), md, "utf8");
|
|
32574
33130
|
}
|
|
32575
|
-
report.created.push({ slug, path:
|
|
33131
|
+
report.created.push({ slug, path: join37(dir, "SKILL.md"), members: memberIds });
|
|
32576
33132
|
}
|
|
32577
33133
|
return report;
|
|
32578
33134
|
}
|
|
@@ -32622,18 +33178,18 @@ __export(exports_provenance, {
|
|
|
32622
33178
|
loadSources: () => loadSources,
|
|
32623
33179
|
saveSources: () => saveSources
|
|
32624
33180
|
});
|
|
32625
|
-
import { existsSync as
|
|
32626
|
-
import { join as
|
|
33181
|
+
import { existsSync as existsSync41, readFileSync as readFileSync34, writeFileSync as writeFileSync21, mkdirSync as mkdirSync22 } from "node:fs";
|
|
33182
|
+
import { join as join38 } from "node:path";
|
|
32627
33183
|
function getSourcesFilePath(memoryDir) {
|
|
32628
|
-
return
|
|
33184
|
+
return join38(memoryDir, "sources.json");
|
|
32629
33185
|
}
|
|
32630
33186
|
function loadSources(memoryDir) {
|
|
32631
33187
|
const filePath = getSourcesFilePath(memoryDir);
|
|
32632
|
-
if (!
|
|
33188
|
+
if (!existsSync41(filePath)) {
|
|
32633
33189
|
return [];
|
|
32634
33190
|
}
|
|
32635
33191
|
try {
|
|
32636
|
-
const raw =
|
|
33192
|
+
const raw = readFileSync34(filePath, "utf-8");
|
|
32637
33193
|
const parsed = JSON.parse(raw);
|
|
32638
33194
|
return Array.isArray(parsed) ? parsed : [];
|
|
32639
33195
|
} catch {
|
|
@@ -32643,7 +33199,7 @@ function loadSources(memoryDir) {
|
|
|
32643
33199
|
function saveSources(memoryDir, sources) {
|
|
32644
33200
|
mkdirSync22(memoryDir, { recursive: true });
|
|
32645
33201
|
const filePath = getSourcesFilePath(memoryDir);
|
|
32646
|
-
|
|
33202
|
+
writeFileSync21(filePath, JSON.stringify(sources, null, 2), "utf-8");
|
|
32647
33203
|
}
|
|
32648
33204
|
function addSource(memoryDir, input) {
|
|
32649
33205
|
const textToScan = `${input.title}
|
|
@@ -32710,18 +33266,18 @@ __export(exports_claims, {
|
|
|
32710
33266
|
recordClaim: () => recordClaim,
|
|
32711
33267
|
saveClaims: () => saveClaims
|
|
32712
33268
|
});
|
|
32713
|
-
import { existsSync as
|
|
32714
|
-
import { join as
|
|
33269
|
+
import { existsSync as existsSync42, readFileSync as readFileSync35, writeFileSync as writeFileSync22, mkdirSync as mkdirSync23 } from "node:fs";
|
|
33270
|
+
import { join as join39 } from "node:path";
|
|
32715
33271
|
function getClaimsFilePath(memoryDir) {
|
|
32716
|
-
return
|
|
33272
|
+
return join39(memoryDir, "claims.json");
|
|
32717
33273
|
}
|
|
32718
33274
|
function loadClaims(memoryDir) {
|
|
32719
33275
|
const filePath = getClaimsFilePath(memoryDir);
|
|
32720
|
-
if (!
|
|
33276
|
+
if (!existsSync42(filePath)) {
|
|
32721
33277
|
return [];
|
|
32722
33278
|
}
|
|
32723
33279
|
try {
|
|
32724
|
-
const raw =
|
|
33280
|
+
const raw = readFileSync35(filePath, "utf-8");
|
|
32725
33281
|
const parsed = JSON.parse(raw);
|
|
32726
33282
|
return Array.isArray(parsed) ? parsed : [];
|
|
32727
33283
|
} catch {
|
|
@@ -32731,7 +33287,7 @@ function loadClaims(memoryDir) {
|
|
|
32731
33287
|
function saveClaims(memoryDir, claims) {
|
|
32732
33288
|
mkdirSync23(memoryDir, { recursive: true });
|
|
32733
33289
|
const filePath = getClaimsFilePath(memoryDir);
|
|
32734
|
-
|
|
33290
|
+
writeFileSync22(filePath, JSON.stringify(claims, null, 2), "utf-8");
|
|
32735
33291
|
}
|
|
32736
33292
|
function recordClaim(memoryDir, input) {
|
|
32737
33293
|
const textToScan = `${input.claim}
|
|
@@ -32876,8 +33432,8 @@ ${result.stderr}`.trim().slice(0, 2000)
|
|
|
32876
33432
|
return result;
|
|
32877
33433
|
}
|
|
32878
33434
|
function verifyStrictIntegrity(store, memoryDir, workspaceRoot, options = {}) {
|
|
32879
|
-
const { existsSync:
|
|
32880
|
-
const { join:
|
|
33435
|
+
const { existsSync: existsSync43, readFileSync: readFileSync36, readdirSync: readdirSync16 } = __require("node:fs");
|
|
33436
|
+
const { join: join40 } = __require("node:path");
|
|
32881
33437
|
const { scanSecrets: scanSecrets2 } = (init_secrets(), __toCommonJS(exports_secrets));
|
|
32882
33438
|
const { list: list2 } = (init_store(), __toCommonJS(exports_store));
|
|
32883
33439
|
const { loadSources: loadSources2 } = (init_provenance(), __toCommonJS(exports_provenance));
|
|
@@ -32895,15 +33451,15 @@ ${(e.tags ?? []).join(" ")}`;
|
|
|
32895
33451
|
secretErrors.push(`Secret detected in memory ${e.id}: ${found.join(", ")}`);
|
|
32896
33452
|
}
|
|
32897
33453
|
}
|
|
32898
|
-
const currentPath =
|
|
32899
|
-
if (
|
|
32900
|
-
const found = scanSecrets2(
|
|
33454
|
+
const currentPath = join40(memoryDir, "CURRENT.md");
|
|
33455
|
+
if (existsSync43(currentPath)) {
|
|
33456
|
+
const found = scanSecrets2(readFileSync36(currentPath, "utf-8"));
|
|
32901
33457
|
if (found.length > 0)
|
|
32902
33458
|
secretErrors.push(`Secret detected in CURRENT.md: ${found.join(", ")}`);
|
|
32903
33459
|
}
|
|
32904
|
-
const userPath =
|
|
32905
|
-
if (
|
|
32906
|
-
const found = scanSecrets2(
|
|
33460
|
+
const userPath = join40(memoryDir, "USER.md");
|
|
33461
|
+
if (existsSync43(userPath)) {
|
|
33462
|
+
const found = scanSecrets2(readFileSync36(userPath, "utf-8"));
|
|
32907
33463
|
if (found.length > 0)
|
|
32908
33464
|
secretErrors.push(`Secret detected in USER.md: ${found.join(", ")}`);
|
|
32909
33465
|
}
|
|
@@ -32972,12 +33528,12 @@ ${(e.tags ?? []).join(" ")}`;
|
|
|
32972
33528
|
errors: claimErrors.length > 0 ? claimErrors : undefined
|
|
32973
33529
|
});
|
|
32974
33530
|
const wikiErrors = [];
|
|
32975
|
-
const wikiDir =
|
|
32976
|
-
if (
|
|
33531
|
+
const wikiDir = join40(memoryDir, "wiki");
|
|
33532
|
+
if (existsSync43(wikiDir)) {
|
|
32977
33533
|
let collectSlugs = function(dir) {
|
|
32978
33534
|
const items = readdirSync16(dir, { withFileTypes: true });
|
|
32979
33535
|
for (const it of items) {
|
|
32980
|
-
const full =
|
|
33536
|
+
const full = join40(dir, it.name);
|
|
32981
33537
|
if (it.isDirectory()) {
|
|
32982
33538
|
collectSlugs(full);
|
|
32983
33539
|
} else if (it.name.endsWith(".md")) {
|
|
@@ -32989,11 +33545,11 @@ ${(e.tags ?? []).join(" ")}`;
|
|
|
32989
33545
|
}, scanWikilinks = function(dir) {
|
|
32990
33546
|
const items = readdirSync16(dir, { withFileTypes: true });
|
|
32991
33547
|
for (const it of items) {
|
|
32992
|
-
const full =
|
|
33548
|
+
const full = join40(dir, it.name);
|
|
32993
33549
|
if (it.isDirectory()) {
|
|
32994
33550
|
scanWikilinks(full);
|
|
32995
33551
|
} else if (it.name.endsWith(".md")) {
|
|
32996
|
-
const content =
|
|
33552
|
+
const content = readFileSync36(full, "utf-8");
|
|
32997
33553
|
const matches = content.matchAll(/\[\[([a-zA-Z0-9_\-\./ ]+?)(?:\|[^\r\n\]]+)?\]\]/g);
|
|
32998
33554
|
for (const m of matches) {
|
|
32999
33555
|
const rawTarget = m[1].trim().toLowerCase();
|
|
@@ -33260,14 +33816,14 @@ var init_schema2 = __esm(() => {
|
|
|
33260
33816
|
});
|
|
33261
33817
|
|
|
33262
33818
|
// src/settings/loader.ts
|
|
33263
|
-
import { existsSync as
|
|
33264
|
-
import { join as
|
|
33819
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync24, readFileSync as readFileSync36, writeFileSync as writeFileSync23 } from "node:fs";
|
|
33820
|
+
import { join as join40 } from "node:path";
|
|
33265
33821
|
function getSettingsFilePath(memoryDir) {
|
|
33266
|
-
return
|
|
33822
|
+
return join40(memoryDir, "settings.json");
|
|
33267
33823
|
}
|
|
33268
33824
|
function loadSettings(memoryDir) {
|
|
33269
33825
|
const filePath = getSettingsFilePath(memoryDir);
|
|
33270
|
-
if (!
|
|
33826
|
+
if (!existsSync43(filePath)) {
|
|
33271
33827
|
return {
|
|
33272
33828
|
version: 1,
|
|
33273
33829
|
global: JSON.parse(JSON.stringify(DEFAULT_SETTINGS)),
|
|
@@ -33275,7 +33831,7 @@ function loadSettings(memoryDir) {
|
|
|
33275
33831
|
};
|
|
33276
33832
|
}
|
|
33277
33833
|
try {
|
|
33278
|
-
const raw =
|
|
33834
|
+
const raw = readFileSync36(filePath, "utf8");
|
|
33279
33835
|
const parsed = JSON.parse(raw);
|
|
33280
33836
|
return {
|
|
33281
33837
|
version: parsed.version || 1,
|
|
@@ -33293,7 +33849,7 @@ function loadSettings(memoryDir) {
|
|
|
33293
33849
|
function saveSettings(store, memoryDir) {
|
|
33294
33850
|
mkdirSync24(memoryDir, { recursive: true });
|
|
33295
33851
|
const filePath = getSettingsFilePath(memoryDir);
|
|
33296
|
-
|
|
33852
|
+
writeFileSync23(filePath, JSON.stringify(store, null, 2), "utf8");
|
|
33297
33853
|
}
|
|
33298
33854
|
function getSettings(memoryDir) {
|
|
33299
33855
|
return loadSettings(memoryDir).global;
|
|
@@ -33401,10 +33957,10 @@ var init_settings2 = __esm(() => {
|
|
|
33401
33957
|
});
|
|
33402
33958
|
|
|
33403
33959
|
// src/learning/observation.ts
|
|
33404
|
-
import { existsSync as
|
|
33405
|
-
import { join as
|
|
33960
|
+
import { existsSync as existsSync44, readFileSync as readFileSync37, appendFileSync as appendFileSync2, writeFileSync as writeFileSync24, mkdirSync as mkdirSync25 } from "node:fs";
|
|
33961
|
+
import { join as join41 } from "node:path";
|
|
33406
33962
|
function observationsFilePath(memoryDir) {
|
|
33407
|
-
return
|
|
33963
|
+
return join41(memoryDir, "observations.jsonl");
|
|
33408
33964
|
}
|
|
33409
33965
|
function recordObservation(store, obs) {
|
|
33410
33966
|
if (!obs.raw || !obs.raw.trim()) {
|
|
@@ -33416,7 +33972,7 @@ function recordObservation(store, obs) {
|
|
|
33416
33972
|
}
|
|
33417
33973
|
const memoryDir = store.memoryDir || store.dir;
|
|
33418
33974
|
const filePath = observationsFilePath(memoryDir);
|
|
33419
|
-
if (!
|
|
33975
|
+
if (!existsSync44(memoryDir)) {
|
|
33420
33976
|
mkdirSync25(memoryDir, { recursive: true });
|
|
33421
33977
|
}
|
|
33422
33978
|
const id = `obs_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
@@ -33437,9 +33993,9 @@ function recordObservation(store, obs) {
|
|
|
33437
33993
|
function listObservations(store, options) {
|
|
33438
33994
|
const memoryDir = store.memoryDir || store.dir;
|
|
33439
33995
|
const filePath = observationsFilePath(memoryDir);
|
|
33440
|
-
if (!
|
|
33996
|
+
if (!existsSync44(filePath))
|
|
33441
33997
|
return [];
|
|
33442
|
-
const lines =
|
|
33998
|
+
const lines = readFileSync37(filePath, "utf8").split(`
|
|
33443
33999
|
`).filter((l) => l.trim().length > 0);
|
|
33444
34000
|
const results = [];
|
|
33445
34001
|
for (const line of lines) {
|
|
@@ -33459,9 +34015,9 @@ function listObservations(store, options) {
|
|
|
33459
34015
|
function markObservationProcessed(store, observationId, extractedCandidateId) {
|
|
33460
34016
|
const memoryDir = store.memoryDir || store.dir;
|
|
33461
34017
|
const filePath = observationsFilePath(memoryDir);
|
|
33462
|
-
if (!
|
|
34018
|
+
if (!existsSync44(filePath))
|
|
33463
34019
|
return false;
|
|
33464
|
-
const lines =
|
|
34020
|
+
const lines = readFileSync37(filePath, "utf8").split(`
|
|
33465
34021
|
`).filter((l) => l.trim().length > 0);
|
|
33466
34022
|
let updated = false;
|
|
33467
34023
|
const newLines = [];
|
|
@@ -33480,7 +34036,7 @@ function markObservationProcessed(store, observationId, extractedCandidateId) {
|
|
|
33480
34036
|
}
|
|
33481
34037
|
}
|
|
33482
34038
|
if (updated) {
|
|
33483
|
-
|
|
34039
|
+
writeFileSync24(filePath, `${newLines.join(`
|
|
33484
34040
|
`)}
|
|
33485
34041
|
`, "utf8");
|
|
33486
34042
|
}
|
|
@@ -33781,8 +34337,8 @@ var init_bidirectional = __esm(() => {
|
|
|
33781
34337
|
});
|
|
33782
34338
|
|
|
33783
34339
|
// src/intelligence/impact.ts
|
|
33784
|
-
import { existsSync as
|
|
33785
|
-
import { join as
|
|
34340
|
+
import { existsSync as existsSync45, readdirSync as readdirSync16, readFileSync as readFileSync38 } from "node:fs";
|
|
34341
|
+
import { join as join42, basename as basename2 } from "node:path";
|
|
33786
34342
|
async function analyzeMemoryCodeImpact(store, options) {
|
|
33787
34343
|
const root = options.workspaceRoot || store.dir || process.cwd();
|
|
33788
34344
|
const targetFile = options.filePath;
|
|
@@ -33838,11 +34394,19 @@ async function analyzeMemoryCodeImpact(store, options) {
|
|
|
33838
34394
|
}));
|
|
33839
34395
|
const allAdrs = listAdrs(store);
|
|
33840
34396
|
const matchedAdrs = [];
|
|
34397
|
+
const normTarget = targetFile.toLowerCase().replace(/^[./\\]+/, "");
|
|
33841
34398
|
const fileBase = basename2(targetFile).toLowerCase();
|
|
34399
|
+
const symbolRegex = targetSymbol && targetSymbol.length > 2 ? new RegExp(`\\b${targetSymbol.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&")}\\b`, "i") : null;
|
|
34400
|
+
const pathRegex = fileBase.length > 3 && fileBase !== "index.ts" && fileBase !== "index.js" ? new RegExp(`\\b${fileBase.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&")}\\b`, "i") : null;
|
|
33842
34401
|
for (const adr of allAdrs) {
|
|
33843
|
-
const text = `${adr.title} ${adr.content}
|
|
33844
|
-
const hasAnchor = adr.anchors?.some((a) =>
|
|
33845
|
-
|
|
34402
|
+
const text = `${adr.title} ${adr.content}`;
|
|
34403
|
+
const hasAnchor = adr.anchors?.some((a) => {
|
|
34404
|
+
const aPath = a.file_path.toLowerCase().replace(/^[./\\]+/, "");
|
|
34405
|
+
return aPath === normTarget || aPath.endsWith("/" + fileBase) || targetSymbol && a.symbol_name?.toLowerCase() === targetSymbol.toLowerCase();
|
|
34406
|
+
});
|
|
34407
|
+
const matchesSymbol = symbolRegex ? symbolRegex.test(text) : false;
|
|
34408
|
+
const matchesPath = pathRegex ? pathRegex.test(text) : false;
|
|
34409
|
+
if (hasAnchor || matchesSymbol || matchesPath) {
|
|
33846
34410
|
matchedAdrs.push({
|
|
33847
34411
|
id: adr.id,
|
|
33848
34412
|
title: adr.title,
|
|
@@ -33852,10 +34416,10 @@ async function analyzeMemoryCodeImpact(store, options) {
|
|
|
33852
34416
|
}
|
|
33853
34417
|
}
|
|
33854
34418
|
const activeConstraints = memoryRes.constraints.map((c) => c.title);
|
|
33855
|
-
const currentMdPath =
|
|
33856
|
-
if (
|
|
34419
|
+
const currentMdPath = join42(store.memoryDir || join42(root, ".memory"), "CURRENT.md");
|
|
34420
|
+
if (existsSync45(currentMdPath)) {
|
|
33857
34421
|
try {
|
|
33858
|
-
const currentContent =
|
|
34422
|
+
const currentContent = readFileSync38(currentMdPath, "utf8");
|
|
33859
34423
|
const lines = currentContent.split(`
|
|
33860
34424
|
`);
|
|
33861
34425
|
for (const line of lines) {
|
|
@@ -33875,14 +34439,14 @@ async function analyzeMemoryCodeImpact(store, options) {
|
|
|
33875
34439
|
totalMemoryEntities: linkedMemories.length + matchedAdrs.length + negativeWarnings.length + activeConstraints.length
|
|
33876
34440
|
};
|
|
33877
34441
|
const relatedDocs = [];
|
|
33878
|
-
const docsDir =
|
|
33879
|
-
if (
|
|
34442
|
+
const docsDir = join42(root, "docs");
|
|
34443
|
+
if (existsSync45(docsDir)) {
|
|
33880
34444
|
try {
|
|
33881
34445
|
const docFiles = readdirSync16(docsDir, { recursive: true });
|
|
33882
34446
|
for (const df of docFiles) {
|
|
33883
34447
|
if (typeof df === "string" && (df.endsWith(".md") || df.endsWith(".mdx"))) {
|
|
33884
|
-
const fullPath =
|
|
33885
|
-
const content =
|
|
34448
|
+
const fullPath = join42(docsDir, df);
|
|
34449
|
+
const content = readFileSync38(fullPath, "utf8").toLowerCase();
|
|
33886
34450
|
if (content.includes(fileBase) || targetSymbol && content.includes(targetSymbol.toLowerCase())) {
|
|
33887
34451
|
relatedDocs.push(`docs/${df}`);
|
|
33888
34452
|
}
|
|
@@ -33890,10 +34454,10 @@ async function analyzeMemoryCodeImpact(store, options) {
|
|
|
33890
34454
|
}
|
|
33891
34455
|
} catch {}
|
|
33892
34456
|
}
|
|
33893
|
-
const readmePath =
|
|
33894
|
-
if (
|
|
34457
|
+
const readmePath = join42(root, "README.md");
|
|
34458
|
+
if (existsSync45(readmePath)) {
|
|
33895
34459
|
try {
|
|
33896
|
-
const readmeContent =
|
|
34460
|
+
const readmeContent = readFileSync38(readmePath, "utf8").toLowerCase();
|
|
33897
34461
|
if (readmeContent.includes(fileBase) || targetSymbol && readmeContent.includes(targetSymbol.toLowerCase())) {
|
|
33898
34462
|
relatedDocs.push("README.md");
|
|
33899
34463
|
}
|
|
@@ -34058,8 +34622,8 @@ var init_intelligence = __esm(() => {
|
|
|
34058
34622
|
init_impact();
|
|
34059
34623
|
});
|
|
34060
34624
|
// src/compaction/engine.ts
|
|
34061
|
-
import { existsSync as
|
|
34062
|
-
import { join as
|
|
34625
|
+
import { existsSync as existsSync46, writeFileSync as writeFileSync25, mkdirSync as mkdirSync26 } from "node:fs";
|
|
34626
|
+
import { join as join43 } from "node:path";
|
|
34063
34627
|
function evaluateContextUsage(usedTokens, maxTokens = DEFAULT_CONTEXT_MAX_TOKENS) {
|
|
34064
34628
|
const usagePercent = Math.round(usedTokens / maxTokens * 100);
|
|
34065
34629
|
const thresholdExceeded = usagePercent >= COMPACTION_THRESHOLD_PERCENT;
|
|
@@ -34151,12 +34715,12 @@ function generateSessionHandoff(memoryDir, invariants, options) {
|
|
|
34151
34715
|
if (!invariants.highLevelGoal || !invariants.nextConcreteTask) {
|
|
34152
34716
|
throw new Error("Cannot generate handoff: highLevelGoal and nextConcreteTask are mandatory");
|
|
34153
34717
|
}
|
|
34154
|
-
if (!
|
|
34718
|
+
if (!existsSync46(memoryDir)) {
|
|
34155
34719
|
mkdirSync26(memoryDir, { recursive: true });
|
|
34156
34720
|
}
|
|
34157
|
-
const currentMdPath =
|
|
34721
|
+
const currentMdPath = join43(memoryDir, "CURRENT.md");
|
|
34158
34722
|
const markdownContent = renderCurrentMdContent(invariants, options);
|
|
34159
|
-
|
|
34723
|
+
writeFileSync25(currentMdPath, markdownContent, "utf8");
|
|
34160
34724
|
recordAuditEvent(memoryDir, {
|
|
34161
34725
|
operation: "checkpoint",
|
|
34162
34726
|
entry_id: "CURRENT.md",
|
|
@@ -34295,28 +34859,38 @@ var init_harvester2 = __esm(() => {
|
|
|
34295
34859
|
});
|
|
34296
34860
|
|
|
34297
34861
|
// src/compaction/pr-context.ts
|
|
34298
|
-
import {
|
|
34299
|
-
import { existsSync as
|
|
34300
|
-
import { join as
|
|
34862
|
+
import { execFileSync } from "node:child_process";
|
|
34863
|
+
import { existsSync as existsSync47, readFileSync as readFileSync39 } from "node:fs";
|
|
34864
|
+
import { join as join44, basename as basename3 } from "node:path";
|
|
34301
34865
|
async function generatePrContext(store, options = {}) {
|
|
34302
34866
|
const root = options.workspaceRoot || store.dir || process.cwd();
|
|
34303
|
-
const
|
|
34867
|
+
const rawBase = options.baseBranch || "main";
|
|
34868
|
+
const safeBase = /^[a-zA-Z0-9._\/-]+$/.test(rawBase) ? rawBase : "main";
|
|
34304
34869
|
let changedFiles = [];
|
|
34305
34870
|
try {
|
|
34306
|
-
const
|
|
34307
|
-
|
|
34871
|
+
const stdout = execFileSync("git", ["diff", "--name-only", `${safeBase}...HEAD`], {
|
|
34872
|
+
cwd: root,
|
|
34873
|
+
encoding: "utf8",
|
|
34874
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
34875
|
+
});
|
|
34308
34876
|
changedFiles = stdout.split(`
|
|
34309
34877
|
`).map((f) => f.trim()).filter(Boolean);
|
|
34310
34878
|
} catch {
|
|
34311
34879
|
try {
|
|
34312
|
-
const
|
|
34313
|
-
|
|
34880
|
+
const stdout = execFileSync("git", ["diff", "--name-only", "HEAD~1"], {
|
|
34881
|
+
cwd: root,
|
|
34882
|
+
encoding: "utf8",
|
|
34883
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
34884
|
+
});
|
|
34314
34885
|
changedFiles = stdout.split(`
|
|
34315
34886
|
`).map((f) => f.trim()).filter(Boolean);
|
|
34316
34887
|
} catch {
|
|
34317
34888
|
try {
|
|
34318
|
-
const
|
|
34319
|
-
|
|
34889
|
+
const stdout = execFileSync("git", ["status", "--porcelain"], {
|
|
34890
|
+
cwd: root,
|
|
34891
|
+
encoding: "utf8",
|
|
34892
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
34893
|
+
});
|
|
34320
34894
|
changedFiles = stdout.split(`
|
|
34321
34895
|
`).map((l) => l.slice(3).trim()).filter(Boolean);
|
|
34322
34896
|
} catch {
|
|
@@ -34358,10 +34932,10 @@ async function generatePrContext(store, options = {}) {
|
|
|
34358
34932
|
} catch {}
|
|
34359
34933
|
}
|
|
34360
34934
|
const activeConstraints = [];
|
|
34361
|
-
const currentMdPath =
|
|
34362
|
-
if (
|
|
34935
|
+
const currentMdPath = join44(store.memoryDir || join44(root, ".memory"), "CURRENT.md");
|
|
34936
|
+
if (existsSync47(currentMdPath)) {
|
|
34363
34937
|
try {
|
|
34364
|
-
const lines =
|
|
34938
|
+
const lines = readFileSync39(currentMdPath, "utf8").split(`
|
|
34365
34939
|
`);
|
|
34366
34940
|
for (const line of lines) {
|
|
34367
34941
|
const trimmed = line.trim();
|
|
@@ -34472,7 +35046,7 @@ async function generatePrContext(store, options = {}) {
|
|
|
34472
35046
|
return {
|
|
34473
35047
|
title: prTitle,
|
|
34474
35048
|
bodyMarkdown: md,
|
|
34475
|
-
baseBranch:
|
|
35049
|
+
baseBranch: safeBase,
|
|
34476
35050
|
changedFiles,
|
|
34477
35051
|
anchorsTouched: totalAnchorsTouched,
|
|
34478
35052
|
adrsInvolved,
|
|
@@ -34514,8 +35088,6 @@ var init_anchors = __esm(() => {
|
|
|
34514
35088
|
init_resolver();
|
|
34515
35089
|
});
|
|
34516
35090
|
// src/orchestrator/context.ts
|
|
34517
|
-
import { existsSync as existsSync47, readFileSync as readFileSync39 } from "node:fs";
|
|
34518
|
-
import { join as join44 } from "node:path";
|
|
34519
35091
|
function estimateTokens(text) {
|
|
34520
35092
|
return Math.max(1, Math.ceil(text.length / 4));
|
|
34521
35093
|
}
|
|
@@ -34542,18 +35114,29 @@ async function resolveMuseContext(store, workspaceRoot, input) {
|
|
|
34542
35114
|
const compositeQuery = queryParts.join(" ") || "active constraints and architecture";
|
|
34543
35115
|
const activeConstraints = [];
|
|
34544
35116
|
if (store.memoryDir) {
|
|
34545
|
-
|
|
34546
|
-
|
|
34547
|
-
|
|
34548
|
-
const constraintMatch = currentMd.match(/## Active Working Constraints & Open Loops([\s\S]*?)(?:##|$)/);
|
|
34549
|
-
if (constraintMatch && constraintMatch[1].trim()) {
|
|
35117
|
+
try {
|
|
35118
|
+
const currentData = parseCurrentFile(store.memoryDir);
|
|
35119
|
+
if (currentData.constraints.length > 0) {
|
|
34550
35120
|
activeConstraints.push({
|
|
34551
35121
|
id: "current_md_constraints",
|
|
34552
35122
|
title: "Session Working Constraints",
|
|
34553
|
-
content:
|
|
35123
|
+
content: currentData.constraints.join(`
|
|
35124
|
+
`)
|
|
34554
35125
|
});
|
|
34555
35126
|
}
|
|
34556
|
-
|
|
35127
|
+
if (currentData.workstreams && currentData.workstreams.length > 0) {
|
|
35128
|
+
const activeWs = currentData.workstreams.filter((w) => w.status === "IN-PROGRESS" || w.status === "BLOCKED");
|
|
35129
|
+
if (activeWs.length > 0) {
|
|
35130
|
+
const wsSummary = activeWs.map((w) => `- Agent \`${w.agent}\` [${w.status}]: ${w.task}${w.targetScope ? ` (Scope: ${w.targetScope})` : ""}`).join(`
|
|
35131
|
+
`);
|
|
35132
|
+
activeConstraints.push({
|
|
35133
|
+
id: "concurrent_workstreams",
|
|
35134
|
+
title: "Active Concurrent Agent Workstreams",
|
|
35135
|
+
content: wsSummary
|
|
35136
|
+
});
|
|
35137
|
+
}
|
|
35138
|
+
}
|
|
35139
|
+
} catch {}
|
|
34557
35140
|
}
|
|
34558
35141
|
const allEntries = list(store);
|
|
34559
35142
|
const constraintEntries = allEntries.filter((e) => (e.type === "constraint" || e.temporal_mode === "timeless") && e.status !== "archived" && e.status !== "superseded" && e.status !== "rejected");
|
|
@@ -34669,6 +35252,7 @@ ${c.content}`);
|
|
|
34669
35252
|
var init_context = __esm(() => {
|
|
34670
35253
|
init_store();
|
|
34671
35254
|
init_ranking();
|
|
35255
|
+
init_governor();
|
|
34672
35256
|
});
|
|
34673
35257
|
|
|
34674
35258
|
// src/orchestrator/profiles.ts
|
|
@@ -34807,7 +35391,7 @@ var init_orchestrator = __esm(() => {
|
|
|
34807
35391
|
});
|
|
34808
35392
|
|
|
34809
35393
|
// src/prompts.ts
|
|
34810
|
-
import { existsSync as existsSync48, readFileSync as readFileSync40, writeFileSync as
|
|
35394
|
+
import { existsSync as existsSync48, readFileSync as readFileSync40, writeFileSync as writeFileSync26, mkdirSync as mkdirSync27, readdirSync as readdirSync17 } from "node:fs";
|
|
34811
35395
|
import { join as join45 } from "node:path";
|
|
34812
35396
|
function getPromptsDir(memoryDir) {
|
|
34813
35397
|
if (!memoryDir)
|
|
@@ -34996,7 +35580,7 @@ Period: {{period}}
|
|
|
34996
35580
|
});
|
|
34997
35581
|
|
|
34998
35582
|
// src/compounding/temporal.ts
|
|
34999
|
-
import { existsSync as existsSync49, readFileSync as readFileSync41, writeFileSync as
|
|
35583
|
+
import { existsSync as existsSync49, readFileSync as readFileSync41, writeFileSync as writeFileSync27, mkdirSync as mkdirSync28 } from "node:fs";
|
|
35000
35584
|
import { join as join46 } from "node:path";
|
|
35001
35585
|
function getPeriodKey(dateInput, period) {
|
|
35002
35586
|
const date4 = typeof dateInput === "string" ? new Date(dateInput) : dateInput;
|
|
@@ -35066,7 +35650,7 @@ function compileHotCache(store, memoryDir) {
|
|
|
35066
35650
|
`;
|
|
35067
35651
|
const hotPath = join46(memoryDir, "HOT.md");
|
|
35068
35652
|
mkdirSync28(memoryDir, { recursive: true });
|
|
35069
|
-
|
|
35653
|
+
writeFileSync27(hotPath, hotContent, "utf-8");
|
|
35070
35654
|
return hotPath;
|
|
35071
35655
|
}
|
|
35072
35656
|
function rollupTemporal(store, options) {
|
|
@@ -35120,7 +35704,7 @@ function rollupTemporal(store, options) {
|
|
|
35120
35704
|
const rollupDir = join46(memoryDir, "wiki", "rollups");
|
|
35121
35705
|
mkdirSync28(rollupDir, { recursive: true });
|
|
35122
35706
|
const filePath = join46(rollupDir, `${periodKey}.md`);
|
|
35123
|
-
|
|
35707
|
+
writeFileSync27(filePath, lines.join(`
|
|
35124
35708
|
`) + `
|
|
35125
35709
|
`, "utf-8");
|
|
35126
35710
|
const hotMdPath = compileHotCache(store, memoryDir);
|
|
@@ -35137,7 +35721,7 @@ var init_temporal = __esm(() => {
|
|
|
35137
35721
|
});
|
|
35138
35722
|
|
|
35139
35723
|
// src/iterations.ts
|
|
35140
|
-
import { existsSync as existsSync50, readFileSync as readFileSync42, appendFileSync as appendFileSync3, writeFileSync as
|
|
35724
|
+
import { existsSync as existsSync50, readFileSync as readFileSync42, appendFileSync as appendFileSync3, writeFileSync as writeFileSync28, mkdirSync as mkdirSync29 } from "node:fs";
|
|
35141
35725
|
import { join as join47 } from "node:path";
|
|
35142
35726
|
function getIterationsFilePath(memoryDir) {
|
|
35143
35727
|
return join47(memoryDir, "iterations.jsonl");
|
|
@@ -35180,7 +35764,7 @@ function listIterations(memoryDir) {
|
|
|
35180
35764
|
function clearIterations(memoryDir) {
|
|
35181
35765
|
const filePath = getIterationsFilePath(memoryDir);
|
|
35182
35766
|
if (existsSync50(filePath)) {
|
|
35183
|
-
|
|
35767
|
+
writeFileSync28(filePath, "", "utf-8");
|
|
35184
35768
|
}
|
|
35185
35769
|
}
|
|
35186
35770
|
function detectIterationStatus(memoryDir) {
|
|
@@ -35241,7 +35825,7 @@ __export(exports_plasticity, {
|
|
|
35241
35825
|
recordCoActivation: () => recordCoActivation,
|
|
35242
35826
|
saveHebbianGraph: () => saveHebbianGraph
|
|
35243
35827
|
});
|
|
35244
|
-
import { existsSync as existsSync51, readFileSync as readFileSync43, writeFileSync as
|
|
35828
|
+
import { existsSync as existsSync51, readFileSync as readFileSync43, writeFileSync as writeFileSync29 } from "node:fs";
|
|
35245
35829
|
import { join as join48 } from "node:path";
|
|
35246
35830
|
function getPlasticityPath(memoryDir) {
|
|
35247
35831
|
return join48(memoryDir, "hebbian-plasticity.json");
|
|
@@ -35259,7 +35843,7 @@ function loadHebbianGraph(memoryDir) {
|
|
|
35259
35843
|
function saveHebbianGraph(memoryDir, graph) {
|
|
35260
35844
|
const p = getPlasticityPath(memoryDir);
|
|
35261
35845
|
try {
|
|
35262
|
-
|
|
35846
|
+
writeFileSync29(p, JSON.stringify(graph, null, 2), "utf8");
|
|
35263
35847
|
} catch {}
|
|
35264
35848
|
}
|
|
35265
35849
|
function recordCoActivation(memoryIds, memoryDir) {
|
|
@@ -35349,7 +35933,7 @@ __export(exports_drift, {
|
|
|
35349
35933
|
scanCodeDrift: () => scanCodeDrift,
|
|
35350
35934
|
scanCodeDriftFromDiff: () => scanCodeDriftFromDiff
|
|
35351
35935
|
});
|
|
35352
|
-
import { execSync as
|
|
35936
|
+
import { execSync as execSync3 } from "node:child_process";
|
|
35353
35937
|
import { existsSync as existsSync52 } from "node:fs";
|
|
35354
35938
|
import { join as join49, isAbsolute as isAbsolute2 } from "node:path";
|
|
35355
35939
|
function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
|
|
@@ -35390,7 +35974,7 @@ function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
|
|
|
35390
35974
|
function getGitChangedFiles(workspaceRoot) {
|
|
35391
35975
|
const root = workspaceRoot || process.cwd();
|
|
35392
35976
|
try {
|
|
35393
|
-
const stdout =
|
|
35977
|
+
const stdout = execSync3("git status --porcelain", {
|
|
35394
35978
|
cwd: root,
|
|
35395
35979
|
encoding: "utf8",
|
|
35396
35980
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -35407,7 +35991,7 @@ function getGitChangedFiles(workspaceRoot) {
|
|
|
35407
35991
|
files.push(filePath);
|
|
35408
35992
|
}
|
|
35409
35993
|
try {
|
|
35410
|
-
const diffOut =
|
|
35994
|
+
const diffOut = execSync3("git diff --name-only HEAD", {
|
|
35411
35995
|
cwd: root,
|
|
35412
35996
|
encoding: "utf8",
|
|
35413
35997
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -38079,7 +38663,7 @@ var init_daemon = () => {};
|
|
|
38079
38663
|
|
|
38080
38664
|
// src/cli/ecosystem.ts
|
|
38081
38665
|
import { join as join51 } from "node:path";
|
|
38082
|
-
import { existsSync as existsSync54, mkdirSync as mkdirSync30, writeFileSync as
|
|
38666
|
+
import { existsSync as existsSync54, mkdirSync as mkdirSync30, writeFileSync as writeFileSync30, readFileSync as readFileSync44 } from "node:fs";
|
|
38083
38667
|
import { homedir as homedir7 } from "node:os";
|
|
38084
38668
|
function ensureProjectAgentInstructions(targetDir) {
|
|
38085
38669
|
const agentsMdPath = join51(targetDir, "AGENTS.md");
|
|
@@ -38088,9 +38672,9 @@ function ensureProjectAgentInstructions(targetDir) {
|
|
|
38088
38672
|
const existing = readFileSync44(agentsMdPath, "utf8");
|
|
38089
38673
|
if (existing.includes("<!-- agentmemory:start -->")) {
|
|
38090
38674
|
const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
|
|
38091
|
-
|
|
38675
|
+
writeFileSync30(agentsMdPath, updated, "utf8");
|
|
38092
38676
|
} else if (!existing.includes("<!-- musememory:start -->") && !existing.includes("Muse Memory")) {
|
|
38093
|
-
|
|
38677
|
+
writeFileSync30(agentsMdPath, `${existing.trim()}
|
|
38094
38678
|
|
|
38095
38679
|
${MUSE_MEMORY_DIRECTIVE}
|
|
38096
38680
|
`, "utf8");
|
|
@@ -38101,7 +38685,7 @@ ${MUSE_MEMORY_DIRECTIVE}
|
|
|
38101
38685
|
|
|
38102
38686
|
${MUSE_MEMORY_DIRECTIVE}
|
|
38103
38687
|
`;
|
|
38104
|
-
|
|
38688
|
+
writeFileSync30(agentsMdPath, initialContent, "utf8");
|
|
38105
38689
|
}
|
|
38106
38690
|
}
|
|
38107
38691
|
async function handleInstallCommand({ positional, flags }) {
|
|
@@ -38113,7 +38697,7 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
38113
38697
|
mkdirSync30(join51(globalDir, "memories"), { recursive: true });
|
|
38114
38698
|
const currentPath = join51(memoryDir, "CURRENT.md");
|
|
38115
38699
|
if (!existsSync54(currentPath)) {
|
|
38116
|
-
|
|
38700
|
+
writeFileSync30(currentPath, `# Active Project Constraints
|
|
38117
38701
|
`, "utf8");
|
|
38118
38702
|
}
|
|
38119
38703
|
const globalUserPath = userFilePath(globalDir);
|
|
@@ -38139,7 +38723,7 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
38139
38723
|
const existing = readFileSync44(globalAgentsMd, "utf8");
|
|
38140
38724
|
if (existing.includes("<!-- agentmemory:start -->")) {
|
|
38141
38725
|
const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
|
|
38142
|
-
|
|
38726
|
+
writeFileSync30(globalAgentsMd, updated, "utf8");
|
|
38143
38727
|
}
|
|
38144
38728
|
} catch {}
|
|
38145
38729
|
}
|
|
@@ -38298,7 +38882,7 @@ async function handleInitCommand({ positional, flags }) {
|
|
|
38298
38882
|
mkdirSync30(join51(memoryDir, "memories"), { recursive: true });
|
|
38299
38883
|
const currentPath = join51(memoryDir, "CURRENT.md");
|
|
38300
38884
|
if (!existsSync54(currentPath)) {
|
|
38301
|
-
|
|
38885
|
+
writeFileSync30(currentPath, `# Active Project Constraints
|
|
38302
38886
|
`, "utf8");
|
|
38303
38887
|
}
|
|
38304
38888
|
if (!isGlobal) {
|
|
@@ -39261,7 +39845,7 @@ var init_entities2 = __esm(() => {
|
|
|
39261
39845
|
});
|
|
39262
39846
|
|
|
39263
39847
|
// src/cli/settings.ts
|
|
39264
|
-
import { writeFileSync as
|
|
39848
|
+
import { writeFileSync as writeFileSync31, readFileSync as readFileSync46 } from "node:fs";
|
|
39265
39849
|
function handleSettingsCommand(parsed) {
|
|
39266
39850
|
const ctx = requireRoot(parsed.flags);
|
|
39267
39851
|
if (!ctx)
|
|
@@ -39343,7 +39927,7 @@ function handleSettingsCommand(parsed) {
|
|
|
39343
39927
|
const out = parsed.flags.out;
|
|
39344
39928
|
const json2 = exportSettings(memoryDir);
|
|
39345
39929
|
if (out) {
|
|
39346
|
-
|
|
39930
|
+
writeFileSync31(out, json2, "utf8");
|
|
39347
39931
|
console.log(`Exported settings to ${out}`);
|
|
39348
39932
|
} else {
|
|
39349
39933
|
console.log(json2);
|
|
@@ -39427,7 +40011,7 @@ var init_routines = __esm(() => {
|
|
|
39427
40011
|
});
|
|
39428
40012
|
|
|
39429
40013
|
// src/cli/lifecycle.ts
|
|
39430
|
-
import { writeFileSync as
|
|
40014
|
+
import { writeFileSync as writeFileSync32, readFileSync as readFileSync48, existsSync as existsSync58 } from "node:fs";
|
|
39431
40015
|
async function handleProposeCommand({ positional, flags }) {
|
|
39432
40016
|
const ctx = requireRoot(flags);
|
|
39433
40017
|
if (!ctx)
|
|
@@ -39576,7 +40160,7 @@ async function handleExportCommand({ flags }) {
|
|
|
39576
40160
|
const snapshot = exportSnapshot(ctx.store);
|
|
39577
40161
|
const outPath = flags["out"];
|
|
39578
40162
|
if (outPath) {
|
|
39579
|
-
|
|
40163
|
+
writeFileSync32(outPath, JSON.stringify(snapshot, null, 2), "utf8");
|
|
39580
40164
|
console.log(`exported ${snapshot.total} memories to ${outPath}`);
|
|
39581
40165
|
} else {
|
|
39582
40166
|
console.log(JSON.stringify(snapshot, null, 2));
|
|
@@ -39776,6 +40360,58 @@ async function handleConsolidateCommand({ flags }) {
|
|
|
39776
40360
|
}
|
|
39777
40361
|
return 0;
|
|
39778
40362
|
}
|
|
40363
|
+
async function handleOptimizeCommand({ flags }) {
|
|
40364
|
+
const ctx = requireRoot(flags);
|
|
40365
|
+
if (!ctx)
|
|
40366
|
+
return 1;
|
|
40367
|
+
const isDryRun = flags["dry-run"] === "true";
|
|
40368
|
+
const force = flags["force"] !== "false";
|
|
40369
|
+
const project = flags["project"];
|
|
40370
|
+
console.log(`
|
|
40371
|
+
====================================================`);
|
|
40372
|
+
console.log(` ⚡ Muse Memory Optimizer ${isDryRun ? "(DRY-RUN)" : ""}`);
|
|
40373
|
+
console.log(`====================================================`);
|
|
40374
|
+
if (project)
|
|
40375
|
+
console.log(`Scope: Project '${project}'`);
|
|
40376
|
+
console.log(`Store: ${ctx.memoryDir}
|
|
40377
|
+
`);
|
|
40378
|
+
const report = optimizeStore(ctx.store, {
|
|
40379
|
+
project,
|
|
40380
|
+
dryRun: isDryRun,
|
|
40381
|
+
force,
|
|
40382
|
+
memoryDir: ctx.memoryDir
|
|
40383
|
+
});
|
|
40384
|
+
if (report.skippedReason) {
|
|
40385
|
+
console.log(`ℹ️ Optimization skipped: ${report.skippedReason}`);
|
|
40386
|
+
console.log(`Tip: Pass --force to run immediately regardless of cadence.`);
|
|
40387
|
+
return 0;
|
|
40388
|
+
}
|
|
40389
|
+
const formatBytes = (bytes) => {
|
|
40390
|
+
if (bytes >= 1024 * 1024)
|
|
40391
|
+
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
40392
|
+
if (bytes >= 1024)
|
|
40393
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
40394
|
+
return `${bytes} B`;
|
|
40395
|
+
};
|
|
40396
|
+
console.log(`Results:`);
|
|
40397
|
+
console.log(` - Pruned Test Noise: ${report.prunedNoise} items`);
|
|
40398
|
+
console.log(` - Pruned Junk Fragments: ${report.prunedJunk} items`);
|
|
40399
|
+
console.log(` - Pruned Duplicates: ${report.prunedDuplicates} items`);
|
|
40400
|
+
console.log(` -----------------------------------------`);
|
|
40401
|
+
console.log(` - Total Items Pruned: ${report.totalPruned} items`);
|
|
40402
|
+
console.log(` - Total Before: ${report.totalBefore} items`);
|
|
40403
|
+
console.log(` - Total After: ${report.totalAfter} items`);
|
|
40404
|
+
if (report.spaceReclaimedBytes > 0) {
|
|
40405
|
+
console.log(` - Storage Reclaimed: ${formatBytes(report.spaceReclaimedBytes)}`);
|
|
40406
|
+
}
|
|
40407
|
+
if (report.vacuumExecuted) {
|
|
40408
|
+
console.log(` - SQLite Vacuum: Executed (Defragmented)`);
|
|
40409
|
+
}
|
|
40410
|
+
console.log(` - Duration: ${report.durationMs}ms
|
|
40411
|
+
`);
|
|
40412
|
+
console.log(`✅ Optimization successfully completed.`);
|
|
40413
|
+
return 0;
|
|
40414
|
+
}
|
|
39779
40415
|
async function handleTraceCommand({ positional, flags }) {
|
|
39780
40416
|
const ctx = requireRoot(flags);
|
|
39781
40417
|
if (!ctx)
|
|
@@ -39946,6 +40582,7 @@ var init_lifecycle = __esm(() => {
|
|
|
39946
40582
|
init_store();
|
|
39947
40583
|
init_retrieval();
|
|
39948
40584
|
init_consolidate();
|
|
40585
|
+
init_optimize();
|
|
39949
40586
|
init_trace();
|
|
39950
40587
|
init_loops();
|
|
39951
40588
|
init_nudge();
|
|
@@ -40249,8 +40886,9 @@ async function runMemoryBenchmark(store, options = {}) {
|
|
|
40249
40886
|
const iterations = options.iterations || 30;
|
|
40250
40887
|
const testQuery = options.query || "authentication architecture security";
|
|
40251
40888
|
const tokenBudget = options.tokenBudget || 1500;
|
|
40252
|
-
const allEntries = list(store);
|
|
40253
40889
|
const coldStartT0 = performance.now();
|
|
40890
|
+
const coldStore = openStore(store.memoryDir || store.dir);
|
|
40891
|
+
const allEntries = list(coldStore);
|
|
40254
40892
|
const entriesCount = allEntries.length;
|
|
40255
40893
|
const cold_startup_ms = Math.round((performance.now() - coldStartT0) * 100) / 100;
|
|
40256
40894
|
const hotSamplesUs = [];
|
|
@@ -40473,10 +41111,11 @@ async function handleReconcileCommand(parsed) {
|
|
|
40473
41111
|
return 1;
|
|
40474
41112
|
}
|
|
40475
41113
|
const { root, store } = ctx;
|
|
40476
|
-
const
|
|
40477
|
-
const
|
|
40478
|
-
const
|
|
40479
|
-
const
|
|
41114
|
+
const isTrue = (val) => val === true || val === "true" || val === "";
|
|
41115
|
+
const prune = isTrue(parsed.flags["prune"]) || isTrue(parsed.flags["p"]);
|
|
41116
|
+
const markStale2 = isTrue(parsed.flags["mark-stale"]) || isTrue(parsed.flags["stale"]);
|
|
41117
|
+
const updateHashes = isTrue(parsed.flags["update-hashes"]);
|
|
41118
|
+
const dryRun = isTrue(parsed.flags["dry-run"]) || !prune && !markStale2 && !updateHashes;
|
|
40480
41119
|
const { reconcileCodeAnchors: reconcileCodeAnchors2, formatReconcileReport: formatReconcileReport2 } = await Promise.resolve().then(() => (init_health(), exports_health));
|
|
40481
41120
|
const report = await reconcileCodeAnchors2(store, {
|
|
40482
41121
|
prune,
|
|
@@ -40557,9 +41196,9 @@ async function handlePrContextCommand(parsed) {
|
|
|
40557
41196
|
});
|
|
40558
41197
|
const outFile = parsed.flags["out"];
|
|
40559
41198
|
if (outFile) {
|
|
40560
|
-
const { writeFileSync:
|
|
41199
|
+
const { writeFileSync: writeFileSync33 } = await import("node:fs");
|
|
40561
41200
|
const { resolve: resolve4 } = await import("node:path");
|
|
40562
|
-
|
|
41201
|
+
writeFileSync33(resolve4(root, outFile), result.bodyMarkdown, "utf8");
|
|
40563
41202
|
console.log(`[+] Wrote PR context description to ${outFile}`);
|
|
40564
41203
|
return 0;
|
|
40565
41204
|
}
|
|
@@ -40579,7 +41218,7 @@ var init_health2 = __esm(() => {
|
|
|
40579
41218
|
});
|
|
40580
41219
|
|
|
40581
41220
|
// src/cli/sync.ts
|
|
40582
|
-
import { writeFileSync as
|
|
41221
|
+
import { writeFileSync as writeFileSync33, readFileSync as readFileSync49 } from "node:fs";
|
|
40583
41222
|
import { resolve as resolve4 } from "node:path";
|
|
40584
41223
|
async function handleSyncCommand(parsed) {
|
|
40585
41224
|
const ctx = requireRoot(parsed.flags);
|
|
@@ -40596,7 +41235,7 @@ async function handleSyncCommand(parsed) {
|
|
|
40596
41235
|
});
|
|
40597
41236
|
if (parsed.flags.out) {
|
|
40598
41237
|
const outPath = resolve4(process.cwd(), parsed.flags.out);
|
|
40599
|
-
|
|
41238
|
+
writeFileSync33(outPath, JSON.stringify(packet2, null, 2), "utf-8");
|
|
40600
41239
|
console.log(`\x1B[32m✓ Broadcast packet saved to '${outPath}' (${packet2.payload.memories.length} memories)\x1B[0m`);
|
|
40601
41240
|
} else {
|
|
40602
41241
|
console.log(JSON.stringify(packet2, null, 2));
|
|
@@ -40942,6 +41581,8 @@ async function main(argv) {
|
|
|
40942
41581
|
return handleStaleCommand(parsed);
|
|
40943
41582
|
case "consolidate":
|
|
40944
41583
|
return handleConsolidateCommand(parsed);
|
|
41584
|
+
case "optimize":
|
|
41585
|
+
return handleOptimizeCommand(parsed);
|
|
40945
41586
|
case "trace":
|
|
40946
41587
|
return handleTraceCommand(parsed);
|
|
40947
41588
|
case "loops":
|
|
@@ -41024,6 +41665,7 @@ Core Memory Lifecycle Commands:
|
|
|
41024
41665
|
stats Display total memory counts and status/type distribution
|
|
41025
41666
|
stale [--days N] List entries exceeding staleness policy
|
|
41026
41667
|
consolidate [--project P] [--dry-run] Cluster confirmed memories into scene rollups
|
|
41668
|
+
optimize [--dry-run] [--project P] [--force] Prune test noise, junk, duplicates & vacuum SQLite DB
|
|
41027
41669
|
trace <id> [--depth N] Walk causal graph pathways from an entry (default depth 5)
|
|
41028
41670
|
loops Prioritized open-loop report: git state, stale candidates, constraints
|
|
41029
41671
|
nudge Proactive attention list: overdue/due-soon entries, stale-by-policy, open loops
|