@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
@@ -0,0 +1,530 @@
1
+ /**
2
+ * Child tool plan: which builtin tools, MCP tools, runtime hooks, and extension
3
+ * files a child launch gets, and how that resolution is reported. Both the
4
+ * foreground path and the async runner build their session launch from this.
5
+ */
6
+ import { createHash } from "node:crypto";
7
+ import * as fs from "node:fs";
8
+ import * as path from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+ import {
11
+ formatUnresolvedMcpDirectToolSelectors,
12
+ resolveMcpDirectToolResolution,
13
+ type McpRuntimeSnapshotHost,
14
+ type ResolvedMcpDirectToolSelection,
15
+ } from "./mcp-direct-tool-allowlist.ts";
16
+ import {
17
+ TEMP_ROOT_DIR,
18
+ type JsonSchemaObject,
19
+ type LaunchResolvedChildExtensions,
20
+ } from "../../shared/types.ts";
21
+ import { THINKING_LEVELS } from "../../shared/model-info.ts";
22
+ import { getAgentDir } from "../../shared/utils.ts";
23
+ import type { PermissionRules } from "./permissions.ts";
24
+ import {
25
+ capabilityCeilingAgentRestrictionSources,
26
+ intersectSubagentCapabilityCeilings,
27
+ isAgentAllowedByCapabilityCeiling,
28
+ type ResolvedSubagentCapabilityCeiling,
29
+ type SubagentCapabilityAudit,
30
+ } from "./capability-ceiling.ts";
31
+
32
+ const MAX_LAUNCH_RESOLVED_EXTENSION_IDS = 32;
33
+ const PROMPT_RUNTIME_EXTENSION_PATH = path.join(
34
+ path.dirname(fileURLToPath(import.meta.url)),
35
+ "subagent-prompt-runtime.ts",
36
+ );
37
+ const FANOUT_CHILD_EXTENSION_PATH = path.join(
38
+ path.dirname(fileURLToPath(import.meta.url)),
39
+ "..",
40
+ "..",
41
+ "extension",
42
+ "fanout-child.ts",
43
+ );
44
+ const FAST_MODE_EXTENSION_PATH = path.join(
45
+ path.dirname(fileURLToPath(import.meta.url)),
46
+ "fast-mode-extension.ts",
47
+ );
48
+ const SUBAGENT_RUNTIME_EXTENSION_PATHS = new Set([
49
+ PROMPT_RUNTIME_EXTENSION_PATH,
50
+ FANOUT_CHILD_EXTENSION_PATH,
51
+ FAST_MODE_EXTENSION_PATH,
52
+ ].map((extensionPath) => path.normalize(extensionPath)));
53
+
54
+ /** True for the extension files pi-subagents itself installs in child sessions. */
55
+ export function isSubagentRuntimeExtensionPath(extensionPath: string): boolean {
56
+ return SUBAGENT_RUNTIME_EXTENSION_PATHS.has(path.normalize(extensionPath));
57
+ }
58
+ const FAST_MODE_ALLOWED_MODELS = new Set([
59
+ "openai-codex/gpt-5.6-luna",
60
+ "openai-codex/gpt-5.6-sol",
61
+ ]);
62
+ const OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH = 64;
63
+
64
+ export function deriveForkPromptCacheKey(parentSessionId: string | undefined): string | undefined {
65
+ const parent = parentSessionId?.trim();
66
+ if (!parent) return undefined;
67
+ const digest = createHash("sha256").update(parent).digest("hex").slice(0, OPENAI_PROMPT_CACHE_KEY_MAX_LENGTH - "pi-fork:".length);
68
+ return `pi-fork:${digest}`;
69
+ }
70
+
71
+ function sanitizeSupervisorChannelSegment(value: string): string {
72
+ return (
73
+ value
74
+ .trim()
75
+ .replace(/[^A-Za-z0-9._-]+/g, "-")
76
+ .replace(/^-+|-+$/g, "") || "unknown"
77
+ );
78
+ }
79
+
80
+ export function supervisorChannelDir(
81
+ runId: string,
82
+ agent: string,
83
+ childIndex: number,
84
+ ): string {
85
+ return path.join(
86
+ TEMP_ROOT_DIR,
87
+ "supervisor-channels",
88
+ `${sanitizeSupervisorChannelSegment(runId)}-${sanitizeSupervisorChannelSegment(agent)}-${childIndex}`,
89
+ );
90
+ }
91
+
92
+ export function applyThinkingSuffix(
93
+ model: string | undefined,
94
+ thinking: string | false | undefined,
95
+ replaceExisting = false,
96
+ ): string | undefined {
97
+ if (!model || !thinking) return model;
98
+ const colonIdx = model.lastIndexOf(":");
99
+ if (
100
+ colonIdx !== -1 &&
101
+ THINKING_LEVELS.some((level) => level === model.substring(colonIdx + 1))
102
+ ) {
103
+ return replaceExisting ? `${model.slice(0, colonIdx)}:${thinking}` : model;
104
+ }
105
+ return `${model}:${thinking}`;
106
+ }
107
+
108
+ function stripThinkingSuffix(model: string): string {
109
+ const colonIdx = model.lastIndexOf(":");
110
+ if (colonIdx === -1) return model;
111
+ return THINKING_LEVELS.some((level) => level === model.substring(colonIdx + 1))
112
+ ? model.slice(0, colonIdx)
113
+ : model;
114
+ }
115
+
116
+ function resolveFastModeExtension(input: Pick<ResolvePiLaunchToolPlanInput, "fast" | "model" | "modelCandidates" | "agentName">): string[] {
117
+ if (!input.fast) return [];
118
+ const candidates = (input.modelCandidates?.length ? input.modelCandidates : input.model ? [input.model] : [])
119
+ .map(stripThinkingSuffix);
120
+ if (candidates.length === 0) {
121
+ throw new Error(`fast mode requires an explicit supported native OpenAI-Codex model${input.agentName ? ` for agent '${input.agentName}'` : ""}.`);
122
+ }
123
+ const unsupported = candidates.filter((model) => !FAST_MODE_ALLOWED_MODELS.has(model));
124
+ if (unsupported.length > 0) {
125
+ throw new Error(`fast mode supports only ${[...FAST_MODE_ALLOWED_MODELS].join(", ")}; unsupported model${unsupported.length === 1 ? "" : "s"}: ${unsupported.join(", ")}.`);
126
+ }
127
+ return [FAST_MODE_EXTENSION_PATH];
128
+ }
129
+
130
+ export interface ResolvePiLaunchToolPlanInput {
131
+ tools?: string[];
132
+ excludeTools?: string[];
133
+ allowNestedSubagents?: boolean;
134
+ extensions?: string[];
135
+ subagentOnlyExtensions?: string[];
136
+ mcpDirectTools?: string[];
137
+ cwd?: string;
138
+ requireReadTool?: boolean;
139
+ structuredOutput?:
140
+ | boolean
141
+ | {
142
+ schema: JsonSchemaObject;
143
+ schemaPath: string;
144
+ outputPath: string;
145
+ };
146
+ fast?: boolean;
147
+ model?: string;
148
+ modelCandidates?: readonly string[];
149
+ capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
150
+ inheritedCapabilityCeiling?: ResolvedSubagentCapabilityCeiling;
151
+ agentName?: string;
152
+ permissionRules?: PermissionRules;
153
+ runtimeSnapshotHost?: McpRuntimeSnapshotHost;
154
+ }
155
+
156
+ export interface PiLaunchToolPlan {
157
+ capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
158
+ requestedBuiltinTools: string[];
159
+ declaredBuiltinTools: string[];
160
+ excludeTools: string[];
161
+ toolExtensionPaths: string[];
162
+ resolvedMcpSelections: ResolvedMcpDirectToolSelection[];
163
+ effectiveMcpSelections: ResolvedMcpDirectToolSelection[];
164
+ effectiveMcpTools: string[];
165
+ explicitToolAllowlist: boolean;
166
+ internalTools: string[];
167
+ effectiveToolAllowlist: string[];
168
+ requiredChildTools: string[];
169
+ fanoutAuthorized: boolean;
170
+ runtimeExtensions: string[];
171
+ configuredExtensions: string[];
172
+ extensionArgs: string[];
173
+ disableAmbientExtensions: boolean;
174
+ capabilityAudit?: SubagentCapabilityAudit;
175
+ /** Non-fatal launch warnings; they do not change behavior. */
176
+ warnings: string[];
177
+ }
178
+
179
+ function extensionIdentifier(value: string): string {
180
+ return `sha256:${createHash("sha256").update(path.normalize(value.trim())).digest("hex").slice(0, 16)}`;
181
+ }
182
+
183
+ function boundedExtensionIdentifiers(values: string[]): {
184
+ ids: string[];
185
+ omitted: number;
186
+ } {
187
+ const ids = [...new Set(values.map(extensionIdentifier))];
188
+ return {
189
+ ids: ids.slice(0, MAX_LAUNCH_RESOLVED_EXTENSION_IDS),
190
+ omitted: Math.max(0, ids.length - MAX_LAUNCH_RESOLVED_EXTENSION_IDS),
191
+ };
192
+ }
193
+
194
+ function hasPermissionRules(rules: PermissionRules | undefined): boolean {
195
+ return rules !== undefined && Object.keys(rules).length > 0;
196
+ }
197
+
198
+ /**
199
+ * Children are pi sessions inside the parent or the runner process; a spawned
200
+ * `pi` received extra MCP server definitions as a CLI argument, but a session
201
+ * has no such input. Selecting a server that exists only in pi-mcp-adapter's
202
+ * runtime snapshot therefore cannot work and fails the launch.
203
+ */
204
+ export function formatRuntimeSnapshotMcpServersError(agentName: string | undefined, serverNames: readonly string[]): string {
205
+ const subject = agentName ? `Agent '${agentName}'` : "Subagent";
206
+ return `${subject} selects MCP tools from servers that exist only in pi-mcp-adapter's runtime snapshot (${serverNames.join(", ")}). MCP servers from the runtime snapshot cannot be provided to in-process children; MCP tools must come from an ambient adapter extension in a background child (\`async: true\`), so add the server to the adapter's configuration file instead.`;
207
+ }
208
+
209
+ export function projectLaunchResolvedChildExtensions(
210
+ toolPlan: Pick<
211
+ PiLaunchToolPlan,
212
+ | "runtimeExtensions"
213
+ | "configuredExtensions"
214
+ | "extensionArgs"
215
+ | "disableAmbientExtensions"
216
+ >,
217
+ ): LaunchResolvedChildExtensions {
218
+ const runtime = boundedExtensionIdentifiers(toolPlan.runtimeExtensions);
219
+ const configured = boundedExtensionIdentifiers(toolPlan.configuredExtensions);
220
+ const effective = boundedExtensionIdentifiers(toolPlan.extensionArgs);
221
+ return {
222
+ version: 1,
223
+ source: "launch-resolved",
224
+ disableAmbientExtensions: toolPlan.disableAmbientExtensions,
225
+ runtime: runtime.ids,
226
+ configured: configured.ids,
227
+ effective: effective.ids,
228
+ omitted: {
229
+ runtime: runtime.omitted,
230
+ configured: configured.omitted,
231
+ effective: effective.omitted,
232
+ },
233
+ };
234
+ }
235
+
236
+ /**
237
+ * Resolve the permission-system extension entry point when installed.
238
+ * Returns the absolute path to the extension's main module, or undefined
239
+ * when the package is not installed. Callers can check `autoInject` config
240
+ * to decide whether to include it in child sessions.
241
+ */
242
+ export function resolvePermissionSystemExtension(): string | undefined {
243
+ const agentDir = getAgentDir();
244
+ const candidates = [
245
+ // npm-scoped package (most common)
246
+ path.join(
247
+ agentDir,
248
+ "npm",
249
+ "node_modules",
250
+ "@gotgenes",
251
+ "pi-permission-system",
252
+ ),
253
+ // direct extension directory (some layouts)
254
+ path.join(agentDir, "extensions", "pi-permission-system"),
255
+ ];
256
+ const errors: Error[] = [];
257
+ for (const extDir of candidates) {
258
+ if (!fs.existsSync(extDir)) continue;
259
+ const pkgPath = path.join(extDir, "package.json");
260
+ if (!fs.existsSync(pkgPath)) {
261
+ errors.push(new Error(`Permission-system package manifest is missing at ${pkgPath}.`));
262
+ continue;
263
+ }
264
+ try {
265
+ let pkg: { pi?: { extensions?: string[] } };
266
+ const parsed: unknown = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
267
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
268
+ throw new Error("manifest root must be an object");
269
+ }
270
+ pkg = parsed as typeof pkg;
271
+ const extensions = pkg.pi?.extensions;
272
+ const entry = Array.isArray(extensions) ? extensions[0] : undefined;
273
+ if (typeof entry !== "string" || !entry.trim()) {
274
+ throw new Error(
275
+ `Permission-system package manifest at ${pkgPath} must declare pi.extensions[0] as a non-empty string.`,
276
+ );
277
+ }
278
+ const resolved = path.resolve(extDir, entry);
279
+ if (fs.existsSync(resolved)) return resolved;
280
+ throw new Error(
281
+ `Permission-system extension entry ${JSON.stringify(entry)} in ${pkgPath} does not exist at ${resolved}.`,
282
+ );
283
+ } catch (error) {
284
+ const message = error instanceof Error ? error.message : String(error);
285
+ errors.push(message.startsWith("Permission-system") ? new Error(message) : new Error(`Cannot read permission-system package manifest at ${pkgPath}: ${message}`));
286
+ }
287
+ }
288
+ if (errors.length > 0) throw errors[0]!;
289
+ return undefined;
290
+ }
291
+
292
+ export function resolvePiLaunchToolPlan(
293
+ input: ResolvePiLaunchToolPlanInput,
294
+ ): PiLaunchToolPlan {
295
+ const capabilityCeiling = intersectSubagentCapabilityCeilings(
296
+ input.capabilityCeiling,
297
+ input.inheritedCapabilityCeiling,
298
+ );
299
+ const allowedToolSet =
300
+ capabilityCeiling?.allowedTools === undefined
301
+ ? undefined
302
+ : new Set(capabilityCeiling.allowedTools);
303
+ const requestedBuiltinTools =
304
+ input.tools?.filter(
305
+ (tool) =>
306
+ !(tool.includes("/") || tool.endsWith(".ts") || tool.endsWith(".js")),
307
+ ) ?? [];
308
+ if (input.requireReadTool && allowedToolSet && !allowedToolSet.has("read")) {
309
+ throw new Error(
310
+ `Capability ceiling from ${capabilityCeiling?.sources.join(", ") || "unknown source"} excludes required tool 'read' for lazy skill loading.`,
311
+ );
312
+ }
313
+ const declaredBuiltinTools =
314
+ input.tools === undefined
315
+ ? allowedToolSet
316
+ ? [...allowedToolSet]
317
+ : []
318
+ : (input.requireReadTool &&
319
+ requestedBuiltinTools.length > 0 &&
320
+ !requestedBuiltinTools.includes("read") &&
321
+ !allowedToolSet
322
+ ? ["read", ...requestedBuiltinTools]
323
+ : requestedBuiltinTools
324
+ ).filter((tool) => !allowedToolSet || allowedToolSet.has(tool));
325
+ const excludeTools = [...new Set((input.excludeTools ?? []).map((tool) => tool.trim()).filter(Boolean))];
326
+ const excludedToolSet = new Set(excludeTools);
327
+ const effectiveDeclaredBuiltinTools = declaredBuiltinTools.filter((tool) => !excludedToolSet.has(tool));
328
+ const fanoutAuthorized = effectiveDeclaredBuiltinTools.includes("subagent") || (
329
+ input.allowNestedSubagents === true &&
330
+ !excludedToolSet.has("subagent") &&
331
+ (!allowedToolSet || allowedToolSet.has("subagent"))
332
+ );
333
+ const toolExtensionPaths: string[] = capabilityCeiling?.denyExtensions
334
+ ? []
335
+ : (input.tools ?? []).filter(
336
+ (tool) =>
337
+ !requestedBuiltinTools.includes(tool) &&
338
+ (tool.includes("/") || tool.endsWith(".ts") || tool.endsWith(".js")),
339
+ );
340
+ const mcpResolution = capabilityCeiling?.denyExtensions
341
+ ? { selections: [], unresolvedSelectors: [] }
342
+ : resolveMcpDirectToolResolution(input.mcpDirectTools, input.cwd, input.runtimeSnapshotHost);
343
+ if (mcpResolution.runtimeServerNames?.length) {
344
+ throw new Error(formatRuntimeSnapshotMcpServersError(input.agentName, mcpResolution.runtimeServerNames));
345
+ }
346
+ if (mcpResolution.unresolvedSelectors.length > 0) {
347
+ throw new Error(formatUnresolvedMcpDirectToolSelectors(mcpResolution.unresolvedSelectors));
348
+ }
349
+ const resolvedMcpSelections = mcpResolution.selections;
350
+ const resolvedMcpNames = new Set(resolvedMcpSelections.map((selection) => selection.name));
351
+ const legacyMcpNameCounts = countLegacyUnderscoreMcpToolNames(resolvedMcpSelections);
352
+ const effectiveMcpSelections = resolvedMcpSelections.filter(
353
+ (selection) =>
354
+ !allowedToolSet ||
355
+ allowedToolSet.has(selection.name) ||
356
+ isLegacyUnderscoreMcpToolAllowed(selection, allowedToolSet, resolvedMcpNames, legacyMcpNameCounts),
357
+ ).filter((selection) => !excludedToolSet.has(selection.name));
358
+ const effectiveMcpTools = effectiveMcpSelections.map(
359
+ (selection) => selection.name,
360
+ );
361
+ const explicitToolAllowlist =
362
+ input.tools !== undefined ||
363
+ (input.mcpDirectTools?.length ?? 0) > 0 ||
364
+ allowedToolSet !== undefined;
365
+ const internalTools = (input.structuredOutput ? ["structured_output"] : []).filter((tool) => !excludedToolSet.has(tool));
366
+ const effectiveToolAllowlist = [
367
+ ...new Set([
368
+ ...effectiveDeclaredBuiltinTools,
369
+ ...effectiveMcpTools,
370
+ ...internalTools,
371
+ ]),
372
+ ];
373
+ // Supervisor-coordination names stay in the --tools allowlist but are never
374
+ // strict requirements: children register contact_supervisor at runtime through
375
+ // the native supervisor channel (or pi-intercom). The pre-0.50 bridge always
376
+ // appended intercom alongside contact_supervisor, so that exact pairing is
377
+ // legacy plumbing, not a user demand for an external intercom provider;
378
+ // a lone intercom entry stays strictly required (#1207).
379
+ const legacySupervisorPairing = effectiveDeclaredBuiltinTools.includes("contact_supervisor");
380
+ const requiredChildTools = explicitToolAllowlist
381
+ ? [
382
+ ...new Set([
383
+ ...(input.tools !== undefined ? effectiveDeclaredBuiltinTools : []),
384
+ ...(input.mcpDirectTools?.length ? effectiveMcpTools : []),
385
+ ...internalTools,
386
+ ].filter((tool) => tool !== "contact_supervisor" && (!legacySupervisorPairing || tool !== "intercom"))),
387
+ ]
388
+ : [];
389
+ const permSystemExt = capabilityCeiling?.denyExtensions
390
+ ? undefined
391
+ : hasPermissionRules(input.permissionRules)
392
+ ? resolvePermissionSystemExtension()
393
+ : undefined;
394
+ if (input.fast && capabilityCeiling?.denyExtensions) throw new Error("fast mode requires a child runtime extension, but this launch denies extensions.");
395
+ const fastModeExtensions = resolveFastModeExtension({ fast: input.fast, model: input.model, modelCandidates: input.modelCandidates, agentName: input.agentName });
396
+ const runtimeExtensions = [
397
+ PROMPT_RUNTIME_EXTENSION_PATH,
398
+ ...fastModeExtensions,
399
+ ...(fanoutAuthorized ? [FANOUT_CHILD_EXTENSION_PATH] : []),
400
+ ...(permSystemExt ? [permSystemExt] : []),
401
+ ];
402
+ const disableAmbientExtensions =
403
+ capabilityCeiling?.denyExtensions === true ||
404
+ input.extensions !== undefined;
405
+ const warnings: string[] = [];
406
+ // An explicit empty list disables ambient extensions, including model providers.
407
+ if (capabilityCeiling?.denyExtensions !== true && Array.isArray(input.extensions) && input.extensions.length === 0) {
408
+ const agentLabel = input.agentName ? ` for agent '${input.agentName}'` : "";
409
+ warnings.push(
410
+ `extensions: [] override${agentLabel} disables ALL ambient extensions for this child (not just "adds nothing"), `
411
+ + "including any model-provider extension needed to resolve a provider-qualified model. "
412
+ + "List the extensions this child actually needs instead of an empty array.",
413
+ );
414
+ }
415
+ const configuredExtensions = capabilityCeiling?.denyExtensions
416
+ ? []
417
+ : [
418
+ ...toolExtensionPaths,
419
+ ...(input.extensions ?? []),
420
+ ...(input.subagentOnlyExtensions ?? []),
421
+ ];
422
+ const extensionArgs = disableAmbientExtensions
423
+ ? [...new Set([...runtimeExtensions, ...configuredExtensions])]
424
+ : [
425
+ ...new Set([
426
+ ...runtimeExtensions,
427
+ ...toolExtensionPaths,
428
+ ...(input.subagentOnlyExtensions ?? []),
429
+ ]),
430
+ ];
431
+ const requestedToolNames =
432
+ input.tools !== undefined
433
+ ? [
434
+ ...new Set([
435
+ ...requestedBuiltinTools,
436
+ ...resolvedMcpSelections.map((selection) => selection.name),
437
+ ]),
438
+ ]
439
+ : undefined;
440
+ const capabilityAudit = capabilityCeiling
441
+ ? ({
442
+ ceiling: capabilityCeiling,
443
+ ...(requestedToolNames ? { requestedTools: requestedToolNames } : {}),
444
+ effectiveTools: effectiveToolAllowlist,
445
+ ...(excludeTools.length > 0 ? { excludeTools } : {}),
446
+ removedTools:
447
+ requestedToolNames?.filter(
448
+ (tool) => !effectiveToolAllowlist.includes(tool),
449
+ ) ?? [],
450
+ internalTools,
451
+ extensionsDenied: capabilityCeiling.denyExtensions,
452
+ removedExtensionCount: capabilityCeiling.denyExtensions
453
+ ? (input.extensions?.length ?? 0) +
454
+ (input.subagentOnlyExtensions?.length ?? 0) +
455
+ (input.tools ?? []).filter(
456
+ (tool) =>
457
+ tool.includes("/") ||
458
+ tool.endsWith(".ts") ||
459
+ tool.endsWith(".js"),
460
+ ).length
461
+ : 0,
462
+ requestedMcpToolCount: input.mcpDirectTools?.length ?? 0,
463
+ effectiveMcpTools,
464
+ agentAllowed:
465
+ input.agentName === undefined
466
+ ? true
467
+ : isAgentAllowedByCapabilityCeiling(
468
+ input.agentName,
469
+ capabilityCeiling,
470
+ ),
471
+ ...(capabilityCeilingAgentRestrictionSources(capabilityCeiling)
472
+ ? {
473
+ agentRestrictionSources:
474
+ capabilityCeilingAgentRestrictionSources(capabilityCeiling),
475
+ }
476
+ : {}),
477
+ } satisfies SubagentCapabilityAudit)
478
+ : undefined;
479
+ return {
480
+ ...(capabilityCeiling ? { capabilityCeiling } : {}),
481
+ requestedBuiltinTools,
482
+ declaredBuiltinTools,
483
+ excludeTools,
484
+ toolExtensionPaths,
485
+ resolvedMcpSelections,
486
+ effectiveMcpSelections,
487
+ effectiveMcpTools,
488
+ explicitToolAllowlist,
489
+ internalTools,
490
+ effectiveToolAllowlist,
491
+ requiredChildTools,
492
+ fanoutAuthorized,
493
+ runtimeExtensions,
494
+ configuredExtensions,
495
+ extensionArgs,
496
+ disableAmbientExtensions,
497
+ warnings,
498
+ ...(capabilityAudit ? { capabilityAudit } : {}),
499
+ };
500
+ }
501
+
502
+ // Capability ceilings persisted before #1685 may still name hyphenated MCP server prefixes with underscores.
503
+ function countLegacyUnderscoreMcpToolNames(selections: readonly ResolvedMcpDirectToolSelection[]): Map<string, number> {
504
+ const counts = new Map<string, number>();
505
+ for (const selection of selections) {
506
+ const legacyName = legacyUnderscoreMcpToolName(selection);
507
+ if (legacyName !== selection.name) counts.set(legacyName, (counts.get(legacyName) ?? 0) + 1);
508
+ }
509
+ return counts;
510
+ }
511
+
512
+ function isLegacyUnderscoreMcpToolAllowed(
513
+ selection: ResolvedMcpDirectToolSelection,
514
+ allowedToolSet: ReadonlySet<string>,
515
+ resolvedMcpNames: ReadonlySet<string>,
516
+ legacyMcpNameCounts: ReadonlyMap<string, number>,
517
+ ): boolean {
518
+ const legacyName = legacyUnderscoreMcpToolName(selection);
519
+ return legacyMcpNameCounts.get(legacyName) === 1 && !resolvedMcpNames.has(legacyName) && allowedToolSet.has(legacyName);
520
+ }
521
+
522
+ function legacyUnderscoreMcpToolName(selection: ResolvedMcpDirectToolSelection): string {
523
+ const slash = selection.selector.indexOf("/");
524
+ if (slash < 1) return selection.name;
525
+ const toolName = selection.selector.slice(slash + 1);
526
+ const suffix = `_${toolName}`;
527
+ if (!selection.name.endsWith(suffix)) return selection.name;
528
+ const prefix = selection.name.slice(0, -suffix.length);
529
+ return `${prefix.replace(/-/g, "_")}${suffix}`;
530
+ }
@@ -26,7 +26,7 @@ export function planCompletionEvidence(input: {
26
26
  mutationAttemptObserved: boolean;
27
27
  mutationEvidence?: TrackedMutationEvidence;
28
28
  arbiterRescued?: boolean;
29
- agentContractV1: boolean;
29
+ agentContractEnabled: boolean;
30
30
  }): CompletionEvidencePlan {
31
31
  const guardBlocked = input.guard?.blocked === true;
32
32
  const guardTriggered = input.guardTriggered
@@ -59,7 +59,7 @@ export function planCompletionEvidence(input: {
59
59
  mutationExpected,
60
60
  mutationAttempted,
61
61
  fileMutation,
62
- legacyFailureError: guardTriggered && !input.agentContractV1
62
+ legacyFailureError: guardTriggered && !input.agentContractEnabled
63
63
  ? MISSING_IMPLEMENTATION_MUTATION_ERROR
64
64
  : undefined,
65
65
  };
@@ -13,6 +13,7 @@ const READ_ONLY_BUILTIN_TOOLS = new Set([
13
13
  "web_search",
14
14
  "fetch_content",
15
15
  "get_search_content",
16
+ "source_check",
16
17
  "intercom",
17
18
  "contact_supervisor",
18
19
  "structured_output",
@@ -24,7 +25,7 @@ const READ_ONLY_BUILTIN_TOOLS = new Set([
24
25
  const CURSOR_FILE_MUTATION_THINKING =
25
26
  /(?:^|\n)\s*Cursor (?:edit|write)\s*:/i;
26
27
 
27
- const REVIVED_TASK_PREFIX = /^You are reviving a previous subagent conversation\.\n\nOriginal run: .+\nOriginal agent: .+(?:\nOriginal session file: .+)?\n\nUse the stored session context as background\. Answer the orchestrator's follow-up below\. Do not assume the original child process is still alive\.\n\nFollow-up:\n/;
28
+ const REVIVED_TASK_PREFIX = /^You are reviving a previous subagent conversation\.\n\nOriginal run: .+\nOriginal agent: .+(?:\nOriginal session file: .+)?\n\nUse the stored session context as background\. Answer the orchestrator's follow-up below\. Do not assume the original child session is still running\.\n\nFollow-up:\n/;
28
29
  const IMPLEMENTATION_CHALLENGE_FOLLOW_UP_PATTERN = /^(?:Run )?implementation challenge pass (?:one|two|\d+)(?:\s+and implement any better current[- ]scope change\.?|\s+for the accepted candidate\.\s+Reconsider it and implement any better current[- ]scope change\.?)?$/i;
29
30
  const NO_BETTER_CHANGE_NEEDED_PATTERN = /^\s*no (?:better|further|additional) (?:current[- ]scope )?(?:code |source |file )?(?:change|changes|edit|edits|patch|patches) (?:is|are) needed\b/i;
30
31
  const KEPT_CURRENT_IMPLEMENTATION_PATTERN = /\b(?:kept (?:the )?current (?:implementation|candidate|shape)|(?:the )?current (?:implementation|candidate|shape) was kept)\b/i;
@@ -5,6 +5,7 @@ import * as path from "node:path";
5
5
  const MAX_PROBE_OUTPUT_BYTES = 256 * 1024;
6
6
  const MAX_PROBE_TIMEOUT_MS = 5_000;
7
7
  const MAX_CACHE_ENTRIES = 64;
8
+ const MAX_AVAILABILITY_REASON_LENGTH = 256;
8
9
 
9
10
  export type ExternalCliPreflightInvalidationReason = "launch" | "auth" | "parser" | "permission";
10
11
 
@@ -32,6 +33,10 @@ type CachedPreflight = Omit<ExternalCliPreflightResult, "cacheHit">;
32
33
  const cache = new Map<string, CachedPreflight>();
33
34
  const lookup = new Map<string, string>();
34
35
 
36
+ export type ExternalCliBinaryAvailability =
37
+ | { available: true }
38
+ | { available: false; unavailableReason: string };
39
+
35
40
  function resolveBinary(command: string, env: NodeJS.ProcessEnv): string {
36
41
  if (path.isAbsolute(command) || command.includes(path.sep)) {
37
42
  const resolved = path.resolve(command);
@@ -52,6 +57,17 @@ function resolveBinary(command: string, env: NodeJS.ProcessEnv): string {
52
57
  throw new Error(`External CLI binary '${command}' was not found on PATH.`);
53
58
  }
54
59
 
60
+ /** Resolve only the configured command; unlike preflight, this never starts a child process. */
61
+ export function resolveExternalCliBinaryAvailability(command: string, env: NodeJS.ProcessEnv): ExternalCliBinaryAvailability {
62
+ try {
63
+ resolveBinary(command, env);
64
+ return { available: true };
65
+ } catch (error) {
66
+ const reason = error instanceof Error ? error.message : String(error);
67
+ return { available: false, unavailableReason: reason.slice(0, MAX_AVAILABILITY_REASON_LENGTH) };
68
+ }
69
+ }
70
+
55
71
  function probeWithTimeout(binaryPath: string, args: readonly string[], env: NodeJS.ProcessEnv, label: string, timeoutMs: number, cwd?: string): string {
56
72
  const result = spawnSync(binaryPath, [...args], {
57
73
  cwd,