@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
@@ -6,6 +6,9 @@ import * as path from "node:path";
6
6
  import { after, afterEach, before, beforeEach, describe, it } from "node:test";
7
7
  import { ASYNC_DIR, INTERCOM_DETACH_REQUEST_EVENT, RESULTS_DIR, SUBAGENT_ASYNC_STARTED_EVENT, SUBAGENT_FOREGROUND_COMPLETE_EVENT } from "../../src/shared/types.ts";
8
8
  import { ACTIVE_ASYNC_CAPACITY_DIR, acquireActiveAsyncCapacity, activeAsyncCapacitySessionKey, getActiveAsyncCapacitySnapshot } from "../../src/runs/background/active-async-capacity.ts";
9
+ import { EXTERNAL_JOB_PROVIDER_REGISTRY_KEY, registerExternalJobProvider } from "../../src/api/external-job-provider.ts";
10
+ import { serviceExternalJobBridgeRequests } from "../../src/runs/shared/external-job-bridge.ts";
11
+ import { externalJobFollowUpRequestDigest, externalJobFollowUpRunId, externalJobPromptDigest } from "../../src/runs/shared/external-job-runner.ts";
9
12
  import { waitForSubagents } from "../../src/runs/background/subagent-wait.ts";
10
13
  import { createRunFanoutBudget } from "../../src/runs/shared/run-fanout-budget.ts";
11
14
  import { acquireSessionLease, sessionLeaseDir } from "../../src/runs/shared/session-lease.ts";
@@ -114,6 +117,7 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
114
117
  });
115
118
 
116
119
  afterEach(() => {
120
+ delete (globalThis as Record<PropertyKey, unknown>)[Symbol.for(EXTERNAL_JOB_PROVIDER_REGISTRY_KEY)];
117
121
  removeTempDir(tempDir);
118
122
  for (const directory of budgetDirectories.splice(0)) fs.rmSync(directory, { recursive: true, force: true });
119
123
  });
@@ -260,9 +264,9 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
260
264
  assert.equal(payload.mode, "single");
261
265
  assert.equal(payload.children?.length, 1);
262
266
  assert.equal(payload.children?.[0]?.agent, "worker");
263
- assert.match(payload.children?.[0]?.intercomTarget ?? "", /^subagent-worker-[a-f0-9]+-1$/);
267
+ assert.match(payload.children?.[0]?.intercomTarget ?? "", /^subagent-worker-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}-1$/);
264
268
  assert.match(String(payload.message ?? ""), /Intercom targets below identify child sessions used while they were running/);
265
- assert.match(String(payload.message ?? ""), /Run intercom target: subagent-worker-[a-f0-9]+-1/);
269
+ assert.match(String(payload.message ?? ""), /Run intercom target: subagent-worker-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}-1/);
266
270
  assert.match(result.content[0]?.text ?? "", /Delivered single subagent result via intercom\./);
267
271
  assert.doesNotMatch(result.content[0]?.text ?? "", /Full child output from worker/);
268
272
  assert.equal(result.details?.results?.[0]?.finalOutput, undefined);
@@ -410,31 +414,7 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
410
414
  assert.match(result.content[0]?.text ?? "", /Unacknowledged foreground output/);
411
415
  });
412
416
 
413
- it("top-level parallel runs emit one grouped event containing all children", async () => {
414
- mockPi.onCall({ output: "Parallel child output" });
415
- const { executor, events } = makeExecutor({ resultDelivery: true, agents: [makeAgent("a"), makeAgent("b")] });
416
417
 
417
- const result = await executor.execute(
418
- "parallel-intercom",
419
- { tasks: [{ agent: "a", task: "task-a" }, { agent: "b", task: "task-b" }] },
420
- new AbortController().signal,
421
- undefined,
422
- makeMinimalCtx(tempDir),
423
- );
424
-
425
- const intercomEvents = events.emitted.filter((entry) => entry.channel === "subagent:result-intercom");
426
- assert.equal(intercomEvents.length, 1);
427
- const payload = intercomEvents[0]!.payload as { children?: Array<{ agent?: string; intercomTarget?: string }>; message?: string; mode?: string };
428
- assert.equal(payload.mode, "parallel");
429
- assert.deepEqual((payload.children ?? []).map((child) => child.agent).sort(), ["a", "b"]);
430
- assert.equal((payload.children ?? []).every((child) => /^subagent-[ab]-[a-f0-9]+-[12]$/.test(child.intercomTarget ?? "")), true);
431
- assert.match(String(payload.message ?? ""), /Intercom targets below identify child sessions used while they were running/);
432
- assert.match(String(payload.message ?? ""), /Run intercom target: subagent-a-[a-f0-9]+-1/);
433
- assert.match(String(payload.message ?? ""), /1\. a — process completed · output present/);
434
- assert.match(String(payload.message ?? ""), /2\. b — process completed · output present/);
435
- assert.match(result.content[0]?.text ?? "", /Delivered parallel subagent results via intercom\./);
436
- assert.equal(result.details?.results?.every((entry) => entry.finalOutput === undefined), true);
437
- });
438
418
 
439
419
  it("suppresses successful worktree child receipts for live-card workflows", { skip: process.platform === "win32" ? "git worktree cleanup differs on Windows" : undefined }, async () => {
440
420
  execFileSync("git", ["init"], { cwd: tempDir, stdio: "ignore" });
@@ -460,110 +440,13 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
460
440
  assert.match(result.content[0]?.text ?? "", /Worktree child output/);
461
441
  });
462
442
 
463
- it("keeps a queued top-level parallel child controlled after an early outer rejection", async () => {
464
- mockPi.onCall({ matchArgIncludes: "task-a", output: "early child", delay: 100 });
465
- mockPi.onCall({ matchArgIncludes: "task-b", output: "middle child", delay: 400 });
466
- mockPi.onCall({ matchArgIncludes: "task-c", output: "too late", delay: 10_000 });
467
- const { executor, state } = makeExecutor({ bridgeMode: "off", agents: [makeAgent("a"), makeAgent("b"), makeAgent("c")] });
468
- let rejected = false;
469
- const result = await executor.execute(
470
- "parallel-rejection-cleanup",
471
- { concurrency: 2, tasks: [{ agent: "a", task: "task-a" }, { agent: "b", task: "task-b" }, { agent: "c", task: "task-c" }] },
472
- new AbortController().signal,
473
- (update: { details?: { progress?: Array<{ agent?: string; status?: string }> } }) => {
474
- if (!rejected && update.details?.progress?.some((entry) => entry.agent === "a" && entry.status === "completed")) {
475
- rejected = true;
476
- throw new Error("reject early parallel completion");
477
- }
478
- },
479
- makeMinimalCtx(tempDir),
480
- );
481
- assert.equal(rejected, true);
482
- assert.equal(result.isError, true);
483
- assert.equal(state.foregroundControls.size, 1, "remaining worker still owns queued scheduling");
484
- await waitForCallCount(3);
485
- const liveControl = [...state.foregroundControls.values()][0];
486
- assert.equal(liveControl?.currentAgent, "c", "later queued child must remain discoverable after launch");
487
- assert.ok(liveControl?.interrupt, "later queued child must remain interruptible");
488
- assert.equal(liveControl.interrupt(), true);
489
- for (let attempt = 0; attempt < 100 && state.foregroundControls.size > 0; attempt++) await new Promise((resolve) => setTimeout(resolve, 20));
490
- assert.equal(state.foregroundControls.size, 0, "control must disappear after workers and children settle");
491
- });
492
443
 
493
- it("keeps a queued chain-parallel child controlled after an early outer rejection", async () => {
494
- mockPi.onCall({ matchArgIncludes: "chain-task-a", output: "early chain child", delay: 100 });
495
- mockPi.onCall({ matchArgIncludes: "chain-task-b", output: "middle chain child", delay: 400 });
496
- mockPi.onCall({ matchArgIncludes: "chain-task-c", output: "too late", delay: 10_000 });
497
- const { executor, state } = makeExecutor({ bridgeMode: "off", agents: [makeAgent("a"), makeAgent("b"), makeAgent("c")] });
498
- let rejected = false;
499
- const result = await executor.execute(
500
- "chain-parallel-rejection-cleanup",
501
- { chain: [{ concurrency: 2, parallel: [{ agent: "a", task: "chain-task-a" }, { agent: "b", task: "chain-task-b" }, { agent: "c", task: "chain-task-c" }] }] },
502
- new AbortController().signal,
503
- (update: { details?: { progress?: Array<{ agent?: string; status?: string }> } }) => {
504
- if (!rejected && update.details?.progress?.some((entry) => entry.agent === "a" && entry.status === "completed")) {
505
- rejected = true;
506
- throw new Error("reject early chain completion");
507
- }
508
- },
509
- makeMinimalCtx(tempDir),
510
- );
511
- assert.equal(rejected, true);
512
- assert.equal(result.isError, true);
513
- assert.equal(state.foregroundControls.size, 1, "remaining chain worker still owns queued scheduling");
514
- await waitForCallCount(3);
515
- const liveControl = [...state.foregroundControls.values()][0];
516
- assert.equal(liveControl?.currentAgent, "c", "later queued chain child must remain discoverable after launch");
517
- assert.ok(liveControl?.interrupt, "later queued chain child must remain interruptible");
518
- assert.equal(liveControl.interrupt(), true);
519
- for (let attempt = 0; attempt < 100 && state.foregroundControls.size > 0; attempt++) await new Promise((resolve) => setTimeout(resolve, 20));
520
- assert.equal(state.foregroundControls.size, 0, "chain control must disappear after workers and children settle");
521
- });
522
444
 
523
- it("cleans a rejected sequential chain child and releases foreground ownership", async () => {
524
- mockPi.onCall({ output: "sequential child output" });
525
- const { executor, state } = makeExecutor({ bridgeMode: "off", agents: [makeAgent("worker")] });
526
- let rejected = false;
527
- let ownedControl: { schedulingOwners?: number; activeChildren?: Map<number, unknown> } | undefined;
528
- const result = await executor.execute(
529
- "chain-sequential-rejection-cleanup",
530
- { chain: [{ agent: "worker", task: "sequential task" }] },
531
- new AbortController().signal,
532
- (update: { details?: { progress?: Array<{ status?: string }> } }) => {
533
- if (rejected || !update.details?.progress?.some((entry) => entry.status === "completed")) return;
534
- rejected = true;
535
- ownedControl = [...state.foregroundControls.values()][0];
536
- throw new Error("reject sequential chain completion");
537
- },
538
- makeMinimalCtx(tempDir),
539
- );
540
- assert.equal(rejected, true);
541
- assert.equal(result.isError, true);
542
- assert.ok(ownedControl);
543
- assert.equal(ownedControl.schedulingOwners, 0);
544
- assert.equal(ownedControl.activeChildren?.size, 0);
545
- assert.equal(state.foregroundControls.size, 0);
546
- });
547
445
 
548
- it("cleans a sequential chain child after an early tool-budget validation return", async () => {
549
- const { executor, state } = makeExecutor({ bridgeMode: "off", agents: [makeAgent("worker")] });
550
- const execution = executor.execute(
551
- "chain-sequential-budget-cleanup",
552
- { chain: [{ agent: "worker", task: "invalid budget task", toolBudget: { hard: 0 } }] },
553
- new AbortController().signal,
554
- undefined,
555
- makeMinimalCtx(tempDir),
556
- );
557
- const ownedControl = [...state.foregroundControls.values()][0];
558
- assert.ok(ownedControl, "outer scheduling owner should remain visible until execution settles");
559
- const result = await execution;
560
- assert.equal(result.isError, true);
561
- assert.match(result.content[0]?.text ?? "", /toolBudget\.hard must be an integer >= 1/);
562
- assert.equal(mockPi.callCount(), 0);
563
- assert.equal(ownedControl.schedulingOwners, 0);
564
- assert.equal(ownedControl.activeChildren?.size, 0);
565
- assert.equal(state.foregroundControls.size, 0);
566
- });
446
+
447
+
448
+
449
+
567
450
 
568
451
  it("cleans an attached single rejection and its temporary structured runtime", async () => {
569
452
  mockPi.onCall({
@@ -593,70 +476,9 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
593
476
  assert.equal(fs.existsSync(structuredDir), false, "temporary structured runtime must be removed on rejection");
594
477
  });
595
478
 
596
- it("chain runs emit one grouped event containing all executed children", async () => {
597
- mockPi.onCall({ output: "Chain child output" });
598
- const { executor, events } = makeExecutor({ resultDelivery: true, agents: [makeAgent("a"), makeAgent("b"), makeAgent("c")] });
599
479
 
600
- const result = await executor.execute(
601
- "chain-intercom",
602
- {
603
- chain: [
604
- { agent: "a", task: "step-a" },
605
- { parallel: [{ agent: "b", task: "step-b" }, { agent: "c", task: "step-c" }] },
606
- ],
607
- },
608
- new AbortController().signal,
609
- undefined,
610
- makeMinimalCtx(tempDir),
611
- );
612
480
 
613
- const intercomEvents = events.emitted.filter((entry) => entry.channel === "subagent:result-intercom");
614
- assert.equal(intercomEvents.length, 1);
615
- const payload = intercomEvents[0]!.payload as { children?: Array<{ agent?: string; intercomTarget?: string }>; message?: string; mode?: string };
616
- assert.equal(payload.mode, "chain");
617
- assert.deepEqual((payload.children ?? []).map((child) => child.agent).sort(), ["a", "b", "c"]);
618
- assert.equal((payload.children ?? []).every((child) => /^subagent-[abc]-[a-f0-9]+-[123]$/.test(child.intercomTarget ?? "")), true);
619
- assert.match(String(payload.message ?? ""), /1\. a — process completed · output present/);
620
- assert.match(String(payload.message ?? ""), /2\. b — process completed · output present/);
621
- assert.match(String(payload.message ?? ""), /3\. c — process completed · output present/);
622
- assert.match(result.content[0]?.text ?? "", /Delivered chain subagent results via intercom\./);
623
- assert.equal(result.details?.results?.every((entry) => entry.finalOutput === undefined), true);
624
- });
625
481
 
626
- it("detached chain runs do not emit grouped completion receipts", async () => {
627
- mockPi.onCall({
628
- steps: [
629
- { jsonl: [events.toolStart("contact_supervisor", { reason: "need_decision", message: "Need a decision" })] },
630
- { delay: 1000, jsonl: [events.assistantMessage("after reply")] },
631
- ],
632
- });
633
- const { executor, events: bus } = makeExecutor({ agents: [makeAgent("a", { systemPrompt: "Intercom orchestration channel:" }), makeAgent("b")] });
634
- let detachEmitted = false;
635
-
636
- const result = await executor.execute(
637
- "chain-detached-intercom",
638
- {
639
- chain: [
640
- { agent: "a", task: "ask supervisor" },
641
- { agent: "b", task: "must not run" },
642
- ],
643
- },
644
- new AbortController().signal,
645
- (update: { details?: { progress?: Array<{ currentTool?: string }> } }) => {
646
- if (detachEmitted) return;
647
- if (!update.details?.progress?.some((entry) => entry.currentTool === "contact_supervisor")) return;
648
- detachEmitted = true;
649
- bus.emit(INTERCOM_DETACH_REQUEST_EVENT, { requestId: "chain-detached" });
650
- },
651
- makeMinimalCtx(tempDir),
652
- );
653
-
654
- assert.equal(detachEmitted, true);
655
- assert.match(result.content[0]?.text ?? "", /Chain detached for intercom coordination/);
656
- assert.match(result.content[0]?.text ?? "", /do not resume or launch a replacement/);
657
- assert.equal(bus.emitted.some((entry) => entry.channel === "subagent:result-intercom"), false);
658
- assert.equal(mockPi.callCount(), 1);
659
- });
660
482
 
661
483
  it("resume action rejects a live async child without side effects", async () => {
662
484
  const runId = `resume-live-${Date.now()}`;
@@ -700,6 +522,202 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
700
522
  }
701
523
  });
702
524
 
525
+ it("resume action starts a completed external-job follow-up and dedupes the same message", async () => {
526
+ const sourceRunId = `resume-external-job-${Date.now()}`;
527
+ const sourceAsyncDir = path.join(ASYNC_DIR, sourceRunId);
528
+ const followUpMessage = "What changed after the first answer?";
529
+ const requestDigest = externalJobFollowUpRequestDigest({
530
+ provider: "surf-oracle",
531
+ parentProviderJobId: "job-parent",
532
+ promptDigest: externalJobPromptDigest(followUpMessage),
533
+ options: { tier: "pro" },
534
+ });
535
+ const expectedRunId = externalJobFollowUpRunId(requestDigest);
536
+ const continuationAsyncDir = path.join(ASYNC_DIR, expectedRunId);
537
+ let followUps = 0;
538
+ registerExternalJobProvider({
539
+ name: "surf-oracle",
540
+ start: () => { throw new Error("start must not be called"); },
541
+ followUp: (input) => {
542
+ followUps += 1;
543
+ assert.equal(input.parentProviderJobId, "job-parent");
544
+ assert.equal(input.sourceRunId, sourceRunId);
545
+ assert.equal(input.sourceStepIndex, 0);
546
+ assert.equal(input.requestDigest, requestDigest);
547
+ return { providerJobId: "job-child", state: "completed", conversationUrl: "https://surf.example/c/job-child" };
548
+ },
549
+ status: (providerJobId) => ({ providerJobId, state: "completed" }),
550
+ reattach: (providerJobId) => ({ providerJobId, state: "completed" }),
551
+ result: (providerJobId) => ({ providerJobId, state: "completed", output: "follow-up answer" }),
552
+ });
553
+ try {
554
+ fs.mkdirSync(sourceAsyncDir, { recursive: true });
555
+ fs.writeFileSync(path.join(sourceAsyncDir, "status.json"), JSON.stringify({
556
+ runId: sourceRunId,
557
+ sessionId: "session-123",
558
+ mode: "single",
559
+ state: "complete",
560
+ startedAt: 100,
561
+ lastUpdate: 200,
562
+ cwd: tempDir,
563
+ steps: [{
564
+ agent: "gpt-pro",
565
+ status: "complete",
566
+ runner: { type: "external-job", provider: "surf-oracle", options: { tier: "pro" }, capabilities: { stop: false, steer: false, resume: false, structuredOutput: false, toolEvents: false } },
567
+ externalJob: { provider: "surf-oracle", providerJobId: "job-parent", promptDigest: externalJobPromptDigest("original prompt"), options: { tier: "pro" }, state: "completed" },
568
+ }],
569
+ }, null, 2), "utf-8");
570
+ const { executor } = makeExecutor({ agents: [makeAgent("gpt-pro", { runner: { type: "external-job", provider: "surf-oracle", options: { tier: "pro" } } })] });
571
+
572
+ const first = await executor.execute("resume-external-job-first", { action: "resume", id: sourceRunId, message: followUpMessage }, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
573
+ assert.equal(first.isError, undefined, first.content[0]?.text ?? "follow-up failed");
574
+ assert.equal(first.details?.asyncId, expectedRunId);
575
+
576
+ const duplicate = await executor.execute("resume-external-job-duplicate", { action: "resume", id: sourceRunId, message: followUpMessage }, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
577
+ assert.equal(duplicate.isError, undefined, duplicate.content[0]?.text ?? "duplicate failed");
578
+ assert.equal(duplicate.details?.asyncId, expectedRunId);
579
+ assert.match(duplicate.content[0]?.text ?? "", /already exists/);
580
+
581
+ const resultPath = path.join(RESULTS_DIR, `${expectedRunId}.json`);
582
+ const deadline = Date.now() + 10_000;
583
+ while (!fs.existsSync(resultPath)) {
584
+ if (Date.now() >= deadline) {
585
+ const statusPath = path.join(continuationAsyncDir, "status.json");
586
+ const stderrPath = path.join(continuationAsyncDir, "runner.stderr.log");
587
+ assert.fail(`Timed out waiting for external-job follow-up result; status=${fs.existsSync(statusPath) ? fs.readFileSync(statusPath, "utf-8") : "missing"}; stderr=${fs.existsSync(stderrPath) ? fs.readFileSync(stderrPath, "utf-8") : "missing"}`);
588
+ }
589
+ serviceExternalJobBridgeRequests(continuationAsyncDir);
590
+ await new Promise((resolve) => setTimeout(resolve, 25));
591
+ }
592
+ const status = JSON.parse(fs.readFileSync(path.join(continuationAsyncDir, "status.json"), "utf-8")) as { steps?: Array<{ externalJob?: Record<string, unknown> }> };
593
+ assert.equal(followUps, 1);
594
+ assert.equal(status.steps?.[0]?.externalJob?.operation, "follow-up");
595
+ assert.equal(status.steps?.[0]?.externalJob?.parentProviderJobId, "job-parent");
596
+ assert.equal(status.steps?.[0]?.externalJob?.requestDigest, requestDigest);
597
+ assert.equal(status.steps?.[0]?.externalJob?.providerJobId, "job-child");
598
+ } finally {
599
+ fs.rmSync(sourceAsyncDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
600
+ fs.rmSync(continuationAsyncDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
601
+ fs.rmSync(path.join(RESULTS_DIR, `${expectedRunId}.json`), { force: true });
602
+ }
603
+ });
604
+
605
+ it("resume action starts an indexed external-job follow-up from multi-child async runs", async () => {
606
+ const sourceRunId = `resume-external-job-multi-${Date.now()}`;
607
+ const sourceAsyncDir = path.join(ASYNC_DIR, sourceRunId);
608
+ const followUpMessage = "Continue the selected advisor";
609
+ const requestDigest = externalJobFollowUpRequestDigest({
610
+ provider: "surf-oracle",
611
+ parentProviderJobId: "job-second",
612
+ promptDigest: externalJobPromptDigest(followUpMessage),
613
+ options: { tier: "pro" },
614
+ });
615
+ const expectedRunId = externalJobFollowUpRunId(requestDigest);
616
+ const continuationAsyncDir = path.join(ASYNC_DIR, expectedRunId);
617
+ let selectedSourceStep: number | undefined;
618
+ registerExternalJobProvider({
619
+ name: "surf-oracle",
620
+ start: () => { throw new Error("start must not be called"); },
621
+ followUp: (input) => {
622
+ selectedSourceStep = input.sourceStepIndex;
623
+ assert.equal(input.sourceRunId, sourceRunId);
624
+ assert.equal(input.parentProviderJobId, "job-second");
625
+ return { providerJobId: "job-child", state: "completed" };
626
+ },
627
+ status: (providerJobId) => ({ providerJobId, state: "completed" }),
628
+ reattach: (providerJobId) => ({ providerJobId, state: "completed" }),
629
+ result: (providerJobId) => ({ providerJobId, state: "completed", output: "indexed follow-up answer" }),
630
+ });
631
+ try {
632
+ fs.mkdirSync(sourceAsyncDir, { recursive: true });
633
+ fs.writeFileSync(path.join(sourceAsyncDir, "status.json"), JSON.stringify({
634
+ runId: sourceRunId,
635
+ sessionId: "session-123",
636
+ mode: "parallel",
637
+ state: "complete",
638
+ startedAt: 100,
639
+ lastUpdate: 200,
640
+ cwd: tempDir,
641
+ steps: [{
642
+ agent: "scout",
643
+ status: "complete",
644
+ }, {
645
+ agent: "gpt-pro",
646
+ status: "complete",
647
+ runner: { type: "external-job", provider: "surf-oracle", options: { tier: "pro" }, capabilities: { stop: false, steer: false, resume: false, structuredOutput: false, toolEvents: false } },
648
+ externalJob: { provider: "surf-oracle", providerJobId: "job-second", promptDigest: externalJobPromptDigest("original prompt"), options: { tier: "pro" }, state: "completed" },
649
+ }],
650
+ }, null, 2), "utf-8");
651
+ const { executor } = makeExecutor({ agents: [makeAgent("gpt-pro", { runner: { type: "external-job", provider: "surf-oracle", options: { tier: "pro" } } })] });
652
+
653
+ const first = await executor.execute("resume-external-job-indexed", { action: "resume", id: sourceRunId, index: 1, message: followUpMessage }, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
654
+ assert.equal(first.isError, undefined, first.content[0]?.text ?? "follow-up failed");
655
+ assert.equal(first.details?.asyncId, expectedRunId);
656
+
657
+ const resultPath = path.join(RESULTS_DIR, `${expectedRunId}.json`);
658
+ const deadline = Date.now() + 10_000;
659
+ while (!fs.existsSync(resultPath)) {
660
+ if (Date.now() >= deadline) assert.fail("Timed out waiting for indexed external-job follow-up result");
661
+ serviceExternalJobBridgeRequests(continuationAsyncDir);
662
+ await new Promise((resolve) => setTimeout(resolve, 25));
663
+ }
664
+ const status = JSON.parse(fs.readFileSync(path.join(continuationAsyncDir, "status.json"), "utf-8")) as { steps?: Array<{ externalJob?: Record<string, unknown> }> };
665
+ assert.equal(selectedSourceStep, 1);
666
+ assert.equal(status.steps?.[0]?.externalJob?.sourceStepIndex, 1);
667
+ assert.equal(status.steps?.[0]?.externalJob?.parentProviderJobId, "job-second");
668
+ } finally {
669
+ fs.rmSync(sourceAsyncDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
670
+ fs.rmSync(continuationAsyncDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
671
+ fs.rmSync(path.join(RESULTS_DIR, `${expectedRunId}.json`), { force: true });
672
+ }
673
+ });
674
+
675
+ it("resume action rejects running or unsupported external-job parents without launching", async () => {
676
+ for (const [suffix, provider, stepStatus, providerState, expected] of [
677
+ ["running", { followUp: true }, "running", "running", /still running|Wait for completion/],
678
+ ["unsupported", { followUp: false }, "complete", "completed", /does not support follow-up/],
679
+ ["mismatch", { followUp: true }, "complete", "completed", /mismatched provider options/],
680
+ ] as const) {
681
+ delete (globalThis as Record<PropertyKey, unknown>)[Symbol.for(EXTERNAL_JOB_PROVIDER_REGISTRY_KEY)];
682
+ registerExternalJobProvider({
683
+ name: "surf-oracle",
684
+ start: () => ({ providerJobId: "unused", state: "completed" }),
685
+ ...(provider.followUp ? { followUp: () => ({ providerJobId: "job-child", state: "completed" }) } : {}),
686
+ status: (providerJobId) => ({ providerJobId, state: "completed" }),
687
+ reattach: (providerJobId) => ({ providerJobId, state: "completed" }),
688
+ result: (providerJobId) => ({ providerJobId, state: "completed" }),
689
+ });
690
+ const sourceRunId = `resume-external-job-${suffix}-${Date.now()}`;
691
+ const sourceAsyncDir = path.join(ASYNC_DIR, sourceRunId);
692
+ try {
693
+ fs.mkdirSync(sourceAsyncDir, { recursive: true });
694
+ fs.writeFileSync(path.join(sourceAsyncDir, "status.json"), JSON.stringify({
695
+ runId: sourceRunId,
696
+ sessionId: "session-123",
697
+ mode: "single",
698
+ state: stepStatus === "running" ? "running" : "complete",
699
+ startedAt: 100,
700
+ lastUpdate: 200,
701
+ cwd: tempDir,
702
+ steps: [{
703
+ agent: "gpt-pro",
704
+ status: stepStatus,
705
+ runner: { type: "external-job", provider: "surf-oracle", options: { tier: "pro" }, capabilities: { stop: false, steer: false, resume: false, structuredOutput: false, toolEvents: false } },
706
+ externalJob: { provider: "surf-oracle", providerJobId: "job-parent", promptDigest: externalJobPromptDigest("original prompt"), options: suffix === "mismatch" ? { tier: "old" } : { tier: "pro" }, state: providerState },
707
+ }],
708
+ }, null, 2), "utf-8");
709
+ const { executor, events } = makeExecutor({ agents: [makeAgent("gpt-pro", { runner: { type: "external-job", provider: "surf-oracle", options: { tier: "pro" } } })] });
710
+
711
+ const result = await executor.execute(`resume-external-job-${suffix}`, { action: "resume", id: sourceRunId, message: "Follow up" }, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
712
+ assert.equal(result.isError, true);
713
+ assert.match(result.content[0]?.text ?? "", expected);
714
+ assert.equal(events.emitted.some((entry) => entry.channel === SUBAGENT_ASYNC_STARTED_EVENT), false);
715
+ } finally {
716
+ fs.rmSync(sourceAsyncDir, { recursive: true, force: true });
717
+ }
718
+ }
719
+ });
720
+
703
721
  it("resume action rejects async runs from another or missing parent session", async () => {
704
722
  for (const [suffix, sessionId] of [["other", "another-session"], ["missing", undefined]] as const) {
705
723
  const runId = `resume-${suffix}-session-${Date.now()}`;
@@ -809,6 +827,7 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
809
827
  assert.equal(startedEvent?.goal, "[prompt redacted]");
810
828
  const attachedId = result.details?.asyncId;
811
829
  assert.ok(attachedId, "expected attached chain async id");
830
+ assert.match(attachedId, /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
812
831
  assert.match(result.details?.asyncDir ?? "", new RegExp(`${attachedId}$`));
813
832
  const statusPath = path.join(result.details!.asyncDir!, "status.json");
814
833
  await waitForFile(statusPath);
@@ -878,6 +897,7 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
878
897
  assert.equal(attached.isError, undefined);
879
898
  assert.match(attached.content[0]?.text ?? "", /Attached async subagent/);
880
899
  assert.ok(attached.details?.asyncId, "expected attached chain async id");
900
+ assert.match(attached.details.asyncId, /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
881
901
  await waitForFile(path.join(RESULTS_DIR, `${attached.details.asyncId}.json`));
882
902
  } finally {
883
903
  fs.rmSync(sourceAsyncDir, { recursive: true, force: true });
@@ -921,6 +941,7 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
921
941
 
922
942
  assert.equal(result.isError, undefined);
923
943
  assert.match(result.content[0]?.text ?? "", /Revived async subagent from/);
944
+ assert.match(result.details?.asyncId ?? "", /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
924
945
  assert.match(result.content[0]?.text ?? "", /Agent: b/);
925
946
  assert.match(result.content[0]?.text ?? "", new RegExp(secondSession.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")));
926
947
  const args = await readMockCallArgs(0);
@@ -983,6 +1004,62 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
983
1004
  }
984
1005
  });
985
1006
 
1007
+ it("resume action runs retained children in a managed worktree when requested", async () => {
1008
+ execFileSync("git", ["init"], { cwd: tempDir, stdio: "ignore" });
1009
+ execFileSync("git", ["config", "user.email", "test@example.com"], { cwd: tempDir });
1010
+ execFileSync("git", ["config", "user.name", "Test User"], { cwd: tempDir });
1011
+ fs.writeFileSync(path.join(tempDir, "base.txt"), "base\n", "utf-8");
1012
+ execFileSync("git", ["add", "base.txt"], { cwd: tempDir });
1013
+ execFileSync("git", ["commit", "-m", "base"], { cwd: tempDir, stdio: "ignore" });
1014
+ mockPi.onCall({ output: "revived isolated answer", writeFiles: [{ path: "feature.txt", content: "feature\n" }] });
1015
+ const runId = `resume-worktree-${Date.now()}`;
1016
+ const asyncDir = path.join(ASYNC_DIR, runId);
1017
+ const sessionFile = path.join(homeDir, `${runId}.jsonl`);
1018
+ let revivedId: string | undefined;
1019
+ try {
1020
+ fs.mkdirSync(asyncDir, { recursive: true });
1021
+ fs.writeFileSync(sessionFile, "", "utf-8");
1022
+ fs.writeFileSync(path.join(asyncDir, "status.json"), JSON.stringify({
1023
+ runId,
1024
+ sessionId: "session-123",
1025
+ mode: "single",
1026
+ state: "complete",
1027
+ startedAt: 100,
1028
+ lastUpdate: 200,
1029
+ cwd: tempDir,
1030
+ sessionFile,
1031
+ steps: [{ agent: "worker", status: "complete", sessionFile }],
1032
+ }, null, 2), "utf-8");
1033
+ writeRecoveryDescriptor(asyncDir, runId, "worker", { sessionFile });
1034
+ const { executor } = makeExecutor();
1035
+
1036
+ const result = await executor.execute(
1037
+ "resume-worktree",
1038
+ { action: "resume", id: runId, message: "Continue in isolation.", worktree: true },
1039
+ new AbortController().signal,
1040
+ undefined,
1041
+ makeMinimalCtx(tempDir),
1042
+ );
1043
+
1044
+ assert.equal(result.isError, undefined, result.content[0]?.text ?? "resume failed");
1045
+ revivedId = result.details?.asyncId;
1046
+ assert.ok(revivedId);
1047
+ const resultPath = path.join(RESULTS_DIR, `${revivedId}.json`);
1048
+ await waitForFile(resultPath);
1049
+ const status = await waitForStatus(path.join(ASYNC_DIR, revivedId, "status.json"), (candidate) => candidate.state === "complete");
1050
+ assert.equal(fs.existsSync(path.join(tempDir, "feature.txt")), false);
1051
+ assert.equal(status.parallelHandoff?.changedPatches, 1);
1052
+ const handoff = JSON.parse(fs.readFileSync(status.parallelHandoff!.path!, "utf-8")) as { groups?: Array<{ children?: Array<{ patch?: { changed?: boolean; filesChanged?: number } }> }> };
1053
+ assert.equal(handoff.groups?.[0]?.children?.[0]?.patch?.changed, true);
1054
+ assert.equal(handoff.groups?.[0]?.children?.[0]?.patch?.filesChanged, 1);
1055
+ } finally {
1056
+ fs.rmSync(asyncDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
1057
+ if (revivedId) fs.rmSync(path.join(ASYNC_DIR, revivedId), { recursive: true, force: true, maxRetries: 5, retryDelay: 20 });
1058
+ if (revivedId) fs.rmSync(path.join(RESULTS_DIR, `${revivedId}.json`), { force: true });
1059
+ fs.rmSync(sessionFile, { force: true });
1060
+ }
1061
+ });
1062
+
986
1063
  it("revives a removed agent with its persisted bridge override", async () => {
987
1064
  mockPi.onCall({ output: "descriptor-backed answer" });
988
1065
  const runId = `resume-descriptor-${Date.now()}`;
@@ -1257,60 +1334,7 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
1257
1334
  }
1258
1335
  });
1259
1336
 
1260
- it("resume action revives a completed foreground child by index", async () => {
1261
- mockPi.onCall({ output: "first child done" });
1262
- mockPi.onCall({ output: "second child done" });
1263
- mockPi.onCall({ output: "revived foreground answer" });
1264
- const { executor } = makeExecutor({ bridgeMode: "off", agents: [makeAgent("a"), makeAgent("b", { model: "anthropic/claude-sonnet-4", thinking: "high" })] });
1265
1337
 
1266
- const original = await executor.execute(
1267
- "foreground-resume-original",
1268
- { tasks: [{ agent: "a", task: "task-a" }, { agent: "b", task: "task-b" }] },
1269
- new AbortController().signal,
1270
- undefined,
1271
- makeMinimalCtx(tempDir),
1272
- );
1273
- const runId = original.details?.runId;
1274
- assert.ok(runId, "expected foreground run id");
1275
-
1276
- const overridden = await executor.execute(
1277
- "foreground-resume-model-override",
1278
- { action: "resume", id: runId, index: 1, message: "Follow up with b", model: "openai/gpt-5" },
1279
- new AbortController().signal,
1280
- undefined,
1281
- makeMinimalCtx(tempDir),
1282
- );
1283
- assert.equal(overridden.isError, true);
1284
- assert.match(overridden.content[0]?.text ?? "", /reuses the persisted child model/);
1285
- assert.equal(mockPi.callCount(), 2, "rejected model override must not spawn a revival");
1286
-
1287
- const revived = await executor.execute(
1288
- "foreground-resume",
1289
- { action: "resume", id: runId, index: 1, message: "Follow up with b" },
1290
- new AbortController().signal,
1291
- undefined,
1292
- makeMinimalCtx(tempDir),
1293
- );
1294
-
1295
- assert.equal(revived.isError, undefined);
1296
- assert.match(revived.content[0]?.text ?? "", /Revived foreground subagent from/);
1297
- assert.match(revived.content[0]?.text ?? "", /Agent: b/);
1298
- assert.equal(revived.details?.sourceLaunchContractDigest, original.details?.results?.[1]?.launchContractDigest);
1299
- assert.ok(revived.details?.sourceLaunchContractDigest, "expected foreground source launch contract digest");
1300
- const reviveArgs = await readMockCallArgs(2);
1301
- const selectedSession = original.details?.results?.[1]?.sessionFile;
1302
- assert.ok(selectedSession, "expected selected child session file");
1303
- assert.equal(reviveArgs[reviveArgs.indexOf("--session") + 1], selectedSession);
1304
- assert.equal(reviveArgs[reviveArgs.indexOf("--model") + 1], original.details?.results?.[1]?.model);
1305
- const revivedId = revived.details?.asyncId;
1306
- assert.ok(revivedId, "expected revived async id");
1307
- const resultPath = path.join(RESULTS_DIR, `${revivedId}.json`);
1308
- const deadline = Date.now() + 10_000;
1309
- while (!fs.existsSync(resultPath)) {
1310
- if (Date.now() > deadline) assert.fail(`Timed out waiting for revived result file: ${resultPath}`);
1311
- await new Promise((resolve) => setTimeout(resolve, 50));
1312
- }
1313
- });
1314
1338
 
1315
1339
  it("applies the same exclusive lease to remembered foreground revival", async () => {
1316
1340
  const releasePath = path.join(tempDir, "release-foreground-revival");
@@ -1578,121 +1602,9 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
1578
1602
  assert.match(status.content[0]?.text ?? "", /error: Acceptance rejected/);
1579
1603
  });
1580
1604
 
1581
- it("status recovers remembered detached chain output after child exit", async () => {
1582
- mockPi.onCall({
1583
- steps: [
1584
- { jsonl: [events.toolStart("contact_supervisor", { reason: "need_decision", message: "Need a decision" })] },
1585
- { delay: 50, jsonl: [events.assistantMessage("chain recovered answer")] },
1586
- ],
1587
- });
1588
- const { executor, events: bus } = makeExecutor({ agents: [makeAgent("a", { systemPrompt: "Intercom orchestration channel:" }), makeAgent("b")] });
1589
- let detachEmitted = false;
1590
- const original = await executor.execute(
1591
- "foreground-detached-chain-status-original",
1592
- { chain: [{ agent: "a", task: "ask supervisor" }, { agent: "b", task: "must not run" }] },
1593
- new AbortController().signal,
1594
- (update: { details?: { progress?: Array<{ currentTool?: string }> } }) => {
1595
- if (detachEmitted) return;
1596
- if (!update.details?.progress?.some((entry) => entry.currentTool === "contact_supervisor")) return;
1597
- detachEmitted = true;
1598
- bus.emit(INTERCOM_DETACH_REQUEST_EVENT, { requestId: "chain-detached-status" });
1599
- },
1600
- makeMinimalCtx(tempDir),
1601
- );
1602
- assert.equal(detachEmitted, true);
1603
- const runId = original.details?.runId;
1604
- assert.ok(runId, "expected foreground run id");
1605
- assert.match(original.content[0]?.text ?? "", /Chain detached for intercom coordination/);
1606
- assert.equal(mockPi.callCount(), 1);
1607
-
1608
- const deadline = Date.now() + 5000;
1609
- let statusText = "";
1610
- while (Date.now() < deadline) {
1611
- const status = await executor.execute(
1612
- "foreground-detached-chain-status",
1613
- { action: "status", id: runId },
1614
- new AbortController().signal,
1615
- undefined,
1616
- makeMinimalCtx(tempDir),
1617
- );
1618
- statusText = status.content[0]?.text ?? "";
1619
- if (/chain recovered answer/.test(statusText)) break;
1620
- await new Promise((resolve) => setTimeout(resolve, 25));
1621
- }
1622
-
1623
- assert.doesNotMatch(statusText, /Async run not found/);
1624
- assert.match(statusText, /State: remembered foreground/);
1625
- assert.match(statusText, /a completed/);
1626
- assert.match(statusText, /chain recovered answer/);
1627
-
1628
- const transcript = await executor.execute(
1629
- "foreground-detached-chain-transcript",
1630
- { action: "status", id: runId, index: 0, view: "transcript" },
1631
- new AbortController().signal,
1632
- undefined,
1633
- makeMinimalCtx(tempDir),
1634
- );
1635
- assert.match(transcript.content[0]?.text ?? "", /chain recovered answer/);
1636
- });
1637
-
1638
- it("status recovers a later detached serial chain child under its original index", async () => {
1639
- mockPi.onCall({ output: "first step done" });
1640
- mockPi.onCall({
1641
- steps: [
1642
- { jsonl: [events.toolStart("contact_supervisor", { reason: "need_decision", message: "Need a decision" })] },
1643
- { delay: 200, jsonl: [events.assistantMessage("second recovered answer")] },
1644
- ],
1645
- });
1646
- const { executor, events: bus } = makeExecutor({ agents: [makeAgent("a"), makeAgent("b", { systemPrompt: "Intercom orchestration channel:" }), makeAgent("c")] });
1647
- let detachEmitted = false;
1648
- const original = await executor.execute(
1649
- "foreground-later-detached-chain-status-original",
1650
- { chain: [{ agent: "a", task: "first" }, { agent: "b", task: "ask supervisor" }, { agent: "c", task: "must not run" }] },
1651
- new AbortController().signal,
1652
- (update: { details?: { progress?: Array<{ currentTool?: string }> } }) => {
1653
- if (detachEmitted) return;
1654
- if (!update.details?.progress?.some((entry) => entry.currentTool === "contact_supervisor")) return;
1655
- detachEmitted = true;
1656
- bus.emit(INTERCOM_DETACH_REQUEST_EVENT, { requestId: "later-chain-detached-status" });
1657
- },
1658
- makeMinimalCtx(tempDir),
1659
- );
1660
- assert.equal(detachEmitted, true);
1661
- const runId = original.details?.runId;
1662
- assert.ok(runId, "expected foreground run id");
1663
- assert.match(original.content[0]?.text ?? "", /Chain detached for intercom coordination/);
1664
- assert.equal(mockPi.callCount(), 2);
1665
1605
 
1666
- const deadline = Date.now() + 5000;
1667
- let statusText = "";
1668
- while (Date.now() < deadline) {
1669
- const status = await executor.execute(
1670
- "foreground-later-detached-chain-status",
1671
- { action: "status", id: runId },
1672
- new AbortController().signal,
1673
- undefined,
1674
- makeMinimalCtx(tempDir),
1675
- );
1676
- statusText = status.content[0]?.text ?? "";
1677
- if (/second recovered answer/.test(statusText)) break;
1678
- await new Promise((resolve) => setTimeout(resolve, 25));
1679
- }
1680
1606
 
1681
- assert.doesNotMatch(statusText, /Async run not found/);
1682
- assert.match(statusText, /State: remembered foreground/);
1683
- assert.match(statusText, /a completed/);
1684
- assert.match(statusText, /b completed/);
1685
- assert.match(statusText, /second recovered answer/);
1686
1607
 
1687
- const transcript = await executor.execute(
1688
- "foreground-later-detached-chain-transcript",
1689
- { action: "status", id: runId, index: 1, view: "transcript" },
1690
- new AbortController().signal,
1691
- undefined,
1692
- makeMinimalCtx(tempDir),
1693
- );
1694
- assert.match(transcript.content[0]?.text ?? "", /second recovered answer/);
1695
- });
1696
1608
 
1697
1609
  it("blocks sibling resume while any remembered foreground child remains detached", async () => {
1698
1610
  const { executor, state } = makeExecutor({ bridgeMode: "off", agents: [makeAgent("a"), makeAgent("b")] });
@@ -2010,29 +1922,7 @@ describe("intercom result delivery cutover", { skip: !available ? "executor not
2010
1922
  }
2011
1923
  });
2012
1924
 
2013
- it("mixed foreground outcomes produce failed grouped status and receipt counts", async () => {
2014
- mockPi.onCall({ matchArgIncludes: "task-a", output: "Parallel child success", exitCode: 0 });
2015
- mockPi.onCall({ matchArgIncludes: "task-b", output: "Parallel child failure", stderr: "Parallel child failure", exitCode: 1 });
2016
- const { executor, events } = makeExecutor({ resultDelivery: true, agents: [makeAgent("a"), makeAgent("b")] });
2017
1925
 
2018
- const result = await executor.execute(
2019
- "parallel-mixed-intercom",
2020
- { tasks: [{ agent: "a", task: "task-a" }, { agent: "b", task: "task-b" }] },
2021
- new AbortController().signal,
2022
- undefined,
2023
- makeMinimalCtx(tempDir),
2024
- );
2025
-
2026
- const intercomEvents = events.emitted.filter((entry) => entry.channel === "subagent:result-intercom");
2027
- assert.equal(intercomEvents.length, 1);
2028
- const payload = intercomEvents[0]!.payload as { status?: string; summary?: string; message?: string };
2029
- assert.equal(payload.status, "failed");
2030
- assert.match(String(payload.summary ?? ""), /1 completed, 1 failed/);
2031
- assert.match(String(payload.message ?? ""), /Process status: failed/);
2032
- assert.match(String(payload.message ?? ""), /Outputs: 2 present \(semantic adequacy unassessed\)/);
2033
- assert.match(String(payload.message ?? ""), /Inspect that output before retrying/);
2034
- assert.match(result.content[0]?.text ?? "", /Children: 1 completed, 1 failed/);
2035
- });
2036
1926
 
2037
1927
  it("does not treat a synthetic foreground startup error as child output", async () => {
2038
1928
  mockPi.onCall({ output: "", stderr: "mock startup failure", exitCode: 1 });