@selesai/code 0.13.0 → 0.13.1

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 (461) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/core/agent-session.d.ts +1 -1
  3. package/dist/core/agent-session.js +1 -1
  4. package/dist/core/sdk.d.ts +2 -2
  5. package/dist/core/sdk.js +1 -1
  6. package/dist/core/system-prompt.d.ts +1 -1
  7. package/dist/core/system-prompt.js +1 -1
  8. package/dist/extensions/ascii.txt +9 -0
  9. package/dist/extensions/package.json +1 -2
  10. package/dist/extensions/pi-hermes-memory/CHANGELOG.md +371 -0
  11. package/dist/extensions/pi-hermes-memory/LICENSE +21 -0
  12. package/dist/extensions/pi-hermes-memory/README.md +643 -0
  13. package/dist/extensions/pi-hermes-memory/docs/0.1/TASKS.md +197 -0
  14. package/dist/extensions/pi-hermes-memory/docs/0.2/PLAN.md +290 -0
  15. package/dist/extensions/pi-hermes-memory/docs/0.2/TASKS.md +134 -0
  16. package/dist/extensions/pi-hermes-memory/docs/0.2/TEST-PLAN.md +216 -0
  17. package/dist/extensions/pi-hermes-memory/docs/0.3/PLAN.md +330 -0
  18. package/dist/extensions/pi-hermes-memory/docs/0.3/TASKS.md +125 -0
  19. package/dist/extensions/pi-hermes-memory/docs/0.4/PLAN.md +160 -0
  20. package/dist/extensions/pi-hermes-memory/docs/0.4/TASKS.md +113 -0
  21. package/dist/extensions/pi-hermes-memory/docs/0.6/CHANGELOG.md +57 -0
  22. package/dist/extensions/pi-hermes-memory/docs/0.6/PLAN.md +202 -0
  23. package/dist/extensions/pi-hermes-memory/docs/0.6/TASKS.md +144 -0
  24. package/dist/extensions/pi-hermes-memory/docs/0.7/PLAN.md +349 -0
  25. package/dist/extensions/pi-hermes-memory/docs/0.7/TASKS.md +110 -0
  26. package/dist/extensions/pi-hermes-memory/docs/PUBLISHING.md +149 -0
  27. package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +468 -0
  28. package/dist/extensions/pi-hermes-memory/docs/images/memory-architecture.svg +1 -0
  29. package/dist/extensions/pi-hermes-memory/docs/images/pi-logo.svg +22 -0
  30. package/dist/extensions/pi-hermes-memory/docs/images/pi_memory.png +0 -0
  31. package/dist/extensions/pi-hermes-memory/docs/images/pi_memory.svg +19 -0
  32. package/dist/extensions/pi-hermes-memory/docs/images/security-flow.svg +1 -0
  33. package/dist/extensions/pi-hermes-memory/docs/images/session-lifecycle.svg +1 -0
  34. package/dist/extensions/pi-hermes-memory/docs/images/source-architecture.svg +1 -0
  35. package/dist/extensions/pi-hermes-memory/docs/mermaid/memory-architecture.mmd +49 -0
  36. package/dist/extensions/pi-hermes-memory/docs/mermaid/security-flow.mmd +40 -0
  37. package/dist/extensions/pi-hermes-memory/docs/mermaid/session-lifecycle.mmd +56 -0
  38. package/dist/extensions/pi-hermes-memory/docs/mermaid/source-architecture.mmd +54 -0
  39. package/dist/extensions/pi-hermes-memory/package-lock.json +3799 -0
  40. package/dist/extensions/pi-hermes-memory/package.json +66 -0
  41. package/dist/extensions/pi-hermes-memory/scripts/check-min-sdk.mjs +99 -0
  42. package/dist/extensions/pi-hermes-memory/scripts/ensure-dev.mjs +57 -0
  43. package/dist/extensions/pi-hermes-memory/src/auto-consolidation-warning.ts +6 -0
  44. package/dist/extensions/pi-hermes-memory/src/config.ts +178 -0
  45. package/dist/extensions/pi-hermes-memory/src/constants.ts +424 -0
  46. package/dist/extensions/pi-hermes-memory/src/extension-root-migration.ts +639 -0
  47. package/dist/extensions/pi-hermes-memory/src/handlers/auto-consolidate.ts +401 -0
  48. package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +297 -0
  49. package/dist/extensions/pi-hermes-memory/src/handlers/child-process-watchdog.mjs +90 -0
  50. package/dist/extensions/pi-hermes-memory/src/handlers/correction-detector.ts +300 -0
  51. package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +86 -0
  52. package/dist/extensions/pi-hermes-memory/src/handlers/insights.ts +78 -0
  53. package/dist/extensions/pi-hermes-memory/src/handlers/interview.ts +37 -0
  54. package/dist/extensions/pi-hermes-memory/src/handlers/learn-memory.ts +186 -0
  55. package/dist/extensions/pi-hermes-memory/src/handlers/message-parts.ts +27 -0
  56. package/dist/extensions/pi-hermes-memory/src/handlers/pi-child-process.ts +485 -0
  57. package/dist/extensions/pi-hermes-memory/src/handlers/preview-context.ts +105 -0
  58. package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +506 -0
  59. package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +145 -0
  60. package/dist/extensions/pi-hermes-memory/src/handlers/session-flush.ts +151 -0
  61. package/dist/extensions/pi-hermes-memory/src/handlers/session-live-index.ts +94 -0
  62. package/dist/extensions/pi-hermes-memory/src/handlers/skills-command.ts +1334 -0
  63. package/dist/extensions/pi-hermes-memory/src/handlers/standing-pin.ts +111 -0
  64. package/dist/extensions/pi-hermes-memory/src/handlers/switch-project.ts +75 -0
  65. package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +266 -0
  66. package/dist/extensions/pi-hermes-memory/src/index.ts +378 -0
  67. package/dist/extensions/pi-hermes-memory/src/lifecycle-timing.ts +54 -0
  68. package/dist/extensions/pi-hermes-memory/src/paths.ts +61 -0
  69. package/dist/extensions/pi-hermes-memory/src/project-context.ts +13 -0
  70. package/dist/extensions/pi-hermes-memory/src/project-memory-migration.ts +93 -0
  71. package/dist/extensions/pi-hermes-memory/src/project.ts +157 -0
  72. package/dist/extensions/pi-hermes-memory/src/prompt-context.ts +55 -0
  73. package/dist/extensions/pi-hermes-memory/src/store/atomic-lock-coordinator.ts +375 -0
  74. package/dist/extensions/pi-hermes-memory/src/store/canonical-storage-path.ts +54 -0
  75. package/dist/extensions/pi-hermes-memory/src/store/content-scanner.ts +101 -0
  76. package/dist/extensions/pi-hermes-memory/src/store/db.ts +1180 -0
  77. package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +101 -0
  78. package/dist/extensions/pi-hermes-memory/src/store/markdown-mutation-lock.ts +38 -0
  79. package/dist/extensions/pi-hermes-memory/src/store/memory-lookup.ts +24 -0
  80. package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +1191 -0
  81. package/dist/extensions/pi-hermes-memory/src/store/recovery-maintenance.ts +66 -0
  82. package/dist/extensions/pi-hermes-memory/src/store/schema.ts +118 -0
  83. package/dist/extensions/pi-hermes-memory/src/store/session-anchor-search.ts +472 -0
  84. package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +511 -0
  85. package/dist/extensions/pi-hermes-memory/src/store/session-parser.ts +213 -0
  86. package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +234 -0
  87. package/dist/extensions/pi-hermes-memory/src/store/skill-store.ts +950 -0
  88. package/dist/extensions/pi-hermes-memory/src/store/skill-utils.ts +133 -0
  89. package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +1002 -0
  90. package/dist/extensions/pi-hermes-memory/src/store/sqlite-native.ts +241 -0
  91. package/dist/extensions/pi-hermes-memory/src/store/standing-instructions.ts +247 -0
  92. package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +95 -0
  93. package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +469 -0
  94. package/dist/extensions/pi-hermes-memory/src/tools/session-search-tool.ts +246 -0
  95. package/dist/extensions/pi-hermes-memory/src/tools/shared-output-view.ts +170 -0
  96. package/dist/extensions/pi-hermes-memory/src/tools/skill-tool.ts +333 -0
  97. package/dist/extensions/pi-hermes-memory/src/tools/tool-result-views.ts +105 -0
  98. package/dist/extensions/pi-hermes-memory/src/types.ts +214 -0
  99. package/dist/extensions/pi-hermes-memory/tests/config.test.ts +434 -0
  100. package/dist/extensions/pi-hermes-memory/tests/extension-root-migration.test.ts +368 -0
  101. package/dist/extensions/pi-hermes-memory/tests/handlers/auto-consolidate.test.ts +984 -0
  102. package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +950 -0
  103. package/dist/extensions/pi-hermes-memory/tests/handlers/correction-detector.test.ts +671 -0
  104. package/dist/extensions/pi-hermes-memory/tests/handlers/insights.test.ts +157 -0
  105. package/dist/extensions/pi-hermes-memory/tests/handlers/interview.test.ts +127 -0
  106. package/dist/extensions/pi-hermes-memory/tests/handlers/pi-child-process.test.ts +905 -0
  107. package/dist/extensions/pi-hermes-memory/tests/handlers/preview-context.test.ts +152 -0
  108. package/dist/extensions/pi-hermes-memory/tests/handlers/prompt-context.test.ts +166 -0
  109. package/dist/extensions/pi-hermes-memory/tests/handlers/resources-discover.test.ts +71 -0
  110. package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +614 -0
  111. package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +192 -0
  112. package/dist/extensions/pi-hermes-memory/tests/handlers/session-flush.test.ts +677 -0
  113. package/dist/extensions/pi-hermes-memory/tests/handlers/session-live-index.test.ts +225 -0
  114. package/dist/extensions/pi-hermes-memory/tests/handlers/skills-command.test.ts +827 -0
  115. package/dist/extensions/pi-hermes-memory/tests/handlers/standing-pin.test.ts +134 -0
  116. package/dist/extensions/pi-hermes-memory/tests/handlers/sync-markdown-memories.test.ts +491 -0
  117. package/dist/extensions/pi-hermes-memory/tests/handlers/system-prompt.test.ts +199 -0
  118. package/dist/extensions/pi-hermes-memory/tests/handlers/thinking-max.test.ts +64 -0
  119. package/dist/extensions/pi-hermes-memory/tests/index.test.ts +30 -0
  120. package/dist/extensions/pi-hermes-memory/tests/integration/flow.test.ts +126 -0
  121. package/dist/extensions/pi-hermes-memory/tests/lifecycle-timing.test.ts +76 -0
  122. package/dist/extensions/pi-hermes-memory/tests/paths.test.ts +23 -0
  123. package/dist/extensions/pi-hermes-memory/tests/project-memory-migration.test.ts +80 -0
  124. package/dist/extensions/pi-hermes-memory/tests/project-rebinding.test.ts +115 -0
  125. package/dist/extensions/pi-hermes-memory/tests/project.test.ts +120 -0
  126. package/dist/extensions/pi-hermes-memory/tests/run-all-timeout.test.ts +107 -0
  127. package/dist/extensions/pi-hermes-memory/tests/run-all.sh +45 -0
  128. package/dist/extensions/pi-hermes-memory/tests/store/atomic-lock-coordinator.test.ts +381 -0
  129. package/dist/extensions/pi-hermes-memory/tests/store/content-scanner.test.ts +388 -0
  130. package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +1046 -0
  131. package/dist/extensions/pi-hermes-memory/tests/store/markdown-mutation-lock.test.ts +34 -0
  132. package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +2150 -0
  133. package/dist/extensions/pi-hermes-memory/tests/store/recovery-maintenance.test.ts +170 -0
  134. package/dist/extensions/pi-hermes-memory/tests/store/session-anchor-search.test.ts +210 -0
  135. package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +643 -0
  136. package/dist/extensions/pi-hermes-memory/tests/store/session-parser.test.ts +282 -0
  137. package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +287 -0
  138. package/dist/extensions/pi-hermes-memory/tests/store/skill-store.test.ts +678 -0
  139. package/dist/extensions/pi-hermes-memory/tests/store/skill-utils.test.ts +21 -0
  140. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-lazy-load.test.ts +78 -0
  141. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +543 -0
  142. package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +164 -0
  143. package/dist/extensions/pi-hermes-memory/tests/store/standing-instructions.test.ts +171 -0
  144. package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +84 -0
  145. package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +709 -0
  146. package/dist/extensions/pi-hermes-memory/tests/tools/session-search-tool.test.ts +345 -0
  147. package/dist/extensions/pi-hermes-memory/tests/tools/shared-output-view.test.ts +362 -0
  148. package/dist/extensions/pi-hermes-memory/tests/tools/skill-tool.test.ts +478 -0
  149. package/dist/extensions/pi-hermes-memory/tests/tools/tool-result-renderer-wiring.test.ts +40 -0
  150. package/dist/extensions/pi-hermes-memory/tsconfig.json +19 -0
  151. package/dist/extensions/pi-subagents/.oxlintrc.json +43 -0
  152. package/dist/extensions/pi-subagents/AGENTS.md +5 -0
  153. package/dist/extensions/pi-subagents/CHANGELOG.md +157 -0
  154. package/dist/extensions/pi-subagents/README.md +12 -6
  155. package/dist/extensions/pi-subagents/VISION.md +81 -0
  156. package/dist/extensions/pi-subagents/agents/claude-code-writer.md +15 -0
  157. package/dist/extensions/pi-subagents/agents/claude-code.md +15 -0
  158. package/dist/extensions/pi-subagents/agents/codex-exec-writer.md +15 -0
  159. package/dist/extensions/pi-subagents/agents/codex-exec.md +15 -0
  160. package/dist/extensions/pi-subagents/agents/cursor-agent-writer.md +14 -0
  161. package/dist/extensions/pi-subagents/agents/cursor-agent.md +14 -0
  162. package/dist/extensions/pi-subagents/agents/reviewer.md +1 -3
  163. package/dist/extensions/pi-subagents/docs/agents.md +488 -0
  164. package/dist/extensions/pi-subagents/docs/configuration.md +46 -9
  165. package/dist/extensions/pi-subagents/docs/extension-api.md +42 -3
  166. package/dist/extensions/pi-subagents/docs/models.md +27 -4
  167. package/dist/extensions/pi-subagents/docs/observability.md +10 -9
  168. package/dist/extensions/pi-subagents/docs/tool-reference.md +102 -6
  169. package/dist/extensions/pi-subagents/docs/workflows.md +135 -0
  170. package/dist/extensions/pi-subagents/package-lock.json +389 -2
  171. package/dist/extensions/pi-subagents/package.json +3 -1
  172. package/dist/extensions/pi-subagents/prompts/review-loop.md +2 -2
  173. package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +1 -1
  174. package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +3 -1
  175. package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +7 -3
  176. package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
  177. package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +26 -5
  178. package/dist/extensions/pi-subagents/src/agents/agent-management.ts +41 -22
  179. package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +4 -4
  180. package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +9 -2
  181. package/dist/extensions/pi-subagents/src/agents/agents.ts +322 -75
  182. package/dist/extensions/pi-subagents/src/agents/builtin-names.ts +6 -0
  183. package/dist/extensions/pi-subagents/src/agents/runtime-agent-events.ts +70 -0
  184. package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +27 -20
  185. package/dist/extensions/pi-subagents/src/api/agents.ts +10 -5
  186. package/dist/extensions/pi-subagents/src/api/background-work.ts +5 -1
  187. package/dist/extensions/pi-subagents/src/api/delegation.ts +0 -7
  188. package/dist/extensions/pi-subagents/src/api/preflight.ts +34 -12
  189. package/dist/extensions/pi-subagents/src/extension/config.ts +70 -0
  190. package/dist/extensions/pi-subagents/src/extension/doctor.ts +3 -3
  191. package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +5 -3
  192. package/dist/extensions/pi-subagents/src/extension/index.ts +83 -30
  193. package/dist/extensions/pi-subagents/src/extension/public-execution.ts +44 -15
  194. package/dist/extensions/pi-subagents/src/extension/rpc.ts +55 -19
  195. package/dist/extensions/pi-subagents/src/extension/schemas.ts +41 -15
  196. package/dist/extensions/pi-subagents/src/extension/tool-description.ts +28 -31
  197. package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +2 -1
  198. package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +2 -10
  199. package/dist/extensions/pi-subagents/src/inspectors/herdr/session-roots-codec.ts +42 -0
  200. package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +51 -3
  201. package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +2 -0
  202. package/dist/extensions/pi-subagents/src/profiles/profiles.ts +5 -6
  203. package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +77 -10
  204. package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +176 -53
  205. package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +19 -12
  206. package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +29 -27
  207. package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +20 -3
  208. package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +23 -261
  209. package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +73 -7
  210. package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +8 -3
  211. package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +74 -8
  212. package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +37 -21
  213. package/dist/extensions/pi-subagents/src/runs/background/inspect-rpc.ts +8 -8
  214. package/dist/extensions/pi-subagents/src/runs/background/notify.ts +184 -9
  215. package/dist/extensions/pi-subagents/src/runs/background/result-delivery-ownership.ts +45 -0
  216. package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +28 -14
  217. package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +38 -15
  218. package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +1 -1
  219. package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +1 -1
  220. package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +50 -13
  221. package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +93 -8
  222. package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +10 -4
  223. package/dist/extensions/pi-subagents/src/runs/background/steering.ts +4 -14
  224. package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +549 -377
  225. package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +58 -10
  226. package/dist/extensions/pi-subagents/src/runs/background/terminal-run-index.ts +1 -1
  227. package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +26 -1
  228. package/dist/extensions/pi-subagents/src/runs/background/wait-config.ts +23 -9
  229. package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +9 -2
  230. package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +2 -2
  231. package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +204 -129
  232. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +9 -0
  233. package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +23 -1
  234. package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +773 -311
  235. package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +140 -115
  236. package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +119 -0
  237. package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +463 -0
  238. package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +19 -4
  239. package/dist/extensions/pi-subagents/src/runs/shared/child-launch-plan.ts +151 -0
  240. package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +21 -7
  241. package/dist/extensions/pi-subagents/src/runs/shared/claude-code-adapter.ts +129 -0
  242. package/dist/extensions/pi-subagents/src/runs/shared/codex-exec-adapter.ts +129 -0
  243. package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +89 -0
  244. package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +5 -4
  245. package/dist/extensions/pi-subagents/src/runs/shared/cursor-agent-adapter.ts +114 -0
  246. package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +3 -3
  247. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-contract.ts +167 -0
  248. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +122 -0
  249. package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +348 -55
  250. package/dist/extensions/pi-subagents/src/runs/shared/fast-mode-extension.ts +5 -5
  251. package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +230 -0
  252. package/dist/extensions/pi-subagents/src/runs/shared/lane-metadata.ts +105 -0
  253. package/dist/extensions/pi-subagents/src/runs/shared/launch-cwd.ts +16 -0
  254. package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +2 -1
  255. package/dist/extensions/pi-subagents/src/runs/shared/mcp-config-sources.ts +422 -0
  256. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +221 -158
  257. package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-grant.ts +197 -0
  258. package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +69 -7
  259. package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +47 -6
  260. package/dist/extensions/pi-subagents/src/runs/shared/mutation-evidence.ts +7 -2
  261. package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +9 -3
  262. package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +9 -5
  263. package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +419 -7
  264. package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +15 -1
  265. package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +81 -8
  266. package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +13 -0
  267. package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +21 -1
  268. package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +44 -4
  269. package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +98 -13
  270. package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +1 -1
  271. package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +847 -0
  272. package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +18 -0
  273. package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +46 -0
  274. package/dist/extensions/pi-subagents/src/shared/extension-context.ts +24 -0
  275. package/dist/extensions/pi-subagents/src/shared/fork-context.ts +21 -0
  276. package/dist/extensions/pi-subagents/src/shared/formatters.ts +18 -3
  277. package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +5 -1
  278. package/dist/extensions/pi-subagents/src/shared/pruned-fork.ts +450 -0
  279. package/dist/extensions/pi-subagents/src/shared/session-file-trust.ts +19 -0
  280. package/dist/extensions/pi-subagents/src/shared/session-tokens.ts +14 -3
  281. package/dist/extensions/pi-subagents/src/shared/settings.ts +19 -105
  282. package/dist/extensions/pi-subagents/src/shared/shortcuts.ts +17 -0
  283. package/dist/extensions/pi-subagents/src/shared/types.ts +359 -40
  284. package/dist/extensions/pi-subagents/src/shared/utils.ts +41 -84
  285. package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +116 -0
  286. package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -9
  287. package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +0 -4
  288. package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +1 -2
  289. package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +378 -88
  290. package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +22 -11
  291. package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +3 -0
  292. package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +147 -79
  293. package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +11 -5
  294. package/dist/extensions/pi-subagents/src/tui/fleet.ts +39 -18
  295. package/dist/extensions/pi-subagents/src/tui/render.ts +369 -46
  296. package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +1 -1
  297. package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +6 -3
  298. package/dist/extensions/pi-subagents/src/workflows/host-command.ts +230 -0
  299. package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +740 -58
  300. package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +121 -0
  301. package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +270 -0
  302. package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +195 -6
  303. package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +246 -0
  304. package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +2 -2
  305. package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1114 -260
  306. package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +34 -0
  307. package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +150 -3
  308. package/dist/extensions/pi-subagents/test/integration/claude-code-smoke.test.ts +52 -0
  309. package/dist/extensions/pi-subagents/test/integration/claude-code-writer-smoke.test.ts +55 -0
  310. package/dist/extensions/pi-subagents/test/integration/codex-exec-smoke.test.ts +53 -0
  311. package/dist/extensions/pi-subagents/test/integration/codex-exec-writer-smoke.test.ts +57 -0
  312. package/dist/extensions/pi-subagents/test/integration/cursor-agent-smoke.test.ts +59 -0
  313. package/dist/extensions/pi-subagents/test/integration/cursor-agent-writer-smoke.test.ts +62 -0
  314. package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +57 -1
  315. package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +1 -0
  316. package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +20 -0
  317. package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +4 -3
  318. package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +2 -2
  319. package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +54 -4
  320. package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +482 -4
  321. package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +157 -9
  322. package/dist/extensions/pi-subagents/test/integration/session-tokens.test.ts +5 -5
  323. package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1508 -291
  324. package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +423 -1
  325. package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +8 -0
  326. package/dist/extensions/pi-subagents/test/support/cursor-smoke-inputs.ts +51 -0
  327. package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
  328. package/dist/extensions/pi-subagents/test/support/mock-pi.ts +5 -5
  329. package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +6 -6
  330. package/dist/extensions/pi-subagents/test/unit/abort-recovery.test.ts +152 -0
  331. package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +48 -0
  332. package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +184 -6
  333. package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +66 -6
  334. package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +77 -0
  335. package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +18 -0
  336. package/dist/extensions/pi-subagents/test/unit/anti-slop-oxlint.test.ts +86 -0
  337. package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +1 -1
  338. package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +101 -1
  339. package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +121 -0
  340. package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +28 -0
  341. package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +14 -7
  342. package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +53 -0
  343. package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +190 -0
  344. package/dist/extensions/pi-subagents/test/unit/async-status-snapshot.test.ts +42 -0
  345. package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +8 -4
  346. package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +23 -0
  347. package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +78 -1
  348. package/dist/extensions/pi-subagents/test/unit/child-launch-plan.test.ts +94 -0
  349. package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +21 -0
  350. package/dist/extensions/pi-subagents/test/unit/child-session-name.test.ts +50 -0
  351. package/dist/extensions/pi-subagents/test/unit/claude-code-adapter.test.ts +245 -0
  352. package/dist/extensions/pi-subagents/test/unit/codex-exec-adapter.test.ts +192 -0
  353. package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +27 -0
  354. package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +150 -0
  355. package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +21 -0
  356. package/dist/extensions/pi-subagents/test/unit/cursor-agent-adapter.test.ts +259 -0
  357. package/dist/extensions/pi-subagents/test/unit/cursor-smoke-inputs.test.ts +77 -0
  358. package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +1 -4
  359. package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
  360. package/dist/extensions/pi-subagents/test/unit/extension-context.test.ts +27 -0
  361. package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +223 -0
  362. package/dist/extensions/pi-subagents/test/unit/fast-mode-extension.test.ts +27 -0
  363. package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +208 -2
  364. package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +29 -1
  365. package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +110 -1
  366. package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +10 -0
  367. package/dist/extensions/pi-subagents/test/unit/formatters.test.ts +14 -0
  368. package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +18 -9
  369. package/dist/extensions/pi-subagents/test/unit/herdr-session-roots-codec.test.ts +63 -0
  370. package/dist/extensions/pi-subagents/test/unit/herdr-shell-command.test.ts +2 -2
  371. package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +132 -0
  372. package/dist/extensions/pi-subagents/test/unit/host-command.test.ts +156 -0
  373. package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +98 -0
  374. package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +178 -26
  375. package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +2 -1
  376. package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +21 -0
  377. package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-grant.test.ts +138 -0
  378. package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +1 -1
  379. package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +91 -0
  380. package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +72 -7
  381. package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +21 -0
  382. package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +1 -0
  383. package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +20 -2
  384. package/dist/extensions/pi-subagents/test/unit/notify.test.ts +129 -1
  385. package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +2 -2
  386. package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +4 -0
  387. package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +358 -0
  388. package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +574 -21
  389. package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +109 -1
  390. package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +71 -1
  391. package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +7 -7
  392. package/dist/extensions/pi-subagents/test/unit/pruned-fork.test.ts +214 -0
  393. package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +29 -8
  394. package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +53 -0
  395. package/dist/extensions/pi-subagents/test/unit/result-delivery-ownership.test.ts +34 -0
  396. package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +101 -3
  397. package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +1 -0
  398. package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +10 -8
  399. package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +71 -1
  400. package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +41 -7
  401. package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +136 -2
  402. package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +137 -0
  403. package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +33 -12
  404. package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +504 -1
  405. package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +8 -0
  406. package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
  407. package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +12 -1
  408. package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +3 -5
  409. package/dist/extensions/pi-subagents/test/unit/steering.test.ts +5 -6
  410. package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +0 -8
  411. package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +5 -0
  412. package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +157 -2
  413. package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +1 -1
  414. package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +63 -4
  415. package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +27 -23
  416. package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +44 -0
  417. package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +1 -0
  418. package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +7 -5
  419. package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +106 -0
  420. package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +484 -9
  421. package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +38 -4
  422. package/dist/extensions/pi-subagents/test/unit/workflow-preflight.test.ts +155 -0
  423. package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +318 -0
  424. package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +365 -0
  425. package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +349 -0
  426. package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +21 -0
  427. package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +2 -7
  428. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/effect/index.ts +13 -0
  429. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/effect/rules/no-service-constructor-imports.ts +52 -0
  430. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/index.ts +41 -0
  431. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-chained-type-assertions.ts +77 -0
  432. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-conditional-empty-object-spread.ts +49 -0
  433. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-known-value-widening.ts +247 -0
  434. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-module-mocking.ts +91 -0
  435. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-object-parameters.ts +126 -0
  436. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-reflect-apply.ts +28 -0
  437. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-reflect-get.ts +28 -0
  438. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-runtime-typeof.ts +67 -0
  439. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-shape-in-symbol-names.ts +39 -0
  440. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-parameters.ts +83 -0
  441. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-returns.ts +115 -0
  442. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unknown-type-aliases.ts +72 -0
  443. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-unsafe-dictionary-type.ts +134 -0
  444. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/no-widen-then-assert.ts +366 -0
  445. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/rules/require-safety-comment-for-type-assertion.ts +62 -0
  446. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/dictionary-types.ts +502 -0
  447. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/lexical-type-parameters.ts +60 -0
  448. package/dist/extensions/pi-subagents/tools/oxlint/anti-slop/shared/reflect-method.ts +35 -0
  449. package/dist/extensions/pi-tool-display/tests/capabilities.test.ts +1 -1
  450. package/dist/extensions/pi-tool-display/tests/settings-inspector.test.ts +2 -2
  451. package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +1 -1
  452. package/dist/modes/interactive/interactive-mode.js +7 -7
  453. package/dist/skills/workflow/SKILL.md +65 -50
  454. package/package.json +112 -110
  455. package/dist/extensions/enable-readonly-tools.test.ts +0 -63
  456. package/dist/extensions/enable-readonly-tools.ts +0 -24
  457. package/dist/extensions/model-prompt-injector/config.json +0 -16
  458. package/dist/extensions/model-prompt-injector/index.test.ts +0 -102
  459. package/dist/extensions/model-prompt-injector/index.ts +0 -148
  460. package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +0 -98
  461. package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +0 -250
@@ -8,7 +8,8 @@ import { parse as parseYaml } from "yaml";
8
8
  import * as os from "node:os";
9
9
  import * as path from "node:path";
10
10
  import { fileURLToPath } from "node:url";
11
- import type { AcceptanceInput, AcceptanceRole, AgentRunnerConfig, OutputMode, ToolBudgetConfig, TurnBudgetConfig } from "../shared/types.ts";
11
+ import type { AcceptanceInput, AcceptanceRole, AgentRunnerConfig, OutputMode, ToolBudgetConfig } from "../shared/types.ts";
12
+ import { CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL, isCodeOwnedExternalCliAdapterId, parseExternalCliCapabilityNarrowing, validateCodeOwnedProfileRunner } from "../runs/shared/external-cli-contract.ts";
12
13
  import { getAgentDir, getProjectConfigDir } from "../shared/utils.ts";
13
14
  import { KNOWN_FIELDS } from "./agent-serializer.ts";
14
15
  import { parseChain, parseJsonChain } from "./chain-serializer.ts";
@@ -19,7 +20,6 @@ import { parseModelScopeConfig, type ModelScopeConfig } from "../runs/shared/mod
19
20
  export { BUILTIN_AGENT_NAMES } from "./builtin-names.ts";
20
21
  export { buildRuntimeName, frontmatterNameForConfig, parsePackageName } from "./identity.ts";
21
22
  import { parseMemoryFrontmatter } from "./agent-memory.ts";
22
- import { resolveTurnBudgetConfig } from "../runs/shared/turn-budget.ts";
23
23
  import { validateAcceptanceInput } from "../runs/shared/acceptance.ts";
24
24
  import { validatePermissionRules, type PermissionRules } from "../runs/shared/permissions.ts";
25
25
  import { parseThinkingLevel, type ThinkingLevel } from "../shared/thinking-ceiling.ts";
@@ -61,6 +61,7 @@ export interface BuiltinAgentOverrideBase {
61
61
  thinking?: string | false;
62
62
  systemPromptMode: SystemPromptMode;
63
63
  inheritProjectContext: boolean;
64
+ inheritGlobalContext: boolean;
64
65
  inheritSkills: boolean;
65
66
  defaultContext?: AgentDefaultContext;
66
67
  acceptanceRole?: AcceptanceRole;
@@ -69,9 +70,11 @@ export interface BuiltinAgentOverrideBase {
69
70
  skills?: string[];
70
71
  skillPath?: string[];
71
72
  tools?: string[];
73
+ allowNestedSubagents?: boolean;
72
74
  mcpDirectTools?: string[];
73
75
  extensions?: string[];
74
76
  subagentOnlyExtensions?: string[];
77
+ mutationTools?: string[];
75
78
  completionGuard?: boolean;
76
79
  toolBudget?: ToolBudgetConfig;
77
80
  }
@@ -88,6 +91,7 @@ interface BuiltinAgentOverrideConfig {
88
91
  thinking?: string | false;
89
92
  systemPromptMode?: SystemPromptMode;
90
93
  inheritProjectContext?: boolean;
94
+ inheritGlobalContext?: boolean;
91
95
  inheritSkills?: boolean;
92
96
  defaultContext?: AgentDefaultContext | false;
93
97
  acceptanceRole?: AcceptanceRole | false;
@@ -95,8 +99,10 @@ interface BuiltinAgentOverrideConfig {
95
99
  systemPrompt?: string;
96
100
  skills?: string[] | false;
97
101
  tools?: string[] | false | "inherit";
102
+ allowNestedSubagents?: boolean;
98
103
  extensions?: string[] | false;
99
104
  subagentOnlyExtensions?: string[] | false;
105
+ mutationTools?: string[] | false;
100
106
  completionGuard?: boolean;
101
107
  toolBudget?: ToolBudgetConfig | false;
102
108
  }
@@ -126,6 +132,7 @@ export interface AgentConfig {
126
132
  description: string;
127
133
  aliases?: string[];
128
134
  tools?: string[];
135
+ allowNestedSubagents?: boolean;
129
136
  mcpDirectTools?: string[];
130
137
  model?: string;
131
138
  modelProvider?: string;
@@ -134,12 +141,12 @@ export interface AgentConfig {
134
141
  thinking?: string | false;
135
142
  systemPromptMode: SystemPromptMode;
136
143
  inheritProjectContext: boolean;
144
+ inheritGlobalContext: boolean;
137
145
  inheritSkills: boolean;
138
146
  defaultContext?: AgentDefaultContext;
139
147
  defaultAsync?: boolean;
140
148
  defaultTimeoutMs?: number;
141
149
  defaultToolTimeoutMs?: number;
142
- defaultTurnBudget?: TurnBudgetConfig;
143
150
  defaultAcceptance?: AcceptanceInput;
144
151
  acceptanceRole?: AcceptanceRole;
145
152
  systemPrompt: string;
@@ -151,6 +158,7 @@ export interface AgentConfig {
151
158
  extensions?: string[];
152
159
  extensionsFromDefault?: boolean;
153
160
  subagentOnlyExtensions?: string[];
161
+ mutationTools?: string[];
154
162
  output?: string;
155
163
  outputMode?: OutputMode;
156
164
  defaultReads?: string[];
@@ -172,6 +180,7 @@ type ProjectRootResolution = "nearest" | "git-root";
172
180
 
173
181
  interface SubagentSettings {
174
182
  overrides: Record<string, BuiltinAgentOverrideConfig>;
183
+ providerOverrides: Record<string, Record<string, BuiltinAgentOverrideConfig>>;
175
184
  defaultModel?: string;
176
185
  defaultProvider?: string;
177
186
  defaultThinking?: string;
@@ -182,7 +191,7 @@ interface SubagentSettings {
182
191
  modelScope?: ModelScopeConfig;
183
192
  }
184
193
 
185
- const EMPTY_SUBAGENT_SETTINGS: SubagentSettings = { overrides: {} };
194
+ const EMPTY_SUBAGENT_SETTINGS: SubagentSettings = { overrides: {}, providerOverrides: {} };
186
195
  const agentFrontmatterFields = new WeakMap<AgentConfig, Set<string>>();
187
196
 
188
197
  export interface ChainStepConfig {
@@ -262,14 +271,72 @@ export function findBlockingAgentDiagnostic(name: string, agent: AgentConfig | r
262
271
  return !agents.length || (match && agentDefinitionPriority(match) > highestPriority) ? match : undefined;
263
272
  }
264
273
 
265
- interface AgentDiscoveryResult {
274
+ export type AgentDefinitionDirectoryState = "absent" | "empty" | "candidates" | "unreadable" | "not-directory";
275
+
276
+ /** A definition directory actually inspected during one agent-discovery operation. */
277
+ export interface AgentDefinitionDirectoryReport {
278
+ source: AgentSource;
279
+ path: string;
280
+ state: AgentDefinitionDirectoryState;
281
+ candidateCount?: number;
282
+ }
283
+
284
+ /**
285
+ * Filesystem provenance for a failed agent resolution. Context is created from
286
+ * the discovery result that supplied the effective agents; callers must not
287
+ * pair arbitrary agent arrays with these directory reports.
288
+ */
289
+ export interface UnknownAgentDiagnosticContext {
290
+ cwd: string;
291
+ scope: AgentScope;
292
+ directories: readonly AgentDefinitionDirectoryReport[];
293
+ agents: readonly AgentConfig[];
294
+ }
295
+
296
+ export interface AgentDiscoveryResult {
266
297
  agents: AgentConfig[];
267
298
  agentDiagnostics?: AgentDiscoveryDiagnostic[];
268
299
  projectAgentsDir: string | null;
300
+ cwd: string;
301
+ scope: AgentScope;
302
+ directories: readonly AgentDefinitionDirectoryReport[];
269
303
  modelScope?: ModelScopeConfig;
270
304
  maxThinking?: ThinkingLevel;
271
305
  }
272
306
 
307
+ /** Create formatter input from the exact discovery operation used for resolution. */
308
+ export function unknownAgentDiagnosticContext(discovered: Pick<AgentDiscoveryResult, "cwd" | "scope" | "directories" | "agents">): UnknownAgentDiagnosticContext {
309
+ return {
310
+ cwd: discovered.cwd,
311
+ scope: discovered.scope,
312
+ directories: discovered.directories,
313
+ agents: discovered.agents,
314
+ };
315
+ }
316
+
317
+ /** Render local discovery evidence without exposing filesystem error details. */
318
+ export function formatUnknownAgentError(name: string, context: UnknownAgentDiagnosticContext, prefix = "Unknown agent"): string {
319
+ const directories = context.directories.map((directory) => {
320
+ const state = directory.state === "candidates"
321
+ ? `${directory.candidateCount ?? 0} candidate${directory.candidateCount === 1 ? "" : "s"}`
322
+ : directory.state === "empty" ? "present but empty"
323
+ : directory.state === "not-directory" ? "not a directory"
324
+ : directory.state;
325
+ return `- ${directory.source}: ${directory.path} (${state})`;
326
+ });
327
+ const agents = [...context.agents]
328
+ .sort((left, right) => left.name.localeCompare(right.name) || left.source.localeCompare(right.source))
329
+ .map((agent) => `- ${agent.name} (${agent.source})`);
330
+ return [
331
+ `${prefix}: ${name}`,
332
+ `Effective cwd: ${path.resolve(context.cwd)}`,
333
+ "Consulted agent-definition directories:",
334
+ ...(directories.length ? directories : ["- (none)"]),
335
+ "Discovered agents:",
336
+ ...(agents.length ? agents : ["- (none)"]),
337
+ ].join("\n");
338
+ }
339
+
273
340
  function getUserChainDir(): string {
274
341
  return path.join(getAgentDir(), "chains");
275
342
  }
@@ -381,6 +448,10 @@ function resolveSettingsPackageRoot(source: string, baseDir: string): string | u
381
448
  if (normalized === "." || normalized === ".." || normalized.startsWith("./") || normalized.startsWith("../")) {
382
449
  return path.resolve(baseDir, normalized);
383
450
  }
451
+ if (/^https?:\/\//i.test(trimmed)) {
452
+ const parsed = parseGitPackagePath(`git:${trimmed}`);
453
+ return parsed ? path.join(baseDir, "git", parsed.host, parsed.repoPath) : undefined;
454
+ }
384
455
  return undefined;
385
456
  }
386
457
 
@@ -647,6 +718,7 @@ function cloneOverrideBase(agent: AgentConfig): BuiltinAgentOverrideBase {
647
718
  ...(agent.thinking !== undefined ? { thinking: agent.thinking } : {}),
648
719
  systemPromptMode: agent.systemPromptMode,
649
720
  inheritProjectContext: agent.inheritProjectContext,
721
+ inheritGlobalContext: agent.inheritGlobalContext,
650
722
  inheritSkills: agent.inheritSkills,
651
723
  ...(agent.defaultContext !== undefined ? { defaultContext: agent.defaultContext } : {}),
652
724
  ...(agent.acceptanceRole !== undefined ? { acceptanceRole: agent.acceptanceRole } : {}),
@@ -655,9 +727,11 @@ function cloneOverrideBase(agent: AgentConfig): BuiltinAgentOverrideBase {
655
727
  ...(agent.skills ? { skills: [...agent.skills] } : {}),
656
728
  ...(agent.skillPath ? { skillPath: [...agent.skillPath] } : {}),
657
729
  ...(agent.tools ? { tools: [...agent.tools] } : {}),
730
+ ...(agent.allowNestedSubagents !== undefined ? { allowNestedSubagents: agent.allowNestedSubagents } : {}),
658
731
  ...(agent.mcpDirectTools ? { mcpDirectTools: [...agent.mcpDirectTools] } : {}),
659
732
  ...(!agent.extensionsFromDefault && agent.extensions ? { extensions: [...agent.extensions] } : {}),
660
733
  ...(agent.subagentOnlyExtensions ? { subagentOnlyExtensions: [...agent.subagentOnlyExtensions] } : {}),
734
+ ...(agent.mutationTools ? { mutationTools: [...agent.mutationTools] } : {}),
661
735
  ...(agent.completionGuard !== undefined ? { completionGuard: agent.completionGuard } : {}),
662
736
  ...(agent.toolBudget !== undefined ? { toolBudget: agent.toolBudget } : {}),
663
737
  };
@@ -678,6 +752,7 @@ function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentO
678
752
  ...(override.thinking !== undefined ? { thinking: override.thinking } : {}),
679
753
  ...(override.systemPromptMode !== undefined ? { systemPromptMode: override.systemPromptMode } : {}),
680
754
  ...(override.inheritProjectContext !== undefined ? { inheritProjectContext: override.inheritProjectContext } : {}),
755
+ ...(override.inheritGlobalContext !== undefined ? { inheritGlobalContext: override.inheritGlobalContext } : {}),
681
756
  ...(override.inheritSkills !== undefined ? { inheritSkills: override.inheritSkills } : {}),
682
757
  ...(override.defaultContext !== undefined ? { defaultContext: override.defaultContext } : {}),
683
758
  ...(override.acceptanceRole !== undefined ? { acceptanceRole: override.acceptanceRole } : {}),
@@ -685,8 +760,10 @@ function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentO
685
760
  ...(override.systemPrompt !== undefined ? { systemPrompt: override.systemPrompt } : {}),
686
761
  ...(override.skills !== undefined ? { skills: override.skills === false ? false : [...override.skills] } : {}),
687
762
  ...(override.tools !== undefined ? { tools: Array.isArray(override.tools) ? [...override.tools] : override.tools } : {}),
763
+ ...(override.allowNestedSubagents !== undefined ? { allowNestedSubagents: override.allowNestedSubagents } : {}),
688
764
  ...(override.extensions !== undefined ? { extensions: override.extensions === false ? false : [...override.extensions] } : {}),
689
765
  ...(override.subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions: override.subagentOnlyExtensions === false ? false : [...override.subagentOnlyExtensions] } : {}),
766
+ ...(override.mutationTools !== undefined ? { mutationTools: override.mutationTools === false ? false : [...override.mutationTools] } : {}),
690
767
  ...(override.completionGuard !== undefined ? { completionGuard: override.completionGuard } : {}),
691
768
  ...(override.toolBudget !== undefined ? { toolBudget: override.toolBudget === false ? false : { ...override.toolBudget, ...(Array.isArray(override.toolBudget.block) ? { block: [...override.toolBudget.block] } : {}) } } : {}),
692
769
  };
@@ -736,7 +813,7 @@ export function findNearestProjectRoot(cwd: string): string | null {
736
813
  return findProjectRootCandidates(cwd)[0] ?? null;
737
814
  }
738
815
 
739
- function findConfiguredProjectRoot(cwd: string): string | null {
816
+ export function findConfiguredProjectRoot(cwd: string): string | null {
740
817
  const candidates = findProjectRootCandidates(cwd);
741
818
  const nearestRoot = candidates[0];
742
819
  if (!nearestRoot) return null;
@@ -895,6 +972,14 @@ function parseBuiltinOverrideEntry(
895
972
  }
896
973
  }
897
974
 
975
+ if ("inheritGlobalContext" in input) {
976
+ if (typeof input.inheritGlobalContext === "boolean") {
977
+ override.inheritGlobalContext = input.inheritGlobalContext;
978
+ } else {
979
+ throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'inheritGlobalContext'; expected a boolean.`);
980
+ }
981
+ }
982
+
898
983
  if ("inheritSkills" in input) {
899
984
  if (typeof input.inheritSkills === "boolean") {
900
985
  override.inheritSkills = input.inheritSkills;
@@ -967,6 +1052,10 @@ function parseBuiltinOverrideEntry(
967
1052
 
968
1053
  const tools = parseToolsOverride(input.tools, { filePath, name });
969
1054
  if (tools !== undefined) override.tools = tools;
1055
+ if ("allowNestedSubagents" in input) {
1056
+ if (typeof input.allowNestedSubagents === "boolean") override.allowNestedSubagents = input.allowNestedSubagents;
1057
+ else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'allowNestedSubagents'; expected a boolean.`);
1058
+ }
970
1059
 
971
1060
  const extensions = parseOverrideStringArrayOrFalse(input.extensions, { filePath, name, field: "extensions" });
972
1061
  if (extensions !== undefined) override.extensions = extensions;
@@ -974,6 +1063,9 @@ function parseBuiltinOverrideEntry(
974
1063
  const subagentOnlyExtensions = parseOverrideStringArrayOrFalse(input.subagentOnlyExtensions, { filePath, name, field: "subagentOnlyExtensions" });
975
1064
  if (subagentOnlyExtensions !== undefined) override.subagentOnlyExtensions = subagentOnlyExtensions;
976
1065
 
1066
+ const mutationTools = parseOverrideStringArrayOrFalse(input.mutationTools, { filePath, name, field: "mutationTools" });
1067
+ if (mutationTools !== undefined) override.mutationTools = mutationTools;
1068
+
977
1069
  return Object.keys(override).length > 0 ? override : undefined;
978
1070
  }
979
1071
 
@@ -1043,9 +1135,12 @@ function readSubagentSettings(filePath: string | null): SubagentSettings {
1043
1135
  const modelScope = parseModelScopeConfig(subagentsObject.modelScope, { filePath });
1044
1136
 
1045
1137
  const parsed: Record<string, BuiltinAgentOverrideConfig> = {};
1138
+ const providerOverrides: Record<string, Record<string, BuiltinAgentOverrideConfig>> = {};
1046
1139
  const agentOverrides = subagentsObject.agentOverrides;
1140
+ const agentOverridesByProvider = subagentsObject.agentOverridesByProvider;
1047
1141
  const parsedSettings: SubagentSettings = {
1048
1142
  overrides: parsed,
1143
+ providerOverrides,
1049
1144
  ...(defaultModel !== undefined ? { defaultModel } : {}),
1050
1145
  ...(defaultProvider !== undefined ? { defaultProvider } : {}),
1051
1146
  ...(defaultThinking !== undefined ? { defaultThinking } : {}),
@@ -1055,16 +1150,42 @@ function readSubagentSettings(filePath: string | null): SubagentSettings {
1055
1150
  ...(disableThinking !== undefined ? { disableThinking } : {}),
1056
1151
  ...(modelScope !== undefined ? { modelScope } : {}),
1057
1152
  };
1058
- if (!agentOverrides || typeof agentOverrides !== "object" || Array.isArray(agentOverrides)) {
1059
- return parsedSettings;
1153
+ if (agentOverrides && typeof agentOverrides === "object" && !Array.isArray(agentOverrides)) {
1154
+ for (const [name, value] of Object.entries(agentOverrides)) {
1155
+ const override = parseBuiltinOverrideEntry(name, value, filePath);
1156
+ if (override) parsed[name] = override;
1157
+ }
1060
1158
  }
1061
- for (const [name, value] of Object.entries(agentOverrides)) {
1062
- const override = parseBuiltinOverrideEntry(name, value, filePath);
1063
- if (override) parsed[name] = override;
1159
+ if (agentOverridesByProvider !== undefined) {
1160
+ if (!agentOverridesByProvider || typeof agentOverridesByProvider !== "object" || Array.isArray(agentOverridesByProvider)) {
1161
+ throw new Error(`Subagent settings in '${filePath}' have invalid 'agentOverridesByProvider'; expected an object keyed by provider.`);
1162
+ }
1163
+ for (const [provider, value] of Object.entries(agentOverridesByProvider)) {
1164
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1165
+ throw new Error(`Subagent settings in '${filePath}' have invalid 'agentOverridesByProvider.${provider}'; expected an object keyed by agent.`);
1166
+ }
1167
+ const entries: Record<string, BuiltinAgentOverrideConfig> = {};
1168
+ for (const [agentName, agentValue] of Object.entries(value)) {
1169
+ const override = parseBuiltinOverrideEntry(`agentOverridesByProvider.${provider}.${agentName}`, agentValue, filePath);
1170
+ if (override) entries[agentName] = override;
1171
+ }
1172
+ providerOverrides[provider] = entries;
1173
+ }
1064
1174
  }
1065
1175
  return parsedSettings;
1066
1176
  }
1067
1177
 
1178
+ function selectProviderOverrides(settings: SubagentSettings, provider: string | undefined): SubagentSettings {
1179
+ if (!provider) return settings;
1180
+ const selected = settings.providerOverrides[provider];
1181
+ if (!selected) return settings;
1182
+ const overrides = { ...settings.overrides };
1183
+ for (const [name, override] of Object.entries(selected)) {
1184
+ overrides[name] = { ...overrides[name], ...override };
1185
+ }
1186
+ return { ...settings, overrides };
1187
+ }
1188
+
1068
1189
  function resolveSubagentDefaultProvider(
1069
1190
  userSettings: SubagentSettings,
1070
1191
  projectSettings: SubagentSettings,
@@ -1209,6 +1330,7 @@ function applyBuiltinOverride(
1209
1330
  if (override.thinking !== undefined) { if (override.thinking === false) delete next.thinking; else next.thinking = override.thinking; }
1210
1331
  if (override.systemPromptMode !== undefined) next.systemPromptMode = override.systemPromptMode;
1211
1332
  if (override.inheritProjectContext !== undefined) next.inheritProjectContext = override.inheritProjectContext;
1333
+ if (override.inheritGlobalContext !== undefined) next.inheritGlobalContext = override.inheritGlobalContext;
1212
1334
  if (override.inheritSkills !== undefined) next.inheritSkills = override.inheritSkills;
1213
1335
  if (override.defaultContext !== undefined) { if (override.defaultContext === false) delete next.defaultContext; else next.defaultContext = override.defaultContext; }
1214
1336
  if (override.acceptanceRole !== undefined) { if (override.acceptanceRole === false) delete next.acceptanceRole; else next.acceptanceRole = override.acceptanceRole; }
@@ -1216,8 +1338,10 @@ function applyBuiltinOverride(
1216
1338
  if (override.systemPrompt !== undefined) next.systemPrompt = override.systemPrompt;
1217
1339
  if (override.skills !== undefined) { if (override.skills === false) delete next.skills; else next.skills = [...override.skills]; }
1218
1340
  if (override.tools !== undefined) applyToolsOverride(next, override.tools);
1341
+ if (override.allowNestedSubagents !== undefined) next.allowNestedSubagents = override.allowNestedSubagents;
1219
1342
  if (override.extensions !== undefined) { if (override.extensions === false) delete next.extensions; else next.extensions = [...override.extensions]; }
1220
1343
  if (override.subagentOnlyExtensions !== undefined) { if (override.subagentOnlyExtensions === false) delete next.subagentOnlyExtensions; else next.subagentOnlyExtensions = [...override.subagentOnlyExtensions]; }
1344
+ if (override.mutationTools !== undefined) { if (override.mutationTools === false) delete next.mutationTools; else next.mutationTools = [...override.mutationTools]; }
1221
1345
  if (override.completionGuard !== undefined) next.completionGuard = override.completionGuard;
1222
1346
  if (override.toolBudget !== undefined) { if (override.toolBudget === false) delete next.toolBudget; else next.toolBudget = override.toolBudget; }
1223
1347
 
@@ -1355,6 +1479,9 @@ function applyCustomAgentOverride(
1355
1479
  if (override.inheritProjectContext !== undefined) {
1356
1480
  fill("inheritProjectContext", ["inheritProjectContext"], override.inheritProjectContext);
1357
1481
  }
1482
+ if (override.inheritGlobalContext !== undefined) {
1483
+ fill("inheritGlobalContext", ["inheritGlobalContext"], override.inheritGlobalContext);
1484
+ }
1358
1485
  if (override.inheritSkills !== undefined) {
1359
1486
  fill("inheritSkills", ["inheritSkills"], override.inheritSkills);
1360
1487
  }
@@ -1376,6 +1503,9 @@ function applyCustomAgentOverride(
1376
1503
  applyToolsOverride(mutable(), override.tools);
1377
1504
  anyFilled = true;
1378
1505
  }
1506
+ if (override.allowNestedSubagents !== undefined) {
1507
+ fill("allowNestedSubagents", ["allowNestedSubagents"], override.allowNestedSubagents);
1508
+ }
1379
1509
  if (override.extensions !== undefined) {
1380
1510
  fill("extensions", ["extensions"], override.extensions === false ? undefined : [...override.extensions]);
1381
1511
  }
@@ -1386,6 +1516,9 @@ function applyCustomAgentOverride(
1386
1516
  override.subagentOnlyExtensions === false ? undefined : [...override.subagentOnlyExtensions],
1387
1517
  );
1388
1518
  }
1519
+ if (override.mutationTools !== undefined) {
1520
+ fill("mutationTools", ["mutationTools"], override.mutationTools === false ? undefined : [...override.mutationTools]);
1521
+ }
1389
1522
  if (override.completionGuard !== undefined) {
1390
1523
  fill("completionGuard", ["completionGuard"], override.completionGuard);
1391
1524
  }
@@ -1425,7 +1558,7 @@ function applyCustomAgentOverrides(
1425
1558
 
1426
1559
  export function buildBuiltinOverrideConfig(
1427
1560
  base: BuiltinAgentOverrideBase,
1428
- draft: Pick<AgentConfig, "model" | "modelProvider" | "fallbackModels" | "fast" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "acceptanceRole" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools" | "extensions" | "subagentOnlyExtensions" | "completionGuard" | "toolBudget"> & Partial<Pick<AgentConfig, "description" | "output" | "outputMode" | "defaultReads">>,
1561
+ draft: Pick<AgentConfig, "model" | "modelProvider" | "fallbackModels" | "fast" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritGlobalContext" | "inheritSkills" | "defaultContext" | "acceptanceRole" | "disabled" | "systemPrompt" | "skills" | "tools" | "allowNestedSubagents" | "mcpDirectTools" | "extensions" | "subagentOnlyExtensions" | "mutationTools" | "completionGuard" | "toolBudget"> & Partial<Pick<AgentConfig, "description" | "output" | "outputMode" | "defaultReads">>,
1429
1562
  ): BuiltinAgentOverrideConfig | undefined {
1430
1563
  const override: BuiltinAgentOverrideConfig = {};
1431
1564
 
@@ -1443,6 +1576,7 @@ export function buildBuiltinOverrideConfig(
1443
1576
  if (draft.thinking !== base.thinking) override.thinking = draft.thinking ?? false;
1444
1577
  if (draft.systemPromptMode !== base.systemPromptMode) override.systemPromptMode = draft.systemPromptMode;
1445
1578
  if (draft.inheritProjectContext !== base.inheritProjectContext) override.inheritProjectContext = draft.inheritProjectContext;
1579
+ if (draft.inheritGlobalContext !== base.inheritGlobalContext) override.inheritGlobalContext = draft.inheritGlobalContext;
1446
1580
  if (draft.inheritSkills !== base.inheritSkills) override.inheritSkills = draft.inheritSkills;
1447
1581
  if (draft.defaultContext !== base.defaultContext) override.defaultContext = draft.defaultContext ?? false;
1448
1582
  if (draft.acceptanceRole !== base.acceptanceRole) override.acceptanceRole = draft.acceptanceRole ?? false;
@@ -1453,10 +1587,12 @@ export function buildBuiltinOverrideConfig(
1453
1587
  const baseTools = joinToolList(base);
1454
1588
  const draftTools = joinToolList(draft);
1455
1589
  if (!arraysEqual(draftTools, baseTools)) override.tools = draftTools ? [...draftTools] : false;
1590
+ if (draft.allowNestedSubagents !== base.allowNestedSubagents) override.allowNestedSubagents = draft.allowNestedSubagents === true;
1456
1591
  if (!arraysEqual(draft.extensions, base.extensions)) override.extensions = draft.extensions ? [...draft.extensions] : false;
1457
1592
  if (!arraysEqual(draft.subagentOnlyExtensions, base.subagentOnlyExtensions)) {
1458
1593
  override.subagentOnlyExtensions = draft.subagentOnlyExtensions ? [...draft.subagentOnlyExtensions] : false;
1459
1594
  }
1595
+ if (!arraysEqual(draft.mutationTools, base.mutationTools)) override.mutationTools = draft.mutationTools ? [...draft.mutationTools] : false;
1460
1596
  if ((draft.completionGuard !== false) !== (base.completionGuard !== false)) {
1461
1597
  override.completionGuard = draft.completionGuard !== false;
1462
1598
  }
@@ -1586,7 +1722,7 @@ export function removeBuiltinAgentOverrideFields(
1586
1722
  return { path: filePath, removed: true };
1587
1723
  }
1588
1724
 
1589
- const DISCOVERY_PRUNED_DIR_NAMES = new Set([".git", "node_modules"]);
1725
+ const DISCOVERY_PRUNED_DIR_NAMES = new Set([".git", "node_modules", ".pi", ".selesai", "sync-backups"]);
1590
1726
 
1591
1727
  function isDiscoveryNestedProjectRoot(dir: string): boolean {
1592
1728
  return isDirectory(getProjectConfigDir(dir)) || isDirectory(path.join(dir, ".agents"));
@@ -1598,9 +1734,22 @@ function shouldPruneDiscoveryDir(rootDir: string, dir: string, dirName: string):
1598
1734
  return path.resolve(dir) !== path.resolve(rootDir) && isDiscoveryNestedProjectRoot(dir);
1599
1735
  }
1600
1736
 
1601
- function listFilesRecursive(dir: string, predicate: (fileName: string) => boolean, rootDir = dir): string[] {
1737
+ function listFilesRecursive(
1738
+ dir: string,
1739
+ predicate: (fileName: string) => boolean,
1740
+ rootDir = dir,
1741
+ visitedDirectories = new Set<string>(),
1742
+ ): string[] {
1602
1743
  const files: string[] = [];
1603
1744
  if (!fs.existsSync(dir)) return files;
1745
+ let realDir: string;
1746
+ try {
1747
+ realDir = fs.realpathSync(dir);
1748
+ } catch {
1749
+ return files;
1750
+ }
1751
+ if (visitedDirectories.has(realDir)) return files;
1752
+ visitedDirectories.add(realDir);
1604
1753
 
1605
1754
  let entries: fs.Dirent[];
1606
1755
  try {
@@ -1611,9 +1760,17 @@ function listFilesRecursive(dir: string, predicate: (fileName: string) => boolea
1611
1760
 
1612
1761
  for (const entry of entries) {
1613
1762
  const filePath = path.join(dir, entry.name);
1614
- if (entry.isDirectory()) {
1763
+ let isDirectory = entry.isDirectory();
1764
+ if (entry.isSymbolicLink()) {
1765
+ try {
1766
+ isDirectory = fs.statSync(filePath).isDirectory();
1767
+ } catch {
1768
+ isDirectory = false;
1769
+ }
1770
+ }
1771
+ if (isDirectory) {
1615
1772
  if (!shouldPruneDiscoveryDir(rootDir, filePath, entry.name)) {
1616
- files.push(...listFilesRecursive(filePath, predicate, rootDir));
1773
+ files.push(...listFilesRecursive(filePath, predicate, rootDir, visitedDirectories));
1617
1774
  }
1618
1775
  continue;
1619
1776
  }
@@ -1624,6 +1781,81 @@ function listFilesRecursive(dir: string, predicate: (fileName: string) => boolea
1624
1781
  return files;
1625
1782
  }
1626
1783
 
1784
+ export interface AgentDefinitionInspection {
1785
+ files: string[];
1786
+ state: AgentDefinitionDirectoryState;
1787
+ }
1788
+
1789
+ /** Narrow filesystem seam so unavailable paths can be tested without permissions. */
1790
+ export interface AgentDefinitionInspectionFs {
1791
+ existsSync(filePath: string): boolean;
1792
+ realpathSync?(filePath: string): string;
1793
+ statSync(filePath: string): { isDirectory(): boolean };
1794
+ readdirSync(dir: string): fs.Dirent[];
1795
+ }
1796
+
1797
+ const DEFAULT_AGENT_DEFINITION_INSPECTION_FS: AgentDefinitionInspectionFs = {
1798
+ existsSync: fs.existsSync,
1799
+ realpathSync: fs.realpathSync,
1800
+ statSync: fs.statSync,
1801
+ readdirSync: (dir) => fs.readdirSync(dir, { withFileTypes: true }),
1802
+ };
1803
+
1804
+ /**
1805
+ * Inspect one agent-definition directory while retaining traversal failure
1806
+ * state. A nested unreadable directory makes the whole inspection unavailable,
1807
+ * preventing a partial traversal from being reported as empty or complete.
1808
+ */
1809
+ export function inspectAgentDefinitionDirectory(dir: string, operations: AgentDefinitionInspectionFs = DEFAULT_AGENT_DEFINITION_INSPECTION_FS): AgentDefinitionInspection {
1810
+ const root = path.resolve(dir);
1811
+ try {
1812
+ if (!operations.existsSync(root)) return { files: [], state: "absent" };
1813
+ if (!operations.statSync(root).isDirectory()) return { files: [], state: "not-directory" };
1814
+ } catch {
1815
+ return { files: [], state: "unreadable" };
1816
+ }
1817
+ const files: string[] = [];
1818
+ let unreadable = false;
1819
+ const visitedDirectories = new Set<string>();
1820
+ const visit = (current: string): void => {
1821
+ let realDir: string;
1822
+ try {
1823
+ realDir = operations.realpathSync?.(current) ?? path.resolve(current);
1824
+ } catch {
1825
+ unreadable = true;
1826
+ return;
1827
+ }
1828
+ if (visitedDirectories.has(realDir)) return;
1829
+ visitedDirectories.add(realDir);
1830
+
1831
+ let entries: fs.Dirent[];
1832
+ try {
1833
+ entries = operations.readdirSync(current).sort((a, b) => a.name.localeCompare(b.name));
1834
+ } catch {
1835
+ unreadable = true;
1836
+ return;
1837
+ }
1838
+ for (const entry of entries) {
1839
+ const filePath = path.join(current, entry.name);
1840
+ let isDirectory = entry.isDirectory();
1841
+ if (entry.isSymbolicLink()) {
1842
+ try {
1843
+ isDirectory = operations.statSync(filePath).isDirectory();
1844
+ } catch {
1845
+ isDirectory = false;
1846
+ }
1847
+ }
1848
+ if (isDirectory) {
1849
+ if (!shouldPruneDiscoveryDir(root, filePath, entry.name)) visit(filePath);
1850
+ continue;
1851
+ }
1852
+ if ((entry.isFile() || entry.isSymbolicLink()) && entry.name.endsWith(".md") && !entry.name.endsWith(".chain.md") && !isLegacyAgentSkillPath(root, filePath)) files.push(filePath);
1853
+ }
1854
+ };
1855
+ visit(root);
1856
+ return { files, state: unreadable ? "unreadable" : files.length ? "candidates" : "empty" };
1857
+ }
1858
+
1627
1859
  function isLegacyAgentSkillPath(rootDir: string, filePath: string): boolean {
1628
1860
  const relative = path.relative(rootDir, filePath);
1629
1861
  const parts = relative.split(path.sep).map((part) => part.toLowerCase());
@@ -1682,24 +1914,29 @@ function parseAgentRunnerFrontmatter(raw: string | undefined, agentName: string)
1682
1914
  if (runner.args !== undefined && (!Array.isArray(runner.args) || runner.args.some((arg) => typeof arg !== "string"))) {
1683
1915
  throw new Error(`Agent '${agentName}' external-cli runner args must be an array of strings.`);
1684
1916
  }
1917
+ if (runner.adapter !== undefined && !isCodeOwnedExternalCliAdapterId(runner.adapter)) throw new Error(`Agent '${agentName}' external-cli runner adapter must be ${CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL}.`);
1918
+ if (runner.adapter !== undefined && Array.isArray(runner.args) && runner.args.length > 0) throw new Error(`Agent '${agentName}' ${runner.adapter} adapter owns its argv; runner args are not supported.`);
1685
1919
  if (runner.promptDelivery !== undefined && runner.promptDelivery !== "stdin") {
1686
1920
  throw new Error(`Agent '${agentName}' external-cli runner promptDelivery must be 'stdin'.`);
1687
1921
  }
1688
- const supported = new Set(["type", "command", "args", "promptDelivery"]);
1922
+ const capabilities = parseExternalCliCapabilityNarrowing(runner.capabilities, `Agent '${agentName}' external-cli runner capabilities`);
1923
+ const supported = new Set(["type", "adapter", "command", "args", "promptDelivery", "capabilities"]);
1689
1924
  const unknown = Object.keys(runner).filter((key) => !supported.has(key));
1690
1925
  if (unknown.length > 0) throw new Error(`Agent '${agentName}' external-cli runner has unsupported fields: ${unknown.join(", ")}.`);
1691
1926
  const runnerArgs = Array.isArray(runner.args) ? runner.args.filter((arg): arg is string => typeof arg === "string") : undefined;
1692
1927
  return {
1693
1928
  type: "external-cli",
1929
+ ...(isCodeOwnedExternalCliAdapterId(runner.adapter) ? { adapter: runner.adapter } : {}),
1694
1930
  command: runner.command.trim(),
1695
1931
  ...(runnerArgs?.length ? { args: runnerArgs } : {}),
1696
1932
  ...(runner.promptDelivery ? { promptDelivery: "stdin" as const } : {}),
1933
+ ...(capabilities ? { capabilities } : {}),
1697
1934
  };
1698
1935
  }
1699
1936
 
1700
1937
  function validateExternalRunnerProfile(frontmatter: Record<string, string>, agentName: string, runner: AgentRunnerConfig | undefined): void {
1701
1938
  if (runner?.type !== "external-cli" && runner?.type !== "external-job") return;
1702
- const unsupported = ["tools", "model", "fallbackModels", "thinking", "extensions", "subagentOnlyExtensions", "maxSubagentDepth", "completionGuard", "skills", "skill", "skillPath", "toolBudget", "permission", "permissions"]
1939
+ const unsupported = ["tools", "allowNestedSubagents", "model", "fallbackModels", "thinking", "extensions", "subagentOnlyExtensions", "mutationTools", "maxSubagentDepth", "completionGuard", "skills", "skill", "skillPath", "toolBudget", "permission", "permissions"]
1703
1940
  .filter((field) => frontmatter[field] !== undefined);
1704
1941
  if (unsupported.length > 0) {
1705
1942
  throw new Error(`Agent '${agentName}' uses runner.type='${runner.type}' and declares unsupported Pi-only fields: ${unsupported.join(", ")}.`);
@@ -1724,9 +1961,9 @@ interface AgentDefinitionFile {
1724
1961
  content: string;
1725
1962
  }
1726
1963
 
1727
- function readAgentDefinitionFiles(dir: string): AgentDefinitionFile[] {
1964
+ function readAgentDefinitionFiles(dir: string, inspection = inspectAgentDefinitionDirectory(dir)): AgentDefinitionFile[] {
1728
1965
  const files: AgentDefinitionFile[] = [];
1729
- for (const filePath of listFilesRecursive(dir, (fileName) => fileName.endsWith(".md") && !fileName.endsWith(".chain.md"))) {
1966
+ for (const filePath of inspection.files) {
1730
1967
  if (isLegacyAgentSkillPath(dir, filePath)) {
1731
1968
  continue;
1732
1969
  }
@@ -1783,6 +2020,8 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
1783
2020
  const mcpDirectTools = parsedTools.mcpDirectTools ?? [];
1784
2021
  const defaultReads = parseFrontmatterList(frontmatter.defaultReads);
1785
2022
  const aliases = normalizeAgentAliases(parseFrontmatterList(frontmatter.aliases ?? frontmatter.alias), runtimeName);
2023
+ const profileError = validateCodeOwnedProfileRunner({ name: runtimeName, localName, aliases, runner });
2024
+ if (profileError) throw new Error(profileError);
1786
2025
  const skillStr = frontmatter.skill || frontmatter.skills;
1787
2026
  const skills = parseFrontmatterList(skillStr);
1788
2027
  const skillPath = parseFrontmatterList(frontmatter.skillPath);
@@ -1797,6 +2036,7 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
1797
2036
  : frontmatter.inheritProjectContext === "false"
1798
2037
  ? false
1799
2038
  : defaultInheritProjectContext(localName);
2039
+ const inheritGlobalContext = frontmatter.inheritGlobalContext === "true";
1800
2040
  const inheritSkills = frontmatter.inheritSkills === "true"
1801
2041
  ? true
1802
2042
  : frontmatter.inheritSkills === "false"
@@ -1829,13 +2069,6 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
1829
2069
  }
1830
2070
  defaultToolTimeoutMs = parsed;
1831
2071
  }
1832
- let defaultTurnBudget: TurnBudgetConfig | undefined;
1833
- if (frontmatter.turnBudget !== undefined && frontmatter.turnBudget.trim()) {
1834
- const parsed = JSON.parse(frontmatter.turnBudget) as unknown;
1835
- const resolved = resolveTurnBudgetConfig(parsed, `Agent '${localName}' turnBudget frontmatter`);
1836
- if (resolved.error) throw new Error(resolved.error);
1837
- defaultTurnBudget = resolved.turnBudget;
1838
- }
1839
2072
  const defaultAcceptance = parseAgentAcceptanceFrontmatter(frontmatter.acceptance, localName);
1840
2073
  let outputMode: OutputMode | undefined;
1841
2074
  if (frontmatter.outputMode !== undefined) {
@@ -1850,12 +2083,19 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
1850
2083
 
1851
2084
  const extensions = resolveAgentRelativeExtensionPaths(parseFrontmatterList(frontmatter.extensions), filePath);
1852
2085
  const subagentOnlyExtensions = resolveAgentRelativeExtensionPaths(parseFrontmatterList(frontmatter.subagentOnlyExtensions), filePath);
2086
+ const mutationTools = parseFrontmatterList(frontmatter.mutationTools);
1853
2087
  let fast: boolean | undefined;
1854
2088
  if (frontmatter.fast !== undefined) {
1855
2089
  if (frontmatter.fast === "true") fast = true;
1856
2090
  else if (frontmatter.fast === "false") fast = false;
1857
2091
  else throw new Error(`Agent '${localName}' has invalid fast frontmatter; expected true or false.`);
1858
2092
  }
2093
+ let allowNestedSubagents: boolean | undefined;
2094
+ if (frontmatter.allowNestedSubagents !== undefined) {
2095
+ if (frontmatter.allowNestedSubagents === "true") allowNestedSubagents = true;
2096
+ else if (frontmatter.allowNestedSubagents === "false") allowNestedSubagents = false;
2097
+ else throw new Error(`Agent '${localName}' has invalid allowNestedSubagents frontmatter; expected true or false.`);
2098
+ }
1859
2099
 
1860
2100
  const extraFields: Record<string, string> = {};
1861
2101
  for (const [key, value] of Object.entries(frontmatter)) {
@@ -1899,6 +2139,7 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
1899
2139
  description: frontmatter.description,
1900
2140
  ...(aliases !== undefined ? { aliases } : {}),
1901
2141
  ...(rawTools !== undefined ? { tools } : {}),
2142
+ ...(allowNestedSubagents !== undefined ? { allowNestedSubagents } : {}),
1902
2143
  ...(mcpDirectTools.length > 0 ? { mcpDirectTools } : {}),
1903
2144
  ...(frontmatter.model !== undefined ? { model: frontmatter.model } : {}),
1904
2145
  ...(fallbackModels?.length ? { fallbackModels } : {}),
@@ -1906,12 +2147,12 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
1906
2147
  ...(frontmatter.thinking !== undefined ? { thinking: frontmatter.thinking === "false" ? false : frontmatter.thinking } : {}),
1907
2148
  systemPromptMode,
1908
2149
  inheritProjectContext,
2150
+ inheritGlobalContext,
1909
2151
  inheritSkills,
1910
2152
  ...(defaultContext !== undefined ? { defaultContext } : {}),
1911
2153
  ...(defaultAsync !== undefined ? { defaultAsync } : {}),
1912
2154
  ...(defaultTimeoutMs !== undefined ? { defaultTimeoutMs } : {}),
1913
2155
  ...(defaultToolTimeoutMs !== undefined ? { defaultToolTimeoutMs } : {}),
1914
- ...(defaultTurnBudget !== undefined ? { defaultTurnBudget } : {}),
1915
2156
  ...(defaultAcceptance !== undefined ? { defaultAcceptance } : {}),
1916
2157
  ...(acceptanceRole !== undefined ? { acceptanceRole } : {}),
1917
2158
  systemPrompt: body,
@@ -1922,6 +2163,7 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
1922
2163
  ...(skillPath?.length ? { skillPath } : {}),
1923
2164
  ...(extensions !== undefined ? { extensions } : {}),
1924
2165
  ...(subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions } : {}),
2166
+ ...(mutationTools?.length ? { mutationTools } : {}),
1925
2167
  ...(frontmatter.output !== undefined ? { output: frontmatter.output } : {}),
1926
2168
  ...(outputMode !== undefined ? { outputMode } : {}),
1927
2169
  ...(defaultReads?.length ? { defaultReads } : {}),
@@ -1944,8 +2186,17 @@ function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: Age
1944
2186
  return { agents, diagnostics };
1945
2187
  }
1946
2188
 
1947
- function loadAgentsFromDir(dir: string, source: AgentSource, discoveryPriority?: number, packageSource?: Omit<PackageSubagentPath, "dir">): { agents: AgentConfig[]; diagnostics: AgentDiscoveryDiagnostic[] } {
1948
- return loadAgentsFromDefinitionFiles(readAgentDefinitionFiles(dir), source, discoveryPriority, packageSource);
2189
+ function loadAgentsFromDir(dir: string, source: AgentSource, discoveryPriority?: number, packageSource?: Omit<PackageSubagentPath, "dir">, inspection = inspectAgentDefinitionDirectory(dir)): { agents: AgentConfig[]; diagnostics: AgentDiscoveryDiagnostic[] } {
2190
+ return loadAgentsFromDefinitionFiles(readAgentDefinitionFiles(dir, inspection), source, discoveryPriority, packageSource);
2191
+ }
2192
+
2193
+ function reportAgentDefinitionDirectory(source: AgentSource, dir: string, inspection: AgentDefinitionInspection): AgentDefinitionDirectoryReport {
2194
+ return {
2195
+ source,
2196
+ path: path.resolve(dir),
2197
+ state: inspection.state,
2198
+ ...(inspection.state === "candidates" ? { candidateCount: inspection.files.length } : {}),
2199
+ };
1949
2200
  }
1950
2201
 
1951
2202
  function loadChainsFromDir(dir: string, source: AgentSource): { chains: ChainConfig[]; diagnostics: ChainDiscoveryDiagnostic[] } {
@@ -1982,20 +2233,18 @@ function isDirectory(p: string): boolean {
1982
2233
  }
1983
2234
  }
1984
2235
 
1985
- function resolveNearestProjectAgentDirs(cwd: string): { readDirs: string[]; preferredDir: string | null } {
2236
+ function resolveNearestProjectAgentDirs(cwd: string): { readDirs: string[]; candidateDirs: string[]; preferredDir: string | null } {
1986
2237
  const projectRoot = findConfiguredProjectRoot(cwd);
1987
- if (!projectRoot) return { readDirs: [], preferredDir: null };
2238
+ if (!projectRoot) return { readDirs: [], candidateDirs: [], preferredDir: null };
1988
2239
 
1989
2240
  const legacyDir = path.join(projectRoot, ".agents");
1990
2241
  const preferredDir = path.join(getProjectConfigDir(projectRoot), "agents");
2242
+ const candidateDirs = [legacyDir, preferredDir];
1991
2243
  const readDirs: string[] = [];
1992
2244
  if (isDirectory(legacyDir)) readDirs.push(legacyDir);
1993
2245
  if (isDirectory(preferredDir)) readDirs.push(preferredDir);
1994
2246
 
1995
- return {
1996
- readDirs,
1997
- preferredDir,
1998
- };
2247
+ return { readDirs, candidateDirs, preferredDir };
1999
2248
  }
2000
2249
 
2001
2250
  function resolveNearestProjectChainDirs(cwd: string): { readDirs: string[]; preferredDir: string | null } {
@@ -2009,7 +2258,9 @@ function resolveNearestProjectChainDirs(cwd: string): { readDirs: string[]; pref
2009
2258
  };
2010
2259
  }
2011
2260
  const BUILTIN_AGENTS_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "agents");
2012
- const BUILTIN_AGENT_DEFINITION_FILES = readAgentDefinitionFiles(BUILTIN_AGENTS_DIR);
2261
+ // Candidate files and inspection state must describe the same cached builtin scan.
2262
+ const BUILTIN_AGENT_DEFINITION_INSPECTION = inspectAgentDefinitionDirectory(BUILTIN_AGENTS_DIR);
2263
+ const BUILTIN_AGENT_DEFINITION_FILES = readAgentDefinitionFiles(BUILTIN_AGENTS_DIR, BUILTIN_AGENT_DEFINITION_INSPECTION);
2013
2264
 
2014
2265
  export const EXTRA_AGENT_DIRS_ENV = "SELESAI_SUBAGENT_EXTRA_AGENT_DIRS";
2015
2266
 
@@ -2027,82 +2278,78 @@ function extraUserAgentDirs(): string[] {
2027
2278
  .filter((dir) => dir.length > 0);
2028
2279
  }
2029
2280
 
2030
- export function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryResult {
2281
+ export function discoverAgents(cwd: string, scope: AgentScope, preferredModelProvider?: string): AgentDiscoveryResult {
2282
+ const effectiveCwd = path.resolve(cwd);
2031
2283
  const userDirOld = path.join(getAgentDir(), "agents");
2032
2284
  const userDirNew = path.join(os.homedir(), ".agents");
2033
- const { readDirs: projectAgentDirs, preferredDir: projectAgentsDir } = resolveNearestProjectAgentDirs(cwd);
2285
+ const { readDirs: projectAgentDirs, candidateDirs: projectCandidateDirs, preferredDir: projectAgentsDir } = resolveNearestProjectAgentDirs(effectiveCwd);
2034
2286
  const userSettingsPath = getUserAgentSettingsPath();
2035
- const projectSettingsPath = getProjectAgentSettingsPath(cwd);
2036
- const userSettings = scope === "project" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(userSettingsPath);
2037
- const projectSettings = scope === "user" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(projectSettingsPath);
2287
+ const projectSettingsPath = getProjectAgentSettingsPath(effectiveCwd);
2288
+ const userSettings = selectProviderOverrides(scope === "project" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(userSettingsPath), preferredModelProvider);
2289
+ const projectSettings = selectProviderOverrides(scope === "user" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(projectSettingsPath), preferredModelProvider);
2038
2290
  const defaultProvider = resolveSubagentDefaultProvider(userSettings, projectSettings, projectSettingsPath);
2039
2291
  const defaultModel = resolveSubagentDefaultModel(userSettings, projectSettings, userSettingsPath, projectSettingsPath, defaultProvider);
2040
2292
  const defaultThinking = resolveSubagentDefaultThinking(userSettings, projectSettings, projectSettingsPath);
2041
2293
  const maxThinking = resolveSubagentMaxThinking(userSettings, projectSettings, projectSettingsPath);
2042
2294
  const defaultExtensions = resolveSubagentDefaultExtensions(userSettings, projectSettings, projectSettingsPath);
2043
2295
  const modelScope = projectSettings.modelScope ?? userSettings.modelScope;
2044
- const packageSubagentPaths = collectPackageSubagentPaths(cwd, {
2296
+ const packageSubagentPaths = collectPackageSubagentPaths(effectiveCwd, {
2045
2297
  includeUser: scope !== "project",
2046
2298
  includeProject: scope !== "user",
2047
2299
  });
2300
+ const directories: AgentDefinitionDirectoryReport[] = [reportAgentDefinitionDirectory("builtin", BUILTIN_AGENTS_DIR, BUILTIN_AGENT_DEFINITION_INSPECTION)];
2048
2301
 
2049
2302
  const builtinLoaded = loadAgentsFromDefinitionFiles(BUILTIN_AGENT_DEFINITION_FILES, "builtin");
2050
2303
  const builtinAgents = applyBuiltinOverrides(
2051
2304
  applySubagentDefaults(builtinLoaded.agents, defaultModel, defaultProvider, defaultThinking, defaultExtensions),
2052
- userSettings,
2053
- projectSettings,
2054
- userSettingsPath,
2055
- projectSettingsPath,
2305
+ userSettings, projectSettings, userSettingsPath, projectSettingsPath,
2056
2306
  );
2057
2307
 
2058
- const userLoaded = scope === "project" ? [] : [...extraUserAgentDirs(), userDirOld, userDirNew]
2059
- .map((dir, discoveryPriority) => loadAgentsFromDir(dir, "user", discoveryPriority));
2308
+ const userLoaded = scope === "project" ? [] : [...extraUserAgentDirs(), userDirOld, userDirNew].map((dir, discoveryPriority) => {
2309
+ const inspection = inspectAgentDefinitionDirectory(dir);
2310
+ directories.push(reportAgentDefinitionDirectory("user", dir, inspection));
2311
+ return loadAgentsFromDir(dir, "user", discoveryPriority, undefined, inspection);
2312
+ });
2060
2313
  const userAgents = applyCustomAgentOverrides(
2061
2314
  applySubagentDefaults(userLoaded.flatMap((loaded) => loaded.agents), defaultModel, defaultProvider, defaultThinking, defaultExtensions),
2062
- userSettings,
2063
- projectSettings,
2064
- userSettingsPath,
2065
- projectSettingsPath,
2315
+ userSettings, projectSettings, userSettingsPath, projectSettingsPath,
2066
2316
  );
2067
2317
 
2068
- const projectLoaded = scope === "user" ? [] : projectAgentDirs.map((dir) => loadAgentsFromDir(dir, "project", dir === projectAgentsDir ? 1 : 0));
2318
+ // Report both legacy and preferred project definition paths only after the
2319
+ // existing configured-root resolver found a root; never synthesize cwd paths.
2320
+ const projectInspections = scope === "user" ? new Map<string, AgentDefinitionInspection>() : new Map(projectCandidateDirs.map((dir) => [dir, inspectAgentDefinitionDirectory(dir)]));
2321
+ if (scope !== "user") for (const dir of projectCandidateDirs) directories.push(reportAgentDefinitionDirectory("project", dir, projectInspections.get(dir)!));
2322
+ const projectLoaded = scope === "user" ? [] : projectAgentDirs.map((dir) => loadAgentsFromDir(dir, "project", dir === projectAgentsDir ? 1 : 0, undefined, projectInspections.get(dir)!));
2069
2323
  const projectAgents = applyCustomAgentOverrides(
2070
2324
  applySubagentDefaults(projectLoaded.flatMap((loaded) => loaded.agents), defaultModel, defaultProvider, defaultThinking, defaultExtensions),
2071
- userSettings,
2072
- projectSettings,
2073
- userSettingsPath,
2074
- projectSettingsPath,
2325
+ userSettings, projectSettings, userSettingsPath, projectSettingsPath,
2075
2326
  );
2076
- const packageLoaded = packageSubagentPaths.agents.map((entry, index) => loadAgentsFromDir(entry.dir, "package", packageSubagentPaths.agents.length - index, entry));
2327
+
2328
+ const packageLoaded = packageSubagentPaths.agents.map((entry, index) => {
2329
+ const inspection = inspectAgentDefinitionDirectory(entry.dir);
2330
+ directories.push(reportAgentDefinitionDirectory("package", entry.dir, inspection));
2331
+ return loadAgentsFromDir(entry.dir, "package", packageSubagentPaths.agents.length - index, entry, inspection);
2332
+ });
2077
2333
  const packageMap = new Map<string, AgentConfig>();
2078
- for (const loaded of packageLoaded) {
2079
- for (const agent of loaded.agents) {
2080
- if (!packageMap.has(agent.name)) packageMap.set(agent.name, agent);
2081
- }
2082
- }
2334
+ for (const loaded of packageLoaded) for (const agent of loaded.agents) if (!packageMap.has(agent.name)) packageMap.set(agent.name, agent);
2083
2335
  const packageAgents = applyCustomAgentOverrides(
2084
2336
  applySubagentDefaults(Array.from(packageMap.values()), defaultModel, defaultProvider, defaultThinking, defaultExtensions),
2085
- userSettings,
2086
- projectSettings,
2087
- userSettingsPath,
2088
- projectSettingsPath,
2337
+ userSettings, projectSettings, userSettingsPath, projectSettingsPath,
2089
2338
  );
2090
2339
  const agents = applySubagentMaxThinking(
2091
- mergeAgentsForScope(scope, userAgents, projectAgents, builtinAgents, packageAgents)
2092
- .filter((agent) => agent.disabled !== true),
2340
+ mergeAgentsForScope(scope, userAgents, projectAgents, builtinAgents, packageAgents).filter((agent) => agent.disabled !== true),
2093
2341
  maxThinking,
2094
2342
  );
2095
-
2096
2343
  const agentDiagnostics = [
2097
2344
  ...builtinLoaded.diagnostics,
2098
2345
  ...userLoaded.flatMap((loaded) => loaded.diagnostics),
2099
2346
  ...projectLoaded.flatMap((loaded) => loaded.diagnostics),
2100
2347
  ...packageLoaded.flatMap((loaded) => loaded.diagnostics),
2101
2348
  ];
2102
- return { agents, agentDiagnostics, projectAgentsDir, ...(modelScope !== undefined ? { modelScope } : {}), ...(maxThinking !== undefined ? { maxThinking } : {}) };
2349
+ return { agents, agentDiagnostics, projectAgentsDir, cwd: effectiveCwd, scope, directories, ...(modelScope !== undefined ? { modelScope } : {}), ...(maxThinking !== undefined ? { maxThinking } : {}) };
2103
2350
  }
2104
2351
 
2105
- export function discoverAgentsAll(cwd: string): {
2352
+ export function discoverAgentsAll(cwd: string, preferredModelProvider?: string): {
2106
2353
  builtin: AgentConfig[];
2107
2354
  package: AgentConfig[];
2108
2355
  user: AgentConfig[];
@@ -2125,8 +2372,8 @@ export function discoverAgentsAll(cwd: string): {
2125
2372
  const { readDirs: projectChainDirs, preferredDir: projectChainDir } = resolveNearestProjectChainDirs(cwd);
2126
2373
  const userSettingsPath = getUserAgentSettingsPath();
2127
2374
  const projectSettingsPath = getProjectAgentSettingsPath(cwd);
2128
- const userSettings = readSubagentSettings(userSettingsPath);
2129
- const projectSettings = readSubagentSettings(projectSettingsPath);
2375
+ const userSettings = selectProviderOverrides(readSubagentSettings(userSettingsPath), preferredModelProvider);
2376
+ const projectSettings = selectProviderOverrides(readSubagentSettings(projectSettingsPath), preferredModelProvider);
2130
2377
  const defaultProvider = resolveSubagentDefaultProvider(userSettings, projectSettings, projectSettingsPath);
2131
2378
  const defaultModel = resolveSubagentDefaultModel(userSettings, projectSettings, userSettingsPath, projectSettingsPath, defaultProvider);
2132
2379
  const defaultThinking = resolveSubagentDefaultThinking(userSettings, projectSettings, projectSettingsPath);