@agimon-ai/doompi-team 0.0.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (520) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +46 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.cjs +1 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.mjs +1 -0
  5. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateMetadata.cjs +1 -0
  6. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateMetadata.mjs +1 -0
  7. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateParam.cjs +1 -0
  8. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateParam.mjs +1 -0
  9. package/dist/_virtual/_rolldown/runtime.cjs +1 -0
  10. package/dist/_virtual/_rolldown/runtime.mjs +1 -0
  11. package/dist/agents/discovery.cjs +2 -0
  12. package/dist/agents/discovery.cjs.map +1 -0
  13. package/dist/agents/discovery.mjs +2 -0
  14. package/dist/agents/discovery.mjs.map +1 -0
  15. package/dist/agents/frontmatter.cjs +10 -0
  16. package/dist/agents/frontmatter.cjs.map +1 -0
  17. package/dist/agents/frontmatter.mjs +10 -0
  18. package/dist/agents/frontmatter.mjs.map +1 -0
  19. package/dist/agents/loader.cjs +2 -0
  20. package/dist/agents/loader.cjs.map +1 -0
  21. package/dist/agents/loader.mjs +2 -0
  22. package/dist/agents/loader.mjs.map +1 -0
  23. package/dist/agents/memory.cjs +3 -0
  24. package/dist/agents/memory.cjs.map +1 -0
  25. package/dist/agents/memory.mjs +3 -0
  26. package/dist/agents/memory.mjs.map +1 -0
  27. package/dist/agents/projectRoot.cjs +2 -0
  28. package/dist/agents/projectRoot.cjs.map +1 -0
  29. package/dist/agents/projectRoot.mjs +2 -0
  30. package/dist/agents/projectRoot.mjs.map +1 -0
  31. package/dist/agents/settings.cjs +2 -0
  32. package/dist/agents/settings.cjs.map +1 -0
  33. package/dist/agents/settings.mjs +2 -0
  34. package/dist/agents/settings.mjs.map +1 -0
  35. package/dist/agents/skills.cjs +0 -0
  36. package/dist/agents/skills.cjs.map +1 -0
  37. package/dist/agents/skills.mjs +5 -0
  38. package/dist/agents/skills.mjs.map +1 -0
  39. package/dist/agents/types.d.cts +121 -0
  40. package/dist/agents/types.d.cts.map +1 -0
  41. package/dist/agents/types.d.mts +121 -0
  42. package/dist/agents/types.d.mts.map +1 -0
  43. package/dist/api/backgroundWork.cjs +1 -0
  44. package/dist/api/backgroundWork.d.cts +2 -0
  45. package/dist/api/backgroundWork.d.mts +2 -0
  46. package/dist/api/backgroundWork.mjs +1 -0
  47. package/dist/api/capabilityCeiling.cjs +1 -0
  48. package/dist/api/capabilityCeiling.d.cts +3 -0
  49. package/dist/api/capabilityCeiling.d.mts +3 -0
  50. package/dist/api/capabilityCeiling.mjs +2 -0
  51. package/dist/api/capabilityCeiling.mjs.map +1 -0
  52. package/dist/api/delegation.cjs +1 -0
  53. package/dist/api/delegation.d.cts +2 -0
  54. package/dist/api/delegation.d.mts +2 -0
  55. package/dist/api/delegation.mjs +1 -0
  56. package/dist/api/teamSnapshot.cjs +1 -0
  57. package/dist/api/teamSnapshot.d.cts +2 -0
  58. package/dist/api/teamSnapshot.d.mts +2 -0
  59. package/dist/api/teamSnapshot.mjs +2 -0
  60. package/dist/api/teamSnapshot.mjs.map +1 -0
  61. package/dist/container/bindOrRebind.cjs +2 -0
  62. package/dist/container/bindOrRebind.cjs.map +1 -0
  63. package/dist/container/bindOrRebind.mjs +2 -0
  64. package/dist/container/bindOrRebind.mjs.map +1 -0
  65. package/dist/container/globalBridge.cjs +2 -0
  66. package/dist/container/globalBridge.cjs.map +1 -0
  67. package/dist/container/globalBridge.d.cts +19 -0
  68. package/dist/container/globalBridge.d.cts.map +1 -0
  69. package/dist/container/globalBridge.d.mts +19 -0
  70. package/dist/container/globalBridge.d.mts.map +1 -0
  71. package/dist/container/globalBridge.mjs +2 -0
  72. package/dist/container/globalBridge.mjs.map +1 -0
  73. package/dist/container/index.cjs +2 -0
  74. package/dist/container/index.cjs.map +1 -0
  75. package/dist/container/index.d.cts +38 -0
  76. package/dist/container/index.d.cts.map +1 -0
  77. package/dist/container/index.d.mts +38 -0
  78. package/dist/container/index.d.mts.map +1 -0
  79. package/dist/container/index.mjs +2 -0
  80. package/dist/container/index.mjs.map +1 -0
  81. package/dist/container/modules/agents.cjs +2 -0
  82. package/dist/container/modules/agents.cjs.map +1 -0
  83. package/dist/container/modules/agents.d.cts +1 -0
  84. package/dist/container/modules/agents.d.mts +1 -0
  85. package/dist/container/modules/agents.mjs +2 -0
  86. package/dist/container/modules/agents.mjs.map +1 -0
  87. package/dist/container/modules/core.cjs +2 -0
  88. package/dist/container/modules/core.cjs.map +1 -0
  89. package/dist/container/modules/core.d.cts +1 -0
  90. package/dist/container/modules/core.d.mts +1 -0
  91. package/dist/container/modules/core.mjs +2 -0
  92. package/dist/container/modules/core.mjs.map +1 -0
  93. package/dist/container/modules/extensions.cjs +2 -0
  94. package/dist/container/modules/extensions.cjs.map +1 -0
  95. package/dist/container/modules/extensions.mjs +2 -0
  96. package/dist/container/modules/extensions.mjs.map +1 -0
  97. package/dist/container/modules/intercom.cjs +2 -0
  98. package/dist/container/modules/intercom.cjs.map +1 -0
  99. package/dist/container/modules/intercom.mjs +2 -0
  100. package/dist/container/modules/intercom.mjs.map +1 -0
  101. package/dist/container/modules/runs.cjs +2 -0
  102. package/dist/container/modules/runs.cjs.map +1 -0
  103. package/dist/container/modules/runs.mjs +2 -0
  104. package/dist/container/modules/runs.mjs.map +1 -0
  105. package/dist/container/types.cjs +2 -0
  106. package/dist/container/types.cjs.map +1 -0
  107. package/dist/container/types.d.cts +45 -0
  108. package/dist/container/types.d.cts.map +1 -0
  109. package/dist/container/types.d.mts +45 -0
  110. package/dist/container/types.d.mts.map +1 -0
  111. package/dist/container/types.mjs +2 -0
  112. package/dist/container/types.mjs.map +1 -0
  113. package/dist/env.cjs +2 -0
  114. package/dist/env.cjs.map +1 -0
  115. package/dist/env.d.cts +65 -0
  116. package/dist/env.d.cts.map +1 -0
  117. package/dist/env.d.mts +65 -0
  118. package/dist/env.d.mts.map +1 -0
  119. package/dist/env.mjs +2 -0
  120. package/dist/env.mjs.map +1 -0
  121. package/dist/extension.cjs +2 -0
  122. package/dist/extension.cjs.map +1 -0
  123. package/dist/extension.mjs +2 -0
  124. package/dist/extension.mjs.map +1 -0
  125. package/dist/extensions/config.cjs +2 -0
  126. package/dist/extensions/config.cjs.map +1 -0
  127. package/dist/extensions/config.mjs +2 -0
  128. package/dist/extensions/config.mjs.map +1 -0
  129. package/dist/extensions/delegationBridge.cjs +2 -0
  130. package/dist/extensions/delegationBridge.cjs.map +1 -0
  131. package/dist/extensions/delegationBridge.mjs +2 -0
  132. package/dist/extensions/delegationBridge.mjs.map +1 -0
  133. package/dist/extensions/doom.cjs +2 -0
  134. package/dist/extensions/doom.cjs.map +1 -0
  135. package/dist/extensions/doom.d.cts +8 -0
  136. package/dist/extensions/doom.d.cts.map +1 -0
  137. package/dist/extensions/doom.d.mts +8 -0
  138. package/dist/extensions/doom.d.mts.map +1 -0
  139. package/dist/extensions/doom.mjs +2 -0
  140. package/dist/extensions/doom.mjs.map +1 -0
  141. package/dist/extensions/fablePlanBridge.cjs +2 -0
  142. package/dist/extensions/fablePlanBridge.cjs.map +1 -0
  143. package/dist/extensions/fablePlanBridge.mjs +2 -0
  144. package/dist/extensions/fablePlanBridge.mjs.map +1 -0
  145. package/dist/extensions/managementActions.cjs +2 -0
  146. package/dist/extensions/managementActions.cjs.map +1 -0
  147. package/dist/extensions/managementActions.mjs +2 -0
  148. package/dist/extensions/managementActions.mjs.map +1 -0
  149. package/dist/extensions/operationJournal.cjs +2 -0
  150. package/dist/extensions/operationJournal.cjs.map +1 -0
  151. package/dist/extensions/operationJournal.mjs +2 -0
  152. package/dist/extensions/operationJournal.mjs.map +1 -0
  153. package/dist/extensions/orchestratorPrompt.cjs +35 -0
  154. package/dist/extensions/orchestratorPrompt.cjs.map +1 -0
  155. package/dist/extensions/orchestratorPrompt.mjs +35 -0
  156. package/dist/extensions/orchestratorPrompt.mjs.map +1 -0
  157. package/dist/extensions/pi.cjs +2 -0
  158. package/dist/extensions/pi.cjs.map +1 -0
  159. package/dist/extensions/pi.d.cts +2 -0
  160. package/dist/extensions/pi.d.mts +2 -0
  161. package/dist/extensions/pi.mjs +2 -0
  162. package/dist/extensions/pi.mjs.map +1 -0
  163. package/dist/extensions/schemas.cjs +1 -0
  164. package/dist/extensions/schemas.mjs +2 -0
  165. package/dist/extensions/schemas.mjs.map +1 -0
  166. package/dist/extensions/spawnPlan.cjs +3 -0
  167. package/dist/extensions/spawnPlan.cjs.map +1 -0
  168. package/dist/extensions/spawnPlan.mjs +3 -0
  169. package/dist/extensions/spawnPlan.mjs.map +1 -0
  170. package/dist/extensions/standard.cjs +2 -0
  171. package/dist/extensions/standard.cjs.map +1 -0
  172. package/dist/extensions/standard.d.cts +8 -0
  173. package/dist/extensions/standard.d.cts.map +1 -0
  174. package/dist/extensions/standard.d.mts +8 -0
  175. package/dist/extensions/standard.d.mts.map +1 -0
  176. package/dist/extensions/standard.mjs +2 -0
  177. package/dist/extensions/standard.mjs.map +1 -0
  178. package/dist/extensions/statusViews.cjs +7 -0
  179. package/dist/extensions/statusViews.cjs.map +1 -0
  180. package/dist/extensions/statusViews.mjs +7 -0
  181. package/dist/extensions/statusViews.mjs.map +1 -0
  182. package/dist/extensions/subagentPromptRuntime.cjs +18 -0
  183. package/dist/extensions/subagentPromptRuntime.cjs.map +1 -0
  184. package/dist/extensions/subagentPromptRuntime.d.cts +58 -0
  185. package/dist/extensions/subagentPromptRuntime.d.cts.map +1 -0
  186. package/dist/extensions/subagentPromptRuntime.d.mts +58 -0
  187. package/dist/extensions/subagentPromptRuntime.d.mts.map +1 -0
  188. package/dist/extensions/subagentPromptRuntime.mjs +18 -0
  189. package/dist/extensions/subagentPromptRuntime.mjs.map +1 -0
  190. package/dist/extensions/subagentPromptRuntimeEntry.cjs +2 -0
  191. package/dist/extensions/subagentPromptRuntimeEntry.cjs.map +1 -0
  192. package/dist/extensions/subagentPromptRuntimeEntry.d.cts +2 -0
  193. package/dist/extensions/subagentPromptRuntimeEntry.d.mts +2 -0
  194. package/dist/extensions/subagentPromptRuntimeEntry.mjs +2 -0
  195. package/dist/extensions/subagentPromptRuntimeEntry.mjs.map +1 -0
  196. package/dist/extensions/subagentTool.cjs +7 -0
  197. package/dist/extensions/subagentTool.cjs.map +1 -0
  198. package/dist/extensions/subagentTool.mjs +7 -0
  199. package/dist/extensions/subagentTool.mjs.map +1 -0
  200. package/dist/extensions/toolDescription.cjs +2 -0
  201. package/dist/extensions/toolDescription.cjs.map +1 -0
  202. package/dist/extensions/toolDescription.mjs +2 -0
  203. package/dist/extensions/toolDescription.mjs.map +1 -0
  204. package/dist/index.cjs +2 -0
  205. package/dist/index.cjs.map +1 -0
  206. package/dist/index.d.cts +34 -0
  207. package/dist/index.d.cts.map +1 -0
  208. package/dist/index.d.mts +34 -0
  209. package/dist/index.d.mts.map +1 -0
  210. package/dist/index.mjs +2 -0
  211. package/dist/index.mjs.map +1 -0
  212. package/dist/intercom/intercomBridge.cjs +2 -0
  213. package/dist/intercom/intercomBridge.cjs.map +1 -0
  214. package/dist/intercom/intercomBridge.mjs +2 -0
  215. package/dist/intercom/intercomBridge.mjs.map +1 -0
  216. package/dist/intercom/nativeTeamChannel.cjs +5 -0
  217. package/dist/intercom/nativeTeamChannel.cjs.map +1 -0
  218. package/dist/intercom/nativeTeamChannel.d.cts +22 -0
  219. package/dist/intercom/nativeTeamChannel.d.cts.map +1 -0
  220. package/dist/intercom/nativeTeamChannel.d.mts +22 -0
  221. package/dist/intercom/nativeTeamChannel.d.mts.map +1 -0
  222. package/dist/intercom/nativeTeamChannel.mjs +5 -0
  223. package/dist/intercom/nativeTeamChannel.mjs.map +1 -0
  224. package/dist/intercom/supervisorControlChannel.cjs +2 -0
  225. package/dist/intercom/supervisorControlChannel.cjs.map +1 -0
  226. package/dist/intercom/supervisorControlChannel.mjs +2 -0
  227. package/dist/intercom/supervisorControlChannel.mjs.map +1 -0
  228. package/dist/protocol/backgroundWork.cjs +2 -0
  229. package/dist/protocol/backgroundWork.cjs.map +1 -0
  230. package/dist/protocol/backgroundWork.d.cts +52 -0
  231. package/dist/protocol/backgroundWork.d.cts.map +1 -0
  232. package/dist/protocol/backgroundWork.d.mts +52 -0
  233. package/dist/protocol/backgroundWork.d.mts.map +1 -0
  234. package/dist/protocol/backgroundWork.mjs +2 -0
  235. package/dist/protocol/backgroundWork.mjs.map +1 -0
  236. package/dist/protocol/capabilityCeiling.cjs +2 -0
  237. package/dist/protocol/capabilityCeiling.cjs.map +1 -0
  238. package/dist/protocol/capabilityCeiling.d.cts +51 -0
  239. package/dist/protocol/capabilityCeiling.d.cts.map +1 -0
  240. package/dist/protocol/capabilityCeiling.d.mts +51 -0
  241. package/dist/protocol/capabilityCeiling.d.mts.map +1 -0
  242. package/dist/protocol/capabilityCeiling.mjs +2 -0
  243. package/dist/protocol/capabilityCeiling.mjs.map +1 -0
  244. package/dist/protocol/delegation.cjs +2 -0
  245. package/dist/protocol/delegation.cjs.map +1 -0
  246. package/dist/protocol/delegation.d.cts +269 -0
  247. package/dist/protocol/delegation.d.cts.map +1 -0
  248. package/dist/protocol/delegation.d.mts +269 -0
  249. package/dist/protocol/delegation.d.mts.map +1 -0
  250. package/dist/protocol/delegation.mjs +2 -0
  251. package/dist/protocol/delegation.mjs.map +1 -0
  252. package/dist/runs/background/asyncExecution.cjs +2 -0
  253. package/dist/runs/background/asyncExecution.cjs.map +1 -0
  254. package/dist/runs/background/asyncExecution.mjs +2 -0
  255. package/dist/runs/background/asyncExecution.mjs.map +1 -0
  256. package/dist/runs/background/asyncJobTracker.cjs +2 -0
  257. package/dist/runs/background/asyncJobTracker.cjs.map +1 -0
  258. package/dist/runs/background/asyncJobTracker.mjs +2 -0
  259. package/dist/runs/background/asyncJobTracker.mjs.map +1 -0
  260. package/dist/runs/background/cliRunnerEntry.cjs +2 -0
  261. package/dist/runs/background/cliRunnerEntry.cjs.map +1 -0
  262. package/dist/runs/background/cliRunnerEntry.d.cts +1 -0
  263. package/dist/runs/background/cliRunnerEntry.d.mts +1 -0
  264. package/dist/runs/background/cliRunnerEntry.mjs +2 -0
  265. package/dist/runs/background/cliRunnerEntry.mjs.map +1 -0
  266. package/dist/runs/background/completionBatcher.cjs +2 -0
  267. package/dist/runs/background/completionBatcher.cjs.map +1 -0
  268. package/dist/runs/background/completionBatcher.mjs +2 -0
  269. package/dist/runs/background/completionBatcher.mjs.map +1 -0
  270. package/dist/runs/background/notify.cjs +4 -0
  271. package/dist/runs/background/notify.cjs.map +1 -0
  272. package/dist/runs/background/notify.mjs +4 -0
  273. package/dist/runs/background/notify.mjs.map +1 -0
  274. package/dist/runs/background/parentWatchdog.cjs +2 -0
  275. package/dist/runs/background/parentWatchdog.cjs.map +1 -0
  276. package/dist/runs/background/parentWatchdog.mjs +2 -0
  277. package/dist/runs/background/parentWatchdog.mjs.map +1 -0
  278. package/dist/runs/background/processTerminal.cjs +2 -0
  279. package/dist/runs/background/processTerminal.cjs.map +1 -0
  280. package/dist/runs/background/processTerminal.mjs +2 -0
  281. package/dist/runs/background/processTerminal.mjs.map +1 -0
  282. package/dist/runs/background/resultWatcher.cjs +2 -0
  283. package/dist/runs/background/resultWatcher.cjs.map +1 -0
  284. package/dist/runs/background/resultWatcher.mjs +2 -0
  285. package/dist/runs/background/resultWatcher.mjs.map +1 -0
  286. package/dist/runs/background/runIdResolver.cjs +2 -0
  287. package/dist/runs/background/runIdResolver.cjs.map +1 -0
  288. package/dist/runs/background/runIdResolver.mjs +2 -0
  289. package/dist/runs/background/runIdResolver.mjs.map +1 -0
  290. package/dist/runs/background/runnerBootstrap.cjs +2 -0
  291. package/dist/runs/background/runnerBootstrap.cjs.map +1 -0
  292. package/dist/runs/background/runnerBootstrap.mjs +2 -0
  293. package/dist/runs/background/runnerBootstrap.mjs.map +1 -0
  294. package/dist/runs/background/runnerExecution.cjs +2 -0
  295. package/dist/runs/background/runnerExecution.cjs.map +1 -0
  296. package/dist/runs/background/runnerExecution.mjs +2 -0
  297. package/dist/runs/background/runnerExecution.mjs.map +1 -0
  298. package/dist/runs/background/runnerReporting.cjs +3 -0
  299. package/dist/runs/background/runnerReporting.cjs.map +1 -0
  300. package/dist/runs/background/runnerReporting.mjs +3 -0
  301. package/dist/runs/background/runnerReporting.mjs.map +1 -0
  302. package/dist/runs/background/runnerTeamMembership.cjs +2 -0
  303. package/dist/runs/background/runnerTeamMembership.cjs.map +1 -0
  304. package/dist/runs/background/runnerTeamMembership.mjs +2 -0
  305. package/dist/runs/background/runnerTeamMembership.mjs.map +1 -0
  306. package/dist/runs/background/spawnHandshake.cjs +2 -0
  307. package/dist/runs/background/spawnHandshake.cjs.map +1 -0
  308. package/dist/runs/background/spawnHandshake.mjs +2 -0
  309. package/dist/runs/background/spawnHandshake.mjs.map +1 -0
  310. package/dist/runs/background/staleRunReconciler.cjs +2 -0
  311. package/dist/runs/background/staleRunReconciler.cjs.map +1 -0
  312. package/dist/runs/background/staleRunReconciler.mjs +2 -0
  313. package/dist/runs/background/staleRunReconciler.mjs.map +1 -0
  314. package/dist/runs/background/statusReader.cjs +2 -0
  315. package/dist/runs/background/statusReader.cjs.map +1 -0
  316. package/dist/runs/background/statusReader.mjs +2 -0
  317. package/dist/runs/background/statusReader.mjs.map +1 -0
  318. package/dist/runs/background/statusWriter.cjs +2 -0
  319. package/dist/runs/background/statusWriter.cjs.map +1 -0
  320. package/dist/runs/background/statusWriter.mjs +2 -0
  321. package/dist/runs/background/statusWriter.mjs.map +1 -0
  322. package/dist/runs/background/subagentWait.cjs +2 -0
  323. package/dist/runs/background/subagentWait.cjs.map +1 -0
  324. package/dist/runs/background/subagentWait.mjs +2 -0
  325. package/dist/runs/background/subagentWait.mjs.map +1 -0
  326. package/dist/runs/background/terminalPersistence.cjs +2 -0
  327. package/dist/runs/background/terminalPersistence.cjs.map +1 -0
  328. package/dist/runs/background/terminalPersistence.mjs +2 -0
  329. package/dist/runs/background/terminalPersistence.mjs.map +1 -0
  330. package/dist/runs/registry/processGroup.cjs +2 -0
  331. package/dist/runs/registry/processGroup.cjs.map +1 -0
  332. package/dist/runs/registry/processGroup.mjs +2 -0
  333. package/dist/runs/registry/processGroup.mjs.map +1 -0
  334. package/dist/runs/registry/runRegistry.cjs +2 -0
  335. package/dist/runs/registry/runRegistry.cjs.map +1 -0
  336. package/dist/runs/registry/runRegistry.mjs +2 -0
  337. package/dist/runs/registry/runRegistry.mjs.map +1 -0
  338. package/dist/runs/registry/sessionLifecycle.cjs +2 -0
  339. package/dist/runs/registry/sessionLifecycle.cjs.map +1 -0
  340. package/dist/runs/registry/sessionLifecycle.mjs +2 -0
  341. package/dist/runs/registry/sessionLifecycle.mjs.map +1 -0
  342. package/dist/runs/registry/suspendedRuns.cjs +4 -0
  343. package/dist/runs/registry/suspendedRuns.cjs.map +1 -0
  344. package/dist/runs/registry/suspendedRuns.mjs +4 -0
  345. package/dist/runs/registry/suspendedRuns.mjs.map +1 -0
  346. package/dist/runs/sdkRunnerEntry.cjs +2 -0
  347. package/dist/runs/sdkRunnerEntry.cjs.map +1 -0
  348. package/dist/runs/sdkRunnerEntry.d.cts +1 -0
  349. package/dist/runs/sdkRunnerEntry.d.mts +1 -0
  350. package/dist/runs/sdkRunnerEntry.mjs +2 -0
  351. package/dist/runs/sdkRunnerEntry.mjs.map +1 -0
  352. package/dist/runs/shared/claudeFableProfile.cjs +4 -0
  353. package/dist/runs/shared/claudeFableProfile.cjs.map +1 -0
  354. package/dist/runs/shared/claudeFableProfile.mjs +4 -0
  355. package/dist/runs/shared/claudeFableProfile.mjs.map +1 -0
  356. package/dist/runs/shared/depthGuard.cjs +2 -0
  357. package/dist/runs/shared/depthGuard.cjs.map +1 -0
  358. package/dist/runs/shared/depthGuard.mjs +2 -0
  359. package/dist/runs/shared/depthGuard.mjs.map +1 -0
  360. package/dist/runs/shared/mcpDirectToolAllowlist.cjs +2 -0
  361. package/dist/runs/shared/mcpDirectToolAllowlist.cjs.map +1 -0
  362. package/dist/runs/shared/mcpDirectToolAllowlist.mjs +2 -0
  363. package/dist/runs/shared/mcpDirectToolAllowlist.mjs.map +1 -0
  364. package/dist/runs/shared/modelFallback.cjs +2 -0
  365. package/dist/runs/shared/modelFallback.cjs.map +1 -0
  366. package/dist/runs/shared/modelFallback.mjs +2 -0
  367. package/dist/runs/shared/modelFallback.mjs.map +1 -0
  368. package/dist/runs/shared/modelScope.cjs +2 -0
  369. package/dist/runs/shared/modelScope.cjs.map +1 -0
  370. package/dist/runs/shared/modelScope.mjs +2 -0
  371. package/dist/runs/shared/modelScope.mjs.map +1 -0
  372. package/dist/runs/shared/nestedPath.cjs +2 -0
  373. package/dist/runs/shared/nestedPath.cjs.map +1 -0
  374. package/dist/runs/shared/nestedPath.mjs +2 -0
  375. package/dist/runs/shared/nestedPath.mjs.map +1 -0
  376. package/dist/runs/shared/piArgs.cjs +2 -0
  377. package/dist/runs/shared/piArgs.cjs.map +1 -0
  378. package/dist/runs/shared/piArgs.mjs +2 -0
  379. package/dist/runs/shared/piArgs.mjs.map +1 -0
  380. package/dist/runs/shared/piSpawn.cjs +2 -0
  381. package/dist/runs/shared/piSpawn.cjs.map +1 -0
  382. package/dist/runs/shared/piSpawn.mjs +2 -0
  383. package/dist/runs/shared/piSpawn.mjs.map +1 -0
  384. package/dist/runs/shared/runWithConcurrency.cjs +2 -0
  385. package/dist/runs/shared/runWithConcurrency.cjs.map +1 -0
  386. package/dist/runs/shared/runWithConcurrency.mjs +2 -0
  387. package/dist/runs/shared/runWithConcurrency.mjs.map +1 -0
  388. package/dist/runs/shared/runtimeRegistry.cjs +2 -0
  389. package/dist/runs/shared/runtimeRegistry.cjs.map +1 -0
  390. package/dist/runs/shared/runtimeRegistry.mjs +2 -0
  391. package/dist/runs/shared/runtimeRegistry.mjs.map +1 -0
  392. package/dist/runs/shared/structuredOutput.cjs +2 -0
  393. package/dist/runs/shared/structuredOutput.cjs.map +1 -0
  394. package/dist/runs/shared/structuredOutput.mjs +2 -0
  395. package/dist/runs/shared/structuredOutput.mjs.map +1 -0
  396. package/dist/runs/shared/toolAvailability.cjs +2 -0
  397. package/dist/runs/shared/toolAvailability.cjs.map +1 -0
  398. package/dist/runs/shared/toolAvailability.mjs +2 -0
  399. package/dist/runs/shared/toolAvailability.mjs.map +1 -0
  400. package/dist/runs/shared/toolBudget.cjs +2 -0
  401. package/dist/runs/shared/toolBudget.cjs.map +1 -0
  402. package/dist/runs/shared/toolBudget.mjs +2 -0
  403. package/dist/runs/shared/toolBudget.mjs.map +1 -0
  404. package/dist/shared/artifacts.cjs +2 -0
  405. package/dist/shared/artifacts.cjs.map +1 -0
  406. package/dist/shared/artifacts.mjs +2 -0
  407. package/dist/shared/artifacts.mjs.map +1 -0
  408. package/dist/shared/atomicJson.cjs +2 -0
  409. package/dist/shared/atomicJson.cjs.map +1 -0
  410. package/dist/shared/atomicJson.mjs +2 -0
  411. package/dist/shared/atomicJson.mjs.map +1 -0
  412. package/dist/shared/boundedKeySet.cjs +2 -0
  413. package/dist/shared/boundedKeySet.cjs.map +1 -0
  414. package/dist/shared/boundedKeySet.mjs +2 -0
  415. package/dist/shared/boundedKeySet.mjs.map +1 -0
  416. package/dist/shared/childTranscript.cjs +5 -0
  417. package/dist/shared/childTranscript.cjs.map +1 -0
  418. package/dist/shared/childTranscript.mjs +5 -0
  419. package/dist/shared/childTranscript.mjs.map +1 -0
  420. package/dist/shared/configDir.cjs +2 -0
  421. package/dist/shared/configDir.cjs.map +1 -0
  422. package/dist/shared/configDir.mjs +2 -0
  423. package/dist/shared/configDir.mjs.map +1 -0
  424. package/dist/shared/errors.cjs +2 -0
  425. package/dist/shared/errors.cjs.map +1 -0
  426. package/dist/shared/errors.mjs +2 -0
  427. package/dist/shared/errors.mjs.map +1 -0
  428. package/dist/shared/fileSystemRetry.cjs +2 -0
  429. package/dist/shared/fileSystemRetry.cjs.map +1 -0
  430. package/dist/shared/fileSystemRetry.mjs +2 -0
  431. package/dist/shared/fileSystemRetry.mjs.map +1 -0
  432. package/dist/shared/formatters.cjs +2 -0
  433. package/dist/shared/formatters.cjs.map +1 -0
  434. package/dist/shared/formatters.mjs +2 -0
  435. package/dist/shared/formatters.mjs.map +1 -0
  436. package/dist/shared/lruCache.cjs +2 -0
  437. package/dist/shared/lruCache.cjs.map +1 -0
  438. package/dist/shared/lruCache.mjs +2 -0
  439. package/dist/shared/lruCache.mjs.map +1 -0
  440. package/dist/shared/modelInfo.cjs +2 -0
  441. package/dist/shared/modelInfo.cjs.map +1 -0
  442. package/dist/shared/modelInfo.mjs +2 -0
  443. package/dist/shared/modelInfo.mjs.map +1 -0
  444. package/dist/shared/modelResolution.cjs +2 -0
  445. package/dist/shared/modelResolution.cjs.map +1 -0
  446. package/dist/shared/modelResolution.mjs +2 -0
  447. package/dist/shared/modelResolution.mjs.map +1 -0
  448. package/dist/shared/paths.cjs +2 -0
  449. package/dist/shared/paths.cjs.map +1 -0
  450. package/dist/shared/paths.mjs +2 -0
  451. package/dist/shared/paths.mjs.map +1 -0
  452. package/dist/shared/pollScheduler.cjs +2 -0
  453. package/dist/shared/pollScheduler.cjs.map +1 -0
  454. package/dist/shared/pollScheduler.mjs +2 -0
  455. package/dist/shared/pollScheduler.mjs.map +1 -0
  456. package/dist/shared/scopeOwner.cjs +2 -0
  457. package/dist/shared/scopeOwner.cjs.map +1 -0
  458. package/dist/shared/scopeOwner.mjs +2 -0
  459. package/dist/shared/scopeOwner.mjs.map +1 -0
  460. package/dist/shared/versioned.cjs +2 -0
  461. package/dist/shared/versioned.cjs.map +1 -0
  462. package/dist/shared/versioned.mjs +2 -0
  463. package/dist/shared/versioned.mjs.map +1 -0
  464. package/dist/slash/chainExpression.cjs +2 -0
  465. package/dist/slash/chainExpression.cjs.map +1 -0
  466. package/dist/slash/chainExpression.mjs +2 -0
  467. package/dist/slash/chainExpression.mjs.map +1 -0
  468. package/dist/slash/doctor.cjs +5 -0
  469. package/dist/slash/doctor.cjs.map +1 -0
  470. package/dist/slash/doctor.mjs +5 -0
  471. package/dist/slash/doctor.mjs.map +1 -0
  472. package/dist/slash/slashCommands.cjs +4 -0
  473. package/dist/slash/slashCommands.cjs.map +1 -0
  474. package/dist/slash/slashCommands.mjs +4 -0
  475. package/dist/slash/slashCommands.mjs.map +1 -0
  476. package/dist/slash/spawnRequestMapping.cjs +2 -0
  477. package/dist/slash/spawnRequestMapping.cjs.map +1 -0
  478. package/dist/slash/spawnRequestMapping.mjs +2 -0
  479. package/dist/slash/spawnRequestMapping.mjs.map +1 -0
  480. package/dist/slash/subagentLaunch.cjs +2 -0
  481. package/dist/slash/subagentLaunch.cjs.map +1 -0
  482. package/dist/slash/subagentLaunch.mjs +2 -0
  483. package/dist/slash/subagentLaunch.mjs.map +1 -0
  484. package/dist/tui/agentCatalog.cjs +2 -0
  485. package/dist/tui/agentCatalog.cjs.map +1 -0
  486. package/dist/tui/agentCatalog.mjs +2 -0
  487. package/dist/tui/agentCatalog.mjs.map +1 -0
  488. package/dist/tui/agentResourceProjection.cjs +2 -0
  489. package/dist/tui/agentResourceProjection.cjs.map +1 -0
  490. package/dist/tui/agentResourceProjection.mjs +2 -0
  491. package/dist/tui/agentResourceProjection.mjs.map +1 -0
  492. package/dist/tui/completionNotice.cjs +5 -0
  493. package/dist/tui/completionNotice.cjs.map +1 -0
  494. package/dist/tui/completionNotice.mjs +5 -0
  495. package/dist/tui/completionNotice.mjs.map +1 -0
  496. package/dist/tui/fleet.cjs +3 -0
  497. package/dist/tui/fleet.cjs.map +1 -0
  498. package/dist/tui/fleet.mjs +3 -0
  499. package/dist/tui/fleet.mjs.map +1 -0
  500. package/dist/tui/fleetAgentView.cjs +2 -0
  501. package/dist/tui/fleetAgentView.cjs.map +1 -0
  502. package/dist/tui/fleetAgentView.mjs +2 -0
  503. package/dist/tui/fleetAgentView.mjs.map +1 -0
  504. package/dist/tui/fleetStatus.cjs +2 -0
  505. package/dist/tui/fleetStatus.cjs.map +1 -0
  506. package/dist/tui/fleetStatus.mjs +2 -0
  507. package/dist/tui/fleetStatus.mjs.map +1 -0
  508. package/dist/tui/fleetTranscript.cjs +5 -0
  509. package/dist/tui/fleetTranscript.cjs.map +1 -0
  510. package/dist/tui/fleetTranscript.mjs +5 -0
  511. package/dist/tui/fleetTranscript.mjs.map +1 -0
  512. package/dist/tui/register.cjs +2 -0
  513. package/dist/tui/register.cjs.map +1 -0
  514. package/dist/tui/register.mjs +2 -0
  515. package/dist/tui/register.mjs.map +1 -0
  516. package/dist/types.d.cts +59 -0
  517. package/dist/types.d.cts.map +1 -0
  518. package/dist/types.d.mts +59 -0
  519. package/dist/types.d.mts.map +1 -0
  520. package/package.json +86 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"depthGuard.mjs","names":[],"sources":["../../../src/runs/shared/depthGuard.ts"],"sourcesContent":["/**\n * Enforces `maxSubagentDepth`: how many spawn-levels deep a chain of\n * subagents may go before a further spawn is refused.\n *\n * WHY ABSENT MEANS DEPTH 0, NOT \"UNKNOWN, REFUSE\":\n * `SUBAGENT_PARENT_DEPTH_ENV` is only ever set by a parent that is itself a\n * spawned child (see `piArgs.ts`'s child env contract). A root session -\n * the common case, and every top-level spawn - never has it set. Treating\n * absence as \"unknown depth\" and failing closed would refuse every\n * top-level spawn, which is the opposite of the intended behavior. Absence\n * means this process IS the root, depth 0.\n *\n * WHY A PRESENT-BUT-UNPARSEABLE VALUE IS A HARD FAILURE, NOT A SILENT 0:\n * Falling back to 0 for a corrupted value would make a runaway or tampered\n * depth chain invisible - exactly the failure mode this guard exists to\n * catch. A value that is present but not a valid non-negative integer is\n * treated as more suspicious than merely absent, not less.\n *\n * TWO SEPARATE STEPS, MATCHING `spawn-budget.ts`'S RESOLVE/PREFLIGHT SPLIT:\n * `resolveCurrentSubagentDepth` only reads and validates this process's own\n * depth (throws on corruption); `preflightSubagentDepth` only compares an\n * already-resolved depth against the configured limit, returning a\n * describable `{error}` the same shape `spawn-budget.ts` already uses for\n * \"over the limit\" - a business-rule refusal, not an anomaly, so it does\n * not throw on its own. The caller (`spawnPlan.ts`'s preflight) decides\n * when to turn a returned `error` into an actual throw.\n */\n\nimport { SUBAGENT_PARENT_DEPTH_ENV } from '../../env.ts';\n\n/** The slice of extension configuration this module reads. */\nexport interface DepthGuardLimitConfig {\n maxSubagentDepth?: number;\n}\n\nexport interface DepthPreflightResult {\n depth: number;\n limit: number | undefined;\n error?: string;\n}\n\n/**\n * This process's own spawn depth: 0 for a root session, N for the Nth-level\n * child of a chain of spawns. Throws when `SUBAGENT_PARENT_DEPTH_ENV` is\n * present but not a valid non-negative integer - see the module header.\n */\nexport function resolveCurrentSubagentDepth(env: NodeJS.ProcessEnv = process.env): number {\n const raw = env[SUBAGENT_PARENT_DEPTH_ENV];\n if (raw === undefined) return 0;\n // An empty string is \"present but says nothing\", not \"present and zero\" -\n // `Number('')` is 0 by a JS quirk, which would otherwise let a blank env\n // var silently pass as a valid depth.\n const parsed = raw.trim() === '' ? Number.NaN : Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(\n `${SUBAGENT_PARENT_DEPTH_ENV} is set to an invalid value (${JSON.stringify(raw)}); expected a non-negative integer.`,\n );\n }\n return parsed;\n}\n\n/**\n * Would a spawn from a process at `depth` exceed `config.maxSubagentDepth`?\n * A configured limit of 0 or `undefined` means no limit. At the limit is\n * allowed - the refusal is for a depth one PAST it, per the boundary team\n * lead specified: `depth === limit` passes, `depth === limit + 1` refuses.\n */\nexport function preflightSubagentDepth(depth: number, config: DepthGuardLimitConfig): DepthPreflightResult {\n const limit =\n typeof config.maxSubagentDepth === 'number' &&\n Number.isInteger(config.maxSubagentDepth) &&\n config.maxSubagentDepth > 0\n ? config.maxSubagentDepth\n : undefined;\n if (limit === undefined || depth <= limit) return { depth, limit };\n return {\n depth,\n limit,\n error: `Subagent spawn refused: this process is already at depth ${depth}, past the configured maxSubagentDepth of ${limit}.`,\n };\n}\n"],"mappings":"wIA8CA,SAAgB,EAA4B,EAAyB,QAAQ,IAAa,CACxF,IAAM,EAAM,EAAI,GAChB,GAAI,IAAQ,IAAA,GAAW,MAAO,GAI9B,IAAM,EAAS,EAAI,MAAM,GAAK,GAAK,IAAa,OAAO,EAAI,CAC3D,GAAI,CAAC,OAAO,UAAU,EAAO,EAAI,EAAS,EACxC,MAAU,MACR,GAAG,EAA0B,+BAA+B,KAAK,UAAU,EAAI,CAAC,qCACjF,CAEH,OAAO,EAST,SAAgB,EAAuB,EAAe,EAAqD,CACzG,IAAM,EACJ,OAAO,EAAO,kBAAqB,UACnC,OAAO,UAAU,EAAO,iBAAiB,EACzC,EAAO,iBAAmB,EACtB,EAAO,iBACP,IAAA,GAEN,OADI,IAAU,IAAA,IAAa,GAAS,EAAc,CAAE,QAAO,QAAO,CAC3D,CACL,QACA,QACA,MAAO,4DAA4D,EAAM,4CAA4C,EAAM,GAC5H,kBAnDsD"}
@@ -0,0 +1,2 @@
1
+ require(`../../_virtual/_rolldown/runtime.cjs`);let e=require(`@agimon-ai/doompi-mcp`);const t=new Set([`read`,`bash`,`edit`,`write`,`grep`,`find`,`ls`,`mcp`]);function n(e){let t=!1,n=new Set,r=new Map;for(let i of e){let e=i.trim().replace(/\/+$/u,``);if(!e)continue;if(e===`*`){t=!0;continue}let a=e.indexOf(`/`);if(a===-1){n.add(e);continue}let o=e.slice(0,a),s=e.slice(a+1);if(!o)continue;if(!s){n.add(o);continue}let c=r.get(o)??new Set;c.add(s),r.set(o,c)}return{allServers:t,servers:n,tools:r}}function r(r,i=process.cwd()){if(!r?.length)return[];try{let a=(0,e.readCachedCatalog)((0,e.buildMcpConfigGroups)((0,e.readSessionConfig)(process.env,i)).sessionLocal.configPaths),{allServers:o,servers:s,tools:c}=n(r),l=[],u=new Set;for(let n of a.servers){let r=o||s.has(n.name),i=c.get(n.name);if(!(!r&&!i))for(let a of n.tools){if(!r&&!i?.has(a.name))continue;let o=(0,e.toPiToolName)(n.name,a.name);t.has(o)||u.has(o)||(u.add(o),l.push({name:o,selector:`${n.name}/${a.name}`}))}}return l}catch{return[]}}exports.resolveMcpDirectToolSelections=r;
2
+ //# sourceMappingURL=mcpDirectToolAllowlist.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpDirectToolAllowlist.cjs","names":[],"sources":["../../../src/runs/shared/mcpDirectToolAllowlist.ts"],"sourcesContent":["/**\n * Resolve an agent's MCP direct-tool selectors into the tool names a child will see.\n *\n * A child is launched with a strict tool allowlist, and MCP tools reach it under a\n * host-computed prefixed name, not the name written in the agent frontmatter.\n * Connecting to every MCP server to ask would add seconds to every launch, so the\n * names are read from the host's own configuration and definitions cache instead.\n *\n * DESIGN PATTERNS:\n * - The host's own modules do the work. Layer discovery, the domain allowlist and\n * the prefixing rule all come from `@agimon-ai/doompi-mcp`, which is what actually\n * registers the tools, so there is no second implementation to drift from\n * - A cache miss resolves nothing rather than guessing a name\n * - Every failure resolves to fewer tools, never more\n *\n * WHY FAILURES ARE SWALLOWED HERE:\n * This is name reconstruction, not authorization. An unreadable config or cache\n * yields an empty selection, which means the child is launched without those MCP\n * tools and reports them through the child tool diagnostic. There is no path where\n * a failure grants a tool, so swallowing narrows access rather than widening it.\n * The ceiling clamp is applied by the caller on the result.\n *\n * AVOID:\n * - Reimplementing the prefixing rule here; import `toPiToolName` so a change to\n * the naming policy cannot silently strand every child's MCP tools\n * - Returning a name on a cache miss \"so the child can try\"; an unverified name in\n * the allowlist is capability the host never confirmed exists\n */\n\nimport { buildMcpConfigGroups, readCachedCatalog, readSessionConfig, toPiToolName } from '@agimon-ai/doompi-mcp';\n\nconst SELECTOR_SEPARATOR = '/';\nconst ALL_SERVERS_SELECTOR = '*';\n\n/** Names the coding agent reserves; an MCP tool may never shadow one. */\nconst BUILTIN_TOOL_NAMES = new Set(['read', 'bash', 'edit', 'write', 'grep', 'find', 'ls', 'mcp']);\n\nexport interface ResolvedMcpDirectToolSelection {\n name: string;\n selector: string;\n}\n\ninterface Selection {\n allServers: boolean;\n servers: Set<string>;\n tools: Map<string, Set<string>>;\n}\n\nfunction parseSelections(selections: readonly string[]): Selection {\n let allServers = false;\n const servers = new Set<string>();\n const tools = new Map<string, Set<string>>();\n for (const selection of selections) {\n const item = selection.trim().replace(/\\/+$/u, '');\n if (!item) continue;\n if (item === ALL_SERVERS_SELECTOR) {\n allServers = true;\n continue;\n }\n const separator = item.indexOf(SELECTOR_SEPARATOR);\n if (separator === -1) {\n servers.add(item);\n continue;\n }\n const server = item.slice(0, separator);\n const tool = item.slice(separator + 1);\n if (!server) continue;\n if (!tool) {\n servers.add(server);\n continue;\n }\n const selected = tools.get(server) ?? new Set<string>();\n selected.add(tool);\n tools.set(server, selected);\n }\n return { allServers, servers, tools };\n}\n\nexport function resolveMcpDirectToolSelections(\n mcpDirectTools: string[] | undefined,\n cwd = process.cwd(),\n): ResolvedMcpDirectToolSelection[] {\n if (!mcpDirectTools?.length) return [];\n\n try {\n // The same two inputs the extension itself uses: the layers this session\n // selected, and the catalog the previous run wrote for exactly those layers.\n const groups = buildMcpConfigGroups(readSessionConfig(process.env, cwd));\n const catalog = readCachedCatalog(groups.sessionLocal.configPaths);\n const { allServers, servers: selectedServers, tools: selectedTools } = parseSelections(mcpDirectTools);\n\n const resolved: ResolvedMcpDirectToolSelection[] = [];\n const seen = new Set<string>();\n for (const server of catalog.servers) {\n const wholeServer = allServers || selectedServers.has(server.name);\n const named = selectedTools.get(server.name);\n if (!wholeServer && !named) continue;\n for (const tool of server.tools) {\n if (!wholeServer && !named?.has(tool.name)) continue;\n const name = toPiToolName(server.name, tool.name);\n if (BUILTIN_TOOL_NAMES.has(name) || seen.has(name)) continue;\n seen.add(name);\n resolved.push({ name, selector: `${server.name}${SELECTOR_SEPARATOR}${tool.name}` });\n }\n }\n return resolved;\n } catch {\n // Reconstruction failed, so no MCP tool name is confirmed. Resolving none\n // launches the child without them, which is the narrow outcome; the missing\n // tools then surface through the child tool diagnostic.\n return [];\n }\n}\n\nexport function resolveMcpDirectToolNames(mcpDirectTools: string[] | undefined, cwd = process.cwd()): string[] {\n return resolveMcpDirectToolSelections(mcpDirectTools, cwd).map((selection) => selection.name);\n}\n"],"mappings":"uFA+BA,MAIM,EAAqB,IAAI,IAAI,CAAC,OAAQ,OAAQ,OAAQ,QAAS,OAAQ,OAAQ,KAAM,MAAM,CAAC,CAalG,SAAS,EAAgB,EAA0C,CACjE,IAAI,EAAa,GACX,EAAU,IAAI,IACd,EAAQ,IAAI,IAClB,IAAK,IAAM,KAAa,EAAY,CAClC,IAAM,EAAO,EAAU,MAAM,CAAC,QAAQ,QAAS,GAAG,CAClD,GAAI,CAAC,EAAM,SACX,GAAI,IAAS,IAAsB,CACjC,EAAa,GACb,SAEF,IAAM,EAAY,EAAK,QAAQ,IAAmB,CAClD,GAAI,IAAc,GAAI,CACpB,EAAQ,IAAI,EAAK,CACjB,SAEF,IAAM,EAAS,EAAK,MAAM,EAAG,EAAU,CACjC,EAAO,EAAK,MAAM,EAAY,EAAE,CACtC,GAAI,CAAC,EAAQ,SACb,GAAI,CAAC,EAAM,CACT,EAAQ,IAAI,EAAO,CACnB,SAEF,IAAM,EAAW,EAAM,IAAI,EAAO,EAAI,IAAI,IAC1C,EAAS,IAAI,EAAK,CAClB,EAAM,IAAI,EAAQ,EAAS,CAE7B,MAAO,CAAE,aAAY,UAAS,QAAO,CAGvC,SAAgB,EACd,EACA,EAAM,QAAQ,KAAK,CACe,CAClC,GAAI,CAAC,GAAgB,OAAQ,MAAO,EAAE,CAEtC,GAAI,CAIF,IAAM,GAAA,EAAA,EAAA,oBAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,mBADgD,QAAQ,IAAK,EAAI,CAC/B,CAAC,aAAa,YAAY,CAC5D,CAAE,aAAY,QAAS,EAAiB,MAAO,GAAkB,EAAgB,EAAe,CAEhG,EAA6C,EAAE,CAC/C,EAAO,IAAI,IACjB,IAAK,IAAM,KAAU,EAAQ,QAAS,CACpC,IAAM,EAAc,GAAc,EAAgB,IAAI,EAAO,KAAK,CAC5D,EAAQ,EAAc,IAAI,EAAO,KAAK,CACxC,MAAC,GAAe,CAAC,GACrB,IAAK,IAAM,KAAQ,EAAO,MAAO,CAC/B,GAAI,CAAC,GAAe,CAAC,GAAO,IAAI,EAAK,KAAK,CAAE,SAC5C,IAAM,GAAA,EAAA,EAAA,cAAoB,EAAO,KAAM,EAAK,KAAK,CAC7C,EAAmB,IAAI,EAAK,EAAI,EAAK,IAAI,EAAK,GAClD,EAAK,IAAI,EAAK,CACd,EAAS,KAAK,CAAE,OAAM,SAAU,GAAG,EAAO,QAA4B,EAAK,OAAQ,CAAC,GAGxF,OAAO,OACD,CAIN,MAAO,EAAE"}
@@ -0,0 +1,2 @@
1
+ import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import{buildMcpConfigGroups as t,readCachedCatalog as n,readSessionConfig as r,toPiToolName as i}from"@agimon-ai/doompi-mcp";function a(e){let t=!1,n=new Set,r=new Map;for(let i of e){let e=i.trim().replace(/\/+$/u,``);if(!e)continue;if(e===c){t=!0;continue}let a=e.indexOf(s);if(a===-1){n.add(e);continue}let o=e.slice(0,a),l=e.slice(a+1);if(!o)continue;if(!l){n.add(o);continue}let u=r.get(o)??new Set;u.add(l),r.set(o,u)}return{allServers:t,servers:n,tools:r}}function o(e,o=process.cwd()){if(!e?.length)return[];try{let c=n(t(r(process.env,o)).sessionLocal.configPaths),{allServers:u,servers:d,tools:f}=a(e),p=[],m=new Set;for(let e of c.servers){let t=u||d.has(e.name),n=f.get(e.name);if(!(!t&&!n))for(let r of e.tools){if(!t&&!n?.has(r.name))continue;let a=i(e.name,r.name);l.has(a)||m.has(a)||(m.add(a),p.push({name:a,selector:`${e.name}${s}${r.name}`}))}}return p}catch{return[]}}var s,c,l,u=e((()=>{s=`/`,c=`*`,l=new Set([`read`,`bash`,`edit`,`write`,`grep`,`find`,`ls`,`mcp`])}));u();export{u as init_mcpDirectToolAllowlist,o as resolveMcpDirectToolSelections};
2
+ //# sourceMappingURL=mcpDirectToolAllowlist.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpDirectToolAllowlist.mjs","names":[],"sources":["../../../src/runs/shared/mcpDirectToolAllowlist.ts"],"sourcesContent":["/**\n * Resolve an agent's MCP direct-tool selectors into the tool names a child will see.\n *\n * A child is launched with a strict tool allowlist, and MCP tools reach it under a\n * host-computed prefixed name, not the name written in the agent frontmatter.\n * Connecting to every MCP server to ask would add seconds to every launch, so the\n * names are read from the host's own configuration and definitions cache instead.\n *\n * DESIGN PATTERNS:\n * - The host's own modules do the work. Layer discovery, the domain allowlist and\n * the prefixing rule all come from `@agimon-ai/doompi-mcp`, which is what actually\n * registers the tools, so there is no second implementation to drift from\n * - A cache miss resolves nothing rather than guessing a name\n * - Every failure resolves to fewer tools, never more\n *\n * WHY FAILURES ARE SWALLOWED HERE:\n * This is name reconstruction, not authorization. An unreadable config or cache\n * yields an empty selection, which means the child is launched without those MCP\n * tools and reports them through the child tool diagnostic. There is no path where\n * a failure grants a tool, so swallowing narrows access rather than widening it.\n * The ceiling clamp is applied by the caller on the result.\n *\n * AVOID:\n * - Reimplementing the prefixing rule here; import `toPiToolName` so a change to\n * the naming policy cannot silently strand every child's MCP tools\n * - Returning a name on a cache miss \"so the child can try\"; an unverified name in\n * the allowlist is capability the host never confirmed exists\n */\n\nimport { buildMcpConfigGroups, readCachedCatalog, readSessionConfig, toPiToolName } from '@agimon-ai/doompi-mcp';\n\nconst SELECTOR_SEPARATOR = '/';\nconst ALL_SERVERS_SELECTOR = '*';\n\n/** Names the coding agent reserves; an MCP tool may never shadow one. */\nconst BUILTIN_TOOL_NAMES = new Set(['read', 'bash', 'edit', 'write', 'grep', 'find', 'ls', 'mcp']);\n\nexport interface ResolvedMcpDirectToolSelection {\n name: string;\n selector: string;\n}\n\ninterface Selection {\n allServers: boolean;\n servers: Set<string>;\n tools: Map<string, Set<string>>;\n}\n\nfunction parseSelections(selections: readonly string[]): Selection {\n let allServers = false;\n const servers = new Set<string>();\n const tools = new Map<string, Set<string>>();\n for (const selection of selections) {\n const item = selection.trim().replace(/\\/+$/u, '');\n if (!item) continue;\n if (item === ALL_SERVERS_SELECTOR) {\n allServers = true;\n continue;\n }\n const separator = item.indexOf(SELECTOR_SEPARATOR);\n if (separator === -1) {\n servers.add(item);\n continue;\n }\n const server = item.slice(0, separator);\n const tool = item.slice(separator + 1);\n if (!server) continue;\n if (!tool) {\n servers.add(server);\n continue;\n }\n const selected = tools.get(server) ?? new Set<string>();\n selected.add(tool);\n tools.set(server, selected);\n }\n return { allServers, servers, tools };\n}\n\nexport function resolveMcpDirectToolSelections(\n mcpDirectTools: string[] | undefined,\n cwd = process.cwd(),\n): ResolvedMcpDirectToolSelection[] {\n if (!mcpDirectTools?.length) return [];\n\n try {\n // The same two inputs the extension itself uses: the layers this session\n // selected, and the catalog the previous run wrote for exactly those layers.\n const groups = buildMcpConfigGroups(readSessionConfig(process.env, cwd));\n const catalog = readCachedCatalog(groups.sessionLocal.configPaths);\n const { allServers, servers: selectedServers, tools: selectedTools } = parseSelections(mcpDirectTools);\n\n const resolved: ResolvedMcpDirectToolSelection[] = [];\n const seen = new Set<string>();\n for (const server of catalog.servers) {\n const wholeServer = allServers || selectedServers.has(server.name);\n const named = selectedTools.get(server.name);\n if (!wholeServer && !named) continue;\n for (const tool of server.tools) {\n if (!wholeServer && !named?.has(tool.name)) continue;\n const name = toPiToolName(server.name, tool.name);\n if (BUILTIN_TOOL_NAMES.has(name) || seen.has(name)) continue;\n seen.add(name);\n resolved.push({ name, selector: `${server.name}${SELECTOR_SEPARATOR}${tool.name}` });\n }\n }\n return resolved;\n } catch {\n // Reconstruction failed, so no MCP tool name is confirmed. Resolving none\n // launches the child without them, which is the narrow outcome; the missing\n // tools then surface through the child tool diagnostic.\n return [];\n }\n}\n\nexport function resolveMcpDirectToolNames(mcpDirectTools: string[] | undefined, cwd = process.cwd()): string[] {\n return resolveMcpDirectToolSelections(mcpDirectTools, cwd).map((selection) => selection.name);\n}\n"],"mappings":"6LAgDA,SAAS,EAAgB,EAA0C,CACjE,IAAI,EAAa,GACX,EAAU,IAAI,IACd,EAAQ,IAAI,IAClB,IAAK,IAAM,KAAa,EAAY,CAClC,IAAM,EAAO,EAAU,MAAM,CAAC,QAAQ,QAAS,GAAG,CAClD,GAAI,CAAC,EAAM,SACX,GAAI,IAAS,EAAsB,CACjC,EAAa,GACb,SAEF,IAAM,EAAY,EAAK,QAAQ,EAAmB,CAClD,GAAI,IAAc,GAAI,CACpB,EAAQ,IAAI,EAAK,CACjB,SAEF,IAAM,EAAS,EAAK,MAAM,EAAG,EAAU,CACjC,EAAO,EAAK,MAAM,EAAY,EAAE,CACtC,GAAI,CAAC,EAAQ,SACb,GAAI,CAAC,EAAM,CACT,EAAQ,IAAI,EAAO,CACnB,SAEF,IAAM,EAAW,EAAM,IAAI,EAAO,EAAI,IAAI,IAC1C,EAAS,IAAI,EAAK,CAClB,EAAM,IAAI,EAAQ,EAAS,CAE7B,MAAO,CAAE,aAAY,UAAS,QAAO,CAGvC,SAAgB,EACd,EACA,EAAM,QAAQ,KAAK,CACe,CAClC,GAAI,CAAC,GAAgB,OAAQ,MAAO,EAAE,CAEtC,GAAI,CAIF,IAAM,EAAU,EADD,EAAqB,EAAkB,QAAQ,IAAK,EAAI,CAC/B,CAAC,aAAa,YAAY,CAC5D,CAAE,aAAY,QAAS,EAAiB,MAAO,GAAkB,EAAgB,EAAe,CAEhG,EAA6C,EAAE,CAC/C,EAAO,IAAI,IACjB,IAAK,IAAM,KAAU,EAAQ,QAAS,CACpC,IAAM,EAAc,GAAc,EAAgB,IAAI,EAAO,KAAK,CAC5D,EAAQ,EAAc,IAAI,EAAO,KAAK,CACxC,MAAC,GAAe,CAAC,GACrB,IAAK,IAAM,KAAQ,EAAO,MAAO,CAC/B,GAAI,CAAC,GAAe,CAAC,GAAO,IAAI,EAAK,KAAK,CAAE,SAC5C,IAAM,EAAO,EAAa,EAAO,KAAM,EAAK,KAAK,CAC7C,EAAmB,IAAI,EAAK,EAAI,EAAK,IAAI,EAAK,GAClD,EAAK,IAAI,EAAK,CACd,EAAS,KAAK,CAAE,OAAM,SAAU,GAAG,EAAO,OAAO,IAAqB,EAAK,OAAQ,CAAC,GAGxF,OAAO,OACD,CAIN,MAAO,EAAE,sBA/EP,EAAqB,IACrB,EAAuB,IAGvB,EAAqB,IAAI,IAAI,CAAC,OAAQ,OAAQ,OAAQ,QAAS,OAAQ,OAAQ,KAAM,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ const e=require(`../../shared/modelInfo.cjs`),t=require(`../../shared/modelResolution.cjs`),n=require(`./modelScope.cjs`);function r(e){if(!e||typeof e!=`object`||!(`provider`in e)||!(`id`in e))return;let{provider:t,id:n}=e;if(!(typeof t!=`string`||typeof n!=`string`)&&!(!t||!n))return{provider:t,id:n}}function i(e){}function a(e,r,a,o,s){let c=new Set,l=[],u=[e,...r??[]];for(let e=0;e<u.length;e++){let r=u[e];if(!r)continue;let d=t.resolveModelCandidate(r.trim(),a,o);if(!(!d||c.has(d))){if(e>0&&s?.scope?.enforce){let e=n.checkModelScope(d,s.scope,`inherited`);e&&(s.onWarn??i)(e)}c.add(d),l.push(d)}}return l}function o(t,n,r,i){if(r===void 0)return t;let o=new Set(r.map(e=>e.fullId));for(let s of a(t,n,r,i)){let{baseModel:t}=e.splitKnownThinkingSuffix(s);if(o.has(t))return s}}exports.normalizeParentModel=r,exports.selectAvailableModel=o;
2
+ //# sourceMappingURL=modelFallback.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelFallback.cjs","names":["resolveModelCandidate","checkModelScope","splitKnownThinkingSuffix"],"sources":["../../../src/runs/shared/modelFallback.ts"],"sourcesContent":["/**\n * Resolving which model a child run uses, and which models it may fall back to.\n *\n * WHY A CHILD IS ALWAYS GIVEN AN EXPLICIT MODEL:\n * Without a `provider/id` on the command line, a child resolves its own model\n * from the global agent settings file, which every open session shares. Another\n * session that changed its model in the TUI would then silently decide this\n * session's children. Passing the parent's in-memory model keeps each session's\n * children isolated to that session.\n *\n * DESIGN PATTERNS:\n * - Every resolver is pure, so model policy is testable without a registry, a\n * process, or config on disk\n * - Enforcement severity follows provenance: a model the caller named explicitly\n * throws when out of scope, an inherited one only warns, so tightening scope\n * never breaks a working configuration outright\n * - Fuzzy matching tolerates separator, case, and date-stamp spelling but never\n * crosses providers for a qualified query, and refuses ambiguous matches\n * rather than guessing, because the wrong provider costs real money\n *\n * AVOID:\n * - Retrying a different model on a tool failure; the model was never the\n * problem and the retry reruns the whole task\n * - Splitting a model string on the first colon to find the thinking suffix;\n * ids legitimately contain colons\n */\n\nimport { splitKnownThinkingSuffix, type ModelInfo as AvailableModelInfo } from '../../shared/modelInfo.ts';\nimport { PROVIDER_SEPARATOR, resolveModelCandidate } from '../../shared/modelResolution.ts';\nimport type { ModelScopeConfig, Usage } from '../../types.ts';\nimport { checkModelScope, type ModelScopeViolation, type ModelSource } from './modelScope.ts';\n\nexport type { AvailableModelInfo };\n// Re-exported so the runs domain still reads as the entry point for model\n// resolution, while the definitions stay in a leaf both domains can reach.\nexport { fuzzyResolveModel, normalizeModelSegment, resolveModelCandidate } from '../../shared/modelResolution.ts';\n\n/** One finished attempt at running a child on a given model. */\nexport interface ModelAttemptSummary {\n model: string;\n success: boolean;\n exitCode?: number | null;\n error?: string;\n usage?: Usage;\n}\n\n/** Sentinel model value requesting that a subagent inherit the parent session's model. */\nexport const INHERIT_MODEL = 'inherit';\n\nconst FALLBACK_NOTE_PREFIX = '[fallback]';\nconst EXPLICIT_MODEL_SOURCE: ModelSource = 'explicit';\nconst INHERITED_MODEL_SOURCE: ModelSource = 'inherited';\n\n/** Minimal shape of the parent session's in-memory model (`ctx.model`). */\nexport interface ParentModel {\n provider: string;\n id: string;\n}\n\nexport function normalizeParentModel(model: unknown): ParentModel | undefined {\n if (!model || typeof model !== 'object') return undefined;\n if (!('provider' in model) || !('id' in model)) return undefined;\n const { provider, id } = model;\n if (typeof provider !== 'string' || typeof id !== 'string') return undefined;\n if (!provider || !id) return undefined;\n return { provider, id };\n}\n\nexport interface ResolveSubagentModelOverrideOptions {\n /** When set with `enforce: true`, out-of-scope models are rejected. */\n scope?: ModelScopeConfig;\n /** Origin of the requested model: explicit caller-supplied (hard error) vs inherited (warn). Defaults to `\"inherited\"`. */\n source?: ModelSource;\n /** Sink for warn-severity violations. Without it they are dropped; see `discardScopeViolation`. */\n onWarn?: (violation: ModelScopeViolation) => void;\n}\n\n/**\n * Where a warn-severity scope violation goes when the caller supplies no sink.\n *\n * Deliberately silent rather than writing to stdio. This module runs inside both\n * the parent's TUI process and a detached runner whose stdout is the child's\n * captured transcript, so writing here would corrupt one and pollute the other.\n * The violation is advisory by definition: its error-severity sibling throws\n * instead. A composition root that wants these visible passes `onWarn` and\n * routes them into that process's own diagnostics.\n */\nfunction discardScopeViolation(_violation: ModelScopeViolation): void {}\n\n/**\n * Resolve the `--model` override passed to a spawned subagent.\n *\n * When no model is requested (`undefined`, `false`, empty, or the `\"inherit\"`\n * sentinel), the child inherits the parent session's in-memory `provider/id`\n * rather than being left to resolve its own; see the module header for why.\n *\n * An explicitly requested model string is resolved via {@link resolveModelCandidate}.\n * When `options.scope.enforce` is on, an out-of-scope resolved model throws for\n * an explicit (`source: \"explicit\"`) request and warns for an inherited one.\n */\nexport function resolveSubagentModelOverride(\n requestedModel: string | boolean | undefined,\n parentModel: ParentModel | undefined,\n availableModels: AvailableModelInfo[] | undefined,\n preferredProvider?: string,\n options?: ResolveSubagentModelOverrideOptions,\n): string | undefined {\n const trimmed = typeof requestedModel === 'string' ? requestedModel.trim() : '';\n const explicit = trimmed && trimmed !== INHERIT_MODEL ? trimmed : undefined;\n let resolved: string | undefined;\n if (explicit === undefined) {\n resolved = parentModel ? `${parentModel.provider}${PROVIDER_SEPARATOR}${parentModel.id}` : undefined;\n } else {\n resolved = resolveModelCandidate(explicit, availableModels, preferredProvider);\n }\n if (resolved && options?.scope?.enforce) {\n // A model that fell back to the parent's was never explicitly requested,\n // whatever the caller declared, so it can only ever warn.\n const source = explicit === undefined ? INHERITED_MODEL_SOURCE : (options.source ?? INHERITED_MODEL_SOURCE);\n const violation = checkModelScope(resolved, options.scope, source);\n if (violation) {\n if (violation.severity === 'error') throw new Error(violation.message);\n (options.onWarn ?? discardScopeViolation)(violation);\n }\n }\n return resolved;\n}\n\n/**\n * Resolve the model for a run from the caller's request, falling back to the\n * agent's own declared model. A caller-supplied model that resolves to nothing\n * retries against the agent's, which is inherited and so only ever warns.\n */\nexport function resolveEffectiveSubagentModel(\n explicitModel: string | boolean | undefined,\n agentModel: string | boolean | undefined,\n parentModel: ParentModel | undefined,\n availableModels: AvailableModelInfo[] | undefined,\n preferredProvider?: string,\n options?: Omit<ResolveSubagentModelOverrideOptions, 'source'>,\n): string | undefined {\n const resolved = resolveSubagentModelOverride(\n explicitModel ?? agentModel,\n parentModel,\n availableModels,\n preferredProvider,\n { ...options, source: explicitModel !== undefined ? EXPLICIT_MODEL_SOURCE : INHERITED_MODEL_SOURCE },\n );\n if (resolved || explicitModel === undefined) return resolved;\n return resolveSubagentModelOverride(agentModel, parentModel, availableModels, preferredProvider, {\n ...options,\n source: INHERITED_MODEL_SOURCE,\n });\n}\n\nexport interface BuildModelCandidatesOptions {\n /** Fallback models are inherited agent config and warn, rather than error, when out of scope. */\n scope?: ModelScopeConfig;\n onWarn?: (violation: ModelScopeViolation) => void;\n}\n\n/**\n * Build the ordered, de-duplicated list of models to try: the primary first,\n * then each declared fallback. The primary is left to the caller to scope-check,\n * since only the caller knows whether it was explicitly requested.\n */\nexport function buildModelCandidates(\n primaryModel: string | undefined,\n fallbackModels: string[] | undefined,\n availableModels: AvailableModelInfo[] | undefined,\n preferredProvider?: string,\n options?: BuildModelCandidatesOptions,\n): string[] {\n const seen = new Set<string>();\n const candidates: string[] = [];\n const rawCandidates = [primaryModel, ...(fallbackModels ?? [])];\n for (let index = 0; index < rawCandidates.length; index++) {\n const raw = rawCandidates[index];\n if (!raw) continue;\n const normalized = resolveModelCandidate(raw.trim(), availableModels, preferredProvider);\n if (!normalized || seen.has(normalized)) continue;\n if (index > 0 && options?.scope?.enforce) {\n const violation = checkModelScope(normalized, options.scope, INHERITED_MODEL_SOURCE);\n if (violation) (options.onWarn ?? discardScopeViolation)(violation);\n }\n seen.add(normalized);\n candidates.push(normalized);\n }\n return candidates;\n}\n\n/**\n * Pick the first configured primary/fallback model that the live parent can\n * authenticate. When no registry snapshot is supplied, preserve the primary\n * model for non-interactive callers and older persisted schedules.\n */\nexport function selectAvailableModel(\n primaryModel: string | undefined,\n fallbackModels: string[] | undefined,\n availableModels: AvailableModelInfo[] | undefined,\n preferredProvider?: string,\n): string | undefined {\n if (availableModels === undefined) return primaryModel;\n const availableIds = new Set(availableModels.map((model) => model.fullId));\n for (const candidate of buildModelCandidates(primaryModel, fallbackModels, availableModels, preferredProvider)) {\n const { baseModel } = splitKnownThinkingSuffix(candidate);\n if (availableIds.has(baseModel)) return candidate;\n }\n return undefined;\n}\n\nconst RETRYABLE_MODEL_FAILURE_PATTERNS = [\n /rate\\s*limit/i,\n /too many requests/i,\n /\\b429\\b/,\n /quota/i,\n /billing/i,\n /credit/i,\n /auth(?:entication)?/i,\n /unauthori[sz]ed/i,\n /forbidden/i,\n /api key/i,\n /token expired/i,\n /invalid key/i,\n /provider.*unavailable/i,\n /model.*unavailable/i,\n /model.*disabled/i,\n /model.*not found/i,\n /unknown model/i,\n /overloaded/i,\n /service unavailable/i,\n /temporar(?:ily)? unavailable/i,\n /connection refused/i,\n /fetch failed/i,\n /network error/i,\n /socket hang up/i,\n /stream ended without finish_reason/i,\n /upstream/i,\n /timed? out/i,\n /timeout/i,\n /\\b502\\b/,\n /\\b503\\b/,\n /\\b504\\b/,\n /cold.?start/i,\n /empty response/i,\n /no output/i,\n /model.*(?:load|fail|error)/i,\n];\n\n/**\n * Failures reported as `<tool> failed (exit N): ...` or `<tool> failed with\n * exit code N` come from a tool call inside the child's task, not from the\n * provider/model, however network-flavored their details read. Retrying a\n * different model cannot fix them and would rerun the whole task. Tool names\n * include namespaced forms like `mcp.server/write`.\n */\nconst TOOL_FAILURE_PREFIX = /^[\\w.:@/-]+ failed (?:(?:\\(exit \\d+\\):)|(?:with exit code \\d+))(?:\\s|$)/i;\n\nexport function isRetryableModelFailure(error: string | undefined): boolean {\n if (!error) return false;\n if (TOOL_FAILURE_PREFIX.test(error.trim())) return false;\n return RETRYABLE_MODEL_FAILURE_PATTERNS.some((pattern) => pattern.test(error));\n}\n\n/** Default exit code reported when an attempt failed without one, so the note never reads `exit undefined`. */\nconst UNKNOWN_EXIT_CODE = 1;\n\nexport function formatModelAttemptNote(attempt: ModelAttemptSummary, nextModel?: string): string {\n const failure = attempt.error?.trim() || `exit ${attempt.exitCode ?? UNKNOWN_EXIT_CODE}`;\n return nextModel\n ? `${FALLBACK_NOTE_PREFIX} ${attempt.model} failed: ${failure}. Retrying with ${nextModel}.`\n : `${FALLBACK_NOTE_PREFIX} ${attempt.model} failed: ${failure}.`;\n}\n"],"mappings":"0HA2DA,SAAgB,EAAqB,EAAyC,CAE5E,GADI,CAAC,GAAS,OAAO,GAAU,UAC3B,EAAE,aAAc,IAAU,EAAE,OAAQ,GAAQ,OAChD,GAAM,CAAE,WAAU,MAAO,EACrB,YAAO,GAAa,UAAY,OAAO,GAAO,WAC9C,GAAC,GAAY,CAAC,GAClB,MAAO,CAAE,WAAU,KAAI,CAsBzB,SAAS,EAAsB,EAAuC,EA+EtE,SAAgB,EACd,EACA,EACA,EACA,EACA,EACU,CACV,IAAM,EAAO,IAAI,IACX,EAAuB,EAAE,CACzB,EAAgB,CAAC,EAAc,GAAI,GAAkB,EAAE,CAAE,CAC/D,IAAK,IAAI,EAAQ,EAAG,EAAQ,EAAc,OAAQ,IAAS,CACzD,IAAM,EAAM,EAAc,GAC1B,GAAI,CAAC,EAAK,SACV,IAAM,EAAaA,EAAAA,sBAAsB,EAAI,MAAM,CAAE,EAAiB,EAAkB,CACpF,MAAC,GAAc,EAAK,IAAI,EAAW,EACvC,IAAI,EAAQ,GAAK,GAAS,OAAO,QAAS,CACxC,IAAM,EAAYC,EAAAA,gBAAgB,EAAY,EAAQ,MAAO,YAAuB,CAChF,IAAY,EAAQ,QAAU,GAAuB,EAAU,CAErE,EAAK,IAAI,EAAW,CACpB,EAAW,KAAK,EAAW,EAE7B,OAAO,EAQT,SAAgB,EACd,EACA,EACA,EACA,EACoB,CACpB,GAAI,IAAoB,IAAA,GAAW,OAAO,EAC1C,IAAM,EAAe,IAAI,IAAI,EAAgB,IAAK,GAAU,EAAM,OAAO,CAAC,CAC1E,IAAK,IAAM,KAAa,EAAqB,EAAc,EAAgB,EAAiB,EAAkB,CAAE,CAC9G,GAAM,CAAE,aAAcC,EAAAA,yBAAyB,EAAU,CACzD,GAAI,EAAa,IAAI,EAAU,CAAE,OAAO"}
@@ -0,0 +1,2 @@
1
+ import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import{init_modelInfo as t,splitKnownThinkingSuffix as n}from"../../shared/modelInfo.mjs";import{init_modelResolution as r,resolveModelCandidate as i}from"../../shared/modelResolution.mjs";import{checkModelScope as a,init_modelScope as o}from"./modelScope.mjs";function s(e){if(!e||typeof e!=`object`||!(`provider`in e)||!(`id`in e))return;let{provider:t,id:n}=e;if(!(typeof t!=`string`||typeof n!=`string`)&&!(!t||!n))return{provider:t,id:n}}function c(e){}function l(e,t,n,r,o){let s=new Set,l=[],u=[e,...t??[]];for(let e=0;e<u.length;e++){let t=u[e];if(!t)continue;let f=i(t.trim(),n,r);if(!(!f||s.has(f))){if(e>0&&o?.scope?.enforce){let e=a(f,o.scope,d);e&&(o.onWarn??c)(e)}s.add(f),l.push(f)}}return l}function u(e,t,r,i){if(r===void 0)return e;let a=new Set(r.map(e=>e.fullId));for(let o of l(e,t,r,i)){let{baseModel:e}=n(o);if(a.has(e))return o}}var d,f=e((()=>{t(),r(),o(),d=`inherited`}));f();export{f as init_modelFallback,s as normalizeParentModel,u as selectAvailableModel};
2
+ //# sourceMappingURL=modelFallback.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelFallback.mjs","names":[],"sources":["../../../src/runs/shared/modelFallback.ts"],"sourcesContent":["/**\n * Resolving which model a child run uses, and which models it may fall back to.\n *\n * WHY A CHILD IS ALWAYS GIVEN AN EXPLICIT MODEL:\n * Without a `provider/id` on the command line, a child resolves its own model\n * from the global agent settings file, which every open session shares. Another\n * session that changed its model in the TUI would then silently decide this\n * session's children. Passing the parent's in-memory model keeps each session's\n * children isolated to that session.\n *\n * DESIGN PATTERNS:\n * - Every resolver is pure, so model policy is testable without a registry, a\n * process, or config on disk\n * - Enforcement severity follows provenance: a model the caller named explicitly\n * throws when out of scope, an inherited one only warns, so tightening scope\n * never breaks a working configuration outright\n * - Fuzzy matching tolerates separator, case, and date-stamp spelling but never\n * crosses providers for a qualified query, and refuses ambiguous matches\n * rather than guessing, because the wrong provider costs real money\n *\n * AVOID:\n * - Retrying a different model on a tool failure; the model was never the\n * problem and the retry reruns the whole task\n * - Splitting a model string on the first colon to find the thinking suffix;\n * ids legitimately contain colons\n */\n\nimport { splitKnownThinkingSuffix, type ModelInfo as AvailableModelInfo } from '../../shared/modelInfo.ts';\nimport { PROVIDER_SEPARATOR, resolveModelCandidate } from '../../shared/modelResolution.ts';\nimport type { ModelScopeConfig, Usage } from '../../types.ts';\nimport { checkModelScope, type ModelScopeViolation, type ModelSource } from './modelScope.ts';\n\nexport type { AvailableModelInfo };\n// Re-exported so the runs domain still reads as the entry point for model\n// resolution, while the definitions stay in a leaf both domains can reach.\nexport { fuzzyResolveModel, normalizeModelSegment, resolveModelCandidate } from '../../shared/modelResolution.ts';\n\n/** One finished attempt at running a child on a given model. */\nexport interface ModelAttemptSummary {\n model: string;\n success: boolean;\n exitCode?: number | null;\n error?: string;\n usage?: Usage;\n}\n\n/** Sentinel model value requesting that a subagent inherit the parent session's model. */\nexport const INHERIT_MODEL = 'inherit';\n\nconst FALLBACK_NOTE_PREFIX = '[fallback]';\nconst EXPLICIT_MODEL_SOURCE: ModelSource = 'explicit';\nconst INHERITED_MODEL_SOURCE: ModelSource = 'inherited';\n\n/** Minimal shape of the parent session's in-memory model (`ctx.model`). */\nexport interface ParentModel {\n provider: string;\n id: string;\n}\n\nexport function normalizeParentModel(model: unknown): ParentModel | undefined {\n if (!model || typeof model !== 'object') return undefined;\n if (!('provider' in model) || !('id' in model)) return undefined;\n const { provider, id } = model;\n if (typeof provider !== 'string' || typeof id !== 'string') return undefined;\n if (!provider || !id) return undefined;\n return { provider, id };\n}\n\nexport interface ResolveSubagentModelOverrideOptions {\n /** When set with `enforce: true`, out-of-scope models are rejected. */\n scope?: ModelScopeConfig;\n /** Origin of the requested model: explicit caller-supplied (hard error) vs inherited (warn). Defaults to `\"inherited\"`. */\n source?: ModelSource;\n /** Sink for warn-severity violations. Without it they are dropped; see `discardScopeViolation`. */\n onWarn?: (violation: ModelScopeViolation) => void;\n}\n\n/**\n * Where a warn-severity scope violation goes when the caller supplies no sink.\n *\n * Deliberately silent rather than writing to stdio. This module runs inside both\n * the parent's TUI process and a detached runner whose stdout is the child's\n * captured transcript, so writing here would corrupt one and pollute the other.\n * The violation is advisory by definition: its error-severity sibling throws\n * instead. A composition root that wants these visible passes `onWarn` and\n * routes them into that process's own diagnostics.\n */\nfunction discardScopeViolation(_violation: ModelScopeViolation): void {}\n\n/**\n * Resolve the `--model` override passed to a spawned subagent.\n *\n * When no model is requested (`undefined`, `false`, empty, or the `\"inherit\"`\n * sentinel), the child inherits the parent session's in-memory `provider/id`\n * rather than being left to resolve its own; see the module header for why.\n *\n * An explicitly requested model string is resolved via {@link resolveModelCandidate}.\n * When `options.scope.enforce` is on, an out-of-scope resolved model throws for\n * an explicit (`source: \"explicit\"`) request and warns for an inherited one.\n */\nexport function resolveSubagentModelOverride(\n requestedModel: string | boolean | undefined,\n parentModel: ParentModel | undefined,\n availableModels: AvailableModelInfo[] | undefined,\n preferredProvider?: string,\n options?: ResolveSubagentModelOverrideOptions,\n): string | undefined {\n const trimmed = typeof requestedModel === 'string' ? requestedModel.trim() : '';\n const explicit = trimmed && trimmed !== INHERIT_MODEL ? trimmed : undefined;\n let resolved: string | undefined;\n if (explicit === undefined) {\n resolved = parentModel ? `${parentModel.provider}${PROVIDER_SEPARATOR}${parentModel.id}` : undefined;\n } else {\n resolved = resolveModelCandidate(explicit, availableModels, preferredProvider);\n }\n if (resolved && options?.scope?.enforce) {\n // A model that fell back to the parent's was never explicitly requested,\n // whatever the caller declared, so it can only ever warn.\n const source = explicit === undefined ? INHERITED_MODEL_SOURCE : (options.source ?? INHERITED_MODEL_SOURCE);\n const violation = checkModelScope(resolved, options.scope, source);\n if (violation) {\n if (violation.severity === 'error') throw new Error(violation.message);\n (options.onWarn ?? discardScopeViolation)(violation);\n }\n }\n return resolved;\n}\n\n/**\n * Resolve the model for a run from the caller's request, falling back to the\n * agent's own declared model. A caller-supplied model that resolves to nothing\n * retries against the agent's, which is inherited and so only ever warns.\n */\nexport function resolveEffectiveSubagentModel(\n explicitModel: string | boolean | undefined,\n agentModel: string | boolean | undefined,\n parentModel: ParentModel | undefined,\n availableModels: AvailableModelInfo[] | undefined,\n preferredProvider?: string,\n options?: Omit<ResolveSubagentModelOverrideOptions, 'source'>,\n): string | undefined {\n const resolved = resolveSubagentModelOverride(\n explicitModel ?? agentModel,\n parentModel,\n availableModels,\n preferredProvider,\n { ...options, source: explicitModel !== undefined ? EXPLICIT_MODEL_SOURCE : INHERITED_MODEL_SOURCE },\n );\n if (resolved || explicitModel === undefined) return resolved;\n return resolveSubagentModelOverride(agentModel, parentModel, availableModels, preferredProvider, {\n ...options,\n source: INHERITED_MODEL_SOURCE,\n });\n}\n\nexport interface BuildModelCandidatesOptions {\n /** Fallback models are inherited agent config and warn, rather than error, when out of scope. */\n scope?: ModelScopeConfig;\n onWarn?: (violation: ModelScopeViolation) => void;\n}\n\n/**\n * Build the ordered, de-duplicated list of models to try: the primary first,\n * then each declared fallback. The primary is left to the caller to scope-check,\n * since only the caller knows whether it was explicitly requested.\n */\nexport function buildModelCandidates(\n primaryModel: string | undefined,\n fallbackModels: string[] | undefined,\n availableModels: AvailableModelInfo[] | undefined,\n preferredProvider?: string,\n options?: BuildModelCandidatesOptions,\n): string[] {\n const seen = new Set<string>();\n const candidates: string[] = [];\n const rawCandidates = [primaryModel, ...(fallbackModels ?? [])];\n for (let index = 0; index < rawCandidates.length; index++) {\n const raw = rawCandidates[index];\n if (!raw) continue;\n const normalized = resolveModelCandidate(raw.trim(), availableModels, preferredProvider);\n if (!normalized || seen.has(normalized)) continue;\n if (index > 0 && options?.scope?.enforce) {\n const violation = checkModelScope(normalized, options.scope, INHERITED_MODEL_SOURCE);\n if (violation) (options.onWarn ?? discardScopeViolation)(violation);\n }\n seen.add(normalized);\n candidates.push(normalized);\n }\n return candidates;\n}\n\n/**\n * Pick the first configured primary/fallback model that the live parent can\n * authenticate. When no registry snapshot is supplied, preserve the primary\n * model for non-interactive callers and older persisted schedules.\n */\nexport function selectAvailableModel(\n primaryModel: string | undefined,\n fallbackModels: string[] | undefined,\n availableModels: AvailableModelInfo[] | undefined,\n preferredProvider?: string,\n): string | undefined {\n if (availableModels === undefined) return primaryModel;\n const availableIds = new Set(availableModels.map((model) => model.fullId));\n for (const candidate of buildModelCandidates(primaryModel, fallbackModels, availableModels, preferredProvider)) {\n const { baseModel } = splitKnownThinkingSuffix(candidate);\n if (availableIds.has(baseModel)) return candidate;\n }\n return undefined;\n}\n\nconst RETRYABLE_MODEL_FAILURE_PATTERNS = [\n /rate\\s*limit/i,\n /too many requests/i,\n /\\b429\\b/,\n /quota/i,\n /billing/i,\n /credit/i,\n /auth(?:entication)?/i,\n /unauthori[sz]ed/i,\n /forbidden/i,\n /api key/i,\n /token expired/i,\n /invalid key/i,\n /provider.*unavailable/i,\n /model.*unavailable/i,\n /model.*disabled/i,\n /model.*not found/i,\n /unknown model/i,\n /overloaded/i,\n /service unavailable/i,\n /temporar(?:ily)? unavailable/i,\n /connection refused/i,\n /fetch failed/i,\n /network error/i,\n /socket hang up/i,\n /stream ended without finish_reason/i,\n /upstream/i,\n /timed? out/i,\n /timeout/i,\n /\\b502\\b/,\n /\\b503\\b/,\n /\\b504\\b/,\n /cold.?start/i,\n /empty response/i,\n /no output/i,\n /model.*(?:load|fail|error)/i,\n];\n\n/**\n * Failures reported as `<tool> failed (exit N): ...` or `<tool> failed with\n * exit code N` come from a tool call inside the child's task, not from the\n * provider/model, however network-flavored their details read. Retrying a\n * different model cannot fix them and would rerun the whole task. Tool names\n * include namespaced forms like `mcp.server/write`.\n */\nconst TOOL_FAILURE_PREFIX = /^[\\w.:@/-]+ failed (?:(?:\\(exit \\d+\\):)|(?:with exit code \\d+))(?:\\s|$)/i;\n\nexport function isRetryableModelFailure(error: string | undefined): boolean {\n if (!error) return false;\n if (TOOL_FAILURE_PREFIX.test(error.trim())) return false;\n return RETRYABLE_MODEL_FAILURE_PATTERNS.some((pattern) => pattern.test(error));\n}\n\n/** Default exit code reported when an attempt failed without one, so the note never reads `exit undefined`. */\nconst UNKNOWN_EXIT_CODE = 1;\n\nexport function formatModelAttemptNote(attempt: ModelAttemptSummary, nextModel?: string): string {\n const failure = attempt.error?.trim() || `exit ${attempt.exitCode ?? UNKNOWN_EXIT_CODE}`;\n return nextModel\n ? `${FALLBACK_NOTE_PREFIX} ${attempt.model} failed: ${failure}. Retrying with ${nextModel}.`\n : `${FALLBACK_NOTE_PREFIX} ${attempt.model} failed: ${failure}.`;\n}\n"],"mappings":"qUA2DA,SAAgB,EAAqB,EAAyC,CAE5E,GADI,CAAC,GAAS,OAAO,GAAU,UAC3B,EAAE,aAAc,IAAU,EAAE,OAAQ,GAAQ,OAChD,GAAM,CAAE,WAAU,MAAO,EACrB,YAAO,GAAa,UAAY,OAAO,GAAO,WAC9C,GAAC,GAAY,CAAC,GAClB,MAAO,CAAE,WAAU,KAAI,CAsBzB,SAAS,EAAsB,EAAuC,EA+EtE,SAAgB,EACd,EACA,EACA,EACA,EACA,EACU,CACV,IAAM,EAAO,IAAI,IACX,EAAuB,EAAE,CACzB,EAAgB,CAAC,EAAc,GAAI,GAAkB,EAAE,CAAE,CAC/D,IAAK,IAAI,EAAQ,EAAG,EAAQ,EAAc,OAAQ,IAAS,CACzD,IAAM,EAAM,EAAc,GAC1B,GAAI,CAAC,EAAK,SACV,IAAM,EAAa,EAAsB,EAAI,MAAM,CAAE,EAAiB,EAAkB,CACpF,MAAC,GAAc,EAAK,IAAI,EAAW,EACvC,IAAI,EAAQ,GAAK,GAAS,OAAO,QAAS,CACxC,IAAM,EAAY,EAAgB,EAAY,EAAQ,MAAO,EAAuB,CAChF,IAAY,EAAQ,QAAU,GAAuB,EAAU,CAErE,EAAK,IAAI,EAAW,CACpB,EAAW,KAAK,EAAW,EAE7B,OAAO,EAQT,SAAgB,EACd,EACA,EACA,EACA,EACoB,CACpB,GAAI,IAAoB,IAAA,GAAW,OAAO,EAC1C,IAAM,EAAe,IAAI,IAAI,EAAgB,IAAK,GAAU,EAAM,OAAO,CAAC,CAC1E,IAAK,IAAM,KAAa,EAAqB,EAAc,EAAgB,EAAiB,EAAkB,CAAE,CAC9G,GAAM,CAAE,aAAc,EAAyB,EAAU,CACzD,GAAI,EAAa,IAAI,EAAU,CAAE,OAAO,sBAnL+D,IACf,IAEE,CAqBxF,EAAsC"}
@@ -0,0 +1,2 @@
1
+ const e=require(`../../shared/modelInfo.cjs`),t=/[.+^${}()|[\]\\]/g,n=/\*/g;function r(t){return e.splitKnownThinkingSuffix(t).baseModel}function i(e){let r=e.replace(t,`\\$&`).replace(n,`.*`);return RegExp(`^${r}$`,`i`)}function a(e,t){return i(t).test(r(e))}function o(e,t,n){if(!e||!t?.enforce)return;let i=t.allow;if(!i||i.length===0||i.some(t=>a(e,t)))return;let o=r(e);return{model:o,severity:n===`explicit`?`error`:`warn`,allowedPatterns:i,message:`Model '${o}' is outside the configured subagent model scope. Allowed patterns: ${i.join(`, `)}.`}}exports.checkModelScope=o;
2
+ //# sourceMappingURL=modelScope.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelScope.cjs","names":["splitKnownThinkingSuffix"],"sources":["../../../src/runs/shared/modelScope.ts"],"sourcesContent":["/**\n * Decides whether a resolved model is inside the configured subagent model scope.\n *\n * DESIGN PATTERNS:\n * - Pure decision function, so scope policy can be unit-tested without config or\n * filesystem access\n * - Severity follows provenance rather than the model: a model the caller asked\n * for by name is an error, a model inherited from frontmatter, the settings\n * default, or the parent session is only a warning, so tightening scope never\n * breaks a working configuration outright\n * - Patterns match the full `provider/id`, never a bare id, so `*` cannot let an\n * unintended provider in through a same-named model\n *\n * AVOID:\n * - Treating an empty `allow` list as \"deny everything\"; enforcement without\n * patterns is a no-op here and is rejected at settings-parse time instead\n * - Comparing the raw model string; the thinking suffix is not part of identity\n */\n\nimport { splitKnownThinkingSuffix } from '../../shared/modelInfo.ts';\nimport type { ModelScopeConfig } from '../../types.ts';\n\n/** Where a resolved model originated, deciding enforcement severity. */\nexport type ModelSource = 'explicit' | 'inherited';\n\nexport interface ModelScopeViolation {\n /** Resolved model id (without thinking suffix) that fell outside the scope. */\n model: string;\n severity: 'warn' | 'error';\n message: string;\n allowedPatterns: string[];\n}\n\n/** RegExp metacharacters that must be escaped. `*` is excluded: it is the glob wildcard. */\nconst REGEXP_SPECIALS_EXCEPT_WILDCARD = /[.+^${}()|[\\]\\\\]/g;\nconst GLOB_WILDCARD = /\\*/g;\n/** What `*` expands to: any run of characters, including `/`, so `anthropic/*` covers every id. */\nconst WILDCARD_EXPANSION = '.*';\n\nfunction stripThinkingSuffix(model: string): string {\n return splitKnownThinkingSuffix(model).baseModel;\n}\n\n/** Escape RegExp specials except `*`, then turn `*` into `.*`. */\nfunction globToRegExp(pattern: string): RegExp {\n const escaped = pattern.replace(REGEXP_SPECIALS_EXCEPT_WILDCARD, '\\\\$&').replace(GLOB_WILDCARD, WILDCARD_EXPANSION);\n return new RegExp(`^${escaped}$`, 'i');\n}\n\n/**\n * Test whether a resolved model matches a single allow pattern. Both sides are\n * compared case-insensitively against the full `provider/id` (thinking suffix\n * stripped from the model).\n */\nexport function matchesScopePattern(model: string, pattern: string): boolean {\n return globToRegExp(pattern).test(stripThinkingSuffix(model));\n}\n\n/**\n * Pure scope decision. Returns a {@link ModelScopeViolation} when the model is\n * out of scope and enforcement is on, otherwise `undefined`. Enforcement with\n * no `allow` list is a no-op (the settings parser rejects that combination, but\n * this stays defensive for callers that build configs programmatically).\n */\nexport function checkModelScope(\n model: string | undefined,\n scope: ModelScopeConfig | undefined,\n source: ModelSource,\n): ModelScopeViolation | undefined {\n if (!model || !scope?.enforce) return undefined;\n const allow = scope.allow;\n if (!allow || allow.length === 0) return undefined;\n if (allow.some((pattern) => matchesScopePattern(model, pattern))) return undefined;\n\n const baseModel = stripThinkingSuffix(model);\n const severity: ModelScopeViolation['severity'] = source === 'explicit' ? 'error' : 'warn';\n return {\n model: baseModel,\n severity,\n allowedPatterns: allow,\n message:\n `Model '${baseModel}' is outside the configured subagent model scope. ` +\n `Allowed patterns: ${allow.join(', ')}.`,\n };\n}\n"],"mappings":"8CAkCM,EAAkC,oBAClC,EAAgB,MAItB,SAAS,EAAoB,EAAuB,CAClD,OAAOA,EAAAA,yBAAyB,EAAM,CAAC,UAIzC,SAAS,EAAa,EAAyB,CAC7C,IAAM,EAAU,EAAQ,QAAQ,EAAiC,OAAO,CAAC,QAAQ,EAAe,KAAmB,CACnH,OAAW,OAAO,IAAI,EAAQ,GAAI,IAAI,CAQxC,SAAgB,EAAoB,EAAe,EAA0B,CAC3E,OAAO,EAAa,EAAQ,CAAC,KAAK,EAAoB,EAAM,CAAC,CAS/D,SAAgB,EACd,EACA,EACA,EACiC,CACjC,GAAI,CAAC,GAAS,CAAC,GAAO,QAAS,OAC/B,IAAM,EAAQ,EAAM,MAEpB,GADI,CAAC,GAAS,EAAM,SAAW,GAC3B,EAAM,KAAM,GAAY,EAAoB,EAAO,EAAQ,CAAC,CAAE,OAElE,IAAM,EAAY,EAAoB,EAAM,CAE5C,MAAO,CACL,MAAO,EACP,SAHgD,IAAW,WAAa,QAAU,OAIlF,gBAAiB,EACjB,QACE,UAAU,EAAU,sEACC,EAAM,KAAK,KAAK,CAAC,GACzC"}
@@ -0,0 +1,2 @@
1
+ import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import{init_modelInfo as t,splitKnownThinkingSuffix as n}from"../../shared/modelInfo.mjs";function r(e){return n(e).baseModel}function i(e){let t=e.replace(s,`\\$&`).replace(c,l);return RegExp(`^${t}$`,`i`)}function a(e,t){return i(t).test(r(e))}function o(e,t,n){if(!e||!t?.enforce)return;let i=t.allow;if(!i||i.length===0||i.some(t=>a(e,t)))return;let o=r(e);return{model:o,severity:n===`explicit`?`error`:`warn`,allowedPatterns:i,message:`Model '${o}' is outside the configured subagent model scope. Allowed patterns: ${i.join(`, `)}.`}}var s,c,l,u=e((()=>{t(),s=/[.+^${}()|[\]\\]/g,c=/\*/g,l=`.*`}));u();export{o as checkModelScope,u as init_modelScope};
2
+ //# sourceMappingURL=modelScope.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelScope.mjs","names":[],"sources":["../../../src/runs/shared/modelScope.ts"],"sourcesContent":["/**\n * Decides whether a resolved model is inside the configured subagent model scope.\n *\n * DESIGN PATTERNS:\n * - Pure decision function, so scope policy can be unit-tested without config or\n * filesystem access\n * - Severity follows provenance rather than the model: a model the caller asked\n * for by name is an error, a model inherited from frontmatter, the settings\n * default, or the parent session is only a warning, so tightening scope never\n * breaks a working configuration outright\n * - Patterns match the full `provider/id`, never a bare id, so `*` cannot let an\n * unintended provider in through a same-named model\n *\n * AVOID:\n * - Treating an empty `allow` list as \"deny everything\"; enforcement without\n * patterns is a no-op here and is rejected at settings-parse time instead\n * - Comparing the raw model string; the thinking suffix is not part of identity\n */\n\nimport { splitKnownThinkingSuffix } from '../../shared/modelInfo.ts';\nimport type { ModelScopeConfig } from '../../types.ts';\n\n/** Where a resolved model originated, deciding enforcement severity. */\nexport type ModelSource = 'explicit' | 'inherited';\n\nexport interface ModelScopeViolation {\n /** Resolved model id (without thinking suffix) that fell outside the scope. */\n model: string;\n severity: 'warn' | 'error';\n message: string;\n allowedPatterns: string[];\n}\n\n/** RegExp metacharacters that must be escaped. `*` is excluded: it is the glob wildcard. */\nconst REGEXP_SPECIALS_EXCEPT_WILDCARD = /[.+^${}()|[\\]\\\\]/g;\nconst GLOB_WILDCARD = /\\*/g;\n/** What `*` expands to: any run of characters, including `/`, so `anthropic/*` covers every id. */\nconst WILDCARD_EXPANSION = '.*';\n\nfunction stripThinkingSuffix(model: string): string {\n return splitKnownThinkingSuffix(model).baseModel;\n}\n\n/** Escape RegExp specials except `*`, then turn `*` into `.*`. */\nfunction globToRegExp(pattern: string): RegExp {\n const escaped = pattern.replace(REGEXP_SPECIALS_EXCEPT_WILDCARD, '\\\\$&').replace(GLOB_WILDCARD, WILDCARD_EXPANSION);\n return new RegExp(`^${escaped}$`, 'i');\n}\n\n/**\n * Test whether a resolved model matches a single allow pattern. Both sides are\n * compared case-insensitively against the full `provider/id` (thinking suffix\n * stripped from the model).\n */\nexport function matchesScopePattern(model: string, pattern: string): boolean {\n return globToRegExp(pattern).test(stripThinkingSuffix(model));\n}\n\n/**\n * Pure scope decision. Returns a {@link ModelScopeViolation} when the model is\n * out of scope and enforcement is on, otherwise `undefined`. Enforcement with\n * no `allow` list is a no-op (the settings parser rejects that combination, but\n * this stays defensive for callers that build configs programmatically).\n */\nexport function checkModelScope(\n model: string | undefined,\n scope: ModelScopeConfig | undefined,\n source: ModelSource,\n): ModelScopeViolation | undefined {\n if (!model || !scope?.enforce) return undefined;\n const allow = scope.allow;\n if (!allow || allow.length === 0) return undefined;\n if (allow.some((pattern) => matchesScopePattern(model, pattern))) return undefined;\n\n const baseModel = stripThinkingSuffix(model);\n const severity: ModelScopeViolation['severity'] = source === 'explicit' ? 'error' : 'warn';\n return {\n model: baseModel,\n severity,\n allowedPatterns: allow,\n message:\n `Model '${baseModel}' is outside the configured subagent model scope. ` +\n `Allowed patterns: ${allow.join(', ')}.`,\n };\n}\n"],"mappings":"0JAuCA,SAAS,EAAoB,EAAuB,CAClD,OAAO,EAAyB,EAAM,CAAC,UAIzC,SAAS,EAAa,EAAyB,CAC7C,IAAM,EAAU,EAAQ,QAAQ,EAAiC,OAAO,CAAC,QAAQ,EAAe,EAAmB,CACnH,OAAW,OAAO,IAAI,EAAQ,GAAI,IAAI,CAQxC,SAAgB,EAAoB,EAAe,EAA0B,CAC3E,OAAO,EAAa,EAAQ,CAAC,KAAK,EAAoB,EAAM,CAAC,CAS/D,SAAgB,EACd,EACA,EACA,EACiC,CACjC,GAAI,CAAC,GAAS,CAAC,GAAO,QAAS,OAC/B,IAAM,EAAQ,EAAM,MAEpB,GADI,CAAC,GAAS,EAAM,SAAW,GAC3B,EAAM,KAAM,GAAY,EAAoB,EAAO,EAAQ,CAAC,CAAE,OAElE,IAAM,EAAY,EAAoB,EAAM,CAE5C,MAAO,CACL,MAAO,EACP,SAHgD,IAAW,WAAa,QAAU,OAIlF,gBAAiB,EACjB,QACE,UAAU,EAAU,sEACC,EAAM,KAAK,KAAK,CAAC,GACzC,wBAhEkE,CAe/D,EAAkC,oBAClC,EAAgB,MAEhB,EAAqB"}
@@ -0,0 +1,2 @@
1
+ const e=require(`../../_virtual/_rolldown/runtime.cjs`);let t=require(`node:path`);t=e.__toESM(t,1);function n(e){return typeof e==`string`&&e.length>0&&e.length<=128&&!t.isAbsolute(e)&&!e.includes(`/`)&&!e.includes(`\\`)&&!e.includes(`..`)}function r(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function i(e,t){return typeof e==`string`&&e.length>0?e.slice(0,t):void 0}function a(e){if(!Array.isArray(e))return[];let t=[];for(let a of e){if(typeof a!=`object`||!a)continue;let e=a,o=e.runId;if(!n(o))continue;let s=r(e.stepIndex),c=i(e.agent,128);if(t.push({runId:o,...s===void 0?{}:{stepIndex:s},...c?{agent:c}:{}}),t.length===4)break}return t}function o(e){if(!e)return[];try{return a(JSON.parse(e))}catch{return[]}}function s(e){let t=a(e);return t.length?JSON.stringify(t):``}exports.encodeNestedPathEnv=s,exports.parseNestedPathEnv=o;
2
+ //# sourceMappingURL=nestedPath.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nestedPath.cjs","names":["path"],"sources":["../../../src/runs/shared/nestedPath.ts"],"sourcesContent":["/**\n * The ancestry chain a nested child inherits from its parent.\n *\n * Each entry names one run in the line from the root run down to the child's\n * immediate parent, so a grandchild can report where it sits without the root\n * having to be asked.\n *\n * DESIGN PATTERNS:\n * - Sanitize on both encode and decode. The value crosses a process boundary in\n * an environment variable, so it is untrusted in both directions: a child\n * reads whatever its parent set, and a parent may be encoding ids that came\n * from further up. Neither side is a trusted source\n * - Every id is checked to be usable as a single path segment. Run ids become\n * directory names for run state, so a separator or `..` in one is a traversal,\n * not a formatting problem\n * - Malformed input degrades to an empty path rather than throwing. A broken\n * ancestry record is reporting metadata; it must not fail the run carrying it\n * - The chain is length-capped, so a fan-out loop cannot grow the variable until\n * it exceeds the environment block limit and breaks every later spawn\n *\n * AVOID:\n * - Trusting a decoded entry without re-sanitizing it\n * - Using an entry's `runId` in a path without this module having produced it\n */\n\nimport * as path from 'node:path';\n\nconst MAX_NESTED_ID_LENGTH = 128;\nconst MAX_AGENT_NAME_LENGTH = 128;\nconst PARENT_DIRECTORY_SEGMENT = '..';\nexport const MAX_NESTED_PATH_ENTRIES = 4;\n\nexport type NestedPathEntry = { runId: string; stepIndex?: number; agent?: string };\n\n/** True when `value` is safe to use as a single path segment. */\nexport function isSafeNestedPathId(value: unknown): value is string {\n return (\n typeof value === 'string' &&\n value.length > 0 &&\n value.length <= MAX_NESTED_ID_LENGTH &&\n !path.isAbsolute(value) &&\n !value.includes('/') &&\n !value.includes('\\\\') &&\n !value.includes(PARENT_DIRECTORY_SEGMENT)\n );\n}\n\nfunction finiteNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction nonEmptyString(value: unknown, max: number): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value.slice(0, max) : undefined;\n}\n\n/**\n * Keep only the entries that are well formed, dropping the rest.\n *\n * An entry without a safe `runId` is discarded entirely rather than repaired:\n * there is nothing to fall back to, and a guessed id would name the wrong run.\n * `stepIndex` and `agent` are labels only, so an unusable one is simply omitted.\n */\nexport function sanitizeNestedPath(value: unknown): NestedPathEntry[] {\n if (!Array.isArray(value)) return [];\n const sanitized: NestedPathEntry[] = [];\n for (const part of value) {\n if (typeof part !== 'object' || part === null) continue;\n const record: Record<string, unknown> = part as Record<string, unknown>;\n const runId = record.runId;\n if (!isSafeNestedPathId(runId)) continue;\n const stepIndex = finiteNumber(record.stepIndex);\n const agent = nonEmptyString(record.agent, MAX_AGENT_NAME_LENGTH);\n sanitized.push({\n runId,\n ...(stepIndex !== undefined ? { stepIndex } : {}),\n ...(agent ? { agent } : {}),\n });\n if (sanitized.length === MAX_NESTED_PATH_ENTRIES) break;\n }\n return sanitized;\n}\n\nexport function parseNestedPathEnv(value: string | undefined): NestedPathEntry[] {\n if (!value) return [];\n try {\n const parsed: unknown = JSON.parse(value);\n return sanitizeNestedPath(parsed);\n } catch {\n // The variable was set by another process and may be anything. An\n // unparseable ancestry reads as no ancestry, which is the narrow outcome.\n return [];\n }\n}\n\n/** Empty string, not `[]`, so an absent path and an empty one look alike to a child. */\nexport function encodeNestedPathEnv(value: NestedPathEntry[]): string {\n const sanitized = sanitizeNestedPath(value);\n return sanitized.length ? JSON.stringify(sanitized) : '';\n}\n"],"mappings":"oGAmCA,SAAgB,EAAmB,EAAiC,CAClE,OACE,OAAO,GAAU,UACjB,EAAM,OAAS,GACf,EAAM,QAAU,KAChB,CAACA,EAAK,WAAW,EAAM,EACvB,CAAC,EAAM,SAAS,IAAI,EACpB,CAAC,EAAM,SAAS,KAAK,EACrB,CAAC,EAAM,SAAS,KAAyB,CAI7C,SAAS,EAAa,EAAoC,CACxD,OAAO,OAAO,GAAU,UAAY,OAAO,SAAS,EAAM,CAAG,EAAQ,IAAA,GAGvE,SAAS,EAAe,EAAgB,EAAiC,CACvE,OAAO,OAAO,GAAU,UAAY,EAAM,OAAS,EAAI,EAAM,MAAM,EAAG,EAAI,CAAG,IAAA,GAU/E,SAAgB,EAAmB,EAAmC,CACpE,GAAI,CAAC,MAAM,QAAQ,EAAM,CAAE,MAAO,EAAE,CACpC,IAAM,EAA+B,EAAE,CACvC,IAAK,IAAM,KAAQ,EAAO,CACxB,GAAI,OAAO,GAAS,WAAY,EAAe,SAC/C,IAAM,EAAkC,EAClC,EAAQ,EAAO,MACrB,GAAI,CAAC,EAAmB,EAAM,CAAE,SAChC,IAAM,EAAY,EAAa,EAAO,UAAU,CAC1C,EAAQ,EAAe,EAAO,MAAO,IAAsB,CAMjE,GALA,EAAU,KAAK,CACb,QACA,GAAI,IAAc,IAAA,GAA4B,EAAE,CAAlB,CAAE,YAAW,CAC3C,GAAI,EAAQ,CAAE,QAAO,CAAG,EAAE,CAC3B,CAAC,CACE,EAAU,SAAA,EAAoC,MAEpD,OAAO,EAGT,SAAgB,EAAmB,EAA8C,CAC/E,GAAI,CAAC,EAAO,MAAO,EAAE,CACrB,GAAI,CAEF,OAAO,EADiB,KAAK,MAAM,EACH,CAAC,MAC3B,CAGN,MAAO,EAAE,EAKb,SAAgB,EAAoB,EAAkC,CACpE,IAAM,EAAY,EAAmB,EAAM,CAC3C,OAAO,EAAU,OAAS,KAAK,UAAU,EAAU,CAAG"}
@@ -0,0 +1,2 @@
1
+ import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import*as t from"node:path";function n(e){return typeof e==`string`&&e.length>0&&e.length<=c&&!t.isAbsolute(e)&&!e.includes(`/`)&&!e.includes(`\\`)&&!e.includes(u)}function r(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function i(e,t){return typeof e==`string`&&e.length>0?e.slice(0,t):void 0}function a(e){if(!Array.isArray(e))return[];let t=[];for(let a of e){if(typeof a!=`object`||!a)continue;let e=a,o=e.runId;if(!n(o))continue;let s=r(e.stepIndex),c=i(e.agent,l);if(t.push({runId:o,...s===void 0?{}:{stepIndex:s},...c?{agent:c}:{}}),t.length===4)break}return t}function o(e){if(!e)return[];try{return a(JSON.parse(e))}catch{return[]}}function s(e){let t=a(e);return t.length?JSON.stringify(t):``}var c,l,u,d=e((()=>{c=128,l=128,u=`..`}));d();export{s as encodeNestedPathEnv,d as init_nestedPath,o as parseNestedPathEnv};
2
+ //# sourceMappingURL=nestedPath.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nestedPath.mjs","names":[],"sources":["../../../src/runs/shared/nestedPath.ts"],"sourcesContent":["/**\n * The ancestry chain a nested child inherits from its parent.\n *\n * Each entry names one run in the line from the root run down to the child's\n * immediate parent, so a grandchild can report where it sits without the root\n * having to be asked.\n *\n * DESIGN PATTERNS:\n * - Sanitize on both encode and decode. The value crosses a process boundary in\n * an environment variable, so it is untrusted in both directions: a child\n * reads whatever its parent set, and a parent may be encoding ids that came\n * from further up. Neither side is a trusted source\n * - Every id is checked to be usable as a single path segment. Run ids become\n * directory names for run state, so a separator or `..` in one is a traversal,\n * not a formatting problem\n * - Malformed input degrades to an empty path rather than throwing. A broken\n * ancestry record is reporting metadata; it must not fail the run carrying it\n * - The chain is length-capped, so a fan-out loop cannot grow the variable until\n * it exceeds the environment block limit and breaks every later spawn\n *\n * AVOID:\n * - Trusting a decoded entry without re-sanitizing it\n * - Using an entry's `runId` in a path without this module having produced it\n */\n\nimport * as path from 'node:path';\n\nconst MAX_NESTED_ID_LENGTH = 128;\nconst MAX_AGENT_NAME_LENGTH = 128;\nconst PARENT_DIRECTORY_SEGMENT = '..';\nexport const MAX_NESTED_PATH_ENTRIES = 4;\n\nexport type NestedPathEntry = { runId: string; stepIndex?: number; agent?: string };\n\n/** True when `value` is safe to use as a single path segment. */\nexport function isSafeNestedPathId(value: unknown): value is string {\n return (\n typeof value === 'string' &&\n value.length > 0 &&\n value.length <= MAX_NESTED_ID_LENGTH &&\n !path.isAbsolute(value) &&\n !value.includes('/') &&\n !value.includes('\\\\') &&\n !value.includes(PARENT_DIRECTORY_SEGMENT)\n );\n}\n\nfunction finiteNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\nfunction nonEmptyString(value: unknown, max: number): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value.slice(0, max) : undefined;\n}\n\n/**\n * Keep only the entries that are well formed, dropping the rest.\n *\n * An entry without a safe `runId` is discarded entirely rather than repaired:\n * there is nothing to fall back to, and a guessed id would name the wrong run.\n * `stepIndex` and `agent` are labels only, so an unusable one is simply omitted.\n */\nexport function sanitizeNestedPath(value: unknown): NestedPathEntry[] {\n if (!Array.isArray(value)) return [];\n const sanitized: NestedPathEntry[] = [];\n for (const part of value) {\n if (typeof part !== 'object' || part === null) continue;\n const record: Record<string, unknown> = part as Record<string, unknown>;\n const runId = record.runId;\n if (!isSafeNestedPathId(runId)) continue;\n const stepIndex = finiteNumber(record.stepIndex);\n const agent = nonEmptyString(record.agent, MAX_AGENT_NAME_LENGTH);\n sanitized.push({\n runId,\n ...(stepIndex !== undefined ? { stepIndex } : {}),\n ...(agent ? { agent } : {}),\n });\n if (sanitized.length === MAX_NESTED_PATH_ENTRIES) break;\n }\n return sanitized;\n}\n\nexport function parseNestedPathEnv(value: string | undefined): NestedPathEntry[] {\n if (!value) return [];\n try {\n const parsed: unknown = JSON.parse(value);\n return sanitizeNestedPath(parsed);\n } catch {\n // The variable was set by another process and may be anything. An\n // unparseable ancestry reads as no ancestry, which is the narrow outcome.\n return [];\n }\n}\n\n/** Empty string, not `[]`, so an absent path and an empty one look alike to a child. */\nexport function encodeNestedPathEnv(value: NestedPathEntry[]): string {\n const sanitized = sanitizeNestedPath(value);\n return sanitized.length ? JSON.stringify(sanitized) : '';\n}\n"],"mappings":"4FAmCA,SAAgB,EAAmB,EAAiC,CAClE,OACE,OAAO,GAAU,UACjB,EAAM,OAAS,GACf,EAAM,QAAU,GAChB,CAAC,EAAK,WAAW,EAAM,EACvB,CAAC,EAAM,SAAS,IAAI,EACpB,CAAC,EAAM,SAAS,KAAK,EACrB,CAAC,EAAM,SAAS,EAAyB,CAI7C,SAAS,EAAa,EAAoC,CACxD,OAAO,OAAO,GAAU,UAAY,OAAO,SAAS,EAAM,CAAG,EAAQ,IAAA,GAGvE,SAAS,EAAe,EAAgB,EAAiC,CACvE,OAAO,OAAO,GAAU,UAAY,EAAM,OAAS,EAAI,EAAM,MAAM,EAAG,EAAI,CAAG,IAAA,GAU/E,SAAgB,EAAmB,EAAmC,CACpE,GAAI,CAAC,MAAM,QAAQ,EAAM,CAAE,MAAO,EAAE,CACpC,IAAM,EAA+B,EAAE,CACvC,IAAK,IAAM,KAAQ,EAAO,CACxB,GAAI,OAAO,GAAS,WAAY,EAAe,SAC/C,IAAM,EAAkC,EAClC,EAAQ,EAAO,MACrB,GAAI,CAAC,EAAmB,EAAM,CAAE,SAChC,IAAM,EAAY,EAAa,EAAO,UAAU,CAC1C,EAAQ,EAAe,EAAO,MAAO,EAAsB,CAMjE,GALA,EAAU,KAAK,CACb,QACA,GAAI,IAAc,IAAA,GAA4B,EAAE,CAAlB,CAAE,YAAW,CAC3C,GAAI,EAAQ,CAAE,QAAO,CAAG,EAAE,CAC3B,CAAC,CACE,EAAU,SAAA,EAAoC,MAEpD,OAAO,EAGT,SAAgB,EAAmB,EAA8C,CAC/E,GAAI,CAAC,EAAO,MAAO,EAAE,CACrB,GAAI,CAEF,OAAO,EADiB,KAAK,MAAM,EACH,CAAC,MAC3B,CAGN,MAAO,EAAE,EAKb,SAAgB,EAAoB,EAAkC,CACpE,IAAM,EAAY,EAAmB,EAAM,CAC3C,OAAO,EAAU,OAAS,KAAK,UAAU,EAAU,CAAG,uBAtElD,EAAuB,IACvB,EAAwB,IACxB,EAA2B"}
@@ -0,0 +1,2 @@
1
+ const e=require(`../../_virtual/_rolldown/runtime.cjs`),t=require(`../../env.cjs`),n=require(`../../protocol/capabilityCeiling.cjs`),r=require(`../../shared/paths.cjs`),i=require(`../../shared/modelInfo.cjs`),a=require(`../../intercom/nativeTeamChannel.cjs`),o=require(`./mcpDirectToolAllowlist.cjs`),s=require(`./nestedPath.cjs`),c=require(`./piSpawn.cjs`),l=require(`./toolBudget.cjs`);let u=require(`node:fs`);u=e.__toESM(u,1);let d=require(`node:path`);d=e.__toESM(d,1);let f=require(`@agimon-ai/doompi-extension-contracts/child-process`),p=require(`node:url`);const m=`Task: `,h=`read`,g=`structured_output`,_=/[^\w.-]/g,v=/^\d+$/,y=`dist`,b=`extensions/subagentPromptRuntimeEntry`,x=`.cts`;function S(e,t=`.ts`){let n=(0,p.fileURLToPath)(require(`url`).pathToFileURL(__filename).href),r=n.split(d.sep).includes(y),i=r?y:`src`,a=r?`.mjs`:t,o=d.dirname(n);for(;;){let t=d.join(o,i,`${e}${a}`);if(u.existsSync(t))return t;let n=d.dirname(o);if(n===o)throw Error(`Could not resolve runtime extension ${e}`);o=n}}function C(e=process.env){let n=e[t.DOOMPI_CHILD_EXTENSIONS_ENV];if(!n)return[];let r;try{r=JSON.parse(n)}catch(e){let n=e instanceof Error?` ${e.message}`:``;throw Error(`${t.DOOMPI_CHILD_EXTENSIONS_ENV} must be valid JSON.${n}`)}if(!Array.isArray(r)||!r.every(e=>typeof e==`string`))throw Error(`${t.DOOMPI_CHILD_EXTENSIONS_ENV} must be a JSON array of extension paths.`);return r}function w(e=process.env){let n=e[t.DOOMPI_SKILL_DIRS_ENV];return n?n.split(d.delimiter).filter(Boolean):[]}function T(e,t,n=!1){if(!e||!t)return e;let r=e.lastIndexOf(`:`);return r!==-1&&i.THINKING_LEVELS.some(t=>t===e.substring(r+1))?n?`${e.slice(0,r)}:${t}`:e:`${e}:${t}`}function E(e){return e.includes(`/`)||e.endsWith(`.ts`)||e.endsWith(`.js`)}function D(e){let t=n.intersectSubagentCapabilityCeilings(e.capabilityCeiling,e.inheritedCapabilityCeiling),r=t?.allowedTools===void 0?void 0:new Set(t.allowedTools),i=t?.allowedTools?.filter(e=>!(t.allowMcpTools===!0&&e===`mcp`)),s=[...new Set((e.excludeTools??[]).map(e=>e.trim()).filter(e=>e.length>0))],c=new Set(s),l=t?.requiredTools??[],u=t?.allowMcpTools===!0,d=u&&[...e.tools??[],...l].includes(`mcp`),f=[...new Set([...e.tools??[],...l])].filter(e=>!E(e)&&!(d&&e===`mcp`)),p=[...e.mcpDirectTools??[],...d?[`*`]:[]];if(e.requireReadTool&&c.has(h))throw Error(`Child tool exclusions exclude required tool '${h}' for lazy skill loading.`);if(e.structuredOutput&&c.has(g))throw Error(`Child tool exclusions exclude required tool '${g}'.`);if(e.requireReadTool&&r&&!r.has(h))throw Error(`Capability ceiling from ${t?.sources.join(`, `)||`unknown source`} excludes required tool '${h}' for lazy skill loading.`);let m=e.tools===void 0?i??[]:(e.requireReadTool&&f.length>0&&!f.includes(h)&&!r?[h,...f]:f).filter(e=>!r||r.has(e)).filter(e=>!c.has(e)),_=m.includes(`subagent`),v=t?.denyExtensions?[]:(e.tools??[]).filter(e=>!f.includes(e)&&E(e)),y=t?.denyExtensions?[]:o.resolveMcpDirectToolSelections(p,e.cwd),C=y.filter(e=>(u||!r||r.has(e.name))&&!c.has(e.name)),w=C.map(e=>e.name),T=e.tools!==void 0||p.length>0||r!==void 0,D=[...e.structuredOutput?[g]:[],...e.teamToolEnabled?[a.NATIVE_TEAM_TOOL_NAME]:[]].filter(e=>!c.has(e)),O=[...new Set([...m,...w,...D])];if(e.requireReadTool&&T&&!O.includes(h))throw Error(`Effective child tool allowlist excludes required tool '${h}' for lazy skill loading.`);let k=T?[...new Set([...e.tools===void 0?[]:m,...p.length?w:[],...D])]:[],A=_?[S(b,x),S(`extension/fanout-child`)]:[S(b,x)],j=t?.denyExtensions===!0||e.extensions!==void 0,M=t?.denyExtensions?[]:[...v,...e.extensions??[],...e.subagentOnlyExtensions??[]],N=j?[...new Set([...A,...M])]:[...new Set([...A,...v,...e.subagentOnlyExtensions??[]])],P=e.tools===void 0?void 0:[...new Set([...f,...y.map(e=>e.name)])],F=t?{ceiling:t,...P?{requestedTools:P}:{},effectiveTools:O,removedTools:P?.filter(e=>!O.includes(e))??[],internalTools:D,extensionsDenied:t.denyExtensions,removedExtensionCount:t.denyExtensions?(e.extensions?.length??0)+(e.subagentOnlyExtensions?.length??0)+(e.tools??[]).filter(E).length:0,requestedMcpToolCount:p.length,effectiveMcpTools:w}:void 0;return{...t?{capabilityCeiling:t}:{},excludedTools:s,requestedBuiltinTools:f,declaredBuiltinTools:m,toolExtensionPaths:v,resolvedMcpSelections:y,effectiveMcpSelections:C,effectiveMcpTools:w,explicitToolAllowlist:T,internalTools:D,effectiveToolAllowlist:O,requiredChildTools:k,fanoutAuthorized:_,runtimeExtensions:A,configuredExtensions:M,extensionArgs:N,disableAmbientExtensions:j,...F?{capabilityAudit:F}:{}}}function O(e){let r=e.environment??process.env,i=n.intersectSubagentCapabilityCeilings(e.inheritedCapabilityCeiling,n.decodeSubagentCapabilityCeiling(r[t.SUBAGENT_CAPABILITY_CEILING_ENV])),a=D({tools:e.tools,extensions:e.extensions,subagentOnlyExtensions:e.subagentOnlyExtensions,mcpDirectTools:e.mcpDirectTools,cwd:e.cwd,requireReadTool:e.requireReadTool,excludeTools:e.excludeTools,structuredOutput:e.structuredOutput,teamToolEnabled:e.teamToolEnabled,capabilityCeiling:e.capabilityCeiling,inheritedCapabilityCeiling:i}),o=a.explicitToolAllowlist?a.effectiveToolAllowlist:void 0;return{toolPlan:a,...o&&o.length>0?{tools:o}:{},...o?.length===0?{noTools:`all`}:{},...a.excludedTools.length>0?{excludeTools:a.excludedTools}:{},extensions:[...new Set([...C(r),...a.extensionArgs])],noAmbientExtensions:a.disableAmbientExtensions,skillPaths:e.inheritSkills?w(r):[],noSkills:!e.inheritSkills}}function k(){return u.mkdirSync(r.currentChildLaunchTempDir(),{recursive:!0,mode:448}),u.mkdtempSync(d.join(r.currentChildLaunchTempDir(),`doom-team-launch-`))}function A(e){let r=[...e.baseArgs];e.sessionFile?(u.mkdirSync(d.dirname(e.sessionFile),{recursive:!0}),r.push(`--session`,e.sessionFile)):(e.sessionEnabled||r.push(`--no-session`),e.sessionDir&&(u.mkdirSync(e.sessionDir,{recursive:!0}),r.push(`--session-dir`,e.sessionDir)));let i=T(e.model,e.thinking);i&&r.push(`--model`,i);let{toolPlan:o,...p}=O({tools:e.tools,extensions:e.extensions,subagentOnlyExtensions:e.subagentOnlyExtensions,mcpDirectTools:e.mcpDirectTools,cwd:e.cwd,requireReadTool:e.requireReadTool,excludeTools:e.excludeTools,structuredOutput:!!e.structuredOutput,teamToolEnabled:!!e.teamMember||e.teamToolEnabled===!0,capabilityCeiling:e.capabilityCeiling,inheritSkills:e.inheritSkills});o.explicitToolAllowlist&&(r.push(o.effectiveToolAllowlist.length>0?`--tools`:`--no-tools`),o.effectiveToolAllowlist.length>0&&r.push(o.effectiveToolAllowlist.join(`,`))),o.excludedTools.length>0&&r.push(`--exclude-tools`,o.excludedTools.join(`,`)),o.disableAmbientExtensions&&r.push(`--no-extensions`);for(let e of o.extensionArgs)r.push(`--extension`,e);e.inheritProjectContext||r.push(`--no-context-files`),e.inheritSkills||r.push(`--no-skills`);let h,g=()=>(h??=k(),h);if(e.systemPrompt!==void 0&&e.systemPrompt!==null){let t=(e.promptFileStem??`prompt`).replace(_,`_`),n=d.join(g(),`${t}.md`);u.writeFileSync(n,e.systemPrompt,{mode:384}),r.push(e.systemPromptMode===`replace`?`--system-prompt`:`--append-system-prompt`,n)}if(e.task.length>8e3){let t=d.join(g(),`task.md`);u.writeFileSync(t,`${m}${e.task}`,{mode:384}),r.push(`@${t}`)}else r.push(`${m}${e.task}`);let y={...e.teamMember?a.nativeTeamMemberEnvironment(e.teamMember):a.clearNativeTeamMemberEnvironment()},b=process.env.PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT??c.resolvePiPackageRoot();b&&(y[t.PI_CODING_AGENT_PACKAGE_ROOT_ENV]=b);let x;o.requiredChildTools.length>0&&(x=d.join(g(),`tool-diagnostic.json`),y[t.REQUIRED_CHILD_TOOLS_ENV]=JSON.stringify(o.requiredChildTools),y[t.CHILD_TOOL_DIAGNOSTIC_PATH_ENV]=x),y[t.MCP_DIRECT_CHILD_TOOLS_ENV]=o.effectiveMcpTools.length>0?JSON.stringify(o.effectiveMcpTools):void 0,y[f.SUBAGENT_CHILD_ENV]=`1`,y[t.SUBAGENT_FANOUT_CHILD_ENV]=o.fanoutAuthorized?`1`:`0`;let S=!!(process.env.PI_SUBAGENT_PARENT_EVENT_SINK&&process.env.PI_SUBAGENT_PARENT_ROOT_RUN_ID&&process.env.PI_SUBAGENT_PARENT_CAPABILITY_TOKEN),C=e.parentRunId??e.runId??(S?process.env.PI_SUBAGENT_RUN_ID:void 0)??process.env.PI_SUBAGENT_PARENT_RUN_ID??``,w=e.parentChildIndex===void 0?e.childIndex===void 0?process.env.PI_SUBAGENT_PARENT_CHILD_INDEX??``:String(e.childIndex):String(e.parentChildIndex),E=Number(process.env[t.SUBAGENT_PARENT_DEPTH_ENV]),D=e.parentDepth??(S&&Number.isFinite(E)?E+1:1),A=e.parentPath??[...s.parseNestedPathEnv(process.env.PI_SUBAGENT_PARENT_PATH),...C?[{runId:C,...w&&v.test(w)?{stepIndex:Number(w)}:{},...e.childAgentName?{agent:e.childAgentName}:{}}]:[]];y[t.SUBAGENT_PARENT_EVENT_SINK_ENV]=o.fanoutAuthorized?e.parentEventSink??process.env.PI_SUBAGENT_PARENT_EVENT_SINK??``:``,y[t.SUBAGENT_PARENT_CONTROL_INBOX_ENV]=o.fanoutAuthorized?e.parentControlInbox??process.env.PI_SUBAGENT_PARENT_CONTROL_INBOX??``:``,y[t.SUBAGENT_PARENT_ROOT_RUN_ID_ENV]=o.fanoutAuthorized?e.parentRootRunId??process.env.PI_SUBAGENT_PARENT_ROOT_RUN_ID??e.runId??``:``,y[t.SUBAGENT_PARENT_RUN_ID_ENV]=o.fanoutAuthorized?C:``,y[t.SUBAGENT_PARENT_CHILD_INDEX_ENV]=o.fanoutAuthorized?w:``,y[t.SUBAGENT_PARENT_DEPTH_ENV]=o.fanoutAuthorized?String(D):``,y[t.SUBAGENT_PARENT_PATH_ENV]=o.fanoutAuthorized?s.encodeNestedPathEnv(A):``,y[t.SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV]=o.fanoutAuthorized?e.parentCapabilityToken??process.env.PI_SUBAGENT_PARENT_CAPABILITY_TOKEN??``:``,y[t.INHERIT_PROJECT_CONTEXT_ENV]=e.inheritProjectContext?`1`:`0`,y[t.INHERIT_SKILLS_ENV]=e.inheritSkills?`1`:`0`,y[t.PI_INTERCOM_STABLE_ID_ENV]=e.intercomSessionName||void 0,y[t.PI_INTERCOM_SESSION_ID_ENV]=void 0,e.intercomSessionName&&(y[t.SUBAGENT_INTERCOM_SESSION_NAME_ENV]=e.intercomSessionName),e.runId&&(y[t.SUBAGENT_RUN_ID_ENV]=e.runId),e.childAgentName&&(y[t.SUBAGENT_CHILD_AGENT_ENV]=e.childAgentName),e.childIndex!==void 0&&(y[t.SUBAGENT_CHILD_INDEX_ENV]=String(e.childIndex)),!o.capabilityCeiling&&e.mcpDirectTools?.length?y[t.MCP_DIRECT_TOOLS_ENV]=e.mcpDirectTools.join(`,`):o.capabilityCeiling&&o.effectiveMcpSelections.length&&!o.capabilityCeiling.denyExtensions?y[t.MCP_DIRECT_TOOLS_ENV]=o.effectiveMcpSelections.map(e=>e.selector).join(`,`):y[t.MCP_DIRECT_TOOLS_ENV]=`__none__`;let j=n.encodeSubagentCapabilityCeiling(o.capabilityCeiling);j&&(y[t.SUBAGENT_CAPABILITY_CEILING_ENV]=j),e.structuredOutput&&(y[t.STRUCTURED_OUTPUT_CAPTURE_ENV]=e.structuredOutput.outputPath,y[t.STRUCTURED_OUTPUT_SCHEMA_ENV]=e.structuredOutput.schemaPath),e.steerInboxDir&&(y[t.SUBAGENT_STEER_INBOX_ENV]=e.steerInboxDir),e.steerCapabilityPath&&(y[t.SUBAGENT_STEER_CAPABILITY_ENV]=e.steerCapabilityPath),e.steerAckDir&&(y[t.SUBAGENT_STEER_ACK_DIR_ENV]=e.steerAckDir);let M=l.encodeToolBudgetEnv(e.toolBudget);return M&&(y[t.TOOL_BUDGET_ENV]=M),y[t.TOOL_BUDGET_ZERO_AUTH_ENV]=e.allowZeroToolBudget?`1`:void 0,y[f.SUBAGENT_PARENT_SESSION_ENV]=e.parentSessionId??process.env[f.SUBAGENT_PARENT_SESSION_ENV]??``,y[f.DOOM_CHILD_PROCESS_CONTEXT_ENV]=e.parentSessionId?(0,f.encodeChildProcessContext)({parentSessionId:e.parentSessionId,workingDirectory:e.cwd??process.cwd(),...e.childAgentName?{mode:e.childAgentName}:{}}):void 0,{args:r,env:y,sdk:{...e.model||e.thinking?{model:T(e.model,e.thinking)}:{},...p,noContextFiles:!e.inheritProjectContext,sessionEnabled:e.sessionEnabled,...e.sessionDir?{sessionDir:e.sessionDir}:{},...e.sessionFile?{sessionFile:e.sessionFile}:{},...e.systemPrompt!==void 0&&e.systemPrompt!==null?{systemPrompt:e.systemPrompt}:{},...e.systemPromptMode?{systemPromptMode:e.systemPromptMode}:{}},tempDir:h,toolDiagnosticPath:x,capabilityAudit:o.capabilityAudit}}exports.buildPiArgs=A,exports.resolvePiSdkResourcePlan=O;
2
+ //# sourceMappingURL=piArgs.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"piArgs.cjs","names":["path","fs","DOOMPI_CHILD_EXTENSIONS_ENV","DOOMPI_SKILL_DIRS_ENV","THINKING_LEVELS","intersectSubagentCapabilityCeilings","resolveMcpDirectToolSelections","NATIVE_TEAM_TOOL_NAME","decodeSubagentCapabilityCeiling","SUBAGENT_CAPABILITY_CEILING_ENV","currentChildLaunchTempDir","nativeTeamMemberEnvironment","clearNativeTeamMemberEnvironment","resolvePiPackageRoot","PI_CODING_AGENT_PACKAGE_ROOT_ENV","REQUIRED_CHILD_TOOLS_ENV","CHILD_TOOL_DIAGNOSTIC_PATH_ENV","MCP_DIRECT_CHILD_TOOLS_ENV","SUBAGENT_CHILD_ENV","SUBAGENT_FANOUT_CHILD_ENV","SUBAGENT_PARENT_DEPTH_ENV","parseNestedPathEnv","SUBAGENT_PARENT_EVENT_SINK_ENV","SUBAGENT_PARENT_CONTROL_INBOX_ENV","SUBAGENT_PARENT_ROOT_RUN_ID_ENV","SUBAGENT_PARENT_RUN_ID_ENV","SUBAGENT_PARENT_CHILD_INDEX_ENV","SUBAGENT_PARENT_PATH_ENV","encodeNestedPathEnv","SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV","INHERIT_PROJECT_CONTEXT_ENV","INHERIT_SKILLS_ENV","PI_INTERCOM_STABLE_ID_ENV","PI_INTERCOM_SESSION_ID_ENV","SUBAGENT_INTERCOM_SESSION_NAME_ENV","SUBAGENT_RUN_ID_ENV","SUBAGENT_CHILD_AGENT_ENV","SUBAGENT_CHILD_INDEX_ENV","MCP_DIRECT_TOOLS_ENV","encodeSubagentCapabilityCeiling","STRUCTURED_OUTPUT_CAPTURE_ENV","STRUCTURED_OUTPUT_SCHEMA_ENV","SUBAGENT_STEER_INBOX_ENV","SUBAGENT_STEER_CAPABILITY_ENV","SUBAGENT_STEER_ACK_DIR_ENV","encodeToolBudgetEnv","TOOL_BUDGET_ENV","TOOL_BUDGET_ZERO_AUTH_ENV","SUBAGENT_PARENT_SESSION_ENV","DOOM_CHILD_PROCESS_CONTEXT_ENV"],"sources":["../../../src/runs/shared/piArgs.ts"],"sourcesContent":["/**\n * The argv and environment handed to a spawned child agent.\n *\n * DESIGN PATTERNS:\n * - `resolvePiLaunchToolPlan` is the single place tool access is decided, and it\n * is pure. Everything about what a child may call is computable and testable\n * without touching the filesystem or spawning anything\n * - Capability ceilings only ever narrow. A ceiling from this process is\n * intersected with the one inherited from our own parent, and every requested\n * tool is then filtered against the result. Nothing in this file can add a tool\n * the ceiling excludes\n * - Fan-out authority is derived, not requested. A child receives the parent\n * event sink, control inbox, capability token and nesting path ONLY if it was\n * granted the `subagent` tool. Otherwise those variables are set to the empty\n * string rather than omitted, so an inherited value from our own environment\n * cannot leak through into a child that is not allowed to fan out\n * - Long task text goes to a private file passed as `@path` instead of argv,\n * because argv is both length-limited and visible in the process table\n *\n * AVOID:\n * - Widening anything here. If a case is ambiguous, narrow it\n * - Omitting a fan-out variable instead of blanking it; omission inherits\n * - Re-declaring env var names; they live in `src/env.ts` and cross processes\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n DOOM_CHILD_PROCESS_CONTEXT_ENV,\n encodeChildProcessContext,\n} from '@agimon-ai/doompi-extension-contracts/child-process';\nimport {\n CHILD_TOOL_DIAGNOSTIC_PATH_ENV,\n DOOMPI_CHILD_EXTENSIONS_ENV,\n DOOMPI_SKILL_DIRS_ENV,\n INHERIT_PROJECT_CONTEXT_ENV,\n INHERIT_SKILLS_ENV,\n MCP_DIRECT_CHILD_TOOLS_ENV,\n MCP_DIRECT_TOOLS_ENV,\n PI_CODING_AGENT_PACKAGE_ROOT_ENV,\n PI_INTERCOM_SESSION_ID_ENV,\n PI_INTERCOM_STABLE_ID_ENV,\n REQUIRED_CHILD_TOOLS_ENV,\n STRUCTURED_OUTPUT_CAPTURE_ENV,\n STRUCTURED_OUTPUT_SCHEMA_ENV,\n SUBAGENT_CAPABILITY_CEILING_ENV,\n SUBAGENT_CHILD_AGENT_ENV,\n SUBAGENT_CHILD_ENV,\n SUBAGENT_CHILD_INDEX_ENV,\n SUBAGENT_FANOUT_CHILD_ENV,\n SUBAGENT_INTERCOM_SESSION_NAME_ENV,\n SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV,\n SUBAGENT_PARENT_CHILD_INDEX_ENV,\n SUBAGENT_PARENT_CONTROL_INBOX_ENV,\n SUBAGENT_PARENT_DEPTH_ENV,\n SUBAGENT_PARENT_EVENT_SINK_ENV,\n SUBAGENT_PARENT_PATH_ENV,\n SUBAGENT_PARENT_ROOT_RUN_ID_ENV,\n SUBAGENT_PARENT_RUN_ID_ENV,\n SUBAGENT_PARENT_SESSION_ENV,\n SUBAGENT_RUN_ID_ENV,\n SUBAGENT_STEER_ACK_DIR_ENV,\n SUBAGENT_STEER_CAPABILITY_ENV,\n SUBAGENT_STEER_INBOX_ENV,\n TOOL_BUDGET_ENV,\n TOOL_BUDGET_ZERO_AUTH_ENV,\n} from '../../env.ts';\nimport {\n decodeSubagentCapabilityCeiling,\n encodeSubagentCapabilityCeiling,\n intersectSubagentCapabilityCeilings,\n type ResolvedSubagentCapabilityCeiling,\n type SubagentCapabilityAudit,\n} from '../../protocol/capabilityCeiling.ts';\nimport { THINKING_LEVELS } from '../../shared/modelInfo.ts';\nimport { currentChildLaunchTempDir } from '../../shared/paths.ts';\nimport type { JsonSchemaObject } from '../../types.ts';\nimport {\n NATIVE_TEAM_TOOL_NAME,\n clearNativeTeamMemberEnvironment,\n nativeTeamMemberEnvironment,\n type TeamMemberContext,\n} from '../../intercom/nativeTeamChannel.ts';\nimport { resolveMcpDirectToolSelections, type ResolvedMcpDirectToolSelection } from './mcpDirectToolAllowlist.ts';\nimport { encodeNestedPathEnv, parseNestedPathEnv, type NestedPathEntry } from './nestedPath.ts';\nimport { resolvePiPackageRoot } from './piSpawn.ts';\nimport { encodeToolBudgetEnv, type ResolvedToolBudget } from './toolBudget.ts';\n\n/**\n * Task text longer than this is written to a file and passed as `@path`.\n *\n * Well under the platform argv limit, because the task shares argv with the\n * model, tool and extension flags.\n */\nconst TASK_ARG_LIMIT = 8000;\nconst TEMP_DIRECTORY_PREFIX = 'doom-team-launch-';\nconst TASK_PREFIX = 'Task: ';\nconst TYPESCRIPT_EXTENSION = '.ts';\nconst JAVASCRIPT_EXTENSION = '.js';\nconst PROMPT_FILE_EXTENSION = '.md';\nconst DEFAULT_PROMPT_FILE_STEM = 'prompt';\nconst TASK_FILE_NAME = 'task.md';\nconst TOOL_DIAGNOSTIC_FILE_NAME = 'tool-diagnostic.json';\nconst READ_TOOL_NAME = 'read';\nconst MCP_TOOL_NAME = 'mcp';\nconst ALL_MCP_SERVERS_SELECTOR = '*';\nconst SUBAGENT_TOOL_NAME = 'subagent';\nconst STRUCTURED_OUTPUT_TOOL_NAME = 'structured_output';\nconst NO_MCP_DIRECT_TOOLS = '__none__';\nconst ENABLED_ENV_VALUE = '1';\nconst DISABLED_ENV_VALUE = '0';\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIR_MODE = 0o700;\nconst ROOT_FANOUT_DEPTH = 1;\nconst UNSAFE_PROMPT_STEM_CHARACTERS = /[^\\w.-]/g;\nconst DIGITS_ONLY = /^\\d+$/;\n\nconst SESSION_FLAG = '--session';\nconst NO_SESSION_FLAG = '--no-session';\nconst SESSION_DIRECTORY_FLAG = '--session-dir';\nconst MODEL_FLAG = '--model';\nconst TOOLS_FLAG = '--tools';\nconst NO_TOOLS_FLAG = '--no-tools';\nconst EXCLUDE_TOOLS_FLAG = '--exclude-tools';\nconst NO_EXTENSIONS_FLAG = '--no-extensions';\nconst EXTENSION_FLAG = '--extension';\nconst NO_CONTEXT_FILES_FLAG = '--no-context-files';\nconst NO_SKILLS_FLAG = '--no-skills';\nconst SYSTEM_PROMPT_FLAG = '--system-prompt';\nconst APPEND_SYSTEM_PROMPT_FLAG = '--append-system-prompt';\n\nconst BUILT_OUTPUT_DIR = 'dist';\nconst SOURCE_DIR = 'src';\nconst BUILT_EXTENSION = '.mjs';\nconst PROMPT_RUNTIME_EXTENSION = 'extensions/subagentPromptRuntimeEntry';\nconst PROMPT_RUNTIME_SOURCE_EXTENSION = '.cts';\nconst FANOUT_CHILD_EXTENSION = 'extension/fanout-child';\n\n/**\n * Locate an extension the child must load, in either a built or a source tree.\n *\n * The child is a separate process loading these by path, so the path has to be\n * the one that exists on disk now: `.mjs` under `dist` when this bundle is\n * built, the original source file when it is not.\n *\n * Resolved on demand rather than at module load. Doing it eagerly would make\n * importing this module throw in any tree where the extensions are not built\n * yet, which turns a launch-time problem into an import-time one.\n */\nfunction resolveRuntimeExtensionPath(relativePath: string, sourceExtension = TYPESCRIPT_EXTENSION): string {\n const modulePath = fileURLToPath(import.meta.url);\n const builtMode = modulePath.split(path.sep).includes(BUILT_OUTPUT_DIR);\n const runtimeRoot = builtMode ? BUILT_OUTPUT_DIR : SOURCE_DIR;\n const extension = builtMode ? BUILT_EXTENSION : sourceExtension;\n let directory = path.dirname(modulePath);\n while (true) {\n const candidate = path.join(directory, runtimeRoot, `${relativePath}${extension}`);\n if (fs.existsSync(candidate)) return candidate;\n const parent = path.dirname(directory);\n if (parent === directory) throw new Error(`Could not resolve runtime extension ${relativePath}`);\n directory = parent;\n }\n}\n\nexport interface BuildPiArgsInput {\n parentSessionId?: string;\n baseArgs: string[];\n task: string;\n sessionEnabled: boolean;\n sessionDir?: string;\n sessionFile?: string;\n model?: string;\n thinking?: string | false;\n systemPromptMode?: 'append' | 'replace';\n inheritProjectContext: boolean;\n inheritSkills: boolean;\n requireReadTool?: boolean;\n tools?: string[];\n excludeTools?: string[];\n extensions?: string[];\n subagentOnlyExtensions?: string[];\n systemPrompt?: string | null;\n mcpDirectTools?: string[];\n cwd?: string;\n promptFileStem?: string;\n intercomSessionName?: string;\n runId?: string;\n childAgentName?: string;\n childIndex?: number;\n parentEventSink?: string;\n parentControlInbox?: string;\n parentRootRunId?: string;\n parentRunId?: string;\n parentChildIndex?: number;\n parentDepth?: number;\n parentPath?: NestedPathEntry[];\n parentCapabilityToken?: string;\n steerInboxDir?: string;\n steerCapabilityPath?: string;\n steerAckDir?: string;\n structuredOutput?: {\n schema: JsonSchemaObject;\n schemaPath: string;\n outputPath: string;\n };\n toolBudget?: ResolvedToolBudget;\n allowZeroToolBudget?: boolean;\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n teamMember?: TeamMemberContext;\n teamToolEnabled?: boolean;\n}\n\nexport interface BuildPiArgsResult {\n args: string[];\n env: Record<string, string | undefined>;\n sdk: PiSdkLaunchSettings;\n tempDir?: string;\n toolDiagnosticPath?: string;\n capabilityAudit?: SubagentCapabilityAudit;\n}\n\nexport interface PiSdkLaunchSettings {\n model?: string;\n tools?: string[];\n noTools?: 'all';\n excludeTools?: string[];\n extensions: string[];\n noAmbientExtensions: boolean;\n skillPaths: string[];\n noSkills: boolean;\n noContextFiles: boolean;\n sessionEnabled: boolean;\n sessionDir?: string;\n sessionFile?: string;\n systemPrompt?: string;\n systemPromptMode?: 'append' | 'replace';\n}\n\nfunction inheritedDoomPiExtensions(environment: NodeJS.ProcessEnv = process.env): string[] {\n const raw = environment[DOOMPI_CHILD_EXTENSIONS_ENV];\n if (!raw) return [];\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n const detail = error instanceof Error ? ` ${error.message}` : '';\n throw new Error(`${DOOMPI_CHILD_EXTENSIONS_ENV} must be valid JSON.${detail}`);\n }\n if (!Array.isArray(parsed) || !parsed.every((value) => typeof value === 'string')) {\n throw new Error(`${DOOMPI_CHILD_EXTENSIONS_ENV} must be a JSON array of extension paths.`);\n }\n return parsed;\n}\n\nfunction inheritedDoomPiSkillPaths(environment: NodeJS.ProcessEnv = process.env): string[] {\n const raw = environment[DOOMPI_SKILL_DIRS_ENV];\n return raw ? raw.split(path.delimiter).filter(Boolean) : [];\n}\n\n/**\n * Append a thinking level to a model id.\n *\n * A model id that already carries a known level is left alone unless the caller\n * asks to replace it, so an explicit per-agent choice survives an inherited one.\n */\nexport function applyThinkingSuffix(\n model: string | undefined,\n thinking: string | false | undefined,\n replaceExisting = false,\n): string | undefined {\n if (!model || !thinking) return model;\n const colonIdx = model.lastIndexOf(':');\n if (colonIdx !== -1 && THINKING_LEVELS.some((level) => level === model.substring(colonIdx + 1))) {\n return replaceExisting ? `${model.slice(0, colonIdx)}:${thinking}` : model;\n }\n return `${model}:${thinking}`;\n}\n\nexport interface ResolvePiLaunchToolPlanInput {\n tools?: string[];\n extensions?: string[];\n subagentOnlyExtensions?: string[];\n mcpDirectTools?: string[];\n cwd?: string;\n requireReadTool?: boolean;\n excludeTools?: string[];\n structuredOutput?: boolean;\n teamToolEnabled?: boolean;\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n inheritedCapabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n}\n\nexport interface PiLaunchToolPlan {\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n excludedTools: string[];\n requestedBuiltinTools: string[];\n declaredBuiltinTools: string[];\n toolExtensionPaths: string[];\n resolvedMcpSelections: ResolvedMcpDirectToolSelection[];\n effectiveMcpSelections: ResolvedMcpDirectToolSelection[];\n effectiveMcpTools: string[];\n explicitToolAllowlist: boolean;\n internalTools: string[];\n effectiveToolAllowlist: string[];\n requiredChildTools: string[];\n fanoutAuthorized: boolean;\n runtimeExtensions: string[];\n configuredExtensions: string[];\n extensionArgs: string[];\n disableAmbientExtensions: boolean;\n capabilityAudit?: SubagentCapabilityAudit;\n}\n\nexport interface ResolvePiSdkResourcePlanInput extends ResolvePiLaunchToolPlanInput {\n inheritSkills: boolean;\n environment?: NodeJS.ProcessEnv;\n}\n\n/** The resource-only subset of Pi SDK settings, safe to calculate without writing launch files. */\nexport interface PiSdkResourcePlan {\n toolPlan: PiLaunchToolPlan;\n tools?: string[];\n noTools?: 'all';\n excludeTools?: string[];\n extensions: string[];\n noAmbientExtensions: boolean;\n skillPaths: string[];\n noSkills: boolean;\n}\n\n/** A tool entry is an extension path, not a builtin name, when it looks like a path. */\nfunction isToolExtensionPath(tool: string): boolean {\n return tool.includes('/') || tool.endsWith(TYPESCRIPT_EXTENSION) || tool.endsWith(JAVASCRIPT_EXTENSION);\n}\n\n/**\n * Decide exactly what the child may call.\n *\n * This is the security boundary. The order matters: the ceiling is computed\n * first, and every later step filters against it. `requireReadTool` can add\n * `read` to a nonempty caller request only when no ceiling is in force. A\n * ceiling or explicit effective allowlist that omits `read` is refused rather\n * than widened.\n */\nexport function resolvePiLaunchToolPlan(input: ResolvePiLaunchToolPlanInput): PiLaunchToolPlan {\n const capabilityCeiling = intersectSubagentCapabilityCeilings(\n input.capabilityCeiling,\n input.inheritedCapabilityCeiling,\n );\n const allowedToolSet =\n capabilityCeiling?.allowedTools === undefined ? undefined : new Set(capabilityCeiling.allowedTools);\n const allowedBuiltinTools = capabilityCeiling?.allowedTools?.filter(\n (tool) => !(capabilityCeiling.allowMcpTools === true && tool === MCP_TOOL_NAME),\n );\n const excludedTools = [\n ...new Set((input.excludeTools ?? []).map((tool) => tool.trim()).filter((tool) => tool.length > 0)),\n ];\n const excludedToolSet = new Set(excludedTools);\n const policyRequiredTools = capabilityCeiling?.requiredTools ?? [];\n const mcpToolsAllowed = capabilityCeiling?.allowMcpTools === true;\n const mcpRequested = mcpToolsAllowed && [...(input.tools ?? []), ...policyRequiredTools].includes(MCP_TOOL_NAME);\n const requestedBuiltinTools = [...new Set([...(input.tools ?? []), ...policyRequiredTools])].filter(\n (tool) => !isToolExtensionPath(tool) && !(mcpRequested && tool === MCP_TOOL_NAME),\n );\n const requestedMcpSelectors = [...(input.mcpDirectTools ?? []), ...(mcpRequested ? [ALL_MCP_SERVERS_SELECTOR] : [])];\n if (input.requireReadTool && excludedToolSet.has(READ_TOOL_NAME)) {\n throw new Error(`Child tool exclusions exclude required tool '${READ_TOOL_NAME}' for lazy skill loading.`);\n }\n if (input.structuredOutput && excludedToolSet.has(STRUCTURED_OUTPUT_TOOL_NAME)) {\n throw new Error(`Child tool exclusions exclude required tool '${STRUCTURED_OUTPUT_TOOL_NAME}'.`);\n }\n if (input.requireReadTool && allowedToolSet && !allowedToolSet.has(READ_TOOL_NAME)) {\n throw new Error(\n `Capability ceiling from ${capabilityCeiling?.sources.join(', ') || 'unknown source'} excludes required tool '${READ_TOOL_NAME}' for lazy skill loading.`,\n );\n }\n // No `tools` at all means \"whatever the host allows\", which under a ceiling\n // becomes exactly the ceiling and without one stays unconstrained.\n const declaredBuiltinTools =\n input.tools === undefined\n ? (allowedBuiltinTools ?? [])\n : (input.requireReadTool &&\n requestedBuiltinTools.length > 0 &&\n !requestedBuiltinTools.includes(READ_TOOL_NAME) &&\n !allowedToolSet\n ? [READ_TOOL_NAME, ...requestedBuiltinTools]\n : requestedBuiltinTools\n )\n .filter((tool) => !allowedToolSet || allowedToolSet.has(tool))\n .filter((tool) => !excludedToolSet.has(tool));\n // Fan-out authority is exactly \"was granted the subagent tool\", read after\n // ceiling filtering so a denied tool cannot confer it.\n const fanoutAuthorized = declaredBuiltinTools.includes(SUBAGENT_TOOL_NAME);\n const toolExtensionPaths: string[] = capabilityCeiling?.denyExtensions\n ? []\n : (input.tools ?? []).filter((tool) => !requestedBuiltinTools.includes(tool) && isToolExtensionPath(tool));\n const resolvedMcpSelections = capabilityCeiling?.denyExtensions\n ? []\n : resolveMcpDirectToolSelections(requestedMcpSelectors, input.cwd);\n const effectiveMcpSelections = resolvedMcpSelections.filter(\n (selection) =>\n (mcpToolsAllowed || !allowedToolSet || allowedToolSet.has(selection.name)) &&\n !excludedToolSet.has(selection.name),\n );\n const effectiveMcpTools = effectiveMcpSelections.map((selection) => selection.name);\n const explicitToolAllowlist =\n input.tools !== undefined || requestedMcpSelectors.length > 0 || allowedToolSet !== undefined;\n // Internal tools are ours, not the caller's, so they bypass the allowlist but\n // are still reported in the audit.\n const internalTools = [\n ...(input.structuredOutput ? [STRUCTURED_OUTPUT_TOOL_NAME] : []),\n ...(input.teamToolEnabled ? [NATIVE_TEAM_TOOL_NAME] : []),\n ].filter((tool) => !excludedToolSet.has(tool));\n const effectiveToolAllowlist = [...new Set([...declaredBuiltinTools, ...effectiveMcpTools, ...internalTools])];\n if (input.requireReadTool && explicitToolAllowlist && !effectiveToolAllowlist.includes(READ_TOOL_NAME)) {\n throw new Error(\n `Effective child tool allowlist excludes required tool '${READ_TOOL_NAME}' for lazy skill loading.`,\n );\n }\n const requiredChildTools = explicitToolAllowlist\n ? [\n ...new Set([\n ...(input.tools !== undefined ? declaredBuiltinTools : []),\n ...(requestedMcpSelectors.length ? effectiveMcpTools : []),\n ...internalTools,\n ]),\n ]\n : [];\n const runtimeExtensions = fanoutAuthorized\n ? [\n resolveRuntimeExtensionPath(PROMPT_RUNTIME_EXTENSION, PROMPT_RUNTIME_SOURCE_EXTENSION),\n resolveRuntimeExtensionPath(FANOUT_CHILD_EXTENSION),\n ]\n : [resolveRuntimeExtensionPath(PROMPT_RUNTIME_EXTENSION, PROMPT_RUNTIME_SOURCE_EXTENSION)];\n const disableAmbientExtensions = capabilityCeiling?.denyExtensions === true || input.extensions !== undefined;\n const configuredExtensions = capabilityCeiling?.denyExtensions\n ? []\n : [...toolExtensionPaths, ...(input.extensions ?? []), ...(input.subagentOnlyExtensions ?? [])];\n const extensionArgs = disableAmbientExtensions\n ? [...new Set([...runtimeExtensions, ...configuredExtensions])]\n : [...new Set([...runtimeExtensions, ...toolExtensionPaths, ...(input.subagentOnlyExtensions ?? [])])];\n const requestedToolNames =\n input.tools !== undefined\n ? [...new Set([...requestedBuiltinTools, ...resolvedMcpSelections.map((selection) => selection.name)])]\n : undefined;\n const capabilityAudit = capabilityCeiling\n ? ({\n ceiling: capabilityCeiling,\n ...(requestedToolNames ? { requestedTools: requestedToolNames } : {}),\n effectiveTools: effectiveToolAllowlist,\n removedTools: requestedToolNames?.filter((tool) => !effectiveToolAllowlist.includes(tool)) ?? [],\n internalTools,\n extensionsDenied: capabilityCeiling.denyExtensions,\n removedExtensionCount: capabilityCeiling.denyExtensions\n ? (input.extensions?.length ?? 0) +\n (input.subagentOnlyExtensions?.length ?? 0) +\n (input.tools ?? []).filter(isToolExtensionPath).length\n : 0,\n requestedMcpToolCount: requestedMcpSelectors.length,\n effectiveMcpTools,\n } satisfies SubagentCapabilityAudit)\n : undefined;\n return {\n ...(capabilityCeiling ? { capabilityCeiling } : {}),\n excludedTools,\n requestedBuiltinTools,\n declaredBuiltinTools,\n toolExtensionPaths,\n resolvedMcpSelections,\n effectiveMcpSelections,\n effectiveMcpTools,\n explicitToolAllowlist,\n internalTools,\n effectiveToolAllowlist,\n requiredChildTools,\n fanoutAuthorized,\n runtimeExtensions,\n configuredExtensions,\n extensionArgs,\n disableAmbientExtensions,\n ...(capabilityAudit ? { capabilityAudit } : {}),\n };\n}\n\n/**\n * Resolve the child SDK's resource settings without creating launch files or\n * starting a child process. Filesystem-backed MCP and runtime-extension lookup\n * still follows the same path as a real launch.\n */\nexport function resolvePiSdkResourcePlan(input: ResolvePiSdkResourcePlanInput): PiSdkResourcePlan {\n const environment = input.environment ?? process.env;\n const inheritedCapabilityCeiling = intersectSubagentCapabilityCeilings(\n input.inheritedCapabilityCeiling,\n decodeSubagentCapabilityCeiling(environment[SUBAGENT_CAPABILITY_CEILING_ENV]),\n );\n const toolPlan = resolvePiLaunchToolPlan({\n tools: input.tools,\n extensions: input.extensions,\n subagentOnlyExtensions: input.subagentOnlyExtensions,\n mcpDirectTools: input.mcpDirectTools,\n cwd: input.cwd,\n requireReadTool: input.requireReadTool,\n excludeTools: input.excludeTools,\n structuredOutput: input.structuredOutput,\n teamToolEnabled: input.teamToolEnabled,\n capabilityCeiling: input.capabilityCeiling,\n inheritedCapabilityCeiling,\n });\n const explicitTools = toolPlan.explicitToolAllowlist ? toolPlan.effectiveToolAllowlist : undefined;\n return {\n toolPlan,\n ...(explicitTools && explicitTools.length > 0 ? { tools: explicitTools } : {}),\n ...(explicitTools?.length === 0 ? { noTools: 'all' as const } : {}),\n ...(toolPlan.excludedTools.length > 0 ? { excludeTools: toolPlan.excludedTools } : {}),\n extensions: [...new Set([...inheritedDoomPiExtensions(environment), ...toolPlan.extensionArgs])],\n noAmbientExtensions: toolPlan.disableAmbientExtensions,\n skillPaths: input.inheritSkills ? inheritedDoomPiSkillPaths(environment) : [],\n noSkills: !input.inheritSkills,\n };\n}\n\n/**\n * Scratch directory for this launch's prompt, task and diagnostics.\n *\n * Created 0700 under the per-user temp root, because the files inside carry the\n * full task and system prompt.\n */\nfunction createLaunchTempDir(): string {\n fs.mkdirSync(currentChildLaunchTempDir(), { recursive: true, mode: PRIVATE_DIR_MODE });\n return fs.mkdtempSync(path.join(currentChildLaunchTempDir(), TEMP_DIRECTORY_PREFIX));\n}\n\nexport function buildPiArgs(input: BuildPiArgsInput): BuildPiArgsResult {\n const args = [...input.baseArgs];\n\n if (input.sessionFile) {\n fs.mkdirSync(path.dirname(input.sessionFile), { recursive: true });\n args.push(SESSION_FLAG, input.sessionFile);\n } else {\n if (!input.sessionEnabled) {\n args.push(NO_SESSION_FLAG);\n }\n if (input.sessionDir) {\n fs.mkdirSync(input.sessionDir, { recursive: true });\n args.push(SESSION_DIRECTORY_FLAG, input.sessionDir);\n }\n }\n\n const modelArg = applyThinkingSuffix(input.model, input.thinking);\n if (modelArg) {\n args.push(MODEL_FLAG, modelArg);\n }\n\n const resourcePlan = resolvePiSdkResourcePlan({\n tools: input.tools,\n extensions: input.extensions,\n subagentOnlyExtensions: input.subagentOnlyExtensions,\n mcpDirectTools: input.mcpDirectTools,\n cwd: input.cwd,\n requireReadTool: input.requireReadTool,\n excludeTools: input.excludeTools,\n structuredOutput: Boolean(input.structuredOutput),\n teamToolEnabled: Boolean(input.teamMember) || input.teamToolEnabled === true,\n capabilityCeiling: input.capabilityCeiling,\n inheritSkills: input.inheritSkills,\n });\n const { toolPlan, ...sdkResources } = resourcePlan;\n if (toolPlan.explicitToolAllowlist) {\n // An empty allowlist means no tools at all, which is a different flag rather\n // than an empty `--tools` value.\n args.push(toolPlan.effectiveToolAllowlist.length > 0 ? TOOLS_FLAG : NO_TOOLS_FLAG);\n if (toolPlan.effectiveToolAllowlist.length > 0) args.push(toolPlan.effectiveToolAllowlist.join(','));\n }\n if (toolPlan.excludedTools.length > 0) {\n args.push(EXCLUDE_TOOLS_FLAG, toolPlan.excludedTools.join(','));\n }\n if (toolPlan.disableAmbientExtensions) {\n args.push(NO_EXTENSIONS_FLAG);\n }\n for (const extPath of toolPlan.extensionArgs) args.push(EXTENSION_FLAG, extPath);\n\n if (!input.inheritProjectContext) {\n args.push(NO_CONTEXT_FILES_FLAG);\n }\n if (!input.inheritSkills) {\n args.push(NO_SKILLS_FLAG);\n }\n\n let tempDir: string | undefined;\n const ensureTempDir = (): string => {\n tempDir ??= createLaunchTempDir();\n return tempDir;\n };\n\n if (input.systemPrompt !== undefined && input.systemPrompt !== null) {\n const stem = (input.promptFileStem ?? DEFAULT_PROMPT_FILE_STEM).replace(UNSAFE_PROMPT_STEM_CHARACTERS, '_');\n const promptPath = path.join(ensureTempDir(), `${stem}${PROMPT_FILE_EXTENSION}`);\n fs.writeFileSync(promptPath, input.systemPrompt, { mode: PRIVATE_FILE_MODE });\n args.push(input.systemPromptMode === 'replace' ? SYSTEM_PROMPT_FLAG : APPEND_SYSTEM_PROMPT_FLAG, promptPath);\n }\n\n if (input.task.length > TASK_ARG_LIMIT) {\n const taskFilePath = path.join(ensureTempDir(), TASK_FILE_NAME);\n fs.writeFileSync(taskFilePath, `${TASK_PREFIX}${input.task}`, { mode: PRIVATE_FILE_MODE });\n args.push(`@${taskFilePath}`);\n } else {\n args.push(`${TASK_PREFIX}${input.task}`);\n }\n\n // Team membership vars are always written: the clearing form blanks whatever\n // this process inherited so a non-team child cannot join its parent's team.\n const env: Record<string, string | undefined> = {\n ...(input.teamMember ? nativeTeamMemberEnvironment(input.teamMember) : clearNativeTeamMemberEnvironment()),\n };\n const piPackageRoot = process.env[PI_CODING_AGENT_PACKAGE_ROOT_ENV] ?? resolvePiPackageRoot();\n if (piPackageRoot) env[PI_CODING_AGENT_PACKAGE_ROOT_ENV] = piPackageRoot;\n let toolDiagnosticPath: string | undefined;\n if (toolPlan.requiredChildTools.length > 0) {\n toolDiagnosticPath = path.join(ensureTempDir(), TOOL_DIAGNOSTIC_FILE_NAME);\n env[REQUIRED_CHILD_TOOLS_ENV] = JSON.stringify(toolPlan.requiredChildTools);\n env[CHILD_TOOL_DIAGNOSTIC_PATH_ENV] = toolDiagnosticPath;\n }\n env[MCP_DIRECT_CHILD_TOOLS_ENV] =\n toolPlan.effectiveMcpTools.length > 0 ? JSON.stringify(toolPlan.effectiveMcpTools) : undefined;\n env[SUBAGENT_CHILD_ENV] = ENABLED_ENV_VALUE;\n env[SUBAGENT_FANOUT_CHILD_ENV] = toolPlan.fanoutAuthorized ? ENABLED_ENV_VALUE : DISABLED_ENV_VALUE;\n // We are ourselves a nested child only if our parent granted us the full\n // fan-out route; a partial set of inherited vars is not trusted.\n const inheritedNestedRoute = Boolean(\n process.env[SUBAGENT_PARENT_EVENT_SINK_ENV] &&\n process.env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] &&\n process.env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV],\n );\n const parentRunId =\n input.parentRunId ??\n input.runId ??\n (inheritedNestedRoute ? process.env[SUBAGENT_RUN_ID_ENV] : undefined) ??\n process.env[SUBAGENT_PARENT_RUN_ID_ENV] ??\n '';\n const parentChildIndex =\n input.parentChildIndex !== undefined\n ? String(input.parentChildIndex)\n : input.childIndex !== undefined\n ? String(input.childIndex)\n : (process.env[SUBAGENT_PARENT_CHILD_INDEX_ENV] ?? '');\n const inheritedDepth = Number(process.env[SUBAGENT_PARENT_DEPTH_ENV]);\n const parentDepth =\n input.parentDepth ??\n (inheritedNestedRoute && Number.isFinite(inheritedDepth) ? inheritedDepth + 1 : ROOT_FANOUT_DEPTH);\n const parentPath = input.parentPath ?? [\n ...parseNestedPathEnv(process.env[SUBAGENT_PARENT_PATH_ENV]),\n ...(parentRunId\n ? [\n {\n runId: parentRunId,\n ...(parentChildIndex && DIGITS_ONLY.test(parentChildIndex) ? { stepIndex: Number(parentChildIndex) } : {}),\n ...(input.childAgentName ? { agent: input.childAgentName } : {}),\n },\n ]\n : []),\n ];\n // Blanked rather than omitted when fan-out is not authorized: an omitted key\n // would let the child inherit this process's own value.\n env[SUBAGENT_PARENT_EVENT_SINK_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentEventSink ?? process.env[SUBAGENT_PARENT_EVENT_SINK_ENV] ?? '')\n : '';\n env[SUBAGENT_PARENT_CONTROL_INBOX_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentControlInbox ?? process.env[SUBAGENT_PARENT_CONTROL_INBOX_ENV] ?? '')\n : '';\n env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentRootRunId ?? process.env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] ?? input.runId ?? '')\n : '';\n env[SUBAGENT_PARENT_RUN_ID_ENV] = toolPlan.fanoutAuthorized ? parentRunId : '';\n env[SUBAGENT_PARENT_CHILD_INDEX_ENV] = toolPlan.fanoutAuthorized ? parentChildIndex : '';\n env[SUBAGENT_PARENT_DEPTH_ENV] = toolPlan.fanoutAuthorized ? String(parentDepth) : '';\n env[SUBAGENT_PARENT_PATH_ENV] = toolPlan.fanoutAuthorized ? encodeNestedPathEnv(parentPath) : '';\n env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentCapabilityToken ?? process.env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV] ?? '')\n : '';\n env[INHERIT_PROJECT_CONTEXT_ENV] = input.inheritProjectContext ? ENABLED_ENV_VALUE : DISABLED_ENV_VALUE;\n env[INHERIT_SKILLS_ENV] = input.inheritSkills ? ENABLED_ENV_VALUE : DISABLED_ENV_VALUE;\n env[PI_INTERCOM_STABLE_ID_ENV] = input.intercomSessionName || undefined;\n // Cleared unconditionally: an inherited session id would make the child adopt\n // its parent's intercom identity.\n env[PI_INTERCOM_SESSION_ID_ENV] = undefined;\n if (input.intercomSessionName) {\n env[SUBAGENT_INTERCOM_SESSION_NAME_ENV] = input.intercomSessionName;\n }\n if (input.runId) {\n env[SUBAGENT_RUN_ID_ENV] = input.runId;\n }\n if (input.childAgentName) {\n env[SUBAGENT_CHILD_AGENT_ENV] = input.childAgentName;\n }\n if (input.childIndex !== undefined) {\n env[SUBAGENT_CHILD_INDEX_ENV] = String(input.childIndex);\n }\n // The Pi host reads its own selector list from this var. Without a ceiling the\n // caller's selectors pass through; with one, only the selectors that survived\n // filtering do, and anything else resolves to the explicit \"none\" sentinel.\n if (!toolPlan.capabilityCeiling && input.mcpDirectTools?.length)\n env[MCP_DIRECT_TOOLS_ENV] = input.mcpDirectTools.join(',');\n else if (\n toolPlan.capabilityCeiling &&\n toolPlan.effectiveMcpSelections.length &&\n !toolPlan.capabilityCeiling.denyExtensions\n )\n env[MCP_DIRECT_TOOLS_ENV] = toolPlan.effectiveMcpSelections.map((selection) => selection.selector).join(',');\n else env[MCP_DIRECT_TOOLS_ENV] = NO_MCP_DIRECT_TOOLS;\n const encodedCapabilityCeiling = encodeSubagentCapabilityCeiling(toolPlan.capabilityCeiling);\n if (encodedCapabilityCeiling) env[SUBAGENT_CAPABILITY_CEILING_ENV] = encodedCapabilityCeiling;\n if (input.structuredOutput) {\n env[STRUCTURED_OUTPUT_CAPTURE_ENV] = input.structuredOutput.outputPath;\n env[STRUCTURED_OUTPUT_SCHEMA_ENV] = input.structuredOutput.schemaPath;\n }\n if (input.steerInboxDir) {\n env[SUBAGENT_STEER_INBOX_ENV] = input.steerInboxDir;\n }\n if (input.steerCapabilityPath) env[SUBAGENT_STEER_CAPABILITY_ENV] = input.steerCapabilityPath;\n if (input.steerAckDir) env[SUBAGENT_STEER_ACK_DIR_ENV] = input.steerAckDir;\n const encodedToolBudget = encodeToolBudgetEnv(input.toolBudget);\n if (encodedToolBudget) env[TOOL_BUDGET_ENV] = encodedToolBudget;\n env[TOOL_BUDGET_ZERO_AUTH_ENV] = input.allowZeroToolBudget ? ENABLED_ENV_VALUE : undefined;\n env[SUBAGENT_PARENT_SESSION_ENV] = input.parentSessionId ?? process.env[SUBAGENT_PARENT_SESSION_ENV] ?? '';\n env[DOOM_CHILD_PROCESS_CONTEXT_ENV] = input.parentSessionId\n ? encodeChildProcessContext({\n parentSessionId: input.parentSessionId,\n workingDirectory: input.cwd ?? process.cwd(),\n ...(input.childAgentName ? { mode: input.childAgentName } : {}),\n })\n : undefined;\n\n const sdk: PiSdkLaunchSettings = {\n ...(input.model || input.thinking ? { model: applyThinkingSuffix(input.model, input.thinking) } : {}),\n ...sdkResources,\n noContextFiles: !input.inheritProjectContext,\n sessionEnabled: input.sessionEnabled,\n ...(input.sessionDir ? { sessionDir: input.sessionDir } : {}),\n ...(input.sessionFile ? { sessionFile: input.sessionFile } : {}),\n ...(input.systemPrompt !== undefined && input.systemPrompt !== null ? { systemPrompt: input.systemPrompt } : {}),\n ...(input.systemPromptMode ? { systemPromptMode: input.systemPromptMode } : {}),\n };\n\n return { args, env, sdk, tempDir, toolDiagnosticPath, capabilityAudit: toolPlan.capabilityAudit };\n}\n\nexport const parseParentPathEnv = parseNestedPathEnv;\n\nexport function cleanupTempDir(tempDir: string | null | undefined): boolean {\n if (!tempDir) return true;\n try {\n fs.rmSync(tempDir, { recursive: true, force: true });\n return true;\n } catch {\n // The child may still hold the prompt file open. Reporting false lets the\n // caller record the leak; throwing would fail a run that already succeeded.\n return false;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import{CHILD_TOOL_DIAGNOSTIC_PATH_ENV as t,DOOMPI_CHILD_EXTENSIONS_ENV as n,DOOMPI_SKILL_DIRS_ENV as r,INHERIT_PROJECT_CONTEXT_ENV as i,INHERIT_SKILLS_ENV as a,MCP_DIRECT_CHILD_TOOLS_ENV as o,MCP_DIRECT_TOOLS_ENV as s,PI_CODING_AGENT_PACKAGE_ROOT_ENV as c,PI_INTERCOM_SESSION_ID_ENV as l,PI_INTERCOM_STABLE_ID_ENV as u,REQUIRED_CHILD_TOOLS_ENV as d,STRUCTURED_OUTPUT_CAPTURE_ENV as f,STRUCTURED_OUTPUT_SCHEMA_ENV as p,SUBAGENT_CAPABILITY_CEILING_ENV as m,SUBAGENT_CHILD_AGENT_ENV as h,SUBAGENT_CHILD_ENV as g,SUBAGENT_CHILD_INDEX_ENV as _,SUBAGENT_FANOUT_CHILD_ENV as v,SUBAGENT_INTERCOM_SESSION_NAME_ENV as y,SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV as ee,SUBAGENT_PARENT_CHILD_INDEX_ENV as b,SUBAGENT_PARENT_CONTROL_INBOX_ENV as x,SUBAGENT_PARENT_DEPTH_ENV as S,SUBAGENT_PARENT_EVENT_SINK_ENV as te,SUBAGENT_PARENT_PATH_ENV as C,SUBAGENT_PARENT_ROOT_RUN_ID_ENV as w,SUBAGENT_PARENT_RUN_ID_ENV as ne,SUBAGENT_PARENT_SESSION_ENV as re,SUBAGENT_RUN_ID_ENV as ie,SUBAGENT_STEER_ACK_DIR_ENV as ae,SUBAGENT_STEER_CAPABILITY_ENV as oe,SUBAGENT_STEER_INBOX_ENV as se,TOOL_BUDGET_ENV as ce,TOOL_BUDGET_ZERO_AUTH_ENV as le,init_env as T}from"../../env.mjs";import{decodeSubagentCapabilityCeiling as ue,encodeSubagentCapabilityCeiling as de,init_capabilityCeiling as E,intersectSubagentCapabilityCeilings as D}from"../../protocol/capabilityCeiling.mjs";import{currentChildLaunchTempDir as O,init_paths as k}from"../../shared/paths.mjs";import{THINKING_LEVELS as A,init_modelInfo as j}from"../../shared/modelInfo.mjs";import{NATIVE_TEAM_TOOL_NAME as M,clearNativeTeamMemberEnvironment as fe,init_nativeTeamChannel as N,nativeTeamMemberEnvironment as pe}from"../../intercom/nativeTeamChannel.mjs";import{init_mcpDirectToolAllowlist as P,resolveMcpDirectToolSelections as me}from"./mcpDirectToolAllowlist.mjs";import{encodeNestedPathEnv as he,init_nestedPath as ge,parseNestedPathEnv as _e}from"./nestedPath.mjs";import{init_piSpawn as F,resolvePiPackageRoot as ve}from"./piSpawn.mjs";import{encodeToolBudgetEnv as ye,init_toolBudget as I}from"./toolBudget.mjs";import*as L from"node:fs";import*as R from"node:path";import{DOOM_CHILD_PROCESS_CONTEXT_ENV as be,encodeChildProcessContext as xe}from"@agimon-ai/doompi-extension-contracts/child-process";import{fileURLToPath as Se}from"node:url";function z(e,t=H){let n=Se(import.meta.url),r=n.split(R.sep).includes(X),i=r?X:nt,a=r?rt:t,o=R.dirname(n);for(;;){let t=R.join(o,i,`${e}${a}`);if(L.existsSync(t))return t;let n=R.dirname(o);if(n===o)throw Error(`Could not resolve runtime extension ${e}`);o=n}}function Ce(e=process.env){let t=e[n];if(!t)return[];let r;try{r=JSON.parse(t)}catch(e){let t=e instanceof Error?` ${e.message}`:``;throw Error(`${n} must be valid JSON.${t}`)}if(!Array.isArray(r)||!r.every(e=>typeof e==`string`))throw Error(`${n} must be a JSON array of extension paths.`);return r}function we(e=process.env){let t=e[r];return t?t.split(R.delimiter).filter(Boolean):[]}function Te(e,t,n=!1){if(!e||!t)return e;let r=e.lastIndexOf(`:`);return r!==-1&&A.some(t=>t===e.substring(r+1))?n?`${e.slice(0,r)}:${t}`:e:`${e}:${t}`}function B(e){return e.includes(`/`)||e.endsWith(H)||e.endsWith(Me)}function Ee(e){let t=D(e.capabilityCeiling,e.inheritedCapabilityCeiling),n=t?.allowedTools===void 0?void 0:new Set(t.allowedTools),r=t?.allowedTools?.filter(e=>!(t.allowMcpTools===!0&&e===W)),i=[...new Set((e.excludeTools??[]).map(e=>e.trim()).filter(e=>e.length>0))],a=new Set(i),o=t?.requiredTools??[],s=t?.allowMcpTools===!0,c=s&&[...e.tools??[],...o].includes(W),l=[...new Set([...e.tools??[],...o])].filter(e=>!B(e)&&!(c&&e===W)),u=[...e.mcpDirectTools??[],...c?[Le]:[]];if(e.requireReadTool&&a.has(U))throw Error(`Child tool exclusions exclude required tool '${U}' for lazy skill loading.`);if(e.structuredOutput&&a.has(G))throw Error(`Child tool exclusions exclude required tool '${G}'.`);if(e.requireReadTool&&n&&!n.has(U))throw Error(`Capability ceiling from ${t?.sources.join(`, `)||`unknown source`} excludes required tool '${U}' for lazy skill loading.`);let d=e.tools===void 0?r??[]:(e.requireReadTool&&l.length>0&&!l.includes(U)&&!n?[U,...l]:l).filter(e=>!n||n.has(e)).filter(e=>!a.has(e)),f=d.includes(Re),p=t?.denyExtensions?[]:(e.tools??[]).filter(e=>!l.includes(e)&&B(e)),m=t?.denyExtensions?[]:me(u,e.cwd),h=m.filter(e=>(s||!n||n.has(e.name))&&!a.has(e.name)),g=h.map(e=>e.name),_=e.tools!==void 0||u.length>0||n!==void 0,v=[...e.structuredOutput?[G]:[],...e.teamToolEnabled?[M]:[]].filter(e=>!a.has(e)),y=[...new Set([...d,...g,...v])];if(e.requireReadTool&&_&&!y.includes(U))throw Error(`Effective child tool allowlist excludes required tool '${U}' for lazy skill loading.`);let ee=_?[...new Set([...e.tools===void 0?[]:d,...u.length?g:[],...v])]:[],b=f?[z(Z,Q),z(it)]:[z(Z,Q)],x=t?.denyExtensions===!0||e.extensions!==void 0,S=t?.denyExtensions?[]:[...p,...e.extensions??[],...e.subagentOnlyExtensions??[]],te=x?[...new Set([...b,...S])]:[...new Set([...b,...p,...e.subagentOnlyExtensions??[]])],C=e.tools===void 0?void 0:[...new Set([...l,...m.map(e=>e.name)])],w=t?{ceiling:t,...C?{requestedTools:C}:{},effectiveTools:y,removedTools:C?.filter(e=>!y.includes(e))??[],internalTools:v,extensionsDenied:t.denyExtensions,removedExtensionCount:t.denyExtensions?(e.extensions?.length??0)+(e.subagentOnlyExtensions?.length??0)+(e.tools??[]).filter(B).length:0,requestedMcpToolCount:u.length,effectiveMcpTools:g}:void 0;return{...t?{capabilityCeiling:t}:{},excludedTools:i,requestedBuiltinTools:l,declaredBuiltinTools:d,toolExtensionPaths:p,resolvedMcpSelections:m,effectiveMcpSelections:h,effectiveMcpTools:g,explicitToolAllowlist:_,internalTools:v,effectiveToolAllowlist:y,requiredChildTools:ee,fanoutAuthorized:f,runtimeExtensions:b,configuredExtensions:S,extensionArgs:te,disableAmbientExtensions:x,...w?{capabilityAudit:w}:{}}}function De(e){let t=e.environment??process.env,n=D(e.inheritedCapabilityCeiling,ue(t[m])),r=Ee({tools:e.tools,extensions:e.extensions,subagentOnlyExtensions:e.subagentOnlyExtensions,mcpDirectTools:e.mcpDirectTools,cwd:e.cwd,requireReadTool:e.requireReadTool,excludeTools:e.excludeTools,structuredOutput:e.structuredOutput,teamToolEnabled:e.teamToolEnabled,capabilityCeiling:e.capabilityCeiling,inheritedCapabilityCeiling:n}),i=r.explicitToolAllowlist?r.effectiveToolAllowlist:void 0;return{toolPlan:r,...i&&i.length>0?{tools:i}:{},...i?.length===0?{noTools:`all`}:{},...r.excludedTools.length>0?{excludeTools:r.excludedTools}:{},extensions:[...new Set([...Ce(t),...r.extensionArgs])],noAmbientExtensions:r.disableAmbientExtensions,skillPaths:e.inheritSkills?we(t):[],noSkills:!e.inheritSkills}}function Oe(){return L.mkdirSync(O(),{recursive:!0,mode:Be}),L.mkdtempSync(R.join(O(),je))}function ke(e){let n=[...e.baseArgs];e.sessionFile?(L.mkdirSync(R.dirname(e.sessionFile),{recursive:!0}),n.push(We,e.sessionFile)):(e.sessionEnabled||n.push(Ge),e.sessionDir&&(L.mkdirSync(e.sessionDir,{recursive:!0}),n.push(Ke,e.sessionDir)));let r=Te(e.model,e.thinking);r&&n.push(qe,r);let{toolPlan:T,...ue}=De({tools:e.tools,extensions:e.extensions,subagentOnlyExtensions:e.subagentOnlyExtensions,mcpDirectTools:e.mcpDirectTools,cwd:e.cwd,requireReadTool:e.requireReadTool,excludeTools:e.excludeTools,structuredOutput:!!e.structuredOutput,teamToolEnabled:!!e.teamMember||e.teamToolEnabled===!0,capabilityCeiling:e.capabilityCeiling,inheritSkills:e.inheritSkills});T.explicitToolAllowlist&&(n.push(T.effectiveToolAllowlist.length>0?Je:Ye),T.effectiveToolAllowlist.length>0&&n.push(T.effectiveToolAllowlist.join(`,`))),T.excludedTools.length>0&&n.push(Xe,T.excludedTools.join(`,`)),T.disableAmbientExtensions&&n.push(Ze);for(let e of T.extensionArgs)n.push(Qe,e);e.inheritProjectContext||n.push(Y),e.inheritSkills||n.push($e);let E,D=()=>(E??=Oe(),E);if(e.systemPrompt!==void 0&&e.systemPrompt!==null){let t=(e.promptFileStem??Pe).replace(He,`_`),r=R.join(D(),`${t}${Ne}`);L.writeFileSync(r,e.systemPrompt,{mode:J}),n.push(e.systemPromptMode===`replace`?et:tt,r)}if(e.task.length>Ae){let t=R.join(D(),Fe);L.writeFileSync(t,`${V}${e.task}`,{mode:J}),n.push(`@${t}`)}else n.push(`${V}${e.task}`);let O={...e.teamMember?pe(e.teamMember):fe()},k=process.env.PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT??ve();k&&(O[c]=k);let A;T.requiredChildTools.length>0&&(A=R.join(D(),Ie),O[d]=JSON.stringify(T.requiredChildTools),O[t]=A),O[o]=T.effectiveMcpTools.length>0?JSON.stringify(T.effectiveMcpTools):void 0,O[g]=K,O[v]=T.fanoutAuthorized?K:q;let j=!!(process.env.PI_SUBAGENT_PARENT_EVENT_SINK&&process.env.PI_SUBAGENT_PARENT_ROOT_RUN_ID&&process.env.PI_SUBAGENT_PARENT_CAPABILITY_TOKEN),M=e.parentRunId??e.runId??(j?process.env.PI_SUBAGENT_RUN_ID:void 0)??process.env.PI_SUBAGENT_PARENT_RUN_ID??``,N=e.parentChildIndex===void 0?e.childIndex===void 0?process.env.PI_SUBAGENT_PARENT_CHILD_INDEX??``:String(e.childIndex):String(e.parentChildIndex),P=Number(process.env[S]),me=e.parentDepth??(j&&Number.isFinite(P)?P+1:Ve),ge=e.parentPath??[..._e(process.env.PI_SUBAGENT_PARENT_PATH),...M?[{runId:M,...N&&Ue.test(N)?{stepIndex:Number(N)}:{},...e.childAgentName?{agent:e.childAgentName}:{}}]:[]];O[te]=T.fanoutAuthorized?e.parentEventSink??process.env.PI_SUBAGENT_PARENT_EVENT_SINK??``:``,O[x]=T.fanoutAuthorized?e.parentControlInbox??process.env.PI_SUBAGENT_PARENT_CONTROL_INBOX??``:``,O[w]=T.fanoutAuthorized?e.parentRootRunId??process.env.PI_SUBAGENT_PARENT_ROOT_RUN_ID??e.runId??``:``,O[ne]=T.fanoutAuthorized?M:``,O[b]=T.fanoutAuthorized?N:``,O[S]=T.fanoutAuthorized?String(me):``,O[C]=T.fanoutAuthorized?he(ge):``,O[ee]=T.fanoutAuthorized?e.parentCapabilityToken??process.env.PI_SUBAGENT_PARENT_CAPABILITY_TOKEN??``:``,O[i]=e.inheritProjectContext?K:q,O[a]=e.inheritSkills?K:q,O[u]=e.intercomSessionName||void 0,O[l]=void 0,e.intercomSessionName&&(O[y]=e.intercomSessionName),e.runId&&(O[ie]=e.runId),e.childAgentName&&(O[h]=e.childAgentName),e.childIndex!==void 0&&(O[_]=String(e.childIndex)),!T.capabilityCeiling&&e.mcpDirectTools?.length?O[s]=e.mcpDirectTools.join(`,`):T.capabilityCeiling&&T.effectiveMcpSelections.length&&!T.capabilityCeiling.denyExtensions?O[s]=T.effectiveMcpSelections.map(e=>e.selector).join(`,`):O[s]=ze;let F=de(T.capabilityCeiling);F&&(O[m]=F),e.structuredOutput&&(O[f]=e.structuredOutput.outputPath,O[p]=e.structuredOutput.schemaPath),e.steerInboxDir&&(O[se]=e.steerInboxDir),e.steerCapabilityPath&&(O[oe]=e.steerCapabilityPath),e.steerAckDir&&(O[ae]=e.steerAckDir);let I=ye(e.toolBudget);return I&&(O[ce]=I),O[le]=e.allowZeroToolBudget?K:void 0,O[re]=e.parentSessionId??process.env[re]??``,O[be]=e.parentSessionId?xe({parentSessionId:e.parentSessionId,workingDirectory:e.cwd??process.cwd(),...e.childAgentName?{mode:e.childAgentName}:{}}):void 0,{args:n,env:O,sdk:{...e.model||e.thinking?{model:Te(e.model,e.thinking)}:{},...ue,noContextFiles:!e.inheritProjectContext,sessionEnabled:e.sessionEnabled,...e.sessionDir?{sessionDir:e.sessionDir}:{},...e.sessionFile?{sessionFile:e.sessionFile}:{},...e.systemPrompt!==void 0&&e.systemPrompt!==null?{systemPrompt:e.systemPrompt}:{},...e.systemPromptMode?{systemPromptMode:e.systemPromptMode}:{}},tempDir:E,toolDiagnosticPath:A,capabilityAudit:T.capabilityAudit}}var Ae,je,V,H,Me,Ne,Pe,Fe,Ie,U,W,Le,Re,G,ze,K,q,J,Be,Ve,He,Ue,We,Ge,Ke,qe,Je,Ye,Xe,Ze,Qe,Y,$e,et,tt,X,nt,rt,Z,Q,it,$=e((()=>{T(),E(),j(),k(),N(),P(),ge(),F(),I(),Ae=8e3,je=`doom-team-launch-`,V=`Task: `,H=`.ts`,Me=`.js`,Ne=`.md`,Pe=`prompt`,Fe=`task.md`,Ie=`tool-diagnostic.json`,U=`read`,W=`mcp`,Le=`*`,Re=`subagent`,G=`structured_output`,ze=`__none__`,K=`1`,q=`0`,J=384,Be=448,Ve=1,He=/[^\w.-]/g,Ue=/^\d+$/,We=`--session`,Ge=`--no-session`,Ke=`--session-dir`,qe=`--model`,Je=`--tools`,Ye=`--no-tools`,Xe=`--exclude-tools`,Ze=`--no-extensions`,Qe=`--extension`,Y=`--no-context-files`,$e=`--no-skills`,et=`--system-prompt`,tt=`--append-system-prompt`,X=`dist`,nt=`src`,rt=`.mjs`,Z=`extensions/subagentPromptRuntimeEntry`,Q=`.cts`,it=`extension/fanout-child`}));$();export{ke as buildPiArgs,$ as init_piArgs,De as resolvePiSdkResourcePlan};
2
+ //# sourceMappingURL=piArgs.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"piArgs.mjs","names":[],"sources":["../../../src/runs/shared/piArgs.ts"],"sourcesContent":["/**\n * The argv and environment handed to a spawned child agent.\n *\n * DESIGN PATTERNS:\n * - `resolvePiLaunchToolPlan` is the single place tool access is decided, and it\n * is pure. Everything about what a child may call is computable and testable\n * without touching the filesystem or spawning anything\n * - Capability ceilings only ever narrow. A ceiling from this process is\n * intersected with the one inherited from our own parent, and every requested\n * tool is then filtered against the result. Nothing in this file can add a tool\n * the ceiling excludes\n * - Fan-out authority is derived, not requested. A child receives the parent\n * event sink, control inbox, capability token and nesting path ONLY if it was\n * granted the `subagent` tool. Otherwise those variables are set to the empty\n * string rather than omitted, so an inherited value from our own environment\n * cannot leak through into a child that is not allowed to fan out\n * - Long task text goes to a private file passed as `@path` instead of argv,\n * because argv is both length-limited and visible in the process table\n *\n * AVOID:\n * - Widening anything here. If a case is ambiguous, narrow it\n * - Omitting a fan-out variable instead of blanking it; omission inherits\n * - Re-declaring env var names; they live in `src/env.ts` and cross processes\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n DOOM_CHILD_PROCESS_CONTEXT_ENV,\n encodeChildProcessContext,\n} from '@agimon-ai/doompi-extension-contracts/child-process';\nimport {\n CHILD_TOOL_DIAGNOSTIC_PATH_ENV,\n DOOMPI_CHILD_EXTENSIONS_ENV,\n DOOMPI_SKILL_DIRS_ENV,\n INHERIT_PROJECT_CONTEXT_ENV,\n INHERIT_SKILLS_ENV,\n MCP_DIRECT_CHILD_TOOLS_ENV,\n MCP_DIRECT_TOOLS_ENV,\n PI_CODING_AGENT_PACKAGE_ROOT_ENV,\n PI_INTERCOM_SESSION_ID_ENV,\n PI_INTERCOM_STABLE_ID_ENV,\n REQUIRED_CHILD_TOOLS_ENV,\n STRUCTURED_OUTPUT_CAPTURE_ENV,\n STRUCTURED_OUTPUT_SCHEMA_ENV,\n SUBAGENT_CAPABILITY_CEILING_ENV,\n SUBAGENT_CHILD_AGENT_ENV,\n SUBAGENT_CHILD_ENV,\n SUBAGENT_CHILD_INDEX_ENV,\n SUBAGENT_FANOUT_CHILD_ENV,\n SUBAGENT_INTERCOM_SESSION_NAME_ENV,\n SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV,\n SUBAGENT_PARENT_CHILD_INDEX_ENV,\n SUBAGENT_PARENT_CONTROL_INBOX_ENV,\n SUBAGENT_PARENT_DEPTH_ENV,\n SUBAGENT_PARENT_EVENT_SINK_ENV,\n SUBAGENT_PARENT_PATH_ENV,\n SUBAGENT_PARENT_ROOT_RUN_ID_ENV,\n SUBAGENT_PARENT_RUN_ID_ENV,\n SUBAGENT_PARENT_SESSION_ENV,\n SUBAGENT_RUN_ID_ENV,\n SUBAGENT_STEER_ACK_DIR_ENV,\n SUBAGENT_STEER_CAPABILITY_ENV,\n SUBAGENT_STEER_INBOX_ENV,\n TOOL_BUDGET_ENV,\n TOOL_BUDGET_ZERO_AUTH_ENV,\n} from '../../env.ts';\nimport {\n decodeSubagentCapabilityCeiling,\n encodeSubagentCapabilityCeiling,\n intersectSubagentCapabilityCeilings,\n type ResolvedSubagentCapabilityCeiling,\n type SubagentCapabilityAudit,\n} from '../../protocol/capabilityCeiling.ts';\nimport { THINKING_LEVELS } from '../../shared/modelInfo.ts';\nimport { currentChildLaunchTempDir } from '../../shared/paths.ts';\nimport type { JsonSchemaObject } from '../../types.ts';\nimport {\n NATIVE_TEAM_TOOL_NAME,\n clearNativeTeamMemberEnvironment,\n nativeTeamMemberEnvironment,\n type TeamMemberContext,\n} from '../../intercom/nativeTeamChannel.ts';\nimport { resolveMcpDirectToolSelections, type ResolvedMcpDirectToolSelection } from './mcpDirectToolAllowlist.ts';\nimport { encodeNestedPathEnv, parseNestedPathEnv, type NestedPathEntry } from './nestedPath.ts';\nimport { resolvePiPackageRoot } from './piSpawn.ts';\nimport { encodeToolBudgetEnv, type ResolvedToolBudget } from './toolBudget.ts';\n\n/**\n * Task text longer than this is written to a file and passed as `@path`.\n *\n * Well under the platform argv limit, because the task shares argv with the\n * model, tool and extension flags.\n */\nconst TASK_ARG_LIMIT = 8000;\nconst TEMP_DIRECTORY_PREFIX = 'doom-team-launch-';\nconst TASK_PREFIX = 'Task: ';\nconst TYPESCRIPT_EXTENSION = '.ts';\nconst JAVASCRIPT_EXTENSION = '.js';\nconst PROMPT_FILE_EXTENSION = '.md';\nconst DEFAULT_PROMPT_FILE_STEM = 'prompt';\nconst TASK_FILE_NAME = 'task.md';\nconst TOOL_DIAGNOSTIC_FILE_NAME = 'tool-diagnostic.json';\nconst READ_TOOL_NAME = 'read';\nconst MCP_TOOL_NAME = 'mcp';\nconst ALL_MCP_SERVERS_SELECTOR = '*';\nconst SUBAGENT_TOOL_NAME = 'subagent';\nconst STRUCTURED_OUTPUT_TOOL_NAME = 'structured_output';\nconst NO_MCP_DIRECT_TOOLS = '__none__';\nconst ENABLED_ENV_VALUE = '1';\nconst DISABLED_ENV_VALUE = '0';\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIR_MODE = 0o700;\nconst ROOT_FANOUT_DEPTH = 1;\nconst UNSAFE_PROMPT_STEM_CHARACTERS = /[^\\w.-]/g;\nconst DIGITS_ONLY = /^\\d+$/;\n\nconst SESSION_FLAG = '--session';\nconst NO_SESSION_FLAG = '--no-session';\nconst SESSION_DIRECTORY_FLAG = '--session-dir';\nconst MODEL_FLAG = '--model';\nconst TOOLS_FLAG = '--tools';\nconst NO_TOOLS_FLAG = '--no-tools';\nconst EXCLUDE_TOOLS_FLAG = '--exclude-tools';\nconst NO_EXTENSIONS_FLAG = '--no-extensions';\nconst EXTENSION_FLAG = '--extension';\nconst NO_CONTEXT_FILES_FLAG = '--no-context-files';\nconst NO_SKILLS_FLAG = '--no-skills';\nconst SYSTEM_PROMPT_FLAG = '--system-prompt';\nconst APPEND_SYSTEM_PROMPT_FLAG = '--append-system-prompt';\n\nconst BUILT_OUTPUT_DIR = 'dist';\nconst SOURCE_DIR = 'src';\nconst BUILT_EXTENSION = '.mjs';\nconst PROMPT_RUNTIME_EXTENSION = 'extensions/subagentPromptRuntimeEntry';\nconst PROMPT_RUNTIME_SOURCE_EXTENSION = '.cts';\nconst FANOUT_CHILD_EXTENSION = 'extension/fanout-child';\n\n/**\n * Locate an extension the child must load, in either a built or a source tree.\n *\n * The child is a separate process loading these by path, so the path has to be\n * the one that exists on disk now: `.mjs` under `dist` when this bundle is\n * built, the original source file when it is not.\n *\n * Resolved on demand rather than at module load. Doing it eagerly would make\n * importing this module throw in any tree where the extensions are not built\n * yet, which turns a launch-time problem into an import-time one.\n */\nfunction resolveRuntimeExtensionPath(relativePath: string, sourceExtension = TYPESCRIPT_EXTENSION): string {\n const modulePath = fileURLToPath(import.meta.url);\n const builtMode = modulePath.split(path.sep).includes(BUILT_OUTPUT_DIR);\n const runtimeRoot = builtMode ? BUILT_OUTPUT_DIR : SOURCE_DIR;\n const extension = builtMode ? BUILT_EXTENSION : sourceExtension;\n let directory = path.dirname(modulePath);\n while (true) {\n const candidate = path.join(directory, runtimeRoot, `${relativePath}${extension}`);\n if (fs.existsSync(candidate)) return candidate;\n const parent = path.dirname(directory);\n if (parent === directory) throw new Error(`Could not resolve runtime extension ${relativePath}`);\n directory = parent;\n }\n}\n\nexport interface BuildPiArgsInput {\n parentSessionId?: string;\n baseArgs: string[];\n task: string;\n sessionEnabled: boolean;\n sessionDir?: string;\n sessionFile?: string;\n model?: string;\n thinking?: string | false;\n systemPromptMode?: 'append' | 'replace';\n inheritProjectContext: boolean;\n inheritSkills: boolean;\n requireReadTool?: boolean;\n tools?: string[];\n excludeTools?: string[];\n extensions?: string[];\n subagentOnlyExtensions?: string[];\n systemPrompt?: string | null;\n mcpDirectTools?: string[];\n cwd?: string;\n promptFileStem?: string;\n intercomSessionName?: string;\n runId?: string;\n childAgentName?: string;\n childIndex?: number;\n parentEventSink?: string;\n parentControlInbox?: string;\n parentRootRunId?: string;\n parentRunId?: string;\n parentChildIndex?: number;\n parentDepth?: number;\n parentPath?: NestedPathEntry[];\n parentCapabilityToken?: string;\n steerInboxDir?: string;\n steerCapabilityPath?: string;\n steerAckDir?: string;\n structuredOutput?: {\n schema: JsonSchemaObject;\n schemaPath: string;\n outputPath: string;\n };\n toolBudget?: ResolvedToolBudget;\n allowZeroToolBudget?: boolean;\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n teamMember?: TeamMemberContext;\n teamToolEnabled?: boolean;\n}\n\nexport interface BuildPiArgsResult {\n args: string[];\n env: Record<string, string | undefined>;\n sdk: PiSdkLaunchSettings;\n tempDir?: string;\n toolDiagnosticPath?: string;\n capabilityAudit?: SubagentCapabilityAudit;\n}\n\nexport interface PiSdkLaunchSettings {\n model?: string;\n tools?: string[];\n noTools?: 'all';\n excludeTools?: string[];\n extensions: string[];\n noAmbientExtensions: boolean;\n skillPaths: string[];\n noSkills: boolean;\n noContextFiles: boolean;\n sessionEnabled: boolean;\n sessionDir?: string;\n sessionFile?: string;\n systemPrompt?: string;\n systemPromptMode?: 'append' | 'replace';\n}\n\nfunction inheritedDoomPiExtensions(environment: NodeJS.ProcessEnv = process.env): string[] {\n const raw = environment[DOOMPI_CHILD_EXTENSIONS_ENV];\n if (!raw) return [];\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n const detail = error instanceof Error ? ` ${error.message}` : '';\n throw new Error(`${DOOMPI_CHILD_EXTENSIONS_ENV} must be valid JSON.${detail}`);\n }\n if (!Array.isArray(parsed) || !parsed.every((value) => typeof value === 'string')) {\n throw new Error(`${DOOMPI_CHILD_EXTENSIONS_ENV} must be a JSON array of extension paths.`);\n }\n return parsed;\n}\n\nfunction inheritedDoomPiSkillPaths(environment: NodeJS.ProcessEnv = process.env): string[] {\n const raw = environment[DOOMPI_SKILL_DIRS_ENV];\n return raw ? raw.split(path.delimiter).filter(Boolean) : [];\n}\n\n/**\n * Append a thinking level to a model id.\n *\n * A model id that already carries a known level is left alone unless the caller\n * asks to replace it, so an explicit per-agent choice survives an inherited one.\n */\nexport function applyThinkingSuffix(\n model: string | undefined,\n thinking: string | false | undefined,\n replaceExisting = false,\n): string | undefined {\n if (!model || !thinking) return model;\n const colonIdx = model.lastIndexOf(':');\n if (colonIdx !== -1 && THINKING_LEVELS.some((level) => level === model.substring(colonIdx + 1))) {\n return replaceExisting ? `${model.slice(0, colonIdx)}:${thinking}` : model;\n }\n return `${model}:${thinking}`;\n}\n\nexport interface ResolvePiLaunchToolPlanInput {\n tools?: string[];\n extensions?: string[];\n subagentOnlyExtensions?: string[];\n mcpDirectTools?: string[];\n cwd?: string;\n requireReadTool?: boolean;\n excludeTools?: string[];\n structuredOutput?: boolean;\n teamToolEnabled?: boolean;\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n inheritedCapabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n}\n\nexport interface PiLaunchToolPlan {\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n excludedTools: string[];\n requestedBuiltinTools: string[];\n declaredBuiltinTools: string[];\n toolExtensionPaths: string[];\n resolvedMcpSelections: ResolvedMcpDirectToolSelection[];\n effectiveMcpSelections: ResolvedMcpDirectToolSelection[];\n effectiveMcpTools: string[];\n explicitToolAllowlist: boolean;\n internalTools: string[];\n effectiveToolAllowlist: string[];\n requiredChildTools: string[];\n fanoutAuthorized: boolean;\n runtimeExtensions: string[];\n configuredExtensions: string[];\n extensionArgs: string[];\n disableAmbientExtensions: boolean;\n capabilityAudit?: SubagentCapabilityAudit;\n}\n\nexport interface ResolvePiSdkResourcePlanInput extends ResolvePiLaunchToolPlanInput {\n inheritSkills: boolean;\n environment?: NodeJS.ProcessEnv;\n}\n\n/** The resource-only subset of Pi SDK settings, safe to calculate without writing launch files. */\nexport interface PiSdkResourcePlan {\n toolPlan: PiLaunchToolPlan;\n tools?: string[];\n noTools?: 'all';\n excludeTools?: string[];\n extensions: string[];\n noAmbientExtensions: boolean;\n skillPaths: string[];\n noSkills: boolean;\n}\n\n/** A tool entry is an extension path, not a builtin name, when it looks like a path. */\nfunction isToolExtensionPath(tool: string): boolean {\n return tool.includes('/') || tool.endsWith(TYPESCRIPT_EXTENSION) || tool.endsWith(JAVASCRIPT_EXTENSION);\n}\n\n/**\n * Decide exactly what the child may call.\n *\n * This is the security boundary. The order matters: the ceiling is computed\n * first, and every later step filters against it. `requireReadTool` can add\n * `read` to a nonempty caller request only when no ceiling is in force. A\n * ceiling or explicit effective allowlist that omits `read` is refused rather\n * than widened.\n */\nexport function resolvePiLaunchToolPlan(input: ResolvePiLaunchToolPlanInput): PiLaunchToolPlan {\n const capabilityCeiling = intersectSubagentCapabilityCeilings(\n input.capabilityCeiling,\n input.inheritedCapabilityCeiling,\n );\n const allowedToolSet =\n capabilityCeiling?.allowedTools === undefined ? undefined : new Set(capabilityCeiling.allowedTools);\n const allowedBuiltinTools = capabilityCeiling?.allowedTools?.filter(\n (tool) => !(capabilityCeiling.allowMcpTools === true && tool === MCP_TOOL_NAME),\n );\n const excludedTools = [\n ...new Set((input.excludeTools ?? []).map((tool) => tool.trim()).filter((tool) => tool.length > 0)),\n ];\n const excludedToolSet = new Set(excludedTools);\n const policyRequiredTools = capabilityCeiling?.requiredTools ?? [];\n const mcpToolsAllowed = capabilityCeiling?.allowMcpTools === true;\n const mcpRequested = mcpToolsAllowed && [...(input.tools ?? []), ...policyRequiredTools].includes(MCP_TOOL_NAME);\n const requestedBuiltinTools = [...new Set([...(input.tools ?? []), ...policyRequiredTools])].filter(\n (tool) => !isToolExtensionPath(tool) && !(mcpRequested && tool === MCP_TOOL_NAME),\n );\n const requestedMcpSelectors = [...(input.mcpDirectTools ?? []), ...(mcpRequested ? [ALL_MCP_SERVERS_SELECTOR] : [])];\n if (input.requireReadTool && excludedToolSet.has(READ_TOOL_NAME)) {\n throw new Error(`Child tool exclusions exclude required tool '${READ_TOOL_NAME}' for lazy skill loading.`);\n }\n if (input.structuredOutput && excludedToolSet.has(STRUCTURED_OUTPUT_TOOL_NAME)) {\n throw new Error(`Child tool exclusions exclude required tool '${STRUCTURED_OUTPUT_TOOL_NAME}'.`);\n }\n if (input.requireReadTool && allowedToolSet && !allowedToolSet.has(READ_TOOL_NAME)) {\n throw new Error(\n `Capability ceiling from ${capabilityCeiling?.sources.join(', ') || 'unknown source'} excludes required tool '${READ_TOOL_NAME}' for lazy skill loading.`,\n );\n }\n // No `tools` at all means \"whatever the host allows\", which under a ceiling\n // becomes exactly the ceiling and without one stays unconstrained.\n const declaredBuiltinTools =\n input.tools === undefined\n ? (allowedBuiltinTools ?? [])\n : (input.requireReadTool &&\n requestedBuiltinTools.length > 0 &&\n !requestedBuiltinTools.includes(READ_TOOL_NAME) &&\n !allowedToolSet\n ? [READ_TOOL_NAME, ...requestedBuiltinTools]\n : requestedBuiltinTools\n )\n .filter((tool) => !allowedToolSet || allowedToolSet.has(tool))\n .filter((tool) => !excludedToolSet.has(tool));\n // Fan-out authority is exactly \"was granted the subagent tool\", read after\n // ceiling filtering so a denied tool cannot confer it.\n const fanoutAuthorized = declaredBuiltinTools.includes(SUBAGENT_TOOL_NAME);\n const toolExtensionPaths: string[] = capabilityCeiling?.denyExtensions\n ? []\n : (input.tools ?? []).filter((tool) => !requestedBuiltinTools.includes(tool) && isToolExtensionPath(tool));\n const resolvedMcpSelections = capabilityCeiling?.denyExtensions\n ? []\n : resolveMcpDirectToolSelections(requestedMcpSelectors, input.cwd);\n const effectiveMcpSelections = resolvedMcpSelections.filter(\n (selection) =>\n (mcpToolsAllowed || !allowedToolSet || allowedToolSet.has(selection.name)) &&\n !excludedToolSet.has(selection.name),\n );\n const effectiveMcpTools = effectiveMcpSelections.map((selection) => selection.name);\n const explicitToolAllowlist =\n input.tools !== undefined || requestedMcpSelectors.length > 0 || allowedToolSet !== undefined;\n // Internal tools are ours, not the caller's, so they bypass the allowlist but\n // are still reported in the audit.\n const internalTools = [\n ...(input.structuredOutput ? [STRUCTURED_OUTPUT_TOOL_NAME] : []),\n ...(input.teamToolEnabled ? [NATIVE_TEAM_TOOL_NAME] : []),\n ].filter((tool) => !excludedToolSet.has(tool));\n const effectiveToolAllowlist = [...new Set([...declaredBuiltinTools, ...effectiveMcpTools, ...internalTools])];\n if (input.requireReadTool && explicitToolAllowlist && !effectiveToolAllowlist.includes(READ_TOOL_NAME)) {\n throw new Error(\n `Effective child tool allowlist excludes required tool '${READ_TOOL_NAME}' for lazy skill loading.`,\n );\n }\n const requiredChildTools = explicitToolAllowlist\n ? [\n ...new Set([\n ...(input.tools !== undefined ? declaredBuiltinTools : []),\n ...(requestedMcpSelectors.length ? effectiveMcpTools : []),\n ...internalTools,\n ]),\n ]\n : [];\n const runtimeExtensions = fanoutAuthorized\n ? [\n resolveRuntimeExtensionPath(PROMPT_RUNTIME_EXTENSION, PROMPT_RUNTIME_SOURCE_EXTENSION),\n resolveRuntimeExtensionPath(FANOUT_CHILD_EXTENSION),\n ]\n : [resolveRuntimeExtensionPath(PROMPT_RUNTIME_EXTENSION, PROMPT_RUNTIME_SOURCE_EXTENSION)];\n const disableAmbientExtensions = capabilityCeiling?.denyExtensions === true || input.extensions !== undefined;\n const configuredExtensions = capabilityCeiling?.denyExtensions\n ? []\n : [...toolExtensionPaths, ...(input.extensions ?? []), ...(input.subagentOnlyExtensions ?? [])];\n const extensionArgs = disableAmbientExtensions\n ? [...new Set([...runtimeExtensions, ...configuredExtensions])]\n : [...new Set([...runtimeExtensions, ...toolExtensionPaths, ...(input.subagentOnlyExtensions ?? [])])];\n const requestedToolNames =\n input.tools !== undefined\n ? [...new Set([...requestedBuiltinTools, ...resolvedMcpSelections.map((selection) => selection.name)])]\n : undefined;\n const capabilityAudit = capabilityCeiling\n ? ({\n ceiling: capabilityCeiling,\n ...(requestedToolNames ? { requestedTools: requestedToolNames } : {}),\n effectiveTools: effectiveToolAllowlist,\n removedTools: requestedToolNames?.filter((tool) => !effectiveToolAllowlist.includes(tool)) ?? [],\n internalTools,\n extensionsDenied: capabilityCeiling.denyExtensions,\n removedExtensionCount: capabilityCeiling.denyExtensions\n ? (input.extensions?.length ?? 0) +\n (input.subagentOnlyExtensions?.length ?? 0) +\n (input.tools ?? []).filter(isToolExtensionPath).length\n : 0,\n requestedMcpToolCount: requestedMcpSelectors.length,\n effectiveMcpTools,\n } satisfies SubagentCapabilityAudit)\n : undefined;\n return {\n ...(capabilityCeiling ? { capabilityCeiling } : {}),\n excludedTools,\n requestedBuiltinTools,\n declaredBuiltinTools,\n toolExtensionPaths,\n resolvedMcpSelections,\n effectiveMcpSelections,\n effectiveMcpTools,\n explicitToolAllowlist,\n internalTools,\n effectiveToolAllowlist,\n requiredChildTools,\n fanoutAuthorized,\n runtimeExtensions,\n configuredExtensions,\n extensionArgs,\n disableAmbientExtensions,\n ...(capabilityAudit ? { capabilityAudit } : {}),\n };\n}\n\n/**\n * Resolve the child SDK's resource settings without creating launch files or\n * starting a child process. Filesystem-backed MCP and runtime-extension lookup\n * still follows the same path as a real launch.\n */\nexport function resolvePiSdkResourcePlan(input: ResolvePiSdkResourcePlanInput): PiSdkResourcePlan {\n const environment = input.environment ?? process.env;\n const inheritedCapabilityCeiling = intersectSubagentCapabilityCeilings(\n input.inheritedCapabilityCeiling,\n decodeSubagentCapabilityCeiling(environment[SUBAGENT_CAPABILITY_CEILING_ENV]),\n );\n const toolPlan = resolvePiLaunchToolPlan({\n tools: input.tools,\n extensions: input.extensions,\n subagentOnlyExtensions: input.subagentOnlyExtensions,\n mcpDirectTools: input.mcpDirectTools,\n cwd: input.cwd,\n requireReadTool: input.requireReadTool,\n excludeTools: input.excludeTools,\n structuredOutput: input.structuredOutput,\n teamToolEnabled: input.teamToolEnabled,\n capabilityCeiling: input.capabilityCeiling,\n inheritedCapabilityCeiling,\n });\n const explicitTools = toolPlan.explicitToolAllowlist ? toolPlan.effectiveToolAllowlist : undefined;\n return {\n toolPlan,\n ...(explicitTools && explicitTools.length > 0 ? { tools: explicitTools } : {}),\n ...(explicitTools?.length === 0 ? { noTools: 'all' as const } : {}),\n ...(toolPlan.excludedTools.length > 0 ? { excludeTools: toolPlan.excludedTools } : {}),\n extensions: [...new Set([...inheritedDoomPiExtensions(environment), ...toolPlan.extensionArgs])],\n noAmbientExtensions: toolPlan.disableAmbientExtensions,\n skillPaths: input.inheritSkills ? inheritedDoomPiSkillPaths(environment) : [],\n noSkills: !input.inheritSkills,\n };\n}\n\n/**\n * Scratch directory for this launch's prompt, task and diagnostics.\n *\n * Created 0700 under the per-user temp root, because the files inside carry the\n * full task and system prompt.\n */\nfunction createLaunchTempDir(): string {\n fs.mkdirSync(currentChildLaunchTempDir(), { recursive: true, mode: PRIVATE_DIR_MODE });\n return fs.mkdtempSync(path.join(currentChildLaunchTempDir(), TEMP_DIRECTORY_PREFIX));\n}\n\nexport function buildPiArgs(input: BuildPiArgsInput): BuildPiArgsResult {\n const args = [...input.baseArgs];\n\n if (input.sessionFile) {\n fs.mkdirSync(path.dirname(input.sessionFile), { recursive: true });\n args.push(SESSION_FLAG, input.sessionFile);\n } else {\n if (!input.sessionEnabled) {\n args.push(NO_SESSION_FLAG);\n }\n if (input.sessionDir) {\n fs.mkdirSync(input.sessionDir, { recursive: true });\n args.push(SESSION_DIRECTORY_FLAG, input.sessionDir);\n }\n }\n\n const modelArg = applyThinkingSuffix(input.model, input.thinking);\n if (modelArg) {\n args.push(MODEL_FLAG, modelArg);\n }\n\n const resourcePlan = resolvePiSdkResourcePlan({\n tools: input.tools,\n extensions: input.extensions,\n subagentOnlyExtensions: input.subagentOnlyExtensions,\n mcpDirectTools: input.mcpDirectTools,\n cwd: input.cwd,\n requireReadTool: input.requireReadTool,\n excludeTools: input.excludeTools,\n structuredOutput: Boolean(input.structuredOutput),\n teamToolEnabled: Boolean(input.teamMember) || input.teamToolEnabled === true,\n capabilityCeiling: input.capabilityCeiling,\n inheritSkills: input.inheritSkills,\n });\n const { toolPlan, ...sdkResources } = resourcePlan;\n if (toolPlan.explicitToolAllowlist) {\n // An empty allowlist means no tools at all, which is a different flag rather\n // than an empty `--tools` value.\n args.push(toolPlan.effectiveToolAllowlist.length > 0 ? TOOLS_FLAG : NO_TOOLS_FLAG);\n if (toolPlan.effectiveToolAllowlist.length > 0) args.push(toolPlan.effectiveToolAllowlist.join(','));\n }\n if (toolPlan.excludedTools.length > 0) {\n args.push(EXCLUDE_TOOLS_FLAG, toolPlan.excludedTools.join(','));\n }\n if (toolPlan.disableAmbientExtensions) {\n args.push(NO_EXTENSIONS_FLAG);\n }\n for (const extPath of toolPlan.extensionArgs) args.push(EXTENSION_FLAG, extPath);\n\n if (!input.inheritProjectContext) {\n args.push(NO_CONTEXT_FILES_FLAG);\n }\n if (!input.inheritSkills) {\n args.push(NO_SKILLS_FLAG);\n }\n\n let tempDir: string | undefined;\n const ensureTempDir = (): string => {\n tempDir ??= createLaunchTempDir();\n return tempDir;\n };\n\n if (input.systemPrompt !== undefined && input.systemPrompt !== null) {\n const stem = (input.promptFileStem ?? DEFAULT_PROMPT_FILE_STEM).replace(UNSAFE_PROMPT_STEM_CHARACTERS, '_');\n const promptPath = path.join(ensureTempDir(), `${stem}${PROMPT_FILE_EXTENSION}`);\n fs.writeFileSync(promptPath, input.systemPrompt, { mode: PRIVATE_FILE_MODE });\n args.push(input.systemPromptMode === 'replace' ? SYSTEM_PROMPT_FLAG : APPEND_SYSTEM_PROMPT_FLAG, promptPath);\n }\n\n if (input.task.length > TASK_ARG_LIMIT) {\n const taskFilePath = path.join(ensureTempDir(), TASK_FILE_NAME);\n fs.writeFileSync(taskFilePath, `${TASK_PREFIX}${input.task}`, { mode: PRIVATE_FILE_MODE });\n args.push(`@${taskFilePath}`);\n } else {\n args.push(`${TASK_PREFIX}${input.task}`);\n }\n\n // Team membership vars are always written: the clearing form blanks whatever\n // this process inherited so a non-team child cannot join its parent's team.\n const env: Record<string, string | undefined> = {\n ...(input.teamMember ? nativeTeamMemberEnvironment(input.teamMember) : clearNativeTeamMemberEnvironment()),\n };\n const piPackageRoot = process.env[PI_CODING_AGENT_PACKAGE_ROOT_ENV] ?? resolvePiPackageRoot();\n if (piPackageRoot) env[PI_CODING_AGENT_PACKAGE_ROOT_ENV] = piPackageRoot;\n let toolDiagnosticPath: string | undefined;\n if (toolPlan.requiredChildTools.length > 0) {\n toolDiagnosticPath = path.join(ensureTempDir(), TOOL_DIAGNOSTIC_FILE_NAME);\n env[REQUIRED_CHILD_TOOLS_ENV] = JSON.stringify(toolPlan.requiredChildTools);\n env[CHILD_TOOL_DIAGNOSTIC_PATH_ENV] = toolDiagnosticPath;\n }\n env[MCP_DIRECT_CHILD_TOOLS_ENV] =\n toolPlan.effectiveMcpTools.length > 0 ? JSON.stringify(toolPlan.effectiveMcpTools) : undefined;\n env[SUBAGENT_CHILD_ENV] = ENABLED_ENV_VALUE;\n env[SUBAGENT_FANOUT_CHILD_ENV] = toolPlan.fanoutAuthorized ? ENABLED_ENV_VALUE : DISABLED_ENV_VALUE;\n // We are ourselves a nested child only if our parent granted us the full\n // fan-out route; a partial set of inherited vars is not trusted.\n const inheritedNestedRoute = Boolean(\n process.env[SUBAGENT_PARENT_EVENT_SINK_ENV] &&\n process.env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] &&\n process.env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV],\n );\n const parentRunId =\n input.parentRunId ??\n input.runId ??\n (inheritedNestedRoute ? process.env[SUBAGENT_RUN_ID_ENV] : undefined) ??\n process.env[SUBAGENT_PARENT_RUN_ID_ENV] ??\n '';\n const parentChildIndex =\n input.parentChildIndex !== undefined\n ? String(input.parentChildIndex)\n : input.childIndex !== undefined\n ? String(input.childIndex)\n : (process.env[SUBAGENT_PARENT_CHILD_INDEX_ENV] ?? '');\n const inheritedDepth = Number(process.env[SUBAGENT_PARENT_DEPTH_ENV]);\n const parentDepth =\n input.parentDepth ??\n (inheritedNestedRoute && Number.isFinite(inheritedDepth) ? inheritedDepth + 1 : ROOT_FANOUT_DEPTH);\n const parentPath = input.parentPath ?? [\n ...parseNestedPathEnv(process.env[SUBAGENT_PARENT_PATH_ENV]),\n ...(parentRunId\n ? [\n {\n runId: parentRunId,\n ...(parentChildIndex && DIGITS_ONLY.test(parentChildIndex) ? { stepIndex: Number(parentChildIndex) } : {}),\n ...(input.childAgentName ? { agent: input.childAgentName } : {}),\n },\n ]\n : []),\n ];\n // Blanked rather than omitted when fan-out is not authorized: an omitted key\n // would let the child inherit this process's own value.\n env[SUBAGENT_PARENT_EVENT_SINK_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentEventSink ?? process.env[SUBAGENT_PARENT_EVENT_SINK_ENV] ?? '')\n : '';\n env[SUBAGENT_PARENT_CONTROL_INBOX_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentControlInbox ?? process.env[SUBAGENT_PARENT_CONTROL_INBOX_ENV] ?? '')\n : '';\n env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentRootRunId ?? process.env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] ?? input.runId ?? '')\n : '';\n env[SUBAGENT_PARENT_RUN_ID_ENV] = toolPlan.fanoutAuthorized ? parentRunId : '';\n env[SUBAGENT_PARENT_CHILD_INDEX_ENV] = toolPlan.fanoutAuthorized ? parentChildIndex : '';\n env[SUBAGENT_PARENT_DEPTH_ENV] = toolPlan.fanoutAuthorized ? String(parentDepth) : '';\n env[SUBAGENT_PARENT_PATH_ENV] = toolPlan.fanoutAuthorized ? encodeNestedPathEnv(parentPath) : '';\n env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentCapabilityToken ?? process.env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV] ?? '')\n : '';\n env[INHERIT_PROJECT_CONTEXT_ENV] = input.inheritProjectContext ? ENABLED_ENV_VALUE : DISABLED_ENV_VALUE;\n env[INHERIT_SKILLS_ENV] = input.inheritSkills ? ENABLED_ENV_VALUE : DISABLED_ENV_VALUE;\n env[PI_INTERCOM_STABLE_ID_ENV] = input.intercomSessionName || undefined;\n // Cleared unconditionally: an inherited session id would make the child adopt\n // its parent's intercom identity.\n env[PI_INTERCOM_SESSION_ID_ENV] = undefined;\n if (input.intercomSessionName) {\n env[SUBAGENT_INTERCOM_SESSION_NAME_ENV] = input.intercomSessionName;\n }\n if (input.runId) {\n env[SUBAGENT_RUN_ID_ENV] = input.runId;\n }\n if (input.childAgentName) {\n env[SUBAGENT_CHILD_AGENT_ENV] = input.childAgentName;\n }\n if (input.childIndex !== undefined) {\n env[SUBAGENT_CHILD_INDEX_ENV] = String(input.childIndex);\n }\n // The Pi host reads its own selector list from this var. Without a ceiling the\n // caller's selectors pass through; with one, only the selectors that survived\n // filtering do, and anything else resolves to the explicit \"none\" sentinel.\n if (!toolPlan.capabilityCeiling && input.mcpDirectTools?.length)\n env[MCP_DIRECT_TOOLS_ENV] = input.mcpDirectTools.join(',');\n else if (\n toolPlan.capabilityCeiling &&\n toolPlan.effectiveMcpSelections.length &&\n !toolPlan.capabilityCeiling.denyExtensions\n )\n env[MCP_DIRECT_TOOLS_ENV] = toolPlan.effectiveMcpSelections.map((selection) => selection.selector).join(',');\n else env[MCP_DIRECT_TOOLS_ENV] = NO_MCP_DIRECT_TOOLS;\n const encodedCapabilityCeiling = encodeSubagentCapabilityCeiling(toolPlan.capabilityCeiling);\n if (encodedCapabilityCeiling) env[SUBAGENT_CAPABILITY_CEILING_ENV] = encodedCapabilityCeiling;\n if (input.structuredOutput) {\n env[STRUCTURED_OUTPUT_CAPTURE_ENV] = input.structuredOutput.outputPath;\n env[STRUCTURED_OUTPUT_SCHEMA_ENV] = input.structuredOutput.schemaPath;\n }\n if (input.steerInboxDir) {\n env[SUBAGENT_STEER_INBOX_ENV] = input.steerInboxDir;\n }\n if (input.steerCapabilityPath) env[SUBAGENT_STEER_CAPABILITY_ENV] = input.steerCapabilityPath;\n if (input.steerAckDir) env[SUBAGENT_STEER_ACK_DIR_ENV] = input.steerAckDir;\n const encodedToolBudget = encodeToolBudgetEnv(input.toolBudget);\n if (encodedToolBudget) env[TOOL_BUDGET_ENV] = encodedToolBudget;\n env[TOOL_BUDGET_ZERO_AUTH_ENV] = input.allowZeroToolBudget ? ENABLED_ENV_VALUE : undefined;\n env[SUBAGENT_PARENT_SESSION_ENV] = input.parentSessionId ?? process.env[SUBAGENT_PARENT_SESSION_ENV] ?? '';\n env[DOOM_CHILD_PROCESS_CONTEXT_ENV] = input.parentSessionId\n ? encodeChildProcessContext({\n parentSessionId: input.parentSessionId,\n workingDirectory: input.cwd ?? process.cwd(),\n ...(input.childAgentName ? { mode: input.childAgentName } : {}),\n })\n : undefined;\n\n const sdk: PiSdkLaunchSettings = {\n ...(input.model || input.thinking ? { model: applyThinkingSuffix(input.model, input.thinking) } : {}),\n ...sdkResources,\n noContextFiles: !input.inheritProjectContext,\n sessionEnabled: input.sessionEnabled,\n ...(input.sessionDir ? { sessionDir: input.sessionDir } : {}),\n ...(input.sessionFile ? { sessionFile: input.sessionFile } : {}),\n ...(input.systemPrompt !== undefined && input.systemPrompt !== null ? { systemPrompt: input.systemPrompt } : {}),\n ...(input.systemPromptMode ? { systemPromptMode: input.systemPromptMode } : {}),\n };\n\n return { args, env, sdk, tempDir, toolDiagnosticPath, capabilityAudit: toolPlan.capabilityAudit };\n}\n\nexport const parseParentPathEnv = parseNestedPathEnv;\n\nexport function cleanupTempDir(tempDir: string | null | undefined): boolean {\n if (!tempDir) return true;\n try {\n fs.rmSync(tempDir, { recursive: true, force: true });\n return true;\n } catch {\n // The child may still hold the prompt file open. Reporting false lets the\n // caller record the leak; throwing would fail a run that already succeeded.\n return false;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require(`../../_virtual/_rolldown/runtime.cjs`);require(`../../env.cjs`);let t=require(`node:fs`);t=e.__toESM(t,1);let n=require(`node:path`);n=e.__toESM(n,1),require(`node:url`);function r(e){let r=n.dirname(e);for(;r!==n.dirname(r);){let e=n.join(r,`package.json`);if(t.existsSync(e)&&i(JSON.parse(t.readFileSync(e,`utf-8`)))===`@earendil-works/pi-coding-agent`)return r;r=n.dirname(r)}}function i(e){if(typeof e!=`object`||!e)return;let t=e.name;return typeof t==`string`?t:void 0}function a(){try{let e=process.argv[1];return e?r(t.realpathSync(e)):void 0}catch{return}}exports.resolvePiPackageRoot=a;
2
+ //# sourceMappingURL=piSpawn.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"piSpawn.cjs","names":["path","fs"],"sources":["../../../src/runs/shared/piSpawn.ts"],"sourcesContent":["/**\n * How to invoke the Pi CLI for a child process.\n *\n * DESIGN PATTERNS:\n * - Three resolution tiers, most explicit first: an operator override env var,\n * then a verified script path run through this process's own Node binary, then\n * bare `pi` on PATH. Running the resolved script under `process.execPath` means\n * a child gets the same Node version as its parent, which a shebang would not\n * guarantee\n * - Every resolution step is best-effort. Failing to identify the installed CLI\n * is not an error, it just falls through to the next tier\n * - Filesystem and resolver calls are injectable, because ESM module namespaces\n * are frozen and `node:fs` cannot otherwise be substituted in a test\n *\n * AVOID:\n * - Trusting `process.argv[1]` without confirming it really is the Pi CLI. The\n * host embedding this package has its own entry point there, and spawning that\n * would run the host again rather than the agent\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { PI_SUBAGENT_PI_BINARY_ENV } from '../../env.ts';\n\nexport const PI_CODING_AGENT_PACKAGE = '@earendil-works/pi-coding-agent';\n\nconst PACKAGE_MANIFEST_NAME = 'package.json';\nconst PI_BIN_FIELD_NAME = 'pi';\nconst PI_PATH_COMMAND = 'pi';\nconst NODE_SCRIPT_EXTENSIONS = /\\.(?:mjs|cjs|js)$/i;\n\n/** Walk up from an entry point to the package root that declares the Pi CLI. */\nexport function findPiPackageRootFromEntry(entryPoint: string): string | undefined {\n let dir = path.dirname(entryPoint);\n while (dir !== path.dirname(dir)) {\n const packageJsonPath = path.join(dir, PACKAGE_MANIFEST_NAME);\n if (fs.existsSync(packageJsonPath)) {\n const manifest: unknown = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));\n if (readManifestName(manifest) === PI_CODING_AGENT_PACKAGE) return dir;\n }\n dir = path.dirname(dir);\n }\n return undefined;\n}\n\nfunction readManifestName(manifest: unknown): string | undefined {\n if (typeof manifest !== 'object' || manifest === null) return undefined;\n const name: unknown = (manifest as { name?: unknown }).name;\n return typeof name === 'string' ? name : undefined;\n}\n\n/**\n * The `bin` entry to spawn, from a package manifest of unknown shape.\n *\n * npm allows `bin` to be either a bare string or a map. The named `pi` entry\n * wins; any single other entry is accepted because a renamed fork still exposes\n * exactly one executable.\n */\nfunction readManifestBinPath(manifest: unknown): string | undefined {\n if (typeof manifest !== 'object' || manifest === null) return undefined;\n const bin: unknown = (manifest as { bin?: unknown }).bin;\n if (typeof bin === 'string') return bin;\n if (typeof bin !== 'object' || bin === null) return undefined;\n const entries: Record<string, unknown> = bin as Record<string, unknown>;\n const named: unknown = entries[PI_BIN_FIELD_NAME];\n if (typeof named === 'string') return named;\n const first = Object.values(entries).find((value): value is string => typeof value === 'string');\n return first;\n}\n\nexport function resolveInstalledPiPackageRoot(): string | undefined {\n return findPiPackageRootFromEntry(fileURLToPath(import.meta.resolve(PI_CODING_AGENT_PACKAGE)));\n}\n\nexport function resolvePiPackageRoot(): string | undefined {\n try {\n const entry = process.argv[1];\n return entry ? findPiPackageRootFromEntry(fs.realpathSync(entry)) : undefined;\n } catch {\n // process.argv[1] probing is best-effort; callers fall back to PATH or package resolution.\n return undefined;\n }\n}\n\nexport interface PiSpawnDeps {\n platform?: NodeJS.Platform;\n execPath?: string;\n argv1?: string;\n existsSync?: (filePath: string) => boolean;\n realpathSync?: (filePath: string) => string;\n readFileSync?: (filePath: string, encoding: 'utf-8') => string;\n resolvePackageJson?: () => string;\n resolvePackageEntry?: () => string;\n piPackageRoot?: string;\n env?: NodeJS.ProcessEnv;\n}\n\ninterface PiSpawnCommand {\n command: string;\n args: string[];\n}\n\nfunction isRunnableNodeScript(filePath: string, existsSync: (filePath: string) => boolean): boolean {\n if (!existsSync(filePath)) return false;\n return NODE_SCRIPT_EXTENSIONS.test(filePath);\n}\n\nfunction normalizePath(filePath: string): string {\n return path.isAbsolute(filePath) ? filePath : path.resolve(filePath);\n}\n\n/** A concrete Pi CLI script this process can hand to Node, or undefined. */\nexport function resolvePiCliScript(deps: PiSpawnDeps = {}): string | undefined {\n const existsSync = deps.existsSync ?? fs.existsSync;\n const realpathSync = deps.realpathSync ?? fs.realpathSync;\n const readFileSync =\n deps.readFileSync ?? ((filePath: string, encoding: 'utf-8') => fs.readFileSync(filePath, encoding));\n const argv1 = deps.argv1 ?? process.argv[1];\n\n // Reuse our own entry point only when it provably belongs to the Pi package.\n if (argv1) {\n const argvPath = normalizePath(argv1);\n if (isRunnableNodeScript(argvPath, existsSync)) {\n try {\n const canonicalArgvPath = realpathSync(argvPath);\n if (isRunnableNodeScript(canonicalArgvPath, existsSync) && findPiPackageRootFromEntry(canonicalArgvPath)) {\n return canonicalArgvPath;\n }\n } catch {\n // Host package metadata is untrusted here; keep resolving the installed Pi CLI.\n }\n }\n }\n\n try {\n const resolvePackageJson =\n deps.resolvePackageJson ??\n (() => {\n const root = deps.piPackageRoot ?? resolvePiPackageRoot();\n if (root) return path.join(root, PACKAGE_MANIFEST_NAME);\n const packageRoot = deps.resolvePackageEntry\n ? findPiPackageRootFromEntry(deps.resolvePackageEntry())\n : resolveInstalledPiPackageRoot();\n if (!packageRoot) throw new Error(`Could not resolve ${PI_CODING_AGENT_PACKAGE} package root`);\n return path.join(packageRoot, PACKAGE_MANIFEST_NAME);\n });\n const packageJsonPath = resolvePackageJson();\n const manifest: unknown = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const binPath = readManifestBinPath(manifest);\n if (!binPath) return undefined;\n const candidate = path.resolve(path.dirname(packageJsonPath), binPath);\n if (isRunnableNodeScript(candidate, existsSync)) {\n return candidate;\n }\n } catch {\n // Verified CLI resolution is optional; falling back to `pi` lets PATH handle execution.\n return undefined;\n }\n\n return undefined;\n}\n\nexport function getPiSpawnCommand(args: string[], deps: PiSpawnDeps = {}): PiSpawnCommand {\n const env = deps.env ?? process.env;\n const piBinary = env[PI_SUBAGENT_PI_BINARY_ENV]?.trim();\n if (piBinary) {\n return { command: piBinary, args };\n }\n\n const piCliPath = resolvePiCliScript(deps);\n if (piCliPath) {\n return {\n command: deps.execPath ?? process.execPath,\n args: [piCliPath, ...args],\n };\n }\n\n return { command: PI_PATH_COMMAND, args };\n}\n"],"mappings":"2LAiCA,SAAgB,EAA2B,EAAwC,CACjF,IAAI,EAAMA,EAAK,QAAQ,EAAW,CAClC,KAAO,IAAQA,EAAK,QAAQ,EAAI,EAAE,CAChC,IAAM,EAAkBA,EAAK,KAAK,EAAK,eAAsB,CAC7D,GAAIC,EAAG,WAAW,EAAgB,EAE5B,EADsB,KAAK,MAAMA,EAAG,aAAa,EAAiB,QAAQ,CACjD,CAAC,GAAA,kCAA8B,OAAO,EAErE,EAAMD,EAAK,QAAQ,EAAI,EAK3B,SAAS,EAAiB,EAAuC,CAC/D,GAAI,OAAO,GAAa,WAAY,EAAmB,OACvD,IAAM,EAAiB,EAAgC,KACvD,OAAO,OAAO,GAAS,SAAW,EAAO,IAAA,GA0B3C,SAAgB,GAA2C,CACzD,GAAI,CACF,IAAM,EAAQ,QAAQ,KAAK,GAC3B,OAAO,EAAQ,EAA2BC,EAAG,aAAa,EAAM,CAAC,CAAG,IAAA,QAC9D,CAEN"}
@@ -0,0 +1,2 @@
1
+ import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import{init_env as t}from"../../env.mjs";import*as n from"node:fs";import*as r from"node:path";import"node:url";function i(e){let t=r.dirname(e);for(;t!==r.dirname(t);){let e=r.join(t,s);if(n.existsSync(e)&&a(JSON.parse(n.readFileSync(e,`utf-8`)))===`@earendil-works/pi-coding-agent`)return t;t=r.dirname(t)}}function a(e){if(typeof e!=`object`||!e)return;let t=e.name;return typeof t==`string`?t:void 0}function o(){try{let e=process.argv[1];return e?i(n.realpathSync(e)):void 0}catch{return}}var s,c=e((()=>{t(),s=`package.json`}));c();export{c as init_piSpawn,o as resolvePiPackageRoot};
2
+ //# sourceMappingURL=piSpawn.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"piSpawn.mjs","names":[],"sources":["../../../src/runs/shared/piSpawn.ts"],"sourcesContent":["/**\n * How to invoke the Pi CLI for a child process.\n *\n * DESIGN PATTERNS:\n * - Three resolution tiers, most explicit first: an operator override env var,\n * then a verified script path run through this process's own Node binary, then\n * bare `pi` on PATH. Running the resolved script under `process.execPath` means\n * a child gets the same Node version as its parent, which a shebang would not\n * guarantee\n * - Every resolution step is best-effort. Failing to identify the installed CLI\n * is not an error, it just falls through to the next tier\n * - Filesystem and resolver calls are injectable, because ESM module namespaces\n * are frozen and `node:fs` cannot otherwise be substituted in a test\n *\n * AVOID:\n * - Trusting `process.argv[1]` without confirming it really is the Pi CLI. The\n * host embedding this package has its own entry point there, and spawning that\n * would run the host again rather than the agent\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { PI_SUBAGENT_PI_BINARY_ENV } from '../../env.ts';\n\nexport const PI_CODING_AGENT_PACKAGE = '@earendil-works/pi-coding-agent';\n\nconst PACKAGE_MANIFEST_NAME = 'package.json';\nconst PI_BIN_FIELD_NAME = 'pi';\nconst PI_PATH_COMMAND = 'pi';\nconst NODE_SCRIPT_EXTENSIONS = /\\.(?:mjs|cjs|js)$/i;\n\n/** Walk up from an entry point to the package root that declares the Pi CLI. */\nexport function findPiPackageRootFromEntry(entryPoint: string): string | undefined {\n let dir = path.dirname(entryPoint);\n while (dir !== path.dirname(dir)) {\n const packageJsonPath = path.join(dir, PACKAGE_MANIFEST_NAME);\n if (fs.existsSync(packageJsonPath)) {\n const manifest: unknown = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));\n if (readManifestName(manifest) === PI_CODING_AGENT_PACKAGE) return dir;\n }\n dir = path.dirname(dir);\n }\n return undefined;\n}\n\nfunction readManifestName(manifest: unknown): string | undefined {\n if (typeof manifest !== 'object' || manifest === null) return undefined;\n const name: unknown = (manifest as { name?: unknown }).name;\n return typeof name === 'string' ? name : undefined;\n}\n\n/**\n * The `bin` entry to spawn, from a package manifest of unknown shape.\n *\n * npm allows `bin` to be either a bare string or a map. The named `pi` entry\n * wins; any single other entry is accepted because a renamed fork still exposes\n * exactly one executable.\n */\nfunction readManifestBinPath(manifest: unknown): string | undefined {\n if (typeof manifest !== 'object' || manifest === null) return undefined;\n const bin: unknown = (manifest as { bin?: unknown }).bin;\n if (typeof bin === 'string') return bin;\n if (typeof bin !== 'object' || bin === null) return undefined;\n const entries: Record<string, unknown> = bin as Record<string, unknown>;\n const named: unknown = entries[PI_BIN_FIELD_NAME];\n if (typeof named === 'string') return named;\n const first = Object.values(entries).find((value): value is string => typeof value === 'string');\n return first;\n}\n\nexport function resolveInstalledPiPackageRoot(): string | undefined {\n return findPiPackageRootFromEntry(fileURLToPath(import.meta.resolve(PI_CODING_AGENT_PACKAGE)));\n}\n\nexport function resolvePiPackageRoot(): string | undefined {\n try {\n const entry = process.argv[1];\n return entry ? findPiPackageRootFromEntry(fs.realpathSync(entry)) : undefined;\n } catch {\n // process.argv[1] probing is best-effort; callers fall back to PATH or package resolution.\n return undefined;\n }\n}\n\nexport interface PiSpawnDeps {\n platform?: NodeJS.Platform;\n execPath?: string;\n argv1?: string;\n existsSync?: (filePath: string) => boolean;\n realpathSync?: (filePath: string) => string;\n readFileSync?: (filePath: string, encoding: 'utf-8') => string;\n resolvePackageJson?: () => string;\n resolvePackageEntry?: () => string;\n piPackageRoot?: string;\n env?: NodeJS.ProcessEnv;\n}\n\ninterface PiSpawnCommand {\n command: string;\n args: string[];\n}\n\nfunction isRunnableNodeScript(filePath: string, existsSync: (filePath: string) => boolean): boolean {\n if (!existsSync(filePath)) return false;\n return NODE_SCRIPT_EXTENSIONS.test(filePath);\n}\n\nfunction normalizePath(filePath: string): string {\n return path.isAbsolute(filePath) ? filePath : path.resolve(filePath);\n}\n\n/** A concrete Pi CLI script this process can hand to Node, or undefined. */\nexport function resolvePiCliScript(deps: PiSpawnDeps = {}): string | undefined {\n const existsSync = deps.existsSync ?? fs.existsSync;\n const realpathSync = deps.realpathSync ?? fs.realpathSync;\n const readFileSync =\n deps.readFileSync ?? ((filePath: string, encoding: 'utf-8') => fs.readFileSync(filePath, encoding));\n const argv1 = deps.argv1 ?? process.argv[1];\n\n // Reuse our own entry point only when it provably belongs to the Pi package.\n if (argv1) {\n const argvPath = normalizePath(argv1);\n if (isRunnableNodeScript(argvPath, existsSync)) {\n try {\n const canonicalArgvPath = realpathSync(argvPath);\n if (isRunnableNodeScript(canonicalArgvPath, existsSync) && findPiPackageRootFromEntry(canonicalArgvPath)) {\n return canonicalArgvPath;\n }\n } catch {\n // Host package metadata is untrusted here; keep resolving the installed Pi CLI.\n }\n }\n }\n\n try {\n const resolvePackageJson =\n deps.resolvePackageJson ??\n (() => {\n const root = deps.piPackageRoot ?? resolvePiPackageRoot();\n if (root) return path.join(root, PACKAGE_MANIFEST_NAME);\n const packageRoot = deps.resolvePackageEntry\n ? findPiPackageRootFromEntry(deps.resolvePackageEntry())\n : resolveInstalledPiPackageRoot();\n if (!packageRoot) throw new Error(`Could not resolve ${PI_CODING_AGENT_PACKAGE} package root`);\n return path.join(packageRoot, PACKAGE_MANIFEST_NAME);\n });\n const packageJsonPath = resolvePackageJson();\n const manifest: unknown = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const binPath = readManifestBinPath(manifest);\n if (!binPath) return undefined;\n const candidate = path.resolve(path.dirname(packageJsonPath), binPath);\n if (isRunnableNodeScript(candidate, existsSync)) {\n return candidate;\n }\n } catch {\n // Verified CLI resolution is optional; falling back to `pi` lets PATH handle execution.\n return undefined;\n }\n\n return undefined;\n}\n\nexport function getPiSpawnCommand(args: string[], deps: PiSpawnDeps = {}): PiSpawnCommand {\n const env = deps.env ?? process.env;\n const piBinary = env[PI_SUBAGENT_PI_BINARY_ENV]?.trim();\n if (piBinary) {\n return { command: piBinary, args };\n }\n\n const piCliPath = resolvePiCliScript(deps);\n if (piCliPath) {\n return {\n command: deps.execPath ?? process.execPath,\n args: [piCliPath, ...args],\n };\n }\n\n return { command: PI_PATH_COMMAND, args };\n}\n"],"mappings":"gLAiCA,SAAgB,EAA2B,EAAwC,CACjF,IAAI,EAAM,EAAK,QAAQ,EAAW,CAClC,KAAO,IAAQ,EAAK,QAAQ,EAAI,EAAE,CAChC,IAAM,EAAkB,EAAK,KAAK,EAAK,EAAsB,CAC7D,GAAI,EAAG,WAAW,EAAgB,EAE5B,EADsB,KAAK,MAAM,EAAG,aAAa,EAAiB,QAAQ,CACjD,CAAC,GAAA,kCAA8B,OAAO,EAErE,EAAM,EAAK,QAAQ,EAAI,EAK3B,SAAS,EAAiB,EAAuC,CAC/D,GAAI,OAAO,GAAa,WAAY,EAAmB,OACvD,IAAM,EAAiB,EAAgC,KACvD,OAAO,OAAO,GAAS,SAAW,EAAO,IAAA,GA0B3C,SAAgB,GAA2C,CACzD,GAAI,CACF,IAAM,EAAQ,QAAQ,KAAK,GAC3B,OAAO,EAAQ,EAA2B,EAAG,aAAa,EAAM,CAAC,CAAG,IAAA,QAC9D,CAEN,2BA1DqD,CAInD,EAAwB"}
@@ -0,0 +1,2 @@
1
+ require(`../../_virtual/_rolldown/runtime.cjs`);const e=(0,require(`@agimon-ai/doompi-telemetry`).createDoomTelemetry)({serviceName:`doom-team-concurrency`,packageName:`@agimon-ai/doompi-team`,env:process.env,enableLogs:!0,enableTraces:!0});async function t(t,n){let r=Date.now(),i=Array.from({length:t.length}),a=Math.max(1,Math.min(n,t.length||1)),o=0;async function s(){for(;;){let e=o;if(o+=1,e>=t.length)return;try{i[e]={status:`fulfilled`,value:await t[e]()}}catch(t){i[e]={status:`rejected`,reason:t}}}}return e.recordEvent(`doom_team.concurrency_started`,{"team.task_count":t.length,"team.concurrency":a}),await Promise.all(Array.from({length:a},()=>s())),e.recordEvent(`doom_team.concurrency_finished`,{"team.task_count":t.length,"team.concurrency":a,"team.failure_count":i.filter(e=>e?.status===`rejected`).length,duration_ms:Date.now()-r,outcome:`completed`}),i}exports.runWithConcurrency=t;
2
+ //# sourceMappingURL=runWithConcurrency.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runWithConcurrency.cjs","names":[],"sources":["../../../src/runs/shared/runWithConcurrency.ts"],"sourcesContent":["/**\n * Runs a batch of async operations with at most N in flight at once, and\n * always settles all of them - one rejection never aborts its peers.\n *\n * WHY THIS EXISTS, RATHER THAN BEING INLINED INTO ITS ONE CALLER:\n * `spawnPlan.ts`'s PARALLEL mode needs exactly this shape (fire up to\n * `concurrency` tasks at once, wait for a slot to free before starting the\n * next, return every outcome regardless of individual failure), and it is a\n * property worth testing directly rather than only through spawn-plan's own\n * fixtures: \"at most N in flight at any moment\" and \"one rejection does not\n * abort its peers\" are each independently verifiable here, which is more\n * precise than inferring them from a higher-level test that also exercises\n * agent resolution, depth checks, and status writes.\n *\n * DELIBERATELY MINIMAL:\n * Bounded concurrency and settle-all, nothing else - no priority ordering\n * beyond FIFO start order, no cancellation, no `AbortSignal`. Add any of\n * those only when a real caller needs them, not speculatively.\n */\n\nimport { createDoomTelemetry } from '@agimon-ai/doompi-telemetry';\n\nconst telemetry = createDoomTelemetry({\n serviceName: 'doom-team-concurrency',\n packageName: '@agimon-ai/doompi-team',\n env: process.env,\n enableLogs: true,\n enableTraces: true,\n});\n\nexport type ConcurrencyOutcome<T> = { status: 'fulfilled'; value: T } | { status: 'rejected'; reason: unknown };\n\n/**\n * Runs `factories` (each called at most once, lazily, only once a slot is\n * free) with at most `concurrency` in flight at a time. Resolves once every\n * factory has settled, in the SAME ORDER as `factories` regardless of which\n * one finished first - a caller zipping results back against its own input\n * list does not need to track indices itself.\n */\nexport async function runWithConcurrency<T>(\n factories: ReadonlyArray<() => Promise<T>>,\n concurrency: number,\n): Promise<ConcurrencyOutcome<T>[]> {\n const startedAt = Date.now();\n const results: ConcurrencyOutcome<T>[] = Array.from({ length: factories.length });\n const effectiveConcurrency = Math.max(1, Math.min(concurrency, factories.length || 1));\n let nextIndex = 0;\n\n async function worker(): Promise<void> {\n for (;;) {\n const index = nextIndex;\n nextIndex += 1;\n if (index >= factories.length) return;\n try {\n results[index] = { status: 'fulfilled', value: await factories[index]!() };\n } catch (reason) {\n results[index] = { status: 'rejected', reason };\n }\n }\n }\n\n void telemetry.recordEvent('doom_team.concurrency_started', {\n 'team.task_count': factories.length,\n 'team.concurrency': effectiveConcurrency,\n });\n await Promise.all(Array.from({ length: effectiveConcurrency }, () => worker()));\n void telemetry.recordEvent('doom_team.concurrency_finished', {\n 'team.task_count': factories.length,\n 'team.concurrency': effectiveConcurrency,\n 'team.failure_count': results.filter((result) => result?.status === 'rejected').length,\n duration_ms: Date.now() - startedAt,\n outcome: 'completed',\n });\n return results;\n}\n"],"mappings":"gDAsBA,MAAM,GAAA,wCAAA,CAAA,qBAAgC,CACpC,YAAa,wBACb,YAAa,yBACb,IAAK,QAAQ,IACb,WAAY,GACZ,aAAc,GACf,CAAC,CAWF,eAAsB,EACpB,EACA,EACkC,CAClC,IAAM,EAAY,KAAK,KAAK,CACtB,EAAmC,MAAM,KAAK,CAAE,OAAQ,EAAU,OAAQ,CAAC,CAC3E,EAAuB,KAAK,IAAI,EAAG,KAAK,IAAI,EAAa,EAAU,QAAU,EAAE,CAAC,CAClF,EAAY,EAEhB,eAAe,GAAwB,CACrC,OAAS,CACP,IAAM,EAAQ,EAEd,GADA,GAAa,EACT,GAAS,EAAU,OAAQ,OAC/B,GAAI,CACF,EAAQ,GAAS,CAAE,OAAQ,YAAa,MAAO,MAAM,EAAU,IAAS,CAAE,OACnE,EAAQ,CACf,EAAQ,GAAS,CAAE,OAAQ,WAAY,SAAQ,GAiBrD,OAZK,EAAU,YAAY,gCAAiC,CAC1D,kBAAmB,EAAU,OAC7B,mBAAoB,EACrB,CAAC,CACF,MAAM,QAAQ,IAAI,MAAM,KAAK,CAAE,OAAQ,EAAsB,KAAQ,GAAQ,CAAC,CAAC,CAC1E,EAAU,YAAY,iCAAkC,CAC3D,kBAAmB,EAAU,OAC7B,mBAAoB,EACpB,qBAAsB,EAAQ,OAAQ,GAAW,GAAQ,SAAW,WAAW,CAAC,OAChF,YAAa,KAAK,KAAK,CAAG,EAC1B,QAAS,YACV,CAAC,CACK"}
@@ -0,0 +1,2 @@
1
+ import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import{createDoomTelemetry as t}from"@agimon-ai/doompi-telemetry";async function n(e,t){let n=Date.now(),i=Array.from({length:e.length}),a=Math.max(1,Math.min(t,e.length||1)),o=0;async function s(){for(;;){let t=o;if(o+=1,t>=e.length)return;try{i[t]={status:`fulfilled`,value:await e[t]()}}catch(e){i[t]={status:`rejected`,reason:e}}}}return r.recordEvent(`doom_team.concurrency_started`,{"team.task_count":e.length,"team.concurrency":a}),await Promise.all(Array.from({length:a},()=>s())),r.recordEvent(`doom_team.concurrency_finished`,{"team.task_count":e.length,"team.concurrency":a,"team.failure_count":i.filter(e=>e?.status===`rejected`).length,duration_ms:Date.now()-n,outcome:`completed`}),i}var r,i=e((()=>{r=t({serviceName:`doom-team-concurrency`,packageName:`@agimon-ai/doompi-team`,env:process.env,enableLogs:!0,enableTraces:!0})}));i();export{i as init_runWithConcurrency,n as runWithConcurrency};
2
+ //# sourceMappingURL=runWithConcurrency.mjs.map