musememory 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -23
- package/dist/index.js +653 -287
- package/package.json +1 -2
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ var __create = Object.create;
|
|
|
4
4
|
var __getProtoOf = Object.getPrototypeOf;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
9
|
function __accessProp(key) {
|
|
9
10
|
return this[key];
|
|
@@ -32,6 +33,23 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
32
33
|
cache.set(mod, to);
|
|
33
34
|
return to;
|
|
34
35
|
};
|
|
36
|
+
var __toCommonJS = (from) => {
|
|
37
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
38
|
+
if (entry)
|
|
39
|
+
return entry;
|
|
40
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
41
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
42
|
+
for (var key of __getOwnPropNames(from))
|
|
43
|
+
if (!__hasOwnProp.call(entry, key))
|
|
44
|
+
__defProp(entry, key, {
|
|
45
|
+
get: __accessProp.bind(from, key),
|
|
46
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
__moduleCache.set(from, entry);
|
|
50
|
+
return entry;
|
|
51
|
+
};
|
|
52
|
+
var __moduleCache;
|
|
35
53
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
36
54
|
var __returnValue = (v) => v;
|
|
37
55
|
function __exportSetter(name, newValue) {
|
|
@@ -3511,9 +3529,256 @@ var init_types = __esm(() => {
|
|
|
3511
3529
|
};
|
|
3512
3530
|
});
|
|
3513
3531
|
|
|
3532
|
+
// src/graph.ts
|
|
3533
|
+
var exports_graph = {};
|
|
3534
|
+
__export(exports_graph, {
|
|
3535
|
+
autoStampGraphMetadata: () => autoStampGraphMetadata,
|
|
3536
|
+
detectGraphProvider: () => detectGraphProvider,
|
|
3537
|
+
detectProvider: () => detectProvider,
|
|
3538
|
+
extractReferencedSymbols: () => extractReferencedSymbols,
|
|
3539
|
+
getGraphStatus: () => getGraphStatus,
|
|
3540
|
+
getRuntimeTrustVerdict: () => getRuntimeTrustVerdict,
|
|
3541
|
+
graphSymbolsPath: () => graphSymbolsPath,
|
|
3542
|
+
indexGraph: () => indexGraph,
|
|
3543
|
+
loadGraphSymbolIndex: () => loadGraphSymbolIndex,
|
|
3544
|
+
verifyRuntimeFiles: () => verifyRuntimeFiles
|
|
3545
|
+
});
|
|
3546
|
+
import { existsSync as existsSync4, readdirSync, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4 } from "node:fs";
|
|
3547
|
+
import { join as join4, isAbsolute } from "node:path";
|
|
3548
|
+
function detectProvider(projectRoot) {
|
|
3549
|
+
if (!projectRoot || !existsSync4(projectRoot))
|
|
3550
|
+
return "none";
|
|
3551
|
+
if (existsSync4(join4(projectRoot, ".codegraph"))) {
|
|
3552
|
+
return "codegraph";
|
|
3553
|
+
}
|
|
3554
|
+
if (existsSync4(join4(projectRoot, ".graphify"))) {
|
|
3555
|
+
return "graphify";
|
|
3556
|
+
}
|
|
3557
|
+
return "none";
|
|
3558
|
+
}
|
|
3559
|
+
function getGraphStatus(projectRoot) {
|
|
3560
|
+
const provider = detectProvider(projectRoot);
|
|
3561
|
+
if (provider === "codegraph") {
|
|
3562
|
+
const codegraphDir = join4(projectRoot, ".codegraph");
|
|
3563
|
+
let symbolCount;
|
|
3564
|
+
let graphRevision;
|
|
3565
|
+
try {
|
|
3566
|
+
if (existsSync4(codegraphDir)) {
|
|
3567
|
+
const files = readdirSync(codegraphDir);
|
|
3568
|
+
symbolCount = files.length;
|
|
3569
|
+
const metaPath = join4(codegraphDir, "meta.json");
|
|
3570
|
+
if (existsSync4(metaPath)) {
|
|
3571
|
+
const meta = JSON.parse(readFileSync4(metaPath, "utf8"));
|
|
3572
|
+
graphRevision = meta.revision ?? meta.commit ?? meta.version;
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3575
|
+
} catch {}
|
|
3576
|
+
return {
|
|
3577
|
+
provider: "codegraph",
|
|
3578
|
+
available: true,
|
|
3579
|
+
root: codegraphDir,
|
|
3580
|
+
graphRevision,
|
|
3581
|
+
symbolCount
|
|
3582
|
+
};
|
|
3583
|
+
}
|
|
3584
|
+
if (provider === "graphify") {
|
|
3585
|
+
const graphifyDir = join4(projectRoot, ".graphify");
|
|
3586
|
+
let symbolCount;
|
|
3587
|
+
let graphRevision;
|
|
3588
|
+
try {
|
|
3589
|
+
if (existsSync4(graphifyDir)) {
|
|
3590
|
+
const files = readdirSync(graphifyDir);
|
|
3591
|
+
symbolCount = files.length;
|
|
3592
|
+
const metaPath = join4(graphifyDir, "meta.json");
|
|
3593
|
+
if (existsSync4(metaPath)) {
|
|
3594
|
+
const meta = JSON.parse(readFileSync4(metaPath, "utf8"));
|
|
3595
|
+
graphRevision = meta.revision ?? meta.commit ?? meta.version;
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
} catch {}
|
|
3599
|
+
return {
|
|
3600
|
+
provider: "graphify",
|
|
3601
|
+
available: true,
|
|
3602
|
+
root: graphifyDir,
|
|
3603
|
+
graphRevision,
|
|
3604
|
+
symbolCount
|
|
3605
|
+
};
|
|
3606
|
+
}
|
|
3607
|
+
return {
|
|
3608
|
+
provider: "none",
|
|
3609
|
+
available: false,
|
|
3610
|
+
root: projectRoot
|
|
3611
|
+
};
|
|
3612
|
+
}
|
|
3613
|
+
function graphSymbolsPath(memoryDir) {
|
|
3614
|
+
return join4(memoryDir, "graph-symbols.json");
|
|
3615
|
+
}
|
|
3616
|
+
function indexGraph(projectRoot, memoryDir) {
|
|
3617
|
+
const status = getGraphStatus(projectRoot);
|
|
3618
|
+
const symbols = {};
|
|
3619
|
+
if (status.provider === "codegraph") {
|
|
3620
|
+
const codegraphDir = join4(projectRoot, ".codegraph");
|
|
3621
|
+
try {
|
|
3622
|
+
const candidates = [
|
|
3623
|
+
join4(codegraphDir, "symbols.json"),
|
|
3624
|
+
join4(codegraphDir, "index.json"),
|
|
3625
|
+
join4(codegraphDir, "graph.json")
|
|
3626
|
+
];
|
|
3627
|
+
for (const c of candidates) {
|
|
3628
|
+
if (existsSync4(c)) {
|
|
3629
|
+
const data = JSON.parse(readFileSync4(c, "utf8"));
|
|
3630
|
+
if (Array.isArray(data)) {
|
|
3631
|
+
for (const item of data) {
|
|
3632
|
+
if (item.name && item.path) {
|
|
3633
|
+
symbols[String(item.name)] = String(item.path);
|
|
3634
|
+
}
|
|
3635
|
+
}
|
|
3636
|
+
} else if (typeof data === "object" && data !== null) {
|
|
3637
|
+
if (data.symbols && typeof data.symbols === "object") {
|
|
3638
|
+
for (const [k, v] of Object.entries(data.symbols)) {
|
|
3639
|
+
symbols[k] = typeof v === "string" ? v : v?.path || "";
|
|
3640
|
+
}
|
|
3641
|
+
} else {
|
|
3642
|
+
for (const [k, v] of Object.entries(data)) {
|
|
3643
|
+
if (typeof v === "string")
|
|
3644
|
+
symbols[k] = v;
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3648
|
+
}
|
|
3649
|
+
}
|
|
3650
|
+
if (Object.keys(symbols).length === 0 && existsSync4(codegraphDir)) {
|
|
3651
|
+
const files = readdirSync(codegraphDir);
|
|
3652
|
+
for (const file of files) {
|
|
3653
|
+
if (file.endsWith(".json") && file !== "meta.json") {
|
|
3654
|
+
try {
|
|
3655
|
+
const content = JSON.parse(readFileSync4(join4(codegraphDir, file), "utf8"));
|
|
3656
|
+
if (content.name && content.path) {
|
|
3657
|
+
symbols[String(content.name)] = String(content.path);
|
|
3658
|
+
} else if (content.symbols && Array.isArray(content.symbols)) {
|
|
3659
|
+
for (const s of content.symbols) {
|
|
3660
|
+
if (s.name && (s.path || content.path)) {
|
|
3661
|
+
symbols[String(s.name)] = String(s.path || content.path);
|
|
3662
|
+
}
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
} catch {}
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
} catch {}
|
|
3670
|
+
} else if (status.provider === "graphify") {
|
|
3671
|
+
const graphifyDir = join4(projectRoot, ".graphify");
|
|
3672
|
+
try {
|
|
3673
|
+
const candidates = [
|
|
3674
|
+
join4(graphifyDir, "graph.json"),
|
|
3675
|
+
join4(graphifyDir, "symbols.json")
|
|
3676
|
+
];
|
|
3677
|
+
for (const c of candidates) {
|
|
3678
|
+
if (existsSync4(c)) {
|
|
3679
|
+
const data = JSON.parse(readFileSync4(c, "utf8"));
|
|
3680
|
+
if (data.nodes && Array.isArray(data.nodes)) {
|
|
3681
|
+
for (const node of data.nodes) {
|
|
3682
|
+
if (node.name && node.path) {
|
|
3683
|
+
symbols[String(node.name)] = String(node.path);
|
|
3684
|
+
}
|
|
3685
|
+
}
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3689
|
+
} catch {}
|
|
3690
|
+
}
|
|
3691
|
+
const index = {
|
|
3692
|
+
provider: status.provider,
|
|
3693
|
+
indexedAt: new Date().toISOString(),
|
|
3694
|
+
symbolCount: Object.keys(symbols).length,
|
|
3695
|
+
symbols
|
|
3696
|
+
};
|
|
3697
|
+
try {
|
|
3698
|
+
mkdirSync4(memoryDir, { recursive: true });
|
|
3699
|
+
writeFileSync3(graphSymbolsPath(memoryDir), JSON.stringify(index, null, 2), "utf8");
|
|
3700
|
+
} catch {}
|
|
3701
|
+
return index;
|
|
3702
|
+
}
|
|
3703
|
+
function loadGraphSymbolIndex(memoryDir) {
|
|
3704
|
+
const p = graphSymbolsPath(memoryDir);
|
|
3705
|
+
if (!existsSync4(p))
|
|
3706
|
+
return null;
|
|
3707
|
+
try {
|
|
3708
|
+
const raw = readFileSync4(p, "utf8");
|
|
3709
|
+
return JSON.parse(raw);
|
|
3710
|
+
} catch {
|
|
3711
|
+
return null;
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
function extractReferencedSymbols(text, memoryDir) {
|
|
3715
|
+
const index = loadGraphSymbolIndex(memoryDir);
|
|
3716
|
+
if (!index || index.symbolCount === 0) {
|
|
3717
|
+
return { symbol_names: [], affected_paths: [], provider: "none" };
|
|
3718
|
+
}
|
|
3719
|
+
const matchedSymbols = new Set;
|
|
3720
|
+
const affectedPaths = new Set;
|
|
3721
|
+
const words = text.match(/[a-zA-Z_$][a-zA-Z0-9_$]*/g) || [];
|
|
3722
|
+
const wordSet = new Set(words);
|
|
3723
|
+
for (const [symbol, path] of Object.entries(index.symbols)) {
|
|
3724
|
+
if (wordSet.has(symbol)) {
|
|
3725
|
+
matchedSymbols.add(symbol);
|
|
3726
|
+
if (path)
|
|
3727
|
+
affectedPaths.add(path);
|
|
3728
|
+
}
|
|
3729
|
+
}
|
|
3730
|
+
return {
|
|
3731
|
+
symbol_names: Array.from(matchedSymbols),
|
|
3732
|
+
affected_paths: Array.from(affectedPaths),
|
|
3733
|
+
provider: index.provider
|
|
3734
|
+
};
|
|
3735
|
+
}
|
|
3736
|
+
function autoStampGraphMetadata(text, memoryDir) {
|
|
3737
|
+
const extracted = extractReferencedSymbols(text, memoryDir);
|
|
3738
|
+
if (extracted.symbol_names.length === 0)
|
|
3739
|
+
return;
|
|
3740
|
+
return {
|
|
3741
|
+
provider: extracted.provider,
|
|
3742
|
+
symbol_names: extracted.symbol_names,
|
|
3743
|
+
affected_paths: extracted.affected_paths,
|
|
3744
|
+
graph_verified_at: new Date().toISOString()
|
|
3745
|
+
};
|
|
3746
|
+
}
|
|
3747
|
+
function verifyRuntimeFiles(entry, workspaceRoot) {
|
|
3748
|
+
const root = workspaceRoot || process.cwd();
|
|
3749
|
+
const affected = entry.graph?.affected_paths || [];
|
|
3750
|
+
if (affected.length === 0) {
|
|
3751
|
+
return { verdict: "STRONG", existingPaths: [], missingPaths: [] };
|
|
3752
|
+
}
|
|
3753
|
+
const existingPaths = [];
|
|
3754
|
+
const missingPaths = [];
|
|
3755
|
+
for (const relPath of affected) {
|
|
3756
|
+
const fullPath = isAbsolute(relPath) ? relPath : join4(root, relPath);
|
|
3757
|
+
if (existsSync4(fullPath)) {
|
|
3758
|
+
existingPaths.push(relPath);
|
|
3759
|
+
} else {
|
|
3760
|
+
missingPaths.push(relPath);
|
|
3761
|
+
}
|
|
3762
|
+
}
|
|
3763
|
+
if (missingPaths.length > 0 && existingPaths.length === 0) {
|
|
3764
|
+
return { verdict: "STALE", existingPaths, missingPaths, details: `Missing: ${missingPaths.join(", ")}` };
|
|
3765
|
+
}
|
|
3766
|
+
if (missingPaths.length > 0) {
|
|
3767
|
+
return { verdict: "WEAK", existingPaths, missingPaths, details: `Partially missing: ${missingPaths.join(", ")}` };
|
|
3768
|
+
}
|
|
3769
|
+
return { verdict: "STRONG", existingPaths, missingPaths };
|
|
3770
|
+
}
|
|
3771
|
+
function getRuntimeTrustVerdict(entry, workspaceRoot) {
|
|
3772
|
+
return verifyRuntimeFiles(entry, workspaceRoot).verdict;
|
|
3773
|
+
}
|
|
3774
|
+
var detectGraphProvider;
|
|
3775
|
+
var init_graph = __esm(() => {
|
|
3776
|
+
detectGraphProvider = detectProvider;
|
|
3777
|
+
});
|
|
3778
|
+
|
|
3514
3779
|
// src/retrieval.ts
|
|
3515
|
-
import { existsSync as
|
|
3516
|
-
import { join as
|
|
3780
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
3781
|
+
import { join as join5 } from "node:path";
|
|
3517
3782
|
function tokenize(text) {
|
|
3518
3783
|
if (!text || typeof text !== "string")
|
|
3519
3784
|
return [];
|
|
@@ -3587,7 +3852,7 @@ function graphSymbolOverlapBonus(entry, queryTokens) {
|
|
|
3587
3852
|
return 0;
|
|
3588
3853
|
return Math.min(0.2, matches / queryTokens.length * 0.2);
|
|
3589
3854
|
}
|
|
3590
|
-
function scoreEntry(entry, queryTokens, now) {
|
|
3855
|
+
function scoreEntry(entry, queryTokens, now = Date.now(), workspaceRoot) {
|
|
3591
3856
|
const app = applicability(entry, queryTokens);
|
|
3592
3857
|
const statusPenalty = STATUS_PENALTY[entry.status] ?? 0;
|
|
3593
3858
|
const vLevel = entry.verification?.level ?? "unverified";
|
|
@@ -3597,9 +3862,19 @@ function scoreEntry(entry, queryTokens, now) {
|
|
|
3597
3862
|
const reinforcementBonus = Math.sign(r) * 0.05 * Math.min(Math.abs(r), 5);
|
|
3598
3863
|
const dueBonus = dueDateBonus(entry, now);
|
|
3599
3864
|
const graphBonus = graphSymbolOverlapBonus(entry, queryTokens);
|
|
3865
|
+
let trustAdjustment = 0;
|
|
3866
|
+
if (entry.graph?.affected_paths && entry.graph.affected_paths.length > 0) {
|
|
3867
|
+
const { verifyRuntimeFiles: verifyRuntimeFiles2 } = (init_graph(), __toCommonJS(exports_graph));
|
|
3868
|
+
const verdict = verifyRuntimeFiles2(entry, workspaceRoot);
|
|
3869
|
+
if (verdict.verdict === "STRONG")
|
|
3870
|
+
trustAdjustment = 0.15;
|
|
3871
|
+
else if (verdict.verdict === "STALE")
|
|
3872
|
+
trustAdjustment = -0.4;
|
|
3873
|
+
}
|
|
3600
3874
|
const decayBase = entry.valid_from ?? entry.updated_at;
|
|
3601
3875
|
const decay = 0.3 * Math.exp(-daysSince(decayBase, now) / 90);
|
|
3602
|
-
|
|
3876
|
+
const zeroMatchPenalty = queryTokens.length > 0 && app === 0 && graphBonus === 0 ? -0.35 : 0;
|
|
3877
|
+
return app + statusPenalty + verificationBonus + salienceBonus + reinforcementBonus + dueBonus + graphBonus + trustAdjustment + decay + zeroMatchPenalty;
|
|
3603
3878
|
}
|
|
3604
3879
|
function sortCandidates(candidates, queryTokens, now) {
|
|
3605
3880
|
return candidates.map((entry) => ({ entry, score: scoreEntry(entry, queryTokens, now) })).sort((a, b) => {
|
|
@@ -3719,7 +3994,7 @@ function formatPromptContext(store, memoryDir, query = "", options = {}) {
|
|
|
3719
3994
|
}
|
|
3720
3995
|
parts.push("");
|
|
3721
3996
|
}
|
|
3722
|
-
if (memoryDir &&
|
|
3997
|
+
if (memoryDir && existsSync5(join5(memoryDir, "wiki"))) {
|
|
3723
3998
|
try {
|
|
3724
3999
|
const wikiPages = listWikiPages(memoryDir, { detailLevel: "l1", project: options.project });
|
|
3725
4000
|
if (wikiPages.length > 0) {
|
|
@@ -3979,17 +4254,17 @@ var init_retrieval = __esm(() => {
|
|
|
3979
4254
|
});
|
|
3980
4255
|
|
|
3981
4256
|
// src/governor.ts
|
|
3982
|
-
import { existsSync as
|
|
3983
|
-
import { join as
|
|
4257
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5 } from "node:fs";
|
|
4258
|
+
import { join as join6 } from "node:path";
|
|
3984
4259
|
import { execSync } from "node:child_process";
|
|
3985
4260
|
function currentFilePath(memoryDir) {
|
|
3986
|
-
return
|
|
4261
|
+
return join6(memoryDir, "CURRENT.md");
|
|
3987
4262
|
}
|
|
3988
4263
|
function parseCurrentFile(memoryDir) {
|
|
3989
4264
|
const p = currentFilePath(memoryDir);
|
|
3990
|
-
if (!
|
|
4265
|
+
if (!existsSync6(p))
|
|
3991
4266
|
return { constraints: [], handoff: null };
|
|
3992
|
-
const raw =
|
|
4267
|
+
const raw = readFileSync5(p, "utf8");
|
|
3993
4268
|
const lines = raw.split(`
|
|
3994
4269
|
`);
|
|
3995
4270
|
const constraints = [];
|
|
@@ -4079,7 +4354,7 @@ function parseCurrentFile(memoryDir) {
|
|
|
4079
4354
|
}
|
|
4080
4355
|
function writeCurrentFile(memoryDir, data) {
|
|
4081
4356
|
const p = currentFilePath(memoryDir);
|
|
4082
|
-
|
|
4357
|
+
mkdirSync5(memoryDir, { recursive: true });
|
|
4083
4358
|
const parts = [`# Active Project Constraints & In-Flight Context
|
|
4084
4359
|
`];
|
|
4085
4360
|
parts.push("## Active Working Invariants & Hard Constraints");
|
|
@@ -4118,7 +4393,7 @@ function writeCurrentFile(memoryDir, data) {
|
|
|
4118
4393
|
}
|
|
4119
4394
|
parts.push("");
|
|
4120
4395
|
}
|
|
4121
|
-
|
|
4396
|
+
writeFileSync4(p, parts.join(`
|
|
4122
4397
|
`), "utf8");
|
|
4123
4398
|
}
|
|
4124
4399
|
function updateSessionHandoff(memoryDir, update) {
|
|
@@ -4422,7 +4697,7 @@ var init_current = __esm(() => {
|
|
|
4422
4697
|
});
|
|
4423
4698
|
|
|
4424
4699
|
// src/transcript.ts
|
|
4425
|
-
import { existsSync as
|
|
4700
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "node:fs";
|
|
4426
4701
|
function parseJsonlTranscript(jsonlText) {
|
|
4427
4702
|
if (!jsonlText)
|
|
4428
4703
|
return [];
|
|
@@ -4473,8 +4748,8 @@ function parseJsonlTranscript(jsonlText) {
|
|
|
4473
4748
|
}
|
|
4474
4749
|
function searchTranscriptWithBookends(transcriptPathOrContent, query, options = {}) {
|
|
4475
4750
|
let content = transcriptPathOrContent;
|
|
4476
|
-
if (
|
|
4477
|
-
content =
|
|
4751
|
+
if (existsSync7(transcriptPathOrContent)) {
|
|
4752
|
+
content = readFileSync6(transcriptPathOrContent, "utf8");
|
|
4478
4753
|
}
|
|
4479
4754
|
const turns = parseJsonlTranscript(content);
|
|
4480
4755
|
if (turns.length === 0) {
|
|
@@ -4544,7 +4819,7 @@ ${m.matchedTurn}`);
|
|
|
4544
4819
|
var init_transcript = () => {};
|
|
4545
4820
|
|
|
4546
4821
|
// src/harvest.ts
|
|
4547
|
-
import { existsSync as
|
|
4822
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
|
|
4548
4823
|
import { createHash } from "node:crypto";
|
|
4549
4824
|
function extractHarvestUnits(text) {
|
|
4550
4825
|
if (!text || typeof text !== "string")
|
|
@@ -4679,8 +4954,8 @@ function openLoopId(text) {
|
|
|
4679
4954
|
}
|
|
4680
4955
|
function importTranscript(store, transcriptPathOrContent, options = {}) {
|
|
4681
4956
|
let content = transcriptPathOrContent;
|
|
4682
|
-
if (
|
|
4683
|
-
content =
|
|
4957
|
+
if (existsSync8(transcriptPathOrContent)) {
|
|
4958
|
+
content = readFileSync7(transcriptPathOrContent, "utf8");
|
|
4684
4959
|
}
|
|
4685
4960
|
const blocks = parseJsonlTranscript(content);
|
|
4686
4961
|
const fullText = blocks.join(`
|
|
@@ -4758,210 +5033,6 @@ var init_harvest = __esm(() => {
|
|
|
4758
5033
|
];
|
|
4759
5034
|
});
|
|
4760
5035
|
|
|
4761
|
-
// src/graph.ts
|
|
4762
|
-
import { existsSync as existsSync8, readdirSync, readFileSync as readFileSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5 } from "node:fs";
|
|
4763
|
-
import { join as join6 } from "node:path";
|
|
4764
|
-
function detectProvider(projectRoot) {
|
|
4765
|
-
if (!projectRoot || !existsSync8(projectRoot))
|
|
4766
|
-
return "none";
|
|
4767
|
-
if (existsSync8(join6(projectRoot, ".codegraph"))) {
|
|
4768
|
-
return "codegraph";
|
|
4769
|
-
}
|
|
4770
|
-
if (existsSync8(join6(projectRoot, ".graphify"))) {
|
|
4771
|
-
return "graphify";
|
|
4772
|
-
}
|
|
4773
|
-
return "none";
|
|
4774
|
-
}
|
|
4775
|
-
function getGraphStatus(projectRoot) {
|
|
4776
|
-
const provider = detectProvider(projectRoot);
|
|
4777
|
-
if (provider === "codegraph") {
|
|
4778
|
-
const codegraphDir = join6(projectRoot, ".codegraph");
|
|
4779
|
-
let symbolCount;
|
|
4780
|
-
let graphRevision;
|
|
4781
|
-
try {
|
|
4782
|
-
if (existsSync8(codegraphDir)) {
|
|
4783
|
-
const files = readdirSync(codegraphDir);
|
|
4784
|
-
symbolCount = files.length;
|
|
4785
|
-
const metaPath = join6(codegraphDir, "meta.json");
|
|
4786
|
-
if (existsSync8(metaPath)) {
|
|
4787
|
-
const meta = JSON.parse(readFileSync7(metaPath, "utf8"));
|
|
4788
|
-
graphRevision = meta.revision ?? meta.commit ?? meta.version;
|
|
4789
|
-
}
|
|
4790
|
-
}
|
|
4791
|
-
} catch {}
|
|
4792
|
-
return {
|
|
4793
|
-
provider: "codegraph",
|
|
4794
|
-
available: true,
|
|
4795
|
-
root: codegraphDir,
|
|
4796
|
-
graphRevision,
|
|
4797
|
-
symbolCount
|
|
4798
|
-
};
|
|
4799
|
-
}
|
|
4800
|
-
if (provider === "graphify") {
|
|
4801
|
-
const graphifyDir = join6(projectRoot, ".graphify");
|
|
4802
|
-
let symbolCount;
|
|
4803
|
-
let graphRevision;
|
|
4804
|
-
try {
|
|
4805
|
-
if (existsSync8(graphifyDir)) {
|
|
4806
|
-
const files = readdirSync(graphifyDir);
|
|
4807
|
-
symbolCount = files.length;
|
|
4808
|
-
const metaPath = join6(graphifyDir, "meta.json");
|
|
4809
|
-
if (existsSync8(metaPath)) {
|
|
4810
|
-
const meta = JSON.parse(readFileSync7(metaPath, "utf8"));
|
|
4811
|
-
graphRevision = meta.revision ?? meta.commit ?? meta.version;
|
|
4812
|
-
}
|
|
4813
|
-
}
|
|
4814
|
-
} catch {}
|
|
4815
|
-
return {
|
|
4816
|
-
provider: "graphify",
|
|
4817
|
-
available: true,
|
|
4818
|
-
root: graphifyDir,
|
|
4819
|
-
graphRevision,
|
|
4820
|
-
symbolCount
|
|
4821
|
-
};
|
|
4822
|
-
}
|
|
4823
|
-
return {
|
|
4824
|
-
provider: "none",
|
|
4825
|
-
available: false,
|
|
4826
|
-
root: projectRoot
|
|
4827
|
-
};
|
|
4828
|
-
}
|
|
4829
|
-
function graphSymbolsPath(memoryDir) {
|
|
4830
|
-
return join6(memoryDir, "graph-symbols.json");
|
|
4831
|
-
}
|
|
4832
|
-
function indexGraph(projectRoot, memoryDir) {
|
|
4833
|
-
const status = getGraphStatus(projectRoot);
|
|
4834
|
-
const symbols = {};
|
|
4835
|
-
if (status.provider === "codegraph") {
|
|
4836
|
-
const codegraphDir = join6(projectRoot, ".codegraph");
|
|
4837
|
-
try {
|
|
4838
|
-
const candidates = [
|
|
4839
|
-
join6(codegraphDir, "symbols.json"),
|
|
4840
|
-
join6(codegraphDir, "index.json"),
|
|
4841
|
-
join6(codegraphDir, "graph.json")
|
|
4842
|
-
];
|
|
4843
|
-
for (const c of candidates) {
|
|
4844
|
-
if (existsSync8(c)) {
|
|
4845
|
-
const data = JSON.parse(readFileSync7(c, "utf8"));
|
|
4846
|
-
if (Array.isArray(data)) {
|
|
4847
|
-
for (const item of data) {
|
|
4848
|
-
if (item.name && item.path) {
|
|
4849
|
-
symbols[String(item.name)] = String(item.path);
|
|
4850
|
-
}
|
|
4851
|
-
}
|
|
4852
|
-
} else if (typeof data === "object" && data !== null) {
|
|
4853
|
-
if (data.symbols && typeof data.symbols === "object") {
|
|
4854
|
-
for (const [k, v] of Object.entries(data.symbols)) {
|
|
4855
|
-
symbols[k] = typeof v === "string" ? v : v?.path || "";
|
|
4856
|
-
}
|
|
4857
|
-
} else {
|
|
4858
|
-
for (const [k, v] of Object.entries(data)) {
|
|
4859
|
-
if (typeof v === "string")
|
|
4860
|
-
symbols[k] = v;
|
|
4861
|
-
}
|
|
4862
|
-
}
|
|
4863
|
-
}
|
|
4864
|
-
}
|
|
4865
|
-
}
|
|
4866
|
-
if (Object.keys(symbols).length === 0 && existsSync8(codegraphDir)) {
|
|
4867
|
-
const files = readdirSync(codegraphDir);
|
|
4868
|
-
for (const file of files) {
|
|
4869
|
-
if (file.endsWith(".json") && file !== "meta.json") {
|
|
4870
|
-
try {
|
|
4871
|
-
const content = JSON.parse(readFileSync7(join6(codegraphDir, file), "utf8"));
|
|
4872
|
-
if (content.name && content.path) {
|
|
4873
|
-
symbols[String(content.name)] = String(content.path);
|
|
4874
|
-
} else if (content.symbols && Array.isArray(content.symbols)) {
|
|
4875
|
-
for (const s of content.symbols) {
|
|
4876
|
-
if (s.name && (s.path || content.path)) {
|
|
4877
|
-
symbols[String(s.name)] = String(s.path || content.path);
|
|
4878
|
-
}
|
|
4879
|
-
}
|
|
4880
|
-
}
|
|
4881
|
-
} catch {}
|
|
4882
|
-
}
|
|
4883
|
-
}
|
|
4884
|
-
}
|
|
4885
|
-
} catch {}
|
|
4886
|
-
} else if (status.provider === "graphify") {
|
|
4887
|
-
const graphifyDir = join6(projectRoot, ".graphify");
|
|
4888
|
-
try {
|
|
4889
|
-
const candidates = [
|
|
4890
|
-
join6(graphifyDir, "graph.json"),
|
|
4891
|
-
join6(graphifyDir, "symbols.json")
|
|
4892
|
-
];
|
|
4893
|
-
for (const c of candidates) {
|
|
4894
|
-
if (existsSync8(c)) {
|
|
4895
|
-
const data = JSON.parse(readFileSync7(c, "utf8"));
|
|
4896
|
-
if (data.nodes && Array.isArray(data.nodes)) {
|
|
4897
|
-
for (const node of data.nodes) {
|
|
4898
|
-
if (node.name && node.path) {
|
|
4899
|
-
symbols[String(node.name)] = String(node.path);
|
|
4900
|
-
}
|
|
4901
|
-
}
|
|
4902
|
-
}
|
|
4903
|
-
}
|
|
4904
|
-
}
|
|
4905
|
-
} catch {}
|
|
4906
|
-
}
|
|
4907
|
-
const index = {
|
|
4908
|
-
provider: status.provider,
|
|
4909
|
-
indexedAt: new Date().toISOString(),
|
|
4910
|
-
symbolCount: Object.keys(symbols).length,
|
|
4911
|
-
symbols
|
|
4912
|
-
};
|
|
4913
|
-
try {
|
|
4914
|
-
mkdirSync5(memoryDir, { recursive: true });
|
|
4915
|
-
writeFileSync4(graphSymbolsPath(memoryDir), JSON.stringify(index, null, 2), "utf8");
|
|
4916
|
-
} catch {}
|
|
4917
|
-
return index;
|
|
4918
|
-
}
|
|
4919
|
-
function loadGraphSymbolIndex(memoryDir) {
|
|
4920
|
-
const p = graphSymbolsPath(memoryDir);
|
|
4921
|
-
if (!existsSync8(p))
|
|
4922
|
-
return null;
|
|
4923
|
-
try {
|
|
4924
|
-
const raw = readFileSync7(p, "utf8");
|
|
4925
|
-
return JSON.parse(raw);
|
|
4926
|
-
} catch {
|
|
4927
|
-
return null;
|
|
4928
|
-
}
|
|
4929
|
-
}
|
|
4930
|
-
function extractReferencedSymbols(text, memoryDir) {
|
|
4931
|
-
const index = loadGraphSymbolIndex(memoryDir);
|
|
4932
|
-
if (!index || index.symbolCount === 0) {
|
|
4933
|
-
return { symbol_names: [], affected_paths: [], provider: "none" };
|
|
4934
|
-
}
|
|
4935
|
-
const matchedSymbols = new Set;
|
|
4936
|
-
const affectedPaths = new Set;
|
|
4937
|
-
const words = text.match(/[a-zA-Z_$][a-zA-Z0-9_$]*/g) || [];
|
|
4938
|
-
const wordSet = new Set(words);
|
|
4939
|
-
for (const [symbol, path] of Object.entries(index.symbols)) {
|
|
4940
|
-
if (wordSet.has(symbol)) {
|
|
4941
|
-
matchedSymbols.add(symbol);
|
|
4942
|
-
if (path)
|
|
4943
|
-
affectedPaths.add(path);
|
|
4944
|
-
}
|
|
4945
|
-
}
|
|
4946
|
-
return {
|
|
4947
|
-
symbol_names: Array.from(matchedSymbols),
|
|
4948
|
-
affected_paths: Array.from(affectedPaths),
|
|
4949
|
-
provider: index.provider
|
|
4950
|
-
};
|
|
4951
|
-
}
|
|
4952
|
-
function autoStampGraphMetadata(text, memoryDir) {
|
|
4953
|
-
const extracted = extractReferencedSymbols(text, memoryDir);
|
|
4954
|
-
if (extracted.symbol_names.length === 0)
|
|
4955
|
-
return;
|
|
4956
|
-
return {
|
|
4957
|
-
provider: extracted.provider,
|
|
4958
|
-
symbol_names: extracted.symbol_names,
|
|
4959
|
-
affected_paths: extracted.affected_paths,
|
|
4960
|
-
graph_verified_at: new Date().toISOString()
|
|
4961
|
-
};
|
|
4962
|
-
}
|
|
4963
|
-
var init_graph = () => {};
|
|
4964
|
-
|
|
4965
5036
|
// src/sqlite.ts
|
|
4966
5037
|
import { existsSync as existsSync9, mkdirSync as mkdirSync6 } from "node:fs";
|
|
4967
5038
|
import { dirname } from "node:path";
|
|
@@ -6776,6 +6847,9 @@ function ancestorChain(startDir) {
|
|
|
6776
6847
|
}
|
|
6777
6848
|
return chain;
|
|
6778
6849
|
}
|
|
6850
|
+
function resolveMemoryDir(options = {}) {
|
|
6851
|
+
return findOrCreateProjectRoot(options.root || process.cwd(), options).memoryDir;
|
|
6852
|
+
}
|
|
6779
6853
|
var MEMORY_DIR_NAMES;
|
|
6780
6854
|
var init_root = __esm(() => {
|
|
6781
6855
|
init_user();
|
|
@@ -26553,6 +26627,211 @@ var init_settings2 = __esm(() => {
|
|
|
26553
26627
|
init_settings();
|
|
26554
26628
|
});
|
|
26555
26629
|
|
|
26630
|
+
// src/plasticity.ts
|
|
26631
|
+
var exports_plasticity = {};
|
|
26632
|
+
__export(exports_plasticity, {
|
|
26633
|
+
getAssociatedMemories: () => getAssociatedMemories,
|
|
26634
|
+
getHebbianAssociationWeight: () => getHebbianAssociationWeight,
|
|
26635
|
+
loadHebbianGraph: () => loadHebbianGraph,
|
|
26636
|
+
recordCoActivation: () => recordCoActivation,
|
|
26637
|
+
saveHebbianGraph: () => saveHebbianGraph
|
|
26638
|
+
});
|
|
26639
|
+
import { existsSync as existsSync30, readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "node:fs";
|
|
26640
|
+
import { join as join27 } from "node:path";
|
|
26641
|
+
function getPlasticityPath(memoryDir) {
|
|
26642
|
+
return join27(memoryDir, "hebbian-plasticity.json");
|
|
26643
|
+
}
|
|
26644
|
+
function loadHebbianGraph(memoryDir) {
|
|
26645
|
+
const p = getPlasticityPath(memoryDir);
|
|
26646
|
+
if (!existsSync30(p))
|
|
26647
|
+
return {};
|
|
26648
|
+
try {
|
|
26649
|
+
return JSON.parse(readFileSync24(p, "utf8"));
|
|
26650
|
+
} catch {
|
|
26651
|
+
return {};
|
|
26652
|
+
}
|
|
26653
|
+
}
|
|
26654
|
+
function saveHebbianGraph(memoryDir, graph) {
|
|
26655
|
+
const p = getPlasticityPath(memoryDir);
|
|
26656
|
+
try {
|
|
26657
|
+
writeFileSync16(p, JSON.stringify(graph, null, 2), "utf8");
|
|
26658
|
+
} catch {}
|
|
26659
|
+
}
|
|
26660
|
+
function recordCoActivation(memoryIds, memoryDir) {
|
|
26661
|
+
const ids = Array.from(new Set(memoryIds.filter(Boolean)));
|
|
26662
|
+
if (ids.length < 2)
|
|
26663
|
+
return;
|
|
26664
|
+
const graph = loadHebbianGraph(memoryDir);
|
|
26665
|
+
const now = new Date().toISOString();
|
|
26666
|
+
for (let i = 0;i < ids.length; i++) {
|
|
26667
|
+
const src = ids[i];
|
|
26668
|
+
if (!graph[src])
|
|
26669
|
+
graph[src] = {};
|
|
26670
|
+
for (let j = 0;j < ids.length; j++) {
|
|
26671
|
+
if (i === j)
|
|
26672
|
+
continue;
|
|
26673
|
+
const tgt = ids[j];
|
|
26674
|
+
const existing = graph[src][tgt];
|
|
26675
|
+
const prevWeight = existing ? existing.weight : 0;
|
|
26676
|
+
const prevCount = existing ? existing.count : 0;
|
|
26677
|
+
const newWeight = Math.min(1, Math.round((prevWeight + 0.05) * 1000) / 1000);
|
|
26678
|
+
graph[src][tgt] = {
|
|
26679
|
+
weight: newWeight,
|
|
26680
|
+
count: prevCount + 1,
|
|
26681
|
+
lastActivated: now
|
|
26682
|
+
};
|
|
26683
|
+
}
|
|
26684
|
+
}
|
|
26685
|
+
saveHebbianGraph(memoryDir, graph);
|
|
26686
|
+
}
|
|
26687
|
+
function getHebbianAssociationWeight(sourceId, targetId, memoryDir) {
|
|
26688
|
+
const graph = loadHebbianGraph(memoryDir);
|
|
26689
|
+
return graph[sourceId]?.[targetId]?.weight ?? 0;
|
|
26690
|
+
}
|
|
26691
|
+
function getAssociatedMemories(sourceId, memoryDir) {
|
|
26692
|
+
const graph = loadHebbianGraph(memoryDir);
|
|
26693
|
+
const targets = graph[sourceId];
|
|
26694
|
+
if (!targets)
|
|
26695
|
+
return [];
|
|
26696
|
+
return Object.entries(targets).map(([targetId, edge]) => ({
|
|
26697
|
+
targetId,
|
|
26698
|
+
weight: edge.weight,
|
|
26699
|
+
count: edge.count
|
|
26700
|
+
})).sort((a, b) => b.weight - a.weight);
|
|
26701
|
+
}
|
|
26702
|
+
var init_plasticity = () => {};
|
|
26703
|
+
|
|
26704
|
+
// src/compress.ts
|
|
26705
|
+
var exports_compress = {};
|
|
26706
|
+
__export(exports_compress, {
|
|
26707
|
+
compressPromptContext: () => compressPromptContext,
|
|
26708
|
+
estimateTokens: () => estimateTokens
|
|
26709
|
+
});
|
|
26710
|
+
function estimateTokens(text) {
|
|
26711
|
+
if (!text || text.trim().length === 0)
|
|
26712
|
+
return 0;
|
|
26713
|
+
return Math.max(1, Math.ceil(text.length / 4));
|
|
26714
|
+
}
|
|
26715
|
+
function compressPromptContext(text, options = {}) {
|
|
26716
|
+
if (!text || text.trim().length === 0) {
|
|
26717
|
+
return {
|
|
26718
|
+
compressed: "",
|
|
26719
|
+
originalTokens: 0,
|
|
26720
|
+
compressedTokens: 0,
|
|
26721
|
+
savingsPercent: 0
|
|
26722
|
+
};
|
|
26723
|
+
}
|
|
26724
|
+
const originalTokens = estimateTokens(text);
|
|
26725
|
+
let cleaned = text.replace(/\n\s*\n\s*\n+/g, `
|
|
26726
|
+
|
|
26727
|
+
`).replace(/### Active Working Constraints \(CURRENT\.md\)/gi, "### Active Constraints").replace(/### Active In-Flight Context & Session Handoff \(CURRENT\.md\)/gi, "### In-Flight Handoff").replace(/### User Profile & Preferences \(USER\.md\)/gi, "### User Profile").replace(/### Relevant Memories & Learned Patterns/gi, "### Memories").replace(/\n\s*---\s*\n/g, `
|
|
26728
|
+
`).replace(/\*Memory Directive: When learning durable facts[^\n]*\*/gi, "").replace(/[ \t]{2,}/g, " ").trim();
|
|
26729
|
+
const compressedTokens = estimateTokens(cleaned);
|
|
26730
|
+
const diff = originalTokens - compressedTokens;
|
|
26731
|
+
const savingsPercent = originalTokens > 0 ? Math.round(Math.max(0, diff) / originalTokens * 100) : 0;
|
|
26732
|
+
return {
|
|
26733
|
+
compressed: cleaned,
|
|
26734
|
+
originalTokens,
|
|
26735
|
+
compressedTokens,
|
|
26736
|
+
savingsPercent
|
|
26737
|
+
};
|
|
26738
|
+
}
|
|
26739
|
+
|
|
26740
|
+
// src/drift.ts
|
|
26741
|
+
var exports_drift = {};
|
|
26742
|
+
__export(exports_drift, {
|
|
26743
|
+
getGitChangedFiles: () => getGitChangedFiles,
|
|
26744
|
+
scanCodeDrift: () => scanCodeDrift,
|
|
26745
|
+
scanCodeDriftFromDiff: () => scanCodeDriftFromDiff
|
|
26746
|
+
});
|
|
26747
|
+
import { execSync as execSync2 } from "node:child_process";
|
|
26748
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
26749
|
+
import { join as join28, isAbsolute as isAbsolute2 } from "node:path";
|
|
26750
|
+
function scanCodeDriftFromDiff(entries, changedFiles, workspaceRoot) {
|
|
26751
|
+
const root = workspaceRoot || process.cwd();
|
|
26752
|
+
const normalizedChanged = new Set(changedFiles.map((f) => f.trim().replace(/^[\.\/]+/, "")).filter(Boolean));
|
|
26753
|
+
const drifted = [];
|
|
26754
|
+
for (const entry of entries) {
|
|
26755
|
+
if (entry.status !== "confirmed" && entry.status !== "candidate")
|
|
26756
|
+
continue;
|
|
26757
|
+
const paths = entry.graph?.affected_paths || [];
|
|
26758
|
+
const symbols = entry.graph?.symbol_names || [];
|
|
26759
|
+
for (const p of paths) {
|
|
26760
|
+
const norm = p.trim().replace(/^[\.\/]+/, "");
|
|
26761
|
+
const matched = Array.from(normalizedChanged).find((cf) => cf === norm || cf.endsWith(`/${norm}`) || norm.endsWith(`/${cf}`));
|
|
26762
|
+
if (matched) {
|
|
26763
|
+
const fullPath = isAbsolute2(p) ? p : join28(root, p);
|
|
26764
|
+
const exists = existsSync31(fullPath);
|
|
26765
|
+
drifted.push({
|
|
26766
|
+
memoryId: entry.id,
|
|
26767
|
+
title: entry.title,
|
|
26768
|
+
affectedPath: p,
|
|
26769
|
+
symbols,
|
|
26770
|
+
driftType: exists ? "modified" : "deleted",
|
|
26771
|
+
suggestedAction: exists ? "verify" : "mark_stale"
|
|
26772
|
+
});
|
|
26773
|
+
break;
|
|
26774
|
+
}
|
|
26775
|
+
}
|
|
26776
|
+
}
|
|
26777
|
+
return {
|
|
26778
|
+
isDrifted: drifted.length > 0,
|
|
26779
|
+
driftCount: drifted.length,
|
|
26780
|
+
driftedMemories: drifted,
|
|
26781
|
+
scannedFilesCount: normalizedChanged.size,
|
|
26782
|
+
changedFiles: Array.from(normalizedChanged)
|
|
26783
|
+
};
|
|
26784
|
+
}
|
|
26785
|
+
function getGitChangedFiles(workspaceRoot) {
|
|
26786
|
+
const root = workspaceRoot || process.cwd();
|
|
26787
|
+
try {
|
|
26788
|
+
const stdout = execSync2("git status --porcelain", {
|
|
26789
|
+
cwd: root,
|
|
26790
|
+
encoding: "utf8",
|
|
26791
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
26792
|
+
});
|
|
26793
|
+
const files = [];
|
|
26794
|
+
for (const line of stdout.split(`
|
|
26795
|
+
`)) {
|
|
26796
|
+
const trimmed = line.trim();
|
|
26797
|
+
if (!trimmed)
|
|
26798
|
+
continue;
|
|
26799
|
+
const parts = trimmed.split(/\s+/);
|
|
26800
|
+
const filePath = parts.length >= 2 ? parts[parts.length - 1] : "";
|
|
26801
|
+
if (filePath)
|
|
26802
|
+
files.push(filePath);
|
|
26803
|
+
}
|
|
26804
|
+
try {
|
|
26805
|
+
const diffOut = execSync2("git diff --name-only HEAD", {
|
|
26806
|
+
cwd: root,
|
|
26807
|
+
encoding: "utf8",
|
|
26808
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
26809
|
+
});
|
|
26810
|
+
for (const line of diffOut.split(`
|
|
26811
|
+
`)) {
|
|
26812
|
+
const f = line.trim();
|
|
26813
|
+
if (f && !files.includes(f))
|
|
26814
|
+
files.push(f);
|
|
26815
|
+
}
|
|
26816
|
+
} catch {}
|
|
26817
|
+
return files;
|
|
26818
|
+
} catch {
|
|
26819
|
+
return [];
|
|
26820
|
+
}
|
|
26821
|
+
}
|
|
26822
|
+
function scanCodeDrift(options = {}) {
|
|
26823
|
+
const root = options.workspaceRoot || process.cwd();
|
|
26824
|
+
const changedFiles = getGitChangedFiles(root);
|
|
26825
|
+
const memDir = options.memoryDir || resolveMemoryDir({ global: false, root });
|
|
26826
|
+
const store = openStore(memDir);
|
|
26827
|
+
const entries = list(store);
|
|
26828
|
+
return scanCodeDriftFromDiff(entries, changedFiles, root);
|
|
26829
|
+
}
|
|
26830
|
+
var init_drift = __esm(() => {
|
|
26831
|
+
init_store();
|
|
26832
|
+
init_root();
|
|
26833
|
+
});
|
|
26834
|
+
|
|
26556
26835
|
// src/mcp.ts
|
|
26557
26836
|
var exports_mcp = {};
|
|
26558
26837
|
__export(exports_mcp, {
|
|
@@ -27163,6 +27442,28 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
27163
27442
|
},
|
|
27164
27443
|
required: ["settings"]
|
|
27165
27444
|
}
|
|
27445
|
+
},
|
|
27446
|
+
{
|
|
27447
|
+
name: "memory_drift",
|
|
27448
|
+
description: "Scan the local Git workspace for modified or deleted code files and AST symbols referenced by memories. Flags drifted memories for re-verification or supersession.",
|
|
27449
|
+
inputSchema: {
|
|
27450
|
+
type: "object",
|
|
27451
|
+
properties: {
|
|
27452
|
+
dir: { type: "string", description: "Optional project workspace directory path" }
|
|
27453
|
+
}
|
|
27454
|
+
}
|
|
27455
|
+
},
|
|
27456
|
+
{
|
|
27457
|
+
name: "memory_compress",
|
|
27458
|
+
description: "Compress formatted prompt context losslessly, stripping header whitespace and boilerplate while preserving all architectural facts.",
|
|
27459
|
+
inputSchema: {
|
|
27460
|
+
type: "object",
|
|
27461
|
+
properties: {
|
|
27462
|
+
text: { type: "string", description: "Markdown prompt context to compress" },
|
|
27463
|
+
level: { type: "string", enum: ["light", "aggressive"], description: "Compression aggressiveness level" }
|
|
27464
|
+
},
|
|
27465
|
+
required: ["text"]
|
|
27466
|
+
}
|
|
27166
27467
|
}
|
|
27167
27468
|
]
|
|
27168
27469
|
}));
|
|
@@ -27200,8 +27501,19 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
27200
27501
|
verified: a.verified === true,
|
|
27201
27502
|
depth: a.depth ? String(a.depth) : undefined
|
|
27202
27503
|
});
|
|
27504
|
+
if (formatted.entries.length >= 2 && activeMemoryDir) {
|
|
27505
|
+
try {
|
|
27506
|
+
const { recordCoActivation: recordCoActivation2 } = await Promise.resolve().then(() => (init_plasticity(), exports_plasticity));
|
|
27507
|
+
recordCoActivation2(formatted.entries.map((e) => e.entry.id), activeMemoryDir);
|
|
27508
|
+
} catch {}
|
|
27509
|
+
}
|
|
27510
|
+
let finalMarkdown = formatted.markdown;
|
|
27511
|
+
if (a.compress === true) {
|
|
27512
|
+
const { compressPromptContext: compressPromptContext2 } = await Promise.resolve().then(() => exports_compress);
|
|
27513
|
+
finalMarkdown = compressPromptContext2(finalMarkdown).compressed;
|
|
27514
|
+
}
|
|
27203
27515
|
return toolResult({
|
|
27204
|
-
markdown:
|
|
27516
|
+
markdown: finalMarkdown,
|
|
27205
27517
|
entries: formatted.entries.map((r) => ({ ...r.entry, score: r.score })),
|
|
27206
27518
|
total_tokens_used: formatted.totalTokensUsed,
|
|
27207
27519
|
constraints: formatted.constraints,
|
|
@@ -27635,6 +27947,18 @@ Path: ${item.path}`,
|
|
|
27635
27947
|
return toolError(err instanceof Error ? err.message : String(err));
|
|
27636
27948
|
}
|
|
27637
27949
|
}
|
|
27950
|
+
case "memory_drift": {
|
|
27951
|
+
const { scanCodeDrift: scanCodeDrift2 } = await Promise.resolve().then(() => (init_drift(), exports_drift));
|
|
27952
|
+
const report = scanCodeDrift2({ workspaceRoot: activeRoot, memoryDir: activeMemoryDir });
|
|
27953
|
+
return toolResult(report);
|
|
27954
|
+
}
|
|
27955
|
+
case "memory_compress": {
|
|
27956
|
+
const { compressPromptContext: compressPromptContext2 } = await Promise.resolve().then(() => exports_compress);
|
|
27957
|
+
const text = String(a.text ?? "");
|
|
27958
|
+
const level = a.level === "aggressive" ? "aggressive" : "light";
|
|
27959
|
+
const result = compressPromptContext2(text, { level });
|
|
27960
|
+
return toolResult(result);
|
|
27961
|
+
}
|
|
27638
27962
|
default:
|
|
27639
27963
|
return toolError(`unknown tool ${name}`);
|
|
27640
27964
|
}
|
|
@@ -27699,8 +28023,8 @@ __export(exports_daemon, {
|
|
|
27699
28023
|
startHub: () => startHub
|
|
27700
28024
|
});
|
|
27701
28025
|
import { createServer as createServer2 } from "node:http";
|
|
27702
|
-
import { existsSync as
|
|
27703
|
-
import { join as
|
|
28026
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
28027
|
+
import { join as join29 } from "node:path";
|
|
27704
28028
|
import { watch } from "node:fs";
|
|
27705
28029
|
function startHub(port, memoryDir) {
|
|
27706
28030
|
const clients = new Set;
|
|
@@ -27766,7 +28090,7 @@ data: ${JSON.stringify(event)}
|
|
|
27766
28090
|
return clients.size;
|
|
27767
28091
|
}
|
|
27768
28092
|
if (memoryDir) {
|
|
27769
|
-
const memoriesDir =
|
|
28093
|
+
const memoriesDir = join29(memoryDir, "memories");
|
|
27770
28094
|
const armDebounced = (type2) => {
|
|
27771
28095
|
if (debounceTimer)
|
|
27772
28096
|
clearTimeout(debounceTimer);
|
|
@@ -27775,11 +28099,11 @@ data: ${JSON.stringify(event)}
|
|
|
27775
28099
|
}, DEBOUNCE_MS);
|
|
27776
28100
|
};
|
|
27777
28101
|
try {
|
|
27778
|
-
if (
|
|
28102
|
+
if (existsSync32(memoriesDir)) {
|
|
27779
28103
|
watchers.push(watch(memoriesDir, () => armDebounced("memory.changed")));
|
|
27780
28104
|
}
|
|
27781
|
-
const currentMd =
|
|
27782
|
-
if (
|
|
28105
|
+
const currentMd = join29(memoryDir, "CURRENT.md");
|
|
28106
|
+
if (existsSync32(currentMd)) {
|
|
27783
28107
|
watchers.push(watch(currentMd, () => armDebounced("constraints.changed")));
|
|
27784
28108
|
}
|
|
27785
28109
|
} catch {}
|
|
@@ -27812,19 +28136,19 @@ var DEBOUNCE_MS = 300;
|
|
|
27812
28136
|
var init_daemon = () => {};
|
|
27813
28137
|
|
|
27814
28138
|
// src/cli/ecosystem.ts
|
|
27815
|
-
import { join as
|
|
27816
|
-
import { existsSync as
|
|
28139
|
+
import { join as join30 } from "node:path";
|
|
28140
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync18, writeFileSync as writeFileSync17, readFileSync as readFileSync25 } from "node:fs";
|
|
27817
28141
|
import { homedir as homedir6 } from "node:os";
|
|
27818
28142
|
function ensureProjectAgentInstructions(targetDir) {
|
|
27819
|
-
const agentsMdPath =
|
|
27820
|
-
if (
|
|
28143
|
+
const agentsMdPath = join30(targetDir, "AGENTS.md");
|
|
28144
|
+
if (existsSync33(agentsMdPath)) {
|
|
27821
28145
|
try {
|
|
27822
|
-
const existing =
|
|
28146
|
+
const existing = readFileSync25(agentsMdPath, "utf8");
|
|
27823
28147
|
if (existing.includes("<!-- agentmemory:start -->")) {
|
|
27824
28148
|
const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
|
|
27825
|
-
|
|
28149
|
+
writeFileSync17(agentsMdPath, updated, "utf8");
|
|
27826
28150
|
} else if (!existing.includes("<!-- musememory:start -->") && !existing.includes("Muse Memory")) {
|
|
27827
|
-
|
|
28151
|
+
writeFileSync17(agentsMdPath, `${existing.trim()}
|
|
27828
28152
|
|
|
27829
28153
|
${MUSE_MEMORY_DIRECTIVE}
|
|
27830
28154
|
`, "utf8");
|
|
@@ -27835,23 +28159,23 @@ ${MUSE_MEMORY_DIRECTIVE}
|
|
|
27835
28159
|
|
|
27836
28160
|
${MUSE_MEMORY_DIRECTIVE}
|
|
27837
28161
|
`;
|
|
27838
|
-
|
|
28162
|
+
writeFileSync17(agentsMdPath, initialContent, "utf8");
|
|
27839
28163
|
}
|
|
27840
28164
|
}
|
|
27841
28165
|
async function handleInstallCommand({ positional, flags }) {
|
|
27842
28166
|
const isGlobal = flags["global"] === "true" || flags["g"] === "true";
|
|
27843
|
-
const targetDir = positional[0] ?
|
|
27844
|
-
const memoryDir = isGlobal ? getGlobalMemoryDir() :
|
|
28167
|
+
const targetDir = positional[0] ? join30(process.cwd(), positional[0]) : process.cwd();
|
|
28168
|
+
const memoryDir = isGlobal ? getGlobalMemoryDir() : join30(targetDir, ".memory");
|
|
27845
28169
|
const globalDir = getGlobalMemoryDir();
|
|
27846
|
-
mkdirSync18(
|
|
27847
|
-
mkdirSync18(
|
|
27848
|
-
const currentPath =
|
|
27849
|
-
if (!
|
|
27850
|
-
|
|
28170
|
+
mkdirSync18(join30(memoryDir, "memories"), { recursive: true });
|
|
28171
|
+
mkdirSync18(join30(globalDir, "memories"), { recursive: true });
|
|
28172
|
+
const currentPath = join30(memoryDir, "CURRENT.md");
|
|
28173
|
+
if (!existsSync33(currentPath)) {
|
|
28174
|
+
writeFileSync17(currentPath, `# Active Project Constraints
|
|
27851
28175
|
`, "utf8");
|
|
27852
28176
|
}
|
|
27853
28177
|
const globalUserPath = userFilePath(globalDir);
|
|
27854
|
-
if (!
|
|
28178
|
+
if (!existsSync33(globalUserPath)) {
|
|
27855
28179
|
const { promptSingleSelect: promptSingleSelect2 } = await Promise.resolve().then(() => (init_prompt(), exports_prompt));
|
|
27856
28180
|
const archetypeOptions = [
|
|
27857
28181
|
{ id: "developer", label: "Software Engineer / Developer", hint: "Code-first, direct, strict typing" },
|
|
@@ -27867,13 +28191,13 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
27867
28191
|
if (!isGlobal) {
|
|
27868
28192
|
ensureProjectAgentInstructions(targetDir);
|
|
27869
28193
|
}
|
|
27870
|
-
const globalAgentsMd =
|
|
27871
|
-
if (
|
|
28194
|
+
const globalAgentsMd = join30(homedir6(), ".agents", "AGENTS.md");
|
|
28195
|
+
if (existsSync33(globalAgentsMd)) {
|
|
27872
28196
|
try {
|
|
27873
|
-
const existing =
|
|
28197
|
+
const existing = readFileSync25(globalAgentsMd, "utf8");
|
|
27874
28198
|
if (existing.includes("<!-- agentmemory:start -->")) {
|
|
27875
28199
|
const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
|
|
27876
|
-
|
|
28200
|
+
writeFileSync17(globalAgentsMd, updated, "utf8");
|
|
27877
28201
|
}
|
|
27878
28202
|
} catch {}
|
|
27879
28203
|
}
|
|
@@ -27901,11 +28225,11 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
27901
28225
|
return 0;
|
|
27902
28226
|
}
|
|
27903
28227
|
async function promptOrNotifyGitHook(targetDir, autoInstall = false) {
|
|
27904
|
-
const gitDir =
|
|
27905
|
-
if (!
|
|
28228
|
+
const gitDir = join30(targetDir, ".git");
|
|
28229
|
+
if (!existsSync33(gitDir))
|
|
27906
28230
|
return false;
|
|
27907
|
-
const hookPath =
|
|
27908
|
-
const isInstalled =
|
|
28231
|
+
const hookPath = join30(gitDir, "hooks", "pre-commit");
|
|
28232
|
+
const isInstalled = existsSync33(hookPath) && readFileSync25(hookPath, "utf8").includes("memory harvest-auto");
|
|
27909
28233
|
if (isInstalled)
|
|
27910
28234
|
return true;
|
|
27911
28235
|
if (autoInstall) {
|
|
@@ -27949,7 +28273,7 @@ async function handleUninstallCommand({ positional, flags }) {
|
|
|
27949
28273
|
}
|
|
27950
28274
|
if (purge) {
|
|
27951
28275
|
const ctx = requireRoot(flags);
|
|
27952
|
-
if (ctx &&
|
|
28276
|
+
if (ctx && existsSync33(ctx.memoryDir) && !dryRun) {
|
|
27953
28277
|
const { rmSync: rmSync3 } = await import("node:fs");
|
|
27954
28278
|
rmSync3(ctx.memoryDir, { recursive: true, force: true });
|
|
27955
28279
|
console.log(` [PURGED] Memory directory removed: ${ctx.memoryDir}`);
|
|
@@ -27962,13 +28286,13 @@ async function handleUninstallCommand({ positional, flags }) {
|
|
|
27962
28286
|
}
|
|
27963
28287
|
async function handleInitCommand({ positional, flags }) {
|
|
27964
28288
|
const isGlobal = flags["global"] === "true";
|
|
27965
|
-
const targetDir = positional[0] ?
|
|
28289
|
+
const targetDir = positional[0] ? join30(process.cwd(), positional[0]) : process.cwd();
|
|
27966
28290
|
const memoryDirName = flags["legacy"] === "true" ? ".musememory" : ".memory";
|
|
27967
|
-
const memoryDir = isGlobal ? getGlobalMemoryDir() :
|
|
27968
|
-
mkdirSync18(
|
|
27969
|
-
const currentPath =
|
|
27970
|
-
if (!
|
|
27971
|
-
|
|
28291
|
+
const memoryDir = isGlobal ? getGlobalMemoryDir() : join30(targetDir, memoryDirName);
|
|
28292
|
+
mkdirSync18(join30(memoryDir, "memories"), { recursive: true });
|
|
28293
|
+
const currentPath = join30(memoryDir, "CURRENT.md");
|
|
28294
|
+
if (!existsSync33(currentPath)) {
|
|
28295
|
+
writeFileSync17(currentPath, `# Active Project Constraints
|
|
27972
28296
|
`, "utf8");
|
|
27973
28297
|
}
|
|
27974
28298
|
if (!isGlobal) {
|
|
@@ -28192,9 +28516,46 @@ async function handleDaemonCommand({ flags }) {
|
|
|
28192
28516
|
const { startHub: startHub2 } = await Promise.resolve().then(() => (init_daemon(), exports_daemon));
|
|
28193
28517
|
const hub = await startHub2(port, ctx.memoryDir);
|
|
28194
28518
|
console.log(`Agency hub listening on ${hub.url}`);
|
|
28195
|
-
console.log(`Publish events: curl -X POST http://localhost:${hub.port}/publish -d '{"type":"agent.joined","payload":{"name":"me"}}'`);
|
|
28196
28519
|
return new Promise(() => {});
|
|
28197
28520
|
}
|
|
28521
|
+
async function handleDriftCommand({ flags }) {
|
|
28522
|
+
const ctx = requireRoot(flags);
|
|
28523
|
+
if (!ctx)
|
|
28524
|
+
return 1;
|
|
28525
|
+
const { scanCodeDrift: scanCodeDrift2 } = await Promise.resolve().then(() => (init_drift(), exports_drift));
|
|
28526
|
+
const report = scanCodeDrift2({ workspaceRoot: ctx.root, memoryDir: ctx.memoryDir });
|
|
28527
|
+
if (flags["json"] === "true") {
|
|
28528
|
+
console.log(JSON.stringify(report, null, 2));
|
|
28529
|
+
return 0;
|
|
28530
|
+
}
|
|
28531
|
+
console.log(`[Code-Drift Scanner] Scanned ${report.scannedFilesCount} modified/deleted files in Git workspace.`);
|
|
28532
|
+
if (!report.isDrifted) {
|
|
28533
|
+
console.log(`✓ 0 drifted memories. All referenced code symbols and files are intact.`);
|
|
28534
|
+
return 0;
|
|
28535
|
+
}
|
|
28536
|
+
console.log(`⚠️ Detected ${report.driftCount} drifted memories:`);
|
|
28537
|
+
for (const d of report.driftedMemories) {
|
|
28538
|
+
console.log(` - [${d.driftType.toUpperCase()}] ${d.memoryId}: "${d.title}" -> ${d.affectedPath} (action: ${d.suggestedAction})`);
|
|
28539
|
+
}
|
|
28540
|
+
return 0;
|
|
28541
|
+
}
|
|
28542
|
+
async function handleCompressCommand({ positional, flags }) {
|
|
28543
|
+
const text = positional.join(" ") || "";
|
|
28544
|
+
if (!text) {
|
|
28545
|
+
return usageError("compress requires text or input");
|
|
28546
|
+
}
|
|
28547
|
+
const { compressPromptContext: compressPromptContext2 } = await Promise.resolve().then(() => exports_compress);
|
|
28548
|
+
const level = flags["aggressive"] === "true" ? "aggressive" : "light";
|
|
28549
|
+
const result = compressPromptContext2(text, { level });
|
|
28550
|
+
if (flags["json"] === "true") {
|
|
28551
|
+
console.log(JSON.stringify(result, null, 2));
|
|
28552
|
+
return 0;
|
|
28553
|
+
}
|
|
28554
|
+
console.log(`[Prompt Compression] Tokens: ${result.originalTokens} ➔ ${result.compressedTokens} (${result.savingsPercent}% savings)
|
|
28555
|
+
`);
|
|
28556
|
+
console.log(result.compressed);
|
|
28557
|
+
return 0;
|
|
28558
|
+
}
|
|
28198
28559
|
var MUSE_MEMORY_DIRECTIVE = `<!-- musememory:start -->
|
|
28199
28560
|
## \uD83E\uDDE0 Persistent Cognitive Memory (Muse Memory)
|
|
28200
28561
|
|
|
@@ -28215,8 +28576,8 @@ var init_ecosystem = __esm(() => {
|
|
|
28215
28576
|
});
|
|
28216
28577
|
|
|
28217
28578
|
// src/agentcontract.ts
|
|
28218
|
-
import { existsSync as
|
|
28219
|
-
import { join as
|
|
28579
|
+
import { existsSync as existsSync34 } from "node:fs";
|
|
28580
|
+
import { join as join31 } from "node:path";
|
|
28220
28581
|
function parseAgentMemoryContract(markdown) {
|
|
28221
28582
|
if (!markdown || !markdown.startsWith("---"))
|
|
28222
28583
|
return null;
|
|
@@ -28248,17 +28609,17 @@ function parseAgentMemoryContract(markdown) {
|
|
|
28248
28609
|
function resolveAgentFile(nameOrPath, workspaceRoot) {
|
|
28249
28610
|
if (!nameOrPath)
|
|
28250
28611
|
return null;
|
|
28251
|
-
if (
|
|
28612
|
+
if (existsSync34(nameOrPath))
|
|
28252
28613
|
return nameOrPath;
|
|
28253
28614
|
const candidates = [
|
|
28254
|
-
|
|
28255
|
-
|
|
28615
|
+
join31(workspaceRoot, ".agents", `${nameOrPath}.md`),
|
|
28616
|
+
join31(workspaceRoot, ".memory", "agents", `${nameOrPath}.md`)
|
|
28256
28617
|
];
|
|
28257
28618
|
const home = process.env.HOME;
|
|
28258
28619
|
if (home)
|
|
28259
|
-
candidates.push(
|
|
28620
|
+
candidates.push(join31(home, ".config", "opencode", "agents", `${nameOrPath}.md`));
|
|
28260
28621
|
for (const c of candidates) {
|
|
28261
|
-
if (
|
|
28622
|
+
if (existsSync34(c))
|
|
28262
28623
|
return c;
|
|
28263
28624
|
}
|
|
28264
28625
|
return null;
|
|
@@ -28268,8 +28629,8 @@ var init_agentcontract = __esm(() => {
|
|
|
28268
28629
|
});
|
|
28269
28630
|
|
|
28270
28631
|
// src/cli/retrieval.ts
|
|
28271
|
-
import { existsSync as
|
|
28272
|
-
import { join as
|
|
28632
|
+
import { existsSync as existsSync35, readFileSync as readFileSync26 } from "node:fs";
|
|
28633
|
+
import { join as join32 } from "node:path";
|
|
28273
28634
|
async function handleContextCommand({ positional, flags }) {
|
|
28274
28635
|
let agentTypes;
|
|
28275
28636
|
let agentTags;
|
|
@@ -28277,7 +28638,7 @@ async function handleContextCommand({ positional, flags }) {
|
|
|
28277
28638
|
const file = resolveAgentFile(flags["for-agent"], flags["dir"] ?? process.cwd());
|
|
28278
28639
|
if (!file)
|
|
28279
28640
|
return usageError(`--for-agent: cannot resolve agent '${flags["for-agent"]}'`);
|
|
28280
|
-
const contract = parseAgentMemoryContract(
|
|
28641
|
+
const contract = parseAgentMemoryContract(readFileSync26(file, "utf8"));
|
|
28281
28642
|
if (contract) {
|
|
28282
28643
|
agentTypes = contract.types;
|
|
28283
28644
|
agentTags = contract.tags;
|
|
@@ -28417,7 +28778,7 @@ async function handleHarvestCommand({ positional, flags }) {
|
|
|
28417
28778
|
const project = flags["project"];
|
|
28418
28779
|
if (!project)
|
|
28419
28780
|
return usageError("harvest requires --project");
|
|
28420
|
-
const rawText =
|
|
28781
|
+
const rawText = existsSync35(target) ? readFileSync26(target, "utf8") : target;
|
|
28421
28782
|
const created = harvestMemories(ctx.store, {
|
|
28422
28783
|
text: rawText,
|
|
28423
28784
|
project,
|
|
@@ -28453,8 +28814,8 @@ async function handleSearchTranscriptCommand({ positional, flags }) {
|
|
|
28453
28814
|
const filePath = positional[1];
|
|
28454
28815
|
if (!query)
|
|
28455
28816
|
return usageError("search-transcript requires <query> [file.jsonl]");
|
|
28456
|
-
const targetFile = filePath ? filePath.startsWith("/") ? filePath :
|
|
28457
|
-
if (!
|
|
28817
|
+
const targetFile = filePath ? filePath.startsWith("/") ? filePath : join32(process.cwd(), filePath) : join32(process.cwd(), "transcript.jsonl");
|
|
28818
|
+
if (!existsSync35(targetFile)) {
|
|
28458
28819
|
return fail(`error: transcript file not found: ${targetFile}`);
|
|
28459
28820
|
}
|
|
28460
28821
|
const windowSize = flags["window"] ? parseInt(flags["window"], 10) : 2;
|
|
@@ -28470,7 +28831,7 @@ async function handleReindexCommand({ flags }) {
|
|
|
28470
28831
|
const { rebuildIndex: rebuildIndex2, saveIndex: saveIndex2 } = await Promise.resolve().then(() => (init_vector(), exports_vector));
|
|
28471
28832
|
const index = rebuildIndex2(ctx.store);
|
|
28472
28833
|
saveIndex2(index, ctx.memoryDir);
|
|
28473
|
-
console.log(`indexed ${Object.keys(index.entries).length} entries -> ${
|
|
28834
|
+
console.log(`indexed ${Object.keys(index.entries).length} entries -> ${join32(ctx.memoryDir, "index.json")}`);
|
|
28474
28835
|
return 0;
|
|
28475
28836
|
}
|
|
28476
28837
|
async function handleHookCommand({ positional, flags }) {
|
|
@@ -28861,7 +29222,7 @@ var init_entities2 = __esm(() => {
|
|
|
28861
29222
|
});
|
|
28862
29223
|
|
|
28863
29224
|
// src/cli/settings.ts
|
|
28864
|
-
import { writeFileSync as
|
|
29225
|
+
import { writeFileSync as writeFileSync18, readFileSync as readFileSync27 } from "node:fs";
|
|
28865
29226
|
function handleSettingsCommand(parsed) {
|
|
28866
29227
|
const ctx = requireRoot(parsed.flags);
|
|
28867
29228
|
if (!ctx)
|
|
@@ -28943,7 +29304,7 @@ function handleSettingsCommand(parsed) {
|
|
|
28943
29304
|
const out = parsed.flags.out;
|
|
28944
29305
|
const json2 = exportSettings(memoryDir);
|
|
28945
29306
|
if (out) {
|
|
28946
|
-
|
|
29307
|
+
writeFileSync18(out, json2, "utf8");
|
|
28947
29308
|
console.log(`Exported settings to ${out}`);
|
|
28948
29309
|
} else {
|
|
28949
29310
|
console.log(json2);
|
|
@@ -28957,7 +29318,7 @@ function handleSettingsCommand(parsed) {
|
|
|
28957
29318
|
return 2;
|
|
28958
29319
|
}
|
|
28959
29320
|
try {
|
|
28960
|
-
const raw =
|
|
29321
|
+
const raw = readFileSync27(file, "utf8");
|
|
28961
29322
|
importSettings(memoryDir, raw);
|
|
28962
29323
|
console.log(`Successfully imported settings from ${file}`);
|
|
28963
29324
|
return 0;
|
|
@@ -28980,16 +29341,16 @@ var init_nudge = __esm(() => {
|
|
|
28980
29341
|
});
|
|
28981
29342
|
|
|
28982
29343
|
// src/routines.ts
|
|
28983
|
-
import { readFileSync as
|
|
28984
|
-
import { join as
|
|
29344
|
+
import { readFileSync as readFileSync28, existsSync as existsSync36 } from "node:fs";
|
|
29345
|
+
import { join as join33 } from "node:path";
|
|
28985
29346
|
function routinesPath(memoryDir) {
|
|
28986
|
-
return
|
|
29347
|
+
return join33(memoryDir, "routines.yaml");
|
|
28987
29348
|
}
|
|
28988
29349
|
function loadRoutines(memoryDir) {
|
|
28989
29350
|
const p = routinesPath(memoryDir);
|
|
28990
|
-
if (!
|
|
29351
|
+
if (!existsSync36(p))
|
|
28991
29352
|
return { routines: {} };
|
|
28992
|
-
const doc2 = yaml.load(
|
|
29353
|
+
const doc2 = yaml.load(readFileSync28(p, "utf8"), { schema: yaml.JSON_SCHEMA }) ?? {};
|
|
28993
29354
|
const routines = doc2.routines ?? {};
|
|
28994
29355
|
for (const [name, r] of Object.entries(routines)) {
|
|
28995
29356
|
if (!r || typeof r.schedule !== "string" || !r.schedule.trim()) {
|
|
@@ -29027,7 +29388,7 @@ var init_routines = __esm(() => {
|
|
|
29027
29388
|
});
|
|
29028
29389
|
|
|
29029
29390
|
// src/cli/lifecycle.ts
|
|
29030
|
-
import { writeFileSync as
|
|
29391
|
+
import { writeFileSync as writeFileSync19, readFileSync as readFileSync29, existsSync as existsSync37 } from "node:fs";
|
|
29031
29392
|
async function handleProposeCommand({ positional, flags }) {
|
|
29032
29393
|
const ctx = requireRoot(flags);
|
|
29033
29394
|
if (!ctx)
|
|
@@ -29176,7 +29537,7 @@ async function handleExportCommand({ flags }) {
|
|
|
29176
29537
|
const snapshot = exportSnapshot(ctx.store);
|
|
29177
29538
|
const outPath = flags["out"];
|
|
29178
29539
|
if (outPath) {
|
|
29179
|
-
|
|
29540
|
+
writeFileSync19(outPath, JSON.stringify(snapshot, null, 2), "utf8");
|
|
29180
29541
|
console.log(`exported ${snapshot.total} memories to ${outPath}`);
|
|
29181
29542
|
} else {
|
|
29182
29543
|
console.log(JSON.stringify(snapshot, null, 2));
|
|
@@ -29190,9 +29551,9 @@ async function handleImportCommand({ positional, flags }) {
|
|
|
29190
29551
|
const file = positional[0];
|
|
29191
29552
|
if (!file)
|
|
29192
29553
|
return usageError("import requires <file.json>");
|
|
29193
|
-
if (!
|
|
29554
|
+
if (!existsSync37(file))
|
|
29194
29555
|
return fail(`error: file ${file} does not exist`);
|
|
29195
|
-
const raw = JSON.parse(
|
|
29556
|
+
const raw = JSON.parse(readFileSync29(file, "utf8"));
|
|
29196
29557
|
const res = importSnapshot(ctx.store, raw, { overwrite: flags["overwrite"] === "true" });
|
|
29197
29558
|
if (res.errors.length > 0) {
|
|
29198
29559
|
console.error(`import encountered errors:`);
|
|
@@ -29577,6 +29938,11 @@ async function main(argv) {
|
|
|
29577
29938
|
return handleUiCommand(parsed);
|
|
29578
29939
|
case "graph":
|
|
29579
29940
|
return handleGraphCommand(parsed);
|
|
29941
|
+
case "drift":
|
|
29942
|
+
case "check":
|
|
29943
|
+
return handleDriftCommand(parsed);
|
|
29944
|
+
case "compress":
|
|
29945
|
+
return handleCompressCommand(parsed);
|
|
29580
29946
|
case "mcp":
|
|
29581
29947
|
return handleMcpCommand();
|
|
29582
29948
|
case "daemon":
|