@selesai/code 0.13.15 → 0.13.18

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 (473) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +2 -14
  3. package/dist/bun/cli.d.ts +3 -1
  4. package/dist/bun/cli.js +3 -9
  5. package/dist/bun/{register-bedrock.js → runtime-setup.js} +5 -0
  6. package/dist/bun/sandbox-env-setup.d.ts +1 -0
  7. package/dist/bun/sandbox-env-setup.js +3 -0
  8. package/dist/cli/auth-command.d.ts +23 -0
  9. package/dist/cli/auth-command.js +102 -0
  10. package/dist/cli/config-selector.js +2 -1
  11. package/dist/cli/setup.d.ts +1 -0
  12. package/dist/cli/setup.js +11 -0
  13. package/dist/cli.js +2 -14
  14. package/dist/config.d.ts +3 -2
  15. package/dist/config.js +9 -4
  16. package/dist/core/agent-session-runtime.js +15 -7
  17. package/dist/core/agent-session.d.ts +2 -6
  18. package/dist/core/agent-session.js +15 -4
  19. package/dist/core/compaction/branch-summarization.d.ts +1 -1
  20. package/dist/core/compaction/branch-summarization.js +2 -1
  21. package/dist/core/extensions/loader.js +3 -0
  22. package/dist/core/extensions/types.d.ts +16 -2
  23. package/dist/core/http-dispatcher.js +2 -0
  24. package/dist/core/keybindings.d.ts +5 -0
  25. package/dist/core/keybindings.js +4 -0
  26. package/dist/core/messages.d.ts +1 -1
  27. package/dist/core/model-config.d.ts +15 -0
  28. package/dist/core/model-config.js +3 -0
  29. package/dist/core/model-runtime.d.ts +1 -0
  30. package/dist/core/model-runtime.js +5 -2
  31. package/dist/core/provider-composer.js +8 -2
  32. package/dist/core/session-export.d.ts +3 -0
  33. package/dist/core/session-export.js +31 -0
  34. package/dist/core/session-manager.d.ts +3 -2
  35. package/dist/core/session-manager.js +40 -13
  36. package/dist/core/skills.d.ts +1 -1
  37. package/dist/core/skills.js +4 -2
  38. package/dist/core/system-prompt.js +10 -10
  39. package/dist/core/tools/bash.js +3 -117
  40. package/dist/core/tools/edit.d.ts +1 -12
  41. package/dist/core/tools/edit.js +5 -163
  42. package/dist/core/tools/find.js +4 -55
  43. package/dist/core/tools/grep.js +4 -60
  44. package/dist/core/tools/ls.js +4 -49
  45. package/dist/core/tools/read.d.ts +4 -0
  46. package/dist/core/tools/read.js +10 -122
  47. package/dist/core/tools/renderers/bash.d.ts +11 -0
  48. package/dist/core/tools/renderers/bash.js +129 -0
  49. package/dist/core/tools/renderers/edit.d.ts +22 -0
  50. package/dist/core/tools/renderers/edit.js +166 -0
  51. package/dist/core/tools/renderers/find.d.ts +9 -0
  52. package/dist/core/tools/renderers/find.js +63 -0
  53. package/dist/core/tools/renderers/grep.d.ts +9 -0
  54. package/dist/core/tools/renderers/grep.js +68 -0
  55. package/dist/core/tools/renderers/index.d.ts +27 -0
  56. package/dist/core/tools/renderers/index.js +46 -0
  57. package/dist/core/tools/renderers/ls.d.ts +9 -0
  58. package/dist/core/tools/renderers/ls.js +57 -0
  59. package/dist/core/tools/renderers/read.d.ts +10 -0
  60. package/dist/core/tools/renderers/read.js +128 -0
  61. package/dist/core/tools/renderers/write.d.ts +9 -0
  62. package/dist/core/tools/renderers/write.js +152 -0
  63. package/dist/core/tools/write.js +5 -146
  64. package/dist/extensions/capability-gateway/index.ts +12 -1
  65. package/dist/extensions/capability-gateway/integration.test.ts +23 -0
  66. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +18 -0
  67. package/dist/extensions/pi-hermes-memory/README.md +16 -12
  68. package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +1 -1
  69. package/dist/extensions/pi-hermes-memory/package-lock.json +587 -62
  70. package/dist/extensions/pi-hermes-memory/package.json +4 -4
  71. package/dist/extensions/pi-hermes-memory/src/config.ts +32 -0
  72. package/dist/extensions/pi-hermes-memory/src/constants.ts +12 -2
  73. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +109 -51
  74. package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +9 -3
  75. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +257 -98
  76. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +9 -2
  77. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +5 -0
  78. package/dist/extensions/pi-hermes-memory/src/index.ts +22 -2
  79. package/dist/extensions/pi-hermes-memory/src/paths.ts +1 -1
  80. package/dist/extensions/pi-hermes-memory/src/store/db.ts +6 -0
  81. package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +58 -1
  82. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +60 -8
  83. package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +169 -7
  84. package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +7 -21
  85. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +134 -15
  86. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +4 -2
  87. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +24 -9
  88. package/dist/extensions/pi-hermes-memory/src/types.ts +11 -0
  89. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +42 -0
  90. package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +159 -3
  91. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +452 -0
  92. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +39 -0
  93. package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +91 -0
  94. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +29 -0
  95. package/dist/extensions/pi-hermes-memory/tests/store/fts-query.test.ts +116 -0
  96. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +163 -0
  97. package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +233 -0
  98. package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +12 -0
  99. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +175 -0
  100. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +2 -2
  101. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +22 -0
  102. package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +37 -1
  103. package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
  104. package/dist/extensions/pi-intercom/README.md +16 -2
  105. package/dist/extensions/pi-intercom/broker/spawn.test.ts +19 -2
  106. package/dist/extensions/pi-intercom/broker/spawn.ts +4 -4
  107. package/dist/extensions/pi-intercom/index.ts +1 -1
  108. package/dist/extensions/pi-intercom/intercom.integration.test.ts +121 -2
  109. package/dist/extensions/pi-intercom/package.json +1 -1
  110. package/dist/extensions/pi-intercom/project-agent.test.ts +1 -1
  111. package/dist/extensions/pi-intercom/project-agent.ts +1 -6
  112. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +7 -6
  113. package/dist/extensions/pi-rewind-hook/index.test.ts +7 -0
  114. package/dist/extensions/pi-subagents/.github/workflows/test.yml +36 -4
  115. package/dist/extensions/pi-subagents/CHANGELOG.md +120 -0
  116. package/dist/extensions/pi-subagents/README.md +3 -3
  117. package/dist/extensions/pi-subagents/agents/researcher.md +23 -13
  118. package/dist/extensions/pi-subagents/agents/reviewer.md +1 -1
  119. package/dist/extensions/pi-subagents/agents/scout.md +1 -1
  120. package/dist/extensions/pi-subagents/docs/agents.md +32 -16
  121. package/dist/extensions/pi-subagents/docs/configuration.md +41 -15
  122. package/dist/extensions/pi-subagents/docs/extension-api.md +109 -6
  123. package/dist/extensions/pi-subagents/docs/missions.md +2 -0
  124. package/dist/extensions/pi-subagents/docs/models.md +58 -1
  125. package/dist/extensions/pi-subagents/docs/observability.md +50 -12
  126. package/dist/extensions/pi-subagents/docs/tool-reference.md +17 -10
  127. package/dist/extensions/pi-subagents/docs/watchdog.md +1 -1
  128. package/dist/extensions/pi-subagents/docs/workflows.md +26 -9
  129. package/dist/extensions/pi-subagents/package-lock.json +747 -177
  130. package/dist/extensions/pi-subagents/package.json +6 -4
  131. package/dist/extensions/pi-subagents/runner-server-preload.mjs +13 -0
  132. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -1
  133. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
  134. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +21 -4
  135. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
  136. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +2 -0
  137. package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +63 -0
  138. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +61 -16
  139. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
  140. package/dist/extensions/pi-subagents/src/agents/agents.ts +8 -0
  141. package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +0 -1
  142. package/dist/extensions/pi-subagents/src/api/{pi-args.ts → child-tool-plan.ts} +1 -1
  143. package/dist/extensions/pi-subagents/src/api/preflight.ts +7 -4
  144. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -2
  145. package/dist/extensions/pi-subagents/src/api/workflow-resources.ts +6 -0
  146. package/dist/extensions/pi-subagents/src/extension/config.ts +4 -2
  147. package/dist/extensions/pi-subagents/src/extension/doctor.ts +2 -10
  148. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +9 -11
  149. package/dist/extensions/pi-subagents/src/extension/index.ts +99 -10
  150. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +13 -0
  151. package/dist/extensions/pi-subagents/src/extension/rpc.ts +7 -23
  152. package/dist/extensions/pi-subagents/src/extension/schemas.ts +11 -8
  153. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +25 -7
  154. package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +73 -0
  155. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +228 -136
  156. package/dist/extensions/pi-subagents/src/intercom/supervisor-ui.ts +244 -0
  157. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +37 -16
  158. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +18 -18
  159. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +51 -25
  160. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +46 -3
  161. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -3
  162. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +9 -0
  163. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +10 -12
  164. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -15
  165. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +40 -29
  166. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +8 -0
  167. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +79 -247
  168. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +88 -12
  169. package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +6 -6
  170. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +24 -24
  171. package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +96 -0
  172. package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +642 -0
  173. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +75 -6
  174. package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +163 -0
  175. package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +86 -0
  176. package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +31 -0
  177. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +18 -4
  178. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -1
  179. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +597 -1092
  180. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +3 -0
  181. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +4 -0
  182. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +20 -17
  183. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +296 -394
  184. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +4 -0
  185. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +3 -1
  186. package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +9 -5
  187. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +630 -283
  188. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +8 -5
  189. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +78 -98
  190. package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +3 -3
  191. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +16 -3
  192. package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
  193. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +47 -47
  194. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -2
  195. package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +174 -0
  196. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +14 -3
  197. package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +319 -0
  198. package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +25 -0
  199. package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +126 -0
  200. package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +373 -0
  201. package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +530 -0
  202. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +2 -2
  203. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +2 -1
  204. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +16 -0
  205. package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +11 -11
  206. package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +30 -20
  207. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +5 -4
  208. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +84 -15
  209. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +88 -12
  210. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +37 -53
  211. package/dist/extensions/pi-subagents/src/runs/shared/nested-path.ts +1 -1
  212. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +18 -7
  213. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +57 -12
  214. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -4
  215. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +0 -11
  216. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +4 -1
  217. package/dist/extensions/pi-subagents/src/runs/shared/readonly-drain-observation.ts +42 -0
  218. package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +69 -0
  219. package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +307 -0
  220. package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +8 -21
  221. package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +3 -30
  222. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +17 -4
  223. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +2 -0
  224. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +99 -386
  225. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +18 -62
  226. package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +0 -14
  227. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +31 -9
  228. package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +190 -0
  229. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +506 -226
  230. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +1 -1
  231. package/dist/extensions/pi-subagents/src/shared/jsonl-writer.ts +11 -0
  232. package/dist/extensions/pi-subagents/src/shared/model-response-aliases.ts +13 -0
  233. package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +0 -6
  234. package/dist/extensions/pi-subagents/src/shared/types.ts +145 -89
  235. package/dist/extensions/pi-subagents/src/shared/utils.ts +13 -6
  236. package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +2 -0
  237. package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +18 -13
  238. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +0 -6
  239. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +1 -1
  240. package/dist/extensions/pi-subagents/src/tui/fleet.ts +11 -6
  241. package/dist/extensions/pi-subagents/src/tui/render.ts +277 -46
  242. package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +0 -1
  243. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +12 -12
  244. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
  245. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +116 -15
  246. package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +15 -18
  247. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +57 -8
  248. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +19 -19
  249. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +3 -3
  250. package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +97 -22
  251. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +3 -0
  252. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +336 -21
  253. package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +1181 -0
  254. package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +2240 -0
  255. package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +2268 -0
  256. package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +1512 -0
  257. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +231 -16
  258. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +4 -18
  259. package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +95 -0
  260. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +9 -15
  261. package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +374 -0
  262. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -10
  263. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +18 -6
  264. package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +151 -0
  265. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +42 -1
  266. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +150 -25
  267. package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +354 -0
  268. package/dist/extensions/pi-subagents/test/integration/shared-cwd-terminal-evidence.test.ts +117 -0
  269. package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +3678 -0
  270. package/dist/extensions/pi-subagents/test/integration/{single-execution.test.ts → single-execution.part-2.test.ts} +500 -4207
  271. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -2
  272. package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +127 -0
  273. package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +365 -0
  274. package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +31 -0
  275. package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +74 -0
  276. package/dist/extensions/pi-subagents/test/smoke/pi085-extension.ts +16 -0
  277. package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +699 -0
  278. package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +418 -0
  279. package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +13 -0
  280. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +30 -76
  281. package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +84 -0
  282. package/dist/extensions/pi-subagents/test/support/result-publication-capacity-preload.mjs +70 -0
  283. package/dist/extensions/pi-subagents/test/support/runner-child-session-factory.ts +17 -0
  284. package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +390 -0
  285. package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +120 -0
  286. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +24 -3
  287. package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +87 -0
  288. package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +163 -0
  289. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -31
  290. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +78 -3
  291. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +2 -8
  292. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +1 -1
  293. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +73 -66
  294. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +51 -1
  295. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +49 -1
  296. package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +103 -0
  297. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +3 -3
  298. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +9 -8
  299. package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +10 -7
  300. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +48 -6
  301. package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +90 -0
  302. package/dist/extensions/pi-subagents/test/unit/{pi-args-permission-system.test.ts → child-tool-plan-permission-system.test.ts} +48 -86
  303. package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +33 -0
  304. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +18 -18
  305. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +9 -9
  306. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +8 -7
  307. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +225 -65
  308. package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +17 -22
  309. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +11 -1
  310. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +47 -3
  311. package/dist/extensions/pi-subagents/test/unit/foreign-workflow-steering.test.ts +74 -0
  312. package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +23 -29
  313. package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +96 -4
  314. package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +4 -4
  315. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +116 -55
  316. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +58 -1
  317. package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +104 -3
  318. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
  319. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +31 -1
  320. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +102 -51
  321. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +196 -6
  322. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +181 -38
  323. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +62 -70
  324. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +58 -53
  325. package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +42 -0
  326. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +84 -0
  327. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +13 -5
  328. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +21 -5
  329. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +5 -4
  330. package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +2 -6
  331. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +28 -2
  332. package/dist/extensions/pi-subagents/test/unit/pi-web-session-liveness.test.ts +209 -0
  333. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +38 -1
  334. package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +43 -0
  335. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +24 -2
  336. package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +174 -0
  337. package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +94 -0
  338. package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +1329 -0
  339. package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +29 -80
  340. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +11 -8
  341. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +2 -2
  342. package/dist/extensions/pi-subagents/test/unit/retained-nested-route-tracker.test.ts +175 -0
  343. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +38 -12
  344. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +2 -5
  345. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +89 -1
  346. package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +2 -16
  347. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +27 -3
  348. package/dist/extensions/pi-subagents/test/unit/scheduled-supervisor-demand.test.ts +215 -0
  349. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +15 -11
  350. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +237 -1
  351. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -5
  352. package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +2 -2
  353. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +14 -1
  354. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +130 -739
  355. package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +682 -0
  356. package/dist/extensions/pi-subagents/test/unit/supervisor-ui.test.ts +137 -0
  357. package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +1 -11
  358. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +23 -3
  359. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +8 -1
  360. package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +19 -1
  361. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +72 -4
  362. package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +17 -3
  363. package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +34 -0
  364. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +12 -2
  365. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +46 -6
  366. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +3 -3
  367. package/dist/extensions/pi-subagents/test/unit/workflow-resources.test.ts +133 -1
  368. package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +53 -2
  369. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +222 -14
  370. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +526 -85
  371. package/dist/extensions/pi-web-agent/src/backends/config.ts +1 -0
  372. package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +5 -3
  373. package/dist/extensions/pi-web-agent/src/search/tokenin.ts +7 -3
  374. package/dist/extensions/pi-web-agent/src/types.ts +1 -1
  375. package/dist/extensions/pi-zentui/README.md +17 -0
  376. package/dist/extensions/pi-zentui/assets/screenshots/footer-status-hyperlink.png +0 -0
  377. package/dist/extensions/pi-zentui/docs/configuration.md +71 -2
  378. package/dist/extensions/pi-zentui/extensions/zentui/config.ts +11 -0
  379. package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +14 -0
  380. package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +29 -13
  381. package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +5 -4
  382. package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +11 -0
  383. package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +11 -10
  384. package/dist/extensions/pi-zentui/extensions/zentui/index.ts +77 -3
  385. package/dist/extensions/pi-zentui/extensions/zentui/presets.ts +77 -0
  386. package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +103 -2
  387. package/dist/extensions/pi-zentui/extensions/zentui/working-line-extension-segments.ts +115 -0
  388. package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +87 -5
  389. package/dist/extensions/pi-zentui/package-lock.json +277 -517
  390. package/dist/extensions/pi-zentui/package.json +7 -4
  391. package/dist/extensions/pi-zentui/test/config-presets.test.ts +238 -0
  392. package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +24 -1
  393. package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +570 -2
  394. package/dist/extensions/pi-zentui/test/extension-status.test.ts +90 -0
  395. package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +243 -0
  396. package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
  397. package/dist/extensions/pi-zentui/test/presets.test.ts +121 -0
  398. package/dist/extensions/pi-zentui/test/settings-command.test.ts +205 -1
  399. package/dist/extensions/pi-zentui/test/working-line-extension-segments.test.ts +139 -0
  400. package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +237 -3
  401. package/dist/extensions/pi-zentui/test/working-line.test.ts +94 -2
  402. package/dist/index.d.ts +1 -1
  403. package/dist/main.js +4 -1
  404. package/dist/modes/interactive/chat-viewport.d.ts +19 -0
  405. package/dist/modes/interactive/chat-viewport.js +27 -0
  406. package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
  407. package/dist/modes/interactive/components/assistant-message.js +30 -13
  408. package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
  409. package/dist/modes/interactive/components/custom-editor.js +39 -1
  410. package/dist/modes/interactive/components/first-time-setup.js +1 -1
  411. package/dist/modes/interactive/components/index.d.ts +1 -1
  412. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -0
  413. package/dist/modes/interactive/components/markdown-transform.js +18 -0
  414. package/dist/modes/interactive/components/model-selector.js +19 -17
  415. package/dist/modes/interactive/components/scoped-models-selector.js +21 -23
  416. package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
  417. package/dist/modes/interactive/components/settings-selector.js +128 -20
  418. package/dist/modes/interactive/components/settings-submenu.d.ts +71 -0
  419. package/dist/modes/interactive/components/settings-submenu.js +164 -0
  420. package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
  421. package/dist/modes/interactive/components/status-indicator.js +10 -3
  422. package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
  423. package/dist/modes/interactive/components/thinking-selector.js +75 -18
  424. package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
  425. package/dist/modes/interactive/components/tool-execution.js +35 -33
  426. package/dist/modes/interactive/components/trust-selector.js +2 -2
  427. package/dist/modes/interactive/interactive-mode.d.ts +13 -15
  428. package/dist/modes/interactive/interactive-mode.js +144 -80
  429. package/dist/modes/interactive/session-share.d.ts +15 -0
  430. package/dist/modes/interactive/session-share.js +183 -0
  431. package/dist/modes/interactive/theme/dark.json +2 -1
  432. package/dist/modes/interactive/theme/light.json +2 -1
  433. package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
  434. package/dist/modes/interactive/theme/theme-controller.js +5 -0
  435. package/dist/modes/interactive/theme/theme-json.d.ts +83 -0
  436. package/dist/modes/interactive/theme/theme-json.js +129 -0
  437. package/dist/modes/interactive/theme/theme-schema.json +9 -1
  438. package/dist/modes/interactive/theme/theme.d.ts +14 -5
  439. package/dist/modes/interactive/theme/theme.js +18 -119
  440. package/dist/modes/interactive/tui-renderer.d.ts +20 -0
  441. package/dist/modes/interactive/tui-renderer.js +65 -0
  442. package/dist/utils/exif-orientation.js +2 -3
  443. package/dist/utils/management-http.d.ts +24 -0
  444. package/dist/utils/management-http.js +53 -0
  445. package/dist/utils/text.d.ts +7 -0
  446. package/dist/utils/text.js +8 -0
  447. package/dist/utils/tools-manager.d.ts +1 -0
  448. package/dist/utils/tools-manager.js +43 -21
  449. package/docs/docs.json +0 -4
  450. package/package.json +4 -4
  451. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +0 -415
  452. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +0 -1059
  453. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +0 -116
  454. package/dist/extensions/pi-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
  455. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +0 -224
  456. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +0 -6986
  457. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +0 -447
  458. package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +0 -185
  459. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +0 -311
  460. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +0 -84
  461. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +0 -202
  462. package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +0 -101
  463. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +0 -2347
  464. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +0 -104
  465. package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +0 -49
  466. package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
  467. package/dist/skills/imagegen-frontend-web/SKILL.md +0 -987
  468. package/dist/skills/implanger/SKILL.md +0 -70
  469. package/dist/skills/output/SKILL.md +0 -49
  470. package/dist/skills/planger/SKILL.md +0 -167
  471. package/dist/skills/workflow/SKILL.md +0 -95
  472. package/docs/workflows.md +0 -18
  473. /package/dist/bun/{register-bedrock.d.ts → runtime-setup.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-subagents",
3
- "version": "0.64.0",
3
+ "version": "0.66.0",
4
4
  "description": "Selesai extension for single-agent delegation and scripted multi-agent workflows",
5
5
  "author": "Nico Bailon",
6
6
  "license": "MIT",
@@ -13,10 +13,11 @@
13
13
  "./agents": "./src/api/agents.ts",
14
14
  "./delegation": "./src/api/delegation.ts",
15
15
  "./capability-ceiling": "./src/api/capability-ceiling.ts",
16
+ "./workflow-resources": "./src/api/workflow-resources.ts",
16
17
  "./preflight": "./src/api/preflight.ts",
17
18
  "./control-channel": "./src/api/control-channel.ts",
18
19
  "./intercom-bridge": "./src/api/intercom-bridge.ts",
19
- "./pi-args": "./src/api/pi-args.ts",
20
+ "./child-tool-plan": "./src/api/child-tool-plan.ts",
20
21
  "./shared-types": "./src/api/shared-types.ts",
21
22
  "./project-panes": "./src/api/project-panes.ts"
22
23
  },
@@ -56,8 +57,7 @@
56
57
  "test": "npm run test:unit",
57
58
  "test:unit": "node --experimental-strip-types --import ./test/support/isolated-temp-root.mjs --test test/unit/*.test.ts",
58
59
  "test:integration": "node --experimental-strip-types --import ./test/support/register-loader.mjs --test test/integration/*.test.ts",
59
- "test:e2e": "node --experimental-strip-types --import ./test/support/register-loader.mjs --test test/e2e/*.test.ts",
60
- "test:all": "npm run test:unit && npm run test:integration && npm run test:e2e"
60
+ "test:all": "npm run test:unit && npm run test:integration"
61
61
  },
62
62
  "pi": {
63
63
  "extensions": [
@@ -91,9 +91,11 @@
91
91
  }
92
92
  },
93
93
  "dependencies": {
94
+ "@earendil-works/pi-server": "0.85.0",
94
95
  "acorn": "8.18.0",
95
96
  "jiti": "2.7.0",
96
97
  "typebox": "1.1.38",
98
+ "undici": "8.10.0",
97
99
  "yaml": "2.8.3"
98
100
  },
99
101
  "devDependencies": {
@@ -0,0 +1,13 @@
1
+ // Only loaded when the parent supplies Pi 0.85.0's missing server exports.
2
+ import { registerHooks } from "node:module";
3
+ import { pathToFileURL } from "node:url";
4
+
5
+ const aliases = JSON.parse(process.env.JITI_ALIAS);
6
+ registerHooks({
7
+ resolve(specifier, context, nextResolve) {
8
+ if (specifier === "@earendil-works/pi-server" || specifier === "@earendil-works/pi-server/unix") {
9
+ return nextResolve(pathToFileURL(aliases[specifier]).href, context);
10
+ }
11
+ return nextResolve(specifier, context);
12
+ },
13
+ });
@@ -91,7 +91,8 @@ review.
91
91
  - Exact model names are deployment policy. Put them in user/project settings or profiles, not package guidance.
92
92
  - Give every child a compact meta-prompt checklist: objective; repo/cwd/ref; authority/edit boundary; relevant files/contracts and constraints; success/acceptance criteria; validation; expected output/report; and stop/ask conditions. See `references/prompting-and-roles.md`.
93
93
  - For mutation work, use an isolated lane/worktree when isolation, overlap, or concurrent juggling matters; keep one writer per cwd/worktree. See `references/multi-lane-orchestration.md` for lane mechanics.
94
- - Keep long/high-output validation out of chat: prefer `interactive_shell` dispatch/background monitors, bounded logs, or subagent-owned reports; return a concise summary plus report path unless same-turn output is required. See `references/execution-controls.md`.
94
+ - Keep long/high-output validation out of chat: prefer `interactive_shell` dispatch/background monitors, bounded logs, or subagent-owned reports; return a concise summary plus report path unless same-turn output is required. Do not use `interactive_shell` as an implicit fallback for a failed `subagent` lane; see `references/execution-controls.md`.
95
+ - Treat subagent workflow, child launch, prompt runtime, extension load, and child tooling setup failures as lane infrastructure blockers. Stop, report the exact failure and run/worktree state, verify a clean worktree or capture a partial diff, and use only a clear same-protocol retry or an owner-approved execution-mode fallback.
95
96
  - For cross-codebase work, record the repo, explicit `cwd`, authority boundary, and expected output before launch.
96
97
  - Make parallel prompts distinct by source seam, evidence, and decision. Do not clone prompts with only item numbers swapped.
97
98
  - Prefer fresh-context review/validation fanout, then synthesize and apply fixes in the parent.
@@ -21,7 +21,7 @@ This file is a detailed reference loaded from `skills/pi-subagents/SKILL.md`.
21
21
  become second decision-makers.
22
22
  - **Respect the fixed authority policy.** `authorityPolicy` is a small `auto` / `confirm` / `forbid` map for supported operational actions. Worktree discard, destructive cleanup, and spawn-budget grants default to confirmation; stop, steer, and schedule creation remain automatic. Use `worktree.discard` with the durable `handoffPath`; confirm-required actions refuse safely without an interactive UI and retained paths include manual Git recovery commands.
23
23
 
24
- Runtime config can change orchestration behavior. `intercomBridge.resultDelivery: false` disables only external acknowledged grouped-result delivery when native parent notifications own completion; supervisor asks/progress stay active, and enabled transport failures are still reported. `asyncByDefault` and `forceTopLevelAsync` affect whether launches detach; `waitTool` can make direct `bg_wait()` calls return immediately while headless auto-drain remains active, and its effective value is propagated to child runtimes; `globalConcurrencyLimit` bounds concurrent fanout, while a positive `maxSubagentSpawnsPerSession` optionally caps cumulative launches (`0` or unset is unlimited). Status and doctor report the budget; static work preflights declared capacity; only the settled root interactive parent can use `grant-spawn-budget` after native confirmation, with total grants bounded by the original cap. Compaction does not reset usage or grants; `singleRunOutputBaseDir` and `worktreeBaseDir` route outputs and worktrees; `completionBatch` groups async notifications. `artifactDir` is `session` (default), `project`, or `temp` and chooses where subagent artifacts are stored. Set `asyncWidget: false` to hide the above-editor background-run widget when a companion footer or dashboard owns that space (fleet inspector remains available). Per-run `artifacts: false` disables artifact capture for that launch. Async status and result artifacts include `lifecycleArtifactVersion` and fields such as `workflowGraph`, `steps`, `results`, `totalTokens`, `totalCost`, `turnCount`, `toolCount`, and nested `children`. Child protocol failures expose a structured `protocolError`; `protocol_output_limit` means a child emitted a JSONL line above the 16 MiB live-parser cap. Prefer these artifacts and `status` views over scraping terminal output.
24
+ Runtime config can change orchestration behavior. `intercomBridge.resultDelivery: false` disables only external acknowledged grouped-result delivery when native parent notifications own completion; supervisor asks/progress stay active, and enabled transport failures are still reported. `asyncByDefault` and `forceTopLevelAsync` affect whether launches detach; `waitTool` can make direct `bg_wait()` calls return immediately while headless auto-drain remains active, and its effective value is propagated to child runtimes; `globalConcurrencyLimit` bounds concurrent fanout, while a positive `maxSubagentSpawnsPerSession` optionally caps cumulative launches (`0` or unset is unlimited). Status and doctor report the budget; static work preflights declared capacity; only the settled root interactive parent can use `grant-spawn-budget` after native confirmation, with total grants bounded by the original cap. Compaction does not reset usage or grants; `singleRunOutputBaseDir` and `worktreeBaseDir` route outputs and worktrees; `completionBatch` groups async notifications. `artifactDir` is `session` (default), `project`, or `temp` and chooses where subagent artifacts are stored. Set `asyncWidget: false` to hide the above-editor background-run widget when a companion footer or dashboard owns that space (fleet inspector remains available). Per-run `artifacts: false` disables artifact capture for that launch. Async status and result artifacts include `lifecycleArtifactVersion` and fields such as `workflowGraph`, `steps`, `results`, `totalTokens`, `totalCost`, `turnCount`, `toolCount`, and nested `children`. Prefer these artifacts and `status` views over scraping terminal output.
25
25
 
26
26
  ### Keep report artifacts out of the repository root
27
27
 
@@ -236,8 +236,8 @@ Resume behavior:
236
236
  - Multi-child async runs require `index` unless only one running child is selectable.
237
237
  - Completed foreground single, parallel, and chain runs can also be revived by `index` while their run metadata remains in extension state.
238
238
  - Nested runs can be resumed by nested id when a live route or persisted nested session metadata is available.
239
- - Revive starts a new child process from the old session context; it does not restart the same OS process.
240
- - Direct revival holds an exclusive cross-process lease on the canonical child session file until the new child finishes. Concurrent attempts fail before Pi starts and identify the owning revived run; stale ownership is reclaimed only when the recorded process is demonstrably gone or reused.
239
+ - Revive starts a new child session from the old session context; it does not resume the original child session.
240
+ - Direct revival holds an exclusive cross-process lease on the canonical child session file until the new child finishes. Concurrent attempts fail before the child session starts and identify the owning revived run; stale ownership is reclaimed only when the recorded process is demonstrably gone or reused.
241
241
  - If the chosen child has no persisted `.jsonl` session file, resume fails and reports that directly.
242
242
 
243
243
  Use diagnostics when setup or child startup looks wrong:
@@ -246,15 +246,19 @@ Use diagnostics when setup or child startup looks wrong:
246
246
  subagent({ action: "doctor" })
247
247
  ```
248
248
 
249
+ ### Failed lane recovery and execution-mode fallback
250
+
251
+ A failure in the subagent workflow, child launch, prompt runtime, extension loading, or child tooling setup is a lane infrastructure blocker, not permission to silently change execution mode. Stop and report the exact failure, run/status, and repo/cwd/worktree/branch/ref state. Retry or fix the `subagent` path only through a clear same-protocol retry; before retrying or asking the owner, verify the worktree is clean or capture the partial diff. For backlog lanes and other subagent-governed workflows, switching to `interactive_shell`, `pi -ne`, Codex/Claude/Cursor CLI, a foreground agent, or another external mode requires explicit owner approval. Pi core may print a generic `pi -ne` extension-load hint; that hint is outside this package and is not protocol-approved fallback. This execution-mode boundary does not prohibit configured native model/provider fallback.
252
+
249
253
  ### External terminal work
250
254
 
251
- Use native `subagent` runs for unattended implementation, review, and gate work that needs managed isolation, durable artifacts, and process controls. Use `interactive_shell` for visible terminal work, alternate CLIs, trust prompts, and recovery.
255
+ Use native `subagent` runs for unattended implementation, review, and gate work that needs managed isolation, durable artifacts, and process controls. Use `interactive_shell` for visible terminal work, alternate CLIs, trust prompts, or recovery only when the user explicitly requests that mode or the task is outside the governed subagent protocol; it is not an implicit replacement for a failed `subagent` lane.
252
256
 
253
257
  A cooperating terminal runtime can register read-only external records through `pi-subagents/external-runs`. Records include the source, session, state, optional report path, and completion reason. They are observations only: pi-subagents does not start, stop, steer, or otherwise own the foreign process. Run unattended raw terminal agents in an explicit isolated cwd or worktree; do not use a live project checkout as disposable review space.
254
258
 
255
259
  ### Scheduled subagent runs
256
260
 
257
- Schedules are durable project records under `.pi-subagents/schedules/`. They are enabled by default; set `{ "scheduledRuns": { "enabled": false } }` in `~/.selesai/agent/extensions/subagent/config.json` to disable them. Only schedule explicit work the user asked for.
261
+ Schedules are durable project records under `.pi-subagents/schedules/`. They are enabled by default; set `{ "scheduledRuns": { "enabled": false } }` in `~/.selesai/agent/extensions/subagent/config.json` to disable them. Only schedule explicit work the user asked for. To keep schedules outside the project repository, set `{ "scheduledRuns": { "storeRoot": "~/.selesai/subagent-schedules" } }` in the same config: `storeRoot` accepts an absolute path or a `~/`-prefixed path, and records land under `<storeRoot>/<sha256(path.resolve(cwd)) first 20 hex>/<scheduleId>/`.
258
262
 
259
263
  ```typescript
260
264
  // One-shot reviewer
@@ -323,6 +327,19 @@ subagent({ action: "steer", id: "abc123", message: "Focus on the failing test."
323
327
 
324
328
  The action waits up to three seconds for the child Pi session to accept the correlated user input and returns a request id with `delivered`, `scheduled`, `pending`, `partial`, `recovered`, or `failed` plus per-child states. Indexed pending children return `scheduled` immediately. Only a top-level single-child run may automatically interrupt after a missed acknowledgment and recover after confirmed pause within a further 15 seconds. Recovery preserves the original child contract and only its remaining deadline, turn, and tool budgets. If the session is missing, a budget is exhausted, the pause cannot be confirmed, or replacement launch fails, the source remains paused when pausing succeeded and the action returns the exact failure. Chain, parallel, and nested runs never auto-interrupt; inspect their per-child outcomes and handle failures explicitly. A late acknowledgment is recorded and cannot cancel committed recovery.
325
329
 
330
+ Steering supports three delivery modes via the `mode` parameter (`steer` is the default):
331
+
332
+ - `mode: "steer"` — interrupt the child at the next safe point of its current turn and deliver the message.
333
+ - `mode: "follow_up"` — do not interrupt; queue input through Pi's native follow-up path for the next turn boundary. Eligible completed retained workflow children (single-step runs in state `complete` with a stored session file) receive the message as a revival brief (`queueRevivalBrief`) when they are revived; paused children reject follow-up steering outright. The 20-message queue limit applies to retained revival briefs, not live follow-up input.
334
+ - `mode: "auto"` — same next-safe-point delivery path as `steer`, but without the automatic pause-and-revive recovery after a missed acknowledgment.
335
+
336
+ ```typescript
337
+ subagent({ action: "steer", id: "abc123", mode: "follow_up", message: "After this step, also validate the config file." })
338
+ subagent({ action: "steer", id: "abc123", mode: "auto", message: "Switch to the failing test now." })
339
+ ```
340
+
341
+ Direct input acceptance returns `delivered`, not proof of model compliance. A live follow-up acknowledgment reports `queued`, meaning Pi accepted it into its follow-up queue, not that it was delivered. The runtime does not provide a later correlated live queued-to-delivered receipt.
342
+
326
343
  ## Watchdog
327
344
 
328
345
  The subagent watchdog is an **opt-in** adversarial change reviewer. It is not the
@@ -96,6 +96,7 @@ A minimal agent file looks like this:
96
96
  name: my-agent
97
97
  package: code-analysis
98
98
  description: What this agent does
99
+ advertise: true
99
100
  aliases: developer, coder
100
101
  model: provider/model-id
101
102
  thinking: high
@@ -111,7 +112,7 @@ skillPath: ./skills, ../shared-skills
111
112
  Your system prompt here.
112
113
  ```
113
114
 
114
- That is only a starting point. Omit `package` for the traditional unqualified runtime name. Common optional fields include:
115
+ That is only a starting point. Omit `package` for the traditional unqualified runtime name. Set `advertise: true` only when the parent should receive this agent's name and description before deciding whether to delegate; advertisement is off by default. Common optional fields include:
115
116
  - `defaultProgress`
116
117
  - `defaultReads`
117
118
  - `output`
@@ -46,6 +46,8 @@ After a writer produces a candidate, run the required fresh-context, read-only r
46
46
 
47
47
  Use stable lane-qualified artifact paths for reports and review output. A handoff states the lane status, repository and worktree, changed files, validation, open decisions, next action, and artifact or receipt paths. Copy only the final evidence to memory, a mission record, or a PR/comment, then remove scratch files from the active worktree before closing the lane.
48
48
 
49
+ For backlog lanes and other subagent-governed workflows, a setup/runtime/tooling failure remains an infrastructure blocker. Preserve the exact failure, run/status, and repository/cwd/worktree/branch/ref state; verify a clean worktree or capture any partial diff before a same-protocol retry or asking the owner. Do not start another writer or switch to an external, foreground, or CLI execution mode without explicit owner approval.
50
+
49
51
  Keep a worktree until its handoff is durable, no run owns it, and no later gate needs it. Clean up only inside the recorded authority boundary. If a run stops or needs attention, preserve its worktree and artifacts, record the last known state and recovery owner, then resume that run or create one replacement lane from the handoff. Do not start another writer while worktree ownership is uncertain.
50
52
 
51
53
  Before completion, inspect the board. Every lane must be terminal or blocked with a named next action. Confirm one writer per repo/cwd or worktree, required validation, required fresh read-only review, and a durable handoff. The parent reports outcomes, evidence, residual risks, and the next decision.
@@ -0,0 +1,63 @@
1
+ import { Buffer } from "node:buffer";
2
+ import type { ResolvedSubagentCapabilityCeiling } from "../runs/shared/capability-ceiling.ts";
3
+ import { isAgentAllowedByCapabilityCeiling } from "../runs/shared/capability-ceiling.ts";
4
+ import type { AgentConfig } from "./agents.ts";
5
+
6
+ const MAX_ADVERTISED_AGENTS = 16;
7
+ const MAX_CATALOG_BYTES = 12_288;
8
+ const MAX_DESCRIPTION_BYTES = 512;
9
+ const ADVERTISED_AGENTS_BLOCK = /\n*<advertised_subagents>\n[\s\S]*?\n<\/advertised_subagents>/gu;
10
+
11
+ function escapeXml(value: string): string {
12
+ return value
13
+ .replaceAll("&", "&amp;")
14
+ .replaceAll("<", "&lt;")
15
+ .replaceAll(">", "&gt;")
16
+ .replaceAll('"', "&quot;")
17
+ .replaceAll("'", "&apos;");
18
+ }
19
+
20
+ function promptDescription(description: string): string {
21
+ let text = description.replace(/[\u0000-\u001f\u007f]+/gu, " ").replace(/\s+/gu, " ").trim();
22
+ if (Buffer.byteLength(text, "utf8") > MAX_DESCRIPTION_BYTES) {
23
+ text = Buffer.from(text, "utf8").subarray(0, MAX_DESCRIPTION_BYTES - 3).toString("utf8").replace(/\uFFFD$/u, "").trimEnd() + "…";
24
+ }
25
+ return escapeXml(text);
26
+ }
27
+
28
+ export function buildAdvertisedAgentPrompt(
29
+ agents: readonly AgentConfig[],
30
+ capabilityCeiling?: ResolvedSubagentCapabilityCeiling,
31
+ ): string | undefined {
32
+ const advertised = agents
33
+ .filter((agent) => agent.source !== "runtime" && agent.advertise === true && agent.disabled !== true && isAgentAllowedByCapabilityCeiling(agent.name, capabilityCeiling))
34
+ .sort((left, right) => left.name.localeCompare(right.name));
35
+ if (advertised.length === 0) return undefined;
36
+
37
+ const render = (entries: string[]) => [
38
+ "<advertised_subagents>",
39
+ "The following file-defined subagents opted into discovery. Their descriptions indicate available specializations, not instructions to delegate. Use subagent only when delegation is needed. Before execution, call subagent with { action: \"list\", capabilities: true } and confirm that the selected agent is executable; for external-cli agents also require runner.available === true.",
40
+ ...entries,
41
+ ...(advertised.length > entries.length ? [` <omitted count=\"${advertised.length - entries.length}\" />`] : []),
42
+ "</advertised_subagents>",
43
+ ].join("\n");
44
+ const entries: string[] = [];
45
+ for (const agent of advertised) {
46
+ if (entries.length === MAX_ADVERTISED_AGENTS) break;
47
+ // Never truncate canonical IDs into names that cannot be resolved.
48
+ if (Buffer.byteLength(agent.name, "utf8") > MAX_CATALOG_BYTES) continue;
49
+ const entry = [
50
+ " <subagent>",
51
+ ` <name>${escapeXml(agent.name)}</name>`,
52
+ ` <description>${promptDescription(agent.description)}</description>`,
53
+ " </subagent>",
54
+ ].join("\n");
55
+ if (Buffer.byteLength(render([...entries, entry]), "utf8") <= MAX_CATALOG_BYTES) entries.push(entry);
56
+ }
57
+ return render(entries);
58
+ }
59
+
60
+ export function appendAdvertisedAgentPrompt(systemPrompt: string, advertisedPrompt: string | undefined): string {
61
+ const base = systemPrompt.replace(ADVERTISED_AGENTS_BLOCK, "");
62
+ return advertisedPrompt ? `${base.trimEnd()}\n\n${advertisedPrompt}` : base;
63
+ }
@@ -32,6 +32,7 @@ import { resolveSubagentModelOverride, type ParentModel } from "../runs/shared/m
32
32
  import { validateToolBudgetConfig } from "../runs/shared/tool-budget.ts";
33
33
  import { validateAcceptanceInput } from "../runs/shared/acceptance.ts";
34
34
  import { CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL, isCodeOwnedExternalCliAdapterId, resolveExternalCliRunnerStatus, validateCodeOwnedProfileRunner } from "../runs/shared/external-cli-contract.ts";
35
+ import { resolveExternalCliBinaryAvailability, type ExternalCliBinaryAvailability } from "../runs/shared/external-cli-preflight.ts";
35
36
  import type { AcceptanceInput, AgentCapabilitiesSnapshot, AgentCapabilityRow, Details, ExtensionConfig, ToolBudgetConfig } from "../shared/types.ts";
36
37
  import { getProjectConfigDir } from "../shared/utils.ts";
37
38
  import { previewDisplayText } from "../shared/display-text.ts";
@@ -41,7 +42,7 @@ import { listExternalJobProviders } from "../api/external-job-provider.ts";
41
42
 
42
43
  type ManagementAction = "list" | "get" | "models" | "create" | "update" | "delete" | "eject" | "disable" | "enable" | "reset";
43
44
  type ManagementScope = "user" | "project";
44
- type ManagementContext = Pick<ExtensionContext, "cwd" | "modelRegistry"> & { model?: ExtensionContext["model"]; config?: ExtensionConfig; currentSessionId?: string; runtimeAgentOwner?: RuntimeAgentOwner };
45
+ type ManagementContext = Pick<ExtensionContext, "cwd" | "modelRegistry"> & { model?: ExtensionContext["model"]; config?: ExtensionConfig; currentSessionId?: string; runtimeAgentOwner?: RuntimeAgentOwner; onAgentsChanged?: () => void };
45
46
 
46
47
  interface ManagementParams {
47
48
  action?: string;
@@ -347,6 +348,7 @@ export function preservedAgentFrontmatterFields(agent: AgentConfig, cfg: Record<
347
348
  if (hasKey(cfg, "name")) changed("name");
348
349
  if (hasKey(cfg, "package")) changed("package");
349
350
  if (hasKey(cfg, "description")) changed("description");
351
+ if (hasKey(cfg, "advertise")) changed("advertise");
350
352
  if (hasKey(cfg, "aliases")) changed("alias", "aliases");
351
353
  if (hasKey(cfg, "systemPrompt")) changed("systemPrompt");
352
354
  if (hasKey(cfg, "runner")) changed("runner");
@@ -414,6 +416,11 @@ function parseTools(raw: string): { tools?: string[]; mcpDirectTools?: string[]
414
416
  }
415
417
 
416
418
  function applyAgentConfig(target: AgentConfig, cfg: Record<string, unknown>): string | undefined {
419
+ if (hasKey(cfg, "advertise")) {
420
+ if (cfg.advertise === "") delete target.advertise;
421
+ else if (typeof cfg.advertise === "boolean") target.advertise = cfg.advertise;
422
+ else return "config.advertise must be a boolean or empty string when provided.";
423
+ }
417
424
  if (hasKey(cfg, "aliases")) {
418
425
  if (cfg.aliases === false || cfg.aliases === "") delete target.aliases;
419
426
  else if (typeof cfg.aliases === "string") {
@@ -704,17 +711,34 @@ function externalJobProviderSuffix(provider: string, names: Set<string> | undefi
704
711
  return names.has(provider) ? "✓" : "missing";
705
712
  }
706
713
 
707
- function runnerListBadge(agent: AgentConfig, providerNames: Set<string> | undefined): string | undefined {
714
+ type ExternalCliAvailabilityByCommand = ReadonlyMap<string, ExternalCliBinaryAvailability>;
715
+
716
+ function externalCliAvailabilityForAgents(agents: readonly AgentConfig[]): ExternalCliAvailabilityByCommand {
717
+ const availability = new Map<string, ExternalCliBinaryAvailability>();
718
+ for (const agent of agents) {
719
+ const runner = agent.runner;
720
+ if (runner?.type === "external-cli" && !availability.has(runner.command)) {
721
+ availability.set(runner.command, resolveExternalCliBinaryAvailability(runner.command, process.env));
722
+ }
723
+ }
724
+ return availability;
725
+ }
726
+
727
+ function runnerListBadge(agent: AgentConfig, providerNames: Set<string> | undefined, externalCliAvailability?: ExternalCliAvailabilityByCommand): string | undefined {
708
728
  if (agent.runner?.type === "external-job") return `external-job:${agent.runner.provider} ${externalJobProviderSuffix(agent.runner.provider, providerNames)}`;
709
- if (agent.runner?.type === "external-cli") return "external-cli";
729
+ if (agent.runner?.type === "external-cli") {
730
+ const availability = externalCliAvailability?.get(agent.runner.command);
731
+ if (!availability) return "external-cli";
732
+ return `external-cli:${agent.runner.command} ${availability.available ? "✓" : "missing"}`;
733
+ }
710
734
  return undefined;
711
735
  }
712
736
 
713
- function agentListMetadata(agent: AgentConfig, providerNames: Set<string> | undefined): string {
737
+ function agentListMetadata(agent: AgentConfig, providerNames: Set<string> | undefined, externalCliAvailability?: ExternalCliAvailabilityByCommand): string {
714
738
  const source = agent.source === "package" ? packageSourceLabel(agent) : agent.source;
715
739
  return [
716
740
  source,
717
- runnerListBadge(agent, providerNames),
741
+ runnerListBadge(agent, providerNames, externalCliAvailability),
718
742
  agent.defaultContext ? `context: ${agent.defaultContext}` : undefined,
719
743
  agent.aliases?.length ? `aliases: ${agent.aliases.join(", ")}` : undefined,
720
744
  ].filter((part): part is string => Boolean(part)).join(", ");
@@ -724,7 +748,7 @@ function formatAgentListLine(agent: AgentConfig, providerNames: Set<string> | un
724
748
  return `- ${agent.name} (${agentListMetadata(agent, providerNames)}): ${agent.description}`;
725
749
  }
726
750
 
727
- function formatAgentCapabilitiesLine(agent: AgentConfig, providerNames: Set<string> | undefined): string {
751
+ function formatAgentCapabilitiesLine(agent: AgentConfig, providerNames: Set<string> | undefined, externalCliAvailability?: ExternalCliAvailabilityByCommand): string {
728
752
  const declaredTools = [
729
753
  ...(agent.tools ?? []),
730
754
  ...(agent.mcpDirectTools ?? []).map((tool) => `mcp:${tool}`),
@@ -742,7 +766,7 @@ function formatAgentCapabilitiesLine(agent: AgentConfig, providerNames: Set<stri
742
766
  if (agent.modelProvider && !agent.model.includes("/")) model = `${agent.modelProvider}/${agent.model}`;
743
767
  }
744
768
  const thinking = agent.thinking === false ? "off" : agent.thinking ?? "default";
745
- return `- ${agent.name} (${agentListMetadata(agent, providerNames)}): Description: ${previewDisplayText(agent.description, 240)}; Tools: ${tools}; Model: ${model}; Thinking: ${thinking}`;
769
+ return `- ${agent.name} (${agentListMetadata(agent, providerNames, externalCliAvailability)}): Description: ${previewDisplayText(agent.description, 240)}; Tools: ${tools}; Model: ${model}; Thinking: ${thinking}`;
746
770
  }
747
771
 
748
772
  const EXTERNAL_JOB_CAPABILITIES = { stop: false, steer: false, resume: false, structuredOutput: false, toolEvents: false } as const;
@@ -752,10 +776,19 @@ function listOrEmpty<T>(values: T[] | undefined): T[] {
752
776
  return values ?? [];
753
777
  }
754
778
 
755
- function agentCapabilityRunner(agent: AgentConfig, providerNames: Set<string> | undefined): AgentCapabilityRow["runner"] {
779
+ function agentCapabilityRunner(agent: AgentConfig, providerNames: Set<string> | undefined, externalCliAvailability: ExternalCliAvailabilityByCommand): AgentCapabilityRow["runner"] {
756
780
  const runner = agent.runner;
757
781
  if (!runner || runner.type === "pi") return PI_AGENT_RUNNER;
758
- if (runner.type === "external-cli") return { type: "external-cli", adapter: runner.adapter, capabilities: resolveExternalCliRunnerStatus(runner).capabilities };
782
+ if (runner.type === "external-cli") {
783
+ const availability = externalCliAvailability.get(runner.command)!;
784
+ return {
785
+ type: "external-cli",
786
+ adapter: runner.adapter,
787
+ command: runner.command,
788
+ ...availability,
789
+ capabilities: resolveExternalCliRunnerStatus(runner).capabilities,
790
+ };
791
+ }
759
792
  return { type: "external-job", provider: runner.provider, available: providerNames?.has(runner.provider), capabilities: EXTERNAL_JOB_CAPABILITIES };
760
793
  }
761
794
 
@@ -769,7 +802,7 @@ function agentCapabilityTools(agent: AgentConfig): AgentCapabilityRow["tools"] {
769
802
  };
770
803
  }
771
804
 
772
- function agentCapabilityRow(agent: AgentConfig, options: { executable: boolean; providerNames?: Set<string>; restrictionSources?: string[] }): AgentCapabilityRow {
805
+ function agentCapabilityRow(agent: AgentConfig, options: { executable: boolean; providerNames?: Set<string>; externalCliAvailability: ExternalCliAvailabilityByCommand; restrictionSources?: string[] }): AgentCapabilityRow {
773
806
  return {
774
807
  name: agent.name,
775
808
  description: previewDisplayText(agent.description, 1000),
@@ -777,7 +810,7 @@ function agentCapabilityRow(agent: AgentConfig, options: { executable: boolean;
777
810
  executable: options.executable,
778
811
  restrictionSources: options.executable ? undefined : options.restrictionSources ?? [],
779
812
  aliases: agent.aliases ? [...agent.aliases] : undefined,
780
- runner: agentCapabilityRunner(agent, options.providerNames),
813
+ runner: agentCapabilityRunner(agent, options.providerNames, options.externalCliAvailability),
781
814
  tools: agentCapabilityTools(agent),
782
815
  model: presentDetails({ value: agent.model, fallbackModels: agent.fallbackModels, thinking: agent.thinking }),
783
816
  execution: presentDetails({ defaultAsync: agent.defaultAsync, timeoutMs: agent.defaultTimeoutMs }),
@@ -786,11 +819,11 @@ function agentCapabilityRow(agent: AgentConfig, options: { executable: boolean;
786
819
  };
787
820
  }
788
821
 
789
- function agentCapabilitiesSnapshot(input: { agents: AgentConfig[]; restrictedAgents: AgentConfig[]; providerNames?: Set<string>; restrictedSources?: string[] }): AgentCapabilitiesSnapshot {
822
+ function agentCapabilitiesSnapshot(input: { agents: AgentConfig[]; restrictedAgents: AgentConfig[]; providerNames?: Set<string>; externalCliAvailability: ExternalCliAvailabilityByCommand; restrictedSources?: string[] }): AgentCapabilitiesSnapshot {
790
823
  return {
791
824
  agents: [
792
- ...input.agents.map((agent) => agentCapabilityRow(agent, { executable: true, providerNames: input.providerNames })),
793
- ...input.restrictedAgents.map((agent) => agentCapabilityRow(agent, { executable: false, providerNames: input.providerNames, restrictionSources: input.restrictedSources })),
825
+ ...input.agents.map((agent) => agentCapabilityRow(agent, { executable: true, providerNames: input.providerNames, externalCliAvailability: input.externalCliAvailability })),
826
+ ...input.restrictedAgents.map((agent) => agentCapabilityRow(agent, { executable: false, providerNames: input.providerNames, externalCliAvailability: input.externalCliAvailability, restrictionSources: input.restrictedSources })),
794
827
  ],
795
828
  restrictedCount: input.restrictedAgents.length,
796
829
  ...(input.restrictedSources?.length ? { capabilityCeilingSources: [...input.restrictedSources] } : {}),
@@ -824,13 +857,14 @@ function appendAgentDiagnosticLines(lines: string[], diagnostics: AgentDiscovery
824
857
  );
825
858
  }
826
859
 
827
- function agentCapabilityDetails(input: { capabilityMode: boolean; agents: AgentConfig[]; restrictedAgents: AgentConfig[]; providerNames?: Set<string>; restrictedSources?: string[] }): Partial<Details> | undefined {
860
+ function agentCapabilityDetails(input: { capabilityMode: boolean; agents: AgentConfig[]; restrictedAgents: AgentConfig[]; providerNames?: Set<string>; externalCliAvailability: ExternalCliAvailabilityByCommand; restrictedSources?: string[] }): Partial<Details> | undefined {
828
861
  if (!input.capabilityMode) return undefined;
829
862
  return {
830
863
  agentCapabilities: jsonDetails(agentCapabilitiesSnapshot({
831
864
  agents: input.agents,
832
865
  restrictedAgents: input.restrictedAgents,
833
866
  providerNames: input.providerNames,
867
+ externalCliAvailability: input.externalCliAvailability,
834
868
  restrictedSources: input.restrictedSources,
835
869
  })),
836
870
  };
@@ -936,7 +970,10 @@ export function handleList(params: ManagementParams, ctx: ManagementContext): Ag
936
970
  const providerStatus = registeredExternalJobProviderStatus();
937
971
  const providerNameSet = providerNames(providerStatus);
938
972
  const capabilityMode = params.capabilities === true;
939
- const formatLine = capabilityMode ? formatAgentCapabilitiesLine : formatAgentListLine;
973
+ const externalCliAvailability = capabilityMode ? externalCliAvailabilityForAgents([...agents, ...restrictedAgents]) : undefined;
974
+ const formatLine = capabilityMode
975
+ ? (agent: AgentConfig, names: Set<string> | undefined) => formatAgentCapabilitiesLine(agent, names, externalCliAvailability)
976
+ : formatAgentListLine;
940
977
  const lines = [
941
978
  capabilityMode ? "Executable agents (capabilities):" : "Executable agents:",
942
979
  ...formatAgentListSections(agents, providerNameSet, formatLine),
@@ -950,6 +987,7 @@ export function handleList(params: ManagementParams, ctx: ManagementContext): Ag
950
987
  agents,
951
988
  restrictedAgents,
952
989
  providerNames: providerNameSet,
990
+ externalCliAvailability: externalCliAvailability ?? new Map(),
953
991
  restrictedSources,
954
992
  }));
955
993
  }
@@ -1144,6 +1182,7 @@ export function handleCreate(params: ManagementParams, ctx: ManagementContext):
1144
1182
  const sw = skillsWarning(ctx.cwd, agent);
1145
1183
  if (sw) warnings.push(sw);
1146
1184
  fs.writeFileSync(targetPath, serializeAgent(agent), "utf-8");
1185
+ ctx.onAgentsChanged?.();
1147
1186
  return result([`Created agent '${runtimeName}' at ${targetPath}.`, ...warnings].join("\n"));
1148
1187
  }
1149
1188
 
@@ -1209,6 +1248,7 @@ export function handleUpdate(params: ManagementParams, ctx: ManagementContext):
1209
1248
  updated.filePath = renamed.filePath!;
1210
1249
  }
1211
1250
  fs.writeFileSync(updated.filePath, serializeAgent(updated, { preserveFrontmatterFields }), "utf-8");
1251
+ ctx.onAgentsChanged?.();
1212
1252
  const headline = updated.name === oldName
1213
1253
  ? `Updated agent '${updated.name}' at ${updated.filePath}.`
1214
1254
  : `Updated agent '${oldName}' to '${updated.name}' at ${updated.filePath}.`;
@@ -1222,6 +1262,7 @@ function handleDelete(params: ManagementParams, ctx: ManagementContext): AgentTo
1222
1262
  if ("content" in targetOrError) return targetOrError;
1223
1263
  const target = targetOrError;
1224
1264
  fs.unlinkSync(target.filePath);
1265
+ ctx.onAgentsChanged?.();
1225
1266
  return result(`Deleted agent '${target.name}' at ${target.filePath}.`);
1226
1267
  }
1227
1268
 
@@ -1260,6 +1301,7 @@ function handleEject(params: ManagementParams, ctx: ManagementContext): AgentToo
1260
1301
  return result(`Failed to read source agent at ${source.filePath}: ${message}`, true);
1261
1302
  }
1262
1303
  fs.writeFileSync(targetPath, content, "utf-8");
1304
+ ctx.onAgentsChanged?.();
1263
1305
  return result(`Ejected agent '${runtimeName}' from ${source.source} to ${scope} scope at ${targetPath}. Edit it there to customize; it shadows the bundled ${source.source} agent of the same name.`);
1264
1306
  }
1265
1307
 
@@ -1282,6 +1324,7 @@ function handleDisable(params: ManagementParams, ctx: ManagementContext): AgentT
1282
1324
  const settingsPath = mergeBuiltinAgentOverride(ctx.cwd, runtimeName, scope, { disabled: true });
1283
1325
  const after = resolveEffectiveAgent(discoverAgentsAll(ctx.cwd), raw).agent;
1284
1326
  if (after?.disabled === true) {
1327
+ ctx.onAgentsChanged?.();
1285
1328
  return result(`Disabled agent '${runtimeName}' via ${scope} settings override at ${settingsPath}. It is now hidden from runtime discovery and { action: "list" }.`);
1286
1329
  }
1287
1330
  return result(`Wrote a disabled override for '${runtimeName}' at ${settingsPath}, but the agent is still enabled. A higher-precedence ${after?.override?.scope ?? "project"} override is likely winning. Try agentScope: '${after?.override?.scope ?? "project"}'.`, true);
@@ -1306,6 +1349,7 @@ function handleEnable(params: ManagementParams, ctx: ManagementContext): AgentTo
1306
1349
  const { path: settingsPath, removed } = removeBuiltinAgentOverrideFields(ctx.cwd, runtimeName, scope, ["disabled"]);
1307
1350
  const after = resolveEffectiveAgent(discoverAgentsAll(ctx.cwd), raw).agent;
1308
1351
  if (after && after.disabled !== true) {
1352
+ if (removed) ctx.onAgentsChanged?.();
1309
1353
  if (removed) return result(`Enabled agent '${runtimeName}' (removed disabled override at ${settingsPath}).`);
1310
1354
  return result(`Agent '${runtimeName}' is already enabled.`);
1311
1355
  }
@@ -1353,6 +1397,7 @@ function handleReset(params: ManagementParams, ctx: ManagementContext): AgentToo
1353
1397
  return result(`Agent '${runtimeName}' has no ${scope} customization to reset.${note} It is at its bundled ${bundled.source} default.`);
1354
1398
  }
1355
1399
  lines.push(`Reset agent '${runtimeName}' to its bundled ${bundled.source} default.`);
1400
+ ctx.onAgentsChanged?.();
1356
1401
  return result(lines.join("\n"));
1357
1402
  }
1358
1403
 
@@ -6,6 +6,7 @@ export const KNOWN_FIELDS = new Set([
6
6
  "name",
7
7
  "package",
8
8
  "description",
9
+ "advertise",
9
10
  "alias",
10
11
  "aliases",
11
12
  "tools",
@@ -62,6 +63,7 @@ export function serializeAgent(config: AgentConfig, options: SerializeAgentOptio
62
63
  lines.push(`name: ${frontmatterNameForConfig(config)}`);
63
64
  if (config.packageName) lines.push(`package: ${config.packageName}`);
64
65
  lines.push(`description: ${config.description}`);
66
+ if (config.advertise === true || preserve("advertise")) lines.push(`advertise: ${config.advertise === true ? "true" : "false"}`);
65
67
  const aliasesValue = joinComma(config.aliases);
66
68
  if (aliasesValue || preserve("alias", "aliases")) lines.push(`aliases: ${aliasesValue ?? ""}`);
67
69
 
@@ -135,6 +135,7 @@ export interface AgentConfig {
135
135
  packageSourceVersion?: string;
136
136
  packageSourceRoot?: string;
137
137
  description: string;
138
+ advertise?: boolean;
138
139
  aliases?: string[];
139
140
  tools?: string[];
140
141
  excludeTools?: string[];
@@ -1981,6 +1982,12 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
1981
1982
 
1982
1983
  const runner = parseAgentRunnerFrontmatter(frontmatter.runner, localName);
1983
1984
  validateExternalRunnerProfile(frontmatter, localName, runner);
1985
+ let advertise: boolean | undefined;
1986
+ if (frontmatter.advertise !== undefined) {
1987
+ if (frontmatter.advertise === "true") advertise = true;
1988
+ else if (frontmatter.advertise === "false") advertise = false;
1989
+ else throw new Error(`Agent '${localName}' has invalid advertise frontmatter; expected true or false.`);
1990
+ }
1984
1991
  const rawTools = parseFrontmatterList(frontmatter.tools);
1985
1992
  const parsedTools = splitToolList(rawTools);
1986
1993
  const tools = parsedTools.tools ?? [];
@@ -2105,6 +2112,7 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
2105
2112
  ...(packageSource?.packageVersion ? { packageSourceVersion: packageSource.packageVersion } : {}),
2106
2113
  ...(packageSource?.packageRoot ? { packageSourceRoot: packageSource.packageRoot } : {}),
2107
2114
  description: frontmatter.description,
2115
+ ...(advertise !== undefined ? { advertise } : {}),
2108
2116
  ...(aliases !== undefined ? { aliases } : {}),
2109
2117
  ...(rawTools !== undefined ? { tools } : {}),
2110
2118
  ...(excludeTools !== undefined ? { excludeTools } : {}),
@@ -1,5 +1,4 @@
1
1
  export {
2
- SUBAGENT_CAPABILITY_CEILING_ENV,
3
2
  SUBAGENT_CAPABILITY_CEILING_REGISTRY_KEY,
4
3
  SUBAGENT_CAPABILITY_CEILING_VERSION,
5
4
  decodeSubagentCapabilityCeiling,
@@ -2,4 +2,4 @@ export {
2
2
  resolvePiLaunchToolPlan,
3
3
  type PiLaunchToolPlan,
4
4
  type ResolvePiLaunchToolPlanInput,
5
- } from "../runs/shared/pi-args.ts";
5
+ } from "../runs/shared/child-tool-plan.ts";
@@ -7,11 +7,11 @@ import { buildSkillInjection, normalizeSkillInput, resolveSkillsWithFallback } f
7
7
  import { buildAgentMemoryInjection } from "../agents/agent-memory.ts";
8
8
  import { buildModelCandidates, inheritsParentModel, resolveEffectiveSubagentModel, resolveModelOrigin, type AvailableModelInfo, type ParentModel } from "../runs/shared/model-fallback.ts";
9
9
  import { resolveModelScopesForAgent } from "../runs/shared/model-scope.ts";
10
- import { applyThinkingSuffix, resolvePiLaunchToolPlan, type PiLaunchToolPlan } from "../runs/shared/pi-args.ts";
10
+ import { applyThinkingSuffix, resolvePiLaunchToolPlan, type PiLaunchToolPlan } from "../runs/shared/child-tool-plan.ts";
11
11
  import { injectOutputPathSystemPrompt, normalizeSingleOutputOverride, resolveSingleOutputPath } from "../runs/shared/single-output.ts";
12
12
  import { getArtifactPaths, getArtifactsDir } from "../shared/artifacts.ts";
13
13
  import { resolveEffectiveThinking } from "../shared/model-info.ts";
14
- import { assertThinkingWithinCeiling, decodeThinkingCeiling, intersectThinkingCeilings, SUBAGENT_THINKING_CEILING_ENV, type ThinkingLevel } from "../shared/thinking-ceiling.ts";
14
+ import { assertThinkingWithinCeiling, intersectThinkingCeilings, type ThinkingLevel } from "../shared/thinking-ceiling.ts";
15
15
  import { SUBAGENT_LIFECYCLE_ARTIFACT_VERSION, type ArtifactDirPreference, type ArtifactPaths, type JsonSchemaObject, type OutputMode } from "../shared/types.ts";
16
16
  import { capabilityCeilingAgentRestrictionMessage, intersectSubagentCapabilityCeilings, type ResolvedSubagentCapabilityCeiling, type SubagentCapabilityAudit } from "../runs/shared/capability-ceiling.ts";
17
17
  import { resolvePermissionRules } from "../runs/shared/permissions.ts";
@@ -73,6 +73,7 @@ export interface SubagentLaunchContractInput {
73
73
  /** Current parent leaf required before an implicit `defaultContext: fork` stays `fork`. */
74
74
  parentLeafId?: string | null;
75
75
  sessionRoot?: string;
76
+ /** Caller directory used as a root keyed by the child run id ("preflight" placeholder when runId is omitted). */
76
77
  sessionDir?: string;
77
78
  runId?: string;
78
79
  /** Root run id supplied by a host when projecting nested async lifecycle paths. */
@@ -330,7 +331,6 @@ export async function resolveSubagentLaunchContract(input: SubagentLaunchContrac
330
331
  discovered.maxThinking,
331
332
  input.thinkingCeiling,
332
333
  input.inheritedThinkingCeiling,
333
- decodeThinkingCeiling(process.env[SUBAGENT_THINKING_CEILING_ENV]),
334
334
  );
335
335
  const model = externalRunner ? undefined : applyThinkingSuffix(primaryModel, effectiveThinkingConfig, input.thinking !== undefined);
336
336
  const modelCandidates = externalRunner
@@ -381,7 +381,10 @@ export async function resolveSubagentLaunchContract(input: SubagentLaunchContrac
381
381
  const artifactsDir = artifactsEnabled ? getArtifactsDir(input.parentSessionFile ?? null, effectiveCwd, input.artifactDir) : undefined;
382
382
  const artifactPaths = artifactsDir ? getArtifactPaths(artifactsDir, runId, agent.name, 0) : undefined;
383
383
  const outputPath = resolveSingleOutputPath(behavior.output, effectiveCwd, effectiveCwd, artifactsDir ? path.join(artifactsDir, "outputs", runId) : undefined);
384
- const sessionRoot = input.sessionDir ? path.resolve(input.sessionDir) : input.sessionRoot ? path.join(path.resolve(input.sessionRoot), runId) : undefined;
384
+ // An explicit sessionDir is a root keyed by the child run id, matching the
385
+ // sibling sessionRoot derivation; hosts omitting runId get the documented
386
+ // deterministic "preflight" placeholder.
387
+ const sessionRoot = input.sessionDir ? path.join(path.resolve(input.sessionDir), runId) : input.sessionRoot ? path.join(path.resolve(input.sessionRoot), runId) : undefined;
385
388
  const sessionDir = sessionRoot ? path.join(sessionRoot, "run-0") : undefined;
386
389
  const lifecycleAsyncDir = input.nestedRootRunId
387
390
  ? path.join(TEMP_ROOT_DIR, "nested-subagent-runs", input.nestedRootRunId, runId)
@@ -23,5 +23,5 @@ export {
23
23
  type ManagedWorktreeProvider,
24
24
  type WorktreeNaming,
25
25
  type WorktreeProvider,
26
- type WorkflowResourceProvenanceV1,
27
- } from "../shared/types.ts";
26
+ type WorkflowResourceProvenance,
27
+ } from "../shared/types.ts";
@@ -0,0 +1,6 @@
1
+ export { registerWorkflowResource } from "../workflows/workflow-resources.ts";
2
+ export type {
3
+ RegisterWorkflowResourceInput,
4
+ WorkflowResourceDefinition,
5
+ WorkflowResourceRegistration,
6
+ } from "../workflows/workflow-resources.ts";
@@ -10,6 +10,7 @@ import { DEFAULT_MODEL_EXCLUSION_TTL_MS, MAX_MODEL_EXCLUSION_TTL_MS, setDefaultT
10
10
  import { validatePermissionConfig } from "../runs/shared/permissions.ts";
11
11
  import { MAX_ABANDONED_SLOT_RELEASE_AFTER_MS, MIN_ABANDONED_SLOT_RELEASE_AFTER_MS } from "../runs/background/active-async-capacity.ts";
12
12
  import { normalizeWorktreeBranchPrefix } from "../runs/shared/worktree.ts";
13
+ import { validateModelResponseAliases } from "../shared/model-response-aliases.ts";
13
14
 
14
15
  const ARTIFACT_DIR_PREFERENCES = new Set<ArtifactDirPreference>(["project", "session", "temp"]);
15
16
  const FLEET_KEYBINDING_ACTION_SET = new Set<string>(FLEET_KEYBINDING_ACTIONS);
@@ -177,6 +178,7 @@ function validateConfig(config: Record<string, unknown>): void {
177
178
  validateArtifactConfig(config.artifactConfig);
178
179
  validateCapacityConfig(config.capacity);
179
180
  validateModelExclusionsConfig(config.modelExclusions);
181
+ validateModelResponseAliases(config.modelResponseAliases);
180
182
  validateMainWindowRendererConfig(config.mainWindowRenderer);
181
183
  validateOrcaProgressTabsConfig(config.orcaProgressTabs);
182
184
  }
@@ -240,12 +242,12 @@ export function loadConfig(): ExtensionConfig {
240
242
  return readConfigForUpdate(configPath);
241
243
  } catch (error) {
242
244
  if (error instanceof PrunedForkConfigError) throw error;
243
- // An explicitly requested worktree provider/prefix must not be silently
245
+ // Explicit route identity and worktree policies must not be silently
244
246
  // discarded and replaced by the built-in defaults after validation fails.
245
247
  try {
246
248
  const raw = JSON.parse(fs.readFileSync(configPath, "utf-8")) as unknown;
247
249
  if (raw && typeof raw === "object" && !Array.isArray(raw)
248
- && (Object.hasOwn(raw, "worktreeProvider") || Object.hasOwn(raw, "worktreeBranchPrefix"))) throw error;
250
+ && (Object.hasOwn(raw, "worktreeProvider") || Object.hasOwn(raw, "worktreeBranchPrefix") || Object.hasOwn(raw, "modelResponseAliases"))) throw error;
249
251
  } catch (readError) {
250
252
  if (readError === error) throw error;
251
253
  }