@shgroup/dsh-serenity-hooks 1.25.0 → 1.25.2
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/dsh.plugin.json +1 -1
- package/lib/client.js +32 -1
- package/lib/index.js +30 -15
- package/package.json +1 -1
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-serenity-hooks",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.2",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"description": "宁静号 ACC harness(Native Cordis 插件):真实 DSH 工具 cc_fs/session/acc_msm/eap/neat/cce/handyman/session_rebuild/skiff_admin + 拦截缝机械约束(safe-mode/路径守卫)+ 高级设定面板(双端口网关/账号管理)+ Skiff 认知子集角色(实验性)。适配 DSH 公开版(0.1.0-rc,deepseek-ai/deepseek-harness)。",
|
|
6
6
|
"engines": {
|
package/lib/client.js
CHANGED
|
@@ -3819,7 +3819,7 @@ Instruction-following style:
|
|
|
3819
3819
|
}
|
|
3820
3820
|
//#endregion
|
|
3821
3821
|
//#region \0sp-css:/home/yh/home/home-serenity/AI_LAB/dsh-serenity-plugin/hooks/dsh-serenity-hooks/src/client/SettingsSection
|
|
3822
|
-
const css = "/* SettingsSection — dsh 原生设置面板 serenity-hooks 简单配置页\n v1.21.1 看齐 dsh 自身:官方 settings 设计语言——\n section > title + intro + group(groupTitle) + rowCard 行卡;\n 全部 --dsw-alias-* token(与 ui-settings-models 同词汇表)。 */\n\n/* 页面容器(官方 .section:flex column gap 12) */\n.ss-section {\n display: flex;\n flex-direction: column;\n gap: 14px;\n max-width: 720px;\n color: var(--dsw-alias-label-primary);\n}\n\n/* 页面标题(官方 .title:16px/24 500) */\n.ss-title {\n margin: 0;\n font-size: 16px;\n line-height: 24px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n/* 页面说明(官方 .intro:14px/22 tertiary) */\n.ss-intro {\n margin: 0;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n/* 分组(多级标题:分组标题 + 行卡列表) */\n.ss-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* 分组标题(二级:12px/18 500 secondary——官方 fieldLabel 风格) */\n.ss-groupTitle {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* 行卡列表(官方 .rows:无 marker,gap 8) */\n.ss-rows {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* 行卡(官方 .rowCard:border-l2 r12 padding 12/14) */\n.ss-rowCard {\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n padding: 12px 14px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n/* 行卡文本(标题 + 说明 左列) */\n.ss-rowText {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n flex: 1;\n}\n\n/* 行卡标题(官方 .rowName:14px/22 500) */\n.ss-rowName {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n/* 行卡说明(12px/18 tertiary) */\n.ss-rowDesc {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n/* 行卡控件(右置) */\n.ss-rowControl {\n flex: none;\n display: flex;\n align-items: center;\n}\n\n/* 开关(官方 token 的自绘 toggle:track 22px,thumb 16px) */\n.ss-switch {\n position: relative;\n flex: none;\n width: 40px;\n height: 22px;\n cursor: pointer;\n}\n\n.ss-switch input {\n position: absolute;\n opacity: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n cursor: pointer;\n}\n\n.ss-switchTrack {\n position: absolute;\n inset: 0;\n border-radius: 11px;\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.3));\n transition: background var(--ds-transition-duration-fast, 0.15s) var(--ds-ease-in-out, ease);\n}\n\n.ss-switchTrack::after {\n content: '';\n position: absolute;\n top: 3px;\n left: 3px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--dsw-alias-label-primary, #eee);\n transition: transform var(--ds-transition-duration-fast, 0.15s) var(--ds-ease-in-out, ease);\n}\n\n.ss-switch input:checked + .ss-switchTrack {\n background: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n.ss-switch input:checked + .ss-switchTrack::after {\n transform: translateX(18px);\n}\n\n.ss-switch input:disabled + .ss-switchTrack {\n opacity: 0.4;\n cursor: default;\n}\n\n/* 阈值行(滑块 + 值) */\n.ss-threshold {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.ss-threshold input[type='range'] {\n width: 160px;\n}\n\n.ss-value {\n min-width: 40px;\n font-variant-numeric: tabular-nums;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n text-align: right;\n}\n\n/* 底部帮助行 */\n.ss-hint {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n/* 降级提示 */\n.ss-degrade {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-warn-label);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n";
|
|
3822
|
+
const css = "/* SettingsSection — dsh 原生设置面板 serenity-hooks 简单配置页\n v1.21.1 看齐 dsh 自身:官方 settings 设计语言——\n section > title + intro + group(groupTitle) + rowCard 行卡;\n 全部 --dsw-alias-* token(与 ui-settings-models 同词汇表)。 */\n\n/* 页面容器(官方 .section:flex column gap 12) */\n.ss-section {\n display: flex;\n flex-direction: column;\n gap: 14px;\n max-width: 720px;\n color: var(--dsw-alias-label-primary);\n}\n\n/* 页面标题(官方 .title:16px/24 500) */\n.ss-title {\n margin: 0;\n font-size: 16px;\n line-height: 24px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n/* 页面说明(官方 .intro:14px/22 tertiary) */\n.ss-intro {\n margin: 0;\n font-size: 14px;\n line-height: 22px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n/* 分组(多级标题:分组标题 + 行卡列表) */\n.ss-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* 分组标题(二级:12px/18 500 secondary——官方 fieldLabel 风格) */\n.ss-groupTitle {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n color: var(--dsw-alias-label-secondary);\n}\n\n/* 行卡列表(官方 .rows:无 marker,gap 8) */\n.ss-rows {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* 行卡(官方 .rowCard:border-l2 r12 padding 12/14) */\n.ss-rowCard {\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n padding: 12px 14px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n/* 行卡文本(标题 + 说明 左列) */\n.ss-rowText {\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n flex: 1;\n}\n\n/* 行卡标题(官方 .rowName:14px/22 500) */\n.ss-rowName {\n font-size: 14px;\n line-height: 22px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n/* 行卡说明(12px/18 tertiary) */\n.ss-rowDesc {\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n/* 行卡控件(右置) */\n.ss-rowControl {\n flex: none;\n display: flex;\n align-items: center;\n}\n\n/* 开关(官方 token 的自绘 toggle:track 22px,thumb 16px) */\n.ss-switch {\n position: relative;\n flex: none;\n width: 40px;\n height: 22px;\n cursor: pointer;\n}\n\n.ss-switch input {\n position: absolute;\n opacity: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n cursor: pointer;\n}\n\n.ss-switchTrack {\n position: absolute;\n inset: 0;\n border-radius: 11px;\n background: var(--dsw-alias-interactive-bg-active, rgba(128, 128, 128, 0.3));\n transition: background var(--ds-transition-duration-fast, 0.15s) var(--ds-ease-in-out, ease);\n}\n\n.ss-switchTrack::after {\n content: '';\n position: absolute;\n top: 3px;\n left: 3px;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--dsw-alias-label-primary, #eee);\n transition: transform var(--ds-transition-duration-fast, 0.15s) var(--ds-ease-in-out, ease);\n}\n\n.ss-switch input:checked + .ss-switchTrack {\n background: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n.ss-switch input:checked + .ss-switchTrack::after {\n transform: translateX(18px);\n}\n\n.ss-switch input:disabled + .ss-switchTrack {\n opacity: 0.4;\n cursor: default;\n}\n\n/* 阈值行(滑块 + 值) */\n.ss-threshold {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.ss-threshold input[type='range'] {\n width: 160px;\n}\n\n/* Skiff 调试端口输入(number;关闭时跟随 disabled 半透明) */\n.ss-portInput {\n width: 96px;\n padding: 6px 8px;\n border-radius: 8px;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-fill-l1, rgba(128, 128, 128, 0.08));\n color: var(--dsw-alias-label-primary);\n font-size: 13px;\n font-variant-numeric: tabular-nums;\n text-align: right;\n}\n\n.ss-portInput:disabled {\n opacity: 0.4;\n cursor: default;\n}\n\n.ss-value {\n min-width: 40px;\n font-variant-numeric: tabular-nums;\n font-size: 13px;\n font-weight: 600;\n color: var(--dsw-alias-label-primary);\n text-align: right;\n}\n\n/* 底部帮助行 */\n.ss-hint {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n/* 降级提示 */\n.ss-degrade {\n margin: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-warn-label);\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n";
|
|
3823
3823
|
if (typeof document !== "undefined" && document.querySelector("style[data-sp-css=\"SettingsSection\"]") === null) {
|
|
3824
3824
|
const tag = document.createElement("style");
|
|
3825
3825
|
tag.setAttribute("data-sp-css", "SettingsSection");
|
|
@@ -3892,6 +3892,9 @@ Instruction-following style:
|
|
|
3892
3892
|
const setThreshold = (v) => {
|
|
3893
3893
|
scope.set("rebuildThreshold", Math.min(1, Math.max(.01, v)));
|
|
3894
3894
|
};
|
|
3895
|
+
const setSkiffPort = (v) => {
|
|
3896
|
+
scope.set("skiffDebugPort", Math.min(65535, Math.max(1024, Math.round(v))));
|
|
3897
|
+
};
|
|
3895
3898
|
if (!ready) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3896
3899
|
className: "ss-section",
|
|
3897
3900
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -3903,6 +3906,8 @@ Instruction-following style:
|
|
|
3903
3906
|
const rebuildOn = value?.rebuildEnabled ?? true;
|
|
3904
3907
|
const threshold = value?.rebuildThreshold ?? .9;
|
|
3905
3908
|
const namingOn = value?.namingEnabled ?? true;
|
|
3909
|
+
const skiffOn = value?.skiffEnabled ?? false;
|
|
3910
|
+
const skiffPort = value?.skiffDebugPort ?? 3099;
|
|
3906
3911
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3907
3912
|
className: "ss-section",
|
|
3908
3913
|
children: [
|
|
@@ -3965,6 +3970,32 @@ Instruction-following style:
|
|
|
3965
3970
|
})
|
|
3966
3971
|
}) })
|
|
3967
3972
|
}),
|
|
3973
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Group, {
|
|
3974
|
+
title: "Skiff",
|
|
3975
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
|
|
3976
|
+
title: "认知子集调试服务",
|
|
3977
|
+
desc: "Skiff 角色问答页(实验性;启停人工控制,仅监听 127.0.0.1)",
|
|
3978
|
+
control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Toggle, {
|
|
3979
|
+
checked: skiffOn,
|
|
3980
|
+
onChange: (on) => toggle("skiffEnabled", on)
|
|
3981
|
+
})
|
|
3982
|
+
}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
|
|
3983
|
+
title: "调试端口",
|
|
3984
|
+
desc: "Skiff 问答页端口(1024 ~ 65535,默认 3099)",
|
|
3985
|
+
control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3986
|
+
className: "ss-threshold",
|
|
3987
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
3988
|
+
className: "ss-portInput",
|
|
3989
|
+
type: "number",
|
|
3990
|
+
min: 1024,
|
|
3991
|
+
max: 65535,
|
|
3992
|
+
value: skiffPort,
|
|
3993
|
+
disabled: !skiffOn,
|
|
3994
|
+
onChange: (e) => setSkiffPort(Number(e.target.value))
|
|
3995
|
+
})
|
|
3996
|
+
})
|
|
3997
|
+
}) })]
|
|
3998
|
+
}),
|
|
3968
3999
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3969
4000
|
className: "ss-group",
|
|
3970
4001
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
package/lib/index.js
CHANGED
|
@@ -9333,8 +9333,8 @@ function sendHtml(res, html) {
|
|
|
9333
9333
|
});
|
|
9334
9334
|
res.end(html);
|
|
9335
9335
|
}
|
|
9336
|
-
/** 问答页 HTML:角色下拉 + 输入 + 答案区 + 轨迹区(JS 渲染)+ WebUI 链接 */
|
|
9337
|
-
function skiffDebugPage(roles, webPort) {
|
|
9336
|
+
/** 问答页 HTML:角色下拉 + 输入 + 答案区 + 轨迹区(JS 渲染)+ 绑定的 CCC + WebUI 链接 */
|
|
9337
|
+
function skiffDebugPage(roles, cccRoot, webPort) {
|
|
9338
9338
|
const roleOptions = [...roles.entries()].map(([name, r]) => `<option value="${escapeHtml(name)}">${escapeHtml(name)}${r.model ? ` (${escapeHtml(r.model)})` : ""}</option>`).join("\n");
|
|
9339
9339
|
const webUrl = `http://127.0.0.1:${webPort}`;
|
|
9340
9340
|
return `<!DOCTYPE html>
|
|
@@ -9350,6 +9350,8 @@ function skiffDebugPage(roles, webPort) {
|
|
|
9350
9350
|
main { max-width: 720px; margin: 0 auto; }
|
|
9351
9351
|
h1 { font-size: 18px; margin: 0 0 4px; }
|
|
9352
9352
|
.sub { opacity: .65; font-size: 13px; margin-bottom: 16px; }
|
|
9353
|
+
.ccc { display: inline-block; padding: 3px 10px; border-radius: 999px; background: rgba(11,168,117,.12); color: #0ba875; font-size: 12px; font-weight: 600; margin-bottom: 12px; word-break: break-all; }
|
|
9354
|
+
@media (prefers-color-scheme: dark) { .ccc { color: #3ddc9a; } }
|
|
9353
9355
|
label { font-size: 13px; font-weight: 600; display: block; margin: 12px 0 4px; }
|
|
9354
9356
|
select, textarea { width: 100%; box-sizing: border-box; padding: 8px 10px; border-radius: 8px; border: 1px solid #d0d7de; background: #fff; color: inherit; font-size: 14px; }
|
|
9355
9357
|
@media (prefers-color-scheme: dark) { select, textarea { background: #26282c; border-color: #3a3d42; } }
|
|
@@ -9371,7 +9373,8 @@ function skiffDebugPage(roles, webPort) {
|
|
|
9371
9373
|
<body>
|
|
9372
9374
|
<main>
|
|
9373
9375
|
<h1>Skiff Debug</h1>
|
|
9374
|
-
<div class="sub">宁静号 trajectory 子集角色问答页(v1.25.
|
|
9376
|
+
<div class="sub">宁静号 trajectory 子集角色问答页(v1.25.2 实验性)— 走 DSH agent-loop 会话核心,轨迹与 WebUI 同源</div>
|
|
9377
|
+
<div class="ccc">CCC: ${escapeHtml(cccRoot)}</div>
|
|
9375
9378
|
<label for="role">角色</label>
|
|
9376
9379
|
<select id="role">${roleOptions || "<option value=\"\">(未配置角色)</option>"}</select>
|
|
9377
9380
|
<label for="q">问题</label>
|
|
@@ -9431,15 +9434,20 @@ function escapeHtml(s) {
|
|
|
9431
9434
|
}
|
|
9432
9435
|
/**
|
|
9433
9436
|
* 启动调试问答服务(单实例;重复启动幂等返回既有实例)。
|
|
9434
|
-
*
|
|
9437
|
+
*
|
|
9438
|
+
* **CCC 绑定(v1.25.2 用户指出)**:服务绑定一个 CCC root(调用方 resolveSkiffRoot
|
|
9439
|
+
* 解析:live 会话中**含 skiff.roles 的 CCC 优先**);角色配置**每次请求实时读取**
|
|
9440
|
+
* (不缓存快照)——改 .opencode/serenity.json 后刷新页面即生效,无需重启服务。
|
|
9441
|
+
* 页面顶部显示绑定的 CCC root,绑定可核对。
|
|
9442
|
+
*
|
|
9443
|
+
* @param root 绑定的 CCC 根(角色配置读取 + skiff agent cwd)
|
|
9435
9444
|
* @param port 调试端口(仅 127.0.0.1)
|
|
9436
9445
|
* @param webPort 主 WebUI 端口(WebUI 链接)
|
|
9437
9446
|
*/
|
|
9438
9447
|
async function startSkiffDebugServer(ctx, root, port, webPort) {
|
|
9439
9448
|
if (active) return;
|
|
9440
|
-
const roles = readSkiffRoles(root);
|
|
9441
9449
|
const server = createServer((req, res) => {
|
|
9442
|
-
handle(ctx, root,
|
|
9450
|
+
handle(ctx, root, webPort, req, res);
|
|
9443
9451
|
});
|
|
9444
9452
|
await new Promise((resolve, reject) => {
|
|
9445
9453
|
server.once("error", reject);
|
|
@@ -9449,7 +9457,7 @@ async function startSkiffDebugServer(ctx, root, port, webPort) {
|
|
|
9449
9457
|
server,
|
|
9450
9458
|
port
|
|
9451
9459
|
};
|
|
9452
|
-
console.log(`[serenity-hooks] ✓ Skiff 调试问答页: http://127.0.0.1:${port}
|
|
9460
|
+
console.log(`[serenity-hooks] ✓ Skiff 调试问答页: http://127.0.0.1:${port}(CCC: ${root},WebUI: ${webPort})`);
|
|
9453
9461
|
}
|
|
9454
9462
|
function stopSkiffDebugServer() {
|
|
9455
9463
|
if (!active) return;
|
|
@@ -9458,11 +9466,11 @@ function stopSkiffDebugServer() {
|
|
|
9458
9466
|
} catch {}
|
|
9459
9467
|
active = null;
|
|
9460
9468
|
}
|
|
9461
|
-
async function handle(ctx, root,
|
|
9469
|
+
async function handle(ctx, root, webPort, req, res) {
|
|
9462
9470
|
try {
|
|
9463
9471
|
const url = (req.url ?? "/").split("?")[0] ?? "/";
|
|
9464
9472
|
if (req.method === "GET" && url === "/") {
|
|
9465
|
-
sendHtml(res, skiffDebugPage(
|
|
9473
|
+
sendHtml(res, skiffDebugPage(readSkiffRoles(root), root, webPort));
|
|
9466
9474
|
return;
|
|
9467
9475
|
}
|
|
9468
9476
|
if (req.method === "POST" && url === "/ask") {
|
|
@@ -9477,7 +9485,7 @@ async function handle(ctx, root, roles, webPort, req, res) {
|
|
|
9477
9485
|
}
|
|
9478
9486
|
const roleName = typeof body.role === "string" ? body.role : "";
|
|
9479
9487
|
const question = typeof body.question === "string" ? body.question : "";
|
|
9480
|
-
const role =
|
|
9488
|
+
const role = readSkiffRoles(root).get(roleName);
|
|
9481
9489
|
if (!roleName || !role) {
|
|
9482
9490
|
sendJson(res, 400, { error: `unknown role: ${roleName}` });
|
|
9483
9491
|
return;
|
|
@@ -9606,21 +9614,28 @@ function registerSkiff(ctx) {
|
|
|
9606
9614
|
} catch {}
|
|
9607
9615
|
sync();
|
|
9608
9616
|
}
|
|
9609
|
-
/**
|
|
9617
|
+
/**
|
|
9618
|
+
* 解析 Skiff 调试服务绑定的 CCC 根(v1.25.2 用户指出:skiff 必须绑定 CCC):
|
|
9619
|
+
* ① live 会话中**配置了 skiff.roles 的 CCC 优先**(用户认知中的绑定目标)
|
|
9620
|
+
* ② 回退进程 cwd 上溯 .serenity
|
|
9621
|
+
* ③ 再回退任一 live 会话的 CCC
|
|
9622
|
+
*/
|
|
9610
9623
|
function resolveSkiffRoot(ctx) {
|
|
9611
|
-
const
|
|
9612
|
-
if (fromCwd) return fromCwd;
|
|
9624
|
+
const liveRoots = [];
|
|
9613
9625
|
try {
|
|
9614
9626
|
const sessions = ctx.sessions;
|
|
9615
9627
|
for (const s of sessions?.list?.() ?? []) {
|
|
9616
9628
|
const cwd = s?.header?.cwd;
|
|
9617
9629
|
if (typeof cwd === "string") {
|
|
9618
9630
|
const r = findSerenityRoot(cwd);
|
|
9619
|
-
if (r
|
|
9631
|
+
if (r && !liveRoots.includes(r)) liveRoots.push(r);
|
|
9620
9632
|
}
|
|
9621
9633
|
}
|
|
9622
9634
|
} catch {}
|
|
9623
|
-
return
|
|
9635
|
+
for (const r of liveRoots) if (readSkiffRoles(r).size > 0) return r;
|
|
9636
|
+
const fromCwd = findSerenityRoot(process.cwd());
|
|
9637
|
+
if (fromCwd) return fromCwd;
|
|
9638
|
+
return liveRoots[0] ?? null;
|
|
9624
9639
|
}
|
|
9625
9640
|
/** 主 WebUI 端口(WebUI 链接;webServer 未装配回退 3080) */
|
|
9626
9641
|
function readWebPort(ctx) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.2",
|
|
4
4
|
"description": "宁静号 ACC harness — Native Cordis 插件(DeepSeek Harness 运行时)。真实 DSH 工具注册(cc_fs/session/acc_msm 等 9 工具)+ 拦截缝机械约束(safe-mode/路径守卫/会话落盘)+ 系统提示词注入(ACC/CCE/Constraints/SKILL/Session 五块)。适配 DSH 公开版(deepseek-ai/deepseek-harness 0.1.0-rc)。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|