@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,199 +0,0 @@
1
- // src/execution/agent-registry.ts
2
- //
3
- // agent .md 文件发现与解析。
4
- //
5
- // 发现逻辑统一走 shared/resource-discovery(ADR-031),与 workflow 共享同一套
6
- // 扫描源前缀 + manifest 校验。hot-reload:每次调用重扫(mtime 缓存跳过未变文件)。
7
- //
8
- // builtin agent(包内 agents/*.md)走 pi.agents manifest(与 npm 包内发现规则一致)。
9
-
10
-
11
- import * as path from "node:path";
12
-
13
- import { getLogger } from "@zhushanwen/pi-extension-logger";
14
-
15
- import {
16
- getCachedFile,
17
- } from "../shared/resource-discovery.ts";
18
- import { normalizeRef, AGENT_REF_EXT } from "../shared/agent-ref.ts";
19
- import { parseResourceMeta } from "../shared/meta-parser.ts";
20
- import { lintAgentMeta } from "../orchestration/script-lint.ts";
21
- import type { AgentMeta } from "../shared/resource-meta.ts";
22
- import type { AgentConfig } from "./model-resolver.ts";
23
- import { hasEngine, listEngines, EngineNotFoundError } from "./engine/registry.ts";
24
-
25
- const logger = getLogger("subagents");
26
-
27
- /** mtime 缓存条目(跨 loadByPath 保留,靠 mtime 判失效)。 */
28
- interface FileCacheEntry {
29
- mtimeMs: number;
30
- config: AgentConfig;
31
- /** AgentMeta(W4 lint 用——cache-miss 时 lint 一次,warn 随 mtime 变化刷)。 */
32
- meta: AgentMeta | null;
33
- }
34
-
35
- // ============================================================
36
- // frontmatter 解析
37
- // ============================================================
38
-
39
- /** frontmatter 分隔符。 */
40
- const FM_DELIM = "---";
41
-
42
- /**
43
- * 解析 .md frontmatter(name/tools/model/thinkingLevel/defaultBackground)+ body(systemPrompt)。
44
- * 兼容简单 YAML(key: value 单行格式)。body 作为 systemPrompt。
45
- */
46
- export function parseAgentFrontmatter(filePath: string, content: string): AgentConfig {
47
- return parseAgentWithMeta(filePath, content).config;
48
- }
49
-
50
- /**
51
- * 解析 agent .md → { config, meta } 二元组(m5 T2:W4 lint 需要 AgentMeta——
52
- * AgentConfig 投影时 examples 被丢弃,meta 供 lintAgentMeta 使用)。
53
- */
54
- export function parseAgentWithMeta(
55
- filePath: string,
56
- content: string,
57
- ): { config: AgentConfig; meta: AgentMeta | null } {
58
- const name = path.basename(filePath, ".md");
59
-
60
- // 无 frontmatter → 整个内容作为 systemPrompt
61
- if (!content.startsWith(FM_DELIM)) {
62
- return { config: { name, systemPrompt: content.trim() }, meta: null };
63
- }
64
-
65
- const closeIdx = content.indexOf(FM_DELIM, FM_DELIM.length);
66
- if (closeIdx === -1) {
67
- // 未闭合 frontmatter:提取 name,其余作为 systemPrompt
68
- const yamlBlock = content.slice(FM_DELIM.length);
69
- return {
70
- config: {
71
- name: extractYamlField(yamlBlock, "name") ?? name,
72
- systemPrompt: content.trim(),
73
- },
74
- meta: null,
75
- };
76
- }
77
-
78
- const yamlBlock = content.slice(FM_DELIM.length, closeIdx);
79
- const body = content.slice(closeIdx + FM_DELIM.length).trim();
80
-
81
- // m2:结构化路由字段(name/model/tools)经 IF1 parseResourceMeta(统一 parser),
82
- // 消灭本地 frontmatter parser 与 subagent-list-injector 的重复。thinkingLevel/defaultBackground
83
- // 是执行配置(非 AgentMeta 路由字段),仍用 extractYamlField 取。
84
- const meta = parseResourceMeta(content, "agent");
85
- const agentMeta = meta?.kind === "agent" ? meta : null;
86
- // MF-3 regression fix:agentMeta=null(IF1 要求 name/description 必填,缺则 parseResourceMeta
87
- // 返 null)时,model/tools 不能静默丢失——fallback 用 extractYamlField 取(保留重构前行为)。
88
- // 注入路由可见性由 discovery/injector 按 available 标志决定,与本处(direct-path loadByPath)无关。
89
- const modelFallback = extractYamlField(yamlBlock, "model");
90
- const toolsFallbackRaw = extractYamlField(yamlBlock, "tools");
91
- const toolsFallback = toolsFallbackRaw
92
- ? toolsFallbackRaw.split(",").map((s) => s.trim()).filter(Boolean)
93
- : undefined;
94
- if (!agentMeta && /^model:|^tools:/m.test(yamlBlock)) {
95
- // m2 exec-review MINOR-2 + MF-3:IF1 未通过(缺 name/description)→ model/tools 经 legacy
96
- // fallback 取(direct-path loadByPath 不丢配置,与重构前一致);但结构化路由注入不可见,
97
- // 建议 agent 作者补 description 以满足 IF1。
98
- logger.warn(
99
- `[agent-registry] ${filePath}: agent frontmatter 缺 name/description(IF1 必填),` +
100
- "model/tools 经 legacy fallback 生效(直接路径不丢配置),但结构化路由不可见——请补充 description",
101
- );
102
- }
103
- const defaultBackgroundRaw = extractYamlField(yamlBlock, "defaultBackground");
104
- // engine 字段(D9):结构化优先(IF1),legacy fallback 与 model/tools 同判——
105
- // agentMeta 未通过 IF1 时配置不丢
106
- const engine = agentMeta?.engine ?? extractYamlField(yamlBlock, "engine");
107
- // 解析期校验(D9:未注册 id 前置暴露,不留到运行时神秘失败)。为什么在解析期而非
108
- // 路由期:配置错误的根源在 .md 文件,越早报错定位越准(错误含文件路径 + 注册清单)
109
- if (engine !== undefined && !hasEngine(engine)) {
110
- throw new EngineNotFoundError(engine, listEngines(), filePath);
111
- }
112
-
113
- return {
114
- config: {
115
- name: agentMeta?.name ?? name,
116
- systemPrompt: body,
117
- model: agentMeta?.model ?? modelFallback ?? undefined,
118
- thinkingLevel: extractYamlField(yamlBlock, "thinkingLevel") ?? undefined,
119
- ...(engine !== undefined ? { engine } : {}),
120
- tools: agentMeta?.tools && agentMeta.tools.length > 0
121
- ? agentMeta.tools
122
- : (toolsFallback && toolsFallback.length > 0 ? toolsFallback : undefined),
123
- defaultBackground: defaultBackgroundRaw === "true" ? true : undefined,
124
- },
125
- meta: agentMeta,
126
- };
127
- }
128
-
129
- /** 提取简单 `key: value` 字段,剥离引号。 */
130
- function extractYamlField(yaml: string, key: string): string | undefined {
131
- const regex = new RegExp(`^${key}:\\s*(.+)$`, "m");
132
- const match = yaml.match(regex);
133
- if (!match) return undefined;
134
- let value = match[1].trim();
135
- if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
136
- value = value.slice(1, -1);
137
- }
138
- return value || undefined;
139
- }
140
-
141
- // ============================================================
142
- // AgentRegistry
143
- // ============================================================
144
-
145
- export class AgentRegistry {
146
- /** 文件级 mtime 缓存(key=绝对路径,跨 loadByPath 保留)。 */
147
- private readonly fileCache = new Map<string, FileCacheEntry>();
148
-
149
- /**
150
- * 按绝对路径加载 agent(agentRef 统一解析入口——S2 路径统一)。
151
- *
152
- * - ~/ 前缀展开;相对路径/非 .md 引用返回 undefined(引用唯一形态 = 绝对路径)
153
- * - 文件不可读/不存在 → 驱逐缓存 + 返回 undefined(调用方给错误指引)
154
- * - mtime 未变复用 config 缓存;cache-miss 时 W4 lint 一次
155
- *
156
- * require 语义:require:true 时上述两类失败改为 throw(错误文案含
157
- * <available_subagents> 恢复指引),供「用户显式点名 agent」的调用点使用——
158
- * 显式 ref 失败是配置错误,必须显式报错而非静默降级(三通道对称审查)。
159
- */
160
- loadByPath(ref: string, require: true): AgentConfig;
161
- loadByPath(ref: string, require?: boolean): AgentConfig | undefined;
162
- loadByPath(ref: string, require?: boolean): AgentConfig | undefined {
163
- const filePath = normalizeRef(ref, AGENT_REF_EXT);
164
- if (filePath === null) {
165
- if (require) {
166
- throw new Error(
167
- `Invalid agent ref: ${ref}. Agent refs must be absolute paths to .md files (use <location> from <available_subagents>).`,
168
- );
169
- }
170
- return undefined;
171
- }
172
-
173
- const file = getCachedFile(filePath);
174
- if (file === null) {
175
- // ENOENT/不可读 → 驱逐(mtime 缓存下文件删除不自愈的修复)
176
- this.fileCache.delete(filePath);
177
- if (require) {
178
- throw new Error(
179
- `Agent file not found or unreadable: ${filePath}. Use an absolute path from <available_subagents> <location>.`,
180
- );
181
- }
182
- return undefined;
183
- }
184
-
185
- const cached = this.fileCache.get(filePath);
186
- if (cached && cached.mtimeMs === file.mtimeMs) {
187
- return cached.config;
188
- }
189
-
190
- const { config, meta } = parseAgentWithMeta(filePath, file.content);
191
- // W4 lint:cache-miss(parse 时一次)——warn 只随 mtime 变化刷
192
- const lintFindings = meta ? lintAgentMeta(meta) : [];
193
- for (const finding of lintFindings) {
194
- logger.warn(`[agent-registry] ${filePath}: ${finding.message}`);
195
- }
196
- this.fileCache.set(filePath, { mtimeMs: file.mtimeMs, config, meta });
197
- return config;
198
- }
199
- }
@@ -1,90 +0,0 @@
1
- // src/execution/agent-result-mapper.ts
2
- //
3
- // D-A10: subagents AgentResult → workflow AgentResult 映射。
4
- // 纯 DTO 映射函数——executeAndAwait 出口调,SAR 不感知形状差异。
5
- //
6
- // 接线层级:[模块内直调] —— SubagentService.executeAndAwait 出口调。
7
-
8
- import type { AgentResult as WorkflowAgentResult, AgentUsage as WorkflowAgentUsage, ToolCallEntry } from "../orchestration/models/types.ts";
9
- import type { AgentResult as SubagentsAgentResult, AgentUsageTotal, ToolCall } from "./types.ts";
10
-
11
- /** safeStringify 的 JSON 截断长度(字符),防大对象拼进 toolCalls 挤爆 trace。 */
12
- const TOOL_ARGS_JSON_MAX_CHARS = 500;
13
-
14
- /**
15
- * D-A10: subagents AgentResult → workflow AgentResult 映射。
16
- *
17
- * 字段映射表:
18
- * subagents → workflow
19
- * ─────────────────────────────────────────────
20
- * text → content
21
- * parsedOutput → parsedOutput(structured-output 契约,BC-8)
22
- * !success && error → error(失败时填,成功时 undefined)
23
- * !success && !error → error fallback(abort 路径:session-runner 设 success=false,error=undefined,
24
- * 若直接透传 undefined 则 executeAgentCall 的 `error===undefined` 误判 completed。H4 修复:synthesize fallback)
25
- * durationMs → durationMs
26
- * sessionId → sessionId
27
- * usage (AgentUsageTotal) → usage (AgentUsage: input/output/cacheRead/cacheWrite/cost/contextTokens/turns)
28
- * toolCalls (ToolCall[]) → toolCalls (ToolCallEntry[]: name/input)
29
- *
30
- * @param r subagents 管道产出的 AgentResult(runSpawn/collectResult 出口形状)
31
- * @returns workflow 编排层消费的 AgentResult(executeAgentCall/finalizeCall 入参形状)
32
- */
33
- export function mapToWorkflowAgentResult(
34
- r: SubagentsAgentResult,
35
- ): WorkflowAgentResult {
36
- return {
37
- content: r.text,
38
- parsedOutput: r.parsedOutput,
39
- error: r.success ? undefined : (r.error || "Agent call failed (aborted or unknown error)"),
40
- durationMs: r.durationMs,
41
- sessionId: r.sessionId,
42
- sessionFile: r.sessionFile,
43
- usage: r.usage ? mapUsage(r.usage, r.turns) : undefined,
44
- toolCalls: r.toolCalls ? mapToolCalls(r.toolCalls) : undefined,
45
- };
46
- }
47
-
48
- /**
49
- * AgentUsageTotal(subagents)→ AgentUsage(workflow)映射。
50
- *
51
- * subagents AgentUsageTotal: { input, output, cacheRead, cacheWrite, total, cost }
52
- * workflow AgentUsage: { input, output, cacheRead, cacheWrite, cost, contextTokens, turns }
53
- *
54
- * contextTokens ≈ total(subagents 的四项之和,近似上下文 token 量)。
55
- * turns 来自 AgentResult.turns(非 usage 内字段)。
56
- */
57
- function mapUsage(u: AgentUsageTotal, turns: number): WorkflowAgentUsage {
58
- return {
59
- input: u.input,
60
- output: u.output,
61
- cacheRead: u.cacheRead,
62
- cacheWrite: u.cacheWrite,
63
- cost: u.cost,
64
- contextTokens: u.total,
65
- turns,
66
- };
67
- }
68
-
69
- /**
70
- * ToolCall(subagents)→ ToolCallEntry(workflow)映射。
71
- *
72
- * subagents ToolCall: { toolName, args?, result?, isError? }
73
- * workflow ToolCallEntry: { name, input }
74
- */
75
- function mapToolCalls(calls: ToolCall[]): ToolCallEntry[] {
76
- return calls.map((c) => ({
77
- name: c.toolName,
78
- input: c.args === undefined ? "" : safeStringify(c.args),
79
- }));
80
- }
81
-
82
- /** 安全序列化(args 可能含循环引用或大对象,截断防 OOM)。 */
83
- function safeStringify(value: unknown): string {
84
- try {
85
- const s = JSON.stringify(value);
86
- return s.length > TOOL_ARGS_JSON_MAX_CHARS ? `${s.slice(0, TOOL_ARGS_JSON_MAX_CHARS)}...` : s;
87
- } catch {
88
- return String(value);
89
- }
90
- }
@@ -1,92 +0,0 @@
1
- // src/runtime/execution/alive-store.ts
2
- //
3
- // .alive sidecar 生产者 + pid 探活。
4
- //
5
- // 子进程启动时写 .alive(pid+id+startedAt),心跳检测时读它 + isProcessAlive
6
- // 判活。finalize/cancel 收尾时 remove。与 .cancelled/.finalized 构成三件套。
7
- //
8
- // 设计对齐 tombstone-store:单文件 sidecar、best-effort I/O、无全局 index。
9
-
10
- import * as fs from "node:fs";
11
-
12
- import type { AliveMarker } from "./types.ts";
13
-
14
- // ============================================================
15
- // 公开函数
16
- // ============================================================
17
-
18
- /**
19
- * 在 sessionFile 旁写 .alive sidecar(单行 JSON)。
20
- * 覆盖写——同一 sessionFile 只有最后一个 alive marker 有意义。
21
- */
22
- export function writeAliveMarker(sessionFile: string, marker: AliveMarker): void {
23
- const alivePath = `${sessionFile}.alive`;
24
- fs.writeFileSync(alivePath, `${JSON.stringify(marker)}\n`, "utf-8");
25
- }
26
-
27
- /**
28
- * 读 sessionFile 旁的 .alive sidecar。
29
- * 返回 undefined:不存在 / 损坏 / 解析失败。
30
- */
31
- export function readAliveMarker(sessionFile: string): AliveMarker | undefined {
32
- let raw: string;
33
- try {
34
- raw = fs.readFileSync(`${sessionFile}.alive`, "utf-8");
35
- } catch {
36
- return undefined;
37
- }
38
- try {
39
- const parsed = JSON.parse(raw) as Partial<AliveMarker>;
40
- if (
41
- typeof parsed.pid === "number" &&
42
- typeof parsed.id === "string" &&
43
- typeof parsed.startedAt === "number"
44
- ) {
45
- return parsed as AliveMarker;
46
- }
47
- return undefined;
48
- } catch {
49
- return undefined;
50
- }
51
- }
52
-
53
- /**
54
- * 删除 sessionFile 旁的 .alive sidecar。
55
- * best-effort:不存在不抛(finalize/cancel 收尾调,sidecar 可能已被清理)。
56
- */
57
- export function removeAliveMarker(sessionFile: string): void {
58
- try {
59
- fs.unlinkSync(`${sessionFile}.alive`);
60
- } catch {
61
- void 0; // best-effort
62
- }
63
- }
64
-
65
- /**
66
- * 检测 pid 是否存活。
67
- *
68
- * process.kill(pid, 0) 语义:不发信号,仅检查进程是否存在。
69
- * - 无异常 → 存活
70
- * - ESRCH(No such process)→ 死
71
- * - EPERM(Process exists but no permission)→ 存活(保守)
72
- * - 其他异常 → 保守判死 false,避免误删活进程
73
- */
74
- export function isProcessAlive(pid: number): boolean {
75
- try {
76
- process.kill(pid, 0);
77
- return true;
78
- } catch (err: unknown) {
79
- if (isErrnoException(err) && err.code === "EPERM") {
80
- return true; // 存在但无权限发信号 → 判活
81
- }
82
- return false; // ESRCH 或其他异常 → 保守判死
83
- }
84
- }
85
-
86
- // ============================================================
87
- // 内部工具
88
- // ============================================================
89
-
90
- function isErrnoException(err: unknown): err is NodeJS.ErrnoException {
91
- return err instanceof Error && "code" in err;
92
- }
@@ -1,113 +0,0 @@
1
- /**
2
- * 从主进程 argv 解析可镜像给子进程的 flag。
3
- *
4
- * 独立模块:argv 解析是独立职责,从 session-runner.ts 拆出避免该文件超行数上限。
5
- */
6
-
7
- /**
8
- * 镜像 flag 集合:从主进程 argv 解析出的可透传给子进程的 flag。
9
- * 面向 buildSpawnArgs 的入参形态(解析后)。undefined 字段语义与解析为空一致。
10
- */
11
- export interface MirrorFlags {
12
- noExtensions: boolean;
13
- approve: boolean;
14
- extensionPaths: string[];
15
- noContextFiles: boolean;
16
- }
17
-
18
- /**
19
- * 有值 flag 的解析规则表:成员是「后跟一个值」的 flag 名(含长短形式)。
20
- * 用于 mirrorMainProcessFlags 跳过其他 flag 的值时不误吃。
21
- */
22
- const VALUED_FLAGS = new Set<string>([
23
- "--extension", "-e",
24
- "--skill",
25
- "--model", "--system-prompt", "--append-system-prompt",
26
- "--tools", "-t", "--exclude-tools", "-xt",
27
- "--fork", "--session-dir", "--mode",
28
- "--thinking", "--models",
29
- ]);
30
-
31
- /** argv 中 flag 的起始索引:argv[0]=runtime, argv[1]=binary 路径。 */
32
- const ARGV_FLAG_START = 2;
33
-
34
- /**
35
- * 从主进程 argv 解析可镜像的 flag(--no-extensions/--approve/--extension/--no-context-files)。
36
- *
37
- * 数据源是主 pi 进程的 process.argv:子进程 spawn 的父就是主进程,
38
- * 主进程 argv 完整保留启动时收到的全部 flag(已运行时验证)。这让子进程
39
- * extension/approve 加载行为与主进程一致,且对任意 pi 宿主通用(不止 xyz-agent)。
40
- *
41
- * 解析规则:
42
- * - --no-extensions / -ne、--approve / -a:布尔 flag
43
- * - --no-context-files / -nc:布尔 flag(镜像理由:--extension 镜像会把
44
- * @zhushanwen/pi-system-prompt 带进每个 subagent,该扩展靠子进程自己的
45
- * argv 检测此 flag 决定是否注入全局 AGENTS.md——不镜像则用户 opt-out
46
- * 在 subagent 路径失效)
47
- * - --extension / -e:支持 `--extension <path>`(空格)与 `--extension=<path>`(等号)
48
- * - 其他 flag(在 VALUED_FLAGS 中)的值不被误当 extension 路径
49
- * - positional 参数被忽略
50
- * - argv[0]/argv[1] 是 bun/pi binary 路径,从 argv[2:] 开始扫
51
- */
52
- // [perf] 进程内 process.argv 引用恒定(唯一调用点 session-runner 每次 spawn 传同一引用),
53
- // 解析结果按 argv 引用相等 memo——每次 spawn 免重复扫描/正则。测试传新数组引用不命中。
54
- let memoArgv: readonly string[] | undefined;
55
- let memoResult: MirrorFlags | undefined;
56
-
57
- export function mirrorMainProcessFlags(argv: readonly string[]): MirrorFlags {
58
- if (memoResult !== undefined && memoArgv === argv) return memoResult;
59
- let hasNoExtensions = false;
60
- let hasApprove = false;
61
- let hasNoContextFiles = false;
62
- const extensionPaths: string[] = [];
63
-
64
- // argv[0]=runtime(bun), argv[1]=pi binary 路径;flag 从 argv[2] 起
65
- const flagArgs = argv.length > ARGV_FLAG_START ? argv.slice(ARGV_FLAG_START) : [];
66
-
67
- for (let i = 0; i < flagArgs.length; i++) {
68
- const tok = flagArgs[i];
69
- if (tok === "--no-extensions" || tok === "-ne") {
70
- hasNoExtensions = true;
71
- continue;
72
- }
73
- if (tok === "--approve" || tok === "-a") {
74
- hasApprove = true;
75
- continue;
76
- }
77
- if (tok === "--no-context-files" || tok === "-nc") {
78
- hasNoContextFiles = true;
79
- continue;
80
- }
81
- // 等号形式 --extension=path / -e=path
82
- const eqMatch = /^(--extension|-e)=(.*)$/.exec(tok);
83
- if (eqMatch) {
84
- const val = eqMatch[2];
85
- if (val) extensionPaths.push(val);
86
- continue;
87
- }
88
- // 空格形式 --extension <path> / -e <path>:值在下一个 token
89
- // [MF-7a] flag 判定收窄为 startsWith("--"):守卫原为 !startsWith("-"),把以单个
90
- // - 开头的合法路径(如相对路径 -weird-dir/x.md)误判为 flag 跳过——extension 路径
91
- // 静默丢失。pi CLI 的多字符长 flag 一律 -- 前缀,单 - 只接单字符短 flag(-e 本身),
92
- // 故「-- 开头才算 flag」不误吃真 flag 且放行 - 开头路径。
93
- if (tok === "--extension" || tok === "-e") {
94
- const next = flagArgs[i + 1];
95
- if (next !== undefined && !next.startsWith("--") && next.length > 0) {
96
- extensionPaths.push(next);
97
- i++; // 跳过值
98
- }
99
- continue;
100
- }
101
- // 其他有值 flag:跳过其值,避免误吃(如 --skill /a 的 /a)
102
- if (VALUED_FLAGS.has(tok)) {
103
- i++;
104
- continue;
105
- }
106
- // 其他情况(未知 flag、--flag=val 形式、positional)忽略
107
- }
108
-
109
- const result = { noExtensions: hasNoExtensions, approve: hasApprove, extensionPaths, noContextFiles: hasNoContextFiles };
110
- memoArgv = argv;
111
- memoResult = result;
112
- return result;
113
- }
@@ -1,38 +0,0 @@
1
- // src/utils/best-effort.ts
2
- //
3
- // best-effort IO 清理的错误吞咽 helper。
4
- //
5
- // 用途:sidecar 写入 / worktree remove / alive marker 删除等次要 IO,失败不影响
6
- // 主流程(session 已完成或正在收尾)。这类 catch 故意吞错——但 taste/no-silent-catch
7
- // 规则禁止空 catch 或仅 console 的 catch。本 helper 提供一条「实质调用语句」让
8
- // catch 合规,同时把错误记录到 debug/error 便于排查。
9
- //
10
- // 规则绕过原理:taste/no-silent-catch 仅检查 CatchClause 直接 body 是否为空或仅
11
- // console 调用。本 helper 是普通函数调用(ExpressionStatement),既非空也非仅
12
- // console,故合规。helper 函数体内部经共享 logger 路由(不裸 console)。
13
-
14
- import { getLogger } from "@zhushanwen/pi-extension-logger";
15
-
16
- const logger = getLogger("subagents");
17
-
18
- /** 错误日志级别。debug = 次要清理(默认);error = 关键步骤但需继续后续清理。 */
19
- export type BestEffortLevel = "debug" | "error";
20
-
21
- /**
22
- * 吞咽 best-effort IO 的错误,按 level 经共享 logger 记录。
23
- *
24
- * - debug(默认):次要清理(sidecar/worktree/alive marker),失败属预期路径
25
- * - error:关键步骤抛错但需继续后续清理(如 finalizeRecord 的 B9 链:completeRecord
26
- * 抛错后仍要执行 finalized/cleanup,错误需可见但不阻断)
27
- *
28
- * 错误对象优先取 message(避免打印巨大堆栈/对象),其他类型原样传入。
29
- */
30
- export function bestEffort(err: unknown, context: string, level: BestEffortLevel = "debug"): void {
31
- const detail = err instanceof Error ? err.message : err;
32
- const msg = `[subagents] best-effort ${context} failed`;
33
- if (level === "error") {
34
- logger.error(msg, { detail });
35
- } else {
36
- logger.debug(msg, { detail });
37
- }
38
- }
@@ -1,144 +0,0 @@
1
- // src/execution/channel-registry-access.ts
2
- //
3
- // Channel registry 的访问入口(本扩展内部用 + 契约文档化导出)。
4
- //
5
- // ask-user 等扩展通过本模块注册 channel handler,让 subagent 子进程的 UI 请求
6
- // 能透传到主进程渲染。所有扩展各自直接读写
7
- // globalThis[Symbol.for("@zhushanwen/pi-subagents.channelHandshake")],
8
- // 拿到结构兼容 ChannelRegistryHandshake 的同一握手对象。
9
- //
10
- // ── 升级说明(决策 D 修复 M4)─────────────────────────────────
11
- // 历史问题:原协议槽位直接存 UiChannelRegistry 实例,谁先 session_start 谁创建。
12
- // ask-user 先到时会自建简化 registry 占位,劫持 canonical 槽位,subagent-workflow
13
- // 后到时拿到的是 ask-user 的非 canonical 实例,行为不一致。
14
- //
15
- // 修复:槽位从「存 registry 实例」升级为「存握手对象 {version, registry?, pending[]}」。
16
- // canonical registry 实例永远由 subagent-workflow 单一创建点(本模块的
17
- // getOrCreateChannelRegistry)实例化。ask-user 先到时只往 pending 推 handler,
18
- // 等 subagent-workflow 来 flush;subagent-workflow 先到时直接创建 registry 并
19
- // 接收后续 ask-user 推入的 pending。
20
- //
21
- // ── 跨扩展协议契约(必须与 ask-user 侧严格一致)──────────────
22
- // key 字面量: "@zhushanwen/pi-subagents.channelHandshake"
23
- // ↑ 必须与 ask-user/src/channel-registry-register.ts 完全一致
24
- // handshake 形状: ChannelRegistryHandshake(version=1)
25
- // version 守卫: slot.version !== 1 时 console.warn + 丢弃重建(向前兼容未来升级)
26
-
27
- import { getLogger } from "@zhushanwen/pi-extension-logger";
28
-
29
- import { createUiChannelRegistry, type UiChannelRegistry, type ChannelHandler } from "./ui-channels.ts";
30
-
31
- const logger = getLogger("subagents");
32
-
33
- /** 进程级 channel 握手的 globalThis key(Symbol.for 跨模块共享)。
34
- *
35
- * **协议契约**:字面量 `"@zhushanwen/pi-subagents.channelHandshake"` 必须与
36
- * ask-user 扩展的 `ask-user/src/channel-registry-register.ts` 完全一致——
37
- * 两边读写同一个 Symbol.for key 才能拿到同一握手对象。
38
- *
39
- * 改名历史:原 `CHANNEL_REGISTRY_KEY`(字面量 `...channelRegistry`)在决策 D
40
- * 中升级为 `CHANNEL_HANDSHAKE_KEY`(字面量 `...channelHandshake`),槽位形状
41
- * 从 registry 实例改为握手对象。 */
42
- export const CHANNEL_HANDSHAKE_KEY = Symbol.for("@zhushanwen/pi-subagents.channelHandshake");
43
-
44
- /** 握手版本。未来若形状不兼容升级,递增此常量并在 getOrCreateChannelRegistry
45
- * 的 version 守卫里加迁移逻辑。 */
46
- const HANDSHAKE_VERSION = 1 as const;
47
-
48
- /** pending channel handler 条目。ask-user 先到、registry 未就绪时临时存放。 */
49
- export interface ChannelRegistryHandshakePendingEntry {
50
- channel: string;
51
- handler: ChannelHandler;
52
- }
53
-
54
- /** 跨扩展 channel registry 握手对象(globalThis 槽位形状)。
55
- *
56
- * - `version`:协议版本,当前固定 1。读取时若 ≠1 视为不兼容,丢弃重建。
57
- * - `registry`:canonical UiChannelRegistry 实例。仅由 subagent-workflow 的
58
- * getOrCreateChannelRegistry 创建并填充。未就绪时为 undefined。
59
- * - `pending`:ask-user 在 registry 就绪前推入的 handler 条目。
60
- * subagent-workflow 创建 registry 后逐条 flush(注册),然后清空。 */
61
- export interface ChannelRegistryHandshake {
62
- version: typeof HANDSHAKE_VERSION;
63
- registry?: UiChannelRegistry;
64
- pending: ChannelRegistryHandshakePendingEntry[];
65
- }
66
-
67
- /** 读取握手槽位;若 version 不匹配则视为缺失(warn + 返回 undefined)。
68
- * 类型不安全的 globalThis 反射访问集中在本函数,外层逻辑保持类型严谨。 */
69
- function readHandshakeSlot(): ChannelRegistryHandshake | undefined {
70
- const slot = Reflect.get(globalThis, CHANNEL_HANDSHAKE_KEY) as unknown;
71
- if (slot === undefined) return undefined;
72
- // 形状校验:必须是对象且 version===1,否则视为不兼容
73
- if (typeof slot !== "object" || slot === null) {
74
- logger.warn(
75
- "[pi-subagent-workflow] channel handshake slot is not an object; discarding and recreating.",
76
- );
77
- return undefined;
78
- }
79
- // 断言目标含必填 version 字段(object/null 已守卫;version 值本身在下一行校验),
80
- // 对齐 format.ts extractAgentName 的必填字段断言先例,避免全可选断言零校验。
81
- const version = (slot as { version: unknown }).version;
82
- if (version !== HANDSHAKE_VERSION) {
83
- logger.warn(
84
- `[pi-subagent-workflow] channel handshake version mismatch (got ${String(
85
- version,
86
- )}, expected ${HANDSHAKE_VERSION}); discarding and recreating.`,
87
- );
88
- return undefined;
89
- }
90
- // version 正确,但 pending 可能被恶意/错误地塞了非数组;防御性处理
91
- const candidate = slot as ChannelRegistryHandshake;
92
- if (!Array.isArray(candidate.pending)) {
93
- logger.warn(
94
- "[pi-subagent-workflow] channel handshake pending is not an array; discarding and recreating.",
95
- );
96
- return undefined;
97
- }
98
- return candidate;
99
- }
100
-
101
- /** 将 pending 条目逐个注册进 registry,注册完清空 pending。
102
- * pending 内部 entry 的形状由 ask-user 侧保证,此处不再二次校验。 */
103
- function flushPending(registry: UiChannelRegistry, pending: ChannelRegistryHandshakePendingEntry[]): void {
104
- for (const entry of pending) {
105
- registry.register(entry.channel, entry.handler);
106
- }
107
- }
108
-
109
- /** 获取或创建进程级 channel registry(canonical 单例)。
110
- *
111
- * **唯一创建点**:canonical UiChannelRegistry 实例仅由本函数创建。
112
- * ask-user 扩展绝不自建 registry——它在 registry 未就绪时只往 slot.pending 推条目。
113
- *
114
- * 行为分支:
115
- * 1. 槽位不存在或 version ≠ 1 → warn(version 不匹配时)+ 建新 slot
116
- * `{version:1, pending:[], registry:<newly created>}`
117
- * 2. 槽位存在但 registry 未就绪(ask-user 先到过,塞过 pending)→
118
- * 创建 canonical registry + flush pending + 清空 pending
119
- * 3. 槽位存在且 registry 已就绪(本函数已被调用过)→
120
- * 直接返回同一实例引用(===),不重建、不重复 flush
121
- *
122
- * @returns 进程级 canonical UiChannelRegistry 单例(永不返回 undefined) */
123
- export function getOrCreateChannelRegistry(): UiChannelRegistry {
124
- let slot = readHandshakeSlot();
125
- if (slot === undefined) {
126
- // 分支 1:无合规槽位,新建并立即创建 canonical registry
127
- const registry = createUiChannelRegistry();
128
- slot = { version: HANDSHAKE_VERSION, registry, pending: [] };
129
- Reflect.set(globalThis, CHANNEL_HANDSHAKE_KEY, slot);
130
- return registry;
131
- }
132
- if (slot.registry === undefined) {
133
- // 分支 2:ask-user 先到过,flush pending 进 canonical registry
134
- const registry = createUiChannelRegistry();
135
- flushPending(registry, slot.pending);
136
- slot.pending = [];
137
- slot.registry = registry;
138
- return registry;
139
- }
140
- // 分支 3:registry 已就绪,返回同一实例
141
- return slot.registry;
142
- }
143
-
144
- export type { UiChannelRegistry, ChannelHandler };