@zhushanwen/subagent-core 0.5.1 → 0.7.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 (318) hide show
  1. package/README.md +1 -1
  2. package/dist/chunk-KXVBIVOU.js +16 -0
  3. package/dist/chunk-T2SYBW3I.js +24 -0
  4. package/dist/chunk-VURUAGMM.js +2305 -0
  5. package/dist/{types-Dv4QhSJ_.d.cts → engine-discovery-scan-ocpM8FmI.d.cts} +835 -668
  6. package/dist/{types-Dv4QhSJ_.d.ts → engine-discovery-scan-ocpM8FmI.d.ts} +835 -668
  7. package/dist/execution/engine/engine-discovery-scan.cjs +2210 -0
  8. package/dist/execution/engine/engine-discovery-scan.d.cts +4 -0
  9. package/dist/execution/engine/engine-discovery-scan.d.ts +4 -0
  10. package/dist/execution/engine/engine-discovery-scan.js +20 -0
  11. package/dist/execution/engine/paths.cjs +6 -23
  12. package/dist/execution/engine/paths.d.cts +1 -8
  13. package/dist/execution/engine/paths.d.ts +1 -8
  14. package/dist/execution/engine/paths.js +1 -1
  15. package/dist/execution/relay-env.cjs +12 -28
  16. package/dist/execution/relay-env.d.cts +1 -33
  17. package/dist/execution/relay-env.d.ts +1 -33
  18. package/dist/execution/relay-env.js +5 -3
  19. package/dist/index.cjs +14123 -15467
  20. package/dist/index.d.cts +1179 -1540
  21. package/dist/index.d.ts +1179 -1540
  22. package/dist/index.js +7694 -10986
  23. package/dist.bundle/index.cjs +33485 -0
  24. package/package.json +20 -26
  25. package/src/__tests__/record-store-last-line.test.ts +16 -7
  26. package/src/core/error-message.ts +7 -6
  27. package/src/core/host-services.ts +8 -2
  28. package/src/core/notify-ports.ts +17 -2
  29. package/src/execution/__tests__/agent-registry.test.ts +1 -1
  30. package/src/execution/__tests__/alive-store.test.ts +1 -1
  31. package/src/execution/__tests__/chat-engine-routing.test.ts +62 -28
  32. package/src/execution/__tests__/chat-round-first-round-watchdog.test.ts +255 -0
  33. package/src/execution/__tests__/collect-budget.test.ts +291 -0
  34. package/src/execution/__tests__/collect-coordinator-service.test.ts +316 -0
  35. package/src/execution/__tests__/collect-coordinator.test.ts +371 -0
  36. package/src/execution/__tests__/collect-mixed-dispatch.test.ts +229 -0
  37. package/src/execution/__tests__/config-collect-sync.test.ts +120 -0
  38. package/src/execution/__tests__/config.test.ts +1 -1
  39. package/src/execution/__tests__/delivery-methods.test.ts +179 -237
  40. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -2
  41. package/src/execution/__tests__/execute-nesting.test.ts +20 -13
  42. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +21 -34
  43. package/src/execution/__tests__/finalized-marker.test.ts +1 -1
  44. package/src/execution/__tests__/gc-timer.test.ts +8 -23
  45. package/src/execution/__tests__/get-record-for-action-restart.test.ts +20 -10
  46. package/src/execution/__tests__/helpers/fake-engine-port.ts +187 -0
  47. package/src/execution/__tests__/helpers/spawn-mock.ts +36 -9
  48. package/src/execution/__tests__/helpers/subagent-service-mocks.ts +1 -1
  49. package/src/execution/__tests__/idle-gc.test.ts +200 -0
  50. package/src/execution/__tests__/lifecycle-predicates.test.ts +26 -21
  51. package/src/execution/__tests__/manifest-store-tmp-recovery.test.ts +1 -1
  52. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +5 -2
  53. package/src/execution/__tests__/notify-batch.test.ts +500 -0
  54. package/src/execution/__tests__/notify-ledger.test.ts +27 -0
  55. package/src/execution/__tests__/reconcile-sweep.test.ts +200 -0
  56. package/src/execution/__tests__/record-entry-collect.test.ts +102 -0
  57. package/src/execution/__tests__/record-store.test.ts +60 -6
  58. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +20 -13
  59. package/src/execution/__tests__/relay-env.test.ts +12 -1
  60. package/src/execution/__tests__/round-supervisor.test.ts +293 -0
  61. package/src/execution/__tests__/session-file-gc.test.ts +1 -1
  62. package/src/execution/__tests__/session-pending.test.ts +119 -17
  63. package/src/execution/__tests__/start-collect-guard.test.ts +255 -0
  64. package/src/execution/__tests__/stream-sink-retirement.test.ts +10 -10
  65. package/src/execution/__tests__/subagent-actions-core.test.ts +6 -0
  66. package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +14 -11
  67. package/src/execution/__tests__/subagent-service-notify-gate.test.ts +33 -30
  68. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +2 -9
  69. package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +59 -129
  70. package/src/execution/__tests__/subagent-service.test.ts +2 -2
  71. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +109 -7
  72. package/src/execution/__tests__/subprocess-agent-runner.test.ts +108 -36
  73. package/src/execution/__tests__/sync-collect-recovery.test.ts +1102 -0
  74. package/src/execution/__tests__/tombstone-store.test.ts +1 -1
  75. package/src/execution/__tests__/workflow-state-root.test.ts +232 -0
  76. package/src/execution/__tests__/worktree-git-ops.test.ts +1 -1
  77. package/src/execution/__tests__/worktree-reconcile-aging.test.ts +2 -2
  78. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +1 -1
  79. package/src/execution/__tests__/worktree-registry.test.ts +1 -1
  80. package/src/execution/agent-registry.ts +6 -2
  81. package/src/execution/collect-coordinator.ts +200 -0
  82. package/src/execution/config.ts +77 -5
  83. package/src/execution/dialog-queue.ts +6 -73
  84. package/src/execution/engine/__tests__/common/capability-gate.test.ts +115 -15
  85. package/src/execution/engine/__tests__/common/errors.test.ts +11 -18
  86. package/src/execution/engine/__tests__/common/event-journal.test.ts +1 -1
  87. package/src/execution/engine/__tests__/common/kill-chain.test.ts +7 -0
  88. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +9 -3
  89. package/src/execution/engine/__tests__/common/pool-manager.test.ts +2 -2
  90. package/src/execution/engine/__tests__/common/session-view-service.test.ts +90 -3
  91. package/src/execution/engine/__tests__/conformance/H9-test-disposition.md +116 -0
  92. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/fake-engine-protocol.mjs +377 -0
  93. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/recorded.fixture.json +331 -0
  94. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/smoke-run.fixture.json +213 -0
  95. package/src/execution/engine/__tests__/conformance/chat-round-protocol.test.ts +230 -0
  96. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +69 -42
  97. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +4 -81
  98. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +67 -44
  99. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +82 -55
  100. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +133 -70
  101. package/src/execution/engine/__tests__/conformance/engine-crash.test.ts +143 -0
  102. package/src/execution/engine/__tests__/conformance/fake-engine-capabilities.ts +19 -0
  103. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +8 -3
  104. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +6 -5
  105. package/src/execution/engine/__tests__/conformance/protocol-blackbox.test.ts +398 -0
  106. package/src/execution/engine/__tests__/conformance/registry-fork-filter.test.ts +221 -0
  107. package/src/execution/engine/__tests__/conformance/round-liveness-supervisor.test.ts +302 -0
  108. package/src/execution/engine/__tests__/conformance/static-spawn-guard.test.ts +58 -0
  109. package/src/execution/engine/__tests__/engine-discovery-scan.test.ts +558 -0
  110. package/src/execution/engine/__tests__/host-task-spec.test.ts +45 -0
  111. package/src/execution/engine/__tests__/model-ref-split.test.ts +74 -0
  112. package/src/execution/engine/__tests__/registry.test.ts +206 -1
  113. package/src/execution/engine/__tests__/routing.test.ts +97 -0
  114. package/src/execution/engine/__tests__/run-failure-worktree-cleanup.test.ts +97 -0
  115. package/src/execution/engine/client/__tests__/__fixtures__/fake-engine.mjs +294 -0
  116. package/src/execution/engine/client/__tests__/engine-client.test.ts +516 -0
  117. package/src/execution/engine/client/__tests__/mirror.test.ts +67 -0
  118. package/src/execution/engine/client/__tests__/pid-file.test.ts +257 -0
  119. package/src/execution/engine/client/__tests__/protocol-closure.test.ts +95 -0
  120. package/src/execution/engine/client/__tests__/remote-engine.test.ts +457 -0
  121. package/src/execution/engine/client/client-options.ts +103 -0
  122. package/src/execution/engine/client/engine-client.ts +687 -0
  123. package/src/execution/engine/client/mirror.ts +167 -0
  124. package/src/execution/engine/client/pid-file.ts +392 -0
  125. package/src/execution/engine/client/reaper.ts +95 -0
  126. package/src/execution/engine/client/remote-engine.ts +441 -0
  127. package/src/execution/engine/client/reverse-router.ts +255 -0
  128. package/src/execution/engine/common/capability-gate.ts +109 -22
  129. package/src/execution/engine/common/errors.ts +9 -25
  130. package/src/execution/engine/common/event-journal.ts +4 -50
  131. package/src/execution/engine/common/journal-replay.ts +3 -1
  132. package/src/execution/engine/common/kill-chain.ts +18 -251
  133. package/src/execution/engine/common/nesting-guard.ts +18 -114
  134. package/src/execution/engine/common/pool-manager.ts +4 -0
  135. package/src/execution/engine/common/session-view-service.ts +56 -84
  136. package/src/execution/engine/config.ts +151 -0
  137. package/src/execution/engine/d8-compat.ts +346 -0
  138. package/src/execution/engine/engine-discovery-roots.ts +107 -0
  139. package/src/execution/engine/engine-discovery-scan.ts +269 -0
  140. package/src/execution/engine/engine-discovery.ts +30 -7
  141. package/src/execution/engine/engine-inspect-package.ts +282 -0
  142. package/src/execution/engine/engine-manifest.ts +244 -0
  143. package/src/execution/engine/host/__tests__/host-askuser-endpoint.test.ts +123 -0
  144. package/src/execution/engine/host/__tests__/host-bridge.test.ts +135 -0
  145. package/src/execution/engine/host/__tests__/spawned-children.test.ts +73 -0
  146. package/src/execution/engine/host/host-bridge.ts +150 -0
  147. package/src/execution/engine/host/host-ui-endpoint.ts +47 -0
  148. package/src/execution/engine/host/pi-host-binding.ts +91 -0
  149. package/src/execution/engine/host/spawned-children.ts +139 -0
  150. package/src/execution/engine/host-task-spec.ts +29 -2
  151. package/src/execution/engine/model-validation.ts +55 -2
  152. package/src/execution/engine/paths.ts +16 -41
  153. package/src/execution/engine/port.ts +48 -2
  154. package/src/execution/engine/registry.ts +153 -34
  155. package/src/execution/engine/routing.ts +225 -52
  156. package/src/execution/engine/types.ts +25 -200
  157. package/src/execution/execution-record.ts +7 -0
  158. package/src/execution/finalize-record.ts +40 -11
  159. package/src/execution/idle-gc.ts +89 -14
  160. package/src/execution/lifecycle-manager.ts +10 -7
  161. package/src/execution/lifecycle-predicates.ts +10 -8
  162. package/src/execution/notifier.ts +234 -25
  163. package/src/execution/notify-host.ts +21 -1
  164. package/src/execution/record-entry.ts +16 -0
  165. package/src/execution/record-store.ts +189 -31
  166. package/src/execution/relay-env.ts +19 -36
  167. package/src/execution/round-supervisor/domain.ts +89 -0
  168. package/src/execution/round-supervisor/index.ts +33 -0
  169. package/src/execution/round-supervisor/notify-accounting.ts +87 -0
  170. package/src/execution/round-supervisor/reconcile-sweep.ts +235 -0
  171. package/src/execution/round-supervisor/service-binding.test.ts +661 -0
  172. package/src/execution/round-supervisor/service-binding.ts +273 -0
  173. package/src/execution/round-supervisor/supervisor.ts +426 -0
  174. package/src/execution/session-pending.ts +68 -74
  175. package/src/execution/settled-watchdog.ts +39 -0
  176. package/src/execution/subagent-actions-core.ts +62 -6
  177. package/src/execution/subagent-service.ts +1161 -406
  178. package/src/execution/subprocess-agent-runner.ts +16 -8
  179. package/src/execution/sync-rebuild.ts +87 -0
  180. package/src/execution/types.ts +104 -117
  181. package/src/execution/ui-channels.ts +13 -214
  182. package/src/execution/ui-request-handler-factory.ts +7 -4
  183. package/src/execution/ui-request-observability.ts +2 -2
  184. package/src/execution/workflow-state-root.ts +67 -0
  185. package/src/execution/worktree-git-ops.ts +5 -0
  186. package/src/execution/worktree-manager.ts +11 -1
  187. package/src/index.ts +55 -26
  188. package/src/orchestration/__tests__/config-loader.test.ts +1 -1
  189. package/src/orchestration/__tests__/execute-agent-call.test.ts +1 -1
  190. package/src/orchestration/__tests__/file-run-store-prune.test.ts +1 -1
  191. package/src/orchestration/__tests__/file-run-store-throttle.test.ts +1 -1
  192. package/src/orchestration/__tests__/review-fix-loop-scriptpath-failfast.test.ts +1 -1
  193. package/src/orchestration/__tests__/script-generate.test.ts +5 -5
  194. package/src/orchestration/__tests__/skill-discovery.test.ts +2 -2
  195. package/src/orchestration/__tests__/workflow-files.test.ts +10 -10
  196. package/src/orchestration/__tests__/workflow-script-registry-impl.test.ts +1 -1
  197. package/src/orchestration/execute-agent-call.ts +1 -1
  198. package/src/orchestration/file-run-store.ts +144 -59
  199. package/src/orchestration/models/types.ts +43 -42
  200. package/src/shared/__tests__/atomic-write.test.ts +1 -1
  201. package/src/shared/__tests__/resource-discovery-host-roots.test.ts +5 -5
  202. package/src/shared/zcode-model-ref.ts +31 -0
  203. package/dist/chunk-43ONBFZX.js +0 -240
  204. package/dist/chunk-A4IVZWVX.js +0 -31
  205. package/dist/chunk-APZY4IME.js +0 -27
  206. package/dist/chunk-V3VHZ2VX.js +0 -59
  207. package/dist/execution/engine/engines/zcode/constants.cjs +0 -107
  208. package/dist/execution/engine/engines/zcode/constants.d.cts +0 -135
  209. package/dist/execution/engine/engines/zcode/constants.d.ts +0 -135
  210. package/dist/execution/engine/engines/zcode/constants.js +0 -54
  211. package/dist/execution/engine/engines/zcode/reader.cjs +0 -276
  212. package/dist/execution/engine/engines/zcode/reader.d.cts +0 -21
  213. package/dist/execution/engine/engines/zcode/reader.d.ts +0 -21
  214. package/dist/execution/engine/engines/zcode/reader.js +0 -9
  215. package/src/__tests__/append-system-prompt-assembly.test.ts +0 -243
  216. package/src/__tests__/fr4-get-state-handshake.test.ts +0 -125
  217. package/src/__tests__/session-runner.test.ts +0 -69
  218. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  219. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -191
  220. package/src/execution/__tests__/descendant-sweep-guards.test.ts +0 -220
  221. package/src/execution/__tests__/descendant-sweep.test.ts +0 -269
  222. package/src/execution/__tests__/engine-model-validation.test.ts +0 -741
  223. package/src/execution/__tests__/epipe-fallback.test.ts +0 -248
  224. package/src/execution/__tests__/execution-runtime-face.test.ts +0 -272
  225. package/src/execution/__tests__/get-state-handshake.test.ts +0 -127
  226. package/src/execution/__tests__/helpers/session-runner-mocks.ts +0 -113
  227. package/src/execution/__tests__/keep-alive-no-progress.test.ts +0 -280
  228. package/src/execution/__tests__/kill-all-escalation.test.ts +0 -196
  229. package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +0 -113
  230. package/src/execution/__tests__/output-collector.test.ts +0 -469
  231. package/src/execution/__tests__/pi-invocation.test.ts +0 -134
  232. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -149
  233. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  234. package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +0 -387
  235. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -277
  236. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -254
  237. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -1079
  238. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  239. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  240. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  241. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +0 -207
  242. package/src/execution/__tests__/service-kill-escalation.test.ts +0 -91
  243. package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +0 -110
  244. package/src/execution/__tests__/session-runner-close-prune.test.ts +0 -181
  245. package/src/execution/__tests__/session-runner-dispatch.test.ts +0 -489
  246. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -179
  247. package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +0 -227
  248. package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +0 -290
  249. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -352
  250. package/src/execution/__tests__/settled-watchdog.test.ts +0 -524
  251. package/src/execution/__tests__/spawn-args.test.ts +0 -446
  252. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -192
  253. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  254. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -208
  255. package/src/execution/__tests__/spawned-children.test.ts +0 -236
  256. package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
  257. package/src/execution/__tests__/stdin-writer.test.ts +0 -464
  258. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -693
  259. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  260. package/src/execution/__tests__/timeout-integration.test.ts +0 -616
  261. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  262. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  263. package/src/execution/__tests__/ui-request-handler.test.ts +0 -205
  264. package/src/execution/__tests__/ui-request-queue.test.ts +0 -298
  265. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -230
  266. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  267. package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +0 -149
  268. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  269. package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +0 -128
  270. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  271. package/src/execution/engine/common/schema-emulation.ts +0 -189
  272. package/src/execution/engine/common/session-view-projection.ts +0 -51
  273. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -615
  274. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  275. package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +0 -257
  276. package/src/execution/engine/engines/pi/argv-mirror.ts +0 -135
  277. package/src/execution/engine/engines/pi/get-state-handshake.ts +0 -179
  278. package/src/execution/engine/engines/pi/output-collector.ts +0 -317
  279. package/src/execution/engine/engines/pi/pi-engine.ts +0 -811
  280. package/src/execution/engine/engines/pi/pi-invocation.ts +0 -120
  281. package/src/execution/engine/engines/pi/reader.ts +0 -59
  282. package/src/execution/engine/engines/pi/registration.ts +0 -37
  283. package/src/execution/engine/engines/pi/session-runner.ts +0 -2840
  284. package/src/execution/engine/engines/pi/spawn-event-adapter.ts +0 -404
  285. package/src/execution/engine/engines/pi/stdin-writer.ts +0 -199
  286. package/src/execution/engine/engines/pi/temp-prompt.ts +0 -62
  287. package/src/execution/engine/engines/pi/turn-limiter.ts +0 -102
  288. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +0 -301
  289. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +0 -36
  290. package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +0 -321
  291. package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +0 -473
  292. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -43
  293. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -124
  294. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  295. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -71
  296. package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +0 -247
  297. package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +0 -451
  298. package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +0 -792
  299. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +0 -782
  300. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +0 -168
  301. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +0 -210
  302. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +0 -353
  303. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +0 -282
  304. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +0 -372
  305. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -145
  306. package/src/execution/engine/engines/zcode/appserver-launcher.ts +0 -167
  307. package/src/execution/engine/engines/zcode/connection.ts +0 -598
  308. package/src/execution/engine/engines/zcode/constants.ts +0 -176
  309. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -47
  310. package/src/execution/engine/engines/zcode/parser.ts +0 -102
  311. package/src/execution/engine/engines/zcode/preparer.ts +0 -235
  312. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  313. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  314. package/src/execution/engine/engines/zcode/session-channel.ts +0 -968
  315. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -1431
  316. package/src/execution/round-settlement.ts +0 -93
  317. package/src/execution/ui-request-queue.ts +0 -215
  318. package/src/shared/schema-env.ts +0 -44
@@ -32,7 +32,6 @@ import {
32
32
  finalizedMarkerModule,
33
33
  fsSyncModule,
34
34
  manifestStoreModule,
35
- tempPromptModule,
36
35
  } from "./helpers/subagent-service-mocks.ts";
37
36
 
38
37
  vi.mock("node:child_process", () => childProcessModule());
@@ -40,11 +39,11 @@ vi.mock("node:fs", async (importOriginal) => fsSyncModule(await importOriginal<t
40
39
  vi.mock("../alive-store.ts", async (importOriginal) => aliveStoreModule(await importOriginal<typeof import("../alive-store.ts")>()));
41
40
  vi.mock("../finalized-marker.ts", () => finalizedMarkerModule());
42
41
  vi.mock("../manifest-store.ts", () => manifestStoreModule());
43
- vi.mock("../engine/engines/pi/temp-prompt.ts", () => tempPromptModule());
44
42
 
45
43
  import { spawn } from "node:child_process";
46
44
 
47
- import { waitForSpawn, lastSpawnedChild } from "./helpers/spawn-mock.ts";
45
+ import { registerFakePiEngine, type FakePiEnginePort } from "./helpers/fake-engine-port.ts";
46
+ import { clearEngines } from "../engine/registry.ts";
48
47
  import { ModelConfigService } from "../model-config-service.ts";
49
48
  import type { ModelInfo, ModelRegistryLike } from "../model-resolver.ts";
50
49
  import { MAX_FORK_DEPTH } from "../session-context-resolver.ts";
@@ -85,6 +84,15 @@ function setup(): SetupResult {
85
84
  return { service };
86
85
  }
87
86
 
87
+ /** [W3] 协议替身注册 + 受控 settle(原 driveChildToCompletion 的等价驱动面):
88
+ * execute 发起的 engine.run 由测试显式应答(轮终语义对齐 driveChild 的 close(0))。 */
89
+ function setupWithFakeEngine(): SetupResult & { fake: FakePiEnginePort } {
90
+ const base = setup();
91
+ clearEngines();
92
+ const fake = registerFakePiEngine();
93
+ return { ...base, fake };
94
+ }
95
+
88
96
  const ctxModel: ModelInfo = { id: "m", name: "M", provider: "p", reasoning: false };
89
97
 
90
98
  /** [D3-⑤] execNesting(公共层 ExecutionNestingContext).run 的 duck-type(绕过
@@ -103,15 +111,15 @@ describe("嵌套护栏 / 并发池 / 节流(D-030~D-033 回归锁)", () => {
103
111
  // ============================================================
104
112
 
105
113
  it("[D-032] background execute 调 pool.acquire(进池限流)", async () => {
106
- const { service } = setup();
114
+ const { service, fake } = setupWithFakeEngine();
107
115
 
108
116
  const pool = Reflect.get(service, "pool") as { acquire: ReturnType<typeof vi.fn>; release: ReturnType<typeof vi.fn> };
109
117
  const acquireSpy = vi.spyOn(pool, "acquire");
110
118
 
111
119
  const execPromise = service.execute({ task: "bg in pool", slug: "test", ctxModel });
112
- // detached runAndFinalize → acquire。等 spawn 拿到 child 再驱动完成。
113
- await waitForSpawn(mockSpawn);
114
- await driveChildToCompletion(lastSpawnedChild(mockSpawn));
120
+ // detached kickOffChatRound → acquire。等替身 run 到位再驱动应答。
121
+ await vi.waitFor(() => expect(fake.runs.length).toBe(1));
122
+ fake.runs[0]!.settle({ content: "ok" });
115
123
 
116
124
  // 等 detached promise 链跑完(kickOffChatRound 的 .then notify)
117
125
  await new Promise<void>((r) => setTimeout(r, 10));
@@ -120,6 +128,7 @@ describe("嵌套护栏 / 并发池 / 节流(D-030~D-033 回归锁)", () => {
120
128
  // background execute 立即返回 handle(不等完成)
121
129
  const handle = await execPromise;
122
130
  expect(handle.mode).toBe("background");
131
+ clearEngines();
123
132
  });
124
133
 
125
134
  // ============================================================
@@ -144,21 +153,19 @@ describe("嵌套护栏 / 并发池 / 节流(D-030~D-033 回归锁)", () => {
144
153
  });
145
154
 
146
155
  it("[D-033] execCtxAls depth=MAX-1 时 execute 不抛(nestingDepth=MAX 允许)", async () => {
147
- const { service } = setup();
156
+ const { service, fake } = setupWithFakeEngine();
148
157
 
149
158
  const execNesting = Reflect.get(service, "execNesting") as ExecCtxAls;
150
159
 
151
160
  const execPromise = execNesting.run({ recordId: "parent", depth: MAX_FORK_DEPTH - 1 }, () =>
152
161
  service.execute({ task: "at limit", slug: "test", ctxModel }),
153
162
  );
154
- await waitForSpawn(mockSpawn);
155
- await driveChildToCompletion(lastSpawnedChild(mockSpawn), [
156
- { type: "turn_end" },
157
- { type: "message_end", message: { usage: { input: 1 } } },
158
- ]);
163
+ await vi.waitFor(() => expect(fake.runs.length).toBe(1));
164
+ fake.runs[0]!.settle({ content: "ok" });
159
165
  const result = await execPromise;
160
166
 
161
167
  expect(result.mode).toBe("background");
168
+ clearEngines();
162
169
  });
163
170
 
164
171
  // ============================================================
@@ -7,46 +7,31 @@
7
7
  // 错误含 <available_subagents> 恢复指引,对齐 workflow name not found 反馈风格)。
8
8
  //
9
9
  // 本文件锁住:
10
- // 1. 裸名/相对路径 agent ref → execute 同步 reject(Invalid agent ref),无 spawn、
11
- // 无子 session、record 不落盘(buildSpawnArgs/spawn/appendEntry 零触达)
10
+ // 1. 裸名/相对路径 agent ref → execute 同步 reject(Invalid agent ref),无引擎
11
+ // 派发、无子 session、record 不落盘(engine.run/appendEntry 零触达)
12
12
  // 2. 绝对路径但文件不存在 → reject(not found or unreadable)
13
13
  // 3. 对照:不传 agent(默认 general-purpose)与合法绝对路径 ref 均不误伤
14
14
  //
15
+ // [W3 改写] 原 vi.mock(inproc pi 引擎目录/session-runner)(buildSpawnArgs spy)随删件消亡
16
+ // ——「spawn 链路零触达」的结构性证据改经协议替身(engine.run 零调用)+ appendEntry
17
+ // 零触达承载;守卫位于同步裁决期、引擎派发前置的结构不变。
18
+ //
15
19
  // harness 复用 start-sync-model-guard.test.ts(真实 SubagentService + tmpdir +
16
- // mock spawn),保证守卫位于同步裁决期、spawn 前置的结构性证据可断言。
20
+ // 协议替身),保证守卫位于同步裁决期、引擎派发前置的结构性证据可断言。
17
21
 
18
- import { spawn } from "node:child_process";
19
22
  import * as fs from "node:fs";
20
23
  import * as os from "node:os";
21
24
  import * as path from "node:path";
22
25
 
23
26
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
24
27
 
25
- vi.mock("node:child_process", async () => {
26
- const actual = await import("node:child_process");
27
- return {
28
- ...actual,
29
- spawn: vi.fn(() => {
30
- throw new Error("spawn must not be called on agent-ref rejection");
31
- }),
32
- };
33
- });
34
-
35
- // buildSpawnArgs 包装为 spy(保留真实实现)——「显式 ref 拒单不触达 spawn 参数组装」的承重断言。
36
- vi.mock("../engine/engines/pi/session-runner.ts", async (importOriginal) => {
37
- const actual = await importOriginal<typeof import("../engine/engines/pi/session-runner.ts")>();
38
- return { ...actual, buildSpawnArgs: vi.fn(actual.buildSpawnArgs) };
39
- });
40
-
28
+ import { registerFakePiEngine, type FakePiEnginePort } from "./helpers/fake-engine-port.ts";
29
+ import { clearEngines } from "../engine/registry.ts";
41
30
  import { ModelConfigService } from "../model-config-service.ts";
42
31
  import type { ModelInfo, ModelRegistryLike } from "../model-resolver.ts";
43
- import { buildSpawnArgs } from "../engine/engines/pi/session-runner.ts";
44
32
  import type { PiLike } from "../subagent-service.ts";
45
33
  import { SubagentService } from "../subagent-service.ts";
46
34
 
47
- const mockSpawn = vi.mocked(spawn);
48
- const mockBuildSpawnArgs = vi.mocked(buildSpawnArgs);
49
-
50
35
  // ── 工具(start-sync-model-guard 同款)──
51
36
 
52
37
  function makeModel(over: Partial<ModelInfo> = {}): ModelInfo {
@@ -79,9 +64,12 @@ describe("显式 agent ref 失败报错(非静默降级 general-purpose)", (
79
64
  let tmpDir: string;
80
65
  let service: SubagentService;
81
66
  let pi: PiLike;
67
+ let fake: FakePiEnginePort;
82
68
 
83
69
  beforeEach(() => {
84
70
  vi.clearAllMocks();
71
+ clearEngines();
72
+ fake = registerFakePiEngine();
85
73
  tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sw-agent-ref-guard-"));
86
74
  const modelService = new ModelConfigService({ agentDir: tmpDir, cwd: tmpDir });
87
75
  modelService.initModel({
@@ -95,20 +83,20 @@ describe("显式 agent ref 失败报错(非静默降级 general-purpose)", (
95
83
 
96
84
  afterEach(() => {
97
85
  vi.restoreAllMocks();
98
- fs.rmSync(tmpDir, { recursive: true, force: true });
86
+ clearEngines();
87
+ fs.rmSync(tmpDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
99
88
  });
100
89
 
101
- // ── 拒绝路径:显式 ref 失败 → 同步 reject + spawn 链路零触达 ──
90
+ // ── 拒绝路径:显式 ref 失败 → 同步 reject + 引擎派发零触达 ──
102
91
 
103
92
  it("裸名 agent ref('worker')→ execute 同步 reject(Invalid agent ref + 恢复指引)", async () => {
104
93
  await expect(
105
94
  service.execute({ task: "probe task", slug: "ref-guard", agent: "worker" }),
106
95
  ).rejects.toThrow(/Invalid agent ref: worker.*<available_subagents>/s);
107
96
 
108
- // spawn 链路零触达 + record 未创建——非静默降级的结构性证据:
109
- // 旧行为(静默 undefined)会继续走 record 创建(appendEntry 被调)后启动子进程。
110
- expect(mockBuildSpawnArgs).not.toHaveBeenCalled();
111
- expect(mockSpawn).not.toHaveBeenCalled();
97
+ // 引擎派发零触达 + record 未创建——非静默降级的结构性证据:
98
+ // 旧行为(静默 undefined)会继续走 record 创建(appendEntry 被调)后派发引擎。
99
+ expect(fake.runs.length).toBe(0);
112
100
  expect(pi.appendEntry).not.toHaveBeenCalled();
113
101
  });
114
102
 
@@ -117,7 +105,7 @@ describe("显式 agent ref 失败报错(非静默降级 general-purpose)", (
117
105
  service.execute({ task: "probe task", slug: "ref-guard", agent: "./agents/worker.md" }),
118
106
  ).rejects.toThrow(/Invalid agent ref/);
119
107
 
120
- expect(mockBuildSpawnArgs).not.toHaveBeenCalled();
108
+ expect(fake.runs.length).toBe(0);
121
109
  expect(pi.appendEntry).not.toHaveBeenCalled();
122
110
  });
123
111
 
@@ -127,8 +115,7 @@ describe("显式 agent ref 失败报错(非静默降级 general-purpose)", (
127
115
  service.execute({ task: "probe task", slug: "ref-guard", agent: missing }),
128
116
  ).rejects.toThrow(/not found or unreadable.*<available_subagents>/s);
129
117
 
130
- expect(mockBuildSpawnArgs).not.toHaveBeenCalled();
131
- expect(mockSpawn).not.toHaveBeenCalled();
118
+ expect(fake.runs.length).toBe(0);
132
119
  expect(pi.appendEntry).not.toHaveBeenCalled();
133
120
  });
134
121
 
@@ -140,7 +127,7 @@ describe("显式 agent ref 失败报错(非静默降级 general-purpose)", (
140
127
  slug: "ref-default-ok",
141
128
  ctxModel: makeModel(),
142
129
  });
143
- // 默认语义下 identity 解析必须放行(execute 可能因 mock 环境子进程收尾而 reject,
130
+ // 默认语义下 identity 解析必须放行(execute 可能因 mock 环境引擎收尾而 reject,
144
131
  // 但错误不能是 agent ref 拒绝);record 已创建(appendEntry 发生)。
145
132
  try {
146
133
  await promise;
@@ -20,7 +20,7 @@ describe("finalized-marker", () => {
20
20
  sessionFile = path.join(tmpDir, "2026-01-01_uuid.jsonl");
21
21
  });
22
22
  afterEach(() => {
23
- fs.rmSync(tmpDir, { recursive: true, force: true });
23
+ fs.rmSync(tmpDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
24
24
  });
25
25
 
26
26
  describe("write → read 往返", () => {
@@ -1,3 +1,6 @@
1
+ // [W3 改写] 原 vi.mock(inproc pi 引擎目录/session-runner)(runSpawn 占位 + getChildByRecord
2
+ // 活进程判定)随 inproc pi 引擎目录 删除消亡——「有活进程」形态改经 core 侧 spawnedChildren
3
+ // 镜像注入(host/spawned-children.ts,isResumable 的 hasLiveProcessHandle 唯一读点)。
1
4
  // src/execution/__tests__/gc-timer.test.ts
2
5
  //
3
6
  // [M8] idle record GC 定时器测试(subagent-service.ts startGcTimer,L485-507)。
@@ -12,7 +15,6 @@
12
15
  // session-runner(import 链依赖 + isResumable 的 hasLiveProcessHandle 查询点)与 logger。
13
16
  // timer 全部 vi.useFakeTimers,不真实等待。
14
17
 
15
- import type { ChildProcess } from "node:child_process";
16
18
  import * as fs from "node:fs";
17
19
  import * as os from "node:os";
18
20
  import * as path from "node:path";
@@ -24,17 +26,6 @@ const { loggerMock } = vi.hoisted(() => ({
24
26
  }));
25
27
  vi.mock("../../core/logger.ts", () => ({ getLogger: () => loggerMock }));
26
28
 
27
- // mock session-runner:runSpawn/killAllSpawnedChildren 占位(import 链需要),
28
- // getChildByRecord 默认返回 undefined(无活进程 → isResumable=true),用例内按需覆盖。
29
- vi.mock("../engine/engines/pi/session-runner.ts", () => ({
30
- runSpawn: vi.fn(),
31
- killAllSpawnedChildren: vi.fn(),
32
- getChildByRecord: vi.fn(() => undefined),
33
- registerSpawnedChildForRecord: vi.fn(),
34
- killRecordChildWithEscalation: vi.fn(),
35
- spawnedChildren: new Map(),
36
- }));
37
-
38
29
  // [D8] idle-gc 归档时释放引擎池引用(releasePoolRef 经 getEngineDataDir 解析
39
30
  // dataDir)——测试钉到模块级 holder(vi.mock factory 闭包只能引用模块级变量),
40
31
  // beforeEach 刷新为当前 tmp agentDir,防触碰真实数据目录。
@@ -44,15 +35,13 @@ vi.mock("../engine/common/data-dir.ts", () => ({
44
35
  }));
45
36
 
46
37
  import { acquirePool } from "../engine/common/pool-manager.ts";
47
- import { getChildByRecord } from "../engine/engines/pi/session-runner.ts";
38
+ import { coreSpawnedChildrenMirror, _resetCoreSpawnedChildrenMirrorForTest } from "../engine/host/spawned-children.ts";
48
39
  import { createRecord } from "../execution-record.ts";
49
40
  import { ModelConfigService } from "../model-config-service.ts";
50
41
  import { RecordStore } from "../record-store.ts";
51
42
  import { SubagentService } from "../subagent-service.ts";
52
43
  import type { ExecutionRecord } from "../types.ts";
53
44
 
54
- const mockGetChildByRecord = vi.mocked(getChildByRecord);
55
-
56
45
  /** 与 startGcTimer 内部常量一致(1h 扫描 / 30 天 TTL)。 */
57
46
  const GC_INTERVAL_MS = 60 * 60 * 1000;
58
47
  const IDLE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
@@ -111,15 +100,14 @@ describe("[M8] idle record GC 定时器(startGcTimer)", () => {
111
100
  service = new SubagentService({ cwd: agentDir, modelService });
112
101
  service.initSession({ pi: makePi(), sessionId: "root-session" });
113
102
  store = (service as unknown as ServiceInternals).store;
114
- mockGetChildByRecord.mockReset();
115
103
  // 默认无活进程(isResumable=true)——Path B:进程已回收、可冷路径 resume 的等待续聊态
116
- mockGetChildByRecord.mockImplementation(() => undefined);
104
+ _resetCoreSpawnedChildrenMirrorForTest();
117
105
  loggerMock.warn.mockClear();
118
106
  });
119
107
 
120
108
  afterEach(() => {
121
109
  service.dispose();
122
- fs.rmSync(agentDir, { recursive: true, force: true });
110
+ fs.rmSync(agentDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
123
111
  vi.useRealTimers();
124
112
  });
125
113
 
@@ -144,12 +132,9 @@ describe("[M8] idle record GC 定时器(startGcTimer)", () => {
144
132
 
145
133
  it("有活进程的 record 不归档(isResumable=false,即使 idleSince 超 TTL)", () => {
146
134
  const fireAt = Date.now() + GC_INTERVAL_MS;
147
- // Path A:进程保活等待续聊(idle timer armed、child 未 kill)——归档会让活进程失管
135
+ // Path A:进程保活等待续聊(idle timer armed、镜像登记活句柄)——归档会让活进程失管
148
136
  store.register(makeIdleRecord("sa-live", fireAt - IDLE_TTL_MS - 1));
149
- mockGetChildByRecord.mockImplementation(
150
- (id: string): ChildProcess | undefined =>
151
- id === "sa-live" ? ({ killed: false } as unknown as ChildProcess) : undefined,
152
- );
137
+ coreSpawnedChildrenMirror().register("sa-live", { pid: 4242, killed: false });
153
138
 
154
139
  service.startGcTimer();
155
140
  vi.advanceTimersByTime(GC_INTERVAL_MS);
@@ -25,18 +25,13 @@ const { loggerMock } = vi.hoisted(() => ({
25
25
  }));
26
26
  vi.mock("../../core/logger.ts", () => ({ getLogger: () => loggerMock }));
27
27
 
28
- // mock session-runner:import 链需要(getRecordForAction 本身不调 spawn,仅守卫读
29
- // hasLiveProcessHandle——默认无活进程,与跨重启场景一致)。
30
- vi.mock("../engine/engines/pi/session-runner.ts", () => ({
31
- runSpawn: vi.fn(),
32
- killAllSpawnedChildren: vi.fn(),
33
- getChildByRecord: vi.fn(() => undefined),
34
- registerSpawnedChildForRecord: vi.fn(),
35
- killRecordChildWithEscalation: vi.fn(),
36
- spawnedChildren: new Map(),
37
- }));
28
+ // [W3 改写] 原 vi.mock(inproc pi 引擎目录/session-runner) 随删件消亡——deliverChatMessage
29
+ // 协议 seam(registerFakePiEngine 替身;跨重启无活进程 = 引擎冷路径拒绝,续聊落
30
+ // resumeColdRound 守卫链)。
38
31
 
39
32
  import { writeFinalized } from "../finalized-marker.ts";
33
+ import { registerFakePiEngine } from "./helpers/fake-engine-port.ts";
34
+ import { clearEngines } from "../engine/registry.ts";
40
35
  import { ModelConfigService } from "../model-config-service.ts";
41
36
  import { getSubagentSessionDir } from "../path-encoding.ts";
42
37
  import { RecordStore } from "../record-store.ts";
@@ -224,6 +219,14 @@ describe("[M10] getRecordForAction 跨重启磁盘重建(S3 回归场景)",
224
219
  // 不可序列化、重建后恒缺失,若无守卫 → 冷路径 resume 的 spawn cwd 静默回落主 repo
225
220
  //(隔离失效,正是 worktree 要防的并发写冲突场景)。
226
221
  it("[review round2] worktree record 跨重启重建 → hadWorktree 标记 + 续聊被拒(行动语言)", async () => {
222
+ clearEngines();
223
+ const fake = registerFakePiEngine();
224
+ // 跨重启无活进程 → 引擎冷路径拒绝 → 续聊落 resumeColdRound 守卫链
225
+ fake.interactMessageResult = {
226
+ ok: false,
227
+ code: "engine_session_not_resumable",
228
+ message: "no live process (cold path)",
229
+ };
227
230
  writeSessionJsonl(sessionsDir, {
228
231
  id: "sa-wt",
229
232
  rootSessionId: "root-session",
@@ -243,6 +246,13 @@ describe("[M10] getRecordForAction 跨重启磁盘重建(S3 回归场景)",
243
246
  });
244
247
 
245
248
  it("[review round2] 非 worktree record 跨重启重建 → 续聊不受 worktree 守卫拦截(向后兼容)", async () => {
249
+ clearEngines();
250
+ const fake = registerFakePiEngine();
251
+ fake.interactMessageResult = {
252
+ ok: false,
253
+ code: "engine_session_not_resumable",
254
+ message: "no live process (cold path)",
255
+ };
246
256
  // identity entry 无 worktree 字段(旧文件)→ found.worktree undefined → hadWorktree false
247
257
  writeSessionJsonl(sessionsDir, { id: "sa-nowt", rootSessionId: "root-session" });
248
258
 
@@ -0,0 +1,187 @@
1
+ // src/execution/__tests__/helpers/fake-engine-port.ts
2
+ //
3
+ // [W3 chat 域收口] SubagentService 编排层测试共享的 pi EnginePort 替身。
4
+ //
5
+ // 背景:chat 域执行链路自 W3 起经协议客户端(registry 'pi' 的 cli 形态 port——
6
+ // RemoteEngine)发往 pi-subagent-cli 引擎进程;原 inproc 链路的测试替身
7
+ //(vi.mock session-runner / FakeChild stdout pump)随 inproc pi 引擎目录 删除消亡。
8
+ // 本 helper 是协议 seam 的替身单源:测试经 registerEngine("pi", fake) 注入,
9
+ // 拿到 fake 实例后驱动 run/interact/roundLifecycle,断言协议交互。
10
+ //
11
+ // 消费方式(与 spawn-mock.ts 同款先例):
12
+ // const fake = registerFakePiEngine();
13
+ // await service.execute({ task: "...", conversation: true });
14
+ // fake.runs[0].settle({ content: "round text" }); // 模拟首轮 agent_settled 应答
15
+ // fake.interacts[0] // interact 受理断言
16
+ //
17
+ // 形态对照(协议语义,见 pi-subagent-cli chat-session.ts):
18
+ // - run 应答时点 = 首轮 agent_settled(outcome = 本轮内容非会话终态);
19
+ // - interact message 受理 = { ok: true, delivered: true };冷路径 = engine_session_not_resumable;
20
+ // - interact cancel = { ok: true, delivered: true }(引擎侧 SIGTERM → settle → 杀链);
21
+ // - roundLifecycle 相位由测试显式驱动(idle 帧先于 run 应答帧)。
22
+
23
+ import type { EnginePort, EngineRunResult, RunContext, ChatRoundRoute } from "../../../execution/engine/port.ts";
24
+ import type { AgentCallOpts } from "../../../orchestration/models/types.ts";
25
+ import type {
26
+ AgentOutcome,
27
+ EngineCapabilities,
28
+ EngineHandle,
29
+ InteractAction,
30
+ InteractResult,
31
+ ProbeReport,
32
+ SessionView,
33
+ } from "../../../execution/engine/types.ts";
34
+ import { registerEngine } from "../../../execution/engine/registry.ts";
35
+
36
+ /** 一次 run 调用的捕获(task + ctx + 结算控制面)。 */
37
+ export class FakeRun {
38
+ readonly task: AgentCallOpts;
39
+ readonly ctx: RunContext;
40
+ private resolve!: (r: EngineRunResult) => void;
41
+ private reject!: (err: unknown) => void;
42
+ readonly promise: Promise<EngineRunResult>;
43
+
44
+ constructor(task: AgentCallOpts, ctx: RunContext) {
45
+ this.task = task;
46
+ this.ctx = ctx;
47
+ this.promise = new Promise<EngineRunResult>((res, rej) => {
48
+ this.resolve = res;
49
+ this.reject = rej;
50
+ });
51
+ }
52
+
53
+ /** 模拟 run 正常应答(首轮 agent_settled 口径;outcome 缺省 = 成功空轮)。 */
54
+ settle(outcome: Partial<AgentOutcome> = {}): void {
55
+ this.resolve({
56
+ handle: {
57
+ data: {
58
+ v: 1,
59
+ engineId: "pi",
60
+ sessionRef: { recordId: this.ctx.taskId },
61
+ poolKey: "shared",
62
+ adapterVersion: "fake-engine-port",
63
+ },
64
+ },
65
+ outcome: {
66
+ content: "",
67
+ engineId: "pi",
68
+ ...outcome,
69
+ },
70
+ });
71
+ }
72
+
73
+ /** 模拟 run 期失败(prepare 期 reject / 引擎进程死亡)。 */
74
+ fail(err: unknown): void {
75
+ this.reject(err);
76
+ }
77
+
78
+ /** 模拟引擎反向事件通知(协议 event 通知形态)。 */
79
+ emitEvent(event: unknown): void {
80
+ this.ctx.onEvent?.(event as never);
81
+ }
82
+
83
+ /** 模拟 host/streamDelta(runId 键——首轮)。 */
84
+ emitDelta(delta: string): void {
85
+ this.ctx.stream?.onDelta(delta);
86
+ }
87
+
88
+ /** 模拟 host/roundLifecycle(runId 键——首轮)。 */
89
+ emitLifecycle(phase: Record<string, unknown>): void {
90
+ this.ctx.onRoundLifecycle?.({ runId: this.ctx.taskId, ...phase } as never);
91
+ }
92
+
93
+ /** 模拟 host/handleReady(运行中句柄回填)。 */
94
+ emitHandleReady(sessionRef: Record<string, string>, poolKey = "shared"): void {
95
+ this.ctx.onHandleReady?.({ sessionRef, poolKey });
96
+ }
97
+ }
98
+
99
+ /** 一次 interact 调用的捕获(action 原样记录,供断言)。 */
100
+ export interface FakeInteractCall {
101
+ handle: EngineHandle;
102
+ action: InteractAction;
103
+ result: InteractResult | Promise<InteractResult>;
104
+ }
105
+
106
+ export class FakePiEnginePort implements EnginePort {
107
+ readonly id = "pi";
108
+
109
+ /** run 调用捕获(按序)。 */
110
+ readonly runs: FakeRun[] = [];
111
+ /** interact 调用捕获(按序;result = 受理时返回值)。 */
112
+ readonly interacts: FakeInteractCall[] = [];
113
+ /** recordId 键路由注册捕获(recordId → 注销函数)。 */
114
+ readonly chatRoutes = new Map<string, ChatRoundRoute>();
115
+ readonly chatRouteUnregisters: string[] = [];
116
+
117
+ /** interact message 的应答形态(默认受理;测试改写为冷路径拒绝等)。 */
118
+ interactMessageResult: InteractResult = { ok: true, delivered: true };
119
+ /** interact cancel / close 的应答形态。 */
120
+ interactControlResult: InteractResult = { ok: true, delivered: true };
121
+
122
+ capabilities(): EngineCapabilities {
123
+ // 与 pi-subagent-cli manifest 逐位一致(gate 同步面放行 pi 全参数——V4⑤ 反向守护)。
124
+ return {
125
+ schemaEnforcement: "native",
126
+ steer: "unsupported",
127
+ conversation: "native",
128
+ personaInjection: "flag",
129
+ eventGranularity: "stream",
130
+ sandbox: "emulated",
131
+ sessionRead: "full",
132
+ resume: "native",
133
+ interrupt: "kill-only",
134
+ permissionMode: "native",
135
+ maxTurns: true,
136
+ };
137
+ }
138
+
139
+ async probe(): Promise<ProbeReport> {
140
+ return { ok: true, engineVersion: "fake-1", checks: [{ name: "invocation", ok: true, detail: "fake" }] };
141
+ }
142
+
143
+ run(task: AgentCallOpts, ctx: RunContext): Promise<EngineRunResult> {
144
+ const captured = new FakeRun(task, ctx);
145
+ this.runs.push(captured);
146
+ return captured.promise;
147
+ }
148
+
149
+ async interact(handle: EngineHandle, action: InteractAction): Promise<InteractResult> {
150
+ const result = action.kind === "message" ? this.interactMessageResult : this.interactControlResult;
151
+ this.interacts.push({ handle, action, result });
152
+ return result;
153
+ }
154
+
155
+ async read(handle: EngineHandle): Promise<SessionView> {
156
+ return { engineId: "pi", turns: [], source: "outcome-only" };
157
+ }
158
+
159
+ registerChatRoundRoute(recordId: string, route: ChatRoundRoute): () => void {
160
+ this.chatRoutes.set(recordId, route);
161
+ return () => {
162
+ if (this.chatRoutes.get(recordId) === route) {
163
+ this.chatRoutes.delete(recordId);
164
+ this.chatRouteUnregisters.push(recordId);
165
+ }
166
+ };
167
+ }
168
+
169
+ // ── 测试驱动面(recordId 键路由——interact 续聊轮的协议回流)──
170
+
171
+ /** 向指定 record 的 chat 路由发 recordId 键 delta。 */
172
+ emitRecordDelta(recordId: string, delta: string): void {
173
+ void this.chatRoutes.get(recordId)?.onStreamDelta?.(delta);
174
+ }
175
+
176
+ /** 向指定 record 的 chat 路由发 recordId 键 roundLifecycle 相位。 */
177
+ emitRecordLifecycle(recordId: string, phase: Record<string, unknown>): void {
178
+ void this.chatRoutes.get(recordId)?.onRoundLifecycle?.({ recordId, ...phase } as never);
179
+ }
180
+ }
181
+
182
+ /** 注册替身 pi 引擎进 registry(覆盖同 id 既有注册——测试隔离自负责清理)。 */
183
+ export function registerFakePiEngine(): FakePiEnginePort {
184
+ const fake = new FakePiEnginePort();
185
+ registerEngine("pi", () => fake);
186
+ return fake;
187
+ }
@@ -47,7 +47,7 @@
47
47
  // };
48
48
  // });
49
49
  // vi.mock("../alive-store.ts", () => ({ writeAliveMarker: vi.fn() }));
50
- // vi.mock("../engine/engines/pi/temp-prompt.ts", () => ({
50
+ // vi.mock("../engine/inproc temp-prompt(已删)", () => ({
51
51
  // writePromptToTempFile: vi.fn(async (agent: string) => {
52
52
  // const safeName = agent.replace(/[^\w.-]+/g, "_");
53
53
  // return { dir: `/tmp/fake-${safeName}`, filePath: `/tmp/fake-${safeName}/prompt-${safeName}.md` };
@@ -63,7 +63,11 @@ import { PassThrough } from "node:stream";
63
63
  import { vi } from "vitest";
64
64
 
65
65
  import { createRecord } from "../../execution-record.ts";
66
- import type { RunOptions, SessionRunnerContext } from "../../engine/engines/pi/session-runner.ts";
66
+
67
+ // [W3 改写] RunOptions / SessionRunnerContext 类型源(inproc session-runner(已删))
68
+ // 随删件消亡——makeOpts/makeCtx 改用结构化最小类型(消费方为 keep-alive 系历史
69
+ // fixture 形态;引擎侧等价类型在 pi-subagent-cli)。core 侧剩余消费面为
70
+ // recursive-visibility-baseline 的 spawn 断言工具(waitForSpawn/lastSpawnedChild)。
67
71
 
68
72
  /** FakeChild 的假 pid(满足 ChildProcess.pid 形状,无真实进程语义)。 */
69
73
  const FAKE_PID = 12345;
@@ -82,7 +86,7 @@ const SPAWN_POLL_INTERVAL_MS = 5;
82
86
  * 导出 class(而非只在工厂内部定义)是为了:
83
87
  * 1. vi.mock 工厂内 `await import("./helpers/spawn-mock.ts")` 后 `new FakeChild()` 与
84
88
  * 测试侧 `instanceof FakeChild` / 类型断言用同一个 class。
85
- * 2. C13 e2e 测试可直接 `new FakeChild()` 手动构造 child 喂给 ui-request-queue(不经 spawn)。
89
+ * 2. C13 e2e 测试可直接 `new FakeChild()` 手动构造 child 喂给 inproc UI 请求队列(已删)(不经 spawn)。
86
90
  */
87
91
  export class FakeChild extends EventEmitter {
88
92
  pid = FAKE_PID;
@@ -206,8 +210,21 @@ export function makeRecord(id = "run-1") {
206
210
  });
207
211
  }
208
212
 
213
+ /** RunOptions 的结构化最小形态(原 inproc pi 引擎目录 RunOptions 同构;测试 fixture 用)。 */
214
+ export interface RunOptionsLike {
215
+ resolved: { model: { id: string; name: string; provider: string; reasoning: boolean }; thinkingLevel: string | undefined };
216
+ agentConfig: undefined;
217
+ appendSystemPrompt?: string[];
218
+ skillPath?: string;
219
+ schema?: Record<string, unknown>;
220
+ maxTurns?: number;
221
+ graceTurns?: number;
222
+ signal?: AbortSignal;
223
+ onEvent?: ((event: unknown) => void) | undefined;
224
+ }
225
+
209
226
  /** 构造最小合法的 RunOptions(runSpawn 入参,可 override 关键字段)。 */
210
- export function makeOpts(overrides: Partial<RunOptions> = {}): RunOptions {
227
+ export function makeOpts(overrides: Partial<RunOptionsLike> = {}): RunOptionsLike {
211
228
  return {
212
229
  resolved: {
213
230
  model: {
@@ -230,8 +247,19 @@ export function makeOpts(overrides: Partial<RunOptions> = {}): RunOptions {
230
247
  };
231
248
  }
232
249
 
250
+ /** SessionRunnerContext 的结构化最小形态(core 侧消费字段面)。 */
251
+ export interface SessionRunnerContextLike {
252
+ cwd: string;
253
+ agentDir: string;
254
+ skillDirs: string[];
255
+ mainCwd: string;
256
+ mainSessionFile?: string;
257
+ sessionRootId: string;
258
+ rootCwd: string;
259
+ }
260
+
233
261
  /** 构造最小合法的 SessionRunnerContext(runSpawn 入参,可 override 关键字段)。 */
234
- export function makeCtx(overrides: Partial<SessionRunnerContext> = {}): SessionRunnerContext {
262
+ export function makeCtx(overrides: Partial<SessionRunnerContextLike> = {}): SessionRunnerContextLike {
235
263
  return {
236
264
  cwd: "/tmp/test",
237
265
  agentDir: "/tmp/test/agents",
@@ -318,11 +346,10 @@ export function sessionPendingModule() {
318
346
  return {
319
347
  readActivePendingFromSessionFile: vi.fn(() => ({ count: 1, recentUnregister: false })),
320
348
  prunePendingCursor: vi.fn(),
321
- listActivePendingFromSessionFile: vi.fn(() => ({ items: [] })),
322
349
  };
323
350
  }
324
351
 
325
- /** "../engine/engines/pi/temp-prompt.ts" mock 工厂(prompt 落 /tmp/fake-<agent>,收尾 no-op)。 */
352
+ /** "../engine/inproc temp-prompt(已删)" mock 工厂(prompt 落 /tmp/fake-<agent>,收尾 no-op)。 */
326
353
  export function tempPromptModule() {
327
354
  return {
328
355
  writePromptToTempFile: vi.fn(async (agent: string) => {
@@ -352,7 +379,7 @@ export function makeVisibilityRecord(overrides: { id?: string; depth?: number }
352
379
  }
353
380
 
354
381
  /** 构造 env 注入断言族的 RunOptions(可 override 关键字段)。 */
355
- export function makeRunOpts(overrides: Partial<RunOptions> = {}): RunOptions {
382
+ export function makeRunOpts(overrides: Partial<RunOptionsLike> = {}): RunOptionsLike {
356
383
  return {
357
384
  resolved: { model: { provider: "test", id: "model", name: "Model", reasoning: false }, thinkingLevel: undefined },
358
385
  agentConfig: undefined,
@@ -368,7 +395,7 @@ export function makeRunOpts(overrides: Partial<RunOptions> = {}): RunOptions {
368
395
  }
369
396
 
370
397
  /** 构造 env 注入断言族的 SessionRunnerContext(可 override 关键字段)。 */
371
- export function makeVisibilityCtx(overrides: Partial<SessionRunnerContext> = {}): SessionRunnerContext {
398
+ export function makeVisibilityCtx(overrides: Partial<SessionRunnerContextLike> = {}): SessionRunnerContextLike {
372
399
  return {
373
400
  cwd: "/fake/cwd",
374
401
  agentDir: "/fake/agent",
@@ -112,7 +112,7 @@ export function manifestStoreModule() {
112
112
  return { ManifestStore: vi.fn(function (_recordsDir: string) { return new FakeManifestStore(); }) };
113
113
  }
114
114
 
115
- /** ../engine/engines/pi/temp-prompt.ts mock 模块(固定路径,消除 fake-timers 下 flaky 竞态)。 */
115
+ /** temp-prompt mock 模块(固定路径,消除 fake-timers 下 flaky 竞态)。[W3] 被 mock 的 inproc temp-prompt 模块已删——本工厂仅余存量测试文件引用。 */
116
116
  export function tempPromptModule() {
117
117
  return {
118
118
  writePromptToTempFile: vi.fn(async (agent: string) => {