@zhushanwen/subagent-core 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +1 -1
  2. package/dist/chunk-KXVBIVOU.js +16 -0
  3. package/dist/chunk-T2SYBW3I.js +24 -0
  4. package/dist/chunk-VURUAGMM.js +2305 -0
  5. package/dist/{types-C3fE3R9x.d.cts → engine-discovery-scan-ocpM8FmI.d.cts} +770 -668
  6. package/dist/{types-C3fE3R9x.d.ts → engine-discovery-scan-ocpM8FmI.d.ts} +770 -668
  7. package/dist/execution/engine/engine-discovery-scan.cjs +2210 -0
  8. package/dist/execution/engine/engine-discovery-scan.d.cts +4 -0
  9. package/dist/execution/engine/engine-discovery-scan.d.ts +4 -0
  10. package/dist/execution/engine/engine-discovery-scan.js +20 -0
  11. package/dist/execution/engine/paths.cjs +6 -23
  12. package/dist/execution/engine/paths.d.cts +1 -8
  13. package/dist/execution/engine/paths.d.ts +1 -8
  14. package/dist/execution/engine/paths.js +1 -1
  15. package/dist/execution/relay-env.cjs +12 -28
  16. package/dist/execution/relay-env.d.cts +1 -33
  17. package/dist/execution/relay-env.d.ts +1 -33
  18. package/dist/execution/relay-env.js +5 -3
  19. package/dist/index.cjs +14045 -16059
  20. package/dist/index.d.cts +1035 -1579
  21. package/dist/index.d.ts +1035 -1579
  22. package/dist/index.js +9838 -13800
  23. package/dist.bundle/index.cjs +28875 -30323
  24. package/package.json +20 -26
  25. package/src/__tests__/record-store-last-line.test.ts +16 -7
  26. package/src/core/error-message.ts +7 -6
  27. package/src/core/host-services.ts +8 -2
  28. package/src/core/notify-ports.ts +17 -2
  29. package/src/execution/__tests__/chat-engine-routing.test.ts +62 -28
  30. package/src/execution/__tests__/chat-round-first-round-watchdog.test.ts +255 -0
  31. package/src/execution/__tests__/collect-coordinator-service.test.ts +36 -47
  32. package/src/execution/__tests__/collect-mixed-dispatch.test.ts +20 -53
  33. package/src/execution/__tests__/delivery-methods.test.ts +179 -237
  34. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -2
  35. package/src/execution/__tests__/execute-nesting.test.ts +20 -13
  36. package/src/execution/__tests__/explicit-agent-ref-guard.test.ts +20 -33
  37. package/src/execution/__tests__/gc-timer.test.ts +7 -22
  38. package/src/execution/__tests__/get-record-for-action-restart.test.ts +20 -10
  39. package/src/execution/__tests__/helpers/fake-engine-port.ts +187 -0
  40. package/src/execution/__tests__/helpers/spawn-mock.ts +36 -9
  41. package/src/execution/__tests__/helpers/subagent-service-mocks.ts +1 -1
  42. package/src/execution/__tests__/idle-gc.test.ts +200 -0
  43. package/src/execution/__tests__/lifecycle-predicates.test.ts +26 -21
  44. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +5 -2
  45. package/src/execution/__tests__/reconcile-sweep.test.ts +200 -0
  46. package/src/execution/__tests__/record-store.test.ts +60 -6
  47. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +20 -13
  48. package/src/execution/__tests__/round-supervisor.test.ts +293 -0
  49. package/src/execution/__tests__/session-pending.test.ts +119 -17
  50. package/src/execution/__tests__/stream-sink-retirement.test.ts +10 -10
  51. package/src/execution/__tests__/subagent-service-multiproc-guard.test.ts +1 -11
  52. package/src/execution/__tests__/subagent-service-notify-gate.test.ts +33 -30
  53. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +2 -9
  54. package/src/execution/__tests__/subagent-service-recovery-bounds.test.ts +59 -129
  55. package/src/execution/__tests__/subagent-service.test.ts +2 -2
  56. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +109 -7
  57. package/src/execution/__tests__/subprocess-agent-runner.test.ts +108 -36
  58. package/src/execution/__tests__/sync-collect-recovery.test.ts +21 -36
  59. package/src/execution/__tests__/workflow-state-root.test.ts +232 -0
  60. package/src/execution/agent-registry.ts +6 -2
  61. package/src/execution/dialog-queue.ts +6 -73
  62. package/src/execution/engine/__tests__/common/capability-gate.test.ts +115 -15
  63. package/src/execution/engine/__tests__/common/errors.test.ts +11 -18
  64. package/src/execution/engine/__tests__/common/kill-chain.test.ts +7 -0
  65. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +9 -3
  66. package/src/execution/engine/__tests__/common/session-view-service.test.ts +90 -3
  67. package/src/execution/engine/__tests__/conformance/H9-test-disposition.md +116 -0
  68. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/fake-engine-protocol.mjs +377 -0
  69. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/recorded.fixture.json +331 -0
  70. package/src/execution/engine/__tests__/conformance/__fixtures__/engine-protocol/smoke-run.fixture.json +213 -0
  71. package/src/execution/engine/__tests__/conformance/chat-round-protocol.test.ts +230 -0
  72. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +69 -42
  73. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +4 -81
  74. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +67 -44
  75. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +81 -54
  76. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +133 -70
  77. package/src/execution/engine/__tests__/conformance/engine-crash.test.ts +143 -0
  78. package/src/execution/engine/__tests__/conformance/fake-engine-capabilities.ts +19 -0
  79. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +7 -2
  80. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +6 -5
  81. package/src/execution/engine/__tests__/conformance/protocol-blackbox.test.ts +398 -0
  82. package/src/execution/engine/__tests__/conformance/registry-fork-filter.test.ts +221 -0
  83. package/src/execution/engine/__tests__/conformance/round-liveness-supervisor.test.ts +302 -0
  84. package/src/execution/engine/__tests__/conformance/static-spawn-guard.test.ts +58 -0
  85. package/src/execution/engine/__tests__/engine-discovery-scan.test.ts +558 -0
  86. package/src/execution/engine/__tests__/host-task-spec.test.ts +45 -0
  87. package/src/execution/engine/__tests__/model-ref-split.test.ts +74 -0
  88. package/src/execution/engine/__tests__/registry.test.ts +206 -1
  89. package/src/execution/engine/__tests__/routing.test.ts +97 -0
  90. package/src/execution/engine/__tests__/run-failure-worktree-cleanup.test.ts +97 -0
  91. package/src/execution/engine/client/__tests__/__fixtures__/fake-engine.mjs +294 -0
  92. package/src/execution/engine/client/__tests__/engine-client.test.ts +516 -0
  93. package/src/execution/engine/client/__tests__/mirror.test.ts +67 -0
  94. package/src/execution/engine/client/__tests__/pid-file.test.ts +257 -0
  95. package/src/execution/engine/client/__tests__/protocol-closure.test.ts +95 -0
  96. package/src/execution/engine/client/__tests__/remote-engine.test.ts +457 -0
  97. package/src/execution/engine/client/client-options.ts +103 -0
  98. package/src/execution/engine/client/engine-client.ts +687 -0
  99. package/src/execution/engine/client/mirror.ts +167 -0
  100. package/src/execution/engine/client/pid-file.ts +392 -0
  101. package/src/execution/engine/client/reaper.ts +95 -0
  102. package/src/execution/engine/client/remote-engine.ts +441 -0
  103. package/src/execution/engine/client/reverse-router.ts +255 -0
  104. package/src/execution/engine/common/capability-gate.ts +109 -22
  105. package/src/execution/engine/common/errors.ts +9 -25
  106. package/src/execution/engine/common/event-journal.ts +4 -50
  107. package/src/execution/engine/common/journal-replay.ts +3 -1
  108. package/src/execution/engine/common/kill-chain.ts +18 -251
  109. package/src/execution/engine/common/nesting-guard.ts +18 -114
  110. package/src/execution/engine/common/pool-manager.ts +4 -0
  111. package/src/execution/engine/common/session-view-service.ts +56 -84
  112. package/src/execution/engine/config.ts +151 -0
  113. package/src/execution/engine/d8-compat.ts +346 -0
  114. package/src/execution/engine/engine-discovery-roots.ts +107 -0
  115. package/src/execution/engine/engine-discovery-scan.ts +269 -0
  116. package/src/execution/engine/engine-discovery.ts +30 -7
  117. package/src/execution/engine/engine-inspect-package.ts +282 -0
  118. package/src/execution/engine/engine-manifest.ts +244 -0
  119. package/src/execution/engine/host/__tests__/host-askuser-endpoint.test.ts +123 -0
  120. package/src/execution/engine/host/__tests__/host-bridge.test.ts +135 -0
  121. package/src/execution/engine/host/__tests__/spawned-children.test.ts +73 -0
  122. package/src/execution/engine/host/host-bridge.ts +150 -0
  123. package/src/execution/engine/host/host-ui-endpoint.ts +47 -0
  124. package/src/execution/engine/host/pi-host-binding.ts +91 -0
  125. package/src/execution/engine/host/spawned-children.ts +139 -0
  126. package/src/execution/engine/host-task-spec.ts +29 -2
  127. package/src/execution/engine/model-validation.ts +55 -2
  128. package/src/execution/engine/paths.ts +16 -41
  129. package/src/execution/engine/port.ts +48 -2
  130. package/src/execution/engine/registry.ts +153 -34
  131. package/src/execution/engine/routing.ts +225 -52
  132. package/src/execution/engine/types.ts +25 -200
  133. package/src/execution/finalize-record.ts +25 -0
  134. package/src/execution/idle-gc.ts +89 -14
  135. package/src/execution/lifecycle-manager.ts +10 -7
  136. package/src/execution/lifecycle-predicates.ts +10 -8
  137. package/src/execution/record-store.ts +29 -2
  138. package/src/execution/relay-env.ts +19 -36
  139. package/src/execution/round-supervisor/domain.ts +89 -0
  140. package/src/execution/round-supervisor/index.ts +33 -0
  141. package/src/execution/round-supervisor/notify-accounting.ts +87 -0
  142. package/src/execution/round-supervisor/reconcile-sweep.ts +235 -0
  143. package/src/execution/round-supervisor/service-binding.test.ts +661 -0
  144. package/src/execution/round-supervisor/service-binding.ts +273 -0
  145. package/src/execution/round-supervisor/supervisor.ts +426 -0
  146. package/src/execution/session-pending.ts +68 -74
  147. package/src/execution/settled-watchdog.ts +39 -0
  148. package/src/execution/subagent-service.ts +746 -400
  149. package/src/execution/subprocess-agent-runner.ts +16 -8
  150. package/src/execution/types.ts +41 -117
  151. package/src/execution/ui-channels.ts +13 -214
  152. package/src/execution/ui-request-handler-factory.ts +7 -4
  153. package/src/execution/ui-request-observability.ts +2 -2
  154. package/src/execution/workflow-state-root.ts +67 -0
  155. package/src/execution/worktree-git-ops.ts +5 -0
  156. package/src/execution/worktree-manager.ts +11 -1
  157. package/src/index.ts +55 -26
  158. package/src/orchestration/__tests__/execute-agent-call.test.ts +1 -1
  159. package/src/orchestration/execute-agent-call.ts +1 -1
  160. package/src/orchestration/file-run-store.ts +144 -59
  161. package/src/orchestration/models/types.ts +43 -42
  162. package/src/shared/zcode-model-ref.ts +31 -0
  163. package/dist/chunk-43ONBFZX.js +0 -240
  164. package/dist/chunk-A4IVZWVX.js +0 -31
  165. package/dist/chunk-APZY4IME.js +0 -27
  166. package/dist/chunk-V3VHZ2VX.js +0 -59
  167. package/dist/execution/engine/engines/zcode/constants.cjs +0 -107
  168. package/dist/execution/engine/engines/zcode/constants.d.cts +0 -135
  169. package/dist/execution/engine/engines/zcode/constants.d.ts +0 -135
  170. package/dist/execution/engine/engines/zcode/constants.js +0 -54
  171. package/dist/execution/engine/engines/zcode/reader.cjs +0 -276
  172. package/dist/execution/engine/engines/zcode/reader.d.cts +0 -21
  173. package/dist/execution/engine/engines/zcode/reader.d.ts +0 -21
  174. package/dist/execution/engine/engines/zcode/reader.js +0 -9
  175. package/src/__tests__/append-system-prompt-assembly.test.ts +0 -243
  176. package/src/__tests__/fr4-get-state-handshake.test.ts +0 -125
  177. package/src/__tests__/session-runner.test.ts +0 -69
  178. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  179. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -191
  180. package/src/execution/__tests__/descendant-sweep-guards.test.ts +0 -220
  181. package/src/execution/__tests__/descendant-sweep.test.ts +0 -269
  182. package/src/execution/__tests__/engine-model-validation.test.ts +0 -741
  183. package/src/execution/__tests__/epipe-fallback.test.ts +0 -248
  184. package/src/execution/__tests__/execution-runtime-face.test.ts +0 -272
  185. package/src/execution/__tests__/get-state-handshake.test.ts +0 -127
  186. package/src/execution/__tests__/helpers/session-runner-mocks.ts +0 -113
  187. package/src/execution/__tests__/keep-alive-no-progress.test.ts +0 -280
  188. package/src/execution/__tests__/kill-all-escalation.test.ts +0 -196
  189. package/src/execution/__tests__/max-turns-to-watchdog-ms.test.ts +0 -113
  190. package/src/execution/__tests__/output-collector.test.ts +0 -469
  191. package/src/execution/__tests__/pi-invocation.test.ts +0 -166
  192. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -149
  193. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  194. package/src/execution/__tests__/run-and-finalize-anchoring.test.ts +0 -387
  195. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -277
  196. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -254
  197. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -1079
  198. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  199. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  200. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  201. package/src/execution/__tests__/run-spawn-stdout-callback-throw.test.ts +0 -207
  202. package/src/execution/__tests__/service-kill-escalation.test.ts +0 -91
  203. package/src/execution/__tests__/session-runner-branch-cache-lru.test.ts +0 -110
  204. package/src/execution/__tests__/session-runner-close-prune.test.ts +0 -181
  205. package/src/execution/__tests__/session-runner-dispatch.test.ts +0 -489
  206. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -179
  207. package/src/execution/__tests__/session-runner-heartbeat-idle-fallback.test.ts +0 -227
  208. package/src/execution/__tests__/session-runner-lifecycle-helpers.test.ts +0 -290
  209. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -352
  210. package/src/execution/__tests__/settled-watchdog.test.ts +0 -524
  211. package/src/execution/__tests__/spawn-args.test.ts +0 -446
  212. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -192
  213. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  214. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -208
  215. package/src/execution/__tests__/spawned-children.test.ts +0 -236
  216. package/src/execution/__tests__/start-sync-model-guard.test.ts +0 -150
  217. package/src/execution/__tests__/stdin-writer.test.ts +0 -464
  218. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -693
  219. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  220. package/src/execution/__tests__/timeout-integration.test.ts +0 -616
  221. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  222. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  223. package/src/execution/__tests__/ui-request-handler.test.ts +0 -205
  224. package/src/execution/__tests__/ui-request-queue.test.ts +0 -298
  225. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -230
  226. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  227. package/src/execution/engine/__tests__/common/session-view-service-zcode-dbpath.test.ts +0 -149
  228. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  229. package/src/execution/engine/__tests__/conformance/zcode-appserver-harness.ts +0 -128
  230. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  231. package/src/execution/engine/common/schema-emulation.ts +0 -189
  232. package/src/execution/engine/common/session-view-projection.ts +0 -51
  233. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -615
  234. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  235. package/src/execution/engine/engines/pi/__tests__/spawn-opts-direct.test.ts +0 -257
  236. package/src/execution/engine/engines/pi/argv-mirror.ts +0 -135
  237. package/src/execution/engine/engines/pi/get-state-handshake.ts +0 -179
  238. package/src/execution/engine/engines/pi/output-collector.ts +0 -317
  239. package/src/execution/engine/engines/pi/pi-engine.ts +0 -811
  240. package/src/execution/engine/engines/pi/pi-invocation.ts +0 -120
  241. package/src/execution/engine/engines/pi/reader.ts +0 -59
  242. package/src/execution/engine/engines/pi/registration.ts +0 -37
  243. package/src/execution/engine/engines/pi/session-runner.ts +0 -2840
  244. package/src/execution/engine/engines/pi/spawn-event-adapter.ts +0 -404
  245. package/src/execution/engine/engines/pi/stdin-writer.ts +0 -199
  246. package/src/execution/engine/engines/pi/temp-prompt.ts +0 -62
  247. package/src/execution/engine/engines/pi/turn-limiter.ts +0 -102
  248. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/fake-appserver.mjs +0 -301
  249. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-appserver.json +0 -36
  250. package/src/execution/engine/engines/zcode/__tests__/appserver-launcher.test.ts +0 -321
  251. package/src/execution/engine/engines/zcode/__tests__/connection.test.ts +0 -473
  252. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -43
  253. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -124
  254. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  255. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -71
  256. package/src/execution/engine/engines/zcode/__tests__/session-channel-dispose-harvest.test.ts +0 -247
  257. package/src/execution/engine/engines/zcode/__tests__/session-channel-turn-timers.test.ts +0 -451
  258. package/src/execution/engine/engines/zcode/__tests__/session-channel.test.ts +0 -792
  259. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-appserver.test.ts +0 -782
  260. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-degrade.test.ts +0 -168
  261. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-dispose.test.ts +0 -210
  262. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-retry.test.ts +0 -353
  263. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-status.test.ts +0 -282
  264. package/src/execution/engine/engines/zcode/__tests__/zcode-engine-timeout.test.ts +0 -372
  265. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -145
  266. package/src/execution/engine/engines/zcode/appserver-launcher.ts +0 -167
  267. package/src/execution/engine/engines/zcode/connection.ts +0 -598
  268. package/src/execution/engine/engines/zcode/constants.ts +0 -176
  269. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -47
  270. package/src/execution/engine/engines/zcode/parser.ts +0 -102
  271. package/src/execution/engine/engines/zcode/preparer.ts +0 -235
  272. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  273. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  274. package/src/execution/engine/engines/zcode/session-channel.ts +0 -968
  275. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -1431
  276. package/src/execution/round-settlement.ts +0 -93
  277. package/src/execution/ui-request-queue.ts +0 -215
  278. package/src/shared/schema-env.ts +0 -44
@@ -1,254 +0,0 @@
1
- // src/execution/__tests__/run-spawn-chatmode-settled.test.ts
2
- //
3
- // [V2 模块 3] chatMode agent_settled 信号换挂单测(Step 3)。
4
- //
5
- // 验证 session-runner 的 V2 改动(5 处):
6
- // ① chatMode record agent_end 不触发 SIGTERM(进程保活,等 agent_settled)
7
- // ② chatMode record agent_settled 触发 armIdleTimer(fake timer + 超时后 kill)
8
- // ③ chatMode agent_settled 调 ctx.onRoundSettled(挂载点,mock 断言被调)
9
- // ④ 非 chatMode agent_settled 不 armIdleTimer、不调 onRoundSettled
10
- //
11
- // mock 结构与 run-spawn-edges.test.ts 一致(FakeChild + session-pending 受控 count=0)。
12
- // lifecycle-manager 用真实模块(hasIdleTimer / _resetLifecycleState 可观测 + 隔离)。
13
-
14
- import { spawn } from "node:child_process";
15
- import * as fs from "node:fs";
16
-
17
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
18
-
19
- vi.mock("node:child_process", async () => {
20
- const { FakeChild } = await import("./helpers/spawn-mock.ts");
21
- return {
22
- spawn: vi.fn(() => new FakeChild()),
23
- // buildEnvBlock 的 git branch 调用(execFile 异步):默认 err-first 兜底 → catch → branch=""
24
- execFile: vi.fn(
25
- (
26
- _cmd: string,
27
- _args: readonly string[],
28
- _opts: unknown,
29
- cb: (err: Error | null, stdout?: string, stderr?: string) => void,
30
- ) => cb(new Error("execFile not configured in this test")),
31
- ),
32
- };
33
- });
34
-
35
- vi.mock("node:fs", async () => {
36
- const actual = await import("node:fs");
37
- return {
38
- default: {
39
- ...actual,
40
- mkdirSync: vi.fn(),
41
- existsSync: vi.fn(() => false),
42
- appendFileSync: vi.fn(),
43
- writeFileSync: vi.fn(),
44
- readdirSync: vi.fn(() => []),
45
- },
46
- mkdirSync: vi.fn(),
47
- existsSync: vi.fn(() => false),
48
- appendFileSync: vi.fn(),
49
- writeFileSync: vi.fn(),
50
- readdirSync: vi.fn(() => []),
51
- promises: actual.promises,
52
- };
53
- });
54
-
55
- vi.mock("../alive-store.ts", () => ({
56
- writeAliveMarker: vi.fn(),
57
- }));
58
-
59
- // chatMode 测试不依赖后代判定(chatMode agent_end 早返回跳过 readActivePending),统一 count=0。
60
- // 非 chatMode 用例 ④ 的 agent_end 走正常 kill 分支(count=0 → SIGTERM)。
61
- vi.mock("../session-pending.ts", () => ({
62
- readActivePendingFromSessionFile: vi.fn(() => ({ count: 0 })),
63
- prunePendingCursor: vi.fn(),
64
- }));
65
-
66
- vi.mock("../engine/engines/pi/temp-prompt.ts", () => ({
67
- writePromptToTempFile: vi.fn(async (agent: string) => {
68
- const safeName = agent.replace(/[^\w.-]+/g, "_");
69
- return { dir: `/tmp/fake-${safeName}`, filePath: `/tmp/fake-${safeName}/prompt-${safeName}.md` };
70
- }),
71
- cleanupTempPrompt: vi.fn(async () => {}),
72
- }));
73
-
74
- import { runSpawn } from "../engine/engines/pi/session-runner.ts";
75
- import type { SessionRunnerContext } from "../engine/engines/pi/session-runner.ts";
76
- import {
77
- DEFAULT_IDLE_TIMEOUT_MS,
78
- hasIdleTimer,
79
- _resetLifecycleState,
80
- } from "../lifecycle-manager.ts";
81
- import { createRecord } from "../execution-record.ts";
82
- import type { ExecutionRecord } from "../types.ts";
83
- import {
84
- emitStdoutLine,
85
- type FakeChild,
86
- lastSpawnedChild as lastSpawnedChildOf,
87
- makeCtx,
88
- makeOpts,
89
- makeRecord,
90
- sessionHeader,
91
- waitForSpawn as waitForSpawnOf,
92
- } from "./helpers/spawn-mock.ts";
93
-
94
- const mockSpawn = vi.mocked(spawn);
95
-
96
- const lastSpawnedChild = (): FakeChild => lastSpawnedChildOf(mockSpawn);
97
- const waitForSpawn = (timeoutMs = 1000): Promise<void> => waitForSpawnOf(mockSpawn, timeoutMs);
98
-
99
- /** 构造 chatMode record(spawn-mock.makeRecord 默认非 chatMode,此处显式开启)。 */
100
- function makeChatModeRecord(id = "sa-chat"): ExecutionRecord {
101
- return createRecord(id, {
102
- agent: "general-purpose",
103
- model: "test-model",
104
- mode: "background",
105
- task: "chat task",
106
- slug: "chat",
107
- startedAt: 1_000_000,
108
- rootSessionId: "root-session",
109
- parentRecordId: undefined,
110
- depth: 0,
111
- chatMode: true,
112
- });
113
- }
114
-
115
- describe("[V2 模块 3] chatMode agent_settled 信号换挂", () => {
116
- beforeEach(() => {
117
- vi.clearAllMocks();
118
- // lifecycle-manager 是模块级单例(idleTimers Map 跨用例共享),每用例前清空防泄漏。
119
- _resetLifecycleState();
120
- });
121
-
122
- afterEach(() => {
123
- vi.restoreAllMocks();
124
- vi.useRealTimers();
125
- _resetLifecycleState();
126
- });
127
-
128
- it("① chatMode agent_end → 不触发 SIGTERM(进程保活,等 agent_settled)", async () => {
129
- const record = makeChatModeRecord("sa-chat-end");
130
- const promise = runSpawn(record, "Task: chatmode-end", makeOpts(), makeCtx());
131
-
132
- await waitForSpawn();
133
- const child = lastSpawnedChild();
134
-
135
- emitStdoutLine(child, sessionHeader());
136
- emitStdoutLine(child, { type: "agent_end", willRetry: false });
137
- // 让事件 pump 处理 agent_end(stream flush 异步)
138
- await new Promise((r) => setTimeout(r, 20));
139
-
140
- // [V2 决策 1] chatMode agent_end 不 kill——进程不因轮次死,等 agent_settled。
141
- expect(child.killed).toBe(false);
142
- // agent_end 不 arm idle timer(arm 点是 agent_settled,不是 agent_end)
143
- expect(hasIdleTimer(record.id)).toBe(false);
144
-
145
- // 收尾:手动 close 让 runSpawn resolve(模拟后续 idle timer 超时 kill / 外部终止)
146
- child.stdout.end();
147
- child.stderr.end();
148
- child.emit("close", 143);
149
- const result = await promise;
150
- expect(result.success).toBe(true);
151
- });
152
-
153
- it("② chatMode agent_settled → armIdleTimer,idle 超时后 SIGTERM kill", async () => {
154
- const record = makeChatModeRecord("sa-chat-settled");
155
- const promise = runSpawn(record, "Task: chatmode-settled", makeOpts(), makeCtx());
156
-
157
- await waitForSpawn();
158
- const child = lastSpawnedChild();
159
-
160
- // 必须在 emit agent_settled 前启用 fake timers——armIdleTimer 内 setTimeout 在 agent_settled
161
- // 处理器里新建,新建时已是 fake timer 才可 advance。不 fake setImmediate:stream flush 靠
162
- // 真实事件循环。对齐 run-spawn-edges MF-3/MF-4 模式。
163
- vi.useFakeTimers({ toFake: ["setTimeout", "clearTimeout", "Date"] });
164
- try {
165
- emitStdoutLine(child, sessionHeader());
166
- emitStdoutLine(child, { type: "agent_end", willRetry: false });
167
- await new Promise((r) => setImmediate(r));
168
- emitStdoutLine(child, { type: "agent_settled" });
169
- await new Promise((r) => setImmediate(r));
170
-
171
- // agent_settled → arm idle timer(DEFAULT_IDLE_TIMEOUT_MS = 5min)
172
- expect(hasIdleTimer(record.id)).toBe(true);
173
- // 进程仍存活(idle timer 未到期)
174
- expect(child.killed).toBe(false);
175
-
176
- // 未到 idle timeout(5min - 1ms):不 kill
177
- await vi.advanceTimersByTimeAsync(DEFAULT_IDLE_TIMEOUT_MS - 1);
178
- expect(child.killed).toBe(false);
179
-
180
- // idle timeout 到期:onTimeout → child.kill("SIGTERM")(复用现有 kill 路径)
181
- await vi.advanceTimersByTimeAsync(1);
182
- expect(child.killed).toBe(true);
183
- expect(child.killSignal).toBe("SIGTERM");
184
- // timer 触发后从 Map 移除(armIdleTimer 内 setTimeout 回调 idleTimers.delete)
185
- expect(hasIdleTimer(record.id)).toBe(false);
186
- } finally {
187
- vi.useRealTimers();
188
- }
189
-
190
- // 收尾:close 让 runSpawn resolve
191
- child.stdout.end();
192
- child.stderr.end();
193
- child.emit("close", 143);
194
- const result = await promise;
195
- expect(result.success).toBe(true);
196
- });
197
-
198
- it("③ chatMode agent_settled → 调 ctx.onRoundSettled(Step 3 挂载点,回调被调 1 次)", async () => {
199
- const record = makeChatModeRecord("sa-chat-cb");
200
- const onRoundSettled = vi.fn();
201
- const ctx: SessionRunnerContext = makeCtx({ onRoundSettled });
202
- const promise = runSpawn(record, "Task: chatmode-cb", makeOpts(), ctx);
203
-
204
- await waitForSpawn();
205
- const child = lastSpawnedChild();
206
-
207
- emitStdoutLine(child, sessionHeader());
208
- emitStdoutLine(child, { type: "agent_end", willRetry: false });
209
- await new Promise((r) => setTimeout(r, 10));
210
- emitStdoutLine(child, { type: "agent_settled" });
211
- await new Promise((r) => setTimeout(r, 10));
212
-
213
- // agent_settled → onRoundSettled 被调,入参是当前 record
214
- expect(onRoundSettled).toHaveBeenCalledTimes(1);
215
- expect(onRoundSettled).toHaveBeenCalledWith(record);
216
-
217
- // 收尾:手动 close(idle timer 仍 armed,由 afterEach _resetLifecycleState 清理)
218
- child.stdout.end();
219
- child.stderr.end();
220
- child.emit("close", 143);
221
- const result = await promise;
222
- expect(result.success).toBe(true);
223
- });
224
-
225
- it("④ 非 chatMode agent_settled → 不 armIdleTimer、不调 onRoundSettled", async () => {
226
- // makeRecord 默认非 chatMode(createRecord 未传 chatMode)
227
- const record = makeRecord("sa-nonchat-settled");
228
- const onRoundSettled = vi.fn();
229
- const ctx: SessionRunnerContext = makeCtx({ onRoundSettled });
230
- const promise = runSpawn(record, "Task: nonchat-settled", makeOpts(), ctx);
231
-
232
- await waitForSpawn();
233
- const child = lastSpawnedChild();
234
-
235
- emitStdoutLine(child, sessionHeader());
236
- // 直接 emit agent_settled(非 chatMode:handler 应忽略,不 arm、不调回调)
237
- emitStdoutLine(child, { type: "agent_settled" });
238
- await new Promise((r) => setTimeout(r, 20));
239
-
240
- expect(hasIdleTimer(record.id)).toBe(false);
241
- expect(onRoundSettled).not.toHaveBeenCalled();
242
-
243
- // 收尾:emit agent_end 走正常 kill 分支(count=0 → SIGTERM)→ close resolve
244
- emitStdoutLine(child, { type: "agent_end", willRetry: false });
245
- await new Promise((r) => setTimeout(r, 10));
246
- expect(child.killed).toBe(true); // 非 chatMode agent_end → kill(现有行为,V2 不动)
247
-
248
- child.stdout.end();
249
- child.stderr.end();
250
- child.emit("close", 143);
251
- const result = await promise;
252
- expect(result.success).toBe(true);
253
- });
254
- });