mindcache 3.2.0 → 3.3.1

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
@@ -429,7 +429,7 @@ var MindCache = class {
429
429
  listeners = {};
430
430
  globalListeners = [];
431
431
  // Metadata
432
- version = "3.1.0";
432
+ version = "3.3.1";
433
433
  // Internal flag to prevent sync loops when receiving remote updates
434
434
  // (Less critical with Yjs but kept for API compat)
435
435
  _isRemoteUpdate = false;
@@ -489,8 +489,22 @@ var MindCache = class {
489
489
  constructor(options) {
490
490
  this.doc = new Y__namespace.Doc();
491
491
  this.rootMap = this.doc.getMap("mindcache");
492
- this.rootMap.observe((event) => {
493
- event.keysChanged.forEach((key) => {
492
+ this.rootMap.observeDeep((events) => {
493
+ const keysAffected = /* @__PURE__ */ new Set();
494
+ events.forEach((event) => {
495
+ if (event.target === this.rootMap) {
496
+ const mapEvent = event;
497
+ mapEvent.keysChanged.forEach((key) => keysAffected.add(key));
498
+ } else if (event.target.parent === this.rootMap) {
499
+ for (const [key, val] of this.rootMap) {
500
+ if (val === event.target) {
501
+ keysAffected.add(key);
502
+ break;
503
+ }
504
+ }
505
+ }
506
+ });
507
+ keysAffected.forEach((key) => {
494
508
  const entryMap = this.rootMap.get(key);
495
509
  if (entryMap) {
496
510
  const value = entryMap.get("value");
@@ -503,8 +517,6 @@ var MindCache = class {
503
517
  }
504
518
  }
505
519
  });
506
- });
507
- this.rootMap.observeDeep((_events) => {
508
520
  this.notifyGlobalListeners();
509
521
  });
510
522
  this.initGlobalUndoManager();
@@ -829,18 +841,35 @@ var MindCache = class {
829
841
  }
830
842
  // Deserialize state (for IndexedDBAdapter compatibility)
831
843
  deserialize(data) {
844
+ if (!data || typeof data !== "object") {
845
+ return;
846
+ }
832
847
  this.doc.transact(() => {
848
+ for (const key of this.rootMap.keys()) {
849
+ this.rootMap.delete(key);
850
+ }
833
851
  for (const [key, entry] of Object.entries(data)) {
834
852
  if (key.startsWith("$")) {
835
853
  continue;
836
854
  }
837
- let entryMap = this.rootMap.get(key);
838
- if (!entryMap) {
839
- entryMap = new Y__namespace.Map();
840
- this.rootMap.set(key, entryMap);
841
- }
855
+ const entryMap = new Y__namespace.Map();
856
+ this.rootMap.set(key, entryMap);
842
857
  entryMap.set("value", entry.value);
843
- entryMap.set("attributes", entry.attributes);
858
+ const attrs = entry.attributes || {};
859
+ const normalizedAttrs = {
860
+ type: attrs.type || "text",
861
+ contentTags: attrs.contentTags || [],
862
+ systemTags: attrs.systemTags || this.normalizeSystemTags(attrs.visible !== false ? ["prompt"] : []),
863
+ zIndex: attrs.zIndex ?? 0,
864
+ // Legacy fields
865
+ readonly: attrs.readonly ?? false,
866
+ visible: attrs.visible ?? true,
867
+ hardcoded: attrs.hardcoded ?? false,
868
+ template: attrs.template ?? false,
869
+ tags: attrs.tags || [],
870
+ contentType: attrs.contentType
871
+ };
872
+ entryMap.set("attributes", normalizedAttrs);
844
873
  }
845
874
  });
846
875
  }
@@ -878,16 +907,46 @@ var MindCache = class {
878
907
  }
879
908
  return false;
880
909
  }
881
- // InjectSTM replacement
882
- injectSTM(template, _processingStack) {
910
+ // InjectSTM replacement (private helper)
911
+ _injectSTMInternal(template, _processingStack) {
883
912
  return template.replace(/\{\{([^}]+)\}\}/g, (_, key) => {
884
913
  const val = this.get_value(key.trim(), _processingStack);
885
914
  return val !== void 0 ? String(val) : `{{${key}}}`;
886
915
  });
887
916
  }
917
+ /**
918
+ * Replace {{key}} placeholders in a template string with values from MindCache.
919
+ * @param template The template string with {{key}} placeholders
920
+ * @returns The template with placeholders replaced by values
921
+ */
922
+ injectSTM(template) {
923
+ return this._injectSTMInternal(template, /* @__PURE__ */ new Set());
924
+ }
888
925
  // Public API Methods
889
926
  getAll() {
890
- return this.serialize();
927
+ const result = {};
928
+ for (const [key] of this.rootMap) {
929
+ result[key] = this.get_value(key);
930
+ }
931
+ result["$date"] = this.get_value("$date");
932
+ result["$time"] = this.get_value("$time");
933
+ return result;
934
+ }
935
+ /**
936
+ * Get all entries with their full structure (value + attributes).
937
+ * Use this for UI/admin interfaces that need to display key properties.
938
+ * Unlike serialize(), this format is stable and won't change.
939
+ */
940
+ getAllEntries() {
941
+ const result = {};
942
+ for (const [key] of this.rootMap) {
943
+ const value = this.get_value(key);
944
+ const attributes = this.get_attributes(key);
945
+ if (attributes) {
946
+ result[key] = { value, attributes };
947
+ }
948
+ }
949
+ return result;
891
950
  }
892
951
  get_value(key, _processingStack) {
893
952
  if (key === "$date") {
@@ -917,7 +976,7 @@ var MindCache = class {
917
976
  if (typeof value === "string") {
918
977
  const stack = _processingStack || /* @__PURE__ */ new Set();
919
978
  stack.add(key);
920
- return this.injectSTM(value, stack);
979
+ return this._injectSTMInternal(value, stack);
921
980
  }
922
981
  }
923
982
  return value;
@@ -1015,6 +1074,638 @@ var MindCache = class {
1015
1074
  keys.forEach((k) => this.rootMap.delete(k));
1016
1075
  });
1017
1076
  }
1077
+ // ============================================
1078
+ // Restored Methods (from v2.x)
1079
+ // ============================================
1080
+ /**
1081
+ * Check if a key exists in MindCache.
1082
+ */
1083
+ has(key) {
1084
+ if (key === "$date" || key === "$time" || key === "$version") {
1085
+ return true;
1086
+ }
1087
+ return this.rootMap.has(key);
1088
+ }
1089
+ /**
1090
+ * Delete a key from MindCache.
1091
+ * @returns true if the key existed and was deleted
1092
+ */
1093
+ delete(key) {
1094
+ if (key === "$date" || key === "$time" || key === "$version") {
1095
+ return false;
1096
+ }
1097
+ if (!this.rootMap.has(key)) {
1098
+ return false;
1099
+ }
1100
+ this.rootMap.delete(key);
1101
+ this.notifyGlobalListeners();
1102
+ if (this.listeners[key]) {
1103
+ this.listeners[key].forEach((listener) => listener(void 0));
1104
+ }
1105
+ return true;
1106
+ }
1107
+ /** @deprecated Use get_value instead */
1108
+ get(key) {
1109
+ return this.get_value(key);
1110
+ }
1111
+ /** @deprecated Use set_value instead */
1112
+ set(key, value) {
1113
+ this.set_value(key, value);
1114
+ }
1115
+ /**
1116
+ * Update multiple values at once from an object.
1117
+ * @deprecated Use set_value for individual keys
1118
+ */
1119
+ update(data) {
1120
+ this.doc.transact(() => {
1121
+ for (const [key, value] of Object.entries(data)) {
1122
+ if (key !== "$date" && key !== "$time" && key !== "$version") {
1123
+ this.set_value(key, value);
1124
+ }
1125
+ }
1126
+ });
1127
+ this.notifyGlobalListeners();
1128
+ }
1129
+ /**
1130
+ * Get the number of keys in MindCache.
1131
+ */
1132
+ size() {
1133
+ return this.rootMap.size + 2;
1134
+ }
1135
+ /**
1136
+ * Get all keys in MindCache (including temporal keys).
1137
+ */
1138
+ keys() {
1139
+ const keys = Array.from(this.rootMap.keys());
1140
+ keys.push("$date", "$time");
1141
+ return keys;
1142
+ }
1143
+ /**
1144
+ * Get all values in MindCache (including temporal values).
1145
+ */
1146
+ values() {
1147
+ const result = [];
1148
+ for (const [key] of this.rootMap) {
1149
+ result.push(this.get_value(key));
1150
+ }
1151
+ result.push(this.get_value("$date"));
1152
+ result.push(this.get_value("$time"));
1153
+ return result;
1154
+ }
1155
+ /**
1156
+ * Get all key-value entries (including temporal entries).
1157
+ */
1158
+ entries() {
1159
+ const result = [];
1160
+ for (const [key] of this.rootMap) {
1161
+ result.push([key, this.get_value(key)]);
1162
+ }
1163
+ result.push(["$date", this.get_value("$date")]);
1164
+ result.push(["$time", this.get_value("$time")]);
1165
+ return result;
1166
+ }
1167
+ /**
1168
+ * Unsubscribe from key changes.
1169
+ * @deprecated Use the cleanup function returned by subscribe() instead
1170
+ */
1171
+ unsubscribe(key, listener) {
1172
+ if (this.listeners[key]) {
1173
+ this.listeners[key] = this.listeners[key].filter((l) => l !== listener);
1174
+ }
1175
+ }
1176
+ /**
1177
+ * Get the STM as a formatted string for LLM context.
1178
+ * @deprecated Use get_system_prompt() instead
1179
+ */
1180
+ getSTM() {
1181
+ return this.get_system_prompt();
1182
+ }
1183
+ /**
1184
+ * Get the STM as an object with values directly (no attributes).
1185
+ * Includes system keys ($date, $time).
1186
+ * @deprecated Use getAll() for full STM format
1187
+ */
1188
+ getSTMObject() {
1189
+ const result = {};
1190
+ for (const [key] of this.rootMap) {
1191
+ result[key] = this.get_value(key);
1192
+ }
1193
+ result["$date"] = this.get_value("$date");
1194
+ result["$time"] = this.get_value("$time");
1195
+ return result;
1196
+ }
1197
+ /**
1198
+ * Add a content tag to a key.
1199
+ * @returns true if the tag was added, false if key doesn't exist or tag already exists
1200
+ */
1201
+ addTag(key, tag) {
1202
+ if (key === "$date" || key === "$time" || key === "$version") {
1203
+ return false;
1204
+ }
1205
+ const entryMap = this.rootMap.get(key);
1206
+ if (!entryMap) {
1207
+ return false;
1208
+ }
1209
+ const attributes = entryMap.get("attributes");
1210
+ const contentTags = attributes?.contentTags || [];
1211
+ if (contentTags.includes(tag)) {
1212
+ return false;
1213
+ }
1214
+ this.doc.transact(() => {
1215
+ const newContentTags = [...contentTags, tag];
1216
+ entryMap.set("attributes", {
1217
+ ...attributes,
1218
+ contentTags: newContentTags,
1219
+ tags: newContentTags
1220
+ // Sync legacy tags array
1221
+ });
1222
+ });
1223
+ this.notifyGlobalListeners();
1224
+ return true;
1225
+ }
1226
+ /**
1227
+ * Remove a content tag from a key.
1228
+ * @returns true if the tag was removed
1229
+ */
1230
+ removeTag(key, tag) {
1231
+ if (key === "$date" || key === "$time" || key === "$version") {
1232
+ return false;
1233
+ }
1234
+ const entryMap = this.rootMap.get(key);
1235
+ if (!entryMap) {
1236
+ return false;
1237
+ }
1238
+ const attributes = entryMap.get("attributes");
1239
+ const contentTags = attributes?.contentTags || [];
1240
+ const tagIndex = contentTags.indexOf(tag);
1241
+ if (tagIndex === -1) {
1242
+ return false;
1243
+ }
1244
+ this.doc.transact(() => {
1245
+ const newContentTags = contentTags.filter((t) => t !== tag);
1246
+ entryMap.set("attributes", {
1247
+ ...attributes,
1248
+ contentTags: newContentTags,
1249
+ tags: newContentTags
1250
+ // Sync legacy tags array
1251
+ });
1252
+ });
1253
+ this.notifyGlobalListeners();
1254
+ return true;
1255
+ }
1256
+ /**
1257
+ * Get all content tags for a key.
1258
+ */
1259
+ getTags(key) {
1260
+ if (key === "$date" || key === "$time" || key === "$version") {
1261
+ return [];
1262
+ }
1263
+ const entryMap = this.rootMap.get(key);
1264
+ if (!entryMap) {
1265
+ return [];
1266
+ }
1267
+ const attributes = entryMap.get("attributes");
1268
+ return attributes?.contentTags || [];
1269
+ }
1270
+ /**
1271
+ * Get all unique content tags across all keys.
1272
+ */
1273
+ getAllTags() {
1274
+ const allTags = /* @__PURE__ */ new Set();
1275
+ for (const [, val] of this.rootMap) {
1276
+ const entryMap = val;
1277
+ const attributes = entryMap.get("attributes");
1278
+ if (attributes?.contentTags) {
1279
+ attributes.contentTags.forEach((tag) => allTags.add(tag));
1280
+ }
1281
+ }
1282
+ return Array.from(allTags);
1283
+ }
1284
+ /**
1285
+ * Check if a key has a specific content tag.
1286
+ */
1287
+ hasTag(key, tag) {
1288
+ if (key === "$date" || key === "$time" || key === "$version") {
1289
+ return false;
1290
+ }
1291
+ const entryMap = this.rootMap.get(key);
1292
+ if (!entryMap) {
1293
+ return false;
1294
+ }
1295
+ const attributes = entryMap.get("attributes");
1296
+ return attributes?.contentTags?.includes(tag) || false;
1297
+ }
1298
+ /**
1299
+ * Get all keys with a specific content tag as formatted string.
1300
+ */
1301
+ getTagged(tag) {
1302
+ const entries = [];
1303
+ const keys = this.getSortedKeys();
1304
+ keys.forEach((key) => {
1305
+ if (this.hasTag(key, tag)) {
1306
+ entries.push([key, this.get_value(key)]);
1307
+ }
1308
+ });
1309
+ return entries.map(([key, value]) => `${key}: ${value}`).join(", ");
1310
+ }
1311
+ /**
1312
+ * Get array of keys with a specific content tag.
1313
+ */
1314
+ getKeysByTag(tag) {
1315
+ const keys = this.getSortedKeys();
1316
+ return keys.filter((key) => this.hasTag(key, tag));
1317
+ }
1318
+ // ============================================
1319
+ // System Tag Methods (requires system access level)
1320
+ // ============================================
1321
+ /**
1322
+ * Add a system tag to a key (requires system access).
1323
+ * System tags: 'SystemPrompt', 'LLMRead', 'LLMWrite', 'readonly', 'protected', 'ApplyTemplate'
1324
+ */
1325
+ systemAddTag(key, tag) {
1326
+ if (!this.hasSystemAccess) {
1327
+ console.warn("MindCache: systemAddTag requires system access level");
1328
+ return false;
1329
+ }
1330
+ if (key === "$date" || key === "$time" || key === "$version") {
1331
+ return false;
1332
+ }
1333
+ const entryMap = this.rootMap.get(key);
1334
+ if (!entryMap) {
1335
+ return false;
1336
+ }
1337
+ const attributes = entryMap.get("attributes");
1338
+ const systemTags = attributes?.systemTags || [];
1339
+ if (systemTags.includes(tag)) {
1340
+ return false;
1341
+ }
1342
+ this.doc.transact(() => {
1343
+ const newSystemTags = [...systemTags, tag];
1344
+ const normalizedTags = this.normalizeSystemTags(newSystemTags);
1345
+ entryMap.set("attributes", {
1346
+ ...attributes,
1347
+ systemTags: normalizedTags
1348
+ });
1349
+ });
1350
+ this.notifyGlobalListeners();
1351
+ return true;
1352
+ }
1353
+ /**
1354
+ * Remove a system tag from a key (requires system access).
1355
+ */
1356
+ systemRemoveTag(key, tag) {
1357
+ if (!this.hasSystemAccess) {
1358
+ console.warn("MindCache: systemRemoveTag requires system access level");
1359
+ return false;
1360
+ }
1361
+ if (key === "$date" || key === "$time" || key === "$version") {
1362
+ return false;
1363
+ }
1364
+ const entryMap = this.rootMap.get(key);
1365
+ if (!entryMap) {
1366
+ return false;
1367
+ }
1368
+ const attributes = entryMap.get("attributes");
1369
+ const systemTags = attributes?.systemTags || [];
1370
+ const tagIndex = systemTags.indexOf(tag);
1371
+ if (tagIndex === -1) {
1372
+ return false;
1373
+ }
1374
+ this.doc.transact(() => {
1375
+ const newSystemTags = systemTags.filter((t) => t !== tag);
1376
+ entryMap.set("attributes", {
1377
+ ...attributes,
1378
+ systemTags: newSystemTags
1379
+ });
1380
+ });
1381
+ this.notifyGlobalListeners();
1382
+ return true;
1383
+ }
1384
+ /**
1385
+ * Get all system tags for a key (requires system access).
1386
+ */
1387
+ systemGetTags(key) {
1388
+ if (!this.hasSystemAccess) {
1389
+ console.warn("MindCache: systemGetTags requires system access level");
1390
+ return [];
1391
+ }
1392
+ if (key === "$date" || key === "$time" || key === "$version") {
1393
+ return [];
1394
+ }
1395
+ const entryMap = this.rootMap.get(key);
1396
+ if (!entryMap) {
1397
+ return [];
1398
+ }
1399
+ const attributes = entryMap.get("attributes");
1400
+ return attributes?.systemTags || [];
1401
+ }
1402
+ /**
1403
+ * Check if a key has a specific system tag (requires system access).
1404
+ */
1405
+ systemHasTag(key, tag) {
1406
+ if (!this.hasSystemAccess) {
1407
+ console.warn("MindCache: systemHasTag requires system access level");
1408
+ return false;
1409
+ }
1410
+ if (key === "$date" || key === "$time" || key === "$version") {
1411
+ return false;
1412
+ }
1413
+ const entryMap = this.rootMap.get(key);
1414
+ if (!entryMap) {
1415
+ return false;
1416
+ }
1417
+ const attributes = entryMap.get("attributes");
1418
+ return attributes?.systemTags?.includes(tag) || false;
1419
+ }
1420
+ /**
1421
+ * Set all system tags for a key at once (requires system access).
1422
+ */
1423
+ systemSetTags(key, tags) {
1424
+ if (!this.hasSystemAccess) {
1425
+ console.warn("MindCache: systemSetTags requires system access level");
1426
+ return false;
1427
+ }
1428
+ if (key === "$date" || key === "$time" || key === "$version") {
1429
+ return false;
1430
+ }
1431
+ const entryMap = this.rootMap.get(key);
1432
+ if (!entryMap) {
1433
+ return false;
1434
+ }
1435
+ this.doc.transact(() => {
1436
+ const attributes = entryMap.get("attributes");
1437
+ entryMap.set("attributes", {
1438
+ ...attributes,
1439
+ systemTags: [...tags]
1440
+ });
1441
+ });
1442
+ this.notifyGlobalListeners();
1443
+ return true;
1444
+ }
1445
+ /**
1446
+ * Get all keys with a specific system tag (requires system access).
1447
+ */
1448
+ systemGetKeysByTag(tag) {
1449
+ if (!this.hasSystemAccess) {
1450
+ console.warn("MindCache: systemGetKeysByTag requires system access level");
1451
+ return [];
1452
+ }
1453
+ const keys = this.getSortedKeys();
1454
+ return keys.filter((key) => this.systemHasTag(key, tag));
1455
+ }
1456
+ /**
1457
+ * Helper to get sorted keys (by zIndex).
1458
+ */
1459
+ getSortedKeys() {
1460
+ const entries = [];
1461
+ for (const [key, val] of this.rootMap) {
1462
+ const entryMap = val;
1463
+ const attributes = entryMap.get("attributes");
1464
+ entries.push({ key, zIndex: attributes?.zIndex ?? 0 });
1465
+ }
1466
+ return entries.sort((a, b) => a.zIndex - b.zIndex).map((e) => e.key);
1467
+ }
1468
+ /**
1469
+ * Serialize to JSON string.
1470
+ */
1471
+ toJSON() {
1472
+ return JSON.stringify(this.serialize());
1473
+ }
1474
+ /**
1475
+ * Deserialize from JSON string.
1476
+ */
1477
+ fromJSON(jsonString) {
1478
+ try {
1479
+ const data = JSON.parse(jsonString);
1480
+ this.deserialize(data);
1481
+ } catch (error) {
1482
+ console.error("MindCache: Failed to deserialize JSON:", error);
1483
+ }
1484
+ }
1485
+ /**
1486
+ * Export to Markdown format.
1487
+ */
1488
+ toMarkdown() {
1489
+ const now = /* @__PURE__ */ new Date();
1490
+ const lines = [];
1491
+ const appendixEntries = [];
1492
+ let appendixCounter = 0;
1493
+ lines.push("# MindCache STM Export");
1494
+ lines.push("");
1495
+ lines.push(`Export Date: ${now.toISOString().split("T")[0]}`);
1496
+ lines.push("");
1497
+ lines.push("---");
1498
+ lines.push("");
1499
+ lines.push("## STM Entries");
1500
+ lines.push("");
1501
+ const sortedKeys = this.getSortedKeys();
1502
+ sortedKeys.forEach((key) => {
1503
+ const entryMap = this.rootMap.get(key);
1504
+ if (!entryMap) {
1505
+ return;
1506
+ }
1507
+ const attributes = entryMap.get("attributes");
1508
+ const value = entryMap.get("value");
1509
+ if (attributes?.hardcoded) {
1510
+ return;
1511
+ }
1512
+ lines.push(`### ${key}`);
1513
+ const entryType = attributes?.type || "text";
1514
+ lines.push(`- **Type**: \`${entryType}\``);
1515
+ lines.push(`- **Readonly**: \`${attributes?.readonly ?? false}\``);
1516
+ lines.push(`- **Visible**: \`${attributes?.visible ?? true}\``);
1517
+ lines.push(`- **Template**: \`${attributes?.template ?? false}\``);
1518
+ lines.push(`- **Z-Index**: \`${attributes?.zIndex ?? 0}\``);
1519
+ if (attributes?.contentTags && attributes.contentTags.length > 0) {
1520
+ lines.push(`- **Tags**: \`${attributes.contentTags.join("`, `")}\``);
1521
+ }
1522
+ if (attributes?.contentType) {
1523
+ lines.push(`- **Content Type**: \`${attributes.contentType}\``);
1524
+ }
1525
+ if (entryType === "image" || entryType === "file") {
1526
+ const label = String.fromCharCode(65 + appendixCounter);
1527
+ appendixCounter++;
1528
+ lines.push(`- **Value**: [See Appendix ${label}]`);
1529
+ appendixEntries.push({
1530
+ key,
1531
+ type: entryType,
1532
+ contentType: attributes?.contentType || "application/octet-stream",
1533
+ base64: value,
1534
+ label
1535
+ });
1536
+ } else if (entryType === "json") {
1537
+ lines.push("- **Value**:");
1538
+ lines.push("```json");
1539
+ try {
1540
+ const jsonValue = typeof value === "string" ? value : JSON.stringify(value, null, 2);
1541
+ lines.push(jsonValue);
1542
+ } catch {
1543
+ lines.push(String(value));
1544
+ }
1545
+ lines.push("```");
1546
+ } else {
1547
+ lines.push(`- **Value**: ${value}`);
1548
+ }
1549
+ lines.push("");
1550
+ });
1551
+ if (appendixEntries.length > 0) {
1552
+ lines.push("---");
1553
+ lines.push("");
1554
+ lines.push("## Appendix: Binary Data");
1555
+ lines.push("");
1556
+ appendixEntries.forEach((entry) => {
1557
+ lines.push(`### Appendix ${entry.label}: ${entry.key}`);
1558
+ lines.push(`- **Type**: \`${entry.type}\``);
1559
+ lines.push(`- **Content Type**: \`${entry.contentType}\``);
1560
+ lines.push("- **Base64 Data**:");
1561
+ lines.push("```");
1562
+ lines.push(entry.base64);
1563
+ lines.push("```");
1564
+ lines.push("");
1565
+ });
1566
+ }
1567
+ return lines.join("\n");
1568
+ }
1569
+ /**
1570
+ * Import from Markdown format.
1571
+ */
1572
+ fromMarkdown(markdown) {
1573
+ const lines = markdown.split("\n");
1574
+ let currentKey = null;
1575
+ let currentAttributes = {};
1576
+ let currentValue = null;
1577
+ let inCodeBlock = false;
1578
+ let codeBlockContent = [];
1579
+ for (const line of lines) {
1580
+ if (line.startsWith("### ") && !line.startsWith("### Appendix")) {
1581
+ if (currentKey && currentValue !== null) {
1582
+ this.set_value(currentKey, currentValue, currentAttributes);
1583
+ }
1584
+ currentKey = line.substring(4).trim();
1585
+ currentAttributes = {};
1586
+ currentValue = null;
1587
+ continue;
1588
+ }
1589
+ if (line.startsWith("### Appendix ")) {
1590
+ const match = line.match(/### Appendix ([A-Z]): (.+)/);
1591
+ if (match) {
1592
+ currentKey = match[2];
1593
+ }
1594
+ continue;
1595
+ }
1596
+ if (line.startsWith("- **Type**:")) {
1597
+ const type = line.match(/`(.+)`/)?.[1];
1598
+ if (type) {
1599
+ currentAttributes.type = type;
1600
+ }
1601
+ continue;
1602
+ }
1603
+ if (line.startsWith("- **Readonly**:")) {
1604
+ currentAttributes.readonly = line.includes("`true`");
1605
+ continue;
1606
+ }
1607
+ if (line.startsWith("- **Visible**:")) {
1608
+ currentAttributes.visible = line.includes("`true`");
1609
+ continue;
1610
+ }
1611
+ if (line.startsWith("- **Template**:")) {
1612
+ currentAttributes.template = line.includes("`true`");
1613
+ continue;
1614
+ }
1615
+ if (line.startsWith("- **Z-Index**:")) {
1616
+ const zIndex = parseInt(line.match(/`(\d+)`/)?.[1] || "0", 10);
1617
+ currentAttributes.zIndex = zIndex;
1618
+ continue;
1619
+ }
1620
+ if (line.startsWith("- **Tags**:")) {
1621
+ const tags = line.match(/`([^`]+)`/g)?.map((t) => t.slice(1, -1)) || [];
1622
+ currentAttributes.contentTags = tags;
1623
+ currentAttributes.tags = tags;
1624
+ continue;
1625
+ }
1626
+ if (line.startsWith("- **Content Type**:")) {
1627
+ currentAttributes.contentType = line.match(/`(.+)`/)?.[1];
1628
+ continue;
1629
+ }
1630
+ if (line.startsWith("- **Value**:") && !line.includes("[See Appendix")) {
1631
+ currentValue = line.substring(12).trim();
1632
+ continue;
1633
+ }
1634
+ if (line === "```json" || line === "```") {
1635
+ if (inCodeBlock) {
1636
+ inCodeBlock = false;
1637
+ if (currentKey && codeBlockContent.length > 0) {
1638
+ currentValue = codeBlockContent.join("\n");
1639
+ }
1640
+ codeBlockContent = [];
1641
+ } else {
1642
+ inCodeBlock = true;
1643
+ }
1644
+ continue;
1645
+ }
1646
+ if (inCodeBlock) {
1647
+ codeBlockContent.push(line);
1648
+ }
1649
+ }
1650
+ if (currentKey && currentValue !== null) {
1651
+ this.set_value(currentKey, currentValue, currentAttributes);
1652
+ }
1653
+ }
1654
+ /**
1655
+ * Set base64 binary data.
1656
+ */
1657
+ set_base64(key, base64Data, contentType, type = "file", attributes) {
1658
+ if (!this.validateContentType(type, contentType)) {
1659
+ throw new Error(`Invalid content type ${contentType} for type ${type}`);
1660
+ }
1661
+ const fileAttributes = {
1662
+ type,
1663
+ contentType,
1664
+ ...attributes
1665
+ };
1666
+ this.set_value(key, base64Data, fileAttributes);
1667
+ }
1668
+ /**
1669
+ * Add an image from base64 data.
1670
+ */
1671
+ add_image(key, base64Data, contentType = "image/jpeg", attributes) {
1672
+ if (!contentType.startsWith("image/")) {
1673
+ throw new Error(`Invalid image content type: ${contentType}. Must start with 'image/'`);
1674
+ }
1675
+ this.set_base64(key, base64Data, contentType, "image", attributes);
1676
+ }
1677
+ /**
1678
+ * Get the data URL for an image or file key.
1679
+ */
1680
+ get_data_url(key) {
1681
+ const entryMap = this.rootMap.get(key);
1682
+ if (!entryMap) {
1683
+ return void 0;
1684
+ }
1685
+ const attributes = entryMap.get("attributes");
1686
+ if (attributes?.type !== "image" && attributes?.type !== "file") {
1687
+ return void 0;
1688
+ }
1689
+ if (!attributes?.contentType) {
1690
+ return void 0;
1691
+ }
1692
+ const value = entryMap.get("value");
1693
+ return this.createDataUrl(value, attributes.contentType);
1694
+ }
1695
+ /**
1696
+ * Get the base64 data for an image or file key.
1697
+ */
1698
+ get_base64(key) {
1699
+ const entryMap = this.rootMap.get(key);
1700
+ if (!entryMap) {
1701
+ return void 0;
1702
+ }
1703
+ const attributes = entryMap.get("attributes");
1704
+ if (attributes?.type !== "image" && attributes?.type !== "file") {
1705
+ return void 0;
1706
+ }
1707
+ return entryMap.get("value");
1708
+ }
1018
1709
  // File methods
1019
1710
  async set_file(key, file, attributes) {
1020
1711
  const base64 = await this.encodeFileToBase64(file);
@@ -1335,10 +2026,14 @@ var MindCache = class {
1335
2026
  const sanitizedKey = this.sanitizeKeyForTool(key);
1336
2027
  if (isWritable) {
1337
2028
  if (isDocument) {
1338
- lines.push(`${key}: ${displayValue}. Document tools: write_${sanitizedKey}, append_${sanitizedKey}, edit_${sanitizedKey}`);
2029
+ lines.push(
2030
+ `${key}: ${displayValue}. Document tools: write_${sanitizedKey}, append_${sanitizedKey}, edit_${sanitizedKey}`
2031
+ );
1339
2032
  } else {
1340
2033
  const oldValueHint = displayValue ? ` This tool DOES NOT append \u2014 start your response with the old value (${displayValue})` : "";
1341
- lines.push(`${key}: ${displayValue}. You can rewrite "${key}" by using the write_${sanitizedKey} tool.${oldValueHint}`);
2034
+ lines.push(
2035
+ `${key}: ${displayValue}. You can rewrite "${key}" by using the write_${sanitizedKey} tool.${oldValueHint}`
2036
+ );
1342
2037
  }
1343
2038
  } else {
1344
2039
  lines.push(`${key}: ${displayValue}`);
@@ -1479,8 +2174,12 @@ function useMindCache(options) {
1479
2174
  };
1480
2175
  }
1481
2176
 
2177
+ // src/index.ts
2178
+ var mindcache = new MindCache();
2179
+
1482
2180
  exports.DEFAULT_KEY_ATTRIBUTES = DEFAULT_KEY_ATTRIBUTES;
1483
2181
  exports.MindCache = MindCache;
2182
+ exports.mindcache = mindcache;
1484
2183
  exports.useMindCache = useMindCache;
1485
2184
  //# sourceMappingURL=index.js.map
1486
2185
  //# sourceMappingURL=index.js.map