@zhushanwen/pi-subagent-workflow 8.5.0 → 8.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 (336) hide show
  1. package/package.json +13 -16
  2. package/relay/relay.mjs +1 -1
  3. package/src/host/__tests__/pi-host.test.ts +214 -0
  4. package/src/host/pi-host.ts +109 -0
  5. package/src/index.ts +142 -32
  6. package/src/injectors/__tests__/engine-awareness.test.ts +292 -0
  7. package/src/injectors/__tests__/engine-section-stability.test.ts +341 -0
  8. package/src/injectors/__tests__/subagent-list-injector.test.ts +5 -5
  9. package/src/injectors/__tests__/workflow-list-injector.test.ts +5 -5
  10. package/src/injectors/engine-awareness.ts +123 -0
  11. package/src/injectors/model-list-injector.ts +1 -1
  12. package/src/injectors/subagent-list-injector.ts +8 -8
  13. package/src/injectors/workflow-list-injector.ts +8 -8
  14. package/src/interface/__tests__/detectors.test.ts +3 -3
  15. package/src/interface/__tests__/subagent-tool-path-guard.test.ts +157 -0
  16. package/src/interface/__tests__/subagent-tool-prompt.test.ts +12 -0
  17. package/src/interface/__tests__/tool-workflow-script-generate.test.ts +2 -2
  18. package/src/interface/__tests__/tool-workflow-throw-paths.test.ts +1 -1
  19. package/src/interface/bg-notify-render.ts +34 -13
  20. package/src/interface/commands.ts +3 -3
  21. package/src/interface/format.ts +2 -2
  22. package/src/interface/helpers.ts +3 -3
  23. package/src/interface/list-component.ts +4 -4
  24. package/src/interface/list-shared.ts +2 -2
  25. package/src/interface/list-view.ts +2 -2
  26. package/src/interface/subagent-actions.ts +288 -19
  27. package/src/interface/subagent-tool-schema.ts +163 -0
  28. package/src/interface/subagent-tool.ts +65 -129
  29. package/src/interface/subagents.ts +5 -5
  30. package/src/interface/tool-render.ts +34 -2
  31. package/src/interface/tool-workflow-script.ts +4 -4
  32. package/src/interface/tool-workflow.ts +6 -6
  33. package/src/interface/views/WorkflowsView.ts +5 -5
  34. package/src/interface/views/__tests__/WorkflowsView-signature.test.ts +3 -3
  35. package/src/interface/views/__tests__/detail-content-session-file.test.ts +2 -2
  36. package/src/interface/views/detail-content.ts +4 -4
  37. package/src/interface/views/format.ts +4 -4
  38. package/src/{orchestration/jsonl-run-store.ts → jsonl-run-store.ts} +132 -18
  39. package/src/execution/__tests__/__fixtures__/notifier-golden-snapshots.json +0 -53
  40. package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +0 -1
  41. package/src/execution/__tests__/agent-registry.test.ts +0 -363
  42. package/src/execution/__tests__/agent-result-mapper.test.ts +0 -150
  43. package/src/execution/__tests__/alive-store.test.ts +0 -147
  44. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  45. package/src/execution/__tests__/before-agent-start-injection.test.ts +0 -132
  46. package/src/execution/__tests__/bg-notify-render.test.ts +0 -256
  47. package/src/execution/__tests__/channel-registry-handshake.test.ts +0 -243
  48. package/src/execution/__tests__/chat-engine-routing.test.ts +0 -597
  49. package/src/execution/__tests__/chatmode-first-round-closure-service.test.ts +0 -365
  50. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -190
  51. package/src/execution/__tests__/chatmode-round-notify-real-chain.test.ts +0 -215
  52. package/src/execution/__tests__/concurrency-pool.test.ts +0 -250
  53. package/src/execution/__tests__/config.test.ts +0 -110
  54. package/src/execution/__tests__/conversation-wiring.test.ts +0 -198
  55. package/src/execution/__tests__/crash-recovery.test.ts +0 -320
  56. package/src/execution/__tests__/delivery-methods.test.ts +0 -385
  57. package/src/execution/__tests__/dialog-queue.test.ts +0 -299
  58. package/src/execution/__tests__/epipe-fallback.test.ts +0 -241
  59. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -243
  60. package/src/execution/__tests__/execute-nesting.test.ts +0 -323
  61. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -189
  62. package/src/execution/__tests__/execution-record.test.ts +0 -1284
  63. package/src/execution/__tests__/finalize-record.test.ts +0 -368
  64. package/src/execution/__tests__/finalized-marker.test.ts +0 -82
  65. package/src/execution/__tests__/format-schema-instruction.test.ts +0 -138
  66. package/src/execution/__tests__/format.test.ts +0 -458
  67. package/src/execution/__tests__/gc-timer.test.ts +0 -184
  68. package/src/execution/__tests__/get-record-for-action-restart.test.ts +0 -254
  69. package/src/execution/__tests__/gui-mode-dispatch.test.ts +0 -59
  70. package/src/execution/__tests__/helpers/mock-extension-api.ts +0 -30
  71. package/src/execution/__tests__/helpers/spawn-mock.ts +0 -238
  72. package/src/execution/__tests__/host-mode.test.ts +0 -87
  73. package/src/execution/__tests__/index-session-start-identity.test.ts +0 -371
  74. package/src/execution/__tests__/index-session-start.test.ts +0 -593
  75. package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
  76. package/src/execution/__tests__/lifecycle-manager.test.ts +0 -337
  77. package/src/execution/__tests__/lifecycle-predicates.test.ts +0 -116
  78. package/src/execution/__tests__/list-component.test.ts +0 -401
  79. package/src/execution/__tests__/list-fields.test.ts +0 -109
  80. package/src/execution/__tests__/manifest-parentid.test.ts +0 -117
  81. package/src/execution/__tests__/model-resolver.test.ts +0 -413
  82. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +0 -287
  83. package/src/execution/__tests__/nested-visibility.test.ts +0 -325
  84. package/src/execution/__tests__/notifier-flush.test.ts +0 -574
  85. package/src/execution/__tests__/notifier-golden-snapshot.test.ts +0 -261
  86. package/src/execution/__tests__/one-shot-upgrade.test.ts +0 -205
  87. package/src/execution/__tests__/output-collector.test.ts +0 -61
  88. package/src/execution/__tests__/parent-child-matrix.test.ts +0 -336
  89. package/src/execution/__tests__/path-encoding.test.ts +0 -104
  90. package/src/execution/__tests__/pi-invocation.test.ts +0 -134
  91. package/src/execution/__tests__/record-store.test.ts +0 -1057
  92. package/src/execution/__tests__/records-cwd-isolation.test.ts +0 -91
  93. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +0 -339
  94. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -273
  95. package/src/execution/__tests__/relay-agent.test.ts +0 -448
  96. package/src/execution/__tests__/relay-env.test.ts +0 -42
  97. package/src/execution/__tests__/resource-policy.test.ts +0 -109
  98. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  99. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -267
  100. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -253
  101. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -644
  102. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  103. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  104. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  105. package/src/execution/__tests__/sdk-contract.test.ts +0 -273
  106. package/src/execution/__tests__/session-context-resolver.test.ts +0 -167
  107. package/src/execution/__tests__/session-file-gc.test.ts +0 -293
  108. package/src/execution/__tests__/session-pending.test.ts +0 -197
  109. package/src/execution/__tests__/session-reconstructor.test.ts +0 -379
  110. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -178
  111. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -311
  112. package/src/execution/__tests__/session-start-reaper.test.ts +0 -233
  113. package/src/execution/__tests__/spawn-args.test.ts +0 -434
  114. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -189
  115. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  116. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -207
  117. package/src/execution/__tests__/spawned-children.test.ts +0 -92
  118. package/src/execution/__tests__/startup-config-declaration.test.ts +0 -35
  119. package/src/execution/__tests__/status-refactor.test.ts +0 -345
  120. package/src/execution/__tests__/stdin-writer.test.ts +0 -463
  121. package/src/execution/__tests__/stream-sink-retirement.test.ts +0 -261
  122. package/src/execution/__tests__/subagent-service-abort.test.ts +0 -60
  123. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -629
  124. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +0 -180
  125. package/src/execution/__tests__/subagent-service.test.ts +0 -788
  126. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -310
  127. package/src/execution/__tests__/subprocess-agent-runner.test.ts +0 -506
  128. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  129. package/src/execution/__tests__/timeout-integration.test.ts +0 -397
  130. package/src/execution/__tests__/tombstone-store.test.ts +0 -73
  131. package/src/execution/__tests__/tool-action.test.ts +0 -385
  132. package/src/execution/__tests__/truncline-snapshot.test.ts +0 -81
  133. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  134. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  135. package/src/execution/__tests__/ui-channels.test.ts +0 -187
  136. package/src/execution/__tests__/ui-interaction-model.test.ts +0 -67
  137. package/src/execution/__tests__/ui-request-handler-factory.test.ts +0 -370
  138. package/src/execution/__tests__/ui-request-handler.test.ts +0 -204
  139. package/src/execution/__tests__/ui-request-observability.test.ts +0 -114
  140. package/src/execution/__tests__/ui-request-queue.test.ts +0 -133
  141. package/src/execution/__tests__/worktree-manager.test.ts +0 -633
  142. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -229
  143. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +0 -181
  144. package/src/execution/__tests__/worktree-registry.test.ts +0 -199
  145. package/src/execution/agent-registry.ts +0 -193
  146. package/src/execution/agent-result-mapper.ts +0 -90
  147. package/src/execution/alive-store.ts +0 -92
  148. package/src/execution/argv-mirror.ts +0 -109
  149. package/src/execution/best-effort.ts +0 -38
  150. package/src/execution/channel-registry-access.ts +0 -144
  151. package/src/execution/concurrency-pool.ts +0 -116
  152. package/src/execution/config.ts +0 -96
  153. package/src/execution/dialog-queue.ts +0 -330
  154. package/src/execution/engine/__tests__/common/data-dir.test.ts +0 -53
  155. package/src/execution/engine/__tests__/common/errors.test.ts +0 -132
  156. package/src/execution/engine/__tests__/common/event-journal.test.ts +0 -177
  157. package/src/execution/engine/__tests__/common/kill-chain.test.ts +0 -192
  158. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +0 -81
  159. package/src/execution/engine/__tests__/common/persona-router.test.ts +0 -123
  160. package/src/execution/engine/__tests__/common/pool-manager.test.ts +0 -154
  161. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  162. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  163. package/src/execution/engine/__tests__/conformance/agent-event-invariants.ts +0 -141
  164. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +0 -109
  165. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +0 -101
  166. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +0 -77
  167. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +0 -104
  168. package/src/execution/engine/__tests__/conformance/contract.relay.test.ts +0 -342
  169. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +0 -201
  170. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +0 -76
  171. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +0 -79
  172. package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -87
  173. package/src/execution/engine/__tests__/engines-declaration.test.ts +0 -36
  174. package/src/execution/engine/__tests__/model-prompt.test.ts +0 -85
  175. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  176. package/src/execution/engine/__tests__/registry.test.ts +0 -120
  177. package/src/execution/engine/__tests__/routing.test.ts +0 -231
  178. package/src/execution/engine/common/data-dir.ts +0 -62
  179. package/src/execution/engine/common/errors.ts +0 -183
  180. package/src/execution/engine/common/event-journal.ts +0 -254
  181. package/src/execution/engine/common/journal-replay.ts +0 -62
  182. package/src/execution/engine/common/kill-chain.ts +0 -221
  183. package/src/execution/engine/common/nesting-guard.ts +0 -50
  184. package/src/execution/engine/common/persona-router.ts +0 -108
  185. package/src/execution/engine/common/pool-manager.ts +0 -226
  186. package/src/execution/engine/common/schema-emulation.ts +0 -189
  187. package/src/execution/engine/common/session-view-projection.ts +0 -51
  188. package/src/execution/engine/engine-discovery.ts +0 -65
  189. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -469
  190. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  191. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  192. package/src/execution/engine/engines/pi/pi-engine.ts +0 -415
  193. package/src/execution/engine/engines/pi/reader.ts +0 -48
  194. package/src/execution/engine/engines/pi/registration.ts +0 -35
  195. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  196. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  197. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  198. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -246
  199. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -228
  200. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  201. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -64
  202. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -127
  203. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -567
  204. package/src/execution/engine/engines/zcode/constants.ts +0 -43
  205. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -39
  206. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  207. package/src/execution/engine/engines/zcode/parser.ts +0 -436
  208. package/src/execution/engine/engines/zcode/preparer.ts +0 -363
  209. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  210. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  211. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -648
  212. package/src/execution/engine/host-task-spec.ts +0 -47
  213. package/src/execution/engine/model-prompt.ts +0 -59
  214. package/src/execution/engine/paths.ts +0 -42
  215. package/src/execution/engine/port.ts +0 -153
  216. package/src/execution/engine/registry.ts +0 -123
  217. package/src/execution/engine/routing.ts +0 -218
  218. package/src/execution/engine/types.ts +0 -304
  219. package/src/execution/execute-options-mapper.ts +0 -111
  220. package/src/execution/execution-record.ts +0 -906
  221. package/src/execution/finalize-record.ts +0 -251
  222. package/src/execution/finalized-marker.ts +0 -51
  223. package/src/execution/get-state-handshake.ts +0 -104
  224. package/src/execution/host-mode.ts +0 -56
  225. package/src/execution/idle-gc.ts +0 -47
  226. package/src/execution/lifecycle-manager.ts +0 -491
  227. package/src/execution/lifecycle-predicates.ts +0 -65
  228. package/src/execution/manifest-store.ts +0 -256
  229. package/src/execution/model-config-service.ts +0 -204
  230. package/src/execution/model-resolver.ts +0 -276
  231. package/src/execution/notifier.ts +0 -260
  232. package/src/execution/output-collector.ts +0 -88
  233. package/src/execution/path-encoding.ts +0 -60
  234. package/src/execution/pi-invocation.ts +0 -120
  235. package/src/execution/record-entry.ts +0 -132
  236. package/src/execution/record-store.ts +0 -1234
  237. package/src/execution/relay-env.ts +0 -37
  238. package/src/execution/session-context-resolver.ts +0 -64
  239. package/src/execution/session-file-gc.ts +0 -120
  240. package/src/execution/session-pending.ts +0 -164
  241. package/src/execution/session-reconstructor.ts +0 -678
  242. package/src/execution/session-runner.ts +0 -1548
  243. package/src/execution/sessions-index.ts +0 -304
  244. package/src/execution/spawn-event-adapter.ts +0 -363
  245. package/src/execution/stdin-writer.ts +0 -198
  246. package/src/execution/stream-sink.ts +0 -126
  247. package/src/execution/subagent-service.ts +0 -2119
  248. package/src/execution/subprocess-agent-runner.ts +0 -303
  249. package/src/execution/temp-prompt.ts +0 -62
  250. package/src/execution/tombstone-store.ts +0 -72
  251. package/src/execution/turn-limiter.ts +0 -102
  252. package/src/execution/types.ts +0 -910
  253. package/src/execution/ui-channels.ts +0 -216
  254. package/src/execution/ui-interaction-model.ts +0 -48
  255. package/src/execution/ui-request-handler-factory.ts +0 -212
  256. package/src/execution/ui-request-observability.ts +0 -81
  257. package/src/execution/ui-request-queue.ts +0 -174
  258. package/src/execution/worktree-manager.ts +0 -688
  259. package/src/execution/worktree-registry.ts +0 -222
  260. package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +0 -336
  261. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +0 -208
  262. package/src/orchestration/__tests__/agent-call-stream.test.ts +0 -157
  263. package/src/orchestration/__tests__/args-validator.test.ts +0 -143
  264. package/src/orchestration/__tests__/concurrency-gate.test.ts +0 -125
  265. package/src/orchestration/__tests__/config-loader.test.ts +0 -503
  266. package/src/orchestration/__tests__/error-recovery-handlers.test.ts +0 -724
  267. package/src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts +0 -405
  268. package/src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts +0 -56
  269. package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +0 -166
  270. package/src/orchestration/__tests__/execute-agent-call.test.ts +0 -314
  271. package/src/orchestration/__tests__/jsonl-run-store-loadall-sources.test.ts +0 -171
  272. package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +0 -1030
  273. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -277
  274. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +0 -96
  275. package/src/orchestration/__tests__/lifecycle.test.ts +0 -625
  276. package/src/orchestration/__tests__/review-fix-loop-e2e.test.ts +0 -1971
  277. package/src/orchestration/__tests__/script-lint.test.ts +0 -831
  278. package/src/orchestration/__tests__/skill-discovery.test.ts +0 -157
  279. package/src/orchestration/__tests__/test-mocks.ts +0 -197
  280. package/src/orchestration/__tests__/worker-host.test.ts +0 -120
  281. package/src/orchestration/__tests__/worker-returnmeta-passthrough.test.ts +0 -164
  282. package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +0 -520
  283. package/src/orchestration/__tests__/worker-script-builder.test.ts +0 -309
  284. package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +0 -110
  285. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +0 -317
  286. package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +0 -110
  287. package/src/orchestration/__tests__/workflows-e2e.test.ts +0 -537
  288. package/src/orchestration/agent-opts-resolver.ts +0 -93
  289. package/src/orchestration/args-validator.ts +0 -127
  290. package/src/orchestration/concurrency-gate.ts +0 -69
  291. package/src/orchestration/config-loader.ts +0 -315
  292. package/src/orchestration/error-recovery.ts +0 -862
  293. package/src/orchestration/execute-agent-call.ts +0 -217
  294. package/src/orchestration/launcher.ts +0 -410
  295. package/src/orchestration/lifecycle.ts +0 -396
  296. package/src/orchestration/models/__tests__/budget.test.ts +0 -367
  297. package/src/orchestration/models/__tests__/trace.test.ts +0 -408
  298. package/src/orchestration/models/agent-call.ts +0 -83
  299. package/src/orchestration/models/budget.ts +0 -148
  300. package/src/orchestration/models/ports.ts +0 -164
  301. package/src/orchestration/models/run-runtime.ts +0 -89
  302. package/src/orchestration/models/run-spec.ts +0 -83
  303. package/src/orchestration/models/run-state.ts +0 -44
  304. package/src/orchestration/models/trace.ts +0 -183
  305. package/src/orchestration/models/types.ts +0 -292
  306. package/src/orchestration/models/workflow-run.ts +0 -254
  307. package/src/orchestration/models/workflow-script-registry.ts +0 -35
  308. package/src/orchestration/models/workflow-script.ts +0 -117
  309. package/src/orchestration/script-lint.ts +0 -766
  310. package/src/orchestration/skill-discovery.ts +0 -92
  311. package/src/orchestration/worker-handle.ts +0 -115
  312. package/src/orchestration/worker-host.ts +0 -98
  313. package/src/orchestration/worker-script-builder.ts +0 -408
  314. package/src/orchestration/workflow-files.ts +0 -85
  315. package/src/orchestration/workflow-script-registry-impl.ts +0 -133
  316. package/src/shared/__tests__/agent-ref.test.ts +0 -34
  317. package/src/shared/__tests__/meta-parser.test.ts +0 -304
  318. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -280
  319. package/src/shared/__tests__/resource-discovery.test.ts +0 -736
  320. package/src/shared/__tests__/resource-meta.test.ts +0 -51
  321. package/src/shared/__tests__/schema-jsonify.test.ts +0 -81
  322. package/src/shared/agent-event.ts +0 -13
  323. package/src/shared/agent-ref.ts +0 -57
  324. package/src/shared/meta-parser.ts +0 -261
  325. package/src/shared/resource-discovery.ts +0 -811
  326. package/src/shared/resource-meta.ts +0 -65
  327. package/src/shared/schema-jsonify.ts +0 -56
  328. package/src/shared/xml-injection.ts +0 -35
  329. package/workflows/README.md +0 -81
  330. package/workflows/_shared/agent-refs.cjs +0 -40
  331. package/workflows/chain.js +0 -131
  332. package/workflows/map-reduce.js +0 -174
  333. package/workflows/parallel.js +0 -148
  334. package/workflows/review-fix-loop-utils.cjs +0 -1307
  335. package/workflows/review-fix-loop.js +0 -1396
  336. package/workflows/scatter-gather.js +0 -178
@@ -1,254 +0,0 @@
1
- // src/execution/engine/common/event-journal.ts
2
- //
3
- // 宿主 event journal(P2 公共降级层)。设计权威源:
4
- // docs/architecture/subagent-engine-abstraction.md D6(第②级归属宿主——host 统一落盘
5
- // 则全引擎免费获得、格式唯一)+ §3.3.6 event journal 格式(JSONL 中立 v1)。
6
- //
7
- // 为什么 host 落盘而非各 adapter 缓存:adapter 各自缓存会演变出六种格式;host 消费
8
- // onEvent 统一落盘,read 第②级(journal 重放)与探针 golden 语料共用同一份产物。
9
- //
10
- // 写入纪律(§3.3.6):onEvent 回调内追加写(有界缓冲 + 批量 flush),run 终态后
11
- // flush 并 fsync 一次。journal 不随池删(D5),生命周期跟随 record。
12
- //
13
- // 失败语义:journal 是降级链第②级(尽力而为的数据源)——写失败不炸主流程:
14
- // warn 一次 + 置 failed,后续 append 丢弃、close 立即返回(不静默:warn 有留痕)。
15
-
16
- import { appendFile, mkdir, open } from "node:fs/promises";
17
- import { readFileSync } from "node:fs";
18
- import { dirname } from "node:path";
19
-
20
- import { getLogger } from "@zhushanwen/pi-extension-logger";
21
-
22
- import type { AgentEvent } from "../../types.ts";
23
-
24
- const logger = getLogger("subagents");
25
-
26
- // ============================================================
27
- // 中立行格式(§3.3.6 v1)
28
- // ============================================================
29
-
30
- /** journal 单行(JSONL)。seq 是 host 侧单调递增序号——重放顺序权威。 */
31
- export interface JournalLine {
32
- v: 1;
33
- /** host 落盘时刻(Date.now(),ms)。 */
34
- ts: number;
35
- /** = RunContext.taskId = record.id(journal 文件名与池引用计数 key)。 */
36
- taskId: string;
37
- engineId: string;
38
- seq: number;
39
- /** AgentEvent 原样(onEvent 回调对象的 JSON.stringify 直接产物,无二次变换)。 */
40
- event: AgentEvent;
41
- }
42
-
43
- // ============================================================
44
- // JournalWriter
45
- // ============================================================
46
-
47
- /** flush 触发的缓冲阈值:行数与字节数任一到达即批量落盘(有界缓冲)。 */
48
- const FLUSH_THRESHOLD_LINES = 64;
49
- // eslint-disable-next-line no-magic-numbers -- 32KB = 32 * 1024 bytes 缓冲字节换算常数
50
- const FLUSH_THRESHOLD_BYTES = 32 * 1024;
51
-
52
- /** FileHandle 的结构子集(close 期 fsync 用;注入 fake 可测)。 */
53
- export interface FileHandleLike {
54
- sync(): Promise<void>;
55
- close(): Promise<void>;
56
- }
57
-
58
- /** writer 的文件系统依赖面(结构接口:测试注入 fake,免 vi.mock 整个 fs 模块)。 */
59
- export interface JournalFsDeps {
60
- mkdir(path: string, opts: { recursive: boolean }): Promise<unknown>;
61
- appendFile(path: string, data: string): Promise<void>;
62
- open(path: string, flags: string): Promise<FileHandleLike>;
63
- }
64
-
65
- const defaultFs: JournalFsDeps = {
66
- mkdir: (p, o) => mkdir(p, o),
67
- appendFile: (p, d) => appendFile(p, d, "utf8"),
68
- open: (p, f) => open(p, f),
69
- };
70
-
71
- /** JournalWriter 构造参数。 */
72
- export interface JournalWriterOpts {
73
- /** journal 文件绝对路径(经 paths.ts resolveJournalPath 派生,禁自拼)。 */
74
- path: string;
75
- taskId: string;
76
- engineId: string;
77
- }
78
-
79
- /**
80
- * 追加写 writer:append 同步入队(onEvent 是同步回调,不阻塞事件流),批量异步
81
- * flush;close = flush 全部 + fsync 一次(§3.3.6 写入纪律)。
82
- *
83
- * 文件惰性创建:首个 flush 才 mkdir + appendFile——无事件的任务不产生空 journal。
84
- */
85
- export class JournalWriter {
86
- private readonly opts: JournalWriterOpts;
87
- private readonly fs: JournalFsDeps;
88
- private readonly warn: (msg: string) => void;
89
-
90
- private buffer: string[] = [];
91
- private bufferedBytes = 0;
92
- private seq = 0;
93
- /** 串行化异步写(promise 链),防交错 append。 */
94
- private chain: Promise<void> = Promise.resolve();
95
- private failed = false;
96
- private closed = false;
97
- /** 是否成功落过盘——close 的 fsync 只对已存在的文件做(无事件任务不产生空文件)。 */
98
- private wrote = false;
99
-
100
- constructor(opts: JournalWriterOpts, fs: JournalFsDeps = defaultFs, warn: (msg: string) => void = defaultWarn) {
101
- this.opts = opts;
102
- this.fs = fs;
103
- this.warn = warn;
104
- }
105
-
106
- /** 追加一个事件(同步入队;缓冲达阈值自动排队 flush)。closed/failed 后丢弃。 */
107
- append(event: AgentEvent): void {
108
- if (this.failed || this.closed) return;
109
- const line: JournalLine = {
110
- v: 1,
111
- ts: Date.now(),
112
- taskId: this.opts.taskId,
113
- engineId: this.opts.engineId,
114
- seq: this.seq++,
115
- event,
116
- };
117
- const serialized = JSON.stringify(line);
118
- this.buffer.push(serialized);
119
- this.bufferedBytes += serialized.length;
120
- if (this.buffer.length >= FLUSH_THRESHOLD_LINES || this.bufferedBytes >= FLUSH_THRESHOLD_BYTES) {
121
- void this.flush();
122
- }
123
- }
124
-
125
- /** 把缓冲写入磁盘(串行排队;等待此前所有排队写完成)。 */
126
- flush(): Promise<void> {
127
- if (this.failed || this.buffer.length === 0) return this.chain;
128
- const chunk = `${this.buffer.join("\n")}\n`;
129
- this.buffer = [];
130
- this.bufferedBytes = 0;
131
- this.chain = this.chain.then(() => this.writeChunk(chunk));
132
- return this.chain;
133
- }
134
-
135
- /** run 终态后调用:flush 全部 + fsync 一次 + 关闭(幂等)。 */
136
- async close(): Promise<void> {
137
- if (this.closed) return;
138
- this.closed = true;
139
- await this.flush();
140
- if (this.failed || !this.wrote) return;
141
- // fsync 一次(§3.3.6):进程崩溃后已 flush 的行不丢——record 读第②级的一致性依据
142
- this.chain = this.chain.then(async () => {
143
- const fh = await this.fs.open(this.opts.path, "r");
144
- try {
145
- await fh.sync();
146
- } finally {
147
- await fh.close();
148
- }
149
- });
150
- await this.chain;
151
- }
152
-
153
- /** 是否已写失败(降级诊断用;failed 后 journal 不可作为②级数据源)。 */
154
- get isFailed(): boolean {
155
- return this.failed;
156
- }
157
-
158
- /**
159
- * 重定向落盘路径(对齐点③:journal 路径权威 = 引擎声明的池 key)。
160
- * 仅在尚未落盘(wrote=false)时允许——已 flush 过的文件搬家会制造两份半截 journal,
161
- * 重放语义破坏;已落盘时 warn 拒绝(不静默)。事件在重定向前到达的场景由调用方
162
- * 契约保证(RunContext.onPoolResolved 注释:引擎须在首个事件 emit 前回调)。
163
- */
164
- retarget(path: string): void {
165
- if (this.closed || this.failed) return;
166
- if (this.wrote) {
167
- this.warn(
168
- `[event-journal] retarget ignored for task ${this.opts.taskId}: journal already flushed to ` +
169
- `${this.opts.path} (events must not precede onPoolResolved)`,
170
- );
171
- return;
172
- }
173
- this.opts.path = path;
174
- }
175
-
176
- /** 当前落盘路径(handle.journalPath 回填数据源)。 */
177
- get path(): string {
178
- return this.opts.path;
179
- }
180
-
181
- private async writeChunk(chunk: string): Promise<void> {
182
- try {
183
- await this.fs.mkdir(dirname(this.opts.path), { recursive: true });
184
- await this.fs.appendFile(this.opts.path, chunk);
185
- this.wrote = true;
186
- } catch (err) {
187
- // 尽力而为语义:一次写失败即永久放弃(重试追写会产生乱序行),warn 留痕不静默
188
- this.failed = true;
189
- this.buffer = [];
190
- this.warn(
191
- `[event-journal] write failed, journal for task ${this.opts.taskId} is unavailable ` +
192
- `(read falls back to lower tiers): ${err instanceof Error ? err.message : String(err)}`,
193
- );
194
- }
195
- }
196
- }
197
-
198
- function defaultWarn(msg: string): void {
199
- logger.warn(msg);
200
- }
201
-
202
- // ============================================================
203
- // 重放
204
- // ============================================================
205
-
206
- /**
207
- * 重放 journal:读取路径下全部事件,重放即得 AgentEvent 流(read 第②级)。
208
- *
209
- * - 文件不存在 → [](降级链语义:②级不可达不算错误,调用方落 ③级);
210
- * - 损坏行跳过(追加写产物末行可能截断;跳过优于整体失败——设计 C5「三级都不 throw」);
211
- * - 按 seq 稳定排序后返回(重放顺序权威是 seq,不依赖文件行序的隐式保证,§3.3.6)。
212
- */
213
- export function replayJournal(path: string): AgentEvent[] {
214
- let raw: string;
215
- try {
216
- raw = readFileSync(path, "utf8");
217
- } catch {
218
- return [];
219
- }
220
- const lines: JournalLine[] = [];
221
- for (const row of raw.split("\n")) {
222
- const trimmed = row.trim();
223
- if (trimmed === "") continue;
224
- const parsed = parseLine(trimmed);
225
- if (parsed !== undefined) lines.push(parsed);
226
- }
227
- lines.sort((a, b) => a.seq - b.seq);
228
- return lines.map((l) => l.event);
229
- }
230
-
231
- /** 单行 parse + 结构 guard(v=1 + event 形状最小判别:object 且 type 为 string)。 */
232
- function parseLine(trimmed: string): JournalLine | undefined {
233
- let parsed: unknown;
234
- try {
235
- parsed = JSON.parse(trimmed);
236
- } catch {
237
- return undefined;
238
- }
239
- if (typeof parsed !== "object" || parsed === null) return undefined;
240
- const rec = parsed as Record<string, unknown>;
241
- const event = rec.event;
242
- if (rec.v !== 1 || typeof rec.ts !== "number" || typeof rec.seq !== "number") return undefined;
243
- if (typeof event !== "object" || event === null || typeof (event as Record<string, unknown>).type !== "string") {
244
- return undefined;
245
- }
246
- return {
247
- v: 1,
248
- ts: rec.ts,
249
- taskId: typeof rec.taskId === "string" ? rec.taskId : "",
250
- engineId: typeof rec.engineId === "string" ? rec.engineId : "",
251
- seq: rec.seq,
252
- event: event as AgentEvent,
253
- };
254
- }
@@ -1,62 +0,0 @@
1
- // src/execution/engine/common/journal-replay.ts
2
- //
3
- // read 第②级(宿主 event journal 重放)的公共实现(P4,对齐点①接线)。设计权威源:
4
- // docs/architecture/subagent-engine-abstraction.md D6 + §3.3.6「重放等价性」——
5
- // journal 重放与 live 通路共用同一 reducer(updateFromEvent 范式),不引入第二套
6
- // 解析器;conformance C5 断言重放 turns 与 live 一致。
7
- //
8
- // 为什么放 common:zcode/pi 的 read() ②级降级是同一段逻辑(replayJournal 拿事件流 →
9
- // live reducer 累积 turns → 投影 SessionView)——放引擎各自实现会漂移出两份形状。
10
-
11
- import { createRecord, updateFromEvent } from "../../execution-record.ts";
12
- import type { AgentEvent } from "../../types.ts";
13
- import type { EngineHandle, SessionView } from "../types.ts";
14
- import { replayJournal } from "./event-journal.ts";
15
- import { aggregateUsage, toReplayedTurn } from "./session-view-projection.ts";
16
-
17
- /**
18
- * journal → SessionView(read 第②级)。
19
- * 返回 undefined = ②级不可达(journal 路径缺省 / 文件不存在 / 无事件),调用方落 ③级。
20
- * coarse 引擎(zcode)journal 只含合成事件,重放退化为摘要级——D6 已声明的保真度
21
- * 下限,非缺陷。
22
- */
23
- export function replayJournalToSessionView(
24
- handle: EngineHandle,
25
- engineId: string,
26
- ): SessionView | undefined {
27
- const journalPath = handle.data.journalPath;
28
- if (journalPath === undefined) return undefined;
29
- const events = replayJournal(journalPath);
30
- if (events.length === 0) return undefined;
31
- return eventsToSessionView(events, engineId, sessionIdFromHandle(handle));
32
- }
33
-
34
- /** 事件流 → SessionView(live reducer 累积 turns——重放等价性的实现体)。 */
35
- export function eventsToSessionView(
36
- events: readonly AgentEvent[],
37
- engineId: string,
38
- sessionId?: string,
39
- ): SessionView {
40
- const record = createRecord("journal-replay", {
41
- agent: "journal-replay",
42
- model: "",
43
- mode: "background",
44
- task: "",
45
- slug: "",
46
- startedAt: 0,
47
- });
48
- for (const ev of events) updateFromEvent(record, ev);
49
- return {
50
- engineId,
51
- ...(sessionId !== undefined ? { sessionId } : {}),
52
- turns: record.turns.map(toReplayedTurn),
53
- usage: aggregateUsage(record.turns),
54
- source: "journal",
55
- };
56
- }
57
-
58
- /** handle.sessionRef 的 sessionId 提取(引擎自定义键,运行时 guard)。 */
59
- function sessionIdFromHandle(handle: EngineHandle): string | undefined {
60
- const v = handle.data.sessionRef["sessionId"];
61
- return typeof v === "string" ? v : undefined;
62
- }
@@ -1,221 +0,0 @@
1
- // src/execution/engine/common/kill-chain.ts
2
- //
3
- // 超时杀链与 abort 两级中断(P2 公共降级层)。设计权威源:
4
- // docs/architecture/subagent-engine-abstraction.md D1(abort 分级:引擎原生中断 →
5
- // 公共杀链兜底;CLI-only 引擎直接杀链,杀死后宿主合成终态)+ §3.3.3 engine_timeout /
6
- // engine_run_failed 行 + 附录 A「CLI 超时」行(6/6 引擎全缺 → 宿主公共层全补)。
7
- //
8
- // 为什么放公共层:没有任何引擎有 CLI 级超时(§2.2 表),杀链写一次全引擎复用(D4)。
9
-
10
- import { getLogger } from "@zhushanwen/pi-extension-logger";
11
-
12
- import { engineTimeoutDetail } from "./errors.ts";
13
- import type { AgentOutcome, AgentTaskSpec } from "../types.ts";
14
- import { DEFAULT_ENGINE_ID } from "../registry.ts";
15
-
16
- const logger = getLogger("subagents");
17
-
18
- // ============================================================
19
- // 杀链(SIGTERM → grace → SIGKILL)
20
- // ============================================================
21
-
22
- /**
23
- * 可杀子进程的结构形状(Node ChildProcess 的结构子集)。
24
- * 用结构接口而非 ChildProcess 类型:测试可注入 fake(ChildProcess 全字段构造过重),
25
- * 且未来 driver host 的常驻进程句柄只要满足此形状即可复用杀链。
26
- */
27
- export interface KillableChild {
28
- /** 非 null = 进程已退出(自然退出码)。 */
29
- readonly exitCode: number | null;
30
- /** 非 null = 进程被信号杀死。exitCode/signalCode 任一非 null 即已退出。 */
31
- readonly signalCode: string | null;
32
- /** 发信号。返回 false = 进程已不存在(kill no-op)。 */
33
- kill(signal?: NodeJS.Signals | number): boolean;
34
- once(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): unknown;
35
- }
36
-
37
- /** SIGTERM 优雅窗口默认值(ms)。实测校准点:设计 §5 待验证检查点⑤(zcode 对 SIGTERM 的响应时序)。 */
38
- export const DEFAULT_KILL_GRACE_MS = 5_000;
39
-
40
- /** SIGKILL 发出后的收尸等待上限(ms)——SIGKILL 后进程必死(D 状态罕见),有界等待防挂死。 */
41
- const SIGKILL_REAP_TIMEOUT_MS = 10_000;
42
-
43
- /**
44
- * 宿主超时 abort 的 signal.reason 标记(对齐点④)。mergeTimeoutSignal(SAR 侧超时
45
- * 合并链)产出;引擎 abort 合成终态时判别「超时 vs 用户 cancel」——超时统一走
46
- * synthesizeTimeoutOutcome(engine_timeout),cancel 维持中止标记(engine_run_failed)。
47
- */
48
- export const HOST_TIMEOUT_ABORT_REASON = "agent-call-timeout";
49
-
50
- /**
51
- * 杀链:SIGTERM → 等待 graceMs → 仍存活则 SIGKILL。
52
- *
53
- * @returns 'terminated' = SIGTERM 优雅退出(或进程已自行退出);'killed' = 走了 SIGKILL。
54
- */
55
- export async function killChain(
56
- child: KillableChild,
57
- opts: { graceMs: number },
58
- ): Promise<"terminated" | "killed"> {
59
- // 已退出(自然/已被杀)→ 无需发信号,按优雅终止口径返回
60
- if (child.exitCode !== null || child.signalCode !== null) return "terminated";
61
-
62
- const exited = waitForExit(child);
63
- safeKill(child, "SIGTERM");
64
-
65
- const graceful = await raceTimeout(exited, opts.graceMs);
66
- if (graceful === "settled") return "terminated";
67
- // grace 超时后进程可能恰好在检查前一刻退出——复核退出态,避免误杀已死进程
68
- if (child.exitCode !== null || child.signalCode !== null) return "terminated";
69
-
70
- safeKill(child, "SIGKILL");
71
- // 有界收尸:无论等到与否都返回 'killed'(信号已发出,返回值表达「走了 SIGKILL」)
72
- await raceTimeout(exited, SIGKILL_REAP_TIMEOUT_MS);
73
- return "killed";
74
- }
75
-
76
- /**
77
- * 发信号兜底包裹:进程恰在退出态检查与 kill 之间自退时,ChildProcess.kill 可能抛
78
- * (zsub 实测经验)——幂等吞掉并 debug 留痕,不阻断杀链语义(对已退进程信号本就是
79
- * no-op)。收口自 zcode launcher 的内联实现(对齐点②:单一权威)。
80
- */
81
- function safeKill(child: KillableChild, signal: NodeJS.Signals): void {
82
- try {
83
- child.kill(signal);
84
- } catch (err) {
85
- logger.debug(
86
- `[kill-chain] ${signal} on exited process: ${err instanceof Error ? err.message : String(err)}`,
87
- );
88
- }
89
- }
90
-
91
- // ============================================================
92
- // 超时终态合成
93
- // ============================================================
94
-
95
- /**
96
- * 合成 engine_timeout 终态(宿主超时杀链走完后的 AgentOutcome)。
97
- * 含 stdout 尾部 2000 字 + 「可用 engine: pi 重跑」建议(§3.3.3 第 6 行);
98
- * exitCode: null = 被信号杀死(AgentOutcome 的杀链判据,§3.3.5)。
99
- */
100
- export function synthesizeTimeoutOutcome(
101
- task: AgentTaskSpec,
102
- stdoutTail: string,
103
- engineId: string = DEFAULT_ENGINE_ID,
104
- ): AgentOutcome {
105
- return {
106
- content: "",
107
- // slug 进错误信息:单看 outcome(record 之外)也能定位是哪个任务超时
108
- error: `engine_timeout: [slug=${task.slug}] ${engineTimeoutDetail(stdoutTail)}`,
109
- // 被信号杀死:退出码语义为 null(§3.3.5 AgentOutcome.exitCode 注释)
110
- exitCode: null,
111
- engineId,
112
- };
113
- }
114
-
115
- // ============================================================
116
- // abort 两级编排
117
- // ============================================================
118
-
119
- /** 原生中断后的宽限窗口默认值(ms):中断指令送达 → 引擎自行收尾的等待上限。 */
120
- export const DEFAULT_NATIVE_INTERRUPT_GRACE_MS = 3_000;
121
-
122
- /**
123
- * abort 两级编排 helper(D1 abort 分级的公共实现):
124
- * signal abort 时 ①先调引擎原生中断(tryNativeInterrupt,若有)并给宽限窗口,
125
- * 窗口内未停(或无原生中断——CLI-only 引擎)则 ②走杀链兜底。
126
- *
127
- * 进程自然退出时以 'terminated' settle(挂在 exit 事件上,杀链对已退进程是 no-op),
128
- * 调用方可安全 await;signal 永不 abort 且进程已退时也会 settle,不悬挂。
129
- */
130
- export function abortWithFallback(
131
- child: KillableChild,
132
- signal: AbortSignal,
133
- tryNativeInterrupt?: () => Promise<void>,
134
- opts?: { graceMs?: number; nativeGraceMs?: number },
135
- ): Promise<"terminated" | "killed"> {
136
- const graceMs = opts?.graceMs ?? DEFAULT_KILL_GRACE_MS;
137
- const nativeGraceMs = opts?.nativeGraceMs ?? DEFAULT_NATIVE_INTERRUPT_GRACE_MS;
138
-
139
- return new Promise<"terminated" | "killed">((resolve) => {
140
- let settled = false;
141
- // 三个 handler 互相引用(finish 移除 onAbort / onAbort 触发 runChain / runChain
142
- // 兜底 finish),用函数声明 + 提升消解声明环,避免 use-before-define。
143
- function finish(result: "terminated" | "killed"): void {
144
- if (settled) return;
145
- settled = true;
146
- signal.removeEventListener("abort", onAbort);
147
- resolve(result);
148
- }
149
-
150
- function onExit(): void {
151
- finish("terminated");
152
- }
153
-
154
- function runChain(): void {
155
- void (async () => {
156
- if (tryNativeInterrupt) {
157
- try {
158
- await tryNativeInterrupt();
159
- } catch (err) {
160
- // 原生中断失败(协议错/管道断)→ 直接落杀链,中断失败不阻断兜底。
161
- // debug 级留诊断线索:这不是错误终态,只是该引擎优雅中断不可用
162
- logger.debug(
163
- `[kill-chain] native interrupt failed, falling back to kill chain: ${
164
- err instanceof Error ? err.message : String(err)
165
- }`,
166
- );
167
- }
168
- const stopped = await raceTimeout(waitForExit(child), nativeGraceMs);
169
- if (stopped === "settled" || settled) return; // 原生中断生效,进程已停
170
- }
171
- finish(await killChain(child, { graceMs }));
172
- })();
173
- }
174
-
175
- function onAbort(): void {
176
- runChain();
177
- }
178
-
179
- // 进程自然退出(含原生中断生效)→ 优雅终止口径。
180
- // once listener 不显式移除:触发时 finish 已幂等,单 child 单 listener 无堆积。
181
- child.once("exit", onExit);
182
- if (child.exitCode !== null || child.signalCode !== null) {
183
- finish("terminated");
184
- return;
185
- }
186
-
187
- if (signal.aborted) runChain();
188
- else signal.addEventListener("abort", onAbort, { once: true });
189
- });
190
- }
191
-
192
- // ── 内部工具 ────────────────────────────────────────────────────
193
-
194
- /** 等 child 退出(已退出立即 settle;否则挂一次性 exit listener)。 */
195
- function waitForExit(child: KillableChild): Promise<void> {
196
- return new Promise<void>((resolve) => {
197
- if (child.exitCode !== null || child.signalCode !== null) {
198
- resolve();
199
- return;
200
- }
201
- child.once("exit", () => resolve());
202
- });
203
- }
204
-
205
- /** promise vs 超时:超时先到返回 'timeout'(promise 继续但被放弃等待)。 */
206
- function raceTimeout(p: Promise<void>, ms: number): Promise<"settled" | "timeout"> {
207
- return new Promise<"settled" | "timeout">((resolve) => {
208
- const timer = setTimeout(() => resolve("timeout"), ms);
209
- p.then(
210
- () => {
211
- clearTimeout(timer);
212
- resolve("settled");
213
- },
214
- () => {
215
- // 被 await 的 exit promise 不会 reject;防御分支保持语义完整(超时口径胜出前出错按 settled 处理)
216
- clearTimeout(timer);
217
- resolve("settled");
218
- },
219
- );
220
- });
221
- }
@@ -1,50 +0,0 @@
1
- // src/execution/engine/common/nesting-guard.ts
2
- //
3
- // 嵌套防护(P2 公共降级层)。设计权威源:
4
- // docs/architecture/subagent-engine-abstraction.md D8(嵌套防护双层):
5
- // 统一 XYZ_AGENT_SUBAGENT=1 标记(所有引擎 spawn 都注入,引擎 adapter 检测到即拒绝
6
- // 递归派发)+ 剥离各引擎原生标记(CC 的 CLAUDECODE / zsub 的 ZSW_NESTED / pi 的
7
- // PI_SUBAGENT_*)防继承泄漏——子代理环境的旧标记会让孙代理误判自己已在嵌套层。
8
- //
9
- // 为什么 env 标记是唯一跨引擎可靠手段(被否方案见设计):「隔离目录里不装扩展」
10
- // 依赖配置洁癖,且 opencode/CC 会吃项目级配置;env 由宿主显式控制,随 spawn 必达。
11
-
12
- import { nestedSpawnRejectedError } from "./errors.ts";
13
-
14
- /** 统一嵌套标记 env 名(D8)。值恒 '1'。 */
15
- export const NESTED_SPAWN_ENV = "XYZ_AGENT_SUBAGENT";
16
-
17
- /** 需剥离的引擎原生嵌套标记(精确名)。 */
18
- const NATIVE_NESTED_KEYS: readonly string[] = ["CLAUDECODE", "ZSW_NESTED"];
19
-
20
- /** 需剥离的引擎原生嵌套标记前缀(pi 家族)。 */
21
- const NATIVE_NESTED_PREFIXES: readonly string[] = ["PI_SUBAGENT_"];
22
-
23
- /** env 对象形状(NodeJS.ProcessEnv 的结构子集,测试可传普通对象)。 */
24
- export type SpawnEnv = Record<string, string | undefined>;
25
-
26
- /**
27
- * 构造子代理 spawn env:注入 XYZ_AGENT_SUBAGENT=1 + 剥离引擎原生嵌套标记。
28
- * 返回新对象,不改入参(spawn env 组装链中的多层 spread 安全)。
29
- */
30
- export function buildNestedSpawnEnv(baseEnv: SpawnEnv): SpawnEnv {
31
- const env: SpawnEnv = {};
32
- for (const [key, value] of Object.entries(baseEnv)) {
33
- if (NATIVE_NESTED_KEYS.includes(key)) continue;
34
- if (NATIVE_NESTED_PREFIXES.some((prefix) => key.startsWith(prefix))) continue;
35
- env[key] = value;
36
- }
37
- env[NESTED_SPAWN_ENV] = "1";
38
- return env;
39
- }
40
-
41
- /**
42
- * 嵌套 spawn 防护断言:检测到统一标记(本进程已是 subagent)抛
43
- * EngineError(nested_spawn_rejected)——文案说明防护规则、指向 task 内自行完成。
44
- * 调用点:subagent 工具入口(进程创建前拒绝,D11 处置三级)。
45
- */
46
- export function assertNotNestedSpawn(env: SpawnEnv): void {
47
- if (env[NESTED_SPAWN_ENV] === "1") {
48
- throw nestedSpawnRejectedError();
49
- }
50
- }