@xmanrui/dsh-im 0.12.0 → 0.14.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 +64 -43
- package/README.md +66 -45
- package/assets/logo-dsh-im-connecting-readme-3x2.png +0 -0
- package/assets/logo-dsh-im-connecting-square-v4.png +0 -0
- package/assets/logo-plugin-phone.png +0 -0
- package/lib/client.js +805 -173
- package/lib/index.js +142 -129
- package/package.json +4 -3
- package/plugin-src/client/build.mjs +1 -6
- package/plugin-src/client/channel-logos.js +12 -0
- package/plugin-src/client/channels/office/api.js +44 -0
- package/plugin-src/client/channels/office/index.js +152 -0
- package/plugin-src/client/channels/office/styles.js +50 -0
- package/plugin-src/client/channels/shared/token-api.js +5 -1
- package/plugin-src/client/channels/shared/token-channel.js +16 -1
- package/plugin-src/client/channels/telegram/api.js +17 -2
- package/plugin-src/client/channels/telegram/index.js +112 -0
- package/plugin-src/client/channels/telegram/styles.js +26 -0
- package/plugin-src/client/i18n.js +69 -1
- package/plugin-src/client/index.js +22 -12
- package/plugin-src/client/styles.js +5 -3
- package/plugin-src/host/channels/office/index.mjs +10 -0
- package/plugin-src/host/channels/office/production.mjs +45 -0
- package/plugin-src/host/channels/office/rpc.mjs +48 -0
- package/plugin-src/host/channels/shared/production.mjs +9 -1
- package/plugin-src/host/channels/telegram/production.mjs +2 -0
- package/plugin-src/host/channels/telegram/rpc.mjs +58 -8
- package/plugin-src/host/index.mjs +3 -0
- package/scripts/verify-package.mjs +34 -0
- package/src/channels/dingtalk/dingtalk-bridge.mjs +3 -2
- package/src/channels/discord/discord-api.mjs +1 -1
- package/src/channels/feishu/bridge.mjs +3 -2
- package/src/channels/office/config-store.mjs +107 -0
- package/src/channels/office/office-controller.mjs +167 -0
- package/src/channels/office/office-job-executor.mjs +390 -0
- package/src/channels/office/office-runtime.mjs +171 -0
- package/src/channels/office/office-transport.mjs +170 -0
- package/src/channels/office/protocol.mjs +43 -0
- package/src/channels/qq/qq-bridge.mjs +3 -2
- package/src/channels/shared/model-command.mjs +44 -6
- package/src/channels/shared/text-harness-bridge.mjs +3 -2
- package/src/channels/shared/token-bot-controller.mjs +28 -0
- package/src/channels/shared/token-config-store.mjs +14 -1
- package/src/channels/telegram/config-store.mjs +62 -1
- package/src/channels/telegram/telegram-controller.mjs +25 -1
- package/src/channels/telegram/telegram-runtime.mjs +26 -1
- package/src/channels/wecom/wecom-bridge.mjs +3 -2
- package/src/channels/weixin/weixin-api.mjs +1 -1
- package/src/channels/weixin/weixin-bridge.mjs +3 -2
package/lib/client.js
CHANGED
|
@@ -40,7 +40,7 @@ __export(index_exports, {
|
|
|
40
40
|
name: () => name
|
|
41
41
|
});
|
|
42
42
|
module.exports = __toCommonJS(index_exports);
|
|
43
|
-
var
|
|
43
|
+
var React18 = __toESM(require("react"), 1);
|
|
44
44
|
|
|
45
45
|
// plugin-src/client/channel-logos.js
|
|
46
46
|
var React = __toESM(require("react"), 1);
|
|
@@ -171,6 +171,20 @@ function WhatsappLogoGlyph({ size } = {}) {
|
|
|
171
171
|
d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.074-.297-.149-1.255-.462-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.521.149-.173.198-.297.298-.495.099-.198.05-.372-.025-.521-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a12.8 12.8 0 0 0-.57-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479s1.065 2.875 1.213 3.074c.149.198 2.095 3.2 5.077 4.487.709.306 1.262.489 1.694.626.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.29.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.981.999-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.83 9.83 0 0 1 2.893 6.991c-.003 5.45-4.437 9.884-9.886 9.884m8.413-18.297A11.8 11.8 0 0 0 12.055 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.9 11.9 0 0 0 5.688 1.448h.005c6.557 0 11.892-5.335 11.895-11.893a11.82 11.82 0 0 0-3.486-8.413"
|
|
172
172
|
}));
|
|
173
173
|
}
|
|
174
|
+
function OfficeLogoGlyph({ size } = {}) {
|
|
175
|
+
return h(
|
|
176
|
+
"svg",
|
|
177
|
+
{
|
|
178
|
+
...dimensions(size),
|
|
179
|
+
viewBox: "0 0 24 24",
|
|
180
|
+
focusable: "false",
|
|
181
|
+
"aria-hidden": "true",
|
|
182
|
+
"data-im-channel-logo": "office"
|
|
183
|
+
},
|
|
184
|
+
h("path", { fill: "currentColor", d: "M4 3.5h10.5a2 2 0 0 1 2 2v13H4v-15Zm2.2 3v1.8h2V6.5h-2Zm4.1 0v1.8h2V6.5h-2Zm-4.1 4v1.8h2v-1.8h-2Zm4.1 0v1.8h2v-1.8h-2ZM8.4 15v3.5h3V15h-3Z" }),
|
|
185
|
+
h("path", { fill: "currentColor", d: "M18.3 8.2h1.5v3h3v1.5h-3v3h-1.5v-3h-3v-1.5h3v-3Z" })
|
|
186
|
+
);
|
|
187
|
+
}
|
|
174
188
|
|
|
175
189
|
// plugin-src/client/channels/dingtalk/api.js
|
|
176
190
|
var DINGTALK_RPC_CHANNEL = "/dingtalk";
|
|
@@ -383,7 +397,52 @@ var EN = Object.freeze({
|
|
|
383
397
|
"IM\u673A\u5668\u4EBA": "IM bots",
|
|
384
398
|
"IM\u673A\u5668\u4EBA\u8BBE\u7F6E": "IM bot settings",
|
|
385
399
|
"IM \u6E20\u9053": "IM channels",
|
|
386
|
-
"\u8BA9\
|
|
400
|
+
"\u8BA9 DeepSeek Harness \u89E6\u624B\u53EF\u53CA": "DeepSeek Harness, always within reach",
|
|
401
|
+
"AI Office": "AI Office",
|
|
402
|
+
"AI Office \u8BBE\u7F6E": "AI Office settings",
|
|
403
|
+
"AI Office \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5": "AI Office settings are missing an RPC connection",
|
|
404
|
+
"\u6B63\u5728\u8BFB\u53D6 AI Office Connector\u2026": "Loading AI Office Connector\u2026",
|
|
405
|
+
"\u672C\u673A\u4E3B\u52A8\u8FDE\u63A5\u516C\u7F51 Office\uFF1BHarness \u4E0D\u5F00\u653E\u7AEF\u53E3\u3002\u534F\u8BAE Hook \u56FA\u5B9A\u4E3A ": "This machine connects outward to the public Office; Harness exposes no port. Protocol hooks: ",
|
|
406
|
+
"\u5C1A\u672A\u914D\u7F6E": "Not configured",
|
|
407
|
+
"\u5DF2\u8FDE\u63A5 Office": "Connected to Office",
|
|
408
|
+
"\u5DF2\u914D\u7F6E": "Configured",
|
|
409
|
+
"\u7B49\u5F85\u91CD\u8FDE": "Waiting to reconnect",
|
|
410
|
+
"\u51ED\u636E\u7F3A\u5931": "Credential missing",
|
|
411
|
+
"\u6700\u8FD1\u5FC3\u8DF3": "Last heartbeat",
|
|
412
|
+
"\u6700\u8FD1\u4E8B\u4EF6": "Last event",
|
|
413
|
+
"\u91CD\u8FDE\u6B21\u6570": "Reconnects",
|
|
414
|
+
"\u8FD0\u884C Job": "Running Jobs",
|
|
415
|
+
"\u5B8C\u6210 Job": "Completed Jobs",
|
|
416
|
+
"\u5C1A\u65E0": "None yet",
|
|
417
|
+
"\u8BBE\u5907\u8FDE\u63A5": "Device connection",
|
|
418
|
+
"Token \u53EA\u5199\u5165\u672C\u673A\u51ED\u636E\u5B58\u50A8": "Token is written only to the local credential store",
|
|
419
|
+
"\u7C98\u8D34 Office \u4E00\u6B21\u6027\u51ED\u636E": "Paste the one-time Office credential",
|
|
420
|
+
"\u5DF2\u5B89\u5168\u4FDD\u5B58\uFF1B\u7559\u7A7A\u4FDD\u6301\u4E0D\u53D8": "Stored securely; leave blank to keep it",
|
|
421
|
+
"\u6700\u5927\u5E76\u53D1": "Max concurrency",
|
|
422
|
+
"Heartbeat \u79D2\u6570": "Heartbeat seconds",
|
|
423
|
+
"Workspace \u6620\u5C04": "Workspace mappings",
|
|
424
|
+
"\u6BCF\u884C alias=/\u672C\u673A/\u7EDD\u5BF9\u8DEF\u5F84\uFF1BOffice \u53EA\u80FD\u770B\u5230 alias\u3002": "One alias=/local/absolute/path per line; Office sees only aliases.",
|
|
425
|
+
"Instruction Preset \u6620\u5C04": "Instruction preset mappings",
|
|
426
|
+
"\u6BCF\u884C alias=\u6307\u4EE4\uFF1B\u65B0\u589E preset \u4E0D\u9700\u8981\u6539 Office \u4EE3\u7801\u3002": "One alias=instruction per line; new presets require no Office code change.",
|
|
427
|
+
"\u4FDD\u5B58\u5E76\u8FDE\u63A5": "Save and connect",
|
|
428
|
+
"\u6D4B\u8BD5\u8FDE\u63A5": "Test connection",
|
|
429
|
+
"\u6D4B\u8BD5\u4E2D\u2026": "Testing\u2026",
|
|
430
|
+
"\u91CD\u65B0\u8FDE\u63A5": "Reconnect",
|
|
431
|
+
"\u79FB\u9664\u8FDE\u63A5": "Remove connection",
|
|
432
|
+
"\u8FDE\u63A5\u6D4B\u8BD5\u901A\u8FC7\u3002": "Connection test passed.",
|
|
433
|
+
"\u914D\u7F6E\u5DF2\u4FDD\u5B58\u3002": "Configuration saved.",
|
|
434
|
+
"\u534F\u8BAE Hook \u9884\u89C8": "Protocol hook preview",
|
|
435
|
+
"\u7531 Base URL \u81EA\u52A8\u6D3E\u751F\uFF0C\u4E0D\u5355\u72EC\u586B\u5199": "Derived from Base URL; no separate input",
|
|
436
|
+
"Base URL \u65E0\u6548": "Invalid Base URL",
|
|
437
|
+
"Office Hook \u5C1A\u672A\u90E8\u7F72\u65F6\uFF0C\u914D\u7F6E\u4F1A\u5B89\u5168\u4FDD\u5B58\u5E76\u81EA\u52A8\u91CD\u8BD5\uFF1B\u51FA\u73B0 HTTP 404 \u4EE3\u8868\u534F\u8BAE\u7AEF\u70B9\u5F85\u4E0A\u7EBF\uFF0C\u4E0D\u4EE3\u8868 Harness \u6545\u969C\u3002": "Configuration is saved and retried while Office hooks are unavailable; HTTP 404 means the protocol endpoint is pending, not a Harness failure.",
|
|
438
|
+
"Workspace \u6620\u5C04\u6BCF\u884C\u5FC5\u987B\u4F7F\u7528 alias=value": "Each workspace mapping must use alias=value",
|
|
439
|
+
"Instruction Preset \u6620\u5C04\u6BCF\u884C\u5FC5\u987B\u4F7F\u7528 alias=value": "Each instruction preset mapping must use alias=value",
|
|
440
|
+
"action-items=\u8F6C\u6362\u4E3A\u8D1F\u8D23\u4EBA\u3001\u622A\u6B62\u548C\u9A8C\u6536\u660E\u786E\u7684\u5DE5\u5355": "action-items=Turn this into accountable tasks with deadlines and acceptance criteria",
|
|
441
|
+
"AI Office \u62D2\u7EDD\u4E86 Device Token\u3002": "AI Office rejected the Device Token.",
|
|
442
|
+
"AI Office Connector Hook \u5C1A\u672A\u5C31\u7EEA\u3002": "AI Office Connector hooks are not available yet.",
|
|
443
|
+
"AI Office Connector \u534F\u8BAE\u7248\u672C\u4E0D\u517C\u5BB9\u3002": "The AI Office Connector protocol is incompatible.",
|
|
444
|
+
"\u672C\u673A\u6682\u65F6\u65E0\u6CD5\u8BBF\u95EE AI Office\u3002": "AI Office cannot currently be reached from this machine.",
|
|
445
|
+
"AI Office \u8FDE\u63A5\u5DF2\u4E2D\u65AD\u3002": "The AI Office connection was interrupted.",
|
|
387
446
|
"\u5E2E\u52A9\u4E0E\u53CD\u9988 \xB7 \u524D\u5F80 GitHub": "Help & feedback \xB7 Open GitHub",
|
|
388
447
|
"\u5FAE\u4FE1": "WeChat",
|
|
389
448
|
"\u98DE\u4E66": "Feishu",
|
|
@@ -612,6 +671,29 @@ var EN = Object.freeze({
|
|
|
612
671
|
"\u63A5\u5165 Telegram \u673A\u5668\u4EBA": "Connect a Telegram bot",
|
|
613
672
|
"\u5148\u901A\u8FC7 @BotFather \u83B7\u53D6 Bot Token\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002": "Get a Bot Token from @BotFather, then connect it here.",
|
|
614
673
|
"\u586B\u5199 @BotFather \u751F\u6210\u7684 Bot Token": "Enter the Bot Token from @BotFather",
|
|
674
|
+
"\u8BBF\u95EE\u6A21\u5F0F": "Access mode",
|
|
675
|
+
"\u8BBF\u95EE\u8BBE\u7F6E": "Access settings",
|
|
676
|
+
"Telegram \u8BBF\u95EE\u6A21\u5F0F": "Telegram access mode",
|
|
677
|
+
"\u67E5\u770B Telegram \u8BBF\u95EE\u6A21\u5F0F\u8BF4\u660E": "View Telegram access mode details",
|
|
678
|
+
"\u7FA4\u804A\u5168\u90E8\u5FFD\u7565\uFF0C\u79C1\u804A\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u7528\u6237\u3002": "All group messages are ignored; only allowlisted users may send DMs.",
|
|
679
|
+
"\u4FDD\u6301\u539F\u6709\u884C\u4E3A\uFF1A\u79C1\u804A\u76F4\u63A5\u54CD\u5E94\uFF0C\u7FA4\u804A\u5728\u88AB\u63D0\u53CA\u6216\u56DE\u590D\u65F6\u54CD\u5E94\u3002": "Keep the original behavior: respond to DMs and to group mentions or replies.",
|
|
680
|
+
"\u5B89\u5168\u6A21\u5F0F": "Safe mode",
|
|
681
|
+
"\u517C\u5BB9\u6A21\u5F0F": "Compatible mode",
|
|
682
|
+
"\u5DF2\u751F\u6548\uFF1A\u5B89\u5168\u6A21\u5F0F": "Active: Safe mode",
|
|
683
|
+
"\u5DF2\u751F\u6548\uFF1A\u517C\u5BB9\u6A21\u5F0F": "Active: Compatible mode",
|
|
684
|
+
"\u6A21\u5F0F": "Mode",
|
|
685
|
+
"\u517C\u5BB9\u6A21\u5F0F\uFF08\u9ED8\u8BA4\uFF09": "Compatible mode (default)",
|
|
686
|
+
"\u5B89\u5168\u6A21\u5F0F\uFF08\u79C1\u804A\u767D\u540D\u5355\uFF09": "Safe mode (private-chat allowlist)",
|
|
687
|
+
"\u5141\u8BB8\u79C1\u804A\u7684 Telegram User ID": "Telegram User IDs allowed to send DMs",
|
|
688
|
+
"\u6BCF\u884C\u4E00\u4E2A\u6570\u5B57 User ID": "One numeric User ID per line",
|
|
689
|
+
"\u767D\u540D\u5355\u4EC5\u5C5E\u4E8E\u5F53\u524D\u673A\u5668\u4EBA\u3002": "This allowlist belongs only to the current bot.",
|
|
690
|
+
"\u517C\u5BB9\u6A21\u5F0F\u4E0B\u6682\u4E0D\u4F7F\u7528\u767D\u540D\u5355\uFF0C\u5207\u6362\u6A21\u5F0F\u65F6\u4F1A\u4FDD\u7559\u3002": "Compatible mode does not enforce the allowlist; it is retained when modes change.",
|
|
691
|
+
"\u767D\u540D\u5355\u4E3A\u7A7A\uFF1B\u4FDD\u5B58\u540E\u8BE5\u673A\u5668\u4EBA\u4F1A\u62D2\u7EDD\u6240\u6709\u5165\u7AD9\u6D88\u606F\u3002": "The allowlist is empty; this bot will reject all inbound messages after saving.",
|
|
692
|
+
"\u6B63\u5728\u4FDD\u5B58\u2026": "Saving\u2026",
|
|
693
|
+
"\u4FDD\u5B58\u8BBF\u95EE\u8BBE\u7F6E": "Save access settings",
|
|
694
|
+
"User ID \u5FC5\u987B\u662F 1\u201316 \u4F4D\u6B63\u6574\u6570\uFF0C\u6BCF\u884C\u4E00\u4E2A\u3002": "Each User ID must be a 1\u201316 digit positive integer on its own line.",
|
|
695
|
+
"Telegram \u8BBF\u95EE\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002": "Telegram access settings are currently unavailable.",
|
|
696
|
+
"Telegram \u8BBF\u95EE\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\u3002": "Could not save Telegram access settings.",
|
|
615
697
|
"\u63A5\u5165 Discord \u673A\u5668\u4EBA": "Connect a Discord bot",
|
|
616
698
|
"\u5148\u5728 Developer Portal \u521B\u5EFA Bot \u5E76\u9080\u8BF7\u5230\u670D\u52A1\u5668\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002": "Create a bot in the Developer Portal and invite it to your server, then connect it here.",
|
|
617
699
|
"\u586B\u5199 Discord Developer Portal \u7684 Bot Token": "Enter the Bot Token from the Discord Developer Portal",
|
|
@@ -1773,7 +1855,7 @@ function AccountCard({
|
|
|
1773
1855
|
}) {
|
|
1774
1856
|
const state = busy === "reconnect" ? "connecting" : account.state;
|
|
1775
1857
|
const tone = account.connected ? "success" : state === "error" ? "error" : "warning";
|
|
1776
|
-
const
|
|
1858
|
+
const stateLabel2 = account.connected ? "\u8FD0\u884C\u6B63\u5E38" : state === "connecting" ? "\u6B63\u5728\u8FDE\u63A5" : "\u8FDE\u63A5\u672A\u5C31\u7EEA";
|
|
1777
1859
|
const summary = account.error?.message ?? (account.connected ? null : account.health.summary);
|
|
1778
1860
|
return h2(
|
|
1779
1861
|
"article",
|
|
@@ -1799,7 +1881,7 @@ function AccountCard({
|
|
|
1799
1881
|
"div",
|
|
1800
1882
|
{ className: "ddt-health dim-botHealth" },
|
|
1801
1883
|
h2("span", { className: "ddt-dot dim-healthDot", "data-tone": tone }),
|
|
1802
|
-
h2("span", null,
|
|
1884
|
+
h2("span", null, stateLabel2)
|
|
1803
1885
|
)
|
|
1804
1886
|
),
|
|
1805
1887
|
h2(
|
|
@@ -2405,7 +2487,9 @@ var TOKEN_BOT_ENDPOINTS = Object.freeze({
|
|
|
2405
2487
|
deleteBot: "bot.delete",
|
|
2406
2488
|
setWorkspace: "bot.workspace.set"
|
|
2407
2489
|
});
|
|
2408
|
-
function createTokenChannelApi(channel4, connectionSummary
|
|
2490
|
+
function createTokenChannelApi(channel4, connectionSummary, {
|
|
2491
|
+
normalizeBotExtension = () => ({})
|
|
2492
|
+
} = {}) {
|
|
2409
2493
|
const unwrapRpcResult10 = (result) => {
|
|
2410
2494
|
if (!isRecord2(result) || typeof result.ok !== "boolean") {
|
|
2411
2495
|
throw new Error(`${channel4} \u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94`);
|
|
@@ -2421,6 +2505,7 @@ function createTokenChannelApi(channel4, connectionSummary) {
|
|
|
2421
2505
|
if (!isRecord2(value) || !id(value.botId)) return void 0;
|
|
2422
2506
|
const connected = value.connected === true;
|
|
2423
2507
|
const state = ACCOUNT_STATES2.has(value.state) ? value.state : "offline";
|
|
2508
|
+
const extension = normalizeBotExtension(value);
|
|
2424
2509
|
return {
|
|
2425
2510
|
botId: id(value.botId),
|
|
2426
2511
|
connected,
|
|
@@ -2441,7 +2526,8 @@ function createTokenChannelApi(channel4, connectionSummary) {
|
|
|
2441
2526
|
error: isRecord2(value.error) ? {
|
|
2442
2527
|
code: text(value.error.code, `${channel4.toUpperCase()}_ACCOUNT_ERROR`, 80),
|
|
2443
2528
|
message: text(value.error.message, `${channel4}\u8FDE\u63A5\u5C1A\u672A\u5C31\u7EEA`)
|
|
2444
|
-
} : null
|
|
2529
|
+
} : null,
|
|
2530
|
+
...isRecord2(extension) ? extension : {}
|
|
2445
2531
|
};
|
|
2446
2532
|
};
|
|
2447
2533
|
const normalizeSnapshot9 = (value) => {
|
|
@@ -2521,12 +2607,14 @@ function createTokenChannelSettings(definition) {
|
|
|
2521
2607
|
credentialOpenLabel = "\u624B\u52A8\u63A5\u5165",
|
|
2522
2608
|
credentialCloseLabel = "\u6536\u8D77\u51ED\u636E",
|
|
2523
2609
|
credentialNoun = "Bot Token",
|
|
2524
|
-
emptyActionLabel = "\u586B\u5199 Bot Token"
|
|
2610
|
+
emptyActionLabel = "\u586B\u5199 Bot Token",
|
|
2611
|
+
AccountSettings = null,
|
|
2612
|
+
accountSettingsEndpoint = null
|
|
2525
2613
|
} = definition;
|
|
2526
|
-
function AccountCard5({ account, busy, testNotice, removing, onReconnect, onWorkspaceSave, onRequestRemove, onConfirmRemove, onCancelRemove }) {
|
|
2614
|
+
function AccountCard5({ account, busy, testNotice, removing, onReconnect, onWorkspaceSave, onAccountSettingsSave, onRequestRemove, onConfirmRemove, onCancelRemove }) {
|
|
2527
2615
|
const state = busy === "reconnect" ? "connecting" : account.state;
|
|
2528
2616
|
const tone = account.connected ? "success" : state === "error" ? "error" : "warning";
|
|
2529
|
-
const
|
|
2617
|
+
const stateLabel2 = account.connected ? "\u8FD0\u884C\u6B63\u5E38" : state === "connecting" ? "\u6B63\u5728\u8FDE\u63A5" : "\u8FDE\u63A5\u672A\u5C31\u7EEA";
|
|
2530
2618
|
const summary = account.error?.message ?? (account.connected ? null : account.health.summary);
|
|
2531
2619
|
const identity = account.bot.username ? `@${account.bot.username}` : account.bot.idMasked;
|
|
2532
2620
|
return h2(
|
|
@@ -2557,7 +2645,7 @@ function createTokenChannelSettings(definition) {
|
|
|
2557
2645
|
"div",
|
|
2558
2646
|
{ className: "ddt-health dim-botHealth" },
|
|
2559
2647
|
h2("span", { className: "ddt-dot dim-healthDot", "data-tone": tone }),
|
|
2560
|
-
h2("span", null,
|
|
2648
|
+
h2("span", null, stateLabel2)
|
|
2561
2649
|
)
|
|
2562
2650
|
),
|
|
2563
2651
|
h2(
|
|
@@ -2581,6 +2669,11 @@ function createTokenChannelSettings(definition) {
|
|
|
2581
2669
|
disabled: Boolean(busy),
|
|
2582
2670
|
onSave: onWorkspaceSave
|
|
2583
2671
|
}),
|
|
2672
|
+
AccountSettings ? h2(AccountSettings, {
|
|
2673
|
+
account,
|
|
2674
|
+
busy: Boolean(busy),
|
|
2675
|
+
onSave: onAccountSettingsSave
|
|
2676
|
+
}) : null,
|
|
2584
2677
|
h2(
|
|
2585
2678
|
"div",
|
|
2586
2679
|
{ className: "ddt-accountFooter dim-cardFooter" },
|
|
@@ -2765,6 +2858,12 @@ function createTokenChannelSettings(definition) {
|
|
|
2765
2858
|
endpoints.setWorkspace,
|
|
2766
2859
|
{ botId: account.botId, workspace }
|
|
2767
2860
|
),
|
|
2861
|
+
onAccountSettingsSave: AccountSettings && accountSettingsEndpoint ? (payload) => botAction(
|
|
2862
|
+
account,
|
|
2863
|
+
"settings",
|
|
2864
|
+
accountSettingsEndpoint,
|
|
2865
|
+
{ botId: account.botId, ...payload }
|
|
2866
|
+
) : void 0,
|
|
2768
2867
|
onRequestRemove: () => setRemoveTarget(account.botId),
|
|
2769
2868
|
onCancelRemove: () => setRemoveTarget(null),
|
|
2770
2869
|
onConfirmRemove: async () => {
|
|
@@ -5148,7 +5247,7 @@ function AccountCard2({
|
|
|
5148
5247
|
onCancelRemove
|
|
5149
5248
|
}) {
|
|
5150
5249
|
const tone = account.connected ? "success" : account.state === "error" ? "error" : "warning";
|
|
5151
|
-
const
|
|
5250
|
+
const stateLabel2 = account.connected ? "\u8FD0\u884C\u6B63\u5E38" : account.state === "connecting" ? "\u6B63\u5728\u8FDE\u63A5" : "\u8FDE\u63A5\u672A\u5C31\u7EEA";
|
|
5152
5251
|
const summary = account.error?.message ?? (account.connected ? null : account.health.summary);
|
|
5153
5252
|
return h2(
|
|
5154
5253
|
"article",
|
|
@@ -5174,7 +5273,7 @@ function AccountCard2({
|
|
|
5174
5273
|
"div",
|
|
5175
5274
|
{ className: "ddt-health dim-botHealth" },
|
|
5176
5275
|
h2("span", { className: "ddt-dot dim-healthDot", "data-tone": tone }),
|
|
5177
|
-
h2("span", null,
|
|
5276
|
+
h2("span", null, stateLabel2)
|
|
5178
5277
|
)
|
|
5179
5278
|
),
|
|
5180
5279
|
h2(
|
|
@@ -5490,6 +5589,350 @@ function QqSettingsTab({ rpcCall }) {
|
|
|
5490
5589
|
);
|
|
5491
5590
|
}
|
|
5492
5591
|
|
|
5592
|
+
// src/channels/office/protocol.mjs
|
|
5593
|
+
var OFFICE_PROTOCOL_VERSION = "office-harness.v1";
|
|
5594
|
+
var OFFICE_RPC_CHANNEL = "/office";
|
|
5595
|
+
var OFFICE_RPC_ENDPOINTS = Object.freeze({
|
|
5596
|
+
status: "connection.status",
|
|
5597
|
+
configure: "connector.configure",
|
|
5598
|
+
reconnect: "connector.reconnect",
|
|
5599
|
+
test: "connector.test",
|
|
5600
|
+
remove: "connector.remove"
|
|
5601
|
+
});
|
|
5602
|
+
var OFFICE_HOOK_PATHS = Object.freeze({
|
|
5603
|
+
stream: "/api/harness/connector/stream",
|
|
5604
|
+
heartbeat: "/api/harness/connector/heartbeat",
|
|
5605
|
+
job: "/api/harness/connector/jobs/:id",
|
|
5606
|
+
accept: "/api/harness/connector/jobs/:id/accept",
|
|
5607
|
+
renew: "/api/harness/connector/jobs/:id/renew",
|
|
5608
|
+
progress: "/api/harness/connector/jobs/:id/progress",
|
|
5609
|
+
approval: "/api/harness/connector/jobs/:id/approval",
|
|
5610
|
+
result: "/api/harness/connector/jobs/:id/result",
|
|
5611
|
+
fail: "/api/harness/connector/jobs/:id/fail"
|
|
5612
|
+
});
|
|
5613
|
+
function normalizeOfficeBaseUrl(value) {
|
|
5614
|
+
const url = new URL(typeof value === "string" ? value.trim() : "");
|
|
5615
|
+
const localHttp = url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
|
|
5616
|
+
if (url.protocol !== "https:" && !localHttp) {
|
|
5617
|
+
throw new TypeError("AI Office URL must use HTTPS (HTTP is allowed only for loopback testing)");
|
|
5618
|
+
}
|
|
5619
|
+
if (url.username || url.password || url.search || url.hash) {
|
|
5620
|
+
throw new TypeError("AI Office URL must be a bare origin");
|
|
5621
|
+
}
|
|
5622
|
+
url.pathname = "/";
|
|
5623
|
+
return url;
|
|
5624
|
+
}
|
|
5625
|
+
function officeHookUrls(baseUrl) {
|
|
5626
|
+
const origin = normalizeOfficeBaseUrl(baseUrl);
|
|
5627
|
+
return Object.fromEntries(Object.entries(OFFICE_HOOK_PATHS).map(([name2, path]) => [
|
|
5628
|
+
name2,
|
|
5629
|
+
new URL(path, origin).toString()
|
|
5630
|
+
]));
|
|
5631
|
+
}
|
|
5632
|
+
|
|
5633
|
+
// plugin-src/client/channels/office/api.js
|
|
5634
|
+
function record(value) {
|
|
5635
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5636
|
+
}
|
|
5637
|
+
function unwrapOfficeRpc(result) {
|
|
5638
|
+
if (!record(result) || typeof result.ok !== "boolean") throw new Error("AI Office \u670D\u52A1\u8FD4\u56DE\u4E86\u65E0\u6CD5\u8BC6\u522B\u7684\u54CD\u5E94");
|
|
5639
|
+
if (!result.ok) {
|
|
5640
|
+
const error = new Error(typeof result.error?.message === "string" ? result.error.message : "AI Office \u64CD\u4F5C\u5931\u8D25");
|
|
5641
|
+
error.code = typeof result.error?.code === "string" ? result.error.code : "office-rpc-error";
|
|
5642
|
+
throw error;
|
|
5643
|
+
}
|
|
5644
|
+
return result.value;
|
|
5645
|
+
}
|
|
5646
|
+
function normalizeOfficeStatus(value) {
|
|
5647
|
+
if (!record(value) || value.configured !== true) {
|
|
5648
|
+
return { configured: false, connected: false, state: "unconfigured", config: null, health: null };
|
|
5649
|
+
}
|
|
5650
|
+
const config = record(value.config) ? value.config : {};
|
|
5651
|
+
return {
|
|
5652
|
+
configured: true,
|
|
5653
|
+
connected: value.connected === true,
|
|
5654
|
+
state: typeof value.state === "string" ? value.state : "idle",
|
|
5655
|
+
tokenConfigured: value.tokenConfigured === true,
|
|
5656
|
+
config: {
|
|
5657
|
+
protocolVersion: config.protocolVersion ?? OFFICE_PROTOCOL_VERSION,
|
|
5658
|
+
baseUrl: typeof config.baseUrl === "string" ? config.baseUrl : "",
|
|
5659
|
+
deviceId: typeof config.deviceId === "string" ? config.deviceId : "",
|
|
5660
|
+
maxConcurrency: Number(config.maxConcurrency ?? 1),
|
|
5661
|
+
heartbeatSeconds: Number(config.heartbeatSeconds ?? 30),
|
|
5662
|
+
workspaces: record(config.workspaces) ? config.workspaces : {},
|
|
5663
|
+
instructionPresets: record(config.instructionPresets) ? config.instructionPresets : {},
|
|
5664
|
+
hooks: record(config.hooks) ? config.hooks : {}
|
|
5665
|
+
},
|
|
5666
|
+
health: record(value.health) ? value.health : null
|
|
5667
|
+
};
|
|
5668
|
+
}
|
|
5669
|
+
|
|
5670
|
+
// plugin-src/client/channels/office/index.js
|
|
5671
|
+
var React12 = __toESM(require("react"), 1);
|
|
5672
|
+
function Button9({ children, kind = "secondary", ...props }) {
|
|
5673
|
+
return h2("button", { ...props, type: "button", className: "ddt-button", "data-kind": kind }, children);
|
|
5674
|
+
}
|
|
5675
|
+
function mapText(value) {
|
|
5676
|
+
return Object.entries(value ?? {}).map(([key, item]) => `${key}=${item}`).join("\n");
|
|
5677
|
+
}
|
|
5678
|
+
function parseMap(value, label) {
|
|
5679
|
+
const output = {};
|
|
5680
|
+
for (const raw of value.split(/\r?\n/)) {
|
|
5681
|
+
const line = raw.trim();
|
|
5682
|
+
if (!line) continue;
|
|
5683
|
+
const index = line.indexOf("=");
|
|
5684
|
+
if (index < 1 || !line.slice(index + 1).trim()) {
|
|
5685
|
+
throw new Error(label === "Workspace \u6620\u5C04" ? "Workspace \u6620\u5C04\u6BCF\u884C\u5FC5\u987B\u4F7F\u7528 alias=value" : "Instruction Preset \u6620\u5C04\u6BCF\u884C\u5FC5\u987B\u4F7F\u7528 alias=value");
|
|
5686
|
+
}
|
|
5687
|
+
output[line.slice(0, index).trim()] = line.slice(index + 1).trim();
|
|
5688
|
+
}
|
|
5689
|
+
return output;
|
|
5690
|
+
}
|
|
5691
|
+
function stateLabel(model) {
|
|
5692
|
+
if (model.connected) return "\u5DF2\u8FDE\u63A5 Office";
|
|
5693
|
+
if (!model.configured) return "\u5C1A\u672A\u914D\u7F6E";
|
|
5694
|
+
if (model.state === "connecting") return "\u6B63\u5728\u8FDE\u63A5";
|
|
5695
|
+
if (model.state === "reconnecting") return "\u7B49\u5F85\u91CD\u8FDE";
|
|
5696
|
+
if (model.state === "missing-token") return "\u51ED\u636E\u7F3A\u5931";
|
|
5697
|
+
return "\u5DF2\u914D\u7F6E";
|
|
5698
|
+
}
|
|
5699
|
+
function OfficeSettingsTab({ rpcCall, initialStatus }) {
|
|
5700
|
+
const [model, setModel] = React12.useState(normalizeOfficeStatus(initialStatus));
|
|
5701
|
+
const [phase, setPhase] = React12.useState(initialStatus === void 0 ? "loading" : "ready");
|
|
5702
|
+
const [busy, setBusy] = React12.useState("");
|
|
5703
|
+
const [error, setError] = React12.useState("");
|
|
5704
|
+
const [notice, setNotice] = React12.useState("");
|
|
5705
|
+
const [form, setForm] = React12.useState({
|
|
5706
|
+
baseUrl: "",
|
|
5707
|
+
deviceId: "local-harness",
|
|
5708
|
+
deviceToken: "",
|
|
5709
|
+
maxConcurrency: "1",
|
|
5710
|
+
heartbeatSeconds: "30",
|
|
5711
|
+
workspaces: "",
|
|
5712
|
+
instructionPresets: ""
|
|
5713
|
+
});
|
|
5714
|
+
const invoke = React12.useCallback(async (endpoint, payload = {}) => {
|
|
5715
|
+
if (typeof rpcCall !== "function") throw new Error("AI Office \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
5716
|
+
return unwrapOfficeRpc(await rpcCall(endpoint, payload));
|
|
5717
|
+
}, [rpcCall]);
|
|
5718
|
+
const adopt = React12.useCallback((value) => {
|
|
5719
|
+
const next = normalizeOfficeStatus(value?.snapshot ?? value);
|
|
5720
|
+
setModel(next);
|
|
5721
|
+
if (next.config) setForm((current) => ({
|
|
5722
|
+
...current,
|
|
5723
|
+
baseUrl: next.config.baseUrl,
|
|
5724
|
+
deviceId: next.config.deviceId,
|
|
5725
|
+
maxConcurrency: String(next.config.maxConcurrency),
|
|
5726
|
+
heartbeatSeconds: String(next.config.heartbeatSeconds),
|
|
5727
|
+
workspaces: mapText(next.config.workspaces),
|
|
5728
|
+
instructionPresets: mapText(next.config.instructionPresets),
|
|
5729
|
+
deviceToken: ""
|
|
5730
|
+
}));
|
|
5731
|
+
return next;
|
|
5732
|
+
}, []);
|
|
5733
|
+
const load = React12.useCallback(async () => {
|
|
5734
|
+
try {
|
|
5735
|
+
adopt(await invoke(OFFICE_RPC_ENDPOINTS.status));
|
|
5736
|
+
setPhase("ready");
|
|
5737
|
+
setError("");
|
|
5738
|
+
} catch (caught) {
|
|
5739
|
+
setPhase("error");
|
|
5740
|
+
setError(caught.message);
|
|
5741
|
+
}
|
|
5742
|
+
}, [adopt, invoke]);
|
|
5743
|
+
React12.useEffect(() => {
|
|
5744
|
+
void load();
|
|
5745
|
+
}, [load]);
|
|
5746
|
+
const run = async (name2, operation) => {
|
|
5747
|
+
setBusy(name2);
|
|
5748
|
+
setError("");
|
|
5749
|
+
setNotice("");
|
|
5750
|
+
try {
|
|
5751
|
+
const value = await operation();
|
|
5752
|
+
adopt(value);
|
|
5753
|
+
setNotice(name2 === "test" ? "\u8FDE\u63A5\u6D4B\u8BD5\u901A\u8FC7\u3002" : "\u914D\u7F6E\u5DF2\u4FDD\u5B58\u3002");
|
|
5754
|
+
} catch (caught) {
|
|
5755
|
+
setError(caught.message);
|
|
5756
|
+
} finally {
|
|
5757
|
+
setBusy("");
|
|
5758
|
+
}
|
|
5759
|
+
};
|
|
5760
|
+
const hooks = React12.useMemo(() => {
|
|
5761
|
+
try {
|
|
5762
|
+
return officeHookUrls(form.baseUrl);
|
|
5763
|
+
} catch {
|
|
5764
|
+
return {};
|
|
5765
|
+
}
|
|
5766
|
+
}, [form.baseUrl]);
|
|
5767
|
+
const health = model.health ?? {};
|
|
5768
|
+
if (phase === "loading") return h2("div", { className: "ddt-card ddt-loading", "aria-busy": "true" }, "\u6B63\u5728\u8BFB\u53D6 AI Office Connector\u2026");
|
|
5769
|
+
return h2(
|
|
5770
|
+
"section",
|
|
5771
|
+
{ className: "dof-page", "aria-label": "AI Office \u8BBE\u7F6E" },
|
|
5772
|
+
h2(
|
|
5773
|
+
"div",
|
|
5774
|
+
{ className: "dof-hero" },
|
|
5775
|
+
h2(
|
|
5776
|
+
"div",
|
|
5777
|
+
{ className: "dof-heroCopy" },
|
|
5778
|
+
h2("h3", null, "AI Office Connector"),
|
|
5779
|
+
h2("p", null, "\u672C\u673A\u4E3B\u52A8\u8FDE\u63A5\u516C\u7F51 Office\uFF1BHarness \u4E0D\u5F00\u653E\u7AEF\u53E3\u3002\u534F\u8BAE Hook \u56FA\u5B9A\u4E3A ", OFFICE_PROTOCOL_VERSION, "\u3002")
|
|
5780
|
+
),
|
|
5781
|
+
h2(
|
|
5782
|
+
"span",
|
|
5783
|
+
{ className: "dof-status", "data-connected": String(model.connected) },
|
|
5784
|
+
h2("span", { className: "dof-dot" }),
|
|
5785
|
+
stateLabel(model)
|
|
5786
|
+
)
|
|
5787
|
+
),
|
|
5788
|
+
model.configured ? h2(
|
|
5789
|
+
"div",
|
|
5790
|
+
{ className: "dof-metrics" },
|
|
5791
|
+
h2("div", { className: "dof-metric" }, h2("span", null, "\u6700\u8FD1\u5FC3\u8DF3"), h2("strong", null, health.lastHeartbeatAt ?? "\u5C1A\u65E0")),
|
|
5792
|
+
h2("div", { className: "dof-metric" }, h2("span", null, "\u6700\u8FD1\u4E8B\u4EF6"), h2("strong", null, health.lastEventType ?? "\u5C1A\u65E0")),
|
|
5793
|
+
h2("div", { className: "dof-metric" }, h2("span", null, "\u91CD\u8FDE\u6B21\u6570"), h2("strong", null, String(health.reconnects ?? 0))),
|
|
5794
|
+
h2("div", { className: "dof-metric" }, h2("span", null, "Job Offer"), h2("strong", null, String(health.jobsOffered ?? 0))),
|
|
5795
|
+
h2("div", { className: "dof-metric" }, h2("span", null, "\u8FD0\u884C Job"), h2("strong", null, String(health.jobs?.running ?? 0))),
|
|
5796
|
+
h2("div", { className: "dof-metric" }, h2("span", null, "\u5B8C\u6210 Job"), h2("strong", null, String(health.jobs?.completed ?? 0)))
|
|
5797
|
+
) : null,
|
|
5798
|
+
h2(
|
|
5799
|
+
"div",
|
|
5800
|
+
{ className: "dof-card" },
|
|
5801
|
+
h2("div", { className: "dof-cardTitle" }, h2("h4", null, "\u8BBE\u5907\u8FDE\u63A5"), h2("span", null, "Token \u53EA\u5199\u5165\u672C\u673A\u51ED\u636E\u5B58\u50A8")),
|
|
5802
|
+
h2(
|
|
5803
|
+
"div",
|
|
5804
|
+
{ className: "dof-grid" },
|
|
5805
|
+
h2(
|
|
5806
|
+
"label",
|
|
5807
|
+
{ className: "dof-field", "data-wide": "true" },
|
|
5808
|
+
"Office Base URL",
|
|
5809
|
+
h2("input", { value: form.baseUrl, placeholder: "https://office.example.com", onChange: (event) => setForm({ ...form, baseUrl: event.target.value }) })
|
|
5810
|
+
),
|
|
5811
|
+
h2(
|
|
5812
|
+
"label",
|
|
5813
|
+
{ className: "dof-field" },
|
|
5814
|
+
"Device ID",
|
|
5815
|
+
h2("input", { value: form.deviceId, placeholder: "local-harness", onChange: (event) => setForm({ ...form, deviceId: event.target.value }) })
|
|
5816
|
+
),
|
|
5817
|
+
h2(
|
|
5818
|
+
"label",
|
|
5819
|
+
{ className: "dof-field" },
|
|
5820
|
+
"Device Token",
|
|
5821
|
+
h2("input", { type: "password", value: form.deviceToken, placeholder: model.tokenConfigured ? "\u5DF2\u5B89\u5168\u4FDD\u5B58\uFF1B\u7559\u7A7A\u4FDD\u6301\u4E0D\u53D8" : "\u7C98\u8D34 Office \u4E00\u6B21\u6027\u51ED\u636E", autoComplete: "new-password", onChange: (event) => setForm({ ...form, deviceToken: event.target.value }) })
|
|
5822
|
+
),
|
|
5823
|
+
h2(
|
|
5824
|
+
"label",
|
|
5825
|
+
{ className: "dof-field" },
|
|
5826
|
+
"\u6700\u5927\u5E76\u53D1",
|
|
5827
|
+
h2("input", { type: "number", min: 1, max: 4, value: form.maxConcurrency, onChange: (event) => setForm({ ...form, maxConcurrency: event.target.value }) })
|
|
5828
|
+
),
|
|
5829
|
+
h2(
|
|
5830
|
+
"label",
|
|
5831
|
+
{ className: "dof-field" },
|
|
5832
|
+
"Heartbeat \u79D2\u6570",
|
|
5833
|
+
h2("input", { type: "number", min: 10, max: 300, value: form.heartbeatSeconds, onChange: (event) => setForm({ ...form, heartbeatSeconds: event.target.value }) })
|
|
5834
|
+
),
|
|
5835
|
+
h2(
|
|
5836
|
+
"label",
|
|
5837
|
+
{ className: "dof-field", "data-wide": "true" },
|
|
5838
|
+
"Workspace \u6620\u5C04",
|
|
5839
|
+
h2("textarea", { value: form.workspaces, placeholder: "office-project=/Users/you/projects/ai-office", onChange: (event) => setForm({ ...form, workspaces: event.target.value }) }),
|
|
5840
|
+
h2("small", null, "\u6BCF\u884C alias=/\u672C\u673A/\u7EDD\u5BF9\u8DEF\u5F84\uFF1BOffice \u53EA\u80FD\u770B\u5230 alias\u3002")
|
|
5841
|
+
),
|
|
5842
|
+
h2(
|
|
5843
|
+
"label",
|
|
5844
|
+
{ className: "dof-field", "data-wide": "true" },
|
|
5845
|
+
"Instruction Preset \u6620\u5C04",
|
|
5846
|
+
h2("textarea", { value: form.instructionPresets, placeholder: "action-items=\u8F6C\u6362\u4E3A\u8D1F\u8D23\u4EBA\u3001\u622A\u6B62\u548C\u9A8C\u6536\u660E\u786E\u7684\u5DE5\u5355", onChange: (event) => setForm({ ...form, instructionPresets: event.target.value }) }),
|
|
5847
|
+
h2("small", null, "\u6BCF\u884C alias=\u6307\u4EE4\uFF1B\u65B0\u589E preset \u4E0D\u9700\u8981\u6539 Office \u4EE3\u7801\u3002")
|
|
5848
|
+
)
|
|
5849
|
+
),
|
|
5850
|
+
error ? h2("p", { className: "dof-error", role: "alert" }, error) : null,
|
|
5851
|
+
notice ? h2("p", { className: "dof-notice", role: "status" }, notice) : null,
|
|
5852
|
+
health.error?.message ? h2("p", { className: "dof-error" }, health.error.message) : null,
|
|
5853
|
+
h2(
|
|
5854
|
+
"div",
|
|
5855
|
+
{ className: "dof-actions" },
|
|
5856
|
+
h2(Button9, { kind: "primary", disabled: Boolean(busy), onClick: () => void run("save", () => invoke(OFFICE_RPC_ENDPOINTS.configure, {
|
|
5857
|
+
baseUrl: form.baseUrl,
|
|
5858
|
+
deviceId: form.deviceId,
|
|
5859
|
+
...form.deviceToken ? { deviceToken: form.deviceToken } : {},
|
|
5860
|
+
maxConcurrency: Number(form.maxConcurrency),
|
|
5861
|
+
heartbeatSeconds: Number(form.heartbeatSeconds),
|
|
5862
|
+
workspaces: parseMap(form.workspaces, "Workspace \u6620\u5C04"),
|
|
5863
|
+
instructionPresets: parseMap(form.instructionPresets, "Instruction Preset \u6620\u5C04")
|
|
5864
|
+
})) }, busy === "save" ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u5E76\u8FDE\u63A5"),
|
|
5865
|
+
h2(Button9, { disabled: !model.configured || Boolean(busy), onClick: () => void run("test", () => invoke(OFFICE_RPC_ENDPOINTS.test)) }, busy === "test" ? "\u6D4B\u8BD5\u4E2D\u2026" : "\u6D4B\u8BD5\u8FDE\u63A5"),
|
|
5866
|
+
h2(Button9, { disabled: !model.configured || Boolean(busy), onClick: () => void run("reconnect", () => invoke(OFFICE_RPC_ENDPOINTS.reconnect)) }, "\u91CD\u65B0\u8FDE\u63A5"),
|
|
5867
|
+
h2(Button9, { kind: "danger", disabled: !model.configured || Boolean(busy), onClick: () => void run("remove", () => invoke(OFFICE_RPC_ENDPOINTS.remove, { confirm: true })) }, "\u79FB\u9664\u8FDE\u63A5")
|
|
5868
|
+
)
|
|
5869
|
+
),
|
|
5870
|
+
h2(
|
|
5871
|
+
"div",
|
|
5872
|
+
{ className: "dof-card" },
|
|
5873
|
+
h2("div", { className: "dof-cardTitle" }, h2("h4", null, "\u534F\u8BAE Hook \u9884\u89C8"), h2("span", null, "\u7531 Base URL \u81EA\u52A8\u6D3E\u751F\uFF0C\u4E0D\u5355\u72EC\u586B\u5199")),
|
|
5874
|
+
h2(
|
|
5875
|
+
"div",
|
|
5876
|
+
{ className: "dof-hooks" },
|
|
5877
|
+
[["SSE", hooks.stream], ["Heartbeat", hooks.heartbeat], ["Job", hooks.job], ["Result", hooks.result]].map(([label, url]) => h2("div", { className: "dof-hook", key: label }, h2("strong", null, label), h2("code", null, url ?? "Base URL \u65E0\u6548")))
|
|
5878
|
+
)
|
|
5879
|
+
),
|
|
5880
|
+
h2("p", { className: "dof-notice" }, "Office Hook \u5C1A\u672A\u90E8\u7F72\u65F6\uFF0C\u914D\u7F6E\u4F1A\u5B89\u5168\u4FDD\u5B58\u5E76\u81EA\u52A8\u91CD\u8BD5\uFF1B\u51FA\u73B0 HTTP 404 \u4EE3\u8868\u534F\u8BAE\u7AEF\u70B9\u5F85\u4E0A\u7EBF\uFF0C\u4E0D\u4EE3\u8868 Harness \u6545\u969C\u3002")
|
|
5881
|
+
);
|
|
5882
|
+
}
|
|
5883
|
+
|
|
5884
|
+
// plugin-src/client/channels/office/styles.js
|
|
5885
|
+
var OFFICE_STYLE_ID = "xmanrui-dsh-im-office-settings";
|
|
5886
|
+
var CSS5 = `
|
|
5887
|
+
.dof-page { --dof-accent: var(--dsw-alias-brand-primary, #3964fe); }
|
|
5888
|
+
.dof-hero { position: relative; overflow: hidden; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px; align-items: center; margin-bottom: 12px; padding: 18px; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 16px; background: linear-gradient(135deg, color-mix(in srgb, var(--dof-accent) 9%, var(--dsw-alias-bg-layer-1, #fff)), var(--dsw-alias-bg-layer-1, #fff) 62%); }
|
|
5889
|
+
.dof-hero::after { content: ""; position: absolute; width: 150px; height: 150px; right: -75px; top: -90px; border: 24px solid color-mix(in srgb, var(--dof-accent) 12%, transparent); border-radius: 50%; pointer-events: none; }
|
|
5890
|
+
.dof-heroCopy { min-width: 0; }
|
|
5891
|
+
.dof-heroCopy h3 { margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 17px; line-height: 1.35; }
|
|
5892
|
+
.dof-heroCopy p { margin: 6px 0 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 1.6; }
|
|
5893
|
+
.dof-status { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 7px; padding: 7px 10px; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 999px; background: var(--dsw-alias-bg-layer-1, #fff); color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; white-space: nowrap; }
|
|
5894
|
+
.dof-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--dsw-alias-state-warn-primary, #d97706); }
|
|
5895
|
+
.dof-status[data-connected="true"] .dof-dot { background: var(--dsw-alias-state-success-primary, #20a162); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dsw-alias-state-success-primary, #20a162) 14%, transparent); }
|
|
5896
|
+
.dof-card { margin-top: 10px; padding: 16px; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); border-radius: 14px; background: var(--dsw-alias-bg-layer-1, #fff); }
|
|
5897
|
+
.dof-cardTitle { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; margin-bottom: 12px; }
|
|
5898
|
+
.dof-cardTitle h4 { margin: 0; color: var(--dsw-alias-label-primary, #1f2329); font-size: 14px; }
|
|
5899
|
+
.dof-cardTitle span { color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 11px; }
|
|
5900
|
+
.dof-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
|
|
5901
|
+
.dof-field { min-width: 0; display: flex; flex-direction: column; gap: 6px; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; }
|
|
5902
|
+
.dof-field[data-wide="true"] { grid-column: 1 / -1; }
|
|
5903
|
+
.dof-field input, .dof-field textarea { box-sizing: border-box; width: 100%; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; background: var(--dsw-alias-bg-layer-1, #fff); color: var(--dsw-alias-label-primary, #1f2329); font: inherit; font-size: 13px; line-height: 1.5; outline: none; }
|
|
5904
|
+
.dof-field input { height: 38px; padding: 0 11px; }
|
|
5905
|
+
.dof-field textarea { min-height: 86px; resize: vertical; padding: 9px 11px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
5906
|
+
.dof-field input:focus, .dof-field textarea:focus { border-color: var(--dof-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dof-accent) 12%, transparent); }
|
|
5907
|
+
.dof-field small { color: var(--dsw-alias-label-tertiary, #8f959e); line-height: 1.45; }
|
|
5908
|
+
.dof-hooks { display: grid; gap: 7px; }
|
|
5909
|
+
.dof-hook { min-width: 0; display: grid; grid-template-columns: 82px minmax(0, 1fr); gap: 10px; align-items: center; padding: 8px 10px; border-radius: 9px; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
|
|
5910
|
+
.dof-hook strong { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; }
|
|
5911
|
+
.dof-hook code { overflow: hidden; color: var(--dsw-alias-label-primary, #1f2329); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
|
|
5912
|
+
.dof-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
|
|
5913
|
+
.dof-actions .ddt-button[data-kind="primary"] { color: #fff; border-color: var(--dof-accent); background: var(--dof-accent); }
|
|
5914
|
+
.dof-error, .dof-notice { margin: 10px 0 0; padding: 9px 11px; border-radius: 9px; font-size: 12px; line-height: 1.5; }
|
|
5915
|
+
.dof-error { color: var(--dsw-alias-state-error-primary, #d54941); background: var(--dsw-alias-state-error-secondary, #fff0ef); }
|
|
5916
|
+
.dof-notice { color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
|
|
5917
|
+
.dof-metrics { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 12px; }
|
|
5918
|
+
.dof-metric { min-width: 0; padding: 9px; border-radius: 10px; background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
|
|
5919
|
+
.dof-metric span { display: block; color: var(--dsw-alias-label-tertiary, #8f959e); font-size: 10px; }
|
|
5920
|
+
.dof-metric strong { display: block; overflow: hidden; margin-top: 4px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
|
|
5921
|
+
@container (max-width: 680px) { .dof-grid { grid-template-columns: minmax(0, 1fr); } .dof-field[data-wide="true"] { grid-column: auto; } .dof-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
|
5922
|
+
@media (prefers-reduced-motion: reduce) { .dof-page * { transition: none !important; } }
|
|
5923
|
+
`;
|
|
5924
|
+
function installOfficeStyles() {
|
|
5925
|
+
if (typeof document === "undefined") return () => {
|
|
5926
|
+
};
|
|
5927
|
+
if (document.querySelector(`style[data-plugin-css="${OFFICE_STYLE_ID}"]`)) return () => {
|
|
5928
|
+
};
|
|
5929
|
+
const style = document.createElement("style");
|
|
5930
|
+
style.dataset.pluginCss = OFFICE_STYLE_ID;
|
|
5931
|
+
style.textContent = CSS5;
|
|
5932
|
+
document.head.append(style);
|
|
5933
|
+
return () => style.remove();
|
|
5934
|
+
}
|
|
5935
|
+
|
|
5493
5936
|
// plugin-src/client/channels/slack/api.js
|
|
5494
5937
|
var SLACK_RPC_CHANNEL = "/slack";
|
|
5495
5938
|
var SLACK_ENDPOINTS = TOKEN_BOT_ENDPOINTS;
|
|
@@ -5499,7 +5942,7 @@ var normalizeSnapshot4 = api2.normalizeSnapshot;
|
|
|
5499
5942
|
var presentError5 = api2.presentError;
|
|
5500
5943
|
|
|
5501
5944
|
// plugin-src/client/channels/slack/index.js
|
|
5502
|
-
var
|
|
5945
|
+
var React13 = __toESM(require("react"), 1);
|
|
5503
5946
|
|
|
5504
5947
|
// src/channels/slack/manifest.mjs
|
|
5505
5948
|
var SLACK_APP_MANIFEST_YAML = `_metadata:
|
|
@@ -5536,7 +5979,7 @@ var SLACK_CREATE_APP_URL = "https://api.slack.com/apps?new_app=1";
|
|
|
5536
5979
|
|
|
5537
5980
|
// plugin-src/client/channels/slack/styles.js
|
|
5538
5981
|
var SLACK_STYLE_ID = "xmanrui-dsh-im-slack-settings";
|
|
5539
|
-
var
|
|
5982
|
+
var CSS6 = String.raw`
|
|
5540
5983
|
.dsl-page { --ddt-accent: #4a154b; --ddt-accent-deep: #321033; --ddt-accent-wash: #f7eef7; }
|
|
5541
5984
|
.dsl-avatar { color: #fff; background: #4a154b; }
|
|
5542
5985
|
.dsl-avatar svg { display: block; }
|
|
@@ -5565,17 +6008,17 @@ function installSlackStyles() {
|
|
|
5565
6008
|
const style = document.createElement("style");
|
|
5566
6009
|
style.dataset.plugin = "@xmanrui/dsh-im";
|
|
5567
6010
|
style.dataset.pluginCss = SLACK_STYLE_ID;
|
|
5568
|
-
style.textContent =
|
|
6011
|
+
style.textContent = CSS6;
|
|
5569
6012
|
document.head.appendChild(style);
|
|
5570
6013
|
return () => style.remove();
|
|
5571
6014
|
}
|
|
5572
6015
|
|
|
5573
6016
|
// plugin-src/client/channels/slack/index.js
|
|
5574
6017
|
function SlackCredentialPanel({ busy, error, onSubmit, onCancel }) {
|
|
5575
|
-
const [botToken, setBotToken] =
|
|
5576
|
-
const [appToken, setAppToken] =
|
|
5577
|
-
const [copied, setCopied] =
|
|
5578
|
-
const headingId =
|
|
6018
|
+
const [botToken, setBotToken] = React13.useState("");
|
|
6019
|
+
const [appToken, setAppToken] = React13.useState("");
|
|
6020
|
+
const [copied, setCopied] = React13.useState(false);
|
|
6021
|
+
const headingId = React13.useId();
|
|
5579
6022
|
const copyManifest = async () => {
|
|
5580
6023
|
try {
|
|
5581
6024
|
await navigator.clipboard.writeText(SLACK_APP_MANIFEST_YAML);
|
|
@@ -5714,18 +6157,57 @@ var SlackAccountCard = channel2.AccountCard;
|
|
|
5714
6157
|
|
|
5715
6158
|
// plugin-src/client/channels/telegram/api.js
|
|
5716
6159
|
var TELEGRAM_RPC_CHANNEL = "/telegram";
|
|
5717
|
-
var TELEGRAM_ENDPOINTS =
|
|
5718
|
-
|
|
6160
|
+
var TELEGRAM_ENDPOINTS = Object.freeze({
|
|
6161
|
+
...TOKEN_BOT_ENDPOINTS,
|
|
6162
|
+
setAccessPolicy: "bot.access-policy.set"
|
|
6163
|
+
});
|
|
6164
|
+
var api3 = createTokenChannelApi("Telegram", " Bot API \u957F\u8F6E\u8BE2", {
|
|
6165
|
+
normalizeBotExtension: (value) => {
|
|
6166
|
+
const source = value?.accessPolicy;
|
|
6167
|
+
const accessMode = source?.accessMode === "private-allowlist" ? "private-allowlist" : "compatible";
|
|
6168
|
+
const allowedUsers = Array.isArray(source?.allowedUsers) ? [...new Set(source.allowedUsers.filter((entry) => typeof entry === "string" && /^[1-9]\d{0,15}$/.test(entry)))] : [];
|
|
6169
|
+
return { accessPolicy: { accessMode, allowedUsers } };
|
|
6170
|
+
}
|
|
6171
|
+
});
|
|
5719
6172
|
var unwrapRpcResult6 = api3.unwrapRpcResult;
|
|
5720
6173
|
var normalizeSnapshot5 = api3.normalizeSnapshot;
|
|
5721
6174
|
var presentError6 = api3.presentError;
|
|
5722
6175
|
|
|
6176
|
+
// plugin-src/client/channels/telegram/index.js
|
|
6177
|
+
var React14 = __toESM(require("react"), 1);
|
|
6178
|
+
|
|
5723
6179
|
// plugin-src/client/channels/telegram/styles.js
|
|
5724
6180
|
var TELEGRAM_STYLE_ID = "xmanrui-dsh-im-telegram-settings";
|
|
5725
|
-
var
|
|
6181
|
+
var CSS7 = String.raw`
|
|
5726
6182
|
.dtg-page { --ddt-accent: #229ed9; --ddt-accent-deep: #1687bd; --ddt-accent-wash: #eaf7fd; }
|
|
5727
6183
|
.dtg-avatar { color: #fff; background: #229ed9; }
|
|
5728
6184
|
.dtg-avatar svg { display: block; }
|
|
6185
|
+
.dtg-access { display: grid; gap: 10px; padding: 12px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 10px; background: var(--dsw-alias-bg-layer-2, #f7f8fa); }
|
|
6186
|
+
.dtg-accessHeading { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
|
6187
|
+
.dtg-accessHeading > strong { font-size: 13px; }
|
|
6188
|
+
.dtg-accessStatus { min-width: 0; display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; }
|
|
6189
|
+
.dtg-accessBadge { flex: none; padding: 3px 8px; border-radius: 999px; color: #1687bd; background: #eaf7fd; font-size: 11px; font-weight: 700; }
|
|
6190
|
+
.dtg-accessBadge[data-mode="private-allowlist"] { color: #a15c00; background: #fff3d6; }
|
|
6191
|
+
.dtg-accessHelp { position: relative; display: inline-flex; flex: none; }
|
|
6192
|
+
.dtg-accessHelpButton { width: 20px; height: 20px; display: grid; place-items: center; padding: 0; border: 1px solid color-mix(in srgb, #229ed9 28%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 50%; color: #1687bd; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 12px; line-height: 1; font-weight: 750; cursor: help; transition: border-color .15s ease, color .15s ease, background .15s ease, box-shadow .15s ease; }
|
|
6193
|
+
.dtg-accessHelpButton:hover { border-color: #229ed9; color: #1178a8; background: #eaf7fd; }
|
|
6194
|
+
.dtg-accessHelpButton:focus-visible { outline: none; border-color: #229ed9; box-shadow: 0 0 0 3px color-mix(in srgb, #229ed9 18%, transparent); }
|
|
6195
|
+
.dtg-accessTooltip { position: absolute; top: calc(100% + 8px); right: 0; z-index: 30; width: 260px; max-width: min(280px, calc(100vw - 48px)); display: grid; gap: 8px; padding: 10px 11px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 10px 28px rgb(31 35 41 / 16%); opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
|
|
6196
|
+
.dtg-accessTooltipItem { display: grid; gap: 2px; }
|
|
6197
|
+
.dtg-accessTooltipItem + .dtg-accessTooltipItem { padding-top: 8px; border-top: 1px solid var(--dsw-alias-border-l2, #eef0f3); }
|
|
6198
|
+
.dtg-accessTooltipItem strong { color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; line-height: 17px; font-weight: 700; }
|
|
6199
|
+
.dtg-accessTooltipItem > span { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 16px; font-weight: 400; }
|
|
6200
|
+
.dtg-accessHelp:hover .dtg-accessTooltip, .dtg-accessHelp:focus-within .dtg-accessTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
6201
|
+
.dtg-accessField { display: grid; gap: 5px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; font-weight: 600; }
|
|
6202
|
+
.dtg-accessField select, .dtg-accessField textarea { width: 100%; box-sizing: border-box; border: 1px solid var(--dsw-alias-border-l1, #c9cdd4); border-radius: 7px; color: inherit; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-weight: 400; }
|
|
6203
|
+
.dtg-accessField select { height: 34px; padding: 0 9px; }
|
|
6204
|
+
.dtg-accessField textarea { min-height: 68px; padding: 8px 9px; resize: vertical; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
6205
|
+
.dtg-accessField textarea:disabled { color: var(--dsw-alias-label-tertiary, #8f959e); background: var(--dsw-alias-bg-module-platform, #f2f3f5); cursor: not-allowed; resize: none; opacity: 1; }
|
|
6206
|
+
.dtg-accessField small { color: var(--dsw-alias-label-secondary, #646a73); font-weight: 400; }
|
|
6207
|
+
.dtg-accessWarning, .dtg-accessError { margin: 0; font-size: 12px; line-height: 1.5; }
|
|
6208
|
+
.dtg-accessWarning { color: #a15c00; }
|
|
6209
|
+
.dtg-accessError { color: var(--dsw-alias-state-error-primary, #d83931); }
|
|
6210
|
+
.dtg-accessActions { display: flex; justify-content: flex-end; }
|
|
5729
6211
|
`;
|
|
5730
6212
|
function installTelegramStyles() {
|
|
5731
6213
|
if (typeof document === "undefined") return () => {
|
|
@@ -5736,12 +6218,152 @@ function installTelegramStyles() {
|
|
|
5736
6218
|
const style = document.createElement("style");
|
|
5737
6219
|
style.dataset.plugin = "@xmanrui/dsh-im";
|
|
5738
6220
|
style.dataset.pluginCss = TELEGRAM_STYLE_ID;
|
|
5739
|
-
style.textContent =
|
|
6221
|
+
style.textContent = CSS7;
|
|
5740
6222
|
document.head.appendChild(style);
|
|
5741
6223
|
return () => style.remove();
|
|
5742
6224
|
}
|
|
5743
6225
|
|
|
5744
6226
|
// plugin-src/client/channels/telegram/index.js
|
|
6227
|
+
function policyFor(account) {
|
|
6228
|
+
return {
|
|
6229
|
+
accessMode: account?.accessPolicy?.accessMode === "private-allowlist" ? "private-allowlist" : "compatible",
|
|
6230
|
+
allowedUsers: Array.isArray(account?.accessPolicy?.allowedUsers) ? account.accessPolicy.allowedUsers : []
|
|
6231
|
+
};
|
|
6232
|
+
}
|
|
6233
|
+
function allowedUsersFromText(value) {
|
|
6234
|
+
const entries = value.split(/\r?\n/).map((entry) => entry.trim()).filter(Boolean);
|
|
6235
|
+
if (entries.some((entry) => !/^[1-9]\d{0,15}$/.test(entry))) {
|
|
6236
|
+
throw new TypeError("User ID \u5FC5\u987B\u662F 1\u201316 \u4F4D\u6B63\u6574\u6570\uFF0C\u6BCF\u884C\u4E00\u4E2A\u3002");
|
|
6237
|
+
}
|
|
6238
|
+
return [...new Set(entries)];
|
|
6239
|
+
}
|
|
6240
|
+
function TelegramAccessSettings({ account, busy = false, onSave }) {
|
|
6241
|
+
const policy = policyFor(account);
|
|
6242
|
+
const sourceUsers = policy.allowedUsers.join("\n");
|
|
6243
|
+
const accessHelpId = React14.useId();
|
|
6244
|
+
const [accessMode, setAccessMode] = React14.useState(policy.accessMode);
|
|
6245
|
+
const [allowedUsers, setAllowedUsers] = React14.useState(sourceUsers);
|
|
6246
|
+
const [error, setError] = React14.useState(null);
|
|
6247
|
+
React14.useEffect(() => {
|
|
6248
|
+
setAccessMode(policy.accessMode);
|
|
6249
|
+
setAllowedUsers(sourceUsers);
|
|
6250
|
+
setError(null);
|
|
6251
|
+
}, [policy.accessMode, sourceUsers]);
|
|
6252
|
+
const save = async (event) => {
|
|
6253
|
+
event.preventDefault();
|
|
6254
|
+
setError(null);
|
|
6255
|
+
try {
|
|
6256
|
+
const normalized = allowedUsersFromText(allowedUsers);
|
|
6257
|
+
if (typeof onSave !== "function") throw new Error("Telegram \u8BBF\u95EE\u8BBE\u7F6E\u6682\u4E0D\u53EF\u7528\u3002");
|
|
6258
|
+
await onSave({ accessMode, allowedUsers: normalized });
|
|
6259
|
+
} catch (caught) {
|
|
6260
|
+
setError(caught?.message ?? "Telegram \u8BBF\u95EE\u8BBE\u7F6E\u4FDD\u5B58\u5931\u8D25\u3002");
|
|
6261
|
+
}
|
|
6262
|
+
};
|
|
6263
|
+
const privateAllowlist = accessMode === "private-allowlist";
|
|
6264
|
+
const savedPrivateAllowlist = policy.accessMode === "private-allowlist";
|
|
6265
|
+
const emptyAllowlist = privateAllowlist && allowedUsers.trim() === "";
|
|
6266
|
+
return h2(
|
|
6267
|
+
"form",
|
|
6268
|
+
{ className: "dtg-access", onSubmit: save },
|
|
6269
|
+
h2(
|
|
6270
|
+
"div",
|
|
6271
|
+
{ className: "dtg-accessHeading" },
|
|
6272
|
+
h2("strong", null, "\u8BBF\u95EE\u8BBE\u7F6E"),
|
|
6273
|
+
h2(
|
|
6274
|
+
"span",
|
|
6275
|
+
{ className: "dtg-accessStatus" },
|
|
6276
|
+
h2(
|
|
6277
|
+
"span",
|
|
6278
|
+
{ className: "dtg-accessBadge", "data-mode": policy.accessMode },
|
|
6279
|
+
savedPrivateAllowlist ? "\u5DF2\u751F\u6548\uFF1A\u5B89\u5168\u6A21\u5F0F" : "\u5DF2\u751F\u6548\uFF1A\u517C\u5BB9\u6A21\u5F0F"
|
|
6280
|
+
),
|
|
6281
|
+
h2(
|
|
6282
|
+
"span",
|
|
6283
|
+
{ className: "dtg-accessHelp" },
|
|
6284
|
+
h2("button", {
|
|
6285
|
+
type: "button",
|
|
6286
|
+
className: "dtg-accessHelpButton",
|
|
6287
|
+
"aria-label": "\u67E5\u770B Telegram \u8BBF\u95EE\u6A21\u5F0F\u8BF4\u660E",
|
|
6288
|
+
"aria-describedby": accessHelpId
|
|
6289
|
+
}, h2("span", { "aria-hidden": "true" }, "?")),
|
|
6290
|
+
h2(
|
|
6291
|
+
"span",
|
|
6292
|
+
{
|
|
6293
|
+
id: accessHelpId,
|
|
6294
|
+
className: "dtg-accessTooltip",
|
|
6295
|
+
role: "tooltip"
|
|
6296
|
+
},
|
|
6297
|
+
h2(
|
|
6298
|
+
"span",
|
|
6299
|
+
{ className: "dtg-accessTooltipItem" },
|
|
6300
|
+
h2("strong", null, "\u517C\u5BB9\u6A21\u5F0F"),
|
|
6301
|
+
h2("span", null, "\u4FDD\u6301\u539F\u6709\u884C\u4E3A\uFF1A\u79C1\u804A\u76F4\u63A5\u54CD\u5E94\uFF0C\u7FA4\u804A\u5728\u88AB\u63D0\u53CA\u6216\u56DE\u590D\u65F6\u54CD\u5E94\u3002")
|
|
6302
|
+
),
|
|
6303
|
+
h2(
|
|
6304
|
+
"span",
|
|
6305
|
+
{ className: "dtg-accessTooltipItem" },
|
|
6306
|
+
h2("strong", null, "\u5B89\u5168\u6A21\u5F0F"),
|
|
6307
|
+
h2("span", null, "\u7FA4\u804A\u5168\u90E8\u5FFD\u7565\uFF0C\u79C1\u804A\u4EC5\u5141\u8BB8\u767D\u540D\u5355\u7528\u6237\u3002")
|
|
6308
|
+
)
|
|
6309
|
+
)
|
|
6310
|
+
)
|
|
6311
|
+
)
|
|
6312
|
+
),
|
|
6313
|
+
h2(
|
|
6314
|
+
"label",
|
|
6315
|
+
{ className: "dtg-accessField" },
|
|
6316
|
+
h2("span", null, "\u6A21\u5F0F"),
|
|
6317
|
+
h2(
|
|
6318
|
+
"select",
|
|
6319
|
+
{
|
|
6320
|
+
value: accessMode,
|
|
6321
|
+
disabled: busy,
|
|
6322
|
+
"aria-label": "Telegram \u8BBF\u95EE\u6A21\u5F0F",
|
|
6323
|
+
onChange: (event) => {
|
|
6324
|
+
setAccessMode(event.target.value);
|
|
6325
|
+
setError(null);
|
|
6326
|
+
}
|
|
6327
|
+
},
|
|
6328
|
+
h2("option", { value: "compatible" }, "\u517C\u5BB9\u6A21\u5F0F\uFF08\u9ED8\u8BA4\uFF09"),
|
|
6329
|
+
h2("option", { value: "private-allowlist" }, "\u5B89\u5168\u6A21\u5F0F\uFF08\u79C1\u804A\u767D\u540D\u5355\uFF09")
|
|
6330
|
+
)
|
|
6331
|
+
),
|
|
6332
|
+
h2(
|
|
6333
|
+
"label",
|
|
6334
|
+
{ className: "dtg-accessField" },
|
|
6335
|
+
h2("span", null, "\u5141\u8BB8\u79C1\u804A\u7684 Telegram User ID"),
|
|
6336
|
+
h2("textarea", {
|
|
6337
|
+
value: allowedUsers,
|
|
6338
|
+
disabled: busy || !privateAllowlist,
|
|
6339
|
+
rows: 3,
|
|
6340
|
+
placeholder: "\u6BCF\u884C\u4E00\u4E2A\u6570\u5B57 User ID",
|
|
6341
|
+
"aria-label": "\u5141\u8BB8\u79C1\u804A\u7684 Telegram User ID",
|
|
6342
|
+
onChange: (event) => {
|
|
6343
|
+
setAllowedUsers(event.target.value);
|
|
6344
|
+
setError(null);
|
|
6345
|
+
}
|
|
6346
|
+
}),
|
|
6347
|
+
h2("small", null, privateAllowlist ? "\u767D\u540D\u5355\u4EC5\u5C5E\u4E8E\u5F53\u524D\u673A\u5668\u4EBA\u3002" : "\u517C\u5BB9\u6A21\u5F0F\u4E0B\u6682\u4E0D\u4F7F\u7528\u767D\u540D\u5355\uFF0C\u5207\u6362\u6A21\u5F0F\u65F6\u4F1A\u4FDD\u7559\u3002")
|
|
6348
|
+
),
|
|
6349
|
+
emptyAllowlist ? h2(
|
|
6350
|
+
"p",
|
|
6351
|
+
{ className: "dtg-accessWarning", role: "status" },
|
|
6352
|
+
"\u767D\u540D\u5355\u4E3A\u7A7A\uFF1B\u4FDD\u5B58\u540E\u8BE5\u673A\u5668\u4EBA\u4F1A\u62D2\u7EDD\u6240\u6709\u5165\u7AD9\u6D88\u606F\u3002"
|
|
6353
|
+
) : null,
|
|
6354
|
+
error ? h2("p", { className: "dtg-accessError", role: "alert" }, error) : null,
|
|
6355
|
+
h2(
|
|
6356
|
+
"div",
|
|
6357
|
+
{ className: "dtg-accessActions" },
|
|
6358
|
+
h2("button", {
|
|
6359
|
+
type: "submit",
|
|
6360
|
+
className: "ddt-button",
|
|
6361
|
+
"data-kind": "secondary",
|
|
6362
|
+
disabled: busy
|
|
6363
|
+
}, busy ? "\u6B63\u5728\u4FDD\u5B58\u2026" : "\u4FDD\u5B58\u8BBF\u95EE\u8BBE\u7F6E")
|
|
6364
|
+
)
|
|
6365
|
+
);
|
|
6366
|
+
}
|
|
5745
6367
|
var channel3 = createTokenChannelSettings({
|
|
5746
6368
|
channel: "Telegram",
|
|
5747
6369
|
endpoints: TELEGRAM_ENDPOINTS,
|
|
@@ -5754,7 +6376,9 @@ var channel3 = createTokenChannelSettings({
|
|
|
5754
6376
|
tokenPlaceholder: "\u586B\u5199 @BotFather \u751F\u6210\u7684 Bot Token",
|
|
5755
6377
|
emptyTitle: "\u63A5\u5165 Telegram \u673A\u5668\u4EBA",
|
|
5756
6378
|
emptyDescription: "\u5148\u901A\u8FC7 @BotFather \u83B7\u53D6 Bot Token\uFF0C\u518D\u5728\u8FD9\u91CC\u5B8C\u6210\u63A5\u5165\u3002",
|
|
5757
|
-
platformLabel: "Telegram"
|
|
6379
|
+
platformLabel: "Telegram",
|
|
6380
|
+
AccountSettings: TelegramAccessSettings,
|
|
6381
|
+
accountSettingsEndpoint: TELEGRAM_ENDPOINTS.setAccessPolicy
|
|
5758
6382
|
});
|
|
5759
6383
|
var TelegramSettingsTab = channel3.SettingsTab;
|
|
5760
6384
|
var TelegramAccountCard = channel3.AccountCard;
|
|
@@ -5877,11 +6501,11 @@ function formatRemaining4(milliseconds) {
|
|
|
5877
6501
|
}
|
|
5878
6502
|
|
|
5879
6503
|
// plugin-src/client/channels/wecom/index.js
|
|
5880
|
-
var
|
|
6504
|
+
var React15 = __toESM(require("react"), 1);
|
|
5881
6505
|
|
|
5882
6506
|
// plugin-src/client/channels/wecom/styles.js
|
|
5883
6507
|
var WECOM_STYLE_ID = "xmanrui-dsh-im-wecom-settings";
|
|
5884
|
-
var
|
|
6508
|
+
var CSS8 = String.raw`
|
|
5885
6509
|
.dwecom-page { --ddt-accent: #3370ff; --ddt-accent-deep: #245bdb; --ddt-accent-wash: #eef4ff; }
|
|
5886
6510
|
.dwecom-avatar, .dwecom-brand { color: #3370ff; background: #fff; border: 1px solid var(--dsw-alias-border-l2, #e5e6eb); }
|
|
5887
6511
|
.dwecom-avatar svg, .dwecom-brand svg { display: block; }
|
|
@@ -5895,14 +6519,14 @@ function installWecomStyles() {
|
|
|
5895
6519
|
const style = document.createElement("style");
|
|
5896
6520
|
style.dataset.plugin = "@xmanrui/dsh-im";
|
|
5897
6521
|
style.dataset.pluginCss = WECOM_STYLE_ID;
|
|
5898
|
-
style.textContent =
|
|
6522
|
+
style.textContent = CSS8;
|
|
5899
6523
|
document.head.appendChild(style);
|
|
5900
6524
|
return () => style.remove();
|
|
5901
6525
|
}
|
|
5902
6526
|
|
|
5903
6527
|
// plugin-src/client/channels/wecom/index.js
|
|
5904
6528
|
var ACTIVE_STATES2 = /* @__PURE__ */ new Set(["pending", "refreshing", "connecting"]);
|
|
5905
|
-
var
|
|
6529
|
+
var Button10 = React15.forwardRef(function Button11({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
5906
6530
|
return h2("button", {
|
|
5907
6531
|
...props,
|
|
5908
6532
|
ref,
|
|
@@ -5933,7 +6557,7 @@ function Heading4({ totals, adding, busy, onAdd, onCredential, credentialOpen, a
|
|
|
5933
6557
|
h2(
|
|
5934
6558
|
"div",
|
|
5935
6559
|
{ className: "dim-bindActions" },
|
|
5936
|
-
h2(
|
|
6560
|
+
h2(Button10, {
|
|
5937
6561
|
kind: "primary",
|
|
5938
6562
|
className: "dim-scanButton",
|
|
5939
6563
|
onClick: onAdd,
|
|
@@ -5941,7 +6565,7 @@ function Heading4({ totals, adding, busy, onAdd, onCredential, credentialOpen, a
|
|
|
5941
6565
|
ref: addButtonRef,
|
|
5942
6566
|
"aria-label": "\u626B\u7801\u63A5\u5165\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA"
|
|
5943
6567
|
}, h2(QrActionIcon), adding ? "\u6B63\u5728\u63A5\u5165" : "\u626B\u7801\u63A5\u5165\u673A\u5668\u4EBA"),
|
|
5944
|
-
h2(
|
|
6568
|
+
h2(Button10, {
|
|
5945
6569
|
kind: "credential",
|
|
5946
6570
|
className: "dim-credentialButton",
|
|
5947
6571
|
onClick: onCredential,
|
|
@@ -5988,7 +6612,7 @@ function EmptyView4({ busy, onStart }) {
|
|
|
5988
6612
|
"div",
|
|
5989
6613
|
{ className: "ddt-actions dim-viewActions" },
|
|
5990
6614
|
h2(
|
|
5991
|
-
|
|
6615
|
+
Button10,
|
|
5992
6616
|
{ kind: "primary", onClick: onStart, disabled: busy },
|
|
5993
6617
|
busy ? "\u6B63\u5728\u751F\u6210\u4E8C\u7EF4\u7801\u2026" : "\u751F\u6210\u4F01\u4E1A\u5FAE\u4FE1\u4E8C\u7EF4\u7801"
|
|
5994
6618
|
)
|
|
@@ -6059,8 +6683,8 @@ function QrPanel3({ provision, now, busy, onRefresh, onCancel }) {
|
|
|
6059
6683
|
h2(
|
|
6060
6684
|
"div",
|
|
6061
6685
|
{ className: "ddt-actions dim-viewActions" },
|
|
6062
|
-
h2(
|
|
6063
|
-
h2(
|
|
6686
|
+
h2(Button10, { onClick: onRefresh, disabled: busy }, "\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801"),
|
|
6687
|
+
h2(Button10, { kind: "quiet", onClick: onCancel, disabled: busy }, "\u53D6\u6D88")
|
|
6064
6688
|
)
|
|
6065
6689
|
)
|
|
6066
6690
|
)
|
|
@@ -6089,8 +6713,8 @@ function ProvisionView2({ provision, busy, onRetry, onClose }) {
|
|
|
6089
6713
|
h2(
|
|
6090
6714
|
"div",
|
|
6091
6715
|
{ className: "ddt-actions dim-viewActions" },
|
|
6092
|
-
h2(
|
|
6093
|
-
h2(
|
|
6716
|
+
h2(Button10, { kind: "primary", onClick: onRetry, disabled: busy }, "\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801"),
|
|
6717
|
+
h2(Button10, { onClick: onClose, disabled: busy }, "\u5173\u95ED")
|
|
6094
6718
|
)
|
|
6095
6719
|
)
|
|
6096
6720
|
);
|
|
@@ -6104,8 +6728,8 @@ function RemoveConfirmation4({ account, busy, onConfirm, onCancel }) {
|
|
|
6104
6728
|
h2(
|
|
6105
6729
|
"div",
|
|
6106
6730
|
{ className: "ddt-actions dim-viewActions" },
|
|
6107
|
-
h2(
|
|
6108
|
-
h2(
|
|
6731
|
+
h2(Button10, { onClick: onCancel, disabled: busy }, "\u4FDD\u7559\u673A\u5668\u4EBA"),
|
|
6732
|
+
h2(Button10, { kind: "danger", onClick: onConfirm, disabled: busy }, busy ? "\u6B63\u5728\u79FB\u9664\u2026" : "\u786E\u8BA4\u79FB\u9664\u63A5\u5165")
|
|
6109
6733
|
)
|
|
6110
6734
|
);
|
|
6111
6735
|
}
|
|
@@ -6121,7 +6745,7 @@ function AccountCard3({
|
|
|
6121
6745
|
onCancelRemove
|
|
6122
6746
|
}) {
|
|
6123
6747
|
const tone = account.connected ? "success" : account.state === "error" ? "error" : "warning";
|
|
6124
|
-
const
|
|
6748
|
+
const stateLabel2 = account.connected ? "\u8FD0\u884C\u6B63\u5E38" : account.state === "connecting" ? "\u6B63\u5728\u8FDE\u63A5" : "\u8FDE\u63A5\u672A\u5C31\u7EEA";
|
|
6125
6749
|
const summary = account.error?.message ?? (account.connected ? null : account.health.summary);
|
|
6126
6750
|
return h2(
|
|
6127
6751
|
"article",
|
|
@@ -6147,7 +6771,7 @@ function AccountCard3({
|
|
|
6147
6771
|
"div",
|
|
6148
6772
|
{ className: "ddt-health dim-botHealth" },
|
|
6149
6773
|
h2("span", { className: "ddt-dot dim-healthDot", "data-tone": tone }),
|
|
6150
|
-
h2("span", null,
|
|
6774
|
+
h2("span", null, stateLabel2)
|
|
6151
6775
|
)
|
|
6152
6776
|
),
|
|
6153
6777
|
h2(
|
|
@@ -6173,8 +6797,8 @@ function AccountCard3({
|
|
|
6173
6797
|
h2(
|
|
6174
6798
|
"div",
|
|
6175
6799
|
{ className: "ddt-actions dim-cardActions" },
|
|
6176
|
-
h2(
|
|
6177
|
-
h2(
|
|
6800
|
+
h2(Button10, { className: "dim-cardAction", onClick: onReconnect, disabled: Boolean(busy) }, busy === "reconnect" ? "\u68C0\u67E5\u4E2D\u2026" : account.connected ? "\u68C0\u67E5\u8FDE\u63A5" : "\u91CD\u8BD5\u8FDE\u63A5"),
|
|
6801
|
+
h2(Button10, { className: "dim-cardAction", kind: "danger", onClick: onRequestRemove, disabled: Boolean(busy) }, "\u79FB\u9664\u63A5\u5165")
|
|
6178
6802
|
)
|
|
6179
6803
|
)
|
|
6180
6804
|
),
|
|
@@ -6187,21 +6811,21 @@ function AccountCard3({
|
|
|
6187
6811
|
);
|
|
6188
6812
|
}
|
|
6189
6813
|
function WecomSettingsTab({ rpcCall }) {
|
|
6190
|
-
const [model, setModel] =
|
|
6191
|
-
const [provision, setProvision] =
|
|
6192
|
-
const [busy, setBusy] =
|
|
6193
|
-
const [busyByBot, setBusyByBot] =
|
|
6194
|
-
const [feedbackByBot, setFeedbackByBot] =
|
|
6195
|
-
const [removeTarget, setRemoveTarget] =
|
|
6196
|
-
const [credentialOpen, setCredentialOpen] =
|
|
6197
|
-
const [credentialError, setCredentialError] =
|
|
6198
|
-
const [notice, setNotice] =
|
|
6199
|
-
const [now, setNow] =
|
|
6200
|
-
const mounted =
|
|
6814
|
+
const [model, setModel] = React15.useState({ phase: "loading", bots: [], totals: { configured: 0, connected: 0 }, error: null });
|
|
6815
|
+
const [provision, setProvision] = React15.useState(null);
|
|
6816
|
+
const [busy, setBusy] = React15.useState(false);
|
|
6817
|
+
const [busyByBot, setBusyByBot] = React15.useState({});
|
|
6818
|
+
const [feedbackByBot, setFeedbackByBot] = React15.useState({});
|
|
6819
|
+
const [removeTarget, setRemoveTarget] = React15.useState(null);
|
|
6820
|
+
const [credentialOpen, setCredentialOpen] = React15.useState(false);
|
|
6821
|
+
const [credentialError, setCredentialError] = React15.useState(null);
|
|
6822
|
+
const [notice, setNotice] = React15.useState("");
|
|
6823
|
+
const [now, setNow] = React15.useState(Date.now());
|
|
6824
|
+
const mounted = React15.useRef(true);
|
|
6201
6825
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
6202
|
-
const addButtonRef =
|
|
6203
|
-
const noticeFrameRef =
|
|
6204
|
-
const announce =
|
|
6826
|
+
const addButtonRef = React15.useRef(null);
|
|
6827
|
+
const noticeFrameRef = React15.useRef(null);
|
|
6828
|
+
const announce = React15.useCallback((message) => {
|
|
6205
6829
|
if (!mounted.current) return;
|
|
6206
6830
|
if (noticeFrameRef.current !== null) {
|
|
6207
6831
|
window.cancelAnimationFrame(noticeFrameRef.current);
|
|
@@ -6215,7 +6839,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6215
6839
|
});
|
|
6216
6840
|
}
|
|
6217
6841
|
}, []);
|
|
6218
|
-
|
|
6842
|
+
React15.useEffect(() => {
|
|
6219
6843
|
const disposeDingtalk = installDingtalkStyles();
|
|
6220
6844
|
const disposeWecom = installWecomStyles();
|
|
6221
6845
|
mounted.current = true;
|
|
@@ -6229,11 +6853,11 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6229
6853
|
disposeDingtalk();
|
|
6230
6854
|
};
|
|
6231
6855
|
}, []);
|
|
6232
|
-
const invoke =
|
|
6856
|
+
const invoke = React15.useCallback(async (endpoint, payload = {}, signal) => {
|
|
6233
6857
|
if (typeof rpcCall !== "function") throw new TypeError("\u4F01\u4E1A\u5FAE\u4FE1\u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
6234
6858
|
return unwrapRpcResult7(await rpcCall(endpoint, payload, signal));
|
|
6235
6859
|
}, [rpcCall]);
|
|
6236
|
-
const loadStatus =
|
|
6860
|
+
const loadStatus = React15.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
|
6237
6861
|
const workspaceVersion = workspaceFence.beginStatus();
|
|
6238
6862
|
if (workspaceVersion === null) return void 0;
|
|
6239
6863
|
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
|
@@ -6253,12 +6877,12 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6253
6877
|
return void 0;
|
|
6254
6878
|
}
|
|
6255
6879
|
}, [invoke, workspaceFence]);
|
|
6256
|
-
|
|
6880
|
+
React15.useEffect(() => {
|
|
6257
6881
|
const controller = new AbortController();
|
|
6258
6882
|
void loadStatus({ signal: controller.signal, restore: true });
|
|
6259
6883
|
return () => controller.abort();
|
|
6260
6884
|
}, [loadStatus]);
|
|
6261
|
-
|
|
6885
|
+
React15.useEffect(() => {
|
|
6262
6886
|
if (model.phase !== "ready") return void 0;
|
|
6263
6887
|
const controller = new AbortController();
|
|
6264
6888
|
const timer = window.setInterval(() => void loadStatus({ signal: controller.signal, silent: true }), 15e3);
|
|
@@ -6267,12 +6891,12 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6267
6891
|
window.clearInterval(timer);
|
|
6268
6892
|
};
|
|
6269
6893
|
}, [loadStatus, model.phase]);
|
|
6270
|
-
|
|
6894
|
+
React15.useEffect(() => {
|
|
6271
6895
|
if (!provision || !ACTIVE_STATES2.has(provision.status)) return void 0;
|
|
6272
6896
|
const timer = window.setInterval(() => mounted.current && setNow(Date.now()), 1e3);
|
|
6273
6897
|
return () => window.clearInterval(timer);
|
|
6274
6898
|
}, [provision?.attemptId, provision?.status]);
|
|
6275
|
-
const startProvisioning =
|
|
6899
|
+
const startProvisioning = React15.useCallback(async (replace = false) => {
|
|
6276
6900
|
setCredentialOpen(false);
|
|
6277
6901
|
setCredentialError(null);
|
|
6278
6902
|
setBusy(true);
|
|
@@ -6290,7 +6914,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6290
6914
|
if (mounted.current) setBusy(false);
|
|
6291
6915
|
}
|
|
6292
6916
|
}, [invoke, provision?.attemptId]);
|
|
6293
|
-
const bindCredentials =
|
|
6917
|
+
const bindCredentials = React15.useCallback(async ({ identity, secret }) => {
|
|
6294
6918
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
6295
6919
|
setBusy(true);
|
|
6296
6920
|
setCredentialError(null);
|
|
@@ -6312,7 +6936,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6312
6936
|
if (mounted.current) setBusy(false);
|
|
6313
6937
|
}
|
|
6314
6938
|
}, [invoke, loadStatus, workspaceFence]);
|
|
6315
|
-
const closeProvision =
|
|
6939
|
+
const closeProvision = React15.useCallback(async () => {
|
|
6316
6940
|
setBusy(true);
|
|
6317
6941
|
try {
|
|
6318
6942
|
if (provision?.attemptId && ACTIVE_STATES2.has(provision.status)) {
|
|
@@ -6323,7 +6947,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6323
6947
|
if (mounted.current) setBusy(false);
|
|
6324
6948
|
}
|
|
6325
6949
|
}, [invoke, provision?.attemptId, provision?.status]);
|
|
6326
|
-
|
|
6950
|
+
React15.useEffect(() => {
|
|
6327
6951
|
const attemptId = provision?.attemptId;
|
|
6328
6952
|
if (!attemptId || !ACTIVE_STATES2.has(provision.status)) return void 0;
|
|
6329
6953
|
const controller = new AbortController();
|
|
@@ -6353,7 +6977,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6353
6977
|
window.clearTimeout(timer);
|
|
6354
6978
|
};
|
|
6355
6979
|
}, [invoke, loadStatus, provision?.attemptId, provision?.pollIntervalMs, provision?.status]);
|
|
6356
|
-
const botAction =
|
|
6980
|
+
const botAction = React15.useCallback(async (account, operation, endpoint, payload) => {
|
|
6357
6981
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
6358
6982
|
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
|
6359
6983
|
try {
|
|
@@ -6372,7 +6996,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6372
6996
|
});
|
|
6373
6997
|
}
|
|
6374
6998
|
}, [invoke, loadStatus, workspaceFence]);
|
|
6375
|
-
const reconnect =
|
|
6999
|
+
const reconnect = React15.useCallback(async (account) => {
|
|
6376
7000
|
setFeedbackByBot((current) => {
|
|
6377
7001
|
const next = { ...current };
|
|
6378
7002
|
delete next[account.botId];
|
|
@@ -6484,8 +7108,8 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6484
7108
|
addButtonRef
|
|
6485
7109
|
}),
|
|
6486
7110
|
h2("div", { className: "ddt-visuallyHidden", role: "status", "aria-live": "polite" }, notice),
|
|
6487
|
-
model.phase === "loading" ? h2(LoadingView4) : model.phase === "error" ? h2("div", { className: "ddt-card dim-surfaceCard" }, h2("div", { className: "ddt-inlineError dim-inlineError" }, h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u72B6\u6001"), h2("p", null, model.error?.message), h2(
|
|
6488
|
-
|
|
7111
|
+
model.phase === "loading" ? h2(LoadingView4) : model.phase === "error" ? h2("div", { className: "ddt-card dim-surfaceCard" }, h2("div", { className: "ddt-inlineError dim-inlineError" }, h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA\u72B6\u6001"), h2("p", null, model.error?.message), h2(Button10, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6"))) : h2(
|
|
7112
|
+
React15.Fragment,
|
|
6489
7113
|
null,
|
|
6490
7114
|
credentialView,
|
|
6491
7115
|
provisionView,
|
|
@@ -6496,7 +7120,7 @@ function WecomSettingsTab({ rpcCall }) {
|
|
|
6496
7120
|
}
|
|
6497
7121
|
|
|
6498
7122
|
// plugin-src/client/channels/weixin/index.js
|
|
6499
|
-
var
|
|
7123
|
+
var React16 = __toESM(require("react"), 1);
|
|
6500
7124
|
|
|
6501
7125
|
// plugin-src/client/channels/weixin/api.js
|
|
6502
7126
|
var WEIXIN_RPC_CHANNEL = "/weixin";
|
|
@@ -6648,7 +7272,7 @@ function formatRemaining5(milliseconds) {
|
|
|
6648
7272
|
|
|
6649
7273
|
// plugin-src/client/channels/weixin/styles.js
|
|
6650
7274
|
var WEIXIN_STYLE_ID = "xmanrui-dsh-weixin-settings";
|
|
6651
|
-
var
|
|
7275
|
+
var CSS9 = String.raw`
|
|
6652
7276
|
.dxw-page {
|
|
6653
7277
|
--dxw-accent: #07c160;
|
|
6654
7278
|
--dxw-accent-dark: #05994c;
|
|
@@ -6763,13 +7387,13 @@ function installWeixinStyles() {
|
|
|
6763
7387
|
const style = document.createElement("style");
|
|
6764
7388
|
style.dataset.plugin = "@xmanrui/dsh-weixin";
|
|
6765
7389
|
style.dataset.pluginCss = WEIXIN_STYLE_ID;
|
|
6766
|
-
style.textContent =
|
|
7390
|
+
style.textContent = CSS9;
|
|
6767
7391
|
document.head.appendChild(style);
|
|
6768
7392
|
return () => style.remove();
|
|
6769
7393
|
}
|
|
6770
7394
|
|
|
6771
7395
|
// plugin-src/client/channels/weixin/index.js
|
|
6772
|
-
var
|
|
7396
|
+
var Button12 = React16.forwardRef(function Button13({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
6773
7397
|
return h2("button", {
|
|
6774
7398
|
...props,
|
|
6775
7399
|
ref,
|
|
@@ -6785,7 +7409,7 @@ function Heading5({ totals, adding, busy, onAdd, addButtonRef }) {
|
|
|
6785
7409
|
h2(
|
|
6786
7410
|
"div",
|
|
6787
7411
|
{ className: "dxw-tools" },
|
|
6788
|
-
h2(
|
|
7412
|
+
h2(Button12, {
|
|
6789
7413
|
kind: "primary",
|
|
6790
7414
|
className: "dim-scanButton",
|
|
6791
7415
|
onClick: onAdd,
|
|
@@ -6831,7 +7455,7 @@ function EmptyView5({ onStart, busy }) {
|
|
|
6831
7455
|
"div",
|
|
6832
7456
|
{ className: "dxw-actions dim-viewActions" },
|
|
6833
7457
|
h2(
|
|
6834
|
-
|
|
7458
|
+
Button12,
|
|
6835
7459
|
{ kind: "primary", onClick: onStart, disabled: busy },
|
|
6836
7460
|
busy ? "\u6B63\u5728\u751F\u6210\u4E8C\u7EF4\u7801\u2026" : "\u751F\u6210\u5FAE\u4FE1\u4E8C\u7EF4\u7801"
|
|
6837
7461
|
)
|
|
@@ -6842,14 +7466,14 @@ function EmptyView5({ onStart, busy }) {
|
|
|
6842
7466
|
);
|
|
6843
7467
|
}
|
|
6844
7468
|
function QrPanel4({ provision, now, busy, onRefresh, onCancel }) {
|
|
6845
|
-
const [imageFailed, setImageFailed] =
|
|
7469
|
+
const [imageFailed, setImageFailed] = React16.useState(false);
|
|
6846
7470
|
const source = safeQrSource5(provision.qrCodeDataUrl);
|
|
6847
7471
|
const href = safeVerificationUrl(provision.verificationUrl);
|
|
6848
7472
|
const remaining = Math.max(0, provision.expiresAt - now);
|
|
6849
7473
|
const expired = remaining === 0 || provision.status === "expired";
|
|
6850
7474
|
const duration = Math.max(1, provision.durationMs ?? 5 * 6e4);
|
|
6851
7475
|
const progress = Math.round(Math.min(1, remaining / duration) * 100);
|
|
6852
|
-
|
|
7476
|
+
React16.useEffect(() => setImageFailed(false), [source]);
|
|
6853
7477
|
return h2(
|
|
6854
7478
|
"div",
|
|
6855
7479
|
{ className: "dxw-card dim-surfaceCard" },
|
|
@@ -6901,24 +7525,24 @@ function QrPanel4({ provision, now, busy, onRefresh, onCancel }) {
|
|
|
6901
7525
|
h2(
|
|
6902
7526
|
"div",
|
|
6903
7527
|
{ className: "dxw-actions dim-viewActions" },
|
|
6904
|
-
expired ? h2(
|
|
7528
|
+
expired ? h2(Button12, { kind: "primary", onClick: onRefresh, disabled: busy }, "\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801") : null,
|
|
6905
7529
|
href ? h2("a", {
|
|
6906
7530
|
className: "dxw-button",
|
|
6907
7531
|
href,
|
|
6908
7532
|
target: "_blank",
|
|
6909
7533
|
rel: "noopener noreferrer"
|
|
6910
7534
|
}, "\u6253\u5F00\u5907\u7528\u94FE\u63A5") : null,
|
|
6911
|
-
!expired ? h2(
|
|
6912
|
-
h2(
|
|
7535
|
+
!expired ? h2(Button12, { onClick: onRefresh, disabled: busy }, "\u6362\u4E00\u4E2A\u4E8C\u7EF4\u7801") : null,
|
|
7536
|
+
h2(Button12, { onClick: onCancel, disabled: busy }, "\u53D6\u6D88")
|
|
6913
7537
|
)
|
|
6914
7538
|
)
|
|
6915
7539
|
)
|
|
6916
7540
|
);
|
|
6917
7541
|
}
|
|
6918
7542
|
function VerificationPanel({ provision, busy, onSubmit, onCancel }) {
|
|
6919
|
-
const [code, setCode] =
|
|
7543
|
+
const [code, setCode] = React16.useState("");
|
|
6920
7544
|
const valid = /^\d{4,8}$/.test(code);
|
|
6921
|
-
|
|
7545
|
+
React16.useEffect(() => setCode(""), [provision.attemptId]);
|
|
6922
7546
|
return h2(
|
|
6923
7547
|
"div",
|
|
6924
7548
|
{ className: "dxw-card dim-surfaceCard" },
|
|
@@ -6959,7 +7583,7 @@ function VerificationPanel({ provision, busy, onSubmit, onCancel }) {
|
|
|
6959
7583
|
disabled: !valid || busy
|
|
6960
7584
|
}, busy ? "\u6B63\u5728\u9A8C\u8BC1\u2026" : "\u7EE7\u7EED\u8FDE\u63A5")
|
|
6961
7585
|
),
|
|
6962
|
-
h2(
|
|
7586
|
+
h2(Button12, { onClick: onCancel, disabled: busy }, "\u53D6\u6D88\u7ED1\u5B9A")
|
|
6963
7587
|
)
|
|
6964
7588
|
);
|
|
6965
7589
|
}
|
|
@@ -6973,7 +7597,7 @@ function ProgressPanel2({ scanned, onCancel, busy }) {
|
|
|
6973
7597
|
onCancel ? h2(
|
|
6974
7598
|
"div",
|
|
6975
7599
|
{ className: "dxw-actions dim-viewActions", style: { justifyContent: "center", marginTop: 14 } },
|
|
6976
|
-
h2(
|
|
7600
|
+
h2(Button12, { onClick: onCancel, disabled: busy }, "\u53D6\u6D88")
|
|
6977
7601
|
) : null
|
|
6978
7602
|
);
|
|
6979
7603
|
}
|
|
@@ -6991,8 +7615,8 @@ function ProvisionError3({ provision, busy, onRetry, onClose }) {
|
|
|
6991
7615
|
h2(
|
|
6992
7616
|
"div",
|
|
6993
7617
|
{ className: "dxw-actions dim-viewActions" },
|
|
6994
|
-
h2(
|
|
6995
|
-
h2(
|
|
7618
|
+
h2(Button12, { kind: "primary", onClick: onRetry, disabled: busy }, "\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801"),
|
|
7619
|
+
h2(Button12, { onClick: onClose, disabled: busy }, "\u5173\u95ED")
|
|
6996
7620
|
)
|
|
6997
7621
|
)
|
|
6998
7622
|
);
|
|
@@ -7079,11 +7703,11 @@ function AccountCard4({
|
|
|
7079
7703
|
"div",
|
|
7080
7704
|
{ className: "dxw-actions dim-cardActions" },
|
|
7081
7705
|
h2(
|
|
7082
|
-
|
|
7706
|
+
Button12,
|
|
7083
7707
|
{ className: "dim-cardAction", onClick: onReconnect, disabled: Boolean(busy) },
|
|
7084
7708
|
busy === "reconnect" ? "\u68C0\u67E5\u4E2D\u2026" : account.connected ? "\u68C0\u67E5\u8FDE\u63A5" : "\u91CD\u8BD5\u8FDE\u63A5"
|
|
7085
7709
|
),
|
|
7086
|
-
h2(
|
|
7710
|
+
h2(Button12, { className: "dim-cardAction", kind: "danger", onClick: onRequestRemove, disabled: Boolean(busy) }, "\u79FB\u9664\u63A5\u5165")
|
|
7087
7711
|
)
|
|
7088
7712
|
)
|
|
7089
7713
|
),
|
|
@@ -7095,9 +7719,9 @@ function AccountCard4({
|
|
|
7095
7719
|
h2(
|
|
7096
7720
|
"div",
|
|
7097
7721
|
{ className: "dxw-actions dim-viewActions" },
|
|
7098
|
-
h2(
|
|
7722
|
+
h2(Button12, { onClick: onCancelRemove, disabled: busy === "delete" }, "\u4FDD\u7559\u8D26\u53F7"),
|
|
7099
7723
|
h2(
|
|
7100
|
-
|
|
7724
|
+
Button12,
|
|
7101
7725
|
{ kind: "danger", onClick: onConfirmRemove, disabled: busy === "delete" },
|
|
7102
7726
|
busy === "delete" ? "\u6B63\u5728\u79FB\u9664\u2026" : "\u786E\u8BA4\u79FB\u9664"
|
|
7103
7727
|
)
|
|
@@ -7138,40 +7762,40 @@ function mergeWeixinProvisioningSnapshot(current, incoming, { restoreProvisionin
|
|
|
7138
7762
|
};
|
|
7139
7763
|
}
|
|
7140
7764
|
function WeixinSettingsTab({ rpcCall }) {
|
|
7141
|
-
const [model, setModel] =
|
|
7765
|
+
const [model, setModel] = React16.useState({
|
|
7142
7766
|
phase: "loading",
|
|
7143
7767
|
bots: [],
|
|
7144
7768
|
totals: EMPTY_TOTALS3,
|
|
7145
7769
|
revision: 0,
|
|
7146
7770
|
error: null
|
|
7147
7771
|
});
|
|
7148
|
-
const [provision, setProvision] =
|
|
7149
|
-
const [busy, setBusy] =
|
|
7150
|
-
const [busyByBot, setBusyByBot] =
|
|
7151
|
-
const [feedbackByBot, setFeedbackByBot] =
|
|
7152
|
-
const [removeTarget, setRemoveTarget] =
|
|
7153
|
-
const [notice, setNotice] =
|
|
7154
|
-
const [now, setNow] =
|
|
7155
|
-
const addButtonRef =
|
|
7156
|
-
const mountedRef =
|
|
7772
|
+
const [provision, setProvision] = React16.useState(null);
|
|
7773
|
+
const [busy, setBusy] = React16.useState(false);
|
|
7774
|
+
const [busyByBot, setBusyByBot] = React16.useState({});
|
|
7775
|
+
const [feedbackByBot, setFeedbackByBot] = React16.useState({});
|
|
7776
|
+
const [removeTarget, setRemoveTarget] = React16.useState(null);
|
|
7777
|
+
const [notice, setNotice] = React16.useState("");
|
|
7778
|
+
const [now, setNow] = React16.useState(() => Date.now());
|
|
7779
|
+
const addButtonRef = React16.useRef(null);
|
|
7780
|
+
const mountedRef = React16.useRef(true);
|
|
7157
7781
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
7158
7782
|
const scheduleAnimationFrame = useAnimationFrameScheduler();
|
|
7159
|
-
|
|
7783
|
+
React16.useEffect(() => {
|
|
7160
7784
|
mountedRef.current = true;
|
|
7161
7785
|
return () => {
|
|
7162
7786
|
mountedRef.current = false;
|
|
7163
7787
|
};
|
|
7164
7788
|
}, []);
|
|
7165
|
-
const announce =
|
|
7789
|
+
const announce = React16.useCallback((value) => {
|
|
7166
7790
|
setNotice("");
|
|
7167
7791
|
scheduleAnimationFrame(() => {
|
|
7168
7792
|
if (value) setNotice(value);
|
|
7169
7793
|
}, "announcement");
|
|
7170
7794
|
}, [scheduleAnimationFrame]);
|
|
7171
|
-
const invoke =
|
|
7795
|
+
const invoke = React16.useCallback(async (endpoint, payload = {}, signal) => {
|
|
7172
7796
|
return unwrapRpcResult8(await rpcCall(endpoint, payload, signal));
|
|
7173
7797
|
}, [rpcCall]);
|
|
7174
|
-
const loadStatus =
|
|
7798
|
+
const loadStatus = React16.useCallback(async ({
|
|
7175
7799
|
signal,
|
|
7176
7800
|
silent = false,
|
|
7177
7801
|
restoreProvisioning = false
|
|
@@ -7207,12 +7831,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
7207
7831
|
return void 0;
|
|
7208
7832
|
}
|
|
7209
7833
|
}, [invoke, workspaceFence]);
|
|
7210
|
-
|
|
7834
|
+
React16.useEffect(() => {
|
|
7211
7835
|
const controller = new AbortController();
|
|
7212
7836
|
void loadStatus({ signal: controller.signal, restoreProvisioning: true });
|
|
7213
7837
|
return () => controller.abort();
|
|
7214
7838
|
}, [loadStatus]);
|
|
7215
|
-
|
|
7839
|
+
React16.useEffect(() => {
|
|
7216
7840
|
if (model.phase !== "ready") return void 0;
|
|
7217
7841
|
const controller = new AbortController();
|
|
7218
7842
|
let running = false;
|
|
@@ -7231,12 +7855,12 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
7231
7855
|
window.clearInterval(timer);
|
|
7232
7856
|
};
|
|
7233
7857
|
}, [loadStatus, model.phase]);
|
|
7234
|
-
|
|
7858
|
+
React16.useEffect(() => {
|
|
7235
7859
|
if (!provision || !["pending", "scanned"].includes(provision.status)) return void 0;
|
|
7236
7860
|
const timer = window.setInterval(() => setNow(Date.now()), 1e3);
|
|
7237
7861
|
return () => window.clearInterval(timer);
|
|
7238
7862
|
}, [provision?.attemptId, provision?.status]);
|
|
7239
|
-
const startProvisioning =
|
|
7863
|
+
const startProvisioning = React16.useCallback(async ({ replace = false } = {}) => {
|
|
7240
7864
|
setBusy(true);
|
|
7241
7865
|
try {
|
|
7242
7866
|
if (replace && provision?.attemptId) {
|
|
@@ -7257,7 +7881,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
7257
7881
|
setBusy(false);
|
|
7258
7882
|
}
|
|
7259
7883
|
}, [announce, invoke, provision?.attemptId]);
|
|
7260
|
-
const cancelProvisioning =
|
|
7884
|
+
const cancelProvisioning = React16.useCallback(async () => {
|
|
7261
7885
|
setBusy(true);
|
|
7262
7886
|
try {
|
|
7263
7887
|
if (provision?.attemptId && !["failed", "expired", "cancelled"].includes(provision.status)) {
|
|
@@ -7272,7 +7896,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
7272
7896
|
setBusy(false);
|
|
7273
7897
|
}
|
|
7274
7898
|
}, [announce, invoke, provision?.attemptId, provision?.status, scheduleAnimationFrame]);
|
|
7275
|
-
const submitVerification =
|
|
7899
|
+
const submitVerification = React16.useCallback(async (verifyCode) => {
|
|
7276
7900
|
if (!provision?.attemptId) return;
|
|
7277
7901
|
setBusy(true);
|
|
7278
7902
|
try {
|
|
@@ -7288,7 +7912,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
7288
7912
|
setBusy(false);
|
|
7289
7913
|
}
|
|
7290
7914
|
}, [announce, invoke, provision?.attemptId]);
|
|
7291
|
-
|
|
7915
|
+
React16.useEffect(() => {
|
|
7292
7916
|
const attemptId = provision?.attemptId;
|
|
7293
7917
|
if (!attemptId || !["pending", "scanned", "connecting"].includes(provision.status)) return void 0;
|
|
7294
7918
|
const controller = new AbortController();
|
|
@@ -7336,7 +7960,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
7336
7960
|
controller.abort();
|
|
7337
7961
|
};
|
|
7338
7962
|
}, [announce, invoke, loadStatus, provision?.attemptId, provision?.status, provision?.pollIntervalMs]);
|
|
7339
|
-
const setBotBusy =
|
|
7963
|
+
const setBotBusy = React16.useCallback((botId, value) => {
|
|
7340
7964
|
setBusyByBot((current) => {
|
|
7341
7965
|
const next = { ...current };
|
|
7342
7966
|
if (value) next[botId] = value;
|
|
@@ -7344,7 +7968,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
7344
7968
|
return next;
|
|
7345
7969
|
});
|
|
7346
7970
|
}, []);
|
|
7347
|
-
const reconnect =
|
|
7971
|
+
const reconnect = React16.useCallback(async (account) => {
|
|
7348
7972
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
7349
7973
|
setBotBusy(account.botId, "reconnect");
|
|
7350
7974
|
setFeedbackByBot((current) => {
|
|
@@ -7389,7 +8013,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
7389
8013
|
setBotBusy(account.botId, null);
|
|
7390
8014
|
}
|
|
7391
8015
|
}, [announce, invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
7392
|
-
const saveWorkspace =
|
|
8016
|
+
const saveWorkspace = React16.useCallback(async (account, workspace) => {
|
|
7393
8017
|
const workspaceVersion = workspaceFence.beginMutation();
|
|
7394
8018
|
setBotBusy(account.botId, "workspace");
|
|
7395
8019
|
try {
|
|
@@ -7412,7 +8036,7 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
7412
8036
|
if (mountedRef.current) setBotBusy(account.botId, null);
|
|
7413
8037
|
}
|
|
7414
8038
|
}, [invoke, loadStatus, setBotBusy, workspaceFence]);
|
|
7415
|
-
const remove =
|
|
8039
|
+
const remove = React16.useCallback(async (account) => {
|
|
7416
8040
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
7417
8041
|
setBotBusy(account.botId, "delete");
|
|
7418
8042
|
try {
|
|
@@ -7485,10 +8109,10 @@ function WeixinSettingsTab({ rpcCall }) {
|
|
|
7485
8109
|
{ className: "dxw-error dim-inlineError" },
|
|
7486
8110
|
h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6\u5FAE\u4FE1\u72B6\u6001"),
|
|
7487
8111
|
h2("p", null, model.error?.message ?? "\u8BF7\u7A0D\u540E\u91CD\u8BD5"),
|
|
7488
|
-
h2(
|
|
8112
|
+
h2(Button12, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
7489
8113
|
)
|
|
7490
8114
|
) : h2(
|
|
7491
|
-
|
|
8115
|
+
React16.Fragment,
|
|
7492
8116
|
null,
|
|
7493
8117
|
provisionView,
|
|
7494
8118
|
model.bots.length === 0 && !provision ? h2(EmptyView5, { onStart: () => void startProvisioning(), busy }) : null,
|
|
@@ -7620,11 +8244,11 @@ function formatRemaining6(milliseconds) {
|
|
|
7620
8244
|
}
|
|
7621
8245
|
|
|
7622
8246
|
// plugin-src/client/channels/whatsapp/index.js
|
|
7623
|
-
var
|
|
8247
|
+
var React17 = __toESM(require("react"), 1);
|
|
7624
8248
|
|
|
7625
8249
|
// plugin-src/client/channels/whatsapp/styles.js
|
|
7626
8250
|
var WHATSAPP_STYLE_ID = "xmanrui-dsh-im-whatsapp-settings";
|
|
7627
|
-
var
|
|
8251
|
+
var CSS10 = String.raw`
|
|
7628
8252
|
.dwa-page { --ddt-accent: #25d366; --ddt-accent-deep: #128c7e; --ddt-accent-wash: #eafbf0; }
|
|
7629
8253
|
.dwa-avatar { color: #fff; background: #25d366; }
|
|
7630
8254
|
.dwa-avatar svg { display: block; }
|
|
@@ -7638,14 +8262,14 @@ function installWhatsappStyles() {
|
|
|
7638
8262
|
const style = document.createElement("style");
|
|
7639
8263
|
style.dataset.plugin = "@xmanrui/dsh-im";
|
|
7640
8264
|
style.dataset.pluginCss = WHATSAPP_STYLE_ID;
|
|
7641
|
-
style.textContent =
|
|
8265
|
+
style.textContent = CSS10;
|
|
7642
8266
|
document.head.appendChild(style);
|
|
7643
8267
|
return () => style.remove();
|
|
7644
8268
|
}
|
|
7645
8269
|
|
|
7646
8270
|
// plugin-src/client/channels/whatsapp/index.js
|
|
7647
8271
|
var ACTIVE_STATES3 = /* @__PURE__ */ new Set(["pending", "connecting"]);
|
|
7648
|
-
var
|
|
8272
|
+
var Button14 = React17.forwardRef(function Button15({ children, kind = "secondary", className = "", ...props }, ref) {
|
|
7649
8273
|
return h2("button", {
|
|
7650
8274
|
...props,
|
|
7651
8275
|
ref,
|
|
@@ -7685,7 +8309,7 @@ function Heading6({ totals, busy, onAdd, addButtonRef }) {
|
|
|
7685
8309
|
h2(
|
|
7686
8310
|
"div",
|
|
7687
8311
|
{ className: "dim-bindActions" },
|
|
7688
|
-
h2(
|
|
8312
|
+
h2(Button14, {
|
|
7689
8313
|
kind: "primary",
|
|
7690
8314
|
className: "dim-scanButton",
|
|
7691
8315
|
onClick: onAdd,
|
|
@@ -7730,7 +8354,7 @@ function EmptyView6({ busy, onStart }) {
|
|
|
7730
8354
|
"div",
|
|
7731
8355
|
{ className: "ddt-actions dim-viewActions" },
|
|
7732
8356
|
h2(
|
|
7733
|
-
|
|
8357
|
+
Button14,
|
|
7734
8358
|
{ kind: "primary", onClick: onStart, disabled: busy },
|
|
7735
8359
|
busy ? "\u6B63\u5728\u751F\u6210\u4E8C\u7EF4\u7801\u2026" : "\u751F\u6210\u4E8C\u7EF4\u7801"
|
|
7736
8360
|
)
|
|
@@ -7799,8 +8423,8 @@ function QrPanel5({ provision, now, busy, onRefresh, onCancel }) {
|
|
|
7799
8423
|
h2(
|
|
7800
8424
|
"div",
|
|
7801
8425
|
{ className: "ddt-actions dim-viewActions" },
|
|
7802
|
-
h2(
|
|
7803
|
-
h2(
|
|
8426
|
+
h2(Button14, { onClick: onRefresh, disabled: busy }, "\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801"),
|
|
8427
|
+
h2(Button14, { kind: "quiet", onClick: onCancel, disabled: busy }, "\u53D6\u6D88")
|
|
7804
8428
|
)
|
|
7805
8429
|
)
|
|
7806
8430
|
)
|
|
@@ -7836,8 +8460,8 @@ function ProvisionView3({ provision, busy, onRetry, onClose }) {
|
|
|
7836
8460
|
h2(
|
|
7837
8461
|
"div",
|
|
7838
8462
|
{ className: "ddt-actions dim-viewActions" },
|
|
7839
|
-
h2(
|
|
7840
|
-
h2(
|
|
8463
|
+
h2(Button14, { kind: "primary", onClick: onRetry, disabled: busy }, "\u91CD\u65B0\u751F\u6210\u4E8C\u7EF4\u7801"),
|
|
8464
|
+
h2(Button14, { onClick: onClose, disabled: busy }, "\u5173\u95ED")
|
|
7841
8465
|
)
|
|
7842
8466
|
)
|
|
7843
8467
|
);
|
|
@@ -7851,9 +8475,9 @@ function RemoveConfirmation5({ account, busy, onConfirm, onCancel }) {
|
|
|
7851
8475
|
h2(
|
|
7852
8476
|
"div",
|
|
7853
8477
|
{ className: "ddt-actions dim-viewActions" },
|
|
7854
|
-
h2(
|
|
8478
|
+
h2(Button14, { onClick: onCancel, disabled: busy }, "\u4FDD\u7559\u673A\u5668\u4EBA"),
|
|
7855
8479
|
h2(
|
|
7856
|
-
|
|
8480
|
+
Button14,
|
|
7857
8481
|
{ kind: "danger", onClick: onConfirm, disabled: busy },
|
|
7858
8482
|
busy ? "\u6B63\u5728\u79FB\u9664\u2026" : "\u786E\u8BA4\u79FB\u9664\u63A5\u5165"
|
|
7859
8483
|
)
|
|
@@ -7873,7 +8497,7 @@ function WhatsappAccountCard({
|
|
|
7873
8497
|
}) {
|
|
7874
8498
|
const state = busy === "reconnect" ? "connecting" : account.state;
|
|
7875
8499
|
const tone = account.connected ? "success" : state === "error" ? "error" : "warning";
|
|
7876
|
-
const
|
|
8500
|
+
const stateLabel2 = account.connected ? "\u8FD0\u884C\u6B63\u5E38" : state === "connecting" ? "\u6B63\u5728\u8FDE\u63A5" : "\u8FDE\u63A5\u672A\u5C31\u7EEA";
|
|
7877
8501
|
const summary = account.error?.message ?? (account.connected ? null : account.health.summary);
|
|
7878
8502
|
return h2(
|
|
7879
8503
|
"article",
|
|
@@ -7902,7 +8526,7 @@ function WhatsappAccountCard({
|
|
|
7902
8526
|
"div",
|
|
7903
8527
|
{ className: "ddt-health dim-botHealth" },
|
|
7904
8528
|
h2("span", { className: "ddt-dot dim-healthDot", "data-tone": tone }),
|
|
7905
|
-
h2("span", null,
|
|
8529
|
+
h2("span", null, stateLabel2)
|
|
7906
8530
|
)
|
|
7907
8531
|
),
|
|
7908
8532
|
h2(
|
|
@@ -7937,12 +8561,12 @@ function WhatsappAccountCard({
|
|
|
7937
8561
|
h2(
|
|
7938
8562
|
"div",
|
|
7939
8563
|
{ className: "ddt-actions dim-cardActions" },
|
|
7940
|
-
h2(
|
|
8564
|
+
h2(Button14, {
|
|
7941
8565
|
className: "dim-cardAction",
|
|
7942
8566
|
onClick: onReconnect,
|
|
7943
8567
|
disabled: Boolean(busy)
|
|
7944
8568
|
}, busy === "reconnect" ? "\u68C0\u67E5\u4E2D\u2026" : account.connected ? "\u68C0\u67E5\u8FDE\u63A5" : "\u91CD\u8BD5\u8FDE\u63A5"),
|
|
7945
|
-
h2(
|
|
8569
|
+
h2(Button14, {
|
|
7946
8570
|
className: "dim-cardAction",
|
|
7947
8571
|
kind: "danger",
|
|
7948
8572
|
onClick: onRequestRemove,
|
|
@@ -7960,22 +8584,22 @@ function WhatsappAccountCard({
|
|
|
7960
8584
|
);
|
|
7961
8585
|
}
|
|
7962
8586
|
function WhatsappSettingsTab({ rpcCall }) {
|
|
7963
|
-
const [model, setModel] =
|
|
8587
|
+
const [model, setModel] = React17.useState({
|
|
7964
8588
|
phase: "loading",
|
|
7965
8589
|
bots: [],
|
|
7966
8590
|
totals: { configured: 0, connected: 0 },
|
|
7967
8591
|
error: null
|
|
7968
8592
|
});
|
|
7969
|
-
const [provision, setProvision] =
|
|
7970
|
-
const [busy, setBusy] =
|
|
7971
|
-
const [busyByBot, setBusyByBot] =
|
|
7972
|
-
const [testNoticeByBot, setTestNoticeByBot] =
|
|
7973
|
-
const [removeTarget, setRemoveTarget] =
|
|
7974
|
-
const [now, setNow] =
|
|
7975
|
-
const mounted =
|
|
8593
|
+
const [provision, setProvision] = React17.useState(null);
|
|
8594
|
+
const [busy, setBusy] = React17.useState(false);
|
|
8595
|
+
const [busyByBot, setBusyByBot] = React17.useState({});
|
|
8596
|
+
const [testNoticeByBot, setTestNoticeByBot] = React17.useState({});
|
|
8597
|
+
const [removeTarget, setRemoveTarget] = React17.useState(null);
|
|
8598
|
+
const [now, setNow] = React17.useState(Date.now());
|
|
8599
|
+
const mounted = React17.useRef(true);
|
|
7976
8600
|
const workspaceFence = useWorkspaceSnapshotFence();
|
|
7977
|
-
const addButtonRef =
|
|
7978
|
-
|
|
8601
|
+
const addButtonRef = React17.useRef(null);
|
|
8602
|
+
React17.useEffect(() => {
|
|
7979
8603
|
const disposeDingtalk = installDingtalkStyles();
|
|
7980
8604
|
const disposeWhatsapp = installWhatsappStyles();
|
|
7981
8605
|
mounted.current = true;
|
|
@@ -7985,11 +8609,11 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
7985
8609
|
disposeDingtalk();
|
|
7986
8610
|
};
|
|
7987
8611
|
}, []);
|
|
7988
|
-
const invoke =
|
|
8612
|
+
const invoke = React17.useCallback(async (endpoint, payload = {}, signal) => {
|
|
7989
8613
|
if (typeof rpcCall !== "function") throw new TypeError("WhatsApp \u8BBE\u7F6E\u9875\u7F3A\u5C11 RPC \u8FDE\u63A5");
|
|
7990
8614
|
return unwrapRpcResult9(await rpcCall(endpoint, payload, signal));
|
|
7991
8615
|
}, [rpcCall]);
|
|
7992
|
-
const loadStatus =
|
|
8616
|
+
const loadStatus = React17.useCallback(async ({ signal, silent = false, restore = false } = {}) => {
|
|
7993
8617
|
const workspaceVersion = workspaceFence.beginStatus();
|
|
7994
8618
|
if (workspaceVersion === null) return void 0;
|
|
7995
8619
|
if (!silent && mounted.current) setModel((current) => ({ ...current, phase: "loading", error: null }));
|
|
@@ -8013,12 +8637,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
8013
8637
|
return void 0;
|
|
8014
8638
|
}
|
|
8015
8639
|
}, [invoke, workspaceFence]);
|
|
8016
|
-
|
|
8640
|
+
React17.useEffect(() => {
|
|
8017
8641
|
const controller = new AbortController();
|
|
8018
8642
|
void loadStatus({ signal: controller.signal, restore: true });
|
|
8019
8643
|
return () => controller.abort();
|
|
8020
8644
|
}, [loadStatus]);
|
|
8021
|
-
|
|
8645
|
+
React17.useEffect(() => {
|
|
8022
8646
|
if (model.phase !== "ready") return void 0;
|
|
8023
8647
|
const controller = new AbortController();
|
|
8024
8648
|
const timer = window.setInterval(
|
|
@@ -8030,12 +8654,12 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
8030
8654
|
window.clearInterval(timer);
|
|
8031
8655
|
};
|
|
8032
8656
|
}, [loadStatus, model.phase]);
|
|
8033
|
-
|
|
8657
|
+
React17.useEffect(() => {
|
|
8034
8658
|
if (!provision || !ACTIVE_STATES3.has(provision.status)) return void 0;
|
|
8035
8659
|
const timer = window.setInterval(() => mounted.current && setNow(Date.now()), 1e3);
|
|
8036
8660
|
return () => window.clearInterval(timer);
|
|
8037
8661
|
}, [provision?.attemptId, provision?.status]);
|
|
8038
|
-
const startProvisioning =
|
|
8662
|
+
const startProvisioning = React17.useCallback(async (replace = false) => {
|
|
8039
8663
|
setBusy(true);
|
|
8040
8664
|
try {
|
|
8041
8665
|
if (replace && provision?.attemptId) {
|
|
@@ -8053,7 +8677,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
8053
8677
|
if (mounted.current) setBusy(false);
|
|
8054
8678
|
}
|
|
8055
8679
|
}, [invoke, provision?.attemptId]);
|
|
8056
|
-
const closeProvision =
|
|
8680
|
+
const closeProvision = React17.useCallback(async () => {
|
|
8057
8681
|
setBusy(true);
|
|
8058
8682
|
try {
|
|
8059
8683
|
if (provision?.attemptId && ACTIVE_STATES3.has(provision.status)) {
|
|
@@ -8064,7 +8688,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
8064
8688
|
if (mounted.current) setBusy(false);
|
|
8065
8689
|
}
|
|
8066
8690
|
}, [invoke, provision?.attemptId, provision?.status]);
|
|
8067
|
-
|
|
8691
|
+
React17.useEffect(() => {
|
|
8068
8692
|
const attemptId = provision?.attemptId;
|
|
8069
8693
|
if (!attemptId || !ACTIVE_STATES3.has(provision.status)) return void 0;
|
|
8070
8694
|
const controller = new AbortController();
|
|
@@ -8105,7 +8729,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
8105
8729
|
if (timer) window.clearTimeout(timer);
|
|
8106
8730
|
};
|
|
8107
8731
|
}, [invoke, loadStatus, provision?.attemptId, provision?.status]);
|
|
8108
|
-
const botAction =
|
|
8732
|
+
const botAction = React17.useCallback(async (account, operation, endpoint, payload) => {
|
|
8109
8733
|
const snapshotVersion = workspaceFence.beginMutation();
|
|
8110
8734
|
setBusyByBot((current) => ({ ...current, [account.botId]: operation }));
|
|
8111
8735
|
if (operation === "reconnect") {
|
|
@@ -8201,10 +8825,10 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
8201
8825
|
{ className: "ddt-inlineError dim-inlineError" },
|
|
8202
8826
|
h2("h3", null, "\u65E0\u6CD5\u8BFB\u53D6 WhatsApp \u673A\u5668\u4EBA\u72B6\u6001"),
|
|
8203
8827
|
h2("p", null, model.error?.message),
|
|
8204
|
-
h2(
|
|
8828
|
+
h2(Button14, { onClick: () => void loadStatus() }, "\u91CD\u65B0\u8BFB\u53D6")
|
|
8205
8829
|
)
|
|
8206
8830
|
) : h2(
|
|
8207
|
-
|
|
8831
|
+
React17.Fragment,
|
|
8208
8832
|
null,
|
|
8209
8833
|
provision?.status === "pending" ? h2(QrPanel5, {
|
|
8210
8834
|
provision,
|
|
@@ -8225,7 +8849,7 @@ function WhatsappSettingsTab({ rpcCall }) {
|
|
|
8225
8849
|
|
|
8226
8850
|
// plugin-src/client/styles.js
|
|
8227
8851
|
var IM_STYLE_ID = "xmanrui-dsh-im-settings";
|
|
8228
|
-
var
|
|
8852
|
+
var CSS11 = String.raw`
|
|
8229
8853
|
.dim-page {
|
|
8230
8854
|
--dim-blue: var(--dsw-alias-state-business-primary, #3370ff);
|
|
8231
8855
|
--dim-blue-soft: color-mix(in srgb, var(--dim-blue) 9%, transparent);
|
|
@@ -8237,9 +8861,9 @@ var CSS10 = String.raw`
|
|
|
8237
8861
|
}
|
|
8238
8862
|
.dim-page *, .dim-page *::before, .dim-page *::after { box-sizing: border-box; }
|
|
8239
8863
|
.dim-title { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin: 0 0 18px; }
|
|
8240
|
-
.dim-brand { min-width: 0; display: flex; align-items:
|
|
8241
|
-
.dim-
|
|
8242
|
-
.dim-title p { margin: 0; color: var(--dsw-alias-label-
|
|
8864
|
+
.dim-brand { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 1px; }
|
|
8865
|
+
.dim-brandName { color: var(--dsw-alias-label-primary, #1f2329); font-size: 20px; line-height: 24px; font-weight: 800; letter-spacing: .04em; }
|
|
8866
|
+
.dim-title p { margin: 0; color: var(--dsw-alias-label-secondary, #646a73); font-size: 12px; line-height: 18px; font-weight: 500; white-space: nowrap; }
|
|
8243
8867
|
.dim-githubAction { position: relative; display: inline-flex; flex: none; }
|
|
8244
8868
|
.dim-githubLink { min-height: 30px; display: inline-flex; align-items: center; gap: 5px; flex: none; padding: 0 10px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 8px; color: var(--dsw-alias-label-secondary, #646a73); background: var(--dsw-alias-bg-layer-1, #fff); font-size: 12px; line-height: normal; font-weight: 560; text-decoration: none; transition: border-color .15s ease, color .15s ease, background .15s ease; }
|
|
8245
8869
|
.dim-githubLink:hover { border-color: #aeb3bb; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-interactive-bg-hover, #f7f8fa); }
|
|
@@ -8269,6 +8893,8 @@ var CSS10 = String.raw`
|
|
|
8269
8893
|
.dim-logoWecom svg { width: 22px; height: 22px; }
|
|
8270
8894
|
.dim-logoTelegram { color: white; background: #229ed9; }
|
|
8271
8895
|
.dim-logoTelegram svg { width: 21px; height: 21px; }
|
|
8896
|
+
.dim-logoOffice { color: white; background: linear-gradient(145deg, #12213f, #3964fe); }
|
|
8897
|
+
.dim-logoOffice svg { width: 23px; height: 23px; }
|
|
8272
8898
|
.dim-logoDiscord { color: white; background: #5865f2; }
|
|
8273
8899
|
.dim-logoDiscord svg { width: 21px; height: 21px; }
|
|
8274
8900
|
.dim-logoSlack { color: white; background: #4a154b; }
|
|
@@ -8487,7 +9113,7 @@ function installImStyles() {
|
|
|
8487
9113
|
const style = document.createElement("style");
|
|
8488
9114
|
style.dataset.plugin = "@xmanrui/dsh-im";
|
|
8489
9115
|
style.dataset.pluginCss = IM_STYLE_ID;
|
|
8490
|
-
style.textContent =
|
|
9116
|
+
style.textContent = CSS11;
|
|
8491
9117
|
document.head.appendChild(style);
|
|
8492
9118
|
return () => style.remove();
|
|
8493
9119
|
}
|
|
@@ -8495,7 +9121,6 @@ function installImStyles() {
|
|
|
8495
9121
|
// plugin-src/client/index.js
|
|
8496
9122
|
var name = "im-settings";
|
|
8497
9123
|
var inject = ["slots", "connection", "locale", "workspaces"];
|
|
8498
|
-
var IM_PLUGIN_LOGO_URL = "data:image/png;base64,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";
|
|
8499
9124
|
var CHANNELS = Object.freeze([
|
|
8500
9125
|
{ id: "weixin", label: "\u5FAE\u4FE1" },
|
|
8501
9126
|
{ id: "feishu", label: "\u98DE\u4E66" },
|
|
@@ -8505,7 +9130,8 @@ var CHANNELS = Object.freeze([
|
|
|
8505
9130
|
{ id: "slack", label: "Slack" },
|
|
8506
9131
|
{ id: "telegram", label: "Telegram" },
|
|
8507
9132
|
{ id: "discord", label: "Discord" },
|
|
8508
|
-
{ id: "whatsapp", label: "WhatsApp" }
|
|
9133
|
+
{ id: "whatsapp", label: "WhatsApp" },
|
|
9134
|
+
{ id: "office", label: "AI Office" }
|
|
8509
9135
|
]);
|
|
8510
9136
|
function WeixinLogo() {
|
|
8511
9137
|
return h2(
|
|
@@ -8562,6 +9188,13 @@ function WhatsappLogo() {
|
|
|
8562
9188
|
h2(WhatsappLogoGlyph)
|
|
8563
9189
|
);
|
|
8564
9190
|
}
|
|
9191
|
+
function OfficeLogo() {
|
|
9192
|
+
return h2(
|
|
9193
|
+
"span",
|
|
9194
|
+
{ className: "dim-logo dim-logoOffice", "aria-hidden": "true" },
|
|
9195
|
+
h2(OfficeLogoGlyph)
|
|
9196
|
+
);
|
|
9197
|
+
}
|
|
8565
9198
|
function ChannelLogo({ channel: channel4 }) {
|
|
8566
9199
|
if (channel4 === "weixin") return h2(WeixinLogo);
|
|
8567
9200
|
if (channel4 === "feishu") return h2(FeishuLogo);
|
|
@@ -8571,7 +9204,8 @@ function ChannelLogo({ channel: channel4 }) {
|
|
|
8571
9204
|
if (channel4 === "slack") return h2(SlackLogo);
|
|
8572
9205
|
if (channel4 === "telegram") return h2(TelegramLogo);
|
|
8573
9206
|
if (channel4 === "discord") return h2(DiscordLogo);
|
|
8574
|
-
return h2(WhatsappLogo);
|
|
9207
|
+
if (channel4 === "whatsapp") return h2(WhatsappLogo);
|
|
9208
|
+
return h2(OfficeLogo);
|
|
8575
9209
|
}
|
|
8576
9210
|
function IMSettingsTab({
|
|
8577
9211
|
dingtalkRpcCall,
|
|
@@ -8583,10 +9217,11 @@ function IMSettingsTab({
|
|
|
8583
9217
|
wecomRpcCall,
|
|
8584
9218
|
weixinRpcCall,
|
|
8585
9219
|
whatsappRpcCall,
|
|
9220
|
+
officeRpcCall,
|
|
8586
9221
|
workspaceDirectoryPicker
|
|
8587
9222
|
}) {
|
|
8588
|
-
const [selected, setSelected] =
|
|
8589
|
-
const githubTooltipId =
|
|
9223
|
+
const [selected, setSelected] = React18.useState("weixin");
|
|
9224
|
+
const githubTooltipId = React18.useId();
|
|
8590
9225
|
const active = CHANNELS.find((channel4) => channel4.id === selected) ?? CHANNELS[0];
|
|
8591
9226
|
return h2(
|
|
8592
9227
|
WorkspaceDirectoryPickerContext.Provider,
|
|
@@ -8600,14 +9235,8 @@ function IMSettingsTab({
|
|
|
8600
9235
|
h2(
|
|
8601
9236
|
"div",
|
|
8602
9237
|
{ className: "dim-brand" },
|
|
8603
|
-
h2("
|
|
8604
|
-
|
|
8605
|
-
src: IM_PLUGIN_LOGO_URL,
|
|
8606
|
-
alt: "dsh-im",
|
|
8607
|
-
width: 48,
|
|
8608
|
-
height: 48
|
|
8609
|
-
}),
|
|
8610
|
-
h2("p", null, "\u8BA9\u804A\u5929\u673A\u5668\u4EBA\u8F7B\u677E\u63A5\u5165 DeepSeek Harness")
|
|
9238
|
+
h2("strong", { className: "dim-brandName" }, "DSH-IM"),
|
|
9239
|
+
h2("p", null, "\u8BA9 DeepSeek Harness \u89E6\u624B\u53EF\u53CA")
|
|
8611
9240
|
),
|
|
8612
9241
|
h2(
|
|
8613
9242
|
"span",
|
|
@@ -8664,7 +9293,7 @@ function IMSettingsTab({
|
|
|
8664
9293
|
role: "tabpanel",
|
|
8665
9294
|
id: `dim-panel-${active.id}`,
|
|
8666
9295
|
"aria-labelledby": `dim-tab-${active.id}`
|
|
8667
|
-
}, active.id === "weixin" ? h2(WeixinSettingsTab, { rpcCall: weixinRpcCall }) : active.id === "feishu" ? h2(FeishuSettingsTab, { rpcCall: feishuRpcCall }) : active.id === "dingtalk" ? h2(DingtalkSettingsTab, { rpcCall: dingtalkRpcCall }) : active.id === "wecom" ? h2(WecomSettingsTab, { rpcCall: wecomRpcCall }) : active.id === "qq" ? h2(QqSettingsTab, { rpcCall: qqRpcCall }) : active.id === "slack" ? h2(SlackSettingsTab, { rpcCall: slackRpcCall }) : active.id === "telegram" ? h2(TelegramSettingsTab, { rpcCall: telegramRpcCall }) : active.id === "discord" ? h2(DiscordSettingsTab, { rpcCall: discordRpcCall }) : h2(WhatsappSettingsTab, { rpcCall: whatsappRpcCall }))
|
|
9296
|
+
}, active.id === "weixin" ? h2(WeixinSettingsTab, { rpcCall: weixinRpcCall }) : active.id === "feishu" ? h2(FeishuSettingsTab, { rpcCall: feishuRpcCall }) : active.id === "dingtalk" ? h2(DingtalkSettingsTab, { rpcCall: dingtalkRpcCall }) : active.id === "wecom" ? h2(WecomSettingsTab, { rpcCall: wecomRpcCall }) : active.id === "qq" ? h2(QqSettingsTab, { rpcCall: qqRpcCall }) : active.id === "slack" ? h2(SlackSettingsTab, { rpcCall: slackRpcCall }) : active.id === "telegram" ? h2(TelegramSettingsTab, { rpcCall: telegramRpcCall }) : active.id === "discord" ? h2(DiscordSettingsTab, { rpcCall: discordRpcCall }) : active.id === "whatsapp" ? h2(WhatsappSettingsTab, { rpcCall: whatsappRpcCall }) : h2(OfficeSettingsTab, { rpcCall: officeRpcCall }))
|
|
8668
9297
|
)
|
|
8669
9298
|
)
|
|
8670
9299
|
);
|
|
@@ -8686,6 +9315,7 @@ function apply(ctx) {
|
|
|
8686
9315
|
installTelegramStyles(),
|
|
8687
9316
|
installDiscordStyles(),
|
|
8688
9317
|
installWhatsappStyles(),
|
|
9318
|
+
installOfficeStyles(),
|
|
8689
9319
|
installImStyles()
|
|
8690
9320
|
];
|
|
8691
9321
|
return () => {
|
|
@@ -8701,6 +9331,7 @@ function apply(ctx) {
|
|
|
8701
9331
|
const discordRpcCall = (endpoint, payload, signal) => ctx.connection.rpc.call(DISCORD_RPC_CHANNEL, endpoint, payload, signal);
|
|
8702
9332
|
const whatsappRpcCall = (endpoint, payload, signal) => ctx.connection.rpc.call(WHATSAPP_RPC_CHANNEL, endpoint, payload, signal);
|
|
8703
9333
|
const slackRpcCall = (endpoint, payload, signal) => ctx.connection.rpc.call(SLACK_RPC_CHANNEL, endpoint, payload, signal);
|
|
9334
|
+
const officeRpcCall = (endpoint, payload, signal) => ctx.connection.rpc.call(OFFICE_RPC_CHANNEL, endpoint, payload, signal);
|
|
8704
9335
|
const workspaceDirectoryPicker = Object.freeze({
|
|
8705
9336
|
listDirectory: (path, signal) => ctx.workspaces.listDirectory(path, signal),
|
|
8706
9337
|
pickDirectory: () => ctx.workspaces.pickDirectory()
|
|
@@ -8721,6 +9352,7 @@ function apply(ctx) {
|
|
|
8721
9352
|
wecomRpcCall,
|
|
8722
9353
|
weixinRpcCall,
|
|
8723
9354
|
whatsappRpcCall,
|
|
9355
|
+
officeRpcCall,
|
|
8724
9356
|
workspaceDirectoryPicker
|
|
8725
9357
|
})
|
|
8726
9358
|
}, IMSettingsTab));
|