@xmanrui/dsh-im 2.5.0 → 3.0.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 (37) hide show
  1. package/README.en.md +4 -4
  2. package/README.md +4 -4
  3. package/bin/dsh-im.mjs +1 -1
  4. package/lib/client.js +1410 -1409
  5. package/lib/index.js +206 -206
  6. package/package.json +2 -2
  7. package/plugin-src/client/channels/dingtalk/index.js +0 -17
  8. package/plugin-src/client/channels/dingtalk/styles.js +2 -2
  9. package/plugin-src/client/channels/feishu/index.js +0 -29
  10. package/plugin-src/client/channels/feishu/styles.js +2 -2
  11. package/plugin-src/client/channels/qq/index.js +0 -9
  12. package/plugin-src/client/channels/wecom/index.js +0 -9
  13. package/plugin-src/client/channels/weixin/index.js +0 -19
  14. package/plugin-src/client/channels/weixin/styles.js +2 -2
  15. package/plugin-src/client/index.js +4 -4
  16. package/scripts/verify-package.mjs +48 -11
  17. package/src/channels/dingtalk/dingtalk-api.mjs +101 -5
  18. package/src/channels/dingtalk/dingtalk-bridge.mjs +198 -22
  19. package/src/channels/discord/discord-api.mjs +35 -0
  20. package/src/channels/discord/discord-bridge.mjs +1 -0
  21. package/src/channels/discord/discord-runtime.mjs +26 -0
  22. package/src/channels/feishu/bridge.mjs +21 -28
  23. package/src/channels/feishu/message-utils.mjs +1 -1
  24. package/src/channels/shared/connection-test.mjs +1 -1
  25. package/src/channels/shared/i18n-en/feishu.mjs +6 -6
  26. package/src/channels/shared/i18n-en/shared-c.mjs +2 -2
  27. package/src/channels/shared/status-reaction.mjs +107 -0
  28. package/src/channels/shared/text-harness-bridge.mjs +58 -6
  29. package/src/channels/slack/manifest.mjs +1 -0
  30. package/src/channels/slack/slack-api.mjs +28 -0
  31. package/src/channels/slack/slack-bridge.mjs +5 -0
  32. package/src/channels/slack/slack-runtime.mjs +24 -0
  33. package/src/channels/telegram/telegram-api.mjs +9 -0
  34. package/src/channels/telegram/telegram-bridge.mjs +1 -0
  35. package/src/channels/telegram/telegram-runtime.mjs +20 -0
  36. package/src/channels/whatsapp/whatsapp-bridge.mjs +1 -0
  37. package/src/channels/whatsapp/whatsapp-runtime.mjs +36 -0
package/lib/client.js CHANGED
@@ -47,7 +47,7 @@ var React20 = __toESM(require("react"), 1);
47
47
  // package.json
48
48
  var package_default = {
49
49
  name: "@xmanrui/dsh-im",
50
- version: "2.5.0",
50
+ version: "3.0.0",
51
51
  description: "\u628A\u4E5D\u79CD IM \u673A\u5668\u4EBA\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect nine IM channels and a public AI Office to a local DeepSeek Harness.",
52
52
  keywords: [
53
53
  "deepseek-harness",
@@ -130,7 +130,7 @@ var package_default = {
130
130
  scripts: {
131
131
  build: "node plugin-src/client/build.mjs && node plugin-src/host/build.mjs",
132
132
  test: "node --test test/*.test.mjs test/channels/*/*.test.mjs",
133
- check: "npm test && npm run build && node scripts/verify-package.mjs"
133
+ check: "npm run build && npm test && node scripts/verify-package.mjs"
134
134
  },
135
135
  engines: {
136
136
  node: ">=22.19"
@@ -1947,7 +1947,7 @@ function LastMessageErrorSummary({ className = "", error }) {
1947
1947
  }
1948
1948
 
1949
1949
  // plugin-src/client/channels/dingtalk/styles.js
1950
- var DINGTALK_STYLE_ID = "xmanrui-dsh-dingtalk-settings";
1950
+ var DINGTALK_STYLE_ID = "xmanrui-dsh-im-dingtalk-settings";
1951
1951
  var CSS = String.raw`
1952
1952
  .ddt-page {
1953
1953
  --ddt-accent: #1677ff;
@@ -2075,7 +2075,7 @@ function installDingtalkStyles() {
2075
2075
  if (existing) return () => {
2076
2076
  };
2077
2077
  const style = document.createElement("style");
2078
- style.dataset.plugin = "@xmanrui/dsh-dingtalk";
2078
+ style.dataset.plugin = "@xmanrui/dsh-im";
2079
2079
  style.dataset.pluginCss = DINGTALK_STYLE_ID;
2080
2080
  style.textContent = CSS;
2081
2081
  document.head.appendChild(style);
@@ -3932,1315 +3932,743 @@ function useAnimationFrameScheduler() {
3932
3932
  );
3933
3933
  }
3934
3934
 
3935
- // plugin-src/client/channels/feishu/styles.js
3936
- var FEISHU_STYLE_ID = "beihuixinghe-dsh-feishu-settings";
3937
- var CSS3 = String.raw`
3938
- .bxf-page {
3939
- --bxf-accent: var(--dsw-alias-state-business-primary, #3370ff);
3940
- --bxf-success: var(--dsw-alias-state-success-primary, #20a162);
3941
- --bxf-warning: var(--dsw-alias-state-warn-primary, #d97706);
3942
- --bxf-error: var(--dsw-alias-state-error-primary, #d54941);
3943
- box-sizing: border-box;
3944
- width: 100%;
3945
- max-width: 860px;
3946
- color: var(--dsw-alias-label-primary, #1f2329);
3947
- display: flex;
3948
- flex-direction: column;
3949
- container-type: inline-size;
3950
- gap: 18px;
3951
- padding: 2px 0 24px;
3952
- }
3953
-
3954
- .bxf-page *, .bxf-page *::before, .bxf-page *::after { box-sizing: border-box; }
3955
-
3956
- .bxf-heading {
3957
- display: flex;
3958
- align-items: flex-start;
3959
- justify-content: space-between;
3960
- gap: 20px;
3961
- }
3962
-
3963
- .bxf-headingCopy { min-width: 0; }
3964
- .bxf-heading h2, .bxf-heading p, .bxf-card h3, .bxf-card p { margin: 0; }
3965
-
3966
- .bxf-eyebrow {
3967
- color: var(--dsw-alias-label-tertiary, #8f959e);
3968
- font-size: 12px;
3969
- font-weight: 600;
3970
- line-height: 18px;
3971
- letter-spacing: .08em;
3972
- text-transform: uppercase;
3973
- margin-bottom: 3px;
3974
- }
3975
-
3976
- .bxf-heading h2 {
3977
- font-size: 20px;
3978
- line-height: 28px;
3979
- font-weight: 650;
3980
- letter-spacing: -.015em;
3935
+ // plugin-src/client/channels/feishu/index.js
3936
+ var CALLBACK_REPAIR_OPERATION = FEISHU_REGISTRATION_OPERATIONS.CALLBACK_REPAIR;
3937
+ var GROUP_MESSAGE_PERMISSION_OPERATION = FEISHU_REGISTRATION_OPERATIONS.GROUP_MESSAGE_PERMISSION;
3938
+ function isCallbackRepair(value) {
3939
+ return value?.operation === CALLBACK_REPAIR_OPERATION;
3981
3940
  }
3982
-
3983
- .bxf-heading p {
3984
- max-width: 540px;
3985
- color: var(--dsw-alias-label-secondary, #646a73);
3986
- font-size: 13px;
3987
- line-height: 20px;
3988
- margin-top: 5px;
3989
- white-space: nowrap;
3941
+ function isGroupMessagePermission(value) {
3942
+ return value?.operation === GROUP_MESSAGE_PERMISSION_OPERATION;
3990
3943
  }
3991
-
3992
- .bxf-headingTools {
3993
- width: 100%;
3994
- flex: none;
3995
- display: flex;
3996
- align-items: center;
3997
- justify-content: space-between;
3998
- flex-wrap: nowrap;
3999
- gap: 8px;
3944
+ function isTargetedAppUpdate2(value) {
3945
+ return isCallbackRepair(value) || isGroupMessagePermission(value);
4000
3946
  }
4001
-
4002
- .bxf-totalBadge {
4003
- min-height: 28px;
4004
- display: inline-flex;
4005
- align-items: baseline;
4006
- gap: 3px;
4007
- border-radius: 999px;
4008
- padding: 4px 10px;
4009
- color: var(--dsw-alias-label-secondary, #646a73);
4010
- background: var(--dsw-alias-bg-module-platform, #f2f3f5);
4011
- font-size: 11px;
4012
- line-height: 16px;
4013
- white-space: nowrap;
3947
+ function SvgIcon({ children, size = 18, className, viewBox = "0 0 24 24" }) {
3948
+ return h2("svg", {
3949
+ width: size,
3950
+ height: size,
3951
+ viewBox,
3952
+ fill: "none",
3953
+ xmlns: "http://www.w3.org/2000/svg",
3954
+ "aria-hidden": "true",
3955
+ focusable: "false",
3956
+ className
3957
+ }, children);
4014
3958
  }
4015
-
4016
- .bxf-totalBadge strong { color: var(--bxf-success); font-size: 13px; }
4017
-
4018
- .bxf-card {
4019
- position: relative;
4020
- overflow: hidden;
4021
- border: 1px solid var(--dsw-alias-border-l2, #dee0e3);
4022
- border-radius: 14px;
4023
- background: var(--dsw-alias-bg-layer-3, #fff);
4024
- box-shadow: var(--dsw-shadow-lv1, 0 3px 12px rgba(31, 35, 41, .05));
3959
+ function RobotIcon({ size = 26 }) {
3960
+ return h2(
3961
+ SvgIcon,
3962
+ { size },
3963
+ h2("rect", {
3964
+ x: "5",
3965
+ y: "7.5",
3966
+ width: "14",
3967
+ height: "11",
3968
+ rx: "4",
3969
+ stroke: "currentColor",
3970
+ strokeWidth: "1.7"
3971
+ }),
3972
+ h2("path", {
3973
+ d: "M12 4.5v3M8.7 12h.01M15.3 12h.01M9.2 15.3c1.67 1.08 3.93 1.08 5.6 0M3.5 11.5v3M20.5 11.5v3",
3974
+ stroke: "currentColor",
3975
+ strokeWidth: "1.7",
3976
+ strokeLinecap: "round"
3977
+ })
3978
+ );
4025
3979
  }
4026
-
4027
- .bxf-card::before {
4028
- content: "";
4029
- pointer-events: none;
4030
- position: absolute;
4031
- inset: 0 0 auto;
4032
- height: 88px;
4033
- background:
4034
- radial-gradient(circle at 86% -35%, color-mix(in srgb, var(--bxf-accent) 18%, transparent), transparent 68%);
4035
- opacity: .85;
3980
+ function AlertIcon({ size = 22 }) {
3981
+ return h2(
3982
+ SvgIcon,
3983
+ { size },
3984
+ h2("path", {
3985
+ d: "M12 3.4 21 19H3L12 3.4Z",
3986
+ stroke: "currentColor",
3987
+ strokeWidth: "1.7",
3988
+ strokeLinejoin: "round"
3989
+ }),
3990
+ h2("path", {
3991
+ d: "M12 9v4.4M12 16.6v.01",
3992
+ stroke: "currentColor",
3993
+ strokeWidth: "1.9",
3994
+ strokeLinecap: "round"
3995
+ })
3996
+ );
4036
3997
  }
4037
-
4038
- .bxf-cardBody { position: relative; padding: 24px; }
4039
-
4040
- .bxf-intro {
4041
- min-height: 250px;
4042
- display: grid;
4043
- grid-template-columns: minmax(0, 1fr) 172px;
4044
- gap: 32px;
4045
- align-items: center;
3998
+ function QrIcon({ size = 58 }) {
3999
+ return h2(SvgIcon, { size }, h2("path", {
4000
+ d: "M4 4h6v6H4V4Zm10 0h6v6h-6V4ZM4 14h6v6H4v-6Zm10 0h2v2h-2v-2Zm4 0h2v4h-2v-4Zm-4 4h4v2h-4v-2Z",
4001
+ fill: "currentColor"
4002
+ }));
4046
4003
  }
4047
-
4048
- .bxf-introCopy { max-width: 500px; }
4049
-
4050
- .bxf-stateLabel {
4051
- display: inline-flex;
4052
- align-items: center;
4053
- gap: 7px;
4054
- color: var(--dsw-alias-label-secondary, #646a73);
4055
- font-size: 12px;
4056
- font-weight: 600;
4057
- line-height: 18px;
4058
- margin-bottom: 13px;
4004
+ var Button5 = React12.forwardRef(function Button6({ children, kind = "secondary", size, icon, className = "", ...props }, ref) {
4005
+ return h2("button", {
4006
+ ...props,
4007
+ ref,
4008
+ type: "button",
4009
+ className: `bxf-button ${className}`.trim(),
4010
+ "data-kind": kind,
4011
+ "data-size": size
4012
+ }, icon, h2("span", null, children));
4013
+ });
4014
+ function BrandMark() {
4015
+ return h2("div", { className: "bxf-brandMark" }, h2(RobotIcon, { size: 34 }));
4059
4016
  }
4060
-
4061
- .bxf-dot {
4062
- width: 7px;
4063
- height: 7px;
4064
- border-radius: 50%;
4065
- background: var(--dsw-alias-label-tertiary, #8f959e);
4066
- box-shadow: 0 0 0 4px color-mix(in srgb, var(--dsw-alias-label-tertiary, #8f959e) 12%, transparent);
4017
+ function Heading2({ totals, onAdd, onCredential, credentialOpen, adding, busy, addButtonRef }) {
4018
+ const hasBots = totals.configured > 0;
4019
+ return h2(
4020
+ "div",
4021
+ { className: "bxf-heading" },
4022
+ h2(
4023
+ "div",
4024
+ { className: "bxf-headingTools" },
4025
+ h2(
4026
+ "div",
4027
+ { className: "dim-bindActions" },
4028
+ h2(Button5, {
4029
+ kind: "primary",
4030
+ size: "small",
4031
+ className: "bxf-bindButton dim-scanButton",
4032
+ onClick: onAdd,
4033
+ disabled: adding || busy,
4034
+ ref: addButtonRef,
4035
+ "aria-busy": busy ? "true" : void 0,
4036
+ "aria-label": "\u626B\u7801\u63A5\u5165\u98DE\u4E66\u673A\u5668\u4EBA",
4037
+ icon: h2(QrActionIcon)
4038
+ }, adding ? "\u6B63\u5728\u63A5\u5165" : "\u626B\u7801\u63A5\u5165\u673A\u5668\u4EBA"),
4039
+ h2(Button5, {
4040
+ kind: "credential",
4041
+ size: "small",
4042
+ className: "dim-credentialButton",
4043
+ onClick: onCredential,
4044
+ disabled: adding || busy,
4045
+ "aria-pressed": credentialOpen,
4046
+ "aria-label": "\u4F7F\u7528 App ID \u548C App Secret \u7ED1\u5B9A\u98DE\u4E66\u673A\u5668\u4EBA",
4047
+ icon: h2(CredentialActionIcon)
4048
+ }, credentialOpen ? "\u6536\u8D77\u51ED\u636E" : "\u624B\u52A8\u63A5\u5165")
4049
+ ),
4050
+ hasBots ? h2("div", {
4051
+ className: "bxf-totalBadge dim-onlineBadge",
4052
+ "aria-label": `\u5DF2\u63A5\u5165 ${totals.configured} \u4E2A\u673A\u5668\u4EBA\uFF0C\u5176\u4E2D ${totals.connected} \u4E2A\u5728\u7EBF`
4053
+ }, h2("span", null, `${totals.connected} / ${totals.configured} \u5728\u7EBF`)) : null
4054
+ )
4055
+ );
4067
4056
  }
4068
-
4069
- .bxf-dot[data-tone="success"] {
4070
- background: var(--bxf-success);
4071
- box-shadow: 0 0 0 4px color-mix(in srgb, var(--bxf-success) 13%, transparent);
4057
+ function LoadingView2() {
4058
+ return h2(
4059
+ "div",
4060
+ {
4061
+ className: "bxf-card dim-surfaceCard dim-loadingView",
4062
+ "aria-busy": "true",
4063
+ "aria-label": "\u6B63\u5728\u8BFB\u53D6\u98DE\u4E66\u673A\u5668\u4EBA\u5217\u8868"
4064
+ },
4065
+ h2("div", { className: "dim-spinner", "aria-hidden": "true" }),
4066
+ h2("span", null, "\u6B63\u5728\u8BFB\u53D6\u98DE\u4E66\u8FDE\u63A5\u72B6\u6001\u2026")
4067
+ );
4072
4068
  }
4073
-
4074
- .bxf-dot[data-tone="warning"] {
4075
- background: var(--bxf-warning);
4076
- box-shadow: 0 0 0 4px color-mix(in srgb, var(--bxf-warning) 13%, transparent);
4077
- }
4078
-
4079
- .bxf-dot[data-tone="error"] {
4080
- background: var(--bxf-error);
4081
- box-shadow: 0 0 0 4px color-mix(in srgb, var(--bxf-error) 13%, transparent);
4082
- }
4083
-
4084
- .bxf-intro h3 {
4085
- font-size: 24px;
4086
- line-height: 34px;
4087
- font-weight: 650;
4088
- letter-spacing: -.02em;
4069
+ function EmptyView2({ onStart, busy }) {
4070
+ return h2(
4071
+ "div",
4072
+ { className: "bxf-card dim-surfaceCard" },
4073
+ h2(
4074
+ "div",
4075
+ { className: "bxf-cardBody bxf-intro dim-surfaceBody dim-emptyView" },
4076
+ h2(
4077
+ "div",
4078
+ { className: "bxf-introCopy dim-emptyCopy" },
4079
+ h2(
4080
+ "div",
4081
+ { className: "bxf-stateLabel dim-stateLabel" },
4082
+ h2("span", { className: "bxf-dot dim-stateDot" }),
4083
+ h2("span", null, "\u5C1A\u672A\u63A5\u5165\u673A\u5668\u4EBA")
4084
+ ),
4085
+ h2("h3", null, "\u626B\u7801\uFF0C\u521B\u5EFA\u7B2C\u4E00\u4E2A\u98DE\u4E66\u5165\u53E3"),
4086
+ h2("p", null, "\u65E0\u9700\u624B\u52A8\u586B\u5199 App ID\u3002\u4EE5\u540E\u8FD8\u53EF\u4EE5\u7EE7\u7EED\u6DFB\u52A0\u673A\u5668\u4EBA\uFF0C\u5206\u522B\u670D\u52A1\u4E0D\u540C\u56E2\u961F\u6216\u98DE\u4E66\u79DF\u6237\u3002"),
4087
+ h2(
4088
+ "div",
4089
+ { className: "bxf-actions dim-viewActions" },
4090
+ h2(Button5, {
4091
+ kind: "primary",
4092
+ onClick: onStart,
4093
+ disabled: busy,
4094
+ "aria-busy": busy ? "true" : void 0
4095
+ }, busy ? "\u6B63\u5728\u751F\u6210\u4E8C\u7EF4\u7801\u2026" : "\u751F\u6210\u98DE\u4E66\u4E8C\u7EF4\u7801")
4096
+ )
4097
+ ),
4098
+ h2("div", { className: "bxf-markStage dim-emptyBrand", "aria-hidden": "true" }, h2(BrandMark))
4099
+ )
4100
+ );
4089
4101
  }
4090
-
4091
- .bxf-introCopy > p {
4092
- max-width: 490px;
4093
- color: var(--dsw-alias-label-secondary, #646a73);
4094
- font-size: 14px;
4095
- line-height: 23px;
4096
- margin-top: 8px;
4102
+ function safeVerificationHref(value) {
4103
+ if (!value) return void 0;
4104
+ try {
4105
+ const url = new URL(value);
4106
+ return url.protocol === "https:" && [
4107
+ "accounts.feishu.cn",
4108
+ "accounts.larksuite.com",
4109
+ "open.feishu.cn",
4110
+ "open.larksuite.com"
4111
+ ].includes(url.hostname) && !url.port && !url.username && !url.password ? url.toString() : void 0;
4112
+ } catch {
4113
+ return void 0;
4114
+ }
4097
4115
  }
4098
-
4099
- .bxf-note {
4100
- display: flex;
4101
- gap: 8px;
4102
- align-items: flex-start;
4103
- color: var(--dsw-alias-label-tertiary, #8f959e);
4104
- font-size: 12px;
4105
- line-height: 18px;
4106
- margin-top: 16px;
4116
+ function safeQrSource2(value) {
4117
+ if (!value) return void 0;
4118
+ return /^data:image\/(?:png|webp|svg\+xml)(?:;charset=[^;,]+)?;base64,/i.test(value) ? value : void 0;
4107
4119
  }
4108
-
4109
- .bxf-note svg { flex: none; margin-top: 1px; }
4110
-
4111
- .bxf-actions {
4112
- display: flex;
4113
- align-items: center;
4114
- flex-wrap: wrap;
4115
- gap: 10px;
4116
- margin-top: 22px;
4120
+ function QrPane({ provision, now, onRefresh, onCancel, busy }) {
4121
+ const [imageFailed, setImageFailed] = React12.useState(false);
4122
+ const qrSource = safeQrSource2(provision.qrCodeDataUrl);
4123
+ const href = safeVerificationHref(provision.verificationUrl);
4124
+ const remaining = Math.max(0, provision.expiresAt - now);
4125
+ const expired = provision.expired === true || remaining === 0;
4126
+ const progress = Math.min(1, remaining / Math.max(1, provision.durationMs ?? remaining));
4127
+ const repairing = isCallbackRepair(provision);
4128
+ const grantingGroupMessages = isGroupMessagePermission(provision);
4129
+ const botName = provision.botName ?? "\u6B64\u673A\u5668\u4EBA";
4130
+ React12.useEffect(() => setImageFailed(false), [qrSource]);
4131
+ return h2(
4132
+ "div",
4133
+ { className: "bxf-card bxf-provisionCard dim-surfaceCard" },
4134
+ h2(
4135
+ "div",
4136
+ { className: "bxf-cardBody bxf-qrLayout dim-surfaceBody dim-qrLayout" },
4137
+ h2(
4138
+ "div",
4139
+ { className: "bxf-qrColumn dim-qrColumn" },
4140
+ h2(
4141
+ "div",
4142
+ { className: "bxf-qrFrame dim-qrFrame" },
4143
+ qrSource && !imageFailed ? h2("img", {
4144
+ src: qrSource,
4145
+ alt: repairing ? `\u7528\u4E8E\u4E3A${botName}\u8865\u5168\u6743\u9650\u4E0E\u56DE\u8C03\u7684\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801` : grantingGroupMessages ? `\u7528\u4E8E\u4E3A${botName}\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650\u7684\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801` : "\u7528\u4E8E\u65B0\u589E DeepSeek Harness \u98DE\u4E66\u673A\u5668\u4EBA\u7684\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801",
4146
+ onError: () => setImageFailed(true)
4147
+ }) : h2(
4148
+ "div",
4149
+ { className: "bxf-qrFallback dim-qrFallback" },
4150
+ h2("div", null, h2(QrIcon), h2("span", null, "\u4E8C\u7EF4\u7801\u672A\u5C31\u7EEA\uFF0C\u8BF7\u6253\u5F00\u6388\u6743\u94FE\u63A5"))
4151
+ ),
4152
+ expired ? h2(
4153
+ "div",
4154
+ { className: "bxf-expiredOverlay dim-qrExpired", role: "status" },
4155
+ h2("div", null, "\u4E8C\u7EF4\u7801\u5DF2\u5931\u6548", h2("br"), "\u8BF7\u5237\u65B0\u540E\u91CD\u65B0\u626B\u7801")
4156
+ ) : null
4157
+ ),
4158
+ h2(
4159
+ "div",
4160
+ {
4161
+ className: "bxf-countdown dim-countdown",
4162
+ "aria-label": expired ? "\u4E8C\u7EF4\u7801\u5DF2\u5931\u6548" : `\u4E8C\u7EF4\u7801\u5269\u4F59 ${formatRemaining2(remaining)}`
4163
+ },
4164
+ h2(
4165
+ "div",
4166
+ { className: "bxf-countdownTop dim-countdownTop", "aria-hidden": "true" },
4167
+ h2("span", null, expired ? "\u7B49\u5F85\u5237\u65B0" : "\u4E8C\u7EF4\u7801\u6709\u6548\u65F6\u95F4"),
4168
+ h2("strong", null, formatRemaining2(remaining))
4169
+ ),
4170
+ h2(
4171
+ "div",
4172
+ { className: "bxf-progress dim-progress", "aria-hidden": "true" },
4173
+ h2("span", { style: { "--bxf-progress": `${Math.round(progress * 100)}%` } })
4174
+ )
4175
+ )
4176
+ ),
4177
+ h2(
4178
+ "div",
4179
+ { className: "bxf-qrCopy dim-qrCopy" },
4180
+ h2(
4181
+ "div",
4182
+ { className: "bxf-stateLabel dim-stateLabel" },
4183
+ h2("span", { className: "bxf-dot dim-stateDot", "data-tone": "warning" }),
4184
+ h2("span", null, repairing ? `\u6B63\u5728\u4E3A\u300C${botName}\u300D\u8865\u5168\u6743\u9650\u4E0E\u56DE\u8C03` : grantingGroupMessages ? `\u6B63\u5728\u4E3A\u300C${botName}\u300D\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650` : "\u6B63\u5728\u6DFB\u52A0\u65B0\u673A\u5668\u4EBA")
4185
+ ),
4186
+ h2("h3", null, expired ? "\u5237\u65B0\u4E8C\u7EF4\u7801\u540E\u7EE7\u7EED" : repairing ? "\u4F7F\u7528\u98DE\u4E66\u626B\u7801\u8865\u5168\u6743\u9650" : grantingGroupMessages ? "\u4F7F\u7528\u98DE\u4E66\u786E\u8BA4\u7FA4\u6D88\u606F\u6743\u9650" : "\u4F7F\u7528\u98DE\u4E66\u626B\u7801\u521B\u5EFA\u673A\u5668\u4EBA"),
4187
+ h2("p", null, repairing ? "\u626B\u7801\u4F1A\u66F4\u65B0\u73B0\u6709\u98DE\u4E66\u5E94\u7528\uFF0C\u6700\u591A\u589E\u91CF\u8865\u5145\u5361\u7247\u6309\u94AE\u56DE\u8C03\u3001\u8BFB\u53D6\u7528\u6237\u6D88\u606F\u5185\u56FE\u7247\u6216\u6587\u4EF6\u6240\u9700\u7684 im:message:readonly\uFF08\u98DE\u4E66\u663E\u793A\u4E3A\u201C\u83B7\u53D6\u5355\u804A\u3001\u7FA4\u7EC4\u6D88\u606F\u201D\uFF09\uFF0C\u4EE5\u53CA\u4E0A\u4F20\u673A\u5668\u4EBA\u56FE\u7247\u6216\u6587\u4EF6\u6240\u9700\u7684 im:resource\uFF1B\u4E0D\u4F1A\u521B\u5EFA\u65B0\u5E94\u7528\u3002\u786E\u8BA4\u9875\u53EA\u663E\u793A\u5F53\u524D\u7F3A\u5C11\u9879\uFF0C\u5B8C\u6210\u540E\u6B64\u673A\u5668\u4EBA\u4F1A\u77ED\u6682\u91CD\u8FDE\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u53D7\u5F71\u54CD\u3002" : grantingGroupMessages ? "\u626B\u7801\u4F1A\u66F4\u65B0\u73B0\u6709\u98DE\u4E66\u5E94\u7528\uFF0C\u53EA\u589E\u91CF\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF1B\u4E0D\u4F1A\u521B\u5EFA\u65B0\u5E94\u7528\u3002\u786E\u8BA4\u540E\u4F1A\u81EA\u52A8\u542F\u7528\u201C\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F\u201D\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u53D7\u5F71\u54CD\u3002" : "\u626B\u7801\u53EA\u4F1A\u65B0\u589E\u4E00\u4E2A\u673A\u5668\u4EBA\uFF0C\u5DF2\u63A5\u5165\u7684\u673A\u5668\u4EBA\u4F1A\u7EE7\u7EED\u6B63\u5E38\u6536\u53D1\u6D88\u606F\u3002"),
4188
+ h2(
4189
+ "ol",
4190
+ { className: "bxf-steps dim-steps" },
4191
+ h2("li", null, "\u6253\u5F00\u98DE\u4E66\u79FB\u52A8\u7AEF\uFF0C\u4F7F\u7528\u626B\u4E00\u626B\u8BFB\u53D6\u4E8C\u7EF4\u7801"),
4192
+ h2("li", null, repairing ? "\u6838\u5BF9\u73B0\u6709\u5E94\u7528\u540D\u79F0\uFF0C\u5E76\u786E\u8BA4\u53EA\u65B0\u589E\u5F53\u524D\u7F3A\u5C11\u7684\u4E0A\u8FF0\u914D\u7F6E" : grantingGroupMessages ? "\u6838\u5BF9\u73B0\u6709\u5E94\u7528\uFF0C\u5E76\u786E\u8BA4\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650" : "\u6838\u5BF9\u5E94\u7528\u540D\u79F0\u4E0E\u6743\u9650\u8303\u56F4\uFF0C\u5E76\u786E\u8BA4\u521B\u5EFA"),
4193
+ h2("li", null, repairing ? "\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u6743\u9650\u4E0E\u56DE\u8C03\u8865\u5168\u5B8C\u6210" : grantingGroupMessages ? "\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u6743\u9650\u751F\u6548\u5E76\u81EA\u52A8\u5207\u6362\u54CD\u5E94\u65B9\u5F0F" : "\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u65B0\u673A\u5668\u4EBA\u7684\u957F\u8FDE\u63A5\u5C31\u7EEA")
4194
+ ),
4195
+ h2(
4196
+ "div",
4197
+ { className: "bxf-actions dim-viewActions" },
4198
+ expired ? h2(Button5, {
4199
+ kind: "primary",
4200
+ onClick: onRefresh,
4201
+ disabled: busy
4202
+ }, busy ? "\u5237\u65B0\u4E2D\u2026" : "\u5237\u65B0\u4E8C\u7EF4\u7801") : href ? h2("a", {
4203
+ className: "bxf-button bxf-link",
4204
+ "data-kind": "secondary",
4205
+ href,
4206
+ target: "_blank",
4207
+ rel: "noopener noreferrer"
4208
+ }, h2("span", null, "\u5728\u98DE\u4E66\u4E2D\u6253\u5F00")) : null,
4209
+ !expired ? h2(Button5, { onClick: onRefresh, disabled: busy }, "\u6362\u4E00\u4E2A\u4E8C\u7EF4\u7801") : null,
4210
+ h2(Button5, { onClick: onCancel, disabled: busy }, repairing ? "\u53D6\u6D88\u8865\u5168" : grantingGroupMessages ? "\u53D6\u6D88\u6388\u6743" : "\u53D6\u6D88\u6DFB\u52A0")
4211
+ )
4212
+ )
4213
+ )
4214
+ );
4117
4215
  }
4118
-
4119
- .bxf-button {
4120
- appearance: none;
4121
- min-height: 36px;
4122
- display: inline-flex;
4123
- align-items: center;
4124
- justify-content: center;
4125
- gap: 7px;
4126
- border: 1px solid var(--dsw-alias-border-l2, #dee0e3);
4127
- border-radius: 8px;
4128
- padding: 7px 13px;
4129
- color: var(--dsw-alias-label-primary, #1f2329);
4130
- background: var(--dsw-alias-bg-layer-1, #fff);
4131
- font: inherit;
4132
- font-size: 13px;
4133
- font-weight: 550;
4134
- line-height: 20px;
4135
- text-decoration: none;
4136
- cursor: pointer;
4137
- transition: background .15s var(--ds-ease-in-out, ease), border-color .15s var(--ds-ease-in-out, ease), transform .15s var(--ds-ease-in-out, ease);
4216
+ function ProvisionProgress({ phase, provision, onCancel, busy }) {
4217
+ const connecting = phase === "connecting";
4218
+ const repairing = isCallbackRepair(provision);
4219
+ const grantingGroupMessages = isGroupMessagePermission(provision);
4220
+ return h2(
4221
+ "div",
4222
+ {
4223
+ className: "bxf-card bxf-provisionCard dim-surfaceCard dim-loadingView",
4224
+ "aria-busy": "true"
4225
+ },
4226
+ h2("div", { className: "dim-spinner", "aria-hidden": "true" }),
4227
+ h2("h3", null, connecting ? repairing ? "\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u5B8C\u6210\u6743\u9650\u4E0E\u56DE\u8C03\u914D\u7F6E" : grantingGroupMessages ? "\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u542F\u7528\u5168\u90E8\u6D88\u606F\u6A21\u5F0F" : "\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u8FDE\u63A5\u65B0\u673A\u5668\u4EBA" : repairing ? "\u6B63\u5728\u51C6\u5907\u6743\u9650\u8865\u5168\u4E8C\u7EF4\u7801" : grantingGroupMessages ? "\u6B63\u5728\u51C6\u5907\u6743\u9650\u6388\u6743\u4E8C\u7EF4\u7801" : "\u6B63\u5728\u51C6\u5907\u6388\u6743\u4E8C\u7EF4\u7801"),
4228
+ h2("p", null, connecting ? repairing ? "\u914D\u7F6E\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u4FDD\u5B58\u6743\u9650\u3001\u9A8C\u8BC1\u5361\u7247\u56DE\u8C03\u5E76\u91CD\u8FDE\u6B64\u673A\u5668\u4EBA\uFF1B\u6B64\u9636\u6BB5\u65E0\u6CD5\u53D6\u6D88\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002" : grantingGroupMessages ? "\u6743\u9650\u914D\u7F6E\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u4FDD\u5B58\u8BBE\u7F6E\u5E76\u91CD\u8FDE\u6B64\u673A\u5668\u4EBA\uFF1B\u6B64\u9636\u6BB5\u65E0\u6CD5\u53D6\u6D88\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002" : "\u6B63\u5728\u5B89\u5168\u4FDD\u5B58\u51ED\u636E\u5E76\u68C0\u67E5\u65B0\u673A\u5668\u4EBA\u7684\u6D88\u606F\u901A\u9053\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002" : repairing ? "\u6B63\u5728\u4E3A\u73B0\u6709\u98DE\u4E66\u5E94\u7528\u7533\u8BF7\u4E00\u6B21\u6027\u66F4\u65B0\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u5019\u3002" : grantingGroupMessages ? "\u6B63\u5728\u4E3A\u73B0\u6709\u98DE\u4E66\u5E94\u7528\u7533\u8BF7\u7FA4\u6D88\u606F\u6743\u9650\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u5019\u3002" : "\u6B63\u5728\u5411\u98DE\u4E66\u7533\u8BF7\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u5019\u3002"),
4229
+ connecting && onCancel ? h2(
4230
+ "div",
4231
+ { className: "bxf-actions dim-viewActions", style: { justifyContent: "center" } },
4232
+ h2(Button5, { onClick: onCancel, disabled: busy }, repairing ? "\u53D6\u6D88\u8865\u5168" : grantingGroupMessages ? "\u53D6\u6D88\u6388\u6743" : "\u53D6\u6D88\u6DFB\u52A0")
4233
+ ) : null
4234
+ );
4138
4235
  }
4139
-
4140
- .bxf-button:hover:not(:disabled) {
4141
- background: var(--dsw-alias-interactive-bg-hover, #f2f3f5);
4142
- border-color: var(--dsw-alias-border-l1, #c9cdd4);
4236
+ function ProvisionError2({ error, provision, onRetry, onCancel, busy }) {
4237
+ const repairing = isCallbackRepair(provision);
4238
+ const grantingGroupMessages = isGroupMessagePermission(provision);
4239
+ return h2(
4240
+ "div",
4241
+ { className: "bxf-card bxf-provisionCard dim-surfaceCard" },
4242
+ h2(
4243
+ "div",
4244
+ { className: "bxf-inlineError dim-inlineError", role: "alert" },
4245
+ h2(
4246
+ "div",
4247
+ null,
4248
+ h2("h3", null, repairing ? "\u6743\u9650\u4E0E\u56DE\u8C03\u6CA1\u6709\u8865\u5168\u5B8C\u6210" : grantingGroupMessages ? "\u7FA4\u6D88\u606F\u6743\u9650\u6CA1\u6709\u5F00\u901A\u5B8C\u6210" : "\u65B0\u673A\u5668\u4EBA\u6CA1\u6709\u6DFB\u52A0\u5B8C\u6210"),
4249
+ h2("p", null, error.message),
4250
+ error.code ? h2("span", { className: "bxf-errorCode" }, error.code) : null,
4251
+ h2(
4252
+ "div",
4253
+ { className: "bxf-actions dim-viewActions" },
4254
+ h2(
4255
+ Button5,
4256
+ { kind: "primary", onClick: onRetry, disabled: busy },
4257
+ busy ? "\u91CD\u8BD5\u4E2D\u2026" : "\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801"
4258
+ ),
4259
+ h2(Button5, { onClick: onCancel, disabled: busy }, "\u5173\u95ED")
4260
+ )
4261
+ )
4262
+ )
4263
+ );
4143
4264
  }
4144
-
4145
- .bxf-button:active:not(:disabled) { transform: translateY(1px); }
4146
-
4147
- .bxf-button:focus-visible, .bxf-link:focus-visible {
4148
- outline: 2px solid var(--bxf-accent);
4149
- outline-offset: 2px;
4150
- }
4151
-
4152
- .bxf-button:disabled { cursor: not-allowed; opacity: .55; }
4153
-
4154
- .bxf-button[data-kind="primary"] {
4155
- border-color: var(--bxf-accent);
4156
- color: #fff;
4157
- background: var(--bxf-accent);
4158
- box-shadow: 0 4px 12px color-mix(in srgb, var(--bxf-accent) 24%, transparent);
4159
- }
4160
-
4161
- .bxf-button[data-kind="primary"]:hover:not(:disabled) {
4162
- border-color: color-mix(in srgb, var(--bxf-accent) 86%, #000);
4163
- background: color-mix(in srgb, var(--bxf-accent) 90%, #000);
4164
- }
4165
-
4166
- .bxf-button[data-kind="danger"] { color: var(--bxf-error); }
4167
- .bxf-button[data-size="small"] { min-height: 32px; padding: 5px 10px; font-size: 12px; }
4168
- .bxf-bindButton { flex: none; white-space: nowrap; }
4169
-
4170
- .bxf-provisionCard {
4171
- border-color: color-mix(in srgb, var(--bxf-accent) 32%, var(--dsw-alias-border-l2, #dee0e3));
4172
- }
4173
-
4174
- .bxf-markStage {
4175
- position: relative;
4176
- width: 156px;
4177
- height: 156px;
4178
- display: grid;
4179
- place-items: center;
4180
- justify-self: end;
4181
- }
4182
-
4183
- .bxf-markStage::before, .bxf-markStage::after {
4184
- content: "";
4185
- position: absolute;
4186
- border-radius: 50%;
4187
- }
4188
-
4189
- .bxf-markStage::before {
4190
- inset: 12px;
4191
- border: 1px solid color-mix(in srgb, var(--bxf-accent) 18%, var(--dsw-alias-border-l2, #dee0e3));
4192
- background: color-mix(in srgb, var(--bxf-accent) 4%, var(--dsw-alias-bg-layer-1, #fff));
4193
- }
4194
-
4195
- .bxf-markStage::after {
4196
- inset: 0;
4197
- border: 1px dashed color-mix(in srgb, var(--bxf-accent) 16%, transparent);
4198
- animation: bxf-rotate 18s linear infinite;
4199
- }
4200
-
4201
- .bxf-brandMark {
4202
- position: relative;
4203
- z-index: 1;
4204
- width: 68px;
4205
- height: 68px;
4206
- display: grid;
4207
- place-items: center;
4208
- border-radius: 20px;
4209
- color: #fff;
4210
- background: var(--bxf-accent);
4211
- box-shadow: 0 12px 28px color-mix(in srgb, var(--bxf-accent) 28%, transparent);
4265
+ var HEALTH_LABELS = {
4266
+ connected: "\u8FD0\u884C\u6B63\u5E38",
4267
+ connecting: "\u6B63\u5728\u8FDE\u63A5",
4268
+ offline: "\u8FDE\u63A5\u4E2D\u65AD",
4269
+ error: "\u9700\u8981\u5904\u7406"
4270
+ };
4271
+ function formatCheckedTime(timestamp7) {
4272
+ if (!timestamp7) return "\u5C1A\u672A\u68C0\u67E5";
4273
+ try {
4274
+ return new Intl.DateTimeFormat("zh-CN", {
4275
+ hour: "2-digit",
4276
+ minute: "2-digit",
4277
+ second: "2-digit"
4278
+ }).format(new Date(timestamp7));
4279
+ } catch {
4280
+ return "\u521A\u521A";
4281
+ }
4212
4282
  }
4213
-
4214
- .bxf-qrLayout {
4215
- display: grid;
4216
- grid-template-columns: 236px minmax(0, 1fr);
4217
- align-items: center;
4218
- gap: 32px;
4283
+ function connectionTestNotice2(value) {
4284
+ if (value?.testMessage?.sent === true) {
4285
+ return "\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\uFF0C\u8BF7\u5230\u98DE\u4E66\u4F1A\u8BDD\u4E2D\u786E\u8BA4\u3002";
4286
+ }
4287
+ if (value?.testMessage?.code === "test-target-unavailable") {
4288
+ return "\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\u3002\u673A\u5668\u4EBA\u5C1A\u672A\u6536\u5230\u53EF\u7528\u4E8E\u6D4B\u8BD5\u7684\u79C1\u804A\u6D88\u606F\u3002";
4289
+ }
4290
+ return value?.testMessage ? "\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u6D4B\u8BD5\u6D88\u606F\u53D1\u9001\u5931\u8D25\u3002" : null;
4219
4291
  }
4220
-
4221
- .bxf-qrColumn { min-width: 0; }
4222
-
4223
- .bxf-qrFrame {
4224
- position: relative;
4225
- width: 222px;
4226
- height: 222px;
4227
- display: grid;
4228
- place-items: center;
4229
- border: 1px solid var(--dsw-alias-border-l2, #dee0e3);
4230
- border-radius: 14px;
4231
- padding: 13px;
4232
- background: #fff;
4233
- box-shadow: 0 8px 24px rgba(31, 35, 41, .07);
4292
+ function RemoveConfirmation2({ bot, busy, onConfirm, onCancel }) {
4293
+ const cancelRef = React12.useRef(null);
4294
+ const idPart = bot.botId.replace(/[^a-zA-Z0-9_-]/g, "-");
4295
+ const titleId = `bxf-remove-title-${idPart}`;
4296
+ const descriptionId = `bxf-remove-description-${idPart}`;
4297
+ React12.useEffect(() => cancelRef.current?.focus(), []);
4298
+ return h2(
4299
+ "div",
4300
+ {
4301
+ className: "bxf-confirm dim-confirm",
4302
+ role: "alertdialog",
4303
+ "aria-labelledby": titleId,
4304
+ "aria-describedby": descriptionId,
4305
+ onKeyDown: (event) => {
4306
+ if (event.key === "Escape" && !busy) {
4307
+ event.preventDefault();
4308
+ onCancel();
4309
+ }
4310
+ }
4311
+ },
4312
+ h2("h4", { id: titleId }, `\u4ECE DeepSeek Harness \u79FB\u9664\u201C${bot.bot.name}\u201D\uFF1F`),
4313
+ h2(
4314
+ "p",
4315
+ { id: descriptionId },
4316
+ "\u6B64\u64CD\u4F5C\u4F1A\u505C\u6B62\u8FD9\u4E2A\u673A\u5668\u4EBA\u7684\u8FDE\u63A5\uFF0C\u5E76\u5220\u9664\u4FDD\u5B58\u5728\u672C\u673A\u7684\u63A5\u5165\u914D\u7F6E\u548C\u51ED\u636E\u3002\u98DE\u4E66\u5F00\u653E\u5E73\u53F0\u4E2D\u7684\u5E94\u7528\u4E0D\u4F1A\u88AB\u81EA\u52A8\u5220\u9664\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E5F\u4E0D\u53D7\u5F71\u54CD\u3002"
4317
+ ),
4318
+ h2(
4319
+ "div",
4320
+ { className: "bxf-actions dim-viewActions" },
4321
+ h2(Button5, { ref: cancelRef, onClick: onCancel, disabled: busy }, "\u4FDD\u7559\u673A\u5668\u4EBA"),
4322
+ h2(
4323
+ Button5,
4324
+ { kind: "danger", onClick: onConfirm, disabled: busy },
4325
+ busy ? "\u6B63\u5728\u79FB\u9664\u2026" : "\u786E\u8BA4\u79FB\u9664\u63A5\u5165"
4326
+ )
4327
+ )
4328
+ );
4234
4329
  }
4235
-
4236
- .bxf-qrFrame::before, .bxf-qrFrame::after {
4237
- content: "";
4238
- position: absolute;
4239
- width: 24px;
4240
- height: 24px;
4241
- border-color: var(--bxf-accent);
4242
- border-style: solid;
4330
+ function GroupResponseModeEditor({
4331
+ value,
4332
+ permissionGranted = false,
4333
+ disabled = false,
4334
+ authorizationDisabled = false,
4335
+ onSave,
4336
+ onAuthorize
4337
+ }) {
4338
+ const current = normalizeGroupResponseMode(value);
4339
+ const [saving, setSaving] = React12.useState(false);
4340
+ const [authorizing, setAuthorizing] = React12.useState(false);
4341
+ const [error, setError] = React12.useState(null);
4342
+ const change = async (event) => {
4343
+ const next = normalizeGroupResponseMode(event.target.value);
4344
+ if (next === current || saving || disabled) return;
4345
+ setSaving(true);
4346
+ setError(null);
4347
+ try {
4348
+ await onSave?.(next);
4349
+ } catch (cause) {
4350
+ setError(cause?.message ?? "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F\u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
4351
+ } finally {
4352
+ setSaving(false);
4353
+ }
4354
+ };
4355
+ const authorize = async () => {
4356
+ if (current !== "all" || saving || authorizing || disabled || authorizationDisabled) return;
4357
+ setAuthorizing(true);
4358
+ setError(null);
4359
+ try {
4360
+ await onAuthorize?.();
4361
+ } catch (cause) {
4362
+ setError(cause?.message ?? "\u7FA4\u6D88\u606F\u6743\u9650\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
4363
+ } finally {
4364
+ setAuthorizing(false);
4365
+ }
4366
+ };
4367
+ return h2(
4368
+ "div",
4369
+ { className: "bxf-responseMode dim-responseMode" },
4370
+ h2(
4371
+ "div",
4372
+ { className: "bxf-responseModeHeader dim-responseModeHeader" },
4373
+ h2("span", null, "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F"),
4374
+ saving || authorizing ? h2(
4375
+ "span",
4376
+ { className: "bxf-responseModeStatus dim-responseModeStatus" },
4377
+ saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u6B63\u5728\u51C6\u5907\u6388\u6743\u2026"
4378
+ ) : null
4379
+ ),
4380
+ h2(
4381
+ "select",
4382
+ {
4383
+ className: "bxf-responseModeSelect dim-responseModeSelect",
4384
+ value: current,
4385
+ disabled: disabled || saving,
4386
+ "aria-label": "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F",
4387
+ onChange: (event) => {
4388
+ void change(event);
4389
+ }
4390
+ },
4391
+ h2("option", { value: "mention" }, "\u4EC5\u5728 @\u673A\u5668\u4EBA\u65F6\u54CD\u5E94\uFF08\u63A8\u8350\uFF09"),
4392
+ h2("option", { value: "all" }, "\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F")
4393
+ ),
4394
+ h2(
4395
+ "small",
4396
+ { className: "bxf-responseModeHelp dim-responseModeHelp" },
4397
+ current === "mention" ? permissionGranted ? "\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002\u7FA4\u6D88\u606F\u6743\u9650\u5DF2\u5F00\u901A\uFF0C\u518D\u6B21\u5207\u6362\u65E0\u9700\u6388\u6743\u3002" : "\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002\u9009\u62E9\u5168\u90E8\u6D88\u606F\u540E\u4F1A\u6253\u5F00\u98DE\u4E66\u5B98\u65B9\u6388\u6743\u6D41\u7A0B\u3002" : permissionGranted ? "\u5DF2\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF08im:message.group_msg\uFF09\uFF1B\u673A\u5668\u4EBA\u4F1A\u5904\u7406\u7FA4\u804A\u4E2D\u7684\u6240\u6709\u53EF\u89C1\u6D88\u606F\u3002" : "\u5C1A\u672A\u786E\u8BA4\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF0C\u8BF7\u5B8C\u6210\u98DE\u4E66\u6388\u6743\u3002"
4398
+ ),
4399
+ current === "all" ? h2(
4400
+ "div",
4401
+ { className: "bxf-responseModePermissionAction dim-responseModePermissionAction" },
4402
+ h2(Button5, {
4403
+ className: "bxf-responseModePermissionButton",
4404
+ size: "small",
4405
+ disabled: disabled || authorizationDisabled || saving || authorizing,
4406
+ "aria-busy": authorizing ? "true" : void 0,
4407
+ "aria-label": permissionGranted ? "\u91CD\u65B0\u6388\u6743\u7FA4\u6D88\u606F\u6743\u9650" : "\u6388\u6743\u7FA4\u6D88\u606F\u6743\u9650",
4408
+ onClick: () => {
4409
+ void authorize();
4410
+ }
4411
+ }, authorizing ? "\u6B63\u5728\u51C6\u5907\u2026" : permissionGranted ? "\u91CD\u65B0\u6388\u6743" : "\u53BB\u6388\u6743")
4412
+ ) : null,
4413
+ error ? h2("p", {
4414
+ className: "bxf-responseModeError dim-responseModeError",
4415
+ role: "alert"
4416
+ }, error) : null
4417
+ );
4243
4418
  }
4244
-
4245
- .bxf-qrFrame::before { inset: -3px auto auto -3px; border-width: 2px 0 0 2px; border-radius: 5px 0 0; }
4246
- .bxf-qrFrame::after { inset: auto -3px -3px auto; border-width: 0 2px 2px 0; border-radius: 0 0 5px; }
4247
- .bxf-qrFrame img { width: 100%; height: 100%; display: block; object-fit: contain; }
4248
-
4249
- .bxf-qrFallback {
4250
- width: 100%;
4251
- height: 100%;
4252
- display: grid;
4253
- place-items: center;
4254
- border-radius: 8px;
4255
- color: var(--bxf-accent);
4256
- background: #f7f9ff;
4257
- text-align: center;
4258
- padding: 20px;
4419
+ function BotCard({
4420
+ connection,
4421
+ busy,
4422
+ repairDisabled,
4423
+ provisionContent,
4424
+ provisionRef,
4425
+ actionError,
4426
+ testNotice,
4427
+ removing,
4428
+ onReconnect,
4429
+ onRepairCallback,
4430
+ onWorkspaceSave,
4431
+ onAgentPresetSave,
4432
+ onGroupResponseModeSave,
4433
+ onGroupMessagePermissionAuthorize,
4434
+ onRequestRemove,
4435
+ onConfirmRemove,
4436
+ onCancelRemove,
4437
+ cardRef,
4438
+ removeButtonRef
4439
+ }) {
4440
+ const { bot, health, state, connected } = connection;
4441
+ const repairTooltipId = React12.useId();
4442
+ const stateForDisplay = busy === "reconnect" ? "connecting" : state;
4443
+ const tone = stateForDisplay === "connected" ? "success" : stateForDisplay === "connecting" ? "warning" : "error";
4444
+ const summary = actionError?.message ?? connection.error?.message ?? (connected ? null : health.summary);
4445
+ const titleId = `bxf-bot-${connection.botId.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
4446
+ return h2(
4447
+ "article",
4448
+ {
4449
+ className: "bxf-card bxf-botCard dim-botCard",
4450
+ "aria-labelledby": titleId,
4451
+ "data-bot-id": connection.botId,
4452
+ tabIndex: -1,
4453
+ ref: cardRef
4454
+ },
4455
+ h2(
4456
+ "div",
4457
+ { className: "bxf-cardBody dim-botCardBody" },
4458
+ h2(
4459
+ "div",
4460
+ { className: "bxf-connectedTop dim-botCardTop" },
4461
+ h2(
4462
+ "div",
4463
+ { className: "bxf-botIdentity dim-botIdentity" },
4464
+ h2(
4465
+ "div",
4466
+ { className: "bxf-avatar dim-botAvatar", "aria-hidden": "true" },
4467
+ h2(FeishuLogoGlyph, { size: 34 })
4468
+ ),
4469
+ h2(
4470
+ "div",
4471
+ { className: "bxf-botName dim-botName" },
4472
+ h2("h3", { id: titleId, title: bot.name }, bot.name),
4473
+ h2("p", { title: bot.appIdMasked }, bot.appIdMasked ?? "\u5E94\u7528\u6807\u8BC6\u5DF2\u5B89\u5168\u4FDD\u5B58")
4474
+ )
4475
+ ),
4476
+ h2(BotStatusMeta, {
4477
+ className: "bxf-healthPill",
4478
+ dotClassName: "bxf-dot",
4479
+ tone,
4480
+ stateLabel: HEALTH_LABELS[stateForDisplay] ?? "\u72B6\u6001\u672A\u77E5",
4481
+ lastCheckedAt: health.lastCheckedAt,
4482
+ formatCheckedTime,
4483
+ healthState: stateForDisplay
4484
+ })
4485
+ ),
4486
+ h2(WorkspaceEditor, {
4487
+ workspace: connection.workspace,
4488
+ disabled: Boolean(busy),
4489
+ onSave: onWorkspaceSave
4490
+ }),
4491
+ h2(AgentPresetEditor, {
4492
+ agentPreset: connection.agentPreset,
4493
+ disabled: Boolean(busy),
4494
+ onSave: onAgentPresetSave
4495
+ }),
4496
+ h2(GroupResponseModeEditor, {
4497
+ value: connection.groupResponseMode,
4498
+ permissionGranted: connection.groupMessagePermissionGranted,
4499
+ disabled: Boolean(busy),
4500
+ authorizationDisabled: repairDisabled,
4501
+ onSave: onGroupResponseModeSave,
4502
+ onAuthorize: onGroupMessagePermissionAuthorize
4503
+ }),
4504
+ provisionContent ? h2("section", {
4505
+ className: "bxf-botProvision dim-botProvision",
4506
+ "aria-label": `${bot.name}\u7684\u98DE\u4E66\u6388\u6743\u6D41\u7A0B`,
4507
+ "data-provision-for": connection.botId,
4508
+ ref: provisionRef,
4509
+ tabIndex: -1
4510
+ }, provisionContent) : null,
4511
+ h2(
4512
+ "div",
4513
+ { className: "bxf-connectedFooter dim-cardFooter" },
4514
+ h2(
4515
+ "div",
4516
+ { className: "dim-cardFooterLayout" },
4517
+ h2(
4518
+ "div",
4519
+ { className: "bxf-actions bxf-botActions dim-cardActions" },
4520
+ h2(Button5, {
4521
+ className: "dim-cardAction",
4522
+ onClick: onReconnect,
4523
+ disabled: Boolean(busy),
4524
+ "aria-busy": busy === "reconnect" ? "true" : void 0,
4525
+ "aria-label": `${connected ? "\u68C0\u67E5\u8FDE\u63A5" : "\u91CD\u8BD5\u8FDE\u63A5"}${bot.name}`
4526
+ }, busy === "reconnect" ? connected ? "\u68C0\u67E5\u4E2D\u2026" : "\u6B63\u5728\u8FDE\u63A5\u2026" : connected ? "\u68C0\u67E5\u8FDE\u63A5" : "\u91CD\u8BD5\u8FDE\u63A5"),
4527
+ h2(
4528
+ "span",
4529
+ { className: "bxf-repairAction" },
4530
+ h2(Button5, {
4531
+ className: "bxf-repairButton dim-cardAction",
4532
+ onClick: onRepairCallback,
4533
+ disabled: Boolean(busy) || repairDisabled,
4534
+ "aria-busy": busy === "callback-repair" ? "true" : void 0,
4535
+ "aria-label": `\u4E3A${bot.name}\u8865\u5168\u6743\u9650\u4E0E\u56DE\u8C03`,
4536
+ "aria-describedby": repairTooltipId
4537
+ }, busy === "callback-repair" ? "\u7B49\u5F85\u626B\u7801\u2026" : "\u8865\u5168\u6743\u9650"),
4538
+ h2(
4539
+ "span",
4540
+ {
4541
+ id: repairTooltipId,
4542
+ className: "bxf-repairTooltip",
4543
+ role: "tooltip"
4544
+ },
4545
+ h2("strong", null, "\u8865\u5168\u8303\u56F4"),
4546
+ h2("span", null, "\u6700\u591A\u589E\u91CF\u6DFB\u52A0\u5361\u7247\u56DE\u8C03 card.action.trigger\u3001\u8BFB\u53D6\u6D88\u606F\u5185\u56FE\u7247\u6216\u6587\u4EF6\u6240\u9700\u7684 im:message:readonly\uFF08\u98DE\u4E66\u663E\u793A\u4E3A\u201C\u83B7\u53D6\u5355\u804A\u3001\u7FA4\u7EC4\u6D88\u606F\u201D\uFF09\uFF0C\u4EE5\u53CA\u4E0A\u4F20\u673A\u5668\u4EBA\u56FE\u7247\u6216\u6587\u4EF6\u6240\u9700\u7684 im:resource\uFF1B\u786E\u8BA4\u9875\u53EA\u663E\u793A\u5F53\u524D\u7F3A\u5C11\u9879\uFF0C\u4E0D\u4F1A\u521B\u5EFA\u65B0\u5E94\u7528\u3002")
4547
+ )
4548
+ ),
4549
+ h2(Button5, {
4550
+ className: "dim-cardAction",
4551
+ kind: "danger",
4552
+ onClick: onRequestRemove,
4553
+ disabled: Boolean(busy),
4554
+ ref: removeButtonRef,
4555
+ "aria-label": `\u4ECE DeepSeek Harness \u79FB\u9664${bot.name}`
4556
+ }, "\u79FB\u9664\u63A5\u5165")
4557
+ ),
4558
+ summary ? h2(
4559
+ "div",
4560
+ { className: "bxf-healthSummary dim-cardSummary", "data-error": actionError || connection.error ? "true" : void 0 },
4561
+ summary
4562
+ ) : null,
4563
+ connection.lastMessageError ? h2(LastMessageErrorSummary, {
4564
+ className: "bxf-healthSummary",
4565
+ error: connection.lastMessageError
4566
+ }) : null,
4567
+ testNotice ? h2("div", {
4568
+ className: "bxf-healthSummary dim-cardFeedback",
4569
+ role: "status"
4570
+ }, testNotice) : null
4571
+ )
4572
+ )
4573
+ ),
4574
+ removing ? h2(RemoveConfirmation2, {
4575
+ bot: connection,
4576
+ busy: busy === "delete",
4577
+ onConfirm: onConfirmRemove,
4578
+ onCancel: onCancelRemove
4579
+ }) : null
4580
+ );
4259
4581
  }
4260
-
4261
- .bxf-qrFallback span { display: block; color: #646a73; font-size: 12px; line-height: 18px; margin-top: 8px; }
4262
-
4263
- .bxf-expiredOverlay {
4264
- position: absolute;
4265
- inset: 10px;
4266
- display: grid;
4267
- place-items: center;
4268
- border-radius: 9px;
4269
- color: #1f2329;
4270
- background: rgba(255, 255, 255, .94);
4271
- backdrop-filter: blur(3px);
4272
- font-size: 13px;
4273
- font-weight: 600;
4274
- text-align: center;
4582
+ function BotList(props) {
4583
+ return h2(
4584
+ "section",
4585
+ { className: "bxf-listSection dim-listSection", "aria-labelledby": "bxf-bot-list-title" },
4586
+ h2(ChannelListHeading, {
4587
+ className: "bxf-listHeading",
4588
+ id: "bxf-bot-list-title",
4589
+ title: "\u5DF2\u63A5\u5165\u7684\u673A\u5668\u4EBA",
4590
+ connectionLabel: "\u957F\u8FDE\u63A5"
4591
+ }),
4592
+ h2(
4593
+ "ul",
4594
+ { className: "bxf-botList dim-botList", role: "list" },
4595
+ props.bots.map((bot) => h2(
4596
+ "li",
4597
+ { key: bot.botId },
4598
+ h2(BotCard, {
4599
+ connection: bot,
4600
+ busy: props.busyByBot[bot.botId] ?? (isTargetedAppUpdate2(props.provisioning) && props.provisioning.botId === bot.botId ? props.provisioning.operation : void 0),
4601
+ repairDisabled: Boolean(props.provisioning),
4602
+ provisionContent: isTargetedAppUpdate2(props.provisioning) && props.provisioning.botId === bot.botId ? props.provisionContent : null,
4603
+ provisionRef: props.provisionRef,
4604
+ actionError: props.errorsByBot[bot.botId],
4605
+ testNotice: props.testNoticesByBot[bot.botId],
4606
+ removing: props.removeTargetId === bot.botId,
4607
+ onReconnect: () => props.onReconnect(bot),
4608
+ onRepairCallback: () => props.onRepairCallback(bot),
4609
+ onWorkspaceSave: (workspace) => props.onWorkspaceSave(bot, workspace),
4610
+ onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(bot, agentPreset),
4611
+ onGroupResponseModeSave: (groupResponseMode) => props.onGroupResponseModeSave(bot, groupResponseMode),
4612
+ onGroupMessagePermissionAuthorize: () => props.onGroupMessagePermissionAuthorize(bot),
4613
+ onRequestRemove: () => props.onRequestRemove(bot),
4614
+ onConfirmRemove: () => props.onConfirmRemove(bot),
4615
+ onCancelRemove: props.onCancelRemove,
4616
+ cardRef: (node) => props.setCardRef(bot.botId, node),
4617
+ removeButtonRef: (node) => props.setRemoveButtonRef(bot.botId, node)
4618
+ })
4619
+ ))
4620
+ )
4621
+ );
4275
4622
  }
4276
-
4277
- .bxf-countdown {
4278
- width: 222px;
4279
- color: var(--dsw-alias-label-tertiary, #8f959e);
4280
- font-variant-numeric: tabular-nums;
4281
- font-size: 11px;
4282
- line-height: 17px;
4283
- margin-top: 11px;
4623
+ function PageError({ error, onRetry, busy }) {
4624
+ return h2(
4625
+ "div",
4626
+ { className: "bxf-card dim-surfaceCard" },
4627
+ h2(
4628
+ "div",
4629
+ { className: "bxf-error dim-inlineError", role: "alert" },
4630
+ h2(
4631
+ "div",
4632
+ null,
4633
+ h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6\u98DE\u4E66\u673A\u5668\u4EBA"),
4634
+ h2("p", null, error.message),
4635
+ error.code ? h2("span", { className: "bxf-errorCode" }, error.code) : null,
4636
+ h2(
4637
+ "div",
4638
+ { className: "bxf-actions dim-viewActions" },
4639
+ h2(
4640
+ Button5,
4641
+ { kind: "primary", onClick: onRetry, disabled: busy },
4642
+ busy ? "\u91CD\u8BD5\u4E2D\u2026" : "\u91CD\u65B0\u8BFB\u53D6"
4643
+ )
4644
+ )
4645
+ )
4646
+ )
4647
+ );
4284
4648
  }
4285
-
4286
- .bxf-countdownTop { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
4287
- .bxf-progress { height: 3px; overflow: hidden; border-radius: 99px; background: var(--dsw-alias-bg-module-platform, #f2f3f5); margin-top: 6px; }
4288
- .bxf-progress > span { display: block; width: var(--bxf-progress, 100%); height: 100%; border-radius: inherit; background: var(--bxf-accent); transition: width 1s linear; }
4289
-
4290
- .bxf-qrCopy h3 { font-size: 20px; line-height: 29px; font-weight: 650; }
4291
- .bxf-qrCopy > p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 21px; margin-top: 7px; }
4292
-
4293
- .bxf-steps { counter-reset: bxf-step; display: flex; flex-direction: column; gap: 11px; margin: 20px 0 0; padding: 0; list-style: none; }
4294
- .bxf-steps li { counter-increment: bxf-step; display: grid; grid-template-columns: 23px minmax(0, 1fr); align-items: start; gap: 9px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 19px; }
4295
- .bxf-steps li::before { content: counter(bxf-step); width: 21px; height: 21px; display: grid; place-items: center; border: 1px solid var(--dsw-alias-border-l2, #dee0e3); border-radius: 50%; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font-size: 10px; font-weight: 650; }
4296
-
4297
- .bxf-connecting { min-height: 292px; display: grid; place-items: center; text-align: center; padding: 36px 24px; }
4298
- .bxf-connectingCopy { max-width: 430px; }
4299
- .bxf-orbit { position: relative; width: 86px; height: 86px; display: grid; place-items: center; margin: 0 auto 22px; }
4300
- .bxf-orbit::before, .bxf-orbit::after { content: ""; position: absolute; border-radius: 50%; }
4301
- .bxf-orbit::before { inset: 3px; border: 1px solid color-mix(in srgb, var(--bxf-accent) 24%, transparent); animation: bxf-pulse 1.8s var(--ds-ease-in-out, ease) infinite; }
4302
- .bxf-orbit::after { inset: 0; border: 2px solid transparent; border-top-color: var(--bxf-accent); animation: bxf-rotate 1.2s linear infinite; }
4303
- .bxf-orbitCore { width: 50px; height: 50px; display: grid; place-items: center; border-radius: 16px; color: var(--bxf-accent); background: color-mix(in srgb, var(--bxf-accent) 9%, var(--dsw-alias-bg-layer-1, #fff)); }
4304
- .bxf-connecting h3 { font-size: 20px; line-height: 29px; }
4305
- .bxf-connecting p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 21px; margin-top: 7px; }
4306
- .bxf-connectingCompact { min-height: 248px; }
4307
-
4308
- .bxf-inlineError {
4309
- min-height: 190px;
4310
- display: grid;
4311
- grid-template-columns: 44px minmax(0, 1fr);
4312
- align-content: center;
4313
- gap: 15px;
4314
- padding: 28px;
4315
- }
4316
-
4317
- .bxf-inlineError h3 { font-size: 17px; line-height: 25px; margin: 0; }
4318
- .bxf-inlineError p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 21px; margin-top: 5px; overflow-wrap: anywhere; }
4319
-
4320
- .bxf-listSection { display: flex; flex-direction: column; gap: 10px; }
4321
- .bxf-listHeading { min-height: 28px; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 0 2px; }
4322
- .bxf-listHeading h3 { font-size: 14px; line-height: 22px; font-weight: 650; margin: 0; }
4323
- .bxf-botList { display: flex; flex-direction: column; gap: 12px; margin: 0; padding: 0; list-style: none; }
4324
- .bxf-botList > li { min-width: 0; }
4325
- .bxf-botCard:focus { outline: none; }
4326
- .bxf-botCard:focus-visible { outline: 2px solid var(--bxf-accent); outline-offset: 2px; }
4327
-
4328
- .bxf-connectedTop { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
4329
- .bxf-botIdentity { min-width: 0; display: flex; align-items: center; gap: 13px; }
4330
- .bxf-avatar { flex: none; width: 48px; height: 48px; display: grid; place-items: center; overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 3px rgb(31 35 41 / 7%); }
4331
- .bxf-botName { min-width: 0; }
4332
- .bxf-botName h3 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 17px; line-height: 24px; font-weight: 650; }
4333
- .bxf-botName p { overflow: hidden; color: var(--dsw-alias-label-tertiary, #8f959e); font-family: var(--ds-font-family-code, monospace); font-size: 12px; line-height: 18px; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px; }
4334
-
4335
- .bxf-healthPill { flex: none; display: inline-flex; align-items: center; gap: 7px; min-height: 28px; border-radius: 999px; padding: 4px 10px; color: var(--bxf-success); background: color-mix(in srgb, var(--bxf-success) 10%, transparent); font-size: 12px; font-weight: 600; line-height: 18px; }
4336
- .bxf-healthPill[data-health="degraded"], .bxf-healthPill[data-health="checking"], .bxf-healthPill[data-health="connecting"] { color: var(--bxf-warning); background: color-mix(in srgb, var(--bxf-warning) 10%, transparent); }
4337
- .bxf-healthPill[data-health="offline"], .bxf-healthPill[data-health="error"] { color: var(--bxf-error); background: color-mix(in srgb, var(--bxf-error) 10%, transparent); }
4338
-
4339
-
4340
- .bxf-responseMode { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) max-content; align-items: center; column-gap: 10px; row-gap: 5px; margin-top: 6px; padding: 8px 10px; border: 1px solid var(--dsw-alias-border-l1, #eef0f3); border-radius: 9px; background: var(--dsw-alias-bg-module-platform, #f7f8fa); }
4341
- .bxf-responseModeHeader { display: contents; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: normal; }
4342
- .bxf-responseModeHeader > span:first-child { grid-column: 1; grid-row: 1; white-space: nowrap; }
4343
- .bxf-responseModeStatus { grid-column: 2; grid-row: 1; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 12px; white-space: nowrap; }
4344
- .bxf-responseModeSelect { min-width: 0; width: 100%; grid-column: 1 / -1; grid-row: 2; height: 32px; padding: 0 30px 0 9px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 7px; color: var(--dsw-alias-label-primary, #1f2329); background-color: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 12px; cursor: pointer; transition: border-color .16s ease, box-shadow .16s ease, background-color .16s ease; }
4345
- .bxf-responseModeSelect:hover:not(:disabled) { border-color: color-mix(in srgb, var(--bxf-accent) 45%, var(--dsw-alias-border-l2, #dfe1e5)); }
4346
- .bxf-responseModeSelect:focus-visible { outline: none; border-color: var(--bxf-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--bxf-accent) 16%, transparent); }
4347
- .bxf-responseModeSelect:disabled { cursor: not-allowed; opacity: .55; }
4348
- .bxf-responseModeHelp { grid-column: 1 / -1; grid-row: 3; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; line-height: 1.45; }
4349
- .bxf-responseModePermissionAction { grid-column: 1 / -1; grid-row: 4; display: flex; justify-content: flex-start; margin-top: 2px; }
4350
- .bxf-responseModePermissionButton { min-height: 28px; padding: 3px 9px; color: var(--bxf-accent); border-color: color-mix(in srgb, var(--bxf-accent) 30%, var(--dsw-alias-border-l2, #dfe1e5)); background: var(--dsw-alias-bg-layer-1, #fff); }
4351
- .bxf-responseModePermissionButton:hover:not(:disabled) { background: color-mix(in srgb, var(--bxf-accent) 7%, transparent); }
4352
- .bxf-responseModeError { grid-column: 1 / -1; grid-row: 5; color: var(--bxf-error); font-size: 12px; line-height: 1.4; margin: 0; }
4353
-
4354
- .bxf-botProvision {
4355
- position: relative;
4356
- margin-top: 14px;
4357
- scroll-margin-block: 20px;
4358
- animation: bxf-revealProvision .2s var(--ds-ease-out, ease-out) both;
4359
- }
4360
- .bxf-botProvision:focus { outline: none; }
4361
- .bxf-botProvision:focus-visible {
4362
- outline: 2px solid color-mix(in srgb, var(--bxf-accent) 75%, transparent);
4363
- outline-offset: 3px;
4364
- border-radius: 12px;
4365
- }
4366
- .bxf-botProvision > .bxf-provisionCard {
4367
- border-radius: 11px;
4368
- box-shadow: none;
4369
- background: color-mix(in srgb, var(--bxf-accent) 2.5%, var(--dsw-alias-bg-layer-3, #fff));
4370
- }
4371
- .bxf-botProvision .bxf-cardBody { padding: 18px; }
4372
- .bxf-botProvision .bxf-qrLayout {
4373
- grid-template-columns: 184px minmax(0, 1fr);
4374
- align-items: start;
4375
- gap: 24px;
4376
- }
4377
- .bxf-botProvision .bxf-qrFrame { width: 176px; height: 176px; padding: 10px; border-radius: 11px; }
4378
- .bxf-botProvision .bxf-countdown { width: 176px; }
4379
- .bxf-botProvision .bxf-qrCopy h3 { font-size: 18px; line-height: 26px; }
4380
- .bxf-botProvision .bxf-steps { gap: 8px; margin-top: 14px; }
4381
- .bxf-botProvision .bxf-actions { margin-top: 16px; }
4382
- .bxf-botProvision .bxf-inlineError { min-height: 160px; padding: 22px; }
4383
-
4384
- .bxf-connectedFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
4385
- .bxf-healthSummary { min-width: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 18px; }
4386
- .bxf-healthSummary[data-error="true"] { color: var(--bxf-error); }
4387
- .bxf-botActions { position: relative; flex: none; width: 100%; flex-wrap: wrap; gap: 8px; margin-top: 0; justify-content: flex-end; }
4388
- .bxf-botActions .bxf-button { flex: none; white-space: nowrap; }
4389
- .bxf-botActions .bxf-repairButton { color: var(--bxf-accent); border-color: color-mix(in srgb, var(--bxf-accent) 35%, var(--dsw-alias-border-l2, #dee0e3)); }
4390
- .bxf-botActions .bxf-repairButton:hover:not(:disabled) { background: color-mix(in srgb, var(--bxf-accent) 7%, transparent); }
4391
- .bxf-repairAction { display: inline-flex; }
4392
- .bxf-repairTooltip {
4393
- position: absolute;
4394
- right: 0;
4395
- bottom: calc(100% + 8px);
4396
- z-index: 40;
4397
- width: min(330px, 100%);
4398
- display: grid;
4399
- gap: 3px;
4400
- padding: 9px 10px;
4401
- border: 1px solid var(--dsw-alias-border-l2, #dfe1e5);
4402
- border-radius: 8px;
4403
- color: var(--dsw-alias-label-primary, #1f2329);
4404
- background: var(--dsw-alias-bg-layer-3, #fff);
4405
- box-shadow: 0 10px 28px rgb(31 35 41 / 16%);
4406
- opacity: 0;
4407
- visibility: hidden;
4408
- transform: translateY(3px);
4409
- pointer-events: none;
4410
- transition: opacity .15s ease, transform .15s ease, visibility .15s ease;
4411
- }
4412
- .bxf-repairTooltip strong { font-size: 12px; line-height: 17px; font-weight: 650; }
4413
- .bxf-repairTooltip > span { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 17px; font-weight: 400; overflow-wrap: anywhere; }
4414
- .bxf-repairAction:hover .bxf-repairTooltip,
4415
- .bxf-repairAction:focus-within .bxf-repairTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
4416
-
4417
- .bxf-confirm {
4418
- border-top: 1px solid var(--dsw-alias-border-l2, #dee0e3);
4419
- background: color-mix(in srgb, var(--bxf-error) 4%, var(--dsw-alias-bg-module-platform, #f7f8fa));
4420
- padding: 17px 24px 20px;
4421
- }
4422
- .bxf-confirm:focus { outline: none; }
4423
- .bxf-confirm h4 { font-size: 13px; line-height: 20px; margin: 0; }
4424
- .bxf-confirm p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 19px; margin: 4px 0 0; }
4425
- .bxf-confirm .bxf-actions { margin-top: 12px; }
4426
-
4427
- .bxf-error { min-height: 252px; display: grid; grid-template-columns: 44px minmax(0, 1fr); align-content: center; gap: 15px; padding: 30px; }
4428
- .bxf-errorIcon { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 13px; color: var(--bxf-error); background: color-mix(in srgb, var(--bxf-error) 9%, transparent); }
4429
- .bxf-error h3 { font-size: 17px; line-height: 25px; }
4430
- .bxf-error p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 21px; margin-top: 5px; overflow-wrap: anywhere; }
4431
- .bxf-errorCode { display: inline-block; color: var(--dsw-alias-label-tertiary, #8f959e); font-family: var(--ds-font-family-code, monospace); font-size: 11px; margin-top: 7px; }
4432
-
4433
- .bxf-statusNotice {
4434
- display: flex;
4435
- align-items: center;
4436
- gap: 9px;
4437
- border: 1px solid color-mix(in srgb, var(--bxf-warning) 28%, var(--dsw-alias-border-l2, #dee0e3));
4438
- border-radius: 10px;
4439
- padding: 9px 11px;
4440
- color: var(--dsw-alias-label-secondary, #646a73);
4441
- background: color-mix(in srgb, var(--bxf-warning) 5%, var(--dsw-alias-bg-layer-1, #fff));
4442
- font-size: 12px;
4443
- line-height: 18px;
4444
- }
4445
- .bxf-statusNotice > svg { flex: none; color: var(--bxf-warning); }
4446
- .bxf-statusNotice > span { min-width: 0; flex: 1; overflow-wrap: anywhere; }
4447
-
4448
- .bxf-skeleton { min-height: 260px; padding: 28px; }
4449
- .bxf-skeletonLine { height: 12px; border-radius: 999px; background: linear-gradient(90deg, var(--dsw-alias-bg-module-platform, #f2f3f5), color-mix(in srgb, var(--dsw-alias-label-tertiary, #8f959e) 10%, transparent), var(--dsw-alias-bg-module-platform, #f2f3f5)); background-size: 220% 100%; animation: bxf-shimmer 1.5s linear infinite; }
4450
- .bxf-skeletonLine:nth-child(1) { width: 92px; }
4451
- .bxf-skeletonLine:nth-child(2) { width: 44%; height: 22px; margin-top: 23px; }
4452
- .bxf-skeletonLine:nth-child(3) { width: 72%; margin-top: 14px; }
4453
- .bxf-skeletonLine:nth-child(4) { width: 58%; margin-top: 9px; }
4454
- .bxf-skeletonBox { width: 138px; height: 38px; border-radius: 8px; background: var(--dsw-alias-bg-module-platform, #f2f3f5); margin-top: 28px; }
4455
-
4456
- .bxf-visuallyHidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
4457
-
4458
- @keyframes bxf-rotate { to { transform: rotate(360deg); } }
4459
- @keyframes bxf-pulse { 0%, 100% { transform: scale(.9); opacity: .45; } 50% { transform: scale(1.08); opacity: 1; } }
4460
- @keyframes bxf-shimmer { to { background-position: -220% 0; } }
4461
- @keyframes bxf-revealProvision { from { opacity: 0; transform: translateY(-5px); } }
4462
-
4463
- @container (max-width: 620px) {
4464
- .bxf-headingTools { gap: 6px; }
4465
- .bxf-headingTools .bxf-totalBadge { padding-inline: 8px; }
4466
- .bxf-headingTools .bxf-bindButton { padding-inline: 10px; }
4467
- }
4468
-
4469
- @media (max-width: 680px) {
4470
- .bxf-intro { grid-template-columns: minmax(0, 1fr); }
4471
- .bxf-markStage { display: none; }
4472
- .bxf-qrLayout { grid-template-columns: minmax(0, 1fr); justify-items: center; }
4473
- .bxf-botProvision .bxf-qrLayout { grid-template-columns: minmax(0, 1fr); }
4474
- .bxf-qrCopy { width: 100%; }
4475
- .bxf-connectedTop { align-items: flex-start; flex-direction: column; }
4476
- .bxf-inlineError { grid-template-columns: minmax(0, 1fr); padding: 20px; }
4477
- .bxf-statusNotice { align-items: flex-start; flex-wrap: wrap; }
4478
- .bxf-cardBody { padding: 20px; }
4479
- }
4480
-
4481
- @media (prefers-reduced-motion: reduce) {
4482
- .bxf-page *, .bxf-page *::before, .bxf-page *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: .01ms !important; }
4483
- }
4484
- `;
4485
- function installFeishuStyles() {
4486
- if (typeof document === "undefined") {
4487
- return () => {
4488
- };
4489
- }
4490
- const existing = document.querySelector(
4491
- `style[data-plugin-css="${FEISHU_STYLE_ID}"]`
4492
- );
4493
- if (existing) {
4494
- return () => {
4649
+ var EMPTY_TOTALS2 = Object.freeze({ configured: 0, connected: 0 });
4650
+ function mergeFeishuSnapshotState(current, snapshot, { restoreProvisioning = false, now = Date.now() } = {}) {
4651
+ if (snapshot.revision > 0 && current.revision > snapshot.revision) return current;
4652
+ let provisioning = current.provisioning;
4653
+ if (!provisioning && restoreProvisioning && snapshot.provisioning) {
4654
+ const submitted = snapshot.provisioning.submitted === true;
4655
+ provisioning = {
4656
+ phase: submitted || snapshot.state === "connecting" ? "connecting" : "qr",
4657
+ ...snapshot.provisioning,
4658
+ durationMs: Math.max(1, snapshot.provisioning.expiresAt - now),
4659
+ expired: !submitted && snapshot.provisioning.expiresAt <= now
4495
4660
  };
4496
4661
  }
4497
- const style = document.createElement("style");
4498
- style.dataset.plugin = "@xmanrui/dsh-feishu";
4499
- style.dataset.pluginCss = FEISHU_STYLE_ID;
4500
- style.textContent = CSS3;
4501
- document.head.appendChild(style);
4502
- return () => {
4503
- style.remove();
4504
- };
4505
- }
4506
-
4507
- // plugin-src/client/channels/feishu/index.js
4508
- var CALLBACK_REPAIR_OPERATION = FEISHU_REGISTRATION_OPERATIONS.CALLBACK_REPAIR;
4509
- var GROUP_MESSAGE_PERMISSION_OPERATION = FEISHU_REGISTRATION_OPERATIONS.GROUP_MESSAGE_PERMISSION;
4510
- function isCallbackRepair(value) {
4511
- return value?.operation === CALLBACK_REPAIR_OPERATION;
4512
- }
4513
- function isGroupMessagePermission(value) {
4514
- return value?.operation === GROUP_MESSAGE_PERMISSION_OPERATION;
4515
- }
4516
- function isTargetedAppUpdate2(value) {
4517
- return isCallbackRepair(value) || isGroupMessagePermission(value);
4518
- }
4519
- function SvgIcon({ children, size = 18, className, viewBox = "0 0 24 24" }) {
4520
- return h2("svg", {
4521
- width: size,
4522
- height: size,
4523
- viewBox,
4524
- fill: "none",
4525
- xmlns: "http://www.w3.org/2000/svg",
4526
- "aria-hidden": "true",
4527
- focusable: "false",
4528
- className
4529
- }, children);
4530
- }
4531
- function RobotIcon({ size = 26 }) {
4532
- return h2(
4533
- SvgIcon,
4534
- { size },
4535
- h2("rect", {
4536
- x: "5",
4537
- y: "7.5",
4538
- width: "14",
4539
- height: "11",
4540
- rx: "4",
4541
- stroke: "currentColor",
4542
- strokeWidth: "1.7"
4543
- }),
4544
- h2("path", {
4545
- d: "M12 4.5v3M8.7 12h.01M15.3 12h.01M9.2 15.3c1.67 1.08 3.93 1.08 5.6 0M3.5 11.5v3M20.5 11.5v3",
4546
- stroke: "currentColor",
4547
- strokeWidth: "1.7",
4548
- strokeLinecap: "round"
4549
- })
4550
- );
4551
- }
4552
- function AlertIcon({ size = 22 }) {
4553
- return h2(
4554
- SvgIcon,
4555
- { size },
4556
- h2("path", {
4557
- d: "M12 3.4 21 19H3L12 3.4Z",
4558
- stroke: "currentColor",
4559
- strokeWidth: "1.7",
4560
- strokeLinejoin: "round"
4561
- }),
4562
- h2("path", {
4563
- d: "M12 9v4.4M12 16.6v.01",
4564
- stroke: "currentColor",
4565
- strokeWidth: "1.9",
4566
- strokeLinecap: "round"
4567
- })
4568
- );
4569
- }
4570
- function QrIcon({ size = 58 }) {
4571
- return h2(SvgIcon, { size }, h2("path", {
4572
- d: "M4 4h6v6H4V4Zm10 0h6v6h-6V4ZM4 14h6v6H4v-6Zm10 0h2v2h-2v-2Zm4 0h2v4h-2v-4Zm-4 4h4v2h-4v-2Z",
4573
- fill: "currentColor"
4574
- }));
4575
- }
4576
- var Button5 = React12.forwardRef(function Button6({ children, kind = "secondary", size, icon, className = "", ...props }, ref) {
4577
- return h2("button", {
4578
- ...props,
4579
- ref,
4580
- type: "button",
4581
- className: `bxf-button ${className}`.trim(),
4582
- "data-kind": kind,
4583
- "data-size": size
4584
- }, icon, h2("span", null, children));
4585
- });
4586
- function BrandMark() {
4587
- return h2("div", { className: "bxf-brandMark" }, h2(RobotIcon, { size: 34 }));
4588
- }
4589
- function Heading2({ totals, onAdd, onCredential, credentialOpen, adding, busy, addButtonRef }) {
4590
- const hasBots = totals.configured > 0;
4591
- return h2(
4592
- "div",
4593
- { className: "bxf-heading" },
4594
- h2(
4595
- "div",
4596
- { className: "bxf-headingTools" },
4597
- h2(
4598
- "div",
4599
- { className: "dim-bindActions" },
4600
- h2(Button5, {
4601
- kind: "primary",
4602
- size: "small",
4603
- className: "bxf-bindButton dim-scanButton",
4604
- onClick: onAdd,
4605
- disabled: adding || busy,
4606
- ref: addButtonRef,
4607
- "aria-busy": busy ? "true" : void 0,
4608
- "aria-label": "\u626B\u7801\u63A5\u5165\u98DE\u4E66\u673A\u5668\u4EBA",
4609
- icon: h2(QrActionIcon)
4610
- }, adding ? "\u6B63\u5728\u63A5\u5165" : "\u626B\u7801\u63A5\u5165\u673A\u5668\u4EBA"),
4611
- h2(Button5, {
4612
- kind: "credential",
4613
- size: "small",
4614
- className: "dim-credentialButton",
4615
- onClick: onCredential,
4616
- disabled: adding || busy,
4617
- "aria-pressed": credentialOpen,
4618
- "aria-label": "\u4F7F\u7528 App ID \u548C App Secret \u7ED1\u5B9A\u98DE\u4E66\u673A\u5668\u4EBA",
4619
- icon: h2(CredentialActionIcon)
4620
- }, credentialOpen ? "\u6536\u8D77\u51ED\u636E" : "\u624B\u52A8\u63A5\u5165")
4621
- ),
4622
- hasBots ? h2("div", {
4623
- className: "bxf-totalBadge dim-onlineBadge",
4624
- "aria-label": `\u5DF2\u63A5\u5165 ${totals.configured} \u4E2A\u673A\u5668\u4EBA\uFF0C\u5176\u4E2D ${totals.connected} \u4E2A\u5728\u7EBF`
4625
- }, h2("span", null, `${totals.connected} / ${totals.configured} \u5728\u7EBF`)) : null
4626
- )
4627
- );
4628
- }
4629
- function LoadingView2() {
4630
- return h2(
4631
- "div",
4632
- {
4633
- className: "bxf-card dim-surfaceCard dim-loadingView",
4634
- "aria-busy": "true",
4635
- "aria-label": "\u6B63\u5728\u8BFB\u53D6\u98DE\u4E66\u673A\u5668\u4EBA\u5217\u8868"
4636
- },
4637
- h2("div", { className: "dim-spinner", "aria-hidden": "true" }),
4638
- h2("span", null, "\u6B63\u5728\u8BFB\u53D6\u98DE\u4E66\u8FDE\u63A5\u72B6\u6001\u2026")
4639
- );
4640
- }
4641
- function EmptyView2({ onStart, busy }) {
4642
- return h2(
4643
- "div",
4644
- { className: "bxf-card dim-surfaceCard" },
4645
- h2(
4646
- "div",
4647
- { className: "bxf-cardBody bxf-intro dim-surfaceBody dim-emptyView" },
4648
- h2(
4649
- "div",
4650
- { className: "bxf-introCopy dim-emptyCopy" },
4651
- h2(
4652
- "div",
4653
- { className: "bxf-stateLabel dim-stateLabel" },
4654
- h2("span", { className: "bxf-dot dim-stateDot" }),
4655
- h2("span", null, "\u5C1A\u672A\u63A5\u5165\u673A\u5668\u4EBA")
4656
- ),
4657
- h2("h3", null, "\u626B\u7801\uFF0C\u521B\u5EFA\u7B2C\u4E00\u4E2A\u98DE\u4E66\u5165\u53E3"),
4658
- h2("p", null, "\u65E0\u9700\u624B\u52A8\u586B\u5199 App ID\u3002\u4EE5\u540E\u8FD8\u53EF\u4EE5\u7EE7\u7EED\u6DFB\u52A0\u673A\u5668\u4EBA\uFF0C\u5206\u522B\u670D\u52A1\u4E0D\u540C\u56E2\u961F\u6216\u98DE\u4E66\u79DF\u6237\u3002"),
4659
- h2(
4660
- "div",
4661
- { className: "bxf-actions dim-viewActions" },
4662
- h2(Button5, {
4663
- kind: "primary",
4664
- onClick: onStart,
4665
- disabled: busy,
4666
- "aria-busy": busy ? "true" : void 0
4667
- }, busy ? "\u6B63\u5728\u751F\u6210\u4E8C\u7EF4\u7801\u2026" : "\u751F\u6210\u98DE\u4E66\u4E8C\u7EF4\u7801")
4668
- )
4669
- ),
4670
- h2("div", { className: "bxf-markStage dim-emptyBrand", "aria-hidden": "true" }, h2(BrandMark))
4671
- )
4672
- );
4673
- }
4674
- function safeVerificationHref(value) {
4675
- if (!value) return void 0;
4676
- try {
4677
- const url = new URL(value);
4678
- return url.protocol === "https:" && [
4679
- "accounts.feishu.cn",
4680
- "accounts.larksuite.com",
4681
- "open.feishu.cn",
4682
- "open.larksuite.com"
4683
- ].includes(url.hostname) && !url.port && !url.username && !url.password ? url.toString() : void 0;
4684
- } catch {
4685
- return void 0;
4686
- }
4687
- }
4688
- function safeQrSource2(value) {
4689
- if (!value) return void 0;
4690
- return /^data:image\/(?:png|webp|svg\+xml)(?:;charset=[^;,]+)?;base64,/i.test(value) ? value : void 0;
4691
- }
4692
- function QrPane({ provision, now, onRefresh, onCancel, busy }) {
4693
- const [imageFailed, setImageFailed] = React12.useState(false);
4694
- const qrSource = safeQrSource2(provision.qrCodeDataUrl);
4695
- const href = safeVerificationHref(provision.verificationUrl);
4696
- const remaining = Math.max(0, provision.expiresAt - now);
4697
- const expired = provision.expired === true || remaining === 0;
4698
- const progress = Math.min(1, remaining / Math.max(1, provision.durationMs ?? remaining));
4699
- const repairing = isCallbackRepair(provision);
4700
- const grantingGroupMessages = isGroupMessagePermission(provision);
4701
- const botName = provision.botName ?? "\u6B64\u673A\u5668\u4EBA";
4702
- React12.useEffect(() => setImageFailed(false), [qrSource]);
4703
- return h2(
4704
- "div",
4705
- { className: "bxf-card bxf-provisionCard dim-surfaceCard" },
4706
- h2(
4707
- "div",
4708
- { className: "bxf-cardBody bxf-qrLayout dim-surfaceBody dim-qrLayout" },
4709
- h2(
4710
- "div",
4711
- { className: "bxf-qrColumn dim-qrColumn" },
4712
- h2(
4713
- "div",
4714
- { className: "bxf-qrFrame dim-qrFrame" },
4715
- qrSource && !imageFailed ? h2("img", {
4716
- src: qrSource,
4717
- alt: repairing ? `\u7528\u4E8E\u4E3A${botName}\u8865\u5168\u6743\u9650\u4E0E\u56DE\u8C03\u7684\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801` : grantingGroupMessages ? `\u7528\u4E8E\u4E3A${botName}\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650\u7684\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801` : "\u7528\u4E8E\u65B0\u589E DeepSeek Harness \u98DE\u4E66\u673A\u5668\u4EBA\u7684\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801",
4718
- onError: () => setImageFailed(true)
4719
- }) : h2(
4720
- "div",
4721
- { className: "bxf-qrFallback dim-qrFallback" },
4722
- h2("div", null, h2(QrIcon), h2("span", null, "\u4E8C\u7EF4\u7801\u672A\u5C31\u7EEA\uFF0C\u8BF7\u6253\u5F00\u6388\u6743\u94FE\u63A5"))
4723
- ),
4724
- expired ? h2(
4725
- "div",
4726
- { className: "bxf-expiredOverlay dim-qrExpired", role: "status" },
4727
- h2("div", null, "\u4E8C\u7EF4\u7801\u5DF2\u5931\u6548", h2("br"), "\u8BF7\u5237\u65B0\u540E\u91CD\u65B0\u626B\u7801")
4728
- ) : null
4729
- ),
4730
- h2(
4731
- "div",
4732
- {
4733
- className: "bxf-countdown dim-countdown",
4734
- "aria-label": expired ? "\u4E8C\u7EF4\u7801\u5DF2\u5931\u6548" : `\u4E8C\u7EF4\u7801\u5269\u4F59 ${formatRemaining2(remaining)}`
4735
- },
4736
- h2(
4737
- "div",
4738
- { className: "bxf-countdownTop dim-countdownTop", "aria-hidden": "true" },
4739
- h2("span", null, expired ? "\u7B49\u5F85\u5237\u65B0" : "\u4E8C\u7EF4\u7801\u6709\u6548\u65F6\u95F4"),
4740
- h2("strong", null, formatRemaining2(remaining))
4741
- ),
4742
- h2(
4743
- "div",
4744
- { className: "bxf-progress dim-progress", "aria-hidden": "true" },
4745
- h2("span", { style: { "--bxf-progress": `${Math.round(progress * 100)}%` } })
4746
- )
4747
- )
4748
- ),
4749
- h2(
4750
- "div",
4751
- { className: "bxf-qrCopy dim-qrCopy" },
4752
- h2(
4753
- "div",
4754
- { className: "bxf-stateLabel dim-stateLabel" },
4755
- h2("span", { className: "bxf-dot dim-stateDot", "data-tone": "warning" }),
4756
- h2("span", null, repairing ? `\u6B63\u5728\u4E3A\u300C${botName}\u300D\u8865\u5168\u6743\u9650\u4E0E\u56DE\u8C03` : grantingGroupMessages ? `\u6B63\u5728\u4E3A\u300C${botName}\u300D\u5F00\u901A\u7FA4\u6D88\u606F\u6743\u9650` : "\u6B63\u5728\u6DFB\u52A0\u65B0\u673A\u5668\u4EBA")
4757
- ),
4758
- h2("h3", null, expired ? "\u5237\u65B0\u4E8C\u7EF4\u7801\u540E\u7EE7\u7EED" : repairing ? "\u4F7F\u7528\u98DE\u4E66\u626B\u7801\u8865\u5168\u6743\u9650" : grantingGroupMessages ? "\u4F7F\u7528\u98DE\u4E66\u786E\u8BA4\u7FA4\u6D88\u606F\u6743\u9650" : "\u4F7F\u7528\u98DE\u4E66\u626B\u7801\u521B\u5EFA\u673A\u5668\u4EBA"),
4759
- h2("p", null, repairing ? "\u626B\u7801\u4F1A\u66F4\u65B0\u73B0\u6709\u98DE\u4E66\u5E94\u7528\uFF0C\u6700\u591A\u589E\u91CF\u8865\u5145\u5361\u7247\u6309\u94AE\u56DE\u8C03\u3001\u8BFB\u53D6\u7528\u6237\u6D88\u606F\u5185\u56FE\u7247\u6216\u6587\u4EF6\u6240\u9700\u7684 im:message:readonly\uFF08\u98DE\u4E66\u663E\u793A\u4E3A\u201C\u83B7\u53D6\u5355\u804A\u3001\u7FA4\u7EC4\u6D88\u606F\u201D\uFF09\uFF0C\u4EE5\u53CA\u4E0A\u4F20\u673A\u5668\u4EBA\u56FE\u7247\u6216\u6587\u4EF6\u6240\u9700\u7684 im:resource\uFF1B\u4E0D\u4F1A\u521B\u5EFA\u65B0\u5E94\u7528\u3002\u786E\u8BA4\u9875\u53EA\u663E\u793A\u5F53\u524D\u7F3A\u5C11\u9879\uFF0C\u5B8C\u6210\u540E\u6B64\u673A\u5668\u4EBA\u4F1A\u77ED\u6682\u91CD\u8FDE\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u53D7\u5F71\u54CD\u3002" : grantingGroupMessages ? "\u626B\u7801\u4F1A\u66F4\u65B0\u73B0\u6709\u98DE\u4E66\u5E94\u7528\uFF0C\u53EA\u589E\u91CF\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF1B\u4E0D\u4F1A\u521B\u5EFA\u65B0\u5E94\u7528\u3002\u786E\u8BA4\u540E\u4F1A\u81EA\u52A8\u542F\u7528\u201C\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F\u201D\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u53D7\u5F71\u54CD\u3002" : "\u626B\u7801\u53EA\u4F1A\u65B0\u589E\u4E00\u4E2A\u673A\u5668\u4EBA\uFF0C\u5DF2\u63A5\u5165\u7684\u673A\u5668\u4EBA\u4F1A\u7EE7\u7EED\u6B63\u5E38\u6536\u53D1\u6D88\u606F\u3002"),
4760
- h2(
4761
- "ol",
4762
- { className: "bxf-steps dim-steps" },
4763
- h2("li", null, "\u6253\u5F00\u98DE\u4E66\u79FB\u52A8\u7AEF\uFF0C\u4F7F\u7528\u626B\u4E00\u626B\u8BFB\u53D6\u4E8C\u7EF4\u7801"),
4764
- h2("li", null, repairing ? "\u6838\u5BF9\u73B0\u6709\u5E94\u7528\u540D\u79F0\uFF0C\u5E76\u786E\u8BA4\u53EA\u65B0\u589E\u5F53\u524D\u7F3A\u5C11\u7684\u4E0A\u8FF0\u914D\u7F6E" : grantingGroupMessages ? "\u6838\u5BF9\u73B0\u6709\u5E94\u7528\uFF0C\u5E76\u786E\u8BA4\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650" : "\u6838\u5BF9\u5E94\u7528\u540D\u79F0\u4E0E\u6743\u9650\u8303\u56F4\uFF0C\u5E76\u786E\u8BA4\u521B\u5EFA"),
4765
- h2("li", null, repairing ? "\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u6743\u9650\u4E0E\u56DE\u8C03\u8865\u5168\u5B8C\u6210" : grantingGroupMessages ? "\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u6743\u9650\u751F\u6548\u5E76\u81EA\u52A8\u5207\u6362\u54CD\u5E94\u65B9\u5F0F" : "\u4FDD\u6301\u672C\u9875\u6253\u5F00\uFF0C\u7B49\u5F85\u65B0\u673A\u5668\u4EBA\u7684\u957F\u8FDE\u63A5\u5C31\u7EEA")
4766
- ),
4767
- h2(
4768
- "div",
4769
- { className: "bxf-actions dim-viewActions" },
4770
- expired ? h2(Button5, {
4771
- kind: "primary",
4772
- onClick: onRefresh,
4773
- disabled: busy
4774
- }, busy ? "\u5237\u65B0\u4E2D\u2026" : "\u5237\u65B0\u4E8C\u7EF4\u7801") : href ? h2("a", {
4775
- className: "bxf-button bxf-link",
4776
- "data-kind": "secondary",
4777
- href,
4778
- target: "_blank",
4779
- rel: "noopener noreferrer"
4780
- }, h2("span", null, "\u5728\u98DE\u4E66\u4E2D\u6253\u5F00")) : null,
4781
- !expired ? h2(Button5, { onClick: onRefresh, disabled: busy }, "\u6362\u4E00\u4E2A\u4E8C\u7EF4\u7801") : null,
4782
- h2(Button5, { onClick: onCancel, disabled: busy }, repairing ? "\u53D6\u6D88\u8865\u5168" : grantingGroupMessages ? "\u53D6\u6D88\u6388\u6743" : "\u53D6\u6D88\u6DFB\u52A0")
4783
- )
4784
- )
4785
- )
4786
- );
4787
- }
4788
- function ProvisionProgress({ phase, provision, onCancel, busy }) {
4789
- const connecting = phase === "connecting";
4790
- const repairing = isCallbackRepair(provision);
4791
- const grantingGroupMessages = isGroupMessagePermission(provision);
4792
- return h2(
4793
- "div",
4794
- {
4795
- className: "bxf-card bxf-provisionCard dim-surfaceCard dim-loadingView",
4796
- "aria-busy": "true"
4797
- },
4798
- h2("div", { className: "dim-spinner", "aria-hidden": "true" }),
4799
- h2("h3", null, connecting ? repairing ? "\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u5B8C\u6210\u6743\u9650\u4E0E\u56DE\u8C03\u914D\u7F6E" : grantingGroupMessages ? "\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u542F\u7528\u5168\u90E8\u6D88\u606F\u6A21\u5F0F" : "\u5DF2\u786E\u8BA4\uFF0C\u6B63\u5728\u8FDE\u63A5\u65B0\u673A\u5668\u4EBA" : repairing ? "\u6B63\u5728\u51C6\u5907\u6743\u9650\u8865\u5168\u4E8C\u7EF4\u7801" : grantingGroupMessages ? "\u6B63\u5728\u51C6\u5907\u6743\u9650\u6388\u6743\u4E8C\u7EF4\u7801" : "\u6B63\u5728\u51C6\u5907\u6388\u6743\u4E8C\u7EF4\u7801"),
4800
- h2("p", null, connecting ? repairing ? "\u914D\u7F6E\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u4FDD\u5B58\u6743\u9650\u3001\u9A8C\u8BC1\u5361\u7247\u56DE\u8C03\u5E76\u91CD\u8FDE\u6B64\u673A\u5668\u4EBA\uFF1B\u6B64\u9636\u6BB5\u65E0\u6CD5\u53D6\u6D88\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002" : grantingGroupMessages ? "\u6743\u9650\u914D\u7F6E\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u4FDD\u5B58\u8BBE\u7F6E\u5E76\u91CD\u8FDE\u6B64\u673A\u5668\u4EBA\uFF1B\u6B64\u9636\u6BB5\u65E0\u6CD5\u53D6\u6D88\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002" : "\u6B63\u5728\u5B89\u5168\u4FDD\u5B58\u51ED\u636E\u5E76\u68C0\u67E5\u65B0\u673A\u5668\u4EBA\u7684\u6D88\u606F\u901A\u9053\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E0D\u4F1A\u4E2D\u65AD\u3002" : repairing ? "\u6B63\u5728\u4E3A\u73B0\u6709\u98DE\u4E66\u5E94\u7528\u7533\u8BF7\u4E00\u6B21\u6027\u66F4\u65B0\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u5019\u3002" : grantingGroupMessages ? "\u6B63\u5728\u4E3A\u73B0\u6709\u98DE\u4E66\u5E94\u7528\u7533\u8BF7\u7FA4\u6D88\u606F\u6743\u9650\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u5019\u3002" : "\u6B63\u5728\u5411\u98DE\u4E66\u7533\u8BF7\u4E00\u6B21\u6027\u6388\u6743\u4E8C\u7EF4\u7801\uFF0C\u8BF7\u7A0D\u5019\u3002"),
4801
- connecting && onCancel ? h2(
4802
- "div",
4803
- { className: "bxf-actions dim-viewActions", style: { justifyContent: "center" } },
4804
- h2(Button5, { onClick: onCancel, disabled: busy }, repairing ? "\u53D6\u6D88\u8865\u5168" : grantingGroupMessages ? "\u53D6\u6D88\u6388\u6743" : "\u53D6\u6D88\u6DFB\u52A0")
4805
- ) : null
4806
- );
4807
- }
4808
- function ProvisionError2({ error, provision, onRetry, onCancel, busy }) {
4809
- const repairing = isCallbackRepair(provision);
4810
- const grantingGroupMessages = isGroupMessagePermission(provision);
4811
- return h2(
4812
- "div",
4813
- { className: "bxf-card bxf-provisionCard dim-surfaceCard" },
4814
- h2(
4815
- "div",
4816
- { className: "bxf-inlineError dim-inlineError", role: "alert" },
4817
- h2(
4818
- "div",
4819
- null,
4820
- h2("h3", null, repairing ? "\u6743\u9650\u4E0E\u56DE\u8C03\u6CA1\u6709\u8865\u5168\u5B8C\u6210" : grantingGroupMessages ? "\u7FA4\u6D88\u606F\u6743\u9650\u6CA1\u6709\u5F00\u901A\u5B8C\u6210" : "\u65B0\u673A\u5668\u4EBA\u6CA1\u6709\u6DFB\u52A0\u5B8C\u6210"),
4821
- h2("p", null, error.message),
4822
- error.code ? h2("span", { className: "bxf-errorCode" }, error.code) : null,
4823
- h2(
4824
- "div",
4825
- { className: "bxf-actions dim-viewActions" },
4826
- h2(
4827
- Button5,
4828
- { kind: "primary", onClick: onRetry, disabled: busy },
4829
- busy ? "\u91CD\u8BD5\u4E2D\u2026" : "\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801"
4830
- ),
4831
- h2(Button5, { onClick: onCancel, disabled: busy }, "\u5173\u95ED")
4832
- )
4833
- )
4834
- )
4835
- );
4836
- }
4837
- var HEALTH_LABELS = {
4838
- connected: "\u8FD0\u884C\u6B63\u5E38",
4839
- connecting: "\u6B63\u5728\u8FDE\u63A5",
4840
- offline: "\u8FDE\u63A5\u4E2D\u65AD",
4841
- error: "\u9700\u8981\u5904\u7406"
4842
- };
4843
- function formatCheckedTime(timestamp7) {
4844
- if (!timestamp7) return "\u5C1A\u672A\u68C0\u67E5";
4845
- try {
4846
- return new Intl.DateTimeFormat("zh-CN", {
4847
- hour: "2-digit",
4848
- minute: "2-digit",
4849
- second: "2-digit"
4850
- }).format(new Date(timestamp7));
4851
- } catch {
4852
- return "\u521A\u521A";
4853
- }
4854
- }
4855
- function connectionTestNotice2(value) {
4856
- if (value?.testMessage?.sent === true) {
4857
- return "\u6D4B\u8BD5\u6D88\u606F\u5DF2\u53D1\u9001\uFF0C\u8BF7\u5230\u98DE\u4E66\u4F1A\u8BDD\u4E2D\u786E\u8BA4\u3002";
4858
- }
4859
- if (value?.testMessage?.code === "test-target-unavailable") {
4860
- return "\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\u3002\u673A\u5668\u4EBA\u5C1A\u672A\u6536\u5230\u53EF\u7528\u4E8E\u6D4B\u8BD5\u7684\u79C1\u804A\u6D88\u606F\u3002";
4861
- }
4862
- return value?.testMessage ? "\u8FDE\u63A5\u68C0\u67E5\u5B8C\u6210\uFF0C\u4F46\u6D4B\u8BD5\u6D88\u606F\u53D1\u9001\u5931\u8D25\u3002" : null;
4863
- }
4864
- function RemoveConfirmation2({ bot, busy, onConfirm, onCancel }) {
4865
- const cancelRef = React12.useRef(null);
4866
- const idPart = bot.botId.replace(/[^a-zA-Z0-9_-]/g, "-");
4867
- const titleId = `bxf-remove-title-${idPart}`;
4868
- const descriptionId = `bxf-remove-description-${idPart}`;
4869
- React12.useEffect(() => cancelRef.current?.focus(), []);
4870
- return h2(
4871
- "div",
4872
- {
4873
- className: "bxf-confirm dim-confirm",
4874
- role: "alertdialog",
4875
- "aria-labelledby": titleId,
4876
- "aria-describedby": descriptionId,
4877
- onKeyDown: (event) => {
4878
- if (event.key === "Escape" && !busy) {
4879
- event.preventDefault();
4880
- onCancel();
4881
- }
4882
- }
4883
- },
4884
- h2("h4", { id: titleId }, `\u4ECE DeepSeek Harness \u79FB\u9664\u201C${bot.bot.name}\u201D\uFF1F`),
4885
- h2(
4886
- "p",
4887
- { id: descriptionId },
4888
- "\u6B64\u64CD\u4F5C\u4F1A\u505C\u6B62\u8FD9\u4E2A\u673A\u5668\u4EBA\u7684\u8FDE\u63A5\uFF0C\u5E76\u5220\u9664\u4FDD\u5B58\u5728\u672C\u673A\u7684\u63A5\u5165\u914D\u7F6E\u548C\u51ED\u636E\u3002\u98DE\u4E66\u5F00\u653E\u5E73\u53F0\u4E2D\u7684\u5E94\u7528\u4E0D\u4F1A\u88AB\u81EA\u52A8\u5220\u9664\uFF0C\u5176\u4ED6\u673A\u5668\u4EBA\u4E5F\u4E0D\u53D7\u5F71\u54CD\u3002"
4889
- ),
4890
- h2(
4891
- "div",
4892
- { className: "bxf-actions dim-viewActions" },
4893
- h2(Button5, { ref: cancelRef, onClick: onCancel, disabled: busy }, "\u4FDD\u7559\u673A\u5668\u4EBA"),
4894
- h2(
4895
- Button5,
4896
- { kind: "danger", onClick: onConfirm, disabled: busy },
4897
- busy ? "\u6B63\u5728\u79FB\u9664\u2026" : "\u786E\u8BA4\u79FB\u9664\u63A5\u5165"
4898
- )
4899
- )
4900
- );
4901
- }
4902
- function GroupResponseModeEditor({
4903
- value,
4904
- permissionGranted = false,
4905
- disabled = false,
4906
- authorizationDisabled = false,
4907
- onSave,
4908
- onAuthorize
4909
- }) {
4910
- const current = normalizeGroupResponseMode(value);
4911
- const [saving, setSaving] = React12.useState(false);
4912
- const [authorizing, setAuthorizing] = React12.useState(false);
4913
- const [error, setError] = React12.useState(null);
4914
- const change = async (event) => {
4915
- const next = normalizeGroupResponseMode(event.target.value);
4916
- if (next === current || saving || disabled) return;
4917
- setSaving(true);
4918
- setError(null);
4919
- try {
4920
- await onSave?.(next);
4921
- } catch (cause) {
4922
- setError(cause?.message ?? "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F\u4FEE\u6539\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
4923
- } finally {
4924
- setSaving(false);
4925
- }
4926
- };
4927
- const authorize = async () => {
4928
- if (current !== "all" || saving || authorizing || disabled || authorizationDisabled) return;
4929
- setAuthorizing(true);
4930
- setError(null);
4931
- try {
4932
- await onAuthorize?.();
4933
- } catch (cause) {
4934
- setError(cause?.message ?? "\u7FA4\u6D88\u606F\u6743\u9650\u6388\u6743\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002");
4935
- } finally {
4936
- setAuthorizing(false);
4937
- }
4938
- };
4939
- return h2(
4940
- "div",
4941
- { className: "bxf-responseMode dim-responseMode" },
4942
- h2(
4943
- "div",
4944
- { className: "bxf-responseModeHeader dim-responseModeHeader" },
4945
- h2("span", null, "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F"),
4946
- saving || authorizing ? h2(
4947
- "span",
4948
- { className: "bxf-responseModeStatus dim-responseModeStatus" },
4949
- saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u6B63\u5728\u51C6\u5907\u6388\u6743\u2026"
4950
- ) : null
4951
- ),
4952
- h2(
4953
- "select",
4954
- {
4955
- className: "bxf-responseModeSelect dim-responseModeSelect",
4956
- value: current,
4957
- disabled: disabled || saving,
4958
- "aria-label": "\u7FA4\u804A\u54CD\u5E94\u65B9\u5F0F",
4959
- onChange: (event) => {
4960
- void change(event);
4961
- }
4962
- },
4963
- h2("option", { value: "mention" }, "\u4EC5\u5728 @\u673A\u5668\u4EBA\u65F6\u54CD\u5E94\uFF08\u63A8\u8350\uFF09"),
4964
- h2("option", { value: "all" }, "\u54CD\u5E94\u6240\u6709\u7FA4\u6D88\u606F")
4965
- ),
4966
- h2(
4967
- "small",
4968
- { className: "bxf-responseModeHelp dim-responseModeHelp" },
4969
- current === "mention" ? permissionGranted ? "\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002\u7FA4\u6D88\u606F\u6743\u9650\u5DF2\u5F00\u901A\uFF0C\u518D\u6B21\u5207\u6362\u65E0\u9700\u6388\u6743\u3002" : "\u79C1\u804A\u59CB\u7EC8\u54CD\u5E94\uFF1B\u7FA4\u804A\u4EC5\u5904\u7406\u660E\u786E @\u5F53\u524D\u673A\u5668\u4EBA\u7684\u6D88\u606F\u3002\u9009\u62E9\u5168\u90E8\u6D88\u606F\u540E\u4F1A\u6253\u5F00\u98DE\u4E66\u5B98\u65B9\u6388\u6743\u6D41\u7A0B\u3002" : permissionGranted ? "\u5DF2\u5F00\u901A\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF08im:message.group_msg\uFF09\uFF1B\u673A\u5668\u4EBA\u4F1A\u5904\u7406\u7FA4\u804A\u4E2D\u7684\u6240\u6709\u53EF\u89C1\u6D88\u606F\u3002" : "\u5C1A\u672A\u786E\u8BA4\u201C\u83B7\u53D6\u7FA4\u7EC4\u4E2D\u6240\u6709\u6D88\u606F\u201D\u6743\u9650\uFF0C\u8BF7\u5B8C\u6210\u98DE\u4E66\u6388\u6743\u3002"
4970
- ),
4971
- current === "all" ? h2(
4972
- "div",
4973
- { className: "bxf-responseModePermissionAction dim-responseModePermissionAction" },
4974
- h2(Button5, {
4975
- className: "bxf-responseModePermissionButton",
4976
- size: "small",
4977
- disabled: disabled || authorizationDisabled || saving || authorizing,
4978
- "aria-busy": authorizing ? "true" : void 0,
4979
- "aria-label": permissionGranted ? "\u91CD\u65B0\u6388\u6743\u7FA4\u6D88\u606F\u6743\u9650" : "\u6388\u6743\u7FA4\u6D88\u606F\u6743\u9650",
4980
- onClick: () => {
4981
- void authorize();
4982
- }
4983
- }, authorizing ? "\u6B63\u5728\u51C6\u5907\u2026" : permissionGranted ? "\u91CD\u65B0\u6388\u6743" : "\u53BB\u6388\u6743")
4984
- ) : null,
4985
- error ? h2("p", {
4986
- className: "bxf-responseModeError dim-responseModeError",
4987
- role: "alert"
4988
- }, error) : null
4989
- );
4990
- }
4991
- function BotCard({
4992
- connection,
4993
- busy,
4994
- repairDisabled,
4995
- provisionContent,
4996
- provisionRef,
4997
- actionError,
4998
- testNotice,
4999
- removing,
5000
- onReconnect,
5001
- onRepairCallback,
5002
- onWorkspaceSave,
5003
- onAgentPresetSave,
5004
- onGroupResponseModeSave,
5005
- onGroupMessagePermissionAuthorize,
5006
- onRequestRemove,
5007
- onConfirmRemove,
5008
- onCancelRemove,
5009
- cardRef,
5010
- removeButtonRef
5011
- }) {
5012
- const { bot, health, state, connected } = connection;
5013
- const repairTooltipId = React12.useId();
5014
- const stateForDisplay = busy === "reconnect" ? "connecting" : state;
5015
- const tone = stateForDisplay === "connected" ? "success" : stateForDisplay === "connecting" ? "warning" : "error";
5016
- const summary = actionError?.message ?? connection.error?.message ?? (connected ? null : health.summary);
5017
- const titleId = `bxf-bot-${connection.botId.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
5018
- return h2(
5019
- "article",
5020
- {
5021
- className: "bxf-card bxf-botCard dim-botCard",
5022
- "aria-labelledby": titleId,
5023
- "data-bot-id": connection.botId,
5024
- tabIndex: -1,
5025
- ref: cardRef
5026
- },
5027
- h2(
5028
- "div",
5029
- { className: "bxf-cardBody dim-botCardBody" },
5030
- h2(
5031
- "div",
5032
- { className: "bxf-connectedTop dim-botCardTop" },
5033
- h2(
5034
- "div",
5035
- { className: "bxf-botIdentity dim-botIdentity" },
5036
- h2(
5037
- "div",
5038
- { className: "bxf-avatar dim-botAvatar", "aria-hidden": "true" },
5039
- h2(FeishuLogoGlyph, { size: 34 })
5040
- ),
5041
- h2(
5042
- "div",
5043
- { className: "bxf-botName dim-botName" },
5044
- h2("h3", { id: titleId, title: bot.name }, bot.name),
5045
- h2("p", { title: bot.appIdMasked }, bot.appIdMasked ?? "\u5E94\u7528\u6807\u8BC6\u5DF2\u5B89\u5168\u4FDD\u5B58")
5046
- )
5047
- ),
5048
- h2(BotStatusMeta, {
5049
- className: "bxf-healthPill",
5050
- dotClassName: "bxf-dot",
5051
- tone,
5052
- stateLabel: HEALTH_LABELS[stateForDisplay] ?? "\u72B6\u6001\u672A\u77E5",
5053
- lastCheckedAt: health.lastCheckedAt,
5054
- formatCheckedTime,
5055
- healthState: stateForDisplay
5056
- })
5057
- ),
5058
- h2(WorkspaceEditor, {
5059
- workspace: connection.workspace,
5060
- disabled: Boolean(busy),
5061
- onSave: onWorkspaceSave
5062
- }),
5063
- h2(AgentPresetEditor, {
5064
- agentPreset: connection.agentPreset,
5065
- disabled: Boolean(busy),
5066
- onSave: onAgentPresetSave
5067
- }),
5068
- h2(GroupResponseModeEditor, {
5069
- value: connection.groupResponseMode,
5070
- permissionGranted: connection.groupMessagePermissionGranted,
5071
- disabled: Boolean(busy),
5072
- authorizationDisabled: repairDisabled,
5073
- onSave: onGroupResponseModeSave,
5074
- onAuthorize: onGroupMessagePermissionAuthorize
5075
- }),
5076
- provisionContent ? h2("section", {
5077
- className: "bxf-botProvision dim-botProvision",
5078
- "aria-label": `${bot.name}\u7684\u98DE\u4E66\u6388\u6743\u6D41\u7A0B`,
5079
- "data-provision-for": connection.botId,
5080
- ref: provisionRef,
5081
- tabIndex: -1
5082
- }, provisionContent) : null,
5083
- h2(
5084
- "div",
5085
- { className: "bxf-connectedFooter dim-cardFooter" },
5086
- h2(
5087
- "div",
5088
- { className: "dim-cardFooterLayout" },
5089
- h2(
5090
- "div",
5091
- { className: "bxf-actions bxf-botActions dim-cardActions" },
5092
- h2(Button5, {
5093
- className: "dim-cardAction",
5094
- onClick: onReconnect,
5095
- disabled: Boolean(busy),
5096
- "aria-busy": busy === "reconnect" ? "true" : void 0,
5097
- "aria-label": `${connected ? "\u68C0\u67E5\u8FDE\u63A5" : "\u91CD\u8BD5\u8FDE\u63A5"}${bot.name}`
5098
- }, busy === "reconnect" ? connected ? "\u68C0\u67E5\u4E2D\u2026" : "\u6B63\u5728\u8FDE\u63A5\u2026" : connected ? "\u68C0\u67E5\u8FDE\u63A5" : "\u91CD\u8BD5\u8FDE\u63A5"),
5099
- h2(
5100
- "span",
5101
- { className: "bxf-repairAction" },
5102
- h2(Button5, {
5103
- className: "bxf-repairButton dim-cardAction",
5104
- onClick: onRepairCallback,
5105
- disabled: Boolean(busy) || repairDisabled,
5106
- "aria-busy": busy === "callback-repair" ? "true" : void 0,
5107
- "aria-label": `\u4E3A${bot.name}\u8865\u5168\u6743\u9650\u4E0E\u56DE\u8C03`,
5108
- "aria-describedby": repairTooltipId
5109
- }, busy === "callback-repair" ? "\u7B49\u5F85\u626B\u7801\u2026" : "\u8865\u5168\u6743\u9650"),
5110
- h2(
5111
- "span",
5112
- {
5113
- id: repairTooltipId,
5114
- className: "bxf-repairTooltip",
5115
- role: "tooltip"
5116
- },
5117
- h2("strong", null, "\u8865\u5168\u8303\u56F4"),
5118
- h2("span", null, "\u6700\u591A\u589E\u91CF\u6DFB\u52A0\u5361\u7247\u56DE\u8C03 card.action.trigger\u3001\u8BFB\u53D6\u6D88\u606F\u5185\u56FE\u7247\u6216\u6587\u4EF6\u6240\u9700\u7684 im:message:readonly\uFF08\u98DE\u4E66\u663E\u793A\u4E3A\u201C\u83B7\u53D6\u5355\u804A\u3001\u7FA4\u7EC4\u6D88\u606F\u201D\uFF09\uFF0C\u4EE5\u53CA\u4E0A\u4F20\u673A\u5668\u4EBA\u56FE\u7247\u6216\u6587\u4EF6\u6240\u9700\u7684 im:resource\uFF1B\u786E\u8BA4\u9875\u53EA\u663E\u793A\u5F53\u524D\u7F3A\u5C11\u9879\uFF0C\u4E0D\u4F1A\u521B\u5EFA\u65B0\u5E94\u7528\u3002")
5119
- )
5120
- ),
5121
- h2(Button5, {
5122
- className: "dim-cardAction",
5123
- kind: "danger",
5124
- onClick: onRequestRemove,
5125
- disabled: Boolean(busy),
5126
- ref: removeButtonRef,
5127
- "aria-label": `\u4ECE DeepSeek Harness \u79FB\u9664${bot.name}`
5128
- }, "\u79FB\u9664\u63A5\u5165")
5129
- ),
5130
- summary ? h2(
5131
- "div",
5132
- { className: "bxf-healthSummary dim-cardSummary", "data-error": actionError || connection.error ? "true" : void 0 },
5133
- summary
5134
- ) : null,
5135
- connection.lastMessageError ? h2(LastMessageErrorSummary, {
5136
- className: "bxf-healthSummary",
5137
- error: connection.lastMessageError
5138
- }) : null,
5139
- testNotice ? h2("div", {
5140
- className: "bxf-healthSummary dim-cardFeedback",
5141
- role: "status"
5142
- }, testNotice) : null
5143
- )
5144
- )
5145
- ),
5146
- removing ? h2(RemoveConfirmation2, {
5147
- bot: connection,
5148
- busy: busy === "delete",
5149
- onConfirm: onConfirmRemove,
5150
- onCancel: onCancelRemove
5151
- }) : null
5152
- );
5153
- }
5154
- function BotList(props) {
5155
- return h2(
5156
- "section",
5157
- { className: "bxf-listSection dim-listSection", "aria-labelledby": "bxf-bot-list-title" },
5158
- h2(ChannelListHeading, {
5159
- className: "bxf-listHeading",
5160
- id: "bxf-bot-list-title",
5161
- title: "\u5DF2\u63A5\u5165\u7684\u673A\u5668\u4EBA",
5162
- connectionLabel: "\u957F\u8FDE\u63A5"
5163
- }),
5164
- h2(
5165
- "ul",
5166
- { className: "bxf-botList dim-botList", role: "list" },
5167
- props.bots.map((bot) => h2(
5168
- "li",
5169
- { key: bot.botId },
5170
- h2(BotCard, {
5171
- connection: bot,
5172
- busy: props.busyByBot[bot.botId] ?? (isTargetedAppUpdate2(props.provisioning) && props.provisioning.botId === bot.botId ? props.provisioning.operation : void 0),
5173
- repairDisabled: Boolean(props.provisioning),
5174
- provisionContent: isTargetedAppUpdate2(props.provisioning) && props.provisioning.botId === bot.botId ? props.provisionContent : null,
5175
- provisionRef: props.provisionRef,
5176
- actionError: props.errorsByBot[bot.botId],
5177
- testNotice: props.testNoticesByBot[bot.botId],
5178
- removing: props.removeTargetId === bot.botId,
5179
- onReconnect: () => props.onReconnect(bot),
5180
- onRepairCallback: () => props.onRepairCallback(bot),
5181
- onWorkspaceSave: (workspace) => props.onWorkspaceSave(bot, workspace),
5182
- onAgentPresetSave: (agentPreset) => props.onAgentPresetSave(bot, agentPreset),
5183
- onGroupResponseModeSave: (groupResponseMode) => props.onGroupResponseModeSave(bot, groupResponseMode),
5184
- onGroupMessagePermissionAuthorize: () => props.onGroupMessagePermissionAuthorize(bot),
5185
- onRequestRemove: () => props.onRequestRemove(bot),
5186
- onConfirmRemove: () => props.onConfirmRemove(bot),
5187
- onCancelRemove: props.onCancelRemove,
5188
- cardRef: (node) => props.setCardRef(bot.botId, node),
5189
- removeButtonRef: (node) => props.setRemoveButtonRef(bot.botId, node)
5190
- })
5191
- ))
5192
- )
5193
- );
5194
- }
5195
- function PageError({ error, onRetry, busy }) {
5196
- return h2(
5197
- "div",
5198
- { className: "bxf-card dim-surfaceCard" },
5199
- h2(
5200
- "div",
5201
- { className: "bxf-error dim-inlineError", role: "alert" },
5202
- h2(
5203
- "div",
5204
- null,
5205
- h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6\u98DE\u4E66\u673A\u5668\u4EBA"),
5206
- h2("p", null, error.message),
5207
- error.code ? h2("span", { className: "bxf-errorCode" }, error.code) : null,
5208
- h2(
5209
- "div",
5210
- { className: "bxf-actions dim-viewActions" },
5211
- h2(
5212
- Button5,
5213
- { kind: "primary", onClick: onRetry, disabled: busy },
5214
- busy ? "\u91CD\u8BD5\u4E2D\u2026" : "\u91CD\u65B0\u8BFB\u53D6"
5215
- )
5216
- )
5217
- )
5218
- )
5219
- );
5220
- }
5221
- var EMPTY_TOTALS2 = Object.freeze({ configured: 0, connected: 0 });
5222
- function mergeFeishuSnapshotState(current, snapshot, { restoreProvisioning = false, now = Date.now() } = {}) {
5223
- if (snapshot.revision > 0 && current.revision > snapshot.revision) return current;
5224
- let provisioning = current.provisioning;
5225
- if (!provisioning && restoreProvisioning && snapshot.provisioning) {
5226
- const submitted = snapshot.provisioning.submitted === true;
5227
- provisioning = {
5228
- phase: submitted || snapshot.state === "connecting" ? "connecting" : "qr",
5229
- ...snapshot.provisioning,
5230
- durationMs: Math.max(1, snapshot.provisioning.expiresAt - now),
5231
- expired: !submitted && snapshot.provisioning.expiresAt <= now
5232
- };
5233
- }
5234
- return {
5235
- ...current,
5236
- phase: "ready",
5237
- revision: snapshot.revision,
5238
- bots: snapshot.bots,
5239
- totals: snapshot.totals,
5240
- provisioning,
5241
- pageError: null,
5242
- statusError: null,
5243
- agentPresetCatalog: snapshot.agentPresetCatalog ?? current.agentPresetCatalog
4662
+ return {
4663
+ ...current,
4664
+ phase: "ready",
4665
+ revision: snapshot.revision,
4666
+ bots: snapshot.bots,
4667
+ totals: snapshot.totals,
4668
+ provisioning,
4669
+ pageError: null,
4670
+ statusError: null,
4671
+ agentPresetCatalog: snapshot.agentPresetCatalog ?? current.agentPresetCatalog
5244
4672
  };
5245
4673
  }
5246
4674
  function FeishuSettingsTab({ rpcCall }) {
@@ -5923,6 +5351,578 @@ function FeishuSettingsTab({ rpcCall }) {
5923
5351
  ));
5924
5352
  }
5925
5353
 
5354
+ // plugin-src/client/channels/feishu/styles.js
5355
+ var FEISHU_STYLE_ID = "xmanrui-dsh-im-feishu-settings";
5356
+ var CSS3 = String.raw`
5357
+ .bxf-page {
5358
+ --bxf-accent: var(--dsw-alias-state-business-primary, #3370ff);
5359
+ --bxf-success: var(--dsw-alias-state-success-primary, #20a162);
5360
+ --bxf-warning: var(--dsw-alias-state-warn-primary, #d97706);
5361
+ --bxf-error: var(--dsw-alias-state-error-primary, #d54941);
5362
+ box-sizing: border-box;
5363
+ width: 100%;
5364
+ max-width: 860px;
5365
+ color: var(--dsw-alias-label-primary, #1f2329);
5366
+ display: flex;
5367
+ flex-direction: column;
5368
+ container-type: inline-size;
5369
+ gap: 18px;
5370
+ padding: 2px 0 24px;
5371
+ }
5372
+
5373
+ .bxf-page *, .bxf-page *::before, .bxf-page *::after { box-sizing: border-box; }
5374
+
5375
+ .bxf-heading {
5376
+ display: flex;
5377
+ align-items: flex-start;
5378
+ justify-content: space-between;
5379
+ gap: 20px;
5380
+ }
5381
+
5382
+ .bxf-headingCopy { min-width: 0; }
5383
+ .bxf-heading h2, .bxf-heading p, .bxf-card h3, .bxf-card p { margin: 0; }
5384
+
5385
+ .bxf-eyebrow {
5386
+ color: var(--dsw-alias-label-tertiary, #8f959e);
5387
+ font-size: 12px;
5388
+ font-weight: 600;
5389
+ line-height: 18px;
5390
+ letter-spacing: .08em;
5391
+ text-transform: uppercase;
5392
+ margin-bottom: 3px;
5393
+ }
5394
+
5395
+ .bxf-heading h2 {
5396
+ font-size: 20px;
5397
+ line-height: 28px;
5398
+ font-weight: 650;
5399
+ letter-spacing: -.015em;
5400
+ }
5401
+
5402
+ .bxf-heading p {
5403
+ max-width: 540px;
5404
+ color: var(--dsw-alias-label-secondary, #646a73);
5405
+ font-size: 13px;
5406
+ line-height: 20px;
5407
+ margin-top: 5px;
5408
+ white-space: nowrap;
5409
+ }
5410
+
5411
+ .bxf-headingTools {
5412
+ width: 100%;
5413
+ flex: none;
5414
+ display: flex;
5415
+ align-items: center;
5416
+ justify-content: space-between;
5417
+ flex-wrap: nowrap;
5418
+ gap: 8px;
5419
+ }
5420
+
5421
+ .bxf-totalBadge {
5422
+ min-height: 28px;
5423
+ display: inline-flex;
5424
+ align-items: baseline;
5425
+ gap: 3px;
5426
+ border-radius: 999px;
5427
+ padding: 4px 10px;
5428
+ color: var(--dsw-alias-label-secondary, #646a73);
5429
+ background: var(--dsw-alias-bg-module-platform, #f2f3f5);
5430
+ font-size: 11px;
5431
+ line-height: 16px;
5432
+ white-space: nowrap;
5433
+ }
5434
+
5435
+ .bxf-totalBadge strong { color: var(--bxf-success); font-size: 13px; }
5436
+
5437
+ .bxf-card {
5438
+ position: relative;
5439
+ overflow: hidden;
5440
+ border: 1px solid var(--dsw-alias-border-l2, #dee0e3);
5441
+ border-radius: 14px;
5442
+ background: var(--dsw-alias-bg-layer-3, #fff);
5443
+ box-shadow: var(--dsw-shadow-lv1, 0 3px 12px rgba(31, 35, 41, .05));
5444
+ }
5445
+
5446
+ .bxf-card::before {
5447
+ content: "";
5448
+ pointer-events: none;
5449
+ position: absolute;
5450
+ inset: 0 0 auto;
5451
+ height: 88px;
5452
+ background:
5453
+ radial-gradient(circle at 86% -35%, color-mix(in srgb, var(--bxf-accent) 18%, transparent), transparent 68%);
5454
+ opacity: .85;
5455
+ }
5456
+
5457
+ .bxf-cardBody { position: relative; padding: 24px; }
5458
+
5459
+ .bxf-intro {
5460
+ min-height: 250px;
5461
+ display: grid;
5462
+ grid-template-columns: minmax(0, 1fr) 172px;
5463
+ gap: 32px;
5464
+ align-items: center;
5465
+ }
5466
+
5467
+ .bxf-introCopy { max-width: 500px; }
5468
+
5469
+ .bxf-stateLabel {
5470
+ display: inline-flex;
5471
+ align-items: center;
5472
+ gap: 7px;
5473
+ color: var(--dsw-alias-label-secondary, #646a73);
5474
+ font-size: 12px;
5475
+ font-weight: 600;
5476
+ line-height: 18px;
5477
+ margin-bottom: 13px;
5478
+ }
5479
+
5480
+ .bxf-dot {
5481
+ width: 7px;
5482
+ height: 7px;
5483
+ border-radius: 50%;
5484
+ background: var(--dsw-alias-label-tertiary, #8f959e);
5485
+ box-shadow: 0 0 0 4px color-mix(in srgb, var(--dsw-alias-label-tertiary, #8f959e) 12%, transparent);
5486
+ }
5487
+
5488
+ .bxf-dot[data-tone="success"] {
5489
+ background: var(--bxf-success);
5490
+ box-shadow: 0 0 0 4px color-mix(in srgb, var(--bxf-success) 13%, transparent);
5491
+ }
5492
+
5493
+ .bxf-dot[data-tone="warning"] {
5494
+ background: var(--bxf-warning);
5495
+ box-shadow: 0 0 0 4px color-mix(in srgb, var(--bxf-warning) 13%, transparent);
5496
+ }
5497
+
5498
+ .bxf-dot[data-tone="error"] {
5499
+ background: var(--bxf-error);
5500
+ box-shadow: 0 0 0 4px color-mix(in srgb, var(--bxf-error) 13%, transparent);
5501
+ }
5502
+
5503
+ .bxf-intro h3 {
5504
+ font-size: 24px;
5505
+ line-height: 34px;
5506
+ font-weight: 650;
5507
+ letter-spacing: -.02em;
5508
+ }
5509
+
5510
+ .bxf-introCopy > p {
5511
+ max-width: 490px;
5512
+ color: var(--dsw-alias-label-secondary, #646a73);
5513
+ font-size: 14px;
5514
+ line-height: 23px;
5515
+ margin-top: 8px;
5516
+ }
5517
+
5518
+ .bxf-note {
5519
+ display: flex;
5520
+ gap: 8px;
5521
+ align-items: flex-start;
5522
+ color: var(--dsw-alias-label-tertiary, #8f959e);
5523
+ font-size: 12px;
5524
+ line-height: 18px;
5525
+ margin-top: 16px;
5526
+ }
5527
+
5528
+ .bxf-note svg { flex: none; margin-top: 1px; }
5529
+
5530
+ .bxf-actions {
5531
+ display: flex;
5532
+ align-items: center;
5533
+ flex-wrap: wrap;
5534
+ gap: 10px;
5535
+ margin-top: 22px;
5536
+ }
5537
+
5538
+ .bxf-button {
5539
+ appearance: none;
5540
+ min-height: 36px;
5541
+ display: inline-flex;
5542
+ align-items: center;
5543
+ justify-content: center;
5544
+ gap: 7px;
5545
+ border: 1px solid var(--dsw-alias-border-l2, #dee0e3);
5546
+ border-radius: 8px;
5547
+ padding: 7px 13px;
5548
+ color: var(--dsw-alias-label-primary, #1f2329);
5549
+ background: var(--dsw-alias-bg-layer-1, #fff);
5550
+ font: inherit;
5551
+ font-size: 13px;
5552
+ font-weight: 550;
5553
+ line-height: 20px;
5554
+ text-decoration: none;
5555
+ cursor: pointer;
5556
+ transition: background .15s var(--ds-ease-in-out, ease), border-color .15s var(--ds-ease-in-out, ease), transform .15s var(--ds-ease-in-out, ease);
5557
+ }
5558
+
5559
+ .bxf-button:hover:not(:disabled) {
5560
+ background: var(--dsw-alias-interactive-bg-hover, #f2f3f5);
5561
+ border-color: var(--dsw-alias-border-l1, #c9cdd4);
5562
+ }
5563
+
5564
+ .bxf-button:active:not(:disabled) { transform: translateY(1px); }
5565
+
5566
+ .bxf-button:focus-visible, .bxf-link:focus-visible {
5567
+ outline: 2px solid var(--bxf-accent);
5568
+ outline-offset: 2px;
5569
+ }
5570
+
5571
+ .bxf-button:disabled { cursor: not-allowed; opacity: .55; }
5572
+
5573
+ .bxf-button[data-kind="primary"] {
5574
+ border-color: var(--bxf-accent);
5575
+ color: #fff;
5576
+ background: var(--bxf-accent);
5577
+ box-shadow: 0 4px 12px color-mix(in srgb, var(--bxf-accent) 24%, transparent);
5578
+ }
5579
+
5580
+ .bxf-button[data-kind="primary"]:hover:not(:disabled) {
5581
+ border-color: color-mix(in srgb, var(--bxf-accent) 86%, #000);
5582
+ background: color-mix(in srgb, var(--bxf-accent) 90%, #000);
5583
+ }
5584
+
5585
+ .bxf-button[data-kind="danger"] { color: var(--bxf-error); }
5586
+ .bxf-button[data-size="small"] { min-height: 32px; padding: 5px 10px; font-size: 12px; }
5587
+ .bxf-bindButton { flex: none; white-space: nowrap; }
5588
+
5589
+ .bxf-provisionCard {
5590
+ border-color: color-mix(in srgb, var(--bxf-accent) 32%, var(--dsw-alias-border-l2, #dee0e3));
5591
+ }
5592
+
5593
+ .bxf-markStage {
5594
+ position: relative;
5595
+ width: 156px;
5596
+ height: 156px;
5597
+ display: grid;
5598
+ place-items: center;
5599
+ justify-self: end;
5600
+ }
5601
+
5602
+ .bxf-markStage::before, .bxf-markStage::after {
5603
+ content: "";
5604
+ position: absolute;
5605
+ border-radius: 50%;
5606
+ }
5607
+
5608
+ .bxf-markStage::before {
5609
+ inset: 12px;
5610
+ border: 1px solid color-mix(in srgb, var(--bxf-accent) 18%, var(--dsw-alias-border-l2, #dee0e3));
5611
+ background: color-mix(in srgb, var(--bxf-accent) 4%, var(--dsw-alias-bg-layer-1, #fff));
5612
+ }
5613
+
5614
+ .bxf-markStage::after {
5615
+ inset: 0;
5616
+ border: 1px dashed color-mix(in srgb, var(--bxf-accent) 16%, transparent);
5617
+ animation: bxf-rotate 18s linear infinite;
5618
+ }
5619
+
5620
+ .bxf-brandMark {
5621
+ position: relative;
5622
+ z-index: 1;
5623
+ width: 68px;
5624
+ height: 68px;
5625
+ display: grid;
5626
+ place-items: center;
5627
+ border-radius: 20px;
5628
+ color: #fff;
5629
+ background: var(--bxf-accent);
5630
+ box-shadow: 0 12px 28px color-mix(in srgb, var(--bxf-accent) 28%, transparent);
5631
+ }
5632
+
5633
+ .bxf-qrLayout {
5634
+ display: grid;
5635
+ grid-template-columns: 236px minmax(0, 1fr);
5636
+ align-items: center;
5637
+ gap: 32px;
5638
+ }
5639
+
5640
+ .bxf-qrColumn { min-width: 0; }
5641
+
5642
+ .bxf-qrFrame {
5643
+ position: relative;
5644
+ width: 222px;
5645
+ height: 222px;
5646
+ display: grid;
5647
+ place-items: center;
5648
+ border: 1px solid var(--dsw-alias-border-l2, #dee0e3);
5649
+ border-radius: 14px;
5650
+ padding: 13px;
5651
+ background: #fff;
5652
+ box-shadow: 0 8px 24px rgba(31, 35, 41, .07);
5653
+ }
5654
+
5655
+ .bxf-qrFrame::before, .bxf-qrFrame::after {
5656
+ content: "";
5657
+ position: absolute;
5658
+ width: 24px;
5659
+ height: 24px;
5660
+ border-color: var(--bxf-accent);
5661
+ border-style: solid;
5662
+ }
5663
+
5664
+ .bxf-qrFrame::before { inset: -3px auto auto -3px; border-width: 2px 0 0 2px; border-radius: 5px 0 0; }
5665
+ .bxf-qrFrame::after { inset: auto -3px -3px auto; border-width: 0 2px 2px 0; border-radius: 0 0 5px; }
5666
+ .bxf-qrFrame img { width: 100%; height: 100%; display: block; object-fit: contain; }
5667
+
5668
+ .bxf-qrFallback {
5669
+ width: 100%;
5670
+ height: 100%;
5671
+ display: grid;
5672
+ place-items: center;
5673
+ border-radius: 8px;
5674
+ color: var(--bxf-accent);
5675
+ background: #f7f9ff;
5676
+ text-align: center;
5677
+ padding: 20px;
5678
+ }
5679
+
5680
+ .bxf-qrFallback span { display: block; color: #646a73; font-size: 12px; line-height: 18px; margin-top: 8px; }
5681
+
5682
+ .bxf-expiredOverlay {
5683
+ position: absolute;
5684
+ inset: 10px;
5685
+ display: grid;
5686
+ place-items: center;
5687
+ border-radius: 9px;
5688
+ color: #1f2329;
5689
+ background: rgba(255, 255, 255, .94);
5690
+ backdrop-filter: blur(3px);
5691
+ font-size: 13px;
5692
+ font-weight: 600;
5693
+ text-align: center;
5694
+ }
5695
+
5696
+ .bxf-countdown {
5697
+ width: 222px;
5698
+ color: var(--dsw-alias-label-tertiary, #8f959e);
5699
+ font-variant-numeric: tabular-nums;
5700
+ font-size: 11px;
5701
+ line-height: 17px;
5702
+ margin-top: 11px;
5703
+ }
5704
+
5705
+ .bxf-countdownTop { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
5706
+ .bxf-progress { height: 3px; overflow: hidden; border-radius: 99px; background: var(--dsw-alias-bg-module-platform, #f2f3f5); margin-top: 6px; }
5707
+ .bxf-progress > span { display: block; width: var(--bxf-progress, 100%); height: 100%; border-radius: inherit; background: var(--bxf-accent); transition: width 1s linear; }
5708
+
5709
+ .bxf-qrCopy h3 { font-size: 20px; line-height: 29px; font-weight: 650; }
5710
+ .bxf-qrCopy > p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 21px; margin-top: 7px; }
5711
+
5712
+ .bxf-steps { counter-reset: bxf-step; display: flex; flex-direction: column; gap: 11px; margin: 20px 0 0; padding: 0; list-style: none; }
5713
+ .bxf-steps li { counter-increment: bxf-step; display: grid; grid-template-columns: 23px minmax(0, 1fr); align-items: start; gap: 9px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 19px; }
5714
+ .bxf-steps li::before { content: counter(bxf-step); width: 21px; height: 21px; display: grid; place-items: center; border: 1px solid var(--dsw-alias-border-l2, #dee0e3); border-radius: 50%; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font-size: 10px; font-weight: 650; }
5715
+
5716
+ .bxf-connecting { min-height: 292px; display: grid; place-items: center; text-align: center; padding: 36px 24px; }
5717
+ .bxf-connectingCopy { max-width: 430px; }
5718
+ .bxf-orbit { position: relative; width: 86px; height: 86px; display: grid; place-items: center; margin: 0 auto 22px; }
5719
+ .bxf-orbit::before, .bxf-orbit::after { content: ""; position: absolute; border-radius: 50%; }
5720
+ .bxf-orbit::before { inset: 3px; border: 1px solid color-mix(in srgb, var(--bxf-accent) 24%, transparent); animation: bxf-pulse 1.8s var(--ds-ease-in-out, ease) infinite; }
5721
+ .bxf-orbit::after { inset: 0; border: 2px solid transparent; border-top-color: var(--bxf-accent); animation: bxf-rotate 1.2s linear infinite; }
5722
+ .bxf-orbitCore { width: 50px; height: 50px; display: grid; place-items: center; border-radius: 16px; color: var(--bxf-accent); background: color-mix(in srgb, var(--bxf-accent) 9%, var(--dsw-alias-bg-layer-1, #fff)); }
5723
+ .bxf-connecting h3 { font-size: 20px; line-height: 29px; }
5724
+ .bxf-connecting p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 21px; margin-top: 7px; }
5725
+ .bxf-connectingCompact { min-height: 248px; }
5726
+
5727
+ .bxf-inlineError {
5728
+ min-height: 190px;
5729
+ display: grid;
5730
+ grid-template-columns: 44px minmax(0, 1fr);
5731
+ align-content: center;
5732
+ gap: 15px;
5733
+ padding: 28px;
5734
+ }
5735
+
5736
+ .bxf-inlineError h3 { font-size: 17px; line-height: 25px; margin: 0; }
5737
+ .bxf-inlineError p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 21px; margin-top: 5px; overflow-wrap: anywhere; }
5738
+
5739
+ .bxf-listSection { display: flex; flex-direction: column; gap: 10px; }
5740
+ .bxf-listHeading { min-height: 28px; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 0 2px; }
5741
+ .bxf-listHeading h3 { font-size: 14px; line-height: 22px; font-weight: 650; margin: 0; }
5742
+ .bxf-botList { display: flex; flex-direction: column; gap: 12px; margin: 0; padding: 0; list-style: none; }
5743
+ .bxf-botList > li { min-width: 0; }
5744
+ .bxf-botCard:focus { outline: none; }
5745
+ .bxf-botCard:focus-visible { outline: 2px solid var(--bxf-accent); outline-offset: 2px; }
5746
+
5747
+ .bxf-connectedTop { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
5748
+ .bxf-botIdentity { min-width: 0; display: flex; align-items: center; gap: 13px; }
5749
+ .bxf-avatar { flex: none; width: 48px; height: 48px; display: grid; place-items: center; overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 3px rgb(31 35 41 / 7%); }
5750
+ .bxf-botName { min-width: 0; }
5751
+ .bxf-botName h3 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 17px; line-height: 24px; font-weight: 650; }
5752
+ .bxf-botName p { overflow: hidden; color: var(--dsw-alias-label-tertiary, #8f959e); font-family: var(--ds-font-family-code, monospace); font-size: 12px; line-height: 18px; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px; }
5753
+
5754
+ .bxf-healthPill { flex: none; display: inline-flex; align-items: center; gap: 7px; min-height: 28px; border-radius: 999px; padding: 4px 10px; color: var(--bxf-success); background: color-mix(in srgb, var(--bxf-success) 10%, transparent); font-size: 12px; font-weight: 600; line-height: 18px; }
5755
+ .bxf-healthPill[data-health="degraded"], .bxf-healthPill[data-health="checking"], .bxf-healthPill[data-health="connecting"] { color: var(--bxf-warning); background: color-mix(in srgb, var(--bxf-warning) 10%, transparent); }
5756
+ .bxf-healthPill[data-health="offline"], .bxf-healthPill[data-health="error"] { color: var(--bxf-error); background: color-mix(in srgb, var(--bxf-error) 10%, transparent); }
5757
+
5758
+
5759
+ .bxf-responseMode { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) max-content; align-items: center; column-gap: 10px; row-gap: 5px; margin-top: 6px; padding: 8px 10px; border: 1px solid var(--dsw-alias-border-l1, #eef0f3); border-radius: 9px; background: var(--dsw-alias-bg-module-platform, #f7f8fa); }
5760
+ .bxf-responseModeHeader { display: contents; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: normal; }
5761
+ .bxf-responseModeHeader > span:first-child { grid-column: 1; grid-row: 1; white-space: nowrap; }
5762
+ .bxf-responseModeStatus { grid-column: 2; grid-row: 1; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 12px; white-space: nowrap; }
5763
+ .bxf-responseModeSelect { min-width: 0; width: 100%; grid-column: 1 / -1; grid-row: 2; height: 32px; padding: 0 30px 0 9px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 7px; color: var(--dsw-alias-label-primary, #1f2329); background-color: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 12px; cursor: pointer; transition: border-color .16s ease, box-shadow .16s ease, background-color .16s ease; }
5764
+ .bxf-responseModeSelect:hover:not(:disabled) { border-color: color-mix(in srgb, var(--bxf-accent) 45%, var(--dsw-alias-border-l2, #dfe1e5)); }
5765
+ .bxf-responseModeSelect:focus-visible { outline: none; border-color: var(--bxf-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--bxf-accent) 16%, transparent); }
5766
+ .bxf-responseModeSelect:disabled { cursor: not-allowed; opacity: .55; }
5767
+ .bxf-responseModeHelp { grid-column: 1 / -1; grid-row: 3; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; line-height: 1.45; }
5768
+ .bxf-responseModePermissionAction { grid-column: 1 / -1; grid-row: 4; display: flex; justify-content: flex-start; margin-top: 2px; }
5769
+ .bxf-responseModePermissionButton { min-height: 28px; padding: 3px 9px; color: var(--bxf-accent); border-color: color-mix(in srgb, var(--bxf-accent) 30%, var(--dsw-alias-border-l2, #dfe1e5)); background: var(--dsw-alias-bg-layer-1, #fff); }
5770
+ .bxf-responseModePermissionButton:hover:not(:disabled) { background: color-mix(in srgb, var(--bxf-accent) 7%, transparent); }
5771
+ .bxf-responseModeError { grid-column: 1 / -1; grid-row: 5; color: var(--bxf-error); font-size: 12px; line-height: 1.4; margin: 0; }
5772
+
5773
+ .bxf-botProvision {
5774
+ position: relative;
5775
+ margin-top: 14px;
5776
+ scroll-margin-block: 20px;
5777
+ animation: bxf-revealProvision .2s var(--ds-ease-out, ease-out) both;
5778
+ }
5779
+ .bxf-botProvision:focus { outline: none; }
5780
+ .bxf-botProvision:focus-visible {
5781
+ outline: 2px solid color-mix(in srgb, var(--bxf-accent) 75%, transparent);
5782
+ outline-offset: 3px;
5783
+ border-radius: 12px;
5784
+ }
5785
+ .bxf-botProvision > .bxf-provisionCard {
5786
+ border-radius: 11px;
5787
+ box-shadow: none;
5788
+ background: color-mix(in srgb, var(--bxf-accent) 2.5%, var(--dsw-alias-bg-layer-3, #fff));
5789
+ }
5790
+ .bxf-botProvision .bxf-cardBody { padding: 18px; }
5791
+ .bxf-botProvision .bxf-qrLayout {
5792
+ grid-template-columns: 184px minmax(0, 1fr);
5793
+ align-items: start;
5794
+ gap: 24px;
5795
+ }
5796
+ .bxf-botProvision .bxf-qrFrame { width: 176px; height: 176px; padding: 10px; border-radius: 11px; }
5797
+ .bxf-botProvision .bxf-countdown { width: 176px; }
5798
+ .bxf-botProvision .bxf-qrCopy h3 { font-size: 18px; line-height: 26px; }
5799
+ .bxf-botProvision .bxf-steps { gap: 8px; margin-top: 14px; }
5800
+ .bxf-botProvision .bxf-actions { margin-top: 16px; }
5801
+ .bxf-botProvision .bxf-inlineError { min-height: 160px; padding: 22px; }
5802
+
5803
+ .bxf-connectedFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
5804
+ .bxf-healthSummary { min-width: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 18px; }
5805
+ .bxf-healthSummary[data-error="true"] { color: var(--bxf-error); }
5806
+ .bxf-botActions { position: relative; flex: none; width: 100%; flex-wrap: wrap; gap: 8px; margin-top: 0; justify-content: flex-end; }
5807
+ .bxf-botActions .bxf-button { flex: none; white-space: nowrap; }
5808
+ .bxf-botActions .bxf-repairButton { color: var(--bxf-accent); border-color: color-mix(in srgb, var(--bxf-accent) 35%, var(--dsw-alias-border-l2, #dee0e3)); }
5809
+ .bxf-botActions .bxf-repairButton:hover:not(:disabled) { background: color-mix(in srgb, var(--bxf-accent) 7%, transparent); }
5810
+ .bxf-repairAction { display: inline-flex; }
5811
+ .bxf-repairTooltip {
5812
+ position: absolute;
5813
+ right: 0;
5814
+ bottom: calc(100% + 8px);
5815
+ z-index: 40;
5816
+ width: min(330px, 100%);
5817
+ display: grid;
5818
+ gap: 3px;
5819
+ padding: 9px 10px;
5820
+ border: 1px solid var(--dsw-alias-border-l2, #dfe1e5);
5821
+ border-radius: 8px;
5822
+ color: var(--dsw-alias-label-primary, #1f2329);
5823
+ background: var(--dsw-alias-bg-layer-3, #fff);
5824
+ box-shadow: 0 10px 28px rgb(31 35 41 / 16%);
5825
+ opacity: 0;
5826
+ visibility: hidden;
5827
+ transform: translateY(3px);
5828
+ pointer-events: none;
5829
+ transition: opacity .15s ease, transform .15s ease, visibility .15s ease;
5830
+ }
5831
+ .bxf-repairTooltip strong { font-size: 12px; line-height: 17px; font-weight: 650; }
5832
+ .bxf-repairTooltip > span { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 17px; font-weight: 400; overflow-wrap: anywhere; }
5833
+ .bxf-repairAction:hover .bxf-repairTooltip,
5834
+ .bxf-repairAction:focus-within .bxf-repairTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
5835
+
5836
+ .bxf-confirm {
5837
+ border-top: 1px solid var(--dsw-alias-border-l2, #dee0e3);
5838
+ background: color-mix(in srgb, var(--bxf-error) 4%, var(--dsw-alias-bg-module-platform, #f7f8fa));
5839
+ padding: 17px 24px 20px;
5840
+ }
5841
+ .bxf-confirm:focus { outline: none; }
5842
+ .bxf-confirm h4 { font-size: 13px; line-height: 20px; margin: 0; }
5843
+ .bxf-confirm p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 19px; margin: 4px 0 0; }
5844
+ .bxf-confirm .bxf-actions { margin-top: 12px; }
5845
+
5846
+ .bxf-error { min-height: 252px; display: grid; grid-template-columns: 44px minmax(0, 1fr); align-content: center; gap: 15px; padding: 30px; }
5847
+ .bxf-errorIcon { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 13px; color: var(--bxf-error); background: color-mix(in srgb, var(--bxf-error) 9%, transparent); }
5848
+ .bxf-error h3 { font-size: 17px; line-height: 25px; }
5849
+ .bxf-error p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 21px; margin-top: 5px; overflow-wrap: anywhere; }
5850
+ .bxf-errorCode { display: inline-block; color: var(--dsw-alias-label-tertiary, #8f959e); font-family: var(--ds-font-family-code, monospace); font-size: 11px; margin-top: 7px; }
5851
+
5852
+ .bxf-statusNotice {
5853
+ display: flex;
5854
+ align-items: center;
5855
+ gap: 9px;
5856
+ border: 1px solid color-mix(in srgb, var(--bxf-warning) 28%, var(--dsw-alias-border-l2, #dee0e3));
5857
+ border-radius: 10px;
5858
+ padding: 9px 11px;
5859
+ color: var(--dsw-alias-label-secondary, #646a73);
5860
+ background: color-mix(in srgb, var(--bxf-warning) 5%, var(--dsw-alias-bg-layer-1, #fff));
5861
+ font-size: 12px;
5862
+ line-height: 18px;
5863
+ }
5864
+ .bxf-statusNotice > svg { flex: none; color: var(--bxf-warning); }
5865
+ .bxf-statusNotice > span { min-width: 0; flex: 1; overflow-wrap: anywhere; }
5866
+
5867
+ .bxf-skeleton { min-height: 260px; padding: 28px; }
5868
+ .bxf-skeletonLine { height: 12px; border-radius: 999px; background: linear-gradient(90deg, var(--dsw-alias-bg-module-platform, #f2f3f5), color-mix(in srgb, var(--dsw-alias-label-tertiary, #8f959e) 10%, transparent), var(--dsw-alias-bg-module-platform, #f2f3f5)); background-size: 220% 100%; animation: bxf-shimmer 1.5s linear infinite; }
5869
+ .bxf-skeletonLine:nth-child(1) { width: 92px; }
5870
+ .bxf-skeletonLine:nth-child(2) { width: 44%; height: 22px; margin-top: 23px; }
5871
+ .bxf-skeletonLine:nth-child(3) { width: 72%; margin-top: 14px; }
5872
+ .bxf-skeletonLine:nth-child(4) { width: 58%; margin-top: 9px; }
5873
+ .bxf-skeletonBox { width: 138px; height: 38px; border-radius: 8px; background: var(--dsw-alias-bg-module-platform, #f2f3f5); margin-top: 28px; }
5874
+
5875
+ .bxf-visuallyHidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
5876
+
5877
+ @keyframes bxf-rotate { to { transform: rotate(360deg); } }
5878
+ @keyframes bxf-pulse { 0%, 100% { transform: scale(.9); opacity: .45; } 50% { transform: scale(1.08); opacity: 1; } }
5879
+ @keyframes bxf-shimmer { to { background-position: -220% 0; } }
5880
+ @keyframes bxf-revealProvision { from { opacity: 0; transform: translateY(-5px); } }
5881
+
5882
+ @container (max-width: 620px) {
5883
+ .bxf-headingTools { gap: 6px; }
5884
+ .bxf-headingTools .bxf-totalBadge { padding-inline: 8px; }
5885
+ .bxf-headingTools .bxf-bindButton { padding-inline: 10px; }
5886
+ }
5887
+
5888
+ @media (max-width: 680px) {
5889
+ .bxf-intro { grid-template-columns: minmax(0, 1fr); }
5890
+ .bxf-markStage { display: none; }
5891
+ .bxf-qrLayout { grid-template-columns: minmax(0, 1fr); justify-items: center; }
5892
+ .bxf-botProvision .bxf-qrLayout { grid-template-columns: minmax(0, 1fr); }
5893
+ .bxf-qrCopy { width: 100%; }
5894
+ .bxf-connectedTop { align-items: flex-start; flex-direction: column; }
5895
+ .bxf-inlineError { grid-template-columns: minmax(0, 1fr); padding: 20px; }
5896
+ .bxf-statusNotice { align-items: flex-start; flex-wrap: wrap; }
5897
+ .bxf-cardBody { padding: 20px; }
5898
+ }
5899
+
5900
+ @media (prefers-reduced-motion: reduce) {
5901
+ .bxf-page *, .bxf-page *::before, .bxf-page *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: .01ms !important; }
5902
+ }
5903
+ `;
5904
+ function installFeishuStyles() {
5905
+ if (typeof document === "undefined") {
5906
+ return () => {
5907
+ };
5908
+ }
5909
+ const existing = document.querySelector(
5910
+ `style[data-plugin-css="${FEISHU_STYLE_ID}"]`
5911
+ );
5912
+ if (existing) {
5913
+ return () => {
5914
+ };
5915
+ }
5916
+ const style = document.createElement("style");
5917
+ style.dataset.plugin = "@xmanrui/dsh-im";
5918
+ style.dataset.pluginCss = FEISHU_STYLE_ID;
5919
+ style.textContent = CSS3;
5920
+ document.head.appendChild(style);
5921
+ return () => {
5922
+ style.remove();
5923
+ };
5924
+ }
5925
+
5926
5926
  // plugin-src/client/channels/qq/api.js
5927
5927
  var QQ_RPC_CHANNEL = "/qq";
5928
5928
  var QQ_ENDPOINTS = Object.freeze({
@@ -7062,6 +7062,7 @@ oauth_config:
7062
7062
  - files:read
7063
7063
  - files:write
7064
7064
  - im:history
7065
+ - reactions:write
7065
7066
  settings:
7066
7067
  event_subscriptions:
7067
7068
  bot_events:
@@ -8416,123 +8417,6 @@ function formatRemaining5(milliseconds) {
8416
8417
  return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, "0")}`;
8417
8418
  }
8418
8419
 
8419
- // plugin-src/client/channels/weixin/styles.js
8420
- var WEIXIN_STYLE_ID = "xmanrui-dsh-weixin-settings";
8421
- var CSS9 = String.raw`
8422
- .dxw-page {
8423
- --dxw-accent: #07c160;
8424
- --dxw-accent-dark: #05994c;
8425
- --dxw-success: var(--dsw-alias-state-success-primary, #20a162);
8426
- --dxw-warning: var(--dsw-alias-state-warn-primary, #d97706);
8427
- --dxw-error: var(--dsw-alias-state-error-primary, #d54941);
8428
- width: 100%;
8429
- max-width: 880px;
8430
- display: flex;
8431
- flex-direction: column;
8432
- gap: 18px;
8433
- padding: 2px 0 28px;
8434
- color: var(--dsw-alias-label-primary, #1f2329);
8435
- box-sizing: border-box;
8436
- }
8437
- .dxw-page *, .dxw-page *::before, .dxw-page *::after { box-sizing: border-box; }
8438
- .dxw-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
8439
- .dxw-heading h2, .dxw-heading p, .dxw-card h3, .dxw-card p { margin: 0; }
8440
- .dxw-eyebrow { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 12px; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 3px; }
8441
- .dxw-heading h2 { font-size: 20px; line-height: 28px; font-weight: 680; }
8442
- .dxw-heading p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 20px; margin-top: 5px; white-space: nowrap; }
8443
- .dxw-tools, .dxw-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
8444
- .dxw-tools { width: 100%; justify-content: space-between; flex-wrap: nowrap; }
8445
- .dxw-badge { display: inline-flex; align-items: center; gap: 7px; min-height: 30px; padding: 0 11px; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f2f3f5); font-size: 12px; white-space: nowrap; }
8446
- .dxw-dot { width: 8px; height: 8px; border-radius: 50%; background: #aeb3bb; flex: none; }
8447
- .dxw-dot[data-tone="success"] { background: var(--dxw-success); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dxw-success) 14%, transparent); }
8448
- .dxw-dot[data-tone="warning"] { background: var(--dxw-warning); }
8449
- .dxw-dot[data-tone="error"] { background: var(--dxw-error); }
8450
- .dxw-button { min-height: 34px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; padding: 0 13px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; font-weight: 560; cursor: pointer; text-decoration: none; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
8451
- .dxw-button:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
8452
- .dxw-button:active:not(:disabled) { transform: translateY(1px); }
8453
- .dxw-button:focus-visible, .dxw-input:focus-visible { outline: 2px solid color-mix(in srgb, var(--dxw-accent) 70%, white); outline-offset: 2px; }
8454
- .dxw-button:disabled { cursor: not-allowed; opacity: .55; }
8455
- .dxw-button[data-kind="primary"] { color: white; border-color: var(--dxw-accent); background: var(--dxw-accent); }
8456
- .dxw-button[data-kind="primary"]:hover:not(:disabled) { border-color: var(--dxw-accent-dark); background: var(--dxw-accent-dark); }
8457
- .dxw-button[data-kind="danger"] { color: var(--dxw-error); }
8458
- .dxw-card { overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
8459
- .dxw-cardBody { padding: 24px; }
8460
- .dxw-empty { min-height: 230px; display: grid; grid-template-columns: minmax(0, 1fr) 180px; align-items: center; gap: 30px; }
8461
- .dxw-empty h3 { font-size: 18px; margin-bottom: 8px; }
8462
- .dxw-empty p { max-width: 560px; color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.65; }
8463
- .dxw-empty .dxw-actions { margin-top: 20px; }
8464
- .dxw-logo { width: 110px; height: 110px; display: grid; place-items: center; justify-self: center; border-radius: 28px; color: white; background: var(--dxw-accent); box-shadow: 0 18px 45px rgb(7 193 96 / 22%); }
8465
- .dxw-logo svg { width: 62px; height: 62px; }
8466
- .dxw-qrLayout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 34px; align-items: center; }
8467
- .dxw-qrColumn { display: flex; flex-direction: column; align-items: center; gap: 12px; }
8468
- .dxw-qrFrame { position: relative; width: 270px; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 16px; background: white; }
8469
- .dxw-qrFrame img { display: block; width: 100%; height: 100%; object-fit: contain; }
8470
- .dxw-qrFallback { padding: 24px; text-align: center; color: #646a73; }
8471
- .dxw-expired { position: absolute; inset: 0; display: grid; place-items: center; padding: 30px; color: white; text-align: center; font-weight: 650; background: rgb(31 35 41 / 76%); backdrop-filter: blur(3px); }
8472
- .dxw-countdown { width: 270px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; }
8473
- .dxw-countdown div { display: flex; justify-content: space-between; margin-bottom: 6px; }
8474
- .dxw-progress { height: 4px; overflow: hidden; border-radius: 99px; background: #eef0f3; }
8475
- .dxw-progress span { display: block; width: var(--dxw-progress); height: 100%; background: var(--dxw-accent); transition: width .2s linear; }
8476
- .dxw-qrCopy h3 { margin: 9px 0 8px; font-size: 18px; }
8477
- .dxw-qrCopy > p { color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.65; }
8478
- .dxw-steps { margin: 18px 0 22px; padding-left: 22px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 1.9; }
8479
- .dxw-stateLabel { display: inline-flex; align-items: center; gap: 8px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; font-weight: 600; }
8480
- .dxw-verify { max-width: 560px; margin: 0 auto; padding: 32px; text-align: center; }
8481
- .dxw-verify h3 { margin: 8px 0; font-size: 19px; }
8482
- .dxw-verify p { color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.6; }
8483
- .dxw-codeRow { display: flex; justify-content: center; gap: 10px; margin: 24px 0 10px; }
8484
- .dxw-input { width: 190px; height: 42px; padding: 0 14px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; background: var(--dsw-alias-bg-layer-1, white); color: inherit; font: inherit; font-size: 18px; letter-spacing: .16em; text-align: center; }
8485
- .dxw-statusNotice, .dxw-error { display: flex; align-items: center; gap: 10px; padding: 13px 15px; border: 1px solid color-mix(in srgb, var(--dxw-error) 28%, transparent); border-radius: 10px; color: var(--dxw-error); background: color-mix(in srgb, var(--dxw-error) 7%, transparent); font-size: 13px; }
8486
- .dxw-error { align-items: flex-start; flex-direction: column; padding: 22px; }
8487
- .dxw-error h3 { font-size: 17px; }
8488
- .dxw-errorCode { font-family: ui-monospace, SFMono-Regular, monospace; font-size: 11px; opacity: .8; }
8489
- .dxw-listHeading { display: flex; justify-content: space-between; align-items: center; margin: 2px 0 9px; }
8490
- .dxw-listHeading h3 { margin: 0; font-size: 14px; }
8491
- .dxw-list { display: grid; gap: 12px; margin: 0; padding: 0; list-style: none; }
8492
- .dxw-accountTop { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
8493
- .dxw-accountIdentity { display: flex; align-items: center; gap: 12px; min-width: 0; }
8494
- .dxw-avatar { width: 42px; height: 42px; display: grid; place-items: center; flex: none; border-radius: 12px; color: white; background: var(--dxw-accent); }
8495
- .dxw-accountIdentity h3 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; }
8496
- .dxw-accountIdentity p { color: var(--dsw-alias-label-secondary, #646a73); font: 12px ui-monospace, SFMono-Regular, monospace; margin-top: 4px; }
8497
- .dxw-health { display: inline-flex; align-items: center; gap: 7px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; white-space: nowrap; }
8498
- .dxw-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
8499
- .dxw-accountFooter .dxw-actions { flex: none; flex-wrap: nowrap; gap: 8px; margin-top: 0; }
8500
- .dxw-accountFooter .dxw-button { flex: none; white-space: nowrap; }
8501
- .dxw-summary { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; }
8502
- .dxw-confirm { padding: 18px 24px; border-top: 1px solid color-mix(in srgb, var(--dxw-error) 25%, transparent); background: color-mix(in srgb, var(--dxw-error) 5%, transparent); }
8503
- .dxw-confirm strong { display: block; font-size: 14px; margin-bottom: 6px; }
8504
- .dxw-confirm p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 1.55; }
8505
- .dxw-confirm .dxw-actions { margin-top: 13px; }
8506
- .dxw-loading { padding: 36px; color: var(--dsw-alias-label-secondary, #646a73); text-align: center; }
8507
- .dxw-spinner { width: 24px; height: 24px; margin: 0 auto 12px; border: 3px solid #e6e8eb; border-top-color: var(--dxw-accent); border-radius: 50%; animation: dxw-spin .8s linear infinite; }
8508
- .dxw-visuallyHidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
8509
- @keyframes dxw-spin { to { transform: rotate(360deg); } }
8510
- @media (max-width: 720px) {
8511
- .dxw-heading, .dxw-accountTop { flex-direction: column; align-items: stretch; }
8512
- .dxw-empty { grid-template-columns: minmax(0, 1fr); }
8513
- .dxw-logo { display: none; }
8514
- .dxw-qrLayout { grid-template-columns: minmax(0, 1fr); justify-items: center; }
8515
- .dxw-qrCopy { width: 100%; }
8516
- .dxw-cardBody { padding: 20px; }
8517
- }
8518
- @media (prefers-reduced-motion: reduce) {
8519
- .dxw-page *, .dxw-page *::before, .dxw-page *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
8520
- }
8521
- `;
8522
- function installWeixinStyles() {
8523
- if (typeof document === "undefined") return () => {
8524
- };
8525
- const existing = document.querySelector(`style[data-plugin-css="${WEIXIN_STYLE_ID}"]`);
8526
- if (existing) return () => {
8527
- };
8528
- const style = document.createElement("style");
8529
- style.dataset.plugin = "@xmanrui/dsh-weixin";
8530
- style.dataset.pluginCss = WEIXIN_STYLE_ID;
8531
- style.textContent = CSS9;
8532
- document.head.appendChild(style);
8533
- return () => style.remove();
8534
- }
8535
-
8536
8420
  // plugin-src/client/channels/weixin/index.js
8537
8421
  var Button12 = React18.forwardRef(function Button13({ children, kind = "secondary", className = "", ...props }, ref) {
8538
8422
  return h2("button", {
@@ -9319,6 +9203,123 @@ function WeixinSettingsTab({ rpcCall }) {
9319
9203
  ));
9320
9204
  }
9321
9205
 
9206
+ // plugin-src/client/channels/weixin/styles.js
9207
+ var WEIXIN_STYLE_ID = "xmanrui-dsh-im-weixin-settings";
9208
+ var CSS9 = String.raw`
9209
+ .dxw-page {
9210
+ --dxw-accent: #07c160;
9211
+ --dxw-accent-dark: #05994c;
9212
+ --dxw-success: var(--dsw-alias-state-success-primary, #20a162);
9213
+ --dxw-warning: var(--dsw-alias-state-warn-primary, #d97706);
9214
+ --dxw-error: var(--dsw-alias-state-error-primary, #d54941);
9215
+ width: 100%;
9216
+ max-width: 880px;
9217
+ display: flex;
9218
+ flex-direction: column;
9219
+ gap: 18px;
9220
+ padding: 2px 0 28px;
9221
+ color: var(--dsw-alias-label-primary, #1f2329);
9222
+ box-sizing: border-box;
9223
+ }
9224
+ .dxw-page *, .dxw-page *::before, .dxw-page *::after { box-sizing: border-box; }
9225
+ .dxw-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
9226
+ .dxw-heading h2, .dxw-heading p, .dxw-card h3, .dxw-card p { margin: 0; }
9227
+ .dxw-eyebrow { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 12px; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 3px; }
9228
+ .dxw-heading h2 { font-size: 20px; line-height: 28px; font-weight: 680; }
9229
+ .dxw-heading p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 20px; margin-top: 5px; white-space: nowrap; }
9230
+ .dxw-tools, .dxw-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
9231
+ .dxw-tools { width: 100%; justify-content: space-between; flex-wrap: nowrap; }
9232
+ .dxw-badge { display: inline-flex; align-items: center; gap: 7px; min-height: 30px; padding: 0 11px; border-radius: 999px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-module-platform, #f2f3f5); font-size: 12px; white-space: nowrap; }
9233
+ .dxw-dot { width: 8px; height: 8px; border-radius: 50%; background: #aeb3bb; flex: none; }
9234
+ .dxw-dot[data-tone="success"] { background: var(--dxw-success); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dxw-success) 14%, transparent); }
9235
+ .dxw-dot[data-tone="warning"] { background: var(--dxw-warning); }
9236
+ .dxw-dot[data-tone="error"] { background: var(--dxw-error); }
9237
+ .dxw-button { min-height: 34px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; padding: 0 13px; display: inline-flex; align-items: center; justify-content: center; gap: 7px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 13px; font-weight: 560; cursor: pointer; text-decoration: none; transition: border-color .15s ease, background .15s ease, transform .15s ease; }
9238
+ .dxw-button:hover:not(:disabled) { border-color: #aeb3bb; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
9239
+ .dxw-button:active:not(:disabled) { transform: translateY(1px); }
9240
+ .dxw-button:focus-visible, .dxw-input:focus-visible { outline: 2px solid color-mix(in srgb, var(--dxw-accent) 70%, white); outline-offset: 2px; }
9241
+ .dxw-button:disabled { cursor: not-allowed; opacity: .55; }
9242
+ .dxw-button[data-kind="primary"] { color: white; border-color: var(--dxw-accent); background: var(--dxw-accent); }
9243
+ .dxw-button[data-kind="primary"]:hover:not(:disabled) { border-color: var(--dxw-accent-dark); background: var(--dxw-accent-dark); }
9244
+ .dxw-button[data-kind="danger"] { color: var(--dxw-error); }
9245
+ .dxw-card { overflow: hidden; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); box-shadow: 0 1px 2px rgb(31 35 41 / 3%); }
9246
+ .dxw-cardBody { padding: 24px; }
9247
+ .dxw-empty { min-height: 230px; display: grid; grid-template-columns: minmax(0, 1fr) 180px; align-items: center; gap: 30px; }
9248
+ .dxw-empty h3 { font-size: 18px; margin-bottom: 8px; }
9249
+ .dxw-empty p { max-width: 560px; color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.65; }
9250
+ .dxw-empty .dxw-actions { margin-top: 20px; }
9251
+ .dxw-logo { width: 110px; height: 110px; display: grid; place-items: center; justify-self: center; border-radius: 28px; color: white; background: var(--dxw-accent); box-shadow: 0 18px 45px rgb(7 193 96 / 22%); }
9252
+ .dxw-logo svg { width: 62px; height: 62px; }
9253
+ .dxw-qrLayout { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 34px; align-items: center; }
9254
+ .dxw-qrColumn { display: flex; flex-direction: column; align-items: center; gap: 12px; }
9255
+ .dxw-qrFrame { position: relative; width: 270px; aspect-ratio: 1; display: grid; place-items: center; overflow: hidden; padding: 10px; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 16px; background: white; }
9256
+ .dxw-qrFrame img { display: block; width: 100%; height: 100%; object-fit: contain; }
9257
+ .dxw-qrFallback { padding: 24px; text-align: center; color: #646a73; }
9258
+ .dxw-expired { position: absolute; inset: 0; display: grid; place-items: center; padding: 30px; color: white; text-align: center; font-weight: 650; background: rgb(31 35 41 / 76%); backdrop-filter: blur(3px); }
9259
+ .dxw-countdown { width: 270px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; }
9260
+ .dxw-countdown div { display: flex; justify-content: space-between; margin-bottom: 6px; }
9261
+ .dxw-progress { height: 4px; overflow: hidden; border-radius: 99px; background: #eef0f3; }
9262
+ .dxw-progress span { display: block; width: var(--dxw-progress); height: 100%; background: var(--dxw-accent); transition: width .2s linear; }
9263
+ .dxw-qrCopy h3 { margin: 9px 0 8px; font-size: 18px; }
9264
+ .dxw-qrCopy > p { color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.65; }
9265
+ .dxw-steps { margin: 18px 0 22px; padding-left: 22px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 13px; line-height: 1.9; }
9266
+ .dxw-stateLabel { display: inline-flex; align-items: center; gap: 8px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; font-weight: 600; }
9267
+ .dxw-verify { max-width: 560px; margin: 0 auto; padding: 32px; text-align: center; }
9268
+ .dxw-verify h3 { margin: 8px 0; font-size: 19px; }
9269
+ .dxw-verify p { color: var(--dsw-alias-label-secondary, #646a73); line-height: 1.6; }
9270
+ .dxw-codeRow { display: flex; justify-content: center; gap: 10px; margin: 24px 0 10px; }
9271
+ .dxw-input { width: 190px; height: 42px; padding: 0 14px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; background: var(--dsw-alias-bg-layer-1, white); color: inherit; font: inherit; font-size: 18px; letter-spacing: .16em; text-align: center; }
9272
+ .dxw-statusNotice, .dxw-error { display: flex; align-items: center; gap: 10px; padding: 13px 15px; border: 1px solid color-mix(in srgb, var(--dxw-error) 28%, transparent); border-radius: 10px; color: var(--dxw-error); background: color-mix(in srgb, var(--dxw-error) 7%, transparent); font-size: 13px; }
9273
+ .dxw-error { align-items: flex-start; flex-direction: column; padding: 22px; }
9274
+ .dxw-error h3 { font-size: 17px; }
9275
+ .dxw-errorCode { font-family: ui-monospace, SFMono-Regular, monospace; font-size: 11px; opacity: .8; }
9276
+ .dxw-listHeading { display: flex; justify-content: space-between; align-items: center; margin: 2px 0 9px; }
9277
+ .dxw-listHeading h3 { margin: 0; font-size: 14px; }
9278
+ .dxw-list { display: grid; gap: 12px; margin: 0; padding: 0; list-style: none; }
9279
+ .dxw-accountTop { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
9280
+ .dxw-accountIdentity { display: flex; align-items: center; gap: 12px; min-width: 0; }
9281
+ .dxw-avatar { width: 42px; height: 42px; display: grid; place-items: center; flex: none; border-radius: 12px; color: white; background: var(--dxw-accent); }
9282
+ .dxw-accountIdentity h3 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; }
9283
+ .dxw-accountIdentity p { color: var(--dsw-alias-label-secondary, #646a73); font: 12px ui-monospace, SFMono-Regular, monospace; margin-top: 4px; }
9284
+ .dxw-health { display: inline-flex; align-items: center; gap: 7px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; white-space: nowrap; }
9285
+ .dxw-accountFooter { display: flex; align-items: center; justify-content: space-between; gap: 15px; padding-top: 16px; border-top: 1px solid var(--dsw-alias-border-l1, #eef0f3); }
9286
+ .dxw-accountFooter .dxw-actions { flex: none; flex-wrap: nowrap; gap: 8px; margin-top: 0; }
9287
+ .dxw-accountFooter .dxw-button { flex: none; white-space: nowrap; }
9288
+ .dxw-summary { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; }
9289
+ .dxw-confirm { padding: 18px 24px; border-top: 1px solid color-mix(in srgb, var(--dxw-error) 25%, transparent); background: color-mix(in srgb, var(--dxw-error) 5%, transparent); }
9290
+ .dxw-confirm strong { display: block; font-size: 14px; margin-bottom: 6px; }
9291
+ .dxw-confirm p { color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 1.55; }
9292
+ .dxw-confirm .dxw-actions { margin-top: 13px; }
9293
+ .dxw-loading { padding: 36px; color: var(--dsw-alias-label-secondary, #646a73); text-align: center; }
9294
+ .dxw-spinner { width: 24px; height: 24px; margin: 0 auto 12px; border: 3px solid #e6e8eb; border-top-color: var(--dxw-accent); border-radius: 50%; animation: dxw-spin .8s linear infinite; }
9295
+ .dxw-visuallyHidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
9296
+ @keyframes dxw-spin { to { transform: rotate(360deg); } }
9297
+ @media (max-width: 720px) {
9298
+ .dxw-heading, .dxw-accountTop { flex-direction: column; align-items: stretch; }
9299
+ .dxw-empty { grid-template-columns: minmax(0, 1fr); }
9300
+ .dxw-logo { display: none; }
9301
+ .dxw-qrLayout { grid-template-columns: minmax(0, 1fr); justify-items: center; }
9302
+ .dxw-qrCopy { width: 100%; }
9303
+ .dxw-cardBody { padding: 20px; }
9304
+ }
9305
+ @media (prefers-reduced-motion: reduce) {
9306
+ .dxw-page *, .dxw-page *::before, .dxw-page *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
9307
+ }
9308
+ `;
9309
+ function installWeixinStyles() {
9310
+ if (typeof document === "undefined") return () => {
9311
+ };
9312
+ const existing = document.querySelector(`style[data-plugin-css="${WEIXIN_STYLE_ID}"]`);
9313
+ if (existing) return () => {
9314
+ };
9315
+ const style = document.createElement("style");
9316
+ style.dataset.plugin = "@xmanrui/dsh-im";
9317
+ style.dataset.pluginCss = WEIXIN_STYLE_ID;
9318
+ style.textContent = CSS9;
9319
+ document.head.appendChild(style);
9320
+ return () => style.remove();
9321
+ }
9322
+
9322
9323
  // plugin-src/client/channels/whatsapp/api.js
9323
9324
  var WHATSAPP_RPC_CHANNEL = "/whatsapp";
9324
9325
  var WHATSAPP_ENDPOINTS = Object.freeze({
@@ -10916,10 +10917,10 @@ function apply(ctx) {
10916
10917
  listDirectory: (path, signal) => ctx.workspaces.listDirectory(path, signal),
10917
10918
  pickDirectory: () => ctx.workspaces.pickDirectory()
10918
10919
  });
10919
- ctx.slots.inject("settings.plugins.tab", () => ctx.slots.register({
10920
- name: "settings.plugins.tab",
10921
- id: "im",
10922
- order: 20,
10920
+ ctx.slots.inject("settings.section", () => ctx.slots.register({
10921
+ name: "settings.section",
10922
+ id: "xmanrui-dsh-im",
10923
+ order: 21,
10923
10924
  label: () => t("IM\u673A\u5668\u4EBA"),
10924
10925
  locale: IM_LOCALE_NAMESPACE,
10925
10926
  inject: () => ({