@selesai/code 0.5.20 → 0.5.21

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 (263) hide show
  1. package/dist/extensions/handoff-new.test.ts +8 -9
  2. package/dist/extensions/handoff-new.ts +6 -8
  3. package/dist/extensions/pi-subagents/CHANGELOG.md +1367 -0
  4. package/dist/extensions/pi-subagents/README.md +602 -220
  5. package/dist/extensions/pi-subagents/banner.png +0 -0
  6. package/dist/extensions/pi-subagents/index.ts +1 -0
  7. package/dist/extensions/pi-subagents/install.mjs +3 -3
  8. package/dist/extensions/pi-subagents/package-lock.json +3405 -0
  9. package/dist/extensions/pi-subagents/package.json +26 -14
  10. package/dist/extensions/pi-subagents/prompts/gather-context-and-clarify.md +1 -1
  11. package/dist/extensions/pi-subagents/prompts/parallel-cleanup.md +9 -9
  12. package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +3 -3
  13. package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +7 -7
  14. package/dist/extensions/pi-subagents/prompts/parallel-research.md +6 -6
  15. package/dist/extensions/pi-subagents/prompts/parallel-review.md +8 -8
  16. package/dist/extensions/pi-subagents/prompts/review-loop.md +13 -11
  17. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +267 -176
  18. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +89 -16
  19. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +19 -0
  20. package/dist/extensions/pi-subagents/src/agents/agents.ts +218 -120
  21. package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +67 -13
  22. package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +2 -2
  23. package/dist/extensions/pi-subagents/src/agents/skills.ts +25 -12
  24. package/dist/extensions/pi-subagents/src/api/background-work.ts +197 -0
  25. package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +17 -0
  26. package/dist/extensions/pi-subagents/src/api/delegation.ts +285 -0
  27. package/dist/extensions/pi-subagents/src/api/preflight.ts +399 -0
  28. package/dist/extensions/pi-subagents/src/extension/chain-validation.ts +165 -0
  29. package/dist/extensions/pi-subagents/src/extension/config.ts +7 -1
  30. package/dist/extensions/pi-subagents/src/extension/doctor.ts +15 -0
  31. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +3 -1
  32. package/dist/extensions/pi-subagents/src/extension/index.ts +113 -157
  33. package/dist/extensions/pi-subagents/src/extension/rpc.ts +41 -4
  34. package/dist/extensions/pi-subagents/src/extension/schemas.ts +45 -15
  35. package/dist/extensions/pi-subagents/src/extension/steering-notices.ts +35 -0
  36. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +28 -15
  37. package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +4 -3
  38. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +225 -29
  39. package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +11 -0
  40. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +8 -10
  41. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +452 -62
  42. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +60 -9
  43. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +198 -52
  44. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +119 -21
  45. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +67 -0
  46. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +2 -0
  47. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +16 -8
  48. package/dist/extensions/pi-subagents/src/runs/background/completion-batcher.ts +6 -4
  49. package/dist/extensions/pi-subagents/src/runs/background/completion-dedupe.ts +2 -11
  50. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +260 -13
  51. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +32 -6
  52. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +171 -90
  53. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +280 -0
  54. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +149 -88
  55. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +14 -2
  56. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +33 -17
  57. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +9 -1
  58. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +38 -10
  59. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +237 -0
  60. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +1297 -307
  61. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +610 -0
  62. package/dist/extensions/pi-subagents/src/runs/background/top-level-async.ts +2 -1
  63. package/dist/extensions/pi-subagents/src/runs/background/wait-config.ts +36 -0
  64. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +26 -0
  65. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +230 -0
  66. package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +22 -6
  67. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +228 -140
  68. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +452 -138
  69. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +90 -0
  70. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1001 -416
  71. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +443 -132
  72. package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +38 -0
  73. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +178 -0
  74. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +121 -0
  75. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +41 -93
  76. package/dist/extensions/pi-subagents/src/runs/shared/context-mode.ts +44 -0
  77. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +11 -9
  78. package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +4 -0
  79. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +12 -6
  80. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +36 -0
  81. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +44 -7
  82. package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +4 -1
  83. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +154 -0
  84. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +18 -0
  85. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +174 -54
  86. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +38 -31
  87. package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +90 -5
  88. package/dist/extensions/pi-subagents/src/runs/shared/session-lease.ts +299 -0
  89. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +61 -6
  90. package/dist/extensions/pi-subagents/src/runs/shared/spawn-budget.ts +128 -0
  91. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +112 -7
  92. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +14 -6
  93. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +149 -36
  94. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +181 -0
  95. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +83 -0
  96. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +11 -5
  97. package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +50 -4
  98. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +63 -14
  99. package/dist/extensions/pi-subagents/src/shared/accessible-dir.ts +25 -0
  100. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +37 -7
  101. package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +18 -43
  102. package/dist/extensions/pi-subagents/src/shared/child-transcript.ts +52 -0
  103. package/dist/extensions/pi-subagents/src/shared/env.ts +16 -0
  104. package/dist/extensions/pi-subagents/src/shared/file-system-retry.ts +47 -0
  105. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +28 -3
  106. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +123 -0
  107. package/dist/extensions/pi-subagents/src/shared/model-info.ts +8 -5
  108. package/dist/extensions/pi-subagents/src/shared/settings.ts +9 -1
  109. package/dist/extensions/pi-subagents/src/shared/status-format.ts +7 -1
  110. package/dist/extensions/pi-subagents/src/shared/types.ts +522 -51
  111. package/dist/extensions/pi-subagents/src/shared/utils.ts +59 -53
  112. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +604 -0
  113. package/dist/extensions/pi-subagents/src/slash/delegation-json.ts +108 -0
  114. package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +249 -0
  115. package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +353 -345
  116. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +2 -2
  117. package/dist/extensions/pi-subagents/src/slash/selector.ts +147 -0
  118. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +265 -23
  119. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +2 -2
  120. package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +428 -0
  121. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +362 -0
  122. package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +472 -0
  123. package/dist/extensions/pi-subagents/src/tui/fleet.ts +664 -0
  124. package/dist/extensions/pi-subagents/src/tui/render.ts +115 -31
  125. package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +220 -0
  126. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +205 -0
  127. package/dist/extensions/pi-subagents/src/watchdog/emission-guard.ts +123 -0
  128. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +532 -0
  129. package/dist/extensions/pi-subagents/src/watchdog/model-selection.ts +167 -0
  130. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +117 -0
  131. package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +433 -0
  132. package/dist/extensions/pi-subagents/src/watchdog/render.ts +54 -0
  133. package/dist/extensions/pi-subagents/src/watchdog/review.ts +298 -0
  134. package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +714 -0
  135. package/dist/extensions/pi-subagents/src/watchdog/settings.ts +528 -0
  136. package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +155 -0
  137. package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +161 -0
  138. package/dist/extensions/pi-subagents/src/watchdog/types.ts +188 -0
  139. package/dist/extensions/pi-subagents/src/watchdog/warning-format.ts +73 -0
  140. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +130 -2
  141. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +439 -0
  142. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1632 -61
  143. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +54 -1
  144. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +112 -0
  145. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +98 -1
  146. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +179 -9
  147. package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +16 -9
  148. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +6 -5
  149. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +589 -9
  150. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +528 -21
  151. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +227 -3
  152. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +235 -7
  153. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +27 -0
  154. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +172 -2
  155. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1502 -18
  156. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +993 -4
  157. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +27 -0
  158. package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +7 -1
  159. package/dist/extensions/pi-subagents/test/support/helpers.ts +32 -0
  160. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +59 -2
  161. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +32 -6
  162. package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +25 -24
  163. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +59 -35
  164. package/dist/extensions/pi-subagents/test/support/session-lease-child.mjs +42 -0
  165. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +703 -69
  166. package/dist/extensions/pi-subagents/test/unit/accessible-dir.test.ts +82 -0
  167. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +15 -15
  168. package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +66 -66
  169. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +478 -19
  170. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +228 -7
  171. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +1 -1
  172. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +198 -78
  173. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +15 -1
  174. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +102 -7
  175. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +439 -6
  176. package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +41 -1
  177. package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +79 -0
  178. package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +285 -0
  179. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +84 -0
  180. package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +68 -0
  181. package/dist/extensions/pi-subagents/test/unit/chain-validation.test.ts +326 -0
  182. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +82 -0
  183. package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +46 -4
  184. package/dist/extensions/pi-subagents/test/unit/completion-batcher.test.ts +3 -1
  185. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +9 -17
  186. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +175 -3
  187. package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +10 -5
  188. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +126 -6
  189. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +219 -0
  190. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +913 -0
  191. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +13 -2
  192. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +3 -3
  193. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +351 -0
  194. package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +280 -0
  195. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +575 -0
  196. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +65 -0
  197. package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +94 -1
  198. package/dist/extensions/pi-subagents/test/unit/get-final-output.test.ts +23 -0
  199. package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +157 -0
  200. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +367 -5
  201. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +11 -0
  202. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +36 -0
  203. package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +25 -3
  204. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +1 -1
  205. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +341 -10
  206. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +16 -0
  207. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +52 -0
  208. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +168 -7
  209. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +85 -7
  210. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +175 -0
  211. package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +1 -1
  212. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +243 -16
  213. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +79 -36
  214. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +174 -56
  215. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +322 -0
  216. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +204 -0
  217. package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +20 -12
  218. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +117 -4
  219. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +40 -7
  220. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +48 -1
  221. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +21 -3
  222. package/dist/extensions/pi-subagents/test/unit/selector.test.ts +57 -0
  223. package/dist/extensions/pi-subagents/test/unit/session-lease.test.ts +326 -0
  224. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +101 -2
  225. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +111 -1
  226. package/dist/extensions/pi-subagents/test/unit/spawn-budget.test.ts +124 -0
  227. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +6 -4
  228. package/dist/extensions/pi-subagents/test/unit/status-format.test.ts +7 -0
  229. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +397 -0
  230. package/dist/extensions/pi-subagents/test/unit/steering-notices.test.ts +58 -0
  231. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +173 -0
  232. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +25 -4
  233. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +390 -25
  234. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +837 -0
  235. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +86 -0
  236. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +15 -0
  237. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +47 -1
  238. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +56 -10
  239. package/dist/extensions/pi-subagents/test/unit/watchdog-change-signature.test.ts +387 -0
  240. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +110 -0
  241. package/dist/extensions/pi-subagents/test/unit/watchdog-emission-guard.test.ts +62 -0
  242. package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +144 -0
  243. package/dist/extensions/pi-subagents/test/unit/watchdog-model-selection.test.ts +121 -0
  244. package/dist/extensions/pi-subagents/test/unit/watchdog-render.test.ts +76 -0
  245. package/dist/extensions/pi-subagents/test/unit/watchdog-review.test.ts +327 -0
  246. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +863 -0
  247. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +290 -0
  248. package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +91 -0
  249. package/dist/extensions/pi-subagents/test/unit/watchdog-turn-delta.test.ts +130 -0
  250. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +32 -4
  251. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +5 -1
  252. package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +30 -0
  253. package/dist/extensions/question/batch.ts +39 -0
  254. package/dist/extensions/question/dialog-adapter.ts +23 -1
  255. package/dist/extensions/question/index.ts +237 -7
  256. package/dist/extensions/question/schemas.ts +28 -15
  257. package/dist/extensions/question/tests/batch.test.ts +26 -0
  258. package/dist/extensions/question/tests/ui-protocol.test.ts +23 -3
  259. package/dist/extensions/question/tui-adapter.ts +2 -3
  260. package/dist/extensions/question/types.ts +37 -0
  261. package/dist/extensions/question/ui-protocol.ts +3 -3
  262. package/dist/skills/batch-grill-me/SKILL.md +3 -1
  263. package/package.json +1 -1
@@ -0,0 +1,285 @@
1
+ export const SUBAGENT_DELEGATION_PROTOCOL_VERSION = 1 as const;
2
+ export const SUBAGENT_DELEGATION_V2_PROTOCOL_VERSION = 2 as const;
3
+
4
+ // This is the established extension-to-extension transport. The public API
5
+ // intentionally reuses it instead of adding a second event protocol.
6
+ export const SUBAGENT_DELEGATION_REQUEST_EVENT = "prompt-template:subagent:request";
7
+ export const SUBAGENT_DELEGATION_STARTED_EVENT = "prompt-template:subagent:started";
8
+ export const SUBAGENT_DELEGATION_UPDATE_EVENT = "prompt-template:subagent:update";
9
+ export const SUBAGENT_DELEGATION_RESPONSE_EVENT = "prompt-template:subagent:response";
10
+ export const SUBAGENT_DELEGATION_CANCEL_EVENT = "prompt-template:subagent:cancel";
11
+
12
+ export interface SubagentDelegationTurnBudget {
13
+ maxTurns: number;
14
+ graceTurns?: number;
15
+ }
16
+
17
+ export interface SubagentDelegationToolBudget {
18
+ soft?: number;
19
+ hard: number;
20
+ block?: string[] | "*";
21
+ }
22
+
23
+ export interface SubagentDelegationAgentContract {
24
+ version: 1;
25
+ }
26
+
27
+ export type SubagentDelegationJsonSchemaObject = Record<string, unknown>;
28
+
29
+ export interface SubagentDelegationExecutionResult {
30
+ status: "completed" | "failed" | "paused" | "stopped" | "detached";
31
+ success: boolean;
32
+ exitCode: number;
33
+ error?: string;
34
+ interrupted?: boolean;
35
+ timedOut?: boolean;
36
+ stopped?: boolean;
37
+ detached?: boolean;
38
+ }
39
+
40
+ export interface SubagentDelegationReviewResult {
41
+ status: "not-requested" | "review-required" | "reviewed" | "blockers";
42
+ findings?: Array<{ severity: "blocker" | "non-blocking"; file?: string; issue: string; rationale: string }>;
43
+ }
44
+
45
+ export interface SubagentDelegationEffectsResult {
46
+ fileMutation?: {
47
+ status: "not-requested" | "not-applicable" | "observed" | "missing";
48
+ expected: boolean;
49
+ attempted: boolean;
50
+ message?: string;
51
+ };
52
+ }
53
+
54
+ export type SubagentDelegationAcceptanceEvidence =
55
+ | "changed-files"
56
+ | "tests-added"
57
+ | "commands-run"
58
+ | "validation-output"
59
+ | "residual-risks"
60
+ | "no-staged-files"
61
+ | "diff-summary"
62
+ | "review-findings"
63
+ | "manual-notes";
64
+
65
+ export interface SubagentDelegationAcceptanceCriterion {
66
+ id: string;
67
+ must: string;
68
+ evidence?: SubagentDelegationAcceptanceEvidence[];
69
+ severity?: "required" | "recommended";
70
+ }
71
+
72
+ export interface SubagentDelegationAcceptanceVerifyCommand {
73
+ id: string;
74
+ command: string;
75
+ timeoutMs?: number;
76
+ cwd?: string;
77
+ env?: Record<string, string>;
78
+ allowFailure?: boolean;
79
+ }
80
+
81
+ export interface SubagentDelegationAcceptanceReview {
82
+ agent?: string;
83
+ focus?: string;
84
+ required?: boolean;
85
+ }
86
+
87
+ interface SubagentDelegationAcceptanceFields {
88
+ criteria?: Array<string | SubagentDelegationAcceptanceCriterion>;
89
+ evidence?: SubagentDelegationAcceptanceEvidence[];
90
+ verify?: SubagentDelegationAcceptanceVerifyCommand[];
91
+ review?: SubagentDelegationAcceptanceReview | false;
92
+ stopRules?: string[];
93
+ }
94
+
95
+ export type SubagentDelegationAcceptanceConfig = SubagentDelegationAcceptanceFields & (
96
+ | { level: "none"; reason: string }
97
+ | { level?: "auto" | "attested" | "checked" | "verified"; reason?: string }
98
+ );
99
+
100
+ export type SubagentDelegationAcceptance =
101
+ | "auto"
102
+ | "attested"
103
+ | "checked"
104
+ | "verified"
105
+ | false
106
+ | SubagentDelegationAcceptanceConfig;
107
+
108
+ export interface SubagentDelegationRequest {
109
+ version: typeof SUBAGENT_DELEGATION_PROTOCOL_VERSION;
110
+ requestId: string;
111
+ agent: string;
112
+ task: string;
113
+ context: "fresh" | "fork";
114
+ cwd: string;
115
+ model?: string;
116
+ timeoutMs?: number;
117
+ turnBudget?: SubagentDelegationTurnBudget;
118
+ toolBudget?: SubagentDelegationToolBudget;
119
+ skill?: string | string[] | boolean;
120
+ output?: string | boolean;
121
+ outputMode?: "inline" | "file-only";
122
+ outputSchema?: SubagentDelegationJsonSchemaObject;
123
+ agentContract?: SubagentDelegationAgentContract;
124
+ acceptance?: SubagentDelegationAcceptance;
125
+ artifacts?: boolean;
126
+ }
127
+
128
+ export interface SubagentDelegationStarted {
129
+ version: typeof SUBAGENT_DELEGATION_PROTOCOL_VERSION;
130
+ requestId: string;
131
+ }
132
+
133
+ export interface SubagentDelegationUpdate extends SubagentDelegationStarted {
134
+ currentTool?: string;
135
+ currentToolArgs?: string;
136
+ recentOutput?: string;
137
+ recentOutputLines?: string[];
138
+ recentTools?: Array<{ tool: string; args: string }>;
139
+ model?: string;
140
+ toolCount?: number;
141
+ durationMs?: number;
142
+ tokens?: number;
143
+ }
144
+
145
+ export type SubagentDelegationStatus =
146
+ | "completed"
147
+ | "failed"
148
+ | "timed_out"
149
+ | "cancelled"
150
+ | "interrupted"
151
+ | "turn_budget_exhausted"
152
+ | "tool_budget_exhausted"
153
+ | "structured_output_failed"
154
+ | "acceptance_failed"
155
+ | "invalid_request"
156
+ | "unavailable_context";
157
+
158
+ export type SubagentDelegationAcceptanceStatus =
159
+ | "pending"
160
+ | "not-required"
161
+ | "claimed"
162
+ | "attested"
163
+ | "checked"
164
+ | "verified"
165
+ | "review-required"
166
+ | "reviewed"
167
+ | "accepted"
168
+ | "rejected";
169
+
170
+ export interface SubagentDelegationAcceptanceResult {
171
+ status: SubagentDelegationAcceptanceStatus;
172
+ evidenceStatus: Exclude<SubagentDelegationAcceptanceStatus, "review-required" | "reviewed" | "accepted">;
173
+ explicit: boolean;
174
+ }
175
+
176
+ export interface SubagentDelegationResponse extends SubagentDelegationStarted {
177
+ status: SubagentDelegationStatus;
178
+ error?: string;
179
+ runId?: string;
180
+ childIndex?: number;
181
+ agent?: string;
182
+ model?: string;
183
+ exitCode?: number;
184
+ execution?: SubagentDelegationExecutionResult;
185
+ output?: string;
186
+ outputPath?: string;
187
+ sessionFile?: string;
188
+ acceptance?: SubagentDelegationAcceptanceResult;
189
+ review?: SubagentDelegationReviewResult;
190
+ effects?: SubagentDelegationEffectsResult;
191
+ turns?: number;
192
+ toolCount?: number;
193
+ durationMs?: number;
194
+ tokens?: number;
195
+ warnings?: string[];
196
+ }
197
+
198
+ export interface SubagentDelegationCancel extends SubagentDelegationStarted {}
199
+
200
+ export type SubagentDelegationV2Thinking = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
201
+
202
+ export type SubagentDelegationV2ResultRequest =
203
+ | { kind: "text" }
204
+ | { kind: "structured"; schema: SubagentDelegationJsonSchemaObject };
205
+
206
+ export interface SubagentDelegationV2Request {
207
+ version: typeof SUBAGENT_DELEGATION_V2_PROTOCOL_VERSION;
208
+ requestId: string;
209
+ ownerRunId: string;
210
+ nodeId: string;
211
+ agent: string;
212
+ task: string;
213
+ context: "fresh" | "fork";
214
+ cwd: string;
215
+ model?: string;
216
+ thinking?: SubagentDelegationV2Thinking;
217
+ timeoutMs?: number;
218
+ turnBudget?: SubagentDelegationTurnBudget;
219
+ toolBudget?: SubagentDelegationToolBudget;
220
+ skill?: string | string[] | boolean;
221
+ artifacts?: boolean;
222
+ result: SubagentDelegationV2ResultRequest;
223
+ }
224
+
225
+ export interface SubagentDelegationV2Started {
226
+ version: typeof SUBAGENT_DELEGATION_V2_PROTOCOL_VERSION;
227
+ requestId: string;
228
+ ownerRunId: string;
229
+ nodeId: string;
230
+ }
231
+
232
+ export interface SubagentDelegationV2Update extends SubagentDelegationV2Started {
233
+ currentTool?: string;
234
+ currentToolArgs?: string;
235
+ recentOutput?: string;
236
+ recentOutputLines?: string[];
237
+ recentTools?: Array<{ tool: string; args: string }>;
238
+ model?: string;
239
+ toolCount?: number;
240
+ durationMs?: number;
241
+ tokens?: number;
242
+ }
243
+
244
+ export type SubagentDelegationV2Status = SubagentDelegationStatus | "duplicate_node";
245
+
246
+ export type SubagentDelegationV2Value =
247
+ | { kind: "text"; text: string }
248
+ | { kind: "structured"; value: unknown };
249
+
250
+ export interface SubagentDelegationV2Usage {
251
+ input: number;
252
+ output: number;
253
+ cacheRead: number;
254
+ cacheWrite: number;
255
+ cost: number;
256
+ turns: number;
257
+ toolCalls: number;
258
+ durationMs: number;
259
+ }
260
+
261
+ export interface SubagentDelegationV2TerminalResponse extends SubagentDelegationV2Started {
262
+ status: Exclude<SubagentDelegationV2Status, "invalid_request">;
263
+ error?: string;
264
+ runId?: string;
265
+ agent?: string;
266
+ model?: string;
267
+ thinking?: string;
268
+ exitCode?: number;
269
+ result?: SubagentDelegationV2Value;
270
+ usage?: SubagentDelegationV2Usage;
271
+ }
272
+
273
+ /** A malformed V2 request can only be correlated by the valid identity fields it supplied. */
274
+ export interface SubagentDelegationV2InvalidResponse {
275
+ version: typeof SUBAGENT_DELEGATION_V2_PROTOCOL_VERSION;
276
+ requestId: string;
277
+ ownerRunId?: string;
278
+ nodeId?: string;
279
+ status: "invalid_request";
280
+ error?: string;
281
+ }
282
+
283
+ export type SubagentDelegationV2Response = SubagentDelegationV2TerminalResponse | SubagentDelegationV2InvalidResponse;
284
+
285
+ export interface SubagentDelegationV2Cancel extends SubagentDelegationV2Started {}
@@ -0,0 +1,399 @@
1
+ import { createHash } from "node:crypto";
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { discoverAgents, discoverAgentsAll, type AgentConfig, type AgentScope, type AgentSource } from "../agents/agents.ts";
6
+ import { resolveExecutionAgentScope } from "../agents/agent-scope.ts";
7
+ import { buildSkillInjection, normalizeSkillInput, resolveSkillsWithFallback } from "../agents/skills.ts";
8
+ import { buildAgentMemoryInjection } from "../agents/agent-memory.ts";
9
+ import { buildModelCandidates, resolveEffectiveSubagentModel, type AvailableModelInfo, type ParentModel } from "../runs/shared/model-fallback.ts";
10
+ import { applyThinkingSuffix, resolvePiLaunchToolPlan, type PiLaunchToolPlan } from "../runs/shared/pi-args.ts";
11
+ import { injectOutputPathSystemPrompt, normalizeSingleOutputOverride, resolveSingleOutputPath } from "../runs/shared/single-output.ts";
12
+ import { getArtifactPaths, getArtifactsDir } from "../shared/artifacts.ts";
13
+ import { resolveEffectiveThinking } from "../shared/model-info.ts";
14
+ import { SUBAGENT_LIFECYCLE_ARTIFACT_VERSION, type ArtifactDirPreference, type ArtifactPaths, type JsonSchemaObject, type OutputMode } from "../shared/types.ts";
15
+ import type { ResolvedSubagentCapabilityCeiling, SubagentCapabilityAudit } from "../runs/shared/capability-ceiling.ts";
16
+ import { appendTurnBudgetSystemPrompt } from "../runs/shared/turn-budget.ts";
17
+ import type { ResolvedTurnBudget } from "../shared/types.ts";
18
+ import type { ResolvedMcpDirectToolSelection } from "../runs/shared/mcp-direct-tool-allowlist.ts";
19
+ import { resolveStepBehavior } from "../shared/settings.ts";
20
+ import { agentDefinitionDigest, AGENT_DEFINITION_PROJECTION_VERSION, launchBindingDigest } from "../shared/launch-contract.ts";
21
+ import { ASYNC_DIR, RESULTS_DIR, TEMP_ROOT_DIR } from "../shared/types.ts";
22
+ import { processTerminalCandidatePath, processTerminalPath } from "../runs/background/process-terminal.ts";
23
+ import { nestedResultsPath } from "../runs/shared/nested-events.ts";
24
+
25
+ export const SUBAGENT_LAUNCH_CONTRACT_VERSION = 2 as const;
26
+
27
+ export type SubagentLaunchContractReasonCode =
28
+ | "missing_agent"
29
+ | "ambiguous_agent"
30
+ | "missing_skill"
31
+ | "denied_required_tool"
32
+ | "invalid_artifact_dir"
33
+ | "invalid_cwd"
34
+ | "unsupported_mode";
35
+
36
+ export interface SubagentLaunchContractDiagnostic {
37
+ code: SubagentLaunchContractReasonCode | "host_required" | "snapshot_warning";
38
+ severity: "error" | "warning" | "host-required";
39
+ message: string;
40
+ }
41
+
42
+ export interface SubagentLaunchContractInput {
43
+ agent: string;
44
+ cwd: string;
45
+ task?: string;
46
+ agentScope?: AgentScope;
47
+ context?: "fresh" | "fork";
48
+ model?: string;
49
+ thinking?: string | false;
50
+ parentModel?: ParentModel;
51
+ availableModels?: ReadonlyArray<AvailableModelInfo | { provider: string; id: string; fullId?: string; reasoning?: boolean }>;
52
+ preferredProvider?: string;
53
+ skill?: string | string[] | boolean;
54
+ output?: string | boolean;
55
+ outputMode?: OutputMode;
56
+ outputSchema?: JsonSchemaObject;
57
+ turnBudget?: ResolvedTurnBudget;
58
+ artifacts?: boolean;
59
+ artifactDir?: ArtifactDirPreference;
60
+ parentSessionFile?: string | null;
61
+ sessionRoot?: string;
62
+ sessionDir?: string;
63
+ runId?: string;
64
+ /** Root run id supplied by a host when projecting nested async lifecycle paths. */
65
+ nestedRootRunId?: string;
66
+ capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
67
+ inheritedCapabilityCeiling?: ResolvedSubagentCapabilityCeiling;
68
+ }
69
+
70
+ export interface SubagentLaunchContractAgentCandidate {
71
+ name: string;
72
+ localName?: string;
73
+ packageName?: string;
74
+ source: AgentSource;
75
+ filePath: string;
76
+ disabled?: boolean;
77
+ selected: boolean;
78
+ }
79
+
80
+ export interface SubagentLaunchContractAgent {
81
+ name: string;
82
+ localName?: string;
83
+ packageName?: string;
84
+ source: AgentSource;
85
+ filePath: string;
86
+ definitionProjectionVersion: typeof AGENT_DEFINITION_PROJECTION_VERSION;
87
+ definitionDigest: string;
88
+ shadowedCandidates: SubagentLaunchContractAgentCandidate[];
89
+ }
90
+
91
+ export interface SubagentLaunchContractSkills {
92
+ requested: string[];
93
+ resolved: Array<{ name: string; path: string; source: string }>;
94
+ missing: string[];
95
+ }
96
+
97
+ export interface SubagentLaunchContractTools {
98
+ requestedBuiltin: string[];
99
+ declaredBuiltin: string[];
100
+ effectiveAllowlist: string[];
101
+ explicitAllowlist: boolean;
102
+ requiredChildTools: string[];
103
+ internalTools: string[];
104
+ mcp: ResolvedMcpDirectToolSelection[];
105
+ effectiveMcpTools: string[];
106
+ toolExtensionPaths: string[];
107
+ runtimeExtensions: string[];
108
+ configuredExtensions: string[];
109
+ extensionArgs: string[];
110
+ disableAmbientExtensions: boolean;
111
+ fanoutAuthorized: boolean;
112
+ capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
113
+ capabilityAudit?: SubagentCapabilityAudit;
114
+ }
115
+
116
+ export interface SubagentLaunchContractRoots {
117
+ cwd: string;
118
+ sessionRoot?: string;
119
+ sessionDir?: string;
120
+ sessionFile?: string;
121
+ artifactsDir?: string;
122
+ artifactPaths?: ArtifactPaths;
123
+ outputPath?: string;
124
+ lifecycle?: {
125
+ asyncDir: string;
126
+ resultPath: string;
127
+ statusPath: string;
128
+ eventsPath: string;
129
+ processTerminalPath: string;
130
+ processTerminalCandidatePath: string;
131
+ };
132
+ }
133
+
134
+ export interface SubagentLaunchContract {
135
+ version: typeof SUBAGENT_LAUNCH_CONTRACT_VERSION;
136
+ runId: string;
137
+ agent: SubagentLaunchContractAgent;
138
+ context: "fresh" | "fork";
139
+ model?: string;
140
+ modelCandidates: string[];
141
+ thinking?: string;
142
+ systemPromptMode: AgentConfig["systemPromptMode"];
143
+ inheritProjectContext: boolean;
144
+ inheritSkills: boolean;
145
+ skills: SubagentLaunchContractSkills;
146
+ tools: SubagentLaunchContractTools;
147
+ roots: SubagentLaunchContractRoots;
148
+ protocol: {
149
+ lifecycleArtifactVersion: number;
150
+ packageVersion: string;
151
+ };
152
+ diagnostics: SubagentLaunchContractDiagnostic[];
153
+ /** Digest of the resolved child inputs, recomputed by execution paths. */
154
+ launchContractDigest: string;
155
+ digest: string;
156
+ }
157
+
158
+ export type SubagentLaunchContractResult =
159
+ | { ok: true; contract: SubagentLaunchContract }
160
+ | { ok: false; code: SubagentLaunchContractReasonCode; message: string; diagnostics: SubagentLaunchContractDiagnostic[] };
161
+
162
+ function packageVersion(): string {
163
+ const packagePath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "package.json");
164
+ const parsed = JSON.parse(fs.readFileSync(packagePath, "utf-8")) as { version?: unknown };
165
+ if (typeof parsed.version !== "string" || !parsed.version.trim()) {
166
+ throw new Error(`Invalid package version in '${packagePath}'.`);
167
+ }
168
+ return parsed.version;
169
+ }
170
+
171
+ function stableJson(value: unknown): string {
172
+ if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
173
+ if (value && typeof value === "object") {
174
+ return `{${Object.entries(value as Record<string, unknown>)
175
+ .filter(([, entry]) => entry !== undefined)
176
+ .sort(([a], [b]) => a.localeCompare(b))
177
+ .map(([key, entry]) => `${JSON.stringify(key)}:${stableJson(entry)}`)
178
+ .join(",")}}`;
179
+ }
180
+ return JSON.stringify(value);
181
+ }
182
+
183
+ function digestContract(contract: Omit<SubagentLaunchContract, "digest">): string {
184
+ return createHash("sha256").update(stableJson(contract)).digest("hex");
185
+ }
186
+
187
+ function normalizeAvailableModels(models: SubagentLaunchContractInput["availableModels"]): AvailableModelInfo[] {
188
+ return (models ?? []).map((model) => ({ ...model, fullId: model.fullId ?? `${model.provider}/${model.id}` }));
189
+ }
190
+
191
+ function candidateList(inputAgent: string, selected: AgentConfig | undefined, cwd: string): SubagentLaunchContractAgentCandidate[] {
192
+ const all = discoverAgentsAll(cwd);
193
+ return [...all.builtin, ...all.package, ...all.user, ...all.project]
194
+ .filter((agent) => agent.name === inputAgent || agent.localName === inputAgent)
195
+ .map((agent) => ({
196
+ name: agent.name,
197
+ ...(agent.localName ? { localName: agent.localName } : {}),
198
+ ...(agent.packageName ? { packageName: agent.packageName } : {}),
199
+ source: agent.source,
200
+ filePath: agent.filePath,
201
+ ...(agent.disabled === true ? { disabled: true } : {}),
202
+ selected: Boolean(selected && agent.filePath === selected.filePath && agent.name === selected.name),
203
+ }));
204
+ }
205
+
206
+ export async function resolveSubagentLaunchContract(input: SubagentLaunchContractInput): Promise<SubagentLaunchContractResult> {
207
+ const diagnostics: SubagentLaunchContractDiagnostic[] = [];
208
+ const effectiveCwd = path.resolve(input.cwd);
209
+ try {
210
+ if (!fs.statSync(effectiveCwd).isDirectory()) {
211
+ return { ok: false, code: "invalid_cwd", message: `cwd '${effectiveCwd}' is not a directory.`, diagnostics };
212
+ }
213
+ } catch (error) {
214
+ const detail = error instanceof Error ? ` ${error.message}` : "";
215
+ return { ok: false, code: "invalid_cwd", message: `cwd '${effectiveCwd}' is not a directory.${detail}`, diagnostics };
216
+ }
217
+ if (input.context !== undefined && input.context !== "fresh" && input.context !== "fork") {
218
+ return { ok: false, code: "unsupported_mode", message: `Unsupported context '${String(input.context)}'; expected 'fresh' or 'fork'.`, diagnostics };
219
+ }
220
+ if (input.artifactDir !== undefined && input.artifactDir !== "project" && input.artifactDir !== "session" && input.artifactDir !== "temp") {
221
+ return { ok: false, code: "invalid_artifact_dir", message: `Unsupported artifactDir '${String(input.artifactDir)}'; expected 'project', 'session', or 'temp'.`, diagnostics };
222
+ }
223
+ if (input.context === "fork") {
224
+ diagnostics.push({ code: "host_required", severity: "host-required", message: "Exact fork session branching and fork-thinking downgrade checks require Pi host session and model-registry snapshots." });
225
+ }
226
+ const scope = resolveExecutionAgentScope(input.agentScope);
227
+ const discovered = discoverAgents(effectiveCwd, scope);
228
+ const matches = discovered.agents.filter((agent) => agent.name === input.agent || agent.localName === input.agent);
229
+ if (matches.length === 0) {
230
+ return { ok: false, code: "missing_agent", message: `Unknown agent: ${input.agent}`, diagnostics };
231
+ }
232
+ if (matches.length > 1) {
233
+ return { ok: false, code: "ambiguous_agent", message: `Ambiguous agent: ${input.agent}`, diagnostics };
234
+ }
235
+ const agent = matches[0]!;
236
+ const runId = input.runId ?? "preflight";
237
+ const skillInput = normalizeSkillInput(input.skill);
238
+ const outputOverride = normalizeSingleOutputOverride(input.output, agent.output);
239
+ const behavior = resolveStepBehavior(agent, {
240
+ ...(outputOverride !== undefined ? { output: outputOverride } : {}),
241
+ ...(input.outputMode !== undefined ? { outputMode: input.outputMode } : {}),
242
+ ...(skillInput !== undefined ? { skills: skillInput } : {}),
243
+ ...(input.model !== undefined ? { model: input.model } : {}),
244
+ });
245
+ const requestedSkills = behavior.skills === false ? [] : behavior.skills;
246
+ const resolvedSkills = resolveSkillsWithFallback(
247
+ requestedSkills,
248
+ effectiveCwd,
249
+ effectiveCwd,
250
+ agent.skillPath,
251
+ agent.filePath ? path.dirname(agent.filePath) : effectiveCwd,
252
+ );
253
+ if (resolvedSkills.missing.includes("pi-subagents")) {
254
+ return { ok: false, code: "missing_skill", message: "The pi-subagents orchestration skill is not child-injectable.", diagnostics };
255
+ }
256
+ if (resolvedSkills.missing.length > 0) diagnostics.push({ code: "missing_skill", severity: "error", message: `Missing skills: ${resolvedSkills.missing.join(", ")}` });
257
+
258
+ const availableModels = normalizeAvailableModels(input.availableModels);
259
+ const preferredProvider = input.preferredProvider ?? input.parentModel?.provider;
260
+ const primaryModel = resolveEffectiveSubagentModel(input.model, agent.model, input.parentModel, availableModels, preferredProvider, { scope: discovered.modelScope });
261
+ const effectiveThinkingConfig = input.thinking !== undefined ? input.thinking : agent.thinking;
262
+ const model = applyThinkingSuffix(primaryModel, effectiveThinkingConfig, input.thinking !== undefined);
263
+ const modelCandidates = buildModelCandidates(primaryModel, agent.fallbackModels, availableModels, preferredProvider, { scope: discovered.modelScope })
264
+ .map((candidate) => applyThinkingSuffix(candidate, effectiveThinkingConfig, input.thinking !== undefined) ?? candidate);
265
+ let toolPlan: PiLaunchToolPlan;
266
+ try {
267
+ toolPlan = resolvePiLaunchToolPlan({
268
+ tools: agent.tools,
269
+ extensions: agent.extensions,
270
+ subagentOnlyExtensions: agent.subagentOnlyExtensions,
271
+ mcpDirectTools: agent.mcpDirectTools,
272
+ cwd: effectiveCwd,
273
+ requireReadTool: resolvedSkills.resolved.length > 0,
274
+ structuredOutput: Boolean(input.outputSchema),
275
+ capabilityCeiling: input.capabilityCeiling,
276
+ inheritedCapabilityCeiling: input.inheritedCapabilityCeiling,
277
+ });
278
+ } catch (error) {
279
+ const message = error instanceof Error ? error.message : String(error);
280
+ diagnostics.push({ code: "denied_required_tool", severity: "error", message });
281
+ return { ok: false, code: "denied_required_tool", message, diagnostics };
282
+ }
283
+ const artifactsEnabled = input.artifacts !== false;
284
+ const artifactsDir = artifactsEnabled ? getArtifactsDir(input.parentSessionFile ?? null, effectiveCwd, input.artifactDir ?? "project") : undefined;
285
+ const artifactPaths = artifactsDir ? getArtifactPaths(artifactsDir, runId, agent.name, 0) : undefined;
286
+ const outputPath = resolveSingleOutputPath(behavior.output, effectiveCwd, effectiveCwd, artifactsDir ? path.join(artifactsDir, "outputs", runId) : undefined);
287
+ const sessionRoot = input.sessionDir ? path.resolve(input.sessionDir) : input.sessionRoot ? path.join(path.resolve(input.sessionRoot), runId) : undefined;
288
+ const sessionDir = sessionRoot ? path.join(sessionRoot, "run-0") : undefined;
289
+ const lifecycleAsyncDir = input.nestedRootRunId
290
+ ? path.join(TEMP_ROOT_DIR, "nested-subagent-runs", input.nestedRootRunId, runId)
291
+ : path.join(ASYNC_DIR, runId);
292
+ const lifecycleResultPath = input.nestedRootRunId
293
+ ? nestedResultsPath(input.nestedRootRunId, runId)
294
+ : path.join(RESULTS_DIR, `${runId}.json`);
295
+ if (!sessionDir) diagnostics.push({ code: "host_required", severity: "host-required", message: "No sessionRoot/sessionDir was supplied; exact child session paths require the Pi host session-root policy." });
296
+ if (input.availableModels === undefined && (input.model || agent.model || input.parentModel)) {
297
+ diagnostics.push({ code: "host_required", severity: "host-required", message: "No availableModels snapshot was supplied; model resolution may differ from the active Pi host registry." });
298
+ }
299
+ if (resolvedSkills.missing.length > 0) {
300
+ return { ok: false, code: "missing_skill", message: `Missing skills: ${resolvedSkills.missing.join(", ")}`, diagnostics };
301
+ }
302
+ let effectiveSystemPrompt = agent.systemPrompt?.trim() ?? "";
303
+ if (resolvedSkills.resolved.length > 0) {
304
+ const skillInjection = buildSkillInjection(resolvedSkills.resolved);
305
+ effectiveSystemPrompt = effectiveSystemPrompt ? `${effectiveSystemPrompt}\n\n${skillInjection}` : skillInjection;
306
+ }
307
+ const memoryInjection = buildAgentMemoryInjection(agent, effectiveCwd);
308
+ if (memoryInjection) effectiveSystemPrompt = effectiveSystemPrompt ? `${effectiveSystemPrompt}\n\n${memoryInjection}` : memoryInjection;
309
+ effectiveSystemPrompt = injectOutputPathSystemPrompt(effectiveSystemPrompt, outputPath, agent);
310
+ const turnBudget = input.turnBudget ?? agent.defaultTurnBudget;
311
+ effectiveSystemPrompt = appendTurnBudgetSystemPrompt(effectiveSystemPrompt, turnBudget);
312
+ const candidates = candidateList(input.agent, agent, effectiveCwd);
313
+ const shadowedCandidates = candidates.filter((candidate) => !candidate.selected);
314
+ const definitionDigest = agentDefinitionDigest(agent);
315
+ const contractBase: Omit<SubagentLaunchContract, "digest"> = {
316
+ version: SUBAGENT_LAUNCH_CONTRACT_VERSION,
317
+ runId,
318
+ agent: {
319
+ name: agent.name,
320
+ ...(agent.localName ? { localName: agent.localName } : {}),
321
+ ...(agent.packageName ? { packageName: agent.packageName } : {}),
322
+ source: agent.source,
323
+ filePath: agent.filePath,
324
+ definitionProjectionVersion: AGENT_DEFINITION_PROJECTION_VERSION,
325
+ definitionDigest,
326
+ shadowedCandidates,
327
+ },
328
+ context: input.context ?? agent.defaultContext ?? "fresh",
329
+ ...(model ? { model } : {}),
330
+ modelCandidates,
331
+ ...(resolveEffectiveThinking(model, effectiveThinkingConfig) ? { thinking: resolveEffectiveThinking(model, effectiveThinkingConfig) } : {}),
332
+ systemPromptMode: agent.systemPromptMode,
333
+ inheritProjectContext: agent.inheritProjectContext,
334
+ inheritSkills: agent.inheritSkills,
335
+ skills: {
336
+ requested: requestedSkills,
337
+ resolved: resolvedSkills.resolved.map((skill) => ({ name: skill.name, path: skill.path, source: skill.source })),
338
+ missing: resolvedSkills.missing,
339
+ },
340
+ tools: {
341
+ requestedBuiltin: toolPlan.requestedBuiltinTools,
342
+ declaredBuiltin: toolPlan.declaredBuiltinTools,
343
+ effectiveAllowlist: toolPlan.effectiveToolAllowlist,
344
+ explicitAllowlist: toolPlan.explicitToolAllowlist,
345
+ requiredChildTools: toolPlan.requiredChildTools,
346
+ internalTools: toolPlan.internalTools,
347
+ mcp: toolPlan.effectiveMcpSelections,
348
+ effectiveMcpTools: toolPlan.effectiveMcpTools,
349
+ toolExtensionPaths: toolPlan.toolExtensionPaths,
350
+ runtimeExtensions: toolPlan.runtimeExtensions,
351
+ configuredExtensions: toolPlan.configuredExtensions,
352
+ extensionArgs: toolPlan.extensionArgs,
353
+ disableAmbientExtensions: toolPlan.disableAmbientExtensions,
354
+ fanoutAuthorized: toolPlan.fanoutAuthorized,
355
+ ...(toolPlan.capabilityCeiling ? { capabilityCeiling: toolPlan.capabilityCeiling } : {}),
356
+ ...(toolPlan.capabilityAudit ? { capabilityAudit: toolPlan.capabilityAudit } : {}),
357
+ },
358
+ roots: {
359
+ cwd: effectiveCwd,
360
+ ...(sessionRoot ? { sessionRoot } : {}),
361
+ ...(sessionDir ? { sessionDir, sessionFile: path.join(sessionDir, "session.jsonl") } : {}),
362
+ ...(artifactsDir ? { artifactsDir } : {}),
363
+ ...(artifactPaths ? { artifactPaths } : {}),
364
+ ...(outputPath ? { outputPath } : {}),
365
+ lifecycle: {
366
+ asyncDir: lifecycleAsyncDir,
367
+ resultPath: lifecycleResultPath,
368
+ statusPath: path.join(lifecycleAsyncDir, "status.json"),
369
+ eventsPath: path.join(lifecycleAsyncDir, "events.jsonl"),
370
+ processTerminalPath: processTerminalPath(lifecycleAsyncDir),
371
+ processTerminalCandidatePath: processTerminalCandidatePath(lifecycleAsyncDir),
372
+ },
373
+ },
374
+ protocol: {
375
+ lifecycleArtifactVersion: SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
376
+ packageVersion: packageVersion(),
377
+ },
378
+ diagnostics,
379
+ launchContractDigest: launchBindingDigest({
380
+ task: input.task ?? "",
381
+ definitionDigest,
382
+ ...(model ? { model } : {}),
383
+ modelCandidates,
384
+ ...(resolveEffectiveThinking(model, effectiveThinkingConfig) ? { thinking: resolveEffectiveThinking(model, effectiveThinkingConfig) } : {}),
385
+ systemPrompt: effectiveSystemPrompt,
386
+ systemPromptMode: agent.systemPromptMode,
387
+ inheritProjectContext: agent.inheritProjectContext,
388
+ inheritSkills: agent.inheritSkills,
389
+ skills: requestedSkills,
390
+ tools: toolPlan.effectiveToolAllowlist,
391
+ extensions: toolPlan.extensionArgs,
392
+ mcpDirectTools: toolPlan.effectiveMcpTools,
393
+ ...(outputPath ? { outputPath } : {}),
394
+ outputMode: input.outputMode ?? "inline",
395
+ ...(input.outputSchema ? { structuredOutputSchema: input.outputSchema } : {}),
396
+ }),
397
+ };
398
+ return { ok: true, contract: { ...contractBase, digest: digestContract(contractBase) } };
399
+ }