mindcache 3.4.1 → 3.4.2

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.
@@ -8,17 +8,13 @@ import * as Y from 'yjs';
8
8
  type AccessLevel = 'user' | 'system';
9
9
  /**
10
10
  * Known system tags that control key behavior
11
- * - 'SystemPrompt': Include in system prompt
12
- * - 'LLMRead': LLM can read this key (visible to LLMs)
11
+ * - 'SystemPrompt': Include in system prompt (visible to LLM context)
12
+ * - 'LLMRead': LLM can read this key via tools
13
13
  * - 'LLMWrite': LLM can write to this key via tools
14
- * - 'protected': Cannot be deleted (replaces hardcoded)
14
+ * - 'protected': Cannot be deleted
15
15
  * - 'ApplyTemplate': Process value through template injection
16
- *
17
- * @deprecated 'prompt' - Use 'SystemPrompt' instead
18
- * @deprecated 'readonly' - Use absence of 'LLMWrite' instead (if LLMWrite not present, readonly=true)
19
- * @deprecated 'template' - Use 'ApplyTemplate' instead
20
16
  */
21
- type SystemTag = 'SystemPrompt' | 'LLMRead' | 'LLMWrite' | 'protected' | 'ApplyTemplate' | 'prompt' | 'readonly' | 'template';
17
+ type SystemTag = 'SystemPrompt' | 'LLMRead' | 'LLMWrite' | 'protected' | 'ApplyTemplate';
22
18
  /**
23
19
  * Type of value stored in a MindCache key
24
20
  */
@@ -37,17 +33,11 @@ interface KeyAttributes {
37
33
  systemTags: SystemTag[];
38
34
  /** Z-index for ordering keys (lower values appear first) */
39
35
  zIndex: number;
40
- /** @deprecated Use !systemTags.includes('LLMWrite') instead */
41
- readonly: boolean;
42
- /** @deprecated Use systemTags.includes('SystemPrompt') instead */
43
- visible: boolean;
44
- /** @deprecated Use systemTags.includes('protected') instead */
45
- hardcoded: boolean;
46
- /** @deprecated Use systemTags.includes('ApplyTemplate') instead */
47
- template: boolean;
48
- /** @deprecated Use contentTags instead */
49
- tags?: string[];
50
36
  }
37
+ /**
38
+ * Default attributes for new keys
39
+ */
40
+ declare const DEFAULT_KEY_ATTRIBUTES: KeyAttributes;
51
41
  /**
52
42
  * A single entry in the MindCache store
53
43
  */
@@ -71,10 +61,6 @@ type Listener = (value: unknown) => void;
71
61
  * Called when any key changes (no parameters - use getAll() to get current state)
72
62
  */
73
63
  type GlobalListener = () => void;
74
- /**
75
- * Default attributes for new keys
76
- */
77
- declare const DEFAULT_KEY_ATTRIBUTES: KeyAttributes;
78
64
  /**
79
65
  * A single entry in the global history log
80
66
  */
@@ -95,6 +81,21 @@ interface HistoryOptions {
95
81
  /** Save full snapshot every N entries for fast restore (default: 10) */
96
82
  snapshotInterval?: number;
97
83
  }
84
+ /**
85
+ * Helper functions for working with system tags
86
+ */
87
+ declare const SystemTagHelpers: {
88
+ /** Check if key is writable by LLM */
89
+ isLLMWritable: (attrs: KeyAttributes) => boolean;
90
+ /** Check if key is readable by LLM (in context or via tools) */
91
+ isLLMReadable: (attrs: KeyAttributes) => boolean;
92
+ /** Check if key is included in system prompt */
93
+ isInSystemPrompt: (attrs: KeyAttributes) => boolean;
94
+ /** Check if key is protected from deletion */
95
+ isProtected: (attrs: KeyAttributes) => boolean;
96
+ /** Check if key uses template injection */
97
+ hasTemplateInjection: (attrs: KeyAttributes) => boolean;
98
+ };
98
99
 
99
100
  /**
100
101
  * Cloud configuration options for MindCache constructor
@@ -245,6 +246,16 @@ declare class MindCache {
245
246
  */
246
247
  set_attributes(key: string, attributes: Partial<KeyAttributes>): void;
247
248
  set_value(key: string, value: any, attributes?: Partial<KeyAttributes>): void;
249
+ /**
250
+ * LLM-safe method to write a value to a key.
251
+ * This method:
252
+ * - Only updates the value, never modifies attributes/systemTags
253
+ * - Checks LLMWrite permission before writing
254
+ * - Returns false if key doesn't exist or lacks LLMWrite permission
255
+ *
256
+ * Used by create_vercel_ai_tools() to prevent LLMs from escalating privileges.
257
+ */
258
+ llm_set_key(key: string, value: any): boolean;
248
259
  delete_key(key: string): void;
249
260
  clear(): void;
250
261
  /**
@@ -427,6 +438,14 @@ declare class MindCache {
427
438
  /**
428
439
  * Generate Vercel AI SDK compatible tools for writable keys.
429
440
  * For document type keys, generates additional tools: append_, insert_, edit_
441
+ *
442
+ * Security: All tools use llm_set_key internally which:
443
+ * - Only modifies VALUES, never attributes/systemTags
444
+ * - Prevents LLMs from escalating privileges
445
+ */
446
+ create_vercel_ai_tools(): Record<string, any>;
447
+ /**
448
+ * @deprecated Use create_vercel_ai_tools() instead
430
449
  */
431
450
  get_aisdk_tools(): Record<string, any>;
432
451
  /**
@@ -530,4 +549,4 @@ declare class CloudAdapter {
530
549
  private scheduleReconnect;
531
550
  }
532
551
 
533
- export { type AccessLevel as A, CloudAdapter as C, DEFAULT_KEY_ATTRIBUTES as D, type GlobalListener as G, type HistoryEntry as H, type KeyAttributes as K, type Listener as L, MindCache as M, type Operation as O, type SystemTag as S, type MindCacheOptions as a, type KeyType as b, type STM as c, type STMEntry as d, type HistoryOptions as e, type MindCacheCloudOptions as f, type MindCacheIndexedDBOptions as g, type CloudConfig as h, type ConnectionState as i, type CloudAdapterEvents as j, type SetOperation as k, type DeleteOperation as l, type ClearOperation as m };
552
+ export { type AccessLevel as A, CloudAdapter as C, DEFAULT_KEY_ATTRIBUTES as D, type GlobalListener as G, type HistoryEntry as H, type KeyAttributes as K, type Listener as L, MindCache as M, type Operation as O, type SystemTag as S, type MindCacheOptions as a, type KeyType as b, type STM as c, type STMEntry as d, type HistoryOptions as e, type MindCacheCloudOptions as f, type MindCacheIndexedDBOptions as g, SystemTagHelpers as h, type CloudConfig as i, type ConnectionState as j, type CloudAdapterEvents as k, type SetOperation as l, type DeleteOperation as m, type ClearOperation as n };
@@ -8,17 +8,13 @@ import * as Y from 'yjs';
8
8
  type AccessLevel = 'user' | 'system';
9
9
  /**
10
10
  * Known system tags that control key behavior
11
- * - 'SystemPrompt': Include in system prompt
12
- * - 'LLMRead': LLM can read this key (visible to LLMs)
11
+ * - 'SystemPrompt': Include in system prompt (visible to LLM context)
12
+ * - 'LLMRead': LLM can read this key via tools
13
13
  * - 'LLMWrite': LLM can write to this key via tools
14
- * - 'protected': Cannot be deleted (replaces hardcoded)
14
+ * - 'protected': Cannot be deleted
15
15
  * - 'ApplyTemplate': Process value through template injection
16
- *
17
- * @deprecated 'prompt' - Use 'SystemPrompt' instead
18
- * @deprecated 'readonly' - Use absence of 'LLMWrite' instead (if LLMWrite not present, readonly=true)
19
- * @deprecated 'template' - Use 'ApplyTemplate' instead
20
16
  */
21
- type SystemTag = 'SystemPrompt' | 'LLMRead' | 'LLMWrite' | 'protected' | 'ApplyTemplate' | 'prompt' | 'readonly' | 'template';
17
+ type SystemTag = 'SystemPrompt' | 'LLMRead' | 'LLMWrite' | 'protected' | 'ApplyTemplate';
22
18
  /**
23
19
  * Type of value stored in a MindCache key
24
20
  */
@@ -37,17 +33,11 @@ interface KeyAttributes {
37
33
  systemTags: SystemTag[];
38
34
  /** Z-index for ordering keys (lower values appear first) */
39
35
  zIndex: number;
40
- /** @deprecated Use !systemTags.includes('LLMWrite') instead */
41
- readonly: boolean;
42
- /** @deprecated Use systemTags.includes('SystemPrompt') instead */
43
- visible: boolean;
44
- /** @deprecated Use systemTags.includes('protected') instead */
45
- hardcoded: boolean;
46
- /** @deprecated Use systemTags.includes('ApplyTemplate') instead */
47
- template: boolean;
48
- /** @deprecated Use contentTags instead */
49
- tags?: string[];
50
36
  }
37
+ /**
38
+ * Default attributes for new keys
39
+ */
40
+ declare const DEFAULT_KEY_ATTRIBUTES: KeyAttributes;
51
41
  /**
52
42
  * A single entry in the MindCache store
53
43
  */
@@ -71,10 +61,6 @@ type Listener = (value: unknown) => void;
71
61
  * Called when any key changes (no parameters - use getAll() to get current state)
72
62
  */
73
63
  type GlobalListener = () => void;
74
- /**
75
- * Default attributes for new keys
76
- */
77
- declare const DEFAULT_KEY_ATTRIBUTES: KeyAttributes;
78
64
  /**
79
65
  * A single entry in the global history log
80
66
  */
@@ -95,6 +81,21 @@ interface HistoryOptions {
95
81
  /** Save full snapshot every N entries for fast restore (default: 10) */
96
82
  snapshotInterval?: number;
97
83
  }
84
+ /**
85
+ * Helper functions for working with system tags
86
+ */
87
+ declare const SystemTagHelpers: {
88
+ /** Check if key is writable by LLM */
89
+ isLLMWritable: (attrs: KeyAttributes) => boolean;
90
+ /** Check if key is readable by LLM (in context or via tools) */
91
+ isLLMReadable: (attrs: KeyAttributes) => boolean;
92
+ /** Check if key is included in system prompt */
93
+ isInSystemPrompt: (attrs: KeyAttributes) => boolean;
94
+ /** Check if key is protected from deletion */
95
+ isProtected: (attrs: KeyAttributes) => boolean;
96
+ /** Check if key uses template injection */
97
+ hasTemplateInjection: (attrs: KeyAttributes) => boolean;
98
+ };
98
99
 
99
100
  /**
100
101
  * Cloud configuration options for MindCache constructor
@@ -245,6 +246,16 @@ declare class MindCache {
245
246
  */
246
247
  set_attributes(key: string, attributes: Partial<KeyAttributes>): void;
247
248
  set_value(key: string, value: any, attributes?: Partial<KeyAttributes>): void;
249
+ /**
250
+ * LLM-safe method to write a value to a key.
251
+ * This method:
252
+ * - Only updates the value, never modifies attributes/systemTags
253
+ * - Checks LLMWrite permission before writing
254
+ * - Returns false if key doesn't exist or lacks LLMWrite permission
255
+ *
256
+ * Used by create_vercel_ai_tools() to prevent LLMs from escalating privileges.
257
+ */
258
+ llm_set_key(key: string, value: any): boolean;
248
259
  delete_key(key: string): void;
249
260
  clear(): void;
250
261
  /**
@@ -427,6 +438,14 @@ declare class MindCache {
427
438
  /**
428
439
  * Generate Vercel AI SDK compatible tools for writable keys.
429
440
  * For document type keys, generates additional tools: append_, insert_, edit_
441
+ *
442
+ * Security: All tools use llm_set_key internally which:
443
+ * - Only modifies VALUES, never attributes/systemTags
444
+ * - Prevents LLMs from escalating privileges
445
+ */
446
+ create_vercel_ai_tools(): Record<string, any>;
447
+ /**
448
+ * @deprecated Use create_vercel_ai_tools() instead
430
449
  */
431
450
  get_aisdk_tools(): Record<string, any>;
432
451
  /**
@@ -530,4 +549,4 @@ declare class CloudAdapter {
530
549
  private scheduleReconnect;
531
550
  }
532
551
 
533
- export { type AccessLevel as A, CloudAdapter as C, DEFAULT_KEY_ATTRIBUTES as D, type GlobalListener as G, type HistoryEntry as H, type KeyAttributes as K, type Listener as L, MindCache as M, type Operation as O, type SystemTag as S, type MindCacheOptions as a, type KeyType as b, type STM as c, type STMEntry as d, type HistoryOptions as e, type MindCacheCloudOptions as f, type MindCacheIndexedDBOptions as g, type CloudConfig as h, type ConnectionState as i, type CloudAdapterEvents as j, type SetOperation as k, type DeleteOperation as l, type ClearOperation as m };
552
+ export { type AccessLevel as A, CloudAdapter as C, DEFAULT_KEY_ATTRIBUTES as D, type GlobalListener as G, type HistoryEntry as H, type KeyAttributes as K, type Listener as L, MindCache as M, type Operation as O, type SystemTag as S, type MindCacheOptions as a, type KeyType as b, type STM as c, type STMEntry as d, type HistoryOptions as e, type MindCacheCloudOptions as f, type MindCacheIndexedDBOptions as g, SystemTagHelpers as h, type CloudConfig as i, type ConnectionState as j, type CloudAdapterEvents as k, type SetOperation as l, type DeleteOperation as m, type ClearOperation as n };
@@ -1,5 +1,5 @@
1
- import { M as MindCache, h as CloudConfig, C as CloudAdapter } from '../CloudAdapter-C0UyG6OY.mjs';
2
- export { m as ClearOperation, j as CloudAdapterEvents, i as ConnectionState, l as DeleteOperation, O as Operation, k as SetOperation } from '../CloudAdapter-C0UyG6OY.mjs';
1
+ import { M as MindCache, i as CloudConfig, C as CloudAdapter } from '../CloudAdapter-D2xxVv4E.mjs';
2
+ export { n as ClearOperation, k as CloudAdapterEvents, j as ConnectionState, m as DeleteOperation, O as Operation, l as SetOperation } from '../CloudAdapter-D2xxVv4E.mjs';
3
3
  import 'yjs';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { M as MindCache, h as CloudConfig, C as CloudAdapter } from '../CloudAdapter-C0UyG6OY.js';
2
- export { m as ClearOperation, j as CloudAdapterEvents, i as ConnectionState, l as DeleteOperation, O as Operation, k as SetOperation } from '../CloudAdapter-C0UyG6OY.js';
1
+ import { M as MindCache, i as CloudConfig, C as CloudAdapter } from '../CloudAdapter-D2xxVv4E.js';
2
+ export { n as ClearOperation, k as CloudAdapterEvents, j as ConnectionState, m as DeleteOperation, O as Operation, l as SetOperation } from '../CloudAdapter-D2xxVv4E.js';
3
3
  import 'yjs';
4
4
 
5
5
  /**
@@ -453,15 +453,9 @@ var init_CloudAdapter = __esm({
453
453
  var DEFAULT_KEY_ATTRIBUTES = {
454
454
  type: "text",
455
455
  contentTags: [],
456
- systemTags: ["SystemPrompt", "LLMWrite"],
457
- // visible in system prompt and writable by LLM by default
458
- zIndex: 0,
459
- // Legacy - derived from systemTags
460
- readonly: false,
461
- visible: true,
462
- hardcoded: false,
463
- template: false,
464
- tags: []
456
+ systemTags: [],
457
+ // Keys are private by default - explicitly add SystemPrompt/LLMRead/LLMWrite to enable LLM access
458
+ zIndex: 0
465
459
  };
466
460
 
467
461
  // src/core/MindCache.ts
@@ -479,35 +473,14 @@ var MindCache = class {
479
473
  // (Less critical with Yjs but kept for API compat)
480
474
  normalizeSystemTags(tags) {
481
475
  const normalized = [];
482
- let hasSystemPrompt = false;
483
- let hasLLMRead = false;
484
- let hasLLMWrite = false;
485
- let hasReadonly = false;
476
+ const seen = /* @__PURE__ */ new Set();
486
477
  for (const tag of tags) {
487
- if (tag === "SystemPrompt" || tag === "prompt") {
488
- hasSystemPrompt = true;
489
- } else if (tag === "LLMRead") {
490
- hasLLMRead = true;
491
- } else if (tag === "LLMWrite") {
492
- hasLLMWrite = true;
493
- } else if (tag === "readonly") {
494
- hasReadonly = true;
495
- } else if (tag === "protected") {
496
- normalized.push(tag);
497
- } else if (tag === "ApplyTemplate" || tag === "template") {
498
- normalized.push("ApplyTemplate");
499
- }
500
- }
501
- if (hasSystemPrompt) {
502
- normalized.push("SystemPrompt");
503
- }
504
- if (hasLLMRead) {
505
- normalized.push("LLMRead");
506
- }
507
- if (hasReadonly) {
508
- normalized.push("readonly");
509
- } else if (hasLLMWrite) {
510
- normalized.push("LLMWrite");
478
+ if (["SystemPrompt", "LLMRead", "LLMWrite", "protected", "ApplyTemplate"].includes(tag)) {
479
+ if (!seen.has(tag)) {
480
+ seen.add(tag);
481
+ normalized.push(tag);
482
+ }
483
+ }
511
484
  }
512
485
  return normalized;
513
486
  }
@@ -934,16 +907,10 @@ var MindCache = class {
934
907
  const attrs = entry.attributes || {};
935
908
  const normalizedAttrs = {
936
909
  type: attrs.type || "text",
910
+ contentType: attrs.contentType,
937
911
  contentTags: attrs.contentTags || [],
938
- systemTags: attrs.systemTags || this.normalizeSystemTags(attrs.visible !== false ? ["prompt"] : []),
939
- zIndex: attrs.zIndex ?? 0,
940
- // Legacy fields
941
- readonly: attrs.readonly ?? false,
942
- visible: attrs.visible ?? true,
943
- hardcoded: attrs.hardcoded ?? false,
944
- template: attrs.template ?? false,
945
- tags: attrs.tags || [],
946
- contentType: attrs.contentType
912
+ systemTags: this.normalizeSystemTags(attrs.systemTags || []),
913
+ zIndex: attrs.zIndex ?? 0
947
914
  };
948
915
  entryMap.set("attributes", normalizedAttrs);
949
916
  }
@@ -1048,7 +1015,7 @@ var MindCache = class {
1048
1015
  if (_processingStack && _processingStack.has(key)) {
1049
1016
  return `{{${key}}}`;
1050
1017
  }
1051
- if (attributes?.systemTags?.includes("ApplyTemplate") || attributes?.systemTags?.includes("template") || attributes?.template) {
1018
+ if (attributes?.systemTags?.includes("ApplyTemplate")) {
1052
1019
  if (typeof value === "string") {
1053
1020
  const stack = _processingStack || /* @__PURE__ */ new Set();
1054
1021
  stack.add(key);
@@ -1062,13 +1029,8 @@ var MindCache = class {
1062
1029
  return {
1063
1030
  type: "text",
1064
1031
  contentTags: [],
1065
- systemTags: ["prompt", "readonly", "protected"],
1066
- zIndex: 999999,
1067
- readonly: true,
1068
- visible: true,
1069
- hardcoded: true,
1070
- template: false,
1071
- tags: []
1032
+ systemTags: ["SystemPrompt", "protected"],
1033
+ zIndex: 999999
1072
1034
  };
1073
1035
  }
1074
1036
  const entryMap = this.rootMap.get(key);
@@ -1135,22 +1097,13 @@ var MindCache = class {
1135
1097
  this.getUndoManager(key);
1136
1098
  this.doc.transact(() => {
1137
1099
  const oldAttributes = isNewEntry ? {
1138
- ...DEFAULT_KEY_ATTRIBUTES,
1139
- contentTags: [],
1140
- systemTags: ["SystemPrompt", "LLMWrite"],
1141
- tags: [],
1142
- zIndex: 0
1100
+ ...DEFAULT_KEY_ATTRIBUTES
1143
1101
  } : entryMap.get("attributes");
1144
1102
  const finalAttributes = attributes ? { ...oldAttributes, ...attributes } : oldAttributes;
1145
1103
  let normalizedAttributes = { ...finalAttributes };
1146
1104
  if (finalAttributes.systemTags) {
1147
1105
  normalizedAttributes.systemTags = this.normalizeSystemTags(finalAttributes.systemTags);
1148
1106
  }
1149
- if (finalAttributes.template) {
1150
- if (!normalizedAttributes.systemTags.includes("template")) {
1151
- normalizedAttributes.systemTags.push("template");
1152
- }
1153
- }
1154
1107
  let valueToSet = value;
1155
1108
  if (normalizedAttributes.type === "document" && !(valueToSet instanceof Y__namespace.Text)) {
1156
1109
  valueToSet = new Y__namespace.Text(typeof value === "string" ? value : String(value ?? ""));
@@ -1161,6 +1114,38 @@ var MindCache = class {
1161
1114
  entryMap.set("attributes", normalizedAttributes);
1162
1115
  });
1163
1116
  }
1117
+ /**
1118
+ * LLM-safe method to write a value to a key.
1119
+ * This method:
1120
+ * - Only updates the value, never modifies attributes/systemTags
1121
+ * - Checks LLMWrite permission before writing
1122
+ * - Returns false if key doesn't exist or lacks LLMWrite permission
1123
+ *
1124
+ * Used by create_vercel_ai_tools() to prevent LLMs from escalating privileges.
1125
+ */
1126
+ llm_set_key(key, value) {
1127
+ if (key === "$date" || key === "$time" || key === "$version") {
1128
+ return false;
1129
+ }
1130
+ const entryMap = this.rootMap.get(key);
1131
+ if (!entryMap) {
1132
+ return false;
1133
+ }
1134
+ const attributes = entryMap.get("attributes");
1135
+ if (!attributes?.systemTags?.includes("LLMWrite")) {
1136
+ return false;
1137
+ }
1138
+ if (attributes.type === "document") {
1139
+ if (typeof value === "string") {
1140
+ this._replaceDocumentText(key, value);
1141
+ }
1142
+ return true;
1143
+ }
1144
+ this.doc.transact(() => {
1145
+ entryMap.set("value", value);
1146
+ });
1147
+ return true;
1148
+ }
1164
1149
  delete_key(key) {
1165
1150
  if (key === "$date" || key === "$time") {
1166
1151
  return;
@@ -1605,15 +1590,13 @@ var MindCache = class {
1605
1590
  }
1606
1591
  const attributes = entryMap.get("attributes");
1607
1592
  const value = entryMap.get("value");
1608
- if (attributes?.hardcoded) {
1593
+ if (attributes?.systemTags?.includes("protected")) {
1609
1594
  return;
1610
1595
  }
1611
1596
  lines.push(`### ${key}`);
1612
1597
  const entryType = attributes?.type || "text";
1613
1598
  lines.push(`- **Type**: \`${entryType}\``);
1614
- lines.push(`- **Readonly**: \`${attributes?.readonly ?? false}\``);
1615
- lines.push(`- **Visible**: \`${attributes?.visible ?? true}\``);
1616
- lines.push(`- **Template**: \`${attributes?.template ?? false}\``);
1599
+ lines.push(`- **System Tags**: \`${attributes?.systemTags?.join(", ") || "none"}\``);
1617
1600
  lines.push(`- **Z-Index**: \`${attributes?.zIndex ?? 0}\``);
1618
1601
  if (attributes?.contentTags && attributes.contentTags.length > 0) {
1619
1602
  lines.push(`- **Tags**: \`${attributes.contentTags.join("`, `")}\``);
@@ -1699,16 +1682,11 @@ var MindCache = class {
1699
1682
  }
1700
1683
  continue;
1701
1684
  }
1702
- if (line.startsWith("- **Readonly**:")) {
1703
- currentAttributes.readonly = line.includes("`true`");
1704
- continue;
1705
- }
1706
- if (line.startsWith("- **Visible**:")) {
1707
- currentAttributes.visible = line.includes("`true`");
1708
- continue;
1709
- }
1710
- if (line.startsWith("- **Template**:")) {
1711
- currentAttributes.template = line.includes("`true`");
1685
+ if (line.startsWith("- **System Tags**:")) {
1686
+ const tagsStr = line.match(/`([^`]+)`/)?.[1] || "";
1687
+ if (tagsStr !== "none") {
1688
+ currentAttributes.systemTags = tagsStr.split(", ").filter((t) => t);
1689
+ }
1712
1690
  continue;
1713
1691
  }
1714
1692
  if (line.startsWith("- **Z-Index**:")) {
@@ -1719,7 +1697,6 @@ var MindCache = class {
1719
1697
  if (line.startsWith("- **Tags**:")) {
1720
1698
  const tags = line.match(/`([^`]+)`/g)?.map((t) => t.slice(1, -1)) || [];
1721
1699
  currentAttributes.contentTags = tags;
1722
- currentAttributes.tags = tags;
1723
1700
  continue;
1724
1701
  }
1725
1702
  if (line.startsWith("- **Content Type**:")) {
@@ -1975,8 +1952,12 @@ var MindCache = class {
1975
1952
  /**
1976
1953
  * Generate Vercel AI SDK compatible tools for writable keys.
1977
1954
  * For document type keys, generates additional tools: append_, insert_, edit_
1955
+ *
1956
+ * Security: All tools use llm_set_key internally which:
1957
+ * - Only modifies VALUES, never attributes/systemTags
1958
+ * - Prevents LLMs from escalating privileges
1978
1959
  */
1979
- get_aisdk_tools() {
1960
+ create_vercel_ai_tools() {
1980
1961
  const tools = {};
1981
1962
  for (const [key, val] of this.rootMap) {
1982
1963
  if (key.startsWith("$")) {
@@ -1984,7 +1965,7 @@ var MindCache = class {
1984
1965
  }
1985
1966
  const entryMap = val;
1986
1967
  const attributes = entryMap.get("attributes");
1987
- const isWritable = !attributes?.readonly && (attributes?.systemTags?.includes("LLMWrite") || !attributes?.systemTags);
1968
+ const isWritable = attributes?.systemTags?.includes("LLMWrite");
1988
1969
  if (!isWritable) {
1989
1970
  continue;
1990
1971
  }
@@ -2000,15 +1981,18 @@ var MindCache = class {
2000
1981
  required: ["value"]
2001
1982
  },
2002
1983
  execute: async ({ value }) => {
2003
- if (isDocument) {
2004
- this._replaceDocumentText(key, value);
2005
- } else {
2006
- this.set_value(key, value);
1984
+ const success = this.llm_set_key(key, value);
1985
+ if (success) {
1986
+ return {
1987
+ result: `Successfully wrote "${value}" to ${key}`,
1988
+ key,
1989
+ value
1990
+ };
2007
1991
  }
2008
1992
  return {
2009
- result: `Successfully wrote "${value}" to ${key}`,
1993
+ result: `Failed to write to ${key} - permission denied or key not found`,
2010
1994
  key,
2011
- value
1995
+ error: true
2012
1996
  };
2013
1997
  }
2014
1998
  };
@@ -2023,6 +2007,9 @@ var MindCache = class {
2023
2007
  required: ["text"]
2024
2008
  },
2025
2009
  execute: async ({ text }) => {
2010
+ if (!attributes?.systemTags?.includes("LLMWrite")) {
2011
+ return { result: `Permission denied for ${key}`, key, error: true };
2012
+ }
2026
2013
  const yText = this.get_document(key);
2027
2014
  if (yText) {
2028
2015
  yText.insert(yText.length, text);
@@ -2046,6 +2033,9 @@ var MindCache = class {
2046
2033
  required: ["index", "text"]
2047
2034
  },
2048
2035
  execute: async ({ index, text }) => {
2036
+ if (!attributes?.systemTags?.includes("LLMWrite")) {
2037
+ return { result: `Permission denied for ${key}`, key, error: true };
2038
+ }
2049
2039
  this.insert_text(key, index, text);
2050
2040
  return {
2051
2041
  result: `Successfully inserted text at position ${index} in ${key}`,
@@ -2066,6 +2056,9 @@ var MindCache = class {
2066
2056
  required: ["find", "replace"]
2067
2057
  },
2068
2058
  execute: async ({ find, replace }) => {
2059
+ if (!attributes?.systemTags?.includes("LLMWrite")) {
2060
+ return { result: `Permission denied for ${key}`, key, error: true };
2061
+ }
2069
2062
  const yText = this.get_document(key);
2070
2063
  if (yText) {
2071
2064
  const text = yText.toString();
@@ -2090,6 +2083,12 @@ var MindCache = class {
2090
2083
  }
2091
2084
  return tools;
2092
2085
  }
2086
+ /**
2087
+ * @deprecated Use create_vercel_ai_tools() instead
2088
+ */
2089
+ get_aisdk_tools() {
2090
+ return this.create_vercel_ai_tools();
2091
+ }
2093
2092
  /**
2094
2093
  * Generate a system prompt containing all visible STM keys and their values.
2095
2094
  * Indicates which tools can be used to modify writable keys.
@@ -2102,13 +2101,13 @@ var MindCache = class {
2102
2101
  }
2103
2102
  const entryMap = val;
2104
2103
  const attributes = entryMap.get("attributes");
2105
- const isVisible = attributes?.visible !== false && (attributes?.systemTags?.includes("prompt") || attributes?.systemTags?.includes("SystemPrompt") || !attributes?.systemTags);
2104
+ const isVisible = attributes?.systemTags?.includes("SystemPrompt") || attributes?.systemTags?.includes("LLMRead");
2106
2105
  if (!isVisible) {
2107
2106
  continue;
2108
2107
  }
2109
2108
  const value = this.get_value(key);
2110
2109
  const displayValue = typeof value === "object" ? JSON.stringify(value) : value;
2111
- const isWritable = !attributes?.readonly && (attributes?.systemTags?.includes("LLMWrite") || !attributes?.systemTags);
2110
+ const isWritable = attributes?.systemTags?.includes("LLMWrite");
2112
2111
  const isDocument = attributes?.type === "document";
2113
2112
  const sanitizedKey = this.sanitizeKeyForTool(key);
2114
2113
  if (isWritable) {
@@ -2149,7 +2148,7 @@ var MindCache = class {
2149
2148
  return null;
2150
2149
  }
2151
2150
  const attributes = entryMap.get("attributes");
2152
- const isWritable = !attributes?.readonly && (attributes?.systemTags?.includes("LLMWrite") || !attributes?.systemTags);
2151
+ const isWritable = attributes?.systemTags?.includes("LLMWrite");
2153
2152
  if (!isWritable) {
2154
2153
  return null;
2155
2154
  }