mindcache 2.0.0-alpha.1 → 2.2.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
@@ -297,11 +297,16 @@ var init_CloudAdapter = __esm({
297
297
 
298
298
  // src/core/types.ts
299
299
  var DEFAULT_KEY_ATTRIBUTES = {
300
+ type: "text",
301
+ contentTags: [],
302
+ systemTags: ["prompt"],
303
+ // visible by default
304
+ zIndex: 0,
305
+ // Legacy - derived from systemTags
300
306
  readonly: false,
301
307
  visible: true,
302
308
  hardcoded: false,
303
309
  template: false,
304
- type: "text",
305
310
  tags: []
306
311
  };
307
312
 
@@ -318,7 +323,12 @@ var MindCache = class {
318
323
  _isLoaded = true;
319
324
  // Default true for local mode
320
325
  _cloudConfig = null;
326
+ // Access level for system operations
327
+ _accessLevel = "user";
321
328
  constructor(options) {
329
+ if (options?.accessLevel) {
330
+ this._accessLevel = options.accessLevel;
331
+ }
322
332
  if (options?.cloud) {
323
333
  this._cloudConfig = options.cloud;
324
334
  this._isLoaded = false;
@@ -326,6 +336,18 @@ var MindCache = class {
326
336
  this._initCloud();
327
337
  }
328
338
  }
339
+ /**
340
+ * Get the current access level
341
+ */
342
+ get accessLevel() {
343
+ return this._accessLevel;
344
+ }
345
+ /**
346
+ * Check if this instance has system-level access
347
+ */
348
+ get hasSystemAccess() {
349
+ return this._accessLevel === "system";
350
+ }
329
351
  async _initCloud() {
330
352
  if (!this._cloudConfig) {
331
353
  return;
@@ -343,18 +365,17 @@ var MindCache = class {
343
365
  if (this._cloudConfig.tokenEndpoint) {
344
366
  const tokenEndpoint = this._cloudConfig.tokenEndpoint;
345
367
  const instanceId = this._cloudConfig.instanceId;
346
- const resolveUrl = (endpoint) => {
347
- if (endpoint.startsWith("http://") || endpoint.startsWith("https://")) {
348
- return endpoint;
349
- }
350
- if (typeof window !== "undefined" && window.location?.origin) {
351
- return `${window.location.origin}${endpoint.startsWith("/") ? "" : "/"}${endpoint}`;
352
- }
353
- return endpoint;
354
- };
368
+ let resolvedBaseUrl;
369
+ if (tokenEndpoint.startsWith("http://") || tokenEndpoint.startsWith("https://")) {
370
+ resolvedBaseUrl = tokenEndpoint;
371
+ } else if (typeof window !== "undefined" && window.location?.origin) {
372
+ resolvedBaseUrl = `${window.location.origin}${tokenEndpoint.startsWith("/") ? "" : "/"}${tokenEndpoint}`;
373
+ } else {
374
+ console.warn("MindCache: Cannot resolve tokenEndpoint to absolute URL - window.location not available");
375
+ resolvedBaseUrl = tokenEndpoint;
376
+ }
355
377
  adapter.setTokenProvider(async () => {
356
- const baseUrl2 = resolveUrl(tokenEndpoint);
357
- const url = baseUrl2.includes("?") ? `${baseUrl2}&instanceId=${instanceId}` : `${baseUrl2}?instanceId=${instanceId}`;
378
+ const url = resolvedBaseUrl.includes("?") ? `${resolvedBaseUrl}&instanceId=${instanceId}` : `${resolvedBaseUrl}?instanceId=${instanceId}`;
358
379
  const response = await fetch(url);
359
380
  if (!response.ok) {
360
381
  const error = await response.json().catch(() => ({ error: "Failed to get token" }));
@@ -490,11 +511,16 @@ var MindCache = class {
490
511
  get_attributes(key) {
491
512
  if (key === "$date" || key === "$time") {
492
513
  return {
514
+ type: "text",
515
+ contentTags: [],
516
+ systemTags: ["prompt", "readonly", "protected"],
517
+ zIndex: 999999,
518
+ // System keys appear last
519
+ // Legacy attributes
493
520
  readonly: true,
494
521
  visible: true,
495
522
  hardcoded: true,
496
523
  template: false,
497
- type: "text",
498
524
  tags: []
499
525
  };
500
526
  }
@@ -507,18 +533,98 @@ var MindCache = class {
507
533
  return;
508
534
  }
509
535
  const existingEntry = this.stm[key];
510
- const baseAttributes = existingEntry ? existingEntry.attributes : { ...DEFAULT_KEY_ATTRIBUTES };
536
+ const wasHardcoded = existingEntry?.attributes.hardcoded || existingEntry?.attributes.systemTags?.includes("protected");
537
+ const baseAttributes = existingEntry ? {
538
+ ...existingEntry.attributes,
539
+ contentTags: [...existingEntry.attributes.contentTags || []],
540
+ systemTags: [...existingEntry.attributes.systemTags || []],
541
+ tags: [...existingEntry.attributes.tags || []],
542
+ zIndex: existingEntry.attributes.zIndex ?? 0
543
+ } : {
544
+ ...DEFAULT_KEY_ATTRIBUTES,
545
+ contentTags: [],
546
+ // Fresh array
547
+ systemTags: ["prompt"],
548
+ // Fresh array with default
549
+ tags: [],
550
+ // Fresh array
551
+ zIndex: 0
552
+ };
511
553
  const finalAttributes = attributes ? { ...baseAttributes, ...attributes } : baseAttributes;
512
- if (finalAttributes.hardcoded) {
513
- finalAttributes.readonly = true;
514
- finalAttributes.template = false;
554
+ if (attributes) {
555
+ let systemTags2 = [...finalAttributes.systemTags || []];
556
+ if ("readonly" in attributes) {
557
+ if (attributes.readonly && !systemTags2.includes("readonly")) {
558
+ systemTags2.push("readonly");
559
+ } else if (!attributes.readonly && !wasHardcoded) {
560
+ systemTags2 = systemTags2.filter((t) => t !== "readonly");
561
+ }
562
+ }
563
+ if ("visible" in attributes) {
564
+ if (attributes.visible && !systemTags2.includes("prompt")) {
565
+ systemTags2.push("prompt");
566
+ } else if (!attributes.visible) {
567
+ systemTags2 = systemTags2.filter((t) => t !== "prompt");
568
+ }
569
+ }
570
+ if ("hardcoded" in attributes) {
571
+ if (attributes.hardcoded && !systemTags2.includes("protected")) {
572
+ systemTags2.push("protected");
573
+ } else if (!attributes.hardcoded && !wasHardcoded) {
574
+ systemTags2 = systemTags2.filter((t) => t !== "protected");
575
+ }
576
+ if (wasHardcoded && !systemTags2.includes("protected")) {
577
+ systemTags2.push("protected");
578
+ }
579
+ } else if (wasHardcoded) {
580
+ if (!systemTags2.includes("protected")) {
581
+ systemTags2.push("protected");
582
+ }
583
+ }
584
+ if ("template" in attributes) {
585
+ if (attributes.template && !wasHardcoded && !systemTags2.includes("template")) {
586
+ systemTags2.push("template");
587
+ } else if (!attributes.template || wasHardcoded) {
588
+ systemTags2 = systemTags2.filter((t) => t !== "template");
589
+ }
590
+ }
591
+ finalAttributes.systemTags = systemTags2;
592
+ } else if (wasHardcoded) {
593
+ let systemTags2 = [...finalAttributes.systemTags || []];
594
+ if (!systemTags2.includes("protected")) {
595
+ systemTags2.push("protected");
596
+ }
597
+ if (!systemTags2.includes("readonly")) {
598
+ systemTags2.push("readonly");
599
+ }
600
+ systemTags2 = systemTags2.filter((t) => t !== "template");
601
+ finalAttributes.systemTags = systemTags2;
515
602
  }
603
+ let systemTags = finalAttributes.systemTags || [];
604
+ if (wasHardcoded && !systemTags.includes("protected")) {
605
+ systemTags = [...systemTags, "protected"];
606
+ }
607
+ if (systemTags.includes("protected")) {
608
+ if (!systemTags.includes("readonly")) {
609
+ systemTags = [...systemTags, "readonly"];
610
+ }
611
+ systemTags = systemTags.filter((t) => t !== "template");
612
+ finalAttributes.systemTags = systemTags;
613
+ }
614
+ finalAttributes.readonly = systemTags.includes("readonly");
615
+ finalAttributes.visible = systemTags.includes("prompt");
616
+ finalAttributes.hardcoded = wasHardcoded || systemTags.includes("protected");
617
+ finalAttributes.template = systemTags.includes("template");
618
+ if (attributes && "tags" in attributes && attributes.tags) {
619
+ finalAttributes.contentTags = [...attributes.tags];
620
+ }
621
+ finalAttributes.tags = [...finalAttributes.contentTags || []];
516
622
  this.stm[key] = {
517
623
  value,
518
624
  attributes: finalAttributes
519
625
  };
520
626
  if (this.listeners[key]) {
521
- this.listeners[key].forEach((listener) => listener());
627
+ this.listeners[key].forEach((listener) => listener(value));
522
628
  }
523
629
  this.notifyGlobalListeners();
524
630
  }
@@ -529,12 +635,38 @@ var MindCache = class {
529
635
  return;
530
636
  }
531
637
  this._isRemoteUpdate = true;
638
+ const systemTags = attributes.systemTags || [];
639
+ if (!attributes.systemTags) {
640
+ if (attributes.visible !== false) {
641
+ systemTags.push("prompt");
642
+ }
643
+ if (attributes.readonly) {
644
+ systemTags.push("readonly");
645
+ }
646
+ if (attributes.hardcoded) {
647
+ systemTags.push("protected");
648
+ }
649
+ if (attributes.template) {
650
+ systemTags.push("template");
651
+ }
652
+ }
653
+ const contentTags = attributes.contentTags || attributes.tags || [];
532
654
  this.stm[key] = {
533
655
  value,
534
- attributes
656
+ attributes: {
657
+ ...attributes,
658
+ contentTags,
659
+ systemTags,
660
+ zIndex: attributes.zIndex ?? 0,
661
+ tags: contentTags,
662
+ readonly: systemTags.includes("readonly"),
663
+ visible: systemTags.includes("prompt"),
664
+ hardcoded: systemTags.includes("protected"),
665
+ template: systemTags.includes("template")
666
+ }
535
667
  };
536
668
  if (this.listeners[key]) {
537
- this.listeners[key].forEach((listener) => listener());
669
+ this.listeners[key].forEach((listener) => listener(value));
538
670
  }
539
671
  this.notifyGlobalListeners();
540
672
  this._isRemoteUpdate = false;
@@ -552,7 +684,7 @@ var MindCache = class {
552
684
  if (key in this.stm) {
553
685
  delete this.stm[key];
554
686
  if (this.listeners[key]) {
555
- this.listeners[key].forEach((listener) => listener());
687
+ this.listeners[key].forEach((listener) => listener(void 0));
556
688
  }
557
689
  this.notifyGlobalListeners();
558
690
  }
@@ -574,12 +706,62 @@ var MindCache = class {
574
706
  if (!entry) {
575
707
  return false;
576
708
  }
577
- const { hardcoded: _hardcoded, ...allowedAttributes } = attributes;
709
+ const wasHardcoded = entry.attributes.hardcoded || entry.attributes.systemTags?.includes("protected");
710
+ const { hardcoded: _hardcoded, systemTags: _systemTags, ...allowedAttributes } = attributes;
711
+ if (wasHardcoded) {
712
+ if ("readonly" in allowedAttributes) {
713
+ delete allowedAttributes.readonly;
714
+ }
715
+ if ("template" in allowedAttributes) {
716
+ delete allowedAttributes.template;
717
+ }
718
+ }
578
719
  entry.attributes = { ...entry.attributes, ...allowedAttributes };
579
- if (entry.attributes.hardcoded) {
720
+ if ("readonly" in attributes || "visible" in attributes || "template" in attributes) {
721
+ let newSystemTags = [];
722
+ if (entry.attributes.readonly) {
723
+ newSystemTags.push("readonly");
724
+ }
725
+ if (entry.attributes.visible) {
726
+ newSystemTags.push("prompt");
727
+ }
728
+ if (entry.attributes.template) {
729
+ newSystemTags.push("template");
730
+ }
731
+ if (wasHardcoded || entry.attributes.hardcoded) {
732
+ newSystemTags.push("protected");
733
+ }
734
+ if (newSystemTags.includes("protected")) {
735
+ if (!newSystemTags.includes("readonly")) {
736
+ newSystemTags.push("readonly");
737
+ }
738
+ newSystemTags = newSystemTags.filter((t) => t !== "template");
739
+ entry.attributes.readonly = true;
740
+ entry.attributes.template = false;
741
+ }
742
+ entry.attributes.systemTags = newSystemTags;
743
+ } else if (wasHardcoded) {
744
+ let systemTags = [...entry.attributes.systemTags || []];
745
+ if (!systemTags.includes("protected")) {
746
+ systemTags.push("protected");
747
+ }
748
+ if (!systemTags.includes("readonly")) {
749
+ systemTags.push("readonly");
750
+ }
751
+ systemTags = systemTags.filter((t) => t !== "template");
752
+ entry.attributes.systemTags = systemTags;
753
+ }
754
+ if (wasHardcoded) {
755
+ entry.attributes.hardcoded = true;
756
+ if (!entry.attributes.systemTags?.includes("protected")) {
757
+ entry.attributes.systemTags = [...entry.attributes.systemTags || [], "protected"];
758
+ }
580
759
  entry.attributes.readonly = true;
581
760
  entry.attributes.template = false;
582
761
  }
762
+ if ("contentTags" in attributes) {
763
+ entry.attributes.tags = [...entry.attributes.contentTags || []];
764
+ }
583
765
  this.notifyGlobalListeners();
584
766
  return true;
585
767
  }
@@ -651,7 +833,7 @@ var MindCache = class {
651
833
  if (deleted) {
652
834
  this.notifyGlobalListeners();
653
835
  if (this.listeners[key]) {
654
- this.listeners[key].forEach((listener) => listener());
836
+ this.listeners[key].forEach((listener) => listener(void 0));
655
837
  }
656
838
  }
657
839
  return deleted;
@@ -660,12 +842,26 @@ var MindCache = class {
660
842
  this.stm = {};
661
843
  this.notifyGlobalListeners();
662
844
  }
845
+ /**
846
+ * Get keys sorted by zIndex (ascending), then by key name
847
+ */
848
+ getSortedKeys() {
849
+ return Object.entries(this.stm).sort(([keyA, entryA], [keyB, entryB]) => {
850
+ const zIndexA = entryA.attributes.zIndex ?? 0;
851
+ const zIndexB = entryB.attributes.zIndex ?? 0;
852
+ if (zIndexA !== zIndexB) {
853
+ return zIndexA - zIndexB;
854
+ }
855
+ return keyA.localeCompare(keyB);
856
+ }).map(([key]) => key);
857
+ }
663
858
  keys() {
664
- return [...Object.keys(this.stm), "$date", "$time"];
859
+ return [...this.getSortedKeys(), "$date", "$time"];
665
860
  }
666
861
  values() {
667
862
  const now = /* @__PURE__ */ new Date();
668
- const stmValues = Object.values(this.stm).map((entry) => entry.value);
863
+ const sortedKeys = this.getSortedKeys();
864
+ const stmValues = sortedKeys.map((key) => this.stm[key].value);
669
865
  return [
670
866
  ...stmValues,
671
867
  now.toISOString().split("T")[0],
@@ -674,8 +870,9 @@ var MindCache = class {
674
870
  }
675
871
  entries() {
676
872
  const now = /* @__PURE__ */ new Date();
677
- const stmEntries = Object.entries(this.stm).map(
678
- ([key, entry]) => [key, entry.value]
873
+ const sortedKeys = this.getSortedKeys();
874
+ const stmEntries = sortedKeys.map(
875
+ (key) => [key, this.stm[key].value]
679
876
  );
680
877
  return [
681
878
  ...stmEntries,
@@ -689,8 +886,9 @@ var MindCache = class {
689
886
  getAll() {
690
887
  const now = /* @__PURE__ */ new Date();
691
888
  const result = {};
692
- Object.entries(this.stm).forEach(([key, entry]) => {
693
- result[key] = entry.value;
889
+ const sortedKeys = this.getSortedKeys();
890
+ sortedKeys.forEach((key) => {
891
+ result[key] = this.stm[key].value;
694
892
  });
695
893
  result["$date"] = now.toISOString().split("T")[0];
696
894
  result["$time"] = now.toTimeString().split(" ")[0];
@@ -704,7 +902,7 @@ var MindCache = class {
704
902
  attributes: { ...DEFAULT_KEY_ATTRIBUTES }
705
903
  };
706
904
  if (this.listeners[key]) {
707
- this.listeners[key].forEach((listener) => listener());
905
+ this.listeners[key].forEach((listener) => listener(this.stm[key]?.value));
708
906
  }
709
907
  }
710
908
  });
@@ -773,7 +971,9 @@ var MindCache = class {
773
971
  getSTM() {
774
972
  const now = /* @__PURE__ */ new Date();
775
973
  const entries = [];
776
- Object.entries(this.stm).forEach(([key, entry]) => {
974
+ const sortedKeys = this.getSortedKeys();
975
+ sortedKeys.forEach((key) => {
976
+ const entry = this.stm[key];
777
977
  if (entry.attributes.visible) {
778
978
  entries.push([key, this.get_value(key)]);
779
979
  }
@@ -788,7 +988,9 @@ var MindCache = class {
788
988
  getSTMForAPI() {
789
989
  const now = /* @__PURE__ */ new Date();
790
990
  const apiData = [];
791
- Object.entries(this.stm).forEach(([key, entry]) => {
991
+ const sortedKeys = this.getSortedKeys();
992
+ sortedKeys.forEach((key) => {
993
+ const entry = this.stm[key];
792
994
  if (entry.attributes.visible) {
793
995
  const processedValue = entry.attributes.template ? this.get_value(key) : entry.value;
794
996
  apiData.push({
@@ -813,7 +1015,9 @@ var MindCache = class {
813
1015
  }
814
1016
  getVisibleImages() {
815
1017
  const imageParts = [];
816
- Object.entries(this.stm).forEach(([key, entry]) => {
1018
+ const sortedKeys = this.getSortedKeys();
1019
+ sortedKeys.forEach((key) => {
1020
+ const entry = this.stm[key];
817
1021
  if (entry.attributes.visible && entry.attributes.type === "image" && entry.attributes.contentType) {
818
1022
  const dataUrl = this.createDataUrl(entry.value, entry.attributes.contentType);
819
1023
  imageParts.push({
@@ -839,7 +1043,9 @@ var MindCache = class {
839
1043
  }
840
1044
  serialize() {
841
1045
  const result = {};
842
- Object.entries(this.stm).forEach(([key, entry]) => {
1046
+ const sortedKeys = this.getSortedKeys();
1047
+ sortedKeys.forEach((key) => {
1048
+ const entry = this.stm[key];
843
1049
  if (!entry.attributes.hardcoded) {
844
1050
  result[key] = {
845
1051
  value: entry.value,
@@ -854,11 +1060,40 @@ var MindCache = class {
854
1060
  this.clear();
855
1061
  Object.entries(data).forEach(([key, entry]) => {
856
1062
  if (entry && typeof entry === "object" && "value" in entry && "attributes" in entry) {
1063
+ const attrs = entry.attributes;
1064
+ if (attrs.hardcoded === true || attrs.systemTags?.includes("protected")) {
1065
+ return;
1066
+ }
1067
+ let systemTags = attrs.systemTags || [];
1068
+ if (!attrs.systemTags) {
1069
+ systemTags = [];
1070
+ if (attrs.visible !== false) {
1071
+ systemTags.push("prompt");
1072
+ }
1073
+ if (attrs.readonly) {
1074
+ systemTags.push("readonly");
1075
+ }
1076
+ if (attrs.hardcoded) {
1077
+ systemTags.push("protected");
1078
+ }
1079
+ if (attrs.template) {
1080
+ systemTags.push("template");
1081
+ }
1082
+ }
1083
+ const contentTags = attrs.contentTags || attrs.tags || [];
857
1084
  this.stm[key] = {
858
1085
  value: entry.value,
859
1086
  attributes: {
860
- ...entry.attributes,
861
- tags: entry.attributes.tags || []
1087
+ ...attrs,
1088
+ contentTags,
1089
+ systemTags,
1090
+ zIndex: attrs.zIndex ?? 0,
1091
+ // Sync legacy attributes
1092
+ tags: contentTags,
1093
+ readonly: systemTags.includes("readonly"),
1094
+ visible: systemTags.includes("prompt"),
1095
+ hardcoded: systemTags.includes("protected"),
1096
+ template: systemTags.includes("template")
862
1097
  }
863
1098
  };
864
1099
  }
@@ -869,7 +1104,9 @@ var MindCache = class {
869
1104
  get_system_prompt() {
870
1105
  const now = /* @__PURE__ */ new Date();
871
1106
  const promptLines = [];
872
- Object.entries(this.stm).forEach(([key, entry]) => {
1107
+ const sortedKeys = this.getSortedKeys();
1108
+ sortedKeys.forEach((key) => {
1109
+ const entry = this.stm[key];
873
1110
  if (entry.attributes.visible) {
874
1111
  if (entry.attributes.type === "image") {
875
1112
  promptLines.push(`image ${key} available`);
@@ -904,14 +1141,18 @@ var MindCache = class {
904
1141
  return void 0;
905
1142
  }
906
1143
  const sanitizedKey = toolName.replace("write_", "");
907
- const allKeys = Object.keys(this.stm);
908
- return allKeys.find(
1144
+ const sortedKeys = this.getSortedKeys();
1145
+ return sortedKeys.find(
909
1146
  (k) => k.replace(/[^a-zA-Z0-9_-]/g, "_") === sanitizedKey
910
1147
  );
911
1148
  }
912
1149
  get_aisdk_tools() {
913
1150
  const tools = {};
914
- const writableKeys = Object.entries(this.stm).filter(([, entry]) => !entry.attributes.readonly).map(([key]) => key);
1151
+ const sortedKeys = this.getSortedKeys();
1152
+ const writableKeys = sortedKeys.filter((key) => {
1153
+ const entry = this.stm[key];
1154
+ return !entry.attributes.readonly;
1155
+ });
915
1156
  writableKeys.forEach((key) => {
916
1157
  const sanitizedKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
917
1158
  const toolName = `write_${sanitizedKey}`;
@@ -995,6 +1236,12 @@ var MindCache = class {
995
1236
  value
996
1237
  };
997
1238
  }
1239
+ // ============================================
1240
+ // Content Tag Methods (available to all access levels)
1241
+ // ============================================
1242
+ /**
1243
+ * Add a content tag to a key (user-level organization)
1244
+ */
998
1245
  addTag(key, tag) {
999
1246
  if (key === "$date" || key === "$time") {
1000
1247
  return false;
@@ -1003,64 +1250,231 @@ var MindCache = class {
1003
1250
  if (!entry) {
1004
1251
  return false;
1005
1252
  }
1006
- if (!entry.attributes.tags) {
1007
- entry.attributes.tags = [];
1253
+ if (!entry.attributes.contentTags) {
1254
+ entry.attributes.contentTags = [];
1008
1255
  }
1009
- if (!entry.attributes.tags.includes(tag)) {
1010
- entry.attributes.tags.push(tag);
1256
+ if (!entry.attributes.contentTags.includes(tag)) {
1257
+ entry.attributes.contentTags.push(tag);
1258
+ entry.attributes.tags = [...entry.attributes.contentTags];
1011
1259
  this.notifyGlobalListeners();
1012
1260
  return true;
1013
1261
  }
1014
1262
  return false;
1015
1263
  }
1264
+ /**
1265
+ * Remove a content tag from a key
1266
+ */
1016
1267
  removeTag(key, tag) {
1017
1268
  if (key === "$date" || key === "$time") {
1018
1269
  return false;
1019
1270
  }
1020
1271
  const entry = this.stm[key];
1021
- if (!entry || !entry.attributes.tags) {
1272
+ if (!entry || !entry.attributes.contentTags) {
1022
1273
  return false;
1023
1274
  }
1024
- const tagIndex = entry.attributes.tags.indexOf(tag);
1275
+ const tagIndex = entry.attributes.contentTags.indexOf(tag);
1025
1276
  if (tagIndex > -1) {
1026
- entry.attributes.tags.splice(tagIndex, 1);
1277
+ entry.attributes.contentTags.splice(tagIndex, 1);
1278
+ entry.attributes.tags = [...entry.attributes.contentTags];
1027
1279
  this.notifyGlobalListeners();
1028
1280
  return true;
1029
1281
  }
1030
1282
  return false;
1031
1283
  }
1284
+ /**
1285
+ * Get all content tags for a key
1286
+ */
1032
1287
  getTags(key) {
1033
1288
  if (key === "$date" || key === "$time") {
1034
1289
  return [];
1035
1290
  }
1036
1291
  const entry = this.stm[key];
1037
- return entry?.attributes.tags || [];
1292
+ return entry?.attributes.contentTags || [];
1038
1293
  }
1294
+ /**
1295
+ * Get all unique content tags across all keys
1296
+ */
1039
1297
  getAllTags() {
1040
1298
  const allTags = /* @__PURE__ */ new Set();
1041
1299
  Object.values(this.stm).forEach((entry) => {
1042
- if (entry.attributes.tags) {
1043
- entry.attributes.tags.forEach((tag) => allTags.add(tag));
1300
+ if (entry.attributes.contentTags) {
1301
+ entry.attributes.contentTags.forEach((tag) => allTags.add(tag));
1044
1302
  }
1045
1303
  });
1046
1304
  return Array.from(allTags);
1047
1305
  }
1306
+ /**
1307
+ * Check if a key has a specific content tag
1308
+ */
1048
1309
  hasTag(key, tag) {
1049
1310
  if (key === "$date" || key === "$time") {
1050
1311
  return false;
1051
1312
  }
1052
1313
  const entry = this.stm[key];
1053
- return entry?.attributes.tags?.includes(tag) || false;
1314
+ return entry?.attributes.contentTags?.includes(tag) || false;
1054
1315
  }
1316
+ /**
1317
+ * Get all keys with a specific content tag as formatted string
1318
+ */
1055
1319
  getTagged(tag) {
1056
1320
  const entries = [];
1057
- Object.entries(this.stm).forEach(([key, entry]) => {
1058
- if (entry.attributes.tags?.includes(tag)) {
1321
+ const sortedKeys = this.getSortedKeys();
1322
+ sortedKeys.forEach((key) => {
1323
+ const entry = this.stm[key];
1324
+ if (entry.attributes.contentTags?.includes(tag)) {
1059
1325
  entries.push([key, this.get_value(key)]);
1060
1326
  }
1061
1327
  });
1062
1328
  return entries.map(([key, value]) => `${key}: ${value}`).join(", ");
1063
1329
  }
1330
+ /**
1331
+ * Get all keys with a specific content tag
1332
+ */
1333
+ getKeysByTag(tag) {
1334
+ const sortedKeys = this.getSortedKeys();
1335
+ return sortedKeys.filter((key) => {
1336
+ const entry = this.stm[key];
1337
+ return entry.attributes.contentTags?.includes(tag);
1338
+ });
1339
+ }
1340
+ // ============================================
1341
+ // System Tag Methods (requires system access level)
1342
+ // ============================================
1343
+ /**
1344
+ * Add a system tag to a key (requires system access)
1345
+ * System tags: 'prompt', 'readonly', 'protected', 'template'
1346
+ */
1347
+ systemAddTag(key, tag) {
1348
+ if (!this.hasSystemAccess) {
1349
+ console.warn("MindCache: systemAddTag requires system access level");
1350
+ return false;
1351
+ }
1352
+ if (key === "$date" || key === "$time") {
1353
+ return false;
1354
+ }
1355
+ const entry = this.stm[key];
1356
+ if (!entry) {
1357
+ return false;
1358
+ }
1359
+ if (!entry.attributes.systemTags) {
1360
+ entry.attributes.systemTags = [];
1361
+ }
1362
+ if (!entry.attributes.systemTags.includes(tag)) {
1363
+ entry.attributes.systemTags.push(tag);
1364
+ this.syncLegacyFromSystemTags(entry);
1365
+ this.notifyGlobalListeners();
1366
+ return true;
1367
+ }
1368
+ return false;
1369
+ }
1370
+ /**
1371
+ * Remove a system tag from a key (requires system access)
1372
+ */
1373
+ systemRemoveTag(key, tag) {
1374
+ if (!this.hasSystemAccess) {
1375
+ console.warn("MindCache: systemRemoveTag requires system access level");
1376
+ return false;
1377
+ }
1378
+ if (key === "$date" || key === "$time") {
1379
+ return false;
1380
+ }
1381
+ const entry = this.stm[key];
1382
+ if (!entry || !entry.attributes.systemTags) {
1383
+ return false;
1384
+ }
1385
+ const isHardcoded = entry.attributes.hardcoded || entry.attributes.systemTags.includes("protected");
1386
+ if (tag === "protected" && isHardcoded) {
1387
+ return false;
1388
+ }
1389
+ const tagIndex = entry.attributes.systemTags.indexOf(tag);
1390
+ if (tagIndex > -1) {
1391
+ entry.attributes.systemTags.splice(tagIndex, 1);
1392
+ this.syncLegacyFromSystemTags(entry);
1393
+ if (isHardcoded) {
1394
+ if (!entry.attributes.systemTags.includes("protected")) {
1395
+ entry.attributes.systemTags.push("protected");
1396
+ }
1397
+ entry.attributes.hardcoded = true;
1398
+ entry.attributes.readonly = true;
1399
+ entry.attributes.template = false;
1400
+ }
1401
+ this.notifyGlobalListeners();
1402
+ return true;
1403
+ }
1404
+ return false;
1405
+ }
1406
+ /**
1407
+ * Get all system tags for a key (requires system access)
1408
+ */
1409
+ systemGetTags(key) {
1410
+ if (!this.hasSystemAccess) {
1411
+ console.warn("MindCache: systemGetTags requires system access level");
1412
+ return [];
1413
+ }
1414
+ if (key === "$date" || key === "$time") {
1415
+ return [];
1416
+ }
1417
+ const entry = this.stm[key];
1418
+ return entry?.attributes.systemTags || [];
1419
+ }
1420
+ /**
1421
+ * Check if a key has a specific system tag (requires system access)
1422
+ */
1423
+ systemHasTag(key, tag) {
1424
+ if (!this.hasSystemAccess) {
1425
+ console.warn("MindCache: systemHasTag requires system access level");
1426
+ return false;
1427
+ }
1428
+ if (key === "$date" || key === "$time") {
1429
+ return false;
1430
+ }
1431
+ const entry = this.stm[key];
1432
+ return entry?.attributes.systemTags?.includes(tag) || false;
1433
+ }
1434
+ /**
1435
+ * Set all system tags for a key at once (requires system access)
1436
+ */
1437
+ systemSetTags(key, tags) {
1438
+ if (!this.hasSystemAccess) {
1439
+ console.warn("MindCache: systemSetTags requires system access level");
1440
+ return false;
1441
+ }
1442
+ if (key === "$date" || key === "$time") {
1443
+ return false;
1444
+ }
1445
+ const entry = this.stm[key];
1446
+ if (!entry) {
1447
+ return false;
1448
+ }
1449
+ entry.attributes.systemTags = [...tags];
1450
+ this.syncLegacyFromSystemTags(entry);
1451
+ this.notifyGlobalListeners();
1452
+ return true;
1453
+ }
1454
+ /**
1455
+ * Get all keys with a specific system tag (requires system access)
1456
+ */
1457
+ systemGetKeysByTag(tag) {
1458
+ if (!this.hasSystemAccess) {
1459
+ console.warn("MindCache: systemGetKeysByTag requires system access level");
1460
+ return [];
1461
+ }
1462
+ const sortedKeys = this.getSortedKeys();
1463
+ return sortedKeys.filter((key) => {
1464
+ const entry = this.stm[key];
1465
+ return entry.attributes.systemTags?.includes(tag);
1466
+ });
1467
+ }
1468
+ /**
1469
+ * Helper to sync legacy boolean attributes from system tags
1470
+ */
1471
+ syncLegacyFromSystemTags(entry) {
1472
+ const tags = entry.attributes.systemTags || [];
1473
+ entry.attributes.readonly = tags.includes("readonly");
1474
+ entry.attributes.visible = tags.includes("prompt");
1475
+ entry.attributes.hardcoded = tags.includes("protected");
1476
+ entry.attributes.template = tags.includes("template");
1477
+ }
1064
1478
  toMarkdown() {
1065
1479
  const now = /* @__PURE__ */ new Date();
1066
1480
  const lines = [];
@@ -1074,7 +1488,9 @@ var MindCache = class {
1074
1488
  lines.push("");
1075
1489
  lines.push("## STM Entries");
1076
1490
  lines.push("");
1077
- Object.entries(this.stm).forEach(([key, entry]) => {
1491
+ const sortedKeys = this.getSortedKeys();
1492
+ sortedKeys.forEach((key) => {
1493
+ const entry = this.stm[key];
1078
1494
  if (entry.attributes.hardcoded) {
1079
1495
  return;
1080
1496
  }
@@ -1084,6 +1500,7 @@ var MindCache = class {
1084
1500
  lines.push(`- **Readonly**: \`${entry.attributes.readonly}\``);
1085
1501
  lines.push(`- **Visible**: \`${entry.attributes.visible}\``);
1086
1502
  lines.push(`- **Template**: \`${entry.attributes.template}\``);
1503
+ lines.push(`- **Z-Index**: \`${entry.attributes.zIndex ?? 0}\``);
1087
1504
  if (entry.attributes.tags && entry.attributes.tags.length > 0) {
1088
1505
  lines.push(`- **Tags**: \`${entry.attributes.tags.join("`, `")}\``);
1089
1506
  }
@@ -1196,11 +1613,9 @@ var MindCache = class {
1196
1613
  currentEntry = {
1197
1614
  value: void 0,
1198
1615
  attributes: {
1199
- readonly: false,
1200
- visible: true,
1201
- hardcoded: false,
1202
- template: false,
1203
- type: "text",
1616
+ ...DEFAULT_KEY_ATTRIBUTES,
1617
+ contentTags: [],
1618
+ systemTags: ["prompt"],
1204
1619
  tags: []
1205
1620
  }
1206
1621
  };
@@ -1224,6 +1639,14 @@ var MindCache = class {
1224
1639
  if (currentEntry) {
1225
1640
  currentEntry.attributes.template = value;
1226
1641
  }
1642
+ } else if (trimmed.startsWith("- **Z-Index**: `")) {
1643
+ const zIndexStr = trimmed.match(/`([^`]+)`/)?.[1];
1644
+ if (currentEntry && zIndexStr) {
1645
+ const zIndex = parseInt(zIndexStr, 10);
1646
+ if (!isNaN(zIndex)) {
1647
+ currentEntry.attributes.zIndex = zIndex;
1648
+ }
1649
+ }
1227
1650
  } else if (trimmed.startsWith("- **Tags**: `")) {
1228
1651
  const tagsStr = trimmed.substring(13, trimmed.length - 1);
1229
1652
  if (currentEntry) {
@@ -1280,9 +1703,35 @@ var MindCache = class {
1280
1703
  }
1281
1704
  }
1282
1705
  if (entry.value !== void 0 && entry.attributes) {
1706
+ const attrs = entry.attributes;
1707
+ if (attrs.tags && attrs.tags.length > 0 && (!attrs.contentTags || attrs.contentTags.length === 0)) {
1708
+ attrs.contentTags = [...attrs.tags];
1709
+ }
1710
+ if (!attrs.systemTags || attrs.systemTags.length === 0) {
1711
+ const systemTags = [];
1712
+ if (attrs.visible !== false) {
1713
+ systemTags.push("prompt");
1714
+ }
1715
+ if (attrs.readonly) {
1716
+ systemTags.push("readonly");
1717
+ }
1718
+ if (attrs.hardcoded) {
1719
+ systemTags.push("protected");
1720
+ }
1721
+ if (attrs.template) {
1722
+ systemTags.push("template");
1723
+ }
1724
+ attrs.systemTags = systemTags;
1725
+ }
1726
+ if (!attrs.contentTags) {
1727
+ attrs.contentTags = [];
1728
+ }
1729
+ if (!attrs.tags) {
1730
+ attrs.tags = [...attrs.contentTags];
1731
+ }
1283
1732
  this.stm[key] = {
1284
1733
  value: entry.value,
1285
- attributes: entry.attributes
1734
+ attributes: attrs
1286
1735
  };
1287
1736
  }
1288
1737
  });