pi-subagents 0.69.0 → 0.70.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 (1443) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +1 -1
  3. package/agents/claude-code-writer.md +1 -0
  4. package/agents/codex-exec-writer.md +1 -0
  5. package/agents/cursor-agent-writer.md +1 -0
  6. package/agents/reviewer.md +3 -2
  7. package/agents/worker.md +1 -0
  8. package/docs/agents.md +12 -9
  9. package/docs/configuration.md +3 -1
  10. package/docs/extension-api.md +3 -1
  11. package/docs/models.md +4 -2
  12. package/docs/observability.md +7 -1
  13. package/docs/standalone-background.md +4 -4
  14. package/docs/tool-reference.md +3 -7
  15. package/docs/watchdog.md +2 -0
  16. package/docs/workflows.md +6 -2
  17. package/index.d.ts +3 -0
  18. package/index.d.ts.map +1 -0
  19. package/index.js +10 -0
  20. package/index.js.map +1 -0
  21. package/inspector-runner.mjs +1 -1
  22. package/package.json +89 -73
  23. package/runner-peer-loader.mjs +4 -7
  24. package/runner-peer-preload.mjs +5 -7
  25. package/skills/pi-subagents/SKILL.md +1 -0
  26. package/skills/pi-subagents/references/management-authoring-rpc.md +1 -1
  27. package/skills/pi-subagents/references/multi-lane-orchestration.md +8 -0
  28. package/skills/pi-subagents/references/prompting-and-roles.md +16 -15
  29. package/src/agents/advertised-agent-prompt.d.ts +8 -0
  30. package/src/agents/advertised-agent-prompt.d.ts.map +1 -0
  31. package/src/agents/advertised-agent-prompt.js +77 -0
  32. package/src/agents/advertised-agent-prompt.js.map +1 -0
  33. package/src/agents/agent-management.d.ts +27 -0
  34. package/src/agents/agent-management.d.ts.map +1 -0
  35. package/src/agents/agent-management.js +1514 -0
  36. package/src/agents/agent-management.js.map +1 -0
  37. package/src/agents/agent-memory.d.ts +49 -0
  38. package/src/agents/agent-memory.d.ts.map +1 -0
  39. package/src/agents/agent-memory.js +349 -0
  40. package/src/agents/agent-memory.js.map +1 -0
  41. package/src/agents/agent-refinements.d.ts +100 -0
  42. package/src/agents/agent-refinements.d.ts.map +1 -0
  43. package/src/agents/agent-refinements.js +569 -0
  44. package/src/agents/agent-refinements.js.map +1 -0
  45. package/src/agents/agent-scope.d.ts +3 -0
  46. package/src/agents/agent-scope.d.ts.map +1 -0
  47. package/src/agents/agent-scope.js +6 -0
  48. package/src/agents/agent-scope.js.map +1 -0
  49. package/src/agents/agent-selection.d.ts +3 -0
  50. package/src/agents/agent-selection.d.ts.map +1 -0
  51. package/src/agents/agent-selection.js +23 -0
  52. package/src/agents/agent-selection.js.map +1 -0
  53. package/src/agents/agent-serializer.d.ts +8 -0
  54. package/src/agents/agent-serializer.d.ts.map +1 -0
  55. package/src/agents/agent-serializer.js +196 -0
  56. package/src/agents/agent-serializer.js.map +1 -0
  57. package/src/agents/agents.d.ts +326 -0
  58. package/src/agents/agents.d.ts.map +1 -0
  59. package/src/agents/agents.js +2639 -0
  60. package/src/agents/agents.js.map +1 -0
  61. package/src/agents/builtin-names.d.ts +2 -0
  62. package/src/agents/builtin-names.d.ts.map +1 -0
  63. package/src/agents/builtin-names.js +17 -0
  64. package/src/agents/builtin-names.js.map +1 -0
  65. package/src/agents/chain-serializer.d.ts +7 -0
  66. package/src/agents/chain-serializer.d.ts.map +1 -0
  67. package/src/agents/chain-serializer.js +319 -0
  68. package/src/agents/chain-serializer.js.map +1 -0
  69. package/src/agents/frontmatter.d.ts +16 -0
  70. package/src/agents/frontmatter.d.ts.map +1 -0
  71. package/src/agents/frontmatter.js +142 -0
  72. package/src/agents/frontmatter.js.map +1 -0
  73. package/src/agents/identity.d.ts +8 -0
  74. package/src/agents/identity.d.ts.map +1 -0
  75. package/src/agents/identity.js +30 -0
  76. package/src/agents/identity.js.map +1 -0
  77. package/src/agents/proactive-skills.d.ts +35 -0
  78. package/src/agents/proactive-skills.d.ts.map +1 -0
  79. package/src/agents/proactive-skills.js +154 -0
  80. package/src/agents/proactive-skills.js.map +1 -0
  81. package/src/agents/runtime-agent-events.d.ts +27 -0
  82. package/src/agents/runtime-agent-events.d.ts.map +1 -0
  83. package/src/agents/runtime-agent-events.js +53 -0
  84. package/src/agents/runtime-agent-events.js.map +1 -0
  85. package/src/agents/runtime-agent-registry.d.ts +64 -0
  86. package/src/agents/runtime-agent-registry.d.ts.map +1 -0
  87. package/src/agents/runtime-agent-registry.js +395 -0
  88. package/src/agents/runtime-agent-registry.js.map +1 -0
  89. package/src/agents/skills.d.ts +33 -0
  90. package/src/agents/skills.d.ts.map +1 -0
  91. package/src/agents/skills.js +685 -0
  92. package/src/agents/skills.js.map +1 -0
  93. package/src/api/agents.d.ts +5 -0
  94. package/src/api/agents.d.ts.map +1 -0
  95. package/src/api/agents.js +3 -0
  96. package/src/api/agents.js.map +1 -0
  97. package/src/api/background-work.d.ts +39 -0
  98. package/src/api/background-work.d.ts.map +1 -0
  99. package/src/api/background-work.js +165 -0
  100. package/src/api/background-work.js.map +1 -0
  101. package/src/api/capability-ceiling.d.ts +2 -0
  102. package/src/api/capability-ceiling.d.ts.map +1 -0
  103. package/src/api/capability-ceiling.js +2 -0
  104. package/src/api/capability-ceiling.js.map +1 -0
  105. package/src/api/child-tool-plan.d.ts +2 -0
  106. package/src/api/child-tool-plan.d.ts.map +1 -0
  107. package/src/api/child-tool-plan.js +2 -0
  108. package/src/api/child-tool-plan.js.map +1 -0
  109. package/src/api/control-channel.d.ts +2 -0
  110. package/src/api/control-channel.d.ts.map +1 -0
  111. package/src/api/control-channel.js +2 -0
  112. package/src/api/control-channel.js.map +1 -0
  113. package/src/api/delegation.d.ts +99 -0
  114. package/src/api/delegation.d.ts.map +1 -0
  115. package/src/api/delegation.js +9 -0
  116. package/src/api/delegation.js.map +1 -0
  117. package/src/api/external-job-provider.d.ts +58 -0
  118. package/src/api/external-job-provider.d.ts.map +1 -0
  119. package/src/api/external-job-provider.js +140 -0
  120. package/src/api/external-job-provider.js.map +1 -0
  121. package/src/api/external-runs.d.ts +48 -0
  122. package/src/api/external-runs.d.ts.map +1 -0
  123. package/src/api/external-runs.js +245 -0
  124. package/src/api/external-runs.js.map +1 -0
  125. package/src/api/intercom-bridge.d.ts +2 -0
  126. package/src/api/intercom-bridge.d.ts.map +1 -0
  127. package/src/api/intercom-bridge.js +2 -0
  128. package/src/api/intercom-bridge.js.map +1 -0
  129. package/src/api/preflight.d.ts +173 -0
  130. package/src/api/preflight.d.ts.map +1 -0
  131. package/src/api/preflight.js +362 -0
  132. package/src/api/preflight.js.map +1 -0
  133. package/src/api/project-panes.d.ts +8 -0
  134. package/src/api/project-panes.d.ts.map +1 -0
  135. package/src/api/project-panes.js +8 -0
  136. package/src/api/project-panes.js.map +1 -0
  137. package/src/api/required-child-extensions.d.ts +2 -0
  138. package/src/api/required-child-extensions.d.ts.map +1 -0
  139. package/src/api/required-child-extensions.js +2 -0
  140. package/src/api/required-child-extensions.js.map +1 -0
  141. package/src/api/shared-types.d.ts +2 -0
  142. package/src/api/shared-types.d.ts.map +1 -0
  143. package/src/api/shared-types.js +2 -0
  144. package/src/api/shared-types.js.map +1 -0
  145. package/src/api/workflow-resources.d.ts +3 -0
  146. package/src/api/workflow-resources.d.ts.map +1 -0
  147. package/src/api/workflow-resources.js +2 -0
  148. package/src/api/workflow-resources.js.map +1 -0
  149. package/src/extension/config.d.ts +8 -0
  150. package/src/extension/config.d.ts.map +1 -0
  151. package/src/extension/config.js +245 -0
  152. package/src/extension/config.js.map +1 -0
  153. package/src/extension/control-notices.d.ts +19 -0
  154. package/src/extension/control-notices.d.ts.map +1 -0
  155. package/src/extension/control-notices.js +34 -0
  156. package/src/extension/control-notices.js.map +1 -0
  157. package/src/extension/doctor.d.ts +33 -0
  158. package/src/extension/doctor.d.ts.map +1 -0
  159. package/src/extension/doctor.js +231 -0
  160. package/src/extension/doctor.js.map +1 -0
  161. package/src/extension/fanout-child.d.ts +7 -0
  162. package/src/extension/fanout-child.d.ts.map +1 -0
  163. package/src/extension/fanout-child.js +261 -0
  164. package/src/extension/fanout-child.js.map +1 -0
  165. package/src/extension/herdr-pi-bridge.d.ts +17 -0
  166. package/src/extension/herdr-pi-bridge.d.ts.map +1 -0
  167. package/src/extension/herdr-pi-bridge.js +243 -0
  168. package/src/extension/herdr-pi-bridge.js.map +1 -0
  169. package/src/extension/index.d.ts +20 -0
  170. package/src/extension/index.d.ts.map +1 -0
  171. package/src/extension/index.js +1108 -0
  172. package/src/extension/index.js.map +1 -0
  173. package/src/extension/public-execution.d.ts +62 -0
  174. package/src/extension/public-execution.d.ts.map +1 -0
  175. package/src/extension/public-execution.js +174 -0
  176. package/src/extension/public-execution.js.map +1 -0
  177. package/src/extension/rpc.d.ts +83 -0
  178. package/src/extension/rpc.d.ts.map +1 -0
  179. package/src/extension/rpc.js +687 -0
  180. package/src/extension/rpc.js.map +1 -0
  181. package/src/extension/schemas.d.ts +252 -0
  182. package/src/extension/schemas.d.ts.map +1 -0
  183. package/src/extension/schemas.js +396 -0
  184. package/src/extension/schemas.js.map +1 -0
  185. package/src/extension/steering-notices.d.ts +15 -0
  186. package/src/extension/steering-notices.d.ts.map +1 -0
  187. package/src/extension/steering-notices.js +23 -0
  188. package/src/extension/steering-notices.js.map +1 -0
  189. package/src/extension/subagent-guide.d.ts +4 -0
  190. package/src/extension/subagent-guide.d.ts.map +1 -0
  191. package/src/extension/subagent-guide.js +35 -0
  192. package/src/extension/subagent-guide.js.map +1 -0
  193. package/src/extension/tool-description.d.ts +20 -0
  194. package/src/extension/tool-description.d.ts.map +1 -0
  195. package/src/extension/tool-description.js +160 -0
  196. package/src/extension/tool-description.js.map +1 -0
  197. package/src/extension/tool-result.d.ts +10 -0
  198. package/src/extension/tool-result.d.ts.map +1 -0
  199. package/src/extension/tool-result.js +17 -0
  200. package/src/extension/tool-result.js.map +1 -0
  201. package/src/inspectors/actions.d.ts +23 -0
  202. package/src/inspectors/actions.d.ts.map +1 -0
  203. package/src/inspectors/actions.js +155 -0
  204. package/src/inspectors/actions.js.map +1 -0
  205. package/src/inspectors/ghostty/actions.d.ts +12 -0
  206. package/src/inspectors/ghostty/actions.d.ts.map +1 -0
  207. package/src/inspectors/ghostty/actions.js +63 -0
  208. package/src/inspectors/ghostty/actions.js.map +1 -0
  209. package/src/inspectors/ghostty/plugin.d.ts +8 -0
  210. package/src/inspectors/ghostty/plugin.d.ts.map +1 -0
  211. package/src/inspectors/ghostty/plugin.js +24 -0
  212. package/src/inspectors/ghostty/plugin.js.map +1 -0
  213. package/src/inspectors/herdr/actions.d.ts +26 -0
  214. package/src/inspectors/herdr/actions.d.ts.map +1 -0
  215. package/src/inspectors/herdr/actions.js +134 -0
  216. package/src/inspectors/herdr/actions.js.map +1 -0
  217. package/src/inspectors/herdr/client.d.ts +42 -0
  218. package/src/inspectors/herdr/client.d.ts.map +1 -0
  219. package/src/inspectors/herdr/client.js +130 -0
  220. package/src/inspectors/herdr/client.js.map +1 -0
  221. package/src/inspectors/herdr/focus.d.ts +25 -0
  222. package/src/inspectors/herdr/focus.d.ts.map +1 -0
  223. package/src/inspectors/herdr/focus.js +50 -0
  224. package/src/inspectors/herdr/focus.js.map +1 -0
  225. package/src/inspectors/herdr/plugin.d.ts +7 -0
  226. package/src/inspectors/herdr/plugin.d.ts.map +1 -0
  227. package/src/inspectors/herdr/plugin.js +15 -0
  228. package/src/inspectors/herdr/plugin.js.map +1 -0
  229. package/src/inspectors/herdr/project-panes.d.ts +137 -0
  230. package/src/inspectors/herdr/project-panes.d.ts.map +1 -0
  231. package/src/inspectors/herdr/project-panes.js +608 -0
  232. package/src/inspectors/herdr/project-panes.js.map +1 -0
  233. package/src/inspectors/inspector-runner.d.ts +24 -0
  234. package/src/inspectors/inspector-runner.d.ts.map +1 -0
  235. package/src/inspectors/inspector-runner.js +162 -0
  236. package/src/inspectors/inspector-runner.js.map +1 -0
  237. package/src/inspectors/plugins.d.ts +4 -0
  238. package/src/inspectors/plugins.d.ts.map +1 -0
  239. package/src/inspectors/plugins.js +7 -0
  240. package/src/inspectors/plugins.js.map +1 -0
  241. package/src/inspectors/session-roots-codec.d.ts +16 -0
  242. package/src/inspectors/session-roots-codec.d.ts.map +1 -0
  243. package/src/inspectors/session-roots-codec.js +33 -0
  244. package/src/inspectors/session-roots-codec.js.map +1 -0
  245. package/src/inspectors/shell-command.d.ts +2 -0
  246. package/src/inspectors/shell-command.d.ts.map +1 -0
  247. package/src/inspectors/shell-command.js +17 -0
  248. package/src/inspectors/shell-command.js.map +1 -0
  249. package/src/inspectors/types.d.ts +49 -0
  250. package/src/inspectors/types.d.ts.map +1 -0
  251. package/src/inspectors/types.js +2 -0
  252. package/src/inspectors/types.js.map +1 -0
  253. package/src/integrations/herdr-status.d.ts +46 -0
  254. package/src/integrations/herdr-status.d.ts.map +1 -0
  255. package/src/integrations/herdr-status.js +371 -0
  256. package/src/integrations/herdr-status.js.map +1 -0
  257. package/src/integrations/pi-web-session-liveness.d.ts +20 -0
  258. package/src/integrations/pi-web-session-liveness.d.ts.map +1 -0
  259. package/src/integrations/pi-web-session-liveness.js +54 -0
  260. package/src/integrations/pi-web-session-liveness.js.map +1 -0
  261. package/src/intercom/intercom-bridge.d.ts +59 -0
  262. package/src/intercom/intercom-bridge.d.ts.map +1 -0
  263. package/src/intercom/intercom-bridge.js +192 -0
  264. package/src/intercom/intercom-bridge.js.map +1 -0
  265. package/src/intercom/native-supervisor-channel.d.ts +64 -0
  266. package/src/intercom/native-supervisor-channel.d.ts.map +1 -0
  267. package/src/intercom/native-supervisor-channel.js +894 -0
  268. package/src/intercom/native-supervisor-channel.js.map +1 -0
  269. package/src/intercom/result-intercom.d.ts +36 -0
  270. package/src/intercom/result-intercom.d.ts.map +1 -0
  271. package/src/intercom/result-intercom.js +372 -0
  272. package/src/intercom/result-intercom.js.map +1 -0
  273. package/src/intercom/supervisor-ui.d.ts +40 -0
  274. package/src/intercom/supervisor-ui.d.ts.map +1 -0
  275. package/src/intercom/supervisor-ui.js +202 -0
  276. package/src/intercom/supervisor-ui.js.map +1 -0
  277. package/src/missions/actions.d.ts +55 -0
  278. package/src/missions/actions.d.ts.map +1 -0
  279. package/src/missions/actions.js +396 -0
  280. package/src/missions/actions.js.map +1 -0
  281. package/src/missions/goal-driver.d.ts +16 -0
  282. package/src/missions/goal-driver.d.ts.map +1 -0
  283. package/src/missions/goal-driver.js +157 -0
  284. package/src/missions/goal-driver.js.map +1 -0
  285. package/src/missions/lifecycle.d.ts +40 -0
  286. package/src/missions/lifecycle.d.ts.map +1 -0
  287. package/src/missions/lifecycle.js +352 -0
  288. package/src/missions/lifecycle.js.map +1 -0
  289. package/src/missions/store.d.ts +22 -0
  290. package/src/missions/store.d.ts.map +1 -0
  291. package/src/missions/store.js +573 -0
  292. package/src/missions/store.js.map +1 -0
  293. package/src/missions/types.d.ts +168 -0
  294. package/src/missions/types.d.ts.map +1 -0
  295. package/src/missions/types.js +10 -0
  296. package/src/missions/types.js.map +1 -0
  297. package/src/missions/workflow-state.d.ts +15 -0
  298. package/src/missions/workflow-state.d.ts.map +1 -0
  299. package/src/missions/workflow-state.js +274 -0
  300. package/src/missions/workflow-state.js.map +1 -0
  301. package/src/policy/authority.d.ts +10 -0
  302. package/src/policy/authority.d.ts.map +1 -0
  303. package/src/policy/authority.js +42 -0
  304. package/src/policy/authority.js.map +1 -0
  305. package/src/profiles/profiles.d.ts +135 -0
  306. package/src/profiles/profiles.d.ts.map +1 -0
  307. package/src/profiles/profiles.js +520 -0
  308. package/src/profiles/profiles.js.map +1 -0
  309. package/src/runs/background/active-async-capacity.d.ts +100 -0
  310. package/src/runs/background/active-async-capacity.d.ts.map +1 -0
  311. package/src/runs/background/active-async-capacity.js +492 -0
  312. package/src/runs/background/active-async-capacity.js.map +1 -0
  313. package/src/runs/background/active-run-index.d.ts +13 -0
  314. package/src/runs/background/active-run-index.d.ts.map +1 -0
  315. package/src/runs/background/active-run-index.js +158 -0
  316. package/src/runs/background/active-run-index.js.map +1 -0
  317. package/src/runs/background/async-execution.d.ts +274 -0
  318. package/src/runs/background/async-execution.d.ts.map +1 -0
  319. package/src/runs/background/async-execution.js +1955 -0
  320. package/src/runs/background/async-execution.js.map +1 -0
  321. package/src/runs/background/async-job-tracker.d.ts +28 -0
  322. package/src/runs/background/async-job-tracker.d.ts.map +1 -0
  323. package/src/runs/background/async-job-tracker.js +876 -0
  324. package/src/runs/background/async-job-tracker.js.map +1 -0
  325. package/src/runs/background/async-resume.d.ts +59 -0
  326. package/src/runs/background/async-resume.d.ts.map +1 -0
  327. package/src/runs/background/async-resume.js +667 -0
  328. package/src/runs/background/async-resume.js.map +1 -0
  329. package/src/runs/background/async-retention.d.ts +45 -0
  330. package/src/runs/background/async-retention.d.ts.map +1 -0
  331. package/src/runs/background/async-retention.js +884 -0
  332. package/src/runs/background/async-retention.js.map +1 -0
  333. package/src/runs/background/async-status-snapshot.d.ts +10 -0
  334. package/src/runs/background/async-status-snapshot.d.ts.map +1 -0
  335. package/src/runs/background/async-status-snapshot.js +25 -0
  336. package/src/runs/background/async-status-snapshot.js.map +1 -0
  337. package/src/runs/background/async-status.d.ts +169 -0
  338. package/src/runs/background/async-status.d.ts.map +1 -0
  339. package/src/runs/background/async-status.js +673 -0
  340. package/src/runs/background/async-status.js.map +1 -0
  341. package/src/runs/background/auto-drain.d.ts +17 -0
  342. package/src/runs/background/auto-drain.d.ts.map +1 -0
  343. package/src/runs/background/auto-drain.js +73 -0
  344. package/src/runs/background/auto-drain.js.map +1 -0
  345. package/src/runs/background/binary-bootstrap.d.ts +9 -0
  346. package/src/runs/background/binary-bootstrap.d.ts.map +1 -0
  347. package/src/runs/background/binary-bootstrap.js +41 -0
  348. package/src/runs/background/binary-bootstrap.js.map +1 -0
  349. package/src/runs/background/chain-append.d.ts +35 -0
  350. package/src/runs/background/chain-append.d.ts.map +1 -0
  351. package/src/runs/background/chain-append.js +300 -0
  352. package/src/runs/background/chain-append.js.map +1 -0
  353. package/src/runs/background/chain-root-attachment.d.ts +49 -0
  354. package/src/runs/background/chain-root-attachment.d.ts.map +1 -0
  355. package/src/runs/background/chain-root-attachment.js +184 -0
  356. package/src/runs/background/chain-root-attachment.js.map +1 -0
  357. package/src/runs/background/completion-batcher.d.ts +52 -0
  358. package/src/runs/background/completion-batcher.d.ts.map +1 -0
  359. package/src/runs/background/completion-batcher.js +120 -0
  360. package/src/runs/background/completion-batcher.js.map +1 -0
  361. package/src/runs/background/completion-dedupe.d.ts +14 -0
  362. package/src/runs/background/completion-dedupe.d.ts.map +1 -0
  363. package/src/runs/background/completion-dedupe.js +49 -0
  364. package/src/runs/background/completion-dedupe.js.map +1 -0
  365. package/src/runs/background/completion-replay.d.ts +48 -0
  366. package/src/runs/background/completion-replay.d.ts.map +1 -0
  367. package/src/runs/background/completion-replay.js +267 -0
  368. package/src/runs/background/completion-replay.js.map +1 -0
  369. package/src/runs/background/control-channel.d.ts +156 -0
  370. package/src/runs/background/control-channel.d.ts.map +1 -0
  371. package/src/runs/background/control-channel.js +521 -0
  372. package/src/runs/background/control-channel.js.map +1 -0
  373. package/src/runs/background/fleet-view.d.ts +64 -0
  374. package/src/runs/background/fleet-view.d.ts.map +1 -0
  375. package/src/runs/background/fleet-view.js +648 -0
  376. package/src/runs/background/fleet-view.js.map +1 -0
  377. package/src/runs/background/index-segment.d.ts +16 -0
  378. package/src/runs/background/index-segment.d.ts.map +1 -0
  379. package/src/runs/background/index-segment.js +59 -0
  380. package/src/runs/background/index-segment.js.map +1 -0
  381. package/src/runs/background/inspect-rpc.d.ts +60 -0
  382. package/src/runs/background/inspect-rpc.d.ts.map +1 -0
  383. package/src/runs/background/inspect-rpc.js +406 -0
  384. package/src/runs/background/inspect-rpc.js.map +1 -0
  385. package/src/runs/background/notify.d.ts +162 -0
  386. package/src/runs/background/notify.d.ts.map +1 -0
  387. package/src/runs/background/notify.js +665 -0
  388. package/src/runs/background/notify.js.map +1 -0
  389. package/src/runs/background/owned-process-tree.d.ts +11 -0
  390. package/src/runs/background/owned-process-tree.d.ts.map +1 -0
  391. package/src/runs/background/owned-process-tree.js +117 -0
  392. package/src/runs/background/owned-process-tree.js.map +1 -0
  393. package/src/runs/background/parallel-groups.d.ts +4 -0
  394. package/src/runs/background/parallel-groups.d.ts.map +1 -0
  395. package/src/runs/background/parallel-groups.js +47 -0
  396. package/src/runs/background/parallel-groups.js.map +1 -0
  397. package/src/runs/background/process-terminal.d.ts +34 -0
  398. package/src/runs/background/process-terminal.d.ts.map +1 -0
  399. package/src/runs/background/process-terminal.js +305 -0
  400. package/src/runs/background/process-terminal.js.map +1 -0
  401. package/src/runs/background/result-delivery-ownership.d.ts +11 -0
  402. package/src/runs/background/result-delivery-ownership.d.ts.map +1 -0
  403. package/src/runs/background/result-delivery-ownership.js +37 -0
  404. package/src/runs/background/result-delivery-ownership.js.map +1 -0
  405. package/src/runs/background/result-files.d.ts +33 -0
  406. package/src/runs/background/result-files.d.ts.map +1 -0
  407. package/src/runs/background/result-files.js +528 -0
  408. package/src/runs/background/result-files.js.map +1 -0
  409. package/src/runs/background/result-watcher.d.ts +87 -0
  410. package/src/runs/background/result-watcher.d.ts.map +1 -0
  411. package/src/runs/background/result-watcher.js +764 -0
  412. package/src/runs/background/result-watcher.js.map +1 -0
  413. package/src/runs/background/resume-guidance.d.ts +5 -0
  414. package/src/runs/background/resume-guidance.d.ts.map +1 -0
  415. package/src/runs/background/resume-guidance.js +57 -0
  416. package/src/runs/background/resume-guidance.js.map +1 -0
  417. package/src/runs/background/retained-children.d.ts +25 -0
  418. package/src/runs/background/retained-children.d.ts.map +1 -0
  419. package/src/runs/background/retained-children.js +128 -0
  420. package/src/runs/background/retained-children.js.map +1 -0
  421. package/src/runs/background/retained-nested-route-tracker.d.ts +13 -0
  422. package/src/runs/background/retained-nested-route-tracker.d.ts.map +1 -0
  423. package/src/runs/background/retained-nested-route-tracker.js +91 -0
  424. package/src/runs/background/retained-nested-route-tracker.js.map +1 -0
  425. package/src/runs/background/run-child-session.d.ts +123 -0
  426. package/src/runs/background/run-child-session.d.ts.map +1 -0
  427. package/src/runs/background/run-child-session.js +602 -0
  428. package/src/runs/background/run-child-session.js.map +1 -0
  429. package/src/runs/background/run-id-query.d.ts +4 -0
  430. package/src/runs/background/run-id-query.d.ts.map +1 -0
  431. package/src/runs/background/run-id-query.js +7 -0
  432. package/src/runs/background/run-id-query.js.map +1 -0
  433. package/src/runs/background/run-id-resolver.d.ts +23 -0
  434. package/src/runs/background/run-id-resolver.d.ts.map +1 -0
  435. package/src/runs/background/run-id-resolver.js +170 -0
  436. package/src/runs/background/run-id-resolver.js.map +1 -0
  437. package/src/runs/background/run-status.d.ts +26 -0
  438. package/src/runs/background/run-status.d.ts.map +1 -0
  439. package/src/runs/background/run-status.js +828 -0
  440. package/src/runs/background/run-status.js.map +1 -0
  441. package/src/runs/background/runner-aliases.d.ts +17 -0
  442. package/src/runs/background/runner-aliases.d.ts.map +1 -0
  443. package/src/runs/background/runner-aliases.js +152 -0
  444. package/src/runs/background/runner-aliases.js.map +1 -0
  445. package/src/runs/background/runner-child-launch.d.ts +24 -0
  446. package/src/runs/background/runner-child-launch.d.ts.map +1 -0
  447. package/src/runs/background/runner-child-launch.js +68 -0
  448. package/src/runs/background/runner-child-launch.js.map +1 -0
  449. package/src/runs/background/runner-child-sessions.d.ts +7 -0
  450. package/src/runs/background/runner-child-sessions.d.ts.map +1 -0
  451. package/src/runs/background/runner-child-sessions.js +35 -0
  452. package/src/runs/background/runner-child-sessions.js.map +1 -0
  453. package/src/runs/background/runner-http-dispatcher.d.ts +43 -0
  454. package/src/runs/background/runner-http-dispatcher.d.ts.map +1 -0
  455. package/src/runs/background/runner-http-dispatcher.js +114 -0
  456. package/src/runs/background/runner-http-dispatcher.js.map +1 -0
  457. package/src/runs/background/scheduled-runs.d.ts +116 -0
  458. package/src/runs/background/scheduled-runs.d.ts.map +1 -0
  459. package/src/runs/background/scheduled-runs.js +1024 -0
  460. package/src/runs/background/scheduled-runs.js.map +1 -0
  461. package/src/runs/background/stale-run-reconciler.d.ts +37 -0
  462. package/src/runs/background/stale-run-reconciler.d.ts.map +1 -0
  463. package/src/runs/background/stale-run-reconciler.js +393 -0
  464. package/src/runs/background/stale-run-reconciler.js.map +1 -0
  465. package/src/runs/background/steering.d.ts +52 -0
  466. package/src/runs/background/steering.d.ts.map +1 -0
  467. package/src/runs/background/steering.js +247 -0
  468. package/src/runs/background/steering.js.map +1 -0
  469. package/src/runs/background/subagent-runner.d.ts +197 -0
  470. package/src/runs/background/subagent-runner.d.ts.map +1 -0
  471. package/src/runs/background/subagent-runner.js +5052 -0
  472. package/src/runs/background/subagent-runner.js.map +1 -0
  473. package/src/runs/background/subagent-wait.d.ts +122 -0
  474. package/src/runs/background/subagent-wait.d.ts.map +1 -0
  475. package/src/runs/background/subagent-wait.js +735 -0
  476. package/src/runs/background/subagent-wait.js.map +1 -0
  477. package/src/runs/background/terminal-run-index.d.ts +8 -0
  478. package/src/runs/background/terminal-run-index.d.ts.map +1 -0
  479. package/src/runs/background/terminal-run-index.js +123 -0
  480. package/src/runs/background/terminal-run-index.js.map +1 -0
  481. package/src/runs/background/top-level-async.d.ts +8 -0
  482. package/src/runs/background/top-level-async.d.ts.map +1 -0
  483. package/src/runs/background/top-level-async.js +6 -0
  484. package/src/runs/background/top-level-async.js.map +1 -0
  485. package/src/runs/background/wait-completions.d.ts +29 -0
  486. package/src/runs/background/wait-completions.d.ts.map +1 -0
  487. package/src/runs/background/wait-completions.js +264 -0
  488. package/src/runs/background/wait-completions.js.map +1 -0
  489. package/src/runs/background/wait-config.d.ts +9 -0
  490. package/src/runs/background/wait-config.d.ts.map +1 -0
  491. package/src/runs/background/wait-config.js +47 -0
  492. package/src/runs/background/wait-config.js.map +1 -0
  493. package/src/runs/background/wait-subscriptions.d.ts +27 -0
  494. package/src/runs/background/wait-subscriptions.d.ts.map +1 -0
  495. package/src/runs/background/wait-subscriptions.js +337 -0
  496. package/src/runs/background/wait-subscriptions.js.map +1 -0
  497. package/src/runs/background/wait-tool.d.ts +7 -0
  498. package/src/runs/background/wait-tool.d.ts.map +1 -0
  499. package/src/runs/background/wait-tool.js +36 -0
  500. package/src/runs/background/wait-tool.js.map +1 -0
  501. package/src/runs/foreground/async-dismiss-action.d.ts +7 -0
  502. package/src/runs/foreground/async-dismiss-action.d.ts.map +1 -0
  503. package/src/runs/foreground/async-dismiss-action.js +82 -0
  504. package/src/runs/foreground/async-dismiss-action.js.map +1 -0
  505. package/src/runs/foreground/async-steering-action.d.ts +32 -0
  506. package/src/runs/foreground/async-steering-action.d.ts.map +1 -0
  507. package/src/runs/foreground/async-steering-action.js +270 -0
  508. package/src/runs/foreground/async-steering-action.js.map +1 -0
  509. package/src/runs/foreground/async-stop-action.d.ts +7 -0
  510. package/src/runs/foreground/async-stop-action.d.ts.map +1 -0
  511. package/src/runs/foreground/async-stop-action.js +171 -0
  512. package/src/runs/foreground/async-stop-action.js.map +1 -0
  513. package/src/runs/foreground/execution.d.ts +11 -0
  514. package/src/runs/foreground/execution.d.ts.map +1 -0
  515. package/src/runs/foreground/execution.js +2089 -0
  516. package/src/runs/foreground/execution.js.map +1 -0
  517. package/src/runs/foreground/foreground-control.d.ts +25 -0
  518. package/src/runs/foreground/foreground-control.d.ts.map +1 -0
  519. package/src/runs/foreground/foreground-control.js +139 -0
  520. package/src/runs/foreground/foreground-control.js.map +1 -0
  521. package/src/runs/foreground/foreground-history.d.ts +12 -0
  522. package/src/runs/foreground/foreground-history.d.ts.map +1 -0
  523. package/src/runs/foreground/foreground-history.js +165 -0
  524. package/src/runs/foreground/foreground-history.js.map +1 -0
  525. package/src/runs/foreground/prompt-audit.d.ts +33 -0
  526. package/src/runs/foreground/prompt-audit.d.ts.map +1 -0
  527. package/src/runs/foreground/prompt-audit.js +143 -0
  528. package/src/runs/foreground/prompt-audit.js.map +1 -0
  529. package/src/runs/foreground/subagent-executor.d.ts +296 -0
  530. package/src/runs/foreground/subagent-executor.d.ts.map +1 -0
  531. package/src/runs/foreground/subagent-executor.js +7045 -0
  532. package/src/runs/foreground/subagent-executor.js.map +1 -0
  533. package/src/runs/foreground/workflow-detach-reconcile.d.ts +16 -0
  534. package/src/runs/foreground/workflow-detach-reconcile.d.ts.map +1 -0
  535. package/src/runs/foreground/workflow-detach-reconcile.js +284 -0
  536. package/src/runs/foreground/workflow-detach-reconcile.js.map +1 -0
  537. package/src/runs/foreground/workflow-foreground-steering.d.ts +44 -0
  538. package/src/runs/foreground/workflow-foreground-steering.d.ts.map +1 -0
  539. package/src/runs/foreground/workflow-foreground-steering.js +149 -0
  540. package/src/runs/foreground/workflow-foreground-steering.js.map +1 -0
  541. package/src/runs/shared/abort-recovery.d.ts +27 -0
  542. package/src/runs/shared/abort-recovery.d.ts.map +1 -0
  543. package/src/runs/shared/abort-recovery.js +109 -0
  544. package/src/runs/shared/abort-recovery.js.map +1 -0
  545. package/src/runs/shared/acceptance.d.ts +145 -0
  546. package/src/runs/shared/acceptance.d.ts.map +1 -0
  547. package/src/runs/shared/acceptance.js +1617 -0
  548. package/src/runs/shared/acceptance.js.map +1 -0
  549. package/src/runs/shared/agent-contract.d.ts +6 -0
  550. package/src/runs/shared/agent-contract.d.ts.map +1 -0
  551. package/src/runs/shared/agent-contract.js +36 -0
  552. package/src/runs/shared/agent-contract.js.map +1 -0
  553. package/src/runs/shared/async-status-projection.d.ts +94 -0
  554. package/src/runs/shared/async-status-projection.d.ts.map +1 -0
  555. package/src/runs/shared/async-status-projection.js +542 -0
  556. package/src/runs/shared/async-status-projection.js.map +1 -0
  557. package/src/runs/shared/background-process-options.d.ts +5 -0
  558. package/src/runs/shared/background-process-options.d.ts.map +1 -0
  559. package/src/runs/shared/background-process-options.js +7 -0
  560. package/src/runs/shared/background-process-options.js.map +1 -0
  561. package/src/runs/shared/capability-ceiling.d.ts +58 -0
  562. package/src/runs/shared/capability-ceiling.d.ts.map +1 -0
  563. package/src/runs/shared/capability-ceiling.js +179 -0
  564. package/src/runs/shared/capability-ceiling.js.map +1 -0
  565. package/src/runs/shared/chain-outputs.d.ts +19 -0
  566. package/src/runs/shared/chain-outputs.d.ts.map +1 -0
  567. package/src/runs/shared/chain-outputs.js +105 -0
  568. package/src/runs/shared/chain-outputs.js.map +1 -0
  569. package/src/runs/shared/child-hooks.d.ts +32 -0
  570. package/src/runs/shared/child-hooks.d.ts.map +1 -0
  571. package/src/runs/shared/child-hooks.js +173 -0
  572. package/src/runs/shared/child-hooks.js.map +1 -0
  573. package/src/runs/shared/child-identity.d.ts +24 -0
  574. package/src/runs/shared/child-identity.d.ts.map +1 -0
  575. package/src/runs/shared/child-identity.js +41 -0
  576. package/src/runs/shared/child-identity.js.map +1 -0
  577. package/src/runs/shared/child-launch-plan.d.ts +71 -0
  578. package/src/runs/shared/child-launch-plan.d.ts.map +1 -0
  579. package/src/runs/shared/child-launch-plan.js +89 -0
  580. package/src/runs/shared/child-launch-plan.js.map +1 -0
  581. package/src/runs/shared/child-launch.d.ts +112 -0
  582. package/src/runs/shared/child-launch.d.ts.map +1 -0
  583. package/src/runs/shared/child-launch.js +230 -0
  584. package/src/runs/shared/child-launch.js.map +1 -0
  585. package/src/runs/shared/child-lifecycle.d.ts +14 -0
  586. package/src/runs/shared/child-lifecycle.d.ts.map +1 -0
  587. package/src/runs/shared/child-lifecycle.js +23 -0
  588. package/src/runs/shared/child-lifecycle.js.map +1 -0
  589. package/src/runs/shared/child-runtime-config.d.ts +102 -0
  590. package/src/runs/shared/child-runtime-config.d.ts.map +1 -0
  591. package/src/runs/shared/child-runtime-config.js +39 -0
  592. package/src/runs/shared/child-runtime-config.js.map +1 -0
  593. package/src/runs/shared/child-session.d.ts +154 -0
  594. package/src/runs/shared/child-session.d.ts.map +1 -0
  595. package/src/runs/shared/child-session.js +412 -0
  596. package/src/runs/shared/child-session.js.map +1 -0
  597. package/src/runs/shared/child-tool-plan.d.ts +73 -0
  598. package/src/runs/shared/child-tool-plan.d.ts.map +1 -0
  599. package/src/runs/shared/child-tool-plan.js +380 -0
  600. package/src/runs/shared/child-tool-plan.js.map +1 -0
  601. package/src/runs/shared/claude-code-adapter.d.ts +25 -0
  602. package/src/runs/shared/claude-code-adapter.d.ts.map +1 -0
  603. package/src/runs/shared/claude-code-adapter.js +120 -0
  604. package/src/runs/shared/claude-code-adapter.js.map +1 -0
  605. package/src/runs/shared/codex-exec-adapter.d.ts +26 -0
  606. package/src/runs/shared/codex-exec-adapter.d.ts.map +1 -0
  607. package/src/runs/shared/codex-exec-adapter.js +128 -0
  608. package/src/runs/shared/codex-exec-adapter.js.map +1 -0
  609. package/src/runs/shared/context-mode.d.ts +13 -0
  610. package/src/runs/shared/context-mode.d.ts.map +1 -0
  611. package/src/runs/shared/context-mode.js +39 -0
  612. package/src/runs/shared/context-mode.js.map +1 -0
  613. package/src/runs/shared/cursor-agent-adapter.d.ts +27 -0
  614. package/src/runs/shared/cursor-agent-adapter.d.ts.map +1 -0
  615. package/src/runs/shared/cursor-agent-adapter.js +100 -0
  616. package/src/runs/shared/cursor-agent-adapter.js.map +1 -0
  617. package/src/runs/shared/dynamic-fanout.d.ts +50 -0
  618. package/src/runs/shared/dynamic-fanout.d.ts.map +1 -0
  619. package/src/runs/shared/dynamic-fanout.js +274 -0
  620. package/src/runs/shared/dynamic-fanout.js.map +1 -0
  621. package/src/runs/shared/effective-system-prompt.d.ts +18 -0
  622. package/src/runs/shared/effective-system-prompt.d.ts.map +1 -0
  623. package/src/runs/shared/effective-system-prompt.js +23 -0
  624. package/src/runs/shared/effective-system-prompt.js.map +1 -0
  625. package/src/runs/shared/extension-bindings.d.ts +17 -0
  626. package/src/runs/shared/extension-bindings.d.ts.map +1 -0
  627. package/src/runs/shared/extension-bindings.js +83 -0
  628. package/src/runs/shared/extension-bindings.js.map +1 -0
  629. package/src/runs/shared/external-cli-contract.d.ts +30 -0
  630. package/src/runs/shared/external-cli-contract.d.ts.map +1 -0
  631. package/src/runs/shared/external-cli-contract.js +146 -0
  632. package/src/runs/shared/external-cli-contract.js.map +1 -0
  633. package/src/runs/shared/external-cli-preflight.d.ts +32 -0
  634. package/src/runs/shared/external-cli-preflight.d.ts.map +1 -0
  635. package/src/runs/shared/external-cli-preflight.js +116 -0
  636. package/src/runs/shared/external-cli-preflight.js.map +1 -0
  637. package/src/runs/shared/external-cli-runner.d.ts +66 -0
  638. package/src/runs/shared/external-cli-runner.d.ts.map +1 -0
  639. package/src/runs/shared/external-cli-runner.js +421 -0
  640. package/src/runs/shared/external-cli-runner.js.map +1 -0
  641. package/src/runs/shared/external-job-bridge.d.ts +18 -0
  642. package/src/runs/shared/external-job-bridge.d.ts.map +1 -0
  643. package/src/runs/shared/external-job-bridge.js +424 -0
  644. package/src/runs/shared/external-job-bridge.js.map +1 -0
  645. package/src/runs/shared/external-job-runner.d.ts +45 -0
  646. package/src/runs/shared/external-job-runner.d.ts.map +1 -0
  647. package/src/runs/shared/external-job-runner.js +353 -0
  648. package/src/runs/shared/external-job-runner.js.map +1 -0
  649. package/src/runs/shared/fast-mode-extension.d.ts +4 -0
  650. package/src/runs/shared/fast-mode-extension.d.ts.map +1 -0
  651. package/src/runs/shared/fast-mode-extension.js +9 -0
  652. package/src/runs/shared/fast-mode-extension.js.map +1 -0
  653. package/src/runs/shared/herdr-connection.d.ts +71 -0
  654. package/src/runs/shared/herdr-connection.d.ts.map +1 -0
  655. package/src/runs/shared/herdr-connection.js +258 -0
  656. package/src/runs/shared/herdr-connection.js.map +1 -0
  657. package/src/runs/shared/herdr-external-adapters.d.ts +148 -0
  658. package/src/runs/shared/herdr-external-adapters.d.ts.map +1 -0
  659. package/src/runs/shared/herdr-external-adapters.js +405 -0
  660. package/src/runs/shared/herdr-external-adapters.js.map +1 -0
  661. package/src/runs/shared/herdr-machine.d.ts +48 -0
  662. package/src/runs/shared/herdr-machine.d.ts.map +1 -0
  663. package/src/runs/shared/herdr-machine.js +247 -0
  664. package/src/runs/shared/herdr-machine.js.map +1 -0
  665. package/src/runs/shared/herdr-pi-protocol.d.ts +22 -0
  666. package/src/runs/shared/herdr-pi-protocol.d.ts.map +1 -0
  667. package/src/runs/shared/herdr-pi-protocol.js +58 -0
  668. package/src/runs/shared/herdr-pi-protocol.js.map +1 -0
  669. package/src/runs/shared/herdr-placed-run.d.ts +267 -0
  670. package/src/runs/shared/herdr-placed-run.d.ts.map +1 -0
  671. package/src/runs/shared/herdr-placed-run.js +716 -0
  672. package/src/runs/shared/herdr-placed-run.js.map +1 -0
  673. package/src/runs/shared/host-step-status.d.ts +34 -0
  674. package/src/runs/shared/host-step-status.d.ts.map +1 -0
  675. package/src/runs/shared/host-step-status.js +245 -0
  676. package/src/runs/shared/host-step-status.js.map +1 -0
  677. package/src/runs/shared/lane-metadata.d.ts +24 -0
  678. package/src/runs/shared/lane-metadata.d.ts.map +1 -0
  679. package/src/runs/shared/lane-metadata.js +127 -0
  680. package/src/runs/shared/lane-metadata.js.map +1 -0
  681. package/src/runs/shared/launch-cwd.d.ts +2 -0
  682. package/src/runs/shared/launch-cwd.d.ts.map +1 -0
  683. package/src/runs/shared/launch-cwd.js +17 -0
  684. package/src/runs/shared/launch-cwd.js.map +1 -0
  685. package/src/runs/shared/long-running-guard.d.ts +33 -0
  686. package/src/runs/shared/long-running-guard.d.ts.map +1 -0
  687. package/src/runs/shared/long-running-guard.js +199 -0
  688. package/src/runs/shared/long-running-guard.js.map +1 -0
  689. package/src/runs/shared/mcp-config-sources.d.ts +30 -0
  690. package/src/runs/shared/mcp-config-sources.d.ts.map +1 -0
  691. package/src/runs/shared/mcp-config-sources.js +419 -0
  692. package/src/runs/shared/mcp-config-sources.js.map +1 -0
  693. package/src/runs/shared/mcp-direct-tool-allowlist.d.ts +59 -0
  694. package/src/runs/shared/mcp-direct-tool-allowlist.d.ts.map +1 -0
  695. package/src/runs/shared/mcp-direct-tool-allowlist.js +400 -0
  696. package/src/runs/shared/mcp-direct-tool-allowlist.js.map +1 -0
  697. package/src/runs/shared/mcp-direct-tool-grant.d.ts +41 -0
  698. package/src/runs/shared/mcp-direct-tool-grant.d.ts.map +1 -0
  699. package/src/runs/shared/mcp-direct-tool-grant.js +146 -0
  700. package/src/runs/shared/mcp-direct-tool-grant.js.map +1 -0
  701. package/src/runs/shared/model-resolution-diagnostic.d.ts +22 -0
  702. package/src/runs/shared/model-resolution-diagnostic.d.ts.map +1 -0
  703. package/src/runs/shared/model-resolution-diagnostic.js +65 -0
  704. package/src/runs/shared/model-resolution-diagnostic.js.map +1 -0
  705. package/src/runs/shared/model-resolution.d.ts +92 -0
  706. package/src/runs/shared/model-resolution.d.ts.map +1 -0
  707. package/src/runs/shared/model-resolution.js +343 -0
  708. package/src/runs/shared/model-resolution.js.map +1 -0
  709. package/src/runs/shared/model-scope.d.ts +68 -0
  710. package/src/runs/shared/model-scope.d.ts.map +1 -0
  711. package/src/runs/shared/model-scope.js +156 -0
  712. package/src/runs/shared/model-scope.js.map +1 -0
  713. package/src/runs/shared/mutation-evidence.d.ts +19 -0
  714. package/src/runs/shared/mutation-evidence.d.ts.map +1 -0
  715. package/src/runs/shared/mutation-evidence.js +199 -0
  716. package/src/runs/shared/mutation-evidence.js.map +1 -0
  717. package/src/runs/shared/nested-events.d.ts +134 -0
  718. package/src/runs/shared/nested-events.d.ts.map +1 -0
  719. package/src/runs/shared/nested-events.js +1056 -0
  720. package/src/runs/shared/nested-events.js.map +1 -0
  721. package/src/runs/shared/nested-path.d.ts +9 -0
  722. package/src/runs/shared/nested-path.d.ts.map +1 -0
  723. package/src/runs/shared/nested-path.js +35 -0
  724. package/src/runs/shared/nested-path.js.map +1 -0
  725. package/src/runs/shared/nested-render.d.ts +21 -0
  726. package/src/runs/shared/nested-render.d.ts.map +1 -0
  727. package/src/runs/shared/nested-render.js +116 -0
  728. package/src/runs/shared/nested-render.js.map +1 -0
  729. package/src/runs/shared/orca-progress-tabs.d.ts +33 -0
  730. package/src/runs/shared/orca-progress-tabs.d.ts.map +1 -0
  731. package/src/runs/shared/orca-progress-tabs.js +527 -0
  732. package/src/runs/shared/orca-progress-tabs.js.map +1 -0
  733. package/src/runs/shared/parallel-handoff.d.ts +73 -0
  734. package/src/runs/shared/parallel-handoff.d.ts.map +1 -0
  735. package/src/runs/shared/parallel-handoff.js +733 -0
  736. package/src/runs/shared/parallel-handoff.js.map +1 -0
  737. package/src/runs/shared/parallel-utils.d.ts +164 -0
  738. package/src/runs/shared/parallel-utils.d.ts.map +1 -0
  739. package/src/runs/shared/parallel-utils.js +126 -0
  740. package/src/runs/shared/parallel-utils.js.map +1 -0
  741. package/src/runs/shared/permissions.d.ts +13 -0
  742. package/src/runs/shared/permissions.d.ts.map +1 -0
  743. package/src/runs/shared/permissions.js +93 -0
  744. package/src/runs/shared/permissions.js.map +1 -0
  745. package/src/runs/shared/pi-spawn.d.ts +28 -0
  746. package/src/runs/shared/pi-spawn.d.ts.map +1 -0
  747. package/src/runs/shared/pi-spawn.js +156 -0
  748. package/src/runs/shared/pi-spawn.js.map +1 -0
  749. package/src/runs/shared/process-signal.d.ts +16 -0
  750. package/src/runs/shared/process-signal.d.ts.map +1 -0
  751. package/src/runs/shared/process-signal.js +22 -0
  752. package/src/runs/shared/process-signal.js.map +1 -0
  753. package/src/runs/shared/readonly-drain-observation.d.ts +26 -0
  754. package/src/runs/shared/readonly-drain-observation.d.ts.map +1 -0
  755. package/src/runs/shared/readonly-drain-observation.js +51 -0
  756. package/src/runs/shared/readonly-drain-observation.js.map +1 -0
  757. package/src/runs/shared/run-fanout-budget.d.ts +15 -0
  758. package/src/runs/shared/run-fanout-budget.d.ts.map +1 -0
  759. package/src/runs/shared/run-fanout-budget.js +259 -0
  760. package/src/runs/shared/run-fanout-budget.js.map +1 -0
  761. package/src/runs/shared/run-history.d.ts +20 -0
  762. package/src/runs/shared/run-history.d.ts.map +1 -0
  763. package/src/runs/shared/run-history.js +200 -0
  764. package/src/runs/shared/run-history.js.map +1 -0
  765. package/src/runs/shared/runtime-acknowledged-extensions.d.ts +8 -0
  766. package/src/runs/shared/runtime-acknowledged-extensions.d.ts.map +1 -0
  767. package/src/runs/shared/runtime-acknowledged-extensions.js +45 -0
  768. package/src/runs/shared/runtime-acknowledged-extensions.js.map +1 -0
  769. package/src/runs/shared/session-lease.d.ts +70 -0
  770. package/src/runs/shared/session-lease.d.ts.map +1 -0
  771. package/src/runs/shared/session-lease.js +251 -0
  772. package/src/runs/shared/session-lease.js.map +1 -0
  773. package/src/runs/shared/single-output.d.ts +61 -0
  774. package/src/runs/shared/single-output.d.ts.map +1 -0
  775. package/src/runs/shared/single-output.js +271 -0
  776. package/src/runs/shared/single-output.js.map +1 -0
  777. package/src/runs/shared/spawn-budget.d.ts +21 -0
  778. package/src/runs/shared/spawn-budget.d.ts.map +1 -0
  779. package/src/runs/shared/spawn-budget.js +94 -0
  780. package/src/runs/shared/spawn-budget.js.map +1 -0
  781. package/src/runs/shared/structured-output.d.ts +57 -0
  782. package/src/runs/shared/structured-output.d.ts.map +1 -0
  783. package/src/runs/shared/structured-output.js +391 -0
  784. package/src/runs/shared/structured-output.js.map +1 -0
  785. package/src/runs/shared/subagent-control.d.ts +50 -0
  786. package/src/runs/shared/subagent-control.d.ts.map +1 -0
  787. package/src/runs/shared/subagent-control.js +234 -0
  788. package/src/runs/shared/subagent-control.js.map +1 -0
  789. package/src/runs/shared/subagent-prompt-runtime.d.ts +28 -0
  790. package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -0
  791. package/src/runs/shared/subagent-prompt-runtime.js +548 -0
  792. package/src/runs/shared/subagent-prompt-runtime.js.map +1 -0
  793. package/src/runs/shared/tool-availability.d.ts +17 -0
  794. package/src/runs/shared/tool-availability.d.ts.map +1 -0
  795. package/src/runs/shared/tool-availability.js +30 -0
  796. package/src/runs/shared/tool-availability.js.map +1 -0
  797. package/src/runs/shared/tool-budget.d.ts +22 -0
  798. package/src/runs/shared/tool-budget.d.ts.map +1 -0
  799. package/src/runs/shared/tool-budget.js +79 -0
  800. package/src/runs/shared/tool-budget.js.map +1 -0
  801. package/src/runs/shared/tool-timeout.d.ts +32 -0
  802. package/src/runs/shared/tool-timeout.d.ts.map +1 -0
  803. package/src/runs/shared/tool-timeout.js +74 -0
  804. package/src/runs/shared/tool-timeout.js.map +1 -0
  805. package/src/runs/shared/usage-budget.d.ts +8 -0
  806. package/src/runs/shared/usage-budget.d.ts.map +1 -0
  807. package/src/runs/shared/usage-budget.js +75 -0
  808. package/src/runs/shared/usage-budget.js.map +1 -0
  809. package/src/runs/shared/usage-reconciliation.d.ts +9 -0
  810. package/src/runs/shared/usage-reconciliation.d.ts.map +1 -0
  811. package/src/runs/shared/usage-reconciliation.js +72 -0
  812. package/src/runs/shared/usage-reconciliation.js.map +1 -0
  813. package/src/runs/shared/workflow-async-child-guidance.d.ts +4 -0
  814. package/src/runs/shared/workflow-async-child-guidance.d.ts.map +1 -0
  815. package/src/runs/shared/workflow-async-child-guidance.js +18 -0
  816. package/src/runs/shared/workflow-async-child-guidance.js.map +1 -0
  817. package/src/runs/shared/workflow-graph.d.ts +32 -0
  818. package/src/runs/shared/workflow-graph.d.ts.map +1 -0
  819. package/src/runs/shared/workflow-graph.js +222 -0
  820. package/src/runs/shared/workflow-graph.js.map +1 -0
  821. package/src/runs/shared/worktree-cleanup-plan.d.ts +78 -0
  822. package/src/runs/shared/worktree-cleanup-plan.d.ts.map +1 -0
  823. package/src/runs/shared/worktree-cleanup-plan.js +782 -0
  824. package/src/runs/shared/worktree-cleanup-plan.js.map +1 -0
  825. package/src/runs/shared/worktree-setup-command.d.ts +39 -0
  826. package/src/runs/shared/worktree-setup-command.d.ts.map +1 -0
  827. package/src/runs/shared/worktree-setup-command.js +201 -0
  828. package/src/runs/shared/worktree-setup-command.js.map +1 -0
  829. package/src/runs/shared/worktree.d.ts +179 -0
  830. package/src/runs/shared/worktree.d.ts.map +1 -0
  831. package/src/runs/shared/worktree.js +1333 -0
  832. package/src/runs/shared/worktree.js.map +1 -0
  833. package/src/shared/accessible-dir.d.ts +12 -0
  834. package/src/shared/accessible-dir.d.ts.map +1 -0
  835. package/src/shared/accessible-dir.js +37 -0
  836. package/src/shared/accessible-dir.js.map +1 -0
  837. package/src/shared/agent-stream-options.d.ts +6 -0
  838. package/src/shared/agent-stream-options.d.ts.map +1 -0
  839. package/src/shared/agent-stream-options.js +4 -0
  840. package/src/shared/agent-stream-options.js.map +1 -0
  841. package/src/shared/artifacts.d.ts +23 -0
  842. package/src/shared/artifacts.d.ts.map +1 -0
  843. package/src/shared/artifacts.js +273 -0
  844. package/src/shared/artifacts.js.map +1 -0
  845. package/src/shared/atomic-json.d.ts +19 -0
  846. package/src/shared/atomic-json.d.ts.map +1 -0
  847. package/src/shared/atomic-json.js +60 -0
  848. package/src/shared/atomic-json.js.map +1 -0
  849. package/src/shared/capacity-resilient-json.d.ts +27 -0
  850. package/src/shared/capacity-resilient-json.d.ts.map +1 -0
  851. package/src/shared/capacity-resilient-json.js +87 -0
  852. package/src/shared/capacity-resilient-json.js.map +1 -0
  853. package/src/shared/child-cache-retention.d.ts +30 -0
  854. package/src/shared/child-cache-retention.d.ts.map +1 -0
  855. package/src/shared/child-cache-retention.js +41 -0
  856. package/src/shared/child-cache-retention.js.map +1 -0
  857. package/src/shared/child-session-name.d.ts +9 -0
  858. package/src/shared/child-session-name.d.ts.map +1 -0
  859. package/src/shared/child-session-name.js +39 -0
  860. package/src/shared/child-session-name.js.map +1 -0
  861. package/src/shared/child-transcript.d.ts +38 -0
  862. package/src/shared/child-transcript.d.ts.map +1 -0
  863. package/src/shared/child-transcript.js +226 -0
  864. package/src/shared/child-transcript.js.map +1 -0
  865. package/src/shared/completion-owner.d.ts +3 -0
  866. package/src/shared/completion-owner.d.ts.map +1 -0
  867. package/src/shared/completion-owner.js +9 -0
  868. package/src/shared/completion-owner.js.map +1 -0
  869. package/src/shared/display-text.d.ts +6 -0
  870. package/src/shared/display-text.d.ts.map +1 -0
  871. package/src/shared/display-text.js +155 -0
  872. package/src/shared/display-text.js.map +1 -0
  873. package/src/shared/extension-context.d.ts +6 -0
  874. package/src/shared/extension-context.d.ts.map +1 -0
  875. package/src/shared/extension-context.js +22 -0
  876. package/src/shared/extension-context.js.map +1 -0
  877. package/src/shared/file-coalescer.d.ts +12 -0
  878. package/src/shared/file-coalescer.d.ts.map +1 -0
  879. package/src/shared/file-coalescer.js +35 -0
  880. package/src/shared/file-coalescer.js.map +1 -0
  881. package/src/shared/file-system-retry.d.ts +32 -0
  882. package/src/shared/file-system-retry.d.ts.map +1 -0
  883. package/src/shared/file-system-retry.js +85 -0
  884. package/src/shared/file-system-retry.js.map +1 -0
  885. package/src/shared/fork-context.d.ts +59 -0
  886. package/src/shared/fork-context.d.ts.map +1 -0
  887. package/src/shared/fork-context.js +171 -0
  888. package/src/shared/fork-context.js.map +1 -0
  889. package/src/shared/fork-session-cwd.d.ts +3 -0
  890. package/src/shared/fork-session-cwd.d.ts.map +1 -0
  891. package/src/shared/fork-session-cwd.js +24 -0
  892. package/src/shared/fork-session-cwd.js.map +1 -0
  893. package/src/shared/formatters.d.ts +36 -0
  894. package/src/shared/formatters.d.ts.map +1 -0
  895. package/src/shared/formatters.js +143 -0
  896. package/src/shared/formatters.js.map +1 -0
  897. package/src/shared/jsonl-writer.d.ts +21 -0
  898. package/src/shared/jsonl-writer.d.ts.map +1 -0
  899. package/src/shared/jsonl-writer.js +68 -0
  900. package/src/shared/jsonl-writer.js.map +1 -0
  901. package/src/shared/launch-contract.d.ts +64 -0
  902. package/src/shared/launch-contract.d.ts.map +1 -0
  903. package/src/shared/launch-contract.js +140 -0
  904. package/src/shared/launch-contract.js.map +1 -0
  905. package/src/shared/model-info.d.ts +44 -0
  906. package/src/shared/model-info.d.ts.map +1 -0
  907. package/src/shared/model-info.js +73 -0
  908. package/src/shared/model-info.js.map +1 -0
  909. package/src/shared/model-response-aliases.d.ts +2 -0
  910. package/src/shared/model-response-aliases.d.ts.map +1 -0
  911. package/src/shared/model-response-aliases.js +16 -0
  912. package/src/shared/model-response-aliases.js.map +1 -0
  913. package/src/shared/node-executable.d.ts +2 -0
  914. package/src/shared/node-executable.d.ts.map +1 -0
  915. package/src/shared/node-executable.js +21 -0
  916. package/src/shared/node-executable.js.map +1 -0
  917. package/src/shared/opencode-session-headers.d.ts +13 -0
  918. package/src/shared/opencode-session-headers.d.ts.map +1 -0
  919. package/src/shared/opencode-session-headers.js +27 -0
  920. package/src/shared/opencode-session-headers.js.map +1 -0
  921. package/src/shared/prompt-resources.d.ts +6 -0
  922. package/src/shared/prompt-resources.d.ts.map +1 -0
  923. package/src/shared/prompt-resources.js +11 -0
  924. package/src/shared/prompt-resources.js.map +1 -0
  925. package/src/shared/pruned-fork.d.ts +35 -0
  926. package/src/shared/pruned-fork.d.ts.map +1 -0
  927. package/src/shared/pruned-fork.js +417 -0
  928. package/src/shared/pruned-fork.js.map +1 -0
  929. package/src/shared/required-child-extensions.d.ts +20 -0
  930. package/src/shared/required-child-extensions.d.ts.map +1 -0
  931. package/src/shared/required-child-extensions.js +74 -0
  932. package/src/shared/required-child-extensions.js.map +1 -0
  933. package/src/shared/session-file-trust.d.ts +2 -0
  934. package/src/shared/session-file-trust.d.ts.map +1 -0
  935. package/src/shared/session-file-trust.js +21 -0
  936. package/src/shared/session-file-trust.js.map +1 -0
  937. package/src/shared/session-identity.d.ts +7 -0
  938. package/src/shared/session-identity.d.ts.map +1 -0
  939. package/src/shared/session-identity.js +7 -0
  940. package/src/shared/session-identity.js.map +1 -0
  941. package/src/shared/session-tokens.d.ts +3 -0
  942. package/src/shared/session-tokens.d.ts.map +1 -0
  943. package/src/shared/session-tokens.js +59 -0
  944. package/src/shared/session-tokens.js.map +1 -0
  945. package/src/shared/settings.d.ts +147 -0
  946. package/src/shared/settings.d.ts.map +1 -0
  947. package/src/shared/settings.js +248 -0
  948. package/src/shared/settings.js.map +1 -0
  949. package/src/shared/shortcuts.d.ts +2 -0
  950. package/src/shared/shortcuts.d.ts.map +1 -0
  951. package/src/shared/shortcuts.js +18 -0
  952. package/src/shared/shortcuts.js.map +1 -0
  953. package/src/shared/status-format.d.ts +10 -0
  954. package/src/shared/status-format.d.ts.map +1 -0
  955. package/src/shared/status-format.js +61 -0
  956. package/src/shared/status-format.js.map +1 -0
  957. package/src/shared/thinking-ceiling.d.ts +14 -0
  958. package/src/shared/thinking-ceiling.d.ts.map +1 -0
  959. package/src/shared/thinking-ceiling.js +38 -0
  960. package/src/shared/thinking-ceiling.js.map +1 -0
  961. package/src/shared/types.d.ts +2660 -0
  962. package/src/shared/types.d.ts.map +1 -0
  963. package/src/shared/types.js +265 -0
  964. package/src/shared/types.js.map +1 -0
  965. package/src/shared/utf8.d.ts +6 -0
  966. package/src/shared/utf8.d.ts.map +1 -0
  967. package/src/shared/utf8.js +13 -0
  968. package/src/shared/utf8.js.map +1 -0
  969. package/src/shared/utils.d.ts +71 -0
  970. package/src/shared/utils.d.ts.map +1 -0
  971. package/src/shared/utils.js +593 -0
  972. package/src/shared/utils.js.map +1 -0
  973. package/src/shared/watch-strategy.d.ts +3 -0
  974. package/src/shared/watch-strategy.d.ts.map +1 -0
  975. package/src/shared/watch-strategy.js +6 -0
  976. package/src/shared/watch-strategy.js.map +1 -0
  977. package/src/shared/workflow-child-permit.d.ts +59 -0
  978. package/src/shared/workflow-child-permit.d.ts.map +1 -0
  979. package/src/shared/workflow-child-permit.js +160 -0
  980. package/src/shared/workflow-child-permit.js.map +1 -0
  981. package/src/slash/delegation-adapters.d.ts +147 -0
  982. package/src/slash/delegation-adapters.d.ts.map +1 -0
  983. package/src/slash/delegation-adapters.js +293 -0
  984. package/src/slash/delegation-adapters.js.map +1 -0
  985. package/src/slash/delegation-json.d.ts +11 -0
  986. package/src/slash/delegation-json.d.ts.map +1 -0
  987. package/src/slash/delegation-json.js +118 -0
  988. package/src/slash/delegation-json.js.map +1 -0
  989. package/src/slash/delegation-request.d.ts +13 -0
  990. package/src/slash/delegation-request.d.ts.map +1 -0
  991. package/src/slash/delegation-request.js +175 -0
  992. package/src/slash/delegation-request.js.map +1 -0
  993. package/src/slash/prompt-template-bridge.d.ts +27 -0
  994. package/src/slash/prompt-template-bridge.d.ts.map +1 -0
  995. package/src/slash/prompt-template-bridge.js +380 -0
  996. package/src/slash/prompt-template-bridge.js.map +1 -0
  997. package/src/slash/prompt-workflows.d.ts +22 -0
  998. package/src/slash/prompt-workflows.d.ts.map +1 -0
  999. package/src/slash/prompt-workflows.js +261 -0
  1000. package/src/slash/prompt-workflows.js.map +1 -0
  1001. package/src/slash/selector.d.ts +48 -0
  1002. package/src/slash/selector.d.ts.map +1 -0
  1003. package/src/slash/selector.js +118 -0
  1004. package/src/slash/selector.js.map +1 -0
  1005. package/src/slash/slash-bridge.d.ts +31 -0
  1006. package/src/slash/slash-bridge.d.ts.map +1 -0
  1007. package/src/slash/slash-bridge.js +133 -0
  1008. package/src/slash/slash-bridge.js.map +1 -0
  1009. package/src/slash/slash-commands.d.ts +9 -0
  1010. package/src/slash/slash-commands.d.ts.map +1 -0
  1011. package/src/slash/slash-commands.js +1295 -0
  1012. package/src/slash/slash-commands.js.map +1 -0
  1013. package/src/slash/slash-live-state.d.ts +22 -0
  1014. package/src/slash/slash-live-state.d.ts.map +1 -0
  1015. package/src/slash/slash-live-state.js +264 -0
  1016. package/src/slash/slash-live-state.js.map +1 -0
  1017. package/src/slash/subagents-admin.d.ts +3 -0
  1018. package/src/slash/subagents-admin.d.ts.map +1 -0
  1019. package/src/slash/subagents-admin.js +453 -0
  1020. package/src/slash/subagents-admin.js.map +1 -0
  1021. package/src/tui/fleet-status.d.ts +86 -0
  1022. package/src/tui/fleet-status.d.ts.map +1 -0
  1023. package/src/tui/fleet-status.js +1083 -0
  1024. package/src/tui/fleet-status.js.map +1 -0
  1025. package/src/tui/fleet-transcript.d.ts +50 -0
  1026. package/src/tui/fleet-transcript.d.ts.map +1 -0
  1027. package/src/tui/fleet-transcript.js +497 -0
  1028. package/src/tui/fleet-transcript.js.map +1 -0
  1029. package/src/tui/fleet.d.ts +169 -0
  1030. package/src/tui/fleet.d.ts.map +1 -0
  1031. package/src/tui/fleet.js +1412 -0
  1032. package/src/tui/fleet.js.map +1 -0
  1033. package/src/tui/render-helpers.d.ts +24 -0
  1034. package/src/tui/render-helpers.d.ts.map +1 -0
  1035. package/src/tui/render-helpers.js +101 -0
  1036. package/src/tui/render-helpers.js.map +1 -0
  1037. package/src/tui/render.d.ts +61 -0
  1038. package/src/tui/render.d.ts.map +1 -0
  1039. package/src/tui/render.js +3608 -0
  1040. package/src/tui/render.js.map +1 -0
  1041. package/src/watchdog/change-signature.d.ts +8 -0
  1042. package/src/watchdog/change-signature.d.ts.map +1 -0
  1043. package/src/watchdog/change-signature.js +246 -0
  1044. package/src/watchdog/change-signature.js.map +1 -0
  1045. package/src/watchdog/child-status.d.ts +54 -0
  1046. package/src/watchdog/child-status.d.ts.map +1 -0
  1047. package/src/watchdog/child-status.js +188 -0
  1048. package/src/watchdog/child-status.js.map +1 -0
  1049. package/src/watchdog/diff-tool.d.ts +23 -0
  1050. package/src/watchdog/diff-tool.d.ts.map +1 -0
  1051. package/src/watchdog/diff-tool.js +84 -0
  1052. package/src/watchdog/diff-tool.js.map +1 -0
  1053. package/src/watchdog/emission-guard.d.ts +37 -0
  1054. package/src/watchdog/emission-guard.d.ts.map +1 -0
  1055. package/src/watchdog/emission-guard.js +98 -0
  1056. package/src/watchdog/emission-guard.js.map +1 -0
  1057. package/src/watchdog/guidance.d.ts +4 -0
  1058. package/src/watchdog/guidance.d.ts.map +1 -0
  1059. package/src/watchdog/guidance.js +20 -0
  1060. package/src/watchdog/guidance.js.map +1 -0
  1061. package/src/watchdog/lsp-diagnostics.d.ts +18 -0
  1062. package/src/watchdog/lsp-diagnostics.d.ts.map +1 -0
  1063. package/src/watchdog/lsp-diagnostics.js +490 -0
  1064. package/src/watchdog/lsp-diagnostics.js.map +1 -0
  1065. package/src/watchdog/model-selection.d.ts +25 -0
  1066. package/src/watchdog/model-selection.d.ts.map +1 -0
  1067. package/src/watchdog/model-selection.js +168 -0
  1068. package/src/watchdog/model-selection.js.map +1 -0
  1069. package/src/watchdog/permission-arbiter.d.ts +21 -0
  1070. package/src/watchdog/permission-arbiter.d.ts.map +1 -0
  1071. package/src/watchdog/permission-arbiter.js +141 -0
  1072. package/src/watchdog/permission-arbiter.js.map +1 -0
  1073. package/src/watchdog/register-child.d.ts +12 -0
  1074. package/src/watchdog/register-child.d.ts.map +1 -0
  1075. package/src/watchdog/register-child.js +120 -0
  1076. package/src/watchdog/register-child.js.map +1 -0
  1077. package/src/watchdog/register-main.d.ts +10 -0
  1078. package/src/watchdog/register-main.d.ts.map +1 -0
  1079. package/src/watchdog/register-main.js +419 -0
  1080. package/src/watchdog/register-main.js.map +1 -0
  1081. package/src/watchdog/render.d.ts +12 -0
  1082. package/src/watchdog/render.d.ts.map +1 -0
  1083. package/src/watchdog/render.js +52 -0
  1084. package/src/watchdog/render.js.map +1 -0
  1085. package/src/watchdog/review.d.ts +37 -0
  1086. package/src/watchdog/review.d.ts.map +1 -0
  1087. package/src/watchdog/review.js +325 -0
  1088. package/src/watchdog/review.js.map +1 -0
  1089. package/src/watchdog/rules.d.ts +22 -0
  1090. package/src/watchdog/rules.d.ts.map +1 -0
  1091. package/src/watchdog/rules.js +59 -0
  1092. package/src/watchdog/rules.js.map +1 -0
  1093. package/src/watchdog/runtime.d.ts +196 -0
  1094. package/src/watchdog/runtime.d.ts.map +1 -0
  1095. package/src/watchdog/runtime.js +862 -0
  1096. package/src/watchdog/runtime.js.map +1 -0
  1097. package/src/watchdog/scope.d.ts +15 -0
  1098. package/src/watchdog/scope.d.ts.map +1 -0
  1099. package/src/watchdog/scope.js +45 -0
  1100. package/src/watchdog/scope.js.map +1 -0
  1101. package/src/watchdog/settings.d.ts +30 -0
  1102. package/src/watchdog/settings.d.ts.map +1 -0
  1103. package/src/watchdog/settings.js +476 -0
  1104. package/src/watchdog/settings.js.map +1 -0
  1105. package/src/watchdog/tool-actions.d.ts +18 -0
  1106. package/src/watchdog/tool-actions.d.ts.map +1 -0
  1107. package/src/watchdog/tool-actions.js +151 -0
  1108. package/src/watchdog/tool-actions.js.map +1 -0
  1109. package/src/watchdog/turn-delta.d.ts +12 -0
  1110. package/src/watchdog/turn-delta.d.ts.map +1 -0
  1111. package/src/watchdog/turn-delta.js +185 -0
  1112. package/src/watchdog/turn-delta.js.map +1 -0
  1113. package/src/watchdog/types.d.ts +142 -0
  1114. package/src/watchdog/types.d.ts.map +1 -0
  1115. package/src/watchdog/types.js +28 -0
  1116. package/src/watchdog/types.js.map +1 -0
  1117. package/src/watchdog/warning-format.d.ts +8 -0
  1118. package/src/watchdog/warning-format.d.ts.map +1 -0
  1119. package/src/watchdog/warning-format.js +60 -0
  1120. package/src/watchdog/warning-format.js.map +1 -0
  1121. package/src/workflows/chat-progress.d.ts +38 -0
  1122. package/src/workflows/chat-progress.d.ts.map +1 -0
  1123. package/src/workflows/chat-progress.js +130 -0
  1124. package/src/workflows/chat-progress.js.map +1 -0
  1125. package/src/workflows/host-command.d.ts +31 -0
  1126. package/src/workflows/host-command.d.ts.map +1 -0
  1127. package/src/workflows/host-command.js +228 -0
  1128. package/src/workflows/host-command.js.map +1 -0
  1129. package/src/workflows/scripted-workflow.d.ts +195 -0
  1130. package/src/workflows/scripted-workflow.d.ts.map +1 -0
  1131. package/src/workflows/scripted-workflow.js +2634 -0
  1132. package/src/workflows/scripted-workflow.js.map +1 -0
  1133. package/src/workflows/workflow-checklist.d.ts +124 -0
  1134. package/src/workflows/workflow-checklist.d.ts.map +1 -0
  1135. package/src/workflows/workflow-checklist.js +312 -0
  1136. package/src/workflows/workflow-checklist.js.map +1 -0
  1137. package/src/workflows/workflow-child-summary.d.ts +20 -0
  1138. package/src/workflows/workflow-child-summary.d.ts.map +1 -0
  1139. package/src/workflows/workflow-child-summary.js +179 -0
  1140. package/src/workflows/workflow-child-summary.js.map +1 -0
  1141. package/src/workflows/workflow-preflight.d.ts +59 -0
  1142. package/src/workflows/workflow-preflight.d.ts.map +1 -0
  1143. package/src/workflows/workflow-preflight.js +289 -0
  1144. package/src/workflows/workflow-preflight.js.map +1 -0
  1145. package/src/workflows/workflow-receipt.d.ts +35 -0
  1146. package/src/workflows/workflow-receipt.d.ts.map +1 -0
  1147. package/src/workflows/workflow-receipt.js +449 -0
  1148. package/src/workflows/workflow-receipt.js.map +1 -0
  1149. package/src/workflows/workflow-resources.d.ts +43 -0
  1150. package/src/workflows/workflow-resources.d.ts.map +1 -0
  1151. package/src/workflows/workflow-resources.js +230 -0
  1152. package/src/workflows/workflow-resources.js.map +1 -0
  1153. package/src/workflows/workflow-settlement.d.ts +85 -0
  1154. package/src/workflows/workflow-settlement.d.ts.map +1 -0
  1155. package/src/workflows/workflow-settlement.js +204 -0
  1156. package/src/workflows/workflow-settlement.js.map +1 -0
  1157. package/index.ts +0 -13
  1158. package/src/agents/advertised-agent-prompt.ts +0 -94
  1159. package/src/agents/agent-management.ts +0 -1417
  1160. package/src/agents/agent-memory.ts +0 -254
  1161. package/src/agents/agent-refinements.ts +0 -624
  1162. package/src/agents/agent-scope.ts +0 -6
  1163. package/src/agents/agent-selection.ts +0 -25
  1164. package/src/agents/agent-serializer.ts +0 -182
  1165. package/src/agents/agents.ts +0 -2917
  1166. package/src/agents/builtin-names.ts +0 -16
  1167. package/src/agents/chain-serializer.ts +0 -285
  1168. package/src/agents/frontmatter.ts +0 -153
  1169. package/src/agents/identity.ts +0 -30
  1170. package/src/agents/proactive-skills.ts +0 -194
  1171. package/src/agents/runtime-agent-events.ts +0 -70
  1172. package/src/agents/runtime-agent-registry.ts +0 -430
  1173. package/src/agents/skills.ts +0 -754
  1174. package/src/api/agents.ts +0 -12
  1175. package/src/api/background-work.ts +0 -206
  1176. package/src/api/capability-ceiling.ts +0 -16
  1177. package/src/api/child-tool-plan.ts +0 -5
  1178. package/src/api/control-channel.ts +0 -4
  1179. package/src/api/delegation.ts +0 -116
  1180. package/src/api/external-job-provider.ts +0 -195
  1181. package/src/api/external-runs.ts +0 -282
  1182. package/src/api/intercom-bridge.ts +0 -3
  1183. package/src/api/preflight.ts +0 -539
  1184. package/src/api/project-panes.ts +0 -32
  1185. package/src/api/required-child-extensions.ts +0 -6
  1186. package/src/api/shared-types.ts +0 -29
  1187. package/src/api/workflow-resources.ts +0 -6
  1188. package/src/extension/config.ts +0 -230
  1189. package/src/extension/control-notices.ts +0 -58
  1190. package/src/extension/doctor.ts +0 -270
  1191. package/src/extension/fanout-child.ts +0 -265
  1192. package/src/extension/herdr-pi-bridge.ts +0 -160
  1193. package/src/extension/index.ts +0 -1205
  1194. package/src/extension/public-execution.ts +0 -225
  1195. package/src/extension/rpc.ts +0 -848
  1196. package/src/extension/schemas.ts +0 -428
  1197. package/src/extension/steering-notices.ts +0 -35
  1198. package/src/extension/subagent-guide.ts +0 -39
  1199. package/src/extension/tool-description.ts +0 -175
  1200. package/src/extension/tool-result.ts +0 -19
  1201. package/src/inspectors/actions.ts +0 -148
  1202. package/src/inspectors/ghostty/actions.ts +0 -74
  1203. package/src/inspectors/ghostty/plugin.ts +0 -29
  1204. package/src/inspectors/herdr/actions.ts +0 -155
  1205. package/src/inspectors/herdr/client.ts +0 -130
  1206. package/src/inspectors/herdr/focus.ts +0 -55
  1207. package/src/inspectors/herdr/plugin.ts +0 -20
  1208. package/src/inspectors/herdr/project-panes.ts +0 -730
  1209. package/src/inspectors/inspector-runner.ts +0 -153
  1210. package/src/inspectors/plugins.ts +0 -8
  1211. package/src/inspectors/session-roots-codec.ts +0 -31
  1212. package/src/inspectors/shell-command.ts +0 -16
  1213. package/src/inspectors/types.ts +0 -51
  1214. package/src/integrations/herdr-status.ts +0 -400
  1215. package/src/integrations/pi-web-session-liveness.ts +0 -73
  1216. package/src/intercom/intercom-bridge.ts +0 -233
  1217. package/src/intercom/native-supervisor-channel.ts +0 -917
  1218. package/src/intercom/result-intercom.ts +0 -423
  1219. package/src/intercom/supervisor-ui.ts +0 -244
  1220. package/src/missions/actions.ts +0 -433
  1221. package/src/missions/goal-driver.ts +0 -164
  1222. package/src/missions/lifecycle.ts +0 -367
  1223. package/src/missions/store.ts +0 -584
  1224. package/src/missions/types.ts +0 -190
  1225. package/src/missions/workflow-state.ts +0 -281
  1226. package/src/policy/authority.ts +0 -50
  1227. package/src/profiles/profiles.ts +0 -668
  1228. package/src/runs/background/active-async-capacity.ts +0 -520
  1229. package/src/runs/background/active-run-index.ts +0 -155
  1230. package/src/runs/background/async-execution.ts +0 -2278
  1231. package/src/runs/background/async-job-tracker.ts +0 -826
  1232. package/src/runs/background/async-resume.ts +0 -647
  1233. package/src/runs/background/async-retention.ts +0 -912
  1234. package/src/runs/background/async-status-snapshot.ts +0 -46
  1235. package/src/runs/background/async-status.ts +0 -771
  1236. package/src/runs/background/auto-drain.ts +0 -92
  1237. package/src/runs/background/binary-bootstrap.ts +0 -38
  1238. package/src/runs/background/chain-append.ts +0 -321
  1239. package/src/runs/background/chain-root-attachment.ts +0 -259
  1240. package/src/runs/background/completion-batcher.ts +0 -168
  1241. package/src/runs/background/completion-dedupe.ts +0 -58
  1242. package/src/runs/background/completion-replay.ts +0 -287
  1243. package/src/runs/background/control-channel.ts +0 -600
  1244. package/src/runs/background/fleet-view.ts +0 -648
  1245. package/src/runs/background/index-segment.ts +0 -59
  1246. package/src/runs/background/inspect-rpc.ts +0 -443
  1247. package/src/runs/background/notify.ts +0 -819
  1248. package/src/runs/background/owned-process-tree.ts +0 -131
  1249. package/src/runs/background/parallel-groups.ts +0 -45
  1250. package/src/runs/background/process-terminal.ts +0 -310
  1251. package/src/runs/background/result-delivery-ownership.ts +0 -45
  1252. package/src/runs/background/result-files.ts +0 -523
  1253. package/src/runs/background/result-watcher.ts +0 -809
  1254. package/src/runs/background/resume-guidance.ts +0 -56
  1255. package/src/runs/background/retained-children.ts +0 -135
  1256. package/src/runs/background/retained-nested-route-tracker.ts +0 -96
  1257. package/src/runs/background/run-child-session.ts +0 -690
  1258. package/src/runs/background/run-id-query.ts +0 -7
  1259. package/src/runs/background/run-id-resolver.ts +0 -175
  1260. package/src/runs/background/run-status.ts +0 -786
  1261. package/src/runs/background/runner-aliases.ts +0 -142
  1262. package/src/runs/background/runner-child-launch.ts +0 -91
  1263. package/src/runs/background/runner-child-sessions.ts +0 -32
  1264. package/src/runs/background/runner-http-dispatcher.ts +0 -119
  1265. package/src/runs/background/scheduled-runs.ts +0 -1012
  1266. package/src/runs/background/stale-run-reconciler.ts +0 -436
  1267. package/src/runs/background/steering.ts +0 -260
  1268. package/src/runs/background/subagent-runner.ts +0 -5357
  1269. package/src/runs/background/subagent-wait.ts +0 -876
  1270. package/src/runs/background/terminal-run-index.ts +0 -138
  1271. package/src/runs/background/top-level-async.ts +0 -14
  1272. package/src/runs/background/wait-completions.ts +0 -261
  1273. package/src/runs/background/wait-config.ts +0 -50
  1274. package/src/runs/background/wait-subscriptions.ts +0 -354
  1275. package/src/runs/background/wait-tool.ts +0 -45
  1276. package/src/runs/foreground/async-dismiss-action.ts +0 -86
  1277. package/src/runs/foreground/async-steering-action.ts +0 -276
  1278. package/src/runs/foreground/async-stop-action.ts +0 -176
  1279. package/src/runs/foreground/execution.ts +0 -2254
  1280. package/src/runs/foreground/foreground-control.ts +0 -157
  1281. package/src/runs/foreground/foreground-history.ts +0 -163
  1282. package/src/runs/foreground/prompt-audit.ts +0 -178
  1283. package/src/runs/foreground/subagent-executor.ts +0 -7526
  1284. package/src/runs/foreground/workflow-detach-reconcile.ts +0 -304
  1285. package/src/runs/foreground/workflow-foreground-steering.ts +0 -169
  1286. package/src/runs/shared/abort-recovery.ts +0 -119
  1287. package/src/runs/shared/acceptance.ts +0 -1698
  1288. package/src/runs/shared/agent-contract.ts +0 -38
  1289. package/src/runs/shared/async-status-projection.ts +0 -659
  1290. package/src/runs/shared/background-process-options.ts +0 -9
  1291. package/src/runs/shared/capability-ceiling.ts +0 -211
  1292. package/src/runs/shared/chain-outputs.ts +0 -116
  1293. package/src/runs/shared/child-hooks.ts +0 -189
  1294. package/src/runs/shared/child-identity.ts +0 -62
  1295. package/src/runs/shared/child-launch-plan.ts +0 -163
  1296. package/src/runs/shared/child-launch.ts +0 -342
  1297. package/src/runs/shared/child-lifecycle.ts +0 -28
  1298. package/src/runs/shared/child-runtime-config.ts +0 -133
  1299. package/src/runs/shared/child-session.ts +0 -448
  1300. package/src/runs/shared/child-tool-plan.ts +0 -661
  1301. package/src/runs/shared/claude-code-adapter.ts +0 -133
  1302. package/src/runs/shared/codex-exec-adapter.ts +0 -129
  1303. package/src/runs/shared/completion-evidence.ts +0 -89
  1304. package/src/runs/shared/completion-guard.ts +0 -255
  1305. package/src/runs/shared/context-mode.ts +0 -44
  1306. package/src/runs/shared/cursor-agent-adapter.ts +0 -114
  1307. package/src/runs/shared/dynamic-fanout.ts +0 -297
  1308. package/src/runs/shared/effective-system-prompt.ts +0 -33
  1309. package/src/runs/shared/extension-bindings.ts +0 -78
  1310. package/src/runs/shared/external-cli-contract.ts +0 -177
  1311. package/src/runs/shared/external-cli-preflight.ts +0 -142
  1312. package/src/runs/shared/external-cli-runner.ts +0 -431
  1313. package/src/runs/shared/external-job-bridge.ts +0 -460
  1314. package/src/runs/shared/external-job-runner.ts +0 -389
  1315. package/src/runs/shared/fast-mode-extension.ts +0 -10
  1316. package/src/runs/shared/herdr-connection.ts +0 -134
  1317. package/src/runs/shared/herdr-external-adapters.ts +0 -169
  1318. package/src/runs/shared/herdr-machine.ts +0 -279
  1319. package/src/runs/shared/herdr-pi-protocol.ts +0 -59
  1320. package/src/runs/shared/herdr-placed-run.ts +0 -263
  1321. package/src/runs/shared/host-step-status.ts +0 -231
  1322. package/src/runs/shared/lane-metadata.ts +0 -126
  1323. package/src/runs/shared/launch-cwd.ts +0 -16
  1324. package/src/runs/shared/llm-intent-arbiter.ts +0 -321
  1325. package/src/runs/shared/long-running-guard.ts +0 -221
  1326. package/src/runs/shared/mcp-config-sources.ts +0 -422
  1327. package/src/runs/shared/mcp-direct-tool-allowlist.ts +0 -484
  1328. package/src/runs/shared/mcp-direct-tool-grant.ts +0 -194
  1329. package/src/runs/shared/model-resolution-diagnostic.ts +0 -76
  1330. package/src/runs/shared/model-resolution.ts +0 -441
  1331. package/src/runs/shared/model-scope.ts +0 -205
  1332. package/src/runs/shared/mutation-evidence.ts +0 -199
  1333. package/src/runs/shared/nested-events.ts +0 -1079
  1334. package/src/runs/shared/nested-path.ts +0 -38
  1335. package/src/runs/shared/nested-render.ts +0 -127
  1336. package/src/runs/shared/orca-progress-tabs.ts +0 -510
  1337. package/src/runs/shared/parallel-handoff.ts +0 -741
  1338. package/src/runs/shared/parallel-utils.ts +0 -279
  1339. package/src/runs/shared/permissions.ts +0 -86
  1340. package/src/runs/shared/pi-spawn.ts +0 -207
  1341. package/src/runs/shared/process-signal.ts +0 -35
  1342. package/src/runs/shared/readonly-drain-observation.ts +0 -42
  1343. package/src/runs/shared/run-fanout-budget.ts +0 -267
  1344. package/src/runs/shared/run-history.ts +0 -201
  1345. package/src/runs/shared/runtime-acknowledged-extensions.ts +0 -44
  1346. package/src/runs/shared/session-lease.ts +0 -293
  1347. package/src/runs/shared/single-output.ts +0 -304
  1348. package/src/runs/shared/spawn-budget.ts +0 -128
  1349. package/src/runs/shared/structured-output.ts +0 -236
  1350. package/src/runs/shared/subagent-control.ts +0 -294
  1351. package/src/runs/shared/subagent-prompt-runtime.ts +0 -545
  1352. package/src/runs/shared/task-intent.ts +0 -244
  1353. package/src/runs/shared/tool-availability.ts +0 -37
  1354. package/src/runs/shared/tool-budget.ts +0 -66
  1355. package/src/runs/shared/tool-timeout.ts +0 -93
  1356. package/src/runs/shared/usage-budget.ts +0 -65
  1357. package/src/runs/shared/workflow-async-child-guidance.ts +0 -18
  1358. package/src/runs/shared/workflow-graph.ts +0 -225
  1359. package/src/runs/shared/worktree-cleanup-plan.ts +0 -869
  1360. package/src/runs/shared/worktree-setup-command.ts +0 -213
  1361. package/src/runs/shared/worktree.ts +0 -1538
  1362. package/src/shared/accessible-dir.ts +0 -47
  1363. package/src/shared/agent-stream-options.ts +0 -5
  1364. package/src/shared/artifacts.ts +0 -281
  1365. package/src/shared/atomic-json.ts +0 -83
  1366. package/src/shared/capacity-resilient-json.ts +0 -102
  1367. package/src/shared/child-cache-retention.ts +0 -43
  1368. package/src/shared/child-session-name.ts +0 -46
  1369. package/src/shared/child-transcript.ts +0 -264
  1370. package/src/shared/completion-owner.ts +0 -14
  1371. package/src/shared/display-text.ts +0 -150
  1372. package/src/shared/extension-context.ts +0 -24
  1373. package/src/shared/file-coalescer.ts +0 -49
  1374. package/src/shared/file-system-retry.ts +0 -95
  1375. package/src/shared/fork-context.ts +0 -236
  1376. package/src/shared/fork-session-cwd.ts +0 -27
  1377. package/src/shared/formatters.ts +0 -146
  1378. package/src/shared/jsonl-writer.ts +0 -92
  1379. package/src/shared/launch-contract.ts +0 -198
  1380. package/src/shared/model-info.ts +0 -101
  1381. package/src/shared/model-response-aliases.ts +0 -13
  1382. package/src/shared/node-executable.ts +0 -21
  1383. package/src/shared/opencode-session-headers.ts +0 -30
  1384. package/src/shared/prompt-resources.ts +0 -11
  1385. package/src/shared/pruned-fork.ts +0 -450
  1386. package/src/shared/required-child-extensions.ts +0 -81
  1387. package/src/shared/session-file-trust.ts +0 -19
  1388. package/src/shared/session-identity.ts +0 -10
  1389. package/src/shared/session-tokens.ts +0 -55
  1390. package/src/shared/settings.ts +0 -412
  1391. package/src/shared/shortcuts.ts +0 -13
  1392. package/src/shared/status-format.ts +0 -55
  1393. package/src/shared/thinking-ceiling.ts +0 -46
  1394. package/src/shared/types.ts +0 -2983
  1395. package/src/shared/utf8.ts +0 -11
  1396. package/src/shared/utils.ts +0 -608
  1397. package/src/shared/watch-strategy.ts +0 -12
  1398. package/src/shared/workflow-child-permit.ts +0 -212
  1399. package/src/slash/delegation-adapters.ts +0 -428
  1400. package/src/slash/delegation-json.ts +0 -108
  1401. package/src/slash/delegation-request.ts +0 -176
  1402. package/src/slash/prompt-template-bridge.ts +0 -419
  1403. package/src/slash/prompt-workflows.ts +0 -287
  1404. package/src/slash/selector.ts +0 -147
  1405. package/src/slash/slash-bridge.ts +0 -192
  1406. package/src/slash/slash-commands.ts +0 -1325
  1407. package/src/slash/slash-live-state.ts +0 -310
  1408. package/src/slash/subagents-admin.ts +0 -460
  1409. package/src/tui/fleet-status.ts +0 -1109
  1410. package/src/tui/fleet-transcript.ts +0 -536
  1411. package/src/tui/fleet.ts +0 -1448
  1412. package/src/tui/render-helpers.ts +0 -111
  1413. package/src/tui/render.ts +0 -3721
  1414. package/src/types/pi-runtime-compat.d.ts +0 -8
  1415. package/src/watchdog/change-signature.ts +0 -260
  1416. package/src/watchdog/child-status.ts +0 -225
  1417. package/src/watchdog/diff-tool.ts +0 -77
  1418. package/src/watchdog/emission-guard.ts +0 -125
  1419. package/src/watchdog/guidance.ts +0 -20
  1420. package/src/watchdog/lsp-diagnostics.ts +0 -538
  1421. package/src/watchdog/model-selection.ts +0 -187
  1422. package/src/watchdog/permission-arbiter.ts +0 -156
  1423. package/src/watchdog/register-child.ts +0 -128
  1424. package/src/watchdog/register-main.ts +0 -445
  1425. package/src/watchdog/render.ts +0 -53
  1426. package/src/watchdog/review.ts +0 -363
  1427. package/src/watchdog/rules.ts +0 -70
  1428. package/src/watchdog/runtime.ts +0 -924
  1429. package/src/watchdog/scope.ts +0 -51
  1430. package/src/watchdog/settings.ts +0 -515
  1431. package/src/watchdog/tool-actions.ts +0 -156
  1432. package/src/watchdog/turn-delta.ts +0 -184
  1433. package/src/watchdog/types.ts +0 -186
  1434. package/src/watchdog/warning-format.ts +0 -72
  1435. package/src/workflows/chat-progress.ts +0 -152
  1436. package/src/workflows/host-command.ts +0 -235
  1437. package/src/workflows/scripted-workflow.ts +0 -2575
  1438. package/src/workflows/workflow-checklist.ts +0 -436
  1439. package/src/workflows/workflow-child-summary.ts +0 -170
  1440. package/src/workflows/workflow-preflight.ts +0 -297
  1441. package/src/workflows/workflow-receipt.ts +0 -384
  1442. package/src/workflows/workflow-resources.ts +0 -236
  1443. package/src/workflows/workflow-settlement.ts +0 -249
@@ -1,2917 +0,0 @@
1
- /**
2
- * Agent discovery and configuration
3
- */
4
-
5
- import { execSync } from "node:child_process";
6
- import * as fs from "node:fs";
7
- import { parse as parseYaml } from "yaml";
8
- import * as os from "node:os";
9
- import * as path from "node:path";
10
- import { fileURLToPath } from "node:url";
11
- import type { AcceptanceInput, AcceptanceRole, AgentRunnerConfig, JsonSchemaObject, OutputMode, ToolBudgetConfig } from "../shared/types.ts";
12
- import { CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL, isCodeOwnedExternalCliAdapterId, parseExternalCliCapabilityNarrowing, validateCodeOwnedProfileRunner } from "../runs/shared/external-cli-contract.ts";
13
- import { getAgentDir, getProjectConfigDir } from "../shared/utils.ts";
14
- import { expandHomePath } from "../shared/settings.ts";
15
- import { KNOWN_FIELDS } from "./agent-serializer.ts";
16
- import { parseChain, parseJsonChain } from "./chain-serializer.ts";
17
- import { mergeAgentsForScope } from "./agent-selection.ts";
18
- import { parseFrontmatter, parseFrontmatterList } from "./frontmatter.ts";
19
- import { buildRuntimeName, parsePackageName } from "./identity.ts";
20
- import { parseModelScopeConfig, type ModelScopeConfig } from "../runs/shared/model-scope.ts";
21
- export { BUILTIN_AGENT_NAMES } from "./builtin-names.ts";
22
- export { buildRuntimeName, frontmatterNameForConfig, parsePackageName } from "./identity.ts";
23
- import { parseMemoryFrontmatter } from "./agent-memory.ts";
24
- import { validateAcceptanceInput } from "../runs/shared/acceptance.ts";
25
- import { validatePermissionRules, type PermissionRules } from "../runs/shared/permissions.ts";
26
- import { parseThinkingLevel, type ThinkingLevel } from "../shared/thinking-ceiling.ts";
27
- import { assertJsonSchemaObject } from "../runs/shared/structured-output.ts";
28
-
29
- export type AgentScope = "user" | "project" | "both";
30
-
31
- export type AgentSource = "builtin" | "package" | "user" | "project" | "runtime";
32
- type SystemPromptMode = "append" | "replace";
33
- export type AgentDefaultContext = "fresh" | "fork";
34
-
35
- export type AgentMemoryScope = "project" | "user";
36
-
37
- export interface AgentMemoryConfig {
38
- scope: AgentMemoryScope;
39
- path: string;
40
- }
41
-
42
- export function defaultSystemPromptMode(name: string): SystemPromptMode {
43
- return name === "delegate" ? "append" : "replace";
44
- }
45
-
46
- export function defaultInheritProjectContext(name: string): boolean {
47
- return name === "delegate";
48
- }
49
-
50
- export function defaultInheritSkills(): boolean {
51
- return false;
52
- }
53
-
54
- export interface BuiltinAgentOverrideBase {
55
- description?: string;
56
- machine?: string;
57
- output?: string;
58
- outputMode?: OutputMode;
59
- defaultReads?: string[];
60
- model?: string;
61
- modelProvider?: string;
62
- fast?: boolean;
63
- thinking?: string | false;
64
- systemPromptMode: SystemPromptMode;
65
- inheritProjectContext: boolean;
66
- inheritGlobalContext: boolean;
67
- inheritSkills: boolean;
68
- defaultContext?: AgentDefaultContext;
69
- acceptanceRole?: AcceptanceRole;
70
- disabled?: boolean;
71
- systemPrompt: string;
72
- skills?: string[];
73
- skillPath?: string[];
74
- tools?: string[];
75
- excludeTools?: string[];
76
- allowNestedSubagents?: boolean;
77
- mcpDirectTools?: string[];
78
- extensions?: string[];
79
- subagentOnlyExtensions?: string[];
80
- mutationTools?: string[];
81
- completionGuard?: boolean;
82
- toolBudget?: ToolBudgetConfig;
83
- }
84
-
85
- interface BuiltinAgentOverrideConfig {
86
- description?: string;
87
- machine?: string | false;
88
- output?: string | false;
89
- outputMode?: OutputMode;
90
- defaultReads?: string[] | false;
91
- model?: string | false;
92
- defaultProvider?: string | false;
93
- fast?: boolean;
94
- thinking?: string | false;
95
- systemPromptMode?: SystemPromptMode;
96
- inheritProjectContext?: boolean;
97
- inheritGlobalContext?: boolean;
98
- inheritSkills?: boolean;
99
- defaultContext?: AgentDefaultContext | false;
100
- acceptanceRole?: AcceptanceRole | false;
101
- disabled?: boolean;
102
- systemPrompt?: string;
103
- skills?: string[] | false;
104
- tools?: string[] | false | "inherit";
105
- excludeTools?: string[] | false;
106
- allowNestedSubagents?: boolean;
107
- extensions?: string[] | false;
108
- subagentOnlyExtensions?: string[] | false;
109
- mutationTools?: string[] | false;
110
- completionGuard?: boolean;
111
- toolBudget?: ToolBudgetConfig | false;
112
- }
113
-
114
- interface BuiltinAgentOverrideInfo {
115
- scope: "user" | "project";
116
- path: string;
117
- base: BuiltinAgentOverrideBase;
118
- fields?: string[];
119
- fieldScopes?: Record<string, Array<"user" | "project">>;
120
- }
121
-
122
- export interface AgentModelSourceInfo {
123
- type: "subagents.defaultModel";
124
- scope: "user" | "project";
125
- path: string;
126
- model: string;
127
- defaultProvider?: string;
128
- }
129
-
130
- export interface AgentConfig {
131
- name: string;
132
- runner?: AgentRunnerConfig;
133
- localName?: string;
134
- packageName?: string;
135
- packageSourceName?: string;
136
- packageSourceVersion?: string;
137
- packageSourceRoot?: string;
138
- description: string;
139
- advertise?: boolean;
140
- aliases?: string[];
141
- tools?: string[];
142
- excludeTools?: string[];
143
- allowNestedSubagents?: boolean;
144
- mcpDirectTools?: string[];
145
- model?: string;
146
- modelProvider?: string;
147
- fast?: boolean;
148
- thinking?: string | false;
149
- systemPromptMode: SystemPromptMode;
150
- inheritProjectContext: boolean;
151
- inheritGlobalContext: boolean;
152
- inheritSkills: boolean;
153
- defaultContext?: AgentDefaultContext;
154
- defaultAsync?: boolean;
155
- defaultTimeoutMs?: number;
156
- defaultToolTimeoutMs?: number;
157
- defaultAcceptance?: AcceptanceInput;
158
- acceptanceRole?: AcceptanceRole;
159
- systemPrompt: string;
160
- source: AgentSource;
161
- filePath: string;
162
- discoveryPriority?: number;
163
- skills?: string[];
164
- skillPath?: string[];
165
- extensions?: string[];
166
- extensionsFromDefault?: boolean;
167
- subagentOnlyExtensions?: string[];
168
- mutationTools?: string[];
169
- output?: string;
170
- outputMode?: OutputMode;
171
- outputSchema?: JsonSchemaObject;
172
- defaultReads?: string[];
173
- defaultProgress?: boolean;
174
- interactive?: boolean;
175
- maxSubagentDepth?: number;
176
- completionGuard?: boolean;
177
- toolBudget?: ToolBudgetConfig;
178
- permissions?: PermissionRules;
179
- memory?: AgentMemoryConfig;
180
- machine?: string;
181
- disabled?: boolean;
182
- extraFields?: Record<string, string>;
183
- override?: BuiltinAgentOverrideInfo;
184
- modelSource?: AgentModelSourceInfo;
185
- maxThinking?: ThinkingLevel;
186
- /**
187
- * Digest of the parsed definition, set when a runtime overlay such as the
188
- * Intercom bridge rewrites launch-affecting fields. Launch identity reads
189
- * this instead of re-hashing the overlaid copy.
190
- */
191
- definitionDigest?: string;
192
- }
193
-
194
- type ProjectRootResolution = "nearest" | "git-root";
195
-
196
- interface SubagentSettings {
197
- overrides: Record<string, BuiltinAgentOverrideConfig>;
198
- providerOverrides: Record<string, Record<string, BuiltinAgentOverrideConfig>>;
199
- agentScanDirs?: string[];
200
- agentExcludeDirs?: string[];
201
- defaultModel?: string;
202
- defaultProvider?: string;
203
- defaultThinking?: string;
204
- maxThinking?: ThinkingLevel;
205
- defaultExtensions?: string[];
206
- disableBuiltins?: boolean;
207
- disableThinking?: boolean;
208
- modelScope?: ModelScopeConfig;
209
- }
210
-
211
- const EMPTY_SUBAGENT_SETTINGS: SubagentSettings = { overrides: {}, providerOverrides: {} };
212
- const agentFrontmatterFields = new WeakMap<AgentConfig, Set<string>>();
213
-
214
- export interface ChainStepConfig {
215
- agent?: string;
216
- task?: string;
217
- phase?: string;
218
- label?: string;
219
- as?: string;
220
- outputSchema?: string | Record<string, unknown>;
221
- machine?: string;
222
- output?: string | false;
223
- outputMode?: OutputMode;
224
- reads?: string[] | false;
225
- model?: string;
226
- skills?: string[] | false;
227
- progress?: boolean;
228
- parallel?: unknown;
229
- expand?: unknown;
230
- collect?: unknown;
231
- concurrency?: number;
232
- failFast?: boolean;
233
- worktree?: boolean;
234
- acceptance?: AcceptanceInput;
235
- toolBudget?: ToolBudgetConfig;
236
- }
237
-
238
- export interface ChainConfig {
239
- name: string;
240
- localName?: string;
241
- packageName?: string;
242
- description: string;
243
- source: AgentSource;
244
- filePath: string;
245
- steps: ChainStepConfig[];
246
- extraFields?: Record<string, string>;
247
- }
248
-
249
- export interface ChainDiscoveryDiagnostic {
250
- source: AgentSource;
251
- filePath: string;
252
- error: string;
253
- }
254
-
255
- export interface AgentDiscoveryDiagnostic extends ChainDiscoveryDiagnostic {
256
- name?: string;
257
- runtimeName?: string;
258
- packageSpecified?: boolean;
259
- discoveryPriority?: number;
260
- }
261
-
262
- const AGENT_SOURCE_PRIORITY: Record<AgentSource, number> = {
263
- builtin: 0,
264
- package: 1,
265
- user: 2,
266
- project: 3,
267
- runtime: 4,
268
- };
269
-
270
- function agentDefinitionPriority(definition: Pick<AgentConfig | AgentDiscoveryDiagnostic, "source" | "discoveryPriority">): number {
271
- return AGENT_SOURCE_PRIORITY[definition.source] * 1_000_000
272
- + (definition.discoveryPriority ?? 0);
273
- }
274
-
275
- export function findBlockingAgentDiagnostic(name: string, agent: AgentConfig | readonly AgentConfig[] | undefined, diagnostics: AgentDiscoveryDiagnostic[] | undefined): AgentDiscoveryDiagnostic | undefined {
276
- const normalizedName = name.trim();
277
- const agents = Array.isArray(agent) ? agent : agent ? [agent] : [];
278
- let match: AgentDiscoveryDiagnostic | undefined;
279
- for (const diagnostic of diagnostics ?? []) {
280
- if ((diagnostic.runtimeName === normalizedName
281
- || (diagnostic.name === normalizedName && (!diagnostic.packageSpecified
282
- || diagnostic.runtimeName === undefined
283
- || agents.some((agent) => agent.name === diagnostic.runtimeName && agent.localName === diagnostic.name))))
284
- && (!match || agentDefinitionPriority(diagnostic) > agentDefinitionPriority(match))) {
285
- match = diagnostic;
286
- }
287
- }
288
- const highestPriority = Math.max(...agents.map(agentDefinitionPriority), -Infinity);
289
- return !agents.length || (match && agentDefinitionPriority(match) > highestPriority) ? match : undefined;
290
- }
291
-
292
- export type AgentDefinitionDirectoryState = "absent" | "empty" | "candidates" | "unreadable" | "not-directory";
293
-
294
- /** A definition directory actually inspected during one agent-discovery operation. */
295
- export interface AgentDefinitionDirectoryReport {
296
- source: AgentSource;
297
- path: string;
298
- state: AgentDefinitionDirectoryState;
299
- candidateCount?: number;
300
- }
301
-
302
- /**
303
- * Filesystem provenance for a failed agent resolution. Context is created from
304
- * the discovery result that supplied the effective agents; callers must not
305
- * pair arbitrary agent arrays with these directory reports.
306
- */
307
- export interface UnknownAgentDiagnosticContext {
308
- cwd: string;
309
- scope: AgentScope;
310
- directories: readonly AgentDefinitionDirectoryReport[];
311
- agents: readonly AgentConfig[];
312
- }
313
-
314
- export interface AgentDiscoveryResult {
315
- agents: AgentConfig[];
316
- agentDiagnostics?: AgentDiscoveryDiagnostic[];
317
- projectAgentsDir: string | null;
318
- cwd: string;
319
- scope: AgentScope;
320
- directories: readonly AgentDefinitionDirectoryReport[];
321
- modelScope?: ModelScopeConfig;
322
- maxThinking?: ThinkingLevel;
323
- }
324
-
325
- /** Create formatter input from the exact discovery operation used for resolution. */
326
- export function unknownAgentDiagnosticContext(discovered: Pick<AgentDiscoveryResult, "cwd" | "scope" | "directories" | "agents">): UnknownAgentDiagnosticContext {
327
- return {
328
- cwd: discovered.cwd,
329
- scope: discovered.scope,
330
- directories: discovered.directories,
331
- agents: discovered.agents,
332
- };
333
- }
334
-
335
- /** Render local discovery evidence without exposing filesystem error details. */
336
- export function formatUnknownAgentError(name: string, context: UnknownAgentDiagnosticContext, prefix = "Unknown agent"): string {
337
- const directories = context.directories.map((directory) => {
338
- const state = directory.state === "candidates"
339
- ? `${directory.candidateCount ?? 0} candidate${directory.candidateCount === 1 ? "" : "s"}`
340
- : directory.state === "empty" ? "present but empty"
341
- : directory.state === "not-directory" ? "not a directory"
342
- : directory.state;
343
- return `- ${directory.source}: ${directory.path} (${state})`;
344
- });
345
- const agents = [...context.agents]
346
- .sort((left, right) => left.name.localeCompare(right.name) || left.source.localeCompare(right.source))
347
- .map((agent) => `- ${agent.name} (${agent.source})`);
348
- return [
349
- `${prefix}: ${name}`,
350
- `Effective cwd: ${path.resolve(context.cwd)}`,
351
- "Consulted agent-definition directories:",
352
- ...(directories.length ? directories : ["- (none)"]),
353
- "Discovered agents:",
354
- ...(agents.length ? agents : ["- (none)"]),
355
- ].join("\n");
356
- }
357
-
358
- function getUserChainDir(): string {
359
- return path.join(getAgentDir(), "chains");
360
- }
361
-
362
- type PackageScope = "root" | "user" | "project";
363
- type PackageSettingsScope = Exclude<PackageScope, "root">;
364
-
365
- interface PackageSubagentPath {
366
- dir: string;
367
- // A package can be reachable from more than one settings scope. Keep the
368
- // actual memberships instead of promoting a mixed-scope path to root.
369
- scope: Set<PackageScope>;
370
- packageName?: string;
371
- packageVersion?: string;
372
- packageRoot: string;
373
- }
374
-
375
- interface PackageChainPath {
376
- dir: string;
377
- scope: Set<PackageScope>;
378
- packageRoot: string;
379
- }
380
-
381
- interface PackageSubagentPaths {
382
- agents: PackageSubagentPath[];
383
- chains: PackageChainPath[];
384
- watchPaths: string[];
385
- settingsErrors: Partial<Record<PackageSettingsScope, Error>>;
386
- }
387
-
388
- let cachedGlobalNpmRoot: string | null = null;
389
-
390
- function readJsonFileBestEffort(filePath: string): unknown {
391
- try {
392
- return JSON.parse(fs.readFileSync(filePath, "utf-8"));
393
- } catch {
394
- // Installed package scans are opportunistic; bad third-party manifests
395
- // should not break local agent discovery.
396
- return null;
397
- }
398
- }
399
-
400
- function isSafePackagePath(value: string): boolean {
401
- return value.length > 0
402
- && !path.isAbsolute(value)
403
- && value.split(/[\\/]/).every((part) => part.length > 0 && part !== "." && part !== "..");
404
- }
405
-
406
- function parseNpmPackageName(source: string): string | undefined {
407
- const spec = source.slice(4).trim();
408
- if (!spec) return undefined;
409
- const match = spec.match(/^(@?[^@]+(?:\/[^@]+)?)(?:@(.+))?$/);
410
- const packageName = match?.[1] ?? spec;
411
- return isSafePackagePath(packageName) ? packageName : undefined;
412
- }
413
-
414
- function stripGitRef(repoPath: string): string {
415
- const atIndex = repoPath.indexOf("@");
416
- const hashIndex = repoPath.indexOf("#");
417
- const refIndex = [atIndex, hashIndex].filter((index) => index >= 0).sort((a, b) => a - b)[0];
418
- return refIndex === undefined ? repoPath : repoPath.slice(0, refIndex);
419
- }
420
-
421
- function parseGitPackagePath(source: string): { host: string; repoPath: string } | undefined {
422
- const spec = source.slice(4).trim();
423
- if (!spec) return undefined;
424
-
425
- let host = "";
426
- let repoPath = "";
427
- const scpLike = spec.match(/^git@([^:]+):(.+)$/);
428
- if (scpLike) {
429
- host = scpLike[1] ?? "";
430
- repoPath = scpLike[2] ?? "";
431
- } else if (/^[a-z][a-z0-9+.-]*:\/\//i.test(spec)) {
432
- try {
433
- const url = new URL(spec);
434
- host = url.hostname;
435
- repoPath = url.pathname.replace(/^\/+/, "");
436
- } catch {
437
- return undefined;
438
- }
439
- } else {
440
- const slashIndex = spec.indexOf("/");
441
- if (slashIndex < 0) return undefined;
442
- host = spec.slice(0, slashIndex);
443
- repoPath = spec.slice(slashIndex + 1);
444
- }
445
-
446
- const normalizedPath = stripGitRef(repoPath).replace(/\.git$/, "").replace(/^\/+/, "");
447
- if (!host || !isSafePackagePath(host) || !isSafePackagePath(normalizedPath) || normalizedPath.split(/[\\/]/).length < 2) {
448
- return undefined;
449
- }
450
- return { host, repoPath: normalizedPath };
451
- }
452
-
453
- function resolveSettingsPackageRoot(source: string, baseDir: string): string | undefined {
454
- const trimmed = source.trim();
455
- if (!trimmed) return undefined;
456
- if (trimmed.startsWith("git:")) {
457
- const parsed = parseGitPackagePath(trimmed);
458
- return parsed ? path.join(baseDir, "git", parsed.host, parsed.repoPath) : undefined;
459
- }
460
- if (trimmed.startsWith("npm:")) {
461
- const packageName = parseNpmPackageName(trimmed);
462
- return packageName ? path.join(baseDir, "npm", "node_modules", packageName) : undefined;
463
- }
464
- const normalized = trimmed.startsWith("file:") ? trimmed.slice(5) : trimmed;
465
- if (normalized === "~") return os.homedir();
466
- if (normalized.startsWith("~/")) return path.join(os.homedir(), normalized.slice(2));
467
- if (path.isAbsolute(normalized)) return normalized;
468
- if (normalized === "." || normalized === ".." || normalized.startsWith("./") || normalized.startsWith("../")) {
469
- return path.resolve(baseDir, normalized);
470
- }
471
- if (/^https?:\/\//i.test(trimmed)) {
472
- const parsed = parseGitPackagePath(`git:${trimmed}`);
473
- return parsed ? path.join(baseDir, "git", parsed.host, parsed.repoPath) : undefined;
474
- }
475
- return undefined;
476
- }
477
-
478
- function getGlobalNpmRoot(): string | null {
479
- const offline = process.env.PI_OFFLINE?.toLowerCase();
480
- if (offline === "1" || offline === "true" || offline === "yes") return null;
481
- if (cachedGlobalNpmRoot !== null) return cachedGlobalNpmRoot;
482
-
483
- const windowsGlobalRoot = process.platform === "win32" && process.env.APPDATA
484
- ? path.join(process.env.APPDATA, "npm", "node_modules")
485
- : undefined;
486
- if (windowsGlobalRoot) {
487
- try {
488
- if (fs.statSync(windowsGlobalRoot).isDirectory()) {
489
- cachedGlobalNpmRoot = fs.realpathSync(windowsGlobalRoot);
490
- return cachedGlobalNpmRoot;
491
- }
492
- } catch {
493
- // Fall through if the directory disappears while resolving it.
494
- }
495
- }
496
-
497
- try {
498
- cachedGlobalNpmRoot = fs.realpathSync(execSync("npm root -g", { encoding: "utf-8", timeout: 5000, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }).trim());
499
- return cachedGlobalNpmRoot;
500
- } catch {
501
- cachedGlobalNpmRoot = "";
502
- return null;
503
- }
504
- }
505
-
506
- function stringArray(value: unknown): string[] {
507
- if (!Array.isArray(value)) return [];
508
- return value.filter((entry): entry is string => typeof entry === "string" && entry.trim().length > 0);
509
- }
510
-
511
- function packageMetadata(pkg: Record<string, unknown>, packageRoot: string): Omit<PackageSubagentPath, "dir" | "scope"> {
512
- const name = typeof pkg.name === "string" && pkg.name.trim() ? pkg.name.trim() : undefined;
513
- const version = typeof pkg.version === "string" && pkg.version.trim() ? pkg.version.trim() : undefined;
514
- return {
515
- packageRoot,
516
- ...(name ? { packageName: name } : {}),
517
- ...(version ? { packageVersion: version } : {}),
518
- };
519
- }
520
-
521
- function extractSubagentPathsFromPackageRoot(packageRoot: string, scope: Set<PackageScope>): PackageSubagentPaths {
522
- const packageJsonPath = path.join(packageRoot, "package.json");
523
- const pkg = readJsonFileBestEffort(packageJsonPath);
524
- if (!pkg || typeof pkg !== "object" || Array.isArray(pkg)) return { agents: [], chains: [], watchPaths: [packageJsonPath], settingsErrors: {} };
525
- const pkgRecord = pkg as Record<string, unknown>;
526
- const metadata = packageMetadata(pkgRecord, packageRoot);
527
-
528
- const roots: Record<string, unknown>[] = [];
529
- const piSubagents = pkgRecord["pi-subagents"];
530
- if (piSubagents && typeof piSubagents === "object" && !Array.isArray(piSubagents)) {
531
- roots.push(piSubagents as Record<string, unknown>);
532
- }
533
-
534
- const pi = pkgRecord.pi;
535
- if (pi && typeof pi === "object" && !Array.isArray(pi)) {
536
- const subagents = (pi as { subagents?: unknown }).subagents;
537
- if (subagents && typeof subagents === "object" && !Array.isArray(subagents)) {
538
- roots.push(subagents as Record<string, unknown>);
539
- }
540
- }
541
-
542
- const agents: PackageSubagentPath[] = [];
543
- const chains: PackageChainPath[] = [];
544
- for (const root of roots) {
545
- for (const entry of stringArray(root.agents)) agents.push({ dir: path.resolve(packageRoot, entry), scope, ...metadata });
546
- for (const entry of stringArray(root.chains)) chains.push({ dir: path.resolve(packageRoot, entry), scope, packageRoot });
547
- }
548
- return { agents, chains, watchPaths: [packageJsonPath], settingsErrors: {} };
549
- }
550
-
551
- function collectPackageRootsFromNodeModules(nodeModulesDir: string, watchPaths?: string[]): string[] {
552
- const roots: string[] = [];
553
- watchPaths?.push(nodeModulesDir);
554
- if (!fs.existsSync(nodeModulesDir)) return roots;
555
-
556
- let entries: fs.Dirent[];
557
- try {
558
- entries = fs.readdirSync(nodeModulesDir, { withFileTypes: true });
559
- } catch {
560
- return roots;
561
- }
562
-
563
- for (const entry of entries) {
564
- if (entry.name.startsWith(".")) continue;
565
- if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
566
-
567
- if (entry.name.startsWith("@")) {
568
- const scopeDir = path.join(nodeModulesDir, entry.name);
569
- watchPaths?.push(scopeDir);
570
- let scopeEntries: fs.Dirent[];
571
- try {
572
- scopeEntries = fs.readdirSync(scopeDir, { withFileTypes: true });
573
- } catch {
574
- continue;
575
- }
576
- for (const scopeEntry of scopeEntries) {
577
- if (scopeEntry.name.startsWith(".")) continue;
578
- if (!scopeEntry.isDirectory() && !scopeEntry.isSymbolicLink()) continue;
579
- roots.push(path.join(scopeDir, scopeEntry.name));
580
- }
581
- continue;
582
- }
583
-
584
- roots.push(path.join(nodeModulesDir, entry.name));
585
- }
586
- return roots;
587
- }
588
-
589
- function collectSettingsPackageRoots(settingsFile: string, baseDir: string): string[] {
590
- const settings = readSettingsFileStrict(settingsFile);
591
- const packages = (settings as { packages?: unknown }).packages;
592
- if (!Array.isArray(packages)) return [];
593
-
594
- const roots: string[] = [];
595
- for (const entry of packages) {
596
- const packageSource = typeof entry === "string"
597
- ? entry
598
- : typeof entry === "object" && entry !== null && "source" in entry && typeof entry.source === "string"
599
- ? entry.source
600
- : undefined;
601
- if (!packageSource) continue;
602
- const packageRoot = resolveSettingsPackageRoot(packageSource, baseDir);
603
- if (packageRoot) roots.push(packageRoot);
604
- }
605
- return roots;
606
- }
607
-
608
- function collectPackageSubagentPaths(cwd: string, options: { includeUser: boolean; includeProject: boolean } = { includeUser: true, includeProject: true }): PackageSubagentPaths {
609
- const agentDir = getAgentDir();
610
- const projectRoot = findConfiguredProjectRoot(cwd) ?? cwd;
611
- const packageRoots: Array<{ root: string; scope: PackageScope }> = [
612
- { root: projectRoot, scope: "root" },
613
- ];
614
- const watchPaths: string[] = [path.join(projectRoot, "package.json")];
615
- const settingsErrors: Partial<Record<PackageSettingsScope, Error>> = {};
616
- const collectScopedSettingsRoots = (scope: PackageSettingsScope, settingsFile: string, baseDir: string): string[] => {
617
- try {
618
- return collectSettingsPackageRoots(settingsFile, baseDir);
619
- } catch (error) {
620
- // The raw source snapshot includes both settings scopes. Defer a
621
- // strict failure until a projection actually selects this scope so an
622
- // unrelated malformed settings file stays out of scoped discovery.
623
- settingsErrors[scope] = error instanceof Error
624
- ? error
625
- : new Error(`Failed to read settings file '${settingsFile}': ${String(error)}`, { cause: error });
626
- return [];
627
- }
628
- };
629
- if (options.includeProject) {
630
- const projectConfigDir = getProjectConfigDir(projectRoot);
631
- const nodeModulesDir = path.join(projectConfigDir, "npm", "node_modules");
632
- packageRoots.push(...collectPackageRootsFromNodeModules(nodeModulesDir, watchPaths).map((root) => ({ root, scope: "project" as const })));
633
- packageRoots.push(...collectScopedSettingsRoots("project", path.join(projectConfigDir, "settings.json"), projectConfigDir).map((root) => ({ root, scope: "project" as const })));
634
- }
635
-
636
- if (options.includeUser) {
637
- const nodeModulesDir = path.join(agentDir, "npm", "node_modules");
638
- packageRoots.push(...collectPackageRootsFromNodeModules(nodeModulesDir, watchPaths).map((root) => ({ root, scope: "user" as const })));
639
- packageRoots.push(...collectScopedSettingsRoots("user", path.join(agentDir, "settings.json"), agentDir).map((root) => ({ root, scope: "user" as const })));
640
- }
641
-
642
- if (options.includeUser) {
643
- const globalRoot = getGlobalNpmRoot();
644
- if (globalRoot) {
645
- packageRoots.push(...collectPackageRootsFromNodeModules(globalRoot, watchPaths).map((root) => ({ root, scope: "user" as const })));
646
- }
647
- }
648
-
649
- const seenRoots = new Map<string, Set<PackageScope>>();
650
- const seenAgents = new Map<string, PackageSubagentPath>();
651
- const seenChains = new Map<string, PackageChainPath>();
652
- const agents: PackageSubagentPath[] = [];
653
- const chains: PackageChainPath[] = [];
654
- for (const { root: packageRoot, scope } of packageRoots) {
655
- const resolvedRoot = path.resolve(packageRoot);
656
- const scopes = seenRoots.get(resolvedRoot);
657
- if (scopes !== undefined) {
658
- scopes.add(scope);
659
- continue;
660
- }
661
- const packageScopes = new Set<PackageScope>([scope]);
662
- seenRoots.set(resolvedRoot, packageScopes);
663
- const paths = extractSubagentPathsFromPackageRoot(resolvedRoot, packageScopes);
664
- watchPaths.push(...paths.watchPaths);
665
- for (const agentPath of paths.agents) {
666
- const agentKey = `${agentPath.dir}\u0000${agentPath.packageRoot}`;
667
- const existing = seenAgents.get(agentKey);
668
- if (existing) {
669
- for (const packageScope of agentPath.scope) existing.scope.add(packageScope);
670
- continue;
671
- }
672
- seenAgents.set(agentKey, agentPath);
673
- agents.push(agentPath);
674
- }
675
- for (const chainDir of paths.chains) {
676
- const chainKey = `${chainDir.dir}\u0000${chainDir.packageRoot}`;
677
- const existing = seenChains.get(chainKey);
678
- if (existing) {
679
- for (const packageScope of chainDir.scope) existing.scope.add(packageScope);
680
- continue;
681
- }
682
- seenChains.set(chainKey, chainDir);
683
- chains.push(chainDir);
684
- }
685
- }
686
- return { agents, chains, watchPaths, settingsErrors };
687
- }
688
-
689
- function normalizeAgentAliases(rawAliases: string[] | undefined, agentName: string): string[] | undefined {
690
- const aliases = [...new Set((rawAliases ?? []).map((alias) => alias.trim()).filter(Boolean))]
691
- .filter((alias) => alias !== agentName);
692
- return aliases.length > 0 ? aliases : undefined;
693
- }
694
-
695
- function effectiveAgentMatch(matches: AgentConfig[]): { agent?: AgentConfig; error?: string } {
696
- const distinctNames = [...new Set(matches.map((agent) => agent.name))];
697
- if (distinctNames.length === 1) {
698
- const sourceRank = new Map<AgentConfig["source"], number>([["builtin", 0], ["package", 1], ["user", 2], ["project", 3], ["runtime", 4]]);
699
- const agent = [...matches].sort((a, b) => (sourceRank.get(b.source) ?? 0) - (sourceRank.get(a.source) ?? 0))[0];
700
- return agent ? { agent } : {};
701
- }
702
- return {};
703
- }
704
-
705
- export function resolveAgentName(name: string, agents: AgentConfig[]): { agent?: AgentConfig; error?: string } {
706
- const raw = name.trim();
707
- const canonical = agents.filter((agent) => agent.name === raw);
708
- if (canonical.length === 1) return canonical[0] ? { agent: canonical[0] } : {};
709
- if (canonical.length > 1) {
710
- const effective = effectiveAgentMatch(canonical);
711
- if (effective.agent) return effective;
712
- return { error: `Ambiguous agent name '${name}': ${canonical.map((agent) => agent.name).join(", ")}` };
713
- }
714
-
715
- const local = agents.filter((agent) => agent.localName === raw);
716
- if (local.length === 1) return local[0] ? { agent: local[0] } : {};
717
- if (local.length > 1) {
718
- const effective = effectiveAgentMatch(local);
719
- if (effective.agent) return effective;
720
- return { error: `Ambiguous local agent name '${name}': ${local.map((agent) => agent.name).join(", ")}` };
721
- }
722
-
723
- const aliases = agents.filter((agent) => agent.aliases?.includes(raw));
724
- if (aliases.length === 1) return aliases[0] ? { agent: aliases[0] } : {};
725
- if (aliases.length > 1) {
726
- const effective = effectiveAgentMatch(aliases);
727
- if (effective.agent) return effective;
728
- return { error: `Ambiguous agent alias '${name}': ${aliases.map((agent) => agent.name).join(", ")}` };
729
- }
730
- return {};
731
- }
732
-
733
- function splitToolList(rawTools: string[] | undefined): { tools?: string[]; mcpDirectTools?: string[] } {
734
- const mcpDirectTools: string[] = [];
735
- const tools: string[] = [];
736
- for (const tool of rawTools ?? []) {
737
- if (tool.startsWith("mcp:")) {
738
- mcpDirectTools.push(tool.slice(4));
739
- } else {
740
- tools.push(tool);
741
- }
742
- }
743
- return {
744
- ...(rawTools !== undefined ? { tools } : {}),
745
- ...(mcpDirectTools.length > 0 ? { mcpDirectTools } : {}),
746
- };
747
- }
748
-
749
- function joinToolList(config: Pick<AgentConfig, "tools" | "mcpDirectTools">): string[] | undefined {
750
- const joined = [
751
- ...(config.tools ?? []),
752
- ...(config.mcpDirectTools ?? []).map((tool) => `mcp:${tool}`),
753
- ];
754
- return joined.length > 0 ? joined : undefined;
755
- }
756
-
757
- function arraysEqual(a: string[] | undefined, b: string[] | undefined): boolean {
758
- if (!a && !b) return true;
759
- if (!a || !b) return false;
760
- if (a.length !== b.length) return false;
761
- for (let i = 0; i < a.length; i++) {
762
- if (a[i] !== b[i]) return false;
763
- }
764
- return true;
765
- }
766
-
767
- function cloneOverrideBase(agent: AgentConfig): BuiltinAgentOverrideBase {
768
- return {
769
- description: agent.description,
770
- ...(agent.machine !== undefined ? { machine: agent.machine } : {}),
771
- ...(agent.output !== undefined ? { output: agent.output } : {}),
772
- ...(agent.outputMode !== undefined ? { outputMode: agent.outputMode } : {}),
773
- ...(agent.defaultReads !== undefined ? { defaultReads: [...agent.defaultReads] } : {}),
774
- ...(agent.model !== undefined ? { model: agent.model } : {}),
775
- ...(agent.modelProvider !== undefined ? { modelProvider: agent.modelProvider } : {}),
776
- ...(agent.fast !== undefined ? { fast: agent.fast } : {}),
777
- ...(agent.thinking !== undefined ? { thinking: agent.thinking } : {}),
778
- systemPromptMode: agent.systemPromptMode,
779
- inheritProjectContext: agent.inheritProjectContext,
780
- inheritGlobalContext: agent.inheritGlobalContext,
781
- inheritSkills: agent.inheritSkills,
782
- ...(agent.defaultContext !== undefined ? { defaultContext: agent.defaultContext } : {}),
783
- ...(agent.acceptanceRole !== undefined ? { acceptanceRole: agent.acceptanceRole } : {}),
784
- ...(agent.disabled !== undefined ? { disabled: agent.disabled } : {}),
785
- systemPrompt: agent.systemPrompt,
786
- ...(agent.skills ? { skills: [...agent.skills] } : {}),
787
- ...(agent.skillPath ? { skillPath: [...agent.skillPath] } : {}),
788
- ...(agent.tools ? { tools: [...agent.tools] } : {}),
789
- ...(agent.excludeTools ? { excludeTools: [...agent.excludeTools] } : {}),
790
- ...(agent.allowNestedSubagents !== undefined ? { allowNestedSubagents: agent.allowNestedSubagents } : {}),
791
- ...(agent.mcpDirectTools ? { mcpDirectTools: [...agent.mcpDirectTools] } : {}),
792
- ...(!agent.extensionsFromDefault && agent.extensions ? { extensions: [...agent.extensions] } : {}),
793
- ...(agent.subagentOnlyExtensions ? { subagentOnlyExtensions: [...agent.subagentOnlyExtensions] } : {}),
794
- ...(agent.mutationTools ? { mutationTools: [...agent.mutationTools] } : {}),
795
- ...(agent.completionGuard !== undefined ? { completionGuard: agent.completionGuard } : {}),
796
- ...(agent.toolBudget !== undefined ? { toolBudget: agent.toolBudget } : {}),
797
- };
798
- }
799
-
800
- function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentOverrideConfig {
801
- return {
802
- ...(override.description !== undefined ? { description: override.description } : {}),
803
- ...(override.machine !== undefined ? { machine: override.machine } : {}),
804
- ...(override.output !== undefined ? { output: override.output } : {}),
805
- ...(override.outputMode !== undefined ? { outputMode: override.outputMode } : {}),
806
- ...(override.defaultReads !== undefined ? { defaultReads: override.defaultReads === false ? false : [...override.defaultReads] } : {}),
807
- ...(override.model !== undefined ? { model: override.model } : {}),
808
- ...(override.defaultProvider !== undefined ? { defaultProvider: override.defaultProvider } : {}),
809
- ...(override.fast !== undefined ? { fast: override.fast } : {}),
810
- ...(override.thinking !== undefined ? { thinking: override.thinking } : {}),
811
- ...(override.systemPromptMode !== undefined ? { systemPromptMode: override.systemPromptMode } : {}),
812
- ...(override.inheritProjectContext !== undefined ? { inheritProjectContext: override.inheritProjectContext } : {}),
813
- ...(override.inheritGlobalContext !== undefined ? { inheritGlobalContext: override.inheritGlobalContext } : {}),
814
- ...(override.inheritSkills !== undefined ? { inheritSkills: override.inheritSkills } : {}),
815
- ...(override.defaultContext !== undefined ? { defaultContext: override.defaultContext } : {}),
816
- ...(override.acceptanceRole !== undefined ? { acceptanceRole: override.acceptanceRole } : {}),
817
- ...(override.disabled !== undefined ? { disabled: override.disabled } : {}),
818
- ...(override.systemPrompt !== undefined ? { systemPrompt: override.systemPrompt } : {}),
819
- ...(override.skills !== undefined ? { skills: override.skills === false ? false : [...override.skills] } : {}),
820
- ...(override.tools !== undefined ? { tools: Array.isArray(override.tools) ? [...override.tools] : override.tools } : {}),
821
- ...(override.excludeTools !== undefined ? { excludeTools: override.excludeTools === false ? false : [...override.excludeTools] } : {}),
822
- ...(override.allowNestedSubagents !== undefined ? { allowNestedSubagents: override.allowNestedSubagents } : {}),
823
- ...(override.extensions !== undefined ? { extensions: override.extensions === false ? false : [...override.extensions] } : {}),
824
- ...(override.subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions: override.subagentOnlyExtensions === false ? false : [...override.subagentOnlyExtensions] } : {}),
825
- ...(override.mutationTools !== undefined ? { mutationTools: override.mutationTools === false ? false : [...override.mutationTools] } : {}),
826
- ...(override.completionGuard !== undefined ? { completionGuard: override.completionGuard } : {}),
827
- ...(override.toolBudget !== undefined ? { toolBudget: override.toolBudget === false ? false : { ...override.toolBudget, ...(Array.isArray(override.toolBudget.block) ? { block: [...override.toolBudget.block] } : {}) } } : {}),
828
- };
829
- }
830
-
831
- function isProjectRootCandidate(dir: string): boolean {
832
- return isDirectory(getProjectConfigDir(dir)) || isDirectory(path.join(dir, ".agents"));
833
- }
834
-
835
- function findProjectRootCandidates(cwd: string): string[] {
836
- const roots: string[] = [];
837
- const windowsProfile = process.env.HOMEDRIVE && process.env.HOMEPATH
838
- ? `${process.env.HOMEDRIVE}${process.env.HOMEPATH}`
839
- : undefined;
840
- const homeDirs = new Set([os.homedir(), process.env.HOME, process.env.USERPROFILE, windowsProfile]
841
- .filter((value): value is string => Boolean(value?.trim()))
842
- .filter(isDirectory)
843
- .map((value) => fs.realpathSync.native(value)));
844
- let currentDir = cwd;
845
- while (true) {
846
- // ~/.pi and ~/.agents are user configuration, never an implicit project.
847
- if (isDirectory(currentDir) && homeDirs.has(fs.realpathSync.native(currentDir))) return roots;
848
- if (isProjectRootCandidate(currentDir)) roots.push(currentDir);
849
-
850
- const parentDir = path.dirname(currentDir);
851
- if (parentDir === currentDir) return roots;
852
- currentDir = parentDir;
853
- }
854
- }
855
-
856
- function findNearestGitRoot(cwd: string): string | null {
857
- let currentDir = cwd;
858
- while (true) {
859
- if (fs.existsSync(path.join(currentDir, ".git"))) return currentDir;
860
-
861
- const parentDir = path.dirname(currentDir);
862
- if (parentDir === currentDir) return null;
863
- currentDir = parentDir;
864
- }
865
- }
866
-
867
- function readProjectRootResolution(projectRoot: string): ProjectRootResolution | undefined {
868
- const settingsPath = path.join(getProjectConfigDir(projectRoot), "settings.json");
869
- if (!fs.existsSync(settingsPath)) return undefined;
870
- const settings = readSettingsFileStrict(settingsPath);
871
- const subagents = settings.subagents;
872
- if (!subagents || typeof subagents !== "object" || Array.isArray(subagents)) return undefined;
873
-
874
- const value = (subagents as Record<string, unknown>).projectRootResolution;
875
- if (value === undefined) return undefined;
876
- if (value === "nearest" || value === "git-root") return value;
877
- throw new Error(`Subagent settings in '${settingsPath}' have invalid 'projectRootResolution'; expected 'nearest' or 'git-root'.`);
878
- }
879
-
880
- export function findNearestProjectRoot(cwd: string): string | null {
881
- return findProjectRootCandidates(cwd)[0] ?? null;
882
- }
883
-
884
- export function findConfiguredProjectRoot(cwd: string): string | null {
885
- const candidates = findProjectRootCandidates(cwd);
886
- const nearestRoot = candidates[0];
887
- if (!nearestRoot) return null;
888
-
889
- let policyRoot: string | undefined;
890
- let policyRootIndex = -1;
891
- for (const [index, candidate] of candidates.entries()) {
892
- const mode = readProjectRootResolution(candidate);
893
- if (mode === "nearest") return nearestRoot;
894
- if (mode === "git-root") {
895
- policyRoot = candidate;
896
- policyRootIndex = index;
897
- break;
898
- }
899
- }
900
- if (!policyRoot) return nearestRoot;
901
-
902
- const gitRoot = findNearestGitRoot(cwd);
903
- const gitProjectRoot = gitRoot
904
- ? candidates.slice(policyRootIndex).find((candidate) => path.resolve(candidate) === path.resolve(gitRoot))
905
- : undefined;
906
- const configuredGitRoot = fs.existsSync(path.join(policyRoot, ".git")) ? policyRoot : undefined;
907
- return gitProjectRoot ?? configuredGitRoot ?? nearestRoot;
908
- }
909
-
910
- function getUserAgentSettingsPath(): string {
911
- return path.join(getAgentDir(), "settings.json");
912
- }
913
-
914
- function getProjectAgentSettingsPath(cwd: string): string | null {
915
- const projectRoot = findConfiguredProjectRoot(cwd);
916
- return projectRoot ? path.join(getProjectConfigDir(projectRoot), "settings.json") : null;
917
- }
918
-
919
- function readSettingsFileStrict(filePath: string): Record<string, unknown> {
920
- if (!fs.existsSync(filePath)) return {};
921
- let raw: string;
922
- try {
923
- raw = fs.readFileSync(filePath, "utf-8");
924
- } catch (error) {
925
- const message = error instanceof Error ? error.message : String(error);
926
- throw new Error(`Failed to read settings file '${filePath}': ${message}`, { cause: error });
927
- }
928
-
929
- let parsed: unknown;
930
- try {
931
- parsed = JSON.parse(raw);
932
- } catch (error) {
933
- const message = error instanceof Error ? error.message : String(error);
934
- throw new Error(`Failed to parse settings file '${filePath}': ${message}`, { cause: error });
935
- }
936
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
937
- throw new Error(`Settings file '${filePath}' must contain a JSON object.`);
938
- }
939
- return parsed as Record<string, unknown>;
940
- }
941
-
942
- function writeSettingsFile(filePath: string, settings: Record<string, unknown>): void {
943
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
944
- fs.writeFileSync(filePath, JSON.stringify(settings, null, 2) + "\n", "utf-8");
945
- }
946
-
947
- function parseOverrideStringArrayOrFalse(
948
- value: unknown,
949
- meta: { filePath: string; name: string; field: string },
950
- ): string[] | false | undefined {
951
- if (value === undefined) return undefined;
952
- if (value === false) return false;
953
- if (!Array.isArray(value)) {
954
- throw new Error(`Builtin override '${meta.name}' in '${meta.filePath}' has invalid '${meta.field}'; expected an array of strings or false.`);
955
- }
956
-
957
- const items: string[] = [];
958
- for (const item of value) {
959
- if (typeof item !== "string") {
960
- throw new Error(`Builtin override '${meta.name}' in '${meta.filePath}' has invalid '${meta.field}'; expected an array of strings or false.`);
961
- }
962
- const trimmed = item.trim();
963
- if (trimmed) items.push(trimmed);
964
- }
965
- return items;
966
- }
967
-
968
- function parseToolsOverride(
969
- value: unknown,
970
- meta: { filePath: string; name: string },
971
- ): BuiltinAgentOverrideConfig["tools"] | undefined {
972
- if (typeof value === "string" && value.trim() === "inherit") return "inherit";
973
- if (value === undefined || value === false || Array.isArray(value)) {
974
- return parseOverrideStringArrayOrFalse(value, { ...meta, field: "tools" });
975
- }
976
- throw new Error(`Builtin override '${meta.name}' in '${meta.filePath}' has invalid 'tools'; expected an array of strings, "inherit", or false.`);
977
- }
978
-
979
- function validateOptionalMachine(value: unknown, label: string): string | undefined {
980
- if (value === undefined || value === false) return undefined;
981
- if (typeof value !== "string" || !value.trim()) throw new Error(label + " must be a non-empty string or false.");
982
- const machine = value.trim();
983
- if (machine.length > 128) throw new Error(label + " must be 128 characters or fewer.");
984
- if (/[\u0000-\u001f\u007f]/u.test(machine)) throw new Error(label + " contains control characters.");
985
- return machine;
986
- }
987
-
988
- function parseBuiltinOverrideEntry(
989
- name: string,
990
- value: unknown,
991
- filePath: string,
992
- ): BuiltinAgentOverrideConfig | undefined {
993
- if (!value || typeof value !== "object" || Array.isArray(value)) {
994
- throw new Error(`Builtin override '${name}' in '${filePath}' must be an object.`);
995
- }
996
-
997
- const input = value as Record<string, unknown>;
998
- if (Object.hasOwn(input, "fallbackModels")) {
999
- throw new Error(`Builtin override '${name}' in '${filePath}' uses removed field 'fallbackModels'; configure one model instead.`);
1000
- }
1001
- const override: BuiltinAgentOverrideConfig = {};
1002
-
1003
- if ("description" in input) {
1004
- if (typeof input.description === "string" && input.description.trim()) {
1005
- override.description = input.description.trim();
1006
- } else {
1007
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'description'; expected a non-empty string.`);
1008
- }
1009
- }
1010
-
1011
- if ("output" in input) {
1012
- if ((typeof input.output === "string" && input.output.trim()) || input.output === false) override.output = input.output;
1013
- else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'output'; expected a non-empty string or false.`);
1014
- }
1015
-
1016
- if ("outputMode" in input) {
1017
- if (input.outputMode === "inline" || input.outputMode === "file-only") {
1018
- override.outputMode = input.outputMode;
1019
- } else {
1020
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'outputMode'; expected 'inline' or 'file-only'.`);
1021
- }
1022
- }
1023
-
1024
- if ("model" in input) {
1025
- if (typeof input.model === "string" || input.model === false) override.model = input.model;
1026
- else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'model'; expected a string or false.`);
1027
- }
1028
-
1029
- if ("fast" in input) {
1030
- if (typeof input.fast === "boolean") override.fast = input.fast;
1031
- else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'fast'; expected a boolean.`);
1032
- }
1033
-
1034
- if ("thinking" in input) {
1035
- if (typeof input.thinking === "string" || input.thinking === false) override.thinking = input.thinking;
1036
- else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'thinking'; expected a string or false.`);
1037
- }
1038
-
1039
- if ("systemPromptMode" in input) {
1040
- if (input.systemPromptMode === "append" || input.systemPromptMode === "replace") {
1041
- override.systemPromptMode = input.systemPromptMode;
1042
- } else {
1043
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'systemPromptMode'; expected 'append' or 'replace'.`);
1044
- }
1045
- }
1046
-
1047
- if ("inheritProjectContext" in input) {
1048
- if (typeof input.inheritProjectContext === "boolean") {
1049
- override.inheritProjectContext = input.inheritProjectContext;
1050
- } else {
1051
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'inheritProjectContext'; expected a boolean.`);
1052
- }
1053
- }
1054
-
1055
- if ("inheritGlobalContext" in input) {
1056
- if (typeof input.inheritGlobalContext === "boolean") {
1057
- override.inheritGlobalContext = input.inheritGlobalContext;
1058
- } else {
1059
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'inheritGlobalContext'; expected a boolean.`);
1060
- }
1061
- }
1062
-
1063
- if ("inheritSkills" in input) {
1064
- if (typeof input.inheritSkills === "boolean") {
1065
- override.inheritSkills = input.inheritSkills;
1066
- } else {
1067
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'inheritSkills'; expected a boolean.`);
1068
- }
1069
- }
1070
-
1071
- if ("defaultContext" in input) {
1072
- if (input.defaultContext === "fresh" || input.defaultContext === "fork" || input.defaultContext === false) {
1073
- override.defaultContext = input.defaultContext;
1074
- } else {
1075
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'defaultContext'; expected 'fresh', 'fork', or false.`);
1076
- }
1077
- }
1078
-
1079
- if ("acceptanceRole" in input) {
1080
- if (input.acceptanceRole === "read-only" || input.acceptanceRole === "writer" || input.acceptanceRole === false) {
1081
- override.acceptanceRole = input.acceptanceRole;
1082
- } else {
1083
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'acceptanceRole'; expected 'read-only', 'writer', or false.`);
1084
- }
1085
- }
1086
-
1087
- if ("disabled" in input) {
1088
- if (typeof input.disabled === "boolean") {
1089
- override.disabled = input.disabled;
1090
- } else {
1091
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'disabled'; expected a boolean.`);
1092
- }
1093
- }
1094
-
1095
- if ("completionGuard" in input) {
1096
- if (typeof input.completionGuard === "boolean") {
1097
- override.completionGuard = input.completionGuard;
1098
- } else {
1099
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'completionGuard'; expected a boolean.`);
1100
- }
1101
- }
1102
-
1103
- if ("toolBudget" in input) {
1104
- if (input.toolBudget === false) {
1105
- override.toolBudget = false;
1106
- } else if (input.toolBudget && typeof input.toolBudget === "object" && !Array.isArray(input.toolBudget)) {
1107
- override.toolBudget = input.toolBudget as ToolBudgetConfig;
1108
- } else {
1109
- throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'toolBudget'; expected an object or false.`);
1110
- }
1111
- }
1112
-
1113
- if ("systemPrompt" in input) {
1114
- if (typeof input.systemPrompt === "string") override.systemPrompt = input.systemPrompt;
1115
- else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'systemPrompt'; expected a string.`);
1116
- }
1117
-
1118
- if (input.machine === false) override.machine = false;
1119
- else {
1120
- const machine = validateOptionalMachine(input.machine, `Builtin override '${name}' in '${filePath}' field 'machine'`);
1121
- if (machine !== undefined) override.machine = machine;
1122
- }
1123
-
1124
- const defaultReads = parseOverrideStringArrayOrFalse(input.defaultReads, { filePath, name, field: "defaultReads" });
1125
- if (defaultReads !== undefined) override.defaultReads = defaultReads;
1126
-
1127
-
1128
- if ("defaultProvider" in input) {
1129
- if (input.defaultProvider === false) override.defaultProvider = false;
1130
- else if (typeof input.defaultProvider === "string" && input.defaultProvider.trim()) override.defaultProvider = input.defaultProvider.trim();
1131
- else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'defaultProvider'; expected a non-empty string or false.`);
1132
- }
1133
-
1134
- const skills = parseOverrideStringArrayOrFalse(input.skills, { filePath, name, field: "skills" });
1135
- if (skills !== undefined) override.skills = skills;
1136
-
1137
- const tools = parseToolsOverride(input.tools, { filePath, name });
1138
- if (tools !== undefined) override.tools = tools;
1139
- const excludeTools = parseOverrideStringArrayOrFalse(input.excludeTools, { filePath, name, field: "excludeTools" });
1140
- if (excludeTools !== undefined) override.excludeTools = excludeTools;
1141
- if ("allowNestedSubagents" in input) {
1142
- if (typeof input.allowNestedSubagents === "boolean") override.allowNestedSubagents = input.allowNestedSubagents;
1143
- else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'allowNestedSubagents'; expected a boolean.`);
1144
- }
1145
-
1146
- const extensions = parseOverrideStringArrayOrFalse(input.extensions, { filePath, name, field: "extensions" });
1147
- if (extensions !== undefined) override.extensions = extensions;
1148
-
1149
- const subagentOnlyExtensions = parseOverrideStringArrayOrFalse(input.subagentOnlyExtensions, { filePath, name, field: "subagentOnlyExtensions" });
1150
- if (subagentOnlyExtensions !== undefined) override.subagentOnlyExtensions = subagentOnlyExtensions;
1151
-
1152
- const mutationTools = parseOverrideStringArrayOrFalse(input.mutationTools, { filePath, name, field: "mutationTools" });
1153
- if (mutationTools !== undefined) override.mutationTools = mutationTools;
1154
-
1155
- return Object.keys(override).length > 0 ? override : undefined;
1156
- }
1157
-
1158
- function readSubagentSettings(filePath: string | null): SubagentSettings {
1159
- if (!filePath) return EMPTY_SUBAGENT_SETTINGS;
1160
- const settings = readSettingsFileStrict(filePath);
1161
- const subagents = settings.subagents;
1162
- if (!subagents || typeof subagents !== "object" || Array.isArray(subagents)) return EMPTY_SUBAGENT_SETTINGS;
1163
-
1164
- const subagentsObject = subagents as Record<string, unknown>;
1165
- let disableBuiltins: boolean | undefined;
1166
- if ("disableBuiltins" in subagentsObject) {
1167
- if (typeof subagentsObject.disableBuiltins === "boolean") {
1168
- disableBuiltins = subagentsObject.disableBuiltins;
1169
- } else {
1170
- throw new Error(`Subagent settings in '${filePath}' have invalid 'disableBuiltins'; expected a boolean.`);
1171
- }
1172
- }
1173
- let disableThinking: boolean | undefined;
1174
- if ("disableThinking" in subagentsObject) {
1175
- if (typeof subagentsObject.disableThinking === "boolean") {
1176
- disableThinking = subagentsObject.disableThinking;
1177
- } else {
1178
- throw new Error(`Subagent settings in '${filePath}' have invalid 'disableThinking'; expected a boolean.`);
1179
- }
1180
- }
1181
- let defaultModel: string | undefined;
1182
- if ("defaultModel" in subagentsObject) {
1183
- if (typeof subagentsObject.defaultModel === "string" && subagentsObject.defaultModel.trim()) {
1184
- defaultModel = subagentsObject.defaultModel.trim();
1185
- } else {
1186
- throw new Error(`Subagent settings in '${filePath}' have invalid 'defaultModel'; expected a non-empty string.`);
1187
- }
1188
- }
1189
- let defaultProvider: string | undefined;
1190
- if ("defaultProvider" in subagentsObject) {
1191
- if (typeof subagentsObject.defaultProvider === "string" && subagentsObject.defaultProvider.trim()) {
1192
- defaultProvider = subagentsObject.defaultProvider.trim();
1193
- } else {
1194
- throw new Error(`Subagent settings in '${filePath}' have invalid 'defaultProvider'; expected a non-empty string.`);
1195
- }
1196
- }
1197
- let defaultThinking: string | undefined;
1198
- if ("defaultThinking" in subagentsObject) {
1199
- if (typeof subagentsObject.defaultThinking === "string" && subagentsObject.defaultThinking.trim()) {
1200
- defaultThinking = subagentsObject.defaultThinking.trim();
1201
- } else {
1202
- throw new Error(`Subagent settings in '${filePath}' have invalid 'defaultThinking'; expected a non-empty string.`);
1203
- }
1204
- }
1205
- let maxThinking: ThinkingLevel | undefined;
1206
- if ("maxThinking" in subagentsObject) {
1207
- try {
1208
- maxThinking = parseThinkingLevel(subagentsObject.maxThinking, `'${filePath}' subagents.maxThinking`);
1209
- } catch (error) {
1210
- throw new Error(`Subagent settings in '${filePath}' have invalid 'maxThinking'; expected one of off, minimal, low, medium, high, xhigh, or max.`, { cause: error instanceof Error ? error : undefined });
1211
- }
1212
- }
1213
- let defaultExtensions: string[] | undefined;
1214
- if ("defaultExtensions" in subagentsObject) {
1215
- if (!Array.isArray(subagentsObject.defaultExtensions)
1216
- || subagentsObject.defaultExtensions.some((item) => typeof item !== "string" || !item.trim())) {
1217
- throw new Error(`Subagent settings in '${filePath}' have invalid 'defaultExtensions'; expected an array of non-empty strings.`);
1218
- }
1219
- defaultExtensions = subagentsObject.defaultExtensions.map((item) => item.trim());
1220
- }
1221
- let agentScanDirs: string[] | undefined;
1222
- if ("agentScanDirs" in subagentsObject) {
1223
- if (!Array.isArray(subagentsObject.agentScanDirs)
1224
- || subagentsObject.agentScanDirs.some((item) => typeof item !== "string" || !item.trim())) {
1225
- throw new Error(`Subagent settings in '${filePath}' have invalid 'agentScanDirs'; expected an array of non-empty strings.`);
1226
- }
1227
- agentScanDirs = subagentsObject.agentScanDirs.map((item) => item.trim());
1228
- }
1229
- let agentExcludeDirs: string[] | undefined;
1230
- if ("agentExcludeDirs" in subagentsObject) {
1231
- if (!Array.isArray(subagentsObject.agentExcludeDirs)
1232
- || subagentsObject.agentExcludeDirs.some((item) => typeof item !== "string" || !item.trim())) {
1233
- throw new Error(`Subagent settings in '${filePath}' have invalid 'agentExcludeDirs'; expected an array of non-empty strings.`);
1234
- }
1235
- agentExcludeDirs = subagentsObject.agentExcludeDirs.map((item) => item.trim());
1236
- }
1237
- const modelScope = parseModelScopeConfig(subagentsObject.modelScope, { filePath });
1238
-
1239
- const parsed: Record<string, BuiltinAgentOverrideConfig> = {};
1240
- const providerOverrides: Record<string, Record<string, BuiltinAgentOverrideConfig>> = {};
1241
- const agentOverrides = subagentsObject.agentOverrides;
1242
- const agentOverridesByProvider = subagentsObject.agentOverridesByProvider;
1243
- const parsedSettings: SubagentSettings = {
1244
- overrides: parsed,
1245
- providerOverrides,
1246
- ...(defaultModel !== undefined ? { defaultModel } : {}),
1247
- ...(defaultProvider !== undefined ? { defaultProvider } : {}),
1248
- ...(defaultThinking !== undefined ? { defaultThinking } : {}),
1249
- ...(maxThinking !== undefined ? { maxThinking } : {}),
1250
- ...(defaultExtensions !== undefined ? { defaultExtensions } : {}),
1251
- ...(agentScanDirs !== undefined ? { agentScanDirs } : {}),
1252
- ...(agentExcludeDirs !== undefined ? { agentExcludeDirs } : {}),
1253
- ...(disableBuiltins !== undefined ? { disableBuiltins } : {}),
1254
- ...(disableThinking !== undefined ? { disableThinking } : {}),
1255
- ...(modelScope !== undefined ? { modelScope } : {}),
1256
- };
1257
- if (agentOverrides && typeof agentOverrides === "object" && !Array.isArray(agentOverrides)) {
1258
- for (const [name, value] of Object.entries(agentOverrides)) {
1259
- const override = parseBuiltinOverrideEntry(name, value, filePath);
1260
- if (override) parsed[name] = override;
1261
- }
1262
- }
1263
- if (agentOverridesByProvider !== undefined) {
1264
- if (!agentOverridesByProvider || typeof agentOverridesByProvider !== "object" || Array.isArray(agentOverridesByProvider)) {
1265
- throw new Error(`Subagent settings in '${filePath}' have invalid 'agentOverridesByProvider'; expected an object keyed by provider.`);
1266
- }
1267
- for (const [provider, value] of Object.entries(agentOverridesByProvider)) {
1268
- if (!value || typeof value !== "object" || Array.isArray(value)) {
1269
- throw new Error(`Subagent settings in '${filePath}' have invalid 'agentOverridesByProvider.${provider}'; expected an object keyed by agent.`);
1270
- }
1271
- const entries: Record<string, BuiltinAgentOverrideConfig> = {};
1272
- for (const [agentName, agentValue] of Object.entries(value)) {
1273
- const override = parseBuiltinOverrideEntry(`agentOverridesByProvider.${provider}.${agentName}`, agentValue, filePath);
1274
- if (override) entries[agentName] = override;
1275
- }
1276
- providerOverrides[provider] = entries;
1277
- }
1278
- }
1279
- return parsedSettings;
1280
- }
1281
-
1282
- function selectProviderOverrides(settings: SubagentSettings, provider: string | undefined): SubagentSettings {
1283
- if (!provider) return settings;
1284
- const selected = settings.providerOverrides[provider];
1285
- if (!selected) return settings;
1286
- const overrides = { ...settings.overrides };
1287
- for (const [name, override] of Object.entries(selected)) {
1288
- overrides[name] = { ...overrides[name], ...override };
1289
- }
1290
- return { ...settings, overrides };
1291
- }
1292
-
1293
- function resolveSubagentDefaultProvider(
1294
- userSettings: SubagentSettings,
1295
- projectSettings: SubagentSettings,
1296
- projectSettingsPath: string | null,
1297
- ): string | undefined {
1298
- if (projectSettingsPath && projectSettings.defaultProvider !== undefined) return projectSettings.defaultProvider;
1299
- return userSettings.defaultProvider;
1300
- }
1301
-
1302
- function resolveSubagentDefaultModel(
1303
- userSettings: SubagentSettings,
1304
- projectSettings: SubagentSettings,
1305
- userSettingsPath: string,
1306
- projectSettingsPath: string | null,
1307
- defaultProvider: string | undefined,
1308
- ): AgentModelSourceInfo | undefined {
1309
- if (projectSettingsPath && projectSettings.defaultModel !== undefined) {
1310
- return { type: "subagents.defaultModel", scope: "project", path: projectSettingsPath, model: projectSettings.defaultModel, ...(defaultProvider ? { defaultProvider } : {}) };
1311
- }
1312
- return userSettings.defaultModel !== undefined
1313
- ? { type: "subagents.defaultModel", scope: "user", path: userSettingsPath, model: userSettings.defaultModel, ...(defaultProvider ? { defaultProvider } : {}) }
1314
- : undefined;
1315
- }
1316
-
1317
- function applySubagentDefaultModel(agents: AgentConfig[], defaultModel: AgentModelSourceInfo | undefined, defaultProvider: string | undefined): AgentConfig[] {
1318
- if (!defaultModel && !defaultProvider) return agents;
1319
- return agents.map((agent) => {
1320
- if (agent.model !== undefined && (agent.modelProvider !== undefined || !defaultProvider)) return agent;
1321
- const next = {
1322
- ...agent,
1323
- ...(agent.model === undefined && defaultModel ? { model: defaultModel.model, modelSource: defaultModel } : {}),
1324
- ...(defaultProvider ? { modelProvider: defaultProvider } : {}),
1325
- };
1326
- const frontmatterFields = agentFrontmatterFields.get(agent);
1327
- if (frontmatterFields) agentFrontmatterFields.set(next, frontmatterFields);
1328
- return next;
1329
- });
1330
- }
1331
-
1332
- function resolveSubagentDefaultThinking(
1333
- userSettings: SubagentSettings,
1334
- projectSettings: SubagentSettings,
1335
- projectSettingsPath: string | null,
1336
- ): string | undefined {
1337
- if (projectSettingsPath && projectSettings.defaultThinking !== undefined) return projectSettings.defaultThinking;
1338
- return userSettings.defaultThinking;
1339
- }
1340
-
1341
- function applySubagentDefaultThinking(agents: AgentConfig[], defaultThinking: string | undefined): AgentConfig[] {
1342
- if (defaultThinking === undefined) return agents;
1343
- return agents.map((agent) => {
1344
- if (agent.thinking !== undefined) return agent;
1345
- const next = { ...agent, thinking: defaultThinking };
1346
- const frontmatterFields = agentFrontmatterFields.get(agent);
1347
- if (frontmatterFields) agentFrontmatterFields.set(next, frontmatterFields);
1348
- return next;
1349
- });
1350
- }
1351
-
1352
- function resolveSubagentMaxThinking(
1353
- userSettings: SubagentSettings,
1354
- projectSettings: SubagentSettings,
1355
- projectSettingsPath: string | null,
1356
- ): ThinkingLevel | undefined {
1357
- if (projectSettingsPath && projectSettings.maxThinking !== undefined) return projectSettings.maxThinking;
1358
- return userSettings.maxThinking;
1359
- }
1360
-
1361
- function applySubagentMaxThinking(agents: AgentConfig[], maxThinking: ThinkingLevel | undefined): AgentConfig[] {
1362
- if (maxThinking === undefined) return agents;
1363
- return agents.map((agent) => agent.maxThinking === maxThinking ? agent : { ...agent, maxThinking });
1364
- }
1365
-
1366
- function resolveSubagentDefaultExtensions(
1367
- userSettings: SubagentSettings,
1368
- projectSettings: SubagentSettings,
1369
- projectSettingsPath: string | null,
1370
- ): string[] | undefined {
1371
- if (projectSettingsPath && projectSettings.defaultExtensions !== undefined) return projectSettings.defaultExtensions;
1372
- return userSettings.defaultExtensions;
1373
- }
1374
-
1375
- function applySubagentDefaultExtensions(agents: AgentConfig[], defaultExtensions: string[] | undefined): AgentConfig[] {
1376
- if (defaultExtensions === undefined) return agents;
1377
- return agents.map((agent) => {
1378
- if (agent.extensions !== undefined) return agent;
1379
- const next = { ...agent, extensions: [...defaultExtensions], extensionsFromDefault: true };
1380
- const frontmatterFields = agentFrontmatterFields.get(agent);
1381
- if (frontmatterFields) agentFrontmatterFields.set(next, frontmatterFields);
1382
- return next;
1383
- });
1384
- }
1385
-
1386
- function applySubagentDefaults(
1387
- agents: AgentConfig[],
1388
- defaultModel: AgentModelSourceInfo | undefined,
1389
- defaultProvider: string | undefined,
1390
- defaultThinking: string | undefined,
1391
- defaultExtensions: string[] | undefined,
1392
- ): AgentConfig[] {
1393
- return applySubagentDefaultExtensions(
1394
- applySubagentDefaultThinking(applySubagentDefaultModel(agents, defaultModel, defaultProvider), defaultThinking),
1395
- defaultExtensions,
1396
- );
1397
- }
1398
-
1399
- function applyToolsOverride(target: AgentConfig, toolsOverride: string[] | false | "inherit"): void {
1400
- if (toolsOverride === "inherit") {
1401
- delete target.tools;
1402
- delete target.mcpDirectTools;
1403
- return;
1404
- }
1405
- const { tools, mcpDirectTools } = splitToolList(toolsOverride === false ? [] : toolsOverride);
1406
- if (tools === undefined) delete target.tools; else target.tools = tools;
1407
- if (mcpDirectTools === undefined) delete target.mcpDirectTools; else target.mcpDirectTools = mcpDirectTools;
1408
- }
1409
-
1410
- function applyBuiltinOverride(
1411
- agent: AgentConfig,
1412
- override: BuiltinAgentOverrideConfig,
1413
- meta: { scope: "user" | "project"; path: string },
1414
- ): AgentConfig {
1415
- const overrideInfo: BuiltinAgentOverrideInfo = {
1416
- ...meta,
1417
- base: agent.override?.base ?? cloneOverrideBase(agent),
1418
- fields: [...new Set([...(agent.override?.fields ?? []), ...Object.keys(override)])].sort(),
1419
- fieldScopes: Object.fromEntries(Object.entries({ ...(agent.override?.fieldScopes ?? {}) }).map(([field, scopes]) => [field, [...scopes]])),
1420
- };
1421
- for (const field of Object.keys(override)) {
1422
- const scopes = overrideInfo.fieldScopes![field] ?? [];
1423
- overrideInfo.fieldScopes![field] = [...new Set([...scopes, meta.scope])].sort();
1424
- }
1425
- const next: AgentConfig = {
1426
- ...agent,
1427
- override: overrideInfo,
1428
- };
1429
-
1430
- if (override.description !== undefined) next.description = override.description;
1431
- if (override.machine !== undefined) { if (override.machine === false) delete next.machine; else next.machine = override.machine; }
1432
- if (override.output !== undefined) { if (override.output === false) delete next.output; else next.output = override.output; }
1433
- if (override.outputMode !== undefined) next.outputMode = override.outputMode;
1434
- if (override.defaultReads !== undefined) { if (override.defaultReads === false) delete next.defaultReads; else next.defaultReads = [...override.defaultReads]; }
1435
- if (override.model !== undefined) {
1436
- if (override.model === false) delete next.model; else next.model = override.model;
1437
- delete next.modelSource;
1438
- }
1439
- if (override.defaultProvider !== undefined) {
1440
- if (override.defaultProvider === false) delete next.modelProvider;
1441
- else next.modelProvider = override.defaultProvider;
1442
- }
1443
- if (override.fast !== undefined) next.fast = override.fast;
1444
- if (override.thinking !== undefined) { if (override.thinking === false) delete next.thinking; else next.thinking = override.thinking; }
1445
- if (override.systemPromptMode !== undefined) next.systemPromptMode = override.systemPromptMode;
1446
- if (override.inheritProjectContext !== undefined) next.inheritProjectContext = override.inheritProjectContext;
1447
- if (override.inheritGlobalContext !== undefined) next.inheritGlobalContext = override.inheritGlobalContext;
1448
- if (override.inheritSkills !== undefined) next.inheritSkills = override.inheritSkills;
1449
- if (override.defaultContext !== undefined) { if (override.defaultContext === false) delete next.defaultContext; else next.defaultContext = override.defaultContext; }
1450
- if (override.acceptanceRole !== undefined) { if (override.acceptanceRole === false) delete next.acceptanceRole; else next.acceptanceRole = override.acceptanceRole; }
1451
- if (override.disabled !== undefined) next.disabled = override.disabled;
1452
- if (override.systemPrompt !== undefined) next.systemPrompt = override.systemPrompt;
1453
- if (override.skills !== undefined) { if (override.skills === false) delete next.skills; else next.skills = [...override.skills]; }
1454
- if (override.tools !== undefined) applyToolsOverride(next, override.tools);
1455
- if (override.excludeTools !== undefined) { if (override.excludeTools === false) delete next.excludeTools; else next.excludeTools = [...override.excludeTools]; }
1456
- if (override.allowNestedSubagents !== undefined) next.allowNestedSubagents = override.allowNestedSubagents;
1457
- if (override.extensions !== undefined) { if (override.extensions === false) delete next.extensions; else next.extensions = [...override.extensions]; }
1458
- if (override.subagentOnlyExtensions !== undefined) { if (override.subagentOnlyExtensions === false) delete next.subagentOnlyExtensions; else next.subagentOnlyExtensions = [...override.subagentOnlyExtensions]; }
1459
- if (override.mutationTools !== undefined) { if (override.mutationTools === false) delete next.mutationTools; else next.mutationTools = [...override.mutationTools]; }
1460
- if (override.completionGuard !== undefined) next.completionGuard = override.completionGuard;
1461
- if (override.toolBudget !== undefined) { if (override.toolBudget === false) delete next.toolBudget; else next.toolBudget = override.toolBudget; }
1462
-
1463
- return next;
1464
- }
1465
-
1466
- function clearBuiltinThinking(agent: AgentConfig, meta: { scope: "user" | "project"; path: string }): AgentConfig {
1467
- if (agent.thinking === undefined) return agent;
1468
- const { thinking: _thinking, ...next } = agent;
1469
- return { ...next, override: agent.override ?? { ...meta, base: cloneOverrideBase(agent) } };
1470
- }
1471
-
1472
- function applyBuiltinOverrides(
1473
- builtinAgents: AgentConfig[],
1474
- userSettings: SubagentSettings,
1475
- projectSettings: SubagentSettings,
1476
- userSettingsPath: string,
1477
- projectSettingsPath: string | null,
1478
- ): AgentConfig[] {
1479
- const projectBulkDisabled = projectSettings.disableBuiltins === true && projectSettingsPath !== null;
1480
- const userBulkDisabled = projectSettings.disableBuiltins === undefined && userSettings.disableBuiltins === true;
1481
- const projectThinkingConfigured = projectSettings.disableThinking !== undefined && projectSettingsPath !== null;
1482
- const disableThinking = projectThinkingConfigured ? projectSettings.disableThinking === true : userSettings.disableThinking === true;
1483
- const disableThinkingMeta = projectThinkingConfigured
1484
- ? { scope: "project" as const, path: projectSettingsPath! }
1485
- : { scope: "user" as const, path: userSettingsPath };
1486
-
1487
- const applyGlobalThinking = (agent: AgentConfig, hasExplicitThinkingOverride: boolean): AgentConfig => {
1488
- if (!disableThinking || hasExplicitThinkingOverride) return agent;
1489
- return clearBuiltinThinking(agent, disableThinkingMeta);
1490
- };
1491
-
1492
- return builtinAgents.map((agent) => {
1493
- const projectOverride = projectSettings.overrides[agent.name];
1494
- if (projectOverride && projectSettingsPath) {
1495
- return applyGlobalThinking(
1496
- applyBuiltinOverride(agent, projectOverride, { scope: "project", path: projectSettingsPath }),
1497
- projectOverride.thinking !== undefined,
1498
- );
1499
- }
1500
-
1501
- if (projectBulkDisabled && projectSettingsPath) {
1502
- return applyGlobalThinking(
1503
- applyBuiltinOverride(agent, { disabled: true }, { scope: "project", path: projectSettingsPath }),
1504
- false,
1505
- );
1506
- }
1507
-
1508
- const userOverride = userSettings.overrides[agent.name];
1509
- if (userOverride) {
1510
- return applyGlobalThinking(
1511
- applyBuiltinOverride(agent, userOverride, { scope: "user", path: userSettingsPath }),
1512
- !projectThinkingConfigured && userOverride.thinking !== undefined,
1513
- );
1514
- }
1515
-
1516
- if (userBulkDisabled) {
1517
- return applyGlobalThinking(
1518
- applyBuiltinOverride(agent, { disabled: true }, { scope: "user", path: userSettingsPath }),
1519
- false,
1520
- );
1521
- }
1522
-
1523
- return applyGlobalThinking(agent, false);
1524
- });
1525
- }
1526
-
1527
- function applyCustomAgentOverride(
1528
- agent: AgentConfig,
1529
- override: BuiltinAgentOverrideConfig,
1530
- meta: { scope: "user" | "project"; path: string },
1531
- ): AgentConfig {
1532
- const next = applyBuiltinOverride(agent, override, meta);
1533
- const frontmatterFields = agentFrontmatterFields.get(agent);
1534
- if (frontmatterFields) agentFrontmatterFields.set(next, frontmatterFields);
1535
- return next;
1536
- }
1537
-
1538
- function applyCustomAgentOverrides(
1539
- agents: AgentConfig[],
1540
- userSettings: SubagentSettings,
1541
- projectSettings: SubagentSettings,
1542
- userSettingsPath: string,
1543
- projectSettingsPath: string | null,
1544
- ): AgentConfig[] {
1545
- // Apply user then project so project fields win without dropping user-only fields.
1546
- return agents.map((agent) => {
1547
- const userOverride = userSettings.overrides[agent.name];
1548
- const withUserOverride = userOverride
1549
- ? applyCustomAgentOverride(agent, userOverride, { scope: "user", path: userSettingsPath })
1550
- : agent;
1551
-
1552
- const projectOverride = projectSettings.overrides[agent.name];
1553
- if (projectOverride && projectSettingsPath) {
1554
- return applyCustomAgentOverride(withUserOverride, projectOverride, { scope: "project", path: projectSettingsPath });
1555
- }
1556
-
1557
- return withUserOverride;
1558
- });
1559
- }
1560
-
1561
- export function buildBuiltinOverrideConfig(
1562
- base: BuiltinAgentOverrideBase,
1563
- draft: Pick<AgentConfig, "model" | "modelProvider" | "fast" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritGlobalContext" | "inheritSkills" | "defaultContext" | "acceptanceRole" | "disabled" | "systemPrompt" | "skills" | "tools" | "allowNestedSubagents" | "mcpDirectTools" | "extensions" | "subagentOnlyExtensions" | "mutationTools" | "completionGuard" | "toolBudget"> & Partial<Pick<AgentConfig, "description" | "machine" | "output" | "outputMode" | "defaultReads" | "excludeTools">>,
1564
- ): BuiltinAgentOverrideConfig | undefined {
1565
- const override: BuiltinAgentOverrideConfig = {};
1566
- if (draft.machine !== base.machine) override.machine = draft.machine ?? false;
1567
-
1568
- if (draft.description !== undefined) {
1569
- const description = draft.description.trim();
1570
- if (description && description !== base.description) override.description = description;
1571
- }
1572
- if (draft.output !== base.output) override.output = draft.output ?? false;
1573
- if (draft.outputMode !== undefined && draft.outputMode !== base.outputMode) override.outputMode = draft.outputMode;
1574
- if (!arraysEqual(draft.defaultReads, base.defaultReads)) override.defaultReads = draft.defaultReads ? [...draft.defaultReads] : false;
1575
- if (draft.model !== base.model) override.model = draft.model ?? false;
1576
- if (draft.modelProvider !== base.modelProvider) override.defaultProvider = draft.modelProvider ?? false;
1577
- if (draft.fast !== base.fast) override.fast = draft.fast === true;
1578
- if (draft.thinking !== base.thinking) override.thinking = draft.thinking ?? false;
1579
- if (draft.systemPromptMode !== base.systemPromptMode) override.systemPromptMode = draft.systemPromptMode;
1580
- if (draft.inheritProjectContext !== base.inheritProjectContext) override.inheritProjectContext = draft.inheritProjectContext;
1581
- if (draft.inheritGlobalContext !== base.inheritGlobalContext) override.inheritGlobalContext = draft.inheritGlobalContext;
1582
- if (draft.inheritSkills !== base.inheritSkills) override.inheritSkills = draft.inheritSkills;
1583
- if (draft.defaultContext !== base.defaultContext) override.defaultContext = draft.defaultContext ?? false;
1584
- if (draft.acceptanceRole !== base.acceptanceRole) override.acceptanceRole = draft.acceptanceRole ?? false;
1585
- if (draft.disabled !== base.disabled) override.disabled = draft.disabled ?? false;
1586
- if (draft.systemPrompt !== base.systemPrompt) override.systemPrompt = draft.systemPrompt;
1587
- if (!arraysEqual(draft.skills, base.skills)) override.skills = draft.skills ? [...draft.skills] : false;
1588
-
1589
- const baseTools = joinToolList(base);
1590
- const draftTools = joinToolList(draft);
1591
- if (!arraysEqual(draftTools, baseTools)) override.tools = draftTools ? [...draftTools] : false;
1592
- if (!arraysEqual(draft.excludeTools, base.excludeTools)) override.excludeTools = draft.excludeTools ? [...draft.excludeTools] : false;
1593
- if (draft.allowNestedSubagents !== base.allowNestedSubagents) override.allowNestedSubagents = draft.allowNestedSubagents === true;
1594
- if (!arraysEqual(draft.extensions, base.extensions)) override.extensions = draft.extensions ? [...draft.extensions] : false;
1595
- if (!arraysEqual(draft.subagentOnlyExtensions, base.subagentOnlyExtensions)) {
1596
- override.subagentOnlyExtensions = draft.subagentOnlyExtensions ? [...draft.subagentOnlyExtensions] : false;
1597
- }
1598
- if (!arraysEqual(draft.mutationTools, base.mutationTools)) override.mutationTools = draft.mutationTools ? [...draft.mutationTools] : false;
1599
- if ((draft.completionGuard !== false) !== (base.completionGuard !== false)) {
1600
- override.completionGuard = draft.completionGuard !== false;
1601
- }
1602
- if (JSON.stringify(draft.toolBudget) !== JSON.stringify(base.toolBudget)) override.toolBudget = draft.toolBudget ?? false;
1603
-
1604
- return Object.keys(override).length > 0 ? override : undefined;
1605
- }
1606
-
1607
- export function saveBuiltinAgentOverride(
1608
- cwd: string,
1609
- name: string,
1610
- scope: "user" | "project",
1611
- override: BuiltinAgentOverrideConfig,
1612
- ): string {
1613
- const filePath = scope === "project" ? getProjectAgentSettingsPath(cwd) : getUserAgentSettingsPath();
1614
- if (!filePath) throw new Error("Project override is not available here. No project config root was found.");
1615
-
1616
- const settings = readSettingsFileStrict(filePath);
1617
- const subagents = settings.subagents && typeof settings.subagents === "object" && !Array.isArray(settings.subagents)
1618
- ? { ...(settings.subagents as Record<string, unknown>) }
1619
- : {};
1620
- const agentOverrides = subagents.agentOverrides && typeof subagents.agentOverrides === "object" && !Array.isArray(subagents.agentOverrides)
1621
- ? { ...(subagents.agentOverrides as Record<string, unknown>) }
1622
- : {};
1623
-
1624
- agentOverrides[name] = cloneOverrideValue(override);
1625
- subagents.agentOverrides = agentOverrides;
1626
- settings.subagents = subagents;
1627
- writeSettingsFile(filePath, settings);
1628
- return filePath;
1629
- }
1630
-
1631
- export function removeBuiltinAgentOverride(cwd: string, name: string, scope: "user" | "project", options?: { preserveMachine?: boolean }): { path: string; removed: boolean; machinePreserved: boolean } {
1632
- const filePath = scope === "project" ? getProjectAgentSettingsPath(cwd) : getUserAgentSettingsPath();
1633
- if (!filePath) throw new Error("Project override is not available here. No project config root was found.");
1634
- if (!fs.existsSync(filePath)) return { path: filePath, removed: false, machinePreserved: false };
1635
-
1636
- const settings = readSettingsFileStrict(filePath);
1637
- const subagents = settings.subagents;
1638
- if (!subagents || typeof subagents !== "object" || Array.isArray(subagents)) return { path: filePath, removed: false, machinePreserved: false };
1639
- const nextSubagents = { ...(subagents as Record<string, unknown>) };
1640
- const agentOverrides = nextSubagents.agentOverrides;
1641
- if (!agentOverrides || typeof agentOverrides !== "object" || Array.isArray(agentOverrides)) return { path: filePath, removed: false, machinePreserved: false };
1642
-
1643
- const nextOverrides = { ...(agentOverrides as Record<string, unknown>) };
1644
- const current = nextOverrides[name];
1645
- if (!Object.prototype.hasOwnProperty.call(nextOverrides, name)) return { path: filePath, removed: false, machinePreserved: false };
1646
- const configuredMachine = current && typeof current === "object" && !Array.isArray(current) ? (current as Record<string, unknown>).machine : undefined;
1647
- const machine = configuredMachine === false || (typeof configuredMachine === "string" && configuredMachine.trim()) ? configuredMachine : undefined;
1648
- if (options?.preserveMachine && machine !== undefined) nextOverrides[name] = { machine };
1649
- else delete nextOverrides[name];
1650
- if (Object.keys(nextOverrides).length > 0) nextSubagents.agentOverrides = nextOverrides;
1651
- else delete nextSubagents.agentOverrides;
1652
-
1653
- if (Object.keys(nextSubagents).length > 0) settings.subagents = nextSubagents;
1654
- else delete settings.subagents;
1655
-
1656
- writeSettingsFile(filePath, settings);
1657
- return { path: filePath, removed: true, machinePreserved: options?.preserveMachine === true && machine !== undefined };
1658
- }
1659
-
1660
- export function mergeBuiltinAgentOverride(
1661
- cwd: string,
1662
- name: string,
1663
- scope: "user" | "project",
1664
- fields: BuiltinAgentOverrideConfig,
1665
- ): string {
1666
- const filePath = scope === "project" ? getProjectAgentSettingsPath(cwd) : getUserAgentSettingsPath();
1667
- if (!filePath) throw new Error("Project override is not available here. No project config root was found.");
1668
-
1669
- const settings = readSettingsFileStrict(filePath);
1670
- const subagents = settings.subagents && typeof settings.subagents === "object" && !Array.isArray(settings.subagents)
1671
- ? { ...(settings.subagents as Record<string, unknown>) }
1672
- : {};
1673
- const agentOverrides = subagents.agentOverrides && typeof subagents.agentOverrides === "object" && !Array.isArray(subagents.agentOverrides)
1674
- ? { ...(subagents.agentOverrides as Record<string, unknown>) }
1675
- : {};
1676
-
1677
- const existing = agentOverrides[name];
1678
- const base = existing && typeof existing === "object" && !Array.isArray(existing)
1679
- ? existing as Record<string, unknown>
1680
- : {};
1681
- agentOverrides[name] = { ...base, ...cloneOverrideValue(fields) };
1682
- subagents.agentOverrides = agentOverrides;
1683
- settings.subagents = subagents;
1684
- writeSettingsFile(filePath, settings);
1685
- return filePath;
1686
- }
1687
-
1688
- export function removeBuiltinAgentOverrideFields(
1689
- cwd: string,
1690
- name: string,
1691
- scope: "user" | "project",
1692
- fields: string[],
1693
- ): { path: string; removed: boolean } {
1694
- const filePath = scope === "project" ? getProjectAgentSettingsPath(cwd) : getUserAgentSettingsPath();
1695
- if (!filePath) throw new Error("Project override is not available here. No project config root was found.");
1696
- if (!fs.existsSync(filePath)) return { path: filePath, removed: false };
1697
-
1698
- const settings = readSettingsFileStrict(filePath);
1699
- const subagents = settings.subagents;
1700
- if (!subagents || typeof subagents !== "object" || Array.isArray(subagents)) return { path: filePath, removed: false };
1701
- const agentOverrides = (subagents as Record<string, unknown>).agentOverrides;
1702
- if (!agentOverrides || typeof agentOverrides !== "object" || Array.isArray(agentOverrides)) return { path: filePath, removed: false };
1703
-
1704
- const entry = (agentOverrides as Record<string, unknown>)[name];
1705
- if (!entry || typeof entry !== "object" || Array.isArray(entry)) return { path: filePath, removed: false };
1706
-
1707
- const nextEntry: Record<string, unknown> = { ...(entry as Record<string, unknown>) };
1708
- let removed = false;
1709
- for (const field of fields) {
1710
- if (Object.prototype.hasOwnProperty.call(nextEntry, field)) {
1711
- delete nextEntry[field];
1712
- removed = true;
1713
- }
1714
- }
1715
- if (!removed) return { path: filePath, removed: false };
1716
-
1717
- const nextSubagents = { ...(subagents as Record<string, unknown>) };
1718
- if (Object.keys(nextEntry).length > 0) {
1719
- (nextSubagents.agentOverrides as Record<string, unknown>)[name] = nextEntry;
1720
- } else {
1721
- const nextOverrides = { ...(agentOverrides as Record<string, unknown>) };
1722
- delete nextOverrides[name];
1723
- if (Object.keys(nextOverrides).length > 0) nextSubagents.agentOverrides = nextOverrides;
1724
- else delete nextSubagents.agentOverrides;
1725
- }
1726
- if (Object.keys(nextSubagents).length > 0) settings.subagents = nextSubagents;
1727
- else delete settings.subagents;
1728
- writeSettingsFile(filePath, settings);
1729
- return { path: filePath, removed: true };
1730
- }
1731
-
1732
- const DISCOVERY_PRUNED_DIR_NAMES = new Set([".git", "node_modules", ".pi", "sync-backups"]);
1733
-
1734
- function isDiscoveryNestedProjectRoot(dir: string): boolean {
1735
- return isDirectory(getProjectConfigDir(dir)) || isDirectory(path.join(dir, ".agents"));
1736
- }
1737
-
1738
- function shouldPruneDiscoveryDir(rootDir: string, dir: string, dirName: string): boolean {
1739
- if (DISCOVERY_PRUNED_DIR_NAMES.has(dirName)) return true;
1740
- if (fs.existsSync(path.join(dir, ".git"))) return true;
1741
- return path.resolve(dir) !== path.resolve(rootDir) && isDiscoveryNestedProjectRoot(dir);
1742
- }
1743
-
1744
- function listFilesRecursive(
1745
- dir: string,
1746
- predicate: (fileName: string) => boolean,
1747
- rootDir = dir,
1748
- visitedDirectories = new Set<string>(),
1749
- inspectedDirectories = new Set<string>(),
1750
- ): string[] {
1751
- const files: string[] = [];
1752
- if (!fs.existsSync(dir)) return files;
1753
- inspectedDirectories.add(path.resolve(dir));
1754
- let realDir: string;
1755
- try {
1756
- realDir = fs.realpathSync(dir);
1757
- } catch {
1758
- return files;
1759
- }
1760
- if (visitedDirectories.has(realDir)) return files;
1761
- visitedDirectories.add(realDir);
1762
-
1763
- let entries: fs.Dirent[];
1764
- try {
1765
- entries = fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
1766
- } catch {
1767
- return files;
1768
- }
1769
-
1770
- for (const entry of entries) {
1771
- const filePath = path.join(dir, entry.name);
1772
- let isDirectory = entry.isDirectory();
1773
- if (entry.isSymbolicLink()) {
1774
- try {
1775
- isDirectory = fs.statSync(filePath).isDirectory();
1776
- } catch {
1777
- isDirectory = false;
1778
- }
1779
- }
1780
- if (isDirectory) {
1781
- if (!shouldPruneDiscoveryDir(rootDir, filePath, entry.name)) {
1782
- files.push(...listFilesRecursive(filePath, predicate, rootDir, visitedDirectories, inspectedDirectories));
1783
- }
1784
- continue;
1785
- }
1786
- if (!entry.isFile() && !entry.isSymbolicLink()) continue;
1787
- if (!predicate(entry.name)) continue;
1788
- files.push(filePath);
1789
- }
1790
- return files;
1791
- }
1792
-
1793
- export interface AgentDefinitionInspection {
1794
- files: string[];
1795
- state: AgentDefinitionDirectoryState;
1796
- }
1797
-
1798
- const agentDefinitionInspectionDirectories = new WeakMap<AgentDefinitionInspection, string[]>();
1799
-
1800
- function rememberAgentDefinitionInspection(inspection: AgentDefinitionInspection, directories: Iterable<string>): AgentDefinitionInspection {
1801
- agentDefinitionInspectionDirectories.set(inspection, [...new Set([...directories].map((directory) => path.resolve(directory)))]);
1802
- return inspection;
1803
- }
1804
-
1805
- function inspectedAgentDefinitionDirectories(inspection: AgentDefinitionInspection, root: string): string[] {
1806
- return agentDefinitionInspectionDirectories.get(inspection) ?? [path.resolve(root)];
1807
- }
1808
-
1809
- /** Narrow filesystem seam so unavailable paths can be tested without permissions. */
1810
- export interface AgentDefinitionInspectionFs {
1811
- existsSync(filePath: string): boolean;
1812
- realpathSync?(filePath: string): string;
1813
- statSync(filePath: string): { isDirectory(): boolean };
1814
- readdirSync(dir: string): fs.Dirent[];
1815
- }
1816
-
1817
- const DEFAULT_AGENT_DEFINITION_INSPECTION_FS: AgentDefinitionInspectionFs = {
1818
- existsSync: fs.existsSync,
1819
- realpathSync: fs.realpathSync,
1820
- statSync: fs.statSync,
1821
- readdirSync: (dir) => fs.readdirSync(dir, { withFileTypes: true }),
1822
- };
1823
-
1824
- /**
1825
- * Inspect one agent-definition directory while retaining traversal failure
1826
- * state. A nested unreadable directory makes the whole inspection unavailable,
1827
- * preventing a partial traversal from being reported as empty or complete.
1828
- */
1829
- export function inspectAgentDefinitionDirectory(dir: string, operations: AgentDefinitionInspectionFs = DEFAULT_AGENT_DEFINITION_INSPECTION_FS, isExcluded: (filePath: string) => boolean = () => false): AgentDefinitionInspection {
1830
- const root = path.resolve(dir);
1831
- if (isExcluded(root)) return rememberAgentDefinitionInspection({ files: [], state: "empty" }, []);
1832
- try {
1833
- if (!operations.existsSync(root)) return rememberAgentDefinitionInspection({ files: [], state: "absent" }, [root]);
1834
- if (!operations.statSync(root).isDirectory()) return rememberAgentDefinitionInspection({ files: [], state: "not-directory" }, [root]);
1835
- } catch {
1836
- return rememberAgentDefinitionInspection({ files: [], state: "unreadable" }, [root]);
1837
- }
1838
- const files: string[] = [];
1839
- let unreadable = false;
1840
- const visitedDirectories = new Set<string>();
1841
- const inspectedDirectories = new Set<string>();
1842
- const visit = (current: string): void => {
1843
- inspectedDirectories.add(path.resolve(current));
1844
- let realDir: string;
1845
- try {
1846
- realDir = operations.realpathSync?.(current) ?? path.resolve(current);
1847
- } catch {
1848
- unreadable = true;
1849
- return;
1850
- }
1851
- if (visitedDirectories.has(realDir)) return;
1852
- visitedDirectories.add(realDir);
1853
-
1854
- let entries: fs.Dirent[];
1855
- try {
1856
- entries = operations.readdirSync(current).sort((a, b) => a.name.localeCompare(b.name));
1857
- } catch {
1858
- unreadable = true;
1859
- return;
1860
- }
1861
- for (const entry of entries) {
1862
- const filePath = path.join(current, entry.name);
1863
- if (isExcluded(filePath)) continue;
1864
- let isDirectory = entry.isDirectory();
1865
- if (entry.isSymbolicLink()) {
1866
- try {
1867
- isDirectory = operations.statSync(filePath).isDirectory();
1868
- } catch {
1869
- isDirectory = false;
1870
- }
1871
- }
1872
- if (isDirectory) {
1873
- if (!shouldPruneDiscoveryDir(root, filePath, entry.name)) visit(filePath);
1874
- continue;
1875
- }
1876
- if ((entry.isFile() || entry.isSymbolicLink()) && entry.name.endsWith(".md") && !entry.name.endsWith(".chain.md") && !isLegacyAgentSkillPath(root, filePath)) files.push(filePath);
1877
- }
1878
- };
1879
- visit(root);
1880
- return rememberAgentDefinitionInspection({ files, state: unreadable ? "unreadable" : files.length ? "candidates" : "empty" }, inspectedDirectories);
1881
- }
1882
-
1883
- function isLegacyAgentSkillPath(rootDir: string, filePath: string): boolean {
1884
- const relative = path.relative(rootDir, filePath);
1885
- const parts = relative.split(path.sep).map((part) => part.toLowerCase());
1886
- if (path.basename(rootDir).toLowerCase() === ".agents") {
1887
- parts.unshift(".agents");
1888
- }
1889
- return parts.some((part, index) => part === ".agents" && parts[index + 1] === "skills");
1890
- }
1891
-
1892
- function isJsonSerializable(value: unknown): boolean {
1893
- if (value === null || typeof value === "string" || typeof value === "boolean") return true;
1894
- if (typeof value === "number") return Number.isFinite(value);
1895
- if (Array.isArray(value)) return value.every(isJsonSerializable);
1896
- if (value && typeof value === "object") return Object.values(value).every(isJsonSerializable);
1897
- return false;
1898
- }
1899
-
1900
- function parseAgentRunnerFrontmatter(raw: string | undefined, agentName: string): AgentRunnerConfig | undefined {
1901
- if (raw === undefined || !raw.trim()) return undefined;
1902
- let parsed: unknown;
1903
- try {
1904
- parsed = parseYaml(raw);
1905
- } catch (error) {
1906
- throw new Error(`Agent '${agentName}' has invalid runner frontmatter: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
1907
- }
1908
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1909
- throw new Error(`Agent '${agentName}' has invalid runner frontmatter; expected an object.`);
1910
- }
1911
- const runner = parsed as Record<string, unknown>;
1912
- if (runner.type === "pi") {
1913
- if (Object.keys(runner).some((key) => key !== "type")) throw new Error(`Agent '${agentName}' has invalid Pi runner frontmatter; only 'type' is supported.`);
1914
- return { type: "pi" };
1915
- }
1916
- if (runner.type === "external-job") {
1917
- if (typeof runner.provider !== "string" || !runner.provider.trim() || runner.provider.trim() !== runner.provider) {
1918
- throw new Error(`Agent '${agentName}' external-job runner requires a non-empty trimmed provider string.`);
1919
- }
1920
- if (runner.options !== undefined && (!runner.options || typeof runner.options !== "object" || Array.isArray(runner.options) || !isJsonSerializable(runner.options))) {
1921
- throw new Error(`Agent '${agentName}' external-job runner options must be a JSON-serializable object.`);
1922
- }
1923
- const supported = new Set(["type", "provider", "options"]);
1924
- const unknown = Object.keys(runner).filter((key) => !supported.has(key));
1925
- if (unknown.length > 0) throw new Error(`Agent '${agentName}' external-job runner has unsupported fields: ${unknown.join(", ")}.`);
1926
- return {
1927
- type: "external-job",
1928
- provider: runner.provider,
1929
- ...(runner.options ? { options: runner.options as Record<string, unknown> } : {}),
1930
- };
1931
- }
1932
- if (runner.type !== "external-cli") {
1933
- throw new Error(`Agent '${agentName}' has invalid runner.type; expected 'pi', 'external-cli', or 'external-job'.`);
1934
- }
1935
- if (typeof runner.command !== "string" || !runner.command.trim()) {
1936
- throw new Error(`Agent '${agentName}' external-cli runner requires a non-empty command string.`);
1937
- }
1938
- if (runner.args !== undefined && (!Array.isArray(runner.args) || runner.args.some((arg) => typeof arg !== "string"))) {
1939
- throw new Error(`Agent '${agentName}' external-cli runner args must be an array of strings.`);
1940
- }
1941
- if (runner.adapter !== undefined && !isCodeOwnedExternalCliAdapterId(runner.adapter)) throw new Error(`Agent '${agentName}' external-cli runner adapter must be ${CODE_OWNED_EXTERNAL_CLI_ADAPTER_LABEL}.`);
1942
- 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.`);
1943
- if (runner.promptDelivery !== undefined && runner.promptDelivery !== "stdin") {
1944
- throw new Error(`Agent '${agentName}' external-cli runner promptDelivery must be 'stdin'.`);
1945
- }
1946
- const capabilities = parseExternalCliCapabilityNarrowing(runner.capabilities, `Agent '${agentName}' external-cli runner capabilities`);
1947
- const supported = new Set(["type", "adapter", "command", "args", "promptDelivery", "capabilities"]);
1948
- const unknown = Object.keys(runner).filter((key) => !supported.has(key));
1949
- if (unknown.length > 0) throw new Error(`Agent '${agentName}' external-cli runner has unsupported fields: ${unknown.join(", ")}.`);
1950
- const runnerArgs = Array.isArray(runner.args) ? runner.args.filter((arg): arg is string => typeof arg === "string") : undefined;
1951
- return {
1952
- type: "external-cli",
1953
- ...(isCodeOwnedExternalCliAdapterId(runner.adapter) ? { adapter: runner.adapter } : {}),
1954
- command: runner.command.trim(),
1955
- ...(runnerArgs?.length ? { args: runnerArgs } : {}),
1956
- ...(runner.promptDelivery ? { promptDelivery: "stdin" as const } : {}),
1957
- ...(capabilities ? { capabilities } : {}),
1958
- };
1959
- }
1960
-
1961
- function validateExternalRunnerProfile(frontmatter: Record<string, string>, agentName: string, runner: AgentRunnerConfig | undefined): void {
1962
- if (runner?.type !== "external-cli" && runner?.type !== "external-job") return;
1963
- const unsupported = ["tools", "excludeTools", "allowNestedSubagents", "model", "thinking", "extensions", "subagentOnlyExtensions", "mutationTools", "maxSubagentDepth", "completionGuard", "skills", "skill", "skillPath", "toolBudget", "permission", "permissions"]
1964
- .filter((field) => frontmatter[field] !== undefined);
1965
- if (unsupported.length > 0) {
1966
- throw new Error(`Agent '${agentName}' uses runner.type='${runner.type}' and declares unsupported Pi-only fields: ${unsupported.join(", ")}.`);
1967
- }
1968
- }
1969
-
1970
- function parseAgentAcceptanceFrontmatter(raw: string | undefined, agentName: string): AcceptanceInput | undefined {
1971
- if (raw === undefined || !raw.trim()) return undefined;
1972
- let parsed: unknown;
1973
- try {
1974
- parsed = parseYaml(raw);
1975
- } catch (error) {
1976
- throw new Error(`Agent '${agentName}' has invalid acceptance frontmatter: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
1977
- }
1978
- const errors = validateAcceptanceInput(parsed, `Agent '${agentName}' acceptance frontmatter`);
1979
- if (errors.length > 0) throw new Error(errors.join(" "));
1980
- return parsed as AcceptanceInput;
1981
- }
1982
-
1983
- interface AgentDefinitionFile {
1984
- filePath: string;
1985
- content: string;
1986
- }
1987
-
1988
- function readAgentDefinitionFiles(dir: string, inspection = inspectAgentDefinitionDirectory(dir)): AgentDefinitionFile[] {
1989
- const files: AgentDefinitionFile[] = [];
1990
- for (const filePath of inspection.files) {
1991
- if (isLegacyAgentSkillPath(dir, filePath)) {
1992
- continue;
1993
- }
1994
-
1995
- try {
1996
- files.push({ filePath, content: fs.readFileSync(filePath, "utf-8") });
1997
- } catch {
1998
- continue;
1999
- }
2000
- }
2001
- return files;
2002
- }
2003
-
2004
- function resolveAgentRelativeExtensionPaths(paths: string[] | undefined, agentFilePath: string): string[] | undefined {
2005
- if (paths === undefined) return undefined;
2006
- const baseDir = path.dirname(agentFilePath);
2007
- return paths.map((entry) => {
2008
- const trimmed = entry.trim();
2009
- if (trimmed === "." || trimmed === ".." || trimmed.startsWith("./") || trimmed.startsWith("../")) {
2010
- return path.resolve(baseDir, trimmed);
2011
- }
2012
- return entry;
2013
- });
2014
- }
2015
-
2016
- function loadAgentsFromDefinitionFiles(files: AgentDefinitionFile[], source: AgentSource, discoveryPriority?: number, packageSource?: Omit<PackageSubagentPath, "dir" | "scope">): { agents: AgentConfig[]; diagnostics: AgentDiscoveryDiagnostic[] } {
2017
- const agents: AgentConfig[] = [];
2018
- const diagnostics: AgentDiscoveryDiagnostic[] = [];
2019
-
2020
- for (const { filePath, content } of files) {
2021
- let name: string | undefined;
2022
- let runtimeName: string | undefined;
2023
- let packageSpecified = false;
2024
- try {
2025
- const { frontmatter, body } = parseFrontmatter(content);
2026
-
2027
- if (!frontmatter.name || !frontmatter.description) {
2028
- continue;
2029
- }
2030
-
2031
- const localName = frontmatter.name;
2032
- name = localName;
2033
- const parsedPackage = parsePackageName(frontmatter.package, `Agent '${localName}' package`);
2034
- packageSpecified = parsedPackage.packageName !== undefined || parsedPackage.error !== undefined;
2035
- if (parsedPackage.error) throw new Error(parsedPackage.error);
2036
- const packageName = parsedPackage.packageName;
2037
- runtimeName = buildRuntimeName(localName, packageName);
2038
-
2039
- const runner = parseAgentRunnerFrontmatter(frontmatter.runner, localName);
2040
- validateExternalRunnerProfile(frontmatter, localName, runner);
2041
- let advertise: boolean | undefined;
2042
- if (frontmatter.advertise !== undefined) {
2043
- if (frontmatter.advertise === "true") advertise = true;
2044
- else if (frontmatter.advertise === "false") advertise = false;
2045
- else throw new Error(`Agent '${localName}' has invalid advertise frontmatter; expected true or false.`);
2046
- }
2047
- const rawTools = parseFrontmatterList(frontmatter.tools);
2048
- const parsedTools = splitToolList(rawTools);
2049
- const tools = parsedTools.tools ?? [];
2050
- const mcpDirectTools = parsedTools.mcpDirectTools ?? [];
2051
- const excludeTools = parseFrontmatterList(frontmatter.excludeTools);
2052
- const defaultReads = parseFrontmatterList(frontmatter.defaultReads);
2053
- const aliases = normalizeAgentAliases(parseFrontmatterList(frontmatter.aliases ?? frontmatter.alias), runtimeName);
2054
- const profileError = validateCodeOwnedProfileRunner({ name: runtimeName, localName, aliases, runner });
2055
- if (profileError) throw new Error(profileError);
2056
- const skillStr = frontmatter.skill || frontmatter.skills;
2057
- const skills = parseFrontmatterList(skillStr);
2058
- const skillPath = parseFrontmatterList(frontmatter.skillPath);
2059
- if (frontmatter.fallbackModels !== undefined) throw new Error(`Agent '${filePath}' uses removed frontmatter field 'fallbackModels'. Configure one model instead.`);
2060
- const systemPromptMode = frontmatter.systemPromptMode === "replace"
2061
- ? "replace"
2062
- : frontmatter.systemPromptMode === "append"
2063
- ? "append"
2064
- : defaultSystemPromptMode(localName);
2065
- const inheritProjectContext = frontmatter.inheritProjectContext === "true"
2066
- ? true
2067
- : frontmatter.inheritProjectContext === "false"
2068
- ? false
2069
- : defaultInheritProjectContext(localName);
2070
- const inheritGlobalContext = frontmatter.inheritGlobalContext === "true";
2071
- const inheritSkills = frontmatter.inheritSkills === "true"
2072
- ? true
2073
- : frontmatter.inheritSkills === "false"
2074
- ? false
2075
- : defaultInheritSkills();
2076
- const defaultContext = frontmatter.defaultContext === "fork"
2077
- ? "fork" as const
2078
- : frontmatter.defaultContext === "fresh"
2079
- ? "fresh" as const
2080
- : undefined;
2081
- let defaultAsync: boolean | undefined;
2082
- if (frontmatter.async !== undefined) {
2083
- if (frontmatter.async === "true") defaultAsync = true;
2084
- else if (frontmatter.async === "false") defaultAsync = false;
2085
- else throw new Error(`Agent '${localName}' has invalid async frontmatter; expected true or false.`);
2086
- }
2087
- let defaultTimeoutMs: number | undefined;
2088
- if (frontmatter.timeoutMs !== undefined) {
2089
- const parsed = Number(frontmatter.timeoutMs);
2090
- if (!Number.isInteger(parsed) || parsed <= 0) {
2091
- throw new Error(`Agent '${localName}' has invalid timeoutMs frontmatter; expected a positive integer.`);
2092
- }
2093
- defaultTimeoutMs = parsed;
2094
- }
2095
- let defaultToolTimeoutMs: number | undefined;
2096
- if (frontmatter.toolTimeoutMs !== undefined) {
2097
- const parsed = Number(frontmatter.toolTimeoutMs);
2098
- if (!Number.isInteger(parsed) || parsed <= 0 || parsed > 2_147_483_647) {
2099
- throw new Error(`Agent '${localName}' has invalid toolTimeoutMs frontmatter; expected a positive integer no larger than 2147483647.`);
2100
- }
2101
- defaultToolTimeoutMs = parsed;
2102
- }
2103
- const defaultAcceptance = parseAgentAcceptanceFrontmatter(frontmatter.acceptance, localName);
2104
- let outputMode: OutputMode | undefined;
2105
- if (frontmatter.outputMode !== undefined) {
2106
- if (frontmatter.outputMode === "inline" || frontmatter.outputMode === "file-only") outputMode = frontmatter.outputMode;
2107
- else throw new Error(`Agent '${localName}' has invalid outputMode frontmatter; expected 'inline' or 'file-only'.`);
2108
- }
2109
- let acceptanceRole: AcceptanceRole | undefined;
2110
- if (frontmatter.acceptanceRole !== undefined && frontmatter.acceptanceRole.trim()) {
2111
- if (frontmatter.acceptanceRole === "read-only" || frontmatter.acceptanceRole === "writer") acceptanceRole = frontmatter.acceptanceRole;
2112
- else throw new Error(`Agent '${localName}' has invalid acceptanceRole frontmatter; expected 'read-only' or 'writer'.`);
2113
- }
2114
-
2115
- const extensions = resolveAgentRelativeExtensionPaths(parseFrontmatterList(frontmatter.extensions), filePath);
2116
- const subagentOnlyExtensions = resolveAgentRelativeExtensionPaths(parseFrontmatterList(frontmatter.subagentOnlyExtensions), filePath);
2117
- const mutationTools = parseFrontmatterList(frontmatter.mutationTools);
2118
- let fast: boolean | undefined;
2119
- if (frontmatter.fast !== undefined) {
2120
- if (frontmatter.fast === "true") fast = true;
2121
- else if (frontmatter.fast === "false") fast = false;
2122
- else throw new Error(`Agent '${localName}' has invalid fast frontmatter; expected true or false.`);
2123
- }
2124
- let allowNestedSubagents: boolean | undefined;
2125
- if (frontmatter.allowNestedSubagents !== undefined) {
2126
- if (frontmatter.allowNestedSubagents === "true") allowNestedSubagents = true;
2127
- else if (frontmatter.allowNestedSubagents === "false") allowNestedSubagents = false;
2128
- else throw new Error(`Agent '${localName}' has invalid allowNestedSubagents frontmatter; expected true or false.`);
2129
- }
2130
-
2131
- const extraFields: Record<string, string> = {};
2132
- for (const [key, value] of Object.entries(frontmatter)) {
2133
- if (!KNOWN_FIELDS.has(key)) extraFields[key] = value;
2134
- }
2135
-
2136
- const parsedMaxSubagentDepth = Number(frontmatter.maxSubagentDepth);
2137
- if (frontmatter.permission !== undefined && frontmatter.permissions !== undefined) {
2138
- throw new Error(`Agent '${localName}' cannot declare both permission and permissions frontmatter.`);
2139
- }
2140
- const permissionSource = frontmatter.permissions ?? frontmatter.permission;
2141
- const permissions = permissionSource?.trim()
2142
- ? validatePermissionRules(parseYaml(permissionSource), `Agent '${localName}' permissions`)
2143
- : undefined;
2144
- let toolBudget: ToolBudgetConfig | undefined;
2145
- if (frontmatter.toolBudget !== undefined && frontmatter.toolBudget.trim()) {
2146
- const parsed = JSON.parse(frontmatter.toolBudget) as unknown;
2147
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
2148
- throw new Error(`Agent '${localName}' has invalid toolBudget frontmatter; expected a JSON object.`);
2149
- }
2150
- toolBudget = parsed as ToolBudgetConfig;
2151
- }
2152
- let outputSchema: JsonSchemaObject | undefined;
2153
- if (frontmatter.outputSchema !== undefined && frontmatter.outputSchema.trim()) {
2154
- const parsed: unknown = JSON.parse(frontmatter.outputSchema);
2155
- assertJsonSchemaObject(parsed, `Agent '${localName}' outputSchema`);
2156
- outputSchema = parsed;
2157
- }
2158
- const completionGuard = frontmatter.completionGuard === "false"
2159
- ? false
2160
- : frontmatter.completionGuard === "true"
2161
- ? true
2162
- : undefined;
2163
-
2164
- const maxSubagentDepth = Number.isInteger(parsedMaxSubagentDepth) && parsedMaxSubagentDepth >= 0
2165
- ? parsedMaxSubagentDepth
2166
- : undefined;
2167
- const memory = parseMemoryFrontmatter(frontmatter.memory);
2168
- const machine = validateOptionalMachine(frontmatter.machine, `Agent '${runtimeName}' frontmatter 'machine'`);
2169
- const agent: AgentConfig = {
2170
- name: runtimeName,
2171
- ...(runner !== undefined ? { runner } : {}),
2172
- localName,
2173
- ...(packageName !== undefined ? { packageName } : {}),
2174
- ...(packageSource?.packageName ? { packageSourceName: packageSource.packageName } : {}),
2175
- ...(packageSource?.packageVersion ? { packageSourceVersion: packageSource.packageVersion } : {}),
2176
- ...(packageSource?.packageRoot ? { packageSourceRoot: packageSource.packageRoot } : {}),
2177
- description: frontmatter.description,
2178
- ...(advertise !== undefined ? { advertise } : {}),
2179
- ...(aliases !== undefined ? { aliases } : {}),
2180
- ...(rawTools !== undefined ? { tools } : {}),
2181
- ...(excludeTools !== undefined ? { excludeTools } : {}),
2182
- ...(allowNestedSubagents !== undefined ? { allowNestedSubagents } : {}),
2183
- ...(mcpDirectTools.length > 0 ? { mcpDirectTools } : {}),
2184
- ...(frontmatter.model !== undefined ? { model: frontmatter.model } : {}),
2185
- ...(fast !== undefined ? { fast } : {}),
2186
- ...(frontmatter.thinking !== undefined ? { thinking: frontmatter.thinking === "false" ? false : frontmatter.thinking } : {}),
2187
- systemPromptMode,
2188
- inheritProjectContext,
2189
- inheritGlobalContext,
2190
- inheritSkills,
2191
- ...(defaultContext !== undefined ? { defaultContext } : {}),
2192
- ...(defaultAsync !== undefined ? { defaultAsync } : {}),
2193
- ...(defaultTimeoutMs !== undefined ? { defaultTimeoutMs } : {}),
2194
- ...(defaultToolTimeoutMs !== undefined ? { defaultToolTimeoutMs } : {}),
2195
- ...(defaultAcceptance !== undefined ? { defaultAcceptance } : {}),
2196
- ...(acceptanceRole !== undefined ? { acceptanceRole } : {}),
2197
- systemPrompt: body,
2198
- source,
2199
- filePath,
2200
- ...(discoveryPriority !== undefined ? { discoveryPriority } : {}),
2201
- ...(skills?.length ? { skills } : {}),
2202
- ...(skillPath?.length ? { skillPath } : {}),
2203
- ...(extensions !== undefined ? { extensions } : {}),
2204
- ...(subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions } : {}),
2205
- ...(mutationTools?.length ? { mutationTools } : {}),
2206
- ...(machine !== undefined ? { machine } : {}),
2207
- ...(frontmatter.output !== undefined ? { output: frontmatter.output } : {}),
2208
- ...(outputMode !== undefined ? { outputMode } : {}),
2209
- ...(outputSchema !== undefined ? { outputSchema } : {}),
2210
- ...(defaultReads?.length ? { defaultReads } : {}),
2211
- defaultProgress: frontmatter.defaultProgress === "true",
2212
- interactive: frontmatter.interactive === "true",
2213
- ...(maxSubagentDepth !== undefined ? { maxSubagentDepth } : {}),
2214
- ...(completionGuard !== undefined ? { completionGuard } : {}),
2215
- ...(toolBudget !== undefined ? { toolBudget } : {}),
2216
- ...(permissions !== undefined ? { permissions } : {}),
2217
- ...(memory !== undefined ? { memory } : {}),
2218
- ...(Object.keys(extraFields).length > 0 ? { extraFields } : {}),
2219
- };
2220
- agentFrontmatterFields.set(agent, new Set(Object.keys(frontmatter)));
2221
- agents.push(agent);
2222
- } catch (error) {
2223
- diagnostics.push({ source, filePath, ...(name ? { name } : {}), ...(runtimeName && runtimeName !== name ? { runtimeName } : {}), ...(packageSpecified ? { packageSpecified: true } : {}), ...(discoveryPriority !== undefined ? { discoveryPriority } : {}), error: error instanceof Error ? error.message : String(error) });
2224
- }
2225
- }
2226
-
2227
- return { agents, diagnostics };
2228
- }
2229
-
2230
- function loadAgentsFromDir(dir: string, source: AgentSource, discoveryPriority?: number, packageSource?: Omit<PackageSubagentPath, "dir" | "scope">, inspection = inspectAgentDefinitionDirectory(dir)): { agents: AgentConfig[]; diagnostics: AgentDiscoveryDiagnostic[] } {
2231
- return loadAgentsFromDefinitionFiles(readAgentDefinitionFiles(dir, inspection), source, discoveryPriority, packageSource);
2232
- }
2233
-
2234
- function reportAgentDefinitionDirectory(source: AgentSource, dir: string, inspection: AgentDefinitionInspection): AgentDefinitionDirectoryReport {
2235
- return {
2236
- source,
2237
- path: path.resolve(dir),
2238
- state: inspection.state,
2239
- ...(inspection.state === "candidates" ? { candidateCount: inspection.files.length } : {}),
2240
- };
2241
- }
2242
-
2243
- function loadChainsFromDir(dir: string, source: AgentSource): { chains: ChainConfig[]; diagnostics: ChainDiscoveryDiagnostic[]; files: string[]; directories: string[] } {
2244
- const chains = new Map<string, ChainConfig>();
2245
- const diagnostics: ChainDiscoveryDiagnostic[] = [];
2246
- const directories = new Set<string>();
2247
- const files = listFilesRecursive(dir, (fileName) => fileName.endsWith(".chain.md") || fileName.endsWith(".chain.json"), dir, new Set<string>(), directories);
2248
-
2249
- for (const filePath of files) {
2250
- let content: string;
2251
- try {
2252
- content = fs.readFileSync(filePath, "utf-8");
2253
- } catch {
2254
- continue;
2255
- }
2256
-
2257
- try {
2258
- const chain = filePath.endsWith(".chain.json") ? parseJsonChain(content, source, filePath) : parseChain(content, source, filePath);
2259
- const existing = chains.get(chain.name);
2260
- if (existing && existing.filePath.endsWith(".chain.json") && filePath.endsWith(".chain.md")) continue;
2261
- chains.set(chain.name, chain);
2262
- } catch (error) {
2263
- diagnostics.push({ source, filePath, error: error instanceof Error ? error.message : String(error) });
2264
- continue;
2265
- }
2266
- }
2267
-
2268
- return { chains: Array.from(chains.values()), diagnostics, files, directories: [...directories] };
2269
- }
2270
-
2271
- function isDirectory(p: string): boolean {
2272
- try {
2273
- return fs.statSync(p).isDirectory();
2274
- } catch {
2275
- return false;
2276
- }
2277
- }
2278
-
2279
- function resolveNearestProjectAgentDirs(cwd: string): { readDirs: string[]; candidateDirs: string[]; preferredDir: string | null } {
2280
- const projectRoot = findConfiguredProjectRoot(cwd);
2281
- if (!projectRoot) return { readDirs: [], candidateDirs: [], preferredDir: null };
2282
-
2283
- const legacyDir = path.join(projectRoot, ".agents");
2284
- const preferredDir = path.join(getProjectConfigDir(projectRoot), "agents");
2285
- const candidateDirs = [legacyDir, preferredDir];
2286
- const readDirs: string[] = [];
2287
- if (isDirectory(legacyDir)) readDirs.push(legacyDir);
2288
- if (isDirectory(preferredDir)) readDirs.push(preferredDir);
2289
-
2290
- return { readDirs, candidateDirs, preferredDir };
2291
- }
2292
-
2293
- function resolveNearestProjectChainDirs(cwd: string): { readDirs: string[]; preferredDir: string | null } {
2294
- const projectRoot = findConfiguredProjectRoot(cwd);
2295
- if (!projectRoot) return { readDirs: [], preferredDir: null };
2296
-
2297
- const preferredDir = path.join(getProjectConfigDir(projectRoot), "chains");
2298
- return {
2299
- readDirs: isDirectory(preferredDir) ? [preferredDir] : [],
2300
- preferredDir,
2301
- };
2302
- }
2303
- const BUILTIN_AGENTS_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "agents");
2304
- // Candidate files and inspection state must describe the same cached builtin scan.
2305
- const BUILTIN_AGENT_DEFINITION_INSPECTION = inspectAgentDefinitionDirectory(BUILTIN_AGENTS_DIR);
2306
- const BUILTIN_AGENT_DEFINITION_FILES = readAgentDefinitionFiles(BUILTIN_AGENTS_DIR, BUILTIN_AGENT_DEFINITION_INSPECTION);
2307
-
2308
- export const EXTRA_AGENT_DIRS_ENV = "PI_SUBAGENT_EXTRA_AGENT_DIRS";
2309
-
2310
- // Additional read-only directories to scan for agent definitions, supplied by the
2311
- // launcher via PI_SUBAGENT_EXTRA_AGENT_DIRS (PATH-style, split on os/path delimiter).
2312
- // Lets a hermetic wrapper (e.g. a Nix-store install) expose bundled agents without
2313
- // copying or symlinking them into the writable agent dir. Loaded as "user" source,
2314
- // at lower precedence than agents the user placed in their own agent dir.
2315
- function extraUserAgentDirs(): string[] {
2316
- const raw = process.env[EXTRA_AGENT_DIRS_ENV];
2317
- if (!raw) return [];
2318
- return raw
2319
- .split(path.delimiter)
2320
- .map((dir) => dir.trim())
2321
- .filter((dir) => dir.length > 0);
2322
- }
2323
-
2324
- interface AgentScanDirs {
2325
- dirs: string[];
2326
- watchPaths: string[];
2327
- }
2328
-
2329
- function readConfiguredAgentScanDirs(filePath: string | null, key: "agentScanDirs" | "agentExcludeDirs" = "agentScanDirs"): string[] {
2330
- if (!filePath) return [];
2331
- try {
2332
- const settings = readSettingsFileStrict(filePath);
2333
- const subagents = settings.subagents;
2334
- if (!subagents || typeof subagents !== "object" || Array.isArray(subagents)) return [];
2335
- const dirs = (subagents as Record<string, unknown>)[key];
2336
- return Array.isArray(dirs) ? dirs.filter((dir): dir is string => typeof dir === "string" && dir.trim().length > 0) : [];
2337
- } catch {
2338
- return [];
2339
- }
2340
- }
2341
-
2342
- // Resolve existing ancestors to canonicalize missing descendants of symlinks.
2343
- function canonicalAgentPath(filePath: string): string {
2344
- const resolved = path.resolve(filePath);
2345
- try {
2346
- return fs.realpathSync(resolved);
2347
- } catch {
2348
- const parent = path.dirname(resolved);
2349
- return parent === resolved ? resolved : path.join(canonicalAgentPath(parent), path.basename(resolved));
2350
- }
2351
- }
2352
-
2353
- function agentExclusionRoots(userSettingsPath: string, projectSettingsPath: string | null): Array<{ resolved: string; real: string }> {
2354
- return [userSettingsPath, projectSettingsPath].flatMap((settingsPath) => settingsPath
2355
- ? readConfiguredAgentScanDirs(settingsPath, "agentExcludeDirs").map((entry) => {
2356
- const resolved = path.resolve(path.dirname(settingsPath), expandHomePath(entry.trim()).replace(/[\\/]+/g, path.sep));
2357
- return { resolved, real: canonicalAgentPath(resolved) };
2358
- }) : []);
2359
- }
2360
-
2361
- function agentExclusions(roots: Array<{ resolved: string; real: string }>): (filePath: string) => boolean {
2362
- return (filePath) => {
2363
- if (!roots.length) return false;
2364
- if (roots.some((root) => isPathWithin(root.resolved, filePath))) return true;
2365
- const real = canonicalAgentPath(filePath);
2366
- return roots.some((root) => isPathWithin(root.real, real));
2367
- };
2368
- }
2369
-
2370
- function expandAgentScanDirPattern(pattern: string, isExcluded: (filePath: string) => boolean): AgentScanDirs {
2371
- const expanded = expandHomePath(pattern.trim()).replace(/[\\/]+/g, path.sep);
2372
- if (!expanded) return { dirs: [], watchPaths: [] };
2373
- const wildcardMatches = [...expanded.matchAll(/\*/g)];
2374
- if (wildcardMatches.length === 0) {
2375
- const dir = path.resolve(expanded);
2376
- return { dirs: !isExcluded(dir) && fs.existsSync(dir) ? [dir] : [], watchPaths: [dir] };
2377
- }
2378
- const parts = expanded.split(path.sep);
2379
- const wildcardIndex = parts.findIndex((part) => part.includes("*"));
2380
- if (wildcardMatches.length !== 1 || wildcardIndex === -1 || parts[wildcardIndex] !== "*") return { dirs: [], watchPaths: [] };
2381
- const base = path.resolve(parts.slice(0, wildcardIndex).join(path.sep) || path.sep);
2382
- if (isExcluded(base)) return { dirs: [], watchPaths: [base] };
2383
- const rest = parts.slice(wildcardIndex + 1);
2384
- let entries: fs.Dirent[];
2385
- try {
2386
- entries = fs.readdirSync(base, { withFileTypes: true });
2387
- } catch {
2388
- return { dirs: [], watchPaths: [base] };
2389
- }
2390
- const candidateDirs = entries.filter((entry) => entry.isDirectory()).map((entry) => path.join(base, entry.name, ...rest));
2391
- return {
2392
- dirs: candidateDirs.filter((dir) => !isExcluded(dir) && fs.existsSync(dir)),
2393
- watchPaths: [base, ...candidateDirs],
2394
- };
2395
- }
2396
-
2397
- function settingsAgentScanDirs(entries: string[], isExcluded: (filePath: string) => boolean): AgentScanDirs {
2398
- const dirs = new Set<string>();
2399
- const watchPaths = new Set<string>();
2400
- for (const entry of entries) {
2401
- const expanded = expandAgentScanDirPattern(entry, isExcluded);
2402
- for (const dir of expanded.dirs) dirs.add(dir);
2403
- for (const watchPath of expanded.watchPaths) watchPaths.add(watchPath);
2404
- }
2405
- return { dirs: [...dirs], watchPaths: [...watchPaths] };
2406
- }
2407
-
2408
- export interface AgentDiscoveryAllResult {
2409
- builtin: AgentConfig[];
2410
- package: AgentConfig[];
2411
- user: AgentConfig[];
2412
- project: AgentConfig[];
2413
- agentDiagnostics?: AgentDiscoveryDiagnostic[];
2414
- chains: ChainConfig[];
2415
- chainDiagnostics: ChainDiscoveryDiagnostic[];
2416
- userDir: string;
2417
- projectDir: string | null;
2418
- userChainDir: string;
2419
- projectChainDir: string | null;
2420
- userSettingsPath: string;
2421
- projectSettingsPath: string | null;
2422
- maxThinking?: ThinkingLevel;
2423
- }
2424
-
2425
- /**
2426
- * A single fresh source scan with both projections retained. The effective
2427
- * projection intentionally remains separate from the all-source projection:
2428
- * disabled and shadowed definitions are needed for diagnostics and runtime
2429
- * collision checks even when they are not launchable.
2430
- */
2431
- export interface AgentDiscoverySnapshot {
2432
- effective: AgentDiscoveryResult;
2433
- all: AgentDiscoveryAllResult;
2434
- }
2435
-
2436
- interface LoadedAgentDirectory {
2437
- dir: string;
2438
- inspection: AgentDefinitionInspection;
2439
- loaded: ReturnType<typeof loadAgentsFromDir>;
2440
- packageEntry?: PackageSubagentPath;
2441
- }
2442
-
2443
- interface AgentDiscoverySources {
2444
- cwd: string;
2445
- preferredModelProvider?: string;
2446
- userDir: string;
2447
- userDirOld: string;
2448
- userDirNew: string;
2449
- userChainDir: string;
2450
- projectAgentDirs: string[];
2451
- projectCandidateDirs: string[];
2452
- projectAgentsDir: string | null;
2453
- projectChainDirs: string[];
2454
- projectChainDir: string | null;
2455
- userSettingsPath: string;
2456
- projectSettingsPath: string | null;
2457
- userSettings?: SubagentSettings;
2458
- projectSettings?: SubagentSettings;
2459
- packageSubagentPaths: PackageSubagentPaths;
2460
- builtinLoaded: ReturnType<typeof loadAgentsFromDefinitionFiles>;
2461
- userLoaded: LoadedAgentDirectory[];
2462
- projectLoaded: LoadedAgentDirectory[];
2463
- projectInspections: Map<string, AgentDefinitionInspection>;
2464
- packageLoaded: LoadedAgentDirectory[];
2465
- userChains?: ReturnType<typeof loadChainsFromDir>;
2466
- projectChainLoaded?: Array<{ dir: string; loaded: ReturnType<typeof loadChainsFromDir> }>;
2467
- packageChainLoaded?: Array<{ entry: PackageChainPath; loaded: ReturnType<typeof loadChainsFromDir> }>;
2468
- isExcluded: (filePath: string) => boolean;
2469
- exclusionRoots: Array<{ resolved: string; real: string }>;
2470
- identityWatchPaths: string[];
2471
- chainWatchPaths?: Set<string>;
2472
- watchPaths: string[];
2473
- }
2474
-
2475
- interface AgentDiscoveryCacheEntry {
2476
- sources: AgentDiscoverySources;
2477
- fingerprint: string;
2478
- }
2479
-
2480
- const agentDiscoveryCache = new Map<string, AgentDiscoveryCacheEntry>();
2481
-
2482
- function isPathWithin(root: string, candidate: string): boolean {
2483
- const relative = path.relative(path.resolve(root), path.resolve(candidate));
2484
- return relative === "" || (relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative));
2485
- }
2486
-
2487
- function addDirectoryWatchPaths(paths: Set<string>, root: string, files: readonly string[], directories: readonly string[] = []): void {
2488
- const resolvedRoot = path.resolve(root);
2489
- paths.add(resolvedRoot);
2490
- // The initial recursive inspection is already bounded to this discovery
2491
- // root. Keep every visited directory in the fingerprint so a file added to
2492
- // an existing empty nested directory invalidates the snapshot too.
2493
- for (const directory of directories) {
2494
- if (isPathWithin(resolvedRoot, directory)) paths.add(path.resolve(directory));
2495
- }
2496
- for (const file of files) {
2497
- paths.add(path.resolve(file));
2498
- let current = path.resolve(path.dirname(file));
2499
- while (isPathWithin(resolvedRoot, current)) {
2500
- paths.add(current);
2501
- if (current === resolvedRoot) break;
2502
- current = path.dirname(current);
2503
- }
2504
- }
2505
- }
2506
-
2507
- function watchPathSignature(filePath: string, isExcluded?: (filePath: string) => boolean): string {
2508
- try {
2509
- const stat = fs.statSync(filePath);
2510
- if (stat.isDirectory()) {
2511
- const entries = fs.readdirSync(filePath, { withFileTypes: true })
2512
- .filter((entry) => !isExcluded || !isExcluded(path.join(filePath, entry.name)))
2513
- .sort((left, right) => left.name.localeCompare(right.name))
2514
- .map((entry) => `${entry.name}:${entry.isDirectory() ? "d" : entry.isSymbolicLink() ? (isExcluded ? `l:${canonicalAgentPath(path.join(filePath, entry.name))}` : "l") : "f"}`)
2515
- .join("|");
2516
- return `directory:${entries}`;
2517
- }
2518
- return `file:${stat.size}:${stat.mtimeMs}`;
2519
- } catch {
2520
- return "missing";
2521
- }
2522
- }
2523
-
2524
- function discoveryFingerprint(sources: AgentDiscoverySources): string {
2525
- const exclusionIdentity = JSON.stringify(sources.exclusionRoots.map((root) => ({ resolved: root.resolved, real: canonicalAgentPath(root.resolved) })));
2526
- // A retargeted exclusion needs a fresh scan before fingerprinting old roots.
2527
- if (exclusionIdentity !== JSON.stringify(sources.exclusionRoots)) return exclusionIdentity;
2528
- const rootIdentities = JSON.stringify(sources.identityWatchPaths.map((root) => [root, canonicalAgentPath(root)]));
2529
- // Package metadata can redirect agents outside an excluded tree without chains.
2530
- const unfilteredPaths = new Set([...sources.packageSubagentPaths.watchPaths, ...(sources.chainWatchPaths ?? [])]);
2531
- return exclusionIdentity + "\n" + rootIdentities + "\n" + [...new Set([...sources.watchPaths, ...unfilteredPaths])]
2532
- .filter((filePath) => unfilteredPaths.has(filePath) || filePath === sources.userSettingsPath || filePath === sources.projectSettingsPath || !sources.isExcluded(filePath))
2533
- .sort((left, right) => left.localeCompare(right))
2534
- .map((filePath) => `${filePath}:${watchPathSignature(filePath, sources.exclusionRoots.length && !unfilteredPaths.has(filePath) ? sources.isExcluded : undefined)}`)
2535
- .join("\n");
2536
- }
2537
-
2538
- function discoveryCacheKey(cwd: string, preferredModelProvider: string | undefined): string {
2539
- return JSON.stringify([
2540
- path.resolve(cwd),
2541
- preferredModelProvider ?? null,
2542
- getProjectConfigDir(path.resolve(cwd)),
2543
- getAgentDir(),
2544
- os.homedir(),
2545
- process.env.HOME ?? "",
2546
- process.env.USERPROFILE ?? "",
2547
- process.env[EXTRA_AGENT_DIRS_ENV] ?? "",
2548
- process.env.PI_OFFLINE ?? "",
2549
- process.env.APPDATA ?? "",
2550
- ]);
2551
- }
2552
-
2553
- function projectDiscoveryWatchPaths(cwd: string): string[] {
2554
- const paths: string[] = [];
2555
- let current = path.resolve(cwd);
2556
- while (true) {
2557
- paths.push(getProjectConfigDir(current), path.join(current, ".agents"), path.join(current, ".git"));
2558
- const parent = path.dirname(current);
2559
- if (parent === current) break;
2560
- current = parent;
2561
- }
2562
- return paths;
2563
- }
2564
-
2565
- function packageEntryIncluded(scope: AgentScope, packageScopes: PackageSubagentPath["scope"]): boolean {
2566
- if (scope === "both" || packageScopes.has("root")) return true;
2567
- return packageScopes.has(scope);
2568
- }
2569
-
2570
- function buildAgentDiscoverySources(cwd: string, preferredModelProvider?: string): AgentDiscoverySources {
2571
- const effectiveCwd = path.resolve(cwd);
2572
- const userDirOld = path.join(getAgentDir(), "agents");
2573
- const userDirNew = path.join(os.homedir(), ".agents");
2574
- const userChainDir = getUserChainDir();
2575
- const { readDirs: projectAgentDirs, candidateDirs: projectCandidateDirs, preferredDir: projectAgentsDir } = resolveNearestProjectAgentDirs(effectiveCwd);
2576
- const { readDirs: projectChainDirs, preferredDir: projectChainDir } = resolveNearestProjectChainDirs(effectiveCwd);
2577
- const userSettingsPath = getUserAgentSettingsPath();
2578
- const projectSettingsPath = getProjectAgentSettingsPath(effectiveCwd);
2579
- const packageSubagentPaths = collectPackageSubagentPaths(effectiveCwd);
2580
- const exclusionRoots = agentExclusionRoots(userSettingsPath, projectSettingsPath);
2581
- const isExcluded = agentExclusions(exclusionRoots);
2582
- const userScanDirs = settingsAgentScanDirs(readConfiguredAgentScanDirs(userSettingsPath), isExcluded);
2583
- const projectScanDirs = settingsAgentScanDirs(readConfiguredAgentScanDirs(projectSettingsPath), isExcluded);
2584
-
2585
- const builtinLoaded = loadAgentsFromDefinitionFiles(BUILTIN_AGENT_DEFINITION_FILES, "builtin");
2586
- const userLoaded = [...extraUserAgentDirs(), ...userScanDirs.dirs, userDirOld, userDirNew].filter((dir) => !isExcluded(dir)).map((dir, discoveryPriority): LoadedAgentDirectory => {
2587
- const inspection = inspectAgentDefinitionDirectory(dir, undefined, isExcluded);
2588
- return { dir, inspection, loaded: loadAgentsFromDir(dir, "user", discoveryPriority, undefined, inspection) };
2589
- });
2590
- const projectInspections = new Map(projectCandidateDirs.filter((dir) => !isExcluded(dir)).map((dir) => [dir, inspectAgentDefinitionDirectory(dir, undefined, isExcluded)]));
2591
- const projectLoaded = [...projectScanDirs.dirs, ...projectAgentDirs].filter((dir) => !isExcluded(dir)).map((dir, discoveryPriority): LoadedAgentDirectory => {
2592
- const inspection = projectInspections.get(dir) ?? inspectAgentDefinitionDirectory(dir, undefined, isExcluded);
2593
- return { dir, inspection, loaded: loadAgentsFromDir(dir, "project", dir === projectAgentsDir ? 1 : discoveryPriority, undefined, inspection) };
2594
- });
2595
- const packageLoaded = packageSubagentPaths.agents.filter((entry) => !isExcluded(entry.dir)).map((entry, index): LoadedAgentDirectory => {
2596
- const inspection = inspectAgentDefinitionDirectory(entry.dir, undefined, isExcluded);
2597
- return { dir: entry.dir, inspection, packageEntry: entry, loaded: loadAgentsFromDir(entry.dir, "package", packageSubagentPaths.agents.length - index, entry, inspection) };
2598
- });
2599
-
2600
- const watchPaths = new Set<string>([
2601
- userSettingsPath,
2602
- ...(projectSettingsPath ? [projectSettingsPath] : []),
2603
- ...projectDiscoveryWatchPaths(effectiveCwd),
2604
- ...findProjectRootCandidates(effectiveCwd).map((root) => path.join(getProjectConfigDir(root), "settings.json")),
2605
- ...userScanDirs.watchPaths,
2606
- ...projectScanDirs.watchPaths,
2607
- ...packageSubagentPaths.watchPaths,
2608
- ]);
2609
- for (const directory of userLoaded) addDirectoryWatchPaths(watchPaths, directory.dir, directory.inspection.files, inspectedAgentDefinitionDirectories(directory.inspection, directory.dir));
2610
- for (const dir of projectCandidateDirs) {
2611
- const inspection = projectInspections.get(dir);
2612
- addDirectoryWatchPaths(watchPaths, dir, inspection?.files ?? [], inspection ? inspectedAgentDefinitionDirectories(inspection, dir) : []);
2613
- }
2614
- for (const directory of projectLoaded) addDirectoryWatchPaths(watchPaths, directory.dir, directory.inspection.files, inspectedAgentDefinitionDirectories(directory.inspection, directory.dir));
2615
- for (const directory of packageLoaded) addDirectoryWatchPaths(watchPaths, directory.dir, directory.inspection.files, inspectedAgentDefinitionDirectories(directory.inspection, directory.dir));
2616
-
2617
- const userDir = process.env.PI_CODING_AGENT_DIR ? userDirOld : fs.existsSync(userDirNew) ? userDirNew : userDirOld;
2618
- return {
2619
- cwd: effectiveCwd,
2620
- ...(preferredModelProvider !== undefined ? { preferredModelProvider } : {}),
2621
- userDir,
2622
- userDirOld,
2623
- userDirNew,
2624
- userChainDir,
2625
- projectAgentDirs,
2626
- projectCandidateDirs: projectCandidateDirs.filter((dir) => !isExcluded(dir)),
2627
- projectAgentsDir,
2628
- projectChainDirs,
2629
- projectChainDir,
2630
- userSettingsPath,
2631
- projectSettingsPath,
2632
- packageSubagentPaths,
2633
- builtinLoaded,
2634
- userLoaded,
2635
- projectLoaded,
2636
- projectInspections,
2637
- packageLoaded,
2638
- isExcluded,
2639
- exclusionRoots,
2640
- // Aliases outside excluded lexical subtrees can be retargeted into allowed
2641
- // storage. Watch only their identity, never the excluded target's contents.
2642
- identityWatchPaths: [...new Set([
2643
- ...userScanDirs.watchPaths, ...projectScanDirs.watchPaths,
2644
- ...extraUserAgentDirs(), userDirOld, userDirNew, ...projectCandidateDirs,
2645
- ...packageSubagentPaths.agents.map((entry) => entry.dir),
2646
- ])]
2647
- .filter((dir) => !exclusionRoots.some((root) => isPathWithin(root.resolved, dir)) && isExcluded(dir)),
2648
- watchPaths: [...watchPaths].filter((filePath) => !isExcluded(filePath) || filePath === userSettingsPath || filePath === projectSettingsPath),
2649
- };
2650
- }
2651
-
2652
- function ensureDiscoveryChains(sources: AgentDiscoverySources): void {
2653
- if (sources.userChains) return;
2654
- sources.packageChainLoaded = sources.packageSubagentPaths.chains.map((entry) => ({ entry, loaded: loadChainsFromDir(entry.dir, "package") }));
2655
- sources.userChains = loadChainsFromDir(sources.userChainDir, "user");
2656
- sources.projectChainLoaded = sources.projectChainDirs.map((dir) => ({ dir, loaded: loadChainsFromDir(dir, "project") }));
2657
- const watchPaths = new Set(sources.packageSubagentPaths.watchPaths);
2658
- addDirectoryWatchPaths(watchPaths, sources.userChainDir, sources.userChains.files, sources.userChains.directories);
2659
- for (const chain of sources.projectChainLoaded) addDirectoryWatchPaths(watchPaths, chain.dir, chain.loaded.files, chain.loaded.directories);
2660
- for (const chain of sources.packageChainLoaded) addDirectoryWatchPaths(watchPaths, chain.entry.dir, chain.loaded.files, chain.loaded.directories);
2661
- sources.chainWatchPaths = watchPaths;
2662
- sources.watchPaths = [...new Set([...sources.watchPaths, ...watchPaths])];
2663
- }
2664
-
2665
- function getAgentDiscoverySources(cwd: string, preferredModelProvider?: string, includeChains = false): AgentDiscoverySources {
2666
- const key = discoveryCacheKey(cwd, preferredModelProvider);
2667
- const cached = agentDiscoveryCache.get(key);
2668
- if (cached && cached.fingerprint === discoveryFingerprint(cached.sources)) {
2669
- if (includeChains) {
2670
- ensureDiscoveryChains(cached.sources);
2671
- cached.fingerprint = discoveryFingerprint(cached.sources);
2672
- }
2673
- return cached.sources;
2674
- }
2675
- const sources = buildAgentDiscoverySources(cwd, preferredModelProvider);
2676
- const entry = { sources, fingerprint: discoveryFingerprint(sources) };
2677
- agentDiscoveryCache.set(key, entry);
2678
- if (includeChains) {
2679
- ensureDiscoveryChains(sources);
2680
- entry.fingerprint = discoveryFingerprint(sources);
2681
- }
2682
- return sources;
2683
- }
2684
-
2685
- /** Clear process-local discovery snapshots, primarily for hosts that reload settings in place. */
2686
- export function clearAgentDiscoveryCache(): void {
2687
- agentDiscoveryCache.clear();
2688
- }
2689
-
2690
- function ensureSettingsForScope(sources: AgentDiscoverySources, scope: AgentScope, preferredModelProvider?: string): void {
2691
- if (scope !== "project" && sources.userSettings === undefined) {
2692
- if (sources.packageSubagentPaths.settingsErrors.user) throw sources.packageSubagentPaths.settingsErrors.user;
2693
- sources.userSettings = selectProviderOverrides(readSubagentSettings(sources.userSettingsPath), preferredModelProvider);
2694
- }
2695
- if (scope !== "user" && sources.projectSettings === undefined) {
2696
- if (sources.packageSubagentPaths.settingsErrors.project) throw sources.packageSubagentPaths.settingsErrors.project;
2697
- sources.projectSettings = selectProviderOverrides(readSubagentSettings(sources.projectSettingsPath), preferredModelProvider);
2698
- }
2699
- }
2700
-
2701
- function settingsForScope(sources: AgentDiscoverySources, scope: AgentScope): { user: SubagentSettings; project: SubagentSettings } {
2702
- // Parse only settings that participate in this projection. The source cache
2703
- // still retains both source trees, while malformed out-of-scope settings do
2704
- // not make an otherwise valid scoped projection fail.
2705
- ensureSettingsForScope(sources, scope, sources.preferredModelProvider);
2706
- return {
2707
- user: scope === "project" ? EMPTY_SUBAGENT_SETTINGS : sources.userSettings ?? EMPTY_SUBAGENT_SETTINGS,
2708
- project: scope === "user" ? EMPTY_SUBAGENT_SETTINGS : sources.projectSettings ?? EMPTY_SUBAGENT_SETTINGS,
2709
- };
2710
- }
2711
-
2712
- function configuredAgentsForScope(sources: AgentDiscoverySources, scope: AgentScope, settingsScope = scope): {
2713
- builtin: AgentConfig[];
2714
- package: AgentConfig[];
2715
- user: AgentConfig[];
2716
- project: AgentConfig[];
2717
- userSettings: SubagentSettings;
2718
- projectSettings: SubagentSettings;
2719
- maxThinking?: ThinkingLevel;
2720
- modelScope?: ModelScopeConfig;
2721
- } {
2722
- const { user: userSettings, project: projectSettings } = settingsForScope(sources, settingsScope);
2723
- const defaultProvider = resolveSubagentDefaultProvider(userSettings, projectSettings, sources.projectSettingsPath);
2724
- const defaultModel = resolveSubagentDefaultModel(userSettings, projectSettings, sources.userSettingsPath, sources.projectSettingsPath, defaultProvider);
2725
- const defaultThinking = resolveSubagentDefaultThinking(userSettings, projectSettings, sources.projectSettingsPath);
2726
- const maxThinking = resolveSubagentMaxThinking(userSettings, projectSettings, sources.projectSettingsPath);
2727
- const defaultExtensions = resolveSubagentDefaultExtensions(userSettings, projectSettings, sources.projectSettingsPath);
2728
- const applyDefaults = (agents: AgentConfig[]): AgentConfig[] => applySubagentDefaults(agents, defaultModel, defaultProvider, defaultThinking, defaultExtensions);
2729
- const builtin = applyBuiltinOverrides(applyDefaults(sources.builtinLoaded.agents), userSettings, projectSettings, sources.userSettingsPath, sources.projectSettingsPath);
2730
- const user = applyCustomAgentOverrides(
2731
- applyDefaults(scope === "project" ? [] : sources.userLoaded.flatMap((loaded) => loaded.loaded.agents)),
2732
- userSettings,
2733
- projectSettings,
2734
- sources.userSettingsPath,
2735
- sources.projectSettingsPath,
2736
- );
2737
- const projectMap = new Map<string, AgentConfig>();
2738
- if (scope !== "user") for (const loaded of sources.projectLoaded) for (const agent of loaded.loaded.agents) projectMap.set(agent.name, agent);
2739
- const project = applyCustomAgentOverrides(applyDefaults(Array.from(projectMap.values())), userSettings, projectSettings, sources.userSettingsPath, sources.projectSettingsPath);
2740
- const packageMap = new Map<string, AgentConfig>();
2741
- for (const loaded of sources.packageLoaded) {
2742
- if (!loaded.packageEntry || !packageEntryIncluded(scope, loaded.packageEntry.scope)) continue;
2743
- for (const agent of loaded.loaded.agents) if (!packageMap.has(agent.name)) packageMap.set(agent.name, agent);
2744
- }
2745
- const packageAgents = applyCustomAgentOverrides(applyDefaults(Array.from(packageMap.values())), userSettings, projectSettings, sources.userSettingsPath, sources.projectSettingsPath);
2746
- return {
2747
- builtin,
2748
- package: packageAgents,
2749
- user,
2750
- project,
2751
- userSettings,
2752
- projectSettings,
2753
- maxThinking,
2754
- modelScope: projectSettings.modelScope ?? userSettings.modelScope,
2755
- };
2756
- }
2757
-
2758
- function discoveryDirectories(sources: AgentDiscoverySources, scope: AgentScope): AgentDefinitionDirectoryReport[] {
2759
- const directories: AgentDefinitionDirectoryReport[] = [reportAgentDefinitionDirectory("builtin", BUILTIN_AGENTS_DIR, BUILTIN_AGENT_DEFINITION_INSPECTION)];
2760
- if (scope !== "project") for (const directory of sources.userLoaded) directories.push(reportAgentDefinitionDirectory("user", directory.dir, directory.inspection));
2761
- if (scope !== "user") {
2762
- const reported = new Set<string>();
2763
- for (const dir of sources.projectCandidateDirs) {
2764
- reported.add(path.resolve(dir));
2765
- directories.push(reportAgentDefinitionDirectory("project", dir, sources.projectInspections.get(dir)!));
2766
- }
2767
- for (const directory of sources.projectLoaded) {
2768
- if (!reported.has(path.resolve(directory.dir))) directories.push(reportAgentDefinitionDirectory("project", directory.dir, directory.inspection));
2769
- }
2770
- }
2771
- for (const directory of sources.packageLoaded) {
2772
- if (directory.packageEntry && packageEntryIncluded(scope, directory.packageEntry.scope)) directories.push(reportAgentDefinitionDirectory("package", directory.dir, directory.inspection));
2773
- }
2774
- return directories;
2775
- }
2776
-
2777
- function discoveryDiagnostics(sources: AgentDiscoverySources, scope: AgentScope): AgentDiscoveryDiagnostic[] {
2778
- return [
2779
- ...sources.builtinLoaded.diagnostics,
2780
- ...(scope === "project" ? [] : sources.userLoaded.flatMap((loaded) => loaded.loaded.diagnostics)),
2781
- ...(scope === "user" ? [] : sources.projectLoaded.flatMap((loaded) => loaded.loaded.diagnostics)),
2782
- ...sources.packageLoaded
2783
- .filter((loaded) => loaded.packageEntry && packageEntryIncluded(scope, loaded.packageEntry.scope))
2784
- .flatMap((loaded) => loaded.loaded.diagnostics),
2785
- ];
2786
- }
2787
-
2788
- function buildEffectiveDiscovery(sources: AgentDiscoverySources, scope: AgentScope): AgentDiscoveryResult {
2789
- const configured = configuredAgentsForScope(sources, scope);
2790
- const agents = applySubagentMaxThinking(
2791
- mergeAgentsForScope(scope, configured.user, configured.project, configured.builtin, configured.package).filter((agent) => agent.disabled !== true),
2792
- configured.maxThinking,
2793
- );
2794
- return {
2795
- agents,
2796
- agentDiagnostics: discoveryDiagnostics(sources, scope),
2797
- projectAgentsDir: sources.projectAgentsDir,
2798
- cwd: sources.cwd,
2799
- scope,
2800
- directories: discoveryDirectories(sources, scope),
2801
- ...(configured.modelScope !== undefined ? { modelScope: configured.modelScope } : {}),
2802
- ...(configured.maxThinking !== undefined ? { maxThinking: configured.maxThinking } : {}),
2803
- };
2804
- }
2805
-
2806
- function buildAllDiscovery(sources: AgentDiscoverySources, includeChains: boolean, settingsScope: AgentScope): AgentDiscoveryAllResult {
2807
- if (includeChains) ensureDiscoveryChains(sources);
2808
- const configured = configuredAgentsForScope(sources, "both", settingsScope);
2809
- const packageChainMap = new Map<string, ChainConfig>();
2810
- const packageChainDiagnostics: ChainDiscoveryDiagnostic[] = [];
2811
- for (const chain of sources.packageChainLoaded ?? []) {
2812
- packageChainDiagnostics.push(...chain.loaded.diagnostics);
2813
- for (const definition of chain.loaded.chains) if (!packageChainMap.has(definition.name)) packageChainMap.set(definition.name, definition);
2814
- }
2815
- const projectChainMap = new Map<string, ChainConfig>();
2816
- const projectChainDiagnostics: ChainDiscoveryDiagnostic[] = [];
2817
- for (const chain of sources.projectChainLoaded ?? []) {
2818
- projectChainDiagnostics.push(...chain.loaded.diagnostics);
2819
- for (const definition of chain.loaded.chains) projectChainMap.set(definition.name, definition);
2820
- }
2821
- const chains = [
2822
- ...Array.from(packageChainMap.values()),
2823
- ...(sources.userChains?.chains ?? []),
2824
- ...Array.from(projectChainMap.values()),
2825
- ];
2826
- return {
2827
- builtin: applySubagentMaxThinking(configured.builtin, configured.maxThinking),
2828
- package: applySubagentMaxThinking(configured.package, configured.maxThinking),
2829
- user: applySubagentMaxThinking(configured.user, configured.maxThinking),
2830
- project: applySubagentMaxThinking(configured.project, configured.maxThinking),
2831
- agentDiagnostics: [
2832
- ...sources.builtinLoaded.diagnostics,
2833
- ...sources.userLoaded.flatMap((loaded) => loaded.loaded.diagnostics),
2834
- ...sources.packageLoaded.flatMap((loaded) => loaded.loaded.diagnostics),
2835
- ...sources.projectLoaded.flatMap((loaded) => loaded.loaded.diagnostics),
2836
- ],
2837
- chains,
2838
- chainDiagnostics: [...packageChainDiagnostics, ...(sources.userChains?.diagnostics ?? []), ...projectChainDiagnostics],
2839
- userDir: sources.userDir,
2840
- projectDir: sources.projectAgentsDir,
2841
- userChainDir: sources.userChainDir,
2842
- projectChainDir: sources.projectChainDir,
2843
- userSettingsPath: sources.userSettingsPath,
2844
- projectSettingsPath: sources.projectSettingsPath,
2845
- ...(configured.maxThinking !== undefined ? { maxThinking: configured.maxThinking } : {}),
2846
- };
2847
- }
2848
-
2849
- export function discoverAgentSnapshot(
2850
- cwd: string,
2851
- scope: AgentScope,
2852
- preferredModelProvider?: string,
2853
- options: { includeChains?: boolean } = {},
2854
- ): AgentDiscoverySnapshot {
2855
- const includeChains = options.includeChains !== false;
2856
- const sources = getAgentDiscoverySources(cwd, preferredModelProvider, includeChains);
2857
- return { effective: buildEffectiveDiscovery(sources, scope), all: buildAllDiscovery(sources, includeChains, scope) };
2858
- }
2859
-
2860
- function discoverAgentsUncached(cwd: string, scope: AgentScope, preferredModelProvider?: string): AgentDiscoveryResult {
2861
- const effectiveCwd = path.resolve(cwd);
2862
- const userDirOld = path.join(getAgentDir(), "agents");
2863
- const userDirNew = path.join(os.homedir(), ".agents");
2864
- const { readDirs: projectAgentDirs, candidateDirs: projectCandidateDirs, preferredDir: projectAgentsDir } = resolveNearestProjectAgentDirs(effectiveCwd);
2865
- const userSettingsPath = getUserAgentSettingsPath();
2866
- const projectSettingsPath = getProjectAgentSettingsPath(effectiveCwd);
2867
- const userSettings = selectProviderOverrides(scope === "project" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(userSettingsPath), preferredModelProvider);
2868
- const projectSettings = selectProviderOverrides(scope === "user" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(projectSettingsPath), preferredModelProvider);
2869
- const defaultProvider = resolveSubagentDefaultProvider(userSettings, projectSettings, projectSettingsPath);
2870
- const defaultModel = resolveSubagentDefaultModel(userSettings, projectSettings, userSettingsPath, projectSettingsPath, defaultProvider);
2871
- const defaultThinking = resolveSubagentDefaultThinking(userSettings, projectSettings, projectSettingsPath);
2872
- const maxThinking = resolveSubagentMaxThinking(userSettings, projectSettings, projectSettingsPath);
2873
- const defaultExtensions = resolveSubagentDefaultExtensions(userSettings, projectSettings, projectSettingsPath);
2874
- const modelScope = projectSettings.modelScope ?? userSettings.modelScope;
2875
- const packageSubagentPaths = collectPackageSubagentPaths(effectiveCwd, { includeUser: scope !== "project", includeProject: scope !== "user" });
2876
- const isExcluded = agentExclusions(agentExclusionRoots(userSettingsPath, projectSettingsPath));
2877
- const directories: AgentDefinitionDirectoryReport[] = [reportAgentDefinitionDirectory("builtin", BUILTIN_AGENTS_DIR, BUILTIN_AGENT_DEFINITION_INSPECTION)];
2878
- const builtinLoaded = loadAgentsFromDefinitionFiles(BUILTIN_AGENT_DEFINITION_FILES, "builtin");
2879
- const builtinAgents = applyBuiltinOverrides(applySubagentDefaults(builtinLoaded.agents, defaultModel, defaultProvider, defaultThinking, defaultExtensions), userSettings, projectSettings, userSettingsPath, projectSettingsPath);
2880
- const userScanDirs = settingsAgentScanDirs(userSettings.agentScanDirs ?? [], isExcluded);
2881
- const projectScanDirs = settingsAgentScanDirs(projectSettings.agentScanDirs ?? [], isExcluded);
2882
- const userLoaded = scope === "project" ? [] : [...extraUserAgentDirs(), ...userScanDirs.dirs, userDirOld, userDirNew].filter((dir) => !isExcluded(dir)).map((dir, discoveryPriority) => {
2883
- const inspection = inspectAgentDefinitionDirectory(dir, undefined, isExcluded);
2884
- directories.push(reportAgentDefinitionDirectory("user", dir, inspection));
2885
- return loadAgentsFromDir(dir, "user", discoveryPriority, undefined, inspection);
2886
- });
2887
- const userAgents = applyCustomAgentOverrides(applySubagentDefaults(userLoaded.flatMap((loaded) => loaded.agents), defaultModel, defaultProvider, defaultThinking, defaultExtensions), userSettings, projectSettings, userSettingsPath, projectSettingsPath);
2888
- const projectInspections = scope === "user" ? new Map<string, AgentDefinitionInspection>() : new Map(projectCandidateDirs.filter((dir) => !isExcluded(dir)).map((dir) => [dir, inspectAgentDefinitionDirectory(dir, undefined, isExcluded)]));
2889
- if (scope !== "user") for (const [dir, inspection] of projectInspections) directories.push(reportAgentDefinitionDirectory("project", dir, inspection));
2890
- const projectLoaded = scope === "user" ? [] : [...projectScanDirs.dirs, ...projectAgentDirs].filter((dir) => !isExcluded(dir)).map((dir, discoveryPriority) => {
2891
- const inspection = projectInspections.get(dir) ?? inspectAgentDefinitionDirectory(dir, undefined, isExcluded);
2892
- if (!projectInspections.has(dir)) directories.push(reportAgentDefinitionDirectory("project", dir, inspection));
2893
- return loadAgentsFromDir(dir, "project", dir === projectAgentsDir ? 1 : discoveryPriority, undefined, inspection);
2894
- });
2895
- const projectAgents = applyCustomAgentOverrides(applySubagentDefaults(projectLoaded.flatMap((loaded) => loaded.agents), defaultModel, defaultProvider, defaultThinking, defaultExtensions), userSettings, projectSettings, userSettingsPath, projectSettingsPath);
2896
- const packageLoaded = packageSubagentPaths.agents.filter((entry) => !isExcluded(entry.dir)).map((entry, index) => {
2897
- const inspection = inspectAgentDefinitionDirectory(entry.dir, undefined, isExcluded);
2898
- directories.push(reportAgentDefinitionDirectory("package", entry.dir, inspection));
2899
- return loadAgentsFromDir(entry.dir, "package", packageSubagentPaths.agents.length - index, entry, inspection);
2900
- });
2901
- const packageMap = new Map<string, AgentConfig>();
2902
- for (const loaded of packageLoaded) for (const agent of loaded.agents) if (!packageMap.has(agent.name)) packageMap.set(agent.name, agent);
2903
- const packageAgents = applyCustomAgentOverrides(applySubagentDefaults(Array.from(packageMap.values()), defaultModel, defaultProvider, defaultThinking, defaultExtensions), userSettings, projectSettings, userSettingsPath, projectSettingsPath);
2904
- const agents = applySubagentMaxThinking(mergeAgentsForScope(scope, userAgents, projectAgents, builtinAgents, packageAgents).filter((agent) => agent.disabled !== true), maxThinking);
2905
- const agentDiagnostics = [...builtinLoaded.diagnostics, ...userLoaded.flatMap((loaded) => loaded.diagnostics), ...projectLoaded.flatMap((loaded) => loaded.diagnostics), ...packageLoaded.flatMap((loaded) => loaded.diagnostics)];
2906
- return { agents, agentDiagnostics, projectAgentsDir, cwd: effectiveCwd, scope, directories, ...(modelScope !== undefined ? { modelScope } : {}), ...(maxThinking !== undefined ? { maxThinking } : {}) };
2907
- }
2908
-
2909
- export function discoverAgents(cwd: string, scope: AgentScope, preferredModelProvider?: string): AgentDiscoveryResult {
2910
- if (scope !== "both") return discoverAgentsUncached(cwd, scope, preferredModelProvider);
2911
- const sources = getAgentDiscoverySources(cwd, preferredModelProvider);
2912
- return buildEffectiveDiscovery(sources, scope);
2913
- }
2914
-
2915
- export function discoverAgentsAll(cwd: string, preferredModelProvider?: string): AgentDiscoveryAllResult {
2916
- return discoverAgentSnapshot(cwd, "both", preferredModelProvider).all;
2917
- }