@zhushanwen/subagent-core 0.2.0 → 0.4.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 (195) hide show
  1. package/README.md +45 -2
  2. package/agents/analyst.md +60 -0
  3. package/agents/coder.md +69 -0
  4. package/agents/debugger.md +66 -0
  5. package/agents/doc-reviewer.md +49 -0
  6. package/agents/explorer.md +63 -0
  7. package/agents/general-purpose.md +32 -0
  8. package/agents/orchestrator.md +61 -0
  9. package/agents/planner.md +53 -0
  10. package/agents/researcher.md +67 -0
  11. package/agents/reviewer.md +73 -0
  12. package/dist/chunk-4KN4TTG7.js +240 -0
  13. package/dist/chunk-APZY4IME.js +27 -0
  14. package/dist/chunk-X7SZ5HLQ.js +66 -0
  15. package/dist/execution/engine/engines/zcode/constants.cjs +65 -0
  16. package/dist/execution/engine/engines/zcode/constants.d.cts +93 -1
  17. package/dist/execution/engine/engines/zcode/constants.d.ts +93 -1
  18. package/dist/execution/engine/engines/zcode/constants.js +43 -1
  19. package/dist/execution/engine/engines/zcode/reader.d.cts +1 -1
  20. package/dist/execution/engine/engines/zcode/reader.d.ts +1 -1
  21. package/dist/execution/engine/engines/zcode/reader.js +4 -234
  22. package/dist/execution/engine/paths.js +7 -19
  23. package/dist/index.cjs +14709 -100
  24. package/dist/index.d.cts +4053 -200
  25. package/dist/index.d.ts +4053 -200
  26. package/dist/index.js +14358 -102
  27. package/dist/{types-BxyAidGf.d.cts → types-DpUO16pj.d.cts} +464 -1
  28. package/dist/{types-BxyAidGf.d.ts → types-DpUO16pj.d.ts} +464 -1
  29. package/package.json +6 -3
  30. package/src/__tests__/review-fix-loop-script.test.ts +90 -2
  31. package/src/__tests__/review-fix-loop-utils.test.ts +21 -0
  32. package/src/__tests__/smoke.test.ts +9 -2
  33. package/src/execution/__tests__/agent-profile.test.ts +232 -0
  34. package/src/execution/__tests__/agents-assembly.test.ts +219 -0
  35. package/src/execution/__tests__/chat-engine-routing.test.ts +71 -0
  36. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +1 -0
  37. package/src/execution/__tests__/create-concurrency-pool.test.ts +194 -0
  38. package/src/execution/__tests__/delivery-methods.test.ts +2 -0
  39. package/src/execution/__tests__/descendant-sweep.test.ts +269 -0
  40. package/src/execution/__tests__/dialog-queue.test.ts +199 -1
  41. package/src/execution/__tests__/epipe-fallback.test.ts +2 -0
  42. package/src/execution/__tests__/execution-runtime-face.test.ts +272 -0
  43. package/src/execution/__tests__/finalize-record.test.ts +106 -0
  44. package/src/execution/__tests__/gc-timer.test.ts +2 -0
  45. package/src/execution/__tests__/get-record-for-action-restart.test.ts +2 -0
  46. package/src/execution/__tests__/get-state-handshake.test.ts +127 -0
  47. package/src/execution/__tests__/keep-alive-no-progress.test.ts +378 -0
  48. package/src/execution/__tests__/kill-all-escalation.test.ts +196 -0
  49. package/src/execution/__tests__/lifecycle-manager-idle-timer-identity.test.ts +117 -0
  50. package/src/execution/__tests__/lifecycle-manager.test.ts +39 -0
  51. package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +99 -0
  52. package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +113 -0
  53. package/src/execution/__tests__/notify-ledger.test.ts +294 -0
  54. package/src/execution/__tests__/record-store-orphan-revive.test.ts +159 -0
  55. package/src/execution/__tests__/record-store.test.ts +83 -0
  56. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +4 -0
  57. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +1 -0
  58. package/src/execution/__tests__/run-spawn-edges.test.ts +407 -17
  59. package/src/execution/__tests__/run-spawn-integration.test.ts +1 -1
  60. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +12 -4
  61. package/src/execution/__tests__/service-kill-escalation.test.ts +89 -0
  62. package/src/execution/__tests__/session-pending.test.ts +228 -0
  63. package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +110 -0
  64. package/src/execution/__tests__/session-runner-close-prune.test.ts +181 -0
  65. package/src/execution/__tests__/session-runner-epipe.test.ts +1 -0
  66. package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +226 -0
  67. package/src/execution/__tests__/settled-watchdog.test.ts +289 -0
  68. package/src/execution/__tests__/spawned-children.test.ts +153 -10
  69. package/src/execution/__tests__/subagent-actions-core.test.ts +997 -0
  70. package/src/execution/__tests__/subagent-service-message-close.test.ts +71 -10
  71. package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +174 -0
  72. package/src/execution/__tests__/subagent-service-notify-gate.test.ts +266 -0
  73. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +3 -0
  74. package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +316 -0
  75. package/src/execution/__tests__/timeout-integration.test.ts +7 -7
  76. package/src/execution/__tests__/ui-request-handler-factory.test.ts +95 -1
  77. package/src/execution/__tests__/ui-request-queue.test.ts +25 -0
  78. package/src/execution/__tests__/worktree-git-ops.test.ts +571 -0
  79. package/src/execution/__tests__/worktree-reconcile-aging.test.ts +204 -0
  80. package/src/execution/agent-registry.ts +225 -1
  81. package/src/execution/agents-assembly.ts +88 -0
  82. package/src/execution/concurrency-pool.ts +71 -9
  83. package/src/execution/dialog-queue.ts +101 -3
  84. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +49 -2
  85. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +87 -1
  86. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +26 -0
  87. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +83 -1
  88. package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +131 -0
  89. package/src/execution/engine/__tests__/registry.test.ts +90 -1
  90. package/src/execution/engine/engine-discovery.ts +12 -16
  91. package/src/execution/engine/engines/pi/task-spec-mapper.ts +3 -3
  92. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +274 -0
  93. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +36 -0
  94. package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +472 -0
  95. package/src/execution/engine/engines/zcode/__tests__/preparer-appserver.test.ts +387 -0
  96. package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +780 -0
  97. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +815 -0
  98. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +462 -0
  99. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +119 -1
  100. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +136 -6
  101. package/src/execution/engine/engines/zcode/appserver-home.ts +442 -0
  102. package/src/execution/engine/engines/zcode/appserver-probe.ts +141 -0
  103. package/src/execution/engine/engines/zcode/connection.ts +585 -0
  104. package/src/execution/engine/engines/zcode/constants.ts +129 -0
  105. package/src/execution/engine/engines/zcode/golden-sample.ts +54 -8
  106. package/src/execution/engine/engines/zcode/preparer.ts +25 -22
  107. package/src/execution/engine/engines/zcode/session-channel.ts +656 -0
  108. package/src/execution/engine/engines/zcode/zcode-engine.ts +909 -41
  109. package/src/execution/engine/host-task-spec.ts +3 -3
  110. package/src/execution/engine/port.ts +41 -1
  111. package/src/execution/engine/registry.ts +53 -0
  112. package/src/execution/finalize-record.ts +63 -5
  113. package/src/execution/get-state-handshake.ts +85 -10
  114. package/src/execution/lifecycle-manager.ts +27 -3
  115. package/src/execution/manifest-store.ts +53 -62
  116. package/src/execution/notifier.ts +10 -10
  117. package/src/execution/notify-ledger.ts +117 -16
  118. package/src/execution/record-entry.ts +8 -2
  119. package/src/execution/record-store.ts +29 -15
  120. package/src/execution/session-pending.ts +213 -62
  121. package/src/execution/session-runner.ts +974 -128
  122. package/src/execution/sessions-index.ts +10 -55
  123. package/src/execution/settled-watchdog.ts +99 -0
  124. package/src/execution/subagent-actions-core.ts +686 -0
  125. package/src/execution/subagent-service.ts +396 -49
  126. package/src/execution/ui-request-handler-factory.ts +27 -4
  127. package/src/execution/worktree-git-ops.ts +397 -0
  128. package/src/execution/worktree-manager.ts +72 -10
  129. package/src/execution/worktree-registry.ts +6 -12
  130. package/src/index.ts +413 -6
  131. package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +42 -3
  132. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +2 -4
  133. package/src/orchestration/__tests__/args-meta.test.ts +358 -0
  134. package/src/orchestration/__tests__/error-recovery-handlers.test.ts +1 -8
  135. package/src/orchestration/__tests__/error-recovery-rebuild-failure.test.ts +312 -0
  136. package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +382 -0
  137. package/src/orchestration/__tests__/file-run-store-prune.test.ts +168 -0
  138. package/src/orchestration/__tests__/file-run-store-throttle.test.ts +168 -0
  139. package/src/orchestration/__tests__/file-run-store.test.ts +389 -0
  140. package/src/orchestration/__tests__/helpers/flush-microtasks.ts +13 -0
  141. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +34 -0
  142. package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +357 -0
  143. package/src/orchestration/__tests__/lifecycle-recover-crashed.test.ts +289 -0
  144. package/src/orchestration/__tests__/lifecycle.test.ts +77 -0
  145. package/src/orchestration/__tests__/run-snapshot.test.ts +353 -0
  146. package/src/orchestration/__tests__/script-generate.test.ts +314 -0
  147. package/src/orchestration/__tests__/worker-pending-timeout-abort.test.ts +275 -0
  148. package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +78 -1
  149. package/src/orchestration/__tests__/workflow-files.test.ts +186 -0
  150. package/src/orchestration/__tests__/workflow-run-summary.test.ts +119 -0
  151. package/src/orchestration/__tests__/workflow-script-registry-impl.test.ts +124 -0
  152. package/src/orchestration/agent-opts-resolver.ts +7 -7
  153. package/src/orchestration/args-meta.ts +198 -0
  154. package/src/orchestration/error-recovery.ts +416 -146
  155. package/src/orchestration/execute-agent-call.ts +9 -9
  156. package/src/orchestration/file-run-store.ts +327 -0
  157. package/src/orchestration/launcher.ts +35 -26
  158. package/src/orchestration/lifecycle.ts +355 -79
  159. package/src/orchestration/models/agent-call.ts +7 -7
  160. package/src/orchestration/models/budget.ts +5 -5
  161. package/src/orchestration/models/run-runtime.ts +13 -13
  162. package/src/orchestration/models/trace.ts +8 -8
  163. package/src/orchestration/models/workflow-run.ts +27 -27
  164. package/src/orchestration/models/workflow-script.ts +4 -4
  165. package/src/orchestration/run-snapshot.ts +266 -0
  166. package/src/orchestration/script-generate.ts +154 -0
  167. package/src/orchestration/script-lint.ts +33 -33
  168. package/src/orchestration/worker-handle.ts +10 -10
  169. package/src/orchestration/worker-host.ts +10 -10
  170. package/src/orchestration/worker-script-builder.ts +401 -346
  171. package/src/orchestration/workflow-files.ts +37 -11
  172. package/src/orchestration/workflow-run-summary.ts +69 -0
  173. package/src/orchestration/workflow-script-registry-impl.ts +31 -9
  174. package/src/shared/__tests__/agent-ref.test.ts +209 -2
  175. package/src/shared/__tests__/atomic-write.test.ts +267 -0
  176. package/src/shared/__tests__/bounded-serialize.test.ts +236 -0
  177. package/src/shared/__tests__/injection-render.test.ts +518 -0
  178. package/src/shared/__tests__/resource-discovery-host-roots.test.ts +474 -0
  179. package/src/shared/__tests__/resource-discovery.test.ts +3 -2
  180. package/src/shared/agent-ref.ts +143 -2
  181. package/src/shared/atomic-write.ts +320 -0
  182. package/src/shared/bounded-serialize.ts +154 -0
  183. package/src/shared/injection-render.ts +279 -0
  184. package/src/shared/meta-parser.ts +41 -1
  185. package/src/shared/resource-discovery.ts +104 -37
  186. package/src/shared/resource-meta.ts +14 -0
  187. package/src/shared/xml-injection.ts +9 -9
  188. package/workflows/README.md +9 -9
  189. package/workflows/chain.js +4 -2
  190. package/workflows/map-reduce.js +5 -3
  191. package/workflows/parallel.js +5 -3
  192. package/workflows/review-fix-loop-utils.cjs +14 -3
  193. package/workflows/review-fix-loop.js +18 -7
  194. package/workflows/scatter-gather.js +4 -2
  195. package/dist/chunk-3VOERJPJ.js +0 -22
@@ -41,3 +41,132 @@ export const ZCODE_KILL_GRACE_MS = 5_000;
41
41
 
42
42
  /** 错误信息里保留的 stdout 尾部长度(engine_run_failed 规格:够诊断、不刷屏)。 */
43
43
  export const ZCODE_ERROR_TAIL_CHARS = 2000;
44
+
45
+ /**
46
+ * [R2] app-server 控制面请求默认超时(ms)。依据:旧 zsw 实现 REQUEST_TIMEOUT_MS=15s
47
+ * (60+ fake-server 用例 + 真机 e2e 验证值);R5 probe 冒烟用独立更短预算,不走本值。
48
+ */
49
+ export const ZCODE_APPSERVER_REQUEST_TIMEOUT_MS = 15_000;
50
+
51
+ /**
52
+ * [R2] 连接崩溃错误信息附带的 stderr 尾部长度(字符)。设计 zcode-engine-appserver-
53
+ * resident.md §3.1 失败路径 2 / §3.3 错误规格表「进程意外退出」行:stderr 尾 400 字符。
54
+ */
55
+ export const ZCODE_APPSERVER_STDERR_TAIL_CHARS = 400;
56
+
57
+ /**
58
+ * [R2] stderr 滚动缓冲上限(字符):只保最近内容供崩溃诊断。旧 zsw 实现同值 2048。
59
+ */
60
+ export const ZCODE_APPSERVER_STDERR_TAIL_BUFFER_CHARS = 2048;
61
+
62
+ /**
63
+ * [R3] 终态判定后 session/read 兜底拉取的超时(ms)。read 是全文权威来源(不变量 1
64
+ * 的双来源之二),失败不抛——降级收尾帧/delta 聚合。旧 zsw 实现 READ_TIMEOUT_MS=5000。
65
+ */
66
+ export const ZCODE_APPSERVER_TURN_READ_TIMEOUT_MS = 5_000;
67
+
68
+ /**
69
+ * [R3] 任务收尾 session/close 的控制面超时(ms,best-effort——失败只 warn 不抛)。
70
+ * 旧 zsw 实现 RELEASE_CLOSE_TIMEOUT_MS=1500(wave2 D2,同值同语义)。
71
+ */
72
+ export const ZCODE_APPSERVER_TURN_CLOSE_TIMEOUT_MS = 1_500;
73
+
74
+ /**
75
+ * [R3] 一轮终态等待的缺省预算(ms)。终态双保险(turn.terminal 权威 + 收尾帧宽松
76
+ * 匹配防洪堤)之后的最后一道:全漂移/进程假死时不挂死任务。R4 接线后任务级
77
+ * timeout / abort 链可显式传入更贴任务的值。
78
+ */
79
+ export const ZCODE_APPSERVER_TURN_DEFAULT_TIMEOUT_MS = 300_000;
80
+
81
+ // ============================================================
82
+ // [R4] app-server 常驻 HOME(D7)/ abort 链(D3)/ 孤儿自愈(D6③)
83
+ // ============================================================
84
+
85
+ /**
86
+ * [R4 D7] 常驻 HOME 的池 key(固定名)。锚定不变量 poolDir == HOME == db 所在目录:
87
+ * HOME = resolvePoolDir(engineDataDir, 'zcode', 'home-appserver'),SQLite 落
88
+ * HOME/.zcode/cli/db/db.sqlite,journal 同落该池目录。锁被活宿主持有时派生
89
+ * `home-appserver-2`… 后缀目录,handle.poolKey 记实际目录名。
90
+ */
91
+ export const ZCODE_APPSERVER_POOL_KEY = "home-appserver";
92
+
93
+ /** [R4 D7] 目录锁文件名(HOME 内;O_EXCL 创建,内容 {pid}=持锁宿主进程 pid)。 */
94
+ export const ZCODE_APPSERVER_LOCKFILE_NAME = "lockfile";
95
+
96
+ /** [R4 D6③/D7] app-server 进程 pidfile 文件名(HOME 内;与 lockfile.pid 严格分离)。 */
97
+ export const ZCODE_APPSERVER_PIDFILE_NAME = "appserver.pid";
98
+
99
+ /** [R4 D7] 目录锁心跳间隔(ms):仅刷新 lockfile mtime,不参与活持有否决。 */
100
+ export const ZCODE_APPSERVER_LOCK_HEARTBEAT_MS = 30_000;
101
+
102
+ /** [R4 D7] 派生目录后缀上限(home-appserver-2 … -N)——极端并发场景防无限循环。 */
103
+ export const ZCODE_APPSERVER_MAX_DERIVED_HOMES = 8;
104
+
105
+ /**
106
+ * [R4 D3] abort 链第一级:session/stop 的控制面超时(ms)。stop 失败/超时即落
107
+ * killChain(协议此时已不可信)。
108
+ */
109
+ export const ZCODE_APPSERVER_STOP_TIMEOUT_MS = 3_000;
110
+
111
+ /**
112
+ * [R4 D3] abort 链第二级:stop 送达后的终态确认 grace 窗口(ms)。窗口内终态
113
+ * 到达 → 不杀共享进程;超时 → killChain 连坐。
114
+ */
115
+ export const ZCODE_APPSERVER_ABORT_GRACE_MS = 3_000;
116
+
117
+ /** [R4 D6③] 孤儿回收的 SIGTERM→SIGKILL grace 窗口(ms)。 */
118
+ export const ZCODE_APPSERVER_PIDFILE_GRACE_MS = 2_000;
119
+
120
+ /**
121
+ * [R4/R5] 执行模式定向 env(appserver | spawn)。定向时不探不降;缺省走 app-server
122
+ * (R5 降级链在缺省路径插 probe 门控)。spawn 降级路径(D2 兜底)继续用
123
+ * home-<provider>-<model> 池。
124
+ */
125
+ export const ZCODE_MODE_ENV_VAR = "XYZ_ZCODE_MODE";
126
+
127
+ /**
128
+ * [R4] app-server 内部错误码中「模型配置缺失」的归类判据(A.3:-32603 内部错误族,
129
+ * 消息含 "Model config is missing"——错误规格表第 2 行:报 engine_credential_missing)。
130
+ */
131
+ export const ZCODE_APPSERVER_ERR_MODEL_CONFIG_MISSING = -32603;
132
+
133
+ // ============================================================
134
+ // [R5] 降级链(D2)/ probe 冒烟(D8)
135
+ // ============================================================
136
+
137
+ /**
138
+ * [R5 D8] 协议冒烟探针的总预算(ms):独立短命连接上 create 探针会话 → close →
139
+ * shutdown 的全部时间窗。不发模型请求(无 session/send)、不产生费用。超预算按
140
+ * 探针失败处理(错误规格表末行:结论 failed → 降级 spawn)。
141
+ */
142
+ export const ZCODE_APPSERVER_PROBE_BUDGET_MS = 10_000;
143
+
144
+ /**
145
+ * [R5 D2] 漂移类 RPC 错误码(错误规格表第 1 行:-32601 方法不存在 / -32602 参数
146
+ * 变形)。运行中命中任一 → 归档 protocol-drift:首任务降级 spawn 重跑一次 + 后续
147
+ * 任务直走 spawn(降级标志内存化,进程重启后重探重建)。-32004/-32010/-32603 不在
148
+ * 此列(任务失败上报 / 凭据缺失归类,均不降级)。
149
+ */
150
+ const RPC_METHOD_NOT_FOUND = -32601;
151
+ const RPC_INVALID_PARAMS = -32602;
152
+ export const ZCODE_APPSERVER_DRIFT_RPC_CODES = [RPC_METHOD_NOT_FOUND, RPC_INVALID_PARAMS] as const;
153
+
154
+ /**
155
+ * [R5] app-server 内部错误码「会话忙」:send 时该会话已有轮在跑(busy 不排队不打断)。
156
+ * 单会话一任务是结构保证,运行中命中即 bug(错误文案引导上报 sessionId 与 state 流水)。
157
+ */
158
+ export const ZCODE_APPSERVER_ERR_BUSY_SESSION = -32010;
159
+
160
+ /**
161
+ * [R5 D8] 探针连接的 env 标记:探针用独立短命连接(不污染主连接),但 env 与主连接
162
+ * 同源(同一常驻 HOME)。此标记供 fake/诊断侧区分「探针进程」与「常驻进程」(测试
163
+ * 断言探针帧序、故障注入只命中探针或只命中主连接的判据)。
164
+ */
165
+ export const ZCODE_APPSERVER_PROBE_CONN_ENV = "ZCODE_APPSERVER_PROBE_CONN";
166
+
167
+ /**
168
+ * [R5] 崩溃收割确认的兜底窗口(ms):killChain 在 `exit` 事件 resolve,而连接
169
+ * finalize(onClose → 在途 turn 崩溃收割)挂 `close` 事件——channel 退订前等 onClose
170
+ * 触发,本窗口兜底防 `close` 永不到达时 dispose/teardown 挂死。
171
+ */
172
+ export const ZCODE_APPSERVER_HARVEST_GRACE_MS = 1_000;
@@ -1,15 +1,25 @@
1
1
  // src/execution/engine/engines/zcode/golden-sample.ts
2
2
  //
3
- // probe「干跑校验」的内嵌 golden 样本(D7:zcode 无官方契约,探针必须做已知样本
4
- // 回归——对 embed 样本跑 parser,格式漂移在入口拦截而非运行中静默挂死)。
3
+ // golden 语料内嵌副本(双通道并存,R3 扩充):
5
4
  //
6
- // 来源:2026-08-25 验收前置门真机实录(zcode 0.16.5),完整原文与采集元数据见
7
- // __tests__/__fixtures__/zcode-golden-spawn.json。为什么不直接读 fixture 文件:
8
- // probe 在生产运行(npm 包安装形态)也要可用,__tests__ 不在稳定交付面内——内嵌
9
- // 副本以代码为交付载体;两处不一致时以 fixture 为采集 SSOT、此处为运行时副本,
10
- // 更新样本需同步改两处(conformance golden 回放层会 diff 校验)。
5
+ // spawn 单 JSON(D7):probe「干跑校验」的内嵌 golden 样本——zcode 无官方契约,
6
+ // 探针必须做已知样本回归(对 embed 样本跑 parser,格式漂移在入口拦截而非运行中
7
+ // 静默挂死)。来源:2026-08-25 验收前置门真机实录(zcode 0.16.5),完整原文与采集
8
+ // 元数据见 __tests__/__fixtures__/zcode-golden-spawn.json。为什么不直接读 fixture
9
+ // 文件:probe 在生产运行(npm 包安装形态)也要可用,__tests__ 不在稳定交付面内
10
+ // ——内嵌副本以代码为交付载体。spawn 降级路径(设计 D2 保留)持续消费本语料
11
+ // (zcode-engine probe 干跑 + conformance spawn 回归),故 R3 帧序列语料落地为
12
+ // 并存新增而非删除替换——漂移防御的主力语料已切换到 ②(登记于 impl-plan 偏差表)。
13
+ //
14
+ // ② app-server NDJSON 帧序列(R3,D8-②):常驻通道的 golden 帧序列语料,四类样本
15
+ // (create 应答 / 推送流 / 终态帧 / read 应答,附录 A.2 任务生命周期帧序)。
16
+ // 来源:按 A.2 协议权威 + 旧 zsw 实现真机抓包形态合成(非实录,fixture _meta
17
+ // 如实标注);真机冒烟后替换。双副本 diff 机制沿用 ① 的先例:fixture
18
+ // __tests__/__fixtures__/zcode-golden-appserver.json 是采集 SSOT,此处为运行时
19
+ // 副本,更新样本需同步改两处(session-channel 测试 diff 校验;R6 conformance
20
+ // 迁移后由 golden 回放层接管)。
11
21
 
12
- /** 实录 stdout 原文(单 JSON:sessionId/traceId/turnId/response/usage/eventCount/projection)。 */
22
+ /** [①spawn] 实录 stdout 原文(单 JSON:sessionId/traceId/turnId/response/usage/eventCount/projection)。 */
13
23
  export const ZCODE_GOLDEN_STDOUT = `{
14
24
  "sessionId": "sess_35852a0f-1302-4e20-9e48-87f47527abe3",
15
25
  "traceId": "9fffaebd-749e-468b-af3f-2a89e3347785",
@@ -37,3 +47,39 @@ export const ZCODE_GOLDEN_STDOUT = `{
37
47
  }
38
48
  }
39
49
  `;
50
+
51
+ // ============================================================
52
+ // [②app-server] NDJSON 帧序列语料(R3,附录 A.2 帧序逐字)
53
+ // ============================================================
54
+
55
+ /** 四类样本的结构(与 zcode-golden-appserver.json 的 frames 字段一一对应)。 */
56
+ export interface AppServerGoldenFrames {
57
+ /** ① session/create 应答帧(NDJSON 单行;projection.sessionId 恒 "unknown" 勿用)。 */
58
+ createResponse: string;
59
+ /** ④ 推送流帧(NDJSON 逐行:state.updated / stream.chunk 无文本 / session/event delta 有文本)。 */
60
+ pushStream: string[];
61
+ /** ⑤ 终态帧(NDJSON 逐行:v4 telemetry turn.terminal 权威 + session/event 收尾帧全文/usage)。 */
62
+ terminal: string[];
63
+ /** ⑥ session/read 应答帧(NDJSON 单行:messages[].parts[],text 全文 + step-finish tokens)。 */
64
+ readResponse: string;
65
+ }
66
+
67
+ /** [②app-server] golden 帧序列内嵌副本(采集 SSOT = zcode-golden-appserver.json,双副本 diff 防漂移)。 */
68
+ export const ZCODE_APPSERVER_GOLDEN: AppServerGoldenFrames = {
69
+ createResponse:
70
+ '{"session":{"sessionId":"sess_golden_r3_01"},"projection":{"sessionId":"unknown","status":"idle","turnCount":0,"totalTokenCount":0,"contextUsed":0,"contextWindow":1000000}}',
71
+ pushStream: [
72
+ '{"method":"state.updated","params":{"sessionId":"sess_golden_r3_01","patch":{"status":"running"},"reason":"prompt_started"}}',
73
+ '{"method":"v4/telemetry/event","params":{"kind":"stream.chunk","channel":"text","chunkLength":6,"firstChunk":true,"assistantMessageId":"msg_golden_r3_01"}}',
74
+ '{"method":"session/event","params":{"sessionId":"sess_golden_r3_01","payload":{"delta":"你好","assistantMessageId":"msg_golden_r3_01"}}}',
75
+ '{"method":"v4/telemetry/event","params":{"kind":"stream.chunk","channel":"text","chunkLength":1,"firstChunk":false,"assistantMessageId":"msg_golden_r3_01"}}',
76
+ '{"method":"session/event","params":{"sessionId":"sess_golden_r3_01","payload":{"delta":",","assistantMessageId":"msg_golden_r3_01"}}}',
77
+ '{"method":"session/event","params":{"sessionId":"sess_golden_r3_01","payload":{"delta":"任务完成","assistantMessageId":"msg_golden_r3_01"}}}',
78
+ ],
79
+ terminal: [
80
+ '{"method":"v4/telemetry/event","params":{"kind":"turn.terminal","status":"success"}}',
81
+ '{"method":"session/event","params":{"sessionId":"sess_golden_r3_01","payload":{"response":"你好,任务完成","usage":{"inputTokens":12599,"outputTokens":17}}}}',
82
+ ],
83
+ readResponse:
84
+ '{"messages":[{"info":{"role":"user"},"parts":[{"type":"text","text":"做点什么"}]},{"info":{"role":"assistant"},"parts":[{"type":"text","text":"你好"},{"type":"text","text":",任务完成"},{"type":"step-finish","tokens":{"input":12599,"output":17,"reasoning":0,"cache":512,"total":12616}}]}]}',
85
+ };
@@ -16,12 +16,16 @@
16
16
  // 同一 HOME 但模型不同时,config.json 的 model.main 会出现「后写覆盖先写」的串池——
17
17
  // zsub 的 per-model HOME 池正是防这个;本引擎以 provider+model 为隔离粒度,agent 维度
18
18
  // 的池化留给宿主 refs.json(W3 对齐点)。
19
+ //
20
+ // [R4 D7] app-server 常驻 HOME 语义(锁/派生/pidfile 孤儿回收/allProviders 引导/
21
+ // 凭据内容 hash 刷新)拆至同目录 appserver-home.ts——单一关注点分立。
19
22
 
20
23
  import * as fs from "node:fs";
21
24
  import * as os from "node:os";
22
25
  import * as path from "node:path";
23
26
 
24
27
  import { resolvePoolDir } from "../../paths.ts";
28
+ import { writeAtomicFileSync } from "../../../../shared/atomic-write.ts";
25
29
  import {
26
30
  ZCODE_FALLBACK_DEFAULT_MODEL,
27
31
  ZCODE_POOL_CONFIG_SUFFIX,
@@ -67,16 +71,16 @@ interface SourceConfig {
67
71
  }
68
72
 
69
73
  /** unknown 的 Record 窄化 guard(替代 as 全可选断言——taste/no-unsafe-cast)。 */
70
- function isRecord(v: unknown): v is Record<string, unknown> {
74
+ export function isRecord(v: unknown): v is Record<string, unknown> {
71
75
  return typeof v === "object" && v !== null && !Array.isArray(v);
72
76
  }
73
77
 
74
78
  /** provider 条目一律按 ZcodeProviderEntry 消费(索引签名形态,无需逐键校验)。 */
75
- function isProviderEntry(v: unknown): v is ZcodeProviderEntry {
79
+ export function isProviderEntry(v: unknown): v is ZcodeProviderEntry {
76
80
  return isRecord(v);
77
81
  }
78
82
 
79
- function readSourceConfig(absPath: string): SourceConfig {
83
+ export function readSourceConfig(absPath: string): SourceConfig {
80
84
  const empty: SourceConfig = { providers: new Map(), mtimeMs: 0 };
81
85
  let raw: string;
82
86
  try {
@@ -119,7 +123,12 @@ function providerOf(ref: string): string {
119
123
  return ref.slice(0, ref.lastIndexOf("/"));
120
124
  }
121
125
 
122
- function hasApiKey(entry: ZcodeProviderEntry): boolean {
126
+ /** [R4] 规范化全名 provider/model → create 参数的 per-session model 拆分(A.2 ① strict 对象)。 */
127
+ export function splitZcodeModelRef(modelRef: string): { providerId: string; modelId: string } {
128
+ return { providerId: providerOf(modelRef), modelId: modelShort(modelRef) };
129
+ }
130
+
131
+ export function hasApiKey(entry: ZcodeProviderEntry): boolean {
123
132
  const key = entry.options?.apiKey;
124
133
  return typeof key === "string" && key !== "";
125
134
  }
@@ -129,12 +138,16 @@ export interface ZcodeSourcePaths {
129
138
  v2ConfigPath?: string;
130
139
  }
131
140
 
132
- function defaultV2ConfigPath(): string {
141
+ export function defaultV2ConfigPath(): string {
133
142
  return path.join(os.homedir(), ...ZCODE_V2_CONFIG_PATH_SUFFIX);
134
143
  }
135
144
 
136
- /** 短名(无 provider 前缀)解析的默认 provider(zsub DEFAULT_PROVIDER_ID 同构)。 */
137
- const DEFAULT_PROVIDER_ID = "builtin:bigmodel-coding-plan";
145
+ /**
146
+ * 短名(无 provider 前缀)解析的默认 provider(zsub DEFAULT_PROVIDER_ID 同构)。
147
+ * 导出(sink 设计 U1 模型切分四件之一):barrel re-export 供第三宿主模型路由消费,
148
+ * 实现体内聚本文件不挪。
149
+ */
150
+ export const DEFAULT_PROVIDER_ID = "builtin:bigmodel-coding-plan";
138
151
 
139
152
  /**
140
153
  * 短名模型(如 "GLM-5.3")的默认 provider 决策。让位条件(对齐点⑦):显式默认引擎
@@ -297,7 +310,7 @@ function homeNeedsBootstrap(configPath: string, sourceMtimeMs: number): boolean
297
310
  }
298
311
 
299
312
  /** 池 config.json 缩进(人读友好——与 zsub 产出的文件形态一致)。 */
300
- const CONFIG_INDENT_SPACES = 2;
313
+ export const CONFIG_INDENT_SPACES = 2;
301
314
 
302
315
  /**
303
316
  * 引导隔离 HOME 的 provider 配置(spawn 前调用)。
@@ -342,22 +355,12 @@ export function prepareZcodeHome(opts: {
342
355
  const hitSourceMtime = v2.mtimeMs;
343
356
  let wroteConfig = false;
344
357
  if (homeNeedsBootstrap(configPath, hitSourceMtime)) {
345
- fs.mkdirSync(path.dirname(configPath), { recursive: true });
346
358
  const payload = JSON.stringify({ model: { main: modelRef }, provider: { [provider]: entry } }, null, CONFIG_INDENT_SPACES);
347
- const tmp = `${configPath}.tmp-${process.pid}-${Date.now()}`;
348
- try {
349
- fs.writeFileSync(tmp, payload, "utf8");
350
- fs.renameSync(tmp, configPath);
351
- } finally {
352
- // rename 成功后 tmp 已不存在;失败时清残留,避免污染 HOME 目录
353
- try {
354
- if (fs.existsSync(tmp)) fs.unlinkSync(tmp);
355
- } catch (err) {
356
- // rename 失败路径的残留清理是 best-effort——记录后继续(tmp 文件不参与读取)
357
- void err;
358
- }
359
- }
359
+ // tmp+rename 原子写(shared/atomic-write 统一原语,U6b 迁移——rename 失败时
360
+ // 原语清残留 tmp,避免污染 HOME 目录;tmp 文件不参与读取,best-effort 语义不变)
361
+ writeAtomicFileSync(configPath, payload);
360
362
  wroteConfig = true;
361
363
  }
362
364
  return { modelRef, poolKey, homeDir, configPath, wroteConfig };
363
365
  }
366
+