@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,211 +0,0 @@
1
- // acquireActivateLock 30s 超时兜底单测 —— v4-lifecycle-convergence.md §3.3 A-2。
2
- //
3
- // 验证:前序 holder 持锁不 release(崩溃/死锁模拟)时,waiter
4
- // - 等待 29999ms 仍 pending(未误伤正常排队)
5
- // - 到 30001ms 抛含恢复指引的超时错误('activation timed out' + 'retry action: message')
6
- //
7
- // 测试策略:纯 Promise 链 + setTimeout 超时,用 vi.useFakeTimers() 控时,
8
- // advanceTimersByTimeAsync 同时推进 fake timer 与 microtask flush。
9
-
10
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
11
-
12
- import {
13
- _getActivateLockTailCountForTest,
14
- _resetLifecycleState,
15
- acquireActivateLock,
16
- } from "../lifecycle-manager.ts";
17
-
18
- describe("acquireActivateLock 30s 超时兜底 (v4 A-2)", () => {
19
- beforeEach(() => {
20
- vi.useFakeTimers();
21
- _resetLifecycleState();
22
- });
23
-
24
- afterEach(() => {
25
- _resetLifecycleState();
26
- vi.useRealTimers();
27
- });
28
-
29
- it("waiter 等待 29999ms 仍 pending;到 30001ms 抛含恢复指引的超时错误", async () => {
30
- // 第一个 holder 持锁后不 release(模拟崩溃/死锁)
31
- await acquireActivateLock("sa-stuck");
32
-
33
- // 第二个 waiter 必然排队(前序未 release)
34
- let errMsg: string | null = null;
35
- let gotRelease: (() => void) | null = null;
36
- const waiter = acquireActivateLock("sa-stuck")
37
- .then((release) => {
38
- gotRelease = release;
39
- })
40
- .catch((err: unknown) => {
41
- errMsg = err instanceof Error ? err.message : String(err);
42
- });
43
-
44
- // flush microtask:waiter 进入 prev.then 等待链
45
- await vi.advanceTimersByTimeAsync(0);
46
- expect(gotRelease).toBe(null); // 尚未拿到锁
47
- expect(errMsg).toBe(null);
48
-
49
- // 29999ms:未满 30s,waiter 仍 pending
50
- await vi.advanceTimersByTimeAsync(29999);
51
- expect(gotRelease).toBe(null);
52
- expect(errMsg).toBe(null);
53
-
54
- // 再推进 2ms(累计 30001ms):超时 timer 触发 → reject
55
- await vi.advanceTimersByTimeAsync(2);
56
- await waiter;
57
-
58
- // 超时:未拿到锁,抛含恢复指引的错误
59
- expect(gotRelease).toBe(null);
60
- expect(errMsg).not.toBe(null);
61
- expect(errMsg).toContain("activation timed out");
62
- expect(errMsg).toContain("retry action: message");
63
- expect(errMsg).toContain("sa-stuck");
64
- });
65
-
66
- it("首次 acquire(无前序 holder)立即返回 release,不触发超时", async () => {
67
- // 首次 acquire:prev=Promise.resolve(),立即 resolve,timer 被 clearTimeout 取消
68
- const release = await acquireActivateLock("sa-fresh");
69
- expect(typeof release).toBe("function");
70
-
71
- // 推进远超 30s,不应有任何未捕获的超时 reject(timer 已清除)
72
- await vi.advanceTimersByTimeAsync(60000);
73
- release();
74
- });
75
-
76
- it("[review 修复] 超时后前序 release → 链可推进:二次 acquire 立即获锁(锁链不瘫痪)", async () => {
77
- // 瘫痪路径回归:waiter 超时 reject 后,若其 current 永久 pending,tail 永久
78
- // pending → 前序 release 后后续 acquire 也只能 30s 超时(只能重启恢复)。
79
- // 修复后超时回调 resolve 自身 current 放行链尾:release1 后 tail settle,
80
- // 二次 acquire 的 prev 已 settle → 立即拿到 releaseFn。
81
- const release1 = await acquireActivateLock("sa-recover");
82
-
83
- let waiterErr: string | null = null;
84
- const waiter = acquireActivateLock("sa-recover").catch((err: unknown) => {
85
- waiterErr = err instanceof Error ? err.message : String(err);
86
- });
87
- await vi.advanceTimersByTimeAsync(0); // waiter 挂链
88
- await vi.advanceTimersByTimeAsync(30001); // 超时 reject(+ 超时放行链尾)
89
- await waiter;
90
- expect(waiterErr).toContain("activation timed out");
91
-
92
- release1(); // 前序释放 → tail settle(current 已被超时放行 resolve)
93
- await vi.advanceTimersByTimeAsync(0); // flush microtask 链
94
-
95
- // 二次 acquire:prev 是已 settle 的 tail → 立即拿到锁,不等 30s
96
- const release2 = await acquireActivateLock("sa-recover");
97
- expect(typeof release2).toBe("function");
98
- release2();
99
- await vi.advanceTimersByTimeAsync(0);
100
- });
101
-
102
- it("[review 修复] 前序持续持锁时超时不放行后续 waiter 提前获锁(互斥保持)", async () => {
103
- // 超时放行只 resolve 自身 current(tail 仍等 prev);前序未 release 时,
104
- // 新 acquire 依然排队等待,不会与前序 holder 形成双写者。
105
- const release1 = await acquireActivateLock("sa-mutex");
106
-
107
- const waiter1 = acquireActivateLock("sa-mutex").catch(() => {});
108
- await vi.advanceTimersByTimeAsync(30001); // waiter1 超时放行自身 current
109
- await waiter1;
110
-
111
- // 前序仍持锁:新 acquire 的 prev(= waiter1 的 tail)等待 release1,不提前获锁
112
- let gotRelease2 = false;
113
- const waiter2 = acquireActivateLock("sa-mutex").then(() => {
114
- gotRelease2 = true;
115
- });
116
- await vi.advanceTimersByTimeAsync(0);
117
- expect(gotRelease2).toBe(false); // 未提前获锁
118
-
119
- release1();
120
- await vi.advanceTimersByTimeAsync(0);
121
- await waiter2; // release1 后链推进,waiter2 获锁
122
- expect(gotRelease2).toBe(true);
123
- });
124
-
125
- it("[review 修复] 超时者对称自清:前序 release 推进链尾后 Map 条目回收;前序持锁期间不提前删", async () => {
126
- // round2 INFO 残留:超时者 releaseFn 永不被调用,原实现条目滞留 Map 直到下次
127
- // 同 recordId acquire 覆盖。修复后挂 tail 尾部自清——tail settle(前序已
128
- // release)时回收;tail pending(前序仍持锁)时回调不执行,条目保留(后续
129
- // acquire 仍排队等待,互斥不被破坏)。
130
- const release1 = await acquireActivateLock("sa-timeout-gc");
131
-
132
- const waiter = acquireActivateLock("sa-timeout-gc").catch(() => {});
133
- await vi.advanceTimersByTimeAsync(0); // waiter 挂链,Map 链尾已覆盖为 waiter 的 tail
134
- expect(_getActivateLockTailCountForTest()).toBe(1);
135
-
136
- await vi.advanceTimersByTimeAsync(30001); // 超时:reject + settleCurrent + tail.then 自清排队
137
- await waiter;
138
- // 前序仍持锁 → tail 仍 pending → 自清回调未执行 → 条目仍在
139
- expect(_getActivateLockTailCountForTest()).toBe(1);
140
-
141
- release1(); // 前序释放 → tail settle → 自清回调执行(identity 匹配,无新 waiter)
142
- await vi.advanceTimersByTimeAsync(0);
143
- expect(_getActivateLockTailCountForTest()).toBe(0);
144
- });
145
- });
146
-
147
- describe("activateLockTails tail-identity 自清(release 后回收)", () => {
148
- beforeEach(() => {
149
- vi.useFakeTimers();
150
- _resetLifecycleState();
151
- });
152
-
153
- afterEach(() => {
154
- _resetLifecycleState();
155
- vi.useRealTimers();
156
- });
157
-
158
- it("W3TC14: 无 waiter 时 release 后 Map 空 + release 后可再次 acquire", async () => {
159
- const release = await acquireActivateLock("sa-gc");
160
- // 自清新增的 test-only 观察点:acquire 后 Map 有 1 条链尾
161
- expect(_getActivateLockTailCountForTest()).toBe(1);
162
-
163
- release();
164
- // 自清经 queueMicrotask 异步执行——advanceTimersByTimeAsync(0) flush microtask
165
- await vi.advanceTimersByTimeAsync(0);
166
- // 无 waiter:Map 中链尾即本链尾,identity 匹配 → delete 回收
167
- expect(_getActivateLockTailCountForTest()).toBe(0);
168
-
169
- // release 后可再次 acquire:prev 回落 Promise.resolve(),立即 resolve 返回 release
170
- const release2 = await acquireActivateLock("sa-gc");
171
- expect(typeof release2).toBe("function");
172
- release2();
173
- await vi.advanceTimersByTimeAsync(0);
174
- expect(_getActivateLockTailCountForTest()).toBe(0);
175
- });
176
-
177
- it("W3TC15: 有 waiter 排队不删、最后释放者回收;不同 recordId 链独立", async () => {
178
- const release1 = await acquireActivateLock("sa-q");
179
-
180
- // 发起 acquire#2 同 recordId(不 await,.then 捕获 release2)
181
- let release2: (() => void) | null = null;
182
- const waiter = acquireActivateLock("sa-q").then((r) => {
183
- release2 = r;
184
- });
185
- // #2 进入等待链——此刻 Map 链尾已被 #2 覆盖
186
- await vi.advanceTimersByTimeAsync(0);
187
-
188
- release1();
189
- await vi.advanceTimersByTimeAsync(0);
190
- // ES7 核心:waiter 的链尾仍在——identity 不匹配不删
191
- expect(_getActivateLockTailCountForTest()).toBe(1);
192
-
193
- // acquire#2 在 release1 后正常 resolve(等待链不被 delete 破坏——waiter 持
194
- // acquire 时刻捕获的 prev Promise 引用而非 Map 查询)
195
- await waiter;
196
- expect(typeof release2).toBe("function");
197
-
198
- // 另一 recordId 独立链:同时持有时各自独立计数
199
- const releaseA = await acquireActivateLock("sa-a");
200
- expect(_getActivateLockTailCountForTest()).toBe(2); // sa-q + sa-a
201
-
202
- release2!();
203
- await vi.advanceTimersByTimeAsync(0);
204
- // 最后释放者回收:release2 的 identity 匹配 → sa-q 条目回收,sa-a 仍在
205
- expect(_getActivateLockTailCountForTest()).toBe(1);
206
-
207
- releaseA();
208
- await vi.advanceTimersByTimeAsync(0);
209
- expect(_getActivateLockTailCountForTest()).toBe(0);
210
- });
211
- });
@@ -1,383 +0,0 @@
1
- // lifecycle-manager 单测 —— V2 §5.2 模块 1(进程生命周期管理)五项职责。
2
- //
3
- // 测试策略:
4
- // - idle timer / ceiling LRU 用 vi.useFakeTimers() + advanceTimersByTime(同时 mock
5
- // Date.now(),让 lastTouched 时间戳可控)。
6
- // - activate 互斥锁是纯 Promise 链(无 timer),用 advanceTimersByTimeAsync(0)
7
- // flush microtask 验证串行化。
8
- // - 每个用例 beforeEach 调 _resetLifecycleState() 隔离模块级单例状态。
9
-
10
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
11
-
12
- import {
13
- DEFAULT_IDLE_TIMEOUT_MS,
14
- DEFAULT_MAX_ALIVE_PROCESSES,
15
- _resetLifecycleState,
16
- acquireActivateLock,
17
- armIdleTimer,
18
- disarmIdleTimer,
19
- evictIfOverCeiling,
20
- getActiveProcessCount,
21
- hasIdleTimer,
22
- reapAllAliveProcesses,
23
- registerActiveProcess,
24
- scanOrphanProcesses,
25
- touchActiveProcess,
26
- unregisterActiveProcess,
27
- } from "../lifecycle-manager.ts";
28
-
29
- describe("lifecycle-manager — V2 §5.2 模块 1", () => {
30
- beforeEach(() => {
31
- vi.useFakeTimers();
32
- _resetLifecycleState();
33
- // [F-4 同源修复] env 隔离:「默认超时」用例依赖 XYZ_SUBAGENT_IDLE_TIMEOUT_MS
34
- // 未设基线(getEnvIdleTimeoutMs 会覆盖 DEFAULT),宿主 export 即假红。空串 = 未设。
35
- vi.stubEnv("XYZ_SUBAGENT_IDLE_TIMEOUT_MS", "");
36
- });
37
-
38
- afterEach(() => {
39
- _resetLifecycleState();
40
- vi.useRealTimers();
41
- vi.unstubAllEnvs();
42
- });
43
-
44
- // ============================================================
45
- // 职责 1:idle timer
46
- // ============================================================
47
- describe("职责1 idle timer", () => {
48
- it("arm 后到 timeoutMs 触发 onTimeout(边界:差 1ms 不触发)", () => {
49
- const onTimeout = vi.fn();
50
- armIdleTimer("sa-1", onTimeout, 1000);
51
-
52
- expect(hasIdleTimer("sa-1")).toBe(true);
53
- vi.advanceTimersByTime(999);
54
- expect(onTimeout).not.toHaveBeenCalled();
55
-
56
- vi.advanceTimersByTime(1);
57
- expect(onTimeout).toHaveBeenCalledTimes(1);
58
- // 触发后自动从 Map 移除(不残留失效 entry)
59
- expect(hasIdleTimer("sa-1")).toBe(false);
60
- });
61
-
62
- it("disarm 后不再触发 onTimeout", () => {
63
- const onTimeout = vi.fn();
64
- armIdleTimer("sa-1", onTimeout, 1000);
65
- disarmIdleTimer("sa-1");
66
-
67
- expect(hasIdleTimer("sa-1")).toBe(false);
68
- vi.advanceTimersByTime(5000);
69
- expect(onTimeout).not.toHaveBeenCalled();
70
- });
71
-
72
- it("disarm 不存在的 record 为 no-op(不抛错)", () => {
73
- expect(() => disarmIdleTimer("never-armed")).not.toThrow();
74
- });
75
-
76
- it("重复 arm 刷新 timer:旧 timer 作废、重新计时", () => {
77
- const onTimeout = vi.fn();
78
- armIdleTimer("sa-1", onTimeout, 1000);
79
- vi.advanceTimersByTime(500); // 过了 500ms
80
-
81
- armIdleTimer("sa-1", onTimeout, 1000); // 刷新:重新计 1000ms
82
- vi.advanceTimersByTime(999);
83
- expect(onTimeout).not.toHaveBeenCalled(); // 旧 timer 已作废,新的还没到
84
-
85
- vi.advanceTimersByTime(1);
86
- expect(onTimeout).toHaveBeenCalledTimes(1);
87
- });
88
-
89
- it("默认超时 = DEFAULT_IDLE_TIMEOUT_MS", () => {
90
- const onTimeout = vi.fn();
91
- armIdleTimer("sa-1", onTimeout); // 不传 timeoutMs
92
-
93
- vi.advanceTimersByTime(DEFAULT_IDLE_TIMEOUT_MS - 1);
94
- expect(onTimeout).not.toHaveBeenCalled();
95
-
96
- vi.advanceTimersByTime(1);
97
- expect(onTimeout).toHaveBeenCalledTimes(1);
98
- });
99
-
100
- it("显式禁用值(0/负数)→ 不挂 timer(预算语义对齐:idle GC 可显式关闭;旧实现 0 落成 setTimeout(0) 立即 kill)", () => {
101
- const onTimeout = vi.fn();
102
- armIdleTimer("sa-disable-0", onTimeout, 0);
103
- expect(hasIdleTimer("sa-disable-0")).toBe(false);
104
- armIdleTimer("sa-disable-neg", onTimeout, -1);
105
- expect(hasIdleTimer("sa-disable-neg")).toBe(false);
106
-
107
- vi.advanceTimersByTime(DEFAULT_IDLE_TIMEOUT_MS * 2);
108
- expect(onTimeout).not.toHaveBeenCalled();
109
- });
110
-
111
- it("显式禁用值顺带 disarm 已有 armed timer(禁用不形同虚设)", () => {
112
- const onTimeout = vi.fn();
113
- armIdleTimer("sa-disable-late", onTimeout, 1000);
114
- expect(hasIdleTimer("sa-disable-late")).toBe(true);
115
- armIdleTimer("sa-disable-late", onTimeout, 0);
116
- expect(hasIdleTimer("sa-disable-late")).toBe(false);
117
- vi.advanceTimersByTime(2000);
118
- expect(onTimeout).not.toHaveBeenCalled();
119
- });
120
-
121
- // [U1] setTimeout 2^31-1 溢出 fail-fast:溢出 delay 被 Node 置 1ms 立即触发
122
- //(「长空闲保活」变「立即 kill」),arm 入口拦截且错误含上限值与恢复指引。
123
- // 显式禁用通道(<=0)不受影响(上方用例已锁)。
124
- it("idleTimeoutMs 溢出(>2^31-1)→ fail-fast throw,不挂 timer", () => {
125
- const onTimeout = vi.fn();
126
- expect(() => armIdleTimer("sa-overflow", onTimeout, 3_000_000_000)).toThrowError(/2147483647/);
127
- expect(() => armIdleTimer("sa-overflow", onTimeout, Number.MAX_SAFE_INTEGER)).toThrowError(
128
- /Recovery/,
129
- );
130
- expect(hasIdleTimer("sa-overflow")).toBe(false);
131
- vi.advanceTimersByTime(3_000_000_000);
132
- expect(onTimeout).not.toHaveBeenCalled();
133
- });
134
-
135
- it("env XYZ_SUBAGENT_IDLE_TIMEOUT_MS 溢出 → fail-fast throw(arm 入口统一拦截)", () => {
136
- vi.stubEnv("XYZ_SUBAGENT_IDLE_TIMEOUT_MS", "3000000000");
137
- const onTimeout = vi.fn();
138
- expect(() => armIdleTimer("sa-env-overflow", onTimeout)).toThrowError(/2147483647/);
139
- expect(hasIdleTimer("sa-env-overflow")).toBe(false);
140
- });
141
- });
142
-
143
- // ============================================================
144
- // 职责 2:全局 ceiling(LRU 挤出)
145
- // ============================================================
146
- describe("职责2 全局 ceiling", () => {
147
- it("register 超过上限时 evictIfOverCeiling 挤出最久空闲", () => {
148
- registerActiveProcess("sa-1"); // 最早
149
- vi.advanceTimersByTime(10);
150
- registerActiveProcess("sa-2");
151
- vi.advanceTimersByTime(10);
152
- registerActiveProcess("sa-3"); // 超限(size=3 > ceiling=2)
153
- expect(getActiveProcessCount()).toBe(3);
154
-
155
- const evicted: string[] = [];
156
- evictIfOverCeiling((id) => evicted.push(id), 2);
157
-
158
- expect(evicted).toEqual(["sa-1"]); // lastTouched 最老的被挤出
159
- expect(getActiveProcessCount()).toBe(2);
160
- });
161
-
162
- it("不超过上限时 evictIfOverCeiling 不挤出", () => {
163
- registerActiveProcess("sa-1");
164
- registerActiveProcess("sa-2");
165
-
166
- const evicted: string[] = [];
167
- evictIfOverCeiling((id) => evicted.push(id), 5);
168
-
169
- expect(evicted).toEqual([]);
170
- expect(getActiveProcessCount()).toBe(2);
171
- });
172
-
173
- it("touch 更新 LRU:被 touch 的不再是挤出候选", () => {
174
- registerActiveProcess("sa-1");
175
- vi.advanceTimersByTime(10);
176
- registerActiveProcess("sa-2");
177
- vi.advanceTimersByTime(10);
178
- touchActiveProcess("sa-1"); // sa-1 变最新 → sa-2 变最老
179
-
180
- const evicted: string[] = [];
181
- evictIfOverCeiling((id) => evicted.push(id), 1);
182
-
183
- expect(evicted).toEqual(["sa-2"]); // sa-2 最久未 touch,被挤出
184
- });
185
-
186
- it("touch 不存在的 record 为 no-op(不隐式创建)", () => {
187
- expect(() => touchActiveProcess("never-registered")).not.toThrow();
188
- expect(getActiveProcessCount()).toBe(0);
189
- });
190
-
191
- it("unregister 清理活进程集合", () => {
192
- registerActiveProcess("sa-1");
193
- registerActiveProcess("sa-2");
194
- unregisterActiveProcess("sa-1");
195
- expect(getActiveProcessCount()).toBe(1);
196
- });
197
-
198
- it("挤出时连带 disarm 被挤 record 的 idle timer", () => {
199
- registerActiveProcess("sa-1");
200
- armIdleTimer("sa-1", vi.fn(), 1000);
201
- registerActiveProcess("sa-2");
202
- vi.advanceTimersByTime(10);
203
- registerActiveProcess("sa-3"); // sa-1 最老,将被挤出
204
-
205
- evictIfOverCeiling(() => {
206
- /* kill */
207
- }, 2);
208
-
209
- expect(hasIdleTimer("sa-1")).toBe(false); // 挤出 cascade disarm
210
- });
211
-
212
- it("unregister 连带 disarm idle timer(进程终态 timer 不残留)", () => {
213
- registerActiveProcess("sa-1");
214
- armIdleTimer("sa-1", vi.fn(), 1000);
215
- unregisterActiveProcess("sa-1");
216
- expect(hasIdleTimer("sa-1")).toBe(false);
217
- });
218
-
219
- it("默认上限 = DEFAULT_MAX_ALIVE_PROCESSES(不传 maxAlive)", () => {
220
- for (let i = 0; i < DEFAULT_MAX_ALIVE_PROCESSES; i++) {
221
- registerActiveProcess(`sa-${i}`);
222
- vi.advanceTimersByTime(1); // 保证 lastTouched 严格递增
223
- }
224
- registerActiveProcess("sa-over"); // 超限
225
- const evicted: string[] = [];
226
- evictIfOverCeiling((id) => evicted.push(id)); // 用默认上限
227
-
228
- expect(evicted).toEqual(["sa-0"]); // 默认上限下挤出最早
229
- expect(getActiveProcessCount()).toBe(DEFAULT_MAX_ALIVE_PROCESSES);
230
- });
231
-
232
- it("大幅超限时 while 循环挤出多个直到 ≤ ceiling", () => {
233
- for (let i = 0; i < 5; i++) {
234
- registerActiveProcess(`sa-${i}`);
235
- vi.advanceTimersByTime(1);
236
- }
237
- const evicted: string[] = [];
238
- evictIfOverCeiling((id) => evicted.push(id), 2);
239
-
240
- expect(evicted).toEqual(["sa-0", "sa-1", "sa-2"]); // 挤出 3 个(5-2),按 LRU
241
- });
242
- });
243
-
244
- // ============================================================
245
- // 职责 3:shutdown 收割
246
- // ============================================================
247
- describe("职责3 shutdown 收割", () => {
248
- it("reapAllAliveProcesses 遍历活进程调 killFn 并返回列表", () => {
249
- registerActiveProcess("sa-1");
250
- registerActiveProcess("sa-2");
251
-
252
- const killed: string[] = [];
253
- const reaped = reapAllAliveProcesses((id) => killed.push(id));
254
-
255
- expect(killed).toHaveLength(2);
256
- expect(killed).toEqual(expect.arrayContaining(["sa-1", "sa-2"]));
257
- expect(reaped).toEqual(expect.arrayContaining(["sa-1", "sa-2"]));
258
- expect(getActiveProcessCount()).toBe(0);
259
- });
260
-
261
- it("reap 后 idle timer 已 disarm(advance 不再触发)", () => {
262
- registerActiveProcess("sa-1");
263
- const onTimeout = vi.fn();
264
- armIdleTimer("sa-1", onTimeout, 1000);
265
-
266
- reapAllAliveProcesses(() => {
267
- /* kill */
268
- });
269
- vi.advanceTimersByTime(10000);
270
-
271
- expect(onTimeout).not.toHaveBeenCalled(); // timer 已被 reap 清理
272
- });
273
-
274
- it("无活进程时 reapAll 返回空列表", () => {
275
- const reaped = reapAllAliveProcesses(() => {
276
- /* kill */
277
- });
278
- expect(reaped).toEqual([]);
279
- });
280
- });
281
-
282
- // ============================================================
283
- // 职责 4:孤儿扫描
284
- // ============================================================
285
- describe("职责4 孤儿扫描", () => {
286
- it("pid 存活 + 不在活进程集合 = 孤儿", () => {
287
- registerActiveProcess("sa-active"); // 在集合内
288
- const records = [
289
- { id: "sa-active", pid: 100 },
290
- { id: "sa-orphan", pid: 200 }, // pid 活但不在集合 → 孤儿
291
- { id: "sa-dead", pid: 300 }, // pid 不活 → 非孤儿
292
- { id: "sa-nopid" }, // 无 pid → 非孤儿
293
- ];
294
-
295
- const orphans = scanOrphanProcesses(records, (pid) => pid === 100 || pid === 200);
296
-
297
- expect(orphans).toEqual(["sa-orphan"]);
298
- });
299
-
300
- it("pid 不存活 = 非孤儿", () => {
301
- const records = [{ id: "sa-1", pid: 999 }];
302
- const orphans = scanOrphanProcesses(records, () => false); // 全不活
303
- expect(orphans).toEqual([]);
304
- });
305
-
306
- it("在活进程集合内 = 非孤儿(即使 pid 活)", () => {
307
- registerActiveProcess("sa-1");
308
- const records = [{ id: "sa-1", pid: 100 }];
309
- const orphans = scanOrphanProcesses(records, () => true);
310
- expect(orphans).toEqual([]);
311
- });
312
-
313
- it("无 pid 的 record 不视为孤儿", () => {
314
- const records = [
315
- { id: "sa-1" },
316
- { id: "sa-2", sessionFile: "/x.jsonl" },
317
- ];
318
- const orphans = scanOrphanProcesses(records, () => true);
319
- expect(orphans).toEqual([]);
320
- });
321
-
322
- it("扫描是只读(不改活进程集合)", () => {
323
- registerActiveProcess("sa-1");
324
- scanOrphanProcesses([{ id: "sa-2", pid: 200 }], () => true);
325
- expect(getActiveProcessCount()).toBe(1); // 集合不变
326
- });
327
- });
328
-
329
- // ============================================================
330
- // 职责 5:activate 互斥锁
331
- // ============================================================
332
- describe("职责5 activate 互斥锁", () => {
333
- it("首次 acquire 立即 resolve 返回 release 函数", async () => {
334
- const release = await acquireActivateLock("sa-1");
335
- expect(typeof release).toBe("function");
336
- release();
337
- });
338
-
339
- it("并发 acquire 同一 recordId 串行化:第二次等首次 release", async () => {
340
- const release1 = await acquireActivateLock("sa-1");
341
-
342
- let secondResolved = false;
343
- const secondPromise = acquireActivateLock("sa-1").then((r) => {
344
- secondResolved = true;
345
- return r;
346
- });
347
-
348
- await vi.advanceTimersByTimeAsync(0); // flush microtask
349
- expect(secondResolved).toBe(false); // 还在等首次 release
350
-
351
- release1();
352
- await vi.advanceTimersByTimeAsync(0); // flush microtask
353
- expect(secondResolved).toBe(true);
354
-
355
- const release2 = await secondPromise;
356
- release2();
357
- });
358
-
359
- it("不同 recordId 不互斥(各自独立链)", async () => {
360
- const release1 = await acquireActivateLock("sa-1");
361
-
362
- let secondResolved = false;
363
- acquireActivateLock("sa-2").then((r) => {
364
- secondResolved = true;
365
- r();
366
- });
367
-
368
- await vi.advanceTimersByTimeAsync(0); // flush microtask
369
- expect(secondResolved).toBe(true); // sa-2 不被 sa-1 阻塞
370
-
371
- release1();
372
- });
373
-
374
- it("release 后同 recordId 可再次 acquire", async () => {
375
- const r1 = await acquireActivateLock("sa-1");
376
- r1();
377
-
378
- const r2 = await acquireActivateLock("sa-1");
379
- expect(typeof r2).toBe("function");
380
- r2();
381
- });
382
- });
383
- });