mindcache 3.1.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -326,6 +326,8 @@ var init_CloudAdapter = __esm({
326
326
  } else if (msg.type === "auth_error" || msg.type === "error") {
327
327
  this._state = "error";
328
328
  this.emit("error", new Error(msg.error));
329
+ } else {
330
+ console.debug("MindCache Cloud: Received message type:", msg.type, msg);
329
331
  }
330
332
  } else {
331
333
  const encoder = encoding.createEncoder();
@@ -434,8 +436,6 @@ var MindCache = class {
434
436
  normalized.push("readonly");
435
437
  } else if (hasLLMWrite) {
436
438
  normalized.push("LLMWrite");
437
- } else {
438
- normalized.push("LLMWrite");
439
439
  }
440
440
  return normalized;
441
441
  }
@@ -658,14 +658,16 @@ var MindCache = class {
658
658
  }
659
659
  const CloudAdapter2 = await this._getCloudAdapterClass();
660
660
  if (!this._cloudConfig.baseUrl) ;
661
- const baseUrl = (this._cloudConfig.baseUrl || "https://api.mindcache.io").replace("https://", "wss://").replace("http://", "ws://");
661
+ const baseUrl = (this._cloudConfig.baseUrl || "https://api.mindcache.dev").replace("https://", "wss://").replace("http://", "ws://");
662
662
  const adapter = new CloudAdapter2({
663
663
  instanceId: this._cloudConfig.instanceId,
664
664
  projectId: this._cloudConfig.projectId || "default",
665
665
  baseUrl,
666
666
  apiKey: this._cloudConfig.apiKey
667
667
  });
668
- if (this._cloudConfig.tokenEndpoint) {
668
+ if (this._cloudConfig.tokenProvider) {
669
+ adapter.setTokenProvider(this._cloudConfig.tokenProvider);
670
+ } else if (this._cloudConfig.tokenEndpoint) {
669
671
  const tokenEndpoint = this._cloudConfig.tokenEndpoint;
670
672
  const instanceId = this._cloudConfig.instanceId;
671
673
  let resolvedBaseUrl;
@@ -799,18 +801,35 @@ var MindCache = class {
799
801
  }
800
802
  // Deserialize state (for IndexedDBAdapter compatibility)
801
803
  deserialize(data) {
804
+ if (!data || typeof data !== "object") {
805
+ return;
806
+ }
802
807
  this.doc.transact(() => {
808
+ for (const key of this.rootMap.keys()) {
809
+ this.rootMap.delete(key);
810
+ }
803
811
  for (const [key, entry] of Object.entries(data)) {
804
812
  if (key.startsWith("$")) {
805
813
  continue;
806
814
  }
807
- let entryMap = this.rootMap.get(key);
808
- if (!entryMap) {
809
- entryMap = new Y.Map();
810
- this.rootMap.set(key, entryMap);
811
- }
815
+ const entryMap = new Y.Map();
816
+ this.rootMap.set(key, entryMap);
812
817
  entryMap.set("value", entry.value);
813
- entryMap.set("attributes", entry.attributes);
818
+ const attrs = entry.attributes || {};
819
+ const normalizedAttrs = {
820
+ type: attrs.type || "text",
821
+ contentTags: attrs.contentTags || [],
822
+ systemTags: attrs.systemTags || this.normalizeSystemTags(attrs.visible !== false ? ["prompt"] : []),
823
+ zIndex: attrs.zIndex ?? 0,
824
+ // Legacy fields
825
+ readonly: attrs.readonly ?? false,
826
+ visible: attrs.visible ?? true,
827
+ hardcoded: attrs.hardcoded ?? false,
828
+ template: attrs.template ?? false,
829
+ tags: attrs.tags || [],
830
+ contentType: attrs.contentType
831
+ };
832
+ entryMap.set("attributes", normalizedAttrs);
814
833
  }
815
834
  });
816
835
  }
@@ -848,16 +867,46 @@ var MindCache = class {
848
867
  }
849
868
  return false;
850
869
  }
851
- // InjectSTM replacement
852
- injectSTM(template, _processingStack) {
870
+ // InjectSTM replacement (private helper)
871
+ _injectSTMInternal(template, _processingStack) {
853
872
  return template.replace(/\{\{([^}]+)\}\}/g, (_, key) => {
854
873
  const val = this.get_value(key.trim(), _processingStack);
855
874
  return val !== void 0 ? String(val) : `{{${key}}}`;
856
875
  });
857
876
  }
877
+ /**
878
+ * Replace {{key}} placeholders in a template string with values from MindCache.
879
+ * @param template The template string with {{key}} placeholders
880
+ * @returns The template with placeholders replaced by values
881
+ */
882
+ injectSTM(template) {
883
+ return this._injectSTMInternal(template, /* @__PURE__ */ new Set());
884
+ }
858
885
  // Public API Methods
859
886
  getAll() {
860
- return this.serialize();
887
+ const result = {};
888
+ for (const [key] of this.rootMap) {
889
+ result[key] = this.get_value(key);
890
+ }
891
+ result["$date"] = this.get_value("$date");
892
+ result["$time"] = this.get_value("$time");
893
+ return result;
894
+ }
895
+ /**
896
+ * Get all entries with their full structure (value + attributes).
897
+ * Use this for UI/admin interfaces that need to display key properties.
898
+ * Unlike serialize(), this format is stable and won't change.
899
+ */
900
+ getAllEntries() {
901
+ const result = {};
902
+ for (const [key] of this.rootMap) {
903
+ const value = this.get_value(key);
904
+ const attributes = this.get_attributes(key);
905
+ if (attributes) {
906
+ result[key] = { value, attributes };
907
+ }
908
+ }
909
+ return result;
861
910
  }
862
911
  get_value(key, _processingStack) {
863
912
  if (key === "$date") {
@@ -887,7 +936,7 @@ var MindCache = class {
887
936
  if (typeof value === "string") {
888
937
  const stack = _processingStack || /* @__PURE__ */ new Set();
889
938
  stack.add(key);
890
- return this.injectSTM(value, stack);
939
+ return this._injectSTMInternal(value, stack);
891
940
  }
892
941
  }
893
942
  return value;
@@ -909,6 +958,27 @@ var MindCache = class {
909
958
  const entryMap = this.rootMap.get(key);
910
959
  return entryMap ? entryMap.get("attributes") : void 0;
911
960
  }
961
+ /**
962
+ * Update only the attributes of a key without modifying the value.
963
+ * Useful for updating tags, permissions etc. on document type keys.
964
+ */
965
+ set_attributes(key, attributes) {
966
+ if (key === "$date" || key === "$time" || key === "$version") {
967
+ return;
968
+ }
969
+ const entryMap = this.rootMap.get(key);
970
+ if (!entryMap) {
971
+ return;
972
+ }
973
+ this.doc.transact(() => {
974
+ const existingAttrs = entryMap.get("attributes");
975
+ const mergedAttrs = { ...existingAttrs, ...attributes };
976
+ if (mergedAttrs.systemTags) {
977
+ mergedAttrs.systemTags = this.normalizeSystemTags(mergedAttrs.systemTags);
978
+ }
979
+ entryMap.set("attributes", mergedAttrs);
980
+ });
981
+ }
912
982
  set_value(key, value, attributes) {
913
983
  if (key === "$date" || key === "$time" || key === "$version") {
914
984
  return;
@@ -964,6 +1034,638 @@ var MindCache = class {
964
1034
  keys.forEach((k) => this.rootMap.delete(k));
965
1035
  });
966
1036
  }
1037
+ // ============================================
1038
+ // Restored Methods (from v2.x)
1039
+ // ============================================
1040
+ /**
1041
+ * Check if a key exists in MindCache.
1042
+ */
1043
+ has(key) {
1044
+ if (key === "$date" || key === "$time" || key === "$version") {
1045
+ return true;
1046
+ }
1047
+ return this.rootMap.has(key);
1048
+ }
1049
+ /**
1050
+ * Delete a key from MindCache.
1051
+ * @returns true if the key existed and was deleted
1052
+ */
1053
+ delete(key) {
1054
+ if (key === "$date" || key === "$time" || key === "$version") {
1055
+ return false;
1056
+ }
1057
+ if (!this.rootMap.has(key)) {
1058
+ return false;
1059
+ }
1060
+ this.rootMap.delete(key);
1061
+ this.notifyGlobalListeners();
1062
+ if (this.listeners[key]) {
1063
+ this.listeners[key].forEach((listener) => listener(void 0));
1064
+ }
1065
+ return true;
1066
+ }
1067
+ /** @deprecated Use get_value instead */
1068
+ get(key) {
1069
+ return this.get_value(key);
1070
+ }
1071
+ /** @deprecated Use set_value instead */
1072
+ set(key, value) {
1073
+ this.set_value(key, value);
1074
+ }
1075
+ /**
1076
+ * Update multiple values at once from an object.
1077
+ * @deprecated Use set_value for individual keys
1078
+ */
1079
+ update(data) {
1080
+ this.doc.transact(() => {
1081
+ for (const [key, value] of Object.entries(data)) {
1082
+ if (key !== "$date" && key !== "$time" && key !== "$version") {
1083
+ this.set_value(key, value);
1084
+ }
1085
+ }
1086
+ });
1087
+ this.notifyGlobalListeners();
1088
+ }
1089
+ /**
1090
+ * Get the number of keys in MindCache.
1091
+ */
1092
+ size() {
1093
+ return this.rootMap.size + 2;
1094
+ }
1095
+ /**
1096
+ * Get all keys in MindCache (including temporal keys).
1097
+ */
1098
+ keys() {
1099
+ const keys = Array.from(this.rootMap.keys());
1100
+ keys.push("$date", "$time");
1101
+ return keys;
1102
+ }
1103
+ /**
1104
+ * Get all values in MindCache (including temporal values).
1105
+ */
1106
+ values() {
1107
+ const result = [];
1108
+ for (const [key] of this.rootMap) {
1109
+ result.push(this.get_value(key));
1110
+ }
1111
+ result.push(this.get_value("$date"));
1112
+ result.push(this.get_value("$time"));
1113
+ return result;
1114
+ }
1115
+ /**
1116
+ * Get all key-value entries (including temporal entries).
1117
+ */
1118
+ entries() {
1119
+ const result = [];
1120
+ for (const [key] of this.rootMap) {
1121
+ result.push([key, this.get_value(key)]);
1122
+ }
1123
+ result.push(["$date", this.get_value("$date")]);
1124
+ result.push(["$time", this.get_value("$time")]);
1125
+ return result;
1126
+ }
1127
+ /**
1128
+ * Unsubscribe from key changes.
1129
+ * @deprecated Use the cleanup function returned by subscribe() instead
1130
+ */
1131
+ unsubscribe(key, listener) {
1132
+ if (this.listeners[key]) {
1133
+ this.listeners[key] = this.listeners[key].filter((l) => l !== listener);
1134
+ }
1135
+ }
1136
+ /**
1137
+ * Get the STM as a formatted string for LLM context.
1138
+ * @deprecated Use get_system_prompt() instead
1139
+ */
1140
+ getSTM() {
1141
+ return this.get_system_prompt();
1142
+ }
1143
+ /**
1144
+ * Get the STM as an object with values directly (no attributes).
1145
+ * Includes system keys ($date, $time).
1146
+ * @deprecated Use getAll() for full STM format
1147
+ */
1148
+ getSTMObject() {
1149
+ const result = {};
1150
+ for (const [key] of this.rootMap) {
1151
+ result[key] = this.get_value(key);
1152
+ }
1153
+ result["$date"] = this.get_value("$date");
1154
+ result["$time"] = this.get_value("$time");
1155
+ return result;
1156
+ }
1157
+ /**
1158
+ * Add a content tag to a key.
1159
+ * @returns true if the tag was added, false if key doesn't exist or tag already exists
1160
+ */
1161
+ addTag(key, tag) {
1162
+ if (key === "$date" || key === "$time" || key === "$version") {
1163
+ return false;
1164
+ }
1165
+ const entryMap = this.rootMap.get(key);
1166
+ if (!entryMap) {
1167
+ return false;
1168
+ }
1169
+ const attributes = entryMap.get("attributes");
1170
+ const contentTags = attributes?.contentTags || [];
1171
+ if (contentTags.includes(tag)) {
1172
+ return false;
1173
+ }
1174
+ this.doc.transact(() => {
1175
+ const newContentTags = [...contentTags, tag];
1176
+ entryMap.set("attributes", {
1177
+ ...attributes,
1178
+ contentTags: newContentTags,
1179
+ tags: newContentTags
1180
+ // Sync legacy tags array
1181
+ });
1182
+ });
1183
+ this.notifyGlobalListeners();
1184
+ return true;
1185
+ }
1186
+ /**
1187
+ * Remove a content tag from a key.
1188
+ * @returns true if the tag was removed
1189
+ */
1190
+ removeTag(key, tag) {
1191
+ if (key === "$date" || key === "$time" || key === "$version") {
1192
+ return false;
1193
+ }
1194
+ const entryMap = this.rootMap.get(key);
1195
+ if (!entryMap) {
1196
+ return false;
1197
+ }
1198
+ const attributes = entryMap.get("attributes");
1199
+ const contentTags = attributes?.contentTags || [];
1200
+ const tagIndex = contentTags.indexOf(tag);
1201
+ if (tagIndex === -1) {
1202
+ return false;
1203
+ }
1204
+ this.doc.transact(() => {
1205
+ const newContentTags = contentTags.filter((t) => t !== tag);
1206
+ entryMap.set("attributes", {
1207
+ ...attributes,
1208
+ contentTags: newContentTags,
1209
+ tags: newContentTags
1210
+ // Sync legacy tags array
1211
+ });
1212
+ });
1213
+ this.notifyGlobalListeners();
1214
+ return true;
1215
+ }
1216
+ /**
1217
+ * Get all content tags for a key.
1218
+ */
1219
+ getTags(key) {
1220
+ if (key === "$date" || key === "$time" || key === "$version") {
1221
+ return [];
1222
+ }
1223
+ const entryMap = this.rootMap.get(key);
1224
+ if (!entryMap) {
1225
+ return [];
1226
+ }
1227
+ const attributes = entryMap.get("attributes");
1228
+ return attributes?.contentTags || [];
1229
+ }
1230
+ /**
1231
+ * Get all unique content tags across all keys.
1232
+ */
1233
+ getAllTags() {
1234
+ const allTags = /* @__PURE__ */ new Set();
1235
+ for (const [, val] of this.rootMap) {
1236
+ const entryMap = val;
1237
+ const attributes = entryMap.get("attributes");
1238
+ if (attributes?.contentTags) {
1239
+ attributes.contentTags.forEach((tag) => allTags.add(tag));
1240
+ }
1241
+ }
1242
+ return Array.from(allTags);
1243
+ }
1244
+ /**
1245
+ * Check if a key has a specific content tag.
1246
+ */
1247
+ hasTag(key, tag) {
1248
+ if (key === "$date" || key === "$time" || key === "$version") {
1249
+ return false;
1250
+ }
1251
+ const entryMap = this.rootMap.get(key);
1252
+ if (!entryMap) {
1253
+ return false;
1254
+ }
1255
+ const attributes = entryMap.get("attributes");
1256
+ return attributes?.contentTags?.includes(tag) || false;
1257
+ }
1258
+ /**
1259
+ * Get all keys with a specific content tag as formatted string.
1260
+ */
1261
+ getTagged(tag) {
1262
+ const entries = [];
1263
+ const keys = this.getSortedKeys();
1264
+ keys.forEach((key) => {
1265
+ if (this.hasTag(key, tag)) {
1266
+ entries.push([key, this.get_value(key)]);
1267
+ }
1268
+ });
1269
+ return entries.map(([key, value]) => `${key}: ${value}`).join(", ");
1270
+ }
1271
+ /**
1272
+ * Get array of keys with a specific content tag.
1273
+ */
1274
+ getKeysByTag(tag) {
1275
+ const keys = this.getSortedKeys();
1276
+ return keys.filter((key) => this.hasTag(key, tag));
1277
+ }
1278
+ // ============================================
1279
+ // System Tag Methods (requires system access level)
1280
+ // ============================================
1281
+ /**
1282
+ * Add a system tag to a key (requires system access).
1283
+ * System tags: 'SystemPrompt', 'LLMRead', 'LLMWrite', 'readonly', 'protected', 'ApplyTemplate'
1284
+ */
1285
+ systemAddTag(key, tag) {
1286
+ if (!this.hasSystemAccess) {
1287
+ console.warn("MindCache: systemAddTag requires system access level");
1288
+ return false;
1289
+ }
1290
+ if (key === "$date" || key === "$time" || key === "$version") {
1291
+ return false;
1292
+ }
1293
+ const entryMap = this.rootMap.get(key);
1294
+ if (!entryMap) {
1295
+ return false;
1296
+ }
1297
+ const attributes = entryMap.get("attributes");
1298
+ const systemTags = attributes?.systemTags || [];
1299
+ if (systemTags.includes(tag)) {
1300
+ return false;
1301
+ }
1302
+ this.doc.transact(() => {
1303
+ const newSystemTags = [...systemTags, tag];
1304
+ const normalizedTags = this.normalizeSystemTags(newSystemTags);
1305
+ entryMap.set("attributes", {
1306
+ ...attributes,
1307
+ systemTags: normalizedTags
1308
+ });
1309
+ });
1310
+ this.notifyGlobalListeners();
1311
+ return true;
1312
+ }
1313
+ /**
1314
+ * Remove a system tag from a key (requires system access).
1315
+ */
1316
+ systemRemoveTag(key, tag) {
1317
+ if (!this.hasSystemAccess) {
1318
+ console.warn("MindCache: systemRemoveTag requires system access level");
1319
+ return false;
1320
+ }
1321
+ if (key === "$date" || key === "$time" || key === "$version") {
1322
+ return false;
1323
+ }
1324
+ const entryMap = this.rootMap.get(key);
1325
+ if (!entryMap) {
1326
+ return false;
1327
+ }
1328
+ const attributes = entryMap.get("attributes");
1329
+ const systemTags = attributes?.systemTags || [];
1330
+ const tagIndex = systemTags.indexOf(tag);
1331
+ if (tagIndex === -1) {
1332
+ return false;
1333
+ }
1334
+ this.doc.transact(() => {
1335
+ const newSystemTags = systemTags.filter((t) => t !== tag);
1336
+ entryMap.set("attributes", {
1337
+ ...attributes,
1338
+ systemTags: newSystemTags
1339
+ });
1340
+ });
1341
+ this.notifyGlobalListeners();
1342
+ return true;
1343
+ }
1344
+ /**
1345
+ * Get all system tags for a key (requires system access).
1346
+ */
1347
+ systemGetTags(key) {
1348
+ if (!this.hasSystemAccess) {
1349
+ console.warn("MindCache: systemGetTags requires system access level");
1350
+ return [];
1351
+ }
1352
+ if (key === "$date" || key === "$time" || key === "$version") {
1353
+ return [];
1354
+ }
1355
+ const entryMap = this.rootMap.get(key);
1356
+ if (!entryMap) {
1357
+ return [];
1358
+ }
1359
+ const attributes = entryMap.get("attributes");
1360
+ return attributes?.systemTags || [];
1361
+ }
1362
+ /**
1363
+ * Check if a key has a specific system tag (requires system access).
1364
+ */
1365
+ systemHasTag(key, tag) {
1366
+ if (!this.hasSystemAccess) {
1367
+ console.warn("MindCache: systemHasTag requires system access level");
1368
+ return false;
1369
+ }
1370
+ if (key === "$date" || key === "$time" || key === "$version") {
1371
+ return false;
1372
+ }
1373
+ const entryMap = this.rootMap.get(key);
1374
+ if (!entryMap) {
1375
+ return false;
1376
+ }
1377
+ const attributes = entryMap.get("attributes");
1378
+ return attributes?.systemTags?.includes(tag) || false;
1379
+ }
1380
+ /**
1381
+ * Set all system tags for a key at once (requires system access).
1382
+ */
1383
+ systemSetTags(key, tags) {
1384
+ if (!this.hasSystemAccess) {
1385
+ console.warn("MindCache: systemSetTags requires system access level");
1386
+ return false;
1387
+ }
1388
+ if (key === "$date" || key === "$time" || key === "$version") {
1389
+ return false;
1390
+ }
1391
+ const entryMap = this.rootMap.get(key);
1392
+ if (!entryMap) {
1393
+ return false;
1394
+ }
1395
+ this.doc.transact(() => {
1396
+ const attributes = entryMap.get("attributes");
1397
+ entryMap.set("attributes", {
1398
+ ...attributes,
1399
+ systemTags: [...tags]
1400
+ });
1401
+ });
1402
+ this.notifyGlobalListeners();
1403
+ return true;
1404
+ }
1405
+ /**
1406
+ * Get all keys with a specific system tag (requires system access).
1407
+ */
1408
+ systemGetKeysByTag(tag) {
1409
+ if (!this.hasSystemAccess) {
1410
+ console.warn("MindCache: systemGetKeysByTag requires system access level");
1411
+ return [];
1412
+ }
1413
+ const keys = this.getSortedKeys();
1414
+ return keys.filter((key) => this.systemHasTag(key, tag));
1415
+ }
1416
+ /**
1417
+ * Helper to get sorted keys (by zIndex).
1418
+ */
1419
+ getSortedKeys() {
1420
+ const entries = [];
1421
+ for (const [key, val] of this.rootMap) {
1422
+ const entryMap = val;
1423
+ const attributes = entryMap.get("attributes");
1424
+ entries.push({ key, zIndex: attributes?.zIndex ?? 0 });
1425
+ }
1426
+ return entries.sort((a, b) => a.zIndex - b.zIndex).map((e) => e.key);
1427
+ }
1428
+ /**
1429
+ * Serialize to JSON string.
1430
+ */
1431
+ toJSON() {
1432
+ return JSON.stringify(this.serialize());
1433
+ }
1434
+ /**
1435
+ * Deserialize from JSON string.
1436
+ */
1437
+ fromJSON(jsonString) {
1438
+ try {
1439
+ const data = JSON.parse(jsonString);
1440
+ this.deserialize(data);
1441
+ } catch (error) {
1442
+ console.error("MindCache: Failed to deserialize JSON:", error);
1443
+ }
1444
+ }
1445
+ /**
1446
+ * Export to Markdown format.
1447
+ */
1448
+ toMarkdown() {
1449
+ const now = /* @__PURE__ */ new Date();
1450
+ const lines = [];
1451
+ const appendixEntries = [];
1452
+ let appendixCounter = 0;
1453
+ lines.push("# MindCache STM Export");
1454
+ lines.push("");
1455
+ lines.push(`Export Date: ${now.toISOString().split("T")[0]}`);
1456
+ lines.push("");
1457
+ lines.push("---");
1458
+ lines.push("");
1459
+ lines.push("## STM Entries");
1460
+ lines.push("");
1461
+ const sortedKeys = this.getSortedKeys();
1462
+ sortedKeys.forEach((key) => {
1463
+ const entryMap = this.rootMap.get(key);
1464
+ if (!entryMap) {
1465
+ return;
1466
+ }
1467
+ const attributes = entryMap.get("attributes");
1468
+ const value = entryMap.get("value");
1469
+ if (attributes?.hardcoded) {
1470
+ return;
1471
+ }
1472
+ lines.push(`### ${key}`);
1473
+ const entryType = attributes?.type || "text";
1474
+ lines.push(`- **Type**: \`${entryType}\``);
1475
+ lines.push(`- **Readonly**: \`${attributes?.readonly ?? false}\``);
1476
+ lines.push(`- **Visible**: \`${attributes?.visible ?? true}\``);
1477
+ lines.push(`- **Template**: \`${attributes?.template ?? false}\``);
1478
+ lines.push(`- **Z-Index**: \`${attributes?.zIndex ?? 0}\``);
1479
+ if (attributes?.contentTags && attributes.contentTags.length > 0) {
1480
+ lines.push(`- **Tags**: \`${attributes.contentTags.join("`, `")}\``);
1481
+ }
1482
+ if (attributes?.contentType) {
1483
+ lines.push(`- **Content Type**: \`${attributes.contentType}\``);
1484
+ }
1485
+ if (entryType === "image" || entryType === "file") {
1486
+ const label = String.fromCharCode(65 + appendixCounter);
1487
+ appendixCounter++;
1488
+ lines.push(`- **Value**: [See Appendix ${label}]`);
1489
+ appendixEntries.push({
1490
+ key,
1491
+ type: entryType,
1492
+ contentType: attributes?.contentType || "application/octet-stream",
1493
+ base64: value,
1494
+ label
1495
+ });
1496
+ } else if (entryType === "json") {
1497
+ lines.push("- **Value**:");
1498
+ lines.push("```json");
1499
+ try {
1500
+ const jsonValue = typeof value === "string" ? value : JSON.stringify(value, null, 2);
1501
+ lines.push(jsonValue);
1502
+ } catch {
1503
+ lines.push(String(value));
1504
+ }
1505
+ lines.push("```");
1506
+ } else {
1507
+ lines.push(`- **Value**: ${value}`);
1508
+ }
1509
+ lines.push("");
1510
+ });
1511
+ if (appendixEntries.length > 0) {
1512
+ lines.push("---");
1513
+ lines.push("");
1514
+ lines.push("## Appendix: Binary Data");
1515
+ lines.push("");
1516
+ appendixEntries.forEach((entry) => {
1517
+ lines.push(`### Appendix ${entry.label}: ${entry.key}`);
1518
+ lines.push(`- **Type**: \`${entry.type}\``);
1519
+ lines.push(`- **Content Type**: \`${entry.contentType}\``);
1520
+ lines.push("- **Base64 Data**:");
1521
+ lines.push("```");
1522
+ lines.push(entry.base64);
1523
+ lines.push("```");
1524
+ lines.push("");
1525
+ });
1526
+ }
1527
+ return lines.join("\n");
1528
+ }
1529
+ /**
1530
+ * Import from Markdown format.
1531
+ */
1532
+ fromMarkdown(markdown) {
1533
+ const lines = markdown.split("\n");
1534
+ let currentKey = null;
1535
+ let currentAttributes = {};
1536
+ let currentValue = null;
1537
+ let inCodeBlock = false;
1538
+ let codeBlockContent = [];
1539
+ for (const line of lines) {
1540
+ if (line.startsWith("### ") && !line.startsWith("### Appendix")) {
1541
+ if (currentKey && currentValue !== null) {
1542
+ this.set_value(currentKey, currentValue, currentAttributes);
1543
+ }
1544
+ currentKey = line.substring(4).trim();
1545
+ currentAttributes = {};
1546
+ currentValue = null;
1547
+ continue;
1548
+ }
1549
+ if (line.startsWith("### Appendix ")) {
1550
+ const match = line.match(/### Appendix ([A-Z]): (.+)/);
1551
+ if (match) {
1552
+ currentKey = match[2];
1553
+ }
1554
+ continue;
1555
+ }
1556
+ if (line.startsWith("- **Type**:")) {
1557
+ const type = line.match(/`(.+)`/)?.[1];
1558
+ if (type) {
1559
+ currentAttributes.type = type;
1560
+ }
1561
+ continue;
1562
+ }
1563
+ if (line.startsWith("- **Readonly**:")) {
1564
+ currentAttributes.readonly = line.includes("`true`");
1565
+ continue;
1566
+ }
1567
+ if (line.startsWith("- **Visible**:")) {
1568
+ currentAttributes.visible = line.includes("`true`");
1569
+ continue;
1570
+ }
1571
+ if (line.startsWith("- **Template**:")) {
1572
+ currentAttributes.template = line.includes("`true`");
1573
+ continue;
1574
+ }
1575
+ if (line.startsWith("- **Z-Index**:")) {
1576
+ const zIndex = parseInt(line.match(/`(\d+)`/)?.[1] || "0", 10);
1577
+ currentAttributes.zIndex = zIndex;
1578
+ continue;
1579
+ }
1580
+ if (line.startsWith("- **Tags**:")) {
1581
+ const tags = line.match(/`([^`]+)`/g)?.map((t) => t.slice(1, -1)) || [];
1582
+ currentAttributes.contentTags = tags;
1583
+ currentAttributes.tags = tags;
1584
+ continue;
1585
+ }
1586
+ if (line.startsWith("- **Content Type**:")) {
1587
+ currentAttributes.contentType = line.match(/`(.+)`/)?.[1];
1588
+ continue;
1589
+ }
1590
+ if (line.startsWith("- **Value**:") && !line.includes("[See Appendix")) {
1591
+ currentValue = line.substring(12).trim();
1592
+ continue;
1593
+ }
1594
+ if (line === "```json" || line === "```") {
1595
+ if (inCodeBlock) {
1596
+ inCodeBlock = false;
1597
+ if (currentKey && codeBlockContent.length > 0) {
1598
+ currentValue = codeBlockContent.join("\n");
1599
+ }
1600
+ codeBlockContent = [];
1601
+ } else {
1602
+ inCodeBlock = true;
1603
+ }
1604
+ continue;
1605
+ }
1606
+ if (inCodeBlock) {
1607
+ codeBlockContent.push(line);
1608
+ }
1609
+ }
1610
+ if (currentKey && currentValue !== null) {
1611
+ this.set_value(currentKey, currentValue, currentAttributes);
1612
+ }
1613
+ }
1614
+ /**
1615
+ * Set base64 binary data.
1616
+ */
1617
+ set_base64(key, base64Data, contentType, type = "file", attributes) {
1618
+ if (!this.validateContentType(type, contentType)) {
1619
+ throw new Error(`Invalid content type ${contentType} for type ${type}`);
1620
+ }
1621
+ const fileAttributes = {
1622
+ type,
1623
+ contentType,
1624
+ ...attributes
1625
+ };
1626
+ this.set_value(key, base64Data, fileAttributes);
1627
+ }
1628
+ /**
1629
+ * Add an image from base64 data.
1630
+ */
1631
+ add_image(key, base64Data, contentType = "image/jpeg", attributes) {
1632
+ if (!contentType.startsWith("image/")) {
1633
+ throw new Error(`Invalid image content type: ${contentType}. Must start with 'image/'`);
1634
+ }
1635
+ this.set_base64(key, base64Data, contentType, "image", attributes);
1636
+ }
1637
+ /**
1638
+ * Get the data URL for an image or file key.
1639
+ */
1640
+ get_data_url(key) {
1641
+ const entryMap = this.rootMap.get(key);
1642
+ if (!entryMap) {
1643
+ return void 0;
1644
+ }
1645
+ const attributes = entryMap.get("attributes");
1646
+ if (attributes?.type !== "image" && attributes?.type !== "file") {
1647
+ return void 0;
1648
+ }
1649
+ if (!attributes?.contentType) {
1650
+ return void 0;
1651
+ }
1652
+ const value = entryMap.get("value");
1653
+ return this.createDataUrl(value, attributes.contentType);
1654
+ }
1655
+ /**
1656
+ * Get the base64 data for an image or file key.
1657
+ */
1658
+ get_base64(key) {
1659
+ const entryMap = this.rootMap.get(key);
1660
+ if (!entryMap) {
1661
+ return void 0;
1662
+ }
1663
+ const attributes = entryMap.get("attributes");
1664
+ if (attributes?.type !== "image" && attributes?.type !== "file") {
1665
+ return void 0;
1666
+ }
1667
+ return entryMap.get("value");
1668
+ }
967
1669
  // File methods
968
1670
  async set_file(key, file, attributes) {
969
1671
  const base64 = await this.encodeFileToBase64(file);
@@ -1284,10 +1986,14 @@ var MindCache = class {
1284
1986
  const sanitizedKey = this.sanitizeKeyForTool(key);
1285
1987
  if (isWritable) {
1286
1988
  if (isDocument) {
1287
- lines.push(`${key}: ${displayValue}. Document tools: write_${sanitizedKey}, append_${sanitizedKey}, edit_${sanitizedKey}`);
1989
+ lines.push(
1990
+ `${key}: ${displayValue}. Document tools: write_${sanitizedKey}, append_${sanitizedKey}, edit_${sanitizedKey}`
1991
+ );
1288
1992
  } else {
1289
1993
  const oldValueHint = displayValue ? ` This tool DOES NOT append \u2014 start your response with the old value (${displayValue})` : "";
1290
- lines.push(`${key}: ${displayValue}. You can rewrite "${key}" by using the write_${sanitizedKey} tool.${oldValueHint}`);
1994
+ lines.push(
1995
+ `${key}: ${displayValue}. You can rewrite "${key}" by using the write_${sanitizedKey} tool.${oldValueHint}`
1996
+ );
1291
1997
  }
1292
1998
  } else {
1293
1999
  lines.push(`${key}: ${displayValue}`);
@@ -1428,6 +2134,9 @@ function useMindCache(options) {
1428
2134
  };
1429
2135
  }
1430
2136
 
1431
- export { CloudAdapter, DEFAULT_KEY_ATTRIBUTES, IndexedDBAdapter, MindCache, useMindCache };
2137
+ // src/index.ts
2138
+ var mindcache = new MindCache();
2139
+
2140
+ export { CloudAdapter, DEFAULT_KEY_ATTRIBUTES, IndexedDBAdapter, MindCache, mindcache, useMindCache };
1432
2141
  //# sourceMappingURL=index.mjs.map
1433
2142
  //# sourceMappingURL=index.mjs.map