@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,286 @@
1
+ // Low batch 1 robustness fix verification
2
+ //
3
+ // L9: run.state.errorLogs 追加而非覆盖——保留重试历史的诊断日志
4
+ //
5
+ // 一个 run 经历多次 error → rebuild → 最终 return 的场景,中间 worker 实例的
6
+ // console 日志对排查「为什么重试了 3 次」很关键。旧代码三处赋值都是覆盖式
7
+ //(run.state.errorLogs = ...),每次重试的诊断日志都被最后一次覆盖丢失。
8
+ // 修复:改为 push + 截断(MAX_ERROR_LOGS=500 防无界增长)。
9
+ //
10
+ // 测试搭建方式参照 error-recovery-handlers.test.ts(mock LifecycleDeps + WorkflowRun)。
11
+ // - handleScriptError 是 export 的 async function,直接 import 调用
12
+ // - handleReturn 不是 export 的——通过 handleWorkerMessage 发 { type: "return", ... } 触发
13
+
14
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
15
+
16
+ import { handleScriptError, handleWorkerMessage } from "../orchestration/error-recovery.ts";
17
+ import type { LifecycleDeps, WorkerHandlers } from "../orchestration/models/ports.ts";
18
+ import type { WorkflowRun } from "../orchestration/models/workflow-run.ts";
19
+
20
+ // ── helpers ──────────────────────────────────────────────────
21
+
22
+ /**
23
+ * 构造一个 status="running" 的 mock WorkflowRun。
24
+ *
25
+ * 关键:errorLogs 必须是真实数组(push/slice 会操作它),不能用 vi.fn 占位。
26
+ * transition 把 status 切到 done——调用方可通过 resetRunning() 重置回 running
27
+ * 以便多次触发 handleReturn(每条 return 消息都会 transition done)。
28
+ */
29
+ function makeRunningRun(): WorkflowRun & { resetRunning(): void } {
30
+ const run = {
31
+ runId: "run-test",
32
+ state: {
33
+ status: "running" as const,
34
+ reason: undefined as string | undefined,
35
+ budget: { usedTokens: 0, usedCost: 0 },
36
+ // 真实数组——push/slice 直接作用于它
37
+ errorLogs: [] as Array<{ level: string; message: string }>,
38
+ scriptResult: undefined as unknown,
39
+ // rebuildRuntime 内 discardInFlightCalls 遍历 calls + 移除 trace 节点——
40
+ // 必须是真实 Map(空 = 无在飞 call,discard 为 no-op)
41
+ calls: new Map(),
42
+ trace: { removeByStepIndex: vi.fn() },
43
+ },
44
+ meta: {
45
+ startedAt: new Date().toISOString(),
46
+ },
47
+ spec: {
48
+ scriptName: "test-wf",
49
+ scriptSource: "execute() {}",
50
+ args: {},
51
+ },
52
+ runtime: {
53
+ worker: { postMessage: vi.fn() },
54
+ },
55
+ transition(target: string, reason?: string): void {
56
+ this.state.status = target;
57
+ if (target === "done") this.state.reason = reason;
58
+ },
59
+ replaceRuntime(rt: unknown): void {
60
+ this.runtime = rt;
61
+ },
62
+ // 多次触发 handleReturn 时把状态从 done 重置回 running
63
+ resetRunning(): void {
64
+ this.state.status = "running";
65
+ this.state.reason = undefined;
66
+ },
67
+ } as unknown as WorkflowRun & { resetRunning(): void };
68
+ return run;
69
+ }
70
+
71
+ /** LifecycleDeps mock:store.save 是异步 no-op,其余可观察。 */
72
+ function makeDeps(): LifecycleDeps & {
73
+ store: { save: ReturnType<typeof vi.fn> };
74
+ workerHost: { start: ReturnType<typeof vi.fn> };
75
+ eventBus: { emit: ReturnType<typeof vi.fn> };
76
+ onRunDone: ReturnType<typeof vi.fn>;
77
+ log: ReturnType<typeof vi.fn>;
78
+ } {
79
+ return {
80
+ store: { save: vi.fn(async () => {}) },
81
+ workerHost: { start: vi.fn(() => ({ postMessage: vi.fn() })) },
82
+ runner: { run: vi.fn(async () => ({})) },
83
+ runs: new Map(),
84
+ eventBus: { emit: vi.fn() },
85
+ onRunDone: vi.fn(),
86
+ log: vi.fn(),
87
+ } as unknown as ReturnType<typeof makeDeps>;
88
+ }
89
+
90
+ /** WorkerHandlers 占位(重试路径递归回调,但测试场景不触发)。 */
91
+ function makeHandlers(): WorkerHandlers {
92
+ return {
93
+ onMessage: vi.fn(async () => {}),
94
+ onError: vi.fn(async () => {}),
95
+ onExit: vi.fn(async () => {}),
96
+ } as unknown as WorkerHandlers;
97
+ }
98
+
99
+ beforeEach(() => {
100
+ // handleScriptError 重试路径走 scheduleRebuild(指数退避 1s/2s/4s)。
101
+ // 测试中 workerLogs 已在退避前 push,但为了让 promise resolve(rebuildRuntime 后),
102
+ // 用 fake timers 推进退避。超 MAX 的终态路径不进退避,直接 resolve。
103
+ vi.useFakeTimers();
104
+ });
105
+
106
+ afterEach(() => {
107
+ vi.useRealTimers();
108
+ });
109
+
110
+ // ── handleScriptError: errorLogs 追加 ─────────────────────────
111
+
112
+ describe("L9: handleScriptError 追加 errorLogs(非覆盖)", () => {
113
+ it("第一次 scriptError:errorLogs 长度为 1", async () => {
114
+ const run = makeRunningRun();
115
+ const deps = makeDeps();
116
+
117
+ // count=1 <= MAX → 进退避重试路径。advance timer 让 promise resolve。
118
+ const p = handleScriptError(
119
+ run,
120
+ "boom-1",
121
+ [{ level: "error", message: "console error from worker #1" }],
122
+ deps,
123
+ makeHandlers(),
124
+ );
125
+ await vi.advanceTimersByTimeAsync(1000);
126
+ await p;
127
+
128
+ expect(run.state.errorLogs).toHaveLength(1);
129
+ expect(run.state.errorLogs[0]).toEqual({
130
+ level: "error",
131
+ message: "console error from worker #1",
132
+ });
133
+ });
134
+
135
+ it("第二次 scriptError:errorLogs 长度为 2(追加而非覆盖)", async () => {
136
+ const run = makeRunningRun();
137
+ const deps = makeDeps();
138
+
139
+ // 第一次:count=1 <= MAX → 退避 1s
140
+ const p1 = handleScriptError(
141
+ run,
142
+ "boom-1",
143
+ [{ level: "error", message: "console error from worker #1" }],
144
+ deps,
145
+ makeHandlers(),
146
+ );
147
+ await vi.advanceTimersByTimeAsync(1000);
148
+ await p1;
149
+
150
+ // 第二次:count=2 <= MAX → 退避 2s
151
+ const p2 = handleScriptError(
152
+ run,
153
+ "boom-2",
154
+ [{ level: "warn", message: "console warn from worker #2" }],
155
+ deps,
156
+ makeHandlers(),
157
+ );
158
+ await vi.advanceTimersByTimeAsync(2000);
159
+ await p2;
160
+
161
+ expect(run.state.errorLogs).toHaveLength(2);
162
+ expect(run.state.errorLogs[0]).toEqual({
163
+ level: "error",
164
+ message: "console error from worker #1",
165
+ });
166
+ expect(run.state.errorLogs[1]).toEqual({
167
+ level: "warn",
168
+ message: "console warn from worker #2",
169
+ });
170
+ });
171
+ });
172
+
173
+ // ── handleReturn: errorLogs 追加(经 handleWorkerMessage 触发) ──
174
+
175
+ describe("L9: handleReturn 追加 errorLogs(非覆盖)", () => {
176
+ it("已有 2 条 errorLogs 后 handleReturn 再追加 1 条 → 长度 3", async () => {
177
+ const run = makeRunningRun();
178
+ const deps = makeDeps();
179
+
180
+ // 先用 scriptError 累积 2 条诊断日志
181
+ const p1 = handleScriptError(
182
+ run,
183
+ "boom-1",
184
+ [{ level: "error", message: "diag-1" }],
185
+ deps,
186
+ makeHandlers(),
187
+ );
188
+ await vi.advanceTimersByTimeAsync(1000);
189
+ await p1;
190
+
191
+ const p2 = handleScriptError(
192
+ run,
193
+ "boom-2",
194
+ [{ level: "error", message: "diag-2" }],
195
+ deps,
196
+ makeHandlers(),
197
+ );
198
+ await vi.advanceTimersByTimeAsync(2000);
199
+ await p2;
200
+
201
+ expect(run.state.errorLogs).toHaveLength(2);
202
+
203
+ // handleReturn 经 handleWorkerMessage 触发——它内部会 transition("done","completed")
204
+ run.resetRunning();
205
+ await handleWorkerMessage(
206
+ run,
207
+ { type: "return", result: "final-result", workerLogs: [{ level: "log", message: "final-return-log" }] },
208
+ deps,
209
+ makeHandlers(),
210
+ );
211
+
212
+ expect(run.state.errorLogs).toHaveLength(3);
213
+ expect(run.state.errorLogs[2]).toEqual({
214
+ level: "log",
215
+ message: "final-return-log",
216
+ });
217
+ // scriptResult 也被正确写入(验证未破坏其他字段)
218
+ expect(run.state.scriptResult).toBe("final-result");
219
+ expect(run.state.status).toBe("done");
220
+ expect(run.state.reason).toBe("completed");
221
+ });
222
+ });
223
+
224
+ // ── 截断:超过 MAX_ERROR_LOGS 只保留最后 500 条 ────────────────
225
+
226
+ describe("L9: errorLogs 截断到 MAX_ERROR_LOGS(500)", () => {
227
+ it("handleScriptError 追加超过 MAX 后只保留最后 MAX 条", async () => {
228
+ const run = makeRunningRun();
229
+ const deps = makeDeps();
230
+
231
+ // 注入 499 条已有日志,再追加 3 条 → 502 > 500,应截断到 500
232
+ for (let i = 0; i < 499; i++) {
233
+ run.state.errorLogs.push({ level: "log", message: `pre-${i}` });
234
+ }
235
+ expect(run.state.errorLogs).toHaveLength(499);
236
+
237
+ // handleScriptError 内部 push 3 条 + 截断。走终态路径(count > MAX)避免退避计时。
238
+ // scriptErrorCount=3 → count=4 > 3 → transition done,failed,不进 scheduleRebuild。
239
+ run.meta.scriptErrorCount = 3;
240
+ await handleScriptError(
241
+ run,
242
+ "boom",
243
+ [
244
+ { level: "error", message: "new-1" },
245
+ { level: "error", message: "new-2" },
246
+ { level: "error", message: "new-3" },
247
+ ],
248
+ deps,
249
+ makeHandlers(),
250
+ );
251
+
252
+ expect(run.state.errorLogs).toHaveLength(500);
253
+ // 截断保留最后 500 条:499 + 3 = 502,丢弃最前 2 条(pre-0, pre-1)
254
+ expect(run.state.errorLogs[0]).toEqual({ level: "log", message: "pre-2" });
255
+ expect(run.state.errorLogs[499]).toEqual({ level: "error", message: "new-3" });
256
+ });
257
+
258
+ it("handleReturn 追加超过 MAX 后只保留最后 MAX 条", async () => {
259
+ const run = makeRunningRun();
260
+ const deps = makeDeps();
261
+
262
+ // 注入 500 条已有日志,再追加 2 条 → 502 > 500
263
+ for (let i = 0; i < 500; i++) {
264
+ run.state.errorLogs.push({ level: "log", message: `pre-${i}` });
265
+ }
266
+
267
+ await handleWorkerMessage(
268
+ run,
269
+ {
270
+ type: "return",
271
+ result: "done",
272
+ workerLogs: [
273
+ { level: "log", message: "ret-1" },
274
+ { level: "log", message: "ret-2" },
275
+ ],
276
+ },
277
+ deps,
278
+ makeHandlers(),
279
+ );
280
+
281
+ expect(run.state.errorLogs).toHaveLength(500);
282
+ // 截断保留最后 500 条:丢弃最前 2 条(pre-0, pre-1)
283
+ expect(run.state.errorLogs[0]).toEqual({ level: "log", message: "pre-2" });
284
+ expect(run.state.errorLogs[499]).toEqual({ level: "log", message: "ret-2" });
285
+ });
286
+ });
@@ -0,0 +1,69 @@
1
+ // Medium batch 1 robustness fixes verification
2
+ //
3
+ // M4: dispatchAgentCall .then() clears node.live BEFORE stale guard (not after)
4
+ // M7: handleWorkerMessage validates msg shape before dereferencing msg.opts
5
+ // M8: session-reconstructor guards Array.isArray(msg.content) before for...of
6
+
7
+ import { readFileSync } from "node:fs";
8
+ import { dirname,join } from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+
11
+ import { describe, expect, it } from "vitest";
12
+
13
+ const __dirname = dirname(fileURLToPath(import.meta.url));
14
+ const PKG_ROOT = join(__dirname, "..", "..");
15
+
16
+ function readSrc(relPath: string): string {
17
+ return readFileSync(join(PKG_ROOT, relPath), "utf-8");
18
+ }
19
+
20
+ // ── M4: node.live cleared before stale guard ─────────────────
21
+
22
+ describe("M4: dispatchAgentCall .then() clears node.live before stale guard", () => {
23
+ const src = readSrc(join("src", "orchestration", "error-recovery.ts"));
24
+
25
+ it("node.live = undefined appears before the stale guard return", () => {
26
+ // 找到 .then 回调中的 stale guard 和 node.live 清理的相对顺序
27
+ const thenMatch = src.match(/\.then\(\(\)\s*=>\s*\{[\s\S]*?\}\)/);
28
+ expect(thenMatch).toBeTruthy();
29
+ const thenBlock = thenMatch![0];
30
+
31
+ const liveIdx = thenBlock.indexOf("node.live = undefined");
32
+ const guardIdx = thenBlock.indexOf('run.state.status !== "running"');
33
+
34
+ expect(liveIdx).toBeGreaterThan(-1);
35
+ expect(guardIdx).toBeGreaterThan(-1);
36
+ // node.live 清理必须在 stale guard 之前(代码行号更小)
37
+ expect(liveIdx).toBeLessThan(guardIdx);
38
+ });
39
+ });
40
+
41
+ // ── M7: handleWorkerMessage shape validation ─────────────────
42
+
43
+ describe("M7: handleWorkerMessage validates msg before dereferencing", () => {
44
+ const src = readSrc(join("src", "orchestration", "error-recovery.ts"));
45
+
46
+ it("handleWorkerMessage has shape guard for msg before dereferencing opts", () => {
47
+ // handleWorkerMessage 中 `raw as WorkerMsg` 后应有 typeof/形状校验
48
+ // 防止畸形 IPC 消息(msg.opts undefined)导致 TypeError
49
+ const handlerMatch = src.match(/export async function handleWorkerMessage[\s\S]*?switch/);
50
+ expect(handlerMatch).toBeTruthy();
51
+ const handlerBlock = handlerMatch![0];
52
+ // 在 switch 前应有 msg 形状校验(typeof msg === 'object' 或 msg?.type 检查)
53
+ expect(handlerBlock).toMatch(/typeof\s+(msg|raw)|!\s*(msg|raw)|(msg|raw)\s*&&/);
54
+ });
55
+ });
56
+
57
+ // ── M8: reconstructor Array.isArray guard ────────────────────
58
+
59
+ describe("M8: session-reconstructor guards msg.content with Array.isArray", () => {
60
+ const src = readSrc(join("src", "execution", "session-reconstructor.ts"));
61
+
62
+ it("for...of msg.content is guarded by Array.isArray", () => {
63
+ // 验证 for (const block of msg.content) 前有 Array.isArray 守卫
64
+ expect(src).toContain("Array.isArray");
65
+ // 确保守卫与 msg.content 相关
66
+ const contentGuardMatch = src.match(/Array\.isArray\([^)]*content[^)]*\)/);
67
+ expect(contentGuardMatch).toBeTruthy();
68
+ });
69
+ });
@@ -0,0 +1,65 @@
1
+ // Medium batch 2 robustness fixes verification
2
+ //
3
+ // M6: worktree cleanup not gated by patchOk (decoupled)
4
+ // M9: store.save not fire-and-forget (has .catch)
5
+ // M12: budget-done transition and onRunDone in separate try blocks
6
+ // [u1-move] M10(notifyDone 序列化守卫,读壳侧 interface/helpers.ts 源文本)随壳件
7
+ // 留守 pi extension 包:src/__tests__/robustness-medium-batch2-interface.test.ts。
8
+
9
+ import { readFileSync } from "node:fs";
10
+ import { dirname,join } from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
+
13
+ import { describe, expect, it } from "vitest";
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const PKG_ROOT = join(__dirname, "..", "..");
17
+
18
+ function readSrc(relPath: string): string {
19
+ return readFileSync(join(PKG_ROOT, relPath), "utf-8");
20
+ }
21
+
22
+ // ── M6: worktree cleanup decoupled from patchOk ──────────────
23
+
24
+ describe("M6: worktree cleanup not gated by patchOk", () => {
25
+ const src = readSrc(join("src", "execution", "subagent-service.ts"));
26
+
27
+ it("worktree cleanup condition does not reference patchOk", () => {
28
+ // 找到 worktree cleanup 调用前的条件判断
29
+ const cleanupMatch = src.match(/if\s*\([^)]*worktreeHandle[^)]*\)\s*\{[\s\S]*?worktreeManager\.cleanup/);
30
+ expect(cleanupMatch).toBeTruthy();
31
+ const condition = cleanupMatch![0];
32
+ // 条件中不应包含 patchOk(解耦后 worktree cleanup 只依赖 worktreeHandle 存在)
33
+ expect(condition).not.toContain("patchOk");
34
+ });
35
+ });
36
+
37
+ // ── M9: store.save has .catch (not fire-and-forget) ──────────
38
+
39
+ describe("M9: store.save not fire-and-forget in dispatchAgentCall", () => {
40
+ const src = readSrc(join("src", "orchestration", "error-recovery.ts"));
41
+
42
+ it("no bare `void deps.store.save` without .catch", () => {
43
+ // 查找所有 void deps.store.save(run) 的出现
44
+ const bareSave = /void\s+deps\.store\.save\(run\)\s*;(?!\s*\.catch)/g;
45
+ const matches = [...src.matchAll(bareSave)];
46
+ // 修复后不应有裸 void store.save(应有 .catch 或 await)
47
+ expect(matches.length).toBe(0);
48
+ });
49
+ });
50
+
51
+ // ── M12: budget-done has separate try blocks ─────────────────
52
+
53
+ describe("M12: budget-done separates transition and onRunDone error handling", () => {
54
+ const src = readSrc(join("src", "orchestration", "error-recovery.ts"));
55
+
56
+ it("budget-done block has more than one catch (transition vs onRunDone separated)", () => {
57
+ // 找到 budget isExceeded 块
58
+ const budgetMatch = src.match(/budget\.isExceeded\(\)[\s\S]*?\}\s*\}\s*\)/);
59
+ expect(budgetMatch).toBeTruthy();
60
+ const budgetBlock = budgetMatch![0];
61
+ // 修复后应有多个 catch(至少 2 个:一个给 transition,一个给 onRunDone/emit)
62
+ const catchCount = (budgetBlock.match(/\bcatch\b/g) || []).length;
63
+ expect(catchCount).toBeGreaterThanOrEqual(2);
64
+ });
65
+ });
@@ -0,0 +1,30 @@
1
+ // Medium batch 3: thinkingLevel 字段声明检查
2
+ //
3
+ // M2(保留): AgentCallOpts 声明 thinkingLevel 字段(仍有效)
4
+ // M2 propagation / M3 model fallback: resolveAgentOpts 删除 agent 处理块后废弃,相关测试已移除
5
+
6
+ import { readFileSync } from "node:fs";
7
+ import { dirname,join } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+
10
+ import { describe, expect, it } from "vitest";
11
+
12
+ const __dirname = dirname(fileURLToPath(import.meta.url));
13
+ const PKG_ROOT = join(__dirname, "..", "..");
14
+
15
+ function readSrc(relPath: string): string {
16
+ return readFileSync(join(PKG_ROOT, relPath), "utf-8");
17
+ }
18
+
19
+ // ── M2: AgentCallOpts has thinkingLevel ───────────────────────
20
+
21
+ describe("M2: AgentCallOpts has thinkingLevel field", () => {
22
+ const src = readSrc(join("src", "orchestration", "models", "types.ts"));
23
+
24
+ it("AgentCallOpts interface declares thinkingLevel", () => {
25
+ // 找到 AgentCallOpts interface 块,断言含 thinkingLevel 字段
26
+ const ifaceMatch = src.match(/export interface AgentCallOpts \{[\s\S]*?\}/);
27
+ expect(ifaceMatch).toBeTruthy();
28
+ expect(ifaceMatch![0]).toContain("thinkingLevel");
29
+ });
30
+ });