@zhushanwen/subagent-core 0.4.0 → 0.6.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 (309) hide show
  1. package/dist/{chunk-4KN4TTG7.js → chunk-43ONBFZX.js} +1 -1
  2. package/dist/{chunk-X7SZ5HLQ.js → chunk-V3VHZ2VX.js} +20 -27
  3. package/dist/execution/engine/engines/zcode/constants.cjs +29 -41
  4. package/dist/execution/engine/engines/zcode/constants.d.cts +65 -53
  5. package/dist/execution/engine/engines/zcode/constants.d.ts +65 -53
  6. package/dist/execution/engine/engines/zcode/constants.js +17 -27
  7. package/dist/execution/engine/engines/zcode/reader.d.cts +2 -1
  8. package/dist/execution/engine/engines/zcode/reader.d.ts +2 -1
  9. package/dist/execution/engine/engines/zcode/reader.js +2 -2
  10. package/dist/index.cjs +17100 -14082
  11. package/dist/index.d.cts +5336 -4033
  12. package/dist/index.d.ts +5336 -4033
  13. package/dist/index.js +17020 -14055
  14. package/dist/{types-DpUO16pj.d.cts → types-C3fE3R9x.d.cts} +280 -112
  15. package/dist/{types-DpUO16pj.d.ts → types-C3fE3R9x.d.ts} +280 -112
  16. package/dist.bundle/index.cjs +34933 -0
  17. package/package.json +3 -3
  18. package/src/__tests__/agent-opts-resolver-schema-prompt.test.ts +0 -1
  19. package/src/__tests__/append-system-prompt-assembly.test.ts +8 -7
  20. package/src/__tests__/fr4-get-state-handshake.test.ts +2 -2
  21. package/src/__tests__/m2-append-content-probe.test.ts +0 -1
  22. package/src/__tests__/manifest-store.test.ts +10 -9
  23. package/src/__tests__/record-store-cache.test.ts +0 -2
  24. package/src/__tests__/record-store-index.test.ts +1 -2
  25. package/src/__tests__/review-fix-loop-script.test.ts +4 -2
  26. package/src/__tests__/review-fix-loop-utils.test.ts +10 -10
  27. package/src/__tests__/robustness-low-batch1.test.ts +6 -5
  28. package/src/__tests__/robustness-medium-batch1.test.ts +2 -2
  29. package/src/__tests__/robustness-medium-batch2.test.ts +17 -6
  30. package/src/__tests__/robustness-medium-batch4.test.ts +2 -2
  31. package/src/__tests__/session-runner.test.ts +1 -1
  32. package/src/core/__tests__/host-services.test.ts +2 -2
  33. package/src/core/__tests__/logger.test.ts +1 -1
  34. package/src/core/error-message.ts +9 -0
  35. package/src/core/host-services.ts +21 -5
  36. package/src/core/notify-ports.ts +18 -5
  37. package/src/execution/__tests__/agent-profile.test.ts +4 -4
  38. package/src/execution/__tests__/agent-registry.test.ts +370 -0
  39. package/src/execution/__tests__/agent-result-mapper.test.ts +18 -2
  40. package/src/execution/__tests__/agents-assembly.test.ts +2 -2
  41. package/src/execution/__tests__/alive-store.test.ts +1 -1
  42. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +6 -6
  43. package/src/execution/__tests__/chat-engine-routing.test.ts +68 -33
  44. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +4 -4
  45. package/src/execution/__tests__/cold-resurrect.test.ts +283 -0
  46. package/src/execution/__tests__/collect-budget.test.ts +291 -0
  47. package/src/execution/__tests__/collect-coordinator-service.test.ts +327 -0
  48. package/src/execution/__tests__/collect-coordinator.test.ts +371 -0
  49. package/src/execution/__tests__/collect-mixed-dispatch.test.ts +262 -0
  50. package/src/execution/__tests__/config-collect-sync.test.ts +120 -0
  51. package/src/execution/__tests__/config.test.ts +1 -1
  52. package/src/execution/__tests__/delivery-methods.test.ts +75 -62
  53. package/src/execution/__tests__/descendant-sweep-guards.test.ts +220 -0
  54. package/src/execution/__tests__/descendant-sweep.test.ts +6 -6
  55. package/src/execution/__tests__/dialog-queue.test.ts +2 -2
  56. package/src/execution/__tests__/engine-model-validation.test.ts +741 -0
  57. package/src/execution/__tests__/epipe-fallback.test.ts +29 -24
  58. package/src/execution/__tests__/execute-and-await-worktree.test.ts +21 -91
  59. package/src/execution/__tests__/execute-nesting.test.ts +34 -188
  60. package/src/execution/__tests__/execution-record.test.ts +217 -60
  61. package/src/execution/__tests__/execution-runtime-face.test.ts +5 -5
  62. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +4 -4
  63. package/src/execution/__tests__/finalize-record.test.ts +173 -17
  64. package/src/execution/__tests__/finalized-marker.test.ts +1 -1
  65. package/src/execution/__tests__/gc-timer.test.ts +56 -3
  66. package/src/execution/__tests__/get-record-for-action-restart.test.ts +12 -12
  67. package/src/execution/__tests__/get-state-handshake.test.ts +1 -1
  68. package/src/execution/__tests__/helpers/mock-extension-api.ts +1 -1
  69. package/src/execution/__tests__/helpers/session-runner-mocks.ts +113 -0
  70. package/src/execution/__tests__/helpers/spawn-mock.ts +150 -3
  71. package/src/execution/__tests__/helpers/subagent-service-mocks.ts +137 -0
  72. package/src/execution/__tests__/keep-alive-no-progress.test.ts +50 -148
  73. package/src/execution/__tests__/kill-all-escalation.test.ts +2 -2
  74. package/src/execution/__tests__/lifecycle-predicates.test.ts +1 -2
  75. package/src/execution/__tests__/manifest-parentid.test.ts +4 -4
  76. package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +1 -1
  77. package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +1 -1
  78. package/src/execution/__tests__/model-resolver.test.ts +2 -2
  79. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +23 -121
  80. package/src/execution/__tests__/nested-visibility.test.ts +2 -0
  81. package/src/execution/__tests__/notify-batch.test.ts +500 -0
  82. package/src/execution/__tests__/notify-ledger.test.ts +1000 -18
  83. package/src/execution/__tests__/output-collector.test.ts +117 -6
  84. package/src/execution/__tests__/pi-invocation.test.ts +36 -4
  85. package/src/execution/__tests__/record-entry-collect.test.ts +102 -0
  86. package/src/execution/__tests__/record-store.test.ts +10 -9
  87. package/src/execution/__tests__/records-cwd-isolation.test.ts +2 -2
  88. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +29 -132
  89. package/src/execution/__tests__/recursive-visibility-env.test.ts +55 -179
  90. package/src/execution/__tests__/relay-env.test.ts +12 -1
  91. package/src/execution/__tests__/rpc-mode.test.ts +2 -2
  92. package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +387 -0
  93. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +15 -9
  94. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +4 -4
  95. package/src/execution/__tests__/run-spawn-edges.test.ts +17 -15
  96. package/src/execution/__tests__/run-spawn-integration.test.ts +2 -2
  97. package/src/execution/__tests__/run-spawn-resume.test.ts +2 -2
  98. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +2 -2
  99. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +4 -4
  100. package/src/execution/__tests__/service-kill-escalation.test.ts +7 -5
  101. package/src/execution/__tests__/session-context-resolver.test.ts +0 -2
  102. package/src/execution/__tests__/session-file-gc.test.ts +36 -1
  103. package/src/execution/__tests__/session-pending.test.ts +257 -14
  104. package/src/execution/__tests__/session-reconstructor.test.ts +366 -15
  105. package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +1 -1
  106. package/src/execution/__tests__/session-runner-close-prune.test.ts +2 -2
  107. package/src/execution/__tests__/session-runner-dispatch.test.ts +489 -0
  108. package/src/execution/__tests__/session-runner-epipe.test.ts +3 -3
  109. package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +5 -4
  110. package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +290 -0
  111. package/src/execution/__tests__/session-runner-schema-env.test.ts +7 -5
  112. package/src/execution/__tests__/settled-watchdog.test.ts +282 -47
  113. package/src/execution/__tests__/spawn-args.test.ts +11 -10
  114. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +26 -23
  115. package/src/execution/__tests__/spawn-event-adapter.test.ts +3 -3
  116. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +5 -4
  117. package/src/execution/__tests__/spawned-children.test.ts +2 -1
  118. package/src/execution/__tests__/start-collect-guard.test.ts +255 -0
  119. package/src/execution/__tests__/start-sync-model-guard.test.ts +5 -5
  120. package/src/execution/__tests__/stdin-writer.test.ts +6 -4
  121. package/src/execution/__tests__/stream-sink-retirement.test.ts +6 -6
  122. package/src/execution/__tests__/subagent-actions-core.test.ts +48 -22
  123. package/src/execution/__tests__/subagent-service-message-close.test.ts +29 -26
  124. package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +21 -8
  125. package/src/execution/__tests__/subagent-service-notify-gate.test.ts +27 -22
  126. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +30 -29
  127. package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +45 -20
  128. package/src/execution/__tests__/subagent-service.test.ts +37 -30
  129. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +88 -12
  130. package/src/execution/__tests__/subprocess-agent-runner-timeout.test.ts +75 -0
  131. package/src/execution/__tests__/subprocess-agent-runner.test.ts +22 -20
  132. package/src/execution/__tests__/sync-collect-recovery.test.ts +1117 -0
  133. package/src/execution/__tests__/temp-prompt.test.ts +1 -1
  134. package/src/execution/__tests__/timeout-integration.test.ts +6 -5
  135. package/src/execution/__tests__/tombstone-store.test.ts +1 -1
  136. package/src/execution/__tests__/turn-limiter-semantics.test.ts +1 -1
  137. package/src/execution/__tests__/turn-limiter.test.ts +1 -1
  138. package/src/execution/__tests__/ui-request-handler-factory.test.ts +12 -6
  139. package/src/execution/__tests__/ui-request-handler.test.ts +4 -3
  140. package/src/execution/__tests__/ui-request-queue.test.ts +142 -2
  141. package/src/execution/__tests__/worktree-git-ops.test.ts +1 -1
  142. package/src/execution/__tests__/worktree-manager.test.ts +14 -5
  143. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +4 -3
  144. package/src/execution/__tests__/worktree-reconcile-aging.test.ts +2 -2
  145. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +1 -1
  146. package/src/execution/__tests__/worktree-registry.test.ts +1 -1
  147. package/src/execution/agent-registry.ts +74 -30
  148. package/src/execution/agent-result-mapper.ts +3 -0
  149. package/src/execution/cold-resurrect.ts +199 -0
  150. package/src/execution/collect-coordinator.ts +200 -0
  151. package/src/execution/config.ts +77 -5
  152. package/src/execution/engine/__tests__/common/capability-gate.test.ts +91 -0
  153. package/src/execution/engine/__tests__/common/data-dir.test.ts +1 -1
  154. package/src/execution/engine/__tests__/common/event-journal.test.ts +1 -1
  155. package/src/execution/engine/__tests__/common/journal-wiring.test.ts +84 -0
  156. package/src/execution/engine/__tests__/common/kill-chain.test.ts +34 -7
  157. package/src/execution/engine/__tests__/common/persona-router.test.ts +4 -5
  158. package/src/execution/engine/__tests__/common/pool-manager.test.ts +213 -53
  159. package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +149 -0
  160. package/src/execution/engine/__tests__/common/session-view-service.test.ts +499 -0
  161. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +22 -112
  162. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +15 -28
  163. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +1 -1
  164. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +12 -12
  165. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +2 -2
  166. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +21 -82
  167. package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +4 -7
  168. package/src/execution/engine/__tests__/engine-discovery.test.ts +15 -3
  169. package/src/execution/engine/__tests__/model-prompt.test.ts +15 -3
  170. package/src/execution/engine/__tests__/registry.test.ts +4 -2
  171. package/src/execution/engine/__tests__/routing.test.ts +115 -6
  172. package/src/execution/engine/common/capability-gate.ts +92 -0
  173. package/src/execution/engine/common/journal-wiring.ts +97 -0
  174. package/src/execution/engine/common/kill-chain.ts +42 -10
  175. package/src/execution/engine/common/nesting-guard.ts +66 -0
  176. package/src/execution/engine/common/persona-router.ts +18 -8
  177. package/src/execution/engine/common/pool-manager.ts +332 -78
  178. package/src/execution/engine/common/session-view-service.ts +506 -0
  179. package/src/execution/engine/common/session-view-types.ts +125 -0
  180. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +174 -28
  181. package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +257 -0
  182. package/src/execution/{argv-mirror.ts → engine/engines/pi/argv-mirror.ts} +43 -21
  183. package/src/execution/{get-state-handshake.ts → engine/engines/pi/get-state-handshake.ts} +1 -1
  184. package/src/execution/{output-collector.ts → engine/engines/pi/output-collector.ts} +108 -19
  185. package/src/execution/engine/engines/pi/pi-engine.ts +434 -38
  186. package/src/execution/{pi-invocation.ts → engine/engines/pi/pi-invocation.ts} +2 -2
  187. package/src/execution/engine/engines/pi/reader.ts +11 -0
  188. package/src/execution/engine/engines/pi/registration.ts +4 -2
  189. package/src/execution/{session-runner.ts → engine/engines/pi/session-runner.ts} +617 -412
  190. package/src/execution/{spawn-event-adapter.ts → engine/engines/pi/spawn-event-adapter.ts} +75 -34
  191. package/src/execution/{stdin-writer.ts → engine/engines/pi/stdin-writer.ts} +10 -9
  192. package/src/execution/{temp-prompt.ts → engine/engines/pi/temp-prompt.ts} +2 -2
  193. package/src/execution/{turn-limiter.ts → engine/engines/pi/turn-limiter.ts} +1 -1
  194. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +54 -27
  195. package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +321 -0
  196. package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +13 -12
  197. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +7 -210
  198. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +6 -110
  199. package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +247 -0
  200. package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +451 -0
  201. package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +20 -8
  202. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +77 -110
  203. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +26 -320
  204. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +210 -0
  205. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +353 -0
  206. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +282 -0
  207. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +372 -0
  208. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +48 -148
  209. package/src/execution/engine/engines/zcode/appserver-launcher.ts +167 -0
  210. package/src/execution/engine/engines/zcode/connection.ts +24 -11
  211. package/src/execution/engine/engines/zcode/constants.ts +75 -71
  212. package/src/execution/engine/engines/zcode/golden-sample.ts +8 -46
  213. package/src/execution/engine/engines/zcode/parser.ts +12 -346
  214. package/src/execution/engine/engines/zcode/preparer.ts +12 -143
  215. package/src/execution/engine/engines/zcode/session-channel.ts +351 -39
  216. package/src/execution/engine/engines/zcode/zcode-engine.ts +665 -760
  217. package/src/execution/engine/host-task-spec.ts +32 -36
  218. package/src/execution/engine/model-validation.ts +177 -0
  219. package/src/execution/engine/port.ts +24 -6
  220. package/src/execution/engine/routing.ts +75 -1
  221. package/src/execution/engine/types.ts +30 -103
  222. package/src/execution/execution-record.ts +229 -144
  223. package/src/execution/finalize-record.ts +141 -99
  224. package/src/execution/idle-gc.ts +28 -0
  225. package/src/execution/lifecycle-predicates.ts +1 -1
  226. package/src/execution/notifier.ts +234 -25
  227. package/src/execution/notify-host.ts +232 -0
  228. package/src/execution/record-entry.ts +16 -0
  229. package/src/execution/record-store.ts +280 -103
  230. package/src/execution/round-settlement.ts +93 -0
  231. package/src/execution/session-file-gc.ts +96 -62
  232. package/src/execution/session-reconstructor.ts +256 -143
  233. package/src/execution/sessions-index.ts +117 -47
  234. package/src/execution/settled-watchdog.ts +264 -52
  235. package/src/execution/subagent-actions-core.ts +84 -28
  236. package/src/execution/subagent-service.ts +1225 -964
  237. package/src/execution/subprocess-agent-runner.ts +144 -97
  238. package/src/execution/sync-rebuild.ts +87 -0
  239. package/src/execution/types.ts +72 -0
  240. package/src/execution/ui-request-handler-factory.ts +102 -74
  241. package/src/execution/ui-request-queue.ts +50 -19
  242. package/src/index.ts +442 -316
  243. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +1 -1
  244. package/src/orchestration/__tests__/agent-call-stream.test.ts +2 -2
  245. package/src/orchestration/__tests__/args-validator.test.ts +14 -0
  246. package/src/orchestration/__tests__/config-loader.test.ts +1 -1
  247. package/src/orchestration/__tests__/error-recovery-rebuild-failure.test.ts +1 -1
  248. package/src/orchestration/__tests__/error-recovery-terminal-hardening.test.ts +11 -9
  249. package/src/orchestration/__tests__/execute-agent-call.test.ts +151 -11
  250. package/src/orchestration/__tests__/file-run-store-prune.test.ts +1 -1
  251. package/src/orchestration/__tests__/file-run-store-throttle.test.ts +1 -1
  252. package/src/orchestration/__tests__/file-run-store.test.ts +7 -6
  253. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +2 -2
  254. package/src/orchestration/__tests__/lifecycle-abort-broadcast-signal.test.ts +1 -1
  255. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +3 -3
  256. package/src/orchestration/__tests__/lifecycle.test.ts +7 -5
  257. package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +1 -1
  258. package/src/orchestration/__tests__/review-fix-loop-scriptpath-failfast.test.ts +1 -1
  259. package/src/orchestration/__tests__/run-snapshot.test.ts +8 -5
  260. package/src/orchestration/__tests__/script-generate.test.ts +5 -5
  261. package/src/orchestration/__tests__/script-lint.test.ts +17 -0
  262. package/src/orchestration/__tests__/skill-discovery.test.ts +2 -2
  263. package/src/orchestration/__tests__/test-mocks.ts +2 -0
  264. package/src/orchestration/__tests__/worker-exit-without-result.test.ts +7 -6
  265. package/src/orchestration/__tests__/worker-message-pump-finalize-run.test.ts +229 -0
  266. package/src/orchestration/__tests__/{error-recovery-handlers.test.ts → worker-message-pump-handlers.test.ts} +27 -19
  267. package/src/orchestration/__tests__/{error-recovery-postmessage-defense.test.ts → worker-message-pump-postmessage-defense.test.ts} +8 -8
  268. package/src/orchestration/__tests__/{error-recovery-serialize-failed-result.test.ts → worker-message-pump-serialize-failed-result.test.ts} +2 -2
  269. package/src/orchestration/__tests__/{error-recovery-workflow-call.test.ts → worker-message-pump-workflow-call.test.ts} +1 -1
  270. package/src/orchestration/__tests__/worker-pending-timeout-abort.test.ts +1 -1
  271. package/src/orchestration/__tests__/worker-script-builder.test.ts +1 -1
  272. package/src/orchestration/__tests__/workflow-files.test.ts +10 -10
  273. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +1 -1
  274. package/src/orchestration/__tests__/workflow-script-registry-impl.test.ts +1 -1
  275. package/src/orchestration/agent-opts-resolver.ts +1 -1
  276. package/src/orchestration/args-validator.ts +53 -31
  277. package/src/orchestration/execute-agent-call.ts +19 -73
  278. package/src/orchestration/launcher.ts +128 -81
  279. package/src/orchestration/lifecycle.ts +43 -45
  280. package/src/orchestration/models/ports.ts +4 -4
  281. package/src/orchestration/models/run-runtime.ts +2 -2
  282. package/src/orchestration/models/trace.ts +1 -1
  283. package/src/orchestration/models/types.ts +111 -22
  284. package/src/orchestration/models/workflow-run.ts +1 -1
  285. package/src/orchestration/script-lint.ts +91 -58
  286. package/src/orchestration/{error-recovery.ts → worker-message-pump.ts} +157 -150
  287. package/src/shared/__tests__/atomic-write.test.ts +1 -1
  288. package/src/shared/__tests__/meta-parser.test.ts +151 -0
  289. package/src/shared/__tests__/resource-discovery-host-roots.test.ts +5 -5
  290. package/src/shared/__tests__/resource-discovery.test.ts +258 -215
  291. package/src/shared/atomic-write.ts +12 -9
  292. package/src/shared/meta-parser.ts +158 -84
  293. package/src/shared/model-ref.ts +15 -2
  294. package/src/shared/resource-discovery.ts +9 -183
  295. package/src/shared/schema-jsonify.ts +1 -1
  296. package/workflows/review-fix-loop-utils.cjs +151 -89
  297. package/workflows/review-fix-loop-utils.d.cts +287 -0
  298. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
  299. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  300. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  301. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  302. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  303. package/src/execution/engine/engines/zcode/__tests__/preparer-appserver.test.ts +0 -387
  304. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -710
  305. package/src/execution/engine/engines/zcode/appserver-home.ts +0 -442
  306. package/src/execution/engine/engines/zcode/appserver-probe.ts +0 -141
  307. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  308. package/src/execution/execute-options-mapper.ts +0 -115
  309. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -288
@@ -1,107 +1,27 @@
1
1
  // src/execution/engine/engines/zcode/parser.ts
2
2
  //
3
- // ZcodeEngine parser(P3):stdout 有界收集 JSON 解析 → 合成 coarse AgentEvent
4
- // 流(设计 §3.3.7「批量引擎进程退出后一次性 emit 合成事件」形态)。TS 重写自 zsub
5
- // driver.jscreateBoundedLineBuffer / parseStdoutJson,机制保留:
6
- // - 有界双缓冲(头 4K + 64K):zcode response 可达数十 KB,无上限累加在长任务
7
- // 下爆内存;超限以「行」为单位丢弃,头尾各自保持可读。代价:单行 JSON 超过尾部
8
- // 窗口时无法完整解析——按错误路径处理(错误信息带尾部),内存安全优先。
9
- // - 容错解析:正常是单个 JSON 文档;混入日志行则截取首尾大括号间内容。
3
+ // ZcodeEngine usage 映射与 coarse 事件件(2026-09 收缩):CLI stdout 有界收集/
4
+ // JSON 解析/buildRunFailedMessage spawn 链删除(app-server 路径的终态来自
5
+ // session-channelread 兜底帧,不经 stdout 解析)。保留件:
6
+ // - ZcodeRawUsage / mapZcodeUsage / mapZcodeOutcomeUsage:原生 usage 形状
7
+ // 事件层(execution)与终态层(orchestration)AgentUsage(spawn 时代实测形状,
8
+ // app-server 收尾帧 usage 同形——session-channel 消费);
9
+ // - ZcodeTerminalPayload:app-server 轮成功态的载荷形态(turnResultToPayload 组装);
10
+ // - synthesizeCoarseEvents:终态合成最小事件序列(不变量:turn_end 最后、其前
11
+ // 至少一个 message_end)。
10
12
  //
11
13
  // 事件产出不变量(设计 §3.3.7,coarse 口径):turn_end 前至少一个 message_end;
12
14
  // message_end.usage 出现时为完整 AgentUsage 形状(缺数据给显式 0,不给残缺对象)。
13
15
 
14
- import type { Readable } from "node:stream";
15
-
16
16
  import type { AgentUsage as ExecutionAgentUsage } from "../../../types.ts";
17
17
  import type { AgentUsage as OutcomeAgentUsage } from "../../../../orchestration/models/types.ts";
18
18
  import type { AgentEvent } from "../../types.ts";
19
- import { ZCODE_ERROR_TAIL_CHARS } from "./constants.ts";
20
- import type { ZcodeLaunchedProcess } from "./launcher.ts";
21
19
 
22
20
  // ============================================================
23
- // 有界行缓冲(zsub createBoundedLineBuffer 移植)
21
+ // usage 映射(含运行时 guard——禁 any)
24
22
  // ============================================================
25
23
 
26
- export interface BoundedLineBuffer {
27
- push(chunk: string): void;
28
- flush(): void;
29
- text(): string;
30
- tail(n: number): string;
31
- }
32
-
33
- const DEFAULT_HEAD_BYTES = 4096;
34
- // eslint-disable-next-line no-magic-numbers -- 64KB = 64 * 1024 bytes
35
- const DEFAULT_TAIL_BYTES = 64 * 1024;
36
-
37
- export function createBoundedLineBuffer(opts: { headLimit?: number; tailLimit?: number } = {}): BoundedLineBuffer {
38
- const headLimit = opts.headLimit ?? DEFAULT_HEAD_BYTES;
39
- const tailLimit = opts.tailLimit ?? DEFAULT_TAIL_BYTES;
40
- let pending = "";
41
- let head = "";
42
- let headFull = false;
43
- const tailLines: string[] = [];
44
- let tailBytes = 0;
45
- let droppedBytes = 0;
46
-
47
- function addLine(line: string): void {
48
- if (!headFull) {
49
- if (head.length + line.length <= headLimit) {
50
- head += line;
51
- return;
52
- }
53
- headFull = true;
54
- }
55
- tailLines.push(line);
56
- tailBytes += line.length;
57
- // 超出尾部窗口:从最旧的行开始丢
58
- while (tailBytes > tailLimit && tailLines.length > 1) {
59
- const dropped = tailLines.shift()!;
60
- tailBytes -= dropped.length;
61
- droppedBytes += dropped.length;
62
- }
63
- // 单行超过整个尾部窗口:只保留该行结尾(JSON 的错误信息通常在末尾)
64
- if (tailBytes > tailLimit && tailLines.length === 1) {
65
- const over = tailBytes - tailLimit;
66
- tailLines[0] = tailLines[0]!.slice(over);
67
- tailBytes -= over;
68
- droppedBytes += over;
69
- }
70
- }
71
-
72
- return {
73
- push(chunk: string): void {
74
- pending += chunk;
75
- let nl: number;
76
- while ((nl = pending.indexOf("\n")) >= 0) {
77
- addLine(pending.slice(0, nl + 1));
78
- pending = pending.slice(nl + 1);
79
- }
80
- },
81
- flush(): void {
82
- if (pending !== "") {
83
- addLine(pending);
84
- pending = "";
85
- }
86
- },
87
- text(): string {
88
- this.flush();
89
- const mid =
90
- droppedBytes > 0 ? `\n[zcode-engine] 输出过长,头尾之间已丢弃 ${droppedBytes} 字节\n` : "";
91
- return head + mid + tailLines.join("");
92
- },
93
- tail(n: number): string {
94
- const t = this.text();
95
- return t.length > n ? t.slice(t.length - n) : t;
96
- },
97
- };
98
- }
99
-
100
- // ============================================================
101
- // 终 JSON 解析(含运行时 guard——禁 any)
102
- // ============================================================
103
-
104
- /** stdout 里的原生 usage 形状(2026-08-25 实测 0.16.5,字段名带 Tokens 后缀)。 */
24
+ /** 原生 usage 形状(2026-08-25 实测 0.16.5,字段名带 Tokens 后缀;app-server 收尾帧同形)。 */
105
25
  export interface ZcodeRawUsage {
106
26
  source?: unknown;
107
27
  modelRequestCount?: unknown;
@@ -113,27 +33,6 @@ export interface ZcodeRawUsage {
113
33
  reasoningTokens?: unknown;
114
34
  }
115
35
 
116
- /** 容错解析 stdout:直接 JSON.parse;失败则截取首尾大括号间内容再试。 */
117
- export function parseZcodeStdoutJson(stdout: string): unknown {
118
- const trimmed = stdout.trim();
119
- try {
120
- return JSON.parse(trimmed);
121
- } catch (err) {
122
- // 混入日志行等形态——吞掉异常继续首尾大括号容错提取(malformed 是降级输入不是错误态)
123
- void err;
124
- }
125
- const first = trimmed.indexOf("{");
126
- const last = trimmed.lastIndexOf("}");
127
- if (first >= 0 && last > first) {
128
- try {
129
- return JSON.parse(trimmed.slice(first, last + 1));
130
- } catch {
131
- return null;
132
- }
133
- }
134
- return null;
135
- }
136
-
137
36
  function finiteOr(v: unknown, fallback: number): number {
138
37
  const n = typeof v === "number" ? v : Number(v);
139
38
  return Number.isFinite(n) ? n : fallback;
@@ -177,7 +76,7 @@ function firstFinite(...vals: unknown[]): number {
177
76
  return 0;
178
77
  }
179
78
 
180
- /** JSON 的解析产物(引擎消费面——response 必须是 string 才算合法终态)。 */
79
+ /** 轮成功态的载荷形态(app-server 路径由 turnResultToPayload 组装:response string)。 */
181
80
  export interface ZcodeTerminalPayload {
182
81
  sessionId?: string;
183
82
  response: string;
@@ -189,111 +88,6 @@ export interface ZcodeTerminalPayload {
189
88
  turnCount?: number;
190
89
  }
191
90
 
192
- export type ZcodeTerminalParse =
193
- | { ok: true; payload: ZcodeTerminalPayload }
194
- | { ok: false; reason: string };
195
-
196
- /** 解析终 JSON 并做形状校验(sessionId/usage/turnCount 逐字段 guard)。 */
197
- export function parseZcodeTerminal(stdout: string): ZcodeTerminalParse {
198
- const parsed = parseZcodeStdoutJson(stdout);
199
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
200
- return { ok: false, reason: "stdout 不是 JSON 对象" };
201
- }
202
- const obj = parsed as Record<string, unknown>;
203
- if (typeof obj.response !== "string") {
204
- return { ok: false, reason: "终 JSON 缺 string 型 response 字段(zcode 格式漂移嫌疑)" };
205
- }
206
- const usage = mapZcodeUsage(obj.usage);
207
- const projection =
208
- typeof obj.projection === "object" && obj.projection !== null
209
- ? (obj.projection as Record<string, unknown>)
210
- : undefined;
211
- const outcomeUsage = mapZcodeOutcomeUsage(obj.usage, projection);
212
- const turnCountRaw = projection?.turnCount;
213
- return {
214
- ok: true,
215
- payload: {
216
- response: obj.response,
217
- ...(typeof obj.sessionId === "string" ? { sessionId: obj.sessionId } : {}),
218
- ...(usage !== undefined ? { usage } : {}),
219
- ...(outcomeUsage !== undefined ? { outcomeUsage } : {}),
220
- ...(typeof turnCountRaw === "number" && Number.isFinite(turnCountRaw) ? { turnCount: turnCountRaw } : {}),
221
- },
222
- };
223
- }
224
-
225
- // ============================================================
226
- // 输出收集(进程退出 + 有界缓冲终态)
227
- // ============================================================
228
-
229
- export interface ZcodeCollectedOutput {
230
- exitCode: number | null;
231
- signal?: string;
232
- /** 有界 stdout 全文(头 4K + 尾 64K,中间丢弃段有标记行)。 */
233
- stdoutText: string;
234
- /** stderr 尾部(有界 4K)。 */
235
- stderrTail: string;
236
- }
237
-
238
- /**
239
- * 等待可读流终止(end/close/error 任一,1s 超时兜底)。
240
- * 为什么不能只 await 进程退出:宿主在微任务上下文里续跑时(vitest / async 编排链),
241
- * 进程 exited 的 promise 续跑可能先于流 data/end 事件的 nextTick 冲刷——直接读缓冲
242
- * 会拿到空串。等流终止事件是确定性的「数据已收完」判据;超时兜底防流异常挂起。
243
- */
244
- /** 流终止等待超时(兜底挂起流;比杀链 grace 短一个量级即可)。 */
245
- const DRAIN_TIMEOUT_MS = 1_000;
246
-
247
- function drainReadable(stream: Readable): Promise<void> {
248
- return new Promise((resolve) => {
249
- if (stream.readableEnded || stream.destroyed) {
250
- resolve();
251
- return;
252
- }
253
- let settled = false;
254
- const finish = (): void => {
255
- if (settled) return;
256
- settled = true;
257
- stream.removeListener("end", finish);
258
- stream.removeListener("close", finish);
259
- stream.removeListener("error", finish);
260
- clearTimeout(timer);
261
- resolve();
262
- };
263
- stream.once("end", finish);
264
- stream.once("close", finish);
265
- stream.once("error", finish);
266
- const timer = setTimeout(finish, DRAIN_TIMEOUT_MS);
267
- if (typeof timer.unref === "function") timer.unref();
268
- });
269
- }
270
-
271
- /** 消费进程输出直到退出(事件 emit 前的收集段——终态解析素材)。 */
272
- export async function collectZcodeOutput(
273
- proc: Pick<ZcodeLaunchedProcess, "stdout" | "stderr" | "exited">,
274
- ): Promise<ZcodeCollectedOutput> {
275
- const outBuf = createBoundedLineBuffer();
276
- // stderr 只做诊断:不进解析路径,尾部 4K 足够
277
- const errBuf = createBoundedLineBuffer({ headLimit: 0, tailLimit: DEFAULT_TAIL_BYTES });
278
- proc.stdout.on("data", (d: Buffer | string) => {
279
- outBuf.push(typeof d === "string" ? d : d.toString("utf8"));
280
- });
281
- proc.stderr.on("data", (d: Buffer | string) => {
282
- errBuf.push(typeof d === "string" ? d : d.toString("utf8"));
283
- });
284
- const { code, signal } = await proc.exited;
285
- await drainReadable(proc.stdout);
286
- await drainReadable(proc.stderr);
287
- outBuf.flush();
288
- errBuf.flush();
289
- return {
290
- exitCode: code,
291
- ...(signal !== undefined ? { signal } : {}),
292
- stdoutText: outBuf.text(),
293
- stderrTail: errBuf.text(),
294
- };
295
- }
296
-
297
91
  // ============================================================
298
92
  // coarse 事件合成(不变量:turn_end 最后、其前至少一个 message_end)
299
93
  // ============================================================
@@ -306,131 +100,3 @@ export function synthesizeCoarseEvents(response: string, usage?: ExecutionAgentU
306
100
  { type: "turn_end" },
307
101
  ] as AgentEvent[];
308
102
  }
309
-
310
- // ============================================================
311
- // engine_run_failed 错误文案(设计 §3.3.3 错误规格行)
312
- // ============================================================
313
-
314
- /**
315
- * 运行中失败的结构化文案:stdout 尾部 2000 字 + exit code + 恢复指引。
316
- *
317
- * 指引按 stderr 特征归因(2026-08-25 真机教训:LLM 端点不可达导致的
318
- * AI_APICallError 曾套用「查版本/重跑探针/补 golden」指引,误导排查方向):
319
- * - LLM API 调用失败(stderr 含 AI_APICallError):CLI 本体与输出解析正常,
320
- * 指向池内 provider 的 baseURL/apiKey 排查;
321
- * - 其余(spawn 成功但格式漂移/解析失败):保留 probe/golden 指引。
322
- */
323
- /** 错误文案里 stderr 尾部回显长度(stdout 有专用 2000 常量,stderr 更短防刷屏)。 */
324
- const STDERR_TAIL_IN_MSG_CHARS = 500;
325
-
326
- /** vercel.ai SDK 的 API 调用错误类名——zcode CLI 内部 LLM 调用失败的稳定特征。 */
327
- const LLM_API_FAILURE_SIGNATURE = "APICallError";
328
-
329
- /**
330
- * LLM/turn 级失败判定。两种实测形态(2026-08-25 真机):
331
- * - 无响应形态(端点不可达):stderr 含 AI_APICallError 类名 + Symbol 行;
332
- * - 有响应形态(如 HTTP 401):stderr 打印 response headers + responseStatus/
333
- * statusCode,类名行被截断不在尾部——靠 `Turn execution failed`(zcode CLI
334
- * turn 失败统一尾巴)兜住。
335
- */
336
- function isLlmTurnFailure(stderrTail: string | undefined): boolean {
337
- if (stderrTail === undefined) return false;
338
- return (
339
- stderrTail.includes(LLM_API_FAILURE_SIGNATURE) ||
340
- stderrTail.includes("Turn execution failed")
341
- );
342
- }
343
-
344
- /** stderr 中提取 HTTP 状态码(有响应形态),用于凭据/限流/上游错误的定向指引。 */
345
- function extractHttpStatus(stderrTail: string | undefined): string {
346
- if (stderrTail === undefined) return "";
347
- const m = stderrTail.match(/statusCode:\s*(\d{3})/);
348
- if (m === null) return "";
349
- const code = m[1]!;
350
- const meaning: Record<string, string> = {
351
- "401": "——凭据无效或过期(apiKey 被上游拒绝)",
352
- "403": "——凭据无权限(apiKey 有效但无该模型/资源权限)",
353
- "404": "——模型或路径不存在(核对模型名与 baseURL)",
354
- "429": "——限流/配额耗尽",
355
- };
356
- return `,HTTP ${code}${meaning[code] ?? ""}`;
357
- }
358
-
359
- /**
360
- * 折叠 stderr 里 console.log 浅序列化产生的 "[Object]" 噪音行
361
- * (真实堆栈里常出现连续十余行 `[Object], [Object], …`,折叠后保留计数)。
362
- */
363
- function compactStderrObjectNoise(tail: string): string {
364
- const OBJECT_LINE = /^(\[Object\][,\s]*)+$/;
365
- const lines = tail.split("\n");
366
- const out: string[] = [];
367
- let run = 0;
368
- const flush = (): void => {
369
- if (run > 0) {
370
- out.push(`[Object]×${run}`);
371
- run = 0;
372
- }
373
- };
374
- for (const line of lines) {
375
- if (OBJECT_LINE.test(line.trim())) {
376
- run++;
377
- continue;
378
- }
379
- flush();
380
- out.push(line);
381
- }
382
- flush();
383
- return out.join("\n");
384
- }
385
-
386
- export function buildRunFailedMessage(opts: {
387
- /** 实际使用的 CLI 路径(用户可经 XYZ_ZCODE_CLI 覆盖——文案必须引用真路径,不硬编码缺省值)。 */
388
- cliPath: string;
389
- exitCode: number | null;
390
- stdoutTail: string;
391
- stderrTail?: string;
392
- parseReason?: string;
393
- /** 本次任务解析出的模型全名(provider/model)——LLM 失败归因时点名排查对象。 */
394
- modelRef?: string;
395
- /** 池内 config.json 绝对路径——LLM 失败归因时给出 baseURL/apiKey 核对位置。 */
396
- configPath?: string;
397
- }): string {
398
- const parts: string[] = [];
399
- if (opts.parseReason !== undefined) {
400
- parts.push(`解析失败:${opts.parseReason}。`);
401
- }
402
- parts.push(`exit code: ${opts.exitCode ?? "null(被信号杀死)"}。`);
403
- if (opts.stderrTail !== undefined && opts.stderrTail.trim() !== "") {
404
- const compacted = compactStderrObjectNoise(opts.stderrTail);
405
- parts.push(`stderr 尾部: ${compacted.slice(-STDERR_TAIL_IN_MSG_CHARS)}`);
406
- }
407
- // stdout 空段跳过(与 stderr 同判)——turn 0 即失败时 stdout 恒空,保留空 part
408
- // 只会制造「stdout 尾部: <指引段>」的视觉嵌套误读(2026-08-25 真机复盘)
409
- if (opts.stdoutTail.trim() !== "") {
410
- parts.push(`stdout 尾部: ${opts.stdoutTail.slice(-ZCODE_ERROR_TAIL_CHARS)}`);
411
- }
412
-
413
- if (isLlmTurnFailure(opts.stderrTail)) {
414
- const statusHint = extractHttpStatus(opts.stderrTail);
415
- const modelHint =
416
- opts.modelRef !== undefined ? `(本任务模型 '${opts.modelRef}')` : "";
417
- const configHint =
418
- opts.configPath !== undefined
419
- ? `① 核对池内 provider 的 baseURL 可达性与 apiKey 有效性(\`${opts.configPath}\`)${statusHint.includes("401") || statusHint.includes("403") ? "——apiKey 大概率无效或过期,需在凭据来源(ZCode 桌面或自建网关)更新" : ""};`
420
- : `① 核对 zcode 池内 provider 的 baseURL 可达性与 apiKey 有效性${statusHint};`;
421
- parts.push(
422
- `恢复指引:模型 API 调用失败${statusHint}——CLI 本体与输出解析正常,问题在模型端点或凭据${modelHint}。` +
423
- configHint +
424
- "② 修复后直接重跑本任务(probe 缓存不受影响——运行期失败不缓存);" +
425
- "③ 或任务显式指定其他可用模型(provider/model 全名);" +
426
- "④ 或改用 engine: pi 重跑本任务。",
427
- );
428
- } else {
429
- parts.push(
430
- `恢复指引:跑 \`node ${opts.cliPath} --version\` 确认版本后重跑探针(probe)——` +
431
- "若为格式漂移,把新 stdout 样本补录进 golden 库(\`__tests__/__fixtures__/zcode-golden-spawn.json\`)并更新 parser;" +
432
- "或改用 engine: pi 重跑本任务。详见 docs/research/agent-engine-zcode.md。",
433
- );
434
- }
435
- return `engine_run_failed: zcode CLI 运行失败。${parts.join(" ")}`;
436
- }
@@ -1,36 +1,21 @@
1
1
  // src/execution/engine/engines/zcode/preparer.ts
2
2
  //
3
- // ZcodeEngine preparer(P3):spawn 前唯一副作用模块(设计 §3.3.7)——隔离 HOME 池化
4
- // + 池内 config.json 引导(凭据 + model.main)。TS 重写自 zsub
5
- // bootstrapIsolatedHome / model-router.js(真机验证过的机制),差异点:
3
+ // ZcodeEngine prepare 期模型解析件(P3 起源,2026-09 收缩):隔离 HOME 池化与
4
+ // 池内 config 引导随 CLI spawn 链删除(共享宿主 HOME——app-server 的凭据经
5
+ // appserver-launcher fs 拦截注入 v2 provider,本文件只剩 v2 单源的模型引用
6
+ // 解析/校验/清单:
6
7
  // - **凭据源 = v2 config 单源(2026-08-25 用户拍板)**:只读 `~/.zcode/v2/config.json`
7
8
  // (ZCode 桌面登录态落点,GUI 管理面)。曾泛化过「v2 + cli config 双源合并」,
8
9
  // 但 `~/.zcode/cli/config.json` 不在 GUI 管理面、可能残留历史验证配置
9
10
  // (8/24 zsub 开发残留把默认模型劫持到失效 router 端点的 401 事故),撤掉依赖;
10
- // - 池目录必须经 resolvePoolDir(paths.ts SSOT,禁自拼——池布局要与 journal/refs
11
- // 共享同一形状,设计 §3.3.9);
12
11
  // - 凭据缺失/模型不可解析抛结构化 ZcodePrepareError(错误码对齐设计 §3.3.3:
13
12
  // engine_credential_missing / model_not_available),一律先于进程创建。
14
- //
15
- // 为什么池按 provider+model 隔离(与设计 §3.3.9「agent 名池」不同):并发 run 指向
16
- // 同一 HOME 但模型不同时,config.json 的 model.main 会出现「后写覆盖先写」的串池——
17
- // zsub 的 per-model HOME 池正是防这个;本引擎以 provider+model 为隔离粒度,agent 维度
18
- // 的池化留给宿主 refs.json(W3 对齐点)。
19
- //
20
- // [R4 D7] app-server 常驻 HOME 语义(锁/派生/pidfile 孤儿回收/allProviders 引导/
21
- // 凭据内容 hash 刷新)拆至同目录 appserver-home.ts——单一关注点分立。
22
13
 
23
14
  import * as fs from "node:fs";
24
15
  import * as os from "node:os";
25
16
  import * as path from "node:path";
26
17
 
27
- import { resolvePoolDir } from "../../paths.ts";
28
- import { writeAtomicFileSync } from "../../../../shared/atomic-write.ts";
29
- import {
30
- ZCODE_FALLBACK_DEFAULT_MODEL,
31
- ZCODE_POOL_CONFIG_SUFFIX,
32
- ZCODE_V2_CONFIG_PATH_SUFFIX,
33
- } from "./constants.ts";
18
+ import { ZCODE_FALLBACK_DEFAULT_MODEL, ZCODE_V2_CONFIG_PATH_SUFFIX } from "./constants.ts";
34
19
 
35
20
  // ============================================================
36
21
  // 结构化错误(prepare 期——进程创建前 reject 的载体)
@@ -66,22 +51,20 @@ export interface ZcodeProviderEntry {
66
51
  interface SourceConfig {
67
52
  /** provider 注册表(来自 v2 config,逐条运行时 guard)。 */
68
53
  providers: Map<string, ZcodeProviderEntry>;
69
- /** 源文件 mtime(池 config 免重写的比对基准;不可读 = 0)。 */
70
- mtimeMs: number;
71
54
  }
72
55
 
73
56
  /** unknown 的 Record 窄化 guard(替代 as 全可选断言——taste/no-unsafe-cast)。 */
74
- export function isRecord(v: unknown): v is Record<string, unknown> {
57
+ function isRecord(v: unknown): v is Record<string, unknown> {
75
58
  return typeof v === "object" && v !== null && !Array.isArray(v);
76
59
  }
77
60
 
78
61
  /** provider 条目一律按 ZcodeProviderEntry 消费(索引签名形态,无需逐键校验)。 */
79
- export function isProviderEntry(v: unknown): v is ZcodeProviderEntry {
62
+ function isProviderEntry(v: unknown): v is ZcodeProviderEntry {
80
63
  return isRecord(v);
81
64
  }
82
65
 
83
- export function readSourceConfig(absPath: string): SourceConfig {
84
- const empty: SourceConfig = { providers: new Map(), mtimeMs: 0 };
66
+ function readSourceConfig(absPath: string): SourceConfig {
67
+ const empty: SourceConfig = { providers: new Map() };
85
68
  let raw: string;
86
69
  try {
87
70
  raw = fs.readFileSync(absPath, "utf8");
@@ -95,19 +78,13 @@ export function readSourceConfig(absPath: string): SourceConfig {
95
78
  return empty;
96
79
  }
97
80
  if (!isRecord(parsed)) return empty;
98
- const conf: SourceConfig = { providers: new Map(), mtimeMs: 0 };
81
+ const conf: SourceConfig = { providers: new Map() };
99
82
  const provider = parsed["provider"];
100
83
  if (isRecord(provider)) {
101
84
  for (const [id, entry] of Object.entries(provider)) {
102
85
  if (isProviderEntry(entry)) conf.providers.set(id, entry);
103
86
  }
104
87
  }
105
- try {
106
- conf.mtimeMs = fs.statSync(absPath).mtimeMs;
107
- } catch {
108
- // 源被并发删除等场景:mtime 取 0(比对恒不触发重写,池内完好配置继续用)
109
- conf.mtimeMs = 0;
110
- }
111
88
  return conf;
112
89
  }
113
90
 
@@ -253,114 +230,6 @@ export function listZcodeModels(sources?: ZcodeSourcePaths): Array<{ id: string;
253
230
  }
254
231
 
255
232
  // ============================================================
256
- // 池 key 与目录
233
+ // 池 key 与目录(2026-09 删除:HOME 池化随 CLI spawn 链一并退役——共享宿主 HOME
234
+ // 后无隔离池、无 config 引导,本文件只剩 v2 单源的模型解析/清单校验件)
257
235
  // ============================================================
258
-
259
- /** provider id 安全化(builtin:bigmodel → builtin-bigmodel;zsub providerDirName 同构)。 */
260
- function sanitizeProviderDirName(p: string): string {
261
- return p.replace(/[^A-Za-z0-9._-]/g, "-");
262
- }
263
-
264
- /**
265
- * 池 key:`home-<provider>-<modelShort>`(zsub homePoolDir 同构——provider+model 维度
266
- * 隔离防并发串池,见文件头注释)。model 短名只清洗路径敌对字符(分隔符/空白),
267
- * 保留点号(GLM-5.3 / mimo-v2.5-pro 原样——zsub 同判);进入文件系统时由
268
- * resolvePoolDir 的 sanitizeSeg 再做一层统一编码。
269
- */
270
- export function computeZcodePoolKey(modelRef: string): string {
271
- const provider = providerOf(modelRef);
272
- const short = modelShort(modelRef).replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
273
- return `home-${sanitizeProviderDirName(provider)}-${short.length > 0 ? short : "default"}`;
274
- }
275
-
276
- // ============================================================
277
- // 隔离 HOME 引导(bootstrapIsolatedHome TS 重写)
278
- // ============================================================
279
-
280
- export interface ZcodePreparedHome {
281
- /** 规范化模型全名 provider/model。 */
282
- modelRef: string;
283
- /** 池 key(handle.poolKey 数据源)。 */
284
- poolKey: string;
285
- /** 池目录绝对路径 = 隔离 HOME。 */
286
- homeDir: string;
287
- /** 池内 config.json 绝对路径。 */
288
- configPath: string;
289
- /** 本次是否实际重写了 config(mtime 免重写命中时 false——resume/复用轮零开销)。 */
290
- wroteConfig: boolean;
291
- }
292
-
293
- /**
294
- * 池 config 是否需要重写(zsub homeNeedsBootstrap 同构):
295
- * 1. 池目录或池内 config.json 不存在(首次建池);
296
- * 2. 池内 config.json 损坏(torn write 防线:mtime 看似新但内容不完整);
297
- * 3. 任一「实际被用到的」源 config 的 mtime 比池内 config 新(凭据/模型清单刷新过)。
298
- * 源不可读但池配置完好:保留池现状——没有更好依据时不破坏可用状态。
299
- */
300
- function homeNeedsBootstrap(configPath: string, sourceMtimeMs: number): boolean {
301
- if (!fs.existsSync(configPath)) return true;
302
- let poolMtimeMs = 0;
303
- try {
304
- JSON.parse(fs.readFileSync(configPath, "utf8"));
305
- poolMtimeMs = fs.statSync(configPath).mtimeMs;
306
- } catch {
307
- return true;
308
- }
309
- return sourceMtimeMs > poolMtimeMs;
310
- }
311
-
312
- /** 池 config.json 缩进(人读友好——与 zsub 产出的文件形态一致)。 */
313
- export const CONFIG_INDENT_SPACES = 2;
314
-
315
- /**
316
- * 引导隔离 HOME 的 provider 配置(spawn 前调用)。
317
- *
318
- * - 只写 {model, provider},刻意不含 plugins 块:第二重门禁——subagent 进程在隔离
319
- * HOME 下不加载宿主插件(含 subagent-workflow 自身),物理隔断递归派发。
320
- * - tmp+rename 原子写:跨进程并发 bootstrap 下读者永远看到完整文件。进程内无需
321
- * zsub 的互斥链——本实现全同步 fs(无 await 让出点),单线程事件循环天然不交错。
322
- * - 只写目标 provider 一个条目(spawn 池每池单 provider 单模型,凭据落盘面最小)。
323
- */
324
- export function prepareZcodeHome(opts: {
325
- engineDataDir: string;
326
- modelRef: string;
327
- sources?: ZcodeSourcePaths;
328
- }): ZcodePreparedHome {
329
- const { engineDataDir, modelRef } = opts;
330
- const poolKey = computeZcodePoolKey(modelRef);
331
- const homeDir = resolvePoolDir(engineDataDir, "zcode", poolKey);
332
- const configPath = path.join(homeDir, ...ZCODE_POOL_CONFIG_SUFFIX);
333
-
334
- const v2Path = opts.sources?.v2ConfigPath ?? defaultV2ConfigPath();
335
- const v2 = readSourceConfig(v2Path);
336
- const provider = providerOf(modelRef);
337
- const entry = v2.providers.get(provider);
338
- if (entry === undefined) {
339
- // provider 不在 v2 注册表:模型引用不可解释(resolve 期漏网或直接调用)
340
- throw new ZcodePrepareError(
341
- "model_not_available",
342
- `未知 provider "${provider}"(v2 config 无该条目:${v2Path})。` +
343
- `恢复指引:先经 resolveZcodeModelRef 校验模型引用,或先在 ZCode 桌面端配置该 provider 后重试。`,
344
- );
345
- }
346
- if (!hasApiKey(entry)) {
347
- // provider 存在但无凭据:resolve 与 bootstrap 之间凭据被撤(并发改动)
348
- throw new ZcodePrepareError(
349
- "engine_credential_missing",
350
- `provider "${provider}" 存在但未配置 apiKey(${v2Path} 重读无凭据)。` +
351
- `恢复指引:确认 ZCode 桌面端登录态有效后重试;凭据配置说明见 docs/research/agent-engine-zcode.md。`,
352
- );
353
- }
354
-
355
- const hitSourceMtime = v2.mtimeMs;
356
- let wroteConfig = false;
357
- if (homeNeedsBootstrap(configPath, hitSourceMtime)) {
358
- const payload = JSON.stringify({ model: { main: modelRef }, provider: { [provider]: entry } }, null, CONFIG_INDENT_SPACES);
359
- // tmp+rename 原子写(shared/atomic-write 统一原语,U6b 迁移——rename 失败时
360
- // 原语清残留 tmp,避免污染 HOME 目录;tmp 文件不参与读取,best-effort 语义不变)
361
- writeAtomicFileSync(configPath, payload);
362
- wroteConfig = true;
363
- }
364
- return { modelRef, poolKey, homeDir, configPath, wroteConfig };
365
- }
366
-