@shgroup/dsh-serenity-hooks 1.70.0 → 1.72.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.
Files changed (105) hide show
  1. package/README.md +21 -19
  2. package/dsh.plugin.json +2 -2
  3. package/lib/{ccc-C33QWoWZ.js → ccc-Dkoa2oW3.js} +16 -2
  4. package/lib/{ccc-roots-RzasspMr.js → ccc-roots-jZYR2GVE.js} +16 -10
  5. package/lib/client.js +2 -2
  6. package/lib/{gateway-auth.d.ts → gateway/auth.d.ts} +3 -3
  7. package/lib/{gateway-dsh-auth.d.ts → gateway/dsh-auth.d.ts} +1 -1
  8. package/lib/{gateway-proxy.d.ts → gateway/proxy.d.ts} +3 -3
  9. package/lib/{gateway.d.ts → gateway/server.d.ts} +5 -5
  10. package/lib/{totp.d.ts → gateway/totp.d.ts} +1 -1
  11. package/lib/{output-guard.d.ts → guard/filter.d.ts} +2 -2
  12. package/lib/{output-guard-seam.d.ts → guard/seam.d.ts} +2 -2
  13. package/lib/{weixin-api-BrRcPiQs.js → ilink-DEpmE3yi.js} +6 -6
  14. package/lib/im/accounts.d.ts +105 -0
  15. package/lib/{weixin-bridge.d.ts → im/bridge.d.ts} +16 -9
  16. package/lib/{im-bridge.d.ts → im/channels.d.ts} +3 -3
  17. package/lib/{weixin-send-endpoint.d.ts → im/endpoint.d.ts} +2 -2
  18. package/lib/{weixin-output-guard.d.ts → im/guard.d.ts} +1 -1
  19. package/lib/{weixin-hook.d.ts → im/hook.d.ts} +1 -1
  20. package/lib/{weixin-api.d.ts → im/ilink.d.ts} +3 -3
  21. package/lib/{human-channel.d.ts → im/inbound.d.ts} +4 -4
  22. package/lib/{weixin-route.d.ts → im/route.d.ts} +52 -11
  23. package/lib/{weixin-send-api.d.ts → im/send.d.ts} +3 -3
  24. package/lib/im/weixin-account.d.ts +45 -0
  25. package/lib/{im-weixin.d.ts → im/weixin-channel.d.ts} +2 -2
  26. package/lib/index.js +1008 -815
  27. package/lib/invariant.js +2 -2
  28. package/lib/{ccc-roots.d.ts → kernel/ccc-roots.d.ts} +10 -10
  29. package/lib/{ccc.d.ts → kernel/ccc.d.ts} +114 -44
  30. package/lib/{config-ops.d.ts → kernel/config.d.ts} +2 -2
  31. package/lib/kernel/constants.d.ts +20 -0
  32. package/lib/{invariant.d.ts → kernel/invariant.d.ts} +1 -1
  33. package/lib/{json.d.ts → kernel/json.d.ts} +1 -1
  34. package/lib/{message-source.d.ts → kernel/message-source.d.ts} +1 -1
  35. package/lib/{ports.d.ts → kernel/ports.d.ts} +1 -1
  36. package/lib/{time.d.ts → kernel/time.d.ts} +1 -1
  37. package/lib/message-source-kVoNK0C5.js +432 -0
  38. package/lib/{deepseek-vision-patch.d.ts → patches/deepseek-vision.d.ts} +3 -3
  39. package/lib/{opencode-provider.d.ts → patches/opencode-provider.d.ts} +1 -1
  40. package/lib/{web-fetch-provider.d.ts → patches/web-fetch.d.ts} +1 -1
  41. package/lib/{message-source-DhA1dVBi.js → profile-DyMJ_bfr.js} +277 -463
  42. package/lib/role/skiff/config.d.ts +79 -0
  43. package/lib/role/skiff/core.d.ts +155 -0
  44. package/lib/{skiff-debug.d.ts → role/skiff/debug.d.ts} +4 -4
  45. package/lib/role/skiff/profile.d.ts +115 -0
  46. package/lib/role/skiff/registry.d.ts +41 -0
  47. package/lib/{cheap-worker-ops.d.ts → role/worker/core.d.ts} +1 -1
  48. package/lib/{agent-idle.d.ts → role/worker/idle.d.ts} +2 -2
  49. package/lib/{cheap-worker-preset-inherit.d.ts → role/worker/preset.d.ts} +2 -2
  50. package/lib/{weixin-route-D_DvgPqy.js → route-f7JlinIt.js} +132 -47
  51. package/lib/seams/context.d.ts +3 -3
  52. package/lib/seams/guards.d.ts +18 -12
  53. package/lib/seams/keeper.d.ts +1 -1
  54. package/lib/seams/system-prompt.d.ts +3 -1
  55. package/lib/settings-lt1i3OZv.js +403 -0
  56. package/lib/{skills-discovery.d.ts → skills/discovery.d.ts} +1 -1
  57. package/lib/skills/resource-index.d.ts +2 -2
  58. package/lib/{face-host.d.ts → surface/faces.d.ts} +4 -4
  59. package/lib/{api.d.ts → surface/http.d.ts} +2 -2
  60. package/lib/{container-status.d.ts → surface/observation.d.ts} +16 -16
  61. package/lib/{settings-section.d.ts → surface/settings.d.ts} +1 -1
  62. package/lib/{status.d.ts → surface/status.d.ts} +2 -2
  63. package/lib/{usage-stats.d.ts → surface/usage.d.ts} +4 -4
  64. package/lib/{voyage-page.d.ts → surface/voyage/page.d.ts} +2 -2
  65. package/lib/{voyage-vocab.d.ts → surface/voyage/vocab.d.ts} +1 -1
  66. package/lib/tools/cognitive-trajectory.d.ts +2 -2
  67. package/lib/tools/{acc-diag.d.ts → diag/index.d.ts} +2 -2
  68. package/lib/{diag-ops.d.ts → tools/diag/service.d.ts} +7 -7
  69. package/lib/tools/eap.d.ts +1 -1
  70. package/lib/tools/fs/index.d.ts +7 -0
  71. package/lib/{fs-ops.d.ts → tools/fs/service.d.ts} +2 -2
  72. package/lib/tools/git/index.d.ts +4 -0
  73. package/lib/{git-ops.d.ts → tools/git/service.d.ts} +2 -2
  74. package/lib/tools/im-bridge.d.ts +2 -2
  75. package/lib/tools/{kit.d.ts → kit/index.d.ts} +1 -1
  76. package/lib/{kit-ops.d.ts → tools/kit/service.d.ts} +6 -6
  77. package/lib/tools/{localstore.d.ts → localstore/index.d.ts} +1 -1
  78. package/lib/{localstore-ops.d.ts → tools/localstore/service.d.ts} +2 -2
  79. package/lib/tools/{msm.d.ts → msm/index.d.ts} +1 -1
  80. package/lib/{msm-ops.d.ts → tools/msm/service.d.ts} +2 -2
  81. package/lib/tools/skiff-admin.d.ts +19 -14
  82. package/lib/{cognitive-trajectory-assistant.d.ts → trajectory/assistant.d.ts} +2 -2
  83. package/lib/{cognitive-trajectory-bound.d.ts → trajectory/bound.d.ts} +2 -2
  84. package/lib/{session-cleanup.d.ts → trajectory/cleanup.d.ts} +1 -1
  85. package/lib/{cognitive-trajectory-ops.d.ts → trajectory/core.d.ts} +55 -25
  86. package/lib/{live-sessions.d.ts → trajectory/live.d.ts} +1 -1
  87. package/lib/trajectory/prompt.d.ts +101 -0
  88. package/lib/{rebuild.d.ts → trajectory/rebuild.d.ts} +1 -1
  89. package/lib/{cognitive-trajectory-skills.d.ts → trajectory/skills.d.ts} +1 -1
  90. package/lib/{clock-runtime.d.ts → wake/clock.d.ts} +3 -3
  91. package/lib/{cro-guide.d.ts → wake/cro-guide.d.ts} +1 -1
  92. package/lib/{cro-log.d.ts → wake/cro-log.d.ts} +3 -3
  93. package/lib/{cro-turns.d.ts → wake/cro-turns.d.ts} +5 -5
  94. package/lib/{cro.d.ts → wake/cro.d.ts} +6 -6
  95. package/lib/{wake-registry.d.ts → wake/registry.d.ts} +2 -2
  96. package/lib/{wake-scheduler.d.ts → wake/scheduler.d.ts} +3 -3
  97. package/package.json +2 -2
  98. package/lib/constants.d.ts +0 -6
  99. package/lib/settings-section-0TPYWug9.js +0 -238
  100. package/lib/skiff-core.d.ts +0 -145
  101. package/lib/skiff-registry.d.ts +0 -26
  102. package/lib/skiff-role-cwxAt0gE.js +0 -203
  103. package/lib/skiff-role.d.ts +0 -89
  104. package/lib/tools/cc-fs.d.ts +0 -7
  105. package/lib/tools/git.d.ts +0 -4
@@ -7,7 +7,7 @@
7
7
  * 动作面现行 **8 个**:list / show / create / use / rebuild / **`send-now`** / **`send-later`** / **`cro-guide`**。
8
8
  * 🔴 2026-09-16(所有者裁决):**第 7 个动作 `send-message`(即时投递)**
9
9
  * ——与 `wake-later` 共用取用通路,差别只在**时刻**(现在 vs 未来)与**回执**(有 vs 无);
10
- * 实现落在 `wake-scheduler.ts` 的 `sendToTrajectory()`("怎么把一句话送到一条轨迹"是调度器的知识)。
10
+ * 实现落在 `wake/scheduler.ts` 的 `sendToTrajectory()`("怎么把一句话送到一条轨迹"是调度器的知识)。
11
11
  * 设计稿 = `docs/cognitive-trajectory-send-message-design.md`(v0.2 定稿)。
12
12
  * 🔴 2026-09-17(所有者裁决 · **命名 A 案**):**两个投递动作更名** —— `wake-later` → **`send-later`**、
13
13
  * `send-message` → **`send-now`**。判据(R↓):两者本是**同一条投递通路**(同取用机制 / 同载荷 /
@@ -39,7 +39,7 @@
39
39
  */
40
40
  import { defineTool } from '@deepseek-ai/dsh-tools';
41
41
  import type { Context } from 'cordis';
42
- import { type ActiveSessionInfo, type CreateSessionResult } from '../cognitive-trajectory-ops.js';
42
+ import { type ActiveSessionInfo, type CreateSessionResult } from '../trajectory/core.js';
43
43
  interface RenameOnUseDeps {
44
44
  /** sessionTitle 服务可用性 */
45
45
  sessionTitleAvailable: boolean;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * acc-diag.ts(工具面)— ACC 负责人专用的运行态诊断(v1.33,S142 §32.11)
2
+ * tools/diag/index.ts(工具面)— ACC 负责人专用的运行态诊断(v1.33,S142 §32.11)
3
3
  *
4
4
  * 用户裁决(2026-09-14):「不要 diag-live 了;或者变成一个隐藏 tool **只对 home-serenity 可见**,
5
5
  * 做成我们专属的运行时诊断工具」。⇒ 合并原 `diag`(脚本侧条件链)+ `diag-live`(进程内运行态),
@@ -20,6 +20,6 @@ import type { Context } from 'cordis';
20
20
  * (① live 运行态 / ①b 唤醒时钟 / ③ 唤醒注册表)。
21
21
  *
22
22
  * ⚠️ 2026-09-15(ACC 侧 autopilot 退场,S142):原四段降为三段——原 ②「面板解析」与
23
- * ④「唤起条件链」的主语随机制消失,已删(见 `../diag-ops.ts` 文件头;④ 的缺口已登记)。
23
+ * ④「唤起条件链」的主语随机制消失,已删(见 `tools/diag/service.ts` 文件头;④ 的缺口已登记)。
24
24
  */
25
25
  export declare function createAccDiagTool(ctx: Context): import("@deepseek-ai/dsh-tools").ToolDefinition;
@@ -1,7 +1,7 @@
1
1
  /**
2
- * diag-ops.ts — `acc-diag` 报告装配(v1.33,S142 §32.11;2026-09-15 段数收缩)
2
+ * tools/diag/service.ts — `acc-diag` 报告装配(v1.33,S142 §32.11;2026-09-15 段数收缩)
3
3
  *
4
- * 为什么单独成模块(R↓):工具面(`tools/acc-diag.ts`)只做"取 CCC 根 + 渲染",
4
+ * 为什么单独成模块(R↓):工具面(`tools/diag/index.ts`)只做"取 CCC 根 + 渲染",
5
5
  * 装配逻辑放这里 ⇒ 纯函数可单测、不依赖 DSH 工具注册。
6
6
  *
7
7
  * 为什么**无动作参数**:诊断是低频动作(§32.9 收敛取向),一次调用即出全报告,
@@ -13,7 +13,7 @@
13
13
  * ①b 唤醒时钟 —— `containerClocks().wake`(唤醒调度器进程内快照:武装态/计数/上次跳过原因)
14
14
  * ③ 唤醒注册表 —— `wake-registry.json` 的**在办条目**(state / at / target / lastResult)+ 补跑窗口
15
15
  * (🔴 2026-09-19 §0Q 甲案:终态条目**结案即清除** ⇒ 本段只列在办项,不再是"历史全量";
16
- * 历史由 SESSION.md / 工具输出承担——该承诺原本就写在 `wake-registry.ts` 注释里,本次做实)
16
+ * 历史由 SESSION.md / 工具输出承担——该承诺原本就写在 `wake/registry.ts` 注释里,本次做实)
17
17
  *
18
18
  * ── 2026-09-15:段数由四降为三(S142「ACC 侧 autopilot 退场」§1 二阶裁定)─────────────
19
19
  * ACC 侧 autopilot 整段退场后,报告里两段的**主语消失**,故删除(不是"暂时关掉"):
@@ -29,13 +29,13 @@
29
29
  * 条目到期 / 补跑窗口 / 目标可解析 / CCC 闸)。**不得**以"顺手保留 ④"的方式把它偷偷带回。
30
30
  *
31
31
  * C5「观察面归一」(2026-09-15):① 走 `diagLive`(那是**live 运行态**的独有取数,没有第二个
32
- * 来源);①b 时钟与 ③ 注册表经 `container-status.ts` 取(唯一取数出口)——**投影仍在本文件**
32
+ * 来源);①b 时钟与 ③ 注册表经 `surface/observation.ts` 取(唯一取数出口)——**投影仍在本文件**
33
33
  * (诊断段不含 `message`,面板含;这是渲染差异,不是取数差异)。
34
34
  */
35
- import { type DiagLiveReport } from './live-sessions.js';
36
- import { type ClockSnapshot } from './container-status.js';
35
+ import { type DiagLiveReport } from '../../trajectory/live.js';
36
+ import { type ClockSnapshot } from '../../surface/observation.js';
37
37
  import type { Context } from 'cordis';
38
- /** 进程内时钟状态(唤醒调度器;判据单一真相源 = `wake-scheduler.ts`) */
38
+ /** 进程内时钟状态(唤醒调度器;判据单一真相源 = `wake/scheduler.ts`) */
39
39
  type ClockState = ClockSnapshot;
40
40
  interface AccDiagReport {
41
41
  /** 调用方会话所属 CCC 根(过程内诊断的目标) */
@@ -9,7 +9,7 @@
9
9
  * ⇒ 正文**不再内嵌**(58 KB 塞进 TS 模板字符串还要转义论文里 4 处 ```mermaid 围栏——
10
10
  * 本容器为此踩过四次),改为**随包的静态资产 + 运行时读取**:
11
11
  * 资产 = `assets/eap-paper.md`(**逐字**来自上游论文,未经改写)
12
- * 读取 = `loadEapPaper()`(进程内缓存一次;同 `voyage-page.ts` 的既有先例)
12
+ * 读取 = `loadEapPaper()`(进程内缓存一次;同 `surface/voyage/page.ts` 的既有先例)
13
13
  *
14
14
  * 🔴 **单一真相源**:正文只在 `assets/eap-paper.md` 一个地方。本文件负责**定位与读取**,
15
15
  * `praxis.ts` 只负责**路由**。二者都不得内嵌任何论文片段——否则又是"第二份会漂的正文"。
@@ -0,0 +1,7 @@
1
+ /**
2
+ * tools/fs/index.ts — container_fs 真实 DSH 工具定义(defineTool)(v1.30:cc_fs → container_fs)
3
+ *
4
+ * 进程内注册(取代 v0.1 的 bash spawn runner):zod/schemastery 参数校验、
5
+ * 规范 JSON 输出、纯 render 投影。逻辑在 tools/fs/service.ts(可单测)。
6
+ */
7
+ export declare const ccFsTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * fs-ops.ts — container_fs 纯操作层(cc_fs → container_fs,v1.30;零 DSH 依赖,可独立单测)
2
+ * tools/fs/service.ts — container_fs 纯操作层(cc_fs → container_fs,v1.30;零 DSH 依赖,可独立单测)
3
3
  *
4
4
  * 行为对齐 osp(opencode-serenity-plugin/src/fs/file-system-tool.ts)——osp 是 ACC 工具 spec:
5
5
  * - rm:目录需 recursive 才删除;非空目录无 recursive → [SKIP];保护 .serenity 与 CCC 根;dry-run 预览
@@ -9,7 +9,7 @@
9
9
  * - touch:存在更新 mtime、不存在创建(自动建父目录);append:自动建父目录 + 返回字节数
10
10
  * 保留 dsp 增强:win32 reveal 用 spawn+unref(explorer GUI 进程退出码不可靠,fire-and-forget)。
11
11
  */
12
- import type { JsonValue } from './json.js';
12
+ import type { JsonValue } from '../../kernel/json.js';
13
13
  type CcFsAction = 'root' | 'resolve' | 'exists' | 'list' | 'tree' | 'relative' | 'mkdir' | 'rm' | 'mv' | 'cp' | 'touch' | 'append' | 'reveal' | 'info' | 'find';
14
14
  export declare const CC_FS_ACTIONS: readonly CcFsAction[];
15
15
  export interface CcFsArgs {
@@ -0,0 +1,4 @@
1
+ /**
2
+ * tools/git/index.ts — container_git 真实 DSH 工具定义(defineTool)(v1.30:cc_git → container_git)
3
+ */
4
+ export declare const gitTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * git-ops.ts — container_git 纯操作层(cc_git → container_git,v1.30;零 DSH 依赖)
2
+ * tools/git/service.ts — container_git 纯操作层(cc_git → container_git,v1.30;零 DSH 依赖)
3
3
  *
4
4
  * 行为对齐 osp(opencode-serenity-plugin/src/git/cc-git-tool.ts)——osp 是 ACC 工具 spec:
5
5
  * - status:JSON {clean, files:[{status,file}], summary, ahead, behind}
@@ -20,7 +20,7 @@
20
20
  * "stderr 是否为空";② push 的成功判据改为**可核验事实**(`--porcelain` 的 ref 行);
21
21
  * ③ 超时/未确认一律**不报成功**,并给出 `git ls-remote` 核验指令。
22
22
  */
23
- import type { JsonValue } from './json.js';
23
+ import type { JsonValue } from '../../kernel/json.js';
24
24
  type GitAction = 'status' | 'commit' | 'push' | 'log' | 'pull' | 'diff';
25
25
  export declare const GIT_ACTIONS: readonly GitAction[];
26
26
  interface GitArgs {
@@ -1,11 +1,11 @@
1
1
  /**
2
- * im-bridge.ts(工具面)— IM 消息发送工具(v1.31.0)
2
+ * im/channels.ts(工具面)— IM 消息发送工具(v1.31.0)
3
3
  *
4
4
  * 用户洞察(S142):微信桥是 ACC 提供的 → **发送能力也应是 ACC 的工具**;
5
5
  * 「当用户配置了微信桥则可用,不配置则不可见」。
6
6
  *
7
7
  * 本文件只做工具面三件事:① 从 agent 会话解析**本会话 CCC**(R4:不接受目标 CCC)
8
- * ② 把参数交给 `im-bridge.ts`(能力层)分发 ③ 渲染结果/错误。
8
+ * ② 把参数交给 `im/channels.ts`(能力层)分发 ③ 渲染结果/错误。
9
9
  *
10
10
  * 可见性不在这里判定:`seams/context.ts` 在会话就绪时按 CCC 配置
11
11
  * `agent.ctx.tools.restrict({ deny: ['im-bridge'] })` 把本工具从**未配置通道**的
@@ -1,5 +1,5 @@
1
1
  /**
2
- * kit.ts — dashboard 真实 DSH 工具定义(defineTool)(v1.30:acc_kit → dashboard)
2
+ * tools/kit/index.ts — dashboard 真实 DSH 工具定义(defineTool)(v1.30:acc_kit → dashboard)
3
3
  */
4
4
  import type { Context } from 'cordis';
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * kit-ops.ts — dashboard 纯操作层(acc_kit → dashboard,v1.30;零 DSH 依赖)
2
+ * tools/kit/service.ts — dashboard 纯操作层(acc_kit → dashboard,v1.30;零 DSH 依赖)
3
3
  *
4
4
  * 行为对齐 osp(opencode-serenity-plugin/src/acc-kit.ts)——osp 是 ACC 工具 spec:
5
5
  * - health:{ccc, root, version, status: healthy|degraded, principles: {P1_rooted, P2_git_managed, P3_binary_permissions}}
@@ -12,14 +12,14 @@
12
12
  * wait 用纯 Node setTimeout——不依赖外部 sleep 可执行文件(Windows 无 GNU coreutils sleep)。
13
13
  *
14
14
  * C5「观察面归一」(S142 2026-09-15):本文件的 health **不再自己取数**——三原则、注册表结构判据、
15
- * 配置、宿主契约一律经 `container-status.ts` 取(唯一取数出口),本文件只把事实**渲染**成 osp
15
+ * 配置、宿主契约一律经 `surface/observation.ts` 取(唯一取数出口),本文件只把事实**渲染**成 osp
16
16
  * 既有 wire 形状。故:
17
- * - `checkRegistryHealth` 已迁入 `container-status.ts`(同一实现,名字不变);
18
- * - `container-status.ts` 带 @deepseek-ai 值依赖(时钟段)⇒ 这里用 `await import` 保持本模块
19
- * 静态链**零 DSH 依赖**(与 `api.ts` 的既有约定同规格)。
17
+ * - `checkRegistryHealth` 已迁入 `surface/observation.ts`(同一实现,名字不变);
18
+ * - `surface/observation.ts` 带 @deepseek-ai 值依赖(时钟段)⇒ 这里用 `await import` 保持本模块
19
+ * 静态链**零 DSH 依赖**(与 `surface/http.ts` 的既有约定同规格)。
20
20
  * ⚠️ wire 形状**逐字不变**(字段名/取值/出现条件都不许动)——C5 是取数归一,不是文案改版。
21
21
  */
22
- import type { JsonValue } from './json.js';
22
+ import type { JsonValue } from '../../kernel/json.js';
23
23
  type KitAction = 'health' | 'time' | 'wait';
24
24
  export declare const KIT_ACTIONS: readonly KitAction[];
25
25
  interface KitArgs {
@@ -2,7 +2,7 @@
2
2
  * localstore.ts — localstore 真实 DSH 工具定义(defineTool)
3
3
  *
4
4
  * ACC 标准本地凭据/配置存储(S133 设计,S134 重设计:CCC 根 localstore.json)。
5
- * 进程内注册,零 DSH 依赖逻辑在 localstore-ops.ts(可单测)。
5
+ * 进程内注册,零 DSH 依赖逻辑在 tools/localstore/service.ts(可单测)。
6
6
  * doc 子命令输出存储规范,agent 可直接用 fs 工具(read/write)自己读写。
7
7
  */
8
8
  export declare const localstoreTool: import("@deepseek-ai/dsh-tools").ToolDefinition;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * localstore-ops.ts — localstore 纯逻辑层(零 DSH 依赖,可独立单测)
2
+ * tools/localstore/service.ts — localstore 纯逻辑层(零 DSH 依赖,可独立单测)
3
3
  *
4
4
  * S134 重设计(v1.16.7):存储从 ~/.serenity/ 迁到 **CCC 根根目录 localstore.json**
5
5
  * (JSON 格式——方便 MSM 直接 read + JSON.parse 读取,零解析依赖)。
@@ -16,7 +16,7 @@
16
16
  * credentials 为保留节(credential 命名空间,key 大写蛇形);其余节归 config 命名空间
17
17
  * (path = section.key,如 cheap-worker.models)。
18
18
  */
19
- import type { JsonValue } from './json.js';
19
+ import type { JsonValue } from '../../kernel/json.js';
20
20
  /** 命名空间:credential(凭据)| config(配置) */
21
21
  type LocalStoreScope = 'credential' | 'config';
22
22
  export declare const LOCALSTORE_SCOPES: readonly LocalStoreScope[];
@@ -1,5 +1,5 @@
1
1
  /**
2
- * msm.ts — msm 工具(v1.30 重构:单入口执行,list/exec 合一)
2
+ * tools/msm/index.ts — msm 工具(v1.30 重构:单入口执行,list/exec 合一)
3
3
  *
4
4
  * 设计(S142 用户拍板"msm 单入口同意 + 参数简易高效"):
5
5
  * acc_msm(8 action enum)→ msm(3 参数:name + args + inspect)——
@@ -1,10 +1,10 @@
1
1
  /**
2
- * msm-ops.ts — msm 纯操作层(acc_msm → msm 执行 + container_admin 管理面,v1.30;零 DSH 依赖)
2
+ * tools/msm/service.ts — msm 纯操作层(acc_msm → msm 执行 + container_admin 管理面,v1.30;零 DSH 依赖)
3
3
  *
4
4
  * MSM(Mech & Semi-Mech)框架:exec 执行 / register|deregister|check 管理。
5
5
  * 复用 CCC 的 mech-registry.json(v1 或数组格式)。cwd 钉在 CCC 根。
6
6
  */
7
- import type { JsonValue } from './json.js';
7
+ import type { JsonValue } from '../../kernel/json.js';
8
8
  type MsmAction = 'list' | 'exec' | 'register' | 'deregister' | 'check' | 'guide' | 'ccc-config' | 'catalog';
9
9
  export declare const MSM_ACTIONS: readonly MsmAction[];
10
10
  export declare const MSM_GUIDE = "MSM Development Manual (Mech & Semi-Mech framework)\n\n## What it is\nMSM = the executable-unit layer. Mech is pure TS with zero LLM reasoning; Semi-Mech is a TS framework + LLM decision points.\nMSM is ACC's deterministic executable-unit layer \u2014 all shell/exec operations go through MSM and cannot be bypassed.\n\n## Registering a new MSM (container_admin msm register)\n1. Write the script under <skill>/scripts/ (runnable via tsx; must include a main() CLI guard with an import.meta.url check)\n2. container_admin msm register --domain msm --action register <name> --skill <s> --path <script path relative to root> --category <mech|semi-mech> --description <desc>\n3. Auto-writes mech-registry.json (preserving the original format) + git commit (commits only the registry file)\n4. Validation: path must be inside root, script must exist, name must be globally unique\n\n## flag schema (v1)\nflags is a new-style object array for parameter validation and path-escape guarding:\n [{\"name\":\"output\",\"type\":\"string\",\"description\":\"output path\"},\n {\"name\":\"target\",\"type\":\"path\",\"description\":\"operation target (type:path enables in-root validation + symlink defense)\"},\n {\"name\":\"force\",\"type\":\"boolean\",\"description\":\"force mode\",\"default\":false}]\n- {name, type} format \u2014 new style, type:\"path\" enables the path-escape guard\n- {flag, description} format \u2014 old style, CLI flag description string\n- On registration, flags are passed via container_admin msm register --flags '<json>'\n\n## Script conventions\n- Top-of-file documentation: purpose / usage / exit codes\n- Exit codes: 0 success / 1 user / 2 system / 3 operator (per ACC protocol classification)\n- main() CLI guard (DC-M2): the script must start with\n if (import.meta.url === `file://${process.argv[1]}`) { main() }\n or an equivalent isMain / require.main === check \u2014 so vitest imports never trigger top-level code\n- A paired .test.ts or .spec.ts (DC-M1, vitest)\n- Business subprocess environment: SERENITY_ROOT / SERENITY_CCC / SERENITY_VERSION injected\n\n## Interaction & confirmation conventions (no blocking confirmation)\n- MSMs run in **user-less subprocesses** (spawn/execFile, 600s timeout) \u2014 **never** use\n readline / prompt / process.stdin etc. to block waiting for user input (it would hang until killed by the timeout)\n- When a second confirmation is needed: **directly return the confirmation request** (list the operation to perform and its impact + how to retry with the confirmation flag),\n returning a non-zero exit code (or an explicit hint)\n- After the agent confirms, **re-invoke the MSM with the confirmation flag** (e.g. --confirm / --yes / --force) to retry\n- Standard mode (two-phase):\n 1. First call: destructive/confirmation-requiring operation detected and no confirmation flag present \u2192 output the confirmation request (list operation/impact/rollback),\n exit non-zero (e.g. 1 user), **perform no changes**\n 2. After the agent evaluates, re-invoke: with the confirmation flag \u2192 execute and output the result\n- Applies to: delete/overwrite/push/batch operations and other irreversible or wide-impact operations\n- Anti-example (forbidden): readline waiting for user input, process.stdin.on('data') blocking waits\n (MSMs have no stdin interaction channel \u2014 they hang until the 600s timeout)\n\n## Quality checks (container_admin msm check, DC-M1~M4)\nDC-M1 has .test.ts/.spec.ts; DC-M2 has a main() guard (function main( / isMain / require.main === / import.meta.url);\nDC-M3 bidirectional: scripts unregistered + registry references missing scripts; DC-M4 path-type flags marked type:\"path\"\n\n## Self-description (protocol flags, first argument only)\nmsm(\"<name>\", [\"--list\"]) \u2014 list all MSMs\nmsm(\"<name>\", [\"--schema\", \"<n>\"]) \u2014 view a specific MSM's parameter schema\nmsm(\"<name>\", [\"--format=json\"]) \u2014 JSON output mode (remaining args passed through losslessly)\n";
@@ -1,25 +1,30 @@
1
1
  /**
2
- * skiff-admin.ts — Skiff 角色逻辑层(v1.30:skiff_admin 工具已并入 container_admin role 域)
2
+ * skiff-admin.ts — Skiff 约束面逻辑层(公开入口 = `container_admin` 的 `role` 域)
3
3
  *
4
- * 教 CCC 如何定义 Skiff 角色(用户拍板 2026-08-28 的三动作分工:
5
- * guide 定义教程 / validate 配置校验 / list 角色摘要)。
4
+ * 三动作分工(用户拍板 2026-08-28,2026-10-19 重做后语义不变):guide 定义教程 /
5
+ * validate 校验 / list 摘要 / apply 显式应用确认。
6
6
  *
7
- * 归属:ACC 机制(教会 + 校验),角色内容仍归 CCC 配置(.opencode/serenity.json skiff.roles)。
8
- * 公开入口 = container_admin(domain: role → guide/validate/apply/list);本文件保留纯逻辑。
7
+ * ## 🔴 2026-10-19 重做后,本文件的**数据源变了**
8
+ *
9
+ * 旧:读 `.opencode/serenity.json` 的 `skiff.roles`(容器级配置表)。
10
+ * 新:读**轨迹目录里的 `skiff.json`**(owner:「目录下拥有 `skiff.json` 的认知轨迹自动是一个 skiff」)。
11
+ * ⇒ `roleCount` 的语义 = **本 CCC 有几条 skiff 轨迹**;"角色名"这个概念没有了,只有**轨迹编码**。
12
+ *
13
+ * 归属(D23)不变:ACC 提供机制(教程 + 校验 + 列表),**约束内容归 CCC**(写进 `skiff.json`)。
9
14
  */
10
- import type { JsonValue } from '../json.js';
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 cognitive 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 \"cognitiveTrajectory\": { \"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\uFF08cognitiveTrajectory\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\": [], \"cognitiveTrajectory\": {} }\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\"], \"cognitiveTrajectory\": { \"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 非空 */
15
+ import type { JsonValue } from '../kernel/json.js';
16
+ /** Skiff 定义教程:概念 / `skiff.json` schema / 双白名单 / 轨迹纪律 / 微信路由 */
17
+ export declare const SKIFF_GUIDE = "\u2550\u2550\u2550 Skiff Guide (2026-10-19 redesigned) \u2550\u2550\u2550\n\n**A skiff IS a cognitive trajectory \u2014 the one whose directory contains `skiff.json`.**\nThat is the whole rule. No role table, no name registry: put the file there and the trajectory\nbecomes a skiff; delete it and it goes back to being an ordinary trajectory (takes effect at once).\n\n AGENT_SESSIONS/<YYYY-MM-DD--<code>--<desc>>/\n \u251C\u2500 SESSION.md \u2190 its persistent body (this IS the workspace \u2014 nothing is auto-created)\n \u251C\u2500 skiff.json \u2190 its constraints (this file is what makes it a skiff)\n \u2514\u2500 TRAJECTORY-UID \u2190 legacy, read-only (superseded by the code)\n\n\u2500\u2500 skiff.json schema \u2500\u2500\n {\n \"model\": \"provider/model\", // optional; falls back to cheap-worker.defaultModel\n \"tools\": [\"read\",\"grep\",\"msm\",...], // non-MSM toolbar whitelist \u2014 anything not listed is REMOVED from the schema\n \"msms\": [\"msm-a\",\"msm-b\"], // MSM whitelist \u2014 msm exec may only run these; register/deregister always refused\n \"cognitiveTrajectory\": { \"session\": true, \"keeper\": true, \"rebuild\": true }, // defaults TRUE (see below)\n \"systemPromptFile\": \".opencode/skiff/<role>.md\", // recommended: relative to CCC root, hot-reloads on save\n \"systemPrompt\": \"...\" // inline fallback; systemPromptFile wins when both are set\n }\n\n\u2500\u2500 Two whitelists, both default-deny \u2500\u2500\n - `tools: []` + non-empty `msms` = pure-MSM skiff (the usual knowledge-QA shape)\n - non-empty `msms` \u21D2 the `msm` tool is added automatically (the only entry point for MSMs)\n - anything outside both lists is invisible in the schema, not merely rejected at call time\n\n\u2500\u2500 cognitiveTrajectory: why the defaults are TRUE \u2500\u2500\n The workspace of a skiff is its own SESSION.md. Setting these to false would cut it off from\n its own body, so `session`/`keeper`/`rebuild` all default to true. Set false explicitly only\n when you deliberately want that participation off.\n\n\u2500\u2500 WeChat routing: user \u2192 trajectory code \u2500\u2500\n `weixin.routes`: `[{ \"user\": \"<wx id or *>\", \"trajectory\": \"<code>\" }]`\n A route pointing at a code with no such trajectory is a hard error (the message is NOT delivered).\n A trajectory WITHOUT `skiff.json` is still a legal target \u2014 it is just an ordinary trajectory.\n\n\u2500\u2500 Operating it \u2500\u2500\n Debug page: Settings \u2192 Serenity \u2192 enable the Skiff block \u2192 http://127.0.0.1:<debugPort>\n Everything is read live: saving `skiff.json` takes effect on the next turn, no restart.\n (The prompt FILE hot-reloads by mtime; the JSON itself is re-read every turn.)\n After editing, run container_admin role apply for an explicit validation + confirmation pass.\n Skill loading is always available to skiff sessions (skills are not whitelisted \u2014 they are read-only knowledge).";
18
+ /** 校验当前 CCC 的 skiff 约束面:msms 均已注册 / model ∈ cheap-worker.models / 提示词非空 */
14
19
  export declare function validateSkiffConfig(root: string): JsonValue;
15
- /** 列出当前 CCC 已定义角色(名 / 模型 / msms / tools / 轨迹纪律摘要) */
20
+ /** 列出当前 CCC 的 skiff 轨迹(编码 / 模型 / msms / tools / 纪律摘要 / 提示词来源) */
16
21
  export declare function listSkiffRoles(root: string): JsonValue;
17
22
  /**
18
- * 应用当前 skiff 配置(v1.25.3,S142 用户:改了 json 应该有个生效机制)。
23
+ * 应用当前 skiff 配置(S142 用户:改了 json 应该有个生效机制)。
19
24
  *
20
- * 语义:配置是**每次请求实时读取**的(v1.25.2)——apply 不是"推送",而是**显式校验 + 应用确认**:
21
- * ① 校验配置合法(复用 validate:msms 注册 / model 白名单 / systemPrompt 非空)
25
+ * 语义:约束面是**每轮实时读取**的 ⇒ apply 不是"推送",而是**显式校验 + 应用确认**:
26
+ * ① 校验合法(复用 validate:msms 注册 / model 白名单 / 提示词非空)
22
27
  * ② 非法 → 报告问题清单,不应用(提示修复后重跑 apply)
23
- * ③ 合法 → 应用确认:绑定 CCC + 角色清单 + 说明(调试页刷新即生效)
28
+ * ③ 合法 → 应用确认:绑定 CCC + 轨迹清单 + 说明(下一轮即生效)
24
29
  */
25
30
  export declare function applySkiffConfig(root: string): JsonValue;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * cognitive-trajectory-assistant.ts — 关卡化注入的统一命名与风格门面(v0.3,S142)
2
+ * trajectory/assistant.ts — 关卡化注入的统一命名与风格门面(v0.3,S142)
3
3
  *
4
4
  * 概念(用户拍板 2026-09-05):dsp 全部"过程中动态提示注入"统一命名为
5
5
  * cognitive-trajectory-assistant(轨迹助航员)。关卡设计思想塑造**结构与时机**
@@ -58,7 +58,7 @@ export declare const ACK_SKIP_PREFIX = "COGNITIVE-TRAJECTORY-ASSISTANT-skipped";
58
58
  * ⇒ 分家:**只用一次的交界材料**写进这份**临时便签**(无格式义务、无留档义务、可随时丢弃)。
59
59
  *
60
60
  * ## 🔴 三处引用同一常量(单一真相源)
61
- * **写侧** = `seams/keeper.ts` 的 `rebuildReminderText()`|**读侧** = `rebuild.ts` 的重建锚点|
61
+ * **写侧** = `seams/keeper.ts` 的 `rebuildReminderText()`|**读侧** = `trajectory/rebuild.ts` 的重建锚点|
62
62
  * **体积提醒** = `seams/keeper.ts` 的 `rebuildTodoReminderText()`。
63
63
  * 文件名一旦漂移,写侧写的东西读侧就找不到 —— **且没有任何机械信号会报警**。
64
64
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * cognitive-trajectory-bound.ts — SESSION 绑定持久化(CCC 内 `AGENT_SESSIONS/.bindings.json`)
2
+ * trajectory/bound.ts — SESSION 绑定持久化(CCC 内 `AGENT_SESSIONS/.bindings.json`)
3
3
  *
4
4
  * 目标(S142 用户拍板,方案 v1.0):让「dsh 会话(载体)↔ SESSION(宁静号轨迹)」
5
5
  * 的绑定坚固——LLM 不能因智力因素(幻觉/理解偏差)在过程中或 cognitive_trajectory rebuild 后
@@ -23,7 +23,7 @@
23
23
  * 编码无关(U4):绑定锚 = **完整 AGENT_SESSIONS 目录名**(磁盘唯一存在),
24
24
  * sessionId(S###/apaas-xxx/自定义)仅是派生展示字段——绝不假设 S 前缀。
25
25
  */
26
- import { type BindingStore } from './host/storage-domain.js';
26
+ import { type BindingStore } from '../host/storage-domain.js';
27
27
  type SessionBoundAction = 'activate' | 'switch' | 'create' | 'rebuild' | 'reconcile' | 'release';
28
28
  interface SessionBoundRecord {
29
29
  dirName: string;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * session-cleanup.ts — DSH 平台旧会话自动清理(v1.29,S142 需求③)
2
+ * trajectory/cleanup.ts — DSH 平台旧会话自动清理(v1.29,S142 需求③)
3
3
  *
4
4
  * 背景(实证):DSH 会话物理存储 = `$DSH_HOME/sessions/`(缺省 ~/.dsh/sessions;
5
5
  * base bundle cordis.patch.yml root: dshHomePath('sessions'))。磁盘布局:
@@ -1,5 +1,5 @@
1
1
  /**
2
- * cognitive-trajectory-ops.ts — 轨迹工具纯操作层(零 DSH 依赖,可独立单测)
2
+ * trajectory/core.ts — 轨迹工具纯操作层(零 DSH 依赖,可独立单测)
3
3
  *
4
4
  * 行为对齐 osp(opencode-serenity-plugin/src/session/lib.ts)——osp 是 ACC 工具 spec。
5
5
  *
@@ -91,6 +91,24 @@ interface SessionEntry {
91
91
  mtime: Date;
92
92
  status: SessionStatus;
93
93
  }
94
+ /**
95
+ * 校验轨迹编码形态。**这是写入侧(create --id)与外部输入的唯一闸门。**
96
+ *
97
+ * 判据三条(R↓):
98
+ * ① `CODE_PATTERN` —— 只允许交流安全字符:编码会被逐字打在命令、消息、日志里,
99
+ * 含空格/引号/中文会在 shell、JSON、markdown 各需一套转义(旧 UID 的同一条理由,D158);
100
+ * ② **不得含 `--`** —— 目录名解析用它当分隔符(见上);
101
+ * ③ 长度上限 64(同旧 UID;够长以致不会撞名,够短以致能打出来)。
102
+ *
103
+ * ⚠️ 大小写**敏感**:`S142` 与 `s142` 是两个不同编码(编码不是近似匹配语义)。
104
+ */
105
+ export declare function isValidTrajectoryCode(code: string): boolean;
106
+ /**
107
+ * 从目录名解析轨迹编码(固定位置 = 剥掉日期前缀后的第一段)。
108
+ *
109
+ * @returns 编码;目录名不带日期前缀(非本工具建的 / 损坏)→ `null`
110
+ */
111
+ export declare function parseTrajectoryCode(dirName: string): string | null;
94
112
  /**
95
113
  * UID 的声明文件名(**固定名、住在轨迹目录内**)。
96
114
  *
@@ -107,17 +125,30 @@ interface SessionEntry {
107
125
  * | **独立小文件**(选定) | 与目录名、SESSION.md **都解耦**;改标识符不动正文、不动目录名;删文件即"回到用编码" |
108
126
  *
109
127
  * ## 语义边界(R↓)
110
- * - **可选**:文件不存在 ⇒ 用编码(`S###`),**不是错误**。
128
+ * - **可选**:文件不存在 ⇒ 用编码,**不是错误**。
111
129
  * - **只用于"被指认"**:它是 `findSession` 的一个**解析分支**,不参与排序、不参与展示优先级、
112
130
  * **不改变**目录名与 SESSION.md 一个字节(与 `archive` 同一条纪律:只换指认方式,不动本体)。
113
- * - **唯一性**:由 `setTrajectoryUid` 在写入时保证(重复即拒绝)。读取侧不做全表唯一性断言 ——
114
- * 外部手工造的重复应由写入侧拦,读取侧只能"第一个命中",那是注入侧的职责不是解析侧的。
131
+ *
132
+ * ## 🔴 2026-10-19:**写入侧退役,读取侧保留**
133
+ *
134
+ * owner 追加令裁 B 案:「取消 `S###` 与 UID 的二元性 —— 编码就是唯一标识,用户可指定」。
135
+ * UID 当初存在的**唯一理由**是「命名很可能由于变化而变化」(D158),而现在的编码
136
+ * **本身就稳定且可指定**(`create --id`)⇒ 该理由被覆盖 ⇒ **二元性取消**。
137
+ *
138
+ * 处置(**不对称,刻意**):
139
+ * - **写**:`setTrajectoryUid()` **已删除**(`uid` 动作改为报"已退役"并指向 `create --id`);
140
+ * - **读**:本文件与 `findSession` 的 UID 分支**保留** —— 存量文件(本仓 = S142 的
141
+ * `serenity-acc-maintainer`)仍能按它指认,**不因退役而失去能力**。
142
+ *
143
+ * ⚠️ **为什么不物理删除那些文件**:删了就丢掉一个仍在被读的指认通道(能力倒退),
144
+ * 而保留的成本是零(文件不存在 ⇒ `readFileSync` 失败 ⇒ null)。
145
+ * 判据:**退役的是"产生新标识"这种能力,不是"旧标识还在被用"这个事实。**
115
146
  */
116
147
  export declare const UID_FILENAME = "TRAJECTORY-UID";
117
148
  /**
118
- * 校验 UID 形态。
149
+ * 校验 UID 形态(**只读兼容路径** —— 写入侧已退役,见 `UID_FILENAME` 的 R↓ 段)。
119
150
  *
120
- * 为什么保守(R↓):UID 是**给人和 agent 在对话里互相指认用的**(owner:「用于交流」)⇒
151
+ * 为什么保守:UID 是**给人和 agent 在对话里互相指认用的**(owner:「用于交流」)⇒
121
152
  * 它必须能**逐字打出来**。含空格/引号/中文的 UID 会在 shell、JSON、markdown 里各自需要一套转义
122
153
  * ⇒ "用于交流"这个目的当场失败。⇒ 限定 `[A-Za-z0-9._-]`,首字符必须字母数字,上限 64。
123
154
  *
@@ -130,32 +161,22 @@ export declare function isValidUid(uid: string): boolean;
130
161
  *
131
162
  * 🔴 **形态非法的文件按"没设定"处理,而不是报错**:解析侧出现在**每一次** `findSession` 里
132
163
  * (show/use/archive/send-now/send-later 全走它),在那里抛错会让一个坏文件**炸掉整条轨迹的所有操作**
133
- * —— 惩罚远大于问题本身。坏 UID 由 `setTrajectoryUid` 在**写入侧**拦住(那里才该响亮失败)。
164
+ * —— 惩罚远大于问题本身。而写入侧已退役 ⇒ 坏文件只可能来自外部手改,更不该连坐。
134
165
  */
135
166
  export declare function readTrajectoryUid(sessionPath: string): string | null;
136
- /**
137
- * 设定 / 清除一条轨迹的 UID。
138
- *
139
- * @param sessionsDir AGENT_SESSIONS 绝对路径
140
- * @param key 定位用(目录名 / S### / 既有 UID / 唯一模糊串)
141
- * @param uid 新 UID;`null` ⇒ **删除声明文件**(回到"用编码")
142
- * @throws UID 形态非法 / 已被**别的**轨迹占用 / 目标轨迹不存在
143
- */
144
- export declare function setTrajectoryUid(sessionsDir: string, key: string, uid: string | null): {
145
- dirName: string;
146
- uid: string | null;
147
- path: string;
148
- };
149
167
  /**
150
168
  * 根据 key 查找轨迹。
151
169
  *
152
170
  * 解析顺序(**越精确越靠前**,且**前三级都不做模糊**):
153
- * ① 目录名精确 / ② **UID 精确** / ③ 编码 `S###`(允许 `S31`→`031`)/ ④ 唯一模糊子串(多个则报错)
171
+ * ① 目录名精确 / ② **编码精确** / ③ **UID 精确(只读兼容)** / ④ 唯一模糊子串(多个则报错)
172
+ *
173
+ * 🔴 **2026-10-19 起编码排在 UID 之前**(旧顺序相反):编码现在是**一等标识**
174
+ * (owner:「固定为目录中的固定位置编码」+「允许用户指定」),而 UID 已退役为兼容层。
175
+ * 顺序对结果无实质影响(两者都属精确匹配、形态互斥 —— 编码不含 `--`),
176
+ * 但把顺序写死,避免后来者以为"编码是模糊匹配的一种"或"UID 优先"。
154
177
  *
155
- * 🔴 **UID 排在编码之前**是因为 owner 定的语义:UID 是"单独设定"的**交流标识**
156
- * ("不设定就还是用编码"⇒ 设定之后,用 UID 指认就该与编码同等可靠)。
157
- * 它与目录名都属**精确匹配**、彼此不会混淆(UID 形态不含 `--`,目录名必含)⇒ 顺序对结果无实质影响,
158
- * 但把这个顺序写死,避免后来者以为"UID 是模糊匹配的一种"。
178
+ * 🔵 `S31` → `S031` 的**数字补零**兼容保留(存量用户习惯);它现在只是编码匹配的一个特例:
179
+ * 编码恰为 `S###` 形态时允许省前导零。
159
180
  */
160
181
  export declare function findSession(sessionsDir: string, key: string): SessionEntry | null;
161
182
  /** list 子命令(对齐 osp listSessions 文本格式 + active 标记) */
@@ -168,6 +189,15 @@ interface CreateSessionOptions {
168
189
  desc?: string;
169
190
  /** --issue 模式的工单号(与 desc 互斥) */
170
191
  issue?: string;
192
+ /**
193
+ * 显式指定的**轨迹编码**(owner 2026-10-19 令:「允许用户指定这个编码」)。
194
+ *
195
+ * - 不给 ⇒ 沿用既有行为:自增 `S###`(desc 模式)/ 工单号即编码(issue 模式)。
196
+ * - 给了 ⇒ **它就是目录名的 code 段**,并且是这条轨迹**唯一的**稳定标识。
197
+ *
198
+ * 形态由 `isValidTrajectoryCode` 把关(不得含中文/`--`),唯一性由本函数把关(重复即拒)。
199
+ */
200
+ id?: string;
171
201
  goal?: string;
172
202
  dryRun: boolean;
173
203
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * live-sessions.ts — 进程内 live 会话取数 + 精简诊断
2
+ * trajectory/live.ts — 进程内 live 会话取数 + 精简诊断
3
3
  *
4
4
  * ── 为什么单独成模块(R↓,2026-09-15 S142「ACC 侧 autopilot 退场」S1 搬迁)──
5
5
  * 这两个函数原先住在 `autopilot-trajectory.ts`,但它们的**主语不是 autopilot**:
@@ -0,0 +1,101 @@
1
+ /**
2
+ * trajectory/prompt.ts — **轨迹提示词**(Trajectory Prompt):一条轨迹"是谁、按什么章程工作"
3
+ *
4
+ * ## 概念(owner 2026-10-19 定向,逐字)
5
+ *
6
+ * > 「参考会话的系统提示词,我们建立**轨迹提示词**概念来代替人格。架构上会好很多」
7
+ *
8
+ * **轨迹提示词** = 一条认知轨迹的**可编辑章程声明**,由 ACC 按固定顺序装配进系统提示词。
9
+ * 三个关键词各是一条判据:
10
+ * - **可编辑**:住在 CCC(盘上),改它**不发版**(D23 归属判据的直接推论)
11
+ * - **声明**:它声明**身份/章程/方法论**,**不声明能力**(能力面归 `skiff.json` 白名单与工具 schema)
12
+ * - **固定顺序**:装配顺序由 ACC 定死(见 `seams/system-prompt.ts` 的 ⑧ 位)
13
+ *
14
+ * ## 为什么取代「人格」
15
+ *
16
+ * 「人格」把身份绑在"像不像一个人"上 ⇒ 因为叫人格,它被设计成**可以整体替换**
17
+ * (`persona` 置换 EAP 块,即 review F-05/R-14 那个悬置冲突)。而身份与章程**不该被替换,
18
+ * 只该被特化**。⇒ 本模块把"替换"改成"叠加":容器层与质量层永远保留,轨迹提示词只往上加。
19
+ *
20
+ * ## 落点(为什么在轨迹目录里)
21
+ *
22
+ * `AGENT_SESSIONS/<轨迹目录>/PROMPT.md`
23
+ *
24
+ * - **跟着轨迹走**:`archive` 时整个目录搬走,章程不会掉队(旧形态 `.opencode/skiff/<name>.md`
25
+ * 与轨迹**分居两处** —— 多条轨迹共用一份文件正是那个后果)。
26
+ * - **每条轨迹都能有**:不只是 skiff。普通轨迹同样需要"我是谁、按什么章程"。
27
+ * - 与 `SESSION.md`(身体:延续/日志)、`skiff.json`(约束面:能力)三件并列,
28
+ * 各管一件事,不合并(合并会让"改能力"与"改身份"互相牵连)。
29
+ *
30
+ * ## 兼容(不静默坏)
31
+ *
32
+ * `PROMPT.md` 不存在时**不报错**(普通轨迹常态)。skiff 的旧字段 `systemPromptFile`
33
+ * 在兼容期仍被读取——优先级见 {@link resolveTrajectoryPrompt}。
34
+ */
35
+ import type { SkiffProfile } from '../role/skiff/profile.js';
36
+ /** 轨迹提示词的固定文件名(**判据就是它存在**——不是目录名前缀,也不是配置里的一行) */
37
+ export declare const TRAJECTORY_PROMPT_FILENAME = "PROMPT.md";
38
+ /** 一次解析的结果(`source` 说明正文**从哪来**,便于诊断与「为什么我改的不生效」) */
39
+ export interface TrajectoryPromptResolution {
40
+ /** 提示词正文(已 trim);无来源 ⇒ 空串 */
41
+ text: string;
42
+ /** 来源:轨迹目录的 PROMPT.md / skiff 旧字段 / 无 */
43
+ source: 'trajectory-file' | 'skiff-legacy' | 'none';
44
+ /** 实际读取的绝对路径(`none` ⇒ null) */
45
+ path: string | null;
46
+ }
47
+ /** 轨迹目录的 PROMPT.md 绝对路径(不论存在与否——调用方自己判存在性) */
48
+ export declare function trajectoryPromptPath(root: string, dirName: string): string;
49
+ /**
50
+ * 该轨迹**有没有**轨迹提示词(单一判据)。
51
+ *
52
+ * 用途:兼容期的"让位"判定 —— 若已有 `PROMPT.md`,skiff 旧字段 `systemPromptFile`
53
+ * 必须**让位**,否则同一份章程会在两处各注入一遍(第 ⑧ 段 + `serenity-skiff` 段)。
54
+ * 🔴 判据只有这一处:别在 skiff 那边自己拼路径再判(两处会漂)。
55
+ */
56
+ export declare function hasTrajectoryPrompt(root: string, dirName: string): boolean;
57
+ /**
58
+ * 解析一条轨迹的**轨迹提示词**(一次性读;`create` / 诊断 / 预览用)。
59
+ *
60
+ * 🔴 热路径**不要**用它(那会每次工具调用都读盘)——热路径用 {@link createTrajectoryPromptReader}。
61
+ *
62
+ * 优先级(**确定性,只有这一条**):
63
+ * ① `<轨迹目录>/PROMPT.md` —— 新形态,**所有轨迹**都能有
64
+ * ② skiff 的 `systemPromptFile` —— **兼容期**旧形态(存量 CCC 不必同批迁移)
65
+ * ③ 无 ⇒ 空串(**不是错误**:没有章程的轨迹是常态)
66
+ *
67
+ * ⚠️ 读失败(权限/坏文件)⇒ 空串而不是抛错:提示词读不到不该阻断会话创建;
68
+ * 但**会告警**(见 reader 版本),不静默。
69
+ */
70
+ export declare function resolveTrajectoryPrompt(root: string, dirName: string, legacyProfile?: SkiffProfile | null): TrajectoryPromptResolution;
71
+ /**
72
+ * 轨迹提示词的**读取器**(长期热更新;改文件即生效,无需重启)。
73
+ *
74
+ * ## 为什么返回函数而不是字符串(R↓,实证代价)
75
+ *
76
+ * 旧实现把提示词**快照**进系统提示词段的闭包 ⇒ CCC 改了文件必须重启 dsh web 才生效
77
+ * (实测:改完 18KB 提示词,live agent 仍用旧文本)。现形态由系统提示词段的 `text()`
78
+ * **每轮调用**本读取器:按 **mtime + size** 缓存重读(命中缓存零 IO)。
79
+ *
80
+ * ## 三条失败语义(各治一个失败模式)
81
+ *
82
+ * - **文件不存在** ⇒ 返回空串(**不是错误**:普通轨迹没有章程是常态,且删掉即失效
83
+ * 必须是立即可见的——这就是"删掉 PROMPT.md 即恢复默认"的机制)
84
+ * - **读取失败** ⇒ 返回**上次成功内容**(⛔ 绝不返回空:空提示词会让轨迹失去章程),
85
+ * 并按去重标签告警一次
86
+ * - **首次就读不到** ⇒ 空串 + 告警一次(区分"本来没有"与"有但读不了")
87
+ *
88
+ * @param root CCC 根
89
+ * @param dirName 轨迹目录名(**不是编码**:目录名才是落盘位置)
90
+ */
91
+ export declare function createTrajectoryPromptReader(root: string, dirName: string): () => string;
92
+ /**
93
+ * 装配用的**提示词段**(幂等:无内容 ⇒ 空串,宿主会丢弃空 section/空块)。
94
+ *
95
+ * 标记头 `=== Serenity Trajectory Prompt ===`:
96
+ * ① 让模型知道"下面是**这条轨迹自己的章程**",不是容器规则;
97
+ * ② 让诊断可以按块名 grep。
98
+ *
99
+ * 🔴 这段**追加**在容器层与质量层之后,**永不替换它们**——那正是本概念相对「人格」的核心修正。
100
+ */
101
+ export declare function trajectoryPromptBlock(text: string): string;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * rebuild.ts — 轨迹跟踪器(Cognitive Trajectory Tracker)超限重建:cognitive_trajectory rebuild
2
+ * trajectory/rebuild.ts — 轨迹跟踪器(Cognitive Trajectory Tracker)超限重建:cognitive_trajectory rebuild
3
3
  * (v1.30 起并入 logbook 的 rebuild action,v1.33 随 logbook 并入 trajectory,v1.34 工具名硬切
4
4
  * 为 container_trajectory;原独立 session_rebuild 工具)
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * cognitive-trajectory-skills.ts — 轨迹 skill 声明解析 + 注入内容装配(纯逻辑,零 DSH 依赖)
2
+ * trajectory/skills.ts — 轨迹 skill 声明解析 + 注入内容装配(纯逻辑,零 DSH 依赖)
3
3
  *
4
4
  * 接口真相源:`docs/cognitive-trajectory-skill-injection.md` v1.0(§2 数据契约 / §3 注入契约)。
5
5
  * 一句话:**轨迹自己声明它要挂哪些 skill**(`SESSION.md` 顶部 YAML frontmatter 的 `skills:`),