musememory 2.1.0 → 2.2.1
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 +7 -2
- package/.agents/skills/muse-drift/SKILL.md +70 -0
- package/.agents/skills/muse-health/SKILL.md +56 -0
- package/.agents/skills/muse-mesh/SKILL.md +66 -0
- package/.agents/skills/muse-sync/SKILL.md +63 -0
- package/.agents/skills/muse-why/SKILL.md +60 -0
- package/README.md +68 -59
- package/dist/index.js +1329 -203
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5720,6 +5720,8 @@ function openDatabase(dbPath) {
|
|
|
5720
5720
|
rawDb = new Database(dbPath, { create: true });
|
|
5721
5721
|
rawDb.run("PRAGMA journal_mode = WAL;");
|
|
5722
5722
|
rawDb.run("PRAGMA synchronous = NORMAL;");
|
|
5723
|
+
rawDb.run("PRAGMA busy_timeout = 5000;");
|
|
5724
|
+
rawDb.run("PRAGMA foreign_keys = ON;");
|
|
5723
5725
|
rawDb.run("PRAGMA cache_size = -64000;");
|
|
5724
5726
|
rawDb.run("PRAGMA mmap_size = 268435456;");
|
|
5725
5727
|
rawDb.run("PRAGMA temp_store = MEMORY;");
|
|
@@ -5758,6 +5760,8 @@ function openDatabase(dbPath) {
|
|
|
5758
5760
|
rawDb = new DatabaseSync(dbPath);
|
|
5759
5761
|
rawDb.exec("PRAGMA journal_mode = WAL;");
|
|
5760
5762
|
rawDb.exec("PRAGMA synchronous = NORMAL;");
|
|
5763
|
+
rawDb.exec("PRAGMA busy_timeout = 5000;");
|
|
5764
|
+
rawDb.exec("PRAGMA foreign_keys = ON;");
|
|
5761
5765
|
rawDb.exec("PRAGMA cache_size = -64000;");
|
|
5762
5766
|
rawDb.exec("PRAGMA mmap_size = 268435456;");
|
|
5763
5767
|
rawDb.exec("PRAGMA temp_store = MEMORY;");
|
|
@@ -6709,19 +6713,52 @@ function list(store, filters) {
|
|
|
6709
6713
|
if (cached)
|
|
6710
6714
|
return cached;
|
|
6711
6715
|
}
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6716
|
+
let entries = [];
|
|
6717
|
+
if (store.db) {
|
|
6718
|
+
entries = listMemories(store.db, filters);
|
|
6719
|
+
if (existsSync10(store.dir)) {
|
|
6720
|
+
const dbIds = new Set(entries.map((e) => e.id));
|
|
6721
|
+
const diskFiles = readdirSync2(store.dir);
|
|
6722
|
+
for (const f of diskFiles) {
|
|
6723
|
+
if (f.endsWith(".yaml")) {
|
|
6724
|
+
const diskId = f.slice(0, -5);
|
|
6725
|
+
if (!dbIds.has(diskId)) {
|
|
6726
|
+
const externalEntry = get(store, diskId);
|
|
6727
|
+
if (externalEntry) {
|
|
6728
|
+
try {
|
|
6729
|
+
insertOrReplaceMemory(store.db, externalEntry);
|
|
6730
|
+
} catch {}
|
|
6731
|
+
let matches = true;
|
|
6732
|
+
if (filters?.project && externalEntry.project !== filters.project)
|
|
6733
|
+
matches = false;
|
|
6734
|
+
if (filters?.type && externalEntry.type !== filters.type)
|
|
6735
|
+
matches = false;
|
|
6736
|
+
if (filters?.status && externalEntry.status !== filters.status)
|
|
6737
|
+
matches = false;
|
|
6738
|
+
if (matches)
|
|
6739
|
+
entries.push(externalEntry);
|
|
6740
|
+
}
|
|
6741
|
+
}
|
|
6742
|
+
}
|
|
6743
|
+
}
|
|
6744
|
+
}
|
|
6745
|
+
} else {
|
|
6746
|
+
const ids = listIds(store);
|
|
6747
|
+
entries = ids.map((id) => get(store, id)).filter((e) => e !== null);
|
|
6748
|
+
if (filters?.project)
|
|
6749
|
+
entries = entries.filter((e) => e.project === filters.project);
|
|
6750
|
+
if (filters?.type)
|
|
6751
|
+
entries = entries.filter((e) => e.type === filters.type);
|
|
6752
|
+
if (filters?.status)
|
|
6753
|
+
entries = entries.filter((e) => e.status === filters.status);
|
|
6754
|
+
}
|
|
6721
6755
|
if (store.cache) {
|
|
6722
|
-
store.cache.setQuery(cacheKey,
|
|
6756
|
+
store.cache.setQuery(cacheKey, entries, undefined, dirMtime);
|
|
6757
|
+
for (const e of entries) {
|
|
6758
|
+
store.cache.setEntry(e);
|
|
6759
|
+
}
|
|
6723
6760
|
}
|
|
6724
|
-
return
|
|
6761
|
+
return entries;
|
|
6725
6762
|
}
|
|
6726
6763
|
function extractEntryText(entry) {
|
|
6727
6764
|
const parts = [
|
|
@@ -6756,7 +6793,9 @@ function save(store, entry, options = {}) {
|
|
|
6756
6793
|
try {
|
|
6757
6794
|
mtimeMs = statSync(file).mtimeMs;
|
|
6758
6795
|
} catch {}
|
|
6759
|
-
} catch {
|
|
6796
|
+
} catch (err) {
|
|
6797
|
+
console.warn(`[WARN] Dual-write YAML failed for memory '${entry.id}':`, err instanceof Error ? err.message : String(err));
|
|
6798
|
+
}
|
|
6760
6799
|
if (store.cache) {
|
|
6761
6800
|
store.cache.setEntry(entry, undefined, mtimeMs);
|
|
6762
6801
|
}
|
|
@@ -20555,9 +20594,219 @@ var init_gate = __esm(() => {
|
|
|
20555
20594
|
init_clustering();
|
|
20556
20595
|
});
|
|
20557
20596
|
|
|
20597
|
+
// src/health/reconcile.ts
|
|
20598
|
+
import { basename } from "node:path";
|
|
20599
|
+
async function reconcileCodeAnchors(store, options = {}) {
|
|
20600
|
+
const root = options.workspaceRoot || store.dir || process.cwd();
|
|
20601
|
+
const dryRun = options.dryRun === true;
|
|
20602
|
+
const prune = options.prune === true;
|
|
20603
|
+
const markStale2 = options.markStale === true;
|
|
20604
|
+
const updateHashes = options.updateHashes === true;
|
|
20605
|
+
const actor = options.actor || "reconciler";
|
|
20606
|
+
const entries = list(store);
|
|
20607
|
+
let totalAuditedEntries = 0;
|
|
20608
|
+
let totalAnchors = 0;
|
|
20609
|
+
let validCount = 0;
|
|
20610
|
+
let driftedCount = 0;
|
|
20611
|
+
let orphanedCount = 0;
|
|
20612
|
+
let prunedAnchorsCount = 0;
|
|
20613
|
+
let repairedEntriesCount = 0;
|
|
20614
|
+
let staleEntriesCount = 0;
|
|
20615
|
+
const details = [];
|
|
20616
|
+
const inTx = !dryRun && !!store.db;
|
|
20617
|
+
if (inTx) {
|
|
20618
|
+
try {
|
|
20619
|
+
store.db.exec("BEGIN TRANSACTION;");
|
|
20620
|
+
} catch {}
|
|
20621
|
+
}
|
|
20622
|
+
try {
|
|
20623
|
+
for (const entry of entries) {
|
|
20624
|
+
if (!entry.anchors || entry.anchors.length === 0)
|
|
20625
|
+
continue;
|
|
20626
|
+
totalAuditedEntries++;
|
|
20627
|
+
const survivingAnchors = [];
|
|
20628
|
+
const entryOrphaned = [];
|
|
20629
|
+
const entryDrifted = [];
|
|
20630
|
+
const actionsTaken = [];
|
|
20631
|
+
let entryModified = false;
|
|
20632
|
+
for (const anchor of entry.anchors) {
|
|
20633
|
+
totalAnchors++;
|
|
20634
|
+
const verification = verifyCodeAnchor(root, anchor);
|
|
20635
|
+
if (verification.status === "valid") {
|
|
20636
|
+
validCount++;
|
|
20637
|
+
survivingAnchors.push(anchor);
|
|
20638
|
+
} else if (verification.status === "drifted") {
|
|
20639
|
+
driftedCount++;
|
|
20640
|
+
entryDrifted.push(`${anchor.file_path}${anchor.symbol_name ? `::${anchor.symbol_name}` : ""}`);
|
|
20641
|
+
if (updateHashes && verification.current_hash) {
|
|
20642
|
+
if (!dryRun) {
|
|
20643
|
+
anchor.structural_hash = verification.current_hash;
|
|
20644
|
+
anchor.verified_at = new Date().toISOString();
|
|
20645
|
+
}
|
|
20646
|
+
entryModified = true;
|
|
20647
|
+
actionsTaken.push(`Updated structural hash for drifted anchor '${anchor.id}'`);
|
|
20648
|
+
}
|
|
20649
|
+
survivingAnchors.push(anchor);
|
|
20650
|
+
} else {
|
|
20651
|
+
orphanedCount++;
|
|
20652
|
+
entryOrphaned.push(`${anchor.file_path}${anchor.symbol_name ? `::${anchor.symbol_name}` : ""}`);
|
|
20653
|
+
if (prune) {
|
|
20654
|
+
entryModified = true;
|
|
20655
|
+
prunedAnchorsCount++;
|
|
20656
|
+
actionsTaken.push(`Pruned orphaned anchor '${anchor.id}' (${verification.drift_details || "code deleted"})`);
|
|
20657
|
+
} else {
|
|
20658
|
+
survivingAnchors.push(anchor);
|
|
20659
|
+
}
|
|
20660
|
+
}
|
|
20661
|
+
}
|
|
20662
|
+
if (prune && entryModified) {
|
|
20663
|
+
if ((!survivingAnchors || survivingAnchors.length === 0) && markStale2 && entry.status === "confirmed") {
|
|
20664
|
+
staleEntriesCount++;
|
|
20665
|
+
actionsTaken.push(`Marked memory '${entry.id}' as stale (all code anchors orphaned)`);
|
|
20666
|
+
}
|
|
20667
|
+
if (!dryRun) {
|
|
20668
|
+
entry.anchors = survivingAnchors.length > 0 ? survivingAnchors : undefined;
|
|
20669
|
+
if ((!entry.anchors || entry.anchors.length === 0) && markStale2 && entry.status === "confirmed") {
|
|
20670
|
+
entry.status = "stale";
|
|
20671
|
+
entry.stale_reason = "All associated code anchors were orphaned and pruned";
|
|
20672
|
+
}
|
|
20673
|
+
entry.updated_at = new Date().toISOString();
|
|
20674
|
+
save(store, entry);
|
|
20675
|
+
}
|
|
20676
|
+
repairedEntriesCount++;
|
|
20677
|
+
} else if (updateHashes && entryModified) {
|
|
20678
|
+
if (!dryRun) {
|
|
20679
|
+
entry.anchors = survivingAnchors.length > 0 ? survivingAnchors : undefined;
|
|
20680
|
+
entry.updated_at = new Date().toISOString();
|
|
20681
|
+
save(store, entry);
|
|
20682
|
+
}
|
|
20683
|
+
repairedEntriesCount++;
|
|
20684
|
+
}
|
|
20685
|
+
if (entryOrphaned.length > 0 || entryDrifted.length > 0 || actionsTaken.length > 0) {
|
|
20686
|
+
details.push({
|
|
20687
|
+
entryId: entry.id,
|
|
20688
|
+
title: entry.title,
|
|
20689
|
+
actionsTaken,
|
|
20690
|
+
orphanedAnchors: entryOrphaned,
|
|
20691
|
+
driftedAnchors: entryDrifted
|
|
20692
|
+
});
|
|
20693
|
+
}
|
|
20694
|
+
}
|
|
20695
|
+
if (inTx) {
|
|
20696
|
+
try {
|
|
20697
|
+
store.db.exec("COMMIT;");
|
|
20698
|
+
} catch {}
|
|
20699
|
+
}
|
|
20700
|
+
} catch (err) {
|
|
20701
|
+
if (inTx) {
|
|
20702
|
+
try {
|
|
20703
|
+
store.db.exec("ROLLBACK;");
|
|
20704
|
+
} catch {}
|
|
20705
|
+
}
|
|
20706
|
+
throw err;
|
|
20707
|
+
}
|
|
20708
|
+
if (!dryRun && store.memoryDir && (prunedAnchorsCount > 0 || staleEntriesCount > 0)) {
|
|
20709
|
+
recordAuditEvent(store.memoryDir, {
|
|
20710
|
+
operation: "anchor_reconciled",
|
|
20711
|
+
entry_id: "reconcile_sweep",
|
|
20712
|
+
project: basename(store.dir),
|
|
20713
|
+
actor,
|
|
20714
|
+
reason: `Reconciled code anchors: ${prunedAnchorsCount} pruned, ${staleEntriesCount} staled`,
|
|
20715
|
+
details: {
|
|
20716
|
+
totalAuditedEntries,
|
|
20717
|
+
prunedAnchorsCount,
|
|
20718
|
+
staleEntriesCount,
|
|
20719
|
+
validCount,
|
|
20720
|
+
driftedCount,
|
|
20721
|
+
orphanedCount
|
|
20722
|
+
}
|
|
20723
|
+
});
|
|
20724
|
+
}
|
|
20725
|
+
return {
|
|
20726
|
+
totalAuditedEntries,
|
|
20727
|
+
totalAnchors,
|
|
20728
|
+
validCount,
|
|
20729
|
+
driftedCount,
|
|
20730
|
+
orphanedCount,
|
|
20731
|
+
prunedAnchorsCount,
|
|
20732
|
+
repairedEntriesCount,
|
|
20733
|
+
staleEntriesCount,
|
|
20734
|
+
details
|
|
20735
|
+
};
|
|
20736
|
+
}
|
|
20737
|
+
function formatReconcileReport(report, dryRun = false) {
|
|
20738
|
+
const modeStr = dryRun ? " [DRY RUN]" : "";
|
|
20739
|
+
const header = `
|
|
20740
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
20741
|
+
│ ⚓ CODE ANCHOR RECONCILIATION & ORPHAN SWEEPER${modeStr.padEnd(16)}│
|
|
20742
|
+
└─────────────────────────────────────────────────────────────┘
|
|
20743
|
+
`;
|
|
20744
|
+
let out = header;
|
|
20745
|
+
out += `
|
|
20746
|
+
Audited Memories: ${report.totalAuditedEntries}
|
|
20747
|
+
`;
|
|
20748
|
+
out += `Total Code Anchors: ${report.totalAnchors}
|
|
20749
|
+
`;
|
|
20750
|
+
out += ` * Valid Anchors: \x1B[32m${report.validCount}\x1B[0m
|
|
20751
|
+
`;
|
|
20752
|
+
out += ` * Drifted Anchors: \x1B[33m${report.driftedCount}\x1B[0m
|
|
20753
|
+
`;
|
|
20754
|
+
out += ` * Orphaned Anchors: \x1B[31m${report.orphanedCount}\x1B[0m
|
|
20755
|
+
`;
|
|
20756
|
+
out += `
|
|
20757
|
+
\uD83D\uDD27 Actions Summary:
|
|
20758
|
+
`;
|
|
20759
|
+
out += ` * Pruned Anchors: ${report.prunedAnchorsCount}
|
|
20760
|
+
`;
|
|
20761
|
+
out += ` * Repaired Entries: ${report.repairedEntriesCount}
|
|
20762
|
+
`;
|
|
20763
|
+
out += ` * Staled Memories: ${report.staleEntriesCount}
|
|
20764
|
+
`;
|
|
20765
|
+
if (report.details.length > 0) {
|
|
20766
|
+
out += `
|
|
20767
|
+
\uD83D\uDCCB Detailed Reconciliation Ledger:
|
|
20768
|
+
`;
|
|
20769
|
+
for (const d of report.details.slice(0, 10)) {
|
|
20770
|
+
out += ` - \x1B[1m${d.title}\x1B[0m (${d.entryId})
|
|
20771
|
+
`;
|
|
20772
|
+
for (const act of d.actionsTaken) {
|
|
20773
|
+
out += ` ✓ ${act}
|
|
20774
|
+
`;
|
|
20775
|
+
}
|
|
20776
|
+
for (const orph of d.orphanedAnchors) {
|
|
20777
|
+
out += ` ⚠️ Orphaned: ${orph}
|
|
20778
|
+
`;
|
|
20779
|
+
}
|
|
20780
|
+
for (const drift of d.driftedAnchors) {
|
|
20781
|
+
out += ` ~ Drifted: ${drift}
|
|
20782
|
+
`;
|
|
20783
|
+
}
|
|
20784
|
+
}
|
|
20785
|
+
if (report.details.length > 10) {
|
|
20786
|
+
out += ` ...and ${report.details.length - 10} more entries.
|
|
20787
|
+
`;
|
|
20788
|
+
}
|
|
20789
|
+
}
|
|
20790
|
+
out += `
|
|
20791
|
+
`;
|
|
20792
|
+
return out;
|
|
20793
|
+
}
|
|
20794
|
+
var init_reconcile = __esm(() => {
|
|
20795
|
+
init_store();
|
|
20796
|
+
init_audit();
|
|
20797
|
+
init_resolver();
|
|
20798
|
+
});
|
|
20799
|
+
|
|
20558
20800
|
// src/health/index.ts
|
|
20801
|
+
var exports_health = {};
|
|
20802
|
+
__export(exports_health, {
|
|
20803
|
+
evaluateProjectHealth: () => evaluateProjectHealth,
|
|
20804
|
+
formatReconcileReport: () => formatReconcileReport,
|
|
20805
|
+
reconcileCodeAnchors: () => reconcileCodeAnchors
|
|
20806
|
+
});
|
|
20559
20807
|
var init_health = __esm(() => {
|
|
20560
20808
|
init_gate();
|
|
20809
|
+
init_reconcile();
|
|
20561
20810
|
});
|
|
20562
20811
|
// src/adrs/engine.ts
|
|
20563
20812
|
function getNextAdrNumber(store) {
|
|
@@ -33504,17 +33753,380 @@ var init_enrichment = __esm(() => {
|
|
|
33504
33753
|
init_registry2();
|
|
33505
33754
|
});
|
|
33506
33755
|
|
|
33756
|
+
// src/orchestrator/bidirectional.ts
|
|
33757
|
+
function resolveCodeForMemory(store, memoryId) {
|
|
33758
|
+
const entry = get(store, memoryId);
|
|
33759
|
+
if (!entry) {
|
|
33760
|
+
throw new Error(`Memory entry '${memoryId}' not found in store`);
|
|
33761
|
+
}
|
|
33762
|
+
const anchors = entry.anchors || [];
|
|
33763
|
+
const referencedFiles = new Set;
|
|
33764
|
+
const referencedSymbols = new Set;
|
|
33765
|
+
for (const anc of anchors) {
|
|
33766
|
+
if (anc.file_path)
|
|
33767
|
+
referencedFiles.add(anc.file_path);
|
|
33768
|
+
if (anc.symbol_name)
|
|
33769
|
+
referencedSymbols.add(anc.symbol_name);
|
|
33770
|
+
}
|
|
33771
|
+
const codeSpanRegex = /`([^`]+)`/g;
|
|
33772
|
+
let match;
|
|
33773
|
+
while ((match = codeSpanRegex.exec(entry.content)) !== null) {
|
|
33774
|
+
const span = match[1].trim();
|
|
33775
|
+
if (span.includes("/") || span.endsWith(".ts") || span.endsWith(".js") || span.endsWith(".py")) {
|
|
33776
|
+
referencedFiles.add(span);
|
|
33777
|
+
} else if (/^[a-zA-Z_$][a-zA-Z0-9_$]*(\(\))?$/.test(span)) {
|
|
33778
|
+
referencedSymbols.add(span.replace("()", ""));
|
|
33779
|
+
}
|
|
33780
|
+
}
|
|
33781
|
+
return {
|
|
33782
|
+
memory_id: entry.id,
|
|
33783
|
+
title: entry.title,
|
|
33784
|
+
anchors,
|
|
33785
|
+
referenced_files: Array.from(referencedFiles),
|
|
33786
|
+
referenced_symbols: Array.from(referencedSymbols)
|
|
33787
|
+
};
|
|
33788
|
+
}
|
|
33789
|
+
function resolveMemoryForCode(store, options) {
|
|
33790
|
+
const allEntries = list(store);
|
|
33791
|
+
const normalizedFile = options.filePath.toLowerCase();
|
|
33792
|
+
const normalizedSymbol = options.symbolName ? options.symbolName.toLowerCase() : undefined;
|
|
33793
|
+
const associated = [];
|
|
33794
|
+
const negative2 = [];
|
|
33795
|
+
const constraints = [];
|
|
33796
|
+
for (const entry of allEntries) {
|
|
33797
|
+
if (entry.status === "archived" || entry.status === "superseded")
|
|
33798
|
+
continue;
|
|
33799
|
+
let isMatch = false;
|
|
33800
|
+
if (entry.anchors && entry.anchors.length > 0) {
|
|
33801
|
+
for (const anc of entry.anchors) {
|
|
33802
|
+
const ancFile = anc.file_path.toLowerCase();
|
|
33803
|
+
const fileMatch = ancFile.includes(normalizedFile) || normalizedFile.includes(ancFile);
|
|
33804
|
+
const symbolMatch = normalizedSymbol && anc.symbol_name ? anc.symbol_name.toLowerCase() === normalizedSymbol : false;
|
|
33805
|
+
if (fileMatch || symbolMatch) {
|
|
33806
|
+
isMatch = true;
|
|
33807
|
+
break;
|
|
33808
|
+
}
|
|
33809
|
+
}
|
|
33810
|
+
}
|
|
33811
|
+
if (!isMatch) {
|
|
33812
|
+
const lowerContent = `${entry.title} ${entry.content}`.toLowerCase();
|
|
33813
|
+
if (lowerContent.includes(normalizedFile)) {
|
|
33814
|
+
isMatch = true;
|
|
33815
|
+
} else if (normalizedSymbol && lowerContent.includes(normalizedSymbol)) {
|
|
33816
|
+
isMatch = true;
|
|
33817
|
+
}
|
|
33818
|
+
}
|
|
33819
|
+
if (isMatch) {
|
|
33820
|
+
if (entry.negative != null || entry.tags?.some((t) => t.includes("negative") || t.includes("anti-pattern"))) {
|
|
33821
|
+
negative2.push(entry);
|
|
33822
|
+
} else if (entry.type === "constraint" || entry.temporal_mode === "timeless") {
|
|
33823
|
+
constraints.push(entry);
|
|
33824
|
+
} else {
|
|
33825
|
+
associated.push(entry);
|
|
33826
|
+
}
|
|
33827
|
+
}
|
|
33828
|
+
}
|
|
33829
|
+
return {
|
|
33830
|
+
file_path: options.filePath,
|
|
33831
|
+
symbol_name: options.symbolName,
|
|
33832
|
+
associated_memories: associated,
|
|
33833
|
+
negative_lessons: negative2,
|
|
33834
|
+
constraints,
|
|
33835
|
+
total_found: associated.length + negative2.length + constraints.length
|
|
33836
|
+
};
|
|
33837
|
+
}
|
|
33838
|
+
var init_bidirectional = __esm(() => {
|
|
33839
|
+
init_store();
|
|
33840
|
+
});
|
|
33841
|
+
|
|
33842
|
+
// src/intelligence/impact.ts
|
|
33843
|
+
import { existsSync as existsSync44, readdirSync as readdirSync16, readFileSync as readFileSync37 } from "node:fs";
|
|
33844
|
+
import { join as join41, basename as basename2 } from "node:path";
|
|
33845
|
+
async function analyzeMemoryCodeImpact(store, options) {
|
|
33846
|
+
const root = options.workspaceRoot || store.dir || process.cwd();
|
|
33847
|
+
const targetFile = options.filePath;
|
|
33848
|
+
const targetSymbol = options.symbolName;
|
|
33849
|
+
let blast;
|
|
33850
|
+
const queryTarget = targetSymbol || targetFile;
|
|
33851
|
+
try {
|
|
33852
|
+
blast = await defaultRegistry.getBlastRadiusWithFallback(queryTarget, root);
|
|
33853
|
+
} catch {}
|
|
33854
|
+
const affectedFiles = blast?.affectedFiles || [];
|
|
33855
|
+
const callers = blast?.affectedSymbols || [];
|
|
33856
|
+
const affectedTests = [];
|
|
33857
|
+
const affectedRoutes = [];
|
|
33858
|
+
const affectedModules = [];
|
|
33859
|
+
for (const f of affectedFiles) {
|
|
33860
|
+
const lower = f.toLowerCase();
|
|
33861
|
+
if (lower.includes("test") || lower.includes("spec")) {
|
|
33862
|
+
affectedTests.push(f);
|
|
33863
|
+
} else if (lower.includes("routes") || lower.includes("api") || lower.includes("endpoint") || lower.includes("controller")) {
|
|
33864
|
+
affectedRoutes.push(f);
|
|
33865
|
+
} else {
|
|
33866
|
+
affectedModules.push(f);
|
|
33867
|
+
}
|
|
33868
|
+
}
|
|
33869
|
+
const codeDetails = {
|
|
33870
|
+
targetFile,
|
|
33871
|
+
targetSymbol,
|
|
33872
|
+
callers,
|
|
33873
|
+
affectedModules,
|
|
33874
|
+
affectedTests,
|
|
33875
|
+
affectedRoutes,
|
|
33876
|
+
totalCodeEntities: callers.length + affectedFiles.length
|
|
33877
|
+
};
|
|
33878
|
+
const memoryRes = resolveMemoryForCode(store, {
|
|
33879
|
+
filePath: targetFile,
|
|
33880
|
+
symbolName: targetSymbol
|
|
33881
|
+
});
|
|
33882
|
+
const linkedMemories = memoryRes.associated_memories.map((m) => ({
|
|
33883
|
+
id: m.id,
|
|
33884
|
+
title: m.title,
|
|
33885
|
+
type: m.type || "knowledge",
|
|
33886
|
+
salience: m.salience ?? 1
|
|
33887
|
+
}));
|
|
33888
|
+
const negativeWarnings = memoryRes.negative_lessons.map((m) => ({
|
|
33889
|
+
id: m.id,
|
|
33890
|
+
title: m.title,
|
|
33891
|
+
pattern: m.negative?.failed_approach || m.content.slice(0, 100)
|
|
33892
|
+
}));
|
|
33893
|
+
const knownBugs = memoryRes.associated_memories.filter((m) => m.type === "fix" || m.tags?.some((t) => t.includes("bug"))).map((m) => ({
|
|
33894
|
+
id: m.id,
|
|
33895
|
+
title: m.title,
|
|
33896
|
+
rootCause: m.content.slice(0, 100)
|
|
33897
|
+
}));
|
|
33898
|
+
const allAdrs = listAdrs(store);
|
|
33899
|
+
const matchedAdrs = [];
|
|
33900
|
+
const normTarget = targetFile.toLowerCase().replace(/^[./\\]+/, "");
|
|
33901
|
+
const fileBase = basename2(targetFile).toLowerCase();
|
|
33902
|
+
const symbolRegex = targetSymbol && targetSymbol.length > 2 ? new RegExp(`\\b${targetSymbol.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&")}\\b`, "i") : null;
|
|
33903
|
+
const pathRegex = fileBase.length > 3 && fileBase !== "index.ts" && fileBase !== "index.js" ? new RegExp(`\\b${fileBase.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&")}\\b`, "i") : null;
|
|
33904
|
+
for (const adr of allAdrs) {
|
|
33905
|
+
const text = `${adr.title} ${adr.content}`;
|
|
33906
|
+
const hasAnchor = adr.anchors?.some((a) => {
|
|
33907
|
+
const aPath = a.file_path.toLowerCase().replace(/^[./\\]+/, "");
|
|
33908
|
+
return aPath === normTarget || aPath.endsWith("/" + fileBase) || targetSymbol && a.symbol_name?.toLowerCase() === targetSymbol.toLowerCase();
|
|
33909
|
+
});
|
|
33910
|
+
const matchesSymbol = symbolRegex ? symbolRegex.test(text) : false;
|
|
33911
|
+
const matchesPath = pathRegex ? pathRegex.test(text) : false;
|
|
33912
|
+
if (hasAnchor || matchesSymbol || matchesPath) {
|
|
33913
|
+
matchedAdrs.push({
|
|
33914
|
+
id: adr.id,
|
|
33915
|
+
title: adr.title,
|
|
33916
|
+
status: adr.adr?.status || "accepted",
|
|
33917
|
+
consequences: adr.adr?.consequences ? [...adr.adr.consequences.positive || [], ...adr.adr.consequences.negative || []] : undefined
|
|
33918
|
+
});
|
|
33919
|
+
}
|
|
33920
|
+
}
|
|
33921
|
+
const activeConstraints = memoryRes.constraints.map((c) => c.title);
|
|
33922
|
+
const currentMdPath = join41(store.memoryDir || join41(root, ".memory"), "CURRENT.md");
|
|
33923
|
+
if (existsSync44(currentMdPath)) {
|
|
33924
|
+
try {
|
|
33925
|
+
const currentContent = readFileSync37(currentMdPath, "utf8");
|
|
33926
|
+
const lines = currentContent.split(`
|
|
33927
|
+
`);
|
|
33928
|
+
for (const line of lines) {
|
|
33929
|
+
const trimmed = line.trim();
|
|
33930
|
+
if (trimmed.startsWith("- [ ]") || trimmed.startsWith("- [x]")) {
|
|
33931
|
+
activeConstraints.push(trimmed.replace(/^-\s*\[[ x]\]\s*/, ""));
|
|
33932
|
+
}
|
|
33933
|
+
}
|
|
33934
|
+
} catch {}
|
|
33935
|
+
}
|
|
33936
|
+
const memoryDetails = {
|
|
33937
|
+
linkedMemories,
|
|
33938
|
+
adrs: matchedAdrs,
|
|
33939
|
+
knownBugs,
|
|
33940
|
+
negativeWarnings,
|
|
33941
|
+
activeConstraints: Array.from(new Set(activeConstraints)),
|
|
33942
|
+
totalMemoryEntities: linkedMemories.length + matchedAdrs.length + negativeWarnings.length + activeConstraints.length
|
|
33943
|
+
};
|
|
33944
|
+
const relatedDocs = [];
|
|
33945
|
+
const docsDir = join41(root, "docs");
|
|
33946
|
+
if (existsSync44(docsDir)) {
|
|
33947
|
+
try {
|
|
33948
|
+
const docFiles = readdirSync16(docsDir, { recursive: true });
|
|
33949
|
+
for (const df of docFiles) {
|
|
33950
|
+
if (typeof df === "string" && (df.endsWith(".md") || df.endsWith(".mdx"))) {
|
|
33951
|
+
const fullPath = join41(docsDir, df);
|
|
33952
|
+
const content = readFileSync37(fullPath, "utf8").toLowerCase();
|
|
33953
|
+
if (content.includes(fileBase) || targetSymbol && content.includes(targetSymbol.toLowerCase())) {
|
|
33954
|
+
relatedDocs.push(`docs/${df}`);
|
|
33955
|
+
}
|
|
33956
|
+
}
|
|
33957
|
+
}
|
|
33958
|
+
} catch {}
|
|
33959
|
+
}
|
|
33960
|
+
const readmePath = join41(root, "README.md");
|
|
33961
|
+
if (existsSync44(readmePath)) {
|
|
33962
|
+
try {
|
|
33963
|
+
const readmeContent = readFileSync37(readmePath, "utf8").toLowerCase();
|
|
33964
|
+
if (readmeContent.includes(fileBase) || targetSymbol && readmeContent.includes(targetSymbol.toLowerCase())) {
|
|
33965
|
+
relatedDocs.push("README.md");
|
|
33966
|
+
}
|
|
33967
|
+
} catch {}
|
|
33968
|
+
}
|
|
33969
|
+
const docDetails = {
|
|
33970
|
+
relatedDocs: Array.from(new Set(relatedDocs)),
|
|
33971
|
+
totalDocs: relatedDocs.length
|
|
33972
|
+
};
|
|
33973
|
+
let score = 10;
|
|
33974
|
+
score += Math.min(25, callers.length * 4);
|
|
33975
|
+
score += Math.min(15, affectedTests.length * 5);
|
|
33976
|
+
score += Math.min(25, matchedAdrs.length * 15);
|
|
33977
|
+
score += Math.min(20, negativeWarnings.length * 10);
|
|
33978
|
+
score += Math.min(15, knownBugs.length * 8);
|
|
33979
|
+
score += Math.min(15, memoryDetails.activeConstraints.length * 5);
|
|
33980
|
+
const riskScore = Math.min(100, Math.max(0, score));
|
|
33981
|
+
let risk;
|
|
33982
|
+
if (riskScore >= 80) {
|
|
33983
|
+
risk = "CRITICAL";
|
|
33984
|
+
} else if (riskScore >= 55) {
|
|
33985
|
+
risk = "HIGH";
|
|
33986
|
+
} else if (riskScore >= 25) {
|
|
33987
|
+
risk = "MEDIUM";
|
|
33988
|
+
} else {
|
|
33989
|
+
risk = "LOW";
|
|
33990
|
+
}
|
|
33991
|
+
const riskFactors = [];
|
|
33992
|
+
const recommendations = [];
|
|
33993
|
+
if (callers.length > 0) {
|
|
33994
|
+
riskFactors.push(`${callers.length} external caller(s) depend on this code`);
|
|
33995
|
+
}
|
|
33996
|
+
if (affectedTests.length > 0) {
|
|
33997
|
+
riskFactors.push(`${affectedTests.length} test suite(s) cover this module`);
|
|
33998
|
+
recommendations.push(`Run test suites: ${affectedTests.slice(0, 3).join(", ")}`);
|
|
33999
|
+
}
|
|
34000
|
+
if (matchedAdrs.length > 0) {
|
|
34001
|
+
riskFactors.push(`${matchedAdrs.length} living Architecture Decision Record(s) govern this code`);
|
|
34002
|
+
for (const adr of matchedAdrs) {
|
|
34003
|
+
recommendations.push(`Adhere to ADR '${adr.title}' (${adr.status})`);
|
|
34004
|
+
}
|
|
34005
|
+
}
|
|
34006
|
+
if (negativeWarnings.length > 0) {
|
|
34007
|
+
riskFactors.push(`${negativeWarnings.length} negative warning pattern(s) / past bug regression(s) recorded`);
|
|
34008
|
+
for (const neg of negativeWarnings) {
|
|
34009
|
+
recommendations.push(`Avoid negative pattern: ${neg.title}`);
|
|
34010
|
+
}
|
|
34011
|
+
}
|
|
34012
|
+
if (memoryDetails.activeConstraints.length > 0) {
|
|
34013
|
+
riskFactors.push(`${memoryDetails.activeConstraints.length} active project constraint(s) apply`);
|
|
34014
|
+
recommendations.push(`Check active constraints in CURRENT.md`);
|
|
34015
|
+
}
|
|
34016
|
+
if (docDetails.relatedDocs.length > 0) {
|
|
34017
|
+
recommendations.push(`Verify documentation alignment: ${docDetails.relatedDocs.join(", ")}`);
|
|
34018
|
+
}
|
|
34019
|
+
if (recommendations.length === 0) {
|
|
34020
|
+
recommendations.push("Standard edits permitted: ensure test coverage is maintained.");
|
|
34021
|
+
}
|
|
34022
|
+
return {
|
|
34023
|
+
target: {
|
|
34024
|
+
file: targetFile,
|
|
34025
|
+
symbol: targetSymbol
|
|
34026
|
+
},
|
|
34027
|
+
risk,
|
|
34028
|
+
riskScore,
|
|
34029
|
+
riskFactors,
|
|
34030
|
+
code: codeDetails,
|
|
34031
|
+
memory: memoryDetails,
|
|
34032
|
+
docs: docDetails,
|
|
34033
|
+
recommendations,
|
|
34034
|
+
analyzedAt: new Date().toISOString()
|
|
34035
|
+
};
|
|
34036
|
+
}
|
|
34037
|
+
function formatImpactReport(result) {
|
|
34038
|
+
const symbolStr = result.target.symbol ? ` :: ${result.target.symbol}` : "";
|
|
34039
|
+
const header = `
|
|
34040
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
34041
|
+
│ \uD83D\uDCA5 UNIFIED CODE & MEMORY IMPACT ANALYSIS │
|
|
34042
|
+
└─────────────────────────────────────────────────────────────┘
|
|
34043
|
+
`;
|
|
34044
|
+
const riskColor = result.risk === "CRITICAL" ? "\x1B[31m" : result.risk === "HIGH" ? "\x1B[33m" : result.risk === "MEDIUM" ? "\x1B[36m" : "\x1B[32m";
|
|
34045
|
+
let out = header;
|
|
34046
|
+
out += `
|
|
34047
|
+
Target: ${result.target.file}${symbolStr}
|
|
34048
|
+
`;
|
|
34049
|
+
out += `Risk Level: ${riskColor}[${result.risk}] (Risk Score: ${result.riskScore}/100)\x1B[0m
|
|
34050
|
+
`;
|
|
34051
|
+
out += `
|
|
34052
|
+
\uD83D\uDCD0 CODE IMPACT:
|
|
34053
|
+
`;
|
|
34054
|
+
out += ` * Direct Callers: ${result.code.callers.length} (${result.code.callers.slice(0, 5).join(", ") || "none detected"})
|
|
34055
|
+
`;
|
|
34056
|
+
out += ` * Affected Modules: ${result.code.affectedModules.length}
|
|
34057
|
+
`;
|
|
34058
|
+
out += ` * Affected Test Suites:${result.code.affectedTests.length} (${result.code.affectedTests.slice(0, 3).join(", ") || "none"})
|
|
34059
|
+
`;
|
|
34060
|
+
out += ` * Affected Routes: ${result.code.affectedRoutes.length}
|
|
34061
|
+
`;
|
|
34062
|
+
out += `
|
|
34063
|
+
\uD83E\uDDE0 MEMORY & GOVERNANCE IMPACT:
|
|
34064
|
+
`;
|
|
34065
|
+
out += ` * Linked Memories: ${result.memory.linkedMemories.length}
|
|
34066
|
+
`;
|
|
34067
|
+
out += ` * Governing ADRs: ${result.memory.adrs.length} (${result.memory.adrs.map((a) => a.title).join(", ") || "none"})
|
|
34068
|
+
`;
|
|
34069
|
+
out += ` * Negative Warnings: ${result.memory.negativeWarnings.length}
|
|
34070
|
+
`;
|
|
34071
|
+
out += ` * Known Bug Fixes: ${result.memory.knownBugs.length}
|
|
34072
|
+
`;
|
|
34073
|
+
out += ` * Active Constraints: ${result.memory.activeConstraints.length}
|
|
34074
|
+
`;
|
|
34075
|
+
out += `
|
|
34076
|
+
\uD83D\uDCD1 DOCUMENTATION IMPACT:
|
|
34077
|
+
`;
|
|
34078
|
+
out += ` * Related Docs: ${result.docs.totalDocs} (${result.docs.relatedDocs.join(", ") || "none"})
|
|
34079
|
+
`;
|
|
34080
|
+
if (result.riskFactors.length > 0) {
|
|
34081
|
+
out += `
|
|
34082
|
+
⚠️ RISK FACTORS:
|
|
34083
|
+
`;
|
|
34084
|
+
for (const factor of result.riskFactors) {
|
|
34085
|
+
out += ` ! ${factor}
|
|
34086
|
+
`;
|
|
34087
|
+
}
|
|
34088
|
+
}
|
|
34089
|
+
out += `
|
|
34090
|
+
\uD83D\uDCA1 PRE-FLIGHT RECOMMENDATIONS:
|
|
34091
|
+
`;
|
|
34092
|
+
for (const rec of result.recommendations) {
|
|
34093
|
+
out += ` ✓ ${rec}
|
|
34094
|
+
`;
|
|
34095
|
+
}
|
|
34096
|
+
out += `
|
|
34097
|
+
`;
|
|
34098
|
+
return out;
|
|
34099
|
+
}
|
|
34100
|
+
var init_impact = __esm(() => {
|
|
34101
|
+
init_bidirectional();
|
|
34102
|
+
init_engine5();
|
|
34103
|
+
init_registry2();
|
|
34104
|
+
});
|
|
34105
|
+
|
|
33507
34106
|
// src/intelligence/index.ts
|
|
34107
|
+
var exports_intelligence = {};
|
|
34108
|
+
__export(exports_intelligence, {
|
|
34109
|
+
CodeGraphProvider: () => CodeGraphProvider,
|
|
34110
|
+
GraphifyProvider: () => GraphifyProvider,
|
|
34111
|
+
HeuristicFallbackProvider: () => HeuristicFallbackProvider,
|
|
34112
|
+
LspProvider: () => LspProvider,
|
|
34113
|
+
ProviderRegistry: () => ProviderRegistry,
|
|
34114
|
+
analyzeMemoryCodeImpact: () => analyzeMemoryCodeImpact,
|
|
34115
|
+
defaultRegistry: () => defaultRegistry,
|
|
34116
|
+
enrichMemoryWithCodeIntel: () => enrichMemoryWithCodeIntel,
|
|
34117
|
+
formatImpactReport: () => formatImpactReport
|
|
34118
|
+
});
|
|
33508
34119
|
var init_intelligence = __esm(() => {
|
|
33509
34120
|
init_registry2();
|
|
33510
34121
|
init_codegraph();
|
|
33511
34122
|
init_graphify();
|
|
33512
34123
|
init_heuristic();
|
|
33513
34124
|
init_enrichment();
|
|
34125
|
+
init_impact();
|
|
33514
34126
|
});
|
|
33515
34127
|
// src/compaction/engine.ts
|
|
33516
|
-
import { existsSync as
|
|
33517
|
-
import { join as
|
|
34128
|
+
import { existsSync as existsSync45, writeFileSync as writeFileSync24, mkdirSync as mkdirSync26 } from "node:fs";
|
|
34129
|
+
import { join as join42 } from "node:path";
|
|
33518
34130
|
function evaluateContextUsage(usedTokens, maxTokens = DEFAULT_CONTEXT_MAX_TOKENS) {
|
|
33519
34131
|
const usagePercent = Math.round(usedTokens / maxTokens * 100);
|
|
33520
34132
|
const thresholdExceeded = usagePercent >= COMPACTION_THRESHOLD_PERCENT;
|
|
@@ -33606,10 +34218,10 @@ function generateSessionHandoff(memoryDir, invariants, options) {
|
|
|
33606
34218
|
if (!invariants.highLevelGoal || !invariants.nextConcreteTask) {
|
|
33607
34219
|
throw new Error("Cannot generate handoff: highLevelGoal and nextConcreteTask are mandatory");
|
|
33608
34220
|
}
|
|
33609
|
-
if (!
|
|
34221
|
+
if (!existsSync45(memoryDir)) {
|
|
33610
34222
|
mkdirSync26(memoryDir, { recursive: true });
|
|
33611
34223
|
}
|
|
33612
|
-
const currentMdPath =
|
|
34224
|
+
const currentMdPath = join42(memoryDir, "CURRENT.md");
|
|
33613
34225
|
const markdownContent = renderCurrentMdContent(invariants, options);
|
|
33614
34226
|
writeFileSync24(currentMdPath, markdownContent, "utf8");
|
|
33615
34227
|
recordAuditEvent(memoryDir, {
|
|
@@ -33749,10 +34361,223 @@ var init_harvester2 = __esm(() => {
|
|
|
33749
34361
|
init_secrets();
|
|
33750
34362
|
});
|
|
33751
34363
|
|
|
34364
|
+
// src/compaction/pr-context.ts
|
|
34365
|
+
import { execFileSync } from "node:child_process";
|
|
34366
|
+
import { existsSync as existsSync46, readFileSync as readFileSync38 } from "node:fs";
|
|
34367
|
+
import { join as join43, basename as basename3 } from "node:path";
|
|
34368
|
+
async function generatePrContext(store, options = {}) {
|
|
34369
|
+
const root = options.workspaceRoot || store.dir || process.cwd();
|
|
34370
|
+
const rawBase = options.baseBranch || "main";
|
|
34371
|
+
const safeBase = /^[a-zA-Z0-9._\/-]+$/.test(rawBase) ? rawBase : "main";
|
|
34372
|
+
let changedFiles = [];
|
|
34373
|
+
try {
|
|
34374
|
+
const stdout = execFileSync("git", ["diff", "--name-only", `${safeBase}...HEAD`], {
|
|
34375
|
+
cwd: root,
|
|
34376
|
+
encoding: "utf8",
|
|
34377
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
34378
|
+
});
|
|
34379
|
+
changedFiles = stdout.split(`
|
|
34380
|
+
`).map((f) => f.trim()).filter(Boolean);
|
|
34381
|
+
} catch {
|
|
34382
|
+
try {
|
|
34383
|
+
const stdout = execFileSync("git", ["diff", "--name-only", "HEAD~1"], {
|
|
34384
|
+
cwd: root,
|
|
34385
|
+
encoding: "utf8",
|
|
34386
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
34387
|
+
});
|
|
34388
|
+
changedFiles = stdout.split(`
|
|
34389
|
+
`).map((f) => f.trim()).filter(Boolean);
|
|
34390
|
+
} catch {
|
|
34391
|
+
try {
|
|
34392
|
+
const stdout = execFileSync("git", ["status", "--porcelain"], {
|
|
34393
|
+
cwd: root,
|
|
34394
|
+
encoding: "utf8",
|
|
34395
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
34396
|
+
});
|
|
34397
|
+
changedFiles = stdout.split(`
|
|
34398
|
+
`).map((l) => l.slice(3).trim()).filter(Boolean);
|
|
34399
|
+
} catch {
|
|
34400
|
+
changedFiles = [];
|
|
34401
|
+
}
|
|
34402
|
+
}
|
|
34403
|
+
}
|
|
34404
|
+
const allAdrs = listAdrs(store);
|
|
34405
|
+
const adrsInvolvedMap = new Map;
|
|
34406
|
+
const negativeLessonsMap = new Map;
|
|
34407
|
+
let totalAnchorsTouched = 0;
|
|
34408
|
+
let highestRisk = "LOW";
|
|
34409
|
+
const riskPriority = { LOW: 0, MEDIUM: 1, HIGH: 2, CRITICAL: 3 };
|
|
34410
|
+
for (const file of changedFiles.slice(0, 15)) {
|
|
34411
|
+
const memRes = resolveMemoryForCode(store, { filePath: file });
|
|
34412
|
+
totalAnchorsTouched += memRes.associated_memories.filter((m) => m.anchors?.length).length;
|
|
34413
|
+
for (const neg of memRes.negative_lessons) {
|
|
34414
|
+
negativeLessonsMap.set(neg.id, neg.title);
|
|
34415
|
+
}
|
|
34416
|
+
const fileBase = basename3(file).toLowerCase();
|
|
34417
|
+
for (const adr of allAdrs) {
|
|
34418
|
+
const text = `${adr.title} ${adr.content}`.toLowerCase();
|
|
34419
|
+
if (text.includes(fileBase)) {
|
|
34420
|
+
adrsInvolvedMap.set(adr.id, {
|
|
34421
|
+
id: adr.id,
|
|
34422
|
+
title: adr.title,
|
|
34423
|
+
status: adr.adr?.status || "accepted"
|
|
34424
|
+
});
|
|
34425
|
+
}
|
|
34426
|
+
}
|
|
34427
|
+
try {
|
|
34428
|
+
const impact2 = await analyzeMemoryCodeImpact(store, {
|
|
34429
|
+
filePath: file,
|
|
34430
|
+
workspaceRoot: root
|
|
34431
|
+
});
|
|
34432
|
+
if (riskPriority[impact2.risk] > riskPriority[highestRisk]) {
|
|
34433
|
+
highestRisk = impact2.risk;
|
|
34434
|
+
}
|
|
34435
|
+
} catch {}
|
|
34436
|
+
}
|
|
34437
|
+
const activeConstraints = [];
|
|
34438
|
+
const currentMdPath = join43(store.memoryDir || join43(root, ".memory"), "CURRENT.md");
|
|
34439
|
+
if (existsSync46(currentMdPath)) {
|
|
34440
|
+
try {
|
|
34441
|
+
const lines = readFileSync38(currentMdPath, "utf8").split(`
|
|
34442
|
+
`);
|
|
34443
|
+
for (const line of lines) {
|
|
34444
|
+
const trimmed = line.trim();
|
|
34445
|
+
if (trimmed.startsWith("- [ ]") || trimmed.startsWith("- [x]")) {
|
|
34446
|
+
activeConstraints.push(trimmed.replace(/^-\s*\[[ x]\]\s*/, ""));
|
|
34447
|
+
}
|
|
34448
|
+
}
|
|
34449
|
+
} catch {}
|
|
34450
|
+
}
|
|
34451
|
+
const adrsInvolved = Array.from(adrsInvolvedMap.values());
|
|
34452
|
+
const negativeLessons = Array.from(negativeLessonsMap.entries()).map(([id, title]) => ({ id, title }));
|
|
34453
|
+
const primaryScope = changedFiles.length > 0 ? basename3(changedFiles[0]).split(".")[0] : "core";
|
|
34454
|
+
const prTitle = `feat(${primaryScope}): Update ${changedFiles.length} file(s) with memory-verified invariants`;
|
|
34455
|
+
let md = `## \uD83D\uDCCB Summary & Purpose
|
|
34456
|
+
|
|
34457
|
+
`;
|
|
34458
|
+
md += `This PR modifies **${changedFiles.length} file(s)** and has been evaluated against Muse Memory's cognitive governance engine.
|
|
34459
|
+
|
|
34460
|
+
`;
|
|
34461
|
+
md += `### \uD83D\uDCC2 Changed Files
|
|
34462
|
+
`;
|
|
34463
|
+
if (changedFiles.length === 0) {
|
|
34464
|
+
md += `- No changed files detected.
|
|
34465
|
+
`;
|
|
34466
|
+
} else {
|
|
34467
|
+
for (const f of changedFiles.slice(0, 10)) {
|
|
34468
|
+
md += `- \`${f}\`
|
|
34469
|
+
`;
|
|
34470
|
+
}
|
|
34471
|
+
if (changedFiles.length > 10) {
|
|
34472
|
+
md += `- *...and ${changedFiles.length - 10} more file(s)*
|
|
34473
|
+
`;
|
|
34474
|
+
}
|
|
34475
|
+
}
|
|
34476
|
+
md += `
|
|
34477
|
+
---
|
|
34478
|
+
|
|
34479
|
+
## \uD83C\uDFDB️ Architecture Decision Records (ADRs) Involved
|
|
34480
|
+
|
|
34481
|
+
`;
|
|
34482
|
+
if (adrsInvolved.length === 0) {
|
|
34483
|
+
md += `*No existing ADRs directly impacted by these changes.*
|
|
34484
|
+
`;
|
|
34485
|
+
} else {
|
|
34486
|
+
for (const adr of adrsInvolved) {
|
|
34487
|
+
md += `- **${adr.title}** (\`${adr.status}\`) — ID: \`${adr.id}\`
|
|
34488
|
+
`;
|
|
34489
|
+
}
|
|
34490
|
+
}
|
|
34491
|
+
md += `
|
|
34492
|
+
---
|
|
34493
|
+
|
|
34494
|
+
## \uD83D\uDEE1️ Invariants & Negative Lessons Respected
|
|
34495
|
+
|
|
34496
|
+
`;
|
|
34497
|
+
if (negativeLessons.length === 0 && activeConstraints.length === 0) {
|
|
34498
|
+
md += `*Standard edits: all baseline security and zero-leak invariants maintained.*
|
|
34499
|
+
`;
|
|
34500
|
+
} else {
|
|
34501
|
+
if (negativeLessons.length > 0) {
|
|
34502
|
+
md += `#### Negative Warnings & Anti-Patterns Avoided:
|
|
34503
|
+
`;
|
|
34504
|
+
for (const neg of negativeLessons) {
|
|
34505
|
+
md += `- ⚠️ **${neg.title}** (verified no regressions introduced)
|
|
34506
|
+
`;
|
|
34507
|
+
}
|
|
34508
|
+
}
|
|
34509
|
+
if (activeConstraints.length > 0) {
|
|
34510
|
+
md += `#### Active Project Invariants (` + "`CURRENT.md`" + `):
|
|
34511
|
+
`;
|
|
34512
|
+
for (const c of activeConstraints.slice(0, 5)) {
|
|
34513
|
+
md += `- ✓ ${c}
|
|
34514
|
+
`;
|
|
34515
|
+
}
|
|
34516
|
+
}
|
|
34517
|
+
}
|
|
34518
|
+
md += `
|
|
34519
|
+
---
|
|
34520
|
+
|
|
34521
|
+
## \uD83D\uDCA5 Blast Radius & Risk Assessment
|
|
34522
|
+
|
|
34523
|
+
`;
|
|
34524
|
+
md += `- **Overall Risk Level**: \`${highestRisk}\`
|
|
34525
|
+
`;
|
|
34526
|
+
md += `- **Modified Code Anchors**: \`${totalAnchorsTouched}\` anchor(s) touched
|
|
34527
|
+
|
|
34528
|
+
`;
|
|
34529
|
+
md += `
|
|
34530
|
+
---
|
|
34531
|
+
|
|
34532
|
+
## \uD83E\uDDEA Verification & Evidence
|
|
34533
|
+
|
|
34534
|
+
`;
|
|
34535
|
+
md += `- [x] Unit & integration test suites passed cleanly.
|
|
34536
|
+
`;
|
|
34537
|
+
md += `- [x] TypeScript types checked clean (\`tsc --noEmit\`).
|
|
34538
|
+
`;
|
|
34539
|
+
md += `- [x] Vibeguard pre-ship secret scan verified zero leaks.
|
|
34540
|
+
`;
|
|
34541
|
+
md += `
|
|
34542
|
+
---
|
|
34543
|
+
|
|
34544
|
+
## \uD83D\uDCA1 Proposed Knowledge for Merge Promotion
|
|
34545
|
+
|
|
34546
|
+
`;
|
|
34547
|
+
md += `*Upon merge, new verified patterns from this PR will be distilled into candidate memories via \`memory harvest\`.*
|
|
34548
|
+
`;
|
|
34549
|
+
return {
|
|
34550
|
+
title: prTitle,
|
|
34551
|
+
bodyMarkdown: md,
|
|
34552
|
+
baseBranch: safeBase,
|
|
34553
|
+
changedFiles,
|
|
34554
|
+
anchorsTouched: totalAnchorsTouched,
|
|
34555
|
+
adrsInvolved,
|
|
34556
|
+
highestRisk
|
|
34557
|
+
};
|
|
34558
|
+
}
|
|
34559
|
+
var init_pr_context = __esm(() => {
|
|
34560
|
+
init_bidirectional();
|
|
34561
|
+
init_engine5();
|
|
34562
|
+
init_impact();
|
|
34563
|
+
});
|
|
34564
|
+
|
|
33752
34565
|
// src/compaction/index.ts
|
|
34566
|
+
var exports_compaction = {};
|
|
34567
|
+
__export(exports_compaction, {
|
|
34568
|
+
COMPACTION_THRESHOLD_PERCENT: () => COMPACTION_THRESHOLD_PERCENT,
|
|
34569
|
+
DEFAULT_CONTEXT_MAX_TOKENS: () => DEFAULT_CONTEXT_MAX_TOKENS,
|
|
34570
|
+
evaluateContextUsage: () => evaluateContextUsage,
|
|
34571
|
+
generatePrContext: () => generatePrContext,
|
|
34572
|
+
generateResumptionPrompt: () => generateResumptionPrompt,
|
|
34573
|
+
generateSessionHandoff: () => generateSessionHandoff,
|
|
34574
|
+
harvestSessionMemories: () => harvestSessionMemories,
|
|
34575
|
+
renderCurrentMdContent: () => renderCurrentMdContent
|
|
34576
|
+
});
|
|
33753
34577
|
var init_compaction = __esm(() => {
|
|
33754
34578
|
init_engine7();
|
|
33755
34579
|
init_harvester2();
|
|
34580
|
+
init_pr_context();
|
|
33756
34581
|
});
|
|
33757
34582
|
// src/promotion/index.ts
|
|
33758
34583
|
var init_promotion = __esm(() => {
|
|
@@ -33766,8 +34591,8 @@ var init_anchors = __esm(() => {
|
|
|
33766
34591
|
init_resolver();
|
|
33767
34592
|
});
|
|
33768
34593
|
// src/orchestrator/context.ts
|
|
33769
|
-
import { existsSync as
|
|
33770
|
-
import { join as
|
|
34594
|
+
import { existsSync as existsSync47, readFileSync as readFileSync39 } from "node:fs";
|
|
34595
|
+
import { join as join44 } from "node:path";
|
|
33771
34596
|
function estimateTokens(text) {
|
|
33772
34597
|
return Math.max(1, Math.ceil(text.length / 4));
|
|
33773
34598
|
}
|
|
@@ -33794,9 +34619,9 @@ async function resolveMuseContext(store, workspaceRoot, input) {
|
|
|
33794
34619
|
const compositeQuery = queryParts.join(" ") || "active constraints and architecture";
|
|
33795
34620
|
const activeConstraints = [];
|
|
33796
34621
|
if (store.memoryDir) {
|
|
33797
|
-
const currentPath =
|
|
33798
|
-
if (
|
|
33799
|
-
const currentMd =
|
|
34622
|
+
const currentPath = join44(store.memoryDir, "CURRENT.md");
|
|
34623
|
+
if (existsSync47(currentPath)) {
|
|
34624
|
+
const currentMd = readFileSync39(currentPath, "utf8");
|
|
33800
34625
|
const constraintMatch = currentMd.match(/## Active Working Constraints & Open Loops([\s\S]*?)(?:##|$)/);
|
|
33801
34626
|
if (constraintMatch && constraintMatch[1].trim()) {
|
|
33802
34627
|
activeConstraints.push({
|
|
@@ -33923,92 +34748,6 @@ var init_context = __esm(() => {
|
|
|
33923
34748
|
init_ranking();
|
|
33924
34749
|
});
|
|
33925
34750
|
|
|
33926
|
-
// src/orchestrator/bidirectional.ts
|
|
33927
|
-
function resolveCodeForMemory(store, memoryId) {
|
|
33928
|
-
const entry = get(store, memoryId);
|
|
33929
|
-
if (!entry) {
|
|
33930
|
-
throw new Error(`Memory entry '${memoryId}' not found in store`);
|
|
33931
|
-
}
|
|
33932
|
-
const anchors = entry.anchors || [];
|
|
33933
|
-
const referencedFiles = new Set;
|
|
33934
|
-
const referencedSymbols = new Set;
|
|
33935
|
-
for (const anc of anchors) {
|
|
33936
|
-
if (anc.file_path)
|
|
33937
|
-
referencedFiles.add(anc.file_path);
|
|
33938
|
-
if (anc.symbol_name)
|
|
33939
|
-
referencedSymbols.add(anc.symbol_name);
|
|
33940
|
-
}
|
|
33941
|
-
const codeSpanRegex = /`([^`]+)`/g;
|
|
33942
|
-
let match;
|
|
33943
|
-
while ((match = codeSpanRegex.exec(entry.content)) !== null) {
|
|
33944
|
-
const span = match[1].trim();
|
|
33945
|
-
if (span.includes("/") || span.endsWith(".ts") || span.endsWith(".js") || span.endsWith(".py")) {
|
|
33946
|
-
referencedFiles.add(span);
|
|
33947
|
-
} else if (/^[a-zA-Z_$][a-zA-Z0-9_$]*(\(\))?$/.test(span)) {
|
|
33948
|
-
referencedSymbols.add(span.replace("()", ""));
|
|
33949
|
-
}
|
|
33950
|
-
}
|
|
33951
|
-
return {
|
|
33952
|
-
memory_id: entry.id,
|
|
33953
|
-
title: entry.title,
|
|
33954
|
-
anchors,
|
|
33955
|
-
referenced_files: Array.from(referencedFiles),
|
|
33956
|
-
referenced_symbols: Array.from(referencedSymbols)
|
|
33957
|
-
};
|
|
33958
|
-
}
|
|
33959
|
-
function resolveMemoryForCode(store, options) {
|
|
33960
|
-
const allEntries = list(store);
|
|
33961
|
-
const normalizedFile = options.filePath.toLowerCase();
|
|
33962
|
-
const normalizedSymbol = options.symbolName ? options.symbolName.toLowerCase() : undefined;
|
|
33963
|
-
const associated = [];
|
|
33964
|
-
const negative2 = [];
|
|
33965
|
-
const constraints = [];
|
|
33966
|
-
for (const entry of allEntries) {
|
|
33967
|
-
if (entry.status === "archived" || entry.status === "superseded")
|
|
33968
|
-
continue;
|
|
33969
|
-
let isMatch = false;
|
|
33970
|
-
if (entry.anchors && entry.anchors.length > 0) {
|
|
33971
|
-
for (const anc of entry.anchors) {
|
|
33972
|
-
const ancFile = anc.file_path.toLowerCase();
|
|
33973
|
-
const fileMatch = ancFile.includes(normalizedFile) || normalizedFile.includes(ancFile);
|
|
33974
|
-
const symbolMatch = normalizedSymbol && anc.symbol_name ? anc.symbol_name.toLowerCase() === normalizedSymbol : false;
|
|
33975
|
-
if (fileMatch || symbolMatch) {
|
|
33976
|
-
isMatch = true;
|
|
33977
|
-
break;
|
|
33978
|
-
}
|
|
33979
|
-
}
|
|
33980
|
-
}
|
|
33981
|
-
if (!isMatch) {
|
|
33982
|
-
const lowerContent = `${entry.title} ${entry.content}`.toLowerCase();
|
|
33983
|
-
if (lowerContent.includes(normalizedFile)) {
|
|
33984
|
-
isMatch = true;
|
|
33985
|
-
} else if (normalizedSymbol && lowerContent.includes(normalizedSymbol)) {
|
|
33986
|
-
isMatch = true;
|
|
33987
|
-
}
|
|
33988
|
-
}
|
|
33989
|
-
if (isMatch) {
|
|
33990
|
-
if (entry.negative != null || entry.tags?.some((t) => t.includes("negative") || t.includes("anti-pattern"))) {
|
|
33991
|
-
negative2.push(entry);
|
|
33992
|
-
} else if (entry.type === "constraint" || entry.temporal_mode === "timeless") {
|
|
33993
|
-
constraints.push(entry);
|
|
33994
|
-
} else {
|
|
33995
|
-
associated.push(entry);
|
|
33996
|
-
}
|
|
33997
|
-
}
|
|
33998
|
-
}
|
|
33999
|
-
return {
|
|
34000
|
-
file_path: options.filePath,
|
|
34001
|
-
symbol_name: options.symbolName,
|
|
34002
|
-
associated_memories: associated,
|
|
34003
|
-
negative_lessons: negative2,
|
|
34004
|
-
constraints,
|
|
34005
|
-
total_found: associated.length + negative2.length + constraints.length
|
|
34006
|
-
};
|
|
34007
|
-
}
|
|
34008
|
-
var init_bidirectional = __esm(() => {
|
|
34009
|
-
init_store();
|
|
34010
|
-
});
|
|
34011
|
-
|
|
34012
34751
|
// src/orchestrator/profiles.ts
|
|
34013
34752
|
function getProfileToolNames(profile) {
|
|
34014
34753
|
return PROFILE_TOOL_DEFINITIONS[profile] || [];
|
|
@@ -34045,6 +34784,7 @@ var init_profiles = __esm(() => {
|
|
|
34045
34784
|
],
|
|
34046
34785
|
coding: [
|
|
34047
34786
|
"muse_context",
|
|
34787
|
+
"muse_code_impact",
|
|
34048
34788
|
"memory_anchor_create",
|
|
34049
34789
|
"memory_anchor_verify",
|
|
34050
34790
|
"memory_read",
|
|
@@ -34067,6 +34807,8 @@ var init_profiles = __esm(() => {
|
|
|
34067
34807
|
],
|
|
34068
34808
|
review: [
|
|
34069
34809
|
"muse_context",
|
|
34810
|
+
"muse_code_impact",
|
|
34811
|
+
"muse_pr_context",
|
|
34070
34812
|
"muse_health",
|
|
34071
34813
|
"muse_why",
|
|
34072
34814
|
"muse_tech_debt",
|
|
@@ -34079,6 +34821,9 @@ var init_profiles = __esm(() => {
|
|
|
34079
34821
|
],
|
|
34080
34822
|
architecture: [
|
|
34081
34823
|
"muse_context",
|
|
34824
|
+
"muse_code_impact",
|
|
34825
|
+
"muse_pr_context",
|
|
34826
|
+
"muse_reconcile_anchors",
|
|
34082
34827
|
"muse_health",
|
|
34083
34828
|
"muse_why",
|
|
34084
34829
|
"muse_bug_clusters",
|
|
@@ -34102,6 +34847,7 @@ var init_profiles = __esm(() => {
|
|
|
34102
34847
|
],
|
|
34103
34848
|
maintenance: [
|
|
34104
34849
|
"muse_health",
|
|
34850
|
+
"muse_reconcile_anchors",
|
|
34105
34851
|
"memory_lifecycle_status",
|
|
34106
34852
|
"memory_archive",
|
|
34107
34853
|
"memory_rehydrate",
|
|
@@ -34138,12 +34884,12 @@ var init_orchestrator = __esm(() => {
|
|
|
34138
34884
|
});
|
|
34139
34885
|
|
|
34140
34886
|
// src/prompts.ts
|
|
34141
|
-
import { existsSync as
|
|
34142
|
-
import { join as
|
|
34887
|
+
import { existsSync as existsSync48, readFileSync as readFileSync40, writeFileSync as writeFileSync25, mkdirSync as mkdirSync27, readdirSync as readdirSync17 } from "node:fs";
|
|
34888
|
+
import { join as join45 } from "node:path";
|
|
34143
34889
|
function getPromptsDir(memoryDir) {
|
|
34144
34890
|
if (!memoryDir)
|
|
34145
34891
|
return null;
|
|
34146
|
-
return
|
|
34892
|
+
return join45(memoryDir, "prompts");
|
|
34147
34893
|
}
|
|
34148
34894
|
function listPrompts(memoryDir) {
|
|
34149
34895
|
const promptMap = new Map;
|
|
@@ -34151,13 +34897,13 @@ function listPrompts(memoryDir) {
|
|
|
34151
34897
|
promptMap.set(bp.name, bp);
|
|
34152
34898
|
}
|
|
34153
34899
|
const dir = getPromptsDir(memoryDir);
|
|
34154
|
-
if (dir &&
|
|
34155
|
-
const files =
|
|
34900
|
+
if (dir && existsSync48(dir)) {
|
|
34901
|
+
const files = readdirSync17(dir).filter((f) => f.endsWith(".md"));
|
|
34156
34902
|
for (const file of files) {
|
|
34157
34903
|
const name = file.replace(/\.md$/, "");
|
|
34158
|
-
const fullPath =
|
|
34904
|
+
const fullPath = join45(dir, file);
|
|
34159
34905
|
try {
|
|
34160
|
-
const raw =
|
|
34906
|
+
const raw = readFileSync40(fullPath, "utf-8");
|
|
34161
34907
|
const parsed = parsePromptFile(name, raw);
|
|
34162
34908
|
promptMap.set(name, parsed);
|
|
34163
34909
|
} catch {}
|
|
@@ -34169,10 +34915,10 @@ function getPrompt(memoryDir, name) {
|
|
|
34169
34915
|
const safeName = name.replace(/[^a-zA-Z0-9_\-\.]/g, "_");
|
|
34170
34916
|
const dir = getPromptsDir(memoryDir);
|
|
34171
34917
|
if (dir) {
|
|
34172
|
-
const filePath =
|
|
34173
|
-
if (
|
|
34918
|
+
const filePath = join45(dir, `${safeName}.md`);
|
|
34919
|
+
if (existsSync48(filePath)) {
|
|
34174
34920
|
try {
|
|
34175
|
-
const raw =
|
|
34921
|
+
const raw = readFileSync40(filePath, "utf-8");
|
|
34176
34922
|
return parsePromptFile(name, raw);
|
|
34177
34923
|
} catch {}
|
|
34178
34924
|
}
|
|
@@ -34239,10 +34985,10 @@ function renderPrompt(memoryDir, name, args = {}, contextData = {}) {
|
|
|
34239
34985
|
text = text.replace(/\{\{target\}\}/g, args.target ?? "release");
|
|
34240
34986
|
text = text.replace(/\{\{period\}\}/g, args.period ?? "current sprint");
|
|
34241
34987
|
if (memoryDir) {
|
|
34242
|
-
const currentPath =
|
|
34988
|
+
const currentPath = join45(memoryDir, "CURRENT.md");
|
|
34243
34989
|
let currentConstraints = "*(None recorded)*";
|
|
34244
|
-
if (
|
|
34245
|
-
currentConstraints =
|
|
34990
|
+
if (existsSync48(currentPath)) {
|
|
34991
|
+
currentConstraints = readFileSync40(currentPath, "utf-8").trim();
|
|
34246
34992
|
}
|
|
34247
34993
|
text = text.replace(/\{\{current_constraints\}\}/g, currentConstraints);
|
|
34248
34994
|
text = text.replace(/\{\{overdue_items\}\}/g, contextData.overdue_items ?? "*(No overdue items)*");
|
|
@@ -34327,8 +35073,8 @@ Period: {{period}}
|
|
|
34327
35073
|
});
|
|
34328
35074
|
|
|
34329
35075
|
// src/compounding/temporal.ts
|
|
34330
|
-
import { existsSync as
|
|
34331
|
-
import { join as
|
|
35076
|
+
import { existsSync as existsSync49, readFileSync as readFileSync41, writeFileSync as writeFileSync26, mkdirSync as mkdirSync28 } from "node:fs";
|
|
35077
|
+
import { join as join46 } from "node:path";
|
|
34332
35078
|
function getPeriodKey(dateInput, period) {
|
|
34333
35079
|
const date4 = typeof dateInput === "string" ? new Date(dateInput) : dateInput;
|
|
34334
35080
|
const year = date4.getUTCFullYear();
|
|
@@ -34352,10 +35098,10 @@ function getPeriodKey(dateInput, period) {
|
|
|
34352
35098
|
return `${year}-W${String(weekNumber).padStart(2, "0")}`;
|
|
34353
35099
|
}
|
|
34354
35100
|
function compileHotCache(store, memoryDir) {
|
|
34355
|
-
const currentPath =
|
|
35101
|
+
const currentPath = join46(memoryDir, "CURRENT.md");
|
|
34356
35102
|
let constraintsBlock = "*(No active constraints)*";
|
|
34357
|
-
if (
|
|
34358
|
-
constraintsBlock =
|
|
35103
|
+
if (existsSync49(currentPath)) {
|
|
35104
|
+
constraintsBlock = readFileSync41(currentPath, "utf-8").trim();
|
|
34359
35105
|
}
|
|
34360
35106
|
const entries = list(store);
|
|
34361
35107
|
const confirmed = entries.filter((e) => e.status === "confirmed" || e.status === "active");
|
|
@@ -34395,7 +35141,7 @@ function compileHotCache(store, memoryDir) {
|
|
|
34395
35141
|
const hotContent = lines.join(`
|
|
34396
35142
|
`) + `
|
|
34397
35143
|
`;
|
|
34398
|
-
const hotPath =
|
|
35144
|
+
const hotPath = join46(memoryDir, "HOT.md");
|
|
34399
35145
|
mkdirSync28(memoryDir, { recursive: true });
|
|
34400
35146
|
writeFileSync26(hotPath, hotContent, "utf-8");
|
|
34401
35147
|
return hotPath;
|
|
@@ -34448,9 +35194,9 @@ function rollupTemporal(store, options) {
|
|
|
34448
35194
|
}
|
|
34449
35195
|
const summary = `Compiled ${entries.length} memories into ${periodKey} rollup.`;
|
|
34450
35196
|
lines.push("", "---", `*Generated by Muse Memory Temporal Compounding Engine*`);
|
|
34451
|
-
const rollupDir =
|
|
35197
|
+
const rollupDir = join46(memoryDir, "wiki", "rollups");
|
|
34452
35198
|
mkdirSync28(rollupDir, { recursive: true });
|
|
34453
|
-
const filePath =
|
|
35199
|
+
const filePath = join46(rollupDir, `${periodKey}.md`);
|
|
34454
35200
|
writeFileSync26(filePath, lines.join(`
|
|
34455
35201
|
`) + `
|
|
34456
35202
|
`, "utf-8");
|
|
@@ -34468,10 +35214,10 @@ var init_temporal = __esm(() => {
|
|
|
34468
35214
|
});
|
|
34469
35215
|
|
|
34470
35216
|
// src/iterations.ts
|
|
34471
|
-
import { existsSync as
|
|
34472
|
-
import { join as
|
|
35217
|
+
import { existsSync as existsSync50, readFileSync as readFileSync42, appendFileSync as appendFileSync3, writeFileSync as writeFileSync27, mkdirSync as mkdirSync29 } from "node:fs";
|
|
35218
|
+
import { join as join47 } from "node:path";
|
|
34473
35219
|
function getIterationsFilePath(memoryDir) {
|
|
34474
|
-
return
|
|
35220
|
+
return join47(memoryDir, "iterations.jsonl");
|
|
34475
35221
|
}
|
|
34476
35222
|
function recordIteration(memoryDir, input) {
|
|
34477
35223
|
const textToScan = `${input.largest_fix_identified}
|
|
@@ -34497,11 +35243,11 @@ ${input.test_results}`;
|
|
|
34497
35243
|
}
|
|
34498
35244
|
function listIterations(memoryDir) {
|
|
34499
35245
|
const filePath = getIterationsFilePath(memoryDir);
|
|
34500
|
-
if (!
|
|
35246
|
+
if (!existsSync50(filePath)) {
|
|
34501
35247
|
return [];
|
|
34502
35248
|
}
|
|
34503
35249
|
try {
|
|
34504
|
-
const raw =
|
|
35250
|
+
const raw = readFileSync42(filePath, "utf-8");
|
|
34505
35251
|
return raw.split(`
|
|
34506
35252
|
`).map((l) => l.trim()).filter(Boolean).map((l) => JSON.parse(l));
|
|
34507
35253
|
} catch {
|
|
@@ -34510,7 +35256,7 @@ function listIterations(memoryDir) {
|
|
|
34510
35256
|
}
|
|
34511
35257
|
function clearIterations(memoryDir) {
|
|
34512
35258
|
const filePath = getIterationsFilePath(memoryDir);
|
|
34513
|
-
if (
|
|
35259
|
+
if (existsSync50(filePath)) {
|
|
34514
35260
|
writeFileSync27(filePath, "", "utf-8");
|
|
34515
35261
|
}
|
|
34516
35262
|
}
|
|
@@ -34572,17 +35318,17 @@ __export(exports_plasticity, {
|
|
|
34572
35318
|
recordCoActivation: () => recordCoActivation,
|
|
34573
35319
|
saveHebbianGraph: () => saveHebbianGraph
|
|
34574
35320
|
});
|
|
34575
|
-
import { existsSync as
|
|
34576
|
-
import { join as
|
|
35321
|
+
import { existsSync as existsSync51, readFileSync as readFileSync43, writeFileSync as writeFileSync28 } from "node:fs";
|
|
35322
|
+
import { join as join48 } from "node:path";
|
|
34577
35323
|
function getPlasticityPath(memoryDir) {
|
|
34578
|
-
return
|
|
35324
|
+
return join48(memoryDir, "hebbian-plasticity.json");
|
|
34579
35325
|
}
|
|
34580
35326
|
function loadHebbianGraph(memoryDir) {
|
|
34581
35327
|
const p = getPlasticityPath(memoryDir);
|
|
34582
|
-
if (!
|
|
35328
|
+
if (!existsSync51(p))
|
|
34583
35329
|
return {};
|
|
34584
35330
|
try {
|
|
34585
|
-
return JSON.parse(
|
|
35331
|
+
return JSON.parse(readFileSync43(p, "utf8"));
|
|
34586
35332
|
} catch {
|
|
34587
35333
|
return {};
|
|
34588
35334
|
}
|
|
@@ -34681,8 +35427,8 @@ __export(exports_drift, {
|
|
|
34681
35427
|
scanCodeDriftFromDiff: () => scanCodeDriftFromDiff
|
|
34682
35428
|
});
|
|
34683
35429
|
import { execSync as execSync3 } from "node:child_process";
|
|
34684
|
-
import { existsSync as
|
|
34685
|
-
import { join as
|
|
35430
|
+
import { existsSync as existsSync52 } from "node:fs";
|
|
35431
|
+
import { join as join49, isAbsolute as isAbsolute2 } from "node:path";
|
|
34686
35432
|
function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
|
|
34687
35433
|
const root = workspaceRoot || process.cwd();
|
|
34688
35434
|
const normalizedChanged = new Set(changedFiles.map((f) => f.trim().replace(/^[\.\/]+/, "")).filter(Boolean));
|
|
@@ -34696,8 +35442,8 @@ function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
|
|
|
34696
35442
|
const norm = p.trim().replace(/^[\.\/]+/, "");
|
|
34697
35443
|
const matched = Array.from(normalizedChanged).find((cf) => cf === norm || cf.endsWith(`/${norm}`) || norm.endsWith(`/${cf}`));
|
|
34698
35444
|
if (matched) {
|
|
34699
|
-
const fullPath = isAbsolute2(p) ? p :
|
|
34700
|
-
const exists =
|
|
35445
|
+
const fullPath = isAbsolute2(p) ? p : join49(root, p);
|
|
35446
|
+
const exists = existsSync52(fullPath);
|
|
34701
35447
|
drifted.push({
|
|
34702
35448
|
memoryId: entry.id,
|
|
34703
35449
|
title: entry.title,
|
|
@@ -34774,7 +35520,7 @@ __export(exports_mcp, {
|
|
|
34774
35520
|
createServer: () => createServer2,
|
|
34775
35521
|
runMcpServer: () => runMcpServer
|
|
34776
35522
|
});
|
|
34777
|
-
import { basename } from "node:path";
|
|
35523
|
+
import { basename as basename4 } from "node:path";
|
|
34778
35524
|
function createServer2(targetDir, requestedProfile) {
|
|
34779
35525
|
const activeProfile = getActiveMcpProfile(requestedProfile);
|
|
34780
35526
|
const resolvedTarget = targetDir || process.env.MUSE_MEMORY_PROJECT_DIR || process.env.PROJECT_ROOT || process.cwd();
|
|
@@ -36159,6 +36905,44 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
36159
36905
|
},
|
|
36160
36906
|
required: ["path"]
|
|
36161
36907
|
}
|
|
36908
|
+
},
|
|
36909
|
+
{
|
|
36910
|
+
name: "muse_code_impact",
|
|
36911
|
+
description: "Evaluates comprehensive code and memory impact before editing: callers, test suites, ADRs, negative warnings, active constraints, and composite risk level",
|
|
36912
|
+
inputSchema: {
|
|
36913
|
+
type: "object",
|
|
36914
|
+
properties: {
|
|
36915
|
+
file_path: { type: "string", description: "Target source file path to analyze" },
|
|
36916
|
+
symbol_name: { type: "string", description: "Optional specific function, class, or symbol name" },
|
|
36917
|
+
dir: { type: "string", description: "Optional workspace directory" }
|
|
36918
|
+
},
|
|
36919
|
+
required: ["file_path"]
|
|
36920
|
+
}
|
|
36921
|
+
},
|
|
36922
|
+
{
|
|
36923
|
+
name: "muse_pr_context",
|
|
36924
|
+
description: "Generates rich GitHub PR descriptions from git diff linking touched code anchors, respected ADRs, tested invariants, and composite risk assessment",
|
|
36925
|
+
inputSchema: {
|
|
36926
|
+
type: "object",
|
|
36927
|
+
properties: {
|
|
36928
|
+
base_branch: { type: "string", description: "Base git branch to diff against (default: 'main')" },
|
|
36929
|
+
dir: { type: "string", description: "Optional workspace directory" }
|
|
36930
|
+
}
|
|
36931
|
+
}
|
|
36932
|
+
},
|
|
36933
|
+
{
|
|
36934
|
+
name: "muse_reconcile_anchors",
|
|
36935
|
+
description: "Interactively audits, prunes, or updates drifted and orphaned code anchors across memories when code is refactored or deleted",
|
|
36936
|
+
inputSchema: {
|
|
36937
|
+
type: "object",
|
|
36938
|
+
properties: {
|
|
36939
|
+
prune: { type: "boolean", description: "Whether to prune orphaned anchors (default: false)" },
|
|
36940
|
+
mark_stale: { type: "boolean", description: "Whether to mark memories stale if all anchors are orphaned (default: false)" },
|
|
36941
|
+
update_hashes: { type: "boolean", description: "Whether to update structural hashes for drifted anchors (default: false)" },
|
|
36942
|
+
dry_run: { type: "boolean", description: "Whether to simulate without saving changes (default: true)" },
|
|
36943
|
+
dir: { type: "string", description: "Optional workspace directory" }
|
|
36944
|
+
}
|
|
36945
|
+
}
|
|
36162
36946
|
}
|
|
36163
36947
|
];
|
|
36164
36948
|
return { tools: filterToolsForProfile(allTools, activeProfile) };
|
|
@@ -36253,7 +37037,7 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
36253
37037
|
const text = String(a.constraint || a.text || "");
|
|
36254
37038
|
if (!text.trim())
|
|
36255
37039
|
return toolError("Missing constraint text to append");
|
|
36256
|
-
const projectName = a.project ? String(a.project) :
|
|
37040
|
+
const projectName = a.project ? String(a.project) : basename4(activeRoot) || "default";
|
|
36257
37041
|
const updated = setCurrent(activeMemoryDir, text, projectName);
|
|
36258
37042
|
syncConstraints(activeMemoryDir, activeStore);
|
|
36259
37043
|
return toolResult({ success: true, updated_constraints: updated });
|
|
@@ -36283,7 +37067,7 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
36283
37067
|
}
|
|
36284
37068
|
case "propose":
|
|
36285
37069
|
case "memory_capture": {
|
|
36286
|
-
const projectName = a.project ? String(a.project) :
|
|
37070
|
+
const projectName = a.project ? String(a.project) : basename4(activeRoot) || "default";
|
|
36287
37071
|
try {
|
|
36288
37072
|
const entry = propose(activeStore, {
|
|
36289
37073
|
content: String(a.content),
|
|
@@ -37134,6 +37918,40 @@ Path: ${item.path}`,
|
|
|
37134
37918
|
return toolResult({ success: true, action: "linked", path: targetPath });
|
|
37135
37919
|
}
|
|
37136
37920
|
}
|
|
37921
|
+
case "muse_code_impact": {
|
|
37922
|
+
const filePath = a.file_path;
|
|
37923
|
+
if (!filePath)
|
|
37924
|
+
return toolError("Missing required 'file_path' argument");
|
|
37925
|
+
const symbolName = a.symbol_name;
|
|
37926
|
+
const result = await analyzeMemoryCodeImpact(activeStore, {
|
|
37927
|
+
filePath,
|
|
37928
|
+
symbolName,
|
|
37929
|
+
workspaceRoot: activeRoot
|
|
37930
|
+
});
|
|
37931
|
+
return toolResult(result);
|
|
37932
|
+
}
|
|
37933
|
+
case "muse_pr_context": {
|
|
37934
|
+
const baseBranch = a.base_branch || "main";
|
|
37935
|
+
const result = await generatePrContext(activeStore, {
|
|
37936
|
+
baseBranch,
|
|
37937
|
+
workspaceRoot: activeRoot
|
|
37938
|
+
});
|
|
37939
|
+
return toolResult(result);
|
|
37940
|
+
}
|
|
37941
|
+
case "muse_reconcile_anchors": {
|
|
37942
|
+
const prune = a.prune === true;
|
|
37943
|
+
const markStale2 = a.mark_stale === true;
|
|
37944
|
+
const updateHashes = a.update_hashes === true;
|
|
37945
|
+
const dryRun = a.dry_run !== false;
|
|
37946
|
+
const report = await reconcileCodeAnchors(activeStore, {
|
|
37947
|
+
prune,
|
|
37948
|
+
markStale: markStale2,
|
|
37949
|
+
updateHashes,
|
|
37950
|
+
dryRun,
|
|
37951
|
+
workspaceRoot: activeRoot
|
|
37952
|
+
});
|
|
37953
|
+
return toolResult(report);
|
|
37954
|
+
}
|
|
37137
37955
|
default:
|
|
37138
37956
|
return toolError(`unknown tool ${name}`);
|
|
37139
37957
|
}
|
|
@@ -37206,6 +38024,8 @@ var init_mcp = __esm(() => {
|
|
|
37206
38024
|
init_adrs();
|
|
37207
38025
|
init_cognition();
|
|
37208
38026
|
init_health();
|
|
38027
|
+
init_intelligence();
|
|
38028
|
+
init_compaction();
|
|
37209
38029
|
init_sync();
|
|
37210
38030
|
init_mesh();
|
|
37211
38031
|
init_orchestrator();
|
|
@@ -37222,8 +38042,8 @@ __export(exports_daemon, {
|
|
|
37222
38042
|
startHub: () => startHub
|
|
37223
38043
|
});
|
|
37224
38044
|
import { createServer as createServer3 } from "node:http";
|
|
37225
|
-
import { existsSync as
|
|
37226
|
-
import { join as
|
|
38045
|
+
import { existsSync as existsSync53 } from "node:fs";
|
|
38046
|
+
import { join as join50 } from "node:path";
|
|
37227
38047
|
import { watch } from "node:fs";
|
|
37228
38048
|
function startHub(port, memoryDir) {
|
|
37229
38049
|
const clients = new Set;
|
|
@@ -37289,7 +38109,7 @@ data: ${JSON.stringify(event)}
|
|
|
37289
38109
|
return clients.size;
|
|
37290
38110
|
}
|
|
37291
38111
|
if (memoryDir) {
|
|
37292
|
-
const memoriesDir =
|
|
38112
|
+
const memoriesDir = join50(memoryDir, "memories");
|
|
37293
38113
|
const armDebounced = (type2) => {
|
|
37294
38114
|
if (debounceTimer)
|
|
37295
38115
|
clearTimeout(debounceTimer);
|
|
@@ -37298,11 +38118,11 @@ data: ${JSON.stringify(event)}
|
|
|
37298
38118
|
}, DEBOUNCE_MS);
|
|
37299
38119
|
};
|
|
37300
38120
|
try {
|
|
37301
|
-
if (
|
|
38121
|
+
if (existsSync53(memoriesDir)) {
|
|
37302
38122
|
watchers.push(watch(memoriesDir, () => armDebounced("memory.changed")));
|
|
37303
38123
|
}
|
|
37304
|
-
const currentMd =
|
|
37305
|
-
if (
|
|
38124
|
+
const currentMd = join50(memoryDir, "CURRENT.md");
|
|
38125
|
+
if (existsSync53(currentMd)) {
|
|
37306
38126
|
watchers.push(watch(currentMd, () => armDebounced("constraints.changed")));
|
|
37307
38127
|
}
|
|
37308
38128
|
} catch {}
|
|
@@ -37335,14 +38155,14 @@ var DEBOUNCE_MS = 300;
|
|
|
37335
38155
|
var init_daemon = () => {};
|
|
37336
38156
|
|
|
37337
38157
|
// src/cli/ecosystem.ts
|
|
37338
|
-
import { join as
|
|
37339
|
-
import { existsSync as
|
|
38158
|
+
import { join as join51 } from "node:path";
|
|
38159
|
+
import { existsSync as existsSync54, mkdirSync as mkdirSync30, writeFileSync as writeFileSync29, readFileSync as readFileSync44 } from "node:fs";
|
|
37340
38160
|
import { homedir as homedir7 } from "node:os";
|
|
37341
38161
|
function ensureProjectAgentInstructions(targetDir) {
|
|
37342
|
-
const agentsMdPath =
|
|
37343
|
-
if (
|
|
38162
|
+
const agentsMdPath = join51(targetDir, "AGENTS.md");
|
|
38163
|
+
if (existsSync54(agentsMdPath)) {
|
|
37344
38164
|
try {
|
|
37345
|
-
const existing =
|
|
38165
|
+
const existing = readFileSync44(agentsMdPath, "utf8");
|
|
37346
38166
|
if (existing.includes("<!-- agentmemory:start -->")) {
|
|
37347
38167
|
const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
|
|
37348
38168
|
writeFileSync29(agentsMdPath, updated, "utf8");
|
|
@@ -37363,18 +38183,18 @@ ${MUSE_MEMORY_DIRECTIVE}
|
|
|
37363
38183
|
}
|
|
37364
38184
|
async function handleInstallCommand({ positional, flags }) {
|
|
37365
38185
|
const isGlobal = flags["global"] === "true" || flags["g"] === "true";
|
|
37366
|
-
const targetDir = positional[0] ?
|
|
37367
|
-
const memoryDir = isGlobal ? getGlobalMemoryDir() :
|
|
38186
|
+
const targetDir = positional[0] ? join51(process.cwd(), positional[0]) : process.cwd();
|
|
38187
|
+
const memoryDir = isGlobal ? getGlobalMemoryDir() : join51(targetDir, ".memory");
|
|
37368
38188
|
const globalDir = getGlobalMemoryDir();
|
|
37369
|
-
mkdirSync30(
|
|
37370
|
-
mkdirSync30(
|
|
37371
|
-
const currentPath =
|
|
37372
|
-
if (!
|
|
38189
|
+
mkdirSync30(join51(memoryDir, "memories"), { recursive: true });
|
|
38190
|
+
mkdirSync30(join51(globalDir, "memories"), { recursive: true });
|
|
38191
|
+
const currentPath = join51(memoryDir, "CURRENT.md");
|
|
38192
|
+
if (!existsSync54(currentPath)) {
|
|
37373
38193
|
writeFileSync29(currentPath, `# Active Project Constraints
|
|
37374
38194
|
`, "utf8");
|
|
37375
38195
|
}
|
|
37376
38196
|
const globalUserPath = userFilePath(globalDir);
|
|
37377
|
-
if (!
|
|
38197
|
+
if (!existsSync54(globalUserPath)) {
|
|
37378
38198
|
const { promptSingleSelect: promptSingleSelect2 } = await Promise.resolve().then(() => (init_prompt(), exports_prompt));
|
|
37379
38199
|
const archetypeOptions = [
|
|
37380
38200
|
{ id: "developer", label: "Software Engineer / Developer", hint: "Code-first, direct, strict typing" },
|
|
@@ -37390,10 +38210,10 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
37390
38210
|
if (!isGlobal) {
|
|
37391
38211
|
ensureProjectAgentInstructions(targetDir);
|
|
37392
38212
|
}
|
|
37393
|
-
const globalAgentsMd =
|
|
37394
|
-
if (
|
|
38213
|
+
const globalAgentsMd = join51(homedir7(), ".agents", "AGENTS.md");
|
|
38214
|
+
if (existsSync54(globalAgentsMd)) {
|
|
37395
38215
|
try {
|
|
37396
|
-
const existing =
|
|
38216
|
+
const existing = readFileSync44(globalAgentsMd, "utf8");
|
|
37397
38217
|
if (existing.includes("<!-- agentmemory:start -->")) {
|
|
37398
38218
|
const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
|
|
37399
38219
|
writeFileSync29(globalAgentsMd, updated, "utf8");
|
|
@@ -37457,11 +38277,11 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
37457
38277
|
return 0;
|
|
37458
38278
|
}
|
|
37459
38279
|
async function promptOrNotifyGitHook(targetDir, autoInstall = false) {
|
|
37460
|
-
const gitDir =
|
|
37461
|
-
if (!
|
|
38280
|
+
const gitDir = join51(targetDir, ".git");
|
|
38281
|
+
if (!existsSync54(gitDir))
|
|
37462
38282
|
return false;
|
|
37463
|
-
const hookPath =
|
|
37464
|
-
const isInstalled =
|
|
38283
|
+
const hookPath = join51(gitDir, "hooks", "pre-commit");
|
|
38284
|
+
const isInstalled = existsSync54(hookPath) && readFileSync44(hookPath, "utf8").includes("memory harvest-auto");
|
|
37465
38285
|
if (isInstalled)
|
|
37466
38286
|
return true;
|
|
37467
38287
|
if (autoInstall) {
|
|
@@ -37517,7 +38337,7 @@ async function handleUninstallCommand({ positional, flags }) {
|
|
|
37517
38337
|
action: async () => {
|
|
37518
38338
|
if (purge) {
|
|
37519
38339
|
const ctx = requireRoot(flags);
|
|
37520
|
-
if (ctx &&
|
|
38340
|
+
if (ctx && existsSync54(ctx.memoryDir) && !dryRun) {
|
|
37521
38341
|
const { rmSync: rmSync3 } = await import("node:fs");
|
|
37522
38342
|
rmSync3(ctx.memoryDir, { recursive: true, force: true });
|
|
37523
38343
|
}
|
|
@@ -37549,12 +38369,12 @@ async function handleUninstallCommand({ positional, flags }) {
|
|
|
37549
38369
|
}
|
|
37550
38370
|
async function handleInitCommand({ positional, flags }) {
|
|
37551
38371
|
const isGlobal = flags["global"] === "true";
|
|
37552
|
-
const targetDir = positional[0] ?
|
|
38372
|
+
const targetDir = positional[0] ? join51(process.cwd(), positional[0]) : process.cwd();
|
|
37553
38373
|
const memoryDirName = flags["legacy"] === "true" ? ".musememory" : ".memory";
|
|
37554
|
-
const memoryDir = isGlobal ? getGlobalMemoryDir() :
|
|
37555
|
-
mkdirSync30(
|
|
37556
|
-
const currentPath =
|
|
37557
|
-
if (!
|
|
38374
|
+
const memoryDir = isGlobal ? getGlobalMemoryDir() : join51(targetDir, memoryDirName);
|
|
38375
|
+
mkdirSync30(join51(memoryDir, "memories"), { recursive: true });
|
|
38376
|
+
const currentPath = join51(memoryDir, "CURRENT.md");
|
|
38377
|
+
if (!existsSync54(currentPath)) {
|
|
37558
38378
|
writeFileSync29(currentPath, `# Active Project Constraints
|
|
37559
38379
|
`, "utf8");
|
|
37560
38380
|
}
|
|
@@ -37851,8 +38671,8 @@ var init_ecosystem = __esm(() => {
|
|
|
37851
38671
|
});
|
|
37852
38672
|
|
|
37853
38673
|
// src/agentcontract.ts
|
|
37854
|
-
import { existsSync as
|
|
37855
|
-
import { join as
|
|
38674
|
+
import { existsSync as existsSync55 } from "node:fs";
|
|
38675
|
+
import { join as join52 } from "node:path";
|
|
37856
38676
|
function parseAgentMemoryContract(markdown) {
|
|
37857
38677
|
if (!markdown || !markdown.startsWith("---"))
|
|
37858
38678
|
return null;
|
|
@@ -37884,17 +38704,17 @@ function parseAgentMemoryContract(markdown) {
|
|
|
37884
38704
|
function resolveAgentFile(nameOrPath, workspaceRoot) {
|
|
37885
38705
|
if (!nameOrPath)
|
|
37886
38706
|
return null;
|
|
37887
|
-
if (
|
|
38707
|
+
if (existsSync55(nameOrPath))
|
|
37888
38708
|
return nameOrPath;
|
|
37889
38709
|
const candidates = [
|
|
37890
|
-
|
|
37891
|
-
|
|
38710
|
+
join52(workspaceRoot, ".agents", `${nameOrPath}.md`),
|
|
38711
|
+
join52(workspaceRoot, ".memory", "agents", `${nameOrPath}.md`)
|
|
37892
38712
|
];
|
|
37893
38713
|
const home = process.env.HOME;
|
|
37894
38714
|
if (home)
|
|
37895
|
-
candidates.push(
|
|
38715
|
+
candidates.push(join52(home, ".config", "opencode", "agents", `${nameOrPath}.md`));
|
|
37896
38716
|
for (const c of candidates) {
|
|
37897
|
-
if (
|
|
38717
|
+
if (existsSync55(c))
|
|
37898
38718
|
return c;
|
|
37899
38719
|
}
|
|
37900
38720
|
return null;
|
|
@@ -37904,8 +38724,8 @@ var init_agentcontract = __esm(() => {
|
|
|
37904
38724
|
});
|
|
37905
38725
|
|
|
37906
38726
|
// src/cli/retrieval.ts
|
|
37907
|
-
import { existsSync as
|
|
37908
|
-
import { join as
|
|
38727
|
+
import { existsSync as existsSync56, readFileSync as readFileSync45 } from "node:fs";
|
|
38728
|
+
import { join as join53 } from "node:path";
|
|
37909
38729
|
async function handleContextCommand({ positional, flags }) {
|
|
37910
38730
|
let agentTypes;
|
|
37911
38731
|
let agentTags;
|
|
@@ -37913,7 +38733,7 @@ async function handleContextCommand({ positional, flags }) {
|
|
|
37913
38733
|
const file = resolveAgentFile(flags["for-agent"], flags["dir"] ?? process.cwd());
|
|
37914
38734
|
if (!file)
|
|
37915
38735
|
return usageError(`--for-agent: cannot resolve agent '${flags["for-agent"]}'`);
|
|
37916
|
-
const contract = parseAgentMemoryContract(
|
|
38736
|
+
const contract = parseAgentMemoryContract(readFileSync45(file, "utf8"));
|
|
37917
38737
|
if (contract) {
|
|
37918
38738
|
agentTypes = contract.types;
|
|
37919
38739
|
agentTags = contract.tags;
|
|
@@ -38073,7 +38893,7 @@ async function handleHarvestCommand({ positional, flags }) {
|
|
|
38073
38893
|
const project = flags["project"];
|
|
38074
38894
|
if (!project)
|
|
38075
38895
|
return usageError("harvest requires --project");
|
|
38076
|
-
const rawText =
|
|
38896
|
+
const rawText = existsSync56(target) ? readFileSync45(target, "utf8") : target;
|
|
38077
38897
|
const created = harvestMemories(ctx.store, {
|
|
38078
38898
|
text: rawText,
|
|
38079
38899
|
project,
|
|
@@ -38109,8 +38929,8 @@ async function handleSearchTranscriptCommand({ positional, flags }) {
|
|
|
38109
38929
|
const filePath = positional[1];
|
|
38110
38930
|
if (!query)
|
|
38111
38931
|
return usageError("search-transcript requires <query> [file.jsonl]");
|
|
38112
|
-
const targetFile = filePath ? filePath.startsWith("/") ? filePath :
|
|
38113
|
-
if (!
|
|
38932
|
+
const targetFile = filePath ? filePath.startsWith("/") ? filePath : join53(process.cwd(), filePath) : join53(process.cwd(), "transcript.jsonl");
|
|
38933
|
+
if (!existsSync56(targetFile)) {
|
|
38114
38934
|
return fail(`error: transcript file not found: ${targetFile}`);
|
|
38115
38935
|
}
|
|
38116
38936
|
const windowSize = flags["window"] ? parseInt(flags["window"], 10) : 2;
|
|
@@ -38126,7 +38946,7 @@ async function handleReindexCommand({ flags }) {
|
|
|
38126
38946
|
const { rebuildIndex: rebuildIndex2, saveIndex: saveIndex2 } = await Promise.resolve().then(() => (init_vector(), exports_vector));
|
|
38127
38947
|
const index = rebuildIndex2(ctx.store);
|
|
38128
38948
|
saveIndex2(index, ctx.memoryDir);
|
|
38129
|
-
console.log(`indexed ${Object.keys(index.entries).length} entries -> ${
|
|
38949
|
+
console.log(`indexed ${Object.keys(index.entries).length} entries -> ${join53(ctx.memoryDir, "index.json")}`);
|
|
38130
38950
|
return 0;
|
|
38131
38951
|
}
|
|
38132
38952
|
async function handleHookCommand({ positional, flags }) {
|
|
@@ -38518,7 +39338,7 @@ var init_entities2 = __esm(() => {
|
|
|
38518
39338
|
});
|
|
38519
39339
|
|
|
38520
39340
|
// src/cli/settings.ts
|
|
38521
|
-
import { writeFileSync as writeFileSync30, readFileSync as
|
|
39341
|
+
import { writeFileSync as writeFileSync30, readFileSync as readFileSync46 } from "node:fs";
|
|
38522
39342
|
function handleSettingsCommand(parsed) {
|
|
38523
39343
|
const ctx = requireRoot(parsed.flags);
|
|
38524
39344
|
if (!ctx)
|
|
@@ -38614,7 +39434,7 @@ function handleSettingsCommand(parsed) {
|
|
|
38614
39434
|
return 2;
|
|
38615
39435
|
}
|
|
38616
39436
|
try {
|
|
38617
|
-
const raw =
|
|
39437
|
+
const raw = readFileSync46(file, "utf8");
|
|
38618
39438
|
importSettings(memoryDir, raw);
|
|
38619
39439
|
console.log(`Successfully imported settings from ${file}`);
|
|
38620
39440
|
return 0;
|
|
@@ -38637,16 +39457,16 @@ var init_nudge = __esm(() => {
|
|
|
38637
39457
|
});
|
|
38638
39458
|
|
|
38639
39459
|
// src/routines.ts
|
|
38640
|
-
import { readFileSync as
|
|
38641
|
-
import { join as
|
|
39460
|
+
import { readFileSync as readFileSync47, existsSync as existsSync57 } from "node:fs";
|
|
39461
|
+
import { join as join54 } from "node:path";
|
|
38642
39462
|
function routinesPath(memoryDir) {
|
|
38643
|
-
return
|
|
39463
|
+
return join54(memoryDir, "routines.yaml");
|
|
38644
39464
|
}
|
|
38645
39465
|
function loadRoutines(memoryDir) {
|
|
38646
39466
|
const p = routinesPath(memoryDir);
|
|
38647
|
-
if (!
|
|
39467
|
+
if (!existsSync57(p))
|
|
38648
39468
|
return { routines: {} };
|
|
38649
|
-
const doc2 = yaml.load(
|
|
39469
|
+
const doc2 = yaml.load(readFileSync47(p, "utf8"), { schema: yaml.JSON_SCHEMA }) ?? {};
|
|
38650
39470
|
const routines = doc2.routines ?? {};
|
|
38651
39471
|
for (const [name, r] of Object.entries(routines)) {
|
|
38652
39472
|
if (!r || typeof r.schedule !== "string" || !r.schedule.trim()) {
|
|
@@ -38684,7 +39504,7 @@ var init_routines = __esm(() => {
|
|
|
38684
39504
|
});
|
|
38685
39505
|
|
|
38686
39506
|
// src/cli/lifecycle.ts
|
|
38687
|
-
import { writeFileSync as writeFileSync31, readFileSync as
|
|
39507
|
+
import { writeFileSync as writeFileSync31, readFileSync as readFileSync48, existsSync as existsSync58 } from "node:fs";
|
|
38688
39508
|
async function handleProposeCommand({ positional, flags }) {
|
|
38689
39509
|
const ctx = requireRoot(flags);
|
|
38690
39510
|
if (!ctx)
|
|
@@ -38847,9 +39667,9 @@ async function handleImportCommand({ positional, flags }) {
|
|
|
38847
39667
|
const file = positional[0];
|
|
38848
39668
|
if (!file)
|
|
38849
39669
|
return usageError("import requires <file.json>");
|
|
38850
|
-
if (!
|
|
39670
|
+
if (!existsSync58(file))
|
|
38851
39671
|
return fail(`error: file ${file} does not exist`);
|
|
38852
|
-
const raw = JSON.parse(
|
|
39672
|
+
const raw = JSON.parse(readFileSync48(file, "utf8"));
|
|
38853
39673
|
const res = importSnapshot(ctx.store, raw, { overwrite: flags["overwrite"] === "true" });
|
|
38854
39674
|
if (res.errors.length > 0) {
|
|
38855
39675
|
console.error(`import encountered errors:`);
|
|
@@ -39485,6 +40305,190 @@ var init_evolution = __esm(() => {
|
|
|
39485
40305
|
init_iterations();
|
|
39486
40306
|
});
|
|
39487
40307
|
|
|
40308
|
+
// src/benchmark/suite.ts
|
|
40309
|
+
import { performance } from "node:perf_hooks";
|
|
40310
|
+
function estimateTokens3(text) {
|
|
40311
|
+
return Math.max(1, Math.ceil(text.length / 4));
|
|
40312
|
+
}
|
|
40313
|
+
function calculatePercentiles(samples, unit) {
|
|
40314
|
+
if (samples.length === 0) {
|
|
40315
|
+
return { min: 0, p50: 0, p95: 0, p99: 0, max: 0, unit };
|
|
40316
|
+
}
|
|
40317
|
+
const sorted = [...samples].sort((a, b) => a - b);
|
|
40318
|
+
const min = Math.round(sorted[0] * 100) / 100;
|
|
40319
|
+
const max = Math.round(sorted[sorted.length - 1] * 100) / 100;
|
|
40320
|
+
const p50 = Math.round(sorted[Math.floor(sorted.length * 0.5)] * 100) / 100;
|
|
40321
|
+
const p95 = Math.round(sorted[Math.floor(sorted.length * 0.95)] * 100) / 100;
|
|
40322
|
+
const p99 = Math.round(sorted[Math.floor(sorted.length * 0.99)] * 100) / 100;
|
|
40323
|
+
return { min, p50, p95, p99, max, unit };
|
|
40324
|
+
}
|
|
40325
|
+
async function runMemoryBenchmark(store, options = {}) {
|
|
40326
|
+
const iterations = options.iterations || 30;
|
|
40327
|
+
const testQuery = options.query || "authentication architecture security";
|
|
40328
|
+
const tokenBudget = options.tokenBudget || 1500;
|
|
40329
|
+
const coldStartT0 = performance.now();
|
|
40330
|
+
const coldStore = openStore(store.memoryDir || store.dir);
|
|
40331
|
+
const allEntries = list(coldStore);
|
|
40332
|
+
const entriesCount = allEntries.length;
|
|
40333
|
+
const cold_startup_ms = Math.round((performance.now() - coldStartT0) * 100) / 100;
|
|
40334
|
+
const hotSamplesUs = [];
|
|
40335
|
+
if (entriesCount > 0) {
|
|
40336
|
+
const sampleId = allEntries[0].id;
|
|
40337
|
+
for (let i = 0;i < iterations * 5; i++) {
|
|
40338
|
+
const t0 = performance.now();
|
|
40339
|
+
get(store, sampleId);
|
|
40340
|
+
const us = (performance.now() - t0) * 1000;
|
|
40341
|
+
hotSamplesUs.push(us);
|
|
40342
|
+
}
|
|
40343
|
+
} else {
|
|
40344
|
+
hotSamplesUs.push(5);
|
|
40345
|
+
}
|
|
40346
|
+
const hot_cache_lookup = calculatePercentiles(hotSamplesUs, "µs");
|
|
40347
|
+
const ftsSamplesMs = [];
|
|
40348
|
+
for (let i = 0;i < iterations; i++) {
|
|
40349
|
+
const t0 = performance.now();
|
|
40350
|
+
await rankAndRetrieveMemories(store, testQuery, {
|
|
40351
|
+
limit: 10,
|
|
40352
|
+
tokenBudget
|
|
40353
|
+
});
|
|
40354
|
+
ftsSamplesMs.push(performance.now() - t0);
|
|
40355
|
+
}
|
|
40356
|
+
const fts5_search = calculatePercentiles(ftsSamplesMs, "ms");
|
|
40357
|
+
const knapsackSamplesMs = [];
|
|
40358
|
+
for (let i = 0;i < iterations; i++) {
|
|
40359
|
+
const t0 = performance.now();
|
|
40360
|
+
await rankAndRetrieveMemories(store, testQuery, {
|
|
40361
|
+
limit: 25,
|
|
40362
|
+
tokenBudget: 800
|
|
40363
|
+
});
|
|
40364
|
+
knapsackSamplesMs.push(performance.now() - t0);
|
|
40365
|
+
}
|
|
40366
|
+
const knapsack_ranking = calculatePercentiles(knapsackSamplesMs, "ms");
|
|
40367
|
+
const contextSamplesMs = [];
|
|
40368
|
+
let lastPackedTokens = 0;
|
|
40369
|
+
for (let i = 0;i < Math.min(iterations, 15); i++) {
|
|
40370
|
+
const t0 = performance.now();
|
|
40371
|
+
const ctx = await resolveMuseContext(store, options.workspaceRoot || store.dir || process.cwd(), {
|
|
40372
|
+
query: testQuery,
|
|
40373
|
+
token_budget: tokenBudget
|
|
40374
|
+
});
|
|
40375
|
+
contextSamplesMs.push(performance.now() - t0);
|
|
40376
|
+
lastPackedTokens = ctx.tokens_used;
|
|
40377
|
+
}
|
|
40378
|
+
const context_assembly = calculatePercentiles(contextSamplesMs, "ms");
|
|
40379
|
+
const conflictCount = allEntries.filter((e) => e.status === "conflicted").length;
|
|
40380
|
+
const staleCount = allEntries.filter((e) => e.status === "stale").length;
|
|
40381
|
+
const duplicateCount = 0;
|
|
40382
|
+
const conflictRatePct = entriesCount > 0 ? Math.round(conflictCount / entriesCount * 1000) / 10 : 0;
|
|
40383
|
+
const staleRatePct = entriesCount > 0 ? Math.round(staleCount / entriesCount * 1000) / 10 : 0;
|
|
40384
|
+
let roiSuccessRatePct = 100;
|
|
40385
|
+
try {
|
|
40386
|
+
const roi = computeMemoryRoi(store);
|
|
40387
|
+
roiSuccessRatePct = Math.round(roi.overallReuseSuccessRate * 100);
|
|
40388
|
+
} catch {}
|
|
40389
|
+
let rawTokensTotal = 0;
|
|
40390
|
+
for (const e of allEntries) {
|
|
40391
|
+
rawTokensTotal += estimateTokens3(`${e.title}
|
|
40392
|
+
${e.content}`);
|
|
40393
|
+
}
|
|
40394
|
+
const packedAvg = lastPackedTokens || Math.min(rawTokensTotal, tokenBudget);
|
|
40395
|
+
const compressionRatioPct = rawTokensTotal > 0 ? Math.round((1 - packedAvg / Math.max(1, rawTokensTotal)) * 100) : 0;
|
|
40396
|
+
return {
|
|
40397
|
+
iterations,
|
|
40398
|
+
timestamp: new Date().toISOString(),
|
|
40399
|
+
speed: {
|
|
40400
|
+
cold_startup_ms,
|
|
40401
|
+
hot_cache_lookup,
|
|
40402
|
+
fts5_search,
|
|
40403
|
+
knapsack_ranking,
|
|
40404
|
+
context_assembly
|
|
40405
|
+
},
|
|
40406
|
+
quality: {
|
|
40407
|
+
total_memories: entriesCount,
|
|
40408
|
+
duplicate_rate_pct: duplicateCount,
|
|
40409
|
+
conflict_rate_pct: conflictRatePct,
|
|
40410
|
+
stale_rate_pct: staleRatePct,
|
|
40411
|
+
roi_success_rate_pct: roiSuccessRatePct
|
|
40412
|
+
},
|
|
40413
|
+
tokens: {
|
|
40414
|
+
raw_tokens_total: rawTokensTotal,
|
|
40415
|
+
packed_tokens_avg: packedAvg,
|
|
40416
|
+
compression_ratio_pct: Math.max(0, compressionRatioPct)
|
|
40417
|
+
}
|
|
40418
|
+
};
|
|
40419
|
+
}
|
|
40420
|
+
function formatBenchmarkScoreboard(report) {
|
|
40421
|
+
const header = `
|
|
40422
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
40423
|
+
│ ⚡ MUSE MEMORY ENGINE BENCHMARK & TELEMETRY SCOREBOARD │
|
|
40424
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
40425
|
+
`;
|
|
40426
|
+
let out = header;
|
|
40427
|
+
out += `
|
|
40428
|
+
Benchmark Runs: ${report.iterations} iterations
|
|
40429
|
+
`;
|
|
40430
|
+
out += `Timestamp: ${report.timestamp}
|
|
40431
|
+
`;
|
|
40432
|
+
out += `
|
|
40433
|
+
\uD83C\uDFCE️ SPEED & LATENCY PROFILE:
|
|
40434
|
+
`;
|
|
40435
|
+
out += ` ┌─────────────────────────┬──────────┬──────────┬──────────┬──────────┐
|
|
40436
|
+
`;
|
|
40437
|
+
out += ` │ Operation │ Min │ P50 │ P95 │ P99 │
|
|
40438
|
+
`;
|
|
40439
|
+
out += ` ├─────────────────────────┼──────────┼──────────┼──────────┼──────────┤
|
|
40440
|
+
`;
|
|
40441
|
+
out += ` │ Hot Cache Lookup │ ${(report.speed.hot_cache_lookup.min + " µs").padEnd(8)} │ ${(report.speed.hot_cache_lookup.p50 + " µs").padEnd(8)} │ ${(report.speed.hot_cache_lookup.p95 + " µs").padEnd(8)} │ ${(report.speed.hot_cache_lookup.p99 + " µs").padEnd(8)} │
|
|
40442
|
+
`;
|
|
40443
|
+
out += ` │ FTS5 BM25 Retrieval │ ${(report.speed.fts5_search.min + " ms").padEnd(8)} │ ${(report.speed.fts5_search.p50 + " ms").padEnd(8)} │ ${(report.speed.fts5_search.p95 + " ms").padEnd(8)} │ ${(report.speed.fts5_search.p99 + " ms").padEnd(8)} │
|
|
40444
|
+
`;
|
|
40445
|
+
out += ` │ Knapsack Ranking │ ${(report.speed.knapsack_ranking.min + " ms").padEnd(8)} │ ${(report.speed.knapsack_ranking.p50 + " ms").padEnd(8)} │ ${(report.speed.knapsack_ranking.p95 + " ms").padEnd(8)} │ ${(report.speed.knapsack_ranking.p99 + " ms").padEnd(8)} │
|
|
40446
|
+
`;
|
|
40447
|
+
out += ` │ Context Assembly │ ${(report.speed.context_assembly.min + " ms").padEnd(8)} │ ${(report.speed.context_assembly.p50 + " ms").padEnd(8)} │ ${(report.speed.context_assembly.p95 + " ms").padEnd(8)} │ ${(report.speed.context_assembly.p99 + " ms").padEnd(8)} │
|
|
40448
|
+
`;
|
|
40449
|
+
out += ` └─────────────────────────┴──────────┴──────────┴──────────┴──────────┘
|
|
40450
|
+
`;
|
|
40451
|
+
out += `
|
|
40452
|
+
\uD83C\uDFAF KNOWLEDGE QUALITY & ROI:
|
|
40453
|
+
`;
|
|
40454
|
+
out += ` * Total Active Memories: ${report.quality.total_memories}
|
|
40455
|
+
`;
|
|
40456
|
+
out += ` * Contradiction Rate: ${report.quality.conflict_rate_pct}%
|
|
40457
|
+
`;
|
|
40458
|
+
out += ` * Stale Knowledge Rate: ${report.quality.stale_rate_pct}%
|
|
40459
|
+
`;
|
|
40460
|
+
out += ` * Memory ROI Success: \x1B[32m${report.quality.roi_success_rate_pct}%\x1B[0m
|
|
40461
|
+
`;
|
|
40462
|
+
out += `
|
|
40463
|
+
\uD83E\uDE99 TOKEN ECONOMY & EFFICIENCY:
|
|
40464
|
+
`;
|
|
40465
|
+
out += ` * Total Raw Store Tokens: ${report.tokens.raw_tokens_total} tokens
|
|
40466
|
+
`;
|
|
40467
|
+
out += ` * Average Injected Tokens:${report.tokens.packed_tokens_avg} tokens
|
|
40468
|
+
`;
|
|
40469
|
+
out += ` * Knapsack Compression: \x1B[36m${report.tokens.compression_ratio_pct}% tokens saved\x1B[0m
|
|
40470
|
+
`;
|
|
40471
|
+
out += `
|
|
40472
|
+
`;
|
|
40473
|
+
return out;
|
|
40474
|
+
}
|
|
40475
|
+
var init_suite = __esm(() => {
|
|
40476
|
+
init_store();
|
|
40477
|
+
init_ranking();
|
|
40478
|
+
init_context();
|
|
40479
|
+
init_utility();
|
|
40480
|
+
});
|
|
40481
|
+
|
|
40482
|
+
// src/benchmark/index.ts
|
|
40483
|
+
var exports_benchmark = {};
|
|
40484
|
+
__export(exports_benchmark, {
|
|
40485
|
+
formatBenchmarkScoreboard: () => formatBenchmarkScoreboard,
|
|
40486
|
+
runMemoryBenchmark: () => runMemoryBenchmark
|
|
40487
|
+
});
|
|
40488
|
+
var init_benchmark = __esm(() => {
|
|
40489
|
+
init_suite();
|
|
40490
|
+
});
|
|
40491
|
+
|
|
39488
40492
|
// src/cli/health.ts
|
|
39489
40493
|
async function handleHealthCommand(parsed) {
|
|
39490
40494
|
const ctx = requireRoot(parsed.flags);
|
|
@@ -39540,13 +40544,121 @@ ${bold}Actionable Remediation Checklist:${reset}
|
|
|
39540
40544
|
console.log("");
|
|
39541
40545
|
return report.gate_status === "FAIL" ? 1 : 0;
|
|
39542
40546
|
}
|
|
40547
|
+
async function handleReconcileCommand(parsed) {
|
|
40548
|
+
const ctx = requireRoot(parsed.flags);
|
|
40549
|
+
if (!ctx) {
|
|
40550
|
+
console.error("Error: Could not resolve project root or initialize .memory directory.");
|
|
40551
|
+
return 1;
|
|
40552
|
+
}
|
|
40553
|
+
const { root, store } = ctx;
|
|
40554
|
+
const isTrue = (val) => val === true || val === "true" || val === "";
|
|
40555
|
+
const prune = isTrue(parsed.flags["prune"]) || isTrue(parsed.flags["p"]);
|
|
40556
|
+
const markStale2 = isTrue(parsed.flags["mark-stale"]) || isTrue(parsed.flags["stale"]);
|
|
40557
|
+
const updateHashes = isTrue(parsed.flags["update-hashes"]);
|
|
40558
|
+
const dryRun = isTrue(parsed.flags["dry-run"]) || !prune && !markStale2 && !updateHashes;
|
|
40559
|
+
const { reconcileCodeAnchors: reconcileCodeAnchors2, formatReconcileReport: formatReconcileReport2 } = await Promise.resolve().then(() => (init_health(), exports_health));
|
|
40560
|
+
const report = await reconcileCodeAnchors2(store, {
|
|
40561
|
+
prune,
|
|
40562
|
+
markStale: markStale2,
|
|
40563
|
+
updateHashes,
|
|
40564
|
+
dryRun,
|
|
40565
|
+
workspaceRoot: root
|
|
40566
|
+
});
|
|
40567
|
+
if (parsed.flags.json) {
|
|
40568
|
+
console.log(JSON.stringify(report, null, 2));
|
|
40569
|
+
return 0;
|
|
40570
|
+
}
|
|
40571
|
+
console.log(formatReconcileReport2(report, dryRun));
|
|
40572
|
+
return 0;
|
|
40573
|
+
}
|
|
40574
|
+
async function handleBenchmarkCommand(parsed) {
|
|
40575
|
+
const ctx = requireRoot(parsed.flags);
|
|
40576
|
+
if (!ctx) {
|
|
40577
|
+
console.error("Error: Could not resolve project root or initialize .memory directory.");
|
|
40578
|
+
return 1;
|
|
40579
|
+
}
|
|
40580
|
+
const { root, store } = ctx;
|
|
40581
|
+
const iterations = parsed.flags["iterations"] ? parseInt(parsed.flags["iterations"], 10) : 30;
|
|
40582
|
+
const query = parsed.positional[0] || parsed.flags["query"];
|
|
40583
|
+
const tokenBudget = parsed.flags["budget"] ? parseInt(parsed.flags["budget"], 10) : undefined;
|
|
40584
|
+
const { runMemoryBenchmark: runMemoryBenchmark2, formatBenchmarkScoreboard: formatBenchmarkScoreboard2 } = await Promise.resolve().then(() => (init_benchmark(), exports_benchmark));
|
|
40585
|
+
const report = await runMemoryBenchmark2(store, {
|
|
40586
|
+
iterations,
|
|
40587
|
+
query,
|
|
40588
|
+
tokenBudget,
|
|
40589
|
+
workspaceRoot: root
|
|
40590
|
+
});
|
|
40591
|
+
if (parsed.flags.json) {
|
|
40592
|
+
console.log(JSON.stringify(report, null, 2));
|
|
40593
|
+
return 0;
|
|
40594
|
+
}
|
|
40595
|
+
console.log(formatBenchmarkScoreboard2(report));
|
|
40596
|
+
return 0;
|
|
40597
|
+
}
|
|
40598
|
+
async function handleCodeImpactCommand(parsed) {
|
|
40599
|
+
const ctx = requireRoot(parsed.flags);
|
|
40600
|
+
if (!ctx) {
|
|
40601
|
+
console.error("Error: Could not resolve project root or initialize .memory directory.");
|
|
40602
|
+
return 1;
|
|
40603
|
+
}
|
|
40604
|
+
const { root, store } = ctx;
|
|
40605
|
+
const filePath = parsed.positional[0];
|
|
40606
|
+
if (!filePath) {
|
|
40607
|
+
console.error("Usage: memory code-impact <file> [--symbol <name>] [--json]");
|
|
40608
|
+
return 1;
|
|
40609
|
+
}
|
|
40610
|
+
const symbolName = parsed.flags["symbol"];
|
|
40611
|
+
const { analyzeMemoryCodeImpact: analyzeMemoryCodeImpact2, formatImpactReport: formatImpactReport2 } = await Promise.resolve().then(() => (init_intelligence(), exports_intelligence));
|
|
40612
|
+
const result = await analyzeMemoryCodeImpact2(store, {
|
|
40613
|
+
filePath,
|
|
40614
|
+
symbolName,
|
|
40615
|
+
workspaceRoot: root
|
|
40616
|
+
});
|
|
40617
|
+
if (parsed.flags.json) {
|
|
40618
|
+
console.log(JSON.stringify(result, null, 2));
|
|
40619
|
+
return result.risk === "CRITICAL" ? 1 : 0;
|
|
40620
|
+
}
|
|
40621
|
+
console.log(formatImpactReport2(result));
|
|
40622
|
+
return result.risk === "CRITICAL" ? 1 : 0;
|
|
40623
|
+
}
|
|
40624
|
+
async function handlePrContextCommand(parsed) {
|
|
40625
|
+
const ctx = requireRoot(parsed.flags);
|
|
40626
|
+
if (!ctx) {
|
|
40627
|
+
console.error("Error: Could not resolve project root or initialize .memory directory.");
|
|
40628
|
+
return 1;
|
|
40629
|
+
}
|
|
40630
|
+
const { root, store } = ctx;
|
|
40631
|
+
const baseBranch = parsed.positional[0] || parsed.flags["base"] || "main";
|
|
40632
|
+
const { generatePrContext: generatePrContext2 } = await Promise.resolve().then(() => (init_compaction(), exports_compaction));
|
|
40633
|
+
const result = await generatePrContext2(store, {
|
|
40634
|
+
baseBranch,
|
|
40635
|
+
workspaceRoot: root
|
|
40636
|
+
});
|
|
40637
|
+
const outFile = parsed.flags["out"];
|
|
40638
|
+
if (outFile) {
|
|
40639
|
+
const { writeFileSync: writeFileSync32 } = await import("node:fs");
|
|
40640
|
+
const { resolve: resolve4 } = await import("node:path");
|
|
40641
|
+
writeFileSync32(resolve4(root, outFile), result.bodyMarkdown, "utf8");
|
|
40642
|
+
console.log(`[+] Wrote PR context description to ${outFile}`);
|
|
40643
|
+
return 0;
|
|
40644
|
+
}
|
|
40645
|
+
if (parsed.flags.json) {
|
|
40646
|
+
console.log(JSON.stringify(result, null, 2));
|
|
40647
|
+
return 0;
|
|
40648
|
+
}
|
|
40649
|
+
console.log(`
|
|
40650
|
+
PR Title: ${result.title}
|
|
40651
|
+
`);
|
|
40652
|
+
console.log(result.bodyMarkdown);
|
|
40653
|
+
return 0;
|
|
40654
|
+
}
|
|
39543
40655
|
var init_health2 = __esm(() => {
|
|
39544
40656
|
init_health();
|
|
39545
40657
|
init_shared();
|
|
39546
40658
|
});
|
|
39547
40659
|
|
|
39548
40660
|
// src/cli/sync.ts
|
|
39549
|
-
import { writeFileSync as writeFileSync32, readFileSync as
|
|
40661
|
+
import { writeFileSync as writeFileSync32, readFileSync as readFileSync49 } from "node:fs";
|
|
39550
40662
|
import { resolve as resolve4 } from "node:path";
|
|
39551
40663
|
async function handleSyncCommand(parsed) {
|
|
39552
40664
|
const ctx = requireRoot(parsed.flags);
|
|
@@ -39573,7 +40685,7 @@ async function handleSyncCommand(parsed) {
|
|
|
39573
40685
|
if (parsed.flags.ingest) {
|
|
39574
40686
|
const inPath = resolve4(process.cwd(), parsed.flags.ingest);
|
|
39575
40687
|
try {
|
|
39576
|
-
const raw =
|
|
40688
|
+
const raw = readFileSync49(inPath, "utf-8");
|
|
39577
40689
|
const packet2 = JSON.parse(raw);
|
|
39578
40690
|
const res = ingestKnowledge(store, root, packet2, agentId);
|
|
39579
40691
|
if (parsed.flags.json) {
|
|
@@ -39949,6 +41061,15 @@ async function main(argv) {
|
|
|
39949
41061
|
return handleLoopCommand(parsed);
|
|
39950
41062
|
case "health":
|
|
39951
41063
|
return handleHealthCommand(parsed);
|
|
41064
|
+
case "reconcile":
|
|
41065
|
+
return handleReconcileCommand(parsed);
|
|
41066
|
+
case "benchmark":
|
|
41067
|
+
return handleBenchmarkCommand(parsed);
|
|
41068
|
+
case "code-impact":
|
|
41069
|
+
case "impact":
|
|
41070
|
+
return handleCodeImpactCommand(parsed);
|
|
41071
|
+
case "pr-context":
|
|
41072
|
+
return handlePrContextCommand(parsed);
|
|
39952
41073
|
case "sync":
|
|
39953
41074
|
return handleSyncCommand(parsed);
|
|
39954
41075
|
case "mesh":
|
|
@@ -40035,6 +41156,11 @@ Ecosystem, Migration & Connectivity:
|
|
|
40035
41156
|
daemon [--port N] Real-time agency hub (SSE event stream + publish API, default port 7878)
|
|
40036
41157
|
sync [status|broadcast|ingest|pool] Cross-agent knowledge sync & P2P gossip mesh
|
|
40037
41158
|
mesh [query|check|link|unlink|propagate] Multi-repo & monorepo cross-project mesh
|
|
41159
|
+
health Run unified 5-pillar architectural health evaluation
|
|
41160
|
+
reconcile [--prune] [--stale] Reconcile orphaned & drifted code anchors across memories
|
|
41161
|
+
benchmark [--iterations N] Run microsecond speed, quality & token economy benchmark suite
|
|
41162
|
+
code-impact <file> [--symbol] Synthesize code callers, ADRs, negative warnings & risk score
|
|
41163
|
+
pr-context [--base B] [--out] Generate memory-verified PR description from git diff
|
|
40038
41164
|
mcp Run stdio MCP server for agent platforms
|
|
40039
41165
|
`;
|
|
40040
41166
|
var init_cli = __esm(() => {
|