@agimon-ai/doompi-team 0.0.1-alpha.2 → 0.0.1-alpha.21

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 (727) hide show
  1. package/README.md +33 -17
  2. package/dist/adapters/asyncJobTracker.cjs +2 -0
  3. package/dist/adapters/asyncJobTracker.cjs.map +1 -0
  4. package/dist/adapters/asyncJobTracker.mjs +2 -0
  5. package/dist/adapters/asyncJobTracker.mjs.map +1 -0
  6. package/dist/adapters/atomicJson.cjs +2 -0
  7. package/dist/adapters/atomicJson.cjs.map +1 -0
  8. package/dist/adapters/atomicJson.mjs +2 -0
  9. package/dist/adapters/atomicJson.mjs.map +1 -0
  10. package/dist/adapters/pi/extension.cjs +2 -0
  11. package/dist/adapters/pi/extension.cjs.map +1 -0
  12. package/dist/adapters/pi/extension.mjs +2 -0
  13. package/dist/adapters/pi/extension.mjs.map +1 -0
  14. package/dist/adapters/pollScheduler.cjs +2 -0
  15. package/dist/adapters/pollScheduler.cjs.map +1 -0
  16. package/dist/adapters/pollScheduler.mjs +2 -0
  17. package/dist/adapters/pollScheduler.mjs.map +1 -0
  18. package/dist/adapters/process/childTranscript.cjs +5 -0
  19. package/dist/adapters/process/childTranscript.cjs.map +1 -0
  20. package/dist/adapters/process/childTranscript.mjs +5 -0
  21. package/dist/adapters/process/childTranscript.mjs.map +1 -0
  22. package/dist/adapters/process/env.cjs +2 -0
  23. package/dist/adapters/process/env.cjs.map +1 -0
  24. package/dist/adapters/process/env.d.cts +69 -0
  25. package/dist/adapters/process/env.d.cts.map +1 -0
  26. package/dist/adapters/process/env.d.mts +69 -0
  27. package/dist/adapters/process/env.d.mts.map +1 -0
  28. package/dist/adapters/process/env.mjs +2 -0
  29. package/dist/adapters/process/env.mjs.map +1 -0
  30. package/dist/adapters/process/sdkRunnerEntry.cjs +2 -0
  31. package/dist/adapters/process/sdkRunnerEntry.cjs.map +1 -0
  32. package/dist/adapters/process/sdkRunnerEntry.d.cts +5 -0
  33. package/dist/adapters/process/sdkRunnerEntry.d.cts.map +1 -0
  34. package/dist/adapters/process/sdkRunnerEntry.d.mts +5 -0
  35. package/dist/adapters/process/sdkRunnerEntry.d.mts.map +1 -0
  36. package/dist/adapters/process/sdkRunnerEntry.mjs +2 -0
  37. package/dist/adapters/process/sdkRunnerEntry.mjs.map +1 -0
  38. package/dist/adapters/processTerminal.cjs +2 -0
  39. package/dist/adapters/processTerminal.cjs.map +1 -0
  40. package/dist/adapters/processTerminal.mjs +2 -0
  41. package/dist/adapters/processTerminal.mjs.map +1 -0
  42. package/dist/adapters/resultWatcher.cjs +2 -0
  43. package/dist/adapters/resultWatcher.cjs.map +1 -0
  44. package/dist/adapters/resultWatcher.mjs +2 -0
  45. package/dist/adapters/resultWatcher.mjs.map +1 -0
  46. package/dist/adapters/runIdResolver.cjs +2 -0
  47. package/dist/adapters/runIdResolver.cjs.map +1 -0
  48. package/dist/adapters/runIdResolver.mjs +2 -0
  49. package/dist/adapters/runIdResolver.mjs.map +1 -0
  50. package/dist/adapters/runRegistry.cjs +2 -0
  51. package/dist/adapters/runRegistry.cjs.map +1 -0
  52. package/dist/adapters/runRegistry.mjs +2 -0
  53. package/dist/adapters/runRegistry.mjs.map +1 -0
  54. package/dist/adapters/scopeOwner.cjs +2 -0
  55. package/dist/adapters/scopeOwner.cjs.map +1 -0
  56. package/dist/adapters/scopeOwner.mjs +2 -0
  57. package/dist/adapters/scopeOwner.mjs.map +1 -0
  58. package/dist/adapters/staleRunReconciler.cjs +2 -0
  59. package/dist/adapters/staleRunReconciler.cjs.map +1 -0
  60. package/dist/adapters/staleRunReconciler.mjs +2 -0
  61. package/dist/adapters/staleRunReconciler.mjs.map +1 -0
  62. package/dist/adapters/statusReader.cjs +2 -0
  63. package/dist/adapters/statusReader.cjs.map +1 -0
  64. package/dist/adapters/statusReader.mjs +2 -0
  65. package/dist/adapters/statusReader.mjs.map +1 -0
  66. package/dist/adapters/suspendedRuns.cjs +6 -0
  67. package/dist/adapters/suspendedRuns.cjs.map +1 -0
  68. package/dist/adapters/suspendedRuns.mjs +6 -0
  69. package/dist/adapters/suspendedRuns.mjs.map +1 -0
  70. package/dist/api/backgroundWork.cjs +1 -1
  71. package/dist/api/backgroundWork.d.cts +2 -2
  72. package/dist/api/backgroundWork.d.mts +2 -2
  73. package/dist/api/backgroundWork.mjs +1 -1
  74. package/dist/api/capabilityCeiling.cjs +1 -1
  75. package/dist/api/capabilityCeiling.d.cts +3 -3
  76. package/dist/api/capabilityCeiling.d.mts +3 -3
  77. package/dist/api/capabilityCeiling.mjs +1 -2
  78. package/dist/api/delegation.cjs +1 -1
  79. package/dist/api/delegation.d.cts +1 -1
  80. package/dist/api/delegation.d.mts +1 -1
  81. package/dist/api/delegation.mjs +1 -1
  82. package/dist/api/teamSnapshot.cjs +1 -1
  83. package/dist/api/teamSnapshot.d.cts +2 -2
  84. package/dist/api/teamSnapshot.d.mts +2 -2
  85. package/dist/api/teamSnapshot.mjs +1 -2
  86. package/dist/commands/slash/chainExpression.cjs.map +1 -0
  87. package/dist/commands/slash/chainExpression.mjs.map +1 -0
  88. package/dist/commands/slash/doctor.cjs +5 -0
  89. package/dist/commands/slash/doctor.cjs.map +1 -0
  90. package/dist/commands/slash/doctor.mjs +5 -0
  91. package/dist/{slash/doctor.cjs.map → commands/slash/doctor.mjs.map} +1 -1
  92. package/dist/{slash → commands/slash}/slashCommands.cjs +1 -1
  93. package/dist/commands/slash/slashCommands.cjs.map +1 -0
  94. package/dist/{slash → commands/slash}/slashCommands.mjs +2 -2
  95. package/dist/commands/slash/slashCommands.mjs.map +1 -0
  96. package/dist/commands/slash/spawnRequestMapping.cjs.map +1 -0
  97. package/dist/commands/slash/spawnRequestMapping.mjs.map +1 -0
  98. package/dist/commands/slash/subagentLaunch.cjs +2 -0
  99. package/dist/commands/slash/subagentLaunch.cjs.map +1 -0
  100. package/dist/commands/slash/subagentLaunch.mjs +2 -0
  101. package/dist/commands/slash/subagentLaunch.mjs.map +1 -0
  102. package/dist/container/globalBridge.cjs.map +1 -1
  103. package/dist/container/globalBridge.d.cts +1 -1
  104. package/dist/container/globalBridge.d.mts +1 -1
  105. package/dist/container/globalBridge.mjs.map +1 -1
  106. package/dist/container/index.cjs +1 -1
  107. package/dist/container/index.cjs.map +1 -1
  108. package/dist/container/index.d.cts +2 -1
  109. package/dist/container/index.d.cts.map +1 -1
  110. package/dist/container/index.d.mts +2 -1
  111. package/dist/container/index.d.mts.map +1 -1
  112. package/dist/container/index.mjs +1 -1
  113. package/dist/container/index.mjs.map +1 -1
  114. package/dist/container/modules/agents.cjs +1 -1
  115. package/dist/container/modules/agents.cjs.map +1 -1
  116. package/dist/container/modules/agents.mjs +1 -1
  117. package/dist/container/modules/agents.mjs.map +1 -1
  118. package/dist/container/modules/core.cjs +1 -1
  119. package/dist/container/modules/core.cjs.map +1 -1
  120. package/dist/container/modules/core.mjs +1 -1
  121. package/dist/container/modules/core.mjs.map +1 -1
  122. package/dist/container/modules/extensions.cjs +1 -1
  123. package/dist/container/modules/extensions.cjs.map +1 -1
  124. package/dist/container/modules/extensions.mjs +1 -1
  125. package/dist/container/modules/extensions.mjs.map +1 -1
  126. package/dist/container/modules/intercom.cjs +1 -1
  127. package/dist/container/modules/intercom.cjs.map +1 -1
  128. package/dist/container/modules/intercom.mjs +1 -1
  129. package/dist/container/modules/intercom.mjs.map +1 -1
  130. package/dist/container/modules/runs.cjs +1 -1
  131. package/dist/container/modules/runs.cjs.map +1 -1
  132. package/dist/container/modules/runs.mjs +1 -1
  133. package/dist/container/modules/runs.mjs.map +1 -1
  134. package/dist/container/types.cjs +1 -1
  135. package/dist/container/types.cjs.map +1 -1
  136. package/dist/container/types.d.cts +1 -0
  137. package/dist/container/types.d.cts.map +1 -1
  138. package/dist/container/types.d.mts +1 -0
  139. package/dist/container/types.d.mts.map +1 -1
  140. package/dist/container/types.mjs +1 -1
  141. package/dist/container/types.mjs.map +1 -1
  142. package/dist/env.cjs +1 -2
  143. package/dist/env.d.cts +2 -65
  144. package/dist/env.d.mts +2 -65
  145. package/dist/env.mjs +1 -1
  146. package/dist/env.mjs.map +1 -1
  147. package/dist/extensions/config.cjs.map +1 -1
  148. package/dist/extensions/config.mjs.map +1 -1
  149. package/dist/extensions/delegationBridge.cjs.map +1 -1
  150. package/dist/extensions/delegationBridge.mjs.map +1 -1
  151. package/dist/extensions/doom.cjs +1 -1
  152. package/dist/extensions/doom.cjs.map +1 -1
  153. package/dist/extensions/doom.mjs +1 -1
  154. package/dist/extensions/doom.mjs.map +1 -1
  155. package/dist/extensions/fablePlanBridge.cjs +1 -1
  156. package/dist/extensions/fablePlanBridge.cjs.map +1 -1
  157. package/dist/extensions/fablePlanBridge.mjs +1 -1
  158. package/dist/extensions/fablePlanBridge.mjs.map +1 -1
  159. package/dist/extensions/managementActions.cjs +1 -1
  160. package/dist/extensions/managementActions.cjs.map +1 -1
  161. package/dist/extensions/managementActions.mjs +1 -1
  162. package/dist/extensions/managementActions.mjs.map +1 -1
  163. package/dist/extensions/operationJournal.cjs +1 -1
  164. package/dist/extensions/operationJournal.cjs.map +1 -1
  165. package/dist/extensions/operationJournal.mjs +1 -1
  166. package/dist/extensions/operationJournal.mjs.map +1 -1
  167. package/dist/extensions/orchestratorPrompt.cjs +5 -6
  168. package/dist/extensions/orchestratorPrompt.cjs.map +1 -1
  169. package/dist/extensions/orchestratorPrompt.mjs +5 -6
  170. package/dist/extensions/orchestratorPrompt.mjs.map +1 -1
  171. package/dist/extensions/schemas.mjs.map +1 -1
  172. package/dist/extensions/spawnPlan.cjs +3 -2
  173. package/dist/extensions/spawnPlan.cjs.map +1 -1
  174. package/dist/extensions/spawnPlan.mjs +3 -2
  175. package/dist/extensions/spawnPlan.mjs.map +1 -1
  176. package/dist/extensions/standard.cjs +1 -1
  177. package/dist/extensions/standard.cjs.map +1 -1
  178. package/dist/extensions/standard.mjs +1 -1
  179. package/dist/extensions/standard.mjs.map +1 -1
  180. package/dist/extensions/statusViews.cjs +1 -1
  181. package/dist/extensions/statusViews.cjs.map +1 -1
  182. package/dist/extensions/statusViews.mjs +2 -2
  183. package/dist/extensions/statusViews.mjs.map +1 -1
  184. package/dist/extensions/subagentPromptRuntime.cjs +11 -11
  185. package/dist/extensions/subagentPromptRuntime.cjs.map +1 -1
  186. package/dist/extensions/subagentPromptRuntime.d.cts.map +1 -1
  187. package/dist/extensions/subagentPromptRuntime.d.mts.map +1 -1
  188. package/dist/extensions/subagentPromptRuntime.mjs +5 -5
  189. package/dist/extensions/subagentPromptRuntime.mjs.map +1 -1
  190. package/dist/extensions/subagentTool.cjs +5 -6
  191. package/dist/extensions/subagentTool.cjs.map +1 -1
  192. package/dist/extensions/subagentTool.mjs +5 -6
  193. package/dist/extensions/subagentTool.mjs.map +1 -1
  194. package/dist/extensions/toolDescription.cjs +1 -1
  195. package/dist/extensions/toolDescription.cjs.map +1 -1
  196. package/dist/extensions/toolDescription.mjs +1 -1
  197. package/dist/extensions/toolDescription.mjs.map +1 -1
  198. package/dist/index.cjs +1 -1
  199. package/dist/index.cjs.map +1 -1
  200. package/dist/index.d.cts +2 -2
  201. package/dist/index.d.cts.map +1 -1
  202. package/dist/index.d.mts +2 -2
  203. package/dist/index.d.mts.map +1 -1
  204. package/dist/index.mjs +1 -1
  205. package/dist/index.mjs.map +1 -1
  206. package/dist/runs/background/cliRunnerEntry.cjs +1 -2
  207. package/dist/runs/background/cliRunnerEntry.mjs +1 -2
  208. package/dist/runs/sdkRunnerEntry.cjs +1 -2
  209. package/dist/runs/sdkRunnerEntry.d.cts +2 -1
  210. package/dist/runs/sdkRunnerEntry.d.mts +2 -1
  211. package/dist/runs/sdkRunnerEntry.mjs +1 -2
  212. package/dist/schemas/team/backgroundWork.cjs +2 -0
  213. package/dist/schemas/team/backgroundWork.cjs.map +1 -0
  214. package/dist/{protocol → schemas/team}/backgroundWork.d.cts +2 -2
  215. package/dist/schemas/team/backgroundWork.d.cts.map +1 -0
  216. package/dist/{protocol → schemas/team}/backgroundWork.d.mts +2 -2
  217. package/dist/schemas/team/backgroundWork.d.mts.map +1 -0
  218. package/dist/schemas/team/backgroundWork.mjs +2 -0
  219. package/dist/{protocol/backgroundWork.cjs.map → schemas/team/backgroundWork.mjs.map} +1 -1
  220. package/dist/schemas/team/capabilityCeiling.cjs +2 -0
  221. package/dist/schemas/team/capabilityCeiling.cjs.map +1 -0
  222. package/dist/{protocol → schemas/team}/capabilityCeiling.d.cts +3 -3
  223. package/dist/schemas/team/capabilityCeiling.d.cts.map +1 -0
  224. package/dist/{protocol → schemas/team}/capabilityCeiling.d.mts +3 -3
  225. package/dist/schemas/team/capabilityCeiling.d.mts.map +1 -0
  226. package/dist/schemas/team/capabilityCeiling.mjs +2 -0
  227. package/dist/schemas/team/capabilityCeiling.mjs.map +1 -0
  228. package/dist/schemas/team/delegation.cjs.map +1 -0
  229. package/dist/{protocol → schemas/team}/delegation.d.cts +1 -1
  230. package/dist/schemas/team/delegation.d.cts.map +1 -0
  231. package/dist/{protocol → schemas/team}/delegation.d.mts +1 -1
  232. package/dist/schemas/team/delegation.d.mts.map +1 -0
  233. package/dist/schemas/team/delegation.mjs.map +1 -0
  234. package/dist/schemas/team/packageConfig.cjs +2 -0
  235. package/dist/schemas/team/packageConfig.cjs.map +1 -0
  236. package/dist/schemas/team/packageConfig.mjs +2 -0
  237. package/dist/schemas/team/packageConfig.mjs.map +1 -0
  238. package/dist/services/agents/discovery.cjs +2 -0
  239. package/dist/services/agents/discovery.cjs.map +1 -0
  240. package/dist/services/agents/discovery.mjs +2 -0
  241. package/dist/services/agents/discovery.mjs.map +1 -0
  242. package/dist/services/agents/frontmatter.cjs.map +1 -0
  243. package/dist/{agents → services/agents}/frontmatter.mjs +1 -1
  244. package/dist/services/agents/frontmatter.mjs.map +1 -0
  245. package/dist/services/agents/loader.cjs +2 -0
  246. package/dist/services/agents/loader.cjs.map +1 -0
  247. package/dist/services/agents/loader.mjs +2 -0
  248. package/dist/services/agents/loader.mjs.map +1 -0
  249. package/dist/services/agents/memory.cjs +3 -0
  250. package/dist/services/agents/memory.cjs.map +1 -0
  251. package/dist/{agents → services/agents}/memory.mjs +1 -1
  252. package/dist/services/agents/memory.mjs.map +1 -0
  253. package/dist/services/agents/projectRoot.cjs +2 -0
  254. package/dist/services/agents/projectRoot.cjs.map +1 -0
  255. package/dist/services/agents/projectRoot.mjs +2 -0
  256. package/dist/services/agents/projectRoot.mjs.map +1 -0
  257. package/dist/services/agents/settings.cjs +2 -0
  258. package/dist/services/agents/settings.cjs.map +1 -0
  259. package/dist/services/agents/settings.mjs +2 -0
  260. package/dist/services/agents/settings.mjs.map +1 -0
  261. package/dist/services/agents/skills.cjs +0 -0
  262. package/dist/services/agents/skills.cjs.map +1 -0
  263. package/dist/services/agents/skills.mjs +5 -0
  264. package/dist/services/agents/skills.mjs.map +1 -0
  265. package/dist/{agents → services/agents}/types.d.cts +4 -4
  266. package/dist/services/agents/types.d.cts.map +1 -0
  267. package/dist/{agents → services/agents}/types.d.mts +4 -4
  268. package/dist/services/agents/types.d.mts.map +1 -0
  269. package/dist/services/api/backgroundWork.cjs +1 -0
  270. package/dist/services/api/backgroundWork.d.cts +1 -0
  271. package/dist/services/api/backgroundWork.d.mts +1 -0
  272. package/dist/services/api/backgroundWork.mjs +1 -0
  273. package/dist/services/api/capabilityCeiling.cjs +1 -0
  274. package/dist/services/api/capabilityCeiling.d.cts +2 -0
  275. package/dist/services/api/capabilityCeiling.d.mts +2 -0
  276. package/dist/services/api/capabilityCeiling.mjs +2 -0
  277. package/dist/services/api/capabilityCeiling.mjs.map +1 -0
  278. package/dist/services/api/teamSnapshot.cjs +1 -0
  279. package/dist/services/api/teamSnapshot.d.cts +1 -0
  280. package/dist/services/api/teamSnapshot.d.mts +1 -0
  281. package/dist/services/api/teamSnapshot.mjs +2 -0
  282. package/dist/services/api/teamSnapshot.mjs.map +1 -0
  283. package/dist/services/intercom/intercomBridge.cjs.map +1 -0
  284. package/dist/services/intercom/intercomBridge.mjs.map +1 -0
  285. package/dist/services/intercom/nativeTeamChannel.cjs +5 -0
  286. package/dist/services/intercom/nativeTeamChannel.cjs.map +1 -0
  287. package/dist/{intercom → services/intercom}/nativeTeamChannel.d.cts +1 -1
  288. package/dist/services/intercom/nativeTeamChannel.d.cts.map +1 -0
  289. package/dist/{intercom → services/intercom}/nativeTeamChannel.d.mts +1 -1
  290. package/dist/services/intercom/nativeTeamChannel.d.mts.map +1 -0
  291. package/dist/services/intercom/nativeTeamChannel.mjs +5 -0
  292. package/dist/services/intercom/nativeTeamChannel.mjs.map +1 -0
  293. package/dist/services/intercom/supervisorControlChannel.cjs +2 -0
  294. package/dist/services/intercom/supervisorControlChannel.cjs.map +1 -0
  295. package/dist/{intercom → services/intercom}/supervisorControlChannel.mjs +1 -1
  296. package/dist/services/intercom/supervisorControlChannel.mjs.map +1 -0
  297. package/dist/services/runs/background/asyncExecution.cjs +2 -0
  298. package/dist/services/runs/background/asyncExecution.cjs.map +1 -0
  299. package/dist/services/runs/background/asyncExecution.mjs +2 -0
  300. package/dist/services/runs/background/asyncExecution.mjs.map +1 -0
  301. package/dist/services/runs/background/asyncJobTracker.cjs +1 -0
  302. package/dist/services/runs/background/asyncJobTracker.mjs +2 -0
  303. package/dist/services/runs/background/asyncJobTracker.mjs.map +1 -0
  304. package/dist/services/runs/background/cliRunnerEntry.cjs +2 -0
  305. package/dist/services/runs/background/cliRunnerEntry.cjs.map +1 -0
  306. package/dist/services/runs/background/cliRunnerEntry.mjs +2 -0
  307. package/dist/services/runs/background/cliRunnerEntry.mjs.map +1 -0
  308. package/dist/services/runs/background/completionBatcher.cjs.map +1 -0
  309. package/dist/services/runs/background/completionBatcher.mjs +2 -0
  310. package/dist/services/runs/background/completionBatcher.mjs.map +1 -0
  311. package/dist/{runs → services/runs}/background/notify.cjs +1 -1
  312. package/dist/services/runs/background/notify.cjs.map +1 -0
  313. package/dist/{runs → services/runs}/background/notify.mjs +1 -1
  314. package/dist/services/runs/background/notify.mjs.map +1 -0
  315. package/dist/services/runs/background/parentWatchdog.cjs.map +1 -0
  316. package/dist/services/runs/background/parentWatchdog.mjs.map +1 -0
  317. package/dist/services/runs/background/processTerminal.cjs +1 -0
  318. package/dist/services/runs/background/processTerminal.mjs +2 -0
  319. package/dist/services/runs/background/processTerminal.mjs.map +1 -0
  320. package/dist/services/runs/background/resultWatcher.cjs +1 -0
  321. package/dist/services/runs/background/resultWatcher.mjs +2 -0
  322. package/dist/services/runs/background/resultWatcher.mjs.map +1 -0
  323. package/dist/services/runs/background/runIdResolver.cjs +1 -0
  324. package/dist/services/runs/background/runIdResolver.mjs +2 -0
  325. package/dist/services/runs/background/runIdResolver.mjs.map +1 -0
  326. package/dist/services/runs/background/runnerBootstrap.cjs +2 -0
  327. package/dist/services/runs/background/runnerBootstrap.cjs.map +1 -0
  328. package/dist/services/runs/background/runnerBootstrap.mjs +2 -0
  329. package/dist/services/runs/background/runnerBootstrap.mjs.map +1 -0
  330. package/dist/services/runs/background/runnerExecution.cjs +2 -0
  331. package/dist/services/runs/background/runnerExecution.cjs.map +1 -0
  332. package/dist/services/runs/background/runnerExecution.mjs +2 -0
  333. package/dist/services/runs/background/runnerExecution.mjs.map +1 -0
  334. package/dist/{runs → services/runs}/background/runnerReporting.cjs +2 -2
  335. package/dist/services/runs/background/runnerReporting.cjs.map +1 -0
  336. package/dist/{runs → services/runs}/background/runnerReporting.mjs +2 -2
  337. package/dist/services/runs/background/runnerReporting.mjs.map +1 -0
  338. package/dist/services/runs/background/runnerTeamMembership.cjs +2 -0
  339. package/dist/services/runs/background/runnerTeamMembership.cjs.map +1 -0
  340. package/dist/services/runs/background/runnerTeamMembership.mjs +2 -0
  341. package/dist/services/runs/background/runnerTeamMembership.mjs.map +1 -0
  342. package/dist/services/runs/background/spawnHandshake.cjs +2 -0
  343. package/dist/services/runs/background/spawnHandshake.cjs.map +1 -0
  344. package/dist/services/runs/background/spawnHandshake.mjs +2 -0
  345. package/dist/services/runs/background/spawnHandshake.mjs.map +1 -0
  346. package/dist/services/runs/background/staleRunReconciler.cjs +1 -0
  347. package/dist/services/runs/background/staleRunReconciler.mjs +2 -0
  348. package/dist/services/runs/background/staleRunReconciler.mjs.map +1 -0
  349. package/dist/services/runs/background/statusReader.cjs +1 -0
  350. package/dist/services/runs/background/statusReader.mjs +2 -0
  351. package/dist/services/runs/background/statusReader.mjs.map +1 -0
  352. package/dist/services/runs/background/statusWriter.cjs +2 -0
  353. package/dist/services/runs/background/statusWriter.cjs.map +1 -0
  354. package/dist/services/runs/background/statusWriter.mjs +2 -0
  355. package/dist/services/runs/background/statusWriter.mjs.map +1 -0
  356. package/dist/services/runs/background/subagentWait.cjs +2 -0
  357. package/dist/services/runs/background/subagentWait.cjs.map +1 -0
  358. package/dist/services/runs/background/subagentWait.mjs +2 -0
  359. package/dist/services/runs/background/subagentWait.mjs.map +1 -0
  360. package/dist/{runs/background/terminalPersistence.mjs → services/runs/background/terminalPersistence.cjs} +2 -2
  361. package/dist/services/runs/background/terminalPersistence.cjs.map +1 -0
  362. package/dist/services/runs/background/terminalPersistence.mjs +2 -0
  363. package/dist/services/runs/background/terminalPersistence.mjs.map +1 -0
  364. package/dist/services/runs/extensionErrorTelemetry.cjs +2 -0
  365. package/dist/services/runs/extensionErrorTelemetry.cjs.map +1 -0
  366. package/dist/services/runs/extensionErrorTelemetry.mjs +2 -0
  367. package/dist/services/runs/extensionErrorTelemetry.mjs.map +1 -0
  368. package/dist/services/runs/registry/processGroup.cjs.map +1 -0
  369. package/dist/services/runs/registry/processGroup.mjs.map +1 -0
  370. package/dist/services/runs/registry/runRegistry.cjs +1 -0
  371. package/dist/services/runs/registry/runRegistry.mjs +2 -0
  372. package/dist/services/runs/registry/runRegistry.mjs.map +1 -0
  373. package/dist/services/runs/registry/sessionLifecycle.cjs +2 -0
  374. package/dist/services/runs/registry/sessionLifecycle.cjs.map +1 -0
  375. package/dist/services/runs/registry/sessionLifecycle.mjs +2 -0
  376. package/dist/services/runs/registry/sessionLifecycle.mjs.map +1 -0
  377. package/dist/services/runs/registry/suspendedRuns.cjs +1 -0
  378. package/dist/services/runs/registry/suspendedRuns.mjs +2 -0
  379. package/dist/services/runs/registry/suspendedRuns.mjs.map +1 -0
  380. package/dist/services/runs/sdkRunnerEntry.cjs +1 -0
  381. package/dist/services/runs/sdkRunnerEntry.mjs +1 -0
  382. package/dist/services/runs/shared/claudeFableProfile.cjs +4 -0
  383. package/dist/services/runs/shared/claudeFableProfile.cjs.map +1 -0
  384. package/dist/services/runs/shared/claudeFableProfile.mjs +4 -0
  385. package/dist/services/runs/shared/claudeFableProfile.mjs.map +1 -0
  386. package/dist/services/runs/shared/depthGuard.cjs +2 -0
  387. package/dist/services/runs/shared/depthGuard.cjs.map +1 -0
  388. package/dist/services/runs/shared/depthGuard.mjs +2 -0
  389. package/dist/services/runs/shared/depthGuard.mjs.map +1 -0
  390. package/dist/services/runs/shared/mcpDirectToolAllowlist.cjs +2 -0
  391. package/dist/services/runs/shared/mcpDirectToolAllowlist.cjs.map +1 -0
  392. package/dist/services/runs/shared/mcpDirectToolAllowlist.mjs +2 -0
  393. package/dist/services/runs/shared/mcpDirectToolAllowlist.mjs.map +1 -0
  394. package/dist/services/runs/shared/modelFallback.cjs +2 -0
  395. package/dist/services/runs/shared/modelFallback.cjs.map +1 -0
  396. package/dist/services/runs/shared/modelFallback.mjs +2 -0
  397. package/dist/services/runs/shared/modelFallback.mjs.map +1 -0
  398. package/dist/services/runs/shared/modelScope.cjs +2 -0
  399. package/dist/services/runs/shared/modelScope.cjs.map +1 -0
  400. package/dist/services/runs/shared/modelScope.mjs +2 -0
  401. package/dist/services/runs/shared/modelScope.mjs.map +1 -0
  402. package/dist/services/runs/shared/nestedPath.cjs +2 -0
  403. package/dist/services/runs/shared/nestedPath.cjs.map +1 -0
  404. package/dist/services/runs/shared/nestedPath.mjs +2 -0
  405. package/dist/services/runs/shared/nestedPath.mjs.map +1 -0
  406. package/dist/services/runs/shared/piArgs.cjs +2 -0
  407. package/dist/services/runs/shared/piArgs.cjs.map +1 -0
  408. package/dist/services/runs/shared/piArgs.mjs +2 -0
  409. package/dist/services/runs/shared/piArgs.mjs.map +1 -0
  410. package/dist/services/runs/shared/piSpawn.cjs +2 -0
  411. package/dist/services/runs/shared/piSpawn.cjs.map +1 -0
  412. package/dist/services/runs/shared/piSpawn.mjs +2 -0
  413. package/dist/services/runs/shared/piSpawn.mjs.map +1 -0
  414. package/dist/services/runs/shared/runWithConcurrency.cjs +2 -0
  415. package/dist/services/runs/shared/runWithConcurrency.cjs.map +1 -0
  416. package/dist/services/runs/shared/runWithConcurrency.d.cts +25 -0
  417. package/dist/services/runs/shared/runWithConcurrency.d.cts.map +1 -0
  418. package/dist/services/runs/shared/runWithConcurrency.d.mts +25 -0
  419. package/dist/services/runs/shared/runWithConcurrency.d.mts.map +1 -0
  420. package/dist/services/runs/shared/runWithConcurrency.mjs +2 -0
  421. package/dist/services/runs/shared/runWithConcurrency.mjs.map +1 -0
  422. package/dist/services/runs/shared/runtimeRegistry.cjs +2 -0
  423. package/dist/services/runs/shared/runtimeRegistry.cjs.map +1 -0
  424. package/dist/services/runs/shared/runtimeRegistry.mjs +2 -0
  425. package/dist/services/runs/shared/runtimeRegistry.mjs.map +1 -0
  426. package/dist/services/runs/shared/structuredOutput.cjs +2 -0
  427. package/dist/{runs → services/runs}/shared/structuredOutput.cjs.map +1 -1
  428. package/dist/services/runs/shared/structuredOutput.mjs +2 -0
  429. package/dist/{runs → services/runs}/shared/structuredOutput.mjs.map +1 -1
  430. package/dist/services/runs/shared/toolAvailability.cjs +2 -0
  431. package/dist/services/runs/shared/toolAvailability.cjs.map +1 -0
  432. package/dist/services/runs/shared/toolAvailability.mjs +2 -0
  433. package/dist/services/runs/shared/toolAvailability.mjs.map +1 -0
  434. package/dist/services/runs/shared/toolBudget.cjs +2 -0
  435. package/dist/services/runs/shared/toolBudget.cjs.map +1 -0
  436. package/dist/services/runs/shared/toolBudget.mjs +2 -0
  437. package/dist/services/runs/shared/toolBudget.mjs.map +1 -0
  438. package/dist/shared/artifacts.cjs.map +1 -1
  439. package/dist/shared/artifacts.mjs.map +1 -1
  440. package/dist/shared/atomicJson.cjs +1 -2
  441. package/dist/shared/atomicJson.mjs +1 -1
  442. package/dist/shared/atomicJson.mjs.map +1 -1
  443. package/dist/shared/childTranscript.cjs +1 -5
  444. package/dist/shared/childTranscript.mjs +1 -4
  445. package/dist/shared/childTranscript.mjs.map +1 -1
  446. package/dist/shared/fileSystemRetry.cjs +1 -1
  447. package/dist/shared/fileSystemRetry.cjs.map +1 -1
  448. package/dist/shared/fileSystemRetry.mjs +1 -1
  449. package/dist/shared/fileSystemRetry.mjs.map +1 -1
  450. package/dist/shared/formatters.cjs.map +1 -1
  451. package/dist/shared/formatters.mjs.map +1 -1
  452. package/dist/shared/paths.cjs +1 -1
  453. package/dist/shared/paths.cjs.map +1 -1
  454. package/dist/shared/paths.mjs +1 -1
  455. package/dist/shared/paths.mjs.map +1 -1
  456. package/dist/shared/pollScheduler.cjs +1 -2
  457. package/dist/shared/pollScheduler.mjs +1 -1
  458. package/dist/shared/pollScheduler.mjs.map +1 -1
  459. package/dist/shared/scopeOwner.cjs +1 -2
  460. package/dist/shared/scopeOwner.mjs +1 -1
  461. package/dist/shared/scopeOwner.mjs.map +1 -1
  462. package/dist/tui/agentCatalog.cjs +1 -1
  463. package/dist/tui/agentCatalog.cjs.map +1 -1
  464. package/dist/tui/agentCatalog.mjs +1 -1
  465. package/dist/tui/agentCatalog.mjs.map +1 -1
  466. package/dist/tui/agentResourceProjection.cjs +1 -1
  467. package/dist/tui/agentResourceProjection.cjs.map +1 -1
  468. package/dist/tui/agentResourceProjection.mjs +1 -1
  469. package/dist/tui/agentResourceProjection.mjs.map +1 -1
  470. package/dist/tui/completionNotice.cjs +1 -1
  471. package/dist/tui/completionNotice.cjs.map +1 -1
  472. package/dist/tui/completionNotice.mjs +1 -1
  473. package/dist/tui/completionNotice.mjs.map +1 -1
  474. package/dist/tui/fleet.cjs +2 -2
  475. package/dist/tui/fleet.cjs.map +1 -1
  476. package/dist/tui/fleet.mjs +2 -2
  477. package/dist/tui/fleet.mjs.map +1 -1
  478. package/dist/tui/fleetAgentView.cjs.map +1 -1
  479. package/dist/tui/fleetAgentView.mjs.map +1 -1
  480. package/dist/tui/fleetStatus.cjs +1 -1
  481. package/dist/tui/fleetStatus.cjs.map +1 -1
  482. package/dist/tui/fleetStatus.mjs +1 -1
  483. package/dist/tui/fleetStatus.mjs.map +1 -1
  484. package/dist/tui/fleetTranscript.cjs +1 -1
  485. package/dist/tui/fleetTranscript.cjs.map +1 -1
  486. package/dist/tui/fleetTranscript.mjs +1 -1
  487. package/dist/tui/fleetTranscript.mjs.map +1 -1
  488. package/dist/tui/register.cjs +1 -1
  489. package/dist/tui/register.cjs.map +1 -1
  490. package/dist/tui/register.mjs +1 -1
  491. package/dist/tui/register.mjs.map +1 -1
  492. package/dist/tui/subagentToolRender.cjs +3 -0
  493. package/dist/tui/subagentToolRender.cjs.map +1 -0
  494. package/dist/tui/subagentToolRender.mjs +3 -0
  495. package/dist/tui/subagentToolRender.mjs.map +1 -0
  496. package/dist/{types.d.cts → types/index.d.cts} +2 -2
  497. package/dist/types/index.d.cts.map +1 -0
  498. package/dist/{types.d.mts → types/index.d.mts} +2 -2
  499. package/dist/types/index.d.mts.map +1 -0
  500. package/package.json +23 -16
  501. package/dist/agents/discovery.cjs +0 -2
  502. package/dist/agents/discovery.cjs.map +0 -1
  503. package/dist/agents/discovery.mjs +0 -2
  504. package/dist/agents/discovery.mjs.map +0 -1
  505. package/dist/agents/frontmatter.cjs.map +0 -1
  506. package/dist/agents/frontmatter.mjs.map +0 -1
  507. package/dist/agents/loader.cjs +0 -2
  508. package/dist/agents/loader.cjs.map +0 -1
  509. package/dist/agents/loader.mjs +0 -2
  510. package/dist/agents/loader.mjs.map +0 -1
  511. package/dist/agents/memory.cjs +0 -3
  512. package/dist/agents/memory.cjs.map +0 -1
  513. package/dist/agents/memory.mjs.map +0 -1
  514. package/dist/agents/projectRoot.cjs +0 -2
  515. package/dist/agents/projectRoot.cjs.map +0 -1
  516. package/dist/agents/projectRoot.mjs +0 -2
  517. package/dist/agents/projectRoot.mjs.map +0 -1
  518. package/dist/agents/settings.cjs +0 -2
  519. package/dist/agents/settings.cjs.map +0 -1
  520. package/dist/agents/settings.mjs +0 -2
  521. package/dist/agents/settings.mjs.map +0 -1
  522. package/dist/agents/skills.cjs +0 -0
  523. package/dist/agents/skills.cjs.map +0 -1
  524. package/dist/agents/skills.mjs +0 -5
  525. package/dist/agents/skills.mjs.map +0 -1
  526. package/dist/agents/types.d.cts.map +0 -1
  527. package/dist/agents/types.d.mts.map +0 -1
  528. package/dist/api/capabilityCeiling.mjs.map +0 -1
  529. package/dist/api/teamSnapshot.mjs.map +0 -1
  530. package/dist/env.cjs.map +0 -1
  531. package/dist/env.d.cts.map +0 -1
  532. package/dist/env.d.mts.map +0 -1
  533. package/dist/extension.cjs +0 -2
  534. package/dist/extension.cjs.map +0 -1
  535. package/dist/extension.mjs +0 -2
  536. package/dist/extension.mjs.map +0 -1
  537. package/dist/intercom/intercomBridge.cjs.map +0 -1
  538. package/dist/intercom/intercomBridge.mjs.map +0 -1
  539. package/dist/intercom/nativeTeamChannel.cjs +0 -5
  540. package/dist/intercom/nativeTeamChannel.cjs.map +0 -1
  541. package/dist/intercom/nativeTeamChannel.d.cts.map +0 -1
  542. package/dist/intercom/nativeTeamChannel.d.mts.map +0 -1
  543. package/dist/intercom/nativeTeamChannel.mjs +0 -5
  544. package/dist/intercom/nativeTeamChannel.mjs.map +0 -1
  545. package/dist/intercom/supervisorControlChannel.cjs +0 -2
  546. package/dist/intercom/supervisorControlChannel.cjs.map +0 -1
  547. package/dist/intercom/supervisorControlChannel.mjs.map +0 -1
  548. package/dist/protocol/backgroundWork.cjs +0 -2
  549. package/dist/protocol/backgroundWork.d.cts.map +0 -1
  550. package/dist/protocol/backgroundWork.d.mts.map +0 -1
  551. package/dist/protocol/backgroundWork.mjs +0 -2
  552. package/dist/protocol/backgroundWork.mjs.map +0 -1
  553. package/dist/protocol/capabilityCeiling.cjs +0 -2
  554. package/dist/protocol/capabilityCeiling.cjs.map +0 -1
  555. package/dist/protocol/capabilityCeiling.d.cts.map +0 -1
  556. package/dist/protocol/capabilityCeiling.d.mts.map +0 -1
  557. package/dist/protocol/capabilityCeiling.mjs +0 -2
  558. package/dist/protocol/capabilityCeiling.mjs.map +0 -1
  559. package/dist/protocol/delegation.cjs.map +0 -1
  560. package/dist/protocol/delegation.d.cts.map +0 -1
  561. package/dist/protocol/delegation.d.mts.map +0 -1
  562. package/dist/protocol/delegation.mjs.map +0 -1
  563. package/dist/runs/background/asyncExecution.cjs +0 -2
  564. package/dist/runs/background/asyncExecution.cjs.map +0 -1
  565. package/dist/runs/background/asyncExecution.mjs +0 -2
  566. package/dist/runs/background/asyncExecution.mjs.map +0 -1
  567. package/dist/runs/background/asyncJobTracker.cjs +0 -2
  568. package/dist/runs/background/asyncJobTracker.cjs.map +0 -1
  569. package/dist/runs/background/asyncJobTracker.mjs +0 -2
  570. package/dist/runs/background/asyncJobTracker.mjs.map +0 -1
  571. package/dist/runs/background/cliRunnerEntry.cjs.map +0 -1
  572. package/dist/runs/background/cliRunnerEntry.mjs.map +0 -1
  573. package/dist/runs/background/completionBatcher.cjs.map +0 -1
  574. package/dist/runs/background/completionBatcher.mjs +0 -2
  575. package/dist/runs/background/completionBatcher.mjs.map +0 -1
  576. package/dist/runs/background/notify.cjs.map +0 -1
  577. package/dist/runs/background/notify.mjs.map +0 -1
  578. package/dist/runs/background/parentWatchdog.cjs.map +0 -1
  579. package/dist/runs/background/parentWatchdog.mjs.map +0 -1
  580. package/dist/runs/background/processTerminal.cjs +0 -2
  581. package/dist/runs/background/processTerminal.cjs.map +0 -1
  582. package/dist/runs/background/processTerminal.mjs +0 -2
  583. package/dist/runs/background/processTerminal.mjs.map +0 -1
  584. package/dist/runs/background/resultWatcher.cjs +0 -2
  585. package/dist/runs/background/resultWatcher.cjs.map +0 -1
  586. package/dist/runs/background/resultWatcher.mjs +0 -2
  587. package/dist/runs/background/resultWatcher.mjs.map +0 -1
  588. package/dist/runs/background/runIdResolver.cjs +0 -2
  589. package/dist/runs/background/runIdResolver.cjs.map +0 -1
  590. package/dist/runs/background/runIdResolver.mjs +0 -2
  591. package/dist/runs/background/runIdResolver.mjs.map +0 -1
  592. package/dist/runs/background/runnerBootstrap.cjs +0 -2
  593. package/dist/runs/background/runnerBootstrap.cjs.map +0 -1
  594. package/dist/runs/background/runnerBootstrap.mjs +0 -2
  595. package/dist/runs/background/runnerBootstrap.mjs.map +0 -1
  596. package/dist/runs/background/runnerExecution.cjs +0 -2
  597. package/dist/runs/background/runnerExecution.cjs.map +0 -1
  598. package/dist/runs/background/runnerExecution.mjs +0 -2
  599. package/dist/runs/background/runnerExecution.mjs.map +0 -1
  600. package/dist/runs/background/runnerReporting.cjs.map +0 -1
  601. package/dist/runs/background/runnerReporting.mjs.map +0 -1
  602. package/dist/runs/background/runnerTeamMembership.cjs +0 -2
  603. package/dist/runs/background/runnerTeamMembership.cjs.map +0 -1
  604. package/dist/runs/background/runnerTeamMembership.mjs +0 -2
  605. package/dist/runs/background/runnerTeamMembership.mjs.map +0 -1
  606. package/dist/runs/background/spawnHandshake.cjs +0 -2
  607. package/dist/runs/background/spawnHandshake.cjs.map +0 -1
  608. package/dist/runs/background/spawnHandshake.mjs +0 -2
  609. package/dist/runs/background/spawnHandshake.mjs.map +0 -1
  610. package/dist/runs/background/staleRunReconciler.cjs +0 -2
  611. package/dist/runs/background/staleRunReconciler.cjs.map +0 -1
  612. package/dist/runs/background/staleRunReconciler.mjs +0 -2
  613. package/dist/runs/background/staleRunReconciler.mjs.map +0 -1
  614. package/dist/runs/background/statusReader.cjs +0 -2
  615. package/dist/runs/background/statusReader.cjs.map +0 -1
  616. package/dist/runs/background/statusReader.mjs +0 -2
  617. package/dist/runs/background/statusReader.mjs.map +0 -1
  618. package/dist/runs/background/statusWriter.cjs +0 -2
  619. package/dist/runs/background/statusWriter.cjs.map +0 -1
  620. package/dist/runs/background/statusWriter.mjs +0 -2
  621. package/dist/runs/background/statusWriter.mjs.map +0 -1
  622. package/dist/runs/background/subagentWait.cjs +0 -2
  623. package/dist/runs/background/subagentWait.cjs.map +0 -1
  624. package/dist/runs/background/subagentWait.mjs +0 -2
  625. package/dist/runs/background/subagentWait.mjs.map +0 -1
  626. package/dist/runs/background/terminalPersistence.cjs +0 -2
  627. package/dist/runs/background/terminalPersistence.cjs.map +0 -1
  628. package/dist/runs/background/terminalPersistence.mjs.map +0 -1
  629. package/dist/runs/registry/processGroup.cjs.map +0 -1
  630. package/dist/runs/registry/processGroup.mjs.map +0 -1
  631. package/dist/runs/registry/runRegistry.cjs +0 -2
  632. package/dist/runs/registry/runRegistry.cjs.map +0 -1
  633. package/dist/runs/registry/runRegistry.mjs +0 -2
  634. package/dist/runs/registry/runRegistry.mjs.map +0 -1
  635. package/dist/runs/registry/sessionLifecycle.cjs +0 -2
  636. package/dist/runs/registry/sessionLifecycle.cjs.map +0 -1
  637. package/dist/runs/registry/sessionLifecycle.mjs +0 -2
  638. package/dist/runs/registry/sessionLifecycle.mjs.map +0 -1
  639. package/dist/runs/registry/suspendedRuns.cjs +0 -4
  640. package/dist/runs/registry/suspendedRuns.cjs.map +0 -1
  641. package/dist/runs/registry/suspendedRuns.mjs +0 -4
  642. package/dist/runs/registry/suspendedRuns.mjs.map +0 -1
  643. package/dist/runs/sdkRunnerEntry.cjs.map +0 -1
  644. package/dist/runs/sdkRunnerEntry.mjs.map +0 -1
  645. package/dist/runs/shared/claudeFableProfile.cjs +0 -4
  646. package/dist/runs/shared/claudeFableProfile.cjs.map +0 -1
  647. package/dist/runs/shared/claudeFableProfile.mjs +0 -4
  648. package/dist/runs/shared/claudeFableProfile.mjs.map +0 -1
  649. package/dist/runs/shared/depthGuard.cjs +0 -2
  650. package/dist/runs/shared/depthGuard.cjs.map +0 -1
  651. package/dist/runs/shared/depthGuard.mjs +0 -2
  652. package/dist/runs/shared/depthGuard.mjs.map +0 -1
  653. package/dist/runs/shared/mcpDirectToolAllowlist.cjs +0 -2
  654. package/dist/runs/shared/mcpDirectToolAllowlist.cjs.map +0 -1
  655. package/dist/runs/shared/mcpDirectToolAllowlist.mjs +0 -2
  656. package/dist/runs/shared/mcpDirectToolAllowlist.mjs.map +0 -1
  657. package/dist/runs/shared/modelFallback.cjs +0 -2
  658. package/dist/runs/shared/modelFallback.cjs.map +0 -1
  659. package/dist/runs/shared/modelFallback.mjs +0 -2
  660. package/dist/runs/shared/modelFallback.mjs.map +0 -1
  661. package/dist/runs/shared/modelScope.cjs +0 -2
  662. package/dist/runs/shared/modelScope.cjs.map +0 -1
  663. package/dist/runs/shared/modelScope.mjs +0 -2
  664. package/dist/runs/shared/modelScope.mjs.map +0 -1
  665. package/dist/runs/shared/nestedPath.cjs +0 -2
  666. package/dist/runs/shared/nestedPath.cjs.map +0 -1
  667. package/dist/runs/shared/nestedPath.mjs +0 -2
  668. package/dist/runs/shared/nestedPath.mjs.map +0 -1
  669. package/dist/runs/shared/piArgs.cjs +0 -2
  670. package/dist/runs/shared/piArgs.cjs.map +0 -1
  671. package/dist/runs/shared/piArgs.mjs +0 -2
  672. package/dist/runs/shared/piArgs.mjs.map +0 -1
  673. package/dist/runs/shared/piSpawn.cjs +0 -2
  674. package/dist/runs/shared/piSpawn.cjs.map +0 -1
  675. package/dist/runs/shared/piSpawn.mjs +0 -2
  676. package/dist/runs/shared/piSpawn.mjs.map +0 -1
  677. package/dist/runs/shared/runWithConcurrency.cjs +0 -2
  678. package/dist/runs/shared/runWithConcurrency.cjs.map +0 -1
  679. package/dist/runs/shared/runWithConcurrency.mjs +0 -2
  680. package/dist/runs/shared/runWithConcurrency.mjs.map +0 -1
  681. package/dist/runs/shared/runtimeRegistry.cjs +0 -2
  682. package/dist/runs/shared/runtimeRegistry.cjs.map +0 -1
  683. package/dist/runs/shared/runtimeRegistry.mjs +0 -2
  684. package/dist/runs/shared/runtimeRegistry.mjs.map +0 -1
  685. package/dist/runs/shared/structuredOutput.cjs +0 -2
  686. package/dist/runs/shared/structuredOutput.mjs +0 -2
  687. package/dist/runs/shared/toolAvailability.cjs +0 -2
  688. package/dist/runs/shared/toolAvailability.cjs.map +0 -1
  689. package/dist/runs/shared/toolAvailability.mjs +0 -2
  690. package/dist/runs/shared/toolAvailability.mjs.map +0 -1
  691. package/dist/runs/shared/toolBudget.cjs +0 -2
  692. package/dist/runs/shared/toolBudget.cjs.map +0 -1
  693. package/dist/runs/shared/toolBudget.mjs +0 -2
  694. package/dist/runs/shared/toolBudget.mjs.map +0 -1
  695. package/dist/shared/atomicJson.cjs.map +0 -1
  696. package/dist/shared/childTranscript.cjs.map +0 -1
  697. package/dist/shared/pollScheduler.cjs.map +0 -1
  698. package/dist/shared/scopeOwner.cjs.map +0 -1
  699. package/dist/slash/chainExpression.cjs.map +0 -1
  700. package/dist/slash/chainExpression.mjs.map +0 -1
  701. package/dist/slash/doctor.cjs +0 -5
  702. package/dist/slash/doctor.mjs +0 -5
  703. package/dist/slash/doctor.mjs.map +0 -1
  704. package/dist/slash/slashCommands.cjs.map +0 -1
  705. package/dist/slash/slashCommands.mjs.map +0 -1
  706. package/dist/slash/spawnRequestMapping.cjs.map +0 -1
  707. package/dist/slash/spawnRequestMapping.mjs.map +0 -1
  708. package/dist/slash/subagentLaunch.cjs +0 -2
  709. package/dist/slash/subagentLaunch.cjs.map +0 -1
  710. package/dist/slash/subagentLaunch.mjs +0 -2
  711. package/dist/slash/subagentLaunch.mjs.map +0 -1
  712. package/dist/types.d.cts.map +0 -1
  713. package/dist/types.d.mts.map +0 -1
  714. /package/dist/{slash → commands/slash}/chainExpression.cjs +0 -0
  715. /package/dist/{slash → commands/slash}/chainExpression.mjs +0 -0
  716. /package/dist/{slash → commands/slash}/spawnRequestMapping.cjs +0 -0
  717. /package/dist/{slash → commands/slash}/spawnRequestMapping.mjs +0 -0
  718. /package/dist/{protocol → schemas/team}/delegation.cjs +0 -0
  719. /package/dist/{protocol → schemas/team}/delegation.mjs +0 -0
  720. /package/dist/{agents → services/agents}/frontmatter.cjs +0 -0
  721. /package/dist/{intercom → services/intercom}/intercomBridge.cjs +0 -0
  722. /package/dist/{intercom → services/intercom}/intercomBridge.mjs +0 -0
  723. /package/dist/{runs → services/runs}/background/completionBatcher.cjs +0 -0
  724. /package/dist/{runs → services/runs}/background/parentWatchdog.cjs +0 -0
  725. /package/dist/{runs → services/runs}/background/parentWatchdog.mjs +0 -0
  726. /package/dist/{runs → services/runs}/registry/processGroup.cjs +0 -0
  727. /package/dist/{runs → services/runs}/registry/processGroup.mjs +0 -0
@@ -1,2 +0,0 @@
1
- const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../shared/configDir.cjs`);require(`../shared/atomicJson.cjs`);let n=require(`node:fs`);n=e.__toESM(n,1);const r={overrides:{}},i=new WeakMap;function a(e,t){i.set(e,t)}function o(e,...t){let n=i.get(e);return n?t.some(e=>n.has(e)):!1}function s(e,t){let n=i.get(e);return n&&i.set(t,n),t}function c(e){let t=[],n=[];for(let r of e??[])r.startsWith(`mcp:`)?t.push(r.slice(4)):n.push(r);return{...e===void 0?{}:{tools:n},...t.length>0?{mcpDirectTools:t}:{}}}function l(e,t){let n=e[t];if(!(!n||typeof n!=`object`||Array.isArray(n)))return n}function u(e,t){if(e===void 0)return;if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Subagent settings in '${t}' have invalid 'modelScope'; expected an object.`);let n=e,r={};if(`enforce`in n){if(typeof n.enforce!=`boolean`)throw Error(`Subagent settings in '${t}' have invalid 'modelScope.enforce'; expected a boolean.`);r.enforce=n.enforce}if(`allow`in n){if(!Array.isArray(n.allow))throw Error(`Subagent settings in '${t}' have invalid 'modelScope.allow'; expected an array of strings.`);let e=[];for(let r of n.allow){if(typeof r!=`string`)throw Error(`Subagent settings in '${t}' have invalid 'modelScope.allow'; expected an array of strings.`);let n=r.trim();n&&e.push(n)}if(e.length===0)throw Error(`Subagent settings in '${t}' have invalid 'modelScope.allow'; expected a non-empty array of patterns.`);r.allow=e}if(r.enforce===!0&&(!r.allow||r.allow.length===0))throw Error(`Subagent settings in '${t}' set modelScope.enforce without a non-empty 'allow' list; supply allowed model patterns or disable enforcement.`);return Object.keys(r).length>0?r:void 0}function d(e,t){if(e===void 0)return;if(e===!1)return!1;if(!Array.isArray(e))throw Error(`Builtin override '${t.name}' in '${t.filePath}' has invalid '${t.field}'; expected an array of strings or false.`);let n=[];for(let r of e){if(typeof r!=`string`)throw Error(`Builtin override '${t.name}' in '${t.filePath}' has invalid '${t.field}'; expected an array of strings or false.`);let e=r.trim();e&&n.push(e)}return n}function f(e,t,n){if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Builtin override '${e}' in '${n}' must be an object.`);let r=t,i={};if(`model`in r)if(typeof r.model==`string`||r.model===!1)i.model=r.model;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'model'; expected a string or false.`);if(`thinking`in r)if(typeof r.thinking==`string`||r.thinking===!1)i.thinking=r.thinking;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'thinking'; expected a string or false.`);if(`systemPromptMode`in r)if(r.systemPromptMode===`append`||r.systemPromptMode===`replace`)i.systemPromptMode=r.systemPromptMode;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'systemPromptMode'; expected 'append' or 'replace'.`);if(`inheritProjectContext`in r)if(typeof r.inheritProjectContext==`boolean`)i.inheritProjectContext=r.inheritProjectContext;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'inheritProjectContext'; expected a boolean.`);if(`inheritSkills`in r)if(typeof r.inheritSkills==`boolean`)i.inheritSkills=r.inheritSkills;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'inheritSkills'; expected a boolean.`);if(`defaultContext`in r)if(r.defaultContext===`fresh`||r.defaultContext===`fork`||r.defaultContext===!1)i.defaultContext=r.defaultContext;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'defaultContext'; expected 'fresh', 'fork', or false.`);if(`disabled`in r)if(typeof r.disabled==`boolean`)i.disabled=r.disabled;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'disabled'; expected a boolean.`);if(`completionGuard`in r)if(typeof r.completionGuard==`boolean`)i.completionGuard=r.completionGuard;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'completionGuard'; expected a boolean.`);if(`toolBudget`in r){let t=p(r.toolBudget,e,n);t!==void 0&&(i.toolBudget=t)}if(`systemPrompt`in r)if(typeof r.systemPrompt==`string`)i.systemPrompt=r.systemPrompt;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'systemPrompt'; expected a string.`);let a=t=>d(r[t],{filePath:n,name:e,field:t}),o=a(`fallbackModels`);o!==void 0&&(i.fallbackModels=o);let s=a(`skills`);s!==void 0&&(i.skills=s);let c=a(`tools`);c!==void 0&&(i.tools=c);let l=a(`extensions`);l!==void 0&&(i.extensions=l);let u=a(`subagentOnlyExtensions`);return u!==void 0&&(i.subagentOnlyExtensions=u),Object.keys(i).length>0?i:void 0}function p(e,t,n){if(e===!1)return!1;if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Builtin override '${t}' in '${n}' has invalid 'toolBudget'; expected an object or false.`);let r=e;if(typeof r.hard!=`number`)throw Error(`Builtin override '${t}' in '${n}' has invalid 'toolBudget.hard'; expected a number.`);let i={hard:r.hard};if(`soft`in r){if(typeof r.soft!=`number`)throw Error(`Builtin override '${t}' in '${n}' has invalid 'toolBudget.soft'; expected a number.`);i.soft=r.soft}if(`block`in r)if(r.block===`*`)i.block=`*`;else if(Array.isArray(r.block)&&r.block.every(e=>typeof e==`string`))i.block=[...r.block];else throw Error(`Builtin override '${t}' in '${n}' has invalid 'toolBudget.block'; expected an array of strings or '*'.`);return i}function m(e){if(!e)return r;let n=l(t.readSettingsFileStrict(e),`subagents`);if(!n)return r;let i;if(`disableBuiltins`in n)if(typeof n.disableBuiltins==`boolean`)i=n.disableBuiltins;else throw Error(`Subagent settings in '${e}' have invalid 'disableBuiltins'; expected a boolean.`);let a;if(`disableThinking`in n)if(typeof n.disableThinking==`boolean`)a=n.disableThinking;else throw Error(`Subagent settings in '${e}' have invalid 'disableThinking'; expected a boolean.`);let o;if(`defaultModel`in n)if(typeof n.defaultModel==`string`&&n.defaultModel.trim())o=n.defaultModel.trim();else throw Error(`Subagent settings in '${e}' have invalid 'defaultModel'; expected a non-empty string.`);let s;if(`defaultThinking`in n)if(typeof n.defaultThinking==`string`&&n.defaultThinking.trim())s=n.defaultThinking.trim();else throw Error(`Subagent settings in '${e}' have invalid 'defaultThinking'; expected a non-empty string.`);let c;if(`defaultExtensions`in n){let t=n.defaultExtensions;if(!Array.isArray(t)||t.some(e=>typeof e!=`string`||!e.trim()))throw Error(`Subagent settings in '${e}' have invalid 'defaultExtensions'; expected an array of non-empty strings.`);c=t.map(e=>String(e).trim())}let d=u(n.modelScope,e),p={},m=l(n,`agentOverrides`);if(m)for(let[t,n]of Object.entries(m)){let r=f(t,n,e);r&&(p[t]=r)}return{overrides:p,defaultModel:o,defaultThinking:s,defaultExtensions:c,disableBuiltins:i,disableThinking:a,modelScope:d}}function h(e,t,n,r){return r&&t.defaultModel!==void 0?{type:`subagents.defaultModel`,scope:`project`,path:r,model:t.defaultModel}:e.defaultModel===void 0?void 0:{type:`subagents.defaultModel`,scope:`user`,path:n,model:e.defaultModel}}function g(e,t){return t?e.map(e=>e.model===void 0?s(e,{...e,model:t.model,modelSource:t}):e):e}function _(e,t){return t===void 0?e:e.map(e=>e.fallbackModels===void 0?s(e,{...e,fallbackModels:[...t]}):e)}function v(e,t,n){return n&&t.defaultThinking!==void 0?t.defaultThinking:e.defaultThinking}function y(e,t){return t===void 0?e:e.map(e=>e.thinking===void 0?s(e,{...e,thinking:t}):e)}function b(e,t,n){return n&&t.defaultExtensions!==void 0?t.defaultExtensions:e.defaultExtensions}function x(e,t){return t===void 0?e:e.map(e=>e.extensions===void 0?s(e,{...e,extensions:[...t],extensionsFromDefault:!0}):e)}function S(e,t,n,r,i){return x(y(_(g(e,t),i),n),r)}function C(e){return{model:e.model,fallbackModels:e.fallbackModels?[...e.fallbackModels]:void 0,thinking:e.thinking,systemPromptMode:e.systemPromptMode,inheritProjectContext:e.inheritProjectContext,inheritSkills:e.inheritSkills,defaultContext:e.defaultContext,disabled:e.disabled,systemPrompt:e.systemPrompt,skills:e.skills?[...e.skills]:void 0,skillPath:e.skillPath?[...e.skillPath]:void 0,tools:e.tools?[...e.tools]:void 0,mcpDirectTools:e.mcpDirectTools?[...e.mcpDirectTools]:void 0,extensions:e.extensionsFromDefault?void 0:e.extensions?[...e.extensions]:void 0,subagentOnlyExtensions:e.subagentOnlyExtensions?[...e.subagentOnlyExtensions]:void 0,completionGuard:e.completionGuard,toolBudget:e.toolBudget}}function w(e,t,n){let r,i=!1,a=()=>(r??={...e},r),l=(t,n,r)=>{o(e,...n)||(a()[t]=r,i=!0)};if(t.model!==void 0&&l(`model`,[`model`],t.model===!1?void 0:t.model),t.fallbackModels!==void 0&&l(`fallbackModels`,[`fallbackModels`],t.fallbackModels===!1?void 0:[...t.fallbackModels]),t.thinking!==void 0&&l(`thinking`,[`thinking`],t.thinking===!1?void 0:t.thinking),t.systemPromptMode!==void 0&&l(`systemPromptMode`,[`systemPromptMode`],t.systemPromptMode),t.inheritProjectContext!==void 0&&l(`inheritProjectContext`,[`inheritProjectContext`],t.inheritProjectContext),t.inheritSkills!==void 0&&l(`inheritSkills`,[`inheritSkills`],t.inheritSkills),t.defaultContext!==void 0&&l(`defaultContext`,[`defaultContext`],t.defaultContext===!1?void 0:t.defaultContext),t.disabled!==void 0&&e.disabled===void 0&&(a().disabled=t.disabled,i=!0),t.skills!==void 0&&l(`skills`,[`skill`,`skills`],t.skills===!1?void 0:[...t.skills]),t.tools!==void 0&&!o(e,`tools`)){let{tools:e,mcpDirectTools:n}=c(t.tools===!1?[]:t.tools),r=a();r.tools=e,r.mcpDirectTools=n,i=!0}return t.extensions!==void 0&&l(`extensions`,[`extensions`],t.extensions===!1?void 0:[...t.extensions]),t.subagentOnlyExtensions!==void 0&&l(`subagentOnlyExtensions`,[`subagentOnlyExtensions`],t.subagentOnlyExtensions===!1?void 0:[...t.subagentOnlyExtensions]),t.completionGuard!==void 0&&l(`completionGuard`,[`completionGuard`],t.completionGuard),t.toolBudget!==void 0&&l(`toolBudget`,[`toolBudget`],t.toolBudget===!1?void 0:t.toolBudget),!i||!r?e:(r.override={...n,base:C(e)},s(e,r))}function T(e,t,n,r,i){return e.map(e=>{let a=n.overrides[e.name];if(a&&i)return w(e,a,{scope:`project`,path:i});let o=t.overrides[e.name];return o?w(e,o,{scope:`user`,path:r}):e})}exports.EMPTY_SUBAGENT_SETTINGS=r,exports.applyCustomAgentOverrides=T,exports.applySubagentDefaults=S,exports.readSubagentSettings=m,exports.resolveSubagentDefaultExtensions=b,exports.resolveSubagentDefaultModel=h,exports.resolveSubagentDefaultThinking=v,exports.setAgentFrontmatterFields=a;
2
- //# sourceMappingURL=settings.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"settings.cjs","names":["readSettingsFileStrict"],"sources":["../../src/agents/settings.ts"],"sourcesContent":["/**\n * Agent settings: reading them, and applying what they say to discovered agents.\n *\n * Two things live here because they are the same contract seen from both ends.\n * Reading turns untyped JSON on disk into settings; applying folds those\n * settings over the agents discovery found. The precedence is fixed: project\n * settings beat user settings, an explicit per-agent override beats a bulk\n * switch, and for a custom agent the agent's own frontmatter beats both.\n *\n * That last rule is why builtins and custom agents take different paths.\n * Overriding a builtin replaces values outright, because a builtin has no file\n * the user could have edited instead. Overriding a custom agent only fills\n * fields its frontmatter left unset, so a settings default never silently\n * contradicts what the author wrote in the file.\n *\n * DESIGN PATTERNS:\n * - Reading is strict and throws with the offending path and field. A settings\n * file that is quietly half-ignored is worse than one that refuses to load,\n * because the user sees agents behaving in ways their config does not explain\n * - Applying is pure and copy-on-write. Every `apply*` returns new configs and\n * never mutates its input, so a cached discovery result cannot be corrupted\n * by a later pass over it\n * - Overriding a builtin snapshots the values it replaced into `override.base`,\n * which is what makes removing the override restore the builtin exactly\n *\n * AVOID:\n * - Trusting any shape read off disk without a real guard\n * - Mutating an `AgentConfig` in place\n * - Writing a settings file non-atomically; it holds the user's overrides\n */\n\nimport * as fs from 'node:fs';\nimport { writeAtomicJson } from '../shared/atomicJson.ts';\nimport { readSettingsFileStrict } from '../shared/configDir.ts';\nimport type { ModelScopeConfig, ToolBudgetConfig } from '../types.ts';\nimport { getProjectAgentSettingsPath, getUserAgentSettingsPath } from './projectRoot.ts';\nexport { readSettingsFileStrict } from '../shared/configDir.ts';\nimport type {\n AgentConfig,\n AgentModelSourceInfo,\n BuiltinAgentOverrideBase,\n BuiltinAgentOverrideConfig,\n SubagentSettings,\n} from './types.ts';\n\nconst SUBAGENTS_SETTINGS_KEY = 'subagents';\nconst AGENT_OVERRIDES_KEY = 'agentOverrides';\n/** Prefix marking a tool the child calls on an MCP server directly. */\nconst MCP_DIRECT_TOOL_PREFIX = 'mcp:';\n\n/** Which settings file an override came from, without the value snapshot. */\ntype OverrideScopeMeta = { scope: 'user' | 'project'; path: string };\n\n/**\n * The snapshot of a builtin's pre-override values.\n *\n * Widens the contract with `mcpDirectTools` because a builtin's tool list is\n * stored split in `AgentConfig` and must round-trip through the snapshot to be\n * restorable. See the report note on `BuiltinAgentOverrideBase`.\n */\nexport interface BuiltinOverrideSnapshot extends BuiltinAgentOverrideBase {\n mcpDirectTools?: string[];\n}\n\n/**\n * Returned whenever there is nothing to read.\n *\n * Shared rather than freshly built per call because it is returned on the hot\n * discovery path for every session with no project settings file.\n */\nexport const EMPTY_SUBAGENT_SETTINGS: SubagentSettings = { overrides: {} };\n\n/**\n * Which fields of a config came from its file's frontmatter.\n *\n * Keyed by the config object rather than by agent name because configs are\n * copied on write: each `apply*` pass produces new objects, and the new one\n * inherits the entry so later passes still know what the author declared.\n * A WeakMap means a discarded config's entry is collectable with it.\n */\nconst agentFrontmatterFields = new WeakMap<AgentConfig, Set<string>>();\n\n/** Record which fields a freshly parsed config took from frontmatter. */\nexport function setAgentFrontmatterFields(agent: AgentConfig, fields: Set<string>): void {\n agentFrontmatterFields.set(agent, fields);\n}\n\n/** True when the agent's file declared any of `fields` in its frontmatter. */\nexport function agentHasFrontmatterField(agent: AgentConfig, ...fields: string[]): boolean {\n const frontmatterFields = agentFrontmatterFields.get(agent);\n return frontmatterFields ? fields.some((field) => frontmatterFields.has(field)) : false;\n}\n\n/** Carry the frontmatter record onto a copy produced by an `apply*` pass. */\nfunction inheritFrontmatterFields(source: AgentConfig, next: AgentConfig): AgentConfig {\n const frontmatterFields = agentFrontmatterFields.get(source);\n if (frontmatterFields) agentFrontmatterFields.set(next, frontmatterFields);\n return next;\n}\n\n/** Split a flat tool list into host tools and direct MCP tools. */\nfunction splitToolList(rawTools: string[] | undefined): { tools?: string[]; mcpDirectTools?: string[] } {\n const mcpDirectTools: string[] = [];\n const tools: string[] = [];\n for (const tool of rawTools ?? []) {\n if (tool.startsWith(MCP_DIRECT_TOOL_PREFIX)) mcpDirectTools.push(tool.slice(MCP_DIRECT_TOOL_PREFIX.length));\n else tools.push(tool);\n }\n return {\n ...(rawTools !== undefined ? { tools } : {}),\n ...(mcpDirectTools.length > 0 ? { mcpDirectTools } : {}),\n };\n}\n\n/** Inverse of `splitToolList`, for writing a tool list back to settings. */\nfunction joinToolList(config: { tools?: string[]; mcpDirectTools?: string[] }): string[] | undefined {\n const joined = [\n ...(config.tools ?? []),\n ...(config.mcpDirectTools ?? []).map((tool) => `${MCP_DIRECT_TOOL_PREFIX}${tool}`),\n ];\n return joined.length > 0 ? joined : undefined;\n}\n\n/** Order-sensitive equality; a reordered tool list is a real change. */\nfunction arraysEqual(a: string[] | undefined, b: string[] | undefined): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\n// ============================================================================\n// Reading\n// ============================================================================\n\n/**\n * Write a settings file atomically.\n *\n * This file holds every override the user configured. A partial write from a\n * crash mid-save would be read back as malformed on the next start and, because\n * reading is strict, would refuse to load at all.\n */\nexport function writeSettingsFile(filePath: string, settings: Record<string, unknown>): void {\n writeAtomicJson(filePath, settings);\n}\n\n/** Read a settings object at `key`, or undefined when it is absent or not an object. */\nfunction readObjectField(source: Record<string, unknown>, key: string): Record<string, unknown> | undefined {\n const value = source[key];\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;\n return value as Record<string, unknown>;\n}\n\n/** Copy a settings object at `key`, or start a fresh one when it is absent. */\nfunction cloneObjectField(source: Record<string, unknown>, key: string): Record<string, unknown> {\n // Spreading undefined is already a no-op, so no empty-object fallback is needed.\n return { ...readObjectField(source, key) };\n}\n\n/**\n * Parse the model-scope block.\n *\n * Lives here rather than beside the scope enforcement logic because parsing is\n * a settings concern and the agents domain may not reach into the runs domain.\n */\nfunction parseModelScopeConfig(value: unknown, filePath: string): ModelScopeConfig | undefined {\n if (value === undefined) return undefined;\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`Subagent settings in '${filePath}' have invalid 'modelScope'; expected an object.`);\n }\n\n const input = value as Record<string, unknown>;\n const config: ModelScopeConfig = {};\n\n if ('enforce' in input) {\n if (typeof input.enforce !== 'boolean') {\n throw new Error(`Subagent settings in '${filePath}' have invalid 'modelScope.enforce'; expected a boolean.`);\n }\n config.enforce = input.enforce;\n }\n\n if ('allow' in input) {\n if (!Array.isArray(input.allow)) {\n throw new Error(\n `Subagent settings in '${filePath}' have invalid 'modelScope.allow'; expected an array of strings.`,\n );\n }\n const allow: string[] = [];\n for (const entry of input.allow) {\n if (typeof entry !== 'string') {\n throw new Error(\n `Subagent settings in '${filePath}' have invalid 'modelScope.allow'; expected an array of strings.`,\n );\n }\n const trimmed = entry.trim();\n if (trimmed) allow.push(trimmed);\n }\n if (allow.length === 0) {\n throw new Error(\n `Subagent settings in '${filePath}' have invalid 'modelScope.allow'; expected a non-empty array of patterns.`,\n );\n }\n config.allow = allow;\n }\n\n // Enforcing against an empty allow list would reject every model, so it is\n // rejected here rather than at the point it would start failing runs.\n if (config.enforce === true && (!config.allow || config.allow.length === 0)) {\n throw new Error(\n `Subagent settings in '${filePath}' set modelScope.enforce without a non-empty 'allow' list; supply allowed model patterns or disable enforcement.`,\n );\n }\n\n return Object.keys(config).length > 0 ? config : undefined;\n}\n\n/**\n * Parse a string-array override field, which may also be `false` to clear it.\n *\n * Empty entries are dropped rather than rejected: trailing commas in a hand\n * edited list are common and unambiguous.\n */\nexport function parseOverrideStringArrayOrFalse(\n value: unknown,\n meta: { filePath: string; name: string; field: string },\n): string[] | false | undefined {\n if (value === undefined) return undefined;\n if (value === false) return false;\n if (!Array.isArray(value)) {\n throw new Error(\n `Builtin override '${meta.name}' in '${meta.filePath}' has invalid '${meta.field}'; expected an array of strings or false.`,\n );\n }\n\n const items: string[] = [];\n for (const item of value) {\n if (typeof item !== 'string') {\n throw new Error(\n `Builtin override '${meta.name}' in '${meta.filePath}' has invalid '${meta.field}'; expected an array of strings or false.`,\n );\n }\n const trimmed = item.trim();\n if (trimmed) items.push(trimmed);\n }\n return items;\n}\n\n/**\n * Parse one entry of `subagents.agentOverrides`.\n *\n * Returns undefined for an entry that declared nothing, so an empty object in\n * the file does not register as an override and mark the agent as overridden.\n */\nexport function parseBuiltinOverrideEntry(\n name: string,\n value: unknown,\n filePath: string,\n): BuiltinAgentOverrideConfig | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`Builtin override '${name}' in '${filePath}' must be an object.`);\n }\n\n const input = value as Record<string, unknown>;\n const override: BuiltinAgentOverrideConfig = {};\n\n if ('model' in input) {\n if (typeof input.model === 'string' || input.model === false) override.model = input.model;\n else\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'model'; expected a string or false.`);\n }\n\n if ('thinking' in input) {\n if (typeof input.thinking === 'string' || input.thinking === false) override.thinking = input.thinking;\n else\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'thinking'; expected a string or false.`,\n );\n }\n\n if ('systemPromptMode' in input) {\n if (input.systemPromptMode === 'append' || input.systemPromptMode === 'replace') {\n override.systemPromptMode = input.systemPromptMode;\n } else {\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'systemPromptMode'; expected 'append' or 'replace'.`,\n );\n }\n }\n\n if ('inheritProjectContext' in input) {\n if (typeof input.inheritProjectContext === 'boolean') {\n override.inheritProjectContext = input.inheritProjectContext;\n } else {\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'inheritProjectContext'; expected a boolean.`,\n );\n }\n }\n\n if ('inheritSkills' in input) {\n if (typeof input.inheritSkills === 'boolean') {\n override.inheritSkills = input.inheritSkills;\n } else {\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'inheritSkills'; expected a boolean.`);\n }\n }\n\n if ('defaultContext' in input) {\n if (input.defaultContext === 'fresh' || input.defaultContext === 'fork' || input.defaultContext === false) {\n override.defaultContext = input.defaultContext;\n } else {\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'defaultContext'; expected 'fresh', 'fork', or false.`,\n );\n }\n }\n\n if ('disabled' in input) {\n if (typeof input.disabled === 'boolean') {\n override.disabled = input.disabled;\n } else {\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'disabled'; expected a boolean.`);\n }\n }\n\n if ('completionGuard' in input) {\n if (typeof input.completionGuard === 'boolean') {\n override.completionGuard = input.completionGuard;\n } else {\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'completionGuard'; expected a boolean.`);\n }\n }\n\n if ('toolBudget' in input) {\n const toolBudget = parseToolBudgetOverride(input.toolBudget, name, filePath);\n if (toolBudget !== undefined) override.toolBudget = toolBudget;\n }\n\n if ('systemPrompt' in input) {\n if (typeof input.systemPrompt === 'string') override.systemPrompt = input.systemPrompt;\n else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'systemPrompt'; expected a string.`);\n }\n\n const parseArrayField = (field: string): string[] | false | undefined =>\n parseOverrideStringArrayOrFalse(input[field], { filePath, name, field });\n\n const fallbackModels = parseArrayField('fallbackModels');\n if (fallbackModels !== undefined) override.fallbackModels = fallbackModels;\n const skills = parseArrayField('skills');\n if (skills !== undefined) override.skills = skills;\n const tools = parseArrayField('tools');\n if (tools !== undefined) override.tools = tools;\n const extensions = parseArrayField('extensions');\n if (extensions !== undefined) override.extensions = extensions;\n const subagentOnlyExtensions = parseArrayField('subagentOnlyExtensions');\n if (subagentOnlyExtensions !== undefined) override.subagentOnlyExtensions = subagentOnlyExtensions;\n\n return Object.keys(override).length > 0 ? override : undefined;\n}\n\n/**\n * Parse a `toolBudget` override.\n *\n * `hard` is required by the contract, so an object without a usable one is\n * rejected here instead of producing a budget that never blocks.\n */\nfunction parseToolBudgetOverride(value: unknown, name: string, filePath: string): ToolBudgetConfig | false | undefined {\n if (value === false) return false;\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'toolBudget'; expected an object or false.`,\n );\n }\n\n const input = value as Record<string, unknown>;\n if (typeof input.hard !== 'number') {\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'toolBudget.hard'; expected a number.`);\n }\n\n const budget: ToolBudgetConfig = { hard: input.hard };\n if ('soft' in input) {\n if (typeof input.soft !== 'number') {\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'toolBudget.soft'; expected a number.`);\n }\n budget.soft = input.soft;\n }\n if ('block' in input) {\n if (input.block === '*') {\n budget.block = '*';\n } else if (Array.isArray(input.block) && input.block.every((entry) => typeof entry === 'string')) {\n budget.block = [...input.block];\n } else {\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'toolBudget.block'; expected an array of strings or '*'.`,\n );\n }\n }\n return budget;\n}\n\n/** Read and validate one settings file's `subagents` block. */\nexport function readSubagentSettings(filePath: string | null): SubagentSettings {\n if (!filePath) return EMPTY_SUBAGENT_SETTINGS;\n const settings = readSettingsFileStrict(filePath);\n const subagentsObject = readObjectField(settings, SUBAGENTS_SETTINGS_KEY);\n if (!subagentsObject) return EMPTY_SUBAGENT_SETTINGS;\n\n let disableBuiltins: boolean | undefined;\n if ('disableBuiltins' in subagentsObject) {\n if (typeof subagentsObject.disableBuiltins === 'boolean') {\n disableBuiltins = subagentsObject.disableBuiltins;\n } else {\n throw new Error(`Subagent settings in '${filePath}' have invalid 'disableBuiltins'; expected a boolean.`);\n }\n }\n\n let disableThinking: boolean | undefined;\n if ('disableThinking' in subagentsObject) {\n if (typeof subagentsObject.disableThinking === 'boolean') {\n disableThinking = subagentsObject.disableThinking;\n } else {\n throw new Error(`Subagent settings in '${filePath}' have invalid 'disableThinking'; expected a boolean.`);\n }\n }\n\n let defaultModel: string | undefined;\n if ('defaultModel' in subagentsObject) {\n if (typeof subagentsObject.defaultModel === 'string' && subagentsObject.defaultModel.trim()) {\n defaultModel = subagentsObject.defaultModel.trim();\n } else {\n throw new Error(`Subagent settings in '${filePath}' have invalid 'defaultModel'; expected a non-empty string.`);\n }\n }\n\n let defaultThinking: string | undefined;\n if ('defaultThinking' in subagentsObject) {\n if (typeof subagentsObject.defaultThinking === 'string' && subagentsObject.defaultThinking.trim()) {\n defaultThinking = subagentsObject.defaultThinking.trim();\n } else {\n throw new Error(\n `Subagent settings in '${filePath}' have invalid 'defaultThinking'; expected a non-empty string.`,\n );\n }\n }\n\n let defaultExtensions: string[] | undefined;\n if ('defaultExtensions' in subagentsObject) {\n const raw = subagentsObject.defaultExtensions;\n if (!Array.isArray(raw) || raw.some((item) => typeof item !== 'string' || !item.trim())) {\n throw new Error(\n `Subagent settings in '${filePath}' have invalid 'defaultExtensions'; expected an array of non-empty strings.`,\n );\n }\n defaultExtensions = raw.map((item) => String(item).trim());\n }\n\n const modelScope = parseModelScopeConfig(subagentsObject.modelScope, filePath);\n\n const overrides: Record<string, BuiltinAgentOverrideConfig> = {};\n const agentOverrides = readObjectField(subagentsObject, AGENT_OVERRIDES_KEY);\n if (agentOverrides) {\n for (const [name, value] of Object.entries(agentOverrides)) {\n const override = parseBuiltinOverrideEntry(name, value, filePath);\n if (override) overrides[name] = override;\n }\n }\n\n return { overrides, defaultModel, defaultThinking, defaultExtensions, disableBuiltins, disableThinking, modelScope };\n}\n\n// ============================================================================\n// Settings-level defaults\n// ============================================================================\n\n/** Which settings file supplies `defaultModel`, project winning over user. */\nexport function resolveSubagentDefaultModel(\n userSettings: SubagentSettings,\n projectSettings: SubagentSettings,\n userSettingsPath: string,\n projectSettingsPath: string | null,\n): AgentModelSourceInfo | undefined {\n if (projectSettingsPath && projectSettings.defaultModel !== undefined) {\n return {\n type: 'subagents.defaultModel',\n scope: 'project',\n path: projectSettingsPath,\n model: projectSettings.defaultModel,\n };\n }\n return userSettings.defaultModel !== undefined\n ? { type: 'subagents.defaultModel', scope: 'user', path: userSettingsPath, model: userSettings.defaultModel }\n : undefined;\n}\n\n/**\n * Fill in the default model for agents that declared none.\n *\n * `modelSource` is recorded alongside so callers can tell an inherited model\n * from a requested one, which decides how hard model-scope enforcement bites.\n */\nexport function applySubagentDefaultModel(\n agents: AgentConfig[],\n defaultModel: AgentModelSourceInfo | undefined,\n): AgentConfig[] {\n if (!defaultModel) return agents;\n return agents.map((agent) => {\n if (agent.model !== undefined) return agent;\n return inheritFrontmatterFields(agent, { ...agent, model: defaultModel.model, modelSource: defaultModel });\n });\n}\n\n/** Fill in fallback models only when the agent declared no fallback policy. */\nexport function applySubagentDefaultFallbackModels(\n agents: AgentConfig[],\n fallbackModels: string[] | undefined,\n): AgentConfig[] {\n if (fallbackModels === undefined) return agents;\n return agents.map((agent) => {\n if (agent.fallbackModels !== undefined) return agent;\n return inheritFrontmatterFields(agent, { ...agent, fallbackModels: [...fallbackModels] });\n });\n}\n\nexport function resolveSubagentDefaultThinking(\n userSettings: SubagentSettings,\n projectSettings: SubagentSettings,\n projectSettingsPath: string | null,\n): string | undefined {\n if (projectSettingsPath && projectSettings.defaultThinking !== undefined) return projectSettings.defaultThinking;\n return userSettings.defaultThinking;\n}\n\nexport function applySubagentDefaultThinking(\n agents: AgentConfig[],\n defaultThinking: string | undefined,\n): AgentConfig[] {\n if (defaultThinking === undefined) return agents;\n return agents.map((agent) => {\n if (agent.thinking !== undefined) return agent;\n return inheritFrontmatterFields(agent, { ...agent, thinking: defaultThinking });\n });\n}\n\nexport function resolveSubagentDefaultExtensions(\n userSettings: SubagentSettings,\n projectSettings: SubagentSettings,\n projectSettingsPath: string | null,\n): string[] | undefined {\n if (projectSettingsPath && projectSettings.defaultExtensions !== undefined) return projectSettings.defaultExtensions;\n return userSettings.defaultExtensions;\n}\n\n/**\n * Fill in default extensions for agents that declared none.\n *\n * The `extensionsFromDefault` flag matters when the agent is later overridden:\n * a snapshot must not record a settings default as if the builtin had declared\n * it, or removing the override would bake the default in permanently.\n */\nexport function applySubagentDefaultExtensions(\n agents: AgentConfig[],\n defaultExtensions: string[] | undefined,\n): AgentConfig[] {\n if (defaultExtensions === undefined) return agents;\n return agents.map((agent) => {\n if (agent.extensions !== undefined) return agent;\n return inheritFrontmatterFields(agent, {\n ...agent,\n extensions: [...defaultExtensions],\n extensionsFromDefault: true,\n });\n });\n}\n\nexport function applySubagentDefaults(\n agents: AgentConfig[],\n defaultModel: AgentModelSourceInfo | undefined,\n defaultThinking: string | undefined,\n defaultExtensions: string[] | undefined,\n defaultFallbackModels?: string[],\n): AgentConfig[] {\n return applySubagentDefaultExtensions(\n applySubagentDefaultThinking(\n applySubagentDefaultFallbackModels(applySubagentDefaultModel(agents, defaultModel), defaultFallbackModels),\n defaultThinking,\n ),\n defaultExtensions,\n );\n}\n\n// ============================================================================\n// Override snapshots\n// ============================================================================\n\n/**\n * Snapshot the fields an override may replace, so it can be undone.\n *\n * `extensions` is omitted when it came from a settings default rather than the\n * agent itself; restoring it would turn a default into a permanent value.\n */\nexport function cloneOverrideBase(agent: AgentConfig): BuiltinOverrideSnapshot {\n return {\n model: agent.model,\n fallbackModels: agent.fallbackModels ? [...agent.fallbackModels] : undefined,\n thinking: agent.thinking,\n systemPromptMode: agent.systemPromptMode,\n inheritProjectContext: agent.inheritProjectContext,\n inheritSkills: agent.inheritSkills,\n defaultContext: agent.defaultContext,\n disabled: agent.disabled,\n systemPrompt: agent.systemPrompt,\n skills: agent.skills ? [...agent.skills] : undefined,\n skillPath: agent.skillPath ? [...agent.skillPath] : undefined,\n tools: agent.tools ? [...agent.tools] : undefined,\n mcpDirectTools: agent.mcpDirectTools ? [...agent.mcpDirectTools] : undefined,\n extensions: agent.extensionsFromDefault ? undefined : agent.extensions ? [...agent.extensions] : undefined,\n subagentOnlyExtensions: agent.subagentOnlyExtensions ? [...agent.subagentOnlyExtensions] : undefined,\n completionGuard: agent.completionGuard,\n toolBudget: agent.toolBudget,\n };\n}\n\n/**\n * Deep-copy an override before it is written to a settings file.\n *\n * Only keys the caller actually set are copied, because an explicit `undefined`\n * would serialise the key away and read back as \"not overridden\".\n */\nexport function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentOverrideConfig {\n return {\n ...(override.model !== undefined ? { model: override.model } : {}),\n ...(override.fallbackModels !== undefined\n ? { fallbackModels: override.fallbackModels === false ? false : [...override.fallbackModels] }\n : {}),\n ...(override.thinking !== undefined ? { thinking: override.thinking } : {}),\n ...(override.systemPromptMode !== undefined ? { systemPromptMode: override.systemPromptMode } : {}),\n ...(override.inheritProjectContext !== undefined ? { inheritProjectContext: override.inheritProjectContext } : {}),\n ...(override.inheritSkills !== undefined ? { inheritSkills: override.inheritSkills } : {}),\n ...(override.defaultContext !== undefined ? { defaultContext: override.defaultContext } : {}),\n ...(override.disabled !== undefined ? { disabled: override.disabled } : {}),\n ...(override.systemPrompt !== undefined ? { systemPrompt: override.systemPrompt } : {}),\n ...(override.skills !== undefined ? { skills: override.skills === false ? false : [...override.skills] } : {}),\n ...(override.tools !== undefined ? { tools: override.tools === false ? false : [...override.tools] } : {}),\n ...(override.extensions !== undefined\n ? { extensions: override.extensions === false ? false : [...override.extensions] }\n : {}),\n ...(override.subagentOnlyExtensions !== undefined\n ? {\n subagentOnlyExtensions:\n override.subagentOnlyExtensions === false ? false : [...override.subagentOnlyExtensions],\n }\n : {}),\n ...(override.completionGuard !== undefined ? { completionGuard: override.completionGuard } : {}),\n ...(override.toolBudget !== undefined\n ? {\n toolBudget:\n override.toolBudget === false\n ? false\n : {\n ...override.toolBudget,\n ...(Array.isArray(override.toolBudget.block) ? { block: [...override.toolBudget.block] } : {}),\n },\n }\n : {}),\n };\n}\n\n// ============================================================================\n// Applying overrides\n// ============================================================================\n\n/**\n * Replace a builtin's values with an override's.\n *\n * `false` clears a field rather than setting it to false; that distinction is\n * the whole reason the stored shape differs from the snapshot shape.\n */\nexport function applyBuiltinOverride(\n agent: AgentConfig,\n override: BuiltinAgentOverrideConfig,\n meta: OverrideScopeMeta,\n): AgentConfig {\n const next: AgentConfig = { ...agent, override: { ...meta, base: cloneOverrideBase(agent) } };\n\n if (override.model !== undefined) next.model = override.model === false ? undefined : override.model;\n if (override.fallbackModels !== undefined) {\n next.fallbackModels = override.fallbackModels === false ? undefined : [...override.fallbackModels];\n }\n if (override.thinking !== undefined) next.thinking = override.thinking === false ? undefined : override.thinking;\n if (override.systemPromptMode !== undefined) next.systemPromptMode = override.systemPromptMode;\n if (override.inheritProjectContext !== undefined) next.inheritProjectContext = override.inheritProjectContext;\n if (override.inheritSkills !== undefined) next.inheritSkills = override.inheritSkills;\n if (override.defaultContext !== undefined) {\n next.defaultContext = override.defaultContext === false ? undefined : override.defaultContext;\n }\n if (override.disabled !== undefined) next.disabled = override.disabled;\n if (override.systemPrompt !== undefined) next.systemPrompt = override.systemPrompt;\n if (override.skills !== undefined) next.skills = override.skills === false ? undefined : [...override.skills];\n if (override.tools !== undefined) {\n const { tools, mcpDirectTools } = splitToolList(override.tools === false ? [] : override.tools);\n next.tools = tools;\n next.mcpDirectTools = mcpDirectTools;\n }\n if (override.extensions !== undefined) {\n next.extensions = override.extensions === false ? undefined : [...override.extensions];\n }\n if (override.subagentOnlyExtensions !== undefined) {\n next.subagentOnlyExtensions =\n override.subagentOnlyExtensions === false ? undefined : [...override.subagentOnlyExtensions];\n }\n if (override.completionGuard !== undefined) next.completionGuard = override.completionGuard;\n if (override.toolBudget !== undefined) {\n next.toolBudget = override.toolBudget === false ? undefined : override.toolBudget;\n }\n\n return next;\n}\n\n/**\n * Strip an agent's thinking level for the bulk `disableThinking` switch.\n *\n * An existing `override` is kept rather than replaced, so a per-agent override\n * remains the recorded reason the agent differs from its builtin definition.\n */\nexport function clearBuiltinThinking(agent: AgentConfig, meta: OverrideScopeMeta): AgentConfig {\n if (agent.thinking === undefined) return agent;\n return { ...agent, thinking: undefined, override: agent.override ?? { ...meta, base: cloneOverrideBase(agent) } };\n}\n\n/**\n * Apply user and project settings to the builtin agents.\n *\n * Precedence per agent: a project override, then the project bulk disable, then\n * a user override, then the user bulk disable. A project file that sets\n * `disableBuiltins` at all (including to false) shadows the user's switch, so a\n * project can re-enable builtins its user settings turned off.\n */\nexport function applyBuiltinOverrides(\n builtinAgents: AgentConfig[],\n userSettings: SubagentSettings,\n projectSettings: SubagentSettings,\n userSettingsPath: string,\n projectSettingsPath: string | null,\n): AgentConfig[] {\n const projectBulkDisabled = projectSettings.disableBuiltins === true && projectSettingsPath !== null;\n const userBulkDisabled = projectSettings.disableBuiltins === undefined && userSettings.disableBuiltins === true;\n const projectThinkingConfigured = projectSettings.disableThinking !== undefined && projectSettingsPath !== null;\n const disableThinking = projectThinkingConfigured\n ? projectSettings.disableThinking === true\n : userSettings.disableThinking === true;\n const disableThinkingMeta: OverrideScopeMeta =\n projectThinkingConfigured && projectSettingsPath\n ? { scope: 'project', path: projectSettingsPath }\n : { scope: 'user', path: userSettingsPath };\n\n // A per-agent thinking override is more specific than the bulk switch, so it\n // survives it; everything else is cleared.\n const applyGlobalThinking = (agent: AgentConfig, hasExplicitThinkingOverride: boolean): AgentConfig => {\n if (!disableThinking || hasExplicitThinkingOverride) return agent;\n return clearBuiltinThinking(agent, disableThinkingMeta);\n };\n\n return builtinAgents.map((agent) => {\n const projectOverride = projectSettings.overrides[agent.name];\n if (projectOverride && projectSettingsPath) {\n return applyGlobalThinking(\n applyBuiltinOverride(agent, projectOverride, { scope: 'project', path: projectSettingsPath }),\n projectOverride.thinking !== undefined,\n );\n }\n\n if (projectBulkDisabled && projectSettingsPath) {\n return applyGlobalThinking(\n applyBuiltinOverride(agent, { disabled: true }, { scope: 'project', path: projectSettingsPath }),\n false,\n );\n }\n\n const userOverride = userSettings.overrides[agent.name];\n if (userOverride) {\n return applyGlobalThinking(\n applyBuiltinOverride(agent, userOverride, { scope: 'user', path: userSettingsPath }),\n !projectThinkingConfigured && userOverride.thinking !== undefined,\n );\n }\n\n if (userBulkDisabled) {\n return applyGlobalThinking(\n applyBuiltinOverride(agent, { disabled: true }, { scope: 'user', path: userSettingsPath }),\n false,\n );\n }\n\n return applyGlobalThinking(agent, false);\n });\n}\n\n/**\n * Apply an override to a custom agent, filling only unset fields.\n *\n * A custom agent has a file the user could have edited, so a settings value\n * must never contradict its frontmatter. Nothing is copied and no `override`\n * is recorded unless at least one field was actually filled, which keeps agents\n * that declared everything from being reported as overridden.\n */\nexport function applyCustomAgentOverride(\n agent: AgentConfig,\n override: BuiltinAgentOverrideConfig,\n meta: OverrideScopeMeta,\n): AgentConfig {\n let next: AgentConfig | undefined;\n let anyFilled = false;\n\n const mutable = (): AgentConfig => {\n next ??= { ...agent };\n return next;\n };\n\n const fill = <K extends keyof AgentConfig>(field: K, frontmatterFields: string[], value: AgentConfig[K]): void => {\n if (agentHasFrontmatterField(agent, ...frontmatterFields)) return;\n mutable()[field] = value;\n anyFilled = true;\n };\n\n if (override.model !== undefined) {\n fill('model', ['model'], override.model === false ? undefined : override.model);\n }\n if (override.fallbackModels !== undefined) {\n fill(\n 'fallbackModels',\n ['fallbackModels'],\n override.fallbackModels === false ? undefined : [...override.fallbackModels],\n );\n }\n if (override.thinking !== undefined) {\n fill('thinking', ['thinking'], override.thinking === false ? undefined : override.thinking);\n }\n if (override.systemPromptMode !== undefined) {\n fill('systemPromptMode', ['systemPromptMode'], override.systemPromptMode);\n }\n if (override.inheritProjectContext !== undefined) {\n fill('inheritProjectContext', ['inheritProjectContext'], override.inheritProjectContext);\n }\n if (override.inheritSkills !== undefined) {\n fill('inheritSkills', ['inheritSkills'], override.inheritSkills);\n }\n if (override.defaultContext !== undefined) {\n fill('defaultContext', ['defaultContext'], override.defaultContext === false ? undefined : override.defaultContext);\n }\n if (override.disabled !== undefined && agent.disabled === undefined) {\n mutable().disabled = override.disabled;\n anyFilled = true;\n }\n if (override.skills !== undefined) {\n fill('skills', ['skill', 'skills'], override.skills === false ? undefined : [...override.skills]);\n }\n if (override.tools !== undefined && !agentHasFrontmatterField(agent, 'tools')) {\n const { tools, mcpDirectTools } = splitToolList(override.tools === false ? [] : override.tools);\n const target = mutable();\n target.tools = tools;\n target.mcpDirectTools = mcpDirectTools;\n anyFilled = true;\n }\n if (override.extensions !== undefined) {\n fill('extensions', ['extensions'], override.extensions === false ? undefined : [...override.extensions]);\n }\n if (override.subagentOnlyExtensions !== undefined) {\n fill(\n 'subagentOnlyExtensions',\n ['subagentOnlyExtensions'],\n override.subagentOnlyExtensions === false ? undefined : [...override.subagentOnlyExtensions],\n );\n }\n if (override.completionGuard !== undefined) {\n fill('completionGuard', ['completionGuard'], override.completionGuard);\n }\n if (override.toolBudget !== undefined) {\n fill('toolBudget', ['toolBudget'], override.toolBudget === false ? undefined : override.toolBudget);\n }\n\n if (!anyFilled || !next) return agent;\n next.override = { ...meta, base: cloneOverrideBase(agent) };\n return inheritFrontmatterFields(agent, next);\n}\n\nexport function applyCustomAgentOverrides(\n agents: AgentConfig[],\n userSettings: SubagentSettings,\n projectSettings: SubagentSettings,\n userSettingsPath: string,\n projectSettingsPath: string | null,\n): AgentConfig[] {\n return agents.map((agent) => {\n const projectOverride = projectSettings.overrides[agent.name];\n if (projectOverride && projectSettingsPath) {\n return applyCustomAgentOverride(agent, projectOverride, { scope: 'project', path: projectSettingsPath });\n }\n\n const userOverride = userSettings.overrides[agent.name];\n if (userOverride) {\n return applyCustomAgentOverride(agent, userOverride, { scope: 'user', path: userSettingsPath });\n }\n\n return agent;\n });\n}\n\n/**\n * Diff an edited agent against its pre-override snapshot.\n *\n * Only changed fields are written, so a settings file records the user's edits\n * rather than a full copy of the builtin that would drift as the builtin does.\n * Returns undefined when nothing changed, which callers treat as \"remove the\n * override\" rather than \"write an empty one\".\n */\nexport function buildBuiltinOverrideConfig(\n base: BuiltinOverrideSnapshot,\n draft: Pick<\n AgentConfig,\n | 'model'\n | 'fallbackModels'\n | 'thinking'\n | 'systemPromptMode'\n | 'inheritProjectContext'\n | 'inheritSkills'\n | 'defaultContext'\n | 'disabled'\n | 'systemPrompt'\n | 'skills'\n | 'tools'\n | 'mcpDirectTools'\n | 'extensions'\n | 'subagentOnlyExtensions'\n | 'completionGuard'\n | 'toolBudget'\n >,\n): BuiltinAgentOverrideConfig | undefined {\n const override: BuiltinAgentOverrideConfig = {};\n\n if (draft.model !== base.model) override.model = draft.model ?? false;\n if (!arraysEqual(draft.fallbackModels, base.fallbackModels)) {\n override.fallbackModels = draft.fallbackModels ? [...draft.fallbackModels] : false;\n }\n if (draft.thinking !== base.thinking) override.thinking = draft.thinking ?? false;\n if (draft.systemPromptMode !== base.systemPromptMode) override.systemPromptMode = draft.systemPromptMode;\n if (draft.inheritProjectContext !== base.inheritProjectContext) {\n override.inheritProjectContext = draft.inheritProjectContext;\n }\n if (draft.inheritSkills !== base.inheritSkills) override.inheritSkills = draft.inheritSkills;\n if (draft.defaultContext !== base.defaultContext) override.defaultContext = draft.defaultContext ?? false;\n if (draft.disabled !== base.disabled) override.disabled = draft.disabled ?? false;\n if (draft.systemPrompt !== base.systemPrompt) override.systemPrompt = draft.systemPrompt;\n if (!arraysEqual(draft.skills, base.skills)) override.skills = draft.skills ? [...draft.skills] : false;\n\n const baseTools = joinToolList(base);\n const draftTools = joinToolList(draft);\n if (!arraysEqual(draftTools, baseTools)) override.tools = draftTools ? [...draftTools] : false;\n if (!arraysEqual(draft.extensions, base.extensions)) {\n override.extensions = draft.extensions ? [...draft.extensions] : false;\n }\n if (!arraysEqual(draft.subagentOnlyExtensions, base.subagentOnlyExtensions)) {\n override.subagentOnlyExtensions = draft.subagentOnlyExtensions ? [...draft.subagentOnlyExtensions] : false;\n }\n // Compared as booleans because an unset guard and an enabled one behave the\n // same, so only a switch to or from explicitly disabled is a real change.\n if ((draft.completionGuard !== false) !== (base.completionGuard !== false)) {\n override.completionGuard = draft.completionGuard !== false;\n }\n if (JSON.stringify(draft.toolBudget) !== JSON.stringify(base.toolBudget)) {\n override.toolBudget = draft.toolBudget ?? false;\n }\n\n return Object.keys(override).length > 0 ? override : undefined;\n}\n\n// ============================================================================\n// Persisting overrides\n// ============================================================================\n\nconst NO_PROJECT_ROOT_MESSAGE = 'Project override is not available here. No project config root was found.';\n\n/** Resolve the settings file for a scope, or throw when there is no project. */\nfunction requireSettingsPath(cwd: string, scope: 'user' | 'project'): string {\n const filePath = scope === 'project' ? getProjectAgentSettingsPath(cwd) : getUserAgentSettingsPath();\n if (!filePath) throw new Error(NO_PROJECT_ROOT_MESSAGE);\n return filePath;\n}\n\n/** Write an override, replacing any existing entry for the agent wholesale. */\nexport function saveBuiltinAgentOverride(\n cwd: string,\n name: string,\n scope: 'user' | 'project',\n override: BuiltinAgentOverrideConfig,\n): string {\n const filePath = requireSettingsPath(cwd, scope);\n\n const settings = readSettingsFileStrict(filePath);\n const subagents = cloneObjectField(settings, SUBAGENTS_SETTINGS_KEY);\n const agentOverrides = cloneObjectField(subagents, AGENT_OVERRIDES_KEY);\n\n agentOverrides[name] = cloneOverrideValue(override);\n subagents[AGENT_OVERRIDES_KEY] = agentOverrides;\n settings[SUBAGENTS_SETTINGS_KEY] = subagents;\n writeSettingsFile(filePath, settings);\n return filePath;\n}\n\n/**\n * Drop an agent's whole override entry.\n *\n * Emptied containers are deleted rather than left behind, so removing the last\n * override leaves the settings file as it was before any were added.\n */\nexport function removeBuiltinAgentOverride(\n cwd: string,\n name: string,\n scope: 'user' | 'project',\n): { path: string; removed: boolean } {\n const filePath = requireSettingsPath(cwd, scope);\n if (!fs.existsSync(filePath)) return { path: filePath, removed: false };\n\n const settings = readSettingsFileStrict(filePath);\n const subagents = readObjectField(settings, SUBAGENTS_SETTINGS_KEY);\n if (!subagents) return { path: filePath, removed: false };\n const agentOverrides = readObjectField(subagents, AGENT_OVERRIDES_KEY);\n if (!agentOverrides) return { path: filePath, removed: false };\n if (!Object.hasOwn(agentOverrides, name)) return { path: filePath, removed: false };\n\n const nextSubagents = { ...subagents };\n const nextOverrides = { ...agentOverrides };\n delete nextOverrides[name];\n if (Object.keys(nextOverrides).length > 0) nextSubagents[AGENT_OVERRIDES_KEY] = nextOverrides;\n else delete nextSubagents[AGENT_OVERRIDES_KEY];\n\n if (Object.keys(nextSubagents).length > 0) settings[SUBAGENTS_SETTINGS_KEY] = nextSubagents;\n else delete settings[SUBAGENTS_SETTINGS_KEY];\n\n writeSettingsFile(filePath, settings);\n return { path: filePath, removed: true };\n}\n\n/** Merge fields into an agent's existing override, leaving the rest in place. */\nexport function mergeBuiltinAgentOverride(\n cwd: string,\n name: string,\n scope: 'user' | 'project',\n fields: BuiltinAgentOverrideConfig,\n): string {\n const filePath = requireSettingsPath(cwd, scope);\n\n const settings = readSettingsFileStrict(filePath);\n const subagents = cloneObjectField(settings, SUBAGENTS_SETTINGS_KEY);\n const agentOverrides = cloneObjectField(subagents, AGENT_OVERRIDES_KEY);\n\n const existing = readObjectField(agentOverrides, name) ?? {};\n agentOverrides[name] = { ...existing, ...cloneOverrideValue(fields) };\n subagents[AGENT_OVERRIDES_KEY] = agentOverrides;\n settings[SUBAGENTS_SETTINGS_KEY] = subagents;\n writeSettingsFile(filePath, settings);\n return filePath;\n}\n\n/** Remove named fields from an agent's override, dropping it once empty. */\nexport function removeBuiltinAgentOverrideFields(\n cwd: string,\n name: string,\n scope: 'user' | 'project',\n fields: string[],\n): { path: string; removed: boolean } {\n const filePath = requireSettingsPath(cwd, scope);\n if (!fs.existsSync(filePath)) return { path: filePath, removed: false };\n\n const settings = readSettingsFileStrict(filePath);\n const subagents = readObjectField(settings, SUBAGENTS_SETTINGS_KEY);\n if (!subagents) return { path: filePath, removed: false };\n const agentOverrides = readObjectField(subagents, AGENT_OVERRIDES_KEY);\n if (!agentOverrides) return { path: filePath, removed: false };\n const entry = readObjectField(agentOverrides, name);\n if (!entry) return { path: filePath, removed: false };\n\n const nextEntry: Record<string, unknown> = { ...entry };\n let removed = false;\n for (const field of fields) {\n if (Object.hasOwn(nextEntry, field)) {\n delete nextEntry[field];\n removed = true;\n }\n }\n if (!removed) return { path: filePath, removed: false };\n\n const nextSubagents = { ...subagents };\n const nextOverrides = { ...agentOverrides };\n if (Object.keys(nextEntry).length > 0) {\n nextOverrides[name] = nextEntry;\n nextSubagents[AGENT_OVERRIDES_KEY] = nextOverrides;\n } else {\n delete nextOverrides[name];\n if (Object.keys(nextOverrides).length > 0) nextSubagents[AGENT_OVERRIDES_KEY] = nextOverrides;\n else delete nextSubagents[AGENT_OVERRIDES_KEY];\n }\n if (Object.keys(nextSubagents).length > 0) settings[SUBAGENTS_SETTINGS_KEY] = nextSubagents;\n else delete settings[SUBAGENTS_SETTINGS_KEY];\n\n writeSettingsFile(filePath, settings);\n return { path: filePath, removed: true };\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{__esmMin as e}from"../_virtual/_rolldown/runtime.mjs";import{init_configDir as t,readSettingsFileStrict as n}from"../shared/configDir.mjs";import{init_atomicJson as r}from"../shared/atomicJson.mjs";function i(e,t){k.set(e,t)}function a(e,...t){let n=k.get(e);return n?t.some(e=>n.has(e)):!1}function o(e,t){let n=k.get(e);return n&&k.set(t,n),t}function s(e){let t=[],n=[];for(let r of e??[])r.startsWith(D)?t.push(r.slice(4)):n.push(r);return{...e===void 0?{}:{tools:n},...t.length>0?{mcpDirectTools:t}:{}}}function c(e,t){let n=e[t];if(!(!n||typeof n!=`object`||Array.isArray(n)))return n}function l(e,t){if(e===void 0)return;if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Subagent settings in '${t}' have invalid 'modelScope'; expected an object.`);let n=e,r={};if(`enforce`in n){if(typeof n.enforce!=`boolean`)throw Error(`Subagent settings in '${t}' have invalid 'modelScope.enforce'; expected a boolean.`);r.enforce=n.enforce}if(`allow`in n){if(!Array.isArray(n.allow))throw Error(`Subagent settings in '${t}' have invalid 'modelScope.allow'; expected an array of strings.`);let e=[];for(let r of n.allow){if(typeof r!=`string`)throw Error(`Subagent settings in '${t}' have invalid 'modelScope.allow'; expected an array of strings.`);let n=r.trim();n&&e.push(n)}if(e.length===0)throw Error(`Subagent settings in '${t}' have invalid 'modelScope.allow'; expected a non-empty array of patterns.`);r.allow=e}if(r.enforce===!0&&(!r.allow||r.allow.length===0))throw Error(`Subagent settings in '${t}' set modelScope.enforce without a non-empty 'allow' list; supply allowed model patterns or disable enforcement.`);return Object.keys(r).length>0?r:void 0}function u(e,t){if(e===void 0)return;if(e===!1)return!1;if(!Array.isArray(e))throw Error(`Builtin override '${t.name}' in '${t.filePath}' has invalid '${t.field}'; expected an array of strings or false.`);let n=[];for(let r of e){if(typeof r!=`string`)throw Error(`Builtin override '${t.name}' in '${t.filePath}' has invalid '${t.field}'; expected an array of strings or false.`);let e=r.trim();e&&n.push(e)}return n}function d(e,t,n){if(!t||typeof t!=`object`||Array.isArray(t))throw Error(`Builtin override '${e}' in '${n}' must be an object.`);let r=t,i={};if(`model`in r)if(typeof r.model==`string`||r.model===!1)i.model=r.model;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'model'; expected a string or false.`);if(`thinking`in r)if(typeof r.thinking==`string`||r.thinking===!1)i.thinking=r.thinking;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'thinking'; expected a string or false.`);if(`systemPromptMode`in r)if(r.systemPromptMode===`append`||r.systemPromptMode===`replace`)i.systemPromptMode=r.systemPromptMode;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'systemPromptMode'; expected 'append' or 'replace'.`);if(`inheritProjectContext`in r)if(typeof r.inheritProjectContext==`boolean`)i.inheritProjectContext=r.inheritProjectContext;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'inheritProjectContext'; expected a boolean.`);if(`inheritSkills`in r)if(typeof r.inheritSkills==`boolean`)i.inheritSkills=r.inheritSkills;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'inheritSkills'; expected a boolean.`);if(`defaultContext`in r)if(r.defaultContext===`fresh`||r.defaultContext===`fork`||r.defaultContext===!1)i.defaultContext=r.defaultContext;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'defaultContext'; expected 'fresh', 'fork', or false.`);if(`disabled`in r)if(typeof r.disabled==`boolean`)i.disabled=r.disabled;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'disabled'; expected a boolean.`);if(`completionGuard`in r)if(typeof r.completionGuard==`boolean`)i.completionGuard=r.completionGuard;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'completionGuard'; expected a boolean.`);if(`toolBudget`in r){let t=f(r.toolBudget,e,n);t!==void 0&&(i.toolBudget=t)}if(`systemPrompt`in r)if(typeof r.systemPrompt==`string`)i.systemPrompt=r.systemPrompt;else throw Error(`Builtin override '${e}' in '${n}' has invalid 'systemPrompt'; expected a string.`);let a=t=>u(r[t],{filePath:n,name:e,field:t}),o=a(`fallbackModels`);o!==void 0&&(i.fallbackModels=o);let s=a(`skills`);s!==void 0&&(i.skills=s);let c=a(`tools`);c!==void 0&&(i.tools=c);let l=a(`extensions`);l!==void 0&&(i.extensions=l);let d=a(`subagentOnlyExtensions`);return d!==void 0&&(i.subagentOnlyExtensions=d),Object.keys(i).length>0?i:void 0}function f(e,t,n){if(e===!1)return!1;if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Builtin override '${t}' in '${n}' has invalid 'toolBudget'; expected an object or false.`);let r=e;if(typeof r.hard!=`number`)throw Error(`Builtin override '${t}' in '${n}' has invalid 'toolBudget.hard'; expected a number.`);let i={hard:r.hard};if(`soft`in r){if(typeof r.soft!=`number`)throw Error(`Builtin override '${t}' in '${n}' has invalid 'toolBudget.soft'; expected a number.`);i.soft=r.soft}if(`block`in r)if(r.block===`*`)i.block=`*`;else if(Array.isArray(r.block)&&r.block.every(e=>typeof e==`string`))i.block=[...r.block];else throw Error(`Builtin override '${t}' in '${n}' has invalid 'toolBudget.block'; expected an array of strings or '*'.`);return i}function p(e){if(!e)return O;let t=c(n(e),T);if(!t)return O;let r;if(`disableBuiltins`in t)if(typeof t.disableBuiltins==`boolean`)r=t.disableBuiltins;else throw Error(`Subagent settings in '${e}' have invalid 'disableBuiltins'; expected a boolean.`);let i;if(`disableThinking`in t)if(typeof t.disableThinking==`boolean`)i=t.disableThinking;else throw Error(`Subagent settings in '${e}' have invalid 'disableThinking'; expected a boolean.`);let a;if(`defaultModel`in t)if(typeof t.defaultModel==`string`&&t.defaultModel.trim())a=t.defaultModel.trim();else throw Error(`Subagent settings in '${e}' have invalid 'defaultModel'; expected a non-empty string.`);let o;if(`defaultThinking`in t)if(typeof t.defaultThinking==`string`&&t.defaultThinking.trim())o=t.defaultThinking.trim();else throw Error(`Subagent settings in '${e}' have invalid 'defaultThinking'; expected a non-empty string.`);let s;if(`defaultExtensions`in t){let n=t.defaultExtensions;if(!Array.isArray(n)||n.some(e=>typeof e!=`string`||!e.trim()))throw Error(`Subagent settings in '${e}' have invalid 'defaultExtensions'; expected an array of non-empty strings.`);s=n.map(e=>String(e).trim())}let u=l(t.modelScope,e),f={},p=c(t,E);if(p)for(let[t,n]of Object.entries(p)){let r=d(t,n,e);r&&(f[t]=r)}return{overrides:f,defaultModel:a,defaultThinking:o,defaultExtensions:s,disableBuiltins:r,disableThinking:i,modelScope:u}}function m(e,t,n,r){return r&&t.defaultModel!==void 0?{type:`subagents.defaultModel`,scope:`project`,path:r,model:t.defaultModel}:e.defaultModel===void 0?void 0:{type:`subagents.defaultModel`,scope:`user`,path:n,model:e.defaultModel}}function h(e,t){return t?e.map(e=>e.model===void 0?o(e,{...e,model:t.model,modelSource:t}):e):e}function g(e,t){return t===void 0?e:e.map(e=>e.fallbackModels===void 0?o(e,{...e,fallbackModels:[...t]}):e)}function _(e,t,n){return n&&t.defaultThinking!==void 0?t.defaultThinking:e.defaultThinking}function v(e,t){return t===void 0?e:e.map(e=>e.thinking===void 0?o(e,{...e,thinking:t}):e)}function y(e,t,n){return n&&t.defaultExtensions!==void 0?t.defaultExtensions:e.defaultExtensions}function b(e,t){return t===void 0?e:e.map(e=>e.extensions===void 0?o(e,{...e,extensions:[...t],extensionsFromDefault:!0}):e)}function x(e,t,n,r,i){return b(v(g(h(e,t),i),n),r)}function S(e){return{model:e.model,fallbackModels:e.fallbackModels?[...e.fallbackModels]:void 0,thinking:e.thinking,systemPromptMode:e.systemPromptMode,inheritProjectContext:e.inheritProjectContext,inheritSkills:e.inheritSkills,defaultContext:e.defaultContext,disabled:e.disabled,systemPrompt:e.systemPrompt,skills:e.skills?[...e.skills]:void 0,skillPath:e.skillPath?[...e.skillPath]:void 0,tools:e.tools?[...e.tools]:void 0,mcpDirectTools:e.mcpDirectTools?[...e.mcpDirectTools]:void 0,extensions:e.extensionsFromDefault?void 0:e.extensions?[...e.extensions]:void 0,subagentOnlyExtensions:e.subagentOnlyExtensions?[...e.subagentOnlyExtensions]:void 0,completionGuard:e.completionGuard,toolBudget:e.toolBudget}}function C(e,t,n){let r,i=!1,c=()=>(r??={...e},r),l=(t,n,r)=>{a(e,...n)||(c()[t]=r,i=!0)};if(t.model!==void 0&&l(`model`,[`model`],t.model===!1?void 0:t.model),t.fallbackModels!==void 0&&l(`fallbackModels`,[`fallbackModels`],t.fallbackModels===!1?void 0:[...t.fallbackModels]),t.thinking!==void 0&&l(`thinking`,[`thinking`],t.thinking===!1?void 0:t.thinking),t.systemPromptMode!==void 0&&l(`systemPromptMode`,[`systemPromptMode`],t.systemPromptMode),t.inheritProjectContext!==void 0&&l(`inheritProjectContext`,[`inheritProjectContext`],t.inheritProjectContext),t.inheritSkills!==void 0&&l(`inheritSkills`,[`inheritSkills`],t.inheritSkills),t.defaultContext!==void 0&&l(`defaultContext`,[`defaultContext`],t.defaultContext===!1?void 0:t.defaultContext),t.disabled!==void 0&&e.disabled===void 0&&(c().disabled=t.disabled,i=!0),t.skills!==void 0&&l(`skills`,[`skill`,`skills`],t.skills===!1?void 0:[...t.skills]),t.tools!==void 0&&!a(e,`tools`)){let{tools:e,mcpDirectTools:n}=s(t.tools===!1?[]:t.tools),r=c();r.tools=e,r.mcpDirectTools=n,i=!0}return t.extensions!==void 0&&l(`extensions`,[`extensions`],t.extensions===!1?void 0:[...t.extensions]),t.subagentOnlyExtensions!==void 0&&l(`subagentOnlyExtensions`,[`subagentOnlyExtensions`],t.subagentOnlyExtensions===!1?void 0:[...t.subagentOnlyExtensions]),t.completionGuard!==void 0&&l(`completionGuard`,[`completionGuard`],t.completionGuard),t.toolBudget!==void 0&&l(`toolBudget`,[`toolBudget`],t.toolBudget===!1?void 0:t.toolBudget),!i||!r?e:(r.override={...n,base:S(e)},o(e,r))}function w(e,t,n,r,i){return e.map(e=>{let a=n.overrides[e.name];if(a&&i)return C(e,a,{scope:`project`,path:i});let o=t.overrides[e.name];return o?C(e,o,{scope:`user`,path:r}):e})}var T,E,D,O,k,A=e((()=>{r(),t(),T=`subagents`,E=`agentOverrides`,D=`mcp:`,O={overrides:{}},k=new WeakMap}));A();export{O as EMPTY_SUBAGENT_SETTINGS,w as applyCustomAgentOverrides,x as applySubagentDefaults,A as init_settings,p as readSubagentSettings,y as resolveSubagentDefaultExtensions,m as resolveSubagentDefaultModel,_ as resolveSubagentDefaultThinking,i as setAgentFrontmatterFields};
2
- //# sourceMappingURL=settings.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"settings.mjs","names":[],"sources":["../../src/agents/settings.ts"],"sourcesContent":["/**\n * Agent settings: reading them, and applying what they say to discovered agents.\n *\n * Two things live here because they are the same contract seen from both ends.\n * Reading turns untyped JSON on disk into settings; applying folds those\n * settings over the agents discovery found. The precedence is fixed: project\n * settings beat user settings, an explicit per-agent override beats a bulk\n * switch, and for a custom agent the agent's own frontmatter beats both.\n *\n * That last rule is why builtins and custom agents take different paths.\n * Overriding a builtin replaces values outright, because a builtin has no file\n * the user could have edited instead. Overriding a custom agent only fills\n * fields its frontmatter left unset, so a settings default never silently\n * contradicts what the author wrote in the file.\n *\n * DESIGN PATTERNS:\n * - Reading is strict and throws with the offending path and field. A settings\n * file that is quietly half-ignored is worse than one that refuses to load,\n * because the user sees agents behaving in ways their config does not explain\n * - Applying is pure and copy-on-write. Every `apply*` returns new configs and\n * never mutates its input, so a cached discovery result cannot be corrupted\n * by a later pass over it\n * - Overriding a builtin snapshots the values it replaced into `override.base`,\n * which is what makes removing the override restore the builtin exactly\n *\n * AVOID:\n * - Trusting any shape read off disk without a real guard\n * - Mutating an `AgentConfig` in place\n * - Writing a settings file non-atomically; it holds the user's overrides\n */\n\nimport * as fs from 'node:fs';\nimport { writeAtomicJson } from '../shared/atomicJson.ts';\nimport { readSettingsFileStrict } from '../shared/configDir.ts';\nimport type { ModelScopeConfig, ToolBudgetConfig } from '../types.ts';\nimport { getProjectAgentSettingsPath, getUserAgentSettingsPath } from './projectRoot.ts';\nexport { readSettingsFileStrict } from '../shared/configDir.ts';\nimport type {\n AgentConfig,\n AgentModelSourceInfo,\n BuiltinAgentOverrideBase,\n BuiltinAgentOverrideConfig,\n SubagentSettings,\n} from './types.ts';\n\nconst SUBAGENTS_SETTINGS_KEY = 'subagents';\nconst AGENT_OVERRIDES_KEY = 'agentOverrides';\n/** Prefix marking a tool the child calls on an MCP server directly. */\nconst MCP_DIRECT_TOOL_PREFIX = 'mcp:';\n\n/** Which settings file an override came from, without the value snapshot. */\ntype OverrideScopeMeta = { scope: 'user' | 'project'; path: string };\n\n/**\n * The snapshot of a builtin's pre-override values.\n *\n * Widens the contract with `mcpDirectTools` because a builtin's tool list is\n * stored split in `AgentConfig` and must round-trip through the snapshot to be\n * restorable. See the report note on `BuiltinAgentOverrideBase`.\n */\nexport interface BuiltinOverrideSnapshot extends BuiltinAgentOverrideBase {\n mcpDirectTools?: string[];\n}\n\n/**\n * Returned whenever there is nothing to read.\n *\n * Shared rather than freshly built per call because it is returned on the hot\n * discovery path for every session with no project settings file.\n */\nexport const EMPTY_SUBAGENT_SETTINGS: SubagentSettings = { overrides: {} };\n\n/**\n * Which fields of a config came from its file's frontmatter.\n *\n * Keyed by the config object rather than by agent name because configs are\n * copied on write: each `apply*` pass produces new objects, and the new one\n * inherits the entry so later passes still know what the author declared.\n * A WeakMap means a discarded config's entry is collectable with it.\n */\nconst agentFrontmatterFields = new WeakMap<AgentConfig, Set<string>>();\n\n/** Record which fields a freshly parsed config took from frontmatter. */\nexport function setAgentFrontmatterFields(agent: AgentConfig, fields: Set<string>): void {\n agentFrontmatterFields.set(agent, fields);\n}\n\n/** True when the agent's file declared any of `fields` in its frontmatter. */\nexport function agentHasFrontmatterField(agent: AgentConfig, ...fields: string[]): boolean {\n const frontmatterFields = agentFrontmatterFields.get(agent);\n return frontmatterFields ? fields.some((field) => frontmatterFields.has(field)) : false;\n}\n\n/** Carry the frontmatter record onto a copy produced by an `apply*` pass. */\nfunction inheritFrontmatterFields(source: AgentConfig, next: AgentConfig): AgentConfig {\n const frontmatterFields = agentFrontmatterFields.get(source);\n if (frontmatterFields) agentFrontmatterFields.set(next, frontmatterFields);\n return next;\n}\n\n/** Split a flat tool list into host tools and direct MCP tools. */\nfunction splitToolList(rawTools: string[] | undefined): { tools?: string[]; mcpDirectTools?: string[] } {\n const mcpDirectTools: string[] = [];\n const tools: string[] = [];\n for (const tool of rawTools ?? []) {\n if (tool.startsWith(MCP_DIRECT_TOOL_PREFIX)) mcpDirectTools.push(tool.slice(MCP_DIRECT_TOOL_PREFIX.length));\n else tools.push(tool);\n }\n return {\n ...(rawTools !== undefined ? { tools } : {}),\n ...(mcpDirectTools.length > 0 ? { mcpDirectTools } : {}),\n };\n}\n\n/** Inverse of `splitToolList`, for writing a tool list back to settings. */\nfunction joinToolList(config: { tools?: string[]; mcpDirectTools?: string[] }): string[] | undefined {\n const joined = [\n ...(config.tools ?? []),\n ...(config.mcpDirectTools ?? []).map((tool) => `${MCP_DIRECT_TOOL_PREFIX}${tool}`),\n ];\n return joined.length > 0 ? joined : undefined;\n}\n\n/** Order-sensitive equality; a reordered tool list is a real change. */\nfunction arraysEqual(a: string[] | undefined, b: string[] | undefined): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\n// ============================================================================\n// Reading\n// ============================================================================\n\n/**\n * Write a settings file atomically.\n *\n * This file holds every override the user configured. A partial write from a\n * crash mid-save would be read back as malformed on the next start and, because\n * reading is strict, would refuse to load at all.\n */\nexport function writeSettingsFile(filePath: string, settings: Record<string, unknown>): void {\n writeAtomicJson(filePath, settings);\n}\n\n/** Read a settings object at `key`, or undefined when it is absent or not an object. */\nfunction readObjectField(source: Record<string, unknown>, key: string): Record<string, unknown> | undefined {\n const value = source[key];\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;\n return value as Record<string, unknown>;\n}\n\n/** Copy a settings object at `key`, or start a fresh one when it is absent. */\nfunction cloneObjectField(source: Record<string, unknown>, key: string): Record<string, unknown> {\n // Spreading undefined is already a no-op, so no empty-object fallback is needed.\n return { ...readObjectField(source, key) };\n}\n\n/**\n * Parse the model-scope block.\n *\n * Lives here rather than beside the scope enforcement logic because parsing is\n * a settings concern and the agents domain may not reach into the runs domain.\n */\nfunction parseModelScopeConfig(value: unknown, filePath: string): ModelScopeConfig | undefined {\n if (value === undefined) return undefined;\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`Subagent settings in '${filePath}' have invalid 'modelScope'; expected an object.`);\n }\n\n const input = value as Record<string, unknown>;\n const config: ModelScopeConfig = {};\n\n if ('enforce' in input) {\n if (typeof input.enforce !== 'boolean') {\n throw new Error(`Subagent settings in '${filePath}' have invalid 'modelScope.enforce'; expected a boolean.`);\n }\n config.enforce = input.enforce;\n }\n\n if ('allow' in input) {\n if (!Array.isArray(input.allow)) {\n throw new Error(\n `Subagent settings in '${filePath}' have invalid 'modelScope.allow'; expected an array of strings.`,\n );\n }\n const allow: string[] = [];\n for (const entry of input.allow) {\n if (typeof entry !== 'string') {\n throw new Error(\n `Subagent settings in '${filePath}' have invalid 'modelScope.allow'; expected an array of strings.`,\n );\n }\n const trimmed = entry.trim();\n if (trimmed) allow.push(trimmed);\n }\n if (allow.length === 0) {\n throw new Error(\n `Subagent settings in '${filePath}' have invalid 'modelScope.allow'; expected a non-empty array of patterns.`,\n );\n }\n config.allow = allow;\n }\n\n // Enforcing against an empty allow list would reject every model, so it is\n // rejected here rather than at the point it would start failing runs.\n if (config.enforce === true && (!config.allow || config.allow.length === 0)) {\n throw new Error(\n `Subagent settings in '${filePath}' set modelScope.enforce without a non-empty 'allow' list; supply allowed model patterns or disable enforcement.`,\n );\n }\n\n return Object.keys(config).length > 0 ? config : undefined;\n}\n\n/**\n * Parse a string-array override field, which may also be `false` to clear it.\n *\n * Empty entries are dropped rather than rejected: trailing commas in a hand\n * edited list are common and unambiguous.\n */\nexport function parseOverrideStringArrayOrFalse(\n value: unknown,\n meta: { filePath: string; name: string; field: string },\n): string[] | false | undefined {\n if (value === undefined) return undefined;\n if (value === false) return false;\n if (!Array.isArray(value)) {\n throw new Error(\n `Builtin override '${meta.name}' in '${meta.filePath}' has invalid '${meta.field}'; expected an array of strings or false.`,\n );\n }\n\n const items: string[] = [];\n for (const item of value) {\n if (typeof item !== 'string') {\n throw new Error(\n `Builtin override '${meta.name}' in '${meta.filePath}' has invalid '${meta.field}'; expected an array of strings or false.`,\n );\n }\n const trimmed = item.trim();\n if (trimmed) items.push(trimmed);\n }\n return items;\n}\n\n/**\n * Parse one entry of `subagents.agentOverrides`.\n *\n * Returns undefined for an entry that declared nothing, so an empty object in\n * the file does not register as an override and mark the agent as overridden.\n */\nexport function parseBuiltinOverrideEntry(\n name: string,\n value: unknown,\n filePath: string,\n): BuiltinAgentOverrideConfig | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`Builtin override '${name}' in '${filePath}' must be an object.`);\n }\n\n const input = value as Record<string, unknown>;\n const override: BuiltinAgentOverrideConfig = {};\n\n if ('model' in input) {\n if (typeof input.model === 'string' || input.model === false) override.model = input.model;\n else\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'model'; expected a string or false.`);\n }\n\n if ('thinking' in input) {\n if (typeof input.thinking === 'string' || input.thinking === false) override.thinking = input.thinking;\n else\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'thinking'; expected a string or false.`,\n );\n }\n\n if ('systemPromptMode' in input) {\n if (input.systemPromptMode === 'append' || input.systemPromptMode === 'replace') {\n override.systemPromptMode = input.systemPromptMode;\n } else {\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'systemPromptMode'; expected 'append' or 'replace'.`,\n );\n }\n }\n\n if ('inheritProjectContext' in input) {\n if (typeof input.inheritProjectContext === 'boolean') {\n override.inheritProjectContext = input.inheritProjectContext;\n } else {\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'inheritProjectContext'; expected a boolean.`,\n );\n }\n }\n\n if ('inheritSkills' in input) {\n if (typeof input.inheritSkills === 'boolean') {\n override.inheritSkills = input.inheritSkills;\n } else {\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'inheritSkills'; expected a boolean.`);\n }\n }\n\n if ('defaultContext' in input) {\n if (input.defaultContext === 'fresh' || input.defaultContext === 'fork' || input.defaultContext === false) {\n override.defaultContext = input.defaultContext;\n } else {\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'defaultContext'; expected 'fresh', 'fork', or false.`,\n );\n }\n }\n\n if ('disabled' in input) {\n if (typeof input.disabled === 'boolean') {\n override.disabled = input.disabled;\n } else {\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'disabled'; expected a boolean.`);\n }\n }\n\n if ('completionGuard' in input) {\n if (typeof input.completionGuard === 'boolean') {\n override.completionGuard = input.completionGuard;\n } else {\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'completionGuard'; expected a boolean.`);\n }\n }\n\n if ('toolBudget' in input) {\n const toolBudget = parseToolBudgetOverride(input.toolBudget, name, filePath);\n if (toolBudget !== undefined) override.toolBudget = toolBudget;\n }\n\n if ('systemPrompt' in input) {\n if (typeof input.systemPrompt === 'string') override.systemPrompt = input.systemPrompt;\n else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'systemPrompt'; expected a string.`);\n }\n\n const parseArrayField = (field: string): string[] | false | undefined =>\n parseOverrideStringArrayOrFalse(input[field], { filePath, name, field });\n\n const fallbackModels = parseArrayField('fallbackModels');\n if (fallbackModels !== undefined) override.fallbackModels = fallbackModels;\n const skills = parseArrayField('skills');\n if (skills !== undefined) override.skills = skills;\n const tools = parseArrayField('tools');\n if (tools !== undefined) override.tools = tools;\n const extensions = parseArrayField('extensions');\n if (extensions !== undefined) override.extensions = extensions;\n const subagentOnlyExtensions = parseArrayField('subagentOnlyExtensions');\n if (subagentOnlyExtensions !== undefined) override.subagentOnlyExtensions = subagentOnlyExtensions;\n\n return Object.keys(override).length > 0 ? override : undefined;\n}\n\n/**\n * Parse a `toolBudget` override.\n *\n * `hard` is required by the contract, so an object without a usable one is\n * rejected here instead of producing a budget that never blocks.\n */\nfunction parseToolBudgetOverride(value: unknown, name: string, filePath: string): ToolBudgetConfig | false | undefined {\n if (value === false) return false;\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'toolBudget'; expected an object or false.`,\n );\n }\n\n const input = value as Record<string, unknown>;\n if (typeof input.hard !== 'number') {\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'toolBudget.hard'; expected a number.`);\n }\n\n const budget: ToolBudgetConfig = { hard: input.hard };\n if ('soft' in input) {\n if (typeof input.soft !== 'number') {\n throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'toolBudget.soft'; expected a number.`);\n }\n budget.soft = input.soft;\n }\n if ('block' in input) {\n if (input.block === '*') {\n budget.block = '*';\n } else if (Array.isArray(input.block) && input.block.every((entry) => typeof entry === 'string')) {\n budget.block = [...input.block];\n } else {\n throw new Error(\n `Builtin override '${name}' in '${filePath}' has invalid 'toolBudget.block'; expected an array of strings or '*'.`,\n );\n }\n }\n return budget;\n}\n\n/** Read and validate one settings file's `subagents` block. */\nexport function readSubagentSettings(filePath: string | null): SubagentSettings {\n if (!filePath) return EMPTY_SUBAGENT_SETTINGS;\n const settings = readSettingsFileStrict(filePath);\n const subagentsObject = readObjectField(settings, SUBAGENTS_SETTINGS_KEY);\n if (!subagentsObject) return EMPTY_SUBAGENT_SETTINGS;\n\n let disableBuiltins: boolean | undefined;\n if ('disableBuiltins' in subagentsObject) {\n if (typeof subagentsObject.disableBuiltins === 'boolean') {\n disableBuiltins = subagentsObject.disableBuiltins;\n } else {\n throw new Error(`Subagent settings in '${filePath}' have invalid 'disableBuiltins'; expected a boolean.`);\n }\n }\n\n let disableThinking: boolean | undefined;\n if ('disableThinking' in subagentsObject) {\n if (typeof subagentsObject.disableThinking === 'boolean') {\n disableThinking = subagentsObject.disableThinking;\n } else {\n throw new Error(`Subagent settings in '${filePath}' have invalid 'disableThinking'; expected a boolean.`);\n }\n }\n\n let defaultModel: string | undefined;\n if ('defaultModel' in subagentsObject) {\n if (typeof subagentsObject.defaultModel === 'string' && subagentsObject.defaultModel.trim()) {\n defaultModel = subagentsObject.defaultModel.trim();\n } else {\n throw new Error(`Subagent settings in '${filePath}' have invalid 'defaultModel'; expected a non-empty string.`);\n }\n }\n\n let defaultThinking: string | undefined;\n if ('defaultThinking' in subagentsObject) {\n if (typeof subagentsObject.defaultThinking === 'string' && subagentsObject.defaultThinking.trim()) {\n defaultThinking = subagentsObject.defaultThinking.trim();\n } else {\n throw new Error(\n `Subagent settings in '${filePath}' have invalid 'defaultThinking'; expected a non-empty string.`,\n );\n }\n }\n\n let defaultExtensions: string[] | undefined;\n if ('defaultExtensions' in subagentsObject) {\n const raw = subagentsObject.defaultExtensions;\n if (!Array.isArray(raw) || raw.some((item) => typeof item !== 'string' || !item.trim())) {\n throw new Error(\n `Subagent settings in '${filePath}' have invalid 'defaultExtensions'; expected an array of non-empty strings.`,\n );\n }\n defaultExtensions = raw.map((item) => String(item).trim());\n }\n\n const modelScope = parseModelScopeConfig(subagentsObject.modelScope, filePath);\n\n const overrides: Record<string, BuiltinAgentOverrideConfig> = {};\n const agentOverrides = readObjectField(subagentsObject, AGENT_OVERRIDES_KEY);\n if (agentOverrides) {\n for (const [name, value] of Object.entries(agentOverrides)) {\n const override = parseBuiltinOverrideEntry(name, value, filePath);\n if (override) overrides[name] = override;\n }\n }\n\n return { overrides, defaultModel, defaultThinking, defaultExtensions, disableBuiltins, disableThinking, modelScope };\n}\n\n// ============================================================================\n// Settings-level defaults\n// ============================================================================\n\n/** Which settings file supplies `defaultModel`, project winning over user. */\nexport function resolveSubagentDefaultModel(\n userSettings: SubagentSettings,\n projectSettings: SubagentSettings,\n userSettingsPath: string,\n projectSettingsPath: string | null,\n): AgentModelSourceInfo | undefined {\n if (projectSettingsPath && projectSettings.defaultModel !== undefined) {\n return {\n type: 'subagents.defaultModel',\n scope: 'project',\n path: projectSettingsPath,\n model: projectSettings.defaultModel,\n };\n }\n return userSettings.defaultModel !== undefined\n ? { type: 'subagents.defaultModel', scope: 'user', path: userSettingsPath, model: userSettings.defaultModel }\n : undefined;\n}\n\n/**\n * Fill in the default model for agents that declared none.\n *\n * `modelSource` is recorded alongside so callers can tell an inherited model\n * from a requested one, which decides how hard model-scope enforcement bites.\n */\nexport function applySubagentDefaultModel(\n agents: AgentConfig[],\n defaultModel: AgentModelSourceInfo | undefined,\n): AgentConfig[] {\n if (!defaultModel) return agents;\n return agents.map((agent) => {\n if (agent.model !== undefined) return agent;\n return inheritFrontmatterFields(agent, { ...agent, model: defaultModel.model, modelSource: defaultModel });\n });\n}\n\n/** Fill in fallback models only when the agent declared no fallback policy. */\nexport function applySubagentDefaultFallbackModels(\n agents: AgentConfig[],\n fallbackModels: string[] | undefined,\n): AgentConfig[] {\n if (fallbackModels === undefined) return agents;\n return agents.map((agent) => {\n if (agent.fallbackModels !== undefined) return agent;\n return inheritFrontmatterFields(agent, { ...agent, fallbackModels: [...fallbackModels] });\n });\n}\n\nexport function resolveSubagentDefaultThinking(\n userSettings: SubagentSettings,\n projectSettings: SubagentSettings,\n projectSettingsPath: string | null,\n): string | undefined {\n if (projectSettingsPath && projectSettings.defaultThinking !== undefined) return projectSettings.defaultThinking;\n return userSettings.defaultThinking;\n}\n\nexport function applySubagentDefaultThinking(\n agents: AgentConfig[],\n defaultThinking: string | undefined,\n): AgentConfig[] {\n if (defaultThinking === undefined) return agents;\n return agents.map((agent) => {\n if (agent.thinking !== undefined) return agent;\n return inheritFrontmatterFields(agent, { ...agent, thinking: defaultThinking });\n });\n}\n\nexport function resolveSubagentDefaultExtensions(\n userSettings: SubagentSettings,\n projectSettings: SubagentSettings,\n projectSettingsPath: string | null,\n): string[] | undefined {\n if (projectSettingsPath && projectSettings.defaultExtensions !== undefined) return projectSettings.defaultExtensions;\n return userSettings.defaultExtensions;\n}\n\n/**\n * Fill in default extensions for agents that declared none.\n *\n * The `extensionsFromDefault` flag matters when the agent is later overridden:\n * a snapshot must not record a settings default as if the builtin had declared\n * it, or removing the override would bake the default in permanently.\n */\nexport function applySubagentDefaultExtensions(\n agents: AgentConfig[],\n defaultExtensions: string[] | undefined,\n): AgentConfig[] {\n if (defaultExtensions === undefined) return agents;\n return agents.map((agent) => {\n if (agent.extensions !== undefined) return agent;\n return inheritFrontmatterFields(agent, {\n ...agent,\n extensions: [...defaultExtensions],\n extensionsFromDefault: true,\n });\n });\n}\n\nexport function applySubagentDefaults(\n agents: AgentConfig[],\n defaultModel: AgentModelSourceInfo | undefined,\n defaultThinking: string | undefined,\n defaultExtensions: string[] | undefined,\n defaultFallbackModels?: string[],\n): AgentConfig[] {\n return applySubagentDefaultExtensions(\n applySubagentDefaultThinking(\n applySubagentDefaultFallbackModels(applySubagentDefaultModel(agents, defaultModel), defaultFallbackModels),\n defaultThinking,\n ),\n defaultExtensions,\n );\n}\n\n// ============================================================================\n// Override snapshots\n// ============================================================================\n\n/**\n * Snapshot the fields an override may replace, so it can be undone.\n *\n * `extensions` is omitted when it came from a settings default rather than the\n * agent itself; restoring it would turn a default into a permanent value.\n */\nexport function cloneOverrideBase(agent: AgentConfig): BuiltinOverrideSnapshot {\n return {\n model: agent.model,\n fallbackModels: agent.fallbackModels ? [...agent.fallbackModels] : undefined,\n thinking: agent.thinking,\n systemPromptMode: agent.systemPromptMode,\n inheritProjectContext: agent.inheritProjectContext,\n inheritSkills: agent.inheritSkills,\n defaultContext: agent.defaultContext,\n disabled: agent.disabled,\n systemPrompt: agent.systemPrompt,\n skills: agent.skills ? [...agent.skills] : undefined,\n skillPath: agent.skillPath ? [...agent.skillPath] : undefined,\n tools: agent.tools ? [...agent.tools] : undefined,\n mcpDirectTools: agent.mcpDirectTools ? [...agent.mcpDirectTools] : undefined,\n extensions: agent.extensionsFromDefault ? undefined : agent.extensions ? [...agent.extensions] : undefined,\n subagentOnlyExtensions: agent.subagentOnlyExtensions ? [...agent.subagentOnlyExtensions] : undefined,\n completionGuard: agent.completionGuard,\n toolBudget: agent.toolBudget,\n };\n}\n\n/**\n * Deep-copy an override before it is written to a settings file.\n *\n * Only keys the caller actually set are copied, because an explicit `undefined`\n * would serialise the key away and read back as \"not overridden\".\n */\nexport function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentOverrideConfig {\n return {\n ...(override.model !== undefined ? { model: override.model } : {}),\n ...(override.fallbackModels !== undefined\n ? { fallbackModels: override.fallbackModels === false ? false : [...override.fallbackModels] }\n : {}),\n ...(override.thinking !== undefined ? { thinking: override.thinking } : {}),\n ...(override.systemPromptMode !== undefined ? { systemPromptMode: override.systemPromptMode } : {}),\n ...(override.inheritProjectContext !== undefined ? { inheritProjectContext: override.inheritProjectContext } : {}),\n ...(override.inheritSkills !== undefined ? { inheritSkills: override.inheritSkills } : {}),\n ...(override.defaultContext !== undefined ? { defaultContext: override.defaultContext } : {}),\n ...(override.disabled !== undefined ? { disabled: override.disabled } : {}),\n ...(override.systemPrompt !== undefined ? { systemPrompt: override.systemPrompt } : {}),\n ...(override.skills !== undefined ? { skills: override.skills === false ? false : [...override.skills] } : {}),\n ...(override.tools !== undefined ? { tools: override.tools === false ? false : [...override.tools] } : {}),\n ...(override.extensions !== undefined\n ? { extensions: override.extensions === false ? false : [...override.extensions] }\n : {}),\n ...(override.subagentOnlyExtensions !== undefined\n ? {\n subagentOnlyExtensions:\n override.subagentOnlyExtensions === false ? false : [...override.subagentOnlyExtensions],\n }\n : {}),\n ...(override.completionGuard !== undefined ? { completionGuard: override.completionGuard } : {}),\n ...(override.toolBudget !== undefined\n ? {\n toolBudget:\n override.toolBudget === false\n ? false\n : {\n ...override.toolBudget,\n ...(Array.isArray(override.toolBudget.block) ? { block: [...override.toolBudget.block] } : {}),\n },\n }\n : {}),\n };\n}\n\n// ============================================================================\n// Applying overrides\n// ============================================================================\n\n/**\n * Replace a builtin's values with an override's.\n *\n * `false` clears a field rather than setting it to false; that distinction is\n * the whole reason the stored shape differs from the snapshot shape.\n */\nexport function applyBuiltinOverride(\n agent: AgentConfig,\n override: BuiltinAgentOverrideConfig,\n meta: OverrideScopeMeta,\n): AgentConfig {\n const next: AgentConfig = { ...agent, override: { ...meta, base: cloneOverrideBase(agent) } };\n\n if (override.model !== undefined) next.model = override.model === false ? undefined : override.model;\n if (override.fallbackModels !== undefined) {\n next.fallbackModels = override.fallbackModels === false ? undefined : [...override.fallbackModels];\n }\n if (override.thinking !== undefined) next.thinking = override.thinking === false ? undefined : override.thinking;\n if (override.systemPromptMode !== undefined) next.systemPromptMode = override.systemPromptMode;\n if (override.inheritProjectContext !== undefined) next.inheritProjectContext = override.inheritProjectContext;\n if (override.inheritSkills !== undefined) next.inheritSkills = override.inheritSkills;\n if (override.defaultContext !== undefined) {\n next.defaultContext = override.defaultContext === false ? undefined : override.defaultContext;\n }\n if (override.disabled !== undefined) next.disabled = override.disabled;\n if (override.systemPrompt !== undefined) next.systemPrompt = override.systemPrompt;\n if (override.skills !== undefined) next.skills = override.skills === false ? undefined : [...override.skills];\n if (override.tools !== undefined) {\n const { tools, mcpDirectTools } = splitToolList(override.tools === false ? [] : override.tools);\n next.tools = tools;\n next.mcpDirectTools = mcpDirectTools;\n }\n if (override.extensions !== undefined) {\n next.extensions = override.extensions === false ? undefined : [...override.extensions];\n }\n if (override.subagentOnlyExtensions !== undefined) {\n next.subagentOnlyExtensions =\n override.subagentOnlyExtensions === false ? undefined : [...override.subagentOnlyExtensions];\n }\n if (override.completionGuard !== undefined) next.completionGuard = override.completionGuard;\n if (override.toolBudget !== undefined) {\n next.toolBudget = override.toolBudget === false ? undefined : override.toolBudget;\n }\n\n return next;\n}\n\n/**\n * Strip an agent's thinking level for the bulk `disableThinking` switch.\n *\n * An existing `override` is kept rather than replaced, so a per-agent override\n * remains the recorded reason the agent differs from its builtin definition.\n */\nexport function clearBuiltinThinking(agent: AgentConfig, meta: OverrideScopeMeta): AgentConfig {\n if (agent.thinking === undefined) return agent;\n return { ...agent, thinking: undefined, override: agent.override ?? { ...meta, base: cloneOverrideBase(agent) } };\n}\n\n/**\n * Apply user and project settings to the builtin agents.\n *\n * Precedence per agent: a project override, then the project bulk disable, then\n * a user override, then the user bulk disable. A project file that sets\n * `disableBuiltins` at all (including to false) shadows the user's switch, so a\n * project can re-enable builtins its user settings turned off.\n */\nexport function applyBuiltinOverrides(\n builtinAgents: AgentConfig[],\n userSettings: SubagentSettings,\n projectSettings: SubagentSettings,\n userSettingsPath: string,\n projectSettingsPath: string | null,\n): AgentConfig[] {\n const projectBulkDisabled = projectSettings.disableBuiltins === true && projectSettingsPath !== null;\n const userBulkDisabled = projectSettings.disableBuiltins === undefined && userSettings.disableBuiltins === true;\n const projectThinkingConfigured = projectSettings.disableThinking !== undefined && projectSettingsPath !== null;\n const disableThinking = projectThinkingConfigured\n ? projectSettings.disableThinking === true\n : userSettings.disableThinking === true;\n const disableThinkingMeta: OverrideScopeMeta =\n projectThinkingConfigured && projectSettingsPath\n ? { scope: 'project', path: projectSettingsPath }\n : { scope: 'user', path: userSettingsPath };\n\n // A per-agent thinking override is more specific than the bulk switch, so it\n // survives it; everything else is cleared.\n const applyGlobalThinking = (agent: AgentConfig, hasExplicitThinkingOverride: boolean): AgentConfig => {\n if (!disableThinking || hasExplicitThinkingOverride) return agent;\n return clearBuiltinThinking(agent, disableThinkingMeta);\n };\n\n return builtinAgents.map((agent) => {\n const projectOverride = projectSettings.overrides[agent.name];\n if (projectOverride && projectSettingsPath) {\n return applyGlobalThinking(\n applyBuiltinOverride(agent, projectOverride, { scope: 'project', path: projectSettingsPath }),\n projectOverride.thinking !== undefined,\n );\n }\n\n if (projectBulkDisabled && projectSettingsPath) {\n return applyGlobalThinking(\n applyBuiltinOverride(agent, { disabled: true }, { scope: 'project', path: projectSettingsPath }),\n false,\n );\n }\n\n const userOverride = userSettings.overrides[agent.name];\n if (userOverride) {\n return applyGlobalThinking(\n applyBuiltinOverride(agent, userOverride, { scope: 'user', path: userSettingsPath }),\n !projectThinkingConfigured && userOverride.thinking !== undefined,\n );\n }\n\n if (userBulkDisabled) {\n return applyGlobalThinking(\n applyBuiltinOverride(agent, { disabled: true }, { scope: 'user', path: userSettingsPath }),\n false,\n );\n }\n\n return applyGlobalThinking(agent, false);\n });\n}\n\n/**\n * Apply an override to a custom agent, filling only unset fields.\n *\n * A custom agent has a file the user could have edited, so a settings value\n * must never contradict its frontmatter. Nothing is copied and no `override`\n * is recorded unless at least one field was actually filled, which keeps agents\n * that declared everything from being reported as overridden.\n */\nexport function applyCustomAgentOverride(\n agent: AgentConfig,\n override: BuiltinAgentOverrideConfig,\n meta: OverrideScopeMeta,\n): AgentConfig {\n let next: AgentConfig | undefined;\n let anyFilled = false;\n\n const mutable = (): AgentConfig => {\n next ??= { ...agent };\n return next;\n };\n\n const fill = <K extends keyof AgentConfig>(field: K, frontmatterFields: string[], value: AgentConfig[K]): void => {\n if (agentHasFrontmatterField(agent, ...frontmatterFields)) return;\n mutable()[field] = value;\n anyFilled = true;\n };\n\n if (override.model !== undefined) {\n fill('model', ['model'], override.model === false ? undefined : override.model);\n }\n if (override.fallbackModels !== undefined) {\n fill(\n 'fallbackModels',\n ['fallbackModels'],\n override.fallbackModels === false ? undefined : [...override.fallbackModels],\n );\n }\n if (override.thinking !== undefined) {\n fill('thinking', ['thinking'], override.thinking === false ? undefined : override.thinking);\n }\n if (override.systemPromptMode !== undefined) {\n fill('systemPromptMode', ['systemPromptMode'], override.systemPromptMode);\n }\n if (override.inheritProjectContext !== undefined) {\n fill('inheritProjectContext', ['inheritProjectContext'], override.inheritProjectContext);\n }\n if (override.inheritSkills !== undefined) {\n fill('inheritSkills', ['inheritSkills'], override.inheritSkills);\n }\n if (override.defaultContext !== undefined) {\n fill('defaultContext', ['defaultContext'], override.defaultContext === false ? undefined : override.defaultContext);\n }\n if (override.disabled !== undefined && agent.disabled === undefined) {\n mutable().disabled = override.disabled;\n anyFilled = true;\n }\n if (override.skills !== undefined) {\n fill('skills', ['skill', 'skills'], override.skills === false ? undefined : [...override.skills]);\n }\n if (override.tools !== undefined && !agentHasFrontmatterField(agent, 'tools')) {\n const { tools, mcpDirectTools } = splitToolList(override.tools === false ? [] : override.tools);\n const target = mutable();\n target.tools = tools;\n target.mcpDirectTools = mcpDirectTools;\n anyFilled = true;\n }\n if (override.extensions !== undefined) {\n fill('extensions', ['extensions'], override.extensions === false ? undefined : [...override.extensions]);\n }\n if (override.subagentOnlyExtensions !== undefined) {\n fill(\n 'subagentOnlyExtensions',\n ['subagentOnlyExtensions'],\n override.subagentOnlyExtensions === false ? undefined : [...override.subagentOnlyExtensions],\n );\n }\n if (override.completionGuard !== undefined) {\n fill('completionGuard', ['completionGuard'], override.completionGuard);\n }\n if (override.toolBudget !== undefined) {\n fill('toolBudget', ['toolBudget'], override.toolBudget === false ? undefined : override.toolBudget);\n }\n\n if (!anyFilled || !next) return agent;\n next.override = { ...meta, base: cloneOverrideBase(agent) };\n return inheritFrontmatterFields(agent, next);\n}\n\nexport function applyCustomAgentOverrides(\n agents: AgentConfig[],\n userSettings: SubagentSettings,\n projectSettings: SubagentSettings,\n userSettingsPath: string,\n projectSettingsPath: string | null,\n): AgentConfig[] {\n return agents.map((agent) => {\n const projectOverride = projectSettings.overrides[agent.name];\n if (projectOverride && projectSettingsPath) {\n return applyCustomAgentOverride(agent, projectOverride, { scope: 'project', path: projectSettingsPath });\n }\n\n const userOverride = userSettings.overrides[agent.name];\n if (userOverride) {\n return applyCustomAgentOverride(agent, userOverride, { scope: 'user', path: userSettingsPath });\n }\n\n return agent;\n });\n}\n\n/**\n * Diff an edited agent against its pre-override snapshot.\n *\n * Only changed fields are written, so a settings file records the user's edits\n * rather than a full copy of the builtin that would drift as the builtin does.\n * Returns undefined when nothing changed, which callers treat as \"remove the\n * override\" rather than \"write an empty one\".\n */\nexport function buildBuiltinOverrideConfig(\n base: BuiltinOverrideSnapshot,\n draft: Pick<\n AgentConfig,\n | 'model'\n | 'fallbackModels'\n | 'thinking'\n | 'systemPromptMode'\n | 'inheritProjectContext'\n | 'inheritSkills'\n | 'defaultContext'\n | 'disabled'\n | 'systemPrompt'\n | 'skills'\n | 'tools'\n | 'mcpDirectTools'\n | 'extensions'\n | 'subagentOnlyExtensions'\n | 'completionGuard'\n | 'toolBudget'\n >,\n): BuiltinAgentOverrideConfig | undefined {\n const override: BuiltinAgentOverrideConfig = {};\n\n if (draft.model !== base.model) override.model = draft.model ?? false;\n if (!arraysEqual(draft.fallbackModels, base.fallbackModels)) {\n override.fallbackModels = draft.fallbackModels ? [...draft.fallbackModels] : false;\n }\n if (draft.thinking !== base.thinking) override.thinking = draft.thinking ?? false;\n if (draft.systemPromptMode !== base.systemPromptMode) override.systemPromptMode = draft.systemPromptMode;\n if (draft.inheritProjectContext !== base.inheritProjectContext) {\n override.inheritProjectContext = draft.inheritProjectContext;\n }\n if (draft.inheritSkills !== base.inheritSkills) override.inheritSkills = draft.inheritSkills;\n if (draft.defaultContext !== base.defaultContext) override.defaultContext = draft.defaultContext ?? false;\n if (draft.disabled !== base.disabled) override.disabled = draft.disabled ?? false;\n if (draft.systemPrompt !== base.systemPrompt) override.systemPrompt = draft.systemPrompt;\n if (!arraysEqual(draft.skills, base.skills)) override.skills = draft.skills ? [...draft.skills] : false;\n\n const baseTools = joinToolList(base);\n const draftTools = joinToolList(draft);\n if (!arraysEqual(draftTools, baseTools)) override.tools = draftTools ? [...draftTools] : false;\n if (!arraysEqual(draft.extensions, base.extensions)) {\n override.extensions = draft.extensions ? [...draft.extensions] : false;\n }\n if (!arraysEqual(draft.subagentOnlyExtensions, base.subagentOnlyExtensions)) {\n override.subagentOnlyExtensions = draft.subagentOnlyExtensions ? [...draft.subagentOnlyExtensions] : false;\n }\n // Compared as booleans because an unset guard and an enabled one behave the\n // same, so only a switch to or from explicitly disabled is a real change.\n if ((draft.completionGuard !== false) !== (base.completionGuard !== false)) {\n override.completionGuard = draft.completionGuard !== false;\n }\n if (JSON.stringify(draft.toolBudget) !== JSON.stringify(base.toolBudget)) {\n override.toolBudget = draft.toolBudget ?? false;\n }\n\n return Object.keys(override).length > 0 ? override : undefined;\n}\n\n// ============================================================================\n// Persisting overrides\n// ============================================================================\n\nconst NO_PROJECT_ROOT_MESSAGE = 'Project override is not available here. No project config root was found.';\n\n/** Resolve the settings file for a scope, or throw when there is no project. */\nfunction requireSettingsPath(cwd: string, scope: 'user' | 'project'): string {\n const filePath = scope === 'project' ? getProjectAgentSettingsPath(cwd) : getUserAgentSettingsPath();\n if (!filePath) throw new Error(NO_PROJECT_ROOT_MESSAGE);\n return filePath;\n}\n\n/** Write an override, replacing any existing entry for the agent wholesale. */\nexport function saveBuiltinAgentOverride(\n cwd: string,\n name: string,\n scope: 'user' | 'project',\n override: BuiltinAgentOverrideConfig,\n): string {\n const filePath = requireSettingsPath(cwd, scope);\n\n const settings = readSettingsFileStrict(filePath);\n const subagents = cloneObjectField(settings, SUBAGENTS_SETTINGS_KEY);\n const agentOverrides = cloneObjectField(subagents, AGENT_OVERRIDES_KEY);\n\n agentOverrides[name] = cloneOverrideValue(override);\n subagents[AGENT_OVERRIDES_KEY] = agentOverrides;\n settings[SUBAGENTS_SETTINGS_KEY] = subagents;\n writeSettingsFile(filePath, settings);\n return filePath;\n}\n\n/**\n * Drop an agent's whole override entry.\n *\n * Emptied containers are deleted rather than left behind, so removing the last\n * override leaves the settings file as it was before any were added.\n */\nexport function removeBuiltinAgentOverride(\n cwd: string,\n name: string,\n scope: 'user' | 'project',\n): { path: string; removed: boolean } {\n const filePath = requireSettingsPath(cwd, scope);\n if (!fs.existsSync(filePath)) return { path: filePath, removed: false };\n\n const settings = readSettingsFileStrict(filePath);\n const subagents = readObjectField(settings, SUBAGENTS_SETTINGS_KEY);\n if (!subagents) return { path: filePath, removed: false };\n const agentOverrides = readObjectField(subagents, AGENT_OVERRIDES_KEY);\n if (!agentOverrides) return { path: filePath, removed: false };\n if (!Object.hasOwn(agentOverrides, name)) return { path: filePath, removed: false };\n\n const nextSubagents = { ...subagents };\n const nextOverrides = { ...agentOverrides };\n delete nextOverrides[name];\n if (Object.keys(nextOverrides).length > 0) nextSubagents[AGENT_OVERRIDES_KEY] = nextOverrides;\n else delete nextSubagents[AGENT_OVERRIDES_KEY];\n\n if (Object.keys(nextSubagents).length > 0) settings[SUBAGENTS_SETTINGS_KEY] = nextSubagents;\n else delete settings[SUBAGENTS_SETTINGS_KEY];\n\n writeSettingsFile(filePath, settings);\n return { path: filePath, removed: true };\n}\n\n/** Merge fields into an agent's existing override, leaving the rest in place. */\nexport function mergeBuiltinAgentOverride(\n cwd: string,\n name: string,\n scope: 'user' | 'project',\n fields: BuiltinAgentOverrideConfig,\n): string {\n const filePath = requireSettingsPath(cwd, scope);\n\n const settings = readSettingsFileStrict(filePath);\n const subagents = cloneObjectField(settings, SUBAGENTS_SETTINGS_KEY);\n const agentOverrides = cloneObjectField(subagents, AGENT_OVERRIDES_KEY);\n\n const existing = readObjectField(agentOverrides, name) ?? {};\n agentOverrides[name] = { ...existing, ...cloneOverrideValue(fields) };\n subagents[AGENT_OVERRIDES_KEY] = agentOverrides;\n settings[SUBAGENTS_SETTINGS_KEY] = subagents;\n writeSettingsFile(filePath, settings);\n return filePath;\n}\n\n/** Remove named fields from an agent's override, dropping it once empty. */\nexport function removeBuiltinAgentOverrideFields(\n cwd: string,\n name: string,\n scope: 'user' | 'project',\n fields: string[],\n): { path: string; removed: boolean } {\n const filePath = requireSettingsPath(cwd, scope);\n if (!fs.existsSync(filePath)) return { path: filePath, removed: false };\n\n const settings = readSettingsFileStrict(filePath);\n const subagents = readObjectField(settings, SUBAGENTS_SETTINGS_KEY);\n if (!subagents) return { path: filePath, removed: false };\n const agentOverrides = readObjectField(subagents, AGENT_OVERRIDES_KEY);\n if (!agentOverrides) return { path: filePath, removed: false };\n const entry = readObjectField(agentOverrides, name);\n if (!entry) return { path: filePath, removed: false };\n\n const nextEntry: Record<string, unknown> = { ...entry };\n let removed = false;\n for (const field of fields) {\n if (Object.hasOwn(nextEntry, field)) {\n delete nextEntry[field];\n removed = true;\n }\n }\n if (!removed) return { path: filePath, removed: false };\n\n const nextSubagents = { ...subagents };\n const nextOverrides = { ...agentOverrides };\n if (Object.keys(nextEntry).length > 0) {\n nextOverrides[name] = nextEntry;\n nextSubagents[AGENT_OVERRIDES_KEY] = nextOverrides;\n } else {\n delete nextOverrides[name];\n if (Object.keys(nextOverrides).length > 0) nextSubagents[AGENT_OVERRIDES_KEY] = nextOverrides;\n else delete nextSubagents[AGENT_OVERRIDES_KEY];\n }\n if (Object.keys(nextSubagents).length > 0) settings[SUBAGENTS_SETTINGS_KEY] = nextSubagents;\n else delete settings[SUBAGENTS_SETTINGS_KEY];\n\n writeSettingsFile(filePath, settings);\n return { path: filePath, removed: true };\n}\n"],"mappings":"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"}
Binary file
@@ -1 +0,0 @@
1
- {"version":3,"file":"skills.cjs","names":["fs","path","getProjectConfigDir","os","LruCache","getAgentDir"],"sources":["../../src/agents/skills.ts"],"sourcesContent":["/**\n * Resolving skill files by name and rendering them into a child system prompt.\n *\n * A skill is a markdown file, either `<dir>/SKILL.md` or a bare `<name>.md`,\n * found by sweeping a fixed list of search roots. The same name can appear in\n * several roots, so the sweep records where each hit came from and the highest\n * priority source wins.\n *\n * WHY THIS IS A SERVICE AND NOT A MODULE OF FUNCTIONS:\n * Resolution walks every skill root and reads the frontmatter of every markdown\n * file it finds. Prompt assembly asks for the catalogue on each launch and\n * completion asks on each keystroke, so the answers have to be cached, and a\n * cache needs an owner that can be invalidated and swapped in a test.\n *\n * DESIGN PATTERNS:\n * - Two caches with different lifetimes. Listing answers \"does this name exist\n * and where\", reading answers \"what does it say\"; the first goes stale on any\n * directory change, the second only when one file's mtime moves\n * - Both are bounded LRUs. The predecessor held the listing in a single mutable\n * slot keyed by cwd, which thrashed the moment two working directories were in\n * play, and evicted parsed files in insertion order regardless of use\n * - Every filesystem call is best-effort. A skill root that cannot be read is\n * skipped, never fatal: a missing skill surfaces to the caller as `missing`\n * - Symlinked and repeated directories are visited at most once per priority, so\n * a cycle in the skill tree terminates\n *\n * AVOID:\n * - Walking the skill roots on a completion path without going through the cache\n * - Deriving a config directory here instead of asking `configDir.ts`\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { injectable } from 'inversify';\n\nimport { EXTRA_SKILL_DIRS_ENV } from '../env.ts';\nimport { getAgentDir, getProjectConfigDir } from '../shared/configDir.ts';\nimport { LruCache } from '../shared/lruCache.ts';\n\n/**\n * Where a skill file was found.\n *\n * Deliberately not `AgentSource`: a skill can also come from a settings list or\n * from an extension directory, neither of which can hold an agent definition.\n */\nexport type SkillSource =\n | 'project'\n | 'user'\n | 'project-settings'\n | 'user-settings'\n | 'extension'\n | 'builtin'\n | 'unknown';\n\nexport interface ResolvedSkill {\n name: string;\n path: string;\n content: string;\n description?: string;\n source: SkillSource;\n}\n\nexport interface SkillLocation {\n path: string;\n source: SkillSource;\n}\n\nexport interface SkillResolution {\n resolved: ResolvedSkill[];\n missing: string[];\n}\n\nexport interface DiscoveredSkill {\n name: string;\n source: SkillSource;\n description?: string;\n}\n\n/**\n * Discovery and reading of skill files.\n *\n * Behind an interface for the same reason agent discovery is: the results are\n * cached and invalidated, and callers on the completion path must be able to ask\n * repeatedly without paying for a directory walk each time.\n */\nexport interface ISkillDiscoveryService {\n /** Locate one skill by name, or undefined when no root holds it. */\n resolveSkillPath(skillName: string, cwd: string): SkillLocation | undefined;\n /** Read the named skills, reporting any that could not be resolved. */\n resolveSkills(skillNames: string[], cwd: string, localSkillPaths?: string[], localBaseDir?: string): SkillResolution;\n /** Resolve against `primaryCwd`, retrying whatever is missing in `fallbackCwd`. */\n resolveSkillsWithFallback(\n skillNames: string[],\n primaryCwd: string,\n fallbackCwd?: string,\n localSkillPaths?: string[],\n localBaseDir?: string,\n ): SkillResolution;\n /** Every skill visible from `cwd`, sorted by name. */\n discoverAvailableSkills(cwd: string): DiscoveredSkill[];\n /** Drop cached results. Call after writing or removing a skill file. */\n invalidate(): void;\n}\n\n/** One entry in a listing sweep: located, but not yet read. */\ninterface CachedSkillEntry {\n name: string;\n filePath: string;\n source: SkillSource;\n description?: string;\n /** Discovery order, used to break ties between equal-priority sources. */\n order: number;\n}\n\ninterface SkillFileCacheEntry {\n mtimeMs: number;\n skill: ResolvedSkill;\n}\n\ninterface SkillListingCacheEntry {\n skills: CachedSkillEntry[];\n expiresAt: number;\n}\n\ninterface SkillSearchPath {\n path: string;\n source: SkillSource;\n}\n\n/** Roughly the number of distinct skills one session touches. */\nconst SKILL_FILE_CACHE_CAPACITY = 50;\n/** One entry per (cwd, agentDir) pair; a session rarely spans more than a few. */\nconst SKILL_LISTING_CACHE_CAPACITY = 8;\n/**\n * How long a listing stays valid.\n *\n * Short enough that a skill added mid-session appears without a restart, long\n * enough that a burst of completions does not re-walk the roots per keystroke.\n */\nconst SKILL_LISTING_TTL_MS = 5_000;\n\n/** Cache keys join two paths, so use a separator that cannot occur in either. */\nconst CACHE_KEY_SEPARATOR = '\\0';\n\n/**\n * The orchestration skill, excluded from every listing and injection.\n *\n * A subagent already has the orchestration tools wired in, so handing it the\n * skill that explains how to reach for them wastes context and invites a child\n * to fan out again. The name is the published skill's, not this package's.\n */\nconst SUBAGENT_ORCHESTRATION_SKILL = 'pi-subagents';\n\nconst SKILL_FILE_NAME = 'SKILL.md';\nconst MARKDOWN_EXTENSION = '.md';\nconst FRONTMATTER_FENCE = '---';\nconst NODE_MODULES_DIR = 'node_modules';\nconst HOME_ALIAS_PREFIX = '~/';\n\n/** Sources a listing can report, most authoritative first. */\nconst SOURCE_PRIORITY: Record<SkillSource, number> = {\n project: 700,\n 'project-settings': 650,\n user: 300,\n 'user-settings': 250,\n extension: 150,\n builtin: 100,\n unknown: 0,\n};\n\nfunction priorityOf(source: SkillSource): number {\n return SOURCE_PRIORITY[source] ?? SOURCE_PRIORITY.unknown;\n}\n\n/** Index of the first character after a closing frontmatter fence, or -1. */\nfunction findFrontmatterEnd(normalized: string): number {\n if (!normalized.startsWith(FRONTMATTER_FENCE)) return -1;\n return normalized.indexOf(`\\n${FRONTMATTER_FENCE}`, FRONTMATTER_FENCE.length);\n}\n\nexport function stripSkillFrontmatter(content: string): string {\n const normalized = content.replace(/\\r\\n/g, '\\n');\n const endIndex = findFrontmatterEnd(normalized);\n if (endIndex === -1) return normalized;\n return normalized.slice(endIndex + 1 + FRONTMATTER_FENCE.length).trim();\n}\n\nexport function parseSkillDescription(content: string): string | undefined {\n const normalized = content.replace(/\\r\\n/g, '\\n');\n const endIndex = findFrontmatterEnd(normalized);\n if (endIndex === -1) return undefined;\n\n const frontmatter = normalized.slice(FRONTMATTER_FENCE.length, endIndex).trim();\n const match = frontmatter.match(/^description:\\s*(.+)$/m);\n return match?.[1]?.trim().replace(/^['\"]|['\"]$/g, '');\n}\n\nfunction maybeReadSkillDescription(filePath: string): string | undefined {\n try {\n return parseSkillDescription(fs.readFileSync(filePath, 'utf-8'));\n } catch {\n // The description is optional metadata; an unreadable file still lists by name.\n return undefined;\n }\n}\n\nfunction isWithinPath(filePath: string, dir: string): boolean {\n const relative = path.relative(dir, filePath);\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\n/** Read a JSON file that is allowed to be absent, but not allowed to be corrupt. */\nfunction readOptionalJsonFile(filePath: string, label: string): unknown {\n try {\n const parsed: unknown = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n return parsed;\n } catch (error) {\n const code =\n typeof error === 'object' && error !== null && 'code' in error ? (error as { code?: unknown }).code : undefined;\n if (code === 'ENOENT') return null;\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to read ${label} '${filePath}': ${message}`, {\n cause: error instanceof Error ? error : undefined,\n });\n }\n}\n\n/** Extract the string entries of a settings file's `skills` array. */\nfunction readSettingsSkillList(settings: unknown): string[] {\n if (typeof settings !== 'object' || settings === null || Array.isArray(settings)) return [];\n const skills = (settings as { skills?: unknown }).skills;\n if (!Array.isArray(skills)) return [];\n return skills.filter((entry): entry is string => typeof entry === 'string');\n}\n\nfunction collectSettingsSkillPaths(cwd: string, agentDir: string): SkillSearchPath[] {\n const results: SkillSearchPath[] = [];\n const projectConfigDir = getProjectConfigDir(cwd);\n const settingsFiles = [\n { file: path.join(projectConfigDir, 'settings.json'), base: projectConfigDir, source: 'project-settings' as const },\n { file: path.join(agentDir, 'settings.json'), base: agentDir, source: 'user-settings' as const },\n ];\n\n for (const { file, base, source } of settingsFiles) {\n for (const entry of readSettingsSkillList(readOptionalJsonFile(file, 'skills settings file'))) {\n let resolved = entry;\n if (resolved.startsWith(HOME_ALIAS_PREFIX)) {\n resolved = path.join(os.homedir(), resolved.slice(HOME_ALIAS_PREFIX.length));\n } else if (!path.isAbsolute(resolved)) {\n resolved = path.resolve(base, resolved);\n }\n results.push({ path: resolved, source });\n }\n }\n\n return results;\n}\n\nfunction extraSkillPaths(): SkillSearchPath[] {\n return (process.env[EXTRA_SKILL_DIRS_ENV] ?? '')\n .split(path.delimiter)\n .map((directory) => directory.trim())\n .filter(Boolean)\n .map((directory) => ({ path: directory, source: 'extension' as const }));\n}\n\nfunction buildSkillPaths(cwd: string, agentDir: string): SkillSearchPath[] {\n const projectConfigDir = getProjectConfigDir(cwd);\n return [\n ...extraSkillPaths(),\n { path: path.join(projectConfigDir, 'skills'), source: 'project' },\n { path: path.join(cwd, '.agents', 'skills'), source: 'project' },\n { path: path.join(agentDir, 'skills'), source: 'user' },\n { path: path.join(os.homedir(), '.agents', 'skills'), source: 'user' },\n ...collectSettingsSkillPaths(cwd, agentDir),\n ];\n}\n\n/** Classify a hit that arrived without a source hint, by which root contains it. */\nfunction inferSkillSource(filePath: string, cwd: string, agentDir: string, sourceHint?: SkillSource): SkillSource {\n if (sourceHint) return sourceHint;\n\n const projectConfigRoot = path.resolve(getProjectConfigDir(cwd));\n const projectSkillsRoot = path.resolve(projectConfigRoot, 'skills');\n const projectAgentsRoot = path.resolve(cwd, '.agents');\n const userSkillsRoot = path.resolve(agentDir, 'skills');\n const userAgentRoot = path.resolve(agentDir);\n const userAgentsRoot = path.resolve(os.homedir(), '.agents');\n\n if (isWithinPath(filePath, projectSkillsRoot) || isWithinPath(filePath, projectAgentsRoot)) return 'project';\n if (isWithinPath(filePath, projectConfigRoot)) return 'project-settings';\n\n if (isWithinPath(filePath, userSkillsRoot) || isWithinPath(filePath, userAgentsRoot)) return 'user';\n if (isWithinPath(filePath, userAgentRoot)) return 'user-settings';\n\n return 'unknown';\n}\n\nfunction chooseHigherPrioritySkill(\n existing: CachedSkillEntry | undefined,\n candidate: CachedSkillEntry,\n): CachedSkillEntry {\n if (!existing) return candidate;\n const existingPriority = priorityOf(existing.source);\n const candidatePriority = priorityOf(candidate.source);\n if (candidatePriority > existingPriority) return candidate;\n if (candidatePriority < existingPriority) return existing;\n return candidate.order < existing.order ? candidate : existing;\n}\n\nfunction isMarkdownFile(fileName: string): boolean {\n return fileName.toLowerCase().endsWith(MARKDOWN_EXTENSION);\n}\n\n/** Directory names never worth descending into while hunting for skills. */\nfunction shouldSkipDirectory(name: string): boolean {\n return name.startsWith('.') || name === NODE_MODULES_DIR;\n}\n\nfunction statOrUndefined(target: string): fs.Stats | undefined {\n try {\n return fs.statSync(target);\n } catch {\n // A dangling symlink or a path removed mid-sweep is simply not a skill.\n return undefined;\n }\n}\n\nfunction readDirOrEmpty(dirPath: string): fs.Dirent[] {\n try {\n return fs.readdirSync(dirPath, { withFileTypes: true });\n } catch {\n // An unreadable root must not abort the sweep over the remaining roots.\n return [];\n }\n}\n\n/**\n * Sweep the given roots for skill files.\n *\n * Pure with respect to the caches, which is what lets it serve both the cached\n * catalogue and an agent's own uncached `skillPath` list.\n */\nfunction collectFilesystemSkills(cwd: string, agentDir: string, skillPaths: SkillSearchPath[]): CachedSkillEntry[] {\n const entries: CachedSkillEntry[] = [];\n const seen = new Map<string, number>();\n const visitedDirectories = new Map<string, number>();\n let order = 0;\n\n const pushEntry = (name: string, filePath: string, sourceHint?: SkillSource) => {\n const resolvedFile = path.resolve(filePath);\n if (!fs.existsSync(resolvedFile)) return;\n const source = inferSkillSource(resolvedFile, cwd, agentDir, sourceHint);\n const existingIndex = seen.get(resolvedFile);\n if (existingIndex !== undefined) {\n const existing = entries[existingIndex];\n if (existing && priorityOf(source) > priorityOf(existing.source)) {\n entries[existingIndex] = {\n ...existing,\n name,\n source,\n description: maybeReadSkillDescription(resolvedFile),\n };\n }\n return;\n }\n seen.set(resolvedFile, entries.length);\n entries.push({\n name,\n filePath: resolvedFile,\n source,\n description: maybeReadSkillDescription(resolvedFile),\n order: order++,\n });\n };\n\n /** False when this directory was already walked at an equal or better priority. */\n const markDirectoryVisited = (dirPath: string, sourceHint?: SkillSource): boolean => {\n let resolvedDir: string;\n try {\n resolvedDir = fs.realpathSync(dirPath);\n } catch {\n // Symlink resolution is only needed to detect cycles; the lexical path is\n // a sound fallback that at worst walks one directory twice.\n resolvedDir = path.resolve(dirPath);\n }\n const priority = sourceHint ? priorityOf(sourceHint) : SOURCE_PRIORITY.unknown;\n const previousPriority = visitedDirectories.get(resolvedDir);\n if (previousPriority !== undefined && previousPriority >= priority) return false;\n visitedDirectories.set(resolvedDir, priority);\n return true;\n };\n\n const walkSkillDirectories = (dirPath: string, sourceHint?: SkillSource) => {\n if (!markDirectoryVisited(dirPath, sourceHint)) return;\n\n // A directory holding SKILL.md is itself the skill; do not descend further.\n const skillFile = path.join(dirPath, SKILL_FILE_NAME);\n if (fs.existsSync(skillFile)) {\n pushEntry(path.basename(dirPath), skillFile, sourceHint);\n return;\n }\n\n for (const entry of readDirOrEmpty(dirPath)) {\n if (shouldSkipDirectory(entry.name)) continue;\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n\n const entryPath = path.join(dirPath, entry.name);\n if (statOrUndefined(entryPath)?.isDirectory()) walkSkillDirectories(entryPath, sourceHint);\n }\n };\n\n for (const skillPath of skillPaths) {\n if (!fs.existsSync(skillPath.path)) continue;\n\n const stat = statOrUndefined(skillPath.path);\n if (!stat) continue;\n\n // A root may point straight at a markdown file rather than a directory.\n if (stat.isFile()) {\n const fileName = path.basename(skillPath.path);\n if (!isMarkdownFile(fileName)) continue;\n const skillName =\n fileName.toLowerCase() === SKILL_FILE_NAME.toLowerCase()\n ? path.basename(path.dirname(skillPath.path))\n : path.basename(fileName, path.extname(fileName));\n pushEntry(skillName, skillPath.path, skillPath.source);\n continue;\n }\n\n if (!stat.isDirectory()) continue;\n\n const rootSkillFile = path.join(skillPath.path, SKILL_FILE_NAME);\n if (fs.existsSync(rootSkillFile)) {\n pushEntry(path.basename(skillPath.path), rootSkillFile, skillPath.source);\n continue;\n }\n\n markDirectoryVisited(skillPath.path, skillPath.source);\n\n for (const child of readDirOrEmpty(skillPath.path)) {\n if (child.name.startsWith('.')) continue;\n const childPath = path.join(skillPath.path, child.name);\n if (child.isDirectory() || child.isSymbolicLink()) {\n if (shouldSkipDirectory(child.name)) continue;\n if (statOrUndefined(childPath)?.isDirectory()) walkSkillDirectories(childPath, skillPath.source);\n continue;\n }\n if (child.isFile() && isMarkdownFile(child.name)) {\n pushEntry(path.basename(child.name, path.extname(child.name)), childPath, skillPath.source);\n }\n }\n }\n\n return entries;\n}\n\n@injectable()\nexport class SkillDiscoveryService implements ISkillDiscoveryService {\n /** Parsed skill bodies, keyed by resolved file path and validated by mtime. */\n private readonly fileCache = new LruCache<string, SkillFileCacheEntry>(SKILL_FILE_CACHE_CAPACITY);\n /** Located-but-unread catalogues, keyed by the (cwd, agentDir) pair. */\n private readonly listingCache = new LruCache<string, SkillListingCacheEntry>(SKILL_LISTING_CACHE_CAPACITY);\n\n /**\n * Seams for tests, as protected members rather than constructor arguments.\n *\n * The container resolves this service by type, and inversify cannot supply a\n * primitive like a TTL, so configuration cannot arrive through the\n * constructor. The repo convention is also not to abstract the clock, so a\n * test subclass overrides these instead.\n */\n protected readonly listingTtlMs: number = SKILL_LISTING_TTL_MS;\n\n protected now(): number {\n return Date.now();\n }\n\n resolveSkillPath(skillName: string, cwd: string): SkillLocation | undefined {\n const skill = this.listSkills(cwd).find((candidate) => candidate.name === skillName);\n if (!skill) return undefined;\n return { path: skill.filePath, source: skill.source };\n }\n\n resolveSkills(skillNames: string[], cwd: string, localSkillPaths?: string[], localBaseDir?: string): SkillResolution {\n const resolved: ResolvedSkill[] = [];\n const missing: string[] = [];\n const localByName = localSkillPaths?.length\n ? collectLocalSkills(cwd, localSkillPaths, localBaseDir)\n : new Map<string, CachedSkillEntry>();\n\n for (const name of skillNames) {\n const trimmed = name.trim();\n if (!trimmed) continue;\n if (trimmed === SUBAGENT_ORCHESTRATION_SKILL) {\n missing.push(trimmed);\n continue;\n }\n\n // An agent's own skillPath outranks anything found in the shared roots.\n const local = localByName.get(trimmed);\n let skill = local ? this.readSkill(trimmed, local.filePath, local.source) : undefined;\n if (!skill) {\n const location = this.resolveSkillPath(trimmed, cwd);\n if (location) skill = this.readSkill(trimmed, location.path, location.source);\n }\n if (skill) resolved.push(skill);\n else missing.push(trimmed);\n }\n\n return { resolved, missing };\n }\n\n /**\n * Resolve against `primaryCwd`, then retry whatever is still missing elsewhere.\n *\n * A child launched into a worktree still needs the skills configured in the\n * repository it was launched from.\n */\n resolveSkillsWithFallback(\n skillNames: string[],\n primaryCwd: string,\n fallbackCwd?: string,\n localSkillPaths?: string[],\n localBaseDir?: string,\n ): SkillResolution {\n const primary = this.resolveSkills(skillNames, primaryCwd, localSkillPaths, localBaseDir);\n if (!fallbackCwd || primary.missing.length === 0) return primary;\n if (path.resolve(primaryCwd) === path.resolve(fallbackCwd)) return primary;\n\n const fallback = this.resolveSkills(primary.missing, fallbackCwd);\n return {\n resolved: [...primary.resolved, ...fallback.resolved],\n missing: fallback.missing,\n };\n }\n\n discoverAvailableSkills(cwd: string): DiscoveredSkill[] {\n return this.listSkills(cwd)\n .filter((skill) => skill.name !== SUBAGENT_ORCHESTRATION_SKILL)\n .map((skill) => ({\n name: skill.name,\n source: skill.source,\n description: skill.description,\n }))\n .sort((a, b) => a.name.localeCompare(b.name));\n }\n\n invalidate(): void {\n this.fileCache.clear();\n this.listingCache.clear();\n }\n\n /** The catalogue visible from `cwd`, sweeping the roots only when stale. */\n private listSkills(cwd: string): CachedSkillEntry[] {\n const timestamp = this.now();\n const agentDir = getAgentDir();\n const key = `${cwd}${CACHE_KEY_SEPARATOR}${agentDir}`;\n\n const cached = this.listingCache.get(key);\n if (cached && cached.expiresAt > timestamp) return cached.skills;\n\n const loaded = collectFilesystemSkills(cwd, agentDir, buildSkillPaths(cwd, agentDir));\n const dedupedByName = new Map<string, CachedSkillEntry>();\n for (const entry of loaded) {\n dedupedByName.set(entry.name, chooseHigherPrioritySkill(dedupedByName.get(entry.name), entry));\n }\n\n const skills = [...dedupedByName.values()].sort((a, b) => a.order - b.order);\n this.listingCache.set(key, { skills, expiresAt: timestamp + this.listingTtlMs });\n return skills;\n }\n\n /** Read one skill file, reusing the cached parse while its mtime holds. */\n private readSkill(skillName: string, skillPath: string, source: SkillSource): ResolvedSkill | undefined {\n try {\n const stat = fs.statSync(skillPath);\n const cached = this.fileCache.get(skillPath);\n if (cached && cached.mtimeMs === stat.mtimeMs) return cached.skill;\n\n const raw = fs.readFileSync(skillPath, 'utf-8');\n const skill: ResolvedSkill = {\n name: skillName,\n path: skillPath,\n content: stripSkillFrontmatter(raw),\n description: parseSkillDescription(raw),\n source,\n };\n\n this.fileCache.set(skillPath, { mtimeMs: stat.mtimeMs, skill });\n return skill;\n } catch {\n // Treat an unreadable skill file as unresolved so the caller reports it\n // missing rather than injecting a half-formed block into a child prompt.\n return undefined;\n }\n }\n}\n\n/**\n * Index skill files supplied by an agent's own `skillPath`, keyed by name.\n *\n * Deliberately uncached: these paths are per-agent rather than per-directory, so\n * they would pollute a catalogue cache keyed on cwd.\n */\nfunction collectLocalSkills(\n cwd: string,\n localSkillPaths: string[],\n localBaseDir?: string,\n): Map<string, CachedSkillEntry> {\n const localByName = new Map<string, CachedSkillEntry>();\n const localEntries = collectFilesystemSkills(\n cwd,\n getAgentDir(),\n localSkillPaths.map((entry) => ({\n path: path.resolve(localBaseDir ?? cwd, entry),\n source: 'unknown' as const,\n })),\n );\n for (const entry of localEntries) {\n if (!localByName.has(entry.name)) localByName.set(entry.name, entry);\n }\n return localByName;\n}\n\nfunction escapeXmlText(value: string): string {\n return value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\n/**\n * Render the skill catalogue for a child system prompt.\n *\n * Only names, descriptions and locations are injected. The child reads a skill\n * when its description matches the task, which keeps the prompt small no matter\n * how large the configured skill bodies are.\n */\nexport function buildSkillInjection(skills: ResolvedSkill[]): string {\n if (skills.length === 0) return '';\n\n const lines = [\n 'The following configured skills are available to this subagent.',\n \"Use the read tool to load a skill's file when the task matches its description.\",\n 'When a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.',\n '',\n '<available_skills>',\n ];\n for (const skill of skills) {\n lines.push(' <skill>');\n lines.push(` <name>${escapeXmlText(skill.name)}</name>`);\n lines.push(` <description>${escapeXmlText(skill.description ?? '')}</description>`);\n lines.push(` <location>${escapeXmlText(skill.path)}</location>`);\n lines.push(' </skill>');\n }\n lines.push('</available_skills>');\n return lines.join('\\n');\n}\n\nfunction dedupeSkillNames(names: string[]): string[] {\n return [...new Set(names.map((entry) => entry.trim()).filter((entry) => entry.length > 0))];\n}\n\n/**\n * Normalise the `skills` tool parameter into a name list.\n *\n * `false` means \"no skills at all\" and `undefined` means \"use the agent's own\n * configuration\", which is why they are distinct return values rather than both\n * collapsing to an empty array.\n */\nexport function normalizeSkillInput(input: string | string[] | boolean | undefined): string[] | false | undefined {\n if (input === false) return false;\n if (input === true || input === undefined) return undefined;\n if (Array.isArray(input)) return dedupeSkillNames(input);\n\n // Models sometimes serialise the parameter as a JSON string instead of a native\n // array. Splitting '[\"a\",\"b\"]' on commas would embed brackets and quotes into\n // the names, and resolution would then fail with no obvious cause.\n const trimmed = input.trim();\n if (trimmed.startsWith('[')) {\n try {\n const parsed: unknown = JSON.parse(trimmed);\n if (Array.isArray(parsed)) {\n return dedupeSkillNames(parsed.filter((entry): entry is string => typeof entry === 'string'));\n }\n } catch {\n // Not valid JSON after all; fall through to the comma-separated reading.\n }\n }\n return dedupeSkillNames(input.split(','));\n}\n"],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- import{__esmMin as e}from"../_virtual/_rolldown/runtime.mjs";import{LruCache as t,init_lruCache as n}from"../shared/lruCache.mjs";import{getAgentDir as r,getProjectConfigDir as i,init_configDir as a}from"../shared/configDir.mjs";import{__decorate as o,init_decorate as s}from"../_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.mjs";import{init_env as c}from"../env.mjs";import*as l from"node:fs";import*as u from"node:path";import{injectable as d}from"inversify";import*as f from"node:os";function p(e){return W[e]??W.unknown}function m(e){return e.startsWith(V)?e.indexOf(`\n${V}`,3):-1}function h(e){let t=e.replace(/\r\n/g,`
2
- `),n=m(t);return n===-1?t:t.slice(n+1+3).trim()}function g(e){let t=e.replace(/\r\n/g,`
3
- `),n=m(t);if(n!==-1)return t.slice(3,n).trim().match(/^description:\s*(.+)$/m)?.[1]?.trim().replace(/^['"]|['"]$/g,``)}function _(e){try{return g(l.readFileSync(e,`utf-8`))}catch{return}}function v(e,t){let n=u.relative(t,e);return n===``||!n.startsWith(`..`)&&!u.isAbsolute(n)}function y(e,t){try{return JSON.parse(l.readFileSync(e,`utf-8`))}catch(n){if((typeof n==`object`&&n&&`code`in n?n.code:void 0)===`ENOENT`)return null;let r=n instanceof Error?n.message:String(n);throw Error(`Failed to read ${t} '${e}': ${r}`,{cause:n instanceof Error?n:void 0})}}function b(e){if(typeof e!=`object`||!e||Array.isArray(e))return[];let t=e.skills;return Array.isArray(t)?t.filter(e=>typeof e==`string`):[]}function x(e,t){let n=[],r=i(e),a=[{file:u.join(r,`settings.json`),base:r,source:`project-settings`},{file:u.join(t,`settings.json`),base:t,source:`user-settings`}];for(let{file:e,base:t,source:r}of a)for(let i of b(y(e,`skills settings file`))){let e=i;e.startsWith(U)?e=u.join(f.homedir(),e.slice(2)):u.isAbsolute(e)||(e=u.resolve(t,e)),n.push({path:e,source:r})}return n}function S(){return(process.env.PI_SUBAGENT_EXTRA_SKILL_DIRS??``).split(u.delimiter).map(e=>e.trim()).filter(Boolean).map(e=>({path:e,source:`extension`}))}function C(e,t){let n=i(e);return[...S(),{path:u.join(n,`skills`),source:`project`},{path:u.join(e,`.agents`,`skills`),source:`project`},{path:u.join(t,`skills`),source:`user`},{path:u.join(f.homedir(),`.agents`,`skills`),source:`user`},...x(e,t)]}function w(e,t,n,r){if(r)return r;let a=u.resolve(i(t)),o=u.resolve(a,`skills`),s=u.resolve(t,`.agents`),c=u.resolve(n,`skills`),l=u.resolve(n),d=u.resolve(f.homedir(),`.agents`);return v(e,o)||v(e,s)?`project`:v(e,a)?`project-settings`:v(e,c)||v(e,d)?`user`:v(e,l)?`user-settings`:`unknown`}function T(e,t){if(!e)return t;let n=p(e.source),r=p(t.source);return r>n?t:r<n?e:t.order<e.order?t:e}function E(e){return e.toLowerCase().endsWith(B)}function D(e){return e.startsWith(`.`)||e===H}function O(e){try{return l.statSync(e)}catch{return}}function k(e){try{return l.readdirSync(e,{withFileTypes:!0})}catch{return[]}}function A(e,t,n){let r=[],i=new Map,a=new Map,o=0,s=(n,a,s)=>{let c=u.resolve(a);if(!l.existsSync(c))return;let d=w(c,e,t,s),f=i.get(c);if(f!==void 0){let e=r[f];e&&p(d)>p(e.source)&&(r[f]={...e,name:n,source:d,description:_(c)});return}i.set(c,r.length),r.push({name:n,filePath:c,source:d,description:_(c),order:o++})},c=(e,t)=>{let n;try{n=l.realpathSync(e)}catch{n=u.resolve(e)}let r=t?p(t):W.unknown,i=a.get(n);return i!==void 0&&i>=r?!1:(a.set(n,r),!0)},d=(e,t)=>{if(!c(e,t))return;let n=u.join(e,z);if(l.existsSync(n)){s(u.basename(e),n,t);return}for(let n of k(e)){if(D(n.name)||!n.isDirectory()&&!n.isSymbolicLink())continue;let r=u.join(e,n.name);O(r)?.isDirectory()&&d(r,t)}};for(let e of n){if(!l.existsSync(e.path))continue;let t=O(e.path);if(!t)continue;if(t.isFile()){let t=u.basename(e.path);if(!E(t))continue;s(t.toLowerCase()===z.toLowerCase()?u.basename(u.dirname(e.path)):u.basename(t,u.extname(t)),e.path,e.source);continue}if(!t.isDirectory())continue;let n=u.join(e.path,z);if(l.existsSync(n)){s(u.basename(e.path),n,e.source);continue}c(e.path,e.source);for(let t of k(e.path)){if(t.name.startsWith(`.`))continue;let n=u.join(e.path,t.name);if(t.isDirectory()||t.isSymbolicLink()){if(D(t.name))continue;O(n)?.isDirectory()&&d(n,e.source);continue}t.isFile()&&E(t.name)&&s(u.basename(t.name,u.extname(t.name)),n,e.source)}}return r}function j(e,t,n){let i=new Map,a=A(e,r(),t.map(t=>({path:u.resolve(n??e,t),source:`unknown`})));for(let e of a)i.has(e.name)||i.set(e.name,e);return i}function M(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`)}function N(e){if(e.length===0)return``;let t=[`The following configured skills are available to this subagent.`,`Use the read tool to load a skill's file when the task matches its description.`,`When a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.`,``,`<available_skills>`];for(let n of e)t.push(` <skill>`),t.push(` <name>${M(n.name)}</name>`),t.push(` <description>${M(n.description??``)}</description>`),t.push(` <location>${M(n.path)}</location>`),t.push(` </skill>`);return t.push(`</available_skills>`),t.join(`
4
- `)}var P,F,I,L,R,z,B,V,H,U,W,G,K=e((()=>{c(),a(),n(),s(),P=50,F=8,I=5e3,L=`\0`,R=`pi-subagents`,z=`SKILL.md`,B=`.md`,V=`---`,H=`node_modules`,U=`~/`,W={project:700,"project-settings":650,user:300,"user-settings":250,extension:150,builtin:100,unknown:0},G=class{fileCache=new t(P);listingCache=new t(F);listingTtlMs=I;now(){return Date.now()}resolveSkillPath(e,t){let n=this.listSkills(t).find(t=>t.name===e);if(n)return{path:n.filePath,source:n.source}}resolveSkills(e,t,n,r){let i=[],a=[],o=n?.length?j(t,n,r):new Map;for(let n of e){let e=n.trim();if(!e)continue;if(e===R){a.push(e);continue}let r=o.get(e),s=r?this.readSkill(e,r.filePath,r.source):void 0;if(!s){let n=this.resolveSkillPath(e,t);n&&(s=this.readSkill(e,n.path,n.source))}s?i.push(s):a.push(e)}return{resolved:i,missing:a}}resolveSkillsWithFallback(e,t,n,r,i){let a=this.resolveSkills(e,t,r,i);if(!n||a.missing.length===0||u.resolve(t)===u.resolve(n))return a;let o=this.resolveSkills(a.missing,n);return{resolved:[...a.resolved,...o.resolved],missing:o.missing}}discoverAvailableSkills(e){return this.listSkills(e).filter(e=>e.name!==R).map(e=>({name:e.name,source:e.source,description:e.description})).sort((e,t)=>e.name.localeCompare(t.name))}invalidate(){this.fileCache.clear(),this.listingCache.clear()}listSkills(e){let t=this.now(),n=r(),i=`${e}${L}${n}`,a=this.listingCache.get(i);if(a&&a.expiresAt>t)return a.skills;let o=A(e,n,C(e,n)),s=new Map;for(let e of o)s.set(e.name,T(s.get(e.name),e));let c=[...s.values()].sort((e,t)=>e.order-t.order);return this.listingCache.set(i,{skills:c,expiresAt:t+this.listingTtlMs}),c}readSkill(e,t,n){try{let r=l.statSync(t),i=this.fileCache.get(t);if(i&&i.mtimeMs===r.mtimeMs)return i.skill;let a=l.readFileSync(t,`utf-8`),o={name:e,path:t,content:h(a),description:g(a),source:n};return this.fileCache.set(t,{mtimeMs:r.mtimeMs,skill:o}),o}catch{return}}},G=o([d()],G)}));K();export{G as SkillDiscoveryService,N as buildSkillInjection,K as init_skills};
5
- //# sourceMappingURL=skills.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skills.mjs","names":[],"sources":["../../src/agents/skills.ts"],"sourcesContent":["/**\n * Resolving skill files by name and rendering them into a child system prompt.\n *\n * A skill is a markdown file, either `<dir>/SKILL.md` or a bare `<name>.md`,\n * found by sweeping a fixed list of search roots. The same name can appear in\n * several roots, so the sweep records where each hit came from and the highest\n * priority source wins.\n *\n * WHY THIS IS A SERVICE AND NOT A MODULE OF FUNCTIONS:\n * Resolution walks every skill root and reads the frontmatter of every markdown\n * file it finds. Prompt assembly asks for the catalogue on each launch and\n * completion asks on each keystroke, so the answers have to be cached, and a\n * cache needs an owner that can be invalidated and swapped in a test.\n *\n * DESIGN PATTERNS:\n * - Two caches with different lifetimes. Listing answers \"does this name exist\n * and where\", reading answers \"what does it say\"; the first goes stale on any\n * directory change, the second only when one file's mtime moves\n * - Both are bounded LRUs. The predecessor held the listing in a single mutable\n * slot keyed by cwd, which thrashed the moment two working directories were in\n * play, and evicted parsed files in insertion order regardless of use\n * - Every filesystem call is best-effort. A skill root that cannot be read is\n * skipped, never fatal: a missing skill surfaces to the caller as `missing`\n * - Symlinked and repeated directories are visited at most once per priority, so\n * a cycle in the skill tree terminates\n *\n * AVOID:\n * - Walking the skill roots on a completion path without going through the cache\n * - Deriving a config directory here instead of asking `configDir.ts`\n */\n\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { injectable } from 'inversify';\n\nimport { EXTRA_SKILL_DIRS_ENV } from '../env.ts';\nimport { getAgentDir, getProjectConfigDir } from '../shared/configDir.ts';\nimport { LruCache } from '../shared/lruCache.ts';\n\n/**\n * Where a skill file was found.\n *\n * Deliberately not `AgentSource`: a skill can also come from a settings list or\n * from an extension directory, neither of which can hold an agent definition.\n */\nexport type SkillSource =\n | 'project'\n | 'user'\n | 'project-settings'\n | 'user-settings'\n | 'extension'\n | 'builtin'\n | 'unknown';\n\nexport interface ResolvedSkill {\n name: string;\n path: string;\n content: string;\n description?: string;\n source: SkillSource;\n}\n\nexport interface SkillLocation {\n path: string;\n source: SkillSource;\n}\n\nexport interface SkillResolution {\n resolved: ResolvedSkill[];\n missing: string[];\n}\n\nexport interface DiscoveredSkill {\n name: string;\n source: SkillSource;\n description?: string;\n}\n\n/**\n * Discovery and reading of skill files.\n *\n * Behind an interface for the same reason agent discovery is: the results are\n * cached and invalidated, and callers on the completion path must be able to ask\n * repeatedly without paying for a directory walk each time.\n */\nexport interface ISkillDiscoveryService {\n /** Locate one skill by name, or undefined when no root holds it. */\n resolveSkillPath(skillName: string, cwd: string): SkillLocation | undefined;\n /** Read the named skills, reporting any that could not be resolved. */\n resolveSkills(skillNames: string[], cwd: string, localSkillPaths?: string[], localBaseDir?: string): SkillResolution;\n /** Resolve against `primaryCwd`, retrying whatever is missing in `fallbackCwd`. */\n resolveSkillsWithFallback(\n skillNames: string[],\n primaryCwd: string,\n fallbackCwd?: string,\n localSkillPaths?: string[],\n localBaseDir?: string,\n ): SkillResolution;\n /** Every skill visible from `cwd`, sorted by name. */\n discoverAvailableSkills(cwd: string): DiscoveredSkill[];\n /** Drop cached results. Call after writing or removing a skill file. */\n invalidate(): void;\n}\n\n/** One entry in a listing sweep: located, but not yet read. */\ninterface CachedSkillEntry {\n name: string;\n filePath: string;\n source: SkillSource;\n description?: string;\n /** Discovery order, used to break ties between equal-priority sources. */\n order: number;\n}\n\ninterface SkillFileCacheEntry {\n mtimeMs: number;\n skill: ResolvedSkill;\n}\n\ninterface SkillListingCacheEntry {\n skills: CachedSkillEntry[];\n expiresAt: number;\n}\n\ninterface SkillSearchPath {\n path: string;\n source: SkillSource;\n}\n\n/** Roughly the number of distinct skills one session touches. */\nconst SKILL_FILE_CACHE_CAPACITY = 50;\n/** One entry per (cwd, agentDir) pair; a session rarely spans more than a few. */\nconst SKILL_LISTING_CACHE_CAPACITY = 8;\n/**\n * How long a listing stays valid.\n *\n * Short enough that a skill added mid-session appears without a restart, long\n * enough that a burst of completions does not re-walk the roots per keystroke.\n */\nconst SKILL_LISTING_TTL_MS = 5_000;\n\n/** Cache keys join two paths, so use a separator that cannot occur in either. */\nconst CACHE_KEY_SEPARATOR = '\\0';\n\n/**\n * The orchestration skill, excluded from every listing and injection.\n *\n * A subagent already has the orchestration tools wired in, so handing it the\n * skill that explains how to reach for them wastes context and invites a child\n * to fan out again. The name is the published skill's, not this package's.\n */\nconst SUBAGENT_ORCHESTRATION_SKILL = 'pi-subagents';\n\nconst SKILL_FILE_NAME = 'SKILL.md';\nconst MARKDOWN_EXTENSION = '.md';\nconst FRONTMATTER_FENCE = '---';\nconst NODE_MODULES_DIR = 'node_modules';\nconst HOME_ALIAS_PREFIX = '~/';\n\n/** Sources a listing can report, most authoritative first. */\nconst SOURCE_PRIORITY: Record<SkillSource, number> = {\n project: 700,\n 'project-settings': 650,\n user: 300,\n 'user-settings': 250,\n extension: 150,\n builtin: 100,\n unknown: 0,\n};\n\nfunction priorityOf(source: SkillSource): number {\n return SOURCE_PRIORITY[source] ?? SOURCE_PRIORITY.unknown;\n}\n\n/** Index of the first character after a closing frontmatter fence, or -1. */\nfunction findFrontmatterEnd(normalized: string): number {\n if (!normalized.startsWith(FRONTMATTER_FENCE)) return -1;\n return normalized.indexOf(`\\n${FRONTMATTER_FENCE}`, FRONTMATTER_FENCE.length);\n}\n\nexport function stripSkillFrontmatter(content: string): string {\n const normalized = content.replace(/\\r\\n/g, '\\n');\n const endIndex = findFrontmatterEnd(normalized);\n if (endIndex === -1) return normalized;\n return normalized.slice(endIndex + 1 + FRONTMATTER_FENCE.length).trim();\n}\n\nexport function parseSkillDescription(content: string): string | undefined {\n const normalized = content.replace(/\\r\\n/g, '\\n');\n const endIndex = findFrontmatterEnd(normalized);\n if (endIndex === -1) return undefined;\n\n const frontmatter = normalized.slice(FRONTMATTER_FENCE.length, endIndex).trim();\n const match = frontmatter.match(/^description:\\s*(.+)$/m);\n return match?.[1]?.trim().replace(/^['\"]|['\"]$/g, '');\n}\n\nfunction maybeReadSkillDescription(filePath: string): string | undefined {\n try {\n return parseSkillDescription(fs.readFileSync(filePath, 'utf-8'));\n } catch {\n // The description is optional metadata; an unreadable file still lists by name.\n return undefined;\n }\n}\n\nfunction isWithinPath(filePath: string, dir: string): boolean {\n const relative = path.relative(dir, filePath);\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\n/** Read a JSON file that is allowed to be absent, but not allowed to be corrupt. */\nfunction readOptionalJsonFile(filePath: string, label: string): unknown {\n try {\n const parsed: unknown = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n return parsed;\n } catch (error) {\n const code =\n typeof error === 'object' && error !== null && 'code' in error ? (error as { code?: unknown }).code : undefined;\n if (code === 'ENOENT') return null;\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to read ${label} '${filePath}': ${message}`, {\n cause: error instanceof Error ? error : undefined,\n });\n }\n}\n\n/** Extract the string entries of a settings file's `skills` array. */\nfunction readSettingsSkillList(settings: unknown): string[] {\n if (typeof settings !== 'object' || settings === null || Array.isArray(settings)) return [];\n const skills = (settings as { skills?: unknown }).skills;\n if (!Array.isArray(skills)) return [];\n return skills.filter((entry): entry is string => typeof entry === 'string');\n}\n\nfunction collectSettingsSkillPaths(cwd: string, agentDir: string): SkillSearchPath[] {\n const results: SkillSearchPath[] = [];\n const projectConfigDir = getProjectConfigDir(cwd);\n const settingsFiles = [\n { file: path.join(projectConfigDir, 'settings.json'), base: projectConfigDir, source: 'project-settings' as const },\n { file: path.join(agentDir, 'settings.json'), base: agentDir, source: 'user-settings' as const },\n ];\n\n for (const { file, base, source } of settingsFiles) {\n for (const entry of readSettingsSkillList(readOptionalJsonFile(file, 'skills settings file'))) {\n let resolved = entry;\n if (resolved.startsWith(HOME_ALIAS_PREFIX)) {\n resolved = path.join(os.homedir(), resolved.slice(HOME_ALIAS_PREFIX.length));\n } else if (!path.isAbsolute(resolved)) {\n resolved = path.resolve(base, resolved);\n }\n results.push({ path: resolved, source });\n }\n }\n\n return results;\n}\n\nfunction extraSkillPaths(): SkillSearchPath[] {\n return (process.env[EXTRA_SKILL_DIRS_ENV] ?? '')\n .split(path.delimiter)\n .map((directory) => directory.trim())\n .filter(Boolean)\n .map((directory) => ({ path: directory, source: 'extension' as const }));\n}\n\nfunction buildSkillPaths(cwd: string, agentDir: string): SkillSearchPath[] {\n const projectConfigDir = getProjectConfigDir(cwd);\n return [\n ...extraSkillPaths(),\n { path: path.join(projectConfigDir, 'skills'), source: 'project' },\n { path: path.join(cwd, '.agents', 'skills'), source: 'project' },\n { path: path.join(agentDir, 'skills'), source: 'user' },\n { path: path.join(os.homedir(), '.agents', 'skills'), source: 'user' },\n ...collectSettingsSkillPaths(cwd, agentDir),\n ];\n}\n\n/** Classify a hit that arrived without a source hint, by which root contains it. */\nfunction inferSkillSource(filePath: string, cwd: string, agentDir: string, sourceHint?: SkillSource): SkillSource {\n if (sourceHint) return sourceHint;\n\n const projectConfigRoot = path.resolve(getProjectConfigDir(cwd));\n const projectSkillsRoot = path.resolve(projectConfigRoot, 'skills');\n const projectAgentsRoot = path.resolve(cwd, '.agents');\n const userSkillsRoot = path.resolve(agentDir, 'skills');\n const userAgentRoot = path.resolve(agentDir);\n const userAgentsRoot = path.resolve(os.homedir(), '.agents');\n\n if (isWithinPath(filePath, projectSkillsRoot) || isWithinPath(filePath, projectAgentsRoot)) return 'project';\n if (isWithinPath(filePath, projectConfigRoot)) return 'project-settings';\n\n if (isWithinPath(filePath, userSkillsRoot) || isWithinPath(filePath, userAgentsRoot)) return 'user';\n if (isWithinPath(filePath, userAgentRoot)) return 'user-settings';\n\n return 'unknown';\n}\n\nfunction chooseHigherPrioritySkill(\n existing: CachedSkillEntry | undefined,\n candidate: CachedSkillEntry,\n): CachedSkillEntry {\n if (!existing) return candidate;\n const existingPriority = priorityOf(existing.source);\n const candidatePriority = priorityOf(candidate.source);\n if (candidatePriority > existingPriority) return candidate;\n if (candidatePriority < existingPriority) return existing;\n return candidate.order < existing.order ? candidate : existing;\n}\n\nfunction isMarkdownFile(fileName: string): boolean {\n return fileName.toLowerCase().endsWith(MARKDOWN_EXTENSION);\n}\n\n/** Directory names never worth descending into while hunting for skills. */\nfunction shouldSkipDirectory(name: string): boolean {\n return name.startsWith('.') || name === NODE_MODULES_DIR;\n}\n\nfunction statOrUndefined(target: string): fs.Stats | undefined {\n try {\n return fs.statSync(target);\n } catch {\n // A dangling symlink or a path removed mid-sweep is simply not a skill.\n return undefined;\n }\n}\n\nfunction readDirOrEmpty(dirPath: string): fs.Dirent[] {\n try {\n return fs.readdirSync(dirPath, { withFileTypes: true });\n } catch {\n // An unreadable root must not abort the sweep over the remaining roots.\n return [];\n }\n}\n\n/**\n * Sweep the given roots for skill files.\n *\n * Pure with respect to the caches, which is what lets it serve both the cached\n * catalogue and an agent's own uncached `skillPath` list.\n */\nfunction collectFilesystemSkills(cwd: string, agentDir: string, skillPaths: SkillSearchPath[]): CachedSkillEntry[] {\n const entries: CachedSkillEntry[] = [];\n const seen = new Map<string, number>();\n const visitedDirectories = new Map<string, number>();\n let order = 0;\n\n const pushEntry = (name: string, filePath: string, sourceHint?: SkillSource) => {\n const resolvedFile = path.resolve(filePath);\n if (!fs.existsSync(resolvedFile)) return;\n const source = inferSkillSource(resolvedFile, cwd, agentDir, sourceHint);\n const existingIndex = seen.get(resolvedFile);\n if (existingIndex !== undefined) {\n const existing = entries[existingIndex];\n if (existing && priorityOf(source) > priorityOf(existing.source)) {\n entries[existingIndex] = {\n ...existing,\n name,\n source,\n description: maybeReadSkillDescription(resolvedFile),\n };\n }\n return;\n }\n seen.set(resolvedFile, entries.length);\n entries.push({\n name,\n filePath: resolvedFile,\n source,\n description: maybeReadSkillDescription(resolvedFile),\n order: order++,\n });\n };\n\n /** False when this directory was already walked at an equal or better priority. */\n const markDirectoryVisited = (dirPath: string, sourceHint?: SkillSource): boolean => {\n let resolvedDir: string;\n try {\n resolvedDir = fs.realpathSync(dirPath);\n } catch {\n // Symlink resolution is only needed to detect cycles; the lexical path is\n // a sound fallback that at worst walks one directory twice.\n resolvedDir = path.resolve(dirPath);\n }\n const priority = sourceHint ? priorityOf(sourceHint) : SOURCE_PRIORITY.unknown;\n const previousPriority = visitedDirectories.get(resolvedDir);\n if (previousPriority !== undefined && previousPriority >= priority) return false;\n visitedDirectories.set(resolvedDir, priority);\n return true;\n };\n\n const walkSkillDirectories = (dirPath: string, sourceHint?: SkillSource) => {\n if (!markDirectoryVisited(dirPath, sourceHint)) return;\n\n // A directory holding SKILL.md is itself the skill; do not descend further.\n const skillFile = path.join(dirPath, SKILL_FILE_NAME);\n if (fs.existsSync(skillFile)) {\n pushEntry(path.basename(dirPath), skillFile, sourceHint);\n return;\n }\n\n for (const entry of readDirOrEmpty(dirPath)) {\n if (shouldSkipDirectory(entry.name)) continue;\n if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n\n const entryPath = path.join(dirPath, entry.name);\n if (statOrUndefined(entryPath)?.isDirectory()) walkSkillDirectories(entryPath, sourceHint);\n }\n };\n\n for (const skillPath of skillPaths) {\n if (!fs.existsSync(skillPath.path)) continue;\n\n const stat = statOrUndefined(skillPath.path);\n if (!stat) continue;\n\n // A root may point straight at a markdown file rather than a directory.\n if (stat.isFile()) {\n const fileName = path.basename(skillPath.path);\n if (!isMarkdownFile(fileName)) continue;\n const skillName =\n fileName.toLowerCase() === SKILL_FILE_NAME.toLowerCase()\n ? path.basename(path.dirname(skillPath.path))\n : path.basename(fileName, path.extname(fileName));\n pushEntry(skillName, skillPath.path, skillPath.source);\n continue;\n }\n\n if (!stat.isDirectory()) continue;\n\n const rootSkillFile = path.join(skillPath.path, SKILL_FILE_NAME);\n if (fs.existsSync(rootSkillFile)) {\n pushEntry(path.basename(skillPath.path), rootSkillFile, skillPath.source);\n continue;\n }\n\n markDirectoryVisited(skillPath.path, skillPath.source);\n\n for (const child of readDirOrEmpty(skillPath.path)) {\n if (child.name.startsWith('.')) continue;\n const childPath = path.join(skillPath.path, child.name);\n if (child.isDirectory() || child.isSymbolicLink()) {\n if (shouldSkipDirectory(child.name)) continue;\n if (statOrUndefined(childPath)?.isDirectory()) walkSkillDirectories(childPath, skillPath.source);\n continue;\n }\n if (child.isFile() && isMarkdownFile(child.name)) {\n pushEntry(path.basename(child.name, path.extname(child.name)), childPath, skillPath.source);\n }\n }\n }\n\n return entries;\n}\n\n@injectable()\nexport class SkillDiscoveryService implements ISkillDiscoveryService {\n /** Parsed skill bodies, keyed by resolved file path and validated by mtime. */\n private readonly fileCache = new LruCache<string, SkillFileCacheEntry>(SKILL_FILE_CACHE_CAPACITY);\n /** Located-but-unread catalogues, keyed by the (cwd, agentDir) pair. */\n private readonly listingCache = new LruCache<string, SkillListingCacheEntry>(SKILL_LISTING_CACHE_CAPACITY);\n\n /**\n * Seams for tests, as protected members rather than constructor arguments.\n *\n * The container resolves this service by type, and inversify cannot supply a\n * primitive like a TTL, so configuration cannot arrive through the\n * constructor. The repo convention is also not to abstract the clock, so a\n * test subclass overrides these instead.\n */\n protected readonly listingTtlMs: number = SKILL_LISTING_TTL_MS;\n\n protected now(): number {\n return Date.now();\n }\n\n resolveSkillPath(skillName: string, cwd: string): SkillLocation | undefined {\n const skill = this.listSkills(cwd).find((candidate) => candidate.name === skillName);\n if (!skill) return undefined;\n return { path: skill.filePath, source: skill.source };\n }\n\n resolveSkills(skillNames: string[], cwd: string, localSkillPaths?: string[], localBaseDir?: string): SkillResolution {\n const resolved: ResolvedSkill[] = [];\n const missing: string[] = [];\n const localByName = localSkillPaths?.length\n ? collectLocalSkills(cwd, localSkillPaths, localBaseDir)\n : new Map<string, CachedSkillEntry>();\n\n for (const name of skillNames) {\n const trimmed = name.trim();\n if (!trimmed) continue;\n if (trimmed === SUBAGENT_ORCHESTRATION_SKILL) {\n missing.push(trimmed);\n continue;\n }\n\n // An agent's own skillPath outranks anything found in the shared roots.\n const local = localByName.get(trimmed);\n let skill = local ? this.readSkill(trimmed, local.filePath, local.source) : undefined;\n if (!skill) {\n const location = this.resolveSkillPath(trimmed, cwd);\n if (location) skill = this.readSkill(trimmed, location.path, location.source);\n }\n if (skill) resolved.push(skill);\n else missing.push(trimmed);\n }\n\n return { resolved, missing };\n }\n\n /**\n * Resolve against `primaryCwd`, then retry whatever is still missing elsewhere.\n *\n * A child launched into a worktree still needs the skills configured in the\n * repository it was launched from.\n */\n resolveSkillsWithFallback(\n skillNames: string[],\n primaryCwd: string,\n fallbackCwd?: string,\n localSkillPaths?: string[],\n localBaseDir?: string,\n ): SkillResolution {\n const primary = this.resolveSkills(skillNames, primaryCwd, localSkillPaths, localBaseDir);\n if (!fallbackCwd || primary.missing.length === 0) return primary;\n if (path.resolve(primaryCwd) === path.resolve(fallbackCwd)) return primary;\n\n const fallback = this.resolveSkills(primary.missing, fallbackCwd);\n return {\n resolved: [...primary.resolved, ...fallback.resolved],\n missing: fallback.missing,\n };\n }\n\n discoverAvailableSkills(cwd: string): DiscoveredSkill[] {\n return this.listSkills(cwd)\n .filter((skill) => skill.name !== SUBAGENT_ORCHESTRATION_SKILL)\n .map((skill) => ({\n name: skill.name,\n source: skill.source,\n description: skill.description,\n }))\n .sort((a, b) => a.name.localeCompare(b.name));\n }\n\n invalidate(): void {\n this.fileCache.clear();\n this.listingCache.clear();\n }\n\n /** The catalogue visible from `cwd`, sweeping the roots only when stale. */\n private listSkills(cwd: string): CachedSkillEntry[] {\n const timestamp = this.now();\n const agentDir = getAgentDir();\n const key = `${cwd}${CACHE_KEY_SEPARATOR}${agentDir}`;\n\n const cached = this.listingCache.get(key);\n if (cached && cached.expiresAt > timestamp) return cached.skills;\n\n const loaded = collectFilesystemSkills(cwd, agentDir, buildSkillPaths(cwd, agentDir));\n const dedupedByName = new Map<string, CachedSkillEntry>();\n for (const entry of loaded) {\n dedupedByName.set(entry.name, chooseHigherPrioritySkill(dedupedByName.get(entry.name), entry));\n }\n\n const skills = [...dedupedByName.values()].sort((a, b) => a.order - b.order);\n this.listingCache.set(key, { skills, expiresAt: timestamp + this.listingTtlMs });\n return skills;\n }\n\n /** Read one skill file, reusing the cached parse while its mtime holds. */\n private readSkill(skillName: string, skillPath: string, source: SkillSource): ResolvedSkill | undefined {\n try {\n const stat = fs.statSync(skillPath);\n const cached = this.fileCache.get(skillPath);\n if (cached && cached.mtimeMs === stat.mtimeMs) return cached.skill;\n\n const raw = fs.readFileSync(skillPath, 'utf-8');\n const skill: ResolvedSkill = {\n name: skillName,\n path: skillPath,\n content: stripSkillFrontmatter(raw),\n description: parseSkillDescription(raw),\n source,\n };\n\n this.fileCache.set(skillPath, { mtimeMs: stat.mtimeMs, skill });\n return skill;\n } catch {\n // Treat an unreadable skill file as unresolved so the caller reports it\n // missing rather than injecting a half-formed block into a child prompt.\n return undefined;\n }\n }\n}\n\n/**\n * Index skill files supplied by an agent's own `skillPath`, keyed by name.\n *\n * Deliberately uncached: these paths are per-agent rather than per-directory, so\n * they would pollute a catalogue cache keyed on cwd.\n */\nfunction collectLocalSkills(\n cwd: string,\n localSkillPaths: string[],\n localBaseDir?: string,\n): Map<string, CachedSkillEntry> {\n const localByName = new Map<string, CachedSkillEntry>();\n const localEntries = collectFilesystemSkills(\n cwd,\n getAgentDir(),\n localSkillPaths.map((entry) => ({\n path: path.resolve(localBaseDir ?? cwd, entry),\n source: 'unknown' as const,\n })),\n );\n for (const entry of localEntries) {\n if (!localByName.has(entry.name)) localByName.set(entry.name, entry);\n }\n return localByName;\n}\n\nfunction escapeXmlText(value: string): string {\n return value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\n\n/**\n * Render the skill catalogue for a child system prompt.\n *\n * Only names, descriptions and locations are injected. The child reads a skill\n * when its description matches the task, which keeps the prompt small no matter\n * how large the configured skill bodies are.\n */\nexport function buildSkillInjection(skills: ResolvedSkill[]): string {\n if (skills.length === 0) return '';\n\n const lines = [\n 'The following configured skills are available to this subagent.',\n \"Use the read tool to load a skill's file when the task matches its description.\",\n 'When a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.',\n '',\n '<available_skills>',\n ];\n for (const skill of skills) {\n lines.push(' <skill>');\n lines.push(` <name>${escapeXmlText(skill.name)}</name>`);\n lines.push(` <description>${escapeXmlText(skill.description ?? '')}</description>`);\n lines.push(` <location>${escapeXmlText(skill.path)}</location>`);\n lines.push(' </skill>');\n }\n lines.push('</available_skills>');\n return lines.join('\\n');\n}\n\nfunction dedupeSkillNames(names: string[]): string[] {\n return [...new Set(names.map((entry) => entry.trim()).filter((entry) => entry.length > 0))];\n}\n\n/**\n * Normalise the `skills` tool parameter into a name list.\n *\n * `false` means \"no skills at all\" and `undefined` means \"use the agent's own\n * configuration\", which is why they are distinct return values rather than both\n * collapsing to an empty array.\n */\nexport function normalizeSkillInput(input: string | string[] | boolean | undefined): string[] | false | undefined {\n if (input === false) return false;\n if (input === true || input === undefined) return undefined;\n if (Array.isArray(input)) return dedupeSkillNames(input);\n\n // Models sometimes serialise the parameter as a JSON string instead of a native\n // array. Splitting '[\"a\",\"b\"]' on commas would embed brackets and quotes into\n // the names, and resolution would then fail with no obvious cause.\n const trimmed = input.trim();\n if (trimmed.startsWith('[')) {\n try {\n const parsed: unknown = JSON.parse(trimmed);\n if (Array.isArray(parsed)) {\n return dedupeSkillNames(parsed.filter((entry): entry is string => typeof entry === 'string'));\n }\n } catch {\n // Not valid JSON after all; fall through to the comma-separated reading.\n }\n }\n return dedupeSkillNames(input.split(','));\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/agents/types.ts"],"mappings":";;;;KAmBY,UAAA;AAaZ;;;;;AAEA;AAFA,KALY,WAAA;;KAGA,mBAAA;AAAA,KAEA,gBAAA;AAAA,UAEK,iBAAA;EACf,OAAA;EACA,KAAA,GAAQ,gBAAA;EACR,UAAA;AAAA;AAIF;AAAA,UAAiB,oBAAA;EACf,IAAA;EACA,KAAA;EACA,IAAA;EACA,KAAA;AAAA;;;;AAUF;;;;UAAiB,wBAAA;EACf,WAAA;EACA,KAAA;EACA,KAAA;EACA,cAAA;EACA,QAAA;EACA,gBAAA,GAAmB,gBAAA;EACnB,qBAAA;EACA,aAAA;EACA,MAAA;EACA,SAAA;EACA,UAAA;EACA,sBAAA;EACA,MAAA;EACA,YAAA;EACA,eAAA;EACA,cAAA,GAAiB,mBAAA;EACjB,gBAAA;EAJA;EAMA,OAAA;EACA,WAAA;EACA,gBAAA;EACA,eAAA;EACA,UAAA,GAAa,gBAAA;EACb,MAAA,GAAS,iBAAA;EACT,YAAA;EACA,QAAA;AAAA;;UAsCe,wBAAA;EACf,KAAA;EACA,IAAA;EACA,IAAA,EAAM,wBAAA;AAAA;;;;;;;UASS,WAAA;EACf,IAAA;EAiBA;EAfA,SAAA;EACA,WAAA;EACA,WAAA;EACA,KAAA;EACA,cAAA;EACA,KAAA;EACA,cAAA;EACA,QAAA;EACA,gBAAA,EAAkB,gBAAA;EAClB,qBAAA;EAmBA;EAjBA,aAAA;EACA,cAAA,GAAiB,mBAAA;EACjB,gBAAA;EAmBA;EAjBA,OAAA;EACA,YAAA;EACA,MAAA,EAAQ,WAAA;EACR,QAAA;EAiBA;EAfA,MAAA;EAiBc;EAfd,SAAA;EACA,UAAA;EAgBA;EAdA,qBAAA;EACA,sBAAA;EACA,MAAA;EACA,YAAA;EACA,eAAA;EACA,WAAA;EACA,gBAAA;EACA,eAAA;EACA,UAAA,GAAa,gBAAA;EACb,MAAA,GAAS,iBAAA;EACT,QAAA;;EAEA,WAAA,GAAc,MAAA;EACd,QAAA,GAAW,wBAAA;EACX,WAAA,GAAc,oBAAA;AAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/agents/types.ts"],"mappings":";;;;KAmBY,UAAA;AAaZ;;;;;AAEA;AAFA,KALY,WAAA;;KAGA,mBAAA;AAAA,KAEA,gBAAA;AAAA,UAEK,iBAAA;EACf,OAAA;EACA,KAAA,GAAQ,gBAAA;EACR,UAAA;AAAA;AAIF;AAAA,UAAiB,oBAAA;EACf,IAAA;EACA,KAAA;EACA,IAAA;EACA,KAAA;AAAA;;;;AAUF;;;;UAAiB,wBAAA;EACf,WAAA;EACA,KAAA;EACA,KAAA;EACA,cAAA;EACA,QAAA;EACA,gBAAA,GAAmB,gBAAA;EACnB,qBAAA;EACA,aAAA;EACA,MAAA;EACA,SAAA;EACA,UAAA;EACA,sBAAA;EACA,MAAA;EACA,YAAA;EACA,eAAA;EACA,cAAA,GAAiB,mBAAA;EACjB,gBAAA;EAJA;EAMA,OAAA;EACA,WAAA;EACA,gBAAA;EACA,eAAA;EACA,UAAA,GAAa,gBAAA;EACb,MAAA,GAAS,iBAAA;EACT,YAAA;EACA,QAAA;AAAA;;UAsCe,wBAAA;EACf,KAAA;EACA,IAAA;EACA,IAAA,EAAM,wBAAA;AAAA;;;;;;;UASS,WAAA;EACf,IAAA;EAiBA;EAfA,SAAA;EACA,WAAA;EACA,WAAA;EACA,KAAA;EACA,cAAA;EACA,KAAA;EACA,cAAA;EACA,QAAA;EACA,gBAAA,EAAkB,gBAAA;EAClB,qBAAA;EAmBA;EAjBA,aAAA;EACA,cAAA,GAAiB,mBAAA;EACjB,gBAAA;EAmBA;EAjBA,OAAA;EACA,YAAA;EACA,MAAA,EAAQ,WAAA;EACR,QAAA;EAiBA;EAfA,MAAA;EAiBc;EAfd,SAAA;EACA,UAAA;EAgBA;EAdA,qBAAA;EACA,sBAAA;EACA,MAAA;EACA,YAAA;EACA,eAAA;EACA,WAAA;EACA,gBAAA;EACA,eAAA;EACA,UAAA,GAAa,gBAAA;EACb,MAAA,GAAS,iBAAA;EACT,QAAA;;EAEA,WAAA,GAAc,MAAA;EACd,QAAA,GAAW,wBAAA;EACX,WAAA,GAAc,oBAAA;AAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"capabilityCeiling.mjs","names":[],"sources":["../../src/api/capabilityCeiling.ts"],"sourcesContent":["/**\n * Public entry point: subagent capability ceilings.\n *\n * Consumed by doom-plan, which registers a ceiling while planning mode is on so\n * spawned subagents inherit the same read-only restriction.\n */\n\nexport {\n decodeSubagentCapabilityCeiling,\n encodeSubagentCapabilityCeiling,\n intersectSubagentCapabilityCeilings,\n parseSubagentCapabilityCeiling,\n registerSubagentCapabilityCeiling,\n resolveCurrentSubagentCapabilityCeiling,\n resolveSubagentCapabilityCeiling,\n SUBAGENT_CAPABILITY_CEILING_ENV,\n SUBAGENT_CAPABILITY_CEILING_REGISTRY_KEY,\n SUBAGENT_CAPABILITY_CEILING_VERSION,\n type RegisterSubagentCapabilityCeilingOptions,\n type ResolvedSubagentCapabilityCeiling,\n type SubagentCapabilityAudit,\n type SubagentCapabilityCeiling,\n type SubagentCapabilityCeilingHandle,\n} from '../protocol/capabilityCeiling.ts';\n"],"mappings":"mfAuB0C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"teamSnapshot.mjs","names":[],"sources":["../../src/api/teamSnapshot.ts"],"sourcesContent":["export {\n readActiveNativeTeamSnapshot,\n type NativeTeamMemberSnapshot,\n type NativeTeamSnapshot,\n} from '../intercom/nativeTeamChannel.ts';\n"],"mappings":"gHAI0C"}
package/dist/env.cjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"env.cjs","names":[],"sources":["../src/env.ts"],"sourcesContent":["/**\n * Cross-process environment variable names.\n *\n * DESIGN PATTERNS:\n * - Zero imports, so any process role can read these without pulling in runtime\n * - Names AND values are identical to the predecessor package on purpose\n *\n * WHY THE VALUES ARE UNCHANGED:\n * `PI_SUBAGENT_CHILD` and `PI_SUBAGENT_PARENT_SESSION` are how sibling\n * extensions decide whether they are running inside a subagent child. A child\n * reads whatever its spawning parent set, so during cutover a consumer that has\n * already moved to this package can still be spawned by a doom-pi-subagents\n * parent. Re-prefixing the values would make that child fail to recognise\n * itself. Filesystem roots are namespaced instead; those are what actually\n * needed isolating.\n *\n * AVOID:\n * - Re-prefixing these values; the isolation belongs in the temp roots\n * - Hardcoding any of these literals at a call site\n */\n\nexport {\n SUBAGENT_CHILD_ENV,\n SUBAGENT_PARENT_SESSION_ENV,\n SUBAGENT_ROOT_SESSION_ENV,\n} from '@agimon-ai/doompi-extension-contracts/child-process';\n\nexport const SUBAGENT_RUN_ID_ENV = 'PI_SUBAGENT_RUN_ID';\nexport const SUBAGENT_CHILD_AGENT_ENV = 'PI_SUBAGENT_CHILD_AGENT';\nexport const SUBAGENT_CHILD_INDEX_ENV = 'PI_SUBAGENT_CHILD_INDEX';\nexport const SUBAGENT_FANOUT_CHILD_ENV = 'PI_SUBAGENT_FANOUT_CHILD';\nexport const SUBAGENT_PARENT_EVENT_SINK_ENV = 'PI_SUBAGENT_PARENT_EVENT_SINK';\nexport const SUBAGENT_PARENT_CONTROL_INBOX_ENV = 'PI_SUBAGENT_PARENT_CONTROL_INBOX';\nexport const SUBAGENT_PARENT_ROOT_RUN_ID_ENV = 'PI_SUBAGENT_PARENT_ROOT_RUN_ID';\nexport const SUBAGENT_PARENT_RUN_ID_ENV = 'PI_SUBAGENT_PARENT_RUN_ID';\nexport const SUBAGENT_PARENT_CHILD_INDEX_ENV = 'PI_SUBAGENT_PARENT_CHILD_INDEX';\nexport const SUBAGENT_PARENT_DEPTH_ENV = 'PI_SUBAGENT_PARENT_DEPTH';\nexport const SUBAGENT_PARENT_PATH_ENV = 'PI_SUBAGENT_PARENT_PATH';\nexport const SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV = 'PI_SUBAGENT_PARENT_CAPABILITY_TOKEN';\nexport const SUBAGENT_STEER_INBOX_ENV = 'PI_SUBAGENT_STEER_INBOX';\nexport const SUBAGENT_STEER_CAPABILITY_ENV = 'PI_SUBAGENT_STEER_CAPABILITY';\nexport const SUBAGENT_STEER_ACK_DIR_ENV = 'PI_SUBAGENT_STEER_ACK_DIR';\n\n/** The in-process SDK runtime. Not an external command; see `runtimeRegistry.ts`. */\nexport const PI_RUNTIME_NAME = 'pi';\n\n/**\n * Per-runtime binary override, e.g. `DOOM_TEAM_CLAUDE_BIN=/path/to/claude`.\n *\n * Uppercased and non-alphanumerics folded to `_` so a runtime name that is\n * legal in config is always a legal environment variable name.\n */\nexport function runtimeBinaryEnvVar(runtime: string): string {\n return `DOOM_TEAM_${runtime.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}_BIN`;\n}\n\nexport const SUBAGENT_TEAM_ID_ENV = 'PI_SUBAGENT_TEAM_ID';\nexport const SUBAGENT_TEAM_ROOT_SESSION_ENV = 'PI_SUBAGENT_TEAM_ROOT_SESSION';\nexport const SUBAGENT_TEAM_MAIN_MEMBER_ENV = 'PI_SUBAGENT_TEAM_MAIN_MEMBER';\nexport const SUBAGENT_TEAM_MEMBER_ID_ENV = 'PI_SUBAGENT_TEAM_MEMBER_ID';\nexport const SUBAGENT_TEAM_MEMBER_TOKEN_ENV = 'PI_SUBAGENT_TEAM_MEMBER_TOKEN';\n\nexport const SUBAGENT_CAPABILITY_CEILING_ENV = 'PI_SUBAGENT_CAPABILITY_CEILING_V1';\nexport const REQUIRED_CHILD_TOOLS_ENV = 'PI_SUBAGENT_REQUIRED_TOOLS';\nexport const MCP_DIRECT_CHILD_TOOLS_ENV = 'PI_SUBAGENT_MCP_DIRECT_TOOLS';\nexport const CHILD_TOOL_DIAGNOSTIC_PATH_ENV = 'PI_SUBAGENT_TOOL_DIAGNOSTIC_PATH';\nexport const TOOL_BUDGET_ENV = 'PI_SUBAGENT_TOOL_BUDGET';\nexport const TOOL_BUDGET_ZERO_AUTH_ENV = 'PI_SUBAGENT_TOOL_BUDGET_ZERO_AUTH';\nexport const MAX_SPAWNS_PER_SESSION_ENV = 'PI_SUBAGENT_MAX_SPAWNS_PER_SESSION';\nexport const STRUCTURED_OUTPUT_SCHEMA_ENV = 'PI_SUBAGENT_STRUCTURED_OUTPUT_SCHEMA';\nexport const STRUCTURED_OUTPUT_CAPTURE_ENV = 'PI_SUBAGENT_STRUCTURED_OUTPUT_CAPTURE';\nexport const INHERIT_PROJECT_CONTEXT_ENV = 'PI_SUBAGENT_INHERIT_PROJECT_CONTEXT';\nexport const INHERIT_SKILLS_ENV = 'PI_SUBAGENT_INHERIT_SKILLS';\n/**\n * Unprefixed on purpose: this one belongs to the Pi host, not to us. The child's\n * Pi runtime reads it directly, so the name is fixed by that contract and must\n * not be brought under the `PI_SUBAGENT_` namespace.\n */\nexport const MCP_DIRECT_TOOLS_ENV = 'MCP_DIRECT_TOOLS';\n/** Overrides where worktrees are created, for hosts whose tmpdir is unsuitable. */\nexport const WORKTREE_BASE_DIR_ENV = 'PI_SUBAGENTS_WORKTREE_DIR';\nexport const EXTRA_AGENT_DIRS_ENV = 'PI_SUBAGENT_EXTRA_AGENT_DIRS';\nexport const EXTRA_SKILL_DIRS_ENV = 'PI_SUBAGENT_EXTRA_SKILL_DIRS';\nexport const PI_SUBAGENT_PI_BINARY_ENV = 'PI_SUBAGENT_PI_BINARY';\nexport const PI_CODING_AGENT_PACKAGE_ROOT_ENV = 'PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT';\nexport const SUBAGENT_INTERCOM_SESSION_NAME_ENV = 'PI_SUBAGENT_INTERCOM_SESSION_NAME';\nexport const PI_INTERCOM_STABLE_ID_ENV = 'PI_INTERCOM_STABLE_ID';\nexport const PI_INTERCOM_SESSION_ID_ENV = 'PI_INTERCOM_SESSION_ID';\n\n/** Resolved child-safe DoomPi extensions inherited by SDK-backed agents. */\nexport const DOOMPI_CHILD_EXTENSIONS_ENV = 'DOOMPI_CHILD_EXTENSIONS';\n/** Resolved DoomPi domain skill directories inherited by SDK-backed agents. */\nexport const DOOMPI_SKILL_DIRS_ENV = 'DOOMPI_SKILL_DIRS';\n"],"mappings":"oLAoDA,SAAgB,EAAoB,EAAyB,CAC3D,MAAO,aAAa,EAAQ,aAAa,CAAC,QAAQ,cAAe,IAAI,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"env.d.cts","names":[],"sources":["../src/env.ts"],"mappings":";;;cA2Ba,mBAAA;AAAA,cACA,wBAAA;AAAA,cACA,wBAAA;AAAA,cACA,yBAAA;AAAA,cACA,8BAAA;AAAA,cACA,iCAAA;AAAA,cACA,+BAAA;AAAA,cACA,0BAAA;AAAA,cACA,+BAAA;AAAA,cACA,yBAAA;AAAA,cACA,wBAAA;AAAA,cACA,oCAAA;AAAA,cACA,wBAAA;AAAA,cACA,6BAAA;AAAA,cACA,0BAAA;;cAGA,eAAA;AAVb;;;;;AACA;AADA,iBAkBgB,mBAAA,CAAoB,OAAA;AAAA,cAIvB,oBAAA;AAAA,cACA,8BAAA;AAAA,cACA,6BAAA;AAAA,cACA,2BAAA;AAAA,cACA,8BAAA;AAAA,cAEA,+BAAA;AAAA,cACA,wBAAA;AAAA,cACA,0BAAA;AAAA,cACA,8BAAA;AAAA,cACA,eAAA;AAAA,cACA,yBAAA;AAAA,cACA,0BAAA;AAAA,cACA,4BAAA;AAAA,cACA,6BAAA;AAAA,cACA,2BAAA;AAAA,cACA,kBAAA;;;AAjCb;;;cAuCa,oBAAA;;cAEA,qBAAA;AAAA,cACA,oBAAA;AAAA,cACA,oBAAA;AAAA,cACA,yBAAA;AAAA,cACA,gCAAA;AAAA,cACA,kCAAA;AAAA,cACA,yBAAA;AAAA,cACA,0BAAA;;cAGA,2BAAA;AA9Cb;AAAA,cAgDa,qBAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"env.d.mts","names":[],"sources":["../src/env.ts"],"mappings":";;;cA2Ba,mBAAA;AAAA,cACA,wBAAA;AAAA,cACA,wBAAA;AAAA,cACA,yBAAA;AAAA,cACA,8BAAA;AAAA,cACA,iCAAA;AAAA,cACA,+BAAA;AAAA,cACA,0BAAA;AAAA,cACA,+BAAA;AAAA,cACA,yBAAA;AAAA,cACA,wBAAA;AAAA,cACA,oCAAA;AAAA,cACA,wBAAA;AAAA,cACA,6BAAA;AAAA,cACA,0BAAA;;cAGA,eAAA;AAVb;;;;;AACA;AADA,iBAkBgB,mBAAA,CAAoB,OAAA;AAAA,cAIvB,oBAAA;AAAA,cACA,8BAAA;AAAA,cACA,6BAAA;AAAA,cACA,2BAAA;AAAA,cACA,8BAAA;AAAA,cAEA,+BAAA;AAAA,cACA,wBAAA;AAAA,cACA,0BAAA;AAAA,cACA,8BAAA;AAAA,cACA,eAAA;AAAA,cACA,yBAAA;AAAA,cACA,0BAAA;AAAA,cACA,4BAAA;AAAA,cACA,6BAAA;AAAA,cACA,2BAAA;AAAA,cACA,kBAAA;;;AAjCb;;;cAuCa,oBAAA;;cAEA,qBAAA;AAAA,cACA,oBAAA;AAAA,cACA,oBAAA;AAAA,cACA,yBAAA;AAAA,cACA,gCAAA;AAAA,cACA,kCAAA;AAAA,cACA,yBAAA;AAAA,cACA,0BAAA;;cAGA,2BAAA;AA9Cb;AAAA,cAgDa,qBAAA"}