@zhushanwen/subagent-core 0.2.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 (330) hide show
  1. package/README.md +114 -0
  2. package/dist/chunk-3VOERJPJ.js +22 -0
  3. package/dist/chunk-A4IVZWVX.js +31 -0
  4. package/dist/execution/engine/engines/zcode/constants.cjs +54 -0
  5. package/dist/execution/engine/engines/zcode/constants.d.cts +31 -0
  6. package/dist/execution/engine/engines/zcode/constants.d.ts +31 -0
  7. package/dist/execution/engine/engines/zcode/constants.js +22 -0
  8. package/dist/execution/engine/engines/zcode/reader.cjs +276 -0
  9. package/dist/execution/engine/engines/zcode/reader.d.cts +20 -0
  10. package/dist/execution/engine/engines/zcode/reader.d.ts +20 -0
  11. package/dist/execution/engine/engines/zcode/reader.js +239 -0
  12. package/dist/execution/engine/paths.cjs +55 -0
  13. package/dist/execution/engine/paths.d.cts +8 -0
  14. package/dist/execution/engine/paths.d.ts +8 -0
  15. package/dist/execution/engine/paths.js +26 -0
  16. package/dist/execution/relay-env.cjs +62 -0
  17. package/dist/execution/relay-env.d.cts +33 -0
  18. package/dist/execution/relay-env.d.ts +33 -0
  19. package/dist/execution/relay-env.js +20 -0
  20. package/dist/index.cjs +1852 -0
  21. package/dist/index.d.cts +1184 -0
  22. package/dist/index.d.ts +1184 -0
  23. package/dist/index.js +1810 -0
  24. package/dist/types-BxyAidGf.d.cts +875 -0
  25. package/dist/types-BxyAidGf.d.ts +875 -0
  26. package/package.json +99 -0
  27. package/src/__tests__/agent-opts-resolver-schema-prompt.test.ts +142 -0
  28. package/src/__tests__/append-system-prompt-assembly.test.ts +242 -0
  29. package/src/__tests__/builtin-workflows-structure.test.ts +180 -0
  30. package/src/__tests__/derive-closed-display-parity.test.ts +93 -0
  31. package/src/__tests__/fr4-get-state-handshake.test.ts +125 -0
  32. package/src/__tests__/fr8-orphan-recovery.test.ts +259 -0
  33. package/src/__tests__/m2-append-content-probe.test.ts +73 -0
  34. package/src/__tests__/manifest-store.test.ts +368 -0
  35. package/src/__tests__/record-store-cache.test.ts +335 -0
  36. package/src/__tests__/record-store-index.test.ts +560 -0
  37. package/src/__tests__/record-store-last-line.test.ts +129 -0
  38. package/src/__tests__/review-fix-loop-script.test.ts +288 -0
  39. package/src/__tests__/review-fix-loop-utils.test.ts +2377 -0
  40. package/src/__tests__/robustness-low-batch1.test.ts +286 -0
  41. package/src/__tests__/robustness-medium-batch1.test.ts +69 -0
  42. package/src/__tests__/robustness-medium-batch2.test.ts +65 -0
  43. package/src/__tests__/robustness-medium-batch3.test.ts +30 -0
  44. package/src/__tests__/robustness-medium-batch4.test.ts +358 -0
  45. package/src/__tests__/session-runner.test.ts +69 -0
  46. package/src/__tests__/smoke.test.ts +9 -0
  47. package/src/__tests__/stream-sink.test.ts +203 -0
  48. package/src/core/__tests__/host-services.test.ts +144 -0
  49. package/src/core/__tests__/logger.test.ts +78 -0
  50. package/src/core/__tests__/notify-ports.test.ts +104 -0
  51. package/src/core/host-services.ts +97 -0
  52. package/src/core/logger.ts +47 -0
  53. package/src/core/notify-ports.ts +126 -0
  54. package/src/execution/__tests__/__fixtures__/notifier-golden-snapshots.json +53 -0
  55. package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +1 -0
  56. package/src/execution/__tests__/agent-result-mapper.test.ts +150 -0
  57. package/src/execution/__tests__/alive-store.test.ts +147 -0
  58. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +490 -0
  59. package/src/execution/__tests__/channel-registry-handshake.test.ts +242 -0
  60. package/src/execution/__tests__/chat-engine-routing.test.ts +610 -0
  61. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +190 -0
  62. package/src/execution/__tests__/concurrency-pool.test.ts +250 -0
  63. package/src/execution/__tests__/config.test.ts +302 -0
  64. package/src/execution/__tests__/delivery-methods.test.ts +424 -0
  65. package/src/execution/__tests__/dialog-queue.test.ts +299 -0
  66. package/src/execution/__tests__/epipe-fallback.test.ts +241 -0
  67. package/src/execution/__tests__/execute-and-await-worktree.test.ts +243 -0
  68. package/src/execution/__tests__/execute-nesting.test.ts +323 -0
  69. package/src/execution/__tests__/execute-options-mapper.test.ts +200 -0
  70. package/src/execution/__tests__/execution-record.test.ts +1394 -0
  71. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +171 -0
  72. package/src/execution/__tests__/finalize-record.test.ts +367 -0
  73. package/src/execution/__tests__/finalized-marker.test.ts +104 -0
  74. package/src/execution/__tests__/format-schema-instruction.test.ts +169 -0
  75. package/src/execution/__tests__/gc-timer.test.ts +184 -0
  76. package/src/execution/__tests__/get-record-for-action-restart.test.ts +254 -0
  77. package/src/execution/__tests__/helpers/mock-extension-api.ts +30 -0
  78. package/src/execution/__tests__/helpers/spawn-mock.ts +242 -0
  79. package/src/execution/__tests__/host-mode.test.ts +87 -0
  80. package/src/execution/__tests__/lifecycle-manager-lock.test.ts +211 -0
  81. package/src/execution/__tests__/lifecycle-manager.test.ts +383 -0
  82. package/src/execution/__tests__/lifecycle-predicates.test.ts +116 -0
  83. package/src/execution/__tests__/manifest-parentid.test.ts +117 -0
  84. package/src/execution/__tests__/model-resolver.test.ts +465 -0
  85. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +287 -0
  86. package/src/execution/__tests__/nested-visibility.test.ts +325 -0
  87. package/src/execution/__tests__/output-collector.test.ts +358 -0
  88. package/src/execution/__tests__/path-encoding.test.ts +104 -0
  89. package/src/execution/__tests__/pi-invocation.test.ts +134 -0
  90. package/src/execution/__tests__/record-store.test.ts +1057 -0
  91. package/src/execution/__tests__/records-cwd-isolation.test.ts +91 -0
  92. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +339 -0
  93. package/src/execution/__tests__/recursive-visibility-env.test.ts +273 -0
  94. package/src/execution/__tests__/relay-env.test.ts +42 -0
  95. package/src/execution/__tests__/resource-policy.test.ts +109 -0
  96. package/src/execution/__tests__/rpc-mode.test.ts +89 -0
  97. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +267 -0
  98. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +253 -0
  99. package/src/execution/__tests__/run-spawn-edges.test.ts +687 -0
  100. package/src/execution/__tests__/run-spawn-integration.test.ts +933 -0
  101. package/src/execution/__tests__/run-spawn-resume.test.ts +322 -0
  102. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +196 -0
  103. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +199 -0
  104. package/src/execution/__tests__/session-context-resolver.test.ts +167 -0
  105. package/src/execution/__tests__/session-file-gc.test.ts +293 -0
  106. package/src/execution/__tests__/session-reconstructor.test.ts +379 -0
  107. package/src/execution/__tests__/session-runner-epipe.test.ts +178 -0
  108. package/src/execution/__tests__/session-runner-schema-env.test.ts +350 -0
  109. package/src/execution/__tests__/spawn-args.test.ts +445 -0
  110. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +189 -0
  111. package/src/execution/__tests__/spawn-event-adapter.test.ts +167 -0
  112. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +207 -0
  113. package/src/execution/__tests__/spawned-children.test.ts +92 -0
  114. package/src/execution/__tests__/start-sync-model-guard.test.ts +150 -0
  115. package/src/execution/__tests__/stdin-writer.test.ts +462 -0
  116. package/src/execution/__tests__/stream-sink-retirement.test.ts +261 -0
  117. package/src/execution/__tests__/subagent-service-abort.test.ts +60 -0
  118. package/src/execution/__tests__/subagent-service-message-close.test.ts +629 -0
  119. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +180 -0
  120. package/src/execution/__tests__/subagent-service.test.ts +788 -0
  121. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +310 -0
  122. package/src/execution/__tests__/subprocess-agent-runner.test.ts +612 -0
  123. package/src/execution/__tests__/temp-prompt.test.ts +53 -0
  124. package/src/execution/__tests__/timeout-integration.test.ts +615 -0
  125. package/src/execution/__tests__/tombstone-store.test.ts +73 -0
  126. package/src/execution/__tests__/turn-limiter-semantics.test.ts +194 -0
  127. package/src/execution/__tests__/turn-limiter.test.ts +65 -0
  128. package/src/execution/__tests__/ui-channels.test.ts +187 -0
  129. package/src/execution/__tests__/ui-interaction-model.test.ts +67 -0
  130. package/src/execution/__tests__/ui-request-handler-factory.test.ts +369 -0
  131. package/src/execution/__tests__/ui-request-handler.test.ts +204 -0
  132. package/src/execution/__tests__/ui-request-observability.test.ts +113 -0
  133. package/src/execution/__tests__/ui-request-queue.test.ts +133 -0
  134. package/src/execution/__tests__/worktree-manager.test.ts +633 -0
  135. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +229 -0
  136. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +181 -0
  137. package/src/execution/__tests__/worktree-registry.test.ts +199 -0
  138. package/src/execution/agent-registry.ts +199 -0
  139. package/src/execution/agent-result-mapper.ts +90 -0
  140. package/src/execution/alive-store.ts +119 -0
  141. package/src/execution/argv-mirror.ts +113 -0
  142. package/src/execution/best-effort.ts +38 -0
  143. package/src/execution/channel-registry-access.ts +144 -0
  144. package/src/execution/concurrency-pool.ts +116 -0
  145. package/src/execution/config.ts +165 -0
  146. package/src/execution/dialog-queue.ts +330 -0
  147. package/src/execution/engine/__tests__/common/data-dir.test.ts +78 -0
  148. package/src/execution/engine/__tests__/common/errors.test.ts +132 -0
  149. package/src/execution/engine/__tests__/common/event-journal.test.ts +177 -0
  150. package/src/execution/engine/__tests__/common/kill-chain.test.ts +192 -0
  151. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +81 -0
  152. package/src/execution/engine/__tests__/common/persona-router.test.ts +123 -0
  153. package/src/execution/engine/__tests__/common/pool-manager.test.ts +154 -0
  154. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +128 -0
  155. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +28 -0
  156. package/src/execution/engine/__tests__/conformance/agent-event-invariants.ts +141 -0
  157. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +109 -0
  158. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +101 -0
  159. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +77 -0
  160. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +104 -0
  161. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +201 -0
  162. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +76 -0
  163. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +79 -0
  164. package/src/execution/engine/__tests__/engine-discovery.test.ts +87 -0
  165. package/src/execution/engine/__tests__/model-prompt.test.ts +197 -0
  166. package/src/execution/engine/__tests__/paths.test.ts +39 -0
  167. package/src/execution/engine/__tests__/registry.test.ts +120 -0
  168. package/src/execution/engine/__tests__/routing.test.ts +231 -0
  169. package/src/execution/engine/common/data-dir.ts +66 -0
  170. package/src/execution/engine/common/errors.ts +183 -0
  171. package/src/execution/engine/common/event-journal.ts +254 -0
  172. package/src/execution/engine/common/journal-replay.ts +62 -0
  173. package/src/execution/engine/common/kill-chain.ts +221 -0
  174. package/src/execution/engine/common/nesting-guard.ts +50 -0
  175. package/src/execution/engine/common/persona-router.ts +108 -0
  176. package/src/execution/engine/common/pool-manager.ts +226 -0
  177. package/src/execution/engine/common/schema-emulation.ts +189 -0
  178. package/src/execution/engine/common/session-view-projection.ts +51 -0
  179. package/src/execution/engine/engine-discovery.ts +65 -0
  180. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +469 -0
  181. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +155 -0
  182. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +164 -0
  183. package/src/execution/engine/engines/pi/pi-engine.ts +415 -0
  184. package/src/execution/engine/engines/pi/reader.ts +48 -0
  185. package/src/execution/engine/engines/pi/registration.ts +35 -0
  186. package/src/execution/engine/engines/pi/task-spec-mapper.ts +100 -0
  187. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +39 -0
  188. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +150 -0
  189. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +246 -0
  190. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +228 -0
  191. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +210 -0
  192. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +71 -0
  193. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +127 -0
  194. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +580 -0
  195. package/src/execution/engine/engines/zcode/constants.ts +43 -0
  196. package/src/execution/engine/engines/zcode/golden-sample.ts +39 -0
  197. package/src/execution/engine/engines/zcode/launcher.ts +161 -0
  198. package/src/execution/engine/engines/zcode/parser.ts +436 -0
  199. package/src/execution/engine/engines/zcode/preparer.ts +363 -0
  200. package/src/execution/engine/engines/zcode/reader.ts +381 -0
  201. package/src/execution/engine/engines/zcode/registration.ts +37 -0
  202. package/src/execution/engine/engines/zcode/zcode-engine.ts +658 -0
  203. package/src/execution/engine/host-task-spec.ts +47 -0
  204. package/src/execution/engine/model-prompt.ts +158 -0
  205. package/src/execution/engine/paths.ts +42 -0
  206. package/src/execution/engine/port.ts +153 -0
  207. package/src/execution/engine/registry.ts +133 -0
  208. package/src/execution/engine/routing.ts +218 -0
  209. package/src/execution/engine/types.ts +309 -0
  210. package/src/execution/execute-options-mapper.ts +115 -0
  211. package/src/execution/execution-record.ts +984 -0
  212. package/src/execution/finalize-record.ts +254 -0
  213. package/src/execution/finalized-marker.ts +70 -0
  214. package/src/execution/get-state-handshake.ts +104 -0
  215. package/src/execution/host-mode.ts +56 -0
  216. package/src/execution/idle-gc.ts +47 -0
  217. package/src/execution/lifecycle-manager.ts +513 -0
  218. package/src/execution/lifecycle-predicates.ts +65 -0
  219. package/src/execution/manifest-store.ts +256 -0
  220. package/src/execution/model-config-service.ts +250 -0
  221. package/src/execution/model-resolver.ts +248 -0
  222. package/src/execution/notifier.ts +372 -0
  223. package/src/execution/notify-ledger.ts +580 -0
  224. package/src/execution/output-collector.ts +228 -0
  225. package/src/execution/path-encoding.ts +60 -0
  226. package/src/execution/pi-invocation.ts +120 -0
  227. package/src/execution/record-entry.ts +132 -0
  228. package/src/execution/record-store.ts +1265 -0
  229. package/src/execution/relay-env.ts +37 -0
  230. package/src/execution/session-context-resolver.ts +64 -0
  231. package/src/execution/session-file-gc.ts +120 -0
  232. package/src/execution/session-pending.ts +170 -0
  233. package/src/execution/session-reconstructor.ts +678 -0
  234. package/src/execution/session-runner.ts +1789 -0
  235. package/src/execution/sessions-index.ts +304 -0
  236. package/src/execution/spawn-event-adapter.ts +363 -0
  237. package/src/execution/stdin-writer.ts +198 -0
  238. package/src/execution/stream-sink.ts +126 -0
  239. package/src/execution/subagent-service.ts +2268 -0
  240. package/src/execution/subprocess-agent-runner.ts +317 -0
  241. package/src/execution/temp-prompt.ts +62 -0
  242. package/src/execution/tombstone-store.ts +72 -0
  243. package/src/execution/turn-limiter.ts +102 -0
  244. package/src/execution/types.ts +1023 -0
  245. package/src/execution/ui-channels.ts +216 -0
  246. package/src/execution/ui-interaction-model.ts +48 -0
  247. package/src/execution/ui-request-handler-factory.ts +243 -0
  248. package/src/execution/ui-request-observability.ts +81 -0
  249. package/src/execution/ui-request-queue.ts +184 -0
  250. package/src/execution/worktree-manager.ts +688 -0
  251. package/src/execution/worktree-registry.ts +279 -0
  252. package/src/index.ts +87 -0
  253. package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +349 -0
  254. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +202 -0
  255. package/src/orchestration/__tests__/agent-call-stream.test.ts +152 -0
  256. package/src/orchestration/__tests__/args-validator.test.ts +143 -0
  257. package/src/orchestration/__tests__/config-loader.test.ts +503 -0
  258. package/src/orchestration/__tests__/error-recovery-handlers.test.ts +809 -0
  259. package/src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts +404 -0
  260. package/src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts +56 -0
  261. package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +166 -0
  262. package/src/orchestration/__tests__/execute-agent-call.test.ts +451 -0
  263. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +600 -0
  264. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +96 -0
  265. package/src/orchestration/__tests__/lifecycle.test.ts +659 -0
  266. package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +95 -0
  267. package/src/orchestration/__tests__/review-fix-loop-scriptpath-failfast.test.ts +183 -0
  268. package/src/orchestration/__tests__/script-lint.test.ts +831 -0
  269. package/src/orchestration/__tests__/skill-discovery.test.ts +210 -0
  270. package/src/orchestration/__tests__/test-mocks.ts +197 -0
  271. package/src/orchestration/__tests__/worker-exit-without-result.test.ts +368 -0
  272. package/src/orchestration/__tests__/worker-host.test.ts +120 -0
  273. package/src/orchestration/__tests__/worker-returnmeta-passthrough.test.ts +164 -0
  274. package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +563 -0
  275. package/src/orchestration/__tests__/worker-script-builder.test.ts +309 -0
  276. package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +129 -0
  277. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +317 -0
  278. package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +110 -0
  279. package/src/orchestration/agent-opts-resolver.ts +174 -0
  280. package/src/orchestration/args-validator.ts +127 -0
  281. package/src/orchestration/config-loader.ts +316 -0
  282. package/src/orchestration/error-recovery.ts +1018 -0
  283. package/src/orchestration/execute-agent-call.ts +256 -0
  284. package/src/orchestration/launcher.ts +455 -0
  285. package/src/orchestration/lifecycle.ts +399 -0
  286. package/src/orchestration/models/__tests__/budget.test.ts +307 -0
  287. package/src/orchestration/models/agent-call.ts +83 -0
  288. package/src/orchestration/models/budget.ts +118 -0
  289. package/src/orchestration/models/ports.ts +164 -0
  290. package/src/orchestration/models/run-runtime.ts +104 -0
  291. package/src/orchestration/models/run-spec.ts +83 -0
  292. package/src/orchestration/models/run-state.ts +44 -0
  293. package/src/orchestration/models/trace.ts +183 -0
  294. package/src/orchestration/models/types.ts +301 -0
  295. package/src/orchestration/models/workflow-run.ts +254 -0
  296. package/src/orchestration/models/workflow-script-registry.ts +35 -0
  297. package/src/orchestration/models/workflow-script.ts +117 -0
  298. package/src/orchestration/script-lint.ts +766 -0
  299. package/src/orchestration/skill-discovery.ts +135 -0
  300. package/src/orchestration/worker-handle.ts +115 -0
  301. package/src/orchestration/worker-host.ts +98 -0
  302. package/src/orchestration/worker-script-builder.ts +421 -0
  303. package/src/orchestration/workflow-files.ts +85 -0
  304. package/src/orchestration/workflow-script-registry-impl.ts +133 -0
  305. package/src/shared/__tests__/agent-ref.test.ts +34 -0
  306. package/src/shared/__tests__/meta-parser.test.ts +304 -0
  307. package/src/shared/__tests__/model-ref.test.ts +306 -0
  308. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +288 -0
  309. package/src/shared/__tests__/resource-discovery.test.ts +749 -0
  310. package/src/shared/__tests__/resource-meta.test.ts +51 -0
  311. package/src/shared/__tests__/schema-jsonify.test.ts +81 -0
  312. package/src/shared/__tests__/timer-delay.test.ts +61 -0
  313. package/src/shared/agent-event.ts +13 -0
  314. package/src/shared/agent-ref.ts +57 -0
  315. package/src/shared/meta-parser.ts +261 -0
  316. package/src/shared/model-ref.ts +286 -0
  317. package/src/shared/resource-discovery.ts +835 -0
  318. package/src/shared/resource-meta.ts +65 -0
  319. package/src/shared/schema-env.ts +44 -0
  320. package/src/shared/schema-jsonify.ts +58 -0
  321. package/src/shared/timer-delay.ts +54 -0
  322. package/src/shared/xml-injection.ts +35 -0
  323. package/workflows/README.md +81 -0
  324. package/workflows/_shared/agent-refs.cjs +40 -0
  325. package/workflows/chain.js +137 -0
  326. package/workflows/map-reduce.js +180 -0
  327. package/workflows/parallel.js +154 -0
  328. package/workflows/review-fix-loop-utils.cjs +1542 -0
  329. package/workflows/review-fix-loop.js +1605 -0
  330. package/workflows/scatter-gather.js +184 -0
@@ -0,0 +1,399 @@
1
+ /**
2
+ * Workflow Extension — lifecycle
3
+ *
4
+ * Workflow run 生命周期 free functions(D-12)。
5
+ *
6
+ * 5 个导出函数:
7
+ * - runWorkflow(spec, deps, signal?) → Promise<runId>
8
+ * - abortRun(runId, deps, reason?, doneReason?) → Promise<void>(done no-op)
9
+ * - terminateRunningRuns(deps, reason) → Promise<void>(session 切换/关闭终止)
10
+ * - evictDoneRunsBeyondCap(runs, keepDone) → number(done run 内存淘汰)
11
+ * - scheduleTimeBudget(runId, deps, budgetTimeMs) → timer(C.7 时间预算)
12
+ *
13
+ * 私有 makeHandlers(run, deps) → WorkerHandlers:
14
+ * - onMessage → handleWorkerMessage(run, raw, deps, handlers)
15
+ * - onError → handleWorkerError(run, err, deps, handlers) + workerErrorCount++
16
+ * - onExit(code, handle) → handleWorkerExit(run, code, handle, deps, handlers)
17
+ * (G-025:handle.isCurrent 检查内化在 handleWorkerExit 内)
18
+ *
19
+ * **A4 原子性**:abort/terminate 内部 transition 先 releaseRuntime(cleanup before
20
+ * mutate),失败时 status 不变。transition("done") 在 WorkflowRun.transition 内已实现
21
+ * 「releaseRuntime → 改 status」原子顺序。
22
+ *
23
+ * **G3-001**(run 一次性生命周期):AbortController 一次性无法复用,runtime 释放后
24
+ * 只有两类重建——rebuildRuntime(error-recovery,崩溃重试路径,run 保持 running、
25
+ * replaceRuntime 原子换新)与 abort/terminate 的终态释放(transition("done") 内
26
+ * releaseRuntime,run 不再恢复)。
27
+ * (旧并发门闩 gate 抽象已删——no-op 无生产语义,实际并发由 SubagentService
28
+ * ConcurrencyPool 管理;原 D-13 maxConcurrency=4 无消费方。)
29
+ *
30
+ * 层归属:Engine。依赖 LifecycleDeps + WorkerHost via port +
31
+ * WorkflowRun + handleWorker* 函数。
32
+ *
33
+ * 参考:domain-models.md §1(聚合根状态机)。
34
+ */
35
+
36
+ import { getLogger } from "../core/logger.ts";
37
+
38
+ import { assertSafeTimerDelay } from "../shared/timer-delay.ts";
39
+ import { validateRunArgs } from "./args-validator.ts";
40
+ import {
41
+ handleWorkerError,
42
+ handleWorkerExit,
43
+ handleWorkerMessage,
44
+ } from "./error-recovery.ts";
45
+ import { Budget } from "./models/budget.ts";
46
+ import type { LifecycleDeps, WorkerHandlers } from "./models/ports.ts";
47
+ import { RunRuntime } from "./models/run-runtime.ts";
48
+ import type { RunSpec } from "./models/run-spec.ts";
49
+ import { Trace } from "./models/trace.ts";
50
+ import type { DoneReason } from "./models/types.ts";
51
+ import { WorkflowRun } from "./models/workflow-run.ts";
52
+ import type { WorkerHandle } from "./worker-handle.ts";
53
+
54
+ const logger = getLogger("subagents");
55
+
56
+ // ── 常量 ─────────────────────────────────────────────────────
57
+
58
+ /** runId 生成:wf-<timestamp>-<base36 random 6 chars>。 */
59
+ const RUNID_RADIX = 36;
60
+ const RUNID_SLICE_START = 2;
61
+ const RUNID_SLICE_END = 8;
62
+
63
+ /**
64
+ * done run 内存保留窗口(K=20)。
65
+ *
66
+ * 本淘汰是 done run 内存有界性的唯一来源:calls.result 不裁、单聚合大小不随 wave1
67
+ * 裁剪缩小,故内存上限 = K × 实际聚合大小。同时定义 actionStatus 可查刚完成 run
68
+ * 的窗口(超出窗口的 done run 不再出现在列表中——已接受的用户可见变化)。
69
+ */
70
+ export const MAX_RETAINED_DONE_RUNS = 20;
71
+
72
+ function generateRunId(): string {
73
+ return `wf-${Date.now()}-${Math.random().toString(RUNID_RADIX).slice(RUNID_SLICE_START, RUNID_SLICE_END)}`;
74
+ }
75
+
76
+ // ── makeHandlers(路由 worker 事件到 error-recovery handle* 函数) ──────
77
+
78
+ /**
79
+ * 构造 WorkerHandlers——将 worker 的 onMessage/onError/onExit 事件路由到
80
+ * error-recovery 的 handleWorker* 函数。
81
+ *
82
+ * 闭包捕获 run + deps。runtime 重建(replaceRuntime)后 run 实例不变、deps 不变,
83
+ * 故 handlers 对新 worker 仍有效(lifecycle 与 error-recovery 共用 handlers)。
84
+ *
85
+ * **onExit G-025**:handleWorkerExit 内部检查 handle.isCurrent(stale exit 丢弃)。
86
+ * 本函数不在 onExit 里重复检查——error-recovery.handleWorkerExit 是单一守卫点。
87
+ *
88
+ * **workerErrorCount**:onError 触发时递增(C.5 跨 runtime 存活的重试计数载体)。
89
+ * 注意 handleWorkerError 内部也会递增——这里 onError 递增是 worker 事件层面的
90
+ * 「error 事件到达」计数,handleWorkerError 内的是「错误处理决策」计数。
91
+ * 实际 handleWorkerError 会做最终计数(含重试上限判断),onError 不重复递增。
92
+ */
93
+ function makeHandlers(run: WorkflowRun, deps: LifecycleDeps): WorkerHandlers {
94
+ // 自引用——error-recovery rebuildRuntime 需要 handlers 参数(handlers 引用自身)
95
+ const handlers: WorkerHandlers = {
96
+ async onMessage(raw: unknown): Promise<void> {
97
+ await handleWorkerMessage(run, raw, deps, handlers);
98
+ },
99
+ async onError(err: Error): Promise<void> {
100
+ await handleWorkerError(run, err, deps, handlers);
101
+ },
102
+ async onExit(code: number, handle: WorkerHandle): Promise<void> {
103
+ // H-2:用 worker-host 传入的 handle(即真正触发 exit 的那个 handle),而非
104
+ // run.runtime?.worker——重试竞态下 runtime.worker 可能已被 replaceRuntime 替换
105
+ // 为新 handle,导致 handleWorkerExit 内的 isCurrent 检查误判(漏判 stale exit 或
106
+ // 误杀新 worker)。G-025 检查仍在 handleWorkerExit 内(handle.isCurrent)。
107
+ await handleWorkerExit(run, code, handle, deps, handlers);
108
+ },
109
+ };
110
+ return handlers;
111
+ }
112
+
113
+ // ── scheduleTimeBudget(C.7 Run 级时间预算调度) ──────────
114
+
115
+ /**
116
+ * 启动 run 级墙钟时间预算计时器:到期后 abortRun(doneReason="time_limited")。
117
+ *
118
+ * 恢复旧 orchestrator-budget.ts 的 scheduleTimeBudgetCheck 语义——runWorkflow 启动
119
+ * 一个 setTimeout(maxTimeMs),到期若 run 仍未终态则转 done,time_limited。
120
+ * 计时器存入 RunRuntime.timeBudgetTimer,release(abort/replaceRuntime)时
121
+ * 自动清理,避免孤儿触发。worker/script 错误重试经 rebuildRuntime 重排新计时器。
122
+ *
123
+ * @returns 计时器句柄(未设预算时 undefined)
124
+ * @throws budgetTimeMs 超出 Node setTimeout 上限(2^31-1)——溢出值会被 Node 置 1ms
125
+ * 立即触发(「不限时预算」变「立即超时」),fail-fast 不静默 clamp(U1)。
126
+ */
127
+ export function scheduleTimeBudget(
128
+ runId: string,
129
+ deps: LifecycleDeps,
130
+ budgetTimeMs: number,
131
+ ): ReturnType<typeof setTimeout> {
132
+ // [U1] arm 入口:值流入 setTimeout 前校验安全域(>2^31-1 会变 1ms 立即触发)。
133
+ assertSafeTimerDelay(budgetTimeMs, "budgetTimeMs");
134
+ const timer = setTimeout(() => {
135
+ void abortRun(runId, deps, "Time budget exceeded", "time_limited").catch(
136
+ (err: unknown) => {
137
+ const msg = err instanceof Error ? err.message : String(err);
138
+ logger.error(`[workflow] time budget abort failed: ${msg}`);
139
+ },
140
+ );
141
+ }, budgetTimeMs);
142
+ // unref:不阻止 Node 退出(workflow 是后台任务,不应因计时器持有事件循环)。
143
+ timer.unref();
144
+ return timer;
145
+ }
146
+
147
+ // ── runWorkflow ──────────────────────────────────────────────
148
+
149
+ /**
150
+ * 启动一个 workflow run。
151
+ *
152
+ * 流程:创建 WorkflowRun(running,I1 构造期跳过)+ makeHandlers + 构建 RunRuntime
153
+ * (worker+gate+controller)+ assignRuntime(注入 runtime,恢复 I1)+ 注册到
154
+ * deps.runs + store.save。
155
+ *
156
+ * @param spec RunSpec(scriptSource 只读;args 会被原地注入 _runId——rfl C2 契约,
157
+ * worker 启动与崩溃重建共用同一 args 对象)
158
+ * @param deps LifecycleDeps(store/workerHost/runner/runs)
159
+ * @param signal 外部 abort signal(可选;abort 时调 abortRun)
160
+ * @returns runId(wf-<timestamp>-<random>)
161
+ * @throws signal 已 abort(pre-abort fail fast)
162
+ */
163
+ export async function runWorkflow(
164
+ spec: RunSpec,
165
+ deps: LifecycleDeps,
166
+ signal?: AbortSignal,
167
+ ): Promise<string> {
168
+ // m3 E9:参数校验单一 chokepoint,钉在所有副作用前(generateRunId/log/signal
169
+ // listener/runs.set/workerHost.start/store.save/pending:register)。校验失败时
170
+ // zero side effects。coerceTypes 原地规范化 spec.args——worker 启动与崩溃重建
171
+ // 共用同一对象(run.spec === spec),恢复路径参数一致。
172
+ validateRunArgs(spec);
173
+
174
+ const runId = generateRunId();
175
+ // rfl 仪表(tier-1 §7.1):注入稳定 _runId。runAndWait 与 executeNestedWorkflow
176
+ // 两个 args 入口都经本 choke point;rebuildRuntime 复用 run.spec.args 同一对象
177
+ // (error-recovery.ts),worker rebuild 后脚本侧 $ARGS._runId 不漂移——修复
178
+ // 「rebuild 回退 run-<Date.now()> 导致同一逻辑 run 碎裂到多个 state 目录」。
179
+ // 注入在 validateRunArgs 之后,不参与脚本参数 schema 校验(引擎内部字段)。
180
+ if (spec.args && typeof spec.args === "object") {
181
+ spec.args._runId = runId;
182
+ }
183
+ deps.log?.("debug", "workflow:lifecycle", "runWorkflow start", { runId, scriptName: spec.scriptName });
184
+
185
+ // P1-2: pre-aborted signal → fail fast
186
+ if (signal?.aborted) {
187
+ throw new Error("Workflow run aborted before start");
188
+ }
189
+
190
+ const run = new WorkflowRun(
191
+ runId,
192
+ spec,
193
+ {
194
+ status: "running",
195
+ budget: spec.budgetRef ?? new Budget({
196
+ maxTokens: spec.budgetTokens,
197
+ maxTimeMs: spec.budgetTimeMs,
198
+ }),
199
+ calls: new Map(),
200
+ trace: new Trace(),
201
+ errorLogs: [],
202
+ },
203
+ { startedAt: new Date().toISOString() },
204
+ );
205
+
206
+ // signal abort → abortRun(一次性监听)
207
+ if (signal) {
208
+ signal.addEventListener(
209
+ "abort",
210
+ () => {
211
+ void abortRun(runId, deps, "External signal aborted").catch((err: unknown) => {
212
+ const msg = err instanceof Error ? err.message : String(err);
213
+ logger.error(`[workflow] abortRun on signal failed: ${msg}`);
214
+ });
215
+ },
216
+ { once: true },
217
+ );
218
+ }
219
+
220
+ // 构造 handlers + runtime(worker + controller)
221
+ const handlers = makeHandlers(run, deps);
222
+ const controller = new AbortController();
223
+ const worker = deps.workerHost.start(spec, spec.args, handlers);
224
+ // C.7:run 级时间预算计时器(spec.budgetTimeMs > 0 时启用,到期 abortRun time_limited)。
225
+ const timeBudgetTimer =
226
+ spec.budgetTimeMs && spec.budgetTimeMs > 0
227
+ ? scheduleTimeBudget(runId, deps, spec.budgetTimeMs)
228
+ : undefined;
229
+ const runtime = new RunRuntime(worker, controller, timeBudgetTimer);
230
+
231
+ // assignRuntime(注入 runtime,恢复 I1:running ⟺ runtime!==undefined)
232
+ run.assignRuntime(runtime);
233
+
234
+ // 注册到 deps.runs(assignRuntime 之后——构造到 assignRuntime 之间 run 处于
235
+ // I1 跳过窗口(running 而 runtime undefined),后移保证窗口对外不可见;
236
+ // worker.start 抛错时 run 未注册,无孤儿 run 残留)
237
+ deps.runs.set(runId, run);
238
+
239
+ await deps.store.save(run);
240
+ deps.log?.("debug", "workflow:lifecycle", "run saved", { runId, status: run.state.status });
241
+
242
+ // pending-notifications: run 启动 → 注册(所有 workflow 启动路径的单一汇聚点:
243
+ // runAndWait / actionRun / 未来入口全覆盖)
244
+ deps.log?.("debug", "workflow:lifecycle", "emit pending:register", { runId });
245
+ deps.eventBus?.emit("pending:register", {
246
+ id: runId,
247
+ type: "workflow",
248
+ name: spec.slug || spec.scriptName || runId,
249
+ });
250
+ deps.log?.("debug", "workflow:lifecycle", "emit pending:register done", { runId });
251
+
252
+ return runId;
253
+ }
254
+
255
+ // ── abortRun ─────────────────────────────────────────────────
256
+
257
+ /**
258
+ * 中止 workflow(running)。
259
+ *
260
+ * **done 状态 no-op**:已终态的 run 不重复 abort。
261
+ * **A4 原子性**:transition("done", doneReason) 内部先 releaseRuntime。
262
+ *
263
+ * @param runId
264
+ * @param deps
265
+ * @param reason 可选中止原因(存 run.state.error)
266
+ * @param doneReason 终态原因(默认 "aborted";超时场景传 "time_limited",C.7)
267
+ * @throws runId 不存在
268
+ */
269
+ export async function abortRun(
270
+ runId: string,
271
+ deps: LifecycleDeps,
272
+ reason?: string,
273
+ doneReason: DoneReason = "aborted",
274
+ ): Promise<void> {
275
+ const run = deps.runs.get(runId);
276
+ if (!run) {
277
+ throw new Error(`Workflow '${runId}' not found`);
278
+ }
279
+
280
+ deps.log?.("debug", "workflow:lifecycle", "abortRun", { runId, status: run.state.status, reason, doneReason });
281
+
282
+ // done 状态 no-op
283
+ if (run.state.status === "done") {
284
+ deps.log?.("debug", "workflow:lifecycle", "abortRun no-op: already done", { runId });
285
+ return;
286
+ }
287
+
288
+ // 记录中止原因
289
+ if (reason) {
290
+ run.state.error = reason;
291
+ }
292
+ // A4: transition 内部 releaseRuntime(cleanup before mutate)
293
+ run.transition("done", doneReason);
294
+ await deps.store.save(run);
295
+ deps.log?.("debug", "workflow:lifecycle", "abortRun transition done", { runId, reason: run.state.reason });
296
+ // C-4: run 到达 done 终态 → 注销 pending-notification + 通知 Interface 层
297
+ deps.log?.("debug", "workflow:lifecycle", "emit pending:unregister", { runId, reason: run.state.reason });
298
+ deps.eventBus?.emit("pending:unregister", { id: run.runId, reason: run.state.reason ?? "completed" });
299
+ deps.log?.("debug", "workflow:lifecycle", "emit pending:unregister done", { runId });
300
+ deps.onRunDone?.(run);
301
+ }
302
+
303
+ // ── terminateRunningRuns(session 切换/关闭:终止全部 running run) ────────
304
+
305
+ /**
306
+ * 终止 deps.runs 中全部 running run(session 切换 / session 关闭时调用)。
307
+ *
308
+ * 一次性生命周期(D-2):session 离开当刻,running run 的 token 投入作废,转
309
+ * done,failed 持久化落盘——重启后 kill-9 恢复不误判,也不再存在「挂起待恢复」
310
+ * 的中间态。
311
+ *
312
+ * per-run 行为:`state.error = reason` → `transition("done","failed")`(内部先
313
+ * releaseRuntime,A4)→ `await store.save(run)` → `eventBus.emit("pending:unregister",
314
+ * {reason:"failed"})`。
315
+ *
316
+ * **不调 deps.onRunDone**:对齐 session_start 恢复先例(index.ts kill-9 恢复只发
317
+ * unregister、不发 onRunDone)——session 切换/关闭语境下主 agent 已离开本 session,
318
+ * 注入完成通知只会把消息发给已离开的 session。
319
+ *
320
+ * **不调 discardInFlightCalls**:run 已转终态不再 replay(无恢复路径),在飞 call
321
+ * 缓存清不清都不影响结果;该清理仅 rebuildRuntime 需要(崩溃重试会重放脚本,
322
+ * 假失败结果会污染重跑输出)。
323
+ *
324
+ * 单 run 失败(try/catch + log 带 runId/reason)不中断其余 run——终止是批量收尾,
325
+ * 一个 run 落盘失败不应放走其余 run 的 failed 状态。
326
+ *
327
+ * @param deps LifecycleDeps(runs/store/eventBus/log)
328
+ * @param reason 终止原因(写入 run.state.error,如 "Session switched: run terminated")
329
+ */
330
+ export async function terminateRunningRuns(
331
+ deps: LifecycleDeps,
332
+ reason: string,
333
+ ): Promise<void> {
334
+ for (const run of deps.runs.values()) {
335
+ if (run.state.status !== "running") continue;
336
+ try {
337
+ deps.log?.("debug", "workflow:lifecycle", "terminateRunningRuns", { runId: run.runId, reason });
338
+ run.state.error = reason;
339
+ // A4: transition 内部先 releaseRuntime(cleanup before mutate)
340
+ run.transition("done", "failed");
341
+ await deps.store.save(run);
342
+ // C-4: run 到达 done 终态 → 注销 pending-notification(reason 固定 "failed")
343
+ deps.eventBus?.emit("pending:unregister", { id: run.runId, reason: "failed" });
344
+ deps.log?.("debug", "workflow:lifecycle", "run terminated", { runId: run.runId, reason: run.state.reason });
345
+ } catch (err) {
346
+ const msg = err instanceof Error ? err.message : String(err);
347
+ logger.error(
348
+ `[workflow] terminateRunningRuns failed for run ${run.runId}: ${msg} (reason: ${reason})`,
349
+ );
350
+ }
351
+ }
352
+ }
353
+
354
+ // ── evictDoneRunsBeyondCap(done run 内存淘汰,原地裁剪函数) ────────
355
+
356
+ /**
357
+ * 淘汰 runs Map 中超出保留窗口的 done run,返回本次淘汰数量。
358
+ *
359
+ * 规则(契约 W3C1):
360
+ * 1. **状态白名单**:仅 `state.status === "done"` 可淘汰(RunStatus 封闭两态,
361
+ * 显式白名单而非「非 running」——未来新增状态不落淘汰端)。running
362
+ * (活跃执行,isScriptRunning 遍历依赖)永不淘汰,即使 completedAt 缺失也
363
+ * 绝不参与排序淘汰。
364
+ * 2. **排序**:done 项按 `meta.completedAt` ISO 字符串字典序升序(toISOString 恒
365
+ * UTC 毫秒格式,字典序=时间序)。completedAt 缺失(防御旧格式/异常快照)fallback
366
+ * 排序键为空串——字典序最小=最旧,先被淘汰。
367
+ * 3. **tie 稳定排序**:比较器三态返回(相等返回 0),Array#sort 稳定性(Node≥12)
368
+ * 保持元素原序——原序 = Map 插入序 = 创建序,tie 组内先创建者视为更旧先被淘汰
369
+ * (kill-9 批量恢复同 ms completedAt 场景的确定性保证)。
370
+ * 4. **淘汰执行**:超限数 excess = doneCount - keepDone(<=0 时 no-op 返回 0),
371
+ * 对升序前 excess 项逐个 `runs.delete(runId)`。
372
+ * 5. **边界不变式**:禁止按 Map 插入序直接淘汰——嵌套 workflow 父 run 创建最早、
373
+ * 完成最晚,插入序淘汰会在其自身 onRunDone 同步裁剪中淘汰它,runAndWait 轮询
374
+ * 窗口内 get 不到 → 误返 "Run not found"。
375
+ * 6. **副作用边界**:只清内存 runs Map,不动磁盘 state 文件、不删
376
+ * workflow-state-link 指针条目、不发任何事件。
377
+ *
378
+ * @param runs per-session 的 run 注册表(原地裁剪)
379
+ * @param keepDone done run 保留数(生产传 MAX_RETAINED_DONE_RUNS)
380
+ * @returns 本次淘汰的 run 数量
381
+ */
382
+ export function evictDoneRunsBeyondCap(
383
+ runs: Map<string, WorkflowRun>,
384
+ keepDone: number,
385
+ ): number {
386
+ // 显式白名单:仅 done 参与淘汰(running 误删即功能破坏)
387
+ const done = Array.from(runs.values()).filter((r) => r.state.status === "done");
388
+ const excess = done.length - keepDone;
389
+ if (excess <= 0) return 0;
390
+ // ISO 字典序=时间序;缺失 fallback 空串(ISO 串恒以 '2' 开头非空,空串严格最小=最旧)
391
+ const keyOf = (r: WorkflowRun): string => r.meta.completedAt ?? "";
392
+ // 三态比较器 + sort 稳定性:tie 保持 Array.from 的 Map 插入序(=创建序)——
393
+ // 先插入者更旧先淘汰,禁止按插入序直接 slice 淘汰(边界不变式 5)
394
+ done.sort((a, b) => (keyOf(a) < keyOf(b) ? -1 : keyOf(a) > keyOf(b) ? 1 : 0));
395
+ for (const r of done.slice(0, excess)) {
396
+ runs.delete(r.runId);
397
+ }
398
+ return excess;
399
+ }