@zhushanwen/pi-subagent-workflow 8.5.0 → 8.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/package.json +13 -16
  2. package/relay/relay.mjs +1 -1
  3. package/src/host/__tests__/pi-host.test.ts +214 -0
  4. package/src/host/pi-host.ts +109 -0
  5. package/src/index.ts +142 -32
  6. package/src/injectors/__tests__/engine-awareness.test.ts +292 -0
  7. package/src/injectors/__tests__/engine-section-stability.test.ts +341 -0
  8. package/src/injectors/__tests__/subagent-list-injector.test.ts +5 -5
  9. package/src/injectors/__tests__/workflow-list-injector.test.ts +5 -5
  10. package/src/injectors/engine-awareness.ts +123 -0
  11. package/src/injectors/model-list-injector.ts +1 -1
  12. package/src/injectors/subagent-list-injector.ts +8 -8
  13. package/src/injectors/workflow-list-injector.ts +8 -8
  14. package/src/interface/__tests__/detectors.test.ts +3 -3
  15. package/src/interface/__tests__/subagent-tool-path-guard.test.ts +157 -0
  16. package/src/interface/__tests__/subagent-tool-prompt.test.ts +12 -0
  17. package/src/interface/__tests__/tool-workflow-script-generate.test.ts +2 -2
  18. package/src/interface/__tests__/tool-workflow-throw-paths.test.ts +1 -1
  19. package/src/interface/bg-notify-render.ts +34 -13
  20. package/src/interface/commands.ts +3 -3
  21. package/src/interface/format.ts +2 -2
  22. package/src/interface/helpers.ts +3 -3
  23. package/src/interface/list-component.ts +4 -4
  24. package/src/interface/list-shared.ts +2 -2
  25. package/src/interface/list-view.ts +2 -2
  26. package/src/interface/subagent-actions.ts +288 -19
  27. package/src/interface/subagent-tool-schema.ts +163 -0
  28. package/src/interface/subagent-tool.ts +65 -129
  29. package/src/interface/subagents.ts +5 -5
  30. package/src/interface/tool-render.ts +34 -2
  31. package/src/interface/tool-workflow-script.ts +4 -4
  32. package/src/interface/tool-workflow.ts +6 -6
  33. package/src/interface/views/WorkflowsView.ts +5 -5
  34. package/src/interface/views/__tests__/WorkflowsView-signature.test.ts +3 -3
  35. package/src/interface/views/__tests__/detail-content-session-file.test.ts +2 -2
  36. package/src/interface/views/detail-content.ts +4 -4
  37. package/src/interface/views/format.ts +4 -4
  38. package/src/{orchestration/jsonl-run-store.ts → jsonl-run-store.ts} +132 -18
  39. package/src/execution/__tests__/__fixtures__/notifier-golden-snapshots.json +0 -53
  40. package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +0 -1
  41. package/src/execution/__tests__/agent-registry.test.ts +0 -363
  42. package/src/execution/__tests__/agent-result-mapper.test.ts +0 -150
  43. package/src/execution/__tests__/alive-store.test.ts +0 -147
  44. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  45. package/src/execution/__tests__/before-agent-start-injection.test.ts +0 -132
  46. package/src/execution/__tests__/bg-notify-render.test.ts +0 -256
  47. package/src/execution/__tests__/channel-registry-handshake.test.ts +0 -243
  48. package/src/execution/__tests__/chat-engine-routing.test.ts +0 -597
  49. package/src/execution/__tests__/chatmode-first-round-closure-service.test.ts +0 -365
  50. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -190
  51. package/src/execution/__tests__/chatmode-round-notify-real-chain.test.ts +0 -215
  52. package/src/execution/__tests__/concurrency-pool.test.ts +0 -250
  53. package/src/execution/__tests__/config.test.ts +0 -110
  54. package/src/execution/__tests__/conversation-wiring.test.ts +0 -198
  55. package/src/execution/__tests__/crash-recovery.test.ts +0 -320
  56. package/src/execution/__tests__/delivery-methods.test.ts +0 -385
  57. package/src/execution/__tests__/dialog-queue.test.ts +0 -299
  58. package/src/execution/__tests__/epipe-fallback.test.ts +0 -241
  59. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -243
  60. package/src/execution/__tests__/execute-nesting.test.ts +0 -323
  61. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -189
  62. package/src/execution/__tests__/execution-record.test.ts +0 -1284
  63. package/src/execution/__tests__/finalize-record.test.ts +0 -368
  64. package/src/execution/__tests__/finalized-marker.test.ts +0 -82
  65. package/src/execution/__tests__/format-schema-instruction.test.ts +0 -138
  66. package/src/execution/__tests__/format.test.ts +0 -458
  67. package/src/execution/__tests__/gc-timer.test.ts +0 -184
  68. package/src/execution/__tests__/get-record-for-action-restart.test.ts +0 -254
  69. package/src/execution/__tests__/gui-mode-dispatch.test.ts +0 -59
  70. package/src/execution/__tests__/helpers/mock-extension-api.ts +0 -30
  71. package/src/execution/__tests__/helpers/spawn-mock.ts +0 -238
  72. package/src/execution/__tests__/host-mode.test.ts +0 -87
  73. package/src/execution/__tests__/index-session-start-identity.test.ts +0 -371
  74. package/src/execution/__tests__/index-session-start.test.ts +0 -593
  75. package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
  76. package/src/execution/__tests__/lifecycle-manager.test.ts +0 -337
  77. package/src/execution/__tests__/lifecycle-predicates.test.ts +0 -116
  78. package/src/execution/__tests__/list-component.test.ts +0 -401
  79. package/src/execution/__tests__/list-fields.test.ts +0 -109
  80. package/src/execution/__tests__/manifest-parentid.test.ts +0 -117
  81. package/src/execution/__tests__/model-resolver.test.ts +0 -413
  82. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +0 -287
  83. package/src/execution/__tests__/nested-visibility.test.ts +0 -325
  84. package/src/execution/__tests__/notifier-flush.test.ts +0 -574
  85. package/src/execution/__tests__/notifier-golden-snapshot.test.ts +0 -261
  86. package/src/execution/__tests__/one-shot-upgrade.test.ts +0 -205
  87. package/src/execution/__tests__/output-collector.test.ts +0 -61
  88. package/src/execution/__tests__/parent-child-matrix.test.ts +0 -336
  89. package/src/execution/__tests__/path-encoding.test.ts +0 -104
  90. package/src/execution/__tests__/pi-invocation.test.ts +0 -134
  91. package/src/execution/__tests__/record-store.test.ts +0 -1057
  92. package/src/execution/__tests__/records-cwd-isolation.test.ts +0 -91
  93. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +0 -339
  94. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -273
  95. package/src/execution/__tests__/relay-agent.test.ts +0 -448
  96. package/src/execution/__tests__/relay-env.test.ts +0 -42
  97. package/src/execution/__tests__/resource-policy.test.ts +0 -109
  98. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  99. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -267
  100. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -253
  101. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -644
  102. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  103. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  104. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  105. package/src/execution/__tests__/sdk-contract.test.ts +0 -273
  106. package/src/execution/__tests__/session-context-resolver.test.ts +0 -167
  107. package/src/execution/__tests__/session-file-gc.test.ts +0 -293
  108. package/src/execution/__tests__/session-pending.test.ts +0 -197
  109. package/src/execution/__tests__/session-reconstructor.test.ts +0 -379
  110. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -178
  111. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -311
  112. package/src/execution/__tests__/session-start-reaper.test.ts +0 -233
  113. package/src/execution/__tests__/spawn-args.test.ts +0 -434
  114. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -189
  115. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  116. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -207
  117. package/src/execution/__tests__/spawned-children.test.ts +0 -92
  118. package/src/execution/__tests__/startup-config-declaration.test.ts +0 -35
  119. package/src/execution/__tests__/status-refactor.test.ts +0 -345
  120. package/src/execution/__tests__/stdin-writer.test.ts +0 -463
  121. package/src/execution/__tests__/stream-sink-retirement.test.ts +0 -261
  122. package/src/execution/__tests__/subagent-service-abort.test.ts +0 -60
  123. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -629
  124. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +0 -180
  125. package/src/execution/__tests__/subagent-service.test.ts +0 -788
  126. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -310
  127. package/src/execution/__tests__/subprocess-agent-runner.test.ts +0 -506
  128. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  129. package/src/execution/__tests__/timeout-integration.test.ts +0 -397
  130. package/src/execution/__tests__/tombstone-store.test.ts +0 -73
  131. package/src/execution/__tests__/tool-action.test.ts +0 -385
  132. package/src/execution/__tests__/truncline-snapshot.test.ts +0 -81
  133. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  134. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  135. package/src/execution/__tests__/ui-channels.test.ts +0 -187
  136. package/src/execution/__tests__/ui-interaction-model.test.ts +0 -67
  137. package/src/execution/__tests__/ui-request-handler-factory.test.ts +0 -370
  138. package/src/execution/__tests__/ui-request-handler.test.ts +0 -204
  139. package/src/execution/__tests__/ui-request-observability.test.ts +0 -114
  140. package/src/execution/__tests__/ui-request-queue.test.ts +0 -133
  141. package/src/execution/__tests__/worktree-manager.test.ts +0 -633
  142. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -229
  143. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +0 -181
  144. package/src/execution/__tests__/worktree-registry.test.ts +0 -199
  145. package/src/execution/agent-registry.ts +0 -193
  146. package/src/execution/agent-result-mapper.ts +0 -90
  147. package/src/execution/alive-store.ts +0 -92
  148. package/src/execution/argv-mirror.ts +0 -109
  149. package/src/execution/best-effort.ts +0 -38
  150. package/src/execution/channel-registry-access.ts +0 -144
  151. package/src/execution/concurrency-pool.ts +0 -116
  152. package/src/execution/config.ts +0 -96
  153. package/src/execution/dialog-queue.ts +0 -330
  154. package/src/execution/engine/__tests__/common/data-dir.test.ts +0 -53
  155. package/src/execution/engine/__tests__/common/errors.test.ts +0 -132
  156. package/src/execution/engine/__tests__/common/event-journal.test.ts +0 -177
  157. package/src/execution/engine/__tests__/common/kill-chain.test.ts +0 -192
  158. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +0 -81
  159. package/src/execution/engine/__tests__/common/persona-router.test.ts +0 -123
  160. package/src/execution/engine/__tests__/common/pool-manager.test.ts +0 -154
  161. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  162. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  163. package/src/execution/engine/__tests__/conformance/agent-event-invariants.ts +0 -141
  164. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +0 -109
  165. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +0 -101
  166. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +0 -77
  167. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +0 -104
  168. package/src/execution/engine/__tests__/conformance/contract.relay.test.ts +0 -342
  169. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +0 -201
  170. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +0 -76
  171. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +0 -79
  172. package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -87
  173. package/src/execution/engine/__tests__/engines-declaration.test.ts +0 -36
  174. package/src/execution/engine/__tests__/model-prompt.test.ts +0 -85
  175. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  176. package/src/execution/engine/__tests__/registry.test.ts +0 -120
  177. package/src/execution/engine/__tests__/routing.test.ts +0 -231
  178. package/src/execution/engine/common/data-dir.ts +0 -62
  179. package/src/execution/engine/common/errors.ts +0 -183
  180. package/src/execution/engine/common/event-journal.ts +0 -254
  181. package/src/execution/engine/common/journal-replay.ts +0 -62
  182. package/src/execution/engine/common/kill-chain.ts +0 -221
  183. package/src/execution/engine/common/nesting-guard.ts +0 -50
  184. package/src/execution/engine/common/persona-router.ts +0 -108
  185. package/src/execution/engine/common/pool-manager.ts +0 -226
  186. package/src/execution/engine/common/schema-emulation.ts +0 -189
  187. package/src/execution/engine/common/session-view-projection.ts +0 -51
  188. package/src/execution/engine/engine-discovery.ts +0 -65
  189. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -469
  190. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  191. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  192. package/src/execution/engine/engines/pi/pi-engine.ts +0 -415
  193. package/src/execution/engine/engines/pi/reader.ts +0 -48
  194. package/src/execution/engine/engines/pi/registration.ts +0 -35
  195. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  196. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  197. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  198. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -246
  199. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -228
  200. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  201. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -64
  202. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -127
  203. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -567
  204. package/src/execution/engine/engines/zcode/constants.ts +0 -43
  205. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -39
  206. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  207. package/src/execution/engine/engines/zcode/parser.ts +0 -436
  208. package/src/execution/engine/engines/zcode/preparer.ts +0 -363
  209. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  210. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  211. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -648
  212. package/src/execution/engine/host-task-spec.ts +0 -47
  213. package/src/execution/engine/model-prompt.ts +0 -59
  214. package/src/execution/engine/paths.ts +0 -42
  215. package/src/execution/engine/port.ts +0 -153
  216. package/src/execution/engine/registry.ts +0 -123
  217. package/src/execution/engine/routing.ts +0 -218
  218. package/src/execution/engine/types.ts +0 -304
  219. package/src/execution/execute-options-mapper.ts +0 -111
  220. package/src/execution/execution-record.ts +0 -906
  221. package/src/execution/finalize-record.ts +0 -251
  222. package/src/execution/finalized-marker.ts +0 -51
  223. package/src/execution/get-state-handshake.ts +0 -104
  224. package/src/execution/host-mode.ts +0 -56
  225. package/src/execution/idle-gc.ts +0 -47
  226. package/src/execution/lifecycle-manager.ts +0 -491
  227. package/src/execution/lifecycle-predicates.ts +0 -65
  228. package/src/execution/manifest-store.ts +0 -256
  229. package/src/execution/model-config-service.ts +0 -204
  230. package/src/execution/model-resolver.ts +0 -276
  231. package/src/execution/notifier.ts +0 -260
  232. package/src/execution/output-collector.ts +0 -88
  233. package/src/execution/path-encoding.ts +0 -60
  234. package/src/execution/pi-invocation.ts +0 -120
  235. package/src/execution/record-entry.ts +0 -132
  236. package/src/execution/record-store.ts +0 -1234
  237. package/src/execution/relay-env.ts +0 -37
  238. package/src/execution/session-context-resolver.ts +0 -64
  239. package/src/execution/session-file-gc.ts +0 -120
  240. package/src/execution/session-pending.ts +0 -164
  241. package/src/execution/session-reconstructor.ts +0 -678
  242. package/src/execution/session-runner.ts +0 -1548
  243. package/src/execution/sessions-index.ts +0 -304
  244. package/src/execution/spawn-event-adapter.ts +0 -363
  245. package/src/execution/stdin-writer.ts +0 -198
  246. package/src/execution/stream-sink.ts +0 -126
  247. package/src/execution/subagent-service.ts +0 -2119
  248. package/src/execution/subprocess-agent-runner.ts +0 -303
  249. package/src/execution/temp-prompt.ts +0 -62
  250. package/src/execution/tombstone-store.ts +0 -72
  251. package/src/execution/turn-limiter.ts +0 -102
  252. package/src/execution/types.ts +0 -910
  253. package/src/execution/ui-channels.ts +0 -216
  254. package/src/execution/ui-interaction-model.ts +0 -48
  255. package/src/execution/ui-request-handler-factory.ts +0 -212
  256. package/src/execution/ui-request-observability.ts +0 -81
  257. package/src/execution/ui-request-queue.ts +0 -174
  258. package/src/execution/worktree-manager.ts +0 -688
  259. package/src/execution/worktree-registry.ts +0 -222
  260. package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +0 -336
  261. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +0 -208
  262. package/src/orchestration/__tests__/agent-call-stream.test.ts +0 -157
  263. package/src/orchestration/__tests__/args-validator.test.ts +0 -143
  264. package/src/orchestration/__tests__/concurrency-gate.test.ts +0 -125
  265. package/src/orchestration/__tests__/config-loader.test.ts +0 -503
  266. package/src/orchestration/__tests__/error-recovery-handlers.test.ts +0 -724
  267. package/src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts +0 -405
  268. package/src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts +0 -56
  269. package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +0 -166
  270. package/src/orchestration/__tests__/execute-agent-call.test.ts +0 -314
  271. package/src/orchestration/__tests__/jsonl-run-store-loadall-sources.test.ts +0 -171
  272. package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +0 -1030
  273. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -277
  274. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +0 -96
  275. package/src/orchestration/__tests__/lifecycle.test.ts +0 -625
  276. package/src/orchestration/__tests__/review-fix-loop-e2e.test.ts +0 -1971
  277. package/src/orchestration/__tests__/script-lint.test.ts +0 -831
  278. package/src/orchestration/__tests__/skill-discovery.test.ts +0 -157
  279. package/src/orchestration/__tests__/test-mocks.ts +0 -197
  280. package/src/orchestration/__tests__/worker-host.test.ts +0 -120
  281. package/src/orchestration/__tests__/worker-returnmeta-passthrough.test.ts +0 -164
  282. package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +0 -520
  283. package/src/orchestration/__tests__/worker-script-builder.test.ts +0 -309
  284. package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +0 -110
  285. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +0 -317
  286. package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +0 -110
  287. package/src/orchestration/__tests__/workflows-e2e.test.ts +0 -537
  288. package/src/orchestration/agent-opts-resolver.ts +0 -93
  289. package/src/orchestration/args-validator.ts +0 -127
  290. package/src/orchestration/concurrency-gate.ts +0 -69
  291. package/src/orchestration/config-loader.ts +0 -315
  292. package/src/orchestration/error-recovery.ts +0 -862
  293. package/src/orchestration/execute-agent-call.ts +0 -217
  294. package/src/orchestration/launcher.ts +0 -410
  295. package/src/orchestration/lifecycle.ts +0 -396
  296. package/src/orchestration/models/__tests__/budget.test.ts +0 -367
  297. package/src/orchestration/models/__tests__/trace.test.ts +0 -408
  298. package/src/orchestration/models/agent-call.ts +0 -83
  299. package/src/orchestration/models/budget.ts +0 -148
  300. package/src/orchestration/models/ports.ts +0 -164
  301. package/src/orchestration/models/run-runtime.ts +0 -89
  302. package/src/orchestration/models/run-spec.ts +0 -83
  303. package/src/orchestration/models/run-state.ts +0 -44
  304. package/src/orchestration/models/trace.ts +0 -183
  305. package/src/orchestration/models/types.ts +0 -292
  306. package/src/orchestration/models/workflow-run.ts +0 -254
  307. package/src/orchestration/models/workflow-script-registry.ts +0 -35
  308. package/src/orchestration/models/workflow-script.ts +0 -117
  309. package/src/orchestration/script-lint.ts +0 -766
  310. package/src/orchestration/skill-discovery.ts +0 -92
  311. package/src/orchestration/worker-handle.ts +0 -115
  312. package/src/orchestration/worker-host.ts +0 -98
  313. package/src/orchestration/worker-script-builder.ts +0 -408
  314. package/src/orchestration/workflow-files.ts +0 -85
  315. package/src/orchestration/workflow-script-registry-impl.ts +0 -133
  316. package/src/shared/__tests__/agent-ref.test.ts +0 -34
  317. package/src/shared/__tests__/meta-parser.test.ts +0 -304
  318. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -280
  319. package/src/shared/__tests__/resource-discovery.test.ts +0 -736
  320. package/src/shared/__tests__/resource-meta.test.ts +0 -51
  321. package/src/shared/__tests__/schema-jsonify.test.ts +0 -81
  322. package/src/shared/agent-event.ts +0 -13
  323. package/src/shared/agent-ref.ts +0 -57
  324. package/src/shared/meta-parser.ts +0 -261
  325. package/src/shared/resource-discovery.ts +0 -811
  326. package/src/shared/resource-meta.ts +0 -65
  327. package/src/shared/schema-jsonify.ts +0 -56
  328. package/src/shared/xml-injection.ts +0 -35
  329. package/workflows/README.md +0 -81
  330. package/workflows/_shared/agent-refs.cjs +0 -40
  331. package/workflows/chain.js +0 -131
  332. package/workflows/map-reduce.js +0 -174
  333. package/workflows/parallel.js +0 -148
  334. package/workflows/review-fix-loop-utils.cjs +0 -1307
  335. package/workflows/review-fix-loop.js +0 -1396
  336. package/workflows/scatter-gather.js +0 -178
@@ -1,363 +0,0 @@
1
- // src/execution/__tests__/agent-registry.test.ts
2
- //
3
- // AgentRegistry 测试(S2 路径统一版)。
4
- //
5
- // S2 重构:AgentRegistry 从「按名查找(discoverAll + cache Map<name>)」收敛为
6
- // 「按绝对路径加载(loadByPath)」——agentRef 唯一形态 = .md 绝对路径(注入段
7
- // <location>),内置 agent 即包内物理路径,无 builtin 合并、无名字查找。
8
- // 发现(注入段数据源)职责由 shared/resource-discovery + injector 承担,
9
- // 本文件不再测发现层(见 resource-discovery.test.ts)。
10
- import * as fs from "node:fs";
11
- import * as os from "node:os";
12
- import * as path from "node:path";
13
-
14
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
15
-
16
- // 隔离真实用户全局目录(~/.agents/agents/ 可能有真实 agent 文件)
17
- vi.mock("node:os", async (importOriginal) => {
18
- const actual = await importOriginal<typeof import("node:os")>();
19
- return { ...actual, homedir: () => "/nonexistent-home-for-tests" };
20
- });
21
-
22
- import { lintAgentMeta } from "../../orchestration/script-lint.ts";
23
- import { parseResourceMeta } from "../../shared/meta-parser.ts";
24
- import { AgentRegistry, parseAgentFrontmatter, parseAgentWithMeta } from "../agent-registry.ts";
25
- import type { EnginePort } from "../engine/port.ts";
26
- import { clearEngines, registerEngine } from "../engine/registry.ts";
27
-
28
- // ============================================================
29
- // helpers
30
- // ============================================================
31
-
32
- function tmpWorkspace(): string {
33
- return fs.mkdtempSync(path.join(os.tmpdir(), "agent-reg-test-"));
34
- }
35
-
36
- function writeAgent(dir: string, name: string, body: string): string {
37
- fs.mkdirSync(dir, { recursive: true });
38
- const filePath = path.join(dir, `${name}.md`);
39
- fs.writeFileSync(filePath, body, "utf-8");
40
- return filePath;
41
- }
42
-
43
- // ============================================================
44
- // parseAgentFrontmatter
45
- // ============================================================
46
-
47
- describe("parseAgentFrontmatter", () => {
48
- it("parses name from filename + body as systemPrompt when no frontmatter", () => {
49
- const cfg = parseAgentFrontmatter("/x/worker.md", "You are a worker.");
50
- expect(cfg.name).toBe("worker");
51
- expect(cfg.systemPrompt).toBe("You are a worker.");
52
- });
53
- it("extracts model/thinkingLevel/tools from frontmatter", () => {
54
- const cfg = parseAgentFrontmatter("/x/coder.md", `---
55
- name: coder
56
- description: coding agent
57
- model: anthropic/claude-3.5-sonnet
58
- thinkingLevel: high
59
- tools: [read, bash]
60
- ---
61
- body text`);
62
- expect(cfg.name).toBe("coder");
63
- expect(cfg.model).toBe("anthropic/claude-3.5-sonnet");
64
- expect(cfg.thinkingLevel).toBe("high");
65
- expect(cfg.tools).toEqual(["read", "bash"]);
66
- expect(cfg.systemPrompt).toBe("body text");
67
- });
68
- });
69
-
70
- // ============================================================
71
- // parseAgentWithMeta(m5 T2:W4 lint 用 AgentMeta 二元组)
72
- // ============================================================
73
-
74
- describe("parseAgentWithMeta", () => {
75
- it("有 frontmatter(IF1 通过):meta 非 null 且路由字段完整,config 同步正确", () => {
76
- const { config, meta } = parseAgentWithMeta("/x/coder.md", `---
77
- name: coder
78
- description: 编码 agent
79
- when: 需要写代码
80
- notFor: 纯分析
81
- model: anthropic/claude-3.5-sonnet
82
- thinkingLevel: high
83
- tools: [read, bash]
84
- ---
85
- body text`);
86
- expect(meta).not.toBeNull();
87
- expect(meta!.kind).toBe("agent");
88
- expect(meta!.name).toBe("coder");
89
- expect(meta!.description).toBe("编码 agent");
90
- expect(meta!.when).toBe("需要写代码");
91
- expect(meta!.notFor).toBe("纯分析");
92
- expect(config.name).toBe("coder");
93
- expect(config.systemPrompt).toBe("body text");
94
- expect(config.model).toBe("anthropic/claude-3.5-sonnet");
95
- expect(config.thinkingLevel).toBe("high");
96
- expect(config.tools).toEqual(["read", "bash"]);
97
- });
98
-
99
- it("无 frontmatter:meta = null,整个内容作为 systemPrompt", () => {
100
- const { config, meta } = parseAgentWithMeta("/x/plain.md", "Just a prompt body.");
101
- expect(meta).toBeNull();
102
- expect(config).toEqual({
103
- name: "plain",
104
- systemPrompt: "Just a prompt body.",
105
- });
106
- });
107
-
108
- it("MF-3 fallback:缺 description(IF1 返 null)时 model/tools 经 extractYamlField 仍生效", () => {
109
- const { config, meta } = parseAgentWithMeta("/x/legacy.md", `---
110
- name: legacy
111
- model: anthropic/claude-3.5-sonnet
112
- tools: read, bash, write
113
- ---
114
- body text`);
115
- // 缺 description → parseResourceMeta 返 null → meta 为 null(结构化路由不可见)
116
- expect(meta).toBeNull();
117
- // 但 config 的 model/tools 不丢(direct-path loadByPath 与重构前行为一致)
118
- expect(config.name).toBe("legacy");
119
- expect(config.model).toBe("anthropic/claude-3.5-sonnet");
120
- expect(config.tools).toEqual(["read", "bash", "write"]);
121
- expect(config.systemPrompt).toBe("body text");
122
- });
123
-
124
- it("未闭合 frontmatter:meta = null,name 经 extractYamlField fallback,其余作为 systemPrompt", () => {
125
- const { config, meta } = parseAgentWithMeta("/x/broken.md", `---
126
- name: broken
127
- model: x/y`);
128
- expect(meta).toBeNull();
129
- expect(config.name).toBe("broken");
130
- // 未闭合分支只取 name(原行为),不解析 model
131
- expect(config.systemPrompt).toBe(`---\nname: broken\nmodel: x/y`);
132
- });
133
- });
134
-
135
- // ============================================================
136
- // AgentRegistry.loadByPath(S2:agentRef = .md 绝对路径)
137
- // ============================================================
138
-
139
- describe("AgentRegistry.loadByPath", () => {
140
- let ws: string;
141
- beforeEach(() => { ws = tmpWorkspace(); });
142
- afterEach(() => { fs.rmSync(ws, { recursive: true, force: true }); });
143
-
144
- it("按绝对路径加载 agent:frontmatter + body → AgentConfig", () => {
145
- const file = writeAgent(path.join(ws, ".pi", "agents"), "worker", `---
146
- name: worker
147
- description: 通用执行 agent
148
- tools: [read, bash]
149
- ---
150
- You are a worker.`);
151
- const reg = new AgentRegistry();
152
- const cfg = reg.loadByPath(file);
153
- expect(cfg?.name).toBe("worker");
154
- expect(cfg?.systemPrompt).toBe("You are a worker.");
155
- expect(cfg?.tools).toEqual(["read", "bash"]);
156
- });
157
-
158
- it("无 frontmatter 文件:整个内容作为 systemPrompt", () => {
159
- const file = writeAgent(ws, "plain", "Just a prompt body.");
160
- const cfg = new AgentRegistry().loadByPath(file);
161
- expect(cfg?.name).toBe("plain");
162
- expect(cfg?.systemPrompt).toBe("Just a prompt body.");
163
- });
164
-
165
- it("mtime 缓存:未变文件不重读(config 引用稳定)", () => {
166
- const file = writeAgent(ws, "cached", "v1");
167
- const reg = new AgentRegistry();
168
- const first = reg.loadByPath(file);
169
- const second = reg.loadByPath(file);
170
- expect(second).toBe(first);
171
- // 修改后 mtime 变化 → 新 config
172
- fs.writeFileSync(file, "v2", "utf-8");
173
- const third = reg.loadByPath(file);
174
- expect(third?.systemPrompt).toBe("v2");
175
- });
176
-
177
- it("相对路径引用返回 undefined(引用唯一形态 = 绝对路径)", () => {
178
- const reg = new AgentRegistry();
179
- expect(reg.loadByPath("worker")).toBeUndefined();
180
- expect(reg.loadByPath("./agents/worker.md")).toBeUndefined();
181
- });
182
-
183
- it("非 .md 引用返回 undefined", () => {
184
- const reg = new AgentRegistry();
185
- expect(reg.loadByPath("/tmp/worker.txt")).toBeUndefined();
186
- });
187
-
188
- it("文件不存在返回 undefined,require=true 抛错带指引", () => {
189
- const reg = new AgentRegistry();
190
- expect(reg.loadByPath("/nonexistent/x.md")).toBeUndefined();
191
- // R5(D7):三态错误文案统一带 <available_subagents> <location> 恢复指引
192
- expect(() => reg.loadByPath("/nonexistent/x.md", true)).toThrow(/not found or unreadable/);
193
- expect(() => reg.loadByPath("/nonexistent/x.md", true)).toThrow(/<available_subagents> <location>/);
194
- expect(() => reg.loadByPath("relative", true)).toThrow(/Invalid agent ref/);
195
- expect(() => reg.loadByPath("relative", true)).toThrow(/<available_subagents>/);
196
- });
197
-
198
- it("~/ 前缀展开", () => {
199
- const reg = new AgentRegistry();
200
- // homedir 被 mock 为 /nonexistent-home-for-tests → 文件必然不存在,验证展开逻辑
201
- expect(reg.loadByPath("~/agent.md")).toBeUndefined();
202
- });
203
- });
204
-
205
- // ============================================================
206
- // 包内 agents/*.md 数据合规(S2:内置 agent = 包内路径文件)
207
- // ============================================================
208
-
209
- describe("builtin agents 数据合规", () => {
210
- const AGENTS_DIR = path.resolve(__dirname, "../../../agents");
211
- const CORE = ["explorer", "coder", "reviewer", "debugger", "analyst", "planner", "researcher", "orchestrator", "general-purpose", "doc-reviewer"];
212
-
213
- it("agents/*.md 全部 IF1 解析成功", () => {
214
- for (const f of fs.readdirSync(AGENTS_DIR).filter((x) => x.endsWith(".md"))) {
215
- const meta = parseResourceMeta(fs.readFileSync(path.join(AGENTS_DIR, f), "utf-8"), "agent");
216
- expect(meta?.kind, `${f} parse 失败`).toBe("agent");
217
- }
218
- });
219
-
220
- it("核心 agent 均含 when/notFor/examples 且正反各一(lintAgentMeta 无 finding)", () => {
221
- for (const name of CORE) {
222
- const meta = parseResourceMeta(fs.readFileSync(path.join(AGENTS_DIR, `${name}.md`), "utf-8"), "agent");
223
- expect(meta, `${name} 解析失败`).not.toBeNull();
224
- if (meta?.kind !== "agent") continue;
225
- expect(meta.when, `${name} 缺 when`).toBeDefined();
226
- expect(meta.notFor, `${name} 缺 notFor`).toBeDefined();
227
- expect(meta.examples?.length, `${name} 缺 examples`).toBeGreaterThanOrEqual(2);
228
- expect(meta.examples?.some((e) => e.positive), `${name} 缺正向样本`).toBe(true);
229
- expect(meta.examples?.some((e) => !e.positive), `${name} 缺反向样本`).toBe(true);
230
- expect(lintAgentMeta(meta), `${name} examples 不合规`).toEqual([]);
231
- }
232
- });
233
-
234
- it("loadByPath 直接加载包内 agent(内置 = 路径文件,无名字查找)", () => {
235
- const reg = new AgentRegistry();
236
- const coder = reg.loadByPath(path.join(AGENTS_DIR, "coder.md"));
237
- expect(coder?.name).toBe("coder");
238
- expect(coder?.systemPrompt.length).toBeGreaterThan(0);
239
- // tools 字段精确匹配:未声明的为 undefined,声明的为具体数组。
240
- // 改 frontmatter 时这里会立即报错,拦住拼写错误或字段遗漏。
241
- expect(reg.loadByPath(path.join(AGENTS_DIR, "explorer.md"))?.tools).toEqual(
242
- ["read", "bash", "grep", "find", "structured-output"],
243
- );
244
- expect(reg.loadByPath(path.join(AGENTS_DIR, "researcher.md"))?.tools).toEqual(["read", "bash"]);
245
- expect(reg.loadByPath(path.join(AGENTS_DIR, "orchestrator.md"))?.tools).toEqual([
246
- "todo", "goal_control", "workflow", "subagent", "ask_user",
247
- ]);
248
- expect(reg.loadByPath(path.join(AGENTS_DIR, "reviewer.md"))?.tools).toEqual(["read", "bash", "grep", "find", "structured-output"]);
249
- expect(reg.loadByPath(path.join(AGENTS_DIR, "planner.md"))?.tools).toEqual(["read", "bash", "grep", "find", "structured-output"]);
250
- expect(reg.loadByPath(path.join(AGENTS_DIR, "coder.md"))?.tools).toEqual(["read", "write", "edit", "bash", "grep", "find", "structured-output"]);
251
- expect(reg.loadByPath(path.join(AGENTS_DIR, "debugger.md"))?.tools).toEqual(["read", "write", "edit", "bash", "grep", "find", "structured-output"]);
252
- expect(reg.loadByPath(path.join(AGENTS_DIR, "analyst.md"))?.tools).toEqual(["read", "bash", "grep", "find", "structured-output"]);
253
- expect(reg.loadByPath(path.join(AGENTS_DIR, "doc-reviewer.md"))?.tools).toEqual(["read", "grep", "structured-output"]);
254
- });
255
- });
256
-
257
- // ============================================================
258
- // engine 字段(P4 D9:frontmatter 主通道 + 解析期注册表校验)
259
- // ============================================================
260
-
261
- describe("parseAgentWithMeta engine 字段(P4 路由)", () => {
262
- beforeEach(() => {
263
- // 解析期校验消费注册表——测试内注册假引擎(惰性工厂无副作用)
264
- clearEngines();
265
- // 工厂恒 throw:解析期校验只查注册表存在性,不实例化(惰性工厂契约)
266
- const neverInstantiate = (): EnginePort => {
267
- throw new Error("parse-time validation must not instantiate engines");
268
- };
269
- registerEngine("pi", neverInstantiate);
270
- registerEngine("zcode", neverInstantiate);
271
- });
272
- afterEach(() => {
273
- clearEngines();
274
- });
275
-
276
- it("frontmatter engine 进 config.engine(结构化路径,IF1)", () => {
277
- const { config, meta } = parseAgentWithMeta(
278
- "/x/reviewer.md",
279
- `---
280
- name: reviewer
281
- description: review agent
282
- engine: zcode
283
- ---
284
- body`,
285
- );
286
- expect(config.engine).toBe("zcode");
287
- expect(meta?.kind === "agent" && meta.engine).toBe("zcode");
288
- });
289
-
290
- it("IF1 未通过(缺 description)时 legacy fallback 取 engine(配置不丢,与 model 同判)", () => {
291
- const { config } = parseAgentWithMeta(
292
- "/x/reviewer.md",
293
- `---
294
- name: reviewer
295
- engine: zcode
296
- ---
297
- body`,
298
- );
299
- expect(config.engine).toBe("zcode");
300
- });
301
-
302
- it("未注册 engine id:解析期抛 EngineNotFoundError,文案含注册清单与文件路径", () => {
303
- expect(() =>
304
- parseAgentWithMeta(
305
- "/x/reviewer.md",
306
- `---
307
- name: reviewer
308
- description: review agent
309
- engine: nonexistent-engine
310
- ---
311
- body`,
312
- ),
313
- ).toThrowError(/engine_not_found: engine 'nonexistent-engine'/);
314
- expect(() =>
315
- parseAgentWithMeta(
316
- "/x/reviewer.md",
317
- `---
318
- name: reviewer
319
- description: review agent
320
- engine: nonexistent-engine
321
- ---
322
- body`,
323
- ),
324
- ).toThrowError(/Registered engines: pi, zcode/);
325
- expect(() =>
326
- parseAgentWithMeta(
327
- "/x/my-agent.md",
328
- `---
329
- name: my-agent
330
- description: d
331
- engine: nonexistent-engine
332
- ---
333
- body`,
334
- ),
335
- ).toThrowError(/Source: \/x\/my-agent\.md/);
336
- });
337
-
338
- it("已注册 id(pi/zcode):解析通过,不抛", () => {
339
- expect(() =>
340
- parseAgentWithMeta(
341
- "/x/reviewer.md",
342
- `---
343
- name: reviewer
344
- description: review agent
345
- engine: pi
346
- ---
347
- body`,
348
- ),
349
- ).not.toThrow();
350
- });
351
-
352
- it("无 engine 字段:config.engine 缺省(走全局默认层)", () => {
353
- const { config } = parseAgentWithMeta(
354
- "/x/worker.md",
355
- `---
356
- name: worker
357
- description: d
358
- ---
359
- body`,
360
- );
361
- expect(config.engine).toBeUndefined();
362
- });
363
- });
@@ -1,150 +0,0 @@
1
- // src/execution/__tests__/agent-result-mapper.test.ts
2
- //
3
- // T3.14 (NFR-兼容性): AgentResult 映射字段对齐 —— D-A10 纯函数单测
4
- // T3.1 (正常): executeAndAwait 返回 content → 间接覆盖(subagent-service.test.ts 集成验证)
5
- //
6
- // 测试范围: mapToWorkflowAgentResult 所有字段映射分支(success/error/usage/toolCalls)
7
-
8
- import { describe, expect, it } from "vitest";
9
-
10
- import { mapToWorkflowAgentResult } from "../agent-result-mapper.ts";
11
- import type { AgentResult as SubagentsAgentResult, AgentUsageTotal, ToolCall } from "../types.ts";
12
-
13
- describe("mapToWorkflowAgentResult (D-A10)", () => {
14
- const minimalResult: SubagentsAgentResult = {
15
- text: "Hello",
16
- turns: 3,
17
- durationMs: 1200,
18
- success: true,
19
- sessionId: "session-123",
20
- toolCalls: [],
21
- };
22
-
23
- // ── T3.14: 正常成功路径 ──
24
-
25
- it("映射成功结果: text→content, durationMs/sessionId 透传", () => {
26
- const result = mapToWorkflowAgentResult(minimalResult);
27
- expect(result.content).toBe("Hello");
28
- expect(result.durationMs).toBe(1200);
29
- expect(result.sessionId).toBe("session-123");
30
- expect(result.error).toBeUndefined();
31
- expect(result.parsedOutput).toBeUndefined();
32
- expect(result.usage).toBeUndefined();
33
- expect(result.toolCalls).toEqual([]);
34
- });
35
-
36
- // ── sessionFile 透传(方案 A:让 workflow 继承 subagent 的 session jsonl 路径)──
37
-
38
- it("映射 sessionFile: subagents AgentResult.sessionFile → workflow AgentResult.sessionFile 透传", () => {
39
- const r: SubagentsAgentResult = {
40
- ...minimalResult,
41
- sessionFile: "/abs/path/.pi/agent/subagents/enc/sessions/2026-07-15T10-00-00-000Z_session-123.jsonl",
42
- };
43
- const result = mapToWorkflowAgentResult(r);
44
- expect(result.sessionFile).toBe("/abs/path/.pi/agent/subagents/enc/sessions/2026-07-15T10-00-00-000Z_session-123.jsonl");
45
- });
46
-
47
- it("映射 sessionFile: 无 sessionFile → workflow AgentResult.sessionFile undefined(窗口期/未回填)", () => {
48
- const r: SubagentsAgentResult = { ...minimalResult, sessionFile: undefined };
49
- const result = mapToWorkflowAgentResult(r);
50
- expect(result.sessionFile).toBeUndefined();
51
- });
52
-
53
- it("映射 parsedOutput 透传(structured-output 契约 BC-8)", () => {
54
- const parsedData = { score: 0.95, label: "positive" };
55
- const r: SubagentsAgentResult = { ...minimalResult, parsedOutput: parsedData };
56
- const result = mapToWorkflowAgentResult(r);
57
- expect(result.parsedOutput).toEqual(parsedData);
58
- });
59
-
60
- // ── T3.14: 失败路径 ──
61
-
62
- it("映射失败: success=false 且 error → 填入 error 字段", () => {
63
- const r: SubagentsAgentResult = { ...minimalResult, success: false, error: "timeout" };
64
- const result = mapToWorkflowAgentResult(r);
65
- expect(result.error).toBe("timeout");
66
- expect(result.content).toBe("Hello"); // content 仍保留(可能有部分输出)
67
- });
68
-
69
- it("映射失败: success=false 但无 error(abort 路径)→ error 填入 fallback 而非 undefined", () => {
70
- // H4: session-runner.ts abort 时 success=false, error=undefined。
71
- // 旧代码 error=undefined → executeAgentCall 误判 completed。
72
- // 修复后应 synthesize fallback error。
73
- const r: SubagentsAgentResult = { ...minimalResult, success: false };
74
- const result = mapToWorkflowAgentResult(r);
75
- expect(result.error).toBeDefined();
76
- expect(typeof result.error).toBe("string");
77
- expect(result.error.length).toBeGreaterThan(0);
78
- });
79
-
80
- it("映射成功: success=true 且 error 存在 → error=undefined(不误填)", () => {
81
- const r: SubagentsAgentResult = { ...minimalResult, success: true, error: "stale" };
82
- const result = mapToWorkflowAgentResult(r);
83
- expect(result.error).toBeUndefined();
84
- });
85
-
86
- // ── T3.14: usage 映射 ──
87
-
88
- it("映射 usage: AgentUsageTotal → AgentUsage(字段形状转换)", () => {
89
- const usage: AgentUsageTotal = {
90
- input: 1000,
91
- output: 500,
92
- cacheRead: 200,
93
- cacheWrite: 100,
94
- total: 1800,
95
- cost: 0.005,
96
- };
97
- const r: SubagentsAgentResult = { ...minimalResult, usage };
98
- const result = mapToWorkflowAgentResult(r);
99
- expect(result.usage).toEqual({
100
- input: 1000,
101
- output: 500,
102
- cacheRead: 200,
103
- cacheWrite: 100,
104
- cost: 0.005,
105
- contextTokens: 1800, // total → contextTokens
106
- turns: 3, // 来自 AgentResult.turns
107
- });
108
- });
109
-
110
- it("映射 usage: 无 usage → usage undefined", () => {
111
- const result = mapToWorkflowAgentResult(minimalResult);
112
- expect(result.usage).toBeUndefined();
113
- });
114
-
115
- // ── T3.14: toolCalls 映射 ──
116
-
117
- it("映射 toolCalls: ToolCall → ToolCallEntry(name/input 形状转换)", () => {
118
- const calls: ToolCall[] = [
119
- { toolName: "read", args: { path: "/a.txt" } },
120
- { toolName: "bash", args: { command: "ls" }, result: { content: ["ok"] }, isError: false },
121
- ];
122
- const r: SubagentsAgentResult = { ...minimalResult, toolCalls: calls };
123
- const result = mapToWorkflowAgentResult(r);
124
- expect(result.toolCalls).toBeDefined();
125
- expect(result.toolCalls!).toHaveLength(2);
126
- expect(result.toolCalls![0]).toEqual({ name: "read", input: '{"path":"/a.txt"}' });
127
- expect(result.toolCalls![1].name).toBe("bash");
128
- });
129
-
130
- it("映射 toolCalls: args=undefined → input=''", () => {
131
- const calls: ToolCall[] = [{ toolName: "list" }];
132
- const r: SubagentsAgentResult = { ...minimalResult, toolCalls: calls };
133
- const result = mapToWorkflowAgentResult(r);
134
- expect(result.toolCalls![0].input).toBe("");
135
- });
136
-
137
- it("映射 toolCalls: 长 args 截断(>500 chars)", () => {
138
- const longStr = "x".repeat(600);
139
- const calls: ToolCall[] = [{ toolName: "write", args: { content: longStr } }];
140
- const r: SubagentsAgentResult = { ...minimalResult, toolCalls: calls };
141
- const result = mapToWorkflowAgentResult(r);
142
- expect(result.toolCalls![0].input.length).toBeLessThanOrEqual(503); // 500 + "..."
143
- });
144
-
145
- it("映射 toolCalls: 无 toolCalls → undefined", () => {
146
- const r: SubagentsAgentResult = { ...minimalResult, toolCalls: undefined };
147
- const result = mapToWorkflowAgentResult(r);
148
- expect(result.toolCalls).toBeUndefined();
149
- });
150
- });
@@ -1,147 +0,0 @@
1
- // src/__tests__/alive-store.test.ts
2
-
3
- import * as fs from "node:fs";
4
- import * as os from "node:os";
5
- import * as path from "node:path";
6
-
7
- import { afterEach,describe, expect, it } from "vitest";
8
-
9
- import {
10
- isProcessAlive,
11
- readAliveMarker,
12
- removeAliveMarker,
13
- writeAliveMarker,
14
- } from "../alive-store.ts";
15
- import type { AliveMarker } from "../types.ts";
16
-
17
- function makeTmpDir(): string {
18
- return fs.mkdtempSync(path.join(os.tmpdir(), "alive-store-test-"));
19
- }
20
-
21
- describe("alive-store", () => {
22
- let tmpDir: string;
23
-
24
- afterEach(() => {
25
- if (tmpDir) {
26
- fs.rmSync(tmpDir, { recursive: true, force: true });
27
- }
28
- });
29
-
30
- // ── writeAliveMarker + readAliveMarker 往返 ──
31
-
32
- it("write → read round-trip", () => {
33
- tmpDir = makeTmpDir();
34
- const sessionFile = path.join(tmpDir, "session.jsonl");
35
- const marker: AliveMarker = { pid: 12345, id: "bg-1-abc", startedAt: Date.now() };
36
-
37
- writeAliveMarker(sessionFile, marker);
38
- const result = readAliveMarker(sessionFile);
39
-
40
- expect(result).toEqual(marker);
41
- // 验证 sidecar 文件是单行 JSON
42
- const raw = fs.readFileSync(`${sessionFile}.alive`, "utf-8");
43
- expect(raw.endsWith("\n")).toBe(true);
44
- expect(JSON.parse(raw.trim())).toEqual(marker);
45
- });
46
-
47
- // ── readAliveMarker 损坏文件 ──
48
-
49
- it("readAliveMarker returns undefined for corrupted file", () => {
50
- tmpDir = makeTmpDir();
51
- const sessionFile = path.join(tmpDir, "session.jsonl");
52
- fs.writeFileSync(`${sessionFile}.alive`, "not-json", "utf-8");
53
-
54
- expect(readAliveMarker(sessionFile)).toBeUndefined();
55
- });
56
-
57
- it("readAliveMarker returns undefined for structurally invalid JSON", () => {
58
- tmpDir = makeTmpDir();
59
- const sessionFile = path.join(tmpDir, "session.jsonl");
60
- // pid 字段缺失
61
- fs.writeFileSync(`${sessionFile}.alive`, '{"id":"x","startedAt":1}\n', "utf-8");
62
-
63
- expect(readAliveMarker(sessionFile)).toBeUndefined();
64
- });
65
-
66
- it("readAliveMarker returns undefined when file does not exist", () => {
67
- tmpDir = makeTmpDir();
68
- const sessionFile = path.join(tmpDir, "session.jsonl");
69
-
70
- expect(readAliveMarker(sessionFile)).toBeUndefined();
71
- });
72
-
73
- // ── removeAliveMarker ──
74
-
75
- it("removeAliveMarker removes existing sidecar", () => {
76
- tmpDir = makeTmpDir();
77
- const sessionFile = path.join(tmpDir, "session.jsonl");
78
- const marker: AliveMarker = { pid: 1, id: "x", startedAt: 0 };
79
-
80
- writeAliveMarker(sessionFile, marker);
81
- expect(fs.existsSync(`${sessionFile}.alive`)).toBe(true);
82
-
83
- removeAliveMarker(sessionFile);
84
- expect(fs.existsSync(`${sessionFile}.alive`)).toBe(false);
85
- });
86
-
87
- it("removeAliveMarker does not throw when file does not exist", () => {
88
- tmpDir = makeTmpDir();
89
- const sessionFile = path.join(tmpDir, "session.jsonl");
90
-
91
- expect(() => removeAliveMarker(sessionFile)).not.toThrow();
92
- });
93
-
94
- // ── isProcessAlive ──
95
-
96
- it("isProcessAlive returns true for current process", () => {
97
- expect(isProcessAlive(process.pid)).toBe(true);
98
- });
99
-
100
- it("isProcessAlive returns false for non-existent pid", () => {
101
- // pid 0 不存在于用户空间(kill(0,0) 在某些 OS 有特殊语义,用大数更安全)
102
- expect(isProcessAlive(9999999)).toBe(false);
103
- });
104
-
105
- it("isProcessAlive returns true for EPERM (process exists but no permission)", () => {
106
- // 模拟 EPERM:进程存在但无权限发信号
107
- const err = new Error("EPERM") as NodeJS.ErrnoException;
108
- err.code = "EPERM";
109
- const originalKill = process.kill;
110
- process.kill = (_pid: number, _signal?: string | number) => {
111
- throw err;
112
- };
113
- try {
114
- expect(isProcessAlive(12345)).toBe(true);
115
- } finally {
116
- process.kill = originalKill;
117
- }
118
- });
119
-
120
- it("isProcessAlive returns false for ESRCH (no such process)", () => {
121
- // 模拟 ESRCH:进程不存在
122
- const err = new Error("ESRCH") as NodeJS.ErrnoException;
123
- err.code = "ESRCH";
124
- const originalKill = process.kill;
125
- process.kill = (_pid: number, _signal?: string | number) => {
126
- throw err;
127
- };
128
- try {
129
- expect(isProcessAlive(12345)).toBe(false);
130
- } finally {
131
- process.kill = originalKill;
132
- }
133
- });
134
-
135
- it("isProcessAlive returns false for unknown errors", () => {
136
- // 模拟未知错误:保守判死
137
- const originalKill = process.kill;
138
- process.kill = (_pid: number, _signal?: string | number) => {
139
- throw new Error("unknown error");
140
- };
141
- try {
142
- expect(isProcessAlive(12345)).toBe(false);
143
- } finally {
144
- process.kill = originalKill;
145
- }
146
- });
147
- });