@shgroup/dsh-serenity-hooks 1.25.1 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-serenity-hooks",
3
- "version": "1.25.1",
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/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.0 实验性)— 走 DSH agent-loop 会话核心,轨迹与 WebUI 同源</div>
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
- * @param root 当前 CCC 根(角色配置读取 + skiff agent cwd)
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, roles, webPort, req, res);
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}(角色: ${roles.size},WebUI: ${webPort})`);
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, roles, webPort, req, res) {
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(roles, webPort));
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 = roles.get(roleName);
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
- /** 解析当前 CCC 根:进程 cwd 上溯 .serenity 优先,live 会话 cwd 兜底 */
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 fromCwd = findSerenityRoot(process.cwd());
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) return r;
9631
+ if (r && !liveRoots.includes(r)) liveRoots.push(r);
9620
9632
  }
9621
9633
  }
9622
9634
  } catch {}
9623
- return null;
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.1",
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": {