musememory 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/muse-brief/SKILL.md +67 -0
- package/.agents/skills/muse-capture/SKILL.md +70 -0
- package/.agents/skills/muse-current/SKILL.md +62 -0
- package/.agents/skills/muse-graph/SKILL.md +61 -0
- package/.agents/skills/muse-ground/SKILL.md +62 -0
- package/.agents/skills/muse-wiki/SKILL.md +57 -0
- package/README.md +186 -285
- package/dist/index.js +1267 -901
- package/package.json +4 -1
- package/schema.json +60 -0
- package/skills/muse-brief/SKILL.md +67 -0
- package/skills/muse-capture/SKILL.md +70 -0
- package/skills/muse-current/SKILL.md +62 -0
- package/skills/muse-graph/SKILL.md +61 -0
- package/skills/muse-ground/SKILL.md +62 -0
- package/skills/muse-wiki/SKILL.md +57 -0
package/dist/index.js
CHANGED
|
@@ -4,7 +4,6 @@ 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;
|
|
8
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
8
|
function __accessProp(key) {
|
|
10
9
|
return this[key];
|
|
@@ -33,23 +32,6 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
33
32
|
cache.set(mod, to);
|
|
34
33
|
return to;
|
|
35
34
|
};
|
|
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;
|
|
53
35
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
54
36
|
var __returnValue = (v) => v;
|
|
55
37
|
function __exportSetter(name, newValue) {
|
|
@@ -110,7 +92,7 @@ var init_secrets = __esm(() => {
|
|
|
110
92
|
},
|
|
111
93
|
{
|
|
112
94
|
name: "Private Key Block",
|
|
113
|
-
pattern: /-----BEGIN (?:RSA|DSA|EC|OPENSSH|PGP|ENCRYPTED|PRIVATE)? ?
|
|
95
|
+
pattern: /-----BEGIN (?:RSA|DSA|EC|OPENSSH|PGP|ENCRYPTED|PRIVATE)? ?(?:PRIVATE )?KEY/i
|
|
114
96
|
},
|
|
115
97
|
{
|
|
116
98
|
name: "Slack Token",
|
|
@@ -3532,7 +3514,14 @@ var init_types = __esm(() => {
|
|
|
3532
3514
|
// src/retrieval.ts
|
|
3533
3515
|
import { existsSync as existsSync4 } from "node:fs";
|
|
3534
3516
|
import { join as join4 } from "node:path";
|
|
3517
|
+
function tokenize(text) {
|
|
3518
|
+
if (!text || typeof text !== "string")
|
|
3519
|
+
return [];
|
|
3520
|
+
return text.toLowerCase().match(/[a-z0-9]+/g) ?? [];
|
|
3521
|
+
}
|
|
3535
3522
|
function stalePolicyDays(type2) {
|
|
3523
|
+
if (!type2)
|
|
3524
|
+
return DEFAULT_STALE_DAYS;
|
|
3536
3525
|
switch (type2) {
|
|
3537
3526
|
case "fix":
|
|
3538
3527
|
return 90;
|
|
@@ -3548,11 +3537,6 @@ function stalePolicyDays(type2) {
|
|
|
3548
3537
|
return DEFAULT_STALE_DAYS;
|
|
3549
3538
|
}
|
|
3550
3539
|
}
|
|
3551
|
-
function tokenize(text) {
|
|
3552
|
-
if (!text || typeof text !== "string")
|
|
3553
|
-
return [];
|
|
3554
|
-
return text.toLowerCase().match(/[a-z0-9]+/g) ?? [];
|
|
3555
|
-
}
|
|
3556
3540
|
function estimateEntryTokens(entry) {
|
|
3557
3541
|
const text = `${entry.id} ${entry.status} ${entry.project} ${entry.title}
|
|
3558
3542
|
${entry.content}
|
|
@@ -3593,6 +3577,16 @@ function isExpired(entry, now) {
|
|
|
3593
3577
|
const t = Date.parse(entry.expires_at);
|
|
3594
3578
|
return !Number.isNaN(t) && t <= now;
|
|
3595
3579
|
}
|
|
3580
|
+
function graphSymbolOverlapBonus(entry, queryTokens) {
|
|
3581
|
+
const symbols = entry.graph?.symbol_names;
|
|
3582
|
+
if (!symbols || symbols.length === 0 || queryTokens.length === 0)
|
|
3583
|
+
return 0;
|
|
3584
|
+
const symSet = new Set(symbols.map((s) => s.toLowerCase()));
|
|
3585
|
+
const matches = queryTokens.filter((t) => symSet.has(t.toLowerCase())).length;
|
|
3586
|
+
if (matches === 0)
|
|
3587
|
+
return 0;
|
|
3588
|
+
return Math.min(0.2, matches / queryTokens.length * 0.2);
|
|
3589
|
+
}
|
|
3596
3590
|
function scoreEntry(entry, queryTokens, now) {
|
|
3597
3591
|
const app = applicability(entry, queryTokens);
|
|
3598
3592
|
const statusPenalty = STATUS_PENALTY[entry.status] ?? 0;
|
|
@@ -3602,18 +3596,23 @@ function scoreEntry(entry, queryTokens, now) {
|
|
|
3602
3596
|
const r = entry.reinforcement ?? 0;
|
|
3603
3597
|
const reinforcementBonus = Math.sign(r) * 0.05 * Math.min(Math.abs(r), 5);
|
|
3604
3598
|
const dueBonus = dueDateBonus(entry, now);
|
|
3599
|
+
const graphBonus = graphSymbolOverlapBonus(entry, queryTokens);
|
|
3605
3600
|
const decayBase = entry.valid_from ?? entry.updated_at;
|
|
3606
3601
|
const decay = 0.3 * Math.exp(-daysSince(decayBase, now) / 90);
|
|
3607
|
-
return app + statusPenalty + verificationBonus + salienceBonus + reinforcementBonus + dueBonus + decay;
|
|
3602
|
+
return app + statusPenalty + verificationBonus + salienceBonus + reinforcementBonus + dueBonus + graphBonus + decay;
|
|
3608
3603
|
}
|
|
3609
3604
|
function sortCandidates(candidates, queryTokens, now) {
|
|
3610
3605
|
return candidates.map((entry) => ({ entry, score: scoreEntry(entry, queryTokens, now) })).sort((a, b) => {
|
|
3611
3606
|
if (b.score !== a.score)
|
|
3612
3607
|
return b.score - a.score;
|
|
3613
|
-
const
|
|
3608
|
+
const bU = Date.parse(b.entry.updated_at);
|
|
3609
|
+
const aU = Date.parse(a.entry.updated_at);
|
|
3610
|
+
const u = (Number.isNaN(bU) ? 0 : bU) - (Number.isNaN(aU) ? 0 : aU);
|
|
3614
3611
|
if (u !== 0)
|
|
3615
3612
|
return u;
|
|
3616
|
-
|
|
3613
|
+
const bC = Date.parse(b.entry.created_at);
|
|
3614
|
+
const aC = Date.parse(a.entry.created_at);
|
|
3615
|
+
return (Number.isNaN(bC) ? 0 : bC) - (Number.isNaN(aC) ? 0 : aC);
|
|
3617
3616
|
});
|
|
3618
3617
|
}
|
|
3619
3618
|
function queryContext(store, query = "", options = {}) {
|
|
@@ -3648,14 +3647,16 @@ function queryContext(store, query = "", options = {}) {
|
|
|
3648
3647
|
const limit = options.limit ?? 10;
|
|
3649
3648
|
const results = [];
|
|
3650
3649
|
let totalTokensUsed = 0;
|
|
3651
|
-
if (options.tokenBudget
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3650
|
+
if (options.tokenBudget !== undefined) {
|
|
3651
|
+
if (options.tokenBudget > 0) {
|
|
3652
|
+
for (const item of scored) {
|
|
3653
|
+
if (results.length >= limit)
|
|
3654
|
+
break;
|
|
3655
|
+
const tokens = estimateEntryTokens(item.entry);
|
|
3656
|
+
if (totalTokensUsed + tokens <= options.tokenBudget) {
|
|
3657
|
+
results.push(item);
|
|
3658
|
+
totalTokensUsed += tokens;
|
|
3659
|
+
}
|
|
3659
3660
|
}
|
|
3660
3661
|
}
|
|
3661
3662
|
} else {
|
|
@@ -3694,7 +3695,6 @@ function formatPromptContext(store, memoryDir, query = "", options = {}) {
|
|
|
3694
3695
|
}
|
|
3695
3696
|
parts.push("");
|
|
3696
3697
|
}
|
|
3697
|
-
const { getSessionHandoff } = (init_current(), __toCommonJS(exports_current));
|
|
3698
3698
|
const handoff = memoryDir ? getSessionHandoff(memoryDir) : null;
|
|
3699
3699
|
if (handoff && (handoff.status === "IN-PROGRESS" || handoff.task || handoff.lastQuery)) {
|
|
3700
3700
|
parts.push("### Active In-Flight Context & Session Handoff (CURRENT.md)");
|
|
@@ -3721,7 +3721,6 @@ function formatPromptContext(store, memoryDir, query = "", options = {}) {
|
|
|
3721
3721
|
}
|
|
3722
3722
|
if (memoryDir && existsSync4(join4(memoryDir, "wiki"))) {
|
|
3723
3723
|
try {
|
|
3724
|
-
const { listWikiPages } = (init_wiki(), __toCommonJS(exports_wiki));
|
|
3725
3724
|
const wikiPages = listWikiPages(memoryDir, { detailLevel: "l1", project: options.project });
|
|
3726
3725
|
if (wikiPages.length > 0) {
|
|
3727
3726
|
const queryTokens = tokenize(query);
|
|
@@ -3729,7 +3728,8 @@ function formatPromptContext(store, memoryDir, query = "", options = {}) {
|
|
|
3729
3728
|
if (relevantWiki.length > 0) {
|
|
3730
3729
|
parts.push("### Compiled Knowledge & Concepts (Wiki L1)");
|
|
3731
3730
|
for (const wp of relevantWiki) {
|
|
3732
|
-
|
|
3731
|
+
const sum = wp.summary;
|
|
3732
|
+
parts.push(`- [[${wp.slug}]]: ${wp.title}${sum ? ` — ${sum}` : ""}`);
|
|
3733
3733
|
}
|
|
3734
3734
|
parts.push("");
|
|
3735
3735
|
}
|
|
@@ -3792,12 +3792,190 @@ function formatPromptContext(store, memoryDir, query = "", options = {}) {
|
|
|
3792
3792
|
userProfile
|
|
3793
3793
|
};
|
|
3794
3794
|
}
|
|
3795
|
+
var STOPWORDS;
|
|
3795
3796
|
var init_retrieval = __esm(() => {
|
|
3796
3797
|
init_store();
|
|
3797
|
-
|
|
3798
|
+
init_governor();
|
|
3799
|
+
init_compiler();
|
|
3798
3800
|
init_user();
|
|
3799
3801
|
init_core();
|
|
3800
3802
|
init_types();
|
|
3803
|
+
STOPWORDS = new Set([
|
|
3804
|
+
"a",
|
|
3805
|
+
"about",
|
|
3806
|
+
"above",
|
|
3807
|
+
"after",
|
|
3808
|
+
"again",
|
|
3809
|
+
"against",
|
|
3810
|
+
"all",
|
|
3811
|
+
"am",
|
|
3812
|
+
"an",
|
|
3813
|
+
"and",
|
|
3814
|
+
"any",
|
|
3815
|
+
"are",
|
|
3816
|
+
"aren't",
|
|
3817
|
+
"as",
|
|
3818
|
+
"at",
|
|
3819
|
+
"be",
|
|
3820
|
+
"because",
|
|
3821
|
+
"been",
|
|
3822
|
+
"before",
|
|
3823
|
+
"being",
|
|
3824
|
+
"below",
|
|
3825
|
+
"between",
|
|
3826
|
+
"both",
|
|
3827
|
+
"but",
|
|
3828
|
+
"by",
|
|
3829
|
+
"can't",
|
|
3830
|
+
"cannot",
|
|
3831
|
+
"could",
|
|
3832
|
+
"couldn't",
|
|
3833
|
+
"did",
|
|
3834
|
+
"didn't",
|
|
3835
|
+
"do",
|
|
3836
|
+
"does",
|
|
3837
|
+
"doesn't",
|
|
3838
|
+
"doing",
|
|
3839
|
+
"don't",
|
|
3840
|
+
"down",
|
|
3841
|
+
"during",
|
|
3842
|
+
"each",
|
|
3843
|
+
"few",
|
|
3844
|
+
"for",
|
|
3845
|
+
"from",
|
|
3846
|
+
"further",
|
|
3847
|
+
"had",
|
|
3848
|
+
"hadn't",
|
|
3849
|
+
"has",
|
|
3850
|
+
"hasn't",
|
|
3851
|
+
"have",
|
|
3852
|
+
"haven't",
|
|
3853
|
+
"having",
|
|
3854
|
+
"he",
|
|
3855
|
+
"he'd",
|
|
3856
|
+
"he'll",
|
|
3857
|
+
"he's",
|
|
3858
|
+
"her",
|
|
3859
|
+
"here",
|
|
3860
|
+
"here's",
|
|
3861
|
+
"hers",
|
|
3862
|
+
"herself",
|
|
3863
|
+
"him",
|
|
3864
|
+
"himself",
|
|
3865
|
+
"his",
|
|
3866
|
+
"how",
|
|
3867
|
+
"how's",
|
|
3868
|
+
"i",
|
|
3869
|
+
"i'd",
|
|
3870
|
+
"i'll",
|
|
3871
|
+
"i'm",
|
|
3872
|
+
"i've",
|
|
3873
|
+
"if",
|
|
3874
|
+
"in",
|
|
3875
|
+
"into",
|
|
3876
|
+
"is",
|
|
3877
|
+
"isn't",
|
|
3878
|
+
"it",
|
|
3879
|
+
"it's",
|
|
3880
|
+
"its",
|
|
3881
|
+
"itself",
|
|
3882
|
+
"let's",
|
|
3883
|
+
"me",
|
|
3884
|
+
"more",
|
|
3885
|
+
"most",
|
|
3886
|
+
"mustn't",
|
|
3887
|
+
"my",
|
|
3888
|
+
"myself",
|
|
3889
|
+
"no",
|
|
3890
|
+
"nor",
|
|
3891
|
+
"not",
|
|
3892
|
+
"of",
|
|
3893
|
+
"off",
|
|
3894
|
+
"on",
|
|
3895
|
+
"once",
|
|
3896
|
+
"only",
|
|
3897
|
+
"or",
|
|
3898
|
+
"other",
|
|
3899
|
+
"ought",
|
|
3900
|
+
"our",
|
|
3901
|
+
"ours",
|
|
3902
|
+
"ourselves",
|
|
3903
|
+
"out",
|
|
3904
|
+
"over",
|
|
3905
|
+
"own",
|
|
3906
|
+
"same",
|
|
3907
|
+
"shan't",
|
|
3908
|
+
"she",
|
|
3909
|
+
"she'd",
|
|
3910
|
+
"she'll",
|
|
3911
|
+
"she's",
|
|
3912
|
+
"should",
|
|
3913
|
+
"shouldn't",
|
|
3914
|
+
"so",
|
|
3915
|
+
"some",
|
|
3916
|
+
"such",
|
|
3917
|
+
"than",
|
|
3918
|
+
"that",
|
|
3919
|
+
"that's",
|
|
3920
|
+
"the",
|
|
3921
|
+
"their",
|
|
3922
|
+
"theirs",
|
|
3923
|
+
"them",
|
|
3924
|
+
"themselves",
|
|
3925
|
+
"then",
|
|
3926
|
+
"there",
|
|
3927
|
+
"there's",
|
|
3928
|
+
"these",
|
|
3929
|
+
"they",
|
|
3930
|
+
"they'd",
|
|
3931
|
+
"they'll",
|
|
3932
|
+
"they're",
|
|
3933
|
+
"they've",
|
|
3934
|
+
"this",
|
|
3935
|
+
"those",
|
|
3936
|
+
"through",
|
|
3937
|
+
"to",
|
|
3938
|
+
"too",
|
|
3939
|
+
"under",
|
|
3940
|
+
"until",
|
|
3941
|
+
"up",
|
|
3942
|
+
"very",
|
|
3943
|
+
"was",
|
|
3944
|
+
"wasn't",
|
|
3945
|
+
"we",
|
|
3946
|
+
"we'd",
|
|
3947
|
+
"we'll",
|
|
3948
|
+
"we're",
|
|
3949
|
+
"we've",
|
|
3950
|
+
"were",
|
|
3951
|
+
"weren't",
|
|
3952
|
+
"what",
|
|
3953
|
+
"what's",
|
|
3954
|
+
"when",
|
|
3955
|
+
"when's",
|
|
3956
|
+
"where",
|
|
3957
|
+
"where's",
|
|
3958
|
+
"which",
|
|
3959
|
+
"while",
|
|
3960
|
+
"who",
|
|
3961
|
+
"who's",
|
|
3962
|
+
"whom",
|
|
3963
|
+
"why",
|
|
3964
|
+
"why's",
|
|
3965
|
+
"with",
|
|
3966
|
+
"won't",
|
|
3967
|
+
"would",
|
|
3968
|
+
"wouldn't",
|
|
3969
|
+
"you",
|
|
3970
|
+
"you'd",
|
|
3971
|
+
"you'll",
|
|
3972
|
+
"you're",
|
|
3973
|
+
"you've",
|
|
3974
|
+
"your",
|
|
3975
|
+
"yours",
|
|
3976
|
+
"yourself",
|
|
3977
|
+
"yourselves"
|
|
3978
|
+
]);
|
|
3801
3979
|
});
|
|
3802
3980
|
|
|
3803
3981
|
// src/governor.ts
|
|
@@ -4062,22 +4240,6 @@ function recordSessionEnd(store, sessionId, project, summary) {
|
|
|
4062
4240
|
save(store, entry);
|
|
4063
4241
|
return entry;
|
|
4064
4242
|
}
|
|
4065
|
-
function getSessionMemories(store, sessionId) {
|
|
4066
|
-
return list(store).filter((e) => e.session_id === sessionId && e.type !== "session");
|
|
4067
|
-
}
|
|
4068
|
-
function linkMemoriesToSession(store, sessionId, memoryIds) {
|
|
4069
|
-
const updated = [];
|
|
4070
|
-
const entries = list(store);
|
|
4071
|
-
for (const id of memoryIds) {
|
|
4072
|
-
const entry = entries.find((e) => e.id === id);
|
|
4073
|
-
if (entry) {
|
|
4074
|
-
entry.session_id = sessionId;
|
|
4075
|
-
save(store, entry);
|
|
4076
|
-
updated.push(entry);
|
|
4077
|
-
}
|
|
4078
|
-
}
|
|
4079
|
-
return updated;
|
|
4080
|
-
}
|
|
4081
4243
|
function probeGit(workspaceRoot) {
|
|
4082
4244
|
const items = [];
|
|
4083
4245
|
try {
|
|
@@ -4255,374 +4417,120 @@ var init_governor = __esm(() => {
|
|
|
4255
4417
|
});
|
|
4256
4418
|
|
|
4257
4419
|
// src/current.ts
|
|
4258
|
-
var exports_current = {};
|
|
4259
|
-
__export(exports_current, {
|
|
4260
|
-
WorkspaceGovernor: () => WorkspaceGovernor,
|
|
4261
|
-
collectLoops: () => collectLoops,
|
|
4262
|
-
collectNudges: () => collectNudges,
|
|
4263
|
-
currentFilePath: () => currentFilePath,
|
|
4264
|
-
dueEntries: () => dueEntries,
|
|
4265
|
-
findSession: () => findSession,
|
|
4266
|
-
getCurrent: () => getCurrent2,
|
|
4267
|
-
getSessionHandoff: () => getSessionHandoff,
|
|
4268
|
-
getSessionMemories: () => getSessionMemories,
|
|
4269
|
-
linkMemoriesToSession: () => linkMemoriesToSession,
|
|
4270
|
-
markSessionCompleted: () => markSessionCompleted,
|
|
4271
|
-
parseCurrentFile: () => parseCurrentFile,
|
|
4272
|
-
recordSessionEnd: () => recordSessionEnd,
|
|
4273
|
-
recordSessionStart: () => recordSessionStart,
|
|
4274
|
-
renderLoops: () => renderLoops,
|
|
4275
|
-
renderNudges: () => renderNudges,
|
|
4276
|
-
setCurrent: () => setCurrent,
|
|
4277
|
-
syncConstraints: () => syncConstraints,
|
|
4278
|
-
updateSessionHandoff: () => updateSessionHandoff,
|
|
4279
|
-
writeCurrentFile: () => writeCurrentFile
|
|
4280
|
-
});
|
|
4281
4420
|
var init_current = __esm(() => {
|
|
4282
4421
|
init_governor();
|
|
4283
4422
|
});
|
|
4284
4423
|
|
|
4285
|
-
// src/
|
|
4286
|
-
import { existsSync as existsSync6,
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4424
|
+
// src/transcript.ts
|
|
4425
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "node:fs";
|
|
4426
|
+
function parseJsonlTranscript(jsonlText) {
|
|
4427
|
+
if (!jsonlText)
|
|
4428
|
+
return [];
|
|
4429
|
+
const lines = jsonlText.split(`
|
|
4430
|
+
`).map((l) => l.trim()).filter(Boolean);
|
|
4431
|
+
const blocks = [];
|
|
4432
|
+
for (const line of lines) {
|
|
4433
|
+
try {
|
|
4434
|
+
const obj = JSON.parse(line);
|
|
4435
|
+
const prevLen = blocks.length;
|
|
4436
|
+
if (typeof obj.content === "string") {
|
|
4437
|
+
blocks.push(obj.content);
|
|
4438
|
+
} else if (Array.isArray(obj.content)) {
|
|
4439
|
+
for (const item of obj.content) {
|
|
4440
|
+
if (typeof item === "string")
|
|
4441
|
+
blocks.push(item);
|
|
4442
|
+
else if (item && typeof item.text === "string")
|
|
4443
|
+
blocks.push(item.text);
|
|
4444
|
+
}
|
|
4445
|
+
}
|
|
4446
|
+
if (typeof obj.thinking === "string") {
|
|
4447
|
+
blocks.push(obj.thinking);
|
|
4448
|
+
}
|
|
4449
|
+
if (typeof obj.message === "string") {
|
|
4450
|
+
blocks.push(obj.message);
|
|
4451
|
+
}
|
|
4452
|
+
if (typeof obj.text === "string") {
|
|
4453
|
+
blocks.push(obj.text);
|
|
4454
|
+
}
|
|
4455
|
+
if (typeof obj.path === "string") {
|
|
4456
|
+
blocks.push(obj.path);
|
|
4457
|
+
}
|
|
4458
|
+
if (obj.tool_calls && Array.isArray(obj.tool_calls)) {
|
|
4459
|
+
for (const tc of obj.tool_calls) {
|
|
4460
|
+
if (tc.arguments && typeof tc.arguments === "string")
|
|
4461
|
+
blocks.push(tc.arguments);
|
|
4462
|
+
}
|
|
4463
|
+
}
|
|
4464
|
+
if (blocks.length === prevLen) {
|
|
4465
|
+
const textParts = Object.values(obj).filter((v) => typeof v === "string").join(" ");
|
|
4466
|
+
blocks.push(textParts.length > 0 ? textParts : line);
|
|
4467
|
+
}
|
|
4468
|
+
} catch {
|
|
4469
|
+
blocks.push(line);
|
|
4295
4470
|
}
|
|
4296
|
-
}
|
|
4297
|
-
|
|
4298
|
-
__require("node:sqlite");
|
|
4299
|
-
sqliteDriver = "node";
|
|
4300
|
-
return "node";
|
|
4301
|
-
} catch {}
|
|
4302
|
-
sqliteDriver = "bun";
|
|
4303
|
-
return "bun";
|
|
4471
|
+
}
|
|
4472
|
+
return blocks;
|
|
4304
4473
|
}
|
|
4305
|
-
function
|
|
4306
|
-
|
|
4307
|
-
if (
|
|
4308
|
-
|
|
4474
|
+
function searchTranscriptWithBookends(transcriptPathOrContent, query, options = {}) {
|
|
4475
|
+
let content = transcriptPathOrContent;
|
|
4476
|
+
if (existsSync6(transcriptPathOrContent)) {
|
|
4477
|
+
content = readFileSync5(transcriptPathOrContent, "utf8");
|
|
4309
4478
|
}
|
|
4310
|
-
const
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
exec(sql) {
|
|
4319
|
-
rawDb.exec(sql);
|
|
4320
|
-
},
|
|
4321
|
-
run(sql, params) {
|
|
4322
|
-
if (params && Array.isArray(params)) {
|
|
4323
|
-
rawDb.run(sql, params);
|
|
4324
|
-
} else if (params && typeof params === "object") {
|
|
4325
|
-
rawDb.run(sql, params);
|
|
4326
|
-
} else {
|
|
4327
|
-
rawDb.run(sql);
|
|
4328
|
-
}
|
|
4329
|
-
},
|
|
4330
|
-
query(sql) {
|
|
4331
|
-
const stmt = rawDb.query(sql);
|
|
4332
|
-
return {
|
|
4333
|
-
all(params) {
|
|
4334
|
-
return params ? stmt.all(params) : stmt.all();
|
|
4335
|
-
},
|
|
4336
|
-
get(params) {
|
|
4337
|
-
return params ? stmt.get(params) : stmt.get();
|
|
4338
|
-
}
|
|
4339
|
-
};
|
|
4340
|
-
},
|
|
4341
|
-
close() {
|
|
4342
|
-
rawDb.close();
|
|
4343
|
-
}
|
|
4479
|
+
const turns = parseJsonlTranscript(content);
|
|
4480
|
+
if (turns.length === 0) {
|
|
4481
|
+
return {
|
|
4482
|
+
totalTurns: 0,
|
|
4483
|
+
bookendStart: "",
|
|
4484
|
+
bookendEnd: "",
|
|
4485
|
+
matches: [],
|
|
4486
|
+
formattedSummary: "No turns found in transcript."
|
|
4344
4487
|
};
|
|
4345
|
-
|
|
4346
|
-
|
|
4488
|
+
}
|
|
4489
|
+
const windowSize = options.windowSize ?? 2;
|
|
4490
|
+
const maxMatches = options.maxMatches ?? 5;
|
|
4491
|
+
const bookendStart = turns[0] ?? "";
|
|
4492
|
+
const bookendEnd = turns[turns.length - 1] ?? "";
|
|
4493
|
+
const queryTerms = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
4494
|
+
const matches = [];
|
|
4495
|
+
for (let i = 0;i < turns.length; i++) {
|
|
4496
|
+
if (matches.length >= maxMatches)
|
|
4497
|
+
break;
|
|
4498
|
+
const turnLower = turns[i].toLowerCase();
|
|
4499
|
+
const isMatch = queryTerms.length > 0 && queryTerms.every((term) => turnLower.includes(term));
|
|
4500
|
+
if (isMatch) {
|
|
4501
|
+
const before = turns.slice(Math.max(0, i - windowSize), i);
|
|
4502
|
+
const after = turns.slice(i + 1, Math.min(turns.length, i + 1 + windowSize));
|
|
4503
|
+
matches.push({
|
|
4504
|
+
index: i,
|
|
4505
|
+
matchedTurn: turns[i],
|
|
4506
|
+
before,
|
|
4507
|
+
after
|
|
4508
|
+
});
|
|
4509
|
+
}
|
|
4510
|
+
}
|
|
4511
|
+
const lines = [];
|
|
4512
|
+
lines.push(`### Conversation Overview (${turns.length} total turns)`);
|
|
4513
|
+
lines.push(`**[Start Bookend]**: ${bookendStart.slice(0, 200).replace(/\n+/g, " ")}`);
|
|
4514
|
+
lines.push(`**[End Bookend]**: ${bookendEnd.slice(0, 200).replace(/\n+/g, " ")}`);
|
|
4515
|
+
lines.push("");
|
|
4516
|
+
if (matches.length === 0) {
|
|
4517
|
+
lines.push(`*No matches found for query "${query}".*`);
|
|
4347
4518
|
} else {
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
},
|
|
4356
|
-
run(sql, params) {
|
|
4357
|
-
const stmt = rawDb.prepare(sql);
|
|
4358
|
-
if (params && Array.isArray(params)) {
|
|
4359
|
-
stmt.run(...params);
|
|
4360
|
-
} else if (params && typeof params === "object") {
|
|
4361
|
-
stmt.run(params);
|
|
4362
|
-
} else {
|
|
4363
|
-
stmt.run();
|
|
4364
|
-
}
|
|
4365
|
-
},
|
|
4366
|
-
query(sql) {
|
|
4367
|
-
const stmt = rawDb.prepare(sql);
|
|
4368
|
-
return {
|
|
4369
|
-
all(params) {
|
|
4370
|
-
if (params && Array.isArray(params))
|
|
4371
|
-
return stmt.all(...params);
|
|
4372
|
-
if (params && typeof params === "object")
|
|
4373
|
-
return stmt.all(params);
|
|
4374
|
-
return stmt.all();
|
|
4375
|
-
},
|
|
4376
|
-
get(params) {
|
|
4377
|
-
if (params && Array.isArray(params))
|
|
4378
|
-
return stmt.get(...params);
|
|
4379
|
-
if (params && typeof params === "object")
|
|
4380
|
-
return stmt.get(params);
|
|
4381
|
-
return stmt.get();
|
|
4382
|
-
}
|
|
4383
|
-
};
|
|
4384
|
-
},
|
|
4385
|
-
close() {
|
|
4386
|
-
rawDb.close();
|
|
4519
|
+
lines.push(`### Matches for "${query}" (${matches.length} found):`);
|
|
4520
|
+
matches.forEach((m, idx) => {
|
|
4521
|
+
lines.push(`
|
|
4522
|
+
#### Match ${idx + 1} (Turn ${m.index + 1})`);
|
|
4523
|
+
if (m.before.length > 0) {
|
|
4524
|
+
lines.push(`*Context Before:*`);
|
|
4525
|
+
m.before.forEach((b) => lines.push(`> ${b.slice(0, 150).replace(/\n+/g, " ")}`));
|
|
4387
4526
|
}
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
}
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
CREATE TABLE IF NOT EXISTS memories (
|
|
4396
|
-
id TEXT PRIMARY KEY,
|
|
4397
|
-
title TEXT NOT NULL,
|
|
4398
|
-
content TEXT NOT NULL,
|
|
4399
|
-
project TEXT NOT NULL,
|
|
4400
|
-
type TEXT NOT NULL,
|
|
4401
|
-
status TEXT NOT NULL,
|
|
4402
|
-
salience REAL,
|
|
4403
|
-
reinforcement INTEGER,
|
|
4404
|
-
session_id TEXT,
|
|
4405
|
-
due_at TEXT,
|
|
4406
|
-
expires_at TEXT,
|
|
4407
|
-
valid_from TEXT,
|
|
4408
|
-
valid_to TEXT,
|
|
4409
|
-
data TEXT NOT NULL,
|
|
4410
|
-
created_at TEXT NOT NULL,
|
|
4411
|
-
updated_at TEXT NOT NULL
|
|
4412
|
-
);
|
|
4413
|
-
|
|
4414
|
-
CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project);
|
|
4415
|
-
CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
|
|
4416
|
-
CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status);
|
|
4417
|
-
CREATE INDEX IF NOT EXISTS idx_memories_session_id ON memories(session_id);
|
|
4418
|
-
CREATE INDEX IF NOT EXISTS idx_memories_due_at ON memories(due_at);
|
|
4419
|
-
CREATE INDEX IF NOT EXISTS idx_memories_updated_at ON memories(updated_at);
|
|
4420
|
-
`);
|
|
4421
|
-
}
|
|
4422
|
-
function rowToMemoryEntry(row) {
|
|
4423
|
-
let parsedData = {};
|
|
4424
|
-
try {
|
|
4425
|
-
parsedData = JSON.parse(row.data);
|
|
4426
|
-
} catch {}
|
|
4427
|
-
return {
|
|
4428
|
-
...parsedData,
|
|
4429
|
-
id: row.id,
|
|
4430
|
-
title: row.title,
|
|
4431
|
-
content: row.content,
|
|
4432
|
-
project: row.project,
|
|
4433
|
-
type: row.type,
|
|
4434
|
-
status: row.status,
|
|
4435
|
-
salience: row.salience !== null ? row.salience : parsedData.salience,
|
|
4436
|
-
reinforcement: row.reinforcement !== null ? row.reinforcement : parsedData.reinforcement,
|
|
4437
|
-
session_id: row.session_id !== null ? row.session_id : parsedData.session_id,
|
|
4438
|
-
due_at: row.due_at !== null ? row.due_at : parsedData.due_at,
|
|
4439
|
-
expires_at: row.expires_at !== null ? row.expires_at : parsedData.expires_at,
|
|
4440
|
-
valid_from: row.valid_from !== null ? row.valid_from : parsedData.valid_from,
|
|
4441
|
-
valid_to: row.valid_to !== null ? row.valid_to : parsedData.valid_to,
|
|
4442
|
-
created_at: row.created_at || parsedData.created_at || new Date().toISOString(),
|
|
4443
|
-
updated_at: row.updated_at || parsedData.updated_at || new Date().toISOString()
|
|
4444
|
-
};
|
|
4445
|
-
}
|
|
4446
|
-
function insertOrReplaceMemory(db, entry) {
|
|
4447
|
-
const sql = `
|
|
4448
|
-
INSERT OR REPLACE INTO memories (
|
|
4449
|
-
id, title, content, project, type, status, salience, reinforcement,
|
|
4450
|
-
session_id, due_at, expires_at, valid_from, valid_to, data,
|
|
4451
|
-
created_at, updated_at
|
|
4452
|
-
) VALUES (
|
|
4453
|
-
?, ?, ?, ?, ?, ?, ?, ?,
|
|
4454
|
-
?, ?, ?, ?, ?, ?,
|
|
4455
|
-
?, ?
|
|
4456
|
-
)
|
|
4457
|
-
`;
|
|
4458
|
-
db.run(sql, [
|
|
4459
|
-
entry.id,
|
|
4460
|
-
entry.title,
|
|
4461
|
-
entry.content,
|
|
4462
|
-
entry.project,
|
|
4463
|
-
entry.type || "discovery",
|
|
4464
|
-
entry.status,
|
|
4465
|
-
typeof entry.salience === "number" ? entry.salience : null,
|
|
4466
|
-
typeof entry.reinforcement === "number" ? entry.reinforcement : null,
|
|
4467
|
-
entry.session_id ?? null,
|
|
4468
|
-
entry.due_at ?? null,
|
|
4469
|
-
entry.expires_at ?? null,
|
|
4470
|
-
entry.valid_from ?? null,
|
|
4471
|
-
entry.valid_to ?? null,
|
|
4472
|
-
JSON.stringify(entry),
|
|
4473
|
-
entry.created_at,
|
|
4474
|
-
entry.updated_at
|
|
4475
|
-
]);
|
|
4476
|
-
}
|
|
4477
|
-
function getMemoryById(db, id) {
|
|
4478
|
-
const row = db.query(`SELECT * FROM memories WHERE id = ? LIMIT 1`).get([id]);
|
|
4479
|
-
if (!row)
|
|
4480
|
-
return null;
|
|
4481
|
-
return rowToMemoryEntry(row);
|
|
4482
|
-
}
|
|
4483
|
-
function listMemories(db, filters) {
|
|
4484
|
-
let sql = `SELECT * FROM memories`;
|
|
4485
|
-
const conditions = [];
|
|
4486
|
-
const params = [];
|
|
4487
|
-
if (filters?.project) {
|
|
4488
|
-
conditions.push(`project = ?`);
|
|
4489
|
-
params.push(filters.project);
|
|
4490
|
-
}
|
|
4491
|
-
if (filters?.type) {
|
|
4492
|
-
conditions.push(`type = ?`);
|
|
4493
|
-
params.push(filters.type);
|
|
4494
|
-
}
|
|
4495
|
-
if (filters?.status) {
|
|
4496
|
-
conditions.push(`status = ?`);
|
|
4497
|
-
params.push(filters.status);
|
|
4498
|
-
}
|
|
4499
|
-
if (conditions.length > 0) {
|
|
4500
|
-
sql += ` WHERE ` + conditions.join(` AND `);
|
|
4501
|
-
}
|
|
4502
|
-
sql += ` ORDER BY updated_at DESC`;
|
|
4503
|
-
const rows = db.query(sql).all(params.length > 0 ? params : undefined);
|
|
4504
|
-
return rows.map(rowToMemoryEntry);
|
|
4505
|
-
}
|
|
4506
|
-
function deleteMemoryById(db, id) {
|
|
4507
|
-
const existing = getMemoryById(db, id);
|
|
4508
|
-
if (!existing)
|
|
4509
|
-
return false;
|
|
4510
|
-
db.run(`DELETE FROM memories WHERE id = ?`, [id]);
|
|
4511
|
-
return true;
|
|
4512
|
-
}
|
|
4513
|
-
var sqliteDriver = "none";
|
|
4514
|
-
var init_sqlite = () => {};
|
|
4515
|
-
|
|
4516
|
-
// src/transcript.ts
|
|
4517
|
-
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
|
|
4518
|
-
function parseJsonlTranscript(jsonlText) {
|
|
4519
|
-
if (!jsonlText)
|
|
4520
|
-
return [];
|
|
4521
|
-
const lines = jsonlText.split(`
|
|
4522
|
-
`).map((l) => l.trim()).filter(Boolean);
|
|
4523
|
-
const blocks = [];
|
|
4524
|
-
for (const line of lines) {
|
|
4525
|
-
try {
|
|
4526
|
-
const obj = JSON.parse(line);
|
|
4527
|
-
const prevLen = blocks.length;
|
|
4528
|
-
if (typeof obj.content === "string") {
|
|
4529
|
-
blocks.push(obj.content);
|
|
4530
|
-
} else if (Array.isArray(obj.content)) {
|
|
4531
|
-
for (const item of obj.content) {
|
|
4532
|
-
if (typeof item === "string")
|
|
4533
|
-
blocks.push(item);
|
|
4534
|
-
else if (item && typeof item.text === "string")
|
|
4535
|
-
blocks.push(item.text);
|
|
4536
|
-
}
|
|
4537
|
-
}
|
|
4538
|
-
if (typeof obj.thinking === "string") {
|
|
4539
|
-
blocks.push(obj.thinking);
|
|
4540
|
-
}
|
|
4541
|
-
if (typeof obj.message === "string") {
|
|
4542
|
-
blocks.push(obj.message);
|
|
4543
|
-
}
|
|
4544
|
-
if (typeof obj.text === "string") {
|
|
4545
|
-
blocks.push(obj.text);
|
|
4546
|
-
}
|
|
4547
|
-
if (typeof obj.path === "string") {
|
|
4548
|
-
blocks.push(obj.path);
|
|
4549
|
-
}
|
|
4550
|
-
if (obj.tool_calls && Array.isArray(obj.tool_calls)) {
|
|
4551
|
-
for (const tc of obj.tool_calls) {
|
|
4552
|
-
if (tc.arguments && typeof tc.arguments === "string")
|
|
4553
|
-
blocks.push(tc.arguments);
|
|
4554
|
-
}
|
|
4555
|
-
}
|
|
4556
|
-
if (blocks.length === prevLen) {
|
|
4557
|
-
const textParts = Object.values(obj).filter((v) => typeof v === "string").join(" ");
|
|
4558
|
-
blocks.push(textParts.length > 0 ? textParts : line);
|
|
4559
|
-
}
|
|
4560
|
-
} catch {
|
|
4561
|
-
blocks.push(line);
|
|
4562
|
-
}
|
|
4563
|
-
}
|
|
4564
|
-
return blocks;
|
|
4565
|
-
}
|
|
4566
|
-
function searchTranscriptWithBookends(transcriptPathOrContent, query, options = {}) {
|
|
4567
|
-
let content = transcriptPathOrContent;
|
|
4568
|
-
if (existsSync7(transcriptPathOrContent)) {
|
|
4569
|
-
content = readFileSync5(transcriptPathOrContent, "utf8");
|
|
4570
|
-
}
|
|
4571
|
-
const turns = parseJsonlTranscript(content);
|
|
4572
|
-
if (turns.length === 0) {
|
|
4573
|
-
return {
|
|
4574
|
-
totalTurns: 0,
|
|
4575
|
-
bookendStart: "",
|
|
4576
|
-
bookendEnd: "",
|
|
4577
|
-
matches: [],
|
|
4578
|
-
formattedSummary: "No turns found in transcript."
|
|
4579
|
-
};
|
|
4580
|
-
}
|
|
4581
|
-
const windowSize = options.windowSize ?? 2;
|
|
4582
|
-
const maxMatches = options.maxMatches ?? 5;
|
|
4583
|
-
const bookendStart = turns[0] ?? "";
|
|
4584
|
-
const bookendEnd = turns[turns.length - 1] ?? "";
|
|
4585
|
-
const queryTerms = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
4586
|
-
const matches = [];
|
|
4587
|
-
for (let i = 0;i < turns.length; i++) {
|
|
4588
|
-
if (matches.length >= maxMatches)
|
|
4589
|
-
break;
|
|
4590
|
-
const turnLower = turns[i].toLowerCase();
|
|
4591
|
-
const isMatch = queryTerms.length > 0 && queryTerms.every((term) => turnLower.includes(term));
|
|
4592
|
-
if (isMatch) {
|
|
4593
|
-
const before = turns.slice(Math.max(0, i - windowSize), i);
|
|
4594
|
-
const after = turns.slice(i + 1, Math.min(turns.length, i + 1 + windowSize));
|
|
4595
|
-
matches.push({
|
|
4596
|
-
index: i,
|
|
4597
|
-
matchedTurn: turns[i],
|
|
4598
|
-
before,
|
|
4599
|
-
after
|
|
4600
|
-
});
|
|
4601
|
-
}
|
|
4602
|
-
}
|
|
4603
|
-
const lines = [];
|
|
4604
|
-
lines.push(`### Conversation Overview (${turns.length} total turns)`);
|
|
4605
|
-
lines.push(`**[Start Bookend]**: ${bookendStart.slice(0, 200).replace(/\n+/g, " ")}`);
|
|
4606
|
-
lines.push(`**[End Bookend]**: ${bookendEnd.slice(0, 200).replace(/\n+/g, " ")}`);
|
|
4607
|
-
lines.push("");
|
|
4608
|
-
if (matches.length === 0) {
|
|
4609
|
-
lines.push(`*No matches found for query "${query}".*`);
|
|
4610
|
-
} else {
|
|
4611
|
-
lines.push(`### Matches for "${query}" (${matches.length} found):`);
|
|
4612
|
-
matches.forEach((m, idx) => {
|
|
4613
|
-
lines.push(`
|
|
4614
|
-
#### Match ${idx + 1} (Turn ${m.index + 1})`);
|
|
4615
|
-
if (m.before.length > 0) {
|
|
4616
|
-
lines.push(`*Context Before:*`);
|
|
4617
|
-
m.before.forEach((b) => lines.push(`> ${b.slice(0, 150).replace(/\n+/g, " ")}`));
|
|
4618
|
-
}
|
|
4619
|
-
lines.push(`**Matched Turn:**
|
|
4620
|
-
${m.matchedTurn}`);
|
|
4621
|
-
if (m.after.length > 0) {
|
|
4622
|
-
lines.push(`*Context After:*`);
|
|
4623
|
-
m.after.forEach((a) => lines.push(`> ${a.slice(0, 150).replace(/\n+/g, " ")}`));
|
|
4624
|
-
}
|
|
4625
|
-
});
|
|
4527
|
+
lines.push(`**Matched Turn:**
|
|
4528
|
+
${m.matchedTurn}`);
|
|
4529
|
+
if (m.after.length > 0) {
|
|
4530
|
+
lines.push(`*Context After:*`);
|
|
4531
|
+
m.after.forEach((a) => lines.push(`> ${a.slice(0, 150).replace(/\n+/g, " ")}`));
|
|
4532
|
+
}
|
|
4533
|
+
});
|
|
4626
4534
|
}
|
|
4627
4535
|
return {
|
|
4628
4536
|
totalTurns: turns.length,
|
|
@@ -4636,15 +4544,7 @@ ${m.matchedTurn}`);
|
|
|
4636
4544
|
var init_transcript = () => {};
|
|
4637
4545
|
|
|
4638
4546
|
// src/harvest.ts
|
|
4639
|
-
|
|
4640
|
-
__export(exports_harvest, {
|
|
4641
|
-
defaultSalienceForType: () => defaultSalienceForType,
|
|
4642
|
-
extractCommitments: () => extractCommitments,
|
|
4643
|
-
extractHarvestUnits: () => extractHarvestUnits,
|
|
4644
|
-
importTranscript: () => importTranscript,
|
|
4645
|
-
openLoopId: () => openLoopId
|
|
4646
|
-
});
|
|
4647
|
-
import { existsSync as existsSync8, readFileSync as readFileSync6 } from "node:fs";
|
|
4547
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6 } from "node:fs";
|
|
4648
4548
|
import { createHash } from "node:crypto";
|
|
4649
4549
|
function extractHarvestUnits(text) {
|
|
4650
4550
|
if (!text || typeof text !== "string")
|
|
@@ -4773,115 +4673,551 @@ function extractCommitments(text) {
|
|
|
4773
4673
|
}
|
|
4774
4674
|
return out;
|
|
4775
4675
|
}
|
|
4776
|
-
function openLoopId(text) {
|
|
4777
|
-
const h = createHash("sha256").update(text.toLowerCase().replace(/\s+/g, " ").trim()).digest("hex");
|
|
4778
|
-
return `m_0_ol${h.slice(0, 12)}`;
|
|
4676
|
+
function openLoopId(text) {
|
|
4677
|
+
const h = createHash("sha256").update(text.toLowerCase().replace(/\s+/g, " ").trim()).digest("hex");
|
|
4678
|
+
return `m_0_ol${h.slice(0, 12)}`;
|
|
4679
|
+
}
|
|
4680
|
+
function importTranscript(store, transcriptPathOrContent, options = {}) {
|
|
4681
|
+
let content = transcriptPathOrContent;
|
|
4682
|
+
if (existsSync7(transcriptPathOrContent)) {
|
|
4683
|
+
content = readFileSync6(transcriptPathOrContent, "utf8");
|
|
4684
|
+
}
|
|
4685
|
+
const blocks = parseJsonlTranscript(content);
|
|
4686
|
+
const fullText = blocks.join(`
|
|
4687
|
+
|
|
4688
|
+
`);
|
|
4689
|
+
const units = extractHarvestUnits(fullText);
|
|
4690
|
+
const project = options.project ?? "default";
|
|
4691
|
+
const entries = [];
|
|
4692
|
+
const errors = [];
|
|
4693
|
+
for (const unit of units) {
|
|
4694
|
+
try {
|
|
4695
|
+
const entry = propose(store, {
|
|
4696
|
+
project,
|
|
4697
|
+
title: unit.title,
|
|
4698
|
+
content: unit.content,
|
|
4699
|
+
type: unit.type,
|
|
4700
|
+
tags: unit.tags,
|
|
4701
|
+
source: options.source ?? "transcript_import",
|
|
4702
|
+
confirmed: options.confirmed ?? false
|
|
4703
|
+
});
|
|
4704
|
+
if (options.sessionId) {
|
|
4705
|
+
entry.session_id = options.sessionId;
|
|
4706
|
+
save(store, entry);
|
|
4707
|
+
}
|
|
4708
|
+
entries.push(entry);
|
|
4709
|
+
} catch (err) {
|
|
4710
|
+
errors.push(`Failed to import unit "${unit.title}": ${err instanceof Error ? err.message : String(err)}`);
|
|
4711
|
+
}
|
|
4712
|
+
}
|
|
4713
|
+
const openLoops = [];
|
|
4714
|
+
if (options.openLoops !== false) {
|
|
4715
|
+
const existing = new Set(list(store).map((e) => e.id));
|
|
4716
|
+
for (const commitment of extractCommitments(fullText)) {
|
|
4717
|
+
const id = openLoopId(commitment);
|
|
4718
|
+
if (existing.has(id))
|
|
4719
|
+
continue;
|
|
4720
|
+
try {
|
|
4721
|
+
const entry = propose(store, {
|
|
4722
|
+
id,
|
|
4723
|
+
project,
|
|
4724
|
+
title: commitment.slice(0, 80),
|
|
4725
|
+
content: commitment,
|
|
4726
|
+
type: "operation",
|
|
4727
|
+
tags: ["open-loop", "harvested"],
|
|
4728
|
+
source: options.source ?? "transcript_import"
|
|
4729
|
+
});
|
|
4730
|
+
if (options.sessionId) {
|
|
4731
|
+
entry.session_id = options.sessionId;
|
|
4732
|
+
save(store, entry);
|
|
4733
|
+
}
|
|
4734
|
+
existing.add(id);
|
|
4735
|
+
openLoops.push(entry);
|
|
4736
|
+
} catch (err) {
|
|
4737
|
+
errors.push(`Failed to record open loop "${commitment}": ${err instanceof Error ? err.message : String(err)}`);
|
|
4738
|
+
}
|
|
4739
|
+
}
|
|
4740
|
+
}
|
|
4741
|
+
return {
|
|
4742
|
+
imported: entries.length,
|
|
4743
|
+
entries,
|
|
4744
|
+
errors,
|
|
4745
|
+
openLoops
|
|
4746
|
+
};
|
|
4747
|
+
}
|
|
4748
|
+
var COMMITMENT_PATTERNS;
|
|
4749
|
+
var init_harvest = __esm(() => {
|
|
4750
|
+
init_store();
|
|
4751
|
+
init_transcript();
|
|
4752
|
+
COMMITMENT_PATTERNS = [
|
|
4753
|
+
/\btodo\b\s*[:\-]\s*(.{4,})/i,
|
|
4754
|
+
/\b(?:i'll|i will|i am going to)\s+(.{4,})/i,
|
|
4755
|
+
/\bneed to\s+(.{4,})/i,
|
|
4756
|
+
/\bfollow up (?:on|with)\s+(.{4,})/i,
|
|
4757
|
+
/\bremind me to\s+(.{4,})/i
|
|
4758
|
+
];
|
|
4759
|
+
});
|
|
4760
|
+
|
|
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
|
+
// src/sqlite.ts
|
|
4966
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync6 } from "node:fs";
|
|
4967
|
+
import { dirname } from "node:path";
|
|
4968
|
+
function getDriver() {
|
|
4969
|
+
if (sqliteDriver !== "none")
|
|
4970
|
+
return sqliteDriver;
|
|
4971
|
+
try {
|
|
4972
|
+
if (typeof globalThis.Bun !== "undefined") {
|
|
4973
|
+
sqliteDriver = "bun";
|
|
4974
|
+
return "bun";
|
|
4975
|
+
}
|
|
4976
|
+
} catch {}
|
|
4977
|
+
try {
|
|
4978
|
+
__require("node:sqlite");
|
|
4979
|
+
sqliteDriver = "node";
|
|
4980
|
+
return "node";
|
|
4981
|
+
} catch {}
|
|
4982
|
+
sqliteDriver = "bun";
|
|
4983
|
+
return "bun";
|
|
4984
|
+
}
|
|
4985
|
+
function openDatabase(dbPath) {
|
|
4986
|
+
const dir = dirname(dbPath);
|
|
4987
|
+
if (!existsSync9(dir)) {
|
|
4988
|
+
mkdirSync6(dir, { recursive: true });
|
|
4989
|
+
}
|
|
4990
|
+
const driver = getDriver();
|
|
4991
|
+
let rawDb;
|
|
4992
|
+
if (driver === "bun") {
|
|
4993
|
+
const { Database } = __require("bun:sqlite");
|
|
4994
|
+
rawDb = new Database(dbPath, { create: true });
|
|
4995
|
+
rawDb.run("PRAGMA journal_mode = WAL;");
|
|
4996
|
+
rawDb.run("PRAGMA synchronous = NORMAL;");
|
|
4997
|
+
const db = {
|
|
4998
|
+
exec(sql) {
|
|
4999
|
+
rawDb.exec(sql);
|
|
5000
|
+
},
|
|
5001
|
+
run(sql, params) {
|
|
5002
|
+
if (params && Array.isArray(params)) {
|
|
5003
|
+
rawDb.run(sql, params);
|
|
5004
|
+
} else if (params && typeof params === "object") {
|
|
5005
|
+
rawDb.run(sql, params);
|
|
5006
|
+
} else {
|
|
5007
|
+
rawDb.run(sql);
|
|
5008
|
+
}
|
|
5009
|
+
},
|
|
5010
|
+
query(sql) {
|
|
5011
|
+
const stmt = rawDb.query(sql);
|
|
5012
|
+
return {
|
|
5013
|
+
all(params) {
|
|
5014
|
+
return params ? stmt.all(params) : stmt.all();
|
|
5015
|
+
},
|
|
5016
|
+
get(params) {
|
|
5017
|
+
return params ? stmt.get(params) : stmt.get();
|
|
5018
|
+
}
|
|
5019
|
+
};
|
|
5020
|
+
},
|
|
5021
|
+
close() {
|
|
5022
|
+
rawDb.close();
|
|
5023
|
+
}
|
|
5024
|
+
};
|
|
5025
|
+
initSchema(db);
|
|
5026
|
+
return db;
|
|
5027
|
+
} else {
|
|
5028
|
+
const { DatabaseSync } = __require("node:sqlite");
|
|
5029
|
+
rawDb = new DatabaseSync(dbPath);
|
|
5030
|
+
rawDb.exec("PRAGMA journal_mode = WAL;");
|
|
5031
|
+
rawDb.exec("PRAGMA synchronous = NORMAL;");
|
|
5032
|
+
const db = {
|
|
5033
|
+
exec(sql) {
|
|
5034
|
+
rawDb.exec(sql);
|
|
5035
|
+
},
|
|
5036
|
+
run(sql, params) {
|
|
5037
|
+
const stmt = rawDb.prepare(sql);
|
|
5038
|
+
if (params && Array.isArray(params)) {
|
|
5039
|
+
stmt.run(...params);
|
|
5040
|
+
} else if (params && typeof params === "object") {
|
|
5041
|
+
stmt.run(params);
|
|
5042
|
+
} else {
|
|
5043
|
+
stmt.run();
|
|
5044
|
+
}
|
|
5045
|
+
},
|
|
5046
|
+
query(sql) {
|
|
5047
|
+
const stmt = rawDb.prepare(sql);
|
|
5048
|
+
return {
|
|
5049
|
+
all(params) {
|
|
5050
|
+
if (params && Array.isArray(params))
|
|
5051
|
+
return stmt.all(...params);
|
|
5052
|
+
if (params && typeof params === "object")
|
|
5053
|
+
return stmt.all(params);
|
|
5054
|
+
return stmt.all();
|
|
5055
|
+
},
|
|
5056
|
+
get(params) {
|
|
5057
|
+
if (params && Array.isArray(params))
|
|
5058
|
+
return stmt.get(...params);
|
|
5059
|
+
if (params && typeof params === "object")
|
|
5060
|
+
return stmt.get(params);
|
|
5061
|
+
return stmt.get();
|
|
5062
|
+
}
|
|
5063
|
+
};
|
|
5064
|
+
},
|
|
5065
|
+
close() {
|
|
5066
|
+
rawDb.close();
|
|
5067
|
+
}
|
|
5068
|
+
};
|
|
5069
|
+
initSchema(db);
|
|
5070
|
+
return db;
|
|
5071
|
+
}
|
|
5072
|
+
}
|
|
5073
|
+
function initSchema(db) {
|
|
5074
|
+
db.exec(`
|
|
5075
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
5076
|
+
id TEXT PRIMARY KEY,
|
|
5077
|
+
title TEXT NOT NULL,
|
|
5078
|
+
content TEXT NOT NULL,
|
|
5079
|
+
project TEXT NOT NULL,
|
|
5080
|
+
type TEXT NOT NULL,
|
|
5081
|
+
status TEXT NOT NULL,
|
|
5082
|
+
salience REAL,
|
|
5083
|
+
reinforcement INTEGER,
|
|
5084
|
+
session_id TEXT,
|
|
5085
|
+
due_at TEXT,
|
|
5086
|
+
expires_at TEXT,
|
|
5087
|
+
valid_from TEXT,
|
|
5088
|
+
valid_to TEXT,
|
|
5089
|
+
data TEXT NOT NULL,
|
|
5090
|
+
created_at TEXT NOT NULL,
|
|
5091
|
+
updated_at TEXT NOT NULL
|
|
5092
|
+
);
|
|
5093
|
+
|
|
5094
|
+
CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project);
|
|
5095
|
+
CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
|
|
5096
|
+
CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status);
|
|
5097
|
+
CREATE INDEX IF NOT EXISTS idx_memories_session_id ON memories(session_id);
|
|
5098
|
+
CREATE INDEX IF NOT EXISTS idx_memories_due_at ON memories(due_at);
|
|
5099
|
+
CREATE INDEX IF NOT EXISTS idx_memories_updated_at ON memories(updated_at);
|
|
5100
|
+
`);
|
|
5101
|
+
}
|
|
5102
|
+
function rowToMemoryEntry(row) {
|
|
5103
|
+
let parsedData = {};
|
|
5104
|
+
try {
|
|
5105
|
+
parsedData = JSON.parse(row.data);
|
|
5106
|
+
} catch {}
|
|
5107
|
+
return {
|
|
5108
|
+
...parsedData,
|
|
5109
|
+
id: row.id,
|
|
5110
|
+
title: row.title,
|
|
5111
|
+
content: row.content,
|
|
5112
|
+
project: row.project,
|
|
5113
|
+
type: row.type,
|
|
5114
|
+
status: row.status,
|
|
5115
|
+
salience: row.salience !== null ? row.salience : parsedData.salience,
|
|
5116
|
+
reinforcement: row.reinforcement !== null ? row.reinforcement : parsedData.reinforcement,
|
|
5117
|
+
session_id: row.session_id !== null ? row.session_id : parsedData.session_id,
|
|
5118
|
+
due_at: row.due_at !== null ? row.due_at : parsedData.due_at,
|
|
5119
|
+
expires_at: row.expires_at !== null ? row.expires_at : parsedData.expires_at,
|
|
5120
|
+
valid_from: row.valid_from !== null ? row.valid_from : parsedData.valid_from,
|
|
5121
|
+
valid_to: row.valid_to !== null ? row.valid_to : parsedData.valid_to,
|
|
5122
|
+
created_at: row.created_at || parsedData.created_at || new Date().toISOString(),
|
|
5123
|
+
updated_at: row.updated_at || parsedData.updated_at || new Date().toISOString()
|
|
5124
|
+
};
|
|
5125
|
+
}
|
|
5126
|
+
function insertOrReplaceMemory(db, entry) {
|
|
5127
|
+
const sql = `
|
|
5128
|
+
INSERT OR REPLACE INTO memories (
|
|
5129
|
+
id, title, content, project, type, status, salience, reinforcement,
|
|
5130
|
+
session_id, due_at, expires_at, valid_from, valid_to, data,
|
|
5131
|
+
created_at, updated_at
|
|
5132
|
+
) VALUES (
|
|
5133
|
+
?, ?, ?, ?, ?, ?, ?, ?,
|
|
5134
|
+
?, ?, ?, ?, ?, ?,
|
|
5135
|
+
?, ?
|
|
5136
|
+
)
|
|
5137
|
+
`;
|
|
5138
|
+
db.run(sql, [
|
|
5139
|
+
entry.id,
|
|
5140
|
+
entry.title,
|
|
5141
|
+
entry.content,
|
|
5142
|
+
entry.project,
|
|
5143
|
+
entry.type || "discovery",
|
|
5144
|
+
entry.status,
|
|
5145
|
+
typeof entry.salience === "number" ? entry.salience : null,
|
|
5146
|
+
typeof entry.reinforcement === "number" ? entry.reinforcement : null,
|
|
5147
|
+
entry.session_id ?? null,
|
|
5148
|
+
entry.due_at ?? null,
|
|
5149
|
+
entry.expires_at ?? null,
|
|
5150
|
+
entry.valid_from ?? null,
|
|
5151
|
+
entry.valid_to ?? null,
|
|
5152
|
+
JSON.stringify(entry),
|
|
5153
|
+
entry.created_at,
|
|
5154
|
+
entry.updated_at
|
|
5155
|
+
]);
|
|
4779
5156
|
}
|
|
4780
|
-
function
|
|
4781
|
-
|
|
4782
|
-
if (
|
|
4783
|
-
|
|
5157
|
+
function getMemoryById(db, id) {
|
|
5158
|
+
const row = db.query(`SELECT * FROM memories WHERE id = ? LIMIT 1`).get([id]);
|
|
5159
|
+
if (!row)
|
|
5160
|
+
return null;
|
|
5161
|
+
return rowToMemoryEntry(row);
|
|
5162
|
+
}
|
|
5163
|
+
function listMemories(db, filters) {
|
|
5164
|
+
let sql = `SELECT * FROM memories`;
|
|
5165
|
+
const conditions = [];
|
|
5166
|
+
const params = [];
|
|
5167
|
+
if (filters?.project) {
|
|
5168
|
+
conditions.push(`project = ?`);
|
|
5169
|
+
params.push(filters.project);
|
|
4784
5170
|
}
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
`);
|
|
4789
|
-
const units = extractHarvestUnits(fullText);
|
|
4790
|
-
const project = options.project ?? "default";
|
|
4791
|
-
const entries = [];
|
|
4792
|
-
const errors = [];
|
|
4793
|
-
for (const unit of units) {
|
|
4794
|
-
try {
|
|
4795
|
-
const entry = propose(store, {
|
|
4796
|
-
project,
|
|
4797
|
-
title: unit.title,
|
|
4798
|
-
content: unit.content,
|
|
4799
|
-
type: unit.type,
|
|
4800
|
-
tags: unit.tags,
|
|
4801
|
-
source: options.source ?? "transcript_import",
|
|
4802
|
-
confirmed: options.confirmed ?? false
|
|
4803
|
-
});
|
|
4804
|
-
if (options.sessionId) {
|
|
4805
|
-
entry.session_id = options.sessionId;
|
|
4806
|
-
save(store, entry);
|
|
4807
|
-
}
|
|
4808
|
-
entries.push(entry);
|
|
4809
|
-
} catch (err) {
|
|
4810
|
-
errors.push(`Failed to import unit "${unit.title}": ${err instanceof Error ? err.message : String(err)}`);
|
|
4811
|
-
}
|
|
5171
|
+
if (filters?.type) {
|
|
5172
|
+
conditions.push(`type = ?`);
|
|
5173
|
+
params.push(filters.type);
|
|
4812
5174
|
}
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
for (const commitment of extractCommitments(fullText)) {
|
|
4817
|
-
const id = openLoopId(commitment);
|
|
4818
|
-
if (existing.has(id))
|
|
4819
|
-
continue;
|
|
4820
|
-
try {
|
|
4821
|
-
const entry = propose(store, {
|
|
4822
|
-
id,
|
|
4823
|
-
project,
|
|
4824
|
-
title: commitment.slice(0, 80),
|
|
4825
|
-
content: commitment,
|
|
4826
|
-
type: "operation",
|
|
4827
|
-
tags: ["open-loop", "harvested"],
|
|
4828
|
-
source: options.source ?? "transcript_import"
|
|
4829
|
-
});
|
|
4830
|
-
if (options.sessionId) {
|
|
4831
|
-
entry.session_id = options.sessionId;
|
|
4832
|
-
save(store, entry);
|
|
4833
|
-
}
|
|
4834
|
-
existing.add(id);
|
|
4835
|
-
openLoops.push(entry);
|
|
4836
|
-
} catch (err) {
|
|
4837
|
-
errors.push(`Failed to record open loop "${commitment}": ${err instanceof Error ? err.message : String(err)}`);
|
|
4838
|
-
}
|
|
4839
|
-
}
|
|
5175
|
+
if (filters?.status) {
|
|
5176
|
+
conditions.push(`status = ?`);
|
|
5177
|
+
params.push(filters.status);
|
|
4840
5178
|
}
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
5179
|
+
if (conditions.length > 0) {
|
|
5180
|
+
sql += ` WHERE ` + conditions.join(` AND `);
|
|
5181
|
+
}
|
|
5182
|
+
sql += ` ORDER BY updated_at DESC`;
|
|
5183
|
+
const rows = db.query(sql).all(params.length > 0 ? params : undefined);
|
|
5184
|
+
return rows.map(rowToMemoryEntry);
|
|
4847
5185
|
}
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
/\bremind me to\s+(.{4,})/i
|
|
4858
|
-
];
|
|
4859
|
-
});
|
|
5186
|
+
function deleteMemoryById(db, id) {
|
|
5187
|
+
const existing = getMemoryById(db, id);
|
|
5188
|
+
if (!existing)
|
|
5189
|
+
return false;
|
|
5190
|
+
db.run(`DELETE FROM memories WHERE id = ?`, [id]);
|
|
5191
|
+
return true;
|
|
5192
|
+
}
|
|
5193
|
+
var sqliteDriver = "none";
|
|
5194
|
+
var init_sqlite = () => {};
|
|
4860
5195
|
|
|
4861
5196
|
// src/store.ts
|
|
4862
|
-
import {
|
|
4863
|
-
import {
|
|
5197
|
+
import { resolve } from "node:path";
|
|
5198
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync5, renameSync, unlinkSync, mkdirSync as mkdirSync7, existsSync as existsSync10 } from "node:fs";
|
|
5199
|
+
import { join as join7 } from "node:path";
|
|
4864
5200
|
function getStorageLayout(memoryDir) {
|
|
4865
5201
|
return {
|
|
4866
5202
|
root: workspaceRootFor(memoryDir),
|
|
4867
5203
|
memoryDir,
|
|
4868
|
-
memoriesDir:
|
|
4869
|
-
dbPath:
|
|
4870
|
-
currentMd:
|
|
4871
|
-
userMd:
|
|
4872
|
-
auditJsonl:
|
|
5204
|
+
memoriesDir: join7(memoryDir, "memories"),
|
|
5205
|
+
dbPath: join7(memoryDir, "memory.db"),
|
|
5206
|
+
currentMd: join7(memoryDir, "CURRENT.md"),
|
|
5207
|
+
userMd: join7(memoryDir, "USER.md"),
|
|
5208
|
+
auditJsonl: join7(memoryDir, "audit.jsonl")
|
|
4873
5209
|
};
|
|
4874
5210
|
}
|
|
4875
5211
|
function openStore(memoryDir) {
|
|
4876
5212
|
const layout = getStorageLayout(memoryDir);
|
|
4877
|
-
|
|
4878
|
-
|
|
5213
|
+
mkdirSync7(layout.memoriesDir, { recursive: true });
|
|
5214
|
+
mkdirSync7(memoryDir, { recursive: true });
|
|
4879
5215
|
let db;
|
|
4880
5216
|
try {
|
|
4881
5217
|
db = openDatabase(layout.dbPath);
|
|
4882
5218
|
} catch (err) {}
|
|
4883
5219
|
const store = { dir: layout.memoriesDir, memoryDir, layout, db };
|
|
4884
|
-
if (db &&
|
|
5220
|
+
if (db && existsSync10(layout.memoriesDir)) {
|
|
4885
5221
|
try {
|
|
4886
5222
|
const yamlIds = listIds(store);
|
|
4887
5223
|
for (const yId of yamlIds) {
|
|
@@ -4898,7 +5234,6 @@ function openStore(memoryDir) {
|
|
|
4898
5234
|
syncConstraints(memoryDir, store);
|
|
4899
5235
|
} catch {}
|
|
4900
5236
|
try {
|
|
4901
|
-
const { autoCompileWiki } = (init_wiki(), __toCommonJS(exports_wiki));
|
|
4902
5237
|
autoCompileWiki(store, memoryDir);
|
|
4903
5238
|
} catch {}
|
|
4904
5239
|
return store;
|
|
@@ -4919,7 +5254,13 @@ function slugifyId(id) {
|
|
|
4919
5254
|
return slug.length > 0 ? slug : "entry";
|
|
4920
5255
|
}
|
|
4921
5256
|
function fileForId(store, id) {
|
|
4922
|
-
|
|
5257
|
+
const safeFilename = `${slugifyId(id)}.yaml`;
|
|
5258
|
+
const target = resolve(store.dir, safeFilename);
|
|
5259
|
+
const base = resolve(store.dir);
|
|
5260
|
+
if (!target.startsWith(base)) {
|
|
5261
|
+
throw new Error(`Security Violation: Path traversal detected for id "${id}"`);
|
|
5262
|
+
}
|
|
5263
|
+
return target;
|
|
4923
5264
|
}
|
|
4924
5265
|
function listIds(store) {
|
|
4925
5266
|
const ids = new Set;
|
|
@@ -4928,8 +5269,8 @@ function listIds(store) {
|
|
|
4928
5269
|
ids.add(e.id);
|
|
4929
5270
|
}
|
|
4930
5271
|
}
|
|
4931
|
-
if (
|
|
4932
|
-
for (const f of
|
|
5272
|
+
if (existsSync10(store.dir)) {
|
|
5273
|
+
for (const f of readdirSync2(store.dir)) {
|
|
4933
5274
|
if (f.endsWith(".yaml")) {
|
|
4934
5275
|
ids.add(f.slice(0, -5));
|
|
4935
5276
|
}
|
|
@@ -4939,10 +5280,10 @@ function listIds(store) {
|
|
|
4939
5280
|
}
|
|
4940
5281
|
function getFromYaml(store, id) {
|
|
4941
5282
|
const file = fileForId(store, id);
|
|
4942
|
-
if (!
|
|
5283
|
+
if (!existsSync10(file))
|
|
4943
5284
|
return null;
|
|
4944
5285
|
try {
|
|
4945
|
-
const raw =
|
|
5286
|
+
const raw = readFileSync8(file, "utf8");
|
|
4946
5287
|
const parsed = yaml.load(raw, { schema: yaml.JSON_SCHEMA });
|
|
4947
5288
|
if (!parsed || typeof parsed !== "object")
|
|
4948
5289
|
return null;
|
|
@@ -4953,7 +5294,7 @@ function getFromYaml(store, id) {
|
|
|
4953
5294
|
}
|
|
4954
5295
|
function get2(store, id) {
|
|
4955
5296
|
const file = fileForId(store, id);
|
|
4956
|
-
if (
|
|
5297
|
+
if (existsSync10(file)) {
|
|
4957
5298
|
const fromYaml = getFromYaml(store, id);
|
|
4958
5299
|
if (!fromYaml) {
|
|
4959
5300
|
return null;
|
|
@@ -5003,7 +5344,7 @@ function save(store, entry, options = {}) {
|
|
|
5003
5344
|
try {
|
|
5004
5345
|
const file = fileForId(store, entry.id);
|
|
5005
5346
|
const tmp = `${file}.tmp`;
|
|
5006
|
-
|
|
5347
|
+
writeFileSync5(tmp, yaml.dump(entry, { lineWidth: 120 }), "utf8");
|
|
5007
5348
|
renameSync(tmp, file);
|
|
5008
5349
|
} catch {}
|
|
5009
5350
|
}
|
|
@@ -5060,7 +5401,8 @@ function propose(store, opts) {
|
|
|
5060
5401
|
due_at: opts.dueAt ?? opts.due_at,
|
|
5061
5402
|
expires_at: opts.expiresAt ?? opts.expires_at,
|
|
5062
5403
|
test_command: opts.test_command,
|
|
5063
|
-
verification: opts.verification ?? (opts.confirmed ? { level: "user-confirmed", verified_at: now } : { level: "unverified" })
|
|
5404
|
+
verification: opts.verification ?? (opts.confirmed ? { level: "user-confirmed", verified_at: now } : { level: "unverified" }),
|
|
5405
|
+
graph: opts.graph ?? (store.memoryDir ? autoStampGraphMetadata(`${opts.title ?? ""} ${opts.content}`, store.memoryDir) : undefined)
|
|
5064
5406
|
};
|
|
5065
5407
|
if (opts.confirmed)
|
|
5066
5408
|
entry.last_confirmed_at = now;
|
|
@@ -5269,7 +5611,7 @@ function deleteEntry(store, id, reason, actor) {
|
|
|
5269
5611
|
deleted = deleteMemoryById(store.db, id) || deleted;
|
|
5270
5612
|
}
|
|
5271
5613
|
const file = fileForId(store, id);
|
|
5272
|
-
if (
|
|
5614
|
+
if (existsSync10(file)) {
|
|
5273
5615
|
unlinkSync(file);
|
|
5274
5616
|
deleted = true;
|
|
5275
5617
|
}
|
|
@@ -5290,8 +5632,7 @@ function deleteEntry(store, id, reason, actor) {
|
|
|
5290
5632
|
return deleted;
|
|
5291
5633
|
}
|
|
5292
5634
|
function harvestMemories(store, params) {
|
|
5293
|
-
const
|
|
5294
|
-
const units = extractHarvestUnits2(params.text);
|
|
5635
|
+
const units = extractHarvestUnits(params.text);
|
|
5295
5636
|
const created = [];
|
|
5296
5637
|
for (const u of units) {
|
|
5297
5638
|
try {
|
|
@@ -5313,6 +5654,9 @@ var init_store = __esm(() => {
|
|
|
5313
5654
|
init_secrets();
|
|
5314
5655
|
init_audit();
|
|
5315
5656
|
init_current();
|
|
5657
|
+
init_compiler();
|
|
5658
|
+
init_harvest();
|
|
5659
|
+
init_graph();
|
|
5316
5660
|
init_root();
|
|
5317
5661
|
init_sqlite();
|
|
5318
5662
|
});
|
|
@@ -5412,8 +5756,8 @@ var init_cluster = __esm(() => {
|
|
|
5412
5756
|
});
|
|
5413
5757
|
|
|
5414
5758
|
// src/entities/extractor.ts
|
|
5415
|
-
import { existsSync as
|
|
5416
|
-
import { join as
|
|
5759
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
5760
|
+
import { join as join8 } from "node:path";
|
|
5417
5761
|
function slugify(text) {
|
|
5418
5762
|
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
|
|
5419
5763
|
}
|
|
@@ -5622,17 +5966,17 @@ function extractEntitiesFromText(text, config = {}) {
|
|
|
5622
5966
|
return results;
|
|
5623
5967
|
}
|
|
5624
5968
|
function saveEntities(memoryDir, data) {
|
|
5625
|
-
const filePath =
|
|
5626
|
-
|
|
5969
|
+
const filePath = join8(memoryDir, "entities.json");
|
|
5970
|
+
mkdirSync8(memoryDir, { recursive: true });
|
|
5627
5971
|
const entities = Array.isArray(data) ? data : data.entities;
|
|
5628
|
-
|
|
5972
|
+
writeFileSync6(filePath, JSON.stringify(entities, null, 2), "utf8");
|
|
5629
5973
|
}
|
|
5630
5974
|
function loadEntities(memoryDir) {
|
|
5631
|
-
const filePath =
|
|
5632
|
-
if (!
|
|
5975
|
+
const filePath = join8(memoryDir, "entities.json");
|
|
5976
|
+
if (!existsSync11(filePath))
|
|
5633
5977
|
return [];
|
|
5634
5978
|
try {
|
|
5635
|
-
return JSON.parse(
|
|
5979
|
+
return JSON.parse(readFileSync9(filePath, "utf8"));
|
|
5636
5980
|
} catch {
|
|
5637
5981
|
return [];
|
|
5638
5982
|
}
|
|
@@ -5640,7 +5984,15 @@ function loadEntities(memoryDir) {
|
|
|
5640
5984
|
function findEntity(memoryDir, id) {
|
|
5641
5985
|
const entities = loadEntities(memoryDir);
|
|
5642
5986
|
const cleanId = slugify(id);
|
|
5643
|
-
|
|
5987
|
+
const alphanumericId = id.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
5988
|
+
return entities.find((e) => {
|
|
5989
|
+
if (e.id === cleanId || e.name.toLowerCase() === id.toLowerCase())
|
|
5990
|
+
return true;
|
|
5991
|
+
if (slugify(e.name) === cleanId)
|
|
5992
|
+
return true;
|
|
5993
|
+
const alphaE = e.id.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
5994
|
+
return alphaE.length > 0 && alphaE === alphanumericId;
|
|
5995
|
+
}) ?? null;
|
|
5644
5996
|
}
|
|
5645
5997
|
function findRelatedEntities(memoryDir, id) {
|
|
5646
5998
|
const entities = loadEntities(memoryDir);
|
|
@@ -5826,8 +6178,8 @@ ${entries}
|
|
|
5826
6178
|
}
|
|
5827
6179
|
|
|
5828
6180
|
// src/wiki/compiler.ts
|
|
5829
|
-
import { existsSync as
|
|
5830
|
-
import { join as
|
|
6181
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync9, writeFileSync as writeFileSync7, readFileSync as readFileSync10, readdirSync as readdirSync3 } from "node:fs";
|
|
6182
|
+
import { join as join9 } from "node:path";
|
|
5831
6183
|
function compileWiki(store, memoryDir, options = {}) {
|
|
5832
6184
|
const project = options.project;
|
|
5833
6185
|
const dryRun = options.dryRun ?? false;
|
|
@@ -5851,12 +6203,12 @@ function compileWiki(store, memoryDir, options = {}) {
|
|
|
5851
6203
|
}
|
|
5852
6204
|
}
|
|
5853
6205
|
const memories = project ? allMemories.filter((e) => e.project === project) : allMemories;
|
|
5854
|
-
const wikiDir =
|
|
5855
|
-
const conceptsDir =
|
|
5856
|
-
const entitiesDir =
|
|
6206
|
+
const wikiDir = join9(memoryDir, "wiki");
|
|
6207
|
+
const conceptsDir = join9(wikiDir, "concepts");
|
|
6208
|
+
const entitiesDir = join9(wikiDir, "entities");
|
|
5857
6209
|
if (!dryRun) {
|
|
5858
|
-
|
|
5859
|
-
|
|
6210
|
+
mkdirSync9(conceptsDir, { recursive: true });
|
|
6211
|
+
mkdirSync9(entitiesDir, { recursive: true });
|
|
5860
6212
|
}
|
|
5861
6213
|
const result = { pagesCreated: [], pagesUpdated: [], logEntries: [], errors: [] };
|
|
5862
6214
|
const existingConcepts = loadExistingConcepts(conceptsDir);
|
|
@@ -6101,55 +6453,74 @@ function buildLogPage(logEntries) {
|
|
|
6101
6453
|
entries: logEntries
|
|
6102
6454
|
};
|
|
6103
6455
|
}
|
|
6456
|
+
function stripFrontmatter(content) {
|
|
6457
|
+
const match = content.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/);
|
|
6458
|
+
if (!match)
|
|
6459
|
+
return content;
|
|
6460
|
+
return content.slice(match[0].length);
|
|
6461
|
+
}
|
|
6104
6462
|
function loadExistingConcepts(dir) {
|
|
6105
6463
|
const map2 = new Map;
|
|
6106
|
-
if (!
|
|
6464
|
+
if (!existsSync12(dir))
|
|
6107
6465
|
return map2;
|
|
6108
|
-
for (const file of
|
|
6466
|
+
for (const file of readdirSync3(dir)) {
|
|
6109
6467
|
if (!file.endsWith(".md"))
|
|
6110
6468
|
continue;
|
|
6111
6469
|
const slug = file.slice(0, -3);
|
|
6112
6470
|
try {
|
|
6113
|
-
const content =
|
|
6471
|
+
const content = readFileSync10(join9(dir, file), "utf8");
|
|
6114
6472
|
const frontmatter = parseFrontmatter(content);
|
|
6115
|
-
map2.set(slug, { ...frontmatter, slug, content:
|
|
6116
|
-
---
|
|
6117
|
-
`) + 5) });
|
|
6473
|
+
map2.set(slug, { ...frontmatter, slug, content: stripFrontmatter(content) });
|
|
6118
6474
|
} catch {}
|
|
6119
6475
|
}
|
|
6120
6476
|
return map2;
|
|
6121
6477
|
}
|
|
6122
6478
|
function loadExistingEntities(dir) {
|
|
6123
6479
|
const map2 = new Map;
|
|
6124
|
-
if (!
|
|
6480
|
+
if (!existsSync12(dir))
|
|
6125
6481
|
return map2;
|
|
6126
|
-
for (const file of
|
|
6482
|
+
for (const file of readdirSync3(dir)) {
|
|
6127
6483
|
if (!file.endsWith(".md"))
|
|
6128
6484
|
continue;
|
|
6129
6485
|
const slug = file.slice(0, -3);
|
|
6130
6486
|
try {
|
|
6131
|
-
const content =
|
|
6487
|
+
const content = readFileSync10(join9(dir, file), "utf8");
|
|
6132
6488
|
const frontmatter = parseFrontmatter(content);
|
|
6133
|
-
map2.set(slug, { ...frontmatter, slug, content:
|
|
6134
|
-
---
|
|
6135
|
-
`) + 5) });
|
|
6489
|
+
map2.set(slug, { ...frontmatter, slug, content: stripFrontmatter(content) });
|
|
6136
6490
|
} catch {}
|
|
6137
6491
|
}
|
|
6138
6492
|
return map2;
|
|
6139
6493
|
}
|
|
6140
6494
|
function parseFrontmatter(content) {
|
|
6141
|
-
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
6495
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
6142
6496
|
if (!match)
|
|
6143
6497
|
return {};
|
|
6144
|
-
const lines = match[1].split(
|
|
6145
|
-
`);
|
|
6498
|
+
const lines = match[1].split(/\r?\n/);
|
|
6146
6499
|
const obj = {};
|
|
6147
6500
|
for (const line of lines) {
|
|
6148
6501
|
const idx = line.indexOf(":");
|
|
6149
6502
|
if (idx > 0) {
|
|
6150
6503
|
const key = line.slice(0, idx).trim();
|
|
6151
|
-
const
|
|
6152
|
-
|
|
6504
|
+
const rawVal = line.slice(idx + 1).trim();
|
|
6505
|
+
if (rawVal.startsWith("[") && rawVal.endsWith("]")) {
|
|
6506
|
+
try {
|
|
6507
|
+
obj[key] = JSON.parse(rawVal);
|
|
6508
|
+
continue;
|
|
6509
|
+
} catch {}
|
|
6510
|
+
}
|
|
6511
|
+
if (rawVal === "true") {
|
|
6512
|
+
obj[key] = true;
|
|
6513
|
+
continue;
|
|
6514
|
+
}
|
|
6515
|
+
if (rawVal === "false") {
|
|
6516
|
+
obj[key] = false;
|
|
6517
|
+
continue;
|
|
6518
|
+
}
|
|
6519
|
+
if (!isNaN(Number(rawVal)) && rawVal !== "") {
|
|
6520
|
+
obj[key] = Number(rawVal);
|
|
6521
|
+
continue;
|
|
6522
|
+
}
|
|
6523
|
+
obj[key] = rawVal.replace(/^["']|["']$/g, "");
|
|
6153
6524
|
}
|
|
6154
6525
|
}
|
|
6155
6526
|
return obj;
|
|
@@ -6157,22 +6528,22 @@ function parseFrontmatter(content) {
|
|
|
6157
6528
|
function writeConceptPages(map2, dir) {
|
|
6158
6529
|
for (const [slug, page] of map2) {
|
|
6159
6530
|
const content = renderConceptPage(page);
|
|
6160
|
-
|
|
6531
|
+
writeFileSync7(join9(dir, slug + ".md"), content, "utf8");
|
|
6161
6532
|
}
|
|
6162
6533
|
}
|
|
6163
6534
|
function writeEntityPages(map2, dir) {
|
|
6164
6535
|
for (const [slug, page] of map2) {
|
|
6165
6536
|
const content = renderEntityPage(page);
|
|
6166
|
-
|
|
6537
|
+
writeFileSync7(join9(dir, slug + ".md"), content, "utf8");
|
|
6167
6538
|
}
|
|
6168
6539
|
}
|
|
6169
6540
|
function writeIndexPage(page, dir) {
|
|
6170
6541
|
const content = renderIndexPage(page);
|
|
6171
|
-
|
|
6542
|
+
writeFileSync7(join9(dir, "index.md"), content, "utf8");
|
|
6172
6543
|
}
|
|
6173
6544
|
function writeLogPage(page, dir) {
|
|
6174
6545
|
const content = renderLogPage(page);
|
|
6175
|
-
|
|
6546
|
+
writeFileSync7(join9(dir, "log.md"), content, "utf8");
|
|
6176
6547
|
}
|
|
6177
6548
|
function applyDetailLevel(page, detailLevel) {
|
|
6178
6549
|
if (detailLevel === "l1") {
|
|
@@ -6183,11 +6554,11 @@ function applyDetailLevel(page, detailLevel) {
|
|
|
6183
6554
|
return page;
|
|
6184
6555
|
}
|
|
6185
6556
|
function listWikiPages(memoryDir, options = {}) {
|
|
6186
|
-
const wikiDir =
|
|
6557
|
+
const wikiDir = join9(memoryDir, "wiki");
|
|
6187
6558
|
const pages = [];
|
|
6188
6559
|
const detailLevel = options.detailLevel ?? "full";
|
|
6189
6560
|
if (options.type === undefined || options.type === "concept") {
|
|
6190
|
-
const concepts = loadExistingConcepts(
|
|
6561
|
+
const concepts = loadExistingConcepts(join9(wikiDir, "concepts"));
|
|
6191
6562
|
for (const page of concepts.values()) {
|
|
6192
6563
|
if (!options.project || page.project === options.project) {
|
|
6193
6564
|
pages.push(applyDetailLevel(page, detailLevel));
|
|
@@ -6195,7 +6566,7 @@ function listWikiPages(memoryDir, options = {}) {
|
|
|
6195
6566
|
}
|
|
6196
6567
|
}
|
|
6197
6568
|
if (options.type === undefined || options.type === "entity") {
|
|
6198
|
-
const entities = loadExistingEntities(
|
|
6569
|
+
const entities = loadExistingEntities(join9(wikiDir, "entities"));
|
|
6199
6570
|
for (const page of entities.values()) {
|
|
6200
6571
|
if (!options.project || page.project === options.project) {
|
|
6201
6572
|
pages.push(applyDetailLevel(page, detailLevel));
|
|
@@ -6203,20 +6574,20 @@ function listWikiPages(memoryDir, options = {}) {
|
|
|
6203
6574
|
}
|
|
6204
6575
|
}
|
|
6205
6576
|
if (options.type === undefined || options.type === "index") {
|
|
6206
|
-
const idxPath =
|
|
6207
|
-
if (
|
|
6577
|
+
const idxPath = join9(wikiDir, "index.md");
|
|
6578
|
+
if (existsSync12(idxPath)) {
|
|
6208
6579
|
try {
|
|
6209
|
-
const raw =
|
|
6580
|
+
const raw = readFileSync10(idxPath, "utf8");
|
|
6210
6581
|
const fm = parseFrontmatter(raw);
|
|
6211
6582
|
pages.push(applyDetailLevel({ ...fm, slug: "index", type: "index", content: raw }, detailLevel));
|
|
6212
6583
|
} catch {}
|
|
6213
6584
|
}
|
|
6214
6585
|
}
|
|
6215
6586
|
if (options.type === undefined || options.type === "log") {
|
|
6216
|
-
const logPath =
|
|
6217
|
-
if (
|
|
6587
|
+
const logPath = join9(wikiDir, "log.md");
|
|
6588
|
+
if (existsSync12(logPath)) {
|
|
6218
6589
|
try {
|
|
6219
|
-
const raw =
|
|
6590
|
+
const raw = readFileSync10(logPath, "utf8");
|
|
6220
6591
|
const fm = parseFrontmatter(raw);
|
|
6221
6592
|
pages.push(applyDetailLevel({ ...fm, slug: "log", type: "log", content: raw }, detailLevel));
|
|
6222
6593
|
} catch {}
|
|
@@ -6225,37 +6596,37 @@ function listWikiPages(memoryDir, options = {}) {
|
|
|
6225
6596
|
return pages;
|
|
6226
6597
|
}
|
|
6227
6598
|
function getWikiPage(memoryDir, slug, type2, detailLevel = "full") {
|
|
6228
|
-
const wikiDir =
|
|
6599
|
+
const wikiDir = join9(memoryDir, "wiki");
|
|
6229
6600
|
if (slug === "index") {
|
|
6230
|
-
const p =
|
|
6231
|
-
if (
|
|
6232
|
-
const raw =
|
|
6601
|
+
const p = join9(wikiDir, "index.md");
|
|
6602
|
+
if (existsSync12(p)) {
|
|
6603
|
+
const raw = readFileSync10(p, "utf8");
|
|
6233
6604
|
const fm = parseFrontmatter(raw);
|
|
6234
6605
|
return applyDetailLevel({ ...fm, slug: "index", type: "index", content: raw }, detailLevel);
|
|
6235
6606
|
}
|
|
6236
6607
|
return null;
|
|
6237
6608
|
}
|
|
6238
6609
|
if (slug === "log") {
|
|
6239
|
-
const p =
|
|
6240
|
-
if (
|
|
6241
|
-
const raw =
|
|
6610
|
+
const p = join9(wikiDir, "log.md");
|
|
6611
|
+
if (existsSync12(p)) {
|
|
6612
|
+
const raw = readFileSync10(p, "utf8");
|
|
6242
6613
|
const fm = parseFrontmatter(raw);
|
|
6243
6614
|
return applyDetailLevel({ ...fm, slug: "log", type: "log", content: raw }, detailLevel);
|
|
6244
6615
|
}
|
|
6245
6616
|
return null;
|
|
6246
6617
|
}
|
|
6247
6618
|
if (!type2 || type2 === "concept") {
|
|
6248
|
-
const p =
|
|
6249
|
-
if (
|
|
6250
|
-
const raw =
|
|
6619
|
+
const p = join9(wikiDir, "concepts", `${slug}.md`);
|
|
6620
|
+
if (existsSync12(p)) {
|
|
6621
|
+
const raw = readFileSync10(p, "utf8");
|
|
6251
6622
|
const fm = parseFrontmatter(raw);
|
|
6252
6623
|
return applyDetailLevel({ ...fm, slug, type: "concept", content: raw }, detailLevel);
|
|
6253
6624
|
}
|
|
6254
6625
|
}
|
|
6255
6626
|
if (!type2 || type2 === "entity") {
|
|
6256
|
-
const p =
|
|
6257
|
-
if (
|
|
6258
|
-
const raw =
|
|
6627
|
+
const p = join9(wikiDir, "entities", `${slug}.md`);
|
|
6628
|
+
if (existsSync12(p)) {
|
|
6629
|
+
const raw = readFileSync10(p, "utf8");
|
|
6259
6630
|
const fm = parseFrontmatter(raw);
|
|
6260
6631
|
return applyDetailLevel({ ...fm, slug, type: "entity", content: raw }, detailLevel);
|
|
6261
6632
|
}
|
|
@@ -6263,15 +6634,15 @@ function getWikiPage(memoryDir, slug, type2, detailLevel = "full") {
|
|
|
6263
6634
|
return null;
|
|
6264
6635
|
}
|
|
6265
6636
|
function ensureWikiStructure(memoryDir) {
|
|
6266
|
-
const wikiDir =
|
|
6267
|
-
const conceptsDir =
|
|
6268
|
-
const entitiesDir =
|
|
6269
|
-
if (!
|
|
6270
|
-
|
|
6271
|
-
if (!
|
|
6272
|
-
|
|
6273
|
-
const indexPath =
|
|
6274
|
-
if (!
|
|
6637
|
+
const wikiDir = join9(memoryDir, "wiki");
|
|
6638
|
+
const conceptsDir = join9(wikiDir, "concepts");
|
|
6639
|
+
const entitiesDir = join9(wikiDir, "entities");
|
|
6640
|
+
if (!existsSync12(conceptsDir))
|
|
6641
|
+
mkdirSync9(conceptsDir, { recursive: true });
|
|
6642
|
+
if (!existsSync12(entitiesDir))
|
|
6643
|
+
mkdirSync9(entitiesDir, { recursive: true });
|
|
6644
|
+
const indexPath = join9(wikiDir, "index.md");
|
|
6645
|
+
if (!existsSync12(indexPath)) {
|
|
6275
6646
|
const defaultIndex = `# Knowledge Wiki Index
|
|
6276
6647
|
|
|
6277
6648
|
> Compiled Obsidian-compatible concept and entity knowledge base.
|
|
@@ -6282,16 +6653,16 @@ function ensureWikiStructure(memoryDir) {
|
|
|
6282
6653
|
## Entities
|
|
6283
6654
|
*(No named entities extracted yet)*
|
|
6284
6655
|
`;
|
|
6285
|
-
|
|
6656
|
+
writeFileSync7(indexPath, defaultIndex, "utf8");
|
|
6286
6657
|
}
|
|
6287
|
-
const logPath =
|
|
6288
|
-
if (!
|
|
6658
|
+
const logPath = join9(wikiDir, "log.md");
|
|
6659
|
+
if (!existsSync12(logPath)) {
|
|
6289
6660
|
const defaultLog = `# Wiki Compilation Log
|
|
6290
6661
|
|
|
6291
6662
|
| Timestamp | Action | Page | Memories | Details |
|
|
6292
6663
|
|---|---|---|---|---|
|
|
6293
6664
|
`;
|
|
6294
|
-
|
|
6665
|
+
writeFileSync7(logPath, defaultLog, "utf8");
|
|
6295
6666
|
}
|
|
6296
6667
|
}
|
|
6297
6668
|
function autoCompileWiki(store, memoryDir, options = {}) {
|
|
@@ -6306,25 +6677,13 @@ var init_compiler = __esm(() => {
|
|
|
6306
6677
|
});
|
|
6307
6678
|
|
|
6308
6679
|
// src/wiki/index.ts
|
|
6309
|
-
var exports_wiki = {};
|
|
6310
|
-
__export(exports_wiki, {
|
|
6311
|
-
autoCompileWiki: () => autoCompileWiki,
|
|
6312
|
-
compileWiki: () => compileWiki,
|
|
6313
|
-
ensureWikiStructure: () => ensureWikiStructure,
|
|
6314
|
-
getWikiPage: () => getWikiPage,
|
|
6315
|
-
listWikiPages: () => listWikiPages,
|
|
6316
|
-
renderConceptPage: () => renderConceptPage,
|
|
6317
|
-
renderEntityPage: () => renderEntityPage,
|
|
6318
|
-
renderIndexPage: () => renderIndexPage,
|
|
6319
|
-
renderLogPage: () => renderLogPage
|
|
6320
|
-
});
|
|
6321
6680
|
var init_wiki = __esm(() => {
|
|
6322
6681
|
init_compiler();
|
|
6323
6682
|
});
|
|
6324
6683
|
|
|
6325
6684
|
// src/root.ts
|
|
6326
|
-
import { existsSync as
|
|
6327
|
-
import { dirname as dirname3, join as
|
|
6685
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync10, writeFileSync as writeFileSync8 } from "node:fs";
|
|
6686
|
+
import { dirname as dirname3, join as join10 } from "node:path";
|
|
6328
6687
|
import { homedir } from "node:os";
|
|
6329
6688
|
function isMemoryDirPath(path) {
|
|
6330
6689
|
return MEMORY_DIR_NAMES.some((n) => path.endsWith(n));
|
|
@@ -6337,20 +6696,20 @@ function getGlobalMemoryDir() {
|
|
|
6337
6696
|
if (custom)
|
|
6338
6697
|
return custom;
|
|
6339
6698
|
const home = process.env.HOME || process.env.USERPROFILE || homedir();
|
|
6340
|
-
return
|
|
6699
|
+
return join10(home, ".memory");
|
|
6341
6700
|
}
|
|
6342
6701
|
function ensureMemoryDirectory(memoryDir) {
|
|
6343
|
-
const memoriesDir =
|
|
6344
|
-
if (!
|
|
6345
|
-
|
|
6702
|
+
const memoriesDir = join10(memoryDir, "memories");
|
|
6703
|
+
if (!existsSync13(memoriesDir)) {
|
|
6704
|
+
mkdirSync10(memoriesDir, { recursive: true });
|
|
6346
6705
|
}
|
|
6347
|
-
const currentPath =
|
|
6348
|
-
if (!
|
|
6349
|
-
|
|
6706
|
+
const currentPath = join10(memoryDir, "CURRENT.md");
|
|
6707
|
+
if (!existsSync13(currentPath)) {
|
|
6708
|
+
writeFileSync8(currentPath, `# Active Project Constraints
|
|
6350
6709
|
`, "utf8");
|
|
6351
6710
|
}
|
|
6352
6711
|
const uPath = userFilePath(memoryDir);
|
|
6353
|
-
if (!
|
|
6712
|
+
if (!existsSync13(uPath)) {
|
|
6354
6713
|
const isGlobal = memoryDir === getGlobalMemoryDir();
|
|
6355
6714
|
initUserProfile(memoryDir, "developer", false, !isGlobal);
|
|
6356
6715
|
}
|
|
@@ -6367,19 +6726,19 @@ function findProjectRoot(startDir, options = {}) {
|
|
|
6367
6726
|
}
|
|
6368
6727
|
const ancestors = ancestorChain(startDir);
|
|
6369
6728
|
for (const dir of ancestors) {
|
|
6370
|
-
if (
|
|
6729
|
+
if (existsSync13(join10(dir, ".memory")))
|
|
6371
6730
|
return { root: dir, marker: "memory", memoryDirName: ".memory" };
|
|
6372
|
-
if (
|
|
6731
|
+
if (existsSync13(join10(dir, ".musememory")))
|
|
6373
6732
|
return { root: dir, marker: "memory", memoryDirName: ".musememory" };
|
|
6374
|
-
if (
|
|
6733
|
+
if (existsSync13(join10(dir, ".muse-memory")))
|
|
6375
6734
|
return { root: dir, marker: "memory", memoryDirName: ".muse-memory" };
|
|
6376
6735
|
}
|
|
6377
6736
|
for (const dir of ancestors) {
|
|
6378
|
-
if (
|
|
6737
|
+
if (existsSync13(join10(dir, ".git"))) {
|
|
6379
6738
|
let dirName = ".memory";
|
|
6380
|
-
if (
|
|
6739
|
+
if (existsSync13(join10(dir, ".musememory")))
|
|
6381
6740
|
dirName = ".musememory";
|
|
6382
|
-
else if (
|
|
6741
|
+
else if (existsSync13(join10(dir, ".muse-memory")))
|
|
6383
6742
|
dirName = ".muse-memory";
|
|
6384
6743
|
return { root: dir, marker: "git", memoryDirName: dirName };
|
|
6385
6744
|
}
|
|
@@ -6399,8 +6758,8 @@ function findOrCreateProjectRoot(startDir, options = {}) {
|
|
|
6399
6758
|
return { root: memoryDir2, memoryDir: memoryDir2, marker: res.marker };
|
|
6400
6759
|
}
|
|
6401
6760
|
const root = res.root ?? startDir;
|
|
6402
|
-
const memoryDirName = res.memoryDirName ?? MEMORY_DIR_NAMES.find((n) =>
|
|
6403
|
-
const memoryDir =
|
|
6761
|
+
const memoryDirName = res.memoryDirName ?? MEMORY_DIR_NAMES.find((n) => existsSync13(join10(root, n))) ?? ".memory";
|
|
6762
|
+
const memoryDir = join10(root, memoryDirName);
|
|
6404
6763
|
const marker = res.marker ?? "auto";
|
|
6405
6764
|
ensureMemoryDirectory(memoryDir);
|
|
6406
6765
|
return { root, memoryDir, marker };
|
|
@@ -6410,7 +6769,7 @@ function ancestorChain(startDir) {
|
|
|
6410
6769
|
let dir = startDir;
|
|
6411
6770
|
for (;; ) {
|
|
6412
6771
|
chain.push(dir);
|
|
6413
|
-
const parent =
|
|
6772
|
+
const parent = join10(dir, "..");
|
|
6414
6773
|
if (parent === dir)
|
|
6415
6774
|
break;
|
|
6416
6775
|
dir = parent;
|
|
@@ -6454,7 +6813,8 @@ function parseFlags(args) {
|
|
|
6454
6813
|
}
|
|
6455
6814
|
function requireRoot(flags = {}) {
|
|
6456
6815
|
const isGlobal = flags["global"] === "true";
|
|
6457
|
-
const
|
|
6816
|
+
const startDir = flags["dir"] || process.cwd();
|
|
6817
|
+
const { root, memoryDir } = findOrCreateProjectRoot(startDir, { global: isGlobal });
|
|
6458
6818
|
return { root, memoryDir, store: openStore(memoryDir) };
|
|
6459
6819
|
}
|
|
6460
6820
|
function usageError(msg) {
|
|
@@ -6514,23 +6874,23 @@ function normalizeMemoryType(raw) {
|
|
|
6514
6874
|
}
|
|
6515
6875
|
|
|
6516
6876
|
// src/migrator/detect.ts
|
|
6517
|
-
import { existsSync as
|
|
6518
|
-
import { join as
|
|
6877
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
6878
|
+
import { join as join11, resolve as resolve2 } from "node:path";
|
|
6519
6879
|
import { homedir as homedir2 } from "node:os";
|
|
6520
6880
|
function expandPath(p, baseDir) {
|
|
6521
6881
|
if (p.startsWith("~/") || p === "~") {
|
|
6522
|
-
return
|
|
6882
|
+
return join11(homedir2(), p.slice(1));
|
|
6523
6883
|
}
|
|
6524
6884
|
if (p.startsWith("/")) {
|
|
6525
6885
|
return p;
|
|
6526
6886
|
}
|
|
6527
|
-
return
|
|
6887
|
+
return resolve2(baseDir, p);
|
|
6528
6888
|
}
|
|
6529
6889
|
function detectProviders(baseDir = process.cwd()) {
|
|
6530
6890
|
return PROVIDER_DEFINITIONS.map((def) => {
|
|
6531
6891
|
const resolved = def.paths.map((p) => expandPath(p, baseDir)).filter((p) => {
|
|
6532
6892
|
try {
|
|
6533
|
-
return
|
|
6893
|
+
return existsSync14(p);
|
|
6534
6894
|
} catch {
|
|
6535
6895
|
return false;
|
|
6536
6896
|
}
|
|
@@ -6821,8 +7181,8 @@ var init_detect = __esm(() => {
|
|
|
6821
7181
|
});
|
|
6822
7182
|
|
|
6823
7183
|
// src/migrator/adapters/agentmemory.ts
|
|
6824
|
-
import { existsSync as
|
|
6825
|
-
import { join as
|
|
7184
|
+
import { existsSync as existsSync15, readFileSync as readFileSync11, statSync } from "node:fs";
|
|
7185
|
+
import { join as join12 } from "node:path";
|
|
6826
7186
|
var AgentMemoryAdapter;
|
|
6827
7187
|
var init_agentmemory = __esm(() => {
|
|
6828
7188
|
AgentMemoryAdapter = {
|
|
@@ -6830,23 +7190,23 @@ var init_agentmemory = __esm(() => {
|
|
|
6830
7190
|
extract(sourcePath, options = {}) {
|
|
6831
7191
|
const results = [];
|
|
6832
7192
|
let jsonPath = sourcePath;
|
|
6833
|
-
if (
|
|
7193
|
+
if (existsSync15(sourcePath) && statSync(sourcePath).isDirectory()) {
|
|
6834
7194
|
const candidates = [
|
|
6835
|
-
|
|
6836
|
-
|
|
7195
|
+
join12(sourcePath, "standalone.json"),
|
|
7196
|
+
join12(sourcePath, "engine-state.json")
|
|
6837
7197
|
];
|
|
6838
7198
|
for (const cand of candidates) {
|
|
6839
|
-
if (
|
|
7199
|
+
if (existsSync15(cand)) {
|
|
6840
7200
|
jsonPath = cand;
|
|
6841
7201
|
break;
|
|
6842
7202
|
}
|
|
6843
7203
|
}
|
|
6844
7204
|
}
|
|
6845
|
-
if (!
|
|
7205
|
+
if (!existsSync15(jsonPath) || statSync(jsonPath).isDirectory()) {
|
|
6846
7206
|
return results;
|
|
6847
7207
|
}
|
|
6848
7208
|
try {
|
|
6849
|
-
const raw =
|
|
7209
|
+
const raw = readFileSync11(jsonPath, "utf8");
|
|
6850
7210
|
const parsed = JSON.parse(raw);
|
|
6851
7211
|
const memObj = parsed["mem:memories"] || parsed["memories"] || parsed;
|
|
6852
7212
|
const items = Array.isArray(memObj) ? memObj : Object.values(memObj);
|
|
@@ -6883,25 +7243,25 @@ var init_agentmemory = __esm(() => {
|
|
|
6883
7243
|
});
|
|
6884
7244
|
|
|
6885
7245
|
// src/migrator/adapters/beads.ts
|
|
6886
|
-
import { existsSync as
|
|
6887
|
-
import { join as
|
|
7246
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12, readdirSync as readdirSync4, statSync as statSync2 } from "node:fs";
|
|
7247
|
+
import { join as join13 } from "node:path";
|
|
6888
7248
|
var BeadsAdapter;
|
|
6889
7249
|
var init_beads = __esm(() => {
|
|
6890
7250
|
BeadsAdapter = {
|
|
6891
7251
|
id: "beads",
|
|
6892
7252
|
extract(sourcePath, options = {}) {
|
|
6893
7253
|
const results = [];
|
|
6894
|
-
if (!
|
|
7254
|
+
if (!existsSync16(sourcePath))
|
|
6895
7255
|
return results;
|
|
6896
7256
|
let jsonPath = sourcePath;
|
|
6897
7257
|
if (statSync2(sourcePath).isDirectory()) {
|
|
6898
|
-
const p =
|
|
6899
|
-
if (
|
|
7258
|
+
const p = join13(sourcePath, "beads.json");
|
|
7259
|
+
if (existsSync16(p))
|
|
6900
7260
|
jsonPath = p;
|
|
6901
7261
|
}
|
|
6902
|
-
if (
|
|
7262
|
+
if (existsSync16(jsonPath) && !statSync2(jsonPath).isDirectory()) {
|
|
6903
7263
|
try {
|
|
6904
|
-
const raw =
|
|
7264
|
+
const raw = readFileSync12(jsonPath, "utf8");
|
|
6905
7265
|
const parsed = JSON.parse(raw);
|
|
6906
7266
|
const beads = Array.isArray(parsed) ? parsed : parsed.beads || Object.values(parsed);
|
|
6907
7267
|
for (const b of beads) {
|
|
@@ -6932,12 +7292,12 @@ var init_beads = __esm(() => {
|
|
|
6932
7292
|
}
|
|
6933
7293
|
if (statSync2(sourcePath).isDirectory()) {
|
|
6934
7294
|
try {
|
|
6935
|
-
const files =
|
|
7295
|
+
const files = readdirSync4(sourcePath);
|
|
6936
7296
|
for (const file of files) {
|
|
6937
7297
|
if (!file.endsWith(".md") && !file.endsWith(".markdown"))
|
|
6938
7298
|
continue;
|
|
6939
|
-
const fullPath =
|
|
6940
|
-
const content =
|
|
7299
|
+
const fullPath = join13(sourcePath, file);
|
|
7300
|
+
const content = readFileSync12(fullPath, "utf8");
|
|
6941
7301
|
const title = file.replace(/\.md$/, "").replace(/[-_]/g, " ");
|
|
6942
7302
|
results.push({
|
|
6943
7303
|
title,
|
|
@@ -6957,15 +7317,15 @@ var init_beads = __esm(() => {
|
|
|
6957
7317
|
});
|
|
6958
7318
|
|
|
6959
7319
|
// src/migrator/adapters/letta.ts
|
|
6960
|
-
import { existsSync as
|
|
6961
|
-
import { join as
|
|
7320
|
+
import { existsSync as existsSync17, readFileSync as readFileSync13, readdirSync as readdirSync5, statSync as statSync3 } from "node:fs";
|
|
7321
|
+
import { join as join14 } from "node:path";
|
|
6962
7322
|
var LettaAdapter;
|
|
6963
7323
|
var init_letta = __esm(() => {
|
|
6964
7324
|
LettaAdapter = {
|
|
6965
7325
|
id: "letta",
|
|
6966
7326
|
extract(sourcePath, options = {}) {
|
|
6967
7327
|
const results = [];
|
|
6968
|
-
if (!
|
|
7328
|
+
if (!existsSync17(sourcePath))
|
|
6969
7329
|
return results;
|
|
6970
7330
|
const processJson = (raw, filename) => {
|
|
6971
7331
|
try {
|
|
@@ -7018,16 +7378,16 @@ var init_letta = __esm(() => {
|
|
|
7018
7378
|
};
|
|
7019
7379
|
if (statSync3(sourcePath).isDirectory()) {
|
|
7020
7380
|
try {
|
|
7021
|
-
const entries =
|
|
7381
|
+
const entries = readdirSync5(sourcePath);
|
|
7022
7382
|
for (const file of entries) {
|
|
7023
7383
|
if (file.endsWith(".json")) {
|
|
7024
|
-
const raw =
|
|
7384
|
+
const raw = readFileSync13(join14(sourcePath, file), "utf8");
|
|
7025
7385
|
processJson(raw, file);
|
|
7026
7386
|
}
|
|
7027
7387
|
}
|
|
7028
7388
|
} catch {}
|
|
7029
7389
|
} else {
|
|
7030
|
-
processJson(
|
|
7390
|
+
processJson(readFileSync13(sourcePath, "utf8"), "letta.json");
|
|
7031
7391
|
}
|
|
7032
7392
|
return results;
|
|
7033
7393
|
}
|
|
@@ -7035,8 +7395,8 @@ var init_letta = __esm(() => {
|
|
|
7035
7395
|
});
|
|
7036
7396
|
|
|
7037
7397
|
// src/migrator/adapters/generic.ts
|
|
7038
|
-
import { existsSync as
|
|
7039
|
-
import { join as
|
|
7398
|
+
import { existsSync as existsSync18, readFileSync as readFileSync14, readdirSync as readdirSync6, statSync as statSync4 } from "node:fs";
|
|
7399
|
+
import { join as join15 } from "node:path";
|
|
7040
7400
|
var GenericAdapter;
|
|
7041
7401
|
var init_generic = __esm(() => {
|
|
7042
7402
|
init_js_yaml();
|
|
@@ -7044,11 +7404,11 @@ var init_generic = __esm(() => {
|
|
|
7044
7404
|
id: "generic",
|
|
7045
7405
|
extract(sourcePath, options = {}) {
|
|
7046
7406
|
const results = [];
|
|
7047
|
-
if (!
|
|
7407
|
+
if (!existsSync18(sourcePath))
|
|
7048
7408
|
return results;
|
|
7049
7409
|
const processFile = (filePath, filename) => {
|
|
7050
7410
|
try {
|
|
7051
|
-
const raw =
|
|
7411
|
+
const raw = readFileSync14(filePath, "utf8");
|
|
7052
7412
|
if (filename.endsWith(".json") || filename.endsWith(".jsonl")) {
|
|
7053
7413
|
try {
|
|
7054
7414
|
const parsed = JSON.parse(raw);
|
|
@@ -7119,9 +7479,9 @@ var init_generic = __esm(() => {
|
|
|
7119
7479
|
};
|
|
7120
7480
|
if (statSync4(sourcePath).isDirectory()) {
|
|
7121
7481
|
try {
|
|
7122
|
-
const files =
|
|
7482
|
+
const files = readdirSync6(sourcePath);
|
|
7123
7483
|
for (const file of files) {
|
|
7124
|
-
processFile(
|
|
7484
|
+
processFile(join15(sourcePath, file), file);
|
|
7125
7485
|
}
|
|
7126
7486
|
} catch {}
|
|
7127
7487
|
} else {
|
|
@@ -7289,50 +7649,6 @@ var init_migrator = __esm(() => {
|
|
|
7289
7649
|
init_engine();
|
|
7290
7650
|
});
|
|
7291
7651
|
|
|
7292
|
-
// src/graph.ts
|
|
7293
|
-
import { existsSync as existsSync18, readdirSync as readdirSync6, readFileSync as readFileSync14 } from "node:fs";
|
|
7294
|
-
import { join as join15 } from "node:path";
|
|
7295
|
-
function detectProvider(projectRoot) {
|
|
7296
|
-
if (!projectRoot || !existsSync18(projectRoot))
|
|
7297
|
-
return "none";
|
|
7298
|
-
if (existsSync18(join15(projectRoot, ".codegraph"))) {
|
|
7299
|
-
return "codegraph";
|
|
7300
|
-
}
|
|
7301
|
-
return "none";
|
|
7302
|
-
}
|
|
7303
|
-
function getGraphStatus(projectRoot) {
|
|
7304
|
-
const provider = detectProvider(projectRoot);
|
|
7305
|
-
if (provider === "codegraph") {
|
|
7306
|
-
const codegraphDir = join15(projectRoot, ".codegraph");
|
|
7307
|
-
let symbolCount;
|
|
7308
|
-
let graphRevision;
|
|
7309
|
-
try {
|
|
7310
|
-
if (existsSync18(codegraphDir)) {
|
|
7311
|
-
const files = readdirSync6(codegraphDir);
|
|
7312
|
-
symbolCount = files.length;
|
|
7313
|
-
const metaPath = join15(codegraphDir, "meta.json");
|
|
7314
|
-
if (existsSync18(metaPath)) {
|
|
7315
|
-
const meta = JSON.parse(readFileSync14(metaPath, "utf8"));
|
|
7316
|
-
graphRevision = meta.revision ?? meta.commit ?? meta.version;
|
|
7317
|
-
}
|
|
7318
|
-
}
|
|
7319
|
-
} catch {}
|
|
7320
|
-
return {
|
|
7321
|
-
provider: "codegraph",
|
|
7322
|
-
available: true,
|
|
7323
|
-
root: codegraphDir,
|
|
7324
|
-
graphRevision,
|
|
7325
|
-
symbolCount
|
|
7326
|
-
};
|
|
7327
|
-
}
|
|
7328
|
-
return {
|
|
7329
|
-
provider: "none",
|
|
7330
|
-
available: false,
|
|
7331
|
-
root: projectRoot
|
|
7332
|
-
};
|
|
7333
|
-
}
|
|
7334
|
-
var init_graph = () => {};
|
|
7335
|
-
|
|
7336
7652
|
// src/prompt.ts
|
|
7337
7653
|
var exports_prompt = {};
|
|
7338
7654
|
__export(exports_prompt, {
|
|
@@ -7402,14 +7718,14 @@ ${title}`);
|
|
|
7402
7718
|
input: process.stdin,
|
|
7403
7719
|
output: process.stdout
|
|
7404
7720
|
});
|
|
7405
|
-
return new Promise((
|
|
7721
|
+
return new Promise((resolve3) => {
|
|
7406
7722
|
rl.question(`Enter selection (e.g. "1,3" or "all") [default: ${defaultAll ? "all" : "none"}]: `, (answer) => {
|
|
7407
7723
|
rl.close();
|
|
7408
7724
|
const result = parseSelectionInput(answer, options, defaultAll);
|
|
7409
7725
|
if (answer.trim().toLowerCase().startsWith("q")) {
|
|
7410
7726
|
console.log("Operation cancelled.");
|
|
7411
7727
|
}
|
|
7412
|
-
|
|
7728
|
+
resolve3(result);
|
|
7413
7729
|
});
|
|
7414
7730
|
});
|
|
7415
7731
|
}
|
|
@@ -7432,23 +7748,23 @@ ${title}`);
|
|
|
7432
7748
|
input: process.stdin,
|
|
7433
7749
|
output: process.stdout
|
|
7434
7750
|
});
|
|
7435
|
-
return new Promise((
|
|
7751
|
+
return new Promise((resolve3) => {
|
|
7436
7752
|
rl.question(`
|
|
7437
7753
|
Select role archetype [1-${options.length}] (default: 1): `, (answer) => {
|
|
7438
7754
|
rl.close();
|
|
7439
7755
|
const trimmed = answer.trim();
|
|
7440
7756
|
if (!trimmed) {
|
|
7441
|
-
return
|
|
7757
|
+
return resolve3(defaultId);
|
|
7442
7758
|
}
|
|
7443
7759
|
const num = parseInt(trimmed, 10);
|
|
7444
7760
|
if (!isNaN(num) && num >= 1 && num <= options.length) {
|
|
7445
|
-
return
|
|
7761
|
+
return resolve3(options[num - 1].id);
|
|
7446
7762
|
}
|
|
7447
7763
|
const matched = options.find((o) => o.id.toLowerCase() === trimmed.toLowerCase() || o.label.toLowerCase().includes(trimmed.toLowerCase()));
|
|
7448
7764
|
if (matched) {
|
|
7449
|
-
return
|
|
7765
|
+
return resolve3(matched.id);
|
|
7450
7766
|
}
|
|
7451
|
-
|
|
7767
|
+
resolve3(defaultId);
|
|
7452
7768
|
});
|
|
7453
7769
|
});
|
|
7454
7770
|
}
|
|
@@ -8096,7 +8412,7 @@ __export(exports_connect, {
|
|
|
8096
8412
|
disconnectAllAgents: () => disconnectAllAgents,
|
|
8097
8413
|
disconnectSingleAgent: () => disconnectSingleAgent
|
|
8098
8414
|
});
|
|
8099
|
-
import { existsSync as existsSync20, readFileSync as readFileSync16, writeFileSync as
|
|
8415
|
+
import { existsSync as existsSync20, readFileSync as readFileSync16, writeFileSync as writeFileSync9, mkdirSync as mkdirSync11, statSync as statSync6 } from "node:fs";
|
|
8100
8416
|
import { join as join17, dirname as dirname4 } from "node:path";
|
|
8101
8417
|
import { homedir as homedir4 } from "node:os";
|
|
8102
8418
|
function safeReadJson(path) {
|
|
@@ -8114,8 +8430,8 @@ function safeWriteJson(path, data, dryRun = false) {
|
|
|
8114
8430
|
return;
|
|
8115
8431
|
const dir = dirname4(path);
|
|
8116
8432
|
if (!existsSync20(dir))
|
|
8117
|
-
|
|
8118
|
-
|
|
8433
|
+
mkdirSync11(dir, { recursive: true });
|
|
8434
|
+
writeFileSync9(path, JSON.stringify(data, null, 2) + `
|
|
8119
8435
|
`, "utf8");
|
|
8120
8436
|
}
|
|
8121
8437
|
function safeReadYaml(path) {
|
|
@@ -8134,9 +8450,9 @@ function safeWriteYaml(path, data, dryRun = false) {
|
|
|
8134
8450
|
return;
|
|
8135
8451
|
const dir = dirname4(path);
|
|
8136
8452
|
if (!existsSync20(dir))
|
|
8137
|
-
|
|
8453
|
+
mkdirSync11(dir, { recursive: true });
|
|
8138
8454
|
const dumped = yaml.dump(data, { indent: 2, lineWidth: -1 });
|
|
8139
|
-
|
|
8455
|
+
writeFileSync9(path, dumped, "utf8");
|
|
8140
8456
|
}
|
|
8141
8457
|
function resolveAgentConfigFile(agent, home, foundConfig) {
|
|
8142
8458
|
if (foundConfig && existsSync20(foundConfig)) {
|
|
@@ -8526,8 +8842,8 @@ __export(exports_hook, {
|
|
|
8526
8842
|
import {
|
|
8527
8843
|
existsSync as existsSync21,
|
|
8528
8844
|
readFileSync as readFileSync17,
|
|
8529
|
-
writeFileSync as
|
|
8530
|
-
mkdirSync as
|
|
8845
|
+
writeFileSync as writeFileSync10,
|
|
8846
|
+
mkdirSync as mkdirSync12,
|
|
8531
8847
|
readdirSync as readdirSync7,
|
|
8532
8848
|
statSync as statSync7,
|
|
8533
8849
|
renameSync as renameSync2,
|
|
@@ -8544,8 +8860,8 @@ function installGitHook(workspaceRoot) {
|
|
|
8544
8860
|
if (existsSync21(hookPath)) {
|
|
8545
8861
|
return { installed: false, path: hookPath, message: `pre-commit hook already exists at ${hookPath} — leaving it untouched` };
|
|
8546
8862
|
}
|
|
8547
|
-
|
|
8548
|
-
|
|
8863
|
+
mkdirSync12(hooksDir, { recursive: true });
|
|
8864
|
+
writeFileSync10(hookPath, HOOK_SCRIPT, "utf8");
|
|
8549
8865
|
chmodSync(hookPath, 493);
|
|
8550
8866
|
return { installed: true, path: hookPath, message: `installed pre-commit hook at ${hookPath}` };
|
|
8551
8867
|
}
|
|
@@ -8607,7 +8923,7 @@ function harvestAuto(store, workspaceRoot, memoryDir, options = {}) {
|
|
|
8607
8923
|
confirmed: false,
|
|
8608
8924
|
source: "harvest_auto"
|
|
8609
8925
|
});
|
|
8610
|
-
|
|
8926
|
+
mkdirSync12(processedDir, { recursive: true });
|
|
8611
8927
|
const base = file.split("/").pop() ?? "transcript.jsonl";
|
|
8612
8928
|
let dest = join18(processedDir, base);
|
|
8613
8929
|
if (existsSync21(dest)) {
|
|
@@ -11524,7 +11840,7 @@ var require_compile = __commonJS(function(exports) {
|
|
|
11524
11840
|
const schOrFunc = root.refs[ref];
|
|
11525
11841
|
if (schOrFunc)
|
|
11526
11842
|
return schOrFunc;
|
|
11527
|
-
let _sch =
|
|
11843
|
+
let _sch = resolve3.call(this, root, ref);
|
|
11528
11844
|
if (_sch === undefined) {
|
|
11529
11845
|
const schema2 = (_a = root.localRefs) === null || _a === undefined ? undefined : _a[ref];
|
|
11530
11846
|
const { schemaId } = this.opts;
|
|
@@ -11551,7 +11867,7 @@ var require_compile = __commonJS(function(exports) {
|
|
|
11551
11867
|
function sameSchemaEnv(s1, s2) {
|
|
11552
11868
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
11553
11869
|
}
|
|
11554
|
-
function
|
|
11870
|
+
function resolve3(root, ref) {
|
|
11555
11871
|
let sch;
|
|
11556
11872
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
11557
11873
|
ref = sch;
|
|
@@ -12137,7 +12453,7 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
12137
12453
|
}
|
|
12138
12454
|
return uri;
|
|
12139
12455
|
}
|
|
12140
|
-
function
|
|
12456
|
+
function resolve3(baseURI, relativeURI, options) {
|
|
12141
12457
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
12142
12458
|
const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
|
|
12143
12459
|
const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
|
|
@@ -12422,7 +12738,7 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
12422
12738
|
var fastUri = {
|
|
12423
12739
|
SCHEMES,
|
|
12424
12740
|
normalize,
|
|
12425
|
-
resolve:
|
|
12741
|
+
resolve: resolve3,
|
|
12426
12742
|
resolveComponent,
|
|
12427
12743
|
equal,
|
|
12428
12744
|
serialize,
|
|
@@ -14939,7 +15255,7 @@ var require_ajv = __commonJS(function(exports, module) {
|
|
|
14939
15255
|
});
|
|
14940
15256
|
|
|
14941
15257
|
// src/schema.ts
|
|
14942
|
-
import { readFileSync as readFileSync18 } from "node:fs";
|
|
15258
|
+
import { existsSync as existsSync22, readFileSync as readFileSync18 } from "node:fs";
|
|
14943
15259
|
import { join as join19 } from "node:path";
|
|
14944
15260
|
function getValidator() {
|
|
14945
15261
|
if (cachedValidate)
|
|
@@ -14950,8 +15266,22 @@ function getValidator() {
|
|
|
14950
15266
|
return false;
|
|
14951
15267
|
return !Number.isNaN(Date.parse(value));
|
|
14952
15268
|
});
|
|
14953
|
-
const
|
|
14954
|
-
|
|
15269
|
+
const candidates = [
|
|
15270
|
+
join19(import.meta.dir, "..", "schema.json"),
|
|
15271
|
+
join19(import.meta.dir, "schema.json"),
|
|
15272
|
+
join19(process.cwd(), "schema.json")
|
|
15273
|
+
];
|
|
15274
|
+
let schemaContent = null;
|
|
15275
|
+
for (const p of candidates) {
|
|
15276
|
+
if (existsSync22(p)) {
|
|
15277
|
+
schemaContent = readFileSync18(p, "utf8");
|
|
15278
|
+
break;
|
|
15279
|
+
}
|
|
15280
|
+
}
|
|
15281
|
+
if (!schemaContent) {
|
|
15282
|
+
throw new Error(`Cannot locate schema.json in ${candidates.join(", ")}`);
|
|
15283
|
+
}
|
|
15284
|
+
const schema2 = JSON.parse(schemaContent);
|
|
14955
15285
|
cachedValidate = ajv.compile(schema2);
|
|
14956
15286
|
return cachedValidate;
|
|
14957
15287
|
}
|
|
@@ -15057,13 +15387,13 @@ __export(exports_doctor, {
|
|
|
15057
15387
|
printDoctorReport: () => printDoctorReport,
|
|
15058
15388
|
runDoctor: () => runDoctor
|
|
15059
15389
|
});
|
|
15060
|
-
import { existsSync as
|
|
15390
|
+
import { existsSync as existsSync23, statSync as statSync8, readFileSync as readFileSync19 } from "node:fs";
|
|
15061
15391
|
import { join as join20 } from "node:path";
|
|
15062
15392
|
import { homedir as homedir5 } from "node:os";
|
|
15063
15393
|
async function runDoctor(targetDir, options = {}) {
|
|
15064
15394
|
const home = homedir5();
|
|
15065
15395
|
const storagePath = options.global ? getGlobalMemoryDir() : findOrCreateProjectRoot(targetDir || process.cwd())?.memoryDir || join20(home, ".memory");
|
|
15066
|
-
const isInitialized =
|
|
15396
|
+
const isInitialized = existsSync23(storagePath);
|
|
15067
15397
|
let currentMdExists = false;
|
|
15068
15398
|
let currentMdLines = 0;
|
|
15069
15399
|
let totalEntries = 0;
|
|
@@ -15082,7 +15412,7 @@ async function runDoctor(targetDir, options = {}) {
|
|
|
15082
15412
|
let brokenLinksCount = 0;
|
|
15083
15413
|
if (isInitialized) {
|
|
15084
15414
|
const currentPath = join20(storagePath, "CURRENT.md");
|
|
15085
|
-
if (
|
|
15415
|
+
if (existsSync23(currentPath)) {
|
|
15086
15416
|
currentMdExists = true;
|
|
15087
15417
|
const content = readFileSync19(currentPath, "utf8");
|
|
15088
15418
|
currentMdLines = content.split(`
|
|
@@ -15110,7 +15440,7 @@ async function runDoctor(targetDir, options = {}) {
|
|
|
15110
15440
|
let auditCount = 0;
|
|
15111
15441
|
let auditSize = 0;
|
|
15112
15442
|
let lastEvent;
|
|
15113
|
-
if (
|
|
15443
|
+
if (existsSync23(auditPath)) {
|
|
15114
15444
|
auditExists = true;
|
|
15115
15445
|
try {
|
|
15116
15446
|
const stat = statSync8(auditPath);
|
|
@@ -15245,7 +15575,7 @@ var init_doctor = __esm(() => {
|
|
|
15245
15575
|
});
|
|
15246
15576
|
|
|
15247
15577
|
// src/retrieval/tree-index.ts
|
|
15248
|
-
import { existsSync as
|
|
15578
|
+
import { existsSync as existsSync24, readFileSync as readFileSync20, writeFileSync as writeFileSync11, mkdirSync as mkdirSync13, rmSync } from "node:fs";
|
|
15249
15579
|
import { join as join21 } from "node:path";
|
|
15250
15580
|
function tokenize2(text) {
|
|
15251
15581
|
if (!text || typeof text !== "string")
|
|
@@ -15355,7 +15685,7 @@ function countNodes(node) {
|
|
|
15355
15685
|
function buildTreeIndex(store, memoryDir, config = {}) {
|
|
15356
15686
|
const cfg = { ...DEFAULT_CONFIG, ...config };
|
|
15357
15687
|
const allMemories = list(store).filter((e) => e.status === "confirmed");
|
|
15358
|
-
|
|
15688
|
+
mkdirSync13(indexDir(memoryDir), { recursive: true });
|
|
15359
15689
|
if (allMemories.length === 0) {
|
|
15360
15690
|
const emptyIndex = {
|
|
15361
15691
|
version: 1,
|
|
@@ -15364,7 +15694,7 @@ function buildTreeIndex(store, memoryDir, config = {}) {
|
|
|
15364
15694
|
totalMemories: 0,
|
|
15365
15695
|
builtAt: nowIso3()
|
|
15366
15696
|
};
|
|
15367
|
-
|
|
15697
|
+
writeFileSync11(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(emptyIndex, null, 2), "utf8");
|
|
15368
15698
|
return emptyIndex;
|
|
15369
15699
|
}
|
|
15370
15700
|
const groups = new Map;
|
|
@@ -15382,7 +15712,7 @@ function buildTreeIndex(store, memoryDir, config = {}) {
|
|
|
15382
15712
|
for (const [key, memories] of groups) {
|
|
15383
15713
|
const [project, type2] = key.split("|");
|
|
15384
15714
|
const pDir = partitionDir(indexDir(memoryDir), project, type2);
|
|
15385
|
-
|
|
15715
|
+
mkdirSync13(pDir, { recursive: true });
|
|
15386
15716
|
const maxShardSize = cfg.shardThreshold || 1e4;
|
|
15387
15717
|
const finalShards = [];
|
|
15388
15718
|
const memoryChunks = [];
|
|
@@ -15443,9 +15773,9 @@ function buildTreeIndex(store, memoryDir, config = {}) {
|
|
|
15443
15773
|
partitions[`${project}|${type2}`] = partition;
|
|
15444
15774
|
totalIndexNodes += partitionNodes;
|
|
15445
15775
|
totalIndexMemories += partitionMemories;
|
|
15446
|
-
|
|
15776
|
+
writeFileSync11(partitionIndexFilePath(pDir), JSON.stringify(partition, null, 2), "utf8");
|
|
15447
15777
|
for (const shard of finalShards) {
|
|
15448
|
-
|
|
15778
|
+
writeFileSync11(shardFilePath(pDir, shard.id), JSON.stringify(shard, null, 2), "utf8");
|
|
15449
15779
|
}
|
|
15450
15780
|
}
|
|
15451
15781
|
const index = {
|
|
@@ -15455,12 +15785,12 @@ function buildTreeIndex(store, memoryDir, config = {}) {
|
|
|
15455
15785
|
totalMemories: totalIndexMemories,
|
|
15456
15786
|
builtAt: nowIso3()
|
|
15457
15787
|
};
|
|
15458
|
-
|
|
15788
|
+
writeFileSync11(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(index, null, 2), "utf8");
|
|
15459
15789
|
return index;
|
|
15460
15790
|
}
|
|
15461
15791
|
function loadTreeIndex(memoryDir) {
|
|
15462
15792
|
const path = globalIndexFilePath(indexDir(memoryDir));
|
|
15463
|
-
if (!
|
|
15793
|
+
if (!existsSync24(path))
|
|
15464
15794
|
return null;
|
|
15465
15795
|
try {
|
|
15466
15796
|
const data = JSON.parse(readFileSync20(path, "utf8"));
|
|
@@ -15569,7 +15899,7 @@ function searchTree(index, options) {
|
|
|
15569
15899
|
}
|
|
15570
15900
|
}
|
|
15571
15901
|
results.sort((a, b) => b.score - a.score);
|
|
15572
|
-
const paginated = paginateResults(results, options.page ?? 1, options.pageSize ?? 10);
|
|
15902
|
+
const paginated = paginateResults(results, options.page ?? 1, options.pageSize ?? options.maxNodes ?? 10);
|
|
15573
15903
|
return {
|
|
15574
15904
|
nodes: paginated,
|
|
15575
15905
|
memories: [],
|
|
@@ -15608,7 +15938,7 @@ __export(exports_vector, {
|
|
|
15608
15938
|
saveIndex: () => saveIndex,
|
|
15609
15939
|
termFrequencies: () => termFrequencies
|
|
15610
15940
|
});
|
|
15611
|
-
import { existsSync as
|
|
15941
|
+
import { existsSync as existsSync25, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14 } from "node:fs";
|
|
15612
15942
|
import { join as join22 } from "node:path";
|
|
15613
15943
|
function indexFilePath(memoryDir) {
|
|
15614
15944
|
return join22(memoryDir, "index.json");
|
|
@@ -15658,13 +15988,13 @@ function rebuildIndex(store) {
|
|
|
15658
15988
|
return index;
|
|
15659
15989
|
}
|
|
15660
15990
|
function saveIndex(index, memoryDir) {
|
|
15661
|
-
if (!
|
|
15662
|
-
|
|
15663
|
-
|
|
15991
|
+
if (!existsSync25(memoryDir))
|
|
15992
|
+
mkdirSync14(memoryDir, { recursive: true });
|
|
15993
|
+
writeFileSync12(indexFilePath(memoryDir), JSON.stringify(index), "utf8");
|
|
15664
15994
|
}
|
|
15665
15995
|
function loadIndex(memoryDir) {
|
|
15666
15996
|
const p = indexFilePath(memoryDir);
|
|
15667
|
-
if (!
|
|
15997
|
+
if (!existsSync25(p))
|
|
15668
15998
|
return null;
|
|
15669
15999
|
try {
|
|
15670
16000
|
const parsed = JSON.parse(readFileSync21(p, "utf8"));
|
|
@@ -15739,7 +16069,7 @@ var init_vector = __esm(() => {
|
|
|
15739
16069
|
});
|
|
15740
16070
|
|
|
15741
16071
|
// src/pageindex/engine.ts
|
|
15742
|
-
import { existsSync as
|
|
16072
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync15, readFileSync as readFileSync22, writeFileSync as writeFileSync13, rmSync as rmSync2, readdirSync as readdirSync9 } from "node:fs";
|
|
15743
16073
|
import { join as join23 } from "node:path";
|
|
15744
16074
|
function slugify2(text) {
|
|
15745
16075
|
return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 50);
|
|
@@ -15818,8 +16148,8 @@ function buildPageIndex(content, options) {
|
|
|
15818
16148
|
};
|
|
15819
16149
|
if (options.memoryDir && !options.dryRun) {
|
|
15820
16150
|
const dir = join23(options.memoryDir, "pageindex", project);
|
|
15821
|
-
|
|
15822
|
-
|
|
16151
|
+
mkdirSync15(dir, { recursive: true });
|
|
16152
|
+
writeFileSync13(join23(dir, `${indexId}.json`), JSON.stringify(doc, null, 2), "utf8");
|
|
15823
16153
|
}
|
|
15824
16154
|
return doc;
|
|
15825
16155
|
}
|
|
@@ -15884,7 +16214,7 @@ function searchPageIndex(doc, options) {
|
|
|
15884
16214
|
}
|
|
15885
16215
|
function loadPageIndex(memoryDir, project, indexId) {
|
|
15886
16216
|
const filePath = join23(memoryDir, "pageindex", project, `${indexId}.json`);
|
|
15887
|
-
if (!
|
|
16217
|
+
if (!existsSync26(filePath))
|
|
15888
16218
|
return null;
|
|
15889
16219
|
try {
|
|
15890
16220
|
return JSON.parse(readFileSync22(filePath, "utf8"));
|
|
@@ -15894,13 +16224,13 @@ function loadPageIndex(memoryDir, project, indexId) {
|
|
|
15894
16224
|
}
|
|
15895
16225
|
function listPageIndexes(memoryDir, project) {
|
|
15896
16226
|
const base = join23(memoryDir, "pageindex");
|
|
15897
|
-
if (!
|
|
16227
|
+
if (!existsSync26(base))
|
|
15898
16228
|
return [];
|
|
15899
16229
|
const results = [];
|
|
15900
16230
|
const projects = project ? [project] : readdirSync9(base);
|
|
15901
16231
|
for (const p of projects) {
|
|
15902
16232
|
const pDir = join23(base, p);
|
|
15903
|
-
if (!
|
|
16233
|
+
if (!existsSync26(pDir))
|
|
15904
16234
|
continue;
|
|
15905
16235
|
for (const f of readdirSync9(pDir)) {
|
|
15906
16236
|
if (f.endsWith(".json")) {
|
|
@@ -15914,7 +16244,7 @@ function listPageIndexes(memoryDir, project) {
|
|
|
15914
16244
|
}
|
|
15915
16245
|
function deletePageIndex(memoryDir, project, indexId) {
|
|
15916
16246
|
const base = join23(memoryDir, "pageindex");
|
|
15917
|
-
if (!
|
|
16247
|
+
if (!existsSync26(base))
|
|
15918
16248
|
return { deletedCount: 0 };
|
|
15919
16249
|
let count = 0;
|
|
15920
16250
|
if (!project && !indexId) {
|
|
@@ -15923,13 +16253,13 @@ function deletePageIndex(memoryDir, project, indexId) {
|
|
|
15923
16253
|
}
|
|
15924
16254
|
if (project && !indexId) {
|
|
15925
16255
|
const pDir = join23(base, project);
|
|
15926
|
-
if (
|
|
16256
|
+
if (existsSync26(pDir)) {
|
|
15927
16257
|
rmSync2(pDir, { recursive: true, force: true });
|
|
15928
16258
|
count++;
|
|
15929
16259
|
}
|
|
15930
16260
|
} else if (project && indexId) {
|
|
15931
16261
|
const file = join23(base, project, `${indexId}.json`);
|
|
15932
|
-
if (
|
|
16262
|
+
if (existsSync26(file)) {
|
|
15933
16263
|
rmSync2(file, { force: true });
|
|
15934
16264
|
count++;
|
|
15935
16265
|
}
|
|
@@ -15942,13 +16272,13 @@ var init_engine2 = __esm(() => {
|
|
|
15942
16272
|
});
|
|
15943
16273
|
|
|
15944
16274
|
// src/retrieval/engine.ts
|
|
15945
|
-
import { existsSync as
|
|
16275
|
+
import { existsSync as existsSync27 } from "node:fs";
|
|
15946
16276
|
import { join as join24 } from "node:path";
|
|
15947
16277
|
|
|
15948
16278
|
class RetrievalEngine {
|
|
15949
16279
|
static search(store, memoryDir, query, options = {}) {
|
|
15950
16280
|
const mode = options.mode ?? "auto";
|
|
15951
|
-
if (mode === "pageindex" || options.docPath &&
|
|
16281
|
+
if (mode === "pageindex" || options.docPath && existsSync27(options.docPath)) {
|
|
15952
16282
|
try {
|
|
15953
16283
|
const docs = listPageIndexes(memoryDir, options.project);
|
|
15954
16284
|
if (docs.length > 0) {
|
|
@@ -15976,7 +16306,7 @@ class RetrievalEngine {
|
|
|
15976
16306
|
} catch {}
|
|
15977
16307
|
}
|
|
15978
16308
|
const treeDir = join24(memoryDir, "tree");
|
|
15979
|
-
const hasTree =
|
|
16309
|
+
const hasTree = existsSync27(treeDir);
|
|
15980
16310
|
const allEntries = list(store);
|
|
15981
16311
|
if (mode === "tree" || mode === "auto" && hasTree && allEntries.length >= 500) {
|
|
15982
16312
|
try {
|
|
@@ -16014,7 +16344,7 @@ class RetrievalEngine {
|
|
|
16014
16344
|
} catch {}
|
|
16015
16345
|
}
|
|
16016
16346
|
const vecPath = indexFilePath(memoryDir);
|
|
16017
|
-
const hasVec =
|
|
16347
|
+
const hasVec = existsSync27(vecPath);
|
|
16018
16348
|
if (mode === "hybrid" || mode === "auto" && hasVec && allEntries.length > 100) {
|
|
16019
16349
|
try {
|
|
16020
16350
|
const hybridResults = hybridSearch(store, memoryDir, query, {
|
|
@@ -16133,14 +16463,29 @@ __export(exports_ui, {
|
|
|
16133
16463
|
});
|
|
16134
16464
|
import { createServer } from "node:http";
|
|
16135
16465
|
function startUiServer(opts) {
|
|
16136
|
-
return new Promise((
|
|
16466
|
+
return new Promise((resolve3, reject2) => {
|
|
16137
16467
|
let currentPort = opts.port ?? 2222;
|
|
16138
16468
|
const server = createServer(async (req, res) => {
|
|
16139
16469
|
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
16140
16470
|
const pathname = url.pathname;
|
|
16141
|
-
res.setHeader("
|
|
16471
|
+
res.setHeader("X-Content-Type-Options", "nosniff");
|
|
16472
|
+
res.setHeader("X-Frame-Options", "DENY");
|
|
16473
|
+
res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
|
|
16474
|
+
res.setHeader("Content-Security-Policy", "default-src 'self' 'unsafe-inline' data: https://fonts.googleapis.com https://fonts.gstatic.com; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com data:;");
|
|
16475
|
+
const origin = req.headers.origin;
|
|
16476
|
+
const isLocalOrigin = !origin || /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(origin) || origin === "null";
|
|
16477
|
+
if (origin && isLocalOrigin) {
|
|
16478
|
+
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
16479
|
+
} else if (!origin) {
|
|
16480
|
+
res.setHeader("Access-Control-Allow-Origin", `http://localhost:${currentPort}`);
|
|
16481
|
+
}
|
|
16142
16482
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
16143
16483
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
16484
|
+
if (req.method === "POST" && !isLocalOrigin) {
|
|
16485
|
+
res.writeHead(403, { "Content-Type": "application/json" });
|
|
16486
|
+
res.end(JSON.stringify({ error: "Forbidden: Cross-Origin Request Blocked" }));
|
|
16487
|
+
return;
|
|
16488
|
+
}
|
|
16144
16489
|
if (req.method === "OPTIONS") {
|
|
16145
16490
|
res.writeHead(204);
|
|
16146
16491
|
res.end();
|
|
@@ -16400,15 +16745,15 @@ function startUiServer(opts) {
|
|
|
16400
16745
|
server.on("error", (err) => {
|
|
16401
16746
|
if (err.code === "EADDRINUSE" && !opts.port) {
|
|
16402
16747
|
currentPort++;
|
|
16403
|
-
server.listen(currentPort);
|
|
16748
|
+
server.listen(currentPort, "127.0.0.1");
|
|
16404
16749
|
} else {
|
|
16405
16750
|
reject2(err);
|
|
16406
16751
|
}
|
|
16407
16752
|
});
|
|
16408
|
-
server.listen(currentPort, () => {
|
|
16753
|
+
server.listen(currentPort, "127.0.0.1", () => {
|
|
16409
16754
|
const addr = server.address();
|
|
16410
16755
|
const actualPort = typeof addr === "object" && addr ? addr.port : currentPort;
|
|
16411
|
-
|
|
16756
|
+
resolve3({
|
|
16412
16757
|
port: actualPort,
|
|
16413
16758
|
close: () => server.close()
|
|
16414
16759
|
});
|
|
@@ -16416,12 +16761,21 @@ function startUiServer(opts) {
|
|
|
16416
16761
|
});
|
|
16417
16762
|
}
|
|
16418
16763
|
function parseJsonBody(req) {
|
|
16419
|
-
return new Promise((
|
|
16764
|
+
return new Promise((resolve3, reject2) => {
|
|
16420
16765
|
let data = "";
|
|
16421
|
-
|
|
16766
|
+
let byteLength = 0;
|
|
16767
|
+
req.on("data", (chunk) => {
|
|
16768
|
+
byteLength += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
|
|
16769
|
+
if (byteLength > MAX_BODY_SIZE) {
|
|
16770
|
+
req.destroy();
|
|
16771
|
+
reject2(new Error("Payload too large: request body exceeds 1MB limit"));
|
|
16772
|
+
return;
|
|
16773
|
+
}
|
|
16774
|
+
data += chunk;
|
|
16775
|
+
});
|
|
16422
16776
|
req.on("end", () => {
|
|
16423
16777
|
try {
|
|
16424
|
-
|
|
16778
|
+
resolve3(data ? JSON.parse(data) : {});
|
|
16425
16779
|
} catch (e) {
|
|
16426
16780
|
reject2(e);
|
|
16427
16781
|
}
|
|
@@ -16435,7 +16789,7 @@ function exportStandaloneHtml(store) {
|
|
|
16435
16789
|
return EMBEDDED_HTML.replace("</head>", `${script}
|
|
16436
16790
|
</head>`);
|
|
16437
16791
|
}
|
|
16438
|
-
var EMBEDDED_HTML = `<!DOCTYPE html>
|
|
16792
|
+
var MAX_BODY_SIZE, EMBEDDED_HTML = `<!DOCTYPE html>
|
|
16439
16793
|
<html lang="en">
|
|
16440
16794
|
<head>
|
|
16441
16795
|
<meta charset="UTF-8">
|
|
@@ -17434,6 +17788,7 @@ var init_ui = __esm(() => {
|
|
|
17434
17788
|
init_retrieval2();
|
|
17435
17789
|
init_schema();
|
|
17436
17790
|
init_snapshot();
|
|
17791
|
+
MAX_BODY_SIZE = 1024 * 1024;
|
|
17437
17792
|
});
|
|
17438
17793
|
|
|
17439
17794
|
// node_modules/zod/v4/core/core.js
|
|
@@ -24287,7 +24642,7 @@ class Protocol {
|
|
|
24287
24642
|
return;
|
|
24288
24643
|
}
|
|
24289
24644
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1000;
|
|
24290
|
-
await new Promise((
|
|
24645
|
+
await new Promise((resolve3) => setTimeout(resolve3, pollInterval));
|
|
24291
24646
|
options?.signal?.throwIfAborted();
|
|
24292
24647
|
}
|
|
24293
24648
|
} catch (error2) {
|
|
@@ -24299,7 +24654,7 @@ class Protocol {
|
|
|
24299
24654
|
}
|
|
24300
24655
|
request(request, resultSchema, options) {
|
|
24301
24656
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
24302
|
-
return new Promise((
|
|
24657
|
+
return new Promise((resolve3, reject2) => {
|
|
24303
24658
|
const earlyReject = (error2) => {
|
|
24304
24659
|
reject2(error2);
|
|
24305
24660
|
};
|
|
@@ -24377,7 +24732,7 @@ class Protocol {
|
|
|
24377
24732
|
if (!parseResult.success) {
|
|
24378
24733
|
reject2(parseResult.error);
|
|
24379
24734
|
} else {
|
|
24380
|
-
|
|
24735
|
+
resolve3(parseResult.data);
|
|
24381
24736
|
}
|
|
24382
24737
|
} catch (error2) {
|
|
24383
24738
|
reject2(error2);
|
|
@@ -24568,12 +24923,12 @@ class Protocol {
|
|
|
24568
24923
|
interval = task.pollInterval;
|
|
24569
24924
|
}
|
|
24570
24925
|
} catch {}
|
|
24571
|
-
return new Promise((
|
|
24926
|
+
return new Promise((resolve3, reject2) => {
|
|
24572
24927
|
if (signal.aborted) {
|
|
24573
24928
|
reject2(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
24574
24929
|
return;
|
|
24575
24930
|
}
|
|
24576
|
-
const timeoutId = setTimeout(
|
|
24931
|
+
const timeoutId = setTimeout(resolve3, interval);
|
|
24577
24932
|
signal.addEventListener("abort", () => {
|
|
24578
24933
|
clearTimeout(timeoutId);
|
|
24579
24934
|
reject2(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -25545,12 +25900,12 @@ class StdioServerTransport {
|
|
|
25545
25900
|
this.onclose?.();
|
|
25546
25901
|
}
|
|
25547
25902
|
send(message) {
|
|
25548
|
-
return new Promise((
|
|
25903
|
+
return new Promise((resolve3) => {
|
|
25549
25904
|
const json2 = serializeMessage(message);
|
|
25550
25905
|
if (this._stdout.write(json2)) {
|
|
25551
|
-
|
|
25906
|
+
resolve3();
|
|
25552
25907
|
} else {
|
|
25553
|
-
this._stdout.once("drain",
|
|
25908
|
+
this._stdout.once("drain", resolve3);
|
|
25554
25909
|
}
|
|
25555
25910
|
});
|
|
25556
25911
|
}
|
|
@@ -25685,7 +26040,7 @@ var init_loops = __esm(() => {
|
|
|
25685
26040
|
});
|
|
25686
26041
|
|
|
25687
26042
|
// src/distill.ts
|
|
25688
|
-
import { existsSync as
|
|
26043
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync16, writeFileSync as writeFileSync14 } from "node:fs";
|
|
25689
26044
|
import { join as join25 } from "node:path";
|
|
25690
26045
|
function fixTokens(e) {
|
|
25691
26046
|
const bag = tokenBag(e.title, 2);
|
|
@@ -25707,7 +26062,7 @@ function distillSkills(store, workspaceRoot, options = {}) {
|
|
|
25707
26062
|
const slug = slugifyId(topic.join("-") || "skill");
|
|
25708
26063
|
const dir = join25(skillsDir, slug);
|
|
25709
26064
|
const memberIds = cluster.map((e) => e.id);
|
|
25710
|
-
if (
|
|
26065
|
+
if (existsSync28(dir)) {
|
|
25711
26066
|
report.skippedExisting.push({ slug, members: memberIds });
|
|
25712
26067
|
continue;
|
|
25713
26068
|
}
|
|
@@ -25717,8 +26072,8 @@ function distillSkills(store, workspaceRoot, options = {}) {
|
|
|
25717
26072
|
throw new Error(`Secret detected in generated SKILL.md for '${slug}': ${secrets.join(", ")}`);
|
|
25718
26073
|
}
|
|
25719
26074
|
if (!options.dryRun) {
|
|
25720
|
-
|
|
25721
|
-
|
|
26075
|
+
mkdirSync16(dir, { recursive: true });
|
|
26076
|
+
writeFileSync14(join25(dir, "SKILL.md"), md, "utf8");
|
|
25722
26077
|
}
|
|
25723
26078
|
report.created.push({ slug, path: join25(dir, "SKILL.md"), members: memberIds });
|
|
25724
26079
|
}
|
|
@@ -25762,18 +26117,18 @@ var init_distill = __esm(() => {
|
|
|
25762
26117
|
// src/verify.ts
|
|
25763
26118
|
import { execFile } from "node:child_process";
|
|
25764
26119
|
function runCommand(command, cwd, timeoutSec) {
|
|
25765
|
-
return new Promise((
|
|
26120
|
+
return new Promise((resolve3) => {
|
|
25766
26121
|
execFile("/bin/sh", ["-c", command], { cwd, timeout: timeoutSec * 1000, killSignal: "SIGKILL", maxBuffer: 4 * 1024 * 1024 }, (err, stdout, stderr) => {
|
|
25767
26122
|
if (!err) {
|
|
25768
|
-
|
|
26123
|
+
resolve3({ ok: true, ran: true, exitCode: 0, stdout: String(stdout), stderr: String(stderr), message: "command exited 0" });
|
|
25769
26124
|
return;
|
|
25770
26125
|
}
|
|
25771
26126
|
const e = err;
|
|
25772
26127
|
if (e.killed) {
|
|
25773
|
-
|
|
26128
|
+
resolve3({ ok: false, ran: true, timedOut: true, stdout: String(stdout), stderr: String(stderr), message: `timed out after ${timeoutSec}s` });
|
|
25774
26129
|
return;
|
|
25775
26130
|
}
|
|
25776
|
-
|
|
26131
|
+
resolve3({
|
|
25777
26132
|
ok: false,
|
|
25778
26133
|
ran: true,
|
|
25779
26134
|
exitCode: typeof e.code === "number" ? e.code : -1,
|
|
@@ -26058,14 +26413,14 @@ var init_schema2 = __esm(() => {
|
|
|
26058
26413
|
});
|
|
26059
26414
|
|
|
26060
26415
|
// src/settings/loader.ts
|
|
26061
|
-
import { existsSync as
|
|
26416
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync17, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
|
|
26062
26417
|
import { join as join26 } from "node:path";
|
|
26063
26418
|
function getSettingsFilePath(memoryDir) {
|
|
26064
26419
|
return join26(memoryDir, "settings.json");
|
|
26065
26420
|
}
|
|
26066
26421
|
function loadSettings(memoryDir) {
|
|
26067
26422
|
const filePath = getSettingsFilePath(memoryDir);
|
|
26068
|
-
if (!
|
|
26423
|
+
if (!existsSync29(filePath)) {
|
|
26069
26424
|
return {
|
|
26070
26425
|
version: 1,
|
|
26071
26426
|
global: JSON.parse(JSON.stringify(DEFAULT_SETTINGS)),
|
|
@@ -26089,9 +26444,9 @@ function loadSettings(memoryDir) {
|
|
|
26089
26444
|
}
|
|
26090
26445
|
}
|
|
26091
26446
|
function saveSettings(store, memoryDir) {
|
|
26092
|
-
|
|
26447
|
+
mkdirSync17(memoryDir, { recursive: true });
|
|
26093
26448
|
const filePath = getSettingsFilePath(memoryDir);
|
|
26094
|
-
|
|
26449
|
+
writeFileSync15(filePath, JSON.stringify(store, null, 2), "utf8");
|
|
26095
26450
|
}
|
|
26096
26451
|
function getSettings(memoryDir) {
|
|
26097
26452
|
return loadSettings(memoryDir).global;
|
|
@@ -26220,7 +26575,7 @@ async function runMcpServer() {
|
|
|
26220
26575
|
}
|
|
26221
26576
|
return { activeStore: store, activeMemoryDir: memoryDir, activeRoot: root };
|
|
26222
26577
|
}
|
|
26223
|
-
const server = new Server({ name: "musememory", version: "1.
|
|
26578
|
+
const server = new Server({ name: "musememory", version: "1.6.0" }, {
|
|
26224
26579
|
capabilities: { tools: {}, logging: {} },
|
|
26225
26580
|
instructions: `MUSE MEMORY PROTOCOL:
|
|
26226
26581
|
You are equipped with Muse Memory, an autonomous persistent cognitive memory system.
|
|
@@ -26650,6 +27005,14 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26650
27005
|
properties: {}
|
|
26651
27006
|
}
|
|
26652
27007
|
},
|
|
27008
|
+
{
|
|
27009
|
+
name: "graph_index",
|
|
27010
|
+
description: "Index AST symbols from the project's CodeGraph/Graphify provider and cache in .memory/",
|
|
27011
|
+
inputSchema: {
|
|
27012
|
+
type: "object",
|
|
27013
|
+
properties: {}
|
|
27014
|
+
}
|
|
27015
|
+
},
|
|
26653
27016
|
{
|
|
26654
27017
|
name: "memory_tree_search",
|
|
26655
27018
|
description: "Hierarchical tree-indexed reasoning search across partitioned memory shards",
|
|
@@ -26806,22 +27169,20 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26806
27169
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
26807
27170
|
const { name, arguments: args } = request.params;
|
|
26808
27171
|
const a = args ?? {};
|
|
27172
|
+
const { activeStore, activeMemoryDir, activeRoot } = resolveStoreForRequest(a);
|
|
26809
27173
|
try {
|
|
26810
27174
|
switch (name) {
|
|
26811
27175
|
case "memory_read": {
|
|
26812
|
-
const { activeStore } = resolveStoreForRequest(a);
|
|
26813
27176
|
const entry = get2(activeStore, String(a.id));
|
|
26814
27177
|
if (!entry)
|
|
26815
27178
|
return toolError(`no entry with id ${a.id}`);
|
|
26816
27179
|
return toolResult(entry);
|
|
26817
27180
|
}
|
|
26818
27181
|
case "get_context": {
|
|
26819
|
-
const { activeStore, activeMemoryDir } = resolveStoreForRequest(a);
|
|
26820
27182
|
const queryStr = String(a.query ?? "");
|
|
26821
27183
|
if (queryStr && activeMemoryDir) {
|
|
26822
27184
|
try {
|
|
26823
|
-
|
|
26824
|
-
updateSessionHandoff2(activeMemoryDir, {
|
|
27185
|
+
updateSessionHandoff(activeMemoryDir, {
|
|
26825
27186
|
status: "IN-PROGRESS",
|
|
26826
27187
|
lastQuery: queryStr,
|
|
26827
27188
|
agent: a.agent ? String(a.agent) : process.env.AGENT_NAME || "AI Assistant",
|
|
@@ -26848,10 +27209,8 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26848
27209
|
});
|
|
26849
27210
|
}
|
|
26850
27211
|
case "memory_checkpoint": {
|
|
26851
|
-
const { activeMemoryDir } = resolveStoreForRequest(a);
|
|
26852
27212
|
try {
|
|
26853
|
-
const
|
|
26854
|
-
const handoff = updateSessionHandoff2(activeMemoryDir, {
|
|
27213
|
+
const handoff = updateSessionHandoff(activeMemoryDir, {
|
|
26855
27214
|
status: a.status ? String(a.status).toUpperCase() : "IN-PROGRESS",
|
|
26856
27215
|
task: a.task ? String(a.task) : undefined,
|
|
26857
27216
|
agent: a.agent ? String(a.agent) : process.env.AGENT_NAME || "AI Agent",
|
|
@@ -26865,7 +27224,6 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26865
27224
|
case "memory_current":
|
|
26866
27225
|
case "memory_get_constraints":
|
|
26867
27226
|
case "memory_set_constraints": {
|
|
26868
|
-
const { activeMemoryDir, activeRoot, activeStore } = resolveStoreForRequest(a);
|
|
26869
27227
|
const action = a.action || (name === "memory_set_constraints" ? "append" : "get");
|
|
26870
27228
|
if (action === "append" || a.constraint) {
|
|
26871
27229
|
const text = String(a.constraint || a.text || "");
|
|
@@ -26881,7 +27239,6 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26881
27239
|
}
|
|
26882
27240
|
case "memory_recall":
|
|
26883
27241
|
case "search": {
|
|
26884
|
-
const { activeStore, activeMemoryDir } = resolveStoreForRequest(a);
|
|
26885
27242
|
const mode = a.hybrid === true ? "hybrid" : a.tree === true ? "tree" : "auto";
|
|
26886
27243
|
const res = RetrievalEngine.search(activeStore, activeMemoryDir, String(a.query), {
|
|
26887
27244
|
mode,
|
|
@@ -26902,7 +27259,6 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26902
27259
|
}
|
|
26903
27260
|
case "propose":
|
|
26904
27261
|
case "memory_capture": {
|
|
26905
|
-
const { activeStore, activeRoot, activeMemoryDir } = resolveStoreForRequest(a);
|
|
26906
27262
|
const projectName = a.project ? String(a.project) : basename(activeRoot) || "default";
|
|
26907
27263
|
try {
|
|
26908
27264
|
const entry = propose(activeStore, {
|
|
@@ -26920,8 +27276,7 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26920
27276
|
}
|
|
26921
27277
|
if (activeMemoryDir) {
|
|
26922
27278
|
try {
|
|
26923
|
-
|
|
26924
|
-
updateSessionHandoff2(activeMemoryDir, {
|
|
27279
|
+
updateSessionHandoff(activeMemoryDir, {
|
|
26925
27280
|
discoveries: [String(a.title || a.content || "")]
|
|
26926
27281
|
});
|
|
26927
27282
|
} catch {}
|
|
@@ -26932,7 +27287,7 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26932
27287
|
}
|
|
26933
27288
|
}
|
|
26934
27289
|
case "memory_harvest": {
|
|
26935
|
-
const created = harvestMemories(
|
|
27290
|
+
const created = harvestMemories(activeStore, {
|
|
26936
27291
|
text: String(a.text),
|
|
26937
27292
|
project: String(a.project),
|
|
26938
27293
|
confirmed: a.confirmed === true
|
|
@@ -26943,11 +27298,11 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26943
27298
|
const transcript = String(a.transcript);
|
|
26944
27299
|
const project = a.project ? String(a.project) : undefined;
|
|
26945
27300
|
const isConfirmed = a.confirmed === true;
|
|
26946
|
-
const res = importTranscript(
|
|
27301
|
+
const res = importTranscript(activeStore, transcript, { project, confirmed: isConfirmed });
|
|
26947
27302
|
return toolResult(res);
|
|
26948
27303
|
}
|
|
26949
27304
|
case "memory_confirm": {
|
|
26950
|
-
const entry = confirm(
|
|
27305
|
+
const entry = confirm(activeStore, String(a.id));
|
|
26951
27306
|
if (!entry)
|
|
26952
27307
|
return toolError(`could not confirm ${a.id} (not found or invalid status transition)`);
|
|
26953
27308
|
return toolResult(entry);
|
|
@@ -26957,26 +27312,26 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26957
27312
|
const newId = String(a.with ?? a.new_id ?? "");
|
|
26958
27313
|
if (!newId)
|
|
26959
27314
|
return toolError("memory_supersede requires 'with' or 'new_id' parameter");
|
|
26960
|
-
const entry = supersede(
|
|
27315
|
+
const entry = supersede(activeStore, oldId, newId);
|
|
26961
27316
|
if (!entry)
|
|
26962
27317
|
return toolError(`could not supersede ${oldId} with ${newId} (missing entry or target not confirmed)`);
|
|
26963
27318
|
return toolResult(entry);
|
|
26964
27319
|
}
|
|
26965
27320
|
case "memory_link": {
|
|
26966
27321
|
const related = Array.isArray(a.related) ? a.related.map(String) : [];
|
|
26967
|
-
const entry = link2(
|
|
27322
|
+
const entry = link2(activeStore, String(a.id), related);
|
|
26968
27323
|
if (!entry)
|
|
26969
27324
|
return toolError(`could not link ${a.id} (missing id or related id)`);
|
|
26970
27325
|
return toolResult(entry);
|
|
26971
27326
|
}
|
|
26972
27327
|
case "memory_mark_stale": {
|
|
26973
|
-
const entry = markStale(
|
|
27328
|
+
const entry = markStale(activeStore, String(a.id), a.reason ? String(a.reason) : undefined);
|
|
26974
27329
|
if (!entry)
|
|
26975
27330
|
return toolError(`no entry with id ${a.id}`);
|
|
26976
27331
|
return toolResult(entry);
|
|
26977
27332
|
}
|
|
26978
27333
|
case "memory_reject": {
|
|
26979
|
-
const entry = reject(
|
|
27334
|
+
const entry = reject(activeStore, String(a.id));
|
|
26980
27335
|
if (!entry)
|
|
26981
27336
|
return toolError(`no entry with id ${a.id}`);
|
|
26982
27337
|
return toolResult(entry);
|
|
@@ -26984,13 +27339,13 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26984
27339
|
case "memory_delete": {
|
|
26985
27340
|
const id = String(a.id);
|
|
26986
27341
|
const reason = a.reason ? String(a.reason) : undefined;
|
|
26987
|
-
const ok = deleteEntry(
|
|
27342
|
+
const ok = deleteEntry(activeStore, id, reason, "mcp_agent");
|
|
26988
27343
|
if (!ok)
|
|
26989
27344
|
return toolError(`no entry found with id ${id}`);
|
|
26990
27345
|
return toolResult({ success: true, deleted_id: id });
|
|
26991
27346
|
}
|
|
26992
27347
|
case "memory_audit": {
|
|
26993
|
-
const trail = getAuditTrail(
|
|
27348
|
+
const trail = getAuditTrail(activeMemoryDir, {
|
|
26994
27349
|
operation: a.operation ? String(a.operation) : undefined,
|
|
26995
27350
|
entryId: a.entry_id ? String(a.entry_id) : undefined,
|
|
26996
27351
|
limit: typeof a.limit === "number" ? a.limit : 50
|
|
@@ -26998,37 +27353,37 @@ You are equipped with Muse Memory, an autonomous persistent cognitive memory sys
|
|
|
26998
27353
|
return toolResult({ total: trail.length, entries: trail });
|
|
26999
27354
|
}
|
|
27000
27355
|
case "memory_export": {
|
|
27001
|
-
const snapshot = exportSnapshot(
|
|
27356
|
+
const snapshot = exportSnapshot(activeStore);
|
|
27002
27357
|
return toolResult(snapshot);
|
|
27003
27358
|
}
|
|
27004
27359
|
case "memory_import": {
|
|
27005
27360
|
const entries = a.entries ?? [];
|
|
27006
|
-
const res = importSnapshot(
|
|
27361
|
+
const res = importSnapshot(activeStore, { entries }, { overwrite: a.overwrite === true });
|
|
27007
27362
|
return toolResult(res);
|
|
27008
27363
|
}
|
|
27009
27364
|
case "confirm_fix": {
|
|
27010
|
-
const entry = get2(
|
|
27365
|
+
const entry = get2(activeStore, String(a.id));
|
|
27011
27366
|
if (!entry)
|
|
27012
27367
|
return toolError(`no entry with id ${a.id}`);
|
|
27013
27368
|
if (entry.status !== "disputed")
|
|
27014
27369
|
return toolError(`entry ${a.id} is not disputed`);
|
|
27015
|
-
const updated = confirm(
|
|
27370
|
+
const updated = confirm(activeStore, entry.id);
|
|
27016
27371
|
if (!updated)
|
|
27017
27372
|
return toolError(`no entry with id ${a.id}`);
|
|
27018
27373
|
if (a.resolution) {
|
|
27019
27374
|
updated.content = `${updated.content}
|
|
27020
27375
|
|
|
27021
27376
|
Resolution: ${String(a.resolution)}`;
|
|
27022
|
-
save(
|
|
27377
|
+
save(activeStore, updated);
|
|
27023
27378
|
}
|
|
27024
27379
|
return toolResult(updated);
|
|
27025
27380
|
}
|
|
27026
27381
|
case "record_session": {
|
|
27027
|
-
const { entry, sessionId } = recordSessionStart(
|
|
27382
|
+
const { entry, sessionId } = recordSessionStart(activeStore, String(a.project), a.note ? String(a.note) : undefined);
|
|
27028
27383
|
return toolResult({ ...entry, sessionId });
|
|
27029
27384
|
}
|
|
27030
27385
|
case "memory_validate": {
|
|
27031
|
-
const report = validateStore(
|
|
27386
|
+
const report = validateStore(activeStore);
|
|
27032
27387
|
return toolResult(report);
|
|
27033
27388
|
}
|
|
27034
27389
|
case "memory_core": {
|
|
@@ -27038,41 +27393,41 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27038
27393
|
}
|
|
27039
27394
|
try {
|
|
27040
27395
|
if (tier && a.set !== undefined) {
|
|
27041
|
-
const tiers = setCore(
|
|
27396
|
+
const tiers = setCore(activeMemoryDir, tier, String(a.set));
|
|
27042
27397
|
return toolResult({ tier, lines: tiers[tier] });
|
|
27043
27398
|
}
|
|
27044
27399
|
if (tier && a.remove === true) {
|
|
27045
|
-
const tiers = removeCore(
|
|
27400
|
+
const tiers = removeCore(activeMemoryDir, tier);
|
|
27046
27401
|
return toolResult({ tier, lines: tiers[tier] });
|
|
27047
27402
|
}
|
|
27048
27403
|
if (tier) {
|
|
27049
|
-
return toolResult({ tier, lines: readCore(
|
|
27404
|
+
return toolResult({ tier, lines: readCore(activeMemoryDir)[tier] });
|
|
27050
27405
|
}
|
|
27051
|
-
return toolResult(readCore(
|
|
27406
|
+
return toolResult(readCore(activeMemoryDir));
|
|
27052
27407
|
} catch (err) {
|
|
27053
27408
|
return toolError(err instanceof Error ? err.message : String(err));
|
|
27054
27409
|
}
|
|
27055
27410
|
}
|
|
27056
27411
|
case "memory_consolidate": {
|
|
27057
|
-
const report = consolidateScenes(
|
|
27412
|
+
const report = consolidateScenes(activeStore, {
|
|
27058
27413
|
project: a.project ? String(a.project) : undefined,
|
|
27059
27414
|
dryRun: a.dry_run === true
|
|
27060
27415
|
});
|
|
27061
27416
|
return toolResult(report);
|
|
27062
27417
|
}
|
|
27063
27418
|
case "memory_trace": {
|
|
27064
|
-
const node = traceGraph(
|
|
27419
|
+
const node = traceGraph(activeStore, String(a.id), typeof a.depth === "number" ? a.depth : 5);
|
|
27065
27420
|
if (!node)
|
|
27066
27421
|
return toolError(`no entry with id ${a.id}`);
|
|
27067
27422
|
return toolResult(node);
|
|
27068
27423
|
}
|
|
27069
27424
|
case "memory_loops": {
|
|
27070
|
-
const report = collectLoops(
|
|
27425
|
+
const report = collectLoops(activeStore, activeRoot, activeMemoryDir);
|
|
27071
27426
|
return toolResult(report);
|
|
27072
27427
|
}
|
|
27073
27428
|
case "memory_distill": {
|
|
27074
27429
|
try {
|
|
27075
|
-
const report = distillSkills(
|
|
27430
|
+
const report = distillSkills(activeStore, activeRoot, {
|
|
27076
27431
|
minCount: typeof a.min_count === "number" ? a.min_count : undefined,
|
|
27077
27432
|
dryRun: a.dry_run === true
|
|
27078
27433
|
});
|
|
@@ -27082,7 +27437,7 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27082
27437
|
}
|
|
27083
27438
|
}
|
|
27084
27439
|
case "memory_verify": {
|
|
27085
|
-
const result = await verifyEntry(
|
|
27440
|
+
const result = await verifyEntry(activeStore, activeRoot, activeMemoryDir, String(a.id), {
|
|
27086
27441
|
timeout: typeof a.timeout === "number" ? a.timeout : undefined
|
|
27087
27442
|
});
|
|
27088
27443
|
if (!result.ok)
|
|
@@ -27090,11 +27445,15 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27090
27445
|
return toolResult(result);
|
|
27091
27446
|
}
|
|
27092
27447
|
case "graph_status": {
|
|
27093
|
-
const status = getGraphStatus(
|
|
27448
|
+
const status = getGraphStatus(activeRoot);
|
|
27094
27449
|
return toolResult(status);
|
|
27095
27450
|
}
|
|
27451
|
+
case "graph_index": {
|
|
27452
|
+
const index = indexGraph(activeRoot, activeMemoryDir);
|
|
27453
|
+
return toolResult(index);
|
|
27454
|
+
}
|
|
27096
27455
|
case "memory_detect_providers": {
|
|
27097
|
-
const detected = detectProviders(
|
|
27456
|
+
const detected = detectProviders(activeRoot);
|
|
27098
27457
|
return toolResult(detected);
|
|
27099
27458
|
}
|
|
27100
27459
|
case "memory_detect_agents": {
|
|
@@ -27114,7 +27473,7 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27114
27473
|
}
|
|
27115
27474
|
case "memory_migrate": {
|
|
27116
27475
|
try {
|
|
27117
|
-
const report = await runMigration(
|
|
27476
|
+
const report = await runMigration(activeStore, activeMemoryDir, {
|
|
27118
27477
|
provider: a.provider ? String(a.provider) : undefined,
|
|
27119
27478
|
all: Boolean(a.all),
|
|
27120
27479
|
dryRun: Boolean(a.dry_run),
|
|
@@ -27128,7 +27487,7 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27128
27487
|
}
|
|
27129
27488
|
case "memory_get_user_profile": {
|
|
27130
27489
|
const isGlobal = a.global === true;
|
|
27131
|
-
const dir = isGlobal ? getGlobalMemoryDir() :
|
|
27490
|
+
const dir = isGlobal ? getGlobalMemoryDir() : activeMemoryDir;
|
|
27132
27491
|
const query = a.query ? String(a.query) : undefined;
|
|
27133
27492
|
const profile = getUserProfile(dir, { query });
|
|
27134
27493
|
return toolResult({ profile: profile ?? "No USER.md profile configured.", exists: Boolean(profile) });
|
|
@@ -27136,7 +27495,7 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27136
27495
|
case "memory_set_user_profile": {
|
|
27137
27496
|
try {
|
|
27138
27497
|
const isGlobal = a.global === true;
|
|
27139
|
-
const dir = isGlobal ? getGlobalMemoryDir() :
|
|
27498
|
+
const dir = isGlobal ? getGlobalMemoryDir() : activeMemoryDir;
|
|
27140
27499
|
setUserProfile(dir, String(a.content));
|
|
27141
27500
|
return toolResult({ success: true, message: `Updated USER.md in ${dir}` });
|
|
27142
27501
|
} catch (err) {
|
|
@@ -27155,9 +27514,9 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27155
27514
|
}
|
|
27156
27515
|
}
|
|
27157
27516
|
case "memory_tree_search": {
|
|
27158
|
-
let index = loadTreeIndex(
|
|
27517
|
+
let index = loadTreeIndex(activeMemoryDir);
|
|
27159
27518
|
if (!index) {
|
|
27160
|
-
index = buildTreeIndex(
|
|
27519
|
+
index = buildTreeIndex(activeStore, activeMemoryDir);
|
|
27161
27520
|
}
|
|
27162
27521
|
const res = searchTree(index, {
|
|
27163
27522
|
query: String(a.query),
|
|
@@ -27170,37 +27529,37 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27170
27529
|
return toolResult(res);
|
|
27171
27530
|
}
|
|
27172
27531
|
case "memory_wiki_get": {
|
|
27173
|
-
const page = getWikiPage(
|
|
27532
|
+
const page = getWikiPage(activeMemoryDir, String(a.slug), a.type ? String(a.type) : undefined);
|
|
27174
27533
|
if (!page)
|
|
27175
27534
|
return toolError(`Wiki page '${a.slug}' not found.`);
|
|
27176
27535
|
return toolResult(page);
|
|
27177
27536
|
}
|
|
27178
27537
|
case "memory_wiki_search": {
|
|
27179
|
-
const pages = listWikiPages(
|
|
27538
|
+
const pages = listWikiPages(activeMemoryDir, {
|
|
27180
27539
|
project: a.project ? String(a.project) : undefined,
|
|
27181
27540
|
type: a.type ? String(a.type) : undefined
|
|
27182
27541
|
});
|
|
27183
27542
|
return toolResult({ pages, count: pages.length });
|
|
27184
27543
|
}
|
|
27185
27544
|
case "memory_wiki_compile": {
|
|
27186
|
-
const res = compileWiki(
|
|
27545
|
+
const res = compileWiki(activeStore, activeMemoryDir, {
|
|
27187
27546
|
project: a.project ? String(a.project) : undefined,
|
|
27188
27547
|
dryRun: a.dry_run === true
|
|
27189
27548
|
});
|
|
27190
27549
|
return toolResult(res);
|
|
27191
27550
|
}
|
|
27192
27551
|
case "memory_entities_get": {
|
|
27193
|
-
const ent = findEntity(
|
|
27552
|
+
const ent = findEntity(activeMemoryDir, String(a.id));
|
|
27194
27553
|
if (!ent)
|
|
27195
27554
|
return toolError(`Entity '${a.id}' not found.`);
|
|
27196
27555
|
if (a.include_related === true) {
|
|
27197
|
-
const rel = findRelatedEntities(
|
|
27556
|
+
const rel = findRelatedEntities(activeMemoryDir, String(a.id));
|
|
27198
27557
|
return toolResult({ entity: ent, related: rel });
|
|
27199
27558
|
}
|
|
27200
27559
|
return toolResult(ent);
|
|
27201
27560
|
}
|
|
27202
27561
|
case "memory_entities_search": {
|
|
27203
|
-
let entities = loadEntities(
|
|
27562
|
+
let entities = loadEntities(activeMemoryDir);
|
|
27204
27563
|
if (a.type)
|
|
27205
27564
|
entities = entities.filter((e) => e.type === a.type);
|
|
27206
27565
|
if (a.project)
|
|
@@ -27214,7 +27573,7 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27214
27573
|
title: a.title ? String(a.title) : undefined,
|
|
27215
27574
|
maxDepth: typeof a.maxDepth === "number" ? a.maxDepth : undefined,
|
|
27216
27575
|
dryRun: a.dryRun === true,
|
|
27217
|
-
memoryDir
|
|
27576
|
+
memoryDir: activeMemoryDir
|
|
27218
27577
|
});
|
|
27219
27578
|
return toolResult(doc2);
|
|
27220
27579
|
} catch (err) {
|
|
@@ -27223,7 +27582,7 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27223
27582
|
}
|
|
27224
27583
|
case "memory_pageindex_search": {
|
|
27225
27584
|
const project = a.project ? String(a.project) : "default";
|
|
27226
|
-
const doc2 = loadPageIndex(
|
|
27585
|
+
const doc2 = loadPageIndex(activeMemoryDir, project, String(a.indexId));
|
|
27227
27586
|
if (!doc2)
|
|
27228
27587
|
return toolError(`PageIndex '${a.indexId}' not found for project '${project}'`);
|
|
27229
27588
|
const res = searchPageIndex(doc2, {
|
|
@@ -27236,13 +27595,13 @@ Resolution: ${String(a.resolution)}`;
|
|
|
27236
27595
|
}
|
|
27237
27596
|
case "memory_pageindex_import": {
|
|
27238
27597
|
const project = String(a.project);
|
|
27239
|
-
const doc2 = loadPageIndex(
|
|
27598
|
+
const doc2 = loadPageIndex(activeMemoryDir, project, String(a.indexId));
|
|
27240
27599
|
if (!doc2)
|
|
27241
27600
|
return toolError(`PageIndex '${a.indexId}' not found for project '${project}'`);
|
|
27242
27601
|
const search = searchPageIndex(doc2, { query: String(a.query), maxNodes: 5 });
|
|
27243
27602
|
const imported = [];
|
|
27244
27603
|
for (const item of search.results) {
|
|
27245
|
-
const entry = propose(
|
|
27604
|
+
const entry = propose(activeStore, {
|
|
27246
27605
|
project,
|
|
27247
27606
|
title: item.title,
|
|
27248
27607
|
content: `${item.summary}
|
|
@@ -27256,20 +27615,20 @@ Path: ${item.path}`,
|
|
|
27256
27615
|
return toolResult({ importedCount: imported.length, entries: imported });
|
|
27257
27616
|
}
|
|
27258
27617
|
case "memory_disconnect_pageindex": {
|
|
27259
|
-
const res = deletePageIndex(
|
|
27618
|
+
const res = deletePageIndex(activeMemoryDir, a.project ? String(a.project) : undefined, a.indexId ? String(a.indexId) : undefined);
|
|
27260
27619
|
return toolResult({ success: true, deletedIndexes: res.deletedCount });
|
|
27261
27620
|
}
|
|
27262
27621
|
case "memory_settings_get": {
|
|
27263
|
-
const settings2 = a.project ? getProjectSettings(
|
|
27622
|
+
const settings2 = a.project ? getProjectSettings(activeMemoryDir, String(a.project)) : getSettings(activeMemoryDir);
|
|
27264
27623
|
return toolResult(settings2);
|
|
27265
27624
|
}
|
|
27266
27625
|
case "memory_settings_set": {
|
|
27267
27626
|
try {
|
|
27268
27627
|
if (a.project) {
|
|
27269
|
-
const updated = setProjectSettings(
|
|
27628
|
+
const updated = setProjectSettings(activeMemoryDir, String(a.project), a.settings);
|
|
27270
27629
|
return toolResult(updated);
|
|
27271
27630
|
} else {
|
|
27272
|
-
const updated = setSettings(
|
|
27631
|
+
const updated = setSettings(activeMemoryDir, a.settings);
|
|
27273
27632
|
return toolResult(updated);
|
|
27274
27633
|
}
|
|
27275
27634
|
} catch (err) {
|
|
@@ -27286,9 +27645,9 @@ Path: ${item.path}`,
|
|
|
27286
27645
|
const transport = new StdioServerTransport;
|
|
27287
27646
|
await server.connect(transport);
|
|
27288
27647
|
process.stdin.resume();
|
|
27289
|
-
await new Promise((
|
|
27290
|
-
process.stdin.on("end", () =>
|
|
27291
|
-
process.stdin.on("close", () =>
|
|
27648
|
+
await new Promise((resolve3) => {
|
|
27649
|
+
process.stdin.on("end", () => resolve3());
|
|
27650
|
+
process.stdin.on("close", () => resolve3());
|
|
27292
27651
|
});
|
|
27293
27652
|
}
|
|
27294
27653
|
function toolResult(content) {
|
|
@@ -27309,7 +27668,7 @@ var init_mcp = __esm(() => {
|
|
|
27309
27668
|
init_root();
|
|
27310
27669
|
init_store();
|
|
27311
27670
|
init_retrieval();
|
|
27312
|
-
|
|
27671
|
+
init_governor();
|
|
27313
27672
|
init_consolidate();
|
|
27314
27673
|
init_trace();
|
|
27315
27674
|
init_loops();
|
|
@@ -27340,7 +27699,7 @@ __export(exports_daemon, {
|
|
|
27340
27699
|
startHub: () => startHub
|
|
27341
27700
|
});
|
|
27342
27701
|
import { createServer as createServer2 } from "node:http";
|
|
27343
|
-
import { existsSync as
|
|
27702
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
27344
27703
|
import { join as join27 } from "node:path";
|
|
27345
27704
|
import { watch } from "node:fs";
|
|
27346
27705
|
function startHub(port, memoryDir) {
|
|
@@ -27416,20 +27775,20 @@ data: ${JSON.stringify(event)}
|
|
|
27416
27775
|
}, DEBOUNCE_MS);
|
|
27417
27776
|
};
|
|
27418
27777
|
try {
|
|
27419
|
-
if (
|
|
27778
|
+
if (existsSync30(memoriesDir)) {
|
|
27420
27779
|
watchers.push(watch(memoriesDir, () => armDebounced("memory.changed")));
|
|
27421
27780
|
}
|
|
27422
27781
|
const currentMd = join27(memoryDir, "CURRENT.md");
|
|
27423
|
-
if (
|
|
27782
|
+
if (existsSync30(currentMd)) {
|
|
27424
27783
|
watchers.push(watch(currentMd, () => armDebounced("constraints.changed")));
|
|
27425
27784
|
}
|
|
27426
27785
|
} catch {}
|
|
27427
27786
|
}
|
|
27428
|
-
return new Promise((
|
|
27787
|
+
return new Promise((resolve3) => {
|
|
27429
27788
|
server.listen(port, () => {
|
|
27430
27789
|
const address = server.address();
|
|
27431
27790
|
const actualPort = typeof address === "object" && address ? address.port : port;
|
|
27432
|
-
|
|
27791
|
+
resolve3({
|
|
27433
27792
|
server,
|
|
27434
27793
|
port: actualPort,
|
|
27435
27794
|
url: `http://localhost:${actualPort}/events`,
|
|
@@ -27454,18 +27813,18 @@ var init_daemon = () => {};
|
|
|
27454
27813
|
|
|
27455
27814
|
// src/cli/ecosystem.ts
|
|
27456
27815
|
import { join as join28 } from "node:path";
|
|
27457
|
-
import { existsSync as
|
|
27816
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync18, writeFileSync as writeFileSync16, readFileSync as readFileSync24 } from "node:fs";
|
|
27458
27817
|
import { homedir as homedir6 } from "node:os";
|
|
27459
27818
|
function ensureProjectAgentInstructions(targetDir) {
|
|
27460
27819
|
const agentsMdPath = join28(targetDir, "AGENTS.md");
|
|
27461
|
-
if (
|
|
27820
|
+
if (existsSync31(agentsMdPath)) {
|
|
27462
27821
|
try {
|
|
27463
27822
|
const existing = readFileSync24(agentsMdPath, "utf8");
|
|
27464
27823
|
if (existing.includes("<!-- agentmemory:start -->")) {
|
|
27465
27824
|
const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
|
|
27466
|
-
|
|
27825
|
+
writeFileSync16(agentsMdPath, updated, "utf8");
|
|
27467
27826
|
} else if (!existing.includes("<!-- musememory:start -->") && !existing.includes("Muse Memory")) {
|
|
27468
|
-
|
|
27827
|
+
writeFileSync16(agentsMdPath, `${existing.trim()}
|
|
27469
27828
|
|
|
27470
27829
|
${MUSE_MEMORY_DIRECTIVE}
|
|
27471
27830
|
`, "utf8");
|
|
@@ -27476,7 +27835,7 @@ ${MUSE_MEMORY_DIRECTIVE}
|
|
|
27476
27835
|
|
|
27477
27836
|
${MUSE_MEMORY_DIRECTIVE}
|
|
27478
27837
|
`;
|
|
27479
|
-
|
|
27838
|
+
writeFileSync16(agentsMdPath, initialContent, "utf8");
|
|
27480
27839
|
}
|
|
27481
27840
|
}
|
|
27482
27841
|
async function handleInstallCommand({ positional, flags }) {
|
|
@@ -27484,15 +27843,15 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
27484
27843
|
const targetDir = positional[0] ? join28(process.cwd(), positional[0]) : process.cwd();
|
|
27485
27844
|
const memoryDir = isGlobal ? getGlobalMemoryDir() : join28(targetDir, ".memory");
|
|
27486
27845
|
const globalDir = getGlobalMemoryDir();
|
|
27487
|
-
|
|
27488
|
-
|
|
27846
|
+
mkdirSync18(join28(memoryDir, "memories"), { recursive: true });
|
|
27847
|
+
mkdirSync18(join28(globalDir, "memories"), { recursive: true });
|
|
27489
27848
|
const currentPath = join28(memoryDir, "CURRENT.md");
|
|
27490
|
-
if (!
|
|
27491
|
-
|
|
27849
|
+
if (!existsSync31(currentPath)) {
|
|
27850
|
+
writeFileSync16(currentPath, `# Active Project Constraints
|
|
27492
27851
|
`, "utf8");
|
|
27493
27852
|
}
|
|
27494
27853
|
const globalUserPath = userFilePath(globalDir);
|
|
27495
|
-
if (!
|
|
27854
|
+
if (!existsSync31(globalUserPath)) {
|
|
27496
27855
|
const { promptSingleSelect: promptSingleSelect2 } = await Promise.resolve().then(() => (init_prompt(), exports_prompt));
|
|
27497
27856
|
const archetypeOptions = [
|
|
27498
27857
|
{ id: "developer", label: "Software Engineer / Developer", hint: "Code-first, direct, strict typing" },
|
|
@@ -27509,12 +27868,12 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
27509
27868
|
ensureProjectAgentInstructions(targetDir);
|
|
27510
27869
|
}
|
|
27511
27870
|
const globalAgentsMd = join28(homedir6(), ".agents", "AGENTS.md");
|
|
27512
|
-
if (
|
|
27871
|
+
if (existsSync31(globalAgentsMd)) {
|
|
27513
27872
|
try {
|
|
27514
27873
|
const existing = readFileSync24(globalAgentsMd, "utf8");
|
|
27515
27874
|
if (existing.includes("<!-- agentmemory:start -->")) {
|
|
27516
27875
|
const updated = existing.replace(/<!-- agentmemory:start -->[\s\S]*?<!-- agentmemory:end -->/, MUSE_MEMORY_DIRECTIVE);
|
|
27517
|
-
|
|
27876
|
+
writeFileSync16(globalAgentsMd, updated, "utf8");
|
|
27518
27877
|
}
|
|
27519
27878
|
} catch {}
|
|
27520
27879
|
}
|
|
@@ -27543,10 +27902,10 @@ async function handleInstallCommand({ positional, flags }) {
|
|
|
27543
27902
|
}
|
|
27544
27903
|
async function promptOrNotifyGitHook(targetDir, autoInstall = false) {
|
|
27545
27904
|
const gitDir = join28(targetDir, ".git");
|
|
27546
|
-
if (!
|
|
27905
|
+
if (!existsSync31(gitDir))
|
|
27547
27906
|
return false;
|
|
27548
27907
|
const hookPath = join28(gitDir, "hooks", "pre-commit");
|
|
27549
|
-
const isInstalled =
|
|
27908
|
+
const isInstalled = existsSync31(hookPath) && readFileSync24(hookPath, "utf8").includes("memory harvest-auto");
|
|
27550
27909
|
if (isInstalled)
|
|
27551
27910
|
return true;
|
|
27552
27911
|
if (autoInstall) {
|
|
@@ -27590,7 +27949,7 @@ async function handleUninstallCommand({ positional, flags }) {
|
|
|
27590
27949
|
}
|
|
27591
27950
|
if (purge) {
|
|
27592
27951
|
const ctx = requireRoot(flags);
|
|
27593
|
-
if (ctx &&
|
|
27952
|
+
if (ctx && existsSync31(ctx.memoryDir) && !dryRun) {
|
|
27594
27953
|
const { rmSync: rmSync3 } = await import("node:fs");
|
|
27595
27954
|
rmSync3(ctx.memoryDir, { recursive: true, force: true });
|
|
27596
27955
|
console.log(` [PURGED] Memory directory removed: ${ctx.memoryDir}`);
|
|
@@ -27606,10 +27965,10 @@ async function handleInitCommand({ positional, flags }) {
|
|
|
27606
27965
|
const targetDir = positional[0] ? join28(process.cwd(), positional[0]) : process.cwd();
|
|
27607
27966
|
const memoryDirName = flags["legacy"] === "true" ? ".musememory" : ".memory";
|
|
27608
27967
|
const memoryDir = isGlobal ? getGlobalMemoryDir() : join28(targetDir, memoryDirName);
|
|
27609
|
-
|
|
27968
|
+
mkdirSync18(join28(memoryDir, "memories"), { recursive: true });
|
|
27610
27969
|
const currentPath = join28(memoryDir, "CURRENT.md");
|
|
27611
|
-
if (!
|
|
27612
|
-
|
|
27970
|
+
if (!existsSync31(currentPath)) {
|
|
27971
|
+
writeFileSync16(currentPath, `# Active Project Constraints
|
|
27613
27972
|
`, "utf8");
|
|
27614
27973
|
}
|
|
27615
27974
|
if (!isGlobal) {
|
|
@@ -27800,7 +28159,7 @@ async function handleGraphCommand({ positional, flags }) {
|
|
|
27800
28159
|
const ctx = requireRoot(flags);
|
|
27801
28160
|
if (!ctx)
|
|
27802
28161
|
return 1;
|
|
27803
|
-
const sub = positional[0];
|
|
28162
|
+
const sub = positional[0] ?? "status";
|
|
27804
28163
|
if (sub === "status") {
|
|
27805
28164
|
const status = getGraphStatus(ctx.root);
|
|
27806
28165
|
console.log(`graph provider: ${status.provider}`);
|
|
@@ -27812,7 +28171,13 @@ async function handleGraphCommand({ positional, flags }) {
|
|
|
27812
28171
|
console.log(`symbols: ${status.symbolCount}`);
|
|
27813
28172
|
return 0;
|
|
27814
28173
|
}
|
|
27815
|
-
|
|
28174
|
+
if (sub === "index") {
|
|
28175
|
+
const index = indexGraph(ctx.root, ctx.memoryDir);
|
|
28176
|
+
console.log(`[AST Graph] Indexed ${index.symbolCount} symbols from provider "${index.provider}"`);
|
|
28177
|
+
console.log(`Cached symbol index at: ${ctx.memoryDir}/graph-symbols.json`);
|
|
28178
|
+
return 0;
|
|
28179
|
+
}
|
|
28180
|
+
return usageError("graph requires 'status' or 'index'");
|
|
27816
28181
|
}
|
|
27817
28182
|
async function handleMcpCommand() {
|
|
27818
28183
|
const { runMcpServer: runMcpServer2 } = await Promise.resolve().then(() => (init_mcp(), exports_mcp));
|
|
@@ -27850,7 +28215,7 @@ var init_ecosystem = __esm(() => {
|
|
|
27850
28215
|
});
|
|
27851
28216
|
|
|
27852
28217
|
// src/agentcontract.ts
|
|
27853
|
-
import { existsSync as
|
|
28218
|
+
import { existsSync as existsSync32 } from "node:fs";
|
|
27854
28219
|
import { join as join29 } from "node:path";
|
|
27855
28220
|
function parseAgentMemoryContract(markdown) {
|
|
27856
28221
|
if (!markdown || !markdown.startsWith("---"))
|
|
@@ -27883,7 +28248,7 @@ function parseAgentMemoryContract(markdown) {
|
|
|
27883
28248
|
function resolveAgentFile(nameOrPath, workspaceRoot) {
|
|
27884
28249
|
if (!nameOrPath)
|
|
27885
28250
|
return null;
|
|
27886
|
-
if (
|
|
28251
|
+
if (existsSync32(nameOrPath))
|
|
27887
28252
|
return nameOrPath;
|
|
27888
28253
|
const candidates = [
|
|
27889
28254
|
join29(workspaceRoot, ".agents", `${nameOrPath}.md`),
|
|
@@ -27893,7 +28258,7 @@ function resolveAgentFile(nameOrPath, workspaceRoot) {
|
|
|
27893
28258
|
if (home)
|
|
27894
28259
|
candidates.push(join29(home, ".config", "opencode", "agents", `${nameOrPath}.md`));
|
|
27895
28260
|
for (const c of candidates) {
|
|
27896
|
-
if (
|
|
28261
|
+
if (existsSync32(c))
|
|
27897
28262
|
return c;
|
|
27898
28263
|
}
|
|
27899
28264
|
return null;
|
|
@@ -27903,7 +28268,7 @@ var init_agentcontract = __esm(() => {
|
|
|
27903
28268
|
});
|
|
27904
28269
|
|
|
27905
28270
|
// src/cli/retrieval.ts
|
|
27906
|
-
import { existsSync as
|
|
28271
|
+
import { existsSync as existsSync33, readFileSync as readFileSync25 } from "node:fs";
|
|
27907
28272
|
import { join as join30 } from "node:path";
|
|
27908
28273
|
async function handleContextCommand({ positional, flags }) {
|
|
27909
28274
|
let agentTypes;
|
|
@@ -28008,6 +28373,7 @@ async function handleSearchCommand({ positional, flags }) {
|
|
|
28008
28373
|
const res = queryContext(ctx.store, positional[0], {
|
|
28009
28374
|
limit,
|
|
28010
28375
|
tokenBudget,
|
|
28376
|
+
project: flags["project"],
|
|
28011
28377
|
includeSuperseded: flags["include-superseded"] === "true",
|
|
28012
28378
|
type: flags["type"],
|
|
28013
28379
|
status: flags["status"],
|
|
@@ -28051,7 +28417,7 @@ async function handleHarvestCommand({ positional, flags }) {
|
|
|
28051
28417
|
const project = flags["project"];
|
|
28052
28418
|
if (!project)
|
|
28053
28419
|
return usageError("harvest requires --project");
|
|
28054
|
-
const rawText =
|
|
28420
|
+
const rawText = existsSync33(target) ? readFileSync25(target, "utf8") : target;
|
|
28055
28421
|
const created = harvestMemories(ctx.store, {
|
|
28056
28422
|
text: rawText,
|
|
28057
28423
|
project,
|
|
@@ -28088,7 +28454,7 @@ async function handleSearchTranscriptCommand({ positional, flags }) {
|
|
|
28088
28454
|
if (!query)
|
|
28089
28455
|
return usageError("search-transcript requires <query> [file.jsonl]");
|
|
28090
28456
|
const targetFile = filePath ? filePath.startsWith("/") ? filePath : join30(process.cwd(), filePath) : join30(process.cwd(), "transcript.jsonl");
|
|
28091
|
-
if (!
|
|
28457
|
+
if (!existsSync33(targetFile)) {
|
|
28092
28458
|
return fail(`error: transcript file not found: ${targetFile}`);
|
|
28093
28459
|
}
|
|
28094
28460
|
const windowSize = flags["window"] ? parseInt(flags["window"], 10) : 2;
|
|
@@ -28434,7 +28800,7 @@ function handleEntitiesCommand(parsed) {
|
|
|
28434
28800
|
if (!ctx)
|
|
28435
28801
|
return 1;
|
|
28436
28802
|
const memoryDir = ctx.memoryDir;
|
|
28437
|
-
const sub = parsed.positional[
|
|
28803
|
+
const sub = parsed.positional[0] ?? "list";
|
|
28438
28804
|
if (sub === "list" || sub === "ls") {
|
|
28439
28805
|
const type2 = parsed.flags.type;
|
|
28440
28806
|
const project = parsed.flags.project;
|
|
@@ -28455,7 +28821,7 @@ function handleEntitiesCommand(parsed) {
|
|
|
28455
28821
|
return 0;
|
|
28456
28822
|
}
|
|
28457
28823
|
if (sub === "show" || sub === "get") {
|
|
28458
|
-
const id = parsed.positional[
|
|
28824
|
+
const id = parsed.positional[1];
|
|
28459
28825
|
if (!id) {
|
|
28460
28826
|
console.error("Error: please specify an entity ID or name (e.g. `memory entities show nextjs`)");
|
|
28461
28827
|
return 2;
|
|
@@ -28469,7 +28835,7 @@ function handleEntitiesCommand(parsed) {
|
|
|
28469
28835
|
return 0;
|
|
28470
28836
|
}
|
|
28471
28837
|
if (sub === "related") {
|
|
28472
|
-
const id = parsed.positional[
|
|
28838
|
+
const id = parsed.positional[1];
|
|
28473
28839
|
if (!id) {
|
|
28474
28840
|
console.error("Error: please specify an entity ID or name (e.g. `memory entities related nextjs`)");
|
|
28475
28841
|
return 2;
|
|
@@ -28495,16 +28861,16 @@ var init_entities2 = __esm(() => {
|
|
|
28495
28861
|
});
|
|
28496
28862
|
|
|
28497
28863
|
// src/cli/settings.ts
|
|
28498
|
-
import { writeFileSync as
|
|
28864
|
+
import { writeFileSync as writeFileSync17, readFileSync as readFileSync26 } from "node:fs";
|
|
28499
28865
|
function handleSettingsCommand(parsed) {
|
|
28500
28866
|
const ctx = requireRoot(parsed.flags);
|
|
28501
28867
|
if (!ctx)
|
|
28502
28868
|
return 1;
|
|
28503
28869
|
const memoryDir = ctx.memoryDir;
|
|
28504
|
-
const sub = parsed.positional[
|
|
28870
|
+
const sub = parsed.positional[0] ?? "get";
|
|
28505
28871
|
const project = parsed.flags.project;
|
|
28506
28872
|
if (sub === "get") {
|
|
28507
|
-
const key = parsed.positional[
|
|
28873
|
+
const key = parsed.positional[1];
|
|
28508
28874
|
const settings2 = project ? getProjectSettings(memoryDir, project) : getSettings(memoryDir);
|
|
28509
28875
|
if (key) {
|
|
28510
28876
|
const parts = key.split(".");
|
|
@@ -28523,8 +28889,8 @@ function handleSettingsCommand(parsed) {
|
|
|
28523
28889
|
return 0;
|
|
28524
28890
|
}
|
|
28525
28891
|
if (sub === "set") {
|
|
28526
|
-
const key = parsed.positional[
|
|
28527
|
-
const rawVal = parsed.positional[
|
|
28892
|
+
const key = parsed.positional[1];
|
|
28893
|
+
const rawVal = parsed.positional[2];
|
|
28528
28894
|
if (!key || rawVal === undefined) {
|
|
28529
28895
|
console.error("Error: please specify key and value (e.g. `memory settings set retrieval.defaultMode tree`)");
|
|
28530
28896
|
return 2;
|
|
@@ -28577,7 +28943,7 @@ function handleSettingsCommand(parsed) {
|
|
|
28577
28943
|
const out = parsed.flags.out;
|
|
28578
28944
|
const json2 = exportSettings(memoryDir);
|
|
28579
28945
|
if (out) {
|
|
28580
|
-
|
|
28946
|
+
writeFileSync17(out, json2, "utf8");
|
|
28581
28947
|
console.log(`Exported settings to ${out}`);
|
|
28582
28948
|
} else {
|
|
28583
28949
|
console.log(json2);
|
|
@@ -28585,7 +28951,7 @@ function handleSettingsCommand(parsed) {
|
|
|
28585
28951
|
return 0;
|
|
28586
28952
|
}
|
|
28587
28953
|
if (sub === "import") {
|
|
28588
|
-
const file = parsed.positional[
|
|
28954
|
+
const file = parsed.positional[1];
|
|
28589
28955
|
if (!file) {
|
|
28590
28956
|
console.error("Error: please specify a JSON file to import (e.g. `memory settings import team-settings.json`)");
|
|
28591
28957
|
return 2;
|
|
@@ -28614,14 +28980,14 @@ var init_nudge = __esm(() => {
|
|
|
28614
28980
|
});
|
|
28615
28981
|
|
|
28616
28982
|
// src/routines.ts
|
|
28617
|
-
import { readFileSync as readFileSync27, existsSync as
|
|
28983
|
+
import { readFileSync as readFileSync27, existsSync as existsSync34 } from "node:fs";
|
|
28618
28984
|
import { join as join31 } from "node:path";
|
|
28619
28985
|
function routinesPath(memoryDir) {
|
|
28620
28986
|
return join31(memoryDir, "routines.yaml");
|
|
28621
28987
|
}
|
|
28622
28988
|
function loadRoutines(memoryDir) {
|
|
28623
28989
|
const p = routinesPath(memoryDir);
|
|
28624
|
-
if (!
|
|
28990
|
+
if (!existsSync34(p))
|
|
28625
28991
|
return { routines: {} };
|
|
28626
28992
|
const doc2 = yaml.load(readFileSync27(p, "utf8"), { schema: yaml.JSON_SCHEMA }) ?? {};
|
|
28627
28993
|
const routines = doc2.routines ?? {};
|
|
@@ -28661,7 +29027,7 @@ var init_routines = __esm(() => {
|
|
|
28661
29027
|
});
|
|
28662
29028
|
|
|
28663
29029
|
// src/cli/lifecycle.ts
|
|
28664
|
-
import { writeFileSync as
|
|
29030
|
+
import { writeFileSync as writeFileSync18, readFileSync as readFileSync28, existsSync as existsSync35 } from "node:fs";
|
|
28665
29031
|
async function handleProposeCommand({ positional, flags }) {
|
|
28666
29032
|
const ctx = requireRoot(flags);
|
|
28667
29033
|
if (!ctx)
|
|
@@ -28810,7 +29176,7 @@ async function handleExportCommand({ flags }) {
|
|
|
28810
29176
|
const snapshot = exportSnapshot(ctx.store);
|
|
28811
29177
|
const outPath = flags["out"];
|
|
28812
29178
|
if (outPath) {
|
|
28813
|
-
|
|
29179
|
+
writeFileSync18(outPath, JSON.stringify(snapshot, null, 2), "utf8");
|
|
28814
29180
|
console.log(`exported ${snapshot.total} memories to ${outPath}`);
|
|
28815
29181
|
} else {
|
|
28816
29182
|
console.log(JSON.stringify(snapshot, null, 2));
|
|
@@ -28824,7 +29190,7 @@ async function handleImportCommand({ positional, flags }) {
|
|
|
28824
29190
|
const file = positional[0];
|
|
28825
29191
|
if (!file)
|
|
28826
29192
|
return usageError("import requires <file.json>");
|
|
28827
|
-
if (!
|
|
29193
|
+
if (!existsSync35(file))
|
|
28828
29194
|
return fail(`error: file ${file} does not exist`);
|
|
28829
29195
|
const raw = JSON.parse(readFileSync28(file, "utf8"));
|
|
28830
29196
|
const res = importSnapshot(ctx.store, raw, { overwrite: flags["overwrite"] === "true" });
|
|
@@ -28975,7 +29341,7 @@ async function handleStaleCommand({ flags }) {
|
|
|
28975
29341
|
const daysOverride = flags["days"] ? parseInt(flags["days"], 10) : null;
|
|
28976
29342
|
const now = Date.now();
|
|
28977
29343
|
const stale = list(ctx.store).filter((e) => {
|
|
28978
|
-
if (e.status !== "active")
|
|
29344
|
+
if (e.status !== "active" && e.status !== "confirmed")
|
|
28979
29345
|
return false;
|
|
28980
29346
|
const policy = stalePolicyDays(e.type);
|
|
28981
29347
|
if (policy === null)
|
|
@@ -29365,7 +29731,7 @@ Ecosystem, Migration & Connectivity:
|
|
|
29365
29731
|
export [--out file.json] Export portable JSON memory snapshot
|
|
29366
29732
|
import <file.json> Import portable JSON memory snapshot
|
|
29367
29733
|
validate [--dry-run] Validate YAML schemas and referential integrity
|
|
29368
|
-
graph status
|
|
29734
|
+
graph [status|index] Inspect or index CodeGraph/Graphify AST provider symbols
|
|
29369
29735
|
ui / dashboard [--port 2222] Launch embedded visual knowledge graph UI
|
|
29370
29736
|
daemon [--port N] Real-time agency hub (SSE event stream + publish API, default port 7878)
|
|
29371
29737
|
mcp Run stdio MCP server for agent platforms
|