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/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)? ?KEY|PRIVATE KEY/i
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 u = Date.parse(b.entry.updated_at) - Date.parse(a.entry.updated_at);
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
- return Date.parse(b.entry.created_at) - Date.parse(a.entry.created_at);
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 && 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;
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
- parts.push(`- [[${wp.slug}]]: ${wp.title}${wp.summary ? ` — ${wp.summary}` : ""}`);
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
- init_current();
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/sqlite.ts
4286
- import { existsSync as existsSync6, mkdirSync as mkdirSync5 } from "node:fs";
4287
- import { dirname } from "node:path";
4288
- function getDriver() {
4289
- if (sqliteDriver !== "none")
4290
- return sqliteDriver;
4291
- try {
4292
- if (typeof globalThis.Bun !== "undefined") {
4293
- sqliteDriver = "bun";
4294
- return "bun";
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
- } catch {}
4297
- try {
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 openDatabase(dbPath) {
4306
- const dir = dirname(dbPath);
4307
- if (!existsSync6(dir)) {
4308
- mkdirSync5(dir, { recursive: true });
4474
+ function searchTranscriptWithBookends(transcriptPathOrContent, query, options = {}) {
4475
+ let content = transcriptPathOrContent;
4476
+ if (existsSync6(transcriptPathOrContent)) {
4477
+ content = readFileSync5(transcriptPathOrContent, "utf8");
4309
4478
  }
4310
- const driver = getDriver();
4311
- let rawDb;
4312
- if (driver === "bun") {
4313
- const { Database } = __require("bun:sqlite");
4314
- rawDb = new Database(dbPath, { create: true });
4315
- rawDb.run("PRAGMA journal_mode = WAL;");
4316
- rawDb.run("PRAGMA synchronous = NORMAL;");
4317
- const db = {
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
- initSchema(db);
4346
- return db;
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
- const { DatabaseSync } = __require("node:sqlite");
4349
- rawDb = new DatabaseSync(dbPath);
4350
- rawDb.exec("PRAGMA journal_mode = WAL;");
4351
- rawDb.exec("PRAGMA synchronous = NORMAL;");
4352
- const db = {
4353
- exec(sql) {
4354
- rawDb.exec(sql);
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
- initSchema(db);
4390
- return db;
4391
- }
4392
- }
4393
- function initSchema(db) {
4394
- db.exec(`
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
- var exports_harvest = {};
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 importTranscript(store, transcriptPathOrContent, options = {}) {
4781
- let content = transcriptPathOrContent;
4782
- if (existsSync8(transcriptPathOrContent)) {
4783
- content = readFileSync6(transcriptPathOrContent, "utf8");
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
- const blocks = parseJsonlTranscript(content);
4786
- const fullText = blocks.join(`
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
- const openLoops = [];
4814
- if (options.openLoops !== false) {
4815
- const existing = new Set(list(store).map((e) => e.id));
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
- return {
4842
- imported: entries.length,
4843
- entries,
4844
- errors,
4845
- openLoops
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
- var COMMITMENT_PATTERNS;
4849
- var init_harvest = __esm(() => {
4850
- init_store();
4851
- init_transcript();
4852
- COMMITMENT_PATTERNS = [
4853
- /\btodo\b\s*[:\-]\s*(.{4,})/i,
4854
- /\b(?:i'll|i will|i am going to)\s+(.{4,})/i,
4855
- /\bneed to\s+(.{4,})/i,
4856
- /\bfollow up (?:on|with)\s+(.{4,})/i,
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 { readdirSync, readFileSync as readFileSync7, writeFileSync as writeFileSync4, renameSync, unlinkSync, mkdirSync as mkdirSync6, existsSync as existsSync9 } from "node:fs";
4863
- import { join as join6 } from "node:path";
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: join6(memoryDir, "memories"),
4869
- dbPath: join6(memoryDir, "memory.db"),
4870
- currentMd: join6(memoryDir, "CURRENT.md"),
4871
- userMd: join6(memoryDir, "USER.md"),
4872
- auditJsonl: join6(memoryDir, "audit.jsonl")
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
- mkdirSync6(layout.memoriesDir, { recursive: true });
4878
- mkdirSync6(memoryDir, { recursive: true });
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 && existsSync9(layout.memoriesDir)) {
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
- return join6(store.dir, `${slugifyId(id)}.yaml`);
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 (existsSync9(store.dir)) {
4932
- for (const f of readdirSync(store.dir)) {
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 (!existsSync9(file))
5283
+ if (!existsSync10(file))
4943
5284
  return null;
4944
5285
  try {
4945
- const raw = readFileSync7(file, "utf8");
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 (existsSync9(file)) {
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
- writeFileSync4(tmp, yaml.dump(entry, { lineWidth: 120 }), "utf8");
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 (existsSync9(file)) {
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 { extractHarvestUnits: extractHarvestUnits2 } = (init_harvest(), __toCommonJS(exports_harvest));
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 existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "node:fs";
5416
- import { join as join7 } from "node:path";
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 = join7(memoryDir, "entities.json");
5626
- mkdirSync7(memoryDir, { recursive: true });
5969
+ const filePath = join8(memoryDir, "entities.json");
5970
+ mkdirSync8(memoryDir, { recursive: true });
5627
5971
  const entities = Array.isArray(data) ? data : data.entities;
5628
- writeFileSync5(filePath, JSON.stringify(entities, null, 2), "utf8");
5972
+ writeFileSync6(filePath, JSON.stringify(entities, null, 2), "utf8");
5629
5973
  }
5630
5974
  function loadEntities(memoryDir) {
5631
- const filePath = join7(memoryDir, "entities.json");
5632
- if (!existsSync10(filePath))
5975
+ const filePath = join8(memoryDir, "entities.json");
5976
+ if (!existsSync11(filePath))
5633
5977
  return [];
5634
5978
  try {
5635
- return JSON.parse(readFileSync8(filePath, "utf8"));
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
- return entities.find((e) => e.id === cleanId || e.name.toLowerCase() === id.toLowerCase()) ?? null;
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 existsSync11, mkdirSync as mkdirSync8, writeFileSync as writeFileSync6, readFileSync as readFileSync9, readdirSync as readdirSync2 } from "node:fs";
5830
- import { join as join8 } from "node:path";
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 = join8(memoryDir, "wiki");
5855
- const conceptsDir = join8(wikiDir, "concepts");
5856
- const entitiesDir = join8(wikiDir, "entities");
6206
+ const wikiDir = join9(memoryDir, "wiki");
6207
+ const conceptsDir = join9(wikiDir, "concepts");
6208
+ const entitiesDir = join9(wikiDir, "entities");
5857
6209
  if (!dryRun) {
5858
- mkdirSync8(conceptsDir, { recursive: true });
5859
- mkdirSync8(entitiesDir, { recursive: true });
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 (!existsSync11(dir))
6464
+ if (!existsSync12(dir))
6107
6465
  return map2;
6108
- for (const file of readdirSync2(dir)) {
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 = readFileSync9(join8(dir, file), "utf8");
6471
+ const content = readFileSync10(join9(dir, file), "utf8");
6114
6472
  const frontmatter = parseFrontmatter(content);
6115
- map2.set(slug, { ...frontmatter, slug, content: content.slice(content.indexOf(`
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 (!existsSync11(dir))
6480
+ if (!existsSync12(dir))
6125
6481
  return map2;
6126
- for (const file of readdirSync2(dir)) {
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 = readFileSync9(join8(dir, file), "utf8");
6487
+ const content = readFileSync10(join9(dir, file), "utf8");
6132
6488
  const frontmatter = parseFrontmatter(content);
6133
- map2.set(slug, { ...frontmatter, slug, content: content.slice(content.indexOf(`
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 value = line.slice(idx + 1).trim();
6152
- obj[key] = value.replace(/^["']|["']$/g, "");
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
- writeFileSync6(join8(dir, slug + ".md"), content, "utf8");
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
- writeFileSync6(join8(dir, slug + ".md"), content, "utf8");
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
- writeFileSync6(join8(dir, "index.md"), content, "utf8");
6542
+ writeFileSync7(join9(dir, "index.md"), content, "utf8");
6172
6543
  }
6173
6544
  function writeLogPage(page, dir) {
6174
6545
  const content = renderLogPage(page);
6175
- writeFileSync6(join8(dir, "log.md"), content, "utf8");
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 = join8(memoryDir, "wiki");
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(join8(wikiDir, "concepts"));
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(join8(wikiDir, "entities"));
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 = join8(wikiDir, "index.md");
6207
- if (existsSync11(idxPath)) {
6577
+ const idxPath = join9(wikiDir, "index.md");
6578
+ if (existsSync12(idxPath)) {
6208
6579
  try {
6209
- const raw = readFileSync9(idxPath, "utf8");
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 = join8(wikiDir, "log.md");
6217
- if (existsSync11(logPath)) {
6587
+ const logPath = join9(wikiDir, "log.md");
6588
+ if (existsSync12(logPath)) {
6218
6589
  try {
6219
- const raw = readFileSync9(logPath, "utf8");
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 = join8(memoryDir, "wiki");
6599
+ const wikiDir = join9(memoryDir, "wiki");
6229
6600
  if (slug === "index") {
6230
- const p = join8(wikiDir, "index.md");
6231
- if (existsSync11(p)) {
6232
- const raw = readFileSync9(p, "utf8");
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 = join8(wikiDir, "log.md");
6240
- if (existsSync11(p)) {
6241
- const raw = readFileSync9(p, "utf8");
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 = join8(wikiDir, "concepts", `${slug}.md`);
6249
- if (existsSync11(p)) {
6250
- const raw = readFileSync9(p, "utf8");
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 = join8(wikiDir, "entities", `${slug}.md`);
6257
- if (existsSync11(p)) {
6258
- const raw = readFileSync9(p, "utf8");
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 = join8(memoryDir, "wiki");
6267
- const conceptsDir = join8(wikiDir, "concepts");
6268
- const entitiesDir = join8(wikiDir, "entities");
6269
- if (!existsSync11(conceptsDir))
6270
- mkdirSync8(conceptsDir, { recursive: true });
6271
- if (!existsSync11(entitiesDir))
6272
- mkdirSync8(entitiesDir, { recursive: true });
6273
- const indexPath = join8(wikiDir, "index.md");
6274
- if (!existsSync11(indexPath)) {
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
- writeFileSync6(indexPath, defaultIndex, "utf8");
6656
+ writeFileSync7(indexPath, defaultIndex, "utf8");
6286
6657
  }
6287
- const logPath = join8(wikiDir, "log.md");
6288
- if (!existsSync11(logPath)) {
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
- writeFileSync6(logPath, defaultLog, "utf8");
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 existsSync12, mkdirSync as mkdirSync9, writeFileSync as writeFileSync7 } from "node:fs";
6327
- import { dirname as dirname3, join as join9 } from "node:path";
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 join9(home, ".memory");
6699
+ return join10(home, ".memory");
6341
6700
  }
6342
6701
  function ensureMemoryDirectory(memoryDir) {
6343
- const memoriesDir = join9(memoryDir, "memories");
6344
- if (!existsSync12(memoriesDir)) {
6345
- mkdirSync9(memoriesDir, { recursive: true });
6702
+ const memoriesDir = join10(memoryDir, "memories");
6703
+ if (!existsSync13(memoriesDir)) {
6704
+ mkdirSync10(memoriesDir, { recursive: true });
6346
6705
  }
6347
- const currentPath = join9(memoryDir, "CURRENT.md");
6348
- if (!existsSync12(currentPath)) {
6349
- writeFileSync7(currentPath, `# Active Project Constraints
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 (!existsSync12(uPath)) {
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 (existsSync12(join9(dir, ".memory")))
6729
+ if (existsSync13(join10(dir, ".memory")))
6371
6730
  return { root: dir, marker: "memory", memoryDirName: ".memory" };
6372
- if (existsSync12(join9(dir, ".musememory")))
6731
+ if (existsSync13(join10(dir, ".musememory")))
6373
6732
  return { root: dir, marker: "memory", memoryDirName: ".musememory" };
6374
- if (existsSync12(join9(dir, ".muse-memory")))
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 (existsSync12(join9(dir, ".git"))) {
6737
+ if (existsSync13(join10(dir, ".git"))) {
6379
6738
  let dirName = ".memory";
6380
- if (existsSync12(join9(dir, ".musememory")))
6739
+ if (existsSync13(join10(dir, ".musememory")))
6381
6740
  dirName = ".musememory";
6382
- else if (existsSync12(join9(dir, ".muse-memory")))
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) => existsSync12(join9(root, n))) ?? ".memory";
6403
- const memoryDir = join9(root, memoryDirName);
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 = join9(dir, "..");
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 { root, memoryDir } = findOrCreateProjectRoot(process.cwd(), { global: isGlobal });
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 existsSync13 } from "node:fs";
6518
- import { join as join10, resolve } from "node:path";
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 join10(homedir2(), p.slice(1));
6882
+ return join11(homedir2(), p.slice(1));
6523
6883
  }
6524
6884
  if (p.startsWith("/")) {
6525
6885
  return p;
6526
6886
  }
6527
- return resolve(baseDir, p);
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 existsSync13(p);
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 existsSync14, readFileSync as readFileSync10, statSync } from "node:fs";
6825
- import { join as join11 } from "node:path";
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 (existsSync14(sourcePath) && statSync(sourcePath).isDirectory()) {
7193
+ if (existsSync15(sourcePath) && statSync(sourcePath).isDirectory()) {
6834
7194
  const candidates = [
6835
- join11(sourcePath, "standalone.json"),
6836
- join11(sourcePath, "engine-state.json")
7195
+ join12(sourcePath, "standalone.json"),
7196
+ join12(sourcePath, "engine-state.json")
6837
7197
  ];
6838
7198
  for (const cand of candidates) {
6839
- if (existsSync14(cand)) {
7199
+ if (existsSync15(cand)) {
6840
7200
  jsonPath = cand;
6841
7201
  break;
6842
7202
  }
6843
7203
  }
6844
7204
  }
6845
- if (!existsSync14(jsonPath) || statSync(jsonPath).isDirectory()) {
7205
+ if (!existsSync15(jsonPath) || statSync(jsonPath).isDirectory()) {
6846
7206
  return results;
6847
7207
  }
6848
7208
  try {
6849
- const raw = readFileSync10(jsonPath, "utf8");
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 existsSync15, readFileSync as readFileSync11, readdirSync as readdirSync3, statSync as statSync2 } from "node:fs";
6887
- import { join as join12 } from "node:path";
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 (!existsSync15(sourcePath))
7254
+ if (!existsSync16(sourcePath))
6895
7255
  return results;
6896
7256
  let jsonPath = sourcePath;
6897
7257
  if (statSync2(sourcePath).isDirectory()) {
6898
- const p = join12(sourcePath, "beads.json");
6899
- if (existsSync15(p))
7258
+ const p = join13(sourcePath, "beads.json");
7259
+ if (existsSync16(p))
6900
7260
  jsonPath = p;
6901
7261
  }
6902
- if (existsSync15(jsonPath) && !statSync2(jsonPath).isDirectory()) {
7262
+ if (existsSync16(jsonPath) && !statSync2(jsonPath).isDirectory()) {
6903
7263
  try {
6904
- const raw = readFileSync11(jsonPath, "utf8");
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 = readdirSync3(sourcePath);
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 = join12(sourcePath, file);
6940
- const content = readFileSync11(fullPath, "utf8");
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 existsSync16, readFileSync as readFileSync12, readdirSync as readdirSync4, statSync as statSync3 } from "node:fs";
6961
- import { join as join13 } from "node:path";
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 (!existsSync16(sourcePath))
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 = readdirSync4(sourcePath);
7381
+ const entries = readdirSync5(sourcePath);
7022
7382
  for (const file of entries) {
7023
7383
  if (file.endsWith(".json")) {
7024
- const raw = readFileSync12(join13(sourcePath, file), "utf8");
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(readFileSync12(sourcePath, "utf8"), "letta.json");
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 existsSync17, readFileSync as readFileSync13, readdirSync as readdirSync5, statSync as statSync4 } from "node:fs";
7039
- import { join as join14 } from "node:path";
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 (!existsSync17(sourcePath))
7407
+ if (!existsSync18(sourcePath))
7048
7408
  return results;
7049
7409
  const processFile = (filePath, filename) => {
7050
7410
  try {
7051
- const raw = readFileSync13(filePath, "utf8");
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 = readdirSync5(sourcePath);
7482
+ const files = readdirSync6(sourcePath);
7123
7483
  for (const file of files) {
7124
- processFile(join14(sourcePath, file), file);
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((resolve2) => {
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
- resolve2(result);
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((resolve2) => {
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 resolve2(defaultId);
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 resolve2(options[num - 1].id);
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 resolve2(matched.id);
7765
+ return resolve3(matched.id);
7450
7766
  }
7451
- resolve2(defaultId);
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 writeFileSync8, mkdirSync as mkdirSync10, statSync as statSync6 } from "node:fs";
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
- mkdirSync10(dir, { recursive: true });
8118
- writeFileSync8(path, JSON.stringify(data, null, 2) + `
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
- mkdirSync10(dir, { recursive: true });
8453
+ mkdirSync11(dir, { recursive: true });
8138
8454
  const dumped = yaml.dump(data, { indent: 2, lineWidth: -1 });
8139
- writeFileSync8(path, dumped, "utf8");
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 writeFileSync9,
8530
- mkdirSync as mkdirSync11,
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
- mkdirSync11(hooksDir, { recursive: true });
8548
- writeFileSync9(hookPath, HOOK_SCRIPT, "utf8");
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
- mkdirSync11(processedDir, { recursive: true });
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 = resolve2.call(this, root, ref);
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 resolve2(root, ref) {
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 resolve2(baseURI, relativeURI, options) {
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: resolve2,
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 schemaPath = join19(import.meta.dir, "..", "schema.json");
14954
- const schema2 = JSON.parse(readFileSync18(schemaPath, "utf8"));
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 existsSync22, statSync as statSync8, readFileSync as readFileSync19 } from "node:fs";
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 = existsSync22(storagePath);
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 (existsSync22(currentPath)) {
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 (existsSync22(auditPath)) {
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 existsSync23, readFileSync as readFileSync20, writeFileSync as writeFileSync10, mkdirSync as mkdirSync12, rmSync } from "node:fs";
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
- mkdirSync12(indexDir(memoryDir), { recursive: true });
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
- writeFileSync10(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(emptyIndex, null, 2), "utf8");
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
- mkdirSync12(pDir, { recursive: true });
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
- writeFileSync10(partitionIndexFilePath(pDir), JSON.stringify(partition, null, 2), "utf8");
15776
+ writeFileSync11(partitionIndexFilePath(pDir), JSON.stringify(partition, null, 2), "utf8");
15447
15777
  for (const shard of finalShards) {
15448
- writeFileSync10(shardFilePath(pDir, shard.id), JSON.stringify(shard, null, 2), "utf8");
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
- writeFileSync10(globalIndexFilePath(indexDir(memoryDir)), JSON.stringify(index, null, 2), "utf8");
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 (!existsSync23(path))
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 existsSync24, readFileSync as readFileSync21, writeFileSync as writeFileSync11, mkdirSync as mkdirSync13 } from "node:fs";
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 (!existsSync24(memoryDir))
15662
- mkdirSync13(memoryDir, { recursive: true });
15663
- writeFileSync11(indexFilePath(memoryDir), JSON.stringify(index), "utf8");
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 (!existsSync24(p))
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 existsSync25, mkdirSync as mkdirSync14, readFileSync as readFileSync22, writeFileSync as writeFileSync12, rmSync as rmSync2, readdirSync as readdirSync9 } from "node:fs";
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
- mkdirSync14(dir, { recursive: true });
15822
- writeFileSync12(join23(dir, `${indexId}.json`), JSON.stringify(doc, null, 2), "utf8");
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 (!existsSync25(filePath))
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 (!existsSync25(base))
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 (!existsSync25(pDir))
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 (!existsSync25(base))
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 (existsSync25(pDir)) {
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 (existsSync25(file)) {
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 existsSync26 } from "node:fs";
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 && existsSync26(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 = existsSync26(treeDir);
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 = existsSync26(vecPath);
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((resolve2, reject2) => {
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("Access-Control-Allow-Origin", "*");
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
- resolve2({
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((resolve2, reject2) => {
16764
+ return new Promise((resolve3, reject2) => {
16420
16765
  let data = "";
16421
- req.on("data", (chunk) => data += chunk);
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
- resolve2(data ? JSON.parse(data) : {});
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((resolve2) => setTimeout(resolve2, pollInterval));
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((resolve2, reject2) => {
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
- resolve2(parseResult.data);
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((resolve2, reject2) => {
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(resolve2, interval);
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((resolve2) => {
25903
+ return new Promise((resolve3) => {
25549
25904
  const json2 = serializeMessage(message);
25550
25905
  if (this._stdout.write(json2)) {
25551
- resolve2();
25906
+ resolve3();
25552
25907
  } else {
25553
- this._stdout.once("drain", resolve2);
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 existsSync27, mkdirSync as mkdirSync15, writeFileSync as writeFileSync13 } from "node:fs";
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 (existsSync27(dir)) {
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
- mkdirSync15(dir, { recursive: true });
25721
- writeFileSync13(join25(dir, "SKILL.md"), md, "utf8");
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((resolve2) => {
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
- resolve2({ ok: true, ran: true, exitCode: 0, stdout: String(stdout), stderr: String(stderr), message: "command exited 0" });
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
- resolve2({ ok: false, ran: true, timedOut: true, stdout: String(stdout), stderr: String(stderr), message: `timed out after ${timeoutSec}s` });
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
- resolve2({
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 existsSync28, mkdirSync as mkdirSync16, readFileSync as readFileSync23, writeFileSync as writeFileSync14 } from "node:fs";
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 (!existsSync28(filePath)) {
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
- mkdirSync16(memoryDir, { recursive: true });
26447
+ mkdirSync17(memoryDir, { recursive: true });
26093
26448
  const filePath = getSettingsFilePath(memoryDir);
26094
- writeFileSync14(filePath, JSON.stringify(store, null, 2), "utf8");
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.4.0" }, {
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
- const { updateSessionHandoff: updateSessionHandoff2 } = (init_current(), __toCommonJS(exports_current));
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 { updateSessionHandoff: updateSessionHandoff2 } = (init_current(), __toCommonJS(exports_current));
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
- const { updateSessionHandoff: updateSessionHandoff2 } = (init_current(), __toCommonJS(exports_current));
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(store, {
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(store, transcript, { project, confirmed: isConfirmed });
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(store, String(a.id));
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(store, oldId, newId);
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(store, String(a.id), related);
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(store, String(a.id), a.reason ? String(a.reason) : undefined);
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(store, String(a.id));
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(store, id, reason, "mcp_agent");
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(memoryDir, {
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(store);
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(store, { entries }, { overwrite: a.overwrite === true });
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(store, String(a.id));
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(store, entry.id);
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(store, updated);
27377
+ save(activeStore, updated);
27023
27378
  }
27024
27379
  return toolResult(updated);
27025
27380
  }
27026
27381
  case "record_session": {
27027
- const { entry, sessionId } = recordSessionStart(store, String(a.project), a.note ? String(a.note) : undefined);
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(store);
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(memoryDir, tier, String(a.set));
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(memoryDir, tier);
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(memoryDir)[tier] });
27404
+ return toolResult({ tier, lines: readCore(activeMemoryDir)[tier] });
27050
27405
  }
27051
- return toolResult(readCore(memoryDir));
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(store, {
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(store, String(a.id), typeof a.depth === "number" ? a.depth : 5);
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(store, root, memoryDir);
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(store, root, {
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(store, root, memoryDir, String(a.id), {
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(root);
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(root);
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(store, memoryDir, {
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() : memoryDir;
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() : memoryDir;
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(memoryDir);
27517
+ let index = loadTreeIndex(activeMemoryDir);
27159
27518
  if (!index) {
27160
- index = buildTreeIndex(store, memoryDir);
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(memoryDir, String(a.slug), a.type ? String(a.type) : undefined);
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(memoryDir, {
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(store, memoryDir, {
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(memoryDir, String(a.id));
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(memoryDir, String(a.id));
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(memoryDir);
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(memoryDir, project, String(a.indexId));
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(memoryDir, project, String(a.indexId));
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(store, {
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(memoryDir, a.project ? String(a.project) : undefined, a.indexId ? String(a.indexId) : undefined);
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(memoryDir, String(a.project)) : getSettings(memoryDir);
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(memoryDir, String(a.project), a.settings);
27628
+ const updated = setProjectSettings(activeMemoryDir, String(a.project), a.settings);
27270
27629
  return toolResult(updated);
27271
27630
  } else {
27272
- const updated = setSettings(memoryDir, a.settings);
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((resolve2) => {
27290
- process.stdin.on("end", () => resolve2());
27291
- process.stdin.on("close", () => resolve2());
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
- init_current();
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 existsSync29 } from "node:fs";
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 (existsSync29(memoriesDir)) {
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 (existsSync29(currentMd)) {
27782
+ if (existsSync30(currentMd)) {
27424
27783
  watchers.push(watch(currentMd, () => armDebounced("constraints.changed")));
27425
27784
  }
27426
27785
  } catch {}
27427
27786
  }
27428
- return new Promise((resolve2) => {
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
- resolve2({
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 existsSync30, mkdirSync as mkdirSync17, writeFileSync as writeFileSync15, readFileSync as readFileSync24 } from "node:fs";
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 (existsSync30(agentsMdPath)) {
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
- writeFileSync15(agentsMdPath, updated, "utf8");
27825
+ writeFileSync16(agentsMdPath, updated, "utf8");
27467
27826
  } else if (!existing.includes("<!-- musememory:start -->") && !existing.includes("Muse Memory")) {
27468
- writeFileSync15(agentsMdPath, `${existing.trim()}
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
- writeFileSync15(agentsMdPath, initialContent, "utf8");
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
- mkdirSync17(join28(memoryDir, "memories"), { recursive: true });
27488
- mkdirSync17(join28(globalDir, "memories"), { recursive: true });
27846
+ mkdirSync18(join28(memoryDir, "memories"), { recursive: true });
27847
+ mkdirSync18(join28(globalDir, "memories"), { recursive: true });
27489
27848
  const currentPath = join28(memoryDir, "CURRENT.md");
27490
- if (!existsSync30(currentPath)) {
27491
- writeFileSync15(currentPath, `# Active Project Constraints
27849
+ if (!existsSync31(currentPath)) {
27850
+ writeFileSync16(currentPath, `# Active Project Constraints
27492
27851
  `, "utf8");
27493
27852
  }
27494
27853
  const globalUserPath = userFilePath(globalDir);
27495
- if (!existsSync30(globalUserPath)) {
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 (existsSync30(globalAgentsMd)) {
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
- writeFileSync15(globalAgentsMd, updated, "utf8");
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 (!existsSync30(gitDir))
27905
+ if (!existsSync31(gitDir))
27547
27906
  return false;
27548
27907
  const hookPath = join28(gitDir, "hooks", "pre-commit");
27549
- const isInstalled = existsSync30(hookPath) && readFileSync24(hookPath, "utf8").includes("memory harvest-auto");
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 && existsSync30(ctx.memoryDir) && !dryRun) {
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
- mkdirSync17(join28(memoryDir, "memories"), { recursive: true });
27968
+ mkdirSync18(join28(memoryDir, "memories"), { recursive: true });
27610
27969
  const currentPath = join28(memoryDir, "CURRENT.md");
27611
- if (!existsSync30(currentPath)) {
27612
- writeFileSync15(currentPath, `# Active Project Constraints
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
- return usageError("graph requires status");
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 existsSync31 } from "node:fs";
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 (existsSync31(nameOrPath))
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 (existsSync31(c))
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 existsSync32, readFileSync as readFileSync25 } from "node:fs";
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 = existsSync32(target) ? readFileSync25(target, "utf8") : target;
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 (!existsSync32(targetFile)) {
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[1] ?? "list";
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[2];
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[2];
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 writeFileSync16, readFileSync as readFileSync26 } from "node:fs";
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[1] ?? "get";
28870
+ const sub = parsed.positional[0] ?? "get";
28505
28871
  const project = parsed.flags.project;
28506
28872
  if (sub === "get") {
28507
- const key = parsed.positional[2];
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[2];
28527
- const rawVal = parsed.positional[3];
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
- writeFileSync16(out, json2, "utf8");
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[2];
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 existsSync33 } from "node:fs";
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 (!existsSync33(p))
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 writeFileSync17, readFileSync as readFileSync28, existsSync as existsSync34 } from "node:fs";
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
- writeFileSync17(outPath, JSON.stringify(snapshot, null, 2), "utf8");
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 (!existsSync34(file))
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 Inspect CodeGraph AST provider 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