@xmanrui/dsh-im 4.19.1 → 4.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +96 -4
- package/README.md +96 -4
- package/lib/client.js +666 -217
- package/lib/index.js +277 -273
- package/package.json +13 -1
- package/plugin-src/client/channels/weixin/api.js +35 -17
- package/plugin-src/client/channels/weixin/connection-error.js +68 -0
- package/plugin-src/client/channels/weixin/index.js +36 -12
- package/plugin-src/client/i18n.js +2 -0
- package/plugin-src/client/index.js +15 -0
- package/plugin-src/client/interface-language.js +89 -0
- package/plugin-src/host/channels/shared/startup.mjs +30 -4
- package/plugin-src/host/channels/weixin/connection-supervisor.mjs +13 -1
- package/plugin-src/host/channels/weixin/index.mjs +12 -3
- package/plugin-src/host/channels/weixin/production.mjs +53 -3
- package/plugin-src/host/channels/weixin/rpc.mjs +22 -17
- package/plugin-src/host/host-language-rpc.mjs +71 -0
- package/plugin-src/host/host-language.mjs +157 -0
- package/plugin-src/host/index.mjs +15 -2
- package/scripts/verify-interface-language.mjs +333 -0
- package/src/channels/dingtalk/dingtalk-bridge.mjs +4 -1
- package/src/channels/dingtalk/dingtalk-menu.mjs +8 -4
- package/src/channels/discord/discord-runtime.mjs +1 -1
- package/src/channels/feishu/bridge.mjs +44 -13
- package/src/channels/qq/qq-bridge.mjs +12 -4
- package/src/channels/qq/qq-menu.mjs +11 -8
- package/src/channels/shared/bot-workspace-store.mjs +532 -40
- package/src/channels/shared/command-catalog.mjs +5 -0
- package/src/channels/shared/compact-command.mjs +14 -4
- package/src/channels/shared/control-command.mjs +1 -1
- package/src/channels/shared/deferred-delivery-coordinator.mjs +1 -1
- package/src/channels/shared/history-command.mjs +1 -1
- package/src/channels/shared/i18n-en/discord.mjs +2 -0
- package/src/channels/shared/i18n-en/shared-a.mjs +41 -0
- package/src/channels/shared/i18n-en/telegram.mjs +5 -0
- package/src/channels/shared/i18n-en/weixin.mjs +2 -0
- package/src/channels/shared/i18n.mjs +46 -3
- package/src/channels/shared/interface-language-store.mjs +127 -0
- package/src/channels/shared/interface-language.mjs +51 -0
- package/src/channels/shared/model-command.mjs +5 -3
- package/src/channels/shared/token-bot-controller.mjs +26 -0
- package/src/channels/shared/workspace-command.mjs +114 -9
- package/src/channels/shared/workspace-session.mjs +55 -5
- package/src/channels/telegram/telegram-runtime.mjs +76 -14
- package/src/channels/wecom/wecom-bridge.mjs +2 -2
- package/src/channels/weixin/connection-error.en.mjs +116 -0
- package/src/channels/weixin/connection-error.mjs +204 -0
- package/src/channels/weixin/diagnostic-details.mjs +40 -0
- package/src/channels/weixin/state-store.mjs +4 -3
- package/src/channels/weixin/weixin-api.mjs +20 -8
- package/src/channels/weixin/weixin-bridge.mjs +3 -2
- package/src/channels/weixin/weixin-controller.mjs +133 -104
- package/src/channels/weixin/weixin-runtime.mjs +35 -24
package/lib/client.js
CHANGED
|
@@ -577,12 +577,12 @@ function callManagementRpc(connection, channel5, method, payload, signal) {
|
|
|
577
577
|
}
|
|
578
578
|
|
|
579
579
|
// plugin-src/client/index.js
|
|
580
|
-
var
|
|
580
|
+
var React31 = __toESM(require("react"), 1);
|
|
581
581
|
|
|
582
582
|
// package.json
|
|
583
583
|
var package_default = {
|
|
584
584
|
name: "@xmanrui/dsh-im",
|
|
585
|
-
version: "4.
|
|
585
|
+
version: "4.20.0",
|
|
586
586
|
description: "\u628A\u5341\u4E00\u79CD IM \u6E20\u9053\u548C\u516C\u7F51 AI Office \u63A5\u5165\u672C\u673A DeepSeek Harness\u3002 Connect eleven IM channels and a public AI Office to a local DeepSeek Harness.",
|
|
587
587
|
keywords: [
|
|
588
588
|
"deepseek-harness",
|
|
@@ -634,6 +634,18 @@ var package_default = {
|
|
|
634
634
|
{
|
|
635
635
|
name: "geekyfoxlab",
|
|
636
636
|
url: "https://github.com/geekyfoxlab"
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
name: "grloper",
|
|
640
|
+
url: "https://github.com/grloper"
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
name: "baijian",
|
|
644
|
+
url: "https://github.com/baijian"
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
name: "lyzhu86",
|
|
648
|
+
url: "https://github.com/lyzhu86"
|
|
637
649
|
}
|
|
638
650
|
],
|
|
639
651
|
license: "MIT",
|
|
@@ -911,10 +923,128 @@ function normalizeBotAlias(bot) {
|
|
|
911
923
|
// plugin-src/client/agent-preset.js
|
|
912
924
|
var React3 = __toESM(require("react"), 1);
|
|
913
925
|
|
|
926
|
+
// src/channels/weixin/connection-error.en.mjs
|
|
927
|
+
var connection_error_en_default = {
|
|
928
|
+
"\u63D2\u4EF6\u7248\u672C": "Plugin version",
|
|
929
|
+
"DSH \u5FAE\u4FE1\u7BA1\u7406\u63A5\u53E3\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u72B6\u6001\u3002": "The DSH WeChat management endpoint returned an invalid response. Refresh the status.",
|
|
930
|
+
"\u65E0\u6CD5\u8BFB\u53D6\u73B0\u6709\u767B\u5F55\u51ED\u636E\u3002\u8BF7\u68C0\u67E5 DSH \u51ED\u636E\u5B58\u50A8\u3002": "Could not read the saved login credential. Check the DSH credential store.",
|
|
931
|
+
"\u767B\u5F55\u51ED\u636E\u65E0\u6CD5\u5199\u5165 DSH \u51ED\u636E\u5B58\u50A8\u3002\u8BF7\u68C0\u67E5\u51ED\u636E\u5B58\u50A8\u662F\u5426\u53EF\u5199\u3002": "Could not save the login credential to DSH. Check whether the credential store is writable.",
|
|
932
|
+
"\u8D26\u53F7\u914D\u7F6E\u65E0\u6CD5\u5199\u5165\u672C\u673A\u3002\u8BF7\u68C0\u67E5 DSH_HOME \u76EE\u5F55\u6743\u9650\u3002": "Could not save the account configuration. Check permissions on DSH_HOME.",
|
|
933
|
+
"\u65E0\u6CD5\u521D\u59CB\u5316\u8D26\u53F7\u72B6\u6001\u6216\u5DE5\u4F5C\u533A\u3002\u8BF7\u68C0\u67E5 DSH_HOME \u548C\u5DE5\u4F5C\u533A\u76EE\u5F55\u3002": "Could not prepare the account state or workspace. Check DSH_HOME and the workspace directory.",
|
|
934
|
+
"\u63D2\u4EF6\u65E0\u6CD5\u8FDE\u63A5\u5F53\u524D Harness\uFF0C\u8BF7\u68C0\u67E5\u5BBF\u4E3B\u662F\u5426\u5DF2\u5C31\u7EEA\u3002": "The plugin could not connect to this Harness. Check whether the host is ready.",
|
|
935
|
+
"Harness \u5065\u5EB7\u68C0\u67E5\u8D85\u65F6\u3002\u8BF7\u786E\u8BA4 dsh web \u672A\u963B\u585E\u3002": "The Harness health check timed out. Check whether the host is responsive.",
|
|
936
|
+
"Harness \u5065\u5EB7\u68C0\u67E5\u9700\u8981\u8EAB\u4EFD\u8BA4\u8BC1\u3002\u8BF7\u68C0\u67E5\u4EE3\u7406\u3001\u7F51\u5173\u6216\u81EA\u5B9A\u4E49\u9274\u6743\u914D\u7F6E\u3002": "The Harness health check requires authentication. Check proxy, gateway or custom authentication settings.",
|
|
937
|
+
"\u672C\u673A Harness \u8BF7\u6C42\u88AB\u4EE3\u7406\u8981\u6C42\u8BA4\u8BC1\u3002\u8BF7\u8BA9\u56DE\u73AF\u5730\u5740\u7ED5\u8FC7\u4EE3\u7406\uFF0C\u5E76\u68C0\u67E5 NO_PROXY \u914D\u7F6E\u3002": "The proxy requires authentication for the local Harness request. Bypass the proxy for loopback addresses and check NO_PROXY.",
|
|
938
|
+
"Harness \u5F02\u5E38\u62D2\u7EDD\u4E86\u56DE\u73AF\u5730\u5740\u7684\u5065\u5EB7\u68C0\u67E5\u3002\u8BF7\u68C0\u67E5 HTTP \u4EE3\u7406\u3001Harness \u6E90\u7801\u7248\u672C\u548C\u6784\u5EFA\u4EA7\u7269\u3002": "Harness rejected a loopback health check. Check the HTTP proxy and the running Harness build.",
|
|
939
|
+
"Harness \u7684 Host \u4FE1\u4EFB\u68C0\u67E5\u62D2\u7EDD\u4E86\u975E\u56DE\u73AF\u5730\u5740\u8BF7\u6C42\u3002\u8BF7\u68C0\u67E5 harnessBaseUrl \u4E0E trustedHosts \u914D\u7F6E\u3002": "Harness rejected the non-loopback Host. Check harnessBaseUrl and trustedHosts.",
|
|
940
|
+
"\u5065\u5EB7\u68C0\u67E5\u6536\u5230\u4E86\u975E Harness \u6807\u51C6\u7684 403 \u62D2\u7EDD\u54CD\u5E94\u3002\u8BF7\u68C0\u67E5\u4EE3\u7406\u6216\u7F51\u5173\u914D\u7F6E\u3002": "The health check received a non-standard HTTP 403 response. Check proxy or gateway settings.",
|
|
941
|
+
"\u627E\u4E0D\u5230 Harness \u5065\u5EB7\u68C0\u67E5\u63A5\u53E3\u3002\u8BF7\u786E\u8BA4 Harness \u4E0E\u63D2\u4EF6\u7248\u672C\u517C\u5BB9\u3002": "The Harness health check endpoint was not found. Check Harness and plugin compatibility.",
|
|
942
|
+
"Harness \u5065\u5EB7\u68C0\u67E5\u8FD4\u56DE\u670D\u52A1\u9519\u8BEF\u3002\u8BF7\u67E5\u770B DSH \u65E5\u5FD7\u3002": "The Harness health check returned a service error. Check the DSH logs.",
|
|
943
|
+
"Harness \u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94\u3002\u8BF7\u786E\u8BA4 Harness \u4E0E\u63D2\u4EF6\u7248\u672C\u517C\u5BB9\u3002": "Harness returned an unrecognized response. Check Harness and plugin compatibility.",
|
|
944
|
+
"Harness \u62D2\u7EDD\u4E86\u5065\u5EB7\u68C0\u67E5\u8BF7\u6C42\u3002\u8BF7\u67E5\u770B DSH \u65E5\u5FD7\u3002": "Harness rejected the health check. Check the DSH logs.",
|
|
945
|
+
"Harness \u5065\u5EB7\u68C0\u67E5\u53D1\u751F\u672A\u77E5\u9519\u8BEF\u3002\u8BF7\u67E5\u770B DSH \u65E5\u5FD7\u3002": "The Harness health check failed with an unknown error. Check the DSH logs.",
|
|
946
|
+
"\u6D88\u606F\u8FDE\u63A5\u521D\u59CB\u5316\u5931\u8D25\u3002\u8BF7\u67E5\u770B DSH \u65E5\u5FD7\u540E\u91CD\u8BD5\u3002": "The message connection could not start. Check the DSH logs and retry.",
|
|
947
|
+
"\u6682\u65F6\u65E0\u6CD5\u8BBF\u95EE\u5FAE\u4FE1\u670D\u52A1\u3002": "The WeChat service is temporarily unreachable.",
|
|
948
|
+
"\u5FAE\u4FE1\u670D\u52A1\u8BF7\u6C42\u8D85\u65F6\u3002": "The WeChat service request timed out.",
|
|
949
|
+
"\u5FAE\u4FE1\u670D\u52A1\u8BF7\u6C42\u5931\u8D25\uFF08HTTP {status}\uFF09\u3002": "The WeChat service request failed (HTTP {status}).",
|
|
950
|
+
"\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u89E3\u6790\u7684\u54CD\u5E94\u3002": "The WeChat service returned an unparseable response.",
|
|
951
|
+
"\u5FAE\u4FE1\u670D\u52A1\u6CA1\u6709\u8FD4\u56DE\u6709\u6548\u4E8C\u7EF4\u7801\u3002": "The WeChat service did not return a valid QR code.",
|
|
952
|
+
"\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u626B\u7801\u5730\u5740\u3002": "The WeChat service returned an untrusted QR-code URL.",
|
|
953
|
+
"\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6548\u7684\u8FDE\u63A5\u5730\u5740\u3002": "The WeChat service returned an invalid connection URL.",
|
|
954
|
+
"\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u4E0D\u53D7\u4FE1\u4EFB\u7684\u8FDE\u63A5\u5730\u5740\u3002": "The WeChat service returned an untrusted connection URL.",
|
|
955
|
+
"\u62D2\u7EDD\u8BBF\u95EE\u4E0D\u53D7\u4FE1\u4EFB\u7684\u5FAE\u4FE1\u670D\u52A1\u5730\u5740\u3002": "Refusing to access an untrusted WeChat service URL.",
|
|
956
|
+
"\u5FAE\u4FE1\u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u626B\u7801\u72B6\u6001\u3002": "The WeChat service returned an unrecognized QR-code status.",
|
|
957
|
+
"\u5FAE\u4FE1\u6388\u6743\u6210\u529F\uFF0C\u4F46\u8FD4\u56DE\u7684\u8D26\u53F7\u51ED\u636E\u4E0D\u5B8C\u6574\u3002": "WeChat authorized the account but returned incomplete credentials.",
|
|
958
|
+
"\u5FAE\u4FE1\u670D\u52A1\u62D2\u7EDD\u4E86\u4E8C\u7EF4\u7801\u7533\u8BF7\u3002": "The WeChat service rejected the QR-code request.",
|
|
959
|
+
"\u5DF2\u53D6\u5F97\u626B\u7801\u5730\u5740\uFF0C\u4F46\u672C\u673A\u4E8C\u7EF4\u7801\u56FE\u7247\u751F\u6210\u5931\u8D25\u3002": "The login URL was obtained, but the QR-code image could not be generated locally.",
|
|
960
|
+
"\u65E0\u6CD5\u751F\u6210\u5FAE\u4FE1\u4E8C\u7EF4\u7801\u3002": "Could not generate a WeChat QR code.",
|
|
961
|
+
"\u8FD9\u6B21\u5FAE\u4FE1\u7ED1\u5B9A\u4EFB\u52A1\u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u72B6\u6001\u6216\u751F\u6210\u4E8C\u7EF4\u7801\u3002": "This WeChat setup attempt no longer exists. Refresh the status or generate a new QR code.",
|
|
962
|
+
"\u8FD9\u6B21\u5FAE\u4FE1\u7ED1\u5B9A\u4EFB\u52A1\u5F53\u524D\u4E0D\u80FD\u63D0\u4EA4\u914D\u5BF9\u7801\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u72B6\u6001\u3002": "This setup attempt is not waiting for a pairing code. Refresh the status.",
|
|
963
|
+
"\u767B\u5F55\u51ED\u636E\u7F3A\u5931\uFF0C\u8BF7\u79FB\u9664\u8D26\u53F7\u540E\u91CD\u65B0\u626B\u7801\u3002": "The login credential is missing. Remove the account and scan a new QR code.",
|
|
964
|
+
"\u5FAE\u4FE1\u767B\u5F55\u51ED\u636E\u5DF2\u5931\u6548\uFF0C\u8BF7\u79FB\u9664\u8D26\u53F7\u540E\u91CD\u65B0\u626B\u7801\u3002": "The WeChat login credential has expired. Remove the account and scan a new QR code.",
|
|
965
|
+
"\u65E0\u6CD5\u4ECE DSH \u51ED\u636E\u5B58\u50A8\u79FB\u9664\u5FAE\u4FE1\u767B\u5F55\u51ED\u636E\u3002": "Could not remove the WeChat login credential from the DSH credential store.",
|
|
966
|
+
"\u5FAE\u4FE1\u8D26\u53F7\u914D\u7F6E\u79FB\u9664\u5931\u8D25\u3002": "Could not remove the WeChat account configuration.",
|
|
967
|
+
"\u65E0\u6CD5\u8BFB\u53D6\u5FAE\u4FE1\u8D26\u53F7\u72B6\u6001\u6587\u4EF6\u3002": "Could not read the WeChat account state file.",
|
|
968
|
+
"\u65E0\u6CD5\u4FDD\u5B58\u5FAE\u4FE1\u8D26\u53F7\u72B6\u6001\u6587\u4EF6\u3002": "Could not save the WeChat account state file.",
|
|
969
|
+
"\u5FAE\u4FE1\u8D26\u53F7\u5DF2\u79FB\u9664\uFF0C\u4F46\u672C\u673A\u72B6\u6001\u6587\u4EF6\u6E05\u7406\u5931\u8D25\u3002": "The WeChat account was removed, but its local state file could not be cleaned up.",
|
|
970
|
+
"\u65E0\u6CD5\u4FDD\u5B58\u5FAE\u4FE1\u5DE5\u4F5C\u533A\u8BBE\u7F6E\u3002": "Could not save the WeChat workspace settings.",
|
|
971
|
+
"\u5FAE\u4FE1\u8D26\u53F7\u5DF2\u79FB\u9664\uFF0C\u4F46\u5DE5\u4F5C\u533A\u8BBE\u7F6E\u6E05\u7406\u5931\u8D25\u3002": "The WeChat account was removed, but its workspace settings could not be cleaned up.",
|
|
972
|
+
"\u5FAE\u4FE1\u8D26\u53F7\u8FDE\u63A5\u542F\u52A8\u5931\u8D25\u3002": "The WeChat account connection could not start.",
|
|
973
|
+
"\u5FAE\u4FE1\u6D88\u606F\u540C\u6B65\u8BF7\u6C42\u88AB\u62D2\u7EDD\u3002": "WeChat rejected the message sync request.",
|
|
974
|
+
"\u5FAE\u4FE1\u670D\u52A1\u672A\u786E\u8BA4\u505C\u6B62\u901A\u77E5\u3002": "WeChat did not confirm the stop notification.",
|
|
975
|
+
"\u5FAE\u4FE1\u6D88\u606F\u8FDE\u63A5\u505C\u6B62\u65F6\u53D1\u751F\u9519\u8BEF\u3002": "An error occurred while stopping the WeChat connection.",
|
|
976
|
+
"\u65E0\u6CD5\u8BFB\u53D6\u5FAE\u4FE1\u8FDE\u63A5\u72B6\u6001\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\uFF1B\u4E4B\u524D\u7684\u64CD\u4F5C\u53EF\u80FD\u5DF2\u5B8C\u6210\u3002": "Could not read the WeChat connection status. Refresh it; the previous operation may have completed.",
|
|
977
|
+
"\u5FAE\u4FE1\u6FC0\u6D3B\u8FC7\u7A0B\u4E2D\u53D1\u751F\u672A\u77E5\u9519\u8BEF\u3002": "An unknown error occurred while activating the WeChat account.",
|
|
978
|
+
"\u5FAE\u4FE1\u64CD\u4F5C\u53D1\u751F\u672A\u77E5\u9519\u8BEF\u3002": "The WeChat operation failed with an unknown error.",
|
|
979
|
+
"\u5FAE\u4FE1\u914D\u7F6E\u683C\u5F0F\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5 config.json \u548C workspaces.json \u540E\u91CD\u542F DSH\u3002": "The WeChat configuration is invalid. Check config.json and workspaces.json, then restart DSH.",
|
|
980
|
+
"\u5FAE\u4FE1\u914D\u7F6E\u8BBF\u95EE\u6743\u9650\u4E0D\u8DB3\uFF0C\u8BF7\u68C0\u67E5\u6570\u636E\u76EE\u5F55\u6743\u9650\u540E\u91CD\u542F DSH\u3002": "The WeChat configuration could not be accessed. Check the data directory permissions and restart DSH.",
|
|
981
|
+
"\u5FAE\u4FE1\u521D\u59CB\u5316\u5931\u8D25\uFF0C\u8BF7\u67E5\u770B DSH \u542F\u52A8\u65E5\u5FD7\u3002": "WeChat initialization failed. Check the DSH startup logs.",
|
|
982
|
+
"\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA\u3002": "The WeChat connection is not ready.",
|
|
983
|
+
"\u5FAE\u4FE1\u64CD\u4F5C\u5931\u8D25\u540E\uFF0C\u539F\u8D26\u53F7\u72B6\u6001\u6062\u590D\u5931\u8D25\u3002": "The previous account state could not be restored after the failed WeChat operation.",
|
|
984
|
+
"\u539F\u8D26\u53F7\u72B6\u6001\u5C1A\u672A\u786E\u8BA4\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u72B6\u6001\uFF0C\u5E76\u53CD\u9988\u8BCA\u65AD\u4FE1\u606F\u3002": "The previous account state has not been confirmed. Refresh the status and share the diagnostic information.",
|
|
985
|
+
"\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u5DF2\u6062\u590D\u4E4B\u524D\u7684\u672C\u673A\u72B6\u6001\u3002\u8BF7\u5904\u7406\u4E0A\u8FF0\u95EE\u9898\u540E\u91CD\u8BD5\u3002": "The operation did not complete. The previous local state was restored. Resolve the problem above before retrying.",
|
|
986
|
+
"\u51ED\u636E\u7531\u53EA\u8BFB\u6765\u6E90\u63D0\u4F9B\uFF0C\u8BF7\u5728\u542F\u52A8 DSH \u7684\u914D\u7F6E\u4E2D\u68C0\u67E5\u8BE5\u6765\u6E90\u3002": "The credential comes from a read-only source. Check that source in the configuration used to launch DSH.",
|
|
987
|
+
"\u5FAE\u4FE1\u670D\u52A1\u57DF\u540D\u89E3\u6790\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u8FD0\u884C DSH \u7684\u673A\u5668\u7684\u7F51\u7EDC\u548C DNS \u8BBE\u7F6E\u540E\u91CD\u8BD5\u3002": "The WeChat service domain could not be resolved. Check the network and DNS settings on the machine running DSH and retry.",
|
|
988
|
+
"\u8BF7\u68C0\u67E5 DSH \u6570\u636E\u76EE\u5F55\u548C\u5BF9\u5E94\u6587\u4EF6\u7684\u8BFB\u5199\u6743\u9650\u3002": "Check read and write permissions on the DSH data directory and the affected file.",
|
|
989
|
+
"\u78C1\u76D8\u7A7A\u95F4\u4E0D\u8DB3\uFF0C\u8BF7\u91CA\u653E\u7A7A\u95F4\u540E\u91CD\u8BD5\u3002": "The disk is full. Free up space and retry.",
|
|
990
|
+
"\u672C\u673A\u6587\u4EF6\u683C\u5F0F\u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5\u5BF9\u5E94\u914D\u7F6E\u6216\u72B6\u6001\u6587\u4EF6\uFF1B\u4E0D\u8981\u6E05\u7A7A\u767B\u5F55\u51ED\u636E\u3002": "The local file format is invalid. Check the affected configuration or state file; do not clear login credentials.",
|
|
991
|
+
"\u8BF7\u68C0\u67E5\u8FD0\u884C DSH \u7684\u673A\u5668\u7684\u7CFB\u7EDF\u65F6\u95F4\u3001\u8BC1\u4E66\u548C\u7F51\u7EDC\u8BBE\u7F6E\u3002": "Check the system time, certificates and network settings on the machine running DSH.",
|
|
992
|
+
"\u8BF7\u79FB\u9664\u5931\u6548\u63A5\u5165\u5E76\u91CD\u65B0\u626B\u7801\u7ED1\u5B9A\u3002": "Remove the invalid connection and scan a new QR code to connect.",
|
|
993
|
+
"\u8BF7\u786E\u8BA4\u5F53\u524D DSH \u5BBF\u4E3B\u5DF2\u5C31\u7EEA\uFF0C\u5E76\u68C0\u67E5 Harness \u4E0E\u63D2\u4EF6\u5B9E\u9645\u8FD0\u884C\u7248\u672C\u53CA\u5BBF\u4E3B\u65E5\u5FD7\u3002": "Check that this DSH host is ready, and check the running Harness and plugin versions and the host logs.",
|
|
994
|
+
"\u5FAE\u4FE1\u670D\u52A1\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002": "The WeChat service is rate-limiting requests. Try again later.",
|
|
995
|
+
"\u8BBF\u95EE\u88AB\u62D2\u7EDD\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u8BBF\u95EE\u9650\u5236\uFF1BHTTP \u72B6\u6001\u672C\u8EAB\u4E0D\u80FD\u786E\u8BA4\u767B\u5F55\u51ED\u636E\u5DF2\u5931\u6548\u3002": "Access was denied. Check service access restrictions; the HTTP status alone does not establish that the login credential expired.",
|
|
996
|
+
"\u8BF7\u68C0\u67E5\u8FD0\u884C DSH \u7684\u673A\u5668\u80FD\u5426\u8BBF\u95EE\u5FAE\u4FE1\u670D\u52A1\uFF0C\u7136\u540E\u91CD\u8BD5\u3002": "Check whether the machine running DSH can access the WeChat service, then retry.",
|
|
997
|
+
"\u8BF7\u6309\u53C2\u8003\u53F7\u67E5\u770B DSH \u65E5\u5FD7\uFF0C\u5E76\u590D\u5236\u8BCA\u65AD\u4FE1\u606F\u53CD\u9988\u3002": "Find this reference in the DSH logs and copy the diagnostic information when reporting the issue.",
|
|
998
|
+
"\u65E0\u6CD5\u5B8C\u6210\u5FAE\u4FE1\u7BA1\u7406\u8BF7\u6C42\uFF0C\u8BF7\u68C0\u67E5 DSH \u8FDE\u63A5\u540E\u91CD\u65B0\u8BFB\u53D6\u72B6\u6001\u3002": "The WeChat management request could not be completed. Check the DSH connection and refresh the status.",
|
|
999
|
+
"\u67E5\u8BE2\u5FAE\u4FE1\u626B\u7801\u72B6\u6001\u5931\u8D25": "Could not query WeChat QR-code status",
|
|
1000
|
+
"\u65E0\u6CD5\u5B8C\u6210\u5FAE\u4FE1\u7BA1\u7406\u8BF7\u6C42": "Could not complete the WeChat management request",
|
|
1001
|
+
"\u65E0\u6CD5\u751F\u6210\u5FAE\u4FE1\u4E8C\u7EF4\u7801": "Could not generate a WeChat QR code",
|
|
1002
|
+
"\u72B6\u6001\u8BFB\u53D6\u5931\u8D25\uFF0C\u4EE5\u4E0B\u662F\u4E0A\u6B21\u8BFB\u53D6\u7684\u72B6\u6001\u3002": "Status refresh failed. The last known status is shown below.",
|
|
1003
|
+
"\u8BCA\u65AD\u8BE6\u60C5": "Diagnostic details",
|
|
1004
|
+
"\u8BCA\u65AD\u4FE1\u606F": "Diagnostic information",
|
|
1005
|
+
"\u590D\u5236\u8BCA\u65AD\u4FE1\u606F": "Copy diagnostic information",
|
|
1006
|
+
"\u8BCA\u65AD\u4FE1\u606F\u5DF2\u590D\u5236": "Diagnostic information copied",
|
|
1007
|
+
"\u672A\u53D6\u5F97 Host \u8BCA\u65AD\u53C2\u8003\u53F7\u3002": "No diagnostic reference was received from the host.",
|
|
1008
|
+
"\u65E0\u6CD5\u8BBF\u95EE\u526A\u8D34\u677F\uFF0C\u8BF7\u9009\u62E9\u5E76\u590D\u5236\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002": "Clipboard access is unavailable. Select and copy the diagnostic information below.",
|
|
1009
|
+
"\u9519\u8BEF\u7801": "Error code",
|
|
1010
|
+
"\u5931\u8D25\u9636\u6BB5": "Failed step",
|
|
1011
|
+
"\u5E95\u5C42\u539F\u56E0": "Underlying cause",
|
|
1012
|
+
"HTTP \u72B6\u6001": "HTTP status",
|
|
1013
|
+
"\u5FAE\u4FE1\u8FD4\u56DE\u7801": "WeChat return code",
|
|
1014
|
+
"\u53C2\u8003\u53F7": "Reference",
|
|
1015
|
+
"\u53D1\u751F\u65F6\u95F4": "Time",
|
|
1016
|
+
"\u52A0\u8F7D\u5FAE\u4FE1\u914D\u7F6E": "Load WeChat configuration",
|
|
1017
|
+
"\u7533\u8BF7\u4E8C\u7EF4\u7801": "Request QR code",
|
|
1018
|
+
"\u751F\u6210\u4E8C\u7EF4\u7801\u56FE\u7247": "Generate QR-code image",
|
|
1019
|
+
"\u67E5\u8BE2\u626B\u7801\u72B6\u6001": "Query QR-code status",
|
|
1020
|
+
"\u63D0\u4EA4\u914D\u5BF9\u7801": "Submit pairing code",
|
|
1021
|
+
"\u53D6\u6D88\u7ED1\u5B9A": "Cancel setup",
|
|
1022
|
+
"\u8BFB\u53D6\u767B\u5F55\u51ED\u636E": "Read login credential",
|
|
1023
|
+
"\u4FDD\u5B58\u767B\u5F55\u51ED\u636E": "Save login credential",
|
|
1024
|
+
"\u79FB\u9664\u767B\u5F55\u51ED\u636E": "Remove login credential",
|
|
1025
|
+
"\u4FDD\u5B58\u8D26\u53F7\u914D\u7F6E": "Save account configuration",
|
|
1026
|
+
"\u79FB\u9664\u8D26\u53F7\u914D\u7F6E": "Remove account configuration",
|
|
1027
|
+
"\u8BFB\u53D6\u8D26\u53F7\u72B6\u6001": "Read account state",
|
|
1028
|
+
"\u4FDD\u5B58\u8D26\u53F7\u72B6\u6001": "Save account state",
|
|
1029
|
+
"\u6E05\u7406\u8D26\u53F7\u72B6\u6001": "Clean up account state",
|
|
1030
|
+
"\u4FDD\u5B58\u5DE5\u4F5C\u533A\u8BBE\u7F6E": "Save workspace settings",
|
|
1031
|
+
"\u6E05\u7406\u5DE5\u4F5C\u533A\u8BBE\u7F6E": "Clean up workspace settings",
|
|
1032
|
+
"\u51C6\u5907\u6D88\u606F\u8FDE\u63A5": "Prepare message connection",
|
|
1033
|
+
"\u6FC0\u6D3B\u5FAE\u4FE1\u8D26\u53F7": "Activate WeChat account",
|
|
1034
|
+
"\u68C0\u67E5 DSH \u5BBF\u4E3B": "Check DSH host",
|
|
1035
|
+
"\u542F\u52A8\u5FAE\u4FE1\u8FDE\u63A5": "Start WeChat connection",
|
|
1036
|
+
"\u540C\u6B65\u5FAE\u4FE1\u6D88\u606F": "Sync WeChat messages",
|
|
1037
|
+
"\u505C\u6B62\u5FAE\u4FE1\u8FDE\u63A5": "Stop WeChat connection",
|
|
1038
|
+
"\u8BFB\u53D6\u8FDE\u63A5\u72B6\u6001": "Read connection status",
|
|
1039
|
+
"\u6062\u590D\u539F\u8D26\u53F7\u72B6\u6001": "Restore previous account state",
|
|
1040
|
+
"\u8BBF\u95EE DSH \u7BA1\u7406\u63A5\u53E3": "Access DSH management API"
|
|
1041
|
+
};
|
|
1042
|
+
|
|
914
1043
|
// plugin-src/client/i18n.js
|
|
915
1044
|
var React2 = __toESM(require("react"), 1);
|
|
916
1045
|
var IM_LOCALE_NAMESPACE = "dsh-im";
|
|
917
1046
|
var EN = Object.freeze({
|
|
1047
|
+
...connection_error_en_default,
|
|
918
1048
|
"$locale": "en",
|
|
919
1049
|
"\u4FEE\u6539\u522B\u540D": "Edit alias",
|
|
920
1050
|
"\u5173\u95ED\u4FEE\u6539\u522B\u540D": "Close alias editor",
|
|
@@ -11881,9 +12011,111 @@ function WecomAppSettingsTab({ rpcCall }) {
|
|
|
11881
12011
|
)));
|
|
11882
12012
|
}
|
|
11883
12013
|
|
|
11884
|
-
// plugin-src/client/channels/weixin/
|
|
12014
|
+
// plugin-src/client/channels/weixin/connection-error.js
|
|
11885
12015
|
var React22 = __toESM(require("react"), 1);
|
|
11886
12016
|
|
|
12017
|
+
// src/channels/weixin/diagnostic-details.mjs
|
|
12018
|
+
var OPERATIONS = /* @__PURE__ */ new Set([
|
|
12019
|
+
"startup",
|
|
12020
|
+
"connection.restore",
|
|
12021
|
+
"connection.monitor",
|
|
12022
|
+
"connection.close",
|
|
12023
|
+
"connection.status",
|
|
12024
|
+
"provision.begin",
|
|
12025
|
+
"provision.poll",
|
|
12026
|
+
"provision.verify",
|
|
12027
|
+
"provision.cancel",
|
|
12028
|
+
"bot.reconnect",
|
|
12029
|
+
"bot.delete",
|
|
12030
|
+
"bot.workspace.set",
|
|
12031
|
+
"bot.model.set",
|
|
12032
|
+
"bot.agent-preset.set",
|
|
12033
|
+
"bot.context-enhancement.set",
|
|
12034
|
+
"bot.access-policy.set",
|
|
12035
|
+
"bot.alias.set"
|
|
12036
|
+
]);
|
|
12037
|
+
var STAGES = /* @__PURE__ */ new Set([
|
|
12038
|
+
"startup.load",
|
|
12039
|
+
"qr.begin",
|
|
12040
|
+
"qr.encode",
|
|
12041
|
+
"qr.poll",
|
|
12042
|
+
"qr.verify",
|
|
12043
|
+
"qr.cancel",
|
|
12044
|
+
"credential.read",
|
|
12045
|
+
"credential.save",
|
|
12046
|
+
"credential.remove",
|
|
12047
|
+
"account.save",
|
|
12048
|
+
"account.remove",
|
|
12049
|
+
"state.load",
|
|
12050
|
+
"state.write",
|
|
12051
|
+
"state.cleanup",
|
|
12052
|
+
"workspace.write",
|
|
12053
|
+
"workspace.cleanup",
|
|
12054
|
+
"runtime.prepare",
|
|
12055
|
+
"activation",
|
|
12056
|
+
"harness.check",
|
|
12057
|
+
"connection.start",
|
|
12058
|
+
"connection.poll",
|
|
12059
|
+
"connection.stop",
|
|
12060
|
+
"status.read",
|
|
12061
|
+
"rollback",
|
|
12062
|
+
"management.request"
|
|
12063
|
+
]);
|
|
12064
|
+
var REASONS = /* @__PURE__ */ new Set([
|
|
12065
|
+
"ENOTFOUND",
|
|
12066
|
+
"EAI_AGAIN",
|
|
12067
|
+
"ECONNREFUSED",
|
|
12068
|
+
"ECONNRESET",
|
|
12069
|
+
"EHOSTUNREACH",
|
|
12070
|
+
"ENETUNREACH",
|
|
12071
|
+
"ETIMEDOUT",
|
|
12072
|
+
"EPIPE",
|
|
12073
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
12074
|
+
"UND_ERR_HEADERS_TIMEOUT",
|
|
12075
|
+
"UND_ERR_BODY_TIMEOUT",
|
|
12076
|
+
"UND_ERR_SOCKET",
|
|
12077
|
+
"CERT_HAS_EXPIRED",
|
|
12078
|
+
"CERT_NOT_YET_VALID",
|
|
12079
|
+
"DEPTH_ZERO_SELF_SIGNED_CERT",
|
|
12080
|
+
"SELF_SIGNED_CERT_IN_CHAIN",
|
|
12081
|
+
"UNABLE_TO_VERIFY_LEAF_SIGNATURE",
|
|
12082
|
+
"UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
|
|
12083
|
+
"ERR_TLS_CERT_ALTNAME_INVALID",
|
|
12084
|
+
"ERR_SSL_WRONG_VERSION_NUMBER",
|
|
12085
|
+
"ENOENT",
|
|
12086
|
+
"EACCES",
|
|
12087
|
+
"EPERM",
|
|
12088
|
+
"ENOSPC",
|
|
12089
|
+
"EROFS",
|
|
12090
|
+
"ENOTDIR",
|
|
12091
|
+
"EISDIR",
|
|
12092
|
+
"EBUSY",
|
|
12093
|
+
"EIO",
|
|
12094
|
+
"EXDEV",
|
|
12095
|
+
"EMFILE",
|
|
12096
|
+
"ENFILE",
|
|
12097
|
+
"EEXIST",
|
|
12098
|
+
"invalid-json",
|
|
12099
|
+
"read-only"
|
|
12100
|
+
]);
|
|
12101
|
+
var RESOURCES = /* @__PURE__ */ new Set(["credential-store", "account-config", "account-state", "workspace-config", "workspace-directory"]);
|
|
12102
|
+
function normalizeWeixinDiagnosticDetails(value) {
|
|
12103
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
12104
|
+
const result = {};
|
|
12105
|
+
for (const [field, allowed] of [["operation", OPERATIONS], ["stage", STAGES], ["reason", REASONS], ["resource", RESOURCES]]) {
|
|
12106
|
+
if (allowed.has(value[field])) result[field] = value[field];
|
|
12107
|
+
}
|
|
12108
|
+
if (/^WX-CONN-[A-F0-9]{8}$/.test(value.referenceId ?? "")) result.referenceId = value.referenceId;
|
|
12109
|
+
if (typeof value.occurredAt === "string" && /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z$/.test(value.occurredAt) && Number.isFinite(Date.parse(value.occurredAt))) result.occurredAt = value.occurredAt;
|
|
12110
|
+
if (Number.isInteger(value.httpStatus) && value.httpStatus >= 100 && value.httpStatus <= 599) result.httpStatus = value.httpStatus;
|
|
12111
|
+
const provider = typeof value.providerCode === "number" && Number.isSafeInteger(value.providerCode) ? String(value.providerCode) : value.providerCode;
|
|
12112
|
+
if (typeof provider === "string" && /^-?\d{1,12}$/.test(provider)) result.providerCode = provider;
|
|
12113
|
+
if (typeof value.pluginVersion === "string" && /^\d+\.\d+\.\d+(?:-[A-Za-z0-9.-]+)?$/.test(value.pluginVersion) && value.pluginVersion.length <= 64) result.pluginVersion = value.pluginVersion;
|
|
12114
|
+
if (["succeeded", "failed", "not-attempted", "unknown"].includes(value.rollback)) result.rollback = value.rollback;
|
|
12115
|
+
if (typeof value.hint === "string" && value.hint.trim()) result.hint = value.hint.trim().slice(0, 500);
|
|
12116
|
+
return result;
|
|
12117
|
+
}
|
|
12118
|
+
|
|
11887
12119
|
// plugin-src/client/channels/weixin/api.js
|
|
11888
12120
|
var WEIXIN_RPC_CHANNEL = "/weixin";
|
|
11889
12121
|
var WEIXIN_ENDPOINTS = Object.freeze({
|
|
@@ -11929,13 +12161,35 @@ function normalizeTestMessage5(value) {
|
|
|
11929
12161
|
const code = value.code === "test-target-unavailable" ? "test-target-unavailable" : "test-message-failed";
|
|
11930
12162
|
return { sent: false, code };
|
|
11931
12163
|
}
|
|
12164
|
+
function normalizeConnectionError(value, fallbackCode = "WEIXIN_ERROR", fallbackMessage = "\u5FAE\u4FE1\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5") {
|
|
12165
|
+
const details = normalizeWeixinDiagnosticDetails(value?.details);
|
|
12166
|
+
return {
|
|
12167
|
+
code: string(value?.code, fallbackCode).slice(0, 100),
|
|
12168
|
+
message: string(value?.message, fallbackMessage).slice(0, 500),
|
|
12169
|
+
...Object.keys(details).length ? { details } : {}
|
|
12170
|
+
};
|
|
12171
|
+
}
|
|
12172
|
+
function managementRequestError(cause, operation) {
|
|
12173
|
+
if (cause?.name === "AbortError") return cause;
|
|
12174
|
+
const error = new Error("\u65E0\u6CD5\u5B8C\u6210\u5FAE\u4FE1\u7BA1\u7406\u8BF7\u6C42\uFF0C\u8BF7\u68C0\u67E5 DSH \u8FDE\u63A5\u540E\u91CD\u65B0\u8BFB\u53D6\u72B6\u6001\u3002");
|
|
12175
|
+
error.code = "weixin-management-unreachable";
|
|
12176
|
+
error.details = normalizeWeixinDiagnosticDetails({ operation, stage: "management.request", occurredAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
12177
|
+
return error;
|
|
12178
|
+
}
|
|
12179
|
+
function invalidResponse() {
|
|
12180
|
+
const error = new Error("DSH \u5FAE\u4FE1\u7BA1\u7406\u63A5\u53E3\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94\uFF0C\u8BF7\u91CD\u65B0\u8BFB\u53D6\u72B6\u6001\u3002");
|
|
12181
|
+
error.code = "weixin-management-invalid-response";
|
|
12182
|
+
error.details = { stage: "management.request", occurredAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
12183
|
+
return error;
|
|
12184
|
+
}
|
|
11932
12185
|
function unwrapRpcResult9(result) {
|
|
11933
12186
|
if (!isRecord7(result) || typeof result.ok !== "boolean") {
|
|
11934
|
-
throw
|
|
12187
|
+
throw invalidResponse();
|
|
11935
12188
|
}
|
|
11936
12189
|
if (!result.ok) {
|
|
11937
|
-
|
|
11938
|
-
|
|
12190
|
+
if (!isRecord7(result.error)) throw invalidResponse();
|
|
12191
|
+
const visible = normalizeConnectionError(result.error, "WEIXIN_RPC_ERROR", "\u5FAE\u4FE1\u64CD\u4F5C\u5931\u8D25");
|
|
12192
|
+
const error = Object.assign(new Error(visible.message), visible);
|
|
11939
12193
|
throw error;
|
|
11940
12194
|
}
|
|
11941
12195
|
return result.value;
|
|
@@ -11955,7 +12209,7 @@ function safeVerificationUrl(value) {
|
|
|
11955
12209
|
}
|
|
11956
12210
|
function normalizeProvisioning5(value) {
|
|
11957
12211
|
if (!isRecord7(value) || !string(value.attemptId)) {
|
|
11958
|
-
throw
|
|
12212
|
+
throw invalidResponse();
|
|
11959
12213
|
}
|
|
11960
12214
|
const status = PROVISION_STATES4.has(value.status) ? value.status : "failed";
|
|
11961
12215
|
const result = {
|
|
@@ -11972,10 +12226,7 @@ function normalizeProvisioning5(value) {
|
|
|
11972
12226
|
if (string(value.botId)) result.botId = string(value.botId);
|
|
11973
12227
|
if (value.alreadyConnected === true) result.alreadyConnected = true;
|
|
11974
12228
|
if (isRecord7(value.error)) {
|
|
11975
|
-
result.error =
|
|
11976
|
-
code: string(value.error.code, "WEIXIN_PROVISION_FAILED"),
|
|
11977
|
-
message: string(value.error.message, "\u5FAE\u4FE1\u7ED1\u5B9A\u6CA1\u6709\u5B8C\u6210")
|
|
11978
|
-
};
|
|
12229
|
+
result.error = normalizeConnectionError(value.error, "WEIXIN_PROVISION_FAILED", "\u5FAE\u4FE1\u7ED1\u5B9A\u6CA1\u6709\u5B8C\u6210");
|
|
11979
12230
|
}
|
|
11980
12231
|
return result;
|
|
11981
12232
|
}
|
|
@@ -12008,15 +12259,12 @@ function normalizeBot6(value) {
|
|
|
12008
12259
|
messagesReplied: Math.max(0, Number(value.stats?.messagesReplied) || 0)
|
|
12009
12260
|
},
|
|
12010
12261
|
lastMessageError: normalizeLastMessageError(value.lastMessageError),
|
|
12011
|
-
error: isRecord7(value.error) ?
|
|
12012
|
-
code: string(value.error.code, "WEIXIN_ACCOUNT_ERROR"),
|
|
12013
|
-
message: string(value.error.message, "\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA")
|
|
12014
|
-
} : null
|
|
12262
|
+
error: isRecord7(value.error) ? normalizeConnectionError(value.error, "WEIXIN_ACCOUNT_ERROR", "\u5FAE\u4FE1\u8FDE\u63A5\u672A\u5C31\u7EEA") : null
|
|
12015
12263
|
};
|
|
12016
12264
|
}
|
|
12017
12265
|
function normalizeSnapshot8(value) {
|
|
12018
12266
|
if (!isRecord7(value) || !Array.isArray(value.bots)) {
|
|
12019
|
-
throw
|
|
12267
|
+
throw invalidResponse();
|
|
12020
12268
|
}
|
|
12021
12269
|
const bots = value.bots.map(normalizeBot6).filter(Boolean);
|
|
12022
12270
|
return {
|
|
@@ -12030,23 +12278,130 @@ function normalizeSnapshot8(value) {
|
|
|
12030
12278
|
},
|
|
12031
12279
|
provisioning: value.provisioning ? normalizeProvisioning5(value.provisioning) : null,
|
|
12032
12280
|
testMessage: normalizeTestMessage5(value.testMessage),
|
|
12281
|
+
warnings: Array.isArray(value.warnings) ? value.warnings.filter(isRecord7).slice(0, 8).map((error) => normalizeConnectionError(error)) : [],
|
|
12033
12282
|
agentPresetCatalog: normalizeAgentPresetCatalog(value.agentPresetCatalog),
|
|
12034
12283
|
modelCatalog: normalizeModelCatalog(value.modelCatalog)
|
|
12035
12284
|
};
|
|
12036
12285
|
}
|
|
12037
12286
|
function presentError9(error) {
|
|
12038
|
-
return
|
|
12039
|
-
code: string(error?.code, "WEIXIN_ERROR"),
|
|
12040
|
-
message: string(error?.message, "\u5FAE\u4FE1\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5")
|
|
12041
|
-
};
|
|
12287
|
+
return normalizeConnectionError(error);
|
|
12042
12288
|
}
|
|
12043
12289
|
function formatRemaining5(milliseconds) {
|
|
12044
12290
|
const seconds = Math.max(0, Math.ceil(milliseconds / 1e3));
|
|
12045
12291
|
return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, "0")}`;
|
|
12046
12292
|
}
|
|
12047
12293
|
|
|
12294
|
+
// plugin-src/client/channels/weixin/connection-error.js
|
|
12295
|
+
var STAGE_LABELS = {
|
|
12296
|
+
"startup.load": "\u52A0\u8F7D\u5FAE\u4FE1\u914D\u7F6E",
|
|
12297
|
+
"qr.begin": "\u7533\u8BF7\u4E8C\u7EF4\u7801",
|
|
12298
|
+
"qr.encode": "\u751F\u6210\u4E8C\u7EF4\u7801\u56FE\u7247",
|
|
12299
|
+
"qr.poll": "\u67E5\u8BE2\u626B\u7801\u72B6\u6001",
|
|
12300
|
+
"qr.verify": "\u63D0\u4EA4\u914D\u5BF9\u7801",
|
|
12301
|
+
"qr.cancel": "\u53D6\u6D88\u7ED1\u5B9A",
|
|
12302
|
+
"credential.read": "\u8BFB\u53D6\u767B\u5F55\u51ED\u636E",
|
|
12303
|
+
"credential.save": "\u4FDD\u5B58\u767B\u5F55\u51ED\u636E",
|
|
12304
|
+
"credential.remove": "\u79FB\u9664\u767B\u5F55\u51ED\u636E",
|
|
12305
|
+
"account.save": "\u4FDD\u5B58\u8D26\u53F7\u914D\u7F6E",
|
|
12306
|
+
"account.remove": "\u79FB\u9664\u8D26\u53F7\u914D\u7F6E",
|
|
12307
|
+
"state.load": "\u8BFB\u53D6\u8D26\u53F7\u72B6\u6001",
|
|
12308
|
+
"state.write": "\u4FDD\u5B58\u8D26\u53F7\u72B6\u6001",
|
|
12309
|
+
"state.cleanup": "\u6E05\u7406\u8D26\u53F7\u72B6\u6001",
|
|
12310
|
+
"workspace.write": "\u4FDD\u5B58\u5DE5\u4F5C\u533A\u8BBE\u7F6E",
|
|
12311
|
+
"workspace.cleanup": "\u6E05\u7406\u5DE5\u4F5C\u533A\u8BBE\u7F6E",
|
|
12312
|
+
"runtime.prepare": "\u51C6\u5907\u6D88\u606F\u8FDE\u63A5",
|
|
12313
|
+
activation: "\u6FC0\u6D3B\u5FAE\u4FE1\u8D26\u53F7",
|
|
12314
|
+
"harness.check": "\u68C0\u67E5 DSH \u5BBF\u4E3B",
|
|
12315
|
+
"connection.start": "\u542F\u52A8\u5FAE\u4FE1\u8FDE\u63A5",
|
|
12316
|
+
"connection.poll": "\u540C\u6B65\u5FAE\u4FE1\u6D88\u606F",
|
|
12317
|
+
"connection.stop": "\u505C\u6B62\u5FAE\u4FE1\u8FDE\u63A5",
|
|
12318
|
+
"status.read": "\u8BFB\u53D6\u8FDE\u63A5\u72B6\u6001",
|
|
12319
|
+
rollback: "\u6062\u590D\u539F\u8D26\u53F7\u72B6\u6001",
|
|
12320
|
+
"management.request": "\u8BBF\u95EE DSH \u7BA1\u7406\u63A5\u53E3"
|
|
12321
|
+
};
|
|
12322
|
+
function provisioningErrorTitle(error) {
|
|
12323
|
+
const stage = error?.details?.stage;
|
|
12324
|
+
if (stage === "qr.begin" || stage === "qr.encode") return "\u65E0\u6CD5\u751F\u6210\u5FAE\u4FE1\u4E8C\u7EF4\u7801";
|
|
12325
|
+
if (stage === "qr.poll") return "\u67E5\u8BE2\u5FAE\u4FE1\u626B\u7801\u72B6\u6001\u5931\u8D25";
|
|
12326
|
+
if (stage === "management.request") return "\u65E0\u6CD5\u5B8C\u6210\u5FAE\u4FE1\u7BA1\u7406\u8BF7\u6C42";
|
|
12327
|
+
return "\u5FAE\u4FE1\u6CA1\u6709\u7ED1\u5B9A\u5B8C\u6210";
|
|
12328
|
+
}
|
|
12329
|
+
function formatWeixinDiagnostic(value) {
|
|
12330
|
+
const error = normalizeConnectionError(value);
|
|
12331
|
+
const details = error.details ?? {};
|
|
12332
|
+
return [
|
|
12333
|
+
localizeText(error.message),
|
|
12334
|
+
details.hint ? localizeText(details.hint) : null,
|
|
12335
|
+
localizeText("\u9519\u8BEF\u7801") + ": " + error.code,
|
|
12336
|
+
...["operation", "stage", "reason", "httpStatus", "providerCode", "resource", "referenceId", "occurredAt", "rollback", "pluginVersion"].filter((field) => details[field] !== void 0).map((field) => `${field}: ${details[field]}`)
|
|
12337
|
+
].filter(Boolean).join("\n");
|
|
12338
|
+
}
|
|
12339
|
+
function WeixinConnectionError({ error: value, warning = false }) {
|
|
12340
|
+
const error = normalizeConnectionError(value);
|
|
12341
|
+
const details = error.details ?? {};
|
|
12342
|
+
const [copyState, setCopyState] = React22.useState(null);
|
|
12343
|
+
React22.useEffect(() => setCopyState(null), [details.referenceId, error.code, error.message]);
|
|
12344
|
+
const copy = async () => {
|
|
12345
|
+
try {
|
|
12346
|
+
if (typeof globalThis.navigator?.clipboard?.writeText !== "function") throw new Error("clipboard unavailable");
|
|
12347
|
+
await globalThis.navigator.clipboard.writeText(formatWeixinDiagnostic(error));
|
|
12348
|
+
setCopyState("copied");
|
|
12349
|
+
} catch {
|
|
12350
|
+
setCopyState("manual");
|
|
12351
|
+
}
|
|
12352
|
+
};
|
|
12353
|
+
const fields = [
|
|
12354
|
+
["\u9519\u8BEF\u7801", error.code],
|
|
12355
|
+
["\u5931\u8D25\u9636\u6BB5", localizeText(STAGE_LABELS[details.stage] ?? details.stage ?? "")],
|
|
12356
|
+
["\u5E95\u5C42\u539F\u56E0", details.reason],
|
|
12357
|
+
["HTTP \u72B6\u6001", details.httpStatus],
|
|
12358
|
+
["\u5FAE\u4FE1\u8FD4\u56DE\u7801", details.providerCode],
|
|
12359
|
+
["\u53C2\u8003\u53F7", details.referenceId],
|
|
12360
|
+
["\u53D1\u751F\u65F6\u95F4", details.occurredAt],
|
|
12361
|
+
["\u63D2\u4EF6\u7248\u672C", details.pluginVersion]
|
|
12362
|
+
].filter(([, text7]) => text7 !== void 0 && text7 !== "");
|
|
12363
|
+
return h2(
|
|
12364
|
+
"div",
|
|
12365
|
+
{ className: "dxw-summary dim-cardSummary", "data-weixin-diagnostic": true, role: warning ? "status" : void 0 },
|
|
12366
|
+
h2("p", null, error.message),
|
|
12367
|
+
details.hint ? h2("p", null, details.hint) : null,
|
|
12368
|
+
h2(
|
|
12369
|
+
"details",
|
|
12370
|
+
{ style: { marginTop: 8 } },
|
|
12371
|
+
h2("summary", { style: { cursor: "pointer" } }, "\u8BCA\u65AD\u8BE6\u60C5"),
|
|
12372
|
+
h2(
|
|
12373
|
+
"dl",
|
|
12374
|
+
{ style: { display: "grid", gridTemplateColumns: "auto minmax(0, 1fr)", gap: "4px 12px", margin: "10px 0" } },
|
|
12375
|
+
...fields.flatMap(([label, text7]) => [
|
|
12376
|
+
h2("dt", { key: `${label}-label` }, label),
|
|
12377
|
+
React22.createElement("dd", { key: label, style: { margin: 0, overflowWrap: "anywhere" } }, String(text7))
|
|
12378
|
+
])
|
|
12379
|
+
),
|
|
12380
|
+
!details.referenceId ? h2("p", null, "\u672A\u53D6\u5F97 Host \u8BCA\u65AD\u53C2\u8003\u53F7\u3002") : null,
|
|
12381
|
+
h2(
|
|
12382
|
+
"div",
|
|
12383
|
+
{ className: "dim-viewActions" },
|
|
12384
|
+
h2("button", { type: "button", className: "dxw-button", onClick: copy }, copyState === "copied" ? "\u8BCA\u65AD\u4FE1\u606F\u5DF2\u590D\u5236" : "\u590D\u5236\u8BCA\u65AD\u4FE1\u606F")
|
|
12385
|
+
),
|
|
12386
|
+
copyState === "manual" ? h2(
|
|
12387
|
+
"div",
|
|
12388
|
+
null,
|
|
12389
|
+
h2("p", null, "\u65E0\u6CD5\u8BBF\u95EE\u526A\u8D34\u677F\uFF0C\u8BF7\u9009\u62E9\u5E76\u590D\u5236\u4EE5\u4E0B\u8BCA\u65AD\u4FE1\u606F\u3002"),
|
|
12390
|
+
React22.createElement("textarea", {
|
|
12391
|
+
readOnly: true,
|
|
12392
|
+
value: formatWeixinDiagnostic(error),
|
|
12393
|
+
rows: 7,
|
|
12394
|
+
"aria-label": localizeText("\u8BCA\u65AD\u4FE1\u606F"),
|
|
12395
|
+
style: { width: "100%", boxSizing: "border-box", marginTop: 8 }
|
|
12396
|
+
})
|
|
12397
|
+
) : null
|
|
12398
|
+
)
|
|
12399
|
+
);
|
|
12400
|
+
}
|
|
12401
|
+
|
|
12048
12402
|
// plugin-src/client/channels/weixin/index.js
|
|
12049
|
-
var
|
|
12403
|
+
var React23 = __toESM(require("react"), 1);
|
|
12404
|
+
var Button14 = React23.forwardRef(function Button15({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
12050
12405
|
return h2("button", {
|
|
12051
12406
|
...props,
|
|
12052
12407
|
ref,
|
|
@@ -12119,14 +12474,14 @@ function EmptyView6({ onStart, busy }) {
|
|
|
12119
12474
|
);
|
|
12120
12475
|
}
|
|
12121
12476
|
function QrPanel4({ provision, now, busy, onRefresh, onCancel }) {
|
|
12122
|
-
const [imageFailed, setImageFailed] =
|
|
12477
|
+
const [imageFailed, setImageFailed] = React23.useState(false);
|
|
12123
12478
|
const source = safeQrSource5(provision.qrCodeDataUrl);
|
|
12124
12479
|
const href = safeVerificationUrl(provision.verificationUrl);
|
|
12125
12480
|
const remaining = Math.max(0, provision.expiresAt - now);
|
|
12126
12481
|
const expired = remaining === 0 || provision.status === "expired";
|
|
12127
12482
|
const duration = Math.max(1, provision.durationMs ?? 5 * 6e4);
|
|
12128
12483
|
const progress = Math.round(Math.min(1, remaining / duration) * 100);
|
|
12129
|
-
|
|
12484
|
+
React23.useEffect(() => setImageFailed(false), [source]);
|
|
12130
12485
|
return h2(
|
|
12131
12486
|
"div",
|
|
12132
12487
|
{ className: "dxw-card dim-surfaceCard" },
|
|
@@ -12193,9 +12548,9 @@ function QrPanel4({ provision, now, busy, onRefresh, onCancel }) {
|
|
|
12193
12548
|
);
|
|
12194
12549
|
}
|
|
12195
12550
|
function VerificationPanel({ provision, busy, onSubmit, onCancel }) {
|
|
12196
|
-
const [code, setCode] =
|
|
12551
|
+
const [code, setCode] = React23.useState("");
|
|
12197
12552
|
const valid = /^\d{4,8}$/.test(code);
|
|
12198
|
-
|
|
12553
|
+
React23.useEffect(() => setCode(""), [provision.attemptId]);
|
|
12199
12554
|
return h2(
|
|
12200
12555
|
"div",
|
|
12201
12556
|
{ className: "dxw-card dim-surfaceCard" },
|
|
@@ -12262,9 +12617,8 @@ function ProvisionError3({ provision, busy, onRetry, onClose }) {
|
|
|
12262
12617
|
h2(
|
|
12263
12618
|
"div",
|
|
12264
12619
|
{ className: "dxw-error dim-inlineError", role: "alert" },
|
|
12265
|
-
h2("h3", null, provision.status === "expired" ? "\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F" :
|
|
12266
|
-
h2(
|
|
12267
|
-
h2("span", { className: "dxw-errorCode" }, error.code),
|
|
12620
|
+
h2("h3", null, provision.status === "expired" ? "\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F" : provisioningErrorTitle(error)),
|
|
12621
|
+
h2(WeixinConnectionError, { error }),
|
|
12268
12622
|
h2(
|
|
12269
12623
|
"div",
|
|
12270
12624
|
{ className: "dxw-actions dim-viewActions" },
|
|
@@ -12390,7 +12744,7 @@ function AccountCard5({
|
|
|
12390
12744
|
),
|
|
12391
12745
|
h2(Button14, { className: "dim-cardAction", kind: "danger", onClick: onRequestRemove, disabled: Boolean(busy) }, "\u79FB\u9664\u63A5\u5165")
|
|
12392
12746
|
),
|
|
12393
|
-
summary2 ? h2("div", { className: "dxw-summary dim-cardSummary" }, summary2) : null,
|
|
12747
|
+
account.error ? h2(WeixinConnectionError, { error: account.error }) : summary2 ? h2("div", { className: "dxw-summary dim-cardSummary" }, summary2) : null,
|
|
12394
12748
|
account.lastMessageError ? h2(LastMessageErrorSummary, {
|
|
12395
12749
|
className: "dxw-summary",
|
|
12396
12750
|
error: account.lastMessageError
|
|
@@ -12399,7 +12753,7 @@ function AccountCard5({
|
|
|
12399
12753
|
className: "dxw-summary dim-cardFeedback",
|
|
12400
12754
|
role: "status",
|
|
12401
12755
|
"aria-live": "polite"
|
|
12402
|
-
}, feedback) : null
|
|
12756
|
+
}, typeof feedback === "string" ? feedback : h2(WeixinConnectionError, { error: feedback })) : null
|
|
12403
12757
|
)
|
|
12404
12758
|
)
|
|
12405
12759
|
)
|
|
@@ -12463,7 +12817,7 @@ function mergeWeixinProvisioningSnapshot(current, incoming, { restoreProvisionin
|
|
|
12463
12817
|
};
|
|
12464
12818
|
}
|
|
12465
12819
|
function WeixinSettingsTab({ rpcCall }) {
|
|
12466
|
-
const [model, setModel] =
|
|
12820
|
+
const [model, setModel] = React23.useState({
|
|
12467
12821
|
phase: "loading",
|
|
12468
12822
|
bots: [],
|
|
12469
12823
|
totals: EMPTY_TOTALS3,
|
|
@@ -12472,33 +12826,41 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12472
12826
|
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
12473
12827
|
modelCatalog: EMPTY_MODEL_CATALOG
|
|
12474
12828
|
});
|
|
12475
|
-
const [provision, setProvision] =
|
|
12476
|
-
const [busy, setBusy] =
|
|
12477
|
-
const [busyByBot, setBusyByBot] =
|
|
12478
|
-
const [feedbackByBot, setFeedbackByBot] =
|
|
12479
|
-
const [removeTarget, setRemoveTarget] =
|
|
12480
|
-
const [notice, setNotice] =
|
|
12481
|
-
const [
|
|
12482
|
-
const
|
|
12483
|
-
const
|
|
12829
|
+
const [provision, setProvision] = React23.useState(null);
|
|
12830
|
+
const [busy, setBusy] = React23.useState(false);
|
|
12831
|
+
const [busyByBot, setBusyByBot] = React23.useState({});
|
|
12832
|
+
const [feedbackByBot, setFeedbackByBot] = React23.useState({});
|
|
12833
|
+
const [removeTarget, setRemoveTarget] = React23.useState(null);
|
|
12834
|
+
const [notice, setNotice] = React23.useState("");
|
|
12835
|
+
const [operationWarnings, setOperationWarnings] = React23.useState([]);
|
|
12836
|
+
const [now, setNow] = React23.useState(() => Date.now());
|
|
12837
|
+
const addButtonRef = React23.useRef(null);
|
|
12838
|
+
const mountedRef = React23.useRef(true);
|
|
12484
12839
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
12485
12840
|
const scheduleAnimationFrame = useAnimationFrameScheduler();
|
|
12486
|
-
|
|
12841
|
+
React23.useEffect(() => {
|
|
12487
12842
|
mountedRef.current = true;
|
|
12488
12843
|
return () => {
|
|
12489
12844
|
mountedRef.current = false;
|
|
12490
12845
|
};
|
|
12491
12846
|
}, []);
|
|
12492
|
-
const announce =
|
|
12847
|
+
const announce = React23.useCallback((value) => {
|
|
12493
12848
|
setNotice("");
|
|
12494
12849
|
scheduleAnimationFrame(() => {
|
|
12495
12850
|
if (value) setNotice(value);
|
|
12496
12851
|
}, "announcement");
|
|
12497
12852
|
}, [scheduleAnimationFrame]);
|
|
12498
|
-
const invoke =
|
|
12499
|
-
|
|
12853
|
+
const invoke = React23.useCallback(async (endpoint, payload = {}, signal) => {
|
|
12854
|
+
let result;
|
|
12855
|
+
try {
|
|
12856
|
+
result = await rpcCall(endpoint, payload, signal);
|
|
12857
|
+
} catch (error) {
|
|
12858
|
+
if (signal?.aborted) throw error;
|
|
12859
|
+
throw managementRequestError(error, endpoint);
|
|
12860
|
+
}
|
|
12861
|
+
return unwrapRpcResult9(result);
|
|
12500
12862
|
}, [rpcCall]);
|
|
12501
|
-
const loadStatus =
|
|
12863
|
+
const loadStatus = React23.useCallback(async ({
|
|
12502
12864
|
signal,
|
|
12503
12865
|
silent = false,
|
|
12504
12866
|
restoreProvisioning = false
|
|
@@ -12536,12 +12898,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12536
12898
|
return void 0;
|
|
12537
12899
|
}
|
|
12538
12900
|
}, [invoke, workspaceFence]);
|
|
12539
|
-
|
|
12901
|
+
React23.useEffect(() => {
|
|
12540
12902
|
const controller = new AbortController();
|
|
12541
12903
|
void loadStatus({ signal: controller.signal, restoreProvisioning: true });
|
|
12542
12904
|
return () => controller.abort();
|
|
12543
12905
|
}, [loadStatus]);
|
|
12544
|
-
|
|
12906
|
+
React23.useEffect(() => {
|
|
12545
12907
|
if (model.phase !== "ready") return void 0;
|
|
12546
12908
|
const controller = new AbortController();
|
|
12547
12909
|
let running = false;
|
|
@@ -12560,12 +12922,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12560
12922
|
window.clearInterval(timer);
|
|
12561
12923
|
};
|
|
12562
12924
|
}, [loadStatus, model.phase]);
|
|
12563
|
-
|
|
12925
|
+
React23.useEffect(() => {
|
|
12564
12926
|
if (!provision || !["pending", "scanned"].includes(provision.status)) return void 0;
|
|
12565
12927
|
const timer = window.setInterval(() => setNow(Date.now()), 1e3);
|
|
12566
12928
|
return () => window.clearInterval(timer);
|
|
12567
12929
|
}, [provision?.attemptId, provision?.status]);
|
|
12568
|
-
const startProvisioning =
|
|
12930
|
+
const startProvisioning = React23.useCallback(async ({ replace = false } = {}) => {
|
|
12569
12931
|
setBusy(true);
|
|
12570
12932
|
try {
|
|
12571
12933
|
if (replace && provision?.attemptId) {
|
|
@@ -12586,7 +12948,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12586
12948
|
setBusy(false);
|
|
12587
12949
|
}
|
|
12588
12950
|
}, [announce, invoke, provision?.attemptId]);
|
|
12589
|
-
const cancelProvisioning =
|
|
12951
|
+
const cancelProvisioning = React23.useCallback(async () => {
|
|
12590
12952
|
setBusy(true);
|
|
12591
12953
|
try {
|
|
12592
12954
|
if (provision?.attemptId && !["failed", "expired", "cancelled"].includes(provision.status)) {
|
|
@@ -12601,7 +12963,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12601
12963
|
setBusy(false);
|
|
12602
12964
|
}
|
|
12603
12965
|
}, [announce, invoke, provision?.attemptId, provision?.status, scheduleAnimationFrame]);
|
|
12604
|
-
const submitVerification =
|
|
12966
|
+
const submitVerification = React23.useCallback(async (verifyCode) => {
|
|
12605
12967
|
if (!provision?.attemptId) return;
|
|
12606
12968
|
setBusy(true);
|
|
12607
12969
|
try {
|
|
@@ -12617,7 +12979,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12617
12979
|
setBusy(false);
|
|
12618
12980
|
}
|
|
12619
12981
|
}, [announce, invoke, provision?.attemptId]);
|
|
12620
|
-
|
|
12982
|
+
React23.useEffect(() => {
|
|
12621
12983
|
const attemptId = provision?.attemptId;
|
|
12622
12984
|
if (!attemptId || !["pending", "scanned", "connecting"].includes(provision.status)) return void 0;
|
|
12623
12985
|
const controller = new AbortController();
|
|
@@ -12665,7 +13027,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12665
13027
|
controller.abort();
|
|
12666
13028
|
};
|
|
12667
13029
|
}, [announce, invoke, loadStatus, provision?.attemptId, provision?.status, provision?.pollIntervalMs]);
|
|
12668
|
-
const setBotBusy =
|
|
13030
|
+
const setBotBusy = React23.useCallback((botId, value) => {
|
|
12669
13031
|
setBusyByBot((current) => {
|
|
12670
13032
|
const next = { ...current };
|
|
12671
13033
|
if (value) next[botId] = value;
|
|
@@ -12673,7 +13035,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12673
13035
|
return next;
|
|
12674
13036
|
});
|
|
12675
13037
|
}, []);
|
|
12676
|
-
const reconnect =
|
|
13038
|
+
const reconnect = React23.useCallback(async (account) => {
|
|
12677
13039
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
12678
13040
|
setBotBusy(account.botId, "reconnect");
|
|
12679
13041
|
setFeedbackByBot((current) => {
|
|
@@ -12713,21 +13075,22 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12713
13075
|
setFeedbackByBot((current) => ({ ...current, [account.botId]: feedback }));
|
|
12714
13076
|
}
|
|
12715
13077
|
announce(feedback);
|
|
12716
|
-
} catch {
|
|
12717
|
-
const feedback =
|
|
13078
|
+
} catch (error) {
|
|
13079
|
+
const feedback = presentError9(error);
|
|
12718
13080
|
if (mountedRef.current) {
|
|
12719
13081
|
setFeedbackByBot((current) => ({ ...current, [account.botId]: feedback }));
|
|
12720
13082
|
}
|
|
12721
|
-
announce(feedback);
|
|
13083
|
+
announce(feedback.message);
|
|
12722
13084
|
} finally {
|
|
12723
13085
|
const shouldRefresh = workspaceFence.endMutation();
|
|
12724
13086
|
if (shouldRefresh && mountedRef.current) void loadStatus({ silent: true });
|
|
12725
13087
|
setBotBusy(account.botId, null);
|
|
12726
13088
|
}
|
|
12727
13089
|
}, [announce, invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
12728
|
-
const saveWorkspace =
|
|
13090
|
+
const saveWorkspace = React23.useCallback(async (account, workspace) => {
|
|
12729
13091
|
const workspaceVersion = workspaceFence.beginMutation();
|
|
12730
13092
|
setBotBusy(account.botId, "workspace");
|
|
13093
|
+
setFeedbackByBot((current) => ({ ...current, [account.botId]: null }));
|
|
12731
13094
|
try {
|
|
12732
13095
|
const snapshot = normalizeSnapshot8(await invoke(
|
|
12733
13096
|
WEIXIN_ENDPOINTS.setWorkspace,
|
|
@@ -12744,15 +13107,19 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12744
13107
|
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
12745
13108
|
});
|
|
12746
13109
|
}
|
|
13110
|
+
} catch (error) {
|
|
13111
|
+
if (mountedRef.current) setFeedbackByBot((current) => ({ ...current, [account.botId]: presentError9(error) }));
|
|
13112
|
+
throw error;
|
|
12747
13113
|
} finally {
|
|
12748
13114
|
const shouldRefresh = workspaceFence.endMutation();
|
|
12749
13115
|
if (shouldRefresh && mountedRef.current) void loadStatus({ silent: true });
|
|
12750
13116
|
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
12751
13117
|
}
|
|
12752
13118
|
}, [invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
12753
|
-
const saveBotSetting =
|
|
13119
|
+
const saveBotSetting = React23.useCallback(async (account, operation, endpoint, payload) => {
|
|
12754
13120
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
12755
13121
|
setBotBusy(account.botId, operation);
|
|
13122
|
+
setFeedbackByBot((current) => ({ ...current, [account.botId]: null }));
|
|
12756
13123
|
try {
|
|
12757
13124
|
const snapshot = normalizeSnapshot8(await invoke(
|
|
12758
13125
|
endpoint,
|
|
@@ -12769,15 +13136,20 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12769
13136
|
modelCatalog: snapshot.modelCatalog ?? EMPTY_MODEL_CATALOG
|
|
12770
13137
|
});
|
|
12771
13138
|
}
|
|
13139
|
+
} catch (error) {
|
|
13140
|
+
if (mountedRef.current) setFeedbackByBot((current) => ({ ...current, [account.botId]: presentError9(error) }));
|
|
13141
|
+
throw error;
|
|
12772
13142
|
} finally {
|
|
12773
13143
|
const shouldRefresh = workspaceFence.endMutation();
|
|
12774
13144
|
if (shouldRefresh && mountedRef.current) void loadStatus({ silent: true });
|
|
12775
13145
|
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
12776
13146
|
}
|
|
12777
13147
|
}, [invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
12778
|
-
const remove =
|
|
13148
|
+
const remove = React23.useCallback(async (account) => {
|
|
12779
13149
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
12780
13150
|
setBotBusy(account.botId, "delete");
|
|
13151
|
+
setOperationWarnings([]);
|
|
13152
|
+
setFeedbackByBot((current) => ({ ...current, [account.botId]: null }));
|
|
12781
13153
|
try {
|
|
12782
13154
|
const snapshot = normalizeSnapshot8(await invoke(WEIXIN_ENDPOINTS.deleteBot, {
|
|
12783
13155
|
botId: account.botId,
|
|
@@ -12793,10 +13165,13 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12793
13165
|
modelCatalog: snapshot.modelCatalog ?? current.modelCatalog
|
|
12794
13166
|
}));
|
|
12795
13167
|
}
|
|
13168
|
+
setOperationWarnings(snapshot.warnings);
|
|
12796
13169
|
setRemoveTarget(null);
|
|
12797
13170
|
announce("\u5FAE\u4FE1\u8D26\u53F7\u53CA\u672C\u673A\u51ED\u636E\u5DF2\u79FB\u9664\u3002");
|
|
12798
13171
|
} catch (error) {
|
|
12799
|
-
|
|
13172
|
+
const failure = presentError9(error);
|
|
13173
|
+
if (mountedRef.current) setFeedbackByBot((current) => ({ ...current, [account.botId]: failure }));
|
|
13174
|
+
announce(failure.message);
|
|
12800
13175
|
} finally {
|
|
12801
13176
|
const shouldRefresh = workspaceFence.endMutation();
|
|
12802
13177
|
if (shouldRefresh && mountedRef.current) void loadStatus({ silent: true });
|
|
@@ -12850,7 +13225,13 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12850
13225
|
addButtonRef
|
|
12851
13226
|
}),
|
|
12852
13227
|
h2("div", { className: "dxw-visuallyHidden", role: "status", "aria-live": "polite" }, notice),
|
|
12853
|
-
|
|
13228
|
+
...operationWarnings.map((error, index) => h2(WeixinConnectionError, { key: error.details?.referenceId ?? index, error, warning: true })),
|
|
13229
|
+
model.error && model.phase === "ready" ? h2(
|
|
13230
|
+
"div",
|
|
13231
|
+
{ className: "dxw-statusNotice dim-statusNotice" },
|
|
13232
|
+
h2("p", null, "\u72B6\u6001\u8BFB\u53D6\u5931\u8D25\uFF0C\u4EE5\u4E0B\u662F\u4E0A\u6B21\u8BFB\u53D6\u7684\u72B6\u6001\u3002"),
|
|
13233
|
+
h2(WeixinConnectionError, { error: model.error })
|
|
13234
|
+
) : null,
|
|
12854
13235
|
model.phase === "loading" ? h2(LoadingView6) : model.phase === "error" ? h2(
|
|
12855
13236
|
"div",
|
|
12856
13237
|
{ className: "dxw-card dim-surfaceCard" },
|
|
@@ -12858,11 +13239,11 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
12858
13239
|
"div",
|
|
12859
13240
|
{ className: "dxw-error dim-inlineError" },
|
|
12860
13241
|
h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6\u5FAE\u4FE1\u72B6\u6001"),
|
|
12861
|
-
h2(
|
|
13242
|
+
h2(WeixinConnectionError, { error: model.error }),
|
|
12862
13243
|
h2(Button14, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
12863
13244
|
)
|
|
12864
13245
|
) : h2(
|
|
12865
|
-
|
|
13246
|
+
React23.Fragment,
|
|
12866
13247
|
null,
|
|
12867
13248
|
provisionView,
|
|
12868
13249
|
model.bots.length === 0 && !provision ? h2(EmptyView6, { onStart: () => void startProvisioning(), busy }) : null,
|
|
@@ -13148,7 +13529,7 @@ function formatRemaining6(milliseconds) {
|
|
|
13148
13529
|
}
|
|
13149
13530
|
|
|
13150
13531
|
// plugin-src/client/channels/whatsapp/index.js
|
|
13151
|
-
var
|
|
13532
|
+
var React24 = __toESM(require("react"), 1);
|
|
13152
13533
|
|
|
13153
13534
|
// plugin-src/client/channels/whatsapp/styles.js
|
|
13154
13535
|
var WHATSAPP_STYLE_ID = "xmanrui-dsh-im-whatsapp-settings";
|
|
@@ -13173,7 +13554,7 @@ function installWhatsappStyles() {
|
|
|
13173
13554
|
|
|
13174
13555
|
// plugin-src/client/channels/whatsapp/index.js
|
|
13175
13556
|
var ACTIVE_STATES3 = /* @__PURE__ */ new Set(["pending", "connecting"]);
|
|
13176
|
-
var Button16 =
|
|
13557
|
+
var Button16 = React24.forwardRef(function Button17({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
13177
13558
|
return h2("button", {
|
|
13178
13559
|
...props,
|
|
13179
13560
|
ref,
|
|
@@ -13527,7 +13908,7 @@ function WhatsappAccountCard({
|
|
|
13527
13908
|
);
|
|
13528
13909
|
}
|
|
13529
13910
|
function WhatsappSettingsTab({ rpcCall }) {
|
|
13530
|
-
const [model, setModel] =
|
|
13911
|
+
const [model, setModel] = React24.useState({
|
|
13531
13912
|
phase: "loading",
|
|
13532
13913
|
bots: [],
|
|
13533
13914
|
totals: { configured: 0, connected: 0 },
|
|
@@ -13535,16 +13916,16 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
13535
13916
|
agentPresetCatalog: EMPTY_AGENT_PRESET_CATALOG,
|
|
13536
13917
|
modelCatalog: EMPTY_MODEL_CATALOG
|
|
13537
13918
|
});
|
|
13538
|
-
const [provision, setProvision] =
|
|
13539
|
-
const [busy, setBusy] =
|
|
13540
|
-
const [busyByBot, setBusyByBot] =
|
|
13541
|
-
const [testNoticeByBot, setTestNoticeByBot] =
|
|
13542
|
-
const [removeTarget, setRemoveTarget] =
|
|
13543
|
-
const [now, setNow] =
|
|
13544
|
-
const mounted =
|
|
13919
|
+
const [provision, setProvision] = React24.useState(null);
|
|
13920
|
+
const [busy, setBusy] = React24.useState(false);
|
|
13921
|
+
const [busyByBot, setBusyByBot] = React24.useState({});
|
|
13922
|
+
const [testNoticeByBot, setTestNoticeByBot] = React24.useState({});
|
|
13923
|
+
const [removeTarget, setRemoveTarget] = React24.useState(null);
|
|
13924
|
+
const [now, setNow] = React24.useState(Date.now());
|
|
13925
|
+
const mounted = React24.useRef(true);
|
|
13545
13926
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
13546
|
-
const addButtonRef =
|
|
13547
|
-
|
|
13927
|
+
const addButtonRef = React24.useRef(null);
|
|
13928
|
+
React24.useEffect(() => {
|
|
13548
13929
|
const disposeDingtalk = installDingtalkStyles();
|
|
13549
13930
|
const disposeWhatsapp = installWhatsappStyles();
|
|
13550
13931
|
mounted.current = true;
|
|
@@ -13554,11 +13935,11 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
13554
13935
|
disposeDingtalk();
|
|
13555
13936
|
};
|
|
13556
13937
|
}, []);
|
|
13557
|
-
const invoke =
|
|
13938
|
+
const invoke = React24.useCallback(async (endpoint, payload = {}, signal) => {
|
|
13558
13939
|
if (typeof rpcCall !== "function") throw new TypeError("WhatsApp \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
13559
13940
|
return unwrapRpcResult10(await rpcCall(endpoint, payload, signal));
|
|
13560
13941
|
}, [rpcCall]);
|
|
13561
|
-
const loadStatus =
|
|
13942
|
+
const loadStatus = React24.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
|
13562
13943
|
const workspaceVersion = workspaceFence.beginStatus();
|
|
13563
13944
|
if (workspaceVersion === null) return void 0;
|
|
13564
13945
|
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
|
@@ -13589,12 +13970,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
13589
13970
|
return void 0;
|
|
13590
13971
|
}
|
|
13591
13972
|
}, [invoke, workspaceFence]);
|
|
13592
|
-
|
|
13973
|
+
React24.useEffect(() => {
|
|
13593
13974
|
const controller = new AbortController();
|
|
13594
13975
|
void loadStatus({ signal: controller.signal, restore: true });
|
|
13595
13976
|
return () => controller.abort();
|
|
13596
13977
|
}, [loadStatus]);
|
|
13597
|
-
|
|
13978
|
+
React24.useEffect(() => {
|
|
13598
13979
|
if (model.phase !== "ready") return void 0;
|
|
13599
13980
|
const controller = new AbortController();
|
|
13600
13981
|
const timer = window.setInterval(
|
|
@@ -13606,12 +13987,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
13606
13987
|
window.clearInterval(timer);
|
|
13607
13988
|
};
|
|
13608
13989
|
}, [loadStatus, model.phase]);
|
|
13609
|
-
|
|
13990
|
+
React24.useEffect(() => {
|
|
13610
13991
|
if (!provision || !ACTIVE_STATES3.has(provision.status)) return void 0;
|
|
13611
13992
|
const timer = window.setInterval(() => mounted.current && setNow(Date.now()), 1e3);
|
|
13612
13993
|
return () => window.clearInterval(timer);
|
|
13613
13994
|
}, [provision?.attemptId, provision?.status]);
|
|
13614
|
-
const startProvisioning =
|
|
13995
|
+
const startProvisioning = React24.useCallback(async (replace = false) => {
|
|
13615
13996
|
setBusy(true);
|
|
13616
13997
|
try {
|
|
13617
13998
|
if (replace && provision?.attemptId) {
|
|
@@ -13629,7 +14010,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
13629
14010
|
if (mounted.current) setBusy(false);
|
|
13630
14011
|
}
|
|
13631
14012
|
}, [invoke, provision?.attemptId]);
|
|
13632
|
-
const closeProvision =
|
|
14013
|
+
const closeProvision = React24.useCallback(async () => {
|
|
13633
14014
|
setBusy(true);
|
|
13634
14015
|
try {
|
|
13635
14016
|
if (provision?.attemptId && ACTIVE_STATES3.has(provision.status)) {
|
|
@@ -13640,7 +14021,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
13640
14021
|
if (mounted.current) setBusy(false);
|
|
13641
14022
|
}
|
|
13642
14023
|
}, [invoke, provision?.attemptId, provision?.status]);
|
|
13643
|
-
|
|
14024
|
+
React24.useEffect(() => {
|
|
13644
14025
|
const attemptId = provision?.attemptId;
|
|
13645
14026
|
if (!attemptId || !ACTIVE_STATES3.has(provision.status)) return void 0;
|
|
13646
14027
|
const controller = new AbortController();
|
|
@@ -13681,7 +14062,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
13681
14062
|
if (timer) window.clearTimeout(timer);
|
|
13682
14063
|
};
|
|
13683
14064
|
}, [invoke, loadStatus, provision?.attemptId, provision?.status]);
|
|
13684
|
-
const botAction =
|
|
14065
|
+
const botAction = React24.useCallback(async (account, operation, endpoint, payload) => {
|
|
13685
14066
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
13686
14067
|
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
|
13687
14068
|
if (operation === "reconnect") {
|
|
@@ -13815,7 +14196,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
13815
14196
|
h2(Button16, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
13816
14197
|
)
|
|
13817
14198
|
) : h2(
|
|
13818
|
-
|
|
14199
|
+
React24.Fragment,
|
|
13819
14200
|
null,
|
|
13820
14201
|
provision?.status === "pending" ? h2(QrPanel5, {
|
|
13821
14202
|
provision,
|
|
@@ -13846,7 +14227,7 @@ var normalizeSnapshot10 = api4.normalizeSnapshot;
|
|
|
13846
14227
|
var presentError11 = api4.presentError;
|
|
13847
14228
|
|
|
13848
14229
|
// plugin-src/client/channels/imessage/index.js
|
|
13849
|
-
var
|
|
14230
|
+
var React25 = __toESM(require("react"), 1);
|
|
13850
14231
|
|
|
13851
14232
|
// plugin-src/client/channels/imessage/styles.js
|
|
13852
14233
|
var IMESSAGE_STYLE_ID = "xmanrui-dsh-im-imessage-settings";
|
|
@@ -13938,11 +14319,73 @@ var channel4 = createTokenChannelSettings({
|
|
|
13938
14319
|
var IMessageSettingsTab = channel4.SettingsTab;
|
|
13939
14320
|
var IMessageAccountCard = channel4.AccountCard;
|
|
13940
14321
|
|
|
14322
|
+
// src/channels/shared/interface-language.mjs
|
|
14323
|
+
var LANGUAGE_TAG = /^[A-Za-z]{2,8}(?:-[A-Za-z0-9]{1,8})*$/u;
|
|
14324
|
+
var HOST_LANGUAGE_SOURCES = Object.freeze(["config", "settings", "mirror"]);
|
|
14325
|
+
function normalizeInterfaceLanguageTag(value) {
|
|
14326
|
+
if (typeof value !== "string") return null;
|
|
14327
|
+
const trimmed = value.trim();
|
|
14328
|
+
return LANGUAGE_TAG.test(trimmed) ? trimmed : null;
|
|
14329
|
+
}
|
|
14330
|
+
|
|
14331
|
+
// plugin-src/client/interface-language.js
|
|
14332
|
+
var HOST_LANGUAGE_RPC_CHANNEL = "/dsh-im-language";
|
|
14333
|
+
var HOST_LANGUAGE_ENDPOINTS = Object.freeze({
|
|
14334
|
+
get: "settings.language.get",
|
|
14335
|
+
mirror: "settings.language.mirror"
|
|
14336
|
+
});
|
|
14337
|
+
var RETRY_DELAYS_MS = Object.freeze([1e3, 4e3, 15e3]);
|
|
14338
|
+
function installInterfaceLanguageMirror(ctx, {
|
|
14339
|
+
rpcCall,
|
|
14340
|
+
setTimeoutFn = (callback, delayMs) => globalThis.setTimeout(callback, delayMs),
|
|
14341
|
+
clearTimeoutFn = (timer) => globalThis.clearTimeout(timer),
|
|
14342
|
+
retryDelaysMs = RETRY_DELAYS_MS
|
|
14343
|
+
} = {}) {
|
|
14344
|
+
if (typeof rpcCall !== "function" || typeof ctx?.locale?.getLocale !== "function") {
|
|
14345
|
+
return () => {
|
|
14346
|
+
};
|
|
14347
|
+
}
|
|
14348
|
+
const delays = retryDelaysMs.length > 0 ? retryDelaysMs : RETRY_DELAYS_MS;
|
|
14349
|
+
const scheduler = createPollScheduler({ setTimeoutFn, clearTimeoutFn });
|
|
14350
|
+
let mirrored = null;
|
|
14351
|
+
let attempt = 0;
|
|
14352
|
+
const retry = (active) => {
|
|
14353
|
+
if (mirrored === active) mirrored = null;
|
|
14354
|
+
scheduler.schedule(report, delays[Math.min(attempt, delays.length - 1)]);
|
|
14355
|
+
attempt += 1;
|
|
14356
|
+
};
|
|
14357
|
+
const report = () => {
|
|
14358
|
+
if (scheduler.disposed) return;
|
|
14359
|
+
const active = normalizeInterfaceLanguageTag(ctx.locale.getLocale()?.active);
|
|
14360
|
+
if (active === null || active === mirrored) return;
|
|
14361
|
+
mirrored = active;
|
|
14362
|
+
Promise.resolve(rpcCall(HOST_LANGUAGE_ENDPOINTS.mirror, { locale: active })).then(
|
|
14363
|
+
(result) => {
|
|
14364
|
+
if (result?.ok === true) {
|
|
14365
|
+
attempt = 0;
|
|
14366
|
+
return;
|
|
14367
|
+
}
|
|
14368
|
+
retry(active);
|
|
14369
|
+
},
|
|
14370
|
+
() => retry(active)
|
|
14371
|
+
);
|
|
14372
|
+
};
|
|
14373
|
+
report();
|
|
14374
|
+
const off = typeof ctx.on === "function" ? ctx.on("locale/change", () => {
|
|
14375
|
+
attempt = 0;
|
|
14376
|
+
report();
|
|
14377
|
+
}) : null;
|
|
14378
|
+
return () => {
|
|
14379
|
+
scheduler.dispose();
|
|
14380
|
+
if (typeof off === "function") off();
|
|
14381
|
+
};
|
|
14382
|
+
}
|
|
14383
|
+
|
|
13941
14384
|
// plugin-src/client/delivery-settings.js
|
|
13942
|
-
var
|
|
14385
|
+
var React28 = __toESM(require("react"), 1);
|
|
13943
14386
|
|
|
13944
14387
|
// plugin-src/client/access-policy-settings.js
|
|
13945
|
-
var
|
|
14388
|
+
var React26 = __toESM(require("react"), 1);
|
|
13946
14389
|
var ACCESS_POLICY_ENDPOINT = "bot.access-policy.set";
|
|
13947
14390
|
var ACCESS_CHANNEL_DEFINITIONS = Object.freeze({
|
|
13948
14391
|
weixin: Object.freeze({
|
|
@@ -14055,8 +14498,8 @@ function ScenePolicyEditor({
|
|
|
14055
14498
|
unsupported = false,
|
|
14056
14499
|
onChange
|
|
14057
14500
|
}) {
|
|
14058
|
-
const ownerHelpId =
|
|
14059
|
-
const emptyAllowlistHelpId =
|
|
14501
|
+
const ownerHelpId = React26.useId();
|
|
14502
|
+
const emptyAllowlistHelpId = React26.useId();
|
|
14060
14503
|
const allowlist = policy.mode === "allowlist";
|
|
14061
14504
|
const collectionKey = allowlist ? "users" : "commandPermissionOverrides";
|
|
14062
14505
|
const branchKey = allowlist ? "allowlist" : "open";
|
|
@@ -14108,7 +14551,7 @@ function ScenePolicyEditor({
|
|
|
14108
14551
|
h2("strong", null, "\u5F53\u524D\u6E20\u9053\u4E0D\u652F\u6301\u7FA4\u804A"),
|
|
14109
14552
|
h2("p", null, "\u6B64\u533A\u57DF\u65E0\u9700\u914D\u7F6E\uFF0C\u4FDD\u5B58\u79C1\u804A\u8BBE\u7F6E\u65F6\u4F1A\u4FDD\u7559\u73B0\u6709\u7FA4\u804A\u7B56\u7565\u3002")
|
|
14110
14553
|
) : h2(
|
|
14111
|
-
|
|
14554
|
+
React26.Fragment,
|
|
14112
14555
|
null,
|
|
14113
14556
|
h2(
|
|
14114
14557
|
"div",
|
|
@@ -14249,16 +14692,16 @@ function AccessPolicySettingsPage({ channel: channel5, account, rpcCall, onSaved
|
|
|
14249
14692
|
const definition = ACCESS_CHANNEL_DEFINITIONS[channel5];
|
|
14250
14693
|
const initialPolicy = normalizeAccessPolicy(account?.accessPolicy);
|
|
14251
14694
|
const initialKey = JSON.stringify(initialPolicy);
|
|
14252
|
-
const [draft, setDraft] =
|
|
14695
|
+
const [draft, setDraft] = React26.useState(() => clonePolicy(
|
|
14253
14696
|
initialPolicy ?? DEFAULT_ACCESS_POLICY
|
|
14254
14697
|
));
|
|
14255
|
-
const [saving, setSaving] =
|
|
14256
|
-
const [feedback, setFeedback] =
|
|
14257
|
-
|
|
14698
|
+
const [saving, setSaving] = React26.useState(false);
|
|
14699
|
+
const [feedback, setFeedback] = React26.useState(null);
|
|
14700
|
+
React26.useEffect(() => {
|
|
14258
14701
|
const next = normalizeAccessPolicy(account?.accessPolicy);
|
|
14259
14702
|
setDraft(clonePolicy(next ?? DEFAULT_ACCESS_POLICY));
|
|
14260
14703
|
}, [account?.botId, initialKey]);
|
|
14261
|
-
|
|
14704
|
+
React26.useEffect(() => {
|
|
14262
14705
|
setFeedback(null);
|
|
14263
14706
|
}, [account?.botId]);
|
|
14264
14707
|
if (!definition) {
|
|
@@ -14349,7 +14792,7 @@ function AccessPolicySettingsPage({ channel: channel5, account, rpcCall, onSaved
|
|
|
14349
14792
|
}
|
|
14350
14793
|
|
|
14351
14794
|
// plugin-src/client/channels/feishu/group-settings.js
|
|
14352
|
-
var
|
|
14795
|
+
var React27 = __toESM(require("react"), 1);
|
|
14353
14796
|
var GROUP_MESSAGE_PERMISSION_OPERATION2 = FEISHU_REGISTRATION_OPERATIONS.GROUP_MESSAGE_PERMISSION;
|
|
14354
14797
|
function SettingsButton({ children, kind = "secondary", className = "", ...props }) {
|
|
14355
14798
|
return h2("button", {
|
|
@@ -14410,9 +14853,9 @@ function GroupResponseModeEditor({
|
|
|
14410
14853
|
onAuthorize
|
|
14411
14854
|
}) {
|
|
14412
14855
|
const current = normalizeGroupResponseMode(value);
|
|
14413
|
-
const [saving, setSaving] =
|
|
14414
|
-
const [authorizing, setAuthorizing] =
|
|
14415
|
-
const [error, setError] =
|
|
14856
|
+
const [saving, setSaving] = React27.useState(false);
|
|
14857
|
+
const [authorizing, setAuthorizing] = React27.useState(false);
|
|
14858
|
+
const [error, setError] = React27.useState(null);
|
|
14416
14859
|
const change = async (event) => {
|
|
14417
14860
|
const next = normalizeGroupResponseMode(event.target.value);
|
|
14418
14861
|
if (next === current || saving || disabled) return;
|
|
@@ -14493,8 +14936,8 @@ function GroupResponseModeEditor({
|
|
|
14493
14936
|
}
|
|
14494
14937
|
function GroupTopicReplyEditor({ value = false, disabled = false, onSave }) {
|
|
14495
14938
|
const current = value === true ? "on" : "off";
|
|
14496
|
-
const [saving, setSaving] =
|
|
14497
|
-
const [error, setError] =
|
|
14939
|
+
const [saving, setSaving] = React27.useState(false);
|
|
14940
|
+
const [error, setError] = React27.useState(null);
|
|
14498
14941
|
const change = async (event) => {
|
|
14499
14942
|
const next = event.target.value === "on";
|
|
14500
14943
|
if ((next ? "on" : "off") === current || saving || disabled) return;
|
|
@@ -14681,14 +15124,14 @@ function PermissionFlow({ provision, now, busy, botName, onRetry, onCancel, onCl
|
|
|
14681
15124
|
);
|
|
14682
15125
|
}
|
|
14683
15126
|
function FeishuGroupSettingsPage({ account, rpcCall }) {
|
|
14684
|
-
const [settings, setSettings] =
|
|
14685
|
-
const [refreshing, setRefreshing] =
|
|
14686
|
-
const [refreshError, setRefreshError] =
|
|
14687
|
-
const [provision, setProvision] =
|
|
14688
|
-
const [provisionBusy, setProvisionBusy] =
|
|
14689
|
-
const [now, setNow] =
|
|
14690
|
-
const mounted =
|
|
14691
|
-
|
|
15127
|
+
const [settings, setSettings] = React27.useState(() => groupSettingsFrom(account));
|
|
15128
|
+
const [refreshing, setRefreshing] = React27.useState(false);
|
|
15129
|
+
const [refreshError, setRefreshError] = React27.useState(null);
|
|
15130
|
+
const [provision, setProvision] = React27.useState(null);
|
|
15131
|
+
const [provisionBusy, setProvisionBusy] = React27.useState(false);
|
|
15132
|
+
const [now, setNow] = React27.useState(() => Date.now());
|
|
15133
|
+
const mounted = React27.useRef(true);
|
|
15134
|
+
React27.useEffect(() => {
|
|
14692
15135
|
setSettings(groupSettingsFrom(account));
|
|
14693
15136
|
}, [
|
|
14694
15137
|
account.botId,
|
|
@@ -14696,22 +15139,22 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
|
|
|
14696
15139
|
account.groupTopicReply,
|
|
14697
15140
|
account.groupMessagePermissionGranted
|
|
14698
15141
|
]);
|
|
14699
|
-
|
|
15142
|
+
React27.useEffect(() => {
|
|
14700
15143
|
mounted.current = true;
|
|
14701
15144
|
return () => {
|
|
14702
15145
|
mounted.current = false;
|
|
14703
15146
|
};
|
|
14704
15147
|
}, []);
|
|
14705
|
-
const invoke =
|
|
15148
|
+
const invoke = React27.useCallback(async (endpoint, payload = {}, signal) => {
|
|
14706
15149
|
if (typeof rpcCall !== "function") throw new Error("\u98DE\u4E66\u7FA4\u804A\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
14707
15150
|
return unwrapRpcResult3(await rpcCall(endpoint, payload, signal));
|
|
14708
15151
|
}, [rpcCall]);
|
|
14709
|
-
const applySnapshot =
|
|
15152
|
+
const applySnapshot = React27.useCallback((value) => {
|
|
14710
15153
|
const result = targetBotFromSnapshot(value, account.botId);
|
|
14711
15154
|
if (mounted.current) setSettings(groupSettingsFrom(result.bot));
|
|
14712
15155
|
return result;
|
|
14713
15156
|
}, [account.botId]);
|
|
14714
|
-
const loadSettings =
|
|
15157
|
+
const loadSettings = React27.useCallback(async ({ signal, restoreProvisioning = false } = {}) => {
|
|
14715
15158
|
setRefreshing(true);
|
|
14716
15159
|
setRefreshError(null);
|
|
14717
15160
|
try {
|
|
@@ -14740,16 +15183,16 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
|
|
|
14740
15183
|
if (!signal?.aborted && mounted.current) setRefreshing(false);
|
|
14741
15184
|
}
|
|
14742
15185
|
}, [account.botId, applySnapshot, invoke]);
|
|
14743
|
-
|
|
15186
|
+
React27.useEffect(() => {
|
|
14744
15187
|
const controller = new AbortController();
|
|
14745
15188
|
void loadSettings({ signal: controller.signal, restoreProvisioning: true });
|
|
14746
15189
|
return () => controller.abort();
|
|
14747
15190
|
}, [loadSettings]);
|
|
14748
|
-
const saveSetting =
|
|
15191
|
+
const saveSetting = React27.useCallback(async (endpoint, payload) => {
|
|
14749
15192
|
const value = await invoke(endpoint, { botId: account.botId, ...payload });
|
|
14750
15193
|
applySnapshot(value);
|
|
14751
15194
|
}, [account.botId, applySnapshot, invoke]);
|
|
14752
|
-
const startAuthorization =
|
|
15195
|
+
const startAuthorization = React27.useCallback(async ({ replace = false } = {}) => {
|
|
14753
15196
|
if (provisionBusy) return;
|
|
14754
15197
|
const previousAttemptId = provision?.attemptId;
|
|
14755
15198
|
setProvisionBusy(true);
|
|
@@ -14790,13 +15233,13 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
|
|
|
14790
15233
|
if (mounted.current) setProvisionBusy(false);
|
|
14791
15234
|
}
|
|
14792
15235
|
}, [account.botId, invoke, provision?.attemptId, provisionBusy]);
|
|
14793
|
-
const finishAuthorization =
|
|
15236
|
+
const finishAuthorization = React27.useCallback(async (signal) => {
|
|
14794
15237
|
const bot = await loadSettings({ signal, restoreProvisioning: false });
|
|
14795
15238
|
if (signal?.aborted || !mounted.current) return;
|
|
14796
15239
|
if (!bot) throw new Error("\u7FA4\u6D88\u606F\u6743\u9650\u5DF2\u66F4\u65B0\uFF0C\u4F46\u6682\u65F6\u65E0\u6CD5\u786E\u8BA4\u673A\u5668\u4EBA\u8FDE\u63A5\u72B6\u6001");
|
|
14797
15240
|
setProvision(null);
|
|
14798
15241
|
}, [loadSettings]);
|
|
14799
|
-
|
|
15242
|
+
React27.useEffect(() => {
|
|
14800
15243
|
if (!provision?.attemptId || !["qr", "connecting"].includes(provision.phase) || provision.expired) return void 0;
|
|
14801
15244
|
const timerHost = globalThis.window ?? globalThis;
|
|
14802
15245
|
const controller = new AbortController();
|
|
@@ -14840,7 +15283,7 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
|
|
|
14840
15283
|
timerHost.clearTimeout(timer);
|
|
14841
15284
|
};
|
|
14842
15285
|
}, [account.botId, finishAuthorization, invoke, provision]);
|
|
14843
|
-
|
|
15286
|
+
React27.useEffect(() => {
|
|
14844
15287
|
if (!provision?.attemptId || provision.phase !== "qr" || provision.expired) return void 0;
|
|
14845
15288
|
const timerHost = globalThis.window ?? globalThis;
|
|
14846
15289
|
const tick = () => {
|
|
@@ -14854,7 +15297,7 @@ function FeishuGroupSettingsPage({ account, rpcCall }) {
|
|
|
14854
15297
|
const timer = timerHost.setInterval(tick, 1e3);
|
|
14855
15298
|
return () => timerHost.clearInterval(timer);
|
|
14856
15299
|
}, [provision?.attemptId, provision?.expired, provision?.expiresAt, provision?.phase]);
|
|
14857
|
-
const cancelAuthorization =
|
|
15300
|
+
const cancelAuthorization = React27.useCallback(async () => {
|
|
14858
15301
|
if (!provision?.attemptId || provisionBusy) {
|
|
14859
15302
|
setProvision(null);
|
|
14860
15303
|
return;
|
|
@@ -15175,13 +15618,13 @@ function TargetForm({
|
|
|
15175
15618
|
}) {
|
|
15176
15619
|
const editing = mode === "edit";
|
|
15177
15620
|
const initialKind = initialValue?.kind && definition.fields[initialValue.kind] ? initialValue.kind : definition.kinds[0].value;
|
|
15178
|
-
const [targetId, setTargetId] =
|
|
15179
|
-
const [name2, setName] =
|
|
15180
|
-
const [kind, setKind] =
|
|
15181
|
-
const [route, setRoute] =
|
|
15182
|
-
const [error, setError] =
|
|
15183
|
-
const [testing, setTesting] =
|
|
15184
|
-
const [testState, setTestState] =
|
|
15621
|
+
const [targetId, setTargetId] = React28.useState(initialValue?.targetId ?? "");
|
|
15622
|
+
const [name2, setName] = React28.useState(initialValue?.name ?? "");
|
|
15623
|
+
const [kind, setKind] = React28.useState(initialKind);
|
|
15624
|
+
const [route, setRoute] = React28.useState(initialValue?.route ?? {});
|
|
15625
|
+
const [error, setError] = React28.useState(null);
|
|
15626
|
+
const [testing, setTesting] = React28.useState(false);
|
|
15627
|
+
const [testState, setTestState] = React28.useState(null);
|
|
15185
15628
|
const currentTarget = () => {
|
|
15186
15629
|
const normalizedRoute = Object.fromEntries(fieldsFor(definition, kind).map((field) => {
|
|
15187
15630
|
const raw = String(route[field.key] ?? "").trim();
|
|
@@ -15398,7 +15841,7 @@ function TargetSuggestionPicker({
|
|
|
15398
15841
|
suggestions.map((suggestion, index) => {
|
|
15399
15842
|
const identity = routeIdentity(definition, suggestion);
|
|
15400
15843
|
const added = configured.has(identity);
|
|
15401
|
-
return
|
|
15844
|
+
return React28.createElement("option", {
|
|
15402
15845
|
key: suggestion.id ?? suggestion.suggestionId ?? `${identity}:${index}`,
|
|
15403
15846
|
value: String(index),
|
|
15404
15847
|
disabled: added
|
|
@@ -15415,11 +15858,11 @@ function TargetSuggestionPicker({
|
|
|
15415
15858
|
);
|
|
15416
15859
|
}
|
|
15417
15860
|
function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, onEdit }) {
|
|
15418
|
-
const [action, setAction] =
|
|
15419
|
-
const [testState, setTestState] =
|
|
15420
|
-
const [syncFeedback, setSyncFeedback] =
|
|
15421
|
-
const [copyState, setCopyState] =
|
|
15422
|
-
const [confirmDelete, setConfirmDelete] =
|
|
15861
|
+
const [action, setAction] = React28.useState(null);
|
|
15862
|
+
const [testState, setTestState] = React28.useState(null);
|
|
15863
|
+
const [syncFeedback, setSyncFeedback] = React28.useState(null);
|
|
15864
|
+
const [copyState, setCopyState] = React28.useState(null);
|
|
15865
|
+
const [confirmDelete, setConfirmDelete] = React28.useState(false);
|
|
15423
15866
|
const sessionSync = target.sessionSync ?? { enabled: false, state: "unavailable" };
|
|
15424
15867
|
const syncDescription = sessionSync.state === "active" ? "\u81EA\u52A8\u8DDF\u968F\u8BE5\u79C1\u804A\u7684\u5F53\u524D\u4F1A\u8BDD" : sessionSync.state === "waiting" ? "\u7B49\u5F85\u8BE5\u79C1\u804A\u5EFA\u7ACB\u65B0\u4F1A\u8BDD" : sessionSync.state === "unavailable" ? "\u4EC5\u652F\u6301\u5DF2\u7ECF\u804A\u8FC7\u3001\u5DF2\u5EFA\u7ACB\u5F53\u524D\u4F1A\u8BDD\u4E14\u4F7F\u7528\u5F53\u524D Host Harness \u7684\u79C1\u804A\u76EE\u6807" : "\u5173\u95ED\u65F6\u4E0D\u53D1\u9001 DSH \u4F1A\u8BDD\u6D88\u606F";
|
|
15425
15868
|
const testTarget = async () => {
|
|
@@ -15482,7 +15925,7 @@ function TargetRow({ definition, target, botId, connected, rpcCall, onChanged, o
|
|
|
15482
15925
|
h2(
|
|
15483
15926
|
"div",
|
|
15484
15927
|
{ className: "dim-targetTitle" },
|
|
15485
|
-
|
|
15928
|
+
React28.createElement("strong", null, target.name || target.targetId),
|
|
15486
15929
|
h2("span", null, kindLabel(definition, target.kind))
|
|
15487
15930
|
),
|
|
15488
15931
|
h2("code", null, `targetId: ${target.targetId}`)
|
|
@@ -15568,26 +16011,26 @@ function DeliveryTargetSettingsPage({
|
|
|
15568
16011
|
onBack
|
|
15569
16012
|
}) {
|
|
15570
16013
|
const definition = CHANNEL_DEFINITIONS[channel5];
|
|
15571
|
-
const [activeTabId, setActiveTabId] =
|
|
15572
|
-
const [phase, setPhase] =
|
|
15573
|
-
const [targets, setTargets] =
|
|
15574
|
-
const [suggestionPhase, setSuggestionPhase] =
|
|
15575
|
-
const [suggestions, setSuggestions] =
|
|
15576
|
-
const [suggestionError, setSuggestionError] =
|
|
15577
|
-
const [error, setError] =
|
|
15578
|
-
const [editor, setEditor] =
|
|
15579
|
-
const [saving, setSaving] =
|
|
15580
|
-
const [botCopyState, setBotCopyState] =
|
|
15581
|
-
const [accessPolicy, setAccessPolicy] =
|
|
15582
|
-
const mounted =
|
|
15583
|
-
|
|
16014
|
+
const [activeTabId, setActiveTabId] = React28.useState(BOT_SETTINGS_TABS[0].id);
|
|
16015
|
+
const [phase, setPhase] = React28.useState("loading");
|
|
16016
|
+
const [targets, setTargets] = React28.useState([]);
|
|
16017
|
+
const [suggestionPhase, setSuggestionPhase] = React28.useState("idle");
|
|
16018
|
+
const [suggestions, setSuggestions] = React28.useState([]);
|
|
16019
|
+
const [suggestionError, setSuggestionError] = React28.useState(null);
|
|
16020
|
+
const [error, setError] = React28.useState(null);
|
|
16021
|
+
const [editor, setEditor] = React28.useState(null);
|
|
16022
|
+
const [saving, setSaving] = React28.useState(false);
|
|
16023
|
+
const [botCopyState, setBotCopyState] = React28.useState(null);
|
|
16024
|
+
const [accessPolicy, setAccessPolicy] = React28.useState(account.accessPolicy);
|
|
16025
|
+
const mounted = React28.useRef(true);
|
|
16026
|
+
React28.useEffect(() => {
|
|
15584
16027
|
setAccessPolicy(account.accessPolicy);
|
|
15585
16028
|
}, [account.botId, account.accessPolicy]);
|
|
15586
|
-
const invoke =
|
|
16029
|
+
const invoke = React28.useCallback(async (endpoint, payload = {}, signal) => {
|
|
15587
16030
|
if (typeof rpcCall !== "function") throw new Error("\u6295\u9012\u76EE\u6807\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
15588
16031
|
return unwrapRpcResult13(await rpcCall(endpoint, payload, signal));
|
|
15589
16032
|
}, [rpcCall]);
|
|
15590
|
-
const loadTargets =
|
|
16033
|
+
const loadTargets = React28.useCallback(async ({ signal, silent = false } = {}) => {
|
|
15591
16034
|
if (!silent) setPhase("loading");
|
|
15592
16035
|
setError(null);
|
|
15593
16036
|
try {
|
|
@@ -15601,7 +16044,7 @@ function DeliveryTargetSettingsPage({
|
|
|
15601
16044
|
setPhase("error");
|
|
15602
16045
|
}
|
|
15603
16046
|
}, [account.botId, invoke]);
|
|
15604
|
-
const loadSuggestions =
|
|
16047
|
+
const loadSuggestions = React28.useCallback(async () => {
|
|
15605
16048
|
setSuggestionPhase("loading");
|
|
15606
16049
|
setSuggestionError(null);
|
|
15607
16050
|
try {
|
|
@@ -15615,7 +16058,7 @@ function DeliveryTargetSettingsPage({
|
|
|
15615
16058
|
setSuggestionPhase("error");
|
|
15616
16059
|
}
|
|
15617
16060
|
}, [account.botId, definition, invoke]);
|
|
15618
|
-
|
|
16061
|
+
React28.useEffect(() => {
|
|
15619
16062
|
mounted.current = true;
|
|
15620
16063
|
const controller = new AbortController();
|
|
15621
16064
|
void loadTargets({ signal: controller.signal });
|
|
@@ -15737,7 +16180,7 @@ function DeliveryTargetSettingsPage({
|
|
|
15737
16180
|
account,
|
|
15738
16181
|
rpcCall: accessRpcCall
|
|
15739
16182
|
}) : h2(
|
|
15740
|
-
|
|
16183
|
+
React28.Fragment,
|
|
15741
16184
|
null,
|
|
15742
16185
|
h2(
|
|
15743
16186
|
"section",
|
|
@@ -15848,7 +16291,7 @@ function DeliveryTargetSettingsPage({
|
|
|
15848
16291
|
}
|
|
15849
16292
|
|
|
15850
16293
|
// plugin-src/client/global-settings.js
|
|
15851
|
-
var
|
|
16294
|
+
var React29 = __toESM(require("react"), 1);
|
|
15852
16295
|
|
|
15853
16296
|
// src/channels/shared/inbound-ttl.mjs
|
|
15854
16297
|
var DEFAULT_INBOUND_TTL_HOURS = 168;
|
|
@@ -15910,29 +16353,29 @@ function GlobalButton({ children, kind = "secondary", className = "", ...props }
|
|
|
15910
16353
|
}, children);
|
|
15911
16354
|
}
|
|
15912
16355
|
function GlobalSettingsPanel({ rpcCall }) {
|
|
15913
|
-
const [phase, setPhase] =
|
|
15914
|
-
const [loadError, setLoadError] =
|
|
15915
|
-
const [ttlInput, setTtlInput] =
|
|
15916
|
-
const [savedTtl, setSavedTtl] =
|
|
15917
|
-
const [ttlError, setTtlError] =
|
|
15918
|
-
const [saveError, setSaveError] =
|
|
15919
|
-
const [saveSucceeded, setSaveSucceeded] =
|
|
15920
|
-
const [isSaving, setIsSaving] =
|
|
15921
|
-
const [sweepConfirming, setSweepConfirming] =
|
|
15922
|
-
const [sweeping, setSweeping] =
|
|
15923
|
-
const ttlErrorId =
|
|
15924
|
-
const ttlHintsId =
|
|
15925
|
-
const sweepTriggerId =
|
|
15926
|
-
const sweepConfirmId =
|
|
15927
|
-
const sweepConfirmTextId =
|
|
15928
|
-
const sweepConfirmButtonId =
|
|
15929
|
-
const mounted =
|
|
15930
|
-
const saving =
|
|
15931
|
-
const invoke =
|
|
16356
|
+
const [phase, setPhase] = React29.useState("loading");
|
|
16357
|
+
const [loadError, setLoadError] = React29.useState(null);
|
|
16358
|
+
const [ttlInput, setTtlInput] = React29.useState("");
|
|
16359
|
+
const [savedTtl, setSavedTtl] = React29.useState(null);
|
|
16360
|
+
const [ttlError, setTtlError] = React29.useState(false);
|
|
16361
|
+
const [saveError, setSaveError] = React29.useState(null);
|
|
16362
|
+
const [saveSucceeded, setSaveSucceeded] = React29.useState(false);
|
|
16363
|
+
const [isSaving, setIsSaving] = React29.useState(false);
|
|
16364
|
+
const [sweepConfirming, setSweepConfirming] = React29.useState(false);
|
|
16365
|
+
const [sweeping, setSweeping] = React29.useState(false);
|
|
16366
|
+
const ttlErrorId = React29.useId();
|
|
16367
|
+
const ttlHintsId = React29.useId();
|
|
16368
|
+
const sweepTriggerId = React29.useId();
|
|
16369
|
+
const sweepConfirmId = React29.useId();
|
|
16370
|
+
const sweepConfirmTextId = React29.useId();
|
|
16371
|
+
const sweepConfirmButtonId = React29.useId();
|
|
16372
|
+
const mounted = React29.useRef(true);
|
|
16373
|
+
const saving = React29.useRef(false);
|
|
16374
|
+
const invoke = React29.useCallback(async (endpoint, payload = {}, signal) => {
|
|
15932
16375
|
if (typeof rpcCall !== "function") throw new Error("\u901A\u7528\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
15933
16376
|
return unwrapRpcResult14(await rpcCall(endpoint, payload, signal));
|
|
15934
16377
|
}, [rpcCall]);
|
|
15935
|
-
const loadSettings =
|
|
16378
|
+
const loadSettings = React29.useCallback(async ({ signal } = {}) => {
|
|
15936
16379
|
setPhase("loading");
|
|
15937
16380
|
setLoadError(null);
|
|
15938
16381
|
try {
|
|
@@ -15956,7 +16399,7 @@ function GlobalSettingsPanel({ rpcCall }) {
|
|
|
15956
16399
|
setPhase("error");
|
|
15957
16400
|
}
|
|
15958
16401
|
}, [invoke]);
|
|
15959
|
-
|
|
16402
|
+
React29.useEffect(() => {
|
|
15960
16403
|
mounted.current = true;
|
|
15961
16404
|
const controller = new AbortController();
|
|
15962
16405
|
void loadSettings({ signal: controller.signal });
|
|
@@ -15965,7 +16408,7 @@ function GlobalSettingsPanel({ rpcCall }) {
|
|
|
15965
16408
|
controller.abort();
|
|
15966
16409
|
};
|
|
15967
16410
|
}, [loadSettings]);
|
|
15968
|
-
|
|
16411
|
+
React29.useEffect(() => {
|
|
15969
16412
|
if (!sweepConfirming) return;
|
|
15970
16413
|
globalThis.document?.getElementById(sweepConfirmButtonId)?.focus();
|
|
15971
16414
|
}, [sweepConfirmButtonId, sweepConfirming]);
|
|
@@ -17237,7 +17680,7 @@ function installSessionChannelLogos(document2 = globalThis.document) {
|
|
|
17237
17680
|
}
|
|
17238
17681
|
|
|
17239
17682
|
// plugin-src/client/update-panel.js
|
|
17240
|
-
var
|
|
17683
|
+
var React30 = __toESM(require("react"), 1);
|
|
17241
17684
|
var import_react_dom4 = require("react-dom");
|
|
17242
17685
|
var import_valid = __toESM(require_valid(), 1);
|
|
17243
17686
|
var import_rcompare = __toESM(require_rcompare(), 1);
|
|
@@ -17327,11 +17770,11 @@ function manualUpdateCommand(snapshot) {
|
|
|
17327
17770
|
return `dsh plugin --profile ${profileArgument} add -w @xmanrui/dsh-im@${version}`;
|
|
17328
17771
|
}
|
|
17329
17772
|
function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
17330
|
-
const [copyState, setCopyState] =
|
|
17331
|
-
const commandRef =
|
|
17332
|
-
const mounted =
|
|
17333
|
-
const copying =
|
|
17334
|
-
|
|
17773
|
+
const [copyState, setCopyState] = React30.useState("idle");
|
|
17774
|
+
const commandRef = React30.useRef(null);
|
|
17775
|
+
const mounted = React30.useRef(false);
|
|
17776
|
+
const copying = React30.useRef(false);
|
|
17777
|
+
React30.useEffect(() => {
|
|
17335
17778
|
mounted.current = true;
|
|
17336
17779
|
return () => {
|
|
17337
17780
|
mounted.current = false;
|
|
@@ -17363,7 +17806,7 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
17363
17806
|
{ className: "dim-updateManual", "aria-label": "\u624B\u5DE5\u66F4\u65B0" },
|
|
17364
17807
|
h2("h4", { className: "dim-updateManualHeading" }, "\u624B\u5DE5\u66F4\u65B0"),
|
|
17365
17808
|
command ? h2(
|
|
17366
|
-
|
|
17809
|
+
React30.Fragment,
|
|
17367
17810
|
null,
|
|
17368
17811
|
h2("p", { className: "dim-updateManualHint" }, "\u81EA\u52A8\u66F4\u65B0\u5931\u8D25\u53EF\u4EE5\u4F7F\u7528\u547D\u4EE4\u66F4\u65B0\uFF1A"),
|
|
17369
17812
|
h2(
|
|
@@ -17399,7 +17842,7 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
17399
17842
|
"aria-hidden": "true",
|
|
17400
17843
|
focusable: "false"
|
|
17401
17844
|
}, copyState === "copied" ? h2("path", { d: "m4 10 4 4 8-8" }) : h2(
|
|
17402
|
-
|
|
17845
|
+
React30.Fragment,
|
|
17403
17846
|
null,
|
|
17404
17847
|
h2("rect", { x: 7, y: 7, width: 10, height: 11, rx: 1.5 }),
|
|
17405
17848
|
h2("path", { d: "M5 13H3.5A1.5 1.5 0 0 1 2 11.5v-8A1.5 1.5 0 0 1 3.5 2h8A1.5 1.5 0 0 1 13 3.5V5" })
|
|
@@ -17424,10 +17867,10 @@ function ManualUpdateCommand({ command, disabled, sourceInstall, desktop }) {
|
|
|
17424
17867
|
);
|
|
17425
17868
|
}
|
|
17426
17869
|
function UpdateDialog({ children, onClose }) {
|
|
17427
|
-
const dialogRef =
|
|
17428
|
-
const titleId =
|
|
17429
|
-
const descriptionId =
|
|
17430
|
-
|
|
17870
|
+
const dialogRef = React30.useRef(null);
|
|
17871
|
+
const titleId = React30.useId();
|
|
17872
|
+
const descriptionId = React30.useId();
|
|
17873
|
+
React30.useEffect(() => {
|
|
17431
17874
|
const previous = globalThis.document?.activeElement;
|
|
17432
17875
|
dialogRef.current?.focus?.();
|
|
17433
17876
|
return () => {
|
|
@@ -17485,19 +17928,19 @@ function UpdateDialog({ children, onClose }) {
|
|
|
17485
17928
|
return typeof document !== "undefined" && document.body ? (0, import_react_dom4.createPortal)(content, document.body) : content;
|
|
17486
17929
|
}
|
|
17487
17930
|
function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
17488
|
-
const [snapshot, setSnapshot] =
|
|
17489
|
-
const [action, setAction] =
|
|
17490
|
-
const [error, setError] =
|
|
17491
|
-
const [open, setOpen] =
|
|
17492
|
-
const [uncertainInstall, setUncertainInstall] =
|
|
17493
|
-
const mounted =
|
|
17494
|
-
const busy =
|
|
17495
|
-
const readController =
|
|
17496
|
-
const pollReadController =
|
|
17497
|
-
const installRequest =
|
|
17498
|
-
const onStatusRef =
|
|
17931
|
+
const [snapshot, setSnapshot] = React30.useState(null);
|
|
17932
|
+
const [action, setAction] = React30.useState("status");
|
|
17933
|
+
const [error, setError] = React30.useState(null);
|
|
17934
|
+
const [open, setOpen] = React30.useState(false);
|
|
17935
|
+
const [uncertainInstall, setUncertainInstall] = React30.useState(false);
|
|
17936
|
+
const mounted = React30.useRef(false);
|
|
17937
|
+
const busy = React30.useRef(false);
|
|
17938
|
+
const readController = React30.useRef(null);
|
|
17939
|
+
const pollReadController = React30.useRef(null);
|
|
17940
|
+
const installRequest = React30.useRef(null);
|
|
17941
|
+
const onStatusRef = React30.useRef(onStatus);
|
|
17499
17942
|
onStatusRef.current = onStatus;
|
|
17500
|
-
const accept =
|
|
17943
|
+
const accept = React30.useCallback((next) => {
|
|
17501
17944
|
setSnapshot(next);
|
|
17502
17945
|
onStatusRef.current?.(next);
|
|
17503
17946
|
}, []);
|
|
@@ -17506,7 +17949,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
17506
17949
|
setUncertainInstall(false);
|
|
17507
17950
|
accept(next);
|
|
17508
17951
|
};
|
|
17509
|
-
const invoke =
|
|
17952
|
+
const invoke = React30.useCallback(async (endpoint, payload = {}, signal) => {
|
|
17510
17953
|
if (typeof rpcCall !== "function") {
|
|
17511
17954
|
const unavailable = new Error("\u5F53\u524D Host \u4E0D\u652F\u6301\u66F4\u65B0\u63A5\u53E3\uFF0C\u8BF7\u5148\u624B\u52A8\u66F4\u65B0\u63D2\u4EF6\u5E76\u91CD\u542F\u3002");
|
|
17512
17955
|
unavailable.code = "update-unavailable";
|
|
@@ -17514,7 +17957,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
17514
17957
|
}
|
|
17515
17958
|
return unwrapSnapshot(await rpcCall(endpoint, payload, signal));
|
|
17516
17959
|
}, [rpcCall]);
|
|
17517
|
-
|
|
17960
|
+
React30.useEffect(() => {
|
|
17518
17961
|
mounted.current = true;
|
|
17519
17962
|
busy.current = true;
|
|
17520
17963
|
const controller = new AbortController();
|
|
@@ -17537,7 +17980,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
17537
17980
|
const activeJob = ACTIVE_STATES4.has(snapshot?.job?.state);
|
|
17538
17981
|
const restartRequired = snapshot?.job?.state === "restart-required" || snapshot?.blockedReason === "pending-restart";
|
|
17539
17982
|
const shouldPoll = activeJob || uncertainInstall;
|
|
17540
|
-
|
|
17983
|
+
React30.useEffect(() => {
|
|
17541
17984
|
if (!shouldPoll) return void 0;
|
|
17542
17985
|
let controller;
|
|
17543
17986
|
const scheduler = createPollScheduler({
|
|
@@ -17635,7 +18078,7 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
17635
18078
|
const manualCommand = manualUpdateCommand(snapshot);
|
|
17636
18079
|
const buttonLabel = action === "checking" ? "\u68C0\u67E5\u4E2D\u2026" : action === "starting" || activeJob ? "\u6B63\u5728\u66F4\u65B0\u2026" : restartRequired ? "\u5F85\u624B\u52A8\u91CD\u542F" : snapshot?.canInstall ? "\u66F4\u65B0\u81F3" : "\u68C0\u67E5\u66F4\u65B0";
|
|
17637
18080
|
return h2(
|
|
17638
|
-
|
|
18081
|
+
React30.Fragment,
|
|
17639
18082
|
null,
|
|
17640
18083
|
h2("button", {
|
|
17641
18084
|
type: "button",
|
|
@@ -17660,13 +18103,13 @@ function UpdatePanel({ rpcCall, clientVersion, onStatus }) {
|
|
|
17660
18103
|
h2("dt", null, "\u8FD0\u884C\u7248\u672C"),
|
|
17661
18104
|
h2("dd", null, `v${snapshot?.runningVersion ?? clientVersion}`),
|
|
17662
18105
|
snapshot?.installedVersion && snapshot.installedVersion !== snapshot.runningVersion ? h2(
|
|
17663
|
-
|
|
18106
|
+
React30.Fragment,
|
|
17664
18107
|
null,
|
|
17665
18108
|
h2("dt", null, "\u5DF2\u5B89\u88C5\u7248\u672C"),
|
|
17666
18109
|
h2("dd", null, `v${snapshot.installedVersion}`)
|
|
17667
18110
|
) : null,
|
|
17668
18111
|
targetVersion ? h2(
|
|
17669
|
-
|
|
18112
|
+
React30.Fragment,
|
|
17670
18113
|
null,
|
|
17671
18114
|
h2("dt", null, "\u76EE\u6807\u7248\u672C"),
|
|
17672
18115
|
h2("dd", null, `v${targetVersion}`)
|
|
@@ -17887,23 +18330,23 @@ function IMSettingsTab({
|
|
|
17887
18330
|
browserLocation = globalThis.location,
|
|
17888
18331
|
navigateToRecoveryUrl = replacePageLocation
|
|
17889
18332
|
}) {
|
|
17890
|
-
const [selected, setSelected] =
|
|
17891
|
-
const [loopbackRecovery, setLoopbackRecovery] =
|
|
17892
|
-
const [runningVersion, setRunningVersion] =
|
|
17893
|
-
const [deliverySettings, setDeliverySettings] =
|
|
17894
|
-
const githubTooltipId =
|
|
17895
|
-
const generalSettingsTooltipId =
|
|
18333
|
+
const [selected, setSelected] = React31.useState("weixin");
|
|
18334
|
+
const [loopbackRecovery, setLoopbackRecovery] = React31.useState(null);
|
|
18335
|
+
const [runningVersion, setRunningVersion] = React31.useState(IM_PLUGIN_VERSION);
|
|
18336
|
+
const [deliverySettings, setDeliverySettings] = React31.useState(null);
|
|
18337
|
+
const githubTooltipId = React31.useId();
|
|
18338
|
+
const generalSettingsTooltipId = React31.useId();
|
|
17896
18339
|
const globalSettingsSelected = selected === GLOBAL_SETTINGS_TAB_ID;
|
|
17897
18340
|
const active = CHANNELS.find((channel5) => channel5.id === selected) ?? CHANNELS[0];
|
|
17898
18341
|
const activeTabId = globalSettingsSelected ? "dim-general-settings-trigger" : `dim-tab-${active.id}`;
|
|
17899
18342
|
const activePanelId = globalSettingsSelected ? `dim-panel-${GLOBAL_SETTINGS_TAB_ID}` : `dim-panel-${active.id}`;
|
|
17900
|
-
const reportLoopbackRecovery =
|
|
18343
|
+
const reportLoopbackRecovery = React31.useCallback((recovery) => {
|
|
17901
18344
|
setLoopbackRecovery((current) => current?.url === recovery.url ? current : recovery);
|
|
17902
18345
|
}, []);
|
|
17903
|
-
const reportUpdateStatus =
|
|
18346
|
+
const reportUpdateStatus = React31.useCallback((snapshot) => {
|
|
17904
18347
|
setRunningVersion(snapshot.runningVersion);
|
|
17905
18348
|
}, []);
|
|
17906
|
-
const rpcCalls =
|
|
18349
|
+
const rpcCalls = React31.useMemo(() => createLoopbackAwareRpcCalls({
|
|
17907
18350
|
dingtalkRpcCall,
|
|
17908
18351
|
discordRpcCall,
|
|
17909
18352
|
feishuRpcCall,
|
|
@@ -17941,7 +18384,7 @@ function IMSettingsTab({
|
|
|
17941
18384
|
weixinRpcCall,
|
|
17942
18385
|
whatsappRpcCall
|
|
17943
18386
|
]);
|
|
17944
|
-
const botSettingsContext =
|
|
18387
|
+
const botSettingsContext = React31.useMemo(() => Object.freeze({
|
|
17945
18388
|
openBotSettings: setDeliverySettings
|
|
17946
18389
|
}), []);
|
|
17947
18390
|
return h2(
|
|
@@ -18084,6 +18527,12 @@ function apply(ctx) {
|
|
|
18084
18527
|
);
|
|
18085
18528
|
const t = ctx.locale.bind(IM_LOCALE_NAMESPACE);
|
|
18086
18529
|
setImTranslator(t);
|
|
18530
|
+
ctx.effect(
|
|
18531
|
+
() => installInterfaceLanguageMirror(ctx, {
|
|
18532
|
+
rpcCall: (endpoint, payload, signal) => callManagementRpc(ctx.connection, HOST_LANGUAGE_RPC_CHANNEL, endpoint, payload, signal)
|
|
18533
|
+
}),
|
|
18534
|
+
"im-settings: mirror the DSH interface language"
|
|
18535
|
+
);
|
|
18087
18536
|
ctx.effect(() => installSessionChannelLogos(), "im-settings: Session channel logos");
|
|
18088
18537
|
ctx.effect(() => {
|
|
18089
18538
|
const disposers = [
|