@selesai/code 0.9.11 → 0.9.12

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 (580) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/config.d.ts +4 -6
  3. package/dist/config.js +10 -14
  4. package/dist/core/agent-session.d.ts +0 -1
  5. package/dist/core/agent-session.js +3 -49
  6. package/dist/core/extensions/types.d.ts +0 -2
  7. package/dist/core/settings-manager.d.ts +0 -2
  8. package/dist/core/settings-manager.js +0 -3
  9. package/dist/core/tools/index.d.ts +0 -1
  10. package/dist/core/tools/index.js +0 -1
  11. package/dist/defaults/settings.json +0 -1
  12. package/dist/extensions/model-prompt-injector/index.test.ts +0 -10
  13. package/dist/extensions/model-prompt-injector/index.ts +0 -3
  14. package/dist/extensions/pi-intercom/CHANGELOG.md +53 -16
  15. package/dist/extensions/pi-intercom/README.md +41 -8
  16. package/dist/extensions/pi-intercom/banner.png +0 -0
  17. package/dist/extensions/pi-intercom/broker/broker.ts +498 -215
  18. package/dist/extensions/pi-intercom/broker/client.ts +39 -12
  19. package/dist/extensions/pi-intercom/broker/extension.test.ts +102 -3
  20. package/dist/extensions/pi-intercom/broker/paths.test.ts +2 -2
  21. package/dist/extensions/pi-intercom/broker/protocol.ts +26 -0
  22. package/dist/extensions/pi-intercom/broker/spawn.test.ts +5 -20
  23. package/dist/extensions/pi-intercom/config.test.ts +41 -0
  24. package/dist/extensions/pi-intercom/config.ts +21 -0
  25. package/dist/extensions/pi-intercom/extension-api.ts +40 -0
  26. package/dist/extensions/pi-intercom/index.ts +362 -26
  27. package/dist/extensions/pi-intercom/intercom.integration.test.ts +819 -13
  28. package/dist/extensions/pi-intercom/package.json +1 -1
  29. package/dist/extensions/pi-intercom/project-agent.ts +2 -2
  30. package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +8 -110
  31. package/dist/extensions/pi-intercom/types.ts +32 -5
  32. package/dist/extensions/pi-intercom/ui/inline-message.ts +6 -0
  33. package/dist/extensions/pi-subagents/.github/assets/subagent-fleet-inspector.png +0 -0
  34. package/dist/extensions/pi-subagents/.github/workflows/release.yml +28 -0
  35. package/dist/extensions/pi-subagents/.github/workflows/test.yml +51 -0
  36. package/dist/extensions/pi-subagents/.greptile/config.json +33 -0
  37. package/dist/extensions/pi-subagents/.greptile/files.json +8 -0
  38. package/dist/extensions/pi-subagents/.greptile/rules.md +16 -0
  39. package/dist/extensions/pi-subagents/CHANGELOG.md +309 -87
  40. package/dist/extensions/pi-subagents/README.md +15 -17
  41. package/dist/extensions/pi-subagents/agents/oracle.md +3 -1
  42. package/dist/extensions/pi-subagents/agents/researcher.md +32 -13
  43. package/dist/extensions/pi-subagents/agents/reviewer.md +13 -2
  44. package/dist/extensions/pi-subagents/agents/scout.md +2 -2
  45. package/dist/extensions/pi-subagents/agents/worker.md +2 -1
  46. package/dist/extensions/pi-subagents/async-retention-discovery-worker.mjs +180 -0
  47. package/dist/extensions/pi-subagents/docs/configuration.md +106 -27
  48. package/dist/extensions/pi-subagents/docs/extension-api.md +85 -21
  49. package/dist/extensions/pi-subagents/docs/missions.md +41 -4
  50. package/dist/extensions/pi-subagents/docs/models.md +52 -9
  51. package/dist/extensions/pi-subagents/docs/observability.md +103 -16
  52. package/dist/extensions/pi-subagents/docs/tool-reference.md +60 -45
  53. package/dist/extensions/pi-subagents/docs/watchdog.md +60 -3
  54. package/dist/extensions/pi-subagents/docs/workflows.md +181 -7
  55. package/dist/extensions/pi-subagents/index.ts +10 -1
  56. package/dist/extensions/pi-subagents/install.mjs +4 -4
  57. package/dist/extensions/pi-subagents/package-lock.json +1483 -1470
  58. package/dist/extensions/pi-subagents/package.json +6 -3
  59. package/dist/extensions/pi-subagents/prompts/council.md +60 -0
  60. package/dist/extensions/pi-subagents/prompts/parallel-review.md +5 -1
  61. package/dist/extensions/pi-subagents/prompts/review-loop.md +9 -5
  62. package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +254 -0
  63. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +18 -17
  64. package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +31 -9
  65. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +107 -140
  66. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +9 -12
  67. package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +39 -0
  68. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +44 -92
  69. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +261 -368
  70. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +6 -2
  71. package/dist/extensions/pi-subagents/src/agents/agents.ts +388 -85
  72. package/dist/extensions/pi-subagents/src/agents/builtin-names.ts +14 -0
  73. package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +418 -0
  74. package/dist/extensions/pi-subagents/src/agents/skills.ts +1 -1
  75. package/dist/extensions/pi-subagents/src/api/agents.ts +7 -0
  76. package/dist/extensions/pi-subagents/src/api/external-job-provider.ts +195 -0
  77. package/dist/extensions/pi-subagents/src/api/preflight.ts +88 -27
  78. package/dist/extensions/pi-subagents/src/api/project-panes.ts +2 -0
  79. package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -0
  80. package/dist/extensions/pi-subagents/src/extension/config.ts +20 -11
  81. package/dist/extensions/pi-subagents/src/extension/doctor.ts +14 -6
  82. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +5 -4
  83. package/dist/extensions/pi-subagents/src/extension/index.ts +270 -187
  84. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +65 -28
  85. package/dist/extensions/pi-subagents/src/extension/rpc.ts +120 -11
  86. package/dist/extensions/pi-subagents/src/extension/schemas.ts +46 -64
  87. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +51 -37
  88. package/dist/extensions/pi-subagents/src/extension/tool-result.ts +19 -0
  89. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +2 -2
  90. package/dist/extensions/pi-subagents/src/inspectors/herdr/client.ts +3 -3
  91. package/dist/extensions/pi-subagents/src/inspectors/herdr/focus.ts +55 -0
  92. package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +2 -1
  93. package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +230 -46
  94. package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +26 -4
  95. package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +32 -10
  96. package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +6 -1
  97. package/dist/extensions/pi-subagents/src/missions/store.ts +4 -9
  98. package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +2 -2
  99. package/dist/extensions/pi-subagents/src/policy/authority.ts +2 -0
  100. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +3 -1
  101. package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +31 -8
  102. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +210 -52
  103. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +63 -33
  104. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +71 -17
  105. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +886 -0
  106. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +14 -5
  107. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +49 -56
  108. package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +1 -0
  109. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +3 -33
  110. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +5 -0
  111. package/dist/extensions/pi-subagents/src/runs/background/completion-dedupe.ts +5 -1
  112. package/dist/extensions/pi-subagents/src/runs/background/completion-replay.ts +22 -12
  113. package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +105 -71
  114. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +68 -19
  115. package/dist/extensions/pi-subagents/src/runs/background/index-segment.ts +59 -0
  116. package/dist/extensions/pi-subagents/src/runs/background/inspect-rpc.ts +443 -0
  117. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +94 -10
  118. package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +158 -90
  119. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +141 -53
  120. package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +8 -5
  121. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +14 -4
  122. package/dist/extensions/pi-subagents/src/runs/background/run-id-query.ts +7 -0
  123. package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +13 -14
  124. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +46 -25
  125. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +823 -0
  126. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +9 -3
  127. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +11 -1
  128. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +594 -216
  129. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +17 -13
  130. package/dist/extensions/pi-subagents/src/runs/background/terminal-run-index.ts +138 -0
  131. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +23 -4
  132. package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +82 -4
  133. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +5 -3
  134. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +21 -14
  135. package/dist/extensions/pi-subagents/src/runs/foreground/async-stop-action.ts +23 -2
  136. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +153 -58
  137. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +7 -9
  138. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1283 -1657
  139. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +274 -0
  140. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +6 -5
  141. package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +59 -10
  142. package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
  143. package/dist/extensions/pi-subagents/src/runs/shared/chain-outputs.ts +1 -3
  144. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +36 -0
  145. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +52 -2
  146. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
  147. package/dist/extensions/pi-subagents/src/runs/shared/extension-bindings.ts +78 -0
  148. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +2 -0
  149. package/dist/extensions/pi-subagents/src/runs/shared/external-job-bridge.ts +460 -0
  150. package/dist/extensions/pi-subagents/src/runs/shared/external-job-runner.ts +389 -0
  151. package/dist/extensions/pi-subagents/src/runs/shared/fast-mode-extension.ts +10 -0
  152. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +14 -0
  153. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +243 -0
  154. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +201 -85
  155. package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +106 -39
  156. package/dist/extensions/pi-subagents/src/runs/shared/mutation-evidence.ts +145 -0
  157. package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +150 -27
  158. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +46 -4
  159. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +19 -15
  160. package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +5 -1
  161. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +86 -2
  162. package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +9 -9
  163. package/dist/extensions/pi-subagents/src/runs/shared/session-lease.ts +0 -6
  164. package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +18 -4
  165. package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +51 -7
  166. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +62 -21
  167. package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +1 -3
  168. package/dist/extensions/pi-subagents/src/runs/shared/tool-timeout.ts +1 -3
  169. package/dist/extensions/pi-subagents/src/runs/shared/workflow-graph.ts +1 -23
  170. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +14 -2
  171. package/dist/extensions/pi-subagents/src/shared/artifacts.ts +2 -2
  172. package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +22 -2
  173. package/dist/extensions/pi-subagents/src/shared/capacity-resilient-json.ts +102 -0
  174. package/dist/extensions/pi-subagents/src/shared/completion-owner.ts +14 -0
  175. package/dist/extensions/pi-subagents/src/shared/file-system-retry.ts +49 -1
  176. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +59 -1
  177. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +12 -5
  178. package/dist/extensions/pi-subagents/src/shared/model-info.ts +20 -0
  179. package/dist/extensions/pi-subagents/src/shared/prompt-resources.ts +0 -40
  180. package/dist/extensions/pi-subagents/src/shared/settings.ts +11 -30
  181. package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +52 -0
  182. package/dist/extensions/pi-subagents/src/shared/types.ts +228 -49
  183. package/dist/extensions/pi-subagents/src/shared/utils.ts +11 -3
  184. package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +10 -0
  185. package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +0 -162
  186. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +2 -5
  187. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +105 -13
  188. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +6 -36
  189. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +829 -0
  190. package/dist/extensions/pi-subagents/src/tui/fleet.ts +1415 -0
  191. package/dist/extensions/pi-subagents/src/tui/render.ts +78 -7
  192. package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +1 -1
  193. package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +1 -0
  194. package/dist/extensions/pi-subagents/src/watchdog/permission-arbiter.ts +59 -51
  195. package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +8 -2
  196. package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +2 -1
  197. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +4 -4
  198. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +471 -86
  199. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +140 -0
  200. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +2 -2
  201. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
  202. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
  203. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
  204. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
  205. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
  206. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
  207. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
  208. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
  209. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
  210. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
  211. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
  212. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
  213. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
  214. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
  215. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
  216. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
  217. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
  218. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
  219. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
  220. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
  221. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
  222. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
  223. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
  224. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
  225. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
  226. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
  227. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
  228. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
  229. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
  230. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
  231. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
  232. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
  233. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
  234. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
  235. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
  236. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
  237. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
  238. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
  239. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
  240. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
  241. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
  242. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
  243. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
  244. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
  245. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
  246. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
  247. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
  248. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
  249. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
  250. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
  251. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
  252. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
  253. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
  254. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
  255. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
  256. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
  257. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
  258. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
  259. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
  260. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
  261. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
  262. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
  263. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
  264. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
  265. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
  266. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
  267. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
  268. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
  269. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
  270. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
  271. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
  272. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
  273. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
  274. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
  275. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
  276. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
  277. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
  278. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
  279. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
  280. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
  281. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  282. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
  283. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
  284. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
  285. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
  286. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
  287. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
  288. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
  289. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
  290. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
  291. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
  292. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
  293. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
  294. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
  295. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
  296. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
  297. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
  298. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  299. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  300. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  301. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  302. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
  303. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  304. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  305. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
  306. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
  307. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  308. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
  309. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  310. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  311. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
  312. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
  313. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  314. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
  315. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
  316. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
  317. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  318. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
  319. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
  320. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
  321. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  322. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  323. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
  324. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
  325. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  326. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  327. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
  328. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  329. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  330. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  331. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
  332. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
  333. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  334. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
  335. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  336. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
  337. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
  338. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
  339. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
  340. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
  341. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
  342. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
  343. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
  344. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
  345. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
  346. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
  347. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
  348. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
  349. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
  350. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
  351. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
  352. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
  353. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
  354. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
  355. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
  356. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
  357. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
  358. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
  359. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
  360. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
  361. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
  362. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
  363. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
  364. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
  365. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
  366. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
  367. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
  368. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
  369. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
  370. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
  371. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
  372. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
  373. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
  374. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
  375. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
  376. package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/index.mjs +1 -1
  377. package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +0 -54
  378. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1053 -414
  379. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +194 -4
  380. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +59 -4
  381. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +0 -77
  382. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +107 -6
  383. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +211 -897
  384. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +265 -375
  385. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +77 -7
  386. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +1 -1
  387. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +10 -10
  388. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +547 -30
  389. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +2112 -310
  390. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +274 -34
  391. package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +1 -1
  392. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +20 -3
  393. package/dist/extensions/pi-subagents/test/support/isolated-temp-root.mjs +9 -0
  394. package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +30 -5
  395. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +2 -0
  396. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +4 -2
  397. package/dist/extensions/pi-subagents/test/support/register-loader.mjs +1 -0
  398. package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +197 -0
  399. package/dist/extensions/pi-subagents/test/unit/agent-contract.test.ts +14 -0
  400. package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -1
  401. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +204 -27
  402. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +444 -145
  403. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +256 -4
  404. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +9 -7
  405. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +152 -22
  406. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +29 -0
  407. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +205 -23
  408. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +579 -0
  409. package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +24 -0
  410. package/dist/extensions/pi-subagents/test/unit/authority-policy.test.ts +1 -0
  411. package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +3 -3
  412. package/dist/extensions/pi-subagents/test/unit/capacity-resilient-json.test.ts +155 -0
  413. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +2 -2
  414. package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +7 -0
  415. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +123 -0
  416. package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +81 -3
  417. package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +109 -7
  418. package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +2 -2
  419. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +5 -2
  420. package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +3 -2
  421. package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +79 -0
  422. package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +22 -0
  423. package/dist/extensions/pi-subagents/test/unit/external-job-runner.test.ts +961 -0
  424. package/dist/extensions/pi-subagents/test/unit/file-system-retry.test.ts +64 -0
  425. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +1110 -0
  426. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +1664 -0
  427. package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +81 -1
  428. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +138 -11
  429. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +41 -2
  430. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +210 -79
  431. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +95 -0
  432. package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +596 -0
  433. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
  434. package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +3 -5
  435. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +167 -0
  436. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +319 -18
  437. package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +78 -0
  438. package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +19 -5
  439. package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +44 -0
  440. package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +129 -0
  441. package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +231 -2
  442. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +28 -1
  443. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +106 -2
  444. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +204 -7
  445. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +59 -4
  446. package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +2 -6
  447. package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +34 -2
  448. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +116 -6
  449. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +12 -3
  450. package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +56 -61
  451. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +416 -1
  452. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +9 -2
  453. package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +42 -0
  454. package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +21 -30
  455. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +86 -11
  456. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +49 -1
  457. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +233 -5
  458. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +28 -5
  459. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +323 -20
  460. package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +66 -10
  461. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +68 -5
  462. package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +174 -0
  463. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +679 -0
  464. package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +67 -0
  465. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +55 -44
  466. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +399 -84
  467. package/dist/extensions/pi-subagents/test/unit/session-lease.test.ts +13 -0
  468. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
  469. package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +15 -10
  470. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +11 -7
  471. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -0
  472. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +40 -1
  473. package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +10 -2
  474. package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +38 -3
  475. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +110 -12
  476. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +204 -19
  477. package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +25 -0
  478. package/dist/extensions/pi-subagents/test/unit/thinking-ceiling.test.ts +73 -0
  479. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +90 -50
  480. package/dist/extensions/pi-subagents/test/unit/tool-timeout.test.ts +1 -2
  481. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +234 -7
  482. package/dist/extensions/pi-subagents/test/unit/watch-strategy.test.ts +24 -0
  483. package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +36 -0
  484. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +37 -9
  485. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +302 -0
  486. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +167 -7
  487. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +113 -0
  488. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +6 -6
  489. package/dist/extensions/ponytail/index.js +31 -25
  490. package/dist/extensions/ponytail/ponytail-config.cjs +34 -7
  491. package/dist/extensions/ponytail/ponytail-instructions.cjs +7 -9
  492. package/dist/extensions/ponytail/test/extension.test.js +7 -8
  493. package/dist/extensions/ponytail/test/helpers.test.js +1 -1
  494. package/dist/skills/brandkit/SKILL.md +799 -0
  495. package/dist/skills/design-taste-frontend/SKILL.md +1207 -0
  496. package/dist/skills/design-taste-frontend-v1/SKILL.md +227 -0
  497. package/dist/skills/full-output-enforcement/SKILL.md +50 -0
  498. package/dist/skills/gpt-taste/SKILL.md +75 -0
  499. package/dist/skills/high-end-visual-design/SKILL.md +99 -0
  500. package/dist/skills/image-to-code/SKILL.md +1229 -0
  501. package/dist/skills/imagegen-frontend-mobile/SKILL.md +1466 -0
  502. package/dist/skills/imagegen-frontend-web/SKILL.md +988 -0
  503. package/dist/skills/industrial-brutalist-ui/SKILL.md +93 -0
  504. package/dist/skills/minimalist-ui/SKILL.md +86 -0
  505. package/dist/skills/pi-subagents/SKILL.md +18 -17
  506. package/dist/skills/pi-subagents/references/constraints-and-recipes.md +31 -9
  507. package/dist/skills/pi-subagents/references/execution-controls.md +95 -143
  508. package/dist/skills/pi-subagents/references/management-authoring-rpc.md +9 -12
  509. package/dist/skills/pi-subagents/references/multi-lane-orchestration.md +39 -0
  510. package/dist/skills/pi-subagents/references/prompting-and-roles.md +45 -94
  511. package/dist/skills/ponytail/SKILL.md +12 -8
  512. package/dist/skills/ponytail-audit/SKILL.md +0 -1
  513. package/dist/skills/ponytail-debt/SKILL.md +0 -1
  514. package/dist/skills/ponytail-gain/SKILL.md +0 -1
  515. package/dist/skills/ponytail-help/SKILL.md +4 -3
  516. package/dist/skills/ponytail-review/SKILL.md +0 -1
  517. package/dist/skills/redesign-existing-projects/SKILL.md +179 -0
  518. package/dist/skills/stitch-design-taste/SKILL.md +185 -0
  519. package/dist/skills/unlazy/CHANGELOG.md +100 -0
  520. package/dist/skills/unlazy/CONTRIBUTING.md +66 -0
  521. package/dist/skills/unlazy/LICENSE +21 -0
  522. package/dist/skills/unlazy/README.md +242 -0
  523. package/dist/skills/unlazy/SECURITY.md +70 -0
  524. package/dist/skills/unlazy/SKILL.md +100 -0
  525. package/dist/skills/unlazy/package.json +13 -0
  526. package/dist/skills/unlazy/references/dispatch.md +82 -0
  527. package/dist/skills/unlazy/references/gates.md +132 -0
  528. package/dist/skills/unlazy/references/method.md +49 -0
  529. package/dist/skills/unlazy/references/orchestration.md +99 -0
  530. package/dist/skills/unlazy/references/parallel.md +123 -0
  531. package/dist/skills/unlazy/references/token-economy.md +39 -0
  532. package/dist/skills/unlazy/research/validation-protocol.md +81 -0
  533. package/dist/skills/unlazy/scripts/dispatch-check.mjs +108 -0
  534. package/dist/skills/unlazy/scripts/gate-check.mjs +894 -0
  535. package/dist/skills/unlazy/scripts/gate-lint.mjs +178 -0
  536. package/dist/skills/unlazy/scripts/install-hooks.mjs +206 -0
  537. package/dist/skills/unlazy/scripts/lib/check-supervisor.mjs +46 -0
  538. package/dist/skills/unlazy/scripts/lib/dispatch.mjs +283 -0
  539. package/dist/skills/unlazy/scripts/lib/gates.mjs +629 -0
  540. package/dist/skills/unlazy/scripts/lib/process-tree.mjs +161 -0
  541. package/dist/skills/unlazy/scripts/lib/regex-worker.mjs +9 -0
  542. package/dist/skills/unlazy/scripts/stop-hook.mjs +174 -0
  543. package/dist/skills/unlazy/templates/PLAN.md +65 -0
  544. package/dist/skills/unlazy/templates/gates-leaf.md +51 -0
  545. package/dist/skills/unlazy/templates/gates-node.md +50 -0
  546. package/dist/skills/unlazy/tests/contract-tests.mjs +127 -0
  547. package/dist/skills/unlazy/tests/dispatch-tests.mjs +481 -0
  548. package/dist/skills/unlazy/tests/hardening-tests.mjs +903 -0
  549. package/dist/skills/unlazy/tests/lint-tests.mjs +242 -0
  550. package/dist/skills/unlazy/tests/run-tests.mjs +554 -0
  551. package/dist/skills/unlazy/tests/self-check.mjs +165 -0
  552. package/dist/skills/unlazy/tests/stress-tests.mjs +356 -0
  553. package/dist/skills/web-design-guidelines/SKILL.md +40 -0
  554. package/docs/settings.md +0 -5
  555. package/package.json +1 -1
  556. package/dist/core/tools/schema-prune.d.ts +0 -16
  557. package/dist/core/tools/schema-prune.js +0 -39
  558. package/dist/core/tools/schema-prune.test.d.ts +0 -1
  559. package/dist/core/tools/schema-prune.test.js +0 -111
  560. package/dist/extensions/pi-subagents/UPSTREAM-V0.50-MAPPING.md +0 -172
  561. package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +0 -55
  562. package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +0 -61
  563. package/dist/extensions/pi-subagents/src/agents/task-aware-routing.ts +0 -132
  564. package/dist/extensions/pi-subagents/src/extension/chain-validation.ts +0 -181
  565. package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +0 -1354
  566. package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +0 -1581
  567. package/dist/extensions/pi-subagents/src/shared/env.ts +0 -16
  568. package/dist/extensions/pi-subagents/src/shared/session-lineage.ts +0 -71
  569. package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +0 -136
  570. package/dist/extensions/pi-subagents/src/workflows/workflow-auto-relaunch.ts +0 -41
  571. package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +0 -466
  572. package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +0 -1859
  573. package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +0 -733
  574. package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +0 -63
  575. package/dist/extensions/pi-subagents/test/unit/chain-validation.test.ts +0 -326
  576. package/dist/extensions/pi-subagents/test/unit/handoff-adoption.test.ts +0 -103
  577. package/dist/extensions/pi-subagents/test/unit/inline-subagents.test.ts +0 -127
  578. package/dist/extensions/pi-subagents/test/unit/session-lineage.test.ts +0 -73
  579. package/dist/extensions/pi-subagents/test/unit/task-aware-routing.test.ts +0 -213
  580. package/dist/extensions/pi-subagents/test/unit/workflow-auto-relaunch.test.ts +0 -65
@@ -3,8 +3,11 @@ import * as fs from "node:fs";
3
3
  import * as os from "node:os";
4
4
  import * as path from "node:path";
5
5
  import { afterEach, beforeEach, describe, it } from "node:test";
6
- import { handleCreate, handleList, handleManagementAction, handleUpdate } from "../../src/agents/agent-management.ts";
6
+ import { editableAgentConfig, handleCreate, handleList, handleManagementAction, handleUpdate } from "../../src/agents/agent-management.ts";
7
+ import { EXTRA_AGENT_DIRS_ENV } from "../../src/agents/agents.ts";
8
+ import { EXTERNAL_JOB_PROVIDER_REGISTRY_KEY, registerExternalJobProvider } from "../../src/api/external-job-provider.ts";
7
9
  import { clearSkillCache } from "../../src/agents/skills.ts";
10
+ import { SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV } from "../../src/shared/utils.ts";
8
11
 
9
12
  let tempDir = "";
10
13
  let oldAgentDir: string | undefined;
@@ -57,6 +60,37 @@ describe("agent management config parsing", () => {
57
60
  assert.doesNotMatch(readText(result), /- scout \(builtin/);
58
61
  });
59
62
 
63
+ it("lists valid agents and diagnoses malformed agent definitions", () => {
64
+ const agentsDir = path.join(tempDir, ".selesai", "agents");
65
+ fs.mkdirSync(agentsDir, { recursive: true });
66
+ fs.writeFileSync(path.join(agentsDir, "broken.md"), "---\nname: broken\ndescription: Broken\nrunner:\n type: unknown\n---\nBroken agent.\n");
67
+ fs.writeFileSync(path.join(agentsDir, "working.md"), "---\nname: working\ndescription: Working\n---\nWorking agent.\n");
68
+ const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
69
+
70
+ const listed = handleList({}, ctx);
71
+ assert.equal(listed.isError, false);
72
+ assert.match(readText(listed), /- working \(project/);
73
+ assert.match(readText(listed), /Invalid agent definitions:\n- broken \(project\): Agent 'broken' has invalid runner\.type/);
74
+
75
+ const invalid = handleManagementAction("get", { agent: "broken" }, ctx);
76
+ assert.equal(invalid.isError, true);
77
+ assert.match(readText(invalid), /Agent 'broken' has invalid configuration: Agent 'broken' has invalid runner\.type/);
78
+ fs.writeFileSync(path.join(agentsDir, "bad-agent.md"), "---\nname: bad-agent\ndescription: Bad agent\nrunner:\n type: unknown\n---\nBroken agent.\n");
79
+ const normalizedInvalid = handleManagementAction("get", { agent: "Bad Agent" }, ctx);
80
+ assert.equal(normalizedInvalid.isError, true);
81
+ assert.match(readText(normalizedInvalid), /Agent 'Bad Agent' has invalid configuration: Agent 'bad-agent' has invalid runner\.type/);
82
+
83
+ fs.writeFileSync(path.join(agentsDir, "code-analysis.zeta-worker.md"), "---\nname: zeta-worker\npackage: code-analysis\ndescription: Broken packaged worker\nrunner:\n type: unknown\n---\nBroken agent.\n");
84
+ const invalidPackaged = handleManagementAction("get", { agent: "code-analysis.zeta-worker" }, ctx);
85
+ assert.equal(invalidPackaged.isError, true);
86
+ assert.match(readText(invalidPackaged), /Agent 'code-analysis\.zeta-worker' has invalid configuration: Agent 'zeta-worker' has invalid runner\.type/);
87
+
88
+ fs.writeFileSync(path.join(agentsDir, "reviewer.md"), "---\nname: reviewer\ndescription: Broken reviewer\nrunner:\n type: unknown\n---\nBroken agent.\n");
89
+ const invalidShadow = handleManagementAction("get", { agent: "reviewer" }, ctx);
90
+ assert.equal(invalidShadow.isError, true);
91
+ assert.match(readText(invalidShadow), /Agent 'reviewer' has invalid configuration: Agent 'reviewer' has invalid runner\.type/);
92
+ });
93
+
60
94
  it("gets only the effective agent detail and respects explicit scope", () => {
61
95
  const projectAgentsDir = path.join(tempDir, ".selesai", "agents");
62
96
  const userAgentsDir = path.join(tempDir, "agent-home", "agents");
@@ -64,16 +98,10 @@ describe("agent management config parsing", () => {
64
98
  fs.mkdirSync(projectAgentsDir, { recursive: true });
65
99
  fs.mkdirSync(userAgentsDir, { recursive: true });
66
100
  fs.mkdirSync(path.join(packageDir, "agents"), { recursive: true });
67
- fs.mkdirSync(path.join(packageDir, "chains"), { recursive: true });
68
101
  fs.writeFileSync(path.join(projectAgentsDir, "worker.md"), "---\nname: worker\ndescription: Project worker override\n---\n\nProject worker.\n");
69
102
  fs.writeFileSync(path.join(userAgentsDir, "worker.md"), "---\nname: worker\ndescription: User worker override\n---\n\nUser worker.\n");
70
- fs.writeFileSync(path.join(packageDir, "package.json"), JSON.stringify({ "pi-subagents": { agents: ["agents"], chains: ["chains"] } }));
103
+ fs.writeFileSync(path.join(packageDir, "package.json"), JSON.stringify({ "pi-subagents": { agents: ["agents"] } }));
71
104
  fs.writeFileSync(path.join(packageDir, "agents", "worker.md"), "---\nname: worker\ndescription: Package worker override\n---\n\nPackage worker.\n");
72
- fs.writeFileSync(path.join(packageDir, "chains", "package-flow.chain.json"), JSON.stringify({
73
- name: "package-flow",
74
- description: "Package flow",
75
- chain: [{ agent: "worker", task: "Package task" }],
76
- }), "utf-8");
77
105
  const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
78
106
 
79
107
  const effective = readText(handleManagementAction("get", { agent: "worker" }, ctx));
@@ -86,35 +114,238 @@ describe("agent management config parsing", () => {
86
114
  assert.match(userScoped, /Description: User worker override/);
87
115
  assert.doesNotMatch(userScoped, /Project worker override|Implementation agent for normal tasks/);
88
116
 
89
- const userChainsDir = path.join(tempDir, "agent-home", "chains");
90
- const projectChainsDir = path.join(tempDir, ".selesai", "chains");
91
- fs.mkdirSync(userChainsDir, { recursive: true });
92
- fs.mkdirSync(projectChainsDir, { recursive: true });
93
- fs.writeFileSync(path.join(userChainsDir, "shared-flow.chain.json"), JSON.stringify({
94
- name: "shared-flow",
95
- description: "User shared flow",
96
- chain: [{ agent: "worker", task: "User flow" }],
97
- }), "utf-8");
98
- fs.writeFileSync(path.join(projectChainsDir, "shared-flow.chain.json"), JSON.stringify({
99
- name: "shared-flow",
100
- description: "Project shared flow",
101
- chain: [{ agent: "worker", task: "Project flow" }],
102
- }), "utf-8");
103
-
104
- const userChain = readText(handleManagementAction("get", { chainName: "shared-flow", agentScope: "user" }, ctx));
105
- assert.match(userChain, /Chain: shared-flow \(user\)/);
106
- assert.match(userChain, /Description: User shared flow/);
107
- assert.doesNotMatch(userChain, /Project shared flow|Project flow/);
108
-
109
- const projectChain = readText(handleManagementAction("get", { chainName: "shared-flow", agentScope: "project" }, ctx));
110
- assert.match(projectChain, /Chain: shared-flow \(project\)/);
111
- assert.match(projectChain, /Description: Project shared flow/);
112
- assert.doesNotMatch(projectChain, /User shared flow|User flow/);
113
-
114
- for (const agentScope of ["user", "project"] as const) {
115
- const packageChain = readText(handleManagementAction("get", { chainName: "package-flow", agentScope }, ctx));
116
- assert.match(packageChain, /Chain: package-flow \(package\)/);
117
- assert.match(packageChain, /Description: Package flow/);
117
+ });
118
+
119
+ it("surfaces package source and external-job provider status in list and get", () => {
120
+ const packageDir = path.join(tempDir, ".selesai", "npm", "node_modules", "test-surf");
121
+ fs.mkdirSync(path.join(packageDir, "agents"), { recursive: true });
122
+ fs.writeFileSync(path.join(packageDir, "package.json"), JSON.stringify({
123
+ name: "test-surf",
124
+ version: "9.8.7",
125
+ pi: { subagents: { agents: ["agents"] } },
126
+ }));
127
+ fs.writeFileSync(path.join(packageDir, "agents", "gpt-pro.md"), `---
128
+ name: gpt-pro
129
+ description: ChatGPT Pro advisor via Surf
130
+ runner:
131
+ type: external-job
132
+ provider: test-surf-oracle
133
+ options:
134
+ model: pro
135
+ async: true
136
+ ---
137
+ Advise only.
138
+ `);
139
+ const dispose = registerExternalJobProvider({
140
+ name: "test-surf-oracle",
141
+ start: () => ({ providerJobId: "job", state: "completed" }),
142
+ status: () => ({ providerJobId: "job", state: "completed" }),
143
+ result: () => ({ providerJobId: "job", state: "completed", output: "ok" }),
144
+ reattach: () => ({ providerJobId: "job", state: "completed" }),
145
+ });
146
+ try {
147
+ const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
148
+ const listed = readText(handleList({}, ctx));
149
+ assert.match(listed, /Package agents/);
150
+ assert.match(listed, /- gpt-pro \(test-surf@9\.8\.7, external-job:test-surf-oracle ✓\): ChatGPT Pro advisor via Surf/);
151
+
152
+ const detail = readText(handleManagementAction("get", { agent: "gpt-pro" }, ctx));
153
+ assert.match(detail, /Source package: test-surf@9\.8\.7/);
154
+ assert.match(detail, new RegExp(`Package root: ${packageDir.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`));
155
+ assert.match(detail, /Runner: external-job via test-surf-oracle ✓/);
156
+ assert.match(detail, /Runner options: {"model":"pro"}/);
157
+ } finally {
158
+ dispose();
159
+ }
160
+ });
161
+
162
+ it("keeps external-job provider registry errors visible", () => {
163
+ const packageDir = path.join(tempDir, ".selesai", "npm", "node_modules", "test-surf");
164
+ fs.mkdirSync(path.join(packageDir, "agents"), { recursive: true });
165
+ fs.writeFileSync(path.join(packageDir, "package.json"), JSON.stringify({
166
+ name: "test-surf",
167
+ version: "9.8.7",
168
+ pi: { subagents: { agents: ["agents"] } },
169
+ }));
170
+ fs.writeFileSync(path.join(packageDir, "agents", "gpt-pro.md"), `---
171
+ name: gpt-pro
172
+ description: ChatGPT Pro advisor via Surf
173
+ runner:
174
+ type: external-job
175
+ provider: test-surf-oracle
176
+ ---
177
+ Advise only.
178
+ `);
179
+ const key = Symbol.for(EXTERNAL_JOB_PROVIDER_REGISTRY_KEY);
180
+ const globals = globalThis as Record<PropertyKey, unknown>;
181
+ const previous = globals[key];
182
+ globals[key] = { version: 0, providers: new Map() };
183
+ try {
184
+ const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
185
+ const listed = readText(handleList({}, ctx));
186
+ assert.match(listed, /- gpt-pro \(test-surf@9\.8\.7, external-job:test-surf-oracle \?\): ChatGPT Pro advisor via Surf/);
187
+ assert.match(listed, /External-job provider registry unavailable: Unsupported external-job provider registry/);
188
+
189
+ const detail = readText(handleManagementAction("get", { agent: "gpt-pro" }, ctx));
190
+ assert.match(detail, /Runner: external-job via test-surf-oracle \?/);
191
+ assert.match(detail, /External-job provider registry unavailable: Unsupported external-job provider registry/);
192
+ } finally {
193
+ if (previous === undefined) delete globals[key];
194
+ else globals[key] = previous;
195
+ }
196
+ });
197
+
198
+ it("does not apply a malformed project diagnostic to an explicit user get", () => {
199
+ const projectAgentsDir = path.join(tempDir, ".selesai", "agents");
200
+ const userAgentsDir = path.join(tempDir, "agent-home", "agents");
201
+ fs.mkdirSync(projectAgentsDir, { recursive: true });
202
+ fs.mkdirSync(userAgentsDir, { recursive: true });
203
+ fs.writeFileSync(path.join(userAgentsDir, "worker.md"), "---\nname: worker\ndescription: User worker\n---\nUser worker.\n");
204
+ fs.writeFileSync(path.join(projectAgentsDir, "worker.md"), "---\nname: worker\ndescription: Broken project worker\nrunner:\n type: unknown\n---\nBroken worker.\n");
205
+ const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
206
+
207
+ const userScoped = handleManagementAction("get", { agent: "worker", agentScope: "user" }, ctx);
208
+ assert.equal(userScoped.isError, false);
209
+ assert.match(readText(userScoped), /Agent: worker \(user\)/);
210
+ assert.match(readText(userScoped), /Description: User worker/);
211
+ });
212
+
213
+ it("blocks a malformed higher-precedence user agent from an extra user agent", () => {
214
+ const previousExtraDirs = process.env[EXTRA_AGENT_DIRS_ENV];
215
+ const extraAgentsDir = path.join(tempDir, "extra-agents");
216
+ try {
217
+ process.env[EXTRA_AGENT_DIRS_ENV] = extraAgentsDir;
218
+ fs.mkdirSync(extraAgentsDir, { recursive: true });
219
+ fs.writeFileSync(path.join(extraAgentsDir, "foo.md"), "---\nname: foo\ndescription: Extra user foo\n---\nExtra user foo.\n");
220
+ fs.mkdirSync(path.join(process.env.SELESAI_CODING_AGENT_DIR!, "agents"), { recursive: true });
221
+ fs.writeFileSync(path.join(process.env.SELESAI_CODING_AGENT_DIR!, "agents", "foo.md"), "---\nname: foo\ndescription: Broken configured user foo\nrunner:\n type: unknown\n---\nBroken user foo.\n");
222
+ const result = handleManagementAction("get", { agent: "foo", agentScope: "user" }, { cwd: tempDir, modelRegistry: { getAvailable: () => [] } });
223
+ assert.equal(result.isError, true);
224
+ assert.match(readText(result), /Agent 'foo' has invalid configuration: Agent 'foo' has invalid runner\.type/);
225
+ } finally {
226
+ if (previousExtraDirs === undefined) delete process.env[EXTRA_AGENT_DIRS_ENV];
227
+ else process.env[EXTRA_AGENT_DIRS_ENV] = previousExtraDirs;
228
+ }
229
+ });
230
+
231
+ it("blocks a malformed higher-precedence package agent from a lower package agent", () => {
232
+ const highPackage = path.join(tempDir, "high-package");
233
+ const lowPackage = path.join(tempDir, "low-package");
234
+ for (const packageRoot of [highPackage, lowPackage]) {
235
+ fs.mkdirSync(path.join(packageRoot, "agents"), { recursive: true });
236
+ fs.writeFileSync(path.join(packageRoot, "package.json"), JSON.stringify({ "pi-subagents": { agents: ["agents"] } }));
237
+ }
238
+ fs.writeFileSync(path.join(highPackage, "agents", "foo.md"), "---\nname: foo\npackage: acme\ndescription: Broken high package foo\nrunner:\n type: unknown\n---\nBroken foo.\n");
239
+ fs.writeFileSync(path.join(lowPackage, "agents", "foo.md"), "---\nname: foo\npackage: acme\ndescription: Valid low package foo\n---\nValid foo.\n");
240
+ fs.mkdirSync(path.join(tempDir, ".selesai"), { recursive: true });
241
+ fs.writeFileSync(path.join(tempDir, ".selesai", "settings.json"), JSON.stringify({ packages: [highPackage, lowPackage] }));
242
+
243
+ const result = handleManagementAction("get", { agent: "acme.foo" }, { cwd: tempDir, modelRegistry: { getAvailable: () => [] } });
244
+ assert.equal(result.isError, true);
245
+ assert.match(readText(result), /Agent 'acme\.foo' has invalid configuration: Agent 'foo' has invalid runner\.type/);
246
+ const localResult = handleManagementAction("get", { agent: "foo" }, { cwd: tempDir, modelRegistry: { getAvailable: () => [] } });
247
+ assert.equal(localResult.isError, true);
248
+ assert.match(readText(localResult), /Agent 'foo' has invalid configuration: Agent 'foo' has invalid runner\.type/);
249
+ });
250
+
251
+ it("reports a malformed project agent before lower-priority ambiguity", () => {
252
+ const packageRoot = path.join(tempDir, "package");
253
+ fs.mkdirSync(path.join(packageRoot, "agents"), { recursive: true });
254
+ fs.writeFileSync(path.join(packageRoot, "package.json"), JSON.stringify({ "pi-subagents": { agents: ["agents"] } }));
255
+ fs.writeFileSync(path.join(packageRoot, "agents", "foo.md"), "---\nname: foo\npackage: acme\ndescription: Package foo\n---\nPackage foo.\n");
256
+ fs.mkdirSync(path.join(tempDir, ".selesai", "agents"), { recursive: true });
257
+ fs.writeFileSync(path.join(tempDir, ".selesai", "settings.json"), JSON.stringify({ packages: [packageRoot] }));
258
+ fs.writeFileSync(path.join(tempDir, ".selesai", "agents", "foo.md"), "---\nname: foo\ndescription: Broken project foo\nrunner:\n type: unknown\n---\nBroken foo.\n");
259
+ fs.mkdirSync(path.join(process.env.SELESAI_CODING_AGENT_DIR!, "agents"), { recursive: true });
260
+ fs.writeFileSync(path.join(process.env.SELESAI_CODING_AGENT_DIR!, "agents", "foo.md"), "---\nname: foo\ndescription: User foo\n---\nUser foo.\n");
261
+ const result = handleManagementAction("get", { agent: "foo" }, { cwd: tempDir, modelRegistry: { getAvailable: () => [] } });
262
+ assert.equal(result.isError, true);
263
+ assert.match(readText(result), /Agent 'foo' has invalid configuration: Agent 'foo' has invalid runner\.type/);
264
+ });
265
+
266
+ it("does not let malformed packaged diagnostics block an un-packaged local name", () => {
267
+ const projectAgentsDir = path.join(tempDir, ".selesai", "agents");
268
+ const userAgentsDir = path.join(tempDir, "agent-home", "agents");
269
+ fs.mkdirSync(projectAgentsDir, { recursive: true });
270
+ fs.mkdirSync(userAgentsDir, { recursive: true });
271
+ fs.writeFileSync(path.join(userAgentsDir, "foo.md"), "---\nname: foo\ndescription: User foo\n---\nUser foo.\n");
272
+ fs.writeFileSync(path.join(projectAgentsDir, "acme.foo.md"), "---\nname: foo\npackage: acme\ndescription: Broken packaged foo\nrunner:\n type: unknown\n---\nBroken foo.\n");
273
+ const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
274
+
275
+ const local = handleManagementAction("get", { agent: "foo" }, ctx);
276
+ assert.equal(local.isError, false);
277
+ assert.match(readText(local), /Agent: foo \(user\)/);
278
+ const packaged = handleManagementAction("get", { agent: "acme.foo" }, ctx);
279
+ assert.equal(packaged.isError, true);
280
+ assert.match(readText(packaged), /Agent 'acme\.foo' has invalid configuration: Agent 'foo' has invalid runner\.type/);
281
+ });
282
+
283
+ it("blocks a malformed invalid-package override of a local agent", () => {
284
+ const projectAgentsDir = path.join(tempDir, ".selesai", "agents");
285
+ const userAgentsDir = path.join(tempDir, "agent-home", "agents");
286
+ fs.mkdirSync(projectAgentsDir, { recursive: true });
287
+ fs.mkdirSync(userAgentsDir, { recursive: true });
288
+ fs.writeFileSync(path.join(userAgentsDir, "foo.md"), "---\nname: foo\ndescription: User foo\n---\nUser foo.\n");
289
+ fs.writeFileSync(path.join(projectAgentsDir, "foo.md"), "---\nname: foo\npackage: !!!\ndescription: Broken package\n---\nBroken foo.\n");
290
+ const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
291
+
292
+ const result = handleManagementAction("get", { agent: "foo" }, ctx);
293
+ assert.equal(result.isError, true);
294
+ assert.match(readText(result), /Agent 'foo' has invalid configuration: Agent 'foo' package is invalid after sanitization/);
295
+ });
296
+
297
+ it("blocks a malformed .pi agent from falling back to a legacy project agent", () => {
298
+ const canonicalAgentsDir = path.join(tempDir, ".selesai", "agents");
299
+ const legacyAgentsDir = path.join(tempDir, ".agents");
300
+ fs.mkdirSync(canonicalAgentsDir, { recursive: true });
301
+ fs.mkdirSync(legacyAgentsDir, { recursive: true });
302
+ fs.writeFileSync(path.join(legacyAgentsDir, "shared.md"), "---\nname: shared\ndescription: Legacy shared\n---\nLegacy shared.\n");
303
+ fs.writeFileSync(path.join(canonicalAgentsDir, "shared.md"), "---\nname: shared\ndescription: Broken canonical shared\nrunner:\n type: unknown\n---\nBroken shared.\n");
304
+ const result = handleManagementAction("get", { agent: "shared" }, { cwd: tempDir, modelRegistry: { getAvailable: () => [] } });
305
+ assert.equal(result.isError, true);
306
+ assert.match(readText(result), /Agent 'shared' has invalid configuration: Agent 'shared' has invalid runner\.type/);
307
+ });
308
+
309
+ it("blocks a malformed custom canonical agent directory from falling back to legacy", () => {
310
+ const previousPackageRoot = process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV];
311
+ const packageRoot = path.join(tempDir, "coding-agent-root");
312
+ try {
313
+ fs.mkdirSync(packageRoot, { recursive: true });
314
+ fs.writeFileSync(path.join(packageRoot, "package.json"), JSON.stringify({ name: "@selesai/code", piConfig: { configDir: ".custom-pi" } }));
315
+ process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV] = packageRoot;
316
+ const canonicalAgentsDir = path.join(tempDir, ".custom-pi", "agents");
317
+ const legacyAgentsDir = path.join(tempDir, ".agents");
318
+ fs.mkdirSync(canonicalAgentsDir, { recursive: true });
319
+ fs.mkdirSync(legacyAgentsDir, { recursive: true });
320
+ fs.writeFileSync(path.join(legacyAgentsDir, "shared.md"), "---\nname: shared\ndescription: Legacy shared\n---\nLegacy shared.\n");
321
+ fs.writeFileSync(path.join(canonicalAgentsDir, "shared.md"), "---\nname: shared\ndescription: Broken canonical shared\nrunner:\n type: unknown\n---\nBroken shared.\n");
322
+ const result = handleManagementAction("get", { agent: "shared" }, { cwd: tempDir, modelRegistry: { getAvailable: () => [] } });
323
+ assert.equal(result.isError, true);
324
+ assert.match(readText(result), /Agent 'shared' has invalid configuration: Agent 'shared' has invalid runner\.type/);
325
+ } finally {
326
+ if (previousPackageRoot === undefined) delete process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV];
327
+ else process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV] = previousPackageRoot;
328
+ }
329
+ });
330
+
331
+ it("blocks a malformed canonical .agents/agents definition from legacy .agents", () => {
332
+ const previousPackageRoot = process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV];
333
+ const packageRoot = path.join(tempDir, "coding-agent-root");
334
+ try {
335
+ fs.mkdirSync(packageRoot, { recursive: true });
336
+ fs.writeFileSync(path.join(packageRoot, "package.json"), JSON.stringify({ name: "@selesai/code", piConfig: { configDir: ".agents" } }));
337
+ process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV] = packageRoot;
338
+ const legacyAgentsDir = path.join(tempDir, ".agents");
339
+ const canonicalAgentsDir = path.join(legacyAgentsDir, "agents");
340
+ fs.mkdirSync(canonicalAgentsDir, { recursive: true });
341
+ fs.writeFileSync(path.join(legacyAgentsDir, "foo.md"), "---\nname: foo\ndescription: Legacy foo\n---\nLegacy foo.\n");
342
+ fs.writeFileSync(path.join(canonicalAgentsDir, "foo.md"), "---\nname: foo\ndescription: Broken canonical foo\nrunner:\n type: unknown\n---\nBroken foo.\n");
343
+ const result = handleManagementAction("get", { agent: "foo" }, { cwd: tempDir, modelRegistry: { getAvailable: () => [] } });
344
+ assert.equal(result.isError, true);
345
+ assert.match(readText(result), /Agent 'foo' has invalid configuration: Agent 'foo' has invalid runner\.type/);
346
+ } finally {
347
+ if (previousPackageRoot === undefined) delete process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV];
348
+ else process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV] = previousPackageRoot;
118
349
  }
119
350
  });
120
351
 
@@ -210,41 +441,52 @@ describe("agent management config parsing", () => {
210
441
  assert.match(readText(created), /config\.package is invalid/);
211
442
  });
212
443
 
213
- it("creates and updates packaged chains while preserving packaged step names", () => {
444
+ it("rejects durable chain definitions", () => {
214
445
  const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
215
- fs.mkdirSync(path.join(tempDir, ".selesai", "agents"), { recursive: true });
216
- fs.writeFileSync(path.join(tempDir, ".selesai", "agents", "code-analysis.scout.md"), `---
217
- name: scout
218
- package: code-analysis
219
- description: Fast recon
220
- ---
446
+ const created = handleCreate(
447
+ { config: { name: "Review Flow", description: "Review flow", scope: "project", steps: [{ agent: "scout", task: "Inspect" }] } },
448
+ ctx,
449
+ );
450
+ assert.equal(created.isError, true);
451
+ assert.match(readText(created), /Durable chain definitions were removed/);
221
452
 
222
- Inspect
223
- `, "utf-8");
453
+ const agent = handleCreate(
454
+ { config: { name: "Scout", description: "Scout", scope: "project" } },
455
+ ctx,
456
+ );
457
+ assert.equal(agent.isError, false);
458
+ const updated = handleUpdate(
459
+ { agent: "scout", config: JSON.stringify({ steps: [{ agent: "scout", task: "Inspect" }] }) },
460
+ ctx,
461
+ );
462
+ assert.equal(updated.isError, true);
463
+ assert.match(readText(updated), /Durable chain definitions were removed/);
464
+ });
465
+
466
+ it("ignores discovered legacy chains during agent management", () => {
467
+ const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
468
+ const chainsDir = path.join(tempDir, ".selesai", "chains");
469
+ fs.mkdirSync(chainsDir, { recursive: true });
470
+ fs.writeFileSync(path.join(chainsDir, "scout.chain.md"), "---\nname: scout\ndescription: Old scout flow\n---\n\n## worker\nInspect\n", "utf-8");
471
+ fs.writeFileSync(path.join(chainsDir, "scout-review.chain.md"), "---\nname: scout-review\ndescription: Old review flow\n---\n\n## worker\nReview\n", "utf-8");
472
+ fs.writeFileSync(path.join(chainsDir, "reference.chain.md"), "---\nname: reference\ndescription: Old reference flow\n---\n\n## scout-review\nUse old agent\n", "utf-8");
224
473
 
225
474
  const created = handleCreate(
226
- { config: { name: "Review Flow", package: "Code Analysis", description: "Review flow", scope: "project", steps: [{ agent: "code-analysis.scout", task: "Inspect", toolBudget: { soft: 3, hard: 5, block: ["read"] } }] } },
475
+ { config: { name: "Scout", description: "Scout", scope: "project" } },
227
476
  ctx,
228
477
  );
229
478
  assert.equal(created.isError, false);
230
- assert.match(readText(created), /Created chain 'code-analysis.review-flow'/);
231
- const filePath = path.join(tempDir, ".selesai", "chains", "code-analysis.review-flow.chain.md");
232
- let content = fs.readFileSync(filePath, "utf-8");
233
- assert.match(content, /^name: review-flow$/m);
234
- assert.match(content, /^package: code-analysis$/m);
235
- assert.match(content, /^## code-analysis\.scout$/m);
236
- assert.match(content, /^toolBudget: \{"soft":3,"hard":5,"block":\["read"\]\}$/m);
237
479
 
238
480
  const updated = handleUpdate(
239
- { chainName: "code-analysis.review-flow", config: { package: false } },
481
+ { agent: "scout", config: { name: "Scout Review" } },
240
482
  ctx,
241
483
  );
242
484
  assert.equal(updated.isError, false);
243
- const updatedPath = path.join(tempDir, ".selesai", "chains", "review-flow.chain.md");
244
- assert.equal(fs.existsSync(filePath), false);
245
- content = fs.readFileSync(updatedPath, "utf-8");
246
- assert.match(content, /^name: review-flow$/m);
247
- assert.doesNotMatch(content, /^package:/m);
485
+ assert.doesNotMatch(readText(updated), /chains/i);
486
+
487
+ const deleted = handleManagementAction("delete", { agent: "scout-review" }, ctx);
488
+ assert.equal(deleted.isError, false);
489
+ assert.doesNotMatch(readText(deleted), /chains/i);
248
490
  });
249
491
 
250
492
  it("creates and updates agents with single-agent launch defaults", () => {
@@ -259,6 +501,7 @@ Inspect
259
501
  timeoutMs: 120_000,
260
502
  turnBudget: { maxTurns: 8, graceTurns: 2 },
261
503
  acceptance: { level: "none", reason: "lightweight reviewer" },
504
+ outputMode: "file-only",
262
505
  },
263
506
  },
264
507
  ctx,
@@ -271,6 +514,7 @@ Inspect
271
514
  assert.match(content, /^timeoutMs: 120000$/m);
272
515
  assert.match(content, /^turnBudget: \{"maxTurns":8,"graceTurns":2\}$/m);
273
516
  assert.match(content, /^acceptance: \{"level":"none","reason":"lightweight reviewer"\}$/m);
517
+ assert.match(content, /^outputMode: file-only$/m);
274
518
 
275
519
  const got = handleManagementAction("get", { agent: "background-reviewer" }, ctx);
276
520
  assert.equal(got.isError, false);
@@ -278,9 +522,10 @@ Inspect
278
522
  assert.match(readText(got), /Timeout: 120000ms/);
279
523
  assert.match(readText(got), /Turn budget: \{"maxTurns":8,"graceTurns":2\}/);
280
524
  assert.match(readText(got), /Acceptance: \{"level":"none","reason":"lightweight reviewer"\}/);
525
+ assert.match(readText(got), /Output mode: file-only/);
281
526
 
282
527
  const updated = handleUpdate(
283
- { agent: "background-reviewer", config: { async: true, timeoutMs: false, turnBudget: false, acceptance: "" } },
528
+ { agent: "background-reviewer", config: { async: true, timeoutMs: false, turnBudget: false, acceptance: "", outputMode: "inline" } },
284
529
  ctx,
285
530
  );
286
531
  assert.equal(updated.isError, false);
@@ -289,6 +534,7 @@ Inspect
289
534
  assert.doesNotMatch(content, /^timeoutMs:/m);
290
535
  assert.doesNotMatch(content, /^turnBudget:/m);
291
536
  assert.doesNotMatch(content, /^acceptance:/m);
537
+ assert.match(content, /^outputMode: inline$/m);
292
538
 
293
539
  const deprecatedFalse = handleUpdate(
294
540
  { agent: "background-reviewer", config: { acceptance: false } },
@@ -328,6 +574,20 @@ Inspect
328
574
  );
329
575
  assert.equal(invalidAcceptance.isError, true);
330
576
  assert.match(readText(invalidAcceptance), /config\.acceptance level "none" requires a reason/);
577
+
578
+ const invalidOutputMode = handleCreate(
579
+ {
580
+ config: {
581
+ name: "bad-output-mode",
582
+ description: "Bad output mode",
583
+ scope: "project",
584
+ outputMode: false,
585
+ },
586
+ },
587
+ { cwd: tempDir, modelRegistry: { getAvailable: () => [] } },
588
+ );
589
+ assert.equal(invalidOutputMode.isError, true);
590
+ assert.match(readText(invalidOutputMode), /config\.outputMode must be 'inline' or 'file-only'/);
331
591
  });
332
592
 
333
593
  it("creates and updates agents with tool budgets", () => {
@@ -365,11 +625,11 @@ Inspect
365
625
  assert.match(readText(agentResult), /config\.toolBudget\.soft must be <= config\.toolBudget\.hard/);
366
626
 
367
627
  const chainResult = handleCreate(
368
- { config: { name: "bad-chain-budget", description: "Bad budget", scope: "project", steps: [{ agent: "reviewer", toolBudget: { hard: 2, block: [] } }] } },
628
+ { config: { name: "bad-chain-budget", description: "Bad budget", scope: "project", steps: [{ agent: "reviewer" }] } },
369
629
  ctx,
370
630
  );
371
631
  assert.equal(chainResult.isError, true);
372
- assert.match(readText(chainResult), /config\.steps\[0\]\.toolBudget\.block must contain at least one tool name/);
632
+ assert.match(readText(chainResult), /Durable chain definitions were removed/);
373
633
  });
374
634
 
375
635
  it("creates, updates, reports, clears, and validates acceptance roles", () => {
@@ -442,18 +702,96 @@ Inspect
442
702
 
443
703
  const got = handleManagementAction("get", { agent: "child-tool-user" }, ctx);
444
704
  assert.equal(got.isError, false);
445
- assert.match(readText(got), /Subagent-only extensions: \.\/tools\/child-only\.ts, \/opt\/pi\/child\.ts/);
705
+ assert.ok(readText(got).includes("Subagent-only extensions: " + path.join(tempDir, ".selesai", "agents", "tools", "child-only.ts") + ", /opt/pi/child.ts"));
706
+ });
707
+
708
+ it("preserves relative extension paths during unrelated updates", () => {
709
+ const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
710
+ const agentPath = path.join(tempDir, ".selesai", "agents", "portable.md");
711
+ fs.mkdirSync(path.dirname(agentPath), { recursive: true });
712
+ fs.writeFileSync(
713
+ agentPath,
714
+ "---\nname: portable\ndescription: Portable agent\nextensions: ./tools/parent.ts, package-extension\nsubagentOnlyExtensions: ../child.ts, ~/shared.ts\n---\nOriginal prompt.\n",
715
+ );
716
+
717
+ const updated = handleUpdate({ agent: "portable", config: { description: "Updated agent" } }, ctx);
718
+
719
+ assert.equal(updated.isError, false);
720
+ const content = fs.readFileSync(agentPath, "utf-8");
721
+ assert.match(content, /^description: Updated agent$/m);
722
+ assert.match(content, /^extensions: \.\/tools\/parent\.ts, package-extension$/m);
723
+ assert.match(content, /^subagentOnlyExtensions: \.\.\/child\.ts, ~\/shared\.ts$/m);
724
+ assert.ok(!content.includes(tempDir));
725
+ });
726
+
727
+ it("fails when extension frontmatter cannot be reread", () => {
728
+ const filePath = path.join(tempDir, ".selesai", "agents", "removed.md");
729
+ assert.throws(
730
+ () => editableAgentConfig({
731
+ name: "removed",
732
+ description: "Removed agent",
733
+ systemPromptMode: "replace",
734
+ inheritProjectContext: false,
735
+ inheritSkills: false,
736
+ systemPrompt: "Original prompt.",
737
+ source: "project",
738
+ filePath,
739
+ extensions: [path.join(tempDir, ".selesai", "agents", "tools", "parent.ts")],
740
+ }),
741
+ /ENOENT/,
742
+ );
743
+ });
744
+
745
+ it("returns a structured error when a definition disappears after discovery", () => {
746
+ const agentPath = path.join(tempDir, ".selesai", "agents", "removed-during-update.md");
747
+ fs.mkdirSync(path.dirname(agentPath), { recursive: true });
748
+ fs.writeFileSync(
749
+ agentPath,
750
+ "---\nname: removed-during-update\ndescription: Temporary agent\nextensions: ./tools/parent.ts\n---\nOriginal prompt.\n",
751
+ );
752
+ let cwdReads = 0;
753
+ const ctx = {
754
+ get cwd() {
755
+ cwdReads += 1;
756
+ // handleUpdate reads cwd again after discovery, which models the definition disappearing between reads.
757
+ if (cwdReads === 2) fs.unlinkSync(agentPath);
758
+ return tempDir;
759
+ },
760
+ modelRegistry: { getAvailable: () => [] },
761
+ };
762
+
763
+ const updated = handleUpdate({ agent: "removed-during-update", config: { description: "Updated agent" } }, ctx);
764
+
765
+ assert.equal(updated.isError, true);
766
+ assert.match(readText(updated), /Could not reread agent definition .*removed-during-update\.md before updating 'removed-during-update':.*ENOENT/);
767
+ assert.equal(fs.existsSync(agentPath), false);
446
768
  });
447
769
 
448
770
  it("does not serialize settings overrides into custom agent frontmatter during updates", () => {
449
771
  const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [{ provider: "anthropic", id: "claude-sonnet-4-6" }] } };
772
+ const userSettingsPath = path.join(process.env.SELESAI_CODING_AGENT_DIR!, "settings.json");
450
773
  const settingsPath = path.join(tempDir, ".selesai", "settings.json");
451
774
  const agentPath = path.join(tempDir, ".selesai", "agents", "implementer.md");
452
775
  fs.mkdirSync(path.dirname(agentPath), { recursive: true });
776
+ fs.mkdirSync(path.dirname(userSettingsPath), { recursive: true });
777
+ fs.writeFileSync(userSettingsPath, JSON.stringify({
778
+ subagents: {
779
+ agentOverrides: {
780
+ implementer: {
781
+ output: "user.md",
782
+ defaultReads: ["user.md"],
783
+ model: "anthropic/claude-sonnet-4-6",
784
+ },
785
+ },
786
+ },
787
+ }, null, 2), "utf-8");
453
788
  fs.writeFileSync(settingsPath, JSON.stringify({
454
789
  subagents: {
455
790
  agentOverrides: {
456
791
  implementer: {
792
+ output: "artifacts/implementer.md",
793
+ outputMode: "file-only",
794
+ defaultReads: ["CONTEXT.md"],
457
795
  model: "anthropic/claude-sonnet-4-6",
458
796
  systemPromptMode: "append",
459
797
  inheritProjectContext: true,
@@ -473,6 +811,9 @@ Drive the failing test first.
473
811
  const got = handleManagementAction("get", { agent: "implementer" }, ctx);
474
812
  assert.equal(got.isError, false);
475
813
  const beforeText = readText(got);
814
+ assert.match(beforeText, /Output: artifacts\/implementer\.md/);
815
+ assert.match(beforeText, /Output mode: file-only/);
816
+ assert.match(beforeText, /Reads: CONTEXT\.md/);
476
817
  assert.match(beforeText, /Model: anthropic\/claude-sonnet-4-6/);
477
818
  assert.match(beforeText, /System prompt mode: append/);
478
819
  assert.match(beforeText, /Inherit project context: true/);
@@ -486,6 +827,9 @@ Drive the failing test first.
486
827
 
487
828
  const content = fs.readFileSync(agentPath, "utf-8");
488
829
  assert.match(content, /^description: Updated implementer$/m);
830
+ assert.doesNotMatch(content, /^output:/m);
831
+ assert.doesNotMatch(content, /^outputMode:/m);
832
+ assert.doesNotMatch(content, /^defaultReads:/m);
489
833
  assert.doesNotMatch(content, /^model:/m);
490
834
  assert.doesNotMatch(content, /^systemPromptMode:/m);
491
835
  assert.doesNotMatch(content, /^inheritProjectContext:/m);
@@ -494,12 +838,44 @@ Drive the failing test first.
494
838
  const gotAfter = handleManagementAction("get", { agent: "implementer" }, ctx);
495
839
  assert.equal(gotAfter.isError, false);
496
840
  const afterText = readText(gotAfter);
841
+ assert.match(afterText, /Output: artifacts\/implementer\.md/);
842
+ assert.match(afterText, /Output mode: file-only/);
843
+ assert.match(afterText, /Reads: CONTEXT\.md/);
497
844
  assert.match(afterText, /Model: anthropic\/claude-sonnet-4-6/);
498
845
  assert.match(afterText, /System prompt mode: append/);
499
846
  assert.match(afterText, /Inherit project context: true/);
500
847
  assert.match(afterText, /Inherit skills: true/);
501
848
  });
502
849
 
850
+ it("preserves blank output and defaultReads frontmatter that blocks settings overrides during updates", () => {
851
+ const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
852
+ const settingsPath = path.join(tempDir, ".selesai", "settings.json");
853
+ const agentPath = path.join(tempDir, ".selesai", "agents", "implementer.md");
854
+ fs.mkdirSync(path.dirname(agentPath), { recursive: true });
855
+ fs.writeFileSync(settingsPath, JSON.stringify({
856
+ subagents: { agentOverrides: { implementer: { output: "settings.md", defaultReads: ["settings.md"] } } },
857
+ }, null, 2), "utf-8");
858
+ fs.writeFileSync(agentPath, `---
859
+ name: implementer
860
+ description: TDD implementer
861
+ output:
862
+ defaultReads:
863
+ ---
864
+
865
+ Drive the failing test first.
866
+ `, "utf-8");
867
+
868
+ const updated = handleUpdate({ agent: "implementer", config: { description: "Updated implementer" } }, ctx);
869
+ assert.equal(updated.isError, false);
870
+
871
+ const content = fs.readFileSync(agentPath, "utf-8");
872
+ assert.match(content, /^output: ?$/m);
873
+ assert.match(content, /^defaultReads: ?$/m);
874
+ const after = readText(handleManagementAction("get", { agent: "implementer" }, ctx));
875
+ assert.doesNotMatch(after, /Output: settings\.md/);
876
+ assert.doesNotMatch(after, /Reads: settings\.md/);
877
+ });
878
+
503
879
  it("preserves explicit default-like frontmatter that blocks settings overrides during updates", () => {
504
880
  const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
505
881
  const settingsPath = path.join(tempDir, ".selesai", "settings.json");
@@ -564,86 +940,6 @@ Drive the failing test first.
564
940
  assert.doesNotMatch(afterText, /Thinking: high/);
565
941
  });
566
942
 
567
- it("updates JSON chain descriptions without rewriting them as markdown", () => {
568
- const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
569
- const chainPath = path.join(tempDir, ".selesai", "chains", "dynamic-review.chain.json");
570
- fs.mkdirSync(path.dirname(chainPath), { recursive: true });
571
- fs.writeFileSync(chainPath, JSON.stringify({
572
- name: "dynamic-review",
573
- description: "Review dynamic targets",
574
- chain: [
575
- { agent: "scout", task: "Return targets", as: "targets", outputSchema: { type: "object" } },
576
- {
577
- expand: { from: { output: "targets", path: "/items" }, item: "target", key: "/path", maxItems: 4 },
578
- parallel: { agent: "reviewer", task: "Review {target.path}", outputSchema: { type: "object" } },
579
- collect: { as: "reviews" },
580
- },
581
- ],
582
- }), "utf-8");
583
-
584
- const updated = handleUpdate({ chainName: "dynamic-review", config: { description: "Updated dynamic review" } }, ctx);
585
-
586
- assert.equal(updated.isError, false);
587
- const content = fs.readFileSync(chainPath, "utf-8");
588
- assert.doesNotMatch(content, /^---/);
589
- const parsed = JSON.parse(content) as { description?: string; chain?: Array<{ collect?: { as?: string } }> };
590
- assert.equal(parsed.description, "Updated dynamic review");
591
- assert.equal(parsed.chain?.[1]?.collect?.as, "reviews");
592
- });
593
-
594
- it("renames and repackages JSON chains while preserving JSON format and extension", () => {
595
- const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
596
- const chainPath = path.join(tempDir, ".selesai", "chains", "dynamic-review.chain.json");
597
- fs.mkdirSync(path.dirname(chainPath), { recursive: true });
598
- fs.writeFileSync(chainPath, JSON.stringify({
599
- name: "dynamic-review",
600
- description: "Review dynamic targets",
601
- chain: [{ agent: "scout", task: "Return targets" }],
602
- }), "utf-8");
603
-
604
- const updated = handleUpdate({ chainName: "dynamic-review", config: { name: "Review Flow", package: "Code Analysis" } }, ctx);
605
-
606
- assert.equal(updated.isError, false);
607
- const updatedPath = path.join(tempDir, ".selesai", "chains", "code-analysis.review-flow.chain.json");
608
- assert.equal(fs.existsSync(chainPath), false);
609
- const content = fs.readFileSync(updatedPath, "utf-8");
610
- assert.doesNotMatch(content, /^---/);
611
- const parsed = JSON.parse(content) as { name?: string; package?: string; chain?: Array<{ agent?: string }> };
612
- assert.equal(parsed.name, "review-flow");
613
- assert.equal(parsed.package, "code-analysis");
614
- assert.equal(parsed.chain?.[0]?.agent, "scout");
615
- });
616
-
617
- it("gets dynamic JSON chain details and lists invalid chain diagnostics", () => {
618
- const ctx = { cwd: tempDir, modelRegistry: { getAvailable: () => [] } };
619
- fs.mkdirSync(path.join(tempDir, ".selesai", "chains"), { recursive: true });
620
- fs.writeFileSync(path.join(tempDir, ".selesai", "chains", "dynamic-review.chain.json"), JSON.stringify({
621
- name: "dynamic-review",
622
- description: "Review dynamic targets",
623
- chain: [
624
- { agent: "scout", task: "Return targets", as: "targets", outputSchema: { type: "object" } },
625
- {
626
- expand: { from: { output: "targets", path: "/items" }, item: "target", key: "/path", maxItems: 4 },
627
- parallel: { agent: "reviewer", task: "Review {target.path}", outputSchema: { type: "object" } },
628
- collect: { as: "reviews" },
629
- },
630
- ],
631
- }), "utf-8");
632
- fs.writeFileSync(path.join(tempDir, ".selesai", "chains", "broken.chain.json"), "{", "utf-8");
633
-
634
- const got = handleManagementAction("get", { chainName: "dynamic-review" }, ctx);
635
- assert.equal(got.isError, false);
636
- assert.match(readText(got), /Dynamic fanout -> reviews/);
637
- assert.match(readText(got), /Expand: targets\/items/);
638
- assert.match(readText(got), /Agent: reviewer/);
639
-
640
- const listed = handleManagementAction("list", {}, ctx);
641
- assert.equal(listed.isError, false);
642
- assert.match(readText(listed), /Chain diagnostics:/);
643
- assert.match(readText(listed), /broken\.chain\.json/);
644
- assert.match(readText(listed), /Invalid JSON chain/);
645
- });
646
-
647
943
  it("reports builtin runtime-loaded model mappings from current session state", () => {
648
944
  const ctx = {
649
945
  cwd: tempDir,
@@ -662,6 +958,9 @@ Drive the failing test first.
662
958
  assert.match(text, /^Builtin subagent models/m);
663
959
  assert.match(text, /Current session model:\n openai\/gpt-5-mini/);
664
960
  assert.match(text, /(?:^|\n)scout\n model:\n openai\/gpt-5-mini\n source: inherits current session model(?:\n|$)/);
961
+ assert.match(text, /Available models in this session's registry/);
962
+ assert.match(text, / anthropic\/claude-sonnet-4\n openai\/gpt-5-mini/);
963
+ assert.match(text, /Use an exact provider\/id from this list when you pass model/);
665
964
  });
666
965
 
667
966
  it("reports override source and disabled builtin state in runtime model mappings", () => {
@@ -695,7 +994,7 @@ Drive the failing test first.
695
994
  assert.match(text, /Source: project override/);
696
995
  assert.match(text, /Requested model setting:\n claude-sonnet-4/);
697
996
  assert.match(text, /Disabled: true/);
698
- assert.match(text.replaceAll("\\", "/"), /Override file:\n .*\.selesai\/settings\.json/);
997
+ assert.match(text.replaceAll("\\", "/"), /Override file:\n .*\.pi\/settings\.json/);
699
998
  });
700
999
 
701
1000
  it("rejects unknown builtin filters for runtime model mappings", () => {