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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (727) hide show
  1. package/README.md +33 -17
  2. package/dist/adapters/asyncJobTracker.cjs +2 -0
  3. package/dist/adapters/asyncJobTracker.cjs.map +1 -0
  4. package/dist/adapters/asyncJobTracker.mjs +2 -0
  5. package/dist/adapters/asyncJobTracker.mjs.map +1 -0
  6. package/dist/adapters/atomicJson.cjs +2 -0
  7. package/dist/adapters/atomicJson.cjs.map +1 -0
  8. package/dist/adapters/atomicJson.mjs +2 -0
  9. package/dist/adapters/atomicJson.mjs.map +1 -0
  10. package/dist/adapters/pi/extension.cjs +2 -0
  11. package/dist/adapters/pi/extension.cjs.map +1 -0
  12. package/dist/adapters/pi/extension.mjs +2 -0
  13. package/dist/adapters/pi/extension.mjs.map +1 -0
  14. package/dist/adapters/pollScheduler.cjs +2 -0
  15. package/dist/adapters/pollScheduler.cjs.map +1 -0
  16. package/dist/adapters/pollScheduler.mjs +2 -0
  17. package/dist/adapters/pollScheduler.mjs.map +1 -0
  18. package/dist/adapters/process/childTranscript.cjs +5 -0
  19. package/dist/adapters/process/childTranscript.cjs.map +1 -0
  20. package/dist/adapters/process/childTranscript.mjs +5 -0
  21. package/dist/adapters/process/childTranscript.mjs.map +1 -0
  22. package/dist/adapters/process/env.cjs +2 -0
  23. package/dist/adapters/process/env.cjs.map +1 -0
  24. package/dist/adapters/process/env.d.cts +69 -0
  25. package/dist/adapters/process/env.d.cts.map +1 -0
  26. package/dist/adapters/process/env.d.mts +69 -0
  27. package/dist/adapters/process/env.d.mts.map +1 -0
  28. package/dist/adapters/process/env.mjs +2 -0
  29. package/dist/adapters/process/env.mjs.map +1 -0
  30. package/dist/adapters/process/sdkRunnerEntry.cjs +2 -0
  31. package/dist/adapters/process/sdkRunnerEntry.cjs.map +1 -0
  32. package/dist/adapters/process/sdkRunnerEntry.d.cts +5 -0
  33. package/dist/adapters/process/sdkRunnerEntry.d.cts.map +1 -0
  34. package/dist/adapters/process/sdkRunnerEntry.d.mts +5 -0
  35. package/dist/adapters/process/sdkRunnerEntry.d.mts.map +1 -0
  36. package/dist/adapters/process/sdkRunnerEntry.mjs +2 -0
  37. package/dist/adapters/process/sdkRunnerEntry.mjs.map +1 -0
  38. package/dist/adapters/processTerminal.cjs +2 -0
  39. package/dist/adapters/processTerminal.cjs.map +1 -0
  40. package/dist/adapters/processTerminal.mjs +2 -0
  41. package/dist/adapters/processTerminal.mjs.map +1 -0
  42. package/dist/adapters/resultWatcher.cjs +2 -0
  43. package/dist/adapters/resultWatcher.cjs.map +1 -0
  44. package/dist/adapters/resultWatcher.mjs +2 -0
  45. package/dist/adapters/resultWatcher.mjs.map +1 -0
  46. package/dist/adapters/runIdResolver.cjs +2 -0
  47. package/dist/adapters/runIdResolver.cjs.map +1 -0
  48. package/dist/adapters/runIdResolver.mjs +2 -0
  49. package/dist/adapters/runIdResolver.mjs.map +1 -0
  50. package/dist/adapters/runRegistry.cjs +2 -0
  51. package/dist/adapters/runRegistry.cjs.map +1 -0
  52. package/dist/adapters/runRegistry.mjs +2 -0
  53. package/dist/adapters/runRegistry.mjs.map +1 -0
  54. package/dist/adapters/scopeOwner.cjs +2 -0
  55. package/dist/adapters/scopeOwner.cjs.map +1 -0
  56. package/dist/adapters/scopeOwner.mjs +2 -0
  57. package/dist/adapters/scopeOwner.mjs.map +1 -0
  58. package/dist/adapters/staleRunReconciler.cjs +2 -0
  59. package/dist/adapters/staleRunReconciler.cjs.map +1 -0
  60. package/dist/adapters/staleRunReconciler.mjs +2 -0
  61. package/dist/adapters/staleRunReconciler.mjs.map +1 -0
  62. package/dist/adapters/statusReader.cjs +2 -0
  63. package/dist/adapters/statusReader.cjs.map +1 -0
  64. package/dist/adapters/statusReader.mjs +2 -0
  65. package/dist/adapters/statusReader.mjs.map +1 -0
  66. package/dist/adapters/suspendedRuns.cjs +6 -0
  67. package/dist/adapters/suspendedRuns.cjs.map +1 -0
  68. package/dist/adapters/suspendedRuns.mjs +6 -0
  69. package/dist/adapters/suspendedRuns.mjs.map +1 -0
  70. package/dist/api/backgroundWork.cjs +1 -1
  71. package/dist/api/backgroundWork.d.cts +2 -2
  72. package/dist/api/backgroundWork.d.mts +2 -2
  73. package/dist/api/backgroundWork.mjs +1 -1
  74. package/dist/api/capabilityCeiling.cjs +1 -1
  75. package/dist/api/capabilityCeiling.d.cts +3 -3
  76. package/dist/api/capabilityCeiling.d.mts +3 -3
  77. package/dist/api/capabilityCeiling.mjs +1 -2
  78. package/dist/api/delegation.cjs +1 -1
  79. package/dist/api/delegation.d.cts +1 -1
  80. package/dist/api/delegation.d.mts +1 -1
  81. package/dist/api/delegation.mjs +1 -1
  82. package/dist/api/teamSnapshot.cjs +1 -1
  83. package/dist/api/teamSnapshot.d.cts +2 -2
  84. package/dist/api/teamSnapshot.d.mts +2 -2
  85. package/dist/api/teamSnapshot.mjs +1 -2
  86. package/dist/commands/slash/chainExpression.cjs.map +1 -0
  87. package/dist/commands/slash/chainExpression.mjs.map +1 -0
  88. package/dist/commands/slash/doctor.cjs +5 -0
  89. package/dist/commands/slash/doctor.cjs.map +1 -0
  90. package/dist/commands/slash/doctor.mjs +5 -0
  91. package/dist/{slash/doctor.cjs.map → commands/slash/doctor.mjs.map} +1 -1
  92. package/dist/{slash → commands/slash}/slashCommands.cjs +1 -1
  93. package/dist/commands/slash/slashCommands.cjs.map +1 -0
  94. package/dist/{slash → commands/slash}/slashCommands.mjs +2 -2
  95. package/dist/commands/slash/slashCommands.mjs.map +1 -0
  96. package/dist/commands/slash/spawnRequestMapping.cjs.map +1 -0
  97. package/dist/commands/slash/spawnRequestMapping.mjs.map +1 -0
  98. package/dist/commands/slash/subagentLaunch.cjs +2 -0
  99. package/dist/commands/slash/subagentLaunch.cjs.map +1 -0
  100. package/dist/commands/slash/subagentLaunch.mjs +2 -0
  101. package/dist/commands/slash/subagentLaunch.mjs.map +1 -0
  102. package/dist/container/globalBridge.cjs.map +1 -1
  103. package/dist/container/globalBridge.d.cts +1 -1
  104. package/dist/container/globalBridge.d.mts +1 -1
  105. package/dist/container/globalBridge.mjs.map +1 -1
  106. package/dist/container/index.cjs +1 -1
  107. package/dist/container/index.cjs.map +1 -1
  108. package/dist/container/index.d.cts +2 -1
  109. package/dist/container/index.d.cts.map +1 -1
  110. package/dist/container/index.d.mts +2 -1
  111. package/dist/container/index.d.mts.map +1 -1
  112. package/dist/container/index.mjs +1 -1
  113. package/dist/container/index.mjs.map +1 -1
  114. package/dist/container/modules/agents.cjs +1 -1
  115. package/dist/container/modules/agents.cjs.map +1 -1
  116. package/dist/container/modules/agents.mjs +1 -1
  117. package/dist/container/modules/agents.mjs.map +1 -1
  118. package/dist/container/modules/core.cjs +1 -1
  119. package/dist/container/modules/core.cjs.map +1 -1
  120. package/dist/container/modules/core.mjs +1 -1
  121. package/dist/container/modules/core.mjs.map +1 -1
  122. package/dist/container/modules/extensions.cjs +1 -1
  123. package/dist/container/modules/extensions.cjs.map +1 -1
  124. package/dist/container/modules/extensions.mjs +1 -1
  125. package/dist/container/modules/extensions.mjs.map +1 -1
  126. package/dist/container/modules/intercom.cjs +1 -1
  127. package/dist/container/modules/intercom.cjs.map +1 -1
  128. package/dist/container/modules/intercom.mjs +1 -1
  129. package/dist/container/modules/intercom.mjs.map +1 -1
  130. package/dist/container/modules/runs.cjs +1 -1
  131. package/dist/container/modules/runs.cjs.map +1 -1
  132. package/dist/container/modules/runs.mjs +1 -1
  133. package/dist/container/modules/runs.mjs.map +1 -1
  134. package/dist/container/types.cjs +1 -1
  135. package/dist/container/types.cjs.map +1 -1
  136. package/dist/container/types.d.cts +1 -0
  137. package/dist/container/types.d.cts.map +1 -1
  138. package/dist/container/types.d.mts +1 -0
  139. package/dist/container/types.d.mts.map +1 -1
  140. package/dist/container/types.mjs +1 -1
  141. package/dist/container/types.mjs.map +1 -1
  142. package/dist/env.cjs +1 -2
  143. package/dist/env.d.cts +2 -65
  144. package/dist/env.d.mts +2 -65
  145. package/dist/env.mjs +1 -1
  146. package/dist/env.mjs.map +1 -1
  147. package/dist/extensions/config.cjs.map +1 -1
  148. package/dist/extensions/config.mjs.map +1 -1
  149. package/dist/extensions/delegationBridge.cjs.map +1 -1
  150. package/dist/extensions/delegationBridge.mjs.map +1 -1
  151. package/dist/extensions/doom.cjs +1 -1
  152. package/dist/extensions/doom.cjs.map +1 -1
  153. package/dist/extensions/doom.mjs +1 -1
  154. package/dist/extensions/doom.mjs.map +1 -1
  155. package/dist/extensions/fablePlanBridge.cjs +1 -1
  156. package/dist/extensions/fablePlanBridge.cjs.map +1 -1
  157. package/dist/extensions/fablePlanBridge.mjs +1 -1
  158. package/dist/extensions/fablePlanBridge.mjs.map +1 -1
  159. package/dist/extensions/managementActions.cjs +1 -1
  160. package/dist/extensions/managementActions.cjs.map +1 -1
  161. package/dist/extensions/managementActions.mjs +1 -1
  162. package/dist/extensions/managementActions.mjs.map +1 -1
  163. package/dist/extensions/operationJournal.cjs +1 -1
  164. package/dist/extensions/operationJournal.cjs.map +1 -1
  165. package/dist/extensions/operationJournal.mjs +1 -1
  166. package/dist/extensions/operationJournal.mjs.map +1 -1
  167. package/dist/extensions/orchestratorPrompt.cjs +5 -6
  168. package/dist/extensions/orchestratorPrompt.cjs.map +1 -1
  169. package/dist/extensions/orchestratorPrompt.mjs +5 -6
  170. package/dist/extensions/orchestratorPrompt.mjs.map +1 -1
  171. package/dist/extensions/schemas.mjs.map +1 -1
  172. package/dist/extensions/spawnPlan.cjs +3 -2
  173. package/dist/extensions/spawnPlan.cjs.map +1 -1
  174. package/dist/extensions/spawnPlan.mjs +3 -2
  175. package/dist/extensions/spawnPlan.mjs.map +1 -1
  176. package/dist/extensions/standard.cjs +1 -1
  177. package/dist/extensions/standard.cjs.map +1 -1
  178. package/dist/extensions/standard.mjs +1 -1
  179. package/dist/extensions/standard.mjs.map +1 -1
  180. package/dist/extensions/statusViews.cjs +1 -1
  181. package/dist/extensions/statusViews.cjs.map +1 -1
  182. package/dist/extensions/statusViews.mjs +2 -2
  183. package/dist/extensions/statusViews.mjs.map +1 -1
  184. package/dist/extensions/subagentPromptRuntime.cjs +11 -11
  185. package/dist/extensions/subagentPromptRuntime.cjs.map +1 -1
  186. package/dist/extensions/subagentPromptRuntime.d.cts.map +1 -1
  187. package/dist/extensions/subagentPromptRuntime.d.mts.map +1 -1
  188. package/dist/extensions/subagentPromptRuntime.mjs +5 -5
  189. package/dist/extensions/subagentPromptRuntime.mjs.map +1 -1
  190. package/dist/extensions/subagentTool.cjs +5 -6
  191. package/dist/extensions/subagentTool.cjs.map +1 -1
  192. package/dist/extensions/subagentTool.mjs +5 -6
  193. package/dist/extensions/subagentTool.mjs.map +1 -1
  194. package/dist/extensions/toolDescription.cjs +1 -1
  195. package/dist/extensions/toolDescription.cjs.map +1 -1
  196. package/dist/extensions/toolDescription.mjs +1 -1
  197. package/dist/extensions/toolDescription.mjs.map +1 -1
  198. package/dist/index.cjs +1 -1
  199. package/dist/index.cjs.map +1 -1
  200. package/dist/index.d.cts +2 -2
  201. package/dist/index.d.cts.map +1 -1
  202. package/dist/index.d.mts +2 -2
  203. package/dist/index.d.mts.map +1 -1
  204. package/dist/index.mjs +1 -1
  205. package/dist/index.mjs.map +1 -1
  206. package/dist/runs/background/cliRunnerEntry.cjs +1 -2
  207. package/dist/runs/background/cliRunnerEntry.mjs +1 -2
  208. package/dist/runs/sdkRunnerEntry.cjs +1 -2
  209. package/dist/runs/sdkRunnerEntry.d.cts +2 -1
  210. package/dist/runs/sdkRunnerEntry.d.mts +2 -1
  211. package/dist/runs/sdkRunnerEntry.mjs +1 -2
  212. package/dist/schemas/team/backgroundWork.cjs +2 -0
  213. package/dist/schemas/team/backgroundWork.cjs.map +1 -0
  214. package/dist/{protocol → schemas/team}/backgroundWork.d.cts +2 -2
  215. package/dist/schemas/team/backgroundWork.d.cts.map +1 -0
  216. package/dist/{protocol → schemas/team}/backgroundWork.d.mts +2 -2
  217. package/dist/schemas/team/backgroundWork.d.mts.map +1 -0
  218. package/dist/schemas/team/backgroundWork.mjs +2 -0
  219. package/dist/{protocol/backgroundWork.cjs.map → schemas/team/backgroundWork.mjs.map} +1 -1
  220. package/dist/schemas/team/capabilityCeiling.cjs +2 -0
  221. package/dist/schemas/team/capabilityCeiling.cjs.map +1 -0
  222. package/dist/{protocol → schemas/team}/capabilityCeiling.d.cts +3 -3
  223. package/dist/schemas/team/capabilityCeiling.d.cts.map +1 -0
  224. package/dist/{protocol → schemas/team}/capabilityCeiling.d.mts +3 -3
  225. package/dist/schemas/team/capabilityCeiling.d.mts.map +1 -0
  226. package/dist/schemas/team/capabilityCeiling.mjs +2 -0
  227. package/dist/schemas/team/capabilityCeiling.mjs.map +1 -0
  228. package/dist/schemas/team/delegation.cjs.map +1 -0
  229. package/dist/{protocol → schemas/team}/delegation.d.cts +1 -1
  230. package/dist/schemas/team/delegation.d.cts.map +1 -0
  231. package/dist/{protocol → schemas/team}/delegation.d.mts +1 -1
  232. package/dist/schemas/team/delegation.d.mts.map +1 -0
  233. package/dist/schemas/team/delegation.mjs.map +1 -0
  234. package/dist/schemas/team/packageConfig.cjs +2 -0
  235. package/dist/schemas/team/packageConfig.cjs.map +1 -0
  236. package/dist/schemas/team/packageConfig.mjs +2 -0
  237. package/dist/schemas/team/packageConfig.mjs.map +1 -0
  238. package/dist/services/agents/discovery.cjs +2 -0
  239. package/dist/services/agents/discovery.cjs.map +1 -0
  240. package/dist/services/agents/discovery.mjs +2 -0
  241. package/dist/services/agents/discovery.mjs.map +1 -0
  242. package/dist/services/agents/frontmatter.cjs.map +1 -0
  243. package/dist/{agents → services/agents}/frontmatter.mjs +1 -1
  244. package/dist/services/agents/frontmatter.mjs.map +1 -0
  245. package/dist/services/agents/loader.cjs +2 -0
  246. package/dist/services/agents/loader.cjs.map +1 -0
  247. package/dist/services/agents/loader.mjs +2 -0
  248. package/dist/services/agents/loader.mjs.map +1 -0
  249. package/dist/services/agents/memory.cjs +3 -0
  250. package/dist/services/agents/memory.cjs.map +1 -0
  251. package/dist/{agents → services/agents}/memory.mjs +1 -1
  252. package/dist/services/agents/memory.mjs.map +1 -0
  253. package/dist/services/agents/projectRoot.cjs +2 -0
  254. package/dist/services/agents/projectRoot.cjs.map +1 -0
  255. package/dist/services/agents/projectRoot.mjs +2 -0
  256. package/dist/services/agents/projectRoot.mjs.map +1 -0
  257. package/dist/services/agents/settings.cjs +2 -0
  258. package/dist/services/agents/settings.cjs.map +1 -0
  259. package/dist/services/agents/settings.mjs +2 -0
  260. package/dist/services/agents/settings.mjs.map +1 -0
  261. package/dist/services/agents/skills.cjs +0 -0
  262. package/dist/services/agents/skills.cjs.map +1 -0
  263. package/dist/services/agents/skills.mjs +5 -0
  264. package/dist/services/agents/skills.mjs.map +1 -0
  265. package/dist/{agents → services/agents}/types.d.cts +4 -4
  266. package/dist/services/agents/types.d.cts.map +1 -0
  267. package/dist/{agents → services/agents}/types.d.mts +4 -4
  268. package/dist/services/agents/types.d.mts.map +1 -0
  269. package/dist/services/api/backgroundWork.cjs +1 -0
  270. package/dist/services/api/backgroundWork.d.cts +1 -0
  271. package/dist/services/api/backgroundWork.d.mts +1 -0
  272. package/dist/services/api/backgroundWork.mjs +1 -0
  273. package/dist/services/api/capabilityCeiling.cjs +1 -0
  274. package/dist/services/api/capabilityCeiling.d.cts +2 -0
  275. package/dist/services/api/capabilityCeiling.d.mts +2 -0
  276. package/dist/services/api/capabilityCeiling.mjs +2 -0
  277. package/dist/services/api/capabilityCeiling.mjs.map +1 -0
  278. package/dist/services/api/teamSnapshot.cjs +1 -0
  279. package/dist/services/api/teamSnapshot.d.cts +1 -0
  280. package/dist/services/api/teamSnapshot.d.mts +1 -0
  281. package/dist/services/api/teamSnapshot.mjs +2 -0
  282. package/dist/services/api/teamSnapshot.mjs.map +1 -0
  283. package/dist/services/intercom/intercomBridge.cjs.map +1 -0
  284. package/dist/services/intercom/intercomBridge.mjs.map +1 -0
  285. package/dist/services/intercom/nativeTeamChannel.cjs +5 -0
  286. package/dist/services/intercom/nativeTeamChannel.cjs.map +1 -0
  287. package/dist/{intercom → services/intercom}/nativeTeamChannel.d.cts +1 -1
  288. package/dist/services/intercom/nativeTeamChannel.d.cts.map +1 -0
  289. package/dist/{intercom → services/intercom}/nativeTeamChannel.d.mts +1 -1
  290. package/dist/services/intercom/nativeTeamChannel.d.mts.map +1 -0
  291. package/dist/services/intercom/nativeTeamChannel.mjs +5 -0
  292. package/dist/services/intercom/nativeTeamChannel.mjs.map +1 -0
  293. package/dist/services/intercom/supervisorControlChannel.cjs +2 -0
  294. package/dist/services/intercom/supervisorControlChannel.cjs.map +1 -0
  295. package/dist/{intercom → services/intercom}/supervisorControlChannel.mjs +1 -1
  296. package/dist/services/intercom/supervisorControlChannel.mjs.map +1 -0
  297. package/dist/services/runs/background/asyncExecution.cjs +2 -0
  298. package/dist/services/runs/background/asyncExecution.cjs.map +1 -0
  299. package/dist/services/runs/background/asyncExecution.mjs +2 -0
  300. package/dist/services/runs/background/asyncExecution.mjs.map +1 -0
  301. package/dist/services/runs/background/asyncJobTracker.cjs +1 -0
  302. package/dist/services/runs/background/asyncJobTracker.mjs +2 -0
  303. package/dist/services/runs/background/asyncJobTracker.mjs.map +1 -0
  304. package/dist/services/runs/background/cliRunnerEntry.cjs +2 -0
  305. package/dist/services/runs/background/cliRunnerEntry.cjs.map +1 -0
  306. package/dist/services/runs/background/cliRunnerEntry.mjs +2 -0
  307. package/dist/services/runs/background/cliRunnerEntry.mjs.map +1 -0
  308. package/dist/services/runs/background/completionBatcher.cjs.map +1 -0
  309. package/dist/services/runs/background/completionBatcher.mjs +2 -0
  310. package/dist/services/runs/background/completionBatcher.mjs.map +1 -0
  311. package/dist/{runs → services/runs}/background/notify.cjs +1 -1
  312. package/dist/services/runs/background/notify.cjs.map +1 -0
  313. package/dist/{runs → services/runs}/background/notify.mjs +1 -1
  314. package/dist/services/runs/background/notify.mjs.map +1 -0
  315. package/dist/services/runs/background/parentWatchdog.cjs.map +1 -0
  316. package/dist/services/runs/background/parentWatchdog.mjs.map +1 -0
  317. package/dist/services/runs/background/processTerminal.cjs +1 -0
  318. package/dist/services/runs/background/processTerminal.mjs +2 -0
  319. package/dist/services/runs/background/processTerminal.mjs.map +1 -0
  320. package/dist/services/runs/background/resultWatcher.cjs +1 -0
  321. package/dist/services/runs/background/resultWatcher.mjs +2 -0
  322. package/dist/services/runs/background/resultWatcher.mjs.map +1 -0
  323. package/dist/services/runs/background/runIdResolver.cjs +1 -0
  324. package/dist/services/runs/background/runIdResolver.mjs +2 -0
  325. package/dist/services/runs/background/runIdResolver.mjs.map +1 -0
  326. package/dist/services/runs/background/runnerBootstrap.cjs +2 -0
  327. package/dist/services/runs/background/runnerBootstrap.cjs.map +1 -0
  328. package/dist/services/runs/background/runnerBootstrap.mjs +2 -0
  329. package/dist/services/runs/background/runnerBootstrap.mjs.map +1 -0
  330. package/dist/services/runs/background/runnerExecution.cjs +2 -0
  331. package/dist/services/runs/background/runnerExecution.cjs.map +1 -0
  332. package/dist/services/runs/background/runnerExecution.mjs +2 -0
  333. package/dist/services/runs/background/runnerExecution.mjs.map +1 -0
  334. package/dist/{runs → services/runs}/background/runnerReporting.cjs +2 -2
  335. package/dist/services/runs/background/runnerReporting.cjs.map +1 -0
  336. package/dist/{runs → services/runs}/background/runnerReporting.mjs +2 -2
  337. package/dist/services/runs/background/runnerReporting.mjs.map +1 -0
  338. package/dist/services/runs/background/runnerTeamMembership.cjs +2 -0
  339. package/dist/services/runs/background/runnerTeamMembership.cjs.map +1 -0
  340. package/dist/services/runs/background/runnerTeamMembership.mjs +2 -0
  341. package/dist/services/runs/background/runnerTeamMembership.mjs.map +1 -0
  342. package/dist/services/runs/background/spawnHandshake.cjs +2 -0
  343. package/dist/services/runs/background/spawnHandshake.cjs.map +1 -0
  344. package/dist/services/runs/background/spawnHandshake.mjs +2 -0
  345. package/dist/services/runs/background/spawnHandshake.mjs.map +1 -0
  346. package/dist/services/runs/background/staleRunReconciler.cjs +1 -0
  347. package/dist/services/runs/background/staleRunReconciler.mjs +2 -0
  348. package/dist/services/runs/background/staleRunReconciler.mjs.map +1 -0
  349. package/dist/services/runs/background/statusReader.cjs +1 -0
  350. package/dist/services/runs/background/statusReader.mjs +2 -0
  351. package/dist/services/runs/background/statusReader.mjs.map +1 -0
  352. package/dist/services/runs/background/statusWriter.cjs +2 -0
  353. package/dist/services/runs/background/statusWriter.cjs.map +1 -0
  354. package/dist/services/runs/background/statusWriter.mjs +2 -0
  355. package/dist/services/runs/background/statusWriter.mjs.map +1 -0
  356. package/dist/services/runs/background/subagentWait.cjs +2 -0
  357. package/dist/services/runs/background/subagentWait.cjs.map +1 -0
  358. package/dist/services/runs/background/subagentWait.mjs +2 -0
  359. package/dist/services/runs/background/subagentWait.mjs.map +1 -0
  360. package/dist/{runs/background/terminalPersistence.mjs → services/runs/background/terminalPersistence.cjs} +2 -2
  361. package/dist/services/runs/background/terminalPersistence.cjs.map +1 -0
  362. package/dist/services/runs/background/terminalPersistence.mjs +2 -0
  363. package/dist/services/runs/background/terminalPersistence.mjs.map +1 -0
  364. package/dist/services/runs/extensionErrorTelemetry.cjs +2 -0
  365. package/dist/services/runs/extensionErrorTelemetry.cjs.map +1 -0
  366. package/dist/services/runs/extensionErrorTelemetry.mjs +2 -0
  367. package/dist/services/runs/extensionErrorTelemetry.mjs.map +1 -0
  368. package/dist/services/runs/registry/processGroup.cjs.map +1 -0
  369. package/dist/services/runs/registry/processGroup.mjs.map +1 -0
  370. package/dist/services/runs/registry/runRegistry.cjs +1 -0
  371. package/dist/services/runs/registry/runRegistry.mjs +2 -0
  372. package/dist/services/runs/registry/runRegistry.mjs.map +1 -0
  373. package/dist/services/runs/registry/sessionLifecycle.cjs +2 -0
  374. package/dist/services/runs/registry/sessionLifecycle.cjs.map +1 -0
  375. package/dist/services/runs/registry/sessionLifecycle.mjs +2 -0
  376. package/dist/services/runs/registry/sessionLifecycle.mjs.map +1 -0
  377. package/dist/services/runs/registry/suspendedRuns.cjs +1 -0
  378. package/dist/services/runs/registry/suspendedRuns.mjs +2 -0
  379. package/dist/services/runs/registry/suspendedRuns.mjs.map +1 -0
  380. package/dist/services/runs/sdkRunnerEntry.cjs +1 -0
  381. package/dist/services/runs/sdkRunnerEntry.mjs +1 -0
  382. package/dist/services/runs/shared/claudeFableProfile.cjs +4 -0
  383. package/dist/services/runs/shared/claudeFableProfile.cjs.map +1 -0
  384. package/dist/services/runs/shared/claudeFableProfile.mjs +4 -0
  385. package/dist/services/runs/shared/claudeFableProfile.mjs.map +1 -0
  386. package/dist/services/runs/shared/depthGuard.cjs +2 -0
  387. package/dist/services/runs/shared/depthGuard.cjs.map +1 -0
  388. package/dist/services/runs/shared/depthGuard.mjs +2 -0
  389. package/dist/services/runs/shared/depthGuard.mjs.map +1 -0
  390. package/dist/services/runs/shared/mcpDirectToolAllowlist.cjs +2 -0
  391. package/dist/services/runs/shared/mcpDirectToolAllowlist.cjs.map +1 -0
  392. package/dist/services/runs/shared/mcpDirectToolAllowlist.mjs +2 -0
  393. package/dist/services/runs/shared/mcpDirectToolAllowlist.mjs.map +1 -0
  394. package/dist/services/runs/shared/modelFallback.cjs +2 -0
  395. package/dist/services/runs/shared/modelFallback.cjs.map +1 -0
  396. package/dist/services/runs/shared/modelFallback.mjs +2 -0
  397. package/dist/services/runs/shared/modelFallback.mjs.map +1 -0
  398. package/dist/services/runs/shared/modelScope.cjs +2 -0
  399. package/dist/services/runs/shared/modelScope.cjs.map +1 -0
  400. package/dist/services/runs/shared/modelScope.mjs +2 -0
  401. package/dist/services/runs/shared/modelScope.mjs.map +1 -0
  402. package/dist/services/runs/shared/nestedPath.cjs +2 -0
  403. package/dist/services/runs/shared/nestedPath.cjs.map +1 -0
  404. package/dist/services/runs/shared/nestedPath.mjs +2 -0
  405. package/dist/services/runs/shared/nestedPath.mjs.map +1 -0
  406. package/dist/services/runs/shared/piArgs.cjs +2 -0
  407. package/dist/services/runs/shared/piArgs.cjs.map +1 -0
  408. package/dist/services/runs/shared/piArgs.mjs +2 -0
  409. package/dist/services/runs/shared/piArgs.mjs.map +1 -0
  410. package/dist/services/runs/shared/piSpawn.cjs +2 -0
  411. package/dist/services/runs/shared/piSpawn.cjs.map +1 -0
  412. package/dist/services/runs/shared/piSpawn.mjs +2 -0
  413. package/dist/services/runs/shared/piSpawn.mjs.map +1 -0
  414. package/dist/services/runs/shared/runWithConcurrency.cjs +2 -0
  415. package/dist/services/runs/shared/runWithConcurrency.cjs.map +1 -0
  416. package/dist/services/runs/shared/runWithConcurrency.d.cts +25 -0
  417. package/dist/services/runs/shared/runWithConcurrency.d.cts.map +1 -0
  418. package/dist/services/runs/shared/runWithConcurrency.d.mts +25 -0
  419. package/dist/services/runs/shared/runWithConcurrency.d.mts.map +1 -0
  420. package/dist/services/runs/shared/runWithConcurrency.mjs +2 -0
  421. package/dist/services/runs/shared/runWithConcurrency.mjs.map +1 -0
  422. package/dist/services/runs/shared/runtimeRegistry.cjs +2 -0
  423. package/dist/services/runs/shared/runtimeRegistry.cjs.map +1 -0
  424. package/dist/services/runs/shared/runtimeRegistry.mjs +2 -0
  425. package/dist/services/runs/shared/runtimeRegistry.mjs.map +1 -0
  426. package/dist/services/runs/shared/structuredOutput.cjs +2 -0
  427. package/dist/{runs → services/runs}/shared/structuredOutput.cjs.map +1 -1
  428. package/dist/services/runs/shared/structuredOutput.mjs +2 -0
  429. package/dist/{runs → services/runs}/shared/structuredOutput.mjs.map +1 -1
  430. package/dist/services/runs/shared/toolAvailability.cjs +2 -0
  431. package/dist/services/runs/shared/toolAvailability.cjs.map +1 -0
  432. package/dist/services/runs/shared/toolAvailability.mjs +2 -0
  433. package/dist/services/runs/shared/toolAvailability.mjs.map +1 -0
  434. package/dist/services/runs/shared/toolBudget.cjs +2 -0
  435. package/dist/services/runs/shared/toolBudget.cjs.map +1 -0
  436. package/dist/services/runs/shared/toolBudget.mjs +2 -0
  437. package/dist/services/runs/shared/toolBudget.mjs.map +1 -0
  438. package/dist/shared/artifacts.cjs.map +1 -1
  439. package/dist/shared/artifacts.mjs.map +1 -1
  440. package/dist/shared/atomicJson.cjs +1 -2
  441. package/dist/shared/atomicJson.mjs +1 -1
  442. package/dist/shared/atomicJson.mjs.map +1 -1
  443. package/dist/shared/childTranscript.cjs +1 -5
  444. package/dist/shared/childTranscript.mjs +1 -4
  445. package/dist/shared/childTranscript.mjs.map +1 -1
  446. package/dist/shared/fileSystemRetry.cjs +1 -1
  447. package/dist/shared/fileSystemRetry.cjs.map +1 -1
  448. package/dist/shared/fileSystemRetry.mjs +1 -1
  449. package/dist/shared/fileSystemRetry.mjs.map +1 -1
  450. package/dist/shared/formatters.cjs.map +1 -1
  451. package/dist/shared/formatters.mjs.map +1 -1
  452. package/dist/shared/paths.cjs +1 -1
  453. package/dist/shared/paths.cjs.map +1 -1
  454. package/dist/shared/paths.mjs +1 -1
  455. package/dist/shared/paths.mjs.map +1 -1
  456. package/dist/shared/pollScheduler.cjs +1 -2
  457. package/dist/shared/pollScheduler.mjs +1 -1
  458. package/dist/shared/pollScheduler.mjs.map +1 -1
  459. package/dist/shared/scopeOwner.cjs +1 -2
  460. package/dist/shared/scopeOwner.mjs +1 -1
  461. package/dist/shared/scopeOwner.mjs.map +1 -1
  462. package/dist/tui/agentCatalog.cjs +1 -1
  463. package/dist/tui/agentCatalog.cjs.map +1 -1
  464. package/dist/tui/agentCatalog.mjs +1 -1
  465. package/dist/tui/agentCatalog.mjs.map +1 -1
  466. package/dist/tui/agentResourceProjection.cjs +1 -1
  467. package/dist/tui/agentResourceProjection.cjs.map +1 -1
  468. package/dist/tui/agentResourceProjection.mjs +1 -1
  469. package/dist/tui/agentResourceProjection.mjs.map +1 -1
  470. package/dist/tui/completionNotice.cjs +1 -1
  471. package/dist/tui/completionNotice.cjs.map +1 -1
  472. package/dist/tui/completionNotice.mjs +1 -1
  473. package/dist/tui/completionNotice.mjs.map +1 -1
  474. package/dist/tui/fleet.cjs +2 -2
  475. package/dist/tui/fleet.cjs.map +1 -1
  476. package/dist/tui/fleet.mjs +2 -2
  477. package/dist/tui/fleet.mjs.map +1 -1
  478. package/dist/tui/fleetAgentView.cjs.map +1 -1
  479. package/dist/tui/fleetAgentView.mjs.map +1 -1
  480. package/dist/tui/fleetStatus.cjs +1 -1
  481. package/dist/tui/fleetStatus.cjs.map +1 -1
  482. package/dist/tui/fleetStatus.mjs +1 -1
  483. package/dist/tui/fleetStatus.mjs.map +1 -1
  484. package/dist/tui/fleetTranscript.cjs +1 -1
  485. package/dist/tui/fleetTranscript.cjs.map +1 -1
  486. package/dist/tui/fleetTranscript.mjs +1 -1
  487. package/dist/tui/fleetTranscript.mjs.map +1 -1
  488. package/dist/tui/register.cjs +1 -1
  489. package/dist/tui/register.cjs.map +1 -1
  490. package/dist/tui/register.mjs +1 -1
  491. package/dist/tui/register.mjs.map +1 -1
  492. package/dist/tui/subagentToolRender.cjs +3 -0
  493. package/dist/tui/subagentToolRender.cjs.map +1 -0
  494. package/dist/tui/subagentToolRender.mjs +3 -0
  495. package/dist/tui/subagentToolRender.mjs.map +1 -0
  496. package/dist/{types.d.cts → types/index.d.cts} +2 -2
  497. package/dist/types/index.d.cts.map +1 -0
  498. package/dist/{types.d.mts → types/index.d.mts} +2 -2
  499. package/dist/types/index.d.mts.map +1 -0
  500. package/package.json +23 -16
  501. package/dist/agents/discovery.cjs +0 -2
  502. package/dist/agents/discovery.cjs.map +0 -1
  503. package/dist/agents/discovery.mjs +0 -2
  504. package/dist/agents/discovery.mjs.map +0 -1
  505. package/dist/agents/frontmatter.cjs.map +0 -1
  506. package/dist/agents/frontmatter.mjs.map +0 -1
  507. package/dist/agents/loader.cjs +0 -2
  508. package/dist/agents/loader.cjs.map +0 -1
  509. package/dist/agents/loader.mjs +0 -2
  510. package/dist/agents/loader.mjs.map +0 -1
  511. package/dist/agents/memory.cjs +0 -3
  512. package/dist/agents/memory.cjs.map +0 -1
  513. package/dist/agents/memory.mjs.map +0 -1
  514. package/dist/agents/projectRoot.cjs +0 -2
  515. package/dist/agents/projectRoot.cjs.map +0 -1
  516. package/dist/agents/projectRoot.mjs +0 -2
  517. package/dist/agents/projectRoot.mjs.map +0 -1
  518. package/dist/agents/settings.cjs +0 -2
  519. package/dist/agents/settings.cjs.map +0 -1
  520. package/dist/agents/settings.mjs +0 -2
  521. package/dist/agents/settings.mjs.map +0 -1
  522. package/dist/agents/skills.cjs +0 -0
  523. package/dist/agents/skills.cjs.map +0 -1
  524. package/dist/agents/skills.mjs +0 -5
  525. package/dist/agents/skills.mjs.map +0 -1
  526. package/dist/agents/types.d.cts.map +0 -1
  527. package/dist/agents/types.d.mts.map +0 -1
  528. package/dist/api/capabilityCeiling.mjs.map +0 -1
  529. package/dist/api/teamSnapshot.mjs.map +0 -1
  530. package/dist/env.cjs.map +0 -1
  531. package/dist/env.d.cts.map +0 -1
  532. package/dist/env.d.mts.map +0 -1
  533. package/dist/extension.cjs +0 -2
  534. package/dist/extension.cjs.map +0 -1
  535. package/dist/extension.mjs +0 -2
  536. package/dist/extension.mjs.map +0 -1
  537. package/dist/intercom/intercomBridge.cjs.map +0 -1
  538. package/dist/intercom/intercomBridge.mjs.map +0 -1
  539. package/dist/intercom/nativeTeamChannel.cjs +0 -5
  540. package/dist/intercom/nativeTeamChannel.cjs.map +0 -1
  541. package/dist/intercom/nativeTeamChannel.d.cts.map +0 -1
  542. package/dist/intercom/nativeTeamChannel.d.mts.map +0 -1
  543. package/dist/intercom/nativeTeamChannel.mjs +0 -5
  544. package/dist/intercom/nativeTeamChannel.mjs.map +0 -1
  545. package/dist/intercom/supervisorControlChannel.cjs +0 -2
  546. package/dist/intercom/supervisorControlChannel.cjs.map +0 -1
  547. package/dist/intercom/supervisorControlChannel.mjs.map +0 -1
  548. package/dist/protocol/backgroundWork.cjs +0 -2
  549. package/dist/protocol/backgroundWork.d.cts.map +0 -1
  550. package/dist/protocol/backgroundWork.d.mts.map +0 -1
  551. package/dist/protocol/backgroundWork.mjs +0 -2
  552. package/dist/protocol/backgroundWork.mjs.map +0 -1
  553. package/dist/protocol/capabilityCeiling.cjs +0 -2
  554. package/dist/protocol/capabilityCeiling.cjs.map +0 -1
  555. package/dist/protocol/capabilityCeiling.d.cts.map +0 -1
  556. package/dist/protocol/capabilityCeiling.d.mts.map +0 -1
  557. package/dist/protocol/capabilityCeiling.mjs +0 -2
  558. package/dist/protocol/capabilityCeiling.mjs.map +0 -1
  559. package/dist/protocol/delegation.cjs.map +0 -1
  560. package/dist/protocol/delegation.d.cts.map +0 -1
  561. package/dist/protocol/delegation.d.mts.map +0 -1
  562. package/dist/protocol/delegation.mjs.map +0 -1
  563. package/dist/runs/background/asyncExecution.cjs +0 -2
  564. package/dist/runs/background/asyncExecution.cjs.map +0 -1
  565. package/dist/runs/background/asyncExecution.mjs +0 -2
  566. package/dist/runs/background/asyncExecution.mjs.map +0 -1
  567. package/dist/runs/background/asyncJobTracker.cjs +0 -2
  568. package/dist/runs/background/asyncJobTracker.cjs.map +0 -1
  569. package/dist/runs/background/asyncJobTracker.mjs +0 -2
  570. package/dist/runs/background/asyncJobTracker.mjs.map +0 -1
  571. package/dist/runs/background/cliRunnerEntry.cjs.map +0 -1
  572. package/dist/runs/background/cliRunnerEntry.mjs.map +0 -1
  573. package/dist/runs/background/completionBatcher.cjs.map +0 -1
  574. package/dist/runs/background/completionBatcher.mjs +0 -2
  575. package/dist/runs/background/completionBatcher.mjs.map +0 -1
  576. package/dist/runs/background/notify.cjs.map +0 -1
  577. package/dist/runs/background/notify.mjs.map +0 -1
  578. package/dist/runs/background/parentWatchdog.cjs.map +0 -1
  579. package/dist/runs/background/parentWatchdog.mjs.map +0 -1
  580. package/dist/runs/background/processTerminal.cjs +0 -2
  581. package/dist/runs/background/processTerminal.cjs.map +0 -1
  582. package/dist/runs/background/processTerminal.mjs +0 -2
  583. package/dist/runs/background/processTerminal.mjs.map +0 -1
  584. package/dist/runs/background/resultWatcher.cjs +0 -2
  585. package/dist/runs/background/resultWatcher.cjs.map +0 -1
  586. package/dist/runs/background/resultWatcher.mjs +0 -2
  587. package/dist/runs/background/resultWatcher.mjs.map +0 -1
  588. package/dist/runs/background/runIdResolver.cjs +0 -2
  589. package/dist/runs/background/runIdResolver.cjs.map +0 -1
  590. package/dist/runs/background/runIdResolver.mjs +0 -2
  591. package/dist/runs/background/runIdResolver.mjs.map +0 -1
  592. package/dist/runs/background/runnerBootstrap.cjs +0 -2
  593. package/dist/runs/background/runnerBootstrap.cjs.map +0 -1
  594. package/dist/runs/background/runnerBootstrap.mjs +0 -2
  595. package/dist/runs/background/runnerBootstrap.mjs.map +0 -1
  596. package/dist/runs/background/runnerExecution.cjs +0 -2
  597. package/dist/runs/background/runnerExecution.cjs.map +0 -1
  598. package/dist/runs/background/runnerExecution.mjs +0 -2
  599. package/dist/runs/background/runnerExecution.mjs.map +0 -1
  600. package/dist/runs/background/runnerReporting.cjs.map +0 -1
  601. package/dist/runs/background/runnerReporting.mjs.map +0 -1
  602. package/dist/runs/background/runnerTeamMembership.cjs +0 -2
  603. package/dist/runs/background/runnerTeamMembership.cjs.map +0 -1
  604. package/dist/runs/background/runnerTeamMembership.mjs +0 -2
  605. package/dist/runs/background/runnerTeamMembership.mjs.map +0 -1
  606. package/dist/runs/background/spawnHandshake.cjs +0 -2
  607. package/dist/runs/background/spawnHandshake.cjs.map +0 -1
  608. package/dist/runs/background/spawnHandshake.mjs +0 -2
  609. package/dist/runs/background/spawnHandshake.mjs.map +0 -1
  610. package/dist/runs/background/staleRunReconciler.cjs +0 -2
  611. package/dist/runs/background/staleRunReconciler.cjs.map +0 -1
  612. package/dist/runs/background/staleRunReconciler.mjs +0 -2
  613. package/dist/runs/background/staleRunReconciler.mjs.map +0 -1
  614. package/dist/runs/background/statusReader.cjs +0 -2
  615. package/dist/runs/background/statusReader.cjs.map +0 -1
  616. package/dist/runs/background/statusReader.mjs +0 -2
  617. package/dist/runs/background/statusReader.mjs.map +0 -1
  618. package/dist/runs/background/statusWriter.cjs +0 -2
  619. package/dist/runs/background/statusWriter.cjs.map +0 -1
  620. package/dist/runs/background/statusWriter.mjs +0 -2
  621. package/dist/runs/background/statusWriter.mjs.map +0 -1
  622. package/dist/runs/background/subagentWait.cjs +0 -2
  623. package/dist/runs/background/subagentWait.cjs.map +0 -1
  624. package/dist/runs/background/subagentWait.mjs +0 -2
  625. package/dist/runs/background/subagentWait.mjs.map +0 -1
  626. package/dist/runs/background/terminalPersistence.cjs +0 -2
  627. package/dist/runs/background/terminalPersistence.cjs.map +0 -1
  628. package/dist/runs/background/terminalPersistence.mjs.map +0 -1
  629. package/dist/runs/registry/processGroup.cjs.map +0 -1
  630. package/dist/runs/registry/processGroup.mjs.map +0 -1
  631. package/dist/runs/registry/runRegistry.cjs +0 -2
  632. package/dist/runs/registry/runRegistry.cjs.map +0 -1
  633. package/dist/runs/registry/runRegistry.mjs +0 -2
  634. package/dist/runs/registry/runRegistry.mjs.map +0 -1
  635. package/dist/runs/registry/sessionLifecycle.cjs +0 -2
  636. package/dist/runs/registry/sessionLifecycle.cjs.map +0 -1
  637. package/dist/runs/registry/sessionLifecycle.mjs +0 -2
  638. package/dist/runs/registry/sessionLifecycle.mjs.map +0 -1
  639. package/dist/runs/registry/suspendedRuns.cjs +0 -4
  640. package/dist/runs/registry/suspendedRuns.cjs.map +0 -1
  641. package/dist/runs/registry/suspendedRuns.mjs +0 -4
  642. package/dist/runs/registry/suspendedRuns.mjs.map +0 -1
  643. package/dist/runs/sdkRunnerEntry.cjs.map +0 -1
  644. package/dist/runs/sdkRunnerEntry.mjs.map +0 -1
  645. package/dist/runs/shared/claudeFableProfile.cjs +0 -4
  646. package/dist/runs/shared/claudeFableProfile.cjs.map +0 -1
  647. package/dist/runs/shared/claudeFableProfile.mjs +0 -4
  648. package/dist/runs/shared/claudeFableProfile.mjs.map +0 -1
  649. package/dist/runs/shared/depthGuard.cjs +0 -2
  650. package/dist/runs/shared/depthGuard.cjs.map +0 -1
  651. package/dist/runs/shared/depthGuard.mjs +0 -2
  652. package/dist/runs/shared/depthGuard.mjs.map +0 -1
  653. package/dist/runs/shared/mcpDirectToolAllowlist.cjs +0 -2
  654. package/dist/runs/shared/mcpDirectToolAllowlist.cjs.map +0 -1
  655. package/dist/runs/shared/mcpDirectToolAllowlist.mjs +0 -2
  656. package/dist/runs/shared/mcpDirectToolAllowlist.mjs.map +0 -1
  657. package/dist/runs/shared/modelFallback.cjs +0 -2
  658. package/dist/runs/shared/modelFallback.cjs.map +0 -1
  659. package/dist/runs/shared/modelFallback.mjs +0 -2
  660. package/dist/runs/shared/modelFallback.mjs.map +0 -1
  661. package/dist/runs/shared/modelScope.cjs +0 -2
  662. package/dist/runs/shared/modelScope.cjs.map +0 -1
  663. package/dist/runs/shared/modelScope.mjs +0 -2
  664. package/dist/runs/shared/modelScope.mjs.map +0 -1
  665. package/dist/runs/shared/nestedPath.cjs +0 -2
  666. package/dist/runs/shared/nestedPath.cjs.map +0 -1
  667. package/dist/runs/shared/nestedPath.mjs +0 -2
  668. package/dist/runs/shared/nestedPath.mjs.map +0 -1
  669. package/dist/runs/shared/piArgs.cjs +0 -2
  670. package/dist/runs/shared/piArgs.cjs.map +0 -1
  671. package/dist/runs/shared/piArgs.mjs +0 -2
  672. package/dist/runs/shared/piArgs.mjs.map +0 -1
  673. package/dist/runs/shared/piSpawn.cjs +0 -2
  674. package/dist/runs/shared/piSpawn.cjs.map +0 -1
  675. package/dist/runs/shared/piSpawn.mjs +0 -2
  676. package/dist/runs/shared/piSpawn.mjs.map +0 -1
  677. package/dist/runs/shared/runWithConcurrency.cjs +0 -2
  678. package/dist/runs/shared/runWithConcurrency.cjs.map +0 -1
  679. package/dist/runs/shared/runWithConcurrency.mjs +0 -2
  680. package/dist/runs/shared/runWithConcurrency.mjs.map +0 -1
  681. package/dist/runs/shared/runtimeRegistry.cjs +0 -2
  682. package/dist/runs/shared/runtimeRegistry.cjs.map +0 -1
  683. package/dist/runs/shared/runtimeRegistry.mjs +0 -2
  684. package/dist/runs/shared/runtimeRegistry.mjs.map +0 -1
  685. package/dist/runs/shared/structuredOutput.cjs +0 -2
  686. package/dist/runs/shared/structuredOutput.mjs +0 -2
  687. package/dist/runs/shared/toolAvailability.cjs +0 -2
  688. package/dist/runs/shared/toolAvailability.cjs.map +0 -1
  689. package/dist/runs/shared/toolAvailability.mjs +0 -2
  690. package/dist/runs/shared/toolAvailability.mjs.map +0 -1
  691. package/dist/runs/shared/toolBudget.cjs +0 -2
  692. package/dist/runs/shared/toolBudget.cjs.map +0 -1
  693. package/dist/runs/shared/toolBudget.mjs +0 -2
  694. package/dist/runs/shared/toolBudget.mjs.map +0 -1
  695. package/dist/shared/atomicJson.cjs.map +0 -1
  696. package/dist/shared/childTranscript.cjs.map +0 -1
  697. package/dist/shared/pollScheduler.cjs.map +0 -1
  698. package/dist/shared/scopeOwner.cjs.map +0 -1
  699. package/dist/slash/chainExpression.cjs.map +0 -1
  700. package/dist/slash/chainExpression.mjs.map +0 -1
  701. package/dist/slash/doctor.cjs +0 -5
  702. package/dist/slash/doctor.mjs +0 -5
  703. package/dist/slash/doctor.mjs.map +0 -1
  704. package/dist/slash/slashCommands.cjs.map +0 -1
  705. package/dist/slash/slashCommands.mjs.map +0 -1
  706. package/dist/slash/spawnRequestMapping.cjs.map +0 -1
  707. package/dist/slash/spawnRequestMapping.mjs.map +0 -1
  708. package/dist/slash/subagentLaunch.cjs +0 -2
  709. package/dist/slash/subagentLaunch.cjs.map +0 -1
  710. package/dist/slash/subagentLaunch.mjs +0 -2
  711. package/dist/slash/subagentLaunch.mjs.map +0 -1
  712. package/dist/types.d.cts.map +0 -1
  713. package/dist/types.d.mts.map +0 -1
  714. /package/dist/{slash → commands/slash}/chainExpression.cjs +0 -0
  715. /package/dist/{slash → commands/slash}/chainExpression.mjs +0 -0
  716. /package/dist/{slash → commands/slash}/spawnRequestMapping.cjs +0 -0
  717. /package/dist/{slash → commands/slash}/spawnRequestMapping.mjs +0 -0
  718. /package/dist/{protocol → schemas/team}/delegation.cjs +0 -0
  719. /package/dist/{protocol → schemas/team}/delegation.mjs +0 -0
  720. /package/dist/{agents → services/agents}/frontmatter.cjs +0 -0
  721. /package/dist/{intercom → services/intercom}/intercomBridge.cjs +0 -0
  722. /package/dist/{intercom → services/intercom}/intercomBridge.mjs +0 -0
  723. /package/dist/{runs → services/runs}/background/completionBatcher.cjs +0 -0
  724. /package/dist/{runs → services/runs}/background/parentWatchdog.cjs +0 -0
  725. /package/dist/{runs → services/runs}/background/parentWatchdog.mjs +0 -0
  726. /package/dist/{runs → services/runs}/registry/processGroup.cjs +0 -0
  727. /package/dist/{runs → services/runs}/registry/processGroup.mjs +0 -0
@@ -1 +0,0 @@
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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"}
@@ -1,2 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,2 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,2 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,2 +0,0 @@
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"runWithConcurrency.mjs","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":"kIAuCA,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,kBAnDH,EAAY,EAAoB,CACpC,YAAa,wBACb,YAAa,yBACb,IAAK,QAAQ,IACb,WAAY,GACZ,aAAc,GACf,CAAC"}
@@ -1,2 +0,0 @@
1
- const e=require(`../../env.cjs`),t={claude:{command:`claude`,args:[`-p`,`{prompt}`]},antigravity:{command:`antigravity`,args:[`{prompt}`]}};function n(e){return(e??`pi`).trim()===`pi`}function r(e){return e?{...t,...e}:{...t}}function i(t,n,r){return r[e.runtimeBinaryEnvVar(t)]?.trim()||n.command}function a(e,t){return e.replaceAll(`{prompt}`,t.prompt).replaceAll(`{model}`,t.model??``).replaceAll(`{cwd}`,t.cwd)}function o(e,t,n,r=process.env){let o=t[e];if(!o){let n=Object.keys(t).sort().join(`, `)||`(none configured)`;throw Error(`Unknown subagent runtime '${e}'. Configured runtimes: ${n}.`)}return{runtime:e,command:i(e,o,r),args:o.args.map(e=>a(e,n)).filter(e=>e.length>0)}}exports.isPiRuntime=n,exports.resolveRuntimeLaunch=o,exports.resolveRuntimeTable=r;
2
- //# sourceMappingURL=runtimeRegistry.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtimeRegistry.cjs","names":["runtimeBinaryEnvVar"],"sources":["../../../src/runs/shared/runtimeRegistry.ts"],"sourcesContent":["/**\n * Which agent runtime executes a run, and how to invoke it.\n *\n * WHY THIS IS CONFIG AND NOT A CLASS PER VENDOR:\n * Every external agent CLI is the same shape from here: a binary, an argv with\n * the prompt substituted in, a working directory, and whatever it prints. There\n * is no per-vendor behaviour worth a per-vendor module, and inventing an\n * adapter interface would mean a new file, a new registration and a new test\n * suite every time someone wants to point a run at a different command. Adding\n * or retargeting a CLI is a config edit.\n *\n * WHAT THIS DELIBERATELY DOES NOT DO:\n * It does not parse vendor output. A generic runner cannot know what a given\n * CLI's JSON stream means, and pretending to would either lock the config down\n * to the two CLIs someone happened to test, or silently mis-report a third. The\n * run's final output is its output; status comes from the run lifecycle, which\n * already knows queued/running/terminal without reading a word of it.\n *\n * `pi` IS NOT IN THIS TABLE:\n * It is not an external command - it runs in-process through the SDK\n * (`runs/sdkRunnerEntry.ts`) and gets the team channel, steering and\n * structured output that an external one-shot cannot. Treating it as one more\n * row here would advertise capabilities the external path does not have.\n *\n * AVOID:\n * - Putting a secret in an argv template; argv is visible in the process table\n * - Adding a placeholder without substituting it. An unsubstituted `{prompt}`\n * reaches the CLI literally\n */\n\nimport { PI_RUNTIME_NAME, runtimeBinaryEnvVar } from '../../env.ts';\n\n/** One external CLI, as configured. */\nexport interface RuntimeDefinition {\n /** Binary to execute. Resolved against PATH unless overridden by env. */\n command: string;\n /** Argv template. `{prompt}`, `{model}` and `{cwd}` are substituted per run. */\n args: string[];\n}\n\nexport type RuntimeTable = Record<string, RuntimeDefinition>;\n\n/**\n * Shipped defaults, overridable per entry by config.\n *\n * Both are headless one-shot invocations: the prompt goes in, the final answer\n * comes out on stdout, and the process exits. Neither is asked for a structured\n * stream, because nothing here would read it.\n */\nexport const DEFAULT_RUNTIMES: RuntimeTable = {\n claude: { command: 'claude', args: ['-p', '{prompt}'] },\n antigravity: { command: 'antigravity', args: ['{prompt}'] },\n};\n\nexport interface ResolvedRuntimeLaunch {\n runtime: string;\n command: string;\n args: string[];\n}\n\nexport interface RuntimeSubstitutions {\n prompt: string;\n model?: string;\n cwd: string;\n}\n\n/** True for the in-process SDK path, which this module does not describe. */\nexport function isPiRuntime(runtime: string | undefined): boolean {\n return (runtime ?? PI_RUNTIME_NAME).trim() === PI_RUNTIME_NAME;\n}\n\nexport function resolveRuntimeTable(configured: RuntimeTable | undefined): RuntimeTable {\n if (!configured) return { ...DEFAULT_RUNTIMES };\n return { ...DEFAULT_RUNTIMES, ...configured };\n}\n\n/**\n * The binary to run, most explicit source first.\n *\n * The env override exists for the same reason `piSpawn.ts` has one: a\n * developer testing against a locally built CLI must be able to point a run at\n * it without editing shared config.\n */\nfunction resolveCommand(runtime: string, definition: RuntimeDefinition, env: NodeJS.ProcessEnv): string {\n const override = env[runtimeBinaryEnvVar(runtime)]?.trim();\n return override || definition.command;\n}\n\nfunction substitute(template: string, values: RuntimeSubstitutions): string {\n return template\n .replaceAll('{prompt}', values.prompt)\n .replaceAll('{model}', values.model ?? '')\n .replaceAll('{cwd}', values.cwd);\n}\n\n/**\n * Resolve one run's command line.\n *\n * An argument that reduces to the empty string is dropped rather than passed:\n * a template carrying `--model {model}` for a run with no model override would\n * otherwise hand the CLI a bare `--model` with nothing after it.\n */\nexport function resolveRuntimeLaunch(\n runtime: string,\n table: RuntimeTable,\n values: RuntimeSubstitutions,\n env: NodeJS.ProcessEnv = process.env,\n): ResolvedRuntimeLaunch {\n const definition = table[runtime];\n if (!definition) {\n const known = Object.keys(table).sort().join(', ') || '(none configured)';\n throw new Error(`Unknown subagent runtime '${runtime}'. Configured runtimes: ${known}.`);\n }\n return {\n runtime,\n command: resolveCommand(runtime, definition, env),\n args: definition.args.map((arg) => substitute(arg, values)).filter((arg) => arg.length > 0),\n };\n}\n"],"mappings":"iCAiDa,EAAiC,CAC5C,OAAQ,CAAE,QAAS,SAAU,KAAM,CAAC,KAAM,WAAW,CAAE,CACvD,YAAa,CAAE,QAAS,cAAe,KAAM,CAAC,WAAW,CAAE,CAC5D,CAeD,SAAgB,EAAY,EAAsC,CAChE,OAAQ,GAAA,MAA4B,MAAM,GAAA,KAG5C,SAAgB,EAAoB,EAAoD,CAEtF,OADK,EACE,CAAE,GAAG,EAAkB,GAAG,EAAY,CADrB,CAAE,GAAG,EAAkB,CAWjD,SAAS,EAAe,EAAiB,EAA+B,EAAgC,CAEtG,OADiB,EAAIA,EAAAA,oBAAoB,EAAQ,GAAG,MAAM,EACvC,EAAW,QAGhC,SAAS,EAAW,EAAkB,EAAsC,CAC1E,OAAO,EACJ,WAAW,WAAY,EAAO,OAAO,CACrC,WAAW,UAAW,EAAO,OAAS,GAAG,CACzC,WAAW,QAAS,EAAO,IAAI,CAUpC,SAAgB,EACd,EACA,EACA,EACA,EAAyB,QAAQ,IACV,CACvB,IAAM,EAAa,EAAM,GACzB,GAAI,CAAC,EAAY,CACf,IAAM,EAAQ,OAAO,KAAK,EAAM,CAAC,MAAM,CAAC,KAAK,KAAK,EAAI,oBACtD,MAAU,MAAM,6BAA6B,EAAQ,0BAA0B,EAAM,GAAG,CAE1F,MAAO,CACL,UACA,QAAS,EAAe,EAAS,EAAY,EAAI,CACjD,KAAM,EAAW,KAAK,IAAK,GAAQ,EAAW,EAAK,EAAO,CAAC,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CAC5F"}
@@ -1,2 +0,0 @@
1
- import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import{init_env as t,runtimeBinaryEnvVar as n}from"../../env.mjs";function r(e){return(e??`pi`).trim()===`pi`}function i(e){return e?{...c,...e}:{...c}}function a(e,t,r){return r[n(e)]?.trim()||t.command}function o(e,t){return e.replaceAll(`{prompt}`,t.prompt).replaceAll(`{model}`,t.model??``).replaceAll(`{cwd}`,t.cwd)}function s(e,t,n,r=process.env){let i=t[e];if(!i){let n=Object.keys(t).sort().join(`, `)||`(none configured)`;throw Error(`Unknown subagent runtime '${e}'. Configured runtimes: ${n}.`)}return{runtime:e,command:a(e,i,r),args:i.args.map(e=>o(e,n)).filter(e=>e.length>0)}}var c,l=e((()=>{t(),c={claude:{command:`claude`,args:[`-p`,`{prompt}`]},antigravity:{command:`antigravity`,args:[`{prompt}`]}}}));l();export{l as init_runtimeRegistry,r as isPiRuntime,s as resolveRuntimeLaunch,i as resolveRuntimeTable};
2
- //# sourceMappingURL=runtimeRegistry.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtimeRegistry.mjs","names":[],"sources":["../../../src/runs/shared/runtimeRegistry.ts"],"sourcesContent":["/**\n * Which agent runtime executes a run, and how to invoke it.\n *\n * WHY THIS IS CONFIG AND NOT A CLASS PER VENDOR:\n * Every external agent CLI is the same shape from here: a binary, an argv with\n * the prompt substituted in, a working directory, and whatever it prints. There\n * is no per-vendor behaviour worth a per-vendor module, and inventing an\n * adapter interface would mean a new file, a new registration and a new test\n * suite every time someone wants to point a run at a different command. Adding\n * or retargeting a CLI is a config edit.\n *\n * WHAT THIS DELIBERATELY DOES NOT DO:\n * It does not parse vendor output. A generic runner cannot know what a given\n * CLI's JSON stream means, and pretending to would either lock the config down\n * to the two CLIs someone happened to test, or silently mis-report a third. The\n * run's final output is its output; status comes from the run lifecycle, which\n * already knows queued/running/terminal without reading a word of it.\n *\n * `pi` IS NOT IN THIS TABLE:\n * It is not an external command - it runs in-process through the SDK\n * (`runs/sdkRunnerEntry.ts`) and gets the team channel, steering and\n * structured output that an external one-shot cannot. Treating it as one more\n * row here would advertise capabilities the external path does not have.\n *\n * AVOID:\n * - Putting a secret in an argv template; argv is visible in the process table\n * - Adding a placeholder without substituting it. An unsubstituted `{prompt}`\n * reaches the CLI literally\n */\n\nimport { PI_RUNTIME_NAME, runtimeBinaryEnvVar } from '../../env.ts';\n\n/** One external CLI, as configured. */\nexport interface RuntimeDefinition {\n /** Binary to execute. Resolved against PATH unless overridden by env. */\n command: string;\n /** Argv template. `{prompt}`, `{model}` and `{cwd}` are substituted per run. */\n args: string[];\n}\n\nexport type RuntimeTable = Record<string, RuntimeDefinition>;\n\n/**\n * Shipped defaults, overridable per entry by config.\n *\n * Both are headless one-shot invocations: the prompt goes in, the final answer\n * comes out on stdout, and the process exits. Neither is asked for a structured\n * stream, because nothing here would read it.\n */\nexport const DEFAULT_RUNTIMES: RuntimeTable = {\n claude: { command: 'claude', args: ['-p', '{prompt}'] },\n antigravity: { command: 'antigravity', args: ['{prompt}'] },\n};\n\nexport interface ResolvedRuntimeLaunch {\n runtime: string;\n command: string;\n args: string[];\n}\n\nexport interface RuntimeSubstitutions {\n prompt: string;\n model?: string;\n cwd: string;\n}\n\n/** True for the in-process SDK path, which this module does not describe. */\nexport function isPiRuntime(runtime: string | undefined): boolean {\n return (runtime ?? PI_RUNTIME_NAME).trim() === PI_RUNTIME_NAME;\n}\n\nexport function resolveRuntimeTable(configured: RuntimeTable | undefined): RuntimeTable {\n if (!configured) return { ...DEFAULT_RUNTIMES };\n return { ...DEFAULT_RUNTIMES, ...configured };\n}\n\n/**\n * The binary to run, most explicit source first.\n *\n * The env override exists for the same reason `piSpawn.ts` has one: a\n * developer testing against a locally built CLI must be able to point a run at\n * it without editing shared config.\n */\nfunction resolveCommand(runtime: string, definition: RuntimeDefinition, env: NodeJS.ProcessEnv): string {\n const override = env[runtimeBinaryEnvVar(runtime)]?.trim();\n return override || definition.command;\n}\n\nfunction substitute(template: string, values: RuntimeSubstitutions): string {\n return template\n .replaceAll('{prompt}', values.prompt)\n .replaceAll('{model}', values.model ?? '')\n .replaceAll('{cwd}', values.cwd);\n}\n\n/**\n * Resolve one run's command line.\n *\n * An argument that reduces to the empty string is dropped rather than passed:\n * a template carrying `--model {model}` for a run with no model override would\n * otherwise hand the CLI a bare `--model` with nothing after it.\n */\nexport function resolveRuntimeLaunch(\n runtime: string,\n table: RuntimeTable,\n values: RuntimeSubstitutions,\n env: NodeJS.ProcessEnv = process.env,\n): ResolvedRuntimeLaunch {\n const definition = table[runtime];\n if (!definition) {\n const known = Object.keys(table).sort().join(', ') || '(none configured)';\n throw new Error(`Unknown subagent runtime '${runtime}'. Configured runtimes: ${known}.`);\n }\n return {\n runtime,\n command: resolveCommand(runtime, definition, env),\n args: definition.args.map((arg) => substitute(arg, values)).filter((arg) => arg.length > 0),\n };\n}\n"],"mappings":"kIAmEA,SAAgB,EAAY,EAAsC,CAChE,OAAQ,GAAA,MAA4B,MAAM,GAAA,KAG5C,SAAgB,EAAoB,EAAoD,CAEtF,OADK,EACE,CAAE,GAAG,EAAkB,GAAG,EAAY,CADrB,CAAE,GAAG,EAAkB,CAWjD,SAAS,EAAe,EAAiB,EAA+B,EAAgC,CAEtG,OADiB,EAAI,EAAoB,EAAQ,GAAG,MAAM,EACvC,EAAW,QAGhC,SAAS,EAAW,EAAkB,EAAsC,CAC1E,OAAO,EACJ,WAAW,WAAY,EAAO,OAAO,CACrC,WAAW,UAAW,EAAO,OAAS,GAAG,CACzC,WAAW,QAAS,EAAO,IAAI,CAUpC,SAAgB,EACd,EACA,EACA,EACA,EAAyB,QAAQ,IACV,CACvB,IAAM,EAAa,EAAM,GACzB,GAAI,CAAC,EAAY,CACf,IAAM,EAAQ,OAAO,KAAK,EAAM,CAAC,MAAM,CAAC,KAAK,KAAK,EAAI,oBACtD,MAAU,MAAM,6BAA6B,EAAQ,0BAA0B,EAAM,GAAG,CAE1F,MAAO,CACL,UACA,QAAS,EAAe,EAAS,EAAY,EAAI,CACjD,KAAM,EAAW,KAAK,IAAK,GAAQ,EAAW,EAAK,EAAO,CAAC,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CAC5F,oBAvFiE,CAmBvD,EAAiC,CAC5C,OAAQ,CAAE,QAAS,SAAU,KAAM,CAAC,KAAM,WAAW,CAAE,CACvD,YAAa,CAAE,QAAS,cAAe,KAAM,CAAC,WAAW,CAAE,CAC5D"}
@@ -1,2 +0,0 @@
1
- const e=require(`../../_virtual/_rolldown/runtime.cjs`),t=require(`../../_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.cjs`),n=require(`../../env.cjs`);require(`../../shared/paths.cjs`);let r=require(`node:fs`);r=e.__toESM(r,1);let i=require(`node:path`);i=e.__toESM(i,1);let a=require(`inversify`),o=require(`node:url`),s=require(`node:module`);const c=`value`,l=`#/properties/${c}`,u=[`properties`,`patternProperties`,`$defs`,`definitions`,`dependentSchemas`],d=[`additionalItems`,`additionalProperties`,`contains`,`not`,`propertyNames`,`if`,`then`,`else`,`unevaluatedItems`,`unevaluatedProperties`,`contentSchema`],f=[`allOf`,`anyOf`,`oneOf`,`prefixItems`],p=[`$ref`,`$dynamicRef`,`$recursiveRef`];function m(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function h(e,t,n=!0){if(typeof e==`boolean`||!m(e))return e;let r=e,i={...r},a=n&&typeof r.$id!=`string`;if(a)for(let e of p){let n=r[e];n===`#`?i[e]=t:typeof n==`string`&&n.startsWith(`#/`)&&(i[e]=`${t}${n.slice(1)}`)}for(let e of u){let n=r[e];m(n)&&(i[e]=Object.fromEntries(Object.entries(n).map(([e,n])=>[e,h(n,t,a)])))}let o=r.items;Array.isArray(o)?i.items=o.map(e=>h(e,t,a)):o!==void 0&&(i.items=h(o,t,a));for(let e of d)r[e]!==void 0&&(i[e]=h(r[e],t,a));for(let e of f){let n=r[e];Array.isArray(n)&&(i[e]=n.map(e=>h(e,t,a)))}let s=r.dependencies;return m(s)&&(i.dependencies=Object.fromEntries(Object.entries(s).map(([e,n])=>[e,Array.isArray(n)?n:h(n,t,a)]))),i}function g(e){return{type:`object`,properties:{[c]:h(e,l)},required:[c],additionalProperties:!1}}const _=`typebox/compile`,v=`Compile`;function y(e){return e instanceof Error?e.message:String(e)}function b(e){if(!m(e))return;let t=e[v];return typeof t==`function`?t:void 0}async function x(e){return b(await import((0,o.pathToFileURL)((0,s.createRequire)(i.join(e,`package.json`)).resolve(_)).href))}let S=class{cachedCompile;importCompileModule(){return import(_)}importCompileFromPackageRoot(e){return x(e)}async importCompile(){let e=[];try{let t=b(await this.importCompileModule());if(t)return t;e.push(`${_} did not export a ${v} function`)}catch(t){e.push(`direct import failed: ${y(t)}`)}let t=process.env[n.PI_CODING_AGENT_PACKAGE_ROOT_ENV];if(t)try{let n=await this.importCompileFromPackageRoot(t);if(n)return n;e.push(`Pi package root ${_} did not export a ${v} function`)}catch(t){e.push(`Pi package root import failed: ${y(t)}`)}else e.push(`${n.PI_CODING_AGENT_PACKAGE_ROOT_ENV} is not set`);throw Error(`Cannot load ${_} for structured output validation (${e.join(`; `)})`)}loadCompile(){return this.cachedCompile||=this.importCompile().catch(e=>{throw this.cachedCompile=void 0,e}),this.cachedCompile}reset(){this.cachedCompile=void 0}async validateValue(e,t){let n=await this.loadCompile(),r;try{r=n(e)}catch(e){return{status:`invalid`,message:`invalid outputSchema: ${y(e)}`}}return r.Check(t)?{status:`valid`}:{status:`invalid`,message:[...r.Errors(t)].slice(0,8).map(e=>`${e.instancePath?e.instancePath.replace(/^\//,``).replace(/\//g,`.`):`root`}: ${e.message}`).join(`; `)||`schema validation failed`}}async readStructuredOutput(e){if(!r.existsSync(e.outputPath))return{error:`Missing structured_output call; this step has outputSchema and must finish by calling structured_output.`};let t;try{t=JSON.parse(r.readFileSync(e.outputPath,`utf-8`))}catch(e){return{error:`Failed to read structured output: ${y(e)}`}}try{let n=await this.validateValue(e.schema,t);if(n.status===`invalid`)return{error:`Structured output validation failed: ${n.message}`}}catch(e){return{error:`Failed to validate structured output: ${y(e)}`}}return{value:t}}};S=t.__decorate([(0,a.injectable)()],S),Object.defineProperty(exports,`StructuredOutputValidator`,{enumerable:!0,get:function(){return S}}),exports.createStructuredOutputToolParameters=g;
2
- //# sourceMappingURL=structuredOutput.cjs.map
@@ -1,2 +0,0 @@
1
- import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import{__decorate as t,init_decorate as n}from"../../_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.mjs";import{PI_CODING_AGENT_PACKAGE_ROOT_ENV as r,init_env as i}from"../../env.mjs";import{init_paths as a}from"../../shared/paths.mjs";import{createRequire as o}from"node:module";import*as s from"node:fs";import*as c from"node:path";import{injectable as l}from"inversify";import{pathToFileURL as u}from"node:url";function d(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function f(e,t,n=!0){if(typeof e==`boolean`||!d(e))return e;let r=e,i={...r},a=n&&typeof r.$id!=`string`;if(a)for(let e of C){let n=r[e];n===w?i[e]=t:typeof n==`string`&&n.startsWith(T)&&(i[e]=`${t}${n.slice(1)}`)}for(let e of b){let n=r[e];d(n)&&(i[e]=Object.fromEntries(Object.entries(n).map(([e,n])=>[e,f(n,t,a)])))}let o=r.items;Array.isArray(o)?i.items=o.map(e=>f(e,t,a)):o!==void 0&&(i.items=f(o,t,a));for(let e of x)r[e]!==void 0&&(i[e]=f(r[e],t,a));for(let e of S){let n=r[e];Array.isArray(n)&&(i[e]=n.map(e=>f(e,t,a)))}let s=r.dependencies;return d(s)&&(i.dependencies=Object.fromEntries(Object.entries(s).map(([e,n])=>[e,Array.isArray(n)?n:f(n,t,a)]))),i}function p(e){return{type:`object`,properties:{[v]:f(e,y)},required:[v],additionalProperties:!1}}function m(e){return e instanceof Error?e.message:String(e)}function h(e){if(!d(e))return;let t=e[D];return typeof t==`function`?t:void 0}async function g(e){return h(await import(u(o(c.join(e,`package.json`)).resolve(E)).href))}var _,v,y,b,x,S,C,w,T,E,D,O,k,A,j=e((()=>{i(),a(),n(),_=`Missing structured_output call; this step has outputSchema and must finish by calling structured_output.`,v=`value`,y=`#/properties/${v}`,b=[`properties`,`patternProperties`,`$defs`,`definitions`,`dependentSchemas`],x=[`additionalItems`,`additionalProperties`,`contains`,`not`,`propertyNames`,`if`,`then`,`else`,`unevaluatedItems`,`unevaluatedProperties`,`contentSchema`],S=[`allOf`,`anyOf`,`oneOf`,`prefixItems`],C=[`$ref`,`$dynamicRef`,`$recursiveRef`],w=`#`,T=`#/`,E=`typebox/compile`,D=`Compile`,O=8,k=`root`,A=class{cachedCompile;importCompileModule(){return import(E)}importCompileFromPackageRoot(e){return g(e)}async importCompile(){let e=[];try{let t=h(await this.importCompileModule());if(t)return t;e.push(`${E} did not export a ${D} function`)}catch(t){e.push(`direct import failed: ${m(t)}`)}let t=process.env[r];if(t)try{let n=await this.importCompileFromPackageRoot(t);if(n)return n;e.push(`Pi package root ${E} did not export a ${D} function`)}catch(t){e.push(`Pi package root import failed: ${m(t)}`)}else e.push(`${r} is not set`);throw Error(`Cannot load ${E} for structured output validation (${e.join(`; `)})`)}loadCompile(){return this.cachedCompile||=this.importCompile().catch(e=>{throw this.cachedCompile=void 0,e}),this.cachedCompile}reset(){this.cachedCompile=void 0}async validateValue(e,t){let n=await this.loadCompile(),r;try{r=n(e)}catch(e){return{status:`invalid`,message:`invalid outputSchema: ${m(e)}`}}return r.Check(t)?{status:`valid`}:{status:`invalid`,message:[...r.Errors(t)].slice(0,O).map(e=>`${e.instancePath?e.instancePath.replace(/^\//,``).replace(/\//g,`.`):k}: ${e.message}`).join(`; `)||`schema validation failed`}}async readStructuredOutput(e){if(!s.existsSync(e.outputPath))return{error:_};let t;try{t=JSON.parse(s.readFileSync(e.outputPath,`utf-8`))}catch(e){return{error:`Failed to read structured output: ${m(e)}`}}try{let n=await this.validateValue(e.schema,t);if(n.status===`invalid`)return{error:`Structured output validation failed: ${n.message}`}}catch(e){return{error:`Failed to validate structured output: ${m(e)}`}}return{value:t}}},A=t([l()],A)}));j();export{A as StructuredOutputValidator,p as createStructuredOutputToolParameters,j as init_structuredOutput};
2
- //# sourceMappingURL=structuredOutput.mjs.map
@@ -1,2 +0,0 @@
1
- const e=require(`../../_virtual/_rolldown/runtime.cjs`),t=require(`../../shared/atomicJson.cjs`);let n=require(`node:fs`);n=e.__toESM(n,1);const r=new Set([`bash`,`edit`,`find`,`grep`,`ls`,`read`,`write`]);function i(e,i,a,o,s){let c=new Set([...a,...r]),l=i.filter(e=>!c.has(e));if(l.length===0){n.rmSync(e,{force:!0});return}let u=s?.length?l.filter(e=>s.includes(e)):[],d={...o===void 0?{}:{agent:o},required:i,available:a,missing:l,...u.length>0?{missingMcpDirectTools:u}:{}};return t.writePrivateAtomicJson(e,d),d}exports.writeChildToolDiagnostic=i;
2
- //# sourceMappingURL=toolAvailability.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"toolAvailability.cjs","names":[],"sources":["../../../src/runs/shared/toolAvailability.ts"],"sourcesContent":["/**\n * Diagnostics for child tools an agent asked for that the child never registered.\n *\n * The `tools` field on an agent is a strict allowlist: it selects from what the\n * child process already has, it does not cause extension code to load. When the\n * two disagree the child notices, not the parent, and the child's stderr is not\n * where a user looks. So the child drops a small file the parent reads after the\n * run and turns into an actionable message.\n *\n * DESIGN PATTERNS:\n * - The file is a negative signal only. A run with nothing missing removes it,\n * so a stale file from an earlier run can never be reported against a later one\n * - Written 0600 and atomically, because it is parsed by a different process and\n * a torn read is indistinguishable from a corrupt file\n * - Reads validate every field. The file is JSON on disk that any process could\n * have written, so nothing is trusted on shape alone\n *\n * AVOID:\n * - Treating a malformed diagnostic as \"nothing missing\"; it is reported as a\n * read failure instead, because a silent empty result hides the tool gap\n */\n\nimport * as fs from 'node:fs';\nimport { writePrivateAtomicJson } from '../../shared/atomicJson.ts';\n\nexport interface ChildToolDiagnostic {\n agent?: string;\n required: string[];\n available: string[];\n missing: string[];\n missingMcpDirectTools?: string[];\n}\n\n/**\n * Tools every child has regardless of what it reported.\n *\n * The child registry snapshot can be taken before the builtins finish\n * registering, so treating these as always available avoids a false alarm.\n */\nconst CORE_CHILD_TOOLS = new Set(['bash', 'edit', 'find', 'grep', 'ls', 'read', 'write']);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === 'string' && entry.length > 0);\n}\n\n/**\n * Record the gap between requested and registered tools, or clear a stale record.\n *\n * Returns the diagnostic when there is one so the caller can report it without\n * reading back what it just wrote.\n */\nexport function writeChildToolDiagnostic(\n filePath: string,\n required: string[],\n available: string[],\n agent?: string,\n mcpDirectTools?: string[],\n): ChildToolDiagnostic | undefined {\n const availableNames = new Set([...available, ...CORE_CHILD_TOOLS]);\n const missing = required.filter((name) => !availableNames.has(name));\n if (missing.length === 0) {\n fs.rmSync(filePath, { force: true });\n return undefined;\n }\n\n const missingMcpDirectTools = mcpDirectTools?.length ? missing.filter((name) => mcpDirectTools.includes(name)) : [];\n const diagnostic: ChildToolDiagnostic = {\n ...(agent !== undefined ? { agent } : {}),\n required,\n available,\n missing,\n ...(missingMcpDirectTools.length > 0 ? { missingMcpDirectTools } : {}),\n };\n writePrivateAtomicJson(filePath, diagnostic);\n return diagnostic;\n}\n\n/** Read a diagnostic written by a child. Throws when the file exists but is not one. */\nexport function readChildToolDiagnostic(filePath: string | undefined): ChildToolDiagnostic | undefined {\n if (!filePath || !fs.existsSync(filePath)) return undefined;\n const parsed: unknown = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n if (\n !isRecord(parsed) ||\n !isNonEmptyStringArray(parsed.required) ||\n !isNonEmptyStringArray(parsed.available) ||\n !isNonEmptyStringArray(parsed.missing) ||\n (parsed.agent !== undefined && typeof parsed.agent !== 'string') ||\n (parsed.missingMcpDirectTools !== undefined && !isNonEmptyStringArray(parsed.missingMcpDirectTools))\n ) {\n throw new Error(`Malformed child tool diagnostic at '${filePath}'.`);\n }\n return {\n ...(parsed.agent ? { agent: parsed.agent } : {}),\n required: parsed.required,\n available: parsed.available,\n missing: parsed.missing,\n ...(parsed.missingMcpDirectTools ? { missingMcpDirectTools: parsed.missingMcpDirectTools } : {}),\n };\n}\n\nexport function formatChildToolDiagnostic(diagnostic: ChildToolDiagnostic): string {\n const subject = diagnostic.agent ? `Agent '${diagnostic.agent}'` : 'Subagent';\n return [\n `${subject} requested unavailable child tools: ${diagnostic.missing.join(', ')}.`,\n 'The `tools` field is a strict allowlist; it does not load extension code.',\n ...(diagnostic.missingMcpDirectTools?.length\n ? [\n `Resolved MCP direct tools missing from the child registry: ${diagnostic.missingMcpDirectTools.join(', ')}. This indicates a doom-mcp registration problem, not a tool-call failure.`,\n ]\n : []),\n 'For extension tools, add the provider path to `subagentOnlyExtensions` (child-only), `extensions`, or as a path-like entry in `tools`, while keeping each registered tool name in `tools`.',\n 'For MCP tools, check `/mcp` in the parent session for the server state, and verify the selected tool names. For builtin tools, verify the name against the installed Pi version.',\n ].join('\\n');\n}\n\n/**\n * The reportable message for a run, or undefined when nothing was missing.\n *\n * A read failure is surfaced as its own message rather than swallowed: the file\n * existing at all means the child had a tool gap, so returning undefined here\n * would report a broken run as a clean one.\n */\nexport function readChildToolDiagnosticError(filePath: string | undefined): string | undefined {\n try {\n const diagnostic = readChildToolDiagnostic(filePath);\n return diagnostic ? formatChildToolDiagnostic(diagnostic) : undefined;\n } catch (error) {\n return `Failed to read child tool availability diagnostic: ${error instanceof Error ? error.message : String(error)}`;\n }\n}\n"],"mappings":"2IAuCA,MAAM,EAAmB,IAAI,IAAI,CAAC,OAAQ,OAAQ,OAAQ,OAAQ,KAAM,OAAQ,QAAQ,CAAC,CAgBzF,SAAgB,EACd,EACA,EACA,EACA,EACA,EACiC,CACjC,IAAM,EAAiB,IAAI,IAAI,CAAC,GAAG,EAAW,GAAG,EAAiB,CAAC,CAC7D,EAAU,EAAS,OAAQ,GAAS,CAAC,EAAe,IAAI,EAAK,CAAC,CACpE,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAG,OAAO,EAAU,CAAE,MAAO,GAAM,CAAC,CACpC,OAGF,IAAM,EAAwB,GAAgB,OAAS,EAAQ,OAAQ,GAAS,EAAe,SAAS,EAAK,CAAC,CAAG,EAAE,CAC7G,EAAkC,CACtC,GAAI,IAAU,IAAA,GAAwB,EAAE,CAAd,CAAE,QAAO,CACnC,WACA,YACA,UACA,GAAI,EAAsB,OAAS,EAAI,CAAE,wBAAuB,CAAG,EAAE,CACtE,CAED,OADA,EAAA,uBAAuB,EAAU,EAAW,CACrC"}
@@ -1,2 +0,0 @@
1
- import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import{init_atomicJson as t,writePrivateAtomicJson as n}from"../../shared/atomicJson.mjs";import*as r from"node:fs";function i(e,t,i,o,s){let c=new Set([...i,...a]),l=t.filter(e=>!c.has(e));if(l.length===0){r.rmSync(e,{force:!0});return}let u=s?.length?l.filter(e=>s.includes(e)):[],d={...o===void 0?{}:{agent:o},required:t,available:i,missing:l,...u.length>0?{missingMcpDirectTools:u}:{}};return n(e,d),d}var a,o=e((()=>{t(),a=new Set([`bash`,`edit`,`find`,`grep`,`ls`,`read`,`write`])}));o();export{o as init_toolAvailability,i as writeChildToolDiagnostic};
2
- //# sourceMappingURL=toolAvailability.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"toolAvailability.mjs","names":[],"sources":["../../../src/runs/shared/toolAvailability.ts"],"sourcesContent":["/**\n * Diagnostics for child tools an agent asked for that the child never registered.\n *\n * The `tools` field on an agent is a strict allowlist: it selects from what the\n * child process already has, it does not cause extension code to load. When the\n * two disagree the child notices, not the parent, and the child's stderr is not\n * where a user looks. So the child drops a small file the parent reads after the\n * run and turns into an actionable message.\n *\n * DESIGN PATTERNS:\n * - The file is a negative signal only. A run with nothing missing removes it,\n * so a stale file from an earlier run can never be reported against a later one\n * - Written 0600 and atomically, because it is parsed by a different process and\n * a torn read is indistinguishable from a corrupt file\n * - Reads validate every field. The file is JSON on disk that any process could\n * have written, so nothing is trusted on shape alone\n *\n * AVOID:\n * - Treating a malformed diagnostic as \"nothing missing\"; it is reported as a\n * read failure instead, because a silent empty result hides the tool gap\n */\n\nimport * as fs from 'node:fs';\nimport { writePrivateAtomicJson } from '../../shared/atomicJson.ts';\n\nexport interface ChildToolDiagnostic {\n agent?: string;\n required: string[];\n available: string[];\n missing: string[];\n missingMcpDirectTools?: string[];\n}\n\n/**\n * Tools every child has regardless of what it reported.\n *\n * The child registry snapshot can be taken before the builtins finish\n * registering, so treating these as always available avoids a false alarm.\n */\nconst CORE_CHILD_TOOLS = new Set(['bash', 'edit', 'find', 'grep', 'ls', 'read', 'write']);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === 'string' && entry.length > 0);\n}\n\n/**\n * Record the gap between requested and registered tools, or clear a stale record.\n *\n * Returns the diagnostic when there is one so the caller can report it without\n * reading back what it just wrote.\n */\nexport function writeChildToolDiagnostic(\n filePath: string,\n required: string[],\n available: string[],\n agent?: string,\n mcpDirectTools?: string[],\n): ChildToolDiagnostic | undefined {\n const availableNames = new Set([...available, ...CORE_CHILD_TOOLS]);\n const missing = required.filter((name) => !availableNames.has(name));\n if (missing.length === 0) {\n fs.rmSync(filePath, { force: true });\n return undefined;\n }\n\n const missingMcpDirectTools = mcpDirectTools?.length ? missing.filter((name) => mcpDirectTools.includes(name)) : [];\n const diagnostic: ChildToolDiagnostic = {\n ...(agent !== undefined ? { agent } : {}),\n required,\n available,\n missing,\n ...(missingMcpDirectTools.length > 0 ? { missingMcpDirectTools } : {}),\n };\n writePrivateAtomicJson(filePath, diagnostic);\n return diagnostic;\n}\n\n/** Read a diagnostic written by a child. Throws when the file exists but is not one. */\nexport function readChildToolDiagnostic(filePath: string | undefined): ChildToolDiagnostic | undefined {\n if (!filePath || !fs.existsSync(filePath)) return undefined;\n const parsed: unknown = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n if (\n !isRecord(parsed) ||\n !isNonEmptyStringArray(parsed.required) ||\n !isNonEmptyStringArray(parsed.available) ||\n !isNonEmptyStringArray(parsed.missing) ||\n (parsed.agent !== undefined && typeof parsed.agent !== 'string') ||\n (parsed.missingMcpDirectTools !== undefined && !isNonEmptyStringArray(parsed.missingMcpDirectTools))\n ) {\n throw new Error(`Malformed child tool diagnostic at '${filePath}'.`);\n }\n return {\n ...(parsed.agent ? { agent: parsed.agent } : {}),\n required: parsed.required,\n available: parsed.available,\n missing: parsed.missing,\n ...(parsed.missingMcpDirectTools ? { missingMcpDirectTools: parsed.missingMcpDirectTools } : {}),\n };\n}\n\nexport function formatChildToolDiagnostic(diagnostic: ChildToolDiagnostic): string {\n const subject = diagnostic.agent ? `Agent '${diagnostic.agent}'` : 'Subagent';\n return [\n `${subject} requested unavailable child tools: ${diagnostic.missing.join(', ')}.`,\n 'The `tools` field is a strict allowlist; it does not load extension code.',\n ...(diagnostic.missingMcpDirectTools?.length\n ? [\n `Resolved MCP direct tools missing from the child registry: ${diagnostic.missingMcpDirectTools.join(', ')}. This indicates a doom-mcp registration problem, not a tool-call failure.`,\n ]\n : []),\n 'For extension tools, add the provider path to `subagentOnlyExtensions` (child-only), `extensions`, or as a path-like entry in `tools`, while keeping each registered tool name in `tools`.',\n 'For MCP tools, check `/mcp` in the parent session for the server state, and verify the selected tool names. For builtin tools, verify the name against the installed Pi version.',\n ].join('\\n');\n}\n\n/**\n * The reportable message for a run, or undefined when nothing was missing.\n *\n * A read failure is surfaced as its own message rather than swallowed: the file\n * existing at all means the child had a tool gap, so returning undefined here\n * would report a broken run as a clean one.\n */\nexport function readChildToolDiagnosticError(filePath: string | undefined): string | undefined {\n try {\n const diagnostic = readChildToolDiagnostic(filePath);\n return diagnostic ? formatChildToolDiagnostic(diagnostic) : undefined;\n } catch (error) {\n return `Failed to read child tool availability diagnostic: ${error instanceof Error ? error.message : String(error)}`;\n }\n}\n"],"mappings":"oLAuDA,SAAgB,EACd,EACA,EACA,EACA,EACA,EACiC,CACjC,IAAM,EAAiB,IAAI,IAAI,CAAC,GAAG,EAAW,GAAG,EAAiB,CAAC,CAC7D,EAAU,EAAS,OAAQ,GAAS,CAAC,EAAe,IAAI,EAAK,CAAC,CACpE,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAG,OAAO,EAAU,CAAE,MAAO,GAAM,CAAC,CACpC,OAGF,IAAM,EAAwB,GAAgB,OAAS,EAAQ,OAAQ,GAAS,EAAe,SAAS,EAAK,CAAC,CAAG,EAAE,CAC7G,EAAkC,CACtC,GAAI,IAAU,IAAA,GAAwB,EAAE,CAAd,CAAE,QAAO,CACnC,WACA,YACA,UACA,GAAI,EAAsB,OAAS,EAAI,CAAE,wBAAuB,CAAG,EAAE,CACtE,CAED,OADA,EAAuB,EAAU,EAAW,CACrC,qBAvD2D,CAgB9D,EAAmB,IAAI,IAAI,CAAC,OAAQ,OAAQ,OAAQ,OAAQ,KAAM,OAAQ,QAAQ,CAAC"}
@@ -1,2 +0,0 @@
1
- const e=require(`../../env.cjs`),t=[`read`,`grep`,`find`,`ls`];function n(e){return e===`*`?`*`:e===void 0?[...t]:[...new Set(e.map(e=>e.trim()).filter(Boolean))]}function r(e,t=`toolBudget`,r={}){if(e===void 0)return{};if(typeof e!=`object`||!e||Array.isArray(e))return{error:`${t} must be an object with hard and optional soft/block.`};let i=e,a=r.minimumHard??1,o=i.hard;if(typeof o!=`number`||!Number.isInteger(o)||o<a)return{error:`${t}.hard must be an integer >= ${a}.`};let s=i.soft;if(s!==void 0&&(typeof s!=`number`||!Number.isInteger(s)||s<1))return{error:`${t}.soft must be an integer >= 1 when provided.`};if(s!==void 0&&s>o)return{error:`${t}.soft must be <= ${t}.hard.`};let c=i.block,l;if(c!==void 0&&c!==`*`){if(!Array.isArray(c))return{error:`${t}.block must be "*" or an array of tool names.`};if(c.length===0)return{error:`${t}.block must contain at least one tool name.`};for(let e of c)if(typeof e!=`string`||!e.trim())return{error:`${t}.block must contain non-empty tool names.`};l=c}else l=c;return{budget:{hard:o,...s===void 0?{}:{soft:s},block:n(l)}}}function i(e,t,n){return n<=e.hard?!1:e.block===`*`||e.block.includes(t)}function a(e,t){return`Tool budget soft limit reached after ${t} tool call${t===1?``:`s`} (soft ${e.soft}, hard ${e.hard}). Stop starting new browsing/search work and finalize from the context you already have.`}function o(e,t,n){return`Tool budget hard limit reached after ${n} tool call${n===1?``:`s`} (hard ${e.hard}). The '${t}' tool is blocked so you can finalize from the context you already have.`}function s(e){return e?JSON.stringify(e):void 0}function c(t,n={}){if(!t?.trim())return;let i=r(JSON.parse(t),e.TOOL_BUDGET_ENV,n.allowZero?{minimumHard:0}:void 0);if(i.error)throw Error(i.error);return i.budget}exports.decodeToolBudgetEnv=c,exports.encodeToolBudgetEnv=s,exports.shouldBlockToolForBudget=i,exports.toolBudgetBlockedMessage=o,exports.toolBudgetSoftNudge=a;
2
- //# sourceMappingURL=toolBudget.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"toolBudget.cjs","names":["TOOL_BUDGET_ENV"],"sources":["../../../src/runs/shared/toolBudget.ts"],"sourcesContent":["/**\n * Tool-call budget validation, enforcement predicates and its process handoff.\n *\n * DESIGN PATTERNS:\n * - Pure functions over a resolved budget; the running tool count is the\n * caller's, so this module has nothing to reset between runs\n * - The budget crosses into the child as one JSON environment value, encoded and\n * decoded here, so parent and child can never disagree about its shape\n *\n * WHY BLOCKING IS NARROWED TO A TOOL LIST:\n * The point of the hard limit is to stop open-ended browsing and searching, not\n * to strand a child that still has to write its answer. Blocking only the\n * read-style tools leaves `edit`, `write` and the reporting path available past\n * the limit, so an over-budget child finishes rather than fails.\n *\n * AVOID:\n * - Blocking on the call that reaches the hard limit; the count must exceed it\n * first, so the budgeted number of calls actually happens\n * - Reading the environment variable name from anywhere but `src/env.ts`\n */\n\nimport { TOOL_BUDGET_ENV } from '../../env.ts';\nimport type { ToolBudgetConfig } from '../../types.ts';\n\n/** A tool budget with its block list settled. */\nexport interface ResolvedToolBudget {\n soft?: number;\n hard: number;\n block: string[] | '*';\n}\n\n/** How a run stands against its tool budget. */\nexport type ToolBudgetOutcome = 'within-budget' | 'soft-reached' | 'hard-blocked';\n\n/** The budget plus everything observed about it during one run. */\nexport interface ToolBudgetState extends ResolvedToolBudget {\n outcome: ToolBudgetOutcome;\n toolCount: number;\n softReachedAt?: number;\n hardReachedAt?: number;\n blockedTool?: string;\n}\n\n/**\n * Blocked by default: the read-style tools a child loops on when it is stuck.\n *\n * Deliberately excludes `edit` and `write` so an over-budget child can still\n * land the work it has already reasoned about.\n */\nexport const DEFAULT_TOOL_BUDGET_BLOCK = ['read', 'grep', 'find', 'ls'] as const;\n\nconst BLOCK_ALL_TOOLS = '*';\nconst MIN_SOFT_LIMIT = 1;\nconst DEFAULT_MINIMUM_HARD_LIMIT = 1;\n\n/** Deduplicate and trim an authored block list, or pass through the block-all marker. */\nexport function normalizeToolBudgetBlock(block: ToolBudgetConfig['block'] | undefined): '*' | string[] {\n if (block === BLOCK_ALL_TOOLS) return BLOCK_ALL_TOOLS;\n if (block === undefined) return [...DEFAULT_TOOL_BUDGET_BLOCK];\n return [...new Set(block.map((tool) => tool.trim()).filter(Boolean))];\n}\n\n/**\n * Validate an authored tool budget and settle its block list.\n *\n * `minimumHard` is 0 only for the zero-authorised path, where a caller has\n * explicitly asked for a budget that blocks every tool from the first call.\n */\nexport function validateToolBudgetConfig(\n raw: unknown,\n label = 'toolBudget',\n options: { minimumHard?: 0 | 1 } = {},\n): { budget?: ResolvedToolBudget; error?: string } {\n if (raw === undefined) return {};\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n return { error: `${label} must be an object with hard and optional soft/block.` };\n }\n const value: Record<string, unknown> = raw as Record<string, unknown>;\n const minimumHard = options.minimumHard ?? DEFAULT_MINIMUM_HARD_LIMIT;\n\n const hard = value.hard;\n if (typeof hard !== 'number' || !Number.isInteger(hard) || hard < minimumHard) {\n return { error: `${label}.hard must be an integer >= ${minimumHard}.` };\n }\n const soft = value.soft;\n if (soft !== undefined && (typeof soft !== 'number' || !Number.isInteger(soft) || soft < MIN_SOFT_LIMIT)) {\n return { error: `${label}.soft must be an integer >= ${MIN_SOFT_LIMIT} when provided.` };\n }\n if (soft !== undefined && soft > hard) {\n return { error: `${label}.soft must be <= ${label}.hard.` };\n }\n\n const rawBlock = value.block;\n let block: ToolBudgetConfig['block'] | undefined;\n if (rawBlock !== undefined && rawBlock !== BLOCK_ALL_TOOLS) {\n if (!Array.isArray(rawBlock)) return { error: `${label}.block must be \"*\" or an array of tool names.` };\n if (rawBlock.length === 0) return { error: `${label}.block must contain at least one tool name.` };\n for (const item of rawBlock) {\n if (typeof item !== 'string' || !item.trim()) {\n return { error: `${label}.block must contain non-empty tool names.` };\n }\n }\n block = rawBlock as string[];\n } else {\n block = rawBlock;\n }\n\n return {\n budget: {\n hard,\n ...(soft !== undefined ? { soft } : {}),\n block: normalizeToolBudgetBlock(block),\n },\n };\n}\n\nexport function initialToolBudgetState(budget: ResolvedToolBudget): ToolBudgetState {\n return { ...budget, toolCount: 0, outcome: 'within-budget' };\n}\n\nexport function toolBudgetState(budget: ResolvedToolBudget, toolCount: number, blockedTool?: string): ToolBudgetState {\n const overHard = toolCount > budget.hard;\n const overSoft = budget.soft !== undefined && toolCount >= budget.soft;\n return {\n ...budget,\n toolCount,\n outcome: overHard ? 'hard-blocked' : overSoft ? 'soft-reached' : 'within-budget',\n ...(overSoft ? { softReachedAt: budget.soft } : {}),\n ...(overHard ? { hardReachedAt: budget.hard, blockedTool } : {}),\n };\n}\n\n/**\n * Whether this call must be refused.\n *\n * `nextToolCount` is the count including the call being decided, so the budgeted\n * number of calls runs and only the one after it is refused.\n */\nexport function shouldBlockToolForBudget(budget: ResolvedToolBudget, toolName: string, nextToolCount: number): boolean {\n if (nextToolCount <= budget.hard) return false;\n return budget.block === BLOCK_ALL_TOOLS || budget.block.includes(toolName);\n}\n\nexport function toolBudgetSoftNudge(budget: ResolvedToolBudget, toolCount: number): string {\n return `Tool budget soft limit reached after ${toolCount} tool call${toolCount === 1 ? '' : 's'} (soft ${budget.soft}, hard ${budget.hard}). Stop starting new browsing/search work and finalize from the context you already have.`;\n}\n\nexport function toolBudgetBlockedMessage(budget: ResolvedToolBudget, toolName: string, toolCount: number): string {\n return `Tool budget hard limit reached after ${toolCount} tool call${toolCount === 1 ? '' : 's'} (hard ${budget.hard}). The '${toolName}' tool is blocked so you can finalize from the context you already have.`;\n}\n\nexport function encodeToolBudgetEnv(budget: ResolvedToolBudget | undefined): string | undefined {\n return budget ? JSON.stringify(budget) : undefined;\n}\n\n/**\n * Read the budget a parent handed to this child.\n *\n * Throws rather than returning an error string: an unreadable budget means the\n * child cannot know what it is allowed to do, and running unbudgeted would\n * silently defeat the cap the parent set.\n */\nexport function decodeToolBudgetEnv(\n value: string | undefined,\n options: { allowZero?: boolean } = {},\n): ResolvedToolBudget | undefined {\n if (!value?.trim()) return undefined;\n const parsed: unknown = JSON.parse(value);\n const normalized = validateToolBudgetConfig(\n parsed,\n TOOL_BUDGET_ENV,\n options.allowZero ? { minimumHard: 0 } : undefined,\n );\n if (normalized.error) throw new Error(normalized.error);\n return normalized.budget;\n}\n"],"mappings":"iCAiDa,EAA4B,CAAC,OAAQ,OAAQ,OAAQ,KAAK,CAOvE,SAAgB,EAAyB,EAA8D,CAGrG,OAFI,IAAU,IAAwB,IAClC,IAAU,IAAA,GAAkB,CAAC,GAAG,EAA0B,CACvD,CAAC,GAAG,IAAI,IAAI,EAAM,IAAK,GAAS,EAAK,MAAM,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,CASvE,SAAgB,EACd,EACA,EAAQ,aACR,EAAmC,EAAE,CACY,CACjD,GAAI,IAAQ,IAAA,GAAW,MAAO,EAAE,CAChC,GAAI,OAAO,GAAQ,WAAY,GAAgB,MAAM,QAAQ,EAAI,CAC/D,MAAO,CAAE,MAAO,GAAG,EAAM,uDAAwD,CAEnF,IAAM,EAAiC,EACjC,EAAc,EAAQ,aAAe,EAErC,EAAO,EAAM,KACnB,GAAI,OAAO,GAAS,UAAY,CAAC,OAAO,UAAU,EAAK,EAAI,EAAO,EAChE,MAAO,CAAE,MAAO,GAAG,EAAM,8BAA8B,EAAY,GAAI,CAEzE,IAAM,EAAO,EAAM,KACnB,GAAI,IAAS,IAAA,KAAc,OAAO,GAAS,UAAY,CAAC,OAAO,UAAU,EAAK,EAAI,EAAO,GACvF,MAAO,CAAE,MAAO,GAAG,EAAM,8CAA+D,CAE1F,GAAI,IAAS,IAAA,IAAa,EAAO,EAC/B,MAAO,CAAE,MAAO,GAAG,EAAM,mBAAmB,EAAM,QAAS,CAG7D,IAAM,EAAW,EAAM,MACnB,EACJ,GAAI,IAAa,IAAA,IAAa,IAAa,IAAiB,CAC1D,GAAI,CAAC,MAAM,QAAQ,EAAS,CAAE,MAAO,CAAE,MAAO,GAAG,EAAM,+CAAgD,CACvG,GAAI,EAAS,SAAW,EAAG,MAAO,CAAE,MAAO,GAAG,EAAM,6CAA8C,CAClG,IAAK,IAAM,KAAQ,EACjB,GAAI,OAAO,GAAS,UAAY,CAAC,EAAK,MAAM,CAC1C,MAAO,CAAE,MAAO,GAAG,EAAM,2CAA4C,CAGzE,EAAQ,OAER,EAAQ,EAGV,MAAO,CACL,OAAQ,CACN,OACA,GAAI,IAAS,IAAA,GAAuB,EAAE,CAAb,CAAE,OAAM,CACjC,MAAO,EAAyB,EAAM,CACvC,CACF,CAyBH,SAAgB,EAAyB,EAA4B,EAAkB,EAAgC,CAErH,OADI,GAAiB,EAAO,KAAa,GAClC,EAAO,QAAU,KAAmB,EAAO,MAAM,SAAS,EAAS,CAG5E,SAAgB,EAAoB,EAA4B,EAA2B,CACzF,MAAO,wCAAwC,EAAU,YAAY,IAAc,EAAI,GAAK,IAAI,SAAS,EAAO,KAAK,SAAS,EAAO,KAAK,2FAG5I,SAAgB,EAAyB,EAA4B,EAAkB,EAA2B,CAChH,MAAO,wCAAwC,EAAU,YAAY,IAAc,EAAI,GAAK,IAAI,SAAS,EAAO,KAAK,UAAU,EAAS,0EAG1I,SAAgB,EAAoB,EAA4D,CAC9F,OAAO,EAAS,KAAK,UAAU,EAAO,CAAG,IAAA,GAU3C,SAAgB,EACd,EACA,EAAmC,EAAE,CACL,CAChC,GAAI,CAAC,GAAO,MAAM,CAAE,OAEpB,IAAM,EAAa,EADK,KAAK,MAAM,EAE3B,CACNA,EAAAA,gBACA,EAAQ,UAAY,CAAE,YAAa,EAAG,CAAG,IAAA,GAC1C,CACD,GAAI,EAAW,MAAO,MAAU,MAAM,EAAW,MAAM,CACvD,OAAO,EAAW"}
@@ -1,2 +0,0 @@
1
- import{__esmMin as e}from"../../_virtual/_rolldown/runtime.mjs";import{TOOL_BUDGET_ENV as t,init_env as n}from"../../env.mjs";function r(e){return e===d?d:e===void 0?[...u]:[...new Set(e.map(e=>e.trim()).filter(Boolean))]}function i(e,t=`toolBudget`,n={}){if(e===void 0)return{};if(typeof e!=`object`||!e||Array.isArray(e))return{error:`${t} must be an object with hard and optional soft/block.`};let i=e,a=n.minimumHard??p,o=i.hard;if(typeof o!=`number`||!Number.isInteger(o)||o<a)return{error:`${t}.hard must be an integer >= ${a}.`};let s=i.soft;if(s!==void 0&&(typeof s!=`number`||!Number.isInteger(s)||s<f))return{error:`${t}.soft must be an integer >= ${f} when provided.`};if(s!==void 0&&s>o)return{error:`${t}.soft must be <= ${t}.hard.`};let c=i.block,l;if(c!==void 0&&c!==d){if(!Array.isArray(c))return{error:`${t}.block must be "*" or an array of tool names.`};if(c.length===0)return{error:`${t}.block must contain at least one tool name.`};for(let e of c)if(typeof e!=`string`||!e.trim())return{error:`${t}.block must contain non-empty tool names.`};l=c}else l=c;return{budget:{hard:o,...s===void 0?{}:{soft:s},block:r(l)}}}function a(e,t,n){return n<=e.hard?!1:e.block===d||e.block.includes(t)}function o(e,t){return`Tool budget soft limit reached after ${t} tool call${t===1?``:`s`} (soft ${e.soft}, hard ${e.hard}). Stop starting new browsing/search work and finalize from the context you already have.`}function s(e,t,n){return`Tool budget hard limit reached after ${n} tool call${n===1?``:`s`} (hard ${e.hard}). The '${t}' tool is blocked so you can finalize from the context you already have.`}function c(e){return e?JSON.stringify(e):void 0}function l(e,n={}){if(!e?.trim())return;let r=i(JSON.parse(e),t,n.allowZero?{minimumHard:0}:void 0);if(r.error)throw Error(r.error);return r.budget}var u,d,f,p,m=e((()=>{n(),u=[`read`,`grep`,`find`,`ls`],d=`*`,f=1,p=1}));m();export{l as decodeToolBudgetEnv,c as encodeToolBudgetEnv,m as init_toolBudget,a as shouldBlockToolForBudget,s as toolBudgetBlockedMessage,o as toolBudgetSoftNudge};
2
- //# sourceMappingURL=toolBudget.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"toolBudget.mjs","names":[],"sources":["../../../src/runs/shared/toolBudget.ts"],"sourcesContent":["/**\n * Tool-call budget validation, enforcement predicates and its process handoff.\n *\n * DESIGN PATTERNS:\n * - Pure functions over a resolved budget; the running tool count is the\n * caller's, so this module has nothing to reset between runs\n * - The budget crosses into the child as one JSON environment value, encoded and\n * decoded here, so parent and child can never disagree about its shape\n *\n * WHY BLOCKING IS NARROWED TO A TOOL LIST:\n * The point of the hard limit is to stop open-ended browsing and searching, not\n * to strand a child that still has to write its answer. Blocking only the\n * read-style tools leaves `edit`, `write` and the reporting path available past\n * the limit, so an over-budget child finishes rather than fails.\n *\n * AVOID:\n * - Blocking on the call that reaches the hard limit; the count must exceed it\n * first, so the budgeted number of calls actually happens\n * - Reading the environment variable name from anywhere but `src/env.ts`\n */\n\nimport { TOOL_BUDGET_ENV } from '../../env.ts';\nimport type { ToolBudgetConfig } from '../../types.ts';\n\n/** A tool budget with its block list settled. */\nexport interface ResolvedToolBudget {\n soft?: number;\n hard: number;\n block: string[] | '*';\n}\n\n/** How a run stands against its tool budget. */\nexport type ToolBudgetOutcome = 'within-budget' | 'soft-reached' | 'hard-blocked';\n\n/** The budget plus everything observed about it during one run. */\nexport interface ToolBudgetState extends ResolvedToolBudget {\n outcome: ToolBudgetOutcome;\n toolCount: number;\n softReachedAt?: number;\n hardReachedAt?: number;\n blockedTool?: string;\n}\n\n/**\n * Blocked by default: the read-style tools a child loops on when it is stuck.\n *\n * Deliberately excludes `edit` and `write` so an over-budget child can still\n * land the work it has already reasoned about.\n */\nexport const DEFAULT_TOOL_BUDGET_BLOCK = ['read', 'grep', 'find', 'ls'] as const;\n\nconst BLOCK_ALL_TOOLS = '*';\nconst MIN_SOFT_LIMIT = 1;\nconst DEFAULT_MINIMUM_HARD_LIMIT = 1;\n\n/** Deduplicate and trim an authored block list, or pass through the block-all marker. */\nexport function normalizeToolBudgetBlock(block: ToolBudgetConfig['block'] | undefined): '*' | string[] {\n if (block === BLOCK_ALL_TOOLS) return BLOCK_ALL_TOOLS;\n if (block === undefined) return [...DEFAULT_TOOL_BUDGET_BLOCK];\n return [...new Set(block.map((tool) => tool.trim()).filter(Boolean))];\n}\n\n/**\n * Validate an authored tool budget and settle its block list.\n *\n * `minimumHard` is 0 only for the zero-authorised path, where a caller has\n * explicitly asked for a budget that blocks every tool from the first call.\n */\nexport function validateToolBudgetConfig(\n raw: unknown,\n label = 'toolBudget',\n options: { minimumHard?: 0 | 1 } = {},\n): { budget?: ResolvedToolBudget; error?: string } {\n if (raw === undefined) return {};\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n return { error: `${label} must be an object with hard and optional soft/block.` };\n }\n const value: Record<string, unknown> = raw as Record<string, unknown>;\n const minimumHard = options.minimumHard ?? DEFAULT_MINIMUM_HARD_LIMIT;\n\n const hard = value.hard;\n if (typeof hard !== 'number' || !Number.isInteger(hard) || hard < minimumHard) {\n return { error: `${label}.hard must be an integer >= ${minimumHard}.` };\n }\n const soft = value.soft;\n if (soft !== undefined && (typeof soft !== 'number' || !Number.isInteger(soft) || soft < MIN_SOFT_LIMIT)) {\n return { error: `${label}.soft must be an integer >= ${MIN_SOFT_LIMIT} when provided.` };\n }\n if (soft !== undefined && soft > hard) {\n return { error: `${label}.soft must be <= ${label}.hard.` };\n }\n\n const rawBlock = value.block;\n let block: ToolBudgetConfig['block'] | undefined;\n if (rawBlock !== undefined && rawBlock !== BLOCK_ALL_TOOLS) {\n if (!Array.isArray(rawBlock)) return { error: `${label}.block must be \"*\" or an array of tool names.` };\n if (rawBlock.length === 0) return { error: `${label}.block must contain at least one tool name.` };\n for (const item of rawBlock) {\n if (typeof item !== 'string' || !item.trim()) {\n return { error: `${label}.block must contain non-empty tool names.` };\n }\n }\n block = rawBlock as string[];\n } else {\n block = rawBlock;\n }\n\n return {\n budget: {\n hard,\n ...(soft !== undefined ? { soft } : {}),\n block: normalizeToolBudgetBlock(block),\n },\n };\n}\n\nexport function initialToolBudgetState(budget: ResolvedToolBudget): ToolBudgetState {\n return { ...budget, toolCount: 0, outcome: 'within-budget' };\n}\n\nexport function toolBudgetState(budget: ResolvedToolBudget, toolCount: number, blockedTool?: string): ToolBudgetState {\n const overHard = toolCount > budget.hard;\n const overSoft = budget.soft !== undefined && toolCount >= budget.soft;\n return {\n ...budget,\n toolCount,\n outcome: overHard ? 'hard-blocked' : overSoft ? 'soft-reached' : 'within-budget',\n ...(overSoft ? { softReachedAt: budget.soft } : {}),\n ...(overHard ? { hardReachedAt: budget.hard, blockedTool } : {}),\n };\n}\n\n/**\n * Whether this call must be refused.\n *\n * `nextToolCount` is the count including the call being decided, so the budgeted\n * number of calls runs and only the one after it is refused.\n */\nexport function shouldBlockToolForBudget(budget: ResolvedToolBudget, toolName: string, nextToolCount: number): boolean {\n if (nextToolCount <= budget.hard) return false;\n return budget.block === BLOCK_ALL_TOOLS || budget.block.includes(toolName);\n}\n\nexport function toolBudgetSoftNudge(budget: ResolvedToolBudget, toolCount: number): string {\n return `Tool budget soft limit reached after ${toolCount} tool call${toolCount === 1 ? '' : 's'} (soft ${budget.soft}, hard ${budget.hard}). Stop starting new browsing/search work and finalize from the context you already have.`;\n}\n\nexport function toolBudgetBlockedMessage(budget: ResolvedToolBudget, toolName: string, toolCount: number): string {\n return `Tool budget hard limit reached after ${toolCount} tool call${toolCount === 1 ? '' : 's'} (hard ${budget.hard}). The '${toolName}' tool is blocked so you can finalize from the context you already have.`;\n}\n\nexport function encodeToolBudgetEnv(budget: ResolvedToolBudget | undefined): string | undefined {\n return budget ? JSON.stringify(budget) : undefined;\n}\n\n/**\n * Read the budget a parent handed to this child.\n *\n * Throws rather than returning an error string: an unreadable budget means the\n * child cannot know what it is allowed to do, and running unbudgeted would\n * silently defeat the cap the parent set.\n */\nexport function decodeToolBudgetEnv(\n value: string | undefined,\n options: { allowZero?: boolean } = {},\n): ResolvedToolBudget | undefined {\n if (!value?.trim()) return undefined;\n const parsed: unknown = JSON.parse(value);\n const normalized = validateToolBudgetConfig(\n parsed,\n TOOL_BUDGET_ENV,\n options.allowZero ? { minimumHard: 0 } : undefined,\n );\n if (normalized.error) throw new Error(normalized.error);\n return normalized.budget;\n}\n"],"mappings":"8HAwDA,SAAgB,EAAyB,EAA8D,CAGrG,OAFI,IAAU,EAAwB,EAClC,IAAU,IAAA,GAAkB,CAAC,GAAG,EAA0B,CACvD,CAAC,GAAG,IAAI,IAAI,EAAM,IAAK,GAAS,EAAK,MAAM,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,CASvE,SAAgB,EACd,EACA,EAAQ,aACR,EAAmC,EAAE,CACY,CACjD,GAAI,IAAQ,IAAA,GAAW,MAAO,EAAE,CAChC,GAAI,OAAO,GAAQ,WAAY,GAAgB,MAAM,QAAQ,EAAI,CAC/D,MAAO,CAAE,MAAO,GAAG,EAAM,uDAAwD,CAEnF,IAAM,EAAiC,EACjC,EAAc,EAAQ,aAAe,EAErC,EAAO,EAAM,KACnB,GAAI,OAAO,GAAS,UAAY,CAAC,OAAO,UAAU,EAAK,EAAI,EAAO,EAChE,MAAO,CAAE,MAAO,GAAG,EAAM,8BAA8B,EAAY,GAAI,CAEzE,IAAM,EAAO,EAAM,KACnB,GAAI,IAAS,IAAA,KAAc,OAAO,GAAS,UAAY,CAAC,OAAO,UAAU,EAAK,EAAI,EAAO,GACvF,MAAO,CAAE,MAAO,GAAG,EAAM,8BAA8B,EAAe,iBAAkB,CAE1F,GAAI,IAAS,IAAA,IAAa,EAAO,EAC/B,MAAO,CAAE,MAAO,GAAG,EAAM,mBAAmB,EAAM,QAAS,CAG7D,IAAM,EAAW,EAAM,MACnB,EACJ,GAAI,IAAa,IAAA,IAAa,IAAa,EAAiB,CAC1D,GAAI,CAAC,MAAM,QAAQ,EAAS,CAAE,MAAO,CAAE,MAAO,GAAG,EAAM,+CAAgD,CACvG,GAAI,EAAS,SAAW,EAAG,MAAO,CAAE,MAAO,GAAG,EAAM,6CAA8C,CAClG,IAAK,IAAM,KAAQ,EACjB,GAAI,OAAO,GAAS,UAAY,CAAC,EAAK,MAAM,CAC1C,MAAO,CAAE,MAAO,GAAG,EAAM,2CAA4C,CAGzE,EAAQ,OAER,EAAQ,EAGV,MAAO,CACL,OAAQ,CACN,OACA,GAAI,IAAS,IAAA,GAAuB,EAAE,CAAb,CAAE,OAAM,CACjC,MAAO,EAAyB,EAAM,CACvC,CACF,CAyBH,SAAgB,EAAyB,EAA4B,EAAkB,EAAgC,CAErH,OADI,GAAiB,EAAO,KAAa,GAClC,EAAO,QAAU,GAAmB,EAAO,MAAM,SAAS,EAAS,CAG5E,SAAgB,EAAoB,EAA4B,EAA2B,CACzF,MAAO,wCAAwC,EAAU,YAAY,IAAc,EAAI,GAAK,IAAI,SAAS,EAAO,KAAK,SAAS,EAAO,KAAK,2FAG5I,SAAgB,EAAyB,EAA4B,EAAkB,EAA2B,CAChH,MAAO,wCAAwC,EAAU,YAAY,IAAc,EAAI,GAAK,IAAI,SAAS,EAAO,KAAK,UAAU,EAAS,0EAG1I,SAAgB,EAAoB,EAA4D,CAC9F,OAAO,EAAS,KAAK,UAAU,EAAO,CAAG,IAAA,GAU3C,SAAgB,EACd,EACA,EAAmC,EAAE,CACL,CAChC,GAAI,CAAC,GAAO,MAAM,CAAE,OAEpB,IAAM,EAAa,EADK,KAAK,MAAM,EAE3B,CACN,EACA,EAAQ,UAAY,CAAE,YAAa,EAAG,CAAG,IAAA,GAC1C,CACD,GAAI,EAAW,MAAO,MAAU,MAAM,EAAW,MAAM,CACvD,OAAO,EAAW,gCAzJ2B,CA4BlC,EAA4B,CAAC,OAAQ,OAAQ,OAAQ,KAAK,CAEjE,EAAkB,IAClB,EAAiB,EACjB,EAA6B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"atomicJson.cjs","names":["fs","DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS","waitForFileSystemRetry","path"],"sources":["../../src/shared/atomicJson.ts"],"sourcesContent":["/**\n * Atomic JSON writes.\n *\n * DESIGN PATTERNS:\n * - Write to a uniquely named temp file in the destination directory, then\n * rename onto the target. Rename is atomic within a filesystem, so a reader\n * sees either the previous file or the complete new one, never a partial write\n * - The temp name carries pid, timestamp and a random suffix so two processes\n * writing the same target never collide on the temp file\n *\n * WHAT THIS DOES NOT DO:\n * This prevents torn reads. It does NOT prevent lost updates: two writers doing\n * read-modify-write still clobber each other, because the rename only publishes\n * whatever the caller already computed. Anything needing mutual exclusion has to\n * take a lease or claim, not rely on atomic writes.\n *\n * AVOID:\n * - Treating this as a lock\n * - Using the plain writer for anything sensitive; prefer writePrivateAtomicJson,\n * which creates the file 0600 so a shared temp directory does not leak prompts\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS,\n runFileSystemOperationWithRetry,\n waitForFileSystemRetry,\n} from './fileSystemRetry.ts';\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst JSON_INDENT = 2;\n\ntype AtomicJsonFs = Pick<typeof fs, 'mkdirSync' | 'writeFileSync' | 'renameSync' | 'rmSync'>;\n\ntype AtomicJsonWriterOptions = {\n fs?: AtomicJsonFs;\n now?: () => number;\n pid?: number;\n random?: () => number;\n mode?: number;\n retryRenameErrors?: boolean;\n retryDirectoryErrors?: boolean;\n retryDelaysMs?: readonly number[];\n wait?: (delayMs: number) => void;\n};\n\nexport function createAtomicJsonWriter(\n options: AtomicJsonWriterOptions = {},\n): (filePath: string, payload: object) => void {\n const fsImpl = options.fs ?? fs;\n const now = options.now ?? Date.now;\n const pid = options.pid ?? process.pid;\n const random = options.random ?? Math.random;\n const mode = options.mode;\n // Retries exist for Windows directory and rename locks; other platforms fail fast.\n const retryRenameErrors = options.retryRenameErrors ?? process.platform === 'win32';\n const retryDirectoryErrors = options.retryDirectoryErrors ?? retryRenameErrors;\n const retryDelaysMs = options.retryDelaysMs ?? DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS;\n const renameRetryDelaysMs = retryRenameErrors ? retryDelaysMs : [];\n const directoryRetryDelaysMs = retryDirectoryErrors ? retryDelaysMs : [];\n const wait = options.wait ?? waitForFileSystemRetry;\n\n return (filePath: string, payload: object): void => {\n runFileSystemOperationWithRetry(\n () => {\n fsImpl.mkdirSync(path.dirname(filePath), { recursive: true });\n },\n { retryDelaysMs: directoryRetryDelaysMs, wait },\n );\n const tempPath = path.join(\n path.dirname(filePath),\n `.${path.basename(filePath)}.${pid}.${now()}.${random().toString(36).slice(2)}.tmp`,\n );\n try {\n fsImpl.writeFileSync(\n tempPath,\n JSON.stringify(payload, null, JSON_INDENT),\n mode === undefined ? 'utf-8' : { encoding: 'utf-8', mode },\n );\n runFileSystemOperationWithRetry(\n () => {\n fsImpl.renameSync(tempPath, filePath);\n },\n { retryDelaysMs: renameRetryDelaysMs, wait },\n );\n } finally {\n // Best effort: on the happy path the rename already consumed the temp file.\n fsImpl.rmSync(tempPath, { force: true });\n }\n };\n}\n\nexport const writeAtomicJson = createAtomicJsonWriter();\nexport const writePrivateAtomicJson = createAtomicJsonWriter({ mode: PRIVATE_FILE_MODE });\n"],"mappings":"8KA+CA,SAAgB,EACd,EAAmC,EAAE,CACQ,CAC7C,IAAM,EAAS,EAAQ,IAAMA,EACvB,EAAM,EAAQ,KAAO,KAAK,IAC1B,EAAM,EAAQ,KAAO,QAAQ,IAC7B,EAAS,EAAQ,QAAU,KAAK,OAChC,EAAO,EAAQ,KAEf,EAAoB,EAAQ,mBAAqB,QAAQ,WAAa,QACtE,EAAuB,EAAQ,sBAAwB,EACvD,EAAgB,EAAQ,eAAiBC,EAAAA,oCACzC,EAAsB,EAAoB,EAAgB,EAAE,CAC5D,EAAyB,EAAuB,EAAgB,EAAE,CAClE,EAAO,EAAQ,MAAQC,EAAAA,uBAE7B,OAAQ,EAAkB,IAA0B,CAClD,EAAA,oCACQ,CACJ,EAAO,UAAUC,EAAK,QAAQ,EAAS,CAAE,CAAE,UAAW,GAAM,CAAC,EAE/D,CAAE,cAAe,EAAwB,OAAM,CAChD,CACD,IAAM,EAAWA,EAAK,KACpBA,EAAK,QAAQ,EAAS,CACtB,IAAIA,EAAK,SAAS,EAAS,CAAC,GAAG,EAAI,GAAG,GAAK,CAAC,GAAG,GAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAAC,MAC/E,CACD,GAAI,CACF,EAAO,cACL,EACA,KAAK,UAAU,EAAS,KAAM,EAAY,CAC1C,IAAS,IAAA,GAAY,QAAU,CAAE,SAAU,QAAS,OAAM,CAC3D,CACD,EAAA,oCACQ,CACJ,EAAO,WAAW,EAAU,EAAS,EAEvC,CAAE,cAAe,EAAqB,OAAM,CAC7C,QACO,CAER,EAAO,OAAO,EAAU,CAAE,MAAO,GAAM,CAAC,GAK9C,MAAa,EAAkB,GAAwB,CAC1C,EAAyB,EAAuB,CAAE,KAAM,IAAmB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"childTranscript.cjs","names":["path"],"sources":["../../src/shared/childTranscript.ts"],"sourcesContent":["/**\n * Append-only JSONL transcript of one child run, written by the parent.\n *\n * WHY THE PARENT WRITES ITS OWN:\n * The child's session transcript lives in the host agent's config directory and\n * is keyed by a session id the parent does not learn until the run ends. This\n * file is the parent's independent record: it exists from the first prompt, it\n * survives a child that never started, and it carries the stdout and stderr the\n * child's own transcript has no place for.\n *\n * DESIGN PATTERNS:\n * - Two independent byte budgets. Each tool payload is capped so one huge result\n * cannot consume the file, and the file itself is capped so a runaway child\n * cannot fill the disk\n * - The file budget reserves room for the truncation marker up front, so the\n * record that trips the limit is dropped in favour of a record explaining why\n * - Write failures latch into one reported error instead of throwing. This file\n * is evidence about a run, so losing it must never end the run it describes\n * - Truncation is carried as a flag beside the text. The predecessor rediscovered\n * it by searching the output for the marker substring, which any payload\n * quoting that phrase would have tripped\n *\n * PERFORMANCE:\n * The marker's byte size is measured once. Every field feeding it is fixed for\n * the writer's lifetime and both timestamps are fixed width, so the predecessor's\n * re-serialisation of the marker on every single record bought nothing.\n *\n * AVOID:\n * - Throwing from any writer method\n * - Cutting a payload mid-character; the cut walks back off UTF-8 continuation\n * bytes before slicing\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport const CHILD_TRANSCRIPT_ARTIFACT_VERSION = 1;\n\nconst BYTES_PER_KIB = 1024;\nconst BYTES_PER_MIB = 1024 * BYTES_PER_KIB;\nconst MAX_TOOL_PAYLOAD_BYTES = 32 * BYTES_PER_KIB;\nconst DEFAULT_MAX_CHILD_TRANSCRIPT_BYTES = 50 * BYTES_PER_MIB;\nconst TOOL_PAYLOAD_TRUNCATION_MARKER = '\\n\\n… payload truncated';\nconst JSON_INDENT = 2;\n\n/** High bits identifying a UTF-8 continuation byte (10xxxxxx). */\nconst UTF8_CONTINUATION_MASK = 0xc0;\nconst UTF8_CONTINUATION_BITS = 0x80;\n\nconst PREVIEW_ELLIPSIS = '...';\nconst PREVIEW_MAX_LENGTH = 60;\nconst FALLBACK_PREVIEW_MAX_LENGTH = 50;\nconst WORKFLOW_PREVIEW_MAX_LENGTH = 48;\nconst MCP_ARGS_PREVIEW_MAX_LENGTH = 40;\n\n/** Argument keys worth previewing verbatim, in the order they are preferred. */\nconst PREVIEW_KEYS = ['command', 'path', 'file_path', 'pattern', 'query', 'url', 'task', 'describe', 'search'] as const;\n\n/**\n * Which execution path produced the records in a file.\n *\n * Only background runs exist, so this is single-valued today. It is still\n * written into every record because the file is read by tools that must be able\n * to tell what produced it without being told out of band, and because a second\n * variant is cheaper to add than to retrofit onto files already on disk.\n */\nexport type ChildTranscriptSource = 'async';\n\nexport type ChildTranscriptRecordType = 'message' | 'tool_start' | 'tool_end' | 'stdout' | 'stderr' | 'truncated';\n\n/**\n * The message fields this transcript records.\n *\n * Declared structurally rather than imported from the host agent's message type:\n * the writer only reads these fields, and a shared leaf should not take on an\n * optional peer dependency to describe them.\n */\nexport interface ChildTranscriptMessage {\n role: string;\n content?: unknown;\n toolCallId?: string;\n toolName?: string;\n isError?: boolean;\n timestamp?: unknown;\n model?: string;\n errorMessage?: string;\n stopReason?: string;\n usage?: unknown;\n}\n\nexport interface ChildTranscriptEvent {\n type?: string;\n message?: ChildTranscriptMessage;\n toolCallId?: string;\n toolName?: string;\n args?: unknown;\n isError?: boolean;\n}\n\nexport interface ChildTranscriptWriterInput {\n transcriptPath: string;\n source: ChildTranscriptSource;\n runId: string;\n agent: string;\n childIndex?: number;\n cwd: string;\n maxBytes?: number;\n}\n\nexport interface ChildTranscriptWriter {\n path: string;\n writeInitialUserMessage(prompt: string): void;\n writeChildEvent(event: ChildTranscriptEvent): void;\n writeStdoutLine(line: string): void;\n writeStderrLine(line: string): void;\n writeStderrText(text: string): void;\n getError(): string | undefined;\n}\n\ninterface BoundedPayload {\n text: string;\n truncated: boolean;\n}\n\ninterface NormalizedUsage {\n input: number;\n output: number;\n cacheRead: number;\n cacheWrite: number;\n cost: number;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction finiteNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\n/**\n * Render `value` as text no larger than `maxBytes`, or undefined if it carries\n * nothing worth recording.\n *\n * A value that cannot be serialised (a cycle, a BigInt) is dropped rather than\n * reported, because a tool payload is context and not part of the run's result.\n */\nfunction boundedPayload(value: unknown, maxBytes = MAX_TOOL_PAYLOAD_BYTES): BoundedPayload | undefined {\n let text: string;\n if (typeof value === 'string') {\n text = value;\n } else {\n try {\n const serialized = JSON.stringify(value, null, JSON_INDENT);\n if (serialized === undefined) return undefined;\n text = serialized;\n } catch {\n // Cyclic or non-serialisable payloads have no textual form to record.\n return undefined;\n }\n }\n if (!text.trim()) return undefined;\n\n const payload = Buffer.from(text, 'utf-8');\n if (payload.length <= maxBytes) return { text, truncated: false };\n\n const markerBytes = Buffer.byteLength(TOOL_PAYLOAD_TRUNCATION_MARKER, 'utf-8');\n let end = Math.max(0, maxBytes - markerBytes);\n // Back off any continuation bytes so the cut lands on a character boundary.\n while (end > 0 && ((payload[end] ?? 0) & UTF8_CONTINUATION_MASK) === UTF8_CONTINUATION_BITS) end--;\n return {\n text: `${payload.subarray(0, end).toString('utf-8')}${TOOL_PAYLOAD_TRUNCATION_MARKER}`,\n truncated: true,\n };\n}\n\n/**\n * Read a child's usage counters, tolerating both field namings the host has used.\n *\n * Cost arrives either as a number or as an object with a `total`, so both are\n * accepted; anything else counts as zero rather than as missing, because a run\n * with unreadable cost still has a real elapsed usage record.\n */\nfunction normalizeUsage(value: unknown): NormalizedUsage | undefined {\n if (!value || typeof value !== 'object') return undefined;\n const raw = value as Record<string, unknown>;\n const rawCost = raw.cost;\n const cost =\n rawCost && typeof rawCost === 'object'\n ? (finiteNumber((rawCost as { total?: unknown }).total) ?? 0)\n : (finiteNumber(rawCost) ?? 0);\n return {\n input: finiteNumber(raw.input) ?? finiteNumber(raw.inputTokens) ?? 0,\n output: finiteNumber(raw.output) ?? finiteNumber(raw.outputTokens) ?? 0,\n cacheRead: finiteNumber(raw.cacheRead) ?? 0,\n cacheWrite: finiteNumber(raw.cacheWrite) ?? 0,\n cost,\n };\n}\n\n/**\n * Return the token total observed on one finalized child message.\n *\n * Missing usage means that this message carried no observation and therefore\n * returns undefined. An actual usage object with empty or zero buckets returns\n * zero, which is a meaningful observation for live progress.\n */\nexport function getMessageUsageTokens(message: ChildTranscriptMessage): number | undefined {\n const usage = normalizeUsage(message.usage);\n if (!usage) return undefined;\n return usage.input + usage.output + usage.cacheRead + usage.cacheWrite;\n}\n\nfunction truncatePreview(value: string, maxLength: number): string {\n return value.length > maxLength ? `${value.slice(0, maxLength - PREVIEW_ELLIPSIS.length)}${PREVIEW_ELLIPSIS}` : value;\n}\n\nfunction stringifyPreviewValue(value: unknown): string | undefined {\n if (typeof value === 'string' && value.trim().length > 0) return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return undefined;\n}\n\nfunction previewArray(value: unknown): string | undefined {\n if (!Array.isArray(value) || value.length === 0) return undefined;\n const first = stringifyPreviewValue(value[0]);\n if (!first) return undefined;\n const suffix = value.length > 1 ? ` (+${value.length - 1} more)` : '';\n return `${first}${suffix}`;\n}\n\n/**\n * One short line describing what a tool call was asked to do.\n *\n * The ladder is ordered by how much the key tells a reader, not alphabetically:\n * an MCP call is named by server and tool, a search by its query, and everything\n * else falls back to the first stringable argument so the line is never empty\n * when the call had any arguments at all.\n */\nfunction extractToolArgsPreview(args: Record<string, unknown>): string {\n if (typeof args.tool === 'string' && args.tool) {\n const server = typeof args.server === 'string' && args.server ? `${args.server}/` : '';\n const toolArgs =\n typeof args.args === 'string' && args.args ? ` ${args.args.slice(0, MCP_ARGS_PREVIEW_MAX_LENGTH)}` : '';\n return `${server}${args.tool}${toolArgs}`;\n }\n\n const queriesPreview = previewArray(args.queries);\n if (queriesPreview) return truncatePreview(queriesPreview, PREVIEW_MAX_LENGTH);\n if (typeof args.query === 'string' && args.query.trim().length > 0) {\n return truncatePreview(args.query, PREVIEW_MAX_LENGTH);\n }\n if (typeof args.workflow === 'string' && args.workflow.trim().length > 0) {\n return `workflow=${truncatePreview(args.workflow, WORKFLOW_PREVIEW_MAX_LENGTH)}`;\n }\n if (typeof args.url === 'string' && args.url.trim().length > 0) return truncatePreview(args.url, PREVIEW_MAX_LENGTH);\n const urlsPreview = previewArray(args.urls);\n if (urlsPreview) return truncatePreview(urlsPreview, PREVIEW_MAX_LENGTH);\n if (typeof args.prompt === 'string' && args.prompt.trim().length > 0) {\n return truncatePreview(args.prompt, PREVIEW_MAX_LENGTH);\n }\n\n for (const key of PREVIEW_KEYS) {\n const value = args[key];\n if (typeof value === 'string' && value.length > 0) return truncatePreview(value, PREVIEW_MAX_LENGTH);\n }\n\n for (const [key, value] of Object.entries(args)) {\n const arrayPreview = previewArray(value);\n if (arrayPreview) return `${key}=${truncatePreview(arrayPreview, FALLBACK_PREVIEW_MAX_LENGTH)}`;\n if (typeof value === 'string' && value.length > 0) {\n return `${key}=${truncatePreview(value, FALLBACK_PREVIEW_MAX_LENGTH)}`;\n }\n }\n return '';\n}\n\n/**\n * Flatten a message's content into plain text.\n *\n * Content arrives as unknown JSON in four shapes the host has used over time, so\n * every hop is checked. Anything unrecognised contributes nothing rather than\n * being stringified, which would put `[object Object]` into the transcript.\n */\nfunction extractTextFromContent(content: unknown): string {\n if (!content) return '';\n if (typeof content === 'string') return content;\n if (!Array.isArray(content)) return '';\n\n const texts: string[] = [];\n for (const part of content) {\n if (!part || typeof part !== 'object') continue;\n const record = part as Record<string, unknown>;\n if (record.type === 'text' && 'text' in record) {\n texts.push(String(record.text));\n } else if (record.type === 'tool_result' && 'content' in record) {\n const inner = extractTextFromContent(record.content);\n if (inner) texts.push(inner);\n } else if ('text' in record) {\n texts.push(String(record.text));\n }\n }\n return texts.join('\\n');\n}\n\nfunction eventArgs(event: ChildTranscriptEvent): Record<string, unknown> {\n return event.args && typeof event.args === 'object' && !Array.isArray(event.args)\n ? (event.args as Record<string, unknown>)\n : {};\n}\n\nexport function createChildTranscriptWriter(input: ChildTranscriptWriterInput): ChildTranscriptWriter {\n let bytesWritten = 0;\n let writeError: string | undefined;\n let truncated = false;\n const maxBytes = input.maxBytes ?? DEFAULT_MAX_CHILD_TRANSCRIPT_BYTES;\n\n const baseRecord = (recordType: ChildTranscriptRecordType) => {\n const ts = Date.now();\n return {\n version: CHILD_TRANSCRIPT_ARTIFACT_VERSION,\n recordType,\n source: input.source,\n runId: input.runId,\n agent: input.agent,\n ...(input.childIndex !== undefined ? { childIndex: input.childIndex } : {}),\n cwd: input.cwd,\n ts,\n timestamp: new Date(ts).toISOString(),\n };\n };\n\n const truncationMarkerLine = (): string =>\n `${JSON.stringify({\n ...baseRecord('truncated'),\n maxBytes,\n message: `Child transcript exceeded ${maxBytes} bytes; further records were omitted.`,\n })}\\n`;\n\n // Fixed for this writer: every field is constant except the two timestamps,\n // which are fixed width. Measuring once is why writeRecord stays allocation-free.\n const reservedMarkerBytes = Buffer.byteLength(truncationMarkerLine(), 'utf-8');\n\n const writeTruncatedMarker = () => {\n truncated = true;\n const marker = truncationMarkerLine();\n const markerBytes = Buffer.byteLength(marker, 'utf-8');\n if (bytesWritten + markerBytes > maxBytes) return;\n try {\n fs.appendFileSync(input.transcriptPath, marker, 'utf-8');\n bytesWritten += markerBytes;\n } catch (error) {\n writeError = `Failed to write child transcript '${input.transcriptPath}': ${errorMessage(error)}`;\n }\n };\n\n const writeRecord = (record: Record<string, unknown>) => {\n if (writeError || truncated) return;\n const line = `${JSON.stringify(record)}\\n`;\n const bytes = Buffer.byteLength(line, 'utf-8');\n // The marker's room is reserved, so the file can always state why it ended.\n if (bytesWritten + bytes + reservedMarkerBytes > maxBytes) {\n writeTruncatedMarker();\n return;\n }\n try {\n fs.appendFileSync(input.transcriptPath, line, 'utf-8');\n bytesWritten += bytes;\n } catch (error) {\n writeError = `Failed to write child transcript '${input.transcriptPath}': ${errorMessage(error)}`;\n }\n };\n\n try {\n fs.mkdirSync(path.dirname(input.transcriptPath), { recursive: true });\n fs.writeFileSync(input.transcriptPath, '', 'utf-8');\n } catch (error) {\n writeError = `Failed to initialize child transcript '${input.transcriptPath}': ${errorMessage(error)}`;\n }\n\n const writeMessage = (sourceEventType: string, message: ChildTranscriptMessage) => {\n const text = extractTextFromContent(message.content);\n const usage = normalizeUsage(message.usage);\n if (message.role === 'toolResult') {\n const output = boundedPayload(text);\n writeRecord({\n ...baseRecord('message'),\n sourceEventType,\n role: message.role,\n toolCallId: message.toolCallId,\n toolName: message.toolName,\n isError: message.isError,\n ...(output ? { text: output.text, outputTruncated: output.truncated } : {}),\n message: {\n role: message.role,\n toolCallId: message.toolCallId,\n toolName: message.toolName,\n isError: message.isError,\n content: output ? [{ type: 'text', text: output.text }] : [],\n ...(message.timestamp !== undefined ? { timestamp: message.timestamp } : {}),\n },\n });\n return;\n }\n writeRecord({\n ...baseRecord('message'),\n sourceEventType,\n role: message.role,\n ...(text ? { text } : {}),\n ...(message.model ? { model: message.model } : {}),\n ...(message.stopReason ? { stopReason: message.stopReason } : {}),\n ...(message.errorMessage ? { errorMessage: message.errorMessage } : {}),\n ...(usage ? { usage } : {}),\n message,\n });\n };\n\n const writeStderrLine = (line: string) => {\n if (!line.trim()) return;\n writeRecord({ ...baseRecord('stderr'), text: line });\n };\n\n return {\n path: input.transcriptPath,\n writeInitialUserMessage(prompt: string) {\n writeRecord({\n ...baseRecord('message'),\n sourceEventType: 'initial_prompt',\n role: 'user',\n text: prompt,\n message: { role: 'user', content: [{ type: 'text', text: prompt }] },\n });\n },\n writeChildEvent(event: ChildTranscriptEvent) {\n if ((event.type === 'message_end' || event.type === 'tool_result_end') && event.message) {\n writeMessage(event.type, event.message);\n return;\n }\n if (event.type === 'tool_execution_start' && event.toolName) {\n const args = eventArgs(event);\n const argsPayload = boundedPayload(args);\n writeRecord({\n ...baseRecord('tool_start'),\n sourceEventType: event.type,\n ...(event.toolCallId ? { toolCallId: event.toolCallId } : {}),\n toolName: event.toolName,\n ...(Object.keys(args).length > 0 ? { argsPreview: extractToolArgsPreview(args) } : {}),\n ...(argsPayload ? { argsPayload: argsPayload.text } : {}),\n });\n return;\n }\n if (event.type === 'tool_execution_end') {\n writeRecord({\n ...baseRecord('tool_end'),\n sourceEventType: event.type,\n ...(event.toolCallId ? { toolCallId: event.toolCallId } : {}),\n ...(event.toolName ? { toolName: event.toolName } : {}),\n ...(typeof event.isError === 'boolean' ? { isError: event.isError } : {}),\n });\n }\n },\n writeStdoutLine(line: string) {\n if (!line.trim()) return;\n writeRecord({ ...baseRecord('stdout'), text: line });\n },\n writeStderrLine,\n writeStderrText(text: string) {\n for (const line of text.split(/\\r?\\n/)) writeStderrLine(line);\n },\n getError() {\n return writeError;\n },\n };\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"pollScheduler.cjs","names":[],"sources":["../../src/shared/pollScheduler.ts"],"sourcesContent":["/**\n * One master tick that drives every background subscriber in the runner\n * process: channels, watchers, inspectors, anything that used to own its own\n * `setInterval`.\n *\n * WHY ONE TICK AND NOT ONE TIMER PER SUBSCRIBER:\n * The predecessor package (`doom-pi-subagents`) gave every channel, watcher\n * and inspector its own independent interval. None of them coordinated, all of\n * them kept firing when nothing was happening, and the parent process burned\n * CPU while completely idle. A single scheduler that every subscriber reports\n * to can decide, once, whether there is any reason to keep ticking quickly.\n *\n * IDLE BACKOFF:\n * The tick interval starts at `floorMs`. A tick where nothing reported work\n * multiplies the interval by `backoffMultiplier`, capped at `ceilingMs`. A tick\n * where anything reported work resets it straight back to `floorMs`. \"Reported\n * work\" means a subscriber's `run()` returned `true`; returning `false` or\n * `void` means it checked and found nothing to do.\n *\n * WATCH-FIRST, POLL AS A SAFETY NET:\n * The intended pattern is: a subscriber's own `intervalMs` is set generously\n * (roughly 4x looser than how quickly you actually want it checked), and a\n * filesystem watch is the fast path. When the watch fires, its handler calls\n * `wake()`, which runs every subscriber immediately regardless of backoff.\n * Polling on `intervalMs` only exists to cover the platforms and mount types\n * where filesystem watches are unreliable or simply do not fire. Neither path\n * is trusted alone: the watch gives latency, the poll interval gives a bound\n * on how late a check can ever be.\n *\n * DESIGN PATTERNS:\n * - Subscribers are checked for both \"due\" (their own `intervalMs` has\n * elapsed) and \"forced\" (a `wake()` call), so a fast-changing subscriber and\n * a rarely-changing one can share one clock without either starving\n * - A subscriber's key is internal and never the caller-supplied `id`, so two\n * subscribers that reuse the same `id` string (a plausible mistake with\n * per-run subscriber names) cannot make one's `unregister()` delete the\n * other's registration\n * - `run()` is synchronous. Every current subscriber is a file check, and a\n * synchronous contract is what keeps the scheduler's behaviour deterministic\n * under fake timers; an async contract would need microtask flushing on top\n * of timer advancement in every test\n *\n * AVOID:\n * - Reading `this.floorMs` (or the other seam fields) from the constructor:\n * field initializer order runs the base class's defaults before a test\n * subclass's overrides are applied, so a value read in the constructor would\n * see the base default even when a subclass overrides it. Everything that\n * needs these values reads them lazily, from `start()` or `tick()`, which run\n * after construction is complete\n * - Letting a subscriber's thrown error escape `tick()`; it must not stop the\n * tick or affect its peers. It is recorded rather than discarded, since a\n * subscriber that throws every tick otherwise looks identical to an idle one\n */\n\nimport { injectable } from 'inversify';\n\n/** Minimum spacing between ticks once nothing has reported work in a while. */\nconst DEFAULT_FLOOR_MS = 200;\n/** Ceiling the backoff grows toward while idle. */\nconst DEFAULT_CEILING_MS = 5_000;\n/** Growth factor applied to the tick interval on every idle tick. */\nconst DEFAULT_BACKOFF_MULTIPLIER = 2;\n\nexport interface PollSubscription {\n /** For readability in logs and error messages only; not used as a map key. */\n id: string;\n /** How often this subscriber is checked, in milliseconds. Must be positive. */\n intervalMs: number;\n /**\n * Called when due. Return `true` when it did real work, which resets the\n * scheduler's backoff to the floor. Return `false` or nothing when there was\n * nothing to do, which lets idle backoff continue growing.\n */\n run: () => boolean | void;\n}\n\nexport interface IPollScheduler {\n /** Register a subscriber. Call the returned function to unregister it. */\n register(subscription: PollSubscription): () => void;\n /** Run every subscriber immediately, bypassing backoff and due-checks. */\n wake(): void;\n /** Begin ticking. Idempotent: a second call while running does nothing. */\n start(): void;\n /** Stop ticking and clear the pending timer. Idempotent. */\n stop(): void;\n}\n\ninterface InternalSubscriber extends PollSubscription {\n /** `undefined` until the first tick runs it; never `0`, which a test clock may legitimately start at. */\n lastRunAt: number | undefined;\n}\n\n@injectable()\nexport class PollScheduler implements IPollScheduler {\n /**\n * Seams for tests, as protected members rather than constructor arguments.\n * The container resolves this service by type, and inversify cannot supply a\n * primitive like a backoff curve, so a test subclass overrides these instead.\n */\n protected readonly floorMs: number = DEFAULT_FLOOR_MS;\n protected readonly ceilingMs: number = DEFAULT_CEILING_MS;\n protected readonly backoffMultiplier: number = DEFAULT_BACKOFF_MULTIPLIER;\n\n protected now(): number {\n return Date.now();\n }\n\n /**\n * Records a subscriber that threw. Overridable, and deliberately not a\n * stdio write: this runs inside a detached runner whose stdout is the child's\n * captured transcript. The composition root routes these into that process's\n * own diagnostics; the default keeps the most recent one queryable so a\n * failing subscriber can still be found after the fact.\n */\n protected onSubscriberError(id: string, error: unknown): void {\n this.lastSubscriberError = { id, error, at: this.now() };\n this.subscriberErrorCount += 1;\n }\n\n /** The most recent subscriber failure, for diagnostics. */\n lastSubscriberError: { id: string; error: unknown; at: number } | undefined;\n /** How many subscriber failures this scheduler has absorbed. */\n subscriberErrorCount = 0;\n\n private readonly subscribers = new Map<number, InternalSubscriber>();\n private nextSubscriberKey = 0;\n private timer: ReturnType<typeof setTimeout> | undefined;\n private currentIntervalMs: number | undefined;\n private running = false;\n\n register(subscription: PollSubscription): () => void {\n if (!(subscription.intervalMs > 0)) {\n throw new Error(`Poll subscriber \"${subscription.id}\" must have a positive intervalMs.`);\n }\n const key = this.nextSubscriberKey++;\n this.subscribers.set(key, { ...subscription, lastRunAt: undefined });\n return () => {\n this.subscribers.delete(key);\n };\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n this.currentIntervalMs = this.floorMs;\n this.tick(false);\n }\n\n stop(): void {\n this.running = false;\n if (this.timer) clearTimeout(this.timer);\n this.timer = undefined;\n }\n\n wake(): void {\n if (!this.running) return;\n if (this.timer) clearTimeout(this.timer);\n this.timer = undefined;\n this.tick(true);\n }\n\n /**\n * Run every due subscriber (or, when `forced`, every subscriber), fold the\n * outcome into the backoff curve, and schedule the next tick.\n */\n private tick(forced: boolean): void {\n const timestamp = this.now();\n let workHappened = false;\n let anySubscriberRan = false;\n\n for (const subscriber of this.subscribers.values()) {\n const due =\n forced || subscriber.lastRunAt === undefined || timestamp - subscriber.lastRunAt >= subscriber.intervalMs;\n if (!due) continue;\n subscriber.lastRunAt = timestamp;\n anySubscriberRan = true;\n try {\n if (subscriber.run()) workHappened = true;\n } catch (error) {\n // A subscriber's failure is its own: the tick, and every other\n // subscriber's turn within it, continues regardless. But it is not\n // discarded, because a subscriber that throws on every tick is\n // invisible otherwise and looks exactly like one with nothing to do.\n this.onSubscriberError(subscriber.id, error);\n }\n }\n\n // Backoff only moves on evidence. A tick where nothing was even due says\n // nothing about whether the system is idle, so it must not be mistaken for\n // one where subscribers looked and found nothing: growing the interval\n // there would penalise a scheduler whose subscribers simply poll slower\n // than it ticks, and would let a stale interval survive a stop/start.\n if (anySubscriberRan) {\n const previousIntervalMs = this.currentIntervalMs ?? this.floorMs;\n this.currentIntervalMs = workHappened\n ? this.floorMs\n : Math.min(previousIntervalMs * this.backoffMultiplier, this.ceilingMs);\n }\n\n this.scheduleNext();\n }\n\n private scheduleNext(): void {\n if (!this.running) return;\n const delayMs = this.currentIntervalMs ?? this.floorMs;\n this.timer = setTimeout(() => this.tick(false), delayMs);\n // A pending background poll must never be the reason the process stays\n // alive; `unref` is optional only because some test timer shims omit it.\n this.timer.unref?.();\n }\n}\n"],"mappings":"0JA6FO,EAAA,KAA8C,CAMnD,QAAqC,IACrC,UAAuC,IACvC,kBAA+C,EAE/C,KAAwB,CACtB,OAAO,KAAK,KAAK,CAUnB,kBAA4B,EAAY,EAAsB,CAC5D,KAAK,oBAAsB,CAAE,KAAI,QAAO,GAAI,KAAK,KAAK,CAAE,CACxD,KAAK,sBAAwB,EAI/B,oBAEA,qBAAuB,EAEvB,YAA+B,IAAI,IACnC,kBAA4B,EAC5B,MACA,kBACA,QAAkB,GAElB,SAAS,EAA4C,CACnD,GAAI,EAAE,EAAa,WAAa,GAC9B,MAAU,MAAM,oBAAoB,EAAa,GAAG,oCAAoC,CAE1F,IAAM,EAAM,KAAK,oBAEjB,OADA,KAAK,YAAY,IAAI,EAAK,CAAE,GAAG,EAAc,UAAW,IAAA,GAAW,CAAC,KACvD,CACX,KAAK,YAAY,OAAO,EAAI,EAIhC,OAAc,CACR,KAAK,UACT,KAAK,QAAU,GACf,KAAK,kBAAoB,KAAK,QAC9B,KAAK,KAAK,GAAM,EAGlB,MAAa,CACX,KAAK,QAAU,GACX,KAAK,OAAO,aAAa,KAAK,MAAM,CACxC,KAAK,MAAQ,IAAA,GAGf,MAAa,CACN,KAAK,UACN,KAAK,OAAO,aAAa,KAAK,MAAM,CACxC,KAAK,MAAQ,IAAA,GACb,KAAK,KAAK,GAAK,EAOjB,KAAa,EAAuB,CAClC,IAAM,EAAY,KAAK,KAAK,CACxB,EAAe,GACf,EAAmB,GAEvB,IAAK,IAAM,KAAc,KAAK,YAAY,QAAQ,CAE9C,MAAU,EAAW,YAAc,IAAA,IAAa,EAAY,EAAW,WAAa,EAAW,WAGjG,CADA,EAAW,UAAY,EACvB,EAAmB,GACnB,GAAI,CACE,EAAW,KAAK,GAAE,EAAe,UAC9B,EAAO,CAKd,KAAK,kBAAkB,EAAW,GAAI,EAAM,EAShD,GAAI,EAAkB,CACpB,IAAM,EAAqB,KAAK,mBAAqB,KAAK,QAC1D,KAAK,kBAAoB,EACrB,KAAK,QACL,KAAK,IAAI,EAAqB,KAAK,kBAAmB,KAAK,UAAU,CAG3E,KAAK,cAAc,CAGrB,cAA6B,CAC3B,GAAI,CAAC,KAAK,QAAS,OACnB,IAAM,EAAU,KAAK,mBAAqB,KAAK,QAC/C,KAAK,MAAQ,eAAiB,KAAK,KAAK,GAAM,CAAE,EAAQ,CAGxD,KAAK,MAAM,SAAS,qCApHX,CAAA,CAAA,EAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"scopeOwner.cjs","names":["scopeOwnerPath","fs","parseVersioned"],"sources":["../../src/shared/scopeOwner.ts"],"sourcesContent":["/**\n * Who owns a session scope, recorded on disk so a later sweep can tell an\n * abandoned tree from a live one.\n *\n * WHY A FILE AND NOT AN IN-MEMORY REGISTRY:\n * The process that owns a scope is exactly the process that cannot report on\n * it once it is gone. A crashed session leaves its whole tree behind, and the\n * only thing able to reclaim that is a different process reading something the\n * dead one left written down.\n *\n * WHY LIVENESS IS NOT DECIDED HERE:\n * This module records `hostPid` and reads it back; it does not decide whether a\n * scope is reapable. That rule needs run liveness too - after `/new` the\n * abandoned scope's `hostPid` is the still-live current process, so a\n * hostPid-only test would never reap it - and it belongs with the run registry\n * that knows about runs.\n *\n * AVOID:\n * - Treating a missing or unreadable owner file as \"safe to delete\". An\n * unreadable owner is unknown, not dead\n */\n\nimport * as fs from 'node:fs';\n\nimport { writeAtomicJson } from './atomicJson.ts';\nimport { scopeOwnerPath, type SessionScope } from './paths.ts';\nimport { parseVersioned } from './versioned.ts';\n\nconst SCOPE_OWNER_VERSION = 1;\n\nexport interface ScopeOwnerRecord {\n version: typeof SCOPE_OWNER_VERSION;\n rootSessionId: string;\n /** The process that adopted this scope. Dead pid plus no live runs means reapable. */\n hostPid: number;\n startedAt: number;\n}\n\n/**\n * Claim a scope for this process.\n *\n * Rewritten rather than written once: `/resume` reopens the same session id,\n * so the same scope is legitimately re-adopted by a later process, and the\n * record has to name the process that owns it now rather than the one that\n * first created the directory.\n */\nexport function writeScopeOwner(scope: SessionScope, now: number = Date.now()): ScopeOwnerRecord {\n const record: ScopeOwnerRecord = {\n version: SCOPE_OWNER_VERSION,\n rootSessionId: scope.rootSessionId,\n hostPid: process.pid,\n startedAt: now,\n };\n writeAtomicJson(scopeOwnerPath(scope), record);\n return record;\n}\n\n/** `undefined` when the scope has no readable owner: unknown, which is not the same as dead. */\nexport function readScopeOwner(scope: SessionScope): ScopeOwnerRecord | undefined {\n let raw: string;\n try {\n raw = fs.readFileSync(scopeOwnerPath(scope), 'utf-8');\n } catch {\n // Absent or unreadable. Both mean \"cannot say who owns this\", and the\n // caller must treat that as unknown rather than unowned.\n return undefined;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return undefined;\n }\n\n const result = parseVersioned<ScopeOwnerRecord>(parsed, [SCOPE_OWNER_VERSION]);\n if (!result.ok) return undefined;\n const record = result.value;\n if (typeof record.rootSessionId !== 'string' || !record.rootSessionId) return undefined;\n if (!Number.isInteger(record.hostPid)) return undefined;\n return record;\n}\n"],"mappings":"mLA8CA,SAAgB,EAAgB,EAAqB,EAAc,KAAK,KAAK,CAAoB,CAC/F,IAAM,EAA2B,CAC/B,QAAS,EACT,cAAe,EAAM,cACrB,QAAS,QAAQ,IACjB,UAAW,EACZ,CAED,OADA,EAAA,gBAAgBA,EAAAA,eAAe,EAAM,CAAE,EAAO,CACvC,EAIT,SAAgB,EAAe,EAAmD,CAChF,IAAI,EACJ,GAAI,CACF,EAAMC,EAAG,aAAaD,EAAAA,eAAe,EAAM,CAAE,QAAQ,MAC/C,CAGN,OAGF,IAAI,EACJ,GAAI,CACF,EAAS,KAAK,MAAM,EAAI,MAClB,CACN,OAGF,IAAM,EAASE,EAAAA,eAAiC,EAAQ,CAAC,EAAoB,CAAC,CAC9E,GAAI,CAAC,EAAO,GAAI,OAChB,IAAM,EAAS,EAAO,MAClB,YAAO,EAAO,eAAkB,UAAY,CAAC,EAAO,gBACnD,OAAO,UAAU,EAAO,QAAQ,CACrC,OAAO"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"chainExpression.cjs","names":[],"sources":["../../src/slash/chainExpression.ts"],"sourcesContent":["/**\n * Parses `/chain`/`/parallel`/`/run` slash-command argument strings into\n * structured steps: inline per-agent config (`agent[key=value,...]`),\n * `->`-separated chain steps, and `(a | b)`-style parallel groups within a\n * chain. Pure string parsing - nothing here calls into `SpawnPlanner` or\n * knows what a parsed field is used for; see `subagentLaunch.ts` for the\n * execution side and whichever module maps a `ParsedStep` onto a\n * `SpawnPlanTaskInput`/`SpawnPlanChainStepInput` for what happens to a\n * field this parser accepts once `SpawnPlanner`'s own request shape is\n * settled for this port (see the port's own tracking, not this file).\n *\n * WHY THIS IS ITS OWN MODULE, SEPARATE FROM COMMAND REGISTRATION:\n * The predecessor kept this logic inline in `slashCommands.ts`. Splitting\n * it out means the string-parsing rules - which are intricate and worth\n * testing in isolation (quote tracking, nested parens, top-level-only arrow\n * and pipe splitting) - do not need a `pi.registerCommand` fixture to test,\n * and stay unaffected by whatever `SpawnPlanner` request shape a caller\n * eventually maps a `ParsedStep` onto.\n *\n * AVOID:\n * - Adding execution or `SpawnPlanner` knowledge here. If a function needs\n * to know what a field does once parsed, it belongs in the caller, not\n * this file\n */\n\nexport interface InlineConfig {\n output?: string | false;\n outputMode?: 'inline' | 'file-only';\n reads?: string[] | false;\n model?: string;\n skill?: string[] | false;\n progress?: boolean;\n as?: string;\n label?: string;\n phase?: string;\n cwd?: string;\n count?: number;\n outputSchema?: string;\n acceptance?: string;\n}\n\n/** Parses the `key=value,...` body of `agent[...]` inline config. Unknown keys are ignored, not rejected. */\nexport function parseInlineConfig(raw: string): InlineConfig {\n const config: InlineConfig = {};\n for (const part of raw.split(',')) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const eq = trimmed.indexOf('=');\n if (eq === -1) {\n if (trimmed === 'progress') config.progress = true;\n continue;\n }\n const key = trimmed.slice(0, eq).trim();\n const val = trimmed.slice(eq + 1).trim();\n switch (key) {\n case 'output':\n config.output = val === 'false' ? false : val;\n break;\n case 'outputMode':\n if (val === 'inline' || val === 'file-only') config.outputMode = val;\n break;\n case 'reads':\n config.reads = val === 'false' ? false : val.split('+').filter(Boolean);\n break;\n case 'model':\n config.model = val || undefined;\n break;\n case 'skill':\n case 'skills':\n config.skill = val === 'false' ? false : val.split('+').filter(Boolean);\n break;\n case 'progress':\n config.progress = val !== 'false';\n break;\n case 'as':\n config.as = val || undefined;\n break;\n case 'label':\n config.label = val || undefined;\n break;\n case 'phase':\n config.phase = val || undefined;\n break;\n case 'cwd':\n config.cwd = val || undefined;\n break;\n case 'count': {\n const n = Number(val);\n if (Number.isInteger(n) && n > 0) config.count = n;\n break;\n }\n case 'outputSchema':\n config.outputSchema = val || undefined;\n break;\n case 'acceptance':\n config.acceptance = val || undefined;\n break;\n }\n }\n return config;\n}\n\n/** Splits `agent[key=value]` into the bare agent name and its parsed inline config. */\nexport function parseAgentToken(token: string): { name: string; config: InlineConfig } {\n const bracket = token.indexOf('[');\n if (bracket === -1) return { name: token, config: {} };\n const end = token.lastIndexOf(']');\n return {\n name: token.slice(0, bracket),\n config: parseInlineConfig(token.slice(bracket + 1, end !== -1 ? end : undefined)),\n };\n}\n\nexport interface ParsedStep {\n kind: 'step';\n name: string;\n config: InlineConfig;\n task?: string;\n}\n\nexport class SlashParseError extends Error {}\n\nexport function parseSingleTaskToken(token: string): ParsedStep {\n let agentPart: string;\n let task: string | undefined;\n const qMatch = token.match(/^(\\S+(?:\\[[^\\]]*\\])?)\\s+(?:\"([^\"]*)\"|'([^']*)')$/);\n if (qMatch) {\n agentPart = qMatch[1]!;\n task = (qMatch[2] ?? qMatch[3]) || undefined;\n } else {\n const dashIdx = token.indexOf(' -- ');\n if (dashIdx !== -1) {\n agentPart = token.slice(0, dashIdx).trim();\n task = token.slice(dashIdx + 4).trim() || undefined;\n } else {\n agentPart = token;\n }\n }\n return { kind: 'step', ...parseAgentToken(agentPart), task };\n}\n\n/**\n * User-typed flag selecting fork context for a run.\n *\n * Named because it is part of the command surface a user types, so the literal\n * appears in the parser, in help text and in any error naming it. Three copies\n * of a user-facing token drift one edit at a time, and the failure mode is a\n * flag the help promises and the parser does not accept.\n */\nconst FORK_FLAG = '--fork';\n\n/**\n * The predecessor's flags that used to select background execution. `--async`\n * was a synonym for the same flag, accepted by the since-removed prompt\n * workflow commands; it stays rejected here so anyone carrying an old\n * invocation gets the explanation rather than an unknown-flag error.\n */\nconst DEPRECATED_BACKGROUND_FLAGS = ['--bg', '--async'];\n\n/**\n * Thrown when a command's argument text still contains a background-mode\n * flag. Distinct from a generic parse error so the message can say\n * specifically why the flag is gone, not just that it was unexpected -\n * caught the same way as any other `SlashParseError` by\n * `reportKnownErrorOrRethrow`.\n */\nexport class DeprecatedBackgroundFlagError extends SlashParseError {\n constructor(readonly flag: string) {\n super(`'${flag}' is no longer needed: every run in this package is already background.`);\n this.name = 'DeprecatedBackgroundFlagError';\n }\n}\n\nfunction matchesTrailingFlag(text: string, flag: string): boolean {\n return text === flag || text.endsWith(` ${flag}`);\n}\n\nfunction stripTrailingFlag(text: string, flag: string): string {\n return text === flag ? '' : text.slice(0, -(flag.length + 1)).trim();\n}\n\n/**\n * Removes a trailing ` --fork` flag, returning the remaining argument text.\n *\n * `--bg`/`--async` are gone entirely - not stripped, not accepted, not\n * silently ignored. A user typing `--bg` out of habit gets an explicit,\n * named rejection here rather than falling through as literal text that\n * then produces an unrelated \"no such agent\" error further down the\n * pipeline, which points at the wrong problem. See `subagentLaunch.ts`'s\n * module doc for why background is the only mode.\n */\nexport function extractForkFlag(rawArgs: string): { args: string; fork: boolean } {\n let trimmed = rawArgs.trim();\n let fork = false;\n for (;;) {\n if (matchesTrailingFlag(trimmed, FORK_FLAG)) {\n fork = true;\n trimmed = stripTrailingFlag(trimmed, FORK_FLAG);\n continue;\n }\n const deprecatedFlag = DEPRECATED_BACKGROUND_FLAGS.find((flag) => matchesTrailingFlag(trimmed, flag));\n if (deprecatedFlag) throw new DeprecatedBackgroundFlagError(deprecatedFlag);\n break;\n }\n return { args: trimmed, fork };\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"chainExpression.mjs","names":[],"sources":["../../src/slash/chainExpression.ts"],"sourcesContent":["/**\n * Parses `/chain`/`/parallel`/`/run` slash-command argument strings into\n * structured steps: inline per-agent config (`agent[key=value,...]`),\n * `->`-separated chain steps, and `(a | b)`-style parallel groups within a\n * chain. Pure string parsing - nothing here calls into `SpawnPlanner` or\n * knows what a parsed field is used for; see `subagentLaunch.ts` for the\n * execution side and whichever module maps a `ParsedStep` onto a\n * `SpawnPlanTaskInput`/`SpawnPlanChainStepInput` for what happens to a\n * field this parser accepts once `SpawnPlanner`'s own request shape is\n * settled for this port (see the port's own tracking, not this file).\n *\n * WHY THIS IS ITS OWN MODULE, SEPARATE FROM COMMAND REGISTRATION:\n * The predecessor kept this logic inline in `slashCommands.ts`. Splitting\n * it out means the string-parsing rules - which are intricate and worth\n * testing in isolation (quote tracking, nested parens, top-level-only arrow\n * and pipe splitting) - do not need a `pi.registerCommand` fixture to test,\n * and stay unaffected by whatever `SpawnPlanner` request shape a caller\n * eventually maps a `ParsedStep` onto.\n *\n * AVOID:\n * - Adding execution or `SpawnPlanner` knowledge here. If a function needs\n * to know what a field does once parsed, it belongs in the caller, not\n * this file\n */\n\nexport interface InlineConfig {\n output?: string | false;\n outputMode?: 'inline' | 'file-only';\n reads?: string[] | false;\n model?: string;\n skill?: string[] | false;\n progress?: boolean;\n as?: string;\n label?: string;\n phase?: string;\n cwd?: string;\n count?: number;\n outputSchema?: string;\n acceptance?: string;\n}\n\n/** Parses the `key=value,...` body of `agent[...]` inline config. Unknown keys are ignored, not rejected. */\nexport function parseInlineConfig(raw: string): InlineConfig {\n const config: InlineConfig = {};\n for (const part of raw.split(',')) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const eq = trimmed.indexOf('=');\n if (eq === -1) {\n if (trimmed === 'progress') config.progress = true;\n continue;\n }\n const key = trimmed.slice(0, eq).trim();\n const val = trimmed.slice(eq + 1).trim();\n switch (key) {\n case 'output':\n config.output = val === 'false' ? false : val;\n break;\n case 'outputMode':\n if (val === 'inline' || val === 'file-only') config.outputMode = val;\n break;\n case 'reads':\n config.reads = val === 'false' ? false : val.split('+').filter(Boolean);\n break;\n case 'model':\n config.model = val || undefined;\n break;\n case 'skill':\n case 'skills':\n config.skill = val === 'false' ? false : val.split('+').filter(Boolean);\n break;\n case 'progress':\n config.progress = val !== 'false';\n break;\n case 'as':\n config.as = val || undefined;\n break;\n case 'label':\n config.label = val || undefined;\n break;\n case 'phase':\n config.phase = val || undefined;\n break;\n case 'cwd':\n config.cwd = val || undefined;\n break;\n case 'count': {\n const n = Number(val);\n if (Number.isInteger(n) && n > 0) config.count = n;\n break;\n }\n case 'outputSchema':\n config.outputSchema = val || undefined;\n break;\n case 'acceptance':\n config.acceptance = val || undefined;\n break;\n }\n }\n return config;\n}\n\n/** Splits `agent[key=value]` into the bare agent name and its parsed inline config. */\nexport function parseAgentToken(token: string): { name: string; config: InlineConfig } {\n const bracket = token.indexOf('[');\n if (bracket === -1) return { name: token, config: {} };\n const end = token.lastIndexOf(']');\n return {\n name: token.slice(0, bracket),\n config: parseInlineConfig(token.slice(bracket + 1, end !== -1 ? end : undefined)),\n };\n}\n\nexport interface ParsedStep {\n kind: 'step';\n name: string;\n config: InlineConfig;\n task?: string;\n}\n\nexport class SlashParseError extends Error {}\n\nexport function parseSingleTaskToken(token: string): ParsedStep {\n let agentPart: string;\n let task: string | undefined;\n const qMatch = token.match(/^(\\S+(?:\\[[^\\]]*\\])?)\\s+(?:\"([^\"]*)\"|'([^']*)')$/);\n if (qMatch) {\n agentPart = qMatch[1]!;\n task = (qMatch[2] ?? qMatch[3]) || undefined;\n } else {\n const dashIdx = token.indexOf(' -- ');\n if (dashIdx !== -1) {\n agentPart = token.slice(0, dashIdx).trim();\n task = token.slice(dashIdx + 4).trim() || undefined;\n } else {\n agentPart = token;\n }\n }\n return { kind: 'step', ...parseAgentToken(agentPart), task };\n}\n\n/**\n * User-typed flag selecting fork context for a run.\n *\n * Named because it is part of the command surface a user types, so the literal\n * appears in the parser, in help text and in any error naming it. Three copies\n * of a user-facing token drift one edit at a time, and the failure mode is a\n * flag the help promises and the parser does not accept.\n */\nconst FORK_FLAG = '--fork';\n\n/**\n * The predecessor's flags that used to select background execution. `--async`\n * was a synonym for the same flag, accepted by the since-removed prompt\n * workflow commands; it stays rejected here so anyone carrying an old\n * invocation gets the explanation rather than an unknown-flag error.\n */\nconst DEPRECATED_BACKGROUND_FLAGS = ['--bg', '--async'];\n\n/**\n * Thrown when a command's argument text still contains a background-mode\n * flag. Distinct from a generic parse error so the message can say\n * specifically why the flag is gone, not just that it was unexpected -\n * caught the same way as any other `SlashParseError` by\n * `reportKnownErrorOrRethrow`.\n */\nexport class DeprecatedBackgroundFlagError extends SlashParseError {\n constructor(readonly flag: string) {\n super(`'${flag}' is no longer needed: every run in this package is already background.`);\n this.name = 'DeprecatedBackgroundFlagError';\n }\n}\n\nfunction matchesTrailingFlag(text: string, flag: string): boolean {\n return text === flag || text.endsWith(` ${flag}`);\n}\n\nfunction stripTrailingFlag(text: string, flag: string): string {\n return text === flag ? '' : text.slice(0, -(flag.length + 1)).trim();\n}\n\n/**\n * Removes a trailing ` --fork` flag, returning the remaining argument text.\n *\n * `--bg`/`--async` are gone entirely - not stripped, not accepted, not\n * silently ignored. A user typing `--bg` out of habit gets an explicit,\n * named rejection here rather than falling through as literal text that\n * then produces an unrelated \"no such agent\" error further down the\n * pipeline, which points at the wrong problem. See `subagentLaunch.ts`'s\n * module doc for why background is the only mode.\n */\nexport function extractForkFlag(rawArgs: string): { args: string; fork: boolean } {\n let trimmed = rawArgs.trim();\n let fork = false;\n for (;;) {\n if (matchesTrailingFlag(trimmed, FORK_FLAG)) {\n fork = true;\n trimmed = stripTrailingFlag(trimmed, FORK_FLAG);\n continue;\n }\n const deprecatedFlag = DEPRECATED_BACKGROUND_FLAGS.find((flag) => matchesTrailingFlag(trimmed, flag));\n if (deprecatedFlag) throw new DeprecatedBackgroundFlagError(deprecatedFlag);\n break;\n }\n return { args: trimmed, fork };\n}\n"],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- const e=require(`../_virtual/_rolldown/runtime.cjs`);require(`../env.cjs`);const t=require(`../shared/paths.cjs`),n=require(`../intercom/intercomBridge.cjs`);let r=require(`node:fs`);r=e.__toESM(r,1);let i=require(`@agimon-ai/doompi-extension-contracts/child-process`);function a(e){return e instanceof Error?`${e.name}: ${e.message}`:String(e)}function o(e,t){try{return t()}catch(t){return`- ${e}: failed - ${a(t)}`}}function s(e,t){try{if(!r.existsSync(t))return`- ${e}: missing (${t})`;if(!r.statSync(t).isDirectory())throw Error(`not a directory: ${t}`);return r.accessSync(t,r.constants.R_OK|r.constants.W_OK),`- ${e}: ok (${t})`}catch(n){return`- ${e}: failed (${t}) - ${a(n)}`}}const c=[`plugin`,`user`,`project`],l=[`project`,`project-settings`,`user`,`user-settings`,`extension`,`builtin`,`unknown`];function u(e){let t=new Map;for(let n of e)t.set(n.source,(t.get(n.source)??0)+1);let n=c.map(e=>`${e} ${t.get(e)??0}`).filter(e=>!e.endsWith(` 0`));return n.length>0?n.join(`, `):`none`}function d(e){let t=new Map;for(let n of e)t.set(n.source,(t.get(n.source)??0)+1);let n=l.map(e=>`${e} ${t.get(e)??0}`).filter(e=>!e.endsWith(` 0`));return n.length>0?n.join(`, `):`none`}function f(e){let t=[`- current session file: ${e.currentSessionFile??`not available`}`,`- current session id: ${e.currentSessionId??`not available`}`];return e.sessionError&&t.push(`- session manager: failed - ${e.sessionError}`),t}function p(e,t){return[o(`agents`,()=>{let n=t.discovery.discover(e.cwd,e.agentScope).agents;return`- agents: total ${n.length} (${u(n)})`}),o(`skills`,()=>{let n=t.skills.discoverAvailableSkills(e.cwd);return`- skills: total ${n.length} (${d(n)})`})]}function m(){let e=[],t=(process.env[i.SUBAGENT_PARENT_SESSION_ENV]??``).trim();e.push(t?`- parent session: set (${t})`:`- parent session: not set - ask forwarding from a subprocess child will not reach a parent UI`);let n=process.env[i.SUBAGENT_CHILD_ENV]===`1`;return e.push(`- subagent process: ${n?`yes (${i.SUBAGENT_CHILD_ENV}=1)`:`no`}`),e}function h(e){return o(`intercom bridge`,()=>{let t=n.diagnoseIntercomBridge({config:e.intercomBridgeConfig,context:e.context,orchestratorTarget:e.orchestratorTarget});return[`- bridge: ${t.active?`active`:`inactive`}${t.reason?` (${t.reason})`:``}`,`- mode: ${t.mode}; context: ${e.context??`unspecified`}`,`- orchestrator target: ${t.orchestratorTarget??`not available`}`,`- intercom: ${t.intercomAvailable?`available`:`unavailable`} (${t.extensionDir})`].join(`
2
- `)}).split(`
3
- `)}function g(e,n){return[`Subagents doctor report`,``,`Runtime`,`- cwd: ${e.cwd}`,`- async support: available (this package is async-only)`,...f(e),``,`Filesystem`,s(`temp root`,t.TEMP_ROOT_DIR),s(`runs`,t.currentRunsDir()),s(`results`,t.currentResultsDir()),``,`Discovery`,...p(e,n),``,`Permission system`,...m(),``,`Intercom bridge`,...h(e)].join(`
4
- `)}exports.buildDoctorReport=g;
5
- //# sourceMappingURL=doctor.cjs.map
@@ -1,5 +0,0 @@
1
- import{SUBAGENT_CHILD_ENV as e,SUBAGENT_PARENT_SESSION_ENV as t,init_env as n}from"../env.mjs";import{TEMP_ROOT_DIR as r,currentResultsDir as i,currentRunsDir as a,init_paths as o}from"../shared/paths.mjs";import{diagnoseIntercomBridge as s}from"../intercom/intercomBridge.mjs";import*as c from"node:fs";n(),o();function l(e){return e instanceof Error?`${e.name}: ${e.message}`:String(e)}function u(e,t){try{return t()}catch(t){return`- ${e}: failed - ${l(t)}`}}function d(e,t){try{if(!c.existsSync(t))return`- ${e}: missing (${t})`;if(!c.statSync(t).isDirectory())throw Error(`not a directory: ${t}`);return c.accessSync(t,c.constants.R_OK|c.constants.W_OK),`- ${e}: ok (${t})`}catch(n){return`- ${e}: failed (${t}) - ${l(n)}`}}const f=[`plugin`,`user`,`project`],p=[`project`,`project-settings`,`user`,`user-settings`,`extension`,`builtin`,`unknown`];function m(e){let t=new Map;for(let n of e)t.set(n.source,(t.get(n.source)??0)+1);let n=f.map(e=>`${e} ${t.get(e)??0}`).filter(e=>!e.endsWith(` 0`));return n.length>0?n.join(`, `):`none`}function h(e){let t=new Map;for(let n of e)t.set(n.source,(t.get(n.source)??0)+1);let n=p.map(e=>`${e} ${t.get(e)??0}`).filter(e=>!e.endsWith(` 0`));return n.length>0?n.join(`, `):`none`}function g(e){let t=[`- current session file: ${e.currentSessionFile??`not available`}`,`- current session id: ${e.currentSessionId??`not available`}`];return e.sessionError&&t.push(`- session manager: failed - ${e.sessionError}`),t}function _(e,t){return[u(`agents`,()=>{let n=t.discovery.discover(e.cwd,e.agentScope).agents;return`- agents: total ${n.length} (${m(n)})`}),u(`skills`,()=>{let n=t.skills.discoverAvailableSkills(e.cwd);return`- skills: total ${n.length} (${h(n)})`})]}function v(){let n=[],r=(process.env[t]??``).trim();n.push(r?`- parent session: set (${r})`:`- parent session: not set - ask forwarding from a subprocess child will not reach a parent UI`);let i=process.env[e]===`1`;return n.push(`- subagent process: ${i?`yes (${e}=1)`:`no`}`),n}function y(e){return u(`intercom bridge`,()=>{let t=s({config:e.intercomBridgeConfig,context:e.context,orchestratorTarget:e.orchestratorTarget});return[`- bridge: ${t.active?`active`:`inactive`}${t.reason?` (${t.reason})`:``}`,`- mode: ${t.mode}; context: ${e.context??`unspecified`}`,`- orchestrator target: ${t.orchestratorTarget??`not available`}`,`- intercom: ${t.intercomAvailable?`available`:`unavailable`} (${t.extensionDir})`].join(`
2
- `)}).split(`
3
- `)}function b(e,t){return[`Subagents doctor report`,``,`Runtime`,`- cwd: ${e.cwd}`,`- async support: available (this package is async-only)`,...g(e),``,`Filesystem`,d(`temp root`,r),d(`runs`,a()),d(`results`,i()),``,`Discovery`,..._(e,t),``,`Permission system`,...v(),``,`Intercom bridge`,...y(e)].join(`
4
- `)}export{b as buildDoctorReport};
5
- //# sourceMappingURL=doctor.mjs.map