@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
package/README.md CHANGED
@@ -4,7 +4,7 @@ Pi 的 subagent + workflow 合并包:任务委派 + 多 agent 编排(chain /
4
4
 
5
5
  ## 内置 Agents
6
6
 
7
- 按「读/写 × 视角」正交切分,9 个角色零重叠:
7
+ 按「读/写 × 视角」正交切分,10 个角色零重叠(C1 起随 `@zhushanwen/subagent-core` 的 `agents/` 资产分发,`<available_subagents>` 的 `<location>` 指向 core 包目录):
8
8
 
9
9
  | Agent | 角色 | 读/写 |
10
10
  |-------|------|-------|
@@ -12,6 +12,7 @@ Pi 的 subagent + workflow 合并包:任务委派 + 多 agent 编排(chain /
12
12
  | `planner` | 复杂任务拆解为有序实施计划(合并需求澄清) | 只读产文档 |
13
13
  | `coder` | 代码实现、修改、测试(唯一改代码的角色) | 可改 |
14
14
  | `reviewer` | 代码审查与需求验收(含 git diff) | 只读 |
15
+ | `doc-reviewer` | 文档审查(四遍方法论,事实锚点核实;spec / 设计文档) | 只读 |
15
16
  | `debugger` | 运行时故障诊断,钉根因 | 只读* |
16
17
  | `analyst` | 深度项目分析,产出给人读的报告 | 只读 |
17
18
  | `researcher` | 外部资料调研(依赖 tavily skill) | 只读 |
@@ -30,19 +31,12 @@ Pi 的 subagent + workflow 合并包:任务委派 + 多 agent 编排(chain /
30
31
 
31
32
  ## Orchestrator 协调器模式
32
33
 
33
- agent 禁用 bash / read / write / edit 等执行工具,只保留协调类工具,被迫作为纯协调器:拆解任务 → 委派 subagent → 汇总结果。orchestrator agent 自身也可递归委派子 orchestrator,实现分层任务拆解(深度受 `Depth: N/10` 护栏保护)。
34
+ orchestrator 是纯协调器角色:拆解任务 → 委派 subagent → 汇总结果,自身不做执行类工作。orchestrator agent 自身也可递归委派子 orchestrator,实现分层任务拆解(深度受 `Depth: N/10` 护栏保护)。
34
35
 
35
- 可用工具 5 个:`todo`、`goal_control`、`workflow`、`subagent`、`ask_user`(`ask_user` `@zhushanwen/pi-ask-user` 提供,未安装时 orchestrator 遇歧义会明示停止而非猜测)。
36
-
37
- ### 启动命令
36
+ **工具约束变化(C1/D-5)**:内置模板不再携带 `tools:` frontmatter 白名单,subagent 不再以 `--tools` 白名单启动——工具约束回归宿主默认工具面,orchestrator 靠角色职责(职责边界段)约束自身只做协调。想要白名单的用户在 `<workspace>/.agents/agents/` 放同名 `.md` 覆写(project 级源稳定遮蔽内置,是唯一逃生门),或沿用 pi CLI 的 `--tools` 白名单(临时验证):
38
37
 
39
38
  ```bash
40
- # 方式一:CLI 工具白名单(临时验证最快)
41
39
  pi --tools todo,goal_control,workflow,subagent,ask_user
42
-
43
- # 方式二:白名单 + 注入 orchestrator 的 system prompt(推荐,主进程也具备协调器视角)
44
- pi --tools todo,goal_control,workflow,subagent,ask_user \
45
- --append-system-prompt "$(cat ~/.pi/agent/npm/node_modules/@zhushanwen/pi-subagent-workflow/agents/orchestrator.md)"
46
40
  ```
47
41
 
48
42
  > **依赖**:需先安装本包及相关扩展
@@ -59,7 +53,7 @@ pi --tools todo,goal_control,workflow,subagent,ask_user \
59
53
 
60
54
  ## Workflow 生命周期(one-shot)
61
55
 
62
- Workflow run 是一次性执行,状态机两态:`running → done`(`done` 唯一终态,reason 区分 completed / aborted / failed / budget_limited / time_limited)。`workflow` tool 仅 3 个 action:`run` / `status` / `abort`。
56
+ Workflow run 是一次性执行,状态机两态:`running → done`(`done` 唯一终态,reason 区分 completed / aborted / failed / budget_limited / time_limited)。`workflow` tool 仅 3 个 action:`run` / `status` / `abort`。run 的 `name` 接受 `<available_workflows>` 列出的 workflow 名(内置 chain / parallel / map-reduce / scatter-gather / review-fix-loop 或已保存脚本)或 `.js` 绝对路径。
63
57
 
64
58
  Runs are one-shot: there is no pause/resume — to stop a run early use abort; for a fresh result start a new run.
65
59
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhushanwen/pi-subagent-workflow",
3
- "version": "8.6.0",
3
+ "version": "8.8.0",
4
4
  "type": "module",
5
5
  "main": "index.ts",
6
6
  "description": "Unified subagent execution and multi-agent workflow orchestration for Pi — spawned-process agent runtime with sync/background modes, stateful workflow management with persistence, state machine, and execution tracing.",
@@ -19,17 +19,14 @@
19
19
  },
20
20
  "files": [
21
21
  "index.ts",
22
- "agents/",
23
22
  "skills/",
24
- "workflows/",
25
23
  "scripts/",
26
24
  "relay/",
27
25
  "src/index.ts",
28
- "src/execution/",
26
+ "src/jsonl-run-store.ts",
27
+ "src/host/",
29
28
  "src/injectors/",
30
- "src/orchestration/",
31
- "src/interface/",
32
- "src/shared/"
29
+ "src/interface/"
33
30
  ],
34
31
  "xyz-agent": {
35
32
  "role": "universal",
@@ -53,26 +50,22 @@
53
50
  ],
54
51
  "skills": [
55
52
  "./skills"
56
- ],
57
- "agents": [
58
- "./agents"
59
53
  ]
60
54
  },
61
55
  "dependencies": {
62
- "ajv": "^8.20.0",
63
- "yaml": "^2.9.0",
64
- "@xyz-agent/extension-protocol": "0.7.0",
65
56
  "@xyz-agent/session-delivery": "0.3.0",
66
- "@zhushanwen/pi-extension-logger": "0.3.0",
67
- "@zhushanwen/pi-file-lock": "0.1.2"
57
+ "@zhushanwen/pi-ext-guards": "0.2.0",
58
+ "@zhushanwen/pi-extension-logger": "0.4.0",
59
+ "@xyz-agent/extension-protocol": "0.8.0",
60
+ "@zhushanwen/subagent-core": "0.4.0"
68
61
  },
69
62
  "peerDependencies": {
70
- "@earendil-works/pi-ai": "^0.84.1",
71
- "@earendil-works/pi-coding-agent": "^0.84.1",
72
- "@earendil-works/pi-tui": "^0.84.1",
63
+ "@earendil-works/pi-ai": "^0.84.4",
64
+ "@earendil-works/pi-coding-agent": "^0.84.4",
65
+ "@earendil-works/pi-tui": "^0.84.4",
73
66
  "typebox": "*",
74
- "@zhushanwen/pi-pending-notifications": "0.5.0",
75
- "@zhushanwen/pi-structured-output": "5.1.0"
67
+ "@zhushanwen/pi-structured-output": "5.1.2",
68
+ "@zhushanwen/pi-pending-notifications": "0.5.2"
76
69
  },
77
70
  "peerDependenciesMeta": {
78
71
  "@earendil-works/pi-coding-agent": {
package/relay/relay.mjs CHANGED
@@ -8,7 +8,7 @@
8
8
  * 通道,payload 一律 base64 封装保字节精确。
9
9
  *
10
10
  * ============================ 镜像常量表 ============================
11
- * SSOT = src/execution/relay-env.ts(零依赖脚本不能 import workspace 包,只能内嵌镜像;
11
+ * SSOT = packages/subagent-core/src/execution/relay-env.ts(零依赖脚本不能 import workspace 包,只能内嵌镜像;
12
12
  * 改名/改值必须双侧同步,一致性由 E-3 conformance relay 变体断言锁定——设计 §10-5):
13
13
  *
14
14
  * | relay-env.ts 常量 | 本文件常量 | 值 |
@@ -39,13 +39,22 @@ This is enforced by `lintScript`:
39
39
 
40
40
  ## Required: Meta Declaration
41
41
 
42
- Every script MUST declare `meta` at the top level:
42
+ Every script MUST declare its metadata as a `/* @pi-meta */` YAML block comment at the top level — NOT a `const meta` variable:
43
43
 
44
44
  ```javascript
45
- const meta = { name: 'workflow-name', description: '...', phases: ['phase1', 'phase2'] };
45
+ /* @pi-meta
46
+ name: workflow-name
47
+ description: One-line description of what the workflow does
48
+ phases: ['phase1', 'phase2']
49
+ */
46
50
  ```
47
51
 
48
- `name` must match the filename stem. `phases` is for display only.
52
+ - `name` must match the filename stem. `phases` is for display only.
53
+ - Optional fields: `parameters` (JSON Schema for `$ARGS`) and `usage` (markdown).
54
+ - The YAML body starts on the line after `/* @pi-meta`; the closing `*/` must sit alone at column 0.
55
+ - `generate` round-trip-validates the YAML and reports line/col on error (common pitfall: patternProperties regex must use double backslash `\\d`, not `\d`).
56
+
57
+ > **Legacy `const meta = { ... }` (transition only):** `generate` still accepts a legacy top-level `const meta` during the transition window, but the core discovery chain does NOT recognize it (no legacy fallback) — such scripts stay invisible to discovery and get no metadata injection. Always use `/* @pi-meta */` for new scripts.
49
58
 
50
59
  ## [MANDATORY] Display: description + phase
51
60
 
@@ -59,11 +68,11 @@ TUI `/workflows` 视图按**运行时 `phase()` 调用**分组(非 `meta.phase
59
68
  ### Minimal 示例(三者齐备)
60
69
 
61
70
  ```javascript
62
- const meta = {
63
- name: 'review-fix',
64
- description: 'review then fix',
65
- phases: ['review', 'fix'],
66
- };
71
+ /* @pi-meta
72
+ name: review-fix
73
+ description: review then fix
74
+ phases: ['review', 'fix']
75
+ */
67
76
 
68
77
  phase('review');
69
78
  const r = await agent({ prompt: 'review diff', description: 'review-diff' });
@@ -79,11 +88,17 @@ return { done: true };
79
88
  // ❌ agent() 无 description → TUI 显示 unnamed agent
80
89
  await agent({ prompt: 'review diff' });
81
90
 
82
- // ❌ meta.phases 用对象数组 → 引擎忽略,全部归入 (unnamed)
83
- const meta = { name: 'x', phases: [{ title: 'review' }, { title: 'fix' }] };
91
+ // ❌ phases 用对象数组 → 引擎忽略,全部归入 (unnamed)
92
+ /* @pi-meta
93
+ name: x
94
+ phases: [{ title: 'review' }, { title: 'fix' }]
95
+ */
84
96
 
85
97
  // ❌ 声明了 phases 但从不 phase() 调用 → 运行时分组失效
86
- const meta = { name: 'x', phases: ['review', 'fix'] };
98
+ /* @pi-meta
99
+ name: x
100
+ phases: ['review', 'fix']
101
+ */
87
102
  // ... 直接 await agent(...) 从不调 phase('review') / phase('fix')
88
103
  ```
89
104
 
@@ -201,7 +216,7 @@ const results = await parallel(
201
216
  );
202
217
  ```
203
218
 
204
- > 内置通用编排 workflow(chain / parallel / scatter-gather / map-reduce,可直接 `workflow run`,用 `agent()` 自包含实现)见 `extensions/universal/subagent-workflow/workflows/`。本段教 `workflow()` 嵌套 API,workflows 目录是开箱即用的通用编排工具(用 `agent()` 而非 `workflow()` 嵌套)。
219
+ > 内置通用编排 workflow(chain / parallel / scatter-gather / map-reduce / review-fix-loop,可直接 `workflow run`,用 `agent()` 自包含实现)见 `extensions/universal/subagent-workflow/workflows/`。本段教 `workflow()` 嵌套 API,workflows 目录是开箱即用的通用编排工具(用 `agent()` 而非 `workflow()` 嵌套)。
205
220
 
206
221
  ### Other globals
207
222
 
@@ -249,7 +264,11 @@ agent({ prompt: '...', description: 'review-business-logic' });
249
264
  ## Complete Example
250
265
 
251
266
  ```javascript
252
- const meta = { name: 'review-fix-loop', description: 'Loop: review → fix → commit until clean', phases: ['review-fix'] };
267
+ /* @pi-meta
268
+ name: review-fix-loop
269
+ description: "Loop: review → fix → commit until clean"
270
+ phases: ['review-fix']
271
+ */
253
272
 
254
273
  const MAX_ROUNDS = 10;
255
274
  let round = 0;
@@ -0,0 +1,235 @@
1
+ // pi-host.test.ts —— pi 壳宿主实现与现行为等价(u0-wire 验收①)。
2
+ //
3
+ // 三视角:①使用者——discoveryRoots 各 kind 的根清单/顺序/source 标签与
4
+ // resource-discovery.ts buildScanTargets(user-pi/npm/npm-dev 段)、
5
+ // skill-discovery.ts resolveSkillPath(skills 两根)现推导逐项一致;
6
+ // ②构建者——dataRoot/log/countActiveFromEntries/createDelivery 四端口桥接形态;
7
+ // ③观察者——getAgentDir 每次现取(PI_CODING_AGENT_DIR 实例隔离切换后重取生效,
8
+ // 无模块级缓存)。
9
+ //
10
+ // mock 策略:pi SDK / pi 宿主协作件全部 vi.mock 工厂覆盖(vitest alias 的
11
+ // mocks/ 桩只供其他测试族用,本文件需要可控返回值)。pending-notifications
12
+ // mock 返回 {count: n} 形状直接验证「适配读 .count」;session-delivery mock
13
+ // 验证 createDelivery 透传(参数 + 返回句柄)。
14
+
15
+ import { join, dirname } from "node:path";
16
+ import { createRequire } from "node:module";
17
+ import { existsSync } from "node:fs";
18
+
19
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
20
+
21
+ // ── hoisted mocks(vi.mock 工厂 hoisting 不能引用外部 let/const) ──
22
+
23
+ const piCodingAgentMock = vi.hoisted(() => ({
24
+ // 与实装版 getAgentDir 的 env 契约一致(PI_CODING_AGENT_DIR 实例隔离优先),
25
+ // 使「env 切换后重取生效」可直接断言;缺省值仅作 fallback。
26
+ getAgentDir: vi.fn(() => process.env.PI_CODING_AGENT_DIR ?? "/mock/default/agent-dir"),
27
+ }));
28
+
29
+ const extensionLoggerMock = vi.hoisted(() => ({
30
+ getLogger: vi.fn(),
31
+ }));
32
+
33
+ const pendingNotificationsMock = vi.hoisted(() => ({
34
+ countActiveFromEntries: vi.fn(),
35
+ }));
36
+
37
+ const sessionDeliveryMock = vi.hoisted(() => ({
38
+ createDelivery: vi.fn(),
39
+ }));
40
+
41
+ vi.mock("@earendil-works/pi-coding-agent", () => piCodingAgentMock);
42
+ vi.mock("@zhushanwen/pi-extension-logger", () => extensionLoggerMock);
43
+ vi.mock("@zhushanwen/pi-pending-notifications", () => pendingNotificationsMock);
44
+ vi.mock("@xyz-agent/session-delivery", () => sessionDeliveryMock);
45
+
46
+ import { getAgentDir } from "@earendil-works/pi-coding-agent";
47
+ import { getLogger } from "@zhushanwen/pi-extension-logger";
48
+ import { countActiveFromEntries } from "@zhushanwen/pi-pending-notifications";
49
+ import { createDelivery } from "@xyz-agent/session-delivery";
50
+
51
+ import { createPiHostServices, createPiNotifyDomainPorts } from "../pi-host.ts";
52
+
53
+ beforeEach(() => {
54
+ vi.mocked(getAgentDir).mockClear();
55
+ vi.mocked(getLogger).mockReset();
56
+ vi.mocked(countActiveFromEntries).mockReset();
57
+ vi.mocked(createDelivery).mockReset();
58
+ delete process.env.PI_CODING_AGENT_DIR;
59
+ });
60
+
61
+ afterEach(() => {
62
+ vi.restoreAllMocks();
63
+ delete process.env.PI_CODING_AGENT_DIR;
64
+ });
65
+
66
+ describe("createPiHostServices.discoveryRoots(与现推导逐项一致)", () => {
67
+ // 基线锚点:resource-discovery.ts buildScanTargets(join(agentDir, kind) /
68
+ // join(agentDir, "npm", "node_modules") / join(agentDir, "extensions"))与
69
+ // skill-discovery.ts resolveSkillPath(join(getAgentDir(), "skills") +
70
+ // join(getAgentDir(), "npm/node_modules"))。根列表按优先级低→高排列(D2)。
71
+ const AGENT_DIR = "/fake/agent-dir";
72
+
73
+ function stubAgentDir(): void {
74
+ vi.mocked(getAgentDir).mockReturnValue(AGENT_DIR);
75
+ }
76
+
77
+ it("agents 四根:user-pi → npm → npm-dev → core 包父目录(C5⑥,source npm 追加末位)", () => {
78
+ stubAgentDir();
79
+ const roots = createPiHostServices().discoveryRoots?.().agents;
80
+
81
+ // 期望的 core 注入根用与 pi-host.ts 相同的锚点解析(./workflows/* 子入口在
82
+ // workspace 与 npm dist 双形态同径;探针证据见 probe-c5.md P1/P3)
83
+ const require = createRequire(import.meta.url);
84
+ const anchor = require.resolve("@zhushanwen/subagent-core/workflows/README.md");
85
+ const coreParent = dirname(dirname(dirname(anchor)));
86
+
87
+ expect(roots).toEqual([
88
+ { dir: join(AGENT_DIR, "agents"), source: "user-pi" },
89
+ { dir: join(AGENT_DIR, "npm", "node_modules"), source: "npm" },
90
+ { dir: join(AGENT_DIR, "extensions"), source: "npm-dev" },
91
+ // C5⑥:core 包一级父目录(npm 槽语义:一级子项 = 包目录,无 pi manifest 扫
92
+ // agents/ 约定目录);追加在既有 npm 根之后——同标签靠后者胜(新版遮蔽旧残留)
93
+ { dir: coreParent, source: "npm" },
94
+ ]);
95
+ });
96
+
97
+ it("agents 第 4 根指向 core 包的父目录(其下 subagent-core/agents/ 存在 10 内置角色)", () => {
98
+ stubAgentDir();
99
+ const roots = createPiHostServices().discoveryRoots?.().agents;
100
+ const coreRoot = roots?.[3];
101
+
102
+ expect(coreRoot?.source).toBe("npm");
103
+ // 便捷断言:core 包根(注入 dir 的子目录)下 agents/ 真实存在
104
+ expect(existsSync(join(coreRoot!.dir, "subagent-core", "agents"))).toBe(true);
105
+ });
106
+
107
+ it("workflows 三根:与 agents 同构,末级目录名切换为 workflows", () => {
108
+ stubAgentDir();
109
+ const roots = createPiHostServices().discoveryRoots?.().workflows;
110
+
111
+ expect(roots).toEqual([
112
+ { dir: join(AGENT_DIR, "workflows"), source: "user-pi" },
113
+ { dir: join(AGENT_DIR, "npm", "node_modules"), source: "npm" },
114
+ { dir: join(AGENT_DIR, "extensions"), source: "npm-dev" },
115
+ ]);
116
+ });
117
+
118
+ it("skills 两根:user-pi + npm,无 npm-dev(对齐 skill-discovery 现状)", () => {
119
+ stubAgentDir();
120
+ const roots = createPiHostServices().discoveryRoots?.().skills;
121
+
122
+ expect(roots).toEqual([
123
+ { dir: join(AGENT_DIR, "skills"), source: "user-pi" },
124
+ { dir: join(AGENT_DIR, "npm", "node_modules"), source: "npm" },
125
+ ]);
126
+ });
127
+
128
+ it("每次调用现取 getAgentDir(agentDir 变更后根列表跟随,不缓存)", () => {
129
+ stubAgentDir();
130
+ const first = createPiHostServices().discoveryRoots?.().agents;
131
+ const secondCallDir = "/another/agent-dir";
132
+ vi.mocked(getAgentDir).mockReturnValue(secondCallDir);
133
+ const second = createPiHostServices().discoveryRoots?.().agents;
134
+
135
+ expect(second?.[0].dir).toBe(join(secondCallDir, "agents"));
136
+ expect(first?.[0].dir).not.toBe(second?.[0].dir);
137
+ });
138
+ });
139
+
140
+ describe("createPiHostServices.dataRoot(每次现取 getAgentDir)", () => {
141
+ it("返回 getAgentDir() 本身(env 覆盖段与 warn-once 留 core data-dir)", () => {
142
+ vi.mocked(getAgentDir).mockReturnValue("/data/root");
143
+ expect(createPiHostServices().dataRoot()).toBe("/data/root");
144
+ });
145
+
146
+ it("PI_CODING_AGENT_DIR 切换后重取生效(实例隔离,无模块级缓存)", () => {
147
+ // 恢复 mock 工厂的 env 语义实现(其他用例的 mockReturnValue 会覆盖它)
148
+ vi.mocked(getAgentDir).mockImplementation(
149
+ () => process.env.PI_CODING_AGENT_DIR ?? "/mock/default/agent-dir",
150
+ );
151
+ process.env.PI_CODING_AGENT_DIR = "/instance-a";
152
+ const host = createPiHostServices();
153
+ expect(host.dataRoot()).toBe("/instance-a");
154
+
155
+ process.env.PI_CODING_AGENT_DIR = "/instance-b";
156
+ expect(host.dataRoot()).toBe("/instance-b");
157
+ });
158
+
159
+ it("透传 getAgentDir 调用(不缓存结果、不吞调用)", () => {
160
+ vi.mocked(getAgentDir).mockReturnValue("/d1");
161
+ const host = createPiHostServices();
162
+ host.dataRoot();
163
+ host.dataRoot();
164
+ expect(vi.mocked(getAgentDir)).toHaveBeenCalledTimes(2);
165
+ });
166
+ });
167
+
168
+ describe("createPiHostServices.log(桥接 pi-extension-logger)", () => {
169
+ function stubLogger(): { debug: ReturnType<typeof vi.fn>; warn: ReturnType<typeof vi.fn>; error: ReturnType<typeof vi.fn> } {
170
+ const fake = { debug: vi.fn(), warn: vi.fn(), error: vi.fn() };
171
+ vi.mocked(getLogger).mockReturnValue(fake);
172
+ return fake;
173
+ }
174
+
175
+ it("debug level → logger.debug,(message, data) 透传", () => {
176
+ const fake = stubLogger();
177
+ createPiHostServices().log("debug", "subagents", "d-msg", { k: 1 });
178
+
179
+ expect(vi.mocked(getLogger)).toHaveBeenCalledWith("subagents");
180
+ expect(fake.debug).toHaveBeenCalledWith("d-msg", { k: 1 });
181
+ expect(fake.warn).not.toHaveBeenCalled();
182
+ expect(fake.error).not.toHaveBeenCalled();
183
+ });
184
+
185
+ it("warn level → logger.warn;error level → logger.error", () => {
186
+ const fake = stubLogger();
187
+ const host = createPiHostServices();
188
+
189
+ host.log("warn", "comp-a", "w-msg");
190
+ host.log("error", "comp-b", "e-msg", { reason: "x" });
191
+
192
+ expect(fake.warn).toHaveBeenCalledWith("w-msg", undefined);
193
+ expect(fake.error).toHaveBeenCalledWith("e-msg", { reason: "x" });
194
+ expect(vi.mocked(getLogger)).toHaveBeenNthCalledWith(1, "comp-a");
195
+ expect(vi.mocked(getLogger)).toHaveBeenNthCalledWith(2, "comp-b");
196
+ });
197
+ });
198
+
199
+ describe("createPiNotifyDomainPorts.countActiveFromEntries(适配读 .count)", () => {
200
+ it("拆 CountActiveResult.count 为 number(core 端口契约),entries 透传", () => {
201
+ const entries: unknown[] = [{ customType: "pending:register" }];
202
+ vi.mocked(countActiveFromEntries).mockReturnValue({ count: 3, ids: ["a", "b", "c"], entries: [] });
203
+
204
+ const result = createPiNotifyDomainPorts().countActiveFromEntries?.(entries);
205
+
206
+ expect(result).toBe(3);
207
+ expect(vi.mocked(countActiveFromEntries)).toHaveBeenCalledWith(entries);
208
+ });
209
+
210
+ it("零活跃返回 0({count: 0} 形状)", () => {
211
+ vi.mocked(countActiveFromEntries).mockReturnValue({ count: 0, ids: [], entries: [] });
212
+ expect(createPiNotifyDomainPorts().countActiveFromEntries?.([])).toBe(0);
213
+ });
214
+ });
215
+
216
+ describe("createPiNotifyDomainPorts.createDelivery(透传 session-delivery)", () => {
217
+ it("参数透传 + 返回句柄透传(不经包装)", () => {
218
+ const fakePort = {
219
+ supportedPayloads: ["text"] as const,
220
+ isIdle: () => true,
221
+ hasPendingMessages: () => false,
222
+ send: () => undefined,
223
+ };
224
+ const fakeConfig = { intent: "after-run" as const };
225
+ const fakeHandle = { send: () => {}, flush: () => {}, dispose: () => {} };
226
+ vi.mocked(createDelivery).mockReturnValue(fakeHandle);
227
+
228
+ const result = createPiNotifyDomainPorts().createDelivery?.(fakePort, fakeConfig);
229
+
230
+ expect(vi.mocked(createDelivery)).toHaveBeenCalledTimes(1);
231
+ expect(vi.mocked(createDelivery).mock.calls[0][0]).toBe(fakePort);
232
+ expect(vi.mocked(createDelivery).mock.calls[0][1]).toBe(fakeConfig);
233
+ expect(result).toBe(fakeHandle);
234
+ });
235
+ });
@@ -0,0 +1,163 @@
1
+ // src/host/pi-host.ts
2
+ //
3
+ // pi 壳宿主实现(subagent-core 包抽离 u0-wire)。设计权威源:
4
+ // docs/design/subagent-core-package-extraction.md §3.3 D2(含计划期契约细化 3 条)。
5
+ //
6
+ // 本文件属壳侧(shell),不进 core 切面——对 pi SDK 与 pi 宿主协作件
7
+ // (@earendil-works/pi-coding-agent / @zhushanwen/pi-extension-logger /
8
+ // @zhushanwen/pi-pending-notifications / @xyz-agent/session-delivery)的运行时
9
+ // import 收敛在此层,core 闭包(D9 守卫对象)不得出现这些包。
10
+ //
11
+ // 端口语义:
12
+ // - dataRoot / discoveryRoots 每次调用现取 getAgentDir(),禁止模块级缓存:
13
+ // getAgentDir 尊重 PI_CODING_AGENT_DIR 实例隔离(xyz-agent 按 session dir
14
+ // 隔离 pi 实例),缓存会把后续切换实例的进程钉死在首个 agentDir。
15
+ // - discoveryRoots 的根清单/顺序/source 标签与 shared/resource-discovery.ts
16
+ // buildScanTargets、orchestration/skill-discovery.ts resolveSkillPath 的现推导
17
+ // 逐项一致(user-pi / npm / npm-dev 字面即现 ResourceSource 标签)。
18
+ // project/workspace 根不在壳侧提供——core 消费方按 workspaceRoot 自行推导
19
+ // (u0-data-discovery 波次接注入消费)。C5⑥ 起 agents kind 追加第 4 根:
20
+ // core 包一级父目录(source "npm")——core agents/ 资产进 pi 发现面,见
21
+ // corePackageNpmRoot 注释。
22
+ // - countActiveFromEntries 适配:pi 侧真函数返回 CountActiveResult 对象,core
23
+ // 端口契约是 number(core 消费面只读 .count,notify-ports.ts 契约注释)——
24
+ // foundation 单元登记给本单元的适配责任。
25
+ // - createDelivery 透传:@xyz-agent/session-delivery 的 createDelivery 与 core
26
+ // 的 Delivery* 结构化类型逐字段结构兼容(DeliveryHandle 的 sendChecked/depth
27
+ // 是结构超集成员,多不碍兼容)——结构兼容由本注入点 typecheck 守护,上游签名
28
+ // 漂移即红(notify-ports.ts「闭包红线」段)。
29
+
30
+ import { createRequire } from "node:module";
31
+ import { dirname, join } from "node:path";
32
+
33
+ import { getAgentDir } from "@earendil-works/pi-coding-agent";
34
+ import { getLogger } from "@zhushanwen/pi-extension-logger";
35
+ import { countActiveFromEntries } from "@zhushanwen/pi-pending-notifications";
36
+ import { createDelivery } from "@xyz-agent/session-delivery";
37
+
38
+ import type { DiscoveryRoot, HostServices } from "@zhushanwen/subagent-core/core/host-services.ts";
39
+ import type { LogLevel } from "@zhushanwen/subagent-core/core/logger.ts";
40
+ import type { NotifyDomainPorts } from "@zhushanwen/subagent-core/core/notify-ports.ts";
41
+
42
+ /**
43
+ * core 包(@zhushanwen/subagent-core)agents/ 资产进 pi 发现面的注入根(C5⑥,
44
+ * convergence §5.4 检查点 2;探针证据 docs/design/subagent-core-convergence.probe-c5.md)。
45
+ *
46
+ * 解析锚点 = `@zhushanwen/subagent-core/workflows/README.md`:`./workflows/*` 子入口
47
+ * 在 workspace TS 直引与 npm dist 两种发布形态下同径(publishConfig 保留该子入口),
48
+ * README.md 是两形态都必在的资产文件。core 包根 = 锚点上两级;npm 槽注入其一级
49
+ * 父目录——npm 槽语义:dir 下一级子项 = 包目录,core 无 pi manifest → 扫 agents/
50
+ * 约定目录命中 10 内置角色。
51
+ *
52
+ * 布局覆盖(探针 P2-P5 实测):dev workspace(core 在仓库 packages/ 下)与发布态
53
+ * 嵌套布局(core 在本包 node_modules 内)下这是唯一命中通路;发布态平铺布局
54
+ * (core 与本包同层)下既有 npm 根已命中,本注入是幂等兜底(重复发现被 core
55
+ * realpath 去重吸收)。
56
+ *
57
+ * 每次调用现解析(不 memo):发现调用点稀疏(session_start + 缓存 miss),解析
58
+ * 成本可忽略;失败(异常布局/解析器不可用)降级为不注入并 warn——绝不因资产
59
+ * 接线失败阻断发现主链。
60
+ */
61
+ function corePackageNpmRoot(): string | undefined {
62
+ try {
63
+ // createRequire 锚定本模块(jiti 加载器下 import.meta.url 可用;不可用则随
64
+ // catch 降级)。require.resolve 沿 pi-sw 自身的依赖解析链——workspace 与发布态
65
+ // 都从本包出发命中 core。
66
+ const require = createRequire(import.meta.url);
67
+ const anchor = require.resolve("@zhushanwen/subagent-core/workflows/README.md");
68
+ return dirname(dirname(dirname(anchor)));
69
+ } catch (err) {
70
+ // getLogger 惰性调用(catch 是冷路径——测试环境对 pi-extension-logger 的
71
+ // module-level mock 可能返回 undefined,模块级持有会在 import 期踩 undefined)
72
+ getLogger("pi-host").warn(
73
+ "[pi-host] core 包 agents/ 注入根解析失败——10 内置角色可能不可发现",
74
+ { reason: err instanceof Error ? err.message : String(err) },
75
+ );
76
+ return undefined;
77
+ }
78
+ }
79
+
80
+ /** agents/workflows 共享的 agentDir 派生根(末级目录名由 kind 决定)。
81
+ * 顺序与 source 标签逐项对齐 resource-discovery.ts buildScanTargets 的
82
+ * user-pi → npm → npm-dev 段(根列表按优先级低→高排列,D2 语义边界)。 */
83
+ function agentDirKindRoots(kind: "agents" | "workflows"): DiscoveryRoot[] {
84
+ const agentDir = getAgentDir();
85
+ const roots: DiscoveryRoot[] = [
86
+ // 1. user .pi/agent/<kind>/
87
+ { dir: join(agentDir, kind), source: "user-pi" },
88
+ // 2. npm global: agentDir/npm/node_modules/*/<pkg>/
89
+ { dir: join(agentDir, "npm", "node_modules"), source: "npm" },
90
+ // 3. npm dev symlink: agentDir/extensions/*/<pkg>/
91
+ { dir: join(agentDir, "extensions"), source: "npm-dev" },
92
+ ];
93
+ // 4. core 包根(C5⑥,仅 agents kind):追加在既有 npm 根之后——同标签多根依注入
94
+ // 序扫描 + last-writer-wins,core(随本包依赖分发的新模板)遮蔽同 agentDir 内
95
+ // 旧版残留副本;序位仍在 user 级之上、npm-dev/project 级之下(红线 1)。
96
+ // workflows kind 刻意不注入:<available_workflows> 的 <location> 是 CA2 快照
97
+ // 不豁免面(红线 8 豁免仅限 10 内置 agent 角色路径前缀),注入会翻转内置
98
+ // workflow 的胜出路径。
99
+ if (kind === "agents") {
100
+ const coreNpmRoot = corePackageNpmRoot();
101
+ if (coreNpmRoot !== undefined) {
102
+ roots.push({ dir: coreNpmRoot, source: "npm" });
103
+ }
104
+ }
105
+ return roots;
106
+ }
107
+
108
+ /** skills 的 agentDir 派生根。对齐 skill-discovery.ts resolveSkillPath 的两处
109
+ * 推导(<agentDir>/skills + <agentDir>/npm/node_modules)——现状无 npm-dev 根,
110
+ * 刻意不补(避免静默引入新发现源)。 */
111
+ function skillRoots(): DiscoveryRoot[] {
112
+ const agentDir = getAgentDir();
113
+ return [
114
+ { dir: join(agentDir, "skills"), source: "user-pi" },
115
+ { dir: join(agentDir, "npm", "node_modules"), source: "npm" },
116
+ ];
117
+ }
118
+
119
+ /** pi 宿主 HostServices 实现(扩展初始化最早处经 configureCore 注入)。 */
120
+ export function createPiHostServices(): HostServices {
121
+ return {
122
+ // 每次现取 getAgentDir(实例隔离,见文件头);env 覆盖段与 warn-once 留 core
123
+ // data-dir.ts,壳只返回数据根本身(D2 计划期细化③分段归属)。
124
+ dataRoot(): string {
125
+ return getAgentDir();
126
+ },
127
+
128
+ // 桥接到 pi-extension-logger:component 即 extName(复用其 loggerCache 单例
129
+ // 与 appendEntry/文件日志通路),按 level 分派方法,(message, data) 透传。
130
+ log(level: LogLevel, component: string, message: string, data?: unknown): void {
131
+ const logger = getLogger(component);
132
+ if (level === "error") logger.error(message, data);
133
+ else if (level === "warn") logger.warn(message, data);
134
+ else logger.debug(message, data);
135
+ },
136
+
137
+ discoveryRoots(): {
138
+ agents?: DiscoveryRoot[];
139
+ skills?: DiscoveryRoot[];
140
+ workflows?: DiscoveryRoot[];
141
+ } {
142
+ return {
143
+ agents: agentDirKindRoots("agents"),
144
+ skills: skillRoots(),
145
+ workflows: agentDirKindRoots("workflows"),
146
+ };
147
+ },
148
+ };
149
+ }
150
+
151
+ /** pi 侧通知域窄端口实现(configureNotifyDomain 注入)。zsw 壳不注入本端口
152
+ * (其完成通知走 HostServices.notify,P2 落地)。 */
153
+ export function createPiNotifyDomainPorts(): NotifyDomainPorts {
154
+ return {
155
+ // pi 真函数返回 CountActiveResult,core 契约只读 .count——壳侧拆数值。
156
+ countActiveFromEntries(entries: unknown[]): number {
157
+ return countActiveFromEntries(entries).count;
158
+ },
159
+
160
+ // 投递内核工厂直传本体(结构兼容论证见文件头);不经包装避免多一层间接面。
161
+ createDelivery,
162
+ };
163
+ }