@selesai/code 0.5.27 → 0.5.29

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 (310) hide show
  1. package/dist/cli/args.d.ts.map +1 -1
  2. package/dist/cli/args.js +9 -1
  3. package/dist/cli/args.js.map +1 -1
  4. package/dist/cli/config-selector.d.ts.map +1 -1
  5. package/dist/cli/config-selector.js +1 -1
  6. package/dist/cli/config-selector.js.map +1 -1
  7. package/dist/cli/credential-print.d.ts +23 -0
  8. package/dist/cli/credential-print.d.ts.map +1 -0
  9. package/dist/cli/credential-print.js +117 -0
  10. package/dist/cli/credential-print.js.map +1 -0
  11. package/dist/cli/startup-ui.d.ts.map +1 -1
  12. package/dist/cli/startup-ui.js +1 -1
  13. package/dist/cli/startup-ui.js.map +1 -1
  14. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  15. package/dist/core/agent-session-runtime.js +3 -0
  16. package/dist/core/agent-session-runtime.js.map +1 -1
  17. package/dist/core/agent-session.d.ts +12 -1
  18. package/dist/core/agent-session.d.ts.map +1 -1
  19. package/dist/core/agent-session.js +20 -14
  20. package/dist/core/agent-session.js.map +1 -1
  21. package/dist/core/compaction/compaction.d.ts.map +1 -1
  22. package/dist/core/compaction/compaction.js +11 -3
  23. package/dist/core/compaction/compaction.js.map +1 -1
  24. package/dist/core/extensions/runner.d.ts +1 -0
  25. package/dist/core/extensions/runner.d.ts.map +1 -1
  26. package/dist/core/extensions/runner.js +11 -0
  27. package/dist/core/extensions/runner.js.map +1 -1
  28. package/dist/core/extensions/types.d.ts +14 -1
  29. package/dist/core/extensions/types.d.ts.map +1 -1
  30. package/dist/core/extensions/types.js.map +1 -1
  31. package/dist/core/footer-data-provider.d.ts +10 -0
  32. package/dist/core/footer-data-provider.d.ts.map +1 -1
  33. package/dist/core/footer-data-provider.js +1 -1
  34. package/dist/core/footer-data-provider.js.map +1 -1
  35. package/dist/core/llama/provider.d.ts.map +1 -1
  36. package/dist/core/llama/provider.js +8 -3
  37. package/dist/core/llama/provider.js.map +1 -1
  38. package/dist/core/model-config.d.ts +30 -0
  39. package/dist/core/model-config.d.ts.map +1 -1
  40. package/dist/core/model-config.js +6 -0
  41. package/dist/core/model-config.js.map +1 -1
  42. package/dist/core/model-registry.d.ts.map +1 -1
  43. package/dist/core/model-registry.js +2 -2
  44. package/dist/core/model-registry.js.map +1 -1
  45. package/dist/core/model-resolver.d.ts +1 -0
  46. package/dist/core/model-resolver.d.ts.map +1 -1
  47. package/dist/core/model-resolver.js +20 -3
  48. package/dist/core/model-resolver.js.map +1 -1
  49. package/dist/core/model-runtime.d.ts +2 -0
  50. package/dist/core/model-runtime.d.ts.map +1 -1
  51. package/dist/core/model-runtime.js +5 -4
  52. package/dist/core/model-runtime.js.map +1 -1
  53. package/dist/core/package-manager.d.ts.map +1 -1
  54. package/dist/core/package-manager.js +13 -6
  55. package/dist/core/package-manager.js.map +1 -1
  56. package/dist/core/remote-catalog-provider.d.ts +1 -1
  57. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  58. package/dist/core/remote-catalog-provider.js +24 -11
  59. package/dist/core/remote-catalog-provider.js.map +1 -1
  60. package/dist/core/resource-loader.d.ts +15 -0
  61. package/dist/core/resource-loader.d.ts.map +1 -1
  62. package/dist/core/resource-loader.js +66 -9
  63. package/dist/core/resource-loader.js.map +1 -1
  64. package/dist/core/settings-manager.d.ts +1 -1
  65. package/dist/core/settings-manager.d.ts.map +1 -1
  66. package/dist/core/settings-manager.js.map +1 -1
  67. package/dist/core/system-prompt.d.ts.map +1 -1
  68. package/dist/core/system-prompt.js +1 -1
  69. package/dist/core/system-prompt.js.map +1 -1
  70. package/dist/core/tools/bash.d.ts +2 -0
  71. package/dist/core/tools/bash.d.ts.map +1 -1
  72. package/dist/core/tools/bash.js +34 -5
  73. package/dist/core/tools/bash.js.map +1 -1
  74. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  75. package/dist/core/tools/tool-definition-wrapper.js +3 -1
  76. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  77. package/dist/extensions/pi-intercom/CHANGELOG.md +249 -0
  78. package/dist/extensions/pi-intercom/README.md +102 -39
  79. package/dist/extensions/pi-intercom/broker/broker.ts +1233 -36
  80. package/dist/extensions/pi-intercom/broker/client.test.ts +83 -0
  81. package/dist/extensions/pi-intercom/broker/client.ts +315 -12
  82. package/dist/extensions/pi-intercom/broker/extension-state.ts +186 -0
  83. package/dist/extensions/pi-intercom/broker/extension.test.ts +387 -0
  84. package/dist/extensions/pi-intercom/broker/framing.test.ts +114 -0
  85. package/dist/extensions/pi-intercom/broker/framing.ts +82 -24
  86. package/dist/extensions/pi-intercom/broker/paths.test.ts +153 -0
  87. package/dist/extensions/pi-intercom/broker/paths.ts +117 -8
  88. package/dist/extensions/pi-intercom/broker/runtime-claim.test.ts +34 -0
  89. package/dist/extensions/pi-intercom/broker/runtime-claim.ts +21 -0
  90. package/dist/extensions/pi-intercom/broker/spawn.test.ts +160 -23
  91. package/dist/extensions/pi-intercom/broker/spawn.ts +113 -27
  92. package/dist/extensions/pi-intercom/config.test.ts +93 -0
  93. package/dist/extensions/pi-intercom/config.ts +55 -6
  94. package/dist/extensions/pi-intercom/cwd.test.ts +40 -0
  95. package/dist/extensions/pi-intercom/cwd.ts +31 -0
  96. package/dist/extensions/pi-intercom/extension-api.ts +44 -0
  97. package/dist/extensions/pi-intercom/format-context.test.ts +31 -0
  98. package/dist/extensions/pi-intercom/format-context.ts +32 -0
  99. package/dist/extensions/pi-intercom/index.ts +742 -145
  100. package/dist/extensions/pi-intercom/intercom.integration.test.ts +2646 -0
  101. package/dist/extensions/pi-intercom/package.json +15 -5
  102. package/dist/extensions/pi-intercom/reply-tracker.test.ts +134 -0
  103. package/dist/extensions/pi-intercom/reply-tracker.ts +31 -13
  104. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +13 -11
  105. package/dist/extensions/pi-intercom/test/inline-message.test.ts +184 -0
  106. package/dist/extensions/pi-intercom/test/overlay-width.test.ts +66 -0
  107. package/dist/extensions/pi-intercom/types.ts +94 -4
  108. package/dist/extensions/pi-intercom/ui/compose.ts +8 -4
  109. package/dist/extensions/pi-intercom/ui/inline-message.ts +61 -25
  110. package/dist/extensions/pi-intercom/ui/session-list.ts +7 -3
  111. package/dist/extensions/pi-subagents/CHANGELOG.md +85 -0
  112. package/dist/extensions/pi-subagents/LICENSE +21 -0
  113. package/dist/extensions/pi-subagents/README.md +146 -52
  114. package/dist/extensions/pi-subagents/agents/architect.md +1 -0
  115. package/dist/extensions/pi-subagents/agents/builder.md +1 -0
  116. package/dist/extensions/pi-subagents/package-lock.json +2 -2
  117. package/dist/extensions/pi-subagents/package.json +3 -3
  118. package/dist/extensions/pi-subagents/prompts/review-loop.md +1 -1
  119. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +21 -989
  120. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +256 -0
  121. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +430 -0
  122. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +144 -0
  123. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +282 -0
  124. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +71 -30
  125. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +4 -0
  126. package/dist/extensions/pi-subagents/src/agents/agents.ts +118 -9
  127. package/dist/extensions/pi-subagents/src/agents/skills.ts +14 -12
  128. package/dist/extensions/pi-subagents/src/api/delegation.ts +3 -0
  129. package/dist/extensions/pi-subagents/src/api/preflight.ts +16 -12
  130. package/dist/extensions/pi-subagents/src/extension/chain-validation.ts +17 -1
  131. package/dist/extensions/pi-subagents/src/extension/index.ts +17 -7
  132. package/dist/extensions/pi-subagents/src/extension/rpc.ts +248 -6
  133. package/dist/extensions/pi-subagents/src/extension/schemas.ts +31 -6
  134. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +8 -7
  135. package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +9 -4
  136. package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +33 -4
  137. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +63 -16
  138. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +24 -13
  139. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +7 -5
  140. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -2
  141. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +48 -5
  142. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +68 -1
  143. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +29 -4
  144. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +29 -6
  145. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +29 -3
  146. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +372 -28
  147. package/dist/extensions/pi-subagents/src/runs/foreground/async-stop-action.ts +65 -0
  148. package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +3 -3
  149. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +143 -43
  150. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +527 -247
  151. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +42 -0
  152. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +426 -123
  153. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +15 -7
  154. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +51 -19
  155. package/dist/extensions/pi-subagents/src/runs/shared/chain-outputs.ts +3 -1
  156. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  157. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +44 -11
  158. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +8 -0
  159. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +97 -20
  160. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +43 -12
  161. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +52 -4
  162. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +19 -0
  163. package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +45 -9
  164. package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +71 -0
  165. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +31 -1
  166. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +101 -0
  167. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +1 -1
  168. package/dist/extensions/pi-subagents/src/runs/shared/usage-budget.ts +65 -0
  169. package/dist/extensions/pi-subagents/src/runs/shared/workflow-graph.ts +26 -1
  170. package/dist/extensions/pi-subagents/src/shared/settings.ts +17 -1
  171. package/dist/extensions/pi-subagents/src/shared/types.ts +155 -10
  172. package/dist/extensions/pi-subagents/src/shared/utils.ts +73 -4
  173. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +5 -0
  174. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +46 -4
  175. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +5 -3
  176. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +87 -24
  177. package/dist/extensions/pi-subagents/src/tui/fleet.ts +182 -9
  178. package/dist/extensions/pi-subagents/src/tui/render.ts +27 -28
  179. package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +14 -7
  180. package/dist/extensions/pi-subagents/src/watchdog/review.ts +5 -4
  181. package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +170 -17
  182. package/dist/extensions/pi-subagents/src/watchdog/scope.ts +62 -0
  183. package/dist/extensions/pi-subagents/src/watchdog/settings.ts +41 -1
  184. package/dist/extensions/pi-subagents/src/watchdog/types.ts +10 -0
  185. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +2 -2
  186. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +348 -7
  187. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +84 -0
  188. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +4 -2
  189. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +51 -2
  190. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +26 -1
  191. package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +48 -0
  192. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +3 -3
  193. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +213 -13
  194. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +34 -0
  195. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +44 -0
  196. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +118 -12
  197. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +850 -7
  198. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +112 -23
  199. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +17 -5
  200. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +2 -0
  201. package/dist/extensions/pi-subagents/test/support/register-loader.mjs +3 -3
  202. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +3 -1
  203. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +128 -0
  204. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +47 -2
  205. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +60 -0
  206. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +8 -0
  207. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +102 -0
  208. package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +1 -1
  209. package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +6 -0
  210. package/dist/extensions/pi-subagents/test/unit/chain-validation.test.ts +1 -1
  211. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +48 -48
  212. package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +23 -0
  213. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +27 -0
  214. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +4 -2
  215. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +1 -0
  216. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +176 -8
  217. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +164 -5
  218. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +41 -1
  219. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +11 -11
  220. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +18 -2
  221. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +20 -1
  222. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +30 -2
  223. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +10 -2
  224. package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +22 -0
  225. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +103 -0
  226. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +18 -0
  227. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +46 -0
  228. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +13 -1
  229. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +29 -4
  230. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +223 -4
  231. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +30 -0
  232. package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +52 -0
  233. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +34 -2
  234. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
  235. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +1 -1
  236. package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +78 -0
  237. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +41 -0
  238. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +77 -0
  239. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +3 -0
  240. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +1 -1
  241. package/dist/extensions/pi-subagents/test/unit/total-cost.test.ts +1 -0
  242. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +210 -1
  243. package/dist/extensions/pi-subagents/test/unit/watchdog-scope.test.ts +33 -0
  244. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +32 -0
  245. package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +1 -1
  246. package/dist/extensions/question/index.ts +14 -1
  247. package/dist/extensions/question/tests/wizard.test.ts +11 -8
  248. package/dist/main.d.ts.map +1 -1
  249. package/dist/main.js +43 -0
  250. package/dist/main.js.map +1 -1
  251. package/dist/modes/interactive/components/custom-message.d.ts +3 -1
  252. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  253. package/dist/modes/interactive/components/custom-message.js +10 -2
  254. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  255. package/dist/modes/interactive/components/extension-editor.d.ts +1 -2
  256. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  257. package/dist/modes/interactive/components/extension-editor.js +16 -46
  258. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  259. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  260. package/dist/modes/interactive/components/model-selector.js +4 -1
  261. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  262. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  263. package/dist/modes/interactive/components/scoped-models-selector.js +22 -13
  264. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  265. package/dist/modes/interactive/external-editor.d.ts +12 -0
  266. package/dist/modes/interactive/external-editor.d.ts.map +1 -0
  267. package/dist/modes/interactive/external-editor.js +37 -0
  268. package/dist/modes/interactive/external-editor.js.map +1 -0
  269. package/dist/modes/interactive/interactive-mode.d.ts +1 -1
  270. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  271. package/dist/modes/interactive/interactive-mode.js +72 -64
  272. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  273. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  274. package/dist/modes/rpc/rpc-mode.js +14 -0
  275. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  276. package/dist/skills/batch-grill-me/SKILL.md +3 -1
  277. package/dist/utils/clipboard.d.ts.map +1 -1
  278. package/dist/utils/clipboard.js +19 -8
  279. package/dist/utils/clipboard.js.map +1 -1
  280. package/dist/utils/version-check.d.ts.map +1 -1
  281. package/dist/utils/version-check.js +1 -1
  282. package/dist/utils/version-check.js.map +1 -1
  283. package/docs/compaction.md +1 -1
  284. package/docs/custom-provider.md +14 -5
  285. package/docs/environment-variables.md +86 -0
  286. package/docs/extensions.md +15 -5
  287. package/docs/index.md +1 -0
  288. package/docs/models.md +9 -2
  289. package/docs/providers.md +21 -2
  290. package/docs/rpc.md +23 -6
  291. package/docs/session-format.md +2 -0
  292. package/docs/settings.md +1 -1
  293. package/docs/usage.md +0 -13
  294. package/examples/extensions/custom-compaction.ts +5 -2
  295. package/examples/extensions/custom-provider-anthropic/index.ts +9 -3
  296. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  297. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  298. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  299. package/examples/extensions/gondolin/package-lock.json +2 -2
  300. package/examples/extensions/gondolin/package.json +1 -1
  301. package/examples/extensions/handoff.ts +11 -3
  302. package/examples/extensions/message-renderer.ts +3 -3
  303. package/examples/extensions/sandbox/package-lock.json +2 -2
  304. package/examples/extensions/sandbox/package.json +1 -1
  305. package/examples/extensions/summarize.ts +5 -2
  306. package/examples/extensions/with-deps/package-lock.json +2 -2
  307. package/examples/extensions/with-deps/package.json +1 -1
  308. package/examples/sdk/12-full-control.ts +3 -1
  309. package/package.json +15 -6
  310. package/dist/extensions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
@@ -109,6 +109,14 @@ describe("async resume lookup", () => {
109
109
  });
110
110
  assert.throws(() => resolveAsyncResumeTarget({ id: "run-descriptor" }, { asyncDirRoot: asyncRoot, resultsDir }), /capabilityCeiling sources/);
111
111
 
112
+ writeJson(path.join(asyncDir, "recovery-descriptor.json"), {
113
+ ...descriptor,
114
+ launchContractDigest: "launch-contract-digest",
115
+ });
116
+ const valid = resolveAsyncResumeTarget({ id: "run-descriptor" }, { asyncDirRoot: asyncRoot, resultsDir });
117
+ assert.equal(valid.launchContractDigest, "launch-contract-digest");
118
+ assert.equal(valid.recoveryDescriptor?.launchContractDigest, "launch-contract-digest");
119
+
112
120
  writeJson(path.join(asyncDir, "recovery-descriptor.json"), { ...descriptor, sourceRunId: "another-run" });
113
121
  assert.throws(() => resolveAsyncResumeTarget({ id: "run-descriptor" }, { asyncDirRoot: asyncRoot, resultsDir }), /different source run/);
114
122
 
@@ -0,0 +1,102 @@
1
+ import assert from "node:assert/strict";
2
+ import { describe, it } from "node:test";
3
+ import { handleList } from "../../src/agents/agent-management.ts";
4
+ import type { AgentConfig } from "../../src/agents/agents.ts";
5
+ import { resolveSubagentLaunchContract } from "../../src/api/preflight.ts";
6
+ import {
7
+ decodeSubagentCapabilityCeiling,
8
+ encodeSubagentCapabilityCeiling,
9
+ intersectSubagentCapabilityCeilings,
10
+ parseSubagentCapabilityCeiling,
11
+ registerSubagentCapabilityCeiling,
12
+ } from "../../src/api/capability-ceiling.ts";
13
+ import { runSync } from "../../src/runs/foreground/execution.ts";
14
+ import { buildPiArgs } from "../../src/runs/shared/pi-args.ts";
15
+
16
+ function agent(name: string): AgentConfig {
17
+ return {
18
+ name,
19
+ description: `${name} agent`,
20
+ systemPrompt: `${name} prompt`,
21
+ systemPromptMode: "replace",
22
+ inheritProjectContext: false,
23
+ inheritSkills: false,
24
+ source: "project",
25
+ filePath: `/tmp/${name}.md`,
26
+ };
27
+ }
28
+
29
+ describe("capability ceiling agent allowlist", () => {
30
+ it("parses, round-trips, and intersects allowedAgents", () => {
31
+ const parsed = parseSubagentCapabilityCeiling({ version: 1, allowedAgents: ["worker", "reviewer", "worker"], denyExtensions: false, sources: ["plan"] });
32
+ assert.deepEqual(parsed.allowedAgents, ["reviewer", "worker"]);
33
+ assert.deepEqual(decodeSubagentCapabilityCeiling(encodeSubagentCapabilityCeiling(parsed)), parsed);
34
+
35
+ assert.deepEqual(intersectSubagentCapabilityCeilings(
36
+ { version: 1, allowedAgents: ["worker", "reviewer"], denyExtensions: false, sources: ["outer"] },
37
+ { version: 1, allowedAgents: ["reviewer", "scout"], denyExtensions: true, sources: ["inner"] },
38
+ ), {
39
+ version: 1,
40
+ allowedAgents: ["reviewer"],
41
+ denyExtensions: true,
42
+ sources: ["inner", "outer"],
43
+ });
44
+
45
+ assert.deepEqual(intersectSubagentCapabilityCeilings(
46
+ { version: 1, allowedTools: ["read"], denyExtensions: false, sources: ["tools-only"] },
47
+ { version: 1, allowedAgents: [], denyExtensions: false, sources: ["none"] },
48
+ )?.allowedAgents, []);
49
+ });
50
+
51
+ it("marks non-allowlisted agents as restricted in list output", () => {
52
+ const sessionId = `allowlist-list-${Date.now()}-${Math.random()}`;
53
+ const handle = registerSubagentCapabilityCeiling({ sessionId, source: "plan-mode", ceiling: { allowedAgents: ["commentator"] } });
54
+ try {
55
+ const result = handleList({}, { cwd: process.cwd(), currentSessionId: sessionId, modelRegistry: { getAvailable: () => [] } });
56
+ const text = result.content[0]?.text ?? "";
57
+ assert.match(text, /Executable agents:/);
58
+ assert.match(text, /- commentator /);
59
+ assert.match(text, /Restricted agents \(not executable in this session; capability ceiling: plan-mode\):/);
60
+ assert.match(text, /- builder /);
61
+ } finally {
62
+ handle.dispose();
63
+ }
64
+ });
65
+
66
+ it("rejects a non-allowlisted agent in preflight launch resolution", async () => {
67
+ const result = await resolveSubagentLaunchContract({
68
+ agent: "builder",
69
+ cwd: process.cwd(),
70
+ capabilityCeiling: { version: 1, allowedAgents: ["commentator"], denyExtensions: false, sources: ["plan-mode"] },
71
+ });
72
+ assert.equal(result.ok, false);
73
+ assert.equal(result.code, "restricted_agent");
74
+ assert.match(result.message, /does not allow agent 'builder'/);
75
+ assert.match(result.message, /Allowed agents: commentator/);
76
+ });
77
+
78
+ it("rejects a non-allowlisted foreground launch before spawning", async () => {
79
+ const result = await runSync(process.cwd(), [agent("builder"), agent("commentator")], "builder", "Do work", {
80
+ capabilityCeiling: { version: 1, allowedAgents: ["commentator"], denyExtensions: false, sources: ["plan-mode"] },
81
+ });
82
+ assert.equal(result.exitCode, 1);
83
+ assert.match(result.error ?? "", /does not allow agent 'builder'/);
84
+ assert.deepEqual(result.capabilityCeiling?.allowedAgents, ["commentator"]);
85
+ });
86
+
87
+ it("includes allowedAgents in propagated launch env and audit metadata", () => {
88
+ const { env, capabilityAudit } = buildPiArgs({
89
+ baseArgs: [],
90
+ task: "Review",
91
+ sessionEnabled: false,
92
+ inheritProjectContext: false,
93
+ inheritSkills: false,
94
+ childAgentName: "commentator",
95
+ capabilityCeiling: { version: 1, allowedAgents: ["commentator"], allowedTools: ["read"], denyExtensions: true, sources: ["plan-mode"] },
96
+ });
97
+ assert.equal(capabilityAudit?.agentAllowed, true);
98
+ assert.deepEqual(capabilityAudit?.agentRestrictionSources, ["plan-mode"]);
99
+ assert.ok(env.SELESAI_SUBAGENT_CAPABILITY_CEILING_V1);
100
+ assert.deepEqual(decodeSubagentCapabilityCeiling(env.SELESAI_SUBAGENT_CAPABILITY_CEILING_V1)?.allowedAgents, ["commentator"]);
101
+ });
102
+ });
@@ -33,7 +33,7 @@ describe("subagent capability ceiling", () => {
33
33
  });
34
34
 
35
35
  it("rejects malformed policy and disposed updates", () => {
36
- assert.throws(() => registerSubagentCapabilityCeiling({ sessionId: "x", source: "x", ceiling: {} }), /allowedTools or denyExtensions/);
36
+ assert.throws(() => registerSubagentCapabilityCeiling({ sessionId: "x", source: "x", ceiling: {} }), /allowedTools, allowedAgents, or denyExtensions/);
37
37
  const handle = registerSubagentCapabilityCeiling({ sessionId: "disposed", source: "test", ceiling: { denyExtensions: true } });
38
38
  handle.dispose();
39
39
  assert.throws(() => handle.update({ allowedTools: ["read"] }), /disposed/);
@@ -198,6 +198,12 @@ describe("chain append requests", () => {
198
198
  "reviewer:pending",
199
199
  "auditor:pending",
200
200
  ]);
201
+ // Appended steps must carry their own bounded task description for fleet display.
202
+ assert.deepEqual(status.steps?.slice(1).map((step) => step.description), [
203
+ "Use {previous}",
204
+ "Use {previous}",
205
+ "Use {previous}",
206
+ ]);
201
207
  assert.deepEqual(status.parallelGroups, [{ start: 2, count: 2, stepIndex: 2 }]);
202
208
  assert.equal(status.workflowGraph?.nodes[1]?.id, "step-1");
203
209
  assert.equal(status.workflowGraph?.nodes[2]?.kind, "parallel-group");
@@ -285,7 +285,7 @@ describe("registered subagent tool prepareArguments", { skip: !schemasAvailable
285
285
  const output = execFileSync(
286
286
  process.execPath,
287
287
  [
288
- "--experimental-transform-types",
288
+ "--experimental-strip-types",
289
289
  "--import",
290
290
  "./test/support/register-loader.mjs",
291
291
  "--input-type=module",
@@ -26,7 +26,7 @@ function assistantText(text: string): Message {
26
26
 
27
27
  test("implementation task with no mutation triggers the completion guard", () => {
28
28
  const result = evaluateCompletionMutationGuard({
29
- agent: "worker",
29
+ agent: "builder",
30
30
  task: "Implement the approved fix",
31
31
  messages: [assistantText("Plan: update the files...")],
32
32
  });
@@ -67,9 +67,9 @@ test("read-only issue drafting tasks do not trigger on suggested fix wording", (
67
67
  attemptedMutation: false,
68
68
  triggered: false,
69
69
  });
70
- assert.equal(expectsImplementationMutation("worker", task), false);
70
+ assert.equal(expectsImplementationMutation("builder", task), false);
71
71
  assert.equal(
72
- expectsImplementationMutation("worker", "Draft GitHub issue for a bug. Include suspected cause and suggested fix."),
72
+ expectsImplementationMutation("builder", "Draft GitHub issue for a bug. Include suspected cause and suggested fix."),
73
73
  false,
74
74
  );
75
75
  });
@@ -89,9 +89,9 @@ test("omitted, bash, unknown, write, and MCP tool capabilities stay conservative
89
89
  assert.equal(evaluateCompletionMutationGuard({ ...base, tools: ["read", "grep"], mcpDirectTools: ["github/search"] }).triggered, true);
90
90
  });
91
91
 
92
- test("worker with mutating-capable tools still triggers when no mutation is observed", () => {
92
+ test("builder with mutating-capable tools still triggers when no mutation is observed", () => {
93
93
  const result = evaluateCompletionMutationGuard({
94
- agent: "worker",
94
+ agent: "builder",
95
95
  task: "Fix the test implementation",
96
96
  messages: [assistantText("I will edit it next")],
97
97
  tools: ["read", "edit"],
@@ -104,10 +104,10 @@ test("worker with mutating-capable tools still triggers when no mutation is obse
104
104
  });
105
105
  });
106
106
 
107
- test("oracle review tasks with bash available do not require mutation", () => {
107
+ test("commentator review tasks with bash available do not require mutation", () => {
108
108
  const task = "Review prep findings and determine what to implement with playbooks instead of before.";
109
109
  const result = evaluateCompletionMutationGuard({
110
- agent: "oracle",
110
+ agent: "commentator",
111
111
  task,
112
112
  messages: [assistantText("Review complete with file-backed findings.")],
113
113
  tools: ["read", "grep", "find", "ls", "bash", "intercom"],
@@ -121,57 +121,57 @@ test("oracle review tasks with bash available do not require mutation", () => {
121
121
  });
122
122
 
123
123
  test("review-only, research, and framework output instructions do not expect mutation", () => {
124
- assert.equal(expectsImplementationMutation("worker", "Review only: return findings, do not edit"), false);
125
- assert.equal(expectsImplementationMutation("worker", "Do not edit files. Tell me how to fix the bug."), false);
126
- assert.equal(expectsImplementationMutation("worker", "Review the diff and suggest fixes only. Do not edit files."), false);
127
- assert.equal(expectsImplementationMutation("worker", "Implement this. Do not edit files outside this repo. Do not edit files."), false);
128
- assert.equal(expectsImplementationMutation("worker", "Investigate why this failed"), false);
124
+ assert.equal(expectsImplementationMutation("builder", "Review only: return findings, do not edit"), false);
125
+ assert.equal(expectsImplementationMutation("builder", "Do not edit files. Tell me how to fix the bug."), false);
126
+ assert.equal(expectsImplementationMutation("builder", "Review the diff and suggest fixes only. Do not edit files."), false);
127
+ assert.equal(expectsImplementationMutation("builder", "Implement this. Do not edit files outside this repo. Do not edit files."), false);
128
+ assert.equal(expectsImplementationMutation("builder", "Investigate why this failed"), false);
129
129
  assert.equal(expectsImplementationMutation("researcher", "Research the API behavior"), false);
130
130
  assert.equal(expectsImplementationMutation("researcher", "Research this and patch the bug"), false);
131
- assert.equal(expectsImplementationMutation("reviewer", "Review this and fix any real issues"), false);
132
- assert.equal(expectsImplementationMutation("reviewer", "Review this and fix any real issues; regardless of findings, apply changes directly"), true);
133
- assert.equal(expectsImplementationMutation("worker", "[Write to: /tmp/result.md]\n\nSummarize findings"), false);
134
- assert.equal(expectsImplementationMutation("worker", "Write report"), false);
135
- assert.equal(expectsImplementationMutation("worker", "Create a report"), false);
136
- assert.equal(expectsImplementationMutation("worker", "Create a summary"), false);
137
- assert.equal(expectsImplementationMutation("worker", "Add a report"), false);
138
- assert.equal(expectsImplementationMutation("worker", "Update a summary"), false);
139
- assert.equal(expectsImplementationMutation("worker", "Write to {chain_dir}"), false);
131
+ assert.equal(expectsImplementationMutation("commentator", "Review this and fix any real issues"), false);
132
+ assert.equal(expectsImplementationMutation("commentator", "Review this and fix any real issues; regardless of findings, apply changes directly"), true);
133
+ assert.equal(expectsImplementationMutation("builder", "[Write to: /tmp/result.md]\n\nSummarize findings"), false);
134
+ assert.equal(expectsImplementationMutation("builder", "Write report"), false);
135
+ assert.equal(expectsImplementationMutation("builder", "Create a report"), false);
136
+ assert.equal(expectsImplementationMutation("builder", "Create a summary"), false);
137
+ assert.equal(expectsImplementationMutation("builder", "Add a report"), false);
138
+ assert.equal(expectsImplementationMutation("builder", "Update a summary"), false);
139
+ assert.equal(expectsImplementationMutation("builder", "Write to {chain_dir}"), false);
140
140
  assert.equal(
141
- expectsImplementationMutation("worker", "Do async work\nUpdate progress at: /tmp/progress.md\n**Output:**\nWrite your findings to exactly this path: /tmp/out.md\nThis path is authoritative for this run.\nIgnore any other output filename or output path mentioned elsewhere."),
141
+ expectsImplementationMutation("builder", "Do async work\nUpdate progress at: /tmp/progress.md\n**Output:**\nWrite your findings to exactly this path: /tmp/out.md\nThis path is authoritative for this run.\nIgnore any other output filename or output path mentioned elsewhere."),
142
142
  false,
143
143
  );
144
144
  });
145
145
 
146
- test("worker implementation verbs win over investigative wording and scoped prohibitions", () => {
147
- assert.equal(expectsImplementationMutation("worker", "Investigate why the worker did not edit files and fix it"), true);
148
- assert.equal(expectsImplementationMutation("worker", "Do not modify tests; implement the fix"), true);
149
- assert.equal(expectsImplementationMutation("worker", "Do not modify tests — implement the fix"), true);
150
- assert.equal(expectsImplementationMutation("worker", "Research the current code path and patch the bug"), true);
151
- assert.equal(expectsImplementationMutation("worker", "Fix the bug where no edits were made"), true);
152
- assert.equal(expectsImplementationMutation("worker", "Fix lint"), true);
153
- assert.equal(expectsImplementationMutation("worker", "Fix the build"), true);
154
- assert.equal(expectsImplementationMutation("worker", "Fix TypeScript errors"), true);
155
- assert.equal(expectsImplementationMutation("worker", "Fix CI"), true);
156
- assert.equal(expectsImplementationMutation("worker", "Fix the failing test"), true);
157
- assert.equal(expectsImplementationMutation("worker", "Patch the cold start test"), true);
158
- assert.equal(expectsImplementationMutation("worker", "Implement the fix and return findings."), true);
146
+ test("builder implementation verbs win over investigative wording and scoped prohibitions", () => {
147
+ assert.equal(expectsImplementationMutation("builder", "Investigate why the worker did not edit files and fix it"), true);
148
+ assert.equal(expectsImplementationMutation("builder", "Do not modify tests; implement the fix"), true);
149
+ assert.equal(expectsImplementationMutation("builder", "Do not modify tests — implement the fix"), true);
150
+ assert.equal(expectsImplementationMutation("builder", "Research the current code path and patch the bug"), true);
151
+ assert.equal(expectsImplementationMutation("builder", "Fix the bug where no edits were made"), true);
152
+ assert.equal(expectsImplementationMutation("builder", "Fix lint"), true);
153
+ assert.equal(expectsImplementationMutation("builder", "Fix the build"), true);
154
+ assert.equal(expectsImplementationMutation("builder", "Fix TypeScript errors"), true);
155
+ assert.equal(expectsImplementationMutation("builder", "Fix CI"), true);
156
+ assert.equal(expectsImplementationMutation("builder", "Fix the failing test"), true);
157
+ assert.equal(expectsImplementationMutation("builder", "Patch the cold start test"), true);
158
+ assert.equal(expectsImplementationMutation("builder", "Implement the fix and return findings."), true);
159
159
  });
160
160
 
161
161
  test("non-worker implementation tasks still expect mutation", () => {
162
162
  assert.equal(expectsImplementationMutation("delegate", "Fix the bug where no edits were made"), true);
163
163
  assert.equal(expectsImplementationMutation("delegate", "Apply the suggested fix to src/runs/shared/completion-guard.ts"), true);
164
- assert.equal(expectsImplementationMutation("worker", "Draft a GitHub issue, then implement the fix"), true);
164
+ assert.equal(expectsImplementationMutation("builder", "Draft a GitHub issue, then implement the fix"), true);
165
165
  });
166
166
 
167
- test("worker edit intent covers common docs, config, and source tasks", () => {
168
- assert.equal(expectsImplementationMutation("worker", "Update README to mention the native tool"), true);
169
- assert.equal(expectsImplementationMutation("worker", "Remove share functionality and all Vercel references"), true);
170
- assert.equal(expectsImplementationMutation("worker", "Replace the registered command with a render tool"), true);
171
- assert.equal(expectsImplementationMutation("worker", "Create completion-guard.ts"), true);
172
- assert.equal(expectsImplementationMutation("worker", "Add tests for the completion guard"), true);
173
- assert.equal(expectsImplementationMutation("worker", "Implement the approved fixes. Do not edit files outside this repo."), true);
174
- assert.equal(expectsImplementationMutation("worker", "Implement the fix. Do not edit unrelated files."), true);
167
+ test("builder edit intent covers common docs, config, and source tasks", () => {
168
+ assert.equal(expectsImplementationMutation("builder", "Update README to mention the native tool"), true);
169
+ assert.equal(expectsImplementationMutation("builder", "Remove share functionality and all Vercel references"), true);
170
+ assert.equal(expectsImplementationMutation("builder", "Replace the registered command with a render tool"), true);
171
+ assert.equal(expectsImplementationMutation("builder", "Create completion-guard.ts"), true);
172
+ assert.equal(expectsImplementationMutation("builder", "Add tests for the completion guard"), true);
173
+ assert.equal(expectsImplementationMutation("builder", "Implement the approved fixes. Do not edit files outside this repo."), true);
174
+ assert.equal(expectsImplementationMutation("builder", "Implement the fix. Do not edit unrelated files."), true);
175
175
  });
176
176
 
177
177
  test("edit and write tool calls count as mutation attempts", () => {
@@ -195,7 +195,7 @@ test("obvious mutating bash commands count as mutation attempts", () => {
195
195
 
196
196
  test("implementation task with mutation attempts does not trigger", () => {
197
197
  const result = evaluateCompletionMutationGuard({
198
- agent: "worker",
198
+ agent: "builder",
199
199
  task: "Fix the failing test",
200
200
  messages: [assistantToolCall("edit", { path: "test.ts" })],
201
201
  });
@@ -279,7 +279,7 @@ test("provider checkpoint with a changed commit counts as mutation evidence", ()
279
279
  assert.equal(hasMutationToolCall([message]), true);
280
280
  assert.equal(
281
281
  evaluateCompletionMutationGuard({
282
- agent: "worker",
282
+ agent: "builder",
283
283
  task: "Edit the target source file",
284
284
  messages: [message],
285
285
  }).triggered,
@@ -297,7 +297,7 @@ test("unchanged provider checkpoint does not bypass the completion guard", () =>
297
297
  assert.equal(hasMutationToolCall([message]), false);
298
298
  assert.equal(
299
299
  evaluateCompletionMutationGuard({
300
- agent: "worker",
300
+ agent: "builder",
301
301
  task: "Edit the target source file",
302
302
  messages: [message],
303
303
  }).triggered,
@@ -308,7 +308,7 @@ test("unchanged provider checkpoint does not bypass the completion guard", () =>
308
308
 
309
309
  test("implementation task with Cursor edit thinking does not trigger", () => {
310
310
  const result = evaluateCompletionMutationGuard({
311
- agent: "worker",
311
+ agent: "builder",
312
312
  task: "Edit docs/BACKEND_ARCHITECTURE.md",
313
313
  messages: [
314
314
  assistantThinking("Cursor edit: docs/BACKEND_ARCHITECTURE.md added 1 line\n"),
@@ -65,6 +65,29 @@ describe("config directory resolution", () => {
65
65
  }
66
66
  });
67
67
 
68
+ it("invalidates cached runtime resolution when the package root changes", () => {
69
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-config-cache-"));
70
+ try {
71
+ const firstRoot = path.join(tempDir, "first");
72
+ const secondRoot = path.join(tempDir, "second");
73
+ for (const [root, configDir] of [[firstRoot, ".first-pi"], [secondRoot, ".second-pi"]] as const) {
74
+ fs.mkdirSync(root, { recursive: true });
75
+ fs.writeFileSync(path.join(root, "package.json"), JSON.stringify({
76
+ name: "@selesai/code",
77
+ piConfig: { configDir },
78
+ }), "utf-8");
79
+ }
80
+
81
+ process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV] = firstRoot;
82
+ assert.equal(getConfigDirName(), ".first-pi");
83
+ assert.equal(getConfigDirName(), ".first-pi");
84
+ process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV] = secondRoot;
85
+ assert.equal(getConfigDirName(), ".second-pi");
86
+ } finally {
87
+ fs.rmSync(tempDir, { recursive: true, force: true });
88
+ }
89
+ });
90
+
68
91
  it("canonicalizes watcher paths and preserves the original path when native realpath fails", () => {
69
92
  assert.equal(resolveWatchPath("C:\\SHORT~1\\watch", () => "C:\\Long Path\\watch"), "C:\\Long Path\\watch");
70
93
  assert.equal(resolveWatchPath("C:\\SHORT~1\\watch", () => { throw new Error("missing"); }), "C:\\SHORT~1\\watch");
@@ -148,6 +148,33 @@ describe("control channel: request file", () => {
148
148
  }
149
149
  });
150
150
 
151
+ it("keeps steer requests for retry when the inbox cannot be scanned", () => {
152
+ const asyncDir = tmpAsyncDir("pi-control-steer-scan-retry-");
153
+ try {
154
+ requestAsyncSteer(asyncDir, { message: "retry me", id: "retry", ts: 1 });
155
+ let failScan = true;
156
+ const fsImpl = {
157
+ existsSync: fs.existsSync,
158
+ readdirSync: ((target: fs.PathLike) => {
159
+ if (failScan) {
160
+ failScan = false;
161
+ throw Object.assign(new Error("file table overflow"), { code: "ENFILE" });
162
+ }
163
+ return fs.readdirSync(target);
164
+ }) as typeof fs.readdirSync,
165
+ readFileSync: fs.readFileSync,
166
+ rmSync: fs.rmSync,
167
+ };
168
+
169
+ assert.deepEqual(consumeSteerRequests(asyncDir, fsImpl), []);
170
+ assert.deepEqual(consumeSteerRequests(asyncDir, fsImpl), [
171
+ { type: "steer", id: "retry", ts: 1, message: "retry me" },
172
+ ]);
173
+ } finally {
174
+ cleanup(asyncDir);
175
+ }
176
+ });
177
+
151
178
  it("does not deliver a steer request if another consumer removed it first", () => {
152
179
  const asyncDir = tmpAsyncDir("pi-control-steer-concurrent-");
153
180
  try {
@@ -213,7 +213,7 @@ describe("public subagent delegation contract", () => {
213
213
  },
214
214
  executeVersioned: async (_id, params, _signal, _ctx, onUpdate) => {
215
215
  observedParams = params as unknown as Record<string, unknown>;
216
- onUpdate({ details: { mode: "single", results: [{ agent: "reviewer", model: "openai/gpt-5", thinking: "high" }], progress: [{ currentTool: "read" }] } });
216
+ onUpdate({ details: { mode: "single", runId: "run-v2", results: [{ agent: "reviewer", model: "openai/gpt-5", thinking: "high" }], progress: [{ currentTool: "read" }] } });
217
217
  return {
218
218
  details: {
219
219
  mode: "single",
@@ -223,6 +223,7 @@ describe("public subagent delegation contract", () => {
223
223
  exitCode: 0,
224
224
  model: "openai/gpt-5",
225
225
  thinking: "high",
226
+ launchContractDigest: "launch-contract-digest",
226
227
  finalOutput: '{"looks":"json"}',
227
228
  usage: { input: 2, output: 3, cacheRead: 4, cacheWrite: 5, cost: 0.01, turns: 2 },
228
229
  progressSummary: { toolCount: 6, tokens: 5, durationMs: 7 },
@@ -237,7 +238,7 @@ describe("public subagent delegation contract", () => {
237
238
  const responsePromise = once(events, SUBAGENT_DELEGATION_RESPONSE_EVENT);
238
239
  events.emit(SUBAGENT_DELEGATION_REQUEST_EVENT, textRequest);
239
240
  assert.deepEqual(await startedPromise, { version: 2, requestId: "attempt-1", ownerRunId: "owner-1", nodeId: "node-1" });
240
- assert.deepEqual(await updatePromise, { version: 2, requestId: "attempt-1", ownerRunId: "owner-1", nodeId: "node-1", currentTool: "read", model: "openai/gpt-5" });
241
+ assert.deepEqual(await updatePromise, { version: 2, requestId: "attempt-1", ownerRunId: "owner-1", nodeId: "node-1", runId: "run-v2", currentTool: "read", model: "openai/gpt-5" });
241
242
  assert.deepEqual(await responsePromise, {
242
243
  version: 2,
243
244
  requestId: "attempt-1",
@@ -249,6 +250,7 @@ describe("public subagent delegation contract", () => {
249
250
  model: "openai/gpt-5",
250
251
  thinking: "high",
251
252
  exitCode: 0,
253
+ launchContractDigest: "launch-contract-digest",
252
254
  result: { kind: "text", text: '{"looks":"json"}' },
253
255
  usage: { input: 2, output: 3, cacheRead: 4, cacheWrite: 5, cost: 0.01, turns: 2, toolCalls: 6, durationMs: 7 },
254
256
  } satisfies SubagentDelegationV2Response);
@@ -200,6 +200,7 @@ describe("dynamic fanout helpers", () => {
200
200
  const result = (agent: string, structuredOutput: unknown): SingleResult => ({
201
201
  agent,
202
202
  task: "t",
203
+ index: 0,
203
204
  exitCode: 0,
204
205
  messages: [],
205
206
  usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 },