mindcache 2.3.0 → 2.4.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.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { useState, useRef, useEffect } from 'react';
2
3
 
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -10,6 +11,157 @@ var __export = (target, all) => {
10
11
  __defProp(target, name, { get: all[name], enumerable: true });
11
12
  };
12
13
 
14
+ // src/local/IndexedDBAdapter.ts
15
+ var IndexedDBAdapter_exports = {};
16
+ __export(IndexedDBAdapter_exports, {
17
+ IndexedDBAdapter: () => IndexedDBAdapter
18
+ });
19
+ var IndexedDBAdapter;
20
+ var init_IndexedDBAdapter = __esm({
21
+ "src/local/IndexedDBAdapter.ts"() {
22
+ IndexedDBAdapter = class {
23
+ constructor(config = {}) {
24
+ this.config = config;
25
+ this.dbName = config.dbName || "mindcache_db";
26
+ this.storeName = config.storeName || "mindcache_store";
27
+ this.key = config.key || "mindcache_data";
28
+ }
29
+ mindcache = null;
30
+ unsubscribe = null;
31
+ saveTimeout = null;
32
+ db = null;
33
+ dbName;
34
+ storeName;
35
+ key;
36
+ async attach(mc) {
37
+ if (this.mindcache) {
38
+ this.detach();
39
+ }
40
+ this.mindcache = mc;
41
+ await this.initDB();
42
+ await this.load();
43
+ const listener = () => {
44
+ if (this.mindcache && !this.mindcache.isRemoteUpdate()) {
45
+ this.scheduleSave();
46
+ }
47
+ };
48
+ mc.subscribeToAll(listener);
49
+ this.unsubscribe = () => mc.unsubscribeFromAll(listener);
50
+ console.log("\u{1F5C4}\uFE0F IndexedDBAdapter: Attached to MindCache instance");
51
+ }
52
+ detach() {
53
+ if (this.unsubscribe) {
54
+ this.unsubscribe();
55
+ this.unsubscribe = null;
56
+ }
57
+ if (this.saveTimeout) {
58
+ clearTimeout(this.saveTimeout);
59
+ this.saveTimeout = null;
60
+ }
61
+ this.mindcache = null;
62
+ if (this.db) {
63
+ this.db.close();
64
+ this.db = null;
65
+ }
66
+ }
67
+ initDB() {
68
+ return new Promise((resolve, reject) => {
69
+ const request = indexedDB.open(this.dbName);
70
+ request.onerror = () => {
71
+ console.error("MindCache: IndexedDB error:", request.error);
72
+ reject(request.error);
73
+ };
74
+ request.onsuccess = () => {
75
+ const db = request.result;
76
+ if (!db.objectStoreNames.contains(this.storeName)) {
77
+ const currentVersion = db.version;
78
+ db.close();
79
+ const upgradeRequest = indexedDB.open(this.dbName, currentVersion + 1);
80
+ upgradeRequest.onerror = () => {
81
+ console.error("MindCache: IndexedDB upgrade error:", upgradeRequest.error);
82
+ reject(upgradeRequest.error);
83
+ };
84
+ upgradeRequest.onupgradeneeded = () => {
85
+ const upgradeDb = upgradeRequest.result;
86
+ if (!upgradeDb.objectStoreNames.contains(this.storeName)) {
87
+ upgradeDb.createObjectStore(this.storeName);
88
+ }
89
+ };
90
+ upgradeRequest.onsuccess = () => {
91
+ this.db = upgradeRequest.result;
92
+ resolve();
93
+ };
94
+ } else {
95
+ this.db = db;
96
+ resolve();
97
+ }
98
+ };
99
+ request.onupgradeneeded = () => {
100
+ const db = request.result;
101
+ if (!db.objectStoreNames.contains(this.storeName)) {
102
+ db.createObjectStore(this.storeName);
103
+ }
104
+ };
105
+ });
106
+ }
107
+ load() {
108
+ if (!this.db || !this.mindcache) {
109
+ return Promise.resolve();
110
+ }
111
+ return new Promise((resolve) => {
112
+ try {
113
+ const transaction = this.db.transaction([this.storeName], "readonly");
114
+ const store = transaction.objectStore(this.storeName);
115
+ const request = store.get(this.key);
116
+ request.onsuccess = () => {
117
+ if (request.result) {
118
+ this.mindcache.deserialize(request.result);
119
+ console.log("\u{1F5C4}\uFE0F IndexedDBAdapter: Loaded data from IndexedDB");
120
+ }
121
+ resolve();
122
+ };
123
+ request.onerror = () => {
124
+ console.error("MindCache: Failed to load from IndexedDB:", request.error);
125
+ resolve();
126
+ };
127
+ } catch (error) {
128
+ console.error("MindCache: Error accessing IndexedDB for load:", error);
129
+ resolve();
130
+ }
131
+ });
132
+ }
133
+ scheduleSave() {
134
+ if (this.saveTimeout) {
135
+ clearTimeout(this.saveTimeout);
136
+ }
137
+ this.saveTimeout = setTimeout(() => {
138
+ this.save();
139
+ this.saveTimeout = null;
140
+ }, this.config.debounceMs ?? 1e3);
141
+ }
142
+ save() {
143
+ if (!this.db || !this.mindcache) {
144
+ return;
145
+ }
146
+ try {
147
+ const data = this.mindcache.serialize();
148
+ const transaction = this.db.transaction([this.storeName], "readwrite");
149
+ const store = transaction.objectStore(this.storeName);
150
+ const request = store.put(data, this.key);
151
+ request.onsuccess = () => {
152
+ console.log("\u{1F5C4}\uFE0F IndexedDBAdapter: Saved to IndexedDB");
153
+ };
154
+ request.onerror = () => {
155
+ console.error("MindCache: Failed to save to IndexedDB:", request.error);
156
+ };
157
+ } catch (error) {
158
+ console.error("MindCache: Error accessing IndexedDB for save:", error);
159
+ }
160
+ }
161
+ };
162
+ }
163
+ });
164
+
13
165
  // src/cloud/CloudAdapter.ts
14
166
  var CloudAdapter_exports = {};
15
167
  __export(CloudAdapter_exports, {
@@ -328,8 +480,8 @@ var init_CloudAdapter = __esm({
328
480
  var DEFAULT_KEY_ATTRIBUTES = {
329
481
  type: "text",
330
482
  contentTags: [],
331
- systemTags: ["prompt"],
332
- // visible by default
483
+ systemTags: ["SystemPrompt", "LLMWrite"],
484
+ // visible in system prompt and writable by LLM by default
333
485
  zIndex: 0,
334
486
  // Legacy - derived from systemTags
335
487
  readonly: false,
@@ -346,6 +498,65 @@ var MindCache = class {
346
498
  globalListeners = [];
347
499
  // Internal flag to prevent sync loops when receiving remote updates
348
500
  _isRemoteUpdate = false;
501
+ /**
502
+ * Normalize system tags: migrate old tags to new ones
503
+ * - 'prompt' → 'SystemPrompt'
504
+ * - 'readonly' → remove 'LLMWrite' (or add if not readonly)
505
+ */
506
+ normalizeSystemTags(tags) {
507
+ const normalized = [];
508
+ let hasSystemPrompt = false;
509
+ let hasLLMRead = false;
510
+ let hasLLMWrite = false;
511
+ let hasReadonly = false;
512
+ for (const tag of tags) {
513
+ if (tag === "SystemPrompt" || tag === "prompt") {
514
+ hasSystemPrompt = true;
515
+ } else if (tag === "LLMRead") {
516
+ hasLLMRead = true;
517
+ } else if (tag === "LLMWrite") {
518
+ hasLLMWrite = true;
519
+ } else if (tag === "readonly") {
520
+ hasReadonly = true;
521
+ } else if (tag === "protected") {
522
+ normalized.push(tag);
523
+ } else if (tag === "ApplyTemplate" || tag === "template") {
524
+ normalized.push("ApplyTemplate");
525
+ }
526
+ }
527
+ if (hasSystemPrompt) {
528
+ normalized.push("SystemPrompt");
529
+ }
530
+ if (hasLLMRead) {
531
+ normalized.push("LLMRead");
532
+ }
533
+ if (hasReadonly) {
534
+ normalized.push("readonly");
535
+ } else if (hasLLMWrite) {
536
+ normalized.push("LLMWrite");
537
+ } else {
538
+ normalized.push("LLMWrite");
539
+ }
540
+ return normalized;
541
+ }
542
+ /**
543
+ * Check if key should be visible in system prompt
544
+ */
545
+ hasSystemPrompt(tags) {
546
+ return tags.includes("SystemPrompt") || tags.includes("prompt");
547
+ }
548
+ /**
549
+ * Check if key can be read by LLM (has LLMRead or SystemPrompt)
550
+ */
551
+ hasLLMRead(tags) {
552
+ return tags.includes("LLMRead") || tags.includes("SystemPrompt") || tags.includes("prompt");
553
+ }
554
+ /**
555
+ * Check if key can be written by LLM (has LLMWrite and not readonly)
556
+ */
557
+ hasLLMWrite(tags) {
558
+ return tags.includes("LLMWrite") && !tags.includes("readonly");
559
+ }
349
560
  // Cloud sync state
350
561
  _cloudAdapter = null;
351
562
  _connectionState = "disconnected";
@@ -359,11 +570,28 @@ var MindCache = class {
359
570
  if (options?.accessLevel) {
360
571
  this._accessLevel = options.accessLevel;
361
572
  }
573
+ if (options?.cloud && options?.indexedDB) {
574
+ throw new Error(
575
+ "MindCache: Cannot use both cloud and indexedDB together. Choose one persistence method to avoid data conflicts. Use cloud for real-time sync, or indexedDB for local-only persistence."
576
+ );
577
+ }
578
+ const initPromises = [];
362
579
  if (options?.cloud) {
363
580
  this._cloudConfig = options.cloud;
364
581
  this._isLoaded = false;
365
582
  this._connectionState = "disconnected";
366
- this._initPromise = this._initCloud();
583
+ initPromises.push(this._initCloud());
584
+ }
585
+ if (options?.indexedDB) {
586
+ this._isLoaded = false;
587
+ initPromises.push(this._initIndexedDB(options.indexedDB));
588
+ }
589
+ if (initPromises.length > 0) {
590
+ this._initPromise = Promise.all(initPromises).then(() => {
591
+ if (!this._cloudConfig) {
592
+ this._isLoaded = true;
593
+ }
594
+ });
367
595
  }
368
596
  }
369
597
  /**
@@ -443,6 +671,19 @@ var MindCache = class {
443
671
  this._isLoaded = true;
444
672
  }
445
673
  }
674
+ async _initIndexedDB(config) {
675
+ try {
676
+ const IndexedDBAdapter2 = await this._getIndexedDBAdapterClass();
677
+ const adapter = new IndexedDBAdapter2(config);
678
+ await adapter.attach(this);
679
+ } catch (error) {
680
+ console.error("MindCache: Failed to initialize IndexedDB:", error);
681
+ }
682
+ }
683
+ async _getIndexedDBAdapterClass() {
684
+ const { IndexedDBAdapter: IndexedDBAdapter2 } = await Promise.resolve().then(() => (init_IndexedDBAdapter(), IndexedDBAdapter_exports));
685
+ return IndexedDBAdapter2;
686
+ }
446
687
  /**
447
688
  * Get the current cloud connection state
448
689
  */
@@ -561,7 +802,7 @@ var MindCache = class {
561
802
  if (!entry) {
562
803
  return void 0;
563
804
  }
564
- if (entry.attributes.template) {
805
+ if (entry.attributes.systemTags?.includes("ApplyTemplate") || entry.attributes.systemTags?.includes("template") || entry.attributes.template) {
565
806
  const processingStack = _processingStack || /* @__PURE__ */ new Set();
566
807
  if (processingStack.has(key)) {
567
808
  return entry.value;
@@ -610,77 +851,87 @@ var MindCache = class {
610
851
  ...DEFAULT_KEY_ATTRIBUTES,
611
852
  contentTags: [],
612
853
  // Fresh array
613
- systemTags: ["prompt"],
854
+ systemTags: ["SystemPrompt", "LLMWrite"],
614
855
  // Fresh array with default
615
856
  tags: [],
616
857
  // Fresh array
617
858
  zIndex: 0
618
859
  };
619
860
  const finalAttributes = attributes ? { ...baseAttributes, ...attributes } : baseAttributes;
861
+ let systemTags = this.normalizeSystemTags(finalAttributes.systemTags || []);
620
862
  if (attributes) {
621
- let systemTags2 = [...finalAttributes.systemTags || []];
622
863
  if ("readonly" in attributes) {
623
- if (attributes.readonly && !systemTags2.includes("readonly")) {
624
- systemTags2.push("readonly");
625
- } else if (!attributes.readonly && !wasHardcoded) {
626
- systemTags2 = systemTags2.filter((t) => t !== "readonly");
864
+ if (attributes.readonly) {
865
+ systemTags = systemTags.filter((t) => t !== "LLMWrite");
866
+ if (!systemTags.includes("readonly")) {
867
+ systemTags.push("readonly");
868
+ }
869
+ } else if (!wasHardcoded) {
870
+ if (!systemTags.includes("LLMWrite")) {
871
+ systemTags.push("LLMWrite");
872
+ }
873
+ systemTags = systemTags.filter((t) => t !== "readonly");
627
874
  }
628
875
  }
629
876
  if ("visible" in attributes) {
630
- if (attributes.visible && !systemTags2.includes("prompt")) {
631
- systemTags2.push("prompt");
632
- } else if (!attributes.visible) {
633
- systemTags2 = systemTags2.filter((t) => t !== "prompt");
877
+ if (attributes.visible) {
878
+ if (!systemTags.includes("SystemPrompt")) {
879
+ systemTags.push("SystemPrompt");
880
+ }
881
+ systemTags = systemTags.filter((t) => t !== "prompt");
882
+ } else {
883
+ systemTags = systemTags.filter((t) => t !== "SystemPrompt" && t !== "prompt");
634
884
  }
635
885
  }
886
+ if ("systemTags" in attributes && Array.isArray(attributes.systemTags)) {
887
+ systemTags = this.normalizeSystemTags(attributes.systemTags);
888
+ }
636
889
  if ("hardcoded" in attributes) {
637
- if (attributes.hardcoded && !systemTags2.includes("protected")) {
638
- systemTags2.push("protected");
890
+ if (attributes.hardcoded && !systemTags.includes("protected")) {
891
+ systemTags.push("protected");
639
892
  } else if (!attributes.hardcoded && !wasHardcoded) {
640
- systemTags2 = systemTags2.filter((t) => t !== "protected");
893
+ systemTags = systemTags.filter((t) => t !== "protected");
641
894
  }
642
- if (wasHardcoded && !systemTags2.includes("protected")) {
643
- systemTags2.push("protected");
895
+ if (wasHardcoded && !systemTags.includes("protected")) {
896
+ systemTags.push("protected");
644
897
  }
645
898
  } else if (wasHardcoded) {
646
- if (!systemTags2.includes("protected")) {
647
- systemTags2.push("protected");
899
+ if (!systemTags.includes("protected")) {
900
+ systemTags.push("protected");
648
901
  }
649
902
  }
650
903
  if ("template" in attributes) {
651
- if (attributes.template && !wasHardcoded && !systemTags2.includes("template")) {
652
- systemTags2.push("template");
904
+ if (attributes.template && !wasHardcoded && !systemTags.includes("ApplyTemplate") && !systemTags.includes("template")) {
905
+ systemTags.push("ApplyTemplate");
653
906
  } else if (!attributes.template || wasHardcoded) {
654
- systemTags2 = systemTags2.filter((t) => t !== "template");
907
+ systemTags = systemTags.filter((t) => t !== "ApplyTemplate" && t !== "template");
655
908
  }
656
909
  }
657
- finalAttributes.systemTags = systemTags2;
658
910
  } else if (wasHardcoded) {
659
- let systemTags2 = [...finalAttributes.systemTags || []];
660
- if (!systemTags2.includes("protected")) {
661
- systemTags2.push("protected");
911
+ if (!systemTags.includes("protected")) {
912
+ systemTags.push("protected");
662
913
  }
663
- if (!systemTags2.includes("readonly")) {
664
- systemTags2.push("readonly");
914
+ systemTags = systemTags.filter((t) => t !== "LLMWrite");
915
+ if (!systemTags.includes("readonly")) {
916
+ systemTags.push("readonly");
665
917
  }
666
- systemTags2 = systemTags2.filter((t) => t !== "template");
667
- finalAttributes.systemTags = systemTags2;
918
+ systemTags = systemTags.filter((t) => t !== "template");
668
919
  }
669
- let systemTags = finalAttributes.systemTags || [];
670
920
  if (wasHardcoded && !systemTags.includes("protected")) {
671
- systemTags = [...systemTags, "protected"];
921
+ systemTags.push("protected");
672
922
  }
673
923
  if (systemTags.includes("protected")) {
924
+ systemTags = systemTags.filter((t) => t !== "LLMWrite");
674
925
  if (!systemTags.includes("readonly")) {
675
- systemTags = [...systemTags, "readonly"];
926
+ systemTags.push("readonly");
676
927
  }
677
928
  systemTags = systemTags.filter((t) => t !== "template");
678
- finalAttributes.systemTags = systemTags;
679
929
  }
680
- finalAttributes.readonly = systemTags.includes("readonly");
681
- finalAttributes.visible = systemTags.includes("prompt");
930
+ finalAttributes.systemTags = systemTags;
931
+ finalAttributes.readonly = systemTags.includes("readonly") || !systemTags.includes("LLMWrite");
932
+ finalAttributes.visible = this.hasSystemPrompt(systemTags);
682
933
  finalAttributes.hardcoded = wasHardcoded || systemTags.includes("protected");
683
- finalAttributes.template = systemTags.includes("template");
934
+ finalAttributes.template = systemTags.includes("ApplyTemplate") || systemTags.includes("template");
684
935
  if (attributes && "tags" in attributes && attributes.tags) {
685
936
  finalAttributes.contentTags = [...attributes.tags];
686
937
  }
@@ -701,21 +952,25 @@ var MindCache = class {
701
952
  return;
702
953
  }
703
954
  this._isRemoteUpdate = true;
704
- const systemTags = attributes.systemTags || [];
705
- if (!attributes.systemTags) {
955
+ let systemTags = attributes.systemTags || [];
956
+ if (!attributes.systemTags || systemTags.length === 0) {
957
+ systemTags = [];
706
958
  if (attributes.visible !== false) {
707
959
  systemTags.push("prompt");
708
960
  }
709
961
  if (attributes.readonly) {
710
962
  systemTags.push("readonly");
963
+ } else {
964
+ systemTags.push("LLMWrite");
711
965
  }
712
966
  if (attributes.hardcoded) {
713
967
  systemTags.push("protected");
714
968
  }
715
969
  if (attributes.template) {
716
- systemTags.push("template");
970
+ systemTags.push("ApplyTemplate");
717
971
  }
718
972
  }
973
+ systemTags = this.normalizeSystemTags(systemTags);
719
974
  const contentTags = attributes.contentTags || attributes.tags || [];
720
975
  this.stm[key] = {
721
976
  value,
@@ -725,10 +980,11 @@ var MindCache = class {
725
980
  systemTags,
726
981
  zIndex: attributes.zIndex ?? 0,
727
982
  tags: contentTags,
728
- readonly: systemTags.includes("readonly"),
729
- visible: systemTags.includes("prompt"),
983
+ // Sync legacy attributes FROM normalized systemTags
984
+ readonly: systemTags.includes("readonly") || !systemTags.includes("LLMWrite"),
985
+ visible: this.hasSystemPrompt(systemTags),
730
986
  hardcoded: systemTags.includes("protected"),
731
- template: systemTags.includes("template")
987
+ template: systemTags.includes("ApplyTemplate") || systemTags.includes("template")
732
988
  }
733
989
  };
734
990
  if (this.listeners[key]) {
@@ -783,39 +1039,55 @@ var MindCache = class {
783
1039
  }
784
1040
  }
785
1041
  entry.attributes = { ...entry.attributes, ...allowedAttributes };
786
- if ("readonly" in attributes || "visible" in attributes || "template" in attributes) {
787
- let newSystemTags = [];
788
- if (entry.attributes.readonly) {
789
- newSystemTags.push("readonly");
790
- }
791
- if (entry.attributes.visible) {
792
- newSystemTags.push("prompt");
793
- }
794
- if (entry.attributes.template) {
795
- newSystemTags.push("template");
796
- }
797
- if (wasHardcoded || entry.attributes.hardcoded) {
798
- newSystemTags.push("protected");
1042
+ if ("readonly" in attributes || "visible" in attributes || "template" in attributes || "systemTags" in attributes) {
1043
+ let newSystemTags = entry.attributes.systemTags || [];
1044
+ if ("systemTags" in attributes && Array.isArray(attributes.systemTags)) {
1045
+ newSystemTags = this.normalizeSystemTags(attributes.systemTags);
1046
+ } else {
1047
+ newSystemTags = [];
1048
+ if (!entry.attributes.readonly) {
1049
+ newSystemTags.push("LLMWrite");
1050
+ } else {
1051
+ newSystemTags.push("readonly");
1052
+ }
1053
+ if (entry.attributes.visible) {
1054
+ newSystemTags.push("SystemPrompt");
1055
+ }
1056
+ if (entry.attributes.template) {
1057
+ newSystemTags.push("ApplyTemplate");
1058
+ }
1059
+ if (wasHardcoded || entry.attributes.hardcoded) {
1060
+ newSystemTags.push("protected");
1061
+ }
1062
+ newSystemTags = this.normalizeSystemTags(newSystemTags);
799
1063
  }
800
1064
  if (newSystemTags.includes("protected")) {
1065
+ newSystemTags = newSystemTags.filter((t) => t !== "LLMWrite");
801
1066
  if (!newSystemTags.includes("readonly")) {
802
1067
  newSystemTags.push("readonly");
803
1068
  }
804
- newSystemTags = newSystemTags.filter((t) => t !== "template");
1069
+ newSystemTags = newSystemTags.filter((t) => t !== "ApplyTemplate" && t !== "template");
805
1070
  entry.attributes.readonly = true;
806
1071
  entry.attributes.template = false;
807
1072
  }
808
1073
  entry.attributes.systemTags = newSystemTags;
1074
+ entry.attributes.readonly = newSystemTags.includes("readonly") || !newSystemTags.includes("LLMWrite");
1075
+ entry.attributes.visible = this.hasSystemPrompt(newSystemTags);
1076
+ entry.attributes.template = newSystemTags.includes("ApplyTemplate") || newSystemTags.includes("template");
809
1077
  } else if (wasHardcoded) {
810
- let systemTags = [...entry.attributes.systemTags || []];
1078
+ let systemTags = this.normalizeSystemTags(entry.attributes.systemTags || []);
811
1079
  if (!systemTags.includes("protected")) {
812
1080
  systemTags.push("protected");
813
1081
  }
1082
+ systemTags = systemTags.filter((t) => t !== "LLMWrite");
814
1083
  if (!systemTags.includes("readonly")) {
815
1084
  systemTags.push("readonly");
816
1085
  }
817
- systemTags = systemTags.filter((t) => t !== "template");
1086
+ systemTags = systemTags.filter((t) => t !== "ApplyTemplate" && t !== "template");
818
1087
  entry.attributes.systemTags = systemTags;
1088
+ entry.attributes.readonly = true;
1089
+ entry.attributes.visible = this.hasSystemPrompt(systemTags);
1090
+ entry.attributes.template = false;
819
1091
  }
820
1092
  if (wasHardcoded) {
821
1093
  entry.attributes.hardcoded = true;
@@ -1057,8 +1329,9 @@ var MindCache = class {
1057
1329
  const sortedKeys = this.getSortedKeys();
1058
1330
  sortedKeys.forEach((key) => {
1059
1331
  const entry = this.stm[key];
1060
- if (entry.attributes.visible) {
1061
- const processedValue = entry.attributes.template ? this.get_value(key) : entry.value;
1332
+ if (this.hasLLMRead(entry.attributes.systemTags) || entry.attributes.visible) {
1333
+ const hasTemplate = entry.attributes.systemTags?.includes("ApplyTemplate") || entry.attributes.systemTags?.includes("template") || entry.attributes.template;
1334
+ const processedValue = hasTemplate ? this.get_value(key) : entry.value;
1062
1335
  apiData.push({
1063
1336
  key,
1064
1337
  value: processedValue,
@@ -1084,7 +1357,7 @@ var MindCache = class {
1084
1357
  const sortedKeys = this.getSortedKeys();
1085
1358
  sortedKeys.forEach((key) => {
1086
1359
  const entry = this.stm[key];
1087
- if (entry.attributes.visible && entry.attributes.type === "image" && entry.attributes.contentType) {
1360
+ if ((this.hasLLMRead(entry.attributes.systemTags) || entry.attributes.visible) && entry.attributes.type === "image" && entry.attributes.contentType) {
1088
1361
  const dataUrl = this.createDataUrl(entry.value, entry.attributes.contentType);
1089
1362
  imageParts.push({
1090
1363
  type: "file",
@@ -1123,6 +1396,7 @@ var MindCache = class {
1123
1396
  }
1124
1397
  deserialize(data) {
1125
1398
  if (typeof data === "object" && data !== null) {
1399
+ this._isRemoteUpdate = true;
1126
1400
  this.clear();
1127
1401
  Object.entries(data).forEach(([key, entry]) => {
1128
1402
  if (entry && typeof entry === "object" && "value" in entry && "attributes" in entry) {
@@ -1131,21 +1405,24 @@ var MindCache = class {
1131
1405
  return;
1132
1406
  }
1133
1407
  let systemTags = attrs.systemTags || [];
1134
- if (!attrs.systemTags) {
1408
+ if (!attrs.systemTags || systemTags.length === 0) {
1135
1409
  systemTags = [];
1136
1410
  if (attrs.visible !== false) {
1137
1411
  systemTags.push("prompt");
1138
1412
  }
1139
1413
  if (attrs.readonly) {
1140
1414
  systemTags.push("readonly");
1415
+ } else {
1416
+ systemTags.push("LLMWrite");
1141
1417
  }
1142
1418
  if (attrs.hardcoded) {
1143
1419
  systemTags.push("protected");
1144
1420
  }
1145
1421
  if (attrs.template) {
1146
- systemTags.push("template");
1422
+ systemTags.push("ApplyTemplate");
1147
1423
  }
1148
1424
  }
1425
+ systemTags = this.normalizeSystemTags(systemTags);
1149
1426
  const contentTags = attrs.contentTags || attrs.tags || [];
1150
1427
  this.stm[key] = {
1151
1428
  value: entry.value,
@@ -1154,17 +1431,18 @@ var MindCache = class {
1154
1431
  contentTags,
1155
1432
  systemTags,
1156
1433
  zIndex: attrs.zIndex ?? 0,
1157
- // Sync legacy attributes
1434
+ // Sync legacy attributes FROM normalized systemTags
1158
1435
  tags: contentTags,
1159
- readonly: systemTags.includes("readonly"),
1160
- visible: systemTags.includes("prompt"),
1436
+ readonly: systemTags.includes("readonly") || !systemTags.includes("LLMWrite"),
1437
+ visible: this.hasSystemPrompt(systemTags),
1161
1438
  hardcoded: systemTags.includes("protected"),
1162
- template: systemTags.includes("template")
1439
+ template: systemTags.includes("ApplyTemplate") || systemTags.includes("template")
1163
1440
  }
1164
1441
  };
1165
1442
  }
1166
1443
  });
1167
1444
  this.notifyGlobalListeners();
1445
+ this._isRemoteUpdate = false;
1168
1446
  }
1169
1447
  }
1170
1448
  get_system_prompt() {
@@ -1173,13 +1451,14 @@ var MindCache = class {
1173
1451
  const sortedKeys = this.getSortedKeys();
1174
1452
  sortedKeys.forEach((key) => {
1175
1453
  const entry = this.stm[key];
1176
- if (entry.attributes.visible) {
1454
+ if (this.hasLLMRead(entry.attributes.systemTags) || entry.attributes.visible) {
1177
1455
  if (entry.attributes.type === "image") {
1178
1456
  promptLines.push(`image ${key} available`);
1179
1457
  return;
1180
1458
  }
1181
1459
  if (entry.attributes.type === "file") {
1182
- if (entry.attributes.readonly) {
1460
+ const canWrite2 = this.hasLLMWrite(entry.attributes.systemTags) || !entry.attributes.readonly && !entry.attributes.systemTags.includes("readonly");
1461
+ if (!canWrite2) {
1183
1462
  promptLines.push(`${key}: [${entry.attributes.type.toUpperCase()}] - ${entry.attributes.contentType || "unknown format"}`);
1184
1463
  } else {
1185
1464
  const sanitizedKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
@@ -1189,7 +1468,8 @@ var MindCache = class {
1189
1468
  }
1190
1469
  const value = this.get_value(key);
1191
1470
  const formattedValue = typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
1192
- if (entry.attributes.readonly) {
1471
+ const canWrite = this.hasLLMWrite(entry.attributes.systemTags) || !entry.attributes.readonly && !entry.attributes.systemTags.includes("readonly");
1472
+ if (!canWrite) {
1193
1473
  promptLines.push(`${key}: ${formattedValue}`);
1194
1474
  } else {
1195
1475
  const sanitizedKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
@@ -1217,7 +1497,7 @@ var MindCache = class {
1217
1497
  const sortedKeys = this.getSortedKeys();
1218
1498
  const writableKeys = sortedKeys.filter((key) => {
1219
1499
  const entry = this.stm[key];
1220
- return !entry.attributes.readonly;
1500
+ return this.hasLLMWrite(entry.attributes.systemTags) || !entry.attributes.readonly && !entry.attributes.systemTags.includes("readonly");
1221
1501
  });
1222
1502
  writableKeys.forEach((key) => {
1223
1503
  const sanitizedKey = key.replace(/[^a-zA-Z0-9_-]/g, "_");
@@ -1292,7 +1572,8 @@ var MindCache = class {
1292
1572
  return null;
1293
1573
  }
1294
1574
  const entry = this.stm[originalKey];
1295
- if (entry && entry.attributes.readonly) {
1575
+ const canWrite = entry && (this.hasLLMWrite(entry.attributes.systemTags) || !entry.attributes.readonly && !entry.attributes.systemTags.includes("readonly"));
1576
+ if (!canWrite) {
1296
1577
  return null;
1297
1578
  }
1298
1579
  this.set_value(originalKey, value);
@@ -1539,7 +1820,7 @@ var MindCache = class {
1539
1820
  entry.attributes.readonly = tags.includes("readonly");
1540
1821
  entry.attributes.visible = tags.includes("prompt");
1541
1822
  entry.attributes.hardcoded = tags.includes("protected");
1542
- entry.attributes.template = tags.includes("template");
1823
+ entry.attributes.template = tags.includes("ApplyTemplate") || tags.includes("template");
1543
1824
  }
1544
1825
  toMarkdown() {
1545
1826
  const now = /* @__PURE__ */ new Date();
@@ -1780,6 +2061,8 @@ var MindCache = class {
1780
2061
  }
1781
2062
  if (attrs.readonly) {
1782
2063
  systemTags.push("readonly");
2064
+ } else {
2065
+ systemTags.push("LLMWrite");
1783
2066
  }
1784
2067
  if (attrs.hardcoded) {
1785
2068
  systemTags.push("protected");
@@ -1787,7 +2070,9 @@ var MindCache = class {
1787
2070
  if (attrs.template) {
1788
2071
  systemTags.push("template");
1789
2072
  }
1790
- attrs.systemTags = systemTags;
2073
+ attrs.systemTags = this.normalizeSystemTags(systemTags);
2074
+ } else {
2075
+ attrs.systemTags = this.normalizeSystemTags(attrs.systemTags);
1791
2076
  }
1792
2077
  if (!attrs.contentTags) {
1793
2078
  attrs.contentTags = [];
@@ -1795,6 +2080,11 @@ var MindCache = class {
1795
2080
  if (!attrs.tags) {
1796
2081
  attrs.tags = [...attrs.contentTags];
1797
2082
  }
2083
+ const normalizedTags = attrs.systemTags || [];
2084
+ attrs.readonly = normalizedTags.includes("readonly") || !normalizedTags.includes("LLMWrite");
2085
+ attrs.visible = this.hasSystemPrompt(normalizedTags);
2086
+ attrs.hardcoded = normalizedTags.includes("protected");
2087
+ attrs.template = normalizedTags.includes("ApplyTemplate") || normalizedTags.includes("template");
1798
2088
  this.stm[key] = {
1799
2089
  value: entry.value,
1800
2090
  attributes: attrs
@@ -1810,6 +2100,43 @@ var mindcache = new MindCache();
1810
2100
  init_CloudAdapter();
1811
2101
  init_CloudAdapter();
1812
2102
 
1813
- export { CloudAdapter, DEFAULT_KEY_ATTRIBUTES, MindCache, mindcache };
2103
+ // src/local/index.ts
2104
+ init_IndexedDBAdapter();
2105
+ function useMindCache(options) {
2106
+ const [isLoaded, setIsLoaded] = useState(false);
2107
+ const [error, setError] = useState(null);
2108
+ const mindcacheRef = useRef(null);
2109
+ const initializingRef = useRef(false);
2110
+ useEffect(() => {
2111
+ if (initializingRef.current) {
2112
+ return;
2113
+ }
2114
+ initializingRef.current = true;
2115
+ const initialize = async () => {
2116
+ try {
2117
+ const mc = new MindCache(options);
2118
+ mindcacheRef.current = mc;
2119
+ await mc.waitForSync();
2120
+ setIsLoaded(true);
2121
+ } catch (err) {
2122
+ setError(err instanceof Error ? err : new Error(String(err)));
2123
+ setIsLoaded(true);
2124
+ }
2125
+ };
2126
+ initialize();
2127
+ return () => {
2128
+ if (mindcacheRef.current) {
2129
+ mindcacheRef.current.disconnect();
2130
+ }
2131
+ };
2132
+ }, []);
2133
+ return {
2134
+ mindcache: mindcacheRef.current,
2135
+ isLoaded,
2136
+ error
2137
+ };
2138
+ }
2139
+
2140
+ export { CloudAdapter, DEFAULT_KEY_ATTRIBUTES, IndexedDBAdapter, MindCache, mindcache, useMindCache };
1814
2141
  //# sourceMappingURL=index.mjs.map
1815
2142
  //# sourceMappingURL=index.mjs.map