@zhushanwen/pi-subagent-workflow 8.6.0 → 8.8.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 (364) hide show
  1. package/README.md +5 -11
  2. package/package.json +13 -20
  3. package/relay/relay.mjs +1 -1
  4. package/skills/workflow-script-format/SKILL.md +32 -13
  5. package/src/host/__tests__/pi-host.test.ts +235 -0
  6. package/src/host/pi-host.ts +163 -0
  7. package/src/index.ts +141 -138
  8. package/src/injectors/__tests__/engine-awareness.test.ts +292 -0
  9. package/src/injectors/__tests__/engine-section-stability.test.ts +343 -0
  10. package/src/injectors/__tests__/model-list-injector.test.ts +18 -21
  11. package/src/injectors/__tests__/subagent-list-injector.test.ts +59 -19
  12. package/src/injectors/__tests__/workflow-list-injector.test.ts +31 -17
  13. package/src/injectors/engine-awareness.ts +119 -0
  14. package/src/injectors/model-list-injector.ts +15 -58
  15. package/src/injectors/subagent-list-injector.ts +56 -114
  16. package/src/injectors/workflow-list-injector.ts +37 -70
  17. package/src/interface/__tests__/detectors.test.ts +48 -37
  18. package/src/interface/__tests__/subagent-tool-path-guard.test.ts +2 -2
  19. package/src/interface/__tests__/subagent-tool-prompt.test.ts +6 -3
  20. package/src/interface/__tests__/tool-workflow-run-builtin-name.test.ts +216 -0
  21. package/src/interface/__tests__/tool-workflow-script-generate.test.ts +17 -6
  22. package/src/interface/__tests__/tool-workflow-throw-paths.test.ts +38 -2
  23. package/src/interface/bg-notify-render.ts +7 -17
  24. package/src/interface/command-actions.ts +5 -15
  25. package/src/interface/commands.ts +4 -4
  26. package/src/interface/format.ts +17 -6
  27. package/src/interface/gui-mappers.ts +18 -22
  28. package/src/interface/helpers.ts +9 -130
  29. package/src/interface/list-component.ts +5 -5
  30. package/src/interface/list-shared.ts +3 -3
  31. package/src/interface/list-view.ts +3 -3
  32. package/src/interface/subagent-actions.ts +66 -439
  33. package/src/interface/subagent-tool-schema.ts +21 -17
  34. package/src/interface/subagent-tool.ts +12 -7
  35. package/src/interface/subagents.ts +4 -4
  36. package/src/interface/tool-render.ts +37 -15
  37. package/src/interface/tool-workflow-script.ts +34 -76
  38. package/src/interface/tool-workflow.ts +57 -94
  39. package/src/interface/views/WorkflowsView.ts +8 -16
  40. package/src/interface/views/__tests__/WorkflowsView-signature.test.ts +3 -3
  41. package/src/interface/views/__tests__/detail-content-session-file.test.ts +2 -2
  42. package/src/interface/views/detail-content.ts +4 -4
  43. package/src/interface/views/format.ts +23 -62
  44. package/src/{orchestration/jsonl-run-store.ts → jsonl-run-store.ts} +137 -225
  45. package/agents/analyst.md +0 -61
  46. package/agents/coder.md +0 -70
  47. package/agents/debugger.md +0 -67
  48. package/agents/doc-reviewer.md +0 -50
  49. package/agents/explorer.md +0 -64
  50. package/agents/general-purpose.md +0 -32
  51. package/agents/orchestrator.md +0 -63
  52. package/agents/planner.md +0 -54
  53. package/agents/researcher.md +0 -65
  54. package/agents/reviewer.md +0 -74
  55. package/src/execution/__tests__/__fixtures__/notifier-golden-snapshots.json +0 -53
  56. package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +0 -1
  57. package/src/execution/__tests__/agent-registry.test.ts +0 -363
  58. package/src/execution/__tests__/agent-result-mapper.test.ts +0 -150
  59. package/src/execution/__tests__/alive-store.test.ts +0 -147
  60. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  61. package/src/execution/__tests__/before-agent-start-injection.test.ts +0 -132
  62. package/src/execution/__tests__/bg-notify-render.test.ts +0 -329
  63. package/src/execution/__tests__/channel-registry-handshake.test.ts +0 -243
  64. package/src/execution/__tests__/chat-engine-routing.test.ts +0 -601
  65. package/src/execution/__tests__/chatmode-first-round-closure-service.test.ts +0 -365
  66. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -190
  67. package/src/execution/__tests__/chatmode-round-notify-real-chain.test.ts +0 -215
  68. package/src/execution/__tests__/concurrency-pool.test.ts +0 -250
  69. package/src/execution/__tests__/config.test.ts +0 -110
  70. package/src/execution/__tests__/conversation-wiring.test.ts +0 -198
  71. package/src/execution/__tests__/crash-recovery.test.ts +0 -320
  72. package/src/execution/__tests__/delivery-methods.test.ts +0 -422
  73. package/src/execution/__tests__/dialog-queue.test.ts +0 -299
  74. package/src/execution/__tests__/epipe-fallback.test.ts +0 -241
  75. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -243
  76. package/src/execution/__tests__/execute-nesting.test.ts +0 -323
  77. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
  78. package/src/execution/__tests__/execution-record.test.ts +0 -1394
  79. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +0 -171
  80. package/src/execution/__tests__/finalize-record.test.ts +0 -368
  81. package/src/execution/__tests__/finalized-marker.test.ts +0 -82
  82. package/src/execution/__tests__/format-schema-instruction.test.ts +0 -169
  83. package/src/execution/__tests__/format.test.ts +0 -458
  84. package/src/execution/__tests__/gc-timer.test.ts +0 -184
  85. package/src/execution/__tests__/get-record-for-action-restart.test.ts +0 -254
  86. package/src/execution/__tests__/gui-mode-dispatch.test.ts +0 -59
  87. package/src/execution/__tests__/helpers/mock-extension-api.ts +0 -30
  88. package/src/execution/__tests__/helpers/spawn-mock.ts +0 -242
  89. package/src/execution/__tests__/host-mode.test.ts +0 -87
  90. package/src/execution/__tests__/index-session-start-identity.test.ts +0 -371
  91. package/src/execution/__tests__/index-session-start.test.ts +0 -672
  92. package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
  93. package/src/execution/__tests__/lifecycle-manager.test.ts +0 -383
  94. package/src/execution/__tests__/lifecycle-predicates.test.ts +0 -116
  95. package/src/execution/__tests__/list-component.test.ts +0 -401
  96. package/src/execution/__tests__/list-fields.test.ts +0 -140
  97. package/src/execution/__tests__/manifest-parentid.test.ts +0 -117
  98. package/src/execution/__tests__/model-resolver.test.ts +0 -465
  99. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +0 -287
  100. package/src/execution/__tests__/nested-visibility.test.ts +0 -325
  101. package/src/execution/__tests__/notifier-flush.test.ts +0 -612
  102. package/src/execution/__tests__/notifier-golden-snapshot.test.ts +0 -261
  103. package/src/execution/__tests__/notify-ledger.test.ts +0 -826
  104. package/src/execution/__tests__/one-shot-upgrade.test.ts +0 -205
  105. package/src/execution/__tests__/output-collector.test.ts +0 -358
  106. package/src/execution/__tests__/parent-child-matrix.test.ts +0 -336
  107. package/src/execution/__tests__/path-encoding.test.ts +0 -104
  108. package/src/execution/__tests__/pi-invocation.test.ts +0 -134
  109. package/src/execution/__tests__/record-store.test.ts +0 -1057
  110. package/src/execution/__tests__/records-cwd-isolation.test.ts +0 -91
  111. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +0 -339
  112. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -273
  113. package/src/execution/__tests__/relay-agent.test.ts +0 -448
  114. package/src/execution/__tests__/relay-env.test.ts +0 -42
  115. package/src/execution/__tests__/resource-policy.test.ts +0 -109
  116. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  117. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -267
  118. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -253
  119. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -687
  120. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  121. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  122. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  123. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +0 -199
  124. package/src/execution/__tests__/sdk-contract.test.ts +0 -273
  125. package/src/execution/__tests__/session-context-resolver.test.ts +0 -167
  126. package/src/execution/__tests__/session-file-gc.test.ts +0 -293
  127. package/src/execution/__tests__/session-pending.test.ts +0 -197
  128. package/src/execution/__tests__/session-reconstructor.test.ts +0 -379
  129. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -178
  130. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -350
  131. package/src/execution/__tests__/session-start-reaper.test.ts +0 -233
  132. package/src/execution/__tests__/spawn-args.test.ts +0 -445
  133. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -189
  134. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  135. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -207
  136. package/src/execution/__tests__/spawned-children.test.ts +0 -92
  137. package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
  138. package/src/execution/__tests__/startup-config-declaration.test.ts +0 -35
  139. package/src/execution/__tests__/status-refactor.test.ts +0 -345
  140. package/src/execution/__tests__/stdin-writer.test.ts +0 -463
  141. package/src/execution/__tests__/stream-sink-retirement.test.ts +0 -261
  142. package/src/execution/__tests__/subagent-service-abort.test.ts +0 -60
  143. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -629
  144. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +0 -180
  145. package/src/execution/__tests__/subagent-service.test.ts +0 -788
  146. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -310
  147. package/src/execution/__tests__/subprocess-agent-runner.test.ts +0 -599
  148. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  149. package/src/execution/__tests__/timeout-integration.test.ts +0 -615
  150. package/src/execution/__tests__/tombstone-store.test.ts +0 -73
  151. package/src/execution/__tests__/tool-action.test.ts +0 -476
  152. package/src/execution/__tests__/truncline-snapshot.test.ts +0 -81
  153. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  154. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  155. package/src/execution/__tests__/ui-channels.test.ts +0 -187
  156. package/src/execution/__tests__/ui-interaction-model.test.ts +0 -67
  157. package/src/execution/__tests__/ui-request-handler-factory.test.ts +0 -370
  158. package/src/execution/__tests__/ui-request-handler.test.ts +0 -204
  159. package/src/execution/__tests__/ui-request-observability.test.ts +0 -114
  160. package/src/execution/__tests__/ui-request-queue.test.ts +0 -133
  161. package/src/execution/__tests__/worktree-manager.test.ts +0 -633
  162. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -229
  163. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +0 -181
  164. package/src/execution/__tests__/worktree-registry.test.ts +0 -199
  165. package/src/execution/agent-registry.ts +0 -199
  166. package/src/execution/agent-result-mapper.ts +0 -90
  167. package/src/execution/alive-store.ts +0 -92
  168. package/src/execution/argv-mirror.ts +0 -113
  169. package/src/execution/best-effort.ts +0 -38
  170. package/src/execution/channel-registry-access.ts +0 -144
  171. package/src/execution/concurrency-pool.ts +0 -116
  172. package/src/execution/config.ts +0 -96
  173. package/src/execution/dialog-queue.ts +0 -330
  174. package/src/execution/engine/__tests__/common/data-dir.test.ts +0 -53
  175. package/src/execution/engine/__tests__/common/errors.test.ts +0 -132
  176. package/src/execution/engine/__tests__/common/event-journal.test.ts +0 -177
  177. package/src/execution/engine/__tests__/common/kill-chain.test.ts +0 -192
  178. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +0 -81
  179. package/src/execution/engine/__tests__/common/persona-router.test.ts +0 -123
  180. package/src/execution/engine/__tests__/common/pool-manager.test.ts +0 -154
  181. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  182. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  183. package/src/execution/engine/__tests__/conformance/agent-event-invariants.ts +0 -141
  184. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +0 -109
  185. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +0 -101
  186. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +0 -77
  187. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +0 -104
  188. package/src/execution/engine/__tests__/conformance/contract.relay.test.ts +0 -342
  189. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +0 -201
  190. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +0 -76
  191. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +0 -79
  192. package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -87
  193. package/src/execution/engine/__tests__/engines-declaration.test.ts +0 -36
  194. package/src/execution/engine/__tests__/model-prompt.test.ts +0 -85
  195. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  196. package/src/execution/engine/__tests__/registry.test.ts +0 -120
  197. package/src/execution/engine/__tests__/routing.test.ts +0 -231
  198. package/src/execution/engine/common/data-dir.ts +0 -62
  199. package/src/execution/engine/common/errors.ts +0 -183
  200. package/src/execution/engine/common/event-journal.ts +0 -254
  201. package/src/execution/engine/common/journal-replay.ts +0 -62
  202. package/src/execution/engine/common/kill-chain.ts +0 -221
  203. package/src/execution/engine/common/nesting-guard.ts +0 -50
  204. package/src/execution/engine/common/persona-router.ts +0 -108
  205. package/src/execution/engine/common/pool-manager.ts +0 -226
  206. package/src/execution/engine/common/schema-emulation.ts +0 -189
  207. package/src/execution/engine/common/session-view-projection.ts +0 -51
  208. package/src/execution/engine/engine-discovery.ts +0 -65
  209. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -469
  210. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  211. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  212. package/src/execution/engine/engines/pi/pi-engine.ts +0 -415
  213. package/src/execution/engine/engines/pi/reader.ts +0 -48
  214. package/src/execution/engine/engines/pi/registration.ts +0 -35
  215. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  216. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  217. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  218. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -246
  219. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -228
  220. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  221. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -64
  222. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -127
  223. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -580
  224. package/src/execution/engine/engines/zcode/constants.ts +0 -43
  225. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -39
  226. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  227. package/src/execution/engine/engines/zcode/parser.ts +0 -436
  228. package/src/execution/engine/engines/zcode/preparer.ts +0 -363
  229. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  230. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  231. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -658
  232. package/src/execution/engine/host-task-spec.ts +0 -47
  233. package/src/execution/engine/model-prompt.ts +0 -59
  234. package/src/execution/engine/paths.ts +0 -42
  235. package/src/execution/engine/port.ts +0 -153
  236. package/src/execution/engine/registry.ts +0 -123
  237. package/src/execution/engine/routing.ts +0 -218
  238. package/src/execution/engine/types.ts +0 -309
  239. package/src/execution/execute-options-mapper.ts +0 -112
  240. package/src/execution/execution-record.ts +0 -965
  241. package/src/execution/finalize-record.ts +0 -251
  242. package/src/execution/finalized-marker.ts +0 -51
  243. package/src/execution/get-state-handshake.ts +0 -104
  244. package/src/execution/host-mode.ts +0 -56
  245. package/src/execution/idle-gc.ts +0 -47
  246. package/src/execution/lifecycle-manager.ts +0 -513
  247. package/src/execution/lifecycle-predicates.ts +0 -65
  248. package/src/execution/manifest-store.ts +0 -256
  249. package/src/execution/model-config-service.ts +0 -219
  250. package/src/execution/model-resolver.ts +0 -248
  251. package/src/execution/notifier.ts +0 -330
  252. package/src/execution/notify-ledger.ts +0 -580
  253. package/src/execution/output-collector.ts +0 -228
  254. package/src/execution/path-encoding.ts +0 -60
  255. package/src/execution/pi-invocation.ts +0 -120
  256. package/src/execution/record-entry.ts +0 -132
  257. package/src/execution/record-store.ts +0 -1234
  258. package/src/execution/relay-env.ts +0 -37
  259. package/src/execution/session-context-resolver.ts +0 -64
  260. package/src/execution/session-file-gc.ts +0 -120
  261. package/src/execution/session-pending.ts +0 -164
  262. package/src/execution/session-reconstructor.ts +0 -678
  263. package/src/execution/session-runner.ts +0 -1781
  264. package/src/execution/sessions-index.ts +0 -304
  265. package/src/execution/spawn-event-adapter.ts +0 -363
  266. package/src/execution/stdin-writer.ts +0 -198
  267. package/src/execution/stream-sink.ts +0 -126
  268. package/src/execution/subagent-service.ts +0 -2141
  269. package/src/execution/subprocess-agent-runner.ts +0 -317
  270. package/src/execution/temp-prompt.ts +0 -62
  271. package/src/execution/tombstone-store.ts +0 -72
  272. package/src/execution/turn-limiter.ts +0 -102
  273. package/src/execution/types.ts +0 -973
  274. package/src/execution/ui-channels.ts +0 -216
  275. package/src/execution/ui-interaction-model.ts +0 -48
  276. package/src/execution/ui-request-handler-factory.ts +0 -212
  277. package/src/execution/ui-request-observability.ts +0 -81
  278. package/src/execution/ui-request-queue.ts +0 -184
  279. package/src/execution/worktree-manager.ts +0 -688
  280. package/src/execution/worktree-registry.ts +0 -222
  281. package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +0 -349
  282. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +0 -202
  283. package/src/orchestration/__tests__/agent-call-stream.test.ts +0 -152
  284. package/src/orchestration/__tests__/args-validator.test.ts +0 -143
  285. package/src/orchestration/__tests__/config-loader.test.ts +0 -503
  286. package/src/orchestration/__tests__/error-recovery-handlers.test.ts +0 -809
  287. package/src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts +0 -405
  288. package/src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts +0 -56
  289. package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +0 -166
  290. package/src/orchestration/__tests__/execute-agent-call.test.ts +0 -451
  291. package/src/orchestration/__tests__/jsonl-run-store-corrupt-entry.test.ts +0 -150
  292. package/src/orchestration/__tests__/jsonl-run-store-loadall-sources.test.ts +0 -171
  293. package/src/orchestration/__tests__/jsonl-run-store-retention.test.ts +0 -202
  294. package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +0 -1030
  295. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -600
  296. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +0 -96
  297. package/src/orchestration/__tests__/lifecycle.test.ts +0 -659
  298. package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +0 -95
  299. package/src/orchestration/__tests__/review-fix-loop-e2e.test.ts +0 -2025
  300. package/src/orchestration/__tests__/script-lint.test.ts +0 -831
  301. package/src/orchestration/__tests__/skill-discovery.test.ts +0 -201
  302. package/src/orchestration/__tests__/test-mocks.ts +0 -197
  303. package/src/orchestration/__tests__/worker-exit-without-result.test.ts +0 -368
  304. package/src/orchestration/__tests__/worker-host.test.ts +0 -120
  305. package/src/orchestration/__tests__/worker-returnmeta-passthrough.test.ts +0 -164
  306. package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +0 -563
  307. package/src/orchestration/__tests__/worker-script-builder.test.ts +0 -309
  308. package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +0 -129
  309. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +0 -317
  310. package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +0 -110
  311. package/src/orchestration/__tests__/workflows-e2e.test.ts +0 -537
  312. package/src/orchestration/agent-opts-resolver.ts +0 -174
  313. package/src/orchestration/args-validator.ts +0 -127
  314. package/src/orchestration/config-loader.ts +0 -315
  315. package/src/orchestration/error-recovery.ts +0 -1018
  316. package/src/orchestration/execute-agent-call.ts +0 -256
  317. package/src/orchestration/launcher.ts +0 -455
  318. package/src/orchestration/lifecycle.ts +0 -399
  319. package/src/orchestration/models/__tests__/budget.test.ts +0 -307
  320. package/src/orchestration/models/__tests__/trace.test.ts +0 -408
  321. package/src/orchestration/models/agent-call.ts +0 -83
  322. package/src/orchestration/models/budget.ts +0 -118
  323. package/src/orchestration/models/ports.ts +0 -164
  324. package/src/orchestration/models/run-runtime.ts +0 -104
  325. package/src/orchestration/models/run-spec.ts +0 -83
  326. package/src/orchestration/models/run-state.ts +0 -44
  327. package/src/orchestration/models/trace.ts +0 -183
  328. package/src/orchestration/models/types.ts +0 -301
  329. package/src/orchestration/models/workflow-run.ts +0 -254
  330. package/src/orchestration/models/workflow-script-registry.ts +0 -35
  331. package/src/orchestration/models/workflow-script.ts +0 -117
  332. package/src/orchestration/script-lint.ts +0 -766
  333. package/src/orchestration/skill-discovery.ts +0 -115
  334. package/src/orchestration/worker-handle.ts +0 -115
  335. package/src/orchestration/worker-host.ts +0 -98
  336. package/src/orchestration/worker-script-builder.ts +0 -421
  337. package/src/orchestration/workflow-files.ts +0 -85
  338. package/src/orchestration/workflow-script-registry-impl.ts +0 -133
  339. package/src/shared/__tests__/agent-ref.test.ts +0 -34
  340. package/src/shared/__tests__/meta-parser.test.ts +0 -304
  341. package/src/shared/__tests__/model-ref.test.ts +0 -306
  342. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -280
  343. package/src/shared/__tests__/resource-discovery.test.ts +0 -736
  344. package/src/shared/__tests__/resource-meta.test.ts +0 -51
  345. package/src/shared/__tests__/schema-jsonify.test.ts +0 -81
  346. package/src/shared/__tests__/timer-delay.test.ts +0 -61
  347. package/src/shared/agent-event.ts +0 -13
  348. package/src/shared/agent-ref.ts +0 -57
  349. package/src/shared/meta-parser.ts +0 -261
  350. package/src/shared/model-ref.ts +0 -286
  351. package/src/shared/resource-discovery.ts +0 -811
  352. package/src/shared/resource-meta.ts +0 -65
  353. package/src/shared/schema-env.ts +0 -44
  354. package/src/shared/schema-jsonify.ts +0 -58
  355. package/src/shared/timer-delay.ts +0 -54
  356. package/src/shared/xml-injection.ts +0 -35
  357. package/workflows/README.md +0 -81
  358. package/workflows/_shared/agent-refs.cjs +0 -40
  359. package/workflows/chain.js +0 -131
  360. package/workflows/map-reduce.js +0 -174
  361. package/workflows/parallel.js +0 -148
  362. package/workflows/review-fix-loop-utils.cjs +0 -1309
  363. package/workflows/review-fix-loop.js +0 -1404
  364. package/workflows/scatter-gather.js +0 -178
@@ -1,10 +1,15 @@
1
1
  // src/interface/subagent-actions.ts
2
2
  //
3
- // subagent tool 的内部 handler + 唯一 adapter
3
+ // subagent tool action pi adapter 壳(sink 设计 D6② 消费收缩)。
4
4
  //
5
- // 分层(spec FR-2):
6
- // 1. startHandler / listHandler / cancelHandler —— 纯领域对象进出,不碰 {content, details}
7
- // 2. adapter(action, 领域对象) —— 唯一包装为 AgentToolResult<SubagentToolResult>
5
+ // 领域内核(入参校验 / message 拒绝文案分流 / fork-from 拒绝链 / 终态映射 /
6
+ // list 投影)已下沉 core @zhushanwen/subagent-core/execution/subagent-actions-core——
7
+ // ⛔4 行为快照等值锚定见 core __tests__/subagent-actions-core.test.ts(期望值硬编码自
8
+ // 本文件迁移前实测输出,含错误文案逐字锚)。本壳按设计仅保留三类职责:
9
+ // 1. core 调用面 re-export:六 handler + 领域类型(签名不变,消费方零改动)
10
+ // 2. 参数提取:位于 subagent-tool.ts executeSubagent(action 路由 / listParam /
11
+ // cancelParam 解包 / skillPath-cwd 路径检查),本次收缩零改动
12
+ // 3. TUI/GUI 渲染:adapter / buildGuiComponent(pi TUI 渲染族按设计留壳)
8
13
  //
9
14
  // content(JSON 字符串)给 LLM,details(SubagentToolResult)给 renderResult,同源同处生成。
10
15
 
@@ -16,456 +21,60 @@ import {
16
21
  isGuiCapable,
17
22
  } from "@xyz-agent/extension-protocol";
18
23
 
19
- import { SLUG_MAX_LENGTH } from "../execution/execute-options-mapper.ts";
20
- import { computeElapsedSeconds, projectOutcome } from "../execution/execution-record.ts";
21
- import { isResumable } from "../execution/lifecycle-predicates.ts";
22
- import type { ExecutionRecord } from "../execution/types.ts";
23
- import type { ModelInfo } from "../execution/model-resolver.ts";
24
- import type { SubagentService } from "../execution/subagent-service.ts";
25
- import { displayAgentName } from "../shared/agent-ref.ts";
24
+ import type { SubagentToolResult } from "@zhushanwen/subagent-core/execution/types.ts";
26
25
  import type {
27
- BgResponse,
28
- CancelResponse,
29
- CloseResponse,
30
- ExecutionStatus,
31
- ExternalState,
32
- ListResponse,
33
- MessageResponse,
34
- SubagentListItem,
35
- SubagentRecord,
36
- SubagentToolResult,
37
- } from "../execution/types.ts";
26
+ CancelHandlerResult,
27
+ CloseHandlerResult,
28
+ ForkFromHandlerResult,
29
+ ListHandlerResult,
30
+ MessageHandlerResult,
31
+ StartHandlerResult,
32
+ } from "@zhushanwen/subagent-core/execution/subagent-actions-core.ts";
38
33
  import { mapRunIcon, mapRunStatus } from "./gui-mappers.ts";
39
34
 
40
35
  // ============================================================
41
- // 常量
36
+ // core 领域内核 re-export(pi 消费面符号与收缩前一致,deep path 直连 core 源码)
42
37
  // ============================================================
43
38
 
44
- /** list 默认 limit。 */
45
- const DEFAULT_LIST_LIMIT = 20;
46
- /** list limit 上限。 */
47
- const MAX_LIST_LIMIT = 100;
39
+ export {
40
+ cancelHandler,
41
+ closeHandler,
42
+ endedMessageGuard,
43
+ forkFromHandler,
44
+ listHandler,
45
+ mapExternalState,
46
+ messageHandler,
47
+ recordToListItem,
48
+ startHandler,
49
+ } from "@zhushanwen/subagent-core/execution/subagent-actions-core.ts";
48
50
 
49
- /** background 启动提示文案(spec FR-3 bgResponse.message)。 */
50
- const BG_MESSAGE = "detached, will notify on completion (auto-injected message, do not poll)";
51
-
52
- /** 通知投递契约回显恒值(U1 预置,U2 账本兑现,见 BgResponse.notifyContract)。 */
53
- const NOTIFY_CONTRACT = "ledger+at-least-once" as const;
54
-
55
- /** subagentId(UUID)在 GUI header 的截断显示长度。 */
56
- const SUBAGENT_ID_PREVIEW = 8;
51
+ export type {
52
+ CancelHandlerInput,
53
+ CancelHandlerResult,
54
+ CloseHandlerInput,
55
+ CloseHandlerResult,
56
+ ForkFromHandlerInput,
57
+ ForkFromHandlerResult,
58
+ ListHandlerInput,
59
+ ListHandlerResult,
60
+ MessageHandlerInput,
61
+ MessageHandlerResult,
62
+ StartHandlerInput,
63
+ StartHandlerResult,
64
+ } from "@zhushanwen/subagent-core/execution/subagent-actions-core.ts";
57
65
 
58
66
  // ============================================================
59
- // 入参 / 出参类型
67
+ // 渲染层常量 / 类型(pi TUI 渲染族,按设计留壳)
60
68
  // ============================================================
61
69
 
62
- /** start 入参(拍平后从 tool params 顶层来,task + slug 必填)。
63
- * StartHandlerInput SubagentExecuteParams 的子集(13 字段全 optional);
64
- * 调用方传整个 params(含 action/listParam/cancelParam),多余字段被忽略。 */
65
- export interface StartHandlerInput {
66
- task?: string;
67
- /** 短标签(≤35 字符,kebab-case),必填。 */
68
- slug?: string;
69
- agent?: string;
70
- model?: string;
71
- thinkingLevel?: string;
72
- skillPath?: string;
73
- appendSystemPrompt?: string[];
74
- schema?: Record<string, unknown>;
75
- maxTurns?: number;
76
- graceTurns?: number;
77
- /** fork 模式:继承主 session 上下文(D-018 两级降级)。 */
78
- fork?: boolean;
79
- /** worktree 模式:文件系统隔离运行(D-008 tmpdir)。 */
80
- worktree?: boolean;
81
- /** 覆盖子 agent 工作目录(默认 mainCwd)。 */
82
- cwd?: string;
83
- /** 可持续对话模式(true = chatMode,轮次完成进 idle 等续聊)。 */
84
- conversation?: boolean;
85
- /**
86
- * 空闲超时毫秒数(仅 conversation 模式有意义,覆盖默认 5min)。
87
- * 显式传 0/负数 = 禁用 idle GC(不挂 timer);不传走 env/默认优先级。
88
- */
89
- idleTimeoutMs?: number;
90
- /** 执行引擎(D4 三层路由第一层:本参数 > agent frontmatter engine > config defaultEngine)。 */
91
- engine?: string;
92
- }
93
-
94
- /** start 领域对象(adapter 包成 bgResponse)。 */
95
- export type StartHandlerResult = {
96
- kind: "bg";
97
- subagentId: string;
98
- sessionFile: string | undefined;
99
- /** 短标签,来自 record(handle.details.slug)。用于 result 行展示。 */
100
- slug: string;
101
- /**
102
- * registry 全等回显(U1):handle.details.model = record.model = `${provider}/${id}`,
103
- * 源头是 resolveModel 裁决放行的条目——通过校验 = 子进程必然按此名执行。
104
- */
105
- model: string;
106
- response: BgResponse;
107
- };
108
-
109
- export interface ListHandlerInput {
110
- includeFinished?: boolean;
111
- limit?: number;
112
- }
113
-
114
- /** list 领域对象(adapter 包成 listResponse,最外层 subagentId/sessionFile 为 null)。 */
115
- export interface ListHandlerResult {
116
- response: ListResponse;
117
- }
118
-
119
- export interface CancelHandlerInput {
120
- subagentId?: string;
121
- }
122
-
123
- /** cancel 领域对象(adapter 包成 cancelResponse)。 */
124
- export interface CancelHandlerResult {
125
- subagentId: string;
126
- response: CancelResponse;
127
- }
128
-
129
- // ============================================================
130
- // helpers(模块内)
131
- // ============================================================
132
-
133
- /**
134
- * list 数据源(诚实声明 G3-003):
135
- * collectRecords(limit, statusFilter) 合并内存(running) + 磁盘(sessions/*.jsonl 重建)。
136
- * 磁盘源天然跨 session 可见——/new /resume /fork 后前 session 的终态 record 仍在
137
- * sessions 目录里(直到 30 天 GC)。内存源仅当前 session 的 running record。
138
- * 不新增 sessionId 到 ExecutionRecord(YAGNI,修跨 session 清理是独立问题)。
139
- */
70
+ /** subagentId(UUID)在 GUI header 的截断显示长度。 */
71
+ const SUBAGENT_ID_PREVIEW = 8;
140
72
 
141
- /** exhaustiveness 兜底:default 分支把 status 收敛为 never,ExecutionStatus 加态时 tsc 报错。 */
73
+ /** exhaustiveness 兜底:default 分支把 action 收敛为 never,新增 action tsc 报错。 */
142
74
  function assertNever(value: never): string {
143
75
  return String(value);
144
76
  }
145
77
 
146
- /**
147
- * 内部 ExecutionStatus → 对外 state 映射(设计决策 10 细则 3)。
148
- * v4 B-1 两态收敛后的真实映射只有两条:
149
- * running → active / closed → ended(closed 统一终态,含 cancelled)
150
- * ExternalState 仍声明 waiting/error 四态联合(对外契约不变),但当前状态机不产生
151
- * 这两个值——它们是历史多态映射(idle→waiting / failed+crashed→error)的遗留声明。
152
- * 未来内部加态必须扩展此处,漏加会在 default 分支编译报错(而非静默返回 undefined
153
- * 让 state 字段以无主值进入 listResponse JSON)。
154
- */
155
- export function mapExternalState(status: ExecutionStatus): ExternalState {
156
- switch (status) {
157
- case "running":
158
- return "active";
159
- case "closed":
160
- // v4 B-1: closed 统一终态(含 cancelled)。对外映射为 ended。
161
- return "ended";
162
- default:
163
- throw new Error(`mapExternalState: unhandled ExecutionStatus ${assertNever(status)}`);
164
- }
165
- }
166
-
167
- /** SubagentRecord → SubagentListItem(state 四态主字段 + status 调试字段,duration 实时计算)。
168
- * [v4 A-6] 新增 parent/resumable:parent 从 record.parentRecordId 派生(配合 A-5 直接父
169
- * 守卫),resumable 从 isResumable 派生(B-1「可续聊」对外表达)。
170
- * [U3 C-outcome] 新增 outcome 一等终态语义(projectOutcome 唯一出口);closedReason
171
- * 退出对外 JSON(保留为 record 内部诊断字段),对外成败判读收口到 outcome,消费方
172
- * 零手写推导(三处同构 switch 已收敛删除)。
173
- * agent 是 GUI/TUI list 共用的显示名——取 basename 短名(displayAgentName),
174
- * 完整路径保留在 record.agent(数据层)。 */
175
- export function recordToListItem(r: SubagentRecord): SubagentListItem {
176
- return {
177
- subagentId: r.id,
178
- agent: displayAgentName(r.agent),
179
- slug: r.slug,
180
- state: mapExternalState(r.status),
181
- status: r.status,
182
- mode: r.mode,
183
- duration: computeElapsedSeconds(r),
184
- model: r.model,
185
- totalTokens: r.totalTokens,
186
- sessionFile: r.sessionFile,
187
- parent: r.parentRecordId,
188
- resumable: isResumable(r),
189
- outcome: projectOutcome(r),
190
- };
191
- }
192
-
193
- // ============================================================
194
- // start handler
195
- // ============================================================
196
-
197
- export async function startHandler(
198
- service: SubagentService,
199
- input: StartHandlerInput | undefined,
200
- signal: AbortSignal | undefined,
201
- ctxModel?: ModelInfo,
202
- ): Promise<StartHandlerResult> {
203
- if (!input) throw new Error(
204
- "action:'start' requires task and slug (top-level fields). " +
205
- 'Correct: {"action":"start","task":"<your task>","slug":"<kebab-case>"}',
206
- );
207
- // task 必填 + 空白校验(G-008)
208
- const task = input.task?.trim();
209
- if (!task) throw new Error(
210
- "task is required for action:'start' (top-level field, must not be whitespace-only). " +
211
- 'Correct: {"action":"start","task":"...","slug":"..."}',
212
- );
213
- // slug 必填 + 空白校验 + 长度校验(≤ SLUG_MAX_LENGTH 字符)
214
- const slug = input.slug?.trim();
215
- if (!slug) throw new Error(
216
- "slug is required for action:'start' (top-level field, must not be whitespace-only). " +
217
- 'Correct: {"action":"start","task":"...","slug":"<kebab-case>"}',
218
- );
219
- if (slug.length > SLUG_MAX_LENGTH) throw new Error(`slug must be ≤${SLUG_MAX_LENGTH} chars (got ${slug.length}). Shorten to a kebab-case label, e.g. "fix-login", "extract-urls".`);
220
-
221
- const handle = await service.execute({
222
- task,
223
- slug,
224
- agent: input.agent,
225
- model: input.model,
226
- thinkingLevel: input.thinkingLevel,
227
- skillPath: input.skillPath,
228
- appendSystemPrompt: input.appendSystemPrompt,
229
- schema: input.schema,
230
- maxTurns: input.maxTurns,
231
- graceTurns: input.graceTurns,
232
- fork: input.fork,
233
- worktree: input.worktree,
234
- cwd: input.cwd,
235
- conversation: input.conversation,
236
- idleTimeoutMs: input.idleTimeoutMs,
237
- engine: input.engine,
238
- ctxModel,
239
- signal,
240
- // background detached 运行,完成由 notify 驱动新 turn。
241
- });
242
-
243
- return {
244
- kind: "bg",
245
- subagentId: handle.subagentId,
246
- sessionFile: handle.sessionFile,
247
- slug: handle.details.slug,
248
- // [U1] registry 全等回显:record.model 由 resolved(裁决放行条目)拼接,原样透出。
249
- model: handle.details.model,
250
- response: {
251
- status: "running",
252
- mode: "background",
253
- message: BG_MESSAGE,
254
- notifyContract: NOTIFY_CONTRACT,
255
- },
256
- };
257
- }
258
-
259
- // ============================================================
260
- // list handler
261
- // ============================================================
262
-
263
- export function listHandler(
264
- service: SubagentService,
265
- input: ListHandlerInput | undefined,
266
- ): ListHandlerResult {
267
- const includeFinished = input?.includeFinished === true;
268
- // limit 夹紧:默认 20,范围 [1, 100]
269
- const rawLimit = input?.limit ?? DEFAULT_LIST_LIMIT;
270
- const limit = Math.max(1, Math.min(rawLimit, MAX_LIST_LIMIT));
271
-
272
- // collectRecords 是 service 核心能力:statusFilter 决定 running-only 还是全部。
273
- // 防截断(先多取再过滤)已下沉到 store 层——这里直接传 limit + filter。
274
- const filter = includeFinished ? "all" : "running";
275
- const all = service.collectRecords(limit, filter);
276
- // [perf] collectRecords 磁盘源是 light(无 totalTokens/model 等):SubagentListItem 对
277
- // LLM 消费方暴露 totalTokens/model,逐项 getFullRecord 补全(per-file 缓存,仅首次
278
- // 全量解析;显式 tool 调用非渲染热路径,成本可接受)。
279
- const items: SubagentListItem[] = all.map((r) =>
280
- recordToListItem(service.getFullRecord(r.id) ?? r),
281
- );
282
- const running = items.filter((i) => i.status === "running").length;
283
-
284
- return { response: { running, items } };
285
- }
286
-
287
- // ============================================================
288
- // cancel handler
289
- // ============================================================
290
-
291
- export async function cancelHandler(
292
- service: SubagentService,
293
- input: CancelHandlerInput | undefined,
294
- ): Promise<CancelHandlerResult> {
295
- const id = input?.subagentId?.trim();
296
- if (!id) throw new Error("cancelParam.subagentId is required for action:'cancel'");
297
-
298
- // step 1: id 不存在(findRecord 只查内存 running record,不从 session.jsonl 重建)
299
- const rec = service.findRecord(id);
300
- if (!rec) {
301
- // [S-19] MF-1 全树可见后,list/completion 可能列出其他进程(父/兄弟)的 running record
302
- //(collectRecords 扫共享 sessionsDir 按 rootSessionId 过滤,跨进程互相可见),而 cancel
303
- // 只作用于本进程内存 record。区分两种失败,避免「may have finished」误导(该 record 正
304
- // 被列出且未 finished,只是不属于本进程内存)。仅文案区分,不改 cancel 作用域。
305
- const treeRec = service.collectRecords(DEFAULT_LIST_LIMIT, "all").find((r) => r.id === id);
306
- if (treeRec && treeRec.status === "running") {
307
- throw new Error(
308
- `Subagent record "${id}" is running but owned by another process in the tree ` +
309
- `(it was spawned by a different subagent process) — this process cannot cancel it; ` +
310
- `cancel only works for subagents spawned by the current process.`,
311
- );
312
- }
313
- throw new Error(`No subagent record with id "${id}". It may have finished — use action:'list' with includeFinished:true to verify.`);
314
- }
315
- // step 2: controller 检查(controller 为 undefined 表示 record 已终态或未启动)
316
- if (rec.mode !== "background") {
317
- throw new Error(`Cannot cancel subagent ${id} (unsupported mode: ${rec.mode})`);
318
- }
319
- // 对话模式 cancel = close(force:true) 别名(设计决策 5):chatMode record(running/idle)
320
- // 走 close 行为路径(idle 终态化 done;running 立即 SIGTERM cancelled),
321
- // 返回 cancel 响应(向后兼容 cancel action 的返回类型)。非 chatMode 保持现有 cancel 行为。
322
- if (rec.chatMode) {
323
- const chatRecord = service.getRecordForAction(id);
324
- await service.closeSubagent(chatRecord, true);
325
- return { subagentId: id, response: { cancelled: true } };
326
- }
327
- // step 3: service.cancel boolean(list-view 契约不变);false = 已终态(CAS 抢锁失败)。
328
- // 注意:不嵌入 rec.status——findRecord 快照可能已过期(TOCTOU:cancel 期间 detached
329
- // 路径 CAS 到 done/failed)。重新查当前状态,避免「status: running」与「already finished」矛盾。
330
- if (!service.cancel(id)) {
331
- // CAS 失败 = record 在 cancel 期间被 detached 路径 finalize(done/failed)。
332
- // re-query 查当前真实状态。终态 record 被 archive 立即移出内存,
333
- // 诚实报告 "unknown (evicted from memory)" 而非回落到可能过期的 rec.status(BL-3)。
334
- const now = service.findRecord(id);
335
- const statusDesc = now ? now.status : "unknown (evicted from memory)";
336
- throw new Error(`Subagent ${id} could not be cancelled (it likely just finished; status: ${statusDesc})`);
337
- }
338
- return { subagentId: id, response: { cancelled: true } };
339
- }
340
-
341
- // ============================================================
342
- // message handler(M2-B3 对话模式续聊/插入)
343
- // ============================================================
344
-
345
- export interface MessageHandlerInput {
346
- subagentId?: string;
347
- text?: string;
348
- interrupt?: boolean;
349
- }
350
-
351
- /** message 领域对象(adapter 包成 messageResponse)。
352
- * slug 来自 record(GUI /subagents message 通道的留痕 details 需要,设计 §3.3.3),
353
- * 避免调用方二次 getRecordForAction 查询。 */
354
- export type MessageHandlerResult = {
355
- kind: "message";
356
- subagentId: string;
357
- slug: string;
358
- response: MessageResponse;
359
- };
360
-
361
- /**
362
- * message action handler:向对话模式 subagent 续聊/插入消息。
363
- *
364
- * 状态 × interrupt 自动映射(agent 只表达意图):
365
- * running → deliverMessage 热路径(进程活:prompt + streamingBehavior,interrupt=true
366
- * 抢占 / false 排队,pi 权威裁决 busy/idle)
367
- * 进程死 → deliverMessage 冷路径(resumeRound 重开 session + prompt,interrupt 自动
368
- * 退化,agent 无感)
369
- * 终态 → throw ended(正常路径不命中——终态 record 已 archive,getRecordForAction 先 throw not found)
370
- * (旧 deliverToRunning busy 投递已删除——SP-5 upgrade 后 running 恒走 deliverMessage)
371
- *
372
- * 归属守卫(决策 3):getRecordForAction 内部校验 rootSessionId。
373
- *
374
- * @throws Error subagentId/text 缺失 / 不存在或非本 session 所有 / 已结束
375
- */
376
- export async function messageHandler(
377
- service: SubagentService,
378
- input: MessageHandlerInput | undefined,
379
- ): Promise<MessageHandlerResult> {
380
- const id = input?.subagentId?.trim();
381
- if (!id) throw new Error("messageParam.subagentId is required for action:'message'");
382
- const text = input?.text?.trim();
383
- if (!text) throw new Error(
384
- "messageParam.text is required for action:'message' (must not be whitespace-only). " +
385
- 'Correct: {"action":"message","messageParam":{"subagentId":"sa-...","text":"your follow-up"}}',
386
- );
387
- const interrupt = input?.interrupt === true;
388
-
389
- // 归属守卫(决策 3):getRecordForAction 内部校验 rootSessionId
390
- const record = service.getRecordForAction(id);
391
-
392
- // SP-5 one-shot upgrade:非 chatMode 的 active record(running/idle)收到 message 时
393
- // 自动升级为 chatMode,后续走 deliverMessage 统一投递路径(热路径或冷路径 resume)。
394
- // closed/cancelled 终态 record 不可 upgrade(getRecordForAction 已抛 not found)。
395
- // chatMode 是 ExecutionRecord 的 readonly 字段,用 Mutable<T> 显式断言绕过 readonly 约束(upgrade 语义)。
396
- // Object.assign 隐式绕过 readonly 不可追踪,改为单字段显式赋值。
397
- // [v4 A-3] 进程内 upgrade 入口(SP-5)——one-shot 首条 message 触发 upgrade 置位
398
- // chatMode=true。与 subagent-service.ts getRecordForAction 磁盘重建(跨重启恢复入口)
399
- // 分工:本入口服务进程内 one-shot,跨重启路径恒被 getRecordForAction 磁盘重建绕过
400
- // (该处无条件 chatMode=true)。改动这两处必须协同,带 S3 回归。
401
- if (!record.chatMode && record.status === "running") {
402
- type Mutable<T> = { -readonly [K in keyof T]: T[K] };
403
- (record as Mutable<ExecutionRecord>).chatMode = true;
404
- }
405
-
406
- // [V2 决策 3] chatMode 统一投递:按进程死活分流(热路径 prompt+streamingBehavior / 冷路径 resume),
407
- // 不按 record.status(V2 进程长驻,idle 态进程仍活,续聊走热路径 prompt 而非重开 session)。
408
- // SP-5:upgrade 后 record.chatMode 已为 true,统一进此分支。
409
- if (record.chatMode) {
410
- await service.deliverMessage(record, text, interrupt);
411
- } else {
412
- // 终态(closed/cancelled):防御性兜底(终态 record 已 archive,正常走 not found)
413
- throw new Error(
414
- `subagent ${id} has ended (status: ${record.status}), cannot message. ` +
415
- `Recovery: use action:'close' to clean up, then action:'start' a new subagent.`,
416
- );
417
- }
418
- return { kind: "message", subagentId: id, slug: record.slug, response: { delivered: true } };
419
- }
420
-
421
- // ============================================================
422
- // close handler(M2-B3 对话模式结束)
423
- // ============================================================
424
-
425
- export interface CloseHandlerInput {
426
- subagentId?: string;
427
- force?: boolean;
428
- }
429
-
430
- /** close 领域对象(adapter 包成 closeResponse)。 */
431
- export type CloseHandlerResult = {
432
- kind: "close";
433
- subagentId: string;
434
- response: CloseResponse;
435
- };
436
-
437
- /**
438
- * close action handler:结束 subagent(对话模式为主,one-shot 同样支持)。
439
- *
440
- * force 语义(设计决策 5/10,v4 B-1 两态收敛 + M5 修正):
441
- * force:false(默认)= 优雅关闭——
442
- * 无在跑轮(等待续聊 timer armed / 无活进程)→ 立即终态化(closed + user-close,回收保活进程)
443
- * 有活进程在跑轮 → 置 closeAfterRound,轮完成时终态化(chatMode 消费点 onRoundSettled,
444
- * one-shot 在 runAndFinalize 轮完成分支)——返回 {closed:true} 即承诺轮结束后资源已释放
445
- * force:true = 立即终止——running 立即 SIGTERM(cancelBackground 显式 kill)+ closed+cancelled
446
- *
447
- * 行为分流委托 service.closeSubagent(归属守卫由 getRecordForAction 把关)。
448
- * 已终态 record 由 getRecordForAction throw not found(「已结束的不能再操作」语义)。
449
- */
450
- export async function closeHandler(
451
- service: SubagentService,
452
- input: CloseHandlerInput | undefined,
453
- ): Promise<CloseHandlerResult> {
454
- const id = input?.subagentId?.trim();
455
- if (!id) throw new Error("closeParam.subagentId is required for action:'close'");
456
- const force = input?.force === true;
457
-
458
- // 归属守卫(决策 3)+ 行为分流(service.closeSubagent)
459
- const record = service.getRecordForAction(id);
460
- await service.closeSubagent(record, force);
461
-
462
- return { kind: "close", subagentId: id, response: { closed: true } };
463
- }
464
-
465
- // ============================================================
466
- // adapter(领域对象 → SubagentToolResult + {content, details})
467
- // ============================================================
468
-
469
78
  /**
470
79
  * action ↔ domain 配对的承重类型(替代三处松散 `as`)。
471
80
  * 调用方必须传匹配的 {action, domain}——TS 在调用点校验,错配编译报错。
@@ -475,7 +84,12 @@ type AdapterInput =
475
84
  | { action: "list"; domain: ListHandlerResult }
476
85
  | { action: "cancel"; domain: CancelHandlerResult }
477
86
  | { action: "message"; domain: MessageHandlerResult }
478
- | { action: "close"; domain: CloseHandlerResult };
87
+ | { action: "close"; domain: CloseHandlerResult }
88
+ | { action: "fork-from"; domain: ForkFromHandlerResult };
89
+
90
+ // ============================================================
91
+ // adapter(领域对象 → SubagentToolResult + {content, details})
92
+ // ============================================================
479
93
 
480
94
  export function adapter(
481
95
  input: AdapterInput,
@@ -495,6 +109,11 @@ export function adapter(
495
109
  result = { action, subagentId: input.domain.subagentId, sessionFile: null, cancelResponse: input.domain.response };
496
110
  } else if (action === "message") {
497
111
  result = { action, subagentId: input.domain.subagentId, sessionFile: null, messageResponse: input.domain.response };
112
+ } else if (action === "fork-from") {
113
+ // MF-3 同款瘦身:sourceSessionFile 真实路径只在 forkFromResponse 内层(LLM 接续
114
+ // 不需要拼路径,需要时 list/details 可取);顶层 sessionFile 保持 null 一致性。
115
+ const d = input.domain;
116
+ result = { action, subagentId: d.subagentId, sessionFile: null, forkFromResponse: d.response };
498
117
  } else {
499
118
  // action === "close"
500
119
  result = { action, subagentId: input.domain.subagentId, sessionFile: null, closeResponse: input.domain.response };
@@ -565,6 +184,14 @@ export function buildGuiComponent(
565
184
  items: [{ label: "messaged", value: input.domain.subagentId, severity: "ok" }],
566
185
  });
567
186
  }
187
+ if (action === "fork-from") {
188
+ return guiComponent("stats-line", {
189
+ items: [
190
+ { label: "forked-from", value: input.domain.sourceSessionFile },
191
+ { label: "new subagent", value: input.domain.subagentId, severity: "ok" },
192
+ ],
193
+ });
194
+ }
568
195
  if (action === "close") {
569
196
  return guiComponent("stats-line", {
570
197
  items: [{ label: "closed", value: input.domain.subagentId, severity: "warn" }],
@@ -12,22 +12,18 @@
12
12
  // 编译本 schema 并断言 required/description/enum/pattern 存活——SW 自身测试环境
13
13
  // 把 typebox alias 到 mock(丢 options),SO 侧测试以真实构造为对照基准。
14
14
  //
15
- // 层归属:Interface(工具 schema 的家)。SLUG_MAX_LENGTH schema 迁入:
16
- // 它的唯一语义就是 tool schema 的 maxLength(见原 execute-options-mapper 注释),
17
- // execution 侧经 re-export 保持既有 import 路径不变。
15
+ // 层归属:Interface(工具 schema 的家)。SLUG_MAX_LENGTH 权威定义回归 core
16
+ // execution/execute-options-mapper.ts(subagent-core 包抽离 u1-move:core 切面不得
17
+ // 反向 import 壳侧 interface,常量随之内化)——此处 re-export 保持既有 import 路径。
18
18
 
19
19
  import { StringEnum } from "@earendil-works/pi-ai";
20
- import { type Static, Type } from "typebox";
20
+ import { Type } from "typebox";
21
21
 
22
- import { THINKING_ORDER } from "../shared/model-ref.ts";
22
+ import { THINKING_ORDER } from "@zhushanwen/subagent-core/shared/model-ref.ts";
23
23
 
24
- /**
25
- * slug 最大长度(字符)。subagent/workflow 创建时 slug 超过此值会被截断。
26
- * subagent/workflow tool schema 的 maxLength 引用此常量(单一真相,勿再硬编码)。
27
- * 历史值 20 偏紧——描述性 slug 如 "audit-structured-output"(23)/"fix-subagent-wf-tools"(21)
28
- * 会撞上限,放宽到 35 兼顾「短到能塞进 TUI 标题行」与「容纳合理描述性 kebab-case 名」。
29
- */
30
- export const SLUG_MAX_LENGTH = 35;
24
+ import { SLUG_MAX_LENGTH } from "@zhushanwen/subagent-core/execution/execute-options-mapper.ts";
25
+
26
+ export { SLUG_MAX_LENGTH };
31
27
 
32
28
  // Params schema(跨包契约测试的真实 typebox 校验入口)。
33
29
  //
@@ -42,8 +38,8 @@ export const SLUG_MAX_LENGTH = 35;
42
38
  // (subagent_start / subagent_list / subagent_cancel),让每个 tool 的 schema 真实
43
39
  // 反映必填性。勿在此基础上继续堆 action 条件逻辑——要加就拆 tool。
44
40
  export const SubagentParams = Type.Object({
45
- action: StringEnum(["start", "list", "cancel", "message", "close"], {
46
- description: "Operation: 'start' runs a subagent, 'list' shows subagents, 'cancel' stops a background subagent, 'message' sends a follow-up to a running subagent (one-shot subagents are auto-upgraded to conversation mode on first message), 'close' ends a running subagent (conversation-mode or one-shot).",
41
+ action: StringEnum(["start", "list", "cancel", "message", "close", "fork-from"], {
42
+ description: "Operation: 'start' runs a subagent, 'list' shows subagents, 'cancel' stops a background subagent, 'message' sends a follow-up to a running subagent (one-shot subagents are auto-upgraded to conversation mode on first message), 'close' ends a running subagent (conversation-mode or one-shot), 'fork-from' spawns a NEW subagent inheriting an older one's history (recovery for restart-disconnected subagents; the old record is untouched).",
47
43
  }),
48
44
  // ── action:"start" fields (flattened to top level). task/slug REQUIRED for start. ──
49
45
  // Missing/empty task or slug throws at runtime (startHandler).
@@ -150,7 +146,15 @@ export const SubagentParams = Type.Object({
150
146
  description: "If true, terminate immediately even if mid-round (in-progress work is lost). If false (default), let the current round finish, then close. When idle, the subagent closes immediately regardless.",
151
147
  })),
152
148
  })),
149
+ // action:"fork-from" → forkFromParam.sourceSubagentId REQUIRED ([v8.5 B] 断联恢复通道).
150
+ // 从旧 subagent 的会话历史 spawn 新 id:新进程 --fork 指向旧 session 文件(copy-on-write,
151
+ // 源文件只读不续写);旧记录/状态机不动。pi 引擎限定(非 pi 在 execute 层拒绝)。
152
+ forkFromParam: Type.Optional(Type.Object({
153
+ sourceSubagentId: Type.String({
154
+ description: "REQUIRED for action:'fork-from'. The OLD subagentId whose conversation history becomes the inherited context of the new subagent. Works for records disconnected by a session restart or already finished; cancelled/worktree-bound/still-running ones are rejected with guidance.",
155
+ }),
156
+ prompt: Type.Optional(Type.String({
157
+ description: "Continuation instruction for the new subagent (what to do next on top of the inherited history). When omitted, a standard handover frame is injected: reconstruct done/decided/remaining from the inherited history, then continue to completion. Whitespace-only treated as omitted.",
158
+ })),
159
+ })),
153
160
  });
154
-
155
- /** Params schema 的 Static 投影(消费方经 `Static<typeof SubagentParams>` 使用,见 subagent-tool.ts)。 */
156
- export type SubagentParamsStatic = Static<typeof SubagentParams>;