@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
@@ -16,6 +16,7 @@ import { readFileSync } from "node:fs";
16
16
  import { join } from "node:path";
17
17
 
18
18
  import { lintAgentMeta, lintScript } from "../script-lint.ts";
19
+ import type { LintFinding } from "../script-lint.ts";
19
20
  import { parseResourceMeta } from "../../shared/meta-parser.ts";
20
21
 
21
22
  const WORKFLOWS_DIR = join(__dirname, "../../../workflows");
@@ -491,6 +492,22 @@ describe("MF-4 回归:非字面量实参 agent(callVar) / agent(expr()) 跳过
491
492
  expect(descWarnings).toHaveLength(1);
492
493
  expect(descWarnings[0].line).toBe(2);
493
494
  });
495
+
496
+ it("`agent(` 换行 `{` 的多行字面量调用保留追踪(argTail 为空分支)", () => {
497
+ // agent( 与 { 分离两行:argTail 为空不跳过,范围跨三行闭合——缺 description
498
+ // 报 1 条且行号落在调用起点(锚定 matchAgentCallHead 的空 argTail 保留路径)
499
+ const src = [
500
+ `await agent(`,
501
+ ` { prompt: "x" }`,
502
+ `);`,
503
+ ``,
504
+ ].join("\n");
505
+ const result = lintScript(src);
506
+
507
+ const descWarnings = warnings(result.findings).filter((w) => /description.*unnamed/i.test(w.message));
508
+ expect(descWarnings).toHaveLength(1);
509
+ expect(descWarnings[0].line).toBe(1);
510
+ });
494
511
  });
495
512
 
496
513
  // ── MF-4 回归:checkAgentDescription 的两个跳过分支 ────────────────
@@ -73,8 +73,8 @@ beforeEach(() => {
73
73
  afterEach(() => {
74
74
  vi.restoreAllMocks();
75
75
  resetCoreForTests();
76
- rmSync(projRoot, { recursive: true, force: true });
77
- rmSync(homeRoot, { recursive: true, force: true });
76
+ rmSync(projRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
77
+ rmSync(homeRoot, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
78
78
  });
79
79
 
80
80
  /** mkdir -p(目录存在即 resolveSkillPath 命中——检查的是目录而非 SKILL.md)。 */
@@ -68,6 +68,7 @@ export function mkCtx(
68
68
  ui: mkUi(),
69
69
  // pi 在 xyz-agent 下以 rpc 子进程模式运行;rpc 模式 hasUI 为 true(SDK 契约注释)
70
70
  mode: "rpc",
71
+ scopedModels: [],
71
72
  hasUI: true,
72
73
  cwd: "/tmp",
73
74
  sessionManager: {
@@ -168,6 +169,7 @@ export function mkPi(
168
169
  registerTool: vi.fn(),
169
170
  registerCommand: vi.fn(),
170
171
  registerShortcut: vi.fn(),
172
+ registerMarkdownTransformer: vi.fn(),
171
173
  registerFlag: vi.fn(),
172
174
  getFlag: vi.fn(() => undefined),
173
175
  registerMessageRenderer: vi.fn(),
@@ -18,7 +18,7 @@
18
18
  * `void handlers.onXxx(...)` 无人接 → unhandledRejection + pending:unregister / onRunDone
19
19
  * 不执行(pending 通知幽灵注销)。修复后 save 失败仅 logger.error,状态机继续推进。
20
20
  *
21
- * mock 构建参考 error-recovery-handlers.test.ts(plain-object WorkflowRun mock)。
21
+ * mock 构建参考 worker-message-pump-handlers.test.ts(plain-object WorkflowRun mock)。
22
22
  */
23
23
  import { describe, expect, it, vi } from "vitest";
24
24
 
@@ -27,16 +27,17 @@ import {
27
27
  handleWorkerMessage,
28
28
  handleScriptError,
29
29
  handleWorkerError,
30
- } from "../error-recovery.ts";
30
+ } from "../worker-message-pump.ts";
31
31
  import type { LifecycleDeps, WorkerHandlers } from "../models/ports.ts";
32
+ import type { DoneReason, RunStatus } from "../models/types.ts";
32
33
  import type { WorkflowRun } from "../models/workflow-run.ts";
33
34
  import type { WorkerHandle } from "../worker-handle.ts";
34
35
 
35
- /** [F1] 归因文案——与 error-recovery.ts 常量一致(不直接 import 常量以锚定对外文案)。 */
36
+ /** [F1] 归因文案——与 worker-message-pump.ts 常量一致(不直接 import 常量以锚定对外文案)。 */
36
37
  const EXITED_WITHOUT_RESULT_MSG =
37
38
  "worker exited before delivering a result (return value may not be structured-cloneable)";
38
39
 
39
- // ── helpers(对齐 error-recovery-handlers.test.ts)─────────────────
40
+ // ── helpers(对齐 worker-message-pump-handlers.test.ts)─────────────────
40
41
 
41
42
  interface RunMockOpts {
42
43
  workerErrorCount?: number;
@@ -70,11 +71,11 @@ function makeRunningRun(opts: RunMockOpts = {}): WorkflowRun {
70
71
  worker: { postMessage: vi.fn() },
71
72
  receivedTerminalMessage: opts.receivedTerminalMessage,
72
73
  },
73
- transition(target: string, reason?: string): void {
74
+ transition(this: WorkflowRun, target: RunStatus, reason?: DoneReason): void {
74
75
  this.state.status = target;
75
76
  if (target === "done") this.state.reason = reason;
76
77
  },
77
- replaceRuntime(rt: unknown): void {
78
+ replaceRuntime(this: WorkflowRun, rt: NonNullable<WorkflowRun["runtime"]>): void {
78
79
  this.runtime = rt;
79
80
  },
80
81
  } as unknown as WorkflowRun;
@@ -0,0 +1,229 @@
1
+ /**
2
+ * finalizeRun — D5-② 终态 coda 单写点测试。
3
+ *
4
+ * 「transition → save → pending:unregister → onRunDone」四步终态序列的唯一
5
+ * 定义点(worker-message-pump.ts)。收敛前 8 处逐字复制(本文件 6 处 + lifecycle
6
+ * 2 处)——本文件锁定:
7
+ * 1. 四步恰好一次且有序(transition 先于 save 先于 unregister 先于 onRunDone)
8
+ * 2. notifyDone:false 真差异承载(terminateRunningRuns 不发 onRunDone、unregister 仍发)
9
+ * 3. transition 让位(并发终态化)→ 后三步全不执行
10
+ * 4. save best-effort(SW-DATA-3)→ unregister/onRunDone 不被落盘失败短路
11
+ *
12
+ * 其余终态路径的「恰好一次四步」行为断言(save×1 + unregister + onRunDone×1)
13
+ * 已由既有测试覆盖:handleWorkerError/handleScriptError/handleWorkerExit 超限
14
+ * (worker-message-pump-handlers / worker-exit-without-result)、time_limited
15
+ * (worker-message-pump-handlers race-F3 describe)、abortRun(lifecycle.test)、
16
+ * handleReturn(worker-exit-without-result SW-DATA-3 describe)。本文件补齐
17
+ * budget_limited 路径(dispatchAgentCall coda)与 notifyDone:false 路径。
18
+ */
19
+ import { describe, expect, it, vi } from "vitest";
20
+
21
+ import {
22
+ finalizeRun,
23
+ handleWorkerMessage,
24
+ } from "../worker-message-pump.ts";
25
+ import { Budget } from "../models/budget.ts";
26
+ import { RunRuntime } from "../models/run-runtime.ts";
27
+ import { Trace } from "../models/trace.ts";
28
+ import type { AgentResult } from "../models/types.ts";
29
+ import { WorkflowRun } from "../models/workflow-run.ts";
30
+ import type { LifecycleDeps, WorkerHandlers } from "../models/ports.ts";
31
+ import type { WorkerHandle } from "../worker-handle.ts";
32
+
33
+ // ── helpers ──────────────────────────────────────────────────
34
+
35
+ /** 构造真实 WorkflowRun(真实状态机 transition)+ 初始 runtime。 */
36
+ function makeRealRun(runId: string): WorkflowRun {
37
+ const run = new WorkflowRun(
38
+ runId,
39
+ {
40
+ scriptName: "test-wf",
41
+ scriptSource: "agent('hi')",
42
+ args: {},
43
+ scriptPath: "/tmp/test-wf.js",
44
+ },
45
+ {
46
+ status: "running",
47
+ budget: new Budget(),
48
+ calls: new Map(),
49
+ trace: new Trace(),
50
+ errorLogs: [],
51
+ },
52
+ { startedAt: new Date().toISOString() },
53
+ );
54
+ const worker = {
55
+ postMessage: vi.fn(),
56
+ terminate: vi.fn(async () => {}),
57
+ } as unknown as WorkerHandle;
58
+ run.assignRuntime(new RunRuntime(worker, new AbortController()));
59
+ return run;
60
+ }
61
+
62
+ /** deps mock:副作用打点进单一顺序数组(断言四步顺序)。 */
63
+ function makeTracingDeps(): LifecycleDeps & {
64
+ order: string[];
65
+ store: { save: ReturnType<typeof vi.fn> };
66
+ } {
67
+ const order: string[] = [];
68
+ return {
69
+ order,
70
+ store: {
71
+ save: vi.fn(async () => {
72
+ order.push("save");
73
+ }),
74
+ },
75
+ workerHost: { start: vi.fn(() => ({ postMessage: vi.fn() })) },
76
+ runner: { run: vi.fn(async () => ({}) as AgentResult) },
77
+ runs: new Map(),
78
+ eventBus: {
79
+ emit: vi.fn((event: string) => {
80
+ order.push(`emit:${event}`);
81
+ }),
82
+ },
83
+ onRunDone: vi.fn(() => {
84
+ order.push("onRunDone");
85
+ }),
86
+ log: vi.fn(),
87
+ } as unknown as ReturnType<typeof makeTracingDeps>;
88
+ }
89
+
90
+ /** flush 微任务队列(void finalizeRun 的 async 链推进到稳定态)。 */
91
+ async function flushMicrotasks(ticks = 20): Promise<void> {
92
+ for (let i = 0; i < ticks; i++) {
93
+ // eslint-disable-next-line no-await-in-loop -- 排空微任务队列的固定 tick 循环,非逐项等待
94
+ await Promise.resolve();
95
+ }
96
+ }
97
+
98
+ // ── finalizeRun 直测 ─────────────────────────────────────────
99
+
100
+ describe("finalizeRun(D5-② 单写点直测)", () => {
101
+ it("四步恰好一次且有序:transition → save → pending:unregister → onRunDone", async () => {
102
+ const run = makeRealRun("wf-fin-1");
103
+ const deps = makeTracingDeps();
104
+
105
+ const transitionSpy = vi.spyOn(run, "transition");
106
+ const ok = await finalizeRun(run, deps, "completed", { context: "test" });
107
+
108
+ expect(ok).toBe(true);
109
+ expect(run.state.status).toBe("done");
110
+ expect(run.state.reason).toBe("completed");
111
+ // 四步各恰好一次
112
+ expect(transitionSpy).toHaveBeenCalledTimes(1);
113
+ expect(deps.store.save).toHaveBeenCalledTimes(1);
114
+ expect(deps.eventBus!.emit).toHaveBeenCalledTimes(1);
115
+ expect(deps.onRunDone).toHaveBeenCalledTimes(1);
116
+ // 顺序:save → unregister → onRunDone(transition 已同步先行)
117
+ expect(deps.order).toEqual(["save", "emit:pending:unregister", "onRunDone"]);
118
+ // unregister reason = transition 后的 state.reason
119
+ expect(deps.eventBus!.emit).toHaveBeenCalledWith("pending:unregister", {
120
+ id: "wf-fin-1",
121
+ reason: "completed",
122
+ });
123
+ });
124
+
125
+ it("notifyDone:false → onRunDone 不调、unregister 仍发(terminateRunningRuns 真差异经参数承载)", async () => {
126
+ const run = makeRealRun("wf-fin-2");
127
+ const deps = makeTracingDeps();
128
+
129
+ const ok = await finalizeRun(run, deps, "failed", {
130
+ context: "terminateRunningRuns",
131
+ notifyDone: false,
132
+ });
133
+
134
+ expect(ok).toBe(true);
135
+ expect(run.state.reason).toBe("failed");
136
+ expect(deps.eventBus!.emit).toHaveBeenCalledTimes(1);
137
+ expect(deps.eventBus!.emit).toHaveBeenCalledWith("pending:unregister", {
138
+ id: "wf-fin-2",
139
+ reason: "failed",
140
+ });
141
+ expect(deps.onRunDone).not.toHaveBeenCalled();
142
+ expect(deps.order).toEqual(["save", "emit:pending:unregister"]);
143
+ });
144
+
145
+ it("transition 抛错(并发 abort 抢先终态化)→ 返回 false,后三步全不执行", async () => {
146
+ const run = makeRealRun("wf-fin-3");
147
+ // 抢先终态化——此后 running→done 转移抛 illegal-transition
148
+ run.transition("done", "aborted");
149
+ const deps = makeTracingDeps();
150
+
151
+ const ok = await finalizeRun(run, deps, "failed", { context: "test" });
152
+
153
+ expect(ok).toBe(false);
154
+ // 抢先方已兑现 unregister/onRunDone——本路径让位,不重复执行
155
+ expect(deps.store.save).not.toHaveBeenCalled();
156
+ expect(deps.eventBus!.emit).not.toHaveBeenCalled();
157
+ expect(deps.onRunDone).not.toHaveBeenCalled();
158
+ expect(run.state.reason).toBe("aborted");
159
+ });
160
+
161
+ it("save 抛错(ENOSPC)→ best-effort:unregister + onRunDone 照常(SW-DATA-3 统一)", async () => {
162
+ const run = makeRealRun("wf-fin-4");
163
+ const deps = makeTracingDeps();
164
+ deps.store.save = vi.fn(async () => {
165
+ throw new Error("ENOSPC: no space left on device");
166
+ });
167
+
168
+ const ok = await finalizeRun(run, deps, "failed", { context: "test" });
169
+
170
+ expect(ok).toBe(true);
171
+ expect(run.state.status).toBe("done");
172
+ expect(deps.eventBus!.emit).toHaveBeenCalledTimes(1);
173
+ expect(deps.onRunDone).toHaveBeenCalledTimes(1);
174
+ });
175
+
176
+ it("onRunDone 抛错 → 被捕获记日志(M12:真实副作用错误不静默吞、不上抛)", async () => {
177
+ const run = makeRealRun("wf-fin-5");
178
+ const deps = makeTracingDeps();
179
+ deps.onRunDone = vi.fn(() => {
180
+ throw new Error("interface notify blew up");
181
+ });
182
+
183
+ await expect(
184
+ finalizeRun(run, deps, "completed", { context: "test" }),
185
+ ).resolves.toBe(true);
186
+ expect(deps.eventBus!.emit).toHaveBeenCalledTimes(1);
187
+ expect(run.state.status).toBe("done");
188
+ });
189
+ });
190
+
191
+ // ── budget_limited 路径(dispatchAgentCall coda)四步恰好一次 ────────────
192
+
193
+ describe("budget_limited 终态路径(dispatchAgentCall → finalizeRun)", () => {
194
+ it("agent call 后预算超限 → 四步恰好一次(unregister reason=budget_limited + onRunDone)", async () => {
195
+ const run = makeRealRun("wf-budget-1");
196
+ const deps = makeTracingDeps();
197
+ // budget.isExceeded 恒 true——runner.run 成功返回后命中 C-2 coda
198
+ (run.state.budget as unknown as { isExceeded: () => boolean }).isExceeded =
199
+ () => true;
200
+ deps.runner.run = vi.fn(async () =>
201
+ ({ content: "ok", durationMs: 1, error: undefined, toolCalls: [] }) as AgentResult,
202
+ );
203
+ const handlers: WorkerHandlers = {
204
+ onMessage: vi.fn(async () => {}),
205
+ onError: vi.fn(async () => {}),
206
+ onExit: vi.fn(async () => {}),
207
+ };
208
+
209
+ await handleWorkerMessage(
210
+ run,
211
+ { type: "agent-call", callId: 1, opts: { prompt: "p", description: "d" } },
212
+ deps,
213
+ handlers,
214
+ );
215
+ await flushMicrotasks();
216
+
217
+ expect(run.state.status).toBe("done");
218
+ expect(run.state.reason).toBe("budget_limited");
219
+ // save 2 次 = call 完成快照(dispatchAgentCall .then 的常规持久化)+ budget
220
+ // 终态快照(finalizeRun 内)——两次语义不同,收敛前后一致
221
+ expect(deps.store.save).toHaveBeenCalledTimes(2);
222
+ expect(deps.eventBus!.emit).toHaveBeenCalledTimes(1);
223
+ expect(deps.eventBus!.emit).toHaveBeenCalledWith("pending:unregister", {
224
+ id: "wf-budget-1",
225
+ reason: "budget_limited",
226
+ });
227
+ expect(deps.onRunDone).toHaveBeenCalledTimes(1);
228
+ });
229
+ });
@@ -1,7 +1,7 @@
1
1
  /**
2
- * error-recovery handlers — handleWorkerExit/Error/ScriptError + postBudgetUpdate 测试。
2
+ * worker-message-pump handlers — handleWorkerExit/Error/ScriptError + postBudgetUpdate 测试。
3
3
  *
4
- * 参考 error-recovery-workflow-call.test.ts 的 mock 构建。通过 vi.useFakeTimers() 跳过
4
+ * 参考 worker-message-pump-workflow-call.test.ts 的 mock 构建。通过 vi.useFakeTimers() 跳过
5
5
  * scheduleRebuild 的指数退避(1s/2s/4s)。
6
6
  *
7
7
  * 覆盖:
@@ -23,11 +23,11 @@ import {
23
23
  handleWorkerMessage,
24
24
  postBudgetUpdate,
25
25
  rebuildRuntime,
26
- } from "../error-recovery.ts";
26
+ } from "../worker-message-pump.ts";
27
27
  import { Budget } from "../models/budget.ts";
28
28
  import { RunRuntime } from "../models/run-runtime.ts";
29
29
  import { Trace } from "../models/trace.ts";
30
- import type { AgentResult } from "../models/types.ts";
30
+ import type { AgentResult, DoneReason, RunStatus } from "../models/types.ts";
31
31
  import { WorkflowRun } from "../models/workflow-run.ts";
32
32
  import type { LifecycleDeps, WorkerHandlers } from "../models/ports.ts";
33
33
  import type { WorkerHandle } from "../worker-handle.ts";
@@ -71,26 +71,34 @@ function makeRunningRun(opts: {
71
71
  receivedTerminalMessage: opts.receivedTerminalMessage,
72
72
  },
73
73
  // transition 副作用——run.state.status 由调用方通过 mock 控制后再次断言
74
- transition(target: string, reason?: string): void {
74
+ transition(this: WorkflowRun, target: RunStatus, reason?: DoneReason): void {
75
75
  this.state.status = target;
76
76
  if (target === "done") this.state.reason = reason;
77
77
  },
78
- replaceRuntime(rt: unknown): void {
78
+ replaceRuntime(this: WorkflowRun, rt: NonNullable<WorkflowRun["runtime"]>): void {
79
79
  this.runtime = rt;
80
80
  },
81
81
  } as unknown as WorkflowRun;
82
82
  }
83
83
 
84
- /** LifecycleDeps mock:store/workerHost/runner/eventBus/scheduleTimeBudget 可观察。 */
84
+ /** LifecycleDeps mock:store/workerHost/runner/eventBus/scheduleTimeBudget 可观察。
85
+ * mock 成员 = 真实签名 & vi.fn 能力(交叉纯 Mock 会丢真实签名,传回被测函数即报错)。 */
86
+ type MockLifecycleDeps = Omit<
87
+ LifecycleDeps,
88
+ "store" | "workerHost" | "runner" | "eventBus" | "onRunDone" | "log"
89
+ > & {
90
+ // 真实类型整体保留(RunStore/WorkerHost 等接口成员完整),仅 mock 方法交叉 vi.fn 能力
91
+ store: LifecycleDeps["store"] & { save: LifecycleDeps["store"]["save"] & ReturnType<typeof vi.fn> };
92
+ workerHost: LifecycleDeps["workerHost"] & { start: LifecycleDeps["workerHost"]["start"] & ReturnType<typeof vi.fn> };
93
+ runner: LifecycleDeps["runner"] & { run: LifecycleDeps["runner"]["run"] & ReturnType<typeof vi.fn> };
94
+ eventBus: NonNullable<LifecycleDeps["eventBus"]> & { emit: NonNullable<LifecycleDeps["eventBus"]>["emit"] & ReturnType<typeof vi.fn> };
95
+ onRunDone: LifecycleDeps["onRunDone"] & ReturnType<typeof vi.fn>;
96
+ log: LifecycleDeps["log"] & ReturnType<typeof vi.fn>;
97
+ };
98
+
85
99
  function makeDeps(opts: {
86
100
  scheduleTimeBudget?: LifecycleDeps["scheduleTimeBudget"];
87
- } = {}): LifecycleDeps & {
88
- store: { save: ReturnType<typeof vi.fn> };
89
- workerHost: { start: ReturnType<typeof vi.fn> };
90
- eventBus: { emit: ReturnType<typeof vi.fn> };
91
- onRunDone: ReturnType<typeof vi.fn>;
92
- log: ReturnType<typeof vi.fn>;
93
- } {
101
+ } = {}): MockLifecycleDeps {
94
102
  return {
95
103
  store: { save: vi.fn(async () => {}) },
96
104
  workerHost: { start: vi.fn(() => ({ postMessage: vi.fn() })) },
@@ -344,7 +352,7 @@ describe("rebuildRuntime", () => {
344
352
 
345
353
  it("带 budgetTimeMs 时重排 scheduleTimeBudget 计时器", () => {
346
354
  const run = makeRunningRun({ budgetTimeMs: 5000 });
347
- const scheduleTimeBudget = vi.fn(() => undefined);
355
+ const scheduleTimeBudget = vi.fn((_runId: string, _budgetTimeMs: number) => undefined);
348
356
  const deps = makeDeps({ scheduleTimeBudget });
349
357
 
350
358
  rebuildRuntime(run, deps, makeHandlers());
@@ -413,7 +421,7 @@ describe("race-F3: rebuild 时间预算折算", () => {
413
421
  const run = makeRunningRun({ budgetTimeMs: 5000 });
414
422
  // 已耗 70%(3500ms)→ 剩余 1500ms;fake Date 冻结,elapsed 精确
415
423
  run.meta.startedAt = new Date(Date.now() - 3500).toISOString();
416
- const scheduleTimeBudget = vi.fn(() => undefined);
424
+ const scheduleTimeBudget = vi.fn((_runId: string, _budgetTimeMs: number) => undefined);
417
425
  const deps = makeDeps({ scheduleTimeBudget });
418
426
 
419
427
  rebuildRuntime(run, deps, makeHandlers());
@@ -429,7 +437,7 @@ describe("race-F3: rebuild 时间预算折算", () => {
429
437
  const run = makeRunningRun({ budgetTimeMs: 5000 });
430
438
  // 已耗 6000ms > 预算 5000ms(退避 advance 1000ms 后已耗 7000ms,仍耗尽)
431
439
  run.meta.startedAt = new Date(Date.now() - 6000).toISOString();
432
- const scheduleTimeBudget = vi.fn(() => undefined);
440
+ const scheduleTimeBudget = vi.fn((_runId: string, _budgetTimeMs: number) => undefined);
433
441
  const deps = makeDeps({ scheduleTimeBudget });
434
442
 
435
443
  const p = handleScriptError(run, "boom", [], deps, makeHandlers());
@@ -452,7 +460,7 @@ describe("race-F3: rebuild 时间预算折算", () => {
452
460
 
453
461
  it("预算未耗尽(fresh run)→ 照常 rebuild,不误转 time_limited(防误伤回归)", async () => {
454
462
  const run = makeRunningRun({ budgetTimeMs: 5000 }); // startedAt ≈ now,remaining 满
455
- const scheduleTimeBudget = vi.fn(() => undefined);
463
+ const scheduleTimeBudget = vi.fn((_runId: string, _budgetTimeMs: number) => undefined);
456
464
  const deps = makeDeps({ scheduleTimeBudget });
457
465
 
458
466
  const p = handleScriptError(run, "boom", [], deps, makeHandlers());
@@ -745,7 +753,7 @@ describe("rebuildRuntime 可观察性(OB3 日志点)", () => {
745
753
 
746
754
  it("U7: 带 budgetTimeMs + scheduleTimeBudget 注入时含 L2(在 L1 之后、L3 之前,payload 含 budgetTimeMs)", () => {
747
755
  const run = makeRealRun("wf-rebuild-log-2", { budgetTimeMs: 5000 });
748
- const scheduleTimeBudget = vi.fn(() => undefined);
756
+ const scheduleTimeBudget = vi.fn((_runId: string, _budgetTimeMs: number) => undefined);
749
757
  const deps = makeDeps({ scheduleTimeBudget });
750
758
 
751
759
  rebuildRuntime(run, deps, makeHandlers());
@@ -1,4 +1,4 @@
1
- // src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts
1
+ // src/orchestration/__tests__/worker-message-pump-postmessage-defense.test.ts
2
2
  //
3
3
  // W2: 主线程层 postMessage 防御测试。
4
4
  //
@@ -35,13 +35,13 @@ vi.mock("../../core/logger.ts", () => ({
35
35
  getLogger: () => loggerMock,
36
36
  }));
37
37
 
38
- import { handleWorkerMessage, postBudgetUpdate } from "../error-recovery.ts";
38
+ import { handleWorkerMessage, postBudgetUpdate } from "../worker-message-pump.ts";
39
39
  import type { LifecycleDeps, WorkerHandlers } from "../models/ports.ts";
40
40
  import type { WorkflowRun } from "../models/workflow-run.ts";
41
41
 
42
42
  const __dirname = dirname(fileURLToPath(import.meta.url));
43
- const ERROR_RECOVERY_SRC = readFileSync(
44
- join(__dirname, "../error-recovery.ts"),
43
+ const WORKER_MESSAGE_PUMP_SRC = readFileSync(
44
+ join(__dirname, "../worker-message-pump.ts"),
45
45
  "utf-8",
46
46
  );
47
47
 
@@ -273,7 +273,7 @@ describe("W2b: dispatchWorkflowCall postResult 防御 DataCloneError", () => {
273
273
  // 子进程)。利用这一点构造行为测试——往 cached.result 里塞不可克隆值(function),
274
274
  // mock postMessage 在首次发送 agent-result 时抛 DataCloneError,验证 fallback 路径。
275
275
  //
276
- // 另外补充:验证 error-recovery.ts 源码中三处 postMessage 调用点都有 try/catch 包裹,
276
+ // 另外补充:验证 worker-message-pump.ts 源码中三处 postMessage 调用点都有 try/catch 包裹,
277
277
  // 防止未来重构误删防御(类似 worker-script-builder.test.ts 的源码字符串断言模式)。
278
278
 
279
279
  /** 构造 status="running" 且 calls 已含一个 done 结果(含不可克隆成员)的 mock run。
@@ -376,7 +376,7 @@ describe("W2c: postAgentResult 防御(源码结构断言)", () => {
376
376
  }
377
377
 
378
378
  it("postAgentResult 包含 try/catch + fallback result", () => {
379
- const match = ERROR_RECOVERY_SRC.match(/function postAgentResult\([\s\S]*?\n\}/);
379
+ const match = WORKER_MESSAGE_PUMP_SRC.match(/function postAgentResult\([\s\S]*?\n\}/);
380
380
  expect(match, "postAgentResult 函数定义应存在").toBeTruthy();
381
381
  expect(hasTryCatchAroundPostMessage(match![0])).toBe(true);
382
382
  // fallback 通过共享工厂 makeSerializeFailedResult 构造纯字符串 result(必可克隆)
@@ -387,14 +387,14 @@ describe("W2c: postAgentResult 防御(源码结构断言)", () => {
387
387
  });
388
388
 
389
389
  it("postBudgetUpdate 包含 try/catch", () => {
390
- const match = ERROR_RECOVERY_SRC.match(/export function postBudgetUpdate\([\s\S]*?\n\}/);
390
+ const match = WORKER_MESSAGE_PUMP_SRC.match(/export function postBudgetUpdate\([\s\S]*?\n\}/);
391
391
  expect(match, "postBudgetUpdate 函数定义应存在").toBeTruthy();
392
392
  expect(hasTryCatchAroundPostMessage(match![0])).toBe(true);
393
393
  });
394
394
 
395
395
  it("dispatchWorkflowCall postResult 闭包包含 try/catch + fallback", () => {
396
396
  // postResult 是 const 闭包,匹配到下一个 }; 结尾
397
- const match = ERROR_RECOVERY_SRC.match(/const postResult = \(result[\s\S]*?\n \};/);
397
+ const match = WORKER_MESSAGE_PUMP_SRC.match(/const postResult = \(result[\s\S]*?\n \};/);
398
398
  expect(match, "postResult 闭包定义应存在").toBeTruthy();
399
399
  expect(hasTryCatchAroundPostMessage(match![0])).toBe(true);
400
400
  expect(match![0]).toContain("Workflow result serialization failed");
@@ -1,4 +1,4 @@
1
- // src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts
1
+ // src/orchestration/__tests__/worker-message-pump-serialize-failed-result.test.ts
2
2
  //
3
3
  // makeSerializeFailedResult 独立单测(W2 防御关键纯函数)。
4
4
  //
@@ -15,7 +15,7 @@
15
15
 
16
16
  import { describe, expect, it } from "vitest";
17
17
 
18
- import { makeSerializeFailedResult } from "../error-recovery.ts";
18
+ import { makeSerializeFailedResult } from "../worker-message-pump.ts";
19
19
 
20
20
  describe("makeSerializeFailedResult", () => {
21
21
  it("返回 {content:'', error:'<prefix>: <errMsg>'} 形状(必可克隆 fallback)", () => {
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { describe, expect, it, vi } from "vitest";
12
12
 
13
- import { handleWorkerMessage } from "../error-recovery.ts";
13
+ import { handleWorkerMessage } from "../worker-message-pump.ts";
14
14
  import type { LifecycleDeps, WorkerHandlers } from "../models/ports.ts";
15
15
  import type { WorkflowRun } from "../models/workflow-run.ts";
16
16
 
@@ -105,7 +105,7 @@ function runWorker(userScript: string, opts: RunOptions = {}): Promise<RunResult
105
105
  worker.on("message", (raw: unknown) => {
106
106
  if (isAgentCall(raw)) {
107
107
  result.agentCallCount += 1;
108
- opts.onAgentCall?.(raw as { callId: number; opts: Record<string, unknown> }, worker);
108
+ opts.onAgentCall?.(raw as unknown as { callId: number; opts: Record<string, unknown> }, worker);
109
109
  return;
110
110
  }
111
111
  if (isReturn(raw)) {
@@ -225,7 +225,7 @@ describe("buildWorkerScript — W2 agent() returnMeta mode", () => {
225
225
  // ── thinkingLevel 参数透传(agent() 三分支) ──
226
226
  // 验证 thinkingLevel 在 string / task-agent / object.prompt 三个分支均被透传至
227
227
  // agent-call 的 opts,且加入 _knownFields 白名单(object.prompt 分支整体透传,
228
- // 不被 unknown-fields warn 误报)。底层 AgentCallOpts→mapToExecuteOptions→
228
+ // 不被 unknown-fields warn 误报)。底层 AgentCallOpts(D6 合流后 EnginePort 直传,
229
229
  // buildSpawnArgs 拼 pi CLI --model provider/modelId:thinkingLevel 已打通,
230
230
  // 此处只验入口层 wiring。
231
231
 
@@ -43,7 +43,7 @@ describe("saveWorkflow 目录注入(非 .pi 布局)", () => {
43
43
  expect(existsSync(join(tmpDir, "alpha.js"))).toBe(false);
44
44
  expect(readFileSync(join(savedDir, "alpha.js"), "utf-8")).toBe("// alpha body");
45
45
  } finally {
46
- rmSync(root, { recursive: true, force: true });
46
+ rmSync(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
47
47
  }
48
48
  });
49
49
 
@@ -56,7 +56,7 @@ describe("saveWorkflow 目录注入(非 .pi 布局)", () => {
56
56
  expect(existsSync(join(savedDir, "alpha.js"))).toBe(false);
57
57
  expect(existsSync(join(savedDir, "beta.js"))).toBe(true);
58
58
  } finally {
59
- rmSync(root, { recursive: true, force: true });
59
+ rmSync(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
60
60
  }
61
61
  });
62
62
 
@@ -72,7 +72,7 @@ describe("saveWorkflow 目录注入(非 .pi 布局)", () => {
72
72
  // 原文件不动
73
73
  expect(existsSync(join(tmpDir, "alpha.js"))).toBe(true);
74
74
  } finally {
75
- rmSync(root, { recursive: true, force: true });
75
+ rmSync(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
76
76
  }
77
77
  });
78
78
 
@@ -83,7 +83,7 @@ describe("saveWorkflow 目录注入(非 .pi 布局)", () => {
83
83
  "Temporary workflow 'ghost' not found",
84
84
  );
85
85
  } finally {
86
- rmSync(root, { recursive: true, force: true });
86
+ rmSync(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
87
87
  }
88
88
  });
89
89
  });
@@ -104,7 +104,7 @@ describe("deleteWorkflow 目录注入(非 .pi 布局)", () => {
104
104
  expect(existsSync(join(tmpDir, "dup.js"))).toBe(false);
105
105
  expect(existsSync(join(savedDir, "dup.js"))).toBe(true);
106
106
  } finally {
107
- rmSync(root, { recursive: true, force: true });
107
+ rmSync(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
108
108
  }
109
109
  });
110
110
 
@@ -117,7 +117,7 @@ describe("deleteWorkflow 目录注入(非 .pi 布局)", () => {
117
117
  expect(msg).toBe(`Deleted workflow 'gamma' (${join(savedDir, "gamma.js")})`);
118
118
  expect(existsSync(join(savedDir, "gamma.js"))).toBe(false);
119
119
  } finally {
120
- rmSync(root, { recursive: true, force: true });
120
+ rmSync(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
121
121
  }
122
122
  });
123
123
 
@@ -130,7 +130,7 @@ describe("deleteWorkflow 目录注入(非 .pi 布局)", () => {
130
130
  ).toThrow("Cannot delete 'busy': workflow is currently running. Abort it first.");
131
131
  expect(existsSync(join(tmpDir, "busy.js"))).toBe(true);
132
132
  } finally {
133
- rmSync(root, { recursive: true, force: true });
133
+ rmSync(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
134
134
  }
135
135
  });
136
136
 
@@ -141,7 +141,7 @@ describe("deleteWorkflow 目录注入(非 .pi 布局)", () => {
141
141
  "Workflow file 'void' not found",
142
142
  );
143
143
  } finally {
144
- rmSync(root, { recursive: true, force: true });
144
+ rmSync(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
145
145
  }
146
146
  });
147
147
  });
@@ -164,7 +164,7 @@ describe("缺省目录 = pi 布局(向后兼容回归)", () => {
164
164
  expect(existsSync(join(fakeCwd, ".pi", "workflows", "pi-wf.js"))).toBe(true);
165
165
  } finally {
166
166
  cwdSpy.mockRestore();
167
- rmSync(fakeCwd, { recursive: true, force: true });
167
+ rmSync(fakeCwd, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
168
168
  }
169
169
  });
170
170
 
@@ -180,7 +180,7 @@ describe("缺省目录 = pi 布局(向后兼容回归)", () => {
180
180
  expect(existsSync(join(savedDir, "saved-only.js"))).toBe(false);
181
181
  } finally {
182
182
  cwdSpy.mockRestore();
183
- rmSync(fakeCwd, { recursive: true, force: true });
183
+ rmSync(fakeCwd, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
184
184
  }
185
185
  });
186
186
  });
@@ -24,7 +24,7 @@ vi.mock("../lifecycle.ts", () => ({
24
24
  scheduleTimeBudget: vi.fn(() => undefined),
25
25
  }));
26
26
 
27
- import { handleWorkerMessage } from "../error-recovery.ts";
27
+ import { handleWorkerMessage } from "../worker-message-pump.ts";
28
28
  import { executeNestedWorkflow, type LauncherDeps } from "../launcher.ts";
29
29
  import { runWorkflow } from "../lifecycle.ts";
30
30
  import { Budget } from "../models/budget.ts";
@@ -59,7 +59,7 @@ describe("loadWorkflowScriptByPath / WorkflowScript 导出形态(U1)", () =>
59
59
  afterEach(async () => {
60
60
  invalidateCache();
61
61
  for (const dir of tempDirs) {
62
- await rm(dir, { recursive: true, force: true });
62
+ await rm(dir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
63
63
  }
64
64
  });
65
65