dsh-composer-ux 0.16.4 → 0.17.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/CHANGELOG.md +42 -0
- package/README.md +3 -3
- package/lib/client.js +183 -1
- package/lib/client.js.map +2 -2
- package/lib/index.js +522 -4
- package/lib/index.js.map +4 -4
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
4
4
|
|
|
5
|
+
## [0.17.0] — 2026-10-01(新增:单向微信通知)
|
|
6
|
+
|
|
7
|
+
用户 2026-10-01 明确:**只要通知,不做双向**、不走 OpenClaw,用现成的微信推送服务。界面里固定标注
|
|
8
|
+
**「只能通知,不能回」** —— 不暗示一个不存在的能力。
|
|
9
|
+
|
|
10
|
+
- **两条渠道**:PushPlus token(推到你关注的公众号对话)/ 企业微信群机器人 webhook;总开关**默认关**。
|
|
11
|
+
- **三类事件**(照 dsh-messager 那套):需要你回应(等审批 / 等你回答)· 任务完成 · 任务出错。
|
|
12
|
+
挂在官方事件上:、(**waterfall 透传**,只观察不代答)、
|
|
13
|
+
(只有 running→idle 才算完成)、。
|
|
14
|
+
- **防刷屏**:30 秒内同会话同类合并(按会话分桶,别的会话完成不会被吞)。
|
|
15
|
+
- **测试推送**:绕过防刷屏与分类开关(但仍要求总开关开着、凭据填了),且**不写记账**
|
|
16
|
+
—— 否则一次测试会压掉后面真实的通知。
|
|
17
|
+
- **凭据安全**:只存本机;界面与日志只显示打码形式(头 4 尾 2);响应体与错误信息里绝不回显 token。
|
|
18
|
+
- **投递在宿主侧**:标签页关着也能推。宿主没有事件总线时**只告警不挂**(通知挂不上绝不连累宿主启动)。
|
|
19
|
+
|
|
20
|
+
## 验证
|
|
21
|
+
|
|
22
|
+
- `npm test`:**28 个套件 2473 passed / 0 failed**(新增 4 个套件:微信通知核心 / 事件适配 /
|
|
23
|
+
发送器 / 测试推送路由)。
|
|
24
|
+
- 变异:**167/167 全部咬住**(新增 FP 审批不再透传、FQ 去掉防刷屏、FR 凭据不打码;并把 0.16.4
|
|
25
|
+
滚动改动后失效的 EC/FC 两条重新对准当前结构)。
|
|
26
|
+
|
|
27
|
+
## 待用户验收(不是已验证)
|
|
28
|
+
|
|
29
|
+
**「消息真的到你手机」这一步我无法验证** —— 这台机器上没有 PushPlus token、也没有群机器人地址。
|
|
30
|
+
请你在设置页打开总开关、填好凭据、点一次**「发送测试」**:界面上会显示渠道给的原话(成功或失败原因)。
|
|
31
|
+
在这条完成之前,请不要把本功能当成已验证。
|
|
32
|
+
|
|
33
|
+
## [0.16.5] — 2026-10-01(设置页抬头加「官网 ↗」)
|
|
34
|
+
|
|
35
|
+
起因(用户原话):**「https://www.deepseek.com/harness/ 把这个 DSH 的官网链接放到我的插件里」**;
|
|
36
|
+
被问到时选择放在**设置页抬头、GitHub 旁边**。
|
|
37
|
+
|
|
38
|
+
- 地址只写进契约(`settings-contract.ts` 的 `SITE_URL`),客户端引它 —— 与 `REPO_URL` 同一处理,
|
|
39
|
+
界面上不许硬编码第二份;
|
|
40
|
+
- 链接放在 GitHub 链接**右边**,不打乱既有约定「重启按钮在链接左边」;
|
|
41
|
+
- 新断言盯住它:抬头里必须有 `href={SITE_URL}`,且排在 `href={REPO_URL}` 之后。
|
|
42
|
+
|
|
43
|
+
## 验证
|
|
44
|
+
|
|
45
|
+
- `npm test`:**24 个套件 2385 passed / 0 failed**。
|
|
46
|
+
|
|
5
47
|
## [0.16.4] — 2026-10-01(面板可以整块滚了:那排被切的按钮能划到)
|
|
6
48
|
|
|
7
49
|
起因(用户原话):**「让这个页面可以滑动,使其一些按钮不被遮挡」**(截图里快捷指令/优化面板
|
package/README.md
CHANGED
|
@@ -518,7 +518,7 @@ Windows 上 DSH 给模型的终端工具是 **PowerShell**(工具名 `pwsh`)
|
|
|
518
518
|
| 工具循环的消息形状 / 轮次封顶 / 异常必须降级 | 同上第 6 节(假 llm 驱动整条循环,逐条检查 `role:'tool'` 与 `toolCallId`) |
|
|
519
519
|
| 工具路径:默认关、开了才派、**查完吐散文必须回落**、拿不到工作目录就不派 | `test/quick-commands.mjs` 5g 节(13 条,真路由 + 假 llm) |
|
|
520
520
|
| 工具读到的内容不进台账 | 同 5g 节:断言台账里只有工具名与次数、没有读到的文件内容 |
|
|
521
|
-
| 变异守卫真的会咬人,且**必须是指定的那条测试变红** | `npm run test:mutations`:**
|
|
521
|
+
| 变异守卫真的会咬人,且**必须是指定的那条测试变红** | `npm run test:mutations`:**167 条全部咬住**(判据是 `red.some(line => line.includes(item.expect))`,不是"有红就行") |
|
|
522
522
|
| 发布门禁三条判据 | `npm run gates` 全过;`check:tag` 实测 `v0.12.0` 的 tag 名与所指提交里的版本一致 |
|
|
523
523
|
| 三平台 CI | GitHub Actions:ubuntu / windows / macos × Node 20(`npm ci → typecheck → build → test → check:pack → check:docs`) |
|
|
524
524
|
|
|
@@ -652,9 +652,9 @@ node build.mjs # 产出 lib/index.js + lib/client.js
|
|
|
652
652
|
# ⚠️ 宿主半会**内联** schemastery / cosmokit:
|
|
653
653
|
# 优先用 DSH 检出里的 vendor 副本,检出不在时退到 node_modules
|
|
654
654
|
# 里同版本的 npm 包(两者逐字节相同)——CI 上走的就是退路
|
|
655
|
-
npm test #
|
|
655
|
+
npm test # 28 个套件;当前 2473 passed, 0 failed(2026-09-29 实测;CI 三平台同样全绿)
|
|
656
656
|
# 走 scripts/run-tests.mjs:顺带把"多少套件/多少条"记进 test/.last-run.json
|
|
657
|
-
npm run test:mutations # 手动跑:变异测试,证明那套护栏真的在咬人(
|
|
657
|
+
npm run test:mutations # 手动跑:变异测试,证明那套护栏真的在咬人(167 条,须单独跑)
|
|
658
658
|
# 同样记录结果,供下面的文档门禁核对
|
|
659
659
|
npm run gates # 发版门禁三条一起跑:tag 指向 / 包内容 / 文档数字
|
|
660
660
|
npm run check:tag # ① tag 名里的版本 == 该 tag 所指提交里的 package.json 版本
|
package/lib/client.js
CHANGED
|
@@ -1003,6 +1003,7 @@ function sanitizeTerminalCandidates(value) {
|
|
|
1003
1003
|
// src/settings-contract.ts
|
|
1004
1004
|
var NAMESPACE = "composer-ux";
|
|
1005
1005
|
var REPO_URL = "https://github.com/fangwen9527/dsh-composer-ux";
|
|
1006
|
+
var SITE_URL = "https://www.deepseek.com/harness/";
|
|
1006
1007
|
var RESTART_API_PATH = "/composer-ux/restart";
|
|
1007
1008
|
var USAGE_API_PATH = "/composer-ux/usage";
|
|
1008
1009
|
var MODELS_API_PATH = "/composer-ux/models";
|
|
@@ -1010,6 +1011,12 @@ var RESTART_CSRF_HEADER = "x-composer-ux-restart";
|
|
|
1010
1011
|
var RESTART_CSRF_VALUE = "1";
|
|
1011
1012
|
var SYNC_API_PATH = "/composer-ux/sync-prices";
|
|
1012
1013
|
var ENABLED_FIELD = "enabled";
|
|
1014
|
+
var NOTIFY_ENABLED_FIELD = "notifyEnabled";
|
|
1015
|
+
var NOTIFY_CHANNEL_FIELD = "notifyChannel";
|
|
1016
|
+
var NOTIFY_PUSHPLUS_FIELD = "notifyPushplusToken";
|
|
1017
|
+
var NOTIFY_WECOM_FIELD = "notifyWecomWebhook";
|
|
1018
|
+
var NOTIFY_KINDS_FIELD = "notifyKinds";
|
|
1019
|
+
var NOTIFY_TEST_API_PATH = "/composer-ux/notify/test";
|
|
1013
1020
|
var KEYS_ENABLED_FIELD = "keysEnabled";
|
|
1014
1021
|
var MENU_ENABLED_FIELD = "menuEnabled";
|
|
1015
1022
|
var QUICK_ENABLED_FIELD = "quickEnabled";
|
|
@@ -1277,6 +1284,12 @@ var DEFAULT_HEADER_NAME = "x-opencode-session";
|
|
|
1277
1284
|
var HEADER_VALUE_MAX = 200;
|
|
1278
1285
|
var HEADER_NAME_MAX = 64;
|
|
1279
1286
|
var DEFAULT_SETTINGS = {
|
|
1287
|
+
// 微信通知:默认全关全空(0.17.0)。
|
|
1288
|
+
notifyEnabled: false,
|
|
1289
|
+
notifyChannel: "pushplus",
|
|
1290
|
+
notifyPushplusToken: "",
|
|
1291
|
+
notifyWecomWebhook: "",
|
|
1292
|
+
notifyKinds: { "needs-input": true, done: true, error: true },
|
|
1280
1293
|
// 总开关默认开:它只是总闸,真正"要不要用这一栏"由下面五个开关决定(默认关)。
|
|
1281
1294
|
enabled: true,
|
|
1282
1295
|
// 五栏默认关(老文档由 sectionEnabledOf 迁移成"碰过就开")。
|
|
@@ -1488,7 +1501,26 @@ function sanitizeSettings(value) {
|
|
|
1488
1501
|
return out;
|
|
1489
1502
|
};
|
|
1490
1503
|
const asTier = () => normalizeOptimizerTier(source[OPTIMIZER_TIER_FIELD]);
|
|
1504
|
+
const asNotifyChannel = () => {
|
|
1505
|
+
const raw = source[NOTIFY_CHANNEL_FIELD];
|
|
1506
|
+
return raw === "wecom" ? "wecom" : "pushplus";
|
|
1507
|
+
};
|
|
1508
|
+
const asNotifyKinds = () => {
|
|
1509
|
+
const raw = source[NOTIFY_KINDS_FIELD];
|
|
1510
|
+
const row2 = typeof raw === "object" && raw !== null ? raw : {};
|
|
1511
|
+
return {
|
|
1512
|
+
"needs-input": row2["needs-input"] !== false,
|
|
1513
|
+
done: row2.done !== false,
|
|
1514
|
+
error: row2.error !== false
|
|
1515
|
+
};
|
|
1516
|
+
};
|
|
1491
1517
|
return {
|
|
1518
|
+
// 微信通知(0.17.0,单向):默认全关/全空。
|
|
1519
|
+
notifyEnabled: asBool(NOTIFY_ENABLED_FIELD),
|
|
1520
|
+
notifyChannel: asNotifyChannel(),
|
|
1521
|
+
notifyPushplusToken: asString(NOTIFY_PUSHPLUS_FIELD),
|
|
1522
|
+
notifyWecomWebhook: asString(NOTIFY_WECOM_FIELD),
|
|
1523
|
+
notifyKinds: asNotifyKinds(),
|
|
1492
1524
|
enabled: asBool(ENABLED_FIELD),
|
|
1493
1525
|
// 五栏开关:显式写过听它的,否则按"用户碰过没"迁移(见 sectionEnabledOf)。
|
|
1494
1526
|
keysEnabled: sectionEnabledOf(KEYS_ENABLED_FIELD, source),
|
|
@@ -5832,6 +5864,141 @@ function useRestart() {
|
|
|
5832
5864
|
};
|
|
5833
5865
|
return { stage, detail: detail2, blocked, ask, confirm, cancel };
|
|
5834
5866
|
}
|
|
5867
|
+
function maskSecret(value) {
|
|
5868
|
+
if (value === "") return "";
|
|
5869
|
+
return value.length < 8 ? "****" : `${value.slice(0, 4)}\u2026${value.slice(-2)}`;
|
|
5870
|
+
}
|
|
5871
|
+
function NotifyCard({ settings, setField }) {
|
|
5872
|
+
const on = settings.notifyEnabled;
|
|
5873
|
+
const channel = settings.notifyChannel;
|
|
5874
|
+
const kinds = settings.notifyKinds;
|
|
5875
|
+
const [busy, setBusy] = (0, import_react7.useState)(false);
|
|
5876
|
+
const [note2, setNote] = (0, import_react7.useState)("");
|
|
5877
|
+
const send = () => {
|
|
5878
|
+
setBusy(true);
|
|
5879
|
+
setNote("");
|
|
5880
|
+
void fetch(NOTIFY_TEST_API_PATH, {
|
|
5881
|
+
method: "POST",
|
|
5882
|
+
headers: { "content-type": "application/json", [RESTART_CSRF_HEADER]: RESTART_CSRF_VALUE },
|
|
5883
|
+
body: "{}"
|
|
5884
|
+
}).then(async (r) => await r.json()).then((v) => {
|
|
5885
|
+
setNote(v.ok === true ? "\u5DF2\u53D1\u51FA \u2014\u2014 \u53BB\u5FAE\u4FE1\u770B\u4E00\u773C\uFF08\u8FD9\u91CC\u4E0D\u5199\u201C\u5DF2\u9A8C\u8BC1\u201D\uFF0C\u53EA\u6709\u4F60\u80FD\u786E\u8BA4\uFF09" : `\u6CA1\u53D1\u51FA\u53BB\uFF1A${v.reason ?? "\u672A\u77E5\u539F\u56E0"}`);
|
|
5886
|
+
}).catch((e) => {
|
|
5887
|
+
setNote(`\u8BF7\u6C42\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
5888
|
+
}).finally(() => {
|
|
5889
|
+
setBusy(false);
|
|
5890
|
+
});
|
|
5891
|
+
};
|
|
5892
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
5893
|
+
FoldCard,
|
|
5894
|
+
{
|
|
5895
|
+
name: "\u5FAE\u4FE1\u901A\u77E5",
|
|
5896
|
+
summary: on ? `\u5DF2\u5F00 \xB7 ${channel === "pushplus" ? "PushPlus" : "\u4F01\u4E1A\u5FAE\u4FE1\u673A\u5668\u4EBA"} \xB7 \u53EA\u80FD\u901A\u77E5\uFF0C\u4E0D\u80FD\u56DE` : "\u672A\u542F\u7528 \xB7 \u53EA\u80FD\u901A\u77E5\uFF0C\u4E0D\u80FD\u56DE",
|
|
5897
|
+
toggle: { checked: on, onChange: (next) => {
|
|
5898
|
+
setField(NOTIFY_ENABLED_FIELD, next);
|
|
5899
|
+
} },
|
|
5900
|
+
children: [
|
|
5901
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { margin: "10px 0", fontSize: 12, lineHeight: 1.6, opacity: 0.85 }, children: [
|
|
5902
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: "\u53EA\u80FD\u901A\u77E5\uFF0C\u4E0D\u80FD\u56DE\u3002" }),
|
|
5903
|
+
"\u9700\u8981\u4F60\u56DE\u5E94 / \u5B8C\u6210 / \u51FA\u9519\u65F6\u63A8\u4E00\u6761\u5230\u4F60\u624B\u673A\uFF1B\u8981\u5904\u7406\u4ECD\u56DE DSH \u754C\u9762\u70B9\u3002"
|
|
5904
|
+
] }),
|
|
5905
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5906
|
+
ToggleRow,
|
|
5907
|
+
{
|
|
5908
|
+
label: "\u7528 PushPlus\uFF08\u5230\u4F60\u5173\u6CE8\u7684\u516C\u4F17\u53F7\uFF09",
|
|
5909
|
+
desc: "pushplus.plus \u7528\u5FAE\u4FE1\u767B\u5F55\u62FF token\uFF0C\u586B\u5728\u4E0B\u9762\u3002",
|
|
5910
|
+
checked: channel === "pushplus",
|
|
5911
|
+
onChange: () => {
|
|
5912
|
+
setField(NOTIFY_CHANNEL_FIELD, "pushplus");
|
|
5913
|
+
},
|
|
5914
|
+
first: true
|
|
5915
|
+
}
|
|
5916
|
+
),
|
|
5917
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5918
|
+
TextFieldRow,
|
|
5919
|
+
{
|
|
5920
|
+
title: "PushPlus token",
|
|
5921
|
+
desc: settings.notifyPushplusToken === "" ? "\u8FD8\u6CA1\u586B\uFF08\u586B\u4E86\u624D\u80FD\u63A8\u9001\uFF09" : `\u5F53\u524D\uFF1A${maskSecret(settings.notifyPushplusToken)}\uFF08\u8981\u770B\u5168\u6587\u8BF7\u91CD\u65B0\u7C98\u8D34\uFF09`,
|
|
5922
|
+
value: settings.notifyPushplusToken,
|
|
5923
|
+
placeholder: "\u7C98\u8D34 token",
|
|
5924
|
+
maxLength: 200,
|
|
5925
|
+
onChange: (next) => {
|
|
5926
|
+
setField(NOTIFY_PUSHPLUS_FIELD, next);
|
|
5927
|
+
}
|
|
5928
|
+
}
|
|
5929
|
+
),
|
|
5930
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5931
|
+
ToggleRow,
|
|
5932
|
+
{
|
|
5933
|
+
label: "\u7528\u4F01\u4E1A\u5FAE\u4FE1\u7FA4\u673A\u5668\u4EBA",
|
|
5934
|
+
desc: "\u53EA\u6709\u4F60\u7684\u4F01\u4E1A\u5FAE\u4FE1\u7FA4\u91CC\u52A0\u4E2A\u673A\u5668\u4EBA\uFF0C\u628A webhook \u586B\u4E0B\u9762\u3002",
|
|
5935
|
+
checked: channel === "wecom",
|
|
5936
|
+
onChange: () => {
|
|
5937
|
+
setField(NOTIFY_CHANNEL_FIELD, "wecom");
|
|
5938
|
+
}
|
|
5939
|
+
}
|
|
5940
|
+
),
|
|
5941
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5942
|
+
TextFieldRow,
|
|
5943
|
+
{
|
|
5944
|
+
title: "\u4F01\u4E1A\u5FAE\u4FE1 webhook",
|
|
5945
|
+
desc: settings.notifyWecomWebhook === "" ? "\u8FD8\u6CA1\u586B" : `\u5F53\u524D\uFF1A${maskSecret(settings.notifyWecomWebhook)}`,
|
|
5946
|
+
value: settings.notifyWecomWebhook,
|
|
5947
|
+
placeholder: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=\u2026",
|
|
5948
|
+
maxLength: 500,
|
|
5949
|
+
onChange: (next) => {
|
|
5950
|
+
setField(NOTIFY_WECOM_FIELD, next);
|
|
5951
|
+
}
|
|
5952
|
+
}
|
|
5953
|
+
),
|
|
5954
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5955
|
+
ToggleRow,
|
|
5956
|
+
{
|
|
5957
|
+
label: "\u9700\u8981\u4F60\u56DE\u5E94\u65F6\u901A\u77E5",
|
|
5958
|
+
desc: "\u7B49\u5BA1\u6279\u3001\u7B49\u4F60\u56DE\u7B54\u95EE\u9898\u65F6\u63A8\u4E00\u6761\u3002",
|
|
5959
|
+
checked: kinds["needs-input"],
|
|
5960
|
+
onChange: (next) => {
|
|
5961
|
+
setField(NOTIFY_KINDS_FIELD, { ...kinds, "needs-input": next });
|
|
5962
|
+
}
|
|
5963
|
+
}
|
|
5964
|
+
),
|
|
5965
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5966
|
+
ToggleRow,
|
|
5967
|
+
{
|
|
5968
|
+
label: "\u4EFB\u52A1\u5B8C\u6210\u65F6\u901A\u77E5",
|
|
5969
|
+
desc: "\u4E00\u8F6E\u8DD1\u5B8C\uFF08\u8FD0\u884C\u4E2D\u2192\u7A7A\u95F2\uFF09\u63A8\u4E00\u6761\u3002",
|
|
5970
|
+
checked: kinds.done,
|
|
5971
|
+
onChange: (next) => {
|
|
5972
|
+
setField(NOTIFY_KINDS_FIELD, { ...kinds, done: next });
|
|
5973
|
+
}
|
|
5974
|
+
}
|
|
5975
|
+
),
|
|
5976
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5977
|
+
ToggleRow,
|
|
5978
|
+
{
|
|
5979
|
+
label: "\u4EFB\u52A1\u51FA\u9519\u65F6\u901A\u77E5",
|
|
5980
|
+
desc: "\u67D0\u6B65\u6216\u67D0\u8F6E\u62A5\u9519\u65F6\u63A8\u4E00\u6761\u3002",
|
|
5981
|
+
checked: kinds.error,
|
|
5982
|
+
onChange: (next) => {
|
|
5983
|
+
setField(NOTIFY_KINDS_FIELD, { ...kinds, error: next });
|
|
5984
|
+
}
|
|
5985
|
+
}
|
|
5986
|
+
),
|
|
5987
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
5988
|
+
ToggleRow,
|
|
5989
|
+
{
|
|
5990
|
+
label: "\u6D4B\u8BD5\u63A8\u9001",
|
|
5991
|
+
desc: note2 === "" ? "\u70B9\u53F3\u8FB9\u6309\u94AE\uFF0C\u7ACB\u523B\u53D1\u4E00\u6761\u5230\u4F60\u5FAE\u4FE1\u9A8C\u8BC1\u914D\u7F6E\u3002" : note2,
|
|
5992
|
+
checked: false,
|
|
5993
|
+
onChange: () => {
|
|
5994
|
+
},
|
|
5995
|
+
action: { label: busy ? "\u53D1\u9001\u4E2D\u2026" : "\u53D1\u9001\u6D4B\u8BD5", onClick: send }
|
|
5996
|
+
}
|
|
5997
|
+
)
|
|
5998
|
+
]
|
|
5999
|
+
}
|
|
6000
|
+
);
|
|
6001
|
+
}
|
|
5835
6002
|
function RestartButton({ restart }) {
|
|
5836
6003
|
const busy = restart.stage === "restarting" || restart.stage === "asking";
|
|
5837
6004
|
const blocked = restart.blocked;
|
|
@@ -5882,7 +6049,7 @@ function RestartBanner({ restart }) {
|
|
|
5882
6049
|
}, children: "\u77E5\u9053\u4E86" }) })
|
|
5883
6050
|
] });
|
|
5884
6051
|
}
|
|
5885
|
-
function SettingsSection({ useLive, useBook, useBookStatus, useWriteNotice, actions }) {
|
|
6052
|
+
function SettingsSection({ useLive, useBook, useBookStatus, useWriteNotice, actions, setField }) {
|
|
5886
6053
|
const settings = useLive((item) => item);
|
|
5887
6054
|
const book = useBook((item) => item);
|
|
5888
6055
|
const bookStatus = useBookStatus((item) => item);
|
|
@@ -5943,9 +6110,24 @@ function SettingsSection({ useLive, useBook, useBookStatus, useWriteNotice, acti
|
|
|
5943
6110
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: "\u2197" })
|
|
5944
6111
|
]
|
|
5945
6112
|
}
|
|
6113
|
+
),
|
|
6114
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
6115
|
+
"a",
|
|
6116
|
+
{
|
|
6117
|
+
className: "dsh-ux-cardLink",
|
|
6118
|
+
href: SITE_URL,
|
|
6119
|
+
target: "_blank",
|
|
6120
|
+
rel: "noreferrer noopener",
|
|
6121
|
+
title: "\u6253\u5F00 DSH \u5B98\u7F51\uFF08\u65B0\u6807\u7B7E\uFF09",
|
|
6122
|
+
children: [
|
|
6123
|
+
"\u5B98\u7F51 ",
|
|
6124
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: "\u2197" })
|
|
6125
|
+
]
|
|
6126
|
+
}
|
|
5946
6127
|
)
|
|
5947
6128
|
] })
|
|
5948
6129
|
] }),
|
|
6130
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(NotifyCard, { settings, setField }),
|
|
5949
6131
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RestartBanner, { restart }),
|
|
5950
6132
|
writeNotice !== "" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "dsh-ux-restartBanner dsh-ux-restartBannerFailed", role: "status", children: [
|
|
5951
6133
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "dsh-ux-restartBannerText", children: [
|