@burtson-labs/bandit-engine 2.0.51 → 2.0.53

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 (48) hide show
  1. package/dist/{aiProviderStore-3N3VE6D4.mjs → aiProviderStore-337QNQB3.mjs} +2 -2
  2. package/dist/{chat-W5IFNEUC.mjs → chat-U4SE4JQK.mjs} +6 -6
  3. package/dist/chat-provider.js +242 -17
  4. package/dist/chat-provider.js.map +1 -1
  5. package/dist/chat-provider.mjs +4 -4
  6. package/dist/{chunk-LXD3IV6Z.mjs → chunk-2BGORTWS.mjs} +4 -4
  7. package/dist/{chunk-IDH2YOW3.mjs → chunk-557E5VZ2.mjs} +198 -11
  8. package/dist/chunk-557E5VZ2.mjs.map +1 -0
  9. package/dist/{chunk-QFSEZAG6.mjs → chunk-AVV7HDGR.mjs} +34 -3
  10. package/dist/chunk-AVV7HDGR.mjs.map +1 -0
  11. package/dist/{chunk-N7RMUOFB.mjs → chunk-EULV5CHD.mjs} +2 -2
  12. package/dist/{chunk-STMXPFAQ.mjs → chunk-GNE4TTSI.mjs} +48 -15
  13. package/dist/chunk-GNE4TTSI.mjs.map +1 -0
  14. package/dist/{chunk-BENL3EF2.mjs → chunk-H3BYFEIE.mjs} +18 -10
  15. package/dist/chunk-H3BYFEIE.mjs.map +1 -0
  16. package/dist/{chunk-HETIHZ42.mjs → chunk-NZKLKZJT.mjs} +3 -3
  17. package/dist/{chunk-JBXNXSAH.mjs → chunk-O54PTFJM.mjs} +460 -181
  18. package/dist/chunk-O54PTFJM.mjs.map +1 -0
  19. package/dist/{chunk-EWUUF4GE.mjs → chunk-UFSEYVRS.mjs} +3 -3
  20. package/dist/cli.js +1 -1
  21. package/dist/cli.js.map +1 -1
  22. package/dist/{gateway-oScD5tvE.d.ts → gateway-C5T5FfCy.d.mts} +32 -0
  23. package/dist/{gateway-oScD5tvE.d.mts → gateway-C5T5FfCy.d.ts} +32 -0
  24. package/dist/index.d.mts +2 -2
  25. package/dist/index.d.ts +2 -2
  26. package/dist/index.js +738 -202
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +9 -9
  29. package/dist/management/management.js +708 -202
  30. package/dist/management/management.js.map +1 -1
  31. package/dist/management/management.mjs +7 -7
  32. package/dist/modals/chat-modal/chat-modal.js +214 -17
  33. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  34. package/dist/modals/chat-modal/chat-modal.mjs +4 -4
  35. package/dist/public-types.d.mts +1 -1
  36. package/dist/public-types.d.ts +1 -1
  37. package/package.json +1 -1
  38. package/dist/chunk-BENL3EF2.mjs.map +0 -1
  39. package/dist/chunk-IDH2YOW3.mjs.map +0 -1
  40. package/dist/chunk-JBXNXSAH.mjs.map +0 -1
  41. package/dist/chunk-QFSEZAG6.mjs.map +0 -1
  42. package/dist/chunk-STMXPFAQ.mjs.map +0 -1
  43. /package/dist/{aiProviderStore-3N3VE6D4.mjs.map → aiProviderStore-337QNQB3.mjs.map} +0 -0
  44. /package/dist/{chat-W5IFNEUC.mjs.map → chat-U4SE4JQK.mjs.map} +0 -0
  45. /package/dist/{chunk-LXD3IV6Z.mjs.map → chunk-2BGORTWS.mjs.map} +0 -0
  46. /package/dist/{chunk-N7RMUOFB.mjs.map → chunk-EULV5CHD.mjs.map} +0 -0
  47. /package/dist/{chunk-HETIHZ42.mjs.map → chunk-NZKLKZJT.mjs.map} +0 -0
  48. /package/dist/{chunk-EWUUF4GE.mjs.map → chunk-UFSEYVRS.mjs.map} +0 -0
@@ -1709,7 +1709,8 @@ var init_gateway_service = __esm({
1709
1709
  index: 0,
1710
1710
  delta: {
1711
1711
  role: parsed.message.role,
1712
- content: parsed.message.content
1712
+ content: parsed.message.content,
1713
+ tool_calls: parsed.message.tool_calls
1713
1714
  },
1714
1715
  finish_reason: parsed.done ? parsed.done_reason || "stop" : null
1715
1716
  }]
@@ -2689,6 +2690,7 @@ var init_gateway_provider = __esm({
2689
2690
  }
2690
2691
  }
2691
2692
  }
2693
+ const toolAwareRequest = request;
2692
2694
  const gatewayRequest = {
2693
2695
  model: request.model,
2694
2696
  messages,
@@ -2697,7 +2699,8 @@ var init_gateway_provider = __esm({
2697
2699
  max_tokens: request.maxTokens,
2698
2700
  provider: this.config.provider,
2699
2701
  // Only include top-level images for Ollama (fallback)
2700
- images: this.config.provider === "ollama" ? request.images : void 0
2702
+ images: this.config.provider === "ollama" ? request.images : void 0,
2703
+ tools: toolAwareRequest.tools?.length ? toolAwareRequest.tools : void 0
2701
2704
  };
2702
2705
  debugLogger.debug("Gateway provider chat request", {
2703
2706
  model: request.model,
@@ -2714,13 +2717,18 @@ var init_gateway_provider = __esm({
2714
2717
  }))
2715
2718
  });
2716
2719
  return this.gatewayService.chat(gatewayRequest).pipe(
2717
- (0, import_rxjs7.map)((response) => ({
2718
- message: {
2719
- content: response.choices?.[0]?.message?.content || response.choices?.[0]?.delta?.content || "",
2720
- role: "assistant"
2721
- },
2722
- done: response.choices?.[0]?.finish_reason === "stop" || response.choices?.[0]?.finish_reason === "length"
2723
- }))
2720
+ (0, import_rxjs7.map)((response) => {
2721
+ const choice = response.choices?.[0];
2722
+ const toolCalls = choice?.message?.tool_calls ?? choice?.delta?.tool_calls;
2723
+ return {
2724
+ message: {
2725
+ content: choice?.message?.content ?? choice?.delta?.content ?? "",
2726
+ role: "assistant",
2727
+ tool_calls: toolCalls
2728
+ },
2729
+ done: choice?.finish_reason === "stop" || choice?.finish_reason === "length" || choice?.finish_reason === "tool_calls"
2730
+ };
2731
+ })
2724
2732
  );
2725
2733
  }
2726
2734
  generate(request) {
@@ -7943,13 +7951,22 @@ var init_projectStore = __esm({
7943
7951
  });
7944
7952
 
7945
7953
  // src/services/auth/authenticationService.ts
7946
- var TOKEN_KEY2, AuthenticationService, authenticationService;
7954
+ function emitAuthTokenChanged(token) {
7955
+ if (typeof window === "undefined") {
7956
+ return;
7957
+ }
7958
+ window.dispatchEvent(new CustomEvent(AUTH_TOKEN_CHANGED_EVENT, {
7959
+ detail: { token }
7960
+ }));
7961
+ }
7962
+ var TOKEN_KEY2, AUTH_TOKEN_CHANGED_EVENT, AuthenticationService, authenticationService;
7947
7963
  var init_authenticationService = __esm({
7948
7964
  "src/services/auth/authenticationService.ts"() {
7949
7965
  "use strict";
7950
7966
  init_authenticationStore();
7951
7967
  init_debugLogger();
7952
7968
  TOKEN_KEY2 = "authToken";
7969
+ AUTH_TOKEN_CHANGED_EVENT = "bandit:auth-token-changed";
7953
7970
  AuthenticationService = class {
7954
7971
  getToken() {
7955
7972
  const token = localStorage.getItem(TOKEN_KEY2);
@@ -7958,10 +7975,12 @@ var init_authenticationService = __esm({
7958
7975
  setToken(token) {
7959
7976
  localStorage.setItem(TOKEN_KEY2, token);
7960
7977
  useAuthenticationStore.getState().setToken(token);
7978
+ emitAuthTokenChanged(token);
7961
7979
  }
7962
7980
  clearToken() {
7963
7981
  localStorage.removeItem(TOKEN_KEY2);
7964
7982
  useAuthenticationStore.getState().clearToken();
7983
+ emitAuthTokenChanged(null);
7965
7984
  }
7966
7985
  isAuthenticated() {
7967
7986
  const token = useAuthenticationStore.getState().token;
@@ -8118,9 +8137,99 @@ function ensureDeviceId() {
8118
8137
  return (0, import_uuid4.v4)();
8119
8138
  }
8120
8139
  }
8140
+ function getStoredSyncIdentity() {
8141
+ if (typeof window === "undefined") {
8142
+ return null;
8143
+ }
8144
+ try {
8145
+ return window.localStorage.getItem(SYNC_IDENTITY_STORAGE_KEY);
8146
+ } catch (error) {
8147
+ debugLogger.warn("conversationSyncStore: unable to read stored sync identity", { error });
8148
+ return null;
8149
+ }
8150
+ }
8151
+ function setStoredSyncIdentity(identity) {
8152
+ if (typeof window === "undefined") {
8153
+ return;
8154
+ }
8155
+ try {
8156
+ if (identity) {
8157
+ window.localStorage.setItem(SYNC_IDENTITY_STORAGE_KEY, identity);
8158
+ } else {
8159
+ window.localStorage.removeItem(SYNC_IDENTITY_STORAGE_KEY);
8160
+ }
8161
+ } catch (error) {
8162
+ debugLogger.warn("conversationSyncStore: unable to persist sync identity", { error });
8163
+ }
8164
+ }
8121
8165
  function getPackageDefaultAdvancedKnowledgeSync() {
8122
8166
  return usePackageSettingsStore.getState().settings?.advancedKnowledgeSyncDefaultEnabled;
8123
8167
  }
8168
+ function clearAutoSyncTimer() {
8169
+ if (autoSyncTimeout) {
8170
+ clearTimeout(autoSyncTimeout);
8171
+ autoSyncTimeout = null;
8172
+ }
8173
+ }
8174
+ function resolveAuthIdentity(token) {
8175
+ if (!token) {
8176
+ return null;
8177
+ }
8178
+ const claims = authenticationService.parseJwtClaims(token);
8179
+ if (claims?.sub) {
8180
+ return claims.sub;
8181
+ }
8182
+ if (claims?.email) {
8183
+ return `email:${claims.email.toLowerCase()}`;
8184
+ }
8185
+ return `token:${token.slice(0, 32)}`;
8186
+ }
8187
+ function buildQueueResetState() {
8188
+ return {
8189
+ pendingConversationUpserts: /* @__PURE__ */ new Set(),
8190
+ pendingConversationDeletes: /* @__PURE__ */ new Set(),
8191
+ pendingProjectUpserts: /* @__PURE__ */ new Set(),
8192
+ pendingProjectDeletes: /* @__PURE__ */ new Set(),
8193
+ conflicts: null,
8194
+ lastSyncAt: null,
8195
+ cursor: null,
8196
+ lastError: null,
8197
+ totalConversationsOnServer: void 0,
8198
+ totalProjectsOnServer: void 0,
8199
+ hasCompletedInitialUpload: false,
8200
+ warningConversations: [],
8201
+ oversizedConversations: []
8202
+ };
8203
+ }
8204
+ async function clearLocalStoresForIdentitySwitch(fromIdentity, toIdentity) {
8205
+ const conversationCount = useConversationStore.getState().conversations.length;
8206
+ const projectCount = useProjectStore.getState().projects.length;
8207
+ debugLogger.warn("conversationSyncStore: auth identity changed, clearing local conversation/project cache", {
8208
+ fromIdentity,
8209
+ toIdentity,
8210
+ conversationCount,
8211
+ projectCount
8212
+ });
8213
+ suppressTracking = true;
8214
+ try {
8215
+ await useConversationStore.getState().clearAllConversations();
8216
+ await indexedDBService_default.clear(
8217
+ PROJECT_DB_NAME,
8218
+ PROJECT_DB_VERSION,
8219
+ PROJECT_STORE_NAME,
8220
+ PROJECT_STORE_CONFIGS
8221
+ );
8222
+ useProjectStore.setState({ projects: [] });
8223
+ conversationsMeta = snapshotConversationMetaMap(useConversationStore.getState().conversations);
8224
+ projectsMeta = snapshotProjectMetaMap(useProjectStore.getState().projects);
8225
+ } catch (error) {
8226
+ debugLogger.error("conversationSyncStore: failed to clear local stores on auth switch", {
8227
+ error: error instanceof Error ? error.message : String(error)
8228
+ });
8229
+ } finally {
8230
+ suppressTracking = false;
8231
+ }
8232
+ }
8124
8233
  function mapConversationToDTO(conversation) {
8125
8234
  const updatedAtIso = (conversation.updatedAt ?? /* @__PURE__ */ new Date()).toISOString();
8126
8235
  const createdAtIso = conversation.createdAt ? conversation.createdAt.toISOString() : null;
@@ -8514,7 +8623,7 @@ function buildOversizedMessage(notices) {
8514
8623
  const names = notices.map((n) => `"${n.name || "Untitled"}"`).join(", ");
8515
8624
  return `Some conversations (${names}) are too large for Bandit Cloud. Start a new conversation or archive older turns to continue syncing.`;
8516
8625
  }
8517
- var import_zustand11, import_uuid4, DEVICE_STORAGE_KEY, PAYLOAD_VERSION, MAX_CONVERSATION_BYTES, WARN_CONVERSATION_BYTES, suppressTracking, conversationsMeta, projectsMeta, conversationUnsubscribe, projectUnsubscribe, autoSyncTimeout, AUTO_SYNC_DELAY_MS, useConversationSyncStore;
8626
+ var import_zustand11, import_uuid4, DEVICE_STORAGE_KEY, SYNC_IDENTITY_STORAGE_KEY, PAYLOAD_VERSION, MAX_CONVERSATION_BYTES, WARN_CONVERSATION_BYTES, PROJECT_DB_NAME, PROJECT_DB_VERSION, PROJECT_STORE_NAME, PROJECT_STORE_CONFIGS, suppressTracking, conversationsMeta, projectsMeta, conversationUnsubscribe, projectUnsubscribe, autoSyncTimeout, AUTO_SYNC_DELAY_MS, useConversationSyncStore;
8518
8627
  var init_conversationSyncStore = __esm({
8519
8628
  "src/store/conversationSyncStore.ts"() {
8520
8629
  "use strict";
@@ -8524,13 +8633,19 @@ var init_conversationSyncStore = __esm({
8524
8633
  init_projectStore();
8525
8634
  init_packageSettingsStore();
8526
8635
  init_authenticationService();
8636
+ init_indexedDBService();
8527
8637
  init_conversationSyncEvents();
8528
8638
  init_conversationSyncService();
8529
8639
  init_debugLogger();
8530
8640
  DEVICE_STORAGE_KEY = "banditConversationDeviceId";
8641
+ SYNC_IDENTITY_STORAGE_KEY = "banditConversationSyncIdentity";
8531
8642
  PAYLOAD_VERSION = 1;
8532
8643
  MAX_CONVERSATION_BYTES = 12 * 1024 * 1024;
8533
8644
  WARN_CONVERSATION_BYTES = 10 * 1024 * 1024;
8645
+ PROJECT_DB_NAME = "bandit-projects";
8646
+ PROJECT_DB_VERSION = 1;
8647
+ PROJECT_STORE_NAME = "projects";
8648
+ PROJECT_STORE_CONFIGS = [{ name: PROJECT_STORE_NAME, keyPath: "id" }];
8534
8649
  suppressTracking = false;
8535
8650
  conversationsMeta = /* @__PURE__ */ new Map();
8536
8651
  projectsMeta = /* @__PURE__ */ new Map();
@@ -8566,6 +8681,9 @@ var init_conversationSyncStore = __esm({
8566
8681
  }
8567
8682
  useConversationSyncStore = (0, import_zustand11.create)((set, get) => ({
8568
8683
  initialized: false,
8684
+ hasLoadedPreference: false,
8685
+ initializedForToken: null,
8686
+ initializedForIdentity: null,
8569
8687
  syncEnabled: false,
8570
8688
  status: "disabled",
8571
8689
  lastSyncAt: null,
@@ -8585,20 +8703,63 @@ var init_conversationSyncStore = __esm({
8585
8703
  warningConversations: [],
8586
8704
  oversizedConversations: [],
8587
8705
  async initialize() {
8588
- if (get().initialized) {
8589
- return;
8590
- }
8591
8706
  ensureTrackersInitialized();
8592
8707
  const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;
8708
+ const token = authenticationService.getToken();
8709
+ const tokenIdentity = resolveAuthIdentity(token);
8710
+ const current = get();
8711
+ const storedIdentity = getStoredSyncIdentity();
8712
+ const knownIdentity = current.initializedForIdentity ?? storedIdentity;
8713
+ if (current.initialized && current.hasLoadedPreference && knownIdentity && tokenIdentity && knownIdentity === tokenIdentity) {
8714
+ return;
8715
+ }
8716
+ const hasIdentitySwitch = Boolean(
8717
+ knownIdentity && tokenIdentity && knownIdentity !== tokenIdentity
8718
+ );
8719
+ if (hasIdentitySwitch) {
8720
+ clearAutoSyncTimer();
8721
+ set({
8722
+ ...buildQueueResetState(),
8723
+ syncEnabled: false,
8724
+ status: "disabled",
8725
+ hasLoadedPreference: false,
8726
+ initializedForToken: null,
8727
+ initializedForIdentity: tokenIdentity
8728
+ });
8729
+ await clearLocalStoresForIdentitySwitch(
8730
+ knownIdentity,
8731
+ tokenIdentity
8732
+ );
8733
+ setStoredSyncIdentity(tokenIdentity);
8734
+ }
8593
8735
  if (!gatewayUrl) {
8594
8736
  debugLogger.info("conversationSyncStore: gateway API URL not configured; sync disabled");
8595
- set({ initialized: true, status: "disabled", syncEnabled: false });
8737
+ if (tokenIdentity) {
8738
+ setStoredSyncIdentity(tokenIdentity);
8739
+ }
8740
+ set({
8741
+ ...buildQueueResetState(),
8742
+ initialized: true,
8743
+ hasLoadedPreference: false,
8744
+ initializedForToken: null,
8745
+ initializedForIdentity: tokenIdentity,
8746
+ status: "disabled",
8747
+ syncEnabled: false
8748
+ });
8596
8749
  return;
8597
8750
  }
8598
- const token = authenticationService.getToken();
8599
8751
  if (!token) {
8600
8752
  debugLogger.info("conversationSyncStore: no authentication token; sync disabled until login");
8601
- set({ initialized: true, status: "disabled", syncEnabled: false });
8753
+ clearAutoSyncTimer();
8754
+ set({
8755
+ ...buildQueueResetState(),
8756
+ initialized: true,
8757
+ hasLoadedPreference: false,
8758
+ initializedForToken: null,
8759
+ initializedForIdentity: null,
8760
+ status: "disabled",
8761
+ syncEnabled: false
8762
+ });
8602
8763
  return;
8603
8764
  }
8604
8765
  try {
@@ -8620,14 +8781,27 @@ var init_conversationSyncStore = __esm({
8620
8781
  isAdvancedVectorFeaturesEnabled: get().isAdvancedVectorFeaturesEnabled
8621
8782
  }
8622
8783
  });
8623
- set({ initialized: true });
8784
+ set({
8785
+ initialized: true,
8786
+ hasLoadedPreference: true,
8787
+ initializedForToken: token,
8788
+ initializedForIdentity: tokenIdentity
8789
+ });
8790
+ setStoredSyncIdentity(tokenIdentity);
8624
8791
  if (preference.syncEnabled) {
8625
8792
  await get().runSync({ force: true });
8626
8793
  }
8627
8794
  } catch (error) {
8628
8795
  const message = error instanceof Error ? error.message : "Failed to load conversation sync preference";
8629
8796
  debugLogger.error("conversationSyncStore: initialization failed", { error: message });
8630
- set({ initialized: true, status: "error", lastError: message });
8797
+ set({
8798
+ initialized: true,
8799
+ hasLoadedPreference: false,
8800
+ initializedForToken: null,
8801
+ initializedForIdentity: tokenIdentity,
8802
+ status: "error",
8803
+ lastError: message
8804
+ });
8631
8805
  }
8632
8806
  },
8633
8807
  async setSyncEnabled(enabled) {
@@ -8655,6 +8829,12 @@ var init_conversationSyncStore = __esm({
8655
8829
  isAdvancedVectorFeaturesEnabled
8656
8830
  }
8657
8831
  });
8832
+ set({
8833
+ hasLoadedPreference: true,
8834
+ initializedForToken: authenticationService.getToken(),
8835
+ initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
8836
+ });
8837
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
8658
8838
  if (enabled) {
8659
8839
  set({ hasCompletedInitialUpload: false });
8660
8840
  }
@@ -8692,6 +8872,12 @@ var init_conversationSyncStore = __esm({
8692
8872
  isAdvancedVectorFeaturesEnabled: enabled
8693
8873
  }
8694
8874
  });
8875
+ set({
8876
+ hasLoadedPreference: true,
8877
+ initializedForToken: authenticationService.getToken(),
8878
+ initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
8879
+ });
8880
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
8695
8881
  if (preference.syncEnabled && preference.isAdvancedVectorFeaturesEnabled) {
8696
8882
  await get().runSync({ force: true });
8697
8883
  }
@@ -8737,6 +8923,15 @@ var init_conversationSyncStore = __esm({
8737
8923
  debugLogger.error("conversationSyncStore: runSync error - missing auth token");
8738
8924
  return;
8739
8925
  }
8926
+ const tokenIdentity = resolveAuthIdentity(token);
8927
+ if (state.initializedForIdentity && tokenIdentity && state.initializedForIdentity !== tokenIdentity) {
8928
+ debugLogger.warn("conversationSyncStore: runSync aborted due auth identity mismatch; reinitializing", {
8929
+ initializedForIdentity: state.initializedForIdentity,
8930
+ tokenIdentity
8931
+ });
8932
+ await get().initialize();
8933
+ return;
8934
+ }
8740
8935
  const pendingConversationIds = Array.from(state.pendingConversationUpserts);
8741
8936
  const pendingConversationDeleteIds = Array.from(state.pendingConversationDeletes);
8742
8937
  const pendingProjectIds = Array.from(state.pendingProjectUpserts);
@@ -19878,6 +20073,7 @@ var init_chat_messages = __esm({
19878
20073
  scrollTargetRef,
19879
20074
  responseStarted,
19880
20075
  isStreaming,
20076
+ isThinking = false,
19881
20077
  isNetworkSlow = false,
19882
20078
  showInstantFeedback = true,
19883
20079
  selectedModel,
@@ -19894,6 +20090,7 @@ var init_chat_messages = __esm({
19894
20090
  const isLast = index === lastIndex;
19895
20091
  const isPlaceholder = entry.answer === "...";
19896
20092
  const showLoader = isLast && isStreaming && streamBuffer.trim() === "";
20093
+ const showThinking = showLoader && isThinking;
19897
20094
  const content = isLast ? isStreaming ? streamBuffer || "" : isPlaceholder ? "" : entry.answer : entry.answer;
19898
20095
  const rawSources = entry.sourceFiles;
19899
20096
  const sourceSummaries = rawSources ? rawSources.filter((doc) => doc && typeof doc.name === "string" && doc.name.trim()).map((doc) => ({ id: doc.id || doc.name, name: doc.name.trim() })) : void 0;
@@ -19921,11 +20118,27 @@ var init_chat_messages = __esm({
19921
20118
  pointerEvents: showLoader ? "auto" : "none",
19922
20119
  zIndex: showLoader ? 1 : 0
19923
20120
  },
19924
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_material32.Box, { sx: { display: "flex", alignItems: "center", minHeight: "40px", pl: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "typing-only", children: [
19925
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "dot" }),
19926
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "dot" }),
19927
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "dot" })
19928
- ] }) })
20121
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_material32.Box, { sx: { display: "flex", alignItems: "center", gap: 1, minHeight: "40px", pl: 2 }, children: [
20122
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "typing-only", children: [
20123
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "dot" }),
20124
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "dot" }),
20125
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "dot" })
20126
+ ] }),
20127
+ showThinking && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
20128
+ import_material32.Box,
20129
+ {
20130
+ component: "span",
20131
+ sx: {
20132
+ fontSize: "0.75rem",
20133
+ color: "text.secondary",
20134
+ opacity: 0.6,
20135
+ fontStyle: "italic",
20136
+ userSelect: "none"
20137
+ },
20138
+ children: "Thinking\u2026"
20139
+ }
20140
+ )
20141
+ ] })
19929
20142
  }
19930
20143
  ),
19931
20144
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
@@ -22064,6 +22277,7 @@ var init_useAIProvider = __esm({
22064
22277
  setIsSubmitting,
22065
22278
  setResponseStarted,
22066
22279
  setIsStreaming,
22280
+ setIsThinking,
22067
22281
  setResponse,
22068
22282
  setPastedImages,
22069
22283
  setPendingMessage,
@@ -22521,6 +22735,12 @@ ${protocol}`;
22521
22735
  let fullMessage = "";
22522
22736
  let latestDisplayMessage = "";
22523
22737
  let sawToolBlock = false;
22738
+ const stripThinking = (text) => {
22739
+ let result = text.replace(/<think>[\s\S]*?<\/think>/g, "");
22740
+ const openIdx = result.indexOf("<think>");
22741
+ if (openIdx !== -1) result = result.slice(0, openIdx);
22742
+ return result.trimStart();
22743
+ };
22524
22744
  const flushNow = () => {
22525
22745
  clearFlushTimer();
22526
22746
  if (!sawToolBlock) {
@@ -22548,13 +22768,16 @@ ${protocol}`;
22548
22768
  }
22549
22769
  const sub = stream.subscribe({
22550
22770
  next: (data) => {
22551
- if (!data?.message?.content) return;
22552
- fullMessage += data.message.content;
22553
- if (/```(?:tool_code|TOOL_CODE)/.test(fullMessage)) {
22771
+ if (!data?.message?.content && !data?.message?.tool_calls) return;
22772
+ if (data.message.content) fullMessage += data.message.content;
22773
+ const inThinkBlock = /<think>/.test(fullMessage) && !/<think>[\s\S]*<\/think>/.test(fullMessage);
22774
+ setIsThinking?.(inThinkBlock);
22775
+ const visibleMessage = stripThinking(fullMessage);
22776
+ if (/```(?:tool_code|TOOL_CODE)/.test(visibleMessage)) {
22554
22777
  sawToolBlock = true;
22555
22778
  clearFlushTimer();
22556
22779
  }
22557
- latestDisplayMessage = fullMessage;
22780
+ latestDisplayMessage = visibleMessage;
22558
22781
  if (!sawToolBlock) {
22559
22782
  scheduleFlush();
22560
22783
  }
@@ -22575,6 +22798,7 @@ ${protocol}`;
22575
22798
  setResponse(partial);
22576
22799
  }
22577
22800
  setStreamBuffer("");
22801
+ setIsThinking?.(false);
22578
22802
  setPendingMessage(null);
22579
22803
  setLogoVisible(false);
22580
22804
  if (onError) {
@@ -22583,7 +22807,8 @@ ${protocol}`;
22583
22807
  },
22584
22808
  complete: async () => {
22585
22809
  try {
22586
- latestDisplayMessage = fullMessage;
22810
+ setIsThinking?.(false);
22811
+ latestDisplayMessage = stripThinking(fullMessage);
22587
22812
  if (!sawToolBlock) {
22588
22813
  flushNow();
22589
22814
  }
@@ -27945,6 +28170,7 @@ var init_chat2 = __esm({
27945
28170
  const [streamBuffer, setStreamBuffer] = (0, import_react55.useState)("");
27946
28171
  const [responseStarted, setResponseStarted] = (0, import_react55.useState)(false);
27947
28172
  const [isStreaming, setIsStreaming] = (0, import_react55.useState)(false);
28173
+ const [isThinking, setIsThinking] = (0, import_react55.useState)(false);
27948
28174
  const initialLogoState = history.length === 0;
27949
28175
  const [logoVisible, setLogoVisible] = (0, import_react55.useState)(initialLogoState);
27950
28176
  const [logoShouldRender, setLogoShouldRender] = (0, import_react55.useState)(initialLogoState);
@@ -28428,6 +28654,7 @@ var init_chat2 = __esm({
28428
28654
  overrideComponentStatus: setComponentStatus,
28429
28655
  setIsSubmitting,
28430
28656
  setIsStreaming,
28657
+ setIsThinking,
28431
28658
  setResponseStarted,
28432
28659
  setResponse,
28433
28660
  setStreamBuffer,
@@ -28834,6 +29061,7 @@ var init_chat2 = __esm({
28834
29061
  chat_messages_default,
28835
29062
  {
28836
29063
  isStreaming,
29064
+ isThinking,
28837
29065
  history,
28838
29066
  pendingMessage,
28839
29067
  streamBuffer,
@@ -32157,6 +32385,7 @@ var PersonalitiesTab = ({
32157
32385
  const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react24.useState)(false);
32158
32386
  const [personalityToDelete, setPersonalityToDelete] = (0, import_react24.useState)(null);
32159
32387
  const [clickedChips, setClickedChips] = (0, import_react24.useState)(/* @__PURE__ */ new Set());
32388
+ const [showTemplateHelp, setShowTemplateHelp] = (0, import_react24.useState)(false);
32160
32389
  const [cropperOpen, setCropperOpen] = (0, import_react24.useState)(false);
32161
32390
  const [selectedImageFile, setSelectedImageFile] = (0, import_react24.useState)(null);
32162
32391
  const promptTemplates = [
@@ -32410,28 +32639,15 @@ var PersonalitiesTab = ({
32410
32639
  }
32411
32640
  }
32412
32641
  ),
32413
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: {
32414
- height: "100%",
32415
- overflow: "auto",
32416
- p: { xs: 1.5, sm: 2 },
32417
- // Hide scrollbars while keeping scroll functionality
32418
- scrollbarWidth: "none",
32419
- // Firefox
32420
- "&::-webkit-scrollbar": {
32421
- display: "none"
32422
- // Chrome, Safari, Edge
32423
- },
32424
- "-ms-overflow-style": "none"
32425
- // IE and Edge
32426
- }, children: [
32642
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: { p: { xs: 1, sm: 2 } }, children: [
32427
32643
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: {
32428
32644
  display: "flex",
32429
32645
  flexDirection: { xs: "column", md: "row" },
32430
32646
  alignItems: { xs: "flex-start", md: "center" },
32431
32647
  justifyContent: "space-between",
32432
- mb: { xs: 2, md: 3 },
32648
+ mb: { xs: 1.25, md: 3 },
32433
32649
  flexWrap: "wrap",
32434
- gap: { xs: 1.5, md: 2 }
32650
+ gap: { xs: 1, md: 2 }
32435
32651
  }, children: [
32436
32652
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: {
32437
32653
  display: "flex",
@@ -32461,8 +32677,8 @@ var PersonalitiesTab = ({
32461
32677
  backgroundClip: "text",
32462
32678
  WebkitBackgroundClip: "text",
32463
32679
  WebkitTextFillColor: "transparent",
32464
- mb: 0.5,
32465
- fontSize: { xs: "1.55rem", sm: "1.75rem" }
32680
+ mb: { xs: 0.25, sm: 0.5 },
32681
+ fontSize: { xs: "1.35rem", sm: "1.75rem" }
32466
32682
  },
32467
32683
  children: "Quick Start Templates"
32468
32684
  }
@@ -32487,12 +32703,40 @@ var PersonalitiesTab = ({
32487
32703
  color: "white",
32488
32704
  fontWeight: 600,
32489
32705
  animation: "pulse 2s infinite",
32490
- alignSelf: { xs: "flex-start", md: "center" }
32706
+ alignSelf: { xs: "flex-start", md: "center" },
32707
+ display: { xs: "none", md: "inline-flex" }
32491
32708
  }
32492
32709
  }
32493
32710
  )
32494
32711
  ] }),
32495
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
32712
+ isMobile ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
32713
+ import_material18.Box,
32714
+ {
32715
+ sx: {
32716
+ mb: 1.75,
32717
+ borderRadius: 2,
32718
+ border: "1px solid rgba(25, 118, 210, 0.2)",
32719
+ background: "linear-gradient(135deg, rgba(25, 118, 210, 0.05) 0%, rgba(66, 165, 245, 0.05) 100%)",
32720
+ px: 1.25,
32721
+ py: 1
32722
+ },
32723
+ children: [
32724
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 1 }, children: [
32725
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_material18.Typography, { variant: "body2", sx: { fontWeight: 600, color: "primary.main", fontSize: "0.82rem" }, children: "Tap any template to pre-fill your form" }),
32726
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
32727
+ import_material18.Button,
32728
+ {
32729
+ size: "small",
32730
+ onClick: () => setShowTemplateHelp((prev) => !prev),
32731
+ sx: { minWidth: "auto", px: 1, fontSize: "0.72rem", whiteSpace: "nowrap" },
32732
+ children: showTemplateHelp ? "Hide" : "Details"
32733
+ }
32734
+ )
32735
+ ] }),
32736
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_material18.Collapse, { in: showTemplateHelp, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_material18.Typography, { variant: "body2", sx: { color: "text.secondary", fontSize: "0.8rem", lineHeight: 1.4, mt: 0.75 }, children: "Choose a setup you like, then tweak name, tone, and prompt details in the Create/Edit tab." }) })
32737
+ ]
32738
+ }
32739
+ ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
32496
32740
  import_material18.Alert,
32497
32741
  {
32498
32742
  severity: "info",
@@ -32518,17 +32762,19 @@ var PersonalitiesTab = ({
32518
32762
  import_material18.Card,
32519
32763
  {
32520
32764
  sx: {
32521
- mb: { xs: 3, md: 4 },
32765
+ mb: { xs: 2, md: 4 },
32522
32766
  background: "linear-gradient(135deg, #1976d2 0%, #42a5f5 100%)",
32523
32767
  border: "2px solid transparent",
32524
- borderRadius: 3,
32768
+ borderRadius: { xs: 2.25, sm: 3 },
32525
32769
  cursor: "pointer",
32526
32770
  transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
32527
32771
  position: "relative",
32528
32772
  overflow: "hidden",
32529
- "&:hover": {
32530
- transform: "translateY(-4px) scale(1.02)",
32531
- boxShadow: "0 12px 40px rgba(25, 118, 210, 0.3)"
32773
+ ...isMobile ? {} : {
32774
+ "&:hover": {
32775
+ transform: "translateY(-4px) scale(1.02)",
32776
+ boxShadow: "0 12px 40px rgba(25, 118, 210, 0.3)"
32777
+ }
32532
32778
  },
32533
32779
  "&::before": {
32534
32780
  content: '""',
@@ -32553,41 +32799,70 @@ var PersonalitiesTab = ({
32553
32799
  setPersonalityTabIndex(1);
32554
32800
  },
32555
32801
  children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.CardContent, { sx: {
32556
- p: { xs: 3, sm: 4 },
32802
+ p: { xs: 1.75, sm: 4 },
32557
32803
  color: "white",
32558
- textAlign: "center",
32804
+ textAlign: { xs: "left", sm: "center" },
32559
32805
  position: "relative",
32560
- zIndex: 1
32806
+ zIndex: 1,
32807
+ display: "flex",
32808
+ flexDirection: { xs: "row", sm: "column" },
32809
+ alignItems: { xs: "center", sm: "center" },
32810
+ gap: { xs: 1.25, sm: 0 }
32561
32811
  }, children: [
32562
32812
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_material18.Box, { sx: {
32563
32813
  display: "flex",
32564
32814
  alignItems: "center",
32565
32815
  justifyContent: "center",
32566
32816
  fontSize: 0,
32567
- mb: { xs: 1.5, sm: 2 }
32568
- }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_AutoAwesome.default, { sx: { fontSize: { xs: 36, sm: 44 }, color: "common.white", filter: "drop-shadow(0 4px 12px rgba(0,0,0,0.25))" } }) }),
32569
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
32570
- import_material18.Typography,
32571
- {
32572
- variant: "h5",
32573
- sx: {
32574
- fontWeight: 700,
32575
- mb: { xs: 0.75, sm: 1 },
32576
- textShadow: "0 2px 4px rgba(0,0,0,0.2)"
32577
- },
32578
- children: "Create from Scratch"
32579
- }
32580
- ),
32581
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
32582
- import_material18.Typography,
32817
+ mb: { xs: 0, sm: 2 },
32818
+ flexShrink: 0
32819
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_AutoAwesome.default, { sx: { fontSize: { xs: 28, sm: 44 }, color: "common.white", filter: "drop-shadow(0 4px 12px rgba(0,0,0,0.25))" } }) }),
32820
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: { flex: 1, minWidth: 0 }, children: [
32821
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
32822
+ import_material18.Typography,
32823
+ {
32824
+ variant: "h5",
32825
+ sx: {
32826
+ fontWeight: 700,
32827
+ mb: { xs: 0.25, sm: 1 },
32828
+ textShadow: "0 2px 4px rgba(0,0,0,0.2)",
32829
+ fontSize: { xs: "1.1rem", sm: "1.75rem" }
32830
+ },
32831
+ children: "Create from Scratch"
32832
+ }
32833
+ ),
32834
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
32835
+ import_material18.Typography,
32836
+ {
32837
+ variant: "body1",
32838
+ sx: {
32839
+ opacity: 0.9,
32840
+ fontWeight: 500,
32841
+ textShadow: "0 1px 2px rgba(0,0,0,0.2)",
32842
+ fontSize: { xs: "0.8rem", sm: "1rem" },
32843
+ lineHeight: { xs: 1.3, sm: 1.5 },
32844
+ display: "-webkit-box",
32845
+ WebkitLineClamp: { xs: 2, sm: "unset" },
32846
+ WebkitBoxOrient: "vertical",
32847
+ overflow: "hidden"
32848
+ },
32849
+ children: "Start with a blank canvas and build your perfect AI personality"
32850
+ }
32851
+ )
32852
+ ] }),
32853
+ isMobile && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
32854
+ import_material18.Chip,
32583
32855
  {
32584
- variant: "body1",
32856
+ label: "Start",
32857
+ size: "small",
32585
32858
  sx: {
32586
- opacity: 0.9,
32587
- fontWeight: 500,
32588
- textShadow: "0 1px 2px rgba(0,0,0,0.2)"
32589
- },
32590
- children: "Start with a blank canvas and build your perfect AI personality"
32859
+ backgroundColor: "rgba(255,255,255,0.2)",
32860
+ color: "common.white",
32861
+ border: "1px solid rgba(255,255,255,0.45)",
32862
+ fontWeight: 600,
32863
+ height: 28,
32864
+ flexShrink: 0
32865
+ }
32591
32866
  }
32592
32867
  )
32593
32868
  ] })
@@ -32602,7 +32877,7 @@ var PersonalitiesTab = ({
32602
32877
  lg: "repeat(4, 1fr)",
32603
32878
  xl: "repeat(4, 1fr)"
32604
32879
  },
32605
- gap: { xs: 2, sm: 2.5, md: 3 },
32880
+ gap: { xs: 1.25, sm: 2.5, md: 3 },
32606
32881
  alignItems: "stretch"
32607
32882
  }, children: promptTemplates.map((template, index) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
32608
32883
  import_material18.Card,
@@ -32615,7 +32890,7 @@ var PersonalitiesTab = ({
32615
32890
  border: "1px solid",
32616
32891
  borderColor: "rgba(255,255,255,0.1)",
32617
32892
  borderRadius: 3,
32618
- minHeight: { xs: "auto", md: "280px" },
32893
+ minHeight: { xs: "200px", md: "280px" },
32619
32894
  display: "flex",
32620
32895
  flexDirection: "column",
32621
32896
  overflow: "hidden",
@@ -32633,19 +32908,21 @@ var PersonalitiesTab = ({
32633
32908
  opacity: 0,
32634
32909
  transition: "opacity 0.3s ease"
32635
32910
  },
32636
- "&:hover": {
32637
- transform: "translateY(-8px) scale(1.02)",
32638
- boxShadow: "0 20px 40px rgba(0,0,0,0.15)",
32639
- borderColor: "primary.main",
32640
- "&::before": {
32641
- opacity: 1
32642
- },
32643
- "& .template-icon": {
32644
- transform: "scale(1.1) rotate(5deg)"
32645
- },
32646
- "& .template-chip": {
32647
- transform: "translateY(-2px)",
32648
- boxShadow: "0 4px 12px rgba(0,0,0,0.2)"
32911
+ ...isMobile ? {} : {
32912
+ "&:hover": {
32913
+ transform: "translateY(-8px) scale(1.02)",
32914
+ boxShadow: "0 20px 40px rgba(0,0,0,0.15)",
32915
+ borderColor: "primary.main",
32916
+ "&::before": {
32917
+ opacity: 1
32918
+ },
32919
+ "& .template-icon": {
32920
+ transform: "scale(1.1) rotate(5deg)"
32921
+ },
32922
+ "& .template-chip": {
32923
+ transform: "translateY(-2px)",
32924
+ boxShadow: "0 4px 12px rgba(0,0,0,0.2)"
32925
+ }
32649
32926
  }
32650
32927
  },
32651
32928
  "&:active": {
@@ -32654,7 +32931,7 @@ var PersonalitiesTab = ({
32654
32931
  },
32655
32932
  onClick: () => handleTemplateSelect(template),
32656
32933
  children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.CardContent, { sx: {
32657
- p: { xs: 2.5, sm: 3 },
32934
+ p: { xs: 2, sm: 3 },
32658
32935
  display: "flex",
32659
32936
  flexDirection: "column",
32660
32937
  height: "100%",
@@ -32664,7 +32941,7 @@ var PersonalitiesTab = ({
32664
32941
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: {
32665
32942
  display: "flex",
32666
32943
  alignItems: "center",
32667
- mb: { xs: 2, md: 2.5 },
32944
+ mb: { xs: 1.25, md: 2.5 },
32668
32945
  minHeight: { xs: "auto", md: "60px" }
32669
32946
  }, children: [
32670
32947
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
@@ -32673,9 +32950,9 @@ var PersonalitiesTab = ({
32673
32950
  src: template.avatar,
32674
32951
  alt: template.name,
32675
32952
  sx: {
32676
- width: { xs: 48, sm: 56, md: 60 },
32677
- height: { xs: 48, sm: 56, md: 60 },
32678
- mr: { xs: 1.5, md: 2 },
32953
+ width: { xs: 40, sm: 56, md: 60 },
32954
+ height: { xs: 40, sm: 56, md: 60 },
32955
+ mr: { xs: 1.2, md: 2 },
32679
32956
  transition: "transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
32680
32957
  boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
32681
32958
  border: "2px solid rgba(255,255,255,0.8)"
@@ -32729,10 +33006,10 @@ var PersonalitiesTab = ({
32729
33006
  lineHeight: 1.5,
32730
33007
  fontSize: { xs: "0.82rem", sm: "0.85rem", md: "0.875rem" },
32731
33008
  display: "-webkit-box",
32732
- WebkitLineClamp: 4,
33009
+ WebkitLineClamp: { xs: 2, sm: 4 },
32733
33010
  WebkitBoxOrient: "vertical",
32734
33011
  overflow: "hidden",
32735
- mb: { xs: 1.5, md: 2 },
33012
+ mb: { xs: 1.25, md: 2 },
32736
33013
  minHeight: { xs: "auto", md: "84px" }
32737
33014
  },
32738
33015
  children: template.description
@@ -32769,7 +33046,7 @@ var PersonalitiesTab = ({
32769
33046
  },
32770
33047
  index
32771
33048
  )) }),
32772
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
33049
+ !isMobile && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
32773
33050
  import_material18.Alert,
32774
33051
  {
32775
33052
  severity: "info",
@@ -32783,20 +33060,7 @@ var PersonalitiesTab = ({
32783
33060
  )
32784
33061
  ] })
32785
33062
  ] });
32786
- const renderCreateEditTab = () => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: {
32787
- height: "100%",
32788
- overflow: "auto",
32789
- p: { xs: 1.5, sm: 2 },
32790
- // Hide scrollbars while keeping scroll functionality
32791
- scrollbarWidth: "none",
32792
- // Firefox
32793
- "&::-webkit-scrollbar": {
32794
- display: "none"
32795
- // Chrome, Safari, Edge
32796
- },
32797
- "-ms-overflow-style": "none"
32798
- // IE and Edge
32799
- }, children: [
33063
+ const renderCreateEditTab = () => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: { p: { xs: 1.5, sm: 2 } }, children: [
32800
33064
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: { mb: { xs: 2.5, md: 4 } }, children: [
32801
33065
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
32802
33066
  import_material18.Typography,
@@ -33266,6 +33530,9 @@ var PersonalitiesTab = ({
33266
33530
  import_material18.Box,
33267
33531
  {
33268
33532
  sx: {
33533
+ position: { xs: "sticky", sm: "static" },
33534
+ bottom: { xs: 10, sm: "auto" },
33535
+ zIndex: { xs: 5, sm: "auto" },
33269
33536
  display: "flex",
33270
33537
  flexDirection: { xs: "column", sm: "row" },
33271
33538
  gap: { xs: 1.5, sm: 2 },
@@ -33273,8 +33540,15 @@ var PersonalitiesTab = ({
33273
33540
  // Changed from flex-end to flex-start
33274
33541
  mr: { xs: 0, sm: 10 },
33275
33542
  // Add right margin to avoid FAB
33276
- mb: { xs: 8, sm: 2 }
33543
+ mb: { xs: 8, sm: 2 },
33277
33544
  // Add bottom margin on mobile for FAB clearance
33545
+ mt: { xs: 1.5, sm: 0 },
33546
+ p: { xs: 1.1, sm: 0 },
33547
+ borderRadius: { xs: 2, sm: 0 },
33548
+ border: { xs: "1px solid", sm: "none" },
33549
+ borderColor: { xs: "divider", sm: "transparent" },
33550
+ bgcolor: { xs: "background.paper", sm: "transparent" },
33551
+ boxShadow: { xs: 3, sm: "none" }
33278
33552
  },
33279
33553
  children: [
33280
33554
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
@@ -33302,20 +33576,7 @@ var PersonalitiesTab = ({
33302
33576
  }
33303
33577
  )
33304
33578
  ] });
33305
- const renderManageTab = () => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: {
33306
- height: "100%",
33307
- overflow: "auto",
33308
- p: { xs: 1.5, sm: 2 },
33309
- // Hide scrollbars while keeping scroll functionality
33310
- scrollbarWidth: "none",
33311
- // Firefox
33312
- "&::-webkit-scrollbar": {
33313
- display: "none"
33314
- // Chrome, Safari, Edge
33315
- },
33316
- "-ms-overflow-style": "none"
33317
- // IE and Edge
33318
- }, children: [
33579
+ const renderManageTab = () => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: { p: { xs: 1.5, sm: 2 } }, children: [
33319
33580
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
33320
33581
  import_material18.Box,
33321
33582
  {
@@ -33564,7 +33825,7 @@ var PersonalitiesTab = ({
33564
33825
  ] })
33565
33826
  ] })
33566
33827
  ] });
33567
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: { height: "100%", display: "flex", flexDirection: "column" }, children: [
33828
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: { display: "flex", flexDirection: "column" }, children: [
33568
33829
  /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
33569
33830
  import_material18.Box,
33570
33831
  {
@@ -33690,7 +33951,7 @@ var PersonalitiesTab = ({
33690
33951
  ]
33691
33952
  }
33692
33953
  ) }),
33693
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: { flex: 1, overflow: "hidden" }, children: [
33954
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_material18.Box, { sx: { minHeight: 0 }, children: [
33694
33955
  personalityTabIndex === 0 && renderTemplatesTab(),
33695
33956
  personalityTabIndex === 1 && renderCreateEditTab(),
33696
33957
  personalityTabIndex === 2 && renderManageTab()
@@ -37489,6 +37750,7 @@ var import_Add = __toESM(require("@mui/icons-material/Add"));
37489
37750
  var import_Archive = __toESM(require("@mui/icons-material/Archive"));
37490
37751
  var import_Delete6 = __toESM(require("@mui/icons-material/Delete"));
37491
37752
  var import_Description4 = __toESM(require("@mui/icons-material/Description"));
37753
+ var import_FolderOpen = __toESM(require("@mui/icons-material/FolderOpen"));
37492
37754
  var import_Group2 = __toESM(require("@mui/icons-material/Group"));
37493
37755
  var import_Person3 = __toESM(require("@mui/icons-material/Person"));
37494
37756
  var import_Publish = __toESM(require("@mui/icons-material/Publish"));
@@ -37768,6 +38030,22 @@ var archiveSeedPack = async (sid) => {
37768
38030
  throw error;
37769
38031
  }
37770
38032
  };
38033
+ var deleteSeedPack = async (sid) => {
38034
+ const url = buildUrl2(`/seed-packs/${encodeURIComponent(sid)}`);
38035
+ try {
38036
+ const response = await fetch(url, { method: "DELETE", headers: buildHeaders2() });
38037
+ if (response.status === 204) {
38038
+ return;
38039
+ }
38040
+ await handleJsonResponse2(response, "Failed to delete seed pack");
38041
+ } catch (error) {
38042
+ debugLogger.error("seedPackService: failed to delete seed pack", {
38043
+ sid,
38044
+ error: error instanceof Error ? error.message : String(error)
38045
+ });
38046
+ throw error;
38047
+ }
38048
+ };
37771
38049
 
37772
38050
  // src/management/components/SeedPacksTab.tsx
37773
38051
  var import_jsx_runtime24 = require("react/jsx-runtime");
@@ -37803,10 +38081,23 @@ var getPreviewSnippet = (content) => {
37803
38081
  }
37804
38082
  return trimmed.length > 120 ? `${trimmed.slice(0, 120)}...` : trimmed;
37805
38083
  };
38084
+ var getImportedFileKey = (file) => (file.relativePath ?? file.name).toLowerCase();
38085
+ var isMarkdownFileName = (name) => {
38086
+ const lower = name.toLowerCase();
38087
+ return lower.endsWith(".md") || lower.endsWith(".markdown");
38088
+ };
38089
+ var getWebkitRelativePath = (file) => {
38090
+ const relativePath = file.webkitRelativePath;
38091
+ if (!relativePath) {
38092
+ return void 0;
38093
+ }
38094
+ const trimmed = relativePath.trim().replace(/^\/+/, "");
38095
+ return trimmed.length > 0 ? trimmed : void 0;
38096
+ };
37806
38097
  var mergeMarkdownFiles = (existing, incoming) => {
37807
38098
  const next = [...existing];
37808
38099
  incoming.forEach((file) => {
37809
- const index = next.findIndex((item) => item.name === file.name);
38100
+ const index = next.findIndex((item) => getImportedFileKey(item) === getImportedFileKey(file));
37810
38101
  if (index >= 0) {
37811
38102
  next[index] = file;
37812
38103
  } else {
@@ -37818,17 +38109,22 @@ var mergeMarkdownFiles = (existing, incoming) => {
37818
38109
  var buildMarkdownContent = (files) => {
37819
38110
  return files.map((file) => file.content.trim()).filter((content) => content.length > 0).join("\n\n---\n\n");
37820
38111
  };
37821
- var readMarkdownFiles = async (files) => {
38112
+ var readMarkdownFiles = async (files, source = "local") => {
37822
38113
  const list = Array.from(files);
37823
- const markdownFiles = list.filter((file) => file.name.toLowerCase().endsWith(".md"));
38114
+ const markdownFiles = list.filter((file) => isMarkdownFileName(file.name));
37824
38115
  const imported = await Promise.all(
37825
- markdownFiles.map(async (file) => ({
37826
- id: `${file.name}-${file.lastModified}`,
37827
- name: file.name,
37828
- size: file.size,
37829
- content: await file.text(),
37830
- lastModified: file.lastModified
37831
- }))
38116
+ markdownFiles.map(async (file) => {
38117
+ const relativePath = getWebkitRelativePath(file);
38118
+ return {
38119
+ id: `${source}-${relativePath ?? file.name}-${file.lastModified}-${file.size}`,
38120
+ name: file.name,
38121
+ size: file.size,
38122
+ content: await file.text(),
38123
+ lastModified: file.lastModified,
38124
+ relativePath,
38125
+ source
38126
+ };
38127
+ })
37832
38128
  );
37833
38129
  return { imported, skipped: list.length - markdownFiles.length };
37834
38130
  };
@@ -37944,7 +38240,7 @@ var SeedPackFileCard = ({ file, onPreview, onRemove, isReadOnly }) => /* @__PURE
37944
38240
  )
37945
38241
  }
37946
38242
  ),
37947
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Tooltip, { title: file.name, arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
38243
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Tooltip, { title: file.relativePath ?? file.name, arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
37948
38244
  import_material25.Typography,
37949
38245
  {
37950
38246
  variant: "body2",
@@ -37961,6 +38257,21 @@ var SeedPackFileCard = ({ file, onPreview, onRemove, isReadOnly }) => /* @__PURE
37961
38257
  children: file.name
37962
38258
  }
37963
38259
  ) }),
38260
+ file.relativePath && file.relativePath !== file.name && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Tooltip, { title: file.relativePath, arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
38261
+ import_material25.Typography,
38262
+ {
38263
+ variant: "caption",
38264
+ color: "text.secondary",
38265
+ sx: {
38266
+ display: "block",
38267
+ whiteSpace: "nowrap",
38268
+ overflow: "hidden",
38269
+ textOverflow: "ellipsis",
38270
+ mb: 1
38271
+ },
38272
+ children: file.relativePath
38273
+ }
38274
+ ) }),
37964
38275
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
37965
38276
  import_material25.Box,
37966
38277
  {
@@ -37977,7 +38288,7 @@ var SeedPackFileCard = ({ file, onPreview, onRemove, isReadOnly }) => /* @__PURE
37977
38288
  import_material25.Chip,
37978
38289
  {
37979
38290
  icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_Person3.default, { sx: { fontSize: "0.9rem !important" } }),
37980
- label: "Local",
38291
+ label: file.source === "azure-wiki" ? "Azure Wiki" : "Local",
37981
38292
  size: "small",
37982
38293
  sx: {
37983
38294
  bgcolor: "#388e3c20",
@@ -38066,16 +38377,20 @@ var SeedPacksTab = () => {
38066
38377
  const [createImportedFiles, setCreateImportedFiles] = (0, import_react33.useState)([]);
38067
38378
  const [previewFile, setPreviewFile] = (0, import_react33.useState)(null);
38068
38379
  const fileInputRef = (0, import_react33.useRef)(null);
38380
+ const wikiFolderInputRef = (0, import_react33.useRef)(null);
38069
38381
  const createFileInputRef = (0, import_react33.useRef)(null);
38382
+ const createWikiFolderInputRef = (0, import_react33.useRef)(null);
38070
38383
  const [isLoadingList, setIsLoadingList] = (0, import_react33.useState)(false);
38071
38384
  const [isLoadingDetail, setIsLoadingDetail] = (0, import_react33.useState)(false);
38072
38385
  const [isSaving, setIsSaving] = (0, import_react33.useState)(false);
38073
38386
  const [isPublishing, setIsPublishing] = (0, import_react33.useState)(false);
38074
38387
  const [isArchiving, setIsArchiving] = (0, import_react33.useState)(false);
38388
+ const [isDeleting, setIsDeleting] = (0, import_react33.useState)(false);
38075
38389
  const [isCreating, setIsCreating] = (0, import_react33.useState)(false);
38076
38390
  const [createDialogOpen, setCreateDialogOpen] = (0, import_react33.useState)(false);
38077
38391
  const [publishDialogOpen, setPublishDialogOpen] = (0, import_react33.useState)(false);
38078
38392
  const [archiveDialogOpen, setArchiveDialogOpen] = (0, import_react33.useState)(false);
38393
+ const [deleteDialogOpen, setDeleteDialogOpen] = (0, import_react33.useState)(false);
38079
38394
  const [newPackName, setNewPackName] = (0, import_react33.useState)("");
38080
38395
  const [newPackDescription, setNewPackDescription] = (0, import_react33.useState)("");
38081
38396
  const [newPackTags, setNewPackTags] = (0, import_react33.useState)("");
@@ -38180,26 +38495,37 @@ var SeedPacksTab = () => {
38180
38495
  void loadSeedPackDetail(selectedSid);
38181
38496
  }
38182
38497
  }, [selectedSid, loadSeedPackDetail]);
38498
+ (0, import_react33.useEffect)(() => {
38499
+ const setDirectoryUploadAttributes = (input) => {
38500
+ if (!input) {
38501
+ return;
38502
+ }
38503
+ input.setAttribute("webkitdirectory", "");
38504
+ input.setAttribute("directory", "");
38505
+ };
38506
+ setDirectoryUploadAttributes(wikiFolderInputRef.current);
38507
+ setDirectoryUploadAttributes(createWikiFolderInputRef.current);
38508
+ }, [selectedSeedPack, createDialogOpen]);
38183
38509
  const handleSelectPack = (pack) => {
38184
38510
  setSelectedSid(pack.sid);
38185
38511
  setSelectedSeedPack(pack);
38186
38512
  hydrateDraft(pack);
38187
38513
  };
38188
38514
  const handleImportFiles = (0, import_react33.useCallback)(
38189
- async (files) => {
38515
+ async (files, source = "local") => {
38190
38516
  if (!files || files.length === 0) {
38191
38517
  return;
38192
38518
  }
38193
- const { imported, skipped } = await readMarkdownFiles(files);
38519
+ const { imported, skipped } = await readMarkdownFiles(files, source);
38194
38520
  if (skipped > 0) {
38195
- showSnackbar("Only .md files are supported for seed packs.", "error");
38521
+ showSnackbar("Only .md and .markdown files are supported for seed packs.", "error");
38196
38522
  }
38197
38523
  if (imported.length === 0) {
38198
38524
  return;
38199
38525
  }
38200
38526
  try {
38201
38527
  const newlyAdded = imported.filter(
38202
- (file) => !importedFiles.some((existing) => existing.name === file.name)
38528
+ (file) => !importedFiles.some((existing) => getImportedFileKey(existing) === getImportedFileKey(file))
38203
38529
  );
38204
38530
  setImportedFiles((prev) => mergeMarkdownFiles(prev, imported));
38205
38531
  const combined = buildMarkdownContent(newlyAdded);
@@ -38214,8 +38540,9 @@ ${combined}` : combined;
38214
38540
  return { ...prev, content: nextContent };
38215
38541
  });
38216
38542
  }
38543
+ const importLabel = source === "azure-wiki" ? "from Azure DevOps wiki folder into the editor" : "into the editor";
38217
38544
  showSnackbar(
38218
- `Imported ${imported.length} markdown file${imported.length === 1 ? "" : "s"} into the editor.`,
38545
+ `Imported ${imported.length} markdown file${imported.length === 1 ? "" : "s"} ${importLabel}.`,
38219
38546
  "success"
38220
38547
  );
38221
38548
  } catch (error) {
@@ -38229,7 +38556,14 @@ ${combined}` : combined;
38229
38556
  );
38230
38557
  const handleFileInputChange = (0, import_react33.useCallback)(
38231
38558
  async (event) => {
38232
- await handleImportFiles(event.target.files);
38559
+ await handleImportFiles(event.target.files, "local");
38560
+ event.target.value = "";
38561
+ },
38562
+ [handleImportFiles]
38563
+ );
38564
+ const handleWikiFolderInputChange = (0, import_react33.useCallback)(
38565
+ async (event) => {
38566
+ await handleImportFiles(event.target.files, "azure-wiki");
38233
38567
  event.target.value = "";
38234
38568
  },
38235
38569
  [handleImportFiles]
@@ -38238,20 +38572,21 @@ ${combined}` : combined;
38238
38572
  setImportedFiles((prev) => prev.filter((file) => file.id !== id));
38239
38573
  }, []);
38240
38574
  const handleCreateImportFiles = (0, import_react33.useCallback)(
38241
- async (files) => {
38575
+ async (files, source = "local") => {
38242
38576
  if (!files || files.length === 0) {
38243
38577
  return;
38244
38578
  }
38245
- const { imported, skipped } = await readMarkdownFiles(files);
38579
+ const { imported, skipped } = await readMarkdownFiles(files, source);
38246
38580
  if (skipped > 0) {
38247
- showSnackbar("Only .md files are supported for seed packs.", "error");
38581
+ showSnackbar("Only .md and .markdown files are supported for seed packs.", "error");
38248
38582
  }
38249
38583
  if (imported.length === 0) {
38250
38584
  return;
38251
38585
  }
38252
38586
  setCreateImportedFiles((prev) => mergeMarkdownFiles(prev, imported));
38587
+ const importLabel = source === "azure-wiki" ? "from Azure DevOps wiki folder for this seed pack" : "for this seed pack";
38253
38588
  showSnackbar(
38254
- `Imported ${imported.length} markdown file${imported.length === 1 ? "" : "s"} for this seed pack.`,
38589
+ `Imported ${imported.length} markdown file${imported.length === 1 ? "" : "s"} ${importLabel}.`,
38255
38590
  "success"
38256
38591
  );
38257
38592
  },
@@ -38259,7 +38594,14 @@ ${combined}` : combined;
38259
38594
  );
38260
38595
  const handleCreateFileInputChange = (0, import_react33.useCallback)(
38261
38596
  async (event) => {
38262
- await handleCreateImportFiles(event.target.files);
38597
+ await handleCreateImportFiles(event.target.files, "local");
38598
+ event.target.value = "";
38599
+ },
38600
+ [handleCreateImportFiles]
38601
+ );
38602
+ const handleCreateWikiFolderInputChange = (0, import_react33.useCallback)(
38603
+ async (event) => {
38604
+ await handleCreateImportFiles(event.target.files, "azure-wiki");
38263
38605
  event.target.value = "";
38264
38606
  },
38265
38607
  [handleCreateImportFiles]
@@ -38404,6 +38746,34 @@ ${combined}` : combined;
38404
38746
  setIsArchiving(false);
38405
38747
  }
38406
38748
  };
38749
+ const handleDelete = async () => {
38750
+ if (!selectedSeedPack) {
38751
+ return;
38752
+ }
38753
+ const deletingSid = selectedSeedPack.sid;
38754
+ const deletingName = selectedSeedPack.name;
38755
+ setDeleteDialogOpen(false);
38756
+ setIsDeleting(true);
38757
+ try {
38758
+ await deleteSeedPack(deletingSid);
38759
+ setSelectedSid(null);
38760
+ setSelectedSeedPack(null);
38761
+ setDraft({ name: "", description: "", content: "" });
38762
+ setTagsInput("");
38763
+ setImportedFiles([]);
38764
+ setPreviewFile(null);
38765
+ await refreshSeedPacks();
38766
+ showSnackbar(`Deleted seed pack "${deletingName}".`, "success");
38767
+ } catch (error) {
38768
+ showSnackbar("Failed to delete seed pack.", "error");
38769
+ debugLogger.error("SeedPacksTab: failed to delete seed pack", {
38770
+ sid: deletingSid,
38771
+ error: error instanceof Error ? error.message : String(error)
38772
+ });
38773
+ } finally {
38774
+ setIsDeleting(false);
38775
+ }
38776
+ };
38407
38777
  const previewContent = draft.content.trim().length > 0 ? draft.content : "Preview will appear here as you type.";
38408
38778
  const selectedStatus = selectedSeedPack?.status ?? "draft";
38409
38779
  const statusChip = getStatusChip(selectedStatus);
@@ -38605,32 +38975,56 @@ ${combined}` : combined;
38605
38975
  sx: { mb: 1 },
38606
38976
  children: [
38607
38977
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Typography, { variant: "subtitle2", children: "Markdown content" }),
38978
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material25.Stack, { direction: { xs: "column", sm: "row" }, spacing: 1, children: [
38979
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
38980
+ import_material25.Button,
38981
+ {
38982
+ size: "small",
38983
+ variant: "outlined",
38984
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_UploadFile2.default, {}),
38985
+ onClick: () => fileInputRef.current?.click(),
38986
+ disabled: isReadOnly,
38987
+ children: "Import .md"
38988
+ }
38989
+ ),
38990
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
38991
+ import_material25.Button,
38992
+ {
38993
+ size: "small",
38994
+ variant: "outlined",
38995
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_FolderOpen.default, {}),
38996
+ onClick: () => wikiFolderInputRef.current?.click(),
38997
+ disabled: isReadOnly,
38998
+ children: "Import wiki folder"
38999
+ }
39000
+ )
39001
+ ] }),
38608
39002
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
38609
- import_material25.Button,
39003
+ "input",
38610
39004
  {
38611
- size: "small",
38612
- variant: "outlined",
38613
- startIcon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_UploadFile2.default, {}),
38614
- onClick: () => fileInputRef.current?.click(),
38615
- disabled: isReadOnly,
38616
- children: "Import .md"
39005
+ ref: fileInputRef,
39006
+ type: "file",
39007
+ accept: ".md,.markdown,text/markdown",
39008
+ multiple: true,
39009
+ onChange: handleFileInputChange,
39010
+ style: { display: "none" }
38617
39011
  }
38618
39012
  ),
38619
39013
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
38620
39014
  "input",
38621
39015
  {
38622
- ref: fileInputRef,
39016
+ ref: wikiFolderInputRef,
38623
39017
  type: "file",
38624
- accept: ".md",
39018
+ accept: ".md,.markdown,text/markdown",
38625
39019
  multiple: true,
38626
- onChange: handleFileInputChange,
39020
+ onChange: handleWikiFolderInputChange,
38627
39021
  style: { display: "none" }
38628
39022
  }
38629
39023
  )
38630
39024
  ]
38631
39025
  }
38632
39026
  ),
38633
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Typography, { variant: "caption", color: "text.secondary", sx: { mb: 1, display: "block" }, children: "Paste or import markdown files. Imports copy content into the editor." }),
39027
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Typography, { variant: "caption", color: "text.secondary", sx: { mb: 1, display: "block" }, children: "Paste or import markdown files. Use folder import for Azure DevOps wiki clones." }),
38634
39028
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
38635
39029
  import_material25.TextField,
38636
39030
  {
@@ -38729,6 +39123,17 @@ ${combined}` : combined;
38729
39123
  disabled: isReadOnly || isArchiving,
38730
39124
  children: isArchiving ? "Archiving..." : "Archive"
38731
39125
  }
39126
+ ),
39127
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
39128
+ import_material25.Button,
39129
+ {
39130
+ variant: "text",
39131
+ color: "error",
39132
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_Delete6.default, {}),
39133
+ onClick: () => setDeleteDialogOpen(true),
39134
+ disabled: isDeleting,
39135
+ children: isDeleting ? "Deleting..." : "Delete"
39136
+ }
38732
39137
  )
38733
39138
  ] })
38734
39139
  ] })
@@ -38778,26 +39183,50 @@ ${combined}` : combined;
38778
39183
  ),
38779
39184
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Divider, {}),
38780
39185
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material25.Stack, { direction: { xs: "column", sm: "row" }, spacing: 1, alignItems: "center", children: [
39186
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material25.Stack, { direction: { xs: "column", sm: "row" }, spacing: 1, children: [
39187
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
39188
+ import_material25.Button,
39189
+ {
39190
+ size: "small",
39191
+ variant: "outlined",
39192
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_UploadFile2.default, {}),
39193
+ onClick: () => createFileInputRef.current?.click(),
39194
+ disabled: !canManage,
39195
+ children: "Import .md files"
39196
+ }
39197
+ ),
39198
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
39199
+ import_material25.Button,
39200
+ {
39201
+ size: "small",
39202
+ variant: "outlined",
39203
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_FolderOpen.default, {}),
39204
+ onClick: () => createWikiFolderInputRef.current?.click(),
39205
+ disabled: !canManage,
39206
+ children: "Import wiki folder"
39207
+ }
39208
+ )
39209
+ ] }),
39210
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Typography, { variant: "caption", color: "text.secondary", children: "Optional. Local files or cloned Azure DevOps wiki folders are merged into draft content." }),
38781
39211
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
38782
- import_material25.Button,
39212
+ "input",
38783
39213
  {
38784
- size: "small",
38785
- variant: "outlined",
38786
- startIcon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_UploadFile2.default, {}),
38787
- onClick: () => createFileInputRef.current?.click(),
38788
- disabled: !canManage,
38789
- children: "Import .md files"
39214
+ ref: createFileInputRef,
39215
+ type: "file",
39216
+ accept: ".md,.markdown,text/markdown",
39217
+ multiple: true,
39218
+ onChange: handleCreateFileInputChange,
39219
+ style: { display: "none" }
38790
39220
  }
38791
39221
  ),
38792
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Typography, { variant: "caption", color: "text.secondary", children: "Optional. Files are merged into the draft content." }),
38793
39222
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
38794
39223
  "input",
38795
39224
  {
38796
- ref: createFileInputRef,
39225
+ ref: createWikiFolderInputRef,
38797
39226
  type: "file",
38798
- accept: ".md",
39227
+ accept: ".md,.markdown,text/markdown",
38799
39228
  multiple: true,
38800
- onChange: handleCreateFileInputChange,
39229
+ onChange: handleCreateWikiFolderInputChange,
38801
39230
  style: { display: "none" }
38802
39231
  }
38803
39232
  )
@@ -38862,6 +39291,21 @@ ${combined}` : combined;
38862
39291
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Button, { variant: "contained", color: "error", onClick: handleArchive, disabled: isArchiving, children: isArchiving ? "Archiving..." : "Archive" })
38863
39292
  ] })
38864
39293
  ] }),
39294
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material25.Dialog, { open: deleteDialogOpen, onClose: () => setDeleteDialogOpen(false), maxWidth: "sm", fullWidth: true, children: [
39295
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.DialogTitle, { children: "Delete seed pack" }),
39296
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material25.DialogContent, { children: [
39297
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material25.DialogContentText, { children: [
39298
+ 'Delete "',
39299
+ selectedSeedPack?.name ?? "this seed pack",
39300
+ '" permanently from this scope. Published versions and draft content will no longer be available.'
39301
+ ] }),
39302
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Alert, { severity: "warning", sx: { mt: 2 }, children: "This action cannot be undone." })
39303
+ ] }),
39304
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material25.DialogActions, { children: [
39305
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Button, { onClick: () => setDeleteDialogOpen(false), children: "Cancel" }),
39306
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.Button, { variant: "contained", color: "error", onClick: handleDelete, disabled: isDeleting, children: isDeleting ? "Deleting..." : "Delete" })
39307
+ ] })
39308
+ ] }),
38865
39309
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
38866
39310
  import_material25.Dialog,
38867
39311
  {
@@ -39620,15 +40064,7 @@ var StorageTab = ({ currentTheme }) => {
39620
40064
  ] }) })
39621
40065
  ] }),
39622
40066
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material27.Typography, { variant: "h6", gutterBottom: true, sx: { mb: 2, fontWeight: 600, color: "text.primary" }, children: "Storage Categories" }),
39623
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material27.Box, { sx: {
39624
- maxHeight: "60vh",
39625
- overflow: "auto",
39626
- "&::-webkit-scrollbar": {
39627
- display: "none"
39628
- },
39629
- msOverflowStyle: "none",
39630
- scrollbarWidth: "none"
39631
- }, children: storageCategories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_material27.Alert, { severity: "info", sx: { mt: 2 }, children: [
40067
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material27.Box, { children: storageCategories.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_material27.Alert, { severity: "info", sx: { mt: 2 }, children: [
39632
40068
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_material27.Typography, { variant: "body2", children: "No storage data found. This could mean:" }),
39633
40069
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_material27.Typography, { variant: "body2", component: "ul", sx: { mt: 1, pl: 2 }, children: [
39634
40070
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { children: "All databases are empty" }),
@@ -41147,7 +41583,7 @@ var Management = () => {
41147
41583
  const [modalOpen, setModalOpen] = (0, import_react56.useState)(false);
41148
41584
  const banditHead6 = "https://cdn.burtson.ai/images/bandit-head.png";
41149
41585
  const [fabLogo, setFabLogo] = (0, import_react56.useState)(banditHead6);
41150
- const [tabIndex, setTabIndex] = (0, import_react56.useState)(0);
41586
+ const [tabIndex, setTabIndex] = (0, import_react56.useState)(4);
41151
41587
  const [logoFile, setLogoFile] = (0, import_react56.useState)(null);
41152
41588
  const [logoBase64, setLogoBase64] = (0, import_react56.useState)(null);
41153
41589
  const [brandingText, setBrandingText] = (0, import_react56.useState)("");
@@ -41860,7 +42296,6 @@ var Management = () => {
41860
42296
  }
41861
42297
  });
41862
42298
  }, [theme]);
41863
- if (!brandingLoaded) return null;
41864
42299
  const allNavTabs = [
41865
42300
  {
41866
42301
  label: "Personalities",
@@ -41917,6 +42352,18 @@ var Management = () => {
41917
42352
  }
41918
42353
  return true;
41919
42354
  });
42355
+ const preferredDefaultTabIndex = navTabs.findIndex((tab) => tab.label === "Preferences");
42356
+ const defaultTabIndex = preferredDefaultTabIndex >= 0 ? preferredDefaultTabIndex : 0;
42357
+ (0, import_react56.useEffect)(() => {
42358
+ setTabIndex((current) => {
42359
+ if (current < 0 || current >= navTabs.length) {
42360
+ return defaultTabIndex;
42361
+ }
42362
+ return current;
42363
+ });
42364
+ }, [navTabs.length, defaultTabIndex]);
42365
+ const mobileQuickTabs = navTabs.slice(0, 5);
42366
+ const hasMobileOverflowTabs = navTabs.length > mobileQuickTabs.length;
41920
42367
  const navigationContent = /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
41921
42368
  import_material47.Box,
41922
42369
  {
@@ -42073,6 +42520,7 @@ var Management = () => {
42073
42520
  ]
42074
42521
  }
42075
42522
  );
42523
+ if (!brandingLoaded) return null;
42076
42524
  return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_material47.ThemeProvider, { theme: currentTheme, children: [
42077
42525
  /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_material47.CssBaseline, {}),
42078
42526
  /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
@@ -42093,7 +42541,7 @@ var Management = () => {
42093
42541
  {
42094
42542
  sx: {
42095
42543
  width: "100%",
42096
- height: 64,
42544
+ minHeight: 64,
42097
42545
  display: "flex",
42098
42546
  alignItems: "center",
42099
42547
  justifyContent: "space-between",
@@ -42176,6 +42624,73 @@ var Management = () => {
42176
42624
  ]
42177
42625
  }
42178
42626
  ),
42627
+ isMobile && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
42628
+ import_material47.Box,
42629
+ {
42630
+ sx: {
42631
+ width: "100%",
42632
+ display: "flex",
42633
+ gap: 1,
42634
+ px: 1.5,
42635
+ py: 1,
42636
+ overflowX: "auto",
42637
+ borderBottom: (theme2) => `1px solid ${theme2.palette.divider}`,
42638
+ bgcolor: (theme2) => theme2.palette.mode === "dark" ? "rgba(24,28,40,0.95)" : "rgba(255,255,255,0.95)",
42639
+ backdropFilter: "blur(12px)"
42640
+ },
42641
+ children: [
42642
+ mobileQuickTabs.map((tab) => {
42643
+ const quickTabIndex = navTabs.findIndex((navTab) => navTab.label === tab.label);
42644
+ const selected = tabIndex === quickTabIndex;
42645
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
42646
+ import_material47.Button,
42647
+ {
42648
+ size: "small",
42649
+ onClick: () => setTabIndex(quickTabIndex),
42650
+ sx: {
42651
+ flexShrink: 0,
42652
+ textTransform: "none",
42653
+ borderRadius: 999,
42654
+ px: 1.5,
42655
+ py: 0.6,
42656
+ minHeight: 32,
42657
+ fontSize: "0.78rem",
42658
+ fontWeight: selected ? 700 : 600,
42659
+ bgcolor: selected ? (theme2) => theme2.palette.mode === "dark" ? "rgba(25,118,210,0.2)" : "rgba(25,118,210,0.12)" : "transparent",
42660
+ color: selected ? "primary.main" : "text.secondary",
42661
+ border: (theme2) => selected ? `1px solid ${theme2.palette.primary.main}66` : `1px solid ${(0, import_styles31.alpha)(theme2.palette.divider, 0.45)}`,
42662
+ "&:hover": {
42663
+ bgcolor: (theme2) => theme2.palette.mode === "dark" ? "rgba(25,118,210,0.16)" : "rgba(25,118,210,0.1)"
42664
+ }
42665
+ },
42666
+ children: tab.label
42667
+ },
42668
+ tab.label
42669
+ );
42670
+ }),
42671
+ hasMobileOverflowTabs && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
42672
+ import_material47.Button,
42673
+ {
42674
+ size: "small",
42675
+ onClick: () => setSidebarOpen(true),
42676
+ sx: {
42677
+ flexShrink: 0,
42678
+ textTransform: "none",
42679
+ borderRadius: 999,
42680
+ px: 1.5,
42681
+ py: 0.6,
42682
+ minHeight: 32,
42683
+ fontSize: "0.78rem",
42684
+ fontWeight: 600,
42685
+ color: "text.secondary",
42686
+ border: (theme2) => `1px dashed ${(0, import_styles31.alpha)(theme2.palette.divider, 0.6)}`
42687
+ },
42688
+ children: "More"
42689
+ }
42690
+ )
42691
+ ]
42692
+ }
42693
+ ),
42179
42694
  isMobile ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
42180
42695
  import_material47.SwipeableDrawer,
42181
42696
  {
@@ -42228,26 +42743,17 @@ var Management = () => {
42228
42743
  flex: 1,
42229
42744
  p: { xs: 1, sm: 3, md: 4 },
42230
42745
  overflowY: "auto",
42231
- height: isMobile ? "auto" : "100vh",
42746
+ overflowX: "hidden",
42232
42747
  maxWidth: "100vw",
42233
42748
  minWidth: 0,
42749
+ minHeight: 0,
42234
42750
  display: "flex",
42235
42751
  flexDirection: "column",
42236
42752
  bgcolor: "background.default",
42237
42753
  ml: isMobile ? 0 : "280px",
42238
42754
  // Fixed left margin only on desktop
42239
42755
  mt: 0,
42240
- transition: "margin-left 0.2s",
42241
- overflow: "auto",
42242
- // Hide scrollbars while keeping scroll functionality
42243
- scrollbarWidth: "none",
42244
- // Firefox
42245
- "&::-webkit-scrollbar": {
42246
- display: "none"
42247
- // Chrome, Safari, Edge
42248
- },
42249
- "-ms-overflow-style": "none"
42250
- // IE and Edge
42756
+ transition: "margin-left 0.2s"
42251
42757
  },
42252
42758
  children: [
42253
42759
  navTabs[tabIndex]?.label === "Personalities" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(