@shgroup/dsh-serenity-hooks 1.34.2 → 1.36.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/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-serenity-hooks",
3
- "version": "1.34.2",
3
+ "version": "1.36.0",
4
4
  "main": "lib/index.js",
5
5
  "description": "宁静号 ACC harness(Native Cordis 插件):给 DSH 装一个「AI 工作区」——11 个工具(container_fs/container_trajectory/dashboard/container_git/msm/praxis/handyman/localstore/container_admin/im-bridge/acc-diag;后两个按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 轨迹日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/trajectory 唤醒注册表。适配 DSH 0.1.5-rc.2(deepseek-ai/deepseek-harness)。",
6
6
  "engines": {
package/lib/client.js CHANGED
@@ -8,7 +8,7 @@ window.__ModuleLoader__.load({
8
8
  let react = require("react");
9
9
  let react_jsx_runtime = require("react/jsx-runtime");
10
10
  //#region \0sp-css:/home/yh/home/home-serenity/AI_LAB/dsh-serenity-plugin/hooks/dsh-serenity-hooks/src/client/SafeModePanel
11
- const css$3 = "/* SafeModePanel — 会话头部 Serenity 状态胶囊(v1.24.10 胶囊改版,对齐 OcgoDockEntry pill)\n * 胶囊 999px 全圆 → 点击 → 自绘 popover(340px 右上角卡片,外点/Escape 关闭)\n * popover 内:分组(groupTitle 标题 + rowCard 行卡)——看齐官方 settings 设计语言\n * 遵循 web-styling.md:颜色只用 --dsw-alias-* 语义 token(明暗自适应)+ --sp-safe-green 统一绿家族;\n * 前缀 sp- 防冲突。 */\n\n/* ── 统一绿色变量家族(一处改全改;emerald 500~600 区间保证深色对比度) ── */\n\n.sp-root {\n --sp-safe-green: #0ba875; /* emerald-550:SAFE ON 主色 */\n --sp-safe-green-deep: #059669; /* emerald-600:渐变深端 */\n}\n\n/* ── 头部状态胶囊(可点击) ── */\n\n.sp-card {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 9px; /* 无固定 height:由内容撑高(胶囊) */\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-2);\n color: inherit;\n font-size: 12px;\n line-height: 1;\n cursor: pointer;\n transition: background var(--ds-transition-duration-fast, 0.1s) var(--ds-ease-in-out, ease),\n border-color var(--ds-transition-duration-fast, 0.1s) var(--ds-ease-in-out, ease);\n}\n\n.sp-card:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n border-color: var(--dsw-alias-border-l2);\n}\n\n.sp-card:focus-visible {\n outline: 2px solid var(--dsw-alias-button-ghost-active-border);\n outline-offset: 1px;\n}\n\n.sp-card:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n/* 绿点 = Serenity 在线(恒亮绿,不随 SAFE 变);离线/未激活 → 灰 */\n.sp-dot {\n flex: none;\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--dsw-alias-state-success-primary);\n}\n\n.sp-dotOff {\n background: var(--dsw-alias-label-dimmed);\n}\n\n.sp-cardInactive {\n opacity: 0.85;\n}\n\n.sp-cardInactive .sp-brand {\n color: var(--dsw-alias-label-secondary);\n font-weight: 500;\n}\n\n.sp-brand {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n/* 版本号:monospace + translateY(1px) 下沉对齐(与文字基线齐平) */\n.sp-ver {\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n font-family: var(--ds-font-family-code, monospace);\n transform: translateY(1px);\n}\n\n/* 1px 深灰分隔线(两侧紧凑) */\n.sp-sep {\n flex: none;\n width: 1px;\n height: 12px;\n margin: 0 2px;\n background: var(--dsw-alias-label-tertiary);\n}\n\n.sp-shield {\n display: inline-flex;\n width: 14px;\n height: 14px;\n flex: none;\n}\n\n.sp-shield svg {\n width: 14px;\n height: 14px;\n}\n\n.sp-statusWord {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0;\n white-space: nowrap;\n}\n\n/* SAFE OFF(未保护):灰——低姿态提醒,非错误(用户自己的开关选择) */\n.sp-cardUnprotected .sp-shield {\n color: var(--dsw-alias-label-secondary);\n}\n\n.sp-cardUnprotected .sp-statusWord {\n color: var(--dsw-alias-label-secondary);\n}\n\n/* SAFE ON(保护中):emerald 绿——安心(盾牌实色 + SAFE 文字渐变质感) */\n.sp-cardProtected .sp-shield {\n color: var(--sp-safe-green);\n}\n\n.sp-cardProtected .sp-statusWord {\n color: var(--sp-safe-green);\n background: linear-gradient(135deg, var(--sp-safe-green) 0%, var(--sp-safe-green-deep) 100%);\n -webkit-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n}\n\n/* ── Mac 风格滑块(v1.24.10:轨道 24×13 / thumb 11px 灰白 #f2f4f6 无图标 / cubic-bezier 平滑) ── */\n\n.sp-switch {\n display: inline-block;\n width: 24px;\n height: 13px;\n border-radius: 999px;\n position: relative;\n flex: none;\n cursor: pointer;\n transition: background 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sp-switchOff {\n background: var(--dsw-alias-border-l2);\n}\n\n.sp-switchOn {\n background: var(--sp-safe-green);\n}\n\n.sp-switchThumb {\n position: absolute;\n top: 1px;\n width: 11px;\n height: 11px;\n border-radius: 50%;\n background: #f2f4f6; /* Mac 灰白 thumb(明暗通用) */\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\n transition: left 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sp-switchOff .sp-switchThumb {\n left: 1px;\n}\n\n.sp-switchOn .sp-switchThumb {\n left: 12px; /* 24 - 11 - 1 */\n}\n\n/* CSS 特异性坑(S013 指南):.sp-switch:hover (0,2,0) 会覆盖 .sp-switchOn (0,1,0)\n * → ON 态 hover 绿底消失。必须同特异性且后定义补回。 */\n.sp-switch:hover {\n filter: brightness(1.08);\n}\n\n.sp-switchOn:hover {\n background: var(--sp-safe-green);\n}\n\n.sp-switchBusy {\n opacity: 0.6;\n cursor: default;\n pointer-events: none;\n}\n\n.sp-chev {\n color: var(--dsw-alias-label-dimmed);\n flex: none;\n}\n\n/* ── 自绘 popover(340px 右上角小卡片,替代官方 Modal) ── */\n\n.sp-root {\n position: relative;\n display: inline-flex;\n}\n\n.sp-pop {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n width: 340px;\n max-width: calc(100vw - 24px);\n z-index: 2000;\n box-sizing: border-box;\n padding: 14px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 14px;\n background: var(--dsw-alias-bg-overlay);\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);\n}\n\n.sp-popBody {\n display: flex;\n flex-direction: column;\n gap: 14px;\n max-height: calc(100vh - 140px);\n overflow-y: auto;\n}\n\n/* ── 分组(官方 settings 语言:groupTitle + rows) ── */\n\n.sp-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sp-groupHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.sp-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.sp-rows {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n/* 行卡(rowCard:border + radius + padding;值与 label 分离、长内容可换行) */\n.sp-row {\n display: flex;\n align-items: baseline;\n gap: 12px;\n min-width: 0;\n padding: 8px 12px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.sp-label {\n flex: none;\n width: 76px;\n font-size: 12px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n white-space: nowrap;\n}\n\n.sp-value {\n flex: 1;\n min-width: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-primary);\n font-family: var(--ds-font-family-code, monospace);\n word-break: break-all;\n overflow-wrap: anywhere;\n}\n\n/* 安全模式动作区 */\n.sp-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 8px 12px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.sp-toggle {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 24px;\n padding: 0 10px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 6px;\n font-size: 12px;\n cursor: pointer;\n transition: background var(--ds-transition-duration-fast, 0.1s) var(--ds-ease-in-out, ease);\n}\n\n.sp-toggleLg {\n height: 30px;\n padding: 0 16px;\n font-size: 13px;\n}\n\n.sp-toggleOn {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 14%, transparent);\n color: var(--dsw-alias-state-error-primary);\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary) 45%, transparent);\n}\n\n.sp-toggleOff {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n\n.sp-toggleIcon {\n flex: none;\n}\n\n.sp-toggleDesc {\n flex: 1;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n/* handyman 运行状态区块 */\n\n.sp-handymenToggle {\n flex: none;\n padding: 2px 10px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n cursor: pointer;\n}\n\n.sp-handymenToggle:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.sp-handymenList {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-top: 2px;\n}\n\n.sp-handymanItem {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 8px 12px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n min-width: 0;\n}\n\n.sp-handymanHead {\n display: flex;\n align-items: baseline;\n gap: 8px;\n min-width: 0;\n}\n\n.sp-handymanLabel {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n.sp-handymanRound {\n flex: none;\n font-size: 11px;\n color: var(--dsw-alias-label-dimmed);\n}\n\n.sp-handymanTime {\n flex: none;\n font-size: 11px;\n color: var(--dsw-alias-label-dimmed);\n}\n\n.sp-handymanResp {\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-label-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.sp-handymenMore {\n font-size: 11px;\n color: var(--dsw-alias-label-dimmed);\n padding: 4px 12px;\n}\n\n/* 底部提示(配置入口引导) */\n.sp-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 padding: 8px 12px;\n border: 1px dashed var(--dsw-alias-border-l2);\n border-radius: 10px;\n}\n";
11
+ const css$3 = "/* SafeModePanel — 会话头部 Serenity 状态胶囊(v1.24.10 胶囊改版,对齐 OcgoDockEntry pill)\n * 胶囊 999px 全圆 → 点击 → 自绘 popover(340px 右上角卡片,外点/Escape 关闭)\n * popover 内:分组(groupTitle 标题 + rowCard 行卡)——看齐官方 settings 设计语言\n * 遵循 web-styling.md:颜色只用 --dsw-alias-* 语义 token(明暗自适应)+ --sp-safe-green 统一绿家族;\n * 前缀 sp- 防冲突。 */\n\n/* ── 统一绿色变量家族(一处改全改;emerald 500~600 区间保证深色对比度) ── */\n\n.sp-root {\n --sp-safe-green: #0ba875; /* emerald-550:SAFE ON 主色 */\n --sp-safe-green-deep: #059669; /* emerald-600:渐变深端 */\n}\n\n/* ── 头部状态胶囊(可点击) ── */\n\n.sp-card {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 9px; /* 无固定 height:由内容撑高(胶囊) */\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 999px;\n background: var(--dsw-alias-bg-layer-2);\n color: inherit;\n font-size: 12px;\n line-height: 1;\n cursor: pointer;\n transition: background var(--ds-transition-duration-fast, 0.1s) var(--ds-ease-in-out, ease),\n border-color var(--ds-transition-duration-fast, 0.1s) var(--ds-ease-in-out, ease);\n}\n\n.sp-card:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n border-color: var(--dsw-alias-border-l2);\n}\n\n.sp-card:focus-visible {\n outline: 2px solid var(--dsw-alias-button-ghost-active-border);\n outline-offset: 1px;\n}\n\n.sp-card:disabled {\n opacity: 0.6;\n cursor: default;\n}\n\n/* 绿点 = Serenity 在线(恒亮绿,不随 SAFE 变);离线/未激活 → 灰 */\n.sp-dot {\n flex: none;\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--dsw-alias-state-success-primary);\n}\n\n.sp-dotOff {\n background: var(--dsw-alias-label-dimmed);\n}\n\n.sp-cardInactive {\n opacity: 0.85;\n}\n\n.sp-cardInactive .sp-brand {\n color: var(--dsw-alias-label-secondary);\n font-weight: 500;\n}\n\n.sp-brand {\n color: var(--dsw-alias-label-primary);\n font-weight: 500;\n}\n\n/* 版本号:monospace + translateY(1px) 下沉对齐(与文字基线齐平) */\n.sp-ver {\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n font-family: var(--ds-font-family-code, monospace);\n transform: translateY(1px);\n}\n\n/* 1px 深灰分隔线(两侧紧凑) */\n.sp-sep {\n flex: none;\n width: 1px;\n height: 12px;\n margin: 0 2px;\n background: var(--dsw-alias-label-tertiary);\n}\n\n.sp-shield {\n display: inline-flex;\n width: 14px;\n height: 14px;\n flex: none;\n}\n\n.sp-shield svg {\n width: 14px;\n height: 14px;\n}\n\n.sp-statusWord {\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0;\n white-space: nowrap;\n}\n\n/* SAFE OFF(未保护):灰——低姿态提醒,非错误(用户自己的开关选择) */\n.sp-cardUnprotected .sp-shield {\n color: var(--dsw-alias-label-secondary);\n}\n\n.sp-cardUnprotected .sp-statusWord {\n color: var(--dsw-alias-label-secondary);\n}\n\n/* SAFE ON(保护中):emerald 绿——安心(盾牌实色 + SAFE 文字渐变质感) */\n.sp-cardProtected .sp-shield {\n color: var(--sp-safe-green);\n}\n\n.sp-cardProtected .sp-statusWord {\n color: var(--sp-safe-green);\n background: linear-gradient(135deg, var(--sp-safe-green) 0%, var(--sp-safe-green-deep) 100%);\n -webkit-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n}\n\n/* ── Mac 风格滑块(v1.24.10:轨道 24×13 / thumb 11px 灰白 #f2f4f6 无图标 / cubic-bezier 平滑) ── */\n\n.sp-switch {\n display: inline-block;\n width: 24px;\n height: 13px;\n border-radius: 999px;\n position: relative;\n flex: none;\n cursor: pointer;\n transition: background 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sp-switchOff {\n background: var(--dsw-alias-border-l2);\n}\n\n.sp-switchOn {\n background: var(--sp-safe-green);\n}\n\n.sp-switchThumb {\n position: absolute;\n top: 1px;\n width: 11px;\n height: 11px;\n border-radius: 50%;\n background: #f2f4f6; /* Mac 灰白 thumb(明暗通用) */\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\n transition: left 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.sp-switchOff .sp-switchThumb {\n left: 1px;\n}\n\n.sp-switchOn .sp-switchThumb {\n left: 12px; /* 24 - 11 - 1 */\n}\n\n/* CSS 特异性坑(S013 指南):.sp-switch:hover (0,2,0) 会覆盖 .sp-switchOn (0,1,0)\n * → ON 态 hover 绿底消失。必须同特异性且后定义补回。 */\n.sp-switch:hover {\n filter: brightness(1.08);\n}\n\n.sp-switchOn:hover {\n background: var(--sp-safe-green);\n}\n\n.sp-switchBusy {\n opacity: 0.6;\n cursor: default;\n pointer-events: none;\n}\n\n.sp-chev {\n color: var(--dsw-alias-label-dimmed);\n flex: none;\n}\n\n/* ── 自绘 popover(340px 右上角小卡片,替代官方 Modal) ── */\n\n.sp-root {\n position: relative;\n display: inline-flex;\n}\n\n.sp-pop {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n width: 340px;\n max-width: calc(100vw - 24px);\n z-index: 2000;\n box-sizing: border-box;\n padding: 14px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 14px;\n background: var(--dsw-alias-bg-overlay);\n box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);\n}\n\n/* ── 背景层:宁静号航行动画(ACC 层资产 /serenity/voyage,S142 §12.44)──\n 卡片展开时,背景换成「认知星野 + 飞船」= 宁静号的心智模型。\n 可读性设计:卡片底色改成**半透明暗色**,让动画透出来但把对比度压住——\n 正文(白色 label/value)仍落在足够暗的底上;再叠一层轻模糊做磨砂。\n ⚠️ 动画本身在「卡片模式」下已把词元压到 22% 不透明度、铭牌层整层关闭,\n 这里只负责**让位与压暗**,不改作品。 */\n.sp-popVoyage {\n overflow: hidden; /* 裁掉 iframe 在 14px 圆角外的溢出 */\n /* 合成实测(S142 §12.44,三轮):卡片底色越深,正文越干净,但动画越\"看不见\"——\n 这是一个**真实取舍**,不是可以调没的参数:\n · 0.62 → 飞船最亮的舷窗/灯带正落在「安全模式」「Handyman 模型」两行后面,白字被冲淡\n · 0.85(VLM 建议值)→ 动画基本消失,与\"卡片背景就用这个\"的意图相违\n 取 **0.75** 为中值:正文全部可读,飞船仍看得出轮廓与光晕。若所有者要更干净/更明显,\n 这是唯一的旋钮(另一个旋钮 = iframe 的 blur)。 */\n background: rgba(6, 11, 14, 0.75);\n}\n.sp-voyage {\n position: absolute;\n inset: 0;\n z-index: 0;\n pointer-events: none; /* 纯背景:不挡点击、不抢焦点 */\n overflow: hidden;\n border-radius: 13px;\n}\n.sp-voyage iframe {\n display: block;\n width: 100%;\n height: 100%;\n border: 0;\n /* 把星野的细小亮斑与船体高光化开,避免与正文笔画\"打架\"。\n 1.8px 实测(§12.44 合成第二轮)会把飞船糊成看不清形状 ⇒ 收到 1.2px:\n 既要\"看得出是一艘船\",又要它退到正文之后。\n ⚠️ 用 iframe 自身的 filter 而**不是** backdrop-filter:iframe 内容不参与本文档的\n backdrop(跨文档不采样)⇒ backdrop-filter 对它无效,只有 filter 才是可靠的杠杆。 */\n filter: blur(1.2px);\n}\n.sp-popVoyage > .sp-popBody {\n position: relative;\n z-index: 1;\n}\n\n.sp-popBody {\n display: flex;\n flex-direction: column;\n gap: 14px;\n max-height: calc(100vh - 140px);\n overflow-y: auto;\n}\n\n/* ── 分组(官方 settings 语言:groupTitle + rows) ── */\n\n.sp-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sp-groupHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.sp-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.sp-rows {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n/* 行卡(rowCard:border + radius + padding;值与 label 分离、长内容可换行) */\n.sp-row {\n display: flex;\n align-items: baseline;\n gap: 12px;\n min-width: 0;\n padding: 8px 12px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.sp-label {\n flex: none;\n width: 76px;\n font-size: 12px;\n font-weight: 500;\n color: var(--dsw-alias-label-secondary);\n white-space: nowrap;\n}\n\n.sp-value {\n flex: 1;\n min-width: 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-primary);\n font-family: var(--ds-font-family-code, monospace);\n word-break: break-all;\n overflow-wrap: anywhere;\n}\n\n/* 安全模式动作区 */\n.sp-actions {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 8px 12px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-2);\n}\n\n.sp-toggle {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 24px;\n padding: 0 10px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 6px;\n font-size: 12px;\n cursor: pointer;\n transition: background var(--ds-transition-duration-fast, 0.1s) var(--ds-ease-in-out, ease);\n}\n\n.sp-toggleLg {\n height: 30px;\n padding: 0 16px;\n font-size: 13px;\n}\n\n.sp-toggleOn {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 14%, transparent);\n color: var(--dsw-alias-state-error-primary);\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary) 45%, transparent);\n}\n\n.sp-toggleOff {\n background: var(--dsw-alias-interactive-bg-hover);\n color: var(--dsw-alias-label-secondary);\n}\n\n.sp-toggleIcon {\n flex: none;\n}\n\n.sp-toggleDesc {\n flex: 1;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-label-tertiary);\n}\n\n/* handyman 运行状态区块 */\n\n.sp-handymenToggle {\n flex: none;\n padding: 2px 10px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n cursor: pointer;\n}\n\n.sp-handymenToggle:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.sp-handymenList {\n display: flex;\n flex-direction: column;\n gap: 4px;\n margin-top: 2px;\n}\n\n.sp-handymanItem {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: 8px 12px;\n border: 1px solid var(--dsw-alias-border-l1);\n border-radius: 8px;\n min-width: 0;\n}\n\n.sp-handymanHead {\n display: flex;\n align-items: baseline;\n gap: 8px;\n min-width: 0;\n}\n\n.sp-handymanLabel {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 12px;\n font-weight: 500;\n color: var(--dsw-alias-label-primary);\n}\n\n.sp-handymanRound {\n flex: none;\n font-size: 11px;\n color: var(--dsw-alias-label-dimmed);\n}\n\n.sp-handymanTime {\n flex: none;\n font-size: 11px;\n color: var(--dsw-alias-label-dimmed);\n}\n\n.sp-handymanResp {\n font-size: 11px;\n line-height: 16px;\n color: var(--dsw-alias-label-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.sp-handymenMore {\n font-size: 11px;\n color: var(--dsw-alias-label-dimmed);\n padding: 4px 12px;\n}\n\n/* 底部提示(配置入口引导) */\n.sp-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 padding: 8px 12px;\n border: 1px dashed var(--dsw-alias-border-l2);\n border-radius: 10px;\n}\n";
12
12
  if (typeof document !== "undefined" && document.querySelector("style[data-sp-css=\"SafeModePanel\"]") === null) {
13
13
  const tag = document.createElement("style");
14
14
  tag.setAttribute("data-sp-css", "SafeModePanel");
@@ -176,11 +176,20 @@ window.__ModuleLoader__.load({
176
176
  className: cx("sp-chev")
177
177
  })
178
178
  ]
179
- }), open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
180
- className: cx("sp-pop"),
179
+ }), open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
180
+ className: cx("sp-pop", "sp-popVoyage"),
181
181
  role: "dialog",
182
182
  "aria-label": "CCC 状态栏",
183
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
183
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
184
+ className: cx("sp-voyage"),
185
+ "aria-hidden": "true",
186
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
187
+ src: `/serenity/voyage?card=1&v=${encodeURIComponent(status.accVersion)}`,
188
+ title: "",
189
+ loading: "lazy",
190
+ tabIndex: -1
191
+ }, status.accVersion)
192
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
184
193
  className: cx("sp-popBody"),
185
194
  children: inCcc ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
186
195
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -349,7 +358,7 @@ window.__ModuleLoader__.load({
349
358
  })
350
359
  })]
351
360
  })
352
- })
361
+ })]
353
362
  })]
354
363
  });
355
364
  }
@@ -4735,23 +4744,6 @@ Instruction-following style:
4735
4744
  })]
4736
4745
  });
4737
4746
  }
4738
- /** 只读定义列表(dl/dt/dd 网格——v1.27.5 紧凑化:只读状态不再各占一行卡) */
4739
- function DefList(props) {
4740
- const { items } = props;
4741
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dl", {
4742
- className: "ss-defList",
4743
- children: items.map((it) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4744
- className: "ss-defItem",
4745
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", {
4746
- className: "ss-defTerm",
4747
- children: it.term
4748
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", {
4749
- className: "ss-defValue",
4750
- children: it.value
4751
- })]
4752
- }, it.term))
4753
- });
4754
- }
4755
4747
  /** dsh 原生设置面板:serenity-hooks 配置页(官方 settings 设计语言,多级标题) */
4756
4748
  function SettingsSection(props) {
4757
4749
  const { scope } = props;
@@ -4788,14 +4780,12 @@ Instruction-following style:
4788
4780
  const acpOn = value?.acpEnabled ?? false;
4789
4781
  const acpPort = value?.acpHttpPort ?? 3100;
4790
4782
  const publicAskOn = value?.publicAskEnabled ?? false;
4791
- const autopilotOn = value?.autopilotWakeEnabled ?? value?.autopilotEnabled ?? false;
4792
4783
  const wakeSchedOn = value?.wakeSchedulerEnabled ?? true;
4793
4784
  const [openGateway, setOpenGateway] = (0, react.useState)(false);
4794
4785
  const [openRebuild, setOpenRebuild] = (0, react.useState)(false);
4795
4786
  const [openSkiff, setOpenSkiff] = (0, react.useState)(false);
4796
4787
  const [openAcp, setOpenAcp] = (0, react.useState)(false);
4797
4788
  const [openPublicAsk, setOpenPublicAsk] = (0, react.useState)(false);
4798
- const [openAutopilot, setOpenAutopilot] = (0, react.useState)(false);
4799
4789
  const [openWakeSched, setOpenWakeSched] = (0, react.useState)(false);
4800
4790
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4801
4791
  className: "ss-section",
@@ -4942,24 +4932,6 @@ Instruction-following style:
4942
4932
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PublicAskEditor, { publicAskOn })]
4943
4933
  })
4944
4934
  }) }),
4945
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
4946
- title: "周期自唤醒(autopilot)",
4947
- desc: "定时唤起 autopilot 轨迹(全局开关,默认关——只在指定电脑开启)",
4948
- expandable: true,
4949
- open: openAutopilot,
4950
- onToggle: setOpenAutopilot,
4951
- control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Toggle, {
4952
- checked: autopilotOn,
4953
- onChange: (on) => toggle("autopilotWakeEnabled", on)
4954
- }),
4955
- detail: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4956
- className: "ss-detailStack",
4957
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4958
- className: "ss-detailIntro",
4959
- children: "周期自唤醒全局闸(v1.34 更名收窄,原 Autopilot Trajectory 全局总开关):\n· 作用:控制本机(本 dsh 实例)是否运行**周期**自动巡航唤起\n· 语义边界:**只管周期自唤醒** —— 关掉它不影响一次性唤醒(wake-later,见下一行)\n· 默认关:未开启即使 CCC 配置 enabled=true 也不启动定时器\n· 定位:多台电脑装 dsp 时,只在指定电脑开启(其余默认关)\n· 双重门控:本开关 AND CCC 级 enabled 都满足才运行\n· CCC 级配置(interval/session/偏见脚本/焦点)不受影响"
4960
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutopilotTrajectoryStatusBlock, { autopilotOn })]
4961
- })
4962
- }) }),
4963
4935
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
4964
4936
  title: "唤醒调度器(wake-later)",
4965
4937
  desc: "投递已登记的“未来时刻 + 一条 message”(全局开关,默认开)",
@@ -4974,7 +4946,7 @@ Instruction-following style:
4974
4946
  className: "ss-detailStack",
4975
4947
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4976
4948
  className: "ss-detailIntro",
4977
- children: "唤醒调度器全局闸(v1.34 新增独立开关):\n· 作用:把 CCC 唤醒注册表(AGENT_SESSIONS/wake-registry.json)里到点的条目投递给目标轨迹\n· 条目来源:`container_trajectory wake-later`(对自己或别的 trajectory 预约未来时刻 + 一条 message)\n· 默认开:条目全部由人类/agent 显式登记,无环境自主性 ⇒ 不需要“默认关”的实验保护\n· 与上一行**互不连带**:关掉周期自唤醒不会关掉本调度器(用户 2026-09-15 裁决)\n· 精度:5min tick;补跑窗口 2h(超窗判 missed 留痕);fire-and-forget 无回执"
4949
+ children: "唤醒调度器全局闸(v1.34 独立开关):\n· 作用:把 CCC 唤醒注册表(AGENT_SESSIONS/wake-registry.json)里到点的条目投递给目标轨迹\n· 条目来源:`container_trajectory wake-later`(对自己或别的 trajectory 预约未来时刻 + 一条 message)\n· 默认开:条目全部由人类/agent 显式登记,无环境自主性 ⇒ 不需要“默认关”的实验保护\n· 唯一性:ACC 现存的**唯一**轨迹调度时钟(原并列的周期自唤醒闸已随 ACC 侧 autopilot 退场删除)\n· 精度:5min tick;补跑窗口 2h(超窗判 missed 留痕);fire-and-forget 无回执"
4978
4950
  })
4979
4951
  })
4980
4952
  }) })
@@ -5124,184 +5096,6 @@ Instruction-following style:
5124
5096
  ]
5125
5097
  });
5126
5098
  }
5127
- /** 「Autopilot Trajectory」只读状态区块(v1.26.14;v1.27.4 多 CCC:显式 CCC 选择器——
5128
- * GET/POST 带 ?ccc=/body.ccc——用户"两个 CCC 都设定了,但手工唤起只能唤起一个"修复):
5129
- * 展示所选 CCC 的状态(配置摘要 + 目标会话 + 窗口/可唤起判定 + 审计);配置改走 CCC 配置文件
5130
- * v1.29:autopilotOn prop(需求②——原折叠块并入开关行 detail,全局门控状态由外部行显示) */
5131
- function AutopilotTrajectoryStatusBlock(props) {
5132
- const [cccs, setCccs] = (0, react.useState)([]);
5133
- const [selectedRoot, setSelectedRoot] = (0, react.useState)("");
5134
- const [status, setStatus] = (0, react.useState)(null);
5135
- const [wakes, setWakes] = (0, react.useState)([]);
5136
- const [unavailable, setUnavailable] = (0, react.useState)(false);
5137
- const [waking, setWaking] = (0, react.useState)(false);
5138
- const [wakeResult, setWakeResult] = (0, react.useState)(null);
5139
- (0, react.useEffect)(() => {
5140
- let alive = true;
5141
- (async () => {
5142
- try {
5143
- const res = await fetch("/serenity/cccs", { headers: { accept: "application/json" } });
5144
- if (!res.ok) return;
5145
- const body = await res.json();
5146
- if (!alive || !Array.isArray(body.cccs)) return;
5147
- setCccs(body.cccs);
5148
- if (body.cccs.length > 0) setSelectedRoot((prev) => prev || body.cccs[0].root);
5149
- else setUnavailable(true);
5150
- } catch {}
5151
- })();
5152
- return () => {
5153
- alive = false;
5154
- };
5155
- }, []);
5156
- const refresh = (0, react.useCallback)(async () => {
5157
- if (!selectedRoot) return;
5158
- try {
5159
- const res = await fetch(`/serenity/trajectory?ccc=${encodeURIComponent(selectedRoot)}`, { headers: { accept: "application/json" } });
5160
- if (!res.ok) return;
5161
- const body = await res.json();
5162
- if (Array.isArray(body.wakes)) setWakes(body.wakes);
5163
- if (body.status) {
5164
- setStatus(body.status);
5165
- setUnavailable(false);
5166
- } else {
5167
- setStatus(null);
5168
- setUnavailable(true);
5169
- }
5170
- } catch {}
5171
- }, [selectedRoot]);
5172
- (0, react.useEffect)(() => {
5173
- refresh();
5174
- return () => {};
5175
- }, [refresh]);
5176
- const wakeNow = async () => {
5177
- if (waking || !selectedRoot) return;
5178
- setWaking(true);
5179
- setWakeResult(null);
5180
- try {
5181
- const res = await fetch("/serenity/trajectory", {
5182
- method: "POST",
5183
- headers: {
5184
- "content-type": "application/json",
5185
- "x-serenity-ui": "1"
5186
- },
5187
- body: JSON.stringify({
5188
- action: "wake",
5189
- ccc: selectedRoot
5190
- })
5191
- });
5192
- const body = await res.json();
5193
- setWakeResult(body.detail ?? body.error ?? `HTTP ${res.status}`);
5194
- refresh();
5195
- } catch (err) {
5196
- setWakeResult(err instanceof Error ? err.message : String(err));
5197
- } finally {
5198
- setWaking(false);
5199
- }
5200
- };
5201
- if (unavailable && cccs.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
5202
- className: "ss-rows",
5203
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
5204
- title: "未激活",
5205
- desc: "未发现候选 CCC(/serenity/cccs 为空)——先在工作区打开一个 CCC 会话",
5206
- control: null
5207
- }) })
5208
- });
5209
- if (!status) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
5210
- className: "ss-rows",
5211
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
5212
- title: "加载中…",
5213
- desc: "读取 Autopilot Trajectory 状态",
5214
- control: null
5215
- }) })
5216
- });
5217
- const target = status.target;
5218
- const { autopilotOn } = props;
5219
- const stateText = !props.autopilotOn ? "全局开关关闭(在「外部能力」组开启后才运行)" : !status.configured ? "未配置(机制未开始)" : !status.enabled ? "已配置,未启用(enabled=false,零资源占用)" : "已启用 — 时钟唤起等待中";
5220
- const targetText = target ? `${target.dirName}${target.autoFlag ? "(--auto ✓)" : "(无 --auto 标志)"} · 空闲 ${target.idleHours.toFixed(1)}h / 阈值 ${status.intervalHours}h` : status.session ? `会话 ${status.session} 未命中(AGENT_SESSIONS 无匹配)` : "未配置目标会话(不唤起)";
5221
- const wakeReady = status.enabled && !!target && target.autoFlag;
5222
- const lastWake = status.recentWakes[0];
5223
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", {
5224
- className: "ss-rows",
5225
- children: [
5226
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
5227
- title: "目标 CCC",
5228
- desc: "多 CCC 各自独立——选中哪个就查看/唤起哪个",
5229
- help: "Autopilot Trajectory 目标认知容器:\n· 机制:dsh 一个进程可挂载多个 CCC,每个 CCC 的 autopilot 独立配置\n· 选择:下拉切换要查看/唤起的目标 CCC(各 CCC 时钟独立)\n· 配置:各 CCC 在自身 .opencode/serenity.json 定义 trajectory.autopilot(旧键 autopilotTrajectory 兼容)\n· 唤起:仅对选中 CCC 生效,互不干扰",
5230
- control: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
5231
- className: "ss-select",
5232
- value: selectedRoot,
5233
- onChange: (e) => {
5234
- setSelectedRoot(e.target.value);
5235
- setStatus(null);
5236
- },
5237
- children: [cccs.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
5238
- value: "",
5239
- children: "加载中…"
5240
- }), cccs.map((c) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
5241
- value: c.root,
5242
- children: c.name || c.root
5243
- }, c.root))]
5244
- })
5245
- }) }),
5246
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
5247
- title: "运行状态",
5248
- desc: stateText,
5249
- help: "Autopilot Trajectory 运行状态含义:\n· 未配置:该 CCC 未定义 trajectory.autopilot(机制不开始)\n· 已配置未启用:enabled=false,零资源占用(不唤起不消耗)\n· 已启用:时钟驱动周期性自动唤起——无人类活动满间隔小时数后\n 启动一次前台 agent 轮(用户全程可见可介入)",
5250
- control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5251
- className: "ss-value",
5252
- children: status.enabled ? "● 运行中" : status.configured ? "○ 待启" : "—"
5253
- })
5254
- }) }),
5255
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5256
- className: "ss-rowCard",
5257
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefList, { items: [
5258
- {
5259
- term: "目标会话",
5260
- value: targetText
5261
- },
5262
- {
5263
- term: "唤起窗口",
5264
- value: `北京 ${status.beijingHour} 点 — ${status.windowAllowed ? "允许" : `避开 ${status.avoidWakeHours.start}~${status.avoidWakeHours.end}`}`
5265
- },
5266
- {
5267
- term: "偏见提供者",
5268
- value: status.biasProvider
5269
- },
5270
- {
5271
- term: "轨迹焦点",
5272
- value: status.topPrompt ?? "未定义(CCC 应填写,防焦点丢失)"
5273
- },
5274
- {
5275
- term: "最近唤起",
5276
- value: lastWake ? `${new Date(lastWake.time).toLocaleString()} — ${lastWake.ok ? "✓" : "✗"} ${lastWake.detail}` : "尚无"
5277
- }
5278
- ] })
5279
- }) }),
5280
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5281
- className: "ss-rowCard",
5282
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefList, { items: [{
5283
- term: "唤醒注册表",
5284
- value: wakes.length === 0 ? "无条目(agent 用 container_trajectory wake-later 登记:未来时刻 + 一条 message)" : `${wakes.filter((w) => w.state === "pending").length} 条在办 / 共 ${wakes.length} 条`
5285
- }, ...wakes.slice(0, 5).map((w) => ({
5286
- term: w.state === "pending" ? "· 待唤醒" : `· ${w.state}`,
5287
- value: `${new Date(w.at).toLocaleString()} → ${w.target}${w.lastResult ? `(${w.lastResult})` : ""}`
5288
- }))] })
5289
- }) }),
5290
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowCard, {
5291
- title: "立即唤起",
5292
- desc: wakeResult ?? "调试:手动触发一次(跳过窗口/间隔,仍校验配置与偏见脚本)",
5293
- help: "立即唤起(调试语义):\n· 用途:手动触发一次该 CCC 的自动唤起(不等时钟)\n· 跳过:唤起窗口(北京 8~18 点避开)/ 间隔\n· 保留校验:enabled、目标会话(--auto)、偏见脚本可运行\n· 场景:验证配置/偏见脚本是否就绪,或想立刻跑一轮",
5294
- control: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5295
- type: "button",
5296
- className: "ss-wakeBtn",
5297
- disabled: !wakeReady || waking,
5298
- onClick: () => void wakeNow(),
5299
- children: waking ? "唤起中…" : "立即唤起"
5300
- })
5301
- }) })
5302
- ]
5303
- });
5304
- }
5305
5099
  //#endregion
5306
5100
  //#region src/client/index.ts
5307
5101
  const inject = [
@@ -15,20 +15,19 @@
15
15
  * 其模块级运行时对象里,任何"重新推导"得到的都是与真实调度器不一致的假值。
16
16
  *
17
17
  * 依赖分层(为什么本模块"重"而 `kit-ops` / `status` 保持"轻"):
18
- * {@link containerClocks} 必须读 `wake-scheduler` / `autopilot-trajectory` 的进程内快照,而这两个
19
- * 模块带 **@deepseek-ai 值依赖**(`dsh-llm` 的 `createUserMessage`)。故本模块**只能**被本就重型或
20
- * 异步的消费方使用:`diag-ops`(静态 import)、`api.ts` / `kit-ops`(`await import(...)`,与
21
- * `api.ts` 既有的"保持静态链纯净"约定一致)。**轻链模块不得静态 import 本模块**。
18
+ * {@link containerClocks} 必须读 `wake-scheduler` 的进程内快照,而该模块带 **@deepseek-ai 值依赖**
19
+ * (`dsh-llm` 的 `createUserMessage`)。故本模块**只能**被本就重型或异步的消费方使用:
20
+ * `diag-ops`(静态 import)、`api.ts` / `kit-ops`(`await import(...)`,与 `api.ts` 既有的
21
+ * "保持静态链纯净"约定一致)。**轻链模块不得静态 import 本模块**。
22
22
  *
23
23
  * 已有的单一真相源继续指向原处(**不复制**):
24
24
  * L0 根解析 `ccc.ts findSerenityRoot`|L1/L2 根与枚举 `ccc-roots.ts`|宿主契约 `host/contract.ts`
25
- * |CCC 配置 `ccc.ts loadSerenityConfig`|注册表 `msm-ops.ts`|时钟 `wake-scheduler.ts` /
26
- * `autopilot-trajectory.ts`|唤醒注册表 `wake-registry.ts`。
25
+ * |CCC 配置 `ccc.ts loadSerenityConfig`|注册表 `msm-ops.ts`|时钟 `wake-scheduler.ts`
26
+ * |唤醒注册表 `wake-registry.ts`。
27
27
  */
28
28
  import { type HostContractReport } from './host/contract.js';
29
29
  import { checkRegistryQuality, type RegistryQualityReport } from './msm-ops.js';
30
30
  import { type WakeEntry } from './wake-registry.js';
31
- import { autopilotClockState, getAutopilotStatus } from './autopilot-trajectory.js';
32
31
  import { wakeSchedulerState } from './wake-scheduler.js';
33
32
  import type { JsonValue } from './json.js';
34
33
  export interface ContainerIdentity {
@@ -100,25 +99,21 @@ export declare function checkRegistryHealth(root: string): RegistryStructureRepo
100
99
  export { checkRegistryQuality, type RegistryQualityReport };
101
100
  /**
102
101
  * 进程内时钟快照类型。
103
- * ⚠️ 两个时钟的形状由**各自模块**定义(`WakeSchedulerRuntime` / `AutopilotClockRuntime`,
104
- * 两者都未导出且 `autopilot` 少一个 `lastTickLog` 字段)——故此处取**联合**:它们对外暴露的
105
- * 诊断字段(armed / enabled / ticks / lastTickAt / armedAt / lastSkipReason)语义同规格,
106
- * 但类型上不是同一个。**不为了合并类型去改那两个模块的导出面**。
102
+ * ⚠️ 形状由**时钟模块自身**定义(`wake-scheduler.ts` 未导出的 `WakeSchedulerRuntime`)——故此处
103
+ * 直接取其返回类型。2026-09-15:原为「唤醒调度器 autopilot」联合(两者诊断字段同规格但类型
104
+ * 不同);autopilot 时钟随 ACC autopilot 退场删除后,**只剩一座钟**(唤醒调度器)。
107
105
  */
108
- export type ClockSnapshot = ReturnType<typeof wakeSchedulerState> | ReturnType<typeof autopilotClockState>;
106
+ export type ClockSnapshot = ReturnType<typeof wakeSchedulerState>;
109
107
  export interface ContainerClocks {
110
108
  /** 唤醒调度器(一次性唤醒,5min tick)——**模块级快照**,不重算 */
111
109
  wake: ClockSnapshot;
112
- /** autopilot 时钟(周期自唤醒 tick)——**模块级快照**,不重算 */
113
- autopilot: ClockSnapshot;
114
110
  }
115
111
  /**
116
- * 两条时钟的进程内状态("为什么这轮没被唤起"的第一手判据)。
112
+ * 时钟的进程内状态("为什么这轮没被唤起"的第一手判据)。
117
113
  *
118
114
  * 🔴 **只读快照,不重算**(设计红线):`armed`/`ticks`/`lastTickAt`/`lastSkipReason` 只存在于
119
- * 调度器自己的模块级运行时对象里(`wake-scheduler.ts schedulerRuntime` /
120
- * `autopilot-trajectory.ts` 同规格对象)。任何"从配置或文件重新推导"得到的值都会与真实
121
- * 调度器的状态不一致——那比没有可观测量更糟(会给出假的"一切正常")。
115
+ * 调度器自己的模块级运行时对象里(`wake-scheduler.ts schedulerRuntime`)。任何"从配置或文件
116
+ * 重新推导"得到的值都会与真实调度器的状态不一致——那比没有可观测量更糟(会给出假的"一切正常")。
122
117
  */
123
118
  export declare function containerClocks(): ContainerClocks;
124
119
  export interface ContainerWakes {
@@ -132,14 +127,10 @@ export interface ContainerWakes {
132
127
  /** 唤醒注册表取数(文件 IO:每个渲染点自己决定是否要看它) */
133
128
  export declare function containerWakes(root: string): ContainerWakes;
134
129
  /**
135
- * autopilot 目标状态取数(读 CCC 配置 + 目标 SESSION.md 的 mtime 探测)。
136
- * WebUI 面板 / `acc-diag` 一致——两边渲染的是**同一份** `getAutopilotStatus()` 结果。
137
- * 类型从该函数的返回类型派生(`AutopilotTrajectoryStatus` 未从 `autopilot-trajectory.ts` 导出,
138
- * 此处不为了转出而改动那个模块的导出面)。
130
+ * autopilot 目标状态取数(`getAutopilotStatus`)与 `AutopilotStatusSnapshot` 类型,
131
+ * 连同 ACC autopilot 机制于 2026-09-15 整体删除(所有者裁决 (a))——原消费方是设置面板
132
+ * 的「Autopilot Trajectory」区块与 `/serenity/trajectory` 端点,两者同批删除。
139
133
  */
140
- export type AutopilotStatusSnapshot = ReturnType<typeof getAutopilotStatus>;
141
- /** @returns CCC 根缺失(null)→ null */
142
- export declare function containerAutopilot(root: string | null): AutopilotStatusSnapshot | null;
143
134
  export interface ContainerStatus {
144
135
  identity: ContainerIdentity;
145
136
  principles: ContainerPrinciples;
@@ -176,8 +167,9 @@ export interface ContainerStatusOptions {
176
167
  /**
177
168
  * 核心段组装(`dashboard health` 的取数:身份 + 三原则 + 注册表两判据 + 配置 + 宿主契约)。
178
169
  *
179
- * 时间轴三段(时钟/唤醒注册表/autopilot 目标)**不在本组装内**:它们是各自独立消费方的需要
180
- * (`acc-diag` / `/serenity/trajectory`),硬塞进来会让只想看三原则的调用方付无谓的 IO。
181
- * 需要时按名字调 {@link containerClocks} / {@link containerWakes} / {@link containerAutopilot}
170
+ * 时间轴两段(时钟/唤醒注册表)**不在本组装内**:它们是各自独立消费方的需要
171
+ * (`acc-diag` / 开发面诊断),硬塞进来会让只想看三原则的调用方付无谓的 IO。
172
+ * 需要时按名字调 {@link containerClocks} / {@link containerWakes}。
173
+ * (原第三段「autopilot 目标」及其取数函数 `containerAutopilot` 已随 ACC 侧 autopilot 退场删除。)
182
174
  */
183
175
  export declare function containerStatus(opts?: ContainerStatusOptions): ContainerStatus;
package/lib/diag-ops.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * diag-ops.ts — `acc-diag` 报告装配(v1.33,S142 §32.11
2
+ * diag-ops.ts — `acc-diag` 报告装配(v1.33,S142 §32.11;2026-09-15 段数收缩)
3
3
  *
4
4
  * 为什么单独成模块(R↓):工具面(`tools/acc-diag.ts`)只做"取 CCC 根 + 渲染",
5
5
  * 装配逻辑放这里 ⇒ 纯函数可单测、不依赖 DSH 工具注册。
@@ -7,40 +7,45 @@
7
7
  * 为什么**无动作参数**:诊断是低频动作(§32.9 收敛取向),一次调用即出全报告,
8
8
  * 不需要子命令面;动作越多,模型选择成本越高。
9
9
  *
10
- * 四段内容(数据来源各自单一真相源,本模块只聚合不复制语义):
11
- * ① live 运行态 —— 插件进程内 `diagLive(ctx)`(live 会话清单 + autopilot CCC 的
12
- * 目标命中 / agent 定位诊断)——**独立进程看不到运行时**,这正是本工具存在的理由
13
- * 面板解析 —— `diagLive.panelResolved`(无参面板请求会落到哪个 CCC)
14
- * ③ 唤醒注册表 —— `wake-registry.json` 全量条目(state / at / target / lastResult)+ 补跑窗口
15
- * ④ 唤起条件链 —— **进程内** {@link buildWakeChain}(⑥ C6a):逐条件值 + 阻断点 + 修复建议
16
- * + 只有进程内能看到的三项事实(全局闸 / live 会话 / agent 可解析性)
10
+ * 三段内容(数据来源各自单一真相源,本模块只聚合不复制语义):
11
+ * ① live 运行态 —— 插件进程内 `diagLive(ctx)`(进程 cwd/CCC + live 会话清单)
12
+ * ——**独立进程看不到运行时**,这正是本工具存在的理由
13
+ * ①b 唤醒时钟 —— `containerClocks().wake`(唤醒调度器进程内快照:武装态/计数/上次跳过原因)
14
+ * ③ 唤醒注册表 —— `wake-registry.json` 全量条目(state / at / target / lastResult)+ 补跑窗口
17
15
  *
18
- * C5「观察面归一」(2026-09-15):①/② 仍走 `diagLive`(那是**live 运行态**的独有取数,
19
- * 没有第二个来源),但 ①b 时钟与 ③ 注册表改经 `container-status.ts` 取(唯一取数出口)——
20
- * **投影仍在本文件**(诊断段不含 `message`,面板含;这是渲染差异,不是取数差异)。
16
+ * ── 2026-09-15:段数由四降为三(S142「ACC autopilot 退场」§1 二阶裁定)─────────────
17
+ * ACC autopilot 整段退场后,报告里两段的**主语消失**,故删除(不是"暂时关掉"):
18
+ * · ② 面板解析 —— `diagLive.panelResolved` 的来源是"哪个 CCC 配了 autopilot",
19
+ * 面板区块同批删除 ⇒ 主语不存在。
20
+ * · 原 ④ 唤起条件链 —— 整段都是 ACC autopilot 的唤起条件(`buildWakeChain` +
21
+ * `autopilotRuntimeFacts`),实现模块已删 ⇒ 不留第二份条件链、也不留半死的手写版。
22
+ * · 原 ① 段的 autopilot CCC 渲染(逐 CCC 目标命中 / agent 定位)同批删除。
21
23
  *
22
- * C6a(2026-09-15):④ 段由"spawn 包内脚本"改为**进程内计算**。旧实现是本报告里
23
- * 唯一一条**跨进程**取数:脚本看不到全局闸/live/agent 与本工具 段自相矛盾
24
- * (① 说"agent 未定位",④ 却印"条件全部满足")。现在 段与 段读**同一份事实**
25
- * (`autopilotRuntimeFacts`),且条件链**只有一份实现**(开发面 `dsh-develop diag` import 同一个)。
24
+ * 🔴 **已知缺口(登记,不静默丢弃)**:④「为什么这轮没唤起」的诊断在 **CCC 自管理链**上归零。
25
+ * 新链的失败形态是"S151 漏了自排下一轮"或"调度器闸关/未 tick",而删掉 后这两种病因都不可见。
26
+ * 按所有者裁决本次**不补**(一句话可补,代价 = 一条新条件链:调度器 armed / / tick 在跑 /
27
+ * 条目到期 / 补跑窗口 / 目标可解析 / CCC 闸)。**不得**以"顺手保留 ④"的方式把它偷偷带回。
28
+ *
29
+ * C5「观察面归一」(2026-09-15):① 走 `diagLive`(那是**live 运行态**的独有取数,没有第二个
30
+ * 来源);①b 时钟与 ③ 注册表经 `container-status.ts` 取(唯一取数出口)——**投影仍在本文件**
31
+ * (诊断段不含 `message`,面板含;这是渲染差异,不是取数差异)。
26
32
  */
27
- import { type DiagLiveReport } from './autopilot-trajectory.js';
33
+ import { type DiagLiveReport } from './live-sessions.js';
28
34
  import { type ClockSnapshot } from './container-status.js';
29
35
  import type { Context } from 'cordis';
30
- /** 进程内时钟状态(唤醒调度器 / autopilot 时钟;判据各自单一真相源) */
36
+ /** 进程内时钟状态(唤醒调度器;判据单一真相源 = `wake-scheduler.ts`) */
31
37
  type ClockState = ClockSnapshot;
32
38
  interface AccDiagReport {
33
39
  /** 调用方会话所属 CCC 根(过程内诊断的目标) */
34
40
  ccc: string;
35
41
  live: DiagLiveReport;
36
42
  /**
37
- * 进程内两个时钟的武装状态(2026-09-14 F 段缺陷**新暴露面**)。
38
- * 为什么必须有(R↓):此前"条目为何滞留在 pending"无法从报告回答——④ 段只算**配置**条件,
39
- * 而真正的原因可能在"时钟根本没在跑"这一层。有了它,同类故障一眼可判。
43
+ * 唤醒调度器的进程内武装状态(2026-09-14 F 段缺陷**新暴露面**)。
44
+ * 为什么必须有(R↓):此前"条目为何滞留在 pending"无法从报告回答。有了它,
45
+ * "时钟根本没在跑"这一类故障一眼可判——这是 ACC 现存的**唯一**轨迹调度时钟。
40
46
  */
41
47
  clocks: {
42
48
  wake: ClockState;
43
- autopilot: ClockState;
44
49
  };
45
50
  wakes: {
46
51
  /** 注册表文件路径问题(读不到时非空——不得静默) */
@@ -56,21 +61,14 @@ interface AccDiagReport {
56
61
  }>;
57
62
  pending: number;
58
63
  };
59
- /**
60
- * 唤起条件链(进程内算出的渲染文本,含逐条件值 + 阻断点 + 修复建议)。
61
- * **不是**子进程输出——判据唯一实现见 `autopilot-chain.ts`。
62
- */
63
- autopilotChain: string;
64
- /** 条件链判决档(`ready`/`waiting`/`blocked`/`unknown`;供调用方/测试断言,不再解析文本) */
65
- autopilotVerdict: string;
66
64
  }
67
65
  /**
68
66
  * 装配报告(一次调用即全报告)。
69
67
  * @param ctx 插件上下文(进程内读 sessions/agents)
70
- * @param root 调用方 CCC 根(条件链诊断目标)
68
+ * @param root 调用方 CCC 根(唤醒注册表取数目标)
71
69
  * @returns 结构化报告(渲染由 {@link renderAccDiag} 负责)
72
70
  */
73
71
  export declare function runAccDiag(ctx: Context, root: string): Promise<AccDiagReport>;
74
- /** 人读渲染(四段;空段也要显式说明"无",避免"沉默 = 一切正常"的误读) */
72
+ /** 人读渲染(三段;空段也要显式说明"无",避免"沉默 = 一切正常"的误读) */
75
73
  export declare function renderAccDiag(r: AccDiagReport): string;
76
74
  export {};
@@ -10,7 +10,7 @@
10
10
  * - `ctx.effect` 是宿主成员,但**不可假定存在**(测试替身、极旧宿主、HMR 早期阶段)。
11
11
  * 直接裸调会让 `apply` 抛错 = 整个 dsh 启动失败(app-boot "plugin(s) failed to load"),
12
12
  * 这比"资源没拆卸"严重得多——所以缺失时**响亮降级**(记录 + 返回 false)。
13
- * - 零依赖叶模块:gateway / autopilot 等模块只引它,不会因此被拖进 skiff/rebuild 的依赖链。
13
+ * - 零依赖叶模块:gateway 等模块只引它,不会因此被拖进 skiff/rebuild 的依赖链。
14
14
  */
15
15
  /** 测试辅助:重置"未装配"告警去重(生产零调用) */
16
16
  export declare function __resetDisposerWarningsForTest(): void;