@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,87 @@
1
+ import assert from "node:assert/strict";
2
+ import { describe, it } from "node:test";
3
+ import { appendAdvertisedAgentPrompt, buildAdvertisedAgentPrompt } from "../../src/agents/advertised-agent-prompt.ts";
4
+ import type { AgentConfig } from "../../src/agents/agents.ts";
5
+
6
+ function agent(name: string, overrides: Partial<AgentConfig> = {}): AgentConfig {
7
+ return {
8
+ name,
9
+ description: `${name} agent`,
10
+ systemPrompt: `${name} prompt`,
11
+ systemPromptMode: "replace",
12
+ inheritProjectContext: false,
13
+ inheritSkills: false,
14
+ source: "project",
15
+ filePath: `/tmp/${name}.md`,
16
+ ...overrides,
17
+ };
18
+ }
19
+
20
+ describe("advertised agent prompt", () => {
21
+ it("includes only opted-in, capability-permitted agents in stable order", () => {
22
+ const prompt = buildAdvertisedAgentPrompt([
23
+ agent("zeta", { advertise: true }),
24
+ agent("hidden"),
25
+ agent("disabled", { advertise: true, disabled: true }),
26
+ agent("alpha", { advertise: true }),
27
+ ], {
28
+ version: 1,
29
+ allowedAgents: ["alpha", "hidden", "zeta"],
30
+ denyExtensions: false,
31
+ sources: ["test"],
32
+ });
33
+
34
+ assert.ok(prompt);
35
+ assert.match(prompt, /<name>alpha<\/name>/);
36
+ assert.match(prompt, /<name>zeta<\/name>/);
37
+ assert.doesNotMatch(prompt, /hidden|disabled/);
38
+ assert.ok(prompt.indexOf("alpha") < prompt.indexOf("zeta"));
39
+ });
40
+
41
+ it("escapes agent-owned metadata and bounds the catalog", () => {
42
+ const agents = Array.from({ length: 18 }, (_, index) => agent(`agent-${String(index).padStart(2, "0")}`, {
43
+ advertise: true,
44
+ description: index === 0 ? `<route>&${"x".repeat(700)}` : `agent ${index}`,
45
+ }));
46
+ const prompt = buildAdvertisedAgentPrompt(agents);
47
+
48
+ assert.ok(prompt);
49
+ assert.match(prompt, /&lt;route&gt;&amp;/);
50
+ assert.doesNotMatch(prompt, /<route>/);
51
+ assert.match(prompt, /…<\/description>/);
52
+ assert.match(prompt, /<omitted count="2" \/>/);
53
+ });
54
+
55
+ it("replaces an existing catalog instead of duplicating it", () => {
56
+ const first = buildAdvertisedAgentPrompt([agent("alpha", { advertise: true })]);
57
+ const second = buildAdvertisedAgentPrompt([agent("beta", { advertise: true })]);
58
+ assert.ok(first);
59
+ assert.ok(second);
60
+
61
+ const systemPrompt = appendAdvertisedAgentPrompt(appendAdvertisedAgentPrompt("base prompt", first), second);
62
+ assert.equal(systemPrompt.match(/<advertised_subagents>/gu)?.length, 1);
63
+ assert.doesNotMatch(systemPrompt, /<name>alpha<\/name>/);
64
+ assert.match(systemPrompt, /<name>beta<\/name>/);
65
+ });
66
+
67
+ it("returns no catalog when no agent opts in", () => {
68
+ assert.equal(buildAdvertisedAgentPrompt([agent("hidden")]), undefined);
69
+ assert.equal(appendAdvertisedAgentPrompt("base prompt\n\n", undefined), "base prompt\n\n");
70
+ });
71
+
72
+ it("admits an exact-budget canonical name and omits it one byte over", () => {
73
+ const emptyName = buildAdvertisedAgentPrompt([agent("", { advertise: true, description: "small" })])!;
74
+ const name = "x".repeat(12_288 - Buffer.byteLength(emptyName));
75
+ const exact = buildAdvertisedAgentPrompt([agent(name, { advertise: true, description: "small" })])!;
76
+ assert.equal(Buffer.byteLength(exact), 12_288);
77
+ assert.ok(exact.includes(`<name>${name}</name>`));
78
+ const over = buildAdvertisedAgentPrompt([agent(`${name}x`, { advertise: true, description: "small" })])!;
79
+ assert.doesNotMatch(over, /<name>/);
80
+ assert.match(over, /<omitted count="1"/);
81
+ });
82
+
83
+ it("withdraws a reused catalog when the last advertised agent disappears", () => {
84
+ const prior = appendAdvertisedAgentPrompt("base prompt", buildAdvertisedAgentPrompt([agent("alpha", { advertise: true })]));
85
+ assert.equal(appendAdvertisedAgentPrompt(prior, buildAdvertisedAgentPrompt([])), "base prompt");
86
+ });
87
+ });
@@ -0,0 +1,163 @@
1
+ import assert from "node:assert/strict";
2
+ import { execFileSync } from "node:child_process";
3
+ import * as fs from "node:fs";
4
+ import * as os from "node:os";
5
+ import * as path from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { it } from "node:test";
8
+ import { SUBAGENT_CHILD_ENV } from "../../src/runs/shared/child-runtime-config.ts";
9
+
10
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
11
+
12
+ it("emits bounded file-only snapshots, refreshes through management, and performs zero prompt-time filesystem calls", () => {
13
+ const home = fs.mkdtempSync(path.join(os.tmpdir(), "advertised-refresh-"));
14
+ const env = { ...process.env, SELESAI_CODING_AGENT_DIR: home };
15
+ delete env[SUBAGENT_CHILD_ENV];
16
+ try {
17
+ const output = execFileSync(process.execPath, ["--experimental-strip-types", "--import", "./test/support/register-loader.mjs", "--input-type=module", "--eval", String.raw`
18
+ import assert from "node:assert/strict";
19
+ import fs from "node:fs";
20
+ import path from "node:path";
21
+ import { syncBuiltinESMExports } from "node:module";
22
+ import register from "./src/extension/index.ts";
23
+ import { registerSubagentCapabilityCeiling } from "./src/runs/shared/capability-ceiling.ts";
24
+ const home = process.env.SELESAI_CODING_AGENT_DIR;
25
+ const cwd = path.join(home, "project");
26
+ fs.mkdirSync(path.join(cwd, ".selesai"), { recursive: true });
27
+ const dir = path.join(home, "agents");
28
+ fs.mkdirSync(dir);
29
+ const write = (file, name, description, advertise = true) => fs.writeFileSync(path.join(dir, file + ".md"),
30
+ "---\nname: " + name + "\ndescription: " + description + "\nadvertise: " + advertise + "\n---\nAct narrowly.\n");
31
+ const handlers = new Map();
32
+ let tool;
33
+ let activeTools = ["subagent"];
34
+ const pi = new Proxy({
35
+ events: { on() { return () => {}; }, emit() {} },
36
+ on(event, handler) { handlers.set(event, [...(handlers.get(event) ?? []), handler]); },
37
+ registerTool(value) { if (value.name === "subagent") tool = value; },
38
+ getActiveTools() { return activeTools; },
39
+ }, { get(target, key) { return key in target ? target[key] : () => undefined; } });
40
+ register(pi);
41
+ const ctx = {
42
+ cwd, hasUI: false, model: { provider: "test", id: "test" },
43
+ modelRegistry: { getAvailable() { return []; }, getAll() { return []; } },
44
+ sessionManager: { getSessionId() { return "advertised-test"; }, getSessionFile() { return undefined; }, getBranch() { return []; } },
45
+ };
46
+ // Invoke the registered catalog lifecycle hook; unrelated host services are not started by this harness.
47
+ const refresh = (reason = "reload") => handlers.get("session_start").at(-1)({ reason }, ctx);
48
+ const emit = (systemPrompt = "base", selectedTools = activeTools) => {
49
+ const result = handlers.get("before_agent_start").at(-1)({ systemPrompt, systemPromptOptions: { selectedTools: selectedTools ?? undefined } }, ctx);
50
+ return result?.systemPrompt ?? systemPrompt;
51
+ };
52
+ const io = { statSync: 0, readdirSync: 0, readFileSync: 0 };
53
+ const originals = {};
54
+ for (const key of Object.keys(io)) {
55
+ originals[key] = fs[key];
56
+ fs[key] = (...args) => { io[key]++; return originals[key](...args); };
57
+ }
58
+ syncBuiltinESMExports();
59
+ const noIo = (fn) => {
60
+ const before = { ...io };
61
+ const result = fn();
62
+ assert.deepEqual(io, before, "prompt emission must not stat, readdir, or read files");
63
+ return result;
64
+ };
65
+ refresh("startup");
66
+ noIo(() => { for (let i = 0; i < 20; i++) assert.equal(emit(), "base"); });
67
+ for (let i = 0; i < 250; i++) write("hidden-" + i, "hidden-" + i, "hidden", false);
68
+ refresh();
69
+ noIo(() => { for (let i = 0; i < 20; i++) assert.equal(emit(), "base"); });
70
+ write("specialist", "specialist", "Original specialist");
71
+ assert.equal(noIo(() => emit()), "base", "external edits wait for reload");
72
+ refresh();
73
+ let prompt = noIo(() => emit());
74
+ assert.match(prompt, /<name>specialist<\/name>/);
75
+ assert.doesNotMatch(prompt, /hidden-/);
76
+ assert.match(prompt, /Before execution.*action: "list", capabilities: true/);
77
+ assert.equal(noIo(() => emit(prompt, ["read"])), "base");
78
+ activeTools = ["read"];
79
+ assert.equal(noIo(() => emit(prompt, null)), "base");
80
+ activeTools = ["subagent"];
81
+ const ceiling = registerSubagentCapabilityCeiling({ sessionId: "advertised-test", source: "test", ceiling: { allowedAgents: [] } });
82
+ assert.equal(noIo(() => emit(prompt)), "base");
83
+ ceiling.dispose();
84
+ assert.match(noIo(() => emit()), /Original specialist/);
85
+ const manage = async (params) => tool.execute("manage", params, new AbortController().signal, undefined, ctx);
86
+ write("pending", "pending", "External change awaiting refresh");
87
+ await manage({ action: "get", agent: "specialist" });
88
+ assert.doesNotMatch(noIo(() => emit()), /<name>pending<\/name>/, "reads must not refresh");
89
+ await assert.rejects(manage({ action: "update", agent: "specialist", config: { advertise: "invalid" } }), /config.advertise must be a boolean/);
90
+ assert.doesNotMatch(noIo(() => emit()), /<name>pending<\/name>/, "failed mutations must not refresh");
91
+ fs.unlinkSync(path.join(dir, "pending.md"));
92
+ let result = await manage({ action: "update", agent: "specialist", config: { description: "Updated specialist" } });
93
+ assert.notEqual(result.isError, true, JSON.stringify(result));
94
+ assert.match(noIo(() => emit(prompt)), /Updated specialist/);
95
+ assert.match(fs.readFileSync(path.join(dir, "specialist.md"), "utf8"), /advertise: true/);
96
+ result = await manage({ action: "disable", agent: "specialist", agentScope: "user" });
97
+ assert.notEqual(result.isError, true, JSON.stringify(result));
98
+ assert.equal(noIo(() => emit(prompt)), "base");
99
+ result = await manage({ action: "enable", agent: "specialist", agentScope: "user" });
100
+ assert.notEqual(result.isError, true, JSON.stringify(result));
101
+ prompt = noIo(() => emit());
102
+ assert.match(prompt, /Updated specialist/);
103
+ result = await manage({ action: "delete", agent: "specialist", agentScope: "user" });
104
+ assert.notEqual(result.isError, true, JSON.stringify(result));
105
+ assert.equal(noIo(() => emit(prompt)), "base");
106
+ result = await manage({ action: "create", config: { name: "created", description: "Created specialist", systemPrompt: "Act narrowly.", scope: "user", advertise: true } });
107
+ assert.notEqual(result.isError, true, JSON.stringify(result));
108
+ assert.match(noIo(() => emit()), /<name>created<\/name>/);
109
+ result = await manage({ action: "update", agent: "created", config: { name: "renamed" } });
110
+ assert.notEqual(result.isError, true, JSON.stringify(result));
111
+ prompt = noIo(() => emit());
112
+ assert.match(prompt, /<name>renamed<\/name>/);
113
+ assert.doesNotMatch(prompt, /<name>created<\/name>/);
114
+ result = await manage({ action: "update", agent: "renamed", config: { advertise: false } });
115
+ assert.notEqual(result.isError, true, JSON.stringify(result));
116
+ assert.equal(noIo(() => emit(prompt)), "base");
117
+ // Inject a refresh-only read failure after the management file write has succeeded.
118
+ await manage({ action: "update", agent: "renamed", config: { advertise: true } });
119
+ prompt = noIo(() => emit());
120
+ assert.match(prompt, /<name>renamed<\/name>/);
121
+ const writeFile = fs.writeFileSync;
122
+ fs.writeFileSync = (file, ...args) => {
123
+ const result = writeFile(file, ...args);
124
+ if (String(file).endsWith("renamed.md")) writeFile(path.join(home, "settings.json"), "{");
125
+ return result;
126
+ };
127
+ syncBuiltinESMExports();
128
+ result = await manage({ action: "update", agent: "renamed", config: { description: "Persisted despite refresh failure" } });
129
+ assert.notEqual(result.isError, true, "refresh failure must not change the persisted mutation result");
130
+ assert.match(fs.readFileSync(path.join(dir, "renamed.md"), "utf8"), /advertise: true/);
131
+ assert.equal(noIo(() => emit(prompt)), "base", "failed refresh withdraws stale guidance");
132
+ assert.throws(() => refresh(), /Failed to parse settings file/, "reload discovery errors must reach the host");
133
+ fs.writeFileSync = writeFile;
134
+ syncBuiltinESMExports();
135
+ fs.unlinkSync(path.join(home, "settings.json"));
136
+ refresh();
137
+ assert.match(noIo(() => emit()), /<name>renamed<\/name>/);
138
+ await manage({ action: "delete", agent: "renamed", agentScope: "user" });
139
+ write("huge", "a".repeat(100000), "huge name");
140
+ write("escaped-name", "b" + "&".repeat(4000), "escaped huge name");
141
+ for (let i = 0; i < 25; i++) write("opt-" + i, "pkg.opt-" + i, i % 2 ? '<>&"'.repeat(300) : "🦜界".repeat(300));
142
+ refresh();
143
+ prompt = noIo(() => { let result; for (let i = 0; i < 20; i++) result = emit(); return result; });
144
+ const catalog = prompt.slice(prompt.indexOf("<advertised_subagents>"));
145
+ assert.ok(Buffer.byteLength(catalog) <= 12288);
146
+ assert.doesNotMatch(catalog, /<name>[ab]/);
147
+ assert.match(catalog, /&lt;&gt;&amp;&quot;/);
148
+ assert.match(catalog, /not instructions to delegate/);
149
+ assert.match(catalog, /🦜界/);
150
+ assert.doesNotMatch(catalog, /�/);
151
+ assert.match(catalog, /<name>pkg\.opt-\d+<\/name>/);
152
+ assert.match(catalog, /<omitted count="\d+"/);
153
+ for (const file of fs.readdirSync(dir)) fs.unlinkSync(path.join(dir, file));
154
+ assert.equal(noIo(() => emit()), prompt, "external removal waits for reload");
155
+ refresh();
156
+ assert.equal(noIo(() => emit(prompt)), "base");
157
+ process.stdout.write("prompt contracts passed; zero prompt-time stat/readdir/readFile calls at 0, 250, and 277 definitions");
158
+ `], { cwd: root, env, encoding: "utf8", timeout: 60_000 });
159
+ assert.match(output, /prompt contracts passed/);
160
+ } finally {
161
+ fs.rmSync(home, { recursive: true, force: true });
162
+ }
163
+ });
@@ -9,7 +9,8 @@ import { serializeAgent } from "../../src/agents/agent-serializer.ts";
9
9
  import { parseChain, serializeChain } from "../../src/agents/chain-serializer.ts";
10
10
  import { discoverAgents, discoverAgentsAll, inspectAgentDefinitionDirectory, type AgentConfig } from "../../src/agents/agents.ts";
11
11
  import { parseFrontmatter } from "../../src/agents/frontmatter.ts";
12
- import { buildPiArgs } from "../../src/runs/shared/pi-args.ts";
12
+ import { buildInProcessChildLaunch } from "../../src/runs/shared/child-launch.ts";
13
+ import { applyThinkingSuffix } from "../../src/runs/shared/child-tool-plan.ts";
13
14
  import { THINKING_LEVELS } from "../../src/shared/model-info.ts";
14
15
 
15
16
  const tempDirs: string[] = [];
@@ -384,6 +385,31 @@ body`);
384
385
  }));
385
386
  });
386
387
 
388
+ describe("agent advertise frontmatter", () => {
389
+ it("parses and serializes explicit prompt advertisement", () => withTempHome(() => {
390
+ const project = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-advertised-agent-"));
391
+ tempDirs.push(project);
392
+ writeAgent(path.join(project, ".selesai", "agents", "worker.md"), `---
393
+ name: worker
394
+ description: Worker
395
+ advertise: true
396
+ ---
397
+ body`);
398
+
399
+ const worker = discoverAgents(project, "both").agents.find((agent) => agent.name === "worker")!;
400
+ assert.equal(worker.advertise, true);
401
+ assert.match(serializeAgent(worker), /^advertise: true$/m);
402
+ }));
403
+
404
+ it("rejects non-boolean advertise values", () => withTempHome(() => {
405
+ const project = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-invalid-advertise-"));
406
+ tempDirs.push(project);
407
+ writeAgent(path.join(project, ".selesai", "agents", "worker.md"), "---\nname: worker\ndescription: Worker\nadvertise: yes\n---\nbody");
408
+
409
+ assert.match(discoverAgents(project, "project").agentDiagnostics?.[0]?.error ?? "", /invalid advertise frontmatter; expected true or false/);
410
+ }));
411
+ });
412
+
387
413
  describe("agent aliases", () => {
388
414
  it("parses and serializes agent aliases", () => withTempHome(() => {
389
415
  const project = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-alias-agent-"));
@@ -1037,7 +1063,7 @@ Review nested project work.
1037
1063
  assert.equal(agent.filePath, path.join(packageRoot, "agents", "reviewer.md"));
1038
1064
  }));
1039
1065
 
1040
- it("keeps nearest project root discovery by default when a nested .selesai exists", () => withTempHome(() => {
1066
+ it("keeps nearest project root discovery by default when a nested .pi exists", () => withTempHome(() => {
1041
1067
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-nearest-root-default-"));
1042
1068
  tempDirs.push(dir);
1043
1069
  const nested = path.join(dir, "packages", "app", "src");
@@ -1103,7 +1129,7 @@ Plan outer project work.
1103
1129
  assert.equal(reviewer?.override?.path, path.join(dir, ".selesai", "settings.json"));
1104
1130
  }));
1105
1131
 
1106
- it("keeps git-root discovery stable when a nested linked worktree creates incidental .selesai state", () => withTempHome(() => {
1132
+ it("keeps git-root discovery stable when a nested linked worktree creates incidental .pi state", () => withTempHome(() => {
1107
1133
  const { repo, worktree } = createNestedLinkedWorktree();
1108
1134
  const { packageAgentName, packageAgentPath, settingsPath } = writeLinkedWorktreePackage(repo);
1109
1135
 
@@ -1514,19 +1540,19 @@ Do work
1514
1540
  assert.ok(agent);
1515
1541
  assert.equal(agent.thinking, false);
1516
1542
 
1517
- const { args } = buildPiArgs({
1518
- baseArgs: ["-p"],
1519
- task: "hello",
1543
+ const { session } = buildInProcessChildLaunch({
1544
+ host: "parent",
1545
+ cwd: dir,
1520
1546
  sessionEnabled: false,
1521
- model: agent.model,
1522
- thinking: agent.thinking,
1547
+ model: applyThinkingSuffix(agent.model, agent.thinking),
1523
1548
  inheritProjectContext: agent.inheritProjectContext,
1549
+ inheritGlobalContext: agent.inheritGlobalContext,
1524
1550
  inheritSkills: agent.inheritSkills,
1551
+ childAgentName: agent.name,
1552
+ childIndex: 0,
1525
1553
  });
1526
1554
 
1527
- assert.ok(args.includes("--model"));
1528
- assert.ok(args.includes("glm-5.2-short-fast"));
1529
- assert.ok(!args.some((arg) => arg.includes(":false")));
1555
+ assert.equal(session.model, "glm-5.2-short-fast");
1530
1556
  }
1531
1557
  });
1532
1558
 
@@ -1769,26 +1795,22 @@ Do work
1769
1795
  });
1770
1796
 
1771
1797
  it("adds the fast extension only for allowlisted native models", () => {
1772
- const allowed = buildPiArgs({
1773
- baseArgs: ["-p"],
1774
- task: "hello",
1798
+ const launch = {
1799
+ host: "parent" as const,
1800
+ cwd: process.cwd(),
1775
1801
  sessionEnabled: false,
1776
- model: "openai-codex/gpt-5.6-luna:low",
1777
- fast: true,
1778
1802
  inheritProjectContext: false,
1803
+ inheritGlobalContext: false,
1779
1804
  inheritSkills: false,
1780
- });
1781
-
1782
- assert.ok(allowed.args.some((arg) => arg.endsWith("fast-mode-extension.ts")));
1783
- assert.throws(() => buildPiArgs({
1784
- baseArgs: ["-p"],
1785
- task: "hello",
1786
- sessionEnabled: false,
1787
- model: "anthropic/claude-sonnet-4",
1805
+ childAgentName: "worker",
1806
+ childIndex: 0,
1788
1807
  fast: true,
1789
- inheritProjectContext: false,
1790
- inheritSkills: false,
1791
- }), /fast mode supports only/);
1808
+ };
1809
+ const allowed = buildInProcessChildLaunch({ ...launch, model: "openai-codex/gpt-5.6-luna:low" });
1810
+
1811
+ assert.ok(allowed.toolPlan.runtimeExtensions.some((extensionPath) => extensionPath.endsWith("fast-mode-extension.ts")));
1812
+ assert.deepEqual(allowed.session.hooks.map((hook) => hook.name), ["pi-subagents:prompt-runtime", "pi-subagents:fast-mode"]);
1813
+ assert.throws(() => buildInProcessChildLaunch({ ...launch, model: "anthropic/claude-sonnet-4" }), /fast mode supports only/);
1792
1814
  });
1793
1815
  });
1794
1816
 
@@ -1865,7 +1887,7 @@ Do work
1865
1887
  }
1866
1888
  });
1867
1889
 
1868
- it("worker and delegate include the child-facing supervisor tool", () => {
1890
+ it("bundled standard agents keep bounded tool allowlists", () => {
1869
1891
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-builtin-supervisor-tool-"));
1870
1892
  const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-builtin-supervisor-tool-home-"));
1871
1893
  tempDirs.push(dir);
@@ -1877,11 +1899,28 @@ Do work
1877
1899
  process.env.HOME = homeDir;
1878
1900
  process.env.USERPROFILE = homeDir;
1879
1901
  const agents = discoverAgentsAll(dir).builtin;
1880
- for (const name of ["worker", "delegate"]) {
1902
+ const expectedTools = {
1903
+ worker: ["read", "grep", "find", "ls", "bash", "edit", "write", "contact_supervisor"],
1904
+ delegate: ["read", "grep", "find", "ls", "bash", "edit", "write", "contact_supervisor"],
1905
+ reviewer: ["read", "grep", "find", "ls", "contact_supervisor"],
1906
+ scout: ["read", "grep", "find", "ls", "bash", "write", "contact_supervisor"],
1907
+ researcher: ["read", "write", "web_search", "fetch_content", "get_search_content", "source_check"],
1908
+ };
1909
+ for (const [name, tools] of Object.entries(expectedTools)) {
1881
1910
  const agent = agents.find((candidate) => candidate.name === name);
1882
1911
  assert.ok(agent, `${name} builtin should be discovered`);
1883
- assert.deepEqual(agent?.tools, ["read", "grep", "find", "ls", "bash", "edit", "write", "contact_supervisor"]);
1912
+ assert.deepEqual(agent?.tools, tools);
1884
1913
  }
1914
+
1915
+ const researcherPrompt = agents.find((candidate) => candidate.name === "researcher")?.systemPrompt ?? "";
1916
+ assert.match(researcherPrompt, /search-result summaries as discovery aids, not final evidence/);
1917
+ assert.match(researcherPrompt, /source_check.*decision-critical or disputed claims/);
1918
+ assert.match(researcherPrompt, /direct evidence, source interpretation, and researcher inference distinctly/);
1919
+ assert.match(researcherPrompt, /Record contradictions.*Record missing evidence/);
1920
+ assert.match(researcherPrompt, /Never invent dates, quotations, citations, or unsupported precision/);
1921
+ assert.match(researcherPrompt, /`source_check` must be registered by the loaded provider before launch/);
1922
+ assert.match(researcherPrompt, /If a registered `source_check` call fails, continue/);
1923
+ assert.match(researcherPrompt, /\*\*Support:\*\* direct evidence \| interpretation\. \*\*Confidence:\*\* high \| medium \| low/);
1885
1924
  } finally {
1886
1925
  if (previousHome === undefined) delete process.env.HOME;
1887
1926
  else process.env.HOME = previousHome;
@@ -2321,4 +2360,4 @@ Inspect project
2321
2360
  else process.env.USERPROFILE = oldUserProfile;
2322
2361
  }
2323
2362
  });
2324
- });
2363
+ });
@@ -109,6 +109,81 @@ describe("agent management config parsing", () => {
109
109
  assert.equal(JSON.stringify(capabilities).includes("SYSTEM_PROMPT_SENTINEL"), false);
110
110
  });
111
111
 
112
+ it("reports bundled reviewer supervisor contact without mutation tools in capabilities", () => {
113
+ const listed = handleManagementAction("list", { agentScope: "project", capabilities: true }, {
114
+ cwd: tempDir,
115
+ modelRegistry: { getAvailable: () => [] },
116
+ });
117
+
118
+ assert.equal(listed.isError, false);
119
+ const capabilities = listed.details?.agentCapabilities;
120
+ assert.ok(capabilities);
121
+ const reviewer = capabilities.agents.find((agent) => agent.name === "reviewer");
122
+ assert.ok(reviewer, "reviewer builtin should be present in capability output");
123
+ assert.deepEqual(reviewer.tools.names, ["read", "grep", "find", "ls", "contact_supervisor"]);
124
+ assert.match(readText(listed), /Tools: read, grep, find, ls, contact_supervisor/);
125
+ });
126
+
127
+ it("reports passive external CLI availability for present and absent commands", () => {
128
+ const agentsDir = path.join(tempDir, ".selesai", "agents");
129
+ fs.mkdirSync(agentsDir, { recursive: true });
130
+ const presentCommand = path.basename(process.execPath, path.extname(process.execPath));
131
+ fs.writeFileSync(path.join(agentsDir, "present-external.md"), `---
132
+ name: present-external
133
+ description: Present external CLI
134
+ runner:
135
+ type: external-cli
136
+ command: ${presentCommand}
137
+ ---
138
+ Present.
139
+ `);
140
+ fs.writeFileSync(path.join(agentsDir, "missing-external.md"), `---
141
+ name: missing-external
142
+ description: Missing external CLI
143
+ runner:
144
+ type: external-cli
145
+ command: missing-external-cli
146
+ ---
147
+ Missing.
148
+ `);
149
+ const previousPath = process.env.PATH;
150
+ try {
151
+ process.env.PATH = path.dirname(process.execPath);
152
+ const listed = handleManagementAction("list", { agentScope: "project", capabilities: true }, {
153
+ cwd: tempDir,
154
+ modelRegistry: { getAvailable: () => [] },
155
+ });
156
+ assert.equal(listed.isError, false);
157
+ const text = readText(listed);
158
+ assert.match(text, new RegExp(`external-cli:${presentCommand} ✓`));
159
+ assert.match(text, /external-cli:missing-external-cli missing/);
160
+
161
+ const rows = listed.details?.agentCapabilities?.agents;
162
+ assert.ok(rows);
163
+ const present = rows.find((agent) => agent.name === "present-external");
164
+ const missing = rows.find((agent) => agent.name === "missing-external");
165
+ assert.ok(present);
166
+ assert.ok(missing);
167
+ assert.equal(present.executable, true);
168
+ assert.equal(missing.executable, true);
169
+ assert.equal(present.runner.type, "external-cli");
170
+ assert.equal(missing.runner.type, "external-cli");
171
+ if (present.runner.type !== "external-cli" || missing.runner.type !== "external-cli") return;
172
+ assert.equal(present.runner.command, presentCommand);
173
+ assert.equal(present.runner.available, true);
174
+ assert.equal("unavailableReason" in present.runner, false);
175
+ assert.equal(missing.runner.command, "missing-external-cli");
176
+ assert.equal(missing.runner.available, false);
177
+ assert.match(missing.runner.unavailableReason ?? "", /External CLI binary 'missing-external-cli' was not found on PATH\./);
178
+ assert.ok((missing.runner.unavailableReason ?? "").length <= 256);
179
+ } finally {
180
+ if (previousPath === undefined) delete process.env.PATH;
181
+ else process.env.PATH = previousPath;
182
+ }
183
+ });
184
+
185
+
186
+
112
187
  it("lists valid agents and diagnoses malformed agent definitions", () => {
113
188
  const agentsDir = path.join(tempDir, ".selesai", "agents");
114
189
  fs.mkdirSync(agentsDir, { recursive: true });
@@ -343,7 +418,7 @@ Advise only.
343
418
  assert.match(readText(result), /Agent 'foo' has invalid configuration: Agent 'foo' package is invalid after sanitization/);
344
419
  });
345
420
 
346
- it("blocks a malformed .selesai agent from falling back to a legacy project agent", () => {
421
+ it("blocks a malformed .pi agent from falling back to a legacy project agent", () => {
347
422
  const canonicalAgentsDir = path.join(tempDir, ".selesai", "agents");
348
423
  const legacyAgentsDir = path.join(tempDir, ".agents");
349
424
  fs.mkdirSync(canonicalAgentsDir, { recursive: true });
@@ -1326,7 +1401,7 @@ Drive the failing test first.
1326
1401
  assert.match(text, /Source: project override/);
1327
1402
  assert.match(text, /Requested model setting:\n claude-sonnet-4/);
1328
1403
  assert.match(text, /Disabled: true/);
1329
- assert.match(text.replaceAll("\\", "/"), /Override file:\n .*\.selesai[\\/]settings\.json/);
1404
+ assert.match(text.replaceAll("\\", "/"), /Override file:\n .*\.selesai\/settings\.json/);
1330
1405
  });
1331
1406
 
1332
1407
  it("rejects unknown agents for runtime model mappings", () => {
@@ -1405,4 +1480,4 @@ Inspect cleanup.
1405
1480
  assert.doesNotMatch(readText(listed), /Proactive skill subagent suggestions:/);
1406
1481
  });
1407
1482
 
1408
- });
1483
+ });
@@ -113,7 +113,7 @@ describe("builtin agent overrides", () => {
113
113
 
114
114
  const builtins = discoverAgentsAll(tempProject).builtin;
115
115
  assert.equal(builtins.find((agent) => agent.name === "researcher")?.tools, undefined);
116
- assert.deepEqual(builtins.find((agent) => agent.name === "reviewer")?.tools, ["read", "grep", "find", "ls"]);
116
+ assert.deepEqual(builtins.find((agent) => agent.name === "reviewer")?.tools, ["read", "grep", "find", "ls", "contact_supervisor"]);
117
117
  });
118
118
 
119
119
  it("keeps explicit empty builtin tool allowlists distinct from inherited tools", () => {
@@ -719,7 +719,6 @@ describe("builtin agent overrides", () => {
719
719
  it("agentOverrides replace frontmatter for a shadowing project agent", () => {
720
720
  fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
721
721
  writeJson(path.join(tempProject, ".selesai", "settings.json"), {
722
-
723
722
  subagents: { agentOverrides: { reviewer: { model: "openai/gpt-5.4" } } },
724
723
  });
725
724
  writeProjectAgent(tempProject, "reviewer", `---\nname: reviewer\ndescription: Project reviewer\nmodel: google/gemini-3-pro\n---\n\nUse the project reviewer.\n`);
@@ -734,7 +733,6 @@ describe("builtin agent overrides", () => {
734
733
  it("applies project agentOverrides to a custom project agent", () => {
735
734
  fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
736
735
  writeJson(path.join(tempProject, ".selesai", "settings.json"), {
737
-
738
736
  subagents: {
739
737
  agentOverrides: {
740
738
  implementer: {
@@ -786,7 +784,6 @@ describe("builtin agent overrides", () => {
786
784
 
787
785
  it("applies user agentOverrides to a custom user agent", () => {
788
786
  writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
789
-
790
787
  subagents: { agentOverrides: { implementer: { model: "anthropic/claude-sonnet-4-6" } } },
791
788
  });
792
789
  writeUserAgent(tempHome, "implementer", `---\nname: implementer\ndescription: TDD implementer\n---\n\nDrive the failing test first.\n`);
@@ -832,7 +829,6 @@ describe("builtin agent overrides", () => {
832
829
  it("agentOverrides replace explicit custom frontmatter fields", () => {
833
830
  fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
834
831
  writeJson(path.join(tempProject, ".selesai", "settings.json"), {
835
-
836
832
  subagents: {
837
833
  agentOverrides: {
838
834
  implementer: {
@@ -877,7 +873,6 @@ describe("builtin agent overrides", () => {
877
873
  it("lets false overrides clear explicit output and defaultReads frontmatter", () => {
878
874
  fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
879
875
  writeJson(path.join(tempProject, ".selesai", "settings.json"), {
880
-
881
876
  subagents: { agentOverrides: { implementer: { output: false, defaultReads: false } } },
882
877
  });
883
878
  writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\noutput: explicit.md\ndefaultReads: explicit.md\n---\n\nDrive the failing test first.\n`);
@@ -1058,7 +1053,6 @@ describe("builtin agent overrides", () => {
1058
1053
  writeJson(path.join(packageRoot, "package.json"), { "pi-subagents": { agents: ["agents"] } });
1059
1054
  fs.writeFileSync(path.join(packageRoot, "agents", "package-scout.md"), `---\nname: package-scout\ndescription: Package scout\noutput: package-frontmatter.md\ndefaultReads: PACKAGE-FRONTMATTER.md\n---\n\nScout the package.\n`, "utf-8");
1060
1055
  writeJson(path.join(tempProject, ".selesai", "settings.json"), {
1061
-
1062
1056
  packages: [packageRoot],
1063
1057
  subagents: { agentOverrides: { "package-scout": { output: "package.md", defaultReads: ["PACKAGE.md"] } } },
1064
1058
  });
@@ -1171,4 +1165,4 @@ describe("builtin agent overrides", () => {
1171
1165
  );
1172
1166
  assert.equal(whitespaceDescription, undefined);
1173
1167
  });
1174
- });
1168
+ });
@@ -77,7 +77,7 @@ describe("async runner execution", () => {
77
77
  agents: [{ ...agent("worker"), model: "mock/denied" }],
78
78
  ctx: { ...ctx, cwd: repo },
79
79
  cwd: repo,
80
- asyncDir: path.join(repo, ".selesai", "subagents", "async-step-rules"),
80
+ asyncDir: path.join(repo, ".pi-subagents", "async-step-rules"),
81
81
  maxSubagentDepth: 1,
82
82
  });
83
83