@selesai/code 0.9.11 → 0.9.12

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 (580) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/config.d.ts +4 -6
  3. package/dist/config.js +10 -14
  4. package/dist/core/agent-session.d.ts +0 -1
  5. package/dist/core/agent-session.js +3 -49
  6. package/dist/core/extensions/types.d.ts +0 -2
  7. package/dist/core/settings-manager.d.ts +0 -2
  8. package/dist/core/settings-manager.js +0 -3
  9. package/dist/core/tools/index.d.ts +0 -1
  10. package/dist/core/tools/index.js +0 -1
  11. package/dist/defaults/settings.json +0 -1
  12. package/dist/extensions/model-prompt-injector/index.test.ts +0 -10
  13. package/dist/extensions/model-prompt-injector/index.ts +0 -3
  14. package/dist/extensions/pi-intercom/CHANGELOG.md +53 -16
  15. package/dist/extensions/pi-intercom/README.md +41 -8
  16. package/dist/extensions/pi-intercom/banner.png +0 -0
  17. package/dist/extensions/pi-intercom/broker/broker.ts +498 -215
  18. package/dist/extensions/pi-intercom/broker/client.ts +39 -12
  19. package/dist/extensions/pi-intercom/broker/extension.test.ts +102 -3
  20. package/dist/extensions/pi-intercom/broker/paths.test.ts +2 -2
  21. package/dist/extensions/pi-intercom/broker/protocol.ts +26 -0
  22. package/dist/extensions/pi-intercom/broker/spawn.test.ts +5 -20
  23. package/dist/extensions/pi-intercom/config.test.ts +41 -0
  24. package/dist/extensions/pi-intercom/config.ts +21 -0
  25. package/dist/extensions/pi-intercom/extension-api.ts +40 -0
  26. package/dist/extensions/pi-intercom/index.ts +362 -26
  27. package/dist/extensions/pi-intercom/intercom.integration.test.ts +819 -13
  28. package/dist/extensions/pi-intercom/package.json +1 -1
  29. package/dist/extensions/pi-intercom/project-agent.ts +2 -2
  30. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +8 -110
  31. package/dist/extensions/pi-intercom/types.ts +32 -5
  32. package/dist/extensions/pi-intercom/ui/inline-message.ts +6 -0
  33. package/dist/extensions/pi-subagents/.github/assets/subagent-fleet-inspector.png +0 -0
  34. package/dist/extensions/pi-subagents/.github/workflows/release.yml +28 -0
  35. package/dist/extensions/pi-subagents/.github/workflows/test.yml +51 -0
  36. package/dist/extensions/pi-subagents/.greptile/config.json +33 -0
  37. package/dist/extensions/pi-subagents/.greptile/files.json +8 -0
  38. package/dist/extensions/pi-subagents/.greptile/rules.md +16 -0
  39. package/dist/extensions/pi-subagents/CHANGELOG.md +309 -87
  40. package/dist/extensions/pi-subagents/README.md +15 -17
  41. package/dist/extensions/pi-subagents/agents/oracle.md +3 -1
  42. package/dist/extensions/pi-subagents/agents/researcher.md +32 -13
  43. package/dist/extensions/pi-subagents/agents/reviewer.md +13 -2
  44. package/dist/extensions/pi-subagents/agents/scout.md +2 -2
  45. package/dist/extensions/pi-subagents/agents/worker.md +2 -1
  46. package/dist/extensions/pi-subagents/async-retention-discovery-worker.mjs +180 -0
  47. package/dist/extensions/pi-subagents/docs/configuration.md +106 -27
  48. package/dist/extensions/pi-subagents/docs/extension-api.md +85 -21
  49. package/dist/extensions/pi-subagents/docs/missions.md +41 -4
  50. package/dist/extensions/pi-subagents/docs/models.md +52 -9
  51. package/dist/extensions/pi-subagents/docs/observability.md +103 -16
  52. package/dist/extensions/pi-subagents/docs/tool-reference.md +60 -45
  53. package/dist/extensions/pi-subagents/docs/watchdog.md +60 -3
  54. package/dist/extensions/pi-subagents/docs/workflows.md +181 -7
  55. package/dist/extensions/pi-subagents/index.ts +10 -1
  56. package/dist/extensions/pi-subagents/install.mjs +4 -4
  57. package/dist/extensions/pi-subagents/package-lock.json +1483 -1470
  58. package/dist/extensions/pi-subagents/package.json +6 -3
  59. package/dist/extensions/pi-subagents/prompts/council.md +60 -0
  60. package/dist/extensions/pi-subagents/prompts/parallel-review.md +5 -1
  61. package/dist/extensions/pi-subagents/prompts/review-loop.md +9 -5
  62. package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +254 -0
  63. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +18 -17
  64. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +31 -9
  65. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +107 -140
  66. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +9 -12
  67. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +39 -0
  68. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +44 -92
  69. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +261 -368
  70. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +6 -2
  71. package/dist/extensions/pi-subagents/src/agents/agents.ts +388 -85
  72. package/dist/extensions/pi-subagents/src/agents/builtin-names.ts +14 -0
  73. package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +418 -0
  74. package/dist/extensions/pi-subagents/src/agents/skills.ts +1 -1
  75. package/dist/extensions/pi-subagents/src/api/agents.ts +7 -0
  76. package/dist/extensions/pi-subagents/src/api/external-job-provider.ts +195 -0
  77. package/dist/extensions/pi-subagents/src/api/preflight.ts +88 -27
  78. package/dist/extensions/pi-subagents/src/api/project-panes.ts +2 -0
  79. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -0
  80. package/dist/extensions/pi-subagents/src/extension/config.ts +20 -11
  81. package/dist/extensions/pi-subagents/src/extension/doctor.ts +14 -6
  82. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +5 -4
  83. package/dist/extensions/pi-subagents/src/extension/index.ts +270 -187
  84. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +65 -28
  85. package/dist/extensions/pi-subagents/src/extension/rpc.ts +120 -11
  86. package/dist/extensions/pi-subagents/src/extension/schemas.ts +46 -64
  87. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +51 -37
  88. package/dist/extensions/pi-subagents/src/extension/tool-result.ts +19 -0
  89. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +2 -2
  90. package/dist/extensions/pi-subagents/src/inspectors/herdr/client.ts +3 -3
  91. package/dist/extensions/pi-subagents/src/inspectors/herdr/focus.ts +55 -0
  92. package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +2 -1
  93. package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +230 -46
  94. package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +26 -4
  95. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +32 -10
  96. package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +6 -1
  97. package/dist/extensions/pi-subagents/src/missions/store.ts +4 -9
  98. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +2 -2
  99. package/dist/extensions/pi-subagents/src/policy/authority.ts +2 -0
  100. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +3 -1
  101. package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +31 -8
  102. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +210 -52
  103. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +63 -33
  104. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +71 -17
  105. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +886 -0
  106. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +14 -5
  107. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +49 -56
  108. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +1 -0
  109. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +3 -33
  110. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +5 -0
  111. package/dist/extensions/pi-subagents/src/runs/background/completion-dedupe.ts +5 -1
  112. package/dist/extensions/pi-subagents/src/runs/background/completion-replay.ts +22 -12
  113. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +105 -71
  114. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +68 -19
  115. package/dist/extensions/pi-subagents/src/runs/background/index-segment.ts +59 -0
  116. package/dist/extensions/pi-subagents/src/runs/background/inspect-rpc.ts +443 -0
  117. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +94 -10
  118. package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +158 -90
  119. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +141 -53
  120. package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +8 -5
  121. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +14 -4
  122. package/dist/extensions/pi-subagents/src/runs/background/run-id-query.ts +7 -0
  123. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +13 -14
  124. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +46 -25
  125. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +823 -0
  126. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +9 -3
  127. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +11 -1
  128. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +594 -216
  129. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +17 -13
  130. package/dist/extensions/pi-subagents/src/runs/background/terminal-run-index.ts +138 -0
  131. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +23 -4
  132. package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +82 -4
  133. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +5 -3
  134. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +21 -14
  135. package/dist/extensions/pi-subagents/src/runs/foreground/async-stop-action.ts +23 -2
  136. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +153 -58
  137. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +7 -9
  138. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1283 -1657
  139. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +274 -0
  140. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +6 -5
  141. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +59 -10
  142. package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
  143. package/dist/extensions/pi-subagents/src/runs/shared/chain-outputs.ts +1 -3
  144. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +36 -0
  145. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +52 -2
  146. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  147. package/dist/extensions/pi-subagents/src/runs/shared/extension-bindings.ts +78 -0
  148. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +2 -0
  149. package/dist/extensions/pi-subagents/src/runs/shared/external-job-bridge.ts +460 -0
  150. package/dist/extensions/pi-subagents/src/runs/shared/external-job-runner.ts +389 -0
  151. package/dist/extensions/pi-subagents/src/runs/shared/fast-mode-extension.ts +10 -0
  152. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +14 -0
  153. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +243 -0
  154. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +201 -85
  155. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +106 -39
  156. package/dist/extensions/pi-subagents/src/runs/shared/mutation-evidence.ts +145 -0
  157. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +150 -27
  158. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +46 -4
  159. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +19 -15
  160. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +5 -1
  161. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +86 -2
  162. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +9 -9
  163. package/dist/extensions/pi-subagents/src/runs/shared/session-lease.ts +0 -6
  164. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +18 -4
  165. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +51 -7
  166. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +62 -21
  167. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +1 -3
  168. package/dist/extensions/pi-subagents/src/runs/shared/tool-timeout.ts +1 -3
  169. package/dist/extensions/pi-subagents/src/runs/shared/workflow-graph.ts +1 -23
  170. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +14 -2
  171. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +2 -2
  172. package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +22 -2
  173. package/dist/extensions/pi-subagents/src/shared/capacity-resilient-json.ts +102 -0
  174. package/dist/extensions/pi-subagents/src/shared/completion-owner.ts +14 -0
  175. package/dist/extensions/pi-subagents/src/shared/file-system-retry.ts +49 -1
  176. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +59 -1
  177. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +12 -5
  178. package/dist/extensions/pi-subagents/src/shared/model-info.ts +20 -0
  179. package/dist/extensions/pi-subagents/src/shared/prompt-resources.ts +0 -40
  180. package/dist/extensions/pi-subagents/src/shared/settings.ts +11 -30
  181. package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +52 -0
  182. package/dist/extensions/pi-subagents/src/shared/types.ts +228 -49
  183. package/dist/extensions/pi-subagents/src/shared/utils.ts +11 -3
  184. package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +10 -0
  185. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +0 -162
  186. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +2 -5
  187. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +105 -13
  188. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +6 -36
  189. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +829 -0
  190. package/dist/extensions/pi-subagents/src/tui/fleet.ts +1415 -0
  191. package/dist/extensions/pi-subagents/src/tui/render.ts +78 -7
  192. package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +1 -1
  193. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +1 -0
  194. package/dist/extensions/pi-subagents/src/watchdog/permission-arbiter.ts +59 -51
  195. package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +8 -2
  196. package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +2 -1
  197. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +4 -4
  198. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +471 -86
  199. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +140 -0
  200. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +2 -2
  201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
  202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
  203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
  204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
  205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
  206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
  207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
  208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
  209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
  210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
  211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
  212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
  213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
  214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
  215. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
  216. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
  217. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
  218. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
  219. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
  220. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
  221. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
  222. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
  223. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
  224. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
  225. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
  226. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
  227. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
  228. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
  229. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
  230. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
  231. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
  232. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
  233. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
  234. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
  235. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
  236. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
  237. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
  238. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
  239. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
  240. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
  241. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
  242. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
  243. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
  244. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
  245. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
  246. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
  247. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
  248. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
  249. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
  250. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
  251. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
  252. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
  253. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
  254. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
  255. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
  256. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
  257. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
  258. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
  259. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
  260. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
  261. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
  262. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
  263. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
  264. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
  265. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
  266. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
  267. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
  268. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
  269. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
  270. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
  271. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
  272. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
  273. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
  274. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
  275. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
  276. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
  277. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
  278. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
  279. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
  280. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
  281. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  282. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
  283. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
  284. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
  285. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
  286. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
  287. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
  288. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
  289. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
  290. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
  291. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
  292. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
  293. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
  294. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
  295. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
  296. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
  297. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
  298. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  299. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  300. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  301. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  302. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
  303. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  304. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  305. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  306. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
  307. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  308. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
  309. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  310. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  311. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
  312. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
  313. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  314. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  315. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
  316. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
  317. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  318. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  319. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
  320. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  321. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  322. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  323. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
  324. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
  325. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  326. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  327. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
  328. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  329. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  330. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  331. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
  332. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  333. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  334. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
  335. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  336. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
  337. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
  338. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
  339. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
  340. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
  341. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
  342. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
  343. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
  344. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
  345. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
  346. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
  347. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
  348. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
  349. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
  350. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
  351. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
  352. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
  353. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
  354. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
  355. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
  356. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
  357. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
  358. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
  359. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
  360. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
  361. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
  362. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
  363. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
  364. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
  365. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
  366. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
  367. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
  368. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
  369. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
  370. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
  371. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
  372. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
  373. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
  374. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
  375. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
  376. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/index.mjs +1 -1
  377. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +0 -54
  378. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1053 -414
  379. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +194 -4
  380. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +59 -4
  381. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +0 -77
  382. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +107 -6
  383. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +211 -897
  384. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +265 -375
  385. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +77 -7
  386. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +1 -1
  387. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +10 -10
  388. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +547 -30
  389. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +2112 -310
  390. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +274 -34
  391. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +1 -1
  392. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +20 -3
  393. package/dist/extensions/pi-subagents/test/support/isolated-temp-root.mjs +9 -0
  394. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +30 -5
  395. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +2 -0
  396. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +4 -2
  397. package/dist/extensions/pi-subagents/test/support/register-loader.mjs +1 -0
  398. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +197 -0
  399. package/dist/extensions/pi-subagents/test/unit/agent-contract.test.ts +14 -0
  400. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -1
  401. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +204 -27
  402. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +444 -145
  403. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +256 -4
  404. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +9 -7
  405. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +152 -22
  406. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +29 -0
  407. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +205 -23
  408. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +579 -0
  409. package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +24 -0
  410. package/dist/extensions/pi-subagents/test/unit/authority-policy.test.ts +1 -0
  411. package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +3 -3
  412. package/dist/extensions/pi-subagents/test/unit/capacity-resilient-json.test.ts +155 -0
  413. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +2 -2
  414. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +7 -0
  415. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +123 -0
  416. package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +81 -3
  417. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +109 -7
  418. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +2 -2
  419. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +5 -2
  420. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +3 -2
  421. package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +79 -0
  422. package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +22 -0
  423. package/dist/extensions/pi-subagents/test/unit/external-job-runner.test.ts +961 -0
  424. package/dist/extensions/pi-subagents/test/unit/file-system-retry.test.ts +64 -0
  425. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +1110 -0
  426. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +1664 -0
  427. package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +81 -1
  428. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +138 -11
  429. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +41 -2
  430. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +210 -79
  431. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +95 -0
  432. package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +596 -0
  433. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
  434. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +3 -5
  435. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +167 -0
  436. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +319 -18
  437. package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +78 -0
  438. package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +19 -5
  439. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +44 -0
  440. package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +129 -0
  441. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +231 -2
  442. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +28 -1
  443. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +106 -2
  444. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +204 -7
  445. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +59 -4
  446. package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +2 -6
  447. package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +34 -2
  448. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +116 -6
  449. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +12 -3
  450. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +56 -61
  451. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +416 -1
  452. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +9 -2
  453. package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +42 -0
  454. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +21 -30
  455. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +86 -11
  456. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +49 -1
  457. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +233 -5
  458. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +28 -5
  459. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +323 -20
  460. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +66 -10
  461. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +68 -5
  462. package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +174 -0
  463. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +679 -0
  464. package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +67 -0
  465. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +55 -44
  466. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +399 -84
  467. package/dist/extensions/pi-subagents/test/unit/session-lease.test.ts +13 -0
  468. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
  469. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +15 -10
  470. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +11 -7
  471. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -0
  472. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +40 -1
  473. package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +10 -2
  474. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +38 -3
  475. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +110 -12
  476. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +204 -19
  477. package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +25 -0
  478. package/dist/extensions/pi-subagents/test/unit/thinking-ceiling.test.ts +73 -0
  479. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +90 -50
  480. package/dist/extensions/pi-subagents/test/unit/tool-timeout.test.ts +1 -2
  481. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +234 -7
  482. package/dist/extensions/pi-subagents/test/unit/watch-strategy.test.ts +24 -0
  483. package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +36 -0
  484. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +37 -9
  485. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +302 -0
  486. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +167 -7
  487. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +113 -0
  488. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +6 -6
  489. package/dist/extensions/ponytail/index.js +31 -25
  490. package/dist/extensions/ponytail/ponytail-config.cjs +34 -7
  491. package/dist/extensions/ponytail/ponytail-instructions.cjs +7 -9
  492. package/dist/extensions/ponytail/test/extension.test.js +7 -8
  493. package/dist/extensions/ponytail/test/helpers.test.js +1 -1
  494. package/dist/skills/brandkit/SKILL.md +799 -0
  495. package/dist/skills/design-taste-frontend/SKILL.md +1207 -0
  496. package/dist/skills/design-taste-frontend-v1/SKILL.md +227 -0
  497. package/dist/skills/full-output-enforcement/SKILL.md +50 -0
  498. package/dist/skills/gpt-taste/SKILL.md +75 -0
  499. package/dist/skills/high-end-visual-design/SKILL.md +99 -0
  500. package/dist/skills/image-to-code/SKILL.md +1229 -0
  501. package/dist/skills/imagegen-frontend-mobile/SKILL.md +1466 -0
  502. package/dist/skills/imagegen-frontend-web/SKILL.md +988 -0
  503. package/dist/skills/industrial-brutalist-ui/SKILL.md +93 -0
  504. package/dist/skills/minimalist-ui/SKILL.md +86 -0
  505. package/dist/skills/pi-subagents/SKILL.md +18 -17
  506. package/dist/skills/pi-subagents/references/constraints-and-recipes.md +31 -9
  507. package/dist/skills/pi-subagents/references/execution-controls.md +95 -143
  508. package/dist/skills/pi-subagents/references/management-authoring-rpc.md +9 -12
  509. package/dist/skills/pi-subagents/references/multi-lane-orchestration.md +39 -0
  510. package/dist/skills/pi-subagents/references/prompting-and-roles.md +45 -94
  511. package/dist/skills/ponytail/SKILL.md +12 -8
  512. package/dist/skills/ponytail-audit/SKILL.md +0 -1
  513. package/dist/skills/ponytail-debt/SKILL.md +0 -1
  514. package/dist/skills/ponytail-gain/SKILL.md +0 -1
  515. package/dist/skills/ponytail-help/SKILL.md +4 -3
  516. package/dist/skills/ponytail-review/SKILL.md +0 -1
  517. package/dist/skills/redesign-existing-projects/SKILL.md +179 -0
  518. package/dist/skills/stitch-design-taste/SKILL.md +185 -0
  519. package/dist/skills/unlazy/CHANGELOG.md +100 -0
  520. package/dist/skills/unlazy/CONTRIBUTING.md +66 -0
  521. package/dist/skills/unlazy/LICENSE +21 -0
  522. package/dist/skills/unlazy/README.md +242 -0
  523. package/dist/skills/unlazy/SECURITY.md +70 -0
  524. package/dist/skills/unlazy/SKILL.md +100 -0
  525. package/dist/skills/unlazy/package.json +13 -0
  526. package/dist/skills/unlazy/references/dispatch.md +82 -0
  527. package/dist/skills/unlazy/references/gates.md +132 -0
  528. package/dist/skills/unlazy/references/method.md +49 -0
  529. package/dist/skills/unlazy/references/orchestration.md +99 -0
  530. package/dist/skills/unlazy/references/parallel.md +123 -0
  531. package/dist/skills/unlazy/references/token-economy.md +39 -0
  532. package/dist/skills/unlazy/research/validation-protocol.md +81 -0
  533. package/dist/skills/unlazy/scripts/dispatch-check.mjs +108 -0
  534. package/dist/skills/unlazy/scripts/gate-check.mjs +894 -0
  535. package/dist/skills/unlazy/scripts/gate-lint.mjs +178 -0
  536. package/dist/skills/unlazy/scripts/install-hooks.mjs +206 -0
  537. package/dist/skills/unlazy/scripts/lib/check-supervisor.mjs +46 -0
  538. package/dist/skills/unlazy/scripts/lib/dispatch.mjs +283 -0
  539. package/dist/skills/unlazy/scripts/lib/gates.mjs +629 -0
  540. package/dist/skills/unlazy/scripts/lib/process-tree.mjs +161 -0
  541. package/dist/skills/unlazy/scripts/lib/regex-worker.mjs +9 -0
  542. package/dist/skills/unlazy/scripts/stop-hook.mjs +174 -0
  543. package/dist/skills/unlazy/templates/PLAN.md +65 -0
  544. package/dist/skills/unlazy/templates/gates-leaf.md +51 -0
  545. package/dist/skills/unlazy/templates/gates-node.md +50 -0
  546. package/dist/skills/unlazy/tests/contract-tests.mjs +127 -0
  547. package/dist/skills/unlazy/tests/dispatch-tests.mjs +481 -0
  548. package/dist/skills/unlazy/tests/hardening-tests.mjs +903 -0
  549. package/dist/skills/unlazy/tests/lint-tests.mjs +242 -0
  550. package/dist/skills/unlazy/tests/run-tests.mjs +554 -0
  551. package/dist/skills/unlazy/tests/self-check.mjs +165 -0
  552. package/dist/skills/unlazy/tests/stress-tests.mjs +356 -0
  553. package/dist/skills/web-design-guidelines/SKILL.md +40 -0
  554. package/docs/settings.md +0 -5
  555. package/package.json +1 -1
  556. package/dist/core/tools/schema-prune.d.ts +0 -16
  557. package/dist/core/tools/schema-prune.js +0 -39
  558. package/dist/core/tools/schema-prune.test.d.ts +0 -1
  559. package/dist/core/tools/schema-prune.test.js +0 -111
  560. package/dist/extensions/pi-subagents/UPSTREAM-V0.50-MAPPING.md +0 -172
  561. package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +0 -55
  562. package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +0 -61
  563. package/dist/extensions/pi-subagents/src/agents/task-aware-routing.ts +0 -132
  564. package/dist/extensions/pi-subagents/src/extension/chain-validation.ts +0 -181
  565. package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +0 -1354
  566. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +0 -1581
  567. package/dist/extensions/pi-subagents/src/shared/env.ts +0 -16
  568. package/dist/extensions/pi-subagents/src/shared/session-lineage.ts +0 -71
  569. package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +0 -136
  570. package/dist/extensions/pi-subagents/src/workflows/workflow-auto-relaunch.ts +0 -41
  571. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +0 -466
  572. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +0 -1859
  573. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +0 -733
  574. package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +0 -63
  575. package/dist/extensions/pi-subagents/test/unit/chain-validation.test.ts +0 -326
  576. package/dist/extensions/pi-subagents/test/unit/handoff-adoption.test.ts +0 -103
  577. package/dist/extensions/pi-subagents/test/unit/inline-subagents.test.ts +0 -127
  578. package/dist/extensions/pi-subagents/test/unit/session-lineage.test.ts +0 -73
  579. package/dist/extensions/pi-subagents/test/unit/task-aware-routing.test.ts +0 -213
  580. package/dist/extensions/pi-subagents/test/unit/workflow-auto-relaunch.test.ts +0 -65
@@ -178,6 +178,42 @@ describe("builtin agent overrides", () => {
178
178
  assert.equal(worker.model, "deepseek-v4-pro");
179
179
  });
180
180
 
181
+ it("applies default providers with per-agent overrides", () => {
182
+ fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
183
+ writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
184
+ subagents: {
185
+ defaultModel: "llama-3",
186
+ defaultProvider: "gpu-a",
187
+ agentOverrides: {
188
+ worker: { defaultProvider: "gpu-b" },
189
+ reviewer: { defaultProvider: false },
190
+ },
191
+ },
192
+ });
193
+ writeJson(path.join(tempProject, ".selesai", "settings.json"), {
194
+ subagents: { defaultProvider: "gpu-project" },
195
+ });
196
+
197
+ const builtins = discoverAgentsAll(tempProject).builtin;
198
+ const scout = builtins.find((agent) => agent.name === "scout");
199
+ assert.equal(scout?.model, "llama-3");
200
+ assert.equal(scout?.modelProvider, "gpu-project");
201
+ assert.equal(scout?.modelSource?.defaultProvider, "gpu-project");
202
+ assert.equal(builtins.find((agent) => agent.name === "worker")?.modelProvider, "gpu-b");
203
+ assert.equal(builtins.find((agent) => agent.name === "reviewer")?.modelProvider, undefined);
204
+ });
205
+
206
+ it("applies default providers to custom agent frontmatter models", () => {
207
+ writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
208
+ subagents: { defaultProvider: "gpu-a" },
209
+ });
210
+ writeProjectAgent(tempProject, "worker", `---\nname: worker\ndescription: Project worker\nmodel: llama-3\n---\n\nWork.\n`);
211
+
212
+ const worker = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "worker");
213
+ assert.equal(worker?.model, "llama-3");
214
+ assert.equal(worker?.modelProvider, "gpu-a");
215
+ });
216
+
181
217
  it("applies subagents.defaultThinking only when thinking is unset", () => {
182
218
  writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
183
219
  subagents: {
@@ -239,6 +275,27 @@ describe("builtin agent overrides", () => {
239
275
  }
240
276
  });
241
277
 
278
+ it("surfaces malformed default provider settings", () => {
279
+ const settingsPath = path.join(tempHome, ".selesai", "agent", "settings.json");
280
+ for (const defaultProvider of ["", 42]) {
281
+ writeJson(settingsPath, { subagents: { defaultProvider } });
282
+ assert.throws(
283
+ () => discoverAgents(tempProject, "both"),
284
+ (error: unknown) => error instanceof Error
285
+ && error.message.includes(settingsPath)
286
+ && error.message.includes("defaultProvider"),
287
+ );
288
+ }
289
+ writeJson(settingsPath, { subagents: { agentOverrides: { worker: { defaultProvider: "" } } } });
290
+ assert.throws(
291
+ () => discoverAgents(tempProject, "both"),
292
+ (error: unknown) => error instanceof Error
293
+ && error.message.includes(settingsPath)
294
+ && error.message.includes("worker")
295
+ && error.message.includes("defaultProvider"),
296
+ );
297
+ });
298
+
242
299
  it("applies subagents.defaultModel to custom agents without a frontmatter model", () => {
243
300
  writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
244
301
  subagents: {
@@ -277,9 +334,10 @@ describe("builtin agent overrides", () => {
277
334
  it("applies user settings overrides to builtin agents", () => {
278
335
  writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
279
336
  subagents: {
280
- agentOverrides: {
337
+ agentOverrides: {
281
338
  reviewer: {
282
339
  model: "openai/gpt-5.4",
340
+ fast: true,
283
341
  thinking: "xhigh",
284
342
  systemPromptMode: "replace",
285
343
  inheritProjectContext: true,
@@ -296,6 +354,7 @@ describe("builtin agent overrides", () => {
296
354
  assert.ok(reviewer);
297
355
  assert.equal(reviewer.source, "builtin");
298
356
  assert.equal(reviewer.model, "openai/gpt-5.4");
357
+ assert.equal(reviewer.fast, true);
299
358
  assert.equal(reviewer.thinking, "xhigh");
300
359
  assert.equal(reviewer.systemPromptMode, "replace");
301
360
  assert.equal(reviewer.inheritProjectContext, true);
@@ -420,6 +479,86 @@ describe("builtin agent overrides", () => {
420
479
  assert.equal(reviewer.override?.path, path.join(tempProject, ".selesai", "settings.json"));
421
480
  });
422
481
 
482
+ it("layers a project override on top of a user override for a custom agent instead of discarding it", () => {
483
+ // Regression test: a custom agent (e.g. a reviewer persona shipped as a .md
484
+ // file with no model/thinking/fallbackModels in frontmatter) that gets its
485
+ // model pin exclusively from a *user*-scope agentOverrides entry must keep
486
+ // that pin when a *project*-scope override adds an unrelated field (here:
487
+ // subagentOnlyExtensions). Previously the project override for this agent
488
+ // name replaced the user override wholesale, silently dropping model /
489
+ // thinking / fallbackModels with no error.
490
+ writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
491
+ subagents: {
492
+ agentOverrides: {
493
+ "persona-reviewer": {
494
+ model: "anthropic/claude-opus-4-8",
495
+ thinking: "high",
496
+ fallbackModels: ["anthropic/claude-sonnet-4-6"],
497
+ },
498
+ },
499
+ },
500
+ });
501
+ fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
502
+ writeJson(path.join(tempProject, ".selesai", "settings.json"), {
503
+ subagents: {
504
+ agentOverrides: {
505
+ "persona-reviewer": {
506
+ subagentOnlyExtensions: ["./tools/child-only.ts"],
507
+ },
508
+ },
509
+ },
510
+ });
511
+ writeUserAgent(tempHome, "persona-reviewer", `---\nname: persona-reviewer\ndescription: Shared review persona\n---\n\nReview the diff.\n`);
512
+
513
+ const reviewer = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "persona-reviewer");
514
+ assert.ok(reviewer);
515
+ assert.equal(reviewer.model, "anthropic/claude-opus-4-8");
516
+ assert.equal(reviewer.thinking, "high");
517
+ assert.deepEqual(reviewer.fallbackModels, ["anthropic/claude-sonnet-4-6"]);
518
+ assert.deepEqual(reviewer.subagentOnlyExtensions, ["./tools/child-only.ts"]);
519
+ assert.equal(reviewer.override?.scope, "project");
520
+ });
521
+
522
+ it("lets a project override flip `disabled` on a custom agent even after a user override already set it", () => {
523
+ // Regression test for a bug caught in review of the layering fix above:
524
+ // applyCustomAgentOverride's `disabled` handling used a stray
525
+ // `agent.disabled === undefined` guard (a no-op before layering existed,
526
+ // since this function only ever ran once against the pristine base
527
+ // agent). Once user-then-project layering was introduced, that guard
528
+ // silently blocked the project override from ever changing `disabled`
529
+ // once the user override had already set it — breaking this PR's own
530
+ // "project wins" precedence for that one field. Cover both directions.
531
+ writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
532
+ subagents: {
533
+ agentOverrides: {
534
+ "disable-flip-a": { disabled: true },
535
+ "disable-flip-b": { disabled: false },
536
+ },
537
+ },
538
+ });
539
+ fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
540
+ writeJson(path.join(tempProject, ".selesai", "settings.json"), {
541
+ subagents: {
542
+ agentOverrides: {
543
+ "disable-flip-a": { disabled: false },
544
+ "disable-flip-b": { disabled: true },
545
+ },
546
+ },
547
+ });
548
+ writeUserAgent(tempHome, "disable-flip-a", `---\nname: disable-flip-a\ndescription: User disables, project re-enables\n---\n\nBody.\n`);
549
+ writeUserAgent(tempHome, "disable-flip-b", `---\nname: disable-flip-b\ndescription: User enables, project disables\n---\n\nBody.\n`);
550
+
551
+ // discoverAgents filters out agents whose final `.disabled` resolves to
552
+ // true (agents.ts: `.filter((agent) => agent.disabled !== true)`), so
553
+ // presence/absence in the returned list is the observable signal here,
554
+ // not a `.disabled` property on the result.
555
+ const agents = discoverAgents(tempProject, "both").agents;
556
+ const flipA = agents.find((agent) => agent.name === "disable-flip-a");
557
+ const flipB = agents.find((agent) => agent.name === "disable-flip-b");
558
+ assert.ok(flipA, "project override (disabled: false) must win over user override (disabled: true), so the agent stays enabled and listed");
559
+ assert.equal(flipB, undefined, "project override (disabled: true) must win over user override (disabled: false), so the agent ends up disabled and unlisted");
560
+ });
561
+
423
562
  it("applies acceptance role precedence and false clearing to builtin and custom agents", () => {
424
563
  writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
425
564
  subagents: {
@@ -510,8 +649,12 @@ describe("builtin agent overrides", () => {
510
649
  subagents: {
511
650
  agentOverrides: {
512
651
  implementer: {
652
+ output: "artifacts/implementer.md",
653
+ outputMode: "file-only",
654
+ defaultReads: ["CONTEXT.md", "docs/spec.md"],
513
655
  model: "anthropic/claude-sonnet-4-6",
514
656
  fallbackModels: ["openai/gpt-5-mini"],
657
+ fast: true,
515
658
  thinking: "high",
516
659
  systemPromptMode: "append",
517
660
  inheritProjectContext: true,
@@ -531,8 +674,12 @@ describe("builtin agent overrides", () => {
531
674
  const implementer = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "implementer");
532
675
  assert.ok(implementer);
533
676
  assert.equal(implementer.source, "project");
677
+ assert.equal(implementer.output, "artifacts/implementer.md");
678
+ assert.equal(implementer.outputMode, "file-only");
679
+ assert.deepEqual(implementer.defaultReads, ["CONTEXT.md", "docs/spec.md"]);
534
680
  assert.equal(implementer.model, "anthropic/claude-sonnet-4-6");
535
681
  assert.deepEqual(implementer.fallbackModels, ["openai/gpt-5-mini"]);
682
+ assert.equal(implementer.fast, true);
536
683
  assert.equal(implementer.thinking, "high");
537
684
  assert.equal(implementer.systemPromptMode, "append");
538
685
  assert.equal(implementer.inheritProjectContext, true);
@@ -577,16 +724,18 @@ describe("builtin agent overrides", () => {
577
724
  it("prefers project agentOverrides over user agentOverrides on a custom project agent", () => {
578
725
  fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
579
726
  writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
580
- subagents: { agentOverrides: { implementer: { model: "anthropic/claude-sonnet-4-6" } } },
727
+ subagents: { agentOverrides: { implementer: { model: "anthropic/claude-sonnet-4-6", output: "user.md", defaultReads: ["user.md"] } } },
581
728
  });
582
729
  writeJson(path.join(tempProject, ".selesai", "settings.json"), {
583
- subagents: { agentOverrides: { implementer: { model: "openai/gpt-5.4" } } },
730
+ subagents: { agentOverrides: { implementer: { model: "openai/gpt-5.4", output: "project.md", defaultReads: ["project.md"] } } },
584
731
  });
585
732
  writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\n---\n\nDrive the failing test first.\n`);
586
733
 
587
734
  const implementer = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "implementer");
588
735
  assert.ok(implementer);
589
736
  assert.equal(implementer.model, "openai/gpt-5.4");
737
+ assert.equal(implementer.output, "project.md");
738
+ assert.deepEqual(implementer.defaultReads, ["project.md"]);
590
739
  assert.equal(implementer.override?.scope, "project");
591
740
  });
592
741
 
@@ -596,7 +745,11 @@ describe("builtin agent overrides", () => {
596
745
  subagents: {
597
746
  agentOverrides: {
598
747
  implementer: {
748
+ output: "artifacts/override.md",
749
+ outputMode: "file-only",
750
+ defaultReads: ["override.md"],
599
751
  model: "anthropic/claude-sonnet-4-6",
752
+ fast: true,
600
753
  thinking: "high",
601
754
  tools: ["bash"],
602
755
  skills: ["override-skill"],
@@ -608,11 +761,15 @@ describe("builtin agent overrides", () => {
608
761
  },
609
762
  },
610
763
  });
611
- writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\nmodel: google/gemini-3-pro\nthinking: medium\ntools: read, mcp:local_tool\nskills: agent-skill\ninheritProjectContext: false\ndefaultContext: fresh\nacceptanceRole: read-only\ncompletionGuard: false\n---\n\nDrive the failing test first.\n`);
764
+ writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\noutput: artifacts/explicit.md\noutputMode: inline\ndefaultReads: explicit.md\nmodel: google/gemini-3-pro\nfast: false\nthinking: medium\ntools: read, mcp:local_tool\nskills: agent-skill\ninheritProjectContext: false\ndefaultContext: fresh\nacceptanceRole: read-only\ncompletionGuard: false\n---\n\nDrive the failing test first.\n`);
612
765
 
613
766
  const implementer = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "implementer");
614
767
  assert.ok(implementer);
768
+ assert.equal(implementer.output, "artifacts/explicit.md");
769
+ assert.equal(implementer.outputMode, "inline");
770
+ assert.deepEqual(implementer.defaultReads, ["explicit.md"]);
615
771
  assert.equal(implementer.model, "google/gemini-3-pro");
772
+ assert.equal(implementer.fast, false);
616
773
  assert.equal(implementer.thinking, "medium");
617
774
  assert.deepEqual(implementer.tools, ["read"]);
618
775
  assert.deepEqual(implementer.mcpDirectTools, ["local_tool"]);
@@ -624,6 +781,28 @@ describe("builtin agent overrides", () => {
624
781
  assert.equal(implementer.override, undefined);
625
782
  });
626
783
 
784
+ it("keeps explicit output and defaultReads frontmatter when overrides clear them", () => {
785
+ fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
786
+ writeJson(path.join(tempProject, ".selesai", "settings.json"), {
787
+ subagents: { agentOverrides: { implementer: { output: false, defaultReads: false } } },
788
+ });
789
+ writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\noutput: explicit.md\ndefaultReads: explicit.md\n---\n\nDrive the failing test first.\n`);
790
+
791
+ const implementer = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "implementer");
792
+ assert.equal(implementer?.output, "explicit.md");
793
+ assert.deepEqual(implementer?.defaultReads, ["explicit.md"]);
794
+ });
795
+
796
+ it("keeps an explicit empty defaultReads override distinct from false", () => {
797
+ writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
798
+ subagents: { agentOverrides: { implementer: { defaultReads: [] } } },
799
+ });
800
+ writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\n---\n\nDrive the failing test first.\n`);
801
+
802
+ const implementer = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "implementer");
803
+ assert.deepEqual(implementer?.defaultReads, []);
804
+ });
805
+
627
806
  it("leaves a custom agent untouched when no agentOverrides entry matches its name", () => {
628
807
  writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
629
808
  subagents: { agentOverrides: { reviewer: { model: "openai/gpt-5.4" } } },
@@ -758,10 +937,71 @@ describe("builtin agent overrides", () => {
758
937
  );
759
938
  });
760
939
 
940
+ it("rejects unsupported outputMode override values", () => {
941
+ const settingsPath = path.join(tempHome, ".selesai", "agent", "settings.json");
942
+ for (const outputMode of ["artifact-only", false]) {
943
+ writeJson(settingsPath, {
944
+ subagents: {
945
+ agentOverrides: {
946
+ reviewer: { outputMode },
947
+ },
948
+ },
949
+ });
950
+
951
+ assert.throws(
952
+ () => discoverAgents(tempProject, "both"),
953
+ (error: unknown) => error instanceof Error
954
+ && error.message.includes(settingsPath)
955
+ && error.message.includes("reviewer")
956
+ && error.message.includes("outputMode"),
957
+ );
958
+ }
959
+ });
960
+
961
+ it("applies output and defaultReads overrides to bundled and package agents and supports false clears", () => {
962
+ const packageRoot = path.join(tempProject, "package-agents");
963
+ fs.mkdirSync(path.join(packageRoot, "agents"), { recursive: true });
964
+ writeJson(path.join(packageRoot, "package.json"), { "pi-subagents": { agents: ["agents"] } });
965
+ fs.writeFileSync(path.join(packageRoot, "agents", "package-scout.md"), `---\nname: package-scout\ndescription: Package scout\n---\n\nScout the package.\n`, "utf-8");
966
+ writeJson(path.join(tempProject, ".selesai", "settings.json"), {
967
+ packages: [packageRoot],
968
+ subagents: { agentOverrides: { "package-scout": { output: "package.md", defaultReads: ["PACKAGE.md"] } } },
969
+ });
970
+ writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
971
+ subagents: {
972
+ agentOverrides: {
973
+ scout: { output: "research-scout-results.md", defaultReads: ["AGENTS.md"] },
974
+ reviewer: { output: false, defaultReads: false },
975
+ },
976
+ },
977
+ });
978
+
979
+ const agents = discoverAgents(tempProject, "both").agents;
980
+ assert.equal(agents.find((agent) => agent.name === "scout")?.output, "research-scout-results.md");
981
+ assert.deepEqual(agents.find((agent) => agent.name === "scout")?.defaultReads, ["AGENTS.md"]);
982
+ assert.equal(agents.find((agent) => agent.name === "reviewer")?.output, undefined);
983
+ assert.equal(agents.find((agent) => agent.name === "reviewer")?.defaultReads, undefined);
984
+ assert.equal(agents.find((agent) => agent.name === "package-scout")?.output, "package.md");
985
+ assert.deepEqual(agents.find((agent) => agent.name === "package-scout")?.defaultReads, ["PACKAGE.md"]);
986
+ });
987
+
988
+ it("surfaces malformed output and defaultReads override values", () => {
989
+ const settingsPath = path.join(tempHome, ".selesai", "agent", "settings.json");
990
+ for (const [field, value] of [["output", 42], ["output", ""], ["output", " "], ["defaultReads", ["ok", 42]]] as const) {
991
+ writeJson(settingsPath, { subagents: { agentOverrides: { reviewer: { [field]: value } } } });
992
+ assert.throws(
993
+ () => discoverAgents(tempProject, "both"),
994
+ (error: unknown) => error instanceof Error && error.message.includes(settingsPath) && error.message.includes("reviewer") && error.message.includes(field),
995
+ );
996
+ }
997
+ });
998
+
761
999
  it("builds description changes and false sentinels when an override clears builtin fields", () => {
762
1000
  const override = buildBuiltinOverrideConfig(
763
1001
  {
764
1002
  description: "Base description",
1003
+ output: "base-output.md",
1004
+ defaultReads: ["base-read.md"],
765
1005
  model: "openai-codex/gpt-5.4-mini",
766
1006
  fallbackModels: ["openai/gpt-5-mini"],
767
1007
  thinking: "high",
@@ -779,6 +1019,8 @@ describe("builtin agent overrides", () => {
779
1019
  },
780
1020
  {
781
1021
  description: "Override description",
1022
+ output: undefined,
1023
+ defaultReads: undefined,
782
1024
  model: undefined,
783
1025
  fallbackModels: undefined,
784
1026
  thinking: undefined,
@@ -798,6 +1040,8 @@ describe("builtin agent overrides", () => {
798
1040
 
799
1041
  assert.deepEqual(override, {
800
1042
  description: "Override description",
1043
+ output: false,
1044
+ defaultReads: false,
801
1045
  model: false,
802
1046
  fallbackModels: false,
803
1047
  thinking: false,
@@ -813,8 +1057,16 @@ describe("builtin agent overrides", () => {
813
1057
  assert.ok(override);
814
1058
  fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
815
1059
  saveBuiltinAgentOverride(tempProject, "reviewer", "project", override);
1060
+ const savedOverride = JSON.parse(fs.readFileSync(path.join(tempProject, ".selesai", "settings.json"), "utf-8"));
1061
+ assert.equal(savedOverride.subagents.agentOverrides.reviewer.output, false);
1062
+ assert.equal(savedOverride.subagents.agentOverrides.reviewer.defaultReads, false);
816
1063
  assert.equal(discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "reviewer")?.description, "Override description");
817
1064
 
1065
+ saveBuiltinAgentOverride(tempProject, "scout", "project", { output: "research.md", defaultReads: ["CONTEXT.md"] });
1066
+ const scout = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "scout");
1067
+ assert.equal(scout?.output, "research.md");
1068
+ assert.deepEqual(scout?.defaultReads, ["CONTEXT.md"]);
1069
+
818
1070
  const whitespaceDescription = buildBuiltinOverrideConfig(
819
1071
  { description: "Base description" },
820
1072
  { description: " " } as Parameters<typeof buildBuiltinOverrideConfig>[1],
@@ -11,7 +11,7 @@ import {
11
11
  getProjectChainRunsDir,
12
12
  getProjectSubagentsDir,
13
13
  } from "../../src/shared/artifacts.ts";
14
- import { CHAIN_RUNS_DIR } from "../../src/shared/types.ts";
14
+ import { CHAIN_RUNS_DIR, TEMP_ARTIFACTS_DIR } from "../../src/shared/types.ts";
15
15
 
16
16
  describe("project-local artifact paths", () => {
17
17
  const tempDirs: string[] = [];
@@ -32,7 +32,7 @@ describe("project-local artifact paths", () => {
32
32
  assert.match(getProjectArtifactPackagingWarning(packageDir({ name: "unsafe" })) ?? "", /\.npmignore/);
33
33
  assert.equal(getProjectArtifactPackagingWarning(packageDir({ name: "gitignored" }, { name: ".gitignore", content: ".pi-subagents/\n" })), undefined);
34
34
  assert.equal(getProjectArtifactPackagingWarning(packageDir({ name: "globignored" }, { name: ".npmignore", content: "**/.pi-subagents/**\n" })), undefined);
35
- assert.equal(getProjectArtifactPackagingWarning(packageDir({ name: "classignored" }, { name: ".npmignore", content: "[.]pi-subagents/**\n" })), undefined);
35
+ assert.equal(getProjectArtifactPackagingWarning(packageDir({ name: "classignored" }, { name: ".npmignore", content: "[.]pi/subagents/**\n" })), undefined);
36
36
  assert.match(getProjectArtifactPackagingWarning(packageDir({ name: "explicit-files-over-ignore", files: [".pi-subagents/**"] }, { name: ".npmignore", content: ".pi-subagents/\n" })) ?? "", /artifactDir/);
37
37
  assert.equal(getProjectArtifactPackagingWarning(packageDir({ name: "restricted", files: ["src/**"] })), undefined);
38
38
  assert.equal(getProjectArtifactPackagingWarning(packageDir({ name: "malformed-pattern", files: ["[z-a]"] })), undefined);
@@ -53,24 +53,26 @@ describe("project-local artifact paths", () => {
53
53
  assert.match(getProjectArtifactPackagingWarning(packageDir({ name: "chain-runs-directory-included", files: [".pi-subagents/chain-runs"] })) ?? "", /artifactDir/);
54
54
  });
55
55
 
56
- it("places generated subagent files under .pi-subagents for a project cwd", () => {
56
+ it("keeps project-scoped paths available as an explicit opt-in", () => {
57
57
  const cwd = path.join("tmp", "repo");
58
58
  assert.equal(getProjectSubagentsDir(cwd), path.join(cwd, ".pi-subagents"));
59
59
  assert.equal(getProjectArtifactsDir(cwd), path.join(cwd, ".pi-subagents", "artifacts"));
60
60
  assert.equal(getProjectChainRunsDir(cwd), path.join(cwd, ".pi-subagents", "chain-runs"));
61
- assert.equal(getArtifactsDir(null, cwd), path.join(cwd, ".pi-subagents", "artifacts"));
61
+ assert.equal(getArtifactsDir(null, cwd, "project"), path.join(cwd, ".pi-subagents", "artifacts"));
62
62
  });
63
63
 
64
64
  it("routes chain scratch files according to the artifact preference", () => {
65
65
  const cwd = path.join("tmp", "repo");
66
- assert.equal(getChainRunsDir(cwd), getProjectChainRunsDir(cwd));
66
+ assert.equal(getChainRunsDir(cwd), CHAIN_RUNS_DIR);
67
67
  assert.equal(getChainRunsDir(cwd, "project"), getProjectChainRunsDir(cwd));
68
68
  assert.equal(getChainRunsDir(cwd, "session"), CHAIN_RUNS_DIR);
69
69
  assert.equal(getChainRunsDir(cwd, "temp"), CHAIN_RUNS_DIR);
70
70
  });
71
71
 
72
- it("keeps the session artifact fallback when no project cwd is available", () => {
72
+ it("defaults artifacts to the session directory and falls back to temp", () => {
73
+ const cwd = path.join("tmp", "repo");
73
74
  const sessionFile = path.join("tmp", "sessions", "parent.jsonl");
74
- assert.equal(getArtifactsDir(sessionFile), path.join("tmp", "sessions", "subagent-artifacts"));
75
+ assert.equal(getArtifactsDir(sessionFile, cwd), path.join("tmp", "sessions", "subagent-artifacts"));
76
+ assert.equal(getArtifactsDir(null, cwd), path.join(TEMP_ARTIFACTS_DIR));
75
77
  });
76
78
  });
@@ -4,10 +4,10 @@ import * as os from "node:os";
4
4
  import * as path from "node:path";
5
5
  import { describe, it } from "node:test";
6
6
  import { acquireActiveAsyncCapacity } from "../../src/runs/background/active-async-capacity.ts";
7
- import { consumeSteerRequests, consumeSteerRequestsFromDir, stepSteerInboxDir, writeSteerAck } from "../../src/runs/background/control-channel.ts";
7
+ import { consumeSteerRequests, consumeSteerRequestsFromDir, consumeStopRequestPayload, stepSteerInboxDir, writeSteerAck } from "../../src/runs/background/control-channel.ts";
8
8
  import { listAsyncRuns } from "../../src/runs/background/async-status.ts";
9
9
  import { inspectSubagentStatus } from "../../src/runs/background/run-status.ts";
10
- import { createSubagentExecutor } from "../../src/runs/foreground/subagent-executor.ts";
10
+ import { createSubagentExecutor, steerWorkflowChildByKey } from "../../src/runs/foreground/subagent-executor.ts";
11
11
  import { steerWorkflowForegroundTarget, workflowForegroundSteeringDir } from "../../src/runs/foreground/workflow-foreground-steering.ts";
12
12
  import { ASYNC_DIR, RESULTS_DIR, type SubagentState } from "../../src/shared/types.ts";
13
13
 
@@ -215,11 +215,108 @@ describe("async interrupt action", () => {
215
215
  assert.equal(result.details.steering?.state, "delivered");
216
216
  assert.equal(result.details.steering?.sourceRunId, childRunId);
217
217
  assert.equal(request.message, "Focus on the failing test.");
218
+ assert.match(text(result), /Message: "Focus on the failing test\."/);
218
219
  } finally {
219
220
  cleanup(workflowRunId, asyncDir);
220
221
  }
221
222
  });
222
223
 
224
+ it("steers a foreground workflow child by stable key", async () => {
225
+ const state = createState();
226
+ const workflowRunId = `workflow-key-foreground-${Date.now().toString(36)}`;
227
+ const childRunId = `${workflowRunId}-writer`;
228
+ const asyncDir = createRunningAsync(state, workflowRunId, { track: false, mode: "workflow" });
229
+ const routeDir = createWorkflowForegroundControl(state, workflowRunId, childRunId);
230
+ try {
231
+ const action = steerWorkflowChildByKey({ state, workflowRunId, key: childRunId, message: "Focus on the contract.", options: { ackTimeoutMs: 500 } });
232
+ const request = await waitUntil(() => {
233
+ const inbox = stepSteerInboxDir(routeDir, 0);
234
+ const entry = fs.readdirSync(inbox).find((name) => name.endsWith(".json"));
235
+ return entry ? JSON.parse(fs.readFileSync(path.join(inbox, entry), "utf-8")) as { id: string } : undefined;
236
+ });
237
+ writeSteerAck(routeDir, { requestId: request.id, index: 0, ts: Date.now(), state: "delivered", message: "accepted" });
238
+ assert.equal((await action).state, "delivered");
239
+ } finally {
240
+ cleanup(workflowRunId, asyncDir);
241
+ }
242
+ });
243
+
244
+ it("routes a stable key to async steering without recovery", async () => {
245
+ const state = createState();
246
+ const workflowRunId = `workflow-key-async-${Date.now().toString(36)}`;
247
+ const childRunId = `${workflowRunId}-child`;
248
+ const workflowDir = createRunningAsync(state, workflowRunId, { track: false, mode: "workflow" });
249
+ const childDir = createRunningAsync(state, childRunId, { track: false });
250
+ const childStatus = JSON.parse(fs.readFileSync(path.join(childDir, "status.json"), "utf-8"));
251
+ childStatus.pid = process.pid;
252
+ writeJson(path.join(childDir, "status.json"), childStatus);
253
+ const workflowStatus = JSON.parse(fs.readFileSync(path.join(workflowDir, "status.json"), "utf-8"));
254
+ workflowStatus.steps = [];
255
+ writeJson(path.join(workflowDir, "status.json"), workflowStatus);
256
+ const controller = new AbortController();
257
+ try {
258
+ const action = steerWorkflowChildByKey({ state, workflowRunId, key: "writer", message: "Use the new API.", options: { ackTimeoutMs: 500 }, signal: controller.signal, resolveRunId: () => childRunId });
259
+ await waitUntil(() => consumeSteerRequests(childDir)[0] ? true : undefined);
260
+ controller.abort();
261
+ assert.equal((await action).state, "queued");
262
+ assert.equal(fs.existsSync(path.join(childDir, "control", "steer-recovery")), false);
263
+ } finally {
264
+ cleanup(workflowRunId, workflowDir);
265
+ cleanup(childRunId, childDir);
266
+ }
267
+ });
268
+
269
+ it("returns missed when a terminal keyed child cannot accept a retained follow-up", async () => {
270
+ const state = createState();
271
+ const workflowRunId = `workflow-key-terminal-${Date.now().toString(36)}`;
272
+ const childRunId = `${workflowRunId}-child`;
273
+ const workflowDir = createRunningAsync(state, workflowRunId, { track: false, mode: "workflow" });
274
+ const childDir = createRunningAsync(state, childRunId, { track: false });
275
+ const workflowStatus = JSON.parse(fs.readFileSync(path.join(workflowDir, "status.json"), "utf-8"));
276
+ workflowStatus.steps = [{ agent: "worker", status: "completed", workflowKey: "writer", runId: childRunId, async: true }];
277
+ writeJson(path.join(workflowDir, "status.json"), workflowStatus);
278
+ const sessionFile = path.join(childDir, "child.jsonl");
279
+ fs.writeFileSync(sessionFile, "", "utf-8");
280
+ const childStatus = JSON.parse(fs.readFileSync(path.join(childDir, "status.json"), "utf-8"));
281
+ childStatus.state = "complete";
282
+ childStatus.parentWorkflowRunId = workflowRunId;
283
+ childStatus.steps = [{ agent: "worker", status: "complete", sessionFile }];
284
+ writeJson(path.join(childDir, "status.json"), childStatus);
285
+ try {
286
+ const result = await steerWorkflowChildByKey({ state, workflowRunId, key: "writer", message: "Too late.", options: { mode: "follow_up", index: 1, ackTimeoutMs: 20 } });
287
+ assert.equal(result.state, "missed");
288
+ assert.match(result.error ?? "", /is complete/);
289
+ assert.doesNotMatch(JSON.stringify(result), new RegExp(childRunId));
290
+ assert.equal(consumeSteerRequests(childDir).length, 0);
291
+ assert.equal(fs.existsSync(path.join(childDir, "control", "revival-briefs")), false);
292
+ } finally {
293
+ cleanup(workflowRunId, workflowDir);
294
+ cleanup(childRunId, childDir);
295
+ }
296
+ });
297
+
298
+ it("returns missed when a keyed child's raw running status reconciles terminal", async () => {
299
+ const state = createState();
300
+ const workflowRunId = `workflow-key-reconciled-${Date.now().toString(36)}`;
301
+ const childRunId = `${workflowRunId}-child`;
302
+ const workflowDir = createRunningAsync(state, workflowRunId, { track: false, mode: "workflow" });
303
+ const childDir = createRunningAsync(state, childRunId, { track: false });
304
+ const workflowStatus = JSON.parse(fs.readFileSync(path.join(workflowDir, "status.json"), "utf-8"));
305
+ workflowStatus.steps = [{ agent: "worker", status: "completed", workflowKey: "writer", runId: childRunId, async: true }];
306
+ writeJson(path.join(workflowDir, "status.json"), workflowStatus);
307
+ writeJson(path.join(RESULTS_DIR, `${childRunId}.json`), { runId: childRunId, mode: "single", success: false, error: "terminal", results: [] });
308
+ try {
309
+ const result = await steerWorkflowChildByKey({ state, workflowRunId, key: "writer", message: "Too late.", options: { ackTimeoutMs: 20 } });
310
+ assert.equal(result.state, "missed");
311
+ assert.match(result.error ?? "", /is failed/);
312
+ assert.doesNotMatch(JSON.stringify(result), new RegExp(childRunId));
313
+ assert.equal(consumeSteerRequests(childDir).length, 0);
314
+ } finally {
315
+ cleanup(workflowRunId, workflowDir);
316
+ cleanup(childRunId, childDir);
317
+ }
318
+ });
319
+
223
320
  it("rejects a steer request when its workflow foreground route is already removed", async () => {
224
321
  const state = createState();
225
322
  const workflowRunId = `workflow-missing-route-${Date.now().toString(36)}`;
@@ -489,25 +586,27 @@ describe("async interrupt action", () => {
489
586
  }
490
587
  });
491
588
 
492
- it("rejects interrupt for a running external CLI run without writing a pause request", async () => {
493
- const state = createState();
494
- const runId = `interrupt-external-${Date.now().toString(36)}`;
495
- const asyncDir = createRunningAsync(state, runId, { track: false });
496
- const statusPath = path.join(asyncDir, "status.json");
497
- const status = JSON.parse(fs.readFileSync(statusPath, "utf-8"));
498
- status.steps[0].runner = { type: "external-cli" };
499
- fs.writeFileSync(statusPath, JSON.stringify(status), "utf-8");
500
- try {
501
- const result = await executorWithKill(state, () => {
502
- throw new Error("external interrupt should not signal the runner");
503
- }).execute("interrupt", { action: "interrupt", id: runId }, new AbortController().signal, undefined, ctx());
589
+ it("rejects interrupt for a running external runner without writing a pause request", async () => {
590
+ for (const runner of [{ type: "external-cli" }, { type: "external-job", provider: "surf-oracle", options: {} }]) {
591
+ const state = createState();
592
+ const runId = `interrupt-external-${runner.type}-${Date.now().toString(36)}`;
593
+ const asyncDir = createRunningAsync(state, runId, { track: false });
594
+ const statusPath = path.join(asyncDir, "status.json");
595
+ const status = JSON.parse(fs.readFileSync(statusPath, "utf-8"));
596
+ status.steps[0].runner = runner;
597
+ fs.writeFileSync(statusPath, JSON.stringify(status), "utf-8");
598
+ try {
599
+ const result = await executorWithKill(state, () => {
600
+ throw new Error("external interrupt should not signal the runner");
601
+ }).execute("interrupt", { action: "interrupt", id: runId }, new AbortController().signal, undefined, ctx());
504
602
 
505
- assert.equal(result.isError, true);
506
- assert.match(text(result), /Interrupt is unsupported for one-shot external CLI async run/);
507
- assert.equal(fs.existsSync(path.join(asyncDir, "control", "interrupt.json")), false);
508
- assert.equal(JSON.parse(fs.readFileSync(statusPath, "utf-8")).state, "running");
509
- } finally {
510
- cleanup(runId, asyncDir);
603
+ assert.equal(result.isError, true);
604
+ assert.match(text(result), new RegExp(`Interrupt is unsupported for external async run ${runId}; use stop instead\\.`));
605
+ assert.equal(fs.existsSync(path.join(asyncDir, "control", "interrupt.json")), false);
606
+ assert.equal(JSON.parse(fs.readFileSync(statusPath, "utf-8")).state, "running");
607
+ } finally {
608
+ cleanup(runId, asyncDir);
609
+ }
511
610
  }
512
611
  });
513
612
 
@@ -525,13 +624,44 @@ describe("async interrupt action", () => {
525
624
 
526
625
  assert.equal(result.isError, undefined);
527
626
  assert.match(text(result), new RegExp(`Stop requested for async run ${runId}`));
528
- assert.equal(fs.existsSync(path.join(asyncDir, "control", "stop.json")), true);
627
+ assert.equal(consumeStopRequestPayload(asyncDir)?.type, "stop");
529
628
  assert.deepEqual(kills, [{ pid: 12345, signal: 0 }]);
530
629
  } finally {
531
630
  cleanup(runId, asyncDir);
532
631
  }
533
632
  });
534
633
 
634
+ it("writes child-scoped stop requests for a running async run", async () => {
635
+ const state = createState();
636
+ state.currentSessionId = "session";
637
+ const runId = `stop-child-${Date.now().toString(36)}`;
638
+ const asyncDir = createRunningAsync(state, runId, { track: false, sessionId: "session" });
639
+ try {
640
+ const statusPath = path.join(asyncDir, "status.json");
641
+ writeJson(statusPath, {
642
+ ...JSON.parse(fs.readFileSync(statusPath, "utf-8")),
643
+ steps: [
644
+ { agent: "first", status: "running", runId: "child-a", startedAt: 100 },
645
+ { agent: "second", status: "running", workflowKey: "review", startedAt: 100 },
646
+ ],
647
+ });
648
+
649
+ const result = await executorWithKill(state, () => true)
650
+ .execute("stop-child", { action: "stop", id: runId, childId: "review" }, new AbortController().signal, undefined, ctx());
651
+
652
+ assert.equal(result.isError, undefined);
653
+ assert.match(text(result), /Stop requested for child review/);
654
+ const request = consumeStopRequestPayload(asyncDir);
655
+ assert.equal(request?.type, "stop");
656
+ assert.equal(request?.source, "stop-action");
657
+ assert.equal(request?.targetIndex, 1);
658
+ assert.equal(request?.childId, "review");
659
+ assert.equal(typeof request?.ts, "number");
660
+ } finally {
661
+ cleanup(runId, asyncDir);
662
+ }
663
+ });
664
+
535
665
  it("dismisses only a reload-recovered running workflow without terminating work", async () => {
536
666
  const state = createState();
537
667
  state.currentSessionId = "session";
@@ -725,7 +855,7 @@ describe("async interrupt action", () => {
725
855
 
726
856
  assert.equal(result.isError, undefined);
727
857
  assert.match(text(result), new RegExp(`Stop requested for async run ${runId}`));
728
- assert.equal(fs.existsSync(path.join(asyncDir, "control", "stop.json")), true);
858
+ assert.equal(consumeStopRequestPayload(asyncDir)?.type, "stop");
729
859
  } finally {
730
860
  cleanup(runId, asyncDir);
731
861
  }