@xmanrui/dsh-im 4.37.0 → 4.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -595,7 +595,7 @@ var React40 = __toESM(require("react"), 1);
595
595
  // package.json
596
596
  var package_default = {
597
597
  name: "@xmanrui/dsh-im",
598
- version: "4.37.0",
598
+ version: "4.38.0",
599
599
  icon: "./assets/logo-plugin-message-link-gradient.webp",
600
600
  description: "\u628A\u5FAE\u4FE1\u3001\u98DE\u4E66\u3001\u4F01\u5FAE\u3001\u9489\u9489\u3001QQ\u3001Telegram\u3001WhatsApp\u3001Slack\u3001Discord\u3001Matrix\u63A5\u5165DSH\u3002 Connect Telegram, WhatsApp, Slack, Discord, Matrix, WeChat, Feishu, WeCom, DingTalk, and QQ to DSH.",
601
601
  keywords: [
@@ -2177,14 +2177,15 @@ var EN = Object.freeze({
2177
2177
  "\u901A\u7528": "General",
2178
2178
  "\u5904\u7406\u4E2D\u2026": "Processing\u2026",
2179
2179
  "\u673A\u5668\u4EBA\u901A\u7528\u8BBE\u7F6E": "General bot settings",
2180
- "\u4EE5\u4E0B\u8BBE\u7F6E\u4EC5\u5F71\u54CD\u5F53\u524D\u673A\u5668\u4EBA\u3002": "These settings apply only to this bot.",
2181
- "\u4EFB\u52A1\u8FD0\u884C\u65F6\u7684\u65B0\u6D88\u606F\u5904\u7406\u65B9\u5F0F": "New messages while a task is running",
2182
- "\u6392\u961F\uFF08\u9ED8\u8BA4\uFF09": "Queue (default)",
2180
+ "\u5C55\u5F00\u601D\u8003\u8FC7\u7A0B": "Expand thinking",
2181
+ "\u5C55\u5F00\u5DE5\u5177\u6458\u8981": "Expand tool summaries",
2182
+ "\u4EC5\u5BF9\u5B9E\u65F6\u8FC7\u7A0B\u5361\u751F\u6548\uFF0C\u4EFB\u52A1\u7ED3\u675F\u540E\u81EA\u52A8\u6536\u8D77\u3002": "Applies to streaming process cards only. Panels collapse when the task ends.",
2183
+ "\u8BF7\u9009\u62E9\u5B9E\u65F6\u8FC7\u7A0B\u5361\u9762\u677F\u7684\u5C55\u5F00\u72B6\u6001\u3002": "Choose whether to expand the streaming process card panels.",
2184
+ "\u6D88\u606F\u5904\u7406\u65B9\u5F0F": "Message handling",
2185
+ "\u6392\u961F": "Queue",
2183
2186
  "\u63D2\u8BDD": "Steer",
2184
- "\u5F53\u524D\u4EFB\u52A1\u7ED3\u675F\u540E\uFF0C\u518D\u5904\u7406\u65B0\u6D88\u606F\u3002\u53EF\u4F7F\u7528 /steer \u624B\u52A8\u63D2\u8BDD\u3002": "Process new messages after the current task finishes. Use /steer to send an explicit correction.",
2185
- "\u5C06\u65B0\u7684\u7EAF\u6587\u5B57\u6D88\u606F\u4F5C\u4E3A\u8865\u5145\u6307\u4EE4\u52A0\u5165\u5F53\u524D\u4EFB\u52A1\uFF0CAgent \u5728\u4E0B\u4E00\u6B65\u8BFB\u53D6\u3002": "Add new plain-text messages to the running task. The Agent reads them at its next step.",
2186
- "\u6CA1\u6709\u6B63\u5728\u8FD0\u884C\u7684\u4EFB\u52A1\u65F6\uFF0C\u6B63\u5E38\u5F00\u59CB\u65B0\u4EFB\u52A1\u3002\u56FE\u7247\u3001\u6587\u4EF6\u3001\u8BED\u97F3\u548C\u5E26\u5F15\u7528\u7684\u6D88\u606F\u6309\u539F\u6709\u65B9\u5F0F\u5904\u7406\u3002": "When idle, start a new task normally. Images, files, voice and quoted messages keep their existing handling.",
2187
- "\u5DF2\u4FDD\u5B58\uFF0C\u5BF9\u65B0\u6536\u5230\u7684\u6D88\u606F\u751F\u6548\u3002": "Saved. Applies to newly received messages.",
2187
+ "\u5F53\u524D\u4EFB\u52A1\u7ED3\u675F\u540E\u5904\u7406\u65B0\u6D88\u606F": "Process new messages after the current task",
2188
+ "\u5C06\u65B0\u6D88\u606F\u8865\u5145\u5230\u5F53\u524D\u4EFB\u52A1": "Add new messages to the current task",
2188
2189
  "\u65E0\u6CD5\u8BFB\u53D6\u6D88\u606F\u5904\u7406\u8BBE\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002": "Could not read message handling settings. Try again later.",
2189
2190
  "\u8BF7\u63D0\u4EA4\u6709\u6548\u7684\u6D88\u606F\u5904\u7406\u65B9\u5F0F\u3002": "Choose a valid message handling mode.",
2190
2191
  "\u901A\u7528\u8BBE\u7F6E": "General settings",
@@ -7239,6 +7240,16 @@ var FEISHU_STEP_PUSH_MODES = Object.freeze({
7239
7240
  LIVE_COT: "live_cot"
7240
7241
  });
7241
7242
  var DEFAULT_FEISHU_STEP_PUSH_MODE = FEISHU_STEP_PUSH_MODES.STREAMING_CARD;
7243
+ var DEFAULT_FEISHU_STEP_CARD_PANELS = Object.freeze({
7244
+ thinkingExpanded: false,
7245
+ toolsExpanded: true
7246
+ });
7247
+ function normalizeFeishuStepCardPanels(value) {
7248
+ return Object.freeze({
7249
+ thinkingExpanded: typeof value?.thinkingExpanded === "boolean" ? value.thinkingExpanded : DEFAULT_FEISHU_STEP_CARD_PANELS.thinkingExpanded,
7250
+ toolsExpanded: typeof value?.toolsExpanded === "boolean" ? value.toolsExpanded : DEFAULT_FEISHU_STEP_CARD_PANELS.toolsExpanded
7251
+ });
7252
+ }
7242
7253
  function normalizeFeishuStepPushMode(value) {
7243
7254
  if (value === FEISHU_STEP_PUSH_MODES.STREAMING_CARD) {
7244
7255
  return FEISHU_STEP_PUSH_MODES.STREAMING_CARD;
@@ -7367,6 +7378,7 @@ var FEISHU_ENDPOINTS = Object.freeze({
7367
7378
  setMentionTopicReply: "bot.mention-topic-reply.set",
7368
7379
  setStepPush: "bot.step-push.set",
7369
7380
  setStepPushMode: "bot.step-push-mode.set",
7381
+ setStepCardPanels: "bot.step-card-panels.set",
7370
7382
  setVoice: "bot.voice.set",
7371
7383
  setSlashPanel: "bot.slash-panel.set",
7372
7384
  // Kept for rolling upgrades. The multi-bot UI never calls these endpoints.
@@ -7526,6 +7538,7 @@ function normalizeBotConnection(value, fallbackBotId) {
7526
7538
  mentionTopicReply: value.mentionTopicReply !== false,
7527
7539
  stepPush: value.stepPush === true,
7528
7540
  stepPushMode: normalizeFeishuStepPushMode(value.stepPushMode),
7541
+ stepCardPanels: normalizeFeishuStepCardPanels(value.stepCardPanels),
7529
7542
  voice: normalizeFeishuVoiceConfig(value.voice),
7530
7543
  slashPanel: normalizeSlashPanelConfig(value.slashPanel),
7531
7544
  groupMessagePermissionGranted: value.groupMessagePermissionGranted === true,
@@ -16658,29 +16671,41 @@ function AccessPolicySettingsPage({ channel: channel7, account, rpcCall, onSaved
16658
16671
 
16659
16672
  // plugin-src/client/bot-general-settings.js
16660
16673
  var React29 = __toESM(require("react"), 1);
16661
- function modeFromResult(result, botId) {
16662
- if (result?.ok !== true) throw new Error(result?.error?.message || "\u65E0\u6CD5\u8BFB\u53D6\u6D88\u606F\u5904\u7406\u8BBE\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
16674
+ function settingsFromResult(result, botId) {
16675
+ if (result?.ok !== true) throw new Error(result?.error?.message || "\u65E0\u6CD5\u8BFB\u53D6\u901A\u7528\u8BBE\u7F6E\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
16663
16676
  const bot = result.value?.bots?.find((entry) => entry.botId === botId);
16664
16677
  if (!bot) throw new Error("\u627E\u4E0D\u5230\u8981\u4FEE\u6539\u7684\u673A\u5668\u4EBA\u3002");
16665
- return normalizeBusyMessageMode(bot.busyMessageMode);
16678
+ return {
16679
+ busyMessageMode: normalizeBusyMessageMode(bot.busyMessageMode),
16680
+ stepCardPanels: normalizeFeishuStepCardPanels(bot.stepCardPanels)
16681
+ };
16666
16682
  }
16667
- function BotGeneralSettingsPage({ account, rpcCall }) {
16668
- const [mode, setMode] = React29.useState("queue");
16669
- const [savedMode, setSavedMode] = React29.useState(null);
16683
+ function BotGeneralSettingsPage({ channel: channel7, account, rpcCall }) {
16684
+ const modeId = React29.useId();
16685
+ const [settings, setSettings] = React29.useState(() => ({
16686
+ busyMessageMode: "queue",
16687
+ stepCardPanels: normalizeFeishuStepCardPanels()
16688
+ }));
16689
+ const [savedSettings, setSavedSettings] = React29.useState(null);
16670
16690
  const [busy, setBusy] = React29.useState(false);
16671
16691
  const [feedback, setFeedback] = React29.useState(null);
16672
16692
  const mounted = React29.useRef(false);
16693
+ const inFlight = React29.useRef(false);
16694
+ const mode = settings.busyMessageMode;
16673
16695
  const load = React29.useCallback(async () => {
16696
+ if (inFlight.current) return;
16697
+ inFlight.current = true;
16674
16698
  setBusy(true);
16675
16699
  setFeedback(null);
16676
16700
  try {
16677
- const value = modeFromResult(await rpcCall("connection.status", {}), account.botId);
16701
+ const value = settingsFromResult(await rpcCall("connection.status", {}), account.botId);
16678
16702
  if (!mounted.current) return;
16679
- setMode(value);
16680
- setSavedMode(value);
16703
+ setSettings(value);
16704
+ setSavedSettings(value);
16681
16705
  } catch (error) {
16682
- if (mounted.current) setFeedback({ error: true, text: error.message });
16706
+ if (mounted.current) setFeedback(error.message);
16683
16707
  } finally {
16708
+ inFlight.current = false;
16684
16709
  if (mounted.current) setBusy(false);
16685
16710
  }
16686
16711
  }, [account.botId, rpcCall]);
@@ -16691,63 +16716,115 @@ function BotGeneralSettingsPage({ account, rpcCall }) {
16691
16716
  mounted.current = false;
16692
16717
  };
16693
16718
  }, [load]);
16694
- const save = async () => {
16719
+ const save = async (field2, value) => {
16720
+ if (inFlight.current || savedSettings === null || value === savedSettings[field2]) return;
16721
+ inFlight.current = true;
16722
+ setSettings({ ...settings, [field2]: value });
16695
16723
  setBusy(true);
16696
16724
  setFeedback(null);
16697
16725
  try {
16698
- const value = modeFromResult(await rpcCall(SET_MESSAGE_MODE_ENDPOINT, {
16726
+ const endpoint = field2 === "stepCardPanels" ? FEISHU_ENDPOINTS.setStepCardPanels : SET_MESSAGE_MODE_ENDPOINT;
16727
+ const saved = settingsFromResult(await rpcCall(endpoint, {
16699
16728
  botId: account.botId,
16700
- busyMessageMode: mode
16729
+ [field2]: value
16701
16730
  }), account.botId);
16702
16731
  if (!mounted.current) return;
16703
- setMode(value);
16704
- setSavedMode(value);
16705
- setFeedback({ text: "\u5DF2\u4FDD\u5B58\uFF0C\u5BF9\u65B0\u6536\u5230\u7684\u6D88\u606F\u751F\u6548\u3002" });
16732
+ setSettings(saved);
16733
+ setSavedSettings(saved);
16706
16734
  } catch (error) {
16707
- if (mounted.current) setFeedback({ error: true, text: error.message });
16735
+ if (mounted.current) {
16736
+ setSettings(savedSettings);
16737
+ setFeedback(error.message);
16738
+ }
16708
16739
  } finally {
16740
+ inFlight.current = false;
16709
16741
  if (mounted.current) setBusy(false);
16710
16742
  }
16711
16743
  };
16712
16744
  return h2(
16713
16745
  "section",
16714
- { className: "dim-accessPage", "aria-label": "\u673A\u5668\u4EBA\u901A\u7528\u8BBE\u7F6E" },
16715
- h2("h2", null, "\u901A\u7528"),
16716
- h2("p", null, "\u4EE5\u4E0B\u8BBE\u7F6E\u4EC5\u5F71\u54CD\u5F53\u524D\u673A\u5668\u4EBA\u3002"),
16746
+ { className: "dim-botGeneralSettings", "aria-label": "\u673A\u5668\u4EBA\u901A\u7528\u8BBE\u7F6E", "aria-busy": busy },
16717
16747
  h2(
16718
- "label",
16719
- { className: "dim-accessField" },
16720
- h2("span", null, "\u4EFB\u52A1\u8FD0\u884C\u65F6\u7684\u65B0\u6D88\u606F\u5904\u7406\u65B9\u5F0F"),
16748
+ "div",
16749
+ { className: "dim-botGeneralList" },
16721
16750
  h2(
16722
- "select",
16723
- {
16724
- value: mode,
16725
- disabled: busy || savedMode === null,
16726
- "aria-label": "\u4EFB\u52A1\u8FD0\u884C\u65F6\u7684\u65B0\u6D88\u606F\u5904\u7406\u65B9\u5F0F",
16727
- onChange: (event) => {
16728
- setMode(event.target.value);
16729
- setFeedback(null);
16730
- }
16731
- },
16732
- h2("option", { value: "queue" }, "\u6392\u961F\uFF08\u9ED8\u8BA4\uFF09"),
16733
- h2("option", { value: "steer" }, "\u63D2\u8BDD")
16734
- )
16751
+ "div",
16752
+ { className: "dim-botGeneralRow" },
16753
+ h2(
16754
+ "div",
16755
+ { className: "dim-botGeneralText" },
16756
+ h2("label", { className: "dim-botGeneralTitle", htmlFor: modeId }, "\u6D88\u606F\u5904\u7406\u65B9\u5F0F"),
16757
+ h2("p", { className: "dim-botGeneralHelp", id: `${modeId}-description` }, mode === "queue" ? "\u5F53\u524D\u4EFB\u52A1\u7ED3\u675F\u540E\u5904\u7406\u65B0\u6D88\u606F" : "\u5C06\u65B0\u6D88\u606F\u8865\u5145\u5230\u5F53\u524D\u4EFB\u52A1")
16758
+ ),
16759
+ h2(
16760
+ "div",
16761
+ { className: "dim-botGeneralControl" },
16762
+ h2(
16763
+ "select",
16764
+ {
16765
+ id: modeId,
16766
+ value: mode,
16767
+ disabled: busy || savedSettings === null,
16768
+ "aria-label": "\u6D88\u606F\u5904\u7406\u65B9\u5F0F",
16769
+ "aria-describedby": `${modeId}-description`,
16770
+ onChange: (event) => void save("busyMessageMode", event.target.value)
16771
+ },
16772
+ h2("option", { value: "queue" }, "\u6392\u961F"),
16773
+ h2("option", { value: "steer" }, "\u63D2\u8BDD")
16774
+ ),
16775
+ h2(
16776
+ "svg",
16777
+ { width: 14, height: 14, viewBox: "0 0 16 16", fill: "none", "aria-hidden": true },
16778
+ h2("path", { d: "m4 6 4 4 4-4", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" })
16779
+ )
16780
+ )
16781
+ ),
16782
+ channel7 === "feishu" ? [
16783
+ ["thinkingExpanded", "\u5C55\u5F00\u601D\u8003\u8FC7\u7A0B"],
16784
+ ["toolsExpanded", "\u5C55\u5F00\u5DE5\u5177\u6458\u8981"]
16785
+ ].map(([field2, label]) => h2(
16786
+ "div",
16787
+ { key: field2, className: "dim-botGeneralRow dim-botGeneralPanelRow" },
16788
+ h2("label", { className: "dim-botGeneralTitle", htmlFor: `${modeId}-${field2}` }, label),
16789
+ h2(
16790
+ "div",
16791
+ { className: "dim-botGeneralControl" },
16792
+ h2("input", {
16793
+ id: `${modeId}-${field2}`,
16794
+ type: "checkbox",
16795
+ role: "switch",
16796
+ className: "dim-contextSwitch",
16797
+ checked: settings.stepCardPanels[field2],
16798
+ disabled: busy || savedSettings === null,
16799
+ "aria-label": label,
16800
+ "aria-describedby": `${modeId}-panels-description`,
16801
+ onChange: (event) => void save("stepCardPanels", {
16802
+ ...settings.stepCardPanels,
16803
+ [field2]: event.target.checked
16804
+ })
16805
+ })
16806
+ )
16807
+ )) : null
16735
16808
  ),
16736
- h2("p", null, mode === "queue" ? "\u5F53\u524D\u4EFB\u52A1\u7ED3\u675F\u540E\uFF0C\u518D\u5904\u7406\u65B0\u6D88\u606F\u3002\u53EF\u4F7F\u7528 /steer \u624B\u52A8\u63D2\u8BDD\u3002" : "\u5C06\u65B0\u7684\u7EAF\u6587\u5B57\u6D88\u606F\u4F5C\u4E3A\u8865\u5145\u6307\u4EE4\u52A0\u5165\u5F53\u524D\u4EFB\u52A1\uFF0CAgent \u5728\u4E0B\u4E00\u6B65\u8BFB\u53D6\u3002"),
16737
- h2("p", null, "\u6CA1\u6709\u6B63\u5728\u8FD0\u884C\u7684\u4EFB\u52A1\u65F6\uFF0C\u6B63\u5E38\u5F00\u59CB\u65B0\u4EFB\u52A1\u3002\u56FE\u7247\u3001\u6587\u4EF6\u3001\u8BED\u97F3\u548C\u5E26\u5F15\u7528\u7684\u6D88\u606F\u6309\u539F\u6709\u65B9\u5F0F\u5904\u7406\u3002"),
16738
- h2("button", {
16739
- type: "button",
16740
- className: "dim-deliveryButton",
16741
- "data-kind": "primary",
16742
- disabled: busy || savedMode === null || mode === savedMode,
16743
- onClick: () => void save()
16744
- }, busy ? "\u5904\u7406\u4E2D\u2026" : "\u4FDD\u5B58"),
16745
- savedMode === null && !busy ? h2("button", {
16746
- type: "button",
16747
- className: "dim-deliveryButton",
16748
- onClick: () => void load()
16749
- }, "\u91CD\u65B0\u8BFB\u53D6") : null,
16750
- feedback ? h2("p", { className: "dim-targetFeedback", role: feedback.error ? "alert" : "status" }, feedback.text) : null
16809
+ channel7 === "feishu" ? h2(
16810
+ "p",
16811
+ { className: "dim-botGeneralHelp dim-botGeneralPanelHelp", id: `${modeId}-panels-description` },
16812
+ "\u4EC5\u5BF9\u5B9E\u65F6\u8FC7\u7A0B\u5361\u751F\u6548\uFF0C\u4EFB\u52A1\u7ED3\u675F\u540E\u81EA\u52A8\u6536\u8D77\u3002"
16813
+ ) : null,
16814
+ feedback ? h2("p", {
16815
+ className: "dim-accessFeedback",
16816
+ "data-tone": "error",
16817
+ role: "alert"
16818
+ }, feedback) : null,
16819
+ savedSettings === null && !busy ? h2(
16820
+ "div",
16821
+ { className: "dim-botGeneralActions" },
16822
+ h2("button", {
16823
+ type: "button",
16824
+ className: "dim-deliveryButton",
16825
+ onClick: () => void load()
16826
+ }, "\u91CD\u65B0\u8BFB\u53D6")
16827
+ ) : null
16751
16828
  );
16752
16829
  }
16753
16830
 
@@ -17974,9 +18051,9 @@ var DELIVERY_ENDPOINTS = Object.freeze({
17974
18051
  test: "target.test"
17975
18052
  });
17976
18053
  var BOT_SETTINGS_TABS = Object.freeze([
18054
+ Object.freeze({ id: "general", label: "\u901A\u7528" }),
17977
18055
  Object.freeze({ id: "delivery", label: "\u6295\u9012\u8BBE\u7F6E" }),
17978
- Object.freeze({ id: "access", label: "\u8BBF\u95EE\u8BBE\u7F6E" }),
17979
- Object.freeze({ id: "general", label: "\u901A\u7528" })
18056
+ Object.freeze({ id: "access", label: "\u8BBF\u95EE\u8BBE\u7F6E" })
17980
18057
  ]);
17981
18058
  var FEISHU_BOT_SETTINGS_TABS = Object.freeze([
17982
18059
  ...BOT_SETTINGS_TABS,
@@ -18733,7 +18810,7 @@ function DeliveryTargetSettingsPage({
18733
18810
  role: "tabpanel",
18734
18811
  "aria-labelledby": activeTabDomId
18735
18812
  },
18736
- activeTab.id === "general" ? h2(BotGeneralSettingsPage, { key: account.botId, account, rpcCall: accessRpcCall }) : activeTab.id === "access" ? h2(AccessPolicySettingsPage, {
18813
+ activeTab.id === "general" ? h2(BotGeneralSettingsPage, { key: `${channel7}:${account.botId}`, channel: channel7, account, rpcCall: accessRpcCall }) : activeTab.id === "access" ? h2(AccessPolicySettingsPage, {
18737
18814
  channel: channel7,
18738
18815
  account: { ...account, accessPolicy },
18739
18816
  rpcCall: accessRpcCall,
@@ -20072,6 +20149,25 @@ var CSS15 = String.raw`
20072
20149
  .dim-accessFeedback[data-tone="success"] { color: var(--dsw-alias-state-success-primary, #20a162); }
20073
20150
  .dim-accessFeedback[data-tone="error"] { color: var(--dsw-alias-state-error-primary, #d54941); }
20074
20151
  .dim-accessActions { display: flex; justify-content: flex-end; }
20152
+ .dim-botGeneralSettings { min-width: 0; }
20153
+ .dim-botGeneralList { min-width: 0; display: grid; }
20154
+ .dim-botGeneralRow { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) max-content; align-items: center; gap: 24px; padding: 16px 0; border-bottom: 1px solid var(--dsw-alias-border-l2, #dfe1e5); }
20155
+ .dim-botGeneralRow:last-child { border-bottom: 0; }
20156
+ .dim-botGeneralPanelRow { border-bottom: 0; }
20157
+ .dim-botGeneralText { min-width: 0; display: grid; gap: 4px; }
20158
+ .dim-botGeneralTitle { color: var(--dsw-alias-label-primary, #1f2329); font-size: 14px; line-height: 22px; font-weight: 400; }
20159
+ .dim-botGeneralHelp { margin: 0; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 12px; line-height: 18px; overflow-wrap: anywhere; }
20160
+ .dim-botGeneralPanelHelp { padding-bottom: 16px; border-bottom: 1px solid var(--dsw-alias-border-l2, #dfe1e5); }
20161
+ .dim-botGeneralControl { position: relative; min-width: 0; max-width: 100%; justify-self: end; color: var(--dsw-alias-label-primary, #1f2329); }
20162
+ .dim-botGeneralControl select { display: block; min-width: 104px; max-width: 100%; height: 36px; padding: 0 36px 0 14px; border: 0; border-radius: 10px; color: inherit; background: var(--dsw-alias-bg-module-platform, #f5f6f7); font: inherit; font-size: 14px; line-height: 22px; appearance: none; cursor: pointer; }
20163
+ .dim-botGeneralControl select:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, #eef0f3); }
20164
+ .dim-botGeneralControl select:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 2px; }
20165
+ .dim-botGeneralControl select:disabled { opacity: .5; cursor: not-allowed; }
20166
+ .dim-botGeneralControl svg { position: absolute; top: 50%; right: 12px; transform: translateY(-50%); pointer-events: none; }
20167
+ .dim-botGeneralControl .dim-contextSwitch { display: block; }
20168
+ .dim-botGeneralControl .dim-contextSwitch:disabled { opacity: .5; cursor: not-allowed; }
20169
+ .dim-botGeneralControl .dim-contextSwitch:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 3px; }
20170
+ .dim-botGeneralActions { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 8px; padding-top: 16px; }
20075
20171
  .dim-generalSettingsPage { min-width: 0; display: grid; }
20076
20172
  .dim-generalSettingsHeader { min-width: 0; margin: 0 0 8px; }
20077
20173
  .dim-generalSettingsHeader h2 { margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 18px; line-height: 25px; font-weight: 680; }