@zhushanwen/pi-subagent-workflow 8.6.0 → 8.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/README.md +5 -11
  2. package/package.json +13 -20
  3. package/relay/relay.mjs +1 -1
  4. package/skills/workflow-script-format/SKILL.md +32 -13
  5. package/src/host/__tests__/pi-host.test.ts +235 -0
  6. package/src/host/pi-host.ts +163 -0
  7. package/src/index.ts +141 -138
  8. package/src/injectors/__tests__/engine-awareness.test.ts +292 -0
  9. package/src/injectors/__tests__/engine-section-stability.test.ts +343 -0
  10. package/src/injectors/__tests__/model-list-injector.test.ts +18 -21
  11. package/src/injectors/__tests__/subagent-list-injector.test.ts +59 -19
  12. package/src/injectors/__tests__/workflow-list-injector.test.ts +31 -17
  13. package/src/injectors/engine-awareness.ts +119 -0
  14. package/src/injectors/model-list-injector.ts +15 -58
  15. package/src/injectors/subagent-list-injector.ts +56 -114
  16. package/src/injectors/workflow-list-injector.ts +37 -70
  17. package/src/interface/__tests__/detectors.test.ts +48 -37
  18. package/src/interface/__tests__/subagent-tool-path-guard.test.ts +2 -2
  19. package/src/interface/__tests__/subagent-tool-prompt.test.ts +6 -3
  20. package/src/interface/__tests__/tool-workflow-run-builtin-name.test.ts +216 -0
  21. package/src/interface/__tests__/tool-workflow-script-generate.test.ts +17 -6
  22. package/src/interface/__tests__/tool-workflow-throw-paths.test.ts +38 -2
  23. package/src/interface/bg-notify-render.ts +7 -17
  24. package/src/interface/command-actions.ts +5 -15
  25. package/src/interface/commands.ts +4 -4
  26. package/src/interface/format.ts +17 -6
  27. package/src/interface/gui-mappers.ts +18 -22
  28. package/src/interface/helpers.ts +9 -130
  29. package/src/interface/list-component.ts +5 -5
  30. package/src/interface/list-shared.ts +3 -3
  31. package/src/interface/list-view.ts +3 -3
  32. package/src/interface/subagent-actions.ts +66 -439
  33. package/src/interface/subagent-tool-schema.ts +21 -17
  34. package/src/interface/subagent-tool.ts +12 -7
  35. package/src/interface/subagents.ts +4 -4
  36. package/src/interface/tool-render.ts +37 -15
  37. package/src/interface/tool-workflow-script.ts +34 -76
  38. package/src/interface/tool-workflow.ts +57 -94
  39. package/src/interface/views/WorkflowsView.ts +8 -16
  40. package/src/interface/views/__tests__/WorkflowsView-signature.test.ts +3 -3
  41. package/src/interface/views/__tests__/detail-content-session-file.test.ts +2 -2
  42. package/src/interface/views/detail-content.ts +4 -4
  43. package/src/interface/views/format.ts +23 -62
  44. package/src/{orchestration/jsonl-run-store.ts → jsonl-run-store.ts} +137 -225
  45. package/agents/analyst.md +0 -61
  46. package/agents/coder.md +0 -70
  47. package/agents/debugger.md +0 -67
  48. package/agents/doc-reviewer.md +0 -50
  49. package/agents/explorer.md +0 -64
  50. package/agents/general-purpose.md +0 -32
  51. package/agents/orchestrator.md +0 -63
  52. package/agents/planner.md +0 -54
  53. package/agents/researcher.md +0 -65
  54. package/agents/reviewer.md +0 -74
  55. package/src/execution/__tests__/__fixtures__/notifier-golden-snapshots.json +0 -53
  56. package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +0 -1
  57. package/src/execution/__tests__/agent-registry.test.ts +0 -363
  58. package/src/execution/__tests__/agent-result-mapper.test.ts +0 -150
  59. package/src/execution/__tests__/alive-store.test.ts +0 -147
  60. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  61. package/src/execution/__tests__/before-agent-start-injection.test.ts +0 -132
  62. package/src/execution/__tests__/bg-notify-render.test.ts +0 -329
  63. package/src/execution/__tests__/channel-registry-handshake.test.ts +0 -243
  64. package/src/execution/__tests__/chat-engine-routing.test.ts +0 -601
  65. package/src/execution/__tests__/chatmode-first-round-closure-service.test.ts +0 -365
  66. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -190
  67. package/src/execution/__tests__/chatmode-round-notify-real-chain.test.ts +0 -215
  68. package/src/execution/__tests__/concurrency-pool.test.ts +0 -250
  69. package/src/execution/__tests__/config.test.ts +0 -110
  70. package/src/execution/__tests__/conversation-wiring.test.ts +0 -198
  71. package/src/execution/__tests__/crash-recovery.test.ts +0 -320
  72. package/src/execution/__tests__/delivery-methods.test.ts +0 -422
  73. package/src/execution/__tests__/dialog-queue.test.ts +0 -299
  74. package/src/execution/__tests__/epipe-fallback.test.ts +0 -241
  75. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -243
  76. package/src/execution/__tests__/execute-nesting.test.ts +0 -323
  77. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -200
  78. package/src/execution/__tests__/execution-record.test.ts +0 -1394
  79. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +0 -171
  80. package/src/execution/__tests__/finalize-record.test.ts +0 -368
  81. package/src/execution/__tests__/finalized-marker.test.ts +0 -82
  82. package/src/execution/__tests__/format-schema-instruction.test.ts +0 -169
  83. package/src/execution/__tests__/format.test.ts +0 -458
  84. package/src/execution/__tests__/gc-timer.test.ts +0 -184
  85. package/src/execution/__tests__/get-record-for-action-restart.test.ts +0 -254
  86. package/src/execution/__tests__/gui-mode-dispatch.test.ts +0 -59
  87. package/src/execution/__tests__/helpers/mock-extension-api.ts +0 -30
  88. package/src/execution/__tests__/helpers/spawn-mock.ts +0 -242
  89. package/src/execution/__tests__/host-mode.test.ts +0 -87
  90. package/src/execution/__tests__/index-session-start-identity.test.ts +0 -371
  91. package/src/execution/__tests__/index-session-start.test.ts +0 -672
  92. package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
  93. package/src/execution/__tests__/lifecycle-manager.test.ts +0 -383
  94. package/src/execution/__tests__/lifecycle-predicates.test.ts +0 -116
  95. package/src/execution/__tests__/list-component.test.ts +0 -401
  96. package/src/execution/__tests__/list-fields.test.ts +0 -140
  97. package/src/execution/__tests__/manifest-parentid.test.ts +0 -117
  98. package/src/execution/__tests__/model-resolver.test.ts +0 -465
  99. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +0 -287
  100. package/src/execution/__tests__/nested-visibility.test.ts +0 -325
  101. package/src/execution/__tests__/notifier-flush.test.ts +0 -612
  102. package/src/execution/__tests__/notifier-golden-snapshot.test.ts +0 -261
  103. package/src/execution/__tests__/notify-ledger.test.ts +0 -826
  104. package/src/execution/__tests__/one-shot-upgrade.test.ts +0 -205
  105. package/src/execution/__tests__/output-collector.test.ts +0 -358
  106. package/src/execution/__tests__/parent-child-matrix.test.ts +0 -336
  107. package/src/execution/__tests__/path-encoding.test.ts +0 -104
  108. package/src/execution/__tests__/pi-invocation.test.ts +0 -134
  109. package/src/execution/__tests__/record-store.test.ts +0 -1057
  110. package/src/execution/__tests__/records-cwd-isolation.test.ts +0 -91
  111. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +0 -339
  112. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -273
  113. package/src/execution/__tests__/relay-agent.test.ts +0 -448
  114. package/src/execution/__tests__/relay-env.test.ts +0 -42
  115. package/src/execution/__tests__/resource-policy.test.ts +0 -109
  116. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  117. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -267
  118. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -253
  119. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -687
  120. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  121. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  122. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  123. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +0 -199
  124. package/src/execution/__tests__/sdk-contract.test.ts +0 -273
  125. package/src/execution/__tests__/session-context-resolver.test.ts +0 -167
  126. package/src/execution/__tests__/session-file-gc.test.ts +0 -293
  127. package/src/execution/__tests__/session-pending.test.ts +0 -197
  128. package/src/execution/__tests__/session-reconstructor.test.ts +0 -379
  129. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -178
  130. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -350
  131. package/src/execution/__tests__/session-start-reaper.test.ts +0 -233
  132. package/src/execution/__tests__/spawn-args.test.ts +0 -445
  133. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -189
  134. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  135. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -207
  136. package/src/execution/__tests__/spawned-children.test.ts +0 -92
  137. package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
  138. package/src/execution/__tests__/startup-config-declaration.test.ts +0 -35
  139. package/src/execution/__tests__/status-refactor.test.ts +0 -345
  140. package/src/execution/__tests__/stdin-writer.test.ts +0 -463
  141. package/src/execution/__tests__/stream-sink-retirement.test.ts +0 -261
  142. package/src/execution/__tests__/subagent-service-abort.test.ts +0 -60
  143. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -629
  144. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +0 -180
  145. package/src/execution/__tests__/subagent-service.test.ts +0 -788
  146. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -310
  147. package/src/execution/__tests__/subprocess-agent-runner.test.ts +0 -599
  148. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  149. package/src/execution/__tests__/timeout-integration.test.ts +0 -615
  150. package/src/execution/__tests__/tombstone-store.test.ts +0 -73
  151. package/src/execution/__tests__/tool-action.test.ts +0 -476
  152. package/src/execution/__tests__/truncline-snapshot.test.ts +0 -81
  153. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  154. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  155. package/src/execution/__tests__/ui-channels.test.ts +0 -187
  156. package/src/execution/__tests__/ui-interaction-model.test.ts +0 -67
  157. package/src/execution/__tests__/ui-request-handler-factory.test.ts +0 -370
  158. package/src/execution/__tests__/ui-request-handler.test.ts +0 -204
  159. package/src/execution/__tests__/ui-request-observability.test.ts +0 -114
  160. package/src/execution/__tests__/ui-request-queue.test.ts +0 -133
  161. package/src/execution/__tests__/worktree-manager.test.ts +0 -633
  162. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -229
  163. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +0 -181
  164. package/src/execution/__tests__/worktree-registry.test.ts +0 -199
  165. package/src/execution/agent-registry.ts +0 -199
  166. package/src/execution/agent-result-mapper.ts +0 -90
  167. package/src/execution/alive-store.ts +0 -92
  168. package/src/execution/argv-mirror.ts +0 -113
  169. package/src/execution/best-effort.ts +0 -38
  170. package/src/execution/channel-registry-access.ts +0 -144
  171. package/src/execution/concurrency-pool.ts +0 -116
  172. package/src/execution/config.ts +0 -96
  173. package/src/execution/dialog-queue.ts +0 -330
  174. package/src/execution/engine/__tests__/common/data-dir.test.ts +0 -53
  175. package/src/execution/engine/__tests__/common/errors.test.ts +0 -132
  176. package/src/execution/engine/__tests__/common/event-journal.test.ts +0 -177
  177. package/src/execution/engine/__tests__/common/kill-chain.test.ts +0 -192
  178. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +0 -81
  179. package/src/execution/engine/__tests__/common/persona-router.test.ts +0 -123
  180. package/src/execution/engine/__tests__/common/pool-manager.test.ts +0 -154
  181. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  182. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  183. package/src/execution/engine/__tests__/conformance/agent-event-invariants.ts +0 -141
  184. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +0 -109
  185. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +0 -101
  186. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +0 -77
  187. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +0 -104
  188. package/src/execution/engine/__tests__/conformance/contract.relay.test.ts +0 -342
  189. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +0 -201
  190. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +0 -76
  191. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +0 -79
  192. package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -87
  193. package/src/execution/engine/__tests__/engines-declaration.test.ts +0 -36
  194. package/src/execution/engine/__tests__/model-prompt.test.ts +0 -85
  195. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  196. package/src/execution/engine/__tests__/registry.test.ts +0 -120
  197. package/src/execution/engine/__tests__/routing.test.ts +0 -231
  198. package/src/execution/engine/common/data-dir.ts +0 -62
  199. package/src/execution/engine/common/errors.ts +0 -183
  200. package/src/execution/engine/common/event-journal.ts +0 -254
  201. package/src/execution/engine/common/journal-replay.ts +0 -62
  202. package/src/execution/engine/common/kill-chain.ts +0 -221
  203. package/src/execution/engine/common/nesting-guard.ts +0 -50
  204. package/src/execution/engine/common/persona-router.ts +0 -108
  205. package/src/execution/engine/common/pool-manager.ts +0 -226
  206. package/src/execution/engine/common/schema-emulation.ts +0 -189
  207. package/src/execution/engine/common/session-view-projection.ts +0 -51
  208. package/src/execution/engine/engine-discovery.ts +0 -65
  209. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -469
  210. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  211. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  212. package/src/execution/engine/engines/pi/pi-engine.ts +0 -415
  213. package/src/execution/engine/engines/pi/reader.ts +0 -48
  214. package/src/execution/engine/engines/pi/registration.ts +0 -35
  215. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  216. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  217. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  218. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -246
  219. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -228
  220. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  221. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -64
  222. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -127
  223. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -580
  224. package/src/execution/engine/engines/zcode/constants.ts +0 -43
  225. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -39
  226. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  227. package/src/execution/engine/engines/zcode/parser.ts +0 -436
  228. package/src/execution/engine/engines/zcode/preparer.ts +0 -363
  229. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  230. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  231. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -658
  232. package/src/execution/engine/host-task-spec.ts +0 -47
  233. package/src/execution/engine/model-prompt.ts +0 -59
  234. package/src/execution/engine/paths.ts +0 -42
  235. package/src/execution/engine/port.ts +0 -153
  236. package/src/execution/engine/registry.ts +0 -123
  237. package/src/execution/engine/routing.ts +0 -218
  238. package/src/execution/engine/types.ts +0 -309
  239. package/src/execution/execute-options-mapper.ts +0 -112
  240. package/src/execution/execution-record.ts +0 -965
  241. package/src/execution/finalize-record.ts +0 -251
  242. package/src/execution/finalized-marker.ts +0 -51
  243. package/src/execution/get-state-handshake.ts +0 -104
  244. package/src/execution/host-mode.ts +0 -56
  245. package/src/execution/idle-gc.ts +0 -47
  246. package/src/execution/lifecycle-manager.ts +0 -513
  247. package/src/execution/lifecycle-predicates.ts +0 -65
  248. package/src/execution/manifest-store.ts +0 -256
  249. package/src/execution/model-config-service.ts +0 -219
  250. package/src/execution/model-resolver.ts +0 -248
  251. package/src/execution/notifier.ts +0 -330
  252. package/src/execution/notify-ledger.ts +0 -580
  253. package/src/execution/output-collector.ts +0 -228
  254. package/src/execution/path-encoding.ts +0 -60
  255. package/src/execution/pi-invocation.ts +0 -120
  256. package/src/execution/record-entry.ts +0 -132
  257. package/src/execution/record-store.ts +0 -1234
  258. package/src/execution/relay-env.ts +0 -37
  259. package/src/execution/session-context-resolver.ts +0 -64
  260. package/src/execution/session-file-gc.ts +0 -120
  261. package/src/execution/session-pending.ts +0 -164
  262. package/src/execution/session-reconstructor.ts +0 -678
  263. package/src/execution/session-runner.ts +0 -1781
  264. package/src/execution/sessions-index.ts +0 -304
  265. package/src/execution/spawn-event-adapter.ts +0 -363
  266. package/src/execution/stdin-writer.ts +0 -198
  267. package/src/execution/stream-sink.ts +0 -126
  268. package/src/execution/subagent-service.ts +0 -2141
  269. package/src/execution/subprocess-agent-runner.ts +0 -317
  270. package/src/execution/temp-prompt.ts +0 -62
  271. package/src/execution/tombstone-store.ts +0 -72
  272. package/src/execution/turn-limiter.ts +0 -102
  273. package/src/execution/types.ts +0 -973
  274. package/src/execution/ui-channels.ts +0 -216
  275. package/src/execution/ui-interaction-model.ts +0 -48
  276. package/src/execution/ui-request-handler-factory.ts +0 -212
  277. package/src/execution/ui-request-observability.ts +0 -81
  278. package/src/execution/ui-request-queue.ts +0 -184
  279. package/src/execution/worktree-manager.ts +0 -688
  280. package/src/execution/worktree-registry.ts +0 -222
  281. package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +0 -349
  282. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +0 -202
  283. package/src/orchestration/__tests__/agent-call-stream.test.ts +0 -152
  284. package/src/orchestration/__tests__/args-validator.test.ts +0 -143
  285. package/src/orchestration/__tests__/config-loader.test.ts +0 -503
  286. package/src/orchestration/__tests__/error-recovery-handlers.test.ts +0 -809
  287. package/src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts +0 -405
  288. package/src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts +0 -56
  289. package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +0 -166
  290. package/src/orchestration/__tests__/execute-agent-call.test.ts +0 -451
  291. package/src/orchestration/__tests__/jsonl-run-store-corrupt-entry.test.ts +0 -150
  292. package/src/orchestration/__tests__/jsonl-run-store-loadall-sources.test.ts +0 -171
  293. package/src/orchestration/__tests__/jsonl-run-store-retention.test.ts +0 -202
  294. package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +0 -1030
  295. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -600
  296. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +0 -96
  297. package/src/orchestration/__tests__/lifecycle.test.ts +0 -659
  298. package/src/orchestration/__tests__/non-cloneable-return-e2e.test.ts +0 -95
  299. package/src/orchestration/__tests__/review-fix-loop-e2e.test.ts +0 -2025
  300. package/src/orchestration/__tests__/script-lint.test.ts +0 -831
  301. package/src/orchestration/__tests__/skill-discovery.test.ts +0 -201
  302. package/src/orchestration/__tests__/test-mocks.ts +0 -197
  303. package/src/orchestration/__tests__/worker-exit-without-result.test.ts +0 -368
  304. package/src/orchestration/__tests__/worker-host.test.ts +0 -120
  305. package/src/orchestration/__tests__/worker-returnmeta-passthrough.test.ts +0 -164
  306. package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +0 -563
  307. package/src/orchestration/__tests__/worker-script-builder.test.ts +0 -309
  308. package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +0 -129
  309. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +0 -317
  310. package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +0 -110
  311. package/src/orchestration/__tests__/workflows-e2e.test.ts +0 -537
  312. package/src/orchestration/agent-opts-resolver.ts +0 -174
  313. package/src/orchestration/args-validator.ts +0 -127
  314. package/src/orchestration/config-loader.ts +0 -315
  315. package/src/orchestration/error-recovery.ts +0 -1018
  316. package/src/orchestration/execute-agent-call.ts +0 -256
  317. package/src/orchestration/launcher.ts +0 -455
  318. package/src/orchestration/lifecycle.ts +0 -399
  319. package/src/orchestration/models/__tests__/budget.test.ts +0 -307
  320. package/src/orchestration/models/__tests__/trace.test.ts +0 -408
  321. package/src/orchestration/models/agent-call.ts +0 -83
  322. package/src/orchestration/models/budget.ts +0 -118
  323. package/src/orchestration/models/ports.ts +0 -164
  324. package/src/orchestration/models/run-runtime.ts +0 -104
  325. package/src/orchestration/models/run-spec.ts +0 -83
  326. package/src/orchestration/models/run-state.ts +0 -44
  327. package/src/orchestration/models/trace.ts +0 -183
  328. package/src/orchestration/models/types.ts +0 -301
  329. package/src/orchestration/models/workflow-run.ts +0 -254
  330. package/src/orchestration/models/workflow-script-registry.ts +0 -35
  331. package/src/orchestration/models/workflow-script.ts +0 -117
  332. package/src/orchestration/script-lint.ts +0 -766
  333. package/src/orchestration/skill-discovery.ts +0 -115
  334. package/src/orchestration/worker-handle.ts +0 -115
  335. package/src/orchestration/worker-host.ts +0 -98
  336. package/src/orchestration/worker-script-builder.ts +0 -421
  337. package/src/orchestration/workflow-files.ts +0 -85
  338. package/src/orchestration/workflow-script-registry-impl.ts +0 -133
  339. package/src/shared/__tests__/agent-ref.test.ts +0 -34
  340. package/src/shared/__tests__/meta-parser.test.ts +0 -304
  341. package/src/shared/__tests__/model-ref.test.ts +0 -306
  342. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -280
  343. package/src/shared/__tests__/resource-discovery.test.ts +0 -736
  344. package/src/shared/__tests__/resource-meta.test.ts +0 -51
  345. package/src/shared/__tests__/schema-jsonify.test.ts +0 -81
  346. package/src/shared/__tests__/timer-delay.test.ts +0 -61
  347. package/src/shared/agent-event.ts +0 -13
  348. package/src/shared/agent-ref.ts +0 -57
  349. package/src/shared/meta-parser.ts +0 -261
  350. package/src/shared/model-ref.ts +0 -286
  351. package/src/shared/resource-discovery.ts +0 -811
  352. package/src/shared/resource-meta.ts +0 -65
  353. package/src/shared/schema-env.ts +0 -44
  354. package/src/shared/schema-jsonify.ts +0 -58
  355. package/src/shared/timer-delay.ts +0 -54
  356. package/src/shared/xml-injection.ts +0 -35
  357. package/workflows/README.md +0 -81
  358. package/workflows/_shared/agent-refs.cjs +0 -40
  359. package/workflows/chain.js +0 -131
  360. package/workflows/map-reduce.js +0 -174
  361. package/workflows/parallel.js +0 -148
  362. package/workflows/review-fix-loop-utils.cjs +0 -1309
  363. package/workflows/review-fix-loop.js +0 -1404
  364. package/workflows/scatter-gather.js +0 -178
@@ -1,476 +0,0 @@
1
- // src/__tests__/tool-action.test.ts
2
- //
3
- // tool action 路由 + adapter 出参结构测试(AC-2/AC-3/AC-9)。
4
- // 用 stub SubagentService(不依赖真实 SDK),测 handler + adapter 纯逻辑。
5
-
6
- import { describe, expect, it, vi } from "vitest";
7
-
8
- import { adapter, cancelHandler, listHandler, startHandler } from "../../interface/subagent-actions.ts";
9
- import type { SubagentService } from "../subagent-service.ts";
10
- import type {
11
- ExecutionHandle,
12
- RecordSnapshot,
13
- SubagentRecord,
14
- SubagentToolDetails,
15
- } from "../types.ts";
16
-
17
- // ── stub 工厂 ──
18
-
19
- function makeDetails(over: Partial<SubagentToolDetails> = {}): SubagentToolDetails {
20
- return {
21
- status: "closed",
22
- mode: "background",
23
- agent: "worker",
24
- model: "test/model",
25
- thinkingLevel: undefined,
26
- slug: "test-slug",
27
- turns: 1,
28
- totalTokens: 10,
29
- elapsedSeconds: 1,
30
- eventLog: [],
31
- result: "ok",
32
- ...over,
33
- };
34
- }
35
-
36
- function makeSnapshot(over: Partial<RecordSnapshot> = {}): RecordSnapshot {
37
- return {
38
- id: "run-1",
39
- agent: "worker",
40
- model: "test/model",
41
- thinkingLevel: undefined,
42
- mode: "background",
43
- task: "t",
44
- slug: "test-slug",
45
- status: "closed",
46
- eventLog: [],
47
- turns: 1,
48
- totalTokens: 10,
49
- startedAt: 1000,
50
- endedAt: 2000,
51
- result: "ok",
52
- error: undefined,
53
- sessionFile: undefined,
54
- ...over,
55
- };
56
- }
57
-
58
- function makeService(over: Partial<SubagentService> = {}): SubagentService {
59
- return {
60
- execute: vi.fn(),
61
- findRecord: vi.fn(() => undefined),
62
- cancel: vi.fn(() => false),
63
- collectRecords: vi.fn(() => [] as SubagentRecord[]),
64
- // [perf] listHandler 逐项 enrich 会调 getFullRecord;mock 回 undefined → 调用方回退 light record
65
- getFullRecord: vi.fn(() => undefined as SubagentRecord | undefined),
66
- ...over,
67
- } as SubagentService;
68
- }
69
-
70
- // ============================================================
71
- // startHandler
72
- // ============================================================
73
- describe("startHandler", () => {
74
- it("缺 input → throw + Correct 正例", async () => {
75
- const svc = makeService();
76
- await expect(startHandler(svc, undefined, undefined)).rejects.toThrow(/task and slug/);
77
- // Correct 正例存在(让弱模型撞错后能直接照抄平铺形态)
78
- await expect(startHandler(svc, undefined, undefined)).rejects.toThrow(/Correct: \{"action":"start"/);
79
- });
80
-
81
- it("task 空白 → throw + Correct 正例", async () => {
82
- const svc = makeService();
83
- await expect(startHandler(svc, { task: " ", slug: "x" }, undefined)).rejects.toThrow(/task is required/);
84
- await expect(startHandler(svc, { task: " ", slug: "x" }, undefined)).rejects.toThrow(/Correct: \{"action":"start"/);
85
- });
86
-
87
- it("slug 缺失 → throw + Correct 正例", async () => {
88
- const svc = makeService();
89
- await expect(startHandler(svc, { task: "ok" }, undefined)).rejects.toThrow(/slug is required/);
90
- await expect(startHandler(svc, { task: "ok" }, undefined)).rejects.toThrow(/Correct: \{"action":"start"/);
91
- });
92
-
93
- it("slug 空白 → throw + Correct 正例", async () => {
94
- const svc = makeService();
95
- await expect(startHandler(svc, { task: "ok", slug: " " }, undefined)).rejects.toThrow(/slug is required/);
96
- await expect(startHandler(svc, { task: "ok", slug: " " }, undefined)).rejects.toThrow(/Correct: \{"action":"start"/);
97
- });
98
-
99
- it("slug 超 35 字符 → throw", async () => {
100
- const svc = makeService();
101
- await expect(
102
- startHandler(svc, { task: "ok", slug: "a".repeat(36) }, undefined),
103
- ).rejects.toThrow(/≤35 chars/);
104
- });
105
-
106
- it("background 启动 → kind=bg + bgResponse.message 含 detached + notifyContract 恒值", async () => {
107
- const svc = makeService({
108
- execute: vi.fn(async (): Promise<ExecutionHandle> => ({
109
- mode: "background",
110
- subagentId: "bg-1-123",
111
- sessionFile: undefined,
112
- details: makeDetails({ status: "running", mode: "background" }),
113
- })),
114
- });
115
- const r = await startHandler(svc, { task: "long", slug: "long-running" }, undefined);
116
- expect(r.kind).toBe("bg");
117
- if (r.kind !== "bg") return;
118
- expect(r.subagentId).toBe("bg-1-123");
119
- expect(r.response.message).toMatch(/detached/);
120
- // [U1] 通知投递契约回显位(U2 账本兑现)
121
- expect(r.response.notifyContract).toBe("ledger+at-least-once");
122
- });
123
-
124
- it("[U1] start 返回值 model 为 registry 全等回显(透传 handle.details.model)", async () => {
125
- const svc = makeService({
126
- execute: vi.fn(async (): Promise<ExecutionHandle> => ({
127
- mode: "background",
128
- subagentId: "bg-2-456",
129
- sessionFile: undefined,
130
- // record.model = resolved(裁决放行条目)拼接的 "provider/id",保留 registry 大小写
131
- details: makeDetails({ status: "running", mode: "background", model: "zai-coding-cn/GLM-5.3-Flash" }),
132
- })),
133
- });
134
- const r = await startHandler(svc, { task: "t", slug: "s" }, undefined);
135
- expect(r.model).toBe("zai-coding-cn/GLM-5.3-Flash");
136
- // adapter 外层 result 同源回显
137
- const toolResult = adapter({ action: "start", domain: r });
138
- const result = toolResult.details;
139
- if (result.action !== "start") throw new Error("expected start variant");
140
- expect(result.model).toBe("zai-coding-cn/GLM-5.3-Flash");
141
- // LLM content JSON 同源(与 details 一致)
142
- const contentJson = JSON.parse(toolResult.content[0]!.type === "text" ? toolResult.content[0].text : "{}");
143
- expect(contentJson.model).toBe("zai-coding-cn/GLM-5.3-Flash");
144
- expect(contentJson.bgResponse.notifyContract).toBe("ledger+at-least-once");
145
- });
146
-
147
- it("[U1] model 非全等 → 裁决错误向上传播(无 bgResponse 产出,execute 不重试)", async () => {
148
- // 裁决发生在 service.execute 内部步骤 1(IDENTITY 解析 → resolveModel),在 record
149
- // 创建 / runSpawn 之前——错误直接向上传播为 tool isError。resolveModel 层的拒单
150
- // 行为(含 P-A2 双路径)由 model-ref.test.ts + model-resolver.test.ts 锁定;本用例
151
- // 锁定 handler 层传播语义:异常穿越 startHandler,不产出任何受理响应。
152
- const svc = makeService({
153
- execute: vi.fn(async () => {
154
- throw new Error(
155
- 'Model "zai-coding-cn/glm-5.3-flash" (paramOverride) is not a registry entry. ' +
156
- "Did you mean one of these?\n zai-coding-cn/GLM-5.3-Flash",
157
- );
158
- }),
159
- });
160
- await expect(
161
- startHandler(svc, { task: "t", slug: "s", model: "zai-coding-cn/glm-5.3-flash" }, undefined),
162
- ).rejects.toThrow(/is not a registry entry.*Did you mean/s);
163
- expect(svc.execute).toHaveBeenCalledTimes(1);
164
- });
165
- });
166
-
167
- // ============================================================
168
- // listHandler
169
- // ============================================================
170
- describe("listHandler", () => {
171
- it("空 → running:0, items:[]", () => {
172
- const svc = makeService({ collectRecords: vi.fn(() => [] as SubagentRecord[]) });
173
- const r = listHandler(svc, undefined);
174
- expect(r.response).toEqual({ running: 0, items: [] });
175
- });
176
-
177
- it("limit 夹紧 [1,100]——collectRecords 收到夹紧后的值(C1 回归)", () => {
178
- const collect = vi.fn(() => [] as SubagentRecord[]);
179
- const svc = makeService({ collectRecords: collect });
180
- // includeFinished=true 时 filter="all",验证 limit 夹紧:
181
- // 0 → 1
182
- listHandler(svc, { includeFinished: true, limit: 0 });
183
- expect(collect).toHaveBeenLastCalledWith(1, "all");
184
- // 100000 → 100
185
- listHandler(svc, { includeFinished: true, limit: 100000 });
186
- expect(collect).toHaveBeenLastCalledWith(100, "all");
187
- // undefined → 20(默认)
188
- listHandler(svc, { includeFinished: true });
189
- expect(collect).toHaveBeenLastCalledWith(20, "all");
190
- // 负数 → 1
191
- listHandler(svc, { includeFinished: true, limit: -5 });
192
- expect(collect).toHaveBeenLastCalledWith(1, "all");
193
- });
194
-
195
- it("includeFinished=false → collectRecords 收到 filter='running'(C2 回归)", () => {
196
- const collect = vi.fn(() => [] as SubagentRecord[]);
197
- const svc = makeService({ collectRecords: collect });
198
- // includeFinished=false → filter="running"(防截断下沉到 store)
199
- listHandler(svc, { includeFinished: false, limit: 5 });
200
- expect(collect).toHaveBeenLastCalledWith(5, "running");
201
- // includeFinished=true → filter="all"
202
- listHandler(svc, { includeFinished: true, limit: 5 });
203
- expect(collect).toHaveBeenLastCalledWith(5, "all");
204
- });
205
-
206
- it("includeFinished=false → collectRecords 返回 running-only(过滤在 store 层)", () => {
207
- // store 层已过滤,listHandler 只做透传——mock 返回的即 running-only。
208
- const records: SubagentRecord[] = [
209
- { id: "r1", agent: "w", status: "running", mode: "background", startedAt: 1, endedAt: undefined, turns: 0, totalTokens: 0, model: "m", thinkingLevel: undefined, eventLog: [] },
210
- ];
211
- const svc = makeService({ collectRecords: vi.fn(() => records) });
212
- const r = listHandler(svc, { includeFinished: false });
213
- expect(r.response.items).toHaveLength(1);
214
- expect(r.response.items[0].subagentId).toBe("r1");
215
- expect(r.response.running).toBe(1);
216
- });
217
-
218
- it("item 8 字段齐全(含 duration 实时计算)", () => {
219
- const records: SubagentRecord[] = [
220
- { id: "r1", agent: "w", status: "closed", mode: "background", startedAt: 1000, endedAt: 2500, turns: 2, totalTokens: 50, model: "m", thinkingLevel: "high", eventLog: [], sessionFile: "x.jsonl" },
221
- ];
222
- const svc = makeService({ collectRecords: vi.fn(() => records) });
223
- const r = listHandler(svc, { includeFinished: true });
224
- const item = r.response.items[0];
225
- expect(item).toMatchObject({
226
- subagentId: "r1", agent: "w", status: "closed", mode: "background",
227
- duration: 1, model: "m", totalTokens: 50, sessionFile: "x.jsonl",
228
- });
229
- });
230
-
231
- it("items 超过 limit → 截断在 store 层(listHandler 透传 limit)", () => {
232
- // 截断责任在 collectRecords(store 层),listHandler 只透传 limit + map。
233
- // mock 返回 3 条(模拟 store 未截断),验证 listHandler 不自行截断——全量透传。
234
- const records: SubagentRecord[] = [
235
- { id: "r1", agent: "w", status: "running", mode: "background", startedAt: 1, endedAt: undefined, turns: 0, totalTokens: 0, model: "m", thinkingLevel: undefined, eventLog: [] },
236
- { id: "r2", agent: "w", status: "running", mode: "background", startedAt: 2, endedAt: undefined, turns: 0, totalTokens: 0, model: "m", thinkingLevel: undefined, eventLog: [] },
237
- { id: "r3", agent: "w", status: "running", mode: "background", startedAt: 3, endedAt: undefined, turns: 0, totalTokens: 0, model: "m", thinkingLevel: undefined, eventLog: [] },
238
- ];
239
- const collect = vi.fn(() => records);
240
- const svc = makeService({ collectRecords: collect });
241
- const r = listHandler(svc, { includeFinished: true, limit: 2 });
242
- // listHandler 透传 collectRecords 的结果(截断是 store 的责任)。
243
- expect(r.response.items).toHaveLength(3);
244
- // 验证 limit 确实透传给了 collectRecords。
245
- expect(collect).toHaveBeenCalledWith(2, "all");
246
- });
247
-
248
- // TC-2: running 态实时 duration(Date.now()-startedAt)随时间增长,
249
- // 区别于终态 endedAt-startedAt。喂给 live TUI,更易出 bug。
250
- it("running 态 duration 实时计算:两次 list 间隔 2s,duration 差 = 2(TC-2)", () => {
251
- vi.useFakeTimers({ now: 10_000 });
252
- try {
253
- const records: SubagentRecord[] = [
254
- { id: "r1", agent: "w", status: "running", mode: "background", startedAt: 7_000, endedAt: undefined, turns: 0, totalTokens: 0, model: "m", thinkingLevel: undefined, eventLog: [] },
255
- ];
256
- const svc = makeService({ collectRecords: vi.fn(() => records) });
257
- const r1 = listHandler(svc, { includeFinished: true });
258
- expect(r1.response.items[0].duration).toBe(3); // (10-7)s
259
- vi.advanceTimersByTime(2_000);
260
- const r2 = listHandler(svc, { includeFinished: true });
261
- expect(r2.response.items[0].duration).toBe(5); // (12-7)s
262
- } finally {
263
- vi.useRealTimers();
264
- }
265
- });
266
-
267
- // TC-3: listHandler 保持 collectRecords 返回的顺序(排序责任在 service 层,
268
- // listHandler 是顺序透传)。故意传入反序 list 验证 listHandler 不自行排序。
269
- it("保持 collectRecords 顺序,不自行重排(TC-3)", () => {
270
- // 故意按 startedAt 升序(与 desc 相反)
271
- const records: SubagentRecord[] = [
272
- { id: "old", agent: "w", status: "running", mode: "background", startedAt: 1, endedAt: undefined, turns: 0, totalTokens: 0, model: "m", thinkingLevel: undefined, eventLog: [] },
273
- { id: "new", agent: "w", status: "running", mode: "background", startedAt: 5, endedAt: undefined, turns: 0, totalTokens: 0, model: "m", thinkingLevel: undefined, eventLog: [] },
274
- ];
275
- const svc = makeService({ collectRecords: vi.fn(() => records) });
276
- const r = listHandler(svc, { includeFinished: true });
277
- expect(r.response.items.map((i) => i.subagentId)).toEqual(["old", "new"]);
278
- });
279
- });
280
-
281
- // ============================================================
282
- // cancelHandler
283
- // ============================================================
284
- describe("cancelHandler", () => {
285
- it("缺 subagentId → throw", async () => {
286
- const svc = makeService();
287
- await expect(cancelHandler(svc, undefined)).rejects.toThrow(/subagentId is required/);
288
- await expect(cancelHandler(svc, { subagentId: " " })).rejects.toThrow(/subagentId is required/);
289
- });
290
-
291
- it("id 不存在 → throw No subagent record", async () => {
292
- const svc = makeService({ findRecord: vi.fn(() => undefined) });
293
- await expect(cancelHandler(svc, { subagentId: "nope" })).rejects.toThrow(/No subagent record with id "nope"/);
294
- });
295
-
296
- it("[S-19] id 属树内其他进程的 running record(磁盘可见、本进程内存无)→ throw 跨进程专属消息", async () => {
297
- // MF-1 全树可见后:子进程 list 能看到父/兄弟进程的 running record,但 cancel 只作用于
298
- // 本进程内存。旧消息「may have finished」误导(该 record 未 finished、正被列出)。
299
- const foreign: SubagentRecord = {
300
- id: "bg-foreign", agent: "w", status: "running", mode: "background", startedAt: 1,
301
- endedAt: undefined, turns: 0, totalTokens: 0, model: "m", thinkingLevel: undefined, eventLog: [],
302
- };
303
- const svc = makeService({
304
- findRecord: vi.fn(() => undefined),
305
- collectRecords: vi.fn(() => [foreign] as SubagentRecord[]),
306
- });
307
- await expect(cancelHandler(svc, { subagentId: "bg-foreign" })).rejects.toThrow(/owned by another process in the tree/);
308
- });
309
-
310
- it("[S-19] id 在树内但已终态(磁盘可见 done)→ 仍用 may have finished 消息", async () => {
311
- const done: SubagentRecord = {
312
- id: "bg-done", agent: "w", status: "closed", mode: "background", startedAt: 1,
313
- endedAt: 2, turns: 0, totalTokens: 0, model: "m", thinkingLevel: undefined, eventLog: [],
314
- };
315
- const svc = makeService({
316
- findRecord: vi.fn(() => undefined),
317
- collectRecords: vi.fn(() => [done] as SubagentRecord[]),
318
- });
319
- await expect(cancelHandler(svc, { subagentId: "bg-done" })).rejects.toThrow(/may have finished/);
320
- });
321
-
322
- it("已终态(cancel 返回 false)→ throw could not be cancelled", async () => {
323
- const svc = makeService({
324
- findRecord: vi.fn(() => makeSnapshot({ id: "bg-1", mode: "background", status: "closed" })),
325
- cancel: vi.fn(() => false),
326
- });
327
- await expect(cancelHandler(svc, { subagentId: "bg-1" })).rejects.toThrow(/could not be cancelled.*status: closed/);
328
- });
329
-
330
- it("成功 → cancelled:true", async () => {
331
- const svc = makeService({
332
- findRecord: vi.fn(() => makeSnapshot({ id: "bg-1", mode: "background", status: "running" })),
333
- cancel: vi.fn(() => true),
334
- });
335
- const r = await cancelHandler(svc, { subagentId: "bg-1" });
336
- expect(r.subagentId).toBe("bg-1");
337
- expect(r.response.cancelled).toBe(true);
338
- });
339
-
340
- // TC-1: 并发 CAS 场景——同一 id 两次 cancel,第一次抢锁成功,第二次 CAS 失败后
341
- // re-query 到终态。覆盖 cancelHandler 的 re-query 分支(subagent-actions.ts:267-272)。
342
- it("并发 CAS:两次 cancel 同一 id,第二次 CAS 失败 re-query 到终态", async () => {
343
- const running = makeSnapshot({ id: "bg-cas", mode: "background", status: "running" });
344
- const done = makeSnapshot({ id: "bg-cas", mode: "background", status: "closed" });
345
-
346
- let cancelCalls = 0;
347
- const svc = makeService({
348
- // findRecord 调用序列:
349
- // call 1: 第一次 cancel 初始查询 → running
350
- // call 2: 第二次 cancel 初始查询 → running(快照尚未过期)
351
- // call 3: 第二次 cancel CAS 失败后 re-query → done(状态已变)
352
- findRecord: vi.fn()
353
- .mockReturnValueOnce(running)
354
- .mockReturnValueOnce(running)
355
- .mockReturnValueOnce(done),
356
- cancel: vi.fn(() => {
357
- cancelCalls++;
358
- return cancelCalls === 1; // 第一次 true,第二次 false(CAS 失败)
359
- }),
360
- });
361
-
362
- // 第一次 cancel:抢锁成功
363
- const r1 = await cancelHandler(svc, { subagentId: "bg-cas" });
364
- expect(r1.response.cancelled).toBe(true);
365
-
366
- // 第二次 cancel:CAS 失败,re-query 返回 closed(不是初始的 running)
367
- await expect(cancelHandler(svc, { subagentId: "bg-cas" }))
368
- .rejects.toThrow(/could not be cancelled.*status: closed/);
369
-
370
- // 验证 re-query 确实发生(3 次 findRecord:1 初始 + 1 初始 + 1 re-query)
371
- expect(svc.findRecord).toHaveBeenCalledTimes(3);
372
- expect(svc.cancel).toHaveBeenCalledTimes(2);
373
- });
374
-
375
- // BL-3 回归:CAS 失败后 re-query 时 record 已被 archive 移出内存,
376
- // 文案诚实报告 "evicted" 而非回落到可能过期的 stale status。
377
- it("CAS 失败 + record 被内存淘汰 → 文案诚实报告 evicted(BL-3)", async () => {
378
- const svc = makeService({
379
- // 第一次 findRecord:初始查询 → running
380
- // 第二次 findRecord:CAS 失败后 re-query → undefined(已被淘汰)
381
- findRecord: vi.fn()
382
- .mockReturnValueOnce(makeSnapshot({ id: "bg-evict", mode: "background", status: "running" }))
383
- .mockReturnValueOnce(undefined),
384
- cancel: vi.fn(() => false),
385
- });
386
- await expect(cancelHandler(svc, { subagentId: "bg-evict" }))
387
- .rejects.toThrow(/could not be cancelled.*status: unknown \(evicted from memory\)/);
388
- expect(svc.findRecord).toHaveBeenCalledTimes(2);
389
- });
390
- });
391
-
392
- // ============================================================
393
- // adapter
394
- // ============================================================
395
- describe("adapter", () => {
396
- it("start bg → SubagentToolResult.bgResponse + slug 透传 + content 合法 JSON(C3 回归)", () => {
397
- const r = adapter({
398
- action: "start",
399
- domain: {
400
- kind: "bg", subagentId: "bg-1", sessionFile: undefined, slug: "extract-urls",
401
- response: { status: "running", mode: "background", message: "detached, will notify on completion" },
402
- },
403
- });
404
- expect(r.details.action).toBe("start");
405
- expect(r.details.subagentId).toBe("bg-1");
406
- expect(r.details.bgResponse).toBeDefined();
407
- expect(r.details.sessionFile).toBeNull();
408
- // slug 透传到 result(renderResult 的 background 行展示用)
409
- expect(r.details.slug).toBe("extract-urls");
410
- // content JSON round-trip(bg 序列化回归)
411
- const parsed = JSON.parse(r.content[0]!.text);
412
- expect(parsed.bgResponse.message).toMatch(/detached/);
413
- expect(parsed.slug).toBe("extract-urls");
414
- });
415
-
416
- it("list → 最外层 subagentId/sessionFile 为 null", () => {
417
- const r = adapter({ action: "list", domain: { response: { running: 0, items: [] } } });
418
- expect(r.details.action).toBe("list");
419
- expect(r.details.subagentId).toBeNull();
420
- expect(r.details.sessionFile).toBeNull();
421
- expect(r.details.listResponse).toEqual({ running: 0, items: [] });
422
- });
423
-
424
- // [U3 C-outcome] 对外 JSON 契约:list items 携带 outcome 且旧字段保留(验收③)。
425
- it("[U3] list JSON:items[].outcome 在位(failed 值)且 status/mode/state 旧字段保留", () => {
426
- const r = adapter({
427
- action: "list",
428
- domain: {
429
- response: {
430
- running: 0,
431
- items: [
432
- {
433
- subagentId: "bg-u3", agent: "w", slug: "s", state: "ended", status: "closed",
434
- mode: "background", duration: 1, model: "m", totalTokens: 0,
435
- outcome: "failed",
436
- },
437
- ],
438
- },
439
- },
440
- });
441
- const parsed = JSON.parse(r.content[0]!.text) as {
442
- listResponse: { items: Array<Record<string, unknown>> };
443
- };
444
- const item = parsed.listResponse.items[0]!;
445
- expect(item.outcome).toBe("failed");
446
- // 旧字段保留(向后兼容)
447
- expect(item.status).toBe("closed");
448
- expect(item.state).toBe("ended");
449
- expect(item.mode).toBe("background");
450
- // closedReason 退出对外 JSON
451
- expect("closedReason" in item).toBe(false);
452
- });
453
-
454
- // [U3 C-outcome] start bgResponse:旧字段保留;outcome 为契约完备位,start 时点
455
- // record 未终态恒 undefined(JSON.stringify 落键省略),终态成败经 list items 披露。
456
- it("[U3] start bgResponse JSON:status/mode/message 旧字段保留,outcome 起点为 undefined", () => {
457
- const r = adapter({
458
- action: "start",
459
- domain: {
460
- kind: "bg", subagentId: "bg-u3-2", sessionFile: undefined, slug: "s",
461
- response: { status: "running", mode: "background", message: "detached" },
462
- },
463
- });
464
- const parsed = JSON.parse(r.content[0]!.text) as { bgResponse: Record<string, unknown> };
465
- expect(parsed.bgResponse.status).toBe("running");
466
- expect(parsed.bgResponse.mode).toBe("background");
467
- expect(parsed.bgResponse.message).toBe("detached");
468
- expect(parsed.bgResponse.outcome).toBeUndefined();
469
- });
470
-
471
- it("cancel → cancelResponse.cancelled:true 字面量", () => {
472
- const r = adapter({ action: "cancel", domain: { subagentId: "bg-1", response: { cancelled: true } } });
473
- expect(r.details.cancelResponse).toEqual({ cancelled: true });
474
- expect(r.details.subagentId).toBe("bg-1");
475
- });
476
- });
@@ -1,81 +0,0 @@
1
- /**
2
- * truncLine — indexOf 化(IF12/#18)byte-identical 快照 + 非 SGR ESC 行为锚定。
3
- *
4
- * fixture(__fixtures__/truncline.snapshot.json)由**改造前实现**生成落盘
5
- * (本文件同 commit),断言重构后输出逐字节一致——含 OSC / 裸 \x1b / \x1b[K
6
- * 非 SGR ESC 用例(等价定义点:非 SGR ESC 不构成文本段边界,按文本计宽进 result)。
7
- */
8
- import { readFileSync } from "node:fs";
9
- import { fileURLToPath } from "node:url";
10
- import { dirname, join } from "node:path";
11
-
12
- import { describe, expect, it } from "vitest";
13
-
14
- import { truncLine } from "../../interface/format.ts";
15
-
16
- interface SnapshotCase {
17
- label: string;
18
- maxWidth: number;
19
- text: string;
20
- expected: string;
21
- }
22
-
23
- function loadCases(): SnapshotCase[] {
24
- const here = dirname(fileURLToPath(import.meta.url));
25
- return JSON.parse(
26
- readFileSync(join(here, "__fixtures__", "truncline.snapshot.json"), "utf8"),
27
- ) as SnapshotCase[];
28
- }
29
-
30
- describe("truncLine — indexOf 化 byte-identical 快照(IF12)", () => {
31
- it("全部 fixture 用例(10k ANSI 混合行 / CJK / OSC / 裸 ESC / CSI-K / emoji)与改造前输出逐字节一致", () => {
32
- const cases = loadCases();
33
- expect(cases.length).toBeGreaterThanOrEqual(10);
34
- for (const c of cases) {
35
- expect(truncLine(c.text, c.maxWidth)).toBe(c.expected);
36
- }
37
- });
38
-
39
- it("10k 混合长行在多个截断宽度下均一致(fixture 内 maxWidth 之外再加宽度扫描)", () => {
40
- const mixed = loadCases().find((c) => c.label === "sgr-mixed-10k")!;
41
- for (const w of [8, 15, 30, 61, 100]) {
42
- const expected = mixed.expected; // fixture 锁 maxWidth=60;其他宽度靠 oracle 断言
43
- void expected;
44
- // 非 fixture 宽度用行为断言:输出含省略号且无裸换行
45
- const out = truncLine(mixed.text, w);
46
- expect(out).toContain("…");
47
- expect(out).not.toContain("\n");
48
- }
49
- });
50
- });
51
-
52
- describe("truncLine — 非 SGR ESC 行为(等价定义点,显式锚定)", () => {
53
- it("OSC 序列(\\x1b]0;title\\x07)按文本计宽进 result(不作为样式捕获/段边界)", () => {
54
- // OSC 计入可见宽度(\x1b]0;title\x07 各字符占宽),随后文本继续同段累加
55
- const out = truncLine("AB\x1b]0;title\x07CDEFGHIJKLMNOP", 10);
56
- expect(out.endsWith("…")).toBe(true);
57
- expect(out).not.toContain("\x1b]0;title\x07"); // 截断点在 OSC 之内或之前——
58
- // 逐字节形态由 fixture(osc-title / osc-inside-truncation 用例)锚定
59
- });
60
-
61
- it("裸 \\x1b 后跟非 [ 字符:不匹配 SGR、并入文本段(不丢字符不死循环)", () => {
62
- const out = truncLine("before \x1bZ after bare esc tail", 12);
63
- expect(out.endsWith("…")).toBe(true);
64
- // 输出是输入前缀(前 11 可见列 + …),未吞字符
65
- expect(out.startsWith("before ")).toBe(true);
66
- });
67
-
68
- it("非 SGR CSI(\\x1b[K)与 SGR 混排且触发截断:\x1b[K 不进 activeStyles(无错位 reset)", () => {
69
- const out = truncLine("\x1b[31mred\x1b[K\x1b[32mgreen tail past width", 10);
70
- // SGR(31m/32m)被捕获;\x1b[K 按文本进 result——逐字节形态由 fixture
71
- //(csi-k-mixed-sgr 用例)锚定;此处断言 SGR 样式重应用语义未回归
72
- expect(out).toMatch(/\x1b\[31m/);
73
- expect(out.endsWith("…\x1b[0m")).toBe(true);
74
- });
75
-
76
- it("ESC 恰在串尾:无后续字符可判 SGR,按文本并入(end=flat.length)", () => {
77
- const out = truncLine("text almost at width limit\x1b", 22);
78
- expect(out.endsWith("…")).toBe(true);
79
- expect(out).not.toContain("\x1b["); // 末尾裸 ESC 未触发 SGR 捕获
80
- });
81
- });