@flanksource/clicky-ui 0.3.24 → 0.3.26

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 (491) hide show
  1. package/NOTICE.md +1 -0
  2. package/dist/ai.cjs +4 -0
  3. package/dist/ai.cjs.map +1 -1
  4. package/dist/ai.js +6 -2
  5. package/dist/ai.js.map +1 -1
  6. package/dist/chat.cjs +8 -0
  7. package/dist/chat.cjs.map +1 -1
  8. package/dist/chat.js +9 -1
  9. package/dist/chat.js.map +1 -1
  10. package/dist/comments/CommentCard.cjs +89 -14
  11. package/dist/comments/CommentCard.cjs.map +1 -1
  12. package/dist/comments/CommentCard.d.ts.map +1 -1
  13. package/dist/comments/CommentCard.js +90 -15
  14. package/dist/comments/CommentCard.js.map +1 -1
  15. package/dist/comments/CommentComposer.cjs +25 -2
  16. package/dist/comments/CommentComposer.cjs.map +1 -1
  17. package/dist/comments/CommentComposer.d.ts.map +1 -1
  18. package/dist/comments/CommentComposer.js +25 -2
  19. package/dist/comments/CommentComposer.js.map +1 -1
  20. package/dist/comments/CommentProvider.cjs +21 -14
  21. package/dist/comments/CommentProvider.cjs.map +1 -1
  22. package/dist/comments/CommentProvider.d.ts +1 -1
  23. package/dist/comments/CommentProvider.d.ts.map +1 -1
  24. package/dist/comments/CommentProvider.js +21 -14
  25. package/dist/comments/CommentProvider.js.map +1 -1
  26. package/dist/comments/CommentSidePanel.cjs +1 -1
  27. package/dist/comments/CommentSidePanel.cjs.map +1 -1
  28. package/dist/comments/CommentSidePanel.js +1 -1
  29. package/dist/comments/CommentSidePanel.js.map +1 -1
  30. package/dist/comments/comment-types.cjs.map +1 -1
  31. package/dist/comments/comment-types.d.ts +6 -0
  32. package/dist/comments/comment-types.d.ts.map +1 -1
  33. package/dist/comments/comment-types.js.map +1 -1
  34. package/dist/components/DimensionField.cjs +56 -0
  35. package/dist/components/DimensionField.cjs.map +1 -0
  36. package/dist/components/DimensionField.d.ts +17 -0
  37. package/dist/components/DimensionField.d.ts.map +1 -0
  38. package/dist/components/DimensionField.js +56 -0
  39. package/dist/components/DimensionField.js.map +1 -0
  40. package/dist/components.cjs +4 -0
  41. package/dist/components.cjs.map +1 -1
  42. package/dist/components.d.ts +2 -0
  43. package/dist/components.d.ts.map +1 -1
  44. package/dist/components.js +4 -0
  45. package/dist/components.js.map +1 -1
  46. package/dist/data/Clicky.cjs +4 -5
  47. package/dist/data/Clicky.cjs.map +1 -1
  48. package/dist/data/Clicky.d.ts.map +1 -1
  49. package/dist/data/Clicky.js +4 -5
  50. package/dist/data/Clicky.js.map +1 -1
  51. package/dist/data/TaskExecDetails.cjs +8 -3
  52. package/dist/data/TaskExecDetails.cjs.map +1 -1
  53. package/dist/data/TaskExecDetails.d.ts +4 -0
  54. package/dist/data/TaskExecDetails.d.ts.map +1 -1
  55. package/dist/data/TaskExecDetails.js +9 -4
  56. package/dist/data/TaskExecDetails.js.map +1 -1
  57. package/dist/data/TaskManagerButton.cjs +101 -7
  58. package/dist/data/TaskManagerButton.cjs.map +1 -1
  59. package/dist/data/TaskManagerButton.d.ts +6 -1
  60. package/dist/data/TaskManagerButton.d.ts.map +1 -1
  61. package/dist/data/TaskManagerButton.js +103 -9
  62. package/dist/data/TaskManagerButton.js.map +1 -1
  63. package/dist/data/TaskProcessDetails.cjs +2 -0
  64. package/dist/data/TaskProcessDetails.cjs.map +1 -1
  65. package/dist/data/TaskProcessDetails.d.ts.map +1 -1
  66. package/dist/data/TaskProcessDetails.js +2 -0
  67. package/dist/data/TaskProcessDetails.js.map +1 -1
  68. package/dist/data/TaskProgress.cjs +14 -4
  69. package/dist/data/TaskProgress.cjs.map +1 -1
  70. package/dist/data/TaskProgress.js +14 -4
  71. package/dist/data/TaskProgress.js.map +1 -1
  72. package/dist/data/TaskSnapshot.cjs.map +1 -1
  73. package/dist/data/TaskSnapshot.d.ts +1 -0
  74. package/dist/data/TaskSnapshot.d.ts.map +1 -1
  75. package/dist/data/TaskSnapshot.js.map +1 -1
  76. package/dist/data/ai/ChatWindow.cjs +18 -23
  77. package/dist/data/ai/ChatWindow.cjs.map +1 -1
  78. package/dist/data/ai/ChatWindow.d.ts +1 -1
  79. package/dist/data/ai/ChatWindow.d.ts.map +1 -1
  80. package/dist/data/ai/ChatWindow.js +19 -24
  81. package/dist/data/ai/ChatWindow.js.map +1 -1
  82. package/dist/data/ai/ChatWindow.preferences.cjs +12 -21
  83. package/dist/data/ai/ChatWindow.preferences.cjs.map +1 -1
  84. package/dist/data/ai/ChatWindow.preferences.d.ts +3 -2
  85. package/dist/data/ai/ChatWindow.preferences.d.ts.map +1 -1
  86. package/dist/data/ai/ChatWindow.preferences.js +12 -21
  87. package/dist/data/ai/ChatWindow.preferences.js.map +1 -1
  88. package/dist/data/ai/ChatWindow.tool-catalog.cjs +21 -38
  89. package/dist/data/ai/ChatWindow.tool-catalog.cjs.map +1 -1
  90. package/dist/data/ai/ChatWindow.tool-catalog.d.ts +5 -5
  91. package/dist/data/ai/ChatWindow.tool-catalog.d.ts.map +1 -1
  92. package/dist/data/ai/ChatWindow.tool-catalog.js +21 -38
  93. package/dist/data/ai/ChatWindow.tool-catalog.js.map +1 -1
  94. package/dist/data/ai/ChatWindow.types.d.ts +2 -2
  95. package/dist/data/ai/ChatWindow.types.d.ts.map +1 -1
  96. package/dist/data/ai/ChatWindowManager.cjs +2 -2
  97. package/dist/data/ai/ChatWindowManager.cjs.map +1 -1
  98. package/dist/data/ai/ChatWindowManager.js +2 -2
  99. package/dist/data/ai/ChatWindowManager.js.map +1 -1
  100. package/dist/data/ai/ChatWindowRequestBody.cjs +4 -2
  101. package/dist/data/ai/ChatWindowRequestBody.cjs.map +1 -1
  102. package/dist/data/ai/ChatWindowRequestBody.d.ts +15 -3
  103. package/dist/data/ai/ChatWindowRequestBody.d.ts.map +1 -1
  104. package/dist/data/ai/ChatWindowRequestBody.js +4 -2
  105. package/dist/data/ai/ChatWindowRequestBody.js.map +1 -1
  106. package/dist/data/ai/ToolPreferences.cjs +5 -5
  107. package/dist/data/ai/ToolPreferences.cjs.map +1 -1
  108. package/dist/data/ai/ToolPreferences.d.ts +6 -5
  109. package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
  110. package/dist/data/ai/ToolPreferences.js +5 -5
  111. package/dist/data/ai/ToolPreferences.js.map +1 -1
  112. package/dist/data/ai/ToolPreferences.model.cjs +61 -37
  113. package/dist/data/ai/ToolPreferences.model.cjs.map +1 -1
  114. package/dist/data/ai/ToolPreferences.model.d.ts +32 -13
  115. package/dist/data/ai/ToolPreferences.model.d.ts.map +1 -1
  116. package/dist/data/ai/ToolPreferences.model.js +62 -38
  117. package/dist/data/ai/ToolPreferences.model.js.map +1 -1
  118. package/dist/data/ai/ToolPreferencesList.cjs +17 -20
  119. package/dist/data/ai/ToolPreferencesList.cjs.map +1 -1
  120. package/dist/data/ai/ToolPreferencesList.d.ts +16 -7
  121. package/dist/data/ai/ToolPreferencesList.d.ts.map +1 -1
  122. package/dist/data/ai/ToolPreferencesList.js +18 -21
  123. package/dist/data/ai/ToolPreferencesList.js.map +1 -1
  124. package/dist/data/ai/chat-window-context.cjs +1 -1
  125. package/dist/data/ai/chat-window-context.cjs.map +1 -1
  126. package/dist/data/ai/chat-window-context.d.ts +7 -7
  127. package/dist/data/ai/chat-window-context.d.ts.map +1 -1
  128. package/dist/data/ai/chat-window-context.js +1 -1
  129. package/dist/data/ai/chat-window-context.js.map +1 -1
  130. package/dist/data/ai/index.d.ts +3 -1
  131. package/dist/data/ai/index.d.ts.map +1 -1
  132. package/dist/data/chat/Chat.cjs +8 -4
  133. package/dist/data/chat/Chat.cjs.map +1 -1
  134. package/dist/data/chat/Chat.d.ts.map +1 -1
  135. package/dist/data/chat/Chat.js +8 -4
  136. package/dist/data/chat/Chat.js.map +1 -1
  137. package/dist/data/chat/ChatRuntimeToolbar.cjs +11 -7
  138. package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -1
  139. package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -1
  140. package/dist/data/chat/ChatRuntimeToolbar.js +11 -7
  141. package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
  142. package/dist/data/chat/ContextMeter.cjs +64 -27
  143. package/dist/data/chat/ContextMeter.cjs.map +1 -1
  144. package/dist/data/chat/ContextMeter.d.ts +11 -4
  145. package/dist/data/chat/ContextMeter.d.ts.map +1 -1
  146. package/dist/data/chat/ContextMeter.js +64 -27
  147. package/dist/data/chat/ContextMeter.js.map +1 -1
  148. package/dist/data/chat/clickyOperationsToTools.cjs +2 -1
  149. package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -1
  150. package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -1
  151. package/dist/data/chat/clickyOperationsToTools.js +2 -1
  152. package/dist/data/chat/clickyOperationsToTools.js.map +1 -1
  153. package/dist/data/chat/index.d.ts +2 -1
  154. package/dist/data/chat/index.d.ts.map +1 -1
  155. package/dist/data/chat/tool-policy.cjs +132 -0
  156. package/dist/data/chat/tool-policy.cjs.map +1 -0
  157. package/dist/data/chat/tool-policy.d.ts +81 -0
  158. package/dist/data/chat/tool-policy.d.ts.map +1 -0
  159. package/dist/data/chat/tool-policy.js +132 -0
  160. package/dist/data/chat/tool-policy.js.map +1 -0
  161. package/dist/data/chat/types.cjs +20 -0
  162. package/dist/data/chat/types.cjs.map +1 -1
  163. package/dist/data/chat/types.d.ts +41 -2
  164. package/dist/data/chat/types.d.ts.map +1 -1
  165. package/dist/data/chat/types.js +20 -0
  166. package/dist/data/chat/types.js.map +1 -1
  167. package/dist/data/chat/usage-snapshot.cjs +10 -1
  168. package/dist/data/chat/usage-snapshot.cjs.map +1 -1
  169. package/dist/data/chat/usage-snapshot.d.ts.map +1 -1
  170. package/dist/data/chat/usage-snapshot.js +10 -1
  171. package/dist/data/chat/usage-snapshot.js.map +1 -1
  172. package/dist/data/debugConsoleSignal.cjs +64 -0
  173. package/dist/data/debugConsoleSignal.cjs.map +1 -0
  174. package/dist/data/debugConsoleSignal.d.ts +83 -0
  175. package/dist/data/debugConsoleSignal.d.ts.map +1 -0
  176. package/dist/data/debugConsoleSignal.js +64 -0
  177. package/dist/data/debugConsoleSignal.js.map +1 -0
  178. package/dist/data/har/HarPanel.cjs +20 -14
  179. package/dist/data/har/HarPanel.cjs.map +1 -1
  180. package/dist/data/har/HarPanel.d.ts.map +1 -1
  181. package/dist/data/har/HarPanel.js +20 -14
  182. package/dist/data/har/HarPanel.js.map +1 -1
  183. package/dist/data/har/types.d.ts +18 -0
  184. package/dist/data/har/types.d.ts.map +1 -1
  185. package/dist/data/query-browser/QueryBrowser.cjs +4 -42
  186. package/dist/data/query-browser/QueryBrowser.cjs.map +1 -1
  187. package/dist/data/query-browser/QueryBrowser.d.ts.map +1 -1
  188. package/dist/data/query-browser/QueryBrowser.js +5 -43
  189. package/dist/data/query-browser/QueryBrowser.js.map +1 -1
  190. package/dist/data/query-browser/QueryBrowser.types.cjs.map +1 -1
  191. package/dist/data/query-browser/QueryBrowser.types.d.ts +0 -1
  192. package/dist/data/query-browser/QueryBrowser.types.d.ts.map +1 -1
  193. package/dist/data/query-browser/QueryBrowser.types.js.map +1 -1
  194. package/dist/data/useDebugAction.cjs +29 -0
  195. package/dist/data/useDebugAction.cjs.map +1 -0
  196. package/dist/data/useDebugAction.d.ts +16 -0
  197. package/dist/data/useDebugAction.d.ts.map +1 -0
  198. package/dist/data/useDebugAction.js +29 -0
  199. package/dist/data/useDebugAction.js.map +1 -0
  200. package/dist/data/version-info.cjs +3 -3
  201. package/dist/data/version-info.js +3 -3
  202. package/dist/data.cjs +16 -8
  203. package/dist/data.cjs.map +1 -1
  204. package/dist/data.d.ts +3 -2
  205. package/dist/data.d.ts.map +1 -1
  206. package/dist/data.js +16 -8
  207. package/dist/devtools/DebugConsole.cjs +138 -0
  208. package/dist/devtools/DebugConsole.cjs.map +1 -0
  209. package/dist/devtools/DebugConsole.d.ts +23 -0
  210. package/dist/devtools/DebugConsole.d.ts.map +1 -0
  211. package/dist/devtools/DebugConsole.js +138 -0
  212. package/dist/devtools/DebugConsole.js.map +1 -0
  213. package/dist/devtools/DebugConsoleButton.cjs +59 -0
  214. package/dist/devtools/DebugConsoleButton.cjs.map +1 -0
  215. package/dist/devtools/DebugConsoleButton.d.ts +20 -0
  216. package/dist/devtools/DebugConsoleButton.d.ts.map +1 -0
  217. package/dist/devtools/DebugConsoleButton.js +59 -0
  218. package/dist/devtools/DebugConsoleButton.js.map +1 -0
  219. package/dist/devtools/DebugConsoleDock.cjs +112 -0
  220. package/dist/devtools/DebugConsoleDock.cjs.map +1 -0
  221. package/dist/devtools/DebugConsoleDock.d.ts +26 -0
  222. package/dist/devtools/DebugConsoleDock.d.ts.map +1 -0
  223. package/dist/devtools/DebugConsoleDock.js +112 -0
  224. package/dist/devtools/DebugConsoleDock.js.map +1 -0
  225. package/dist/devtools/ExecutionDetail.cjs +135 -0
  226. package/dist/devtools/ExecutionDetail.cjs.map +1 -0
  227. package/dist/devtools/ExecutionDetail.d.ts +19 -0
  228. package/dist/devtools/ExecutionDetail.d.ts.map +1 -0
  229. package/dist/devtools/ExecutionDetail.js +135 -0
  230. package/dist/devtools/ExecutionDetail.js.map +1 -0
  231. package/dist/devtools/debugClient.cjs +172 -0
  232. package/dist/devtools/debugClient.cjs.map +1 -0
  233. package/dist/devtools/debugClient.d.ts +98 -0
  234. package/dist/devtools/debugClient.d.ts.map +1 -0
  235. package/dist/devtools/debugClient.js +172 -0
  236. package/dist/devtools/debugClient.js.map +1 -0
  237. package/dist/devtools/debugStore.cjs +115 -0
  238. package/dist/devtools/debugStore.cjs.map +1 -0
  239. package/dist/devtools/debugStore.d.ts +83 -0
  240. package/dist/devtools/debugStore.d.ts.map +1 -0
  241. package/dist/devtools/debugStore.js +115 -0
  242. package/dist/devtools/debugStore.js.map +1 -0
  243. package/dist/devtools/dockState.cjs +51 -0
  244. package/dist/devtools/dockState.cjs.map +1 -0
  245. package/dist/devtools/dockState.d.ts +31 -0
  246. package/dist/devtools/dockState.d.ts.map +1 -0
  247. package/dist/devtools/dockState.js +51 -0
  248. package/dist/devtools/dockState.js.map +1 -0
  249. package/dist/devtools/tabs/ConsoleTab.cjs +36 -0
  250. package/dist/devtools/tabs/ConsoleTab.cjs.map +1 -0
  251. package/dist/devtools/tabs/ConsoleTab.d.ts +19 -0
  252. package/dist/devtools/tabs/ConsoleTab.d.ts.map +1 -0
  253. package/dist/devtools/tabs/ConsoleTab.js +36 -0
  254. package/dist/devtools/tabs/ConsoleTab.js.map +1 -0
  255. package/dist/devtools/tabs/InspectionCaches.cjs +150 -0
  256. package/dist/devtools/tabs/InspectionCaches.cjs.map +1 -0
  257. package/dist/devtools/tabs/InspectionCaches.d.ts +23 -0
  258. package/dist/devtools/tabs/InspectionCaches.d.ts.map +1 -0
  259. package/dist/devtools/tabs/InspectionCaches.js +150 -0
  260. package/dist/devtools/tabs/InspectionCaches.js.map +1 -0
  261. package/dist/devtools/tabs/InspectionTab.cjs +316 -0
  262. package/dist/devtools/tabs/InspectionTab.cjs.map +1 -0
  263. package/dist/devtools/tabs/InspectionTab.d.ts +27 -0
  264. package/dist/devtools/tabs/InspectionTab.d.ts.map +1 -0
  265. package/dist/devtools/tabs/InspectionTab.js +316 -0
  266. package/dist/devtools/tabs/InspectionTab.js.map +1 -0
  267. package/dist/devtools/tabs/NetworkTab.cjs +91 -0
  268. package/dist/devtools/tabs/NetworkTab.cjs.map +1 -0
  269. package/dist/devtools/tabs/NetworkTab.d.ts +20 -0
  270. package/dist/devtools/tabs/NetworkTab.d.ts.map +1 -0
  271. package/dist/devtools/tabs/NetworkTab.js +91 -0
  272. package/dist/devtools/tabs/NetworkTab.js.map +1 -0
  273. package/dist/devtools/tabs/QueriesTab.cjs +85 -0
  274. package/dist/devtools/tabs/QueriesTab.cjs.map +1 -0
  275. package/dist/devtools/tabs/QueriesTab.d.ts +24 -0
  276. package/dist/devtools/tabs/QueriesTab.d.ts.map +1 -0
  277. package/dist/devtools/tabs/QueriesTab.js +85 -0
  278. package/dist/devtools/tabs/QueriesTab.js.map +1 -0
  279. package/dist/devtools/types.cjs +26 -0
  280. package/dist/devtools/types.cjs.map +1 -0
  281. package/dist/devtools/types.d.ts +235 -0
  282. package/dist/devtools/types.d.ts.map +1 -0
  283. package/dist/devtools/types.js +26 -0
  284. package/dist/devtools/types.js.map +1 -0
  285. package/dist/devtools/useDebugStream.cjs +46 -0
  286. package/dist/devtools/useDebugStream.cjs.map +1 -0
  287. package/dist/devtools/useDebugStream.d.ts +23 -0
  288. package/dist/devtools/useDebugStream.d.ts.map +1 -0
  289. package/dist/devtools/useDebugStream.js +46 -0
  290. package/dist/devtools/useDebugStream.js.map +1 -0
  291. package/dist/devtools.cjs +51 -0
  292. package/dist/devtools.cjs.map +1 -0
  293. package/dist/devtools.d.ts +37 -0
  294. package/dist/devtools.d.ts.map +1 -0
  295. package/dist/devtools.js +51 -0
  296. package/dist/devtools.js.map +1 -0
  297. package/dist/icons/components/UiOpenScad.cjs +10 -0
  298. package/dist/icons/components/UiOpenScad.cjs.map +1 -0
  299. package/dist/icons/components/UiOpenScad.d.ts +9 -0
  300. package/dist/icons/components/UiOpenScad.d.ts.map +1 -0
  301. package/dist/icons/components/UiOpenScad.js +10 -0
  302. package/dist/icons/components/UiOpenScad.js.map +1 -0
  303. package/dist/icons/index.d.ts +1 -0
  304. package/dist/icons/index.d.ts.map +1 -1
  305. package/dist/icons/registry.cjs +2 -0
  306. package/dist/icons/registry.cjs.map +1 -1
  307. package/dist/icons/registry.d.ts.map +1 -1
  308. package/dist/icons/registry.js +2 -0
  309. package/dist/icons/registry.js.map +1 -1
  310. package/dist/icons.cjs +2 -0
  311. package/dist/icons.cjs.map +1 -1
  312. package/dist/icons.js +2 -0
  313. package/dist/icons.js.map +1 -1
  314. package/dist/index.cjs +20 -8
  315. package/dist/index.cjs.map +1 -1
  316. package/dist/index.js +20 -8
  317. package/dist/index.js.map +1 -1
  318. package/dist/layout/AppShell.cjs +15 -10
  319. package/dist/layout/AppShell.cjs.map +1 -1
  320. package/dist/layout/AppShell.d.ts +11 -0
  321. package/dist/layout/AppShell.d.ts.map +1 -1
  322. package/dist/layout/AppShell.js +15 -10
  323. package/dist/layout/AppShell.js.map +1 -1
  324. package/dist/layout/AppShell.nav.cjs +170 -49
  325. package/dist/layout/AppShell.nav.cjs.map +1 -1
  326. package/dist/layout/AppShell.nav.d.ts.map +1 -1
  327. package/dist/layout/AppShell.nav.js +170 -49
  328. package/dist/layout/AppShell.nav.js.map +1 -1
  329. package/dist/overlay/CellActions.cjs +18 -124
  330. package/dist/overlay/CellActions.cjs.map +1 -1
  331. package/dist/overlay/CellActions.d.ts +1 -1
  332. package/dist/overlay/CellActions.d.ts.map +1 -1
  333. package/dist/overlay/CellActions.js +18 -124
  334. package/dist/overlay/CellActions.js.map +1 -1
  335. package/dist/overlay/ContextMenu.cjs +144 -0
  336. package/dist/overlay/ContextMenu.cjs.map +1 -0
  337. package/dist/overlay/ContextMenu.d.ts +8 -0
  338. package/dist/overlay/ContextMenu.d.ts.map +1 -0
  339. package/dist/overlay/ContextMenu.js +144 -0
  340. package/dist/overlay/ContextMenu.js.map +1 -0
  341. package/dist/profiles/connections/connectionBrowserModel.cjs +14 -65
  342. package/dist/profiles/connections/connectionBrowserModel.cjs.map +1 -1
  343. package/dist/profiles/connections/connectionBrowserModel.d.ts +35 -35
  344. package/dist/profiles/connections/connectionBrowserModel.d.ts.map +1 -1
  345. package/dist/profiles/connections/connectionBrowserModel.js +14 -65
  346. package/dist/profiles/connections/connectionBrowserModel.js.map +1 -1
  347. package/dist/profiles/connections/connectionQueryWorkspace.cjs +29 -9
  348. package/dist/profiles/connections/connectionQueryWorkspace.cjs.map +1 -1
  349. package/dist/profiles/connections/connectionQueryWorkspace.d.ts +3 -2
  350. package/dist/profiles/connections/connectionQueryWorkspace.d.ts.map +1 -1
  351. package/dist/profiles/connections/connectionQueryWorkspace.js +30 -10
  352. package/dist/profiles/connections/connectionQueryWorkspace.js.map +1 -1
  353. package/dist/profiles/connections/connectionQueryWorkspaceModel.cjs +15 -0
  354. package/dist/profiles/connections/connectionQueryWorkspaceModel.cjs.map +1 -1
  355. package/dist/profiles/connections/connectionQueryWorkspaceModel.d.ts +22 -1
  356. package/dist/profiles/connections/connectionQueryWorkspaceModel.d.ts.map +1 -1
  357. package/dist/profiles/connections/connectionQueryWorkspaceModel.js +15 -0
  358. package/dist/profiles/connections/connectionQueryWorkspaceModel.js.map +1 -1
  359. package/dist/profiles/connections/index.d.ts +1 -0
  360. package/dist/profiles/connections/index.d.ts.map +1 -1
  361. package/dist/profiles/connections/inspectionStatus.cjs +44 -0
  362. package/dist/profiles/connections/inspectionStatus.cjs.map +1 -0
  363. package/dist/profiles/connections/inspectionStatus.d.ts +5 -0
  364. package/dist/profiles/connections/inspectionStatus.d.ts.map +1 -0
  365. package/dist/profiles/connections/inspectionStatus.js +44 -0
  366. package/dist/profiles/connections/inspectionStatus.js.map +1 -0
  367. package/dist/profiles/connections/useInspection.cjs +123 -0
  368. package/dist/profiles/connections/useInspection.cjs.map +1 -0
  369. package/dist/profiles/connections/useInspection.d.ts +35 -0
  370. package/dist/profiles/connections/useInspection.d.ts.map +1 -0
  371. package/dist/profiles/connections/useInspection.js +123 -0
  372. package/dist/profiles/connections/useInspection.js.map +1 -0
  373. package/dist/profiles/editor/profileBuilderWorkspace.cjs +55 -23
  374. package/dist/profiles/editor/profileBuilderWorkspace.cjs.map +1 -1
  375. package/dist/profiles/editor/profileBuilderWorkspace.d.ts.map +1 -1
  376. package/dist/profiles/editor/profileBuilderWorkspace.js +56 -24
  377. package/dist/profiles/editor/profileBuilderWorkspace.js.map +1 -1
  378. package/dist/profiles/elasticsearch/esQueryBuilder.cjs +12 -3
  379. package/dist/profiles/elasticsearch/esQueryBuilder.cjs.map +1 -1
  380. package/dist/profiles/elasticsearch/esQueryBuilder.d.ts +2 -2
  381. package/dist/profiles/elasticsearch/esQueryBuilder.d.ts.map +1 -1
  382. package/dist/profiles/elasticsearch/esQueryBuilder.js +12 -3
  383. package/dist/profiles/elasticsearch/esQueryBuilder.js.map +1 -1
  384. package/dist/profiles/fields/profileFieldEditor.cjs +137 -22
  385. package/dist/profiles/fields/profileFieldEditor.cjs.map +1 -1
  386. package/dist/profiles/fields/profileFieldEditor.d.ts.map +1 -1
  387. package/dist/profiles/fields/profileFieldEditor.js +137 -22
  388. package/dist/profiles/fields/profileFieldEditor.js.map +1 -1
  389. package/dist/profiles/fields/profileFieldFilterEditor.cjs +171 -82
  390. package/dist/profiles/fields/profileFieldFilterEditor.cjs.map +1 -1
  391. package/dist/profiles/fields/profileFieldFilterEditor.d.ts +0 -9
  392. package/dist/profiles/fields/profileFieldFilterEditor.d.ts.map +1 -1
  393. package/dist/profiles/fields/profileFieldFilterEditor.js +174 -85
  394. package/dist/profiles/fields/profileFieldFilterEditor.js.map +1 -1
  395. package/dist/profiles/fields/profileFieldIcons.cjs +6 -3
  396. package/dist/profiles/fields/profileFieldIcons.cjs.map +1 -1
  397. package/dist/profiles/fields/profileFieldIcons.js +6 -3
  398. package/dist/profiles/fields/profileFieldIcons.js.map +1 -1
  399. package/dist/profiles/query/profileSampleFilterLookup.cjs +34 -0
  400. package/dist/profiles/query/profileSampleFilterLookup.cjs.map +1 -0
  401. package/dist/profiles/query/profileSampleFilterLookup.d.ts +12 -0
  402. package/dist/profiles/query/profileSampleFilterLookup.d.ts.map +1 -0
  403. package/dist/profiles/query/profileSampleFilterLookup.js +34 -0
  404. package/dist/profiles/query/profileSampleFilterLookup.js.map +1 -0
  405. package/dist/profiles/query/profileSamplePayload.cjs +6 -4
  406. package/dist/profiles/query/profileSamplePayload.cjs.map +1 -1
  407. package/dist/profiles/query/profileSamplePayload.d.ts +11 -4
  408. package/dist/profiles/query/profileSamplePayload.d.ts.map +1 -1
  409. package/dist/profiles/query/profileSamplePayload.js +6 -4
  410. package/dist/profiles/query/profileSamplePayload.js.map +1 -1
  411. package/dist/profiles/query/profileSampleResult.cjs +26 -0
  412. package/dist/profiles/query/profileSampleResult.cjs.map +1 -0
  413. package/dist/profiles/query/profileSampleResult.d.ts +11 -0
  414. package/dist/profiles/query/profileSampleResult.d.ts.map +1 -0
  415. package/dist/profiles/query/profileSampleResult.js +26 -0
  416. package/dist/profiles/query/profileSampleResult.js.map +1 -0
  417. package/dist/profiles/query/queryTargetPicker.cjs +5 -3
  418. package/dist/profiles/query/queryTargetPicker.cjs.map +1 -1
  419. package/dist/profiles/query/queryTargetPicker.d.ts +3 -2
  420. package/dist/profiles/query/queryTargetPicker.d.ts.map +1 -1
  421. package/dist/profiles/query/queryTargetPicker.js +5 -3
  422. package/dist/profiles/query/queryTargetPicker.js.map +1 -1
  423. package/dist/profiles/wizard/profileWizard.cjs +14 -5
  424. package/dist/profiles/wizard/profileWizard.cjs.map +1 -1
  425. package/dist/profiles/wizard/profileWizard.d.ts.map +1 -1
  426. package/dist/profiles/wizard/profileWizard.js +15 -6
  427. package/dist/profiles/wizard/profileWizard.js.map +1 -1
  428. package/dist/profiles/wizard/profileWizardModel.cjs +35 -6
  429. package/dist/profiles/wizard/profileWizardModel.cjs.map +1 -1
  430. package/dist/profiles/wizard/profileWizardModel.d.ts +29 -4
  431. package/dist/profiles/wizard/profileWizardModel.d.ts.map +1 -1
  432. package/dist/profiles/wizard/profileWizardModel.js +35 -6
  433. package/dist/profiles/wizard/profileWizardModel.js.map +1 -1
  434. package/dist/profiles/wizard/profileWizardQueryStep.cjs +44 -11
  435. package/dist/profiles/wizard/profileWizardQueryStep.cjs.map +1 -1
  436. package/dist/profiles/wizard/profileWizardQueryStep.d.ts.map +1 -1
  437. package/dist/profiles/wizard/profileWizardQueryStep.js +46 -13
  438. package/dist/profiles/wizard/profileWizardQueryStep.js.map +1 -1
  439. package/dist/profiles/wizard/profileWizardSteps.cjs +33 -2
  440. package/dist/profiles/wizard/profileWizardSteps.cjs.map +1 -1
  441. package/dist/profiles/wizard/profileWizardSteps.d.ts +11 -2
  442. package/dist/profiles/wizard/profileWizardSteps.d.ts.map +1 -1
  443. package/dist/profiles/wizard/profileWizardSteps.js +33 -2
  444. package/dist/profiles/wizard/profileWizardSteps.js.map +1 -1
  445. package/dist/profiles.cjs +8 -2
  446. package/dist/profiles.cjs.map +1 -1
  447. package/dist/profiles.js +10 -4
  448. package/dist/profiles.js.map +1 -1
  449. package/dist/rpc/FilterForm.cjs +21 -237
  450. package/dist/rpc/FilterForm.cjs.map +1 -1
  451. package/dist/rpc/FilterForm.d.ts +3 -1
  452. package/dist/rpc/FilterForm.d.ts.map +1 -1
  453. package/dist/rpc/FilterForm.js +21 -237
  454. package/dist/rpc/FilterForm.js.map +1 -1
  455. package/dist/rpc/FilterFormFields.cjs +240 -0
  456. package/dist/rpc/FilterFormFields.cjs.map +1 -0
  457. package/dist/rpc/FilterFormFields.d.ts +12 -0
  458. package/dist/rpc/FilterFormFields.d.ts.map +1 -0
  459. package/dist/rpc/FilterFormFields.js +240 -0
  460. package/dist/rpc/FilterFormFields.js.map +1 -0
  461. package/dist/rpc/router.cjs +3 -2
  462. package/dist/rpc/router.cjs.map +1 -1
  463. package/dist/rpc/router.d.ts.map +1 -1
  464. package/dist/rpc/router.js +3 -2
  465. package/dist/rpc/router.js.map +1 -1
  466. package/dist/rpc/types.cjs.map +1 -1
  467. package/dist/rpc/types.d.ts +3 -1
  468. package/dist/rpc/types.d.ts.map +1 -1
  469. package/dist/rpc/types.js.map +1 -1
  470. package/dist/styles.css +1 -1
  471. package/package.json +6 -1
  472. package/dist/data/query-info/QueryInfoDialog.cjs +0 -106
  473. package/dist/data/query-info/QueryInfoDialog.cjs.map +0 -1
  474. package/dist/data/query-info/QueryInfoDialog.d.ts +0 -16
  475. package/dist/data/query-info/QueryInfoDialog.d.ts.map +0 -1
  476. package/dist/data/query-info/QueryInfoDialog.js +0 -106
  477. package/dist/data/query-info/QueryInfoDialog.js.map +0 -1
  478. package/dist/data/query-info/index.d.ts +0 -4
  479. package/dist/data/query-info/index.d.ts.map +0 -1
  480. package/dist/data/query-info/queryInfo.cjs +0 -42
  481. package/dist/data/query-info/queryInfo.cjs.map +0 -1
  482. package/dist/data/query-info/queryInfo.d.ts +0 -45
  483. package/dist/data/query-info/queryInfo.d.ts.map +0 -1
  484. package/dist/data/query-info/queryInfo.js +0 -42
  485. package/dist/data/query-info/queryInfo.js.map +0 -1
  486. package/dist/data/query-info/useQueryInfo.cjs +0 -48
  487. package/dist/data/query-info/useQueryInfo.cjs.map +0 -1
  488. package/dist/data/query-info/useQueryInfo.d.ts +0 -26
  489. package/dist/data/query-info/useQueryInfo.d.ts.map +0 -1
  490. package/dist/data/query-info/useQueryInfo.js +0 -48
  491. package/dist/data/query-info/useQueryInfo.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TaskProcessDetails.js","sources":["../../src/data/TaskProcessDetails.tsx"],"sourcesContent":["import { UiActivity, UiDatabase, UiFile } from \"../icons\";\nimport { TimeseriesGauge } from \"./TimeseriesGauge\";\nimport { DiagnosticsTree } from \"./diagnostics/DiagnosticsTree\";\nimport { formatBytes } from \"./diagnostics/utils\";\nimport { buildTaskProcessForest } from \"./task-process-details\";\nimport type { TaskProcessDetails } from \"./TaskSnapshot\";\n\nexport function TaskProcessDetailsView({\n details,\n metricsBaseUrl,\n}: {\n details: TaskProcessDetails;\n metricsBaseUrl?: string;\n}) {\n const forest = buildTaskProcessForest(details.tree ?? []);\n const metricBase = metricsBaseUrl ?? \"/api/v1/tasks/metrics/\";\n const restartLabel = `${details.restarts} ${details.restarts === 1 ? \"restart\" : \"restarts\"}`;\n\n return (\n <section className=\"mb-3 space-y-3 rounded-md border bg-muted/20 p-3\">\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground\">\n <span className=\"font-mono text-foreground\">pid {details.pid ?? \"—\"}</span>\n <span>{details.status}</span>\n <span>{details.latest.cpuPercent.toFixed(1)}% CPU</span>\n <span>{formatBytes(details.latest.rssBytes)} RSS</span>\n <span>{formatBytes(details.latest.vmsBytes)} VMS</span>\n <span>{details.latest.openFiles >= 0 ? `${details.latest.openFiles} files` : \"files unavailable\"}</span>\n <span>{restartLabel}</span>\n <span>{details.restartPolicy}</span>\n <span>\n Peak {details.peak.cpuPercent.toFixed(1)}% CPU · {formatBytes(details.peak.rssBytes)} RSS · {formatBytes(details.peak.vmsBytes)} VMS · {details.peak.openFiles >= 0 ? `${details.peak.openFiles} files` : \"files unavailable\"}\n </span>\n </div>\n\n {Object.keys(details.metrics).length > 0 && (\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2 xl:grid-cols-4\">\n {details.metrics.cpu && (\n <TimeseriesGauge\n baseUrl={metricBase}\n value={{ id: encodeURIComponent(details.metrics.cpu) }}\n title=\"CPU\"\n icon={UiActivity}\n unit=\"percent\"\n variant=\"cell\"\n range=\"15m\"\n refreshMs={2000}\n />\n )}\n {details.metrics.rss && (\n <TimeseriesGauge\n baseUrl={metricBase}\n value={{ id: encodeURIComponent(details.metrics.rss) }}\n title=\"RSS\"\n icon={UiDatabase}\n unit=\"bytes\"\n variant=\"cell\"\n range=\"15m\"\n refreshMs={2000}\n />\n )}\n {details.metrics.vms && (\n <TimeseriesGauge\n baseUrl={metricBase}\n value={{ id: encodeURIComponent(details.metrics.vms) }}\n title=\"VMS\"\n icon={UiDatabase}\n unit=\"bytes\"\n variant=\"cell\"\n range=\"15m\"\n refreshMs={2000}\n />\n )}\n {details.metrics.openFiles && (\n <TimeseriesGauge\n baseUrl={metricBase}\n value={{ id: encodeURIComponent(details.metrics.openFiles) }}\n title=\"Open files\"\n icon={UiFile}\n unit=\"short\"\n variant=\"cell\"\n range=\"15m\"\n refreshMs={2000}\n />\n )}\n </div>\n )}\n\n {forest.length > 0 && (\n <div className=\"space-y-1\">\n <div className=\"text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n Process tree\n </div>\n <div className=\"overflow-hidden rounded-md border bg-background\">\n {forest.map((root) => (\n <DiagnosticsTree key={root.pid} root={root} expandAll onSelect={() => {}} />\n ))}\n </div>\n </div>\n )}\n </section>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TaskProcessDetails.js","sources":["../../src/data/TaskProcessDetails.tsx"],"sourcesContent":["import { UiActivity, UiDatabase, UiFile } from \"../icons\";\nimport { TimeseriesGauge } from \"./TimeseriesGauge\";\nimport { DiagnosticsTree } from \"./diagnostics/DiagnosticsTree\";\nimport { formatBytes } from \"./diagnostics/utils\";\nimport { buildTaskProcessForest } from \"./task-process-details\";\nimport { TaskCommandLine } from \"./TaskExecDetails\";\nimport type { TaskProcessDetails } from \"./TaskSnapshot\";\n\nexport function TaskProcessDetailsView({\n details,\n metricsBaseUrl,\n}: {\n details: TaskProcessDetails;\n metricsBaseUrl?: string;\n}) {\n const forest = buildTaskProcessForest(details.tree ?? []);\n const metricBase = metricsBaseUrl ?? \"/api/v1/tasks/metrics/\";\n const restartLabel = `${details.restarts} ${details.restarts === 1 ? \"restart\" : \"restarts\"}`;\n\n return (\n <section className=\"mb-3 space-y-3 rounded-md border bg-muted/20 p-3\">\n <TaskCommandLine command={details.command} {...(details.args ? { args: details.args } : {})} />\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground\">\n <span className=\"font-mono text-foreground\">pid {details.pid ?? \"—\"}</span>\n <span>{details.status}</span>\n <span>{details.latest.cpuPercent.toFixed(1)}% CPU</span>\n <span>{formatBytes(details.latest.rssBytes)} RSS</span>\n <span>{formatBytes(details.latest.vmsBytes)} VMS</span>\n <span>{details.latest.openFiles >= 0 ? `${details.latest.openFiles} files` : \"files unavailable\"}</span>\n <span>{restartLabel}</span>\n <span>{details.restartPolicy}</span>\n <span>\n Peak {details.peak.cpuPercent.toFixed(1)}% CPU · {formatBytes(details.peak.rssBytes)} RSS · {formatBytes(details.peak.vmsBytes)} VMS · {details.peak.openFiles >= 0 ? `${details.peak.openFiles} files` : \"files unavailable\"}\n </span>\n </div>\n\n {Object.keys(details.metrics).length > 0 && (\n <div className=\"grid grid-cols-1 gap-2 sm:grid-cols-2 xl:grid-cols-4\">\n {details.metrics.cpu && (\n <TimeseriesGauge\n baseUrl={metricBase}\n value={{ id: encodeURIComponent(details.metrics.cpu) }}\n title=\"CPU\"\n icon={UiActivity}\n unit=\"percent\"\n variant=\"cell\"\n range=\"15m\"\n refreshMs={2000}\n />\n )}\n {details.metrics.rss && (\n <TimeseriesGauge\n baseUrl={metricBase}\n value={{ id: encodeURIComponent(details.metrics.rss) }}\n title=\"RSS\"\n icon={UiDatabase}\n unit=\"bytes\"\n variant=\"cell\"\n range=\"15m\"\n refreshMs={2000}\n />\n )}\n {details.metrics.vms && (\n <TimeseriesGauge\n baseUrl={metricBase}\n value={{ id: encodeURIComponent(details.metrics.vms) }}\n title=\"VMS\"\n icon={UiDatabase}\n unit=\"bytes\"\n variant=\"cell\"\n range=\"15m\"\n refreshMs={2000}\n />\n )}\n {details.metrics.openFiles && (\n <TimeseriesGauge\n baseUrl={metricBase}\n value={{ id: encodeURIComponent(details.metrics.openFiles) }}\n title=\"Open files\"\n icon={UiFile}\n unit=\"short\"\n variant=\"cell\"\n range=\"15m\"\n refreshMs={2000}\n />\n )}\n </div>\n )}\n\n {forest.length > 0 && (\n <div className=\"space-y-1\">\n <div className=\"text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n Process tree\n </div>\n <div className=\"overflow-hidden rounded-md border bg-background\">\n {forest.map((root) => (\n <DiagnosticsTree key={root.pid} root={root} expandAll onSelect={() => {}} />\n ))}\n </div>\n </div>\n )}\n </section>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -130,7 +130,8 @@ function TaskGroupCard({
130
130
  {
131
131
  task: t,
132
132
  group: g,
133
- ...onTaskControl ? { onTaskControl } : {}
133
+ ...onTaskControl ? { onTaskControl } : {},
134
+ ...metricsBaseUrl ? { metricsBaseUrl } : {}
134
135
  },
135
136
  t.id
136
137
  ))
@@ -139,14 +140,16 @@ function TaskGroupCard({
139
140
  function TaskRow({
140
141
  task: t,
141
142
  group,
142
- onTaskControl
143
+ onTaskControl,
144
+ metricsBaseUrl
143
145
  }) {
144
146
  const [expanded, setExpanded] = react.useState(false);
145
147
  const logs = t.logs ?? [];
146
148
  const hasLogs = logs.length > 0;
147
149
  const hasOutput = !!t.stdout || !!t.stderr;
148
150
  const execDetails = taskExecDetails.isTaskExecDetails(t.details) ? t.details : void 0;
149
- const expandable = hasLogs || hasOutput || execDetails !== void 0;
151
+ const processDetails = taskProcessDetails.isTaskProcessDetails(t.details) ? t.details : void 0;
152
+ const expandable = hasLogs || hasOutput || execDetails !== void 0 || processDetails !== void 0;
150
153
  const latestWarn = t.error ? void 0 : logs.filter((l) => l.level === "warn").at(-1);
151
154
  const done = t.progress ?? 0;
152
155
  const hasProgress = typeof t.maxValue === "number" && t.maxValue > 0 && done > 0;
@@ -173,7 +176,7 @@ function TaskRow({
173
176
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: t.name }),
174
177
  t.error && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs font-normal text-red-500", children: t.error }),
175
178
  latestWarn && /* @__PURE__ */ jsxRuntime.jsx("span", { className: utils.cn("truncate text-xs font-normal", taskStatus.logLevelColor("warn")), children: latestWarn.message }),
176
- expandable && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center rounded-full bg-muted px-1.5 text-[10px] font-medium text-muted-foreground", children: logs.length + (t.stdout ? 1 : 0) + (t.stderr ? 1 : 0) + (execDetails ? 1 : 0) })
179
+ expandable && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex shrink-0 items-center rounded-full bg-muted px-1.5 text-[10px] font-medium text-muted-foreground", children: logs.length + (t.stdout ? 1 : 0) + (t.stderr ? 1 : 0) + (execDetails || processDetails ? 1 : 0) })
177
180
  ] }),
178
181
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
179
182
  t.duration && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: t.duration }),
@@ -208,6 +211,13 @@ function TaskRow({
208
211
  }
209
212
  ) }),
210
213
  expanded && execDetails && /* @__PURE__ */ jsxRuntime.jsx(TaskExecDetails.TaskExecDetailsView, { details: execDetails }),
214
+ expanded && processDetails && /* @__PURE__ */ jsxRuntime.jsx(
215
+ TaskProcessDetails.TaskProcessDetailsView,
216
+ {
217
+ details: processDetails,
218
+ ...metricsBaseUrl ? { metricsBaseUrl } : {}
219
+ }
220
+ ),
211
221
  expanded && hasLogs && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 ml-1 max-h-48 space-y-0.5 overflow-y-auto border-l-2 pl-2", children: logs.map((l, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("text-xs", taskStatus.logLevelColor(l.level)), children: [
212
222
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-1 font-mono text-muted-foreground", children: l.level.substring(0, 3) }),
213
223
  l.message
@@ -1 +1 @@
1
- {"version":3,"file":"TaskProgress.cjs","sources":["../../src/data/TaskProgress.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { Button } from \"../components/button\";\nimport { UiPlay, UiRestart, UiStop } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { AnsiHtml } from \"./AnsiHtml\";\nimport { Icon } from \"./Icon\";\nimport { ProgressBar } from \"./ProgressBar\";\nimport { TaskProcessDetailsView } from \"./TaskProcessDetails\";\nimport { TaskExecDetailsView } from \"./TaskExecDetails\";\nimport type { LogEntry, TaskControlAction, TaskSnapshot } from \"./TaskSnapshot\";\nimport { isTaskExecDetails } from \"./task-exec-details\";\nimport { isTaskProcessDetails } from \"./task-process-details\";\nimport {\n bucketTasks,\n logLevelColor,\n taskSegments,\n taskStatusBg,\n taskStatusColor,\n taskStatusIcon,\n} from \"./task-status\";\n\n// TaskProgress renders one or more clicky task runs (groups) and their child\n// tasks: a segmented progress bar per group plus collapsible per-task rows with\n// status icon, duration, error, and expandable logs. Presentational only —\n// callers feed it snapshots from useTaskRun (SSE) or any other source.\n\nconst MAX_COMPLETED = 5;\nconst MAX_PENDING = 3;\n\nexport interface TaskProgressProps {\n snapshots: TaskSnapshot[];\n title?: string;\n /** Tighter spacing for embedding in a panel. */\n compact?: boolean;\n className?: string;\n onControl?: (action: TaskControlAction, group: TaskSnapshot) => void | Promise<void>;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n metricsBaseUrl?: string;\n}\n\nexport function TaskProgress({\n snapshots,\n title,\n compact,\n className,\n onControl,\n onTaskControl,\n metricsBaseUrl,\n}: TaskProgressProps) {\n const groups = snapshots.filter((s) => s.type === \"group\");\n const tasks = snapshots.filter((s) => s.type === \"task\");\n\n if (groups.length === 0) {\n return (\n <div className={cn(\"text-sm text-muted-foreground\", className)}>\n {title ? `${title}: ` : \"\"}No tasks yet.\n </div>\n );\n }\n\n return (\n <div className={cn(compact ? \"space-y-2\" : \"space-y-3\", className)}>\n {title && <h2 className=\"text-sm font-semibold\">{title}</h2>}\n {groups.map((g) => (\n <TaskGroupCard\n key={g.groupId || g.id}\n group={g}\n tasks={tasks.filter((t) => t.groupId === g.groupId || t.group === g.id)}\n compact={compact}\n {...(onControl ? { onControl } : {})}\n {...(onTaskControl ? { onTaskControl } : {})}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n ))}\n </div>\n );\n}\n\nfunction isFailedOrWarn(t: TaskSnapshot): boolean {\n return t.status === \"failed\" || t.status === \"FAIL\" || t.status === \"ERR\" || t.status === \"warning\";\n}\n\nfunction TaskGroupCard({\n group: g,\n tasks,\n compact,\n onControl,\n onTaskControl,\n metricsBaseUrl,\n}: {\n group: TaskSnapshot;\n tasks: TaskSnapshot[];\n compact: boolean | undefined;\n onControl?: (action: TaskControlAction, group: TaskSnapshot) => void | Promise<void>;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n metricsBaseUrl?: string;\n}) {\n const [showAll, setShowAll] = useState(false);\n const total = g.total ?? tasks.length;\n const counts = bucketTasks(tasks);\n const done = counts.ok + counts.warn + counts.fail;\n const progress = total > 0 ? `${done}/${total}` : \"\";\n\n const running = tasks.filter((t) => t.status === \"running\");\n const pending = tasks.filter((t) => t.status === \"pending\");\n const completed = tasks.filter((t) => t.status !== \"running\" && t.status !== \"pending\");\n const alwaysShow = completed.filter(isFailedOrWarn);\n const collapsible = completed.filter((t) => !isFailedOrWarn(t));\n\n const hiddenCompleted = collapsible.length - MAX_COMPLETED;\n const collapseCompleted = !showAll && hiddenCompleted > 0;\n const visibleSuccess = collapseCompleted ? collapsible.slice(-MAX_COMPLETED) : collapsible;\n\n const hiddenPending = pending.length - MAX_PENDING;\n const collapsePending = !showAll && hiddenPending > 0;\n const visiblePending = collapsePending ? pending.slice(0, MAX_PENDING) : pending;\n\n const isTerminal = g.status !== \"running\" && g.status !== \"pending\";\n\n return (\n <div className={cn(\"rounded-lg border bg-card\", compact ? \"p-3\" : \"p-4\")}>\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <h3 className=\"flex items-center gap-1.5 text-sm font-semibold\">\n <Icon\n icon={taskStatusIcon(g.status)}\n className={cn(taskStatusColor(g.status), g.status === \"running\" && \"animate-spin\")}\n />\n <span>{g.name}</span>\n {progress && <span className=\"text-xs text-muted-foreground\">{progress}</span>}\n {g.kind && (\n <span className=\"rounded-full bg-muted px-1.5 py-0 text-[10px] text-muted-foreground\">\n {g.kind}\n </span>\n )}\n </h3>\n <div className=\"flex shrink-0 items-center gap-1\">\n {isTerminal && (\n <span\n className={cn(\n \"rounded-full px-2 py-0.5 text-xs\",\n taskStatusColor(g.status),\n taskStatusBg(g.status),\n )}\n >\n {g.status}\n </span>\n )}\n {onControl && <TaskControls target={g} onControl={onControl} />}\n </div>\n </div>\n\n {total > 0 && (\n <div className=\"mb-3\">\n <ProgressBar segments={taskSegments(counts)} total={total} height=\"h-1.5\" />\n </div>\n )}\n\n {isTaskProcessDetails(g.details) && (\n <TaskProcessDetailsView\n details={g.details}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n )}\n\n {!isTaskProcessDetails(g.details) && isTaskExecDetails(g.details) && (\n <TaskExecDetailsView details={g.details} />\n )}\n\n {hiddenCompleted > 0 || hiddenPending > 0 ? (\n <button\n type=\"button\"\n className=\"border-b py-1.5 text-xs text-muted-foreground hover:text-foreground\"\n onClick={() => setShowAll((v) => !v)}\n >\n {showAll\n ? \"▲ collapse\"\n : `... ${(collapseCompleted ? hiddenCompleted : 0) + (collapsePending ? hiddenPending : 0)} more tasks`}\n </button>\n ) : null}\n\n {[...visibleSuccess, ...alwaysShow, ...running, ...visiblePending].map((t) => (\n <TaskRow\n key={t.id}\n task={t}\n group={g}\n {...(onTaskControl ? { onTaskControl } : {})}\n />\n ))}\n </div>\n );\n}\n\nfunction TaskRow({\n task: t,\n group,\n onTaskControl,\n}: {\n task: TaskSnapshot;\n group: TaskSnapshot;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n}) {\n const [expanded, setExpanded] = useState(false);\n const logs: LogEntry[] = t.logs ?? [];\n const hasLogs = logs.length > 0;\n const hasOutput = !!t.stdout || !!t.stderr;\n const execDetails = isTaskExecDetails(t.details) ? t.details : undefined;\n const expandable = hasLogs || hasOutput || execDetails !== undefined;\n // Promote the latest warning message inline so a `warning` row shows its\n // reason without expanding. Suppressed when an error is already shown.\n const latestWarn = t.error ? undefined : logs.filter((l) => l.level === \"warn\").at(-1);\n // Bounded per-task progress (e.g. records emitted in a phase): render an x/y\n // count, a percentage, and a thin bar while the task runs.\n const done = t.progress ?? 0;\n // Only surface bounded progress once work has actually started — an untouched\n // task should not render a \"0/100 · 0%\" placeholder.\n const hasProgress = typeof t.maxValue === \"number\" && t.maxValue > 0 && done > 0;\n const pct = hasProgress ? Math.round((done / (t.maxValue as number)) * 100) : 0;\n\n return (\n <div\n className={cn(\n \"flex items-start gap-3 border-b py-2 last:border-0\",\n expandable && \"-mx-1 cursor-pointer rounded px-1 hover:bg-muted/50\",\n )}\n onClick={expandable ? () => setExpanded((v) => !v) : undefined}\n >\n <Icon\n icon={taskStatusIcon(t.status)}\n className={cn(taskStatusColor(t.status), \"mt-0.5 text-lg\", t.status === \"running\" && \"animate-spin\")}\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-1.5 text-sm font-medium\">\n <span className=\"truncate\">{t.name}</span>\n {t.error && <span className=\"truncate text-xs font-normal text-red-500\">{t.error}</span>}\n {latestWarn && (\n <span className={cn(\"truncate text-xs font-normal\", logLevelColor(\"warn\"))}>\n {latestWarn.message}\n </span>\n )}\n {expandable && (\n <span className=\"inline-flex shrink-0 items-center rounded-full bg-muted px-1.5 text-[10px] font-medium text-muted-foreground\">\n {logs.length + (t.stdout ? 1 : 0) + (t.stderr ? 1 : 0) + (execDetails ? 1 : 0)}\n </span>\n )}\n </span>\n <div className=\"flex shrink-0 items-center gap-1\">\n {t.duration && <span className=\"text-xs text-muted-foreground\">{t.duration}</span>}\n {onTaskControl && (\n <TaskControls\n target={t}\n labelSuffix={t.name}\n stopPropagation\n onControl={(action) => onTaskControl(action, t, group)}\n />\n )}\n </div>\n </div>\n {(t.description || hasProgress) && (\n <div className=\"mt-0.5 flex items-center gap-2\">\n {t.description && (\n <span className=\"min-w-0 flex-1 truncate text-xs text-muted-foreground\">{t.description}</span>\n )}\n {hasProgress && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {done}/{t.maxValue} · {pct}%\n </span>\n )}\n </div>\n )}\n {hasProgress && t.status === \"running\" && (\n <div className=\"mt-1\">\n <ProgressBar\n segments={[{ count: done, color: \"bg-blue-500\", label: \"done\" }]}\n total={t.maxValue as number}\n height=\"h-1\"\n />\n </div>\n )}\n {expanded && execDetails && <TaskExecDetailsView details={execDetails} />}\n {expanded && hasLogs && (\n <div className=\"mt-1 ml-1 max-h-48 space-y-0.5 overflow-y-auto border-l-2 pl-2\">\n {logs.map((l, i) => (\n <div key={i} className={cn(\"text-xs\", logLevelColor(l.level))}>\n <span className=\"mr-1 font-mono text-muted-foreground\">{l.level.substring(0, 3)}</span>\n {l.message}\n </div>\n ))}\n </div>\n )}\n {expanded && hasOutput && (\n <div className=\"mt-2 space-y-2\">\n {t.stdout && <TaskStream label=\"stdout\" text={t.stdout} {...(t.stdoutTruncated ? { truncated: true } : {})} />}\n {t.stderr && <TaskStream label=\"stderr\" text={t.stderr} {...(t.stderrTruncated ? { truncated: true } : {})} error />}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction TaskStream({\n label,\n text,\n truncated,\n error,\n}: {\n label: string;\n text: string;\n truncated?: boolean;\n error?: boolean;\n}) {\n return (\n <div className=\"overflow-hidden rounded border bg-black\">\n <div className=\"flex items-center justify-between border-b border-white/10 px-2 py-1 text-[10px] text-gray-400\">\n <span>{label}</span>\n {truncated && <span>showing latest 1 MiB</span>}\n </div>\n <AnsiHtml\n text={text}\n className={cn(\"max-h-64 overflow-auto whitespace-pre-wrap p-2 text-xs text-gray-100\", error && \"text-red-300\")}\n />\n </div>\n );\n}\n\nfunction TaskControls({\n target,\n onControl,\n labelSuffix,\n stopPropagation,\n}: {\n target: TaskSnapshot;\n onControl: (action: TaskControlAction, target: TaskSnapshot) => void | Promise<void>;\n labelSuffix?: string;\n stopPropagation?: boolean;\n}) {\n const [busy, setBusy] = useState<TaskControlAction | null>(null);\n const [error, setError] = useState(\"\");\n const icons = { start: UiPlay, stop: UiStop, restart: UiRestart };\n const invoke = async (action: TaskControlAction) => {\n setBusy(action);\n setError(\"\");\n try {\n await onControl(action, target);\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : `Failed to ${action} task`);\n } finally {\n setBusy(null);\n }\n };\n return (\n <>\n {(target.controls ?? []).map((action) => {\n const ControlIcon = icons[action];\n const actionLabel = action[0]?.toUpperCase() + action.slice(1);\n const label = labelSuffix ? `${actionLabel} ${labelSuffix}` : actionLabel;\n return (\n <Button\n key={action}\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n title={label}\n disabled={busy !== null}\n onClick={(event) => {\n if (stopPropagation) event.stopPropagation();\n void invoke(action);\n }}\n >\n <ControlIcon />\n </Button>\n );\n })}\n {error && <span role=\"alert\" className=\"text-xs text-red-600\">{error}</span>}\n </>\n );\n}\n"],"names":["cn","jsxs","jsx","useState","bucketTasks","Icon","taskStatusIcon","taskStatusColor","taskStatusBg","ProgressBar","taskSegments","isTaskProcessDetails","TaskProcessDetailsView","isTaskExecDetails","TaskExecDetailsView","logLevelColor","AnsiHtml","UiPlay","UiStop","UiRestart","Fragment","Button"],"mappings":"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"}
1
+ {"version":3,"file":"TaskProgress.cjs","sources":["../../src/data/TaskProgress.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { Button } from \"../components/button\";\nimport { UiPlay, UiRestart, UiStop } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { AnsiHtml } from \"./AnsiHtml\";\nimport { Icon } from \"./Icon\";\nimport { ProgressBar } from \"./ProgressBar\";\nimport { TaskProcessDetailsView } from \"./TaskProcessDetails\";\nimport { TaskExecDetailsView } from \"./TaskExecDetails\";\nimport type { LogEntry, TaskControlAction, TaskSnapshot } from \"./TaskSnapshot\";\nimport { isTaskExecDetails } from \"./task-exec-details\";\nimport { isTaskProcessDetails } from \"./task-process-details\";\nimport {\n bucketTasks,\n logLevelColor,\n taskSegments,\n taskStatusBg,\n taskStatusColor,\n taskStatusIcon,\n} from \"./task-status\";\n\n// TaskProgress renders one or more clicky task runs (groups) and their child\n// tasks: a segmented progress bar per group plus collapsible per-task rows with\n// status icon, duration, error, and expandable logs. Presentational only —\n// callers feed it snapshots from useTaskRun (SSE) or any other source.\n\nconst MAX_COMPLETED = 5;\nconst MAX_PENDING = 3;\n\nexport interface TaskProgressProps {\n snapshots: TaskSnapshot[];\n title?: string;\n /** Tighter spacing for embedding in a panel. */\n compact?: boolean;\n className?: string;\n onControl?: (action: TaskControlAction, group: TaskSnapshot) => void | Promise<void>;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n metricsBaseUrl?: string;\n}\n\nexport function TaskProgress({\n snapshots,\n title,\n compact,\n className,\n onControl,\n onTaskControl,\n metricsBaseUrl,\n}: TaskProgressProps) {\n const groups = snapshots.filter((s) => s.type === \"group\");\n const tasks = snapshots.filter((s) => s.type === \"task\");\n\n if (groups.length === 0) {\n return (\n <div className={cn(\"text-sm text-muted-foreground\", className)}>\n {title ? `${title}: ` : \"\"}No tasks yet.\n </div>\n );\n }\n\n return (\n <div className={cn(compact ? \"space-y-2\" : \"space-y-3\", className)}>\n {title && <h2 className=\"text-sm font-semibold\">{title}</h2>}\n {groups.map((g) => (\n <TaskGroupCard\n key={g.groupId || g.id}\n group={g}\n tasks={tasks.filter((t) => t.groupId === g.groupId || t.group === g.id)}\n compact={compact}\n {...(onControl ? { onControl } : {})}\n {...(onTaskControl ? { onTaskControl } : {})}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n ))}\n </div>\n );\n}\n\nfunction isFailedOrWarn(t: TaskSnapshot): boolean {\n return t.status === \"failed\" || t.status === \"FAIL\" || t.status === \"ERR\" || t.status === \"warning\";\n}\n\nfunction TaskGroupCard({\n group: g,\n tasks,\n compact,\n onControl,\n onTaskControl,\n metricsBaseUrl,\n}: {\n group: TaskSnapshot;\n tasks: TaskSnapshot[];\n compact: boolean | undefined;\n onControl?: (action: TaskControlAction, group: TaskSnapshot) => void | Promise<void>;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n metricsBaseUrl?: string;\n}) {\n const [showAll, setShowAll] = useState(false);\n const total = g.total ?? tasks.length;\n const counts = bucketTasks(tasks);\n const done = counts.ok + counts.warn + counts.fail;\n const progress = total > 0 ? `${done}/${total}` : \"\";\n\n const running = tasks.filter((t) => t.status === \"running\");\n const pending = tasks.filter((t) => t.status === \"pending\");\n const completed = tasks.filter((t) => t.status !== \"running\" && t.status !== \"pending\");\n const alwaysShow = completed.filter(isFailedOrWarn);\n const collapsible = completed.filter((t) => !isFailedOrWarn(t));\n\n const hiddenCompleted = collapsible.length - MAX_COMPLETED;\n const collapseCompleted = !showAll && hiddenCompleted > 0;\n const visibleSuccess = collapseCompleted ? collapsible.slice(-MAX_COMPLETED) : collapsible;\n\n const hiddenPending = pending.length - MAX_PENDING;\n const collapsePending = !showAll && hiddenPending > 0;\n const visiblePending = collapsePending ? pending.slice(0, MAX_PENDING) : pending;\n\n const isTerminal = g.status !== \"running\" && g.status !== \"pending\";\n\n return (\n <div className={cn(\"rounded-lg border bg-card\", compact ? \"p-3\" : \"p-4\")}>\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <h3 className=\"flex items-center gap-1.5 text-sm font-semibold\">\n <Icon\n icon={taskStatusIcon(g.status)}\n className={cn(taskStatusColor(g.status), g.status === \"running\" && \"animate-spin\")}\n />\n <span>{g.name}</span>\n {progress && <span className=\"text-xs text-muted-foreground\">{progress}</span>}\n {g.kind && (\n <span className=\"rounded-full bg-muted px-1.5 py-0 text-[10px] text-muted-foreground\">\n {g.kind}\n </span>\n )}\n </h3>\n <div className=\"flex shrink-0 items-center gap-1\">\n {isTerminal && (\n <span\n className={cn(\n \"rounded-full px-2 py-0.5 text-xs\",\n taskStatusColor(g.status),\n taskStatusBg(g.status),\n )}\n >\n {g.status}\n </span>\n )}\n {onControl && <TaskControls target={g} onControl={onControl} />}\n </div>\n </div>\n\n {total > 0 && (\n <div className=\"mb-3\">\n <ProgressBar segments={taskSegments(counts)} total={total} height=\"h-1.5\" />\n </div>\n )}\n\n {isTaskProcessDetails(g.details) && (\n <TaskProcessDetailsView\n details={g.details}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n )}\n\n {!isTaskProcessDetails(g.details) && isTaskExecDetails(g.details) && (\n <TaskExecDetailsView details={g.details} />\n )}\n\n {hiddenCompleted > 0 || hiddenPending > 0 ? (\n <button\n type=\"button\"\n className=\"border-b py-1.5 text-xs text-muted-foreground hover:text-foreground\"\n onClick={() => setShowAll((v) => !v)}\n >\n {showAll\n ? \"▲ collapse\"\n : `... ${(collapseCompleted ? hiddenCompleted : 0) + (collapsePending ? hiddenPending : 0)} more tasks`}\n </button>\n ) : null}\n\n {[...visibleSuccess, ...alwaysShow, ...running, ...visiblePending].map((t) => (\n <TaskRow\n key={t.id}\n task={t}\n group={g}\n {...(onTaskControl ? { onTaskControl } : {})}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n ))}\n </div>\n );\n}\n\nfunction TaskRow({\n task: t,\n group,\n onTaskControl,\n metricsBaseUrl,\n}: {\n task: TaskSnapshot;\n group: TaskSnapshot;\n metricsBaseUrl?: string;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n}) {\n const [expanded, setExpanded] = useState(false);\n const logs: LogEntry[] = t.logs ?? [];\n const hasLogs = logs.length > 0;\n const hasOutput = !!t.stdout || !!t.stderr;\n const execDetails = isTaskExecDetails(t.details) ? t.details : undefined;\n const processDetails = isTaskProcessDetails(t.details) ? t.details : undefined;\n const expandable = hasLogs || hasOutput || execDetails !== undefined || processDetails !== undefined;\n // Promote the latest warning message inline so a `warning` row shows its\n // reason without expanding. Suppressed when an error is already shown.\n const latestWarn = t.error ? undefined : logs.filter((l) => l.level === \"warn\").at(-1);\n // Bounded per-task progress (e.g. records emitted in a phase): render an x/y\n // count, a percentage, and a thin bar while the task runs.\n const done = t.progress ?? 0;\n // Only surface bounded progress once work has actually started — an untouched\n // task should not render a \"0/100 · 0%\" placeholder.\n const hasProgress = typeof t.maxValue === \"number\" && t.maxValue > 0 && done > 0;\n const pct = hasProgress ? Math.round((done / (t.maxValue as number)) * 100) : 0;\n\n return (\n <div\n className={cn(\n \"flex items-start gap-3 border-b py-2 last:border-0\",\n expandable && \"-mx-1 cursor-pointer rounded px-1 hover:bg-muted/50\",\n )}\n onClick={expandable ? () => setExpanded((v) => !v) : undefined}\n >\n <Icon\n icon={taskStatusIcon(t.status)}\n className={cn(taskStatusColor(t.status), \"mt-0.5 text-lg\", t.status === \"running\" && \"animate-spin\")}\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-1.5 text-sm font-medium\">\n <span className=\"truncate\">{t.name}</span>\n {t.error && <span className=\"truncate text-xs font-normal text-red-500\">{t.error}</span>}\n {latestWarn && (\n <span className={cn(\"truncate text-xs font-normal\", logLevelColor(\"warn\"))}>\n {latestWarn.message}\n </span>\n )}\n {expandable && (\n <span className=\"inline-flex shrink-0 items-center rounded-full bg-muted px-1.5 text-[10px] font-medium text-muted-foreground\">\n {logs.length + (t.stdout ? 1 : 0) + (t.stderr ? 1 : 0) + (execDetails || processDetails ? 1 : 0)}\n </span>\n )}\n </span>\n <div className=\"flex shrink-0 items-center gap-1\">\n {t.duration && <span className=\"text-xs text-muted-foreground\">{t.duration}</span>}\n {onTaskControl && (\n <TaskControls\n target={t}\n labelSuffix={t.name}\n stopPropagation\n onControl={(action) => onTaskControl(action, t, group)}\n />\n )}\n </div>\n </div>\n {(t.description || hasProgress) && (\n <div className=\"mt-0.5 flex items-center gap-2\">\n {t.description && (\n <span className=\"min-w-0 flex-1 truncate text-xs text-muted-foreground\">{t.description}</span>\n )}\n {hasProgress && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {done}/{t.maxValue} · {pct}%\n </span>\n )}\n </div>\n )}\n {hasProgress && t.status === \"running\" && (\n <div className=\"mt-1\">\n <ProgressBar\n segments={[{ count: done, color: \"bg-blue-500\", label: \"done\" }]}\n total={t.maxValue as number}\n height=\"h-1\"\n />\n </div>\n )}\n {expanded && execDetails && <TaskExecDetailsView details={execDetails} />}\n {expanded && processDetails && (\n <TaskProcessDetailsView\n details={processDetails}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n )}\n {expanded && hasLogs && (\n <div className=\"mt-1 ml-1 max-h-48 space-y-0.5 overflow-y-auto border-l-2 pl-2\">\n {logs.map((l, i) => (\n <div key={i} className={cn(\"text-xs\", logLevelColor(l.level))}>\n <span className=\"mr-1 font-mono text-muted-foreground\">{l.level.substring(0, 3)}</span>\n {l.message}\n </div>\n ))}\n </div>\n )}\n {expanded && hasOutput && (\n <div className=\"mt-2 space-y-2\">\n {t.stdout && <TaskStream label=\"stdout\" text={t.stdout} {...(t.stdoutTruncated ? { truncated: true } : {})} />}\n {t.stderr && <TaskStream label=\"stderr\" text={t.stderr} {...(t.stderrTruncated ? { truncated: true } : {})} error />}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction TaskStream({\n label,\n text,\n truncated,\n error,\n}: {\n label: string;\n text: string;\n truncated?: boolean;\n error?: boolean;\n}) {\n return (\n <div className=\"overflow-hidden rounded border bg-black\">\n <div className=\"flex items-center justify-between border-b border-white/10 px-2 py-1 text-[10px] text-gray-400\">\n <span>{label}</span>\n {truncated && <span>showing latest 1 MiB</span>}\n </div>\n <AnsiHtml\n text={text}\n className={cn(\"max-h-64 overflow-auto whitespace-pre-wrap p-2 text-xs text-gray-100\", error && \"text-red-300\")}\n />\n </div>\n );\n}\n\nfunction TaskControls({\n target,\n onControl,\n labelSuffix,\n stopPropagation,\n}: {\n target: TaskSnapshot;\n onControl: (action: TaskControlAction, target: TaskSnapshot) => void | Promise<void>;\n labelSuffix?: string;\n stopPropagation?: boolean;\n}) {\n const [busy, setBusy] = useState<TaskControlAction | null>(null);\n const [error, setError] = useState(\"\");\n const icons = { start: UiPlay, stop: UiStop, restart: UiRestart };\n const invoke = async (action: TaskControlAction) => {\n setBusy(action);\n setError(\"\");\n try {\n await onControl(action, target);\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : `Failed to ${action} task`);\n } finally {\n setBusy(null);\n }\n };\n return (\n <>\n {(target.controls ?? []).map((action) => {\n const ControlIcon = icons[action];\n const actionLabel = action[0]?.toUpperCase() + action.slice(1);\n const label = labelSuffix ? `${actionLabel} ${labelSuffix}` : actionLabel;\n return (\n <Button\n key={action}\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n title={label}\n disabled={busy !== null}\n onClick={(event) => {\n if (stopPropagation) event.stopPropagation();\n void invoke(action);\n }}\n >\n <ControlIcon />\n </Button>\n );\n })}\n {error && <span role=\"alert\" className=\"text-xs text-red-600\">{error}</span>}\n </>\n );\n}\n"],"names":["cn","jsxs","jsx","useState","bucketTasks","Icon","taskStatusIcon","taskStatusColor","taskStatusBg","ProgressBar","taskSegments","isTaskProcessDetails","TaskProcessDetailsView","isTaskExecDetails","TaskExecDetailsView","logLevelColor","AnsiHtml","UiPlay","UiStop","UiRestart","Fragment","Button"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,MAAM,gBAAgB;AACtB,MAAM,cAAc;AAiBb,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,SAAS,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO;AACzD,QAAM,QAAQ,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AAEvD,MAAI,OAAO,WAAW,GAAG;AACvB,2CACG,OAAA,EAAI,WAAWA,MAAAA,GAAG,iCAAiC,SAAS,GAC1D,UAAA;AAAA,MAAA,QAAQ,GAAG,KAAK,OAAO;AAAA,MAAG;AAAA,IAAA,GAC7B;AAAA,EAEJ;AAEA,SACEC,gCAAC,SAAI,WAAWD,MAAAA,GAAG,UAAU,cAAc,aAAa,SAAS,GAC9D,UAAA;AAAA,IAAA,SAASE,2BAAAA,IAAC,MAAA,EAAG,WAAU,yBAAyB,UAAA,OAAM;AAAA,IACtD,OAAO,IAAI,CAAC,MACXA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QAEC,OAAO;AAAA,QACP,OAAO,MAAM,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE;AAAA,QACtE;AAAA,QACC,GAAI,YAAY,EAAE,UAAA,IAAc,CAAA;AAAA,QAChC,GAAI,gBAAgB,EAAE,cAAA,IAAkB,CAAA;AAAA,QACxC,GAAI,iBAAiB,EAAE,mBAAmB,CAAA;AAAA,MAAC;AAAA,MANvC,EAAE,WAAW,EAAE;AAAA,IAAA,CAQvB;AAAA,EAAA,GACH;AAEJ;AAEA,SAAS,eAAe,GAA0B;AAChD,SAAO,EAAE,WAAW,YAAY,EAAE,WAAW,UAAU,EAAE,WAAW,SAAS,EAAE,WAAW;AAC5F;AAEA,SAAS,cAAc;AAAA,EACrB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAWG;AACD,QAAM,CAAC,SAAS,UAAU,IAAIC,MAAAA,SAAS,KAAK;AAC5C,QAAM,QAAQ,EAAE,SAAS,MAAM;AAC/B,QAAM,SAASC,WAAAA,YAAY,KAAK;AAChC,QAAM,OAAO,OAAO,KAAK,OAAO,OAAO,OAAO;AAC9C,QAAM,WAAW,QAAQ,IAAI,GAAG,IAAI,IAAI,KAAK,KAAK;AAElD,QAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS;AAC1D,QAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS;AAC1D,QAAM,YAAY,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,aAAa,EAAE,WAAW,SAAS;AACtF,QAAM,aAAa,UAAU,OAAO,cAAc;AAClD,QAAM,cAAc,UAAU,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;AAE9D,QAAM,kBAAkB,YAAY,SAAS;AAC7C,QAAM,oBAAoB,CAAC,WAAW,kBAAkB;AACxD,QAAM,iBAAiB,oBAAoB,YAAY,MAAM,CAAC,aAAa,IAAI;AAE/E,QAAM,gBAAgB,QAAQ,SAAS;AACvC,QAAM,kBAAkB,CAAC,WAAW,gBAAgB;AACpD,QAAM,iBAAiB,kBAAkB,QAAQ,MAAM,GAAG,WAAW,IAAI;AAEzE,QAAM,aAAa,EAAE,WAAW,aAAa,EAAE,WAAW;AAE1D,SACEH,gCAAC,SAAI,WAAWD,MAAAA,GAAG,6BAA6B,UAAU,QAAQ,KAAK,GACrE,UAAA;AAAA,IAAAC,2BAAAA,KAAC,OAAA,EAAI,WAAU,gDACb,UAAA;AAAA,MAAAA,2BAAAA,KAAC,MAAA,EAAG,WAAU,mDACZ,UAAA;AAAA,QAAAC,2BAAAA;AAAAA,UAACG,KAAAA;AAAAA,UAAA;AAAA,YACC,MAAMC,WAAAA,eAAe,EAAE,MAAM;AAAA,YAC7B,WAAWN,MAAAA,GAAGO,WAAAA,gBAAgB,EAAE,MAAM,GAAG,EAAE,WAAW,aAAa,cAAc;AAAA,UAAA;AAAA,QAAA;AAAA,QAEnFL,2BAAAA,IAAC,QAAA,EAAM,UAAA,EAAE,KAAA,CAAK;AAAA,QACb,YAAYA,2BAAAA,IAAC,QAAA,EAAK,WAAU,iCAAiC,UAAA,UAAS;AAAA,QACtE,EAAE,QACDA,2BAAAA,IAAC,UAAK,WAAU,uEACb,YAAE,KAAA,CACL;AAAA,MAAA,GAEJ;AAAA,MACAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oCACZ,UAAA;AAAA,QAAA,cACCC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWF,MAAAA;AAAAA,cACT;AAAA,cACAO,WAAAA,gBAAgB,EAAE,MAAM;AAAA,cACxBC,WAAAA,aAAa,EAAE,MAAM;AAAA,YAAA;AAAA,YAGtB,UAAA,EAAE;AAAA,UAAA;AAAA,QAAA;AAAA,QAGN,aAAaN,2BAAAA,IAAC,cAAA,EAAa,QAAQ,GAAG,UAAA,CAAsB;AAAA,MAAA,EAAA,CAC/D;AAAA,IAAA,GACF;AAAA,IAEC,QAAQ,KACPA,+BAAC,OAAA,EAAI,WAAU,QACb,UAAAA,2BAAAA,IAACO,YAAAA,aAAA,EAAY,UAAUC,WAAAA,aAAa,MAAM,GAAG,OAAc,QAAO,SAAQ,GAC5E;AAAA,IAGDC,wCAAqB,EAAE,OAAO,KAC7BT,2BAAAA;AAAAA,MAACU,mBAAAA;AAAAA,MAAA;AAAA,QACC,SAAS,EAAE;AAAA,QACV,GAAI,iBAAiB,EAAE,mBAAmB,CAAA;AAAA,MAAC;AAAA,IAAA;AAAA,IAI/C,CAACD,mBAAAA,qBAAqB,EAAE,OAAO,KAAKE,gBAAAA,kBAAkB,EAAE,OAAO,KAC9DX,2BAAAA,IAACY,gBAAAA,qBAAA,EAAoB,SAAS,EAAE,QAAA,CAAS;AAAA,IAG1C,kBAAkB,KAAK,gBAAgB,IACtCZ,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;AAAA,QAElC,UAAA,UACG,eACA,QAAQ,oBAAoB,kBAAkB,MAAM,kBAAkB,gBAAgB,EAAE;AAAA,MAAA;AAAA,IAAA,IAE5F;AAAA,IAEH,CAAC,GAAG,gBAAgB,GAAG,YAAY,GAAG,SAAS,GAAG,cAAc,EAAE,IAAI,CAAC,MACtEA,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAM;AAAA,QACN,OAAO;AAAA,QACN,GAAI,gBAAgB,EAAE,cAAA,IAAkB,CAAA;AAAA,QACxC,GAAI,iBAAiB,EAAE,mBAAmB,CAAA;AAAA,MAAC;AAAA,MAJvC,EAAE;AAAA,IAAA,CAMV;AAAA,EAAA,GACH;AAEJ;AAEA,SAAS,QAAQ;AAAA,EACf,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AACF,GASG;AACD,QAAM,CAAC,UAAU,WAAW,IAAIC,MAAAA,SAAS,KAAK;AAC9C,QAAM,OAAmB,EAAE,QAAQ,CAAA;AACnC,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,YAAY,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE;AACpC,QAAM,cAAcU,gBAAAA,kBAAkB,EAAE,OAAO,IAAI,EAAE,UAAU;AAC/D,QAAM,iBAAiBF,mBAAAA,qBAAqB,EAAE,OAAO,IAAI,EAAE,UAAU;AACrE,QAAM,aAAa,WAAW,aAAa,gBAAgB,UAAa,mBAAmB;AAG3F,QAAM,aAAa,EAAE,QAAQ,SAAY,KAAK,OAAO,CAAC,MAAM,EAAE,UAAU,MAAM,EAAE,GAAG,EAAE;AAGrF,QAAM,OAAO,EAAE,YAAY;AAG3B,QAAM,cAAc,OAAO,EAAE,aAAa,YAAY,EAAE,WAAW,KAAK,OAAO;AAC/E,QAAM,MAAM,cAAc,KAAK,MAAO,OAAQ,EAAE,WAAuB,GAAG,IAAI;AAE9E,SACEV,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWD,MAAAA;AAAAA,QACT;AAAA,QACA,cAAc;AAAA,MAAA;AAAA,MAEhB,SAAS,aAAa,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI;AAAA,MAErD,UAAA;AAAA,QAAAE,2BAAAA;AAAAA,UAACG,KAAAA;AAAAA,UAAA;AAAA,YACC,MAAMC,WAAAA,eAAe,EAAE,MAAM;AAAA,YAC7B,WAAWN,MAAAA,GAAGO,WAAAA,gBAAgB,EAAE,MAAM,GAAG,kBAAkB,EAAE,WAAW,aAAa,cAAc;AAAA,UAAA;AAAA,QAAA;AAAA,QAErGN,2BAAAA,KAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,UAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,YAAAA,2BAAAA,KAAC,QAAA,EAAK,WAAU,yDACd,UAAA;AAAA,cAAAC,2BAAAA,IAAC,QAAA,EAAK,WAAU,YAAY,UAAA,EAAE,MAAK;AAAA,cAClC,EAAE,SAASA,2BAAAA,IAAC,UAAK,WAAU,6CAA6C,YAAE,OAAM;AAAA,cAChF,cACCA,2BAAAA,IAAC,QAAA,EAAK,WAAWF,MAAAA,GAAG,gCAAgCe,WAAAA,cAAc,MAAM,CAAC,GACtE,UAAA,WAAW,QAAA,CACd;AAAA,cAED,cACCb,2BAAAA,IAAC,QAAA,EAAK,WAAU,gHACb,UAAA,KAAK,UAAU,EAAE,SAAS,IAAI,MAAM,EAAE,SAAS,IAAI,MAAM,eAAe,iBAAiB,IAAI,GAAA,CAChG;AAAA,YAAA,GAEJ;AAAA,YACAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,oCACZ,UAAA;AAAA,cAAA,EAAE,YAAYC,2BAAAA,IAAC,QAAA,EAAK,WAAU,iCAAiC,YAAE,UAAS;AAAA,cAC1E,iBACCA,2BAAAA;AAAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,QAAQ;AAAA,kBACR,aAAa,EAAE;AAAA,kBACf,iBAAe;AAAA,kBACf,WAAW,CAAC,WAAW,cAAc,QAAQ,GAAG,KAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,YACvD,EAAA,CAEJ;AAAA,UAAA,GACF;AAAA,WACE,EAAE,eAAe,gBACjBD,2BAAAA,KAAC,OAAA,EAAI,WAAU,kCACZ,UAAA;AAAA,YAAA,EAAE,eACDC,2BAAAA,IAAC,QAAA,EAAK,WAAU,yDAAyD,YAAE,aAAY;AAAA,YAExF,eACCD,2BAAAA,KAAC,QAAA,EAAK,WAAU,uDACb,UAAA;AAAA,cAAA;AAAA,cAAK;AAAA,cAAE,EAAE;AAAA,cAAS;AAAA,cAAI;AAAA,cAAI;AAAA,YAAA,EAAA,CAC7B;AAAA,UAAA,GAEJ;AAAA,UAED,eAAe,EAAE,WAAW,aAC3BC,2BAAAA,IAAC,OAAA,EAAI,WAAU,QACb,UAAAA,2BAAAA;AAAAA,YAACO,YAAAA;AAAAA,YAAA;AAAA,cACC,UAAU,CAAC,EAAE,OAAO,MAAM,OAAO,eAAe,OAAO,QAAQ;AAAA,cAC/D,OAAO,EAAE;AAAA,cACT,QAAO;AAAA,YAAA;AAAA,UAAA,GAEX;AAAA,UAED,YAAY,eAAeP,2BAAAA,IAACY,gBAAAA,qBAAA,EAAoB,SAAS,aAAa;AAAA,UACtE,YAAY,kBACXZ,2BAAAA;AAAAA,YAACU,mBAAAA;AAAAA,YAAA;AAAA,cACC,SAAS;AAAA,cACR,GAAI,iBAAiB,EAAE,mBAAmB,CAAA;AAAA,YAAC;AAAA,UAAA;AAAA,UAG/C,YAAY,WACXV,+BAAC,OAAA,EAAI,WAAU,kEACZ,UAAA,KAAK,IAAI,CAAC,GAAG,MACZD,2BAAAA,KAAC,OAAA,EAAY,WAAWD,SAAG,WAAWe,WAAAA,cAAc,EAAE,KAAK,CAAC,GAC1D,UAAA;AAAA,YAAAb,2BAAAA,IAAC,QAAA,EAAK,WAAU,wCAAwC,UAAA,EAAE,MAAM,UAAU,GAAG,CAAC,EAAA,CAAE;AAAA,YAC/E,EAAE;AAAA,UAAA,KAFK,CAGV,CACD,GACH;AAAA,UAED,YAAY,aACXD,gCAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,YAAA,EAAE,UAAUC,+BAAC,YAAA,EAAW,OAAM,UAAS,MAAM,EAAE,QAAS,GAAI,EAAE,kBAAkB,EAAE,WAAW,KAAA,IAAS,CAAA,GAAK;AAAA,YAC3G,EAAE,UAAUA,+BAAC,cAAW,OAAM,UAAS,MAAM,EAAE,QAAS,GAAI,EAAE,kBAAkB,EAAE,WAAW,KAAA,IAAS,CAAA,GAAK,OAAK,KAAA,CAAC;AAAA,UAAA,EAAA,CACpH;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,SACED,2BAAAA,KAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,IAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,kGACb,UAAA;AAAA,MAAAC,2BAAAA,IAAC,UAAM,UAAA,MAAA,CAAM;AAAA,MACZ,aAAaA,2BAAAA,IAAC,QAAA,EAAK,UAAA,uBAAA,CAAoB;AAAA,IAAA,GAC1C;AAAA,IACAA,2BAAAA;AAAAA,MAACc,SAAAA;AAAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAWhB,MAAAA,GAAG,wEAAwE,SAAS,cAAc;AAAA,MAAA;AAAA,IAAA;AAAA,EAC/G,GACF;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,CAAC,MAAM,OAAO,IAAIG,MAAAA,SAAmC,IAAI;AAC/D,QAAM,CAAC,OAAO,QAAQ,IAAIA,MAAAA,SAAS,EAAE;AACrC,QAAM,QAAQ,EAAE,OAAOc,OAAAA,QAAQ,MAAMC,OAAAA,QAAQ,SAASC,oBAAA;AACtD,QAAM,SAAS,OAAO,WAA8B;AAClD,YAAQ,MAAM;AACd,aAAS,EAAE;AACX,QAAI;AACF,YAAM,UAAU,QAAQ,MAAM;AAAA,IAChC,SAAS,OAAO;AACd,eAAS,iBAAiB,QAAQ,MAAM,UAAU,aAAa,MAAM,OAAO;AAAA,IAC9E,UAAA;AACE,cAAQ,IAAI;AAAA,IACd;AAAA,EACF;AACA,SACElB,2BAAAA,KAAAmB,qBAAA,EACI,UAAA;AAAA,KAAA,OAAO,YAAY,CAAA,GAAI,IAAI,CAAC,WAAW;;AACvC,YAAM,cAAc,MAAM,MAAM;AAChC,YAAM,gBAAc,YAAO,CAAC,MAAR,mBAAW,iBAAgB,OAAO,MAAM,CAAC;AAC7D,YAAM,QAAQ,cAAc,GAAG,WAAW,IAAI,WAAW,KAAK;AAC9D,aACElB,2BAAAA;AAAAA,QAACmB,OAAAA;AAAAA,QAAA;AAAA,UAEC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,cAAY;AAAA,UACZ,OAAO;AAAA,UACP,UAAU,SAAS;AAAA,UACnB,SAAS,CAAC,UAAU;AAClB,gBAAI,uBAAuB,gBAAA;AAC3B,iBAAK,OAAO,MAAM;AAAA,UACpB;AAAA,UAEA,yCAAC,aAAA,CAAA,CAAY;AAAA,QAAA;AAAA,QAZR;AAAA,MAAA;AAAA,IAeX,CAAC;AAAA,IACA,SAASnB,2BAAAA,IAAC,QAAA,EAAK,MAAK,SAAQ,WAAU,wBAAwB,UAAA,MAAA,CAAM;AAAA,EAAA,GACvE;AAEJ;;"}
@@ -128,7 +128,8 @@ function TaskGroupCard({
128
128
  {
129
129
  task: t,
130
130
  group: g,
131
- ...onTaskControl ? { onTaskControl } : {}
131
+ ...onTaskControl ? { onTaskControl } : {},
132
+ ...metricsBaseUrl ? { metricsBaseUrl } : {}
132
133
  },
133
134
  t.id
134
135
  ))
@@ -137,14 +138,16 @@ function TaskGroupCard({
137
138
  function TaskRow({
138
139
  task: t,
139
140
  group,
140
- onTaskControl
141
+ onTaskControl,
142
+ metricsBaseUrl
141
143
  }) {
142
144
  const [expanded, setExpanded] = useState(false);
143
145
  const logs = t.logs ?? [];
144
146
  const hasLogs = logs.length > 0;
145
147
  const hasOutput = !!t.stdout || !!t.stderr;
146
148
  const execDetails = isTaskExecDetails(t.details) ? t.details : void 0;
147
- const expandable = hasLogs || hasOutput || execDetails !== void 0;
149
+ const processDetails = isTaskProcessDetails(t.details) ? t.details : void 0;
150
+ const expandable = hasLogs || hasOutput || execDetails !== void 0 || processDetails !== void 0;
148
151
  const latestWarn = t.error ? void 0 : logs.filter((l) => l.level === "warn").at(-1);
149
152
  const done = t.progress ?? 0;
150
153
  const hasProgress = typeof t.maxValue === "number" && t.maxValue > 0 && done > 0;
@@ -171,7 +174,7 @@ function TaskRow({
171
174
  /* @__PURE__ */ jsx("span", { className: "truncate", children: t.name }),
172
175
  t.error && /* @__PURE__ */ jsx("span", { className: "truncate text-xs font-normal text-red-500", children: t.error }),
173
176
  latestWarn && /* @__PURE__ */ jsx("span", { className: cn("truncate text-xs font-normal", logLevelColor("warn")), children: latestWarn.message }),
174
- expandable && /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0 items-center rounded-full bg-muted px-1.5 text-[10px] font-medium text-muted-foreground", children: logs.length + (t.stdout ? 1 : 0) + (t.stderr ? 1 : 0) + (execDetails ? 1 : 0) })
177
+ expandable && /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0 items-center rounded-full bg-muted px-1.5 text-[10px] font-medium text-muted-foreground", children: logs.length + (t.stdout ? 1 : 0) + (t.stderr ? 1 : 0) + (execDetails || processDetails ? 1 : 0) })
175
178
  ] }),
176
179
  /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
177
180
  t.duration && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t.duration }),
@@ -206,6 +209,13 @@ function TaskRow({
206
209
  }
207
210
  ) }),
208
211
  expanded && execDetails && /* @__PURE__ */ jsx(TaskExecDetailsView, { details: execDetails }),
212
+ expanded && processDetails && /* @__PURE__ */ jsx(
213
+ TaskProcessDetailsView,
214
+ {
215
+ details: processDetails,
216
+ ...metricsBaseUrl ? { metricsBaseUrl } : {}
217
+ }
218
+ ),
209
219
  expanded && hasLogs && /* @__PURE__ */ jsx("div", { className: "mt-1 ml-1 max-h-48 space-y-0.5 overflow-y-auto border-l-2 pl-2", children: logs.map((l, i) => /* @__PURE__ */ jsxs("div", { className: cn("text-xs", logLevelColor(l.level)), children: [
210
220
  /* @__PURE__ */ jsx("span", { className: "mr-1 font-mono text-muted-foreground", children: l.level.substring(0, 3) }),
211
221
  l.message
@@ -1 +1 @@
1
- {"version":3,"file":"TaskProgress.js","sources":["../../src/data/TaskProgress.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { Button } from \"../components/button\";\nimport { UiPlay, UiRestart, UiStop } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { AnsiHtml } from \"./AnsiHtml\";\nimport { Icon } from \"./Icon\";\nimport { ProgressBar } from \"./ProgressBar\";\nimport { TaskProcessDetailsView } from \"./TaskProcessDetails\";\nimport { TaskExecDetailsView } from \"./TaskExecDetails\";\nimport type { LogEntry, TaskControlAction, TaskSnapshot } from \"./TaskSnapshot\";\nimport { isTaskExecDetails } from \"./task-exec-details\";\nimport { isTaskProcessDetails } from \"./task-process-details\";\nimport {\n bucketTasks,\n logLevelColor,\n taskSegments,\n taskStatusBg,\n taskStatusColor,\n taskStatusIcon,\n} from \"./task-status\";\n\n// TaskProgress renders one or more clicky task runs (groups) and their child\n// tasks: a segmented progress bar per group plus collapsible per-task rows with\n// status icon, duration, error, and expandable logs. Presentational only —\n// callers feed it snapshots from useTaskRun (SSE) or any other source.\n\nconst MAX_COMPLETED = 5;\nconst MAX_PENDING = 3;\n\nexport interface TaskProgressProps {\n snapshots: TaskSnapshot[];\n title?: string;\n /** Tighter spacing for embedding in a panel. */\n compact?: boolean;\n className?: string;\n onControl?: (action: TaskControlAction, group: TaskSnapshot) => void | Promise<void>;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n metricsBaseUrl?: string;\n}\n\nexport function TaskProgress({\n snapshots,\n title,\n compact,\n className,\n onControl,\n onTaskControl,\n metricsBaseUrl,\n}: TaskProgressProps) {\n const groups = snapshots.filter((s) => s.type === \"group\");\n const tasks = snapshots.filter((s) => s.type === \"task\");\n\n if (groups.length === 0) {\n return (\n <div className={cn(\"text-sm text-muted-foreground\", className)}>\n {title ? `${title}: ` : \"\"}No tasks yet.\n </div>\n );\n }\n\n return (\n <div className={cn(compact ? \"space-y-2\" : \"space-y-3\", className)}>\n {title && <h2 className=\"text-sm font-semibold\">{title}</h2>}\n {groups.map((g) => (\n <TaskGroupCard\n key={g.groupId || g.id}\n group={g}\n tasks={tasks.filter((t) => t.groupId === g.groupId || t.group === g.id)}\n compact={compact}\n {...(onControl ? { onControl } : {})}\n {...(onTaskControl ? { onTaskControl } : {})}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n ))}\n </div>\n );\n}\n\nfunction isFailedOrWarn(t: TaskSnapshot): boolean {\n return t.status === \"failed\" || t.status === \"FAIL\" || t.status === \"ERR\" || t.status === \"warning\";\n}\n\nfunction TaskGroupCard({\n group: g,\n tasks,\n compact,\n onControl,\n onTaskControl,\n metricsBaseUrl,\n}: {\n group: TaskSnapshot;\n tasks: TaskSnapshot[];\n compact: boolean | undefined;\n onControl?: (action: TaskControlAction, group: TaskSnapshot) => void | Promise<void>;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n metricsBaseUrl?: string;\n}) {\n const [showAll, setShowAll] = useState(false);\n const total = g.total ?? tasks.length;\n const counts = bucketTasks(tasks);\n const done = counts.ok + counts.warn + counts.fail;\n const progress = total > 0 ? `${done}/${total}` : \"\";\n\n const running = tasks.filter((t) => t.status === \"running\");\n const pending = tasks.filter((t) => t.status === \"pending\");\n const completed = tasks.filter((t) => t.status !== \"running\" && t.status !== \"pending\");\n const alwaysShow = completed.filter(isFailedOrWarn);\n const collapsible = completed.filter((t) => !isFailedOrWarn(t));\n\n const hiddenCompleted = collapsible.length - MAX_COMPLETED;\n const collapseCompleted = !showAll && hiddenCompleted > 0;\n const visibleSuccess = collapseCompleted ? collapsible.slice(-MAX_COMPLETED) : collapsible;\n\n const hiddenPending = pending.length - MAX_PENDING;\n const collapsePending = !showAll && hiddenPending > 0;\n const visiblePending = collapsePending ? pending.slice(0, MAX_PENDING) : pending;\n\n const isTerminal = g.status !== \"running\" && g.status !== \"pending\";\n\n return (\n <div className={cn(\"rounded-lg border bg-card\", compact ? \"p-3\" : \"p-4\")}>\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <h3 className=\"flex items-center gap-1.5 text-sm font-semibold\">\n <Icon\n icon={taskStatusIcon(g.status)}\n className={cn(taskStatusColor(g.status), g.status === \"running\" && \"animate-spin\")}\n />\n <span>{g.name}</span>\n {progress && <span className=\"text-xs text-muted-foreground\">{progress}</span>}\n {g.kind && (\n <span className=\"rounded-full bg-muted px-1.5 py-0 text-[10px] text-muted-foreground\">\n {g.kind}\n </span>\n )}\n </h3>\n <div className=\"flex shrink-0 items-center gap-1\">\n {isTerminal && (\n <span\n className={cn(\n \"rounded-full px-2 py-0.5 text-xs\",\n taskStatusColor(g.status),\n taskStatusBg(g.status),\n )}\n >\n {g.status}\n </span>\n )}\n {onControl && <TaskControls target={g} onControl={onControl} />}\n </div>\n </div>\n\n {total > 0 && (\n <div className=\"mb-3\">\n <ProgressBar segments={taskSegments(counts)} total={total} height=\"h-1.5\" />\n </div>\n )}\n\n {isTaskProcessDetails(g.details) && (\n <TaskProcessDetailsView\n details={g.details}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n )}\n\n {!isTaskProcessDetails(g.details) && isTaskExecDetails(g.details) && (\n <TaskExecDetailsView details={g.details} />\n )}\n\n {hiddenCompleted > 0 || hiddenPending > 0 ? (\n <button\n type=\"button\"\n className=\"border-b py-1.5 text-xs text-muted-foreground hover:text-foreground\"\n onClick={() => setShowAll((v) => !v)}\n >\n {showAll\n ? \"▲ collapse\"\n : `... ${(collapseCompleted ? hiddenCompleted : 0) + (collapsePending ? hiddenPending : 0)} more tasks`}\n </button>\n ) : null}\n\n {[...visibleSuccess, ...alwaysShow, ...running, ...visiblePending].map((t) => (\n <TaskRow\n key={t.id}\n task={t}\n group={g}\n {...(onTaskControl ? { onTaskControl } : {})}\n />\n ))}\n </div>\n );\n}\n\nfunction TaskRow({\n task: t,\n group,\n onTaskControl,\n}: {\n task: TaskSnapshot;\n group: TaskSnapshot;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n}) {\n const [expanded, setExpanded] = useState(false);\n const logs: LogEntry[] = t.logs ?? [];\n const hasLogs = logs.length > 0;\n const hasOutput = !!t.stdout || !!t.stderr;\n const execDetails = isTaskExecDetails(t.details) ? t.details : undefined;\n const expandable = hasLogs || hasOutput || execDetails !== undefined;\n // Promote the latest warning message inline so a `warning` row shows its\n // reason without expanding. Suppressed when an error is already shown.\n const latestWarn = t.error ? undefined : logs.filter((l) => l.level === \"warn\").at(-1);\n // Bounded per-task progress (e.g. records emitted in a phase): render an x/y\n // count, a percentage, and a thin bar while the task runs.\n const done = t.progress ?? 0;\n // Only surface bounded progress once work has actually started — an untouched\n // task should not render a \"0/100 · 0%\" placeholder.\n const hasProgress = typeof t.maxValue === \"number\" && t.maxValue > 0 && done > 0;\n const pct = hasProgress ? Math.round((done / (t.maxValue as number)) * 100) : 0;\n\n return (\n <div\n className={cn(\n \"flex items-start gap-3 border-b py-2 last:border-0\",\n expandable && \"-mx-1 cursor-pointer rounded px-1 hover:bg-muted/50\",\n )}\n onClick={expandable ? () => setExpanded((v) => !v) : undefined}\n >\n <Icon\n icon={taskStatusIcon(t.status)}\n className={cn(taskStatusColor(t.status), \"mt-0.5 text-lg\", t.status === \"running\" && \"animate-spin\")}\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-1.5 text-sm font-medium\">\n <span className=\"truncate\">{t.name}</span>\n {t.error && <span className=\"truncate text-xs font-normal text-red-500\">{t.error}</span>}\n {latestWarn && (\n <span className={cn(\"truncate text-xs font-normal\", logLevelColor(\"warn\"))}>\n {latestWarn.message}\n </span>\n )}\n {expandable && (\n <span className=\"inline-flex shrink-0 items-center rounded-full bg-muted px-1.5 text-[10px] font-medium text-muted-foreground\">\n {logs.length + (t.stdout ? 1 : 0) + (t.stderr ? 1 : 0) + (execDetails ? 1 : 0)}\n </span>\n )}\n </span>\n <div className=\"flex shrink-0 items-center gap-1\">\n {t.duration && <span className=\"text-xs text-muted-foreground\">{t.duration}</span>}\n {onTaskControl && (\n <TaskControls\n target={t}\n labelSuffix={t.name}\n stopPropagation\n onControl={(action) => onTaskControl(action, t, group)}\n />\n )}\n </div>\n </div>\n {(t.description || hasProgress) && (\n <div className=\"mt-0.5 flex items-center gap-2\">\n {t.description && (\n <span className=\"min-w-0 flex-1 truncate text-xs text-muted-foreground\">{t.description}</span>\n )}\n {hasProgress && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {done}/{t.maxValue} · {pct}%\n </span>\n )}\n </div>\n )}\n {hasProgress && t.status === \"running\" && (\n <div className=\"mt-1\">\n <ProgressBar\n segments={[{ count: done, color: \"bg-blue-500\", label: \"done\" }]}\n total={t.maxValue as number}\n height=\"h-1\"\n />\n </div>\n )}\n {expanded && execDetails && <TaskExecDetailsView details={execDetails} />}\n {expanded && hasLogs && (\n <div className=\"mt-1 ml-1 max-h-48 space-y-0.5 overflow-y-auto border-l-2 pl-2\">\n {logs.map((l, i) => (\n <div key={i} className={cn(\"text-xs\", logLevelColor(l.level))}>\n <span className=\"mr-1 font-mono text-muted-foreground\">{l.level.substring(0, 3)}</span>\n {l.message}\n </div>\n ))}\n </div>\n )}\n {expanded && hasOutput && (\n <div className=\"mt-2 space-y-2\">\n {t.stdout && <TaskStream label=\"stdout\" text={t.stdout} {...(t.stdoutTruncated ? { truncated: true } : {})} />}\n {t.stderr && <TaskStream label=\"stderr\" text={t.stderr} {...(t.stderrTruncated ? { truncated: true } : {})} error />}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction TaskStream({\n label,\n text,\n truncated,\n error,\n}: {\n label: string;\n text: string;\n truncated?: boolean;\n error?: boolean;\n}) {\n return (\n <div className=\"overflow-hidden rounded border bg-black\">\n <div className=\"flex items-center justify-between border-b border-white/10 px-2 py-1 text-[10px] text-gray-400\">\n <span>{label}</span>\n {truncated && <span>showing latest 1 MiB</span>}\n </div>\n <AnsiHtml\n text={text}\n className={cn(\"max-h-64 overflow-auto whitespace-pre-wrap p-2 text-xs text-gray-100\", error && \"text-red-300\")}\n />\n </div>\n );\n}\n\nfunction TaskControls({\n target,\n onControl,\n labelSuffix,\n stopPropagation,\n}: {\n target: TaskSnapshot;\n onControl: (action: TaskControlAction, target: TaskSnapshot) => void | Promise<void>;\n labelSuffix?: string;\n stopPropagation?: boolean;\n}) {\n const [busy, setBusy] = useState<TaskControlAction | null>(null);\n const [error, setError] = useState(\"\");\n const icons = { start: UiPlay, stop: UiStop, restart: UiRestart };\n const invoke = async (action: TaskControlAction) => {\n setBusy(action);\n setError(\"\");\n try {\n await onControl(action, target);\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : `Failed to ${action} task`);\n } finally {\n setBusy(null);\n }\n };\n return (\n <>\n {(target.controls ?? []).map((action) => {\n const ControlIcon = icons[action];\n const actionLabel = action[0]?.toUpperCase() + action.slice(1);\n const label = labelSuffix ? `${actionLabel} ${labelSuffix}` : actionLabel;\n return (\n <Button\n key={action}\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n title={label}\n disabled={busy !== null}\n onClick={(event) => {\n if (stopPropagation) event.stopPropagation();\n void invoke(action);\n }}\n >\n <ControlIcon />\n </Button>\n );\n })}\n {error && <span role=\"alert\" className=\"text-xs text-red-600\">{error}</span>}\n </>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TaskProgress.js","sources":["../../src/data/TaskProgress.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { Button } from \"../components/button\";\nimport { UiPlay, UiRestart, UiStop } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { AnsiHtml } from \"./AnsiHtml\";\nimport { Icon } from \"./Icon\";\nimport { ProgressBar } from \"./ProgressBar\";\nimport { TaskProcessDetailsView } from \"./TaskProcessDetails\";\nimport { TaskExecDetailsView } from \"./TaskExecDetails\";\nimport type { LogEntry, TaskControlAction, TaskSnapshot } from \"./TaskSnapshot\";\nimport { isTaskExecDetails } from \"./task-exec-details\";\nimport { isTaskProcessDetails } from \"./task-process-details\";\nimport {\n bucketTasks,\n logLevelColor,\n taskSegments,\n taskStatusBg,\n taskStatusColor,\n taskStatusIcon,\n} from \"./task-status\";\n\n// TaskProgress renders one or more clicky task runs (groups) and their child\n// tasks: a segmented progress bar per group plus collapsible per-task rows with\n// status icon, duration, error, and expandable logs. Presentational only —\n// callers feed it snapshots from useTaskRun (SSE) or any other source.\n\nconst MAX_COMPLETED = 5;\nconst MAX_PENDING = 3;\n\nexport interface TaskProgressProps {\n snapshots: TaskSnapshot[];\n title?: string;\n /** Tighter spacing for embedding in a panel. */\n compact?: boolean;\n className?: string;\n onControl?: (action: TaskControlAction, group: TaskSnapshot) => void | Promise<void>;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n metricsBaseUrl?: string;\n}\n\nexport function TaskProgress({\n snapshots,\n title,\n compact,\n className,\n onControl,\n onTaskControl,\n metricsBaseUrl,\n}: TaskProgressProps) {\n const groups = snapshots.filter((s) => s.type === \"group\");\n const tasks = snapshots.filter((s) => s.type === \"task\");\n\n if (groups.length === 0) {\n return (\n <div className={cn(\"text-sm text-muted-foreground\", className)}>\n {title ? `${title}: ` : \"\"}No tasks yet.\n </div>\n );\n }\n\n return (\n <div className={cn(compact ? \"space-y-2\" : \"space-y-3\", className)}>\n {title && <h2 className=\"text-sm font-semibold\">{title}</h2>}\n {groups.map((g) => (\n <TaskGroupCard\n key={g.groupId || g.id}\n group={g}\n tasks={tasks.filter((t) => t.groupId === g.groupId || t.group === g.id)}\n compact={compact}\n {...(onControl ? { onControl } : {})}\n {...(onTaskControl ? { onTaskControl } : {})}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n ))}\n </div>\n );\n}\n\nfunction isFailedOrWarn(t: TaskSnapshot): boolean {\n return t.status === \"failed\" || t.status === \"FAIL\" || t.status === \"ERR\" || t.status === \"warning\";\n}\n\nfunction TaskGroupCard({\n group: g,\n tasks,\n compact,\n onControl,\n onTaskControl,\n metricsBaseUrl,\n}: {\n group: TaskSnapshot;\n tasks: TaskSnapshot[];\n compact: boolean | undefined;\n onControl?: (action: TaskControlAction, group: TaskSnapshot) => void | Promise<void>;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n metricsBaseUrl?: string;\n}) {\n const [showAll, setShowAll] = useState(false);\n const total = g.total ?? tasks.length;\n const counts = bucketTasks(tasks);\n const done = counts.ok + counts.warn + counts.fail;\n const progress = total > 0 ? `${done}/${total}` : \"\";\n\n const running = tasks.filter((t) => t.status === \"running\");\n const pending = tasks.filter((t) => t.status === \"pending\");\n const completed = tasks.filter((t) => t.status !== \"running\" && t.status !== \"pending\");\n const alwaysShow = completed.filter(isFailedOrWarn);\n const collapsible = completed.filter((t) => !isFailedOrWarn(t));\n\n const hiddenCompleted = collapsible.length - MAX_COMPLETED;\n const collapseCompleted = !showAll && hiddenCompleted > 0;\n const visibleSuccess = collapseCompleted ? collapsible.slice(-MAX_COMPLETED) : collapsible;\n\n const hiddenPending = pending.length - MAX_PENDING;\n const collapsePending = !showAll && hiddenPending > 0;\n const visiblePending = collapsePending ? pending.slice(0, MAX_PENDING) : pending;\n\n const isTerminal = g.status !== \"running\" && g.status !== \"pending\";\n\n return (\n <div className={cn(\"rounded-lg border bg-card\", compact ? \"p-3\" : \"p-4\")}>\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <h3 className=\"flex items-center gap-1.5 text-sm font-semibold\">\n <Icon\n icon={taskStatusIcon(g.status)}\n className={cn(taskStatusColor(g.status), g.status === \"running\" && \"animate-spin\")}\n />\n <span>{g.name}</span>\n {progress && <span className=\"text-xs text-muted-foreground\">{progress}</span>}\n {g.kind && (\n <span className=\"rounded-full bg-muted px-1.5 py-0 text-[10px] text-muted-foreground\">\n {g.kind}\n </span>\n )}\n </h3>\n <div className=\"flex shrink-0 items-center gap-1\">\n {isTerminal && (\n <span\n className={cn(\n \"rounded-full px-2 py-0.5 text-xs\",\n taskStatusColor(g.status),\n taskStatusBg(g.status),\n )}\n >\n {g.status}\n </span>\n )}\n {onControl && <TaskControls target={g} onControl={onControl} />}\n </div>\n </div>\n\n {total > 0 && (\n <div className=\"mb-3\">\n <ProgressBar segments={taskSegments(counts)} total={total} height=\"h-1.5\" />\n </div>\n )}\n\n {isTaskProcessDetails(g.details) && (\n <TaskProcessDetailsView\n details={g.details}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n )}\n\n {!isTaskProcessDetails(g.details) && isTaskExecDetails(g.details) && (\n <TaskExecDetailsView details={g.details} />\n )}\n\n {hiddenCompleted > 0 || hiddenPending > 0 ? (\n <button\n type=\"button\"\n className=\"border-b py-1.5 text-xs text-muted-foreground hover:text-foreground\"\n onClick={() => setShowAll((v) => !v)}\n >\n {showAll\n ? \"▲ collapse\"\n : `... ${(collapseCompleted ? hiddenCompleted : 0) + (collapsePending ? hiddenPending : 0)} more tasks`}\n </button>\n ) : null}\n\n {[...visibleSuccess, ...alwaysShow, ...running, ...visiblePending].map((t) => (\n <TaskRow\n key={t.id}\n task={t}\n group={g}\n {...(onTaskControl ? { onTaskControl } : {})}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n ))}\n </div>\n );\n}\n\nfunction TaskRow({\n task: t,\n group,\n onTaskControl,\n metricsBaseUrl,\n}: {\n task: TaskSnapshot;\n group: TaskSnapshot;\n metricsBaseUrl?: string;\n onTaskControl?: (\n action: TaskControlAction,\n task: TaskSnapshot,\n group: TaskSnapshot,\n ) => void | Promise<void>;\n}) {\n const [expanded, setExpanded] = useState(false);\n const logs: LogEntry[] = t.logs ?? [];\n const hasLogs = logs.length > 0;\n const hasOutput = !!t.stdout || !!t.stderr;\n const execDetails = isTaskExecDetails(t.details) ? t.details : undefined;\n const processDetails = isTaskProcessDetails(t.details) ? t.details : undefined;\n const expandable = hasLogs || hasOutput || execDetails !== undefined || processDetails !== undefined;\n // Promote the latest warning message inline so a `warning` row shows its\n // reason without expanding. Suppressed when an error is already shown.\n const latestWarn = t.error ? undefined : logs.filter((l) => l.level === \"warn\").at(-1);\n // Bounded per-task progress (e.g. records emitted in a phase): render an x/y\n // count, a percentage, and a thin bar while the task runs.\n const done = t.progress ?? 0;\n // Only surface bounded progress once work has actually started — an untouched\n // task should not render a \"0/100 · 0%\" placeholder.\n const hasProgress = typeof t.maxValue === \"number\" && t.maxValue > 0 && done > 0;\n const pct = hasProgress ? Math.round((done / (t.maxValue as number)) * 100) : 0;\n\n return (\n <div\n className={cn(\n \"flex items-start gap-3 border-b py-2 last:border-0\",\n expandable && \"-mx-1 cursor-pointer rounded px-1 hover:bg-muted/50\",\n )}\n onClick={expandable ? () => setExpanded((v) => !v) : undefined}\n >\n <Icon\n icon={taskStatusIcon(t.status)}\n className={cn(taskStatusColor(t.status), \"mt-0.5 text-lg\", t.status === \"running\" && \"animate-spin\")}\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"flex min-w-0 items-center gap-1.5 text-sm font-medium\">\n <span className=\"truncate\">{t.name}</span>\n {t.error && <span className=\"truncate text-xs font-normal text-red-500\">{t.error}</span>}\n {latestWarn && (\n <span className={cn(\"truncate text-xs font-normal\", logLevelColor(\"warn\"))}>\n {latestWarn.message}\n </span>\n )}\n {expandable && (\n <span className=\"inline-flex shrink-0 items-center rounded-full bg-muted px-1.5 text-[10px] font-medium text-muted-foreground\">\n {logs.length + (t.stdout ? 1 : 0) + (t.stderr ? 1 : 0) + (execDetails || processDetails ? 1 : 0)}\n </span>\n )}\n </span>\n <div className=\"flex shrink-0 items-center gap-1\">\n {t.duration && <span className=\"text-xs text-muted-foreground\">{t.duration}</span>}\n {onTaskControl && (\n <TaskControls\n target={t}\n labelSuffix={t.name}\n stopPropagation\n onControl={(action) => onTaskControl(action, t, group)}\n />\n )}\n </div>\n </div>\n {(t.description || hasProgress) && (\n <div className=\"mt-0.5 flex items-center gap-2\">\n {t.description && (\n <span className=\"min-w-0 flex-1 truncate text-xs text-muted-foreground\">{t.description}</span>\n )}\n {hasProgress && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {done}/{t.maxValue} · {pct}%\n </span>\n )}\n </div>\n )}\n {hasProgress && t.status === \"running\" && (\n <div className=\"mt-1\">\n <ProgressBar\n segments={[{ count: done, color: \"bg-blue-500\", label: \"done\" }]}\n total={t.maxValue as number}\n height=\"h-1\"\n />\n </div>\n )}\n {expanded && execDetails && <TaskExecDetailsView details={execDetails} />}\n {expanded && processDetails && (\n <TaskProcessDetailsView\n details={processDetails}\n {...(metricsBaseUrl ? { metricsBaseUrl } : {})}\n />\n )}\n {expanded && hasLogs && (\n <div className=\"mt-1 ml-1 max-h-48 space-y-0.5 overflow-y-auto border-l-2 pl-2\">\n {logs.map((l, i) => (\n <div key={i} className={cn(\"text-xs\", logLevelColor(l.level))}>\n <span className=\"mr-1 font-mono text-muted-foreground\">{l.level.substring(0, 3)}</span>\n {l.message}\n </div>\n ))}\n </div>\n )}\n {expanded && hasOutput && (\n <div className=\"mt-2 space-y-2\">\n {t.stdout && <TaskStream label=\"stdout\" text={t.stdout} {...(t.stdoutTruncated ? { truncated: true } : {})} />}\n {t.stderr && <TaskStream label=\"stderr\" text={t.stderr} {...(t.stderrTruncated ? { truncated: true } : {})} error />}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction TaskStream({\n label,\n text,\n truncated,\n error,\n}: {\n label: string;\n text: string;\n truncated?: boolean;\n error?: boolean;\n}) {\n return (\n <div className=\"overflow-hidden rounded border bg-black\">\n <div className=\"flex items-center justify-between border-b border-white/10 px-2 py-1 text-[10px] text-gray-400\">\n <span>{label}</span>\n {truncated && <span>showing latest 1 MiB</span>}\n </div>\n <AnsiHtml\n text={text}\n className={cn(\"max-h-64 overflow-auto whitespace-pre-wrap p-2 text-xs text-gray-100\", error && \"text-red-300\")}\n />\n </div>\n );\n}\n\nfunction TaskControls({\n target,\n onControl,\n labelSuffix,\n stopPropagation,\n}: {\n target: TaskSnapshot;\n onControl: (action: TaskControlAction, target: TaskSnapshot) => void | Promise<void>;\n labelSuffix?: string;\n stopPropagation?: boolean;\n}) {\n const [busy, setBusy] = useState<TaskControlAction | null>(null);\n const [error, setError] = useState(\"\");\n const icons = { start: UiPlay, stop: UiStop, restart: UiRestart };\n const invoke = async (action: TaskControlAction) => {\n setBusy(action);\n setError(\"\");\n try {\n await onControl(action, target);\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : `Failed to ${action} task`);\n } finally {\n setBusy(null);\n }\n };\n return (\n <>\n {(target.controls ?? []).map((action) => {\n const ControlIcon = icons[action];\n const actionLabel = action[0]?.toUpperCase() + action.slice(1);\n const label = labelSuffix ? `${actionLabel} ${labelSuffix}` : actionLabel;\n return (\n <Button\n key={action}\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n title={label}\n disabled={busy !== null}\n onClick={(event) => {\n if (stopPropagation) event.stopPropagation();\n void invoke(action);\n }}\n >\n <ControlIcon />\n </Button>\n );\n })}\n {error && <span role=\"alert\" className=\"text-xs text-red-600\">{error}</span>}\n </>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA0BA,MAAM,gBAAgB;AACtB,MAAM,cAAc;AAiBb,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,SAAS,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO;AACzD,QAAM,QAAQ,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,MAAM;AAEvD,MAAI,OAAO,WAAW,GAAG;AACvB,gCACG,OAAA,EAAI,WAAW,GAAG,iCAAiC,SAAS,GAC1D,UAAA;AAAA,MAAA,QAAQ,GAAG,KAAK,OAAO;AAAA,MAAG;AAAA,IAAA,GAC7B;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAW,GAAG,UAAU,cAAc,aAAa,SAAS,GAC9D,UAAA;AAAA,IAAA,SAAS,oBAAC,MAAA,EAAG,WAAU,yBAAyB,UAAA,OAAM;AAAA,IACtD,OAAO,IAAI,CAAC,MACX;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,OAAO;AAAA,QACP,OAAO,MAAM,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE;AAAA,QACtE;AAAA,QACC,GAAI,YAAY,EAAE,UAAA,IAAc,CAAA;AAAA,QAChC,GAAI,gBAAgB,EAAE,cAAA,IAAkB,CAAA;AAAA,QACxC,GAAI,iBAAiB,EAAE,mBAAmB,CAAA;AAAA,MAAC;AAAA,MANvC,EAAE,WAAW,EAAE;AAAA,IAAA,CAQvB;AAAA,EAAA,GACH;AAEJ;AAEA,SAAS,eAAe,GAA0B;AAChD,SAAO,EAAE,WAAW,YAAY,EAAE,WAAW,UAAU,EAAE,WAAW,SAAS,EAAE,WAAW;AAC5F;AAEA,SAAS,cAAc;AAAA,EACrB,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAWG;AACD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,QAAQ,EAAE,SAAS,MAAM;AAC/B,QAAM,SAAS,YAAY,KAAK;AAChC,QAAM,OAAO,OAAO,KAAK,OAAO,OAAO,OAAO;AAC9C,QAAM,WAAW,QAAQ,IAAI,GAAG,IAAI,IAAI,KAAK,KAAK;AAElD,QAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS;AAC1D,QAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS;AAC1D,QAAM,YAAY,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,aAAa,EAAE,WAAW,SAAS;AACtF,QAAM,aAAa,UAAU,OAAO,cAAc;AAClD,QAAM,cAAc,UAAU,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;AAE9D,QAAM,kBAAkB,YAAY,SAAS;AAC7C,QAAM,oBAAoB,CAAC,WAAW,kBAAkB;AACxD,QAAM,iBAAiB,oBAAoB,YAAY,MAAM,CAAC,aAAa,IAAI;AAE/E,QAAM,gBAAgB,QAAQ,SAAS;AACvC,QAAM,kBAAkB,CAAC,WAAW,gBAAgB;AACpD,QAAM,iBAAiB,kBAAkB,QAAQ,MAAM,GAAG,WAAW,IAAI;AAEzE,QAAM,aAAa,EAAE,WAAW,aAAa,EAAE,WAAW;AAE1D,SACE,qBAAC,SAAI,WAAW,GAAG,6BAA6B,UAAU,QAAQ,KAAK,GACrE,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,gDACb,UAAA;AAAA,MAAA,qBAAC,MAAA,EAAG,WAAU,mDACZ,UAAA;AAAA,QAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAM,eAAe,EAAE,MAAM;AAAA,YAC7B,WAAW,GAAG,gBAAgB,EAAE,MAAM,GAAG,EAAE,WAAW,aAAa,cAAc;AAAA,UAAA;AAAA,QAAA;AAAA,QAEnF,oBAAC,QAAA,EAAM,UAAA,EAAE,KAAA,CAAK;AAAA,QACb,YAAY,oBAAC,QAAA,EAAK,WAAU,iCAAiC,UAAA,UAAS;AAAA,QACtE,EAAE,QACD,oBAAC,UAAK,WAAU,uEACb,YAAE,KAAA,CACL;AAAA,MAAA,GAEJ;AAAA,MACA,qBAAC,OAAA,EAAI,WAAU,oCACZ,UAAA;AAAA,QAAA,cACC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA,gBAAgB,EAAE,MAAM;AAAA,cACxB,aAAa,EAAE,MAAM;AAAA,YAAA;AAAA,YAGtB,UAAA,EAAE;AAAA,UAAA;AAAA,QAAA;AAAA,QAGN,aAAa,oBAAC,cAAA,EAAa,QAAQ,GAAG,UAAA,CAAsB;AAAA,MAAA,EAAA,CAC/D;AAAA,IAAA,GACF;AAAA,IAEC,QAAQ,KACP,oBAAC,OAAA,EAAI,WAAU,QACb,UAAA,oBAAC,aAAA,EAAY,UAAU,aAAa,MAAM,GAAG,OAAc,QAAO,SAAQ,GAC5E;AAAA,IAGD,qBAAqB,EAAE,OAAO,KAC7B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAAS,EAAE;AAAA,QACV,GAAI,iBAAiB,EAAE,mBAAmB,CAAA;AAAA,MAAC;AAAA,IAAA;AAAA,IAI/C,CAAC,qBAAqB,EAAE,OAAO,KAAK,kBAAkB,EAAE,OAAO,KAC9D,oBAAC,qBAAA,EAAoB,SAAS,EAAE,QAAA,CAAS;AAAA,IAG1C,kBAAkB,KAAK,gBAAgB,IACtC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;AAAA,QAElC,UAAA,UACG,eACA,QAAQ,oBAAoB,kBAAkB,MAAM,kBAAkB,gBAAgB,EAAE;AAAA,MAAA;AAAA,IAAA,IAE5F;AAAA,IAEH,CAAC,GAAG,gBAAgB,GAAG,YAAY,GAAG,SAAS,GAAG,cAAc,EAAE,IAAI,CAAC,MACtE;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAM;AAAA,QACN,OAAO;AAAA,QACN,GAAI,gBAAgB,EAAE,cAAA,IAAkB,CAAA;AAAA,QACxC,GAAI,iBAAiB,EAAE,mBAAmB,CAAA;AAAA,MAAC;AAAA,MAJvC,EAAE;AAAA,IAAA,CAMV;AAAA,EAAA,GACH;AAEJ;AAEA,SAAS,QAAQ;AAAA,EACf,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AACF,GASG;AACD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,OAAmB,EAAE,QAAQ,CAAA;AACnC,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,YAAY,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE;AACpC,QAAM,cAAc,kBAAkB,EAAE,OAAO,IAAI,EAAE,UAAU;AAC/D,QAAM,iBAAiB,qBAAqB,EAAE,OAAO,IAAI,EAAE,UAAU;AACrE,QAAM,aAAa,WAAW,aAAa,gBAAgB,UAAa,mBAAmB;AAG3F,QAAM,aAAa,EAAE,QAAQ,SAAY,KAAK,OAAO,CAAC,MAAM,EAAE,UAAU,MAAM,EAAE,GAAG,EAAE;AAGrF,QAAM,OAAO,EAAE,YAAY;AAG3B,QAAM,cAAc,OAAO,EAAE,aAAa,YAAY,EAAE,WAAW,KAAK,OAAO;AAC/E,QAAM,MAAM,cAAc,KAAK,MAAO,OAAQ,EAAE,WAAuB,GAAG,IAAI;AAE9E,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,cAAc;AAAA,MAAA;AAAA,MAEhB,SAAS,aAAa,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI;AAAA,MAErD,UAAA;AAAA,QAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAM,eAAe,EAAE,MAAM;AAAA,YAC7B,WAAW,GAAG,gBAAgB,EAAE,MAAM,GAAG,kBAAkB,EAAE,WAAW,aAAa,cAAc;AAAA,UAAA;AAAA,QAAA;AAAA,QAErG,qBAAC,OAAA,EAAI,WAAU,kBACb,UAAA;AAAA,UAAA,qBAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,YAAA,qBAAC,QAAA,EAAK,WAAU,yDACd,UAAA;AAAA,cAAA,oBAAC,QAAA,EAAK,WAAU,YAAY,UAAA,EAAE,MAAK;AAAA,cAClC,EAAE,SAAS,oBAAC,UAAK,WAAU,6CAA6C,YAAE,OAAM;AAAA,cAChF,cACC,oBAAC,QAAA,EAAK,WAAW,GAAG,gCAAgC,cAAc,MAAM,CAAC,GACtE,UAAA,WAAW,QAAA,CACd;AAAA,cAED,cACC,oBAAC,QAAA,EAAK,WAAU,gHACb,UAAA,KAAK,UAAU,EAAE,SAAS,IAAI,MAAM,EAAE,SAAS,IAAI,MAAM,eAAe,iBAAiB,IAAI,GAAA,CAChG;AAAA,YAAA,GAEJ;AAAA,YACA,qBAAC,OAAA,EAAI,WAAU,oCACZ,UAAA;AAAA,cAAA,EAAE,YAAY,oBAAC,QAAA,EAAK,WAAU,iCAAiC,YAAE,UAAS;AAAA,cAC1E,iBACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,QAAQ;AAAA,kBACR,aAAa,EAAE;AAAA,kBACf,iBAAe;AAAA,kBACf,WAAW,CAAC,WAAW,cAAc,QAAQ,GAAG,KAAK;AAAA,gBAAA;AAAA,cAAA;AAAA,YACvD,EAAA,CAEJ;AAAA,UAAA,GACF;AAAA,WACE,EAAE,eAAe,gBACjB,qBAAC,OAAA,EAAI,WAAU,kCACZ,UAAA;AAAA,YAAA,EAAE,eACD,oBAAC,QAAA,EAAK,WAAU,yDAAyD,YAAE,aAAY;AAAA,YAExF,eACC,qBAAC,QAAA,EAAK,WAAU,uDACb,UAAA;AAAA,cAAA;AAAA,cAAK;AAAA,cAAE,EAAE;AAAA,cAAS;AAAA,cAAI;AAAA,cAAI;AAAA,YAAA,EAAA,CAC7B;AAAA,UAAA,GAEJ;AAAA,UAED,eAAe,EAAE,WAAW,aAC3B,oBAAC,OAAA,EAAI,WAAU,QACb,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,UAAU,CAAC,EAAE,OAAO,MAAM,OAAO,eAAe,OAAO,QAAQ;AAAA,cAC/D,OAAO,EAAE;AAAA,cACT,QAAO;AAAA,YAAA;AAAA,UAAA,GAEX;AAAA,UAED,YAAY,eAAe,oBAAC,qBAAA,EAAoB,SAAS,aAAa;AAAA,UACtE,YAAY,kBACX;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS;AAAA,cACR,GAAI,iBAAiB,EAAE,mBAAmB,CAAA;AAAA,YAAC;AAAA,UAAA;AAAA,UAG/C,YAAY,WACX,oBAAC,OAAA,EAAI,WAAU,kEACZ,UAAA,KAAK,IAAI,CAAC,GAAG,MACZ,qBAAC,OAAA,EAAY,WAAW,GAAG,WAAW,cAAc,EAAE,KAAK,CAAC,GAC1D,UAAA;AAAA,YAAA,oBAAC,QAAA,EAAK,WAAU,wCAAwC,UAAA,EAAE,MAAM,UAAU,GAAG,CAAC,EAAA,CAAE;AAAA,YAC/E,EAAE;AAAA,UAAA,KAFK,CAGV,CACD,GACH;AAAA,UAED,YAAY,aACX,qBAAC,OAAA,EAAI,WAAU,kBACZ,UAAA;AAAA,YAAA,EAAE,UAAU,oBAAC,YAAA,EAAW,OAAM,UAAS,MAAM,EAAE,QAAS,GAAI,EAAE,kBAAkB,EAAE,WAAW,KAAA,IAAS,CAAA,GAAK;AAAA,YAC3G,EAAE,UAAU,oBAAC,cAAW,OAAM,UAAS,MAAM,EAAE,QAAS,GAAI,EAAE,kBAAkB,EAAE,WAAW,KAAA,IAAS,CAAA,GAAK,OAAK,KAAA,CAAC;AAAA,UAAA,EAAA,CACpH;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,SACE,qBAAC,OAAA,EAAI,WAAU,2CACb,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,kGACb,UAAA;AAAA,MAAA,oBAAC,UAAM,UAAA,MAAA,CAAM;AAAA,MACZ,aAAa,oBAAC,QAAA,EAAK,UAAA,uBAAA,CAAoB;AAAA,IAAA,GAC1C;AAAA,IACA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,wEAAwE,SAAS,cAAc;AAAA,MAAA;AAAA,IAAA;AAAA,EAC/G,GACF;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAmC,IAAI;AAC/D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,EAAE;AACrC,QAAM,QAAQ,EAAE,OAAO,QAAQ,MAAM,QAAQ,SAAS,UAAA;AACtD,QAAM,SAAS,OAAO,WAA8B;AAClD,YAAQ,MAAM;AACd,aAAS,EAAE;AACX,QAAI;AACF,YAAM,UAAU,QAAQ,MAAM;AAAA,IAChC,SAAS,OAAO;AACd,eAAS,iBAAiB,QAAQ,MAAM,UAAU,aAAa,MAAM,OAAO;AAAA,IAC9E,UAAA;AACE,cAAQ,IAAI;AAAA,IACd;AAAA,EACF;AACA,SACE,qBAAA,UAAA,EACI,UAAA;AAAA,KAAA,OAAO,YAAY,CAAA,GAAI,IAAI,CAAC,WAAW;;AACvC,YAAM,cAAc,MAAM,MAAM;AAChC,YAAM,gBAAc,YAAO,CAAC,MAAR,mBAAW,iBAAgB,OAAO,MAAM,CAAC;AAC7D,YAAM,QAAQ,cAAc,GAAG,WAAW,IAAI,WAAW,KAAK;AAC9D,aACE;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,MAAK;AAAA,UACL,cAAY;AAAA,UACZ,OAAO;AAAA,UACP,UAAU,SAAS;AAAA,UACnB,SAAS,CAAC,UAAU;AAClB,gBAAI,uBAAuB,gBAAA;AAC3B,iBAAK,OAAO,MAAM;AAAA,UACpB;AAAA,UAEA,8BAAC,aAAA,CAAA,CAAY;AAAA,QAAA;AAAA,QAZR;AAAA,MAAA;AAAA,IAeX,CAAC;AAAA,IACA,SAAS,oBAAC,QAAA,EAAK,MAAK,SAAQ,WAAU,wBAAwB,UAAA,MAAA,CAAM;AAAA,EAAA,GACvE;AAEJ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"TaskSnapshot.cjs","sources":["../../src/data/TaskSnapshot.ts"],"sourcesContent":["// TaskSnapshot mirrors the Go `task.TaskSnapshot` wire format emitted by clicky's\n// JSONHandler / SSEHandler (github.com/flanksource/clicky/task/snapshot.go). Field\n// names match the JSON tags exactly. This module is generic — it carries no\n// application-specific concepts.\n\nexport interface LogEntry {\n level: string;\n message: string;\n}\n\nexport type TaskControlAction = \"start\" | \"stop\" | \"restart\";\n\nexport interface TaskResourceSnapshot {\n cpuPercent: number;\n rssBytes: number;\n vmsBytes: number;\n openFiles: number;\n sampledAt: string;\n}\n\nexport interface TaskProcessSample {\n pid: number;\n ppid: number;\n command: string;\n status?: string;\n isRoot?: boolean;\n cpuPercent: number;\n rssBytes: number;\n vmsBytes: number;\n openFiles: number;\n}\n\nexport interface TaskProcessDetails {\n pid?: number;\n command: string;\n status: string;\n started?: string;\n exitCode?: number;\n ports?: number[];\n restarts: number;\n restartPolicy: string;\n maxRestarts?: number;\n latest: TaskResourceSnapshot;\n peak: TaskResourceSnapshot;\n metrics: Record<string, string>;\n tree?: TaskProcessSample[];\n}\n\nexport interface TaskExecDetails {\n command: string;\n args?: string[];\n pid?: number;\n status: string;\n exitCode: number;\n started?: string;\n /** Go time.Duration encoded as nanoseconds. */\n duration?: number;\n [key: string]: unknown;\n}\n\nexport interface TaskSnapshot {\n id: string;\n name: string;\n /** \"task\" or \"group\". */\n type: \"task\" | \"group\";\n /** Parent group NAME (groups: empty). */\n group?: string;\n status: string;\n duration?: string;\n error?: string;\n /** Latest log line. */\n message?: string;\n logs?: LogEntry[];\n /** Group aggregates. */\n total?: number;\n completed?: number;\n failed?: number;\n running?: number;\n /** Per-task (type === \"task\") live stage label and bounded progress. */\n description?: string;\n progress?: number;\n /** Progress denominator; 0/undefined means the task has no bounded progress. */\n maxValue?: number;\n /** Stable parent-run id (tasks) or the run's own id (groups). */\n groupId?: string;\n kind?: string;\n labels?: Record<string, string>;\n owner?: string;\n /** RFC3339. */\n startedAt?: string;\n /** RFC3339. */\n finishedAt?: string;\n href?: string;\n controls?: TaskControlAction[];\n stdout?: string;\n stderr?: string;\n stdoutTruncated?: boolean;\n stderrTruncated?: boolean;\n details?: TaskProcessDetails | TaskExecDetails | Record<string, unknown>;\n}\n\n// TaskRunMeta mirrors the Go `task.RunMeta` listing summary returned by\n// GET {prefix}/tasks. Named TaskRunMeta to avoid colliding with the unrelated\n// diagnostics `RunMeta` already exported by this package.\nexport interface TaskRunMeta {\n id: string;\n name: string;\n kind?: string;\n labels?: Record<string, string>;\n owner?: string;\n status: string;\n startedAt?: string;\n finishedAt?: string;\n total: number;\n completed: number;\n failed: number;\n running: number;\n href?: string;\n controls?: TaskControlAction[];\n}\n\n// Terminal run/group statuses (not running/pending). Used to decide when an SSE\n// stream is done or when polling should stop.\nconst TERMINAL_STATUSES = new Set([\n \"success\",\n \"failed\",\n \"warning\",\n \"canceled\",\n \"PASS\",\n \"FAIL\",\n \"ERR\",\n \"SKIP\",\n]);\n\nexport function isTerminalStatus(status: string | undefined): boolean {\n return !!status && TERMINAL_STATUSES.has(status);\n}\n\n// allGroupsTerminal reports whether every group snapshot has reached a terminal\n// status — i.e. the run(s) are complete and an SSE stream / poll can stop.\nexport function allGroupsTerminal(snapshots: TaskSnapshot[]): boolean {\n const groups = snapshots.filter((s) => s.type === \"group\");\n if (groups.length === 0) return false;\n return groups.every((g) => isTerminalStatus(g.status));\n}\n"],"names":[],"mappings":";;AA2HA,MAAM,wCAAwB,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,iBAAiB,QAAqC;AACpE,SAAO,CAAC,CAAC,UAAU,kBAAkB,IAAI,MAAM;AACjD;AAIO,SAAS,kBAAkB,WAAoC;AACpE,QAAM,SAAS,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO;AACzD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,OAAO,MAAM,CAAC,MAAM,iBAAiB,EAAE,MAAM,CAAC;AACvD;;;"}
1
+ {"version":3,"file":"TaskSnapshot.cjs","sources":["../../src/data/TaskSnapshot.ts"],"sourcesContent":["// TaskSnapshot mirrors the Go `task.TaskSnapshot` wire format emitted by clicky's\n// JSONHandler / SSEHandler (github.com/flanksource/clicky/task/snapshot.go). Field\n// names match the JSON tags exactly. This module is generic — it carries no\n// application-specific concepts.\n\nexport interface LogEntry {\n level: string;\n message: string;\n}\n\nexport type TaskControlAction = \"start\" | \"stop\" | \"restart\";\n\nexport interface TaskResourceSnapshot {\n cpuPercent: number;\n rssBytes: number;\n vmsBytes: number;\n openFiles: number;\n sampledAt: string;\n}\n\nexport interface TaskProcessSample {\n pid: number;\n ppid: number;\n command: string;\n status?: string;\n isRoot?: boolean;\n cpuPercent: number;\n rssBytes: number;\n vmsBytes: number;\n openFiles: number;\n}\n\nexport interface TaskProcessDetails {\n pid?: number;\n command: string;\n args?: string[];\n status: string;\n started?: string;\n exitCode?: number;\n ports?: number[];\n restarts: number;\n restartPolicy: string;\n maxRestarts?: number;\n latest: TaskResourceSnapshot;\n peak: TaskResourceSnapshot;\n metrics: Record<string, string>;\n tree?: TaskProcessSample[];\n}\n\nexport interface TaskExecDetails {\n command: string;\n args?: string[];\n pid?: number;\n status: string;\n exitCode: number;\n started?: string;\n /** Go time.Duration encoded as nanoseconds. */\n duration?: number;\n [key: string]: unknown;\n}\n\nexport interface TaskSnapshot {\n id: string;\n name: string;\n /** \"task\" or \"group\". */\n type: \"task\" | \"group\";\n /** Parent group NAME (groups: empty). */\n group?: string;\n status: string;\n duration?: string;\n error?: string;\n /** Latest log line. */\n message?: string;\n logs?: LogEntry[];\n /** Group aggregates. */\n total?: number;\n completed?: number;\n failed?: number;\n running?: number;\n /** Per-task (type === \"task\") live stage label and bounded progress. */\n description?: string;\n progress?: number;\n /** Progress denominator; 0/undefined means the task has no bounded progress. */\n maxValue?: number;\n /** Stable parent-run id (tasks) or the run's own id (groups). */\n groupId?: string;\n kind?: string;\n labels?: Record<string, string>;\n owner?: string;\n /** RFC3339. */\n startedAt?: string;\n /** RFC3339. */\n finishedAt?: string;\n href?: string;\n controls?: TaskControlAction[];\n stdout?: string;\n stderr?: string;\n stdoutTruncated?: boolean;\n stderrTruncated?: boolean;\n details?: TaskProcessDetails | TaskExecDetails | Record<string, unknown>;\n}\n\n// TaskRunMeta mirrors the Go `task.RunMeta` listing summary returned by\n// GET {prefix}/tasks. Named TaskRunMeta to avoid colliding with the unrelated\n// diagnostics `RunMeta` already exported by this package.\nexport interface TaskRunMeta {\n id: string;\n name: string;\n kind?: string;\n labels?: Record<string, string>;\n owner?: string;\n status: string;\n startedAt?: string;\n finishedAt?: string;\n total: number;\n completed: number;\n failed: number;\n running: number;\n href?: string;\n controls?: TaskControlAction[];\n}\n\n// Terminal run/group statuses (not running/pending). Used to decide when an SSE\n// stream is done or when polling should stop.\nconst TERMINAL_STATUSES = new Set([\n \"success\",\n \"failed\",\n \"warning\",\n \"canceled\",\n \"PASS\",\n \"FAIL\",\n \"ERR\",\n \"SKIP\",\n]);\n\nexport function isTerminalStatus(status: string | undefined): boolean {\n return !!status && TERMINAL_STATUSES.has(status);\n}\n\n// allGroupsTerminal reports whether every group snapshot has reached a terminal\n// status — i.e. the run(s) are complete and an SSE stream / poll can stop.\nexport function allGroupsTerminal(snapshots: TaskSnapshot[]): boolean {\n const groups = snapshots.filter((s) => s.type === \"group\");\n if (groups.length === 0) return false;\n return groups.every((g) => isTerminalStatus(g.status));\n}\n"],"names":[],"mappings":";;AA4HA,MAAM,wCAAwB,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,iBAAiB,QAAqC;AACpE,SAAO,CAAC,CAAC,UAAU,kBAAkB,IAAI,MAAM;AACjD;AAIO,SAAS,kBAAkB,WAAoC;AACpE,QAAM,SAAS,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO;AACzD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,OAAO,MAAM,CAAC,MAAM,iBAAiB,EAAE,MAAM,CAAC;AACvD;;;"}
@@ -24,6 +24,7 @@ export interface TaskProcessSample {
24
24
  export interface TaskProcessDetails {
25
25
  pid?: number;
26
26
  command: string;
27
+ args?: string[];
27
28
  status: string;
28
29
  started?: string;
29
30
  exitCode?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"TaskSnapshot.d.ts","sourceRoot":"","sources":["../../src/data/TaskSnapshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TaskSnapshot.d.ts","sourceRoot":"","sources":["../../src/data/TaskSnapshot.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TaskSnapshot.js","sources":["../../src/data/TaskSnapshot.ts"],"sourcesContent":["// TaskSnapshot mirrors the Go `task.TaskSnapshot` wire format emitted by clicky's\n// JSONHandler / SSEHandler (github.com/flanksource/clicky/task/snapshot.go). Field\n// names match the JSON tags exactly. This module is generic — it carries no\n// application-specific concepts.\n\nexport interface LogEntry {\n level: string;\n message: string;\n}\n\nexport type TaskControlAction = \"start\" | \"stop\" | \"restart\";\n\nexport interface TaskResourceSnapshot {\n cpuPercent: number;\n rssBytes: number;\n vmsBytes: number;\n openFiles: number;\n sampledAt: string;\n}\n\nexport interface TaskProcessSample {\n pid: number;\n ppid: number;\n command: string;\n status?: string;\n isRoot?: boolean;\n cpuPercent: number;\n rssBytes: number;\n vmsBytes: number;\n openFiles: number;\n}\n\nexport interface TaskProcessDetails {\n pid?: number;\n command: string;\n status: string;\n started?: string;\n exitCode?: number;\n ports?: number[];\n restarts: number;\n restartPolicy: string;\n maxRestarts?: number;\n latest: TaskResourceSnapshot;\n peak: TaskResourceSnapshot;\n metrics: Record<string, string>;\n tree?: TaskProcessSample[];\n}\n\nexport interface TaskExecDetails {\n command: string;\n args?: string[];\n pid?: number;\n status: string;\n exitCode: number;\n started?: string;\n /** Go time.Duration encoded as nanoseconds. */\n duration?: number;\n [key: string]: unknown;\n}\n\nexport interface TaskSnapshot {\n id: string;\n name: string;\n /** \"task\" or \"group\". */\n type: \"task\" | \"group\";\n /** Parent group NAME (groups: empty). */\n group?: string;\n status: string;\n duration?: string;\n error?: string;\n /** Latest log line. */\n message?: string;\n logs?: LogEntry[];\n /** Group aggregates. */\n total?: number;\n completed?: number;\n failed?: number;\n running?: number;\n /** Per-task (type === \"task\") live stage label and bounded progress. */\n description?: string;\n progress?: number;\n /** Progress denominator; 0/undefined means the task has no bounded progress. */\n maxValue?: number;\n /** Stable parent-run id (tasks) or the run's own id (groups). */\n groupId?: string;\n kind?: string;\n labels?: Record<string, string>;\n owner?: string;\n /** RFC3339. */\n startedAt?: string;\n /** RFC3339. */\n finishedAt?: string;\n href?: string;\n controls?: TaskControlAction[];\n stdout?: string;\n stderr?: string;\n stdoutTruncated?: boolean;\n stderrTruncated?: boolean;\n details?: TaskProcessDetails | TaskExecDetails | Record<string, unknown>;\n}\n\n// TaskRunMeta mirrors the Go `task.RunMeta` listing summary returned by\n// GET {prefix}/tasks. Named TaskRunMeta to avoid colliding with the unrelated\n// diagnostics `RunMeta` already exported by this package.\nexport interface TaskRunMeta {\n id: string;\n name: string;\n kind?: string;\n labels?: Record<string, string>;\n owner?: string;\n status: string;\n startedAt?: string;\n finishedAt?: string;\n total: number;\n completed: number;\n failed: number;\n running: number;\n href?: string;\n controls?: TaskControlAction[];\n}\n\n// Terminal run/group statuses (not running/pending). Used to decide when an SSE\n// stream is done or when polling should stop.\nconst TERMINAL_STATUSES = new Set([\n \"success\",\n \"failed\",\n \"warning\",\n \"canceled\",\n \"PASS\",\n \"FAIL\",\n \"ERR\",\n \"SKIP\",\n]);\n\nexport function isTerminalStatus(status: string | undefined): boolean {\n return !!status && TERMINAL_STATUSES.has(status);\n}\n\n// allGroupsTerminal reports whether every group snapshot has reached a terminal\n// status — i.e. the run(s) are complete and an SSE stream / poll can stop.\nexport function allGroupsTerminal(snapshots: TaskSnapshot[]): boolean {\n const groups = snapshots.filter((s) => s.type === \"group\");\n if (groups.length === 0) return false;\n return groups.every((g) => isTerminalStatus(g.status));\n}\n"],"names":[],"mappings":"AA2HA,MAAM,wCAAwB,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,iBAAiB,QAAqC;AACpE,SAAO,CAAC,CAAC,UAAU,kBAAkB,IAAI,MAAM;AACjD;AAIO,SAAS,kBAAkB,WAAoC;AACpE,QAAM,SAAS,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO;AACzD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,OAAO,MAAM,CAAC,MAAM,iBAAiB,EAAE,MAAM,CAAC;AACvD;"}
1
+ {"version":3,"file":"TaskSnapshot.js","sources":["../../src/data/TaskSnapshot.ts"],"sourcesContent":["// TaskSnapshot mirrors the Go `task.TaskSnapshot` wire format emitted by clicky's\n// JSONHandler / SSEHandler (github.com/flanksource/clicky/task/snapshot.go). Field\n// names match the JSON tags exactly. This module is generic — it carries no\n// application-specific concepts.\n\nexport interface LogEntry {\n level: string;\n message: string;\n}\n\nexport type TaskControlAction = \"start\" | \"stop\" | \"restart\";\n\nexport interface TaskResourceSnapshot {\n cpuPercent: number;\n rssBytes: number;\n vmsBytes: number;\n openFiles: number;\n sampledAt: string;\n}\n\nexport interface TaskProcessSample {\n pid: number;\n ppid: number;\n command: string;\n status?: string;\n isRoot?: boolean;\n cpuPercent: number;\n rssBytes: number;\n vmsBytes: number;\n openFiles: number;\n}\n\nexport interface TaskProcessDetails {\n pid?: number;\n command: string;\n args?: string[];\n status: string;\n started?: string;\n exitCode?: number;\n ports?: number[];\n restarts: number;\n restartPolicy: string;\n maxRestarts?: number;\n latest: TaskResourceSnapshot;\n peak: TaskResourceSnapshot;\n metrics: Record<string, string>;\n tree?: TaskProcessSample[];\n}\n\nexport interface TaskExecDetails {\n command: string;\n args?: string[];\n pid?: number;\n status: string;\n exitCode: number;\n started?: string;\n /** Go time.Duration encoded as nanoseconds. */\n duration?: number;\n [key: string]: unknown;\n}\n\nexport interface TaskSnapshot {\n id: string;\n name: string;\n /** \"task\" or \"group\". */\n type: \"task\" | \"group\";\n /** Parent group NAME (groups: empty). */\n group?: string;\n status: string;\n duration?: string;\n error?: string;\n /** Latest log line. */\n message?: string;\n logs?: LogEntry[];\n /** Group aggregates. */\n total?: number;\n completed?: number;\n failed?: number;\n running?: number;\n /** Per-task (type === \"task\") live stage label and bounded progress. */\n description?: string;\n progress?: number;\n /** Progress denominator; 0/undefined means the task has no bounded progress. */\n maxValue?: number;\n /** Stable parent-run id (tasks) or the run's own id (groups). */\n groupId?: string;\n kind?: string;\n labels?: Record<string, string>;\n owner?: string;\n /** RFC3339. */\n startedAt?: string;\n /** RFC3339. */\n finishedAt?: string;\n href?: string;\n controls?: TaskControlAction[];\n stdout?: string;\n stderr?: string;\n stdoutTruncated?: boolean;\n stderrTruncated?: boolean;\n details?: TaskProcessDetails | TaskExecDetails | Record<string, unknown>;\n}\n\n// TaskRunMeta mirrors the Go `task.RunMeta` listing summary returned by\n// GET {prefix}/tasks. Named TaskRunMeta to avoid colliding with the unrelated\n// diagnostics `RunMeta` already exported by this package.\nexport interface TaskRunMeta {\n id: string;\n name: string;\n kind?: string;\n labels?: Record<string, string>;\n owner?: string;\n status: string;\n startedAt?: string;\n finishedAt?: string;\n total: number;\n completed: number;\n failed: number;\n running: number;\n href?: string;\n controls?: TaskControlAction[];\n}\n\n// Terminal run/group statuses (not running/pending). Used to decide when an SSE\n// stream is done or when polling should stop.\nconst TERMINAL_STATUSES = new Set([\n \"success\",\n \"failed\",\n \"warning\",\n \"canceled\",\n \"PASS\",\n \"FAIL\",\n \"ERR\",\n \"SKIP\",\n]);\n\nexport function isTerminalStatus(status: string | undefined): boolean {\n return !!status && TERMINAL_STATUSES.has(status);\n}\n\n// allGroupsTerminal reports whether every group snapshot has reached a terminal\n// status — i.e. the run(s) are complete and an SSE stream / poll can stop.\nexport function allGroupsTerminal(snapshots: TaskSnapshot[]): boolean {\n const groups = snapshots.filter((s) => s.type === \"group\");\n if (groups.length === 0) return false;\n return groups.every((g) => isTerminalStatus(g.status));\n}\n"],"names":[],"mappings":"AA4HA,MAAM,wCAAwB,IAAI;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,iBAAiB,QAAqC;AACpE,SAAO,CAAC,CAAC,UAAU,kBAAkB,IAAI,MAAM;AACjD;AAIO,SAAS,kBAAkB,WAAoC;AACpE,QAAM,SAAS,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO;AACzD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,OAAO,MAAM,CAAC,MAAM,iBAAiB,EAAE,MAAM,CAAC;AACvD;"}
@@ -38,6 +38,7 @@ const ChatWindow_preferences = require("./ChatWindow.preferences.cjs");
38
38
  const ChatWindow_runtime = require("./ChatWindow.runtime.cjs");
39
39
  const ChatWindow_catalogs = require("./ChatWindow.catalogs.cjs");
40
40
  const ChatWindow_toolCatalog = require("./ChatWindow.tool-catalog.cjs");
41
+ const ToolPreferences_model = require("./ToolPreferences.model.cjs");
41
42
  const ChatWindow_thread = require("./ChatWindow.thread.cjs");
42
43
  const ChatWindow_threadStatus = require("./ChatWindow.thread-status.cjs");
43
44
  const UiGitBranch = require("../../icons/components/UiGitBranch.cjs");
@@ -61,7 +62,7 @@ function ChatWindow({
61
62
  threadsSource,
62
63
  contextTypeConfig,
63
64
  tools,
64
- defaultToolMode = "ask",
65
+ defaultToolPolicy = "ask",
65
66
  toolsApi = "/api/chat/tools",
66
67
  runtimesApi = null,
67
68
  toolRenderers,
@@ -87,7 +88,9 @@ function ChatWindow({
87
88
  );
88
89
  const [usage, setUsage] = react.useState(null);
89
90
  const [titleRefresh, setTitleRefresh] = react.useState(0);
90
- const [explicitToolPrefs, setExplicitToolPrefs] = react.useState(storedPrefs.toolPrefs ?? {});
91
+ const [userToolRules, setUserToolRules] = react.useState(
92
+ storedPrefs.toolRules ?? []
93
+ );
91
94
  const [fetchedTools, setFetchedTools] = react.useState(
92
95
  void 0
93
96
  );
@@ -170,30 +173,21 @@ function ChatWindow({
170
173
  runtime: runtimeLocked ? preferredRuntimeRef.current : runtime,
171
174
  ...budget.cost !== void 0 || budget.maxTokens !== void 0 ? { budget } : {},
172
175
  permissionMode,
173
- toolPrefs: explicitToolPrefs
176
+ toolRules: userToolRules
174
177
  });
175
- }, [budget, permissionMode, runtime, runtimeLocked, explicitToolPrefs]);
178
+ }, [budget, permissionMode, runtime, runtimeLocked, userToolRules]);
176
179
  const toolPrefs = react.useMemo(
177
- () => ChatWindow_toolCatalog.effectiveToolPreferences({
180
+ () => ToolPreferences_model.effectiveToolPolicies({
178
181
  tools: resolvedTools,
179
- explicit: explicitToolPrefs,
180
- surfaceDefaults: panel.toolDefaults,
181
- fallback: defaultToolMode
182
+ surfacePolicy: panel.toolPolicy,
183
+ userRules: userToolRules,
184
+ fallback: defaultToolPolicy
182
185
  }),
183
- [defaultToolMode, explicitToolPrefs, panel.toolDefaults, resolvedTools]
184
- );
185
- const handleToolPrefsChange = react.useCallback(
186
- (next) => {
187
- setExplicitToolPrefs((prev) => {
188
- const updated = { ...prev };
189
- for (const [name, mode] of Object.entries(next)) {
190
- if (toolPrefs[name] !== mode) updated[name] = mode;
191
- }
192
- return updated;
193
- });
194
- },
195
- [toolPrefs]
186
+ [defaultToolPolicy, panel.toolPolicy, resolvedTools, userToolRules]
196
187
  );
188
+ const handleToolRule = react.useCallback((rule) => {
189
+ setUserToolRules((prev) => ToolPreferences_model.withUserRule(prev, rule));
190
+ }, []);
197
191
  react.useEffect(() => {
198
192
  let active = true;
199
193
  import("react-rnd").then((m) => {
@@ -228,7 +222,8 @@ function ChatWindow({
228
222
  base: chat == null ? void 0 : chat.body,
229
223
  contextItems: panel.contextItems,
230
224
  tools: resolvedTools,
231
- toolPrefs
225
+ surfacePolicy: panel.toolPolicy,
226
+ userPolicy: userToolRules
232
227
  });
233
228
  const initialPrompt = panel.initialPrompt ?? (chat == null ? void 0 : chat.initialPrompt) ?? null;
234
229
  const handleInitialPromptSent = react.useCallback(() => {
@@ -308,7 +303,7 @@ function ChatWindow({
308
303
  {
309
304
  tools: resolvedTools,
310
305
  value: toolPrefs,
311
- onChange: handleToolPrefsChange,
306
+ onRule: handleToolRule,
312
307
  models: resolvedModels,
313
308
  runtime,
314
309
  onRuntimeChange: handleRuntimeChange,