@xmanrui/dsh-im 4.23.0 → 4.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.en.md +7 -2
  2. package/README.md +7 -2
  3. package/lib/client.js +498 -347
  4. package/lib/index.js +284 -283
  5. package/package.json +11 -2
  6. package/plugin-src/client/channel-card-meta.js +3 -9
  7. package/plugin-src/client/channels/dingtalk/index.js +9 -8
  8. package/plugin-src/client/channels/feishu/index.js +21 -17
  9. package/plugin-src/client/channels/qq/index.js +9 -8
  10. package/plugin-src/client/channels/shared/collapsible-account.js +49 -26
  11. package/plugin-src/client/channels/shared/token-api.js +3 -0
  12. package/plugin-src/client/channels/shared/token-channel.js +9 -8
  13. package/plugin-src/client/channels/telegram/index.js +3 -0
  14. package/plugin-src/client/channels/telegram/styles.js +12 -0
  15. package/plugin-src/client/channels/telegram/thinking-traces.js +25 -0
  16. package/plugin-src/client/channels/wecom/index.js +9 -8
  17. package/plugin-src/client/channels/wecom-app/index.js +9 -8
  18. package/plugin-src/client/channels/weixin/index.js +9 -8
  19. package/plugin-src/client/channels/whatsapp/index.js +9 -8
  20. package/plugin-src/client/i18n.js +13 -1
  21. package/plugin-src/client/index.js +10 -2
  22. package/plugin-src/client/styles.js +12 -8
  23. package/plugin-src/client/update-panel.js +18 -8
  24. package/plugin-src/host/channels/shared/rpc.mjs +9 -0
  25. package/plugin-src/host/channels/shared/thinking-traces-rpc.mjs +11 -0
  26. package/plugin-src/host/modern-harness-api.mjs +7 -2
  27. package/plugin-src/host/update-service.mjs +19 -14
  28. package/scripts/verify-package.mjs +11 -5
  29. package/src/channels/email/email-runtime.mjs +9 -2
  30. package/src/channels/email/transports/agent-mail.mjs +14 -3
  31. package/src/channels/feishu/bridge.mjs +122 -46
  32. package/src/channels/feishu/feishu-channel.mjs +35 -0
  33. package/src/channels/feishu/live-cot.mjs +260 -0
  34. package/src/channels/feishu/slash-command-registry.mjs +17 -0
  35. package/src/channels/feishu/step-push-mode.mjs +10 -4
  36. package/src/channels/shared/harness-client.mjs +224 -39
  37. package/src/channels/shared/text-harness-bridge.mjs +60 -14
  38. package/src/channels/shared/workspace-session.mjs +7 -1
  39. package/src/channels/telegram/config-store.mjs +4 -1
  40. package/src/channels/telegram/telegram-controller.mjs +13 -1
  41. package/src/channels/telegram/telegram-runtime.mjs +198 -1
package/lib/client.js CHANGED
@@ -595,7 +595,7 @@ var React33 = __toESM(require("react"), 1);
595
595
  // package.json
596
596
  var package_default = {
597
597
  name: "@xmanrui/dsh-im",
598
- version: "4.23.0",
598
+ version: "4.24.1",
599
599
  description: "\u628A\u5341\u4E00\u79CD IM \u6E20\u9053\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect eleven IM channels and a public AI Office to a local DeepSeek Harness.",
600
600
  keywords: [
601
601
  "deepseek-harness",
@@ -675,6 +675,10 @@ var package_default = {
675
675
  {
676
676
  name: "wings1848",
677
677
  url: "https://github.com/wings1848"
678
+ },
679
+ {
680
+ name: "Zhe (Phil) Yang",
681
+ url: "https://github.com/yangzhe1991"
678
682
  }
679
683
  ],
680
684
  license: "MIT",
@@ -705,7 +709,12 @@ var package_default = {
705
709
  "cordis.patch.yml",
706
710
  "lib",
707
711
  "plugin-src",
708
- "scripts",
712
+ "scripts/verify-interface-language.mjs",
713
+ "scripts/verify-lan-management.mjs",
714
+ "scripts/verify-model-setting.mjs",
715
+ "scripts/verify-package.mjs",
716
+ "scripts/verify-session-channel-logos.mjs",
717
+ "scripts/verify-session-title-prefix.mjs",
709
718
  "src",
710
719
  "PROACTIVE_DELIVERY.md",
711
720
  "PROACTIVE_DELIVERY.en.md",
@@ -1227,6 +1236,8 @@ var EN = Object.freeze({
1227
1236
  "IM\u673A\u5668\u4EBA\u8BBE\u7F6E": "IM bot settings",
1228
1237
  "IM \u9762\u677F\u52A0\u8F7D\u5931\u8D25": "Could not load the IM panel",
1229
1238
  "\u66F4\u591A\u673A\u5668\u4EBA\u8BBE\u7F6E": "More bot settings",
1239
+ "\u66F4\u591A\u8BBE\u7F6E": "More settings",
1240
+ "\u5E38\u7528\u914D\u7F6E": "Common settings",
1230
1241
  "\u673A\u5668\u4EBA\u8BBE\u7F6E": "Bot settings",
1231
1242
  "\u673A\u5668\u4EBA\u8BBE\u7F6E\u9875\u7B7E": "Bot settings tabs",
1232
1243
  "\u6295\u9012\u8BBE\u7F6E": "Delivery settings",
@@ -1312,6 +1323,8 @@ var EN = Object.freeze({
1312
1323
  "\u5DF2\u5B89\u88C5\u7248\u672C": "Installed version",
1313
1324
  "\u76EE\u6807 profile": "Target profile",
1314
1325
  "\u76EE\u6807\u7248\u672C": "Target version",
1326
+ "\u6700\u65B0\u7248\u672C": "Latest version",
1327
+ "\u4E0A\u6B21\u66F4\u65B0\u76EE\u6807": "Previous update target",
1315
1328
  "\u65E0\u6CD5\u786E\u8BA4": "Unknown",
1316
1329
  "\u53D1\u73B0\u65B0\u7248\u672C": "Update available",
1317
1330
  "\u5DF2\u662F\u6700\u65B0\u7248\u672C": "Up to date",
@@ -1325,6 +1338,7 @@ var EN = Object.freeze({
1325
1338
  "\u66F4\u65B0\u5DF2\u751F\u6548": "Updated version is active",
1326
1339
  "\u66F4\u65B0\u5931\u8D25": "Update failed",
1327
1340
  "\u66F4\u65B0\u8BF7\u6C42\u5931\u8D25": "Update request failed",
1341
+ "\u6682\u65F6\u65E0\u6CD5\u5B89\u88C5\u66F4\u65B0": "Update installation is unavailable",
1328
1342
  "\u4EC5\u66F4\u65B0 DSH-IM\u3002\u5B89\u88C5\u5B8C\u6210\u540E\u9700\u624B\u52A8\u91CD\u542F\u540E\u53F0\uFF1B\u672C\u529F\u80FD\u4E0D\u4F1A\u81EA\u52A8\u91CD\u542F\u6216\u4E3B\u52A8\u5237\u65B0\u9875\u9762\u3002": "Only DSH-IM will be updated. Restart the backend manually after installation. This feature does not automatically restart it or initiate a page refresh.",
1329
1343
  "\u5F53\u524D\u662F\u6E90\u7801\u6216\u94FE\u63A5\u5B89\u88C5\uFF0C\u53EA\u80FD\u68C0\u67E5\u7248\u672C\uFF1B\u8BF7\u624B\u52A8\u66F4\u65B0\u6E90\u7801\uFF0C\u6216\u8FC1\u79FB\u5230 npm \u5B89\u88C5\u3002": "This is a source or linked installation. You can check versions, but must update the source manually or migrate to an npm installation.",
1330
1344
  "\u65E0\u6CD5\u786E\u8BA4\u5F53\u524D profile\uFF0C\u8BF7\u5728\u5BF9\u5E94\u7684 Harness \u73AF\u5883\u4E2D\u624B\u52A8\u66F4\u65B0\u3002": "The current profile could not be identified. Update manually in the corresponding Harness environment.",
@@ -1444,11 +1458,13 @@ var EN = Object.freeze({
1444
1458
  "\u67E5\u770B\u5206\u6B65\u76F4\u63A8\u8BF4\u660E": "View step push help",
1445
1459
  "\u5F00\u542F\u540E\u9010\u6B65\u63A8\u9001\u5DE5\u5177\u8C03\u7528\u4E0E\u8FC7\u7A0B\u8BF4\u660E": "Push tool calls and process notes step by step",
1446
1460
  "\u4EFB\u52A1\u8FC7\u7A0B\u5C55\u793A": "Task progress display",
1447
- "\u8BBE\u7F6E\u4EFB\u52A1\u6267\u884C\u8FC7\u7A0B\u7684\u5448\u73B0\u65B9\u5F0F\uFF1A\u4E0D\u663E\u793A\u3001\u5B9E\u65F6\u5361\u7247\u6216\u9010\u6B65\u6D88\u606F": "Choose how the execution is presented: hidden, one live card, or step-by-step messages",
1461
+ "\u8BBE\u7F6E\u4EFB\u52A1\u6267\u884C\u8FC7\u7A0B\u7684\u5448\u73B0\u65B9\u5F0F\uFF1A\u4E0D\u663E\u793A\u3001\u539F\u751F\u76F4\u64AD\u3001\u5B9E\u65F6\u5361\u7247\u6216\u9010\u6B65\u6D88\u606F": "Choose how execution is presented: hidden, native live process, one live card, or step-by-step messages",
1448
1462
  "\u4E0D\u663E\u793A\u8FC7\u7A0B\uFF08\u53EA\u53D1\u9001\u6700\u7EC8\u7B54\u6848\uFF09": "Hide the process (send the final answer only)",
1463
+ "\u5B9E\u65F6\u76F4\u64AD\uFF08\u98DE\u4E66\u539F\u751F\u601D\u8003\u8FC7\u7A0B\uFF09": "Live process (native Feishu thinking process)",
1449
1464
  "\u5B9E\u65F6\u8FC7\u7A0B\u5361\uFF08\u5168\u7A0B\u4E00\u5F20\u5361\u7247\u52A8\u6001\u66F4\u65B0\uFF09": "Live process card (one card updated throughout)",
1450
1465
  "\u9010\u6B65\u76F4\u64AD\uFF08\u6BCF\u4E00\u6B65\u5355\u72EC\u53D1\u4E00\u6761\u6D88\u606F\uFF09": "Step-by-step feed (one message per step)",
1451
1466
  "\u9002\u5408\u65E5\u5E38\u95EE\u7B54\uFF1A\u6267\u884C\u8FC7\u7A0B\u4E2D\u4E0D\u663E\u793A\u5DE5\u5177\u8C03\u7528\u7B49\u4E2D\u95F4\u6B65\u9AA4\uFF0C\u53EA\u56DE\u590D\u6700\u7EC8\u7ED3\u679C": "For everyday Q&A: tool calls and other interim steps stay hidden, only the final result is replied",
1467
+ "\u4F7F\u7528\u98DE\u4E66\u539F\u751F\u601D\u8003\u8FC7\u7A0B\u5C55\u793A\u63A8\u7406\u3001\u5DE5\u5177\u8C03\u7528\u4E0E\u7ED3\u679C\uFF0C\u6700\u7EC8\u7B54\u6848\u5355\u72EC\u53D1\u9001": "Use Feishu\u2019s native thinking process for reasoning, tool calls, and results, then send the final answer separately",
1452
1468
  "\u63A8\u8350\u957F\u4EFB\u52A1\u4F7F\u7528\uFF1A\u8FC7\u7A0B\u4E0E\u6700\u7EC8\u7B54\u6848\u90FD\u5728\u540C\u4E00\u5F20\u5361\u7247\u91CC\u5B9E\u65F6\u66F4\u65B0\uFF0C\u4E0D\u5237\u5C4F": "Recommended for long tasks: the process and the final answer update live in one card without flooding the chat",
1453
1469
  "\u6BCF\u4E00\u6B65\u90FD\u5355\u72EC\u53D1\u4E00\u6761\u6D88\u606F\uFF08\u542B\u5DE5\u5177\u8C03\u7528\u548C\u8FC7\u7A0B\u8BF4\u660E\uFF09\uFF1B\u6CE8\u610F\u957F\u4EFB\u52A1\u4F1A\u8FDE\u7EED\u53D1\u9001\u8F83\u591A\u6D88\u606F": "Every step is sent as its own message (including tool calls and notes); long tasks may send many messages in a row",
1454
1470
  "\u5206\u6B65\u76F4\u63A8\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002": "Could not save the step push setting. Try again.",
@@ -1847,6 +1863,11 @@ var EN = Object.freeze({
1847
1863
  "\u63A5\u5165 Telegram \u673A\u5668\u4EBA": "Connect a Telegram bot",
1848
1864
  "\u5148\u901A\u8FC7 @BotFather \u83B7\u53D6 Bot Token\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002": "Get a Bot Token from @BotFather, then connect it here.",
1849
1865
  "\u586B\u5199 @BotFather \u751F\u6210\u7684 Bot Token": "Enter the Bot Token from @BotFather",
1866
+ "\u4F1A\u8BDD\u884C\u4E3A": "Conversation behavior",
1867
+ "\u601D\u8003\u8FC7\u7A0B\u7559\u75D5": "Thinking traces",
1868
+ "\u5B9E\u65F6\u663E\u793A\u601D\u8003\u6B65\u9AA4\u4E0E\u5DE5\u5177\u8C03\u7528\uFF0C\u6700\u7EC8\u7B54\u6848\u5355\u72EC\u6210\u6761": "Show thinking steps and tool calls as they happen; the final answer arrives as its own message",
1869
+ "\u8BF7\u63D0\u4EA4\u6709\u6548\u7684\u601D\u8003\u8FC7\u7A0B\u7559\u75D5\u8BBE\u7F6E\u3002": "Submit a valid thinking-traces setting.",
1870
+ "\u6B63\u5728\u4F7F\u7528{name}\u2026": "Using {name}\u2026",
1850
1871
  "\u8BBF\u95EE\u6A21\u5F0F": "Access mode",
1851
1872
  "Telegram \u8BBF\u95EE\u6A21\u5F0F": "Telegram access mode",
1852
1873
  "\u67E5\u770B Telegram \u8BBF\u95EE\u6A21\u5F0F\u8BF4\u660E": "View Telegram access mode details",
@@ -4105,9 +4126,206 @@ function CredentialBindingPanel({
4105
4126
  }
4106
4127
 
4107
4128
  // plugin-src/client/channels/shared/collapsible-account.js
4129
+ var React9 = __toESM(require("react"), 1);
4130
+
4131
+ // plugin-src/client/channel-card-meta.js
4108
4132
  var React8 = __toESM(require("react"), 1);
4133
+ var BotSettingsContext = React8.createContext(Object.freeze({
4134
+ openBotSettings() {
4135
+ }
4136
+ }));
4137
+ function SettingsGlyph() {
4138
+ return h2(
4139
+ "svg",
4140
+ {
4141
+ viewBox: "0 0 24 24",
4142
+ width: 16,
4143
+ height: 16,
4144
+ fill: "none",
4145
+ stroke: "currentColor",
4146
+ strokeWidth: 1.8,
4147
+ strokeLinecap: "round",
4148
+ strokeLinejoin: "round",
4149
+ "aria-hidden": "true"
4150
+ },
4151
+ h2("circle", { cx: 12, cy: 12, r: 3 }),
4152
+ h2("path", { d: "M19.4 15a1.7 1.7 0 0 0 .34 1.88l.06.06-2.83 2.83-.06-.06a1.7 1.7 0 0 0-1.88-.34 1.7 1.7 0 0 0-1.03 1.55V21h-4v-.08A1.7 1.7 0 0 0 8.97 19.4a1.7 1.7 0 0 0-1.88.34l-.06.06-2.83-2.83.06-.06A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-1.52-1.03H3v-4h.08A1.7 1.7 0 0 0 4.6 8.97a1.7 1.7 0 0 0-.34-1.88l-.06-.06L7.03 4.2l.06.06a1.7 1.7 0 0 0 1.88.34A1.7 1.7 0 0 0 10 3.08V3h4v.08a1.7 1.7 0 0 0 1.03 1.52 1.7 1.7 0 0 0 1.88-.34l.06-.06 2.83 2.83-.06.06a1.7 1.7 0 0 0-.34 1.88A1.7 1.7 0 0 0 20.92 10H21v4h-.08A1.7 1.7 0 0 0 19.4 15Z" })
4153
+ );
4154
+ }
4155
+ function BotSettingsButton({
4156
+ channel: channel6,
4157
+ botId,
4158
+ botName,
4159
+ connected,
4160
+ accessPolicy,
4161
+ channelSettings
4162
+ }) {
4163
+ const { openBotSettings } = React8.useContext(BotSettingsContext);
4164
+ return h2(
4165
+ "span",
4166
+ { className: "dim-botSettingsAction" },
4167
+ h2(
4168
+ "button",
4169
+ {
4170
+ type: "button",
4171
+ className: "dim-botSettingsButton",
4172
+ "data-delivery-channel": channel6,
4173
+ "aria-label": "\u66F4\u591A\u673A\u5668\u4EBA\u8BBE\u7F6E",
4174
+ onClick: () => openBotSettings?.({
4175
+ ...channelSettings && typeof channelSettings === "object" ? channelSettings : {},
4176
+ channel: channel6,
4177
+ botId,
4178
+ botName,
4179
+ connected: Boolean(connected),
4180
+ accessPolicy
4181
+ })
4182
+ },
4183
+ h2(SettingsGlyph),
4184
+ h2("span", null, "\u66F4\u591A\u8BBE\u7F6E"),
4185
+ h2("span", { className: "dim-moreSettingsChevron", "aria-hidden": "true" })
4186
+ )
4187
+ );
4188
+ }
4189
+ function messageErrorTime(value) {
4190
+ try {
4191
+ return new Intl.DateTimeFormat(isEnglish() ? "en-US" : "zh-CN", {
4192
+ year: "numeric",
4193
+ month: "2-digit",
4194
+ day: "2-digit",
4195
+ hour: "2-digit",
4196
+ minute: "2-digit"
4197
+ }).format(new Date(value));
4198
+ } catch {
4199
+ return null;
4200
+ }
4201
+ }
4202
+ function ChannelListHeading({ className = "", id: id6, title, connectionLabel }) {
4203
+ const helpId = React8.useId();
4204
+ return h2(
4205
+ "div",
4206
+ { className: `${className} dim-listHeading`.trim() },
4207
+ h2(
4208
+ "div",
4209
+ { className: "dim-listTitle" },
4210
+ h2("h3", id6 ? { id: id6 } : null, title),
4211
+ h2(
4212
+ "span",
4213
+ { className: "dim-channelHelp" },
4214
+ h2("button", {
4215
+ type: "button",
4216
+ className: "dim-channelHelpButton",
4217
+ "aria-label": "\u67E5\u770B\u6D88\u606F\u901A\u9053\u8BF4\u660E",
4218
+ "aria-describedby": helpId
4219
+ }, h2("span", { "aria-hidden": "true" }, "?")),
4220
+ h2(
4221
+ "span",
4222
+ {
4223
+ id: helpId,
4224
+ className: "dim-channelTooltip",
4225
+ role: "tooltip"
4226
+ },
4227
+ h2("span", null, "\u6D88\u606F\u901A\u9053"),
4228
+ h2("strong", null, connectionLabel)
4229
+ )
4230
+ )
4231
+ )
4232
+ );
4233
+ }
4234
+ function BotStatusMeta({
4235
+ className = "",
4236
+ dotClassName = "",
4237
+ tone,
4238
+ stateLabel: stateLabel2,
4239
+ lastCheckedAt,
4240
+ formatCheckedTime: formatCheckedTime2,
4241
+ healthState
4242
+ }) {
4243
+ return h2(
4244
+ "div",
4245
+ { className: "dim-botHealthGroup" },
4246
+ h2(
4247
+ "div",
4248
+ {
4249
+ className: `${className} dim-botHealth`.trim(),
4250
+ ...healthState ? { "data-health": healthState } : {}
4251
+ },
4252
+ h2("span", {
4253
+ className: `${dotClassName} dim-healthDot`.trim(),
4254
+ "data-tone": tone
4255
+ }),
4256
+ h2("span", null, stateLabel2)
4257
+ ),
4258
+ h2(
4259
+ "div",
4260
+ { className: "dim-lastChecked" },
4261
+ h2("span", null, "\u6700\u8FD1\u68C0\u67E5"),
4262
+ h2("span", null, formatCheckedTime2(lastCheckedAt))
4263
+ )
4264
+ );
4265
+ }
4266
+ function LastMessageErrorSummary({ className = "", error }) {
4267
+ if (!error) return null;
4268
+ const occurredAt = messageErrorTime(error.at);
4269
+ return h2(
4270
+ "div",
4271
+ {
4272
+ className: `${className} dim-cardSummary`.trim(),
4273
+ role: "status"
4274
+ },
4275
+ h2("strong", null, "\u6700\u8FD1\u4E00\u6761\u6D88\u606F\u5904\u7406\u5931\u8D25"),
4276
+ "\uFF1A",
4277
+ h2("span", null, error.message),
4278
+ error.details ? h2(ConnectionError, { error, showMessage: false }) : null,
4279
+ "\uFF08",
4280
+ h2("span", null, "\u9519\u8BEF\u7801"),
4281
+ ` ${error.code} \xB7 `,
4282
+ h2("span", null, "\u53C2\u8003\u53F7"),
4283
+ ` ${error.referenceId}`,
4284
+ occurredAt ? h2(
4285
+ React8.Fragment,
4286
+ null,
4287
+ " \xB7 ",
4288
+ h2("time", { dateTime: new Date(error.at).toISOString() }, occurredAt)
4289
+ ) : null,
4290
+ "\uFF09"
4291
+ );
4292
+ }
4293
+
4294
+ // plugin-src/client/channels/shared/collapsible-account.js
4295
+ var AccountSectionContext = React9.createContext(null);
4296
+ function AccountSettingsToggle() {
4297
+ const { open, toggle, contentId } = React9.useContext(AccountSectionContext);
4298
+ return h2(
4299
+ "button",
4300
+ {
4301
+ type: "button",
4302
+ className: "dim-accountSettingsToggle",
4303
+ "aria-label": open ? "\u6536\u8D77\u8BE5\u8D26\u53F7\u7684\u8BBE\u7F6E" : "\u5C55\u5F00\u8BE5\u8D26\u53F7\u7684\u8BBE\u7F6E",
4304
+ "aria-expanded": open ? "true" : "false",
4305
+ "aria-controls": contentId,
4306
+ onClick: (event) => {
4307
+ event.stopPropagation();
4308
+ toggle();
4309
+ }
4310
+ },
4311
+ h2(SettingsGlyph),
4312
+ h2("svg", {
4313
+ className: "dim-collapsibleChevron",
4314
+ viewBox: "0 0 12 16",
4315
+ width: 12,
4316
+ height: 16,
4317
+ fill: "none",
4318
+ stroke: "currentColor",
4319
+ strokeWidth: 1.8,
4320
+ strokeLinecap: "round",
4321
+ strokeLinejoin: "round",
4322
+ "aria-hidden": "true"
4323
+ }, h2("path", { d: "M2 6 6 10 10 6" }))
4324
+ );
4325
+ }
4109
4326
  function CollapsibleAccountSection({
4110
4327
  header,
4328
+ settings,
4111
4329
  defaultOpen = false,
4112
4330
  open: controlledOpen,
4113
4331
  onToggle,
@@ -4115,57 +4333,59 @@ function CollapsibleAccountSection({
4115
4333
  className = "",
4116
4334
  children
4117
4335
  }) {
4118
- const [uncontrolledOpen, setUncontrolledOpen] = React8.useState(defaultOpen);
4336
+ const [uncontrolledOpen, setUncontrolledOpen] = React9.useState(defaultOpen);
4337
+ const generatedId = React9.useId();
4119
4338
  const open = controlledOpen ?? uncontrolledOpen;
4120
- const contentId = id6 ? `${id6}-content` : void 0;
4339
+ const contentId = `${id6 ?? generatedId}-content`;
4121
4340
  const toggle = () => {
4122
4341
  if (controlledOpen === void 0) setUncontrolledOpen((value) => !value);
4123
4342
  onToggle?.(!open);
4124
4343
  };
4125
- const onKeyDown = (event) => {
4126
- if (event.key === "Enter" || event.key === " " || event.key === "Spacebar") {
4127
- event.preventDefault();
4128
- toggle();
4129
- }
4130
- };
4131
4344
  return h2(
4132
- "div",
4133
- {
4134
- className: `dim-collapsibleAccount ${open ? "is-open" : ""} ${className}`.trim(),
4135
- "data-open": open ? "true" : "false"
4136
- },
4345
+ AccountSectionContext.Provider,
4346
+ { value: { open, toggle, contentId } },
4137
4347
  h2(
4138
4348
  "div",
4139
4349
  {
4140
- className: "dim-collapsibleHead",
4141
- role: "button",
4142
- tabIndex: 0,
4143
- onClick: toggle,
4144
- onKeyDown,
4145
- "aria-expanded": open ? "true" : "false",
4146
- "aria-controls": contentId,
4147
- "aria-label": open ? "\u6536\u8D77\u8BE5\u8D26\u53F7\u7684\u8BBE\u7F6E" : "\u5C55\u5F00\u8BE5\u8D26\u53F7\u7684\u8BBE\u7F6E"
4350
+ className: `dim-collapsibleAccount ${open ? "is-open" : ""} ${className}`.trim(),
4351
+ "data-open": open ? "true" : "false"
4148
4352
  },
4149
- h2("div", { className: "dim-collapsibleHeaderContent" }, header),
4150
- h2("span", { className: "dim-collapsibleChevron", "aria-hidden": "true" })
4151
- ),
4152
- h2(
4153
- "div",
4154
- {
4155
- id: contentId,
4156
- className: "dim-collapsibleBody",
4157
- role: "region"
4158
- },
4159
- h2("div", { className: "dim-collapsibleBodyInner" }, children)
4353
+ h2(
4354
+ "div",
4355
+ {
4356
+ className: "dim-collapsibleHead",
4357
+ onClick: toggle
4358
+ },
4359
+ h2("div", { className: "dim-collapsibleHeaderContent" }, header)
4360
+ ),
4361
+ h2(
4362
+ "div",
4363
+ {
4364
+ id: contentId,
4365
+ className: "dim-collapsibleBody",
4366
+ role: "region"
4367
+ },
4368
+ h2(
4369
+ "div",
4370
+ { className: "dim-collapsibleBodyInner" },
4371
+ settings ? h2(
4372
+ "div",
4373
+ { className: "dim-accountSettingsHeader" },
4374
+ h2("span", null, "\u5E38\u7528\u914D\u7F6E"),
4375
+ settings
4376
+ ) : null,
4377
+ children
4378
+ )
4379
+ )
4160
4380
  )
4161
4381
  );
4162
4382
  }
4163
4383
 
4164
4384
  // plugin-src/client/workspace-editor.js
4165
- var React10 = __toESM(require("react"), 1);
4385
+ var React11 = __toESM(require("react"), 1);
4166
4386
 
4167
4387
  // plugin-src/client/workspace-directory-picker.js
4168
- var React9 = __toESM(require("react"), 1);
4388
+ var React10 = __toESM(require("react"), 1);
4169
4389
  var import_react_dom2 = require("react-dom");
4170
4390
  function pickerErrorCode(error) {
4171
4391
  return error?.rpcError?.code ?? error?.code;
@@ -4186,7 +4406,7 @@ function pickerErrorMessage(error) {
4186
4406
  return error?.rpcError?.message ?? error?.message ?? "\u65E0\u6CD5\u8BFB\u53D6\u76EE\u5F55\uFF0C\u8BF7\u91CD\u8BD5\u3002";
4187
4407
  }
4188
4408
  function FolderIcon() {
4189
- return React9.createElement(
4409
+ return React10.createElement(
4190
4410
  "svg",
4191
4411
  {
4192
4412
  viewBox: "0 0 24 24",
@@ -4197,11 +4417,11 @@ function FolderIcon() {
4197
4417
  strokeLinejoin: "round",
4198
4418
  "aria-hidden": "true"
4199
4419
  },
4200
- React9.createElement("path", { d: "M3.5 7.25A2.25 2.25 0 0 1 5.75 5h4.1l1.8 2h6.6a2.25 2.25 0 0 1 2.25 2.25v7A2.75 2.75 0 0 1 17.75 19h-12A2.25 2.25 0 0 1 3.5 16.75v-9.5Z" })
4420
+ React10.createElement("path", { d: "M3.5 7.25A2.25 2.25 0 0 1 5.75 5h4.1l1.8 2h6.6a2.25 2.25 0 0 1 2.25 2.25v7A2.75 2.75 0 0 1 17.75 19h-12A2.25 2.25 0 0 1 3.5 16.75v-9.5Z" })
4201
4421
  );
4202
4422
  }
4203
4423
  function ChevronIcon() {
4204
- return React9.createElement("svg", {
4424
+ return React10.createElement("svg", {
4205
4425
  viewBox: "0 0 20 20",
4206
4426
  fill: "none",
4207
4427
  stroke: "currentColor",
@@ -4209,7 +4429,7 @@ function ChevronIcon() {
4209
4429
  strokeLinecap: "round",
4210
4430
  strokeLinejoin: "round",
4211
4431
  "aria-hidden": "true"
4212
- }, React9.createElement("path", { d: "m7.5 4.5 5 5.5-5 5.5" }));
4432
+ }, React10.createElement("path", { d: "m7.5 4.5 5 5.5-5 5.5" }));
4213
4433
  }
4214
4434
  function displayCrumbs(listing) {
4215
4435
  const homeIndex = listing.crumbs.findIndex((crumb) => crumb.path === listing.home);
@@ -4225,28 +4445,28 @@ function WorkspaceDirectoryPicker({
4225
4445
  onPicked,
4226
4446
  onCancel
4227
4447
  }) {
4228
- const [listing, setListing] = React9.useState(null);
4229
- const [loading, setLoading] = React9.useState(false);
4230
- const [error, setError] = React9.useState(null);
4231
- const [pathDraft, setPathDraft] = React9.useState(startPath ?? "");
4232
- const [showHidden, setShowHidden] = React9.useState(false);
4233
- const [retryKey, setRetryKey] = React9.useState(0);
4234
- const requestRef = React9.useRef(0);
4235
- const controllerRef = React9.useRef(null);
4236
- const dialogRef = React9.useRef(null);
4237
- const bodyRef = React9.useRef(null);
4238
- const titleId = React9.useId();
4239
- const noticeId = React9.useId();
4240
- const pathInputId = React9.useId();
4241
- const errorId = React9.useId();
4242
- const initialPathRef = React9.useRef(startPath);
4243
- const onPickedRef = React9.useRef(onPicked);
4244
- const onCancelRef = React9.useRef(onCancel);
4245
- const busyRef = React9.useRef(busy);
4448
+ const [listing, setListing] = React10.useState(null);
4449
+ const [loading, setLoading] = React10.useState(false);
4450
+ const [error, setError] = React10.useState(null);
4451
+ const [pathDraft, setPathDraft] = React10.useState(startPath ?? "");
4452
+ const [showHidden, setShowHidden] = React10.useState(false);
4453
+ const [retryKey, setRetryKey] = React10.useState(0);
4454
+ const requestRef = React10.useRef(0);
4455
+ const controllerRef = React10.useRef(null);
4456
+ const dialogRef = React10.useRef(null);
4457
+ const bodyRef = React10.useRef(null);
4458
+ const titleId = React10.useId();
4459
+ const noticeId = React10.useId();
4460
+ const pathInputId = React10.useId();
4461
+ const errorId = React10.useId();
4462
+ const initialPathRef = React10.useRef(startPath);
4463
+ const onPickedRef = React10.useRef(onPicked);
4464
+ const onCancelRef = React10.useRef(onCancel);
4465
+ const busyRef = React10.useRef(busy);
4246
4466
  onPickedRef.current = onPicked;
4247
4467
  onCancelRef.current = onCancel;
4248
4468
  busyRef.current = busy;
4249
- const loadDirectory = React9.useCallback(async (path, { reportError = true } = {}) => {
4469
+ const loadDirectory = React10.useCallback(async (path, { reportError = true } = {}) => {
4250
4470
  const request = requestRef.current + 1;
4251
4471
  requestRef.current = request;
4252
4472
  controllerRef.current?.abort();
@@ -4270,7 +4490,7 @@ function WorkspaceDirectoryPicker({
4270
4490
  if (request === requestRef.current) setLoading(false);
4271
4491
  }
4272
4492
  }, [picker]);
4273
- React9.useEffect(() => {
4493
+ React10.useEffect(() => {
4274
4494
  if (!open) return void 0;
4275
4495
  let active = true;
4276
4496
  setListing(null);
@@ -4350,10 +4570,10 @@ function WorkspaceDirectoryPicker({
4350
4570
  "nav",
4351
4571
  { className: "dim-directoryCrumbs", "aria-label": "\u5F53\u524D\u76EE\u5F55" },
4352
4572
  crumbs.map((crumb, index) => h2(
4353
- React9.Fragment,
4573
+ React10.Fragment,
4354
4574
  { key: crumb.path },
4355
4575
  index > 0 ? h2("span", { className: "dim-directoryCrumbSeparator", "aria-hidden": "true" }, "\u203A") : null,
4356
- React9.createElement("button", {
4576
+ React10.createElement("button", {
4357
4577
  type: "button",
4358
4578
  title: crumb.path,
4359
4579
  disabled: loading || busy,
@@ -4416,7 +4636,7 @@ function WorkspaceDirectoryPicker({
4416
4636
  ) : listing ? entries.length > 0 ? h2("ul", { className: "dim-directoryList" }, entries.map((entry) => h2(
4417
4637
  "li",
4418
4638
  { key: entry.path },
4419
- React9.createElement(
4639
+ React10.createElement(
4420
4640
  "button",
4421
4641
  {
4422
4642
  type: "button",
@@ -4425,7 +4645,7 @@ function WorkspaceDirectoryPicker({
4425
4645
  onClick: () => void loadDirectory(entry.path)
4426
4646
  },
4427
4647
  h2("span", { className: "dim-directoryFolder" }, h2(FolderIcon)),
4428
- React9.createElement("span", { className: "dim-directoryName" }, entry.name),
4648
+ React10.createElement("span", { className: "dim-directoryName" }, entry.name),
4429
4649
  h2("span", { className: "dim-directoryChevron" }, h2(ChevronIcon))
4430
4650
  )
4431
4651
  ))) : h2(
@@ -4478,21 +4698,21 @@ function WorkspaceDirectoryPicker({
4478
4698
  }
4479
4699
 
4480
4700
  // plugin-src/client/workspace-editor.js
4481
- var WorkspaceDirectoryPickerContext = React10.createContext(null);
4701
+ var WorkspaceDirectoryPickerContext = React11.createContext(null);
4482
4702
  function WorkspaceEditor({ workspace, directoryPicker, disabled = false, onSave }) {
4483
- const sharedDirectoryPicker = React10.useContext(WorkspaceDirectoryPickerContext);
4703
+ const sharedDirectoryPicker = React11.useContext(WorkspaceDirectoryPickerContext);
4484
4704
  const activeDirectoryPicker = directoryPicker ?? sharedDirectoryPicker;
4485
- const [open, setOpen] = React10.useState(false);
4486
- const [saving, setSaving] = React10.useState(false);
4487
- const [error, setError] = React10.useState(null);
4488
- const editButtonRef = React10.useRef(null);
4489
- const savingRef = React10.useRef(false);
4490
- const close = React10.useCallback(() => {
4705
+ const [open, setOpen] = React11.useState(false);
4706
+ const [saving, setSaving] = React11.useState(false);
4707
+ const [error, setError] = React11.useState(null);
4708
+ const editButtonRef = React11.useRef(null);
4709
+ const savingRef = React11.useRef(false);
4710
+ const close = React11.useCallback(() => {
4491
4711
  setOpen(false);
4492
4712
  setError(null);
4493
4713
  queueMicrotask(() => editButtonRef.current?.focus?.());
4494
4714
  }, []);
4495
- const pick = React10.useCallback(async (value) => {
4715
+ const pick = React11.useCallback(async (value) => {
4496
4716
  if (!value || savingRef.current || disabled) return;
4497
4717
  if (value === workspace) {
4498
4718
  close();
@@ -4529,7 +4749,7 @@ function WorkspaceEditor({ workspace, directoryPicker, disabled = false, onSave
4529
4749
  disabled: disabled || !activeDirectoryPicker
4530
4750
  }, "\u9009\u62E9\u76EE\u5F55")
4531
4751
  ),
4532
- workspace ? React10.createElement("code", {
4752
+ workspace ? React11.createElement("code", {
4533
4753
  className: "dim-workspacePath",
4534
4754
  title: workspace
4535
4755
  }, workspace) : h2("code", { className: "dim-workspacePath" }, "\u672A\u8BBE\u7F6E"),
@@ -4546,7 +4766,7 @@ function WorkspaceEditor({ workspace, directoryPicker, disabled = false, onSave
4546
4766
  }
4547
4767
 
4548
4768
  // plugin-src/client/context-enhancement.js
4549
- var React11 = __toESM(require("react"), 1);
4769
+ var React12 = __toESM(require("react"), 1);
4550
4770
  var import_react_dom3 = require("react-dom");
4551
4771
  var FIELD_LABELS = Object.freeze({
4552
4772
  channel: "\u6E20\u9053",
@@ -4791,7 +5011,7 @@ function ContextEnhancementScopeEditor({
4791
5011
  );
4792
5012
  }
4793
5013
  function ContextEnhancementDialog({ config, groupSupported, disabled, onSave, onClose, returnFocusRef, id: id6 }) {
4794
- const [draft, setDraft] = React11.useState(() => {
5014
+ const [draft, setDraft] = React12.useState(() => {
4795
5015
  const normalized = normalizeContextEnhancementConfig(config);
4796
5016
  return {
4797
5017
  ...normalized,
@@ -4800,23 +5020,23 @@ function ContextEnhancementDialog({ config, groupSupported, disabled, onSave, on
4800
5020
  } : {}
4801
5021
  };
4802
5022
  });
4803
- const [saving, setSaving] = React11.useState(false);
4804
- const [error, setError] = React11.useState(null);
4805
- const [activeScope, setActiveScope] = React11.useState("direct");
4806
- const savingRef = React11.useRef(false);
4807
- const dialogRef = React11.useRef(null);
4808
- const mountedRef = React11.useRef(true);
4809
- const groupTabRef = React11.useRef(null);
4810
- const directTabRef = React11.useRef(null);
4811
- const titleId = React11.useId();
4812
- const descriptionId = React11.useId();
4813
- const scopeIdPrefix = React11.useId();
5023
+ const [saving, setSaving] = React12.useState(false);
5024
+ const [error, setError] = React12.useState(null);
5025
+ const [activeScope, setActiveScope] = React12.useState("direct");
5026
+ const savingRef = React12.useRef(false);
5027
+ const dialogRef = React12.useRef(null);
5028
+ const mountedRef = React12.useRef(true);
5029
+ const groupTabRef = React12.useRef(null);
5030
+ const directTabRef = React12.useRef(null);
5031
+ const titleId = React12.useId();
5032
+ const descriptionId = React12.useId();
5033
+ const scopeIdPrefix = React12.useId();
4814
5034
  const groupGuidanceExample = localizeText(CONTEXT_GROUP_GUIDANCE_EXAMPLE);
4815
5035
  const directGuidanceExample = localizeText(CONTEXT_DIRECT_GUIDANCE_EXAMPLE);
4816
5036
  const busy = disabled || saving;
4817
5037
  const scopeKinds = ["direct", "group"];
4818
5038
  const tabRefs = { group: groupTabRef, direct: directTabRef };
4819
- React11.useEffect(() => {
5039
+ React12.useEffect(() => {
4820
5040
  mountedRef.current = true;
4821
5041
  dialogRef.current?.focus?.();
4822
5042
  const keepFocus = (event) => {
@@ -5007,17 +5227,17 @@ function ContextEnhancementDialog({ config, groupSupported, disabled, onSave, on
5007
5227
  return globalThis.document?.body ? (0, import_react_dom3.createPortal)(content, document.body) : content;
5008
5228
  }
5009
5229
  function ContextEnhancementEditor({ config, groupSupported = true, disabled = false, onSave }) {
5010
- const [open, setOpen] = React11.useState(false);
5011
- const entryRef = React11.useRef(null);
5012
- const dialogId = React11.useId();
5013
- const statusId = React11.useId();
5230
+ const [open, setOpen] = React12.useState(false);
5231
+ const entryRef = React12.useRef(null);
5232
+ const dialogId = React12.useId();
5233
+ const statusId = React12.useId();
5014
5234
  const saved = normalizeContextEnhancementConfig(config);
5015
5235
  const label = contextEnhancementLabel(groupSupported ? saved : {
5016
5236
  ...saved,
5017
5237
  group: { ...saved.group, enabled: false }
5018
5238
  });
5019
5239
  return h2(
5020
- React11.Fragment,
5240
+ React12.Fragment,
5021
5241
  null,
5022
5242
  h2(
5023
5243
  "button",
@@ -5051,10 +5271,10 @@ function ContextEnhancementEditor({ config, groupSupported = true, disabled = fa
5051
5271
  }
5052
5272
 
5053
5273
  // plugin-src/client/workspace-snapshot-fence.js
5054
- var React12 = __toESM(require("react"), 1);
5274
+ var React13 = __toESM(require("react"), 1);
5055
5275
  function useWorkspaceSnapshotFence() {
5056
- const state = React12.useRef({ version: 0, pendingMutations: 0 });
5057
- return React12.useMemo(() => Object.freeze({
5276
+ const state = React13.useRef({ version: 0, pendingMutations: 0 });
5277
+ return React13.useMemo(() => Object.freeze({
5058
5278
  beginStatus() {
5059
5279
  return state.current.pendingMutations === 0 ? state.current.version : null;
5060
5280
  },
@@ -5076,170 +5296,6 @@ function useWorkspaceSnapshotFence() {
5076
5296
  }), []);
5077
5297
  }
5078
5298
 
5079
- // plugin-src/client/channel-card-meta.js
5080
- var React13 = __toESM(require("react"), 1);
5081
- var BotSettingsContext = React13.createContext(Object.freeze({
5082
- openBotSettings() {
5083
- }
5084
- }));
5085
- function SettingsGlyph() {
5086
- return h2(
5087
- "svg",
5088
- {
5089
- viewBox: "0 0 24 24",
5090
- width: 16,
5091
- height: 16,
5092
- fill: "none",
5093
- stroke: "currentColor",
5094
- strokeWidth: 1.8,
5095
- strokeLinecap: "round",
5096
- strokeLinejoin: "round",
5097
- "aria-hidden": "true"
5098
- },
5099
- h2("circle", { cx: 12, cy: 12, r: 3 }),
5100
- h2("path", { d: "M19.4 15a1.7 1.7 0 0 0 .34 1.88l.06.06-2.83 2.83-.06-.06a1.7 1.7 0 0 0-1.88-.34 1.7 1.7 0 0 0-1.03 1.55V21h-4v-.08A1.7 1.7 0 0 0 8.97 19.4a1.7 1.7 0 0 0-1.88.34l-.06.06-2.83-2.83.06-.06A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-1.52-1.03H3v-4h.08A1.7 1.7 0 0 0 4.6 8.97a1.7 1.7 0 0 0-.34-1.88l-.06-.06L7.03 4.2l.06.06a1.7 1.7 0 0 0 1.88.34A1.7 1.7 0 0 0 10 3.08V3h4v.08a1.7 1.7 0 0 0 1.03 1.52 1.7 1.7 0 0 0 1.88-.34l.06-.06 2.83 2.83-.06.06a1.7 1.7 0 0 0-.34 1.88A1.7 1.7 0 0 0 20.92 10H21v4h-.08A1.7 1.7 0 0 0 19.4 15Z" })
5101
- );
5102
- }
5103
- function BotSettingsButton({
5104
- channel: channel6,
5105
- botId,
5106
- botName,
5107
- connected,
5108
- accessPolicy,
5109
- channelSettings
5110
- }) {
5111
- const { openBotSettings } = React13.useContext(BotSettingsContext);
5112
- const tooltipId = React13.useId();
5113
- return h2(
5114
- "span",
5115
- { className: "dim-botSettingsAction" },
5116
- h2("button", {
5117
- type: "button",
5118
- className: "dim-botSettingsButton",
5119
- "data-delivery-channel": channel6,
5120
- "aria-label": "\u66F4\u591A\u673A\u5668\u4EBA\u8BBE\u7F6E",
5121
- "aria-describedby": tooltipId,
5122
- onClick: () => openBotSettings?.({
5123
- ...channelSettings && typeof channelSettings === "object" ? channelSettings : {},
5124
- channel: channel6,
5125
- botId,
5126
- botName,
5127
- connected: Boolean(connected),
5128
- accessPolicy
5129
- })
5130
- }, h2(SettingsGlyph)),
5131
- h2("span", {
5132
- id: tooltipId,
5133
- className: "dim-botSettingsTooltip",
5134
- role: "tooltip"
5135
- }, "\u66F4\u591A\u673A\u5668\u4EBA\u8BBE\u7F6E")
5136
- );
5137
- }
5138
- function messageErrorTime(value) {
5139
- try {
5140
- return new Intl.DateTimeFormat(isEnglish() ? "en-US" : "zh-CN", {
5141
- year: "numeric",
5142
- month: "2-digit",
5143
- day: "2-digit",
5144
- hour: "2-digit",
5145
- minute: "2-digit"
5146
- }).format(new Date(value));
5147
- } catch {
5148
- return null;
5149
- }
5150
- }
5151
- function ChannelListHeading({ className = "", id: id6, title, connectionLabel }) {
5152
- const helpId = React13.useId();
5153
- return h2(
5154
- "div",
5155
- { className: `${className} dim-listHeading`.trim() },
5156
- h2(
5157
- "div",
5158
- { className: "dim-listTitle" },
5159
- h2("h3", id6 ? { id: id6 } : null, title),
5160
- h2(
5161
- "span",
5162
- { className: "dim-channelHelp" },
5163
- h2("button", {
5164
- type: "button",
5165
- className: "dim-channelHelpButton",
5166
- "aria-label": "\u67E5\u770B\u6D88\u606F\u901A\u9053\u8BF4\u660E",
5167
- "aria-describedby": helpId
5168
- }, h2("span", { "aria-hidden": "true" }, "?")),
5169
- h2(
5170
- "span",
5171
- {
5172
- id: helpId,
5173
- className: "dim-channelTooltip",
5174
- role: "tooltip"
5175
- },
5176
- h2("span", null, "\u6D88\u606F\u901A\u9053"),
5177
- h2("strong", null, connectionLabel)
5178
- )
5179
- )
5180
- )
5181
- );
5182
- }
5183
- function BotStatusMeta({
5184
- className = "",
5185
- dotClassName = "",
5186
- tone,
5187
- stateLabel: stateLabel2,
5188
- lastCheckedAt,
5189
- formatCheckedTime: formatCheckedTime2,
5190
- healthState
5191
- }) {
5192
- return h2(
5193
- "div",
5194
- { className: "dim-botHealthGroup" },
5195
- h2(
5196
- "div",
5197
- {
5198
- className: `${className} dim-botHealth`.trim(),
5199
- ...healthState ? { "data-health": healthState } : {}
5200
- },
5201
- h2("span", {
5202
- className: `${dotClassName} dim-healthDot`.trim(),
5203
- "data-tone": tone
5204
- }),
5205
- h2("span", null, stateLabel2)
5206
- ),
5207
- h2(
5208
- "div",
5209
- { className: "dim-lastChecked" },
5210
- h2("span", null, "\u6700\u8FD1\u68C0\u67E5"),
5211
- h2("span", null, formatCheckedTime2(lastCheckedAt))
5212
- )
5213
- );
5214
- }
5215
- function LastMessageErrorSummary({ className = "", error }) {
5216
- if (!error) return null;
5217
- const occurredAt = messageErrorTime(error.at);
5218
- return h2(
5219
- "div",
5220
- {
5221
- className: `${className} dim-cardSummary`.trim(),
5222
- role: "status"
5223
- },
5224
- h2("strong", null, "\u6700\u8FD1\u4E00\u6761\u6D88\u606F\u5904\u7406\u5931\u8D25"),
5225
- "\uFF1A",
5226
- h2("span", null, error.message),
5227
- error.details ? h2(ConnectionError, { error, showMessage: false }) : null,
5228
- "\uFF08",
5229
- h2("span", null, "\u9519\u8BEF\u7801"),
5230
- ` ${error.code} \xB7 `,
5231
- h2("span", null, "\u53C2\u8003\u53F7"),
5232
- ` ${error.referenceId}`,
5233
- occurredAt ? h2(
5234
- React13.Fragment,
5235
- null,
5236
- " \xB7 ",
5237
- h2("time", { dateTime: new Date(error.at).toISOString() }, occurredAt)
5238
- ) : null,
5239
- "\uFF09"
5240
- );
5241
- }
5242
-
5243
5299
  // plugin-src/client/channels/dingtalk/styles.js
5244
5300
  var DINGTALK_STYLE_ID = "xmanrui-dsh-im-dingtalk-settings";
5245
5301
  var CSS = String.raw`
@@ -5674,6 +5730,13 @@ function AccountCard({
5674
5730
  h2(
5675
5731
  CollapsibleAccountSection,
5676
5732
  {
5733
+ settings: h2(BotSettingsButton, {
5734
+ channel: "dingtalk",
5735
+ botId: account.botId,
5736
+ botName: account.bot.name,
5737
+ connected: account.connected,
5738
+ accessPolicy: account.accessPolicy
5739
+ }),
5677
5740
  id: `ddt-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, "-")}`,
5678
5741
  header: h2(
5679
5742
  "div",
@@ -5709,13 +5772,7 @@ function AccountCard({
5709
5772
  lastCheckedAt: account.health.lastCheckedAt,
5710
5773
  formatCheckedTime: checkedTime
5711
5774
  }),
5712
- h2(BotSettingsButton, {
5713
- channel: "dingtalk",
5714
- botId: account.botId,
5715
- botName: account.bot.name,
5716
- connected: account.connected,
5717
- accessPolicy: account.accessPolicy
5718
- })
5775
+ h2(AccountSettingsToggle)
5719
5776
  )
5720
5777
  )
5721
5778
  },
@@ -6418,7 +6475,8 @@ var TOKEN_BOT_ENDPOINTS = Object.freeze({
6418
6475
  setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
6419
6476
  setContextEnhancement: "bot.context-enhancement.set",
6420
6477
  setAccessPolicy: "bot.access-policy.set",
6421
- setAlias: "bot.alias.set"
6478
+ setAlias: "bot.alias.set",
6479
+ setThinkingTraces: "bot.thinking-traces.set"
6422
6480
  });
6423
6481
  function createTokenChannelApi(channel6, connectionSummary, {
6424
6482
  normalizeBotExtension = () => ({})
@@ -6448,6 +6506,8 @@ function createTokenChannelApi(channel6, connectionSummary, {
6448
6506
  model: normalizeModelSelection(value.model),
6449
6507
  agentPreset: normalizeAgentPresetId(value.agentPreset),
6450
6508
  contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
6509
+ // Absent from the backend means ON; only an explicit false opts out.
6510
+ thinkingTraces: value.thinkingTraces !== false,
6451
6511
  ...Object.hasOwn(value, "accessPolicy") ? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) } : {},
6452
6512
  bot: {
6453
6513
  ...normalizeBotAlias(value.bot),
@@ -6571,6 +6631,13 @@ function createTokenChannelSettings(definition) {
6571
6631
  h2(
6572
6632
  CollapsibleAccountSection,
6573
6633
  {
6634
+ settings: h2(BotSettingsButton, {
6635
+ channel: channel6.toLowerCase(),
6636
+ botId: account.botId,
6637
+ botName: account.bot.name,
6638
+ connected: account.connected,
6639
+ accessPolicy: account.accessPolicy
6640
+ }),
6574
6641
  id: `tok-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, "-")}`,
6575
6642
  header: h2(
6576
6643
  "div",
@@ -6610,13 +6677,7 @@ function createTokenChannelSettings(definition) {
6610
6677
  lastCheckedAt: account.health.lastCheckedAt,
6611
6678
  formatCheckedTime: checkedTime2
6612
6679
  }),
6613
- h2(BotSettingsButton, {
6614
- channel: channel6.toLowerCase(),
6615
- botId: account.botId,
6616
- botName: account.bot.name,
6617
- connected: account.connected,
6618
- accessPolicy: account.accessPolicy
6619
- })
6680
+ h2(AccountSettingsToggle)
6620
6681
  )
6621
6682
  )
6622
6683
  },
@@ -7092,11 +7153,18 @@ var React17 = __toESM(require("react"), 1);
7092
7153
  // src/channels/feishu/step-push-mode.mjs
7093
7154
  var FEISHU_STEP_PUSH_MODES = Object.freeze({
7094
7155
  POST: "post",
7095
- STREAMING_CARD: "streaming_card"
7156
+ STREAMING_CARD: "streaming_card",
7157
+ LIVE_COT: "live_cot"
7096
7158
  });
7097
7159
  var DEFAULT_FEISHU_STEP_PUSH_MODE = FEISHU_STEP_PUSH_MODES.STREAMING_CARD;
7098
7160
  function normalizeFeishuStepPushMode(value) {
7099
- return value === FEISHU_STEP_PUSH_MODES.STREAMING_CARD ? FEISHU_STEP_PUSH_MODES.STREAMING_CARD : FEISHU_STEP_PUSH_MODES.POST;
7161
+ if (value === FEISHU_STEP_PUSH_MODES.STREAMING_CARD) {
7162
+ return FEISHU_STEP_PUSH_MODES.STREAMING_CARD;
7163
+ }
7164
+ if (value === FEISHU_STEP_PUSH_MODES.LIVE_COT) {
7165
+ return FEISHU_STEP_PUSH_MODES.LIVE_COT;
7166
+ }
7167
+ return FEISHU_STEP_PUSH_MODES.POST;
7100
7168
  }
7101
7169
 
7102
7170
  // plugin-src/client/channels/feishu/api.js
@@ -7874,12 +7942,12 @@ function StepPushEditor({ value = false, mode = "post", disabled = false, onSave
7874
7942
  if (value === true) await onSave?.(false);
7875
7943
  return;
7876
7944
  }
7877
- const nextMode = next === "streaming_card" ? "streaming_card" : "post";
7945
+ const nextMode = ["streaming_card", "live_cot"].includes(next) ? next : "post";
7878
7946
  if (value !== true) await onSave?.(true);
7879
7947
  if (nextMode !== mode) await onModeSave?.(nextMode);
7880
7948
  });
7881
7949
  };
7882
- const helpText = current === "off" ? "\u9002\u5408\u65E5\u5E38\u95EE\u7B54\uFF1A\u6267\u884C\u8FC7\u7A0B\u4E2D\u4E0D\u663E\u793A\u5DE5\u5177\u8C03\u7528\u7B49\u4E2D\u95F4\u6B65\u9AA4\uFF0C\u53EA\u56DE\u590D\u6700\u7EC8\u7ED3\u679C" : current === "streaming_card" ? "\u63A8\u8350\u957F\u4EFB\u52A1\u4F7F\u7528\uFF1A\u8FC7\u7A0B\u4E0E\u6700\u7EC8\u7B54\u6848\u90FD\u5728\u540C\u4E00\u5F20\u5361\u7247\u91CC\u5B9E\u65F6\u66F4\u65B0\uFF0C\u4E0D\u5237\u5C4F" : "\u6BCF\u4E00\u6B65\u90FD\u5355\u72EC\u53D1\u4E00\u6761\u6D88\u606F\uFF08\u542B\u5DE5\u5177\u8C03\u7528\u548C\u8FC7\u7A0B\u8BF4\u660E\uFF09\uFF1B\u6CE8\u610F\u957F\u4EFB\u52A1\u4F1A\u8FDE\u7EED\u53D1\u9001\u8F83\u591A\u6D88\u606F";
7950
+ const helpText = current === "off" ? "\u9002\u5408\u65E5\u5E38\u95EE\u7B54\uFF1A\u6267\u884C\u8FC7\u7A0B\u4E2D\u4E0D\u663E\u793A\u5DE5\u5177\u8C03\u7528\u7B49\u4E2D\u95F4\u6B65\u9AA4\uFF0C\u53EA\u56DE\u590D\u6700\u7EC8\u7ED3\u679C" : current === "live_cot" ? "\u4F7F\u7528\u98DE\u4E66\u539F\u751F\u601D\u8003\u8FC7\u7A0B\u5C55\u793A\u63A8\u7406\u3001\u5DE5\u5177\u8C03\u7528\u4E0E\u7ED3\u679C\uFF0C\u6700\u7EC8\u7B54\u6848\u5355\u72EC\u53D1\u9001" : current === "streaming_card" ? "\u63A8\u8350\u957F\u4EFB\u52A1\u4F7F\u7528\uFF1A\u8FC7\u7A0B\u4E0E\u6700\u7EC8\u7B54\u6848\u90FD\u5728\u540C\u4E00\u5F20\u5361\u7247\u91CC\u5B9E\u65F6\u66F4\u65B0\uFF0C\u4E0D\u5237\u5C4F" : "\u6BCF\u4E00\u6B65\u90FD\u5355\u72EC\u53D1\u4E00\u6761\u6D88\u606F\uFF08\u542B\u5DE5\u5177\u8C03\u7528\u548C\u8FC7\u7A0B\u8BF4\u660E\uFF09\uFF1B\u6CE8\u610F\u957F\u4EFB\u52A1\u4F1A\u8FDE\u7EED\u53D1\u9001\u8F83\u591A\u6D88\u606F";
7883
7951
  return h2(
7884
7952
  "section",
7885
7953
  {
@@ -7906,7 +7974,7 @@ function StepPushEditor({ value = false, mode = "post", disabled = false, onSave
7906
7974
  id: helpId,
7907
7975
  className: "dim-presetTooltip",
7908
7976
  role: "tooltip"
7909
- }, "\u8BBE\u7F6E\u4EFB\u52A1\u6267\u884C\u8FC7\u7A0B\u7684\u5448\u73B0\u65B9\u5F0F\uFF1A\u4E0D\u663E\u793A\u3001\u5B9E\u65F6\u5361\u7247\u6216\u9010\u6B65\u6D88\u606F")
7977
+ }, "\u8BBE\u7F6E\u4EFB\u52A1\u6267\u884C\u8FC7\u7A0B\u7684\u5448\u73B0\u65B9\u5F0F\uFF1A\u4E0D\u663E\u793A\u3001\u539F\u751F\u76F4\u64AD\u3001\u5B9E\u65F6\u5361\u7247\u6216\u9010\u6B65\u6D88\u606F")
7910
7978
  )
7911
7979
  ),
7912
7980
  saving ? h2("span", { className: "dim-feishuGroupControlStatus", role: "status" }, "\u4FDD\u5B58\u4E2D\u2026") : null
@@ -7921,6 +7989,7 @@ function StepPushEditor({ value = false, mode = "post", disabled = false, onSave
7921
7989
  onChange: change
7922
7990
  },
7923
7991
  h2("option", { value: "off" }, "\u4E0D\u663E\u793A\u8FC7\u7A0B\uFF08\u53EA\u53D1\u9001\u6700\u7EC8\u7B54\u6848\uFF09"),
7992
+ h2("option", { value: "live_cot" }, "\u5B9E\u65F6\u76F4\u64AD\uFF08\u98DE\u4E66\u539F\u751F\u601D\u8003\u8FC7\u7A0B\uFF09"),
7924
7993
  h2("option", { value: "streaming_card" }, "\u5B9E\u65F6\u8FC7\u7A0B\u5361\uFF08\u5168\u7A0B\u4E00\u5F20\u5361\u7247\u52A8\u6001\u66F4\u65B0\uFF09"),
7925
7994
  h2("option", { value: "post" }, "\u9010\u6B65\u76F4\u64AD\uFF08\u6BCF\u4E00\u6B65\u5355\u72EC\u53D1\u4E00\u6761\u6D88\u606F\uFF09")
7926
7995
  ),
@@ -7976,6 +8045,18 @@ function BotCard({
7976
8045
  h2(
7977
8046
  CollapsibleAccountSection,
7978
8047
  {
8048
+ settings: h2(BotSettingsButton, {
8049
+ channel: "feishu",
8050
+ botId: connection.botId,
8051
+ botName: bot.name,
8052
+ connected,
8053
+ accessPolicy: connection.accessPolicy,
8054
+ channelSettings: {
8055
+ groupResponseMode: connection.groupResponseMode,
8056
+ groupTopicReply: connection.groupTopicReply,
8057
+ groupMessagePermissionGranted: connection.groupMessagePermissionGranted
8058
+ }
8059
+ }),
7979
8060
  id: `bxf-settings-${connection.botId.replace(/[^a-zA-Z0-9_-]/g, "-")}`,
7980
8061
  header: h2(
7981
8062
  "div",
@@ -8016,18 +8097,7 @@ function BotCard({
8016
8097
  formatCheckedTime,
8017
8098
  healthState: stateForDisplay
8018
8099
  }),
8019
- h2(BotSettingsButton, {
8020
- channel: "feishu",
8021
- botId: connection.botId,
8022
- botName: bot.name,
8023
- connected,
8024
- accessPolicy: connection.accessPolicy,
8025
- channelSettings: {
8026
- groupResponseMode: connection.groupResponseMode,
8027
- groupTopicReply: connection.groupTopicReply,
8028
- groupMessagePermissionGranted: connection.groupMessagePermissionGranted
8029
- }
8030
- })
8100
+ h2(AccountSettingsToggle)
8031
8101
  )
8032
8102
  )
8033
8103
  },
@@ -9912,6 +9982,13 @@ function AccountCard2({
9912
9982
  h2(
9913
9983
  CollapsibleAccountSection,
9914
9984
  {
9985
+ settings: h2(BotSettingsButton, {
9986
+ channel: "qq",
9987
+ botId: account.botId,
9988
+ botName: account.bot.name,
9989
+ connected: account.connected,
9990
+ accessPolicy: account.accessPolicy
9991
+ }),
9915
9992
  id: `qq-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, "-")}`,
9916
9993
  header: h2(
9917
9994
  "div",
@@ -9947,13 +10024,7 @@ function AccountCard2({
9947
10024
  lastCheckedAt: account.health.lastCheckedAt,
9948
10025
  formatCheckedTime: checkedTime3
9949
10026
  }),
9950
- h2(BotSettingsButton, {
9951
- channel: "qq",
9952
- botId: account.botId,
9953
- botName: account.bot.name,
9954
- connected: account.connected,
9955
- accessPolicy: account.accessPolicy
9956
- })
10027
+ h2(AccountSettingsToggle)
9957
10028
  )
9958
10029
  )
9959
10030
  },
@@ -10937,12 +11008,57 @@ var unwrapRpcResult6 = api3.unwrapRpcResult;
10937
11008
  var normalizeSnapshot5 = api3.normalizeSnapshot;
10938
11009
  var presentError6 = api3.presentError;
10939
11010
 
11011
+ // plugin-src/client/channels/telegram/thinking-traces.js
11012
+ function ThinkingTracesSettings({ account, busy, onSave }) {
11013
+ const checked = account.thinkingTraces !== false;
11014
+ return h2(
11015
+ "div",
11016
+ { className: "dim-accountSettings" },
11017
+ h2("h4", { className: "dim-accountSettingsTitle" }, "\u4F1A\u8BDD\u884C\u4E3A"),
11018
+ h2(
11019
+ "label",
11020
+ { className: "dim-accountSettingsRow" },
11021
+ h2(
11022
+ "span",
11023
+ { className: "dim-accountSettingsText" },
11024
+ h2("span", { className: "dim-accountSettingsLabel" }, "\u601D\u8003\u8FC7\u7A0B\u7559\u75D5"),
11025
+ h2(
11026
+ "span",
11027
+ { className: "dim-accountSettingsHelp" },
11028
+ "\u5B9E\u65F6\u663E\u793A\u601D\u8003\u6B65\u9AA4\u4E0E\u5DE5\u5177\u8C03\u7528\uFF0C\u6700\u7EC8\u7B54\u6848\u5355\u72EC\u6210\u6761"
11029
+ )
11030
+ ),
11031
+ h2("input", {
11032
+ type: "checkbox",
11033
+ className: "dim-accountSettingsSwitch",
11034
+ checked,
11035
+ disabled: Boolean(busy),
11036
+ onChange: (event) => {
11037
+ onSave?.({ thinkingTraces: event.target.checked });
11038
+ }
11039
+ })
11040
+ )
11041
+ );
11042
+ }
11043
+
10940
11044
  // plugin-src/client/channels/telegram/styles.js
10941
11045
  var TELEGRAM_STYLE_ID = "xmanrui-dsh-im-telegram-settings";
10942
11046
  var CSS7 = String.raw`
10943
11047
  .dtg-page { --ddt-accent: #229ed9; --ddt-accent-deep: #1687bd; --ddt-accent-wash: #eaf7fd; }
10944
11048
  .dtg-avatar { color: #fff; background: #229ed9; }
10945
11049
  .dtg-avatar svg { display: block; }
11050
+ .dim-accountSettings { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--dsw-alias-border-l2, #eceef1); }
11051
+ .dim-accountSettingsTitle { margin: 0 0 8px; font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-secondary, #646a73); letter-spacing: 0.02em; }
11052
+ .dim-accountSettingsRow { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 40px; cursor: pointer; }
11053
+ .dim-accountSettingsText { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
11054
+ .dim-accountSettingsLabel { font-size: 13px; font-weight: 500; color: var(--dsw-alias-label, #1f2329); }
11055
+ .dim-accountSettingsHelp { font-size: 12px; color: var(--dsw-alias-label-tertiary, #8a919f); }
11056
+ .dim-accountSettingsSwitch { appearance: none; flex: none; width: 32px; height: 19px; margin: 0; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 12px; background: var(--dsw-alias-interactive-bg-hover, #eef0f3); cursor: pointer; position: relative; }
11057
+ .dim-accountSettingsSwitch::before { content: ""; position: absolute; top: 2px; left: 2px; width: 13px; height: 13px; border-radius: 50%; background: var(--dsw-alias-label-secondary, #646a73); transition: transform 120ms ease, background 120ms ease; }
11058
+ .dim-accountSettingsSwitch:checked { border-color: #229ed9; background: #229ed9; }
11059
+ .dim-accountSettingsSwitch:checked::before { transform: translateX(13px); background: #fff; }
11060
+ .dim-accountSettingsSwitch:disabled { opacity: 0.5; cursor: not-allowed; }
11061
+ @media (prefers-reduced-motion: reduce) { .dim-accountSettingsSwitch::before { transition: none; } }
10946
11062
  `;
10947
11063
  function installTelegramStyles() {
10948
11064
  if (typeof document === "undefined") return () => {
@@ -10971,7 +11087,9 @@ var channel3 = createTokenChannelSettings({
10971
11087
  tokenPlaceholder: "\u586B\u5199 @BotFather \u751F\u6210\u7684 Bot Token",
10972
11088
  emptyTitle: "\u63A5\u5165 Telegram \u673A\u5668\u4EBA",
10973
11089
  emptyDescription: "\u5148\u901A\u8FC7 @BotFather \u83B7\u53D6 Bot Token\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002",
10974
- platformLabel: "Telegram"
11090
+ platformLabel: "Telegram",
11091
+ AccountSettings: ThinkingTracesSettings,
11092
+ accountSettingsEndpoint: "bot.thinking-traces.set"
10975
11093
  });
10976
11094
  var TelegramSettingsTab = channel3.SettingsTab;
10977
11095
  var TelegramAccountCard = channel3.AccountCard;
@@ -11370,6 +11488,13 @@ function AccountCard3({
11370
11488
  h2(
11371
11489
  CollapsibleAccountSection,
11372
11490
  {
11491
+ settings: h2(BotSettingsButton, {
11492
+ channel: "wecom",
11493
+ botId: account.botId,
11494
+ botName: account.bot.name,
11495
+ connected: account.connected,
11496
+ accessPolicy: account.accessPolicy
11497
+ }),
11373
11498
  id: `wec-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, "-")}`,
11374
11499
  header: h2(
11375
11500
  "div",
@@ -11405,13 +11530,7 @@ function AccountCard3({
11405
11530
  lastCheckedAt: account.health.lastCheckedAt,
11406
11531
  formatCheckedTime: checkedTime4
11407
11532
  }),
11408
- h2(BotSettingsButton, {
11409
- channel: "wecom",
11410
- botId: account.botId,
11411
- botName: account.bot.name,
11412
- connected: account.connected,
11413
- accessPolicy: account.accessPolicy
11414
- })
11533
+ h2(AccountSettingsToggle)
11415
11534
  )
11416
11535
  )
11417
11536
  },
@@ -12298,6 +12417,13 @@ function AccountCard4({
12298
12417
  h2(
12299
12418
  CollapsibleAccountSection,
12300
12419
  {
12420
+ settings: h2(BotSettingsButton, {
12421
+ channel: "wecomApp",
12422
+ botId: account.botId,
12423
+ botName: account.bot.name,
12424
+ connected: account.connected,
12425
+ accessPolicy: account.accessPolicy
12426
+ }),
12301
12427
  id: elementId,
12302
12428
  header: h2(
12303
12429
  "div",
@@ -12332,13 +12458,7 @@ function AccountCard4({
12332
12458
  lastCheckedAt: account.health.lastCheckedAt,
12333
12459
  formatCheckedTime: checkedTime5
12334
12460
  }),
12335
- h2(BotSettingsButton, {
12336
- channel: "wecomApp",
12337
- botId: account.botId,
12338
- botName: account.bot.name,
12339
- connected: account.connected,
12340
- accessPolicy: account.accessPolicy
12341
- })
12461
+ h2(AccountSettingsToggle)
12342
12462
  )
12343
12463
  )
12344
12464
  },
@@ -13149,6 +13269,13 @@ function AccountCard5({
13149
13269
  h2(
13150
13270
  CollapsibleAccountSection,
13151
13271
  {
13272
+ settings: h2(BotSettingsButton, {
13273
+ channel: "weixin",
13274
+ botId: account.botId,
13275
+ botName: account.bot.name,
13276
+ connected: account.connected,
13277
+ accessPolicy: account.accessPolicy
13278
+ }),
13152
13279
  id: `dxw-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, "-")}`,
13153
13280
  header: h2(
13154
13281
  "div",
@@ -13179,13 +13306,7 @@ function AccountCard5({
13179
13306
  lastCheckedAt: account.health.lastCheckedAt,
13180
13307
  formatCheckedTime: checkedTime6
13181
13308
  }),
13182
- h2(BotSettingsButton, {
13183
- channel: "weixin",
13184
- botId: account.botId,
13185
- botName: account.bot.name,
13186
- connected: account.connected,
13187
- accessPolicy: account.accessPolicy
13188
- })
13309
+ h2(AccountSettingsToggle)
13189
13310
  )
13190
13311
  )
13191
13312
  },
@@ -14283,6 +14404,13 @@ function WhatsappAccountCard({
14283
14404
  h2(
14284
14405
  CollapsibleAccountSection,
14285
14406
  {
14407
+ settings: h2(BotSettingsButton, {
14408
+ channel: "whatsapp",
14409
+ botId: account.botId,
14410
+ botName: account.bot.name,
14411
+ connected: account.connected,
14412
+ accessPolicy: account.accessPolicy
14413
+ }),
14286
14414
  id: `wsp-settings-${account.botId.replace(/[^a-zA-Z0-9_-]/g, "-")}`,
14287
14415
  header: h2(
14288
14416
  "div",
@@ -14321,13 +14449,7 @@ function WhatsappAccountCard({
14321
14449
  lastCheckedAt: account.health.lastCheckedAt,
14322
14450
  formatCheckedTime: checkedTime7
14323
14451
  }),
14324
- h2(BotSettingsButton, {
14325
- channel: "whatsapp",
14326
- botId: account.botId,
14327
- botName: account.bot.name,
14328
- connected: account.connected,
14329
- accessPolicy: account.accessPolicy
14330
- })
14452
+ h2(AccountSettingsToggle)
14331
14453
  )
14332
14454
  )
14333
14455
  },
@@ -18261,10 +18383,10 @@ var CSS14 = String.raw`
18261
18383
  .dim-updateFooter .dim-updateButton:first-child { margin-right: auto; }
18262
18384
  .dim-updatePrimary, .dim-updatePrimary:hover:not(:disabled) { border-color: var(--dsw-alias-state-business-primary, #3370ff); color: #fff; background: var(--dsw-alias-state-business-primary, #3370ff); }
18263
18385
  .dim-githubAction { position: relative; display: inline-flex; flex: none; }
18264
- .dim-githubLink { min-height: 30px; display: inline-flex; align-items: center; gap: 5px; flex: none; padding: 0 10px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-layer-1, #fff); font-size: 12px; line-height: normal; font-weight: 560; text-decoration: none; transition: border-color .15s ease, color .15s ease, background .15s ease; }
18386
+ .dim-githubLink { width: 30px; height: 30px; display: grid; place-items: center; flex: none; padding: 0; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-layer-1, #fff); text-decoration: none; transition: border-color .15s ease, color .15s ease, background .15s ease; }
18387
+ .dim-githubLink svg { display: block; }
18265
18388
  .dim-githubLink:hover { border-color: #aeb3bb; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
18266
18389
  .dim-githubLink:focus-visible { outline: 2px solid color-mix(in srgb, var(--dim-blue) 70%, white); outline-offset: 2px; }
18267
- .dim-githubArrow { font-size: 13px; line-height: 1; }
18268
18390
  .dim-githubTooltip { position: absolute; top: calc(100% + 8px); right: 0; z-index: 20; width: max-content; max-width: min(220px, 80vw); padding: 6px 9px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 8px 24px rgb(31 35 41 / 14%); font-size: 11px; line-height: 16px; font-weight: 500; white-space: nowrap; opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
18269
18391
  .dim-githubAction:hover .dim-githubTooltip, .dim-githubAction:focus-within .dim-githubTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
18270
18392
  .dim-generalSettingsAction { position: relative; display: inline-flex; flex: none; }
@@ -18585,10 +18707,15 @@ var CSS14 = String.raw`
18585
18707
  .dim-panel .dim-botCardBody { position: relative; min-width: 0; width: 100%; max-width: 100%; padding: 12px 8px; }
18586
18708
  .dim-collapsibleAccount { min-width: 0; display: flex; flex-direction: column; }
18587
18709
  .dim-collapsibleHead { min-width: 0; display: flex; align-items: center; gap: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; }
18588
- .dim-collapsibleHead:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 2px; border-radius: 8px; }
18589
18710
  .dim-collapsibleHeaderContent { min-width: 0; flex: 1 1 auto; display: flex; align-items: center; }
18590
- .dim-collapsibleChevron { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 9px; height: 9px; border-right: 1.6px solid var(--dsw-alias-label-tertiary, #8f959e); border-bottom: 1.6px solid var(--dsw-alias-label-tertiary, #8f959e); transform: rotate(-45deg); transition: transform .22s cubic-bezier(.4, 0, .2, 1); transform-origin: 50% 50%; }
18591
- .dim-collapsibleAccount.is-open .dim-collapsibleChevron { transform: rotate(45deg); }
18711
+ /* Keep the original header footprint; center both icons with equal side space. */
18712
+ .dim-accountSettingsToggle { flex: none; width: 45px; height: 32px; display: inline-flex; gap: 5px; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 8px; color: var(--dsw-alias-state-business-primary, #3370ff); background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 8%, var(--dsw-alias-bg-layer-1, #fff)); cursor: pointer; }
18713
+ .dim-accountSettingsToggle > svg { flex: none; display: block; }
18714
+ .dim-accountSettingsToggle:hover { background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #3370ff) 14%, var(--dsw-alias-bg-layer-1, #fff)); }
18715
+ .dim-accountSettingsToggle:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 2px; }
18716
+ .dim-collapsibleChevron { width: 12px; height: 16px; transition: transform .22s cubic-bezier(.4, 0, .2, 1); transform-origin: 50% 50%; }
18717
+ .dim-accountSettingsToggle[aria-expanded="true"] .dim-collapsibleChevron { transform: rotate(180deg); }
18718
+ .dim-accountSettingsHeader { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; padding-top: 8px; border-top: 1px solid var(--dsw-alias-border-l2, #e5e6eb); color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; }
18592
18719
  /* Animate height without measuring content; hide collapsed controls from focus and accessibility. */
18593
18720
  .dim-collapsibleBody { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .22s cubic-bezier(.4, 0, .2, 1); }
18594
18721
  .dim-collapsibleAccount.is-open > .dim-collapsibleBody { grid-template-rows: 1fr; }
@@ -18613,11 +18740,10 @@ var CSS14 = String.raw`
18613
18740
  .dim-panel .dim-botCard .dim-healthDot[data-tone="warning"] { background: var(--dsw-alias-state-warn-primary, #d97706); }
18614
18741
  .dim-panel .dim-botCard .dim-healthDot[data-tone="error"] { background: var(--dsw-alias-state-error-primary, #d54941); }
18615
18742
  .dim-botSettingsAction { position: relative; flex: none; display: inline-flex; }
18616
- .dim-botSettingsButton { width: 32px; height: 32px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 8px; color: var(--dsw-alias-label-secondary, #646a73); background: transparent; cursor: pointer; transition: color .15s ease, background .15s ease; }
18743
+ .dim-botSettingsButton { min-height: 32px; display: inline-flex; align-items: center; gap: 6px; padding: 0 6px; border: 0; border-radius: 8px; color: var(--dsw-alias-state-business-primary, #3370ff); background: transparent; font: inherit; font-size: 12px; white-space: nowrap; cursor: pointer; transition: color .15s ease, background .15s ease; }
18617
18744
  .dim-botSettingsButton:hover { color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-interactive-bg-hover, #eef0f3); }
18618
18745
  .dim-botSettingsButton:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary, #3370ff); outline-offset: 2px; }
18619
- .dim-botSettingsTooltip { position: absolute; top: calc(100% + 6px); right: 0; z-index: 30; width: max-content; padding: 6px 9px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 8px 24px rgb(31 35 41 / 14%); font-size: 11px; line-height: 16px; opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
18620
- .dim-botSettingsAction:hover .dim-botSettingsTooltip, .dim-botSettingsAction:focus-within .dim-botSettingsTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
18746
+ .dim-moreSettingsChevron { width: 6px; height: 6px; margin-right: 2px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); }
18621
18747
  .dim-deliveryPage { min-width: 0; display: grid; }
18622
18748
  .dim-deliveryHeader { min-width: 0; display: flex; align-items: center; justify-content: space-between; gap: 16px; }
18623
18749
  .dim-botSettingsTabsBar { min-width: 0; margin-top: 10px; border-bottom: 1px solid var(--dsw-alias-border-l2, #dfe1e5); }
@@ -19201,14 +19327,17 @@ function summary(snapshot, action, error) {
19201
19327
  if (snapshot?.job?.state === "restart-required" || snapshot?.blockedReason === "pending-restart") {
19202
19328
  return "\u5DF2\u5B89\u88C5\uFF0C\u5F85\u624B\u52A8\u91CD\u542F";
19203
19329
  }
19204
- if (snapshot?.job?.state === "completed") return "\u66F4\u65B0\u5DF2\u751F\u6548";
19205
- if (snapshot?.job?.state === "failed") return "\u66F4\u65B0\u5931\u8D25";
19206
- if (snapshot?.job?.state === "interrupted") return "\u4E0A\u6B21\u66F4\u65B0\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u68C0\u67E5\u5B89\u88C5\u72B6\u6001\u540E\u91CD\u8BD5\u3002";
19207
19330
  if (error) return "\u66F4\u65B0\u8BF7\u6C42\u5931\u8D25";
19331
+ if (!snapshot?.job?.recoverable) {
19332
+ if (snapshot?.job?.state === "failed") return "\u66F4\u65B0\u5931\u8D25";
19333
+ if (snapshot?.job?.state === "interrupted") return "\u4E0A\u6B21\u66F4\u65B0\u5DF2\u4E2D\u65AD\uFF0C\u8BF7\u68C0\u67E5\u5B89\u88C5\u72B6\u6001\u540E\u91CD\u8BD5\u3002";
19334
+ }
19335
+ if (snapshot?.blockedReason === "no-update") return "\u5F53\u524D\u7248\u672C\u65E0\u9700\u66F4\u65B0";
19336
+ if (snapshot?.blockedReason) return "\u6682\u65F6\u65E0\u6CD5\u5B89\u88C5\u66F4\u65B0";
19208
19337
  if (snapshot?.canInstall) return "\u53D1\u73B0\u65B0\u7248\u672C";
19209
19338
  if (snapshot?.checkedAt && snapshot.latestVersion === snapshot.runningVersion) return "\u5DF2\u662F\u6700\u65B0\u7248\u672C";
19210
- if (snapshot?.blockedReason === "no-update") return "\u5F53\u524D\u7248\u672C\u65E0\u9700\u66F4\u65B0";
19211
19339
  if (snapshot?.checkedAt) return "\u5DF2\u83B7\u53D6 npm \u6700\u65B0\u7248\u672C";
19340
+ if (snapshot?.job?.state === "completed") return "\u66F4\u65B0\u5DF2\u751F\u6548";
19212
19341
  return "\u68C0\u67E5 npm \u6700\u65B0\u7248\u672C\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u5B89\u88C5\u3002";
19213
19342
  }
19214
19343
  function retainDialogFocus(event) {
@@ -19223,7 +19352,7 @@ function manualUpdateCommand(snapshot) {
19223
19352
  const targets = [
19224
19353
  snapshot.latestVersion,
19225
19354
  pendingRestart ? snapshot.installedVersion : null,
19226
- snapshot.job?.state !== "completed" ? snapshot.job?.targetVersion : null
19355
+ snapshot.job?.state !== "completed" && !snapshot.job?.recoverable ? snapshot.job?.targetVersion : null
19227
19356
  ].filter(validVersion);
19228
19357
  const version = targets.length ? [...targets, snapshot.runningVersion, snapshot.installedVersion].filter(validVersion).sort(import_rcompare.default)[0] : "latest";
19229
19358
  return `dsh plugin --profile ${profileArgument} add -w @xmanrui/dsh-im@${version}`;
@@ -19531,9 +19660,11 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
19531
19660
  const blocked = BLOCKED_REASONS[snapshot?.blockedReason] ?? ERROR_MESSAGES[snapshot?.blockedReason];
19532
19661
  const canConfirm = snapshot?.canInstall && snapshot.checkId && !activeJob && !restartRequired;
19533
19662
  const versionsDiffer = snapshot && clientVersion && snapshot.runningVersion !== clientVersion;
19534
- const failedJob = ["failed", "interrupted"].includes(snapshot?.job?.state);
19663
+ const failedJob = ["failed", "interrupted"].includes(snapshot?.job?.state) && !snapshot.job.recoverable;
19535
19664
  const jobMessage = snapshot?.job?.message;
19536
- const targetVersion = snapshot?.job?.targetVersion;
19665
+ const targetVersion = activeJob || restartRequired ? snapshot?.job?.targetVersion : null;
19666
+ const historicalTargetVersion = !activeJob && !restartRequired ? snapshot?.job?.targetVersion : null;
19667
+ const latestVersion = !activeJob && !restartRequired && !error && snapshot?.checkedAt ? snapshot.latestVersion : null;
19537
19668
  const manualCommand = manualUpdateCommand(snapshot);
19538
19669
  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";
19539
19670
  return h2(
@@ -19547,7 +19678,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
19547
19678
  onClick: () => {
19548
19679
  setOpen(true);
19549
19680
  if (restartRequired) void refreshStatus();
19550
- else if (!snapshot?.canInstall && !snapshot?.job) void check();
19681
+ else if (!snapshot?.canInstall && !activeJob && !uncertainInstall) void check();
19551
19682
  }
19552
19683
  }, buttonLabel, buttonLabel === "\u66F4\u65B0\u81F3" ? ` v${snapshot.latestVersion}` : null),
19553
19684
  open ? h2(
@@ -19573,6 +19704,18 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
19573
19704
  h2("dt", null, "\u76EE\u6807\u7248\u672C"),
19574
19705
  h2("dd", null, `v${targetVersion}`)
19575
19706
  ) : null,
19707
+ latestVersion ? h2(
19708
+ React31.Fragment,
19709
+ null,
19710
+ h2("dt", null, "\u6700\u65B0\u7248\u672C"),
19711
+ h2("dd", null, `v${latestVersion}`)
19712
+ ) : null,
19713
+ historicalTargetVersion ? h2(
19714
+ React31.Fragment,
19715
+ null,
19716
+ h2("dt", null, "\u4E0A\u6B21\u66F4\u65B0\u76EE\u6807"),
19717
+ h2("dd", null, `v${historicalTargetVersion}`)
19718
+ ) : null,
19576
19719
  h2("dt", null, "\u76EE\u6807 profile"),
19577
19720
  h2("dd", null, snapshot?.profileName ?? "\u65E0\u6CD5\u786E\u8BA4")
19578
19721
  ),
@@ -19926,8 +20069,16 @@ function IMSettingsTab({
19926
20069
  "aria-label": "dsh-im GitHub",
19927
20070
  "aria-describedby": githubTooltipId
19928
20071
  },
19929
- h2("span", null, "GitHub"),
19930
- h2("span", { className: "dim-githubArrow", "aria-hidden": "true" }, "\u2197")
20072
+ h2("svg", {
20073
+ width: 18,
20074
+ height: 18,
20075
+ viewBox: "0 0 16 16",
20076
+ fill: "currentColor",
20077
+ focusable: "false",
20078
+ "aria-hidden": "true"
20079
+ }, h2("path", {
20080
+ d: "M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82a7.65 7.65 0 0 1 2-.27c.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8Z"
20081
+ }))
19931
20082
  ),
19932
20083
  h2("span", {
19933
20084
  id: githubTooltipId,