@zhushanwen/pi-subagent-workflow 8.5.0 → 8.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/package.json +13 -16
  2. package/relay/relay.mjs +1 -1
  3. package/src/host/__tests__/pi-host.test.ts +214 -0
  4. package/src/host/pi-host.ts +109 -0
  5. package/src/index.ts +142 -32
  6. package/src/injectors/__tests__/engine-awareness.test.ts +292 -0
  7. package/src/injectors/__tests__/engine-section-stability.test.ts +341 -0
  8. package/src/injectors/__tests__/subagent-list-injector.test.ts +5 -5
  9. package/src/injectors/__tests__/workflow-list-injector.test.ts +5 -5
  10. package/src/injectors/engine-awareness.ts +123 -0
  11. package/src/injectors/model-list-injector.ts +1 -1
  12. package/src/injectors/subagent-list-injector.ts +8 -8
  13. package/src/injectors/workflow-list-injector.ts +8 -8
  14. package/src/interface/__tests__/detectors.test.ts +3 -3
  15. package/src/interface/__tests__/subagent-tool-path-guard.test.ts +157 -0
  16. package/src/interface/__tests__/subagent-tool-prompt.test.ts +12 -0
  17. package/src/interface/__tests__/tool-workflow-script-generate.test.ts +2 -2
  18. package/src/interface/__tests__/tool-workflow-throw-paths.test.ts +1 -1
  19. package/src/interface/bg-notify-render.ts +34 -13
  20. package/src/interface/commands.ts +3 -3
  21. package/src/interface/format.ts +2 -2
  22. package/src/interface/helpers.ts +3 -3
  23. package/src/interface/list-component.ts +4 -4
  24. package/src/interface/list-shared.ts +2 -2
  25. package/src/interface/list-view.ts +2 -2
  26. package/src/interface/subagent-actions.ts +288 -19
  27. package/src/interface/subagent-tool-schema.ts +163 -0
  28. package/src/interface/subagent-tool.ts +65 -129
  29. package/src/interface/subagents.ts +5 -5
  30. package/src/interface/tool-render.ts +34 -2
  31. package/src/interface/tool-workflow-script.ts +4 -4
  32. package/src/interface/tool-workflow.ts +6 -6
  33. package/src/interface/views/WorkflowsView.ts +5 -5
  34. package/src/interface/views/__tests__/WorkflowsView-signature.test.ts +3 -3
  35. package/src/interface/views/__tests__/detail-content-session-file.test.ts +2 -2
  36. package/src/interface/views/detail-content.ts +4 -4
  37. package/src/interface/views/format.ts +4 -4
  38. package/src/{orchestration/jsonl-run-store.ts → jsonl-run-store.ts} +132 -18
  39. package/src/execution/__tests__/__fixtures__/notifier-golden-snapshots.json +0 -53
  40. package/src/execution/__tests__/__fixtures__/truncline.snapshot.json +0 -1
  41. package/src/execution/__tests__/agent-registry.test.ts +0 -363
  42. package/src/execution/__tests__/agent-result-mapper.test.ts +0 -150
  43. package/src/execution/__tests__/alive-store.test.ts +0 -147
  44. package/src/execution/__tests__/ask-user-transit-e2e.test.ts +0 -490
  45. package/src/execution/__tests__/before-agent-start-injection.test.ts +0 -132
  46. package/src/execution/__tests__/bg-notify-render.test.ts +0 -256
  47. package/src/execution/__tests__/channel-registry-handshake.test.ts +0 -243
  48. package/src/execution/__tests__/chat-engine-routing.test.ts +0 -597
  49. package/src/execution/__tests__/chatmode-first-round-closure-service.test.ts +0 -365
  50. package/src/execution/__tests__/chatmode-first-round-closure-spawn.test.ts +0 -190
  51. package/src/execution/__tests__/chatmode-round-notify-real-chain.test.ts +0 -215
  52. package/src/execution/__tests__/concurrency-pool.test.ts +0 -250
  53. package/src/execution/__tests__/config.test.ts +0 -110
  54. package/src/execution/__tests__/conversation-wiring.test.ts +0 -198
  55. package/src/execution/__tests__/crash-recovery.test.ts +0 -320
  56. package/src/execution/__tests__/delivery-methods.test.ts +0 -385
  57. package/src/execution/__tests__/dialog-queue.test.ts +0 -299
  58. package/src/execution/__tests__/epipe-fallback.test.ts +0 -241
  59. package/src/execution/__tests__/execute-and-await-worktree.test.ts +0 -243
  60. package/src/execution/__tests__/execute-nesting.test.ts +0 -323
  61. package/src/execution/__tests__/execute-options-mapper.test.ts +0 -189
  62. package/src/execution/__tests__/execution-record.test.ts +0 -1284
  63. package/src/execution/__tests__/finalize-record.test.ts +0 -368
  64. package/src/execution/__tests__/finalized-marker.test.ts +0 -82
  65. package/src/execution/__tests__/format-schema-instruction.test.ts +0 -138
  66. package/src/execution/__tests__/format.test.ts +0 -458
  67. package/src/execution/__tests__/gc-timer.test.ts +0 -184
  68. package/src/execution/__tests__/get-record-for-action-restart.test.ts +0 -254
  69. package/src/execution/__tests__/gui-mode-dispatch.test.ts +0 -59
  70. package/src/execution/__tests__/helpers/mock-extension-api.ts +0 -30
  71. package/src/execution/__tests__/helpers/spawn-mock.ts +0 -238
  72. package/src/execution/__tests__/host-mode.test.ts +0 -87
  73. package/src/execution/__tests__/index-session-start-identity.test.ts +0 -371
  74. package/src/execution/__tests__/index-session-start.test.ts +0 -593
  75. package/src/execution/__tests__/lifecycle-manager-lock.test.ts +0 -211
  76. package/src/execution/__tests__/lifecycle-manager.test.ts +0 -337
  77. package/src/execution/__tests__/lifecycle-predicates.test.ts +0 -116
  78. package/src/execution/__tests__/list-component.test.ts +0 -401
  79. package/src/execution/__tests__/list-fields.test.ts +0 -109
  80. package/src/execution/__tests__/manifest-parentid.test.ts +0 -117
  81. package/src/execution/__tests__/model-resolver.test.ts +0 -413
  82. package/src/execution/__tests__/nested-visibility-env-propagation.test.ts +0 -287
  83. package/src/execution/__tests__/nested-visibility.test.ts +0 -325
  84. package/src/execution/__tests__/notifier-flush.test.ts +0 -574
  85. package/src/execution/__tests__/notifier-golden-snapshot.test.ts +0 -261
  86. package/src/execution/__tests__/one-shot-upgrade.test.ts +0 -205
  87. package/src/execution/__tests__/output-collector.test.ts +0 -61
  88. package/src/execution/__tests__/parent-child-matrix.test.ts +0 -336
  89. package/src/execution/__tests__/path-encoding.test.ts +0 -104
  90. package/src/execution/__tests__/pi-invocation.test.ts +0 -134
  91. package/src/execution/__tests__/record-store.test.ts +0 -1057
  92. package/src/execution/__tests__/records-cwd-isolation.test.ts +0 -91
  93. package/src/execution/__tests__/recursive-visibility-baseline.test.ts +0 -339
  94. package/src/execution/__tests__/recursive-visibility-env.test.ts +0 -273
  95. package/src/execution/__tests__/relay-agent.test.ts +0 -448
  96. package/src/execution/__tests__/relay-env.test.ts +0 -42
  97. package/src/execution/__tests__/resource-policy.test.ts +0 -109
  98. package/src/execution/__tests__/rpc-mode.test.ts +0 -89
  99. package/src/execution/__tests__/run-and-finalize-chatmode.test.ts +0 -267
  100. package/src/execution/__tests__/run-spawn-chatmode-settled.test.ts +0 -253
  101. package/src/execution/__tests__/run-spawn-edges.test.ts +0 -644
  102. package/src/execution/__tests__/run-spawn-integration.test.ts +0 -933
  103. package/src/execution/__tests__/run-spawn-resume.test.ts +0 -322
  104. package/src/execution/__tests__/run-spawn-rpc-mode.test.ts +0 -196
  105. package/src/execution/__tests__/sdk-contract.test.ts +0 -273
  106. package/src/execution/__tests__/session-context-resolver.test.ts +0 -167
  107. package/src/execution/__tests__/session-file-gc.test.ts +0 -293
  108. package/src/execution/__tests__/session-pending.test.ts +0 -197
  109. package/src/execution/__tests__/session-reconstructor.test.ts +0 -379
  110. package/src/execution/__tests__/session-runner-epipe.test.ts +0 -178
  111. package/src/execution/__tests__/session-runner-schema-env.test.ts +0 -311
  112. package/src/execution/__tests__/session-start-reaper.test.ts +0 -233
  113. package/src/execution/__tests__/spawn-args.test.ts +0 -434
  114. package/src/execution/__tests__/spawn-event-adapter-rpc.test.ts +0 -189
  115. package/src/execution/__tests__/spawn-event-adapter.test.ts +0 -167
  116. package/src/execution/__tests__/spawn-worktree-guidance.test.ts +0 -207
  117. package/src/execution/__tests__/spawned-children.test.ts +0 -92
  118. package/src/execution/__tests__/startup-config-declaration.test.ts +0 -35
  119. package/src/execution/__tests__/status-refactor.test.ts +0 -345
  120. package/src/execution/__tests__/stdin-writer.test.ts +0 -463
  121. package/src/execution/__tests__/stream-sink-retirement.test.ts +0 -261
  122. package/src/execution/__tests__/subagent-service-abort.test.ts +0 -60
  123. package/src/execution/__tests__/subagent-service-message-close.test.ts +0 -629
  124. package/src/execution/__tests__/subagent-service-parent-guard.test.ts +0 -180
  125. package/src/execution/__tests__/subagent-service.test.ts +0 -788
  126. package/src/execution/__tests__/subprocess-agent-runner-routing.test.ts +0 -310
  127. package/src/execution/__tests__/subprocess-agent-runner.test.ts +0 -506
  128. package/src/execution/__tests__/temp-prompt.test.ts +0 -53
  129. package/src/execution/__tests__/timeout-integration.test.ts +0 -397
  130. package/src/execution/__tests__/tombstone-store.test.ts +0 -73
  131. package/src/execution/__tests__/tool-action.test.ts +0 -385
  132. package/src/execution/__tests__/truncline-snapshot.test.ts +0 -81
  133. package/src/execution/__tests__/turn-limiter-semantics.test.ts +0 -194
  134. package/src/execution/__tests__/turn-limiter.test.ts +0 -65
  135. package/src/execution/__tests__/ui-channels.test.ts +0 -187
  136. package/src/execution/__tests__/ui-interaction-model.test.ts +0 -67
  137. package/src/execution/__tests__/ui-request-handler-factory.test.ts +0 -370
  138. package/src/execution/__tests__/ui-request-handler.test.ts +0 -204
  139. package/src/execution/__tests__/ui-request-observability.test.ts +0 -114
  140. package/src/execution/__tests__/ui-request-queue.test.ts +0 -133
  141. package/src/execution/__tests__/worktree-manager.test.ts +0 -633
  142. package/src/execution/__tests__/worktree-pid-registration.integration.test.ts +0 -229
  143. package/src/execution/__tests__/worktree-reconcile.integration.test.ts +0 -181
  144. package/src/execution/__tests__/worktree-registry.test.ts +0 -199
  145. package/src/execution/agent-registry.ts +0 -193
  146. package/src/execution/agent-result-mapper.ts +0 -90
  147. package/src/execution/alive-store.ts +0 -92
  148. package/src/execution/argv-mirror.ts +0 -109
  149. package/src/execution/best-effort.ts +0 -38
  150. package/src/execution/channel-registry-access.ts +0 -144
  151. package/src/execution/concurrency-pool.ts +0 -116
  152. package/src/execution/config.ts +0 -96
  153. package/src/execution/dialog-queue.ts +0 -330
  154. package/src/execution/engine/__tests__/common/data-dir.test.ts +0 -53
  155. package/src/execution/engine/__tests__/common/errors.test.ts +0 -132
  156. package/src/execution/engine/__tests__/common/event-journal.test.ts +0 -177
  157. package/src/execution/engine/__tests__/common/kill-chain.test.ts +0 -192
  158. package/src/execution/engine/__tests__/common/nesting-guard.test.ts +0 -81
  159. package/src/execution/engine/__tests__/common/persona-router.test.ts +0 -123
  160. package/src/execution/engine/__tests__/common/pool-manager.test.ts +0 -154
  161. package/src/execution/engine/__tests__/common/schema-emulation.test.ts +0 -128
  162. package/src/execution/engine/__tests__/conformance/__fixtures__/pi-golden-events.json +0 -28
  163. package/src/execution/engine/__tests__/conformance/agent-event-invariants.ts +0 -141
  164. package/src/execution/engine/__tests__/conformance/contract.abort.test.ts +0 -109
  165. package/src/execution/engine/__tests__/conformance/contract.agent-events.test.ts +0 -101
  166. package/src/execution/engine/__tests__/conformance/contract.probe.test.ts +0 -77
  167. package/src/execution/engine/__tests__/conformance/contract.read-degradation.test.ts +0 -104
  168. package/src/execution/engine/__tests__/conformance/contract.relay.test.ts +0 -342
  169. package/src/execution/engine/__tests__/conformance/engine-conformance.live.test.ts +0 -201
  170. package/src/execution/engine/__tests__/conformance/golden-replay.pi.test.ts +0 -76
  171. package/src/execution/engine/__tests__/conformance/golden-replay.zcode.test.ts +0 -79
  172. package/src/execution/engine/__tests__/engine-discovery.test.ts +0 -87
  173. package/src/execution/engine/__tests__/engines-declaration.test.ts +0 -36
  174. package/src/execution/engine/__tests__/model-prompt.test.ts +0 -85
  175. package/src/execution/engine/__tests__/paths.test.ts +0 -39
  176. package/src/execution/engine/__tests__/registry.test.ts +0 -120
  177. package/src/execution/engine/__tests__/routing.test.ts +0 -231
  178. package/src/execution/engine/common/data-dir.ts +0 -62
  179. package/src/execution/engine/common/errors.ts +0 -183
  180. package/src/execution/engine/common/event-journal.ts +0 -254
  181. package/src/execution/engine/common/journal-replay.ts +0 -62
  182. package/src/execution/engine/common/kill-chain.ts +0 -221
  183. package/src/execution/engine/common/nesting-guard.ts +0 -50
  184. package/src/execution/engine/common/persona-router.ts +0 -108
  185. package/src/execution/engine/common/pool-manager.ts +0 -226
  186. package/src/execution/engine/common/schema-emulation.ts +0 -189
  187. package/src/execution/engine/common/session-view-projection.ts +0 -51
  188. package/src/execution/engine/engine-discovery.ts +0 -65
  189. package/src/execution/engine/engines/pi/__tests__/pi-engine.test.ts +0 -469
  190. package/src/execution/engine/engines/pi/__tests__/reader.test.ts +0 -155
  191. package/src/execution/engine/engines/pi/__tests__/task-spec-mapper.test.ts +0 -164
  192. package/src/execution/engine/engines/pi/pi-engine.ts +0 -415
  193. package/src/execution/engine/engines/pi/reader.ts +0 -48
  194. package/src/execution/engine/engines/pi/registration.ts +0 -35
  195. package/src/execution/engine/engines/pi/task-spec-mapper.ts +0 -100
  196. package/src/execution/engine/engines/zcode/__tests__/__fixtures__/zcode-golden-spawn.json +0 -39
  197. package/src/execution/engine/engines/zcode/__tests__/launcher.test.ts +0 -150
  198. package/src/execution/engine/engines/zcode/__tests__/parser.test.ts +0 -246
  199. package/src/execution/engine/engines/zcode/__tests__/preparer.test.ts +0 -228
  200. package/src/execution/engine/engines/zcode/__tests__/reader.test.ts +0 -210
  201. package/src/execution/engine/engines/zcode/__tests__/registration.test.ts +0 -64
  202. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.live.test.ts +0 -127
  203. package/src/execution/engine/engines/zcode/__tests__/zcode-engine.test.ts +0 -567
  204. package/src/execution/engine/engines/zcode/constants.ts +0 -43
  205. package/src/execution/engine/engines/zcode/golden-sample.ts +0 -39
  206. package/src/execution/engine/engines/zcode/launcher.ts +0 -161
  207. package/src/execution/engine/engines/zcode/parser.ts +0 -436
  208. package/src/execution/engine/engines/zcode/preparer.ts +0 -363
  209. package/src/execution/engine/engines/zcode/reader.ts +0 -381
  210. package/src/execution/engine/engines/zcode/registration.ts +0 -37
  211. package/src/execution/engine/engines/zcode/zcode-engine.ts +0 -648
  212. package/src/execution/engine/host-task-spec.ts +0 -47
  213. package/src/execution/engine/model-prompt.ts +0 -59
  214. package/src/execution/engine/paths.ts +0 -42
  215. package/src/execution/engine/port.ts +0 -153
  216. package/src/execution/engine/registry.ts +0 -123
  217. package/src/execution/engine/routing.ts +0 -218
  218. package/src/execution/engine/types.ts +0 -304
  219. package/src/execution/execute-options-mapper.ts +0 -111
  220. package/src/execution/execution-record.ts +0 -906
  221. package/src/execution/finalize-record.ts +0 -251
  222. package/src/execution/finalized-marker.ts +0 -51
  223. package/src/execution/get-state-handshake.ts +0 -104
  224. package/src/execution/host-mode.ts +0 -56
  225. package/src/execution/idle-gc.ts +0 -47
  226. package/src/execution/lifecycle-manager.ts +0 -491
  227. package/src/execution/lifecycle-predicates.ts +0 -65
  228. package/src/execution/manifest-store.ts +0 -256
  229. package/src/execution/model-config-service.ts +0 -204
  230. package/src/execution/model-resolver.ts +0 -276
  231. package/src/execution/notifier.ts +0 -260
  232. package/src/execution/output-collector.ts +0 -88
  233. package/src/execution/path-encoding.ts +0 -60
  234. package/src/execution/pi-invocation.ts +0 -120
  235. package/src/execution/record-entry.ts +0 -132
  236. package/src/execution/record-store.ts +0 -1234
  237. package/src/execution/relay-env.ts +0 -37
  238. package/src/execution/session-context-resolver.ts +0 -64
  239. package/src/execution/session-file-gc.ts +0 -120
  240. package/src/execution/session-pending.ts +0 -164
  241. package/src/execution/session-reconstructor.ts +0 -678
  242. package/src/execution/session-runner.ts +0 -1548
  243. package/src/execution/sessions-index.ts +0 -304
  244. package/src/execution/spawn-event-adapter.ts +0 -363
  245. package/src/execution/stdin-writer.ts +0 -198
  246. package/src/execution/stream-sink.ts +0 -126
  247. package/src/execution/subagent-service.ts +0 -2119
  248. package/src/execution/subprocess-agent-runner.ts +0 -303
  249. package/src/execution/temp-prompt.ts +0 -62
  250. package/src/execution/tombstone-store.ts +0 -72
  251. package/src/execution/turn-limiter.ts +0 -102
  252. package/src/execution/types.ts +0 -910
  253. package/src/execution/ui-channels.ts +0 -216
  254. package/src/execution/ui-interaction-model.ts +0 -48
  255. package/src/execution/ui-request-handler-factory.ts +0 -212
  256. package/src/execution/ui-request-observability.ts +0 -81
  257. package/src/execution/ui-request-queue.ts +0 -174
  258. package/src/execution/worktree-manager.ts +0 -688
  259. package/src/execution/worktree-registry.ts +0 -222
  260. package/src/orchestration/__tests__/__fixtures__/worker-template.snapshot.txt +0 -336
  261. package/src/orchestration/__tests__/agent-call-catch-fallback.test.ts +0 -208
  262. package/src/orchestration/__tests__/agent-call-stream.test.ts +0 -157
  263. package/src/orchestration/__tests__/args-validator.test.ts +0 -143
  264. package/src/orchestration/__tests__/concurrency-gate.test.ts +0 -125
  265. package/src/orchestration/__tests__/config-loader.test.ts +0 -503
  266. package/src/orchestration/__tests__/error-recovery-handlers.test.ts +0 -724
  267. package/src/orchestration/__tests__/error-recovery-postmessage-defense.test.ts +0 -405
  268. package/src/orchestration/__tests__/error-recovery-serialize-failed-result.test.ts +0 -56
  269. package/src/orchestration/__tests__/error-recovery-workflow-call.test.ts +0 -166
  270. package/src/orchestration/__tests__/execute-agent-call.test.ts +0 -314
  271. package/src/orchestration/__tests__/jsonl-run-store-loadall-sources.test.ts +0 -171
  272. package/src/orchestration/__tests__/jsonl-run-store-session-file.test.ts +0 -1030
  273. package/src/orchestration/__tests__/launcher-nested-workflow.test.ts +0 -277
  274. package/src/orchestration/__tests__/lifecycle-runid-injection.test.ts +0 -96
  275. package/src/orchestration/__tests__/lifecycle.test.ts +0 -625
  276. package/src/orchestration/__tests__/review-fix-loop-e2e.test.ts +0 -1971
  277. package/src/orchestration/__tests__/script-lint.test.ts +0 -831
  278. package/src/orchestration/__tests__/skill-discovery.test.ts +0 -157
  279. package/src/orchestration/__tests__/test-mocks.ts +0 -197
  280. package/src/orchestration/__tests__/worker-host.test.ts +0 -120
  281. package/src/orchestration/__tests__/worker-returnmeta-passthrough.test.ts +0 -164
  282. package/src/orchestration/__tests__/worker-script-builder-runtime.test.ts +0 -520
  283. package/src/orchestration/__tests__/worker-script-builder.test.ts +0 -309
  284. package/src/orchestration/__tests__/worker-script-template-snapshot.test.ts +0 -110
  285. package/src/orchestration/__tests__/workflow-nesting-e2e.test.ts +0 -317
  286. package/src/orchestration/__tests__/workflow-script-lint-memo.test.ts +0 -110
  287. package/src/orchestration/__tests__/workflows-e2e.test.ts +0 -537
  288. package/src/orchestration/agent-opts-resolver.ts +0 -93
  289. package/src/orchestration/args-validator.ts +0 -127
  290. package/src/orchestration/concurrency-gate.ts +0 -69
  291. package/src/orchestration/config-loader.ts +0 -315
  292. package/src/orchestration/error-recovery.ts +0 -862
  293. package/src/orchestration/execute-agent-call.ts +0 -217
  294. package/src/orchestration/launcher.ts +0 -410
  295. package/src/orchestration/lifecycle.ts +0 -396
  296. package/src/orchestration/models/__tests__/budget.test.ts +0 -367
  297. package/src/orchestration/models/__tests__/trace.test.ts +0 -408
  298. package/src/orchestration/models/agent-call.ts +0 -83
  299. package/src/orchestration/models/budget.ts +0 -148
  300. package/src/orchestration/models/ports.ts +0 -164
  301. package/src/orchestration/models/run-runtime.ts +0 -89
  302. package/src/orchestration/models/run-spec.ts +0 -83
  303. package/src/orchestration/models/run-state.ts +0 -44
  304. package/src/orchestration/models/trace.ts +0 -183
  305. package/src/orchestration/models/types.ts +0 -292
  306. package/src/orchestration/models/workflow-run.ts +0 -254
  307. package/src/orchestration/models/workflow-script-registry.ts +0 -35
  308. package/src/orchestration/models/workflow-script.ts +0 -117
  309. package/src/orchestration/script-lint.ts +0 -766
  310. package/src/orchestration/skill-discovery.ts +0 -92
  311. package/src/orchestration/worker-handle.ts +0 -115
  312. package/src/orchestration/worker-host.ts +0 -98
  313. package/src/orchestration/worker-script-builder.ts +0 -408
  314. package/src/orchestration/workflow-files.ts +0 -85
  315. package/src/orchestration/workflow-script-registry-impl.ts +0 -133
  316. package/src/shared/__tests__/agent-ref.test.ts +0 -34
  317. package/src/shared/__tests__/meta-parser.test.ts +0 -304
  318. package/src/shared/__tests__/resource-discovery-manifest-cache.test.ts +0 -280
  319. package/src/shared/__tests__/resource-discovery.test.ts +0 -736
  320. package/src/shared/__tests__/resource-meta.test.ts +0 -51
  321. package/src/shared/__tests__/schema-jsonify.test.ts +0 -81
  322. package/src/shared/agent-event.ts +0 -13
  323. package/src/shared/agent-ref.ts +0 -57
  324. package/src/shared/meta-parser.ts +0 -261
  325. package/src/shared/resource-discovery.ts +0 -811
  326. package/src/shared/resource-meta.ts +0 -65
  327. package/src/shared/schema-jsonify.ts +0 -56
  328. package/src/shared/xml-injection.ts +0 -35
  329. package/workflows/README.md +0 -81
  330. package/workflows/_shared/agent-refs.cjs +0 -40
  331. package/workflows/chain.js +0 -131
  332. package/workflows/map-reduce.js +0 -174
  333. package/workflows/parallel.js +0 -148
  334. package/workflows/review-fix-loop-utils.cjs +0 -1307
  335. package/workflows/review-fix-loop.js +0 -1396
  336. package/workflows/scatter-gather.js +0 -178
@@ -1,251 +0,0 @@
1
- // src/execution/finalize-record.ts
2
- //
3
- // 时序收尾逻辑(从 subagent-service.ts 提取,降低主文件行数 < 1000 上限)。
4
- //
5
- // D-017 时序:collectPatch → completeRecord → archive → cleanup(finalized+worktree+
6
- // aliveMarker+pending注销) → manifest(最后 best-effort)。
7
- //
8
- // [Critical #1 / PR #85] cleanup 全部在 manifest 写之前执行——manifest 是诊断辅助
9
- //(orphan recovery),写失败仅记录不阻断。旧实现 Step 2.5 throw 会跳过 Step 3 cleanup,
10
- // 导致磁盘满/权限错时 worktree 泄漏 + finalized marker 不写 + alive marker 残留 +
11
- // pending 记账错乱。现 manifest 写移到 Step 4(最后),best-effort(console.error +
12
- // appendEntry,不 throw)。
13
- //
14
- // B9 兜底:completeRecord/archive 抛错→后续 cleanup/manifest 仍执行。
15
-
16
- import * as fs from "node:fs";
17
- import * as path from "node:path";
18
-
19
- import { getLogger } from "@zhushanwen/pi-extension-logger";
20
-
21
- import { removeAliveMarker } from "./alive-store.ts";
22
- import { bestEffort } from "./best-effort.ts";
23
- import { completeRecord } from "./execution-record.ts";
24
- import { writeFinalized } from "./finalized-marker.ts";
25
- import type { ManifestStore } from "./manifest-store.ts";
26
- import type { ModelConfigService } from "./model-config-service.ts";
27
- import { getSubagentSessionDir } from "./path-encoding.ts";
28
- import type { RecordStore } from "./record-store.ts";
29
- import { writeCancelledTombstone } from "./tombstone-store.ts";
30
- import type { AgentResult, ClosedReason, ExecutionRecord } from "./types.ts";
31
- import type { WorktreeManager } from "./worktree-manager.ts";
32
-
33
- const logger = getLogger("subagents");
34
-
35
- /** doFinalizeRecord 的依赖(从 SubagentService 注入,避免 this 绑定 + 解耦可测试)。 */
36
- export interface FinalizeDeps {
37
- manifestStore: ManifestStore;
38
- worktreeManager: WorktreeManager;
39
- store: RecordStore;
40
- modelService: ModelConfigService;
41
- /** Pi ExtensionAPI(仅用 appendEntry 记录 manifest 写失败事件)。null 在 dispose 后。 */
42
- pi: { appendEntry?: (type: string, data: unknown) => void } | null;
43
- /** pending-notifications 终态注销(绑定 pi.events.emit,由调用方闭包提供)。 */
44
- emitUnregister(id: string, status: string): void;
45
- // [review 修复] 已删除 redeliverPending 回调(MF-1 消费确认制补投):pendingMessages
46
- // 三段消费链随 deliverToRunning 一并移除(无生产调用方,死机制)。
47
- }
48
-
49
- /**
50
- * 时序收尾(D-017)。步骤 0→4 全部 best-effort 互不阻断(除 manifest 外都幂等)。
51
- *
52
- * [Critical #1] Step 3 cleanup 全部在 Step 4 manifest 之前——manifest 写失败仅 console.error +
53
- * appendEntry,不 throw 不跳过 cleanup。task/slug/model 从 ExecutionRecord 抓取(配合 ManifestRecord
54
- * 补字段),manifestToSubagent 投影真实值而非硬编码空串。
55
- */
56
- export async function doFinalizeRecord(
57
- deps: FinalizeDeps,
58
- record: ExecutionRecord,
59
- result: AgentResult,
60
- status: "closed",
61
- closedReason?: ClosedReason,
62
- ): Promise<void> {
63
- // ── Step 0: collectPatch(best-effort)──
64
- // [MF#3] patchFile 写到 worktree 之外(sessionsDir/<branch>.patch),避免被 cleanup 删除;
65
- // 路径回填 record.patchFile,供调用方(tool result / /subagents list)应用。
66
- if (record.worktreeHandle) {
67
- try {
68
- const sessionsDir = getSubagentSessionDir(
69
- deps.modelService.getAgentDir(),
70
- record.worktreeHandle.mainCwd,
71
- );
72
- fs.mkdirSync(sessionsDir, { recursive: true });
73
- const patchFile = path.join(sessionsDir, `${record.worktreeHandle.branch}.patch`);
74
- const patch = await deps.worktreeManager.collectPatch(record.worktreeHandle, patchFile);
75
- if (patch.written) record.patchFile = patchFile;
76
- } catch (pe: unknown) {
77
- bestEffort(pe, "collectPatch (finalizeRecord Step0)");
78
- }
79
- }
80
-
81
- // ── Step 1: completeRecord(B9: 抛错→后续仍执行)──
82
- try {
83
- completeRecord(record, result, status, closedReason);
84
- } catch (err) {
85
- bestEffort(err, "completeRecord (finalizeRecord B9)", "error");
86
- }
87
-
88
- // ── Step 2: archive(B9: 抛错→后续仍执行)──
89
- try {
90
- deps.store.archive(record);
91
- } catch (err) {
92
- bestEffort(err, "store.archive (finalizeRecord B9)", "error");
93
- }
94
-
95
- // ── Step 3: finalized + cleanup + aliveMarker + pending注销(全部先执行,幂等)──
96
- // [Critical] 清理必须在 manifest 写入之前:worktree cleanup / finalized marker / aliveMarker
97
- // 都是幂等且不可跳过的副作用。绝不能因 manifest 写失败而跳过 worktree cleanup
98
- // (否则 worktree 泄漏)。各件独立 try/catch,互不阻断。
99
- if (record.sessionFile) {
100
- try {
101
- // MF-1 fix / v4 B-1: cancelled(closedReason='cancelled')写 tombstone 而非 finalized,防重建丢失 cancelled
102
- if (closedReason === "cancelled") {
103
- writeCancelledTombstone(record.sessionFile, {
104
- id: record.id,
105
- status: "cancelled",
106
- agent: record.agent,
107
- startedAt: record.startedAt,
108
- endedAt: record.endedAt ?? Date.now(),
109
- });
110
- } else {
111
- writeFinalized(record.sessionFile);
112
- }
113
- } catch (err) {
114
- bestEffort(err, "writeFinalized/tombstone (finalizeRecord Step3)");
115
- }
116
- }
117
- if (record.worktreeHandle) {
118
- try {
119
- await deps.worktreeManager.cleanup(record.worktreeHandle);
120
- } catch (err) {
121
- bestEffort(err, "worktree cleanup (finalizeRecord Step3)");
122
- }
123
- }
124
- if (record.sessionFile) {
125
- try {
126
- removeAliveMarker(record.sessionFile);
127
- } catch (err) {
128
- bestEffort(err, "removeAliveMarker (finalizeRecord Step3)");
129
- }
130
- }
131
-
132
- // pending-notifications:终态注销(只记 registry 状态,通知由 BgNotifier 发)
133
- deps.emitUnregister(record.id, status);
134
-
135
- // ── Step 4 (last): manifest 持久化(best-effort,不阻断、不 throw)──
136
- // [Critical #1] manifest 是诊断辅助(orphan recovery),不是正确性依赖。写失败时
137
- // 仅记录(console.error + appendEntry),绝不让 manifest 写失败跳过上面的 worktree
138
- // cleanup 或抛出打断 finalize 链。旧实现 Step 2.5 throw 会跳过 Step 3 cleanup。
139
- // task/slug/model 从 ExecutionRecord 抓取(配合 ManifestRecord 补字段),
140
- // manifestToSubagent 投影时用真实值而非硬编码空串。
141
- try {
142
- await deps.manifestStore.writeManifest({
143
- id: record.id,
144
- rootSessionId: record.rootSessionId ?? "",
145
- parentRecordId: record.parentRecordId,
146
- agentName: record.agent,
147
- // v4 B-1: manifest status 统一为 closed(cancelled 折入 closed,区分靠 tombstone sidecar)
148
- status: "closed",
149
- createdAt: record.startedAt,
150
- completedAt: record.endedAt ?? Date.now(),
151
- sessionFile: record.sessionFile,
152
- task: record.task,
153
- slug: record.slug,
154
- model: record.model,
155
- });
156
- } catch (err) {
157
- const msg = err instanceof Error ? err.message : String(err);
158
- logger.error(`[subagent] manifest 写入失败 (record=${record.id}): ${msg}`);
159
- deps.pi?.appendEntry?.("subagent:manifest-write-failed", {
160
- id: record.id,
161
- error: msg,
162
- });
163
- }
164
- }
165
-
166
- /**
167
- * 对话模式轮次完成收尾:record 进 idle 态(非终态化,等待续聊)。
168
- *
169
- * 与 doFinalizeRecord 的关键区别(M2-A idle 语义):
170
- * - 不调 completeRecord(record 不冻结,保留 turns[] 等运行时状态供续聊累积)
171
- * - 不调 store.archive(record 留内存,getMutable 可查、list 可见)
172
- * - 不 cleanup worktree(保留对话模式工作目录)
173
- * - 不写 manifest(idle 非终态,manifest 是终态诊断辅助)
174
- * - 删 .alive marker(进程已 SIGTERM 回收,不再是活进程)
175
- * - emitUnregister(进程已死,从 pending 活跃后代差集移除;record 留内存不 archive)
176
- *
177
- * MF-2:设 record.result = result.text(否则 notifier idle 回复正文恒为 "(empty)",
178
- * G1/G2 多轮回复送达不成立)。失败轮次(result.success=false,MF-6 回退 idle 路径)
179
- * 的 result.text 可能为空,用 result.error 兜底让 notify 可读。
180
- *
181
- * 状态:record.status = "idle"(覆盖 tryTransition 设的 done/failed),record.round += 1。
182
- * 各步骤 best-effort 互不阻断(参照 doFinalizeRecord 的 bestEffort 用法)。
183
- *
184
- * @param deps 与 doFinalizeRecord 同源(从 SubagentService 注入)
185
- * @param result 本轮 AgentResult(MF-2:result.text 写入 record.result 供 notifier idle 回复)
186
- */
187
- export async function doFinalizeRoundToIdle(
188
- deps: FinalizeDeps,
189
- record: ExecutionRecord,
190
- result: AgentResult,
191
- ): Promise<void> {
192
- // MF-2:设 record.result 供 notifier idle 回复正文(否则恒 "(empty)",G1/G2 不成立)。
193
- // MF-6 兜底:失败轮次(success=false)的 result.text 可能为空,用 error 让 notify 可读。
194
- // [R2-1] 轮终写点恒写非空:one-shot 空文本成功完成(collectResult getFullText 返回 ""、
195
- // success=true、真实可达,本写点被 subagent-service runAndFinalize 的成功分支共用)首轮
196
- // result 前值 undefined,兜底补 "(empty)" 占位——措辞与 notifier buildLlmContent 的
197
- // `record.result ?? "(empty)"` 兜底同款,通知文案逐字节不变([增量 G2] G4 取舍保持)。
198
- // 轮终信号优先:record.result 非 undefined 是 renderer hasRunning 排除「轮终
199
- // running-resumable」的判据(shared SubagentRecord.result 契约),保持 undefined 会让
200
- // 完成注入后末位 turn 永久「工作中」。续轮(前值存在)沿用前值:one-shot 无增量语义,
201
- // record.result = 该 subagent 最终输出。chatMode 空增量轮 → 固定占位
202
- // "(no output this round)"(D5:增量语义下沿用旧 record.result = 上一轮增量,本轮通知
203
- // 正文 = 上一轮内容,父 agent 误读为原样重复回复)。
204
- let nextResult: string | undefined;
205
- if (result.text) {
206
- nextResult = result.text;
207
- } else if (result.error) {
208
- nextResult = `round did not complete: ${result.error}`;
209
- } else if (record.chatMode) {
210
- nextResult = "(no output this round)";
211
- } else {
212
- nextResult = record.result ?? "(empty)";
213
- }
214
- record.result = nextResult;
215
-
216
- // 删 .alive marker(进程已 SIGTERM 回收)。
217
- // sessionFile 窗口期可能 undefined(极少——对话模式轮次完成意味着 session 已跑过),
218
- // 缺失时跳过但仍设内存 idle(重启后磁盘重建会落到 crashed,边界可接受)。
219
- if (record.sessionFile) {
220
- try {
221
- removeAliveMarker(record.sessionFile);
222
- } catch (err) {
223
- bestEffort(err, "removeAliveMarker (doFinalizeRoundToIdle)");
224
- }
225
- }
226
-
227
- // pending-notifications:进程已死,从活跃后代差集移除(record 留内存不 archive,
228
- // v4 B-1:record 现为 running-resumable,但 pending 注册的是进程活跃性,进程死了需注销)。
229
- deps.emitUnregister(record.id, "running");
230
-
231
- // 状态机(v4 B-1):record 保持 running(旧 idle 折入 running,覆盖 tryTransition 设的 closed,
232
- // 可冷路径 resume),轮次计数 +1。idleSince 时间戳独立保留供 GC 判据。
233
- // [S10] closedReason 同步清除:调用方(runAndFinalize catch / MF-6 分支)先 tryTransition
234
- // 设了 closed+closedReason 再回退 running——不清则 "gc"/"cancelled" 残留在 running record 上,
235
- // 泄漏进 list 投影与后续 notify 载荷(toNotifyRecord 透传 record.closedReason),让一个
236
- // 活跃 record 看起来像已被某原因关闭过。
237
- record.status = "running";
238
- record.closedReason = undefined;
239
- record.round = (record.round ?? 0) + 1;
240
- record.idleSince = Date.now();
241
- // 执行态信号(residual-fixes):轮终回 running-resumable = 无活进程驱动(idle timer
242
- // 回收/保活等待续聊),GUI 侧据此判 waiting(非 streaming)。冷路径续轮(进程启动)清除。
243
- record.resumable = true;
244
-
245
- // W16 [D4]:轮终回 running-resumable 是类外状态写点(record 留内存不走 archive),
246
- // 显式上报迁移——entry 携带新 round 与本轮 result,pi 文件的重建源不滞后。
247
- deps.store.reportRecordTransition(record);
248
-
249
- // [review 修复] 已删除残留 pendingMessages 的 redeliverPending 补投段(MF-1 消费
250
- // 确认安全网):三段消费链随 deliverToRunning 一并移除,本段不可达。
251
- }
@@ -1,51 +0,0 @@
1
- // src/runtime/execution/finalized-marker.ts
2
- //
3
- // Finalized 状态的 sidecar 持久化。
4
- //
5
- // 背景:subagent 执行完成(done/failed)后,session.jsonl 的最终写入可能因进程
6
- // 异常终止而丢失。`.finalized` sidecar 标记该 session 已正常结束,collectRecords
7
- // 重建时可用它区分「正常结束但文件截断」与「执行中断」。
8
- //
9
- // 设计:对称 cancelled sidecar(tombstone-store.ts)。`.finalized` 为空文件,
10
- // 存在性即信号(done/failed 的细分仍靠 recon.stopReason 推断)。与 `.cancelled`
11
- // 互斥——一个 session 要么 finalized 要么 cancelled,不可能两者兼有。
12
- //
13
- // best-effort:写 IO 错静默,不阻断主流程。
14
-
15
- import * as fs from "node:fs";
16
-
17
- // ============================================================
18
- // 公开函数
19
- // ============================================================
20
-
21
- /**
22
- * 在 session.jsonl 旁写 `.finalized` sidecar(空文件)。
23
- * best-effort:任何 I/O 错误静默(finalize 标记是次要信号,status 已在内存 record 上设好)。
24
- *
25
- * 与 `.cancelled` 互斥(BC-4):写前删除 `.cancelled`(如存在),确保不会两者共存。
26
- */
27
- export function writeFinalized(sessionFile: string): void {
28
- try {
29
- // BC-4 互斥:清理可能存在的 .cancelled。force:true 静默 ENOENT——
30
- // 未 cancel 过的 session(done/failed/aborted)本就无 .cancelled,属正常路径。
31
- // 此前用 unlinkSync+bestEffort 记 console.debug,取消嵌套链条时每层 ENOENT 刷屏。
32
- fs.rmSync(`${sessionFile}.cancelled`, { force: true });
33
- fs.writeFileSync(`${sessionFile}.finalized`, "", "utf-8");
34
- } catch (_e) {
35
- void _e; // 静默:写失败不阻断 finalize 主流程。
36
- }
37
- }
38
-
39
- /**
40
- * 读 session.jsonl 旁的 `.finalized` sidecar。
41
- * 返回 true:sidecar 存在(内容不校验,存在性即信号)。
42
- * 返回 false:sidecar 不存在 / 读取失败。
43
- */
44
- export function readFinalized(sessionFile: string): boolean {
45
- try {
46
- fs.accessSync(`${sessionFile}.finalized`);
47
- return true;
48
- } catch {
49
- return false;
50
- }
51
- }
@@ -1,104 +0,0 @@
1
- // src/execution/get-state-handshake.ts
2
- //
3
- // FR-4: get_state RPC 握手逻辑。
4
- //
5
- // 从 session-runner.ts 提取(保持文件 < 1000 行)。职责单一:通过 get_state RPC
6
- // 查询子进程 sessionFile/sessionId,带超时重试。session-runner spawn 后无条件调用。
7
- //
8
- // 设计要点:
9
- // - 重试节奏:单次超时 GET_STATE_TIMEOUT_MS(2s)后,等 GET_STATE_RETRY_INTERVAL_MS(500ms)
10
- // 再发起下一次 get_state,最多 GET_STATE_MAX_RETRIES(3)次。修复点:旧实现超时后
11
- // 立即递归 tryOnce(),GET_STATE_RETRY_INTERVAL_MS 声明了却从未使用(eslint error 阻断),
12
- // 现在让常量名与行为一致——重试前真的等间隔。
13
- // - 加速路径:sessionFile 一旦拿到立即 resolve(不等剩余重试)。
14
- // - 全部超时:resolve 空对象(调用方走兜底查找)。
15
-
16
- import type { ChildProcess } from "node:child_process";
17
-
18
- import { sendGetStateCommand } from "./stdin-writer.ts";
19
-
20
- /** FR-4: get_state RPC 握手最大重试次数。 */
21
- const GET_STATE_MAX_RETRIES = 3;
22
- /** FR-4: get_state RPC 握手重试间隔(ms)——单次超时后等待此间隔再重试。 */
23
- const GET_STATE_RETRY_INTERVAL_MS = 500;
24
- /** FR-4: get_state RPC 握手单次超时(ms)。 */
25
- const GET_STATE_TIMEOUT_MS = 2000;
26
-
27
- /** get_state 握手结果。 */
28
- export interface GetStateResult {
29
- sessionFile?: string;
30
- sessionId?: string;
31
- }
32
-
33
- /**
34
- * FR-4: 通过 get_state RPC 查询子进程获取 sessionFile/sessionId。
35
- *
36
- * 当 stdout header 未获取到 sessionFile 时,尝试通过 get_state RPC 查询。
37
- * 最多重试 GET_STATE_MAX_RETRIES 次,单次超时 GET_STATE_TIMEOUT_MS 后等待
38
- * GET_STATE_RETRY_INTERVAL_MS 再发起下一次重试。
39
- *
40
- * @param child 子进程(stdin 写入 get_state 命令)
41
- * @param addResponseListener 注册 response 监听器的函数(stdout pump 中调用)
42
- * @returns 握手结果(可能为空——所有重试均超时/失败)
43
- */
44
- export function performGetStateHandshake(
45
- child: ChildProcess,
46
- addResponseListener: (id: string, resolver: (data: unknown) => void) => void,
47
- ): Promise<GetStateResult> {
48
- return new Promise<GetStateResult>((resolve) => {
49
- const collected: GetStateResult = {};
50
- let attempts = 0;
51
- let resolved = false;
52
-
53
- function tryOnce(): void {
54
- if (resolved) return;
55
- attempts++;
56
- const reqId = sendGetStateCommand(child);
57
-
58
- // [#15] 本次 tryOnce 私有的 timer(2s 超时 + 超时后派生的 retry)。
59
- // 关键:response 回调通过闭包引用的是"本次 tryOnce 对应的 timer",而非某个
60
- // 外层共享变量——即便后续 tryOnce(#2) 重新发起请求,旧 reqId 的迟到 response 回调
61
- // 闭包仍指向它自己那次 tryOnce 的 timer,不会误清新 reqId 的 timer。retry 句柄也
62
- // 一并捕获,response 到达时同步取消"已在排队但尚未触发的下一次重试"。
63
- let pendingRetry: ReturnType<typeof setTimeout> | undefined;
64
- const timer: ReturnType<typeof setTimeout> = setTimeout(() => {
65
- pendingRetry = undefined;
66
- // 单次超时:等待间隔后重试,或放弃
67
- if (attempts < GET_STATE_MAX_RETRIES && !resolved) {
68
- // [Bug fix] 旧实现直接 tryOnce() 立即重试,GET_STATE_RETRY_INTERVAL_MS 声明却
69
- // 从未使用(eslint error 阻断 commit)。现在重试前等待间隔,让常量名与行为一致。
70
- pendingRetry = setTimeout(() => tryOnce(), GET_STATE_RETRY_INTERVAL_MS);
71
- pendingRetry.unref();
72
- } else if (!resolved) {
73
- resolved = true;
74
- resolve(collected);
75
- }
76
- }, GET_STATE_TIMEOUT_MS);
77
- timer.unref();
78
-
79
- addResponseListener(reqId, (data: unknown) => {
80
- if (resolved) return;
81
- // [#15] 闭包清理本次 tryOnce 的 timer(2s 超时 + 排队中的 retry),不碰其他 reqId 的 timer。
82
- clearTimeout(timer);
83
- if (pendingRetry) clearTimeout(pendingRetry);
84
- if (data && typeof data === "object") {
85
- const d = data as Record<string, unknown>;
86
- if (typeof d.sessionFile === "string" && d.sessionFile.length > 0) {
87
- collected.sessionFile = d.sessionFile;
88
- }
89
- if (typeof d.sessionId === "string" && d.sessionId.length > 0) {
90
- collected.sessionId = d.sessionId;
91
- }
92
- }
93
- // sessionFile 已获取——立即 resolve(无需更多重试)
94
- if (collected.sessionFile) {
95
- resolved = true;
96
- resolve(collected);
97
- }
98
- // 否则等待超时重试
99
- });
100
- }
101
-
102
- tryOnce();
103
- });
104
- }
@@ -1,56 +0,0 @@
1
- // src/execution/host-mode.ts
2
- //
3
- // 主进程运行模式分类工具。
4
- //
5
- // 将 Pi 的 ExtensionMode("tui"|"rpc"|"json"|"print")聚合为业务语义的
6
- // HostMode("tui"|"gui"|"headless"),供 session-runner 的 W4 提示词守卫、
7
- // handler 工厂分流、stdio 选择等消费点统一调用。
8
- //
9
- // 判定依据见 AGENTS.md「运行时环境区分」章节 +
10
- // docs/extensions/pi-tui-development-guide.md 第四部分第 8 节。
11
- // ExtensionMode 来自 Pi 源码 packages/coding-agent/src/core/extensions/types.ts:299
12
- // (dist 中 core/extensions/types.d.ts:207)。
13
- //
14
- // 设计动机(.fix-plans/00-master-summary.md §一冲突 4):
15
- // - 把散落多处的 `ctx.mode === "tui" || ctx.mode === "rpc"` 字面量比较
16
- // 集中到单一修改点,未来 Pi 新增 mode 值时只改本文件。
17
- // - 业务语义命名("gui"/"headless")比原始枚举值更清晰表达意图。
18
-
19
- // ExtensionMode 在 Pi SDK 的 core/extensions/types.d.ts 中定义为
20
- // `"tui" | "rpc" | "json" | "print"`(ExtensionContext.mode 的类型),但未从包根
21
- // 导出。这里定义与 SDK 同构的本地别名(ctx.mode 的字面量联合),由同包其他模块复用,
22
- // 避免依赖未导出的内部类型。
23
- export type ExtensionMode = "tui" | "rpc" | "json" | "print";
24
-
25
- /** 主进程运行模式分类。基于 ExtensionMode 聚合为业务语义。
26
- * - "tui":纯 Pi TUI,ctx.ui.custom 可用,用户在终端交互
27
- * - "gui":xyz-agent GUI,通过 rpc sidecar 通道与前端 Vue 组件交互
28
- * - "headless":无交互 UI 通道(json/print 输出模式,或 mode 未穿透) */
29
- export type HostMode = "tui" | "gui" | "headless";
30
-
31
- /** 从 ExtensionContext.mode 解析主进程模式分类。
32
- * - "tui" → tui(纯 Pi TUI,ctx.ui.custom 可用)
33
- * - "rpc" → gui(xyz-agent GUI,sidecar 通道可用)
34
- * - "json"/"print"/undefined → headless(无交互通道)
35
- *
36
- * undefined 归入 headless 是向后兼容:mode 未穿透 SessionRunnerContext 时
37
- * 按「无 UI」保守处理,避免误注入依赖 UI 的逻辑。 */
38
- export function resolveHostMode(mode: ExtensionMode | undefined): HostMode {
39
- if (mode === "tui") return "tui";
40
- if (mode === "rpc") return "gui";
41
- return "headless"; // json/print/undefined
42
- }
43
-
44
- /** 主进程是否会响应子进程的 ask_user(UI 透传)。
45
- * tui + gui 都会(冲突 3 裁决:TUI 必须注入 handler;GUI 透传所有 UI),
46
- * headless 不会(无 UI 通道,注入 W4 提示词会误导 LLM)。 */
47
- export function willRespondToAskUser(mode: ExtensionMode | undefined): boolean {
48
- const host = resolveHostMode(mode);
49
- return host === "tui" || host === "gui";
50
- }
51
-
52
- /** 主进程是否有交互 UI 通道(TUI 组件 / GUI sidecar)。
53
- * 非 headless 即有。用于 stdio 选择等不区分 tui/gui 的决策点。 */
54
- export function hasInteractiveUI(mode: ExtensionMode | undefined): boolean {
55
- return resolveHostMode(mode) !== "headless";
56
- }
@@ -1,47 +0,0 @@
1
- /**
2
- * SP-4 idle record GC:30 天 TTL 定时归档,防 idle record 永久驻留内存。
3
- * 从 subagent-service.ts 抽出(文件超 max-lines;逻辑自包含:interval + TTL 扫描)。
4
- * 启动幂等由调用方(service.startGcTimer)守卫;返回 stop 函数供 dispose 清理。
5
- */
6
- import { getLogger } from "@zhushanwen/pi-extension-logger";
7
- import { bestEffort } from "./best-effort.ts";
8
- import { isResumable } from "./lifecycle-predicates.ts";
9
- import type { RecordStore } from "./record-store.ts";
10
-
11
- const logger = getLogger("subagents");
12
-
13
- /** GC 扫描间隔:1 小时。 */
14
- // eslint-disable-next-line no-magic-numbers -- 60*60*1000 = 1h 的毫秒换算常数
15
- const GC_INTERVAL_MS = 60 * 60 * 1000;
16
- /** idle record TTL:30 天(超龄归档)。 */
17
- // eslint-disable-next-line no-magic-numbers -- 30*24*60*60*1000 = 30d 的毫秒换算常数
18
- const IDLE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
19
- /** 毫秒/天(GC 日志的 d 换算)。 */
20
- // eslint-disable-next-line no-magic-numbers -- 24*60*60*1000 = 1d 的毫秒换算常数
21
- const MS_PER_DAY = 24 * 60 * 60 * 1000;
22
-
23
- /**
24
- * 启动 idle record GC 定时器,返回 stop 函数(清理 interval;幂等)。
25
- * 每个扫描周期:对 store 内全部 active record 中 resumable 且带 idleSince 的,
26
- * 超过 IDLE_TTL_MS 的归档(archive 单条失败不阻断其余,bestEffort 留痕)。
27
- */
28
- export function startIdleGc(store: RecordStore): () => void {
29
- const timer = setInterval(() => {
30
- const now = Date.now();
31
- for (const record of store.listAllActive()) {
32
- if (isResumable(record) && record.idleSince) {
33
- const age = now - record.idleSince;
34
- if (age > IDLE_TTL_MS) {
35
- logger.warn(`[subagents] GC: archiving idle record ${record.id} (idle for ${Math.round(age / MS_PER_DAY)}d)`);
36
- try {
37
- store.archive(record);
38
- } catch (err) {
39
- bestEffort(err, `GC archive record ${record.id}`);
40
- }
41
- }
42
- }
43
- }
44
- }, GC_INTERVAL_MS);
45
- timer.unref?.();
46
- return () => clearInterval(timer);
47
- }