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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (520) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +46 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.cjs +1 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.mjs +1 -0
  5. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateMetadata.cjs +1 -0
  6. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateMetadata.mjs +1 -0
  7. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateParam.cjs +1 -0
  8. package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateParam.mjs +1 -0
  9. package/dist/_virtual/_rolldown/runtime.cjs +1 -0
  10. package/dist/_virtual/_rolldown/runtime.mjs +1 -0
  11. package/dist/agents/discovery.cjs +2 -0
  12. package/dist/agents/discovery.cjs.map +1 -0
  13. package/dist/agents/discovery.mjs +2 -0
  14. package/dist/agents/discovery.mjs.map +1 -0
  15. package/dist/agents/frontmatter.cjs +10 -0
  16. package/dist/agents/frontmatter.cjs.map +1 -0
  17. package/dist/agents/frontmatter.mjs +10 -0
  18. package/dist/agents/frontmatter.mjs.map +1 -0
  19. package/dist/agents/loader.cjs +2 -0
  20. package/dist/agents/loader.cjs.map +1 -0
  21. package/dist/agents/loader.mjs +2 -0
  22. package/dist/agents/loader.mjs.map +1 -0
  23. package/dist/agents/memory.cjs +3 -0
  24. package/dist/agents/memory.cjs.map +1 -0
  25. package/dist/agents/memory.mjs +3 -0
  26. package/dist/agents/memory.mjs.map +1 -0
  27. package/dist/agents/projectRoot.cjs +2 -0
  28. package/dist/agents/projectRoot.cjs.map +1 -0
  29. package/dist/agents/projectRoot.mjs +2 -0
  30. package/dist/agents/projectRoot.mjs.map +1 -0
  31. package/dist/agents/settings.cjs +2 -0
  32. package/dist/agents/settings.cjs.map +1 -0
  33. package/dist/agents/settings.mjs +2 -0
  34. package/dist/agents/settings.mjs.map +1 -0
  35. package/dist/agents/skills.cjs +0 -0
  36. package/dist/agents/skills.cjs.map +1 -0
  37. package/dist/agents/skills.mjs +5 -0
  38. package/dist/agents/skills.mjs.map +1 -0
  39. package/dist/agents/types.d.cts +121 -0
  40. package/dist/agents/types.d.cts.map +1 -0
  41. package/dist/agents/types.d.mts +121 -0
  42. package/dist/agents/types.d.mts.map +1 -0
  43. package/dist/api/backgroundWork.cjs +1 -0
  44. package/dist/api/backgroundWork.d.cts +2 -0
  45. package/dist/api/backgroundWork.d.mts +2 -0
  46. package/dist/api/backgroundWork.mjs +1 -0
  47. package/dist/api/capabilityCeiling.cjs +1 -0
  48. package/dist/api/capabilityCeiling.d.cts +3 -0
  49. package/dist/api/capabilityCeiling.d.mts +3 -0
  50. package/dist/api/capabilityCeiling.mjs +2 -0
  51. package/dist/api/capabilityCeiling.mjs.map +1 -0
  52. package/dist/api/delegation.cjs +1 -0
  53. package/dist/api/delegation.d.cts +2 -0
  54. package/dist/api/delegation.d.mts +2 -0
  55. package/dist/api/delegation.mjs +1 -0
  56. package/dist/api/teamSnapshot.cjs +1 -0
  57. package/dist/api/teamSnapshot.d.cts +2 -0
  58. package/dist/api/teamSnapshot.d.mts +2 -0
  59. package/dist/api/teamSnapshot.mjs +2 -0
  60. package/dist/api/teamSnapshot.mjs.map +1 -0
  61. package/dist/container/bindOrRebind.cjs +2 -0
  62. package/dist/container/bindOrRebind.cjs.map +1 -0
  63. package/dist/container/bindOrRebind.mjs +2 -0
  64. package/dist/container/bindOrRebind.mjs.map +1 -0
  65. package/dist/container/globalBridge.cjs +2 -0
  66. package/dist/container/globalBridge.cjs.map +1 -0
  67. package/dist/container/globalBridge.d.cts +19 -0
  68. package/dist/container/globalBridge.d.cts.map +1 -0
  69. package/dist/container/globalBridge.d.mts +19 -0
  70. package/dist/container/globalBridge.d.mts.map +1 -0
  71. package/dist/container/globalBridge.mjs +2 -0
  72. package/dist/container/globalBridge.mjs.map +1 -0
  73. package/dist/container/index.cjs +2 -0
  74. package/dist/container/index.cjs.map +1 -0
  75. package/dist/container/index.d.cts +38 -0
  76. package/dist/container/index.d.cts.map +1 -0
  77. package/dist/container/index.d.mts +38 -0
  78. package/dist/container/index.d.mts.map +1 -0
  79. package/dist/container/index.mjs +2 -0
  80. package/dist/container/index.mjs.map +1 -0
  81. package/dist/container/modules/agents.cjs +2 -0
  82. package/dist/container/modules/agents.cjs.map +1 -0
  83. package/dist/container/modules/agents.d.cts +1 -0
  84. package/dist/container/modules/agents.d.mts +1 -0
  85. package/dist/container/modules/agents.mjs +2 -0
  86. package/dist/container/modules/agents.mjs.map +1 -0
  87. package/dist/container/modules/core.cjs +2 -0
  88. package/dist/container/modules/core.cjs.map +1 -0
  89. package/dist/container/modules/core.d.cts +1 -0
  90. package/dist/container/modules/core.d.mts +1 -0
  91. package/dist/container/modules/core.mjs +2 -0
  92. package/dist/container/modules/core.mjs.map +1 -0
  93. package/dist/container/modules/extensions.cjs +2 -0
  94. package/dist/container/modules/extensions.cjs.map +1 -0
  95. package/dist/container/modules/extensions.mjs +2 -0
  96. package/dist/container/modules/extensions.mjs.map +1 -0
  97. package/dist/container/modules/intercom.cjs +2 -0
  98. package/dist/container/modules/intercom.cjs.map +1 -0
  99. package/dist/container/modules/intercom.mjs +2 -0
  100. package/dist/container/modules/intercom.mjs.map +1 -0
  101. package/dist/container/modules/runs.cjs +2 -0
  102. package/dist/container/modules/runs.cjs.map +1 -0
  103. package/dist/container/modules/runs.mjs +2 -0
  104. package/dist/container/modules/runs.mjs.map +1 -0
  105. package/dist/container/types.cjs +2 -0
  106. package/dist/container/types.cjs.map +1 -0
  107. package/dist/container/types.d.cts +45 -0
  108. package/dist/container/types.d.cts.map +1 -0
  109. package/dist/container/types.d.mts +45 -0
  110. package/dist/container/types.d.mts.map +1 -0
  111. package/dist/container/types.mjs +2 -0
  112. package/dist/container/types.mjs.map +1 -0
  113. package/dist/env.cjs +2 -0
  114. package/dist/env.cjs.map +1 -0
  115. package/dist/env.d.cts +65 -0
  116. package/dist/env.d.cts.map +1 -0
  117. package/dist/env.d.mts +65 -0
  118. package/dist/env.d.mts.map +1 -0
  119. package/dist/env.mjs +2 -0
  120. package/dist/env.mjs.map +1 -0
  121. package/dist/extension.cjs +2 -0
  122. package/dist/extension.cjs.map +1 -0
  123. package/dist/extension.mjs +2 -0
  124. package/dist/extension.mjs.map +1 -0
  125. package/dist/extensions/config.cjs +2 -0
  126. package/dist/extensions/config.cjs.map +1 -0
  127. package/dist/extensions/config.mjs +2 -0
  128. package/dist/extensions/config.mjs.map +1 -0
  129. package/dist/extensions/delegationBridge.cjs +2 -0
  130. package/dist/extensions/delegationBridge.cjs.map +1 -0
  131. package/dist/extensions/delegationBridge.mjs +2 -0
  132. package/dist/extensions/delegationBridge.mjs.map +1 -0
  133. package/dist/extensions/doom.cjs +2 -0
  134. package/dist/extensions/doom.cjs.map +1 -0
  135. package/dist/extensions/doom.d.cts +8 -0
  136. package/dist/extensions/doom.d.cts.map +1 -0
  137. package/dist/extensions/doom.d.mts +8 -0
  138. package/dist/extensions/doom.d.mts.map +1 -0
  139. package/dist/extensions/doom.mjs +2 -0
  140. package/dist/extensions/doom.mjs.map +1 -0
  141. package/dist/extensions/fablePlanBridge.cjs +2 -0
  142. package/dist/extensions/fablePlanBridge.cjs.map +1 -0
  143. package/dist/extensions/fablePlanBridge.mjs +2 -0
  144. package/dist/extensions/fablePlanBridge.mjs.map +1 -0
  145. package/dist/extensions/managementActions.cjs +2 -0
  146. package/dist/extensions/managementActions.cjs.map +1 -0
  147. package/dist/extensions/managementActions.mjs +2 -0
  148. package/dist/extensions/managementActions.mjs.map +1 -0
  149. package/dist/extensions/operationJournal.cjs +2 -0
  150. package/dist/extensions/operationJournal.cjs.map +1 -0
  151. package/dist/extensions/operationJournal.mjs +2 -0
  152. package/dist/extensions/operationJournal.mjs.map +1 -0
  153. package/dist/extensions/orchestratorPrompt.cjs +35 -0
  154. package/dist/extensions/orchestratorPrompt.cjs.map +1 -0
  155. package/dist/extensions/orchestratorPrompt.mjs +35 -0
  156. package/dist/extensions/orchestratorPrompt.mjs.map +1 -0
  157. package/dist/extensions/pi.cjs +2 -0
  158. package/dist/extensions/pi.cjs.map +1 -0
  159. package/dist/extensions/pi.d.cts +2 -0
  160. package/dist/extensions/pi.d.mts +2 -0
  161. package/dist/extensions/pi.mjs +2 -0
  162. package/dist/extensions/pi.mjs.map +1 -0
  163. package/dist/extensions/schemas.cjs +1 -0
  164. package/dist/extensions/schemas.mjs +2 -0
  165. package/dist/extensions/schemas.mjs.map +1 -0
  166. package/dist/extensions/spawnPlan.cjs +3 -0
  167. package/dist/extensions/spawnPlan.cjs.map +1 -0
  168. package/dist/extensions/spawnPlan.mjs +3 -0
  169. package/dist/extensions/spawnPlan.mjs.map +1 -0
  170. package/dist/extensions/standard.cjs +2 -0
  171. package/dist/extensions/standard.cjs.map +1 -0
  172. package/dist/extensions/standard.d.cts +8 -0
  173. package/dist/extensions/standard.d.cts.map +1 -0
  174. package/dist/extensions/standard.d.mts +8 -0
  175. package/dist/extensions/standard.d.mts.map +1 -0
  176. package/dist/extensions/standard.mjs +2 -0
  177. package/dist/extensions/standard.mjs.map +1 -0
  178. package/dist/extensions/statusViews.cjs +7 -0
  179. package/dist/extensions/statusViews.cjs.map +1 -0
  180. package/dist/extensions/statusViews.mjs +7 -0
  181. package/dist/extensions/statusViews.mjs.map +1 -0
  182. package/dist/extensions/subagentPromptRuntime.cjs +18 -0
  183. package/dist/extensions/subagentPromptRuntime.cjs.map +1 -0
  184. package/dist/extensions/subagentPromptRuntime.d.cts +58 -0
  185. package/dist/extensions/subagentPromptRuntime.d.cts.map +1 -0
  186. package/dist/extensions/subagentPromptRuntime.d.mts +58 -0
  187. package/dist/extensions/subagentPromptRuntime.d.mts.map +1 -0
  188. package/dist/extensions/subagentPromptRuntime.mjs +18 -0
  189. package/dist/extensions/subagentPromptRuntime.mjs.map +1 -0
  190. package/dist/extensions/subagentPromptRuntimeEntry.cjs +2 -0
  191. package/dist/extensions/subagentPromptRuntimeEntry.cjs.map +1 -0
  192. package/dist/extensions/subagentPromptRuntimeEntry.d.cts +2 -0
  193. package/dist/extensions/subagentPromptRuntimeEntry.d.mts +2 -0
  194. package/dist/extensions/subagentPromptRuntimeEntry.mjs +2 -0
  195. package/dist/extensions/subagentPromptRuntimeEntry.mjs.map +1 -0
  196. package/dist/extensions/subagentTool.cjs +7 -0
  197. package/dist/extensions/subagentTool.cjs.map +1 -0
  198. package/dist/extensions/subagentTool.mjs +7 -0
  199. package/dist/extensions/subagentTool.mjs.map +1 -0
  200. package/dist/extensions/toolDescription.cjs +2 -0
  201. package/dist/extensions/toolDescription.cjs.map +1 -0
  202. package/dist/extensions/toolDescription.mjs +2 -0
  203. package/dist/extensions/toolDescription.mjs.map +1 -0
  204. package/dist/index.cjs +2 -0
  205. package/dist/index.cjs.map +1 -0
  206. package/dist/index.d.cts +34 -0
  207. package/dist/index.d.cts.map +1 -0
  208. package/dist/index.d.mts +34 -0
  209. package/dist/index.d.mts.map +1 -0
  210. package/dist/index.mjs +2 -0
  211. package/dist/index.mjs.map +1 -0
  212. package/dist/intercom/intercomBridge.cjs +2 -0
  213. package/dist/intercom/intercomBridge.cjs.map +1 -0
  214. package/dist/intercom/intercomBridge.mjs +2 -0
  215. package/dist/intercom/intercomBridge.mjs.map +1 -0
  216. package/dist/intercom/nativeTeamChannel.cjs +5 -0
  217. package/dist/intercom/nativeTeamChannel.cjs.map +1 -0
  218. package/dist/intercom/nativeTeamChannel.d.cts +22 -0
  219. package/dist/intercom/nativeTeamChannel.d.cts.map +1 -0
  220. package/dist/intercom/nativeTeamChannel.d.mts +22 -0
  221. package/dist/intercom/nativeTeamChannel.d.mts.map +1 -0
  222. package/dist/intercom/nativeTeamChannel.mjs +5 -0
  223. package/dist/intercom/nativeTeamChannel.mjs.map +1 -0
  224. package/dist/intercom/supervisorControlChannel.cjs +2 -0
  225. package/dist/intercom/supervisorControlChannel.cjs.map +1 -0
  226. package/dist/intercom/supervisorControlChannel.mjs +2 -0
  227. package/dist/intercom/supervisorControlChannel.mjs.map +1 -0
  228. package/dist/protocol/backgroundWork.cjs +2 -0
  229. package/dist/protocol/backgroundWork.cjs.map +1 -0
  230. package/dist/protocol/backgroundWork.d.cts +52 -0
  231. package/dist/protocol/backgroundWork.d.cts.map +1 -0
  232. package/dist/protocol/backgroundWork.d.mts +52 -0
  233. package/dist/protocol/backgroundWork.d.mts.map +1 -0
  234. package/dist/protocol/backgroundWork.mjs +2 -0
  235. package/dist/protocol/backgroundWork.mjs.map +1 -0
  236. package/dist/protocol/capabilityCeiling.cjs +2 -0
  237. package/dist/protocol/capabilityCeiling.cjs.map +1 -0
  238. package/dist/protocol/capabilityCeiling.d.cts +51 -0
  239. package/dist/protocol/capabilityCeiling.d.cts.map +1 -0
  240. package/dist/protocol/capabilityCeiling.d.mts +51 -0
  241. package/dist/protocol/capabilityCeiling.d.mts.map +1 -0
  242. package/dist/protocol/capabilityCeiling.mjs +2 -0
  243. package/dist/protocol/capabilityCeiling.mjs.map +1 -0
  244. package/dist/protocol/delegation.cjs +2 -0
  245. package/dist/protocol/delegation.cjs.map +1 -0
  246. package/dist/protocol/delegation.d.cts +269 -0
  247. package/dist/protocol/delegation.d.cts.map +1 -0
  248. package/dist/protocol/delegation.d.mts +269 -0
  249. package/dist/protocol/delegation.d.mts.map +1 -0
  250. package/dist/protocol/delegation.mjs +2 -0
  251. package/dist/protocol/delegation.mjs.map +1 -0
  252. package/dist/runs/background/asyncExecution.cjs +2 -0
  253. package/dist/runs/background/asyncExecution.cjs.map +1 -0
  254. package/dist/runs/background/asyncExecution.mjs +2 -0
  255. package/dist/runs/background/asyncExecution.mjs.map +1 -0
  256. package/dist/runs/background/asyncJobTracker.cjs +2 -0
  257. package/dist/runs/background/asyncJobTracker.cjs.map +1 -0
  258. package/dist/runs/background/asyncJobTracker.mjs +2 -0
  259. package/dist/runs/background/asyncJobTracker.mjs.map +1 -0
  260. package/dist/runs/background/cliRunnerEntry.cjs +2 -0
  261. package/dist/runs/background/cliRunnerEntry.cjs.map +1 -0
  262. package/dist/runs/background/cliRunnerEntry.d.cts +1 -0
  263. package/dist/runs/background/cliRunnerEntry.d.mts +1 -0
  264. package/dist/runs/background/cliRunnerEntry.mjs +2 -0
  265. package/dist/runs/background/cliRunnerEntry.mjs.map +1 -0
  266. package/dist/runs/background/completionBatcher.cjs +2 -0
  267. package/dist/runs/background/completionBatcher.cjs.map +1 -0
  268. package/dist/runs/background/completionBatcher.mjs +2 -0
  269. package/dist/runs/background/completionBatcher.mjs.map +1 -0
  270. package/dist/runs/background/notify.cjs +4 -0
  271. package/dist/runs/background/notify.cjs.map +1 -0
  272. package/dist/runs/background/notify.mjs +4 -0
  273. package/dist/runs/background/notify.mjs.map +1 -0
  274. package/dist/runs/background/parentWatchdog.cjs +2 -0
  275. package/dist/runs/background/parentWatchdog.cjs.map +1 -0
  276. package/dist/runs/background/parentWatchdog.mjs +2 -0
  277. package/dist/runs/background/parentWatchdog.mjs.map +1 -0
  278. package/dist/runs/background/processTerminal.cjs +2 -0
  279. package/dist/runs/background/processTerminal.cjs.map +1 -0
  280. package/dist/runs/background/processTerminal.mjs +2 -0
  281. package/dist/runs/background/processTerminal.mjs.map +1 -0
  282. package/dist/runs/background/resultWatcher.cjs +2 -0
  283. package/dist/runs/background/resultWatcher.cjs.map +1 -0
  284. package/dist/runs/background/resultWatcher.mjs +2 -0
  285. package/dist/runs/background/resultWatcher.mjs.map +1 -0
  286. package/dist/runs/background/runIdResolver.cjs +2 -0
  287. package/dist/runs/background/runIdResolver.cjs.map +1 -0
  288. package/dist/runs/background/runIdResolver.mjs +2 -0
  289. package/dist/runs/background/runIdResolver.mjs.map +1 -0
  290. package/dist/runs/background/runnerBootstrap.cjs +2 -0
  291. package/dist/runs/background/runnerBootstrap.cjs.map +1 -0
  292. package/dist/runs/background/runnerBootstrap.mjs +2 -0
  293. package/dist/runs/background/runnerBootstrap.mjs.map +1 -0
  294. package/dist/runs/background/runnerExecution.cjs +2 -0
  295. package/dist/runs/background/runnerExecution.cjs.map +1 -0
  296. package/dist/runs/background/runnerExecution.mjs +2 -0
  297. package/dist/runs/background/runnerExecution.mjs.map +1 -0
  298. package/dist/runs/background/runnerReporting.cjs +3 -0
  299. package/dist/runs/background/runnerReporting.cjs.map +1 -0
  300. package/dist/runs/background/runnerReporting.mjs +3 -0
  301. package/dist/runs/background/runnerReporting.mjs.map +1 -0
  302. package/dist/runs/background/runnerTeamMembership.cjs +2 -0
  303. package/dist/runs/background/runnerTeamMembership.cjs.map +1 -0
  304. package/dist/runs/background/runnerTeamMembership.mjs +2 -0
  305. package/dist/runs/background/runnerTeamMembership.mjs.map +1 -0
  306. package/dist/runs/background/spawnHandshake.cjs +2 -0
  307. package/dist/runs/background/spawnHandshake.cjs.map +1 -0
  308. package/dist/runs/background/spawnHandshake.mjs +2 -0
  309. package/dist/runs/background/spawnHandshake.mjs.map +1 -0
  310. package/dist/runs/background/staleRunReconciler.cjs +2 -0
  311. package/dist/runs/background/staleRunReconciler.cjs.map +1 -0
  312. package/dist/runs/background/staleRunReconciler.mjs +2 -0
  313. package/dist/runs/background/staleRunReconciler.mjs.map +1 -0
  314. package/dist/runs/background/statusReader.cjs +2 -0
  315. package/dist/runs/background/statusReader.cjs.map +1 -0
  316. package/dist/runs/background/statusReader.mjs +2 -0
  317. package/dist/runs/background/statusReader.mjs.map +1 -0
  318. package/dist/runs/background/statusWriter.cjs +2 -0
  319. package/dist/runs/background/statusWriter.cjs.map +1 -0
  320. package/dist/runs/background/statusWriter.mjs +2 -0
  321. package/dist/runs/background/statusWriter.mjs.map +1 -0
  322. package/dist/runs/background/subagentWait.cjs +2 -0
  323. package/dist/runs/background/subagentWait.cjs.map +1 -0
  324. package/dist/runs/background/subagentWait.mjs +2 -0
  325. package/dist/runs/background/subagentWait.mjs.map +1 -0
  326. package/dist/runs/background/terminalPersistence.cjs +2 -0
  327. package/dist/runs/background/terminalPersistence.cjs.map +1 -0
  328. package/dist/runs/background/terminalPersistence.mjs +2 -0
  329. package/dist/runs/background/terminalPersistence.mjs.map +1 -0
  330. package/dist/runs/registry/processGroup.cjs +2 -0
  331. package/dist/runs/registry/processGroup.cjs.map +1 -0
  332. package/dist/runs/registry/processGroup.mjs +2 -0
  333. package/dist/runs/registry/processGroup.mjs.map +1 -0
  334. package/dist/runs/registry/runRegistry.cjs +2 -0
  335. package/dist/runs/registry/runRegistry.cjs.map +1 -0
  336. package/dist/runs/registry/runRegistry.mjs +2 -0
  337. package/dist/runs/registry/runRegistry.mjs.map +1 -0
  338. package/dist/runs/registry/sessionLifecycle.cjs +2 -0
  339. package/dist/runs/registry/sessionLifecycle.cjs.map +1 -0
  340. package/dist/runs/registry/sessionLifecycle.mjs +2 -0
  341. package/dist/runs/registry/sessionLifecycle.mjs.map +1 -0
  342. package/dist/runs/registry/suspendedRuns.cjs +4 -0
  343. package/dist/runs/registry/suspendedRuns.cjs.map +1 -0
  344. package/dist/runs/registry/suspendedRuns.mjs +4 -0
  345. package/dist/runs/registry/suspendedRuns.mjs.map +1 -0
  346. package/dist/runs/sdkRunnerEntry.cjs +2 -0
  347. package/dist/runs/sdkRunnerEntry.cjs.map +1 -0
  348. package/dist/runs/sdkRunnerEntry.d.cts +1 -0
  349. package/dist/runs/sdkRunnerEntry.d.mts +1 -0
  350. package/dist/runs/sdkRunnerEntry.mjs +2 -0
  351. package/dist/runs/sdkRunnerEntry.mjs.map +1 -0
  352. package/dist/runs/shared/claudeFableProfile.cjs +4 -0
  353. package/dist/runs/shared/claudeFableProfile.cjs.map +1 -0
  354. package/dist/runs/shared/claudeFableProfile.mjs +4 -0
  355. package/dist/runs/shared/claudeFableProfile.mjs.map +1 -0
  356. package/dist/runs/shared/depthGuard.cjs +2 -0
  357. package/dist/runs/shared/depthGuard.cjs.map +1 -0
  358. package/dist/runs/shared/depthGuard.mjs +2 -0
  359. package/dist/runs/shared/depthGuard.mjs.map +1 -0
  360. package/dist/runs/shared/mcpDirectToolAllowlist.cjs +2 -0
  361. package/dist/runs/shared/mcpDirectToolAllowlist.cjs.map +1 -0
  362. package/dist/runs/shared/mcpDirectToolAllowlist.mjs +2 -0
  363. package/dist/runs/shared/mcpDirectToolAllowlist.mjs.map +1 -0
  364. package/dist/runs/shared/modelFallback.cjs +2 -0
  365. package/dist/runs/shared/modelFallback.cjs.map +1 -0
  366. package/dist/runs/shared/modelFallback.mjs +2 -0
  367. package/dist/runs/shared/modelFallback.mjs.map +1 -0
  368. package/dist/runs/shared/modelScope.cjs +2 -0
  369. package/dist/runs/shared/modelScope.cjs.map +1 -0
  370. package/dist/runs/shared/modelScope.mjs +2 -0
  371. package/dist/runs/shared/modelScope.mjs.map +1 -0
  372. package/dist/runs/shared/nestedPath.cjs +2 -0
  373. package/dist/runs/shared/nestedPath.cjs.map +1 -0
  374. package/dist/runs/shared/nestedPath.mjs +2 -0
  375. package/dist/runs/shared/nestedPath.mjs.map +1 -0
  376. package/dist/runs/shared/piArgs.cjs +2 -0
  377. package/dist/runs/shared/piArgs.cjs.map +1 -0
  378. package/dist/runs/shared/piArgs.mjs +2 -0
  379. package/dist/runs/shared/piArgs.mjs.map +1 -0
  380. package/dist/runs/shared/piSpawn.cjs +2 -0
  381. package/dist/runs/shared/piSpawn.cjs.map +1 -0
  382. package/dist/runs/shared/piSpawn.mjs +2 -0
  383. package/dist/runs/shared/piSpawn.mjs.map +1 -0
  384. package/dist/runs/shared/runWithConcurrency.cjs +2 -0
  385. package/dist/runs/shared/runWithConcurrency.cjs.map +1 -0
  386. package/dist/runs/shared/runWithConcurrency.mjs +2 -0
  387. package/dist/runs/shared/runWithConcurrency.mjs.map +1 -0
  388. package/dist/runs/shared/runtimeRegistry.cjs +2 -0
  389. package/dist/runs/shared/runtimeRegistry.cjs.map +1 -0
  390. package/dist/runs/shared/runtimeRegistry.mjs +2 -0
  391. package/dist/runs/shared/runtimeRegistry.mjs.map +1 -0
  392. package/dist/runs/shared/structuredOutput.cjs +2 -0
  393. package/dist/runs/shared/structuredOutput.cjs.map +1 -0
  394. package/dist/runs/shared/structuredOutput.mjs +2 -0
  395. package/dist/runs/shared/structuredOutput.mjs.map +1 -0
  396. package/dist/runs/shared/toolAvailability.cjs +2 -0
  397. package/dist/runs/shared/toolAvailability.cjs.map +1 -0
  398. package/dist/runs/shared/toolAvailability.mjs +2 -0
  399. package/dist/runs/shared/toolAvailability.mjs.map +1 -0
  400. package/dist/runs/shared/toolBudget.cjs +2 -0
  401. package/dist/runs/shared/toolBudget.cjs.map +1 -0
  402. package/dist/runs/shared/toolBudget.mjs +2 -0
  403. package/dist/runs/shared/toolBudget.mjs.map +1 -0
  404. package/dist/shared/artifacts.cjs +2 -0
  405. package/dist/shared/artifacts.cjs.map +1 -0
  406. package/dist/shared/artifacts.mjs +2 -0
  407. package/dist/shared/artifacts.mjs.map +1 -0
  408. package/dist/shared/atomicJson.cjs +2 -0
  409. package/dist/shared/atomicJson.cjs.map +1 -0
  410. package/dist/shared/atomicJson.mjs +2 -0
  411. package/dist/shared/atomicJson.mjs.map +1 -0
  412. package/dist/shared/boundedKeySet.cjs +2 -0
  413. package/dist/shared/boundedKeySet.cjs.map +1 -0
  414. package/dist/shared/boundedKeySet.mjs +2 -0
  415. package/dist/shared/boundedKeySet.mjs.map +1 -0
  416. package/dist/shared/childTranscript.cjs +5 -0
  417. package/dist/shared/childTranscript.cjs.map +1 -0
  418. package/dist/shared/childTranscript.mjs +5 -0
  419. package/dist/shared/childTranscript.mjs.map +1 -0
  420. package/dist/shared/configDir.cjs +2 -0
  421. package/dist/shared/configDir.cjs.map +1 -0
  422. package/dist/shared/configDir.mjs +2 -0
  423. package/dist/shared/configDir.mjs.map +1 -0
  424. package/dist/shared/errors.cjs +2 -0
  425. package/dist/shared/errors.cjs.map +1 -0
  426. package/dist/shared/errors.mjs +2 -0
  427. package/dist/shared/errors.mjs.map +1 -0
  428. package/dist/shared/fileSystemRetry.cjs +2 -0
  429. package/dist/shared/fileSystemRetry.cjs.map +1 -0
  430. package/dist/shared/fileSystemRetry.mjs +2 -0
  431. package/dist/shared/fileSystemRetry.mjs.map +1 -0
  432. package/dist/shared/formatters.cjs +2 -0
  433. package/dist/shared/formatters.cjs.map +1 -0
  434. package/dist/shared/formatters.mjs +2 -0
  435. package/dist/shared/formatters.mjs.map +1 -0
  436. package/dist/shared/lruCache.cjs +2 -0
  437. package/dist/shared/lruCache.cjs.map +1 -0
  438. package/dist/shared/lruCache.mjs +2 -0
  439. package/dist/shared/lruCache.mjs.map +1 -0
  440. package/dist/shared/modelInfo.cjs +2 -0
  441. package/dist/shared/modelInfo.cjs.map +1 -0
  442. package/dist/shared/modelInfo.mjs +2 -0
  443. package/dist/shared/modelInfo.mjs.map +1 -0
  444. package/dist/shared/modelResolution.cjs +2 -0
  445. package/dist/shared/modelResolution.cjs.map +1 -0
  446. package/dist/shared/modelResolution.mjs +2 -0
  447. package/dist/shared/modelResolution.mjs.map +1 -0
  448. package/dist/shared/paths.cjs +2 -0
  449. package/dist/shared/paths.cjs.map +1 -0
  450. package/dist/shared/paths.mjs +2 -0
  451. package/dist/shared/paths.mjs.map +1 -0
  452. package/dist/shared/pollScheduler.cjs +2 -0
  453. package/dist/shared/pollScheduler.cjs.map +1 -0
  454. package/dist/shared/pollScheduler.mjs +2 -0
  455. package/dist/shared/pollScheduler.mjs.map +1 -0
  456. package/dist/shared/scopeOwner.cjs +2 -0
  457. package/dist/shared/scopeOwner.cjs.map +1 -0
  458. package/dist/shared/scopeOwner.mjs +2 -0
  459. package/dist/shared/scopeOwner.mjs.map +1 -0
  460. package/dist/shared/versioned.cjs +2 -0
  461. package/dist/shared/versioned.cjs.map +1 -0
  462. package/dist/shared/versioned.mjs +2 -0
  463. package/dist/shared/versioned.mjs.map +1 -0
  464. package/dist/slash/chainExpression.cjs +2 -0
  465. package/dist/slash/chainExpression.cjs.map +1 -0
  466. package/dist/slash/chainExpression.mjs +2 -0
  467. package/dist/slash/chainExpression.mjs.map +1 -0
  468. package/dist/slash/doctor.cjs +5 -0
  469. package/dist/slash/doctor.cjs.map +1 -0
  470. package/dist/slash/doctor.mjs +5 -0
  471. package/dist/slash/doctor.mjs.map +1 -0
  472. package/dist/slash/slashCommands.cjs +4 -0
  473. package/dist/slash/slashCommands.cjs.map +1 -0
  474. package/dist/slash/slashCommands.mjs +4 -0
  475. package/dist/slash/slashCommands.mjs.map +1 -0
  476. package/dist/slash/spawnRequestMapping.cjs +2 -0
  477. package/dist/slash/spawnRequestMapping.cjs.map +1 -0
  478. package/dist/slash/spawnRequestMapping.mjs +2 -0
  479. package/dist/slash/spawnRequestMapping.mjs.map +1 -0
  480. package/dist/slash/subagentLaunch.cjs +2 -0
  481. package/dist/slash/subagentLaunch.cjs.map +1 -0
  482. package/dist/slash/subagentLaunch.mjs +2 -0
  483. package/dist/slash/subagentLaunch.mjs.map +1 -0
  484. package/dist/tui/agentCatalog.cjs +2 -0
  485. package/dist/tui/agentCatalog.cjs.map +1 -0
  486. package/dist/tui/agentCatalog.mjs +2 -0
  487. package/dist/tui/agentCatalog.mjs.map +1 -0
  488. package/dist/tui/agentResourceProjection.cjs +2 -0
  489. package/dist/tui/agentResourceProjection.cjs.map +1 -0
  490. package/dist/tui/agentResourceProjection.mjs +2 -0
  491. package/dist/tui/agentResourceProjection.mjs.map +1 -0
  492. package/dist/tui/completionNotice.cjs +5 -0
  493. package/dist/tui/completionNotice.cjs.map +1 -0
  494. package/dist/tui/completionNotice.mjs +5 -0
  495. package/dist/tui/completionNotice.mjs.map +1 -0
  496. package/dist/tui/fleet.cjs +3 -0
  497. package/dist/tui/fleet.cjs.map +1 -0
  498. package/dist/tui/fleet.mjs +3 -0
  499. package/dist/tui/fleet.mjs.map +1 -0
  500. package/dist/tui/fleetAgentView.cjs +2 -0
  501. package/dist/tui/fleetAgentView.cjs.map +1 -0
  502. package/dist/tui/fleetAgentView.mjs +2 -0
  503. package/dist/tui/fleetAgentView.mjs.map +1 -0
  504. package/dist/tui/fleetStatus.cjs +2 -0
  505. package/dist/tui/fleetStatus.cjs.map +1 -0
  506. package/dist/tui/fleetStatus.mjs +2 -0
  507. package/dist/tui/fleetStatus.mjs.map +1 -0
  508. package/dist/tui/fleetTranscript.cjs +5 -0
  509. package/dist/tui/fleetTranscript.cjs.map +1 -0
  510. package/dist/tui/fleetTranscript.mjs +5 -0
  511. package/dist/tui/fleetTranscript.mjs.map +1 -0
  512. package/dist/tui/register.cjs +2 -0
  513. package/dist/tui/register.cjs.map +1 -0
  514. package/dist/tui/register.mjs +2 -0
  515. package/dist/tui/register.mjs.map +1 -0
  516. package/dist/types.d.cts +59 -0
  517. package/dist/types.d.cts.map +1 -0
  518. package/dist/types.d.mts +59 -0
  519. package/dist/types.d.mts.map +1 -0
  520. package/package.json +86 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fleetStatus.cjs","names":["TERMINAL_ASYNC_JOB_STATES"],"sources":["../../src/tui/fleetStatus.ts"],"sourcesContent":["import type { ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { FooterTextSegment } from '@agimon-ai/doompi-extension-contracts/footer';\nimport type { DoomFooterContributionValue } from '@agimon-ai/doompi-ui/footer';\nimport { agentIdentityColor } from '@agimon-ai/doompi-ui/theme';\n\nimport type { ActivityState } from '../types.ts';\nimport {\n TERMINAL_ASYNC_JOB_STATES,\n type ITrackedAsyncJobs,\n type TrackedAsyncJob,\n} from '../runs/background/asyncJobTracker.ts';\n\nexport const FLEET_STATUS_KEY = 'doom-team-agents';\nexport const AGENT_PULSE_FRAMES = ['◐', '●', '◑'] as const;\n\nconst FULL_PREFIX = 'Agents ';\nconst COMPACT_PREFIX = 'A ';\nconst FULL_TEXT_LIMIT = 80;\nconst COMPACT_TEXT_LIMIT = 24;\nconst ATTENTION_GLYPH = '!';\nconst WAITING_GLYPH = '○';\nconst COMPLETED_GLYPH = '✓';\nconst FAILED_GLYPH = '✗';\nconst STOPPED_GLYPH = '■';\nconst NEEDS_ATTENTION_STATE: ActivityState = 'needs_attention';\nconst COMPLETED_JOB_STATES: ReadonlySet<string> = new Set(['complete', 'completed']);\nconst STOPPED_JOB_STATES: ReadonlySet<string> = new Set(['paused', 'stopped']);\nconst FAILED_JOB_STATE = 'failed';\nconst PULSING_ACTIVITY_STATES: ReadonlySet<ActivityState> = new Set([\n 'working',\n 'tool',\n 'finalizing',\n 'active_long_running',\n]);\n\nexport interface AgentFleetStatus {\n text: string;\n footer: DoomFooterContributionValue;\n fingerprint: string;\n pulsing: boolean;\n}\n\ninterface AgentDot {\n glyph: string;\n color: ReturnType<typeof agentIdentityColor> | 'warning';\n}\n\nfunction stableOffset(value: string): number {\n let hash = 0;\n for (const character of value) hash = (Math.imul(hash, 31) + (character.codePointAt(0) ?? 0)) >>> 0;\n return hash % AGENT_PULSE_FRAMES.length;\n}\n\nfunction orderedAgents(tracker: ITrackedAsyncJobs): TrackedAsyncJob[] {\n return tracker\n .list()\n .toSorted(\n (left, right) =>\n (left.startedAt ?? Number.MAX_SAFE_INTEGER) - (right.startedAt ?? Number.MAX_SAFE_INTEGER) ||\n left.runId.localeCompare(right.runId),\n );\n}\n\nfunction activeAgents(tracker: ITrackedAsyncJobs): TrackedAsyncJob[] {\n return orderedAgents(tracker).filter((job) => !job.status || !TERMINAL_ASYNC_JOB_STATES.has(job.status));\n}\n\nfunction dotFor(job: TrackedAsyncJob, frame: number): AgentDot {\n const color = agentIdentityColor(job.runId);\n if (job.status && COMPLETED_JOB_STATES.has(job.status)) return { glyph: COMPLETED_GLYPH, color };\n if (job.status === FAILED_JOB_STATE) return { glyph: FAILED_GLYPH, color };\n if (job.status && STOPPED_JOB_STATES.has(job.status)) return { glyph: STOPPED_GLYPH, color };\n if (job.activityState === NEEDS_ATTENTION_STATE) return { glyph: ATTENTION_GLYPH, color: 'warning' };\n if (!job.activityState || !PULSING_ACTIVITY_STATES.has(job.activityState)) return { glyph: WAITING_GLYPH, color };\n return { glyph: AGENT_PULSE_FRAMES[(frame + stableOffset(job.runId)) % AGENT_PULSE_FRAMES.length]!, color };\n}\n\nfunction projectDots(\n jobs: readonly TrackedAsyncJob[],\n dots: readonly AgentDot[],\n prefix: string,\n limit: number,\n): { text: string; segments: FooterTextSegment[] } {\n const available = limit - prefix.length;\n let visibleCount = Math.min(jobs.length, available);\n let suffix = '';\n while (visibleCount < jobs.length) {\n suffix = `…+${jobs.length - visibleCount}`;\n if (visibleCount + suffix.length <= available) break;\n visibleCount -= 1;\n }\n const visibleDots = dots.slice(0, Math.max(0, visibleCount));\n const text = `${prefix}${visibleDots.map((dot) => dot.glyph).join('')}${suffix}`;\n return {\n text,\n segments: [\n { text: prefix },\n ...visibleDots.map((dot) => ({ text: dot.glyph, color: dot.color })),\n ...(suffix ? [{ text: suffix, color: 'dim' as const }] : []),\n ],\n };\n}\n\n/** Count only work that has not reached a terminal state. */\nexport function activeAgentCount(tracker: ITrackedAsyncJobs): number {\n return activeAgents(tracker).length;\n}\n\n/** Render one animation frame for both Pi's status and the Doom footer contribution. */\nexport function agentFleetStatus(tracker: ITrackedAsyncJobs, frame = 0): AgentFleetStatus | undefined {\n const jobs = orderedAgents(tracker);\n if (jobs.length === 0) return undefined;\n const dots = jobs.map((job) => dotFor(job, frame));\n const full = projectDots(jobs, dots, FULL_PREFIX, FULL_TEXT_LIMIT);\n const compact = projectDots(jobs, dots, COMPACT_PREFIX, COMPACT_TEXT_LIMIT);\n const pulsing = activeAgents(tracker).some(\n (job) => job.activityState !== undefined && PULSING_ACTIVITY_STATES.has(job.activityState),\n );\n return {\n text: full.text,\n footer: {\n fullText: full.text,\n compactText: compact.text,\n fullSegments: full.segments,\n compactSegments: compact.segments,\n },\n fingerprint: `${jobs.map((job) => `${job.runId}:${job.agent ?? ''}:${job.status ?? ''}:${job.activityState ?? ''}`).join('|')}:${pulsing ? frame : 'static'}`,\n pulsing,\n };\n}\n\n/** Compact footer text. An absent value removes the group entirely. */\nexport function agentStatusText(tracker: ITrackedAsyncJobs, frame = 0): string | undefined {\n return agentFleetStatus(tracker, frame)?.text;\n}\n\nexport function publishAgentStatus(ctx: ExtensionContext, tracker: ITrackedAsyncJobs, frame = 0): string | undefined {\n const text = agentStatusText(tracker, frame);\n if (ctx.hasUI) ctx.ui.setStatus(FLEET_STATUS_KEY, text);\n return text;\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{TERMINAL_ASYNC_JOB_STATES as e,init_asyncJobTracker as t}from"../runs/background/asyncJobTracker.mjs";import{agentIdentityColor as n}from"@agimon-ai/doompi-ui/theme";t();const r=`doom-team-agents`,i=[`◐`,`●`,`◑`],a=new Set([`complete`,`completed`]),o=new Set([`paused`,`stopped`]),s=new Set([`working`,`tool`,`finalizing`,`active_long_running`]);function c(e){let t=0;for(let n of e)t=Math.imul(t,31)+(n.codePointAt(0)??0)>>>0;return t%i.length}function l(e){return e.list().toSorted((e,t)=>(e.startedAt??2**53-1)-(t.startedAt??2**53-1)||e.runId.localeCompare(t.runId))}function u(t){return l(t).filter(t=>!t.status||!e.has(t.status))}function d(e,t){let r=n(e.runId);return e.status&&a.has(e.status)?{glyph:`✓`,color:r}:e.status===`failed`?{glyph:`✗`,color:r}:e.status&&o.has(e.status)?{glyph:`■`,color:r}:e.activityState===`needs_attention`?{glyph:`!`,color:`warning`}:!e.activityState||!s.has(e.activityState)?{glyph:`○`,color:r}:{glyph:i[(t+c(e.runId))%i.length],color:r}}function f(e,t,n,r){let i=r-n.length,a=Math.min(e.length,i),o=``;for(;a<e.length&&(o=`…+${e.length-a}`,!(a+o.length<=i));)--a;let s=t.slice(0,Math.max(0,a));return{text:`${n}${s.map(e=>e.glyph).join(``)}${o}`,segments:[{text:n},...s.map(e=>({text:e.glyph,color:e.color})),...o?[{text:o,color:`dim`}]:[]]}}function p(e,t=0){let n=l(e);if(n.length===0)return;let r=n.map(e=>d(e,t)),i=f(n,r,`Agents `,80),a=f(n,r,`A `,24),o=u(e).some(e=>e.activityState!==void 0&&s.has(e.activityState));return{text:i.text,footer:{fullText:i.text,compactText:a.text,fullSegments:i.segments,compactSegments:a.segments},fingerprint:`${n.map(e=>`${e.runId}:${e.agent??``}:${e.status??``}:${e.activityState??``}`).join(`|`)}:${o?t:`static`}`,pulsing:o}}export{i as AGENT_PULSE_FRAMES,r as FLEET_STATUS_KEY,p as agentFleetStatus};
2
+ //# sourceMappingURL=fleetStatus.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fleetStatus.mjs","names":[],"sources":["../../src/tui/fleetStatus.ts"],"sourcesContent":["import type { ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport type { FooterTextSegment } from '@agimon-ai/doompi-extension-contracts/footer';\nimport type { DoomFooterContributionValue } from '@agimon-ai/doompi-ui/footer';\nimport { agentIdentityColor } from '@agimon-ai/doompi-ui/theme';\n\nimport type { ActivityState } from '../types.ts';\nimport {\n TERMINAL_ASYNC_JOB_STATES,\n type ITrackedAsyncJobs,\n type TrackedAsyncJob,\n} from '../runs/background/asyncJobTracker.ts';\n\nexport const FLEET_STATUS_KEY = 'doom-team-agents';\nexport const AGENT_PULSE_FRAMES = ['◐', '●', '◑'] as const;\n\nconst FULL_PREFIX = 'Agents ';\nconst COMPACT_PREFIX = 'A ';\nconst FULL_TEXT_LIMIT = 80;\nconst COMPACT_TEXT_LIMIT = 24;\nconst ATTENTION_GLYPH = '!';\nconst WAITING_GLYPH = '○';\nconst COMPLETED_GLYPH = '✓';\nconst FAILED_GLYPH = '✗';\nconst STOPPED_GLYPH = '■';\nconst NEEDS_ATTENTION_STATE: ActivityState = 'needs_attention';\nconst COMPLETED_JOB_STATES: ReadonlySet<string> = new Set(['complete', 'completed']);\nconst STOPPED_JOB_STATES: ReadonlySet<string> = new Set(['paused', 'stopped']);\nconst FAILED_JOB_STATE = 'failed';\nconst PULSING_ACTIVITY_STATES: ReadonlySet<ActivityState> = new Set([\n 'working',\n 'tool',\n 'finalizing',\n 'active_long_running',\n]);\n\nexport interface AgentFleetStatus {\n text: string;\n footer: DoomFooterContributionValue;\n fingerprint: string;\n pulsing: boolean;\n}\n\ninterface AgentDot {\n glyph: string;\n color: ReturnType<typeof agentIdentityColor> | 'warning';\n}\n\nfunction stableOffset(value: string): number {\n let hash = 0;\n for (const character of value) hash = (Math.imul(hash, 31) + (character.codePointAt(0) ?? 0)) >>> 0;\n return hash % AGENT_PULSE_FRAMES.length;\n}\n\nfunction orderedAgents(tracker: ITrackedAsyncJobs): TrackedAsyncJob[] {\n return tracker\n .list()\n .toSorted(\n (left, right) =>\n (left.startedAt ?? Number.MAX_SAFE_INTEGER) - (right.startedAt ?? Number.MAX_SAFE_INTEGER) ||\n left.runId.localeCompare(right.runId),\n );\n}\n\nfunction activeAgents(tracker: ITrackedAsyncJobs): TrackedAsyncJob[] {\n return orderedAgents(tracker).filter((job) => !job.status || !TERMINAL_ASYNC_JOB_STATES.has(job.status));\n}\n\nfunction dotFor(job: TrackedAsyncJob, frame: number): AgentDot {\n const color = agentIdentityColor(job.runId);\n if (job.status && COMPLETED_JOB_STATES.has(job.status)) return { glyph: COMPLETED_GLYPH, color };\n if (job.status === FAILED_JOB_STATE) return { glyph: FAILED_GLYPH, color };\n if (job.status && STOPPED_JOB_STATES.has(job.status)) return { glyph: STOPPED_GLYPH, color };\n if (job.activityState === NEEDS_ATTENTION_STATE) return { glyph: ATTENTION_GLYPH, color: 'warning' };\n if (!job.activityState || !PULSING_ACTIVITY_STATES.has(job.activityState)) return { glyph: WAITING_GLYPH, color };\n return { glyph: AGENT_PULSE_FRAMES[(frame + stableOffset(job.runId)) % AGENT_PULSE_FRAMES.length]!, color };\n}\n\nfunction projectDots(\n jobs: readonly TrackedAsyncJob[],\n dots: readonly AgentDot[],\n prefix: string,\n limit: number,\n): { text: string; segments: FooterTextSegment[] } {\n const available = limit - prefix.length;\n let visibleCount = Math.min(jobs.length, available);\n let suffix = '';\n while (visibleCount < jobs.length) {\n suffix = `…+${jobs.length - visibleCount}`;\n if (visibleCount + suffix.length <= available) break;\n visibleCount -= 1;\n }\n const visibleDots = dots.slice(0, Math.max(0, visibleCount));\n const text = `${prefix}${visibleDots.map((dot) => dot.glyph).join('')}${suffix}`;\n return {\n text,\n segments: [\n { text: prefix },\n ...visibleDots.map((dot) => ({ text: dot.glyph, color: dot.color })),\n ...(suffix ? [{ text: suffix, color: 'dim' as const }] : []),\n ],\n };\n}\n\n/** Count only work that has not reached a terminal state. */\nexport function activeAgentCount(tracker: ITrackedAsyncJobs): number {\n return activeAgents(tracker).length;\n}\n\n/** Render one animation frame for both Pi's status and the Doom footer contribution. */\nexport function agentFleetStatus(tracker: ITrackedAsyncJobs, frame = 0): AgentFleetStatus | undefined {\n const jobs = orderedAgents(tracker);\n if (jobs.length === 0) return undefined;\n const dots = jobs.map((job) => dotFor(job, frame));\n const full = projectDots(jobs, dots, FULL_PREFIX, FULL_TEXT_LIMIT);\n const compact = projectDots(jobs, dots, COMPACT_PREFIX, COMPACT_TEXT_LIMIT);\n const pulsing = activeAgents(tracker).some(\n (job) => job.activityState !== undefined && PULSING_ACTIVITY_STATES.has(job.activityState),\n );\n return {\n text: full.text,\n footer: {\n fullText: full.text,\n compactText: compact.text,\n fullSegments: full.segments,\n compactSegments: compact.segments,\n },\n fingerprint: `${jobs.map((job) => `${job.runId}:${job.agent ?? ''}:${job.status ?? ''}:${job.activityState ?? ''}`).join('|')}:${pulsing ? frame : 'static'}`,\n pulsing,\n };\n}\n\n/** Compact footer text. An absent value removes the group entirely. */\nexport function agentStatusText(tracker: ITrackedAsyncJobs, frame = 0): string | undefined {\n return agentFleetStatus(tracker, frame)?.text;\n}\n\nexport function publishAgentStatus(ctx: ExtensionContext, tracker: ITrackedAsyncJobs, frame = 0): string | undefined {\n const text = agentStatusText(tracker, frame);\n if (ctx.hasUI) ctx.ui.setStatus(FLEET_STATUS_KEY, text);\n return text;\n}\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../shared/formatters.cjs`);let n=require(`node:fs`);n=e.__toESM(n,1);let r=require(`@earendil-works/pi-tui`);function i(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function a(e){let t=e.trim();if(t)try{let e=JSON.parse(t);return i(e)?e:void 0}catch{return}}function o(e){if(!Array.isArray(e))return;let t=[],n=[];for(let r of e){if(!r||typeof r!=`object`)continue;let e=r;if(e.type===`thinking`){let n=typeof e.thinking==`string`?e.thinking:``;n.trim()&&t.push(n);continue}e.type===`text`&&typeof e.text==`string`&&n.push(e.text)}return{thinking:t,text:n.join(`
2
+ `)}}function s(e){if(e)try{let t=JSON.parse(e);return i(t)?t:void 0}catch{return}}function c(e,t){return{path:e,events:[],byteOffset:0,size:0,toolCalls:new Map,firstDirtyIndex:void 0,droppedEvents:0,...t?{warning:t}:{}}}function l(e,t,r){let i=n.openSync(e,`r`);try{let e=Buffer.allocUnsafe(r),a=0;for(;a<r;){let o=n.readSync(i,e,a,r-a,t+a);if(o<=0)break;a+=o}return a===r?e:e.subarray(0,a)}finally{n.closeSync(i)}}function u(e,t){(e.firstDirtyIndex===void 0||t<e.firstDirtyIndex)&&(e.firstDirtyIndex=t)}function d(e,t){return e.events.push(t),e.events.length-1}function f(e){let t=e.events.length-1e3;if(!(t<=0)){e.events.splice(0,t),e.droppedEvents+=t,e.firstDirtyIndex!==void 0&&(e.firstDirtyIndex=Math.max(0,e.firstDirtyIndex-t));for(let[n,r]of e.toolCalls){let i=r.index-t;i<0?e.toolCalls.delete(n):r.index=i}}}function p(e,t){let n=t.ts??0;if(t.role===`toolResult`){let n=t.toolCallId?e.toolCalls.get(t.toolCallId):void 0;if(!n)return;n.event.result=t.text??``,n.event.resultTruncated=t.outputTruncated===!0,t.isError===!0&&(n.event.status=`error`),u(e,n.index);return}if(t.role===`user`){let r=t.text??``;r.trim()&&d(e,{kind:`user`,at:n,text:r});return}if(t.role===`assistant`){let r=o(t.message?.content);for(let t of r?.thinking??[])d(e,{kind:`thinking`,at:n,text:t});let i=r?r.text:t.text??``;i.trim()&&d(e,{kind:`assistant`,at:n,text:i,...t.model?{model:t.model}:{}});return}if(t.role===`custom`){let r=t.text??``;r.trim()&&d(e,{kind:`notice`,at:n,text:r})}}function m(e,t){let n=t.ts??0;if(t.recordType===`message`)return p(e,t);if(t.recordType===`tool_start`){let r=s(t.argsPayload),i={kind:`tool`,at:n,text:t.argsPreview??``,...t.toolName?{name:t.toolName}:{},status:`running`,...r?{args:r}:{}},a=d(e,i);t.toolCallId&&e.toolCalls.set(t.toolCallId,{event:i,index:a});return}if(t.recordType===`tool_end`){let r=t.toolCallId?e.toolCalls.get(t.toolCallId):void 0;if(r){r.event.status=t.isError===!0||r.event.status===`error`?`error`:`ok`,r.event.endedAt=n,u(e,r.index);return}d(e,{kind:`tool`,at:n,text:``,...t.toolName?{name:t.toolName}:{},status:t.isError===!0?`error`:`ok`});return}(t.recordType===`stdout`||t.recordType===`stderr`)&&d(e,{kind:t.recordType,at:n,text:t.text??``})}function h(e,t){let r;try{r=n.statSync(e).size}catch(t){return c(e,t instanceof Error?t.message:String(t))}let i=t!==void 0&&t.path===e&&t.warning===void 0&&r>=t.byteOffset?{...t,size:r,firstDirtyIndex:void 0,warning:void 0}:c(e);if(i.size=r,r<=i.byteOffset)return i;let o;try{o=l(e,i.byteOffset,r-i.byteOffset)}catch(e){return{...i,warning:e instanceof Error?e.message:String(e)}}let s=o.lastIndexOf(10),u=s===-1?void 0:o.subarray(0,s+1),d=o.subarray(s+1),p=d.length>0?a(d.toString(`utf-8`)):void 0;if(i.byteOffset+=(u?.length??0)+(p?d.length:0),!u&&!p)return i;for(let e of u?u.toString(`utf-8`).split(/\r?\n/):[]){let t=a(e);t&&m(i,t)}return p&&m(i,p),f(i),i}function g(e){let t=h(e);return t.warning?{events:t.events,warning:t.warning}:{events:t.events}}const _={user:8,thinking:6,notice:3,result:3},v=` ⎿ `,y=` `,b=[`command`,`pattern`,`query`,`queries`,`prompt`,`task`,`describe`,`workflow`,`url`,`urls`,`old_string`,`content`,`file_path`,`filePath`,`path`],x=[`path`,`file_path`,`filePath`];function S(e){return e===`ok`?`✓`:e===`error`?`✗`:`…`}function C(e){return e===`error`?`error`:e===`running`?`accent`:`muted`}function w(e,n){if(n){if(e===n)return`.`;let t=n.endsWith(`/`)?n:`${n}/`;if(e.startsWith(t))return e.slice(t.length)||`.`}return t.shortenPath(e)}function T(e,t){if(typeof e==`string`){let n=e.trim();if(!n)return;let r=n.replace(/\s+/g,` `);return r.startsWith(`/`)?w(r,t):r}if(Array.isArray(e)){let n=e.map(e=>T(e,t)).filter(e=>!!e);return n.length>0?n.join(`, `):void 0}}function E(e,t){let n=e.args;if(!n)return e.text?w(e.text,t):``;let r,i;for(let e of b){let a=T(n[e],t);if(a){r=e,i=a;break}}if(!i)for(let[e,a]of Object.entries(n)){let n=T(a,t);if(n){r=e,i=`${e}=${n}`;break}}if(!i)return``;let a=x.find(e=>e!==r&&typeof n[e]==`string`),o=a?T(n[a],t):void 0;return o&&o!==`.`?`${i} · ${o}`:i}function D(e,t,n,i){let a=(0,r.wrapTextWithAnsi)(e,Math.max(1,t));return a.length<=n?a.map(i):[...a.slice(0,n).map(i),i(`… +${a.length-n} lines`)]}function O(e,n,i,a){let o=E(e,a.cwd),s=e.endedAt===void 0?void 0:t.formatDuration(Math.max(0,e.endedAt-e.at)),c=[(0,r.truncateToWidth)([i.fg(C(e.status),S(e.status)),i.bold(e.name??`tool`),o?i.fg(`muted`,o):void 0,s?i.fg(`dim`,s):void 0].filter(e=>e!==void 0).join(` `),n)];if(a.verbosity===`full`&&e.args){let t=JSON.stringify(e.args,null,2);for(let e of t.split(`
3
+ `))c.push(i.fg(`dim`,(0,r.truncateToWidth)(`${y}${e}`,n)))}let l=e.result?.trimEnd();if(l){let t=a.verbosity===`full`?200:_.result,o=e.status===`error`?`error`:`dim`,s=l.split(`
4
+ `),u=s.slice(0,t);u.forEach((e,t)=>{let a=t===0?v:y;c.push(i.fg(o,(0,r.truncateToWidth)(`${a}${e}`,n)))});let d=s.length-u.length;d>0&&c.push(i.fg(`dim`,(0,r.truncateToWidth)(`${y}… +${d} lines`,n))),e.resultTruncated&&c.push(i.fg(`dim`,(0,r.truncateToWidth)(`${y}(output truncated by the recorder)`,n)))}else e.status===`running`&&c.push(i.fg(`dim`,(0,r.truncateToWidth)(`${v}running…`,n)));return c}function k(e,t,n,i,a){let o=Math.max(1,t);if(e.kind===`tool`)return[...O(e,o,n,a),``];if(e.kind===`assistant`)return[n.fg(`accent`,n.bold(`● assistant`)),...i?new r.Markdown(e.text,0,0,i).render(o):(0,r.wrapTextWithAnsi)(e.text,o),``];if(e.kind===`thinking`){let t=n.fg(`dim`,n.bold(`✻ thinking`)),r=a.verbosity===`full`?1/0:_.thinking;return[t,...D(e.text,o,r,e=>n.fg(`dim`,e)),``]}if(e.kind===`user`){let t=n.fg(`accent`,n.bold(`▸ user`)),r=a.verbosity===`full`?1/0:_.user;return[t,...D(e.text,o,r,e=>e),``]}if(e.kind===`notice`){let t=a.verbosity===`full`?1/0:_.notice;return[...D(`ℹ ${e.text}`,o,t,e=>n.fg(`muted`,e)),``]}return[(0,r.truncateToWidth)(`${e.kind===`stderr`?n.fg(`warning`,`stderr`):n.fg(`dim`,`stdout`)} ${e.text}`,o),``]}function A(e,t,n,i,a,o){let s=o!==void 0&&o.width===t&&o.verbosity===a.verbosity&&o.cwd===a.cwd&&o.droppedEvents<=e.droppedEvents;if(s&&o.droppedEvents===e.droppedEvents&&e.firstDirtyIndex===void 0&&o.blocks.length===e.events.length)return o;let c=s?o.blocks.slice(e.droppedEvents-o.droppedEvents):[],l=Math.min(e.firstDirtyIndex??c.length,c.length,e.events.length),u=c.slice(0,l);for(let r=l;r<e.events.length;r++)u.push(k(e.events[r],t,n,i,a));let d=[];e.droppedEvents>0&&d.push(n.fg(`dim`,(0,r.truncateToWidth)(`… ${e.droppedEvents} earlier events not shown`,t)),``);for(let e of u)d.push(...e);return{width:t,verbosity:a.verbosity,cwd:a.cwd,droppedEvents:e.droppedEvents,blocks:u,lines:d}}exports.readFleetTranscript=g,exports.readFleetTranscriptTail=h,exports.renderFleetTranscript=A;
5
+ //# sourceMappingURL=fleetTranscript.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fleetTranscript.cjs","names":["fs","shortenPath","formatDuration","Markdown"],"sources":["../../src/tui/fleetTranscript.ts"],"sourcesContent":["/**\n * Reads and renders a run's child transcript for the fleet detail pane.\n *\n * NOT A PORT:\n * The predecessor's `fleetTranscript.ts` parsed the HOST agent's own session\n * JSONL. `childTranscript.ts` (`../shared/childTranscript.ts`) is a\n * from-scratch, write-only format this package invented for its own reasons\n * (see that module's header: it is the parent's independent record, not the\n * host's session file). Translating the predecessor's parser would build a\n * reader for a format nothing here writes, so this reads `childTranscript.ts`'s\n * actual record shapes (`message`/`tool_start`/`tool_end`/`stdout`/`stderr`/\n * `truncated`) directly.\n *\n * READ THE RECORD, NOT THE SUMMARY:\n * `childTranscript.ts` flattens each message to a `text` field with\n * `extractTextFromContent`, which recognises only `{type:'text'}`. An assistant\n * turn made of a `thinking` block plus `toolCall` blocks therefore flattens to\n * nothing, and the writer omits the field entirely - which is what produced\n * rows of bare `assistant` headers with no content under them. The writer does\n * still persist the whole `message.content` array verbatim, so this module\n * parses THAT: thinking becomes its own event, and a turn with no text emits no\n * assistant event at all. Same reasoning for `argsPayload` (full tool arguments,\n * written all along, previously unread) and for `role: 'toolResult'` records,\n * which used to be dropped so a reader could see what ran but never what came\n * back.\n *\n * INCREMENTAL BY CONSTRUCTION:\n * A transcript is append-only and can reach 50 MiB, while the fleet overlay\n * re-checks the selected run roughly once a second. Re-reading and re-parsing\n * the whole file on every change makes cost grow with run length, so the reader\n * is resumable (`readFleetTranscriptTail`): it reads only the bytes appended\n * since the last call, and the renderer keeps one rendered block per event so\n * an append re-renders only the new and mutated ones. Steady-state cost is\n * proportional to what arrived, not to what the file holds.\n *\n * DESIGN PATTERNS:\n * - Reading is tolerant, not strict: the writer appends lines as a run\n * progresses, so the last line on disk may be a partial write mid-flush.\n * A line that fails to parse is dropped rather than failing the whole read\n * - `tool_start`/`tool_end`/`toolResult` are folded into ONE `tool` event keyed\n * by `toolCallId`, so the pane reads as a sequence of turns rather than three\n * lines per call. Calls interleave and `tool_end` arrives BEFORE its\n * `toolResult`, so the fold map retains an entry for as long as its event is\n * retained rather than closing it out on `tool_end`\n * - A `tool_end` with no matching start (the start fell outside the retained\n * window) still renders on its own rather than being dropped, since it is\n * still evidence of what ran\n *\n * AVOID:\n * - Reusing a `FleetTranscriptTail` after passing it as `previous`. The reader\n * takes ownership of its `events` and fold map instead of copying them, which\n * is the whole point of resuming; the returned tail supersedes it\n */\n\nimport * as fs from 'node:fs';\n\nimport { Markdown, truncateToWidth, wrapTextWithAnsi, type MarkdownTheme } from '@earendil-works/pi-tui';\n\nimport { formatDuration, shortenPath } from '../shared/formatters.ts';\n\nexport type FleetTranscriptEventKind = 'user' | 'assistant' | 'thinking' | 'tool' | 'notice' | 'stdout' | 'stderr';\n\nexport interface FleetTranscriptEvent {\n kind: FleetTranscriptEventKind;\n at: number;\n text: string;\n /** Tool name, present only for `kind: 'tool'`. */\n name?: string;\n /** Present only for `kind: 'tool'`: `'running'` until a matching `tool_end` arrives. */\n status?: 'running' | 'ok' | 'error';\n /** Tool arguments parsed from `argsPayload`, when the writer recorded them. */\n args?: Record<string, unknown>;\n /** Tool output, folded in from the matching `toolResult` record. */\n result?: string;\n /** Set when the writer bounded `result` at its payload cap. */\n resultTruncated?: boolean;\n /** `tool_end` timestamp, for the call's duration. */\n endedAt?: number;\n /** Model that produced an assistant turn, when reported. */\n model?: string;\n}\n\nexport interface FleetTranscript {\n events: FleetTranscriptEvent[];\n warning?: string;\n}\n\n/** One retained tool event and where it sits in `events`, so a later fold can mark it dirty. */\ninterface FleetTranscriptToolEntry {\n event: FleetTranscriptEvent;\n index: number;\n}\n\n/**\n * A resume point for `readFleetTranscriptTail`.\n *\n * `byteOffset` is deliberately the end of the last COMPLETE line rather than\n * the file size: a partial trailing line is left unconsumed so the next read\n * picks it up whole, instead of being dropped as unparseable the way a\n * whole-file read has to.\n */\nexport interface FleetTranscriptTail extends FleetTranscript {\n path: string;\n byteOffset: number;\n /** Size observed at this read. A later shrink means the file was replaced, forcing a full re-read. */\n size: number;\n toolCalls: Map<string, FleetTranscriptToolEntry>;\n /** Earliest index whose content changed in this read. Undefined when only appends happened. */\n firstDirtyIndex: number | undefined;\n /** Cumulative events dropped from the front by the retention cap. */\n droppedEvents: number;\n}\n\n/**\n * Retention cap. Bounds memory and worst-case render cost independently of how\n * long a run goes on; `droppedEvents` keeps the fact that a window was applied\n * visible, so a tail is never mistaken for a whole run.\n */\nexport const MAX_RETAINED_EVENTS = 1000;\n\nconst NEWLINE_BYTE = 0x0a;\n\ninterface RawRecord {\n recordType?: string;\n ts?: number;\n role?: string;\n text?: string;\n toolCallId?: string;\n toolName?: string;\n isError?: boolean;\n argsPreview?: string;\n argsPayload?: string;\n outputTruncated?: boolean;\n model?: string;\n message?: { role?: string; content?: unknown };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseLine(line: string): RawRecord | undefined {\n const trimmed = line.trim();\n if (!trimmed) return undefined;\n try {\n const parsed: unknown = JSON.parse(trimmed);\n return isRecord(parsed) ? (parsed as RawRecord) : undefined;\n } catch {\n // The writer appends line-by-line; a trailing partial write on the last\n // line is expected while a run is in flight, not evidence of corruption.\n return undefined;\n }\n}\n\n/**\n * Split an assistant turn's raw content into its thinking and its prose.\n *\n * Returns undefined when the record carried no content array, so the caller can\n * fall back to the writer's flattened `text` rather than treating a shape this\n * does not recognise as an empty turn.\n */\nfunction splitAssistantContent(content: unknown): { thinking: string[]; text: string } | undefined {\n if (!Array.isArray(content)) return undefined;\n const thinking: string[] = [];\n const texts: string[] = [];\n for (const part of content) {\n if (!part || typeof part !== 'object') continue;\n const record = part as Record<string, unknown>;\n if (record.type === 'thinking') {\n const value = typeof record.thinking === 'string' ? record.thinking : '';\n if (value.trim()) thinking.push(value);\n continue;\n }\n // Anything else - toolCall in particular - is represented by its own event,\n // so it must not be folded into the assistant turn's text.\n if (record.type === 'text' && typeof record.text === 'string') texts.push(record.text);\n }\n return { thinking, text: texts.join('\\n') };\n}\n\nfunction parseArgsPayload(payload: string | undefined): Record<string, unknown> | undefined {\n if (!payload) return undefined;\n try {\n const parsed: unknown = JSON.parse(payload);\n return isRecord(parsed) ? parsed : undefined;\n } catch {\n // The writer bounds this payload, so a long argument set can land here\n // truncated mid-JSON. The preview still renders; the args just stay absent.\n return undefined;\n }\n}\n\nfunction emptyTail(transcriptPath: string, warning?: string): FleetTranscriptTail {\n return {\n path: transcriptPath,\n events: [],\n byteOffset: 0,\n size: 0,\n toolCalls: new Map(),\n firstDirtyIndex: undefined,\n droppedEvents: 0,\n ...(warning ? { warning } : {}),\n };\n}\n\n/** Read exactly the appended range, so cost tracks what arrived rather than what the file holds. */\nfunction readRange(filePath: string, offset: number, length: number): Buffer {\n const handle = fs.openSync(filePath, 'r');\n try {\n const buffer = Buffer.allocUnsafe(length);\n let read = 0;\n while (read < length) {\n const chunk = fs.readSync(handle, buffer, read, length - read, offset + read);\n if (chunk <= 0) break;\n read += chunk;\n }\n return read === length ? buffer : buffer.subarray(0, read);\n } finally {\n fs.closeSync(handle);\n }\n}\n\nfunction markDirty(tail: FleetTranscriptTail, index: number): void {\n if (tail.firstDirtyIndex === undefined || index < tail.firstDirtyIndex) tail.firstDirtyIndex = index;\n}\n\nfunction pushEvent(tail: FleetTranscriptTail, event: FleetTranscriptEvent): number {\n tail.events.push(event);\n return tail.events.length - 1;\n}\n\n/** Apply the retention cap, keeping every index that survives it consistent. */\nfunction applyRetention(tail: FleetTranscriptTail): void {\n const excess = tail.events.length - MAX_RETAINED_EVENTS;\n if (excess <= 0) return;\n tail.events.splice(0, excess);\n tail.droppedEvents += excess;\n if (tail.firstDirtyIndex !== undefined) tail.firstDirtyIndex = Math.max(0, tail.firstDirtyIndex - excess);\n for (const [callId, entry] of tail.toolCalls) {\n const shifted = entry.index - excess;\n if (shifted < 0) tail.toolCalls.delete(callId);\n else entry.index = shifted;\n }\n}\n\nfunction consumeMessage(tail: FleetTranscriptTail, record: RawRecord): void {\n const at = record.ts ?? 0;\n if (record.role === 'toolResult') {\n const entry = record.toolCallId ? tail.toolCalls.get(record.toolCallId) : undefined;\n // A result whose call fell outside the retained window has nothing to\n // attach to; the call itself is already gone, so the output would be\n // unattributable rather than useful.\n if (!entry) return;\n entry.event.result = record.text ?? '';\n entry.event.resultTruncated = record.outputTruncated === true;\n if (record.isError === true) entry.event.status = 'error';\n markDirty(tail, entry.index);\n return;\n }\n if (record.role === 'user') {\n const text = record.text ?? '';\n if (text.trim()) pushEvent(tail, { kind: 'user', at, text });\n return;\n }\n if (record.role === 'assistant') {\n const parts = splitAssistantContent(record.message?.content);\n for (const thinking of parts?.thinking ?? []) pushEvent(tail, { kind: 'thinking', at, text: thinking });\n const text = parts ? parts.text : (record.text ?? '');\n // A turn that only thought and called tools has no prose of its own. Both\n // are already represented, so emitting a header for it says nothing.\n if (text.trim()) {\n pushEvent(tail, { kind: 'assistant', at, text, ...(record.model ? { model: record.model } : {}) });\n }\n return;\n }\n if (record.role === 'custom') {\n // Host-injected notices (skill suggestions, hook output) are part of what\n // the child was told, so they belong in the transcript rather than nowhere.\n const text = record.text ?? '';\n if (text.trim()) pushEvent(tail, { kind: 'notice', at, text });\n }\n}\n\nfunction consumeRecord(tail: FleetTranscriptTail, record: RawRecord): void {\n const at = record.ts ?? 0;\n if (record.recordType === 'message') return consumeMessage(tail, record);\n if (record.recordType === 'tool_start') {\n const args = parseArgsPayload(record.argsPayload);\n const event: FleetTranscriptEvent = {\n kind: 'tool',\n at,\n text: record.argsPreview ?? '',\n ...(record.toolName ? { name: record.toolName } : {}),\n status: 'running',\n ...(args ? { args } : {}),\n };\n const index = pushEvent(tail, event);\n if (record.toolCallId) tail.toolCalls.set(record.toolCallId, { event, index });\n return;\n }\n if (record.recordType === 'tool_end') {\n const entry = record.toolCallId ? tail.toolCalls.get(record.toolCallId) : undefined;\n if (entry) {\n // An error reported by either half of the call is the call's outcome.\n entry.event.status = record.isError === true || entry.event.status === 'error' ? 'error' : 'ok';\n entry.event.endedAt = at;\n markDirty(tail, entry.index);\n return;\n }\n pushEvent(tail, {\n kind: 'tool',\n at,\n text: '',\n ...(record.toolName ? { name: record.toolName } : {}),\n status: record.isError === true ? 'error' : 'ok',\n });\n return;\n }\n if (record.recordType === 'stdout' || record.recordType === 'stderr') {\n pushEvent(tail, { kind: record.recordType, at, text: record.text ?? '' });\n }\n // 'truncated' carries no displayable content of its own; the events\n // recorded before it already show what happened up to the cutoff.\n}\n\n/**\n * Read whatever has been appended since `previous`, or the whole file when no\n * resume point is given.\n *\n * Never throws: a missing or unreadable file is a normal state (the run has\n * not started writing yet, or was cleaned up), reported through `warning`\n * rather than an exception the caller would have to guard against.\n */\nexport function readFleetTranscriptTail(transcriptPath: string, previous?: FleetTranscriptTail): FleetTranscriptTail {\n let size: number;\n try {\n size = fs.statSync(transcriptPath).size;\n } catch (cause) {\n return emptyTail(transcriptPath, cause instanceof Error ? cause.message : String(cause));\n }\n\n // A shrink means the file was replaced rather than appended to, so nothing\n // parsed from the old one can be trusted to still describe it.\n const resumable =\n previous !== undefined &&\n previous.path === transcriptPath &&\n previous.warning === undefined &&\n size >= previous.byteOffset;\n\n const tail: FleetTranscriptTail = resumable\n ? { ...previous, size, firstDirtyIndex: undefined, warning: undefined }\n : emptyTail(transcriptPath);\n tail.size = size;\n if (size <= tail.byteOffset) return tail;\n\n let chunk: Buffer;\n try {\n chunk = readRange(transcriptPath, tail.byteOffset, size - tail.byteOffset);\n } catch (cause) {\n return { ...tail, warning: cause instanceof Error ? cause.message : String(cause) };\n }\n\n // Split at the last newline: 0x0A cannot occur inside a UTF-8 multi-byte\n // sequence, so this is a byte boundary that is also a character boundary.\n const lastNewline = chunk.lastIndexOf(NEWLINE_BYTE);\n const complete = lastNewline === -1 ? undefined : chunk.subarray(0, lastNewline + 1);\n const remainder = chunk.subarray(lastNewline + 1);\n\n // A trailing line with no newline after it is ambiguous: either a write\n // caught mid-flush, or simply the last record of a file the writer did not\n // terminate. Parsing decides - a half-written record cannot be valid JSON,\n // since it is missing its closing brace - so a complete record is never\n // withheld just because nothing followed it, and a partial one is left\n // unconsumed for the next read to pick up whole.\n const pending = remainder.length > 0 ? parseLine(remainder.toString('utf-8')) : undefined;\n tail.byteOffset += (complete?.length ?? 0) + (pending ? remainder.length : 0);\n if (!complete && !pending) return tail;\n\n for (const line of complete ? complete.toString('utf-8').split(/\\r?\\n/) : []) {\n const record = parseLine(line);\n if (record) consumeRecord(tail, record);\n }\n if (pending) consumeRecord(tail, pending);\n applyRetention(tail);\n return tail;\n}\n\n/** Whole-file read, for callers with no incremental state to keep. */\nexport function readFleetTranscript(transcriptPath: string): FleetTranscript {\n const tail = readFleetTranscriptTail(transcriptPath);\n return tail.warning ? { events: tail.events, warning: tail.warning } : { events: tail.events };\n}\n\n// ============================================================================\n// Rendering\n// ============================================================================\n\nexport type FleetTranscriptVerbosity = 'compact' | 'full';\n\nexport interface FleetTranscriptTheme {\n fg(color: string, text: string): string;\n bold(text: string): string;\n}\n\n/**\n * What the renderer needs from a tail: the events, and the two facts that say\n * which rendered blocks are still valid. Deliberately narrower than\n * `FleetTranscriptTail` so rendering does not depend on the reader's file\n * bookkeeping.\n */\nexport type FleetTranscriptRenderable = Pick<FleetTranscriptTail, 'events' | 'firstDirtyIndex' | 'droppedEvents'>;\n\nexport interface FleetTranscriptRenderOptions {\n /** Run cwd, so absolute paths render as the part that actually differs between rows. */\n cwd?: string;\n verbosity: FleetTranscriptVerbosity;\n}\n\n/**\n * One rendered block per event, plus their flattened lines.\n *\n * Blocks are kept so an append re-renders only what changed: markdown is by far\n * the most expensive part of this module, and an assistant message's rendering\n * never changes once written.\n */\nexport interface FleetTranscriptRender {\n width: number;\n verbosity: FleetTranscriptVerbosity;\n cwd: string | undefined;\n droppedEvents: number;\n blocks: string[][];\n lines: string[];\n}\n\nconst COMPACT_LINES: Record<'user' | 'thinking' | 'notice' | 'result', number> = {\n user: 8,\n thinking: 6,\n notice: 3,\n result: 3,\n};\n/** Even expanded, one 32 KiB tool result must not be able to bury the pane. */\nconst FULL_RESULT_LINES = 200;\nconst RESULT_GUTTER = ' ⎿ ';\nconst RESULT_CONTINUATION = ' ';\n\n/** Keys that identify what a call actually did, ahead of the ones every call shares. */\nconst PRIMARY_ARG_KEYS = [\n 'command',\n 'pattern',\n 'query',\n 'queries',\n 'prompt',\n 'task',\n 'describe',\n 'workflow',\n 'url',\n 'urls',\n 'old_string',\n 'content',\n 'file_path',\n 'filePath',\n 'path',\n];\nconst PATH_ARG_KEYS = ['path', 'file_path', 'filePath'];\n\nfunction statusGlyph(status: FleetTranscriptEvent['status']): string {\n if (status === 'ok') return '✓';\n if (status === 'error') return '✗';\n return '…';\n}\n\nfunction statusColor(status: FleetTranscriptEvent['status']): string {\n if (status === 'error') return 'error';\n if (status === 'running') return 'accent';\n return 'muted';\n}\n\n/**\n * Render a path as the part that distinguishes it.\n *\n * Every row in a single run shares the run's cwd as a prefix, so keeping it\n * costs the width that would otherwise show which file was touched.\n */\nfunction displayPath(value: string, cwd?: string): string {\n if (cwd) {\n if (value === cwd) return '.';\n const prefix = cwd.endsWith('/') ? cwd : `${cwd}/`;\n if (value.startsWith(prefix)) return value.slice(prefix.length) || '.';\n }\n return shortenPath(value);\n}\n\nfunction argToDisplay(value: unknown, cwd?: string): string | undefined {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const collapsed = trimmed.replace(/\\s+/g, ' ');\n return collapsed.startsWith('/') ? displayPath(collapsed, cwd) : collapsed;\n }\n if (Array.isArray(value)) {\n const parts = value.map((entry) => argToDisplay(entry, cwd)).filter((entry): entry is string => Boolean(entry));\n return parts.length > 0 ? parts.join(', ') : undefined;\n }\n return undefined;\n}\n\n/**\n * The call's headline arguments.\n *\n * Prefers the distinguishing argument over the shared one, then appends the\n * path when it was not already the headline - `grep` reads as\n * `pattern · where`, `read` as just the file.\n */\nfunction toolArgsSummary(event: FleetTranscriptEvent, cwd?: string): string {\n const args = event.args;\n if (!args) return event.text ? displayPath(event.text, cwd) : '';\n let primaryKey: string | undefined;\n let primary: string | undefined;\n for (const key of PRIMARY_ARG_KEYS) {\n const display = argToDisplay(args[key], cwd);\n if (display) {\n primaryKey = key;\n primary = display;\n break;\n }\n }\n if (!primary) {\n for (const [key, value] of Object.entries(args)) {\n const display = argToDisplay(value, cwd);\n if (display) {\n primaryKey = key;\n primary = `${key}=${display}`;\n break;\n }\n }\n }\n if (!primary) return '';\n const pathKey = PATH_ARG_KEYS.find((key) => key !== primaryKey && typeof args[key] === 'string');\n const pathDisplay = pathKey ? argToDisplay(args[pathKey], cwd) : undefined;\n // A path that relativizes to the run's own cwd says nothing the pane does\n // not already know, and every such row would carry the same '.'.\n return pathDisplay && pathDisplay !== '.' ? `${primary} · ${pathDisplay}` : primary;\n}\n\n/** Wrap to `width`, capped, with the number of hidden lines stated rather than implied. */\nfunction cappedLines(text: string, width: number, limit: number, decorate: (line: string) => string): string[] {\n const wrapped = wrapTextWithAnsi(text, Math.max(1, width));\n if (wrapped.length <= limit) return wrapped.map(decorate);\n return [...wrapped.slice(0, limit).map(decorate), decorate(`… +${wrapped.length - limit} lines`)];\n}\n\nfunction renderToolEvent(\n event: FleetTranscriptEvent,\n width: number,\n theme: FleetTranscriptTheme,\n options: FleetTranscriptRenderOptions,\n): string[] {\n const summary = toolArgsSummary(event, options.cwd);\n const duration = event.endedAt !== undefined ? formatDuration(Math.max(0, event.endedAt - event.at)) : undefined;\n const header = [\n theme.fg(statusColor(event.status), statusGlyph(event.status)),\n theme.bold(event.name ?? 'tool'),\n summary ? theme.fg('muted', summary) : undefined,\n duration ? theme.fg('dim', duration) : undefined,\n ]\n .filter((part): part is string => part !== undefined)\n .join(' ');\n const lines = [truncateToWidth(header, width)];\n\n if (options.verbosity === 'full' && event.args) {\n const pretty = JSON.stringify(event.args, null, 2);\n for (const line of pretty.split('\\n')) {\n lines.push(theme.fg('dim', truncateToWidth(`${RESULT_CONTINUATION}${line}`, width)));\n }\n }\n\n const result = event.result?.trimEnd();\n if (result) {\n const limit = options.verbosity === 'full' ? FULL_RESULT_LINES : COMPACT_LINES.result;\n const color = event.status === 'error' ? 'error' : 'dim';\n const body = result.split('\\n');\n const shown = body.slice(0, limit);\n shown.forEach((line, index) => {\n const prefix = index === 0 ? RESULT_GUTTER : RESULT_CONTINUATION;\n lines.push(theme.fg(color, truncateToWidth(`${prefix}${line}`, width)));\n });\n const hidden = body.length - shown.length;\n if (hidden > 0) lines.push(theme.fg('dim', truncateToWidth(`${RESULT_CONTINUATION}… +${hidden} lines`, width)));\n if (event.resultTruncated) {\n lines.push(theme.fg('dim', truncateToWidth(`${RESULT_CONTINUATION}(output truncated by the recorder)`, width)));\n }\n } else if (event.status === 'running') {\n lines.push(theme.fg('dim', truncateToWidth(`${RESULT_GUTTER}running…`, width)));\n }\n return lines;\n}\n\nfunction renderEvent(\n event: FleetTranscriptEvent,\n width: number,\n theme: FleetTranscriptTheme,\n markdownTheme: MarkdownTheme | undefined,\n options: FleetTranscriptRenderOptions,\n): string[] {\n const safeWidth = Math.max(1, width);\n if (event.kind === 'tool') return [...renderToolEvent(event, safeWidth, theme, options), ''];\n\n if (event.kind === 'assistant') {\n const header = theme.fg('accent', theme.bold('● assistant'));\n // Markdown is the expensive call in this module; the block cache is what\n // keeps it to once per message rather than once per repaint.\n const body = markdownTheme\n ? new Markdown(event.text, 0, 0, markdownTheme).render(safeWidth)\n : wrapTextWithAnsi(event.text, safeWidth);\n return [header, ...body, ''];\n }\n\n if (event.kind === 'thinking') {\n const header = theme.fg('dim', theme.bold('✻ thinking'));\n const limit = options.verbosity === 'full' ? Number.POSITIVE_INFINITY : COMPACT_LINES.thinking;\n return [header, ...cappedLines(event.text, safeWidth, limit, (line) => theme.fg('dim', line)), ''];\n }\n\n if (event.kind === 'user') {\n const header = theme.fg('accent', theme.bold('▸ user'));\n const limit = options.verbosity === 'full' ? Number.POSITIVE_INFINITY : COMPACT_LINES.user;\n return [header, ...cappedLines(event.text, safeWidth, limit, (line) => line), ''];\n }\n\n if (event.kind === 'notice') {\n const limit = options.verbosity === 'full' ? Number.POSITIVE_INFINITY : COMPACT_LINES.notice;\n return [...cappedLines(`ℹ ${event.text}`, safeWidth, limit, (line) => theme.fg('muted', line)), ''];\n }\n\n const prefix = event.kind === 'stderr' ? theme.fg('warning', 'stderr') : theme.fg('dim', 'stdout');\n return [truncateToWidth(`${prefix} ${event.text}`, safeWidth), ''];\n}\n\n/**\n * Render `tail`'s events, reusing `previous`'s blocks wherever nothing changed.\n *\n * A full render happens only when something global changed - width, verbosity,\n * cwd, or the absence of a usable previous render. An append re-renders from\n * the earliest dirty index onward and reuses every block before it.\n */\nexport function renderFleetTranscript(\n tail: FleetTranscriptRenderable,\n width: number,\n theme: FleetTranscriptTheme,\n markdownTheme: MarkdownTheme | undefined,\n options: FleetTranscriptRenderOptions,\n previous?: FleetTranscriptRender,\n): FleetTranscriptRender {\n const reusable =\n previous !== undefined &&\n previous.width === width &&\n previous.verbosity === options.verbosity &&\n previous.cwd === options.cwd &&\n previous.droppedEvents <= tail.droppedEvents;\n\n // Nothing changed at all: hand back the same render rather than rebuilding\n // a flat line array out of blocks that are all still valid. This is the\n // common case - every repaint driven by a keystroke or an unrelated run -\n // and without it the pane still pays a cost proportional to the whole\n // transcript on each one.\n if (\n reusable &&\n previous.droppedEvents === tail.droppedEvents &&\n tail.firstDirtyIndex === undefined &&\n previous.blocks.length === tail.events.length\n ) {\n return previous;\n }\n\n // Retention drops events off the front, so a reused block list has to be\n // realigned by however many went before it can be indexed alongside events.\n const base = reusable ? previous.blocks.slice(tail.droppedEvents - previous.droppedEvents) : [];\n const from = Math.min(tail.firstDirtyIndex ?? base.length, base.length, tail.events.length);\n const blocks = base.slice(0, from);\n for (let index = from; index < tail.events.length; index++) {\n blocks.push(renderEvent(tail.events[index], width, theme, markdownTheme, options));\n }\n\n const lines: string[] = [];\n if (tail.droppedEvents > 0) {\n lines.push(theme.fg('dim', truncateToWidth(`… ${tail.droppedEvents} earlier events not shown`, width)), '');\n }\n for (const block of blocks) lines.push(...block);\n return { width, verbosity: options.verbosity, cwd: options.cwd, droppedEvents: tail.droppedEvents, blocks, lines };\n}\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import{__esmMin as e}from"../_virtual/_rolldown/runtime.mjs";import{formatDuration as t,init_formatters as n,shortenPath as r}from"../shared/formatters.mjs";import*as i from"node:fs";import{Markdown as a,truncateToWidth as o,wrapTextWithAnsi as s}from"@earendil-works/pi-tui";function c(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function l(e){let t=e.trim();if(t)try{let e=JSON.parse(t);return c(e)?e:void 0}catch{return}}function u(e){if(!Array.isArray(e))return;let t=[],n=[];for(let r of e){if(!r||typeof r!=`object`)continue;let e=r;if(e.type===`thinking`){let n=typeof e.thinking==`string`?e.thinking:``;n.trim()&&t.push(n);continue}e.type===`text`&&typeof e.text==`string`&&n.push(e.text)}return{thinking:t,text:n.join(`
2
+ `)}}function d(e){if(e)try{let t=JSON.parse(e);return c(t)?t:void 0}catch{return}}function f(e,t){return{path:e,events:[],byteOffset:0,size:0,toolCalls:new Map,firstDirtyIndex:void 0,droppedEvents:0,...t?{warning:t}:{}}}function p(e,t,n){let r=i.openSync(e,`r`);try{let e=Buffer.allocUnsafe(n),a=0;for(;a<n;){let o=i.readSync(r,e,a,n-a,t+a);if(o<=0)break;a+=o}return a===n?e:e.subarray(0,a)}finally{i.closeSync(r)}}function m(e,t){(e.firstDirtyIndex===void 0||t<e.firstDirtyIndex)&&(e.firstDirtyIndex=t)}function h(e,t){return e.events.push(t),e.events.length-1}function g(e){let t=e.events.length-A;if(!(t<=0)){e.events.splice(0,t),e.droppedEvents+=t,e.firstDirtyIndex!==void 0&&(e.firstDirtyIndex=Math.max(0,e.firstDirtyIndex-t));for(let[n,r]of e.toolCalls){let i=r.index-t;i<0?e.toolCalls.delete(n):r.index=i}}}function _(e,t){let n=t.ts??0;if(t.role===`toolResult`){let n=t.toolCallId?e.toolCalls.get(t.toolCallId):void 0;if(!n)return;n.event.result=t.text??``,n.event.resultTruncated=t.outputTruncated===!0,t.isError===!0&&(n.event.status=`error`),m(e,n.index);return}if(t.role===`user`){let r=t.text??``;r.trim()&&h(e,{kind:`user`,at:n,text:r});return}if(t.role===`assistant`){let r=u(t.message?.content);for(let t of r?.thinking??[])h(e,{kind:`thinking`,at:n,text:t});let i=r?r.text:t.text??``;i.trim()&&h(e,{kind:`assistant`,at:n,text:i,...t.model?{model:t.model}:{}});return}if(t.role===`custom`){let r=t.text??``;r.trim()&&h(e,{kind:`notice`,at:n,text:r})}}function v(e,t){let n=t.ts??0;if(t.recordType===`message`)return _(e,t);if(t.recordType===`tool_start`){let r=d(t.argsPayload),i={kind:`tool`,at:n,text:t.argsPreview??``,...t.toolName?{name:t.toolName}:{},status:`running`,...r?{args:r}:{}},a=h(e,i);t.toolCallId&&e.toolCalls.set(t.toolCallId,{event:i,index:a});return}if(t.recordType===`tool_end`){let r=t.toolCallId?e.toolCalls.get(t.toolCallId):void 0;if(r){r.event.status=t.isError===!0||r.event.status===`error`?`error`:`ok`,r.event.endedAt=n,m(e,r.index);return}h(e,{kind:`tool`,at:n,text:``,...t.toolName?{name:t.toolName}:{},status:t.isError===!0?`error`:`ok`});return}(t.recordType===`stdout`||t.recordType===`stderr`)&&h(e,{kind:t.recordType,at:n,text:t.text??``})}function y(e,t){let n;try{n=i.statSync(e).size}catch(t){return f(e,t instanceof Error?t.message:String(t))}let r=t!==void 0&&t.path===e&&t.warning===void 0&&n>=t.byteOffset?{...t,size:n,firstDirtyIndex:void 0,warning:void 0}:f(e);if(r.size=n,n<=r.byteOffset)return r;let a;try{a=p(e,r.byteOffset,n-r.byteOffset)}catch(e){return{...r,warning:e instanceof Error?e.message:String(e)}}let o=a.lastIndexOf(j),s=o===-1?void 0:a.subarray(0,o+1),c=a.subarray(o+1),u=c.length>0?l(c.toString(`utf-8`)):void 0;if(r.byteOffset+=(s?.length??0)+(u?c.length:0),!s&&!u)return r;for(let e of s?s.toString(`utf-8`).split(/\r?\n/):[]){let t=l(e);t&&v(r,t)}return u&&v(r,u),g(r),r}function b(e){let t=y(e);return t.warning?{events:t.events,warning:t.warning}:{events:t.events}}function x(e){return e===`ok`?`✓`:e===`error`?`✗`:`…`}function S(e){return e===`error`?`error`:e===`running`?`accent`:`muted`}function C(e,t){if(t){if(e===t)return`.`;let n=t.endsWith(`/`)?t:`${t}/`;if(e.startsWith(n))return e.slice(n.length)||`.`}return r(e)}function w(e,t){if(typeof e==`string`){let n=e.trim();if(!n)return;let r=n.replace(/\s+/g,` `);return r.startsWith(`/`)?C(r,t):r}if(Array.isArray(e)){let n=e.map(e=>w(e,t)).filter(e=>!!e);return n.length>0?n.join(`, `):void 0}}function T(e,t){let n=e.args;if(!n)return e.text?C(e.text,t):``;let r,i;for(let e of I){let a=w(n[e],t);if(a){r=e,i=a;break}}if(!i)for(let[e,a]of Object.entries(n)){let n=w(a,t);if(n){r=e,i=`${e}=${n}`;break}}if(!i)return``;let a=L.find(e=>e!==r&&typeof n[e]==`string`),o=a?w(n[a],t):void 0;return o&&o!==`.`?`${i} · ${o}`:i}function E(e,t,n,r){let i=s(e,Math.max(1,t));return i.length<=n?i.map(r):[...i.slice(0,n).map(r),r(`… +${i.length-n} lines`)]}function D(e,n,r,i){let a=T(e,i.cwd),s=e.endedAt===void 0?void 0:t(Math.max(0,e.endedAt-e.at)),c=[o([r.fg(S(e.status),x(e.status)),r.bold(e.name??`tool`),a?r.fg(`muted`,a):void 0,s?r.fg(`dim`,s):void 0].filter(e=>e!==void 0).join(` `),n)];if(i.verbosity===`full`&&e.args){let t=JSON.stringify(e.args,null,2);for(let e of t.split(`
3
+ `))c.push(r.fg(`dim`,o(`${F}${e}`,n)))}let l=e.result?.trimEnd();if(l){let t=i.verbosity===`full`?N:M.result,a=e.status===`error`?`error`:`dim`,s=l.split(`
4
+ `),u=s.slice(0,t);u.forEach((e,t)=>{let i=t===0?P:F;c.push(r.fg(a,o(`${i}${e}`,n)))});let d=s.length-u.length;d>0&&c.push(r.fg(`dim`,o(`${F}… +${d} lines`,n))),e.resultTruncated&&c.push(r.fg(`dim`,o(`${F}(output truncated by the recorder)`,n)))}else e.status===`running`&&c.push(r.fg(`dim`,o(`${P}running…`,n)));return c}function O(e,t,n,r,i){let c=Math.max(1,t);if(e.kind===`tool`)return[...D(e,c,n,i),``];if(e.kind===`assistant`)return[n.fg(`accent`,n.bold(`● assistant`)),...r?new a(e.text,0,0,r).render(c):s(e.text,c),``];if(e.kind===`thinking`){let t=n.fg(`dim`,n.bold(`✻ thinking`)),r=i.verbosity===`full`?1/0:M.thinking;return[t,...E(e.text,c,r,e=>n.fg(`dim`,e)),``]}if(e.kind===`user`){let t=n.fg(`accent`,n.bold(`▸ user`)),r=i.verbosity===`full`?1/0:M.user;return[t,...E(e.text,c,r,e=>e),``]}if(e.kind===`notice`){let t=i.verbosity===`full`?1/0:M.notice;return[...E(`ℹ ${e.text}`,c,t,e=>n.fg(`muted`,e)),``]}return[o(`${e.kind===`stderr`?n.fg(`warning`,`stderr`):n.fg(`dim`,`stdout`)} ${e.text}`,c),``]}function k(e,t,n,r,i,a){let s=a!==void 0&&a.width===t&&a.verbosity===i.verbosity&&a.cwd===i.cwd&&a.droppedEvents<=e.droppedEvents;if(s&&a.droppedEvents===e.droppedEvents&&e.firstDirtyIndex===void 0&&a.blocks.length===e.events.length)return a;let c=s?a.blocks.slice(e.droppedEvents-a.droppedEvents):[],l=Math.min(e.firstDirtyIndex??c.length,c.length,e.events.length),u=c.slice(0,l);for(let a=l;a<e.events.length;a++)u.push(O(e.events[a],t,n,r,i));let d=[];e.droppedEvents>0&&d.push(n.fg(`dim`,o(`… ${e.droppedEvents} earlier events not shown`,t)),``);for(let e of u)d.push(...e);return{width:t,verbosity:i.verbosity,cwd:i.cwd,droppedEvents:e.droppedEvents,blocks:u,lines:d}}var A,j,M,N,P,F,I,L,R=e((()=>{n(),A=1e3,j=10,M={user:8,thinking:6,notice:3,result:3},N=200,P=` ⎿ `,F=` `,I=[`command`,`pattern`,`query`,`queries`,`prompt`,`task`,`describe`,`workflow`,`url`,`urls`,`old_string`,`content`,`file_path`,`filePath`,`path`],L=[`path`,`file_path`,`filePath`]}));R();export{R as init_fleetTranscript,b as readFleetTranscript,y as readFleetTranscriptTail,k as renderFleetTranscript};
5
+ //# sourceMappingURL=fleetTranscript.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fleetTranscript.mjs","names":[],"sources":["../../src/tui/fleetTranscript.ts"],"sourcesContent":["/**\n * Reads and renders a run's child transcript for the fleet detail pane.\n *\n * NOT A PORT:\n * The predecessor's `fleetTranscript.ts` parsed the HOST agent's own session\n * JSONL. `childTranscript.ts` (`../shared/childTranscript.ts`) is a\n * from-scratch, write-only format this package invented for its own reasons\n * (see that module's header: it is the parent's independent record, not the\n * host's session file). Translating the predecessor's parser would build a\n * reader for a format nothing here writes, so this reads `childTranscript.ts`'s\n * actual record shapes (`message`/`tool_start`/`tool_end`/`stdout`/`stderr`/\n * `truncated`) directly.\n *\n * READ THE RECORD, NOT THE SUMMARY:\n * `childTranscript.ts` flattens each message to a `text` field with\n * `extractTextFromContent`, which recognises only `{type:'text'}`. An assistant\n * turn made of a `thinking` block plus `toolCall` blocks therefore flattens to\n * nothing, and the writer omits the field entirely - which is what produced\n * rows of bare `assistant` headers with no content under them. The writer does\n * still persist the whole `message.content` array verbatim, so this module\n * parses THAT: thinking becomes its own event, and a turn with no text emits no\n * assistant event at all. Same reasoning for `argsPayload` (full tool arguments,\n * written all along, previously unread) and for `role: 'toolResult'` records,\n * which used to be dropped so a reader could see what ran but never what came\n * back.\n *\n * INCREMENTAL BY CONSTRUCTION:\n * A transcript is append-only and can reach 50 MiB, while the fleet overlay\n * re-checks the selected run roughly once a second. Re-reading and re-parsing\n * the whole file on every change makes cost grow with run length, so the reader\n * is resumable (`readFleetTranscriptTail`): it reads only the bytes appended\n * since the last call, and the renderer keeps one rendered block per event so\n * an append re-renders only the new and mutated ones. Steady-state cost is\n * proportional to what arrived, not to what the file holds.\n *\n * DESIGN PATTERNS:\n * - Reading is tolerant, not strict: the writer appends lines as a run\n * progresses, so the last line on disk may be a partial write mid-flush.\n * A line that fails to parse is dropped rather than failing the whole read\n * - `tool_start`/`tool_end`/`toolResult` are folded into ONE `tool` event keyed\n * by `toolCallId`, so the pane reads as a sequence of turns rather than three\n * lines per call. Calls interleave and `tool_end` arrives BEFORE its\n * `toolResult`, so the fold map retains an entry for as long as its event is\n * retained rather than closing it out on `tool_end`\n * - A `tool_end` with no matching start (the start fell outside the retained\n * window) still renders on its own rather than being dropped, since it is\n * still evidence of what ran\n *\n * AVOID:\n * - Reusing a `FleetTranscriptTail` after passing it as `previous`. The reader\n * takes ownership of its `events` and fold map instead of copying them, which\n * is the whole point of resuming; the returned tail supersedes it\n */\n\nimport * as fs from 'node:fs';\n\nimport { Markdown, truncateToWidth, wrapTextWithAnsi, type MarkdownTheme } from '@earendil-works/pi-tui';\n\nimport { formatDuration, shortenPath } from '../shared/formatters.ts';\n\nexport type FleetTranscriptEventKind = 'user' | 'assistant' | 'thinking' | 'tool' | 'notice' | 'stdout' | 'stderr';\n\nexport interface FleetTranscriptEvent {\n kind: FleetTranscriptEventKind;\n at: number;\n text: string;\n /** Tool name, present only for `kind: 'tool'`. */\n name?: string;\n /** Present only for `kind: 'tool'`: `'running'` until a matching `tool_end` arrives. */\n status?: 'running' | 'ok' | 'error';\n /** Tool arguments parsed from `argsPayload`, when the writer recorded them. */\n args?: Record<string, unknown>;\n /** Tool output, folded in from the matching `toolResult` record. */\n result?: string;\n /** Set when the writer bounded `result` at its payload cap. */\n resultTruncated?: boolean;\n /** `tool_end` timestamp, for the call's duration. */\n endedAt?: number;\n /** Model that produced an assistant turn, when reported. */\n model?: string;\n}\n\nexport interface FleetTranscript {\n events: FleetTranscriptEvent[];\n warning?: string;\n}\n\n/** One retained tool event and where it sits in `events`, so a later fold can mark it dirty. */\ninterface FleetTranscriptToolEntry {\n event: FleetTranscriptEvent;\n index: number;\n}\n\n/**\n * A resume point for `readFleetTranscriptTail`.\n *\n * `byteOffset` is deliberately the end of the last COMPLETE line rather than\n * the file size: a partial trailing line is left unconsumed so the next read\n * picks it up whole, instead of being dropped as unparseable the way a\n * whole-file read has to.\n */\nexport interface FleetTranscriptTail extends FleetTranscript {\n path: string;\n byteOffset: number;\n /** Size observed at this read. A later shrink means the file was replaced, forcing a full re-read. */\n size: number;\n toolCalls: Map<string, FleetTranscriptToolEntry>;\n /** Earliest index whose content changed in this read. Undefined when only appends happened. */\n firstDirtyIndex: number | undefined;\n /** Cumulative events dropped from the front by the retention cap. */\n droppedEvents: number;\n}\n\n/**\n * Retention cap. Bounds memory and worst-case render cost independently of how\n * long a run goes on; `droppedEvents` keeps the fact that a window was applied\n * visible, so a tail is never mistaken for a whole run.\n */\nexport const MAX_RETAINED_EVENTS = 1000;\n\nconst NEWLINE_BYTE = 0x0a;\n\ninterface RawRecord {\n recordType?: string;\n ts?: number;\n role?: string;\n text?: string;\n toolCallId?: string;\n toolName?: string;\n isError?: boolean;\n argsPreview?: string;\n argsPayload?: string;\n outputTruncated?: boolean;\n model?: string;\n message?: { role?: string; content?: unknown };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction parseLine(line: string): RawRecord | undefined {\n const trimmed = line.trim();\n if (!trimmed) return undefined;\n try {\n const parsed: unknown = JSON.parse(trimmed);\n return isRecord(parsed) ? (parsed as RawRecord) : undefined;\n } catch {\n // The writer appends line-by-line; a trailing partial write on the last\n // line is expected while a run is in flight, not evidence of corruption.\n return undefined;\n }\n}\n\n/**\n * Split an assistant turn's raw content into its thinking and its prose.\n *\n * Returns undefined when the record carried no content array, so the caller can\n * fall back to the writer's flattened `text` rather than treating a shape this\n * does not recognise as an empty turn.\n */\nfunction splitAssistantContent(content: unknown): { thinking: string[]; text: string } | undefined {\n if (!Array.isArray(content)) return undefined;\n const thinking: string[] = [];\n const texts: string[] = [];\n for (const part of content) {\n if (!part || typeof part !== 'object') continue;\n const record = part as Record<string, unknown>;\n if (record.type === 'thinking') {\n const value = typeof record.thinking === 'string' ? record.thinking : '';\n if (value.trim()) thinking.push(value);\n continue;\n }\n // Anything else - toolCall in particular - is represented by its own event,\n // so it must not be folded into the assistant turn's text.\n if (record.type === 'text' && typeof record.text === 'string') texts.push(record.text);\n }\n return { thinking, text: texts.join('\\n') };\n}\n\nfunction parseArgsPayload(payload: string | undefined): Record<string, unknown> | undefined {\n if (!payload) return undefined;\n try {\n const parsed: unknown = JSON.parse(payload);\n return isRecord(parsed) ? parsed : undefined;\n } catch {\n // The writer bounds this payload, so a long argument set can land here\n // truncated mid-JSON. The preview still renders; the args just stay absent.\n return undefined;\n }\n}\n\nfunction emptyTail(transcriptPath: string, warning?: string): FleetTranscriptTail {\n return {\n path: transcriptPath,\n events: [],\n byteOffset: 0,\n size: 0,\n toolCalls: new Map(),\n firstDirtyIndex: undefined,\n droppedEvents: 0,\n ...(warning ? { warning } : {}),\n };\n}\n\n/** Read exactly the appended range, so cost tracks what arrived rather than what the file holds. */\nfunction readRange(filePath: string, offset: number, length: number): Buffer {\n const handle = fs.openSync(filePath, 'r');\n try {\n const buffer = Buffer.allocUnsafe(length);\n let read = 0;\n while (read < length) {\n const chunk = fs.readSync(handle, buffer, read, length - read, offset + read);\n if (chunk <= 0) break;\n read += chunk;\n }\n return read === length ? buffer : buffer.subarray(0, read);\n } finally {\n fs.closeSync(handle);\n }\n}\n\nfunction markDirty(tail: FleetTranscriptTail, index: number): void {\n if (tail.firstDirtyIndex === undefined || index < tail.firstDirtyIndex) tail.firstDirtyIndex = index;\n}\n\nfunction pushEvent(tail: FleetTranscriptTail, event: FleetTranscriptEvent): number {\n tail.events.push(event);\n return tail.events.length - 1;\n}\n\n/** Apply the retention cap, keeping every index that survives it consistent. */\nfunction applyRetention(tail: FleetTranscriptTail): void {\n const excess = tail.events.length - MAX_RETAINED_EVENTS;\n if (excess <= 0) return;\n tail.events.splice(0, excess);\n tail.droppedEvents += excess;\n if (tail.firstDirtyIndex !== undefined) tail.firstDirtyIndex = Math.max(0, tail.firstDirtyIndex - excess);\n for (const [callId, entry] of tail.toolCalls) {\n const shifted = entry.index - excess;\n if (shifted < 0) tail.toolCalls.delete(callId);\n else entry.index = shifted;\n }\n}\n\nfunction consumeMessage(tail: FleetTranscriptTail, record: RawRecord): void {\n const at = record.ts ?? 0;\n if (record.role === 'toolResult') {\n const entry = record.toolCallId ? tail.toolCalls.get(record.toolCallId) : undefined;\n // A result whose call fell outside the retained window has nothing to\n // attach to; the call itself is already gone, so the output would be\n // unattributable rather than useful.\n if (!entry) return;\n entry.event.result = record.text ?? '';\n entry.event.resultTruncated = record.outputTruncated === true;\n if (record.isError === true) entry.event.status = 'error';\n markDirty(tail, entry.index);\n return;\n }\n if (record.role === 'user') {\n const text = record.text ?? '';\n if (text.trim()) pushEvent(tail, { kind: 'user', at, text });\n return;\n }\n if (record.role === 'assistant') {\n const parts = splitAssistantContent(record.message?.content);\n for (const thinking of parts?.thinking ?? []) pushEvent(tail, { kind: 'thinking', at, text: thinking });\n const text = parts ? parts.text : (record.text ?? '');\n // A turn that only thought and called tools has no prose of its own. Both\n // are already represented, so emitting a header for it says nothing.\n if (text.trim()) {\n pushEvent(tail, { kind: 'assistant', at, text, ...(record.model ? { model: record.model } : {}) });\n }\n return;\n }\n if (record.role === 'custom') {\n // Host-injected notices (skill suggestions, hook output) are part of what\n // the child was told, so they belong in the transcript rather than nowhere.\n const text = record.text ?? '';\n if (text.trim()) pushEvent(tail, { kind: 'notice', at, text });\n }\n}\n\nfunction consumeRecord(tail: FleetTranscriptTail, record: RawRecord): void {\n const at = record.ts ?? 0;\n if (record.recordType === 'message') return consumeMessage(tail, record);\n if (record.recordType === 'tool_start') {\n const args = parseArgsPayload(record.argsPayload);\n const event: FleetTranscriptEvent = {\n kind: 'tool',\n at,\n text: record.argsPreview ?? '',\n ...(record.toolName ? { name: record.toolName } : {}),\n status: 'running',\n ...(args ? { args } : {}),\n };\n const index = pushEvent(tail, event);\n if (record.toolCallId) tail.toolCalls.set(record.toolCallId, { event, index });\n return;\n }\n if (record.recordType === 'tool_end') {\n const entry = record.toolCallId ? tail.toolCalls.get(record.toolCallId) : undefined;\n if (entry) {\n // An error reported by either half of the call is the call's outcome.\n entry.event.status = record.isError === true || entry.event.status === 'error' ? 'error' : 'ok';\n entry.event.endedAt = at;\n markDirty(tail, entry.index);\n return;\n }\n pushEvent(tail, {\n kind: 'tool',\n at,\n text: '',\n ...(record.toolName ? { name: record.toolName } : {}),\n status: record.isError === true ? 'error' : 'ok',\n });\n return;\n }\n if (record.recordType === 'stdout' || record.recordType === 'stderr') {\n pushEvent(tail, { kind: record.recordType, at, text: record.text ?? '' });\n }\n // 'truncated' carries no displayable content of its own; the events\n // recorded before it already show what happened up to the cutoff.\n}\n\n/**\n * Read whatever has been appended since `previous`, or the whole file when no\n * resume point is given.\n *\n * Never throws: a missing or unreadable file is a normal state (the run has\n * not started writing yet, or was cleaned up), reported through `warning`\n * rather than an exception the caller would have to guard against.\n */\nexport function readFleetTranscriptTail(transcriptPath: string, previous?: FleetTranscriptTail): FleetTranscriptTail {\n let size: number;\n try {\n size = fs.statSync(transcriptPath).size;\n } catch (cause) {\n return emptyTail(transcriptPath, cause instanceof Error ? cause.message : String(cause));\n }\n\n // A shrink means the file was replaced rather than appended to, so nothing\n // parsed from the old one can be trusted to still describe it.\n const resumable =\n previous !== undefined &&\n previous.path === transcriptPath &&\n previous.warning === undefined &&\n size >= previous.byteOffset;\n\n const tail: FleetTranscriptTail = resumable\n ? { ...previous, size, firstDirtyIndex: undefined, warning: undefined }\n : emptyTail(transcriptPath);\n tail.size = size;\n if (size <= tail.byteOffset) return tail;\n\n let chunk: Buffer;\n try {\n chunk = readRange(transcriptPath, tail.byteOffset, size - tail.byteOffset);\n } catch (cause) {\n return { ...tail, warning: cause instanceof Error ? cause.message : String(cause) };\n }\n\n // Split at the last newline: 0x0A cannot occur inside a UTF-8 multi-byte\n // sequence, so this is a byte boundary that is also a character boundary.\n const lastNewline = chunk.lastIndexOf(NEWLINE_BYTE);\n const complete = lastNewline === -1 ? undefined : chunk.subarray(0, lastNewline + 1);\n const remainder = chunk.subarray(lastNewline + 1);\n\n // A trailing line with no newline after it is ambiguous: either a write\n // caught mid-flush, or simply the last record of a file the writer did not\n // terminate. Parsing decides - a half-written record cannot be valid JSON,\n // since it is missing its closing brace - so a complete record is never\n // withheld just because nothing followed it, and a partial one is left\n // unconsumed for the next read to pick up whole.\n const pending = remainder.length > 0 ? parseLine(remainder.toString('utf-8')) : undefined;\n tail.byteOffset += (complete?.length ?? 0) + (pending ? remainder.length : 0);\n if (!complete && !pending) return tail;\n\n for (const line of complete ? complete.toString('utf-8').split(/\\r?\\n/) : []) {\n const record = parseLine(line);\n if (record) consumeRecord(tail, record);\n }\n if (pending) consumeRecord(tail, pending);\n applyRetention(tail);\n return tail;\n}\n\n/** Whole-file read, for callers with no incremental state to keep. */\nexport function readFleetTranscript(transcriptPath: string): FleetTranscript {\n const tail = readFleetTranscriptTail(transcriptPath);\n return tail.warning ? { events: tail.events, warning: tail.warning } : { events: tail.events };\n}\n\n// ============================================================================\n// Rendering\n// ============================================================================\n\nexport type FleetTranscriptVerbosity = 'compact' | 'full';\n\nexport interface FleetTranscriptTheme {\n fg(color: string, text: string): string;\n bold(text: string): string;\n}\n\n/**\n * What the renderer needs from a tail: the events, and the two facts that say\n * which rendered blocks are still valid. Deliberately narrower than\n * `FleetTranscriptTail` so rendering does not depend on the reader's file\n * bookkeeping.\n */\nexport type FleetTranscriptRenderable = Pick<FleetTranscriptTail, 'events' | 'firstDirtyIndex' | 'droppedEvents'>;\n\nexport interface FleetTranscriptRenderOptions {\n /** Run cwd, so absolute paths render as the part that actually differs between rows. */\n cwd?: string;\n verbosity: FleetTranscriptVerbosity;\n}\n\n/**\n * One rendered block per event, plus their flattened lines.\n *\n * Blocks are kept so an append re-renders only what changed: markdown is by far\n * the most expensive part of this module, and an assistant message's rendering\n * never changes once written.\n */\nexport interface FleetTranscriptRender {\n width: number;\n verbosity: FleetTranscriptVerbosity;\n cwd: string | undefined;\n droppedEvents: number;\n blocks: string[][];\n lines: string[];\n}\n\nconst COMPACT_LINES: Record<'user' | 'thinking' | 'notice' | 'result', number> = {\n user: 8,\n thinking: 6,\n notice: 3,\n result: 3,\n};\n/** Even expanded, one 32 KiB tool result must not be able to bury the pane. */\nconst FULL_RESULT_LINES = 200;\nconst RESULT_GUTTER = ' ⎿ ';\nconst RESULT_CONTINUATION = ' ';\n\n/** Keys that identify what a call actually did, ahead of the ones every call shares. */\nconst PRIMARY_ARG_KEYS = [\n 'command',\n 'pattern',\n 'query',\n 'queries',\n 'prompt',\n 'task',\n 'describe',\n 'workflow',\n 'url',\n 'urls',\n 'old_string',\n 'content',\n 'file_path',\n 'filePath',\n 'path',\n];\nconst PATH_ARG_KEYS = ['path', 'file_path', 'filePath'];\n\nfunction statusGlyph(status: FleetTranscriptEvent['status']): string {\n if (status === 'ok') return '✓';\n if (status === 'error') return '✗';\n return '…';\n}\n\nfunction statusColor(status: FleetTranscriptEvent['status']): string {\n if (status === 'error') return 'error';\n if (status === 'running') return 'accent';\n return 'muted';\n}\n\n/**\n * Render a path as the part that distinguishes it.\n *\n * Every row in a single run shares the run's cwd as a prefix, so keeping it\n * costs the width that would otherwise show which file was touched.\n */\nfunction displayPath(value: string, cwd?: string): string {\n if (cwd) {\n if (value === cwd) return '.';\n const prefix = cwd.endsWith('/') ? cwd : `${cwd}/`;\n if (value.startsWith(prefix)) return value.slice(prefix.length) || '.';\n }\n return shortenPath(value);\n}\n\nfunction argToDisplay(value: unknown, cwd?: string): string | undefined {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed) return undefined;\n const collapsed = trimmed.replace(/\\s+/g, ' ');\n return collapsed.startsWith('/') ? displayPath(collapsed, cwd) : collapsed;\n }\n if (Array.isArray(value)) {\n const parts = value.map((entry) => argToDisplay(entry, cwd)).filter((entry): entry is string => Boolean(entry));\n return parts.length > 0 ? parts.join(', ') : undefined;\n }\n return undefined;\n}\n\n/**\n * The call's headline arguments.\n *\n * Prefers the distinguishing argument over the shared one, then appends the\n * path when it was not already the headline - `grep` reads as\n * `pattern · where`, `read` as just the file.\n */\nfunction toolArgsSummary(event: FleetTranscriptEvent, cwd?: string): string {\n const args = event.args;\n if (!args) return event.text ? displayPath(event.text, cwd) : '';\n let primaryKey: string | undefined;\n let primary: string | undefined;\n for (const key of PRIMARY_ARG_KEYS) {\n const display = argToDisplay(args[key], cwd);\n if (display) {\n primaryKey = key;\n primary = display;\n break;\n }\n }\n if (!primary) {\n for (const [key, value] of Object.entries(args)) {\n const display = argToDisplay(value, cwd);\n if (display) {\n primaryKey = key;\n primary = `${key}=${display}`;\n break;\n }\n }\n }\n if (!primary) return '';\n const pathKey = PATH_ARG_KEYS.find((key) => key !== primaryKey && typeof args[key] === 'string');\n const pathDisplay = pathKey ? argToDisplay(args[pathKey], cwd) : undefined;\n // A path that relativizes to the run's own cwd says nothing the pane does\n // not already know, and every such row would carry the same '.'.\n return pathDisplay && pathDisplay !== '.' ? `${primary} · ${pathDisplay}` : primary;\n}\n\n/** Wrap to `width`, capped, with the number of hidden lines stated rather than implied. */\nfunction cappedLines(text: string, width: number, limit: number, decorate: (line: string) => string): string[] {\n const wrapped = wrapTextWithAnsi(text, Math.max(1, width));\n if (wrapped.length <= limit) return wrapped.map(decorate);\n return [...wrapped.slice(0, limit).map(decorate), decorate(`… +${wrapped.length - limit} lines`)];\n}\n\nfunction renderToolEvent(\n event: FleetTranscriptEvent,\n width: number,\n theme: FleetTranscriptTheme,\n options: FleetTranscriptRenderOptions,\n): string[] {\n const summary = toolArgsSummary(event, options.cwd);\n const duration = event.endedAt !== undefined ? formatDuration(Math.max(0, event.endedAt - event.at)) : undefined;\n const header = [\n theme.fg(statusColor(event.status), statusGlyph(event.status)),\n theme.bold(event.name ?? 'tool'),\n summary ? theme.fg('muted', summary) : undefined,\n duration ? theme.fg('dim', duration) : undefined,\n ]\n .filter((part): part is string => part !== undefined)\n .join(' ');\n const lines = [truncateToWidth(header, width)];\n\n if (options.verbosity === 'full' && event.args) {\n const pretty = JSON.stringify(event.args, null, 2);\n for (const line of pretty.split('\\n')) {\n lines.push(theme.fg('dim', truncateToWidth(`${RESULT_CONTINUATION}${line}`, width)));\n }\n }\n\n const result = event.result?.trimEnd();\n if (result) {\n const limit = options.verbosity === 'full' ? FULL_RESULT_LINES : COMPACT_LINES.result;\n const color = event.status === 'error' ? 'error' : 'dim';\n const body = result.split('\\n');\n const shown = body.slice(0, limit);\n shown.forEach((line, index) => {\n const prefix = index === 0 ? RESULT_GUTTER : RESULT_CONTINUATION;\n lines.push(theme.fg(color, truncateToWidth(`${prefix}${line}`, width)));\n });\n const hidden = body.length - shown.length;\n if (hidden > 0) lines.push(theme.fg('dim', truncateToWidth(`${RESULT_CONTINUATION}… +${hidden} lines`, width)));\n if (event.resultTruncated) {\n lines.push(theme.fg('dim', truncateToWidth(`${RESULT_CONTINUATION}(output truncated by the recorder)`, width)));\n }\n } else if (event.status === 'running') {\n lines.push(theme.fg('dim', truncateToWidth(`${RESULT_GUTTER}running…`, width)));\n }\n return lines;\n}\n\nfunction renderEvent(\n event: FleetTranscriptEvent,\n width: number,\n theme: FleetTranscriptTheme,\n markdownTheme: MarkdownTheme | undefined,\n options: FleetTranscriptRenderOptions,\n): string[] {\n const safeWidth = Math.max(1, width);\n if (event.kind === 'tool') return [...renderToolEvent(event, safeWidth, theme, options), ''];\n\n if (event.kind === 'assistant') {\n const header = theme.fg('accent', theme.bold('● assistant'));\n // Markdown is the expensive call in this module; the block cache is what\n // keeps it to once per message rather than once per repaint.\n const body = markdownTheme\n ? new Markdown(event.text, 0, 0, markdownTheme).render(safeWidth)\n : wrapTextWithAnsi(event.text, safeWidth);\n return [header, ...body, ''];\n }\n\n if (event.kind === 'thinking') {\n const header = theme.fg('dim', theme.bold('✻ thinking'));\n const limit = options.verbosity === 'full' ? Number.POSITIVE_INFINITY : COMPACT_LINES.thinking;\n return [header, ...cappedLines(event.text, safeWidth, limit, (line) => theme.fg('dim', line)), ''];\n }\n\n if (event.kind === 'user') {\n const header = theme.fg('accent', theme.bold('▸ user'));\n const limit = options.verbosity === 'full' ? Number.POSITIVE_INFINITY : COMPACT_LINES.user;\n return [header, ...cappedLines(event.text, safeWidth, limit, (line) => line), ''];\n }\n\n if (event.kind === 'notice') {\n const limit = options.verbosity === 'full' ? Number.POSITIVE_INFINITY : COMPACT_LINES.notice;\n return [...cappedLines(`ℹ ${event.text}`, safeWidth, limit, (line) => theme.fg('muted', line)), ''];\n }\n\n const prefix = event.kind === 'stderr' ? theme.fg('warning', 'stderr') : theme.fg('dim', 'stdout');\n return [truncateToWidth(`${prefix} ${event.text}`, safeWidth), ''];\n}\n\n/**\n * Render `tail`'s events, reusing `previous`'s blocks wherever nothing changed.\n *\n * A full render happens only when something global changed - width, verbosity,\n * cwd, or the absence of a usable previous render. An append re-renders from\n * the earliest dirty index onward and reuses every block before it.\n */\nexport function renderFleetTranscript(\n tail: FleetTranscriptRenderable,\n width: number,\n theme: FleetTranscriptTheme,\n markdownTheme: MarkdownTheme | undefined,\n options: FleetTranscriptRenderOptions,\n previous?: FleetTranscriptRender,\n): FleetTranscriptRender {\n const reusable =\n previous !== undefined &&\n previous.width === width &&\n previous.verbosity === options.verbosity &&\n previous.cwd === options.cwd &&\n previous.droppedEvents <= tail.droppedEvents;\n\n // Nothing changed at all: hand back the same render rather than rebuilding\n // a flat line array out of blocks that are all still valid. This is the\n // common case - every repaint driven by a keystroke or an unrelated run -\n // and without it the pane still pays a cost proportional to the whole\n // transcript on each one.\n if (\n reusable &&\n previous.droppedEvents === tail.droppedEvents &&\n tail.firstDirtyIndex === undefined &&\n previous.blocks.length === tail.events.length\n ) {\n return previous;\n }\n\n // Retention drops events off the front, so a reused block list has to be\n // realigned by however many went before it can be indexed alongside events.\n const base = reusable ? previous.blocks.slice(tail.droppedEvents - previous.droppedEvents) : [];\n const from = Math.min(tail.firstDirtyIndex ?? base.length, base.length, tail.events.length);\n const blocks = base.slice(0, from);\n for (let index = from; index < tail.events.length; index++) {\n blocks.push(renderEvent(tail.events[index], width, theme, markdownTheme, options));\n }\n\n const lines: string[] = [];\n if (tail.droppedEvents > 0) {\n lines.push(theme.fg('dim', truncateToWidth(`… ${tail.droppedEvents} earlier events not shown`, width)), '');\n }\n for (const block of blocks) lines.push(...block);\n return { width, verbosity: options.verbosity, cwd: options.cwd, droppedEvents: tail.droppedEvents, blocks, lines };\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../agents/discovery.cjs`),t=require(`../runs/background/asyncJobTracker.cjs`),n=require(`./agentCatalog.cjs`),r=require(`./agentResourceProjection.cjs`),i=require(`./fleet.cjs`),a=require(`./fleetStatus.cjs`);let o=require(`@agimon-ai/doompi-ui/footer`),s=require(`@agimon-ai/doompi-ui/leader`);const c=`subagents-fleet`,l=`subagents-list`,u=`@agimon-ai/doompi-team`,d={key:`a`,label:`agents`,detail:`subagent resources and runs`,order:15},f=`requested`;function p(e){return(0,s.registerDoomLeaderContribution)(e,{source:u,bindings:[{id:`subagents.fleet`,path:[d,{key:`r`,label:`runs`,detail:`current-session runs`}],command:{name:c}},{id:`subagents.list`,path:[d,{key:`l`,label:`list`,detail:`available agents`}],command:{name:l}}]})}function m(t,i){t.registerCommand(l,{description:`Browse agents available from this session cwd and inspect their projected launch resources`,handler:async(t,a)=>{let o=i.discovery.discover(a.cwd,`both`).agents,s=e.resolveActiveLayerSubagentConfig(),c=i.skills.discoverAvailableSkills(a.cwd);await n.openAgentCatalog(a,r.buildAgentCatalogEntries(o,{cwd:a.cwd,skills:{resolveSkillsWithFallback:(...e)=>i.skills.resolveSkillsWithFallback(...e),discoverAvailableSkills:()=>c},capabilityCeiling:i.policies.resolve(),...s?.config.excludeTools?{excludeTools:s.config.excludeTools,exclusionSource:s.path}:{},environment:{...process.env}}))}})}function h(e,n){return async r=>{let i=t.resolveTrackedRunId(n,r.id);if(r.action===`interrupt`)return e.interrupt(i,r.message),{status:f};if(r.action===`stop`)return e.stop(i,r.message),{status:f};if(r.action===`steer`){let t=await e.steer(i,r.message??``);return{status:t.state,detail:t.message}}throw Error(`Resume is not supported by the current subagent runtime.`)}}function g(e,t){let n,r=!1,i=0,s=(0,o.registerDoomFooterContribution)(e,{source:u,id:`agent-count`,order:20}),c=(e=!1)=>{if(!n)return!1;let t=a.agentFleetStatus(n.jobs,i),r=t?.fingerprint;return!e&&r===n.fingerprint?!1:(s.update(t?.footer),n.ctx.hasUI&&n.ctx.ui.setStatus(a.FLEET_STATUS_KEY,t?.text),n.fingerprint=r,!0)},l=t.scheduler.register({id:`doom-team-agent-status`,intervalMs:250,run:()=>(i=(i+1)%a.AGENT_PULSE_FRAMES.length,c())});return e.on(`session_start`,(e,i)=>{r||(n={ctx:i,jobs:t.tracker.forSession(i.sessionManager.getSessionId()),fingerprint:void 0},c(!0))}),()=>{r||(r=!0,l(),s.dispose(),n?.ctx.hasUI&&n.ctx.ui.setStatus(a.FLEET_STATUS_KEY,void 0),n=void 0)}}function _(e,t){e.registerCommand(c,{description:`Open the live agent runs overlay: inspect current-session runs and apply runtime controls`,handler:async(e,n)=>{let r=t.tracker.forSession(n.sessionManager.getSessionId()),a=t.dispatchAction??(t.management?h(t.management,r):void 0);await i.openSubagentFleet(n,t.scheduler,r,{dispatchAction:a})}})}exports.SUBAGENT_LEADER_SOURCE=u,exports.registerAgentListCommand=m,exports.registerAgentStatus=g,exports.registerFleetCommand=_,exports.registerSubagentLeaderContribution=p;
2
+ //# sourceMappingURL=register.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.cjs","names":["resolveActiveLayerSubagentConfig","openAgentCatalog","buildAgentCatalogEntries","resolveTrackedRunId","agentFleetStatus","FLEET_STATUS_KEY","AGENT_PULSE_FRAMES","openSubagentFleet"],"sources":["../../src/tui/register.ts"],"sourcesContent":["/**\n * Wires the agent catalog, run fleet, and compact footer status into the host.\n *\n * DESIGN PATTERNS:\n * - Wiring only: display decisions live in `agentCatalog.ts`, `fleet.ts`, and\n * `fleetStatus.ts`; this file connects those surfaces to host services.\n */\n\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport { registerDoomFooterContribution } from '@agimon-ai/doompi-ui/footer';\nimport { registerDoomLeaderContribution } from '@agimon-ai/doompi-ui/leader';\n\nimport {\n resolveTrackedRunId,\n type IAsyncJobTracker,\n type ITrackedAsyncJobs,\n} from '../runs/background/asyncJobTracker.ts';\nimport { resolveActiveLayerSubagentConfig } from '../agents/discovery.ts';\nimport type { ISkillDiscoveryService } from '../agents/skills.ts';\nimport type { IAgentDiscoveryService } from '../agents/types.ts';\nimport type { IManagementActions } from '../extensions/managementActions.ts';\nimport type { SubagentCapabilityPolicyStore } from '../protocol/capabilityCeiling.ts';\nimport type { IPollScheduler } from '../shared/pollScheduler.ts';\nimport { openAgentCatalog } from './agentCatalog.ts';\nimport { buildAgentCatalogEntries } from './agentResourceProjection.ts';\nimport { openSubagentFleet, type FleetActionDispatcher } from './fleet.ts';\nimport { AGENT_PULSE_FRAMES, agentFleetStatus, FLEET_STATUS_KEY } from './fleetStatus.ts';\n\nexport const SUBAGENT_FLEET_COMMAND = 'subagents-fleet';\nexport const SUBAGENT_LIST_COMMAND = 'subagents-list';\nexport const SUBAGENT_LEADER_SOURCE = '@agimon-ai/doompi-team';\nconst SUBAGENT_LEADER_ORDER = 15;\nconst SUBAGENT_LEADER_SEGMENT = {\n key: 'a',\n label: 'agents',\n detail: 'subagent resources and runs',\n order: SUBAGENT_LEADER_ORDER,\n} as const;\nconst AGENT_FOOTER_ORDER = 20;\nconst AGENT_STATUS_POLL_INTERVAL_MS = 250;\nconst REQUESTED_STATUS = 'requested';\n\n/** Publishes the nested SPC a menu for available agents and current-session runs. */\nexport function registerSubagentLeaderContribution(pi: Pick<ExtensionAPI, 'events' | 'on'>): () => void {\n return registerDoomLeaderContribution(pi, {\n source: SUBAGENT_LEADER_SOURCE,\n bindings: [\n {\n id: 'subagents.fleet',\n path: [SUBAGENT_LEADER_SEGMENT, { key: 'r', label: 'runs', detail: 'current-session runs' }],\n command: { name: SUBAGENT_FLEET_COMMAND },\n },\n {\n id: 'subagents.list',\n path: [SUBAGENT_LEADER_SEGMENT, { key: 'l', label: 'list', detail: 'available agents' }],\n command: { name: SUBAGENT_LIST_COMMAND },\n },\n ],\n });\n}\n\nexport interface RegisterAgentListCommandDeps {\n discovery: IAgentDiscoveryService;\n skills: ISkillDiscoveryService;\n policies: SubagentCapabilityPolicyStore;\n}\n\nexport function registerAgentListCommand(pi: ExtensionAPI, deps: RegisterAgentListCommandDeps): void {\n pi.registerCommand(SUBAGENT_LIST_COMMAND, {\n description: 'Browse agents available from this session cwd and inspect their projected launch resources',\n handler: async (_args: string, ctx: ExtensionContext) => {\n const agents = deps.discovery.discover(ctx.cwd, 'both').agents;\n const activeLayer = resolveActiveLayerSubagentConfig();\n const availableSkills = deps.skills.discoverAvailableSkills(ctx.cwd);\n const skillSnapshot = {\n resolveSkillsWithFallback: (\n ...args: Parameters<ISkillDiscoveryService['resolveSkillsWithFallback']>\n ): ReturnType<ISkillDiscoveryService['resolveSkillsWithFallback']> =>\n deps.skills.resolveSkillsWithFallback(...args),\n discoverAvailableSkills: (): ReturnType<ISkillDiscoveryService['discoverAvailableSkills']> => availableSkills,\n };\n const entries = buildAgentCatalogEntries(agents, {\n cwd: ctx.cwd,\n skills: skillSnapshot,\n capabilityCeiling: deps.policies.resolve(),\n ...(activeLayer?.config.excludeTools\n ? { excludeTools: activeLayer.config.excludeTools, exclusionSource: activeLayer.path }\n : {}),\n environment: { ...process.env },\n });\n await openAgentCatalog(ctx, entries);\n },\n });\n}\n\nexport interface RegisterFleetCommandDeps {\n scheduler: IPollScheduler;\n tracker: IAsyncJobTracker;\n /** Optional: absent until a composition root wires runtime controls to a real dispatcher. */\n dispatchAction?: FleetActionDispatcher;\n /** Builds context-scoped controls when a static test dispatcher is not supplied. */\n management?: IManagementActions;\n}\n\nexport function createFleetActionDispatcher(\n management: IManagementActions,\n jobs: ITrackedAsyncJobs,\n): FleetActionDispatcher {\n return async (request) => {\n const runId = resolveTrackedRunId(jobs, request.id);\n if (request.action === 'interrupt') {\n management.interrupt(runId, request.message);\n return { status: REQUESTED_STATUS };\n }\n if (request.action === 'stop') {\n management.stop(runId, request.message);\n return { status: REQUESTED_STATUS };\n }\n if (request.action === 'steer') {\n const result = await management.steer(runId, request.message ?? '');\n return { status: result.state, detail: result.message };\n }\n throw new Error('Resume is not supported by the current subagent runtime.');\n };\n}\n\nexport function registerAgentStatus(pi: ExtensionAPI, deps: RegisterFleetCommandDeps): () => void {\n let current: { ctx: ExtensionContext; jobs: ITrackedAsyncJobs; fingerprint: string | undefined } | undefined;\n let disposed = false;\n let frame = 0;\n const footerContribution = registerDoomFooterContribution(pi, {\n source: SUBAGENT_LEADER_SOURCE,\n id: 'agent-count',\n order: AGENT_FOOTER_ORDER,\n });\n\n const publish = (force = false): boolean => {\n if (!current) return false;\n const status = agentFleetStatus(current.jobs, frame);\n const fingerprint = status?.fingerprint;\n if (!force && fingerprint === current.fingerprint) return false;\n footerContribution.update(status?.footer);\n if (current.ctx.hasUI) current.ctx.ui.setStatus(FLEET_STATUS_KEY, status?.text);\n current.fingerprint = fingerprint;\n return true;\n };\n\n const unregisterPoll = deps.scheduler.register({\n id: 'doom-team-agent-status',\n intervalMs: AGENT_STATUS_POLL_INTERVAL_MS,\n run: () => {\n frame = (frame + 1) % AGENT_PULSE_FRAMES.length;\n return publish();\n },\n });\n\n pi.on('session_start', (_event, ctx: ExtensionContext) => {\n if (disposed) return;\n current = {\n ctx,\n jobs: deps.tracker.forSession(ctx.sessionManager.getSessionId()),\n fingerprint: undefined,\n };\n publish(true);\n });\n\n return () => {\n if (disposed) return;\n disposed = true;\n unregisterPoll();\n footerContribution.dispose();\n if (current?.ctx.hasUI) current.ctx.ui.setStatus(FLEET_STATUS_KEY, undefined);\n current = undefined;\n };\n}\n\nexport function registerFleetCommand(pi: ExtensionAPI, deps: RegisterFleetCommandDeps): void {\n pi.registerCommand(SUBAGENT_FLEET_COMMAND, {\n description: 'Open the live agent runs overlay: inspect current-session runs and apply runtime controls',\n handler: async (_args: string, ctx: ExtensionContext) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const dispatchAction =\n deps.dispatchAction ?? (deps.management ? createFleetActionDispatcher(deps.management, jobs) : undefined);\n await openSubagentFleet(ctx, deps.scheduler, jobs, { dispatchAction });\n },\n });\n}\n"],"mappings":"qWA4BA,MAAa,EAAyB,kBACzB,EAAwB,iBACxB,EAAyB,yBAEhC,EAA0B,CAC9B,IAAK,IACL,MAAO,SACP,OAAQ,8BACR,MAAO,GACR,CAGK,EAAmB,YAGzB,SAAgB,EAAmC,EAAqD,CACtG,OAAA,EAAA,EAAA,gCAAsC,EAAI,CACxC,OAAQ,EACR,SAAU,CACR,CACE,GAAI,kBACJ,KAAM,CAAC,EAAyB,CAAE,IAAK,IAAK,MAAO,OAAQ,OAAQ,uBAAwB,CAAC,CAC5F,QAAS,CAAE,KAAM,EAAwB,CAC1C,CACD,CACE,GAAI,iBACJ,KAAM,CAAC,EAAyB,CAAE,IAAK,IAAK,MAAO,OAAQ,OAAQ,mBAAoB,CAAC,CACxF,QAAS,CAAE,KAAM,EAAuB,CACzC,CACF,CACF,CAAC,CASJ,SAAgB,EAAyB,EAAkB,EAA0C,CACnG,EAAG,gBAAgB,EAAuB,CACxC,YAAa,6FACb,QAAS,MAAO,EAAe,IAA0B,CACvD,IAAM,EAAS,EAAK,UAAU,SAAS,EAAI,IAAK,OAAO,CAAC,OAClD,EAAcA,EAAAA,kCAAkC,CAChD,EAAkB,EAAK,OAAO,wBAAwB,EAAI,IAAI,CAiBpE,MAAMC,EAAAA,iBAAiB,EATPC,EAAAA,yBAAyB,EAAQ,CAC/C,IAAK,EAAI,IACT,OAAQ,CARR,2BACE,GAAG,IAEH,EAAK,OAAO,0BAA0B,GAAG,EAAK,CAChD,4BAA8F,EAIzE,CACrB,kBAAmB,EAAK,SAAS,SAAS,CAC1C,GAAI,GAAa,OAAO,aACpB,CAAE,aAAc,EAAY,OAAO,aAAc,gBAAiB,EAAY,KAAM,CACpF,EAAE,CACN,YAAa,CAAE,GAAG,QAAQ,IAAK,CAChC,CACkC,CAAC,EAEvC,CAAC,CAYJ,SAAgB,EACd,EACA,EACuB,CACvB,OAAO,KAAO,IAAY,CACxB,IAAM,EAAQC,EAAAA,oBAAoB,EAAM,EAAQ,GAAG,CACnD,GAAI,EAAQ,SAAW,YAErB,OADA,EAAW,UAAU,EAAO,EAAQ,QAAQ,CACrC,CAAE,OAAQ,EAAkB,CAErC,GAAI,EAAQ,SAAW,OAErB,OADA,EAAW,KAAK,EAAO,EAAQ,QAAQ,CAChC,CAAE,OAAQ,EAAkB,CAErC,GAAI,EAAQ,SAAW,QAAS,CAC9B,IAAM,EAAS,MAAM,EAAW,MAAM,EAAO,EAAQ,SAAW,GAAG,CACnE,MAAO,CAAE,OAAQ,EAAO,MAAO,OAAQ,EAAO,QAAS,CAEzD,MAAU,MAAM,2DAA2D,EAI/E,SAAgB,EAAoB,EAAkB,EAA4C,CAChG,IAAI,EACA,EAAW,GACX,EAAQ,EACN,GAAA,EAAA,EAAA,gCAAoD,EAAI,CAC5D,OAAQ,EACR,GAAI,cACJ,MAAO,GACR,CAAC,CAEI,GAAW,EAAQ,KAAmB,CAC1C,GAAI,CAAC,EAAS,MAAO,GACrB,IAAM,EAASC,EAAAA,iBAAiB,EAAQ,KAAM,EAAM,CAC9C,EAAc,GAAQ,YAK5B,MAJI,CAAC,GAAS,IAAgB,EAAQ,YAAoB,IAC1D,EAAmB,OAAO,GAAQ,OAAO,CACrC,EAAQ,IAAI,OAAO,EAAQ,IAAI,GAAG,UAAUC,EAAAA,iBAAkB,GAAQ,KAAK,CAC/E,EAAQ,YAAc,EACf,KAGH,EAAiB,EAAK,UAAU,SAAS,CAC7C,GAAI,yBACJ,WAAY,IACZ,SACE,GAAS,EAAQ,GAAKC,EAAAA,mBAAmB,OAClC,GAAS,EAEnB,CAAC,CAYF,OAVA,EAAG,GAAG,iBAAkB,EAAQ,IAA0B,CACpD,IACJ,EAAU,CACR,MACA,KAAM,EAAK,QAAQ,WAAW,EAAI,eAAe,cAAc,CAAC,CAChE,YAAa,IAAA,GACd,CACD,EAAQ,GAAK,GACb,KAEW,CACP,IACJ,EAAW,GACX,GAAgB,CAChB,EAAmB,SAAS,CACxB,GAAS,IAAI,OAAO,EAAQ,IAAI,GAAG,UAAUD,EAAAA,iBAAkB,IAAA,GAAU,CAC7E,EAAU,IAAA,KAId,SAAgB,EAAqB,EAAkB,EAAsC,CAC3F,EAAG,gBAAgB,EAAwB,CACzC,YAAa,4FACb,QAAS,MAAO,EAAe,IAA0B,CACvD,IAAM,EAAO,EAAK,QAAQ,WAAW,EAAI,eAAe,cAAc,CAAC,CACjE,EACJ,EAAK,iBAAmB,EAAK,WAAa,EAA4B,EAAK,WAAY,EAAK,CAAG,IAAA,IACjG,MAAME,EAAAA,kBAAkB,EAAK,EAAK,UAAW,EAAM,CAAE,iBAAgB,CAAC,EAEzE,CAAC"}
@@ -0,0 +1,2 @@
1
+ import{init_discovery as e,resolveActiveLayerSubagentConfig as t}from"../agents/discovery.mjs";import{init_asyncJobTracker as n,resolveTrackedRunId as r}from"../runs/background/asyncJobTracker.mjs";import{openAgentCatalog as i}from"./agentCatalog.mjs";import{buildAgentCatalogEntries as a}from"./agentResourceProjection.mjs";import{openSubagentFleet as o}from"./fleet.mjs";import{AGENT_PULSE_FRAMES as s,FLEET_STATUS_KEY as c,agentFleetStatus as l}from"./fleetStatus.mjs";import{registerDoomFooterContribution as u}from"@agimon-ai/doompi-ui/footer";import{registerDoomLeaderContribution as d}from"@agimon-ai/doompi-ui/leader";n(),e();const f=`subagents-fleet`,p=`subagents-list`,m=`@agimon-ai/doompi-team`,h={key:`a`,label:`agents`,detail:`subagent resources and runs`,order:15},g=`requested`;function _(e){return d(e,{source:m,bindings:[{id:`subagents.fleet`,path:[h,{key:`r`,label:`runs`,detail:`current-session runs`}],command:{name:f}},{id:`subagents.list`,path:[h,{key:`l`,label:`list`,detail:`available agents`}],command:{name:p}}]})}function v(e,n){e.registerCommand(p,{description:`Browse agents available from this session cwd and inspect their projected launch resources`,handler:async(e,r)=>{let o=n.discovery.discover(r.cwd,`both`).agents,s=t(),c=n.skills.discoverAvailableSkills(r.cwd);await i(r,a(o,{cwd:r.cwd,skills:{resolveSkillsWithFallback:(...e)=>n.skills.resolveSkillsWithFallback(...e),discoverAvailableSkills:()=>c},capabilityCeiling:n.policies.resolve(),...s?.config.excludeTools?{excludeTools:s.config.excludeTools,exclusionSource:s.path}:{},environment:{...process.env}}))}})}function y(e,t){return async n=>{let i=r(t,n.id);if(n.action===`interrupt`)return e.interrupt(i,n.message),{status:g};if(n.action===`stop`)return e.stop(i,n.message),{status:g};if(n.action===`steer`){let t=await e.steer(i,n.message??``);return{status:t.state,detail:t.message}}throw Error(`Resume is not supported by the current subagent runtime.`)}}function b(e,t){let n,r=!1,i=0,a=u(e,{source:m,id:`agent-count`,order:20}),o=(e=!1)=>{if(!n)return!1;let t=l(n.jobs,i),r=t?.fingerprint;return!e&&r===n.fingerprint?!1:(a.update(t?.footer),n.ctx.hasUI&&n.ctx.ui.setStatus(c,t?.text),n.fingerprint=r,!0)},d=t.scheduler.register({id:`doom-team-agent-status`,intervalMs:250,run:()=>(i=(i+1)%s.length,o())});return e.on(`session_start`,(e,i)=>{r||(n={ctx:i,jobs:t.tracker.forSession(i.sessionManager.getSessionId()),fingerprint:void 0},o(!0))}),()=>{r||(r=!0,d(),a.dispose(),n?.ctx.hasUI&&n.ctx.ui.setStatus(c,void 0),n=void 0)}}function x(e,t){e.registerCommand(f,{description:`Open the live agent runs overlay: inspect current-session runs and apply runtime controls`,handler:async(e,n)=>{let r=t.tracker.forSession(n.sessionManager.getSessionId()),i=t.dispatchAction??(t.management?y(t.management,r):void 0);await o(n,t.scheduler,r,{dispatchAction:i})}})}export{m as SUBAGENT_LEADER_SOURCE,v as registerAgentListCommand,b as registerAgentStatus,x as registerFleetCommand,_ as registerSubagentLeaderContribution};
2
+ //# sourceMappingURL=register.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.mjs","names":[],"sources":["../../src/tui/register.ts"],"sourcesContent":["/**\n * Wires the agent catalog, run fleet, and compact footer status into the host.\n *\n * DESIGN PATTERNS:\n * - Wiring only: display decisions live in `agentCatalog.ts`, `fleet.ts`, and\n * `fleetStatus.ts`; this file connects those surfaces to host services.\n */\n\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\nimport { registerDoomFooterContribution } from '@agimon-ai/doompi-ui/footer';\nimport { registerDoomLeaderContribution } from '@agimon-ai/doompi-ui/leader';\n\nimport {\n resolveTrackedRunId,\n type IAsyncJobTracker,\n type ITrackedAsyncJobs,\n} from '../runs/background/asyncJobTracker.ts';\nimport { resolveActiveLayerSubagentConfig } from '../agents/discovery.ts';\nimport type { ISkillDiscoveryService } from '../agents/skills.ts';\nimport type { IAgentDiscoveryService } from '../agents/types.ts';\nimport type { IManagementActions } from '../extensions/managementActions.ts';\nimport type { SubagentCapabilityPolicyStore } from '../protocol/capabilityCeiling.ts';\nimport type { IPollScheduler } from '../shared/pollScheduler.ts';\nimport { openAgentCatalog } from './agentCatalog.ts';\nimport { buildAgentCatalogEntries } from './agentResourceProjection.ts';\nimport { openSubagentFleet, type FleetActionDispatcher } from './fleet.ts';\nimport { AGENT_PULSE_FRAMES, agentFleetStatus, FLEET_STATUS_KEY } from './fleetStatus.ts';\n\nexport const SUBAGENT_FLEET_COMMAND = 'subagents-fleet';\nexport const SUBAGENT_LIST_COMMAND = 'subagents-list';\nexport const SUBAGENT_LEADER_SOURCE = '@agimon-ai/doompi-team';\nconst SUBAGENT_LEADER_ORDER = 15;\nconst SUBAGENT_LEADER_SEGMENT = {\n key: 'a',\n label: 'agents',\n detail: 'subagent resources and runs',\n order: SUBAGENT_LEADER_ORDER,\n} as const;\nconst AGENT_FOOTER_ORDER = 20;\nconst AGENT_STATUS_POLL_INTERVAL_MS = 250;\nconst REQUESTED_STATUS = 'requested';\n\n/** Publishes the nested SPC a menu for available agents and current-session runs. */\nexport function registerSubagentLeaderContribution(pi: Pick<ExtensionAPI, 'events' | 'on'>): () => void {\n return registerDoomLeaderContribution(pi, {\n source: SUBAGENT_LEADER_SOURCE,\n bindings: [\n {\n id: 'subagents.fleet',\n path: [SUBAGENT_LEADER_SEGMENT, { key: 'r', label: 'runs', detail: 'current-session runs' }],\n command: { name: SUBAGENT_FLEET_COMMAND },\n },\n {\n id: 'subagents.list',\n path: [SUBAGENT_LEADER_SEGMENT, { key: 'l', label: 'list', detail: 'available agents' }],\n command: { name: SUBAGENT_LIST_COMMAND },\n },\n ],\n });\n}\n\nexport interface RegisterAgentListCommandDeps {\n discovery: IAgentDiscoveryService;\n skills: ISkillDiscoveryService;\n policies: SubagentCapabilityPolicyStore;\n}\n\nexport function registerAgentListCommand(pi: ExtensionAPI, deps: RegisterAgentListCommandDeps): void {\n pi.registerCommand(SUBAGENT_LIST_COMMAND, {\n description: 'Browse agents available from this session cwd and inspect their projected launch resources',\n handler: async (_args: string, ctx: ExtensionContext) => {\n const agents = deps.discovery.discover(ctx.cwd, 'both').agents;\n const activeLayer = resolveActiveLayerSubagentConfig();\n const availableSkills = deps.skills.discoverAvailableSkills(ctx.cwd);\n const skillSnapshot = {\n resolveSkillsWithFallback: (\n ...args: Parameters<ISkillDiscoveryService['resolveSkillsWithFallback']>\n ): ReturnType<ISkillDiscoveryService['resolveSkillsWithFallback']> =>\n deps.skills.resolveSkillsWithFallback(...args),\n discoverAvailableSkills: (): ReturnType<ISkillDiscoveryService['discoverAvailableSkills']> => availableSkills,\n };\n const entries = buildAgentCatalogEntries(agents, {\n cwd: ctx.cwd,\n skills: skillSnapshot,\n capabilityCeiling: deps.policies.resolve(),\n ...(activeLayer?.config.excludeTools\n ? { excludeTools: activeLayer.config.excludeTools, exclusionSource: activeLayer.path }\n : {}),\n environment: { ...process.env },\n });\n await openAgentCatalog(ctx, entries);\n },\n });\n}\n\nexport interface RegisterFleetCommandDeps {\n scheduler: IPollScheduler;\n tracker: IAsyncJobTracker;\n /** Optional: absent until a composition root wires runtime controls to a real dispatcher. */\n dispatchAction?: FleetActionDispatcher;\n /** Builds context-scoped controls when a static test dispatcher is not supplied. */\n management?: IManagementActions;\n}\n\nexport function createFleetActionDispatcher(\n management: IManagementActions,\n jobs: ITrackedAsyncJobs,\n): FleetActionDispatcher {\n return async (request) => {\n const runId = resolveTrackedRunId(jobs, request.id);\n if (request.action === 'interrupt') {\n management.interrupt(runId, request.message);\n return { status: REQUESTED_STATUS };\n }\n if (request.action === 'stop') {\n management.stop(runId, request.message);\n return { status: REQUESTED_STATUS };\n }\n if (request.action === 'steer') {\n const result = await management.steer(runId, request.message ?? '');\n return { status: result.state, detail: result.message };\n }\n throw new Error('Resume is not supported by the current subagent runtime.');\n };\n}\n\nexport function registerAgentStatus(pi: ExtensionAPI, deps: RegisterFleetCommandDeps): () => void {\n let current: { ctx: ExtensionContext; jobs: ITrackedAsyncJobs; fingerprint: string | undefined } | undefined;\n let disposed = false;\n let frame = 0;\n const footerContribution = registerDoomFooterContribution(pi, {\n source: SUBAGENT_LEADER_SOURCE,\n id: 'agent-count',\n order: AGENT_FOOTER_ORDER,\n });\n\n const publish = (force = false): boolean => {\n if (!current) return false;\n const status = agentFleetStatus(current.jobs, frame);\n const fingerprint = status?.fingerprint;\n if (!force && fingerprint === current.fingerprint) return false;\n footerContribution.update(status?.footer);\n if (current.ctx.hasUI) current.ctx.ui.setStatus(FLEET_STATUS_KEY, status?.text);\n current.fingerprint = fingerprint;\n return true;\n };\n\n const unregisterPoll = deps.scheduler.register({\n id: 'doom-team-agent-status',\n intervalMs: AGENT_STATUS_POLL_INTERVAL_MS,\n run: () => {\n frame = (frame + 1) % AGENT_PULSE_FRAMES.length;\n return publish();\n },\n });\n\n pi.on('session_start', (_event, ctx: ExtensionContext) => {\n if (disposed) return;\n current = {\n ctx,\n jobs: deps.tracker.forSession(ctx.sessionManager.getSessionId()),\n fingerprint: undefined,\n };\n publish(true);\n });\n\n return () => {\n if (disposed) return;\n disposed = true;\n unregisterPoll();\n footerContribution.dispose();\n if (current?.ctx.hasUI) current.ctx.ui.setStatus(FLEET_STATUS_KEY, undefined);\n current = undefined;\n };\n}\n\nexport function registerFleetCommand(pi: ExtensionAPI, deps: RegisterFleetCommandDeps): void {\n pi.registerCommand(SUBAGENT_FLEET_COMMAND, {\n description: 'Open the live agent runs overlay: inspect current-session runs and apply runtime controls',\n handler: async (_args: string, ctx: ExtensionContext) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const dispatchAction =\n deps.dispatchAction ?? (deps.management ? createFleetActionDispatcher(deps.management, jobs) : undefined);\n await openSubagentFleet(ctx, deps.scheduler, jobs, { dispatchAction });\n },\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { Container } from "inversify";
2
+
3
+ //#region src/types.d.ts
4
+ /** Whether an agent's prompt extends the host's system prompt or replaces it. */
5
+ type SystemPromptMode = 'append' | 'replace';
6
+ /**
7
+ * A ceiling on how many tool calls a child may make.
8
+ *
9
+ * `soft` nudges, `hard` blocks. `block` narrows enforcement to named tools, or
10
+ * `'*'` for all of them.
11
+ */
12
+ interface ToolBudgetConfig {
13
+ soft?: number;
14
+ hard: number;
15
+ block?: string[] | '*';
16
+ }
17
+ /**
18
+ * Owns every `globalThis` access in the package.
19
+ *
20
+ * Three things legitimately outlive a container and so cannot live inside one:
21
+ * the cross-bundle protocol registries other extensions attach to, the cleanup
22
+ * handle that lets a reloaded bundle tear down its predecessor, and the default
23
+ * container that public API functions resolve through when their callers hold
24
+ * no container of their own.
25
+ */
26
+ interface IGlobalStateBridge {
27
+ /**
28
+ * Take ownership of a previous bundle's cleanup handle, clearing it so it is
29
+ * run at most once. Returns undefined when no prior bundle registered one.
30
+ */
31
+ takeRuntimeCleanup(): (() => void) | undefined;
32
+ /** Publish this bundle's cleanup handle for whichever bundle replaces it. */
33
+ setRuntimeCleanup(cleanup: () => void): void;
34
+ /** Resolve the process-wide default container, if one has been published. */
35
+ getDefaultContainer(): Container | undefined;
36
+ /** Publish the process-wide default container. */
37
+ setDefaultContainer(container: Container): void;
38
+ /** Drop the process-wide default container reference. */
39
+ clearDefaultContainer(): void;
40
+ /**
41
+ * Read a cross-bundle protocol slot, creating it when absent.
42
+ *
43
+ * The slot key is a `Symbol.for` string shared with every other bundle
44
+ * speaking the protocol, so `adopt` receives whatever a foreign bundle put
45
+ * there and must validate it before this package trusts it. Protocol
46
+ * semantics stay in the protocol module; only the `globalThis` access is
47
+ * centralised here.
48
+ */
49
+ protocolSlot<T>(key: string, create: () => T, adopt: (existing: unknown) => T): T;
50
+ /** Read a cross-bundle protocol slot without creating it. */
51
+ peekProtocolSlot(key: string): unknown;
52
+ /** Claim a protocol slot only if no other bundle has taken it yet. */
53
+ claimProtocolSlot(key: string, value: unknown): void;
54
+ /** Remove a protocol slot. Intended for tests and teardown. */
55
+ clearProtocolSlot(key: string): void;
56
+ }
57
+ //#endregion
58
+ export { IGlobalStateBridge, SystemPromptMode, ToolBudgetConfig };
59
+ //# sourceMappingURL=types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":";;;;KA2GY,gBAAA;;;;;;;UA4CK,gBAAA;EACf,IAAA;EACA,IAAA;EACA,KAAA;AAAA;;;;;;;;;;UAuFe,kBAAA;;;;;EAKf,kBAAA;;EAEA,iBAAA,CAAkB,OAAA;;EAElB,mBAAA,IAAuB,SAAA;;EAEvB,mBAAA,CAAoB,SAAA,EAAW,SAAA;;EAE/B,qBAAA;;;;;;;;;;EAUA,YAAA,IAAgB,GAAA,UAAa,MAAA,QAAc,CAAA,EAAG,KAAA,GAAQ,QAAA,cAAsB,CAAA,GAAI,CAAA;;EAEhF,gBAAA,CAAiB,GAAA;;EAEjB,iBAAA,CAAkB,GAAA,UAAa,KAAA;;EAE/B,iBAAA,CAAkB,GAAA;AAAA"}
@@ -0,0 +1,59 @@
1
+ import { Container } from "inversify";
2
+
3
+ //#region src/types.d.ts
4
+ /** Whether an agent's prompt extends the host's system prompt or replaces it. */
5
+ type SystemPromptMode = 'append' | 'replace';
6
+ /**
7
+ * A ceiling on how many tool calls a child may make.
8
+ *
9
+ * `soft` nudges, `hard` blocks. `block` narrows enforcement to named tools, or
10
+ * `'*'` for all of them.
11
+ */
12
+ interface ToolBudgetConfig {
13
+ soft?: number;
14
+ hard: number;
15
+ block?: string[] | '*';
16
+ }
17
+ /**
18
+ * Owns every `globalThis` access in the package.
19
+ *
20
+ * Three things legitimately outlive a container and so cannot live inside one:
21
+ * the cross-bundle protocol registries other extensions attach to, the cleanup
22
+ * handle that lets a reloaded bundle tear down its predecessor, and the default
23
+ * container that public API functions resolve through when their callers hold
24
+ * no container of their own.
25
+ */
26
+ interface IGlobalStateBridge {
27
+ /**
28
+ * Take ownership of a previous bundle's cleanup handle, clearing it so it is
29
+ * run at most once. Returns undefined when no prior bundle registered one.
30
+ */
31
+ takeRuntimeCleanup(): (() => void) | undefined;
32
+ /** Publish this bundle's cleanup handle for whichever bundle replaces it. */
33
+ setRuntimeCleanup(cleanup: () => void): void;
34
+ /** Resolve the process-wide default container, if one has been published. */
35
+ getDefaultContainer(): Container | undefined;
36
+ /** Publish the process-wide default container. */
37
+ setDefaultContainer(container: Container): void;
38
+ /** Drop the process-wide default container reference. */
39
+ clearDefaultContainer(): void;
40
+ /**
41
+ * Read a cross-bundle protocol slot, creating it when absent.
42
+ *
43
+ * The slot key is a `Symbol.for` string shared with every other bundle
44
+ * speaking the protocol, so `adopt` receives whatever a foreign bundle put
45
+ * there and must validate it before this package trusts it. Protocol
46
+ * semantics stay in the protocol module; only the `globalThis` access is
47
+ * centralised here.
48
+ */
49
+ protocolSlot<T>(key: string, create: () => T, adopt: (existing: unknown) => T): T;
50
+ /** Read a cross-bundle protocol slot without creating it. */
51
+ peekProtocolSlot(key: string): unknown;
52
+ /** Claim a protocol slot only if no other bundle has taken it yet. */
53
+ claimProtocolSlot(key: string, value: unknown): void;
54
+ /** Remove a protocol slot. Intended for tests and teardown. */
55
+ clearProtocolSlot(key: string): void;
56
+ }
57
+ //#endregion
58
+ export { IGlobalStateBridge, SystemPromptMode, ToolBudgetConfig };
59
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;;KA2GY,gBAAA;;;;;;;UA4CK,gBAAA;EACf,IAAA;EACA,IAAA;EACA,KAAA;AAAA;;;;;;;;;;UAuFe,kBAAA;;;;;EAKf,kBAAA;;EAEA,iBAAA,CAAkB,OAAA;;EAElB,mBAAA,IAAuB,SAAA;;EAEvB,mBAAA,CAAoB,SAAA,EAAW,SAAA;;EAE/B,qBAAA;;;;;;;;;;EAUA,YAAA,IAAgB,GAAA,UAAa,MAAA,QAAc,CAAA,EAAG,KAAA,GAAQ,QAAA,cAAsB,CAAA,GAAI,CAAA;;EAEhF,gBAAA,CAAiB,GAAA;;EAEjB,iBAAA,CAAkB,GAAA,UAAa,KAAA;;EAE/B,iBAAA,CAAkB,GAAA;AAAA"}
package/package.json ADDED
@@ -0,0 +1,86 @@
1
+ {
2
+ "name": "@agimon-ai/doompi-team",
3
+ "version": "0.0.1-alpha.0",
4
+ "description": "Async-only subagent team runtime for Pi: named agents, peer messaging, shared task board",
5
+ "homepage": "https://agimon.ai",
6
+ "license": "MIT",
7
+ "author": "Vuong Ngo",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "type": "module",
12
+ "types": "./dist/index.d.mts",
13
+ "jsnext:main": "./dist/index.mjs",
14
+ "exports": {
15
+ ".": "./dist/index.mjs",
16
+ "./api/background-work": "./dist/api/backgroundWork.mjs",
17
+ "./api/capability-ceiling": "./dist/api/capabilityCeiling.mjs",
18
+ "./api/delegation": "./dist/api/delegation.mjs",
19
+ "./api/team-snapshot": "./dist/api/teamSnapshot.mjs",
20
+ "./env": "./dist/env.mjs",
21
+ "./extensions/pi": "./dist/extensions/pi.mjs",
22
+ "./extensions/doom": "./dist/extensions/doom.mjs",
23
+ "./package.json": "./package.json"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public",
27
+ "registry": "https://registry.npmjs.org/"
28
+ },
29
+ "dependencies": {
30
+ "inversify": "8.2.1",
31
+ "reflect-metadata": "0.2.2",
32
+ "typebox": "1.1.38",
33
+ "yaml": "2.9.0",
34
+ "@agimon-ai/doompi-config": "0.0.1-alpha.0",
35
+ "@agimon-ai/doompi-mcp": "0.0.1-alpha.0",
36
+ "@agimon-ai/doompi-extension-contracts": "0.0.1-alpha.0",
37
+ "@agimon-ai/doompi-telemetry": "0.0.1-alpha.0",
38
+ "@agimon-ai/doompi-ui": "0.0.1-alpha.0",
39
+ "@agimon-ai/mcp-proxy": "0.30.9"
40
+ },
41
+ "devDependencies": {
42
+ "@earendil-works/pi-agent-core": "0.84.1",
43
+ "@earendil-works/pi-ai": "0.84.1",
44
+ "@earendil-works/pi-coding-agent": "0.84.1",
45
+ "@earendil-works/pi-tui": "0.84.1",
46
+ "@types/node": "26.1.1",
47
+ "@vitest/coverage-v8": "4.1.10",
48
+ "typescript": "6.0.3",
49
+ "vitest": "4.1.10"
50
+ },
51
+ "peerDependencies": {
52
+ "@earendil-works/pi-agent-core": "0.84.1",
53
+ "@earendil-works/pi-ai": "0.84.1",
54
+ "@earendil-works/pi-coding-agent": "0.84.1",
55
+ "@earendil-works/pi-tui": "0.84.1"
56
+ },
57
+ "peerDependenciesMeta": {
58
+ "@earendil-works/pi-agent-core": {
59
+ "optional": true
60
+ },
61
+ "@earendil-works/pi-ai": {
62
+ "optional": true
63
+ },
64
+ "@earendil-works/pi-coding-agent": {
65
+ "optional": true
66
+ },
67
+ "@earendil-works/pi-tui": {
68
+ "optional": true
69
+ }
70
+ },
71
+ "engines": {
72
+ "node": ">=22.19.0"
73
+ },
74
+ "pi": {
75
+ "extensions": [
76
+ "./dist/extensions/pi.mjs"
77
+ ]
78
+ },
79
+ "scripts": {
80
+ "build": "tsdown",
81
+ "test": "vitest --run",
82
+ "typecheck": "tsc --noEmit",
83
+ "lint": "oxlint . && oxfmt . --check",
84
+ "fixcode": "oxlint . --fix && oxfmt ."
85
+ }
86
+ }