@selesai/code 0.13.40 → 0.14.3

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 (1360) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/dist/bun/runtime-setup.js +4 -1
  3. package/dist/cli/args.d.ts +3 -1
  4. package/dist/cli/args.js +76 -33
  5. package/dist/cli/auth-check.d.ts +18 -0
  6. package/dist/cli/auth-check.js +49 -0
  7. package/dist/cli/credential-print.d.ts +5 -15
  8. package/dist/cli/credential-print.js +42 -82
  9. package/dist/cli/file-processor.d.ts +1 -1
  10. package/dist/cli/file-processor.js +2 -1
  11. package/dist/cli/list-models.d.ts +1 -1
  12. package/dist/cli/list-models.js +2 -2
  13. package/dist/cli/startup-ui.js +38 -30
  14. package/dist/config.d.ts +45 -7
  15. package/dist/config.js +134 -18
  16. package/dist/core/agent-session-custom-tools.test.js +64 -0
  17. package/dist/core/agent-session-length-continuation.test.js +7 -3
  18. package/dist/core/agent-session-runtime.js +2 -2
  19. package/dist/core/agent-session-services.d.ts +1 -0
  20. package/dist/core/agent-session-services.js +14 -0
  21. package/dist/core/agent-session.d.ts +180 -40
  22. package/dist/core/agent-session.js +1061 -485
  23. package/dist/core/auth-storage.d.ts +25 -15
  24. package/dist/core/auth-storage.js +242 -66
  25. package/dist/core/bash-executor.js +42 -52
  26. package/dist/core/bug-report.js +1 -1
  27. package/dist/core/cache-warmer.d.ts +1 -0
  28. package/dist/core/cache-warmer.js +15 -1
  29. package/dist/core/compaction/branch-summarization.js +3 -0
  30. package/dist/core/compaction/compaction.d.ts +3 -1
  31. package/dist/core/compaction/compaction.js +156 -79
  32. package/dist/core/compaction/utils.d.ts +2 -1
  33. package/dist/core/compaction/utils.js +25 -18
  34. package/dist/core/crash-log.d.ts +5 -0
  35. package/dist/core/crash-log.js +69 -0
  36. package/dist/core/defaults.d.ts +1 -1
  37. package/dist/core/defaults.js +1 -1
  38. package/dist/core/export-html/template.css +10 -0
  39. package/dist/core/export-html/template.js +72 -18
  40. package/dist/core/export-html/tool-renderer.d.ts +3 -3
  41. package/dist/core/export-html/tool-renderer.js +5 -3
  42. package/dist/core/extensions/index.d.ts +2 -2
  43. package/dist/core/extensions/index.js +1 -1
  44. package/dist/core/extensions/loader.js +138 -55
  45. package/dist/core/extensions/runner.d.ts +38 -5
  46. package/dist/core/extensions/runner.js +220 -7
  47. package/dist/core/extensions/types.d.ts +438 -51
  48. package/dist/core/extensions/types.js +3 -0
  49. package/dist/core/extensions/virtual-modules.js +6 -0
  50. package/dist/core/extensions/wrapper.d.ts +2 -2
  51. package/dist/core/extensions/wrapper.js +3 -3
  52. package/dist/core/footer-data-provider.d.ts +1 -1
  53. package/dist/core/footer-data-provider.js +1 -1
  54. package/dist/core/handoff.d.ts +0 -1
  55. package/dist/core/handoff.js +0 -1
  56. package/dist/core/http-dispatcher.js +5 -0
  57. package/dist/core/index.d.ts +1 -1
  58. package/dist/core/keybindings.d.ts +25 -24
  59. package/dist/core/keybindings.js +27 -6
  60. package/dist/core/mcp-servers.d.ts +134 -0
  61. package/dist/core/mcp-servers.js +223 -0
  62. package/dist/core/model-config.d.ts +122 -5
  63. package/dist/core/model-config.js +35 -1
  64. package/dist/core/model-registry.d.ts +23 -15
  65. package/dist/core/model-registry.js +46 -22
  66. package/dist/core/model-resolver.d.ts +6 -5
  67. package/dist/core/model-resolver.js +51 -21
  68. package/dist/core/model-runtime.d.ts +73 -14
  69. package/dist/core/model-runtime.js +398 -104
  70. package/dist/core/models-store.d.ts +12 -7
  71. package/dist/core/models-store.js +85 -15
  72. package/dist/core/nested-tool-calls.d.ts +102 -0
  73. package/dist/core/nested-tool-calls.js +178 -0
  74. package/dist/core/package-manager.d.ts +8 -1
  75. package/dist/core/package-manager.js +144 -61
  76. package/dist/core/package-manager.test.js +5 -5
  77. package/dist/core/pi-manifest.d.ts +9 -0
  78. package/dist/core/pi-manifest.js +25 -0
  79. package/dist/core/prompt-templates.d.ts +6 -1
  80. package/dist/core/prompt-templates.js +61 -35
  81. package/dist/core/provider-composer.d.ts +44 -19
  82. package/dist/core/provider-composer.js +166 -64
  83. package/dist/core/radius.d.ts +2 -0
  84. package/dist/core/radius.js +2 -0
  85. package/dist/core/remote-catalog-provider.d.ts +8 -1
  86. package/dist/core/remote-catalog-provider.js +25 -13
  87. package/dist/core/resource-loader.d.ts +9 -1
  88. package/dist/core/resource-loader.js +179 -45
  89. package/dist/core/runtime-credentials.d.ts +5 -5
  90. package/dist/core/runtime-credentials.js +11 -8
  91. package/dist/core/sdk.d.ts +16 -7
  92. package/dist/core/sdk.js +57 -24
  93. package/dist/core/session-manager.d.ts +45 -9
  94. package/dist/core/session-manager.js +124 -31
  95. package/dist/core/settings-diagnostics.d.ts +8 -0
  96. package/dist/core/settings-diagnostics.js +20 -0
  97. package/dist/core/settings-manager.d.ts +62 -32
  98. package/dist/core/settings-manager.js +147 -69
  99. package/dist/core/skills.d.ts +5 -2
  100. package/dist/core/skills.js +58 -35
  101. package/dist/core/slash-commands.js +2 -1
  102. package/dist/core/source-info.d.ts +8 -0
  103. package/dist/core/source-info.js +16 -0
  104. package/dist/core/system-prompt.d.ts +9 -3
  105. package/dist/core/system-prompt.js +9 -12
  106. package/dist/core/system-prompt.test.js +2 -7
  107. package/dist/core/tools/bash.d.ts +12 -0
  108. package/dist/core/tools/bash.js +33 -2
  109. package/dist/core/tools/edit-diff.d.ts +0 -5
  110. package/dist/core/tools/edit-diff.js +2 -5
  111. package/dist/core/tools/edit.d.ts +4 -0
  112. package/dist/core/tools/edit.js +31 -11
  113. package/dist/core/tools/find.d.ts +7 -0
  114. package/dist/core/tools/find.js +16 -19
  115. package/dist/core/tools/grep.d.ts +4 -0
  116. package/dist/core/tools/grep.js +5 -1
  117. package/dist/core/tools/index.d.ts +1 -1
  118. package/dist/core/tools/index.js +11 -2
  119. package/dist/core/tools/ls.d.ts +4 -0
  120. package/dist/core/tools/ls.js +5 -1
  121. package/dist/core/tools/output-accumulator.d.ts +11 -0
  122. package/dist/core/tools/output-accumulator.js +40 -10
  123. package/dist/core/tools/read.d.ts +17 -2
  124. package/dist/core/tools/read.js +23 -2
  125. package/dist/core/tools/render-utils.d.ts +6 -0
  126. package/dist/core/tools/render-utils.js +26 -0
  127. package/dist/core/tools/renderers/bash.js +19 -35
  128. package/dist/core/tools/renderers/edit.js +5 -4
  129. package/dist/core/tools/renderers/index.d.ts +2 -2
  130. package/dist/core/tools/renderers/read.js +3 -2
  131. package/dist/core/tools/tool-definition-wrapper.d.ts +5 -3
  132. package/dist/core/tools/tool-definition-wrapper.js +3 -1
  133. package/dist/core/tools/truncate.d.ts +14 -0
  134. package/dist/core/tools/truncate.js +29 -0
  135. package/dist/core/tools/write.d.ts +4 -0
  136. package/dist/core/tools/write.js +6 -2
  137. package/dist/core/trust-manager.js +3 -1
  138. package/dist/core/usage-totals.d.ts +2 -0
  139. package/dist/core/usage-totals.js +23 -0
  140. package/dist/core/virtual-models.d.ts +116 -0
  141. package/dist/core/virtual-models.js +123 -0
  142. package/dist/defaults/models.json +32 -0
  143. package/dist/defaults/settings.json +1 -9
  144. package/dist/extensions/codemode/execute.d.ts +15 -0
  145. package/dist/extensions/codemode/execute.js +645 -0
  146. package/dist/extensions/codemode/execute.lazy.d.ts +2 -0
  147. package/dist/extensions/codemode/execute.lazy.js +2 -0
  148. package/dist/extensions/codemode/index.d.ts +20 -0
  149. package/dist/extensions/codemode/index.js +31 -0
  150. package/dist/extensions/codemode/renderer.d.ts +11 -0
  151. package/dist/extensions/codemode/renderer.js +136 -0
  152. package/dist/extensions/codemode/tool.d.ts +129 -0
  153. package/dist/extensions/codemode/tool.js +275 -0
  154. package/dist/extensions/context-compaction-reminder.ts +1 -1
  155. package/dist/extensions/grep-app/index.ts +2 -10
  156. package/dist/extensions/herdr-agent-state.ts +1 -1
  157. package/dist/extensions/{pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts → index.d.ts} +0 -1
  158. package/dist/extensions/index.js +12 -0
  159. package/dist/extensions/jev/classifier-context.ts +54 -0
  160. package/dist/extensions/jev/classifier.test.ts +150 -0
  161. package/dist/extensions/jev/classifier.ts +191 -0
  162. package/dist/extensions/jev/decisions.test.ts +56 -47
  163. package/dist/extensions/jev/decisions.ts +94 -109
  164. package/dist/extensions/jev/test-support.ts +33 -38
  165. package/dist/extensions/jev-advisory-lifecycle.test.ts +12 -12
  166. package/dist/extensions/jev-advisory-memory.test.ts +9 -9
  167. package/dist/extensions/jev-advisory-recommendations.test.ts +8 -8
  168. package/dist/extensions/jev-ask-tool.test.ts +41 -45
  169. package/dist/extensions/jev-ask-tool.ts +11 -39
  170. package/dist/extensions/jev-find-source.test.ts +26 -0
  171. package/dist/extensions/jev-find-source.ts +58 -19
  172. package/dist/extensions/jev-tool-ranker.test.ts +185 -0
  173. package/dist/extensions/jev-tool-ranker.ts +169 -0
  174. package/dist/{core → extensions}/llama/client.d.ts +2 -0
  175. package/dist/{core → extensions}/llama/client.js +7 -3
  176. package/dist/{core → extensions}/llama/index.js +13 -2
  177. package/dist/{core → extensions}/llama/provider.d.ts +1 -1
  178. package/dist/extensions/llama/provider.js +235 -0
  179. package/dist/extensions/mcp/cli.d.ts +20 -0
  180. package/dist/extensions/mcp/cli.js +496 -0
  181. package/dist/extensions/mcp/cli.lazy.d.ts +2 -0
  182. package/dist/extensions/mcp/cli.lazy.js +2 -0
  183. package/dist/extensions/mcp/config.d.ts +83 -0
  184. package/dist/extensions/mcp/config.js +193 -0
  185. package/dist/extensions/mcp/index.d.ts +78 -0
  186. package/dist/extensions/mcp/index.js +1201 -0
  187. package/dist/extensions/mcp/log.d.ts +15 -0
  188. package/dist/extensions/mcp/log.js +65 -0
  189. package/dist/extensions/mcp/oauth.d.ts +97 -0
  190. package/dist/extensions/mcp/oauth.js +401 -0
  191. package/dist/extensions/mcp/resources.d.ts +41 -0
  192. package/dist/extensions/mcp/resources.js +260 -0
  193. package/dist/extensions/mcp/runtime.d.ts +96 -0
  194. package/dist/extensions/mcp/runtime.js +412 -0
  195. package/dist/extensions/mcp/runtime.lazy.d.ts +2 -0
  196. package/dist/extensions/mcp/runtime.lazy.js +2 -0
  197. package/dist/extensions/mcp/tools.d.ts +86 -0
  198. package/dist/extensions/mcp/tools.js +252 -0
  199. package/dist/extensions/mcp/ui.d.ts +59 -0
  200. package/dist/extensions/mcp/ui.js +185 -0
  201. package/dist/extensions/package.json +2 -1
  202. package/dist/extensions/pi-graft/index.ts +4 -19
  203. package/dist/extensions/pi-graft/lifecycle.test.ts +32 -25
  204. package/dist/extensions/pi-graft/tools.ts +6 -0
  205. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +25 -0
  206. package/dist/extensions/pi-hermes-memory/README.md +140 -4
  207. package/dist/extensions/pi-hermes-memory/package-lock.json +624 -2720
  208. package/dist/extensions/pi-hermes-memory/package.json +9 -7
  209. package/dist/extensions/pi-hermes-memory/scripts/benchmark-memory-startup.mjs +72 -0
  210. package/dist/extensions/pi-hermes-memory/scripts/check-production-install.mjs +107 -0
  211. package/dist/extensions/pi-hermes-memory/src/auto-consolidation-warning.ts +2 -1
  212. package/dist/extensions/pi-hermes-memory/src/config.ts +35 -0
  213. package/dist/extensions/pi-hermes-memory/src/constants.ts +62 -15
  214. package/dist/extensions/pi-hermes-memory/src/handlers/auto-consolidate.ts +374 -50
  215. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +7 -4
  216. package/dist/extensions/pi-hermes-memory/src/handlers/correction-detector.ts +19 -14
  217. package/dist/extensions/pi-hermes-memory/src/handlers/insights.ts +75 -1
  218. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +322 -22
  219. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +8 -0
  220. package/dist/extensions/pi-hermes-memory/src/handlers/session-flush.ts +193 -54
  221. package/dist/extensions/pi-hermes-memory/src/handlers/skills-command.ts +6 -2
  222. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +33 -5
  223. package/dist/extensions/pi-hermes-memory/src/index.ts +116 -47
  224. package/dist/extensions/pi-hermes-memory/src/memory-initialization.ts +101 -0
  225. package/dist/extensions/pi-hermes-memory/src/store/atomic-lock-coordinator.ts +10 -2
  226. package/dist/extensions/pi-hermes-memory/src/store/db.ts +34 -9
  227. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +44 -8
  228. package/dist/extensions/pi-hermes-memory/src/store/schema.ts +3 -1
  229. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +141 -0
  230. package/dist/extensions/pi-hermes-memory/src/store/standing-instructions.ts +17 -6
  231. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +20 -10
  232. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +1 -17
  233. package/dist/extensions/pi-hermes-memory/src/tools/session-search-tool.ts +2 -10
  234. package/dist/extensions/pi-hermes-memory/src/tools/skill-tool.ts +4 -8
  235. package/dist/extensions/pi-hermes-memory/src/types.ts +48 -0
  236. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +108 -0
  237. package/dist/extensions/pi-hermes-memory/tests/handlers/auto-consolidate.test.ts +1185 -42
  238. package/dist/extensions/pi-hermes-memory/tests/handlers/insights.test.ts +57 -1
  239. package/dist/extensions/pi-hermes-memory/tests/handlers/lazy-memory-hooks.test.ts +128 -0
  240. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +844 -1
  241. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +16 -0
  242. package/dist/extensions/pi-hermes-memory/tests/handlers/session-flush.test.ts +512 -3
  243. package/dist/extensions/pi-hermes-memory/tests/handlers/skills-command.test.ts +38 -0
  244. package/dist/extensions/pi-hermes-memory/tests/handlers/sync-markdown-memories.test.ts +183 -2
  245. package/dist/extensions/pi-hermes-memory/tests/handlers/system-prompt.test.ts +1 -3
  246. package/dist/extensions/pi-hermes-memory/tests/index.test.ts +17 -0
  247. package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +21 -0
  248. package/dist/extensions/pi-hermes-memory/tests/lazy-startup.test.ts +313 -0
  249. package/dist/extensions/pi-hermes-memory/tests/memory-initialization.test.ts +182 -0
  250. package/dist/extensions/pi-hermes-memory/tests/prompt-injection.test.ts +184 -0
  251. package/dist/extensions/pi-hermes-memory/tests/skill-discovery-contract.test.ts +60 -0
  252. package/dist/extensions/pi-hermes-memory/tests/store/atomic-lock-lazy-probe.test.ts +80 -0
  253. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +2 -0
  254. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +79 -0
  255. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +268 -0
  256. package/dist/extensions/pi-hermes-memory/tests/store/standing-instructions.test.ts +29 -0
  257. package/dist/extensions/pi-hermes-memory/tests/store/usage-tracking.test.ts +170 -0
  258. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +80 -1
  259. package/dist/extensions/pi-hermes-memory/tests/tools/skill-tool.test.ts +51 -0
  260. package/dist/extensions/pi-intercom/CHANGELOG.md +66 -0
  261. package/dist/extensions/pi-intercom/README.md +100 -12
  262. package/dist/extensions/pi-intercom/broker/broker.ts +28 -12
  263. package/dist/extensions/pi-intercom/broker/client.ts +3 -0
  264. package/dist/extensions/pi-intercom/broker/cross-machine-provenance.test.ts +63 -0
  265. package/dist/extensions/pi-intercom/broker/protocol.ts +64 -0
  266. package/dist/extensions/pi-intercom/broker/spawn.test.ts +58 -167
  267. package/dist/extensions/pi-intercom/broker/spawn.ts +40 -87
  268. package/dist/extensions/pi-intercom/cli.mjs +6 -0
  269. package/dist/extensions/pi-intercom/cli.test.ts +428 -0
  270. package/dist/extensions/pi-intercom/cli.ts +343 -0
  271. package/dist/extensions/pi-intercom/config.test.ts +61 -1
  272. package/dist/extensions/pi-intercom/config.ts +53 -2
  273. package/dist/extensions/pi-intercom/cross-machine-discovery.test.ts +218 -0
  274. package/dist/extensions/pi-intercom/cross-machine-discovery.ts +140 -0
  275. package/dist/extensions/pi-intercom/cross-machine-envelope.test.ts +106 -0
  276. package/dist/extensions/pi-intercom/cross-machine-envelope.ts +92 -0
  277. package/dist/extensions/pi-intercom/cross-machine-integration.test.ts +25 -0
  278. package/dist/extensions/pi-intercom/cross-machine-transport.test.ts +106 -0
  279. package/dist/extensions/pi-intercom/cross-machine-transport.ts +110 -0
  280. package/dist/extensions/pi-intercom/extension-api.ts +14 -0
  281. package/dist/extensions/pi-intercom/handover.test.ts +88 -0
  282. package/dist/extensions/pi-intercom/handover.ts +115 -0
  283. package/dist/extensions/pi-intercom/herdr-location.test.ts +173 -0
  284. package/dist/extensions/pi-intercom/herdr-location.ts +137 -0
  285. package/dist/extensions/pi-intercom/human-priority.pi.test.ts +489 -0
  286. package/dist/extensions/pi-intercom/index.ts +582 -164
  287. package/dist/extensions/pi-intercom/intercom.integration.test.ts +590 -22
  288. package/dist/extensions/pi-intercom/package.json +12 -2
  289. package/dist/extensions/pi-intercom/project-agent.ts +1 -1
  290. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +26 -2
  291. package/dist/extensions/pi-intercom/test/handover-picker.test.ts +134 -0
  292. package/dist/extensions/pi-intercom/test/inline-message.test.ts +43 -0
  293. package/dist/extensions/pi-intercom/types.d.ts +247 -0
  294. package/dist/extensions/pi-intercom/types.js +2 -0
  295. package/dist/extensions/pi-intercom/types.ts +39 -1
  296. package/dist/extensions/pi-intercom/ui/handover-picker.ts +318 -0
  297. package/dist/extensions/pi-intercom/ui/inline-message.ts +10 -3
  298. package/dist/extensions/pi-intercom/ui/session-list.ts +28 -15
  299. package/dist/extensions/pi-subagents/.github/workflows/release.yml +5 -1
  300. package/dist/extensions/pi-subagents/.github/workflows/test.yml +188 -18
  301. package/dist/extensions/pi-subagents/CHANGELOG.md +514 -1
  302. package/dist/extensions/pi-subagents/README.md +7 -5
  303. package/dist/extensions/pi-subagents/VISION.md +6 -0
  304. package/dist/extensions/pi-subagents/agents/reviewer.md +7 -5
  305. package/dist/extensions/pi-subagents/agents/worker.md +1 -1
  306. package/dist/extensions/pi-subagents/docs/agents.md +75 -35
  307. package/dist/extensions/pi-subagents/docs/configuration.md +156 -25
  308. package/dist/extensions/pi-subagents/docs/extension-api.md +113 -29
  309. package/dist/extensions/pi-subagents/docs/missions.md +46 -14
  310. package/dist/extensions/pi-subagents/docs/models.md +22 -84
  311. package/dist/extensions/pi-subagents/docs/observability.md +49 -24
  312. package/dist/extensions/pi-subagents/docs/standalone-background.md +59 -0
  313. package/dist/extensions/pi-subagents/docs/tool-reference.md +167 -116
  314. package/dist/extensions/pi-subagents/docs/watchdog.md +41 -10
  315. package/dist/extensions/pi-subagents/docs/workflows.md +239 -163
  316. package/dist/extensions/pi-subagents/examples/typed-gate/.pi/agents/classifier.md +14 -0
  317. package/dist/extensions/pi-subagents/examples/typed-gate/README.md +42 -0
  318. package/dist/extensions/pi-subagents/examples/typed-gate/classify +38 -0
  319. package/dist/extensions/pi-subagents/examples/typed-gate/workflow.js +32 -0
  320. package/dist/extensions/pi-subagents/index.ts +11 -3
  321. package/dist/extensions/pi-subagents/inspector-runner.mjs +3 -3
  322. package/dist/extensions/pi-subagents/package-lock.json +517 -1129
  323. package/dist/extensions/pi-subagents/package.json +22 -11
  324. package/dist/extensions/pi-subagents/prompts/council.md +7 -4
  325. package/dist/extensions/pi-subagents/prompts/parallel-review.md +2 -2
  326. package/dist/extensions/pi-subagents/prompts/review-loop.md +2 -2
  327. package/dist/extensions/pi-subagents/runner-peer-loader.mjs +21 -0
  328. package/dist/extensions/pi-subagents/runner-peer-preload.mjs +30 -0
  329. package/dist/extensions/pi-subagents/scripts/build-package.mjs +79 -0
  330. package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +2 -2
  331. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +46 -27
  332. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +11 -7
  333. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +78 -73
  334. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +4 -5
  335. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +10 -2
  336. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +69 -67
  337. package/dist/extensions/pi-subagents/skills/pi-subagents/references/review-and-validation.md +3 -3
  338. package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +21 -10
  339. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +113 -113
  340. package/dist/extensions/pi-subagents/src/agents/agent-memory.ts +91 -4
  341. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +15 -9
  342. package/dist/extensions/pi-subagents/src/agents/agents.ts +432 -193
  343. package/dist/extensions/pi-subagents/src/agents/chain-serializer.ts +6 -1
  344. package/dist/extensions/pi-subagents/src/agents/global-npm-root.ts +58 -0
  345. package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +5 -2
  346. package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +22 -18
  347. package/dist/extensions/pi-subagents/src/agents/skills.ts +43 -10
  348. package/dist/extensions/pi-subagents/src/api/delegation.ts +20 -1
  349. package/dist/extensions/pi-subagents/src/api/inspectors.ts +27 -0
  350. package/dist/extensions/pi-subagents/src/api/preflight.ts +140 -62
  351. package/dist/extensions/pi-subagents/src/api/required-child-extensions.ts +6 -0
  352. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -0
  353. package/dist/extensions/pi-subagents/src/extension/config.ts +24 -40
  354. package/dist/extensions/pi-subagents/src/extension/control-notices.ts +4 -1
  355. package/dist/extensions/pi-subagents/src/extension/doctor.ts +18 -15
  356. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +87 -13
  357. package/dist/extensions/pi-subagents/src/extension/herdr-pi-bridge.ts +162 -0
  358. package/dist/extensions/pi-subagents/src/extension/index.ts +280 -268
  359. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +76 -37
  360. package/dist/extensions/pi-subagents/src/extension/reply-workflow-script.ts +67 -0
  361. package/dist/extensions/pi-subagents/src/extension/rpc.ts +34 -11
  362. package/dist/extensions/pi-subagents/src/extension/schemas.ts +116 -205
  363. package/dist/extensions/pi-subagents/src/extension/subagent-guide.ts +13 -5
  364. package/dist/extensions/pi-subagents/src/extension/tool-activation.ts +146 -0
  365. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +77 -90
  366. package/dist/extensions/pi-subagents/src/extension/upgrade-notice.ts +40 -0
  367. package/dist/extensions/pi-subagents/src/inspectors/actions.ts +148 -0
  368. package/dist/extensions/pi-subagents/src/inspectors/ghostty/actions.ts +74 -0
  369. package/dist/extensions/pi-subagents/src/inspectors/ghostty/plugin.ts +29 -0
  370. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +100 -180
  371. package/dist/extensions/pi-subagents/src/inspectors/herdr/plugin.ts +20 -0
  372. package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +2 -2
  373. package/dist/extensions/pi-subagents/src/inspectors/{herdr/inspector-runner.ts → inspector-runner.ts} +13 -13
  374. package/dist/extensions/pi-subagents/src/inspectors/plugins.ts +75 -0
  375. package/dist/extensions/pi-subagents/src/inspectors/{herdr/session-roots-codec.ts → session-roots-codec.ts} +4 -15
  376. package/dist/extensions/pi-subagents/src/inspectors/{herdr/shell-command.ts → shell-command.ts} +1 -1
  377. package/dist/extensions/pi-subagents/src/inspectors/types.ts +51 -0
  378. package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +38 -53
  379. package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +53 -9
  380. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +69 -55
  381. package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +7 -2
  382. package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +45 -32
  383. package/dist/extensions/pi-subagents/src/missions/store.ts +11 -2
  384. package/dist/extensions/pi-subagents/src/policy/authority.ts +5 -1
  385. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +30 -18
  386. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +59 -9
  387. package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +18 -2
  388. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +463 -248
  389. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +106 -66
  390. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +33 -20
  391. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +47 -17
  392. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -5
  393. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +24 -11
  394. package/dist/extensions/pi-subagents/src/runs/background/await-async-run.ts +78 -0
  395. package/dist/extensions/pi-subagents/src/runs/background/binary-bootstrap.ts +66 -0
  396. package/dist/extensions/pi-subagents/src/runs/background/calendar-schedule.ts +90 -0
  397. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +2 -2
  398. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +19 -38
  399. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +62 -3
  400. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +82 -10
  401. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +259 -21
  402. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +30 -3
  403. package/dist/extensions/pi-subagents/src/runs/background/pid-namespace.ts +18 -0
  404. package/dist/extensions/pi-subagents/src/runs/background/process-terminal-candidate.ts +98 -0
  405. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +18 -97
  406. package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +14 -5
  407. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +66 -12
  408. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +4 -3
  409. package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +126 -45
  410. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +11 -6
  411. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +18 -7
  412. package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +43 -51
  413. package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +8 -1
  414. package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +5 -4
  415. package/dist/extensions/pi-subagents/src/runs/background/runner-http-dispatcher.ts +119 -0
  416. package/dist/extensions/pi-subagents/src/runs/background/runner-startup-failure.ts +56 -0
  417. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +233 -69
  418. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +67 -16
  419. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +21 -3
  420. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner-bootstrap.ts +276 -0
  421. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +592 -573
  422. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +177 -29
  423. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +77 -28
  424. package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +10 -4
  425. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +7 -13
  426. package/dist/extensions/pi-subagents/src/runs/background/workflow-terminal-proof.ts +41 -23
  427. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +19 -8
  428. package/dist/extensions/pi-subagents/src/runs/foreground/async-stop-action.ts +130 -7
  429. package/dist/extensions/pi-subagents/src/runs/foreground/command-action.ts +41 -0
  430. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +267 -385
  431. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +4 -2
  432. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +6 -10
  433. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1158 -413
  434. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +3 -1
  435. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +2 -1
  436. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +200 -74
  437. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +133 -34
  438. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +6 -1
  439. package/dist/extensions/pi-subagents/src/runs/shared/child-commands.ts +228 -0
  440. package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +18 -18
  441. package/dist/extensions/pi-subagents/src/runs/shared/child-launch-plan.ts +16 -4
  442. package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +55 -12
  443. package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +6 -3
  444. package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +11 -1
  445. package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +367 -74
  446. package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +50 -86
  447. package/dist/extensions/pi-subagents/src/runs/shared/claude-code-adapter.ts +288 -0
  448. package/dist/extensions/pi-subagents/src/runs/shared/codex-exec-adapter.ts +129 -0
  449. package/dist/extensions/pi-subagents/src/runs/shared/cursor-agent-adapter.ts +114 -0
  450. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +5 -5
  451. package/dist/extensions/pi-subagents/src/runs/shared/effective-system-prompt.ts +33 -0
  452. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-contract.ts +49 -10
  453. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +61 -9
  454. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +16 -9
  455. package/dist/extensions/pi-subagents/src/runs/shared/external-job-bridge.ts +55 -1
  456. package/dist/extensions/pi-subagents/src/runs/shared/git-environment.ts +1 -1
  457. package/dist/extensions/pi-subagents/src/runs/shared/herdr-connection.ts +134 -0
  458. package/dist/extensions/pi-subagents/src/runs/shared/herdr-external-adapters.ts +169 -0
  459. package/dist/extensions/pi-subagents/src/runs/shared/herdr-machine.ts +279 -0
  460. package/dist/extensions/pi-subagents/src/runs/shared/herdr-pi-protocol.ts +59 -0
  461. package/dist/extensions/pi-subagents/src/runs/shared/herdr-placed-run.ts +263 -0
  462. package/dist/extensions/pi-subagents/src/runs/shared/mcp-config-sources.ts +6 -2
  463. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +108 -13
  464. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-grant.ts +23 -7
  465. package/dist/extensions/pi-subagents/src/runs/shared/model-resolution-diagnostic.ts +76 -0
  466. package/dist/extensions/pi-subagents/src/runs/shared/{model-fallback.ts → model-resolution.ts} +65 -245
  467. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +30 -11
  468. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +24 -3
  469. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +5 -4
  470. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +55 -7
  471. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +14 -4
  472. package/dist/extensions/pi-subagents/src/runs/shared/partial-output.ts +48 -0
  473. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +12 -4
  474. package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +88 -1
  475. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +12 -3
  476. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +160 -9
  477. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +35 -34
  478. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +58 -19
  479. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +2 -2
  480. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +21 -0
  481. package/dist/extensions/pi-subagents/src/runs/shared/usage-reconciliation.ts +73 -0
  482. package/dist/extensions/pi-subagents/src/runs/shared/workflow-async-child-guidance.ts +18 -0
  483. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-apply.ts +160 -0
  484. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +42 -20
  485. package/dist/extensions/pi-subagents/src/runs/shared/worktree-lock.ts +29 -0
  486. package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +27 -4
  487. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +94 -26
  488. package/dist/extensions/pi-subagents/src/shared/child-cache-retention.ts +43 -0
  489. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +5 -3
  490. package/dist/extensions/pi-subagents/src/shared/disabled-features.ts +123 -0
  491. package/dist/extensions/pi-subagents/src/shared/extension-context.ts +14 -1
  492. package/dist/extensions/pi-subagents/src/shared/file-lease.ts +74 -0
  493. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +27 -77
  494. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +70 -10
  495. package/dist/extensions/pi-subagents/src/shared/model-info.ts +10 -1
  496. package/dist/extensions/pi-subagents/src/shared/opencode-session-headers.ts +30 -0
  497. package/dist/extensions/pi-subagents/src/shared/package-version.ts +17 -0
  498. package/dist/extensions/pi-subagents/src/shared/parent-wake.ts +66 -0
  499. package/dist/extensions/pi-subagents/src/shared/pruned-fork.ts +71 -58
  500. package/dist/extensions/pi-subagents/src/shared/required-child-extensions.ts +115 -0
  501. package/dist/extensions/pi-subagents/src/shared/settings-file-lease.ts +36 -0
  502. package/dist/extensions/pi-subagents/src/shared/settings.ts +7 -4
  503. package/dist/extensions/pi-subagents/src/shared/shortcuts.ts +1 -5
  504. package/dist/extensions/pi-subagents/src/shared/types.ts +146 -48
  505. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +28 -2
  506. package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +15 -1
  507. package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +19 -4
  508. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +13 -2
  509. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +15 -15
  510. package/dist/extensions/pi-subagents/src/slash/subagent-cost.ts +46 -9
  511. package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +29 -16
  512. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +201 -26
  513. package/dist/extensions/pi-subagents/src/tui/fleet.ts +33 -16
  514. package/dist/extensions/pi-subagents/src/tui/render.ts +334 -103
  515. package/dist/extensions/pi-subagents/src/tui/running-tone.ts +28 -0
  516. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +27 -28
  517. package/dist/extensions/pi-subagents/src/watchdog/diff-tool.ts +47 -12
  518. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +2 -2
  519. package/dist/extensions/pi-subagents/src/watchdog/model-selection.ts +22 -2
  520. package/dist/extensions/pi-subagents/src/watchdog/permission-arbiter.ts +17 -17
  521. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +24 -8
  522. package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +43 -39
  523. package/dist/extensions/pi-subagents/src/watchdog/render.ts +2 -2
  524. package/dist/extensions/pi-subagents/src/watchdog/review.ts +127 -78
  525. package/dist/extensions/pi-subagents/src/watchdog/rules.ts +1 -1
  526. package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +107 -31
  527. package/dist/extensions/pi-subagents/src/watchdog/scope.ts +1 -1
  528. package/dist/extensions/pi-subagents/src/watchdog/settings.ts +22 -14
  529. package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +14 -13
  530. package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +35 -6
  531. package/dist/extensions/pi-subagents/src/watchdog/types.ts +6 -4
  532. package/dist/extensions/pi-subagents/src/watchdog/warning-format.ts +2 -2
  533. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
  534. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +500 -65
  535. package/dist/extensions/pi-subagents/src/workflows/structured-workflow-scripts.ts +177 -0
  536. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +8 -2
  537. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +5 -3
  538. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +70 -10
  539. package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +57 -18
  540. package/dist/extensions/pi-subagents/src/workflows/workflow-reuse.ts +120 -0
  541. package/dist/extensions/pi-subagents/src/workflows/workflow-revival.ts +123 -0
  542. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +5 -2
  543. package/dist/extensions/pi-subagents/test/fixtures/cwd-workflow-child.ts +37 -0
  544. package/dist/extensions/pi-subagents/test/fixtures/herdr-allocation-lock-child.ts +16 -0
  545. package/dist/extensions/pi-subagents/test/fixtures/herdr-provision-child.ts +15 -0
  546. package/dist/extensions/pi-subagents/test/fixtures/native-nested-wait-provider.ts +76 -0
  547. package/dist/extensions/pi-subagents/test/fixtures/runner-bootstrap-harness.ts +36 -0
  548. package/dist/extensions/pi-subagents/test/fixtures/schedule-history-writer.mjs +48 -0
  549. package/dist/extensions/pi-subagents/test/fixtures/settings-race-writer.mjs +57 -0
  550. package/dist/extensions/pi-subagents/test/fixtures/workflow-cwd-access-failure.ts +33 -0
  551. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +40 -7
  552. package/dist/extensions/pi-subagents/test/integration/async-attention-clearing.test.ts +9 -8
  553. package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +435 -276
  554. package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +435 -397
  555. package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +918 -497
  556. package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +264 -17
  557. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +185 -22
  558. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +3 -2
  559. package/dist/extensions/pi-subagents/test/integration/claude-code-dispatch.test.ts +127 -0
  560. package/dist/extensions/pi-subagents/test/integration/deadline-checkpoint.test.ts +126 -0
  561. package/dist/extensions/pi-subagents/test/integration/doctor-executor.test.ts +29 -1
  562. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +88 -0
  563. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +450 -13
  564. package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +10 -6
  565. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +105 -86
  566. package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +403 -18
  567. package/dist/extensions/pi-subagents/test/integration/inline-workflow-visibility.test.ts +351 -0
  568. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +195 -10
  569. package/dist/extensions/pi-subagents/test/integration/model-resolution-diagnostic.test.ts +108 -0
  570. package/dist/extensions/pi-subagents/test/integration/nested-async-wait.test.ts +61 -0
  571. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +5 -4
  572. package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +1 -1
  573. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +6 -4
  574. package/dist/extensions/pi-subagents/test/integration/render-widget-mouse.test.ts +84 -0
  575. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +242 -16
  576. package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +2 -2
  577. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +158 -4
  578. package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +1435 -248
  579. package/dist/extensions/pi-subagents/test/integration/single-execution.part-2.test.ts +454 -515
  580. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +140 -21
  581. package/dist/extensions/pi-subagents/test/integration/structured-workflows.test.ts +105 -0
  582. package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +90 -11
  583. package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +18 -15
  584. package/dist/extensions/pi-subagents/test/integration/workflow-worktree-admission.test.ts +100 -0
  585. package/dist/extensions/pi-subagents/test/smoke/clean-install.mjs +106 -0
  586. package/dist/extensions/pi-subagents/test/smoke/npm-background.mjs +43 -0
  587. package/dist/extensions/pi-subagents/test/smoke/packed-runner-selection.mjs +42 -0
  588. package/dist/extensions/pi-subagents/test/smoke/runner-loader-capability.mjs +50 -0
  589. package/dist/extensions/pi-subagents/test/smoke/sdk-child.ts +57 -0
  590. package/dist/extensions/pi-subagents/test/smoke/{pi085-extension.ts → sdk-extension.ts} +2 -2
  591. package/dist/extensions/pi-subagents/test/smoke/standalone-background.mjs +140 -0
  592. package/dist/extensions/pi-subagents/test/smoke/standalone-fault.ts +43 -0
  593. package/dist/extensions/pi-subagents/test/smoke/standalone-matrix.mjs +65 -0
  594. package/dist/extensions/pi-subagents/test/smoke/standalone-observer.ts +8 -0
  595. package/dist/extensions/pi-subagents/test/smoke/standalone-parent.ts +220 -0
  596. package/dist/extensions/pi-subagents/test/smoke/standalone-provider.ts +58 -0
  597. package/dist/extensions/pi-subagents/test/smoke/standalone-release.json +8 -0
  598. package/dist/extensions/pi-subagents/test/smoke/standalone-revival.ts +109 -0
  599. package/dist/extensions/pi-subagents/test/smoke/standalone-shared.ts +79 -0
  600. package/dist/extensions/pi-subagents/test/smoke/tool-activation.test.ts +128 -0
  601. package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +6 -25
  602. package/dist/extensions/pi-subagents/test/support/async-result-timeout-evidence.ts +61 -0
  603. package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +122 -9
  604. package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +15 -7
  605. package/dist/extensions/pi-subagents/test/support/helpers.ts +11 -14
  606. package/dist/extensions/pi-subagents/test/support/isolated-temp-root.mjs +21 -3
  607. package/dist/extensions/pi-subagents/test/support/native-peer-loader.mjs +15 -0
  608. package/dist/extensions/pi-subagents/test/support/node-command.ts +29 -6
  609. package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +5 -3
  610. package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +7 -15
  611. package/dist/extensions/pi-subagents/test/support/watchdog-stable-host-loader.mjs +23 -0
  612. package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +3 -3
  613. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +158 -155
  614. package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +52 -1
  615. package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +21 -17
  616. package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +105 -36
  617. package/dist/extensions/pi-subagents/test/unit/advertisement-barrier.test.ts +151 -0
  618. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -2
  619. package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +33 -3
  620. package/dist/extensions/pi-subagents/test/unit/agent-end-auto-drain.test.ts +149 -0
  621. package/dist/extensions/pi-subagents/test/unit/agent-exclude-dirs.test.ts +246 -0
  622. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +62 -87
  623. package/dist/extensions/pi-subagents/test/unit/agent-global-root-override.test.ts +86 -0
  624. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +398 -48
  625. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +126 -1
  626. package/dist/extensions/pi-subagents/test/unit/agent-name-resolution.test.ts +75 -0
  627. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +94 -42
  628. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +73 -3
  629. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +428 -2
  630. package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +4 -4
  631. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +112 -1
  632. package/dist/extensions/pi-subagents/test/unit/async-result-timeout-evidence.test.ts +53 -0
  633. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +92 -4
  634. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +58 -6
  635. package/dist/extensions/pi-subagents/test/unit/async-run-history.test.ts +123 -0
  636. package/dist/extensions/pi-subagents/test/unit/async-spawn-package-dir.test.ts +203 -0
  637. package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +26 -35
  638. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +185 -0
  639. package/dist/extensions/pi-subagents/test/unit/authority-policy.test.ts +9 -1
  640. package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +106 -1
  641. package/dist/extensions/pi-subagents/test/unit/await-async-run.test.ts +202 -0
  642. package/dist/extensions/pi-subagents/test/unit/binary-async-spawn.test.ts +115 -0
  643. package/dist/extensions/pi-subagents/test/unit/binary-pi-spawn.test.ts +27 -0
  644. package/dist/extensions/pi-subagents/test/unit/calendar-schedule.test.ts +70 -0
  645. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +38 -0
  646. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +10 -2
  647. package/dist/extensions/pi-subagents/test/unit/changelog-format.test.ts +11 -0
  648. package/dist/extensions/pi-subagents/test/unit/child-cache-retention.test.ts +87 -0
  649. package/dist/extensions/pi-subagents/test/unit/child-commands.test.ts +243 -0
  650. package/dist/extensions/pi-subagents/test/unit/child-external-job-bridge.test.ts +126 -0
  651. package/dist/extensions/pi-subagents/test/unit/child-launch-plan.test.ts +12 -1
  652. package/dist/extensions/pi-subagents/test/unit/child-lifecycle.test.ts +36 -0
  653. package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +24 -0
  654. package/dist/extensions/pi-subagents/test/unit/child-session-commands.test.ts +162 -0
  655. package/dist/extensions/pi-subagents/test/unit/child-session-host-sdk.test.ts +226 -0
  656. package/dist/extensions/pi-subagents/test/unit/child-session-parent-providers.test.ts +200 -0
  657. package/dist/extensions/pi-subagents/test/unit/child-session-queued.test.ts +260 -0
  658. package/dist/extensions/pi-subagents/test/unit/child-tool-plan-permission-system.test.ts +3 -98
  659. package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +222 -1
  660. package/dist/extensions/pi-subagents/test/unit/claude-code-adapter.test.ts +314 -0
  661. package/dist/extensions/pi-subagents/test/unit/claude-code-dispatch.test.ts +182 -0
  662. package/dist/extensions/pi-subagents/test/unit/codex-exec-adapter.test.ts +157 -0
  663. package/dist/extensions/pi-subagents/test/unit/command-action.test.ts +50 -0
  664. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +25 -11
  665. package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +3 -1
  666. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +18 -0
  667. package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +7 -1
  668. package/dist/extensions/pi-subagents/test/unit/cursor-agent-adapter.test.ts +220 -0
  669. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +104 -32
  670. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +138 -1
  671. package/dist/extensions/pi-subagents/test/unit/disabled-features.test.ts +227 -0
  672. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +48 -9
  673. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +7 -4
  674. package/dist/extensions/pi-subagents/test/unit/extension-lazy-loading.test.ts +21 -0
  675. package/dist/extensions/pi-subagents/test/unit/extension-maintenance-lifecycle.test.ts +66 -0
  676. package/dist/extensions/pi-subagents/test/unit/extension-module-preload.test.ts +49 -0
  677. package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +104 -3
  678. package/dist/extensions/pi-subagents/test/unit/file-lease.test.ts +17 -0
  679. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +316 -0
  680. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +58 -7
  681. package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +25 -96
  682. package/dist/extensions/pi-subagents/test/unit/ghostty-inspector.test.ts +92 -0
  683. package/dist/extensions/pi-subagents/test/unit/global-npm-root.test.ts +108 -0
  684. package/dist/extensions/pi-subagents/test/unit/herdr-connection.test.ts +43 -0
  685. package/dist/extensions/pi-subagents/test/unit/herdr-external-adapters.test.ts +89 -0
  686. package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +11 -20
  687. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +113 -19
  688. package/dist/extensions/pi-subagents/test/unit/herdr-machine.test.ts +161 -0
  689. package/dist/extensions/pi-subagents/test/unit/herdr-native-placement.test.ts +187 -0
  690. package/dist/extensions/pi-subagents/test/unit/herdr-session-roots-codec.test.ts +7 -12
  691. package/dist/extensions/pi-subagents/test/unit/herdr-shell-command.test.ts +2 -2
  692. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +182 -87
  693. package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +68 -49
  694. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +295 -135
  695. package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +3 -3
  696. package/dist/extensions/pi-subagents/test/unit/inspector-authority-policy.test.ts +144 -0
  697. package/dist/extensions/pi-subagents/test/unit/inspector-registration.test.ts +128 -0
  698. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +49 -1
  699. package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-grant.test.ts +74 -1
  700. package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-resolution.test.ts +112 -0
  701. package/dist/extensions/pi-subagents/test/unit/mission-global-projection.test.ts +215 -0
  702. package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +65 -1
  703. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +2 -1
  704. package/dist/extensions/pi-subagents/test/unit/model-resolution-diagnostic.test.ts +78 -0
  705. package/dist/extensions/pi-subagents/test/unit/model-resolution.test.ts +153 -0
  706. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +43 -1
  707. package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +1 -21
  708. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +279 -2
  709. package/dist/extensions/pi-subagents/test/unit/nested-control-fanout.test.ts +73 -0
  710. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +297 -3
  711. package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +1 -1
  712. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +431 -23
  713. package/dist/extensions/pi-subagents/test/unit/opencode-session-headers.test.ts +32 -0
  714. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +89 -21
  715. package/dist/extensions/pi-subagents/test/unit/owned-process-tree.test.ts +31 -1
  716. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +18 -24
  717. package/dist/extensions/pi-subagents/test/unit/parent-wake.test.ts +206 -0
  718. package/dist/extensions/pi-subagents/test/unit/partial-output.test.ts +53 -0
  719. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +216 -32
  720. package/dist/extensions/pi-subagents/test/unit/pi-spawn-host-root.test.ts +82 -0
  721. package/dist/extensions/pi-subagents/test/unit/pi-subagents-policy-guidance.test.ts +28 -0
  722. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +193 -104
  723. package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +16 -1
  724. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +17 -1
  725. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +89 -9
  726. package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +6 -0
  727. package/dist/extensions/pi-subagents/test/unit/prompt-audit-provider-routing.test.ts +69 -0
  728. package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +2 -2
  729. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +23 -1
  730. package/dist/extensions/pi-subagents/test/unit/pruned-fork.test.ts +117 -3
  731. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +35 -14
  732. package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +3 -2
  733. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +261 -9
  734. package/dist/extensions/pi-subagents/test/unit/reply-workflow-script.test.ts +37 -0
  735. package/dist/extensions/pi-subagents/test/unit/required-child-extensions.test.ts +114 -0
  736. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +11 -1
  737. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +22 -2
  738. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +125 -18
  739. package/dist/extensions/pi-subagents/test/unit/run-child-session.test.ts +230 -0
  740. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +50 -1
  741. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +301 -4
  742. package/dist/extensions/pi-subagents/test/unit/runner-bootstrap.test.ts +182 -0
  743. package/dist/extensions/pi-subagents/test/unit/runner-http-dispatcher.test.ts +136 -0
  744. package/dist/extensions/pi-subagents/test/unit/runner-peer-loader.test.ts +68 -0
  745. package/dist/extensions/pi-subagents/test/unit/runner-peer-symlinks.test.ts +50 -0
  746. package/dist/extensions/pi-subagents/test/unit/running-tone.test.ts +13 -0
  747. package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +155 -4
  748. package/dist/extensions/pi-subagents/test/unit/schedule-claim-initialization.test.ts +71 -0
  749. package/dist/extensions/pi-subagents/test/unit/schedule-claim-preservation.test.ts +98 -0
  750. package/dist/extensions/pi-subagents/test/unit/schedule-history-transactions.test.ts +201 -0
  751. package/dist/extensions/pi-subagents/test/unit/scheduled-mission.test.ts +317 -0
  752. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +412 -11
  753. package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +2 -8
  754. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +70 -71
  755. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +748 -5
  756. package/dist/extensions/pi-subagents/test/unit/session-liveness-delivery.test.ts +337 -0
  757. package/dist/extensions/pi-subagents/test/unit/settings-atomic-save.test.ts +419 -0
  758. package/dist/extensions/pi-subagents/test/unit/settings-transactions.test.ts +88 -0
  759. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +13 -1
  760. package/dist/extensions/pi-subagents/test/unit/skills-disable-model-invocation.test.ts +164 -0
  761. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +35 -2
  762. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +2 -2
  763. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +334 -9
  764. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +170 -0
  765. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +34 -5
  766. package/dist/extensions/pi-subagents/test/unit/structured-output-validation.test.ts +199 -0
  767. package/dist/extensions/pi-subagents/test/unit/structured-workflow-resources.test.ts +241 -0
  768. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +47 -38
  769. package/dist/extensions/pi-subagents/test/unit/subagent-cost.test.ts +97 -0
  770. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +10 -0
  771. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +343 -44
  772. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +410 -11
  773. package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +459 -22
  774. package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +43 -3
  775. package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +11 -1
  776. package/dist/extensions/pi-subagents/test/unit/tool-activation-stale-peer.test.ts +32 -0
  777. package/dist/extensions/pi-subagents/test/unit/tool-activation.test.ts +313 -0
  778. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +14 -0
  779. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +76 -89
  780. package/dist/extensions/pi-subagents/test/unit/typed-gate-output.test.ts +141 -0
  781. package/dist/extensions/pi-subagents/test/unit/upgrade-notice.test.ts +31 -0
  782. package/dist/extensions/pi-subagents/test/unit/usage-reconciliation-owners.test.ts +66 -0
  783. package/dist/extensions/pi-subagents/test/unit/usage-reconciliation.test.ts +23 -0
  784. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +195 -1
  785. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +3 -1
  786. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +48 -45
  787. package/dist/extensions/pi-subagents/test/unit/watchdog-compaction-scope.test.ts +94 -0
  788. package/dist/extensions/pi-subagents/test/unit/watchdog-diff-tool.test.ts +48 -3
  789. package/dist/extensions/pi-subagents/test/unit/watchdog-native-scheduling.test.ts +107 -0
  790. package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +95 -7
  791. package/dist/extensions/pi-subagents/test/unit/watchdog-register-child.test.ts +79 -0
  792. package/dist/extensions/pi-subagents/test/unit/watchdog-render.test.ts +7 -4
  793. package/dist/extensions/pi-subagents/test/unit/watchdog-review.test.ts +111 -24
  794. package/dist/extensions/pi-subagents/test/unit/watchdog-rules.test.ts +1 -1
  795. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +283 -2
  796. package/dist/extensions/pi-subagents/test/unit/watchdog-scope.test.ts +3 -0
  797. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +12 -1
  798. package/dist/extensions/pi-subagents/test/unit/watchdog-stable-host-layout.test.ts +23 -0
  799. package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +30 -0
  800. package/dist/extensions/pi-subagents/test/unit/watchdog-turn-delta.test.ts +39 -2
  801. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +18 -1
  802. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +8 -4
  803. package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +10 -0
  804. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +6 -3
  805. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +44 -1
  806. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +28 -1
  807. package/dist/extensions/pi-subagents/test/unit/workflow-revival.test.ts +85 -0
  808. package/dist/extensions/pi-subagents/test/unit/workflow-scripts-feature.test.ts +177 -0
  809. package/dist/extensions/pi-subagents/test/unit/workflow-terminal-proof.test.ts +8 -0
  810. package/dist/extensions/pi-subagents/test/unit/workflow-worktree-admission.test.ts +29 -0
  811. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +343 -4
  812. package/dist/extensions/pi-subagents/test/unit/worktree-lock.test.ts +123 -0
  813. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +252 -22
  814. package/dist/extensions/pi-subagents/tsconfig.build.json +13 -0
  815. package/dist/extensions/pi-tool-display/tests/custom-tool-overrides.test.ts +1 -1
  816. package/dist/extensions/pi-tool-display/tests/tool-overrides-config.test.ts +1 -1
  817. package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +24 -1
  818. package/dist/extensions/pi-tool-display/tests/tool-overrides-registration.test.ts +6 -2
  819. package/dist/extensions/pi-web-agent/src/extension.ts +1 -5
  820. package/dist/extensions/pi-zentui/.github/workflows/ci.yml +67 -4
  821. package/dist/extensions/pi-zentui/AGENTS.md +3 -2
  822. package/dist/extensions/pi-zentui/README.md +60 -32
  823. package/dist/extensions/pi-zentui/docs/configuration.md +662 -51
  824. package/dist/extensions/pi-zentui/docs/footer-format.md +174 -5
  825. package/dist/extensions/pi-zentui/extensions/zentui/accent-rail-editor.ts +15 -4
  826. package/dist/extensions/pi-zentui/extensions/zentui/average-token-rate.ts +146 -0
  827. package/dist/extensions/pi-zentui/extensions/zentui/codex-quota-display.ts +34 -0
  828. package/dist/extensions/pi-zentui/extensions/zentui/codex-quota.ts +298 -0
  829. package/dist/extensions/pi-zentui/extensions/zentui/component-colors.ts +172 -0
  830. package/dist/extensions/pi-zentui/extensions/zentui/component-settings.ts +243 -0
  831. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +851 -114
  832. package/dist/extensions/pi-zentui/extensions/zentui/custom-value-colors.ts +93 -0
  833. package/dist/extensions/pi-zentui/extensions/zentui/custom-variable-demand.ts +61 -0
  834. package/dist/extensions/pi-zentui/extensions/zentui/custom-variable-format.ts +80 -0
  835. package/dist/extensions/pi-zentui/extensions/zentui/custom-variables.ts +152 -0
  836. package/dist/extensions/pi-zentui/extensions/zentui/editor-metadata-format.ts +138 -23
  837. package/dist/extensions/pi-zentui/extensions/zentui/editor-mouse.ts +89 -0
  838. package/dist/extensions/pi-zentui/extensions/zentui/extension-status-controller.ts +148 -0
  839. package/dist/extensions/pi-zentui/extensions/zentui/extension-status-settings.ts +40 -0
  840. package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +109 -1
  841. package/dist/extensions/pi-zentui/extensions/zentui/footer-format.ts +203 -23
  842. package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +80 -3
  843. package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +1 -1
  844. package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +432 -125
  845. package/dist/extensions/pi-zentui/extensions/zentui/format.ts +92 -4
  846. package/dist/extensions/pi-zentui/extensions/zentui/git.ts +47 -30
  847. package/dist/extensions/pi-zentui/extensions/zentui/github-status.ts +575 -0
  848. package/dist/extensions/pi-zentui/extensions/zentui/host-project-changes.ts +25 -0
  849. package/dist/extensions/pi-zentui/extensions/zentui/host-template-values.ts +29 -0
  850. package/dist/extensions/pi-zentui/extensions/zentui/icons.ts +53 -13
  851. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +778 -258
  852. package/dist/extensions/pi-zentui/extensions/zentui/interaction-summary.ts +70 -5
  853. package/dist/extensions/pi-zentui/extensions/zentui/layered-editor.ts +55 -0
  854. package/dist/extensions/pi-zentui/extensions/zentui/live-context.ts +6 -1
  855. package/dist/extensions/pi-zentui/extensions/zentui/live-metadata-demand.ts +72 -0
  856. package/dist/extensions/pi-zentui/extensions/zentui/live-metadata-display.ts +21 -0
  857. package/dist/extensions/pi-zentui/extensions/zentui/live-metadata.ts +255 -0
  858. package/dist/extensions/pi-zentui/extensions/zentui/minimalist-editor.ts +476 -36
  859. package/dist/extensions/pi-zentui/extensions/zentui/minimalist-settings.ts +118 -0
  860. package/dist/extensions/pi-zentui/extensions/zentui/minimalist-template.ts +177 -0
  861. package/dist/extensions/pi-zentui/extensions/zentui/omp-editor-frame.ts +148 -0
  862. package/dist/extensions/pi-zentui/extensions/zentui/omp-statusline.ts +569 -0
  863. package/dist/extensions/pi-zentui/extensions/zentui/omp-template-lookups.ts +344 -0
  864. package/dist/extensions/pi-zentui/extensions/zentui/omp-template-metrics.ts +91 -0
  865. package/dist/extensions/pi-zentui/extensions/zentui/omp-template-modes.ts +323 -0
  866. package/dist/extensions/pi-zentui/extensions/zentui/omp-ui.ts +210 -0
  867. package/dist/extensions/pi-zentui/extensions/zentui/package-version.ts +30 -12
  868. package/dist/extensions/pi-zentui/extensions/zentui/project-demand.ts +46 -0
  869. package/dist/extensions/pi-zentui/extensions/zentui/project-discovery.ts +58 -0
  870. package/dist/extensions/pi-zentui/extensions/zentui/project-refresh.ts +10 -3
  871. package/dist/extensions/pi-zentui/extensions/zentui/project-state.ts +37 -0
  872. package/dist/extensions/pi-zentui/extensions/zentui/repository-root.ts +1 -0
  873. package/dist/extensions/pi-zentui/extensions/zentui/runtime.ts +119 -43
  874. package/dist/extensions/pi-zentui/extensions/zentui/selector-border.ts +40 -29
  875. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +1268 -722
  876. package/dist/extensions/pi-zentui/extensions/zentui/settings-keys.ts +59 -0
  877. package/dist/extensions/pi-zentui/extensions/zentui/settings-list-selection.ts +13 -0
  878. package/dist/extensions/pi-zentui/extensions/zentui/settings-previews.ts +11 -4
  879. package/dist/extensions/pi-zentui/extensions/zentui/state.ts +24 -11
  880. package/dist/extensions/pi-zentui/extensions/zentui/style.ts +6 -0
  881. package/dist/extensions/pi-zentui/extensions/zentui/telemetry.ts +113 -11
  882. package/dist/extensions/pi-zentui/extensions/zentui/thinking-experimental.ts +234 -46
  883. package/dist/extensions/pi-zentui/extensions/zentui/thinking-steps.ts +20 -5
  884. package/dist/extensions/pi-zentui/extensions/zentui/token-rate.ts +313 -0
  885. package/dist/extensions/pi-zentui/extensions/zentui/turn-summary-format.ts +59 -0
  886. package/dist/extensions/pi-zentui/extensions/zentui/turn-summary-rate.ts +52 -0
  887. package/dist/extensions/pi-zentui/extensions/zentui/ui.ts +640 -172
  888. package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +72 -34
  889. package/dist/extensions/pi-zentui/extensions/zentui/user-message.ts +219 -34
  890. package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +495 -119
  891. package/dist/extensions/pi-zentui/omp.ts +157 -0
  892. package/dist/extensions/pi-zentui/package-lock.json +3762 -1507
  893. package/dist/extensions/pi-zentui/package.json +50 -12
  894. package/dist/extensions/pi-zentui/test/accent-rail-editor.test.ts +13 -2
  895. package/dist/extensions/pi-zentui/test/average-token-rate.test.ts +297 -0
  896. package/dist/extensions/pi-zentui/test/behavior-compatibility.mjs +89 -0
  897. package/dist/extensions/pi-zentui/test/codex-quota-lifecycle.test.ts +284 -0
  898. package/dist/extensions/pi-zentui/test/codex-quota-rendering.test.ts +466 -0
  899. package/dist/extensions/pi-zentui/test/codex-quota.test.ts +440 -0
  900. package/dist/extensions/pi-zentui/test/component-colors.test.ts +554 -0
  901. package/dist/extensions/pi-zentui/test/component-settings.test.ts +364 -0
  902. package/dist/extensions/pi-zentui/test/config-component-independence.test.ts +402 -0
  903. package/dist/extensions/pi-zentui/test/config-extension-status-choice.test.ts +233 -0
  904. package/dist/extensions/pi-zentui/test/config-hidden-extension-status-colors.test.ts +118 -0
  905. package/dist/extensions/pi-zentui/test/config-hidden-extension-status-placement.test.ts +142 -0
  906. package/dist/extensions/pi-zentui/test/config-minimalist-templates.test.ts +240 -0
  907. package/dist/extensions/pi-zentui/test/config-template-variables.test.ts +85 -0
  908. package/dist/extensions/pi-zentui/test/config.test.ts +80 -17
  909. package/dist/extensions/pi-zentui/test/custom-value-colors-integration.test.ts +453 -0
  910. package/dist/extensions/pi-zentui/test/custom-value-colors.test.ts +399 -0
  911. package/dist/extensions/pi-zentui/test/custom-variable-alias-prototypes.test.ts +177 -0
  912. package/dist/extensions/pi-zentui/test/custom-variable-consumers.test.ts +194 -0
  913. package/dist/extensions/pi-zentui/test/custom-variable-demand.test.ts +169 -0
  914. package/dist/extensions/pi-zentui/test/custom-variable-probe-reservation.test.ts +141 -0
  915. package/dist/extensions/pi-zentui/test/custom-variables-lifecycle.integration.test.ts +365 -0
  916. package/dist/extensions/pi-zentui/test/custom-variables.test.ts +330 -0
  917. package/dist/extensions/pi-zentui/test/editor-metadata-format.test.ts +121 -0
  918. package/dist/extensions/pi-zentui/test/editor-mouse.test.ts +507 -0
  919. package/dist/extensions/pi-zentui/test/editor-viewport-indicators.test.ts +247 -20
  920. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +204 -260
  921. package/dist/extensions/pi-zentui/test/extension-status-controller.test.ts +323 -0
  922. package/dist/extensions/pi-zentui/test/extension-status-lifecycle.integration.test.ts +466 -0
  923. package/dist/extensions/pi-zentui/test/extension-status-settings.test.ts +79 -0
  924. package/dist/extensions/pi-zentui/test/footer-alignment.test.ts +135 -0
  925. package/dist/extensions/pi-zentui/test/footer-authority.test.ts +69 -0
  926. package/dist/extensions/pi-zentui/test/footer-auto-compaction.test.ts +148 -0
  927. package/dist/extensions/pi-zentui/test/footer-format-cache.test.ts +186 -0
  928. package/dist/extensions/pi-zentui/test/footer-format.test.ts +154 -4
  929. package/dist/extensions/pi-zentui/test/footer-hidden.test.ts +312 -0
  930. package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +22 -0
  931. package/dist/extensions/pi-zentui/test/footer-layout.test.ts +80 -0
  932. package/dist/extensions/pi-zentui/test/footer-thinking-level.test.ts +123 -0
  933. package/dist/extensions/pi-zentui/test/format.test.ts +75 -1
  934. package/dist/extensions/pi-zentui/test/git-probes.test.ts +182 -0
  935. package/dist/extensions/pi-zentui/test/github-status.test.ts +931 -0
  936. package/dist/extensions/pi-zentui/test/host-template-surfaces.test.ts +287 -0
  937. package/dist/extensions/pi-zentui/test/icons.test.ts +86 -16
  938. package/dist/extensions/pi-zentui/test/layered-editor.test.ts +53 -0
  939. package/dist/extensions/pi-zentui/test/live-context-integration.test.ts +154 -7
  940. package/dist/extensions/pi-zentui/test/live-context.test.ts +45 -0
  941. package/dist/extensions/pi-zentui/test/live-metadata-lifecycle.integration.test.ts +963 -0
  942. package/dist/extensions/pi-zentui/test/live-metadata.test.ts +767 -0
  943. package/dist/extensions/pi-zentui/test/minimalist-cache-hit-colors.test.ts +183 -0
  944. package/dist/extensions/pi-zentui/test/minimalist-editor.test.ts +222 -4
  945. package/dist/extensions/pi-zentui/test/minimalist-settings.test.ts +103 -0
  946. package/dist/extensions/pi-zentui/test/minimalist-templates.test.ts +489 -0
  947. package/dist/extensions/pi-zentui/test/omp-editor-composers.test.ts +324 -0
  948. package/dist/extensions/pi-zentui/test/omp-statusline.test.ts +579 -0
  949. package/dist/extensions/pi-zentui/test/omp-template-lookups.test.ts +630 -0
  950. package/dist/extensions/pi-zentui/test/omp-template-metrics.test.ts +72 -0
  951. package/dist/extensions/pi-zentui/test/omp-template-modes.test.ts +557 -0
  952. package/dist/extensions/pi-zentui/test/omp-ui.test.ts +93 -0
  953. package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
  954. package/dist/extensions/pi-zentui/test/pi-version-policy.test.ts +37 -0
  955. package/dist/extensions/pi-zentui/test/project-demand-integration.test.ts +542 -0
  956. package/dist/extensions/pi-zentui/test/project-discovery.test.ts +412 -0
  957. package/dist/extensions/pi-zentui/test/project-refresh.test.ts +44 -0
  958. package/dist/extensions/pi-zentui/test/project-state.test.ts +38 -1
  959. package/dist/extensions/pi-zentui/test/responsive-dependencies.test.ts +7 -7
  960. package/dist/extensions/pi-zentui/test/runtime.test.ts +127 -2
  961. package/dist/extensions/pi-zentui/test/selesai-v030-gate.json +939 -0
  962. package/dist/extensions/pi-zentui/test/settings-command.test.ts +1330 -82
  963. package/dist/extensions/pi-zentui/test/settings-keys.test.ts +41 -0
  964. package/dist/extensions/pi-zentui/test/settings-list-selection.test.ts +88 -0
  965. package/dist/extensions/pi-zentui/test/settings-previews.test.ts +4 -1
  966. package/dist/extensions/pi-zentui/test/state.test.ts +15 -1
  967. package/dist/extensions/pi-zentui/test/telemetry-lifecycle-integration.test.ts +214 -12
  968. package/dist/extensions/pi-zentui/test/telemetry-snapshot.test.ts +246 -0
  969. package/dist/extensions/pi-zentui/test/thinking-experimental-cache.test.ts +246 -0
  970. package/dist/extensions/pi-zentui/test/thinking-experimental-rows.test.ts +22 -0
  971. package/dist/extensions/pi-zentui/test/thinking-experimental-tui.mjs +113 -51
  972. package/dist/extensions/pi-zentui/test/thinking-experimental.test.ts +576 -76
  973. package/dist/extensions/pi-zentui/test/thinking-steps.test.ts +23 -0
  974. package/dist/extensions/pi-zentui/test/token-rate.test.ts +450 -0
  975. package/dist/extensions/pi-zentui/test/turn-summary-format.test.ts +207 -0
  976. package/dist/extensions/pi-zentui/test/turn-summary-lifecycle.integration.test.ts +72 -5
  977. package/dist/extensions/pi-zentui/test/turn-summary-rate.test.ts +158 -0
  978. package/dist/extensions/pi-zentui/test/usage-lifecycle-integration.test.ts +421 -0
  979. package/dist/extensions/pi-zentui/test/usage-snapshot.test.ts +154 -0
  980. package/dist/extensions/pi-zentui/test/user-message-cache.test.ts +239 -0
  981. package/dist/extensions/pi-zentui/test/user-message-native-reduced-capabilities.test.ts +61 -0
  982. package/dist/extensions/pi-zentui/test/user-message-native.test.ts +447 -0
  983. package/dist/extensions/pi-zentui/test/user-message-styles.test.ts +2 -2
  984. package/dist/extensions/pi-zentui/test/working-line-editor-placement.test.ts +317 -0
  985. package/dist/extensions/pi-zentui/test/working-line-generation-cache.test.ts +238 -0
  986. package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +674 -179
  987. package/dist/extensions/pi-zentui/test/working-line-message-ownership.test.ts +239 -0
  988. package/dist/extensions/pi-zentui/test/working-line-metric-animation.test.ts +284 -0
  989. package/dist/extensions/pi-zentui/test/working-line-placement.test.ts +298 -0
  990. package/dist/extensions/pi-zentui/test/working-line.test.ts +386 -18
  991. package/dist/extensions/pi-zentui/test/wrapped-editor-consumers.integration.test.ts +579 -0
  992. package/dist/extensions/pi-zentui/test/wrapped-editor-usage.integration.test.ts +298 -0
  993. package/dist/extensions/pi-zentui/tsconfig.json +1 -1
  994. package/dist/extensions/pi-zentui/vitest.host.config.ts +33 -0
  995. package/dist/extensions/question/index.ts +1 -5
  996. package/dist/extensions/rtk.test.ts +28 -15
  997. package/dist/extensions/rtk.ts +22 -22
  998. package/dist/extensions/skills-index/index.test.ts +99 -0
  999. package/dist/extensions/skills-index/index.ts +105 -0
  1000. package/dist/extensions/skills-index/package.json +9 -0
  1001. package/dist/extensions/tokenin-onboarding.ts +48 -208
  1002. package/dist/extensions/tool-search/index.d.ts +11 -0
  1003. package/dist/extensions/tool-search/index.js +14 -0
  1004. package/dist/extensions/tool-search/tool.d.ts +91 -0
  1005. package/dist/extensions/tool-search/tool.js +214 -0
  1006. package/dist/index.d.ts +17 -9
  1007. package/dist/index.js +11 -5
  1008. package/dist/main.d.ts +4 -0
  1009. package/dist/main.js +106 -42
  1010. package/dist/migrations.js +4 -3
  1011. package/dist/modes/index.d.ts +1 -0
  1012. package/dist/modes/interactive/bug-report.js +4 -0
  1013. package/dist/modes/interactive/components/armin.d.ts +3 -0
  1014. package/dist/modes/interactive/components/armin.js +7 -5
  1015. package/dist/modes/interactive/components/assistant-message.js +1 -1
  1016. package/dist/modes/interactive/components/auth-url.d.ts +13 -0
  1017. package/dist/modes/interactive/components/auth-url.js +36 -0
  1018. package/dist/modes/interactive/components/bash-execution.d.ts +5 -1
  1019. package/dist/modes/interactive/components/bash-execution.js +17 -14
  1020. package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
  1021. package/dist/modes/interactive/components/branch-summary-message.js +5 -2
  1022. package/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -1
  1023. package/dist/modes/interactive/components/compaction-summary-message.js +5 -2
  1024. package/dist/modes/interactive/components/config-selector.js +13 -3
  1025. package/dist/modes/interactive/components/custom-editor.js +7 -0
  1026. package/dist/modes/interactive/components/custom-entry.d.ts +3 -1
  1027. package/dist/modes/interactive/components/custom-entry.js +8 -2
  1028. package/dist/modes/interactive/components/custom-message.js +1 -0
  1029. package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
  1030. package/dist/modes/interactive/components/first-time-setup.js +8 -2
  1031. package/dist/modes/interactive/components/footer.d.ts +7 -0
  1032. package/dist/modes/interactive/components/footer.js +44 -4
  1033. package/dist/modes/interactive/components/index.d.ts +0 -1
  1034. package/dist/modes/interactive/components/index.js +0 -1
  1035. package/dist/modes/interactive/components/login-dialog.d.ts +2 -0
  1036. package/dist/modes/interactive/components/login-dialog.js +11 -5
  1037. package/dist/modes/interactive/components/mermaid.d.ts +10 -0
  1038. package/dist/modes/interactive/components/mermaid.js +74 -0
  1039. package/dist/modes/interactive/components/model-selector.d.ts +14 -9
  1040. package/dist/modes/interactive/components/model-selector.js +79 -31
  1041. package/dist/modes/interactive/components/oauth-selector.d.ts +8 -2
  1042. package/dist/modes/interactive/components/oauth-selector.js +24 -21
  1043. package/dist/modes/interactive/components/pi-logo.d.ts +18 -0
  1044. package/dist/modes/interactive/components/pi-logo.js +36 -0
  1045. package/dist/modes/interactive/components/radius-login-selector.d.ts +14 -0
  1046. package/dist/modes/interactive/components/radius-login-selector.js +84 -0
  1047. package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
  1048. package/dist/modes/interactive/components/scoped-models-selector.js +26 -0
  1049. package/dist/modes/interactive/components/settings-selector.d.ts +8 -11
  1050. package/dist/modes/interactive/components/settings-selector.js +60 -102
  1051. package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
  1052. package/dist/modes/interactive/components/skill-invocation-message.js +5 -2
  1053. package/dist/modes/interactive/components/themed-text.d.ts +16 -0
  1054. package/dist/modes/interactive/components/themed-text.js +28 -0
  1055. package/dist/modes/interactive/components/tool-execution.d.ts +11 -18
  1056. package/dist/modes/interactive/components/tool-execution.js +34 -47
  1057. package/dist/modes/interactive/components/tree-selector.js +7 -0
  1058. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  1059. package/dist/modes/interactive/components/user-message.js +14 -6
  1060. package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
  1061. package/dist/modes/interactive/components/visual-truncate.js +39 -6
  1062. package/dist/modes/interactive/external-editor.js +2 -1
  1063. package/dist/modes/interactive/interactive-mode.d.ts +41 -8
  1064. package/dist/modes/interactive/interactive-mode.js +854 -492
  1065. package/dist/modes/interactive/program-status-reporter.d.ts +33 -0
  1066. package/dist/modes/interactive/program-status-reporter.js +109 -0
  1067. package/dist/modes/interactive/theme/dark.json +59 -72
  1068. package/dist/modes/interactive/theme/light.json +57 -69
  1069. package/dist/modes/interactive/theme/system-theme.d.ts +54 -0
  1070. package/dist/modes/interactive/theme/system-theme.js +545 -0
  1071. package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
  1072. package/dist/modes/interactive/theme/theme-controller.js +127 -47
  1073. package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
  1074. package/dist/modes/interactive/theme/theme-json.js +3 -1
  1075. package/dist/modes/interactive/theme/theme-schema.json +7 -2
  1076. package/dist/modes/interactive/theme/theme.d.ts +66 -39
  1077. package/dist/modes/interactive/theme/theme.js +243 -320
  1078. package/dist/modes/interactive/tui-renderer.d.ts +2 -1
  1079. package/dist/modes/interactive/tui-renderer.js +1 -0
  1080. package/dist/modes/json-event.d.ts +33 -0
  1081. package/dist/modes/json-event.js +28 -0
  1082. package/dist/modes/print-mode.js +12 -2
  1083. package/dist/modes/rpc/rpc-client.d.ts +11 -19
  1084. package/dist/modes/rpc/rpc-client.js +52 -35
  1085. package/dist/modes/rpc/rpc-mode.js +11 -26
  1086. package/dist/modes/rpc/rpc-types.d.ts +12 -23
  1087. package/dist/package-manager-cli.js +16 -5
  1088. package/dist/rpc-entry.js +1 -0
  1089. package/dist/skills/pi-subagents/SKILL.md +109 -35
  1090. package/dist/skills/pi-subagents/references/constraints-and-recipes.md +38 -238
  1091. package/dist/skills/pi-subagents/references/execution-controls.md +181 -83
  1092. package/dist/skills/pi-subagents/references/management-authoring-rpc.md +9 -9
  1093. package/dist/skills/pi-subagents/references/multi-lane-orchestration.md +24 -2
  1094. package/dist/skills/pi-subagents/references/prompting-and-roles.md +121 -91
  1095. package/dist/skills/pi-subagents/references/review-and-validation.md +73 -0
  1096. package/dist/utils/ansi.d.ts +8 -0
  1097. package/dist/utils/ansi.js +30 -11
  1098. package/dist/utils/clipboard-image.js +14 -17
  1099. package/dist/utils/clipboard.d.ts +2 -0
  1100. package/dist/utils/clipboard.js +17 -11
  1101. package/dist/utils/frontmatter.js +2 -1
  1102. package/dist/utils/image-convert.d.ts +12 -0
  1103. package/dist/utils/image-convert.js +45 -6
  1104. package/dist/utils/image-resize-core.d.ts +12 -0
  1105. package/dist/utils/image-resize-core.js +5 -0
  1106. package/dist/utils/image-resize-worker.js +3 -2
  1107. package/dist/utils/image-resize.js +9 -10
  1108. package/dist/utils/mime.js +1 -1
  1109. package/dist/utils/output-files.d.ts +14 -0
  1110. package/dist/utils/output-files.js +29 -0
  1111. package/dist/utils/paths.d.ts +6 -3
  1112. package/dist/utils/paths.js +28 -5
  1113. package/dist/utils/shell.d.ts +1 -3
  1114. package/dist/utils/shell.js +3 -30
  1115. package/dist/utils/syntax-highlight.d.ts +1 -0
  1116. package/dist/utils/syntax-highlight.js +68 -2
  1117. package/dist/utils/tool-result-images.d.ts +20 -0
  1118. package/dist/utils/tool-result-images.js +47 -0
  1119. package/dist/utils/tools-manager.d.ts +5 -0
  1120. package/dist/utils/tools-manager.js +6 -6
  1121. package/dist/utils/version-check.d.ts +4 -0
  1122. package/dist/utils/version-check.js +20 -2
  1123. package/docs/cli-integration.md +104 -0
  1124. package/docs/cli.md +333 -0
  1125. package/docs/codemode.md +230 -0
  1126. package/docs/configuration.md +47 -0
  1127. package/docs/environment-variables.md +5 -0
  1128. package/docs/extensions.md +107 -30
  1129. package/docs/json.md +8 -4
  1130. package/docs/keybindings.md +10 -10
  1131. package/docs/mcp.md +262 -0
  1132. package/docs/models.md +104 -3
  1133. package/docs/providers.md +20 -2
  1134. package/docs/rpc.md +13 -12
  1135. package/docs/sdk.md +41 -33
  1136. package/docs/security.md +21 -20
  1137. package/docs/settings.md +18 -46
  1138. package/docs/terminal-setup.md +14 -0
  1139. package/docs/virtual-models.md +114 -0
  1140. package/examples/extensions/jev-router.ts +113 -0
  1141. package/examples/extensions/tokenin-usage-widget.ts +124 -0
  1142. package/examples/rpc-client.ts +35 -0
  1143. package/examples/sdk/14-codemode-mcp.ts +67 -0
  1144. package/package.json +15 -8
  1145. package/dist/core/agent-session-auto-handoff.test.js +0 -195
  1146. package/dist/core/built-in-extensions.d.ts +0 -2
  1147. package/dist/core/built-in-extensions.js +0 -2
  1148. package/dist/core/llama/provider.js +0 -143
  1149. package/dist/core/settings-manager-auto-handoff.test.d.ts +0 -1
  1150. package/dist/core/settings-manager-auto-handoff.test.js +0 -53
  1151. package/dist/extensions/capability-gateway/catalog.ts +0 -177
  1152. package/dist/extensions/capability-gateway/index.test.ts +0 -226
  1153. package/dist/extensions/capability-gateway/index.ts +0 -669
  1154. package/dist/extensions/capability-gateway/integration.test.ts +0 -803
  1155. package/dist/extensions/capability-gateway/package.json +0 -16
  1156. package/dist/extensions/capability-gateway/routing.test.ts +0 -574
  1157. package/dist/extensions/capability-gateway/routing.ts +0 -403
  1158. package/dist/extensions/pi-subagents/runner-server-preload.mjs +0 -13
  1159. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +0 -89
  1160. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +0 -259
  1161. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +0 -312
  1162. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +0 -374
  1163. package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +0 -69
  1164. package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +0 -307
  1165. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +0 -211
  1166. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +0 -3
  1167. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +0 -2
  1168. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +0 -17
  1169. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +0 -57
  1170. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +0 -16
  1171. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +0 -15
  1172. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +0 -18
  1173. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +0 -9
  1174. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +0 -10
  1175. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +0 -10
  1176. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +0 -20
  1177. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +0 -3
  1178. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +0 -96
  1179. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +0 -119
  1180. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +0 -85
  1181. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +0 -620
  1182. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +0 -5
  1183. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +0 -56
  1184. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +0 -32
  1185. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +0 -49
  1186. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +0 -93
  1187. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +0 -128
  1188. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +0 -7
  1189. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +0 -38
  1190. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +0 -3
  1191. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +0 -15
  1192. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +0 -9
  1193. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +0 -29
  1194. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +0 -2
  1195. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +0 -22
  1196. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +0 -37
  1197. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +0 -34
  1198. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +0 -12
  1199. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +0 -23
  1200. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +0 -171
  1201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +0 -1261
  1202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +0 -20
  1203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +0 -54
  1204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +0 -22
  1205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +0 -13
  1206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +0 -358
  1207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +0 -77
  1208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +0 -512
  1209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +0 -43
  1210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +0 -121
  1211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +0 -82
  1212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +0 -17
  1213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +0 -7
  1214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +0 -210
  1215. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +0 -15
  1216. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +0 -54
  1217. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +0 -4
  1218. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +0 -55
  1219. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +0 -2
  1220. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +0 -5
  1221. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +0 -30
  1222. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +0 -206
  1223. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +0 -15
  1224. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +0 -106
  1225. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +0 -19
  1226. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +0 -356
  1227. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +0 -297
  1228. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +0 -60
  1229. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +0 -15
  1230. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +0 -18
  1231. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +0 -28
  1232. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +0 -3
  1233. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +0 -10
  1234. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +0 -68
  1235. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +0 -106
  1236. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +0 -51
  1237. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +0 -6
  1238. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +0 -35
  1239. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +0 -37
  1240. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +0 -40
  1241. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +0 -37
  1242. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +0 -52
  1243. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +0 -10
  1244. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +0 -35
  1245. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +0 -24
  1246. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +0 -14
  1247. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +0 -70
  1248. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +0 -26
  1249. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +0 -36
  1250. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +0 -19
  1251. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +0 -61
  1252. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +0 -23
  1253. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +0 -3
  1254. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +0 -10
  1255. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +0 -42
  1256. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +0 -35
  1257. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +0 -12
  1258. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +0 -33
  1259. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +0 -9
  1260. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +0 -34
  1261. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +0 -22
  1262. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +0 -34
  1263. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +0 -16
  1264. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +0 -16
  1265. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +0 -16
  1266. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +0 -102
  1267. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +0 -14
  1268. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +0 -21
  1269. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +0 -19
  1270. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +0 -20
  1271. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +0 -23
  1272. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +0 -12
  1273. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +0 -15
  1274. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +0 -5
  1275. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +0 -22
  1276. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +0 -23
  1277. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +0 -26
  1278. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +0 -25
  1279. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +0 -32
  1280. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +0 -34
  1281. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +0 -13
  1282. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +0 -52
  1283. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +0 -54
  1284. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +0 -33
  1285. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +0 -42
  1286. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +0 -23
  1287. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +0 -95
  1288. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +0 -77
  1289. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +0 -10
  1290. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +0 -17
  1291. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +0 -28
  1292. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +0 -11
  1293. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +0 -11
  1294. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +0 -63
  1295. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +0 -94
  1296. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +0 -23
  1297. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +0 -30
  1298. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +0 -14
  1299. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +0 -24
  1300. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +0 -394
  1301. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +0 -12
  1302. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +0 -29
  1303. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +0 -120
  1304. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +0 -28
  1305. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +0 -17
  1306. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +0 -246
  1307. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +0 -20
  1308. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +0 -457
  1309. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +0 -8
  1310. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +0 -3
  1311. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +0 -2
  1312. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +0 -22
  1313. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +0 -18
  1314. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +0 -11
  1315. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +0 -11
  1316. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +0 -4
  1317. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +0 -4
  1318. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +0 -5
  1319. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +0 -8
  1320. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +0 -5
  1321. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +0 -26
  1322. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +0 -7
  1323. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +0 -10
  1324. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +0 -18
  1325. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +0 -30
  1326. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +0 -2
  1327. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +0 -16
  1328. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +0 -3
  1329. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +0 -3
  1330. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +0 -9
  1331. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +0 -31
  1332. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +0 -21
  1333. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +0 -2
  1334. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +0 -31
  1335. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +0 -5
  1336. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +0 -12
  1337. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +0 -3
  1338. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +0 -15
  1339. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +0 -3
  1340. package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +0 -31
  1341. package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +0 -74
  1342. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +0 -150
  1343. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +0 -766
  1344. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +0 -327
  1345. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +0 -309
  1346. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +0 -1093
  1347. package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +0 -94
  1348. package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +0 -1329
  1349. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +0 -153
  1350. package/dist/extensions/pi-zentui/extensions/zentui/accent-rail-layout-patch.ts +0 -457
  1351. package/dist/extensions/pi-zentui/test/accent-rail-layout-patch.test.ts +0 -669
  1352. package/dist/extensions/pi-zentui/test/thinking-experimental-docs.test.ts +0 -51
  1353. package/dist/modes/interactive/components/daxnuts.d.ts +0 -22
  1354. package/dist/modes/interactive/components/daxnuts.js +0 -139
  1355. /package/dist/core/{agent-session-auto-handoff.test.d.ts → agent-session-custom-tools.test.d.ts} +0 -0
  1356. /package/dist/{core → extensions}/llama/huggingface.d.ts +0 -0
  1357. /package/dist/{core → extensions}/llama/huggingface.js +0 -0
  1358. /package/dist/{core → extensions}/llama/index.d.ts +0 -0
  1359. /package/dist/{core → extensions}/llama/ui.d.ts +0 -0
  1360. /package/dist/{core → extensions}/llama/ui.js +0 -0
@@ -25,7 +25,7 @@ import * as path from "node:path";
25
25
  import { execFileSync } from "node:child_process";
26
26
  import { createServer, type Socket } from "node:net";
27
27
  import { once } from "node:events";
28
- import { SUBAGENT_FOREGROUND_COMPLETE_EVENT } from "../../src/shared/types.ts";
28
+ import { SUBAGENT_ASYNC_STARTED_EVENT, SUBAGENT_ASYNC_COMPLETE_EVENT, SUBAGENT_FOREGROUND_COMPLETE_EVENT } from "../../src/shared/types.ts";
29
29
  import {
30
30
  createTempDir,
31
31
  createEventBus,
@@ -39,6 +39,7 @@ import {
39
39
  import registerSubagentExtension from "../../src/extension/index.ts";
40
40
  import { handleSubagentControlNotice } from "../../src/extension/control-notices.ts";
41
41
  import { discoverAgents } from "../../src/agents/agents.ts";
42
+ import { INVALID_STRUCTURED_OUTPUT_SCHEMA_ERROR, validateStructuredOutputValue } from "../../src/runs/shared/structured-output.ts";
42
43
  import {
43
44
  SUBAGENT_DELEGATION_REQUEST_EVENT,
44
45
  SUBAGENT_DELEGATION_RESPONSE_EVENT,
@@ -63,9 +64,10 @@ import { discardPreservedWorktrees } from "../../src/runs/shared/parallel-handof
63
64
  import { createWorktrees } from "../../src/runs/shared/worktree.ts";
64
65
  import { resolveAsyncResumeTarget } from "../../src/runs/background/async-resume.ts";
65
66
  import { createResultWatcher } from "../../src/runs/background/result-watcher.ts";
66
- import { clearExclusions, recordModelFailure } from "../../src/runs/shared/model-exclusions.ts";
67
67
  import { createWorkflowChildPermit, workflowChildPermitConsumed } from "../../src/shared/workflow-child-permit.ts";
68
- import { toSubagentDelegationExecutionParams } from "../../src/slash/delegation-adapters.ts";
68
+ import { toSubagentDelegationExecutionParams, toSubagentDelegationUpdate } from "../../src/slash/delegation-adapters.ts";
69
+ import { registerRequiredChildExtensions } from "../../src/api/required-child-extensions.ts";
70
+ import { createStructuredOutputRuntime } from "../../src/runs/shared/structured-output.ts";
69
71
 
70
72
  describe("single sync execution", { skip: !available ? "pi packages not available" : undefined }, () => {
71
73
  installSingleExecutionHooks();
@@ -874,6 +876,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
874
876
  });
875
877
  const ctx = {
876
878
  ...makeMinimalCtx(tempDir),
879
+ isIdle: () => false,
877
880
  modelRegistry: {
878
881
  getAvailable: () => [{ provider: "mock", id: "test-model", reasoning: true }],
879
882
  },
@@ -990,6 +993,58 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
990
993
  }
991
994
  });
992
995
 
996
+ it("keeps unavailable cache classifications out of progress when cancelled before reconciliation", async () => {
997
+ mockPi.onCall({
998
+ steps: [
999
+ {
1000
+ jsonl: [{
1001
+ type: "message_end",
1002
+ message: {
1003
+ role: "assistant",
1004
+ content: [{ type: "toolCall", id: "call-1", name: "read", arguments: { path: "package.json" } }],
1005
+ model: "mock/test-model",
1006
+ stopReason: "toolUse",
1007
+ usage: { input: 5, output: 3, cacheRead: 0, cacheWrite: 0, cost: { total: 0.001 } },
1008
+ },
1009
+ }],
1010
+ },
1011
+ { jsonl: [{ type: "tool_result_end", message: { role: "toolResult", toolCallId: "call-1", toolName: "read", isError: false, content: [] } }] },
1012
+ {
1013
+ jsonl: [{
1014
+ type: "message_end",
1015
+ message: {
1016
+ role: "assistant",
1017
+ content: [{ type: "text", text: "cache counters unavailable" }],
1018
+ model: "mock/test-model",
1019
+ stopReason: "length",
1020
+ usage: { input: 9, output: 4, cost: { total: 0.002 } },
1021
+ },
1022
+ }],
1023
+ },
1024
+ ],
1025
+ keepAliveAfterFinalMessageMs: 10_000,
1026
+ });
1027
+ const controller = new AbortController();
1028
+ const observed: Array<{ inputTokens?: number; outputTokens?: number; cacheRead?: number; cacheWrite?: number; turnCount?: number }> = [];
1029
+ const result = await runSync(tempDir, makeAgentConfigs(["echo"]), "echo", "Task", {
1030
+ acceptance: false,
1031
+ signal: controller.signal,
1032
+ onUpdate: (update) => {
1033
+ const progress = (update as { details?: { progress?: typeof observed } }).details?.progress?.[0];
1034
+ if (!progress || progress.turnCount !== 2) return;
1035
+ observed.push(progress);
1036
+ controller.abort();
1037
+ },
1038
+ });
1039
+
1040
+ assert.equal(result.exitCode, 1);
1041
+ assert.ok(observed.length > 0);
1042
+ assert.equal(observed.at(-1)?.inputTokens, 14);
1043
+ assert.equal(observed.at(-1)?.outputTokens, 7);
1044
+ assert.equal(observed.at(-1)?.cacheRead, undefined);
1045
+ assert.equal(observed.at(-1)?.cacheWrite, undefined);
1046
+ });
1047
+
993
1048
  it("allows concurrent async launches in one turn", async () => {
994
1049
  mockPi.onCall({ output: "async one" });
995
1050
  mockPi.onCall({ output: "async two" });
@@ -1306,7 +1361,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1306
1361
  summary: "done",
1307
1362
  patch: { path: path.join(repo, ".pi-subagents", "artifacts", "worktree.patch"), branch: worktree.branch, changed: false, diffStat: "", filesChanged: 0, insertions: 0, deletions: 0 },
1308
1363
  }],
1309
- cleanup: { state: "partial", pruned: false, tasks: [{ index: 0, path: worktree.path, branch: worktree.branch, worktreeRemoved: false, branchRemoved: false, preserved: true }] },
1364
+ cleanup: { state: "partial", pruned: false, tasks: [{ index: 0, path: worktree.path, branch: worktree.branch, recordedBaseDir: worktree.recordedBaseDir, worktreeRemoved: false, branchRemoved: false, preserved: true }] },
1310
1365
  }],
1311
1366
  }, null, 2), "utf-8");
1312
1367
  fs.writeFileSync(path.join(repo, ".pi-subagents", "artifacts", "status.json"), JSON.stringify({ runId: "cleanup-action-run", state: "complete" }), "utf-8");
@@ -1326,9 +1381,16 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1326
1381
  assert.match(childSafeResult.content[0]?.text ?? "", /child-safe subagent fanout mode/i);
1327
1382
  const apply = await executor.executePublic("cleanup-apply", { action: "worktree.cleanup", repo: "cleanup-repo", mode: "apply", planId }, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
1328
1383
  assert.equal(apply.isError, true);
1329
- assert.match(apply.content[0]?.text ?? "", /plan.*only|apply\/removal is not available/i);
1384
+ assert.match(apply.content[0]?.text ?? "", /requires interactive confirmation/i);
1330
1385
  assert.ok(fs.existsSync(worktree.path));
1331
1386
  assert.notEqual(execFileSync("git", ["-C", repo, "branch", "--list", worktree.branch], { encoding: "utf-8" }).trim(), "");
1387
+ const authorized = makeExecutor([makeAgent("echo")], { worktreeBaseDir: baseDir, authorityPolicy: { discardWorktree: "auto" } });
1388
+ const removed = await authorized.executePublic("cleanup-authorized", { action: "worktree.cleanup", repo: "cleanup-repo", mode: "apply", planId }, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
1389
+ assert.equal(removed.isError, undefined, removed.content[0]?.text);
1390
+ assert.match(removed.content[0]?.text ?? "", /complete/);
1391
+ assert.equal(fs.existsSync(worktree.path), false);
1392
+ assert.notEqual(execFileSync("git", ["-C", repo, "branch", "--list", worktree.branch], { encoding: "utf-8" }).trim(), "");
1393
+
1332
1394
  } finally {
1333
1395
  try { execFileSync("git", ["-C", repo, "worktree", "remove", "--force", worktree.path], { stdio: "ignore" }); } catch {}
1334
1396
  try { execFileSync("git", ["-C", repo, "branch", "-D", worktree.branch], { stdio: "ignore" }); } catch {}
@@ -1434,39 +1496,26 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1434
1496
  }
1435
1497
  });
1436
1498
 
1437
- it("rejects implementation runs without mutation-capable tools before spawn", async () => {
1438
- mockPi.onCall({ output: "should not spawn" });
1439
- const agents = [makeAgent("worker", { tools: ["read", "grep", "find", "ls", "contact_supervisor"] })];
1440
-
1441
- const result = await runSync(tempDir, agents, "worker", "Implement the approved file changes", {
1442
- runId: "readonly-contract-run",
1443
- });
1444
-
1445
- assert.equal(result.exitCode, 1);
1446
- assert.match(result.error ?? "", /no mutation-capable tools/);
1447
- assert.equal(mockPi.callCount(), 0);
1448
- });
1449
-
1450
- it("fails implementation runs that complete without mutation attempts", async () => {
1451
- mockPi.onCall({ output: "Validation:\nlet rawFilename = params.filename.trim();" });
1452
- const agents = [makeAgent("worker")];
1453
- const controlEvents: Array<{ message: string }> = [];
1454
-
1455
- const result = await runSync(tempDir, agents, "worker", "Implement the approved file changes", {
1456
- runId: "guard-run",
1457
- onControlEvent: (event: { message: string }) => controlEvents.push(event),
1458
- });
1459
-
1460
- assert.equal(result.exitCode, 1);
1461
- assert.match(result.error ?? "", /completed without making edits/);
1462
- assert.equal(result.finalOutput, "Validation:\nlet rawFilename = params.filename.trim();");
1463
- assert.equal(result.progress.status, "failed");
1464
- assert.deepEqual(controlEvents.map((event) => event.message), [
1465
- "worker completed without making edits for an implementation task",
1466
- ]);
1467
- assert.deepEqual(result.controlEvents?.map((event) => event.message), [
1468
- "worker completed without making edits for an implementation task",
1469
- ]);
1499
+ it("completes no-edit foreground runs independently of task prose and tool capability", async () => {
1500
+ const cleanRepo = path.join(tempDir, "no-edit-clean-repo");
1501
+ fs.mkdirSync(cleanRepo);
1502
+ execFileSync("git", ["init"], { cwd: cleanRepo, stdio: "ignore" });
1503
+ execFileSync("git", ["config", "user.email", "test@example.com"], { cwd: cleanRepo });
1504
+ execFileSync("git", ["config", "user.name", "Test User"], { cwd: cleanRepo });
1505
+ fs.writeFileSync(path.join(cleanRepo, "tracked.txt"), "unchanged\n");
1506
+ execFileSync("git", ["add", "tracked.txt"], { cwd: cleanRepo });
1507
+ execFileSync("git", ["commit", "-m", "baseline"], { cwd: cleanRepo, stdio: "ignore" });
1508
+ for (const [index, cwd, agent, task] of [
1509
+ [0, tempDir, makeAgent("worker", { tools: ["read"] }), "Implement and write the approved patch."],
1510
+ [1, cleanRepo, makeAgent("worker", { tools: ["read", "write", "bash"], mutationTools: ["replace"] }), "Fix the parser; input data mentions write, edit, bash, and replace."],
1511
+ ] as const) {
1512
+ mockPi.onCall({ output: "Completed without workspace changes." });
1513
+ const result = await runSync(cwd, [agent], "worker", task, { runId: `no-edit-foreground-${index}` });
1514
+
1515
+ assert.equal(result.exitCode, 0, result.error);
1516
+ assert.equal(result.error, undefined);
1517
+ assert.equal(result.finalOutput, "Completed without workspace changes.");
1518
+ }
1470
1519
  });
1471
1520
 
1472
1521
  it("preserves terminal empty-output diagnostics after useful foreground work", async () => {
@@ -1497,43 +1546,9 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1497
1546
 
1498
1547
  assert.equal(result.exitCode, 1);
1499
1548
  assert.match(result.error ?? "", /^Subagent produced no output after terminal assistant stopReason "aborted"\./);
1500
- assert.doesNotMatch(result.error ?? "", /completed without making edits/);
1501
1549
  assert.equal(result.finalOutput, partialOutput);
1502
1550
  });
1503
1551
 
1504
- it("reports why an unsafe foreground compaction abort cannot resume without falling back", async () => {
1505
- mockPi.onCall({
1506
- jsonl: [
1507
- events.toolStart("read", { path: "src/index.ts" }),
1508
- events.toolEnd("read"),
1509
- events.toolResult("read", "file contents"),
1510
- { type: "compaction_start" },
1511
- {
1512
- type: "message_end",
1513
- message: {
1514
- role: "assistant",
1515
- content: [],
1516
- model: "mock/test-model",
1517
- stopReason: "aborted",
1518
- usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: { total: 0 } },
1519
- },
1520
- },
1521
- { type: "agent_settled" },
1522
- ],
1523
- exitCode: 0,
1524
- });
1525
- mockPi.onCall({ output: "Fallback must not run" });
1526
-
1527
- const result = await runSync(tempDir, [makeAgent("worker", { model: "mock/test-model", fallbackModels: ["mock/fallback-model"] })], "worker", "Inspect the current source", {
1528
- runId: "foreground-compaction-abort-no-session",
1529
- });
1530
-
1531
- assert.equal(result.exitCode, 1);
1532
- assert.match(result.error ?? "", /^Subagent produced no output after terminal assistant stopReason "aborted"\./);
1533
- assert.match(result.error ?? "", /Compaction-induced child abort could not be resumed safely: retained session unavailable\./);
1534
- assert.equal(mockPi.callCount(), 1);
1535
- });
1536
-
1537
1552
  it("agent contract reports omitted acceptance separately without injecting a prompt", async () => {
1538
1553
  mockPi.onCall({ output: "Plan only" });
1539
1554
  const agents = [makeAgent("worker", { tools: ["read", "write"] })];
@@ -1554,18 +1569,23 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1554
1569
  });
1555
1570
 
1556
1571
  it("does not inject inferred acceptance into reviewer prompts", async () => {
1557
- mockPi.onCall({ output: "VERDICT: PASS" });
1558
- const result = await runSync(tempDir, [makeAgent("reviewer", { tools: ["read"], completionGuard: false })], "reviewer", "Review the diff and return findings only.", {
1559
- runId: "reviewer-inferred-acceptance",
1560
- });
1572
+ for (const [index, task] of [
1573
+ "Review the diff and return findings only.",
1574
+ "Read-only review. Verify release recovery and security; do not edit files.",
1575
+ ].entries()) {
1576
+ mockPi.onCall({ output: "VERDICT: PASS" });
1577
+ const result = await runSync(tempDir, [makeAgent("reviewer", { tools: ["read"], acceptanceRole: "read-only" })], "reviewer", task, {
1578
+ runId: `reviewer-inferred-acceptance-${index}`,
1579
+ });
1561
1580
 
1562
- assert.equal(result.exitCode, 0);
1563
- assert.doesNotMatch(readCall().args.join("\n"), /## Acceptance Contract/);
1581
+ assert.equal(result.exitCode, 0);
1582
+ assert.doesNotMatch(readCall().args.join("\n"), /## Acceptance Contract/);
1583
+ }
1564
1584
  });
1565
1585
 
1566
1586
  it("agent contract keeps acceptance rejection out of execution status", async () => {
1567
1587
  mockPi.onCall({ output: "Done\n```acceptance-report\n{\"criteriaSatisfied\":[{\"id\":\"criterion-1\",\"status\":\"not-satisfied\",\"evidence\":\"no proof\"}]}\n```" });
1568
- const agents = [makeAgent("worker", { tools: ["read"], completionGuard: false })];
1588
+ const agents = [makeAgent("worker", { tools: ["read"] })];
1569
1589
 
1570
1590
  const result = await runSync(tempDir, agents, "worker", "Summarize the fix", {
1571
1591
  runId: "v1-acceptance-reject",
@@ -1581,22 +1601,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1581
1601
  assert.match(result.acceptance.runtimeChecks?.[0]?.message ?? "", /not-satisfied/);
1582
1602
  });
1583
1603
 
1584
- it("agent contract records explicit completion guard as an effect", async () => {
1585
- mockPi.onCall({ output: "Plan only" });
1586
- const agents = [makeAgent("worker", { tools: ["read", "write"], completionGuard: true })];
1587
-
1588
- const result = await runSync(tempDir, agents, "worker", "Implement the approved file changes", {
1589
- runId: "v1-completion-effect",
1590
- agentContract: { version: 1 },
1591
- });
1592
-
1593
- assert.equal(result.exitCode, 0);
1594
- assert.equal(result.execution?.status, "completed");
1595
- assert.equal(result.effects?.fileMutation?.status, "missing");
1596
- assert.equal(result.effects?.fileMutation?.expected, true);
1597
- assert.equal(result.effects?.fileMutation?.attempted, false);
1598
- });
1599
-
1600
1604
  it("direct single tool calls support outputSchema", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
1601
1605
  mockPi.onCall({
1602
1606
  stdoutRaw: [
@@ -1623,29 +1627,22 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1623
1627
  if (child?.artifactPaths?.outputPath) assert.match(fs.readFileSync(child.artifactPaths.outputPath, "utf-8"), /"note": "captured"/);
1624
1628
  });
1625
1629
 
1626
- it("reports bounded structured_output rejection evidence without leaking the submitted value", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
1627
- const secret = "PRIVATE_STRUCTURED_OUTPUT_VALUE";
1628
- mockPi.onCall({
1629
- stdoutRaw: [
1630
- { type: "tool_execution_start", toolCallId: "structured-rejected", toolName: "structured_output", args: { value: { secret } } },
1631
- { type: "tool_result_end", message: { role: "toolResult", toolCallId: "structured-rejected", toolName: "structured_output", isError: true, content: [{ type: "text", text: `Structured output validation failed: value.secret: expected boolean; received value: ${secret}` }] } },
1632
- { type: "tool_execution_end", toolCallId: "structured-rejected", toolName: "structured_output", isError: true },
1633
- ].map((entry) => JSON.stringify(entry)).join("\n") + "\n",
1634
- });
1635
- const executor = makeExecutor([makeAgent("echo")]);
1636
- const result = await executor.execute(
1637
- "single-schema-rejected",
1638
- { agent: "echo", task: "Return structured data", outputSchema: { type: "object", required: ["ok"], properties: { ok: { type: "boolean" } } }, acceptance: false },
1630
+ it("saves the structured result, not closing prose, to a bound output file", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
1631
+ const structuredOutput = { ok: true, note: "captured" };
1632
+ mockPi.onCall({ output: "Enough; writing up.", structuredOutput });
1633
+ const outputPath = path.join(tempDir, "structured.json");
1634
+
1635
+ const result = await makeExecutor([makeAgent("echo")]).execute(
1636
+ "single-schema-output",
1637
+ { agent: "echo", task: "Return structured data", output: outputPath, outputSchema: { type: "object", required: ["ok"], properties: { ok: { type: "boolean" }, note: { type: "string" } } }, acceptance: false },
1639
1638
  new AbortController().signal,
1640
1639
  undefined,
1641
1640
  makeMinimalCtx(tempDir),
1642
1641
  );
1643
1642
 
1644
- const child = result.details?.results?.[0];
1645
- assert.equal(result.isError, true);
1646
- assert.equal(child?.structuredOutputFailed, true);
1647
- assert.match(child?.error ?? "", /Structured output validation failed: value.secret/);
1648
- assert.doesNotMatch(child?.error ?? "", new RegExp(secret));
1643
+ assert.equal(result.isError, undefined);
1644
+ assert.equal(result.details?.results?.[0]?.savedOutputPath, outputPath);
1645
+ assert.equal(fs.readFileSync(outputPath, "utf-8"), JSON.stringify(structuredOutput, null, 2));
1649
1646
  });
1650
1647
 
1651
1648
  it("routes retained workflow follow-ups to distinct outputs without overwriting the writer report", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
@@ -1653,7 +1650,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1653
1650
  const writerPath = path.join(tempDir, `writer-${relative}.md`);
1654
1651
  const challengeOutput = relative ? "challenge-relative.md" : path.join(tempDir, "challenge-absolute.md");
1655
1652
  mockPi.onCall({ output: "original writer report" });
1656
- mockPi.onCall({ output: "retained challenge report" });
1653
+ mockPi.onCall({ output: "No better current-scope change is needed; the retained implementation remains correct." });
1657
1654
  mockPi.onCall({ output: "repeated challenge report" });
1658
1655
  const result = await makeExecutor([makeAgent("echo")], {}, true).execute(
1659
1656
  `workflow-retained-output-${relative}`,
@@ -1688,7 +1685,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1688
1685
  assert.equal(challenge.outputReference, challengePath);
1689
1686
  assert.notEqual(challenge.outputReference, writer.outputReference);
1690
1687
  assert.equal(fs.readFileSync(writer.outputReference, "utf-8"), "original writer report");
1691
- assert.equal(fs.readFileSync(challenge.outputReference, "utf-8"), "retained challenge report");
1688
+ assert.equal(fs.readFileSync(challenge.outputReference, "utf-8"), "No better current-scope change is needed; the retained implementation remains correct.");
1692
1689
  assert.deepEqual(result.details.results.map((child) => child.savedOutputPath), [writerPath, challengePath, undefined]);
1693
1690
  }
1694
1691
  assert.equal(mockPi.callCount(), 6);
@@ -1816,22 +1813,133 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1816
1813
  assert.equal(resumed.savedOutputPath, undefined);
1817
1814
  });
1818
1815
 
1819
- it("preserves the structured-output contract when resume fields are omitted", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
1820
- const schema = { type: "object", required: ["ok"], properties: { ok: { type: "boolean" } } };
1816
+ it("pairs awaited workflow child starts and completions on success, failure and revival", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
1817
+ const bus = createEventBus();
1818
+ const started: Array<Record<string, unknown>> = [];
1819
+ const completed: Array<Record<string, unknown>> = [];
1820
+ bus.on(SUBAGENT_ASYNC_STARTED_EVENT, (event) => started.push(event as Record<string, unknown>));
1821
+ bus.on(SUBAGENT_ASYNC_COMPLETE_EVENT, (event) => completed.push(event as Record<string, unknown>));
1822
+ const executor = makeExecutor([makeAgent("echo")], {}, true, undefined, true, new Map(), undefined, undefined, bus);
1823
+ const ctx = makeMinimalCtx(tempDir);
1824
+ let firstRunId: string | undefined;
1825
+ for (const [task, call] of [
1826
+ ["Succeeded", { output: "done" }],
1827
+ ["Failed", { stderr: "failure", exitCode: 1 }],
1828
+ ["Revived", { output: "revived" }],
1829
+ ] as const) {
1830
+ mockPi.onCall(call);
1831
+ const script = task === "Revived"
1832
+ ? `return runs.run("child", { resume: ${JSON.stringify(firstRunId)}, task: "Revived", acceptance: false, output: false });`
1833
+ : `return runs.run("child", { agent: "echo", task: ${JSON.stringify(task)}, acceptance: false, output: false });`;
1834
+ const result = await executor.execute(`awaited-${task}`, { async: false, workflowScript: script }, new AbortController().signal, undefined, ctx);
1835
+ assert.equal(result.isError, task === "Failed" ? true : undefined, result.content[0]?.text ?? "");
1836
+ const child = started.at(-1)!;
1837
+ if (task === "Succeeded") firstRunId = child.id as string;
1838
+ const matches = completed.filter((event) => event.id === child.id);
1839
+ assert.equal(matches.length, 1);
1840
+ assert.equal(matches[0]?.awaitedByWorkflow, true);
1841
+ assert.equal(matches[0]?.parentWorkflowRunId, child.parentWorkflowRunId);
1842
+ assert.equal(matches[0]?.sessionId, child.sessionId);
1843
+ assert.equal(matches[0]?.completionOwnerId, child.completionOwnerId);
1844
+ assert.equal(matches[0]?.success, task !== "Failed");
1845
+ assert.equal(matches[0]?.triggerTurn, false);
1846
+ }
1847
+ mockPi.onCall({ output: "detached" });
1848
+ await executor.execute("explicit-child", {
1849
+ async: false,
1850
+ workflowScript: `return runs.run("detached", { agent: "echo", task: "Detached", async: true, acceptance: false, output: false });`,
1851
+ }, new AbortController().signal, undefined, ctx);
1852
+ const explicitStart = started.at(-1)!;
1853
+ const watcherState: SubagentState = {
1854
+ baseCwd: tempDir, currentSessionId: explicitStart.sessionId as string,
1855
+ completionOwnerId: explicitStart.completionOwnerId as string,
1856
+ asyncJobs: new Map(), foregroundControls: new Map(), lastForegroundControlId: null,
1857
+ completionSeen: new Map(), resultFileCoalescer: { schedule: () => false, clear() {} },
1858
+ };
1859
+ const watcher = createResultWatcher({ events: bus }, watcherState, DIRS.results, 60_000, {
1860
+ coalesceDelayMs: 0, deliverIntercomResults: false,
1861
+ notifier: { deliver: async () => true },
1862
+ });
1863
+ try {
1864
+ for (let attempt = 0; attempt < 100 && !completed.some((event) => event.id === explicitStart.id); attempt++) {
1865
+ watcher.refreshResultDelivery();
1866
+ await new Promise((resolve) => setTimeout(resolve, 50));
1867
+ }
1868
+ const matches = completed.filter((event) => event.id === explicitStart.id);
1869
+ assert.equal(matches.length, 1);
1870
+ assert.equal(matches[0]?.awaitedByWorkflow, undefined);
1871
+ } finally {
1872
+ watcher.stopResultWatcher();
1873
+ }
1874
+ });
1875
+
1876
+ it("preserves original parent authority when reviving a foreground child", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
1877
+ const callerRuntime: ChildRuntimeConfig = {
1878
+ capabilityCeiling: {
1879
+ version: 1,
1880
+ allowedTools: ["read"],
1881
+ allowedAgents: ["echo", "researcher"],
1882
+ denyExtensions: true,
1883
+ sources: ["original-parent"],
1884
+ },
1885
+ };
1886
+ const executor = makeExecutor(
1887
+ [makeAgent("echo", { allowedAgents: ["researcher"] }), makeAgent("researcher")],
1888
+ {}, false, undefined, true, new Map(), undefined, undefined, createEventBus(), undefined, callerRuntime,
1889
+ );
1890
+ const ctx = makeMinimalCtx(tempDir);
1891
+ mockPi.onCall({ output: "Initial foreground work" });
1892
+ const firstResult = await executor.execute(
1893
+ "foreground-authority-first",
1894
+ { async: false, workflowScript: `return runs.run("first", { agent: "echo", task: "First", acceptance: false, output: false });` },
1895
+ new AbortController().signal, undefined, ctx,
1896
+ );
1897
+ assert.equal(firstResult.isError, undefined, firstResult.content[0]?.text ?? "foreground launch failed");
1898
+ const first = firstResult.details.workflow?.value as { runId?: string };
1899
+ assert.ok(first.runId);
1900
+
1901
+ callerRuntime.capabilityCeiling = undefined;
1902
+ mockPi.onCall({ output: "Resumed foreground work" });
1903
+ const resumedResult = await executor.execute(
1904
+ "foreground-authority-resume",
1905
+ { async: false, workflowScript: `return runs.run("resumed", { resume: ${JSON.stringify(first.runId)}, task: "Resume", acceptance: false, output: false });` },
1906
+ new AbortController().signal, undefined, ctx,
1907
+ );
1908
+ assert.equal(resumedResult.isError, undefined, resumedResult.content[0]?.text ?? "foreground resume failed");
1909
+ assert.deepEqual(readCall().runtime?.capabilityCeiling, {
1910
+ version: 1,
1911
+ allowedTools: ["read"],
1912
+ allowedAgents: ["researcher"],
1913
+ denyExtensions: true,
1914
+ sources: ["agent:echo", "original-parent"],
1915
+ });
1916
+ });
1917
+
1918
+ it("retains inherited and disabled discovered schemas across definition changes", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
1919
+ const agentPath = path.join(tempDir, ".selesai", "agents", "typed.md");
1920
+ fs.mkdirSync(path.dirname(agentPath), { recursive: true });
1921
+ const definition = (required: string) => `---\nname: typed\ndescription: Typed output\noutputSchema: {"type":"object","required":["${required}"]}\n---\nReturn data.\n`;
1922
+ fs.writeFileSync(agentPath, definition("ok"));
1821
1923
  const structuredEvents = [
1822
1924
  { type: "tool_execution_start", toolName: "structured_output", args: { value: { ok: true } } },
1823
1925
  { type: "tool_result_end", message: { role: "toolResult", toolName: "structured_output", content: [{ type: "text", text: "Structured output captured." }] } },
1824
1926
  { type: "tool_execution_end", toolName: "structured_output" },
1825
1927
  ];
1928
+ mockPi.onCall({ stdoutRaw: structuredEvents.map((entry) => JSON.stringify(entry)).join("\n") + "\n", structuredOutputCapture: { ok: true }, writeFiles: [{ path: agentPath, content: definition("changed") }] });
1826
1929
  mockPi.onCall({ stdoutRaw: structuredEvents.map((entry) => JSON.stringify(entry)).join("\n") + "\n", structuredOutputCapture: { ok: true } });
1827
- mockPi.onCall({ stdoutRaw: structuredEvents.map((entry) => JSON.stringify(entry)).join("\n") + "\n", structuredOutputCapture: { ok: true } });
1828
- const result = await makeExecutor([makeAgent("echo")]).execute(
1930
+ mockPi.onCall({ output: "disabled first", writeFiles: [{ path: agentPath, content: definition("later") }] });
1931
+ mockPi.onCall({ output: "disabled resumed" });
1932
+ const executor = makeExecutor([], {}, false, undefined, true, new Map(), undefined, undefined, createEventBus(), (cwd) => discoverAgents(cwd, "project").agents);
1933
+ const result = await executor.execute(
1829
1934
  "workflow-inherited-resume-schema",
1830
1935
  {
1831
1936
  async: false,
1832
1937
  workflowScript: `
1833
- const first = await runs.run("first", { agent: "echo", task: "First", outputSchema: ${JSON.stringify(schema)}, agentContract: { version: 1 }, acceptance: false, output: false });
1834
- return runs.run("resumed", { resume: first.runId, task: "Resume" });
1938
+ const first = await runs.run("first", { agent: "typed", task: "First", acceptance: false, output: false });
1939
+ const resumed = await runs.run("resumed", { resume: first.runId, task: "Resume" });
1940
+ const disabled = await runs.run("disabled", { agent: "typed", task: "Disabled", outputSchema: false, acceptance: false, output: false });
1941
+ const disabledResumed = await runs.run("disabled-resumed", { resume: disabled.runId, task: "Resume disabled" });
1942
+ return { resumed, disabledResumed };
1835
1943
  `,
1836
1944
  },
1837
1945
  new AbortController().signal,
@@ -1840,9 +1948,12 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1840
1948
  );
1841
1949
 
1842
1950
  assert.equal(result.isError, undefined, result.content[0]?.text ?? "workflow failed");
1843
- const resumed = result.details.workflow?.value as { ok?: boolean; structuredOutput?: unknown };
1844
- assert.equal(resumed.ok, true);
1845
- assert.deepEqual(resumed.structuredOutput, { ok: true });
1951
+ const value = result.details.workflow?.value as { resumed: { ok?: boolean; structuredOutput?: unknown }; disabledResumed: { ok?: boolean; output?: string; structuredOutput?: unknown } };
1952
+ assert.equal(value.resumed.ok, true);
1953
+ assert.deepEqual(value.resumed.structuredOutput, { ok: true });
1954
+ assert.equal(value.disabledResumed.ok, true);
1955
+ assert.equal(value.disabledResumed.output, "disabled resumed");
1956
+ assert.equal(value.disabledResumed.structuredOutput, undefined);
1846
1957
  });
1847
1958
 
1848
1959
  it("auto-resumes a workflow child after a setup abort", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
@@ -1929,7 +2040,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1929
2040
  assert.equal(fs.readFileSync(configuredOutput, "utf-8"), "resumed report");
1930
2041
  });
1931
2042
 
1932
- it("preserves failed foreground resume errors and transcript metadata", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
2043
+ it("preserves successful no-edit foreground resume output and transcript metadata", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
1933
2044
  const executor = makeExecutor([makeAgent("echo")]);
1934
2045
  mockPi.onCall({ output: "first report" });
1935
2046
  const firstResult = await executor.execute(
@@ -1953,13 +2064,10 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
1953
2064
  makeMinimalCtx(tempDir),
1954
2065
  );
1955
2066
 
1956
- assert.equal(resumedResult.isError, true);
1957
- const resumedText = resumedResult.content.map((part) => part.type === "text" ? part.text : "").join("\n");
1958
- assert.match(resumedText, /Subagent completed without making edits for an implementation task/);
1959
- assert.doesNotMatch(resumedText, new RegExp(`^${escapeRegExp(partialOutput)}`));
2067
+ assert.equal(resumedResult.isError, undefined);
1960
2068
  const child = resumedResult.details.results[0];
1961
2069
  assert.equal(child?.finalOutput, partialOutput);
1962
- assert.match(child?.error ?? "", /Subagent completed without making edits for an implementation task/);
2070
+ assert.equal(child?.error, undefined);
1963
2071
  assert.ok(child?.transcriptPath);
1964
2072
  assert.equal(child?.transcriptPath, child?.artifactPaths?.transcriptPath);
1965
2073
  assert.ok(child?.artifactPaths?.outputPath);
@@ -2157,6 +2265,77 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2157
2265
  assert.equal(fs.existsSync(path.dirname(child.structuredOutputPath)), false);
2158
2266
  });
2159
2267
 
2268
+ it("reports rejected structured_output evidence and lets a later valid call win", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
2269
+ const rejectedEvents = [
2270
+ { type: "message_end", message: { role: "assistant", content: [{ type: "toolCall", id: "structured-rejected", name: "structured_output", arguments: { value: {} } }], model: "mock/test-model", stopReason: "toolUse", usage: { input: 1, output: 1, cacheRead: 0, cacheWrite: 0, cost: { total: 0 } } } },
2271
+ { type: "tool_execution_start", toolCallId: "structured-rejected", toolName: "structured_output", args: { value: {} } },
2272
+ { type: "tool_result_end", message: { role: "toolResult", toolCallId: "structured-rejected", toolName: "structured_output", isError: true, content: [{ type: "text", text: "Structured output validation failed: ok: is required" }] } },
2273
+ { type: "tool_execution_end", toolCallId: "structured-rejected", toolName: "structured_output" },
2274
+ ];
2275
+ mockPi.onCall({ stdoutRaw: rejectedEvents.map((entry) => JSON.stringify(entry)).join("\n") + "\n" });
2276
+ const executor = makeExecutor([makeAgent("echo")]);
2277
+ const params = { agent: "echo", task: "Return structured data", outputSchema: { type: "object", required: ["ok"], properties: { ok: { type: "boolean" } } }, acceptance: false, artifacts: false } as const;
2278
+
2279
+ const rejected = await executor.execute("single-schema-rejected", params, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
2280
+
2281
+ assert.equal(rejected.isError, true);
2282
+ assert.equal(rejected.details.results[0]?.structuredOutputFailed, true);
2283
+ assert.match(rejected.details.results[0]?.error ?? "", /Structured output validation failed: ok: is required/);
2284
+ assert.doesNotMatch(rejected.details.results[0]?.error ?? "", /Missing structured_output call/);
2285
+
2286
+ mockPi.reset();
2287
+ mockPi.onCall({
2288
+ stdoutRaw: rejectedEvents.map((entry) => JSON.stringify(entry)).join("\n") + "\n",
2289
+ structuredOutput: { ok: true },
2290
+ });
2291
+ const recovered = await executor.execute("single-schema-recovered", params, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
2292
+
2293
+ assert.equal(recovered.isError, undefined, recovered.content[0]?.text);
2294
+ assert.deepEqual(recovered.details.results[0]?.structuredOutput, { ok: true });
2295
+ });
2296
+
2297
+ it("does not expose malformed outputSchema compiler text in foreground results", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
2298
+ const sentinel = "FOREGROUND_PRIVATE_SCHEMA_SENTINEL";
2299
+ const outputSchema = { type: "string", pattern: `${sentinel}_[invalid` };
2300
+ const validation = await validateStructuredOutputValue(outputSchema, "value");
2301
+ assert.equal(validation.status, "invalid");
2302
+ if (validation.status !== "invalid") return;
2303
+ assert.match(validation.message, new RegExp(sentinel));
2304
+ mockPi.onCall({
2305
+ jsonl: [
2306
+ { type: "tool_execution_start", toolCallId: "structured-malformed-schema", toolName: "structured_output", args: { value: "value" } },
2307
+ { type: "tool_result_end", message: { role: "toolResult", toolCallId: "structured-malformed-schema", toolName: "structured_output", isError: true, content: [{ type: "text", text: `Structured output validation failed: ${validation.message}` }] } },
2308
+ { type: "tool_execution_end", toolCallId: "structured-malformed-schema", toolName: "structured_output" },
2309
+ ],
2310
+ });
2311
+
2312
+ const result = await makeExecutor([makeAgent("echo")]).execute(
2313
+ "single-schema-malformed",
2314
+ { agent: "echo", task: "Return structured data", outputSchema, acceptance: false, artifacts: false },
2315
+ new AbortController().signal, undefined, makeMinimalCtx(tempDir),
2316
+ );
2317
+
2318
+ assert.equal(result.isError, true);
2319
+ assert.equal(result.details.results[0]?.error, INVALID_STRUCTURED_OUTPUT_SCHEMA_ERROR);
2320
+ assert.doesNotMatch(JSON.stringify(result.details.results[0]), new RegExp(sentinel));
2321
+ });
2322
+
2323
+ it("enforces a discovered agent outputSchema and lets false opt out", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
2324
+ const agentDir = path.join(tempDir, ".selesai", "agents");
2325
+ fs.mkdirSync(agentDir, { recursive: true });
2326
+ fs.writeFileSync(path.join(agentDir, "typed.md"), `---\nname: typed\ndescription: Typed output\noutputSchema: {"type":"object","required":["ok"]}\n---\nReturn data.\n`);
2327
+ const executor = makeExecutor(discoverAgents(tempDir, "project").agents);
2328
+ mockPi.onCall({ output: "ordinary prose" });
2329
+ const inherited = await executor.execute("schema-default", { agent: "typed", task: "Return data", acceptance: false, artifacts: false }, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
2330
+ assert.equal(inherited.isError, true);
2331
+ assert.match(inherited.details.results[0]?.error ?? "", /Missing structured_output call/);
2332
+
2333
+ mockPi.onCall({ output: "ordinary prose" });
2334
+ const optedOut = await executor.execute("schema-disabled", { agent: "typed", task: "Return prose", outputSchema: false, acceptance: false, artifacts: false }, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
2335
+ assert.equal(optedOut.isError, undefined);
2336
+ assert.equal(optedOut.details.results[0]?.finalOutput, "ordinary prose");
2337
+ });
2338
+
2160
2339
  it("does not create a temporary structured output directory before file-only validation", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
2161
2340
  const previousTmpdir = process.env.TMPDIR;
2162
2341
  process.env.TMPDIR = tempDir;
@@ -2215,37 +2394,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2215
2394
  assert.deepEqual(child?.structuredOutput, { ok: true });
2216
2395
  });
2217
2396
 
2218
- it("returns captured output when the foreground executor fails an implementation run", async () => {
2219
- mockPi.onCall({ output: "Oracle review:\n- finding one\n- finding two" });
2220
- const executor = makeExecutor([makeAgent("oracle")]);
2221
-
2222
- const result = await executor.execute(
2223
- "failed-single-output",
2224
- { agent: "oracle", task: "Implement the approved file changes" },
2225
- new AbortController().signal,
2226
- undefined,
2227
- makeMinimalCtx(tempDir),
2228
- );
2229
-
2230
- const text = result.content[0]?.text ?? "";
2231
- assert.equal(result.isError, true);
2232
- assert.match(text, /completed without making edits/);
2233
- assert.match(text, /Output:\nOracle review:\n- finding one\n- finding two/);
2234
- assert.match(text, /Output artifact: /);
2235
- });
2236
-
2237
- it("fails future-tense implementation summaries when no mutation attempt occurred", async () => {
2238
- mockPi.onCall({ output: "I’ll do that now and report back after implementing." });
2239
- const agents = [makeAgent("worker")];
2240
-
2241
- const result = await runSync(tempDir, agents, "worker", "Implement the approved fixes", {
2242
- runId: "guard-future-tense",
2243
- });
2244
-
2245
- assert.equal(result.exitCode, 1);
2246
- assert.match(result.error ?? "", /completed without making edits/);
2247
- });
2248
-
2249
2397
  it("allows declared read-only agents to mention implementation words without edits", async () => {
2250
2398
  mockPi.onCall({ output: "Validation report after the patch" });
2251
2399
  const agents = [makeAgent("architect", { tools: ["read", "grep", "find", "ls"] })];
@@ -2259,27 +2407,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2259
2407
  assert.equal(result.finalOutput, "Validation report after the patch");
2260
2408
  });
2261
2409
 
2262
- it("keeps bash-enabled implementation tasks conservative unless completion guard is disabled", async () => {
2263
- mockPi.onCall({ output: "cold start test after patch" });
2264
- mockPi.onCall({ output: "cold start test after patch" });
2265
- const agents = [
2266
- makeAgent("test-runner", { tools: ["read", "grep", "bash", "ls"] }),
2267
- makeAgent("test-runner-optout", { tools: ["read", "grep", "bash", "ls"], completionGuard: false }),
2268
- ];
2269
-
2270
- const withoutOptOut = await runSync(tempDir, agents, "test-runner", "Patch the cold start test", {
2271
- runId: "guard-bash-conservative",
2272
- });
2273
- assert.equal(withoutOptOut.exitCode, 1);
2274
- assert.match(withoutOptOut.error ?? "", /completed without making edits/);
2275
-
2276
- const withOptOut = await runSync(tempDir, agents, "test-runner-optout", "Patch the cold start test", {
2277
- runId: "guard-bash-optout",
2278
- });
2279
- assert.equal(withOptOut.exitCode, 0);
2280
- assert.equal(withOptOut.progress.status, "completed");
2281
- });
2282
-
2283
2410
  it("allows implementation runs when parsed messages include a real edit tool call", async () => {
2284
2411
  mockPi.onCall({
2285
2412
  jsonl: [
@@ -2309,7 +2436,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2309
2436
 
2310
2437
  it("resolves explicit agent aliases to canonical execution names", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
2311
2438
  mockPi.onCall({ output: "Implemented" });
2312
- const executor = makeExecutor([makeAgent("worker", { aliases: ["developer"], completionGuard: false })]);
2439
+ const executor = makeExecutor([makeAgent("worker", { aliases: ["developer"] })]);
2313
2440
 
2314
2441
  const result = await executor.execute("single", { agent: "developer", task: "Implement" }, new AbortController().signal, undefined, makeMinimalCtx(tempDir));
2315
2442
 
@@ -2451,55 +2578,11 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2451
2578
  assert.equal(mockPi.callCount(), 1);
2452
2579
  });
2453
2580
 
2454
- it("fails closed before spawn when cached exclusions leave zero launch candidates", async () => {
2455
- recordModelFailure({ modelId: "gpt-5-mini", provider: "openai", reason: "sk-secret-token-xyz" });
2456
- recordModelFailure({ modelId: "claude-sonnet-4", provider: "anthropic", reason: "sk-secret-token-xyz" });
2457
- mockPi.onCall({ output: "should not spawn" });
2458
- const agents = [makeAgent("worker", {
2459
- model: "openai/gpt-5-mini",
2460
- fallbackModels: ["anthropic/claude-sonnet-4"],
2461
- })];
2462
-
2463
- await assert.rejects(
2464
- runSync(tempDir, agents, "worker", "Do work", {
2465
- runId: "cached-exclusion-zero-candidates",
2466
- acceptance: false,
2467
- availableModels: [
2468
- { provider: "openai", id: "gpt-5-mini", fullId: "openai/gpt-5-mini" },
2469
- { provider: "anthropic", id: "claude-sonnet-4", fullId: "anthropic/claude-sonnet-4" },
2470
- ],
2471
- }),
2472
- (error: unknown) => {
2473
- assert.ok(error instanceof Error);
2474
- assert.match(error.message, /No usable subagent models remain after registry, scope, and cached-exclusion filtering/);
2475
- assert.equal(error.message.includes("sk-secret-token-xyz"), false);
2476
- return true;
2477
- },
2478
- );
2479
- assert.equal(mockPi.callCount(), 0);
2480
- });
2481
-
2482
- it("fails closed before spawn when fallback-only configuration resolves no launch candidates", async () => {
2483
- mockPi.onCall({ output: "should not spawn" });
2484
- const agents = [makeAgent("worker", { fallbackModels: ["does-not-exist"] })];
2485
-
2486
- await assert.rejects(
2487
- runSync(tempDir, agents, "worker", "Do work", {
2488
- runId: "fallback-only-zero-candidates",
2489
- acceptance: false,
2490
- availableModels: [{ provider: "openai", id: "gpt-5-mini", fullId: "openai/gpt-5-mini" }],
2491
- }),
2492
- /Unknown subagent model 'does-not-exist'/,
2493
- );
2494
- assert.equal(mockPi.callCount(), 0);
2495
- });
2496
-
2497
2581
  it("does not retry a non-zero exit after tool activity", async () => {
2498
2582
  mockPi.onCall({ jsonl: [events.toolStart("read", { path: "package.json" })], exitCode: 1 });
2499
2583
  mockPi.onCall({ output: "must not run" });
2500
2584
  const agents = [makeAgent("worker", {
2501
2585
  model: "openai/gpt-5-mini",
2502
- fallbackModels: ["anthropic/claude-sonnet-4"],
2503
2586
  })];
2504
2587
 
2505
2588
  const result = await runSync(tempDir, agents, "worker", "Read a file", {
@@ -2508,26 +2591,23 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2508
2591
  });
2509
2592
 
2510
2593
  assert.equal(result.exitCode, 1);
2511
- assert.equal(result.modelAttempts?.length, 1);
2512
2594
  assert.equal(mockPi.callCount(), 1);
2513
2595
  });
2514
2596
 
2515
- it("stops model fallback and flags contextOverflow when the input exceeds the context window", async () => {
2597
+ it("flags contextOverflow when the input exceeds the context window", async () => {
2516
2598
  mockPi.onCall({ output: "", stderr: "This model's maximum context length is 8192 tokens", exitCode: 1 });
2517
2599
  mockPi.onCall({ output: "must not run" });
2518
2600
  const agents = [makeAgent("worker", {
2519
2601
  model: "openai/gpt-5-mini",
2520
- fallbackModels: ["anthropic/claude-sonnet-4"],
2521
2602
  })];
2522
2603
 
2523
2604
  const result = await runSync(tempDir, agents, "worker", "Summarize a huge file", {
2524
- runId: "context-overflow-stops-fallback",
2605
+ runId: "context-overflow-single-model",
2525
2606
  acceptance: false,
2526
2607
  });
2527
2608
 
2528
2609
  assert.equal(result.exitCode, 1);
2529
2610
  assert.equal(result.contextOverflow, true);
2530
- assert.equal(result.modelAttempts?.length, 1);
2531
2611
  assert.equal(mockPi.callCount(), 1);
2532
2612
  assert.ok(result.error?.includes("context"), "error should mention context overflow");
2533
2613
  });
@@ -2557,34 +2637,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2557
2637
  assert.equal(result.model, "anthropic/claude-sonnet-4");
2558
2638
  });
2559
2639
 
2560
- it("forwards configured response aliases to the resolved foreground fallback without rewriting its route", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
2561
- mockPi.onCall({ jsonl: [], stderr: "429 rate limit exceeded", exitCode: 1 });
2562
- mockPi.onCall({ jsonl: [events.assistantMessage("Declared echo accepted", "claude-opus-5")] });
2563
- const executor = makeExecutor([makeAgent("echo", {
2564
- model: "mock/primary",
2565
- fallbackModels: ["ias-claude-opus-5:high"],
2566
- })], { modelResponseAliases: { "databricks-bedrock/ias-claude-opus-5": ["claude-opus-5"] } });
2567
- const result = await executor.executePublic(
2568
- "foreground-response-alias-fallback",
2569
- { agent: "echo", task: "Say hello", async: false, context: "fresh", acceptance: false },
2570
- new AbortController().signal,
2571
- undefined,
2572
- {
2573
- ...makeMinimalCtx(tempDir),
2574
- modelRegistry: { getAvailable: () => [
2575
- { provider: "mock", id: "primary" },
2576
- { provider: "databricks-bedrock", id: "ias-claude-opus-5" },
2577
- ] },
2578
- },
2579
- );
2580
- assert.equal(result.isError, undefined, result.content[0]?.text ?? "");
2581
- assert.deepEqual(result.details.results[0]?.attemptedModels, ["mock/primary", "databricks-bedrock/ias-claude-opus-5:high"]);
2582
- assert.equal(result.details.results[0]?.model, "databricks-bedrock/ias-claude-opus-5:high");
2583
- const args = readAllCallArgs()[1]!;
2584
- assert.equal(args[args.indexOf("--model") + 1], "databricks-bedrock/ias-claude-opus-5:high");
2585
- assert.equal(mockPi.callCount(), 2);
2586
- });
2587
-
2588
2640
  it("fails when a configured provider-qualified model starts on a different child model", async () => {
2589
2641
  mockPi.onCall({ jsonl: [events.assistantMessage("wrong provider", "openai-codex/gpt-5.6-sol")] });
2590
2642
  const agents = [makeAgent("echo", { model: "opencode-go/ox-alpha-free:max" })];
@@ -2601,12 +2653,9 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2601
2653
 
2602
2654
  assert.equal(result.exitCode, 1);
2603
2655
  assert.equal(result.model, "opencode-go/ox-alpha-free:max");
2604
- assert.deepEqual(result.attemptedModels, ["opencode-go/ox-alpha-free:max"]);
2605
2656
  assert.match(result.error ?? "", /model_verification_failed/);
2606
2657
  assert.match(result.error ?? "", /Expected 'opencode-go\/ox-alpha-free:max'/);
2607
2658
  assert.match(result.error ?? "", /observed 'openai-codex\/gpt-5\.6-sol'/);
2608
- assert.equal(result.modelAttempts?.[0]?.success, false);
2609
- assert.match(result.modelAttempts?.[0]?.error ?? "", /model_verification_failed/);
2610
2659
  const args = readAllCallArgs()[0]!;
2611
2660
  assert.equal(args[args.indexOf("--model") + 1], "opencode-go/ox-alpha-free:max");
2612
2661
  assert.equal(mockPi.callCount(), 1);
@@ -2650,7 +2699,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2650
2699
 
2651
2700
  assert.equal(result.exitCode, 0);
2652
2701
  assert.equal(result.model, "github-copilot/gpt-5-mini");
2653
- assert.deepEqual(result.attemptedModels, ["github-copilot/gpt-5-mini"]);
2654
2702
  });
2655
2703
 
2656
2704
  it("cancels final drain while agent_end reports a retry and waits for agent_settled", async () => {
@@ -2700,7 +2748,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2700
2748
  assert.equal(result.usage.output, 50); // from mock
2701
2749
  });
2702
2750
 
2703
- it("retries with fallback models on retryable provider failures", async () => {
2751
+ it("returns a provider failure after one foreground model launch", async () => {
2704
2752
  mockPi.onCall({
2705
2753
  jsonl: [{
2706
2754
  type: "message_end",
@@ -2714,122 +2762,20 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2714
2762
  }],
2715
2763
  exitCode: 1,
2716
2764
  });
2717
- mockPi.onCall({ output: "Recovered on fallback" });
2718
- const agents = [makeAgent("echo", {
2719
- model: "openai/gpt-5-mini",
2720
- fallbackModels: ["anthropic/claude-sonnet-4"],
2721
- })];
2722
-
2723
- const result = await runSync(tempDir, agents, "echo", "Task", {
2724
- runId: "fallback-sync",
2725
- });
2726
-
2727
- assert.equal(result.exitCode, 0);
2728
- assert.equal(result.model, "anthropic/claude-sonnet-4");
2729
- assert.deepEqual(result.attemptedModels, ["openai/gpt-5-mini", "anthropic/claude-sonnet-4"]);
2730
- assert.equal(result.modelAttempts?.length, 2);
2731
- assert.equal(result.modelAttempts?.[0]?.success, false);
2732
- assert.equal(result.modelAttempts?.[1]?.success, true);
2733
- assert.equal(result.usage.turns, 2);
2734
- assert.equal(mockPi.callCount(), 2);
2735
- });
2736
-
2737
- it("retries with fallback models when provider errors exit zero", async () => {
2738
- mockPi.onCall({
2739
- jsonl: [{
2740
- type: "message_end",
2741
- message: {
2742
- role: "assistant",
2743
- content: [{ type: "text", text: "weekly quota hit" }],
2744
- model: "openai/gpt-5-mini",
2745
- errorMessage: "429 you have reached your weekly usage limit / quota exceeded",
2746
- usage: { input: 10, output: 5, cacheRead: 0, cacheWrite: 0, cost: { total: 0.01 } },
2747
- },
2748
- }],
2749
- exitCode: 0,
2750
- });
2751
- mockPi.onCall({ output: "Recovered on fallback" });
2752
- const agents = [makeAgent("echo", {
2753
- model: "openai/gpt-5-mini",
2754
- fallbackModels: ["anthropic/claude-sonnet-4"],
2755
- })];
2756
-
2757
- const result = await runSync(tempDir, agents, "echo", "Task", {
2758
- runId: "fallback-zero-exit-provider-error",
2759
- });
2760
-
2761
- assert.equal(result.exitCode, 0);
2762
- assert.equal(result.model, "anthropic/claude-sonnet-4");
2763
- assert.deepEqual(result.modelAttempts?.map((attempt) => attempt.success), [false, true]);
2764
- });
2765
-
2766
- it("retries with fallback models when a zero-exit attempt has empty output", async () => {
2767
- mockPi.onCall({
2768
- jsonl: [{
2769
- type: "message_end",
2770
- message: {
2771
- role: "assistant",
2772
- content: [{ type: "text", text: "" }],
2773
- model: "openai/gpt-5-mini",
2774
- stopReason: "error",
2775
- usage: { input: 10, output: 0, cacheRead: 0, cacheWrite: 0, cost: { total: 0.01 } },
2776
- },
2777
- }],
2778
- exitCode: 0,
2779
- });
2780
- mockPi.onCall({ output: "Recovered from empty output" });
2781
- const agents = [makeAgent("echo", {
2782
- model: "openai/gpt-5-mini",
2783
- fallbackModels: ["anthropic/claude-sonnet-4"],
2784
- })];
2785
-
2786
- const result = await runSync(tempDir, agents, "echo", "Task", {
2787
- runId: "fallback-zero-exit-empty-output",
2788
- });
2789
-
2790
- assert.equal(result.exitCode, 0);
2791
- assert.equal(result.model, "anthropic/claude-sonnet-4");
2792
- assert.equal(result.finalOutput, "Recovered from empty output");
2793
- assert.match(result.modelAttempts?.[0]?.error ?? "", /no output/i);
2794
- assert.deepEqual(result.modelAttempts?.map((attempt) => attempt.success), [false, true]);
2795
- assert.equal(mockPi.callCount(), 2);
2796
- });
2797
-
2798
- it("prefers empty-output fallback over an earlier tool error", async () => {
2799
- mockPi.onCall({
2800
- stdoutRaw: [
2801
- events.toolResult("read", "ENOENT: no such file or directory", true),
2802
- events.toolResult("read", "recovered file contents"),
2803
- {
2804
- type: "message_end",
2805
- message: {
2806
- role: "assistant",
2807
- content: [{ type: "text", text: "" }],
2808
- model: "openai/gpt-5-mini",
2809
- stopReason: "stop",
2810
- usage: { input: 0, output: 4, cacheRead: 0, cacheWrite: 0, cost: { total: 0 } },
2811
- },
2812
- },
2813
- ].map((event) => JSON.stringify(event)).join("\n"),
2814
- exitCode: 0,
2815
- });
2816
- mockPi.onCall({ output: "Recovered on fallback" });
2817
- const agents = [makeAgent("echo", {
2818
- model: "openai/gpt-5-mini",
2819
- fallbackModels: ["anthropic/claude-sonnet-4"],
2820
- })];
2765
+ mockPi.onCall({ output: "unexpected second launch" });
2766
+ const agents = [makeAgent("echo", { model: "openai/gpt-5-mini" })];
2821
2767
 
2822
2768
  const result = await runSync(tempDir, agents, "echo", "Task", {
2823
- runId: "fallback-empty-output-after-tool-error",
2769
+ runId: "single-model-sync",
2824
2770
  });
2825
2771
 
2826
- assert.equal(result.exitCode, 0);
2827
- assert.equal(result.model, "anthropic/claude-sonnet-4");
2828
- assert.match(result.modelAttempts?.[0]?.error ?? "", /no output/i);
2829
- assert.equal(mockPi.callCount(), 2);
2772
+ assert.equal(result.exitCode, 1);
2773
+ assert.equal(result.model, "openai/gpt-5-mini");
2774
+ assert.equal("modelAttempts" in result, false);
2775
+ assert.equal(mockPi.callCount(), 1);
2830
2776
  });
2831
2777
 
2832
- it("fails zero-exit provider errors when no fallback succeeds", async () => {
2778
+ it("fails zero-exit provider errors after one launch", async () => {
2833
2779
  mockPi.onCall({
2834
2780
  jsonl: [{
2835
2781
  type: "message_end",
@@ -2846,12 +2792,11 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2846
2792
  const agents = [makeAgent("echo", { model: "openai/gpt-5-mini" })];
2847
2793
 
2848
2794
  const result = await runSync(tempDir, agents, "echo", "Task", {
2849
- runId: "zero-exit-provider-error-no-fallback",
2795
+ runId: "zero-exit-provider-error",
2850
2796
  });
2851
2797
 
2852
2798
  assert.equal(result.exitCode, 1);
2853
2799
  assert.match(result.error ?? "", /429 quota exceeded/);
2854
- assert.deepEqual(result.modelAttempts?.map((attempt) => attempt.success), [false]);
2855
2800
  });
2856
2801
 
2857
2802
  it("treats recovered child tool errors as successful foreground runs", async () => {
@@ -2933,72 +2878,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
2933
2878
  assert.equal(result.progress.status, "failed");
2934
2879
  });
2935
2880
 
2936
- it("fails when all fallback model attempts report provider errors", async () => {
2937
- for (const model of ["openai/gpt-5-mini", "anthropic/claude-sonnet-4"]) {
2938
- mockPi.onCall({
2939
- jsonl: [{
2940
- type: "message_end",
2941
- message: {
2942
- role: "assistant",
2943
- content: [{ type: "text", text: `${model} quota hit` }],
2944
- model,
2945
- errorMessage: "429 quota exceeded",
2946
- usage: { input: 10, output: 5, cacheRead: 0, cacheWrite: 0, cost: { total: 0.01 } },
2947
- },
2948
- }],
2949
- exitCode: 0,
2950
- });
2951
- }
2952
- const agents = [makeAgent("echo", {
2953
- model: "openai/gpt-5-mini",
2954
- fallbackModels: ["anthropic/claude-sonnet-4"],
2955
- })];
2956
-
2957
- const result = await runSync(tempDir, agents, "echo", "Task", {
2958
- runId: "zero-exit-provider-error-all-fallbacks-fail",
2959
- });
2960
-
2961
- assert.equal(result.exitCode, 1);
2962
- assert.deepEqual(result.modelAttempts?.map((attempt) => attempt.success), [false, false]);
2963
- assert.match(result.error ?? "", /429 quota exceeded/);
2964
- });
2965
-
2966
- it("baselines output files per fallback attempt", async () => {
2967
- const outputPath = path.join(tempDir, "fallback-output.md");
2968
- mockPi.onCall({
2969
- jsonl: [{
2970
- type: "message_end",
2971
- message: {
2972
- role: "assistant",
2973
- content: [{ type: "text", text: "primary failed" }],
2974
- model: "openai/gpt-5-mini",
2975
- errorMessage: "429 quota exceeded",
2976
- usage: { input: 10, output: 5, cacheRead: 0, cacheWrite: 0, cost: { total: 0.01 } },
2977
- },
2978
- }],
2979
- exitCode: 0,
2980
- delay: 100,
2981
- });
2982
- mockPi.onCall({ output: "fallback assistant output" });
2983
- const agents = [makeAgent("echo", {
2984
- model: "openai/gpt-5-mini",
2985
- fallbackModels: ["anthropic/claude-sonnet-4"],
2986
- })];
2987
-
2988
- const runPromise = runSync(tempDir, agents, "echo", "Task", {
2989
- runId: "fallback-output-per-attempt",
2990
- outputPath,
2991
- });
2992
- setTimeout(() => {
2993
- fs.writeFileSync(outputPath, "stale partial output from failed primary", "utf-8");
2994
- }, 20);
2995
-
2996
- const result = await runPromise;
2997
-
2998
- assert.equal(result.exitCode, 0);
2999
- assert.equal(fs.readFileSync(outputPath, "utf-8"), "fallback assistant output");
3000
- });
3001
-
3002
2881
  it("does not retry on ordinary task/tool failures", async () => {
3003
2882
  mockPi.onCall({
3004
2883
  jsonl: [events.toolResult("bash", "process exited with code 127", true)],
@@ -3006,15 +2885,13 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
3006
2885
  });
3007
2886
  const agents = [makeAgent("echo", {
3008
2887
  model: "openai/gpt-5-mini",
3009
- fallbackModels: ["anthropic/claude-sonnet-4"],
3010
2888
  })];
3011
2889
 
3012
2890
  const result = await runSync(tempDir, agents, "echo", "Task", {
3013
- runId: "no-fallback-task-failure",
2891
+ runId: "single-launch-task-failure",
3014
2892
  });
3015
2893
 
3016
2894
  assert.equal(result.exitCode, 127);
3017
- assert.equal(result.modelAttempts?.length, 1);
3018
2895
  assert.equal(mockPi.callCount(), 1);
3019
2896
  });
3020
2897
 
@@ -3024,19 +2901,17 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
3024
2901
  stderr: "APIConnectionError: Connection closed.",
3025
2902
  exitCode: 1,
3026
2903
  });
3027
- mockPi.onCall({ output: "fallback must not run" });
2904
+ mockPi.onCall({ output: "second launch must not run" });
3028
2905
  const agents = [makeAgent("echo", {
3029
2906
  model: "openai/gpt-5-mini",
3030
- fallbackModels: ["anthropic/claude-sonnet-4"],
3031
2907
  })];
3032
2908
 
3033
2909
  const result = await runSync(tempDir, agents, "echo", "Task", {
3034
- runId: "no-fallback-raw-stderr",
2910
+ runId: "single-launch-raw-stderr",
3035
2911
  });
3036
2912
 
3037
2913
  assert.equal(result.exitCode, 1);
3038
2914
  assert.match(result.error ?? "", /Connection closed/u);
3039
- assert.equal(result.modelAttempts?.length, 1);
3040
2915
  assert.equal(mockPi.callCount(), 1);
3041
2916
  });
3042
2917
 
@@ -3075,7 +2950,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
3075
2950
 
3076
2951
  assert.equal(result.exitCode, 1);
3077
2952
  assert.match(result.error ?? "", /Subagent produced no output after terminal assistant stopReason "aborted"\./u);
3078
- assert.equal(result.modelAttempts?.length, 1);
3079
2953
  assert.equal(mockPi.callCount(), 1);
3080
2954
  });
3081
2955
 
@@ -3111,7 +2985,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
3111
2985
 
3112
2986
  assert.equal(result.exitCode, 1);
3113
2987
  assert.match(result.error ?? "", /Subagent produced no output after terminal assistant stopReason "aborted"\./u);
3114
- assert.equal(result.modelAttempts?.length, 1);
3115
2988
  assert.equal(mockPi.callCount(), 1);
3116
2989
  });
3117
2990
 
@@ -3130,7 +3003,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
3130
3003
  mockPi.onCall({ output: "Compaction recovery must not run" });
3131
3004
  const agents = [makeAgent("echo", {
3132
3005
  model: "openai/gpt-5-mini",
3133
- fallbackModels: ["anthropic/claude-sonnet-4"],
3134
3006
  })];
3135
3007
 
3136
3008
  const result = await runSync(tempDir, agents, "echo", "Task", {
@@ -3140,55 +3012,68 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
3140
3012
 
3141
3013
  assert.equal(result.exitCode, 1);
3142
3014
  assert.match(result.error ?? "", /Connection reset by provider transport/u);
3143
- assert.equal(result.modelAttempts?.length, 1);
3144
3015
  assert.equal(mockPi.callCount(), 1);
3145
3016
  });
3146
3017
 
3147
- it("resumes the retained session once after a compaction-induced abort following completed tool work", async () => {
3018
+ it("resumes a retained compaction-aborted session once on the same model", async () => {
3148
3019
  const sessionFile = path.join(tempDir, "abort-recovery-session.jsonl");
3149
3020
  mockPi.onCall({
3150
3021
  jsonl: [
3151
3022
  events.toolStart("write", { path: "side-effect.txt", content: "done" }),
3152
3023
  events.toolEnd("write"),
3153
3024
  events.toolResult("write", "Wrote side-effect.txt"),
3154
- { type: "compaction_start" },
3155
- {
3156
- type: "message_end",
3157
- message: {
3158
- role: "assistant",
3159
- content: [],
3160
- model: "openai/gpt-5-mini",
3161
- stopReason: "aborted",
3162
- usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: { total: 0 } },
3163
- },
3164
- },
3025
+ { type: "message_end", message: { role: "assistant", content: [], model: "openai/gpt-5-mini", stopReason: "error", errorMessage: "This operation was aborted", usage: { input: 10, output: 0, cacheRead: 2, cacheWrite: 1, cost: { total: 0.01 } } } },
3165
3026
  { type: "agent_settled" },
3027
+ { type: "compaction_start" },
3166
3028
  ],
3029
+ omitImplicitFinalEvents: true,
3167
3030
  writeFiles: [{ path: "side-effect.txt", content: "done" }, { path: sessionFile, content: "{}\n" }],
3168
3031
  keepAliveAfterFinalMessageMs: 5_000,
3169
3032
  exitCode: 0,
3170
3033
  });
3171
3034
  mockPi.onCall({ output: "Recovered from retained session" });
3172
- const agents = [makeAgent("echo", {
3173
- model: "openai/gpt-5-mini",
3174
- fallbackModels: ["anthropic/claude-sonnet-4"],
3175
- })];
3176
3035
 
3177
- const result = await runSync(tempDir, agents, "echo", "Task", {
3178
- runId: "resume-provider-after-tool",
3036
+ const attemptUsage: Array<{ input: number; output: number; cacheRead: number; cacheWrite: number; turns: number }> = [];
3037
+ const delegationRequest = { requestId: "retry-usage", ownerRunId: "owner", nodeId: "node", agent: "echo", task: "Task", context: "fresh", cwd: tempDir, result: { kind: "text" } } satisfies SubagentDelegationRequest;
3038
+ const result = await runSync(tempDir, [makeAgent("echo", { model: "openai/gpt-5-mini" })], "echo", "Task", {
3039
+ runId: "same-model-abort-recovery",
3179
3040
  sessionFile,
3041
+ onUpdate(update) {
3042
+ const usage = toSubagentDelegationUpdate(delegationRequest, update)?.usage;
3043
+ if (usage) attemptUsage.push(usage);
3044
+ },
3180
3045
  });
3181
3046
 
3182
3047
  assert.equal(result.exitCode, 0);
3183
3048
  assert.equal(result.finalOutput, "Recovered from retained session");
3184
- assert.deepEqual(result.attemptedModels, ["openai/gpt-5-mini"]);
3185
- assert.deepEqual(result.modelAttempts?.map((attempt) => attempt.success), [false, true]);
3049
+ assert.deepEqual(attemptUsage[0], { input: 10, output: 0, cacheRead: 2, cacheWrite: 1, turns: 1 });
3050
+ assert.deepEqual(attemptUsage.at(-1), { input: 100, output: 50, cacheRead: 0, cacheWrite: 0, turns: 1 });
3051
+ assert.deepEqual(result.usage, { input: 110, output: 50, cacheRead: 2, cacheWrite: 1, cost: 0.011, turns: 2 });
3186
3052
  assert.equal(mockPi.callCount(), 2);
3187
- const [firstArgs, resumedArgs] = readAllCallArgs();
3188
- assert.equal(firstArgs?.[firstArgs.indexOf("--session") + 1], sessionFile);
3189
- assert.equal(resumedArgs?.[resumedArgs.indexOf("--session") + 1], sessionFile);
3053
+ for (const args of readAllCallArgs()) {
3054
+ assert.equal(args[args.indexOf("--model") + 1], "openai/gpt-5-mini");
3055
+ assert.equal(args[args.indexOf("--session") + 1], sessionFile);
3056
+ }
3190
3057
  assert.match(readAllCallArgs(true)[1]?.at(-1) ?? "", /Continue from the current files and transcript/);
3191
- assert.equal(fs.readFileSync(path.join(tempDir, "side-effect.txt"), "utf-8"), "done");
3058
+ });
3059
+
3060
+ it("does not recover a compaction abort without a retained session", async () => {
3061
+ mockPi.onCall({
3062
+ jsonl: [
3063
+ events.assistantMessage("Useful inspection completed."),
3064
+ { type: "compaction_start" },
3065
+ { type: "message_end", message: { role: "assistant", content: [], model: "openai/gpt-5-mini", stopReason: "aborted", usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: { total: 0 } } } },
3066
+ { type: "agent_settled" },
3067
+ ],
3068
+ exitCode: 0,
3069
+ });
3070
+ mockPi.onCall({ output: "unexpected recovery" });
3071
+
3072
+ const result = await runSync(tempDir, [makeAgent("echo", { model: "openai/gpt-5-mini" })], "echo", "Task", { runId: "abort-recovery-no-session" });
3073
+
3074
+ assert.equal(result.exitCode, 1);
3075
+ assert.match(result.error ?? "", /Compaction-induced child abort could not be resumed safely: retained session unavailable/);
3076
+ assert.equal(mockPi.callCount(), 1);
3192
3077
  });
3193
3078
 
3194
3079
  it("tracks progress during execution", async () => {
@@ -3578,6 +3463,24 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
3578
3463
  assert.ok(!JSON.stringify(result.launchResolvedExtensions).includes(tempDir), "projection should not expose raw extension paths");
3579
3464
  });
3580
3465
 
3466
+ it("resolves foreground required extensions by Pi session ID rather than session file", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async (t) => {
3467
+ mockPi.onCall({ output: "required extension loaded" });
3468
+ const extensionPath = path.join(tempDir, "foreground-required.mjs");
3469
+ fs.writeFileSync(extensionPath, "export default function () {}\n");
3470
+ const parentPiSessionId = "foreground-pi-session";
3471
+ const registration = registerRequiredChildExtensions({ sessionId: parentPiSessionId, extensions: [{ id: "foreground-required", path: extensionPath }] });
3472
+ t.after(registration.dispose);
3473
+ const ctx = makeMinimalCtx(tempDir);
3474
+ ctx.sessionManager.getSessionId = () => parentPiSessionId;
3475
+ ctx.sessionManager.getSessionFile = () => path.join(tempDir, "sessions", "different-file-identity.jsonl");
3476
+ const result = await makeExecutor([makeAgent("echo")]).execute("foreground-required", { agent: "echo", task: "Load host policy" }, new AbortController().signal, undefined, ctx);
3477
+
3478
+ assert.equal(result.isError, undefined);
3479
+ assert.deepEqual(readCall().launch?.extensionPaths, [fs.realpathSync(extensionPath)]);
3480
+ assert.deepEqual(result.details?.results?.[0]?.launchResolvedExtensions?.required, ["foreground-required"]);
3481
+ assert.equal(JSON.stringify(result.details?.results?.[0]?.launchResolvedExtensions).includes(extensionPath), false);
3482
+ });
3483
+
3581
3484
  it("routes foreground artifacts to the configured session directory", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
3582
3485
  mockPi.onCall({ output: "session artifact result" });
3583
3486
  const sessionFile = path.join(tempDir, "sessions", "parent-session", "session.jsonl");
@@ -4036,6 +3939,41 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
4036
3939
  assert.deepEqual(childTimeout.details.workflow?.receipt?.entries["slow-child"]?.terminalOutcome, { state: "partial", reason: "timeout" });
4037
3940
  });
4038
3941
 
3942
+ it("rejects workflow-script timeouts above the maximum schedulable timer delay before launch", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
3943
+ const executor = makeExecutor([makeAgent("echo")]);
3944
+ const cases = [
3945
+ { name: "timeoutMs", params: { timeoutMs: 2_147_483_648 } },
3946
+ { name: "maxRuntimeMs", params: { maxRuntimeMs: 2_147_483_648 } },
3947
+ { name: "maxRuntimeMs", params: { timeoutMs: 1_000, maxRuntimeMs: 2_147_483_648 } },
3948
+ ] as const;
3949
+ for (const { name, params } of cases) {
3950
+ const result = await executor.execute(
3951
+ `workflow-overflow-${name}`,
3952
+ { async: false, ...params, workflowScript: `return await runs.run("never", { agent: "echo", task: "Never launch" });` },
3953
+ new AbortController().signal,
3954
+ undefined,
3955
+ makeMinimalCtx(tempDir),
3956
+ );
3957
+ assert.equal(result.isError, true);
3958
+ assert.match(result.content[0]?.text ?? "", new RegExp(`${name} must be a positive integer no larger than 2147483647`));
3959
+ }
3960
+ assert.equal(readAllCallArgs().length, 0, "invalid workflow timeout must be rejected before child launch");
3961
+ });
3962
+
3963
+ it("rejects resume timeouts above the maximum schedulable timer delay before launch", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
3964
+ const executor = makeExecutor([makeAgent("echo")]);
3965
+ const result = await executor.execute(
3966
+ "resume-overflow",
3967
+ { action: "resume", id: "missing-run", message: "continue", timeoutMs: 2_147_483_648 },
3968
+ new AbortController().signal,
3969
+ undefined,
3970
+ makeMinimalCtx(tempDir),
3971
+ );
3972
+ assert.equal(result.isError, true);
3973
+ assert.match(result.content[0]?.text ?? "", /timeoutMs must be a positive integer no larger than 2147483647/);
3974
+ assert.equal(readAllCallArgs().length, 0);
3975
+ });
3976
+
4039
3977
  it("runs omitted async launches in the background when the global default is enabled", { skip: !createSubagentExecutor ? "executor not importable" : undefined }, async () => {
4040
3978
  const executor = makeExecutor([makeAgent("echo")], {}, true);
4041
3979
 
@@ -4331,22 +4269,21 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
4331
4269
 
4332
4270
  it("fails with actionable diagnostics when a requested extension tool is not loaded", async () => {
4333
4271
  mockPi.onCall({ output: "Model incorrectly claimed success", missingTools: ["fixture_search"] });
4334
- const agents = [makeAgent("extension-worker", { tools: ["read", "fixture_search"], fallbackModels: ["mock/fallback-model"] })];
4272
+ const agents = [makeAgent("extension-worker", { tools: ["read", "fixture_search"] })];
4335
4273
 
4336
4274
  const result = await runSync(tempDir, agents, "extension-worker", "Use fixture search", { runId: "missing-extension-tool" });
4337
4275
 
4338
4276
  assert.equal(result.exitCode, 1);
4339
4277
  assert.match(result.error ?? "", /ran as a foreground child, which never loads the parent's ambient extensions, and these child tools were unavailable: fixture_search/);
4340
- assert.match(result.error ?? "", /must run as background children \(`async: true`\)/);
4278
+ assert.match(result.error ?? "", /require background children \(`async: true`\)/);
4341
4279
  assert.match(result.error ?? "", /subagentOnlyExtensions/);
4342
4280
  assert.match(result.error ?? "", /strict allowlist/);
4343
4281
  assert.doesNotMatch(result.finalOutput ?? "", /Model incorrectly claimed success/);
4344
4282
  assert.equal(result.messages?.length, 0);
4345
4283
  assert.equal(result.usage.turns, 0);
4346
- assert.equal(result.modelAttempts?.length, 1);
4347
4284
  });
4348
4285
 
4349
- it("records blocked mutation effects when foreground implementation tools are missing", async () => {
4286
+ it("preserves missing child tool failures without inferring mutation intent", async () => {
4350
4287
  mockPi.onCall({ output: "I cannot edit because fixture_search is missing", missingTools: ["fixture_search"] });
4351
4288
  const agents = [makeAgent("worker", { tools: ["read", "fixture_search"] })];
4352
4289
 
@@ -4354,11 +4291,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
4354
4291
 
4355
4292
  assert.equal(result.exitCode, 1);
4356
4293
  assert.match(result.error ?? "", /these child tools were unavailable: fixture_search/);
4357
- assert.doesNotMatch(result.error ?? "", /completed without making edits/);
4358
- assert.equal(result.effects?.fileMutation?.status, "blocked");
4359
- assert.equal(result.effects?.fileMutation?.expected, true);
4360
- assert.equal(result.effects?.fileMutation?.attempted, false);
4361
- assert.match(result.effects?.fileMutation?.message ?? "", /these child tools were unavailable: fixture_search/);
4294
+ assert.equal(result.effects?.fileMutation, undefined);
4362
4295
  });
4363
4296
 
4364
4297
  it("passes custom tool extensions through even when explicit extensions are allowlisted", { skip: process.platform === "win32" ? "extension path resolution intermittent on Windows CI" : undefined }, async () => {
@@ -4441,6 +4374,24 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
4441
4374
  });
4442
4375
  });
4443
4376
 
4377
+ it("completes a structured-only foreground terminal after watchdog settlement", async () => {
4378
+ await withIsolatedWatchdogSettings(tempDir, async () => {
4379
+ writeWatchdogSettings(tempDir);
4380
+ const callsBefore = mockPi.callCount();
4381
+ mockPi.onCall({
4382
+ jsonl: [childWatchdogStatus("idle", 1)],
4383
+ structuredOutput: { ok: true },
4384
+ });
4385
+ const structuredOutput = createStructuredOutputRuntime({ type: "object", required: ["ok"], properties: { ok: { type: "boolean" } } }, tempDir);
4386
+
4387
+ const result = await runSync(tempDir, makeAgentConfigs(["echo"]), "echo", "Return data", { runId: "watchdog-structured-terminal", structuredOutput });
4388
+
4389
+ assert.equal(result.exitCode, 0, result.error);
4390
+ assert.deepEqual(result.structuredOutput, { ok: true });
4391
+ assert.equal(mockPi.callCount(), callsBefore + 1, "settled structured completion must not continue with another turn");
4392
+ });
4393
+ });
4394
+
4444
4395
  it("falls back after child watchdog tail timeout without failing successful foreground output", async () => {
4445
4396
  await withIsolatedWatchdogSettings(tempDir, async () => {
4446
4397
  writeWatchdogSettings(tempDir, 150);
@@ -4518,16 +4469,19 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
4518
4469
  const acceptance = { level: "checked" as const, criteria: ["Ship it"] };
4519
4470
  const blockerCheck = (result: RunSyncResult) => result.acceptance?.runtimeChecks?.find((entry) => entry.id === "watchdog-blocker");
4520
4471
 
4521
- mockPi.onCall({ jsonl: [events.watchdogWarning("concern", "Minor naming concern"), events.acceptanceReport(), events.watchdogWarning("blocker", "Claims tests passed without running them")] });
4522
- const unaddressed = await runSync(tempDir, agents, "echo", "Task", { runId: "watchdog-child-run", acceptance });
4472
+ mockPi.onCall({ jsonl: [events.watchdogStatusWarning("concern", "Minor naming concern", { runId: "watchdog-child-run", agent: "echo", childIndex: 0 }), events.acceptanceReport(), events.watchdogStatusWarning("blocker", "Claims tests passed without running them", { importance: "low", seq: 2, runId: "watchdog-child-run", agent: "echo", childIndex: 0 })], structuredOutput: { ok: true } });
4473
+ const structuredOutput = createStructuredOutputRuntime({ type: "object", required: ["ok"], properties: { ok: { type: "boolean" } } }, tempDir);
4474
+ const unaddressed = await runSync(tempDir, agents, "echo", "Task", { runId: "watchdog-child-run", acceptance, structuredOutput });
4523
4475
  assert.deepEqual(unaddressed.watchdog?.warnings?.map((warning) => [warning.severity, warning.addressed]), [["concern", true], ["blocker", false]]);
4524
4476
  assert.equal(blockerCheck(unaddressed)?.status, "failed");
4525
- assert.match(blockerCheck(unaddressed)?.message ?? "", /Unresolved watchdog blocker: Claims tests passed without running them/);
4477
+ assert.equal(blockerCheck(unaddressed)?.message, "Unresolved watchdog blocker (details are available in child watchdog status).");
4526
4478
  assert.equal(unaddressed.acceptance?.status, "rejected");
4527
4479
  assert.equal(unaddressed.exitCode, 1);
4480
+ assert.deepEqual(unaddressed.structuredOutput, { ok: true }, "a real blocker remains visible alongside valid structured evidence");
4528
4481
  assert.match(unaddressed.error ?? "", /Unresolved watchdog blocker/);
4482
+ assert.doesNotMatch(unaddressed.error ?? "", /Claims tests passed without running them/);
4529
4483
 
4530
- mockPi.onCall({ jsonl: [events.assistantMessage("first pass"), events.watchdogWarning("blocker", "Claims tests passed without running them"), events.acceptanceReport()] });
4484
+ mockPi.onCall({ jsonl: [events.assistantMessage("first pass"), events.watchdogStatusWarning("blocker", "Claims tests passed without running them", { runId: "watchdog-child-run-2", agent: "echo", childIndex: 0 }), events.acceptanceReport()] });
4531
4485
  const addressed = await runSync(tempDir, agents, "echo", "Task", { runId: "watchdog-child-run-2", acceptance });
4532
4486
  assert.equal(addressed.watchdog?.warnings?.[0]?.addressed, true);
4533
4487
  assert.equal(blockerCheck(addressed)?.status, "passed");
@@ -4943,9 +4897,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
4943
4897
  (receipt.progress as unknown as { recentOutput: string[] }).recentOutput.push("caller-only progress");
4944
4898
  receipt.usage.turns = 999;
4945
4899
  receipt.usage.input = 999;
4946
- receipt.attemptedModels = ["caller-only/model"];
4947
- receipt.modelAttempts = [{ success: false, exitCode: 99, error: "caller-only attempt" }];
4948
- receipt.effects = { fileMutation: { status: "missing", expected: true, attempted: false, message: "caller-only effect" } };
4900
+ receipt.effects = { settlementDiagnostic: { finalTextPresent: false, mutation: { attempted: false, observed: false }, afterCompactionSettlement: false } };
4949
4901
  receipt.execution = { status: "failed", success: false, exitCode: 99 };
4950
4902
  receipt.review = { status: "blockers" };
4951
4903
 
@@ -4958,8 +4910,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
4958
4910
  assert.equal(terminal.acceptance?.runtimeChecks.every((check) => check.status === "passed"), true);
4959
4911
  assert.equal(terminal.progress.status, "completed");
4960
4912
  assert.deepEqual(terminal.usage, { turns: 2, input: 107, output: 53, cacheRead: 0, cacheWrite: 0, cost: 0.002 });
4961
- assert.deepEqual(terminal.attemptedModels, ["mock/test-model"]);
4962
- assert.deepEqual(terminal.modelAttempts?.map((attempt) => ({ success: attempt.success, exitCode: attempt.exitCode })), [{ success: true, exitCode: 0 }]);
4963
4913
  assert.equal(terminal.execution?.status, "completed");
4964
4914
  assert.equal(terminal.execution?.success, true);
4965
4915
  assert.equal(terminal.review?.status, "not-requested");
@@ -4970,7 +4920,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
4970
4920
  assert.equal(receiptMessages.length, 2);
4971
4921
  });
4972
4922
 
4973
- it("keeps the full fallback loop and authoritative aggregation alive after detach", async () => {
4923
+ it("returns a provider failure after one detached model launch", async () => {
4974
4924
  mockPi.onCall({
4975
4925
  jsonl: [{
4976
4926
  type: "message_end",
@@ -4984,15 +4934,12 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
4984
4934
  }],
4985
4935
  exitCode: 1,
4986
4936
  });
4987
- mockPi.onCall({ output: "Recovered on detached fallback" });
4988
- const agents = [makeAgent("echo", {
4989
- model: "openai/gpt-5-mini",
4990
- fallbackModels: ["anthropic/claude-sonnet-4"],
4991
- })];
4937
+ mockPi.onCall({ output: "unexpected second launch" });
4938
+ const agents = [makeAgent("echo", { model: "openai/gpt-5-mini" })];
4992
4939
  let terminal: RunSyncResult | undefined;
4993
4940
 
4994
4941
  const receipt = await runSync(tempDir, agents, "echo", "Task", {
4995
- runId: "detached-fallback-loop",
4942
+ runId: "detached-single-model",
4996
4943
  acceptance: false,
4997
4944
  onDetachReady: (detach) => assert.equal(detach("user request"), true),
4998
4945
  onDetachedExit: (result) => { terminal = result as RunSyncResult; },
@@ -5003,12 +4950,8 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
5003
4950
  assert.ok(terminal);
5004
4951
  assert.equal(terminal.detached, undefined, "terminal status must not remain detached");
5005
4952
  assert.equal(terminal.detachedReason, "user request");
5006
- assert.equal(terminal.exitCode, 0);
5007
- assert.equal(terminal.finalOutput, "Recovered on detached fallback");
5008
- assert.deepEqual(terminal.attemptedModels, ["openai/gpt-5-mini", "anthropic/claude-sonnet-4"]);
5009
- assert.deepEqual(terminal.modelAttempts?.map((attempt) => attempt.success), [false, true]);
5010
- assert.equal(terminal.usage.turns, 2);
5011
- assert.equal(mockPi.callCount(), 2);
4953
+ assert.equal(terminal.exitCode, 1);
4954
+ assert.equal(mockPi.callCount(), 1);
5012
4955
  });
5013
4956
 
5014
4957
  it("terminalizes a post-receipt completion pipeline throw exactly once with strict projections", async () => {
@@ -5043,9 +4986,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
5043
4986
  receipt.progress.status = "completed";
5044
4987
  receipt.usage.turns = 999;
5045
4988
  receipt.usage.input = 999;
5046
- receipt.attemptedModels = ["caller-only/fallback"];
5047
- receipt.modelAttempts = [{ success: true, exitCode: 0 }];
5048
- receipt.effects = { fileMutation: { status: "observed", expected: false, attempted: true, message: "caller-only fallback effect" } };
4989
+ receipt.effects = { settlementDiagnostic: { finalTextPresent: false, mutation: { attempted: true, observed: false }, afterCompactionSettlement: false } };
5049
4990
  for (let attempt = 0; attempt < 100 && !terminal; attempt++) await new Promise((resolve) => setTimeout(resolve, 20));
5050
4991
  assert.ok(terminal);
5051
4992
  assert.equal(callbackCount, 1);
@@ -5061,8 +5002,6 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
5061
5002
  assert.deepEqual(terminal.agentContract, { version: 1 });
5062
5003
  assert.deepEqual(terminal.effects, {});
5063
5004
  assert.equal(terminal.usage.turns, 0);
5064
- assert.equal(terminal.attemptedModels, undefined);
5065
- assert.equal(terminal.modelAttempts, undefined);
5066
5005
  assert.doesNotMatch(JSON.stringify(terminal.messages), /caller-only fallback message/);
5067
5006
  assert.match(terminal.error ?? "", /Detached completion pipeline failed after receipt/);
5068
5007
  });
@@ -5336,7 +5275,7 @@ if (!fs.existsSync(${JSON.stringify(holdPath)})) { console.log('{}'); } else {
5336
5275
  let resolveFallbackTerminal!: (result: RunSyncResult) => void;
5337
5276
  const fallbackTerminal = new Promise<RunSyncResult>((resolve) => { resolveFallbackTerminal = resolve; });
5338
5277
  let fallbackRequested = false;
5339
- const receipt = await runSync(tempDir, [makeAgent("echo", { model: "openai/gpt-5-mini", fallbackModels: ["anthropic/claude-sonnet-4"] })], "echo", "Task", {
5278
+ const receipt = await runSync(tempDir, [makeAgent("echo", { model: "openai/gpt-5-mini" })], "echo", "Task", {
5340
5279
  runId: "intercom-no-fallback",
5341
5280
  acceptance: false,
5342
5281
  allowIntercomDetach: true,