@burtson-labs/bandit-engine 2.0.50 → 2.0.52

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.
Files changed (37) hide show
  1. package/dist/{chat-CQWZOJH4.mjs → chat-YWYLVKXX.mjs} +5 -5
  2. package/dist/chat-provider.js +254 -22
  3. package/dist/chat-provider.js.map +1 -1
  4. package/dist/chat-provider.mjs +3 -3
  5. package/dist/{chunk-VL3CMSDO.mjs → chunk-37PEP5JK.mjs} +2 -2
  6. package/dist/{chunk-AXFX2HUK.mjs → chunk-M3BEAMCC.mjs} +2 -2
  7. package/dist/{chunk-HKJTRBWC.mjs → chunk-MH7WFWCP.mjs} +34 -3
  8. package/dist/chunk-MH7WFWCP.mjs.map +1 -0
  9. package/dist/{chunk-6WZUQHZT.mjs → chunk-QX6CO7TJ.mjs} +225 -23
  10. package/dist/chunk-QX6CO7TJ.mjs.map +1 -0
  11. package/dist/{chunk-TVF45U7B.mjs → chunk-RSSJADDD.mjs} +3 -3
  12. package/dist/{chunk-Q2N7CCZI.mjs → chunk-TSQCNHOX.mjs} +45 -6
  13. package/dist/chunk-TSQCNHOX.mjs.map +1 -0
  14. package/dist/{chunk-ZTTGERUG.mjs → chunk-Y5N3NSTU.mjs} +459 -180
  15. package/dist/chunk-Y5N3NSTU.mjs.map +1 -0
  16. package/dist/{chunk-KHKWYHXD.mjs → chunk-YZ2HJFPQ.mjs} +2 -2
  17. package/dist/cli.js +1 -1
  18. package/dist/cli.js.map +1 -1
  19. package/dist/index.js +747 -198
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +8 -8
  22. package/dist/management/management.js +717 -198
  23. package/dist/management/management.js.map +1 -1
  24. package/dist/management/management.mjs +6 -6
  25. package/dist/modals/chat-modal/chat-modal.js +226 -22
  26. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  27. package/dist/modals/chat-modal/chat-modal.mjs +3 -3
  28. package/package.json +1 -1
  29. package/dist/chunk-6WZUQHZT.mjs.map +0 -1
  30. package/dist/chunk-HKJTRBWC.mjs.map +0 -1
  31. package/dist/chunk-Q2N7CCZI.mjs.map +0 -1
  32. package/dist/chunk-ZTTGERUG.mjs.map +0 -1
  33. /package/dist/{chat-CQWZOJH4.mjs.map → chat-YWYLVKXX.mjs.map} +0 -0
  34. /package/dist/{chunk-VL3CMSDO.mjs.map → chunk-37PEP5JK.mjs.map} +0 -0
  35. /package/dist/{chunk-AXFX2HUK.mjs.map → chunk-M3BEAMCC.mjs.map} +0 -0
  36. /package/dist/{chunk-TVF45U7B.mjs.map → chunk-RSSJADDD.mjs.map} +0 -0
  37. /package/dist/{chunk-KHKWYHXD.mjs.map → chunk-YZ2HJFPQ.mjs.map} +0 -0
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ChatProvider,
3
3
  chat_provider_default
4
- } from "./chunk-HKJTRBWC.mjs";
4
+ } from "./chunk-MH7WFWCP.mjs";
5
5
  import "./chunk-ONQMRE2G.mjs";
6
- import "./chunk-VL3CMSDO.mjs";
6
+ import "./chunk-37PEP5JK.mjs";
7
7
  import "./chunk-EHNWQ4T3.mjs";
8
- import "./chunk-6WZUQHZT.mjs";
8
+ import "./chunk-QX6CO7TJ.mjs";
9
9
  import "./chunk-7ZDS33S2.mjs";
10
10
  import "./chunk-BENL3EF2.mjs";
11
11
  import "./chunk-KCI46M23.mjs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  authenticationService
3
- } from "./chunk-6WZUQHZT.mjs";
3
+ } from "./chunk-QX6CO7TJ.mjs";
4
4
  import {
5
5
  indexedDBService_default,
6
6
  usePackageSettingsStore
@@ -287,4 +287,4 @@ var aiProviderInitService = AIProviderInitService.getInstance();
287
287
  export {
288
288
  aiProviderInitService
289
289
  };
290
- //# sourceMappingURL=chunk-VL3CMSDO.mjs.map
290
+ //# sourceMappingURL=chunk-37PEP5JK.mjs.map
@@ -8,7 +8,7 @@ import {
8
8
  useMemoryStore,
9
9
  useNotification,
10
10
  useVectorStore
11
- } from "./chunk-6WZUQHZT.mjs";
11
+ } from "./chunk-QX6CO7TJ.mjs";
12
12
  import {
13
13
  useModelStore,
14
14
  usePackageSettingsStore,
@@ -8922,4 +8922,4 @@ export {
8922
8922
  FeedbackButton,
8923
8923
  useNotificationService
8924
8924
  };
8925
- //# sourceMappingURL=chunk-AXFX2HUK.mjs.map
8925
+ //# sourceMappingURL=chunk-M3BEAMCC.mjs.map
@@ -3,11 +3,12 @@ import {
3
3
  } from "./chunk-ONQMRE2G.mjs";
4
4
  import {
5
5
  aiProviderInitService
6
- } from "./chunk-VL3CMSDO.mjs";
6
+ } from "./chunk-37PEP5JK.mjs";
7
7
  import {
8
8
  useMCPToolsStore
9
9
  } from "./chunk-EHNWQ4T3.mjs";
10
10
  import {
11
+ AUTH_TOKEN_CHANGED_EVENT,
11
12
  FeatureFlagProvider,
12
13
  NotificationProvider,
13
14
  authenticationService,
@@ -20,7 +21,7 @@ import {
20
21
  useKnowledgeStore2,
21
22
  useMemoryStore,
22
23
  useProjectStore
23
- } from "./chunk-6WZUQHZT.mjs";
24
+ } from "./chunk-QX6CO7TJ.mjs";
24
25
  import {
25
26
  indexedDBService_default,
26
27
  useModelStore,
@@ -149,6 +150,36 @@ var ChatProvider = (props) => {
149
150
  };
150
151
  initializeAsync();
151
152
  }, [props.packageSettings, loadDocuments]);
153
+ useEffect(() => {
154
+ const isPlaygroundRoute = typeof window !== "undefined" && window.location.pathname.includes("/playground");
155
+ const isPlaygroundMode = isPlaygroundRoute || props.packageSettings.playgroundMode === true;
156
+ if (isPlaygroundMode || !props.packageSettings.gatewayApiUrl) {
157
+ return;
158
+ }
159
+ const initializeSyncState = async () => {
160
+ try {
161
+ await useConversationSyncStore.getState().initialize();
162
+ } catch (error) {
163
+ debugLogger.error("ChatProvider: deferred sync initialization failed", {
164
+ error: error instanceof Error ? error.message : String(error)
165
+ });
166
+ }
167
+ };
168
+ if (typeof window === "undefined") {
169
+ return;
170
+ }
171
+ const handleAuthTokenChange = () => {
172
+ void initializeSyncState();
173
+ };
174
+ window.addEventListener(AUTH_TOKEN_CHANGED_EVENT, handleAuthTokenChange);
175
+ window.addEventListener("pageshow", handleAuthTokenChange);
176
+ window.addEventListener("focus", handleAuthTokenChange);
177
+ return () => {
178
+ window.removeEventListener(AUTH_TOKEN_CHANGED_EVENT, handleAuthTokenChange);
179
+ window.removeEventListener("pageshow", handleAuthTokenChange);
180
+ window.removeEventListener("focus", handleAuthTokenChange);
181
+ };
182
+ }, [props.packageSettings.gatewayApiUrl, props.packageSettings.playgroundMode]);
152
183
  return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(FeatureFlagProvider, { config: featureFlagConfig, children: /* @__PURE__ */ jsx(NotificationProvider, { children: props.children }) }) });
153
184
  };
154
185
  var chat_provider_default = ChatProvider;
@@ -157,4 +188,4 @@ export {
157
188
  ChatProvider,
158
189
  chat_provider_default
159
190
  };
160
- //# sourceMappingURL=chunk-HKJTRBWC.mjs.map
191
+ //# sourceMappingURL=chunk-MH7WFWCP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chat-provider.tsx","../src/chat-provider.css"],"sourcesContent":["/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-9A05-FB9C98\nconst __banditFingerprint_chatprovidertsx = 'BL-FP-E60286-2996';\nconst __auditTrail_chatprovidertsx = 'BL-AU-MGOIKVV6-O6E4';\n// File: chat-provider.tsx | Path: src/chat-provider.tsx | Hash: 9a052996\n\nimport React, { useEffect, useState } from \"react\";\nimport { PackageSettings, usePackageSettingsStore } from \"./store/packageSettingsStore\";\nimport { AUTH_TOKEN_CHANGED_EVENT, authenticationService } from \"./services/auth/authenticationService\";\nimport { useConversationStore } from \"./store/conversationStore\";\nimport { useAIQueryStore } from \"./store/aiQueryStore\";\nimport { useMemoryStore } from \"./store/memoryStore\";\nimport { useModelStore } from \"./store/modelStore\";\nimport { usePreferencesStore } from \"./store/preferencesStore\";\nimport { useProjectStore } from \"./store/projectStore\";\nimport { useConversationSyncStore } from \"./store/conversationSyncStore\";\nimport { useKnowledgeStore } from \"./store/knowledgeStore\";\nimport { useMCPToolsStore } from \"./store/mcpToolsStore\";\nimport { useKnowledgeStore as useKnowledgeHook } from \"./chat/hooks/useKnowledgeStore\";\nimport { embeddingService } from \"./services/embedding/embeddingService\";\nimport { aiProviderInitService } from \"./services/ai-provider-init.service\";\nimport brandingService, { BrandingConfigPayload } from \"./services/branding/brandingService\";\nimport indexedDBService from \"./services/indexedDB/indexedDBService\";\nimport { debugLogger } from \"./services/logging/debugLogger\";\nimport { NotificationProvider } from \"./shared/components/NotificationProvider\";\nimport { FeatureFlagProvider } from \"./contexts/FeatureFlagContext\";\nimport { FeatureFlagConfig } from \"./types/featureFlags\";\nimport \"./chat-provider.css\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { StoredBanditConfigRecord } from \"./types/config\";\n\nexport interface ChatConfig {\n packageSettings: PackageSettings;\n /** Feature flag configuration - can override packageSettings.featureFlags */\n featureFlags?: FeatureFlagConfig;\n children?: React.ReactNode;\n}\n\nexport const ChatProvider: React.FC<ChatConfig> = (props) => {\n const { loadDocuments } = useKnowledgeHook();\n const [queryClient] = useState(() => new QueryClient());\n\n // Determine final feature flag configuration\n const featureFlagConfig: FeatureFlagConfig = {\n ...props.packageSettings.featureFlags,\n ...props.featureFlags\n };\n\n useEffect(() => {\n const initializeAsync = async () => {\n // Set package settings first\n usePackageSettingsStore.setState(() => ({\n settings: props.packageSettings,\n }));\n\n // Initialize the new AI provider system early\n try {\n await aiProviderInitService.initializeFromSettings();\n } catch (error) {\n debugLogger.error(\"Failed to initialize AI provider:\", { error });\n }\n\n const token = authenticationService.getToken();\n if (token && !authenticationService.isTokenExpired(token)) {\n authenticationService.setToken(token);\n } else {\n authenticationService.clearToken();\n }\n\n useConversationStore.getState().hydrate();\n useProjectStore.getState().hydrate();\n useAIQueryStore.getState().hydrate();\n useMemoryStore.getState().hydrate();\n \n const isPlaygroundRoute = typeof window !== \"undefined\" && window.location.pathname.includes(\"/playground\");\n const isPlaygroundMode = isPlaygroundRoute || props.packageSettings.playgroundMode === true;\n\n if (isPlaygroundMode) {\n debugLogger.info(\"ChatProvider: Playground mode detected — skipping remote preference and sync initialization\");\n } else {\n // Load preferences, knowledge docs, and MCP tools\n await usePreferencesStore.getState().loadPreferences();\n await useKnowledgeStore.getState().loadDocs();\n await useMCPToolsStore.getState().loadTools();\n await useConversationSyncStore.getState().initialize();\n }\n \n // Initialize models after AI provider is set up\n debugLogger.info(\"ChatProvider about to call initModels - checking for existing branding first\");\n \n // Get existing branding before initModels to protect user-saved branding\n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }] as const;\n let existingBranding: StoredBanditConfigRecord[\"branding\"] | null = null;\n try {\n const config = await indexedDBService.get<StoredBanditConfigRecord>(\n \"banditConfig\",\n 1,\n \"config\",\n \"main\",\n storeConfigs\n );\n if (config?.branding?.userSaved) {\n existingBranding = config.branding;\n debugLogger.info(\"Found user-saved branding to protect during initModels\", {\n hasText: !!existingBranding.brandingText,\n hasLogo: !!existingBranding.logoBase64,\n theme: existingBranding.theme\n });\n }\n } catch (err) {\n debugLogger.warn(\"Could not check existing branding before initModels\", { error: err });\n }\n \n await useModelStore.getState().initModels().catch((err) => {\n debugLogger.error(\"❌ Failed to initialize models:\", { error: err });\n });\n \n // Restore user branding if it was overwritten\n if (existingBranding) {\n try {\n const afterInitModels = await indexedDBService.get<StoredBanditConfigRecord>(\n \"banditConfig\",\n 1,\n \"config\",\n \"main\",\n storeConfigs\n );\n if (JSON.stringify(afterInitModels?.branding) !== JSON.stringify(existingBranding)) {\n debugLogger.warn(\"ChatProvider: initModels overwrote user branding! Restoring...\");\n await indexedDBService.put<StoredBanditConfigRecord>(\"banditConfig\", 1, \"config\", {\n ...afterInitModels,\n id: \"main\",\n branding: existingBranding,\n }, storeConfigs);\n debugLogger.info(\"ChatProvider: User branding restored after initModels\");\n }\n } catch (err) {\n debugLogger.error(\"ChatProvider: Failed to restore branding after initModels\", { error: err });\n }\n }\n\n if (props.packageSettings.brandingConfigUrl) {\n fetch(props.packageSettings.brandingConfigUrl)\n .then((res) => {\n if (!res.ok) {\n throw new Error(`HTTP error ${res.status}`);\n }\n return res.json();\n })\n .then((json: unknown) => {\n if (json && typeof json === \"object\") {\n brandingService.setBrandingFromConfig(json as BrandingConfigPayload);\n }\n })\n .catch((err) => {\n debugLogger.error(\"❌ Failed to fetch or apply branding config:\", { error: err });\n });\n }\n\n if (!isPlaygroundMode) {\n loadDocuments();\n embeddingService.backfillMissingEmbeddings().catch((err: unknown) => {\n debugLogger.error(\"❌ Failed to backfill memory embeddings:\", { error: err });\n });\n } else {\n debugLogger.info(\"ChatProvider: Playground mode skipping knowledge backfill\");\n }\n };\n\n initializeAsync();\n }, [props.packageSettings, loadDocuments]);\n\n useEffect(() => {\n const isPlaygroundRoute = typeof window !== \"undefined\" && window.location.pathname.includes(\"/playground\");\n const isPlaygroundMode = isPlaygroundRoute || props.packageSettings.playgroundMode === true;\n\n if (isPlaygroundMode || !props.packageSettings.gatewayApiUrl) {\n return;\n }\n\n const initializeSyncState = async () => {\n try {\n await useConversationSyncStore.getState().initialize();\n } catch (error) {\n debugLogger.error(\"ChatProvider: deferred sync initialization failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n };\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleAuthTokenChange = () => {\n void initializeSyncState();\n };\n\n window.addEventListener(AUTH_TOKEN_CHANGED_EVENT, handleAuthTokenChange);\n window.addEventListener(\"pageshow\", handleAuthTokenChange);\n window.addEventListener(\"focus\", handleAuthTokenChange);\n\n return () => {\n window.removeEventListener(AUTH_TOKEN_CHANGED_EVENT, handleAuthTokenChange);\n window.removeEventListener(\"pageshow\", handleAuthTokenChange);\n window.removeEventListener(\"focus\", handleAuthTokenChange);\n };\n }, [props.packageSettings.gatewayApiUrl, props.packageSettings.playgroundMode]);\n\n return (\n <QueryClientProvider client={queryClient}>\n <FeatureFlagProvider config={featureFlagConfig}>\n <NotificationProvider>\n {props.children}\n </NotificationProvider>\n </FeatureFlagProvider>\n </QueryClientProvider>\n );\n};\n\nexport default ChatProvider;\n","import styleInject from '#style-inject';styleInject(\"*,\\n*::before,\\n*::after {\\n box-sizing: border-box;\\n margin: 0;\\n padding: 0;\\n}\\n:root {\\n --vh: 1vh;\\n --input-offset: 1.5rem;\\n}\\nhtml {\\n height: 100%;\\n overflow: hidden;\\n scrollbar-width: none;\\n -ms-overflow-style: none;\\n}\\nhtml::-webkit-scrollbar {\\n display: none;\\n}\\nbody {\\n height: 100%;\\n overflow: auto;\\n scrollbar-width: none;\\n -ms-overflow-style: none;\\n}\\nbody::-webkit-scrollbar {\\n display: none;\\n}\\na {\\n color: inherit;\\n text-decoration: none;\\n}\\n.container {\\n max-width: 1200px;\\n margin: 0 auto;\\n padding: 2rem;\\n}\\n.mt-2 {\\n margin-top: 0.5rem;\\n}\\n.mb-2 {\\n margin-bottom: 0.5rem;\\n}\\n.mx-auto {\\n margin-left: auto;\\n margin-right: auto;\\n}\\n.bandit-logo-container {\\n display: flex;\\n height: 50vh;\\n margin: auto;\\n}\\n.bandit-logo {\\n margin: auto;\\n display: flex;\\n flex: 1 1 auto;\\n flex-direction: column;\\n align-items: center;\\n width: 90vw;\\n max-width: 640px;\\n height: 55vh;\\n background-size: cover;\\n background-position: center center;\\n background-repeat: no-repeat;\\n transition: opacity 0.6s ease-in-out, transform 0.6s ease-in-out;\\n}\\n.bandit-logo-hidden {\\n opacity: 0;\\n transform: translateY(-10px);\\n pointer-events: none;\\n}\\n.bandit-logo-visible {\\n opacity: 1;\\n transform: translateY(0);\\n}\\n\")"],"mappings":"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","names":["useKnowledgeStore"]}
@@ -63,6 +63,15 @@ var useAuthenticationStore = create((set) => ({
63
63
 
64
64
  // src/services/auth/authenticationService.ts
65
65
  var TOKEN_KEY2 = "authToken";
66
+ var AUTH_TOKEN_CHANGED_EVENT = "bandit:auth-token-changed";
67
+ function emitAuthTokenChanged(token) {
68
+ if (typeof window === "undefined") {
69
+ return;
70
+ }
71
+ window.dispatchEvent(new CustomEvent(AUTH_TOKEN_CHANGED_EVENT, {
72
+ detail: { token }
73
+ }));
74
+ }
66
75
  var AuthenticationService = class {
67
76
  getToken() {
68
77
  const token = localStorage.getItem(TOKEN_KEY2);
@@ -71,10 +80,12 @@ var AuthenticationService = class {
71
80
  setToken(token) {
72
81
  localStorage.setItem(TOKEN_KEY2, token);
73
82
  useAuthenticationStore.getState().setToken(token);
83
+ emitAuthTokenChanged(token);
74
84
  }
75
85
  clearToken() {
76
86
  localStorage.removeItem(TOKEN_KEY2);
77
87
  useAuthenticationStore.getState().clearToken();
88
+ emitAuthTokenChanged(null);
78
89
  }
79
90
  isAuthenticated() {
80
91
  const token = useAuthenticationStore.getState().token;
@@ -119,7 +130,18 @@ async function saveStateToDB(state) {
119
130
  await indexedDBService_default.put(DB_NAME, DB_VERSION, STORE_NAME, state, storeConfigs, STORAGE_KEY);
120
131
  }
121
132
  async function loadStateFromDB() {
122
- return indexedDBService_default.get(DB_NAME, DB_VERSION, STORE_NAME, STORAGE_KEY, storeConfigs);
133
+ let timeoutId;
134
+ const timeoutPromise = new Promise((resolve) => {
135
+ timeoutId = window.setTimeout(() => resolve(void 0), 1200);
136
+ });
137
+ try {
138
+ const getPromise = indexedDBService_default.get(DB_NAME, DB_VERSION, STORE_NAME, STORAGE_KEY, storeConfigs).catch(() => void 0);
139
+ return await Promise.race([getPromise, timeoutPromise]);
140
+ } finally {
141
+ if (timeoutId !== void 0) {
142
+ window.clearTimeout(timeoutId);
143
+ }
144
+ }
123
145
  }
124
146
  var useAIQueryStore = create2((set, get) => ({
125
147
  inputValue: "",
@@ -175,19 +197,23 @@ var useAIQueryStore = create2((set, get) => ({
175
197
  saveStateToDB(resetState);
176
198
  },
177
199
  hydrate: async () => {
178
- const storedState = await loadStateFromDB();
179
- if (storedState) {
180
- set({
181
- inputValue: storedState.inputValue ?? "",
182
- response: storedState.response ?? "",
183
- previousQuestion: storedState.previousQuestion ?? "",
184
- position: storedState.position ?? { x: window.innerWidth / 2 - 300, y: window.innerHeight - 350 },
185
- componentStatus: "Idle",
186
- history: storedState.history ?? [],
187
- apiKey: storedState.apiKey ?? "",
188
- hydrated: true
189
- });
190
- } else {
200
+ try {
201
+ const storedState = await loadStateFromDB();
202
+ if (storedState) {
203
+ set({
204
+ inputValue: storedState.inputValue ?? "",
205
+ response: storedState.response ?? "",
206
+ previousQuestion: storedState.previousQuestion ?? "",
207
+ position: storedState.position ?? { x: window.innerWidth / 2 - 300, y: window.innerHeight - 350 },
208
+ componentStatus: "Idle",
209
+ history: storedState.history ?? [],
210
+ apiKey: storedState.apiKey ?? "",
211
+ hydrated: true
212
+ });
213
+ } else {
214
+ set({ hydrated: true });
215
+ }
216
+ } catch {
191
217
  set({ hydrated: true });
192
218
  }
193
219
  }
@@ -1061,9 +1087,14 @@ async function syncConversations(request) {
1061
1087
 
1062
1088
  // src/store/conversationSyncStore.ts
1063
1089
  var DEVICE_STORAGE_KEY = "banditConversationDeviceId";
1090
+ var SYNC_IDENTITY_STORAGE_KEY = "banditConversationSyncIdentity";
1064
1091
  var PAYLOAD_VERSION = 1;
1065
1092
  var MAX_CONVERSATION_BYTES = 12 * 1024 * 1024;
1066
1093
  var WARN_CONVERSATION_BYTES = 10 * 1024 * 1024;
1094
+ var PROJECT_DB_NAME = "bandit-projects";
1095
+ var PROJECT_DB_VERSION = 1;
1096
+ var PROJECT_STORE_NAME = "projects";
1097
+ var PROJECT_STORE_CONFIGS = [{ name: PROJECT_STORE_NAME, keyPath: "id" }];
1067
1098
  var suppressTracking = false;
1068
1099
  var conversationsMeta = /* @__PURE__ */ new Map();
1069
1100
  var projectsMeta = /* @__PURE__ */ new Map();
@@ -1088,9 +1119,99 @@ function ensureDeviceId() {
1088
1119
  return uuidv43();
1089
1120
  }
1090
1121
  }
1122
+ function getStoredSyncIdentity() {
1123
+ if (typeof window === "undefined") {
1124
+ return null;
1125
+ }
1126
+ try {
1127
+ return window.localStorage.getItem(SYNC_IDENTITY_STORAGE_KEY);
1128
+ } catch (error) {
1129
+ debugLogger.warn("conversationSyncStore: unable to read stored sync identity", { error });
1130
+ return null;
1131
+ }
1132
+ }
1133
+ function setStoredSyncIdentity(identity) {
1134
+ if (typeof window === "undefined") {
1135
+ return;
1136
+ }
1137
+ try {
1138
+ if (identity) {
1139
+ window.localStorage.setItem(SYNC_IDENTITY_STORAGE_KEY, identity);
1140
+ } else {
1141
+ window.localStorage.removeItem(SYNC_IDENTITY_STORAGE_KEY);
1142
+ }
1143
+ } catch (error) {
1144
+ debugLogger.warn("conversationSyncStore: unable to persist sync identity", { error });
1145
+ }
1146
+ }
1091
1147
  function getPackageDefaultAdvancedKnowledgeSync() {
1092
1148
  return usePackageSettingsStore.getState().settings?.advancedKnowledgeSyncDefaultEnabled;
1093
1149
  }
1150
+ function clearAutoSyncTimer() {
1151
+ if (autoSyncTimeout) {
1152
+ clearTimeout(autoSyncTimeout);
1153
+ autoSyncTimeout = null;
1154
+ }
1155
+ }
1156
+ function resolveAuthIdentity(token) {
1157
+ if (!token) {
1158
+ return null;
1159
+ }
1160
+ const claims = authenticationService.parseJwtClaims(token);
1161
+ if (claims?.sub) {
1162
+ return claims.sub;
1163
+ }
1164
+ if (claims?.email) {
1165
+ return `email:${claims.email.toLowerCase()}`;
1166
+ }
1167
+ return `token:${token.slice(0, 32)}`;
1168
+ }
1169
+ function buildQueueResetState() {
1170
+ return {
1171
+ pendingConversationUpserts: /* @__PURE__ */ new Set(),
1172
+ pendingConversationDeletes: /* @__PURE__ */ new Set(),
1173
+ pendingProjectUpserts: /* @__PURE__ */ new Set(),
1174
+ pendingProjectDeletes: /* @__PURE__ */ new Set(),
1175
+ conflicts: null,
1176
+ lastSyncAt: null,
1177
+ cursor: null,
1178
+ lastError: null,
1179
+ totalConversationsOnServer: void 0,
1180
+ totalProjectsOnServer: void 0,
1181
+ hasCompletedInitialUpload: false,
1182
+ warningConversations: [],
1183
+ oversizedConversations: []
1184
+ };
1185
+ }
1186
+ async function clearLocalStoresForIdentitySwitch(fromIdentity, toIdentity) {
1187
+ const conversationCount = useConversationStore.getState().conversations.length;
1188
+ const projectCount = useProjectStore.getState().projects.length;
1189
+ debugLogger.warn("conversationSyncStore: auth identity changed, clearing local conversation/project cache", {
1190
+ fromIdentity,
1191
+ toIdentity,
1192
+ conversationCount,
1193
+ projectCount
1194
+ });
1195
+ suppressTracking = true;
1196
+ try {
1197
+ await useConversationStore.getState().clearAllConversations();
1198
+ await indexedDBService_default.clear(
1199
+ PROJECT_DB_NAME,
1200
+ PROJECT_DB_VERSION,
1201
+ PROJECT_STORE_NAME,
1202
+ PROJECT_STORE_CONFIGS
1203
+ );
1204
+ useProjectStore.setState({ projects: [] });
1205
+ conversationsMeta = snapshotConversationMetaMap(useConversationStore.getState().conversations);
1206
+ projectsMeta = snapshotProjectMetaMap(useProjectStore.getState().projects);
1207
+ } catch (error) {
1208
+ debugLogger.error("conversationSyncStore: failed to clear local stores on auth switch", {
1209
+ error: error instanceof Error ? error.message : String(error)
1210
+ });
1211
+ } finally {
1212
+ suppressTracking = false;
1213
+ }
1214
+ }
1094
1215
  function mapConversationToDTO(conversation) {
1095
1216
  const updatedAtIso = (conversation.updatedAt ?? /* @__PURE__ */ new Date()).toISOString();
1096
1217
  const createdAtIso = conversation.createdAt ? conversation.createdAt.toISOString() : null;
@@ -1459,6 +1580,9 @@ async function applyServerResults(response) {
1459
1580
  }
1460
1581
  var useConversationSyncStore = create6((set, get) => ({
1461
1582
  initialized: false,
1583
+ hasLoadedPreference: false,
1584
+ initializedForToken: null,
1585
+ initializedForIdentity: null,
1462
1586
  syncEnabled: false,
1463
1587
  status: "disabled",
1464
1588
  lastSyncAt: null,
@@ -1478,20 +1602,63 @@ var useConversationSyncStore = create6((set, get) => ({
1478
1602
  warningConversations: [],
1479
1603
  oversizedConversations: [],
1480
1604
  async initialize() {
1481
- if (get().initialized) {
1482
- return;
1483
- }
1484
1605
  ensureTrackersInitialized();
1485
1606
  const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;
1607
+ const token = authenticationService.getToken();
1608
+ const tokenIdentity = resolveAuthIdentity(token);
1609
+ const current = get();
1610
+ const storedIdentity = getStoredSyncIdentity();
1611
+ const knownIdentity = current.initializedForIdentity ?? storedIdentity;
1612
+ if (current.initialized && current.hasLoadedPreference && knownIdentity && tokenIdentity && knownIdentity === tokenIdentity) {
1613
+ return;
1614
+ }
1615
+ const hasIdentitySwitch = Boolean(
1616
+ knownIdentity && tokenIdentity && knownIdentity !== tokenIdentity
1617
+ );
1618
+ if (hasIdentitySwitch) {
1619
+ clearAutoSyncTimer();
1620
+ set({
1621
+ ...buildQueueResetState(),
1622
+ syncEnabled: false,
1623
+ status: "disabled",
1624
+ hasLoadedPreference: false,
1625
+ initializedForToken: null,
1626
+ initializedForIdentity: tokenIdentity
1627
+ });
1628
+ await clearLocalStoresForIdentitySwitch(
1629
+ knownIdentity,
1630
+ tokenIdentity
1631
+ );
1632
+ setStoredSyncIdentity(tokenIdentity);
1633
+ }
1486
1634
  if (!gatewayUrl) {
1487
1635
  debugLogger.info("conversationSyncStore: gateway API URL not configured; sync disabled");
1488
- set({ initialized: true, status: "disabled", syncEnabled: false });
1636
+ if (tokenIdentity) {
1637
+ setStoredSyncIdentity(tokenIdentity);
1638
+ }
1639
+ set({
1640
+ ...buildQueueResetState(),
1641
+ initialized: true,
1642
+ hasLoadedPreference: false,
1643
+ initializedForToken: null,
1644
+ initializedForIdentity: tokenIdentity,
1645
+ status: "disabled",
1646
+ syncEnabled: false
1647
+ });
1489
1648
  return;
1490
1649
  }
1491
- const token = authenticationService.getToken();
1492
1650
  if (!token) {
1493
1651
  debugLogger.info("conversationSyncStore: no authentication token; sync disabled until login");
1494
- set({ initialized: true, status: "disabled", syncEnabled: false });
1652
+ clearAutoSyncTimer();
1653
+ set({
1654
+ ...buildQueueResetState(),
1655
+ initialized: true,
1656
+ hasLoadedPreference: false,
1657
+ initializedForToken: null,
1658
+ initializedForIdentity: null,
1659
+ status: "disabled",
1660
+ syncEnabled: false
1661
+ });
1495
1662
  return;
1496
1663
  }
1497
1664
  try {
@@ -1513,14 +1680,27 @@ var useConversationSyncStore = create6((set, get) => ({
1513
1680
  isAdvancedVectorFeaturesEnabled: get().isAdvancedVectorFeaturesEnabled
1514
1681
  }
1515
1682
  });
1516
- set({ initialized: true });
1683
+ set({
1684
+ initialized: true,
1685
+ hasLoadedPreference: true,
1686
+ initializedForToken: token,
1687
+ initializedForIdentity: tokenIdentity
1688
+ });
1689
+ setStoredSyncIdentity(tokenIdentity);
1517
1690
  if (preference.syncEnabled) {
1518
1691
  await get().runSync({ force: true });
1519
1692
  }
1520
1693
  } catch (error) {
1521
1694
  const message = error instanceof Error ? error.message : "Failed to load conversation sync preference";
1522
1695
  debugLogger.error("conversationSyncStore: initialization failed", { error: message });
1523
- set({ initialized: true, status: "error", lastError: message });
1696
+ set({
1697
+ initialized: true,
1698
+ hasLoadedPreference: false,
1699
+ initializedForToken: null,
1700
+ initializedForIdentity: tokenIdentity,
1701
+ status: "error",
1702
+ lastError: message
1703
+ });
1524
1704
  }
1525
1705
  },
1526
1706
  async setSyncEnabled(enabled) {
@@ -1548,6 +1728,12 @@ var useConversationSyncStore = create6((set, get) => ({
1548
1728
  isAdvancedVectorFeaturesEnabled
1549
1729
  }
1550
1730
  });
1731
+ set({
1732
+ hasLoadedPreference: true,
1733
+ initializedForToken: authenticationService.getToken(),
1734
+ initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
1735
+ });
1736
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
1551
1737
  if (enabled) {
1552
1738
  set({ hasCompletedInitialUpload: false });
1553
1739
  }
@@ -1585,6 +1771,12 @@ var useConversationSyncStore = create6((set, get) => ({
1585
1771
  isAdvancedVectorFeaturesEnabled: enabled
1586
1772
  }
1587
1773
  });
1774
+ set({
1775
+ hasLoadedPreference: true,
1776
+ initializedForToken: authenticationService.getToken(),
1777
+ initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
1778
+ });
1779
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
1588
1780
  if (preference.syncEnabled && preference.isAdvancedVectorFeaturesEnabled) {
1589
1781
  await get().runSync({ force: true });
1590
1782
  }
@@ -1630,6 +1822,15 @@ var useConversationSyncStore = create6((set, get) => ({
1630
1822
  debugLogger.error("conversationSyncStore: runSync error - missing auth token");
1631
1823
  return;
1632
1824
  }
1825
+ const tokenIdentity = resolveAuthIdentity(token);
1826
+ if (state.initializedForIdentity && tokenIdentity && state.initializedForIdentity !== tokenIdentity) {
1827
+ debugLogger.warn("conversationSyncStore: runSync aborted due auth identity mismatch; reinitializing", {
1828
+ initializedForIdentity: state.initializedForIdentity,
1829
+ tokenIdentity
1830
+ });
1831
+ await get().initialize();
1832
+ return;
1833
+ }
1633
1834
  const pendingConversationIds = Array.from(state.pendingConversationUpserts);
1634
1835
  const pendingConversationDeleteIds = Array.from(state.pendingConversationDeletes);
1635
1836
  const pendingProjectIds = Array.from(state.pendingProjectUpserts);
@@ -5684,6 +5885,7 @@ var NotificationProvider = ({
5684
5885
 
5685
5886
  export {
5686
5887
  useAuthenticationStore,
5888
+ AUTH_TOKEN_CHANGED_EVENT,
5687
5889
  authenticationService,
5688
5890
  useAIQueryStore,
5689
5891
  sanitizeConversationName,
@@ -5722,4 +5924,4 @@ export {
5722
5924
  useNotification,
5723
5925
  NotificationProvider
5724
5926
  };
5725
- //# sourceMappingURL=chunk-6WZUQHZT.mjs.map
5927
+ //# sourceMappingURL=chunk-QX6CO7TJ.mjs.map