@flanksource/clicky-ui 0.3.54 → 0.3.56

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 (999) hide show
  1. package/NOTICE.md +6 -0
  2. package/dist/ai.cjs +6 -0
  3. package/dist/ai.js +3 -1
  4. package/dist/chat.cjs +2 -0
  5. package/dist/chat.d.ts +1 -0
  6. package/dist/chat.d.ts.map +1 -1
  7. package/dist/chat.js +2 -1
  8. package/dist/comments/CommentCard.cjs +37 -7
  9. package/dist/comments/CommentCard.cjs.map +1 -1
  10. package/dist/comments/CommentCard.d.ts +11 -1
  11. package/dist/comments/CommentCard.d.ts.map +1 -1
  12. package/dist/comments/CommentCard.js +37 -7
  13. package/dist/comments/CommentCard.js.map +1 -1
  14. package/dist/comments/CommentCardParts.cjs +9 -4
  15. package/dist/comments/CommentCardParts.cjs.map +1 -1
  16. package/dist/comments/CommentCardParts.d.ts.map +1 -1
  17. package/dist/comments/CommentCardParts.js +9 -4
  18. package/dist/comments/CommentCardParts.js.map +1 -1
  19. package/dist/comments/CommentComposer.cjs +8 -8
  20. package/dist/comments/CommentComposer.cjs.map +1 -1
  21. package/dist/comments/CommentComposer.d.ts.map +1 -1
  22. package/dist/comments/CommentComposer.js +8 -8
  23. package/dist/comments/CommentComposer.js.map +1 -1
  24. package/dist/comments/CommentProvider.cjs +5 -1
  25. package/dist/comments/CommentProvider.cjs.map +1 -1
  26. package/dist/comments/CommentProvider.d.ts +1 -1
  27. package/dist/comments/CommentProvider.d.ts.map +1 -1
  28. package/dist/comments/CommentProvider.js +5 -1
  29. package/dist/comments/CommentProvider.js.map +1 -1
  30. package/dist/comments/CommentSidePanel.cjs +17 -11
  31. package/dist/comments/CommentSidePanel.cjs.map +1 -1
  32. package/dist/comments/CommentSidePanel.d.ts +6 -0
  33. package/dist/comments/CommentSidePanel.d.ts.map +1 -1
  34. package/dist/comments/CommentSidePanel.js +17 -11
  35. package/dist/comments/CommentSidePanel.js.map +1 -1
  36. package/dist/comments/CommentThread.cjs +4 -1
  37. package/dist/comments/CommentThread.cjs.map +1 -1
  38. package/dist/comments/CommentThread.d.ts +4 -1
  39. package/dist/comments/CommentThread.d.ts.map +1 -1
  40. package/dist/comments/CommentThread.js +4 -1
  41. package/dist/comments/CommentThread.js.map +1 -1
  42. package/dist/comments/CommentThreadList.cjs +6 -3
  43. package/dist/comments/CommentThreadList.cjs.map +1 -1
  44. package/dist/comments/CommentThreadList.d.ts +7 -2
  45. package/dist/comments/CommentThreadList.d.ts.map +1 -1
  46. package/dist/comments/CommentThreadList.js +6 -3
  47. package/dist/comments/CommentThreadList.js.map +1 -1
  48. package/dist/comments/MentionTextarea.cjs +1 -1
  49. package/dist/comments/MentionTextarea.cjs.map +1 -1
  50. package/dist/comments/MentionTextarea.d.ts.map +1 -1
  51. package/dist/comments/MentionTextarea.js +1 -1
  52. package/dist/comments/MentionTextarea.js.map +1 -1
  53. package/dist/comments/comment-assign.cjs +68 -0
  54. package/dist/comments/comment-assign.cjs.map +1 -0
  55. package/dist/comments/comment-assign.d.ts +31 -0
  56. package/dist/comments/comment-assign.d.ts.map +1 -0
  57. package/dist/comments/comment-assign.js +67 -0
  58. package/dist/comments/comment-assign.js.map +1 -0
  59. package/dist/comments/comment-types.cjs.map +1 -1
  60. package/dist/comments/comment-types.d.ts +39 -0
  61. package/dist/comments/comment-types.d.ts.map +1 -1
  62. package/dist/comments/comment-types.js.map +1 -1
  63. package/dist/comments/comment-utils.cjs +2 -0
  64. package/dist/comments/comment-utils.cjs.map +1 -1
  65. package/dist/comments/comment-utils.d.ts +2 -0
  66. package/dist/comments/comment-utils.d.ts.map +1 -1
  67. package/dist/comments/comment-utils.js +2 -0
  68. package/dist/comments/comment-utils.js.map +1 -1
  69. package/dist/comments.cjs +3 -0
  70. package/dist/comments.d.ts +1 -0
  71. package/dist/comments.d.ts.map +1 -1
  72. package/dist/comments.js +2 -1
  73. package/dist/components/ComboboxMenu.cjs +23 -13
  74. package/dist/components/ComboboxMenu.cjs.map +1 -1
  75. package/dist/components/ComboboxMenu.d.ts.map +1 -1
  76. package/dist/components/ComboboxMenu.js +23 -13
  77. package/dist/components/ComboboxMenu.js.map +1 -1
  78. package/dist/components/FilterBar.cjs +29 -6
  79. package/dist/components/FilterBar.cjs.map +1 -1
  80. package/dist/components/FilterBar.d.ts +3 -1
  81. package/dist/components/FilterBar.d.ts.map +1 -1
  82. package/dist/components/FilterBar.js +29 -6
  83. package/dist/components/FilterBar.js.map +1 -1
  84. package/dist/components/ItemActions.cjs +1 -1
  85. package/dist/components/ItemActions.cjs.map +1 -1
  86. package/dist/components/ItemActions.js +1 -1
  87. package/dist/components/ItemActions.js.map +1 -1
  88. package/dist/components/ListMenu.cjs +33 -3
  89. package/dist/components/ListMenu.cjs.map +1 -1
  90. package/dist/components/ListMenu.d.ts +4 -1
  91. package/dist/components/ListMenu.d.ts.map +1 -1
  92. package/dist/components/ListMenu.js +33 -3
  93. package/dist/components/ListMenu.js.map +1 -1
  94. package/dist/components/ListMenuItems.cjs +80 -0
  95. package/dist/components/ListMenuItems.cjs.map +1 -0
  96. package/dist/components/ListMenuItems.d.ts +8 -0
  97. package/dist/components/ListMenuItems.d.ts.map +1 -0
  98. package/dist/components/ListMenuItems.js +80 -0
  99. package/dist/components/ListMenuItems.js.map +1 -0
  100. package/dist/components/LocalPathPicker.cjs +182 -0
  101. package/dist/components/LocalPathPicker.cjs.map +1 -0
  102. package/dist/components/LocalPathPicker.d.ts +11 -0
  103. package/dist/components/LocalPathPicker.d.ts.map +1 -0
  104. package/dist/components/LocalPathPicker.js +182 -0
  105. package/dist/components/LocalPathPicker.js.map +1 -0
  106. package/dist/components/LocalPathTree.cjs +89 -0
  107. package/dist/components/LocalPathTree.cjs.map +1 -0
  108. package/dist/components/LocalPathTree.d.ts +9 -0
  109. package/dist/components/LocalPathTree.d.ts.map +1 -0
  110. package/dist/components/LocalPathTree.js +89 -0
  111. package/dist/components/LocalPathTree.js.map +1 -0
  112. package/dist/components/RangeSlider.cjs +10 -30
  113. package/dist/components/RangeSlider.cjs.map +1 -1
  114. package/dist/components/RangeSlider.d.ts.map +1 -1
  115. package/dist/components/RangeSlider.js +4 -24
  116. package/dist/components/RangeSlider.js.map +1 -1
  117. package/dist/components/Slider.cjs +79 -0
  118. package/dist/components/Slider.cjs.map +1 -0
  119. package/dist/components/Slider.d.ts +23 -0
  120. package/dist/components/Slider.d.ts.map +1 -0
  121. package/dist/components/Slider.js +79 -0
  122. package/dist/components/Slider.js.map +1 -0
  123. package/dist/components/combobox-types.d.ts +4 -1
  124. package/dist/components/combobox-types.d.ts.map +1 -1
  125. package/dist/components/filter-bar-field-utils.cjs +3 -5
  126. package/dist/components/filter-bar-field-utils.cjs.map +1 -1
  127. package/dist/components/filter-bar-field-utils.d.ts.map +1 -1
  128. package/dist/components/filter-bar-field-utils.js +3 -5
  129. package/dist/components/filter-bar-field-utils.js.map +1 -1
  130. package/dist/components/filter-bar-tree-model.cjs +22 -0
  131. package/dist/components/filter-bar-tree-model.cjs.map +1 -0
  132. package/dist/components/filter-bar-tree-model.d.ts +33 -0
  133. package/dist/components/filter-bar-tree-model.d.ts.map +1 -0
  134. package/dist/components/filter-bar-tree-model.js +21 -0
  135. package/dist/components/filter-bar-tree-model.js.map +1 -0
  136. package/dist/components/filter-bar-tree.cjs +84 -0
  137. package/dist/components/filter-bar-tree.cjs.map +1 -0
  138. package/dist/components/filter-bar-tree.d.ts +7 -0
  139. package/dist/components/filter-bar-tree.d.ts.map +1 -0
  140. package/dist/components/filter-bar-tree.js +84 -0
  141. package/dist/components/filter-bar-tree.js.map +1 -0
  142. package/dist/components/json-schema-form-debug-glyph-map.cjs +2 -0
  143. package/dist/components/json-schema-form-debug-glyph-map.cjs.map +1 -1
  144. package/dist/components/json-schema-form-debug-glyph-map.d.ts.map +1 -1
  145. package/dist/components/json-schema-form-debug-glyph-map.js +2 -0
  146. package/dist/components/json-schema-form-debug-glyph-map.js.map +1 -1
  147. package/dist/components/json-schema-form-help-links.cjs +18 -0
  148. package/dist/components/json-schema-form-help-links.cjs.map +1 -0
  149. package/dist/components/json-schema-form-help-links.d.ts +5 -0
  150. package/dist/components/json-schema-form-help-links.d.ts.map +1 -0
  151. package/dist/components/json-schema-form-help-links.js +18 -0
  152. package/dist/components/json-schema-form-help-links.js.map +1 -0
  153. package/dist/components/json-schema-form-help-model.cjs +7 -0
  154. package/dist/components/json-schema-form-help-model.cjs.map +1 -0
  155. package/dist/components/json-schema-form-help-model.d.ts +3 -0
  156. package/dist/components/json-schema-form-help-model.d.ts.map +1 -0
  157. package/dist/components/json-schema-form-help-model.js +7 -0
  158. package/dist/components/json-schema-form-help-model.js.map +1 -0
  159. package/dist/components/json-schema-form-json.cjs +48 -0
  160. package/dist/components/json-schema-form-json.cjs.map +1 -0
  161. package/dist/components/json-schema-form-json.d.ts +7 -0
  162. package/dist/components/json-schema-form-json.d.ts.map +1 -0
  163. package/dist/components/json-schema-form-json.js +48 -0
  164. package/dist/components/json-schema-form-json.js.map +1 -0
  165. package/dist/components/json-schema-form-layout.cjs +7 -5
  166. package/dist/components/json-schema-form-layout.cjs.map +1 -1
  167. package/dist/components/json-schema-form-layout.d.ts +2 -2
  168. package/dist/components/json-schema-form-layout.d.ts.map +1 -1
  169. package/dist/components/json-schema-form-layout.js +7 -5
  170. package/dist/components/json-schema-form-layout.js.map +1 -1
  171. package/dist/components/json-schema-form-object.cjs +2 -13
  172. package/dist/components/json-schema-form-object.cjs.map +1 -1
  173. package/dist/components/json-schema-form-object.d.ts.map +1 -1
  174. package/dist/components/json-schema-form-object.js +2 -13
  175. package/dist/components/json-schema-form-object.js.map +1 -1
  176. package/dist/components/json-schema-form-refs.cjs +1 -1
  177. package/dist/components/json-schema-form-refs.cjs.map +1 -1
  178. package/dist/components/json-schema-form-refs.d.ts.map +1 -1
  179. package/dist/components/json-schema-form-refs.js +1 -1
  180. package/dist/components/json-schema-form-refs.js.map +1 -1
  181. package/dist/components/json-schema-form-render.cjs +20 -6
  182. package/dist/components/json-schema-form-render.cjs.map +1 -1
  183. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  184. package/dist/components/json-schema-form-render.js +20 -6
  185. package/dist/components/json-schema-form-render.js.map +1 -1
  186. package/dist/components/json-schema-form-resolve.cjs +22 -2
  187. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  188. package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
  189. package/dist/components/json-schema-form-resolve.js +22 -2
  190. package/dist/components/json-schema-form-resolve.js.map +1 -1
  191. package/dist/components/json-schema-form-types.d.ts +5 -1
  192. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  193. package/dist/components/json-schema-form-union-model.cjs +46 -0
  194. package/dist/components/json-schema-form-union-model.cjs.map +1 -0
  195. package/dist/components/json-schema-form-union-model.d.ts +6 -0
  196. package/dist/components/json-schema-form-union-model.d.ts.map +1 -0
  197. package/dist/components/json-schema-form-union-model.js +43 -0
  198. package/dist/components/json-schema-form-union-model.js.map +1 -0
  199. package/dist/components/json-schema-form-union.cjs +52 -0
  200. package/dist/components/json-schema-form-union.cjs.map +1 -0
  201. package/dist/components/json-schema-form-union.d.ts +7 -0
  202. package/dist/components/json-schema-form-union.d.ts.map +1 -0
  203. package/dist/components/json-schema-form-union.js +52 -0
  204. package/dist/components/json-schema-form-union.js.map +1 -0
  205. package/dist/components/list-menu-virtual.cjs +5 -0
  206. package/dist/components/list-menu-virtual.cjs.map +1 -0
  207. package/dist/components/list-menu-virtual.d.ts +12 -0
  208. package/dist/components/list-menu-virtual.d.ts.map +1 -0
  209. package/dist/components/list-menu-virtual.js +6 -0
  210. package/dist/components/list-menu-virtual.js.map +1 -0
  211. package/dist/components/local-path.cjs +12 -0
  212. package/dist/components/local-path.cjs.map +1 -0
  213. package/dist/components/local-path.d.ts +14 -0
  214. package/dist/components/local-path.d.ts.map +1 -0
  215. package/dist/components/local-path.js +12 -0
  216. package/dist/components/local-path.js.map +1 -0
  217. package/dist/components/slider-shared.cjs +32 -0
  218. package/dist/components/slider-shared.cjs.map +1 -0
  219. package/dist/components/slider-shared.d.ts +18 -0
  220. package/dist/components/slider-shared.d.ts.map +1 -0
  221. package/dist/components/slider-shared.js +27 -0
  222. package/dist/components/slider-shared.js.map +1 -0
  223. package/dist/components.cjs +8 -0
  224. package/dist/components.d.ts +6 -1
  225. package/dist/components.d.ts.map +1 -1
  226. package/dist/components.js +5 -1
  227. package/dist/connections/ConnectionsPage.cjs +51 -19
  228. package/dist/connections/ConnectionsPage.cjs.map +1 -1
  229. package/dist/connections/ConnectionsPage.d.ts +9 -1
  230. package/dist/connections/ConnectionsPage.d.ts.map +1 -1
  231. package/dist/connections/ConnectionsPage.js +52 -20
  232. package/dist/connections/ConnectionsPage.js.map +1 -1
  233. package/dist/connections/connectionDashboard.cjs +13 -8
  234. package/dist/connections/connectionDashboard.cjs.map +1 -1
  235. package/dist/connections/connectionDashboard.d.ts +8 -3
  236. package/dist/connections/connectionDashboard.d.ts.map +1 -1
  237. package/dist/connections/connectionDashboard.js +14 -9
  238. package/dist/connections/connectionDashboard.js.map +1 -1
  239. package/dist/connections/connectionDashboardModel.cjs.map +1 -1
  240. package/dist/connections/connectionDashboardModel.d.ts +4 -0
  241. package/dist/connections/connectionDashboardModel.d.ts.map +1 -1
  242. package/dist/connections/connectionDashboardModel.js.map +1 -1
  243. package/dist/connections/connectionDashboardRow.cjs +75 -55
  244. package/dist/connections/connectionDashboardRow.cjs.map +1 -1
  245. package/dist/connections/connectionDashboardRow.d.ts +3 -2
  246. package/dist/connections/connectionDashboardRow.d.ts.map +1 -1
  247. package/dist/connections/connectionDashboardRow.js +75 -55
  248. package/dist/connections/connectionDashboardRow.js.map +1 -1
  249. package/dist/connections/connectionNamespaceField.cjs +17 -0
  250. package/dist/connections/connectionNamespaceField.cjs.map +1 -0
  251. package/dist/connections/connectionNamespaceField.d.ts +10 -0
  252. package/dist/connections/connectionNamespaceField.d.ts.map +1 -0
  253. package/dist/connections/connectionNamespaceField.js +17 -0
  254. package/dist/connections/connectionNamespaceField.js.map +1 -0
  255. package/dist/connections/connectionSchemaFormExtensions.cjs +98 -0
  256. package/dist/connections/connectionSchemaFormExtensions.cjs.map +1 -0
  257. package/dist/connections/connectionSchemaFormExtensions.d.ts +41 -0
  258. package/dist/connections/connectionSchemaFormExtensions.d.ts.map +1 -0
  259. package/dist/connections/connectionSchemaFormExtensions.js +96 -0
  260. package/dist/connections/connectionSchemaFormExtensions.js.map +1 -0
  261. package/dist/connections/connectionsPageModel.cjs +11 -0
  262. package/dist/connections/connectionsPageModel.cjs.map +1 -1
  263. package/dist/connections/connectionsPageModel.d.ts +5 -0
  264. package/dist/connections/connectionsPageModel.d.ts.map +1 -1
  265. package/dist/connections/connectionsPageModel.js +11 -1
  266. package/dist/connections/connectionsPageModel.js.map +1 -1
  267. package/dist/connections.cjs +5 -0
  268. package/dist/connections.d.ts +2 -1
  269. package/dist/connections.d.ts.map +1 -1
  270. package/dist/connections.js +3 -2
  271. package/dist/data/AvatarBadge.cjs +3 -3
  272. package/dist/data/AvatarBadge.cjs.map +1 -1
  273. package/dist/data/AvatarBadge.js +3 -3
  274. package/dist/data/AvatarBadge.js.map +1 -1
  275. package/dist/data/CodeDiff.cjs +2 -0
  276. package/dist/data/CodeDiff.cjs.map +1 -1
  277. package/dist/data/CodeDiff.js +2 -0
  278. package/dist/data/CodeDiff.js.map +1 -1
  279. package/dist/data/DataTable.cjs +3 -2
  280. package/dist/data/DataTable.cjs.map +1 -1
  281. package/dist/data/DataTable.d.ts.map +1 -1
  282. package/dist/data/DataTable.js +3 -2
  283. package/dist/data/DataTable.js.map +1 -1
  284. package/dist/data/Gauge.cjs +1 -1
  285. package/dist/data/Gauge.cjs.map +1 -1
  286. package/dist/data/Gauge.js +1 -1
  287. package/dist/data/Gauge.js.map +1 -1
  288. package/dist/data/HighlightedTokens.cjs +2 -10
  289. package/dist/data/HighlightedTokens.cjs.map +1 -1
  290. package/dist/data/HighlightedTokens.d.ts.map +1 -1
  291. package/dist/data/HighlightedTokens.js +1 -9
  292. package/dist/data/HighlightedTokens.js.map +1 -1
  293. package/dist/data/Markdown.cjs +38 -11
  294. package/dist/data/Markdown.cjs.map +1 -1
  295. package/dist/data/Markdown.d.ts +9 -1
  296. package/dist/data/Markdown.d.ts.map +1 -1
  297. package/dist/data/Markdown.js +39 -12
  298. package/dist/data/Markdown.js.map +1 -1
  299. package/dist/data/MultiGaugeBar.cjs +157 -0
  300. package/dist/data/MultiGaugeBar.cjs.map +1 -0
  301. package/dist/data/MultiGaugeBar.d.ts +29 -0
  302. package/dist/data/MultiGaugeBar.d.ts.map +1 -0
  303. package/dist/data/MultiGaugeBar.js +157 -0
  304. package/dist/data/MultiGaugeBar.js.map +1 -0
  305. package/dist/data/OpenInFilesLink.cjs +27 -0
  306. package/dist/data/OpenInFilesLink.cjs.map +1 -0
  307. package/dist/data/OpenInFilesLink.d.ts +15 -0
  308. package/dist/data/OpenInFilesLink.d.ts.map +1 -0
  309. package/dist/data/OpenInFilesLink.js +27 -0
  310. package/dist/data/OpenInFilesLink.js.map +1 -0
  311. package/dist/data/ProgressBar.cjs +5 -3
  312. package/dist/data/ProgressBar.cjs.map +1 -1
  313. package/dist/data/ProgressBar.d.ts +5 -1
  314. package/dist/data/ProgressBar.d.ts.map +1 -1
  315. package/dist/data/ProgressBar.js +5 -3
  316. package/dist/data/ProgressBar.js.map +1 -1
  317. package/dist/data/ProgressBars.cjs +13 -5
  318. package/dist/data/ProgressBars.cjs.map +1 -1
  319. package/dist/data/ProgressBars.d.ts +6 -1
  320. package/dist/data/ProgressBars.d.ts.map +1 -1
  321. package/dist/data/ProgressBars.js +13 -5
  322. package/dist/data/ProgressBars.js.map +1 -1
  323. package/dist/data/Properties.cjs +3 -3
  324. package/dist/data/Properties.cjs.map +1 -1
  325. package/dist/data/Properties.js +3 -3
  326. package/dist/data/Properties.js.map +1 -1
  327. package/dist/data/TaskProgress.cjs +14 -6
  328. package/dist/data/TaskProgress.cjs.map +1 -1
  329. package/dist/data/TaskProgress.d.ts +3 -1
  330. package/dist/data/TaskProgress.d.ts.map +1 -1
  331. package/dist/data/TaskProgress.js +14 -6
  332. package/dist/data/TaskProgress.js.map +1 -1
  333. package/dist/data/TaskPrompts.cjs +96 -0
  334. package/dist/data/TaskPrompts.cjs.map +1 -0
  335. package/dist/data/TaskPrompts.d.ts +6 -0
  336. package/dist/data/TaskPrompts.d.ts.map +1 -0
  337. package/dist/data/TaskPrompts.js +96 -0
  338. package/dist/data/TaskPrompts.js.map +1 -0
  339. package/dist/data/TaskSnapshot.cjs.map +1 -1
  340. package/dist/data/TaskSnapshot.d.ts +3 -0
  341. package/dist/data/TaskSnapshot.d.ts.map +1 -1
  342. package/dist/data/TaskSnapshot.js.map +1 -1
  343. package/dist/data/TimeseriesCoreBars.cjs +7 -3
  344. package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
  345. package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
  346. package/dist/data/TimeseriesCoreBars.js +8 -4
  347. package/dist/data/TimeseriesCoreBars.js.map +1 -1
  348. package/dist/data/TimeseriesGauge.cjs +12 -5
  349. package/dist/data/TimeseriesGauge.cjs.map +1 -1
  350. package/dist/data/TimeseriesGauge.d.ts.map +1 -1
  351. package/dist/data/TimeseriesGauge.js +13 -6
  352. package/dist/data/TimeseriesGauge.js.map +1 -1
  353. package/dist/data/TimeseriesPanel.cjs +10 -9
  354. package/dist/data/TimeseriesPanel.cjs.map +1 -1
  355. package/dist/data/TimeseriesPanel.d.ts +1 -1
  356. package/dist/data/TimeseriesPanel.d.ts.map +1 -1
  357. package/dist/data/TimeseriesPanel.js +11 -10
  358. package/dist/data/TimeseriesPanel.js.map +1 -1
  359. package/dist/data/TimeseriesPanel.model.cjs +62 -10
  360. package/dist/data/TimeseriesPanel.model.cjs.map +1 -1
  361. package/dist/data/TimeseriesPanel.model.d.ts +40 -1
  362. package/dist/data/TimeseriesPanel.model.d.ts.map +1 -1
  363. package/dist/data/TimeseriesPanel.model.js +62 -11
  364. package/dist/data/TimeseriesPanel.model.js.map +1 -1
  365. package/dist/data/WorkloadCard.cjs +7 -3
  366. package/dist/data/WorkloadCard.cjs.map +1 -1
  367. package/dist/data/WorkloadCard.d.ts +3 -1
  368. package/dist/data/WorkloadCard.d.ts.map +1 -1
  369. package/dist/data/WorkloadCard.js +7 -3
  370. package/dist/data/WorkloadCard.js.map +1 -1
  371. package/dist/data/WorkloadCard.model.cjs.map +1 -1
  372. package/dist/data/WorkloadCard.model.d.ts +2 -0
  373. package/dist/data/WorkloadCard.model.d.ts.map +1 -1
  374. package/dist/data/WorkloadCard.model.js.map +1 -1
  375. package/dist/data/ai/ChatWindow.placement.cjs +2 -1
  376. package/dist/data/ai/ChatWindow.placement.cjs.map +1 -1
  377. package/dist/data/ai/ChatWindow.placement.d.ts +1 -1
  378. package/dist/data/ai/ChatWindow.placement.d.ts.map +1 -1
  379. package/dist/data/ai/ChatWindow.placement.js +2 -1
  380. package/dist/data/ai/ChatWindow.placement.js.map +1 -1
  381. package/dist/data/ai/SpecRuntimeBar.cjs +2 -2
  382. package/dist/data/ai/SpecRuntimeBar.cjs.map +1 -1
  383. package/dist/data/ai/SpecRuntimeBar.d.ts +4 -1
  384. package/dist/data/ai/SpecRuntimeBar.d.ts.map +1 -1
  385. package/dist/data/ai/SpecRuntimeBar.js +2 -2
  386. package/dist/data/ai/SpecRuntimeBar.js.map +1 -1
  387. package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs +1 -1
  388. package/dist/data/ai/SpecRuntimeEditor/PromptSection.cjs.map +1 -1
  389. package/dist/data/ai/SpecRuntimeEditor/PromptSection.js +1 -1
  390. package/dist/data/ai/SpecRuntimeEditor/PromptSection.js.map +1 -1
  391. package/dist/data/ai/SpecRuntimeEditor.model.cjs +2 -2
  392. package/dist/data/ai/SpecRuntimeEditor.model.cjs.map +1 -1
  393. package/dist/data/ai/SpecRuntimeEditor.model.d.ts +2 -2
  394. package/dist/data/ai/SpecRuntimeEditor.model.d.ts.map +1 -1
  395. package/dist/data/ai/SpecRuntimeEditor.model.js +2 -2
  396. package/dist/data/ai/SpecRuntimeEditor.model.js.map +1 -1
  397. package/dist/data/ai/ThreadPicker.cjs +2 -2
  398. package/dist/data/ai/ThreadPicker.cjs.map +1 -1
  399. package/dist/data/ai/ThreadPicker.js +2 -2
  400. package/dist/data/ai/ThreadPicker.js.map +1 -1
  401. package/dist/data/ai/index.d.ts +2 -0
  402. package/dist/data/ai/index.d.ts.map +1 -1
  403. package/dist/data/ai/use-prompt-run-stream.cjs +126 -0
  404. package/dist/data/ai/use-prompt-run-stream.cjs.map +1 -0
  405. package/dist/data/ai/use-prompt-run-stream.d.ts +52 -0
  406. package/dist/data/ai/use-prompt-run-stream.d.ts.map +1 -0
  407. package/dist/data/ai/use-prompt-run-stream.js +126 -0
  408. package/dist/data/ai/use-prompt-run-stream.js.map +1 -0
  409. package/dist/data/cache-browser/CacheBrowser.cjs +1 -0
  410. package/dist/data/cache-browser/CacheBrowser.cjs.map +1 -1
  411. package/dist/data/cache-browser/CacheBrowser.d.ts.map +1 -1
  412. package/dist/data/cache-browser/CacheBrowser.js +1 -0
  413. package/dist/data/cache-browser/CacheBrowser.js.map +1 -1
  414. package/dist/data/charts/BarChart.cjs +194 -0
  415. package/dist/data/charts/BarChart.cjs.map +1 -0
  416. package/dist/data/charts/BarChart.d.ts +19 -0
  417. package/dist/data/charts/BarChart.d.ts.map +1 -0
  418. package/dist/data/charts/BarChart.js +194 -0
  419. package/dist/data/charts/BarChart.js.map +1 -0
  420. package/dist/data/charts/ChartLegend.cjs +54 -0
  421. package/dist/data/charts/ChartLegend.cjs.map +1 -0
  422. package/dist/data/charts/ChartLegend.d.ts +17 -0
  423. package/dist/data/charts/ChartLegend.d.ts.map +1 -0
  424. package/dist/data/charts/ChartLegend.js +54 -0
  425. package/dist/data/charts/ChartLegend.js.map +1 -0
  426. package/dist/data/charts/Sparkline.cjs +56 -0
  427. package/dist/data/charts/Sparkline.cjs.map +1 -0
  428. package/dist/data/charts/Sparkline.d.ts +15 -0
  429. package/dist/data/charts/Sparkline.d.ts.map +1 -0
  430. package/dist/data/charts/Sparkline.js +56 -0
  431. package/dist/data/charts/Sparkline.js.map +1 -0
  432. package/dist/data/charts/StackedBarChart.cjs +241 -0
  433. package/dist/data/charts/StackedBarChart.cjs.map +1 -0
  434. package/dist/data/charts/StackedBarChart.d.ts +20 -0
  435. package/dist/data/charts/StackedBarChart.d.ts.map +1 -0
  436. package/dist/data/charts/StackedBarChart.js +241 -0
  437. package/dist/data/charts/StackedBarChart.js.map +1 -0
  438. package/dist/data/charts/TrendChart.cjs +157 -0
  439. package/dist/data/charts/TrendChart.cjs.map +1 -0
  440. package/dist/data/charts/TrendChart.d.ts +20 -0
  441. package/dist/data/charts/TrendChart.d.ts.map +1 -0
  442. package/dist/data/charts/TrendChart.js +157 -0
  443. package/dist/data/charts/TrendChart.js.map +1 -0
  444. package/dist/data/charts/chart-marks.cjs +115 -0
  445. package/dist/data/charts/chart-marks.cjs.map +1 -0
  446. package/dist/data/charts/chart-marks.d.ts +39 -0
  447. package/dist/data/charts/chart-marks.d.ts.map +1 -0
  448. package/dist/data/charts/chart-marks.js +112 -0
  449. package/dist/data/charts/chart-marks.js.map +1 -0
  450. package/dist/data/charts/chart-palette.cjs +74 -0
  451. package/dist/data/charts/chart-palette.cjs.map +1 -0
  452. package/dist/data/charts/chart-palette.d.ts +58 -0
  453. package/dist/data/charts/chart-palette.d.ts.map +1 -0
  454. package/dist/data/charts/chart-palette.js +72 -0
  455. package/dist/data/charts/chart-palette.js.map +1 -0
  456. package/dist/data/charts/chart-scale.cjs +115 -0
  457. package/dist/data/charts/chart-scale.cjs.map +1 -0
  458. package/dist/data/charts/chart-scale.d.ts +41 -0
  459. package/dist/data/charts/chart-scale.d.ts.map +1 -0
  460. package/dist/data/charts/chart-scale.js +104 -0
  461. package/dist/data/charts/chart-scale.js.map +1 -0
  462. package/dist/data/charts/chart.test-utils.d.ts +7 -0
  463. package/dist/data/charts/chart.test-utils.d.ts.map +1 -0
  464. package/dist/data/charts/index.d.ts +7 -0
  465. package/dist/data/charts/index.d.ts.map +1 -0
  466. package/dist/data/chat/MessageActions.cjs +1 -1
  467. package/dist/data/chat/MessageActions.cjs.map +1 -1
  468. package/dist/data/chat/MessageActions.js +1 -1
  469. package/dist/data/chat/MessageActions.js.map +1 -1
  470. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +1 -1
  471. package/dist/data/diagnostics/DiagnosticsDetailPanel.js +1 -1
  472. package/dist/data/diagnostics/DiagnosticsTree.cjs +1 -1
  473. package/dist/data/diagnostics/DiagnosticsTree.cjs.map +1 -1
  474. package/dist/data/diagnostics/DiagnosticsTree.js +1 -1
  475. package/dist/data/diagnostics/DiagnosticsTree.js.map +1 -1
  476. package/dist/data/diagnostics/FrameSourceWindow.cjs +9 -2
  477. package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
  478. package/dist/data/diagnostics/FrameSourceWindow.d.ts +1 -1
  479. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
  480. package/dist/data/diagnostics/FrameSourceWindow.js +9 -2
  481. package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
  482. package/dist/data/diagnostics/ProblemActions.cjs +37 -0
  483. package/dist/data/diagnostics/ProblemActions.cjs.map +1 -0
  484. package/dist/data/diagnostics/ProblemActions.d.ts +6 -0
  485. package/dist/data/diagnostics/ProblemActions.d.ts.map +1 -0
  486. package/dist/data/diagnostics/ProblemActions.js +37 -0
  487. package/dist/data/diagnostics/ProblemActions.js.map +1 -0
  488. package/dist/data/diagnostics/ProblemFacet.cjs +33 -0
  489. package/dist/data/diagnostics/ProblemFacet.cjs.map +1 -0
  490. package/dist/data/diagnostics/ProblemFacet.d.ts +9 -0
  491. package/dist/data/diagnostics/ProblemFacet.d.ts.map +1 -0
  492. package/dist/data/diagnostics/ProblemFacet.js +33 -0
  493. package/dist/data/diagnostics/ProblemFacet.js.map +1 -0
  494. package/dist/data/diagnostics/ProblemRow.cjs +62 -0
  495. package/dist/data/diagnostics/ProblemRow.cjs.map +1 -0
  496. package/dist/data/diagnostics/ProblemRow.d.ts +14 -0
  497. package/dist/data/diagnostics/ProblemRow.d.ts.map +1 -0
  498. package/dist/data/diagnostics/ProblemRow.js +62 -0
  499. package/dist/data/diagnostics/ProblemRow.js.map +1 -0
  500. package/dist/data/diagnostics/ProblemViewOptions.cjs +18 -0
  501. package/dist/data/diagnostics/ProblemViewOptions.cjs.map +1 -0
  502. package/dist/data/diagnostics/ProblemViewOptions.d.ts +6 -0
  503. package/dist/data/diagnostics/ProblemViewOptions.d.ts.map +1 -0
  504. package/dist/data/diagnostics/ProblemViewOptions.js +18 -0
  505. package/dist/data/diagnostics/ProblemViewOptions.js.map +1 -0
  506. package/dist/data/diagnostics/StackFrameRow.cjs +1 -1
  507. package/dist/data/diagnostics/StackFrameRow.cjs.map +1 -1
  508. package/dist/data/diagnostics/StackFrameRow.js +1 -1
  509. package/dist/data/diagnostics/StackFrameRow.js.map +1 -1
  510. package/dist/data/diagnostics/diagnostic-identity.cjs +14 -0
  511. package/dist/data/diagnostics/diagnostic-identity.cjs.map +1 -0
  512. package/dist/data/diagnostics/diagnostic-identity.d.ts +3 -0
  513. package/dist/data/diagnostics/diagnostic-identity.d.ts.map +1 -0
  514. package/dist/data/diagnostics/diagnostic-identity.js +14 -0
  515. package/dist/data/diagnostics/diagnostic-identity.js.map +1 -0
  516. package/dist/data/diagnostics/use-problem-expansion.cjs +16 -0
  517. package/dist/data/diagnostics/use-problem-expansion.cjs.map +1 -0
  518. package/dist/data/diagnostics/use-problem-expansion.d.ts +3 -0
  519. package/dist/data/diagnostics/use-problem-expansion.d.ts.map +1 -0
  520. package/dist/data/diagnostics/use-problem-expansion.js +16 -0
  521. package/dist/data/diagnostics/use-problem-expansion.js.map +1 -0
  522. package/dist/data/git/GitChangeList.cjs +9 -6
  523. package/dist/data/git/GitChangeList.cjs.map +1 -1
  524. package/dist/data/git/GitChangeList.d.ts +6 -0
  525. package/dist/data/git/GitChangeList.d.ts.map +1 -1
  526. package/dist/data/git/GitChangeList.js +9 -6
  527. package/dist/data/git/GitChangeList.js.map +1 -1
  528. package/dist/data/git/pickers/GitPickersDemo.d.ts.map +1 -1
  529. package/dist/data/git/pickers/ReferencePicker.cjs +1 -0
  530. package/dist/data/git/pickers/ReferencePicker.cjs.map +1 -1
  531. package/dist/data/git/pickers/ReferencePicker.js +1 -0
  532. package/dist/data/git/pickers/ReferencePicker.js.map +1 -1
  533. package/dist/data/lint/LintDetail.cjs +230 -189
  534. package/dist/data/lint/LintDetail.cjs.map +1 -1
  535. package/dist/data/lint/LintDetail.d.ts +25 -3
  536. package/dist/data/lint/LintDetail.d.ts.map +1 -1
  537. package/dist/data/lint/LintDetail.js +231 -192
  538. package/dist/data/lint/LintDetail.js.map +1 -1
  539. package/dist/data/lint/LintFilterBar.cjs +78 -83
  540. package/dist/data/lint/LintFilterBar.cjs.map +1 -1
  541. package/dist/data/lint/LintFilterBar.d.ts +23 -6
  542. package/dist/data/lint/LintFilterBar.d.ts.map +1 -1
  543. package/dist/data/lint/LintFilterBar.js +78 -85
  544. package/dist/data/lint/LintFilterBar.js.map +1 -1
  545. package/dist/data/lint/LintIgnoreMenu.cjs +59 -0
  546. package/dist/data/lint/LintIgnoreMenu.cjs.map +1 -0
  547. package/dist/data/lint/LintIgnoreMenu.d.ts +20 -0
  548. package/dist/data/lint/LintIgnoreMenu.d.ts.map +1 -0
  549. package/dist/data/lint/LintIgnoreMenu.js +58 -0
  550. package/dist/data/lint/LintIgnoreMenu.js.map +1 -0
  551. package/dist/data/lint/LintResults.cjs +59 -14
  552. package/dist/data/lint/LintResults.cjs.map +1 -1
  553. package/dist/data/lint/LintResults.d.ts +25 -1
  554. package/dist/data/lint/LintResults.d.ts.map +1 -1
  555. package/dist/data/lint/LintResults.fixtures.d.ts +19 -0
  556. package/dist/data/lint/LintResults.fixtures.d.ts.map +1 -1
  557. package/dist/data/lint/LintResults.js +60 -15
  558. package/dist/data/lint/LintResults.js.map +1 -1
  559. package/dist/data/lint/LintTable.cjs +156 -0
  560. package/dist/data/lint/LintTable.cjs.map +1 -0
  561. package/dist/data/lint/LintTable.d.ts +13 -0
  562. package/dist/data/lint/LintTable.d.ts.map +1 -0
  563. package/dist/data/lint/LintTable.js +156 -0
  564. package/dist/data/lint/LintTable.js.map +1 -0
  565. package/dist/data/lint/LintTreeNode.cjs +42 -19
  566. package/dist/data/lint/LintTreeNode.cjs.map +1 -1
  567. package/dist/data/lint/LintTreeNode.d.ts +7 -2
  568. package/dist/data/lint/LintTreeNode.d.ts.map +1 -1
  569. package/dist/data/lint/LintTreeNode.js +44 -21
  570. package/dist/data/lint/LintTreeNode.js.map +1 -1
  571. package/dist/data/lint/ViolationSnippet.cjs +113 -0
  572. package/dist/data/lint/ViolationSnippet.cjs.map +1 -0
  573. package/dist/data/lint/ViolationSnippet.d.ts +20 -0
  574. package/dist/data/lint/ViolationSnippet.d.ts.map +1 -0
  575. package/dist/data/lint/ViolationSnippet.js +112 -0
  576. package/dist/data/lint/ViolationSnippet.js.map +1 -0
  577. package/dist/data/lint/actions.cjs +44 -16
  578. package/dist/data/lint/actions.cjs.map +1 -1
  579. package/dist/data/lint/actions.d.ts +7 -3
  580. package/dist/data/lint/actions.d.ts.map +1 -1
  581. package/dist/data/lint/actions.js +44 -16
  582. package/dist/data/lint/actions.js.map +1 -1
  583. package/dist/data/lint/grouping.cjs +105 -8
  584. package/dist/data/lint/grouping.cjs.map +1 -1
  585. package/dist/data/lint/grouping.d.ts +21 -1
  586. package/dist/data/lint/grouping.d.ts.map +1 -1
  587. package/dist/data/lint/grouping.js +105 -10
  588. package/dist/data/lint/grouping.js.map +1 -1
  589. package/dist/data/lint/ignore-menu-items.cjs +18 -0
  590. package/dist/data/lint/ignore-menu-items.cjs.map +1 -0
  591. package/dist/data/lint/ignore-menu-items.d.ts +6 -0
  592. package/dist/data/lint/ignore-menu-items.d.ts.map +1 -0
  593. package/dist/data/lint/ignore-menu-items.js +17 -0
  594. package/dist/data/lint/ignore-menu-items.js.map +1 -0
  595. package/dist/data/lint/index.d.ts +7 -5
  596. package/dist/data/lint/index.d.ts.map +1 -1
  597. package/dist/data/lint/stats.cjs +19 -4
  598. package/dist/data/lint/stats.cjs.map +1 -1
  599. package/dist/data/lint/stats.d.ts +13 -3
  600. package/dist/data/lint/stats.d.ts.map +1 -1
  601. package/dist/data/lint/stats.js +17 -5
  602. package/dist/data/lint/stats.js.map +1 -1
  603. package/dist/data/lint/types.cjs +8 -0
  604. package/dist/data/lint/types.cjs.map +1 -1
  605. package/dist/data/lint/types.d.ts +47 -0
  606. package/dist/data/lint/types.d.ts.map +1 -1
  607. package/dist/data/lint/types.js +8 -1
  608. package/dist/data/lint/types.js.map +1 -1
  609. package/dist/data/lint/violation-menu-items.cjs +31 -0
  610. package/dist/data/lint/violation-menu-items.cjs.map +1 -0
  611. package/dist/data/lint/violation-menu-items.d.ts +12 -0
  612. package/dist/data/lint/violation-menu-items.d.ts.map +1 -0
  613. package/dist/data/lint/violation-menu-items.js +31 -0
  614. package/dist/data/lint/violation-menu-items.js.map +1 -0
  615. package/dist/data/markdown-source-blocks.cjs +38 -0
  616. package/dist/data/markdown-source-blocks.cjs.map +1 -0
  617. package/dist/data/markdown-source-blocks.d.ts +32 -0
  618. package/dist/data/markdown-source-blocks.d.ts.map +1 -0
  619. package/dist/data/markdown-source-blocks.js +35 -0
  620. package/dist/data/markdown-source-blocks.js.map +1 -0
  621. package/dist/data/test-runner/FilterFacet.cjs +52 -0
  622. package/dist/data/test-runner/FilterFacet.cjs.map +1 -0
  623. package/dist/data/test-runner/FilterFacet.d.ts +13 -0
  624. package/dist/data/test-runner/FilterFacet.d.ts.map +1 -0
  625. package/dist/data/test-runner/FilterFacet.js +52 -0
  626. package/dist/data/test-runner/FilterFacet.js.map +1 -0
  627. package/dist/data/test-runner/MatrixMarks.cjs +42 -40
  628. package/dist/data/test-runner/MatrixMarks.cjs.map +1 -1
  629. package/dist/data/test-runner/MatrixMarks.d.ts +20 -4
  630. package/dist/data/test-runner/MatrixMarks.d.ts.map +1 -1
  631. package/dist/data/test-runner/MatrixMarks.js +43 -42
  632. package/dist/data/test-runner/MatrixMarks.js.map +1 -1
  633. package/dist/data/test-runner/TestAttemptDetail.cjs +1 -1
  634. package/dist/data/test-runner/TestAttemptDetail.js +1 -1
  635. package/dist/data/test-runner/TestDetailPanel.cjs +11 -0
  636. package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
  637. package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
  638. package/dist/data/test-runner/TestDetailPanel.js +11 -0
  639. package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
  640. package/dist/data/test-runner/TestFilterBar.cjs +3 -44
  641. package/dist/data/test-runner/TestFilterBar.cjs.map +1 -1
  642. package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -1
  643. package/dist/data/test-runner/TestFilterBar.js +3 -44
  644. package/dist/data/test-runner/TestFilterBar.js.map +1 -1
  645. package/dist/data/test-runner/TestRunner.cjs +3 -1
  646. package/dist/data/test-runner/TestRunner.cjs.map +1 -1
  647. package/dist/data/test-runner/TestRunner.d.ts +7 -1
  648. package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
  649. package/dist/data/test-runner/TestRunner.js +3 -1
  650. package/dist/data/test-runner/TestRunner.js.map +1 -1
  651. package/dist/data/test-runner/context.cjs.map +1 -1
  652. package/dist/data/test-runner/context.d.ts +3 -0
  653. package/dist/data/test-runner/context.d.ts.map +1 -1
  654. package/dist/data/test-runner/context.js.map +1 -1
  655. package/dist/data/test-runner/index.d.ts +2 -2
  656. package/dist/data/test-runner/index.d.ts.map +1 -1
  657. package/dist/data/test-runner/matrix-marks.cjs +2 -11
  658. package/dist/data/test-runner/matrix-marks.cjs.map +1 -1
  659. package/dist/data/test-runner/matrix-marks.d.ts +2 -4
  660. package/dist/data/test-runner/matrix-marks.d.ts.map +1 -1
  661. package/dist/data/test-runner/matrix-marks.js +3 -11
  662. package/dist/data/test-runner/matrix-marks.js.map +1 -1
  663. package/dist/data/test-runner/types.d.ts +2 -0
  664. package/dist/data/test-runner/types.d.ts.map +1 -1
  665. package/dist/data/timeseries-query.cjs +98 -2
  666. package/dist/data/timeseries-query.cjs.map +1 -1
  667. package/dist/data/timeseries-query.d.ts +31 -5
  668. package/dist/data/timeseries-query.d.ts.map +1 -1
  669. package/dist/data/timeseries-query.js +98 -3
  670. package/dist/data/timeseries-query.js.map +1 -1
  671. package/dist/data/timeseries-stream-provider.cjs +38 -0
  672. package/dist/data/timeseries-stream-provider.cjs.map +1 -0
  673. package/dist/data/timeseries-stream-provider.d.ts +26 -0
  674. package/dist/data/timeseries-stream-provider.d.ts.map +1 -0
  675. package/dist/data/timeseries-stream-provider.js +38 -0
  676. package/dist/data/timeseries-stream-provider.js.map +1 -0
  677. package/dist/data/timeseries-stream.cjs +304 -0
  678. package/dist/data/timeseries-stream.cjs.map +1 -0
  679. package/dist/data/timeseries-stream.d.ts +81 -0
  680. package/dist/data/timeseries-stream.d.ts.map +1 -0
  681. package/dist/data/timeseries-stream.fixtures.d.ts +36 -0
  682. package/dist/data/timeseries-stream.fixtures.d.ts.map +1 -0
  683. package/dist/data/timeseries-stream.js +296 -0
  684. package/dist/data/timeseries-stream.js.map +1 -0
  685. package/dist/data/token-style.cjs +13 -0
  686. package/dist/data/token-style.cjs.map +1 -0
  687. package/dist/data/token-style.d.ts +4 -0
  688. package/dist/data/token-style.d.ts.map +1 -0
  689. package/dist/data/token-style.js +13 -0
  690. package/dist/data/token-style.js.map +1 -0
  691. package/dist/data/traces/ProcessTraceDetail.cjs +1 -1
  692. package/dist/data/traces/ProcessTraceDetail.js +1 -1
  693. package/dist/data/traces/index.d.ts +1 -1
  694. package/dist/data/traces/index.d.ts.map +1 -1
  695. package/dist/data/use-data-table-virtual.d.ts +1 -1
  696. package/dist/data/version-info.cjs +3 -3
  697. package/dist/data/version-info.js +3 -3
  698. package/dist/data/workload-panel/MemoryStack.cjs +49 -0
  699. package/dist/data/workload-panel/MemoryStack.cjs.map +1 -0
  700. package/dist/data/workload-panel/MemoryStack.d.ts +11 -0
  701. package/dist/data/workload-panel/MemoryStack.d.ts.map +1 -0
  702. package/dist/data/workload-panel/MemoryStack.js +48 -0
  703. package/dist/data/workload-panel/MemoryStack.js.map +1 -0
  704. package/dist/data/workload-panel/Metrics.cjs +197 -0
  705. package/dist/data/workload-panel/Metrics.cjs.map +1 -0
  706. package/dist/data/workload-panel/Metrics.d.ts +11 -0
  707. package/dist/data/workload-panel/Metrics.d.ts.map +1 -0
  708. package/dist/data/workload-panel/Metrics.js +196 -0
  709. package/dist/data/workload-panel/Metrics.js.map +1 -0
  710. package/dist/data/workload-panel/WorkloadPanel.cjs +66 -0
  711. package/dist/data/workload-panel/WorkloadPanel.cjs.map +1 -0
  712. package/dist/data/workload-panel/WorkloadPanel.d.ts +3 -0
  713. package/dist/data/workload-panel/WorkloadPanel.d.ts.map +1 -0
  714. package/dist/data/workload-panel/WorkloadPanel.js +66 -0
  715. package/dist/data/workload-panel/WorkloadPanel.js.map +1 -0
  716. package/dist/data/workload-panel/fixtures.d.ts +60 -0
  717. package/dist/data/workload-panel/fixtures.d.ts.map +1 -0
  718. package/dist/data/workload-panel/model.cjs +137 -0
  719. package/dist/data/workload-panel/model.cjs.map +1 -0
  720. package/dist/data/workload-panel/model.d.ts +53 -0
  721. package/dist/data/workload-panel/model.d.ts.map +1 -0
  722. package/dist/data/workload-panel/model.js +133 -0
  723. package/dist/data/workload-panel/model.js.map +1 -0
  724. package/dist/data/workload-panel/types.d.ts +56 -0
  725. package/dist/data/workload-panel/types.d.ts.map +1 -0
  726. package/dist/data.cjs +58 -7
  727. package/dist/data.d.ts +9 -1
  728. package/dist/data.d.ts.map +1 -1
  729. package/dist/data.js +29 -12
  730. package/dist/file-findings/AnnotatedCode.cjs +243 -0
  731. package/dist/file-findings/AnnotatedCode.cjs.map +1 -0
  732. package/dist/file-findings/AnnotatedCode.d.ts +30 -0
  733. package/dist/file-findings/AnnotatedCode.d.ts.map +1 -0
  734. package/dist/file-findings/AnnotatedCode.js +243 -0
  735. package/dist/file-findings/AnnotatedCode.js.map +1 -0
  736. package/dist/file-findings/FileFindingsView.cjs +213 -0
  737. package/dist/file-findings/FileFindingsView.cjs.map +1 -0
  738. package/dist/file-findings/FileFindingsView.d.ts +35 -0
  739. package/dist/file-findings/FileFindingsView.d.ts.map +1 -0
  740. package/dist/file-findings/FileFindingsView.js +213 -0
  741. package/dist/file-findings/FileFindingsView.js.map +1 -0
  742. package/dist/file-findings/LazyAnnotatedCode.cjs +22 -0
  743. package/dist/file-findings/LazyAnnotatedCode.cjs.map +1 -0
  744. package/dist/file-findings/LazyAnnotatedCode.d.ts +5 -0
  745. package/dist/file-findings/LazyAnnotatedCode.d.ts.map +1 -0
  746. package/dist/file-findings/LazyAnnotatedCode.js +22 -0
  747. package/dist/file-findings/LazyAnnotatedCode.js.map +1 -0
  748. package/dist/file-findings/adapters.cjs +155 -0
  749. package/dist/file-findings/adapters.cjs.map +1 -0
  750. package/dist/file-findings/adapters.d.ts +24 -0
  751. package/dist/file-findings/adapters.d.ts.map +1 -0
  752. package/dist/file-findings/adapters.js +153 -0
  753. package/dist/file-findings/adapters.js.map +1 -0
  754. package/dist/file-findings/file-review/CommentDraft.cjs +97 -0
  755. package/dist/file-findings/file-review/CommentDraft.cjs.map +1 -0
  756. package/dist/file-findings/file-review/CommentDraft.d.ts +25 -0
  757. package/dist/file-findings/file-review/CommentDraft.d.ts.map +1 -0
  758. package/dist/file-findings/file-review/CommentDraft.js +97 -0
  759. package/dist/file-findings/file-review/CommentDraft.js.map +1 -0
  760. package/dist/file-findings/file-review/FileReview.cjs +863 -0
  761. package/dist/file-findings/file-review/FileReview.cjs.map +1 -0
  762. package/dist/file-findings/file-review/FileReview.d.ts +79 -0
  763. package/dist/file-findings/file-review/FileReview.d.ts.map +1 -0
  764. package/dist/file-findings/file-review/FileReview.fixtures.d.ts +25 -0
  765. package/dist/file-findings/file-review/FileReview.fixtures.d.ts.map +1 -0
  766. package/dist/file-findings/file-review/FileReview.js +863 -0
  767. package/dist/file-findings/file-review/FileReview.js.map +1 -0
  768. package/dist/file-findings/file-review/InlineAuthors.cjs +77 -0
  769. package/dist/file-findings/file-review/InlineAuthors.cjs.map +1 -0
  770. package/dist/file-findings/file-review/InlineAuthors.d.ts +9 -0
  771. package/dist/file-findings/file-review/InlineAuthors.d.ts.map +1 -0
  772. package/dist/file-findings/file-review/InlineAuthors.js +77 -0
  773. package/dist/file-findings/file-review/InlineAuthors.js.map +1 -0
  774. package/dist/file-findings/file-review/InlineThread.cjs +77 -0
  775. package/dist/file-findings/file-review/InlineThread.cjs.map +1 -0
  776. package/dist/file-findings/file-review/InlineThread.d.ts +27 -0
  777. package/dist/file-findings/file-review/InlineThread.d.ts.map +1 -0
  778. package/dist/file-findings/file-review/InlineThread.js +77 -0
  779. package/dist/file-findings/file-review/InlineThread.js.map +1 -0
  780. package/dist/file-findings/file-review/ProblemsList.cjs +164 -0
  781. package/dist/file-findings/file-review/ProblemsList.cjs.map +1 -0
  782. package/dist/file-findings/file-review/ProblemsList.d.ts +15 -0
  783. package/dist/file-findings/file-review/ProblemsList.d.ts.map +1 -0
  784. package/dist/file-findings/file-review/ProblemsList.js +164 -0
  785. package/dist/file-findings/file-review/ProblemsList.js.map +1 -0
  786. package/dist/file-findings/file-review/SourceView.cjs +179 -0
  787. package/dist/file-findings/file-review/SourceView.cjs.map +1 -0
  788. package/dist/file-findings/file-review/SourceView.d.ts +29 -0
  789. package/dist/file-findings/file-review/SourceView.d.ts.map +1 -0
  790. package/dist/file-findings/file-review/SourceView.js +179 -0
  791. package/dist/file-findings/file-review/SourceView.js.map +1 -0
  792. package/dist/file-findings/file-review/blame.cjs +35 -0
  793. package/dist/file-findings/file-review/blame.cjs.map +1 -0
  794. package/dist/file-findings/file-review/blame.d.ts +28 -0
  795. package/dist/file-findings/file-review/blame.d.ts.map +1 -0
  796. package/dist/file-findings/file-review/blame.js +33 -0
  797. package/dist/file-findings/file-review/blame.js.map +1 -0
  798. package/dist/file-findings/file-review/geometry.cjs +101 -0
  799. package/dist/file-findings/file-review/geometry.cjs.map +1 -0
  800. package/dist/file-findings/file-review/geometry.d.ts +45 -0
  801. package/dist/file-findings/file-review/geometry.d.ts.map +1 -0
  802. package/dist/file-findings/file-review/geometry.js +98 -0
  803. package/dist/file-findings/file-review/geometry.js.map +1 -0
  804. package/dist/file-findings/file-review/hooks.cjs +101 -0
  805. package/dist/file-findings/file-review/hooks.cjs.map +1 -0
  806. package/dist/file-findings/file-review/hooks.d.ts +22 -0
  807. package/dist/file-findings/file-review/hooks.d.ts.map +1 -0
  808. package/dist/file-findings/file-review/hooks.js +99 -0
  809. package/dist/file-findings/file-review/hooks.js.map +1 -0
  810. package/dist/file-findings/file-review/marks.cjs +52 -0
  811. package/dist/file-findings/file-review/marks.cjs.map +1 -0
  812. package/dist/file-findings/file-review/marks.d.ts +23 -0
  813. package/dist/file-findings/file-review/marks.d.ts.map +1 -0
  814. package/dist/file-findings/file-review/marks.js +47 -0
  815. package/dist/file-findings/file-review/marks.js.map +1 -0
  816. package/dist/file-findings/file-review/problem-filters.cjs +14 -0
  817. package/dist/file-findings/file-review/problem-filters.cjs.map +1 -0
  818. package/dist/file-findings/file-review/problem-filters.d.ts +10 -0
  819. package/dist/file-findings/file-review/problem-filters.d.ts.map +1 -0
  820. package/dist/file-findings/file-review/problem-filters.js +13 -0
  821. package/dist/file-findings/file-review/problem-filters.js.map +1 -0
  822. package/dist/file-findings/file-review/quote-anchor.cjs +234 -0
  823. package/dist/file-findings/file-review/quote-anchor.cjs.map +1 -0
  824. package/dist/file-findings/file-review/quote-anchor.d.ts +54 -0
  825. package/dist/file-findings/file-review/quote-anchor.d.ts.map +1 -0
  826. package/dist/file-findings/file-review/quote-anchor.js +226 -0
  827. package/dist/file-findings/file-review/quote-anchor.js.map +1 -0
  828. package/dist/file-findings/file-review/source-anchor.cjs +104 -0
  829. package/dist/file-findings/file-review/source-anchor.cjs.map +1 -0
  830. package/dist/file-findings/file-review/source-anchor.d.ts +27 -0
  831. package/dist/file-findings/file-review/source-anchor.d.ts.map +1 -0
  832. package/dist/file-findings/file-review/source-anchor.js +99 -0
  833. package/dist/file-findings/file-review/source-anchor.js.map +1 -0
  834. package/dist/file-findings/file-review/source-marks.cjs +71 -0
  835. package/dist/file-findings/file-review/source-marks.cjs.map +1 -0
  836. package/dist/file-findings/file-review/source-marks.d.ts +27 -0
  837. package/dist/file-findings/file-review/source-marks.d.ts.map +1 -0
  838. package/dist/file-findings/file-review/source-marks.js +68 -0
  839. package/dist/file-findings/file-review/source-marks.js.map +1 -0
  840. package/dist/file-findings/findings-comments.cjs +136 -0
  841. package/dist/file-findings/findings-comments.cjs.map +1 -0
  842. package/dist/file-findings/findings-comments.d.ts +28 -0
  843. package/dist/file-findings/findings-comments.d.ts.map +1 -0
  844. package/dist/file-findings/findings-comments.js +131 -0
  845. package/dist/file-findings/findings-comments.js.map +1 -0
  846. package/dist/file-findings/findings-languages.cjs +53 -0
  847. package/dist/file-findings/findings-languages.cjs.map +1 -0
  848. package/dist/file-findings/findings-languages.d.ts +11 -0
  849. package/dist/file-findings/findings-languages.d.ts.map +1 -0
  850. package/dist/file-findings/findings-languages.js +53 -0
  851. package/dist/file-findings/findings-languages.js.map +1 -0
  852. package/dist/file-findings/mdx-source.cjs +48 -0
  853. package/dist/file-findings/mdx-source.cjs.map +1 -0
  854. package/dist/file-findings/mdx-source.d.ts +7 -0
  855. package/dist/file-findings/mdx-source.d.ts.map +1 -0
  856. package/dist/file-findings/mdx-source.js +48 -0
  857. package/dist/file-findings/mdx-source.js.map +1 -0
  858. package/dist/file-findings/monaco-language.cjs +73 -0
  859. package/dist/file-findings/monaco-language.cjs.map +1 -0
  860. package/dist/file-findings/monaco-language.d.ts +11 -0
  861. package/dist/file-findings/monaco-language.d.ts.map +1 -0
  862. package/dist/file-findings/monaco-language.js +72 -0
  863. package/dist/file-findings/monaco-language.js.map +1 -0
  864. package/dist/file-findings/severity-counts.cjs +20 -0
  865. package/dist/file-findings/severity-counts.cjs.map +1 -0
  866. package/dist/file-findings/severity-counts.d.ts +5 -0
  867. package/dist/file-findings/severity-counts.d.ts.map +1 -0
  868. package/dist/file-findings/severity-counts.js +19 -0
  869. package/dist/file-findings/severity-counts.js.map +1 -0
  870. package/dist/file-findings/types.cjs +12 -0
  871. package/dist/file-findings/types.cjs.map +1 -0
  872. package/dist/file-findings/types.d.ts +43 -0
  873. package/dist/file-findings/types.d.ts.map +1 -0
  874. package/dist/file-findings/types.js +11 -0
  875. package/dist/file-findings/types.js.map +1 -0
  876. package/dist/file-findings.cjs +47 -0
  877. package/dist/file-findings.d.ts +15 -0
  878. package/dist/file-findings.d.ts.map +1 -0
  879. package/dist/file-findings.js +15 -0
  880. package/dist/hooks/event-hub.cjs +22 -8
  881. package/dist/hooks/event-hub.cjs.map +1 -1
  882. package/dist/hooks/event-hub.d.ts.map +1 -1
  883. package/dist/hooks/event-hub.js +22 -8
  884. package/dist/hooks/event-hub.js.map +1 -1
  885. package/dist/icons/components/UiBrowser.cjs +51 -0
  886. package/dist/icons/components/UiBrowser.cjs.map +1 -0
  887. package/dist/icons/components/UiBrowser.d.ts +15 -0
  888. package/dist/icons/components/UiBrowser.d.ts.map +1 -0
  889. package/dist/icons/components/UiBrowser.js +48 -0
  890. package/dist/icons/components/UiBrowser.js.map +1 -0
  891. package/dist/icons/components/UiCreditCard.cjs +51 -0
  892. package/dist/icons/components/UiCreditCard.cjs.map +1 -0
  893. package/dist/icons/components/UiCreditCard.d.ts +15 -0
  894. package/dist/icons/components/UiCreditCard.d.ts.map +1 -0
  895. package/dist/icons/components/UiCreditCard.js +48 -0
  896. package/dist/icons/components/UiCreditCard.js.map +1 -0
  897. package/dist/icons/components/UiShoppingCart.cjs +51 -0
  898. package/dist/icons/components/UiShoppingCart.cjs.map +1 -0
  899. package/dist/icons/components/UiShoppingCart.d.ts +15 -0
  900. package/dist/icons/components/UiShoppingCart.d.ts.map +1 -0
  901. package/dist/icons/components/UiShoppingCart.js +48 -0
  902. package/dist/icons/components/UiShoppingCart.js.map +1 -0
  903. package/dist/icons/index.d.ts +6 -0
  904. package/dist/icons/index.d.ts.map +1 -1
  905. package/dist/icons/registry.cjs +6 -0
  906. package/dist/icons/registry.cjs.map +1 -1
  907. package/dist/icons/registry.d.ts.map +1 -1
  908. package/dist/icons/registry.js +6 -0
  909. package/dist/icons/registry.js.map +1 -1
  910. package/dist/icons.cjs +9 -0
  911. package/dist/icons.js +4 -1
  912. package/dist/index.cjs +76 -8
  913. package/dist/index.d.ts +1 -0
  914. package/dist/index.d.ts.map +1 -1
  915. package/dist/index.js +37 -14
  916. package/dist/layout/AppShell.cjs +37 -21
  917. package/dist/layout/AppShell.cjs.map +1 -1
  918. package/dist/layout/AppShell.d.ts +13 -2
  919. package/dist/layout/AppShell.d.ts.map +1 -1
  920. package/dist/layout/AppShell.js +37 -21
  921. package/dist/layout/AppShell.js.map +1 -1
  922. package/dist/layout/AppShell.nav.cjs +7 -6
  923. package/dist/layout/AppShell.nav.cjs.map +1 -1
  924. package/dist/layout/AppShell.nav.d.ts.map +1 -1
  925. package/dist/layout/AppShell.nav.js +7 -6
  926. package/dist/layout/AppShell.nav.js.map +1 -1
  927. package/dist/layout/SplitPane.cjs +16 -6
  928. package/dist/layout/SplitPane.cjs.map +1 -1
  929. package/dist/layout/SplitPane.d.ts +12 -2
  930. package/dist/layout/SplitPane.d.ts.map +1 -1
  931. package/dist/layout/SplitPane.js +16 -6
  932. package/dist/layout/SplitPane.js.map +1 -1
  933. package/dist/layout/Workspace.cjs +37 -33
  934. package/dist/layout/Workspace.cjs.map +1 -1
  935. package/dist/layout/Workspace.d.ts.map +1 -1
  936. package/dist/layout/Workspace.js +37 -33
  937. package/dist/layout/Workspace.js.map +1 -1
  938. package/dist/layout/Workspace.regions.cjs +3 -3
  939. package/dist/layout/Workspace.regions.cjs.map +1 -1
  940. package/dist/layout/Workspace.regions.js +3 -3
  941. package/dist/layout/Workspace.regions.js.map +1 -1
  942. package/dist/lib/breakpoints.cjs +102 -0
  943. package/dist/lib/breakpoints.cjs.map +1 -0
  944. package/dist/lib/breakpoints.d.ts +36 -0
  945. package/dist/lib/breakpoints.d.ts.map +1 -0
  946. package/dist/lib/breakpoints.js +99 -0
  947. package/dist/lib/breakpoints.js.map +1 -0
  948. package/dist/lib/combobox.cjs +2 -1
  949. package/dist/lib/combobox.cjs.map +1 -1
  950. package/dist/lib/combobox.d.ts +1 -1
  951. package/dist/lib/combobox.d.ts.map +1 -1
  952. package/dist/lib/combobox.js +2 -1
  953. package/dist/lib/combobox.js.map +1 -1
  954. package/dist/lib/path-tree.cjs +21 -0
  955. package/dist/lib/path-tree.cjs.map +1 -1
  956. package/dist/lib/path-tree.d.ts +15 -0
  957. package/dist/lib/path-tree.d.ts.map +1 -1
  958. package/dist/lib/path-tree.js +21 -1
  959. package/dist/lib/path-tree.js.map +1 -1
  960. package/dist/overlay/Modal.cjs +2 -1
  961. package/dist/overlay/Modal.cjs.map +1 -1
  962. package/dist/overlay/Modal.d.ts.map +1 -1
  963. package/dist/overlay/Modal.js +2 -1
  964. package/dist/overlay/Modal.js.map +1 -1
  965. package/dist/overlay/dropdownMenuContext.d.ts +1 -1
  966. package/dist/profiles/editor/profileEditor.cjs +1 -1
  967. package/dist/profiles/editor/profileEditor.cjs.map +1 -1
  968. package/dist/profiles/editor/profileEditor.js +1 -1
  969. package/dist/profiles/editor/profileEditor.js.map +1 -1
  970. package/dist/profiles/editor/profileEditorSections.cjs +2 -2
  971. package/dist/profiles/editor/profileEditorSections.cjs.map +1 -1
  972. package/dist/profiles/editor/profileEditorSections.js +2 -2
  973. package/dist/profiles/editor/profileEditorSections.js.map +1 -1
  974. package/dist/profiles/query/prometheusResults.cjs +24 -36
  975. package/dist/profiles/query/prometheusResults.cjs.map +1 -1
  976. package/dist/profiles/query/prometheusResults.d.ts.map +1 -1
  977. package/dist/profiles/query/prometheusResults.js +24 -36
  978. package/dist/profiles/query/prometheusResults.js.map +1 -1
  979. package/dist/rpc/CommandForm.cjs +1 -1
  980. package/dist/rpc/CommandForm.cjs.map +1 -1
  981. package/dist/rpc/CommandForm.js +1 -1
  982. package/dist/rpc/CommandForm.js.map +1 -1
  983. package/dist/rpc/classify.cjs +1 -1
  984. package/dist/rpc/classify.cjs.map +1 -1
  985. package/dist/rpc/classify.d.ts.map +1 -1
  986. package/dist/rpc/classify.js +1 -1
  987. package/dist/rpc/classify.js.map +1 -1
  988. package/dist/rpc/useOperations.d.ts +24 -24
  989. package/dist/rpc.cjs +0 -2
  990. package/dist/rpc.d.ts +0 -1
  991. package/dist/rpc.d.ts.map +1 -1
  992. package/dist/rpc.js +1 -2
  993. package/dist/styles.css +1 -1
  994. package/dist/utils.cjs +6 -0
  995. package/dist/utils.d.ts +2 -1
  996. package/dist/utils.d.ts.map +1 -1
  997. package/dist/utils.js +3 -2
  998. package/package.json +9 -3
  999. package/schemas/json-schema-form.schema.json +9 -1
@@ -1,8 +1,7 @@
1
1
  import { cn } from "../../lib/utils.js";
2
2
  import { UiServer } from "../../icons/components/UiServer.js";
3
3
  import { UiClock } from "../../icons/components/UiClock.js";
4
- import { ProgressBar } from "../ProgressBar.js";
5
- import { MATRIX_MARKS, MATRIX_ORDER, MATRIX_PLAN_BAR, formatMatrixDuration, matrixBarClass } from "./matrix-marks.js";
4
+ import { MATRIX_MARKS, MATRIX_ORDER, formatMatrixDuration, matrixBarClass } from "./matrix-marks.js";
6
5
  import { jsx, jsxs } from "react/jsx-runtime";
7
6
  // src/data/test-runner/MatrixMarks.tsx
8
7
  function MatrixMark({ mark, label, className, static: isStatic = false }) {
@@ -49,6 +48,23 @@ function MatrixElapsed({ ms, running, clock = false }) {
49
48
  }), formatMatrixDuration(ms)]
50
49
  });
51
50
  }
51
+ /** One tick per item, filled with its outcome's bar colour. */
52
+ function MatrixHeatmap({ ticks, unit, static: isStatic = false }) {
53
+ return /* @__PURE__ */ jsx("span", {
54
+ role: "list",
55
+ ...ticks.length > 0 ? { tabIndex: 0 } : {},
56
+ className: "flex h-3 min-w-10 flex-1 items-stretch [contain:inline-size] gap-px overflow-x-auto [scrollbar-width:none] print:[print-color-adjust:exact] print:[-webkit-print-color-adjust:exact]",
57
+ "aria-label": `${ticks.length} ${unit}`,
58
+ "data-heatmap": unit,
59
+ children: ticks.map((tick, i) => /* @__PURE__ */ jsx("span", {
60
+ role: "listitem",
61
+ "aria-label": `${i + 1}. ${tick.label} · ${MATRIX_MARKS[tick.mark].label}`,
62
+ title: `${i + 1}. ${tick.label} · ${MATRIX_MARKS[tick.mark].label}`,
63
+ className: cn("min-w-[3px] max-w-4 flex-1 rounded-[1px]", matrixBarClass(tick.mark, isStatic)),
64
+ "data-tick-outcome": tick.mark
65
+ }, i))
66
+ });
67
+ }
52
68
  /**
53
69
  * A plan with no run in an environment: pending while queued, error when it
54
70
  * never started, hollow when not part of that run.
@@ -106,39 +122,34 @@ function EnvChip({ context, className }) {
106
122
  }), context]
107
123
  });
108
124
  }
109
- var HEADER_GRID = "grid min-w-48 grid-rows-[auto_auto_auto] gap-1.5";
110
- var HEADER_ROW = "flex h-5 min-w-0 items-center gap-2";
125
+ var HEADER_LINE = "flex h-6 w-full items-center gap-3 whitespace-nowrap";
126
+ var HEADER_GROUP = "flex shrink-0 items-center gap-2";
111
127
  /**
112
- * One environment's column head in three fixed rows: its chip, the plans'
113
- * progress with the elapsed time, and the plan verdict naming its units.
128
+ * One environment's column head on one line that never wraps: its chip, the
129
+ * plans' progress as a heatmap with the elapsed time, and the plan verdict
130
+ * naming its units.
114
131
  */
115
- function MatrixEnvHeader({ context, counts, durationMs, running, renderChip, aside, static: isStatic = false }) {
132
+ function MatrixEnvHeader({ context, counts, plans, durationMs, running, renderChip, aside, static: isStatic = false }) {
133
+ if (plans.length !== counts.total) throw new Error(`${context} header has ${plans.length} plan ticks but counts ${counts.total} plans`);
116
134
  const done = counts.passed + counts.warned + counts.failed + counts.error;
117
135
  const chip = /* @__PURE__ */ jsx(EnvChip, { context });
118
136
  return /* @__PURE__ */ jsxs("div", {
119
- className: HEADER_GRID,
137
+ className: HEADER_LINE,
120
138
  "data-env-header": context,
121
139
  children: [
122
140
  /* @__PURE__ */ jsxs("div", {
123
- className: HEADER_ROW,
141
+ className: HEADER_GROUP,
124
142
  children: [renderChip && !isStatic ? renderChip(chip) : chip, aside]
125
143
  }),
126
144
  /* @__PURE__ */ jsxs("div", {
127
- className: HEADER_ROW,
145
+ className: `${HEADER_GROUP} flex-1`,
128
146
  title: `${done} of ${counts.total} plans finished`,
129
147
  "data-env-progress": "",
130
148
  children: [
131
- /* @__PURE__ */ jsx("span", {
132
- className: "min-w-0 flex-1",
133
- children: /* @__PURE__ */ jsx(ProgressBar, {
134
- total: counts.total,
135
- height: "h-1.5",
136
- segments: MATRIX_PLAN_BAR.map((key) => ({
137
- count: counts[key],
138
- color: matrixBarClass(key, isStatic),
139
- label: `${MATRIX_MARKS[key].label} plans`
140
- }))
141
- })
149
+ /* @__PURE__ */ jsx(MatrixHeatmap, {
150
+ ticks: plans,
151
+ unit: "plans",
152
+ static: isStatic
142
153
  }),
143
154
  /* @__PURE__ */ jsxs("span", {
144
155
  className: "shrink-0 whitespace-nowrap text-[11px] tabular-nums text-foreground",
@@ -157,7 +168,7 @@ function MatrixEnvHeader({ context, counts, durationMs, running, renderChip, asi
157
168
  ]
158
169
  }),
159
170
  /* @__PURE__ */ jsx("div", {
160
- className: HEADER_ROW,
171
+ className: HEADER_GROUP,
161
172
  "data-env-verdict": "",
162
173
  children: /* @__PURE__ */ jsx(MatrixMix, {
163
174
  counts: {
@@ -176,30 +187,20 @@ function MatrixEnvHeader({ context, counts, durationMs, running, renderChip, asi
176
187
  ]
177
188
  });
178
189
  }
179
- /** An environment whose member run did not load, in the same three rows as MatrixEnvHeader. */
190
+ /** An environment whose member run did not load, on the same single line as MatrixEnvHeader. */
180
191
  function MatrixUnavailableEnvHeader({ context }) {
181
192
  return /* @__PURE__ */ jsxs("div", {
182
- className: HEADER_GRID,
193
+ className: HEADER_LINE,
183
194
  "data-env-header": context,
184
- children: [
185
- /* @__PURE__ */ jsx("div", {
186
- className: HEADER_ROW,
187
- children: /* @__PURE__ */ jsx(EnvChip, { context })
188
- }),
189
- /* @__PURE__ */ jsxs("div", {
190
- className: `${HEADER_ROW} text-[11px] font-medium ${MATRIX_MARKS.error.tone}`,
191
- children: [/* @__PURE__ */ jsx(MatrixMark, {
192
- mark: "error",
193
- label: ""
194
- }), "did not load"]
195
- }),
196
- /* @__PURE__ */ jsx("div", {
197
- className: HEADER_ROW,
198
- "aria-hidden": "true"
199
- })
200
- ]
195
+ children: [/* @__PURE__ */ jsx(EnvChip, { context }), /* @__PURE__ */ jsxs("div", {
196
+ className: `${HEADER_GROUP} text-[11px] font-medium ${MATRIX_MARKS.error.tone}`,
197
+ children: [/* @__PURE__ */ jsx(MatrixMark, {
198
+ mark: "error",
199
+ label: ""
200
+ }), "did not load"]
201
+ })]
201
202
  });
202
203
  }
203
- export { EmptyMatrixCell, EnvChip, MatrixElapsed, MatrixEnvHeader, MatrixLegend, MatrixMark, MatrixMix, MatrixUnavailableEnvHeader };
204
+ export { EmptyMatrixCell, EnvChip, MatrixElapsed, MatrixEnvHeader, MatrixHeatmap, MatrixLegend, MatrixMark, MatrixMix, MatrixUnavailableEnvHeader };
204
205
 
205
206
  //# sourceMappingURL=MatrixMarks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MatrixMarks.js","names":[],"sources":["../../../src/data/test-runner/MatrixMarks.tsx"],"sourcesContent":["// Renders the matrix-marks.ts vocabulary: one outcome's glyph, outcome mixes,\n// durations, empty cells, the legend, environment chips and the environment\n// column header. Props-only, so a live web matrix and a static print template\n// draw the same marks; `static` drops animation and links for print.\n\nimport type { ReactNode } from \"react\";\nimport { UiClock, UiServer } from \"../../icons\";\nimport { cn } from \"../../lib/utils\";\nimport { ProgressBar } from \"../ProgressBar\";\nimport {\n MATRIX_MARKS,\n MATRIX_ORDER,\n MATRIX_PLAN_BAR,\n formatMatrixDuration,\n matrixBarClass,\n type MatrixCounts,\n type MatrixEnvCounts,\n type MatrixMarkKey,\n type MatrixMarkToken,\n} from \"./matrix-marks\";\n\nexport type MatrixMarkProps = {\n mark: MatrixMarkKey;\n /** Hover title; \"\" leaves the glyph untitled where the surrounding element already names it. */\n label?: string;\n className?: string;\n /** Print: never spins. */\n static?: boolean;\n};\n\nexport function MatrixMark({ mark, label, className, static: isStatic = false }: MatrixMarkProps) {\n const token: MatrixMarkToken = MATRIX_MARKS[mark];\n const Glyph = token.icon;\n return (\n <Glyph\n {...(label === \"\" ? {} : { title: label ?? token.label })}\n className={cn(\"size-3.5 shrink-0\", token.tone, token.spin && !isStatic && \"animate-spin\", className)}\n data-mark={mark}\n />\n );\n}\n\nexport type MatrixMixProps = {\n counts: MatrixCounts;\n unit: \"steps\" | \"plans\";\n /** Outcomes drawn even at zero; every other zero count is dropped. */\n always?: readonly MatrixMarkKey[];\n static?: boolean;\n};\n\n/** Outcome counts as glyph + number, in matrix order. */\nexport function MatrixMix({ counts, unit, always = [], static: isStatic = false }: MatrixMixProps) {\n return (\n <span role=\"group\" aria-label={`${unit} by outcome`} className=\"flex shrink-0 items-center gap-2 text-xs tabular-nums\" data-mix={unit}>\n {MATRIX_ORDER.filter((key) => (counts[key] ?? 0) > 0 || always.includes(key)).map((key) => {\n const text = `${counts[key] ?? 0} ${MATRIX_MARKS[key].label} ${unit}`;\n return (\n <span key={key} role=\"img\" aria-label={text} title={text} className={cn(\"inline-flex items-center gap-0.5\", MATRIX_MARKS[key].tone)} data-mix-outcome={key}>\n <MatrixMark mark={key} label=\"\" static={isStatic} />\n {counts[key] ?? 0}\n </span>\n );\n })}\n </span>\n );\n}\n\nexport type MatrixElapsedProps = {\n ms: number;\n /** Still counting: drawn blue and titled \"elapsed so far\". */\n running: boolean;\n /** Prefix a clock glyph. */\n clock?: boolean;\n};\n\nexport function MatrixElapsed({ ms, running, clock = false }: MatrixElapsedProps) {\n return (\n <span\n className={cn(\"inline-flex shrink-0 items-center gap-1 whitespace-nowrap text-[11px] tabular-nums\", running ? \"text-blue-700 dark:text-blue-300\" : \"text-muted-foreground\")}\n title={running ? \"elapsed so far\" : \"total duration\"}\n data-duration=\"\"\n >\n {clock && <UiClock className=\"size-3\" aria-hidden=\"true\" />}\n {formatMatrixDuration(ms)}\n </span>\n );\n}\n\nexport type EmptyMatrixCellProps = {\n /** The cell outcome: \"queued\", \"absent\", or \"error\" with detail \"never started\". Anything else throws. */\n outcome: string;\n /** Why a cell has no run: \"never started\". */\n detail?: string;\n /** Hover title of the cell. */\n title: string;\n /** The glyph alone (sub-step rows), its meaning on hover. */\n bare?: boolean;\n};\n\n/**\n * A plan with no run in an environment: pending while queued, error when it\n * never started, hollow when not part of that run.\n */\nexport function EmptyMatrixCell({ outcome, detail, title, bare = false }: EmptyMatrixCellProps) {\n const neverStarted = detail === \"never started\";\n if (!neverStarted && outcome !== \"queued\" && outcome !== \"absent\") throw new Error(`unexpected empty matrix cell ${outcome}: ${title}`);\n const mark: MatrixMarkKey = neverStarted ? \"error\" : outcome === \"queued\" ? \"pending\" : \"absent\";\n const label = neverStarted ? \"never started\" : MATRIX_MARKS[mark].label;\n return (\n <span title={title} className=\"flex h-5 min-w-0 items-center gap-1.5 text-xs\" data-empty-cell={mark}>\n <MatrixMark mark={mark} label={label} />\n {!bare && <span className={MATRIX_MARKS[mark].tone}>{label}</span>}\n </span>\n );\n}\n\nexport type MatrixLegendProps = { static?: boolean };\n\nexport function MatrixLegend({ static: isStatic = false }: MatrixLegendProps) {\n return (\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground\" data-batch-legend=\"\">\n {MATRIX_ORDER.map((key) => {\n const token: MatrixMarkToken = MATRIX_MARKS[key];\n return (\n <span key={key} className=\"inline-flex items-center gap-1\" data-legend-mark={key}>\n <MatrixMark mark={key} label=\"\" static={isStatic} />\n {token.legend ?? token.label}\n </span>\n );\n })}\n <span className=\"inline-flex items-center gap-1\">\n <UiClock className=\"size-3\" aria-hidden=\"true\" />\n elapsed · total duration\n </span>\n </div>\n );\n}\n\nexport type EnvChipProps = { context: string; className?: string };\n\n/** A context name, always in the same chip, so an environment never reads as a plan or a status. */\nexport function EnvChip({ context, className }: EnvChipProps) {\n return (\n <span\n className={cn(\"inline-flex items-center gap-1 rounded border border-border bg-muted/50 px-1.5 py-0.5 font-mono text-[11px] text-foreground\", className)}\n data-env-chip={context}\n >\n <UiServer className=\"size-3 text-muted-foreground\" aria-hidden=\"true\" />\n {context}\n </span>\n );\n}\n\nconst HEADER_GRID = \"grid min-w-48 grid-rows-[auto_auto_auto] gap-1.5\";\nconst HEADER_ROW = \"flex h-5 min-w-0 items-center gap-2\";\n\nexport type MatrixEnvHeaderProps = {\n context: string;\n counts: MatrixEnvCounts;\n durationMs: number;\n /** The environment's run is still running: its elapsed time is still counting. */\n running: boolean;\n /** Wraps the chip, e.g. in the host router's link to the member run. Never called when static. */\n renderChip?: (chip: ReactNode) => ReactNode;\n /** Drawn beside the chip, e.g. how often the member was retried. */\n aside?: ReactNode;\n static?: boolean;\n};\n\n/**\n * One environment's column head in three fixed rows: its chip, the plans'\n * progress with the elapsed time, and the plan verdict naming its units.\n */\nexport function MatrixEnvHeader({ context, counts, durationMs, running, renderChip, aside, static: isStatic = false }: MatrixEnvHeaderProps) {\n const done = counts.passed + counts.warned + counts.failed + counts.error;\n const chip = <EnvChip context={context} />;\n return (\n <div className={HEADER_GRID} data-env-header={context}>\n <div className={HEADER_ROW}>\n {renderChip && !isStatic ? renderChip(chip) : chip}\n {aside}\n </div>\n <div className={HEADER_ROW} title={`${done} of ${counts.total} plans finished`} data-env-progress=\"\">\n <span className=\"min-w-0 flex-1\">\n <ProgressBar\n total={counts.total}\n height=\"h-1.5\"\n segments={MATRIX_PLAN_BAR.map((key) => ({ count: counts[key], color: matrixBarClass(key, isStatic), label: `${MATRIX_MARKS[key].label} plans` }))}\n />\n </span>\n <span className=\"shrink-0 whitespace-nowrap text-[11px] tabular-nums text-foreground\">\n {done}/{counts.total} plans\n </span>\n <MatrixElapsed ms={durationMs} running={running} clock />\n </div>\n <div className={HEADER_ROW} data-env-verdict=\"\">\n <MatrixMix\n counts={{ passed: counts.passed, warned: counts.warned, running: counts.running, pending: counts.queued, failed: counts.failed, error: counts.error }}\n unit=\"plans\"\n always={[\"failed\"]}\n static={isStatic}\n />\n </div>\n </div>\n );\n}\n\nexport type MatrixUnavailableEnvHeaderProps = { context: string };\n\n/** An environment whose member run did not load, in the same three rows as MatrixEnvHeader. */\nexport function MatrixUnavailableEnvHeader({ context }: MatrixUnavailableEnvHeaderProps) {\n return (\n <div className={HEADER_GRID} data-env-header={context}>\n <div className={HEADER_ROW}>\n <EnvChip context={context} />\n </div>\n <div className={`${HEADER_ROW} text-[11px] font-medium ${MATRIX_MARKS.error.tone}`}>\n <MatrixMark mark=\"error\" label=\"\" />\n did not load\n </div>\n <div className={HEADER_ROW} aria-hidden=\"true\" />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MatrixMarks.js","names":[],"sources":["../../../src/data/test-runner/MatrixMarks.tsx"],"sourcesContent":["// Renders the matrix-marks.ts vocabulary: one outcome's glyph, outcome mixes,\n// durations, empty cells, the legend, environment chips and the environment\n// column header. Props-only, so a live web matrix and a static print template\n// draw the same marks; `static` drops animation and links for print.\n\nimport type { ReactNode } from \"react\";\nimport { UiClock, UiServer } from \"../../icons\";\nimport { cn } from \"../../lib/utils\";\nimport {\n MATRIX_MARKS,\n MATRIX_ORDER,\n formatMatrixDuration,\n matrixBarClass,\n type MatrixCounts,\n type MatrixEnvCounts,\n type MatrixMarkKey,\n type MatrixMarkToken,\n} from \"./matrix-marks\";\n\nexport type MatrixMarkProps = {\n mark: MatrixMarkKey;\n /** Hover title; \"\" leaves the glyph untitled where the surrounding element already names it. */\n label?: string;\n className?: string;\n /** Print: never spins. */\n static?: boolean;\n};\n\nexport function MatrixMark({ mark, label, className, static: isStatic = false }: MatrixMarkProps) {\n const token: MatrixMarkToken = MATRIX_MARKS[mark];\n const Glyph = token.icon;\n return (\n <Glyph\n {...(label === \"\" ? {} : { title: label ?? token.label })}\n className={cn(\"size-3.5 shrink-0\", token.tone, token.spin && !isStatic && \"animate-spin\", className)}\n data-mark={mark}\n />\n );\n}\n\nexport type MatrixMixProps = {\n counts: MatrixCounts;\n unit: \"steps\" | \"plans\";\n /** Outcomes drawn even at zero; every other zero count is dropped. */\n always?: readonly MatrixMarkKey[];\n static?: boolean;\n};\n\n/** Outcome counts as glyph + number, in matrix order. */\nexport function MatrixMix({ counts, unit, always = [], static: isStatic = false }: MatrixMixProps) {\n return (\n <span role=\"group\" aria-label={`${unit} by outcome`} className=\"flex shrink-0 items-center gap-2 text-xs tabular-nums\" data-mix={unit}>\n {MATRIX_ORDER.filter((key) => (counts[key] ?? 0) > 0 || always.includes(key)).map((key) => {\n const text = `${counts[key] ?? 0} ${MATRIX_MARKS[key].label} ${unit}`;\n return (\n <span key={key} role=\"img\" aria-label={text} title={text} className={cn(\"inline-flex items-center gap-0.5\", MATRIX_MARKS[key].tone)} data-mix-outcome={key}>\n <MatrixMark mark={key} label=\"\" static={isStatic} />\n {counts[key] ?? 0}\n </span>\n );\n })}\n </span>\n );\n}\n\nexport type MatrixElapsedProps = {\n ms: number;\n /** Still counting: drawn blue and titled \"elapsed so far\". */\n running: boolean;\n /** Prefix a clock glyph. */\n clock?: boolean;\n};\n\nexport function MatrixElapsed({ ms, running, clock = false }: MatrixElapsedProps) {\n return (\n <span\n className={cn(\"inline-flex shrink-0 items-center gap-1 whitespace-nowrap text-[11px] tabular-nums\", running ? \"text-blue-700 dark:text-blue-300\" : \"text-muted-foreground\")}\n title={running ? \"elapsed so far\" : \"total duration\"}\n data-duration=\"\"\n >\n {clock && <UiClock className=\"size-3\" aria-hidden=\"true\" />}\n {formatMatrixDuration(ms)}\n </span>\n );\n}\n\n/** One heatmap tick: an item (a plan, a step) and its outcome. */\nexport type MatrixTick = { label: string; mark: MatrixMarkKey };\n\nexport type MatrixHeatmapProps = {\n /** In run order: where a run is and where it broke read left to right. */\n ticks: readonly MatrixTick[];\n unit: \"steps\" | \"plans\";\n static?: boolean;\n};\n\n/** One tick per item, filled with its outcome's bar colour. */\nexport function MatrixHeatmap({ ticks, unit, static: isStatic = false }: MatrixHeatmapProps) {\n return (\n <span role=\"list\" {...(ticks.length > 0 ? { tabIndex: 0 } : {})} className=\"flex h-3 min-w-10 flex-1 items-stretch [contain:inline-size] gap-px overflow-x-auto [scrollbar-width:none] print:[print-color-adjust:exact] print:[-webkit-print-color-adjust:exact]\" aria-label={`${ticks.length} ${unit}`} data-heatmap={unit}>\n {ticks.map((tick, i) => (\n <span\n key={i}\n role=\"listitem\"\n aria-label={`${i + 1}. ${tick.label} · ${MATRIX_MARKS[tick.mark].label}`}\n title={`${i + 1}. ${tick.label} · ${MATRIX_MARKS[tick.mark].label}`}\n className={cn(\"min-w-[3px] max-w-4 flex-1 rounded-[1px]\", matrixBarClass(tick.mark, isStatic))}\n data-tick-outcome={tick.mark}\n />\n ))}\n </span>\n );\n}\n\nexport type EmptyMatrixCellProps = {\n /** The cell outcome: \"queued\", \"absent\", or \"error\" with detail \"never started\". Anything else throws. */\n outcome: string;\n /** Why a cell has no run: \"never started\". */\n detail?: string;\n /** Hover title of the cell. */\n title: string;\n /** The glyph alone (sub-step rows), its meaning on hover. */\n bare?: boolean;\n};\n\n/**\n * A plan with no run in an environment: pending while queued, error when it\n * never started, hollow when not part of that run.\n */\nexport function EmptyMatrixCell({ outcome, detail, title, bare = false }: EmptyMatrixCellProps) {\n const neverStarted = detail === \"never started\";\n if (!neverStarted && outcome !== \"queued\" && outcome !== \"absent\") throw new Error(`unexpected empty matrix cell ${outcome}: ${title}`);\n const mark: MatrixMarkKey = neverStarted ? \"error\" : outcome === \"queued\" ? \"pending\" : \"absent\";\n const label = neverStarted ? \"never started\" : MATRIX_MARKS[mark].label;\n return (\n <span title={title} className=\"flex h-5 min-w-0 items-center gap-1.5 text-xs\" data-empty-cell={mark}>\n <MatrixMark mark={mark} label={label} />\n {!bare && <span className={MATRIX_MARKS[mark].tone}>{label}</span>}\n </span>\n );\n}\n\nexport type MatrixLegendProps = { static?: boolean };\n\nexport function MatrixLegend({ static: isStatic = false }: MatrixLegendProps) {\n return (\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground\" data-batch-legend=\"\">\n {MATRIX_ORDER.map((key) => {\n const token: MatrixMarkToken = MATRIX_MARKS[key];\n return (\n <span key={key} className=\"inline-flex items-center gap-1\" data-legend-mark={key}>\n <MatrixMark mark={key} label=\"\" static={isStatic} />\n {token.legend ?? token.label}\n </span>\n );\n })}\n <span className=\"inline-flex items-center gap-1\">\n <UiClock className=\"size-3\" aria-hidden=\"true\" />\n elapsed · total duration\n </span>\n </div>\n );\n}\n\nexport type EnvChipProps = { context: string; className?: string };\n\n/** A context name, always in the same chip, so an environment never reads as a plan or a status. */\nexport function EnvChip({ context, className }: EnvChipProps) {\n return (\n <span\n className={cn(\"inline-flex items-center gap-1 rounded border border-border bg-muted/50 px-1.5 py-0.5 font-mono text-[11px] text-foreground\", className)}\n data-env-chip={context}\n >\n <UiServer className=\"size-3 text-muted-foreground\" aria-hidden=\"true\" />\n {context}\n </span>\n );\n}\n\nconst HEADER_LINE = \"flex h-6 w-full items-center gap-3 whitespace-nowrap\";\nconst HEADER_GROUP = \"flex shrink-0 items-center gap-2\";\n\nexport type MatrixEnvHeaderProps = {\n context: string;\n counts: MatrixEnvCounts;\n /** Every plan the counts total, in row order, drawn as the progress heatmap. */\n plans: readonly MatrixTick[];\n durationMs: number;\n /** The environment's run is still running: its elapsed time is still counting. */\n running: boolean;\n /** Wraps the chip, e.g. in the host router's link to the member run. Never called when static. */\n renderChip?: (chip: ReactNode) => ReactNode;\n /** Drawn beside the chip, e.g. how often the member was retried. */\n aside?: ReactNode;\n static?: boolean;\n};\n\n/**\n * One environment's column head on one line that never wraps: its chip, the\n * plans' progress as a heatmap with the elapsed time, and the plan verdict\n * naming its units.\n */\nexport function MatrixEnvHeader({ context, counts, plans, durationMs, running, renderChip, aside, static: isStatic = false }: MatrixEnvHeaderProps) {\n if (plans.length !== counts.total) throw new Error(`${context} header has ${plans.length} plan ticks but counts ${counts.total} plans`);\n const done = counts.passed + counts.warned + counts.failed + counts.error;\n const chip = <EnvChip context={context} />;\n return (\n <div className={HEADER_LINE} data-env-header={context}>\n <div className={HEADER_GROUP}>\n {renderChip && !isStatic ? renderChip(chip) : chip}\n {aside}\n </div>\n <div className={`${HEADER_GROUP} flex-1`} title={`${done} of ${counts.total} plans finished`} data-env-progress=\"\">\n <MatrixHeatmap ticks={plans} unit=\"plans\" static={isStatic} />\n <span className=\"shrink-0 whitespace-nowrap text-[11px] tabular-nums text-foreground\">\n {done}/{counts.total} plans\n </span>\n <MatrixElapsed ms={durationMs} running={running} clock />\n </div>\n <div className={HEADER_GROUP} data-env-verdict=\"\">\n <MatrixMix\n counts={{ passed: counts.passed, warned: counts.warned, running: counts.running, pending: counts.queued, failed: counts.failed, error: counts.error }}\n unit=\"plans\"\n always={[\"failed\"]}\n static={isStatic}\n />\n </div>\n </div>\n );\n}\n\nexport type MatrixUnavailableEnvHeaderProps = { context: string };\n\n/** An environment whose member run did not load, on the same single line as MatrixEnvHeader. */\nexport function MatrixUnavailableEnvHeader({ context }: MatrixUnavailableEnvHeaderProps) {\n return (\n <div className={HEADER_LINE} data-env-header={context}>\n <EnvChip context={context} />\n <div className={`${HEADER_GROUP} text-[11px] font-medium ${MATRIX_MARKS.error.tone}`}>\n <MatrixMark mark=\"error\" label=\"\" />\n did not load\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  const require_format = require("../../lib/format.cjs");
2
+ const require_MetricTile = require("../diagnostics/MetricTile.cjs");
2
3
  const require_status = require("./status.cjs");
3
4
  const require_attempts = require("./attempts.cjs");
4
5
  const require_StackDumpView = require("../diagnostics/StackDumpView.cjs");
5
- const require_MetricTile = require("../diagnostics/MetricTile.cjs");
6
6
  const require_metric_tone = require("../diagnostics/metric-tone.cjs");
7
7
  const require_process_metrics = require("./process-metrics.cjs");
8
8
  let react = require("react");
@@ -1,8 +1,8 @@
1
1
  import { formatBytes } from "../../lib/format.js";
2
+ import { MetricTile } from "../diagnostics/MetricTile.js";
2
3
  import { formatTestDuration } from "./status.js";
3
4
  import { isAttemptLive } from "./attempts.js";
4
5
  import { StackDumpView } from "../diagnostics/StackDumpView.js";
5
- import { MetricTile } from "../diagnostics/MetricTile.js";
6
6
  import { cpuTone } from "../diagnostics/metric-tone.js";
7
7
  import { ProcessNotFoundError } from "./process-metrics.js";
8
8
  import { useEffect, useRef, useState } from "react";
@@ -15,11 +15,13 @@ const require_SplitButton = require("../../components/SplitButton.cjs");
15
15
  const require_JsonView = require("../JsonView.cjs");
16
16
  const require_select = require("../../components/select.cjs");
17
17
  const require_TabButton = require("../TabButton.cjs");
18
+ const require_OpenInFilesLink = require("../OpenInFilesLink.cjs");
18
19
  const require_status = require("./status.cjs");
19
20
  const require_copy = require("./copy.cjs");
20
21
  const require_context = require("./context.cjs");
21
22
  const require_marks = require("./marks.cjs");
22
23
  const require_MarkIcons = require("./MarkIcons.cjs");
24
+ const require_paths = require("../lint/paths.cjs");
23
25
  const require_detailTabContext = require("./detailTabContext.cjs");
24
26
  const require_TestFailureDetail = require("./TestFailureDetail.cjs");
25
27
  const require_TestAttemptDetail = require("./TestAttemptDetail.cjs");
@@ -157,6 +159,15 @@ function DetailHeader({ node, actionNode, actions, attemptChooser }) {
157
159
  title: location,
158
160
  children: location
159
161
  }),
162
+ node.file && runner.onOpenFile && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_OpenInFilesLink.OpenInFilesLink, {
163
+ className: "shrink-0",
164
+ onOpenFile: runner.onOpenFile,
165
+ target: {
166
+ file: require_paths.relPath(node.file, node.work_dir),
167
+ ...node.work_dir ? { workDir: node.work_dir } : {},
168
+ ...node.line ? { line: node.line } : {}
169
+ }
170
+ }),
160
171
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
161
172
  className: "ml-auto flex shrink-0 items-center gap-1",
162
173
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"TestDetailPanel.cjs","names":["useTestRunner","sum","TestFailureDetail","TestOutput","TestAttemptDetail","JsonView","UiCopy","UiHourglass","UiCheck","UiWarningCircle","useCopyFlash","useMemo","UiJson","buildNodeJson","SplitButton","buildNodeBrief","outcomeFor","OutcomeIcon","Icon","UiClass","ToolIcon","toolKeyFor","UiClock","formatTestDuration","Button","UiRefresh","UiStop","useState","Select","DetailTabSelectProvider","cn","TabButton"],"sources":["../../../src/data/test-runner/TestDetailPanel.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport { Icon } from \"../Icon\";\nimport { Button } from \"../../components/button\";\nimport { Select } from \"../../components/select\";\nimport { SplitButton } from \"../../components/SplitButton\";\nimport { useCopyFlash, type CopyFlashState } from \"../../components/clipboard\";\nimport type { DropdownMenuItem } from \"../../overlay/DropdownMenu\";\nimport { cn } from \"../../lib/utils\";\nimport { JsonView } from \"../JsonView\";\nimport { TabButton } from \"../TabButton\";\nimport {\n UiCheck,\n UiClass,\n UiClock,\n UiCopy,\n UiHourglass,\n UiJson,\n UiRefresh,\n UiStop,\n UiWarningCircle,\n} from \"../../icons\";\nimport type { Test } from \"./types\";\nimport { useTestRunner } from \"./context\";\nimport { DetailTabSelectProvider } from \"./detailTabContext\";\nimport { buildNodeBrief, buildNodeJson, type CopyItem } from \"./copy\";\nimport { formatTestDuration, outcomeFor, sum } from \"./status\";\nimport { toolKeyFor } from \"./marks\";\nimport { OutcomeIcon, ToolIcon } from \"./MarkIcons\";\nimport { TestFailureDetail, TestOutput } from \"./TestFailureDetail\";\nimport { TestAttemptDetail } from \"./TestAttemptDetail\";\n\n/** Built-in detail body — used when no adapter contributes `renderDetail`. */\nfunction DefaultDetailBody({ node }: { node: Test }) {\n const runner = useTestRunner();\n const attempt = node.attempts?.at(-1);\n const hasChildren = (node.children?.length ?? 0) > 0;\n const counts = hasChildren ? sum(node) : null;\n return (\n <div className=\"space-y-4 p-density-4\">\n {node.message && !node.failure_detail && (\n <p className=\"whitespace-pre-wrap break-words text-sm\">{node.message}</p>\n )}\n {node.failure_detail && <TestFailureDetail failure={node.failure_detail} />}\n <TestOutput node={node} />\n {attempt && (\n <TestAttemptDetail\n key={`${attempt.run_kind ?? \"\"}:${attempt.sequence}`}\n attempt={attempt}\n {...(runner.fetchProcessMetrics ? { fetchProcessMetrics: runner.fetchProcessMetrics } : {})}\n />\n )}\n {counts && counts.total > 0 && (\n <div className=\"flex flex-wrap gap-3 text-xs text-muted-foreground\">\n <span>{counts.total} total</span>\n {counts.passed > 0 && <span>{counts.passed} passed</span>}\n {counts.failed > 0 && <span>{counts.failed} failed</span>}\n {counts.skipped > 0 && <span>{counts.skipped} skipped</span>}\n </div>\n )}\n {node.detail != null && (\n <div className=\"space-y-1\">\n <div className=\"text-[10px] uppercase tracking-wide text-muted-foreground\">Detail</div>\n <JsonView data={node.detail} />\n </div>\n )}\n </div>\n );\n}\n\nfunction copyMenuItem(item: CopyItem, copy: (text: string) => void): DropdownMenuItem {\n const icon = item.icon ? { icon: item.icon } : {};\n if (\"reason\" in item) {\n return { label: item.label, ...icon, disabled: true, title: item.reason, onSelect: () => {} };\n }\n return { label: item.label, ...icon, onSelect: () => copy(item.value) };\n}\n\nconst COPY_LABEL = {\n idle: \"Copy details\",\n pending: \"Copying…\",\n copied: \"Copied\",\n error: \"Copy failed\",\n} as const satisfies Record<CopyFlashState, string>;\nconst COPY_ICON = {\n idle: UiCopy,\n pending: UiHourglass,\n copied: UiCheck,\n error: UiWarningCircle,\n} as const satisfies Record<CopyFlashState, unknown>;\n\n/**\n * \"Copy details\" split button: the primary action copies a Markdown brief of\n * the generic sections plus every matching adapter's `copy` sections; the menu\n * offers the node as JSON and the adapters' items, disabled with a reason when\n * they have nothing to copy. The label flips to \"Copied\" or \"Copy failed\".\n */\nfunction CopyDetailsButton({ node }: { node: Test }) {\n const runner = useTestRunner();\n const { state, copy } = useCopyFlash();\n const sections = useMemo(() => runner.adapters.resolveCopy(node, runner), [node, runner]);\n const items: DropdownMenuItem[] = [\n { label: \"Copy as JSON\", icon: UiJson, onSelect: () => copy(buildNodeJson(node)) },\n ...sections.items.map((item) => copyMenuItem(item, copy)),\n ];\n return (\n <SplitButton\n label={COPY_LABEL[state]}\n icon={COPY_ICON[state]}\n variant=\"outline\"\n size=\"sm\"\n align=\"right\"\n title=\"More copy options\"\n onClick={() => copy(buildNodeBrief(node, sections))}\n items={items}\n />\n );\n}\n\nfunction DetailHeader({ node, actionNode, actions, attemptChooser }: { node: Test; actionNode: Test; actions?: ReactNode; attemptChooser?: ReactNode }) {\n const runner = useTestRunner();\n const outcome = outcomeFor(node);\n const canRerun = !!runner.onRerun && actionNode.framework !== \"task\";\n const canStop = !!runner.onStop && !!actionNode.can_stop && !!actionNode.task_id;\n const location = node.file ? `${node.file}${node.line ? `:${node.line}` : \"\"}` : undefined;\n return (\n <div\n className=\"flex min-w-0 items-center gap-2 border-b border-border px-density-4 py-density-2\"\n data-detail-header=\"\"\n >\n {outcome ? (\n <OutcomeIcon outcome={outcome} className=\"text-lg\" />\n ) : (\n <Icon icon={UiClass} className=\"shrink-0 text-lg text-muted-foreground\" />\n )}\n <h2 className=\"min-w-0 shrink truncate text-base font-semibold\" title={node.name}>\n {node.name}\n </h2>\n {node.framework && (\n <span className=\"inline-flex shrink-0 items-center gap-1 rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground\">\n <ToolIcon tool={toolKeyFor(node)} className=\"text-sm\" />\n {node.framework}\n </span>\n )}\n {node.duration ? (\n <span className=\"inline-flex shrink-0 items-center gap-1 text-xs text-muted-foreground\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {formatTestDuration(node.duration)}\n </span>\n ) : null}\n {location && (\n <span\n className=\"min-w-0 shrink-[100] truncate font-mono text-xs text-muted-foreground\"\n title={location}\n >\n {location}\n </span>\n )}\n <div className=\"ml-auto flex shrink-0 items-center gap-1\">\n {attemptChooser}\n {actions}\n <CopyDetailsButton node={node} />\n {canRerun && (\n <Button\n size=\"sm\"\n disabled={runner.busy.rerun}\n onClick={() => runner.onRerun!(actionNode)}\n title=\"Rerun this test or subtree\"\n >\n <Icon icon={UiRefresh} className=\"mr-1 text-sm\" />\n {runner.busy.rerun ? \"Running...\" : \"Rerun\"}\n </Button>\n )}\n {canStop && (\n <Button\n size=\"sm\"\n variant=\"destructive\"\n disabled={runner.busy.stop}\n onClick={() => runner.onStop!(actionNode)}\n title=\"Stop this running task\"\n >\n <Icon icon={UiStop} className=\"mr-1 text-sm\" />\n {runner.busy.stop ? \"Stopping...\" : \"Stop\"}\n </Button>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * The right pane. Resolves the node's adapter for body / tabs / header actions,\n * falling back to the built-in default body. Shows an empty state when nothing\n * is selected.\n */\nexport function TestDetailPanel() {\n const runner = useTestRunner();\n const selected = runner.selected;\n const [attemptSelection, setAttemptSelection] = useState<{ key: string; id: number } | null>(null);\n // Tab state is controlled when the host supplies activeTab (e.g. to mirror it\n // into the URL); otherwise the panel owns it. The render below tolerates an\n // unknown id by falling back to the built-in \"detail\" tab.\n const controlled = runner.activeTab !== undefined;\n const [internalTab, setInternalTab] = useState<string>(\"detail\");\n const activeTab = controlled ? runner.activeTab! : internalTab;\n const setActiveTab = (id: string) => {\n if (controlled) runner.onTabChange?.(id);\n else setInternalTab(id);\n };\n\n if (!selected) {\n return (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n <div className=\"text-center\">\n <Icon icon={UiClass} className=\"mb-2 block text-4xl\" />\n Select a test to view its details.\n </div>\n </div>\n );\n }\n\n const attempts = runner.adapters.resolveAttempts(selected, runner);\n const key = selected.task_id ?? selected.name;\n const attemptId = runner.activeAttempt ?? (attemptSelection?.key === key ? attemptSelection.id : undefined);\n const attempt = attempts.find((a) => a.id === attemptId) ?? attempts.at(-1);\n const node = attempts.length > 1 && attempt ? attempt.node : selected;\n const attemptChooser = attempts.length > 1 && attempt ? (\n <div className=\"w-44 shrink-0\">\n <Select aria-label=\"Attempt\" value={String(attempt.id)} className=\"h-7 text-xs\" onChange={(event) => {\n const id = Number(event.target.value);\n if (runner.onAttemptChange) runner.onAttemptChange(id);\n else setAttemptSelection({ key, id });\n }} options={attempts.map((a) => ({ value: String(a.id), label: `Attempt ${a.id}/${attempts.length} · ${a.status}${a.durationMs !== undefined ? ` · ${formatTestDuration(a.durationMs * 1e6)}` : \"\"}` }))} />\n </div>\n ) : null;\n\n const detailAdapter = runner.adapters.resolveDetail(node, runner);\n const actionAdapter = runner.adapters.resolveActions(selected, runner);\n const tabs = runner.adapters.resolveTabs(node, runner);\n const ownsScroll = runner.adapters.ownsScroll(node, runner);\n\n const body = (\n <DetailTabSelectProvider value={setActiveTab}>\n {detailAdapter?.renderDetail\n ? detailAdapter.renderDetail({ node, runner })\n : <DefaultDetailBody node={node} />}\n </DetailTabSelectProvider>\n );\n const actions = actionAdapter?.nodeActions?.({ node: selected, runner });\n\n // A size container, so log blocks can cap themselves at a share of the pane (cqh).\n const detailRegion = cn(\"min-h-0 flex-1 [container-type:size]\", !ownsScroll && \"overflow-y-auto\");\n\n // No extra tabs → just the body under the header.\n if (tabs.length === 0) {\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <DetailHeader node={node} actionNode={selected} actions={actions} attemptChooser={attemptChooser} />\n <div className={detailRegion}>{body}</div>\n </div>\n );\n }\n\n const detailTab = { id: \"detail\", label: \"Detail\", render: () => body };\n const allTabs = [detailTab, ...tabs];\n const active = allTabs.find((t) => t.id === activeTab) ?? detailTab;\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <DetailHeader node={node} actionNode={selected} actions={actions} attemptChooser={attemptChooser} />\n <div className=\"flex shrink-0 items-center gap-1 border-b border-border px-density-2 py-density-1\">\n {allTabs.map((t) => (\n <TabButton\n key={t.id}\n active={active.id === t.id}\n onClick={() => setActiveTab(t.id)}\n label={t.label}\n />\n ))}\n </div>\n <div className={detailRegion}>{active.render()}</div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TestDetailPanel.cjs","names":["useTestRunner","sum","TestFailureDetail","TestOutput","TestAttemptDetail","JsonView","UiCopy","UiHourglass","UiCheck","UiWarningCircle","useCopyFlash","useMemo","UiJson","buildNodeJson","SplitButton","buildNodeBrief","outcomeFor","OutcomeIcon","Icon","UiClass","ToolIcon","toolKeyFor","UiClock","formatTestDuration","OpenInFilesLink","relPath","Button","UiRefresh","UiStop","useState","Select","DetailTabSelectProvider","cn","TabButton"],"sources":["../../../src/data/test-runner/TestDetailPanel.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport { Icon } from \"../Icon\";\nimport { Button } from \"../../components/button\";\nimport { Select } from \"../../components/select\";\nimport { SplitButton } from \"../../components/SplitButton\";\nimport { useCopyFlash, type CopyFlashState } from \"../../components/clipboard\";\nimport type { DropdownMenuItem } from \"../../overlay/DropdownMenu\";\nimport { cn } from \"../../lib/utils\";\nimport { JsonView } from \"../JsonView\";\nimport { TabButton } from \"../TabButton\";\nimport { OpenInFilesLink } from \"../OpenInFilesLink\";\nimport { relPath } from \"../lint/paths\";\nimport {\n UiCheck,\n UiClass,\n UiClock,\n UiCopy,\n UiHourglass,\n UiJson,\n UiRefresh,\n UiStop,\n UiWarningCircle,\n} from \"../../icons\";\nimport type { Test } from \"./types\";\nimport { useTestRunner } from \"./context\";\nimport { DetailTabSelectProvider } from \"./detailTabContext\";\nimport { buildNodeBrief, buildNodeJson, type CopyItem } from \"./copy\";\nimport { formatTestDuration, outcomeFor, sum } from \"./status\";\nimport { toolKeyFor } from \"./marks\";\nimport { OutcomeIcon, ToolIcon } from \"./MarkIcons\";\nimport { TestFailureDetail, TestOutput } from \"./TestFailureDetail\";\nimport { TestAttemptDetail } from \"./TestAttemptDetail\";\n\n/** Built-in detail body — used when no adapter contributes `renderDetail`. */\nfunction DefaultDetailBody({ node }: { node: Test }) {\n const runner = useTestRunner();\n const attempt = node.attempts?.at(-1);\n const hasChildren = (node.children?.length ?? 0) > 0;\n const counts = hasChildren ? sum(node) : null;\n return (\n <div className=\"space-y-4 p-density-4\">\n {node.message && !node.failure_detail && (\n <p className=\"whitespace-pre-wrap break-words text-sm\">{node.message}</p>\n )}\n {node.failure_detail && <TestFailureDetail failure={node.failure_detail} />}\n <TestOutput node={node} />\n {attempt && (\n <TestAttemptDetail\n key={`${attempt.run_kind ?? \"\"}:${attempt.sequence}`}\n attempt={attempt}\n {...(runner.fetchProcessMetrics ? { fetchProcessMetrics: runner.fetchProcessMetrics } : {})}\n />\n )}\n {counts && counts.total > 0 && (\n <div className=\"flex flex-wrap gap-3 text-xs text-muted-foreground\">\n <span>{counts.total} total</span>\n {counts.passed > 0 && <span>{counts.passed} passed</span>}\n {counts.failed > 0 && <span>{counts.failed} failed</span>}\n {counts.skipped > 0 && <span>{counts.skipped} skipped</span>}\n </div>\n )}\n {node.detail != null && (\n <div className=\"space-y-1\">\n <div className=\"text-[10px] uppercase tracking-wide text-muted-foreground\">Detail</div>\n <JsonView data={node.detail} />\n </div>\n )}\n </div>\n );\n}\n\nfunction copyMenuItem(item: CopyItem, copy: (text: string) => void): DropdownMenuItem {\n const icon = item.icon ? { icon: item.icon } : {};\n if (\"reason\" in item) {\n return { label: item.label, ...icon, disabled: true, title: item.reason, onSelect: () => {} };\n }\n return { label: item.label, ...icon, onSelect: () => copy(item.value) };\n}\n\nconst COPY_LABEL = {\n idle: \"Copy details\",\n pending: \"Copying…\",\n copied: \"Copied\",\n error: \"Copy failed\",\n} as const satisfies Record<CopyFlashState, string>;\nconst COPY_ICON = {\n idle: UiCopy,\n pending: UiHourglass,\n copied: UiCheck,\n error: UiWarningCircle,\n} as const satisfies Record<CopyFlashState, unknown>;\n\n/**\n * \"Copy details\" split button: the primary action copies a Markdown brief of\n * the generic sections plus every matching adapter's `copy` sections; the menu\n * offers the node as JSON and the adapters' items, disabled with a reason when\n * they have nothing to copy. The label flips to \"Copied\" or \"Copy failed\".\n */\nfunction CopyDetailsButton({ node }: { node: Test }) {\n const runner = useTestRunner();\n const { state, copy } = useCopyFlash();\n const sections = useMemo(() => runner.adapters.resolveCopy(node, runner), [node, runner]);\n const items: DropdownMenuItem[] = [\n { label: \"Copy as JSON\", icon: UiJson, onSelect: () => copy(buildNodeJson(node)) },\n ...sections.items.map((item) => copyMenuItem(item, copy)),\n ];\n return (\n <SplitButton\n label={COPY_LABEL[state]}\n icon={COPY_ICON[state]}\n variant=\"outline\"\n size=\"sm\"\n align=\"right\"\n title=\"More copy options\"\n onClick={() => copy(buildNodeBrief(node, sections))}\n items={items}\n />\n );\n}\n\nfunction DetailHeader({ node, actionNode, actions, attemptChooser }: { node: Test; actionNode: Test; actions?: ReactNode; attemptChooser?: ReactNode }) {\n const runner = useTestRunner();\n const outcome = outcomeFor(node);\n const canRerun = !!runner.onRerun && actionNode.framework !== \"task\";\n const canStop = !!runner.onStop && !!actionNode.can_stop && !!actionNode.task_id;\n const location = node.file ? `${node.file}${node.line ? `:${node.line}` : \"\"}` : undefined;\n return (\n <div\n className=\"flex min-w-0 items-center gap-2 border-b border-border px-density-4 py-density-2\"\n data-detail-header=\"\"\n >\n {outcome ? (\n <OutcomeIcon outcome={outcome} className=\"text-lg\" />\n ) : (\n <Icon icon={UiClass} className=\"shrink-0 text-lg text-muted-foreground\" />\n )}\n <h2 className=\"min-w-0 shrink truncate text-base font-semibold\" title={node.name}>\n {node.name}\n </h2>\n {node.framework && (\n <span className=\"inline-flex shrink-0 items-center gap-1 rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground\">\n <ToolIcon tool={toolKeyFor(node)} className=\"text-sm\" />\n {node.framework}\n </span>\n )}\n {node.duration ? (\n <span className=\"inline-flex shrink-0 items-center gap-1 text-xs text-muted-foreground\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {formatTestDuration(node.duration)}\n </span>\n ) : null}\n {location && (\n <span\n className=\"min-w-0 shrink-[100] truncate font-mono text-xs text-muted-foreground\"\n title={location}\n >\n {location}\n </span>\n )}\n {node.file && runner.onOpenFile && (\n <OpenInFilesLink\n className=\"shrink-0\"\n onOpenFile={runner.onOpenFile}\n target={{\n file: relPath(node.file, node.work_dir)!,\n ...(node.work_dir ? { workDir: node.work_dir } : {}),\n ...(node.line ? { line: node.line } : {}),\n }}\n />\n )}\n <div className=\"ml-auto flex shrink-0 items-center gap-1\">\n {attemptChooser}\n {actions}\n <CopyDetailsButton node={node} />\n {canRerun && (\n <Button\n size=\"sm\"\n disabled={runner.busy.rerun}\n onClick={() => runner.onRerun!(actionNode)}\n title=\"Rerun this test or subtree\"\n >\n <Icon icon={UiRefresh} className=\"mr-1 text-sm\" />\n {runner.busy.rerun ? \"Running...\" : \"Rerun\"}\n </Button>\n )}\n {canStop && (\n <Button\n size=\"sm\"\n variant=\"destructive\"\n disabled={runner.busy.stop}\n onClick={() => runner.onStop!(actionNode)}\n title=\"Stop this running task\"\n >\n <Icon icon={UiStop} className=\"mr-1 text-sm\" />\n {runner.busy.stop ? \"Stopping...\" : \"Stop\"}\n </Button>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * The right pane. Resolves the node's adapter for body / tabs / header actions,\n * falling back to the built-in default body. Shows an empty state when nothing\n * is selected.\n */\nexport function TestDetailPanel() {\n const runner = useTestRunner();\n const selected = runner.selected;\n const [attemptSelection, setAttemptSelection] = useState<{ key: string; id: number } | null>(null);\n // Tab state is controlled when the host supplies activeTab (e.g. to mirror it\n // into the URL); otherwise the panel owns it. The render below tolerates an\n // unknown id by falling back to the built-in \"detail\" tab.\n const controlled = runner.activeTab !== undefined;\n const [internalTab, setInternalTab] = useState<string>(\"detail\");\n const activeTab = controlled ? runner.activeTab! : internalTab;\n const setActiveTab = (id: string) => {\n if (controlled) runner.onTabChange?.(id);\n else setInternalTab(id);\n };\n\n if (!selected) {\n return (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n <div className=\"text-center\">\n <Icon icon={UiClass} className=\"mb-2 block text-4xl\" />\n Select a test to view its details.\n </div>\n </div>\n );\n }\n\n const attempts = runner.adapters.resolveAttempts(selected, runner);\n const key = selected.task_id ?? selected.name;\n const attemptId = runner.activeAttempt ?? (attemptSelection?.key === key ? attemptSelection.id : undefined);\n const attempt = attempts.find((a) => a.id === attemptId) ?? attempts.at(-1);\n const node = attempts.length > 1 && attempt ? attempt.node : selected;\n const attemptChooser = attempts.length > 1 && attempt ? (\n <div className=\"w-44 shrink-0\">\n <Select aria-label=\"Attempt\" value={String(attempt.id)} className=\"h-7 text-xs\" onChange={(event) => {\n const id = Number(event.target.value);\n if (runner.onAttemptChange) runner.onAttemptChange(id);\n else setAttemptSelection({ key, id });\n }} options={attempts.map((a) => ({ value: String(a.id), label: `Attempt ${a.id}/${attempts.length} · ${a.status}${a.durationMs !== undefined ? ` · ${formatTestDuration(a.durationMs * 1e6)}` : \"\"}` }))} />\n </div>\n ) : null;\n\n const detailAdapter = runner.adapters.resolveDetail(node, runner);\n const actionAdapter = runner.adapters.resolveActions(selected, runner);\n const tabs = runner.adapters.resolveTabs(node, runner);\n const ownsScroll = runner.adapters.ownsScroll(node, runner);\n\n const body = (\n <DetailTabSelectProvider value={setActiveTab}>\n {detailAdapter?.renderDetail\n ? detailAdapter.renderDetail({ node, runner })\n : <DefaultDetailBody node={node} />}\n </DetailTabSelectProvider>\n );\n const actions = actionAdapter?.nodeActions?.({ node: selected, runner });\n\n // A size container, so log blocks can cap themselves at a share of the pane (cqh).\n const detailRegion = cn(\"min-h-0 flex-1 [container-type:size]\", !ownsScroll && \"overflow-y-auto\");\n\n // No extra tabs → just the body under the header.\n if (tabs.length === 0) {\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <DetailHeader node={node} actionNode={selected} actions={actions} attemptChooser={attemptChooser} />\n <div className={detailRegion}>{body}</div>\n </div>\n );\n }\n\n const detailTab = { id: \"detail\", label: \"Detail\", render: () => body };\n const allTabs = [detailTab, ...tabs];\n const active = allTabs.find((t) => t.id === activeTab) ?? detailTab;\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <DetailHeader node={node} actionNode={selected} actions={actions} attemptChooser={attemptChooser} />\n <div className=\"flex shrink-0 items-center gap-1 border-b border-border px-density-2 py-density-1\">\n {allTabs.map((t) => (\n <TabButton\n key={t.id}\n active={active.id === t.id}\n onClick={() => setActiveTab(t.id)}\n label={t.label}\n />\n ))}\n </div>\n <div className={detailRegion}>{active.render()}</div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TestDetailPanel.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestDetailPanel.tsx"],"names":[],"mappings":"AA6LA;;;;GAIG;AACH,wBAAgB,eAAe,gCAwF9B"}
1
+ {"version":3,"file":"TestDetailPanel.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestDetailPanel.tsx"],"names":[],"mappings":"AA0MA;;;;GAIG;AACH,wBAAgB,eAAe,gCAwF9B"}
@@ -15,11 +15,13 @@ import { SplitButton } from "../../components/SplitButton.js";
15
15
  import { JsonView } from "../JsonView.js";
16
16
  import { Select } from "../../components/select.js";
17
17
  import { TabButton } from "../TabButton.js";
18
+ import { OpenInFilesLink } from "../OpenInFilesLink.js";
18
19
  import { formatTestDuration, outcomeFor, sum } from "./status.js";
19
20
  import { buildNodeBrief, buildNodeJson } from "./copy.js";
20
21
  import { useTestRunner } from "./context.js";
21
22
  import { toolKeyFor } from "./marks.js";
22
23
  import { OutcomeIcon, ToolIcon } from "./MarkIcons.js";
24
+ import { relPath } from "../lint/paths.js";
23
25
  import { DetailTabSelectProvider } from "./detailTabContext.js";
24
26
  import { TestFailureDetail, TestOutput } from "./TestFailureDetail.js";
25
27
  import { TestAttemptDetail } from "./TestAttemptDetail.js";
@@ -157,6 +159,15 @@ function DetailHeader({ node, actionNode, actions, attemptChooser }) {
157
159
  title: location,
158
160
  children: location
159
161
  }),
162
+ node.file && runner.onOpenFile && /* @__PURE__ */ jsx(OpenInFilesLink, {
163
+ className: "shrink-0",
164
+ onOpenFile: runner.onOpenFile,
165
+ target: {
166
+ file: relPath(node.file, node.work_dir),
167
+ ...node.work_dir ? { workDir: node.work_dir } : {},
168
+ ...node.line ? { line: node.line } : {}
169
+ }
170
+ }),
160
171
  /* @__PURE__ */ jsxs("div", {
161
172
  className: "ml-auto flex shrink-0 items-center gap-1",
162
173
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"TestDetailPanel.js","names":[],"sources":["../../../src/data/test-runner/TestDetailPanel.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport { Icon } from \"../Icon\";\nimport { Button } from \"../../components/button\";\nimport { Select } from \"../../components/select\";\nimport { SplitButton } from \"../../components/SplitButton\";\nimport { useCopyFlash, type CopyFlashState } from \"../../components/clipboard\";\nimport type { DropdownMenuItem } from \"../../overlay/DropdownMenu\";\nimport { cn } from \"../../lib/utils\";\nimport { JsonView } from \"../JsonView\";\nimport { TabButton } from \"../TabButton\";\nimport {\n UiCheck,\n UiClass,\n UiClock,\n UiCopy,\n UiHourglass,\n UiJson,\n UiRefresh,\n UiStop,\n UiWarningCircle,\n} from \"../../icons\";\nimport type { Test } from \"./types\";\nimport { useTestRunner } from \"./context\";\nimport { DetailTabSelectProvider } from \"./detailTabContext\";\nimport { buildNodeBrief, buildNodeJson, type CopyItem } from \"./copy\";\nimport { formatTestDuration, outcomeFor, sum } from \"./status\";\nimport { toolKeyFor } from \"./marks\";\nimport { OutcomeIcon, ToolIcon } from \"./MarkIcons\";\nimport { TestFailureDetail, TestOutput } from \"./TestFailureDetail\";\nimport { TestAttemptDetail } from \"./TestAttemptDetail\";\n\n/** Built-in detail body — used when no adapter contributes `renderDetail`. */\nfunction DefaultDetailBody({ node }: { node: Test }) {\n const runner = useTestRunner();\n const attempt = node.attempts?.at(-1);\n const hasChildren = (node.children?.length ?? 0) > 0;\n const counts = hasChildren ? sum(node) : null;\n return (\n <div className=\"space-y-4 p-density-4\">\n {node.message && !node.failure_detail && (\n <p className=\"whitespace-pre-wrap break-words text-sm\">{node.message}</p>\n )}\n {node.failure_detail && <TestFailureDetail failure={node.failure_detail} />}\n <TestOutput node={node} />\n {attempt && (\n <TestAttemptDetail\n key={`${attempt.run_kind ?? \"\"}:${attempt.sequence}`}\n attempt={attempt}\n {...(runner.fetchProcessMetrics ? { fetchProcessMetrics: runner.fetchProcessMetrics } : {})}\n />\n )}\n {counts && counts.total > 0 && (\n <div className=\"flex flex-wrap gap-3 text-xs text-muted-foreground\">\n <span>{counts.total} total</span>\n {counts.passed > 0 && <span>{counts.passed} passed</span>}\n {counts.failed > 0 && <span>{counts.failed} failed</span>}\n {counts.skipped > 0 && <span>{counts.skipped} skipped</span>}\n </div>\n )}\n {node.detail != null && (\n <div className=\"space-y-1\">\n <div className=\"text-[10px] uppercase tracking-wide text-muted-foreground\">Detail</div>\n <JsonView data={node.detail} />\n </div>\n )}\n </div>\n );\n}\n\nfunction copyMenuItem(item: CopyItem, copy: (text: string) => void): DropdownMenuItem {\n const icon = item.icon ? { icon: item.icon } : {};\n if (\"reason\" in item) {\n return { label: item.label, ...icon, disabled: true, title: item.reason, onSelect: () => {} };\n }\n return { label: item.label, ...icon, onSelect: () => copy(item.value) };\n}\n\nconst COPY_LABEL = {\n idle: \"Copy details\",\n pending: \"Copying…\",\n copied: \"Copied\",\n error: \"Copy failed\",\n} as const satisfies Record<CopyFlashState, string>;\nconst COPY_ICON = {\n idle: UiCopy,\n pending: UiHourglass,\n copied: UiCheck,\n error: UiWarningCircle,\n} as const satisfies Record<CopyFlashState, unknown>;\n\n/**\n * \"Copy details\" split button: the primary action copies a Markdown brief of\n * the generic sections plus every matching adapter's `copy` sections; the menu\n * offers the node as JSON and the adapters' items, disabled with a reason when\n * they have nothing to copy. The label flips to \"Copied\" or \"Copy failed\".\n */\nfunction CopyDetailsButton({ node }: { node: Test }) {\n const runner = useTestRunner();\n const { state, copy } = useCopyFlash();\n const sections = useMemo(() => runner.adapters.resolveCopy(node, runner), [node, runner]);\n const items: DropdownMenuItem[] = [\n { label: \"Copy as JSON\", icon: UiJson, onSelect: () => copy(buildNodeJson(node)) },\n ...sections.items.map((item) => copyMenuItem(item, copy)),\n ];\n return (\n <SplitButton\n label={COPY_LABEL[state]}\n icon={COPY_ICON[state]}\n variant=\"outline\"\n size=\"sm\"\n align=\"right\"\n title=\"More copy options\"\n onClick={() => copy(buildNodeBrief(node, sections))}\n items={items}\n />\n );\n}\n\nfunction DetailHeader({ node, actionNode, actions, attemptChooser }: { node: Test; actionNode: Test; actions?: ReactNode; attemptChooser?: ReactNode }) {\n const runner = useTestRunner();\n const outcome = outcomeFor(node);\n const canRerun = !!runner.onRerun && actionNode.framework !== \"task\";\n const canStop = !!runner.onStop && !!actionNode.can_stop && !!actionNode.task_id;\n const location = node.file ? `${node.file}${node.line ? `:${node.line}` : \"\"}` : undefined;\n return (\n <div\n className=\"flex min-w-0 items-center gap-2 border-b border-border px-density-4 py-density-2\"\n data-detail-header=\"\"\n >\n {outcome ? (\n <OutcomeIcon outcome={outcome} className=\"text-lg\" />\n ) : (\n <Icon icon={UiClass} className=\"shrink-0 text-lg text-muted-foreground\" />\n )}\n <h2 className=\"min-w-0 shrink truncate text-base font-semibold\" title={node.name}>\n {node.name}\n </h2>\n {node.framework && (\n <span className=\"inline-flex shrink-0 items-center gap-1 rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground\">\n <ToolIcon tool={toolKeyFor(node)} className=\"text-sm\" />\n {node.framework}\n </span>\n )}\n {node.duration ? (\n <span className=\"inline-flex shrink-0 items-center gap-1 text-xs text-muted-foreground\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {formatTestDuration(node.duration)}\n </span>\n ) : null}\n {location && (\n <span\n className=\"min-w-0 shrink-[100] truncate font-mono text-xs text-muted-foreground\"\n title={location}\n >\n {location}\n </span>\n )}\n <div className=\"ml-auto flex shrink-0 items-center gap-1\">\n {attemptChooser}\n {actions}\n <CopyDetailsButton node={node} />\n {canRerun && (\n <Button\n size=\"sm\"\n disabled={runner.busy.rerun}\n onClick={() => runner.onRerun!(actionNode)}\n title=\"Rerun this test or subtree\"\n >\n <Icon icon={UiRefresh} className=\"mr-1 text-sm\" />\n {runner.busy.rerun ? \"Running...\" : \"Rerun\"}\n </Button>\n )}\n {canStop && (\n <Button\n size=\"sm\"\n variant=\"destructive\"\n disabled={runner.busy.stop}\n onClick={() => runner.onStop!(actionNode)}\n title=\"Stop this running task\"\n >\n <Icon icon={UiStop} className=\"mr-1 text-sm\" />\n {runner.busy.stop ? \"Stopping...\" : \"Stop\"}\n </Button>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * The right pane. Resolves the node's adapter for body / tabs / header actions,\n * falling back to the built-in default body. Shows an empty state when nothing\n * is selected.\n */\nexport function TestDetailPanel() {\n const runner = useTestRunner();\n const selected = runner.selected;\n const [attemptSelection, setAttemptSelection] = useState<{ key: string; id: number } | null>(null);\n // Tab state is controlled when the host supplies activeTab (e.g. to mirror it\n // into the URL); otherwise the panel owns it. The render below tolerates an\n // unknown id by falling back to the built-in \"detail\" tab.\n const controlled = runner.activeTab !== undefined;\n const [internalTab, setInternalTab] = useState<string>(\"detail\");\n const activeTab = controlled ? runner.activeTab! : internalTab;\n const setActiveTab = (id: string) => {\n if (controlled) runner.onTabChange?.(id);\n else setInternalTab(id);\n };\n\n if (!selected) {\n return (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n <div className=\"text-center\">\n <Icon icon={UiClass} className=\"mb-2 block text-4xl\" />\n Select a test to view its details.\n </div>\n </div>\n );\n }\n\n const attempts = runner.adapters.resolveAttempts(selected, runner);\n const key = selected.task_id ?? selected.name;\n const attemptId = runner.activeAttempt ?? (attemptSelection?.key === key ? attemptSelection.id : undefined);\n const attempt = attempts.find((a) => a.id === attemptId) ?? attempts.at(-1);\n const node = attempts.length > 1 && attempt ? attempt.node : selected;\n const attemptChooser = attempts.length > 1 && attempt ? (\n <div className=\"w-44 shrink-0\">\n <Select aria-label=\"Attempt\" value={String(attempt.id)} className=\"h-7 text-xs\" onChange={(event) => {\n const id = Number(event.target.value);\n if (runner.onAttemptChange) runner.onAttemptChange(id);\n else setAttemptSelection({ key, id });\n }} options={attempts.map((a) => ({ value: String(a.id), label: `Attempt ${a.id}/${attempts.length} · ${a.status}${a.durationMs !== undefined ? ` · ${formatTestDuration(a.durationMs * 1e6)}` : \"\"}` }))} />\n </div>\n ) : null;\n\n const detailAdapter = runner.adapters.resolveDetail(node, runner);\n const actionAdapter = runner.adapters.resolveActions(selected, runner);\n const tabs = runner.adapters.resolveTabs(node, runner);\n const ownsScroll = runner.adapters.ownsScroll(node, runner);\n\n const body = (\n <DetailTabSelectProvider value={setActiveTab}>\n {detailAdapter?.renderDetail\n ? detailAdapter.renderDetail({ node, runner })\n : <DefaultDetailBody node={node} />}\n </DetailTabSelectProvider>\n );\n const actions = actionAdapter?.nodeActions?.({ node: selected, runner });\n\n // A size container, so log blocks can cap themselves at a share of the pane (cqh).\n const detailRegion = cn(\"min-h-0 flex-1 [container-type:size]\", !ownsScroll && \"overflow-y-auto\");\n\n // No extra tabs → just the body under the header.\n if (tabs.length === 0) {\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <DetailHeader node={node} actionNode={selected} actions={actions} attemptChooser={attemptChooser} />\n <div className={detailRegion}>{body}</div>\n </div>\n );\n }\n\n const detailTab = { id: \"detail\", label: \"Detail\", render: () => body };\n const allTabs = [detailTab, ...tabs];\n const active = allTabs.find((t) => t.id === activeTab) ?? detailTab;\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <DetailHeader node={node} actionNode={selected} actions={actions} attemptChooser={attemptChooser} />\n <div className=\"flex shrink-0 items-center gap-1 border-b border-border px-density-2 py-density-1\">\n {allTabs.map((t) => (\n <TabButton\n key={t.id}\n active={active.id === t.id}\n onClick={() => setActiveTab(t.id)}\n label={t.label}\n />\n ))}\n </div>\n <div className={detailRegion}>{active.render()}</div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TestDetailPanel.js","names":[],"sources":["../../../src/data/test-runner/TestDetailPanel.tsx"],"sourcesContent":["import { useMemo, useState, type ReactNode } from \"react\";\nimport { Icon } from \"../Icon\";\nimport { Button } from \"../../components/button\";\nimport { Select } from \"../../components/select\";\nimport { SplitButton } from \"../../components/SplitButton\";\nimport { useCopyFlash, type CopyFlashState } from \"../../components/clipboard\";\nimport type { DropdownMenuItem } from \"../../overlay/DropdownMenu\";\nimport { cn } from \"../../lib/utils\";\nimport { JsonView } from \"../JsonView\";\nimport { TabButton } from \"../TabButton\";\nimport { OpenInFilesLink } from \"../OpenInFilesLink\";\nimport { relPath } from \"../lint/paths\";\nimport {\n UiCheck,\n UiClass,\n UiClock,\n UiCopy,\n UiHourglass,\n UiJson,\n UiRefresh,\n UiStop,\n UiWarningCircle,\n} from \"../../icons\";\nimport type { Test } from \"./types\";\nimport { useTestRunner } from \"./context\";\nimport { DetailTabSelectProvider } from \"./detailTabContext\";\nimport { buildNodeBrief, buildNodeJson, type CopyItem } from \"./copy\";\nimport { formatTestDuration, outcomeFor, sum } from \"./status\";\nimport { toolKeyFor } from \"./marks\";\nimport { OutcomeIcon, ToolIcon } from \"./MarkIcons\";\nimport { TestFailureDetail, TestOutput } from \"./TestFailureDetail\";\nimport { TestAttemptDetail } from \"./TestAttemptDetail\";\n\n/** Built-in detail body — used when no adapter contributes `renderDetail`. */\nfunction DefaultDetailBody({ node }: { node: Test }) {\n const runner = useTestRunner();\n const attempt = node.attempts?.at(-1);\n const hasChildren = (node.children?.length ?? 0) > 0;\n const counts = hasChildren ? sum(node) : null;\n return (\n <div className=\"space-y-4 p-density-4\">\n {node.message && !node.failure_detail && (\n <p className=\"whitespace-pre-wrap break-words text-sm\">{node.message}</p>\n )}\n {node.failure_detail && <TestFailureDetail failure={node.failure_detail} />}\n <TestOutput node={node} />\n {attempt && (\n <TestAttemptDetail\n key={`${attempt.run_kind ?? \"\"}:${attempt.sequence}`}\n attempt={attempt}\n {...(runner.fetchProcessMetrics ? { fetchProcessMetrics: runner.fetchProcessMetrics } : {})}\n />\n )}\n {counts && counts.total > 0 && (\n <div className=\"flex flex-wrap gap-3 text-xs text-muted-foreground\">\n <span>{counts.total} total</span>\n {counts.passed > 0 && <span>{counts.passed} passed</span>}\n {counts.failed > 0 && <span>{counts.failed} failed</span>}\n {counts.skipped > 0 && <span>{counts.skipped} skipped</span>}\n </div>\n )}\n {node.detail != null && (\n <div className=\"space-y-1\">\n <div className=\"text-[10px] uppercase tracking-wide text-muted-foreground\">Detail</div>\n <JsonView data={node.detail} />\n </div>\n )}\n </div>\n );\n}\n\nfunction copyMenuItem(item: CopyItem, copy: (text: string) => void): DropdownMenuItem {\n const icon = item.icon ? { icon: item.icon } : {};\n if (\"reason\" in item) {\n return { label: item.label, ...icon, disabled: true, title: item.reason, onSelect: () => {} };\n }\n return { label: item.label, ...icon, onSelect: () => copy(item.value) };\n}\n\nconst COPY_LABEL = {\n idle: \"Copy details\",\n pending: \"Copying…\",\n copied: \"Copied\",\n error: \"Copy failed\",\n} as const satisfies Record<CopyFlashState, string>;\nconst COPY_ICON = {\n idle: UiCopy,\n pending: UiHourglass,\n copied: UiCheck,\n error: UiWarningCircle,\n} as const satisfies Record<CopyFlashState, unknown>;\n\n/**\n * \"Copy details\" split button: the primary action copies a Markdown brief of\n * the generic sections plus every matching adapter's `copy` sections; the menu\n * offers the node as JSON and the adapters' items, disabled with a reason when\n * they have nothing to copy. The label flips to \"Copied\" or \"Copy failed\".\n */\nfunction CopyDetailsButton({ node }: { node: Test }) {\n const runner = useTestRunner();\n const { state, copy } = useCopyFlash();\n const sections = useMemo(() => runner.adapters.resolveCopy(node, runner), [node, runner]);\n const items: DropdownMenuItem[] = [\n { label: \"Copy as JSON\", icon: UiJson, onSelect: () => copy(buildNodeJson(node)) },\n ...sections.items.map((item) => copyMenuItem(item, copy)),\n ];\n return (\n <SplitButton\n label={COPY_LABEL[state]}\n icon={COPY_ICON[state]}\n variant=\"outline\"\n size=\"sm\"\n align=\"right\"\n title=\"More copy options\"\n onClick={() => copy(buildNodeBrief(node, sections))}\n items={items}\n />\n );\n}\n\nfunction DetailHeader({ node, actionNode, actions, attemptChooser }: { node: Test; actionNode: Test; actions?: ReactNode; attemptChooser?: ReactNode }) {\n const runner = useTestRunner();\n const outcome = outcomeFor(node);\n const canRerun = !!runner.onRerun && actionNode.framework !== \"task\";\n const canStop = !!runner.onStop && !!actionNode.can_stop && !!actionNode.task_id;\n const location = node.file ? `${node.file}${node.line ? `:${node.line}` : \"\"}` : undefined;\n return (\n <div\n className=\"flex min-w-0 items-center gap-2 border-b border-border px-density-4 py-density-2\"\n data-detail-header=\"\"\n >\n {outcome ? (\n <OutcomeIcon outcome={outcome} className=\"text-lg\" />\n ) : (\n <Icon icon={UiClass} className=\"shrink-0 text-lg text-muted-foreground\" />\n )}\n <h2 className=\"min-w-0 shrink truncate text-base font-semibold\" title={node.name}>\n {node.name}\n </h2>\n {node.framework && (\n <span className=\"inline-flex shrink-0 items-center gap-1 rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground\">\n <ToolIcon tool={toolKeyFor(node)} className=\"text-sm\" />\n {node.framework}\n </span>\n )}\n {node.duration ? (\n <span className=\"inline-flex shrink-0 items-center gap-1 text-xs text-muted-foreground\">\n <Icon icon={UiClock} className=\"text-xs\" />\n {formatTestDuration(node.duration)}\n </span>\n ) : null}\n {location && (\n <span\n className=\"min-w-0 shrink-[100] truncate font-mono text-xs text-muted-foreground\"\n title={location}\n >\n {location}\n </span>\n )}\n {node.file && runner.onOpenFile && (\n <OpenInFilesLink\n className=\"shrink-0\"\n onOpenFile={runner.onOpenFile}\n target={{\n file: relPath(node.file, node.work_dir)!,\n ...(node.work_dir ? { workDir: node.work_dir } : {}),\n ...(node.line ? { line: node.line } : {}),\n }}\n />\n )}\n <div className=\"ml-auto flex shrink-0 items-center gap-1\">\n {attemptChooser}\n {actions}\n <CopyDetailsButton node={node} />\n {canRerun && (\n <Button\n size=\"sm\"\n disabled={runner.busy.rerun}\n onClick={() => runner.onRerun!(actionNode)}\n title=\"Rerun this test or subtree\"\n >\n <Icon icon={UiRefresh} className=\"mr-1 text-sm\" />\n {runner.busy.rerun ? \"Running...\" : \"Rerun\"}\n </Button>\n )}\n {canStop && (\n <Button\n size=\"sm\"\n variant=\"destructive\"\n disabled={runner.busy.stop}\n onClick={() => runner.onStop!(actionNode)}\n title=\"Stop this running task\"\n >\n <Icon icon={UiStop} className=\"mr-1 text-sm\" />\n {runner.busy.stop ? \"Stopping...\" : \"Stop\"}\n </Button>\n )}\n </div>\n </div>\n );\n}\n\n/**\n * The right pane. Resolves the node's adapter for body / tabs / header actions,\n * falling back to the built-in default body. Shows an empty state when nothing\n * is selected.\n */\nexport function TestDetailPanel() {\n const runner = useTestRunner();\n const selected = runner.selected;\n const [attemptSelection, setAttemptSelection] = useState<{ key: string; id: number } | null>(null);\n // Tab state is controlled when the host supplies activeTab (e.g. to mirror it\n // into the URL); otherwise the panel owns it. The render below tolerates an\n // unknown id by falling back to the built-in \"detail\" tab.\n const controlled = runner.activeTab !== undefined;\n const [internalTab, setInternalTab] = useState<string>(\"detail\");\n const activeTab = controlled ? runner.activeTab! : internalTab;\n const setActiveTab = (id: string) => {\n if (controlled) runner.onTabChange?.(id);\n else setInternalTab(id);\n };\n\n if (!selected) {\n return (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n <div className=\"text-center\">\n <Icon icon={UiClass} className=\"mb-2 block text-4xl\" />\n Select a test to view its details.\n </div>\n </div>\n );\n }\n\n const attempts = runner.adapters.resolveAttempts(selected, runner);\n const key = selected.task_id ?? selected.name;\n const attemptId = runner.activeAttempt ?? (attemptSelection?.key === key ? attemptSelection.id : undefined);\n const attempt = attempts.find((a) => a.id === attemptId) ?? attempts.at(-1);\n const node = attempts.length > 1 && attempt ? attempt.node : selected;\n const attemptChooser = attempts.length > 1 && attempt ? (\n <div className=\"w-44 shrink-0\">\n <Select aria-label=\"Attempt\" value={String(attempt.id)} className=\"h-7 text-xs\" onChange={(event) => {\n const id = Number(event.target.value);\n if (runner.onAttemptChange) runner.onAttemptChange(id);\n else setAttemptSelection({ key, id });\n }} options={attempts.map((a) => ({ value: String(a.id), label: `Attempt ${a.id}/${attempts.length} · ${a.status}${a.durationMs !== undefined ? ` · ${formatTestDuration(a.durationMs * 1e6)}` : \"\"}` }))} />\n </div>\n ) : null;\n\n const detailAdapter = runner.adapters.resolveDetail(node, runner);\n const actionAdapter = runner.adapters.resolveActions(selected, runner);\n const tabs = runner.adapters.resolveTabs(node, runner);\n const ownsScroll = runner.adapters.ownsScroll(node, runner);\n\n const body = (\n <DetailTabSelectProvider value={setActiveTab}>\n {detailAdapter?.renderDetail\n ? detailAdapter.renderDetail({ node, runner })\n : <DefaultDetailBody node={node} />}\n </DetailTabSelectProvider>\n );\n const actions = actionAdapter?.nodeActions?.({ node: selected, runner });\n\n // A size container, so log blocks can cap themselves at a share of the pane (cqh).\n const detailRegion = cn(\"min-h-0 flex-1 [container-type:size]\", !ownsScroll && \"overflow-y-auto\");\n\n // No extra tabs → just the body under the header.\n if (tabs.length === 0) {\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <DetailHeader node={node} actionNode={selected} actions={actions} attemptChooser={attemptChooser} />\n <div className={detailRegion}>{body}</div>\n </div>\n );\n }\n\n const detailTab = { id: \"detail\", label: \"Detail\", render: () => body };\n const allTabs = [detailTab, ...tabs];\n const active = allTabs.find((t) => t.id === activeTab) ?? detailTab;\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <DetailHeader node={node} actionNode={selected} actions={actions} attemptChooser={attemptChooser} />\n <div className=\"flex shrink-0 items-center gap-1 border-b border-border px-density-2 py-density-1\">\n {allTabs.map((t) => (\n <TabButton\n key={t.id}\n active={active.id === t.id}\n onClick={() => setActiveTab(t.id)}\n label={t.label}\n />\n ))}\n </div>\n <div className={detailRegion}>{active.render()}</div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,51 +1,10 @@
1
1
  const require_utils = require("../../lib/utils.cjs");
2
- const require_UiChevronDown = require("../../icons/components/UiChevronDown.cjs");
3
- const require_Icon = require("../Icon.cjs");
4
- const require_DropdownMenu = require("../../overlay/DropdownMenu.cjs");
5
- const require_filter_bar_context = require("../../components/filter-bar-context.cjs");
6
- const require_filter_bar_field_utils = require("../../components/filter-bar-field-utils.cjs");
7
- const require_filter_bar_multi = require("../../components/filter-bar-multi.cjs");
8
2
  const require_status = require("./status.cjs");
9
3
  const require_marks = require("./marks.cjs");
10
4
  const require_MarkIcons = require("./MarkIcons.cjs");
5
+ const require_FilterFacet = require("./FilterFacet.cjs");
11
6
  let react_jsx_runtime = require("react/jsx-runtime");
12
7
  // src/data/test-runner/TestFilterBar.tsx
13
- var COMMIT_IMMEDIATELY = {
14
- autoSubmit: false,
15
- compact: false
16
- };
17
- function Facet({ label, options, state, onChange }) {
18
- const value = Object.fromEntries(state);
19
- const active = state.size > 0;
20
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_DropdownMenu.DropdownMenu, {
21
- align: "right",
22
- menuLabel: label,
23
- menuClassName: "p-2",
24
- trigger: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
25
- role: "button",
26
- tabIndex: 0,
27
- className: require_utils.cn("inline-flex h-6 items-center gap-0.5 rounded px-1.5 text-xs transition-colors", active ? "bg-muted font-medium text-foreground" : "text-muted-foreground hover:bg-muted/60 hover:text-foreground"),
28
- children: [require_filter_bar_field_utils.summarizeMultiFilter(label, value), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Icon.Icon, {
29
- icon: require_UiChevronDown.UiChevronDown,
30
- className: "text-[10px] opacity-60"
31
- })]
32
- }),
33
- children: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_filter_bar_context.FilterBarContext.Provider, {
34
- value: COMMIT_IMMEDIATELY,
35
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_filter_bar_multi.MultiFilterPanel, {
36
- chrome: "embedded",
37
- filter: {
38
- key: label,
39
- kind: "multi",
40
- label,
41
- options,
42
- value,
43
- onChange: (v) => onChange(new Map(Object.entries(v)))
44
- }
45
- })
46
- })
47
- });
48
- }
49
8
  /**
50
9
  * Status and tool facets as compact, muted menu triggers sized for the tree
51
10
  * toolbar; each opens a tri-state (include / exclude) option list. Named
@@ -66,7 +25,7 @@ function TestFilterBar({ filters, onChange, counts, frameworks, className }) {
66
25
  }));
67
26
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
68
27
  className: require_utils.cn("flex items-center gap-0.5", className),
69
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Facet, {
28
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_FilterFacet.FilterFacet, {
70
29
  label: "Status",
71
30
  options: statusOptions,
72
31
  state: filters.status,
@@ -74,7 +33,7 @@ function TestFilterBar({ filters, onChange, counts, frameworks, className }) {
74
33
  ...filters,
75
34
  status
76
35
  })
77
- }), frameworks.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Facet, {
36
+ }), frameworks.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_FilterFacet.FilterFacet, {
78
37
  label: "Tool",
79
38
  options: toolOptions,
80
39
  state: filters.framework,
@@ -1 +1 @@
1
- {"version":3,"file":"TestFilterBar.cjs","names":["DropdownMenu","cn","summarizeMultiFilter","Icon","UiChevronDown","FilterBarContext","MultiFilterPanel","STATUS_LABELS","OutcomeIcon","toolMark","ToolIcon"],"sources":["../../../src/data/test-runner/TestFilterBar.tsx"],"sourcesContent":["import { cn } from \"../../lib/utils\";\nimport { Icon } from \"../Icon\";\nimport { UiChevronDown } from \"../../icons\";\nimport { DropdownMenu } from \"../../overlay/DropdownMenu\";\nimport { FilterBarContext } from \"../../components/filter-bar-context\";\nimport { MultiFilterPanel } from \"../../components/filter-bar-multi\";\nimport { summarizeMultiFilter } from \"../../components/filter-bar-field-utils\";\nimport type { MultiSelectOption } from \"../../components/MultiSelect\";\nimport { OutcomeIcon, ToolIcon } from \"./MarkIcons\";\nimport { toolMark } from \"./marks\";\nimport { STATUS_LABELS, type StatusCounts, type TestOutcome } from \"./status\";\nimport type { FilterMode, FilterState, TestFilters } from \"./filterState\";\n\nexport type TestFilterBarProps = {\n filters: TestFilters;\n onChange: (next: TestFilters) => void;\n counts: StatusCounts;\n frameworks: string[];\n className?: string;\n};\n\n// Picks commit straight away: the runner, not a form, owns the filter state.\nconst COMMIT_IMMEDIATELY = { autoSubmit: false, compact: false };\n\nfunction Facet({\n label,\n options,\n state,\n onChange,\n}: {\n label: string;\n options: MultiSelectOption[];\n state: FilterState<string>;\n onChange: (next: FilterState<string>) => void;\n}) {\n const value: Record<string, FilterMode> = Object.fromEntries(state);\n const active = state.size > 0;\n return (\n <DropdownMenu\n align=\"right\"\n menuLabel={label}\n menuClassName=\"p-2\"\n trigger={\n <span\n role=\"button\"\n tabIndex={0}\n className={cn(\n \"inline-flex h-6 items-center gap-0.5 rounded px-1.5 text-xs transition-colors\",\n active\n ? \"bg-muted font-medium text-foreground\"\n : \"text-muted-foreground hover:bg-muted/60 hover:text-foreground\",\n )}\n >\n {summarizeMultiFilter(label, value)}\n <Icon icon={UiChevronDown} className=\"text-[10px] opacity-60\" />\n </span>\n }\n >\n {() => (\n <FilterBarContext.Provider value={COMMIT_IMMEDIATELY}>\n <MultiFilterPanel\n chrome=\"embedded\"\n filter={{\n key: label,\n kind: \"multi\",\n label,\n options,\n value,\n onChange: (v) => onChange(new Map(Object.entries(v))),\n }}\n />\n </FilterBarContext.Provider>\n )}\n </DropdownMenu>\n );\n}\n\n/**\n * Status and tool facets as compact, muted menu triggers sized for the tree\n * toolbar; each opens a tri-state (include / exclude) option list. Named\n * TestFilterBar to avoid the generic `FilterBar` export in clicky-ui/components.\n */\nexport function TestFilterBar({\n filters,\n onChange,\n counts,\n frameworks,\n className,\n}: TestFilterBarProps) {\n const statusOptions: MultiSelectOption[] = STATUS_LABELS.filter((d) => counts[d.key] > 0).map(\n (d) => ({\n value: d.key,\n label: d.label,\n icon: <OutcomeIcon outcome={d.key as TestOutcome} />,\n count: counts[d.key],\n }),\n );\n const toolOptions: MultiSelectOption[] = frameworks.map((fw) => ({\n value: fw,\n label: toolMark(fw)?.label ?? fw,\n title: fw,\n icon: <ToolIcon tool={fw} />,\n }));\n\n return (\n <div className={cn(\"flex items-center gap-0.5\", className)}>\n <Facet\n label=\"Status\"\n options={statusOptions}\n state={filters.status}\n onChange={(status) => onChange({ ...filters, status })}\n />\n {frameworks.length > 1 && (\n <Facet\n label=\"Tool\"\n options={toolOptions}\n state={filters.framework}\n onChange={(framework) => onChange({ ...filters, framework })}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAsBA,IAAM,qBAAqB;CAAE,YAAY;CAAO,SAAS;AAAM;AAE/D,SAAS,MAAM,EACb,OACA,SACA,OACA,YAMC;CACD,MAAM,QAAoC,OAAO,YAAY,KAAK;CAClE,MAAM,SAAS,MAAM,OAAO;CAC5B,OACE,iBAAA,GAAA,kBAAA,IAAA,CAACA,qBAAAA,cAAD;EACE,OAAM;EACN,WAAW;EACX,eAAc;EACd,SACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;GACE,MAAK;GACL,UAAU;GACV,WAAWC,cAAAA,GACT,iFACA,SACI,yCACA,+DACN;GARF,UAAA,CAUGC,+BAAAA,qBAAqB,OAAO,KAAK,GAClC,iBAAA,GAAA,kBAAA,IAAA,CAACC,aAAAA,MAAD;IAAM,MAAMC,sBAAAA;IAAe,WAAU;GAA0B,CAAA,CAC3D;;EAIN,gBAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,2BAAAA,iBAAiB,UAAlB;GAA2B,OAAO;GAChC,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACC,yBAAAA,kBAAD;IACE,QAAO;IACP,QAAQ;KACN,KAAK;KACL,MAAM;KACN;KACA;KACA;KACA,WAAW,MAAM,SAAS,IAAI,IAAI,OAAO,QAAQ,CAAC,CAAC,CAAC;IACtD;GACD,CAAA;EACwB,CAAA;CAEjB,CAAA;AAElB;;;;;;AAOA,SAAgB,cAAc,EAC5B,SACA,UACA,QACA,YACA,aACqB;CACrB,MAAM,gBAAqCC,eAAAA,cAAc,QAAQ,MAAM,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,KACvF,OAAO;EACN,OAAO,EAAE;EACT,OAAO,EAAE;EACT,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAACC,kBAAAA,aAAD,EAAa,SAAS,EAAE,IAAqB,CAAA;EACnD,OAAO,OAAO,EAAE;CAClB,EACF;CACA,MAAM,cAAmC,WAAW,KAAK,QAAQ;EAC/D,OAAO;EACP,OAAOC,cAAAA,SAAS,EAAE,CAAC,EAAE,SAAS;EAC9B,OAAO;EACP,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAACC,kBAAAA,UAAD,EAAU,MAAM,GAAK,CAAA;CAC7B,EAAE;CAEF,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAWT,cAAAA,GAAG,6BAA6B,SAAS;EAAzD,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;GACE,OAAM;GACN,SAAS;GACT,OAAO,QAAQ;GACf,WAAW,WAAW,SAAS;IAAE,GAAG;IAAS;GAAO,CAAC;EACtD,CAAA,GACA,WAAW,SAAS,KACnB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;GACE,OAAM;GACN,SAAS;GACT,OAAO,QAAQ;GACf,WAAW,cAAc,SAAS;IAAE,GAAG;IAAS;GAAU,CAAC;EAC5D,CAAA,CAEA;;AAET"}
1
+ {"version":3,"file":"TestFilterBar.cjs","names":["STATUS_LABELS","OutcomeIcon","toolMark","ToolIcon","cn","Facet"],"sources":["../../../src/data/test-runner/TestFilterBar.tsx"],"sourcesContent":["import { cn } from \"../../lib/utils\";\nimport type { MultiSelectOption } from \"../../components/MultiSelect\";\nimport { FilterFacet as Facet } from \"./FilterFacet\";\nimport { OutcomeIcon, ToolIcon } from \"./MarkIcons\";\nimport { toolMark } from \"./marks\";\nimport { STATUS_LABELS, type StatusCounts, type TestOutcome } from \"./status\";\nimport type { TestFilters } from \"./filterState\";\n\nexport type TestFilterBarProps = {\n filters: TestFilters;\n onChange: (next: TestFilters) => void;\n counts: StatusCounts;\n frameworks: string[];\n className?: string;\n};\n\n\n/**\n * Status and tool facets as compact, muted menu triggers sized for the tree\n * toolbar; each opens a tri-state (include / exclude) option list. Named\n * TestFilterBar to avoid the generic `FilterBar` export in clicky-ui/components.\n */\nexport function TestFilterBar({\n filters,\n onChange,\n counts,\n frameworks,\n className,\n}: TestFilterBarProps) {\n const statusOptions: MultiSelectOption[] = STATUS_LABELS.filter((d) => counts[d.key] > 0).map(\n (d) => ({\n value: d.key,\n label: d.label,\n icon: <OutcomeIcon outcome={d.key as TestOutcome} />,\n count: counts[d.key],\n }),\n );\n const toolOptions: MultiSelectOption[] = frameworks.map((fw) => ({\n value: fw,\n label: toolMark(fw)?.label ?? fw,\n title: fw,\n icon: <ToolIcon tool={fw} />,\n }));\n\n return (\n <div className={cn(\"flex items-center gap-0.5\", className)}>\n <Facet\n label=\"Status\"\n options={statusOptions}\n state={filters.status}\n onChange={(status) => onChange({ ...filters, status })}\n />\n {frameworks.length > 1 && (\n <Facet\n label=\"Tool\"\n options={toolOptions}\n state={filters.framework}\n onChange={(framework) => onChange({ ...filters, framework })}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAsBA,SAAgB,cAAc,EAC5B,SACA,UACA,QACA,YACA,aACqB;CACrB,MAAM,gBAAqCA,eAAAA,cAAc,QAAQ,MAAM,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,KACvF,OAAO;EACN,OAAO,EAAE;EACT,OAAO,EAAE;EACT,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAACC,kBAAAA,aAAD,EAAa,SAAS,EAAE,IAAqB,CAAA;EACnD,OAAO,OAAO,EAAE;CAClB,EACF;CACA,MAAM,cAAmC,WAAW,KAAK,QAAQ;EAC/D,OAAO;EACP,OAAOC,cAAAA,SAAS,EAAE,CAAC,EAAE,SAAS;EAC9B,OAAO;EACP,MAAM,iBAAA,GAAA,kBAAA,IAAA,CAACC,kBAAAA,UAAD,EAAU,MAAM,GAAK,CAAA;CAC7B,EAAE;CAEF,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;EAAK,WAAWC,cAAAA,GAAG,6BAA6B,SAAS;EAAzD,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAACC,oBAAAA,aAAD;GACE,OAAM;GACN,SAAS;GACT,OAAO,QAAQ;GACf,WAAW,WAAW,SAAS;IAAE,GAAG;IAAS;GAAO,CAAC;EACtD,CAAA,GACA,WAAW,SAAS,KACnB,iBAAA,GAAA,kBAAA,IAAA,CAACA,oBAAAA,aAAD;GACE,OAAM;GACN,SAAS;GACT,OAAO,QAAQ;GACf,WAAW,cAAc,SAAS;IAAE,GAAG;IAAS;GAAU,CAAC;EAC5D,CAAA,CAEA;;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"TestFilterBar.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestFilterBar.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAiB,KAAK,YAAY,EAAoB,MAAM,UAAU,CAAC;AAC9E,OAAO,KAAK,EAA2B,WAAW,EAAE,MAAM,eAAe,CAAC;AAE1E,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA0DF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,MAAM,EACN,UAAU,EACV,SAAS,GACV,EAAE,kBAAkB,+BAkCpB"}
1
+ {"version":3,"file":"TestFilterBar.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/TestFilterBar.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAiB,KAAK,YAAY,EAAoB,MAAM,UAAU,CAAC;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,QAAQ,EACR,MAAM,EACN,UAAU,EACV,SAAS,GACV,EAAE,kBAAkB,+BAkCpB"}