@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 +1 @@
1
- {"version":3,"file":"paths.mjs","names":[],"sources":["../../src/shared/paths.ts"],"sourcesContent":["/**\n * Filesystem roots for every artifact this package writes outside the project.\n *\n * DESIGN PATTERNS:\n * - One root, derived subdirectories. Nothing else in the package joins\n * `os.tmpdir()` directly, so the whole tree can be relocated from here\n * - The root is scoped per operating-system user. A shared `/tmp` on a\n * multi-user host would otherwise let one user read another's run state, and\n * worse, let two users collide on the same run id\n *\n * The root is named for this package, not for its predecessor. That is what\n * keeps a doom-team parent and a doom-pi-subagents parent from reading each\n * other's channels while both are installed during cutover.\n *\n * AVOID:\n * - Joining `os.tmpdir()` anywhere else\n * - Putting a user-supplied string into a path segment without sanitizing it\n */\n\nimport { createHash } from 'node:crypto';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nimport { SUBAGENT_ROOT_SESSION_ENV } from '../env.ts';\n\nconst TEMP_ROOT_PREFIX = 'doom-team';\nconst UNKNOWN_SCOPE_SEGMENT = 'unknown';\nconst SHARED_SCOPE_ID = 'shared';\nconst SCOPE_ENV_KEYS = ['USERNAME', 'USER', 'LOGNAME'] as const;\n\n/** Reduce a value to a single safe path segment. */\nfunction sanitizeTempScopeSegment(value: string): string {\n const sanitized = value\n .trim()\n .replace(/[^A-Za-z0-9._-]+/gu, '-')\n .replace(/^-+|-+$/gu, '');\n return sanitized || UNKNOWN_SCOPE_SEGMENT;\n}\n\n/** The identity sources used to scope the temp root, in preference order. */\nexport interface TempScopeSources {\n env?: NodeJS.ProcessEnv;\n getuid?: (() => number) | undefined;\n userInfo?: (() => { username?: string | null }) | undefined;\n homedir?: (() => string) | undefined;\n}\n\n/**\n * Identify the current user for temp-root scoping.\n *\n * The uid is preferred because it cannot be spoofed by the environment. The\n * remaining sources are progressively weaker fallbacks for platforms that do\n * not expose one; `shared` is the last resort and is deliberately reachable, so\n * a run never fails purely because the user could not be identified.\n */\nexport function resolveTempScopeId(options?: TempScopeSources): string {\n const env = options?.env ?? process.env;\n const getuid = options && Object.hasOwn(options, 'getuid') ? options.getuid : process.getuid?.bind(process);\n if (typeof getuid === 'function') return `uid-${getuid()}`;\n\n for (const key of SCOPE_ENV_KEYS) {\n const value = env[key];\n if (value) return `user-${sanitizeTempScopeSegment(value)}`;\n }\n\n const userInfo = options && Object.hasOwn(options, 'userInfo') ? options.userInfo : os.userInfo;\n try {\n const username = userInfo?.().username;\n if (username) return `user-${sanitizeTempScopeSegment(username)}`;\n } catch {\n // os.userInfo throws when the uid has no passwd entry; scope by home instead.\n }\n\n const homedir = env.USERPROFILE ?? env.HOME;\n if (homedir) return `home-${sanitizeTempScopeSegment(homedir)}`;\n\n const resolveHomedir = options && Object.hasOwn(options, 'homedir') ? options.homedir : os.homedir;\n try {\n const fallbackHomedir = resolveHomedir?.();\n if (fallbackHomedir) return `home-${sanitizeTempScopeSegment(fallbackHomedir)}`;\n } catch {\n // Every identity source failed; fall back to the shared scope.\n }\n\n return SHARED_SCOPE_ID;\n}\n\n/** Root of this package's out-of-project state, scoped to the current user. */\nexport const TEMP_ROOT_DIR = path.join(os.tmpdir(), `${TEMP_ROOT_PREFIX}-${resolveTempScopeId()}`);\n\n/** Artifacts produced by runs whose artifact preference resolves to `temp`. */\nexport const TEMP_ARTIFACTS_DIR = path.join(TEMP_ROOT_DIR, 'artifacts');\n\n// ============================================================================\n// Session scope\n// ============================================================================\n\n/**\n * Everything a session owns lives under one directory named for that session.\n *\n * WHY THIS EXISTS:\n * These paths used to be flat constants under `TEMP_ROOT_DIR`, shared by every\n * concurrent session of the same user. That is not merely untidy: with one\n * shared `run-results/`, a session could win `ResultWatcher`'s atomic-rename\n * claim on a run it did not own, and then never deliver it, because the\n * consumer's \"not mine\" answer is the same `false` that means \"retry later\".\n * `tests/unit/sessionIsolation.test.ts` reproduces exactly that. Scoping the\n * read paths removes the race by construction rather than by teaching the\n * consumer to distinguish two meanings of `false`.\n *\n * THE KEY IS THE ROOT SESSION, NOT THIS PROCESS'S SESSION:\n * A spawned child has its own Pi session id, so it cannot derive the tree from\n * `SessionManager.getSessionId()` - it would land in a directory of its own and\n * see none of its parent's state. The ROOT session id travels down by\n * environment instead, which is the same thing `nativeTeamChannel.ts` already\n * does for team membership.\n *\n * AVOID:\n * - Reading another scope's tree for anything except reaping. Cross-scope reads\n * are what this whole layout exists to prevent\n */\nexport interface SessionScope {\n /** Pi's session id for the session at the top of this process tree. */\n rootSessionId: string;\n /** `rootSessionId` reduced to one safe path segment. */\n scopeKey: string;\n}\n\nconst SESSIONS_DIR_NAME = 'sessions';\nconst SCOPE_KEY_HASH_LENGTH = 16;\n\n/** All scopes. Only a reaping sweep may read across this; never a delivery path. */\nexport const SESSIONS_ROOT_DIR = path.join(TEMP_ROOT_DIR, SESSIONS_DIR_NAME);\n\n/**\n * Hashed rather than sanitized: a Pi session id is a uuidv7 today, but the id\n * is also settable by a caller (`SessionManager.newSession({ id })`), and a\n * hash is the only derivation that cannot collide two different ids onto one\n * directory after sanitizing away their differing characters.\n */\nexport function sessionScopeKey(rootSessionId: string): string {\n return createHash('sha256').update(rootSessionId).digest('hex').slice(0, SCOPE_KEY_HASH_LENGTH);\n}\n\nexport function createSessionScope(rootSessionId: string): SessionScope {\n const trimmed = rootSessionId.trim();\n if (!trimmed) throw new Error('A session scope requires a non-empty root session id.');\n return { rootSessionId: trimmed, scopeKey: sessionScopeKey(trimmed) };\n}\n\n/** `sessions/<scopeKey>`. Every other scoped path derives from this one. */\nexport function sessionScopeDir(scope: SessionScope): string {\n return path.join(SESSIONS_ROOT_DIR, scope.scopeKey);\n}\n\n/** Records which session and process own a scope, so a later sweep can reap it. */\nexport function scopeOwnerPath(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'owner.json');\n}\n\n/** Terminal run results, written once by the runner and read by this scope's parent only. */\nexport function scopeResultsDir(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'run-results');\n}\n\n/** Per-run working state: status.json, transcripts, control inboxes, claimed results. */\nexport function scopeRunsDir(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'runs');\n}\n\n/** Team member records, heartbeats, inboxes and replies for this scope's team. */\nexport function scopeTeamDir(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'team');\n}\n\n/** Runs stopped by a session shutdown, awaiting an explicit restore. */\nexport function scopeSuspendedDir(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'suspended');\n}\n\n/**\n * Scratch space for launching a child: its prompt, task and tool diagnostics.\n *\n * Callers `mkdtemp` inside this rather than in `os.tmpdir()` directly, so the\n * scoping applies to launch scratch too. These files carry the full task text,\n * which is exactly the content that should not be world-readable.\n */\nexport function scopeChildLaunchTempDir(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'child-launch');\n}\n\n/**\n * Path of the launch config handed to a detached runner.\n *\n * These files carry the full launch contract, so the runner's spawn site writes\n * them 0600 and the parent removes them once the child has read them.\n */\nexport function getRunConfigPath(scope: SessionScope, runId: string): string {\n return path.join(sessionScopeDir(scope), 'launch', `${runId}.json`);\n}\n\n// ============================================================================\n// The process's current scope\n// ============================================================================\n\n/**\n * One process serves exactly one root session at a time, so the scope is\n * process state rather than a parameter on every path call.\n *\n * WHY THIS IS SETTABLE AND NOT A CONSTANT:\n * `TEMP_ROOT_DIR` can be a constant because the OS user is fixed for the life\n * of the process. The root session is not: a parent learns it at\n * `session_start`, and Pi fires that again with a DIFFERENT session id after\n * `/new`, `/resume` and `/fork` (it builds a fresh `SessionManager` each time).\n * A child learns it from the environment its parent spawned it with.\n *\n * WHY AN UNSET SCOPE THROWS RATHER THAN FALLING BACK:\n * A silent fallback to an unscoped directory is exactly the shared-state bug\n * this layout removes, and it would fail invisibly - two sessions quietly\n * sharing a tree again. Every real code path runs after either `session_start`\n * or child bootstrap, so reaching a path helper with no scope is a wiring bug\n * and should say so.\n *\n * AVOID:\n * - Reading this at module scope. It is not set at import time\n */\nlet currentScope: SessionScope | undefined;\n\nexport function setCurrentSessionScope(scope: SessionScope): void {\n currentScope = scope;\n}\n\n/** Test-only, and for a child that legitimately has no team root forwarded. */\nexport function clearCurrentSessionScope(): void {\n currentScope = undefined;\n}\n\nexport function tryCurrentSessionScope(): SessionScope | undefined {\n return currentScope;\n}\n\nexport function requireCurrentSessionScope(): SessionScope {\n if (!currentScope) {\n throw new Error(\n 'No session scope is set. The parent sets it on session_start; a child sets it from its spawn environment.',\n );\n }\n return currentScope;\n}\n\n/** `run-results/` for this process's scope. */\nexport function currentResultsDir(): string {\n return scopeResultsDir(requireCurrentSessionScope());\n}\n\n/** `runs/` for this process's scope. */\nexport function currentRunsDir(): string {\n return scopeRunsDir(requireCurrentSessionScope());\n}\n\n/** `child-launch/` for this process's scope. */\nexport function currentChildLaunchTempDir(): string {\n return scopeChildLaunchTempDir(requireCurrentSessionScope());\n}\n\n/** `suspended/` for this process's scope. */\nexport function currentSuspendedDir(): string {\n return scopeSuspendedDir(requireCurrentSessionScope());\n}\n\n/** Launch config path for a run in this process's scope. */\nexport function currentRunConfigPath(runId: string): string {\n return getRunConfigPath(requireCurrentSessionScope(), runId);\n}\n\n/** Folded into a spawned child's environment so it resolves the same tree. */\nexport function sessionScopeEnvironment(scope: SessionScope): Record<string, string> {\n return { [SUBAGENT_ROOT_SESSION_ENV]: scope.rootSessionId };\n}\n\n/** The scope a spawned child inherits, or undefined in a process nothing spawned. */\nexport function resolveSessionScopeFromEnv(env: NodeJS.ProcessEnv = process.env): SessionScope | undefined {\n const rootSessionId = env[SUBAGENT_ROOT_SESSION_ENV]?.trim();\n return rootSessionId ? createSessionScope(rootSessionId) : undefined;\n}\n\n/**\n * Adopt the inherited scope, if this process was spawned with one.\n *\n * Returns whether a scope was adopted, so a child entry point can fail loudly\n * rather than silently writing into an unscoped tree.\n */\nexport function adoptSessionScopeFromEnv(env: NodeJS.ProcessEnv = process.env): boolean {\n const scope = resolveSessionScopeFromEnv(env);\n if (!scope) return false;\n setCurrentSessionScope(scope);\n return true;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"paths.mjs","names":[],"sources":["../../src/shared/paths.ts"],"sourcesContent":["/**\n * Filesystem roots for every artifact this package writes outside the project.\n *\n * DESIGN PATTERNS:\n * - One root, derived subdirectories. Nothing else in the package joins\n * `os.tmpdir()` directly, so the whole tree can be relocated from here\n * - The root is scoped per operating-system user. A shared `/tmp` on a\n * multi-user host would otherwise let one user read another's run state, and\n * worse, let two users collide on the same run id\n *\n * The root is named for this package, not for its predecessor. That is what\n * keeps a doom-team parent and a doom-pi-subagents parent from reading each\n * other's channels while both are installed during cutover.\n *\n * AVOID:\n * - Joining `os.tmpdir()` anywhere else\n * - Putting a user-supplied string into a path segment without sanitizing it\n */\n\nimport { createHash } from 'node:crypto';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nimport { SUBAGENT_ROOT_SESSION_ENV } from '../adapters/process/env.ts';\n\nconst TEMP_ROOT_PREFIX = 'doom-team';\nconst UNKNOWN_SCOPE_SEGMENT = 'unknown';\nconst SHARED_SCOPE_ID = 'shared';\nconst SCOPE_ENV_KEYS = ['USERNAME', 'USER', 'LOGNAME'] as const;\n\n/** Reduce a value to a single safe path segment. */\nfunction sanitizeTempScopeSegment(value: string): string {\n const sanitized = value\n .trim()\n .replace(/[^A-Za-z0-9._-]+/gu, '-')\n .replace(/^-+|-+$/gu, '');\n return sanitized || UNKNOWN_SCOPE_SEGMENT;\n}\n\n/** The identity sources used to scope the temp root, in preference order. */\nexport interface TempScopeSources {\n env?: NodeJS.ProcessEnv;\n getuid?: (() => number) | undefined;\n userInfo?: (() => { username?: string | null }) | undefined;\n homedir?: (() => string) | undefined;\n}\n\n/**\n * Identify the current user for temp-root scoping.\n *\n * The uid is preferred because it cannot be spoofed by the environment. The\n * remaining sources are progressively weaker fallbacks for platforms that do\n * not expose one; `shared` is the last resort and is deliberately reachable, so\n * a run never fails purely because the user could not be identified.\n */\nexport function resolveTempScopeId(options?: TempScopeSources): string {\n const env = options?.env ?? process.env;\n const getuid = options && Object.hasOwn(options, 'getuid') ? options.getuid : process.getuid?.bind(process);\n if (typeof getuid === 'function') return `uid-${getuid()}`;\n\n for (const key of SCOPE_ENV_KEYS) {\n const value = env[key];\n if (value) return `user-${sanitizeTempScopeSegment(value)}`;\n }\n\n const userInfo = options && Object.hasOwn(options, 'userInfo') ? options.userInfo : os.userInfo;\n try {\n const username = userInfo?.().username;\n if (username) return `user-${sanitizeTempScopeSegment(username)}`;\n } catch {\n // os.userInfo throws when the uid has no passwd entry; scope by home instead.\n }\n\n const homedir = env.USERPROFILE ?? env.HOME;\n if (homedir) return `home-${sanitizeTempScopeSegment(homedir)}`;\n\n const resolveHomedir = options && Object.hasOwn(options, 'homedir') ? options.homedir : os.homedir;\n try {\n const fallbackHomedir = resolveHomedir?.();\n if (fallbackHomedir) return `home-${sanitizeTempScopeSegment(fallbackHomedir)}`;\n } catch {\n // Every identity source failed; fall back to the shared scope.\n }\n\n return SHARED_SCOPE_ID;\n}\n\n/** Root of this package's out-of-project state, scoped to the current user. */\nexport const TEMP_ROOT_DIR = path.join(os.tmpdir(), `${TEMP_ROOT_PREFIX}-${resolveTempScopeId()}`);\n\n/** Artifacts produced by runs whose artifact preference resolves to `temp`. */\nexport const TEMP_ARTIFACTS_DIR = path.join(TEMP_ROOT_DIR, 'artifacts');\n\n// ============================================================================\n// Session scope\n// ============================================================================\n\n/**\n * Everything a session owns lives under one directory named for that session.\n *\n * WHY THIS EXISTS:\n * These paths used to be flat constants under `TEMP_ROOT_DIR`, shared by every\n * concurrent session of the same user. That is not merely untidy: with one\n * shared `run-results/`, a session could win `ResultWatcher`'s atomic-rename\n * claim on a run it did not own, and then never deliver it, because the\n * consumer's \"not mine\" answer is the same `false` that means \"retry later\".\n * `tests/unit/sessionIsolation.test.ts` reproduces exactly that. Scoping the\n * read paths removes the race by construction rather than by teaching the\n * consumer to distinguish two meanings of `false`.\n *\n * THE KEY IS THE ROOT SESSION, NOT THIS PROCESS'S SESSION:\n * A spawned child has its own Pi session id, so it cannot derive the tree from\n * `SessionManager.getSessionId()` - it would land in a directory of its own and\n * see none of its parent's state. The ROOT session id travels down by\n * environment instead, which is the same thing `nativeTeamChannel.ts` already\n * does for team membership.\n *\n * AVOID:\n * - Reading another scope's tree for anything except reaping. Cross-scope reads\n * are what this whole layout exists to prevent\n */\nexport interface SessionScope {\n /** Pi's session id for the session at the top of this process tree. */\n rootSessionId: string;\n /** `rootSessionId` reduced to one safe path segment. */\n scopeKey: string;\n}\n\nconst SESSIONS_DIR_NAME = 'sessions';\nconst SCOPE_KEY_HASH_LENGTH = 16;\n\n/** All scopes. Only a reaping sweep may read across this; never a delivery path. */\nexport const SESSIONS_ROOT_DIR = path.join(TEMP_ROOT_DIR, SESSIONS_DIR_NAME);\n\n/**\n * Hashed rather than sanitized: a Pi session id is a uuidv7 today, but the id\n * is also settable by a caller (`SessionManager.newSession({ id })`), and a\n * hash is the only derivation that cannot collide two different ids onto one\n * directory after sanitizing away their differing characters.\n */\nexport function sessionScopeKey(rootSessionId: string): string {\n return createHash('sha256').update(rootSessionId).digest('hex').slice(0, SCOPE_KEY_HASH_LENGTH);\n}\n\nexport function createSessionScope(rootSessionId: string): SessionScope {\n const trimmed = rootSessionId.trim();\n if (!trimmed) throw new Error('A session scope requires a non-empty root session id.');\n return { rootSessionId: trimmed, scopeKey: sessionScopeKey(trimmed) };\n}\n\n/** `sessions/<scopeKey>`. Every other scoped path derives from this one. */\nexport function sessionScopeDir(scope: SessionScope): string {\n return path.join(SESSIONS_ROOT_DIR, scope.scopeKey);\n}\n\n/** Records which session and process own a scope, so a later sweep can reap it. */\nexport function scopeOwnerPath(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'owner.json');\n}\n\n/** Terminal run results, written once by the runner and read by this scope's parent only. */\nexport function scopeResultsDir(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'run-results');\n}\n\n/** Per-run working state: status.json, transcripts, control inboxes, claimed results. */\nexport function scopeRunsDir(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'runs');\n}\n\n/** Team member records, heartbeats, inboxes and replies for this scope's team. */\nexport function scopeTeamDir(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'team');\n}\n\n/** Runs stopped by a session shutdown, awaiting an explicit restore. */\nexport function scopeSuspendedDir(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'suspended');\n}\n\n/**\n * Scratch space for launching a child: its prompt, task and tool diagnostics.\n *\n * Callers `mkdtemp` inside this rather than in `os.tmpdir()` directly, so the\n * scoping applies to launch scratch too. These files carry the full task text,\n * which is exactly the content that should not be world-readable.\n */\nexport function scopeChildLaunchTempDir(scope: SessionScope): string {\n return path.join(sessionScopeDir(scope), 'child-launch');\n}\n\n/**\n * Path of the launch config handed to a detached runner.\n *\n * These files carry the full launch contract, so the runner's spawn site writes\n * them 0600 and the parent removes them once the child has read them.\n */\nexport function getRunConfigPath(scope: SessionScope, runId: string): string {\n return path.join(sessionScopeDir(scope), 'launch', `${runId}.json`);\n}\n\n// ============================================================================\n// The process's current scope\n// ============================================================================\n\n/**\n * One process serves exactly one root session at a time, so the scope is\n * process state rather than a parameter on every path call.\n *\n * WHY THIS IS SETTABLE AND NOT A CONSTANT:\n * `TEMP_ROOT_DIR` can be a constant because the OS user is fixed for the life\n * of the process. The root session is not: a parent learns it at\n * `session_start`, and Pi fires that again with a DIFFERENT session id after\n * `/new`, `/resume` and `/fork` (it builds a fresh `SessionManager` each time).\n * A child learns it from the environment its parent spawned it with.\n *\n * WHY AN UNSET SCOPE THROWS RATHER THAN FALLING BACK:\n * A silent fallback to an unscoped directory is exactly the shared-state bug\n * this layout removes, and it would fail invisibly - two sessions quietly\n * sharing a tree again. Every real code path runs after either `session_start`\n * or child bootstrap, so reaching a path helper with no scope is a wiring bug\n * and should say so.\n *\n * AVOID:\n * - Reading this at module scope. It is not set at import time\n */\nlet currentScope: SessionScope | undefined;\n\nexport function setCurrentSessionScope(scope: SessionScope): void {\n currentScope = scope;\n}\n\n/** Test-only, and for a child that legitimately has no team root forwarded. */\nexport function clearCurrentSessionScope(): void {\n currentScope = undefined;\n}\n\nexport function tryCurrentSessionScope(): SessionScope | undefined {\n return currentScope;\n}\n\nexport function requireCurrentSessionScope(): SessionScope {\n if (!currentScope) {\n throw new Error(\n 'No session scope is set. The parent sets it on session_start; a child sets it from its spawn environment.',\n );\n }\n return currentScope;\n}\n\n/** `run-results/` for this process's scope. */\nexport function currentResultsDir(): string {\n return scopeResultsDir(requireCurrentSessionScope());\n}\n\n/** `runs/` for this process's scope. */\nexport function currentRunsDir(): string {\n return scopeRunsDir(requireCurrentSessionScope());\n}\n\n/** `child-launch/` for this process's scope. */\nexport function currentChildLaunchTempDir(): string {\n return scopeChildLaunchTempDir(requireCurrentSessionScope());\n}\n\n/** `suspended/` for this process's scope. */\nexport function currentSuspendedDir(): string {\n return scopeSuspendedDir(requireCurrentSessionScope());\n}\n\n/** Launch config path for a run in this process's scope. */\nexport function currentRunConfigPath(runId: string): string {\n return getRunConfigPath(requireCurrentSessionScope(), runId);\n}\n\n/** Folded into a spawned child's environment so it resolves the same tree. */\nexport function sessionScopeEnvironment(scope: SessionScope): Record<string, string> {\n return { [SUBAGENT_ROOT_SESSION_ENV]: scope.rootSessionId };\n}\n\n/** The scope a spawned child inherits, or undefined in a process nothing spawned. */\nexport function resolveSessionScopeFromEnv(env: NodeJS.ProcessEnv = process.env): SessionScope | undefined {\n const rootSessionId = env[SUBAGENT_ROOT_SESSION_ENV]?.trim();\n return rootSessionId ? createSessionScope(rootSessionId) : undefined;\n}\n\n/**\n * Adopt the inherited scope, if this process was spawned with one.\n *\n * Returns whether a scope was adopted, so a child entry point can fail loudly\n * rather than silently writing into an unscoped tree.\n */\nexport function adoptSessionScopeFromEnv(env: NodeJS.ProcessEnv = process.env): boolean {\n const scope = resolveSessionScopeFromEnv(env);\n if (!scope) return false;\n setCurrentSessionScope(scope);\n return true;\n}\n"],"mappings":"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"}
@@ -1,2 +1 @@
1
- require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.cjs`);let t=require(`inversify`),n=class{floorMs=200;ceilingMs=5e3;backoffMultiplier=2;now(){return Date.now()}onSubscriberError(e,t){this.lastSubscriberError={id:e,error:t,at:this.now()},this.subscriberErrorCount+=1}lastSubscriberError;subscriberErrorCount=0;subscribers=new Map;nextSubscriberKey=0;timer;currentIntervalMs;running=!1;register(e){if(!(e.intervalMs>0))throw Error(`Poll subscriber "${e.id}" must have a positive intervalMs.`);let t=this.nextSubscriberKey++;return this.subscribers.set(t,{...e,lastRunAt:void 0}),()=>{this.subscribers.delete(t)}}start(){this.running||(this.running=!0,this.currentIntervalMs=this.floorMs,this.tick(!1))}stop(){this.running=!1,this.timer&&clearTimeout(this.timer),this.timer=void 0}wake(){this.running&&(this.timer&&clearTimeout(this.timer),this.timer=void 0,this.tick(!0))}tick(e){let t=this.now(),n=!1,r=!1;for(let i of this.subscribers.values())if(e||i.lastRunAt===void 0||t-i.lastRunAt>=i.intervalMs){i.lastRunAt=t,r=!0;try{i.run()&&(n=!0)}catch(e){this.onSubscriberError(i.id,e)}}if(r){let e=this.currentIntervalMs??this.floorMs;this.currentIntervalMs=n?this.floorMs:Math.min(e*this.backoffMultiplier,this.ceilingMs)}this.scheduleNext()}scheduleNext(){if(!this.running)return;let e=this.currentIntervalMs??this.floorMs;this.timer=setTimeout(()=>this.tick(!1),e),this.timer.unref?.()}};n=e.__decorate([(0,t.injectable)()],n),Object.defineProperty(exports,`PollScheduler`,{enumerable:!0,get:function(){return n}});
2
- //# sourceMappingURL=pollScheduler.cjs.map
1
+ require(`../adapters/pollScheduler.cjs`);
@@ -1,2 +1,2 @@
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{injectable as r}from"inversify";var i,a,o,s,c=e((()=>{n(),i=200,a=5e3,o=2,s=class{floorMs=i;ceilingMs=a;backoffMultiplier=o;now(){return Date.now()}onSubscriberError(e,t){this.lastSubscriberError={id:e,error:t,at:this.now()},this.subscriberErrorCount+=1}lastSubscriberError;subscriberErrorCount=0;subscribers=new Map;nextSubscriberKey=0;timer;currentIntervalMs;running=!1;register(e){if(!(e.intervalMs>0))throw Error(`Poll subscriber "${e.id}" must have a positive intervalMs.`);let t=this.nextSubscriberKey++;return this.subscribers.set(t,{...e,lastRunAt:void 0}),()=>{this.subscribers.delete(t)}}start(){this.running||(this.running=!0,this.currentIntervalMs=this.floorMs,this.tick(!1))}stop(){this.running=!1,this.timer&&clearTimeout(this.timer),this.timer=void 0}wake(){this.running&&(this.timer&&clearTimeout(this.timer),this.timer=void 0,this.tick(!0))}tick(e){let t=this.now(),n=!1,r=!1;for(let i of this.subscribers.values())if(e||i.lastRunAt===void 0||t-i.lastRunAt>=i.intervalMs){i.lastRunAt=t,r=!0;try{i.run()&&(n=!0)}catch(e){this.onSubscriberError(i.id,e)}}if(r){let e=this.currentIntervalMs??this.floorMs;this.currentIntervalMs=n?this.floorMs:Math.min(e*this.backoffMultiplier,this.ceilingMs)}this.scheduleNext()}scheduleNext(){if(!this.running)return;let e=this.currentIntervalMs??this.floorMs;this.timer=setTimeout(()=>this.tick(!1),e),this.timer.unref?.()}},s=t([r()],s)}));c();export{s as PollScheduler,c as init_pollScheduler};
1
+ import{__esmMin as e}from"../_virtual/_rolldown/runtime.mjs";import{init_pollScheduler as t}from"../adapters/pollScheduler.mjs";var n=e((()=>{t()}));n();export{n as init_pollScheduler};
2
2
  //# sourceMappingURL=pollScheduler.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pollScheduler.mjs","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":"6OAyDM,EAAmB,IAEnB,EAAqB,IAErB,EAA6B,IAgC5B,KAA8C,CAMnD,QAAqC,EACrC,UAAuC,EACvC,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,QApHvB,GAAY,CAAA,CAAA,EAAA"}
1
+ {"version":3,"file":"pollScheduler.mjs","names":[],"sources":["../../src/shared/pollScheduler.ts"],"sourcesContent":["export { type IPollScheduler, PollScheduler, type PollSubscription } from '../adapters/pollScheduler.ts';\n"],"mappings":"iJAAyG"}
@@ -1,2 +1 @@
1
- const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`./atomicJson.cjs`),n=require(`./paths.cjs`),r=require(`./versioned.cjs`);let i=require(`node:fs`);i=e.__toESM(i,1);function a(e,r=Date.now()){let i={version:1,rootSessionId:e.rootSessionId,hostPid:process.pid,startedAt:r};return t.writeAtomicJson(n.scopeOwnerPath(e),i),i}function o(e){let t;try{t=i.readFileSync(n.scopeOwnerPath(e),`utf-8`)}catch{return}let a;try{a=JSON.parse(t)}catch{return}let o=r.parseVersioned(a,[1]);if(!o.ok)return;let s=o.value;if(!(typeof s.rootSessionId!=`string`||!s.rootSessionId)&&Number.isInteger(s.hostPid))return s}exports.readScopeOwner=o,exports.writeScopeOwner=a;
2
- //# sourceMappingURL=scopeOwner.cjs.map
1
+ require(`../adapters/scopeOwner.cjs`);
@@ -1,2 +1,2 @@
1
- import{__esmMin as e}from"../_virtual/_rolldown/runtime.mjs";import{init_atomicJson as t,writeAtomicJson as n}from"./atomicJson.mjs";import{init_paths as r,scopeOwnerPath as i}from"./paths.mjs";import{init_versioned as a,parseVersioned as o}from"./versioned.mjs";import*as s from"node:fs";function c(e,t=Date.now()){let r={version:u,rootSessionId:e.rootSessionId,hostPid:process.pid,startedAt:t};return n(i(e),r),r}function l(e){let t;try{t=s.readFileSync(i(e),`utf-8`)}catch{return}let n;try{n=JSON.parse(t)}catch{return}let r=o(n,[u]);if(!r.ok)return;let a=r.value;if(!(typeof a.rootSessionId!=`string`||!a.rootSessionId)&&Number.isInteger(a.hostPid))return a}var u,d=e((()=>{t(),r(),a(),u=1}));d();export{d as init_scopeOwner,l as readScopeOwner,c as writeScopeOwner};
1
+ import{init_scopeOwner as e}from"../adapters/scopeOwner.mjs";e();export{};
2
2
  //# sourceMappingURL=scopeOwner.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"scopeOwner.mjs","names":[],"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":"iSA8CA,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,EAAgB,EAAe,EAAM,CAAE,EAAO,CACvC,EAIT,SAAgB,EAAe,EAAmD,CAChF,IAAI,EACJ,GAAI,CACF,EAAM,EAAG,aAAa,EAAe,EAAM,CAAE,QAAQ,MAC/C,CAGN,OAGF,IAAI,EACJ,GAAI,CACF,EAAS,KAAK,MAAM,EAAI,MAClB,CACN,OAGF,IAAM,EAAS,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,qBAxDyC,IACa,IACf,CAE1C,EAAsB"}
1
+ {"version":3,"file":"scopeOwner.mjs","names":[],"sources":["../../src/shared/scopeOwner.ts"],"sourcesContent":["export {\n readScopeOwner,\n readScopeOwnerAsync,\n type ScopeOwnerRecord,\n writeScopeOwner,\n writeScopeOwnerAsync,\n} from '../adapters/scopeOwner.ts';\n"],"mappings":"gEAMmC"}
@@ -1,2 +1,2 @@
1
- require(`../_virtual/_rolldown/runtime.cjs`);let e=require(`@earendil-works/pi-tui`),t=require(`@agimon-ai/doompi-ui/components/doomOverlay`);t.DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;const n=`Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.`,r=[`tools`,`skills`,`extensions`],i=[[`↑↓/jk`,`move`],[`enter`,`view`],[`tab`,`cycle`],[`J/K`,`scroll`]];function a(t,n){let r=Math.max(0,n),i=(0,e.truncateToWidth)(t,r,`…`);return i+` `.repeat(Math.max(0,r-(0,e.visibleWidth)(i)))}function o(t,n,r){let i=Math.max(0,r),o=(0,e.visibleWidth)(n);return o+2>=i?a(t,i):`${a(t,Math.max(1,i-o-2))} ${a(n,o)}`}function s(t,n,r,i,a){for(let o of(0,e.wrapTextWithAnsi)(n,Math.max(1,r)))t.push(a.fg(i,o))}function c(e,t,n,r,i){if(e.push(i.bold(i.fg(`accent`,t))),n.length===0)e.push(i.fg(`dim`,` none`));else for(let t of n)s(e,` • ${t.name}`,r,`text`,i),t.detail&&s(e,` ${t.detail}`,r,`dim`,i);e.push(``)}function l(e,t){return t===`skills`?e.skills:t===`extensions`?e.extensions:e.tools}function u(e,t,n,r){let i=[];e.error&&(i.push(r.bold(r.fg(`error`,`PROJECTION ERROR`))),s(i,e.error,n,`error`,r),i.push(``));let a=l(e,t);return c(i,`PROJECTED EFFECTIVE`,a.effective,n,r),c(i,`REMOVED BY PARENT`,a.removed,n,r),c(i,`UNRESOLVED AT PREVIEW`,a.unresolved,n,r),i}function d(t,n,i){return(0,e.truncateToWidth)(r.map(e=>{let n=e.toUpperCase();return e===t?i.inverse(i.bold(` ${n} `)):i.fg(`dim`,` ${n} `)}).join(` `),Math.max(0,n),`…`)}function f(t){let n=Math.max(2,t-(0,e.visibleWidth)(`│`)),r=Math.max(1,Math.floor(n/3)),i=Math.max(1,n-r),a=+(r>=3&&i>=3);return{leftContentWidth:Math.max(1,r-a),rightContentWidth:Math.max(1,i-a),gutterWidth:a}}var p=class extends t.DoomOverlay{entries;cursorIndex=0;inspectedIndex;tab=`tools`;listPageSize=1;detailPageSize=1;detailOffset=0;detailTotal=0;constructor(e,t,n,r){super(e,t),this.done=r,this.entries=[...n].sort((e,t)=>e.agent.name.localeCompare(t.agent.name))}cursorEntry(){return this.entries[Math.min(this.cursorIndex,Math.max(0,this.entries.length-1))]}inspectedEntry(){if(this.inspectedIndex!==void 0)return this.entries[this.inspectedIndex]}moveCursor(e){if(this.entries.length===0)return;let t=Math.max(0,Math.min(this.entries.length-1,this.cursorIndex+e));t!==this.cursorIndex&&(this.cursorIndex=t,this.invalidate())}inspectCursor(){this.cursorEntry()&&(this.inspectedIndex=this.cursorIndex,this.detailOffset=0,this.invalidate())}switchTab(e){this.tab!==e&&(this.tab=e,this.detailOffset=0,this.invalidate())}cycleTab(){let e=r.indexOf(this.tab);this.switchTab(r[(e+1)%r.length]??`tools`)}scrollDetail(e){if(!this.inspectedEntry())return;let t=Math.max(0,this.detailTotal-this.detailPageSize),n=Math.max(0,Math.min(t,this.detailOffset+e));n!==this.detailOffset&&(this.detailOffset=n,this.invalidate())}handleInput(t){if((0,e.matchesKey)(t,`escape`)||(0,e.matchesKey)(t,`ctrl+c`)){this.done(void 0);return}if((0,e.matchesKey)(t,e.Key.shift(`k`)))return this.scrollDetail(-1);if((0,e.matchesKey)(t,e.Key.shift(`j`)))return this.scrollDetail(1);if((0,e.matchesKey)(t,`up`)||t===`k`)return this.moveCursor(-1);if((0,e.matchesKey)(t,`down`)||t===`j`)return this.moveCursor(1);if((0,e.matchesKey)(t,`pageUp`))return this.moveCursor(-this.listPageSize);if((0,e.matchesKey)(t,`pageDown`))return this.moveCursor(this.listPageSize);if((0,e.matchesKey)(t,`enter`))return this.inspectCursor();if((0,e.matchesKey)(t,`tab`))return this.cycleTab();if(t===`t`)return this.switchTab(`tools`);if(t===`s`)return this.switchTab(`skills`);if(t===`e`)return this.switchTab(`extensions`)}getChrome(){let e=this.cursorEntry(),n=this.inspectedEntry(),r=this.entries.length?String(this.cursorIndex+1):`empty`,a=e?n?`C${r} I${(this.inspectedIndex??0)+1}`:`C${r} I-`:`empty`;return{title:`AGENTS`,accent:t.DOOM_OVERLAY_ACCENT,breadcrumb:`SPC › a / agents › l / available`,headerRight:`${this.entries.length} available · ${this.tab}`,footer:`↑↓/jk cursor · PgUp/PgDn page · enter inspect · tab resource · J/K scroll · esc close`,footerHints:i,footerRight:a}}renderBody(e,t){let n=f(e),r=this.renderList(n.leftContentWidth,t),i=this.renderDetail(n.rightContentWidth,t),o=` `.repeat(n.gutterWidth),s=this.theme.fg(`borderMuted`,`│`),c=[];for(let e=0;e<t;e++)c.push(`${a(r[e]??``,n.leftContentWidth)}${o}${s}${o}${a(i[e]??``,n.rightContentWidth)}`);return c.map(t=>a(t,e))}renderList(e,t){let n=[this.theme.bold(this.theme.fg(`accent`,`AGENTS ${this.entries.length}`))];if(this.entries.length===0)return s(n,`No enabled agents are available from this session cwd.`,e,`dim`,this.theme),this.listPageSize=1,n.slice(0,t);this.listPageSize=Math.max(1,t-1);let r=Math.max(0,Math.min(this.cursorIndex-this.listPageSize+1,Math.max(0,this.entries.length-this.listPageSize)));for(let[t,i]of this.entries.slice(r,r+this.listPageSize).entries()){let s=r+t===this.cursorIndex,c=s?this.theme.fg(`accent`,`›`):` `,l=i.agent.runtime??`pi`,u=o(`${c} ${s?this.theme.bold(i.agent.name):i.agent.name}`,`${i.agent.source} · ${l}`,e),d=s?`selectedBg`:`userMessageBg`;n.push(this.theme.bg(d,a(u,e)))}return n.slice(0,t)}renderDetail(e,t){let r=this.inspectedEntry();if(!r){this.detailTotal=0,this.detailPageSize=Math.max(1,t),this.detailOffset=0;let r=[this.theme.bold(this.theme.fg(`accent`,`AGENT RESOURCES`)),``];return s(r,`Press Enter to inspect the cursor agent.`,e,`text`,this.theme),r.push(``),s(r,n,e,`dim`,this.theme),r.slice(0,t)}let i=r.agent.runtime??`pi`,a=[o(this.theme.bold(this.theme.fg(`accent`,`INSPECTING ${r.agent.name}`)),`${r.agent.source} · ${i}`,e)];s(a,r.agent.description,e,`text`,this.theme),s(a,r.resources.notice||n,e,r.resources.configuredOnly?`warning`:`dim`,this.theme),a.push(d(this.tab,e,this.theme),``);let c=u(r.resources,this.tab,e,this.theme);return this.detailPageSize=Math.max(0,t-a.length),this.detailTotal=c.length,this.detailOffset=Math.min(this.detailOffset,Math.max(0,c.length-this.detailPageSize)),[...a,...c.slice(this.detailOffset,this.detailOffset+this.detailPageSize)].slice(0,t)}};async function m(e,n){await e.ui.custom((e,t,r,i)=>new p(e,t,n,i),t.DOOM_FULLSCREEN_UI_OPTIONS)}exports.openAgentCatalog=m;
1
+ require(`../_virtual/_rolldown/runtime.cjs`);let e=require(`@earendil-works/pi-tui`),t=require(`@agimon-ai/doompi-ui/components/doomOverlay`),n=require(`@agimon-ai/doompi-ui/rendering`);t.DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;const r=`Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.`,i=[`tools`,`skills`,`extensions`],a=`${t.DOOM_NAVIGATION_KEYS.list} cursor · ${t.DOOM_NAVIGATION_KEYS.detail} scroll · PgUp/PgDn page · enter inspect · tab resource · esc close`,o=[[t.DOOM_NAVIGATION_KEYS.list,`move`],[t.DOOM_NAVIGATION_KEYS.detail,`scroll`],[`enter`,`view`],[`tab`,`cycle`]];function s(e,t){return(0,n.fitStyledLine)(e,t,`…`)}function c(t,n,r){let i=Math.max(0,r),a=(0,e.visibleWidth)(n);return a+2>=i?s(t,i):`${s(t,Math.max(1,i-a-2))} ${s(n,a)}`}function l(t,n,r,i,a){for(let o of(0,e.wrapTextWithAnsi)(n,Math.max(1,r)))t.push(a.fg(i,o))}function u(e,t,n,r,i){if(e.push(i.bold(i.fg(`accent`,t))),n.length===0)e.push(i.fg(`dim`,` none`));else for(let t of n)l(e,` • ${t.name}`,r,`text`,i),t.detail&&l(e,` ${t.detail}`,r,`dim`,i);e.push(``)}function d(e,t){return t===`skills`?e.skills:t===`extensions`?e.extensions:e.tools}function f(e,t,n,r){let i=[];e.error&&(i.push(r.bold(r.fg(`error`,`PROJECTION ERROR`))),l(i,e.error,n,`error`,r),i.push(``));let a=d(e,t);return u(i,`PROJECTED EFFECTIVE`,a.effective,n,r),u(i,`REMOVED BY PARENT`,a.removed,n,r),u(i,`UNRESOLVED AT PREVIEW`,a.unresolved,n,r),i}function p(t,n,r){return(0,e.truncateToWidth)(i.map(e=>{let n=e.toUpperCase();return e===t?r.inverse(r.bold(` ${n} `)):r.fg(`dim`,` ${n} `)}).join(` `),Math.max(0,n),`…`)}function m(t){let n=Math.max(2,t-(0,e.visibleWidth)(`│`)),r=Math.max(1,Math.floor(n/3)),i=Math.max(1,n-r),a=+(r>=3&&i>=3);return{leftContentWidth:Math.max(1,r-a),rightContentWidth:Math.max(1,i-a),gutterWidth:a}}var h=class extends t.DoomOverlay{entries;cursorIndex=0;inspectedIndex;tab=`tools`;listPageSize=1;detailPageSize=1;detailOffset=0;detailTotal=0;constructor(e,t,n,r){super(e,t),this.done=r,this.entries=[...n].sort((e,t)=>e.agent.name.localeCompare(t.agent.name))}cursorEntry(){return this.entries[Math.min(this.cursorIndex,Math.max(0,this.entries.length-1))]}inspectedEntry(){if(this.inspectedIndex!==void 0)return this.entries[this.inspectedIndex]}moveCursor(e){if(this.entries.length===0)return;let t=Math.max(0,Math.min(this.entries.length-1,this.cursorIndex+e));t!==this.cursorIndex&&(this.cursorIndex=t,this.invalidate())}inspectCursor(){this.cursorEntry()&&(this.inspectedIndex=this.cursorIndex,this.detailOffset=0,this.invalidate())}switchTab(e){this.tab!==e&&(this.tab=e,this.detailOffset=0,this.invalidate())}cycleTab(){let e=i.indexOf(this.tab);this.switchTab(i[(e+1)%i.length]??`tools`)}scrollDetail(e){if(!this.inspectedEntry())return;let t=Math.max(0,this.detailTotal-this.detailPageSize),n=Math.max(0,Math.min(t,this.detailOffset+e));n!==this.detailOffset&&(this.detailOffset=n,this.invalidate())}handleInput(t){if((0,e.matchesKey)(t,`escape`)||(0,e.matchesKey)(t,`ctrl+c`)){this.done(void 0);return}if((0,e.matchesKey)(t,e.Key.shift(`k`))){this.scrollDetail(-1);return}if((0,e.matchesKey)(t,e.Key.shift(`j`))){this.scrollDetail(1);return}if((0,e.matchesKey)(t,`up`)||t===`k`){this.moveCursor(-1);return}if((0,e.matchesKey)(t,`down`)||t===`j`){this.moveCursor(1);return}if((0,e.matchesKey)(t,`pageUp`)){this.moveCursor(-this.listPageSize);return}if((0,e.matchesKey)(t,`pageDown`)){this.moveCursor(this.listPageSize);return}if((0,e.matchesKey)(t,`enter`)){this.inspectCursor();return}if((0,e.matchesKey)(t,`tab`)){this.cycleTab();return}t===`t`?this.switchTab(`tools`):t===`s`?this.switchTab(`skills`):t===`e`&&this.switchTab(`extensions`)}getChrome(){let e=this.cursorEntry(),n=this.inspectedEntry(),r=this.entries.length?String(this.cursorIndex+1):`empty`,i=e?n?`C${r} I${(this.inspectedIndex??0)+1}`:`C${r} I-`:`empty`;return{title:`AGENTS`,accent:t.DOOM_OVERLAY_ACCENT,breadcrumb:`SPC › a / agents › l / available`,headerRight:`${this.entries.length} available · ${this.tab}`,footer:a,footerHints:o,footerRight:i}}renderBody(e,t){let n=m(e),r=this.renderList(n.leftContentWidth,t),i=this.renderDetail(n.rightContentWidth,t),a=` `.repeat(n.gutterWidth),o=this.theme.fg(`borderMuted`,`│`),c=[];for(let e=0;e<t;e++)c.push(`${s(r[e]??``,n.leftContentWidth)}${a}${o}${a}${s(i[e]??``,n.rightContentWidth)}`);return c.map(t=>s(t,e))}renderList(e,t){let n=[this.theme.bold(this.theme.fg(`accent`,`AGENTS ${this.entries.length}`))];if(this.entries.length===0)return l(n,`No enabled agents are available from this session cwd.`,e,`dim`,this.theme),this.listPageSize=1,n.slice(0,t);this.listPageSize=Math.max(1,t-1);let r=Math.max(0,Math.min(this.cursorIndex-this.listPageSize+1,Math.max(0,this.entries.length-this.listPageSize)));for(let[t,i]of this.entries.slice(r,r+this.listPageSize).entries()){let a=r+t===this.cursorIndex,o=a?this.theme.fg(`accent`,`›`):` `,l=i.agent.runtime??`pi`,u=c(`${o} ${a?this.theme.bold(i.agent.name):i.agent.name}`,`${i.agent.source} · ${l}`,e),d=a?`selectedBg`:`userMessageBg`;n.push(this.theme.bg(d,s(u,e)))}return n.slice(0,t)}renderDetail(e,t){let n=this.inspectedEntry();if(!n){this.detailTotal=0,this.detailPageSize=Math.max(1,t),this.detailOffset=0;let n=[this.theme.bold(this.theme.fg(`accent`,`AGENT RESOURCES`)),``];return l(n,`Press Enter to inspect the cursor agent.`,e,`text`,this.theme),n.push(``),l(n,r,e,`dim`,this.theme),n.slice(0,t)}let i=n.agent.runtime??`pi`,a=[c(this.theme.bold(this.theme.fg(`accent`,`INSPECTING ${n.agent.name}`)),`${n.agent.source} · ${i}`,e)];l(a,n.agent.description,e,`text`,this.theme),l(a,n.resources.notice||r,e,n.resources.configuredOnly?`warning`:`dim`,this.theme),a.push(p(this.tab,e,this.theme),``);let o=f(n.resources,this.tab,e,this.theme);return this.detailPageSize=Math.max(0,t-a.length),this.detailTotal=o.length,this.detailOffset=Math.min(this.detailOffset,Math.max(0,o.length-this.detailPageSize)),[...a,...o.slice(this.detailOffset,this.detailOffset+this.detailPageSize)].slice(0,t)}};async function g(e,n){await e.ui.custom((e,t,r,i)=>new h(e,t,n,i),t.DOOM_FULLSCREEN_UI_OPTIONS)}exports.openAgentCatalog=g;
2
2
  //# sourceMappingURL=agentCatalog.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"agentCatalog.cjs","names":["DOOM_FULLSCREEN_UI_OPTIONS","DoomOverlay","Key","DOOM_OVERLAY_ACCENT"],"sources":["../../src/tui/agentCatalog.ts"],"sourcesContent":["import type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/components/doomOverlay';\nimport { Key, matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi } from '@earendil-works/pi-tui';\n\nimport type { AgentConfig } from '../agents/types.ts';\nimport type {\n AgentCatalogEntry,\n AgentResourceProjection,\n ProjectedResource,\n ResourceTabProjection,\n} from './agentResourceProjection.ts';\n\nexport const AGENT_CATALOG_OVERLAY_OPTIONS = DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;\nexport type AgentResourceTab = 'tools' | 'skills' | 'extensions';\n\ntype ThemeBg = Parameters<Theme['bg']>[0];\ntype ThemeColor = Parameters<Theme['fg']>[0];\n\ninterface SplitLayout {\n leftContentWidth: number;\n rightContentWidth: number;\n gutterWidth: number;\n}\n\nconst TITLE = 'AGENTS';\nconst BREADCRUMB = 'SPC › a / agents › l / available';\nconst SELECTION_MARKER = '›';\nconst ELLIPSIS = '…';\nconst DEFAULT_PAGE_SIZE = 1;\nconst PI_RUNTIME = 'pi';\nconst DIVIDER = '│';\nconst PROJECTED_EFFECTIVE = 'PROJECTED EFFECTIVE';\nconst REMOVED_BY_PARENT = 'REMOVED BY PARENT';\nconst UNRESOLVED_AT_PREVIEW = 'UNRESOLVED AT PREVIEW';\nconst PROJECTION_ERROR = 'PROJECTION ERROR';\nconst GLOBAL_PREVIEW_NOTICE =\n 'Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.';\nconst TAB_ORDER: readonly AgentResourceTab[] = ['tools', 'skills', 'extensions'];\nconst FOOTER = '↑↓/jk cursor · PgUp/PgDn page · enter inspect · tab resource · J/K scroll · esc close';\nconst FOOTER_HINTS: readonly (readonly [string, string])[] = [\n ['↑↓/jk', 'move'],\n ['enter', 'view'],\n ['tab', 'cycle'],\n ['J/K', 'scroll'],\n];\n\nfunction fit(text: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const clipped = truncateToWidth(text, safeWidth, ELLIPSIS);\n return clipped + ' '.repeat(Math.max(0, safeWidth - visibleWidth(clipped)));\n}\n\nfunction rightAligned(left: string, right: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const rightWidth = visibleWidth(right);\n if (rightWidth + 2 >= safeWidth) return fit(left, safeWidth);\n const leftWidth = Math.max(1, safeWidth - rightWidth - 2);\n return `${fit(left, leftWidth)} ${fit(right, rightWidth)}`;\n}\n\nfunction plural(count: number, singular: string): string {\n return `${count} ${singular}${count === 1 ? '' : 's'}`;\n}\n\nexport function agentResourceSummary(agent: AgentConfig): string {\n const mcpTools = plural(agent.mcpDirectTools?.length ?? 0, 'MCP tool');\n const skills = plural(agent.skills?.length ?? 0, 'skill');\n const extensions = plural((agent.extensions?.length ?? 0) + (agent.subagentOnlyExtensions?.length ?? 0), 'extension');\n const configured = `${mcpTools} · ${skills} · ${extensions}`;\n return agent.tools === undefined\n ? `tools default · configured: ${configured}`\n : `configured: ${plural(agent.tools.length, 'tool')} · ${configured}`;\n}\n\nfunction appendWrapped(lines: string[], text: string, width: number, colour: ThemeColor, theme: Theme): void {\n for (const line of wrapTextWithAnsi(text, Math.max(1, width))) lines.push(theme.fg(colour, line));\n}\n\nfunction appendResources(\n lines: string[],\n heading: string,\n items: readonly ProjectedResource[],\n width: number,\n theme: Theme,\n): void {\n lines.push(theme.bold(theme.fg('accent', heading)));\n if (items.length === 0) {\n lines.push(theme.fg('dim', ' none'));\n } else {\n for (const item of items) {\n appendWrapped(lines, ` • ${item.name}`, width, 'text', theme);\n if (item.detail) appendWrapped(lines, ` ${item.detail}`, width, 'dim', theme);\n }\n }\n lines.push('');\n}\n\nfunction tabProjection(projection: AgentResourceProjection, tab: AgentResourceTab): ResourceTabProjection {\n if (tab === 'skills') return projection.skills;\n if (tab === 'extensions') return projection.extensions;\n return projection.tools;\n}\n\nfunction resourceLines(\n projection: AgentResourceProjection,\n tab: AgentResourceTab,\n width: number,\n theme: Theme,\n): string[] {\n const lines: string[] = [];\n if (projection.error) {\n lines.push(theme.bold(theme.fg('error', PROJECTION_ERROR)));\n appendWrapped(lines, projection.error, width, 'error', theme);\n lines.push('');\n }\n const resources = tabProjection(projection, tab);\n appendResources(lines, PROJECTED_EFFECTIVE, resources.effective, width, theme);\n appendResources(lines, REMOVED_BY_PARENT, resources.removed, width, theme);\n appendResources(lines, UNRESOLVED_AT_PREVIEW, resources.unresolved, width, theme);\n return lines;\n}\n\nfunction tabStrip(tab: AgentResourceTab, width: number, theme: Theme): string {\n const labels = TAB_ORDER.map((candidate) => {\n const label = candidate.toUpperCase();\n return candidate === tab ? theme.inverse(theme.bold(` ${label} `)) : theme.fg('dim', ` ${label} `);\n }).join(' ');\n return truncateToWidth(labels, Math.max(0, width), ELLIPSIS);\n}\n\nfunction splitLayout(width: number): SplitLayout {\n const paneBudget = Math.max(2, width - visibleWidth(DIVIDER));\n const leftPaneWidth = Math.max(1, Math.floor(paneBudget / 3));\n const rightPaneWidth = Math.max(1, paneBudget - leftPaneWidth);\n const gutterWidth = leftPaneWidth >= 3 && rightPaneWidth >= 3 ? 1 : 0;\n return {\n leftContentWidth: Math.max(1, leftPaneWidth - gutterWidth),\n rightContentWidth: Math.max(1, rightPaneWidth - gutterWidth),\n gutterWidth,\n };\n}\n\nexport class AgentCatalogComponent extends DoomOverlay {\n private readonly entries: AgentCatalogEntry[];\n private cursorIndex = 0;\n private inspectedIndex: number | undefined;\n private tab: AgentResourceTab = 'tools';\n private listPageSize = DEFAULT_PAGE_SIZE;\n private detailPageSize = DEFAULT_PAGE_SIZE;\n private detailOffset = 0;\n private detailTotal = 0;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n entries: readonly AgentCatalogEntry[],\n private readonly done: (result: undefined) => void,\n ) {\n super(tui, theme);\n this.entries = [...entries].sort((left, right) => left.agent.name.localeCompare(right.agent.name));\n }\n\n private cursorEntry(): AgentCatalogEntry | undefined {\n return this.entries[Math.min(this.cursorIndex, Math.max(0, this.entries.length - 1))];\n }\n\n private inspectedEntry(): AgentCatalogEntry | undefined {\n if (this.inspectedIndex === undefined) return undefined;\n return this.entries[this.inspectedIndex];\n }\n\n private moveCursor(delta: number): void {\n if (this.entries.length === 0) return;\n const next = Math.max(0, Math.min(this.entries.length - 1, this.cursorIndex + delta));\n if (next === this.cursorIndex) return;\n this.cursorIndex = next;\n this.invalidate();\n }\n\n private inspectCursor(): void {\n if (!this.cursorEntry()) return;\n this.inspectedIndex = this.cursorIndex;\n this.detailOffset = 0;\n this.invalidate();\n }\n\n private switchTab(tab: AgentResourceTab): void {\n if (this.tab === tab) return;\n this.tab = tab;\n this.detailOffset = 0;\n this.invalidate();\n }\n\n private cycleTab(): void {\n const current = TAB_ORDER.indexOf(this.tab);\n this.switchTab(TAB_ORDER[(current + 1) % TAB_ORDER.length] ?? 'tools');\n }\n\n private scrollDetail(delta: number): void {\n if (!this.inspectedEntry()) return;\n const maximum = Math.max(0, this.detailTotal - this.detailPageSize);\n const next = Math.max(0, Math.min(maximum, this.detailOffset + delta));\n if (next === this.detailOffset) return;\n this.detailOffset = next;\n this.invalidate();\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.done(undefined);\n return;\n }\n if (matchesKey(data, Key.shift('k'))) return this.scrollDetail(-1);\n if (matchesKey(data, Key.shift('j'))) return this.scrollDetail(1);\n if (matchesKey(data, 'up') || data === 'k') return this.moveCursor(-1);\n if (matchesKey(data, 'down') || data === 'j') return this.moveCursor(1);\n if (matchesKey(data, 'pageUp')) return this.moveCursor(-this.listPageSize);\n if (matchesKey(data, 'pageDown')) return this.moveCursor(this.listPageSize);\n if (matchesKey(data, 'enter')) return this.inspectCursor();\n if (matchesKey(data, 'tab')) return this.cycleTab();\n if (data === 't') return this.switchTab('tools');\n if (data === 's') return this.switchTab('skills');\n if (data === 'e') return this.switchTab('extensions');\n }\n\n protected getChrome(): DoomOverlayChrome {\n const cursor = this.cursorEntry();\n const inspected = this.inspectedEntry();\n const cursorPosition = this.entries.length ? String(this.cursorIndex + 1) : 'empty';\n const footerRight = !cursor\n ? 'empty'\n : inspected\n ? `C${cursorPosition} I${(this.inspectedIndex ?? 0) + 1}`\n : `C${cursorPosition} I-`;\n return {\n title: TITLE,\n accent: DOOM_OVERLAY_ACCENT,\n breadcrumb: BREADCRUMB,\n headerRight: `${this.entries.length} available · ${this.tab}`,\n footer: FOOTER,\n footerHints: FOOTER_HINTS,\n footerRight,\n };\n }\n\n protected renderBody(width: number, height: number): string[] {\n const layout = splitLayout(width);\n const left = this.renderList(layout.leftContentWidth, height);\n const right = this.renderDetail(layout.rightContentWidth, height);\n const gutter = ' '.repeat(layout.gutterWidth);\n const divider = this.theme.fg('borderMuted', DIVIDER);\n const lines: string[] = [];\n for (let index = 0; index < height; index++) {\n lines.push(\n `${fit(left[index] ?? '', layout.leftContentWidth)}${gutter}${divider}${gutter}${fit(\n right[index] ?? '',\n layout.rightContentWidth,\n )}`,\n );\n }\n return lines.map((line) => fit(line, width));\n }\n\n private renderList(width: number, height: number): string[] {\n const lines = [this.theme.bold(this.theme.fg('accent', `AGENTS ${this.entries.length}`))];\n if (this.entries.length === 0) {\n appendWrapped(lines, 'No enabled agents are available from this session cwd.', width, 'dim', this.theme);\n this.listPageSize = DEFAULT_PAGE_SIZE;\n return lines.slice(0, height);\n }\n\n this.listPageSize = Math.max(DEFAULT_PAGE_SIZE, height - 1);\n const start = Math.max(\n 0,\n Math.min(this.cursorIndex - this.listPageSize + 1, Math.max(0, this.entries.length - this.listPageSize)),\n );\n for (const [offset, entry] of this.entries.slice(start, start + this.listPageSize).entries()) {\n const index = start + offset;\n const current = index === this.cursorIndex;\n const marker = current ? this.theme.fg('accent', SELECTION_MARKER) : ' ';\n const runtime = entry.agent.runtime ?? PI_RUNTIME;\n const name = current ? this.theme.bold(entry.agent.name) : entry.agent.name;\n const row = rightAligned(`${marker} ${name}`, `${entry.agent.source} · ${runtime}`, width);\n const background: ThemeBg = current ? 'selectedBg' : 'userMessageBg';\n lines.push(this.theme.bg(background, fit(row, width)));\n }\n return lines.slice(0, height);\n }\n\n private renderDetail(width: number, height: number): string[] {\n const entry = this.inspectedEntry();\n if (!entry) {\n this.detailTotal = 0;\n this.detailPageSize = Math.max(DEFAULT_PAGE_SIZE, height);\n this.detailOffset = 0;\n const lines = [this.theme.bold(this.theme.fg('accent', 'AGENT RESOURCES')), ''];\n appendWrapped(lines, 'Press Enter to inspect the cursor agent.', width, 'text', this.theme);\n lines.push('');\n appendWrapped(lines, GLOBAL_PREVIEW_NOTICE, width, 'dim', this.theme);\n return lines.slice(0, height);\n }\n\n const runtime = entry.agent.runtime ?? PI_RUNTIME;\n const header = [\n rightAligned(\n this.theme.bold(this.theme.fg('accent', `INSPECTING ${entry.agent.name}`)),\n `${entry.agent.source} · ${runtime}`,\n width,\n ),\n ];\n appendWrapped(header, entry.agent.description, width, 'text', this.theme);\n appendWrapped(\n header,\n entry.resources.notice || GLOBAL_PREVIEW_NOTICE,\n width,\n entry.resources.configuredOnly ? 'warning' : 'dim',\n this.theme,\n );\n header.push(tabStrip(this.tab, width, this.theme), '');\n\n const resources = resourceLines(entry.resources, this.tab, width, this.theme);\n this.detailPageSize = Math.max(0, height - header.length);\n this.detailTotal = resources.length;\n this.detailOffset = Math.min(this.detailOffset, Math.max(0, resources.length - this.detailPageSize));\n return [...header, ...resources.slice(this.detailOffset, this.detailOffset + this.detailPageSize)].slice(0, height);\n }\n}\n\nexport async function openAgentCatalog(ctx: ExtensionContext, entries: readonly AgentCatalogEntry[]): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new AgentCatalogComponent(tui, theme, entries, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agentCatalog.cjs","names":["DOOM_FULLSCREEN_UI_OPTIONS","DOOM_NAVIGATION_KEYS","DoomOverlay","Key","DOOM_OVERLAY_ACCENT"],"sources":["../../src/tui/agentCatalog.ts"],"sourcesContent":["import {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_NAVIGATION_KEYS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/components/doomOverlay';\nimport { fitStyledLine } from '@agimon-ai/doompi-ui/rendering';\nimport type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { Key, matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi } from '@earendil-works/pi-tui';\n\nimport type { AgentConfig } from '../services/agents/types.ts';\nimport type {\n AgentCatalogEntry,\n AgentResourceProjection,\n ProjectedResource,\n ResourceTabProjection,\n} from './agentResourceProjection.ts';\n\nexport const AGENT_CATALOG_OVERLAY_OPTIONS = DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;\nexport type AgentResourceTab = 'tools' | 'skills' | 'extensions';\n\ntype ThemeBg = Parameters<Theme['bg']>[0];\ntype ThemeColor = Parameters<Theme['fg']>[0];\n\ninterface SplitLayout {\n leftContentWidth: number;\n rightContentWidth: number;\n gutterWidth: number;\n}\n\nconst TITLE = 'AGENTS';\nconst BREADCRUMB = 'SPC › a / agents › l / available';\nconst SELECTION_MARKER = '›';\nconst ELLIPSIS = '…';\nconst DEFAULT_PAGE_SIZE = 1;\nconst PI_RUNTIME = 'pi';\nconst DIVIDER = '│';\nconst PROJECTED_EFFECTIVE = 'PROJECTED EFFECTIVE';\nconst REMOVED_BY_PARENT = 'REMOVED BY PARENT';\nconst UNRESOLVED_AT_PREVIEW = 'UNRESOLVED AT PREVIEW';\nconst PROJECTION_ERROR = 'PROJECTION ERROR';\nconst GLOBAL_PREVIEW_NOTICE =\n 'Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.';\nconst TAB_ORDER: readonly AgentResourceTab[] = ['tools', 'skills', 'extensions'];\nconst FOOTER = `${DOOM_NAVIGATION_KEYS.list} cursor · ${DOOM_NAVIGATION_KEYS.detail} scroll · PgUp/PgDn page · enter inspect · tab resource · esc close`;\nconst FOOTER_HINTS: readonly (readonly [string, string])[] = [\n [DOOM_NAVIGATION_KEYS.list, 'move'],\n [DOOM_NAVIGATION_KEYS.detail, 'scroll'],\n ['enter', 'view'],\n ['tab', 'cycle'],\n];\n\nfunction fitRow(text: string, width: number): string {\n return fitStyledLine(text, width, ELLIPSIS);\n}\n\nfunction rightAligned(left: string, right: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const rightWidth = visibleWidth(right);\n if (rightWidth + 2 >= safeWidth) return fitRow(left, safeWidth);\n const leftWidth = Math.max(1, safeWidth - rightWidth - 2);\n return `${fitRow(left, leftWidth)} ${fitRow(right, rightWidth)}`;\n}\n\nfunction plural(count: number, singular: string): string {\n return `${count} ${singular}${count === 1 ? '' : 's'}`;\n}\n\nexport function agentResourceSummary(agent: AgentConfig): string {\n const mcpTools = plural(agent.mcpDirectTools?.length ?? 0, 'MCP tool');\n const skills = plural(agent.skills?.length ?? 0, 'skill');\n const extensions = plural((agent.extensions?.length ?? 0) + (agent.subagentOnlyExtensions?.length ?? 0), 'extension');\n const configured = `${mcpTools} · ${skills} · ${extensions}`;\n return agent.tools === undefined\n ? `tools default · configured: ${configured}`\n : `configured: ${plural(agent.tools.length, 'tool')} · ${configured}`;\n}\n\nfunction appendWrapped(lines: string[], text: string, width: number, colour: ThemeColor, theme: Theme): void {\n for (const line of wrapTextWithAnsi(text, Math.max(1, width))) lines.push(theme.fg(colour, line));\n}\n\nfunction appendResources(\n lines: string[],\n heading: string,\n items: readonly ProjectedResource[],\n width: number,\n theme: Theme,\n): void {\n lines.push(theme.bold(theme.fg('accent', heading)));\n if (items.length === 0) {\n lines.push(theme.fg('dim', ' none'));\n } else {\n for (const item of items) {\n appendWrapped(lines, ` • ${item.name}`, width, 'text', theme);\n if (item.detail) appendWrapped(lines, ` ${item.detail}`, width, 'dim', theme);\n }\n }\n lines.push('');\n}\n\nfunction tabProjection(projection: AgentResourceProjection, tab: AgentResourceTab): ResourceTabProjection {\n if (tab === 'skills') return projection.skills;\n if (tab === 'extensions') return projection.extensions;\n return projection.tools;\n}\n\nfunction resourceLines(\n projection: AgentResourceProjection,\n tab: AgentResourceTab,\n width: number,\n theme: Theme,\n): string[] {\n const lines: string[] = [];\n if (projection.error) {\n lines.push(theme.bold(theme.fg('error', PROJECTION_ERROR)));\n appendWrapped(lines, projection.error, width, 'error', theme);\n lines.push('');\n }\n const resources = tabProjection(projection, tab);\n appendResources(lines, PROJECTED_EFFECTIVE, resources.effective, width, theme);\n appendResources(lines, REMOVED_BY_PARENT, resources.removed, width, theme);\n appendResources(lines, UNRESOLVED_AT_PREVIEW, resources.unresolved, width, theme);\n return lines;\n}\n\nfunction tabStrip(tab: AgentResourceTab, width: number, theme: Theme): string {\n const labels = TAB_ORDER.map((candidate) => {\n const label = candidate.toUpperCase();\n return candidate === tab ? theme.inverse(theme.bold(` ${label} `)) : theme.fg('dim', ` ${label} `);\n }).join(' ');\n return truncateToWidth(labels, Math.max(0, width), ELLIPSIS);\n}\n\nfunction splitLayout(width: number): SplitLayout {\n const paneBudget = Math.max(2, width - visibleWidth(DIVIDER));\n const leftPaneWidth = Math.max(1, Math.floor(paneBudget / 3));\n const rightPaneWidth = Math.max(1, paneBudget - leftPaneWidth);\n const gutterWidth = leftPaneWidth >= 3 && rightPaneWidth >= 3 ? 1 : 0;\n return {\n leftContentWidth: Math.max(1, leftPaneWidth - gutterWidth),\n rightContentWidth: Math.max(1, rightPaneWidth - gutterWidth),\n gutterWidth,\n };\n}\n\nexport class AgentCatalogComponent extends DoomOverlay {\n private readonly entries: AgentCatalogEntry[];\n private cursorIndex = 0;\n private inspectedIndex: number | undefined;\n private tab: AgentResourceTab = 'tools';\n private listPageSize = DEFAULT_PAGE_SIZE;\n private detailPageSize = DEFAULT_PAGE_SIZE;\n private detailOffset = 0;\n private detailTotal = 0;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n entries: readonly AgentCatalogEntry[],\n private readonly done: (result: undefined) => void,\n ) {\n super(tui, theme);\n this.entries = [...entries].sort((left, right) => left.agent.name.localeCompare(right.agent.name));\n }\n\n private cursorEntry(): AgentCatalogEntry | undefined {\n return this.entries[Math.min(this.cursorIndex, Math.max(0, this.entries.length - 1))];\n }\n\n private inspectedEntry(): AgentCatalogEntry | undefined {\n if (this.inspectedIndex === undefined) return undefined;\n return this.entries[this.inspectedIndex];\n }\n\n private moveCursor(delta: number): void {\n if (this.entries.length === 0) return;\n const next = Math.max(0, Math.min(this.entries.length - 1, this.cursorIndex + delta));\n if (next === this.cursorIndex) return;\n this.cursorIndex = next;\n this.invalidate();\n }\n\n private inspectCursor(): void {\n if (!this.cursorEntry()) return;\n this.inspectedIndex = this.cursorIndex;\n this.detailOffset = 0;\n this.invalidate();\n }\n\n private switchTab(tab: AgentResourceTab): void {\n if (this.tab === tab) return;\n this.tab = tab;\n this.detailOffset = 0;\n this.invalidate();\n }\n\n private cycleTab(): void {\n const current = TAB_ORDER.indexOf(this.tab);\n this.switchTab(TAB_ORDER[(current + 1) % TAB_ORDER.length] ?? 'tools');\n }\n\n private scrollDetail(delta: number): void {\n if (!this.inspectedEntry()) return;\n const maximum = Math.max(0, this.detailTotal - this.detailPageSize);\n const next = Math.max(0, Math.min(maximum, this.detailOffset + delta));\n if (next === this.detailOffset) return;\n this.detailOffset = next;\n this.invalidate();\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.done(undefined);\n return;\n }\n if (matchesKey(data, Key.shift('k'))) {\n this.scrollDetail(-1);\n return;\n }\n if (matchesKey(data, Key.shift('j'))) {\n this.scrollDetail(1);\n return;\n }\n if (matchesKey(data, 'up') || data === 'k') {\n this.moveCursor(-1);\n return;\n }\n if (matchesKey(data, 'down') || data === 'j') {\n this.moveCursor(1);\n return;\n }\n if (matchesKey(data, 'pageUp')) {\n this.moveCursor(-this.listPageSize);\n return;\n }\n if (matchesKey(data, 'pageDown')) {\n this.moveCursor(this.listPageSize);\n return;\n }\n if (matchesKey(data, 'enter')) {\n this.inspectCursor();\n return;\n }\n if (matchesKey(data, 'tab')) {\n this.cycleTab();\n return;\n }\n if (data === 't') this.switchTab('tools');\n else if (data === 's') this.switchTab('skills');\n else if (data === 'e') this.switchTab('extensions');\n }\n\n protected getChrome(): DoomOverlayChrome {\n const cursor = this.cursorEntry();\n const inspected = this.inspectedEntry();\n const cursorPosition = this.entries.length ? String(this.cursorIndex + 1) : 'empty';\n const footerRight = !cursor\n ? 'empty'\n : inspected\n ? `C${cursorPosition} I${(this.inspectedIndex ?? 0) + 1}`\n : `C${cursorPosition} I-`;\n return {\n title: TITLE,\n accent: DOOM_OVERLAY_ACCENT,\n breadcrumb: BREADCRUMB,\n headerRight: `${this.entries.length} available · ${this.tab}`,\n footer: FOOTER,\n footerHints: FOOTER_HINTS,\n footerRight,\n };\n }\n\n protected renderBody(width: number, height: number): string[] {\n const layout = splitLayout(width);\n const left = this.renderList(layout.leftContentWidth, height);\n const right = this.renderDetail(layout.rightContentWidth, height);\n const gutter = ' '.repeat(layout.gutterWidth);\n const divider = this.theme.fg('borderMuted', DIVIDER);\n const lines: string[] = [];\n for (let index = 0; index < height; index++) {\n lines.push(\n `${fitRow(left[index] ?? '', layout.leftContentWidth)}${gutter}${divider}${gutter}${fitRow(\n right[index] ?? '',\n layout.rightContentWidth,\n )}`,\n );\n }\n return lines.map((line) => fitRow(line, width));\n }\n\n private renderList(width: number, height: number): string[] {\n const lines = [this.theme.bold(this.theme.fg('accent', `AGENTS ${this.entries.length}`))];\n if (this.entries.length === 0) {\n appendWrapped(lines, 'No enabled agents are available from this session cwd.', width, 'dim', this.theme);\n this.listPageSize = DEFAULT_PAGE_SIZE;\n return lines.slice(0, height);\n }\n\n this.listPageSize = Math.max(DEFAULT_PAGE_SIZE, height - 1);\n const start = Math.max(\n 0,\n Math.min(this.cursorIndex - this.listPageSize + 1, Math.max(0, this.entries.length - this.listPageSize)),\n );\n for (const [offset, entry] of this.entries.slice(start, start + this.listPageSize).entries()) {\n const index = start + offset;\n const current = index === this.cursorIndex;\n const marker = current ? this.theme.fg('accent', SELECTION_MARKER) : ' ';\n const runtime = entry.agent.runtime ?? PI_RUNTIME;\n const name = current ? this.theme.bold(entry.agent.name) : entry.agent.name;\n const row = rightAligned(`${marker} ${name}`, `${entry.agent.source} · ${runtime}`, width);\n const background: ThemeBg = current ? 'selectedBg' : 'userMessageBg';\n lines.push(this.theme.bg(background, fitRow(row, width)));\n }\n return lines.slice(0, height);\n }\n\n private renderDetail(width: number, height: number): string[] {\n const entry = this.inspectedEntry();\n if (!entry) {\n this.detailTotal = 0;\n this.detailPageSize = Math.max(DEFAULT_PAGE_SIZE, height);\n this.detailOffset = 0;\n const lines = [this.theme.bold(this.theme.fg('accent', 'AGENT RESOURCES')), ''];\n appendWrapped(lines, 'Press Enter to inspect the cursor agent.', width, 'text', this.theme);\n lines.push('');\n appendWrapped(lines, GLOBAL_PREVIEW_NOTICE, width, 'dim', this.theme);\n return lines.slice(0, height);\n }\n\n const runtime = entry.agent.runtime ?? PI_RUNTIME;\n const header = [\n rightAligned(\n this.theme.bold(this.theme.fg('accent', `INSPECTING ${entry.agent.name}`)),\n `${entry.agent.source} · ${runtime}`,\n width,\n ),\n ];\n appendWrapped(header, entry.agent.description, width, 'text', this.theme);\n appendWrapped(\n header,\n entry.resources.notice || GLOBAL_PREVIEW_NOTICE,\n width,\n entry.resources.configuredOnly ? 'warning' : 'dim',\n this.theme,\n );\n header.push(tabStrip(this.tab, width, this.theme), '');\n\n const resources = resourceLines(entry.resources, this.tab, width, this.theme);\n this.detailPageSize = Math.max(0, height - header.length);\n this.detailTotal = resources.length;\n this.detailOffset = Math.min(this.detailOffset, Math.max(0, resources.length - this.detailPageSize));\n return [...header, ...resources.slice(this.detailOffset, this.detailOffset + this.detailPageSize)].slice(0, height);\n }\n}\n\nexport async function openAgentCatalog(ctx: ExtensionContext, entries: readonly AgentCatalogEntry[]): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new AgentCatalogComponent(tui, theme, entries, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{Key as e,matchesKey as t,truncateToWidth as n,visibleWidth as r,wrapTextWithAnsi as i}from"@earendil-works/pi-tui";import{DOOM_FULLSCREEN_UI_OPTIONS as a,DOOM_OVERLAY_ACCENT as o,DoomOverlay as s}from"@agimon-ai/doompi-ui/components/doomOverlay";a.overlayOptions;const c=`Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.`,l=[`tools`,`skills`,`extensions`],u=[[`↑↓/jk`,`move`],[`enter`,`view`],[`tab`,`cycle`],[`J/K`,`scroll`]];function d(e,t){let i=Math.max(0,t),a=n(e,i,`…`);return a+` `.repeat(Math.max(0,i-r(a)))}function f(e,t,n){let i=Math.max(0,n),a=r(t);return a+2>=i?d(e,i):`${d(e,Math.max(1,i-a-2))} ${d(t,a)}`}function p(e,t,n,r,a){for(let o of i(t,Math.max(1,n)))e.push(a.fg(r,o))}function m(e,t,n,r,i){if(e.push(i.bold(i.fg(`accent`,t))),n.length===0)e.push(i.fg(`dim`,` none`));else for(let t of n)p(e,` • ${t.name}`,r,`text`,i),t.detail&&p(e,` ${t.detail}`,r,`dim`,i);e.push(``)}function h(e,t){return t===`skills`?e.skills:t===`extensions`?e.extensions:e.tools}function g(e,t,n,r){let i=[];e.error&&(i.push(r.bold(r.fg(`error`,`PROJECTION ERROR`))),p(i,e.error,n,`error`,r),i.push(``));let a=h(e,t);return m(i,`PROJECTED EFFECTIVE`,a.effective,n,r),m(i,`REMOVED BY PARENT`,a.removed,n,r),m(i,`UNRESOLVED AT PREVIEW`,a.unresolved,n,r),i}function _(e,t,r){return n(l.map(t=>{let n=t.toUpperCase();return t===e?r.inverse(r.bold(` ${n} `)):r.fg(`dim`,` ${n} `)}).join(` `),Math.max(0,t),`…`)}function v(e){let t=Math.max(2,e-r(`│`)),n=Math.max(1,Math.floor(t/3)),i=Math.max(1,t-n),a=+(n>=3&&i>=3);return{leftContentWidth:Math.max(1,n-a),rightContentWidth:Math.max(1,i-a),gutterWidth:a}}var y=class extends s{entries;cursorIndex=0;inspectedIndex;tab=`tools`;listPageSize=1;detailPageSize=1;detailOffset=0;detailTotal=0;constructor(e,t,n,r){super(e,t),this.done=r,this.entries=[...n].sort((e,t)=>e.agent.name.localeCompare(t.agent.name))}cursorEntry(){return this.entries[Math.min(this.cursorIndex,Math.max(0,this.entries.length-1))]}inspectedEntry(){if(this.inspectedIndex!==void 0)return this.entries[this.inspectedIndex]}moveCursor(e){if(this.entries.length===0)return;let t=Math.max(0,Math.min(this.entries.length-1,this.cursorIndex+e));t!==this.cursorIndex&&(this.cursorIndex=t,this.invalidate())}inspectCursor(){this.cursorEntry()&&(this.inspectedIndex=this.cursorIndex,this.detailOffset=0,this.invalidate())}switchTab(e){this.tab!==e&&(this.tab=e,this.detailOffset=0,this.invalidate())}cycleTab(){let e=l.indexOf(this.tab);this.switchTab(l[(e+1)%l.length]??`tools`)}scrollDetail(e){if(!this.inspectedEntry())return;let t=Math.max(0,this.detailTotal-this.detailPageSize),n=Math.max(0,Math.min(t,this.detailOffset+e));n!==this.detailOffset&&(this.detailOffset=n,this.invalidate())}handleInput(n){if(t(n,`escape`)||t(n,`ctrl+c`)){this.done(void 0);return}if(t(n,e.shift(`k`)))return this.scrollDetail(-1);if(t(n,e.shift(`j`)))return this.scrollDetail(1);if(t(n,`up`)||n===`k`)return this.moveCursor(-1);if(t(n,`down`)||n===`j`)return this.moveCursor(1);if(t(n,`pageUp`))return this.moveCursor(-this.listPageSize);if(t(n,`pageDown`))return this.moveCursor(this.listPageSize);if(t(n,`enter`))return this.inspectCursor();if(t(n,`tab`))return this.cycleTab();if(n===`t`)return this.switchTab(`tools`);if(n===`s`)return this.switchTab(`skills`);if(n===`e`)return this.switchTab(`extensions`)}getChrome(){let e=this.cursorEntry(),t=this.inspectedEntry(),n=this.entries.length?String(this.cursorIndex+1):`empty`,r=e?t?`C${n} I${(this.inspectedIndex??0)+1}`:`C${n} I-`:`empty`;return{title:`AGENTS`,accent:o,breadcrumb:`SPC › a / agents › l / available`,headerRight:`${this.entries.length} available · ${this.tab}`,footer:`↑↓/jk cursor · PgUp/PgDn page · enter inspect · tab resource · J/K scroll · esc close`,footerHints:u,footerRight:r}}renderBody(e,t){let n=v(e),r=this.renderList(n.leftContentWidth,t),i=this.renderDetail(n.rightContentWidth,t),a=` `.repeat(n.gutterWidth),o=this.theme.fg(`borderMuted`,`│`),s=[];for(let e=0;e<t;e++)s.push(`${d(r[e]??``,n.leftContentWidth)}${a}${o}${a}${d(i[e]??``,n.rightContentWidth)}`);return s.map(t=>d(t,e))}renderList(e,t){let n=[this.theme.bold(this.theme.fg(`accent`,`AGENTS ${this.entries.length}`))];if(this.entries.length===0)return p(n,`No enabled agents are available from this session cwd.`,e,`dim`,this.theme),this.listPageSize=1,n.slice(0,t);this.listPageSize=Math.max(1,t-1);let r=Math.max(0,Math.min(this.cursorIndex-this.listPageSize+1,Math.max(0,this.entries.length-this.listPageSize)));for(let[t,i]of this.entries.slice(r,r+this.listPageSize).entries()){let a=r+t===this.cursorIndex,o=a?this.theme.fg(`accent`,`›`):` `,s=i.agent.runtime??`pi`,c=f(`${o} ${a?this.theme.bold(i.agent.name):i.agent.name}`,`${i.agent.source} · ${s}`,e),l=a?`selectedBg`:`userMessageBg`;n.push(this.theme.bg(l,d(c,e)))}return n.slice(0,t)}renderDetail(e,t){let n=this.inspectedEntry();if(!n){this.detailTotal=0,this.detailPageSize=Math.max(1,t),this.detailOffset=0;let n=[this.theme.bold(this.theme.fg(`accent`,`AGENT RESOURCES`)),``];return p(n,`Press Enter to inspect the cursor agent.`,e,`text`,this.theme),n.push(``),p(n,c,e,`dim`,this.theme),n.slice(0,t)}let r=n.agent.runtime??`pi`,i=[f(this.theme.bold(this.theme.fg(`accent`,`INSPECTING ${n.agent.name}`)),`${n.agent.source} · ${r}`,e)];p(i,n.agent.description,e,`text`,this.theme),p(i,n.resources.notice||c,e,n.resources.configuredOnly?`warning`:`dim`,this.theme),i.push(_(this.tab,e,this.theme),``);let a=g(n.resources,this.tab,e,this.theme);return this.detailPageSize=Math.max(0,t-i.length),this.detailTotal=a.length,this.detailOffset=Math.min(this.detailOffset,Math.max(0,a.length-this.detailPageSize)),[...i,...a.slice(this.detailOffset,this.detailOffset+this.detailPageSize)].slice(0,t)}};async function b(e,t){await e.ui.custom((e,n,r,i)=>new y(e,n,t,i),a)}export{b as openAgentCatalog};
1
+ import{Key as e,matchesKey as t,truncateToWidth as n,visibleWidth as r,wrapTextWithAnsi as i}from"@earendil-works/pi-tui";import{DOOM_FULLSCREEN_UI_OPTIONS as a,DOOM_NAVIGATION_KEYS as o,DOOM_OVERLAY_ACCENT as s,DoomOverlay as c}from"@agimon-ai/doompi-ui/components/doomOverlay";import{fitStyledLine as l}from"@agimon-ai/doompi-ui/rendering";a.overlayOptions;const u=`Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.`,d=[`tools`,`skills`,`extensions`],f=`${o.list} cursor · ${o.detail} scroll · PgUp/PgDn page · enter inspect · tab resource · esc close`,p=[[o.list,`move`],[o.detail,`scroll`],[`enter`,`view`],[`tab`,`cycle`]];function m(e,t){return l(e,t,`…`)}function h(e,t,n){let i=Math.max(0,n),a=r(t);return a+2>=i?m(e,i):`${m(e,Math.max(1,i-a-2))} ${m(t,a)}`}function g(e,t,n,r,a){for(let o of i(t,Math.max(1,n)))e.push(a.fg(r,o))}function _(e,t,n,r,i){if(e.push(i.bold(i.fg(`accent`,t))),n.length===0)e.push(i.fg(`dim`,` none`));else for(let t of n)g(e,` • ${t.name}`,r,`text`,i),t.detail&&g(e,` ${t.detail}`,r,`dim`,i);e.push(``)}function v(e,t){return t===`skills`?e.skills:t===`extensions`?e.extensions:e.tools}function y(e,t,n,r){let i=[];e.error&&(i.push(r.bold(r.fg(`error`,`PROJECTION ERROR`))),g(i,e.error,n,`error`,r),i.push(``));let a=v(e,t);return _(i,`PROJECTED EFFECTIVE`,a.effective,n,r),_(i,`REMOVED BY PARENT`,a.removed,n,r),_(i,`UNRESOLVED AT PREVIEW`,a.unresolved,n,r),i}function b(e,t,r){return n(d.map(t=>{let n=t.toUpperCase();return t===e?r.inverse(r.bold(` ${n} `)):r.fg(`dim`,` ${n} `)}).join(` `),Math.max(0,t),`…`)}function x(e){let t=Math.max(2,e-r(`│`)),n=Math.max(1,Math.floor(t/3)),i=Math.max(1,t-n),a=+(n>=3&&i>=3);return{leftContentWidth:Math.max(1,n-a),rightContentWidth:Math.max(1,i-a),gutterWidth:a}}var S=class extends c{entries;cursorIndex=0;inspectedIndex;tab=`tools`;listPageSize=1;detailPageSize=1;detailOffset=0;detailTotal=0;constructor(e,t,n,r){super(e,t),this.done=r,this.entries=[...n].sort((e,t)=>e.agent.name.localeCompare(t.agent.name))}cursorEntry(){return this.entries[Math.min(this.cursorIndex,Math.max(0,this.entries.length-1))]}inspectedEntry(){if(this.inspectedIndex!==void 0)return this.entries[this.inspectedIndex]}moveCursor(e){if(this.entries.length===0)return;let t=Math.max(0,Math.min(this.entries.length-1,this.cursorIndex+e));t!==this.cursorIndex&&(this.cursorIndex=t,this.invalidate())}inspectCursor(){this.cursorEntry()&&(this.inspectedIndex=this.cursorIndex,this.detailOffset=0,this.invalidate())}switchTab(e){this.tab!==e&&(this.tab=e,this.detailOffset=0,this.invalidate())}cycleTab(){let e=d.indexOf(this.tab);this.switchTab(d[(e+1)%d.length]??`tools`)}scrollDetail(e){if(!this.inspectedEntry())return;let t=Math.max(0,this.detailTotal-this.detailPageSize),n=Math.max(0,Math.min(t,this.detailOffset+e));n!==this.detailOffset&&(this.detailOffset=n,this.invalidate())}handleInput(n){if(t(n,`escape`)||t(n,`ctrl+c`)){this.done(void 0);return}if(t(n,e.shift(`k`))){this.scrollDetail(-1);return}if(t(n,e.shift(`j`))){this.scrollDetail(1);return}if(t(n,`up`)||n===`k`){this.moveCursor(-1);return}if(t(n,`down`)||n===`j`){this.moveCursor(1);return}if(t(n,`pageUp`)){this.moveCursor(-this.listPageSize);return}if(t(n,`pageDown`)){this.moveCursor(this.listPageSize);return}if(t(n,`enter`)){this.inspectCursor();return}if(t(n,`tab`)){this.cycleTab();return}n===`t`?this.switchTab(`tools`):n===`s`?this.switchTab(`skills`):n===`e`&&this.switchTab(`extensions`)}getChrome(){let e=this.cursorEntry(),t=this.inspectedEntry(),n=this.entries.length?String(this.cursorIndex+1):`empty`,r=e?t?`C${n} I${(this.inspectedIndex??0)+1}`:`C${n} I-`:`empty`;return{title:`AGENTS`,accent:s,breadcrumb:`SPC › a / agents › l / available`,headerRight:`${this.entries.length} available · ${this.tab}`,footer:f,footerHints:p,footerRight:r}}renderBody(e,t){let n=x(e),r=this.renderList(n.leftContentWidth,t),i=this.renderDetail(n.rightContentWidth,t),a=` `.repeat(n.gutterWidth),o=this.theme.fg(`borderMuted`,`│`),s=[];for(let e=0;e<t;e++)s.push(`${m(r[e]??``,n.leftContentWidth)}${a}${o}${a}${m(i[e]??``,n.rightContentWidth)}`);return s.map(t=>m(t,e))}renderList(e,t){let n=[this.theme.bold(this.theme.fg(`accent`,`AGENTS ${this.entries.length}`))];if(this.entries.length===0)return g(n,`No enabled agents are available from this session cwd.`,e,`dim`,this.theme),this.listPageSize=1,n.slice(0,t);this.listPageSize=Math.max(1,t-1);let r=Math.max(0,Math.min(this.cursorIndex-this.listPageSize+1,Math.max(0,this.entries.length-this.listPageSize)));for(let[t,i]of this.entries.slice(r,r+this.listPageSize).entries()){let a=r+t===this.cursorIndex,o=a?this.theme.fg(`accent`,`›`):` `,s=i.agent.runtime??`pi`,c=h(`${o} ${a?this.theme.bold(i.agent.name):i.agent.name}`,`${i.agent.source} · ${s}`,e),l=a?`selectedBg`:`userMessageBg`;n.push(this.theme.bg(l,m(c,e)))}return n.slice(0,t)}renderDetail(e,t){let n=this.inspectedEntry();if(!n){this.detailTotal=0,this.detailPageSize=Math.max(1,t),this.detailOffset=0;let n=[this.theme.bold(this.theme.fg(`accent`,`AGENT RESOURCES`)),``];return g(n,`Press Enter to inspect the cursor agent.`,e,`text`,this.theme),n.push(``),g(n,u,e,`dim`,this.theme),n.slice(0,t)}let r=n.agent.runtime??`pi`,i=[h(this.theme.bold(this.theme.fg(`accent`,`INSPECTING ${n.agent.name}`)),`${n.agent.source} · ${r}`,e)];g(i,n.agent.description,e,`text`,this.theme),g(i,n.resources.notice||u,e,n.resources.configuredOnly?`warning`:`dim`,this.theme),i.push(b(this.tab,e,this.theme),``);let a=y(n.resources,this.tab,e,this.theme);return this.detailPageSize=Math.max(0,t-i.length),this.detailTotal=a.length,this.detailOffset=Math.min(this.detailOffset,Math.max(0,a.length-this.detailPageSize)),[...i,...a.slice(this.detailOffset,this.detailOffset+this.detailPageSize)].slice(0,t)}};async function C(e,t){await e.ui.custom((e,n,r,i)=>new S(e,n,t,i),a)}export{C as openAgentCatalog};
2
2
  //# sourceMappingURL=agentCatalog.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"agentCatalog.mjs","names":[],"sources":["../../src/tui/agentCatalog.ts"],"sourcesContent":["import type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/components/doomOverlay';\nimport { Key, matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi } from '@earendil-works/pi-tui';\n\nimport type { AgentConfig } from '../agents/types.ts';\nimport type {\n AgentCatalogEntry,\n AgentResourceProjection,\n ProjectedResource,\n ResourceTabProjection,\n} from './agentResourceProjection.ts';\n\nexport const AGENT_CATALOG_OVERLAY_OPTIONS = DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;\nexport type AgentResourceTab = 'tools' | 'skills' | 'extensions';\n\ntype ThemeBg = Parameters<Theme['bg']>[0];\ntype ThemeColor = Parameters<Theme['fg']>[0];\n\ninterface SplitLayout {\n leftContentWidth: number;\n rightContentWidth: number;\n gutterWidth: number;\n}\n\nconst TITLE = 'AGENTS';\nconst BREADCRUMB = 'SPC › a / agents › l / available';\nconst SELECTION_MARKER = '›';\nconst ELLIPSIS = '…';\nconst DEFAULT_PAGE_SIZE = 1;\nconst PI_RUNTIME = 'pi';\nconst DIVIDER = '│';\nconst PROJECTED_EFFECTIVE = 'PROJECTED EFFECTIVE';\nconst REMOVED_BY_PARENT = 'REMOVED BY PARENT';\nconst UNRESOLVED_AT_PREVIEW = 'UNRESOLVED AT PREVIEW';\nconst PROJECTION_ERROR = 'PROJECTION ERROR';\nconst GLOBAL_PREVIEW_NOTICE =\n 'Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.';\nconst TAB_ORDER: readonly AgentResourceTab[] = ['tools', 'skills', 'extensions'];\nconst FOOTER = '↑↓/jk cursor · PgUp/PgDn page · enter inspect · tab resource · J/K scroll · esc close';\nconst FOOTER_HINTS: readonly (readonly [string, string])[] = [\n ['↑↓/jk', 'move'],\n ['enter', 'view'],\n ['tab', 'cycle'],\n ['J/K', 'scroll'],\n];\n\nfunction fit(text: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const clipped = truncateToWidth(text, safeWidth, ELLIPSIS);\n return clipped + ' '.repeat(Math.max(0, safeWidth - visibleWidth(clipped)));\n}\n\nfunction rightAligned(left: string, right: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const rightWidth = visibleWidth(right);\n if (rightWidth + 2 >= safeWidth) return fit(left, safeWidth);\n const leftWidth = Math.max(1, safeWidth - rightWidth - 2);\n return `${fit(left, leftWidth)} ${fit(right, rightWidth)}`;\n}\n\nfunction plural(count: number, singular: string): string {\n return `${count} ${singular}${count === 1 ? '' : 's'}`;\n}\n\nexport function agentResourceSummary(agent: AgentConfig): string {\n const mcpTools = plural(agent.mcpDirectTools?.length ?? 0, 'MCP tool');\n const skills = plural(agent.skills?.length ?? 0, 'skill');\n const extensions = plural((agent.extensions?.length ?? 0) + (agent.subagentOnlyExtensions?.length ?? 0), 'extension');\n const configured = `${mcpTools} · ${skills} · ${extensions}`;\n return agent.tools === undefined\n ? `tools default · configured: ${configured}`\n : `configured: ${plural(agent.tools.length, 'tool')} · ${configured}`;\n}\n\nfunction appendWrapped(lines: string[], text: string, width: number, colour: ThemeColor, theme: Theme): void {\n for (const line of wrapTextWithAnsi(text, Math.max(1, width))) lines.push(theme.fg(colour, line));\n}\n\nfunction appendResources(\n lines: string[],\n heading: string,\n items: readonly ProjectedResource[],\n width: number,\n theme: Theme,\n): void {\n lines.push(theme.bold(theme.fg('accent', heading)));\n if (items.length === 0) {\n lines.push(theme.fg('dim', ' none'));\n } else {\n for (const item of items) {\n appendWrapped(lines, ` • ${item.name}`, width, 'text', theme);\n if (item.detail) appendWrapped(lines, ` ${item.detail}`, width, 'dim', theme);\n }\n }\n lines.push('');\n}\n\nfunction tabProjection(projection: AgentResourceProjection, tab: AgentResourceTab): ResourceTabProjection {\n if (tab === 'skills') return projection.skills;\n if (tab === 'extensions') return projection.extensions;\n return projection.tools;\n}\n\nfunction resourceLines(\n projection: AgentResourceProjection,\n tab: AgentResourceTab,\n width: number,\n theme: Theme,\n): string[] {\n const lines: string[] = [];\n if (projection.error) {\n lines.push(theme.bold(theme.fg('error', PROJECTION_ERROR)));\n appendWrapped(lines, projection.error, width, 'error', theme);\n lines.push('');\n }\n const resources = tabProjection(projection, tab);\n appendResources(lines, PROJECTED_EFFECTIVE, resources.effective, width, theme);\n appendResources(lines, REMOVED_BY_PARENT, resources.removed, width, theme);\n appendResources(lines, UNRESOLVED_AT_PREVIEW, resources.unresolved, width, theme);\n return lines;\n}\n\nfunction tabStrip(tab: AgentResourceTab, width: number, theme: Theme): string {\n const labels = TAB_ORDER.map((candidate) => {\n const label = candidate.toUpperCase();\n return candidate === tab ? theme.inverse(theme.bold(` ${label} `)) : theme.fg('dim', ` ${label} `);\n }).join(' ');\n return truncateToWidth(labels, Math.max(0, width), ELLIPSIS);\n}\n\nfunction splitLayout(width: number): SplitLayout {\n const paneBudget = Math.max(2, width - visibleWidth(DIVIDER));\n const leftPaneWidth = Math.max(1, Math.floor(paneBudget / 3));\n const rightPaneWidth = Math.max(1, paneBudget - leftPaneWidth);\n const gutterWidth = leftPaneWidth >= 3 && rightPaneWidth >= 3 ? 1 : 0;\n return {\n leftContentWidth: Math.max(1, leftPaneWidth - gutterWidth),\n rightContentWidth: Math.max(1, rightPaneWidth - gutterWidth),\n gutterWidth,\n };\n}\n\nexport class AgentCatalogComponent extends DoomOverlay {\n private readonly entries: AgentCatalogEntry[];\n private cursorIndex = 0;\n private inspectedIndex: number | undefined;\n private tab: AgentResourceTab = 'tools';\n private listPageSize = DEFAULT_PAGE_SIZE;\n private detailPageSize = DEFAULT_PAGE_SIZE;\n private detailOffset = 0;\n private detailTotal = 0;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n entries: readonly AgentCatalogEntry[],\n private readonly done: (result: undefined) => void,\n ) {\n super(tui, theme);\n this.entries = [...entries].sort((left, right) => left.agent.name.localeCompare(right.agent.name));\n }\n\n private cursorEntry(): AgentCatalogEntry | undefined {\n return this.entries[Math.min(this.cursorIndex, Math.max(0, this.entries.length - 1))];\n }\n\n private inspectedEntry(): AgentCatalogEntry | undefined {\n if (this.inspectedIndex === undefined) return undefined;\n return this.entries[this.inspectedIndex];\n }\n\n private moveCursor(delta: number): void {\n if (this.entries.length === 0) return;\n const next = Math.max(0, Math.min(this.entries.length - 1, this.cursorIndex + delta));\n if (next === this.cursorIndex) return;\n this.cursorIndex = next;\n this.invalidate();\n }\n\n private inspectCursor(): void {\n if (!this.cursorEntry()) return;\n this.inspectedIndex = this.cursorIndex;\n this.detailOffset = 0;\n this.invalidate();\n }\n\n private switchTab(tab: AgentResourceTab): void {\n if (this.tab === tab) return;\n this.tab = tab;\n this.detailOffset = 0;\n this.invalidate();\n }\n\n private cycleTab(): void {\n const current = TAB_ORDER.indexOf(this.tab);\n this.switchTab(TAB_ORDER[(current + 1) % TAB_ORDER.length] ?? 'tools');\n }\n\n private scrollDetail(delta: number): void {\n if (!this.inspectedEntry()) return;\n const maximum = Math.max(0, this.detailTotal - this.detailPageSize);\n const next = Math.max(0, Math.min(maximum, this.detailOffset + delta));\n if (next === this.detailOffset) return;\n this.detailOffset = next;\n this.invalidate();\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.done(undefined);\n return;\n }\n if (matchesKey(data, Key.shift('k'))) return this.scrollDetail(-1);\n if (matchesKey(data, Key.shift('j'))) return this.scrollDetail(1);\n if (matchesKey(data, 'up') || data === 'k') return this.moveCursor(-1);\n if (matchesKey(data, 'down') || data === 'j') return this.moveCursor(1);\n if (matchesKey(data, 'pageUp')) return this.moveCursor(-this.listPageSize);\n if (matchesKey(data, 'pageDown')) return this.moveCursor(this.listPageSize);\n if (matchesKey(data, 'enter')) return this.inspectCursor();\n if (matchesKey(data, 'tab')) return this.cycleTab();\n if (data === 't') return this.switchTab('tools');\n if (data === 's') return this.switchTab('skills');\n if (data === 'e') return this.switchTab('extensions');\n }\n\n protected getChrome(): DoomOverlayChrome {\n const cursor = this.cursorEntry();\n const inspected = this.inspectedEntry();\n const cursorPosition = this.entries.length ? String(this.cursorIndex + 1) : 'empty';\n const footerRight = !cursor\n ? 'empty'\n : inspected\n ? `C${cursorPosition} I${(this.inspectedIndex ?? 0) + 1}`\n : `C${cursorPosition} I-`;\n return {\n title: TITLE,\n accent: DOOM_OVERLAY_ACCENT,\n breadcrumb: BREADCRUMB,\n headerRight: `${this.entries.length} available · ${this.tab}`,\n footer: FOOTER,\n footerHints: FOOTER_HINTS,\n footerRight,\n };\n }\n\n protected renderBody(width: number, height: number): string[] {\n const layout = splitLayout(width);\n const left = this.renderList(layout.leftContentWidth, height);\n const right = this.renderDetail(layout.rightContentWidth, height);\n const gutter = ' '.repeat(layout.gutterWidth);\n const divider = this.theme.fg('borderMuted', DIVIDER);\n const lines: string[] = [];\n for (let index = 0; index < height; index++) {\n lines.push(\n `${fit(left[index] ?? '', layout.leftContentWidth)}${gutter}${divider}${gutter}${fit(\n right[index] ?? '',\n layout.rightContentWidth,\n )}`,\n );\n }\n return lines.map((line) => fit(line, width));\n }\n\n private renderList(width: number, height: number): string[] {\n const lines = [this.theme.bold(this.theme.fg('accent', `AGENTS ${this.entries.length}`))];\n if (this.entries.length === 0) {\n appendWrapped(lines, 'No enabled agents are available from this session cwd.', width, 'dim', this.theme);\n this.listPageSize = DEFAULT_PAGE_SIZE;\n return lines.slice(0, height);\n }\n\n this.listPageSize = Math.max(DEFAULT_PAGE_SIZE, height - 1);\n const start = Math.max(\n 0,\n Math.min(this.cursorIndex - this.listPageSize + 1, Math.max(0, this.entries.length - this.listPageSize)),\n );\n for (const [offset, entry] of this.entries.slice(start, start + this.listPageSize).entries()) {\n const index = start + offset;\n const current = index === this.cursorIndex;\n const marker = current ? this.theme.fg('accent', SELECTION_MARKER) : ' ';\n const runtime = entry.agent.runtime ?? PI_RUNTIME;\n const name = current ? this.theme.bold(entry.agent.name) : entry.agent.name;\n const row = rightAligned(`${marker} ${name}`, `${entry.agent.source} · ${runtime}`, width);\n const background: ThemeBg = current ? 'selectedBg' : 'userMessageBg';\n lines.push(this.theme.bg(background, fit(row, width)));\n }\n return lines.slice(0, height);\n }\n\n private renderDetail(width: number, height: number): string[] {\n const entry = this.inspectedEntry();\n if (!entry) {\n this.detailTotal = 0;\n this.detailPageSize = Math.max(DEFAULT_PAGE_SIZE, height);\n this.detailOffset = 0;\n const lines = [this.theme.bold(this.theme.fg('accent', 'AGENT RESOURCES')), ''];\n appendWrapped(lines, 'Press Enter to inspect the cursor agent.', width, 'text', this.theme);\n lines.push('');\n appendWrapped(lines, GLOBAL_PREVIEW_NOTICE, width, 'dim', this.theme);\n return lines.slice(0, height);\n }\n\n const runtime = entry.agent.runtime ?? PI_RUNTIME;\n const header = [\n rightAligned(\n this.theme.bold(this.theme.fg('accent', `INSPECTING ${entry.agent.name}`)),\n `${entry.agent.source} · ${runtime}`,\n width,\n ),\n ];\n appendWrapped(header, entry.agent.description, width, 'text', this.theme);\n appendWrapped(\n header,\n entry.resources.notice || GLOBAL_PREVIEW_NOTICE,\n width,\n entry.resources.configuredOnly ? 'warning' : 'dim',\n this.theme,\n );\n header.push(tabStrip(this.tab, width, this.theme), '');\n\n const resources = resourceLines(entry.resources, this.tab, width, this.theme);\n this.detailPageSize = Math.max(0, height - header.length);\n this.detailTotal = resources.length;\n this.detailOffset = Math.min(this.detailOffset, Math.max(0, resources.length - this.detailPageSize));\n return [...header, ...resources.slice(this.detailOffset, this.detailOffset + this.detailPageSize)].slice(0, height);\n }\n}\n\nexport async function openAgentCatalog(ctx: ExtensionContext, entries: readonly AgentCatalogEntry[]): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new AgentCatalogComponent(tui, theme, entries, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agentCatalog.mjs","names":[],"sources":["../../src/tui/agentCatalog.ts"],"sourcesContent":["import {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_NAVIGATION_KEYS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/components/doomOverlay';\nimport { fitStyledLine } from '@agimon-ai/doompi-ui/rendering';\nimport type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport { Key, matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi } from '@earendil-works/pi-tui';\n\nimport type { AgentConfig } from '../services/agents/types.ts';\nimport type {\n AgentCatalogEntry,\n AgentResourceProjection,\n ProjectedResource,\n ResourceTabProjection,\n} from './agentResourceProjection.ts';\n\nexport const AGENT_CATALOG_OVERLAY_OPTIONS = DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;\nexport type AgentResourceTab = 'tools' | 'skills' | 'extensions';\n\ntype ThemeBg = Parameters<Theme['bg']>[0];\ntype ThemeColor = Parameters<Theme['fg']>[0];\n\ninterface SplitLayout {\n leftContentWidth: number;\n rightContentWidth: number;\n gutterWidth: number;\n}\n\nconst TITLE = 'AGENTS';\nconst BREADCRUMB = 'SPC › a / agents › l / available';\nconst SELECTION_MARKER = '›';\nconst ELLIPSIS = '…';\nconst DEFAULT_PAGE_SIZE = 1;\nconst PI_RUNTIME = 'pi';\nconst DIVIDER = '│';\nconst PROJECTED_EFFECTIVE = 'PROJECTED EFFECTIVE';\nconst REMOVED_BY_PARENT = 'REMOVED BY PARENT';\nconst UNRESOLVED_AT_PREVIEW = 'UNRESOLVED AT PREVIEW';\nconst PROJECTION_ERROR = 'PROJECTION ERROR';\nconst GLOBAL_PREVIEW_NOTICE =\n 'Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.';\nconst TAB_ORDER: readonly AgentResourceTab[] = ['tools', 'skills', 'extensions'];\nconst FOOTER = `${DOOM_NAVIGATION_KEYS.list} cursor · ${DOOM_NAVIGATION_KEYS.detail} scroll · PgUp/PgDn page · enter inspect · tab resource · esc close`;\nconst FOOTER_HINTS: readonly (readonly [string, string])[] = [\n [DOOM_NAVIGATION_KEYS.list, 'move'],\n [DOOM_NAVIGATION_KEYS.detail, 'scroll'],\n ['enter', 'view'],\n ['tab', 'cycle'],\n];\n\nfunction fitRow(text: string, width: number): string {\n return fitStyledLine(text, width, ELLIPSIS);\n}\n\nfunction rightAligned(left: string, right: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const rightWidth = visibleWidth(right);\n if (rightWidth + 2 >= safeWidth) return fitRow(left, safeWidth);\n const leftWidth = Math.max(1, safeWidth - rightWidth - 2);\n return `${fitRow(left, leftWidth)} ${fitRow(right, rightWidth)}`;\n}\n\nfunction plural(count: number, singular: string): string {\n return `${count} ${singular}${count === 1 ? '' : 's'}`;\n}\n\nexport function agentResourceSummary(agent: AgentConfig): string {\n const mcpTools = plural(agent.mcpDirectTools?.length ?? 0, 'MCP tool');\n const skills = plural(agent.skills?.length ?? 0, 'skill');\n const extensions = plural((agent.extensions?.length ?? 0) + (agent.subagentOnlyExtensions?.length ?? 0), 'extension');\n const configured = `${mcpTools} · ${skills} · ${extensions}`;\n return agent.tools === undefined\n ? `tools default · configured: ${configured}`\n : `configured: ${plural(agent.tools.length, 'tool')} · ${configured}`;\n}\n\nfunction appendWrapped(lines: string[], text: string, width: number, colour: ThemeColor, theme: Theme): void {\n for (const line of wrapTextWithAnsi(text, Math.max(1, width))) lines.push(theme.fg(colour, line));\n}\n\nfunction appendResources(\n lines: string[],\n heading: string,\n items: readonly ProjectedResource[],\n width: number,\n theme: Theme,\n): void {\n lines.push(theme.bold(theme.fg('accent', heading)));\n if (items.length === 0) {\n lines.push(theme.fg('dim', ' none'));\n } else {\n for (const item of items) {\n appendWrapped(lines, ` • ${item.name}`, width, 'text', theme);\n if (item.detail) appendWrapped(lines, ` ${item.detail}`, width, 'dim', theme);\n }\n }\n lines.push('');\n}\n\nfunction tabProjection(projection: AgentResourceProjection, tab: AgentResourceTab): ResourceTabProjection {\n if (tab === 'skills') return projection.skills;\n if (tab === 'extensions') return projection.extensions;\n return projection.tools;\n}\n\nfunction resourceLines(\n projection: AgentResourceProjection,\n tab: AgentResourceTab,\n width: number,\n theme: Theme,\n): string[] {\n const lines: string[] = [];\n if (projection.error) {\n lines.push(theme.bold(theme.fg('error', PROJECTION_ERROR)));\n appendWrapped(lines, projection.error, width, 'error', theme);\n lines.push('');\n }\n const resources = tabProjection(projection, tab);\n appendResources(lines, PROJECTED_EFFECTIVE, resources.effective, width, theme);\n appendResources(lines, REMOVED_BY_PARENT, resources.removed, width, theme);\n appendResources(lines, UNRESOLVED_AT_PREVIEW, resources.unresolved, width, theme);\n return lines;\n}\n\nfunction tabStrip(tab: AgentResourceTab, width: number, theme: Theme): string {\n const labels = TAB_ORDER.map((candidate) => {\n const label = candidate.toUpperCase();\n return candidate === tab ? theme.inverse(theme.bold(` ${label} `)) : theme.fg('dim', ` ${label} `);\n }).join(' ');\n return truncateToWidth(labels, Math.max(0, width), ELLIPSIS);\n}\n\nfunction splitLayout(width: number): SplitLayout {\n const paneBudget = Math.max(2, width - visibleWidth(DIVIDER));\n const leftPaneWidth = Math.max(1, Math.floor(paneBudget / 3));\n const rightPaneWidth = Math.max(1, paneBudget - leftPaneWidth);\n const gutterWidth = leftPaneWidth >= 3 && rightPaneWidth >= 3 ? 1 : 0;\n return {\n leftContentWidth: Math.max(1, leftPaneWidth - gutterWidth),\n rightContentWidth: Math.max(1, rightPaneWidth - gutterWidth),\n gutterWidth,\n };\n}\n\nexport class AgentCatalogComponent extends DoomOverlay {\n private readonly entries: AgentCatalogEntry[];\n private cursorIndex = 0;\n private inspectedIndex: number | undefined;\n private tab: AgentResourceTab = 'tools';\n private listPageSize = DEFAULT_PAGE_SIZE;\n private detailPageSize = DEFAULT_PAGE_SIZE;\n private detailOffset = 0;\n private detailTotal = 0;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n entries: readonly AgentCatalogEntry[],\n private readonly done: (result: undefined) => void,\n ) {\n super(tui, theme);\n this.entries = [...entries].sort((left, right) => left.agent.name.localeCompare(right.agent.name));\n }\n\n private cursorEntry(): AgentCatalogEntry | undefined {\n return this.entries[Math.min(this.cursorIndex, Math.max(0, this.entries.length - 1))];\n }\n\n private inspectedEntry(): AgentCatalogEntry | undefined {\n if (this.inspectedIndex === undefined) return undefined;\n return this.entries[this.inspectedIndex];\n }\n\n private moveCursor(delta: number): void {\n if (this.entries.length === 0) return;\n const next = Math.max(0, Math.min(this.entries.length - 1, this.cursorIndex + delta));\n if (next === this.cursorIndex) return;\n this.cursorIndex = next;\n this.invalidate();\n }\n\n private inspectCursor(): void {\n if (!this.cursorEntry()) return;\n this.inspectedIndex = this.cursorIndex;\n this.detailOffset = 0;\n this.invalidate();\n }\n\n private switchTab(tab: AgentResourceTab): void {\n if (this.tab === tab) return;\n this.tab = tab;\n this.detailOffset = 0;\n this.invalidate();\n }\n\n private cycleTab(): void {\n const current = TAB_ORDER.indexOf(this.tab);\n this.switchTab(TAB_ORDER[(current + 1) % TAB_ORDER.length] ?? 'tools');\n }\n\n private scrollDetail(delta: number): void {\n if (!this.inspectedEntry()) return;\n const maximum = Math.max(0, this.detailTotal - this.detailPageSize);\n const next = Math.max(0, Math.min(maximum, this.detailOffset + delta));\n if (next === this.detailOffset) return;\n this.detailOffset = next;\n this.invalidate();\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.done(undefined);\n return;\n }\n if (matchesKey(data, Key.shift('k'))) {\n this.scrollDetail(-1);\n return;\n }\n if (matchesKey(data, Key.shift('j'))) {\n this.scrollDetail(1);\n return;\n }\n if (matchesKey(data, 'up') || data === 'k') {\n this.moveCursor(-1);\n return;\n }\n if (matchesKey(data, 'down') || data === 'j') {\n this.moveCursor(1);\n return;\n }\n if (matchesKey(data, 'pageUp')) {\n this.moveCursor(-this.listPageSize);\n return;\n }\n if (matchesKey(data, 'pageDown')) {\n this.moveCursor(this.listPageSize);\n return;\n }\n if (matchesKey(data, 'enter')) {\n this.inspectCursor();\n return;\n }\n if (matchesKey(data, 'tab')) {\n this.cycleTab();\n return;\n }\n if (data === 't') this.switchTab('tools');\n else if (data === 's') this.switchTab('skills');\n else if (data === 'e') this.switchTab('extensions');\n }\n\n protected getChrome(): DoomOverlayChrome {\n const cursor = this.cursorEntry();\n const inspected = this.inspectedEntry();\n const cursorPosition = this.entries.length ? String(this.cursorIndex + 1) : 'empty';\n const footerRight = !cursor\n ? 'empty'\n : inspected\n ? `C${cursorPosition} I${(this.inspectedIndex ?? 0) + 1}`\n : `C${cursorPosition} I-`;\n return {\n title: TITLE,\n accent: DOOM_OVERLAY_ACCENT,\n breadcrumb: BREADCRUMB,\n headerRight: `${this.entries.length} available · ${this.tab}`,\n footer: FOOTER,\n footerHints: FOOTER_HINTS,\n footerRight,\n };\n }\n\n protected renderBody(width: number, height: number): string[] {\n const layout = splitLayout(width);\n const left = this.renderList(layout.leftContentWidth, height);\n const right = this.renderDetail(layout.rightContentWidth, height);\n const gutter = ' '.repeat(layout.gutterWidth);\n const divider = this.theme.fg('borderMuted', DIVIDER);\n const lines: string[] = [];\n for (let index = 0; index < height; index++) {\n lines.push(\n `${fitRow(left[index] ?? '', layout.leftContentWidth)}${gutter}${divider}${gutter}${fitRow(\n right[index] ?? '',\n layout.rightContentWidth,\n )}`,\n );\n }\n return lines.map((line) => fitRow(line, width));\n }\n\n private renderList(width: number, height: number): string[] {\n const lines = [this.theme.bold(this.theme.fg('accent', `AGENTS ${this.entries.length}`))];\n if (this.entries.length === 0) {\n appendWrapped(lines, 'No enabled agents are available from this session cwd.', width, 'dim', this.theme);\n this.listPageSize = DEFAULT_PAGE_SIZE;\n return lines.slice(0, height);\n }\n\n this.listPageSize = Math.max(DEFAULT_PAGE_SIZE, height - 1);\n const start = Math.max(\n 0,\n Math.min(this.cursorIndex - this.listPageSize + 1, Math.max(0, this.entries.length - this.listPageSize)),\n );\n for (const [offset, entry] of this.entries.slice(start, start + this.listPageSize).entries()) {\n const index = start + offset;\n const current = index === this.cursorIndex;\n const marker = current ? this.theme.fg('accent', SELECTION_MARKER) : ' ';\n const runtime = entry.agent.runtime ?? PI_RUNTIME;\n const name = current ? this.theme.bold(entry.agent.name) : entry.agent.name;\n const row = rightAligned(`${marker} ${name}`, `${entry.agent.source} · ${runtime}`, width);\n const background: ThemeBg = current ? 'selectedBg' : 'userMessageBg';\n lines.push(this.theme.bg(background, fitRow(row, width)));\n }\n return lines.slice(0, height);\n }\n\n private renderDetail(width: number, height: number): string[] {\n const entry = this.inspectedEntry();\n if (!entry) {\n this.detailTotal = 0;\n this.detailPageSize = Math.max(DEFAULT_PAGE_SIZE, height);\n this.detailOffset = 0;\n const lines = [this.theme.bold(this.theme.fg('accent', 'AGENT RESOURCES')), ''];\n appendWrapped(lines, 'Press Enter to inspect the cursor agent.', width, 'text', this.theme);\n lines.push('');\n appendWrapped(lines, GLOBAL_PREVIEW_NOTICE, width, 'dim', this.theme);\n return lines.slice(0, height);\n }\n\n const runtime = entry.agent.runtime ?? PI_RUNTIME;\n const header = [\n rightAligned(\n this.theme.bold(this.theme.fg('accent', `INSPECTING ${entry.agent.name}`)),\n `${entry.agent.source} · ${runtime}`,\n width,\n ),\n ];\n appendWrapped(header, entry.agent.description, width, 'text', this.theme);\n appendWrapped(\n header,\n entry.resources.notice || GLOBAL_PREVIEW_NOTICE,\n width,\n entry.resources.configuredOnly ? 'warning' : 'dim',\n this.theme,\n );\n header.push(tabStrip(this.tab, width, this.theme), '');\n\n const resources = resourceLines(entry.resources, this.tab, width, this.theme);\n this.detailPageSize = Math.max(0, height - header.length);\n this.detailTotal = resources.length;\n this.detailOffset = Math.min(this.detailOffset, Math.max(0, resources.length - this.detailPageSize));\n return [...header, ...resources.slice(this.detailOffset, this.detailOffset + this.detailPageSize)].slice(0, height);\n }\n}\n\nexport async function openAgentCatalog(ctx: ExtensionContext, entries: readonly AgentCatalogEntry[]): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new AgentCatalogComponent(tui, theme, entries, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- const e=require(`../agents/skills.cjs`),t=require(`../runs/shared/runtimeRegistry.cjs`),n=require(`../runs/shared/piArgs.cjs`),r=`Ambient Pi extensions`,i=`Ambient Pi skills`;function a(){return{effective:[],removed:[],unresolved:[]}}function o(e,t){return t?{name:e,detail:t}:{name:e}}function s(e){let t=new Set;return e.filter(e=>{let n=`${e.name}\0${e.detail??``}`;return t.has(n)?!1:(t.add(n),!0)})}function c(e){let t=e.capabilityCeiling?.sources??[];return t.length>0?`removed by capability ceiling from ${t.join(`, `)}`:`removed by capability ceiling`}function l(e,t,n){return t.excludedTools.includes(e)?n.exclusionSource?`excluded by active layer policy at ${n.exclusionSource}`:`excluded by active layer policy`:c(t)}function u(e,t){let n=new Set(t.requestedBuiltinTools);return(e.tools??[]).filter(e=>!n.has(e))}function d(e,t){return t.resolvedMcpSelections.some(t=>t.selector===e||t.selector.startsWith(`${e}/`))}function f(e,t){return e.tools===void 0?t.capabilityCeiling?.allowedTools?t.capabilityCeiling.allowedTools:t.excludedTools:t.requestedBuiltinTools}function p(e,t,n){let{toolPlan:r}=t,i=new Set(r.effectiveMcpTools),a=r.explicitToolAllowlist?r.effectiveToolAllowlist.map(t=>o(t,i.has(t)?`resolved MCP tool`:e.tools===void 0?`granted by parent capability ceiling`:`configured builtin tool`)):[],u=f(e,r).filter(e=>!r.declaredBuiltinTools.includes(e)).map(e=>o(e,l(e,r,n))),p=new Set(r.effectiveMcpTools),m=r.resolvedMcpSelections.filter(e=>!p.has(e.name)).map(e=>o(e.name,`${e.selector} · ${l(e.name,r,n)}`)),h=r.capabilityCeiling?.denyExtensions?(e.mcpDirectTools??[]).map(e=>o(e,`${c(r)} · MCP extensions denied`)):[],g=r.capabilityCeiling?.denyExtensions?[]:(e.mcpDirectTools??[]).filter(e=>!d(e,r)).map(e=>o(e,`MCP selector did not resolve from the current parent catalog`));return{effective:s(a),removed:s([...u,...m,...h]),unresolved:s([...r.explicitToolAllowlist?[]:[o(`Pi host-default tool set`,`resolved by Pi only after the child host loads resources`)],...g,o(`Request-specific internal tools`,`intercom and structured_output depend on the concrete spawn request`)])}}function m(t,n){let r=n.skills.resolveSkillsWithFallback(t.skills??[],n.cwd,n.cwd,t.skillPath,n.cwd),a=new Set(r.resolved.map(e=>e.name)),c=t.inheritSkills?n.skills.discoverAvailableSkills(n.cwd).filter(e=>!a.has(e.name)).map(e=>o(e.name,`ambient parent snapshot · ${e.source}`)):[];return{tab:{effective:s([...r.resolved.map(e=>o(e.name,`configured · ${e.source} · ${e.path}`)),...c]),removed:[],unresolved:s([...r.missing.map(e=>o(e,`configured skill was not found from the current session cwd`)),...t.inheritSkills?[o(i,`Pi rediscovers ambient skills when the child resource loader starts`)]:[]])},requireReadTool:e.buildSkillInjection(r.resolved).length>0}}function h(e,t){let n=new Set(t.toolPlan.runtimeExtensions),i=new Set(t.toolPlan.configuredExtensions),a=t.extensions.map(e=>o(e,n.has(e)?`internal runtime extension`:i.has(e)?`configured agent extension`:`inherited parent harness extension`)),l=t.toolPlan.capabilityCeiling?.denyExtensions?[...u(e,t.toolPlan),...e.extensions??[],...e.subagentOnlyExtensions??[]].map(e=>o(e,c(t.toolPlan))):[];return{effective:s(a),removed:s(l),unresolved:t.noAmbientExtensions?[]:[o(r,`Pi discovers additional ambient extensions only when the child loads`)]}}function g(e){let t=a();t.unresolved=s([...(e.tools??[]).map(e=>o(e,`configured for external runtime`)),...(e.mcpDirectTools??[]).map(e=>o(e,`configured MCP selector`)),...e.tools===void 0?[o(`Runtime-default tools`,`determined by the external runtime`)]:[]]);let n=a();n.unresolved=s([...(e.skills??[]).map(e=>o(e,`configured skill name`)),...e.inheritSkills?[o(i,`determined by the external runtime`)]:[]]);let c=a();return c.unresolved=s([...[...e.extensions??[],...e.subagentOnlyExtensions??[]].map(e=>o(e,`configured extension`)),...e.extensions===void 0?[o(r,`determined by the external runtime`)]:[]]),{tools:t,skills:n,extensions:c,notice:`Configured values only. Runtime '${e.runtime}' does not use the Pi launch projection.`,configuredOnly:!0}}function _(e){return{tools:a(),skills:a(),extensions:a(),notice:`Launch projection failed for this agent.`,configuredOnly:!1,error:e instanceof Error?e.message:String(e)}}function v(e,r){if(!t.isPiRuntime(e.runtime))return g(e);try{let t=m(e,r),i=n.resolvePiSdkResourcePlan({tools:e.tools,extensions:e.extensions,subagentOnlyExtensions:e.subagentOnlyExtensions,mcpDirectTools:e.mcpDirectTools,cwd:r.cwd,requireReadTool:t.requireReadTool,excludeTools:r.excludeTools?[...r.excludeTools]:void 0,capabilityCeiling:r.capabilityCeiling,inheritSkills:e.inheritSkills,environment:r.environment});return{tools:p(e,i,r),skills:t.tab,extensions:h(e,i),notice:`Launch projection from the current parent-policy and cwd snapshot. Child loading or request overrides may change qualified resources.`,configuredOnly:!1}}catch(e){return _(e)}}function y(e,t){return e.map(e=>({agent:e,resources:v(e,t)}))}exports.buildAgentCatalogEntries=y;
1
+ const e=require(`../services/agents/skills.cjs`),t=require(`../services/runs/shared/runtimeRegistry.cjs`),n=require(`../services/runs/shared/piArgs.cjs`),r=`Ambient Pi extensions`,i=`Ambient Pi skills`;function a(){return{effective:[],removed:[],unresolved:[]}}function o(e,t){return t?{name:e,detail:t}:{name:e}}function s(e){let t=new Set;return e.filter(e=>{let n=`${e.name}\0${e.detail??``}`;return t.has(n)?!1:(t.add(n),!0)})}function c(e){let t=e.capabilityCeiling?.sources??[];return t.length>0?`removed by capability ceiling from ${t.join(`, `)}`:`removed by capability ceiling`}function l(e,t,n){return t.excludedTools.includes(e)?n.exclusionSource?`excluded by Team package policy at ${n.exclusionSource}`:`excluded by Team package policy`:c(t)}function u(e,t){let n=new Set(t.requestedBuiltinTools);return(e.tools??[]).filter(e=>!n.has(e))}function d(e,t){return t.resolvedMcpSelections.some(t=>t.selector===e||t.selector.startsWith(`${e}/`))}function f(e,t){return e.tools===void 0?t.capabilityCeiling?.allowedTools?t.capabilityCeiling.allowedTools:t.excludedTools:t.requestedBuiltinTools}function p(e,t,n){let{toolPlan:r}=t,i=new Set(r.effectiveMcpTools),a=r.explicitToolAllowlist?r.effectiveToolAllowlist.map(t=>o(t,i.has(t)?`resolved MCP tool`:e.tools===void 0?`granted by parent capability ceiling`:`configured builtin tool`)):[],u=f(e,r).filter(e=>!r.declaredBuiltinTools.includes(e)).map(e=>o(e,l(e,r,n))),p=new Set(r.effectiveMcpTools),m=r.resolvedMcpSelections.filter(e=>!p.has(e.name)).map(e=>o(e.name,`${e.selector} · ${l(e.name,r,n)}`)),h=r.capabilityCeiling?.denyExtensions?(e.mcpDirectTools??[]).map(e=>o(e,`${c(r)} · MCP extensions denied`)):[],g=r.capabilityCeiling?.denyExtensions?[]:(e.mcpDirectTools??[]).filter(e=>!d(e,r)).map(e=>o(e,`MCP selector did not resolve from the current parent catalog`));return{effective:s(a),removed:s([...u,...m,...h]),unresolved:s([...r.explicitToolAllowlist?[]:[o(`Pi host-default tool set`,`resolved by Pi only after the child host loads resources`)],...g,o(`Request-specific internal tools`,`intercom and structured_output depend on the concrete spawn request`)])}}function m(t,n){let r=n.skills.resolveSkillsWithFallback(t.skills??[],n.cwd,n.cwd,t.skillPath,n.cwd),a=new Set(r.resolved.map(e=>e.name)),c=t.inheritSkills?n.skills.discoverAvailableSkills(n.cwd).filter(e=>!a.has(e.name)).map(e=>o(e.name,`ambient parent snapshot · ${e.source}`)):[];return{tab:{effective:s([...r.resolved.map(e=>o(e.name,`configured · ${e.source} · ${e.path}`)),...c]),removed:[],unresolved:s([...r.missing.map(e=>o(e,`configured skill was not found from the current session cwd`)),...t.inheritSkills?[o(i,`Pi rediscovers ambient skills when the child resource loader starts`)]:[]])},requireReadTool:e.buildSkillInjection(r.resolved).length>0}}function h(e,t){let n=new Set(t.toolPlan.runtimeExtensions),i=new Set(t.toolPlan.configuredExtensions),a=t.extensions.map(e=>o(e,n.has(e)?`internal runtime extension`:i.has(e)?`configured agent extension`:`inherited parent harness extension`)),l=t.toolPlan.capabilityCeiling?.denyExtensions?[...u(e,t.toolPlan),...e.extensions??[],...e.subagentOnlyExtensions??[]].map(e=>o(e,c(t.toolPlan))):[];return{effective:s(a),removed:s(l),unresolved:t.noAmbientExtensions?[]:[o(r,`Pi discovers additional ambient extensions only when the child loads`)]}}function g(e){let t=a();t.unresolved=s([...(e.tools??[]).map(e=>o(e,`configured for external runtime`)),...(e.mcpDirectTools??[]).map(e=>o(e,`configured MCP selector`)),...e.tools===void 0?[o(`Runtime-default tools`,`determined by the external runtime`)]:[]]);let n=a();n.unresolved=s([...(e.skills??[]).map(e=>o(e,`configured skill name`)),...e.inheritSkills?[o(i,`determined by the external runtime`)]:[]]);let c=a();return c.unresolved=s([...[...e.extensions??[],...e.subagentOnlyExtensions??[]].map(e=>o(e,`configured extension`)),...e.extensions===void 0?[o(r,`determined by the external runtime`)]:[]]),{tools:t,skills:n,extensions:c,notice:`Configured values only. Runtime '${e.runtime}' does not use the Pi launch projection.`,configuredOnly:!0}}function _(e){return{tools:a(),skills:a(),extensions:a(),notice:`Launch projection failed for this agent.`,configuredOnly:!1,error:e instanceof Error?e.message:String(e)}}function v(e,r){if(!t.isPiRuntime(e.runtime))return g(e);try{let t=m(e,r),i=n.resolvePiSdkResourcePlan({tools:e.tools,extensions:e.extensions,subagentOnlyExtensions:e.subagentOnlyExtensions,mcpDirectTools:e.mcpDirectTools,cwd:r.cwd,requireReadTool:t.requireReadTool,excludeTools:r.excludeTools?[...r.excludeTools]:void 0,capabilityCeiling:r.capabilityCeiling,inheritSkills:e.inheritSkills,environment:r.environment});return{tools:p(e,i,r),skills:t.tab,extensions:h(e,i),notice:`Launch projection from the current parent-policy and cwd snapshot. Child loading or request overrides may change qualified resources.`,configuredOnly:!1}}catch(e){return _(e)}}function y(e,t){return e.map(e=>({agent:e,resources:v(e,t)}))}exports.buildAgentCatalogEntries=y;
2
2
  //# sourceMappingURL=agentResourceProjection.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"agentResourceProjection.cjs","names":["buildSkillInjection","isPiRuntime","resolvePiSdkResourcePlan"],"sources":["../../src/tui/agentResourceProjection.ts"],"sourcesContent":["import { buildSkillInjection, type ISkillDiscoveryService } from '../agents/skills.ts';\nimport type { AgentConfig } from '../agents/types.ts';\nimport type { ResolvedSubagentCapabilityCeiling } from '../protocol/capabilityCeiling.ts';\nimport { resolvePiSdkResourcePlan, type PiLaunchToolPlan, type PiSdkResourcePlan } from '../runs/shared/piArgs.ts';\nimport { isPiRuntime } from '../runs/shared/runtimeRegistry.ts';\n\nconst CONDITIONAL_TOOLS = 'Request-specific internal tools';\nconst HOST_DEFAULT_TOOLS = 'Pi host-default tool set';\nconst AMBIENT_EXTENSIONS = 'Ambient Pi extensions';\nconst AMBIENT_SKILLS = 'Ambient Pi skills';\n\nexport interface ProjectedResource {\n name: string;\n detail?: string;\n}\n\nexport interface ResourceTabProjection {\n effective: readonly ProjectedResource[];\n removed: readonly ProjectedResource[];\n unresolved: readonly ProjectedResource[];\n}\n\nexport interface AgentResourceProjection {\n tools: ResourceTabProjection;\n skills: ResourceTabProjection;\n extensions: ResourceTabProjection;\n notice: string;\n configuredOnly: boolean;\n error?: string;\n}\n\nexport interface AgentCatalogEntry {\n agent: AgentConfig;\n resources: AgentResourceProjection;\n}\n\nexport interface AgentResourceProjectionContext {\n cwd: string;\n skills: Pick<ISkillDiscoveryService, 'resolveSkillsWithFallback' | 'discoverAvailableSkills'>;\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n excludeTools?: readonly string[];\n exclusionSource?: string;\n environment?: NodeJS.ProcessEnv;\n}\n\nfunction emptyTab(): ResourceTabProjection {\n return { effective: [], removed: [], unresolved: [] };\n}\n\nfunction resource(name: string, detail?: string): ProjectedResource {\n return detail ? { name, detail } : { name };\n}\n\nfunction unique(items: readonly ProjectedResource[]): ProjectedResource[] {\n const seen = new Set<string>();\n return items.filter((item) => {\n const key = `${item.name}\\0${item.detail ?? ''}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\nfunction ceilingReason(toolPlan: PiLaunchToolPlan): string {\n const sources = toolPlan.capabilityCeiling?.sources ?? [];\n return sources.length > 0\n ? `removed by capability ceiling from ${sources.join(', ')}`\n : 'removed by capability ceiling';\n}\n\nfunction toolRemovalReason(name: string, toolPlan: PiLaunchToolPlan, context: AgentResourceProjectionContext): string {\n if (toolPlan.excludedTools.includes(name)) {\n return context.exclusionSource\n ? `excluded by active layer policy at ${context.exclusionSource}`\n : 'excluded by active layer policy';\n }\n return ceilingReason(toolPlan);\n}\n\nfunction pathShapedToolEntries(agent: AgentConfig, toolPlan: PiLaunchToolPlan): string[] {\n const builtinTools = new Set(toolPlan.requestedBuiltinTools);\n return (agent.tools ?? []).filter((tool) => !builtinTools.has(tool));\n}\n\nfunction selectorResolved(selector: string, toolPlan: PiLaunchToolPlan): boolean {\n return toolPlan.resolvedMcpSelections.some(\n (selection) => selection.selector === selector || selection.selector.startsWith(`${selector}/`),\n );\n}\n\nfunction removedBuiltinCandidates(agent: AgentConfig, toolPlan: PiLaunchToolPlan): string[] {\n if (agent.tools !== undefined) return toolPlan.requestedBuiltinTools;\n if (toolPlan.capabilityCeiling?.allowedTools) return toolPlan.capabilityCeiling.allowedTools;\n return toolPlan.excludedTools;\n}\n\nfunction toolProjection(\n agent: AgentConfig,\n plan: PiSdkResourcePlan,\n context: AgentResourceProjectionContext,\n): ResourceTabProjection {\n const { toolPlan } = plan;\n const mcpNames = new Set(toolPlan.effectiveMcpTools);\n const effective = toolPlan.explicitToolAllowlist\n ? toolPlan.effectiveToolAllowlist.map((name) =>\n resource(\n name,\n mcpNames.has(name)\n ? 'resolved MCP tool'\n : agent.tools === undefined\n ? 'granted by parent capability ceiling'\n : 'configured builtin tool',\n ),\n )\n : [];\n const removedBuiltins = removedBuiltinCandidates(agent, toolPlan)\n .filter((name) => !toolPlan.declaredBuiltinTools.includes(name))\n .map((name) => resource(name, toolRemovalReason(name, toolPlan, context)));\n const effectiveMcpNames = new Set(toolPlan.effectiveMcpTools);\n const removedMcp = toolPlan.resolvedMcpSelections\n .filter((selection) => !effectiveMcpNames.has(selection.name))\n .map((selection) =>\n resource(selection.name, `${selection.selector} · ${toolRemovalReason(selection.name, toolPlan, context)}`),\n );\n const deniedMcpSelectors = toolPlan.capabilityCeiling?.denyExtensions\n ? (agent.mcpDirectTools ?? []).map((selector) =>\n resource(selector, `${ceilingReason(toolPlan)} · MCP extensions denied`),\n )\n : [];\n const unresolvedSelectors = toolPlan.capabilityCeiling?.denyExtensions\n ? []\n : (agent.mcpDirectTools ?? [])\n .filter((selector) => !selectorResolved(selector, toolPlan))\n .map((selector) => resource(selector, 'MCP selector did not resolve from the current parent catalog'));\n return {\n effective: unique(effective),\n removed: unique([...removedBuiltins, ...removedMcp, ...deniedMcpSelectors]),\n unresolved: unique([\n ...(toolPlan.explicitToolAllowlist\n ? []\n : [resource(HOST_DEFAULT_TOOLS, 'resolved by Pi only after the child host loads resources')]),\n ...unresolvedSelectors,\n resource(CONDITIONAL_TOOLS, 'intercom and structured_output depend on the concrete spawn request'),\n ]),\n };\n}\n\nfunction skillProjection(\n agent: AgentConfig,\n context: AgentResourceProjectionContext,\n): { tab: ResourceTabProjection; requireReadTool: boolean } {\n const resolution = context.skills.resolveSkillsWithFallback(\n agent.skills ?? [],\n context.cwd,\n context.cwd,\n agent.skillPath,\n context.cwd,\n );\n const explicitNames = new Set(resolution.resolved.map((skill) => skill.name));\n const ambient = agent.inheritSkills\n ? context.skills\n .discoverAvailableSkills(context.cwd)\n .filter((skill) => !explicitNames.has(skill.name))\n .map((skill) => resource(skill.name, `ambient parent snapshot · ${skill.source}`))\n : [];\n return {\n tab: {\n effective: unique([\n ...resolution.resolved.map((skill) => resource(skill.name, `configured · ${skill.source} · ${skill.path}`)),\n ...ambient,\n ]),\n removed: [],\n unresolved: unique([\n ...resolution.missing.map((name) =>\n resource(name, 'configured skill was not found from the current session cwd'),\n ),\n ...(agent.inheritSkills\n ? [resource(AMBIENT_SKILLS, 'Pi rediscovers ambient skills when the child resource loader starts')]\n : []),\n ]),\n },\n requireReadTool: buildSkillInjection(resolution.resolved).length > 0,\n };\n}\n\nfunction extensionProjection(agent: AgentConfig, plan: PiSdkResourcePlan): ResourceTabProjection {\n const runtimeExtensions = new Set(plan.toolPlan.runtimeExtensions);\n const configuredExtensions = new Set(plan.toolPlan.configuredExtensions);\n const effective = plan.extensions.map((name) =>\n resource(\n name,\n runtimeExtensions.has(name)\n ? 'internal runtime extension'\n : configuredExtensions.has(name)\n ? 'configured agent extension'\n : 'inherited parent harness extension',\n ),\n );\n const removed = plan.toolPlan.capabilityCeiling?.denyExtensions\n ? [\n ...pathShapedToolEntries(agent, plan.toolPlan),\n ...(agent.extensions ?? []),\n ...(agent.subagentOnlyExtensions ?? []),\n ].map((name) => resource(name, ceilingReason(plan.toolPlan)))\n : [];\n return {\n effective: unique(effective),\n removed: unique(removed),\n unresolved: plan.noAmbientExtensions\n ? []\n : [resource(AMBIENT_EXTENSIONS, 'Pi discovers additional ambient extensions only when the child loads')],\n };\n}\n\nfunction configuredOnlyProjection(agent: AgentConfig): AgentResourceProjection {\n const tools = emptyTab();\n tools.unresolved = unique([\n ...(agent.tools ?? []).map((name) => resource(name, 'configured for external runtime')),\n ...(agent.mcpDirectTools ?? []).map((name) => resource(name, 'configured MCP selector')),\n ...(agent.tools === undefined ? [resource('Runtime-default tools', 'determined by the external runtime')] : []),\n ]);\n const skills = emptyTab();\n skills.unresolved = unique([\n ...(agent.skills ?? []).map((name) => resource(name, 'configured skill name')),\n ...(agent.inheritSkills ? [resource(AMBIENT_SKILLS, 'determined by the external runtime')] : []),\n ]);\n const extensions = emptyTab();\n extensions.unresolved = unique([\n ...[...(agent.extensions ?? []), ...(agent.subagentOnlyExtensions ?? [])].map((name) =>\n resource(name, 'configured extension'),\n ),\n ...(agent.extensions === undefined ? [resource(AMBIENT_EXTENSIONS, 'determined by the external runtime')] : []),\n ]);\n return {\n tools,\n skills,\n extensions,\n notice: `Configured values only. Runtime '${agent.runtime}' does not use the Pi launch projection.`,\n configuredOnly: true,\n };\n}\n\nfunction failedProjection(error: unknown): AgentResourceProjection {\n return {\n tools: emptyTab(),\n skills: emptyTab(),\n extensions: emptyTab(),\n notice: 'Launch projection failed for this agent.',\n configuredOnly: false,\n error: error instanceof Error ? error.message : String(error),\n };\n}\n\nexport function projectAgentResources(\n agent: AgentConfig,\n context: AgentResourceProjectionContext,\n): AgentResourceProjection {\n if (!isPiRuntime(agent.runtime)) return configuredOnlyProjection(agent);\n try {\n const skills = skillProjection(agent, context);\n const plan = resolvePiSdkResourcePlan({\n tools: agent.tools,\n extensions: agent.extensions,\n subagentOnlyExtensions: agent.subagentOnlyExtensions,\n mcpDirectTools: agent.mcpDirectTools,\n cwd: context.cwd,\n requireReadTool: skills.requireReadTool,\n excludeTools: context.excludeTools ? [...context.excludeTools] : undefined,\n capabilityCeiling: context.capabilityCeiling,\n inheritSkills: agent.inheritSkills,\n environment: context.environment,\n });\n return {\n tools: toolProjection(agent, plan, context),\n skills: skills.tab,\n extensions: extensionProjection(agent, plan),\n notice:\n 'Launch projection from the current parent-policy and cwd snapshot. Child loading or request overrides may change qualified resources.',\n configuredOnly: false,\n };\n } catch (error) {\n return failedProjection(error);\n }\n}\n\nexport function buildAgentCatalogEntries(\n agents: readonly AgentConfig[],\n context: AgentResourceProjectionContext,\n): AgentCatalogEntry[] {\n return agents.map((agent) => ({ agent, resources: projectAgentResources(agent, context) }));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agentResourceProjection.cjs","names":["buildSkillInjection","isPiRuntime","resolvePiSdkResourcePlan"],"sources":["../../src/tui/agentResourceProjection.ts"],"sourcesContent":["import type { ResolvedSubagentCapabilityCeiling } from '../schemas/team/capabilityCeiling.ts';\nimport { buildSkillInjection, type ISkillDiscoveryService } from '../services/agents/skills.ts';\nimport type { AgentConfig } from '../services/agents/types.ts';\nimport {\n type PiLaunchToolPlan,\n type PiSdkResourcePlan,\n resolvePiSdkResourcePlan,\n} from '../services/runs/shared/piArgs.ts';\nimport { isPiRuntime } from '../services/runs/shared/runtimeRegistry.ts';\n\nconst CONDITIONAL_TOOLS = 'Request-specific internal tools';\nconst HOST_DEFAULT_TOOLS = 'Pi host-default tool set';\nconst AMBIENT_EXTENSIONS = 'Ambient Pi extensions';\nconst AMBIENT_SKILLS = 'Ambient Pi skills';\n\nexport interface ProjectedResource {\n name: string;\n detail?: string;\n}\n\nexport interface ResourceTabProjection {\n effective: readonly ProjectedResource[];\n removed: readonly ProjectedResource[];\n unresolved: readonly ProjectedResource[];\n}\n\nexport interface AgentResourceProjection {\n tools: ResourceTabProjection;\n skills: ResourceTabProjection;\n extensions: ResourceTabProjection;\n notice: string;\n configuredOnly: boolean;\n error?: string;\n}\n\nexport interface AgentCatalogEntry {\n agent: AgentConfig;\n resources: AgentResourceProjection;\n}\n\nexport interface AgentResourceProjectionContext {\n cwd: string;\n skills: Pick<ISkillDiscoveryService, 'resolveSkillsWithFallback' | 'discoverAvailableSkills'>;\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n excludeTools?: readonly string[];\n exclusionSource?: string;\n environment?: NodeJS.ProcessEnv;\n}\n\nfunction emptyTab(): ResourceTabProjection {\n return { effective: [], removed: [], unresolved: [] };\n}\n\nfunction resource(name: string, detail?: string): ProjectedResource {\n return detail ? { name, detail } : { name };\n}\n\nfunction unique(items: readonly ProjectedResource[]): ProjectedResource[] {\n const seen = new Set<string>();\n return items.filter((item) => {\n const key = `${item.name}\\0${item.detail ?? ''}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\nfunction ceilingReason(toolPlan: PiLaunchToolPlan): string {\n const sources = toolPlan.capabilityCeiling?.sources ?? [];\n return sources.length > 0\n ? `removed by capability ceiling from ${sources.join(', ')}`\n : 'removed by capability ceiling';\n}\n\nfunction toolRemovalReason(name: string, toolPlan: PiLaunchToolPlan, context: AgentResourceProjectionContext): string {\n if (toolPlan.excludedTools.includes(name)) {\n return context.exclusionSource\n ? `excluded by Team package policy at ${context.exclusionSource}`\n : 'excluded by Team package policy';\n }\n return ceilingReason(toolPlan);\n}\n\nfunction pathShapedToolEntries(agent: AgentConfig, toolPlan: PiLaunchToolPlan): string[] {\n const builtinTools = new Set(toolPlan.requestedBuiltinTools);\n return (agent.tools ?? []).filter((tool) => !builtinTools.has(tool));\n}\n\nfunction selectorResolved(selector: string, toolPlan: PiLaunchToolPlan): boolean {\n return toolPlan.resolvedMcpSelections.some(\n (selection) => selection.selector === selector || selection.selector.startsWith(`${selector}/`),\n );\n}\n\nfunction removedBuiltinCandidates(agent: AgentConfig, toolPlan: PiLaunchToolPlan): string[] {\n if (agent.tools !== undefined) return toolPlan.requestedBuiltinTools;\n if (toolPlan.capabilityCeiling?.allowedTools) return toolPlan.capabilityCeiling.allowedTools;\n return toolPlan.excludedTools;\n}\n\nfunction toolProjection(\n agent: AgentConfig,\n plan: PiSdkResourcePlan,\n context: AgentResourceProjectionContext,\n): ResourceTabProjection {\n const { toolPlan } = plan;\n const mcpNames = new Set(toolPlan.effectiveMcpTools);\n const effective = toolPlan.explicitToolAllowlist\n ? toolPlan.effectiveToolAllowlist.map((name) =>\n resource(\n name,\n mcpNames.has(name)\n ? 'resolved MCP tool'\n : agent.tools === undefined\n ? 'granted by parent capability ceiling'\n : 'configured builtin tool',\n ),\n )\n : [];\n const removedBuiltins = removedBuiltinCandidates(agent, toolPlan)\n .filter((name) => !toolPlan.declaredBuiltinTools.includes(name))\n .map((name) => resource(name, toolRemovalReason(name, toolPlan, context)));\n const effectiveMcpNames = new Set(toolPlan.effectiveMcpTools);\n const removedMcp = toolPlan.resolvedMcpSelections\n .filter((selection) => !effectiveMcpNames.has(selection.name))\n .map((selection) =>\n resource(selection.name, `${selection.selector} · ${toolRemovalReason(selection.name, toolPlan, context)}`),\n );\n const deniedMcpSelectors = toolPlan.capabilityCeiling?.denyExtensions\n ? (agent.mcpDirectTools ?? []).map((selector) =>\n resource(selector, `${ceilingReason(toolPlan)} · MCP extensions denied`),\n )\n : [];\n const unresolvedSelectors = toolPlan.capabilityCeiling?.denyExtensions\n ? []\n : (agent.mcpDirectTools ?? [])\n .filter((selector) => !selectorResolved(selector, toolPlan))\n .map((selector) => resource(selector, 'MCP selector did not resolve from the current parent catalog'));\n return {\n effective: unique(effective),\n removed: unique([...removedBuiltins, ...removedMcp, ...deniedMcpSelectors]),\n unresolved: unique([\n ...(toolPlan.explicitToolAllowlist\n ? []\n : [resource(HOST_DEFAULT_TOOLS, 'resolved by Pi only after the child host loads resources')]),\n ...unresolvedSelectors,\n resource(CONDITIONAL_TOOLS, 'intercom and structured_output depend on the concrete spawn request'),\n ]),\n };\n}\n\nfunction skillProjection(\n agent: AgentConfig,\n context: AgentResourceProjectionContext,\n): { tab: ResourceTabProjection; requireReadTool: boolean } {\n const resolution = context.skills.resolveSkillsWithFallback(\n agent.skills ?? [],\n context.cwd,\n context.cwd,\n agent.skillPath,\n context.cwd,\n );\n const explicitNames = new Set(resolution.resolved.map((skill) => skill.name));\n const ambient = agent.inheritSkills\n ? context.skills\n .discoverAvailableSkills(context.cwd)\n .filter((skill) => !explicitNames.has(skill.name))\n .map((skill) => resource(skill.name, `ambient parent snapshot · ${skill.source}`))\n : [];\n return {\n tab: {\n effective: unique([\n ...resolution.resolved.map((skill) => resource(skill.name, `configured · ${skill.source} · ${skill.path}`)),\n ...ambient,\n ]),\n removed: [],\n unresolved: unique([\n ...resolution.missing.map((name) =>\n resource(name, 'configured skill was not found from the current session cwd'),\n ),\n ...(agent.inheritSkills\n ? [resource(AMBIENT_SKILLS, 'Pi rediscovers ambient skills when the child resource loader starts')]\n : []),\n ]),\n },\n requireReadTool: buildSkillInjection(resolution.resolved).length > 0,\n };\n}\n\nfunction extensionProjection(agent: AgentConfig, plan: PiSdkResourcePlan): ResourceTabProjection {\n const runtimeExtensions = new Set(plan.toolPlan.runtimeExtensions);\n const configuredExtensions = new Set(plan.toolPlan.configuredExtensions);\n const effective = plan.extensions.map((name) =>\n resource(\n name,\n runtimeExtensions.has(name)\n ? 'internal runtime extension'\n : configuredExtensions.has(name)\n ? 'configured agent extension'\n : 'inherited parent harness extension',\n ),\n );\n const removed = plan.toolPlan.capabilityCeiling?.denyExtensions\n ? [\n ...pathShapedToolEntries(agent, plan.toolPlan),\n ...(agent.extensions ?? []),\n ...(agent.subagentOnlyExtensions ?? []),\n ].map((name) => resource(name, ceilingReason(plan.toolPlan)))\n : [];\n return {\n effective: unique(effective),\n removed: unique(removed),\n unresolved: plan.noAmbientExtensions\n ? []\n : [resource(AMBIENT_EXTENSIONS, 'Pi discovers additional ambient extensions only when the child loads')],\n };\n}\n\nfunction configuredOnlyProjection(agent: AgentConfig): AgentResourceProjection {\n const tools = emptyTab();\n tools.unresolved = unique([\n ...(agent.tools ?? []).map((name) => resource(name, 'configured for external runtime')),\n ...(agent.mcpDirectTools ?? []).map((name) => resource(name, 'configured MCP selector')),\n ...(agent.tools === undefined ? [resource('Runtime-default tools', 'determined by the external runtime')] : []),\n ]);\n const skills = emptyTab();\n skills.unresolved = unique([\n ...(agent.skills ?? []).map((name) => resource(name, 'configured skill name')),\n ...(agent.inheritSkills ? [resource(AMBIENT_SKILLS, 'determined by the external runtime')] : []),\n ]);\n const extensions = emptyTab();\n extensions.unresolved = unique([\n ...[...(agent.extensions ?? []), ...(agent.subagentOnlyExtensions ?? [])].map((name) =>\n resource(name, 'configured extension'),\n ),\n ...(agent.extensions === undefined ? [resource(AMBIENT_EXTENSIONS, 'determined by the external runtime')] : []),\n ]);\n return {\n tools,\n skills,\n extensions,\n notice: `Configured values only. Runtime '${agent.runtime}' does not use the Pi launch projection.`,\n configuredOnly: true,\n };\n}\n\nfunction failedProjection(error: unknown): AgentResourceProjection {\n return {\n tools: emptyTab(),\n skills: emptyTab(),\n extensions: emptyTab(),\n notice: 'Launch projection failed for this agent.',\n configuredOnly: false,\n error: error instanceof Error ? error.message : String(error),\n };\n}\n\nexport function projectAgentResources(\n agent: AgentConfig,\n context: AgentResourceProjectionContext,\n): AgentResourceProjection {\n if (!isPiRuntime(agent.runtime)) return configuredOnlyProjection(agent);\n try {\n const skills = skillProjection(agent, context);\n const plan = resolvePiSdkResourcePlan({\n tools: agent.tools,\n extensions: agent.extensions,\n subagentOnlyExtensions: agent.subagentOnlyExtensions,\n mcpDirectTools: agent.mcpDirectTools,\n cwd: context.cwd,\n requireReadTool: skills.requireReadTool,\n excludeTools: context.excludeTools ? [...context.excludeTools] : undefined,\n capabilityCeiling: context.capabilityCeiling,\n inheritSkills: agent.inheritSkills,\n environment: context.environment,\n });\n return {\n tools: toolProjection(agent, plan, context),\n skills: skills.tab,\n extensions: extensionProjection(agent, plan),\n notice:\n 'Launch projection from the current parent-policy and cwd snapshot. Child loading or request overrides may change qualified resources.',\n configuredOnly: false,\n };\n } catch (error) {\n return failedProjection(error);\n }\n}\n\nexport function buildAgentCatalogEntries(\n agents: readonly AgentConfig[],\n context: AgentResourceProjectionContext,\n): AgentCatalogEntry[] {\n return agents.map((agent) => ({ agent, resources: projectAgentResources(agent, context) }));\n}\n"],"mappings":"0JAYM,EAAqB,wBACrB,EAAiB,oBAoCvB,SAAS,GAAkC,CACzC,MAAO,CAAE,UAAW,EAAE,CAAE,QAAS,EAAE,CAAE,WAAY,EAAE,CAAE,CAGvD,SAAS,EAAS,EAAc,EAAoC,CAClE,OAAO,EAAS,CAAE,OAAM,SAAQ,CAAG,CAAE,OAAM,CAG7C,SAAS,EAAO,EAA0D,CACxE,IAAM,EAAO,IAAI,IACjB,OAAO,EAAM,OAAQ,GAAS,CAC5B,IAAM,EAAM,GAAG,EAAK,KAAK,IAAI,EAAK,QAAU,KAG5C,OAFI,EAAK,IAAI,EAAI,CAAS,IAC1B,EAAK,IAAI,EAAI,CACN,KACP,CAGJ,SAAS,EAAc,EAAoC,CACzD,IAAM,EAAU,EAAS,mBAAmB,SAAW,EAAE,CACzD,OAAO,EAAQ,OAAS,EACpB,sCAAsC,EAAQ,KAAK,KAAK,GACxD,gCAGN,SAAS,EAAkB,EAAc,EAA4B,EAAiD,CAMpH,OALI,EAAS,cAAc,SAAS,EAAK,CAChC,EAAQ,gBACX,sCAAsC,EAAQ,kBAC9C,kCAEC,EAAc,EAAS,CAGhC,SAAS,EAAsB,EAAoB,EAAsC,CACvF,IAAM,EAAe,IAAI,IAAI,EAAS,sBAAsB,CAC5D,OAAQ,EAAM,OAAS,EAAE,EAAE,OAAQ,GAAS,CAAC,EAAa,IAAI,EAAK,CAAC,CAGtE,SAAS,EAAiB,EAAkB,EAAqC,CAC/E,OAAO,EAAS,sBAAsB,KACnC,GAAc,EAAU,WAAa,GAAY,EAAU,SAAS,WAAW,GAAG,EAAS,GAAG,CAChG,CAGH,SAAS,EAAyB,EAAoB,EAAsC,CAG1F,OAFI,EAAM,QAAU,IAAA,GAChB,EAAS,mBAAmB,aAAqB,EAAS,kBAAkB,aACzE,EAAS,cAFsB,EAAS,sBAKjD,SAAS,EACP,EACA,EACA,EACuB,CACvB,GAAM,CAAE,YAAa,EACf,EAAW,IAAI,IAAI,EAAS,kBAAkB,CAC9C,EAAY,EAAS,sBACvB,EAAS,uBAAuB,IAAK,GACnC,EACE,EACA,EAAS,IAAI,EAAK,CACd,oBACA,EAAM,QAAU,IAAA,GACd,uCACA,0BACP,CACF,CACD,EAAE,CACA,EAAkB,EAAyB,EAAO,EAAS,CAC9D,OAAQ,GAAS,CAAC,EAAS,qBAAqB,SAAS,EAAK,CAAC,CAC/D,IAAK,GAAS,EAAS,EAAM,EAAkB,EAAM,EAAU,EAAQ,CAAC,CAAC,CACtE,EAAoB,IAAI,IAAI,EAAS,kBAAkB,CACvD,EAAa,EAAS,sBACzB,OAAQ,GAAc,CAAC,EAAkB,IAAI,EAAU,KAAK,CAAC,CAC7D,IAAK,GACJ,EAAS,EAAU,KAAM,GAAG,EAAU,SAAS,KAAK,EAAkB,EAAU,KAAM,EAAU,EAAQ,GAAG,CAC5G,CACG,EAAqB,EAAS,mBAAmB,gBAClD,EAAM,gBAAkB,EAAE,EAAE,IAAK,GAChC,EAAS,EAAU,GAAG,EAAc,EAAS,CAAC,0BAA0B,CACzE,CACD,EAAE,CACA,EAAsB,EAAS,mBAAmB,eACpD,EAAE,EACD,EAAM,gBAAkB,EAAE,EACxB,OAAQ,GAAa,CAAC,EAAiB,EAAU,EAAS,CAAC,CAC3D,IAAK,GAAa,EAAS,EAAU,+DAA+D,CAAC,CAC5G,MAAO,CACL,UAAW,EAAO,EAAU,CAC5B,QAAS,EAAO,CAAC,GAAG,EAAiB,GAAG,EAAY,GAAG,EAAmB,CAAC,CAC3E,WAAY,EAAO,CACjB,GAAI,EAAS,sBACT,EAAE,CACF,CAAC,EAAS,2BAAoB,2DAA2D,CAAC,CAC9F,GAAG,EACH,EAAS,kCAAmB,sEAAsE,CACnG,CAAC,CACH,CAGH,SAAS,EACP,EACA,EAC0D,CAC1D,IAAM,EAAa,EAAQ,OAAO,0BAChC,EAAM,QAAU,EAAE,CAClB,EAAQ,IACR,EAAQ,IACR,EAAM,UACN,EAAQ,IACT,CACK,EAAgB,IAAI,IAAI,EAAW,SAAS,IAAK,GAAU,EAAM,KAAK,CAAC,CACvE,EAAU,EAAM,cAClB,EAAQ,OACL,wBAAwB,EAAQ,IAAI,CACpC,OAAQ,GAAU,CAAC,EAAc,IAAI,EAAM,KAAK,CAAC,CACjD,IAAK,GAAU,EAAS,EAAM,KAAM,6BAA6B,EAAM,SAAS,CAAC,CACpF,EAAE,CACN,MAAO,CACL,IAAK,CACH,UAAW,EAAO,CAChB,GAAG,EAAW,SAAS,IAAK,GAAU,EAAS,EAAM,KAAM,gBAAgB,EAAM,OAAO,KAAK,EAAM,OAAO,CAAC,CAC3G,GAAG,EACJ,CAAC,CACF,QAAS,EAAE,CACX,WAAY,EAAO,CACjB,GAAG,EAAW,QAAQ,IAAK,GACzB,EAAS,EAAM,8DAA8D,CAC9E,CACD,GAAI,EAAM,cACN,CAAC,EAAS,EAAgB,sEAAsE,CAAC,CACjG,EAAE,CACP,CAAC,CACH,CACD,gBAAiBA,EAAAA,oBAAoB,EAAW,SAAS,CAAC,OAAS,EACpE,CAGH,SAAS,EAAoB,EAAoB,EAAgD,CAC/F,IAAM,EAAoB,IAAI,IAAI,EAAK,SAAS,kBAAkB,CAC5D,EAAuB,IAAI,IAAI,EAAK,SAAS,qBAAqB,CAClE,EAAY,EAAK,WAAW,IAAK,GACrC,EACE,EACA,EAAkB,IAAI,EAAK,CACvB,6BACA,EAAqB,IAAI,EAAK,CAC5B,6BACA,qCACP,CACF,CACK,EAAU,EAAK,SAAS,mBAAmB,eAC7C,CACE,GAAG,EAAsB,EAAO,EAAK,SAAS,CAC9C,GAAI,EAAM,YAAc,EAAE,CAC1B,GAAI,EAAM,wBAA0B,EAAE,CACvC,CAAC,IAAK,GAAS,EAAS,EAAM,EAAc,EAAK,SAAS,CAAC,CAAC,CAC7D,EAAE,CACN,MAAO,CACL,UAAW,EAAO,EAAU,CAC5B,QAAS,EAAO,EAAQ,CACxB,WAAY,EAAK,oBACb,EAAE,CACF,CAAC,EAAS,EAAoB,uEAAuE,CAAC,CAC3G,CAGH,SAAS,EAAyB,EAA6C,CAC7E,IAAM,EAAQ,GAAU,CACxB,EAAM,WAAa,EAAO,CACxB,IAAI,EAAM,OAAS,EAAE,EAAE,IAAK,GAAS,EAAS,EAAM,kCAAkC,CAAC,CACvF,IAAI,EAAM,gBAAkB,EAAE,EAAE,IAAK,GAAS,EAAS,EAAM,0BAA0B,CAAC,CACxF,GAAI,EAAM,QAAU,IAAA,GAAY,CAAC,EAAS,wBAAyB,qCAAqC,CAAC,CAAG,EAAE,CAC/G,CAAC,CACF,IAAM,EAAS,GAAU,CACzB,EAAO,WAAa,EAAO,CACzB,IAAI,EAAM,QAAU,EAAE,EAAE,IAAK,GAAS,EAAS,EAAM,wBAAwB,CAAC,CAC9E,GAAI,EAAM,cAAgB,CAAC,EAAS,EAAgB,qCAAqC,CAAC,CAAG,EAAE,CAChG,CAAC,CACF,IAAM,EAAa,GAAU,CAO7B,MANA,GAAW,WAAa,EAAO,CAC7B,GAAG,CAAC,GAAI,EAAM,YAAc,EAAE,CAAG,GAAI,EAAM,wBAA0B,EAAE,CAAE,CAAC,IAAK,GAC7E,EAAS,EAAM,uBAAuB,CACvC,CACD,GAAI,EAAM,aAAe,IAAA,GAAY,CAAC,EAAS,EAAoB,qCAAqC,CAAC,CAAG,EAAE,CAC/G,CAAC,CACK,CACL,QACA,SACA,aACA,OAAQ,oCAAoC,EAAM,QAAQ,0CAC1D,eAAgB,GACjB,CAGH,SAAS,EAAiB,EAAyC,CACjE,MAAO,CACL,MAAO,GAAU,CACjB,OAAQ,GAAU,CAClB,WAAY,GAAU,CACtB,OAAQ,2CACR,eAAgB,GAChB,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAC9D,CAGH,SAAgB,EACd,EACA,EACyB,CACzB,GAAI,CAACC,EAAAA,YAAY,EAAM,QAAQ,CAAE,OAAO,EAAyB,EAAM,CACvE,GAAI,CACF,IAAM,EAAS,EAAgB,EAAO,EAAQ,CACxC,EAAOC,EAAAA,yBAAyB,CACpC,MAAO,EAAM,MACb,WAAY,EAAM,WAClB,uBAAwB,EAAM,uBAC9B,eAAgB,EAAM,eACtB,IAAK,EAAQ,IACb,gBAAiB,EAAO,gBACxB,aAAc,EAAQ,aAAe,CAAC,GAAG,EAAQ,aAAa,CAAG,IAAA,GACjE,kBAAmB,EAAQ,kBAC3B,cAAe,EAAM,cACrB,YAAa,EAAQ,YACtB,CAAC,CACF,MAAO,CACL,MAAO,EAAe,EAAO,EAAM,EAAQ,CAC3C,OAAQ,EAAO,IACf,WAAY,EAAoB,EAAO,EAAK,CAC5C,OACE,wIACF,eAAgB,GACjB,OACM,EAAO,CACd,OAAO,EAAiB,EAAM,EAIlC,SAAgB,EACd,EACA,EACqB,CACrB,OAAO,EAAO,IAAK,IAAW,CAAE,QAAO,UAAW,EAAsB,EAAO,EAAQ,CAAE,EAAE"}
@@ -1,2 +1,2 @@
1
- import{buildSkillInjection as e,init_skills as t}from"../agents/skills.mjs";import{init_runtimeRegistry as n,isPiRuntime as r}from"../runs/shared/runtimeRegistry.mjs";import{init_piArgs as i,resolvePiSdkResourcePlan as a}from"../runs/shared/piArgs.mjs";t(),i(),n();const o=`Ambient Pi extensions`,s=`Ambient Pi skills`;function c(){return{effective:[],removed:[],unresolved:[]}}function l(e,t){return t?{name:e,detail:t}:{name:e}}function u(e){let t=new Set;return e.filter(e=>{let n=`${e.name}\0${e.detail??``}`;return t.has(n)?!1:(t.add(n),!0)})}function d(e){let t=e.capabilityCeiling?.sources??[];return t.length>0?`removed by capability ceiling from ${t.join(`, `)}`:`removed by capability ceiling`}function f(e,t,n){return t.excludedTools.includes(e)?n.exclusionSource?`excluded by active layer policy at ${n.exclusionSource}`:`excluded by active layer policy`:d(t)}function p(e,t){let n=new Set(t.requestedBuiltinTools);return(e.tools??[]).filter(e=>!n.has(e))}function m(e,t){return t.resolvedMcpSelections.some(t=>t.selector===e||t.selector.startsWith(`${e}/`))}function h(e,t){return e.tools===void 0?t.capabilityCeiling?.allowedTools?t.capabilityCeiling.allowedTools:t.excludedTools:t.requestedBuiltinTools}function g(e,t,n){let{toolPlan:r}=t,i=new Set(r.effectiveMcpTools),a=r.explicitToolAllowlist?r.effectiveToolAllowlist.map(t=>l(t,i.has(t)?`resolved MCP tool`:e.tools===void 0?`granted by parent capability ceiling`:`configured builtin tool`)):[],o=h(e,r).filter(e=>!r.declaredBuiltinTools.includes(e)).map(e=>l(e,f(e,r,n))),s=new Set(r.effectiveMcpTools),c=r.resolvedMcpSelections.filter(e=>!s.has(e.name)).map(e=>l(e.name,`${e.selector} · ${f(e.name,r,n)}`)),p=r.capabilityCeiling?.denyExtensions?(e.mcpDirectTools??[]).map(e=>l(e,`${d(r)} · MCP extensions denied`)):[],g=r.capabilityCeiling?.denyExtensions?[]:(e.mcpDirectTools??[]).filter(e=>!m(e,r)).map(e=>l(e,`MCP selector did not resolve from the current parent catalog`));return{effective:u(a),removed:u([...o,...c,...p]),unresolved:u([...r.explicitToolAllowlist?[]:[l(`Pi host-default tool set`,`resolved by Pi only after the child host loads resources`)],...g,l(`Request-specific internal tools`,`intercom and structured_output depend on the concrete spawn request`)])}}function _(t,n){let r=n.skills.resolveSkillsWithFallback(t.skills??[],n.cwd,n.cwd,t.skillPath,n.cwd),i=new Set(r.resolved.map(e=>e.name)),a=t.inheritSkills?n.skills.discoverAvailableSkills(n.cwd).filter(e=>!i.has(e.name)).map(e=>l(e.name,`ambient parent snapshot · ${e.source}`)):[];return{tab:{effective:u([...r.resolved.map(e=>l(e.name,`configured · ${e.source} · ${e.path}`)),...a]),removed:[],unresolved:u([...r.missing.map(e=>l(e,`configured skill was not found from the current session cwd`)),...t.inheritSkills?[l(s,`Pi rediscovers ambient skills when the child resource loader starts`)]:[]])},requireReadTool:e(r.resolved).length>0}}function v(e,t){let n=new Set(t.toolPlan.runtimeExtensions),r=new Set(t.toolPlan.configuredExtensions),i=t.extensions.map(e=>l(e,n.has(e)?`internal runtime extension`:r.has(e)?`configured agent extension`:`inherited parent harness extension`)),a=t.toolPlan.capabilityCeiling?.denyExtensions?[...p(e,t.toolPlan),...e.extensions??[],...e.subagentOnlyExtensions??[]].map(e=>l(e,d(t.toolPlan))):[];return{effective:u(i),removed:u(a),unresolved:t.noAmbientExtensions?[]:[l(o,`Pi discovers additional ambient extensions only when the child loads`)]}}function y(e){let t=c();t.unresolved=u([...(e.tools??[]).map(e=>l(e,`configured for external runtime`)),...(e.mcpDirectTools??[]).map(e=>l(e,`configured MCP selector`)),...e.tools===void 0?[l(`Runtime-default tools`,`determined by the external runtime`)]:[]]);let n=c();n.unresolved=u([...(e.skills??[]).map(e=>l(e,`configured skill name`)),...e.inheritSkills?[l(s,`determined by the external runtime`)]:[]]);let r=c();return r.unresolved=u([...[...e.extensions??[],...e.subagentOnlyExtensions??[]].map(e=>l(e,`configured extension`)),...e.extensions===void 0?[l(o,`determined by the external runtime`)]:[]]),{tools:t,skills:n,extensions:r,notice:`Configured values only. Runtime '${e.runtime}' does not use the Pi launch projection.`,configuredOnly:!0}}function b(e){return{tools:c(),skills:c(),extensions:c(),notice:`Launch projection failed for this agent.`,configuredOnly:!1,error:e instanceof Error?e.message:String(e)}}function x(e,t){if(!r(e.runtime))return y(e);try{let n=_(e,t),r=a({tools:e.tools,extensions:e.extensions,subagentOnlyExtensions:e.subagentOnlyExtensions,mcpDirectTools:e.mcpDirectTools,cwd:t.cwd,requireReadTool:n.requireReadTool,excludeTools:t.excludeTools?[...t.excludeTools]:void 0,capabilityCeiling:t.capabilityCeiling,inheritSkills:e.inheritSkills,environment:t.environment});return{tools:g(e,r,t),skills:n.tab,extensions:v(e,r),notice:`Launch projection from the current parent-policy and cwd snapshot. Child loading or request overrides may change qualified resources.`,configuredOnly:!1}}catch(e){return b(e)}}function S(e,t){return e.map(e=>({agent:e,resources:x(e,t)}))}export{S as buildAgentCatalogEntries};
1
+ import{buildSkillInjection as e,init_skills as t}from"../services/agents/skills.mjs";import{init_runtimeRegistry as n,isPiRuntime as r}from"../services/runs/shared/runtimeRegistry.mjs";import{init_piArgs as i,resolvePiSdkResourcePlan as a}from"../services/runs/shared/piArgs.mjs";t(),i(),n();const o=`Ambient Pi extensions`,s=`Ambient Pi skills`;function c(){return{effective:[],removed:[],unresolved:[]}}function l(e,t){return t?{name:e,detail:t}:{name:e}}function u(e){let t=new Set;return e.filter(e=>{let n=`${e.name}\0${e.detail??``}`;return t.has(n)?!1:(t.add(n),!0)})}function d(e){let t=e.capabilityCeiling?.sources??[];return t.length>0?`removed by capability ceiling from ${t.join(`, `)}`:`removed by capability ceiling`}function f(e,t,n){return t.excludedTools.includes(e)?n.exclusionSource?`excluded by Team package policy at ${n.exclusionSource}`:`excluded by Team package policy`:d(t)}function p(e,t){let n=new Set(t.requestedBuiltinTools);return(e.tools??[]).filter(e=>!n.has(e))}function m(e,t){return t.resolvedMcpSelections.some(t=>t.selector===e||t.selector.startsWith(`${e}/`))}function h(e,t){return e.tools===void 0?t.capabilityCeiling?.allowedTools?t.capabilityCeiling.allowedTools:t.excludedTools:t.requestedBuiltinTools}function g(e,t,n){let{toolPlan:r}=t,i=new Set(r.effectiveMcpTools),a=r.explicitToolAllowlist?r.effectiveToolAllowlist.map(t=>l(t,i.has(t)?`resolved MCP tool`:e.tools===void 0?`granted by parent capability ceiling`:`configured builtin tool`)):[],o=h(e,r).filter(e=>!r.declaredBuiltinTools.includes(e)).map(e=>l(e,f(e,r,n))),s=new Set(r.effectiveMcpTools),c=r.resolvedMcpSelections.filter(e=>!s.has(e.name)).map(e=>l(e.name,`${e.selector} · ${f(e.name,r,n)}`)),p=r.capabilityCeiling?.denyExtensions?(e.mcpDirectTools??[]).map(e=>l(e,`${d(r)} · MCP extensions denied`)):[],g=r.capabilityCeiling?.denyExtensions?[]:(e.mcpDirectTools??[]).filter(e=>!m(e,r)).map(e=>l(e,`MCP selector did not resolve from the current parent catalog`));return{effective:u(a),removed:u([...o,...c,...p]),unresolved:u([...r.explicitToolAllowlist?[]:[l(`Pi host-default tool set`,`resolved by Pi only after the child host loads resources`)],...g,l(`Request-specific internal tools`,`intercom and structured_output depend on the concrete spawn request`)])}}function _(t,n){let r=n.skills.resolveSkillsWithFallback(t.skills??[],n.cwd,n.cwd,t.skillPath,n.cwd),i=new Set(r.resolved.map(e=>e.name)),a=t.inheritSkills?n.skills.discoverAvailableSkills(n.cwd).filter(e=>!i.has(e.name)).map(e=>l(e.name,`ambient parent snapshot · ${e.source}`)):[];return{tab:{effective:u([...r.resolved.map(e=>l(e.name,`configured · ${e.source} · ${e.path}`)),...a]),removed:[],unresolved:u([...r.missing.map(e=>l(e,`configured skill was not found from the current session cwd`)),...t.inheritSkills?[l(s,`Pi rediscovers ambient skills when the child resource loader starts`)]:[]])},requireReadTool:e(r.resolved).length>0}}function v(e,t){let n=new Set(t.toolPlan.runtimeExtensions),r=new Set(t.toolPlan.configuredExtensions),i=t.extensions.map(e=>l(e,n.has(e)?`internal runtime extension`:r.has(e)?`configured agent extension`:`inherited parent harness extension`)),a=t.toolPlan.capabilityCeiling?.denyExtensions?[...p(e,t.toolPlan),...e.extensions??[],...e.subagentOnlyExtensions??[]].map(e=>l(e,d(t.toolPlan))):[];return{effective:u(i),removed:u(a),unresolved:t.noAmbientExtensions?[]:[l(o,`Pi discovers additional ambient extensions only when the child loads`)]}}function y(e){let t=c();t.unresolved=u([...(e.tools??[]).map(e=>l(e,`configured for external runtime`)),...(e.mcpDirectTools??[]).map(e=>l(e,`configured MCP selector`)),...e.tools===void 0?[l(`Runtime-default tools`,`determined by the external runtime`)]:[]]);let n=c();n.unresolved=u([...(e.skills??[]).map(e=>l(e,`configured skill name`)),...e.inheritSkills?[l(s,`determined by the external runtime`)]:[]]);let r=c();return r.unresolved=u([...[...e.extensions??[],...e.subagentOnlyExtensions??[]].map(e=>l(e,`configured extension`)),...e.extensions===void 0?[l(o,`determined by the external runtime`)]:[]]),{tools:t,skills:n,extensions:r,notice:`Configured values only. Runtime '${e.runtime}' does not use the Pi launch projection.`,configuredOnly:!0}}function b(e){return{tools:c(),skills:c(),extensions:c(),notice:`Launch projection failed for this agent.`,configuredOnly:!1,error:e instanceof Error?e.message:String(e)}}function x(e,t){if(!r(e.runtime))return y(e);try{let n=_(e,t),r=a({tools:e.tools,extensions:e.extensions,subagentOnlyExtensions:e.subagentOnlyExtensions,mcpDirectTools:e.mcpDirectTools,cwd:t.cwd,requireReadTool:n.requireReadTool,excludeTools:t.excludeTools?[...t.excludeTools]:void 0,capabilityCeiling:t.capabilityCeiling,inheritSkills:e.inheritSkills,environment:t.environment});return{tools:g(e,r,t),skills:n.tab,extensions:v(e,r),notice:`Launch projection from the current parent-policy and cwd snapshot. Child loading or request overrides may change qualified resources.`,configuredOnly:!1}}catch(e){return b(e)}}function S(e,t){return e.map(e=>({agent:e,resources:x(e,t)}))}export{S as buildAgentCatalogEntries};
2
2
  //# sourceMappingURL=agentResourceProjection.mjs.map