@selesai/code 0.6.3 → 0.8.0

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 (1056) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/README.md +5 -3
  3. package/dist/bun/cli.d.ts +0 -1
  4. package/dist/bun/cli.js +0 -1
  5. package/dist/bun/register-bedrock.d.ts +0 -1
  6. package/dist/bun/register-bedrock.js +0 -1
  7. package/dist/bun/restore-sandbox-env.d.ts +0 -1
  8. package/dist/bun/restore-sandbox-env.js +0 -1
  9. package/dist/cli/args.d.ts +0 -1
  10. package/dist/cli/args.js +0 -1
  11. package/dist/cli/config-selector.d.ts +0 -1
  12. package/dist/cli/config-selector.js +0 -1
  13. package/dist/cli/credential-print.d.ts +0 -1
  14. package/dist/cli/credential-print.js +0 -1
  15. package/dist/cli/file-processor.d.ts +0 -1
  16. package/dist/cli/file-processor.js +0 -1
  17. package/dist/cli/initial-message.d.ts +0 -1
  18. package/dist/cli/initial-message.js +0 -1
  19. package/dist/cli/list-models.d.ts +0 -1
  20. package/dist/cli/list-models.js +0 -1
  21. package/dist/cli/project-trust.d.ts +0 -1
  22. package/dist/cli/project-trust.js +0 -1
  23. package/dist/cli/session-picker.d.ts +0 -1
  24. package/dist/cli/session-picker.js +0 -1
  25. package/dist/cli/startup-ui.d.ts +0 -1
  26. package/dist/cli/startup-ui.js +0 -1
  27. package/dist/cli.d.ts +0 -1
  28. package/dist/cli.js +0 -1
  29. package/dist/config.d.ts +0 -1
  30. package/dist/config.js +0 -1
  31. package/dist/core/agent-session-auto-handoff.test.d.ts +0 -1
  32. package/dist/core/agent-session-auto-handoff.test.js +0 -1
  33. package/dist/core/agent-session-runtime.d.ts +0 -1
  34. package/dist/core/agent-session-runtime.js +0 -1
  35. package/dist/core/agent-session-services.d.ts +0 -1
  36. package/dist/core/agent-session-services.js +0 -1
  37. package/dist/core/agent-session-skill-block.test.d.ts +0 -1
  38. package/dist/core/agent-session-skill-block.test.js +0 -1
  39. package/dist/core/agent-session.d.ts +0 -1
  40. package/dist/core/agent-session.js +0 -1
  41. package/dist/core/agents.d.ts +0 -1
  42. package/dist/core/agents.js +0 -1
  43. package/dist/core/auth-guidance.d.ts +0 -1
  44. package/dist/core/auth-guidance.js +0 -1
  45. package/dist/core/auth-storage.d.ts +0 -1
  46. package/dist/core/auth-storage.js +0 -1
  47. package/dist/core/bash-executor.d.ts +0 -1
  48. package/dist/core/bash-executor.js +0 -1
  49. package/dist/core/built-in-extensions.d.ts +0 -1
  50. package/dist/core/built-in-extensions.js +0 -1
  51. package/dist/core/cache-stats.d.ts +0 -1
  52. package/dist/core/cache-stats.js +0 -1
  53. package/dist/core/compaction/branch-summarization.d.ts +0 -1
  54. package/dist/core/compaction/branch-summarization.js +0 -1
  55. package/dist/core/compaction/compaction.d.ts +0 -1
  56. package/dist/core/compaction/compaction.js +0 -1
  57. package/dist/core/compaction/index.d.ts +0 -1
  58. package/dist/core/compaction/index.js +0 -1
  59. package/dist/core/compaction/utils.d.ts +0 -1
  60. package/dist/core/compaction/utils.js +0 -1
  61. package/dist/core/defaults.d.ts +0 -1
  62. package/dist/core/defaults.js +0 -1
  63. package/dist/core/diagnostics.d.ts +0 -1
  64. package/dist/core/diagnostics.js +0 -1
  65. package/dist/core/event-bus.d.ts +0 -1
  66. package/dist/core/event-bus.js +0 -1
  67. package/dist/core/exec.d.ts +0 -1
  68. package/dist/core/exec.js +0 -1
  69. package/dist/core/experimental.d.ts +0 -1
  70. package/dist/core/experimental.js +0 -1
  71. package/dist/core/export-html/ansi-to-html.d.ts +0 -1
  72. package/dist/core/export-html/ansi-to-html.js +0 -1
  73. package/dist/core/export-html/index.d.ts +0 -1
  74. package/dist/core/export-html/index.js +0 -1
  75. package/dist/core/export-html/tool-renderer.d.ts +0 -1
  76. package/dist/core/export-html/tool-renderer.js +0 -1
  77. package/dist/core/extensions/index.d.ts +0 -1
  78. package/dist/core/extensions/index.js +0 -1
  79. package/dist/core/extensions/loader.d.ts +0 -1
  80. package/dist/core/extensions/loader.js +0 -1
  81. package/dist/core/extensions/runner.d.ts +0 -1
  82. package/dist/core/extensions/runner.js +0 -1
  83. package/dist/core/extensions/types.d.ts +0 -1
  84. package/dist/core/extensions/types.js +0 -1
  85. package/dist/core/extensions/wrapper.d.ts +0 -1
  86. package/dist/core/extensions/wrapper.js +0 -1
  87. package/dist/core/footer-data-provider.d.ts +0 -1
  88. package/dist/core/footer-data-provider.js +0 -1
  89. package/dist/core/git-command.d.ts +0 -1
  90. package/dist/core/git-command.js +0 -1
  91. package/dist/core/http-dispatcher.d.ts +0 -1
  92. package/dist/core/http-dispatcher.js +0 -1
  93. package/dist/core/index.d.ts +0 -1
  94. package/dist/core/index.js +0 -1
  95. package/dist/core/keybindings.d.ts +0 -1
  96. package/dist/core/keybindings.js +0 -1
  97. package/dist/core/llama/client.d.ts +0 -1
  98. package/dist/core/llama/client.js +0 -1
  99. package/dist/core/llama/huggingface.d.ts +0 -1
  100. package/dist/core/llama/huggingface.js +0 -1
  101. package/dist/core/llama/index.d.ts +0 -1
  102. package/dist/core/llama/index.js +0 -1
  103. package/dist/core/llama/provider.d.ts +0 -1
  104. package/dist/core/llama/provider.js +0 -1
  105. package/dist/core/llama/ui.d.ts +0 -1
  106. package/dist/core/llama/ui.js +0 -1
  107. package/dist/core/messages.d.ts +0 -1
  108. package/dist/core/messages.js +0 -1
  109. package/dist/core/model-config.d.ts +0 -1
  110. package/dist/core/model-config.js +0 -1
  111. package/dist/core/model-registry.d.ts +0 -1
  112. package/dist/core/model-registry.js +0 -1
  113. package/dist/core/model-resolver.d.ts +0 -1
  114. package/dist/core/model-resolver.js +0 -1
  115. package/dist/core/model-runtime.d.ts +0 -1
  116. package/dist/core/model-runtime.js +0 -1
  117. package/dist/core/models-store.d.ts +0 -1
  118. package/dist/core/models-store.js +0 -1
  119. package/dist/core/output-guard.d.ts +0 -1
  120. package/dist/core/output-guard.js +0 -1
  121. package/dist/core/package-manager.d.ts +0 -1
  122. package/dist/core/package-manager.js +0 -1
  123. package/dist/core/package-manager.test.d.ts +0 -1
  124. package/dist/core/package-manager.test.js +0 -1
  125. package/dist/core/project-trust.d.ts +0 -1
  126. package/dist/core/project-trust.js +0 -1
  127. package/dist/core/prompt-templates.d.ts +0 -1
  128. package/dist/core/prompt-templates.js +0 -1
  129. package/dist/core/provider-attribution.d.ts +0 -1
  130. package/dist/core/provider-attribution.js +0 -1
  131. package/dist/core/provider-composer.d.ts +0 -1
  132. package/dist/core/provider-composer.js +0 -1
  133. package/dist/core/radius.d.ts +0 -1
  134. package/dist/core/radius.js +0 -1
  135. package/dist/core/remote-catalog-provider.d.ts +0 -1
  136. package/dist/core/remote-catalog-provider.js +0 -1
  137. package/dist/core/resolve-config-value.d.ts +0 -1
  138. package/dist/core/resolve-config-value.js +0 -1
  139. package/dist/core/resource-loader.d.ts +0 -1
  140. package/dist/core/resource-loader.js +0 -1
  141. package/dist/core/runtime-credentials.d.ts +0 -1
  142. package/dist/core/runtime-credentials.js +0 -1
  143. package/dist/core/sdk.d.ts +0 -1
  144. package/dist/core/sdk.js +0 -1
  145. package/dist/core/session-cwd.d.ts +0 -1
  146. package/dist/core/session-cwd.js +0 -1
  147. package/dist/core/session-manager.d.ts +0 -1
  148. package/dist/core/session-manager.js +0 -1
  149. package/dist/core/settings-manager-auto-handoff.test.d.ts +0 -1
  150. package/dist/core/settings-manager-auto-handoff.test.js +0 -1
  151. package/dist/core/settings-manager.d.ts +0 -4
  152. package/dist/core/settings-manager.js +0 -12
  153. package/dist/core/skills.d.ts +0 -1
  154. package/dist/core/skills.js +0 -1
  155. package/dist/core/slash-commands.d.ts +0 -1
  156. package/dist/core/slash-commands.js +0 -1
  157. package/dist/core/source-info.d.ts +0 -1
  158. package/dist/core/source-info.js +0 -1
  159. package/dist/core/system-prompt.d.ts +0 -1
  160. package/dist/core/system-prompt.js +0 -1
  161. package/dist/core/system-prompt.test.d.ts +0 -1
  162. package/dist/core/system-prompt.test.js +0 -1
  163. package/dist/core/telemetry.d.ts +0 -1
  164. package/dist/core/telemetry.js +0 -1
  165. package/dist/core/timings.d.ts +0 -1
  166. package/dist/core/timings.js +0 -1
  167. package/dist/core/tools/bash.d.ts +0 -1
  168. package/dist/core/tools/bash.js +0 -1
  169. package/dist/core/tools/edit-diff.d.ts +0 -1
  170. package/dist/core/tools/edit-diff.js +0 -1
  171. package/dist/core/tools/edit.d.ts +0 -1
  172. package/dist/core/tools/edit.js +0 -1
  173. package/dist/core/tools/file-mutation-queue.d.ts +0 -1
  174. package/dist/core/tools/file-mutation-queue.js +0 -1
  175. package/dist/core/tools/find.d.ts +0 -1
  176. package/dist/core/tools/find.js +0 -1
  177. package/dist/core/tools/grep.d.ts +0 -1
  178. package/dist/core/tools/grep.js +0 -1
  179. package/dist/core/tools/index.d.ts +0 -1
  180. package/dist/core/tools/index.js +0 -1
  181. package/dist/core/tools/ls.d.ts +0 -1
  182. package/dist/core/tools/ls.js +0 -1
  183. package/dist/core/tools/output-accumulator.d.ts +0 -1
  184. package/dist/core/tools/output-accumulator.js +0 -1
  185. package/dist/core/tools/path-utils.d.ts +0 -1
  186. package/dist/core/tools/path-utils.js +0 -1
  187. package/dist/core/tools/read.d.ts +0 -1
  188. package/dist/core/tools/read.js +0 -1
  189. package/dist/core/tools/render-utils.d.ts +0 -1
  190. package/dist/core/tools/render-utils.js +0 -1
  191. package/dist/core/tools/tool-definition-wrapper.d.ts +0 -1
  192. package/dist/core/tools/tool-definition-wrapper.js +0 -1
  193. package/dist/core/tools/truncate.d.ts +0 -1
  194. package/dist/core/tools/truncate.js +0 -1
  195. package/dist/core/tools/write.d.ts +0 -1
  196. package/dist/core/tools/write.js +0 -1
  197. package/dist/core/trust-manager.d.ts +0 -1
  198. package/dist/core/trust-manager.js +0 -1
  199. package/dist/core/usage-totals.d.ts +0 -1
  200. package/dist/core/usage-totals.js +0 -1
  201. package/dist/defaults/models.json +8 -0
  202. package/dist/defaults/settings.json +6 -7
  203. package/dist/extensions/agent-browser.test.ts +195 -0
  204. package/dist/extensions/agent-browser.ts +158 -0
  205. package/dist/extensions/inline-skills.test.ts +27 -13
  206. package/dist/extensions/inline-skills.ts +18 -11
  207. package/dist/extensions/package.json +2 -1
  208. package/dist/extensions/pi-powerline-footer/.github/workflows/test.yml +27 -0
  209. package/dist/extensions/pi-powerline-footer/CHANGELOG.md +153 -0
  210. package/dist/extensions/pi-powerline-footer/CONTRIBUTING.md +16 -0
  211. package/dist/extensions/pi-powerline-footer/README.md +192 -44
  212. package/dist/extensions/pi-powerline-footer/bash-mode/completion.ts +19 -4
  213. package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +80 -25
  214. package/dist/extensions/pi-powerline-footer/bash-mode/history.ts +81 -29
  215. package/dist/extensions/pi-powerline-footer/bash-mode/types.ts +1 -1
  216. package/dist/extensions/pi-powerline-footer/cd-command.ts +190 -0
  217. package/dist/extensions/pi-powerline-footer/colors.ts +2 -1
  218. package/dist/extensions/pi-powerline-footer/context-usage.ts +121 -6
  219. package/dist/extensions/pi-powerline-footer/currency-rates.ts +142 -0
  220. package/dist/extensions/pi-powerline-footer/editor-composition.ts +32 -0
  221. package/dist/extensions/pi-powerline-footer/git-status.ts +108 -6
  222. package/dist/extensions/pi-powerline-footer/icons.ts +11 -2
  223. package/dist/extensions/pi-powerline-footer/index.ts +1056 -324
  224. package/dist/extensions/pi-powerline-footer/lifecycle.ts +10 -0
  225. package/dist/extensions/pi-powerline-footer/package.json +10 -6
  226. package/dist/extensions/pi-powerline-footer/paths.ts +22 -0
  227. package/dist/extensions/pi-powerline-footer/powerline-config.ts +297 -15
  228. package/dist/extensions/pi-powerline-footer/presets.ts +6 -25
  229. package/dist/extensions/pi-powerline-footer/queue/store.ts +361 -0
  230. package/dist/extensions/pi-powerline-footer/queue/types.ts +54 -0
  231. package/dist/extensions/pi-powerline-footer/render-scheduler.ts +12 -7
  232. package/dist/extensions/pi-powerline-footer/segments.ts +114 -107
  233. package/dist/extensions/pi-powerline-footer/session-usage.ts +1 -1
  234. package/dist/extensions/pi-powerline-footer/shortcuts.ts +17 -3
  235. package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +189 -17
  236. package/dist/extensions/pi-powerline-footer/tests/cd-command.test.ts +144 -0
  237. package/dist/extensions/pi-powerline-footer/tests/context-usage.test.ts +120 -2
  238. package/dist/extensions/pi-powerline-footer/tests/custom-items.test.ts +245 -22
  239. package/dist/extensions/pi-powerline-footer/tests/editor-composition.test.ts +48 -0
  240. package/dist/extensions/pi-powerline-footer/tests/editor-responsiveness.test.ts +34 -0
  241. package/dist/extensions/pi-powerline-footer/tests/fixed-editor-border.test.ts +39 -0
  242. package/dist/extensions/pi-powerline-footer/tests/git-status.test.ts +92 -0
  243. package/dist/extensions/pi-powerline-footer/tests/guide.test.ts +4 -1
  244. package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +33 -197
  245. package/dist/extensions/pi-powerline-footer/tests/mode-aware-trigger.test.ts +79 -0
  246. package/dist/extensions/pi-powerline-footer/tests/paths.test.ts +63 -0
  247. package/dist/extensions/pi-powerline-footer/tests/queue-store.test.ts +195 -0
  248. package/dist/extensions/pi-powerline-footer/tests/quit-cursor.test.ts +14 -0
  249. package/dist/extensions/pi-powerline-footer/tests/remaining-regressions.test.ts +167 -0
  250. package/dist/extensions/pi-powerline-footer/tests/stash-shortcut.test.ts +23 -18
  251. package/dist/extensions/pi-powerline-footer/tests/thinking-segment.test.ts +16 -1
  252. package/dist/extensions/pi-powerline-footer/tests/token-stats.test.ts +249 -0
  253. package/dist/extensions/pi-powerline-footer/tests/usage-display.test.ts +237 -0
  254. package/dist/extensions/pi-powerline-footer/tests/welcome.test.ts +199 -0
  255. package/dist/extensions/pi-powerline-footer/tests/working-vibes.test.ts +191 -100
  256. package/dist/extensions/pi-powerline-footer/theme.ts +32 -18
  257. package/dist/extensions/pi-powerline-footer/token-stats.ts +304 -0
  258. package/dist/extensions/pi-powerline-footer/tsconfig.json +13 -0
  259. package/dist/extensions/pi-powerline-footer/types.ts +74 -29
  260. package/dist/extensions/pi-powerline-footer/welcome-dismiss.ts +34 -0
  261. package/dist/extensions/pi-powerline-footer/welcome.ts +65 -10
  262. package/dist/extensions/pi-powerline-footer/working-vibes.ts +44 -11
  263. package/dist/extensions/pi-subagents/CHANGELOG.md +89 -12
  264. package/dist/extensions/pi-subagents/README.md +339 -604
  265. package/dist/extensions/pi-subagents/package-lock.json +190 -2079
  266. package/dist/extensions/pi-subagents/package.json +13 -5
  267. package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +1 -1
  268. package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +1 -1
  269. package/dist/extensions/pi-subagents/prompts/review-loop.md +1 -1
  270. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +10 -10
  271. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +32 -43
  272. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +106 -105
  273. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +3 -3
  274. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +28 -35
  275. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +167 -124
  276. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +19 -0
  277. package/dist/extensions/pi-subagents/src/agents/agents.ts +163 -75
  278. package/dist/extensions/pi-subagents/src/agents/chain-serializer.ts +10 -7
  279. package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +5 -3
  280. package/dist/extensions/pi-subagents/src/agents/identity.ts +1 -1
  281. package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +14 -11
  282. package/dist/extensions/pi-subagents/src/agents/skills.ts +23 -6
  283. package/dist/extensions/pi-subagents/src/agents/task-aware-routing.ts +8 -1
  284. package/dist/extensions/pi-subagents/src/api/control-channel.ts +4 -0
  285. package/dist/extensions/pi-subagents/src/api/delegation.ts +26 -194
  286. package/dist/extensions/pi-subagents/src/api/external-runs.ts +129 -0
  287. package/dist/extensions/pi-subagents/src/api/intercom-bridge.ts +3 -0
  288. package/dist/extensions/pi-subagents/src/api/pi-args.ts +5 -0
  289. package/dist/extensions/pi-subagents/src/api/preflight.ts +4 -4
  290. package/dist/extensions/pi-subagents/src/api/shared-types.ts +19 -0
  291. package/dist/extensions/pi-subagents/src/extension/config.ts +10 -0
  292. package/dist/extensions/pi-subagents/src/extension/control-notices.ts +5 -39
  293. package/dist/extensions/pi-subagents/src/extension/doctor.ts +10 -9
  294. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +7 -4
  295. package/dist/extensions/pi-subagents/src/extension/index.ts +243 -77
  296. package/dist/extensions/pi-subagents/src/extension/rpc.ts +18 -6
  297. package/dist/extensions/pi-subagents/src/extension/schemas.ts +50 -39
  298. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +36 -103
  299. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +229 -0
  300. package/dist/extensions/pi-subagents/src/inspectors/herdr/client.ts +130 -0
  301. package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +141 -0
  302. package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +154 -0
  303. package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +330 -0
  304. package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +3 -2
  305. package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +5 -1
  306. package/dist/extensions/pi-subagents/src/missions/actions.ts +372 -0
  307. package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +314 -0
  308. package/dist/extensions/pi-subagents/src/missions/store.ts +442 -0
  309. package/dist/extensions/pi-subagents/src/missions/types.ts +135 -0
  310. package/dist/extensions/pi-subagents/src/policy/authority.ts +46 -0
  311. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +32 -6
  312. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +103 -72
  313. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +10 -2
  314. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +6 -6
  315. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +29 -1
  316. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +3 -3
  317. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +3 -2
  318. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +9 -7
  319. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +3 -4
  320. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +3 -28
  321. package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +5 -5
  322. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +18 -68
  323. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +3 -3
  324. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +35 -8
  325. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +602 -375
  326. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -3
  327. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +612 -464
  328. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +50 -9
  329. package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +253 -0
  330. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +12 -4
  331. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +3 -3
  332. package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +8 -4
  333. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +74 -102
  334. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +21 -22
  335. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1050 -396
  336. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +44 -18
  337. package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +0 -1
  338. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +302 -22
  339. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  340. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +130 -0
  341. package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +42 -1
  342. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +1 -1
  343. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +59 -5
  344. package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +9 -4
  345. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +86 -2
  346. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +11 -2
  347. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +95 -0
  348. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +11 -1
  349. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +15 -6
  350. package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +1 -1
  351. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +9 -63
  352. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +37 -6
  353. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +5 -2
  354. package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +2 -23
  355. package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +6 -6
  356. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +124 -13
  357. package/dist/extensions/pi-subagents/src/shared/accessible-dir.ts +29 -7
  358. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +18 -1
  359. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +3 -2
  360. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +1 -0
  361. package/dist/extensions/pi-subagents/src/shared/settings.ts +10 -0
  362. package/dist/extensions/pi-subagents/src/shared/types.ts +158 -55
  363. package/dist/extensions/pi-subagents/src/shared/utils.ts +16 -66
  364. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +33 -199
  365. package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +43 -126
  366. package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +136 -0
  367. package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +158 -205
  368. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +22 -58
  369. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +14 -0
  370. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +44 -642
  371. package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +18 -14
  372. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +156 -21
  373. package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +110 -5
  374. package/dist/extensions/pi-subagents/src/tui/fleet.ts +60 -24
  375. package/dist/extensions/pi-subagents/src/tui/render.ts +296 -140
  376. package/dist/extensions/pi-subagents/src/types/pi-runtime-compat.d.ts +14 -0
  377. package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +1 -1
  378. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +13 -7
  379. package/dist/extensions/pi-subagents/src/watchdog/model-selection.ts +2 -2
  380. package/dist/extensions/pi-subagents/src/watchdog/permission-arbiter.ts +145 -0
  381. package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +1 -1
  382. package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +1 -1
  383. package/dist/extensions/pi-subagents/src/watchdog/review.ts +4 -1
  384. package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +3 -2
  385. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +140 -0
  386. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +415 -0
  387. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +41 -144
  388. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +16 -16
  389. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +415 -298
  390. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +149 -82
  391. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +40 -40
  392. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +15 -15
  393. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +193 -133
  394. package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +1 -49
  395. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +62 -0
  396. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +56 -58
  397. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +81 -68
  398. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +20 -25
  399. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +425 -317
  400. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +73 -73
  401. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +123 -98
  402. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +653 -240
  403. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +20 -1661
  404. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +9 -9
  405. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +3 -3
  406. package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +2 -2
  407. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +8 -5
  408. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +6 -6
  409. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +4 -20
  410. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +25 -4
  411. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -1
  412. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +280 -295
  413. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +47 -207
  414. package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +26 -26
  415. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +89 -89
  416. package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +9 -9
  417. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +10 -0
  418. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +33 -9
  419. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +24 -2
  420. package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +11 -9
  421. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +2 -2
  422. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +40 -40
  423. package/dist/extensions/pi-subagents/test/unit/authority-policy.test.ts +22 -0
  424. package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +1 -1
  425. package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +5 -39
  426. package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +19 -19
  427. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +9 -9
  428. package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +20 -20
  429. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +99 -0
  430. package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +9 -9
  431. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +41 -0
  432. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +2 -2
  433. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +35 -5
  434. package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +7 -0
  435. package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +16 -82
  436. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +162 -620
  437. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
  438. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +25 -25
  439. package/dist/extensions/pi-subagents/test/unit/ensure-accessible-dir.test.ts +125 -0
  440. package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +94 -0
  441. package/dist/extensions/pi-subagents/test/unit/external-runs.test.ts +66 -0
  442. package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +3 -3
  443. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +242 -52
  444. package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +127 -0
  445. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +197 -36
  446. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +4 -4
  447. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +245 -0
  448. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +494 -0
  449. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +261 -31
  450. package/dist/extensions/pi-subagents/test/unit/inline-subagents.test.ts +127 -0
  451. package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +6 -6
  452. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +217 -0
  453. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +182 -0
  454. package/dist/extensions/pi-subagents/test/unit/mock-pi.test.ts +22 -0
  455. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +1 -1
  456. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +10 -10
  457. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +20 -12
  458. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +47 -5
  459. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +49 -55
  460. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +20 -3
  461. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +37 -7
  462. package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +10 -10
  463. package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +3 -3
  464. package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +46 -0
  465. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +31 -10
  466. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +40 -16
  467. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +42 -44
  468. package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +13 -13
  469. package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +4 -4
  470. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +75 -9
  471. package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +20 -84
  472. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +15 -16
  473. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +28 -28
  474. package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +19 -12
  475. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +37 -21
  476. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +1 -1
  477. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +50 -50
  478. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +396 -433
  479. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +76 -153
  480. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +411 -0
  481. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +1 -91
  482. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +139 -0
  483. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +29 -0
  484. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +13 -13
  485. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -2
  486. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +2 -2
  487. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +35 -35
  488. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +53 -18
  489. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +13 -1
  490. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +44 -11
  491. package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +2 -26
  492. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +24 -148
  493. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +11 -9
  494. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +351 -0
  495. package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +13 -13
  496. package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +1 -1
  497. package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +79 -0
  498. package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +1 -1
  499. package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +8 -8
  500. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +45 -9
  501. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +197 -0
  502. package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +8 -8
  503. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +142 -12
  504. package/dist/extensions/pi-subagents/tsconfig.json +15 -0
  505. package/dist/extensions/ponytail/index.js +1 -31
  506. package/dist/extensions/ponytail/test/extension.test.js +5 -22
  507. package/dist/extensions/rtk.test.ts +141 -0
  508. package/dist/extensions/rtk.ts +78 -36
  509. package/dist/index.d.ts +1 -1
  510. package/dist/index.js +1 -1
  511. package/dist/main.d.ts +0 -1
  512. package/dist/main.js +0 -1
  513. package/dist/migrations.d.ts +0 -1
  514. package/dist/migrations.js +0 -1
  515. package/dist/modes/index.d.ts +0 -1
  516. package/dist/modes/index.js +0 -1
  517. package/dist/modes/interactive/components/armin.d.ts +0 -1
  518. package/dist/modes/interactive/components/armin.js +0 -1
  519. package/dist/modes/interactive/components/assistant-message.d.ts +0 -1
  520. package/dist/modes/interactive/components/assistant-message.js +0 -1
  521. package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
  522. package/dist/modes/interactive/components/bash-execution.js +0 -1
  523. package/dist/modes/interactive/components/bordered-loader.d.ts +0 -1
  524. package/dist/modes/interactive/components/bordered-loader.js +0 -1
  525. package/dist/modes/interactive/components/branch-summary-message.d.ts +0 -1
  526. package/dist/modes/interactive/components/branch-summary-message.js +0 -1
  527. package/dist/modes/interactive/components/compaction-summary-message.d.ts +0 -1
  528. package/dist/modes/interactive/components/compaction-summary-message.js +0 -1
  529. package/dist/modes/interactive/components/config-selector.d.ts +0 -1
  530. package/dist/modes/interactive/components/config-selector.js +0 -1
  531. package/dist/modes/interactive/components/countdown-timer.d.ts +0 -1
  532. package/dist/modes/interactive/components/countdown-timer.js +0 -1
  533. package/dist/modes/interactive/components/custom-editor.d.ts +0 -1
  534. package/dist/modes/interactive/components/custom-editor.js +0 -1
  535. package/dist/modes/interactive/components/custom-entry.d.ts +0 -1
  536. package/dist/modes/interactive/components/custom-entry.js +0 -1
  537. package/dist/modes/interactive/components/custom-message.d.ts +0 -1
  538. package/dist/modes/interactive/components/custom-message.js +0 -1
  539. package/dist/modes/interactive/components/daxnuts.d.ts +0 -1
  540. package/dist/modes/interactive/components/daxnuts.js +0 -1
  541. package/dist/modes/interactive/components/diff.d.ts +0 -1
  542. package/dist/modes/interactive/components/diff.js +0 -1
  543. package/dist/modes/interactive/components/dynamic-border.d.ts +0 -1
  544. package/dist/modes/interactive/components/dynamic-border.js +0 -1
  545. package/dist/modes/interactive/components/earendil-announcement.d.ts +0 -1
  546. package/dist/modes/interactive/components/earendil-announcement.js +0 -1
  547. package/dist/modes/interactive/components/extension-editor.d.ts +0 -1
  548. package/dist/modes/interactive/components/extension-editor.js +0 -1
  549. package/dist/modes/interactive/components/extension-input.d.ts +0 -1
  550. package/dist/modes/interactive/components/extension-input.js +0 -1
  551. package/dist/modes/interactive/components/extension-selector.d.ts +0 -1
  552. package/dist/modes/interactive/components/extension-selector.js +0 -1
  553. package/dist/modes/interactive/components/first-time-setup.d.ts +0 -1
  554. package/dist/modes/interactive/components/first-time-setup.js +0 -1
  555. package/dist/modes/interactive/components/footer.d.ts +0 -1
  556. package/dist/modes/interactive/components/footer.js +0 -1
  557. package/dist/modes/interactive/components/index.d.ts +0 -1
  558. package/dist/modes/interactive/components/index.js +0 -1
  559. package/dist/modes/interactive/components/keybinding-hints.d.ts +0 -1
  560. package/dist/modes/interactive/components/keybinding-hints.js +0 -1
  561. package/dist/modes/interactive/components/login-dialog.d.ts +0 -1
  562. package/dist/modes/interactive/components/login-dialog.js +0 -1
  563. package/dist/modes/interactive/components/model-selector.d.ts +0 -1
  564. package/dist/modes/interactive/components/model-selector.js +0 -1
  565. package/dist/modes/interactive/components/oauth-selector.d.ts +0 -1
  566. package/dist/modes/interactive/components/oauth-selector.js +0 -1
  567. package/dist/modes/interactive/components/scoped-models-selector.d.ts +0 -1
  568. package/dist/modes/interactive/components/scoped-models-selector.js +0 -1
  569. package/dist/modes/interactive/components/session-selector-search.d.ts +0 -1
  570. package/dist/modes/interactive/components/session-selector-search.js +0 -1
  571. package/dist/modes/interactive/components/session-selector.d.ts +0 -1
  572. package/dist/modes/interactive/components/session-selector.js +0 -1
  573. package/dist/modes/interactive/components/settings-selector.d.ts +0 -3
  574. package/dist/modes/interactive/components/settings-selector.js +1 -14
  575. package/dist/modes/interactive/components/show-images-selector.d.ts +0 -1
  576. package/dist/modes/interactive/components/show-images-selector.js +0 -1
  577. package/dist/modes/interactive/components/skill-invocation-message.d.ts +0 -1
  578. package/dist/modes/interactive/components/skill-invocation-message.js +0 -1
  579. package/dist/modes/interactive/components/status-indicator.d.ts +0 -1
  580. package/dist/modes/interactive/components/status-indicator.js +0 -1
  581. package/dist/modes/interactive/components/theme-selector.d.ts +0 -1
  582. package/dist/modes/interactive/components/theme-selector.js +0 -1
  583. package/dist/modes/interactive/components/thinking-selector.d.ts +0 -1
  584. package/dist/modes/interactive/components/thinking-selector.js +0 -1
  585. package/dist/modes/interactive/components/tool-execution.d.ts +0 -1
  586. package/dist/modes/interactive/components/tool-execution.js +0 -1
  587. package/dist/modes/interactive/components/tree-selector.d.ts +0 -1
  588. package/dist/modes/interactive/components/tree-selector.js +0 -1
  589. package/dist/modes/interactive/components/trust-selector.d.ts +0 -1
  590. package/dist/modes/interactive/components/trust-selector.js +0 -1
  591. package/dist/modes/interactive/components/user-message-selector.d.ts +0 -1
  592. package/dist/modes/interactive/components/user-message-selector.js +0 -1
  593. package/dist/modes/interactive/components/user-message.d.ts +0 -1
  594. package/dist/modes/interactive/components/user-message.js +0 -1
  595. package/dist/modes/interactive/components/visual-truncate.d.ts +0 -1
  596. package/dist/modes/interactive/components/visual-truncate.js +0 -1
  597. package/dist/modes/interactive/external-editor.d.ts +0 -1
  598. package/dist/modes/interactive/external-editor.js +0 -1
  599. package/dist/modes/interactive/interactive-mode.d.ts +0 -2
  600. package/dist/modes/interactive/interactive-mode.js +1 -22
  601. package/dist/modes/interactive/model-search.d.ts +0 -1
  602. package/dist/modes/interactive/model-search.js +0 -1
  603. package/dist/modes/interactive/theme/theme-controller.d.ts +0 -1
  604. package/dist/modes/interactive/theme/theme-controller.js +0 -1
  605. package/dist/modes/interactive/theme/theme.d.ts +0 -1
  606. package/dist/modes/interactive/theme/theme.js +0 -1
  607. package/dist/modes/print-mode.d.ts +0 -1
  608. package/dist/modes/print-mode.js +0 -1
  609. package/dist/modes/rpc/jsonl.d.ts +0 -1
  610. package/dist/modes/rpc/jsonl.js +0 -1
  611. package/dist/modes/rpc/rpc-client.d.ts +1 -2
  612. package/dist/modes/rpc/rpc-client.js +1 -2
  613. package/dist/modes/rpc/rpc-mode.d.ts +0 -1
  614. package/dist/modes/rpc/rpc-mode.js +0 -9
  615. package/dist/modes/rpc/rpc-types.d.ts +0 -1
  616. package/dist/modes/rpc/rpc-types.js +0 -1
  617. package/dist/package-manager-cli.d.ts +0 -1
  618. package/dist/package-manager-cli.js +0 -1
  619. package/dist/rpc-entry.d.ts +0 -1
  620. package/dist/rpc-entry.js +0 -1
  621. package/dist/utils/ansi.d.ts +0 -1
  622. package/dist/utils/ansi.js +0 -1
  623. package/dist/utils/changelog.d.ts +0 -1
  624. package/dist/utils/changelog.js +0 -1
  625. package/dist/utils/child-process.d.ts +0 -1
  626. package/dist/utils/child-process.js +0 -1
  627. package/dist/utils/clipboard-image.d.ts +0 -1
  628. package/dist/utils/clipboard-image.js +0 -1
  629. package/dist/utils/clipboard-native.d.ts +0 -1
  630. package/dist/utils/clipboard-native.js +0 -1
  631. package/dist/utils/clipboard.d.ts +0 -1
  632. package/dist/utils/clipboard.js +0 -1
  633. package/dist/utils/deprecation.d.ts +0 -1
  634. package/dist/utils/deprecation.js +0 -1
  635. package/dist/utils/exif-orientation.d.ts +0 -1
  636. package/dist/utils/exif-orientation.js +0 -1
  637. package/dist/utils/frontmatter.d.ts +0 -1
  638. package/dist/utils/frontmatter.js +0 -1
  639. package/dist/utils/fs-watch.d.ts +0 -1
  640. package/dist/utils/fs-watch.js +0 -1
  641. package/dist/utils/git.d.ts +0 -1
  642. package/dist/utils/git.js +0 -1
  643. package/dist/utils/html.d.ts +0 -1
  644. package/dist/utils/html.js +0 -1
  645. package/dist/utils/image-convert.d.ts +0 -1
  646. package/dist/utils/image-convert.js +0 -1
  647. package/dist/utils/image-process.d.ts +0 -1
  648. package/dist/utils/image-process.js +0 -1
  649. package/dist/utils/image-resize-core.d.ts +0 -1
  650. package/dist/utils/image-resize-core.js +0 -1
  651. package/dist/utils/image-resize-worker.d.ts +0 -1
  652. package/dist/utils/image-resize-worker.js +0 -1
  653. package/dist/utils/image-resize.d.ts +0 -1
  654. package/dist/utils/image-resize.js +0 -1
  655. package/dist/utils/json.d.ts +0 -1
  656. package/dist/utils/json.js +0 -1
  657. package/dist/utils/mime.d.ts +0 -1
  658. package/dist/utils/mime.js +0 -1
  659. package/dist/utils/open-browser.d.ts +0 -1
  660. package/dist/utils/open-browser.js +0 -1
  661. package/dist/utils/paths.d.ts +0 -1
  662. package/dist/utils/paths.js +0 -1
  663. package/dist/utils/photon.d.ts +0 -1
  664. package/dist/utils/photon.js +0 -1
  665. package/dist/utils/pi-user-agent.d.ts +0 -1
  666. package/dist/utils/pi-user-agent.js +0 -1
  667. package/dist/utils/shell.d.ts +0 -1
  668. package/dist/utils/shell.js +0 -1
  669. package/dist/utils/sleep.d.ts +0 -1
  670. package/dist/utils/sleep.js +0 -1
  671. package/dist/utils/syntax-highlight.d.ts +0 -1
  672. package/dist/utils/syntax-highlight.js +0 -1
  673. package/dist/utils/thinking-tags.d.ts +0 -1
  674. package/dist/utils/thinking-tags.js +0 -1
  675. package/dist/utils/tools-manager.d.ts +3 -3
  676. package/dist/utils/tools-manager.js +125 -42
  677. package/dist/utils/version-check.d.ts +0 -1
  678. package/dist/utils/version-check.js +0 -1
  679. package/dist/utils/windows-self-update.d.ts +0 -1
  680. package/dist/utils/windows-self-update.js +0 -1
  681. package/docs/rpc.md +1 -2
  682. package/docs/settings.md +0 -1
  683. package/docs/skills.md +10 -18
  684. package/package.json +3 -2
  685. package/dist/bun/cli.d.ts.map +0 -1
  686. package/dist/bun/cli.js.map +0 -1
  687. package/dist/bun/register-bedrock.d.ts.map +0 -1
  688. package/dist/bun/register-bedrock.js.map +0 -1
  689. package/dist/bun/restore-sandbox-env.d.ts.map +0 -1
  690. package/dist/bun/restore-sandbox-env.js.map +0 -1
  691. package/dist/cli/args.d.ts.map +0 -1
  692. package/dist/cli/args.js.map +0 -1
  693. package/dist/cli/config-selector.d.ts.map +0 -1
  694. package/dist/cli/config-selector.js.map +0 -1
  695. package/dist/cli/credential-print.d.ts.map +0 -1
  696. package/dist/cli/credential-print.js.map +0 -1
  697. package/dist/cli/file-processor.d.ts.map +0 -1
  698. package/dist/cli/file-processor.js.map +0 -1
  699. package/dist/cli/initial-message.d.ts.map +0 -1
  700. package/dist/cli/initial-message.js.map +0 -1
  701. package/dist/cli/list-models.d.ts.map +0 -1
  702. package/dist/cli/list-models.js.map +0 -1
  703. package/dist/cli/project-trust.d.ts.map +0 -1
  704. package/dist/cli/project-trust.js.map +0 -1
  705. package/dist/cli/session-picker.d.ts.map +0 -1
  706. package/dist/cli/session-picker.js.map +0 -1
  707. package/dist/cli/startup-ui.d.ts.map +0 -1
  708. package/dist/cli/startup-ui.js.map +0 -1
  709. package/dist/cli.d.ts.map +0 -1
  710. package/dist/cli.js.map +0 -1
  711. package/dist/config.d.ts.map +0 -1
  712. package/dist/config.js.map +0 -1
  713. package/dist/core/agent-session-auto-handoff.test.d.ts.map +0 -1
  714. package/dist/core/agent-session-auto-handoff.test.js.map +0 -1
  715. package/dist/core/agent-session-runtime.d.ts.map +0 -1
  716. package/dist/core/agent-session-runtime.js.map +0 -1
  717. package/dist/core/agent-session-services.d.ts.map +0 -1
  718. package/dist/core/agent-session-services.js.map +0 -1
  719. package/dist/core/agent-session-skill-block.test.d.ts.map +0 -1
  720. package/dist/core/agent-session-skill-block.test.js.map +0 -1
  721. package/dist/core/agent-session.d.ts.map +0 -1
  722. package/dist/core/agent-session.js.map +0 -1
  723. package/dist/core/agents.d.ts.map +0 -1
  724. package/dist/core/agents.js.map +0 -1
  725. package/dist/core/auth-guidance.d.ts.map +0 -1
  726. package/dist/core/auth-guidance.js.map +0 -1
  727. package/dist/core/auth-storage.d.ts.map +0 -1
  728. package/dist/core/auth-storage.js.map +0 -1
  729. package/dist/core/bash-executor.d.ts.map +0 -1
  730. package/dist/core/bash-executor.js.map +0 -1
  731. package/dist/core/built-in-extensions.d.ts.map +0 -1
  732. package/dist/core/built-in-extensions.js.map +0 -1
  733. package/dist/core/cache-stats.d.ts.map +0 -1
  734. package/dist/core/cache-stats.js.map +0 -1
  735. package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
  736. package/dist/core/compaction/branch-summarization.js.map +0 -1
  737. package/dist/core/compaction/compaction.d.ts.map +0 -1
  738. package/dist/core/compaction/compaction.js.map +0 -1
  739. package/dist/core/compaction/index.d.ts.map +0 -1
  740. package/dist/core/compaction/index.js.map +0 -1
  741. package/dist/core/compaction/utils.d.ts.map +0 -1
  742. package/dist/core/compaction/utils.js.map +0 -1
  743. package/dist/core/defaults.d.ts.map +0 -1
  744. package/dist/core/defaults.js.map +0 -1
  745. package/dist/core/diagnostics.d.ts.map +0 -1
  746. package/dist/core/diagnostics.js.map +0 -1
  747. package/dist/core/event-bus.d.ts.map +0 -1
  748. package/dist/core/event-bus.js.map +0 -1
  749. package/dist/core/exec.d.ts.map +0 -1
  750. package/dist/core/exec.js.map +0 -1
  751. package/dist/core/experimental.d.ts.map +0 -1
  752. package/dist/core/experimental.js.map +0 -1
  753. package/dist/core/export-html/ansi-to-html.d.ts.map +0 -1
  754. package/dist/core/export-html/ansi-to-html.js.map +0 -1
  755. package/dist/core/export-html/index.d.ts.map +0 -1
  756. package/dist/core/export-html/index.js.map +0 -1
  757. package/dist/core/export-html/tool-renderer.d.ts.map +0 -1
  758. package/dist/core/export-html/tool-renderer.js.map +0 -1
  759. package/dist/core/extensions/index.d.ts.map +0 -1
  760. package/dist/core/extensions/index.js.map +0 -1
  761. package/dist/core/extensions/loader.d.ts.map +0 -1
  762. package/dist/core/extensions/loader.js.map +0 -1
  763. package/dist/core/extensions/runner.d.ts.map +0 -1
  764. package/dist/core/extensions/runner.js.map +0 -1
  765. package/dist/core/extensions/types.d.ts.map +0 -1
  766. package/dist/core/extensions/types.js.map +0 -1
  767. package/dist/core/extensions/wrapper.d.ts.map +0 -1
  768. package/dist/core/extensions/wrapper.js.map +0 -1
  769. package/dist/core/footer-data-provider.d.ts.map +0 -1
  770. package/dist/core/footer-data-provider.js.map +0 -1
  771. package/dist/core/git-command.d.ts.map +0 -1
  772. package/dist/core/git-command.js.map +0 -1
  773. package/dist/core/http-dispatcher.d.ts.map +0 -1
  774. package/dist/core/http-dispatcher.js.map +0 -1
  775. package/dist/core/index.d.ts.map +0 -1
  776. package/dist/core/index.js.map +0 -1
  777. package/dist/core/keybindings.d.ts.map +0 -1
  778. package/dist/core/keybindings.js.map +0 -1
  779. package/dist/core/llama/client.d.ts.map +0 -1
  780. package/dist/core/llama/client.js.map +0 -1
  781. package/dist/core/llama/huggingface.d.ts.map +0 -1
  782. package/dist/core/llama/huggingface.js.map +0 -1
  783. package/dist/core/llama/index.d.ts.map +0 -1
  784. package/dist/core/llama/index.js.map +0 -1
  785. package/dist/core/llama/provider.d.ts.map +0 -1
  786. package/dist/core/llama/provider.js.map +0 -1
  787. package/dist/core/llama/ui.d.ts.map +0 -1
  788. package/dist/core/llama/ui.js.map +0 -1
  789. package/dist/core/messages.d.ts.map +0 -1
  790. package/dist/core/messages.js.map +0 -1
  791. package/dist/core/model-config.d.ts.map +0 -1
  792. package/dist/core/model-config.js.map +0 -1
  793. package/dist/core/model-registry.d.ts.map +0 -1
  794. package/dist/core/model-registry.js.map +0 -1
  795. package/dist/core/model-resolver.d.ts.map +0 -1
  796. package/dist/core/model-resolver.js.map +0 -1
  797. package/dist/core/model-runtime.d.ts.map +0 -1
  798. package/dist/core/model-runtime.js.map +0 -1
  799. package/dist/core/models-store.d.ts.map +0 -1
  800. package/dist/core/models-store.js.map +0 -1
  801. package/dist/core/output-guard.d.ts.map +0 -1
  802. package/dist/core/output-guard.js.map +0 -1
  803. package/dist/core/package-manager.d.ts.map +0 -1
  804. package/dist/core/package-manager.js.map +0 -1
  805. package/dist/core/package-manager.test.d.ts.map +0 -1
  806. package/dist/core/package-manager.test.js.map +0 -1
  807. package/dist/core/project-trust.d.ts.map +0 -1
  808. package/dist/core/project-trust.js.map +0 -1
  809. package/dist/core/prompt-templates.d.ts.map +0 -1
  810. package/dist/core/prompt-templates.js.map +0 -1
  811. package/dist/core/provider-attribution.d.ts.map +0 -1
  812. package/dist/core/provider-attribution.js.map +0 -1
  813. package/dist/core/provider-composer.d.ts.map +0 -1
  814. package/dist/core/provider-composer.js.map +0 -1
  815. package/dist/core/radius.d.ts.map +0 -1
  816. package/dist/core/radius.js.map +0 -1
  817. package/dist/core/remote-catalog-provider.d.ts.map +0 -1
  818. package/dist/core/remote-catalog-provider.js.map +0 -1
  819. package/dist/core/resolve-config-value.d.ts.map +0 -1
  820. package/dist/core/resolve-config-value.js.map +0 -1
  821. package/dist/core/resource-loader.d.ts.map +0 -1
  822. package/dist/core/resource-loader.js.map +0 -1
  823. package/dist/core/runtime-credentials.d.ts.map +0 -1
  824. package/dist/core/runtime-credentials.js.map +0 -1
  825. package/dist/core/sdk.d.ts.map +0 -1
  826. package/dist/core/sdk.js.map +0 -1
  827. package/dist/core/session-cwd.d.ts.map +0 -1
  828. package/dist/core/session-cwd.js.map +0 -1
  829. package/dist/core/session-manager.d.ts.map +0 -1
  830. package/dist/core/session-manager.js.map +0 -1
  831. package/dist/core/settings-manager-auto-handoff.test.d.ts.map +0 -1
  832. package/dist/core/settings-manager-auto-handoff.test.js.map +0 -1
  833. package/dist/core/settings-manager.d.ts.map +0 -1
  834. package/dist/core/settings-manager.js.map +0 -1
  835. package/dist/core/skills.d.ts.map +0 -1
  836. package/dist/core/skills.js.map +0 -1
  837. package/dist/core/slash-commands.d.ts.map +0 -1
  838. package/dist/core/slash-commands.js.map +0 -1
  839. package/dist/core/source-info.d.ts.map +0 -1
  840. package/dist/core/source-info.js.map +0 -1
  841. package/dist/core/system-prompt.d.ts.map +0 -1
  842. package/dist/core/system-prompt.js.map +0 -1
  843. package/dist/core/system-prompt.test.d.ts.map +0 -1
  844. package/dist/core/system-prompt.test.js.map +0 -1
  845. package/dist/core/telemetry.d.ts.map +0 -1
  846. package/dist/core/telemetry.js.map +0 -1
  847. package/dist/core/timings.d.ts.map +0 -1
  848. package/dist/core/timings.js.map +0 -1
  849. package/dist/core/tools/bash.d.ts.map +0 -1
  850. package/dist/core/tools/bash.js.map +0 -1
  851. package/dist/core/tools/edit-diff.d.ts.map +0 -1
  852. package/dist/core/tools/edit-diff.js.map +0 -1
  853. package/dist/core/tools/edit.d.ts.map +0 -1
  854. package/dist/core/tools/edit.js.map +0 -1
  855. package/dist/core/tools/file-mutation-queue.d.ts.map +0 -1
  856. package/dist/core/tools/file-mutation-queue.js.map +0 -1
  857. package/dist/core/tools/find.d.ts.map +0 -1
  858. package/dist/core/tools/find.js.map +0 -1
  859. package/dist/core/tools/grep.d.ts.map +0 -1
  860. package/dist/core/tools/grep.js.map +0 -1
  861. package/dist/core/tools/index.d.ts.map +0 -1
  862. package/dist/core/tools/index.js.map +0 -1
  863. package/dist/core/tools/ls.d.ts.map +0 -1
  864. package/dist/core/tools/ls.js.map +0 -1
  865. package/dist/core/tools/output-accumulator.d.ts.map +0 -1
  866. package/dist/core/tools/output-accumulator.js.map +0 -1
  867. package/dist/core/tools/path-utils.d.ts.map +0 -1
  868. package/dist/core/tools/path-utils.js.map +0 -1
  869. package/dist/core/tools/read.d.ts.map +0 -1
  870. package/dist/core/tools/read.js.map +0 -1
  871. package/dist/core/tools/render-utils.d.ts.map +0 -1
  872. package/dist/core/tools/render-utils.js.map +0 -1
  873. package/dist/core/tools/tool-definition-wrapper.d.ts.map +0 -1
  874. package/dist/core/tools/tool-definition-wrapper.js.map +0 -1
  875. package/dist/core/tools/truncate.d.ts.map +0 -1
  876. package/dist/core/tools/truncate.js.map +0 -1
  877. package/dist/core/tools/write.d.ts.map +0 -1
  878. package/dist/core/tools/write.js.map +0 -1
  879. package/dist/core/trust-manager.d.ts.map +0 -1
  880. package/dist/core/trust-manager.js.map +0 -1
  881. package/dist/core/usage-totals.d.ts.map +0 -1
  882. package/dist/core/usage-totals.js.map +0 -1
  883. package/dist/extensions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  884. package/dist/extensions/pi-subagents/test/unit/slash-chain-groups.test.ts +0 -464
  885. package/dist/index.d.ts.map +0 -1
  886. package/dist/index.js.map +0 -1
  887. package/dist/main.d.ts.map +0 -1
  888. package/dist/main.js.map +0 -1
  889. package/dist/migrations.d.ts.map +0 -1
  890. package/dist/migrations.js.map +0 -1
  891. package/dist/modes/index.d.ts.map +0 -1
  892. package/dist/modes/index.js.map +0 -1
  893. package/dist/modes/interactive/components/armin.d.ts.map +0 -1
  894. package/dist/modes/interactive/components/armin.js.map +0 -1
  895. package/dist/modes/interactive/components/assistant-message.d.ts.map +0 -1
  896. package/dist/modes/interactive/components/assistant-message.js.map +0 -1
  897. package/dist/modes/interactive/components/bash-execution.d.ts.map +0 -1
  898. package/dist/modes/interactive/components/bash-execution.js.map +0 -1
  899. package/dist/modes/interactive/components/bordered-loader.d.ts.map +0 -1
  900. package/dist/modes/interactive/components/bordered-loader.js.map +0 -1
  901. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +0 -1
  902. package/dist/modes/interactive/components/branch-summary-message.js.map +0 -1
  903. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +0 -1
  904. package/dist/modes/interactive/components/compaction-summary-message.js.map +0 -1
  905. package/dist/modes/interactive/components/config-selector.d.ts.map +0 -1
  906. package/dist/modes/interactive/components/config-selector.js.map +0 -1
  907. package/dist/modes/interactive/components/countdown-timer.d.ts.map +0 -1
  908. package/dist/modes/interactive/components/countdown-timer.js.map +0 -1
  909. package/dist/modes/interactive/components/custom-editor.d.ts.map +0 -1
  910. package/dist/modes/interactive/components/custom-editor.js.map +0 -1
  911. package/dist/modes/interactive/components/custom-entry.d.ts.map +0 -1
  912. package/dist/modes/interactive/components/custom-entry.js.map +0 -1
  913. package/dist/modes/interactive/components/custom-message.d.ts.map +0 -1
  914. package/dist/modes/interactive/components/custom-message.js.map +0 -1
  915. package/dist/modes/interactive/components/daxnuts.d.ts.map +0 -1
  916. package/dist/modes/interactive/components/daxnuts.js.map +0 -1
  917. package/dist/modes/interactive/components/diff.d.ts.map +0 -1
  918. package/dist/modes/interactive/components/diff.js.map +0 -1
  919. package/dist/modes/interactive/components/dynamic-border.d.ts.map +0 -1
  920. package/dist/modes/interactive/components/dynamic-border.js.map +0 -1
  921. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +0 -1
  922. package/dist/modes/interactive/components/earendil-announcement.js.map +0 -1
  923. package/dist/modes/interactive/components/extension-editor.d.ts.map +0 -1
  924. package/dist/modes/interactive/components/extension-editor.js.map +0 -1
  925. package/dist/modes/interactive/components/extension-input.d.ts.map +0 -1
  926. package/dist/modes/interactive/components/extension-input.js.map +0 -1
  927. package/dist/modes/interactive/components/extension-selector.d.ts.map +0 -1
  928. package/dist/modes/interactive/components/extension-selector.js.map +0 -1
  929. package/dist/modes/interactive/components/first-time-setup.d.ts.map +0 -1
  930. package/dist/modes/interactive/components/first-time-setup.js.map +0 -1
  931. package/dist/modes/interactive/components/footer.d.ts.map +0 -1
  932. package/dist/modes/interactive/components/footer.js.map +0 -1
  933. package/dist/modes/interactive/components/index.d.ts.map +0 -1
  934. package/dist/modes/interactive/components/index.js.map +0 -1
  935. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +0 -1
  936. package/dist/modes/interactive/components/keybinding-hints.js.map +0 -1
  937. package/dist/modes/interactive/components/login-dialog.d.ts.map +0 -1
  938. package/dist/modes/interactive/components/login-dialog.js.map +0 -1
  939. package/dist/modes/interactive/components/model-selector.d.ts.map +0 -1
  940. package/dist/modes/interactive/components/model-selector.js.map +0 -1
  941. package/dist/modes/interactive/components/oauth-selector.d.ts.map +0 -1
  942. package/dist/modes/interactive/components/oauth-selector.js.map +0 -1
  943. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +0 -1
  944. package/dist/modes/interactive/components/scoped-models-selector.js.map +0 -1
  945. package/dist/modes/interactive/components/session-selector-search.d.ts.map +0 -1
  946. package/dist/modes/interactive/components/session-selector-search.js.map +0 -1
  947. package/dist/modes/interactive/components/session-selector.d.ts.map +0 -1
  948. package/dist/modes/interactive/components/session-selector.js.map +0 -1
  949. package/dist/modes/interactive/components/settings-selector.d.ts.map +0 -1
  950. package/dist/modes/interactive/components/settings-selector.js.map +0 -1
  951. package/dist/modes/interactive/components/show-images-selector.d.ts.map +0 -1
  952. package/dist/modes/interactive/components/show-images-selector.js.map +0 -1
  953. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +0 -1
  954. package/dist/modes/interactive/components/skill-invocation-message.js.map +0 -1
  955. package/dist/modes/interactive/components/status-indicator.d.ts.map +0 -1
  956. package/dist/modes/interactive/components/status-indicator.js.map +0 -1
  957. package/dist/modes/interactive/components/theme-selector.d.ts.map +0 -1
  958. package/dist/modes/interactive/components/theme-selector.js.map +0 -1
  959. package/dist/modes/interactive/components/thinking-selector.d.ts.map +0 -1
  960. package/dist/modes/interactive/components/thinking-selector.js.map +0 -1
  961. package/dist/modes/interactive/components/tool-execution.d.ts.map +0 -1
  962. package/dist/modes/interactive/components/tool-execution.js.map +0 -1
  963. package/dist/modes/interactive/components/tree-selector.d.ts.map +0 -1
  964. package/dist/modes/interactive/components/tree-selector.js.map +0 -1
  965. package/dist/modes/interactive/components/trust-selector.d.ts.map +0 -1
  966. package/dist/modes/interactive/components/trust-selector.js.map +0 -1
  967. package/dist/modes/interactive/components/user-message-selector.d.ts.map +0 -1
  968. package/dist/modes/interactive/components/user-message-selector.js.map +0 -1
  969. package/dist/modes/interactive/components/user-message.d.ts.map +0 -1
  970. package/dist/modes/interactive/components/user-message.js.map +0 -1
  971. package/dist/modes/interactive/components/visual-truncate.d.ts.map +0 -1
  972. package/dist/modes/interactive/components/visual-truncate.js.map +0 -1
  973. package/dist/modes/interactive/external-editor.d.ts.map +0 -1
  974. package/dist/modes/interactive/external-editor.js.map +0 -1
  975. package/dist/modes/interactive/interactive-mode.d.ts.map +0 -1
  976. package/dist/modes/interactive/interactive-mode.js.map +0 -1
  977. package/dist/modes/interactive/model-search.d.ts.map +0 -1
  978. package/dist/modes/interactive/model-search.js.map +0 -1
  979. package/dist/modes/interactive/theme/theme-controller.d.ts.map +0 -1
  980. package/dist/modes/interactive/theme/theme-controller.js.map +0 -1
  981. package/dist/modes/interactive/theme/theme.d.ts.map +0 -1
  982. package/dist/modes/interactive/theme/theme.js.map +0 -1
  983. package/dist/modes/print-mode.d.ts.map +0 -1
  984. package/dist/modes/print-mode.js.map +0 -1
  985. package/dist/modes/rpc/jsonl.d.ts.map +0 -1
  986. package/dist/modes/rpc/jsonl.js.map +0 -1
  987. package/dist/modes/rpc/rpc-client.d.ts.map +0 -1
  988. package/dist/modes/rpc/rpc-client.js.map +0 -1
  989. package/dist/modes/rpc/rpc-mode.d.ts.map +0 -1
  990. package/dist/modes/rpc/rpc-mode.js.map +0 -1
  991. package/dist/modes/rpc/rpc-types.d.ts.map +0 -1
  992. package/dist/modes/rpc/rpc-types.js.map +0 -1
  993. package/dist/package-manager-cli.d.ts.map +0 -1
  994. package/dist/package-manager-cli.js.map +0 -1
  995. package/dist/rpc-entry.d.ts.map +0 -1
  996. package/dist/rpc-entry.js.map +0 -1
  997. package/dist/utils/ansi.d.ts.map +0 -1
  998. package/dist/utils/ansi.js.map +0 -1
  999. package/dist/utils/changelog.d.ts.map +0 -1
  1000. package/dist/utils/changelog.js.map +0 -1
  1001. package/dist/utils/child-process.d.ts.map +0 -1
  1002. package/dist/utils/child-process.js.map +0 -1
  1003. package/dist/utils/clipboard-image.d.ts.map +0 -1
  1004. package/dist/utils/clipboard-image.js.map +0 -1
  1005. package/dist/utils/clipboard-native.d.ts.map +0 -1
  1006. package/dist/utils/clipboard-native.js.map +0 -1
  1007. package/dist/utils/clipboard.d.ts.map +0 -1
  1008. package/dist/utils/clipboard.js.map +0 -1
  1009. package/dist/utils/deprecation.d.ts.map +0 -1
  1010. package/dist/utils/deprecation.js.map +0 -1
  1011. package/dist/utils/exif-orientation.d.ts.map +0 -1
  1012. package/dist/utils/exif-orientation.js.map +0 -1
  1013. package/dist/utils/frontmatter.d.ts.map +0 -1
  1014. package/dist/utils/frontmatter.js.map +0 -1
  1015. package/dist/utils/fs-watch.d.ts.map +0 -1
  1016. package/dist/utils/fs-watch.js.map +0 -1
  1017. package/dist/utils/git.d.ts.map +0 -1
  1018. package/dist/utils/git.js.map +0 -1
  1019. package/dist/utils/html.d.ts.map +0 -1
  1020. package/dist/utils/html.js.map +0 -1
  1021. package/dist/utils/image-convert.d.ts.map +0 -1
  1022. package/dist/utils/image-convert.js.map +0 -1
  1023. package/dist/utils/image-process.d.ts.map +0 -1
  1024. package/dist/utils/image-process.js.map +0 -1
  1025. package/dist/utils/image-resize-core.d.ts.map +0 -1
  1026. package/dist/utils/image-resize-core.js.map +0 -1
  1027. package/dist/utils/image-resize-worker.d.ts.map +0 -1
  1028. package/dist/utils/image-resize-worker.js.map +0 -1
  1029. package/dist/utils/image-resize.d.ts.map +0 -1
  1030. package/dist/utils/image-resize.js.map +0 -1
  1031. package/dist/utils/json.d.ts.map +0 -1
  1032. package/dist/utils/json.js.map +0 -1
  1033. package/dist/utils/mime.d.ts.map +0 -1
  1034. package/dist/utils/mime.js.map +0 -1
  1035. package/dist/utils/open-browser.d.ts.map +0 -1
  1036. package/dist/utils/open-browser.js.map +0 -1
  1037. package/dist/utils/paths.d.ts.map +0 -1
  1038. package/dist/utils/paths.js.map +0 -1
  1039. package/dist/utils/photon.d.ts.map +0 -1
  1040. package/dist/utils/photon.js.map +0 -1
  1041. package/dist/utils/pi-user-agent.d.ts.map +0 -1
  1042. package/dist/utils/pi-user-agent.js.map +0 -1
  1043. package/dist/utils/shell.d.ts.map +0 -1
  1044. package/dist/utils/shell.js.map +0 -1
  1045. package/dist/utils/sleep.d.ts.map +0 -1
  1046. package/dist/utils/sleep.js.map +0 -1
  1047. package/dist/utils/syntax-highlight.d.ts.map +0 -1
  1048. package/dist/utils/syntax-highlight.js.map +0 -1
  1049. package/dist/utils/thinking-tags.d.ts.map +0 -1
  1050. package/dist/utils/thinking-tags.js.map +0 -1
  1051. package/dist/utils/tools-manager.d.ts.map +0 -1
  1052. package/dist/utils/tools-manager.js.map +0 -1
  1053. package/dist/utils/version-check.d.ts.map +0 -1
  1054. package/dist/utils/version-check.js.map +0 -1
  1055. package/dist/utils/windows-self-update.d.ts.map +0 -1
  1056. package/dist/utils/windows-self-update.js.map +0 -1
@@ -364,7 +364,7 @@ describe("subagents watchdog slash command", { skip: !available ? "watchdog comm
364
364
  fs.writeFileSync(settingsPath, JSON.stringify({
365
365
  other: true,
366
366
  subagents: {
367
- agentOverrides: { scout: { model: "openai/test" } },
367
+ agentOverrides: { explorer: { model: "openai/test" } },
368
368
  watchdog: { agentEndTimeoutMs: 1234, main: { enabled: false, model: "openai/watchdog" } },
369
369
  },
370
370
  }, null, 2), "utf-8");
@@ -375,7 +375,7 @@ describe("subagents watchdog slash command", { skip: !available ? "watchdog comm
375
375
  await commands.get("subagents-watchdog")!.handler("on", createCommandContext({ cwd: root }));
376
376
  let settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
377
377
  assert.equal(settings.other, true);
378
- assert.equal(settings.subagents.agentOverrides.scout.model, "openai/test");
378
+ assert.equal(settings.subagents.agentOverrides.explorer.model, "openai/test");
379
379
  assert.equal(settings.subagents.watchdog.agentEndTimeoutMs, 1234);
380
380
  assert.equal(settings.subagents.watchdog.enabled, true);
381
381
  assert.equal(settings.subagents.watchdog.main.enabled, true);
@@ -678,1685 +678,44 @@ describe("slash command custom message delivery", { skip: !available ? "slash-co
678
678
  assert.equal((visibleSnapshot.result.content[0] as { text?: string }).text, "Subagent failed");
679
679
  });
680
680
 
681
- it("/parallel forwards inline output behavior config", async () => {
682
- const commands = new Map<string, { handler(args: string, ctx: unknown): Promise<void> }>();
683
- const events = createEventBus();
684
- let requestedParams: unknown;
685
- events.on(SLASH_SUBAGENT_REQUEST_EVENT, (data) => {
686
- const payload = data as { requestId: string; params?: unknown };
687
- requestedParams = payload.params;
688
- events.emit(SLASH_SUBAGENT_STARTED_EVENT, { requestId: payload.requestId });
689
- events.emit(SLASH_SUBAGENT_RESPONSE_EVENT, {
690
- requestId: payload.requestId,
691
- result: {
692
- content: [{ type: "text", text: "parallel finished" }],
693
- details: { mode: "parallel", results: [] },
694
- },
695
- isError: false,
696
- });
697
- });
698
-
699
- const pi = {
700
- events,
701
- registerCommand(name: string, spec: { handler(args: string, ctx: unknown): Promise<void> }) {
702
- commands.set(name, spec);
703
- },
704
- registerShortcut() {},
705
- sendMessage(_message: unknown) {},
706
- };
707
-
708
- registerSlashCommands!(pi, createState(process.cwd()));
709
- await commands.get("parallel")!.handler("explorer[output=x.md,outputMode=file-only,reads=a.md+b.md,progress] -- Review", createCommandContext());
710
-
711
- assert.deepEqual(requestedParams, {
712
- tasks: [{ agent: "explorer", task: "Review", output: "x.md", outputMode: "file-only", reads: ["a.md", "b.md"], progress: true }],
713
- clarify: false,
714
- agentScope: "both",
715
- });
716
- });
717
-
718
- it("/parallel no longer hard-blocks runs above the old 8-task limit before the executor responds", async () => {
719
- const sent: unknown[] = [];
720
- const commands = new Map<string, { handler(args: string, ctx: unknown): Promise<void> }>();
721
- const events = createEventBus();
722
- let requestedTasks = 0;
723
- events.on(SLASH_SUBAGENT_REQUEST_EVENT, (data) => {
724
- const payload = data as { requestId: string; params?: { tasks?: unknown[] } };
725
- requestedTasks = payload.params?.tasks?.length ?? 0;
726
- events.emit(SLASH_SUBAGENT_STARTED_EVENT, { requestId: payload.requestId });
727
- events.emit(SLASH_SUBAGENT_RESPONSE_EVENT, {
728
- requestId: payload.requestId,
729
- result: {
730
- content: [{ type: "text", text: "parallel finished" }],
731
- details: { mode: "parallel", results: [] },
732
- },
733
- isError: false,
734
- });
735
- });
736
-
737
- const pi = {
738
- events,
739
- registerCommand(name: string, spec: { handler(args: string, ctx: unknown): Promise<void> }) {
740
- commands.set(name, spec);
741
- },
742
- registerShortcut() {},
743
- sendMessage(message: unknown) {
744
- sent.push(message);
745
- },
746
- };
747
-
748
- registerSlashCommands!(pi, createState(process.cwd()));
749
- const args = Array.from({ length: 9 }, (_, index) => `explorer \"task ${index + 1}\"`).join(" -> ");
750
- await commands.get("parallel")!.handler(args, createCommandContext());
751
- await new Promise<void>((resolve) => setImmediate(resolve));
752
-
753
- assert.equal(requestedTasks, 9);
754
- assert.equal(sent.length, 2);
755
- assert.match((sent[1] as { content?: string }).content ?? "", /parallel finished/);
756
- });
757
- });
758
-
759
- describe("saved chain slash command", { skip: !available ? "slash-commands.ts not importable" : undefined }, () => {
760
- beforeEach(() => {
761
- clearSlashSnapshots?.();
762
- });
763
-
764
- it("/run and /chain accept dotted packaged runtime agent names", async () => {
681
+ it("/run accepts dotted packaged runtime agent names", async () => {
765
682
  await withTempProject("pi-packaged-agent-slash-", async (root) => {
766
- fs.writeFileSync(path.join(root, ".selesai", "agents", "code-analysis.scout.md"), `---
767
- name: scout
683
+ fs.writeFileSync(path.join(root, ".selesai", "agents", "code-analysis.explorer.md"), `---
684
+ name: explorer
768
685
  package: code-analysis
769
686
  description: Fast recon
770
687
  ---
771
688
 
772
689
  Inspect
773
690
  `, "utf-8");
774
- fs.writeFileSync(path.join(root, ".selesai", "agents", "documentation.writer.md"), `---
775
- name: writer
776
- package: documentation
777
- description: Writer
778
- ---
779
-
780
- Write
781
- `, "utf-8");
782
-
783
- const run = await captureSlashCommandParams("run", "code-analysis.scout Investigate", root);
784
- assert.deepEqual(run.params, { agent: "code-analysis.scout", task: "Investigate", clarify: false, agentScope: "both" });
785
-
786
- const chain = await captureSlashCommandParams("chain", "code-analysis.scout \"Scan\" -> documentation.writer", root);
787
- assert.deepEqual((chain.params as { chain?: Array<{ agent?: string; task?: string }> }).chain?.map(({ agent, task }) => ({ agent, task })), [
788
- { agent: "code-analysis.scout", task: "Scan" },
789
- { agent: "documentation.writer", task: undefined },
790
- ]);
791
-
792
- await withIsolatedHome(async () => {
793
- const commands = new Map<string, RegisteredSlashCommand>();
794
- const pi = {
795
- events: createEventBus(),
796
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
797
- registerShortcut() {},
798
- sendMessage(_message: unknown) {},
799
- };
800
- registerSlashCommands!(pi, createState(root));
801
- const runCompletions = commands.get("run")!.getArgumentCompletions!("code-") as Array<{ value: string; label: string }>;
802
- assert.deepEqual(runCompletions.map((completion) => completion.value), ["code-analysis.scout"]);
803
- const chainCompletions = commands.get("chain")!.getArgumentCompletions!("code-analysis.scout \"Scan\" -> doc") as Array<{ value: string; label: string }>;
804
- assert.deepEqual(chainCompletions.map((completion) => completion.value), ["code-analysis.scout \"Scan\" -> documentation.writer"]);
805
- // Regression: bare group-ish syntax inside a `--` shared task is plain text, not
806
- // a group separator, so it must not resume agent completion past the task.
807
- const pipeInTask = commands.get("chain")!.getArgumentCompletions!("code-analysis.scout -- do x | doc");
808
- assert.equal(pipeInTask, null);
809
- const openParenInTask = commands.get("chain")!.getArgumentCompletions!("code-analysis.scout -- do (doc");
810
- assert.equal(openParenInTask, null);
811
- const closeParenInTask = commands.get("chain")!.getArgumentCompletions!("code-analysis.scout -- do ) doc");
812
- assert.equal(closeParenInTask, null);
813
- const balancedParenInTask = commands.get("chain")!.getArgumentCompletions!("code-analysis.scout -- do (x) doc");
814
- assert.equal(balancedParenInTask, null);
815
- // Inside an actual parallel group, `|` still separates tasks and completes agents.
816
- const groupCompletions = commands.get("chain")!.getArgumentCompletions!("code-analysis.scout \"Scan\" -> (documentation.writer \"w\" | code") as Array<{ value: string; label: string }>;
817
- assert.deepEqual(groupCompletions.map((completion) => completion.value), ["code-analysis.scout \"Scan\" -> (documentation.writer \"w\" | code-analysis.scout"]);
818
- });
819
- });
820
- });
821
-
822
- it("/run-chain launches a saved chain with a shared task", async () => {
823
- await withTempProject("pi-run-chain-success-", async (root) => {
824
- writeProjectChain(root, "review-flow.chain.md", `---
825
- name: review-flow
826
- description: Review flow
827
- ---
828
-
829
- ## scout
830
-
831
- Scan {task}
832
-
833
- ## reviewer
834
-
835
- Review {previous}
836
- `);
837
-
838
- const { params } = await captureSlashCommandParams("run-chain", "review-flow -- Audit the auth flow", root);
839
- const runParams = params as {
840
- chain?: Array<{ agent?: string; task?: string }>;
841
- task?: string;
842
- clarify?: boolean;
843
- agentScope?: string;
844
- async?: unknown;
845
- context?: unknown;
846
- };
847
-
848
- assert.deepEqual(runParams.chain?.map(({ agent, task }) => ({ agent, task })), [
849
- { agent: "scout", task: "Scan {task}" },
850
- { agent: "reviewer", task: "Review {previous}" },
851
- ]);
852
- assert.equal(runParams.task, "Audit the auth flow");
853
- assert.equal(runParams.clarify, false);
854
- assert.equal(runParams.agentScope, "both");
855
- assert.equal(runParams.async, undefined);
856
- assert.equal(runParams.context, undefined);
857
- });
858
- });
859
-
860
- it("/run-chain returns while its foreground subagent is still running", async () => {
861
- await withTempProject("pi-run-chain-nonblocking-", async (root) => {
862
- writeProjectChain(root, "slow.chain.md", `---
863
- name: slow
864
- description: Slow chain
865
- ---
866
-
867
- ## scout
868
-
869
- Think for a long time about {task}
870
- `);
871
- const commands = new Map<string, RegisteredSlashCommand>();
872
- const events = createEventBus();
873
- let requestId: string | undefined;
874
- events.on(SLASH_SUBAGENT_REQUEST_EVENT, (data) => {
875
- const payload = data as { requestId: string };
876
- requestId = payload.requestId;
877
- events.emit(SLASH_SUBAGENT_STARTED_EVENT, { requestId });
878
- });
879
- const pi = {
880
- events,
881
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
882
- registerShortcut() {},
883
- sendMessage(_message: unknown) {},
884
- };
885
- registerSlashCommands!(pi, createState(root));
886
-
887
- const returned = await Promise.race([
888
- commands.get("run-chain")!.handler("slow -- test UI responsiveness", createCommandContext({ cwd: root })).then(() => true),
889
- new Promise<boolean>((resolve) => setTimeout(() => resolve(false), 25)),
890
- ]);
891
- assert.equal(returned, true, "the slash command should not hold the UI while the child runs");
892
- assert.ok(requestId);
893
- events.emit(SLASH_SUBAGENT_RESPONSE_EVENT, {
894
- requestId,
895
- result: { content: [{ type: "text", text: "done" }], details: { mode: "chain", results: [] } },
896
- isError: false,
897
- });
898
- });
899
- });
900
691
 
901
- it("/run-chain launches a saved JSON chain with dynamic fanout", async () => {
902
- await withTempProject("pi-run-chain-json-dynamic-", async (root) => {
903
- writeProjectChain(root, "dynamic-review.chain.json", JSON.stringify({
904
- name: "dynamic-review",
905
- description: "Dynamic review flow",
906
- chain: [
907
- { agent: "scout", task: "Return targets", as: "targets", outputSchema: { type: "object" } },
908
- {
909
- expand: { from: { output: "targets", path: "/items" }, item: "target", key: "/path", maxItems: 4 },
910
- parallel: { agent: "reviewer", task: "Review {target.path}", outputSchema: { type: "object" } },
911
- collect: { as: "reviews" },
912
- },
913
- ],
914
- }));
915
-
916
- const { params } = await captureSlashCommandParams("run-chain", "dynamic-review -- Audit", root);
917
- const runParams = params as { chain?: Array<Record<string, unknown>>; task?: string; clarify?: boolean; agentScope?: string };
918
-
919
- assert.equal(runParams.task, "Audit");
920
- assert.equal(runParams.clarify, false);
921
- assert.equal(runParams.agentScope, "both");
922
- assert.equal(runParams.chain?.[0]?.agent, "scout");
923
- assert.deepEqual(runParams.chain?.[1]?.expand, { from: { output: "targets", path: "/items" }, item: "target", key: "/path", maxItems: 4 });
924
- assert.deepEqual(runParams.chain?.[1]?.collect, { as: "reviews" });
925
- });
926
- });
927
-
928
- it("/run-chain preserves saved JSON chain acceptance contracts", async () => {
929
- await withTempProject("pi-run-chain-json-acceptance-", async (root) => {
930
- writeProjectChain(root, "verified-flow.chain.json", JSON.stringify({
931
- name: "verified-flow",
932
- description: "Verified flow",
933
- chain: [
934
- {
935
- agent: "worker",
936
- task: "Implement fix",
937
- acceptance: {
938
- level: "verified",
939
- verify: [{ id: "tests", command: "npm test" }],
940
- },
941
- },
942
- ],
943
- }));
944
-
945
- const { params } = await captureSlashCommandParams("run-chain", "verified-flow -- Audit", root);
946
- assert.deepEqual((params as { chain?: Array<{ acceptance?: unknown }> }).chain?.[0]?.acceptance, {
947
- level: "verified",
948
- verify: [{ id: "tests", command: "npm test" }],
949
- });
950
- });
951
- });
952
-
953
- it("/run-chain launches and completes packaged saved chains by dotted runtime name", async () => {
954
- await withTempProject("pi-run-chain-packaged-", async (root) => {
955
- writeProjectChain(root, "code-analysis.review-flow.chain.md", `---
956
- name: review-flow
957
- package: code-analysis
958
- description: Review flow
959
- ---
960
-
961
- ## code-analysis.scout
962
-
963
- Scan {task}
964
- `);
965
-
966
- const { params } = await captureSlashCommandParams("run-chain", "code-analysis.review-flow -- Audit", root);
967
- assert.equal((params as { task?: string }).task, "Audit");
968
- assert.deepEqual((params as { chain?: Array<{ agent?: string; task?: string }> }).chain?.map(({ agent, task }) => ({ agent, task })), [
969
- { agent: "code-analysis.scout", task: "Scan {task}" },
970
- ]);
692
+ const run = await captureSlashCommandParams("run", "code-analysis.explorer Investigate", root);
693
+ assert.deepEqual(run.params, { agent: "code-analysis.explorer", task: "Investigate", clarify: false, agentScope: "both" });
971
694
 
972
695
  await withIsolatedHome(async () => {
973
696
  const commands = new Map<string, RegisteredSlashCommand>();
974
- const pi = {
697
+ registerSlashCommands!({
975
698
  events: createEventBus(),
976
699
  registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
977
700
  registerShortcut() {},
978
- sendMessage(_message: unknown) {},
979
- };
980
- registerSlashCommands!(pi, createState(root));
981
- const completions = commands.get("run-chain")!.getArgumentCompletions!("code-") as Array<{ value: string; label: string }>;
982
- assert.deepEqual(completions.map((completion) => completion.value), ["code-analysis.review-flow"]);
701
+ sendMessage() {},
702
+ } as never, createState(root));
703
+ const completions = commands.get("run")!.getArgumentCompletions!("code-") as Array<{ value: string }>;
704
+ assert.deepEqual(completions.map(({ value }) => value), ["code-analysis.explorer"]);
983
705
  });
984
706
  });
985
707
  });
986
708
 
987
- it("/run-chain reports an unknown saved chain without launching", async () => {
988
- await withTempProject("pi-run-chain-unknown-", async (root) => {
989
- const { params, notifications } = await captureSlashCommandParams("run-chain", "missing -- Do work", root);
990
-
991
- assert.equal(params, undefined);
992
- assert.deepEqual(notifications, ["Unknown chain: missing"]);
993
- });
994
- });
995
-
996
- it("/run-chain suggests saved chain names", async () => {
997
- await withTempProject("pi-run-chain-completions-", async (root) => {
998
- writeProjectChain(root, "review-flow.chain.md", `---
999
- name: review-flow
1000
- description: Review flow
1001
- ---
1002
-
1003
- ## scout
1004
-
1005
- Scan
1006
- `);
1007
- writeProjectChain(root, "release-flow.chain.md", `---
1008
- name: release-flow
1009
- description: Release flow
1010
- ---
1011
-
1012
- ## planner
1013
-
1014
- Plan
1015
- `);
1016
- writeProjectChain(root, "triage.chain.md", `---
1017
- name: triage
1018
- description: Triage flow
1019
- ---
1020
-
1021
- ## scout
1022
-
1023
- Triage
1024
- `);
1025
-
1026
- await withIsolatedHome(async () => {
1027
- const commands = new Map<string, RegisteredSlashCommand>();
1028
- const pi = {
1029
- events: createEventBus(),
1030
- registerCommand(name: string, spec: RegisteredSlashCommand) {
1031
- commands.set(name, spec);
1032
- },
1033
- registerShortcut() {},
1034
- sendMessage(_message: unknown) {},
1035
- };
1036
-
1037
- registerSlashCommands!(pi, createState(root));
1038
- const completions = commands.get("run-chain")!.getArgumentCompletions!("re") as Array<{ value: string; label: string }>;
1039
- assert.deepEqual(completions.map((completion) => completion.value).sort(), ["release-flow", "review-flow"]);
1040
- assert.deepEqual(completions.map((completion) => completion.label).sort(), ["release-flow", "review-flow"]);
1041
- assert.equal(commands.get("run-chain")!.getArgumentCompletions!("review-flow -- "), null);
1042
- });
1043
- });
1044
- });
1045
-
1046
- it("/run-chain maps --bg to async execution", async () => {
1047
- await withTempProject("pi-run-chain-bg-", async (root) => {
1048
- writeProjectChain(root, "review-flow.chain.md", `---
1049
- name: review-flow
1050
- description: Review flow
1051
- ---
1052
-
1053
- ## scout
1054
-
1055
- Scan
1056
- `);
1057
-
1058
- const { params } = await captureSlashCommandParams("run-chain", "review-flow -- Audit --bg", root);
1059
-
1060
- assert.equal((params as { async?: unknown }).async, true);
1061
- assert.equal((params as { context?: unknown }).context, undefined);
1062
- });
1063
- });
1064
-
1065
- it("/run-chain maps --fork to forked context", async () => {
1066
- await withTempProject("pi-run-chain-fork-", async (root) => {
1067
- writeProjectChain(root, "review-flow.chain.md", `---
1068
- name: review-flow
1069
- description: Review flow
1070
- ---
1071
-
1072
- ## scout
1073
-
1074
- Scan
1075
- `);
1076
-
1077
- const { params } = await captureSlashCommandParams("run-chain", "review-flow -- Audit --fork", root);
1078
-
1079
- assert.equal((params as { context?: unknown }).context, "fork");
1080
- assert.equal((params as { async?: unknown }).async, undefined);
1081
- });
1082
- });
1083
-
1084
- it("/run-chain prefers a project saved chain over a same-named user chain", async () => {
1085
- await withTempProject("pi-run-chain-priority-", async (root) => {
1086
- writeProjectChain(root, "review-flow.chain.md", `---
1087
- name: review-flow
1088
- description: Project review flow
1089
- ---
1090
-
1091
- ## scout
1092
-
1093
- Project chain task
1094
- `);
1095
-
1096
- const { params } = await captureSlashCommandParams("run-chain", "review-flow -- Shared task", root, () => {
1097
- const userChainsDir = path.join(os.homedir(), ".selesai", "agent", "chains");
1098
- fs.mkdirSync(userChainsDir, { recursive: true });
1099
- fs.writeFileSync(path.join(userChainsDir, "review-flow.chain.md"), `---
1100
- name: review-flow
1101
- description: User review flow
1102
- ---
1103
-
1104
- ## scout
1105
-
1106
- User chain task
1107
- `, "utf-8");
1108
- });
1109
-
1110
- assert.equal((params as { chain?: Array<{ task?: string }> }).chain?.[0]?.task, "Project chain task");
1111
- });
1112
- });
1113
-
1114
- it("/run-chain resolves saved outputSchema files at the command boundary", async () => {
1115
- await withTempProject("pi-run-chain-schema-", async (root) => {
1116
- const schemasDir = path.join(root, ".selesai", "chains", "schemas");
1117
- fs.mkdirSync(schemasDir, { recursive: true });
1118
- fs.writeFileSync(path.join(schemasDir, "finding.schema.json"), JSON.stringify({ type: "object", properties: { ok: { type: "boolean" } } }), "utf-8");
1119
- writeProjectChain(root, "schema-flow.chain.md", `---
1120
- name: schema-flow
1121
- description: Schema flow
1122
- ---
1123
-
1124
- ## scout
1125
- outputSchema: ./schemas/finding.schema.json
1126
-
1127
- Gather context
1128
- `);
1129
-
1130
- const { params } = await captureSlashCommandParams("run-chain", "schema-flow -- Shared task", root);
1131
-
1132
- assert.deepEqual((params as { chain?: Array<{ outputSchema?: unknown }> }).chain?.[0]?.outputSchema, {
1133
- type: "object",
1134
- properties: { ok: { type: "boolean" } },
1135
- });
1136
- });
1137
- });
1138
-
1139
- it("/run-chain preserves saved step behavior fields", async () => {
1140
- await withTempProject("pi-run-chain-fields-", async (root) => {
1141
- writeProjectChain(root, "field-flow.chain.md", `---
1142
- name: field-flow
1143
- description: Field flow
1144
- ---
1145
-
1146
- ## scout
1147
- output: context.md
1148
- outputMode: file-only
1149
- reads: input.md, notes.md
1150
- model: openai/gpt-5.5
1151
- skills: research, audit
1152
- progress: true
1153
-
1154
- Gather context
1155
- `);
1156
-
1157
- const { params } = await captureSlashCommandParams("run-chain", "field-flow -- Shared task", root);
1158
-
1159
- assert.deepEqual((params as { chain?: unknown[] }).chain?.[0], {
1160
- agent: "scout",
1161
- task: "Gather context",
1162
- output: "context.md",
1163
- outputMode: "file-only",
1164
- reads: ["input.md", "notes.md"],
1165
- progress: true,
1166
- skill: ["research", "audit"],
1167
- model: "openai/gpt-5.5",
1168
- });
1169
- });
1170
- });
1171
-
1172
- it("/chain parses a parenthesized parallel group into a { parallel: [...] } step", async () => {
1173
- await withTempProject("pi-chain-group-slash-", async (root) => {
1174
- for (const name of ["scout", "reviewer", "writer"]) {
1175
- fs.writeFileSync(path.join(root, ".selesai", "agents", `${name}.md`), `---\nname: ${name}\ndescription: ${name}\n---\n\nBody\n`, "utf-8");
1176
- }
1177
-
1178
- const { params, notifications } = await captureSlashCommandParams("chain", 'scout "scan" -> (reviewer "A" | reviewer "B") -> writer "fix"', root);
1179
- assert.deepEqual(notifications, []);
1180
- const built = params as { chain?: Array<Record<string, unknown>>; task?: string };
1181
- assert.equal(built.task, "scan");
1182
- assert.equal(built.chain?.length, 3);
1183
- assert.equal(built.chain?.[0]?.agent, "scout");
1184
- const parallel = built.chain?.[1]?.parallel as Array<{ agent: string; task: string }>;
1185
- assert.ok(Array.isArray(parallel), "second step should be a parallel group");
1186
- assert.deepEqual(parallel.map(({ agent, task }) => ({ agent, task })), [
1187
- { agent: "reviewer", task: "A" },
1188
- { agent: "reviewer", task: "B" },
1189
- ]);
1190
- assert.equal(built.chain?.[2]?.agent, "writer");
1191
- });
1192
- });
1193
-
1194
- it("/chain reports parallel-group errors as notifications and does not launch", async () => {
1195
- await withTempProject("pi-chain-group-error-", async (root) => {
1196
- for (const name of ["scout", "reviewer"]) {
1197
- fs.writeFileSync(path.join(root, ".selesai", "agents", `${name}.md`), `---\nname: ${name}\ndescription: ${name}\n---\n\nBody\n`, "utf-8");
1198
- }
1199
-
1200
- const { params, notifications } = await captureSlashCommandParams("chain", 'scout "scan" -> (reviewer "A")', root);
1201
- assert.equal(params, undefined);
1202
- assert.equal(notifications.length, 1);
1203
- assert.match(notifications[0] ?? "", /at least two/i);
1204
- });
1205
- });
1206
-
1207
- it("/chain carries inline metadata and group options through to params", async () => {
1208
- await withTempProject("pi-chain-group-meta-", async (root) => {
1209
- for (const name of ["scout", "reviewer", "writer"]) {
1210
- fs.writeFileSync(path.join(root, ".selesai", "agents", `${name}.md`), `---\nname: ${name}\ndescription: ${name}\n---\n\nBody\n`, "utf-8");
1211
- }
1212
-
1213
- const { params, notifications } = await captureSlashCommandParams(
1214
- "chain",
1215
- 'scout[as=ctx,phase=recon] "scan" -> (reviewer "A" | writer "B")[concurrency=2,failFast]',
1216
- root,
1217
- );
1218
- assert.deepEqual(notifications, []);
1219
- const built = params as { chain?: Array<Record<string, unknown>> };
1220
- assert.equal(built.chain?.[0]?.as, "ctx");
1221
- assert.equal(built.chain?.[0]?.phase, "recon");
1222
- const group = built.chain?.[1] as Record<string, unknown>;
1223
- assert.equal((group.parallel as unknown[]).length, 2);
1224
- assert.equal(group.concurrency, 2);
1225
- assert.equal(group.failFast, true);
1226
- });
1227
- });
1228
-
1229
- it("/chain tab-completion works inside parallel groups", async () => {
1230
- await withTempProject("pi-chain-group-complete-", async (root) => {
1231
- for (const name of ["scout", "reviewer", "writer"]) {
1232
- fs.writeFileSync(path.join(root, ".selesai", "agents", `${name}.md`), `---\nname: ${name}\ndescription: ${name}\n---\n\nBody\n`, "utf-8");
1233
- }
1234
- await withIsolatedHome(async () => {
1235
- const commands = new Map<string, RegisteredSlashCommand>();
1236
- const pi = {
1237
- events: createEventBus(),
1238
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
1239
- registerShortcut() {},
1240
- sendMessage(_message: unknown) {},
1241
- };
1242
- registerSlashCommands!(pi, createState(root));
1243
- const complete = (prefix: string) =>
1244
- (commands.get("chain")!.getArgumentCompletions!(prefix) as Array<{ value: string }> | null)?.map((c) => c.value) ?? null;
1245
-
1246
- // after `(`
1247
- assert.deepEqual(complete('scout "scan" -> (rev'), ['scout "scan" -> (reviewer']);
1248
- // after `|`
1249
- assert.deepEqual(complete('scout "scan" -> (reviewer "A" | wr'), ['scout "scan" -> (reviewer "A" | writer']);
1250
- // after a bare `|` a space is inserted before every suggested agent
1251
- const barePipe = complete('scout "scan" -> (reviewer "A" |');
1252
- assert.ok(barePipe && barePipe.length > 0);
1253
- assert.ok(barePipe.every((v) => v.startsWith('scout "scan" -> (reviewer "A" | ')));
1254
- assert.ok(barePipe.includes('scout "scan" -> (reviewer "A" | writer'));
1255
- // inside an open quote: no agent completion
1256
- assert.equal(complete('scout "scan'), null);
1257
- });
1258
- });
1259
- });
1260
- });
1261
-
1262
-
1263
- describe("subagents-models slash command", { skip: !available ? "slash-commands.ts not importable" : undefined }, () => {
1264
- beforeEach(() => {
1265
- clearSlashSnapshots?.();
1266
- });
1267
-
1268
- it("routes to the models tool action", async () => {
1269
- const { params } = await captureSlashCommandParams("subagents-models", "", process.cwd());
1270
- assert.deepEqual(params, { action: "models" });
1271
- });
1272
-
1273
- it("passes an optional builtin filter", async () => {
1274
- const { params } = await captureSlashCommandParams("subagents-models", "explorer", process.cwd());
1275
- assert.deepEqual(params, { action: "models", agent: "explorer" });
1276
- });
1277
-
1278
- it("rejects invalid builtin filters without launching", async () => {
1279
- const { params, notifications } = await captureSlashCommandParams("subagents-models", "not-a-builtin", process.cwd());
1280
- assert.equal(params, undefined);
1281
- assert.deepEqual(notifications, ["Unknown builtin agent: not-a-builtin"]);
1282
- });
1283
-
1284
- it("suggests builtin agent names", async () => {
1285
- await withIsolatedHome(async () => {
1286
- const commands = new Map<string, RegisteredSlashCommand>();
1287
- const pi = {
1288
- events: createEventBus(),
1289
- registerCommand(name: string, spec: RegisteredSlashCommand) {
1290
- commands.set(name, spec);
1291
- },
1292
- registerShortcut() {},
1293
- sendMessage(_message: unknown) {},
1294
- };
1295
-
1296
- registerSlashCommands!(pi, createState(process.cwd()));
1297
- const completions = commands.get("subagents-models")!.getArgumentCompletions!("ex") as Array<{ value: string; label: string }>;
1298
- assert.deepEqual(completions.map((completion) => completion.value), ["explorer"]);
1299
- });
1300
- });
1301
- });
1302
-
1303
- describe("subagent cost slash command", { skip: !available ? "slash-commands.ts not importable" : undefined }, () => {
1304
- it("reports parent and child usage from the current session branch", async () => {
1305
- const sent: unknown[] = [];
1306
- const commands = new Map<string, RegisteredSlashCommand>();
1307
- const pi = {
1308
- events: createEventBus(),
1309
- registerCommand(name: string, spec: RegisteredSlashCommand) {
1310
- commands.set(name, spec);
1311
- },
1312
- registerShortcut() {},
1313
- sendMessage(message: unknown) { sent.push(message); },
1314
- };
1315
- const parentUsage = {
1316
- input: 100,
1317
- output: 50,
1318
- cacheRead: 10,
1319
- cacheWrite: 5,
1320
- cost: { input: 0.001, output: 0.002, cacheRead: 0, cacheWrite: 0, total: 0.003 },
1321
- };
1322
- const childUsage = { input: 20, output: 10, cacheRead: 2, cacheWrite: 1, cost: 0.004, turns: 1 };
1323
- const slashChildUsage = { input: 30, output: 15, cacheRead: 0, cacheWrite: 0, cost: 0.005, turns: 2 };
1324
- registerSlashCommands!(pi, createState(process.cwd()));
1325
- await commands.get("subagent-cost")!.handler("", createCommandContext({
1326
- sessionManager: {
1327
- getBranch: () => [
1328
- { type: "message", message: { role: "assistant", usage: parentUsage } },
1329
- {
1330
- type: "message",
1331
- message: {
1332
- role: "toolResult",
1333
- toolName: "subagent",
1334
- details: {
1335
- mode: "single",
1336
- results: [{ agent: "worker", task: "fix", exitCode: 0, messages: [], usage: childUsage, sessionFile: "/tmp/worker.jsonl" }],
1337
- },
1338
- },
1339
- },
1340
- {
1341
- type: "custom_message",
1342
- customType: SLASH_RESULT_TYPE,
1343
- details: {
1344
- requestId: "slash-1",
1345
- result: {
1346
- content: [{ type: "text", text: "done" }],
1347
- details: {
1348
- mode: "single",
1349
- results: [{ agent: "reviewer", task: "review", exitCode: 0, messages: [], usage: slashChildUsage }],
1350
- },
1351
- },
1352
- },
1353
- },
1354
- ],
1355
- },
1356
- }));
1357
-
1358
- const output = String((sent[0] as { content?: unknown }).content ?? "");
1359
- assert.match(output, /Parent: ↑100 ↓50 \$0\.0030/);
1360
- assert.match(output, /Child 1 \(worker\): ↑20 ↓10 \$0\.0040/);
1361
- assert.match(output, /Session: \/tmp\/worker\.jsonl/);
1362
- assert.match(output, /Child 2 \(reviewer\): ↑30 ↓15 \$0\.0050/);
1363
- assert.match(output, /Children: ↑50 ↓25 \$0\.0090/);
1364
- assert.match(output, /Total: ↑150 ↓75 \$0\.0120/);
1365
- });
1366
- });
1367
-
1368
- describe("subagent profiles slash commands", { skip: !available ? "slash-commands.ts not importable" : undefined }, () => {
1369
- it("lists saved profiles", async () => {
1370
- await withIsolatedHome(async () => {
1371
- const profilesDir = path.join(process.env.HOME!, ".selesai", "agent", "profiles", "pi-subagents");
1372
- fs.mkdirSync(profilesDir, { recursive: true });
1373
- fs.writeFileSync(path.join(profilesDir, "openai-codex.quota.json"), JSON.stringify({ subagents: { agentOverrides: {} } }));
1374
- fs.writeFileSync(path.join(profilesDir, "openai-codex.quality.json"), JSON.stringify({ subagents: { agentOverrides: {} } }));
1375
- const sent: unknown[] = [];
1376
- const commands = new Map<string, RegisteredSlashCommand>();
1377
- const pi = {
1378
- events: createEventBus(),
1379
- registerCommand(name: string, spec: RegisteredSlashCommand) {
1380
- commands.set(name, spec);
1381
- },
1382
- registerShortcut() {},
1383
- sendMessage(message: unknown) { sent.push(message); },
1384
- };
1385
- registerSlashCommands!(pi, createState(process.cwd()));
1386
- await commands.get("subagents-profiles")!.handler("", createCommandContext());
1387
- assert.match(String((sent[0] as { content?: unknown }).content ?? ""), /openai-codex\.quota/);
1388
- assert.match(String((sent[0] as { content?: unknown }).content ?? ""), /openai-codex\.quality/);
1389
- });
1390
- });
1391
-
1392
- it("loads a saved profile into user settings", async () => {
1393
- await withIsolatedHome(async () => {
1394
- const profilesDir = path.join(process.env.HOME!, ".selesai", "agent", "profiles", "pi-subagents");
1395
- fs.mkdirSync(profilesDir, { recursive: true });
1396
- fs.writeFileSync(path.join(profilesDir, "openai-codex.quota.json"), JSON.stringify({
1397
- subagents: { agentOverrides: {
1398
- scout: { model: "openai-codex/gpt-5.3-codex-spark" },
1399
- worker: { model: "openai-codex/gpt-5.4" },
1400
- } },
1401
- }, null, 2));
1402
- const sent: unknown[] = [];
1403
- const commands = new Map<string, RegisteredSlashCommand>();
1404
- const pi = {
1405
- events: createEventBus(),
1406
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
1407
- registerShortcut() {},
1408
- sendMessage(message: unknown) { sent.push(message); },
1409
- };
1410
- registerSlashCommands!(pi, createState(process.cwd()));
1411
- await commands.get("subagents-load-profile")!.handler("openai-codex.quota", createCommandContext());
1412
- const settings = JSON.parse(fs.readFileSync(path.join(process.env.HOME!, ".selesai", "agent", "settings.json"), "utf-8"));
1413
- assert.equal(settings.subagents.agentOverrides.scout.model, "openai-codex/gpt-5.3-codex-spark");
1414
- assert.equal(settings.subagents.agentOverrides.worker.model, "openai-codex/gpt-5.4");
1415
- assert.doesNotMatch(String((sent[0] as { content?: unknown }).content ?? ""), /run \/reload/);
1416
- });
1417
- });
1418
-
1419
- it("can switch the current session model to the loaded profile worker model", async () => {
1420
- await withIsolatedHome(async () => {
1421
- const profilesDir = path.join(process.env.HOME!, ".selesai", "agent", "profiles", "pi-subagents");
1422
- fs.mkdirSync(profilesDir, { recursive: true });
1423
- fs.writeFileSync(path.join(profilesDir, "openai-codex.quota.json"), JSON.stringify({
1424
- subagents: { agentOverrides: { builder: { model: "gpt-5.4:high" } } },
1425
- }, null, 2));
1426
- const sent: unknown[] = [];
1427
- const commands = new Map<string, RegisteredSlashCommand>();
1428
- let setModelArg: unknown;
1429
- const resolvedModel = { provider: "openai-codex", id: "gpt-5.4" };
1430
- const pi = {
1431
- events: createEventBus(),
1432
- async setModel(model: unknown) { setModelArg = model; return true; },
1433
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
1434
- registerShortcut() {},
1435
- sendMessage(message: unknown) { sent.push(message); },
1436
- };
1437
- registerSlashCommands!(pi as never, createState(process.cwd()));
1438
- await commands.get("subagents-load-profile")!.handler("openai-codex.quota", createCommandContext({
1439
- confirm: async () => true,
1440
- modelRegistry: {
1441
- getAvailable: () => [{ provider: "openai-codex", id: "gpt-5.4" }],
1442
- find: (provider, id) => provider === "openai-codex" && id === "gpt-5.4" ? resolvedModel : undefined,
1443
- },
1444
- }) as never);
1445
- assert.equal(setModelArg, resolvedModel);
1446
- assert.match(String((sent[0] as { content?: unknown }).content ?? ""), /Current session model switched to: openai-codex\/gpt-5.4/);
1447
- });
1448
- });
1449
-
1450
- it("refreshes a provider model catalog", async () => {
1451
- await withIsolatedHome(async () => {
1452
- const sent: unknown[] = [];
1453
- const commands = new Map<string, RegisteredSlashCommand>();
1454
- const pi = {
1455
- events: createEventBus(),
1456
- exec: async () => ({ stdout: "OK\n", stderr: "", code: 0, killed: false }),
1457
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
1458
- registerShortcut() {},
1459
- sendMessage(message: unknown) { sent.push(message); },
1460
- };
1461
- registerSlashCommands!(pi, createState(process.cwd()));
1462
- await commands.get("subagents-refresh-provider-models")!.handler("openai-codex", createCommandContext({
1463
- cwd: process.cwd(),
1464
- modelRegistry: {
1465
- getAvailable: () => [
1466
- { provider: "openai-codex", id: "gpt-5.3-codex-spark", reasoning: true },
1467
- { provider: "openai-codex", id: "gpt-5.4-mini", reasoning: true },
1468
- ],
1469
- },
1470
- }) as never);
1471
- assert.match(String((sent[0] as { content?: unknown }).content ?? ""), /Provider: openai-codex/);
1472
- assert.match(String((sent[0] as { content?: unknown }).content ?? ""), /Warning: 2 models were classified with name heuristics fallback\./);
1473
- assert.equal(fs.existsSync(path.join(process.env.HOME!, ".selesai", "agent", "profiles", "pi-subagents", "providers", "openai-codex.models.json")), true);
1474
- });
1475
- });
1476
-
1477
- it("generates provider profiles", async () => {
1478
- await withIsolatedHome(async () => {
1479
- const sent: unknown[] = [];
1480
- const commands = new Map<string, RegisteredSlashCommand>();
1481
- const pi = {
1482
- events: createEventBus(),
1483
- exec: async () => ({ stdout: "OK\n", stderr: "", code: 0, killed: false }),
1484
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
1485
- registerShortcut() {},
1486
- sendMessage(message: unknown) { sent.push(message); },
1487
- };
1488
- registerSlashCommands!(pi, createState(process.cwd()));
1489
- await commands.get("subagents-generate-profiles")!.handler("openai-codex", createCommandContext({
1490
- modelRegistry: {
1491
- getAvailable: () => [
1492
- { provider: "openai-codex", id: "gpt-5.3-codex-spark", reasoning: true },
1493
- { provider: "openai-codex", id: "gpt-5.4-mini", reasoning: true },
1494
- { provider: "openai-codex", id: "gpt-5.4", reasoning: true },
1495
- { provider: "openai-codex", id: "gpt-5.5", reasoning: true },
1496
- ],
1497
- },
1498
- }) as never);
1499
- assert.match(String((sent[0] as { content?: unknown }).content ?? ""), /Generated subagent profiles/);
1500
- assert.match(String((sent[0] as { content?: unknown }).content ?? ""), /Warning: generated profiles depend on heuristic-only classification for 4 selected models\./);
1501
- assert.equal(fs.existsSync(path.join(process.env.HOME!, ".selesai", "agent", "profiles", "pi-subagents", "openai-codex.quota.json")), true);
1502
- assert.equal(fs.existsSync(path.join(process.env.HOME!, ".selesai", "agent", "profiles", "pi-subagents", "openai-codex.quality.json")), true);
1503
- });
1504
- });
1505
-
1506
- it("checks a profile", async () => {
1507
- await withIsolatedHome(async () => {
1508
- const profilesDir = path.join(process.env.HOME!, ".selesai", "agent", "profiles", "pi-subagents");
1509
- fs.mkdirSync(profilesDir, { recursive: true });
1510
- fs.writeFileSync(path.join(profilesDir, "demo.json"), JSON.stringify({
1511
- subagents: { agentOverrides: { scout: { model: "openai-codex/gpt-5.3-codex-spark" } } },
1512
- }, null, 2));
1513
- const sent: unknown[] = [];
1514
- const commands = new Map<string, RegisteredSlashCommand>();
1515
- const pi = {
1516
- events: createEventBus(),
1517
- exec: async () => ({ stdout: "OK\n", stderr: "", code: 0, killed: false }),
1518
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
1519
- registerShortcut() {},
1520
- sendMessage(message: unknown) { sent.push(message); },
1521
- };
1522
- registerSlashCommands!(pi, createState(process.cwd()));
1523
- await commands.get("subagents-check-profile")!.handler("demo", createCommandContext({
1524
- modelRegistry: { getAvailable: () => [{ provider: "openai-codex", id: "gpt-5.3-codex-spark" }] },
1525
- }) as never);
1526
- assert.match(String((sent[0] as { content?: unknown }).content ?? ""), /probe ok/);
1527
- });
1528
- });
1529
-
1530
- it("suggests provider names for refresh and generate commands", async () => {
1531
- await withIsolatedHome(async () => {
1532
- const commands = new Map<string, RegisteredSlashCommand>();
1533
- const pi = {
1534
- events: createEventBus(),
1535
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
1536
- registerShortcut() {},
1537
- sendMessage(_message: unknown) {},
1538
- };
1539
- const state = createState(process.cwd());
1540
- state.lastUiContext = createCommandContext({
1541
- modelRegistry: {
1542
- getAvailable: () => [
1543
- { provider: "openai-codex", id: "gpt-5.4" },
1544
- { provider: "openai", id: "gpt-5" },
1545
- { provider: "anthropic", id: "claude-sonnet-4" },
1546
- ],
1547
- },
1548
- }) as never;
1549
- registerSlashCommands!(pi, state);
1550
- const refresh = commands.get("subagents-refresh-provider-models")!.getArgumentCompletions!("open") as Array<{ value: string; label: string }>;
1551
- const generate = commands.get("subagents-generate-profiles")!.getArgumentCompletions!("an") as Array<{ value: string; label: string }>;
1552
- assert.deepEqual(refresh.map((entry) => entry.value), ["openai", "openai-codex"]);
1553
- assert.deepEqual(generate.map((entry) => entry.value), ["anthropic"]);
1554
- });
1555
- });
1556
- });
1557
-
1558
- describe("subagents admin slash command", { skip: !available ? "slash-commands.ts not importable" : undefined }, () => {
1559
- beforeEach(() => {
1560
- clearSlashSnapshots?.();
1561
- });
1562
-
1563
- function registerAdmin(sent: unknown[]) {
1564
- const commands = new Map<string, RegisteredSlashCommand>();
1565
- const pi = {
1566
- events: createEventBus(),
1567
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
1568
- registerShortcut() {},
1569
- sendMessage(message: unknown) { sent.push(message); },
1570
- };
1571
- registerSlashCommands!(pi, createState(process.cwd()));
1572
- return commands;
1573
- }
1574
-
1575
- it("registers /subagents", async () => {
1576
- await withIsolatedHome(async () => {
1577
- const commands = registerAdmin([]);
1578
- assert.equal(commands.has("subagents"), true);
1579
- });
1580
- });
1581
-
1582
- it("treats agent and scope selector cancellation as a silent no-op", async () => {
1583
- await withIsolatedHome(async () => {
1584
- await withTempProject("pi-subagents-admin-cancel-", async (root) => {
1585
- const sent: unknown[] = [];
1586
- const notifications: string[] = [];
1587
- const commands = registerAdmin(sent);
1588
-
1589
- await commands.get("subagents")!.handler("", createCommandContext({
1590
- cwd: root,
1591
- hasUI: true,
1592
- select: async () => undefined,
1593
- notify: (message) => notifications.push(message),
1594
- }));
1595
-
1596
- await commands.get("subagents")!.handler("builder model", createCommandContext({
1597
- cwd: root,
1598
- hasUI: true,
1599
- modelRegistry: { getAvailable: () => [{ provider: "test", id: "new-model", reasoning: true }] },
1600
- select: async (title) => title.startsWith("Select model") ? "test/new-model" : undefined,
1601
- notify: (message) => notifications.push(message),
1602
- }));
1603
-
1604
- assert.deepEqual(sent, []);
1605
- assert.deepEqual(notifications, []);
1606
- assert.equal(fs.existsSync(path.join(root, ".selesai", "settings.json")), false);
1607
- });
1608
- });
1609
- });
1610
-
1611
- it("reports duplicate names as ambiguous without UI", async () => {
1612
- await withIsolatedHome(async () => {
1613
- await withTempProject("pi-subagents-admin-ambiguous-", async (root) => {
1614
- fs.writeFileSync(path.join(root, ".selesai", "agents", "builder.md"), "---\nname: builder\ndescription: Project builder\n---\n\nWork.\n", "utf-8");
1615
- const sent: unknown[] = [];
1616
- const commands = registerAdmin(sent);
1617
- await commands.get("subagents")!.handler("builder", createCommandContext({ cwd: root }));
1618
- assert.equal(sent.length, 1);
1619
- const content = (sent[0] as { content?: string }).content ?? "";
1620
- assert.match(content, /Subagent 'builder' is ambiguous/);
1621
- assert.match(content, /project:/);
1622
- assert.match(content, /builtin:/);
1623
- });
1624
- });
1625
- });
1626
-
1627
- it("keeps same-source duplicate agents distinct in interactive pickers", async () => {
1628
- await withIsolatedHome(async () => {
1629
- await withTempProject("pi-subagents-admin-same-source-", async (root) => {
1630
- const localPath = path.join(process.env.SELESAI_CODING_AGENT_DIR!, "agents", "duplicate-admin-agent.md");
1631
- const extraDir = path.join(root, "extra-agents");
1632
- const extraPath = path.join(extraDir, "duplicate-admin-agent.md");
1633
- fs.mkdirSync(path.dirname(localPath), { recursive: true });
1634
- fs.mkdirSync(extraDir, { recursive: true });
1635
- const frontmatter = "---\nname: duplicate-admin-agent\ndescription: Duplicate agent\nmodel: test/model\n---\n\n";
1636
- fs.writeFileSync(localPath, `${frontmatter}Local prompt.\n`, "utf-8");
1637
- fs.writeFileSync(extraPath, `${frontmatter}Extra prompt.\n`, "utf-8");
1638
- const previousExtraDirs = process.env.SELESAI_SUBAGENT_EXTRA_AGENT_DIRS;
1639
- process.env.SELESAI_SUBAGENT_EXTRA_AGENT_DIRS = extraDir;
1640
- try {
1641
- const sent: unknown[] = [];
1642
- const commands = registerAdmin(sent);
1643
- await commands.get("subagents")!.handler("duplicate-admin-agent details", createCommandContext({
1644
- cwd: root,
1645
- hasUI: true,
1646
- select: async (_title, choices) => {
1647
- assert.equal(choices.length, 2);
1648
- assert.ok(choices.some((choice) => choice.includes(localPath)));
1649
- assert.ok(choices.some((choice) => choice.includes(extraPath)));
1650
- return choices.find((choice) => choice.includes(localPath));
1651
- },
1652
- }));
1653
- const content = (sent[0] as { content?: string }).content ?? "";
1654
- assert.ok(content.split("\n").includes(`Path: ${localPath}`));
1655
- } finally {
1656
- if (previousExtraDirs === undefined) delete process.env.SELESAI_SUBAGENT_EXTRA_AGENT_DIRS;
1657
- else process.env.SELESAI_SUBAGENT_EXTRA_AGENT_DIRS = previousExtraDirs;
1658
- }
1659
- });
1660
- });
1661
- });
1662
-
1663
- it("updates a project agent model without dumping metadata first", async () => {
1664
- await withIsolatedHome(async () => {
1665
- await withTempProject("pi-subagents-admin-model-", async (root) => {
1666
- const agentPath = path.join(root, ".selesai", "agents", "worker.md");
1667
- fs.writeFileSync(agentPath, `---\nname: worker\ndescription: Test worker\nmodel: anthropic/claude-sonnet-4-6\n---\n\nDo work.\n`, "utf-8");
1668
- const sent: unknown[] = [];
1669
- const commands = registerAdmin(sent);
1670
- let refreshes = 0;
1671
- await commands.get("subagents")!.handler("worker model", createCommandContext({
1672
- cwd: root,
1673
- hasUI: true,
1674
- modelRegistry: {
1675
- refresh: () => { refreshes++; },
1676
- getAvailable: () => [{ provider: "bluebox-azure-openai", id: "gpt-5_6-sol", reasoning: true }],
1677
- },
1678
- select: async (_title, choices) => {
1679
- const projectAgent = choices.find((choice) => choice.startsWith("worker [project]"));
1680
- if (projectAgent) return projectAgent;
1681
- assert.ok(choices.includes("bluebox-azure-openai/gpt-5_6-sol"));
1682
- return "bluebox-azure-openai/gpt-5_6-sol";
1683
- },
1684
- }));
1685
-
1686
- assert.equal(refreshes, 1);
1687
- assert.match(fs.readFileSync(agentPath, "utf-8"), /^model: bluebox-azure-openai\/gpt-5_6-sol$/m);
1688
- assert.equal(sent.length, 1, "only the compact confirmation should enter the conversation");
1689
- assert.match((sent[0] as { content?: string }).content ?? "", /Updated 'worker' model/);
1690
- });
1691
- });
1692
- });
1693
-
1694
- it("updates a profile-managed user agent through settings instead of pinning frontmatter", async () => {
1695
- await withIsolatedHome(async () => {
1696
- await withTempProject("pi-subagents-admin-profile-", async (root) => {
1697
- const userAgentDir = path.join(process.env.HOME!, ".selesai", "agent", "agents");
1698
- fs.mkdirSync(userAgentDir, { recursive: true });
1699
- const agentPath = path.join(userAgentDir, "worker.md");
1700
- fs.writeFileSync(agentPath, `---\nname: worker\ndescription: Profile worker\n---\n\nDo work.\n`, "utf-8");
1701
- const settingsPath = path.join(process.env.HOME!, ".selesai", "agent", "settings.json");
1702
- fs.writeFileSync(settingsPath, JSON.stringify({
1703
- subagents: { disableBuiltins: true, agentOverrides: { worker: { model: "anthropic/claude-opus-4-8" } } },
1704
- }, null, 2));
1705
-
1706
- const sent: unknown[] = [];
1707
- const commands = registerAdmin(sent);
1708
- await commands.get("subagents")!.handler("worker model", createCommandContext({
1709
- cwd: root,
1710
- hasUI: true,
1711
- modelRegistry: { getAvailable: () => [{ provider: "bluebox-azure-openai", id: "gpt-5_6-luna", reasoning: true }] },
1712
- select: async (_title, choices) =>
1713
- choices.find((choice) => choice.startsWith("worker [user]"))
1714
- ?? "bluebox-azure-openai/gpt-5_6-luna",
1715
- }));
1716
-
1717
- assert.doesNotMatch(fs.readFileSync(agentPath, "utf-8"), /^model:/m);
1718
- const settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
1719
- assert.equal(settings.subagents.disableBuiltins, true);
1720
- assert.equal(settings.subagents.agentOverrides.worker.model, "bluebox-azure-openai/gpt-5_6-luna");
1721
- });
1722
- });
1723
- });
1724
-
1725
- it("does not snapshot global disableThinking into an unrelated builtin override", async () => {
1726
- await withIsolatedHome(async () => {
1727
- await withTempProject("pi-subagents-admin-global-thinking-", async (root) => {
1728
- const settingsPath = path.join(process.env.SELESAI_CODING_AGENT_DIR!, "settings.json");
1729
- fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
1730
- fs.writeFileSync(settingsPath, JSON.stringify({ subagents: { disableThinking: true } }, null, 2), "utf-8");
1731
- const commands = registerAdmin([]);
1732
- await commands.get("subagents")!.handler("builder model", createCommandContext({
1733
- cwd: root,
1734
- hasUI: true,
1735
- modelRegistry: { getAvailable: () => [{ provider: "test", id: "new-model", reasoning: true }] },
1736
- select: async () => "test/new-model",
1737
- }));
1738
-
1739
- assert.deepEqual(JSON.parse(fs.readFileSync(settingsPath, "utf-8")).subagents, {
1740
- disableThinking: true,
1741
- agentOverrides: { builder: { model: "test/new-model" } },
1742
- });
1743
- });
1744
- });
1745
- });
1746
-
1747
- it("offers and saves max thinking only when model metadata declares it", async () => {
1748
- await withIsolatedHome(async () => {
1749
- await withTempProject("pi-subagents-admin-thinking-", async (root) => {
1750
- const settingsPath = path.join(process.env.SELESAI_CODING_AGENT_DIR!, "settings.json");
1751
- fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
1752
- fs.writeFileSync(settingsPath, JSON.stringify({
1753
- subagents: { agentOverrides: { worker: { model: "anthropic/claude-opus-4-8", thinking: "high" } } },
1754
- }, null, 2));
1755
- const agentPath = path.join(root, ".selesai", "agents", "worker.md");
1756
- fs.writeFileSync(agentPath, `---\nname: worker\ndescription: Test worker\nmodel: bluebox-azure-openai/gpt-5_6-sol\n---\n\nDo work.\n`, "utf-8");
1757
- const commands = registerAdmin([]);
1758
- await commands.get("subagents")!.handler("worker thinking", createCommandContext({
1759
- cwd: root,
1760
- hasUI: true,
1761
- modelRegistry: {
1762
- getAvailable: () => [{
1763
- provider: "bluebox-azure-openai",
1764
- id: "gpt-5_6-sol",
1765
- reasoning: true,
1766
- thinkingLevelMap: { minimal: null, xhigh: "xhigh", max: "max" },
1767
- }],
1768
- },
1769
- select: async (_title, choices) => {
1770
- const projectAgent = choices.find((choice) => choice.startsWith("worker [project]"));
1771
- if (projectAgent) return projectAgent;
1772
- assert.ok(choices.includes("max"));
1773
- assert.equal(choices.includes("minimal"), false);
1774
- return "max";
1775
- },
1776
- }));
1777
- assert.match(fs.readFileSync(agentPath, "utf-8"), /^thinking: max$/m);
1778
- assert.deepEqual(JSON.parse(fs.readFileSync(settingsPath, "utf-8")).subagents.agentOverrides.worker, {
1779
- model: "anthropic/claude-opus-4-8",
1780
- thinking: "high",
1781
- });
1782
- });
1783
- });
1784
- });
1785
-
1786
- it("uses the inherited session model's thinking capabilities and warns on refresh failure", async () => {
1787
- await withIsolatedHome(async () => {
1788
- await withTempProject("pi-subagents-admin-inherited-thinking-", async (root) => {
1789
- fs.writeFileSync(path.join(root, ".selesai", "agents", "auditor.md"), "---\nname: auditor\ndescription: Audit things\n---\n\nAudit.\n", "utf-8");
1790
- const notifications: Array<{ message: string; type?: string }> = [];
1791
- const commands = registerAdmin([]);
1792
- await commands.get("subagents")!.handler("auditor thinking", createCommandContext({
1793
- cwd: root,
1794
- hasUI: true,
1795
- model: { provider: "test", id: "plain-model" },
1796
- modelRegistry: {
1797
- refresh: () => { throw new Error("invalid models.json"); },
1798
- getAvailable: () => [{ provider: "test", id: "plain-model", reasoning: false }],
1799
- },
1800
- select: async (title, choices) => {
1801
- assert.match(title, /Session model: test\/plain-model/);
1802
- assert.deepEqual(choices, ["Default / inherit session thinking", "off"]);
1803
- return undefined;
1804
- },
1805
- notify: (message, type) => notifications.push({ message, type }),
1806
- }));
1807
-
1808
- assert.equal(notifications.length, 1);
1809
- assert.equal(notifications[0]?.type, "warning");
1810
- assert.match(notifications[0]?.message ?? "", /using the last loaded choices.*invalid models\.json/);
1811
- });
1812
- });
1813
- });
1814
-
1815
- it("does not pin inherited settings when editing a project-owned field", async () => {
1816
- await withIsolatedHome(async () => {
1817
- await withTempProject("pi-subagents-admin-cross-scope-", async (root) => {
1818
- const agentPath = path.join(root, ".selesai", "agents", "worker.md");
1819
- fs.writeFileSync(agentPath, "---\nname: worker\ndescription: Test worker\n---\n\nDo work.\n", "utf-8");
1820
- const settingsPath = path.join(process.env.HOME!, ".selesai", "agent", "settings.json");
1821
- fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
1822
- fs.writeFileSync(settingsPath, JSON.stringify({
1823
- subagents: { agentOverrides: { worker: { thinking: "high" } } },
1824
- }, null, 2));
1825
-
1826
- const commands = registerAdmin([]);
1827
- await commands.get("subagents")!.handler("worker model", createCommandContext({
1828
- cwd: root,
1829
- hasUI: true,
1830
- modelRegistry: { getAvailable: () => [{ provider: "bluebox-azure-openai", id: "gpt-5_6-sol", reasoning: true }] },
1831
- select: async (_title, choices) => {
1832
- const projectAgent = choices.find((choice) => choice.startsWith("worker [project]"));
1833
- if (projectAgent) return projectAgent;
1834
- assert.ok(choices.includes("bluebox-azure-openai/gpt-5_6-sol"));
1835
- return "bluebox-azure-openai/gpt-5_6-sol";
1836
- },
1837
- }));
1838
-
1839
- const updated = fs.readFileSync(agentPath, "utf-8");
1840
- assert.match(updated, /^model: bluebox-azure-openai\/gpt-5_6-sol$/m);
1841
- assert.doesNotMatch(updated, /^thinking:/m);
1842
- assert.doesNotMatch(updated, /^systemPromptMode:/m);
1843
- assert.doesNotMatch(updated, /^inheritProjectContext:/m);
1844
- assert.equal(JSON.parse(fs.readFileSync(settingsPath, "utf-8")).subagents.agentOverrides.worker.thinking, "high");
1845
- });
1846
- });
1847
- });
1848
-
1849
- it("does not write definitions from SELESAI_SUBAGENT_EXTRA_AGENT_DIRS", async () => {
1850
- await withIsolatedHome(async () => {
1851
- await withTempProject("pi-subagents-admin-extra-", async (root) => {
1852
- const extraDir = path.join(root, "extra-agents");
1853
- const agentPath = path.join(extraDir, "worker.md");
1854
- fs.mkdirSync(extraDir, { recursive: true });
1855
- const original = "---\nname: worker\ndescription: Read-only worker\nmodel: anthropic/claude-sonnet-4-6\n---\n\nDo work.\n";
1856
- fs.writeFileSync(agentPath, original, "utf-8");
1857
- const previousExtraDirs = process.env.SELESAI_SUBAGENT_EXTRA_AGENT_DIRS;
1858
- process.env.SELESAI_SUBAGENT_EXTRA_AGENT_DIRS = extraDir;
1859
- try {
1860
- const commands = registerAdmin([]);
1861
- await commands.get("subagents")!.handler("worker model", createCommandContext({
1862
- cwd: root,
1863
- hasUI: true,
1864
- modelRegistry: { getAvailable: () => [{ provider: "bluebox-azure-openai", id: "gpt-5_6-sol", reasoning: true }] },
1865
- select: async (_title, choices) =>
1866
- choices.find((choice) => choice.startsWith("worker [user]"))
1867
- ?? "bluebox-azure-openai/gpt-5_6-sol",
1868
- }));
1869
- assert.equal(fs.readFileSync(agentPath, "utf-8"), original);
1870
- } finally {
1871
- if (previousExtraDirs === undefined) delete process.env.SELESAI_SUBAGENT_EXTRA_AGENT_DIRS;
1872
- else process.env.SELESAI_SUBAGENT_EXTRA_AGENT_DIRS = previousExtraDirs;
1873
- }
1874
- });
1875
- });
1876
- });
1877
-
1878
- it("respects package-owned fields and uses settings only for unset package fields", async () => {
1879
- await withIsolatedHome(async () => {
1880
- await withTempProject("pi-subagents-admin-package-", async (root) => {
1881
- const packageRoot = path.join(root, ".selesai", "npm", "node_modules", "admin-package");
1882
- const agentPath = path.join(packageRoot, "agents", "package-admin-agent.md");
1883
- fs.mkdirSync(path.dirname(agentPath), { recursive: true });
1884
- fs.writeFileSync(path.join(packageRoot, "package.json"), JSON.stringify({
1885
- name: "admin-package",
1886
- "pi-subagents": { agents: ["./agents"] },
1887
- }), "utf-8");
1888
- const original = "---\nname: package-admin-agent\ndescription: Package agent\nmodel: test/original\n---\n\nPackage prompt.\n";
1889
- fs.writeFileSync(agentPath, original, "utf-8");
1890
- const settingsPath = path.join(root, ".selesai", "settings.json");
1891
- fs.writeFileSync(settingsPath, JSON.stringify({
1892
- subagents: { agentOverrides: { "package-admin-agent": { thinking: "low" } } },
1893
- }, null, 2), "utf-8");
1894
-
1895
- const sent: unknown[] = [];
1896
- const commands = registerAdmin(sent);
1897
- await commands.get("subagents")!.handler("package-admin-agent model", createCommandContext({
1898
- cwd: root,
1899
- hasUI: true,
1900
- modelRegistry: { getAvailable: () => [{ provider: "test", id: "replacement", reasoning: true }] },
1901
- select: async () => "test/replacement",
1902
- }));
1903
- await commands.get("subagents")!.handler("package-admin-agent prompt", createCommandContext({
1904
- cwd: root,
1905
- hasUI: true,
1906
- }));
1907
-
1908
- assert.equal(fs.readFileSync(agentPath, "utf-8"), original);
1909
- assert.deepEqual(JSON.parse(fs.readFileSync(settingsPath, "utf-8")).subagents.agentOverrides, {
1910
- "package-admin-agent": { thinking: "low" },
1911
- });
1912
- assert.match((sent[0] as { content?: string }).content ?? "", /model.*read-only package definition/);
1913
- assert.match((sent[1] as { content?: string }).content ?? "", /systemPrompt.*read-only package definition/);
1914
-
1915
- const configurablePath = path.join(packageRoot, "agents", "configurable-package-agent.md");
1916
- const configurable = "---\nname: configurable-package-agent\ndescription: Configurable package agent\n---\n\nPackage prompt.\n";
1917
- fs.writeFileSync(configurablePath, configurable, "utf-8");
1918
- await commands.get("subagents")!.handler("configurable-package-agent model", createCommandContext({
1919
- cwd: root,
1920
- hasUI: true,
1921
- modelRegistry: { getAvailable: () => [{ provider: "test", id: "replacement", reasoning: true }] },
1922
- select: async (title) => title.startsWith("Select model") ? "test/replacement" : "project",
1923
- }));
1924
- assert.equal(fs.readFileSync(configurablePath, "utf-8"), configurable);
1925
- assert.deepEqual(JSON.parse(fs.readFileSync(settingsPath, "utf-8")).subagents.agentOverrides, {
1926
- "package-admin-agent": { thinking: "low" },
1927
- "configurable-package-agent": { model: "test/replacement" },
1928
- });
1929
- });
1930
- });
1931
- });
1932
-
1933
- it("edits a system prompt through Pi's native editor", async () => {
1934
- await withIsolatedHome(async () => {
1935
- await withTempProject("pi-subagents-admin-prompt-", async (root) => {
1936
- const agentPath = path.join(root, ".selesai", "agents", "worker.md");
1937
- fs.writeFileSync(agentPath, `---\nname: worker\ndescription: Test worker\n---\n\nOriginal prompt.\n`, "utf-8");
1938
- const status: Array<[string, string | undefined]> = [];
1939
- let editorArgs: [string, string] | undefined;
1940
- const commands = registerAdmin([]);
1941
- await commands.get("subagents")!.handler("worker prompt", createCommandContext({
1942
- cwd: root,
1943
- hasUI: true,
1944
- select: async (_title, choices) => choices.find((choice) => choice.startsWith("worker [project]")),
1945
- editor: async (title, prefill) => {
1946
- editorArgs = [title, prefill];
1947
- return "Edited prompt.\n";
1948
- },
1949
- setStatus: (key, text) => status.push([key, text]),
1950
- }));
1951
- assert.deepEqual(editorArgs, ["Edit 'worker' system prompt", "Original prompt."]);
1952
- assert.match(fs.readFileSync(agentPath, "utf-8"), /Edited prompt\./);
1953
- assert.deepEqual(status, []);
1954
- });
1955
- });
1956
- });
1957
-
1958
- it("cancels native system-prompt editing without mutation", async () => {
1959
- await withIsolatedHome(async () => {
1960
- await withTempProject("pi-subagents-admin-prompt-cancel-", async (root) => {
1961
- const agentPath = path.join(root, ".selesai", "agents", "worker.md");
1962
- const original = `---\nname: worker\ndescription: Test worker\n---\n\nOriginal prompt.\n`;
1963
- fs.writeFileSync(agentPath, original, "utf-8");
1964
- const sent: unknown[] = [];
1965
- const commands = registerAdmin(sent);
1966
- await commands.get("subagents")!.handler("worker prompt", createCommandContext({
1967
- cwd: root,
1968
- hasUI: true,
1969
- select: async (_title, choices) => choices.find((choice) => choice.startsWith("worker [project]")),
1970
- editor: async () => undefined,
1971
- }));
1972
- assert.equal(fs.readFileSync(agentPath, "utf-8"), original);
1973
- assert.deepEqual(sent, []);
1974
- });
1975
- });
1976
- });
1977
-
1978
- it("reports native-editor failures without rewriting the agent", async () => {
1979
- await withIsolatedHome(async () => {
1980
- await withTempProject("pi-subagents-admin-editor-failure-", async (root) => {
1981
- const agentPath = path.join(root, ".selesai", "agents", "worker.md");
1982
- const original = `---\nname: worker\ndescription: Test worker\n---\n\nOriginal prompt.\n`;
1983
- fs.writeFileSync(agentPath, original, "utf-8");
1984
- const sent: unknown[] = [];
1985
- const commands = registerAdmin(sent);
1986
- await commands.get("subagents")!.handler("worker prompt", createCommandContext({
1987
- cwd: root,
1988
- hasUI: true,
1989
- select: async (_title, choices) => choices.find((choice) => choice.startsWith("worker [project]")),
1990
- editor: async () => { throw new Error("editor unavailable"); },
1991
- }));
1992
- assert.equal(fs.readFileSync(agentPath, "utf-8"), original);
1993
- assert.match((sent.at(-1) as { content?: string }).content ?? "", /Failed to update 'worker': editor unavailable/);
1994
- });
1995
- });
1996
- });
1997
-
1998
- it("shows metadata for a named subagent without requiring UI", async () => {
1999
- await withIsolatedHome(async () => {
2000
- await withTempProject("pi-subagents-admin-metadata-", async (root) => {
2001
- fs.writeFileSync(path.join(root, ".selesai", "agents", "auditor.md"), `---\nname: auditor\ndescription: Audit things\nthinking: false\n---\n\nAudit.\n`, "utf-8");
2002
- const sent: unknown[] = [];
2003
- const commands = registerAdmin(sent);
2004
- await commands.get("subagents")!.handler("auditor", createCommandContext({ cwd: root }));
2005
- assert.equal(sent.length, 1);
2006
- const content = (sent[0] as { content?: string }).content ?? "";
2007
- assert.match(content, /Agent: auditor \(project\)/);
2008
- assert.match(content, /^Thinking: off$/m);
2009
- });
2010
- });
2011
- });
2012
- });
2013
-
2014
-
2015
- describe("subagents-doctor slash command", { skip: !available ? "slash-commands.ts not importable" : undefined }, () => {
2016
- beforeEach(() => {
2017
- clearSlashSnapshots?.();
2018
- });
2019
-
2020
- it("routes to the doctor tool action", async () => {
2021
- const { params } = await captureSlashCommandParams("subagents-doctor", "", process.cwd());
2022
- assert.deepEqual(params, { action: "doctor" });
2023
- });
2024
-
2025
- it("keeps the textual fleet status fallback when no UI is available", async () => {
2026
- const { params } = await captureSlashCommandParams("subagents-fleet", "", process.cwd());
2027
- assert.deepEqual(params, { action: "status", view: "fleet" });
2028
- });
2029
-
2030
- it("opens the native fleet from both the slash command and direct shortcut", async () => {
2031
- const commands = new Map<string, RegisteredSlashCommand>();
2032
- const shortcuts = new Map<string, { description: string; handler(ctx: unknown): Promise<void> }>();
2033
- let opened = 0;
2034
- let rendered = "";
2035
- const custom = async (factory: unknown, options: unknown) => {
2036
- opened++;
2037
- const component = (factory as (tui: unknown, theme: unknown, keybindings: unknown, done: (value: undefined) => void) => { render(width: number): string[]; dispose(): void })(
2038
- { terminal: { rows: 30, columns: 100 }, requestRender() {} },
2039
- { fg: (_name: string, text: string) => text, bold: (text: string) => text },
2040
- undefined,
2041
- () => {},
2042
- );
2043
- rendered = component.render(100).join("\n");
2044
- component.dispose();
2045
- assert.equal(options, undefined);
2046
- return undefined;
2047
- };
2048
- const pi = {
2049
- events: createEventBus(),
2050
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
2051
- registerShortcut(key: string, spec: { description: string; handler(ctx: unknown): Promise<void> }) { shortcuts.set(key, spec); },
2052
- sendMessage(_message: unknown) {},
2053
- };
2054
- const state = createState(process.cwd());
2055
- const ctx = createCommandContext({ hasUI: true, custom });
2056
- registerSlashCommands!(pi, state);
2057
-
2058
- await commands.get("subagents-fleet")!.handler("", ctx);
2059
- assert.equal(shortcuts.size, 1);
2060
- const shortcut = [...shortcuts.values()][0]!;
2061
- assert.equal(shortcut.description, "Open subagent fleet inspector");
2062
- await shortcut.handler(ctx);
2063
-
2064
- assert.equal(opened, 2);
2065
- assert.match(rendered, /Subagent fleet/);
2066
- assert.match(rendered, /live controls/);
2067
- });
2068
-
2069
- it("routes subagents-stop with an id directly to the stop action", async () => {
2070
- const { params } = await captureSlashCommandParams("subagents-stop", "run-123", process.cwd());
2071
- assert.deepEqual(params, { action: "stop", id: "run-123" });
2072
- });
2073
-
2074
- it("detaches the latest active foreground single run without terminating it", async () => {
2075
- const commands = new Map<string, RegisteredSlashCommand>();
2076
- const sent: unknown[] = [];
2077
- const state = createState(process.cwd());
2078
- let detached = 0;
2079
- state.foregroundControls.set("foreground-single", {
2080
- runId: "foreground-single",
2081
- mode: "single",
2082
- startedAt: 1,
2083
- updatedAt: 2,
2084
- detach: () => { detached++; return true; },
2085
- });
2086
- state.foregroundControls.set("newer-parallel", {
2087
- runId: "newer-parallel",
2088
- mode: "parallel",
2089
- startedAt: 2,
2090
- updatedAt: 3,
2091
- });
2092
- state.lastForegroundControlId = "newer-parallel";
709
+ it("does not register legacy orchestration commands", async () => {
710
+ const commands = new Map<string, unknown>();
2093
711
  registerSlashCommands!({
2094
- events: createEventBus(),
2095
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
712
+ registerCommand(name: string, command: unknown) { commands.set(name, command); },
2096
713
  registerShortcut() {},
2097
- sendMessage(message: unknown) { sent.push(message); },
2098
- }, state);
2099
-
2100
- await commands.get("subagents-detach")!.handler("", createCommandContext());
2101
-
2102
- assert.equal(detached, 1);
2103
- const content = String((sent[0] as { content?: unknown }).content ?? "");
2104
- assert.match(content, /Detached foreground run foreground-single without terminating its child/);
2105
- assert.match(content, /does not daemonize the process or guarantee survival across Pi reload\/restart/);
2106
- });
2107
-
2108
- it("reports missing and unsupported foreground detach targets", async () => {
2109
- const commands = new Map<string, RegisteredSlashCommand>();
2110
- const notifications: string[] = [];
2111
- const state = createState(process.cwd());
2112
- state.foregroundControls.set("parallel-run", {
2113
- runId: "parallel-run",
2114
- mode: "parallel",
2115
- startedAt: 1,
2116
- updatedAt: 1,
2117
- detach: () => true,
2118
- });
2119
- registerSlashCommands!({
2120
714
  events: createEventBus(),
2121
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
2122
- registerShortcut() {},
2123
- sendMessage() {},
2124
- }, state);
2125
- const ctx = createCommandContext({ notify: (message) => notifications.push(message) });
2126
-
2127
- await commands.get("subagents-detach")!.handler("missing", ctx);
2128
- await commands.get("subagents-detach")!.handler("parallel", ctx);
2129
-
2130
- assert.match(notifications[0] ?? "", /No active foreground run found for 'missing'/);
2131
- assert.match(notifications[1] ?? "", /currently supports single-subagent runs only/);
2132
- });
2133
-
2134
- it("prints exact stop commands when subagents-stop has no UI", async () => {
2135
- await withIsolatedHome(async () => {
2136
- const runId = `slash-stop-${Date.now().toString(36)}`;
2137
- const asyncDir = path.join(ASYNC_DIR, runId);
2138
- fs.mkdirSync(asyncDir, { recursive: true });
2139
- fs.writeFileSync(path.join(asyncDir, "status.json"), JSON.stringify({
2140
- runId,
2141
- sessionId: "session-test",
2142
- mode: "single",
2143
- state: "running",
2144
- pid: process.pid,
2145
- startedAt: Date.now(),
2146
- lastUpdate: Date.now(),
2147
- steps: [{ agent: "worker", status: "running", startedAt: Date.now() }],
2148
- }, null, 2));
2149
- try {
2150
- const sent: unknown[] = [];
2151
- const commands = new Map<string, RegisteredSlashCommand>();
2152
- const pi = {
2153
- events: createEventBus(),
2154
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
2155
- registerShortcut() {},
2156
- sendMessage(message: unknown) { sent.push(message); },
2157
- };
2158
- const state = createState(process.cwd());
2159
- state.currentSessionId = "session-test";
2160
- registerSlashCommands!(pi, state);
2161
- await commands.get("subagents-stop")!.handler("", createCommandContext({ hasUI: false }));
2162
-
2163
- const content = String((sent[0] as { content?: unknown }).content ?? "");
2164
- assert.match(content, new RegExp(`subagent\\({ action: "stop", id: "${runId}" }\\)`));
2165
- assert.match(content, new RegExp(`/subagents-stop ${runId}`));
2166
- } finally {
2167
- fs.rmSync(asyncDir, { recursive: true, force: true });
2168
- }
2169
- });
2170
- });
2171
-
2172
- it("prints cancel commands for scheduled subagent runs when subagents-stop has no UI", async () => {
2173
- await withIsolatedHome(async () => {
2174
- await withTempProject("pi-slash-stop-scheduled-", async (root) => {
2175
- const storePath = scheduledRunStorePath(root, "session-test");
2176
- fs.mkdirSync(path.dirname(storePath), { recursive: true });
2177
- fs.writeFileSync(storePath, JSON.stringify({
2178
- version: 1,
2179
- cwd: root,
2180
- sessionId: "session-test",
2181
- jobs: [{
2182
- id: "job-1",
2183
- name: "nightly scout",
2184
- schedule: "+10m",
2185
- runAt: Date.now() + 600_000,
2186
- state: "scheduled",
2187
- createdAt: Date.now(),
2188
- updatedAt: Date.now(),
2189
- cwd: root,
2190
- sessionId: "session-test",
2191
- params: { agent: "scout", task: "later", async: true },
2192
- }],
2193
- }, null, 2));
2194
- const sent: unknown[] = [];
2195
- const commands = new Map<string, RegisteredSlashCommand>();
2196
- const state = createState(root);
2197
- state.currentSessionId = "session-test";
2198
- const pi = {
2199
- events: createEventBus(),
2200
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
2201
- registerShortcut() {},
2202
- sendMessage(message: unknown) { sent.push(message); },
2203
- };
2204
- registerSlashCommands!(pi, state);
2205
- await commands.get("subagents-stop")!.handler("", createCommandContext({ cwd: root, hasUI: false }));
2206
-
2207
- const content = String((sent[0] as { content?: unknown }).content ?? "");
2208
- assert.match(content, /job-1 · nightly scout/);
2209
- assert.match(content, /cancel scheduled run: subagent\({ action: "schedule-cancel", id: "job-1" }\)/);
2210
- assert.doesNotMatch(content, /\/subagents-stop job-1/);
2211
- });
2212
- });
715
+ } as never, { baseCwd: process.cwd() } as never);
716
+ assert.equal(commands.has("run"), true);
717
+ assert.equal(commands.has("chain"), false);
718
+ assert.equal(commands.has("parallel"), false);
719
+ assert.equal(commands.has("run-chain"), false);
2213
720
  });
2214
-
2215
- it("routes selected scheduled subagents-stop targets through schedule-cancel", async () => {
2216
- await withIsolatedHome(async () => {
2217
- await withTempProject("pi-slash-stop-selected-scheduled-", async (root) => {
2218
- const storePath = scheduledRunStorePath(root, "session-test");
2219
- fs.mkdirSync(path.dirname(storePath), { recursive: true });
2220
- fs.writeFileSync(storePath, JSON.stringify({
2221
- version: 1,
2222
- cwd: root,
2223
- sessionId: "session-test",
2224
- jobs: [{
2225
- id: "job-1",
2226
- name: "early scout",
2227
- schedule: "+5m",
2228
- runAt: Date.now() + 300_000,
2229
- state: "scheduled",
2230
- createdAt: Date.now(),
2231
- updatedAt: Date.now(),
2232
- cwd: root,
2233
- sessionId: "session-test",
2234
- params: { agent: "scout", task: "soon", async: true },
2235
- }, {
2236
- id: "job-2",
2237
- name: "delayed worker",
2238
- schedule: "+10m",
2239
- runAt: Date.now() + 600_000,
2240
- state: "scheduled",
2241
- createdAt: Date.now(),
2242
- updatedAt: Date.now(),
2243
- cwd: root,
2244
- sessionId: "session-test",
2245
- params: { agent: "worker", task: "later", async: true },
2246
- }],
2247
- }, null, 2));
2248
-
2249
- const commands = new Map<string, RegisteredSlashCommand>();
2250
- const events = createEventBus();
2251
- let requestedParams: unknown;
2252
- events.on(SLASH_SUBAGENT_REQUEST_EVENT, (data) => {
2253
- const payload = data as { requestId: string; params?: unknown };
2254
- requestedParams = payload.params;
2255
- events.emit(SLASH_SUBAGENT_STARTED_EVENT, { requestId: payload.requestId });
2256
- events.emit(SLASH_SUBAGENT_RESPONSE_EVENT, {
2257
- requestId: payload.requestId,
2258
- result: { content: [{ type: "text", text: "cancelled" }], details: { mode: "management", results: [] } },
2259
- isError: false,
2260
- });
2261
- });
2262
- const state = createState(root);
2263
- state.currentSessionId = "session-test";
2264
- const pi = {
2265
- events,
2266
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
2267
- registerShortcut() {},
2268
- sendMessage(_message: unknown) {},
2269
- };
2270
- registerSlashCommands!(pi, state);
2271
- await commands.get("subagents-stop")!.handler("", createCommandContext({
2272
- cwd: root,
2273
- hasUI: true,
2274
- custom: async (...args: unknown[]) => new Promise((resolve) => {
2275
- const factory = args[0] as (
2276
- tui: { requestRender(): void },
2277
- theme: { fg(key: string, text: string): string; bold(text: string): string },
2278
- keybindings: unknown,
2279
- done: (result: unknown) => void,
2280
- ) => { handleInput(data: string): void; render(width: number): string[] };
2281
- const component = factory(
2282
- { requestRender() {} },
2283
- { fg(_key, text) { return text; }, bold(text) { return text; } },
2284
- {},
2285
- resolve,
2286
- );
2287
- assert.match(component.render(84).join("\n"), /↑↓\/jk select/);
2288
- component.handleInput("j");
2289
- assert.ok(component.render(84).some((line) => line.startsWith("›") && line.includes("job-2")));
2290
- component.handleInput("k");
2291
- assert.ok(component.render(84).some((line) => line.startsWith("›") && line.includes("job-1")));
2292
- component.handleInput("j");
2293
- component.handleInput("\r");
2294
- component.handleInput("y");
2295
- }),
2296
- }));
2297
-
2298
- assert.deepEqual(requestedParams, { action: "schedule-cancel", id: "job-2" });
2299
- });
2300
- });
2301
- });
2302
-
2303
- it("prints fallback text instead of opening or enumerating the selector in child-safe fanout mode", async () => {
2304
- await withIsolatedHome(async () => {
2305
- const previous = process.env[SUBAGENT_FANOUT_CHILD_ENV];
2306
- const runId = `slash-stop-child-safe-${Date.now().toString(36)}`;
2307
- const asyncDir = path.join(ASYNC_DIR, runId);
2308
- process.env[SUBAGENT_FANOUT_CHILD_ENV] = "1";
2309
- fs.mkdirSync(asyncDir, { recursive: true });
2310
- fs.writeFileSync(path.join(asyncDir, "status.json"), JSON.stringify({
2311
- runId,
2312
- sessionId: "session-test",
2313
- mode: "single",
2314
- state: "running",
2315
- pid: process.pid,
2316
- startedAt: Date.now(),
2317
- lastUpdate: Date.now(),
2318
- steps: [{ agent: "worker", status: "running", startedAt: Date.now() }],
2319
- }, null, 2));
2320
- try {
2321
- const sent: unknown[] = [];
2322
- const commands = new Map<string, RegisteredSlashCommand>();
2323
- const pi = {
2324
- events: createEventBus(),
2325
- registerCommand(name: string, spec: RegisteredSlashCommand) { commands.set(name, spec); },
2326
- registerShortcut() {},
2327
- sendMessage(message: unknown) { sent.push(message); },
2328
- };
2329
- const state = createState(process.cwd());
2330
- state.currentSessionId = "session-test";
2331
- registerSlashCommands!(pi, state);
2332
- await commands.get("subagents-stop")!.handler("", createCommandContext({ hasUI: true }));
2333
-
2334
- const content = String((sent[0] as { content?: unknown }).content ?? "");
2335
- assert.match(content, /Selector unavailable in child-safe fanout mode\./);
2336
- assert.doesNotMatch(content, new RegExp(runId));
2337
- } finally {
2338
- fs.rmSync(asyncDir, { recursive: true, force: true });
2339
- if (previous === undefined) delete process.env[SUBAGENT_FANOUT_CHILD_ENV];
2340
- else process.env[SUBAGENT_FANOUT_CHILD_ENV] = previous;
2341
- }
2342
- });
2343
- });
2344
-
2345
- it("does not register the removed subagents-status overlay command", async () => {
2346
- await withIsolatedHome(async () => {
2347
- const commands = new Map<string, RegisteredSlashCommand>();
2348
- const pi = {
2349
- events: createEventBus(),
2350
- registerCommand(name: string, spec: RegisteredSlashCommand) {
2351
- commands.set(name, spec);
2352
- },
2353
- registerShortcut() {},
2354
- sendMessage(_message: unknown) {},
2355
- };
2356
-
2357
- registerSlashCommands!(pi, createState(process.cwd()));
2358
- assert.equal(commands.has("subagents-status"), false);
2359
- });
2360
- });
2361
-
2362
721
  });