@shgroup/dsh-serenity-hooks 1.56.10 → 1.57.1

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.
Files changed (46) hide show
  1. package/README.md +25 -11
  2. package/dsh.plugin.json +3 -3
  3. package/lib/agent-idle.d.ts +2 -2
  4. package/lib/api.d.ts +0 -1
  5. package/lib/{ccc-DXky9UZu.js → ccc-B0ZGL9lx.js} +30 -13
  6. package/lib/{ccc-roots-CDW2dO0n.js → ccc-roots-GIJ3A_tw.js} +82 -5
  7. package/lib/ccc-roots.d.ts +3 -2
  8. package/lib/ccc.d.ts +23 -10
  9. package/lib/cheap-worker-ops.d.ts +49 -0
  10. package/lib/cheap-worker-preset-inherit.d.ts +35 -0
  11. package/lib/client.js +47 -471
  12. package/lib/config-ops.d.ts +3 -34
  13. package/lib/cro-guide.d.ts +1 -1
  14. package/lib/face-host.d.ts +7 -5
  15. package/lib/host/access.d.ts +2 -2
  16. package/lib/index.d.ts +0 -31
  17. package/lib/index.js +280 -1599
  18. package/lib/invariant.d.ts +1 -1
  19. package/lib/invariant.js +1 -1
  20. package/lib/localstore-ops.d.ts +1 -1
  21. package/lib/{message-source-CQNfQaTx.js → message-source-B4P3Uw6D.js} +1 -1
  22. package/lib/output-guard-seam.d.ts +9 -2
  23. package/lib/ports.d.ts +6 -6
  24. package/lib/seams/context.d.ts +2 -2
  25. package/lib/seams/lifecycle.d.ts +3 -3
  26. package/lib/{settings-section-xHABl8nk.js → settings-section-DQIVsTqE.js} +45 -30
  27. package/lib/settings-section.d.ts +3 -16
  28. package/lib/skiff-core.d.ts +6 -5
  29. package/lib/skiff-debug.d.ts +5 -4
  30. package/lib/{skiff-role-Det66X16.js → skiff-role-B615L9MV.js} +2 -2
  31. package/lib/skiff-role.d.ts +2 -2
  32. package/lib/status.d.ts +2 -2
  33. package/lib/tools/cheap-worker.d.ts +21 -0
  34. package/lib/tools/skiff-admin.d.ts +2 -2
  35. package/lib/unattended-ops.d.ts +6 -4
  36. package/lib/weixin-bridge.d.ts +9 -2
  37. package/lib/weixin-output-guard.d.ts +1 -1
  38. package/lib/{weixin-route-CxCciqQl.js → weixin-route-B9gU1YXz.js} +5 -5
  39. package/package.json +2 -2
  40. package/lib/access-CNccNtgf.js +0 -79
  41. package/lib/acp-core.d.ts +0 -80
  42. package/lib/acp-http.d.ts +0 -37
  43. package/lib/handyman-ops.d.ts +0 -97
  44. package/lib/handyman-preset-inherit.d.ts +0 -35
  45. package/lib/skiff-registry-BjIX_KD1.js +0 -43
  46. package/lib/tools/handyman.d.ts +0 -24
@@ -58,6 +58,6 @@ export declare function assertManifestProse(manifestPath: string, readmePaths: r
58
58
  * `review`(C 档,调引擎 `compliance`)/`index`(调 P1 的生成器)/`status` ⇒ **14**。
59
59
  * 同规格:**条件可见与否不影响这里列它**(本常量 = "插件**具备**的工具面")。
60
60
  */
61
- export declare const REGISTERED_TOOLS: readonly ["container_fs", "container_trajectory", "dashboard", "container_git", "msm", "praxis", "ontology", "serenity-skill-creator", "handyman", "localstore", "container_admin", "im-bridge", "acc-diag", "diagram"];
61
+ export declare const REGISTERED_TOOLS: readonly ["container_fs", "container_trajectory", "dashboard", "container_git", "msm", "praxis", "ontology", "serenity-skill-creator", "cheap-worker", "localstore", "container_admin", "im-bridge", "acc-diag", "diagram"];
62
62
  /** 条件出现的工具数(`REGISTERED_TOOLS` 的**末段**;`assertManifestProse` 用) */
63
63
  export declare const CONDITIONAL_TOOL_COUNT = 3;
package/lib/invariant.js CHANGED
@@ -144,7 +144,7 @@ const REGISTERED_TOOLS = [
144
144
  "praxis",
145
145
  "ontology",
146
146
  "serenity-skill-creator",
147
- "handyman",
147
+ "cheap-worker",
148
148
  "localstore",
149
149
  "container_admin",
150
150
  "im-bridge",
@@ -14,7 +14,7 @@
14
14
  * 存储结构(JSON 顶层分节):
15
15
  * { "credentials": { "HOME_GITLAB_TOKEN": "xxx" }, "<config节>": { "<key>": "v" } }
16
16
  * credentials 为保留节(credential 命名空间,key 大写蛇形);其余节归 config 命名空间
17
- * (path = section.key,如 handyman.models)。
17
+ * (path = section.key,如 cheap-worker.models)。
18
18
  */
19
19
  import type { JsonValue } from './json.js';
20
20
  /** 命名空间:credential(凭据)| config(配置) */
@@ -1,4 +1,4 @@
1
- import { r as cccRootForCwd } from "./ccc-roots-CDW2dO0n.js";
1
+ import { r as cccRootForCwd } from "./ccc-roots-GIJ3A_tw.js";
2
2
  import { basename, dirname, join } from "node:path";
3
3
  import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, writeFileSync } from "node:fs";
4
4
  //#region src/time.ts
@@ -5,10 +5,17 @@
5
5
  * 命中 → `agent.steer(buildRebuke(hits))` 打回重生成(turn 不关闭,模型同轮重答)。
6
6
  * 连续命中达 REBUKE_MAX_ROUNDS → 放弃打回(防死循环),输出保留 + 审计日志。
7
7
  *
8
- * 作用范围(v1.26.3 用户拍板):**仅外部面**——skiff/ACP/问答页等对外输出会话
9
- * (session id `skiff-`/`acp-`/`rebuild-` 前缀;v1.22.4 rebuild 新建会话同面)。
8
+ * 作用范围(v1.26.3 用户拍板):**仅外部面**——skiff 等对外输出会话
9
+ * (session id `skiff-`/`rebuild-` 前缀;v1.22.4 rebuild 新建会话同面)。
10
10
  * **本地维护会话(普通 dsh 会话)不检测**——维护会话必然提及机制词
11
11
  * (dsh-serenity-hooks/container_trajectory rebuild/mech-registry),打回会瘫痪自身工作。
12
+ *
13
+ * 🔴 **2026-10-15 补注(面 E 退役)**:`acp-` 前缀分支**已成孤儿,但本批不动**。
14
+ * 判据(两条,实测):① **该前缀从来没有生产者** —— 历史 `acp-core.ts` 建会话走的是
15
+ * `createSkiffAgent`,其 id = `` `skiff-${role}-${uuid}` ``(`skiff-core.ts:269`)⇒ `acp-` **从不出现**;
16
+ * ② 面 E 退役后连"本可能产生它的模块"也不在了。⇒ 该分支是**恒 false 的死判据**。
17
+ * ⚠️ **仍不擅自删**:这是**运行时字符串比较**,删它属**行为变更**(不是纯清理),
18
+ * 依本轨既有先例(`cheap-worker-` 四处置孤儿,同族、同判据)⇒ **登记待裁**(见 S142 §当前状态「观察」)。
12
19
  */
13
20
  import type { Context } from 'cordis';
14
21
  import type { Agent } from '@deepseek-ai/dsh-agent';
package/lib/ports.d.ts CHANGED
@@ -20,8 +20,8 @@
20
20
  * 本模块是**零依赖叶模块**(纯常量,无 import)——output-guard(守卫词表)、config-ops
21
21
  * (默认值)、settings-section(面板默认)、index(Config 默认)都可安全引用而不引入依赖环。
22
22
  */
23
- /** 面标识(五个对外面;A 由宿主监听,B/C/D/E 由本插件监听) */
24
- export type FaceId = 'main' | 'gateway' | 'weixinSend' | 'skiffDebug' | 'acpHttp';
23
+ /** 面标识(四个对外面;A 由宿主监听,B/C/D 由本插件监听) */
24
+ export type FaceId = 'main' | 'gateway' | 'weixinSend' | 'skiffDebug';
25
25
  /** 一个面的端口语义 */
26
26
  export interface PortSpec {
27
27
  /** 端口号 */
@@ -36,7 +36,7 @@ export interface PortSpec {
36
36
  /**
37
37
  * 集中端口表。
38
38
  * A=宿主主面(插件不监听)/ B=网关(可配,默认关)/ C=微信发送(默认开,仅 loopback)
39
- * / D=Skiff 调试(默认关)/ E=ACP+问答(默认关)。
39
+ * / D=Skiff 调试(默认关)。
40
40
  */
41
41
  export declare const FACE_PORTS: Readonly<Record<FaceId, PortSpec>>;
42
42
  /** 宿主主 WebUI 端口(面 A:插件**不监听**,只读取;`readWebPort` 的回退值) */
@@ -47,13 +47,13 @@ export declare const GATEWAY_PORT: number;
47
47
  export declare const WEIXIN_SEND_PORT: number;
48
48
  /** Skiff 调试页端口默认值(面 D) */
49
49
  export declare const SKIFF_DEBUG_PORT: number;
50
- /** ACP / 对外问答端口默认值(面 E) */
51
- export declare const ACP_HTTP_PORT: number;
52
50
  /**
53
51
  * **机制端口**词表(output-guard 用:agent 在**用户可见输出**里提及内部端口即打回)。
54
52
  *
55
53
  * 由 {@link FACE_PORTS} 机械派生 ⇒ 与面清单**永不漂移**。
56
54
  * ⚠️ 修复记录(C4 块 B,2026-09-15):旧常量硬写 `['3080','3081','3099','3100']`
57
- * ——**漏 3082**(微信发送面,默认开)⇒ 守卫拦不住"3082"这类提及。现由表派生,五面齐全。
55
+ * ——**漏 3082**(微信发送面,默认开)⇒ 守卫拦不住"3082"这类提及。现由表派生,四面齐全。
56
+ * ⚠️ 面变更记录(2026-10-15):**面 E(3100 ACP/问答)已整体退役**(owner 裁「砍掉外部问答」)
57
+ * ⇒ 本词表随之少一项,**无需另改**(这正是"派生而非手抄"的收益)。
58
58
  */
59
59
  export declare const MECHANISM_PORTS: readonly string[];
@@ -15,7 +15,7 @@ import type { UserMessage } from '@deepseek-ai/dsh-session';
15
15
  export declare function accIdentityText(root: string, configPaths?: string[], entrySkillMaxChars?: number): string;
16
16
  /**
17
17
  * ACC 注入消息(S134 去重):**只含简短身份锚点**([ACC] 已激活 + CCC 根 + 约束 + Phase 2)。
18
- * ⚠️ 原文案含「+ handyman 模型」,该注入已于 2026-09-16 删除(§0e-G)⇒ 此处同步订正(散文级残留)。
18
+ * ⚠️ 原文案含「+ cheap-worker 模型」,该注入已于 2026-09-16 删除(§0e-G)⇒ 此处同步订正(散文级残留)。
19
19
  * 完整身份(ACC 5 块 + CCE + Constraints + EAP + SKILL 全文 + Session 块)由**系统提示词层**
20
20
  * (systemPrompt.section,每轮 prompt 装配自动注入,含 subagent)承担——对话消息流/压缩重注入
21
21
  * 不再重复注入同一内容(token 双倍浪费,见 S134 注入方案梳理)。
@@ -26,7 +26,7 @@ export declare function accMessage(root: string, configPaths: string[], entrySki
26
26
  * 只有"conversation 根会话"才自动恢复最近激活的宁静号会话——
27
27
  * - subagent:session header `origin === 'subagent'`(DSH 路由语义,agent-lookup.ts)
28
28
  * - 派生会话:`parentSession` 存在(任何子会话)
29
- * - handyman 杂工:sessionId 固定 `handyman-` 前缀(tools/handyman.ts 生成)
29
+ * - cheap-worker 杂工:sessionId 固定 `cheap-worker-` 前缀(tools/cheap-worker.ts 生成)
30
30
  * 三者都不恢复(避免把主会话激活注入子上下文,违背 v1.16.2 scope 隔离)。
31
31
  */
32
32
  export declare function shouldAutoRestore(agent: Agent): boolean;
@@ -10,9 +10,9 @@
10
10
  * `core/session/src/index.ts:62`),长跑进程里这些 Map 只增不减——且 `waitIdle`
11
11
  * 在 agent 先被销毁时永不结算。
12
12
  *
13
- * ② **插件卸载/HMR/profile 重载 → 停掉自起的监听器与轮询器**。skiff 调试页、ACP
14
- * HTTP 端点、微信桥轮询都是 dsp 自己起的资源;此前没有 `ctx.effect` 拆卸,
15
- * 卸载后端口仍被占用(EADDRINUSE)、轮询器重复启动。
13
+ * ② **插件卸载/HMR/profile 重载 → 停掉自起的监听器与轮询器**。skiff 调试页、微信桥轮询
14
+ * 都是 dsp 自己起的资源(⚠️ 2026-10-15:原同批还有 ACP HTTP 端点,该面已退役);
15
+ * 此前没有 `ctx.effect` 拆卸,卸载后端口仍被占用(EADDRINUSE)、轮询器重复启动。
16
16
  *
17
17
  * 设计约束:清理与拆卸**一律吞掉异常**——生命周期回调里抛错会影响宿主的销毁流程
18
18
  * (宿主对 `session/disposed` 监听器异常是"contained"语义,但没必要制造噪音)。
@@ -1,10 +1,47 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { o as hostSettings } from "./access-CNccNtgf.js";
1
+ import { f as hostSettings } from "./ccc-roots-GIJ3A_tw.js";
2
+ import { dirname, join } from "node:path";
3
+ import { readFileSync } from "node:fs";
4
+ import { fileURLToPath } from "node:url";
5
+ //#region src/constants.ts
6
+ /** 常量(纯模块,零 DSH 依赖) */
7
+ /**
8
+ * ACC 版本:自动从 package.json 读取(单一真相源,消除与 CHANGELOG 的漂移)。
9
+ * 发布时只需改 package.json 的 version。
10
+ */
11
+ const ACC_VERSION = (() => {
12
+ try {
13
+ const here = dirname(fileURLToPath(import.meta.url));
14
+ return JSON.parse(readFileSync(join(here, "..", "package.json"), "utf-8")).version ?? "0.0.0";
15
+ } catch {
16
+ return "0.0.0";
17
+ }
18
+ })();
19
+ //#endregion
20
+ //#region src/skiff-registry.ts
21
+ const skiffSessions = /* @__PURE__ */ new Map();
22
+ /** 查 sessionId 的 Skiff 角色名(无 → null)——向后兼容(guards/seams 依赖) */
23
+ function skiffRoleFor(sessionId) {
24
+ return skiffSessions.get(sessionId)?.role ?? null;
25
+ }
26
+ /** 查 sessionId 的完整绑定(role + ccc;无 → null)——v1.25.10 会话追问校验 */
27
+ function skiffSessionInfo(sessionId) {
28
+ return skiffSessions.get(sessionId) ?? null;
29
+ }
30
+ function registerSkiffSession(sessionId, role, ccc) {
31
+ skiffSessions.set(sessionId, {
32
+ role,
33
+ ccc
34
+ });
35
+ }
36
+ function unregisterSkiffSession(sessionId) {
37
+ skiffSessions.delete(sessionId);
38
+ }
39
+ //#endregion
3
40
  //#region src/ports.ts
4
41
  /**
5
42
  * 集中端口表。
6
43
  * A=宿主主面(插件不监听)/ B=网关(可配,默认关)/ C=微信发送(默认开,仅 loopback)
7
- * / D=Skiff 调试(默认关)/ E=ACP+问答(默认关)。
44
+ * / D=Skiff 调试(默认关)。
8
45
  */
9
46
  const FACE_PORTS = {
10
47
  main: {
@@ -30,12 +67,6 @@ const FACE_PORTS = {
30
67
  host: "127.0.0.1",
31
68
  defaultEnabled: false,
32
69
  meaning: "Skiff 调试问答面(人工调试子角色;无认证,仅靠 loopback)"
33
- },
34
- acpHttp: {
35
- port: 3100,
36
- host: "127.0.0.1",
37
- defaultEnabled: false,
38
- meaning: "ACP JSON-RPC + 对外问答面(外部程序 + key 认证的问答页共用一 listener)"
39
70
  }
40
71
  };
41
72
  /** 宿主主 WebUI 端口(面 A:插件**不监听**,只读取;`readWebPort` 的回退值) */
@@ -46,28 +77,18 @@ const GATEWAY_PORT = FACE_PORTS.gateway.port;
46
77
  const WEIXIN_SEND_PORT = FACE_PORTS.weixinSend.port;
47
78
  /** Skiff 调试页端口默认值(面 D) */
48
79
  const SKIFF_DEBUG_PORT = FACE_PORTS.skiffDebug.port;
49
- /** ACP / 对外问答端口默认值(面 E) */
50
- const ACP_HTTP_PORT = FACE_PORTS.acpHttp.port;
51
80
  /**
52
81
  * **机制端口**词表(output-guard 用:agent 在**用户可见输出**里提及内部端口即打回)。
53
82
  *
54
83
  * 由 {@link FACE_PORTS} 机械派生 ⇒ 与面清单**永不漂移**。
55
84
  * ⚠️ 修复记录(C4 块 B,2026-09-15):旧常量硬写 `['3080','3081','3099','3100']`
56
- * ——**漏 3082**(微信发送面,默认开)⇒ 守卫拦不住"3082"这类提及。现由表派生,五面齐全。
85
+ * ——**漏 3082**(微信发送面,默认开)⇒ 守卫拦不住"3082"这类提及。现由表派生,四面齐全。
86
+ * ⚠️ 面变更记录(2026-10-15):**面 E(3100 ACP/问答)已整体退役**(owner 裁「砍掉外部问答」)
87
+ * ⇒ 本词表随之少一项,**无需另改**(这正是"派生而非手抄"的收益)。
57
88
  */
58
89
  const MECHANISM_PORTS = Object.keys(FACE_PORTS).map((id) => String(FACE_PORTS[id].port));
59
90
  //#endregion
60
91
  //#region src/settings-section.ts
61
- var settings_section_exports = /* @__PURE__ */ __exportAll({
62
- SERENITY_SETTINGS_NS: () => SERENITY_SETTINGS_NS,
63
- defaultHumanChannelSettings: () => defaultHumanChannelSettings,
64
- defaultSimpleSettings: () => defaultSimpleSettings,
65
- humanChannelSettingsFromConfig: () => humanChannelSettingsFromConfig,
66
- readSimpleSettings: () => readSimpleSettings,
67
- registerSettingsSection: () => registerSettingsSection,
68
- simpleSettingsFromConfig: () => simpleSettingsFromConfig,
69
- unwrapVolatile: () => unwrapVolatile
70
- });
71
92
  /**
72
93
  * 设置面板命名空间 = **profile 条目 id**(v0.1.7 起;与旧 `settings.yaml` 段名逐字相同)。
73
94
  */
@@ -79,9 +100,6 @@ function defaultSimpleSettings() {
79
100
  rebuildThresholdK: 400,
80
101
  skiffEnabled: false,
81
102
  skiffDebugPort: SKIFF_DEBUG_PORT,
82
- acpEnabled: false,
83
- acpHttpPort: ACP_HTTP_PORT,
84
- publicAskEnabled: false,
85
103
  croEnabled: true,
86
104
  unattendedEnabled: false,
87
105
  diagramEnabled: false,
@@ -98,7 +116,7 @@ function defaultSimpleSettings() {
98
116
  * `meta.volatile` **无条件**包 `createVolatile(value)`,且该分支排在"缺省值回退"那一段
99
117
  * **之前** ⇒ **"用户没设过"的字段也是恒真对象**(`.get()` 返回 `undefined`),**不是 `undefined`**。
100
118
  *
101
- * ⇒ 若这里不解包,下面十行的 `??` 链会**短路在这层包装上** ⇒ 网关 / Skiff / ACP 会被
119
+ * ⇒ 若这里不解包,下面十行的 `??` 链会**短路在这层包装上** ⇒ 网关 / Skiff 会被
102
120
  * **无意打开**(比"面板不显示"更坏:静默改变对外暴露面)。
103
121
  *
104
122
  * ## 为什么用结构判定
@@ -178,9 +196,6 @@ function simpleSettingsFromConfig(config) {
178
196
  rebuildThresholdK: unwrapVolatile(config.rebuildThresholdK) ?? config.rebuild?.thresholdK ?? d.rebuildThresholdK,
179
197
  skiffEnabled: unwrapVolatile(config.skiffEnabled) ?? config.skiff?.enabled ?? d.skiffEnabled,
180
198
  skiffDebugPort: unwrapVolatile(config.skiffDebugPort) ?? config.skiff?.debugPort ?? d.skiffDebugPort,
181
- acpEnabled: unwrapVolatile(config.acpEnabled) ?? config.acp?.enabled ?? d.acpEnabled,
182
- acpHttpPort: unwrapVolatile(config.acpHttpPort) ?? config.acp?.httpPort ?? d.acpHttpPort,
183
- publicAskEnabled: unwrapVolatile(config.publicAskEnabled) ?? d.publicAskEnabled,
184
199
  croEnabled: unwrapVolatile(config.croEnabled) ?? d.croEnabled,
185
200
  unattendedEnabled: unwrapVolatile(config.unattendedEnabled) ?? d.unattendedEnabled,
186
201
  diagramEnabled: unwrapVolatile(config.diagramEnabled) ?? config.diagram?.enabled ?? d.diagramEnabled,
@@ -222,4 +237,4 @@ function registerSettingsSection(ctx, config) {
222
237
  } catch {}
223
238
  }
224
239
  //#endregion
225
- export { ACP_HTTP_PORT as a, MAIN_WEB_PORT as c, WEIXIN_SEND_PORT as d, settings_section_exports as i, MECHANISM_PORTS as l, readSimpleSettings as n, FACE_PORTS as o, registerSettingsSection as r, GATEWAY_PORT as s, SERENITY_SETTINGS_NS as t, SKIFF_DEBUG_PORT as u };
240
+ export { GATEWAY_PORT as a, SKIFF_DEBUG_PORT as c, skiffRoleFor as d, skiffSessionInfo as f, FACE_PORTS as i, WEIXIN_SEND_PORT as l, ACC_VERSION as m, readSimpleSettings as n, MAIN_WEB_PORT as o, unregisterSkiffSession as p, registerSettingsSection as r, MECHANISM_PORTS as s, SERENITY_SETTINGS_NS as t, registerSkiffSession as u };
@@ -64,11 +64,7 @@ interface SimpleConfigFragment {
64
64
  enabled?: boolean;
65
65
  debugPort?: number;
66
66
  };
67
- /** F4c ACP(实验性):HTTP JSON-RPC 端点启停(人工) */
68
- acp?: {
69
- enabled?: boolean;
70
- httpPort?: number;
71
- };
67
+ /** F4 Skiff(实验性):调试服务启停(人工) */
72
68
  /** diagram(实验性 demo;2026-09-29 owner 具名令 D104):标签源码 → 进程内出图(不借浏览器) */
73
69
  diagram?: {
74
70
  enabled?: boolean;
@@ -79,9 +75,6 @@ interface SimpleConfigFragment {
79
75
  rebuildThresholdK?: PanelNumber;
80
76
  skiffEnabled?: PanelBoolean;
81
77
  skiffDebugPort?: PanelNumber;
82
- acpEnabled?: PanelBoolean;
83
- acpHttpPort?: PanelNumber;
84
- publicAskEnabled?: PanelBoolean;
85
78
  croEnabled?: PanelBoolean;
86
79
  unattendedEnabled?: PanelBoolean;
87
80
  diagramEnabled?: PanelBoolean;
@@ -102,12 +95,6 @@ interface SerenitySimpleSettings {
102
95
  skiffEnabled: boolean;
103
96
  /** F4 Skiff 调试端口(默认 3099,仅 127.0.0.1) */
104
97
  skiffDebugPort: number;
105
- /** F4c ACP HTTP JSON-RPC 端点总开关(实验性;默认关) */
106
- acpEnabled: boolean;
107
- /** F4c ACP HTTP 端口(默认 3100,仅 127.0.0.1) */
108
- acpHttpPort: number;
109
- /** F4d 建议问答页总开关(实验性;默认关——按认知容器暴露问答页,key 认证) */
110
- publicAskEnabled: boolean;
111
98
  /** **CRO(轨迹自编程唤起)总开关**(2026-09-21 所有者令新增;**缺省开**)。
112
99
  *
113
100
  * CRO = 轨迹目录下放一个 `continuous-re-occurrence.ts`,由 ACC 的 5min tick spawn,
@@ -132,7 +119,7 @@ interface SerenitySimpleSettings {
132
119
  * `parseDsl → renderDsl(SVG + 四项体检)→ resvg-wasm 光栅化(内置字体)→ PNG`,
133
120
  * 产物落 CCC `_tmp/diagram/` 且**图片块进对话**(**不借浏览器、不截图**)。
134
121
  * **缺省关**:owner 口中的"demo 功能" ⇒ 关时**不注册**(工具不进模型工具清单:
135
- * 零 token、不会被误调),同 `skiff`/`acp` 的"未开启零资源占用"口径。
122
+ * 零 token、不会被误调),同 `skiff` 的"未开启零资源占用"口径。
136
123
  * 依赖面:随包分发 3.8 MB 内置字体(`assets/diagram/`,wasm 对系统字体不可见)。 */
137
124
  diagramEnabled: boolean;
138
125
  /** **human-channel(人机信道)机器级配置**(2026-09-26 owner 定案;P0-1 立 schema + 投影)。
@@ -157,7 +144,7 @@ interface VolatileRef<T> {
157
144
  * `meta.volatile` **无条件**包 `createVolatile(value)`,且该分支排在"缺省值回退"那一段
158
145
  * **之前** ⇒ **"用户没设过"的字段也是恒真对象**(`.get()` 返回 `undefined`),**不是 `undefined`**。
159
146
  *
160
- * ⇒ 若这里不解包,下面十行的 `??` 链会**短路在这层包装上** ⇒ 网关 / Skiff / ACP 会被
147
+ * ⇒ 若这里不解包,下面十行的 `??` 链会**短路在这层包装上** ⇒ 网关 / Skiff 会被
161
148
  * **无意打开**(比"面板不显示"更坏:静默改变对外暴露面)。
162
149
  *
163
150
  * ## 为什么用结构判定
@@ -67,7 +67,7 @@ export declare function ensureWorkspacePromptSection(agent: Agent, scope: string
67
67
  *
68
68
  * 判定链:
69
69
  * ⓪ **临时身份不建工作台**(v1.30.9,S142 用户报"SESSION 爆炸"根治):`persistent=false`
70
- * (ACP/调试页/问答页等**无固定会话 id**的临时 agent)→ null。理由(R↓):这些 agent 每次
70
+ * (调试页等**无固定会话 id**的临时 agent)→ null。理由(R↓):这些 agent 每次
71
71
  * 调用都是新 id、无身份延续,为其建 SESSION = 每次问答留一个永久空目录(无界熵增);
72
72
  * 用户模型「skiff 本质是临时会话机制」——工作台属于**持久身份**,不属于单次调用。
73
73
  * ① 角色未启用 session 能力(trajectory.session !== true)→ null(现状零变化)
@@ -96,10 +96,10 @@ interface SkiffAgentRef {
96
96
  * 指定 sessionId 且磁盘已有持久化 log → `ctx.agents.resume`(DSH 持久化语义:
97
97
  * sessionId 即身份,已持久化会话必须 resume——历史 + turn 续号延续,同用户长期记忆保留);
98
98
  * 无 log(首次)/持久化未配置 → `ctx.agents.create`(新建)。不指定 sessionId →
99
- * 随机 id 恒 create(ACP/调试页默认路径)。
99
+ * 随机 id 恒 create(调试页默认路径)。
100
100
  *
101
101
  * @param sessionId 指定会话 id(可选;微信桥等外部面用固定 id 实现用户↔会话长期映射——
102
- * 不传则随机生成 skiff-<role>-<uuid>,ACP/调试页默认路径)
102
+ * 不传则随机生成 skiff-<role>-<uuid>,调试页默认路径)
103
103
  */
104
104
  export declare function createSkiffAgent(ctx: Context, root: string, roleName: string, role: SkiffRoleConfig, defaultModel?: string, sessionId?: string): Promise<SkiffAgentRef>;
105
105
  export interface SkiffTrajectoryEntry {
@@ -117,8 +117,9 @@ interface SkiffAskResult {
117
117
  * 提问一轮:followup → 等 idle → 读答案 + 轨迹。
118
118
  * @param eventsStart 轨迹起点:显式传 0 = 全量轨迹(会话追问时页面重绘完整时间线,
119
119
  * v1.25.10 用户拍板);不传(undefined)= 本轮增量(followup 前 events 之后)
120
- * @param options.includeTrajectory 是否计算轨迹(v1.26.10:**3100 对外只提供问答**——
121
- * 公开问答页 / ACP JSON-RPC 不返回 trajectory,传 false 跳过计算;3099 调试页默认 true 保留)
120
+ * @param options.includeTrajectory 是否计算轨迹(v1.26.10 起供**对外面**传 false 跳过计算——
121
+ * 原消费方 = 3100 公开问答页 / ACP JSON-RPC,**该面已于 2026-10-15 退役** ⇒ 现无生产调用方传 false;
122
+ * 3099 调试页默认 true 保留)
122
123
  */
123
124
  export declare function askSkiff(ctx: Context, agent: Agent, question: string, eventsStart?: number, options?: {
124
125
  includeTrajectory?: boolean;
@@ -11,8 +11,9 @@
11
11
  * 下拉列出全部候选(live 会话 cwd 上溯 .serenity 去重 + 默认绑定 root 兜底),
12
12
  * 切换后角色下拉联动(各 CCC 的 skiff.roles 实时读取),提问按所选 CCC 创建 agent。
13
13
  *
14
- * 与 ACP stdio 协议(F4c 后续)共用同一会话核心(createSkiffAgent + askSkiff),
15
- * 协议层后加不返工。轨迹 = session.events 结构化返回(与 dsh WebUI 同源数据),
14
+ * 与 skiff 会话核心(createSkiffAgent + askSkiff)直接共用同一实现;
15
+ * (原「与 ACP stdio 协议(F4c 后续)共用同一会话核心」一句已随面 E 退役删除,2026-10-15)
16
+ * 轨迹 = session.events 结构化返回(与 dsh WebUI 同源数据),
16
17
  * 页面 JS 渲染成对话时间线;同时保留原生 WebUI 会话链接供完整交互。
17
18
  *
18
19
  * 实验性质:未开启时零资源占用(无监听、无 agent 创建)。
@@ -42,8 +43,8 @@ export declare function skiffDebugPage(cccs: CccEntry[], defaultRoot: string, we
42
43
  * 在 JSON **文本层**把它们替换为 `\uXXXX` 转义序列:JSON.parse 后语义完全一致(还原原字符),
43
44
  * 且 JSC 正则看到的是常规 ASCII 转义(与 JSON.stringify 对控制字符的输出同形态,安全)。
44
45
  *
45
- * 3100 问答页客户端 `await res.json()`(acp-http.ts)与页面内嵌 JSON(skiff-debug/acp-http)
46
- * 均需此兼容层——iOS Safari 用户实测"复杂回答"触发。
46
+ * 3099 调试页客户端 `await res.json()` 与页面内嵌 JSON 均需此兼容层
47
+ * ——iOS Safari 用户实测"复杂回答"触发。(原同批还列了 3100 问答页,该面已退役,2026-10-15)
47
48
  *
48
49
  * @param jsonText JSON.stringify 的输出文本;原地等价替换,返回 JSC 安全文本
49
50
  */
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { _ as resolveInside, g as readUtf8, s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS } from "./ccc-DXky9UZu.js";
2
+ import { _ as resolveInside, g as readUtf8, s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS } from "./ccc-B0ZGL9lx.js";
3
3
  import { existsSync, statSync } from "node:fs";
4
4
  //#region src/skiff-role.ts
5
5
  /**
@@ -27,7 +27,7 @@ var skiff_role_exports = /* @__PURE__ */ __exportAll({
27
27
  });
28
28
  /** Skiff agent 会话 id 前缀(agents.create 生成;seams 旁路/白名单判定用) */
29
29
  const SKIFF_SESSION_PREFIX = "skiff-";
30
- /** 判定 sessionId 是否为 Skiff 会话(仿 handyman- 前缀排除模式) */
30
+ /** 判定 sessionId 是否为 Skiff 会话(仿 cheap-worker- 前缀排除模式) */
31
31
  function isSkiffSessionId(sessionId) {
32
32
  return typeof sessionId === "string" && sessionId.startsWith("skiff-");
33
33
  }
@@ -12,7 +12,7 @@ import { type SkiffRoleConfig } from './ccc.js';
12
12
  export type { SkiffRoleConfig };
13
13
  /** Skiff agent 会话 id 前缀(agents.create 生成;seams 旁路/白名单判定用) */
14
14
  export declare const SKIFF_SESSION_PREFIX = "skiff-";
15
- /** 判定 sessionId 是否为 Skiff 会话(仿 handyman- 前缀排除模式) */
15
+ /** 判定 sessionId 是否为 Skiff 会话(仿 cheap-worker- 前缀排除模式) */
16
16
  export declare function isSkiffSessionId(sessionId: string | undefined): boolean;
17
17
  /**
18
18
  * 读取 CCC 的 Skiff 角色配置(.opencode/serenity.json skiff.roles)。
@@ -47,7 +47,7 @@ export declare function systemPromptSource(role: SkiffRoleConfig | undefined): '
47
47
  * 角色类型(v1.30.15,S142 用户拍板):
48
48
  * - 显式 `role.kind` 优先(`temporary` / `persistent`)
49
49
  * - 缺省 = 隐式推断:调用方给出**稳定 sessionId** → persistent;否则 temporary
50
- * (存量配置零迁移;微信桥传固定会话 id → persistent,ACP/调试页随机 id → temporary)
50
+ * (存量配置零迁移;微信桥传固定会话 id → persistent,调试页随机 id → temporary)
51
51
  */
52
52
  type SkiffKind = 'temporary' | 'persistent';
53
53
  export declare function resolveSkiffKind(role: SkiffRoleConfig | undefined, hasStableId: boolean): SkiffKind;
package/lib/status.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * status.ts — 状态与安全模式操作(纯逻辑,零 DSH 依赖,可独立单测)
3
3
  *
4
- * WebUI 停靠栏的数据源:ACC 版本 / CCC 根 / safe-mode 状态 / 黑名单 / keeper 阈值 / handyman 模型。
4
+ * WebUI 停靠栏的数据源:ACC 版本 / CCC 根 / safe-mode 状态 / 黑名单 / keeper 阈值 / cheap-worker 模型。
5
5
  * setSafeMode 直接读写 .serenity-safe-on 标记(守卫实时读取,写即生效)。
6
6
  */
7
7
  /**
@@ -49,7 +49,7 @@ interface SerenityStatus {
49
49
  message?: string;
50
50
  }[];
51
51
  threshold: number | null;
52
- handymanModel: string | null;
52
+ cheapWorkerModel: string | null;
53
53
  restrict: {
54
54
  lastKey: string | null;
55
55
  lastAttemptAt: string | null;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * cheap-worker.ts — cheap-worker(杂工)真实 DSH 工具
3
+ *
4
+ * v1.24.0:loop(牛马)→ handyman(杂工);2026-10-14:handyman → cheap-worker。
5
+ * 🆕 2026-10-14(owner 令「删除后台运行能力」):**background 模式整条退场** ——
6
+ * 轮次循环 / stop-token 完成码 / 进度文件 / 重启计数 / maxRounds/maxParallel 全部删除。
7
+ * 现存只有**前台委派**一种形态:宿主起子 agent、等它跑完、取回最终文本。
8
+ *
9
+ * 机制:走宿主**委派正门** `ctx.subagents.start('spawn', …)`(深度上限、子 agent 所有权、
10
+ * `subagent/start|end` 事件、`dispose()` 收尾全部沿用宿主实现),模型经 `agentOptions` 注入。
11
+ * 前置:`exec.agent` 必须存在(前台委派要有发起方)。
12
+ *
13
+ * 🔴 **模型不可由调用方指定**(owner 令):**没有 `model` 参数**,一律读 CCC 配置
14
+ * `cheap-worker.models` / `cheap-worker.defaultModel`(单一真相源)。
15
+ *
16
+ * 递归防护:子 agent 的工具面 deny `cheap-worker` 本身(编排归主 agent,防无限嵌套)。
17
+ */
18
+ import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
19
+ import type { Context } from 'cordis';
20
+ /** 创建 cheap-worker 工具(闭包捕获插件 ctx → 可访问 ctx.subagents) */
21
+ export declare function createCheapWorkerTool(ctx: Context): ToolDefinition;
@@ -9,8 +9,8 @@
9
9
  */
10
10
  import type { JsonValue } from '../json.js';
11
11
  /** Skiff 定义教程(核心):概念 / schema / 认知 MSM 写法 / 双白名单 / 轨迹纪律 / 示例角色 */
12
- export declare const SKIFF_GUIDE = "\u2550\u2550\u2550 Skiff Definition Guide (F4, experimental) \u2550\u2550\u2550\n\nSkiff = \u5B81\u9759\u53F7\u653E\u51FA\u7684\u72EC\u7ACB\u5C0F\u8247\u2014\u2014\u5B8C\u6574 trajectory\uFF08\u5728\u5B81\u9759\u53F7\u5185\u5168\u77E5\u5168\u80FD\uFF09\u7684**\u4EFB\u610F\u5B50\u96C6\u89D2\u8272**\u3002\n\u7531\u672C CCC\uFF08.opencode/serenity.json skiff.roles\uFF09\u5B9A\u4E49\uFF1A\u80FD\u529B\u9762\uFF08\u53CC\u767D\u540D\u5355\uFF09+ \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6 + \u7CFB\u7EDF\u63D0\u793A\u8BCD\u3002\ndsp \u53EA\u63D0\u4F9B\u673A\u5236\uFF08\u53CC\u767D\u540D\u5355\u5F3A\u5236 + \u57FA\u7840\u63D0\u793A\u8BCD + \u8C03\u8BD5\u95EE\u7B54\u9875\uFF09\uFF1B\u89D2\u8272\u5185\u5BB9\u5B8C\u5168\u7531 CCC \u53D1\u6325\u3002\n\n\u2500\u2500 \u89D2\u8272\u914D\u7F6E schema \u2500\u2500\n { \"skiff\": { \"roles\": {\n \"<role-name>\": {\n \"model\": \"provider/model\", // \u89D2\u8272\u6A21\u578B\uFF08CCC \u76F4\u63A5\u6307\u5B9A\uFF0C\u65E0\u767D\u540D\u5355\u6821\u9A8C\uFF1B\u7F3A\u7701\u56DE\u9000 handyman.defaultModel\uFF09\n \"msms\": [\"msm-a\", \"msm-b\"], // MSM \u767D\u540D\u5355\uFF08\u72EC\u7ACB\uFF09\uFF1Amsm \u5DE5\u5177\u53EA\u80FD\u6267\u884C\u8FD9\u4E9B\uFF1Bregister/deregister \u5FC5\u62D2\n \"tools\": [\"read\",\"grep\",\"glob\",...], // \u975E MSM \u5DE5\u5177\u767D\u540D\u5355\uFF08\u72EC\u7ACB\uFF09\uFF1A\u767D\u540D\u5355\u5916\u5DE5\u5177\u4E00\u5F8B\u4E0D\u53EF\u7528\uFF08guard \u5F3A\u5236\uFF09\n \"trajectory\": { \"session\": false, \"keeper\": false, \"rebuild\": false }, // \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6\uFF08\u7F3A\u7701\u5168\u5173 = \u5B8C\u5168\u72EC\u7ACB\uFF09\n // \u89D2\u8272\u4EBA\u683C/\u8BA4\u77E5\u8FB9\u754C/\u98CE\u683C\uFF08CCC \u5B8C\u6574\u5B9A\u4E49\uFF1Bdsp \u53EA\u7ED9\u57FA\u7840\u63D0\u793A\u8BCD\uFF09\n \"systemPromptFile\": \".opencode/skiff/<role>.md\" // \u2605 \u63A8\u8350\uFF1A\u5F15\u7528 md \u6587\u4EF6\uFF08\u76F8\u5BF9 CCC \u6839\uFF1B\u8D85\u957F\u63D0\u793A\u8BCD\u5728 JSON \u5185\u5D4C\u4E0D\u53EF\u8BFB\uFF09\n // \"systemPrompt\": \"...\" // \u517C\u5BB9\uFF1A\u5185\u5D4C\u5B57\u7B26\u4E32\u4ECD\u53EF\u7528\uFF1B\u4E24\u8005\u90FD\u8BBE\u65F6 systemPromptFile \u4F18\u5148\n }\n } } }\n\n\u2500\u2500 \u53CC\u767D\u540D\u5355\u8BED\u4E49\uFF08\u5168\u6309\u767D\u540D\u5355\u66B4\u9732\uFF0C\u767D\u540D\u5355\u5916\u5168\u9690\u85CF\uFF09\u2500\u2500\n - tools \u7A7A + msms \u975E\u7A7A = \u7EAF MSM \u89D2\u8272\uFF08\u8BA4\u77E5\u95EE\u7B54\u5178\u578B\u5F62\u6001\uFF09\n - msms \u975E\u7A7A \u2192 msm \u5DE5\u5177\u81EA\u52A8\u53EF\u7528\uFF08MSM \u901A\u9053\uFF09\n - \u767D\u540D\u5355\u5916\u5DE5\u5177\u5373\u4F7F DSH \u672A\u6765\u65B0\u589E\u4E5F\u81EA\u52A8\u88AB\u6321\uFF08guard \u6309\u89D2\u8272\u5224\u5B9A\uFF0C\u4E0D\u679A\u4E3E\u5DE5\u5177\u540D\u2014\u2014\u5B8C\u5907\u6027\uFF09\n\n\u2500\u2500 \u8BA4\u77E5 MSM \u5199\u6CD5\uFF08\u8BFB\u77E5\u8BC6 / \u64CD\u4F5C\u80FD\u529B\uFF09\u2500\u2500\n - \u8BFB\u77E5\u8BC6\uFF1A\u811A\u672C\u8BFB CCC \u5185\u6587\u4EF6\uFF08SERENITY_ROOT env \u6CE8\u5165\uFF09\u2192 \u8F93\u51FA\u7B54\u6848/\u6458\u8981\uFF08\u5982 cognitive-qa\uFF09\n - \u64CD\u4F5C\u80FD\u529B\uFF1A\u811A\u672C\u8C03\u7528\u65E2\u6709\u5BB6\u5EAD\u5DE5\u5177/\u670D\u52A1\uFF08SSH/API/\u6587\u4EF6\u64CD\u4F5C\uFF09\u2014\u2014\u89D2\u8272\u80FD\u529B\u4E0A\u9650 = \u767D\u540D\u5355 MSM \u7684\u5B9E\u9645\u884C\u4E3A\n - \u4F8B\uFF1Acognitive-qa\uFF08\u8BFB docs/references \u56DE\u7B54\uFF09\u3001review-scan\uFF08\u8BFB\u4EE3\u7801\u51FA\u5BA1\u67E5\u610F\u89C1\uFF09\u3001review-fix\uFF08\u5199\u4FEE\u590D\uFF09\n - \u6CE8\u610F\uFF1AMSM \u5728\u811A\u672C\u5C42\u6267\u884C\uFF08bun\uFF09\uFF0C\u6587\u4EF6\u8BBF\u95EE\u4E0D\u53D7 agent \u5DE5\u5177\u9762\u7EA6\u675F\u2014\u2014\"\u53EA\u8BFB\"\u8BED\u4E49\u9760 CCC \u81EA\u5199 MSM \u81EA\u89C9\n\n\u2500\u2500 \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6\uFF08trajectory\uFF09\u2500\u2500\n - session/keeper/rebuild \u9ED8\u8BA4 false\uFF1ASkiff \u5B8C\u5168\u72EC\u7ACB\uFF08\u4E0D\u5EFA SESSION.md\u3001\u65E0 keeper \u63D0\u9192\u3001\u65E0 rebuild \u538B\u529B\u68C0\u6D4B\uFF09\n - \u5F00\u542F\u67D0\u9879 = \u8BE5\u89D2\u8272\u53C2\u4E0E\u5BF9\u5E94\u8F68\u8FF9\u673A\u5236\uFF08\u5982 keeper=true \u8BA1\u5206\u63D0\u9192\u6309\u89D2\u8272\u751F\u6548\uFF09\n\n\u2500\u2500 \u793A\u4F8B\u89D2\u8272 \u2500\u2500\n qa-readonly: { \"msms\": [\"cognitive-qa\"], \"tools\": [], \"trajectory\": {} }\n \u2192 \u8BA4\u77E5\u95EE\u7B54\uFF08\u4EC5 MSM \u901A\u9053\uFF0C\u65E0\u76F4\u63A5\u5DE5\u5177\uFF0C\u5B8C\u5168\u72EC\u7ACB\uFF09\n code-review: { \"msms\": [\"review-scan\",\"review-fix\"], \"tools\": [\"read\",\"grep\",\"glob\",\"write\",\"edit\"], \"trajectory\": { \"keeper\": true } }\n \u2192 \u6709\u64CD\u4F5C\u80FD\u529B\uFF08\u53EF\u5199\u4FEE\u590D\uFF09\uFF0C\u53C2\u4E0E keeper \u8F68\u8FF9\u673A\u5236\n\n\u2500\u2500 \u8FD0\u884C \u2500\u2500\n \u8C03\u8BD5\uFF1A\u8BBE\u7F6E\u9762\u677F\u300CSerenity\u300D\u9875 Skiff \u533A\u5757\u5F00\u542F \u2192 http://127.0.0.1:<debugPort> \u95EE\u7B54\u9875\u5B9E\u6D4B\n ACP \u7A0B\u5E8F\u5316\u9762\uFF08v1.26.0\uFF09\uFF1A\u8BBE\u7F6E\u9762\u677F\u300CACP\u300D\u533A\u5757\u5F00\u542F \u2192 HTTP JSON-RPC \u7AEF\u70B9\uFF08\u9ED8\u8BA4 3100\uFF09\u2014\u2014\n POST / {jsonrpc, id, method, params}\n session/new {ccc, role, sessionId?} \u2192 \u521B\u5EFA/\u5EF6\u7EED\u4F1A\u8BDD\uFF08sessionId \u53EF\u9009=\u8FDB\u7A0B\u5185\u8FFD\u95EE\uFF09\n session/prompt {sessionId, question} \u2192 {answer, trajectory}\n session/cancel / session/close / session/list / request_permission\uFF08\u6052 allow\uFF09\n \u542F\u505C = \u4EBA\u5DE5\uFF08\u8BBE\u7F6E\u9762\u677F\u5F00\u5173\uFF0C\u4E0D\u968F\u63D2\u4EF6\u52A0\u8F7D\u81EA\u52A8\u542F\u52A8\uFF09\uFF1B\u672A\u5F00\u542F\u96F6\u8D44\u6E90\u5360\u7528\n \u751F\u6548\u673A\u5236\uFF1A\u89D2\u8272\u914D\u7F6E**\u5B9E\u65F6\u8BFB\u53D6**\uFF08\u6539 .opencode/serenity.json \u2192 \u5237\u65B0\u8C03\u8BD5\u9875\u5373\u751F\u6548\uFF09\uFF1B\n \u6539\u914D\u7F6E\u540E\u7528 container_admin role apply \u505A\u663E\u5F0F\u6821\u9A8C + \u5E94\u7528\u786E\u8BA4\uFF08\u7ED1\u5B9A CCC + \u89D2\u8272\u6E05\u5355\uFF09\n \u4F1A\u8BDD\u8FFD\u95EE\uFF08v1.25.10\uFF09\uFF1A\u8C03\u8BD5\u9875\u6301\u6709\u5F53\u524D\u4F1A\u8BDD\uFF0C\u8FFD\u95EE\u81EA\u52A8\u7EED\u63A5\uFF08\u540C\u4F1A\u8BDD\u4E0A\u4E0B\u6587\u5EF6\u7EED\uFF09\uFF1B\n \u300C\u65B0\u5BF9\u8BDD\u300D\u6309\u94AE\u5F00\u65B0\u4F1A\u8BDD\uFF1B\u8FDB\u7A0B\u91CD\u542F\u540E\u65E7\u4F1A\u8BDD\u4E0D\u53EF\u7EED\uFF08WebUI \u4ECD\u53EF\u89C1\u5386\u53F2\uFF09\n \u6CE8\u610F\uFF1Askill \u52A0\u8F7D\u5BF9 skiff **\u6052\u53EF\u7528**\uFF08\u4E0D\u8BBE\u767D\u540D\u5355\u2014\u2014\u8BFB\u77E5\u8BC6\u9762\uFF0C\u65E0\u5199\u80FD\u529B\uFF09";
13
- /** 校验当前 CCC 的 skiff 配置:roles schema 合法 / msms 均已注册 / model ∈ handyman.models / systemPrompt 非空 */
12
+ export declare const SKIFF_GUIDE = "\u2550\u2550\u2550 Skiff Definition Guide (F4, experimental) \u2550\u2550\u2550\n\nSkiff = \u5B81\u9759\u53F7\u653E\u51FA\u7684\u72EC\u7ACB\u5C0F\u8247\u2014\u2014\u5B8C\u6574 trajectory\uFF08\u5728\u5B81\u9759\u53F7\u5185\u5168\u77E5\u5168\u80FD\uFF09\u7684**\u4EFB\u610F\u5B50\u96C6\u89D2\u8272**\u3002\n\u7531\u672C CCC\uFF08.opencode/serenity.json skiff.roles\uFF09\u5B9A\u4E49\uFF1A\u80FD\u529B\u9762\uFF08\u53CC\u767D\u540D\u5355\uFF09+ \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6 + \u7CFB\u7EDF\u63D0\u793A\u8BCD\u3002\ndsp \u53EA\u63D0\u4F9B\u673A\u5236\uFF08\u53CC\u767D\u540D\u5355\u5F3A\u5236 + \u57FA\u7840\u63D0\u793A\u8BCD + \u8C03\u8BD5\u95EE\u7B54\u9875\uFF09\uFF1B\u89D2\u8272\u5185\u5BB9\u5B8C\u5168\u7531 CCC \u53D1\u6325\u3002\n\n\u2500\u2500 \u89D2\u8272\u914D\u7F6E schema \u2500\u2500\n { \"skiff\": { \"roles\": {\n \"<role-name>\": {\n \"model\": \"provider/model\", // \u89D2\u8272\u6A21\u578B\uFF08CCC \u76F4\u63A5\u6307\u5B9A\uFF0C\u65E0\u767D\u540D\u5355\u6821\u9A8C\uFF1B\u7F3A\u7701\u56DE\u9000 cheap-worker.defaultModel\uFF09\n \"msms\": [\"msm-a\", \"msm-b\"], // MSM \u767D\u540D\u5355\uFF08\u72EC\u7ACB\uFF09\uFF1Amsm \u5DE5\u5177\u53EA\u80FD\u6267\u884C\u8FD9\u4E9B\uFF1Bregister/deregister \u5FC5\u62D2\n \"tools\": [\"read\",\"grep\",\"glob\",...], // \u975E MSM \u5DE5\u5177\u767D\u540D\u5355\uFF08\u72EC\u7ACB\uFF09\uFF1A\u767D\u540D\u5355\u5916\u5DE5\u5177\u4E00\u5F8B\u4E0D\u53EF\u7528\uFF08guard \u5F3A\u5236\uFF09\n \"trajectory\": { \"session\": false, \"keeper\": false, \"rebuild\": false }, // \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6\uFF08\u7F3A\u7701\u5168\u5173 = \u5B8C\u5168\u72EC\u7ACB\uFF09\n // \u89D2\u8272\u4EBA\u683C/\u8BA4\u77E5\u8FB9\u754C/\u98CE\u683C\uFF08CCC \u5B8C\u6574\u5B9A\u4E49\uFF1Bdsp \u53EA\u7ED9\u57FA\u7840\u63D0\u793A\u8BCD\uFF09\n \"systemPromptFile\": \".opencode/skiff/<role>.md\" // \u2605 \u63A8\u8350\uFF1A\u5F15\u7528 md \u6587\u4EF6\uFF08\u76F8\u5BF9 CCC \u6839\uFF1B\u8D85\u957F\u63D0\u793A\u8BCD\u5728 JSON \u5185\u5D4C\u4E0D\u53EF\u8BFB\uFF09\n // \"systemPrompt\": \"...\" // \u517C\u5BB9\uFF1A\u5185\u5D4C\u5B57\u7B26\u4E32\u4ECD\u53EF\u7528\uFF1B\u4E24\u8005\u90FD\u8BBE\u65F6 systemPromptFile \u4F18\u5148\n }\n } } }\n\n\u2500\u2500 \u53CC\u767D\u540D\u5355\u8BED\u4E49\uFF08\u5168\u6309\u767D\u540D\u5355\u66B4\u9732\uFF0C\u767D\u540D\u5355\u5916\u5168\u9690\u85CF\uFF09\u2500\u2500\n - tools \u7A7A + msms \u975E\u7A7A = \u7EAF MSM \u89D2\u8272\uFF08\u8BA4\u77E5\u95EE\u7B54\u5178\u578B\u5F62\u6001\uFF09\n - msms \u975E\u7A7A \u2192 msm \u5DE5\u5177\u81EA\u52A8\u53EF\u7528\uFF08MSM \u901A\u9053\uFF09\n - \u767D\u540D\u5355\u5916\u5DE5\u5177\u5373\u4F7F DSH \u672A\u6765\u65B0\u589E\u4E5F\u81EA\u52A8\u88AB\u6321\uFF08guard \u6309\u89D2\u8272\u5224\u5B9A\uFF0C\u4E0D\u679A\u4E3E\u5DE5\u5177\u540D\u2014\u2014\u5B8C\u5907\u6027\uFF09\n\n\u2500\u2500 \u8BA4\u77E5 MSM \u5199\u6CD5\uFF08\u8BFB\u77E5\u8BC6 / \u64CD\u4F5C\u80FD\u529B\uFF09\u2500\u2500\n - \u8BFB\u77E5\u8BC6\uFF1A\u811A\u672C\u8BFB CCC \u5185\u6587\u4EF6\uFF08SERENITY_ROOT env \u6CE8\u5165\uFF09\u2192 \u8F93\u51FA\u7B54\u6848/\u6458\u8981\uFF08\u5982 cognitive-qa\uFF09\n - \u64CD\u4F5C\u80FD\u529B\uFF1A\u811A\u672C\u8C03\u7528\u65E2\u6709\u5BB6\u5EAD\u5DE5\u5177/\u670D\u52A1\uFF08SSH/API/\u6587\u4EF6\u64CD\u4F5C\uFF09\u2014\u2014\u89D2\u8272\u80FD\u529B\u4E0A\u9650 = \u767D\u540D\u5355 MSM \u7684\u5B9E\u9645\u884C\u4E3A\n - \u4F8B\uFF1Acognitive-qa\uFF08\u8BFB docs/references \u56DE\u7B54\uFF09\u3001review-scan\uFF08\u8BFB\u4EE3\u7801\u51FA\u5BA1\u67E5\u610F\u89C1\uFF09\u3001review-fix\uFF08\u5199\u4FEE\u590D\uFF09\n - \u6CE8\u610F\uFF1AMSM \u5728\u811A\u672C\u5C42\u6267\u884C\uFF08bun\uFF09\uFF0C\u6587\u4EF6\u8BBF\u95EE\u4E0D\u53D7 agent \u5DE5\u5177\u9762\u7EA6\u675F\u2014\u2014\"\u53EA\u8BFB\"\u8BED\u4E49\u9760 CCC \u81EA\u5199 MSM \u81EA\u89C9\n\n\u2500\u2500 \u8F68\u8FF9\u7EAA\u5F8B\u5B50\u96C6\uFF08trajectory\uFF09\u2500\u2500\n - session/keeper/rebuild \u9ED8\u8BA4 false\uFF1ASkiff \u5B8C\u5168\u72EC\u7ACB\uFF08\u4E0D\u5EFA SESSION.md\u3001\u65E0 keeper \u63D0\u9192\u3001\u65E0 rebuild \u538B\u529B\u68C0\u6D4B\uFF09\n - \u5F00\u542F\u67D0\u9879 = \u8BE5\u89D2\u8272\u53C2\u4E0E\u5BF9\u5E94\u8F68\u8FF9\u673A\u5236\uFF08\u5982 keeper=true \u8BA1\u5206\u63D0\u9192\u6309\u89D2\u8272\u751F\u6548\uFF09\n\n\u2500\u2500 \u793A\u4F8B\u89D2\u8272 \u2500\u2500\n qa-readonly: { \"msms\": [\"cognitive-qa\"], \"tools\": [], \"trajectory\": {} }\n \u2192 \u8BA4\u77E5\u95EE\u7B54\uFF08\u4EC5 MSM \u901A\u9053\uFF0C\u65E0\u76F4\u63A5\u5DE5\u5177\uFF0C\u5B8C\u5168\u72EC\u7ACB\uFF09\n code-review: { \"msms\": [\"review-scan\",\"review-fix\"], \"tools\": [\"read\",\"grep\",\"glob\",\"write\",\"edit\"], \"trajectory\": { \"keeper\": true } }\n \u2192 \u6709\u64CD\u4F5C\u80FD\u529B\uFF08\u53EF\u5199\u4FEE\u590D\uFF09\uFF0C\u53C2\u4E0E keeper \u8F68\u8FF9\u673A\u5236\n\n\u2500\u2500 \u8FD0\u884C \u2500\u2500\n \u8C03\u8BD5\uFF1A\u8BBE\u7F6E\u9762\u677F\u300CSerenity\u300D\u9875 Skiff \u533A\u5757\u5F00\u542F \u2192 http://127.0.0.1:<debugPort> \u95EE\u7B54\u9875\u5B9E\u6D4B\n \uD83D\uDD34 \u5916\u90E8\u7A0B\u5E8F\u5316\u63A5\u5165\uFF082026-10-15 \u8D77\u6539\u8D70\u5B98\u65B9\uFF09\uFF1A\u672C\u63D2\u4EF6\u81EA\u9020\u7684 ACP \u9762\uFF08HTTP JSON-RPC 3100 \uFF0F\n \u5EFA\u8BAE\u95EE\u7B54\u9875\uFF09**\u5DF2\u6574\u4F53\u9000\u5F79**\uFF08owner \u88C1\u300C\u780D\u6389\u5916\u90E8\u95EE\u7B54\u300D\uFF09\u3002\u73B0\u5728\u8981\u7A0B\u5E8F\u5316/\u8FDC\u7A0B\u63A5\u5165\uFF0C\u8D70\u5BBF\u4E3B\n \u81EA\u5E26\u7684\u5B98\u65B9 ACP server\uFF1Adsh --profile acp\uFF08\u7EAF stdio\u3001\u96F6\u8BA4\u8BC1\uFF09\uFF0B \u4EFB\u4E00 ACP \u5BA2\u6237\u7AEF\n \uFF08\u624B\u673A\u7AEF\u5982 Agmente / ACP UI\uFF09\u7ECF\u96A7\u9053\u63A5\u5165\u3002\u8BE6\u89C1 S142 \u7684\u63A5\u5165\u6307\u5357\u6587\u6863\u3002\n \u542F\u505C = \u4EBA\u5DE5\uFF08\u8BBE\u7F6E\u9762\u677F\u5F00\u5173\uFF0C\u4E0D\u968F\u63D2\u4EF6\u52A0\u8F7D\u81EA\u52A8\u542F\u52A8\uFF09\uFF1B\u672A\u5F00\u542F\u96F6\u8D44\u6E90\u5360\u7528\n \u751F\u6548\u673A\u5236\uFF1A\u89D2\u8272\u914D\u7F6E**\u5B9E\u65F6\u8BFB\u53D6**\uFF08\u6539 .opencode/serenity.json \u2192 \u5237\u65B0\u8C03\u8BD5\u9875\u5373\u751F\u6548\uFF09\uFF1B\n \u6539\u914D\u7F6E\u540E\u7528 container_admin role apply \u505A\u663E\u5F0F\u6821\u9A8C + \u5E94\u7528\u786E\u8BA4\uFF08\u7ED1\u5B9A CCC + \u89D2\u8272\u6E05\u5355\uFF09\n \u4F1A\u8BDD\u8FFD\u95EE\uFF08v1.25.10\uFF09\uFF1A\u8C03\u8BD5\u9875\u6301\u6709\u5F53\u524D\u4F1A\u8BDD\uFF0C\u8FFD\u95EE\u81EA\u52A8\u7EED\u63A5\uFF08\u540C\u4F1A\u8BDD\u4E0A\u4E0B\u6587\u5EF6\u7EED\uFF09\uFF1B\n \u300C\u65B0\u5BF9\u8BDD\u300D\u6309\u94AE\u5F00\u65B0\u4F1A\u8BDD\uFF1B\u8FDB\u7A0B\u91CD\u542F\u540E\u65E7\u4F1A\u8BDD\u4E0D\u53EF\u7EED\uFF08WebUI \u4ECD\u53EF\u89C1\u5386\u53F2\uFF09\n \u6CE8\u610F\uFF1Askill \u52A0\u8F7D\u5BF9 skiff **\u6052\u53EF\u7528**\uFF08\u4E0D\u8BBE\u767D\u540D\u5355\u2014\u2014\u8BFB\u77E5\u8BC6\u9762\uFF0C\u65E0\u5199\u80FD\u529B\uFF09";
13
+ /** 校验当前 CCC 的 skiff 配置:roles schema 合法 / msms 均已注册 / model ∈ cheap-worker.models / systemPrompt 非空 */
14
14
  export declare function validateSkiffConfig(root: string): JsonValue;
15
15
  /** 列出当前 CCC 已定义角色(名 / 模型 / msms / tools / 轨迹纪律摘要) */
16
16
  export declare function listSkiffRoles(root: string): JsonValue;
@@ -45,7 +45,7 @@
45
45
  * 注入文本**自带**"请回复 ABCD" ⇒ 模型**复述指令**即**假完成**(高概率,不是小概率)
46
46
  * ⇒ 用**每轮新生成**的 nonce + **包装 + 独占一行**(`[[UNATTENDED-DONE:<hex>]]`),
47
47
  * 明写「**旧码作废**」,校验**只认当前轮**(防上下文里的旧码复活)。
48
- * 先例 = `handyman` background 的 `SERENITY_HANDYMAN_DONE_<16hex>`(同族实现)。
48
+ * 先例 = `cheap-worker` background 的 `SERENITY_CHEAP_WORKER_DONE_<16hex>`(同族实现)。
49
49
  */
50
50
  /** 完成码包装前缀(**独占一行**才有意义;见文件头"禁用 4 位字母码") */
51
51
  export declare const UNATTENDED_DONE_PREFIX = "[[UNATTENDED-DONE:";
@@ -55,7 +55,7 @@ export declare const UNATTENDED_DONE_SUFFIX = "]]";
55
55
  export declare const UNATTENDED_PROXY_MARK = "[[UNATTENDED-PROXY v1]]";
56
56
  /** 🔴 合成消息**固定身份句**(owner 已裁:「形如用户消息,但首句自报身份与权限边界」) */
57
57
  export declare const UNATTENDED_IDENTITY_LINE = "\u65E0\u4EBA\u503C\u5B88\u4EE3\u7406 \u00B7 \u975E\u672C\u4EBA";
58
- /** nonce 字节数 ⇒ 16 个 hex 字符(与 handyman 同量级;够长到不可能被复述猜中) */
58
+ /** nonce 字节数 ⇒ 16 个 hex 字符(与 cheap-worker 同量级;够长到不可能被复述猜中) */
59
59
  export declare const UNATTENDED_NONCE_BYTES = 8;
60
60
  /** 生成一枚新 nonce(**每轮一枚**;旧码作废由调用方在文本里声明) */
61
61
  export declare function newNonce(): string;
@@ -68,7 +68,7 @@ export declare function doneToken(nonce: string): string;
68
68
  export declare function parseDoneNonces(text: string): string[];
69
69
  /** 本轮收尾文本里是否出现过**当前轮**那枚码(唯一合法收束判据) */
70
70
  export declare function hasDoneToken(text: string, nonce: string): boolean;
71
- /** 单个会话在一个"代理段"内的**轮次上限**(设计建议 10–20;取 15——远小于 handyman 的 100) */
71
+ /** 单个会话在一个"代理段"内的**轮次上限**(设计建议 10–20;取 15——远小于 cheap-worker 的 100) */
72
72
  export declare const UNATTENDED_MAX_ROUNDS = 15;
73
73
  /** 一个"代理段"的**墙钟上限**(自第一次注入起算;跨轮累计,防"轮次没到但烧了一天") */
74
74
  export declare const UNATTENDED_MAX_WALL_MS: number;
@@ -98,7 +98,9 @@ export declare function claimsUserNotification(text: string): boolean;
98
98
  /**
99
99
  * **不许开**的会话(设计 §3 的"建议写死",本版**确实写死**):
100
100
  * `skiff-`(F4 问答 / **微信桥会话也是这个前缀** —— 桥那侧的"用户"是**家人**,
101
- * 代理替家人说话 = **冒充**)| `acp-`(对外程序化面)| `handyman-`(自主 worker,已有自己的完成码循环)。
101
+ * 代理替家人说话 = **冒充**)| `acp-`(对外程序化面 —— ⚠️ **2026-10-15 起已成死判据**:
102
+ * 该前缀从无生产者且面 E 已退役;理由与"为何保留"见 `output-guard-seam.ts` 文件头)|
103
+ * `cheap-worker-`(自主 worker,已有自己的完成码循环)。
102
104
  *
103
105
  * ⚠️ **`rebuild-` 不在排除面**(与 `output-guard-seam.ts` 的取向**刻意不同**):重建会话是
104
106
  * **同一轨迹的载体**(内部维护面),不是对外面;把它排除会让"重建后就没人推了"。
@@ -3,8 +3,15 @@
3
3
  *
4
4
  * **CCC 级**:dsh 一个进程含多个 CCC,每个 CCC 独立对接微信桥(S142 用户拍板)——
5
5
  * 扫描 live CCC → 每 CCC 读 weixin 配置(enabled + accounts + routes)→
6
- * 启动该 CCC 该账号的 iLink 轮询循环。消息 → weixin-route 路由 → AcpServer 直调
7
- * (session/new + session/prompt,同进程不经网络——acp-core 传输无关设计)。
6
+ * 启动该 CCC 该账号的 iLink 轮询循环。消息 → weixin-route 路由 → skiff 核心直调
7
+ * (session/new + session/prompt,同进程不经网络)。
8
+ *
9
+ * 🔴 **一处陈旧注释的更正(2026-10-15,随面 E 退役一并核实)**:本行原写「→ **AcpServer 直调**
10
+ * (…——acp-core 传输无关设计)」。**该描述从来不是事实** —— 实测 grep 全仓:本文件**从不**
11
+ * `import acp-core`(它 import 的是 `skiff-core` / `skiff-role` / `weixin-*`),
12
+ * 而 `acp-core` 的消费者**自始至终只有两个**(`acp-http.ts` + 其测试)。
13
+ * ⇒ 当年那句是**设计意图的误记**,不是依赖关系;面 E 退役后它更是彻底失效。
14
+ * 🔵 判据复述:**注释里的"设计意图"不能当依赖判据**,必须 grep import。
8
15
  *
9
16
  * 实验性质:未配置/未启用 → 完全不启动(零资源占用)。配置变化(面板写入)
10
17
  * → 热重建受影响 CCC 的桥(对齐 gateway 热重建模式)。
@@ -58,7 +58,7 @@ export declare function buildManualOutputRebuke(session: ManualOutputSession): s
58
58
  export declare function __resetWeixinOutputGuardForTest(): void;
59
59
  /**
60
60
  * 装配闸门(index.ts apply 调用)。
61
- * 只对**已登记的手动模式会话**生效——其他会话(主舱/其他 skiff/ACP 临时会话)零干预。
61
+ * 只对**已登记的手动模式会话**生效——其他会话(主舱/其他 skiff 会话)零干预。
62
62
  */
63
63
  export declare function registerWeixinOutputGuard(ctx: Context): void;
64
64
  export {};
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS } from "./ccc-DXky9UZu.js";
2
+ import { s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS } from "./ccc-B0ZGL9lx.js";
3
3
  import { join, resolve } from "node:path";
4
4
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
5
  import { createHash } from "node:crypto";
@@ -20,7 +20,7 @@ import { createHash } from "node:crypto";
20
20
  * 存储结构(JSON 顶层分节):
21
21
  * { "credentials": { "HOME_GITLAB_TOKEN": "xxx" }, "<config节>": { "<key>": "v" } }
22
22
  * credentials 为保留节(credential 命名空间,key 大写蛇形);其余节归 config 命名空间
23
- * (path = section.key,如 handyman.models)。
23
+ * (path = section.key,如 cheap-worker.models)。
24
24
  */
25
25
  const LOCALSTORE_SCOPES = ["credential", "config"];
26
26
  /** 存储文件名(CCC 根根目录) */
@@ -113,7 +113,7 @@ function assertCredentialKey(key) {
113
113
  /** 校验 config 路径(节.key);不合法抛错 */
114
114
  function assertConfigPath(path) {
115
115
  const idx = path.indexOf(".");
116
- if (idx <= 0 || idx === path.length - 1) throw new Error(`config path "${path}" must be section.key (e.g. handyman.models)`);
116
+ if (idx <= 0 || idx === path.length - 1) throw new Error(`config path "${path}" must be section.key (e.g. cheap-worker.models)`);
117
117
  const section = path.slice(0, idx);
118
118
  const key = path.slice(idx + 1);
119
119
  if (!CONFIG_SECTION_RE.test(section)) throw new Error(`config section "${section}" must match ^[a-z][a-z0-9-]*$`);
@@ -197,7 +197,7 @@ function docText(root) {
197
197
  " \"credentials\": {",
198
198
  " \"HOME_GITLAB_TOKEN\": \"xxx\"",
199
199
  " },",
200
- " \"handyman\": {",
200
+ " \"cheap-worker\": {",
201
201
  " \"models\": [\"minimax-cn-coding-plan/MiniMax-M3\"]",
202
202
  " }",
203
203
  "}",
@@ -206,7 +206,7 @@ function docText(root) {
206
206
  "",
207
207
  "## Key conventions",
208
208
  "- credential key: ^[A-Z][A-Z0-9_]*$ (e.g. HOME_GITLAB_TOKEN)",
209
- "- config path: section.key (section ^[a-z][a-z0-9-]*$, key lowerCamel ^[a-z][a-zA-Z0-9_]*$, e.g. handyman.models)",
209
+ "- config path: section.key (section ^[a-z][a-z0-9-]*$, key lowerCamel ^[a-z][a-zA-Z0-9_]*$, e.g. cheap-worker.models)",
210
210
  "",
211
211
  "## Reading (agents may use fs tools directly)",
212
212
  `- Read ${path} with the read tool → JSON.parse`,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.56.10",
4
- "description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:14 个工具(container_fs/container_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/handyman/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 工作日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/trajectory 唤醒注册表。适配 DSH 0.1.7-rc.1 与 0.2.0-rc.1(双档)。",
3
+ "version": "1.57.1",
4
+ "description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:14 个工具(container_fs/container_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/cheap-worker/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 工作日志与原地重建 + 网页登录入口/微信桥/子角色/对外问答页/trajectory 唤醒注册表。适配 DSH 0.1.7-rc.1 与 0.2.0-rc.1(双档)。",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",