@xmanrui/dsh-im 4.36.1 → 4.37.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.
Files changed (52) hide show
  1. package/README.en.md +14 -2
  2. package/README.md +13 -1
  3. package/lib/client.js +322 -190
  4. package/lib/index.js +314 -313
  5. package/package.json +2 -2
  6. package/plugin-src/client/bot-general-settings.js +83 -0
  7. package/plugin-src/client/channels/dingtalk/api.js +3 -1
  8. package/plugin-src/client/channels/feishu/api.js +3 -1
  9. package/plugin-src/client/channels/qq/api.js +3 -1
  10. package/plugin-src/client/channels/shared/token-api.js +3 -1
  11. package/plugin-src/client/channels/wecom/api.js +3 -1
  12. package/plugin-src/client/channels/wecom-app/api.js +3 -1
  13. package/plugin-src/client/channels/weixin/api.js +3 -1
  14. package/plugin-src/client/channels/whatsapp/api.js +3 -1
  15. package/plugin-src/client/delivery-settings.js +5 -1
  16. package/plugin-src/client/i18n.js +13 -0
  17. package/plugin-src/host/channels/dingtalk/rpc.mjs +11 -0
  18. package/plugin-src/host/channels/email/rpc.mjs +1 -0
  19. package/plugin-src/host/channels/feishu/rpc.mjs +13 -0
  20. package/plugin-src/host/channels/imessage/rpc.mjs +1 -0
  21. package/plugin-src/host/channels/matrix/rpc.mjs +10 -0
  22. package/plugin-src/host/channels/qq/rpc.mjs +11 -0
  23. package/plugin-src/host/channels/shared/rpc.mjs +9 -0
  24. package/plugin-src/host/channels/slack/rpc.mjs +10 -0
  25. package/plugin-src/host/channels/wecom/rpc.mjs +11 -0
  26. package/plugin-src/host/channels/wecom-app/rpc.mjs +10 -0
  27. package/plugin-src/host/channels/weixin/rpc.mjs +11 -0
  28. package/plugin-src/host/channels/whatsapp/rpc.mjs +11 -0
  29. package/src/channels/dingtalk/dingtalk-bridge.mjs +31 -2
  30. package/src/channels/dingtalk/dingtalk-menu.mjs +1 -1
  31. package/src/channels/dingtalk/dingtalk-runtime.mjs +2 -1
  32. package/src/channels/discord/discord-runtime.mjs +3 -1
  33. package/src/channels/feishu/bridge.mjs +69 -5
  34. package/src/channels/feishu/feishu-cards.mjs +8 -4
  35. package/src/channels/feishu/slash-command-panel.mjs +1 -0
  36. package/src/channels/qq/qq-bridge.mjs +40 -2
  37. package/src/channels/qq/qq-menu.mjs +2 -2
  38. package/src/channels/shared/bot-workspace-store.mjs +69 -1
  39. package/src/channels/shared/busy-message-dispatcher.mjs +94 -0
  40. package/src/channels/shared/clear-command.mjs +85 -0
  41. package/src/channels/shared/command-catalog.mjs +3 -0
  42. package/src/channels/shared/command-permission.mjs +2 -0
  43. package/src/channels/shared/control-command.mjs +20 -11
  44. package/src/channels/shared/i18n-en/feishu.mjs +6 -4
  45. package/src/channels/shared/i18n-en/qq.mjs +2 -1
  46. package/src/channels/shared/i18n-en/shared-b.mjs +27 -0
  47. package/src/channels/shared/message-mode.mjs +19 -0
  48. package/src/channels/shared/text-harness-bridge.mjs +48 -5
  49. package/src/channels/wecom/wecom-bridge.mjs +26 -2
  50. package/src/channels/wecom/wecom-cards.mjs +1 -1
  51. package/src/channels/wecom-app/wecom-app-bridge.mjs +26 -2
  52. package/src/channels/weixin/weixin-bridge.mjs +22 -2
package/lib/client.js CHANGED
@@ -590,12 +590,12 @@ async function callManagementRpc(connection, channel7, method, payload, signal)
590
590
  }
591
591
 
592
592
  // plugin-src/client/index.js
593
- var React39 = __toESM(require("react"), 1);
593
+ var React40 = __toESM(require("react"), 1);
594
594
 
595
595
  // package.json
596
596
  var package_default = {
597
597
  name: "@xmanrui/dsh-im",
598
- version: "4.36.1",
598
+ version: "4.37.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: [
@@ -729,7 +729,7 @@ var package_default = {
729
729
  },
730
730
  optionalDependencies: {
731
731
  "@tencent-qqmail/agently-cli": "^1.0.18",
732
- sharp: "0.35.4"
732
+ sharp: "0.35.5"
733
733
  }
734
734
  };
735
735
 
@@ -931,6 +931,12 @@ function EmailLogoGlyph({ size } = {}) {
931
931
  );
932
932
  }
933
933
 
934
+ // src/channels/shared/message-mode.mjs
935
+ var SET_MESSAGE_MODE_ENDPOINT = "bot.message-mode.set";
936
+ function normalizeBusyMessageMode(value) {
937
+ return value === "steer" ? "steer" : "queue";
938
+ }
939
+
934
940
  // plugin-src/client/connection-error.js
935
941
  var React3 = __toESM(require("react"), 1);
936
942
 
@@ -2168,6 +2174,19 @@ var EN = Object.freeze({
2168
2174
  "\u5C1A\u672A\u914D\u7F6E\u6295\u9012\u76EE\u6807": "No delivery targets yet",
2169
2175
  "\u70B9\u51FB\u201C\u65B0\u5EFA\u76EE\u6807\u201D\u53EF\u4ECE\u5DF2\u804A\u8FC7\u7684\u4F1A\u8BDD\u9009\u62E9\uFF0C\u4E5F\u53EF\u624B\u52A8\u586B\u5199\u3002": "Select New target to choose a conversation or enter the details manually.",
2170
2176
  "\u5168\u5C40\u8BBE\u7F6E": "Global settings",
2177
+ "\u901A\u7528": "General",
2178
+ "\u5904\u7406\u4E2D\u2026": "Processing\u2026",
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)",
2183
+ "\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.",
2188
+ "\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
+ "\u8BF7\u63D0\u4EA4\u6709\u6548\u7684\u6D88\u606F\u5904\u7406\u65B9\u5F0F\u3002": "Choose a valid message handling mode.",
2171
2190
  "\u901A\u7528\u8BBE\u7F6E": "General settings",
2172
2191
  "\u901A\u7528\u8BBE\u7F6E\u5206\u7C7B": "General settings categories",
2173
2192
  "\u9644\u4EF6": "Attachments",
@@ -3557,6 +3576,7 @@ var DINGTALK_ENDPOINTS = Object.freeze({
3557
3576
  setModel: SET_MODEL_ENDPOINT,
3558
3577
  setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
3559
3578
  setContextEnhancement: "bot.context-enhancement.set",
3579
+ setBusyMessageMode: "bot.message-mode.set",
3560
3580
  setAccessPolicy: "bot.access-policy.set",
3561
3581
  setAlias: "bot.alias.set"
3562
3582
  });
@@ -3705,6 +3725,7 @@ function normalizeBot(value) {
3705
3725
  workspace: optionalString(value.workspace, 4096) ?? "",
3706
3726
  model: normalizeModelSelection(value.model),
3707
3727
  agentPreset: normalizeAgentPresetId(value.agentPreset),
3728
+ busyMessageMode: normalizeBusyMessageMode(value.busyMessageMode),
3708
3729
  contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
3709
3730
  ...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
3710
3731
  bot: {
@@ -6533,6 +6554,7 @@ var TOKEN_BOT_ENDPOINTS = Object.freeze({
6533
6554
  setModel: SET_MODEL_ENDPOINT,
6534
6555
  setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
6535
6556
  setContextEnhancement: "bot.context-enhancement.set",
6557
+ setBusyMessageMode: "bot.message-mode.set",
6536
6558
  setAccessPolicy: "bot.access-policy.set",
6537
6559
  setAlias: "bot.alias.set",
6538
6560
  setThinkingTraces: "bot.thinking-traces.set"
@@ -6564,6 +6586,7 @@ function createTokenChannelApi(channel7, connectionSummary, {
6564
6586
  workspace: text2(value.workspace, "", 4096),
6565
6587
  model: normalizeModelSelection(value.model),
6566
6588
  agentPreset: normalizeAgentPresetId(value.agentPreset),
6589
+ busyMessageMode: normalizeBusyMessageMode(value.busyMessageMode),
6567
6590
  contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
6568
6591
  // Absent from the backend means ON; only an explicit false opts out.
6569
6592
  thinkingTraces: value.thinkingTraces !== false,
@@ -7256,6 +7279,7 @@ var SLASH_COMMAND_MANIFEST = Object.freeze([
7256
7279
  { command: "help", icon: "promptword_outlined", default: "\u67E5\u770B\u5E2E\u52A9", en_us: "Show help" },
7257
7280
  { command: "status", icon: "ai-functions_outlined", default: "\u67E5\u770B\u673A\u5668\u4EBA\u72B6\u6001", en_us: "Show bot status" },
7258
7281
  { command: "compact", icon: "ai-block_outlined", default: "\u538B\u7F29\u5F53\u524D\u4F1A\u8BDD\u4E0A\u4E0B\u6587", en_us: "Compact the current session" },
7282
+ { command: "clear", icon: "clear_outlined", default: "\u6E05\u7A7A\u5F53\u524D\u4F1A\u8BDD\u4E0A\u4E0B\u6587", en_us: "Clear the current session context" },
7259
7283
  { command: "sessionlist", icon: "chat-ai_outlined", default: "\u5217\u51FA\u4F1A\u8BDD", en_us: "List sessions" },
7260
7284
  { command: "workspacelist", icon: "folder_outlined", default: "\u5217\u51FA\u5DE5\u4F5C\u533A", en_us: "List workspaces" },
7261
7285
  { command: "workspaces", icon: "folder_outlined", default: "\u5217\u51FA\u5DE5\u4F5C\u533A", en_us: "List workspaces" },
@@ -7336,6 +7360,7 @@ var FEISHU_ENDPOINTS = Object.freeze({
7336
7360
  setModel: SET_MODEL_ENDPOINT,
7337
7361
  setAgentPreset: "bot.preset.set",
7338
7362
  setContextEnhancement: "bot.context-enhancement.set",
7363
+ setBusyMessageMode: "bot.message-mode.set",
7339
7364
  setAccessPolicy: "bot.access-policy.set",
7340
7365
  setAlias: "bot.alias.set",
7341
7366
  setGroupResponseMode: "bot.group-response-mode.set",
@@ -7494,6 +7519,7 @@ function normalizeBotConnection(value, fallbackBotId) {
7494
7519
  workspace: optionalString2(value.workspace)?.slice(0, 4096) ?? "",
7495
7520
  model: normalizeModelSelection(value.model),
7496
7521
  agentPreset: normalizeAgentPresetId(value.agentPreset),
7522
+ busyMessageMode: normalizeBusyMessageMode(value.busyMessageMode),
7497
7523
  contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
7498
7524
  ...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
7499
7525
  groupResponseMode: normalizeGroupResponseMode(value.groupResponseMode),
@@ -9747,6 +9773,7 @@ var QQ_ENDPOINTS = Object.freeze({
9747
9773
  setModel: SET_MODEL_ENDPOINT,
9748
9774
  setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
9749
9775
  setContextEnhancement: "bot.context-enhancement.set",
9776
+ setBusyMessageMode: "bot.message-mode.set",
9750
9777
  setAccessPolicy: "bot.access-policy.set",
9751
9778
  setAlias: "bot.alias.set"
9752
9779
  });
@@ -9816,6 +9843,7 @@ function normalizeBot3(value) {
9816
9843
  workspace: text3(value.workspace, "", 4096),
9817
9844
  model: normalizeModelSelection(value.model),
9818
9845
  agentPreset: normalizeAgentPresetId(value.agentPreset),
9846
+ busyMessageMode: normalizeBusyMessageMode(value.busyMessageMode),
9819
9847
  contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
9820
9848
  ...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
9821
9849
  bot: {
@@ -11266,6 +11294,7 @@ var WECOM_ENDPOINTS = Object.freeze({
11266
11294
  setModel: SET_MODEL_ENDPOINT,
11267
11295
  setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
11268
11296
  setContextEnhancement: "bot.context-enhancement.set",
11297
+ setBusyMessageMode: "bot.message-mode.set",
11269
11298
  setAccessPolicy: "bot.access-policy.set",
11270
11299
  setAlias: "bot.alias.set"
11271
11300
  });
@@ -11341,6 +11370,7 @@ function normalizeBot4(value) {
11341
11370
  workspace: text4(value.workspace, "", 4096),
11342
11371
  model: normalizeModelSelection(value.model),
11343
11372
  agentPreset: normalizeAgentPresetId(value.agentPreset),
11373
+ busyMessageMode: normalizeBusyMessageMode(value.busyMessageMode),
11344
11374
  contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
11345
11375
  ...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
11346
11376
  bot: {
@@ -12136,6 +12166,7 @@ var WECOM_APP_ENDPOINTS = Object.freeze({
12136
12166
  setModel: SET_MODEL_ENDPOINT,
12137
12167
  setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
12138
12168
  setContextEnhancement: "bot.context-enhancement.set",
12169
+ setBusyMessageMode: "bot.message-mode.set",
12139
12170
  setAccessPolicy: "bot.access-policy.set",
12140
12171
  setAlias: "bot.alias.set"
12141
12172
  });
@@ -12187,6 +12218,7 @@ function normalizeBot5(value) {
12187
12218
  workspace: text5(value.workspace, "", 4096),
12188
12219
  model: normalizeModelSelection(value.model),
12189
12220
  agentPreset: normalizeAgentPresetId(value.agentPreset),
12221
+ busyMessageMode: normalizeBusyMessageMode(value.busyMessageMode),
12190
12222
  contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
12191
12223
  ...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
12192
12224
  bot: {
@@ -12999,6 +13031,7 @@ var WEIXIN_ENDPOINTS = Object.freeze({
12999
13031
  setModel: SET_MODEL_ENDPOINT,
13000
13032
  setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
13001
13033
  setContextEnhancement: "bot.context-enhancement.set",
13034
+ setBusyMessageMode: "bot.message-mode.set",
13002
13035
  setAccessPolicy: "bot.access-policy.set",
13003
13036
  setAlias: "bot.alias.set"
13004
13037
  });
@@ -13111,6 +13144,7 @@ function normalizeBot6(value) {
13111
13144
  workspace: string(value.workspace).slice(0, 4096),
13112
13145
  model: normalizeModelSelection(value.model),
13113
13146
  agentPreset: normalizeAgentPresetId(value.agentPreset),
13147
+ busyMessageMode: normalizeBusyMessageMode(value.busyMessageMode),
13114
13148
  contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
13115
13149
  ...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
13116
13150
  bot: {
@@ -14178,7 +14212,8 @@ var WHATSAPP_ENDPOINTS = Object.freeze({
14178
14212
  setWorkspace: "bot.workspace.set",
14179
14213
  setModel: SET_MODEL_ENDPOINT,
14180
14214
  setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
14181
- setContextEnhancement: "bot.context-enhancement.set"
14215
+ setContextEnhancement: "bot.context-enhancement.set",
14216
+ setBusyMessageMode: "bot.message-mode.set"
14182
14217
  });
14183
14218
  var PROVISION_STATES5 = /* @__PURE__ */ new Set(["starting", "pending", "connecting", "connected", "failed", "cancelled"]);
14184
14219
  var BOT_STATES = /* @__PURE__ */ new Set(["connected", "connecting", "offline", "error"]);
@@ -14247,6 +14282,7 @@ function normalizeBot7(value) {
14247
14282
  workspace: text6(value.workspace, "", 4096),
14248
14283
  model: normalizeModelSelection(value.model),
14249
14284
  agentPreset: normalizeAgentPresetId(value.agentPreset),
14285
+ busyMessageMode: normalizeBusyMessageMode(value.busyMessageMode),
14250
14286
  contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
14251
14287
  ...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
14252
14288
  bot: {
@@ -16202,7 +16238,7 @@ function installInterfaceLanguageMirror(ctx, {
16202
16238
  }
16203
16239
 
16204
16240
  // plugin-src/client/delivery-settings.js
16205
- var React34 = __toESM(require("react"), 1);
16241
+ var React35 = __toESM(require("react"), 1);
16206
16242
 
16207
16243
  // plugin-src/client/access-policy-settings.js
16208
16244
  var React28 = __toESM(require("react"), 1);
@@ -16620,8 +16656,103 @@ function AccessPolicySettingsPage({ channel: channel7, account, rpcCall, onSaved
16620
16656
  );
16621
16657
  }
16622
16658
 
16623
- // plugin-src/client/bot-settings-tabs.js
16659
+ // plugin-src/client/bot-general-settings.js
16624
16660
  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");
16663
+ const bot = result.value?.bots?.find((entry) => entry.botId === botId);
16664
+ if (!bot) throw new Error("\u627E\u4E0D\u5230\u8981\u4FEE\u6539\u7684\u673A\u5668\u4EBA\u3002");
16665
+ return normalizeBusyMessageMode(bot.busyMessageMode);
16666
+ }
16667
+ function BotGeneralSettingsPage({ account, rpcCall }) {
16668
+ const [mode, setMode] = React29.useState("queue");
16669
+ const [savedMode, setSavedMode] = React29.useState(null);
16670
+ const [busy, setBusy] = React29.useState(false);
16671
+ const [feedback, setFeedback] = React29.useState(null);
16672
+ const mounted = React29.useRef(false);
16673
+ const load = React29.useCallback(async () => {
16674
+ setBusy(true);
16675
+ setFeedback(null);
16676
+ try {
16677
+ const value = modeFromResult(await rpcCall("connection.status", {}), account.botId);
16678
+ if (!mounted.current) return;
16679
+ setMode(value);
16680
+ setSavedMode(value);
16681
+ } catch (error) {
16682
+ if (mounted.current) setFeedback({ error: true, text: error.message });
16683
+ } finally {
16684
+ if (mounted.current) setBusy(false);
16685
+ }
16686
+ }, [account.botId, rpcCall]);
16687
+ React29.useEffect(() => {
16688
+ mounted.current = true;
16689
+ void load();
16690
+ return () => {
16691
+ mounted.current = false;
16692
+ };
16693
+ }, [load]);
16694
+ const save = async () => {
16695
+ setBusy(true);
16696
+ setFeedback(null);
16697
+ try {
16698
+ const value = modeFromResult(await rpcCall(SET_MESSAGE_MODE_ENDPOINT, {
16699
+ botId: account.botId,
16700
+ busyMessageMode: mode
16701
+ }), account.botId);
16702
+ 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" });
16706
+ } catch (error) {
16707
+ if (mounted.current) setFeedback({ error: true, text: error.message });
16708
+ } finally {
16709
+ if (mounted.current) setBusy(false);
16710
+ }
16711
+ };
16712
+ return h2(
16713
+ "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"),
16717
+ h2(
16718
+ "label",
16719
+ { className: "dim-accessField" },
16720
+ h2("span", null, "\u4EFB\u52A1\u8FD0\u884C\u65F6\u7684\u65B0\u6D88\u606F\u5904\u7406\u65B9\u5F0F"),
16721
+ 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
+ )
16735
+ ),
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
16751
+ );
16752
+ }
16753
+
16754
+ // plugin-src/client/bot-settings-tabs.js
16755
+ var React30 = __toESM(require("react"), 1);
16625
16756
  function revealTab(strip, tab) {
16626
16757
  if (!strip || !tab) return;
16627
16758
  const viewport = strip.getBoundingClientRect();
@@ -16630,11 +16761,11 @@ function revealTab(strip, tab) {
16630
16761
  else if (bounds.right > viewport.right) strip.scrollLeft += bounds.right - viewport.right;
16631
16762
  }
16632
16763
  function BotSettingsTabs({ tabs, activeTabId, onChange }) {
16633
- const barRef = React29.useRef(null);
16634
- const stripRef = React29.useRef(null);
16635
- const listRef = React29.useRef(null);
16636
- const [scroll, setScroll] = React29.useState({ overflow: false, left: false, right: false });
16637
- const measure = React29.useCallback(() => {
16764
+ const barRef = React30.useRef(null);
16765
+ const stripRef = React30.useRef(null);
16766
+ const listRef = React30.useRef(null);
16767
+ const [scroll, setScroll] = React30.useState({ overflow: false, left: false, right: false });
16768
+ const measure = React30.useCallback(() => {
16638
16769
  const bar = barRef.current;
16639
16770
  const strip = stripRef.current;
16640
16771
  const list = listRef.current;
@@ -16647,7 +16778,7 @@ function BotSettingsTabs({ tabs, activeTabId, onChange }) {
16647
16778
  };
16648
16779
  setScroll((previous) => Object.keys(next).every((key) => next[key] === previous[key]) ? previous : next);
16649
16780
  }, []);
16650
- React29.useEffect(() => {
16781
+ React30.useEffect(() => {
16651
16782
  const strip = stripRef.current;
16652
16783
  if (!strip) return void 0;
16653
16784
  const refresh = () => {
@@ -16737,7 +16868,7 @@ function BotSettingsTabs({ tabs, activeTabId, onChange }) {
16737
16868
  }
16738
16869
 
16739
16870
  // plugin-src/client/channels/feishu/group-settings.js
16740
- var React30 = __toESM(require("react"), 1);
16871
+ var React31 = __toESM(require("react"), 1);
16741
16872
  var GROUP_MESSAGE_PERMISSION_OPERATION2 = FEISHU_REGISTRATION_OPERATIONS.GROUP_MESSAGE_PERMISSION;
16742
16873
  function SettingsButton({ children, kind = "secondary", className = "", ...props }) {
16743
16874
  return h2("button", {
@@ -16798,9 +16929,9 @@ function GroupResponseModeEditor({
16798
16929
  onAuthorize
16799
16930
  }) {
16800
16931
  const current = normalizeGroupResponseMode(value);
16801
- const [saving, setSaving] = React30.useState(false);
16802
- const [authorizing, setAuthorizing] = React30.useState(false);
16803
- const [error, setError] = React30.useState(null);
16932
+ const [saving, setSaving] = React31.useState(false);
16933
+ const [authorizing, setAuthorizing] = React31.useState(false);
16934
+ const [error, setError] = React31.useState(null);
16804
16935
  const change = async (event) => {
16805
16936
  const next = normalizeGroupResponseMode(event.target.value);
16806
16937
  if (next === current || saving || disabled) return;
@@ -16881,8 +17012,8 @@ function GroupResponseModeEditor({
16881
17012
  }
16882
17013
  function MentionTopicReplyEditor({ value = true, disabled = false, onSave }) {
16883
17014
  const current = value === true ? "on" : "off";
16884
- const [saving, setSaving] = React30.useState(false);
16885
- const [error, setError] = React30.useState(null);
17015
+ const [saving, setSaving] = React31.useState(false);
17016
+ const [error, setError] = React31.useState(null);
16886
17017
  const change = async (event) => {
16887
17018
  const next = event.target.value === "on";
16888
17019
  if ((next ? "on" : "off") === current || saving || disabled) return;
@@ -17069,14 +17200,14 @@ function PermissionFlow({ provision, now, busy, botName, onRetry, onCancel, onCl
17069
17200
  );
17070
17201
  }
17071
17202
  function FeishuGroupSettingsPage({ account, rpcCall }) {
17072
- const [settings, setSettings] = React30.useState(() => groupSettingsFrom(account));
17073
- const [refreshing, setRefreshing] = React30.useState(false);
17074
- const [refreshError, setRefreshError] = React30.useState(null);
17075
- const [provision, setProvision] = React30.useState(null);
17076
- const [provisionBusy, setProvisionBusy] = React30.useState(false);
17077
- const [now, setNow] = React30.useState(() => Date.now());
17078
- const mounted = React30.useRef(true);
17079
- React30.useEffect(() => {
17203
+ const [settings, setSettings] = React31.useState(() => groupSettingsFrom(account));
17204
+ const [refreshing, setRefreshing] = React31.useState(false);
17205
+ const [refreshError, setRefreshError] = React31.useState(null);
17206
+ const [provision, setProvision] = React31.useState(null);
17207
+ const [provisionBusy, setProvisionBusy] = React31.useState(false);
17208
+ const [now, setNow] = React31.useState(() => Date.now());
17209
+ const mounted = React31.useRef(true);
17210
+ React31.useEffect(() => {
17080
17211
  setSettings(groupSettingsFrom(account));
17081
17212
  }, [
17082
17213
  account.botId,
@@ -17084,22 +17215,22 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
17084
17215
  account.mentionTopicReply,
17085
17216
  account.groupMessagePermissionGranted
17086
17217
  ]);
17087
- React30.useEffect(() => {
17218
+ React31.useEffect(() => {
17088
17219
  mounted.current = true;
17089
17220
  return () => {
17090
17221
  mounted.current = false;
17091
17222
  };
17092
17223
  }, []);
17093
- const invoke = React30.useCallback(async (endpoint, payload = {}, signal) => {
17224
+ const invoke = React31.useCallback(async (endpoint, payload = {}, signal) => {
17094
17225
  if (typeof rpcCall !== "function") throw new Error("\u98DE\u4E66\u7FA4\u804A\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
17095
17226
  return unwrapRpcResult3(await rpcCall(endpoint, payload, signal));
17096
17227
  }, [rpcCall]);
17097
- const applySnapshot = React30.useCallback((value) => {
17228
+ const applySnapshot = React31.useCallback((value) => {
17098
17229
  const result = targetBotFromSnapshot(value, account.botId);
17099
17230
  if (mounted.current) setSettings(groupSettingsFrom(result.bot));
17100
17231
  return result;
17101
17232
  }, [account.botId]);
17102
- const loadSettings = React30.useCallback(async ({ signal, restoreProvisioning = false } = {}) => {
17233
+ const loadSettings = React31.useCallback(async ({ signal, restoreProvisioning = false } = {}) => {
17103
17234
  setRefreshing(true);
17104
17235
  setRefreshError(null);
17105
17236
  try {
@@ -17128,16 +17259,16 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
17128
17259
  if (!signal?.aborted && mounted.current) setRefreshing(false);
17129
17260
  }
17130
17261
  }, [account.botId, applySnapshot, invoke]);
17131
- React30.useEffect(() => {
17262
+ React31.useEffect(() => {
17132
17263
  const controller = new AbortController();
17133
17264
  void loadSettings({ signal: controller.signal, restoreProvisioning: true });
17134
17265
  return () => controller.abort();
17135
17266
  }, [loadSettings]);
17136
- const saveSetting = React30.useCallback(async (endpoint, payload) => {
17267
+ const saveSetting = React31.useCallback(async (endpoint, payload) => {
17137
17268
  const value = await invoke(endpoint, { botId: account.botId, ...payload });
17138
17269
  applySnapshot(value);
17139
17270
  }, [account.botId, applySnapshot, invoke]);
17140
- const startAuthorization = React30.useCallback(async ({ replace = false } = {}) => {
17271
+ const startAuthorization = React31.useCallback(async ({ replace = false } = {}) => {
17141
17272
  if (provisionBusy) return;
17142
17273
  const previousAttemptId = provision?.attemptId;
17143
17274
  setProvisionBusy(true);
@@ -17178,13 +17309,13 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
17178
17309
  if (mounted.current) setProvisionBusy(false);
17179
17310
  }
17180
17311
  }, [account.botId, invoke, provision?.attemptId, provisionBusy]);
17181
- const finishAuthorization = React30.useCallback(async (signal) => {
17312
+ const finishAuthorization = React31.useCallback(async (signal) => {
17182
17313
  const bot = await loadSettings({ signal, restoreProvisioning: false });
17183
17314
  if (signal?.aborted || !mounted.current) return;
17184
17315
  if (!bot) throw new Error("\u7FA4\u6D88\u606F\u6743\u9650\u5DF2\u66F4\u65B0\uFF0C\u4F46\u6682\u65F6\u65E0\u6CD5\u786E\u8BA4\u673A\u5668\u4EBA\u8FDE\u63A5\u72B6\u6001");
17185
17316
  setProvision(null);
17186
17317
  }, [loadSettings]);
17187
- React30.useEffect(() => {
17318
+ React31.useEffect(() => {
17188
17319
  if (!provision?.attemptId || !["qr", "connecting"].includes(provision.phase) || provision.expired) return void 0;
17189
17320
  const timerHost = globalThis.window ?? globalThis;
17190
17321
  const controller = new AbortController();
@@ -17228,7 +17359,7 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
17228
17359
  timerHost.clearTimeout(timer);
17229
17360
  };
17230
17361
  }, [account.botId, finishAuthorization, invoke, provision]);
17231
- React30.useEffect(() => {
17362
+ React31.useEffect(() => {
17232
17363
  if (!provision?.attemptId || provision.phase !== "qr" || provision.expired) return void 0;
17233
17364
  const timerHost = globalThis.window ?? globalThis;
17234
17365
  const tick = () => {
@@ -17242,7 +17373,7 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
17242
17373
  const timer = timerHost.setInterval(tick, 1e3);
17243
17374
  return () => timerHost.clearInterval(timer);
17244
17375
  }, [provision?.attemptId, provision?.expired, provision?.expiresAt, provision?.phase]);
17245
- const cancelAuthorization = React30.useCallback(async () => {
17376
+ const cancelAuthorization = React31.useCallback(async () => {
17246
17377
  if (!provision?.attemptId || provisionBusy) {
17247
17378
  setProvision(null);
17248
17379
  return;
@@ -17331,21 +17462,21 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
17331
17462
  }
17332
17463
 
17333
17464
  // plugin-src/client/channels/feishu/voice-settings.js
17334
- var React32 = __toESM(require("react"), 1);
17465
+ var React33 = __toESM(require("react"), 1);
17335
17466
 
17336
17467
  // plugin-src/client/channels/feishu/voice-editor.js
17337
- var React31 = __toESM(require("react"), 1);
17468
+ var React32 = __toESM(require("react"), 1);
17338
17469
  function VoiceEditor({ value = null, disabled = false, onSave }) {
17339
- const [enabled, setEnabled] = React31.useState(value != null);
17340
- const [secretRef, setSecretRef] = React31.useState(value?.secretRef ?? "DASHSCOPE_API_KEY");
17341
- const [asrModel, setAsrModel] = React31.useState(value?.asrModel ?? "qwen3-asr-flash");
17342
- const [ttsModel, setTtsModel] = React31.useState(value?.ttsModel ?? "qwen3-tts-flash");
17343
- const [ttsVoice, setTtsVoice] = React31.useState(value?.ttsVoice ?? "Momo");
17344
- const [saving, setSaving] = React31.useState(false);
17345
- const [error, setError] = React31.useState(null);
17346
- const titleId = React31.useId();
17470
+ const [enabled, setEnabled] = React32.useState(value != null);
17471
+ const [secretRef, setSecretRef] = React32.useState(value?.secretRef ?? "DASHSCOPE_API_KEY");
17472
+ const [asrModel, setAsrModel] = React32.useState(value?.asrModel ?? "qwen3-asr-flash");
17473
+ const [ttsModel, setTtsModel] = React32.useState(value?.ttsModel ?? "qwen3-tts-flash");
17474
+ const [ttsVoice, setTtsVoice] = React32.useState(value?.ttsVoice ?? "Momo");
17475
+ const [saving, setSaving] = React32.useState(false);
17476
+ const [error, setError] = React32.useState(null);
17477
+ const titleId = React32.useId();
17347
17478
  const helpId = `${titleId}-help`;
17348
- React31.useEffect(() => {
17479
+ React32.useEffect(() => {
17349
17480
  setEnabled(value != null);
17350
17481
  if (value) {
17351
17482
  setSecretRef(value.secretRef ?? "DASHSCOPE_API_KEY");
@@ -17459,20 +17590,20 @@ function VoiceEditor({ value = null, disabled = false, onSave }) {
17459
17590
 
17460
17591
  // plugin-src/client/channels/feishu/voice-settings.js
17461
17592
  function FeishuVoiceSettingsPage({ account, rpcCall }) {
17462
- const [voice, setVoice] = React32.useState(null);
17463
- const [phase, setPhase] = React32.useState("loading");
17464
- const [error, setError] = React32.useState(null);
17465
- const mounted = React32.useRef(true);
17466
- const invoke = React32.useCallback(async (endpoint, payload, signal) => {
17593
+ const [voice, setVoice] = React33.useState(null);
17594
+ const [phase, setPhase] = React33.useState("loading");
17595
+ const [error, setError] = React33.useState(null);
17596
+ const mounted = React33.useRef(true);
17597
+ const invoke = React33.useCallback(async (endpoint, payload, signal) => {
17467
17598
  if (typeof rpcCall !== "function") throw new Error("\u98DE\u4E66\u8BED\u97F3\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
17468
17599
  return unwrapRpcResult3(await rpcCall(endpoint, payload, signal));
17469
17600
  }, [rpcCall]);
17470
- const applySnapshot = React32.useCallback((value) => {
17601
+ const applySnapshot = React33.useCallback((value) => {
17471
17602
  const bot = normalizeBotsSnapshot(value).bots.find((entry) => entry.botId === account.botId);
17472
17603
  if (!bot) throw new Error("\u672A\u627E\u5230\u5F53\u524D\u98DE\u4E66\u673A\u5668\u4EBA\uFF0C\u8BF7\u8FD4\u56DE\u5217\u8868\u540E\u91CD\u8BD5\u3002");
17473
17604
  if (mounted.current) setVoice(bot.voice);
17474
17605
  }, [account.botId]);
17475
- const loadSettings = React32.useCallback(async (signal) => {
17606
+ const loadSettings = React33.useCallback(async (signal) => {
17476
17607
  setPhase("loading");
17477
17608
  setError(null);
17478
17609
  try {
@@ -17486,7 +17617,7 @@ function FeishuVoiceSettingsPage({ account, rpcCall }) {
17486
17617
  setPhase("error");
17487
17618
  }
17488
17619
  }, [applySnapshot, invoke]);
17489
- React32.useEffect(() => {
17620
+ React33.useEffect(() => {
17490
17621
  mounted.current = true;
17491
17622
  const controller = new AbortController();
17492
17623
  void loadSettings(controller.signal);
@@ -17525,7 +17656,7 @@ function FeishuVoiceSettingsPage({ account, rpcCall }) {
17525
17656
  }
17526
17657
 
17527
17658
  // plugin-src/client/channels/feishu/slash-panel-settings.js
17528
- var React33 = __toESM(require("react"), 1);
17659
+ var React34 = __toESM(require("react"), 1);
17529
17660
  var MANIFEST_BY_NAME = new Map(SLASH_COMMAND_MANIFEST.map((entry) => [entry.command, entry]));
17530
17661
  var ALL_COMMANDS = Object.freeze(SLASH_COMMAND_MANIFEST.map((entry) => entry.command));
17531
17662
  function PanelButton({ children, disabled = false, onClick, ...props }) {
@@ -17546,30 +17677,30 @@ function commandText(name2) {
17546
17677
  return `/${name2} \u2014 ${entry?.default ?? name2}`;
17547
17678
  }
17548
17679
  function FeishuSlashPanelSettingsPage({ account, rpcCall, onSaved }) {
17549
- const incoming = React33.useMemo(() => normalizeSlashPanelConfig(account.slashPanel), [account.botId, panelSignature(account.slashPanel)]);
17550
- const [mode, setMode] = React33.useState(incoming.mode);
17551
- const [order, setOrder] = React33.useState(() => [...incoming.order]);
17552
- const [pending, setPending] = React33.useState("");
17553
- const [dirty, setDirty] = React33.useState(false);
17554
- const [saving, setSaving] = React33.useState(false);
17555
- const [saved, setSaved] = React33.useState(false);
17556
- const [syncing, setSyncing] = React33.useState(false);
17557
- const [syncTargets, setSyncTargets] = React33.useState(null);
17558
- const [syncNotice, setSyncNotice] = React33.useState(null);
17559
- const [error, setError] = React33.useState(null);
17560
- const mounted = React33.useRef(true);
17561
- React33.useEffect(() => {
17680
+ const incoming = React34.useMemo(() => normalizeSlashPanelConfig(account.slashPanel), [account.botId, panelSignature(account.slashPanel)]);
17681
+ const [mode, setMode] = React34.useState(incoming.mode);
17682
+ const [order, setOrder] = React34.useState(() => [...incoming.order]);
17683
+ const [pending, setPending] = React34.useState("");
17684
+ const [dirty, setDirty] = React34.useState(false);
17685
+ const [saving, setSaving] = React34.useState(false);
17686
+ const [saved, setSaved] = React34.useState(false);
17687
+ const [syncing, setSyncing] = React34.useState(false);
17688
+ const [syncTargets, setSyncTargets] = React34.useState(null);
17689
+ const [syncNotice, setSyncNotice] = React34.useState(null);
17690
+ const [error, setError] = React34.useState(null);
17691
+ const mounted = React34.useRef(true);
17692
+ React34.useEffect(() => {
17562
17693
  mounted.current = true;
17563
17694
  return () => {
17564
17695
  mounted.current = false;
17565
17696
  };
17566
17697
  }, []);
17567
- React33.useEffect(() => {
17698
+ React34.useEffect(() => {
17568
17699
  if (dirty) return;
17569
17700
  setMode(incoming.mode);
17570
17701
  setOrder([...incoming.order]);
17571
17702
  }, [incoming.mode, incoming.order, dirty]);
17572
- const edit = React33.useCallback((update) => {
17703
+ const edit = React34.useCallback((update) => {
17573
17704
  setSaved(false);
17574
17705
  setDirty(true);
17575
17706
  update();
@@ -17706,7 +17837,7 @@ function FeishuSlashPanelSettingsPage({ account, rpcCall, onSaved }) {
17706
17837
  h2("option", { value: SLASH_PANEL_MODES.CUSTOM }, "\u81EA\u5B9A\u4E49\uFF08\u81EA\u5DF1\u6311\u6307\u4EE4\u548C\u987A\u5E8F\uFF09")
17707
17838
  ),
17708
17839
  mode === SLASH_PANEL_MODES.CUSTOM ? h2(
17709
- React33.Fragment,
17840
+ React34.Fragment,
17710
17841
  null,
17711
17842
  order.length === 0 ? h2("p", { className: "dim-feishuGroupHelp" }, "\u5F53\u524D\u6CA1\u6709\u9009\u62E9\u4EFB\u4F55\u6307\u4EE4\uFF0C\u4FDD\u5B58\u540E\u300C/\u300D\u9762\u677F\u4F1A\u53D8\u6210\u7A7A\u7684\u3002") : h2(
17712
17843
  "ul",
@@ -17844,7 +17975,8 @@ var DELIVERY_ENDPOINTS = Object.freeze({
17844
17975
  });
17845
17976
  var BOT_SETTINGS_TABS = Object.freeze([
17846
17977
  Object.freeze({ id: "delivery", label: "\u6295\u9012\u8BBE\u7F6E" }),
17847
- Object.freeze({ id: "access", label: "\u8BBF\u95EE\u8BBE\u7F6E" })
17978
+ Object.freeze({ id: "access", label: "\u8BBF\u95EE\u8BBE\u7F6E" }),
17979
+ Object.freeze({ id: "general", label: "\u901A\u7528" })
17848
17980
  ]);
17849
17981
  var FEISHU_BOT_SETTINGS_TABS = Object.freeze([
17850
17982
  ...BOT_SETTINGS_TABS,
@@ -18062,13 +18194,13 @@ function TargetForm({
18062
18194
  }) {
18063
18195
  const editing = mode === "edit";
18064
18196
  const initialKind = initialValue?.kind && definition.fields[initialValue.kind] ? initialValue.kind : definition.kinds[0].value;
18065
- const [targetId, setTargetId] = React34.useState(initialValue?.targetId ?? "");
18066
- const [name2, setName] = React34.useState(initialValue?.name ?? "");
18067
- const [kind, setKind] = React34.useState(initialKind);
18068
- const [route, setRoute] = React34.useState(initialValue?.route ?? {});
18069
- const [error, setError] = React34.useState(null);
18070
- const [testing, setTesting] = React34.useState(false);
18071
- const [testState, setTestState] = React34.useState(null);
18197
+ const [targetId, setTargetId] = React35.useState(initialValue?.targetId ?? "");
18198
+ const [name2, setName] = React35.useState(initialValue?.name ?? "");
18199
+ const [kind, setKind] = React35.useState(initialKind);
18200
+ const [route, setRoute] = React35.useState(initialValue?.route ?? {});
18201
+ const [error, setError] = React35.useState(null);
18202
+ const [testing, setTesting] = React35.useState(false);
18203
+ const [testState, setTestState] = React35.useState(null);
18072
18204
  const currentTarget = () => {
18073
18205
  const normalizedRoute = Object.fromEntries(fieldsFor(definition, kind).map((field2) => {
18074
18206
  const raw = String(route[field2.key] ?? "").trim();
@@ -18285,7 +18417,7 @@ function TargetSuggestionPicker({
18285
18417
  suggestions.map((suggestion, index) => {
18286
18418
  const identity = routeIdentity(definition, suggestion);
18287
18419
  const added = configured.has(identity);
18288
- return React34.createElement("option", {
18420
+ return React35.createElement("option", {
18289
18421
  key: suggestion.id ?? suggestion.suggestionId ?? `${identity}:${index}`,
18290
18422
  value: String(index),
18291
18423
  disabled: added
@@ -18302,11 +18434,11 @@ function TargetSuggestionPicker({
18302
18434
  );
18303
18435
  }
18304
18436
  function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, onEdit }) {
18305
- const [action, setAction] = React34.useState(null);
18306
- const [testState, setTestState] = React34.useState(null);
18307
- const [syncFeedback, setSyncFeedback] = React34.useState(null);
18308
- const [copyState, setCopyState] = React34.useState(null);
18309
- const [confirmDelete, setConfirmDelete] = React34.useState(false);
18437
+ const [action, setAction] = React35.useState(null);
18438
+ const [testState, setTestState] = React35.useState(null);
18439
+ const [syncFeedback, setSyncFeedback] = React35.useState(null);
18440
+ const [copyState, setCopyState] = React35.useState(null);
18441
+ const [confirmDelete, setConfirmDelete] = React35.useState(false);
18310
18442
  const sessionSync = target.sessionSync ?? { enabled: false, state: "unavailable" };
18311
18443
  const syncDescription = sessionSync.state === "active" ? "\u81EA\u52A8\u8DDF\u968F\u8BE5\u79C1\u804A\u7684\u5F53\u524D\u4F1A\u8BDD" : sessionSync.state === "waiting" ? "\u7B49\u5F85\u8BE5\u79C1\u804A\u5EFA\u7ACB\u65B0\u4F1A\u8BDD" : sessionSync.state === "unavailable" ? "\u4EC5\u652F\u6301\u5DF2\u7ECF\u804A\u8FC7\u3001\u5DF2\u5EFA\u7ACB\u5F53\u524D\u4F1A\u8BDD\u4E14\u4F7F\u7528\u5F53\u524D Host Harness \u7684\u79C1\u804A\u76EE\u6807" : "\u5173\u95ED\u65F6\u4E0D\u53D1\u9001 DSH \u4F1A\u8BDD\u6D88\u606F";
18312
18444
  const testTarget = async () => {
@@ -18369,7 +18501,7 @@ function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, o
18369
18501
  h2(
18370
18502
  "div",
18371
18503
  { className: "dim-targetTitle" },
18372
- React34.createElement("strong", null, target.name || target.targetId),
18504
+ React35.createElement("strong", null, target.name || target.targetId),
18373
18505
  h2("span", null, kindLabel(definition, target.kind))
18374
18506
  ),
18375
18507
  h2("code", null, `targetId: ${target.targetId}`)
@@ -18455,30 +18587,30 @@ function DeliveryTargetSettingsPage({
18455
18587
  onBack
18456
18588
  }) {
18457
18589
  const definition = CHANNEL_DEFINITIONS[channel7];
18458
- const [activeTabId, setActiveTabId] = React34.useState(BOT_SETTINGS_TABS[0].id);
18459
- const [phase, setPhase] = React34.useState("loading");
18460
- const [targets, setTargets] = React34.useState([]);
18461
- const [suggestionPhase, setSuggestionPhase] = React34.useState("idle");
18462
- const [suggestions, setSuggestions] = React34.useState([]);
18463
- const [suggestionError, setSuggestionError] = React34.useState(null);
18464
- const [error, setError] = React34.useState(null);
18465
- const [editor, setEditor] = React34.useState(null);
18466
- const [saving, setSaving] = React34.useState(false);
18467
- const [botCopyState, setBotCopyState] = React34.useState(null);
18468
- const [accessPolicy, setAccessPolicy] = React34.useState(account.accessPolicy);
18469
- const [slashPanel, setSlashPanel] = React34.useState(account.slashPanel);
18470
- const mounted = React34.useRef(true);
18471
- React34.useEffect(() => {
18590
+ const [activeTabId, setActiveTabId] = React35.useState(BOT_SETTINGS_TABS[0].id);
18591
+ const [phase, setPhase] = React35.useState("loading");
18592
+ const [targets, setTargets] = React35.useState([]);
18593
+ const [suggestionPhase, setSuggestionPhase] = React35.useState("idle");
18594
+ const [suggestions, setSuggestions] = React35.useState([]);
18595
+ const [suggestionError, setSuggestionError] = React35.useState(null);
18596
+ const [error, setError] = React35.useState(null);
18597
+ const [editor, setEditor] = React35.useState(null);
18598
+ const [saving, setSaving] = React35.useState(false);
18599
+ const [botCopyState, setBotCopyState] = React35.useState(null);
18600
+ const [accessPolicy, setAccessPolicy] = React35.useState(account.accessPolicy);
18601
+ const [slashPanel, setSlashPanel] = React35.useState(account.slashPanel);
18602
+ const mounted = React35.useRef(true);
18603
+ React35.useEffect(() => {
18472
18604
  setAccessPolicy(account.accessPolicy);
18473
18605
  }, [account.botId, account.accessPolicy]);
18474
- React34.useEffect(() => {
18606
+ React35.useEffect(() => {
18475
18607
  setSlashPanel(account.slashPanel);
18476
18608
  }, [account.botId, account.slashPanel]);
18477
- const invoke = React34.useCallback(async (endpoint, payload = {}, signal) => {
18609
+ const invoke = React35.useCallback(async (endpoint, payload = {}, signal) => {
18478
18610
  if (typeof rpcCall !== "function") throw new Error("\u6295\u9012\u76EE\u6807\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
18479
18611
  return unwrapRpcResult15(await rpcCall(endpoint, payload, signal));
18480
18612
  }, [rpcCall]);
18481
- const loadTargets = React34.useCallback(async ({ signal, silent = false } = {}) => {
18613
+ const loadTargets = React35.useCallback(async ({ signal, silent = false } = {}) => {
18482
18614
  if (!silent) setPhase("loading");
18483
18615
  setError(null);
18484
18616
  try {
@@ -18492,7 +18624,7 @@ function DeliveryTargetSettingsPage({
18492
18624
  setPhase("error");
18493
18625
  }
18494
18626
  }, [account.botId, invoke]);
18495
- const loadSuggestions = React34.useCallback(async () => {
18627
+ const loadSuggestions = React35.useCallback(async () => {
18496
18628
  setSuggestionPhase("loading");
18497
18629
  setSuggestionError(null);
18498
18630
  try {
@@ -18506,7 +18638,7 @@ function DeliveryTargetSettingsPage({
18506
18638
  setSuggestionPhase("error");
18507
18639
  }
18508
18640
  }, [account.botId, definition, invoke]);
18509
- React34.useEffect(() => {
18641
+ React35.useEffect(() => {
18510
18642
  mounted.current = true;
18511
18643
  const controller = new AbortController();
18512
18644
  void loadTargets({ signal: controller.signal });
@@ -18601,7 +18733,7 @@ function DeliveryTargetSettingsPage({
18601
18733
  role: "tabpanel",
18602
18734
  "aria-labelledby": activeTabDomId
18603
18735
  },
18604
- activeTab.id === "access" ? h2(AccessPolicySettingsPage, {
18736
+ activeTab.id === "general" ? h2(BotGeneralSettingsPage, { key: account.botId, account, rpcCall: accessRpcCall }) : activeTab.id === "access" ? h2(AccessPolicySettingsPage, {
18605
18737
  channel: channel7,
18606
18738
  account: { ...account, accessPolicy },
18607
18739
  rpcCall: accessRpcCall,
@@ -18618,7 +18750,7 @@ function DeliveryTargetSettingsPage({
18618
18750
  account,
18619
18751
  rpcCall: accessRpcCall
18620
18752
  }) : h2(
18621
- React34.Fragment,
18753
+ React35.Fragment,
18622
18754
  null,
18623
18755
  h2(
18624
18756
  "section",
@@ -18729,7 +18861,7 @@ function DeliveryTargetSettingsPage({
18729
18861
  }
18730
18862
 
18731
18863
  // plugin-src/client/global-settings.js
18732
- var React35 = __toESM(require("react"), 1);
18864
+ var React36 = __toESM(require("react"), 1);
18733
18865
 
18734
18866
  // src/channels/shared/inbound-ttl.mjs
18735
18867
  var DEFAULT_INBOUND_TTL_HOURS = 168;
@@ -18814,14 +18946,14 @@ function GlobalButton({ children, kind = "secondary", className = "", ...props }
18814
18946
  }, children);
18815
18947
  }
18816
18948
  function ImageInputSettings({ rpcCall }) {
18817
- const [values, setValues] = React35.useState(DEFAULT_IMAGE_INPUT_SETTINGS);
18818
- const [phase, setPhase] = React35.useState("loading");
18819
- const [error, setError] = React35.useState(null);
18820
- const [saved, setSaved] = React35.useState(false);
18821
- const mounted = React35.useRef(false);
18822
- const saving = React35.useRef(false);
18823
- const id6 = React35.useId();
18824
- const load = React35.useCallback(async (signal) => {
18949
+ const [values, setValues] = React36.useState(DEFAULT_IMAGE_INPUT_SETTINGS);
18950
+ const [phase, setPhase] = React36.useState("loading");
18951
+ const [error, setError] = React36.useState(null);
18952
+ const [saved, setSaved] = React36.useState(false);
18953
+ const mounted = React36.useRef(false);
18954
+ const saving = React36.useRef(false);
18955
+ const id6 = React36.useId();
18956
+ const load = React36.useCallback(async (signal) => {
18825
18957
  setPhase("loading");
18826
18958
  setError(null);
18827
18959
  try {
@@ -18837,7 +18969,7 @@ function ImageInputSettings({ rpcCall }) {
18837
18969
  setPhase("error");
18838
18970
  }
18839
18971
  }, [rpcCall]);
18840
- React35.useEffect(() => {
18972
+ React36.useEffect(() => {
18841
18973
  mounted.current = true;
18842
18974
  const controller = new AbortController();
18843
18975
  void load(controller.signal);
@@ -18944,29 +19076,29 @@ function ImageInputSettings({ rpcCall }) {
18944
19076
  );
18945
19077
  }
18946
19078
  function GlobalSettingsPanel({ rpcCall }) {
18947
- const [phase, setPhase] = React35.useState("loading");
18948
- const [loadError, setLoadError] = React35.useState(null);
18949
- const [ttlInput, setTtlInput] = React35.useState("");
18950
- const [savedTtl, setSavedTtl] = React35.useState(null);
18951
- const [ttlError, setTtlError] = React35.useState(false);
18952
- const [saveError, setSaveError] = React35.useState(null);
18953
- const [saveSucceeded, setSaveSucceeded] = React35.useState(false);
18954
- const [isSaving, setIsSaving] = React35.useState(false);
18955
- const [sweepConfirming, setSweepConfirming] = React35.useState(false);
18956
- const [sweeping, setSweeping] = React35.useState(false);
18957
- const ttlErrorId = React35.useId();
18958
- const ttlHintsId = React35.useId();
18959
- const sweepTriggerId = React35.useId();
18960
- const sweepConfirmId = React35.useId();
18961
- const sweepConfirmTextId = React35.useId();
18962
- const sweepConfirmButtonId = React35.useId();
18963
- const mounted = React35.useRef(true);
18964
- const saving = React35.useRef(false);
18965
- const invoke = React35.useCallback(async (endpoint, payload = {}, signal) => {
19079
+ const [phase, setPhase] = React36.useState("loading");
19080
+ const [loadError, setLoadError] = React36.useState(null);
19081
+ const [ttlInput, setTtlInput] = React36.useState("");
19082
+ const [savedTtl, setSavedTtl] = React36.useState(null);
19083
+ const [ttlError, setTtlError] = React36.useState(false);
19084
+ const [saveError, setSaveError] = React36.useState(null);
19085
+ const [saveSucceeded, setSaveSucceeded] = React36.useState(false);
19086
+ const [isSaving, setIsSaving] = React36.useState(false);
19087
+ const [sweepConfirming, setSweepConfirming] = React36.useState(false);
19088
+ const [sweeping, setSweeping] = React36.useState(false);
19089
+ const ttlErrorId = React36.useId();
19090
+ const ttlHintsId = React36.useId();
19091
+ const sweepTriggerId = React36.useId();
19092
+ const sweepConfirmId = React36.useId();
19093
+ const sweepConfirmTextId = React36.useId();
19094
+ const sweepConfirmButtonId = React36.useId();
19095
+ const mounted = React36.useRef(true);
19096
+ const saving = React36.useRef(false);
19097
+ const invoke = React36.useCallback(async (endpoint, payload = {}, signal) => {
18966
19098
  if (typeof rpcCall !== "function") throw new Error("\u901A\u7528\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
18967
19099
  return unwrapRpcResult16(await rpcCall(endpoint, payload, signal));
18968
19100
  }, [rpcCall]);
18969
- const loadSettings = React35.useCallback(async ({ signal } = {}) => {
19101
+ const loadSettings = React36.useCallback(async ({ signal } = {}) => {
18970
19102
  setPhase("loading");
18971
19103
  setLoadError(null);
18972
19104
  try {
@@ -18990,7 +19122,7 @@ function GlobalSettingsPanel({ rpcCall }) {
18990
19122
  setPhase("error");
18991
19123
  }
18992
19124
  }, [invoke]);
18993
- React35.useEffect(() => {
19125
+ React36.useEffect(() => {
18994
19126
  mounted.current = true;
18995
19127
  const controller = new AbortController();
18996
19128
  void loadSettings({ signal: controller.signal });
@@ -18999,7 +19131,7 @@ function GlobalSettingsPanel({ rpcCall }) {
18999
19131
  controller.abort();
19000
19132
  };
19001
19133
  }, [loadSettings]);
19002
- React35.useEffect(() => {
19134
+ React36.useEffect(() => {
19003
19135
  if (!sweepConfirming) return;
19004
19136
  globalThis.document?.getElementById(sweepConfirmButtonId)?.focus();
19005
19137
  }, [sweepConfirmButtonId, sweepConfirming]);
@@ -20334,7 +20466,7 @@ function installSessionChannelLogos(document2 = globalThis.document) {
20334
20466
  }
20335
20467
 
20336
20468
  // plugin-src/client/update-panel.js
20337
- var React36 = __toESM(require("react"), 1);
20469
+ var React37 = __toESM(require("react"), 1);
20338
20470
  var import_react_dom4 = require("react-dom");
20339
20471
  var import_valid = __toESM(require_valid(), 1);
20340
20472
  var import_rcompare = __toESM(require_rcompare(), 1);
@@ -20427,11 +20559,11 @@ function manualUpdateCommand(snapshot) {
20427
20559
  return `dsh plugin --profile ${profileArgument} add -w @xmanrui/dsh-im@${version}`;
20428
20560
  }
20429
20561
  function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
20430
- const [copyState, setCopyState] = React36.useState("idle");
20431
- const commandRef = React36.useRef(null);
20432
- const mounted = React36.useRef(false);
20433
- const copying = React36.useRef(false);
20434
- React36.useEffect(() => {
20562
+ const [copyState, setCopyState] = React37.useState("idle");
20563
+ const commandRef = React37.useRef(null);
20564
+ const mounted = React37.useRef(false);
20565
+ const copying = React37.useRef(false);
20566
+ React37.useEffect(() => {
20435
20567
  mounted.current = true;
20436
20568
  return () => {
20437
20569
  mounted.current = false;
@@ -20463,7 +20595,7 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
20463
20595
  { className: "dim-updateManual", "aria-label": "\u624B\u5DE5\u66F4\u65B0" },
20464
20596
  h2("h4", { className: "dim-updateManualHeading" }, "\u624B\u5DE5\u66F4\u65B0"),
20465
20597
  command ? h2(
20466
- React36.Fragment,
20598
+ React37.Fragment,
20467
20599
  null,
20468
20600
  h2("p", { className: "dim-updateManualHint" }, "\u81EA\u52A8\u66F4\u65B0\u5931\u8D25\u53EF\u4EE5\u4F7F\u7528\u547D\u4EE4\u66F4\u65B0\uFF1A"),
20469
20601
  h2(
@@ -20499,7 +20631,7 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
20499
20631
  "aria-hidden": "true",
20500
20632
  focusable: "false"
20501
20633
  }, copyState === "copied" ? h2("path", { d: "m4 10 4 4 8-8" }) : h2(
20502
- React36.Fragment,
20634
+ React37.Fragment,
20503
20635
  null,
20504
20636
  h2("rect", { x: 7, y: 7, width: 10, height: 11, rx: 1.5 }),
20505
20637
  h2("path", { d: "M5 13H3.5A1.5 1.5 0 0 1 2 11.5v-8A1.5 1.5 0 0 1 3.5 2h8A1.5 1.5 0 0 1 13 3.5V5" })
@@ -20524,10 +20656,10 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
20524
20656
  );
20525
20657
  }
20526
20658
  function UpdateDialog({ children, onClose }) {
20527
- const dialogRef = React36.useRef(null);
20528
- const titleId = React36.useId();
20529
- const descriptionId = React36.useId();
20530
- React36.useEffect(() => {
20659
+ const dialogRef = React37.useRef(null);
20660
+ const titleId = React37.useId();
20661
+ const descriptionId = React37.useId();
20662
+ React37.useEffect(() => {
20531
20663
  const previous = globalThis.document?.activeElement;
20532
20664
  dialogRef.current?.focus?.();
20533
20665
  return () => {
@@ -20585,20 +20717,20 @@ function UpdateDialog({ children, onClose }) {
20585
20717
  return typeof document !== "undefined" && document.body ? (0, import_react_dom4.createPortal)(content, document.body) : content;
20586
20718
  }
20587
20719
  function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
20588
- const tooltipId = React36.useId();
20589
- const [snapshot, setSnapshot] = React36.useState(null);
20590
- const [action, setAction] = React36.useState("status");
20591
- const [error, setError] = React36.useState(null);
20592
- const [open, setOpen] = React36.useState(false);
20593
- const [uncertainInstall, setUncertainInstall] = React36.useState(false);
20594
- const mounted = React36.useRef(false);
20595
- const busy = React36.useRef(false);
20596
- const readController = React36.useRef(null);
20597
- const pollReadController = React36.useRef(null);
20598
- const installRequest = React36.useRef(null);
20599
- const onStatusRef = React36.useRef(onStatus);
20720
+ const tooltipId = React37.useId();
20721
+ const [snapshot, setSnapshot] = React37.useState(null);
20722
+ const [action, setAction] = React37.useState("status");
20723
+ const [error, setError] = React37.useState(null);
20724
+ const [open, setOpen] = React37.useState(false);
20725
+ const [uncertainInstall, setUncertainInstall] = React37.useState(false);
20726
+ const mounted = React37.useRef(false);
20727
+ const busy = React37.useRef(false);
20728
+ const readController = React37.useRef(null);
20729
+ const pollReadController = React37.useRef(null);
20730
+ const installRequest = React37.useRef(null);
20731
+ const onStatusRef = React37.useRef(onStatus);
20600
20732
  onStatusRef.current = onStatus;
20601
- const accept = React36.useCallback((next) => {
20733
+ const accept = React37.useCallback((next) => {
20602
20734
  setSnapshot(next);
20603
20735
  onStatusRef.current?.(next);
20604
20736
  }, []);
@@ -20607,7 +20739,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
20607
20739
  setUncertainInstall(false);
20608
20740
  accept(next);
20609
20741
  };
20610
- const invoke = React36.useCallback(async (endpoint, payload = {}, signal) => {
20742
+ const invoke = React37.useCallback(async (endpoint, payload = {}, signal) => {
20611
20743
  if (typeof rpcCall !== "function") {
20612
20744
  const unavailable = new Error("\u5F53\u524D Host \u4E0D\u652F\u6301\u66F4\u65B0\u63A5\u53E3\uFF0C\u8BF7\u5148\u624B\u52A8\u66F4\u65B0\u63D2\u4EF6\u5E76\u91CD\u542F\u3002");
20613
20745
  unavailable.code = "update-unavailable";
@@ -20615,7 +20747,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
20615
20747
  }
20616
20748
  return unwrapSnapshot(await rpcCall(endpoint, payload, signal));
20617
20749
  }, [rpcCall]);
20618
- React36.useEffect(() => {
20750
+ React37.useEffect(() => {
20619
20751
  mounted.current = true;
20620
20752
  busy.current = true;
20621
20753
  const controller = new AbortController();
@@ -20638,7 +20770,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
20638
20770
  const activeJob = ACTIVE_STATES4.has(snapshot?.job?.state);
20639
20771
  const restartRequired = snapshot?.job?.state === "restart-required" || snapshot?.blockedReason === "pending-restart";
20640
20772
  const shouldPoll = activeJob || uncertainInstall;
20641
- React36.useEffect(() => {
20773
+ React37.useEffect(() => {
20642
20774
  if (!shouldPoll) return void 0;
20643
20775
  let controller;
20644
20776
  const scheduler = createPollScheduler({
@@ -20739,7 +20871,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
20739
20871
  const buttonLabel = action === "checking" ? "\u68C0\u67E5\u4E2D\u2026" : action === "starting" || activeJob ? "\u6B63\u5728\u66F4\u65B0\u2026" : restartRequired ? "\u5F85\u624B\u52A8\u91CD\u542F" : snapshot?.canInstall ? "\u66F4\u65B0\u81F3" : "\u68C0\u67E5\u66F4\u65B0";
20740
20872
  const buttonDescription = localizeText(buttonLabel) + (buttonLabel === "\u66F4\u65B0\u81F3" ? ` v${snapshot.latestVersion}` : "");
20741
20873
  return h2(
20742
- React36.Fragment,
20874
+ React37.Fragment,
20743
20875
  null,
20744
20876
  h2(
20745
20877
  "span",
@@ -20789,25 +20921,25 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
20789
20921
  h2("dt", null, "\u8FD0\u884C\u7248\u672C"),
20790
20922
  h2("dd", null, `v${snapshot?.runningVersion ?? clientVersion}`),
20791
20923
  snapshot?.installedVersion && snapshot.installedVersion !== snapshot.runningVersion ? h2(
20792
- React36.Fragment,
20924
+ React37.Fragment,
20793
20925
  null,
20794
20926
  h2("dt", null, "\u5DF2\u5B89\u88C5\u7248\u672C"),
20795
20927
  h2("dd", null, `v${snapshot.installedVersion}`)
20796
20928
  ) : null,
20797
20929
  targetVersion ? h2(
20798
- React36.Fragment,
20930
+ React37.Fragment,
20799
20931
  null,
20800
20932
  h2("dt", null, "\u76EE\u6807\u7248\u672C"),
20801
20933
  h2("dd", null, `v${targetVersion}`)
20802
20934
  ) : null,
20803
20935
  latestVersion ? h2(
20804
- React36.Fragment,
20936
+ React37.Fragment,
20805
20937
  null,
20806
20938
  h2("dt", null, "\u6700\u65B0\u7248\u672C"),
20807
20939
  h2("dd", null, `v${latestVersion}`)
20808
20940
  ) : null,
20809
20941
  historicalTargetVersion ? h2(
20810
- React36.Fragment,
20942
+ React37.Fragment,
20811
20943
  null,
20812
20944
  h2("dt", null, "\u4E0A\u6B21\u66F4\u65B0\u76EE\u6807"),
20813
20945
  h2("dd", null, `v${historicalTargetVersion}`)
@@ -20889,8 +21021,8 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
20889
21021
  }
20890
21022
 
20891
21023
  // plugin-src/client/panel-error-boundary.js
20892
- var React37 = __toESM(require("react"), 1);
20893
- var IMPanelErrorBoundary = class extends React37.Component {
21024
+ var React38 = __toESM(require("react"), 1);
21025
+ var IMPanelErrorBoundary = class extends React38.Component {
20894
21026
  state = { failed: false };
20895
21027
  static getDerivedStateFromError() {
20896
21028
  return { failed: true };
@@ -20910,9 +21042,9 @@ var IMPanelErrorBoundary = class extends React37.Component {
20910
21042
  };
20911
21043
 
20912
21044
  // plugin-src/client/plugin-page.js
20913
- var React38 = __toESM(require("react"), 1);
21045
+ var React39 = __toESM(require("react"), 1);
20914
21046
  var IM_MAIN_PANEL_ID = "xmanrui-dsh-im";
20915
- var h3 = React38.createElement;
21047
+ var h3 = React39.createElement;
20916
21048
  function OpenImAction({ subject, packageName, onOpen, t }) {
20917
21049
  if (subject?.kind !== "bundle" && subject?.kind !== "row") return null;
20918
21050
  if (subject.pkg?.name !== packageName) return null;
@@ -21143,28 +21275,28 @@ function IMSettingsTab({
21143
21275
  browserLocation = globalThis.location,
21144
21276
  navigateToRecoveryUrl = replacePageLocation
21145
21277
  }) {
21146
- const [selected, setSelected] = React39.useState(() => preferredSectionId === GLOBAL_SETTINGS_TAB_ID || CHANNELS.some((channel7) => channel7.id === preferredSectionId) ? preferredSectionId : "weixin");
21147
- const [loopbackRecovery, setLoopbackRecovery] = React39.useState(null);
21148
- const [runningVersion, setRunningVersion] = React39.useState(IM_PLUGIN_VERSION);
21149
- const [deliverySettings, setDeliverySettings] = React39.useState(null);
21278
+ const [selected, setSelected] = React40.useState(() => preferredSectionId === GLOBAL_SETTINGS_TAB_ID || CHANNELS.some((channel7) => channel7.id === preferredSectionId) ? preferredSectionId : "weixin");
21279
+ const [loopbackRecovery, setLoopbackRecovery] = React40.useState(null);
21280
+ const [runningVersion, setRunningVersion] = React40.useState(IM_PLUGIN_VERSION);
21281
+ const [deliverySettings, setDeliverySettings] = React40.useState(null);
21150
21282
  const emailEnabled = useEmailChannelEnabled(emailRpcCall);
21151
- const visibleChannels = React39.useMemo(
21283
+ const visibleChannels = React40.useMemo(
21152
21284
  () => CHANNELS.filter((channel7) => channel7.id !== "email" || emailEnabled),
21153
21285
  [emailEnabled]
21154
21286
  );
21155
- const githubTooltipId = React39.useId();
21156
- const generalSettingsTooltipId = React39.useId();
21287
+ const githubTooltipId = React40.useId();
21288
+ const generalSettingsTooltipId = React40.useId();
21157
21289
  const globalSettingsSelected = selected === GLOBAL_SETTINGS_TAB_ID;
21158
21290
  const active = visibleChannels.find((channel7) => channel7.id === selected) ?? visibleChannels[0];
21159
21291
  const activeTabId = globalSettingsSelected ? "dim-general-settings-trigger" : `dim-tab-${active.id}`;
21160
21292
  const activePanelId = globalSettingsSelected ? `dim-panel-${GLOBAL_SETTINGS_TAB_ID}` : `dim-panel-${active.id}`;
21161
- const reportLoopbackRecovery = React39.useCallback((recovery) => {
21293
+ const reportLoopbackRecovery = React40.useCallback((recovery) => {
21162
21294
  setLoopbackRecovery((current) => current?.url === recovery.url ? current : recovery);
21163
21295
  }, []);
21164
- const reportUpdateStatus = React39.useCallback((snapshot) => {
21296
+ const reportUpdateStatus = React40.useCallback((snapshot) => {
21165
21297
  setRunningVersion(snapshot.runningVersion);
21166
21298
  }, []);
21167
- const rpcCalls = React39.useMemo(() => createLoopbackAwareRpcCalls({
21299
+ const rpcCalls = React40.useMemo(() => createLoopbackAwareRpcCalls({
21168
21300
  dingtalkRpcCall,
21169
21301
  discordRpcCall,
21170
21302
  feishuRpcCall,
@@ -21206,7 +21338,7 @@ function IMSettingsTab({
21206
21338
  weixinRpcCall,
21207
21339
  whatsappRpcCall
21208
21340
  ]);
21209
- const botSettingsContext = React39.useMemo(() => Object.freeze({
21341
+ const botSettingsContext = React40.useMemo(() => Object.freeze({
21210
21342
  openBotSettings: setDeliverySettings
21211
21343
  }), []);
21212
21344
  return h2(
@@ -21430,7 +21562,7 @@ function apply(ctx) {
21430
21562
  };
21431
21563
  const localeSnapshot = () => ctx.locale.getLocale?.()?.active ?? "";
21432
21564
  function IMPanel({ preferredSectionId }) {
21433
- React39.useSyncExternalStore(subscribeLocale, localeSnapshot, localeSnapshot);
21565
+ React40.useSyncExternalStore(subscribeLocale, localeSnapshot, localeSnapshot);
21434
21566
  return h2(
21435
21567
  IMPanelErrorBoundary,
21436
21568
  null,