@meowlynxsea/koi 0.2.3 → 0.2.4

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/main.js CHANGED
@@ -3,7 +3,6 @@ var __create = Object.create;
3
3
  var __getProtoOf = Object.getPrototypeOf;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
7
  function __accessProp(key) {
9
8
  return this[key];
@@ -30,23 +29,6 @@ var __toESM = (mod, isNodeMode, target) => {
30
29
  cache.set(mod, to);
31
30
  return to;
32
31
  };
33
- var __toCommonJS = (from) => {
34
- var entry = (__moduleCache ??= new WeakMap).get(from), desc;
35
- if (entry)
36
- return entry;
37
- entry = __defProp({}, "__esModule", { value: true });
38
- if (from && typeof from === "object" || typeof from === "function") {
39
- for (var key of __getOwnPropNames(from))
40
- if (!__hasOwnProp.call(entry, key))
41
- __defProp(entry, key, {
42
- get: __accessProp.bind(from, key),
43
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
44
- });
45
- }
46
- __moduleCache.set(from, entry);
47
- return entry;
48
- };
49
- var __moduleCache;
50
32
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
51
33
  var __returnValue = (v) => v;
52
34
  function __exportSetter(name, newValue) {
@@ -29784,7 +29766,7 @@ var require_gif = __commonJS((exports) => {
29784
29766
  // node_modules/image-q/dist/cjs/image-q.cjs
29785
29767
  var require_image_q = __commonJS((exports, module2) => {
29786
29768
  var __defProp3 = Object.defineProperty;
29787
- var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
29769
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
29788
29770
  var __getOwnPropNames2 = Object.getOwnPropertyNames;
29789
29771
  var __hasOwnProp2 = Object.prototype.hasOwnProperty;
29790
29772
  var __defNormalProp = (obj, key, value2) => (key in obj) ? __defProp3(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2;
@@ -29797,11 +29779,11 @@ var require_image_q = __commonJS((exports, module2) => {
29797
29779
  if (module22 && typeof module22 === "object" || typeof module22 === "function") {
29798
29780
  for (let key of __getOwnPropNames2(module22))
29799
29781
  if (!__hasOwnProp2.call(target, key) && (copyDefault || key !== "default"))
29800
- __defProp3(target, key, { get: () => module22[key], enumerable: !(desc = __getOwnPropDesc2(module22, key)) || desc.enumerable });
29782
+ __defProp3(target, key, { get: () => module22[key], enumerable: !(desc = __getOwnPropDesc(module22, key)) || desc.enumerable });
29801
29783
  }
29802
29784
  return target;
29803
29785
  };
29804
- var __toCommonJS2 = /* @__PURE__ */ ((cache) => {
29786
+ var __toCommonJS = /* @__PURE__ */ ((cache) => {
29805
29787
  return (module22, temp) => {
29806
29788
  return cache && cache.get(module22) || (temp = __reExport(__markAsModule({}), module22, 1), cache && cache.set(module22, temp), temp);
29807
29789
  };
@@ -32378,7 +32360,7 @@ var require_image_q = __commonJS((exports, module2) => {
32378
32360
  throw new Error(`Unknown paletteQuantization ${paletteQuantization}`);
32379
32361
  }
32380
32362
  }
32381
- module2.exports = __toCommonJS2(src_exports);
32363
+ module2.exports = __toCommonJS(src_exports);
32382
32364
  });
32383
32365
 
32384
32366
  // node_modules/gifwrap/src/gifframe.js
@@ -233292,12 +233274,12 @@ var require_babel = __commonJS((exports, module4) => {
233292
233274
  for (let o2 of a(t5))
233293
233275
  l.call(e4, o2) || o2 === r4 || s(e4, o2, { get: () => t5[o2], enumerable: !(n3 = i(t5, o2)) || n3.enumerable });
233294
233276
  return e4;
233295
- }, __toESM2 = (e4, t5, r4) => (r4 = e4 != null ? n2(o(e4)) : {}, __copyProps(!t5 && e4 && e4.__esModule ? r4 : s(r4, "default", { value: e4, enumerable: true }), e4)), __toCommonJS2 = (e4) => __copyProps(s({}, "__esModule", { value: true }), e4), c2 = __commonJS2({ "umd:@jridgewell/sourcemap-codec"(e4, r4) {
233277
+ }, __toESM2 = (e4, t5, r4) => (r4 = e4 != null ? n2(o(e4)) : {}, __copyProps(!t5 && e4 && e4.__esModule ? r4 : s(r4, "default", { value: e4, enumerable: true }), e4)), __toCommonJS = (e4) => __copyProps(s({}, "__esModule", { value: true }), e4), c2 = __commonJS2({ "umd:@jridgewell/sourcemap-codec"(e4, r4) {
233296
233278
  r4.exports = t4;
233297
233279
  } }), p = __commonJS2({ "umd:@jridgewell/trace-mapping"(e4, t5) {
233298
233280
  t5.exports = r3;
233299
233281
  } }), u3 = {};
233300
- __export4(u3, { GenMapping: () => v2, addMapping: () => addMapping, addSegment: () => addSegment, allMappings: () => allMappings, fromMap: () => fromMap, maybeAddMapping: () => maybeAddMapping, maybeAddSegment: () => maybeAddSegment, setIgnore: () => setIgnore, setSourceContent: () => setSourceContent, toDecodedMap: () => toDecodedMap, toEncodedMap: () => toEncodedMap }), e3.exports = __toCommonJS2(u3);
233282
+ __export4(u3, { GenMapping: () => v2, addMapping: () => addMapping, addSegment: () => addSegment, allMappings: () => allMappings, fromMap: () => fromMap, maybeAddMapping: () => maybeAddMapping, maybeAddSegment: () => maybeAddSegment, setIgnore: () => setIgnore, setSourceContent: () => setSourceContent, toDecodedMap: () => toDecodedMap, toEncodedMap: () => toEncodedMap }), e3.exports = __toCommonJS(u3);
233301
233283
  var d2 = class {
233302
233284
  constructor() {
233303
233285
  this._indexes = { __proto__: null }, this.array = [];
@@ -233441,12 +233423,12 @@ var require_babel = __commonJS((exports, module4) => {
233441
233423
  for (let o2 of a(t5))
233442
233424
  l.call(e4, o2) || o2 === r4 || s(e4, o2, { get: () => t5[o2], enumerable: !(n3 = i(t5, o2)) || n3.enumerable });
233443
233425
  return e4;
233444
- }, __toESM2 = (e4, t5, r4) => (r4 = e4 != null ? n2(o(e4)) : {}, __copyProps(!t5 && e4 && e4.__esModule ? r4 : s(r4, "default", { value: e4, enumerable: true }), e4)), __toCommonJS2 = (e4) => __copyProps(s({}, "__esModule", { value: true }), e4), c2 = __commonJS2({ "umd:@jridgewell/trace-mapping"(e4, t5) {
233426
+ }, __toESM2 = (e4, t5, r4) => (r4 = e4 != null ? n2(o(e4)) : {}, __copyProps(!t5 && e4 && e4.__esModule ? r4 : s(r4, "default", { value: e4, enumerable: true }), e4)), __toCommonJS = (e4) => __copyProps(s({}, "__esModule", { value: true }), e4), c2 = __commonJS2({ "umd:@jridgewell/trace-mapping"(e4, t5) {
233445
233427
  t5.exports = r3;
233446
233428
  } }), p = __commonJS2({ "umd:@jridgewell/gen-mapping"(e4, r4) {
233447
233429
  r4.exports = t4;
233448
233430
  } }), u3 = {};
233449
- __export4(u3, { default: () => remapping }), e3.exports = __toCommonJS2(u3);
233431
+ __export4(u3, { default: () => remapping }), e3.exports = __toCommonJS(u3);
233450
233432
  var d2 = __toESM2(c2()), h2 = __toESM2(p()), f = __toESM2(c2()), m2 = SegmentObject("", -1, -1, "", null, false), y3 = [];
233451
233433
  function SegmentObject(e4, t5, r4, n3, s2, i2) {
233452
233434
  return { source: e4, line: t5, column: r4, name: n3, content: s2, ignore: i2 };
@@ -233630,11 +233612,11 @@ Did you specify these with the most recent transformation maps first?`);
233630
233612
  for (let l2 of n2(i2))
233631
233613
  s.call(e4, l2) || l2 === a2 || t4(e4, l2, { get: () => i2[l2], enumerable: !(o2 = r3(i2, l2)) || o2.enumerable });
233632
233614
  return e4;
233633
- }, __toCommonJS2 = (e4) => __copyProps(t4({}, "__esModule", { value: true }), e4), i = {};
233615
+ }, __toCommonJS = (e4) => __copyProps(t4({}, "__esModule", { value: true }), e4), i = {};
233634
233616
  ((e4, r4) => {
233635
233617
  for (var n3 in r4)
233636
233618
  t4(e4, n3, { get: r4[n3], enumerable: true });
233637
- })(i, { decode: () => decode7, decodeGeneratedRanges: () => decodeGeneratedRanges, decodeOriginalScopes: () => decodeOriginalScopes, encode: () => encode8, encodeGeneratedRanges: () => encodeGeneratedRanges, encodeOriginalScopes: () => encodeOriginalScopes }), e3.exports = __toCommonJS2(i);
233619
+ })(i, { decode: () => decode7, decodeGeneratedRanges: () => decodeGeneratedRanges, decodeOriginalScopes: () => decodeOriginalScopes, encode: () => encode8, encodeGeneratedRanges: () => encodeGeneratedRanges, encodeOriginalScopes: () => encodeOriginalScopes }), e3.exports = __toCommonJS(i);
233638
233620
  var a = 44, o = 59, l = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", c2 = new Uint8Array(64), p = new Uint8Array(128);
233639
233621
  for (let e4 = 0;e4 < l.length; e4++) {
233640
233622
  const t5 = l.charCodeAt(e4);
@@ -233875,12 +233857,12 @@ Did you specify these with the most recent transformation maps first?`);
233875
233857
  for (let o2 of a(t5))
233876
233858
  l.call(e4, o2) || o2 === r4 || s(e4, o2, { get: () => t5[o2], enumerable: !(n3 = i(t5, o2)) || n3.enumerable });
233877
233859
  return e4;
233878
- }, __toESM2 = (e4, t5, r4) => (r4 = e4 != null ? n2(o(e4)) : {}, __copyProps(!t5 && e4 && e4.__esModule ? r4 : s(r4, "default", { value: e4, enumerable: true }), e4)), __toCommonJS2 = (e4) => __copyProps(s({}, "__esModule", { value: true }), e4), c2 = __commonJS2({ "umd:@jridgewell/sourcemap-codec"(e4, t5) {
233860
+ }, __toESM2 = (e4, t5, r4) => (r4 = e4 != null ? n2(o(e4)) : {}, __copyProps(!t5 && e4 && e4.__esModule ? r4 : s(r4, "default", { value: e4, enumerable: true }), e4)), __toCommonJS = (e4) => __copyProps(s({}, "__esModule", { value: true }), e4), c2 = __commonJS2({ "umd:@jridgewell/sourcemap-codec"(e4, t5) {
233879
233861
  t5.exports = r3;
233880
233862
  } }), p = __commonJS2({ "umd:@jridgewell/resolve-uri"(e4, r4) {
233881
233863
  r4.exports = t4;
233882
233864
  } }), u3 = {};
233883
- __export4(u3, { AnyMap: () => FlattenMap, FlattenMap: () => FlattenMap, GREATEST_LOWER_BOUND: () => A, LEAST_UPPER_BOUND: () => P2, TraceMap: () => C2, allGeneratedPositionsFor: () => allGeneratedPositionsFor, decodedMap: () => decodedMap, decodedMappings: () => decodedMappings, eachMapping: () => eachMapping, encodedMap: () => encodedMap, encodedMappings: () => encodedMappings, generatedPositionFor: () => generatedPositionFor, isIgnored: () => isIgnored, originalPositionFor: () => originalPositionFor, presortedDecodedMap: () => presortedDecodedMap, sourceContentFor: () => sourceContentFor, traceSegment: () => traceSegment }), e3.exports = __toCommonJS2(u3);
233865
+ __export4(u3, { AnyMap: () => FlattenMap, FlattenMap: () => FlattenMap, GREATEST_LOWER_BOUND: () => A, LEAST_UPPER_BOUND: () => P2, TraceMap: () => C2, allGeneratedPositionsFor: () => allGeneratedPositionsFor, decodedMap: () => decodedMap, decodedMappings: () => decodedMappings, eachMapping: () => eachMapping, encodedMap: () => encodedMap, encodedMappings: () => encodedMappings, generatedPositionFor: () => generatedPositionFor, isIgnored: () => isIgnored, originalPositionFor: () => originalPositionFor, presortedDecodedMap: () => presortedDecodedMap, sourceContentFor: () => sourceContentFor, traceSegment: () => traceSegment }), e3.exports = __toCommonJS(u3);
233884
233866
  var d2 = __toESM2(c2()), h2 = __toESM2(p());
233885
233867
  function stripFilename(e4) {
233886
233868
  if (!e4)
@@ -342893,7 +342875,7 @@ var init_mode = __esm(() => {
342893
342875
  "link_context",
342894
342876
  "link_code",
342895
342877
  "manage_triggers",
342896
- "update_boot"
342878
+ "manage_boot_links"
342897
342879
  ];
342898
342880
  READONLY_TOOLS = [
342899
342881
  "read",
@@ -343892,32 +343874,60 @@ class GraphService {
343892
343874
  }
343893
343875
  return { deleted_uri: `${domain2}://${path7}`, node_uuid: nodeUuid };
343894
343876
  }
343895
- async updateBoot(content, namespace = "") {
343896
- const boot = await this.getMemoryByPath("boot", "system", namespace);
343897
- if (boot) {
343898
- const result = await this.updateMemory("boot", content, "system", namespace);
343899
- this._updateBootCache(namespace, content);
343900
- return result;
343877
+ async addBootLink(uri, namespace = "") {
343878
+ const targetUri = uri.trim();
343879
+ if (!targetUri)
343880
+ throw new Error("URI cannot be empty");
343881
+ await this.db.execute("INSERT OR IGNORE INTO boot_links (target_uri) VALUES (?)", [targetUri]);
343882
+ const row = await this.db.fetchone("SELECT id, target_uri FROM boot_links WHERE target_uri = ?", [targetUri]);
343883
+ if (!row)
343884
+ throw new Error(`Failed to add boot link: ${targetUri}`);
343885
+ return { id: row[0], target_uri: row[1] };
343886
+ }
343887
+ async removeBootLink(uri, namespace = "") {
343888
+ const targetUri = uri.trim();
343889
+ await this.db.execute("DELETE FROM boot_links WHERE target_uri = ?", [targetUri]);
343890
+ return { removed_uri: targetUri };
343891
+ }
343892
+ async getBootLinks(namespace = "") {
343893
+ const rows = await this.db.fetchall("SELECT id, target_uri, created_at FROM boot_links ORDER BY created_at DESC");
343894
+ return rows.map(([id2, target_uri, created_at]) => ({ id: id2, target_uri, created_at }));
343895
+ }
343896
+ async resolveBootLinks(namespace = "") {
343897
+ const links = await this.getBootLinks(namespace);
343898
+ const missingLinks = [];
343899
+ const resolvedLinks = [];
343900
+ const contentParts = [];
343901
+ for (const link3 of links) {
343902
+ const [domain2, path7] = this._parseUri(link3.target_uri);
343903
+ const memory2 = await this.getMemoryByPath(path7, domain2, namespace);
343904
+ if (memory2 && memory2["content"]) {
343905
+ contentParts.push(`
343906
+ ${"=".repeat(60)}
343907
+ [BOOT LINK] ${link3.target_uri}
343908
+ ${"=".repeat(60)}
343909
+
343910
+ ${memory2["content"]}
343911
+ `);
343912
+ resolvedLinks.push({ uri: link3.target_uri, content: memory2["content"], found: true });
343913
+ } else {
343914
+ missingLinks.push(link3.target_uri);
343915
+ resolvedLinks.push({ uri: link3.target_uri, content: "", found: false });
343916
+ }
343901
343917
  }
343902
- const newUuid = randomUUID6();
343903
- await this._ensureNode(newUuid);
343904
- const memoryId = await this._insertMemory(newUuid, content);
343905
- await this._createEdgeWithPaths(ROOT_NODE_UUID, newUuid, "boot", "system", "boot", 0, null, namespace);
343906
- await this.search.refreshSearchDocumentsForNode(newUuid, namespace);
343907
- this._updateBootCache(namespace, content);
343908
343918
  return {
343909
- id: memoryId,
343910
- node_uuid: newUuid,
343911
- domain: "system",
343912
- path: "boot",
343913
- uri: "system://boot"
343919
+ content: contentParts.join(`
343920
+ `),
343921
+ missingLinks,
343922
+ links: resolvedLinks
343914
343923
  };
343915
343924
  }
343916
- _updateBootCache(namespace, content) {
343917
- try {
343918
- const module4 = (init_cce(), __toCommonJS(exports_cce));
343919
- module4.updateBootContentCache?.(namespace, content);
343920
- } catch {}
343925
+ _parseUri(uri) {
343926
+ const m2 = uri.trim().match(/^([a-zA-Z_][a-zA-Z0-9_]*):\/\/(.*)$/);
343927
+ if (m2) {
343928
+ return [m2[1].toLowerCase(), m2[2].trim().replace(/^\/+/, "")];
343929
+ }
343930
+ return ["code", uri.trim().replace(/^\/+/, "")];
343921
343931
  }
343922
343932
  async getMemoryIdByPath(path7, domain2 = "code", namespace = "") {
343923
343933
  const mem = await this.getMemoryByPath(path7, domain2, namespace);
@@ -350487,7 +350497,7 @@ var require_operation = __commonJS((exports, module4) => {
350487
350497
  // node_modules/@img/colour/color.cjs
350488
350498
  var require_color = __commonJS((exports, module4) => {
350489
350499
  var __defProp4 = Object.defineProperty;
350490
- var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
350500
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
350491
350501
  var __getOwnPropNames2 = Object.getOwnPropertyNames;
350492
350502
  var __hasOwnProp2 = Object.prototype.hasOwnProperty;
350493
350503
  var __export4 = (target2, all) => {
@@ -350498,16 +350508,16 @@ var require_color = __commonJS((exports, module4) => {
350498
350508
  if (from && typeof from === "object" || typeof from === "function") {
350499
350509
  for (let key of __getOwnPropNames2(from))
350500
350510
  if (!__hasOwnProp2.call(to2, key) && key !== except)
350501
- __defProp4(to2, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
350511
+ __defProp4(to2, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
350502
350512
  }
350503
350513
  return to2;
350504
350514
  };
350505
- var __toCommonJS2 = (mod) => __copyProps(__defProp4({}, "__esModule", { value: true }), mod);
350515
+ var __toCommonJS = (mod) => __copyProps(__defProp4({}, "__esModule", { value: true }), mod);
350506
350516
  var index_exports = {};
350507
350517
  __export4(index_exports, {
350508
350518
  default: () => index_default
350509
350519
  });
350510
- module4.exports = __toCommonJS2(index_exports);
350520
+ module4.exports = __toCommonJS(index_exports);
350511
350521
  var colors = {
350512
350522
  aliceblue: [240, 248, 255],
350513
350523
  antiquewhite: [250, 235, 215],
@@ -378650,30 +378660,71 @@ Removed: ${removed.join(", ") || "none"}` }] };
378650
378660
  }
378651
378661
  }),
378652
378662
  defineTool({
378653
- name: "update_boot",
378654
- label: "CCE: Update system boot context",
378655
- description: "Updates the system://boot context, which is loaded into Working Memory at session start.",
378663
+ name: "manage_boot_links",
378664
+ label: "CCE: Manage boot memory links",
378665
+ description: "Add, remove, or list memory nodes linked to boot. Linked nodes are automatically injected into Working Memory at session start.",
378656
378666
  parameters: exports_typebox.Object({
378657
- content: exports_typebox.String({ description: "New boot context content" })
378667
+ action: exports_typebox.Union([exports_typebox.Literal("add"), exports_typebox.Literal("remove"), exports_typebox.Literal("list")], {
378668
+ description: "Action to perform: 'add' links a memory, 'remove' unlinks it, 'list' shows all links"
378669
+ }),
378670
+ uri: exports_typebox.Optional(exports_typebox.String({ description: "Memory URI to link/unlink (required for add/remove)" }))
378658
378671
  }),
378659
378672
  execute: async (_id, params) => {
378660
- const { content } = params;
378673
+ const { action: action3, uri } = params;
378661
378674
  const namespace = ns2();
378662
- const result = await deps.graph.updateBoot(content, namespace);
378663
- return { details: result, content: [{ type: "text", text: `Updated system://boot (memory id: ${String(result["id"])})` }] };
378675
+ if (action3 === "list") {
378676
+ const links = await deps.graph.getBootLinks(namespace);
378677
+ if (links.length === 0) {
378678
+ return { details: {}, content: [{ type: "text", text: "No boot links configured." }] };
378679
+ }
378680
+ const lines = ["# Boot Links", "", "Currently linked memories:", ""];
378681
+ for (const link3 of links) {
378682
+ lines.push(`- ${link3.target_uri} (added: ${link3.created_at ?? "unknown"})`);
378683
+ }
378684
+ return { details: {}, content: [{ type: "text", text: lines.join(`
378685
+ `) }] };
378686
+ }
378687
+ if (action3 === "add" || action3 === "remove") {
378688
+ if (!uri) {
378689
+ return { details: {}, content: [{ type: "text", text: "URI is required for add/remove actions." }], isError: true };
378690
+ }
378691
+ if (action3 === "add") {
378692
+ const result = await deps.graph.addBootLink(uri, namespace);
378693
+ const { refreshBootCache } = await Promise.resolve().then(() => (init_cce(), exports_cce));
378694
+ await refreshBootCache(namespace, deps.graph);
378695
+ return { details: result, content: [{ type: "text", text: `Added boot link: ${uri}` }] };
378696
+ } else {
378697
+ const result = await deps.graph.removeBootLink(uri, namespace);
378698
+ const { refreshBootCache } = await Promise.resolve().then(() => (init_cce(), exports_cce));
378699
+ await refreshBootCache(namespace, deps.graph);
378700
+ return { details: result, content: [{ type: "text", text: `Removed boot link: ${uri}` }] };
378701
+ }
378702
+ }
378703
+ return { details: {}, content: [{ type: "text", text: "Invalid action" }], isError: true };
378664
378704
  }
378665
378705
  })
378666
378706
  ];
378667
378707
  }
378668
378708
  async function _generateBootView(graph, namespace) {
378669
- const lines = ["# Core Contexts", ""];
378670
- const boot = await graph.getMemoryByPath("boot", "system", namespace);
378671
- if (boot) {
378672
- lines.push(boot["content"]);
378709
+ const lines = ["# Boot Memory Links", "", "Linked memories that are injected at session start:", ""];
378710
+ const links = await graph.getBootLinks(namespace);
378711
+ if (links.length === 0) {
378712
+ lines.push("(No boot links configured. Use manage_boot_links to add memories.)");
378673
378713
  } else {
378674
- lines.push("(No boot context found. Run sync to generate one.)");
378714
+ for (const link3 of links) {
378715
+ lines.push(`## ${link3.target_uri}`);
378716
+ const [domain2, path7] = link3.target_uri.match(/^([a-zA-Z_][a-zA-Z0-9_]*):\/\/(.*)$/) ? [link3.target_uri.split("://")[0], link3.target_uri.split("://")[1]] : ["code", link3.target_uri];
378717
+ const memory2 = await graph.getMemoryByPath(path7, domain2, namespace);
378718
+ if (memory2 && memory2["content"]) {
378719
+ lines.push("");
378720
+ lines.push(memory2["content"]);
378721
+ } else {
378722
+ lines.push("_(memory not found or deleted)_");
378723
+ }
378724
+ lines.push("");
378725
+ }
378675
378726
  }
378676
- lines.push("");
378727
+ lines.push("", "---", "", "Recent Memories:", "");
378677
378728
  lines.push(await _generateRecentView(graph, namespace, 5));
378678
378729
  return lines.join(`
378679
378730
  `);
@@ -378798,19 +378849,20 @@ var init_agent_bridge = __esm(() => {
378798
378849
  // src/cce/index.ts
378799
378850
  var exports_cce = {};
378800
378851
  __export(exports_cce, {
378801
- updateBootContentCache: () => updateBootContentCache,
378802
378852
  stopCceServices: () => stopCceServices,
378803
378853
  startCceServices: () => startCceServices,
378804
378854
  scanProject: () => scanProject,
378805
378855
  resetCceSystem: () => resetCceSystem,
378856
+ refreshBootCache: () => refreshBootCache,
378806
378857
  isCceSystemReady: () => isCceSystemReady,
378807
378858
  initDb: () => initDb,
378808
378859
  initCceSystem: () => initCceSystem,
378860
+ getResolvedBootContent: () => getResolvedBootContent,
378809
378861
  getNamespaceContext: () => getNamespaceContext,
378810
378862
  getEmbeddingService: () => getEmbeddingService,
378811
378863
  getDbManager: () => getDbManager,
378812
378864
  getCceSystem: () => getCceSystem,
378813
- getCachedBootContent: () => getCachedBootContent,
378865
+ getCachedBootLinks: () => getCachedBootLinks,
378814
378866
  detectLanguage: () => detectLanguage,
378815
378867
  createCceToolDefinitions: () => createCceToolDefinitions,
378816
378868
  closeDbManager: () => closeDbManager,
@@ -378832,11 +378884,31 @@ __export(exports_cce, {
378832
378884
  AssociativeNetwork: () => AssociativeNetwork,
378833
378885
  ActivationEngine: () => ActivationEngine
378834
378886
  });
378835
- function getCachedBootContent(namespace) {
378836
- return _bootContentCache.get(namespace) ?? null;
378887
+ function getCachedBootLinks(namespace) {
378888
+ return _bootLinksCache.get(namespace) ?? [];
378889
+ }
378890
+ async function refreshBootCache(namespace, graph2) {
378891
+ const resolved = await graph2.resolveBootLinks(namespace);
378892
+ _bootLinksCache.set(namespace, resolved.links.filter((l) => l.found).map((l) => ({ uri: l.uri, content: l.content })));
378893
+ return {
378894
+ content: resolved.content,
378895
+ missingLinks: resolved.missingLinks
378896
+ };
378837
378897
  }
378838
- function updateBootContentCache(namespace, content) {
378839
- _bootContentCache.set(namespace, content);
378898
+ function getResolvedBootContent(namespace) {
378899
+ const links = _bootLinksCache.get(namespace) ?? [];
378900
+ const contentParts = [];
378901
+ for (const link3 of links) {
378902
+ contentParts.push(`
378903
+ ${"=".repeat(60)}
378904
+ [BOOT LINK] ${link3.uri}
378905
+ ${"=".repeat(60)}
378906
+
378907
+ ${link3.content}
378908
+ `);
378909
+ }
378910
+ return contentParts.join(`
378911
+ `);
378840
378912
  }
378841
378913
  async function initCceSystem(onProgress, onDownloadProgress) {
378842
378914
  if (_system)
@@ -378879,10 +378951,7 @@ async function initCceSystem(onProgress, onDownloadProgress) {
378879
378951
  disclosure
378880
378952
  };
378881
378953
  try {
378882
- const bootMem = await graph2.getMemoryByPath("boot", "system", namespace);
378883
- if (bootMem && bootMem["content"] && bootMem["content"].trim()) {
378884
- updateBootContentCache(namespace, bootMem["content"].trim());
378885
- }
378954
+ await refreshBootCache(namespace, graph2);
378886
378955
  } catch {}
378887
378956
  return _system;
378888
378957
  }
@@ -378936,10 +379005,10 @@ function resetCceSystem() {
378936
379005
  } catch {}
378937
379006
  }
378938
379007
  _system = null;
378939
- _bootContentCache.clear();
379008
+ _bootLinksCache.clear();
378940
379009
  getEmbeddingService().reset();
378941
379010
  }
378942
- var _bootContentCache, _system = null, _dreamTimer = null;
379011
+ var _bootLinksCache, _system = null, _dreamTimer = null;
378943
379012
  var init_cce = __esm(() => {
378944
379013
  init_db();
378945
379014
  init_init();
@@ -378954,7 +379023,7 @@ var init_cce = __esm(() => {
378954
379023
  init_graph();
378955
379024
  init_sync();
378956
379025
  init_agent_bridge();
378957
- _bootContentCache = new Map;
379026
+ _bootLinksCache = new Map;
378958
379027
  });
378959
379028
 
378960
379029
  // node_modules/delayed-stream/lib/delayed_stream.js
@@ -527827,7 +527896,7 @@ Key principles:
527827
527896
  - Use commit_insight to capture insights that are tightly related to the current conversation\u2014it auto-links to all active Working Memory nodes.
527828
527897
  - Use fuzzySearch to find nodes when you are unsure of the URI.
527829
527898
  - Use link_context to connect related concepts so they activate together in future turns.
527830
- - Use update_boot to modify the system://boot context, which is loaded at every session start.
527899
+ - Use manage_boot_links to add, remove, or list memory nodes linked to boot.
527831
527900
  - code:// nodes are auto-maintained by the background sync engine. Do not manually create or update code:// nodes.
527832
527901
  `;
527833
527902
  async function createAgentSessionWithConfig(sessionManager, config4) {
@@ -527854,11 +527923,11 @@ You are highly capable and often allow users to complete ambitious tasks that wo
527854
527923
  }
527855
527924
  try {
527856
527925
  const namespace = getNamespaceContext().current;
527857
- const bootContent = getCachedBootContent(namespace);
527926
+ const bootContent = getResolvedBootContent(namespace);
527858
527927
  if (bootContent) {
527859
527928
  newPrompt += `
527860
527929
 
527861
- === Boot Memory ===
527930
+ === Boot Memory Links ===
527862
527931
 
527863
527932
  ` + bootContent;
527864
527933
  }
package/dist/schema.sql CHANGED
@@ -167,5 +167,12 @@ CREATE TABLE IF NOT EXISTS memory_episodes (
167
167
  CREATE INDEX IF NOT EXISTS idx_episodes_node ON memory_episodes(node_uuid, created_at);
168
168
  CREATE INDEX IF NOT EXISTS idx_episodes_type ON memory_episodes(episode_type, created_at);
169
169
 
170
+ -- Boot 链接表:存储链接到 boot 的记忆节点 URI
171
+ CREATE TABLE IF NOT EXISTS boot_links (
172
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
173
+ target_uri TEXT NOT NULL UNIQUE,
174
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
175
+ );
176
+
170
177
  -- Schema version marker
171
178
  INSERT OR IGNORE INTO _schema_version (version) VALUES (1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meowlynxsea/koi",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "A coding agent built on Pi SDK with TUI + Bun runtime",
5
5
  "module": "src/main.tsx",
6
6
  "type": "module",
@@ -357,19 +357,54 @@ export function createCceToolDefinitions(deps: CceToolDeps): ToolDefinition[] {
357
357
  },
358
358
  }),
359
359
 
360
- // ─── update_boot ───
360
+ // ─── manage_boot_links ───
361
361
  defineTool({
362
- name: "update_boot",
363
- label: "CCE: Update system boot context",
364
- description: "Updates the system://boot context, which is loaded into Working Memory at session start.",
362
+ name: "manage_boot_links",
363
+ label: "CCE: Manage boot memory links",
364
+ description: "Add, remove, or list memory nodes linked to boot. Linked nodes are automatically injected into Working Memory at session start.",
365
365
  parameters: Type.Object({
366
- content: Type.String({ description: "New boot context content" }),
366
+ action: Type.Union([Type.Literal("add"), Type.Literal("remove"), Type.Literal("list")], {
367
+ description: "Action to perform: 'add' links a memory, 'remove' unlinks it, 'list' shows all links",
368
+ }),
369
+ uri: Type.Optional(Type.String({ description: "Memory URI to link/unlink (required for add/remove)" })),
367
370
  }),
368
371
  execute: async (_id, params) => {
369
- const { content } = params as { content: string };
372
+ const { action, uri } = params as { action: "add" | "remove" | "list"; uri?: string };
370
373
  const namespace = ns();
371
- const result = await deps.graph.updateBoot(content, namespace);
372
- return { details: result, content: [{ type: "text", text: `Updated system://boot (memory id: ${String(result['id'])})` }] };
374
+
375
+ if (action === "list") {
376
+ const links = await deps.graph.getBootLinks(namespace);
377
+ if (links.length === 0) {
378
+ return { details: {}, content: [{ type: "text", text: "No boot links configured." }] };
379
+ }
380
+ const lines = ["# Boot Links", "", "Currently linked memories:", ""];
381
+ for (const link of links) {
382
+ lines.push(`- ${link.target_uri} (added: ${link.created_at ?? "unknown"})`);
383
+ }
384
+ return { details: {}, content: [{ type: "text", text: lines.join("\n") }] };
385
+ }
386
+
387
+ if (action === "add" || action === "remove") {
388
+ if (!uri) {
389
+ return { details: {}, content: [{ type: "text", text: "URI is required for add/remove actions." }], isError: true };
390
+ }
391
+
392
+ if (action === "add") {
393
+ const result = await deps.graph.addBootLink(uri, namespace);
394
+ // Refresh boot cache
395
+ const { refreshBootCache } = await import("../index.js");
396
+ await refreshBootCache(namespace, deps.graph);
397
+ return { details: result, content: [{ type: "text", text: `Added boot link: ${uri}` }] };
398
+ } else {
399
+ const result = await deps.graph.removeBootLink(uri, namespace);
400
+ // Refresh boot cache
401
+ const { refreshBootCache } = await import("../index.js");
402
+ await refreshBootCache(namespace, deps.graph);
403
+ return { details: result, content: [{ type: "text", text: `Removed boot link: ${uri}` }] };
404
+ }
405
+ }
406
+
407
+ return { details: {}, content: [{ type: "text", text: "Invalid action" }], isError: true };
373
408
  },
374
409
  }),
375
410
 
@@ -379,14 +414,29 @@ export function createCceToolDefinitions(deps: CceToolDeps): ToolDefinition[] {
379
414
  // ─── View generators ───
380
415
 
381
416
  async function _generateBootView(graph: GraphService, namespace: string): Promise<string> {
382
- const lines = ["# Core Contexts", ""];
383
- const boot = await graph.getMemoryByPath("boot", "system", namespace);
384
- if (boot) {
385
- lines.push(boot['content'] as string);
417
+ const lines = ["# Boot Memory Links", "", "Linked memories that are injected at session start:", ""];
418
+
419
+ const links = await graph.getBootLinks(namespace);
420
+ if (links.length === 0) {
421
+ lines.push("(No boot links configured. Use manage_boot_links to add memories.)");
386
422
  } else {
387
- lines.push("(No boot context found. Run sync to generate one.)");
423
+ for (const link of links) {
424
+ lines.push(`## ${link.target_uri}`);
425
+ const [domain, path] = link.target_uri.match(/^([a-zA-Z_][a-zA-Z0-9_]*):\/\/(.*)$/)
426
+ ? [link.target_uri.split("://")[0], link.target_uri.split("://")[1]]
427
+ : ["code", link.target_uri];
428
+ const memory = await graph.getMemoryByPath(path, domain, namespace);
429
+ if (memory && memory['content']) {
430
+ lines.push("");
431
+ lines.push(memory['content'] as string);
432
+ } else {
433
+ lines.push("_(memory not found or deleted)_");
434
+ }
435
+ lines.push("");
436
+ }
388
437
  }
389
- lines.push("");
438
+
439
+ lines.push("", "---", "", "Recent Memories:", "");
390
440
  lines.push(await _generateRecentView(graph, namespace, 5));
391
441
  return lines.join("\n");
392
442
  }
@@ -167,5 +167,12 @@ CREATE TABLE IF NOT EXISTS memory_episodes (
167
167
  CREATE INDEX IF NOT EXISTS idx_episodes_node ON memory_episodes(node_uuid, created_at);
168
168
  CREATE INDEX IF NOT EXISTS idx_episodes_type ON memory_episodes(episode_type, created_at);
169
169
 
170
+ -- Boot 链接表:存储链接到 boot 的记忆节点 URI
171
+ CREATE TABLE IF NOT EXISTS boot_links (
172
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
173
+ target_uri TEXT NOT NULL UNIQUE,
174
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
175
+ );
176
+
170
177
  -- Schema version marker
171
178
  INSERT OR IGNORE INTO _schema_version (version) VALUES (1);
@@ -873,39 +873,77 @@ export class GraphService {
873
873
  return { deleted_uri: `${domain}://${path}`, node_uuid: nodeUuid };
874
874
  }
875
875
 
876
- async updateBoot(content: string, namespace = ""): Promise<Record<string, unknown>> {
877
- const boot = await this.getMemoryByPath("boot", "system", namespace);
878
- if (boot) {
879
- const result = await this.updateMemory("boot", content, "system", namespace);
880
- // Update synchronous cache for system prompt injection
881
- this._updateBootCache(namespace, content);
882
- return result;
876
+ // =====================================================================
877
+ // Boot Links Management
878
+ // =====================================================================
879
+
880
+ async addBootLink(uri: string, namespace = ""): Promise<{ id: number; target_uri: string }> {
881
+ const targetUri = uri.trim();
882
+ if (!targetUri) throw new Error("URI cannot be empty");
883
+
884
+ await this.db.execute(
885
+ "INSERT OR IGNORE INTO boot_links (target_uri) VALUES (?)",
886
+ [targetUri]
887
+ );
888
+
889
+ const row = await this.db.fetchone<[number, string]>(
890
+ "SELECT id, target_uri FROM boot_links WHERE target_uri = ?",
891
+ [targetUri]
892
+ );
893
+
894
+ if (!row) throw new Error(`Failed to add boot link: ${targetUri}`);
895
+ return { id: row[0], target_uri: row[1] };
896
+ }
897
+
898
+ async removeBootLink(uri: string, namespace = ""): Promise<{ removed_uri: string }> {
899
+ const targetUri = uri.trim();
900
+ await this.db.execute("DELETE FROM boot_links WHERE target_uri = ?", [targetUri]);
901
+ return { removed_uri: targetUri };
902
+ }
903
+
904
+ async getBootLinks(namespace = ""): Promise<Array<{ id: number; target_uri: string; created_at: string | null }>> {
905
+ const rows = await this.db.fetchall<[number, string, string | null]>(
906
+ "SELECT id, target_uri, created_at FROM boot_links ORDER BY created_at DESC"
907
+ );
908
+ return rows.map(([id, target_uri, created_at]) => ({ id, target_uri, created_at }));
909
+ }
910
+
911
+ async resolveBootLinks(namespace = ""): Promise<{
912
+ content: string;
913
+ missingLinks: string[];
914
+ links: Array<{ uri: string; content: string; found: boolean }>;
915
+ }> {
916
+ const links = await this.getBootLinks(namespace);
917
+ const missingLinks: string[] = [];
918
+ const resolvedLinks: Array<{ uri: string; content: string; found: boolean }> = [];
919
+ const contentParts: string[] = [];
920
+
921
+ for (const link of links) {
922
+ const [domain, path] = this._parseUri(link.target_uri);
923
+ const memory = await this.getMemoryByPath(path, domain, namespace);
924
+
925
+ if (memory && memory['content']) {
926
+ contentParts.push(`\n${'='.repeat(60)}\n[BOOT LINK] ${link.target_uri}\n${'='.repeat(60)}\n\n${memory['content'] as string}\n`);
927
+ resolvedLinks.push({ uri: link.target_uri, content: memory['content'] as string, found: true });
928
+ } else {
929
+ missingLinks.push(link.target_uri);
930
+ resolvedLinks.push({ uri: link.target_uri, content: "", found: false });
931
+ }
883
932
  }
884
- // Create boot node under root if not exists
885
- const newUuid = randomUUID();
886
- await this._ensureNode(newUuid);
887
- const memoryId = await this._insertMemory(newUuid, content);
888
- await this._createEdgeWithPaths(ROOT_NODE_UUID, newUuid, "boot", "system", "boot", 0, null, namespace);
889
- await this.search.refreshSearchDocumentsForNode(newUuid, namespace);
890
- // Update synchronous cache for system prompt injection
891
- this._updateBootCache(namespace, content);
933
+
892
934
  return {
893
- id: memoryId,
894
- node_uuid: newUuid,
895
- domain: "system",
896
- path: "boot",
897
- uri: "system://boot",
935
+ content: contentParts.join("\n"),
936
+ missingLinks,
937
+ links: resolvedLinks,
898
938
  };
899
939
  }
900
940
 
901
- private _updateBootCache(namespace: string, content: string): void {
902
- try {
903
- // Dynamically import to avoid circular dependency
904
- const module = require("../index.js") as { updateBootContentCache?: (ns: string, c: string) => void };
905
- module.updateBootContentCache?.(namespace, content);
906
- } catch {
907
- // ignore - cache will be refreshed on next CCE init
941
+ private _parseUri(uri: string): [string, string] {
942
+ const m = uri.trim().match(/^([a-zA-Z_][a-zA-Z0-9_]*):\/\/(.*)$/);
943
+ if (m) {
944
+ return [m[1]!.toLowerCase(), m[2]!.trim().replace(/^\/+/, "")];
908
945
  }
946
+ return ["code", uri.trim().replace(/^\/+/, "")];
909
947
  }
910
948
 
911
949
  async getMemoryIdByPath(path: string, domain = "code", namespace = ""): Promise<number | null> {
package/src/cce/index.ts CHANGED
@@ -23,15 +23,32 @@ import { PromptInjector } from "./agent-bridge/prompt-injector.js";
23
23
  import { DisclosureEngine } from "./agent-bridge/disclosure-engine.js";
24
24
  import { getNamespaceContext } from "./agent-bridge/namespace-context.js";
25
25
 
26
- // ─── Boot Memory Cache (synchronous access for system prompt injection) ───
27
- const _bootContentCache = new Map<string, string>();
26
+ // ─── Boot Links Cache (synchronous access for system prompt injection) ───
27
+ const _bootLinksCache = new Map<string, Array<{ uri: string; content: string }>>();
28
28
 
29
- export function getCachedBootContent(namespace: string): string | null {
30
- return _bootContentCache.get(namespace) ?? null;
29
+ export function getCachedBootLinks(namespace: string): Array<{ uri: string; content: string }> {
30
+ return _bootLinksCache.get(namespace) ?? [];
31
31
  }
32
32
 
33
- export function updateBootContentCache(namespace: string, content: string): void {
34
- _bootContentCache.set(namespace, content);
33
+ export async function refreshBootCache(namespace: string, graph: GraphService): Promise<{
34
+ content: string;
35
+ missingLinks: string[];
36
+ }> {
37
+ const resolved = await graph.resolveBootLinks(namespace);
38
+ _bootLinksCache.set(namespace, resolved.links.filter(l => l.found).map(l => ({ uri: l.uri, content: l.content })));
39
+ return {
40
+ content: resolved.content,
41
+ missingLinks: resolved.missingLinks,
42
+ };
43
+ }
44
+
45
+ export function getResolvedBootContent(namespace: string): string {
46
+ const links = _bootLinksCache.get(namespace) ?? [];
47
+ const contentParts: string[] = [];
48
+ for (const link of links) {
49
+ contentParts.push(`\n${'='.repeat(60)}\n[BOOT LINK] ${link.uri}\n${'='.repeat(60)}\n\n${link.content}\n`);
50
+ }
51
+ return contentParts.join("\n");
35
52
  }
36
53
 
37
54
  export interface CceDownloadProgress {
@@ -113,14 +130,11 @@ export async function initCceSystem(
113
130
  disclosure,
114
131
  };
115
132
 
116
- // Load boot content into synchronous cache for system prompt injection
133
+ // Load boot links into synchronous cache for system prompt injection
117
134
  try {
118
- const bootMem = await graph.getMemoryByPath("boot", "system", namespace);
119
- if (bootMem && bootMem['content'] && (bootMem['content'] as string).trim()) {
120
- updateBootContentCache(namespace, (bootMem['content'] as string).trim());
121
- }
135
+ await refreshBootCache(namespace, graph);
122
136
  } catch {
123
- // ignore - boot memory will be loaded on demand
137
+ // ignore - boot links will be loaded on demand
124
138
  }
125
139
 
126
140
  return _system;
@@ -184,7 +198,7 @@ export function resetCceSystem(): void {
184
198
  try { _system.db.close(); } catch { /* ignore */ }
185
199
  }
186
200
  _system = null;
187
- _bootContentCache.clear();
201
+ _bootLinksCache.clear();
188
202
  getEmbeddingService().reset();
189
203
  }
190
204