@piwitests/server 0.18.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (773) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{BaDv5D7A.js → -09h6CA9.js} +1 -1
  3. package/.output/public/_nuxt/279D2RYp.js +1 -0
  4. package/.output/public/_nuxt/81InBX9v.js +1 -0
  5. package/.output/public/_nuxt/{CRpbGS75.js → Ar3IelOY.js} +1 -1
  6. package/.output/public/_nuxt/B33iXw77.js +1 -0
  7. package/.output/public/_nuxt/B3B9Ii2A.js +1 -0
  8. package/.output/public/_nuxt/B3HO8kuh.js +1 -0
  9. package/.output/public/_nuxt/B44A4LSJ.js +1 -0
  10. package/.output/public/_nuxt/{CPZ5wygb.js → B7NBP1C-.js} +1 -1
  11. package/.output/public/_nuxt/{Db_-yjYg.js → B9WhzpKO.js} +1 -1
  12. package/.output/public/_nuxt/{DoYgYLOd.js → BCMuIgP5.js} +1 -1
  13. package/.output/public/_nuxt/BDicZ1gQ.js +1 -0
  14. package/.output/public/_nuxt/BJ0XQElc.js +1 -0
  15. package/.output/public/_nuxt/{D4SFgXAf.js → BMvCSA6h.js} +1 -1
  16. package/.output/public/_nuxt/BPQoBGg5.js +1 -0
  17. package/.output/public/_nuxt/BPRffDuo.js +1 -0
  18. package/.output/public/_nuxt/BSIxhGsh.js +1 -0
  19. package/.output/public/_nuxt/BVaxh6Nl.js +4 -0
  20. package/.output/public/_nuxt/{BReNbog6.js → BX9ZXe98.js} +1 -1
  21. package/.output/public/_nuxt/{rm7OkgDG.js → BYDaY0Z7.js} +1 -1
  22. package/.output/public/_nuxt/{WAaPPk0g.js → Bc8mOoz9.js} +2 -2
  23. package/.output/public/_nuxt/BccXfBfI.js +1 -0
  24. package/.output/public/_nuxt/{Dbg8z684.js → BeLWlVK0.js} +1 -1
  25. package/.output/public/_nuxt/{CP0vUzbd.js → BfTuX0wq.js} +1 -1
  26. package/.output/public/_nuxt/BjaRappk.js +1 -0
  27. package/.output/public/_nuxt/{D3MWm6JP.js → Bn0YQDyy.js} +1 -1
  28. package/.output/public/_nuxt/Bp5ELvx9.js +1 -0
  29. package/.output/public/_nuxt/BpUaY9nH.js +2 -0
  30. package/.output/public/_nuxt/BqV0l12c.js +1 -0
  31. package/.output/public/_nuxt/{D8YZvjas.js → Bti38m-M.js} +1 -1
  32. package/.output/public/_nuxt/{DVgMaBxD.js → Bu2aaVIY.js} +3 -3
  33. package/.output/public/_nuxt/{CUDeMcEK.js → BuMC3WjZ.js} +1 -1
  34. package/.output/public/_nuxt/{Bi3i470l.js → BxCKKeYs.js} +1 -1
  35. package/.output/public/_nuxt/{BTYiG93l.js → C-elpgyr.js} +1 -1
  36. package/.output/public/_nuxt/C2_3mdPC.js +1 -0
  37. package/.output/public/_nuxt/{BoC6qaRF.js → C5iG7O4O.js} +4 -4
  38. package/.output/public/_nuxt/C7P1UCO2.js +1 -0
  39. package/.output/public/_nuxt/{BuuvTH9e.js → C95YAaJq.js} +1 -1
  40. package/.output/public/_nuxt/{DOr_4nln.js → C9_jrmk9.js} +2 -2
  41. package/.output/public/_nuxt/CDk0q2hV.js +2 -0
  42. package/.output/public/_nuxt/{DIA_NAIv.js → CGNkHojN.js} +3 -3
  43. package/.output/public/_nuxt/CHEFCN8Q.js +1 -0
  44. package/.output/public/_nuxt/CHNwfU1y.js +1 -0
  45. package/.output/public/_nuxt/CK_2LZBS.js +1 -0
  46. package/.output/public/_nuxt/CNFYDQmj.js +1 -0
  47. package/.output/public/_nuxt/{BfoG8R5a.js → CTxDO9fB.js} +1 -1
  48. package/.output/public/_nuxt/{B1CB30tg.js → CU5S9GCh.js} +1 -1
  49. package/.output/public/_nuxt/{BKaU95es.js → CUtJobDm.js} +1 -1
  50. package/.output/public/_nuxt/CV9-fTmY.js +1 -0
  51. package/.output/public/_nuxt/{BAkJhSAW.js → CYsTqbBS.js} +1 -1
  52. package/.output/public/_nuxt/{AjuKBlzz.js → CZfMdzfk.js} +1 -1
  53. package/.output/public/_nuxt/{lowCGL2S.js → Cdff9XNh.js} +1 -1
  54. package/.output/public/_nuxt/{quV6tp4n.js → ClOqkAcc.js} +1 -1
  55. package/.output/public/_nuxt/{Doul3p1_.js → CpjgB2aY.js} +1 -1
  56. package/.output/public/_nuxt/CrwJAwhk.js +1 -0
  57. package/.output/public/_nuxt/CtQBsNUb.js +1 -0
  58. package/.output/public/_nuxt/CuSVQEkS.js +3 -0
  59. package/.output/public/_nuxt/{wQZj69OY.js → CylWPruw.js} +1 -1
  60. package/.output/public/_nuxt/CzGyac8q.js +1 -0
  61. package/.output/public/_nuxt/D-c8ZSws.js +1 -0
  62. package/.output/public/_nuxt/{B6IHiVa1.js → D0HNloZ9.js} +1 -1
  63. package/.output/public/_nuxt/{ClIKZ4qY.js → D55D4EYo.js} +1 -1
  64. package/.output/public/_nuxt/{Bi9DO8jm.js → DDDpCFpF.js} +1 -1
  65. package/.output/public/_nuxt/{va1mwSm9.js → DEFEpYzn.js} +1 -1
  66. package/.output/public/_nuxt/DGfAxLHV.js +1 -0
  67. package/.output/public/_nuxt/DHDtnj7p.js +1 -0
  68. package/.output/public/_nuxt/DLSrtpsA.js +1 -0
  69. package/.output/public/_nuxt/DP8hfJ9h.js +1 -0
  70. package/.output/public/_nuxt/DS636elg.js +1 -0
  71. package/.output/public/_nuxt/{D51_cB9D.js → DT53RWbC.js} +1 -1
  72. package/.output/public/_nuxt/DVDXJYq2.js +2 -0
  73. package/.output/public/_nuxt/DW0xl3I6.js +17 -0
  74. package/.output/public/_nuxt/{BEB2Mv6B.js → DX-MDGb3.js} +1 -1
  75. package/.output/public/_nuxt/DcmZRa_F.js +1 -0
  76. package/.output/public/_nuxt/DgE2YE3R.js +1 -0
  77. package/.output/public/_nuxt/Dgf5N4Ng.js +1 -0
  78. package/.output/public/_nuxt/DiOLdHBC.js +1 -0
  79. package/.output/public/_nuxt/DiZyJYez.js +1 -0
  80. package/.output/public/_nuxt/Dk9fwOCm.js +34 -0
  81. package/.output/public/_nuxt/{DRE6Aqqp.js → Dnpkl-1q.js} +1 -1
  82. package/.output/public/_nuxt/DoUy4UHi.js +44 -0
  83. package/.output/public/_nuxt/{empGC_x-.js → DprVVyUQ.js} +1 -1
  84. package/.output/public/_nuxt/{BVDBIVAQ.js → DslPMqfa.js} +1 -1
  85. package/.output/public/_nuxt/{Vnfkr1pJ.js → FUXhyidq.js} +1 -1
  86. package/.output/public/_nuxt/HXerICAi.js +79 -0
  87. package/.output/public/_nuxt/{Do6zIWQf.js → IvQlbZk6.js} +1 -1
  88. package/.output/public/_nuxt/{n-QWmQgc.js → Jo8kRmHz.js} +1 -1
  89. package/.output/public/_nuxt/{BsDB_eCd.js → KnfsST6Y.js} +1 -1
  90. package/.output/public/_nuxt/NQikbhmK.js +253 -0
  91. package/.output/public/_nuxt/OSduWzyz.js +1 -0
  92. package/.output/public/_nuxt/SfMRXW25.js +5 -0
  93. package/.output/public/_nuxt/{mlAADjK3.js → SlIRLREZ.js} +2 -2
  94. package/.output/public/_nuxt/TagBadge.By1E6r4y.css +1 -0
  95. package/.output/public/_nuxt/WsxFTEFq.js +10 -0
  96. package/.output/public/_nuxt/YVN7WG7q.js +1 -0
  97. package/.output/public/_nuxt/{CRcjGmf7.js → ZFiQCMUB.js} +1 -1
  98. package/.output/public/_nuxt/aQgs_c6e.js +9 -0
  99. package/.output/public/_nuxt/builds/latest.json +1 -1
  100. package/.output/public/_nuxt/builds/meta/ab473028-4b37-4884-b243-b8f6e5046e5e.json +1 -0
  101. package/.output/public/_nuxt/{Dwp3GkV-.js → cHAnlQbv.js} +1 -1
  102. package/.output/public/_nuxt/dYCKgE-3.js +5 -0
  103. package/.output/public/_nuxt/{DnThe2U0.js → eaVkJRSa.js} +1 -1
  104. package/.output/public/_nuxt/entry.CPhW41mh.css +1 -0
  105. package/.output/public/_nuxt/{DoFSKAvY.js → eptP4pGv.js} +1 -1
  106. package/.output/public/_nuxt/fVcG504p.js +1 -0
  107. package/.output/public/_nuxt/g26aVPxc.js +1 -0
  108. package/.output/public/_nuxt/{wGpfdK6o.js → ndShiWE8.js} +1 -1
  109. package/.output/public/_nuxt/nv9-6vBK.js +1 -0
  110. package/.output/public/_nuxt/rWNTSFD6.js +3 -0
  111. package/.output/public/_nuxt/tvgqrYDd.js +1 -0
  112. package/.output/public/_nuxt/{DCMFuzDI.js → y17lMTFy.js} +1 -1
  113. package/.output/public/_nuxt/{DM_YaJgJ.js → ybDYeNxd.js} +1 -1
  114. package/.output/public/_nuxt/{B_aSGB8S.js → zQyPuvV1.js} +1 -1
  115. package/.output/public/demo/seed.version.json +2 -2
  116. package/.output/server/chunks/_/ai-prompt-preview.mjs +38 -0
  117. package/.output/server/chunks/_/ai-prompt-preview.mjs.map +1 -0
  118. package/.output/server/chunks/_/collect.mjs +122 -0
  119. package/.output/server/chunks/_/collect.mjs.map +1 -0
  120. package/.output/server/chunks/_/import-runs.mjs +351 -0
  121. package/.output/server/chunks/_/import-runs.mjs.map +1 -0
  122. package/.output/server/chunks/_/markers.mjs +1 -1
  123. package/.output/server/chunks/_/quarantine.mjs +112 -0
  124. package/.output/server/chunks/_/quarantine.mjs.map +1 -0
  125. package/.output/server/chunks/_/users.mjs +1 -1
  126. package/.output/server/chunks/build/{Alert-Bp1Wz_sq.mjs → Alert-C4xq8lao.mjs} +2 -2
  127. package/.output/server/chunks/build/Alert-C4xq8lao.mjs.map +1 -0
  128. package/.output/server/chunks/build/{Breadcrumb-C9ZPTLym.mjs → Breadcrumb-Ak2Lg3oM.mjs} +3 -3
  129. package/.output/server/chunks/build/Breadcrumb-Ak2Lg3oM.mjs.map +1 -0
  130. package/.output/server/chunks/build/{BreadcrumbNav-C3y42Vun.mjs → BreadcrumbNav-DO7I_z-n.mjs} +3 -3
  131. package/.output/server/chunks/build/BreadcrumbNav-DO7I_z-n.mjs.map +1 -0
  132. package/.output/server/chunks/build/{BrowserBadge-DNCp9pF-.mjs → BrowserBadge-D33lqUcj.mjs} +5 -5
  133. package/.output/server/chunks/build/BrowserBadge-D33lqUcj.mjs.map +1 -0
  134. package/.output/server/chunks/build/{ChartCard-Fr557IbV.mjs → ChartCard-Y1UKwMsf.mjs} +2 -2
  135. package/.output/server/chunks/build/ChartCard-Y1UKwMsf.mjs.map +1 -0
  136. package/.output/server/chunks/build/{Checkbox-cVOSIY93.mjs → Checkbox-DvUBGagc.mjs} +8 -8
  137. package/.output/server/chunks/build/Checkbox-DvUBGagc.mjs.map +1 -0
  138. package/.output/server/chunks/build/{CiEnvCard-DXPOhdSG.mjs → CiEnvCard-CrjOM17n.mjs} +25 -34
  139. package/.output/server/chunks/build/CiEnvCard-CrjOM17n.mjs.map +1 -0
  140. package/.output/server/chunks/build/{CodeBlock-BGwNmJ8J.mjs → CodeBlock-BgE-NSmE.mjs} +7 -22
  141. package/.output/server/chunks/build/CodeBlock-BgE-NSmE.mjs.map +1 -0
  142. package/.output/server/chunks/build/{DashboardNavbar-Bdp-OwTN.mjs → DashboardNavbar-BHmMSPX7.mjs} +3 -3
  143. package/.output/server/chunks/build/DashboardNavbar-BHmMSPX7.mjs.map +1 -0
  144. package/.output/server/chunks/build/{DashboardSidebarToggle-Ji6ADuqF.mjs → DashboardSidebarToggle-DCTnHiIv.mjs} +3 -3
  145. package/.output/server/chunks/build/DashboardSidebarToggle-DCTnHiIv.mjs.map +1 -0
  146. package/.output/server/chunks/build/{DataLocationCard-D6xSOrme.mjs → DataLocationCard-B_YHdzSz.mjs} +3 -3
  147. package/.output/server/chunks/build/DataLocationCard-B_YHdzSz.mjs.map +1 -0
  148. package/.output/server/chunks/build/{DiagnosisPanel-DV1xwGu4.mjs → DiagnosisPanel-B646dK4p.mjs} +17 -528
  149. package/.output/server/chunks/build/DiagnosisPanel-B646dK4p.mjs.map +1 -0
  150. package/.output/server/chunks/build/DurationValue-D20oGbnc.mjs +43 -0
  151. package/.output/server/chunks/build/DurationValue-D20oGbnc.mjs.map +1 -0
  152. package/.output/server/chunks/build/{EmptyState-DV3oT_xz.mjs → EmptyState-Dtlab7S9.mjs} +3 -3
  153. package/.output/server/chunks/build/EmptyState-Dtlab7S9.mjs.map +1 -0
  154. package/.output/server/chunks/build/{EntityLinks-DeOP13Kr.mjs → EntityLinks-D3fp57pR.mjs} +6 -6
  155. package/.output/server/chunks/build/EntityLinks-D3fp57pR.mjs.map +1 -0
  156. package/.output/server/chunks/build/{EnvManagedBadge-Qpn58Nmr.mjs → EnvManagedBadge-Bg3FSiU1.mjs} +3 -3
  157. package/.output/server/chunks/build/EnvManagedBadge-Bg3FSiU1.mjs.map +1 -0
  158. package/.output/server/chunks/build/{FormField-B-GSn_VR.mjs → FormField-B0HKsdMd.mjs} +3 -3
  159. package/.output/server/chunks/build/FormField-B0HKsdMd.mjs.map +1 -0
  160. package/.output/server/chunks/build/{HelpHint-YEMWtKu1.mjs → HelpHint-DrcIv-Oj.mjs} +53 -6
  161. package/.output/server/chunks/build/HelpHint-DrcIv-Oj.mjs.map +1 -0
  162. package/.output/server/chunks/build/{Label-DBvbHd3A.mjs → Label-DYDR1Oeh.mjs} +2 -2
  163. package/.output/server/chunks/build/Label-DYDR1Oeh.mjs.map +1 -0
  164. package/.output/server/chunks/build/{MiniRunBars-C3HG-EYm.mjs → MiniRunBars-CZMugDrh.mjs} +2 -2
  165. package/.output/server/chunks/build/MiniRunBars-CZMugDrh.mjs.map +1 -0
  166. package/.output/server/chunks/build/{Modal-CfA78Hm1.mjs → Modal-Ck2XLt8d.mjs} +2 -2
  167. package/.output/server/chunks/build/Modal-Ck2XLt8d.mjs.map +1 -0
  168. package/.output/server/chunks/build/{OpenInIdeLink-B92wosXu.mjs → OpenInIdeLink-C4MXA8ya.mjs} +6 -6
  169. package/.output/server/chunks/build/{OpenInIdeLink-B92wosXu.mjs.map → OpenInIdeLink-C4MXA8ya.mjs.map} +1 -1
  170. package/.output/server/chunks/build/{ProjectTestCasesTable-9Ia825h8.mjs → ProjectTestCasesTable-CxfQ5wtN.mjs} +120 -45
  171. package/.output/server/chunks/build/ProjectTestCasesTable-CxfQ5wtN.mjs.map +1 -0
  172. package/.output/server/chunks/build/{RovingFocusItem-CxhHdNGo.mjs → RovingFocusItem-BJSzTBjy.mjs} +2 -2
  173. package/.output/server/chunks/build/RovingFocusItem-BJSzTBjy.mjs.map +1 -0
  174. package/.output/server/chunks/build/{RunReports-BpJqLHY9.mjs → RunReports-DFLv51TX.mjs} +8 -6
  175. package/.output/server/chunks/build/RunReports-DFLv51TX.mjs.map +1 -0
  176. package/.output/server/chunks/build/{RunStatusBadge-BhmJ_RKM.mjs → RunStatusBadge-FfGb6bkW.mjs} +3 -2
  177. package/.output/server/chunks/build/RunStatusBadge-FfGb6bkW.mjs.map +1 -0
  178. package/.output/server/chunks/build/{SectionCard-COd9TuDq.mjs → SectionCard-CN-v0FZ_.mjs} +2 -2
  179. package/.output/server/chunks/build/SectionCard-CN-v0FZ_.mjs.map +1 -0
  180. package/.output/server/chunks/build/{Select-ppPz926C.mjs → Select-CUqj50wi.mjs} +4 -4
  181. package/.output/server/chunks/build/Select-CUqj50wi.mjs.map +1 -0
  182. package/.output/server/chunks/build/{SelectMenu-799c_Ils.mjs → SelectMenu-Db7osY7J.mjs} +4 -4
  183. package/.output/server/chunks/build/{SelectMenu-799c_Ils.mjs.map → SelectMenu-Db7osY7J.mjs.map} +1 -1
  184. package/.output/server/chunks/build/{Separator-CxZdx8kw.mjs → Separator-CR4WcEKD.mjs} +2 -2
  185. package/.output/server/chunks/build/Separator-CR4WcEKD.mjs.map +1 -0
  186. package/.output/server/chunks/build/{SettingsField-DDD4oqys.mjs → SettingsField-D6iEYbEc.mjs} +6 -6
  187. package/.output/server/chunks/build/SettingsField-D6iEYbEc.mjs.map +1 -0
  188. package/.output/server/chunks/build/{Slideover-B95Rj237.mjs → Slideover-DgCa80mf.mjs} +3 -3
  189. package/.output/server/chunks/build/Slideover-DgCa80mf.mjs.map +1 -0
  190. package/.output/server/chunks/build/{Switch-xQQ3_ME1.mjs → Switch-CgUioOYB.mjs} +5 -5
  191. package/.output/server/chunks/build/Switch-CgUioOYB.mjs.map +1 -0
  192. package/.output/server/chunks/build/{Table-CPhhVzDv.mjs → Table-BRk04Hd2.mjs} +3 -3
  193. package/.output/server/chunks/build/Table-BRk04Hd2.mjs.map +1 -0
  194. package/.output/server/chunks/build/{Tabs-BV9XqjoO.mjs → Tabs-Bbsg9wag.mjs} +3 -3
  195. package/.output/server/chunks/build/Tabs-Bbsg9wag.mjs.map +1 -0
  196. package/.output/server/chunks/build/TagBadge-DwzoFCBb.mjs +31 -0
  197. package/.output/server/chunks/build/TagBadge-DwzoFCBb.mjs.map +1 -0
  198. package/.output/server/chunks/build/TagBadge-styles.jhuZ4NjP.mjs +8 -0
  199. package/.output/server/chunks/build/TagBadge-styles.jhuZ4NjP.mjs.map +1 -0
  200. package/.output/server/chunks/build/{TestCaseHistoryChart-DMb-xSJa.mjs → TestCaseHistoryChart-nMLPhdvD.mjs} +6 -6
  201. package/.output/server/chunks/build/TestCaseHistoryChart-nMLPhdvD.mjs.map +1 -0
  202. package/.output/server/chunks/build/TestMetaBadges-D5_yUtIP.mjs +200 -0
  203. package/.output/server/chunks/build/TestMetaBadges-D5_yUtIP.mjs.map +1 -0
  204. package/.output/server/chunks/build/{TestStatusBar-CEzt76wk.mjs → TestStatusBar-j6h2Jp6A.mjs} +15 -15
  205. package/.output/server/chunks/build/TestStatusBar-j6h2Jp6A.mjs.map +1 -0
  206. package/.output/server/chunks/build/{Textarea-DrrqQUVG.mjs → Textarea-Dv2-lOvW.mjs} +2 -2
  207. package/.output/server/chunks/build/Textarea-Dv2-lOvW.mjs.map +1 -0
  208. package/.output/server/chunks/build/{Tooltip-7vwuDPrZ.mjs → Tooltip-BOazooWP.mjs} +3 -3
  209. package/.output/server/chunks/build/Tooltip-BOazooWP.mjs.map +1 -0
  210. package/.output/server/chunks/build/{VisuallyHiddenInput-C9eJVpPW.mjs → VisuallyHiddenInput-D6kBJxVd.mjs} +2 -2
  211. package/.output/server/chunks/build/VisuallyHiddenInput-D6kBJxVd.mjs.map +1 -0
  212. package/.output/server/chunks/build/{_id_-B2yirIuA.mjs → _id_-B78ky13D.mjs} +798 -358
  213. package/.output/server/chunks/build/_id_-B78ky13D.mjs.map +1 -0
  214. package/.output/server/chunks/build/{_id_-bWcP2xFl.mjs → _id_-BHh65pfg.mjs} +690 -443
  215. package/.output/server/chunks/build/_id_-BHh65pfg.mjs.map +1 -0
  216. package/.output/server/chunks/build/{_id_-B4V5fop6.mjs → _id_-Rzkqx55x.mjs} +297 -60
  217. package/.output/server/chunks/build/{_id_-B4V5fop6.mjs.map → _id_-Rzkqx55x.mjs.map} +1 -1
  218. package/.output/server/chunks/build/{_id_-CE0Gso6i.mjs → _id_-z5N6HPyC.mjs} +89 -40
  219. package/.output/server/chunks/build/_id_-z5N6HPyC.mjs.map +1 -0
  220. package/.output/server/chunks/build/{about-CoJjvUwM.mjs → about-CvSP73Ug.mjs} +100 -52
  221. package/.output/server/chunks/build/about-CvSP73Ug.mjs.map +1 -0
  222. package/.output/server/chunks/build/{account-Cn-eZqXM.mjs → account-DAfvaD-F.mjs} +21 -9
  223. package/.output/server/chunks/build/account-DAfvaD-F.mjs.map +1 -0
  224. package/.output/server/chunks/build/{ai-7jdaPOmj.mjs → ai-B4VJ9K1K.mjs} +45 -23
  225. package/.output/server/chunks/build/{ai-7jdaPOmj.mjs.map → ai-B4VJ9K1K.mjs.map} +1 -1
  226. package/.output/server/chunks/build/{analytics-B276WPeU.mjs → analytics-CJPC6t4L.mjs} +65 -39
  227. package/.output/server/chunks/build/{analytics-B276WPeU.mjs.map → analytics-CJPC6t4L.mjs.map} +1 -1
  228. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  229. package/.output/server/chunks/build/compare-RxHSOdsO.mjs +12 -0
  230. package/.output/server/chunks/build/{db.client-aHcD0wyX.mjs → db.client-CQoVTYB9.mjs} +83 -5
  231. package/.output/server/chunks/build/db.client-CQoVTYB9.mjs.map +1 -0
  232. package/.output/server/chunks/build/{default-BSzdkM_L.mjs → default-zvbFgDJG.mjs} +36 -24
  233. package/.output/server/chunks/build/default-zvbFgDJG.mjs.map +1 -0
  234. package/.output/server/chunks/build/{docs-BN_x1OW3.mjs → docs-DyuVEgtB.mjs} +30 -49
  235. package/.output/server/chunks/build/{docs-BN_x1OW3.mjs.map → docs-DyuVEgtB.mjs.map} +1 -1
  236. package/.output/server/chunks/build/{edit-C9Z7oZeu.mjs → edit-CFR5g2Qf.mjs} +30 -18
  237. package/.output/server/chunks/build/edit-CFR5g2Qf.mjs.map +1 -0
  238. package/.output/server/chunks/build/{fetch-8kznMtBM.mjs → fetch-B4FwBOzu.mjs} +3 -3
  239. package/.output/server/chunks/build/fetch-B4FwBOzu.mjs.map +1 -0
  240. package/.output/server/chunks/build/{forgot-password-BqPF4Rxs.mjs → forgot-password-CC__1OnV.mjs} +17 -5
  241. package/.output/server/chunks/build/forgot-password-CC__1OnV.mjs.map +1 -0
  242. package/.output/server/chunks/build/{help-content-DmFnuhNu.mjs → help-content-C876a9WD.mjs} +37 -8
  243. package/.output/server/chunks/build/help-content-C876a9WD.mjs.map +1 -0
  244. package/.output/server/chunks/build/import-CZo3djDi.mjs +1021 -0
  245. package/.output/server/chunks/build/import-CZo3djDi.mjs.map +1 -0
  246. package/.output/server/chunks/build/{index-CULN3-en.mjs → index-CU2nZhAa.mjs} +113 -42
  247. package/.output/server/chunks/build/index-CU2nZhAa.mjs.map +1 -0
  248. package/.output/server/chunks/build/{index-DVUtBexc.mjs → index-D7fe97l3.mjs} +1305 -281
  249. package/.output/server/chunks/build/index-D7fe97l3.mjs.map +1 -0
  250. package/.output/server/chunks/build/{index-BR9hw6qk.mjs → index-Stqw0dEI.mjs} +50 -30
  251. package/.output/server/chunks/build/index-Stqw0dEI.mjs.map +1 -0
  252. package/.output/server/chunks/build/{index-BK9PTRpd.mjs → index-gCw_y4ZJ.mjs} +87 -70
  253. package/.output/server/chunks/build/{index-BK9PTRpd.mjs.map → index-gCw_y4ZJ.mjs.map} +1 -1
  254. package/.output/server/chunks/build/{index-Ba-Fifra.mjs → index-tR6owKzj.mjs} +18 -6
  255. package/.output/server/chunks/build/index-tR6owKzj.mjs.map +1 -0
  256. package/.output/server/chunks/build/{isValueEqualOrExist-DBZjbD_3.mjs → isValueEqualOrExist-D2qw9YEr.mjs} +3 -3
  257. package/.output/server/chunks/build/isValueEqualOrExist-D2qw9YEr.mjs.map +1 -0
  258. package/.output/server/chunks/build/{login-D2XZDuek.mjs → login-Da4u1IlW.mjs} +19 -7
  259. package/.output/server/chunks/build/login-Da4u1IlW.mjs.map +1 -0
  260. package/.output/server/chunks/build/{mcp-_o6cMS6m.mjs → mcp-B3IUvRgD.mjs} +27 -21
  261. package/.output/server/chunks/build/mcp-B3IUvRgD.mjs.map +1 -0
  262. package/.output/server/chunks/build/{notifications-Dzm9c0u_.mjs → notifications-abDv0id8.mjs} +27 -21
  263. package/.output/server/chunks/build/notifications-abDv0id8.mjs.map +1 -0
  264. package/.output/server/chunks/build/pr-feedback-DjZID6q-.mjs +368 -0
  265. package/.output/server/chunks/build/pr-feedback-DjZID6q-.mjs.map +1 -0
  266. package/.output/server/chunks/build/{reset-password-gpFzIEDj.mjs → reset-password-BmrUS4ZD.mjs} +17 -5
  267. package/.output/server/chunks/build/reset-password-BmrUS4ZD.mjs.map +1 -0
  268. package/.output/server/chunks/build/server.mjs +238 -36
  269. package/.output/server/chunks/build/{settings-pNyPBXVa.mjs → settings-Du7YqF8i.mjs} +23 -10
  270. package/.output/server/chunks/build/settings-Du7YqF8i.mjs.map +1 -0
  271. package/.output/server/chunks/build/{settings-metadata-B0wo5R-W.mjs → settings-metadata-DrEqWcW-.mjs} +11 -2
  272. package/.output/server/chunks/build/settings-metadata-DrEqWcW-.mjs.map +1 -0
  273. package/.output/server/chunks/build/{storage-XelzuyPy.mjs → storage-B4vzxd8G.mjs} +41 -31
  274. package/.output/server/chunks/build/storage-B4vzxd8G.mjs.map +1 -0
  275. package/.output/server/chunks/build/styles.mjs +1 -0
  276. package/.output/server/chunks/build/{tags-DrCQ7QSw.mjs → tags-DauTe_F-.mjs} +22 -10
  277. package/.output/server/chunks/build/tags-DauTe_F-.mjs.map +1 -0
  278. package/.output/server/chunks/build/{test-cases-pmOxi-AN.mjs → test-cases-DUvaO1He.mjs} +38 -24
  279. package/.output/server/chunks/build/test-cases-DUvaO1He.mjs.map +1 -0
  280. package/.output/server/chunks/build/{timeout-hygiene-CNs71Iah.mjs → timeout-hygiene-CbnSaVbK.mjs} +20 -8
  281. package/.output/server/chunks/build/timeout-hygiene-CbnSaVbK.mjs.map +1 -0
  282. package/.output/server/chunks/build/{useAiStatus-ZO987RY7.mjs → useAiStatus-CWvIo32Q.mjs} +89 -89
  283. package/.output/server/chunks/build/useAiStatus-CWvIo32Q.mjs.map +1 -0
  284. package/.output/server/chunks/build/{useCopy-BQQKcwlq.mjs → useCopy-CeKWgHyT.mjs} +2 -2
  285. package/.output/server/chunks/build/useCopy-CeKWgHyT.mjs.map +1 -0
  286. package/.output/server/chunks/build/{PageStateCard-Bwee6JTk.mjs → useCopyRich-BemRsKgv.mjs} +418 -39
  287. package/.output/server/chunks/build/useCopyRich-BemRsKgv.mjs.map +1 -0
  288. package/.output/server/chunks/build/useDesktopDownload-D49JRQSw.mjs +46 -0
  289. package/.output/server/chunks/build/useDesktopDownload-D49JRQSw.mjs.map +1 -0
  290. package/.output/server/chunks/build/{useFormControl-BLpq1s4O.mjs → useFormControl-CZ9So7iX.mjs} +2 -2
  291. package/.output/server/chunks/build/useFormControl-CZ9So7iX.mjs.map +1 -0
  292. package/.output/server/chunks/build/{useOpenInIde-kMZ7Jw5c.mjs → useOpenInIde-4GFf-kdi.mjs} +2 -2
  293. package/.output/server/chunks/build/useOpenInIde-4GFf-kdi.mjs.map +1 -0
  294. package/.output/server/chunks/build/{useSettingsNav-NjI2seBy.mjs → useSettingsNav-C3O866KC.mjs} +6 -6
  295. package/.output/server/chunks/build/useSettingsNav-C3O866KC.mjs.map +1 -0
  296. package/.output/server/chunks/build/{useTreeViewCookie-DVYpxW-p.mjs → useTreeViewCookie-CQjQdTkH.mjs} +2 -2
  297. package/.output/server/chunks/build/useTreeViewCookie-CQjQdTkH.mjs.map +1 -0
  298. package/.output/server/chunks/build/{users-NmAUZs3i.mjs → users-CTUqXyGh.mjs} +22 -10
  299. package/.output/server/chunks/build/users-CTUqXyGh.mjs.map +1 -0
  300. package/.output/server/chunks/build/{virtualizer-ZaqK4guJ.mjs → virtualizer-Cd1hhlxC.mjs} +5 -5
  301. package/.output/server/chunks/build/virtualizer-Cd1hhlxC.mjs.map +1 -0
  302. package/.output/server/chunks/build/{wasted-time-CguAF9zc.mjs → wasted-time-lYkx5YO4.mjs} +26 -14
  303. package/.output/server/chunks/build/wasted-time-lYkx5YO4.mjs.map +1 -0
  304. package/.output/server/chunks/nitro/nitro.mjs +4914 -1102
  305. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  306. package/.output/server/chunks/routes/__piwi/session.get.mjs +13 -1
  307. package/.output/server/chunks/routes/__piwi/session.get.mjs.map +1 -1
  308. package/.output/server/chunks/routes/api/admin/cleanup.delete.mjs +12 -0
  309. package/.output/server/chunks/routes/api/admin/cleanup.delete.mjs.map +1 -1
  310. package/.output/server/chunks/routes/api/admin/stats.get.mjs +12 -0
  311. package/.output/server/chunks/routes/api/admin/stats.get.mjs.map +1 -1
  312. package/.output/server/chunks/routes/api/ai/status.get.mjs +12 -0
  313. package/.output/server/chunks/routes/api/ai/status.get.mjs.map +1 -1
  314. package/.output/server/chunks/routes/api/analytics/_widget_.get.mjs +12 -0
  315. package/.output/server/chunks/routes/api/analytics/_widget_.get.mjs.map +1 -1
  316. package/.output/server/chunks/routes/api/auth/change-password.post.mjs +12 -0
  317. package/.output/server/chunks/routes/api/auth/change-password.post.mjs.map +1 -1
  318. package/.output/server/chunks/routes/api/auth/forgot-password.post.mjs +12 -0
  319. package/.output/server/chunks/routes/api/auth/forgot-password.post.mjs.map +1 -1
  320. package/.output/server/chunks/routes/api/auth/login.post.mjs +12 -0
  321. package/.output/server/chunks/routes/api/auth/login.post.mjs.map +1 -1
  322. package/.output/server/chunks/routes/api/auth/logout.post.mjs +12 -0
  323. package/.output/server/chunks/routes/api/auth/logout.post.mjs.map +1 -1
  324. package/.output/server/chunks/routes/api/auth/me.get.mjs +12 -0
  325. package/.output/server/chunks/routes/api/auth/me.get.mjs.map +1 -1
  326. package/.output/server/chunks/routes/api/auth/oauth/_provider/callback.get.mjs +12 -0
  327. package/.output/server/chunks/routes/api/auth/oauth/_provider/callback.get.mjs.map +1 -1
  328. package/.output/server/chunks/routes/api/auth/oauth/_provider/login.get.mjs +12 -0
  329. package/.output/server/chunks/routes/api/auth/oauth/_provider/login.get.mjs.map +1 -1
  330. package/.output/server/chunks/routes/api/auth/oauth/_provider/unlink.post.mjs +12 -0
  331. package/.output/server/chunks/routes/api/auth/oauth/_provider/unlink.post.mjs.map +1 -1
  332. package/.output/server/chunks/routes/api/auth/reset-password.post.mjs +12 -0
  333. package/.output/server/chunks/routes/api/auth/reset-password.post.mjs.map +1 -1
  334. package/.output/server/chunks/routes/api/auth/send-verify-email.post.mjs +12 -0
  335. package/.output/server/chunks/routes/api/auth/send-verify-email.post.mjs.map +1 -1
  336. package/.output/server/chunks/routes/api/auth/setup.get.mjs +12 -0
  337. package/.output/server/chunks/routes/api/auth/setup.get.mjs.map +1 -1
  338. package/.output/server/chunks/routes/api/auth/setup.post.mjs +12 -0
  339. package/.output/server/chunks/routes/api/auth/setup.post.mjs.map +1 -1
  340. package/.output/server/chunks/routes/api/auth/verify-email.get.mjs +12 -0
  341. package/.output/server/chunks/routes/api/auth/verify-email.get.mjs.map +1 -1
  342. package/.output/server/chunks/routes/api/channels/_id/test.post.mjs +12 -0
  343. package/.output/server/chunks/routes/api/channels/_id/test.post.mjs.map +1 -1
  344. package/.output/server/chunks/routes/api/channels/_id_.delete.mjs +12 -0
  345. package/.output/server/chunks/routes/api/channels/_id_.delete.mjs.map +1 -1
  346. package/.output/server/chunks/routes/api/cluster-merge-suggestions/_id/approve.post.mjs +12 -0
  347. package/.output/server/chunks/routes/api/cluster-merge-suggestions/_id/approve.post.mjs.map +1 -1
  348. package/.output/server/chunks/routes/api/cluster-merge-suggestions/_id/reject.post.mjs +12 -0
  349. package/.output/server/chunks/routes/api/cluster-merge-suggestions/_id/reject.post.mjs.map +1 -1
  350. package/.output/server/chunks/routes/api/desktop/reporter-config.get.mjs +12 -0
  351. package/.output/server/chunks/routes/api/desktop/reporter-config.get.mjs.map +1 -1
  352. package/.output/server/chunks/routes/api/failure-clusters/_id/base-commit.patch.mjs +12 -0
  353. package/.output/server/chunks/routes/api/failure-clusters/_id/base-commit.patch.mjs.map +1 -1
  354. package/.output/server/chunks/routes/api/failure-clusters/_id/branches.get.mjs +12 -0
  355. package/.output/server/chunks/routes/api/failure-clusters/_id/branches.get.mjs.map +1 -1
  356. package/.output/server/chunks/routes/api/failure-clusters/_id/commit-diff.get.mjs +12 -0
  357. package/.output/server/chunks/routes/api/failure-clusters/_id/commit-diff.get.mjs.map +1 -1
  358. package/.output/server/chunks/routes/api/failure-clusters/_id/commits.get.mjs +12 -0
  359. package/.output/server/chunks/routes/api/failure-clusters/_id/commits.get.mjs.map +1 -1
  360. package/.output/server/chunks/routes/api/failure-clusters/_id/context.get.mjs +24 -1
  361. package/.output/server/chunks/routes/api/failure-clusters/_id/context.get.mjs.map +1 -1
  362. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnose/stream.post.mjs +13 -1
  363. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnose/stream.post.mjs.map +1 -1
  364. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnose.post.mjs +13 -1
  365. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnose.post.mjs.map +1 -1
  366. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnoses.get.mjs +13 -1
  367. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnoses.get.mjs.map +1 -1
  368. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnosis.get.mjs +13 -1
  369. package/.output/server/chunks/routes/api/failure-clusters/_id/diagnosis.get.mjs.map +1 -1
  370. package/.output/server/chunks/routes/api/failure-clusters/_id/export.get.mjs +64 -0
  371. package/.output/server/chunks/routes/api/failure-clusters/_id/export.get.mjs.map +1 -0
  372. package/.output/server/chunks/routes/api/failure-clusters/_id/extract-cases.post.mjs +13 -1
  373. package/.output/server/chunks/routes/api/failure-clusters/_id/extract-cases.post.mjs.map +1 -1
  374. package/.output/server/chunks/routes/api/failure-clusters/_id/fix-plan.get.mjs +56 -0
  375. package/.output/server/chunks/routes/api/failure-clusters/_id/fix-plan.get.mjs.map +1 -0
  376. package/.output/server/chunks/routes/api/failure-clusters/_id/status.patch.mjs +13 -1
  377. package/.output/server/chunks/routes/api/failure-clusters/_id/status.patch.mjs.map +1 -1
  378. package/.output/server/chunks/routes/api/failure-clusters/_id_.get.mjs +12 -0
  379. package/.output/server/chunks/routes/api/failure-clusters/_id_.get.mjs.map +1 -1
  380. package/.output/server/chunks/routes/api/failure-diagnoses/_id/feedback.patch.mjs +13 -1
  381. package/.output/server/chunks/routes/api/failure-diagnoses/_id/feedback.patch.mjs.map +1 -1
  382. package/.output/server/chunks/routes/api/files/_...path_.get.mjs +13 -32
  383. package/.output/server/chunks/routes/api/files/_...path_.get.mjs.map +1 -1
  384. package/.output/server/chunks/routes/api/health.get.mjs +13 -1
  385. package/.output/server/chunks/routes/api/health.get.mjs.map +1 -1
  386. package/.output/server/chunks/routes/api/index.get.mjs +12 -0
  387. package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
  388. package/.output/server/chunks/routes/api/index.get2.mjs +13 -1
  389. package/.output/server/chunks/routes/api/index.get2.mjs.map +1 -1
  390. package/.output/server/chunks/routes/api/index.get3.mjs +13 -1
  391. package/.output/server/chunks/routes/api/index.get3.mjs.map +1 -1
  392. package/.output/server/chunks/routes/api/index.get4.mjs +13 -1
  393. package/.output/server/chunks/routes/api/index.get4.mjs.map +1 -1
  394. package/.output/server/chunks/routes/api/index.get5.mjs +12 -0
  395. package/.output/server/chunks/routes/api/index.get5.mjs.map +1 -1
  396. package/.output/server/chunks/routes/api/index.post.mjs +12 -0
  397. package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
  398. package/.output/server/chunks/routes/api/index.post2.mjs +13 -1
  399. package/.output/server/chunks/routes/api/index.post2.mjs.map +1 -1
  400. package/.output/server/chunks/routes/api/index.post3.mjs +13 -1
  401. package/.output/server/chunks/routes/api/index.post3.mjs.map +1 -1
  402. package/.output/server/chunks/routes/api/index.post4.mjs +13 -1
  403. package/.output/server/chunks/routes/api/index.post4.mjs.map +1 -1
  404. package/.output/server/chunks/routes/api/index.post5.mjs +13 -1
  405. package/.output/server/chunks/routes/api/index.post5.mjs.map +1 -1
  406. package/.output/server/chunks/routes/api/index.post6.mjs +12 -0
  407. package/.output/server/chunks/routes/api/index.post6.mjs.map +1 -1
  408. package/.output/server/chunks/routes/api/links/_id/refresh.post.mjs +13 -1
  409. package/.output/server/chunks/routes/api/links/_id/refresh.post.mjs.map +1 -1
  410. package/.output/server/chunks/routes/api/links/_id_.delete.mjs +13 -1
  411. package/.output/server/chunks/routes/api/links/_id_.delete.mjs.map +1 -1
  412. package/.output/server/chunks/routes/api/links/_id_.patch.mjs +13 -1
  413. package/.output/server/chunks/routes/api/links/_id_.patch.mjs.map +1 -1
  414. package/.output/server/chunks/routes/api/markers/_id_.delete.mjs +13 -1
  415. package/.output/server/chunks/routes/api/markers/_id_.delete.mjs.map +1 -1
  416. package/.output/server/chunks/routes/api/markers/_id_.put.mjs +13 -1
  417. package/.output/server/chunks/routes/api/markers/_id_.put.mjs.map +1 -1
  418. package/.output/server/chunks/routes/api/notifications/stream.get.mjs +13 -1
  419. package/.output/server/chunks/routes/api/notifications/stream.get.mjs.map +1 -1
  420. package/.output/server/chunks/routes/api/projects/_id/cluster-merge-suggestions.get.mjs +13 -1
  421. package/.output/server/chunks/routes/api/projects/_id/cluster-merge-suggestions.get.mjs.map +1 -1
  422. package/.output/server/chunks/routes/api/projects/_id/failure-clusters.get.mjs +13 -1
  423. package/.output/server/chunks/routes/api/projects/_id/failure-clusters.get.mjs.map +1 -1
  424. package/.output/server/chunks/routes/api/projects/_id/flaky-classify.post.mjs +13 -1
  425. package/.output/server/chunks/routes/api/projects/_id/flaky-classify.post.mjs.map +1 -1
  426. package/.output/server/chunks/routes/api/projects/_id/flaky-tests.get.mjs +22 -2
  427. package/.output/server/chunks/routes/api/projects/_id/flaky-tests.get.mjs.map +1 -1
  428. package/.output/server/chunks/routes/api/projects/_id/latest-run.get.mjs +13 -1
  429. package/.output/server/chunks/routes/api/projects/_id/latest-run.get.mjs.map +1 -1
  430. package/.output/server/chunks/routes/api/projects/_id/markers.get.mjs +13 -1
  431. package/.output/server/chunks/routes/api/projects/_id/markers.get.mjs.map +1 -1
  432. package/.output/server/chunks/routes/api/projects/_id/markers.post.mjs +13 -1
  433. package/.output/server/chunks/routes/api/projects/_id/markers.post.mjs.map +1 -1
  434. package/.output/server/chunks/routes/api/projects/_id/members.get.mjs +13 -1
  435. package/.output/server/chunks/routes/api/projects/_id/members.get.mjs.map +1 -1
  436. package/.output/server/chunks/routes/api/projects/_id/members.put.mjs +13 -1
  437. package/.output/server/chunks/routes/api/projects/_id/members.put.mjs.map +1 -1
  438. package/.output/server/chunks/routes/api/projects/_id/performance.get.mjs +13 -1
  439. package/.output/server/chunks/routes/api/projects/_id/performance.get.mjs.map +1 -1
  440. package/.output/server/chunks/routes/api/projects/_id/quarantine/_testCaseId_.delete.mjs +58 -0
  441. package/.output/server/chunks/routes/api/projects/_id/quarantine/_testCaseId_.delete.mjs.map +1 -0
  442. package/.output/server/chunks/routes/api/projects/_id/quarantine.get.mjs +57 -0
  443. package/.output/server/chunks/routes/api/projects/_id/quarantine.get.mjs.map +1 -0
  444. package/.output/server/chunks/routes/api/projects/_id/quarantine.post.mjs +72 -0
  445. package/.output/server/chunks/routes/api/projects/_id/quarantine.post.mjs.map +1 -0
  446. package/.output/server/chunks/routes/api/projects/_id/slow-tests.get.mjs +13 -1
  447. package/.output/server/chunks/routes/api/projects/_id/slow-tests.get.mjs.map +1 -1
  448. package/.output/server/chunks/routes/api/projects/_id/spec-health.get.mjs +13 -1
  449. package/.output/server/chunks/routes/api/projects/_id/spec-health.get.mjs.map +1 -1
  450. package/.output/server/chunks/routes/api/projects/_id/test-cases.get.mjs +13 -1
  451. package/.output/server/chunks/routes/api/projects/_id/test-cases.get.mjs.map +1 -1
  452. package/.output/server/chunks/routes/api/projects/_id/timeout-opportunities.get.mjs +13 -1
  453. package/.output/server/chunks/routes/api/projects/_id/timeout-opportunities.get.mjs.map +1 -1
  454. package/.output/server/chunks/routes/api/projects/_id_.delete.mjs +13 -1
  455. package/.output/server/chunks/routes/api/projects/_id_.delete.mjs.map +1 -1
  456. package/.output/server/chunks/routes/api/projects/_id_.get.mjs +13 -1
  457. package/.output/server/chunks/routes/api/projects/_id_.get.mjs.map +1 -1
  458. package/.output/server/chunks/routes/api/projects/_id_.put.mjs +13 -1
  459. package/.output/server/chunks/routes/api/projects/_id_.put.mjs.map +1 -1
  460. package/.output/server/chunks/routes/api/projects/menu.get.mjs +13 -1
  461. package/.output/server/chunks/routes/api/projects/menu.get.mjs.map +1 -1
  462. package/.output/server/chunks/routes/api/projects/overview.get.mjs +13 -1
  463. package/.output/server/chunks/routes/api/projects/overview.get.mjs.map +1 -1
  464. package/.output/server/chunks/routes/api/projects.get.mjs +13 -1
  465. package/.output/server/chunks/routes/api/projects.get.mjs.map +1 -1
  466. package/.output/server/chunks/routes/api/search.get.mjs +13 -1
  467. package/.output/server/chunks/routes/api/search.get.mjs.map +1 -1
  468. package/.output/server/chunks/routes/api/settings/ai/limits.get.mjs +13 -1
  469. package/.output/server/chunks/routes/api/settings/ai/limits.get.mjs.map +1 -1
  470. package/.output/server/chunks/routes/api/settings/ai/limits.put.mjs +13 -1
  471. package/.output/server/chunks/routes/api/settings/ai/limits.put.mjs.map +1 -1
  472. package/.output/server/chunks/routes/api/settings/ai/models.post.mjs +12 -0
  473. package/.output/server/chunks/routes/api/settings/ai/models.post.mjs.map +1 -1
  474. package/.output/server/chunks/routes/api/settings/ai/test.post.mjs +13 -1
  475. package/.output/server/chunks/routes/api/settings/ai/test.post.mjs.map +1 -1
  476. package/.output/server/chunks/routes/api/settings/ai/usage.get.mjs +13 -1
  477. package/.output/server/chunks/routes/api/settings/ai/usage.get.mjs.map +1 -1
  478. package/.output/server/chunks/routes/api/settings/ai.get.mjs +13 -1
  479. package/.output/server/chunks/routes/api/settings/ai.get.mjs.map +1 -1
  480. package/.output/server/chunks/routes/api/settings/ai.put.mjs +13 -1
  481. package/.output/server/chunks/routes/api/settings/ai.put.mjs.map +1 -1
  482. package/.output/server/chunks/routes/api/settings/pr-feedback.get.mjs +57 -0
  483. package/.output/server/chunks/routes/api/settings/pr-feedback.get.mjs.map +1 -0
  484. package/.output/server/chunks/routes/api/settings/pr-feedback.put.mjs +63 -0
  485. package/.output/server/chunks/routes/api/settings/pr-feedback.put.mjs.map +1 -0
  486. package/.output/server/chunks/routes/api/settings/smtp/test.post.mjs +12 -0
  487. package/.output/server/chunks/routes/api/settings/smtp/test.post.mjs.map +1 -1
  488. package/.output/server/chunks/routes/api/settings/smtp.get.mjs +13 -1
  489. package/.output/server/chunks/routes/api/settings/smtp.get.mjs.map +1 -1
  490. package/.output/server/chunks/routes/api/settings/timeout-hygiene.get.mjs +13 -1
  491. package/.output/server/chunks/routes/api/settings/timeout-hygiene.get.mjs.map +1 -1
  492. package/.output/server/chunks/routes/api/settings/timeout-hygiene.put.mjs +13 -1
  493. package/.output/server/chunks/routes/api/settings/timeout-hygiene.put.mjs.map +1 -1
  494. package/.output/server/chunks/routes/api/settings/wasted-waits.get.mjs +13 -1
  495. package/.output/server/chunks/routes/api/settings/wasted-waits.get.mjs.map +1 -1
  496. package/.output/server/chunks/routes/api/settings/wasted-waits.put.mjs +13 -1
  497. package/.output/server/chunks/routes/api/settings/wasted-waits.put.mjs.map +1 -1
  498. package/.output/server/chunks/routes/api/stream.get.mjs +13 -1
  499. package/.output/server/chunks/routes/api/stream.get.mjs.map +1 -1
  500. package/.output/server/chunks/routes/api/subscriptions/_id_.delete.mjs +13 -1
  501. package/.output/server/chunks/routes/api/subscriptions/_id_.delete.mjs.map +1 -1
  502. package/.output/server/chunks/routes/api/subscriptions/_id_.patch.mjs +13 -1
  503. package/.output/server/chunks/routes/api/subscriptions/_id_.patch.mjs.map +1 -1
  504. package/.output/server/chunks/routes/api/tags/_id_.delete.mjs +13 -1
  505. package/.output/server/chunks/routes/api/tags/_id_.delete.mjs.map +1 -1
  506. package/.output/server/chunks/routes/api/tags/_id_.put.mjs +13 -1
  507. package/.output/server/chunks/routes/api/tags/_id_.put.mjs.map +1 -1
  508. package/.output/server/chunks/routes/api/test-cases/_id/history.get.mjs +13 -1
  509. package/.output/server/chunks/routes/api/test-cases/_id/history.get.mjs.map +1 -1
  510. package/.output/server/chunks/routes/api/test-cases/_id/stability-trend.get.mjs +13 -1
  511. package/.output/server/chunks/routes/api/test-cases/_id/stability-trend.get.mjs.map +1 -1
  512. package/.output/server/chunks/routes/api/test-cases/_id_.get.mjs +13 -1
  513. package/.output/server/chunks/routes/api/test-cases/_id_.get.mjs.map +1 -1
  514. package/.output/server/chunks/routes/api/test-run-cases/_id/diagnose.post.mjs +13 -1
  515. package/.output/server/chunks/routes/api/test-run-cases/_id/diagnose.post.mjs.map +1 -1
  516. package/.output/server/chunks/routes/api/test-run-cases/_id/diagnosis-context.get.mjs +25 -3
  517. package/.output/server/chunks/routes/api/test-run-cases/_id/diagnosis-context.get.mjs.map +1 -1
  518. package/.output/server/chunks/routes/api/test-run-cases/_id/diagnosis.get.mjs +13 -1
  519. package/.output/server/chunks/routes/api/test-run-cases/_id/diagnosis.get.mjs.map +1 -1
  520. package/.output/server/chunks/routes/api/test-run-cases/_id/export.get.mjs +60 -0
  521. package/.output/server/chunks/routes/api/test-run-cases/_id/export.get.mjs.map +1 -0
  522. package/.output/server/chunks/routes/api/test-run-cases/_id/traces.get.mjs +13 -1
  523. package/.output/server/chunks/routes/api/test-run-cases/_id/traces.get.mjs.map +1 -1
  524. package/.output/server/chunks/routes/api/test-run-cases/_id_.get.mjs +13 -1
  525. package/.output/server/chunks/routes/api/test-run-cases/_id_.get.mjs.map +1 -1
  526. package/.output/server/chunks/routes/api/test-runs/_id/begin.post.mjs +13 -1
  527. package/.output/server/chunks/routes/api/test-runs/_id/begin.post.mjs.map +1 -1
  528. package/.output/server/chunks/routes/api/test-runs/_id/case-files.post.mjs +13 -1
  529. package/.output/server/chunks/routes/api/test-runs/_id/case-files.post.mjs.map +1 -1
  530. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/dom-snapshot.get.mjs +13 -1
  531. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/dom-snapshot.get.mjs.map +1 -1
  532. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/environment-diff.get.mjs +13 -1
  533. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/environment-diff.get.mjs.map +1 -1
  534. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/locator-healing.get.mjs +13 -1
  535. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/locator-healing.get.mjs.map +1 -1
  536. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/locator-pick.post.mjs +13 -1
  537. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/locator-pick.post.mjs.map +1 -1
  538. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-network-body.get.mjs +13 -1
  539. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-network-body.get.mjs.map +1 -1
  540. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-network.get.mjs +13 -1
  541. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-network.get.mjs.map +1 -1
  542. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-stacks.get.mjs +13 -1
  543. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-stacks.get.mjs.map +1 -1
  544. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/visual-diff.get.mjs +13 -1
  545. package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/visual-diff.get.mjs.map +1 -1
  546. package/.output/server/chunks/routes/api/test-runs/_id/events.post.mjs +13 -1
  547. package/.output/server/chunks/routes/api/test-runs/_id/events.post.mjs.map +1 -1
  548. package/.output/server/chunks/routes/api/test-runs/_id/failure-groups.get.mjs +13 -1
  549. package/.output/server/chunks/routes/api/test-runs/_id/failure-groups.get.mjs.map +1 -1
  550. package/.output/server/chunks/routes/api/test-runs/_id/finish.post.mjs +15 -1
  551. package/.output/server/chunks/routes/api/test-runs/_id/finish.post.mjs.map +1 -1
  552. package/.output/server/chunks/routes/api/test-runs/_id/gate.post.mjs +196 -0
  553. package/.output/server/chunks/routes/api/test-runs/_id/gate.post.mjs.map +1 -0
  554. package/.output/server/chunks/routes/api/test-runs/_id/heartbeat.post.mjs +13 -1
  555. package/.output/server/chunks/routes/api/test-runs/_id/heartbeat.post.mjs.map +1 -1
  556. package/.output/server/chunks/routes/api/test-runs/_id/insights.get.mjs +13 -1
  557. package/.output/server/chunks/routes/api/test-runs/_id/insights.get.mjs.map +1 -1
  558. package/.output/server/chunks/routes/api/test-runs/_id/network-requests.get.mjs +13 -1
  559. package/.output/server/chunks/routes/api/test-runs/_id/network-requests.get.mjs.map +1 -1
  560. package/.output/server/chunks/routes/api/test-runs/_id/regression-context.get.mjs +13 -1
  561. package/.output/server/chunks/routes/api/test-runs/_id/regression-context.get.mjs.map +1 -1
  562. package/.output/server/chunks/routes/api/test-runs/_id/stream.get.mjs +13 -1
  563. package/.output/server/chunks/routes/api/test-runs/_id/stream.get.mjs.map +1 -1
  564. package/.output/server/chunks/routes/api/test-runs/_id/summary.get.mjs +13 -1
  565. package/.output/server/chunks/routes/api/test-runs/_id/summary.get.mjs.map +1 -1
  566. package/.output/server/chunks/routes/api/test-runs/_id_.delete.mjs +13 -1
  567. package/.output/server/chunks/routes/api/test-runs/_id_.delete.mjs.map +1 -1
  568. package/.output/server/chunks/routes/api/test-runs/_id_.get.mjs +13 -1
  569. package/.output/server/chunks/routes/api/test-runs/_id_.get.mjs.map +1 -1
  570. package/.output/server/chunks/routes/api/test-runs/_id_.patch.mjs +13 -1
  571. package/.output/server/chunks/routes/api/test-runs/_id_.patch.mjs.map +1 -1
  572. package/.output/server/chunks/routes/api/test-runs/import/check.post.mjs +78 -0
  573. package/.output/server/chunks/routes/api/test-runs/import/check.post.mjs.map +1 -0
  574. package/.output/server/chunks/routes/api/test-runs/import.post.mjs +201 -0
  575. package/.output/server/chunks/routes/api/test-runs/import.post.mjs.map +1 -0
  576. package/.output/server/chunks/routes/api/test-runs/recent.get.mjs +13 -1
  577. package/.output/server/chunks/routes/api/test-runs/recent.get.mjs.map +1 -1
  578. package/.output/server/chunks/routes/api/test-runs/setup.post.mjs +13 -1
  579. package/.output/server/chunks/routes/api/test-runs/setup.post.mjs.map +1 -1
  580. package/.output/server/chunks/routes/api/test-runs/start.post.mjs +13 -1
  581. package/.output/server/chunks/routes/api/test-runs/start.post.mjs.map +1 -1
  582. package/.output/server/chunks/routes/api/test-runs/submit.post.mjs +32 -15
  583. package/.output/server/chunks/routes/api/test-runs/submit.post.mjs.map +1 -1
  584. package/.output/server/chunks/routes/api/test-runs/upload.post.mjs +21 -6
  585. package/.output/server/chunks/routes/api/test-runs/upload.post.mjs.map +1 -1
  586. package/.output/server/chunks/routes/api/tests/cleanup.delete.mjs +154 -3
  587. package/.output/server/chunks/routes/api/tests/cleanup.delete.mjs.map +1 -1
  588. package/.output/server/chunks/routes/api/traces/check.post.mjs +13 -1
  589. package/.output/server/chunks/routes/api/traces/check.post.mjs.map +1 -1
  590. package/.output/server/chunks/routes/api/users/_id/api-keys/_keyId_.delete.mjs +12 -0
  591. package/.output/server/chunks/routes/api/users/_id/api-keys/_keyId_.delete.mjs.map +1 -1
  592. package/.output/server/chunks/routes/api/users/_id/index.get.mjs +12 -0
  593. package/.output/server/chunks/routes/api/users/_id/index.get.mjs.map +1 -1
  594. package/.output/server/chunks/routes/api/users/_id/index.post.mjs +13 -1
  595. package/.output/server/chunks/routes/api/users/_id/index.post.mjs.map +1 -1
  596. package/.output/server/chunks/routes/api/users/_id/invite.post.mjs +13 -1
  597. package/.output/server/chunks/routes/api/users/_id/invite.post.mjs.map +1 -1
  598. package/.output/server/chunks/routes/api/users/_id/projects.get.mjs +13 -1
  599. package/.output/server/chunks/routes/api/users/_id/projects.get.mjs.map +1 -1
  600. package/.output/server/chunks/routes/api/users/_id/projects.put.mjs +13 -1
  601. package/.output/server/chunks/routes/api/users/_id/projects.put.mjs.map +1 -1
  602. package/.output/server/chunks/routes/api/users/_id_.delete.mjs +12 -0
  603. package/.output/server/chunks/routes/api/users/_id_.delete.mjs.map +1 -1
  604. package/.output/server/chunks/routes/api/users/_id_.patch.mjs +12 -0
  605. package/.output/server/chunks/routes/api/users/_id_.patch.mjs.map +1 -1
  606. package/.output/server/chunks/routes/api/version.get.mjs +13 -1
  607. package/.output/server/chunks/routes/api/version.get.mjs.map +1 -1
  608. package/.output/server/chunks/routes/mcp.post.mjs +13 -1
  609. package/.output/server/chunks/routes/mcp.post.mjs.map +1 -1
  610. package/.output/server/chunks/routes/renderer.mjs +1 -1
  611. package/.output/server/chunks/tasks/sweep.mjs +12 -0
  612. package/.output/server/chunks/tasks/sweep.mjs.map +1 -1
  613. package/.output/server/chunks/tasks/sweep2.mjs +12 -0
  614. package/.output/server/chunks/tasks/sweep2.mjs.map +1 -1
  615. package/.output/server/database/migrations/0039_remarkable_jean_grey.sql +2 -0
  616. package/.output/server/database/migrations/0040_organic_phalanx.sql +8 -0
  617. package/.output/server/database/migrations/0041_tense_gravity.sql +5 -0
  618. package/.output/server/database/migrations/0042_burly_hemingway.sql +19 -0
  619. package/.output/server/database/migrations/meta/0039_snapshot.json +3403 -0
  620. package/.output/server/database/migrations/meta/0040_snapshot.json +3457 -0
  621. package/.output/server/database/migrations/meta/0041_snapshot.json +3492 -0
  622. package/.output/server/database/migrations/meta/0042_snapshot.json +3618 -0
  623. package/.output/server/database/migrations/meta/_journal.json +28 -0
  624. package/.output/server/database/migrations-pg/0040_lazy_layla_miller.sql +2 -0
  625. package/.output/server/database/migrations-pg/0041_light_screwball.sql +8 -0
  626. package/.output/server/database/migrations-pg/0042_serious_layla_miller.sql +5 -0
  627. package/.output/server/database/migrations-pg/0043_wonderful_mordo.sql +19 -0
  628. package/.output/server/database/migrations-pg/meta/0040_snapshot.json +4060 -0
  629. package/.output/server/database/migrations-pg/meta/0041_snapshot.json +4123 -0
  630. package/.output/server/database/migrations-pg/meta/0042_snapshot.json +4153 -0
  631. package/.output/server/database/migrations-pg/meta/0043_snapshot.json +4308 -0
  632. package/.output/server/database/migrations-pg/meta/_journal.json +28 -0
  633. package/.output/server/index.mjs +13 -1
  634. package/.output/server/index.mjs.map +1 -1
  635. package/.output/server/node_modules/fflate/esm/index.mjs +2710 -0
  636. package/.output/server/node_modules/fflate/package.json +128 -0
  637. package/.output/server/node_modules/highlight.js/es/languages/yaml.js +213 -0
  638. package/.output/server/node_modules/marked/lib/marked.esm.js +72 -0
  639. package/.output/server/node_modules/marked/package.json +103 -0
  640. package/.output/server/package.json +3 -1
  641. package/package.json +2 -2
  642. package/.output/public/_nuxt/36cXPVrY.js +0 -26
  643. package/.output/public/_nuxt/87SGk1nu.js +0 -1
  644. package/.output/public/_nuxt/B6rt3IcG.js +0 -1
  645. package/.output/public/_nuxt/BAaSmp8J.js +0 -1
  646. package/.output/public/_nuxt/BBnX5xw4.js +0 -2
  647. package/.output/public/_nuxt/BCArQk0c.js +0 -1
  648. package/.output/public/_nuxt/BFjmLXYo.js +0 -8
  649. package/.output/public/_nuxt/BJltXwHg.js +0 -1
  650. package/.output/public/_nuxt/BUMZHDRC.js +0 -2
  651. package/.output/public/_nuxt/BdHdHyop.js +0 -34
  652. package/.output/public/_nuxt/BiX7c2qU.js +0 -1
  653. package/.output/public/_nuxt/C11lmBd4.js +0 -4
  654. package/.output/public/_nuxt/C4AfzZER.js +0 -47
  655. package/.output/public/_nuxt/C7ZVzS0K.js +0 -1
  656. package/.output/public/_nuxt/C8cz5feG.js +0 -1
  657. package/.output/public/_nuxt/C9EpbPNU.js +0 -1
  658. package/.output/public/_nuxt/C9ahP7km.js +0 -1
  659. package/.output/public/_nuxt/CBEM3L1q.js +0 -4
  660. package/.output/public/_nuxt/CCsl9MOZ.js +0 -1
  661. package/.output/public/_nuxt/CCw3Tx4S.js +0 -1
  662. package/.output/public/_nuxt/CGq9qR-0.js +0 -1
  663. package/.output/public/_nuxt/CLdGRzLL.js +0 -1
  664. package/.output/public/_nuxt/CTgM5Fke.js +0 -2
  665. package/.output/public/_nuxt/CU3W9YrI.js +0 -1
  666. package/.output/public/_nuxt/CYIR2GbL.js +0 -1
  667. package/.output/public/_nuxt/Ccit_CX1.js +0 -1
  668. package/.output/public/_nuxt/CiPH-swI.js +0 -1
  669. package/.output/public/_nuxt/ClVRQpP_.js +0 -1
  670. package/.output/public/_nuxt/CmbjAoQu.js +0 -1
  671. package/.output/public/_nuxt/Cx65B3c3.js +0 -1
  672. package/.output/public/_nuxt/D1ttGJfs.js +0 -5
  673. package/.output/public/_nuxt/D3SYPlEB.js +0 -114
  674. package/.output/public/_nuxt/DB3ljns7.js +0 -1
  675. package/.output/public/_nuxt/DC51KKt4.js +0 -1
  676. package/.output/public/_nuxt/DaewB_zT.js +0 -1
  677. package/.output/public/_nuxt/DcfRfTaA.js +0 -34
  678. package/.output/public/_nuxt/Dm1_3W9g.js +0 -1
  679. package/.output/public/_nuxt/DraETso1.js +0 -1
  680. package/.output/public/_nuxt/Dy4TloG3.js +0 -1
  681. package/.output/public/_nuxt/EltzgiyS.js +0 -1
  682. package/.output/public/_nuxt/HTQtMbWb.js +0 -1
  683. package/.output/public/_nuxt/KYucVFu7.js +0 -1
  684. package/.output/public/_nuxt/TBDx0s9p.js +0 -3
  685. package/.output/public/_nuxt/Tt5LX5Y-.js +0 -1
  686. package/.output/public/_nuxt/builds/meta/2f517ae9-c342-457e-b4c5-6301728179f5.json +0 -1
  687. package/.output/public/_nuxt/entry.ChQMshd4.css +0 -1
  688. package/.output/public/_nuxt/l0QnzFNM.js +0 -1
  689. package/.output/public/_nuxt/oFIS9u6t.js +0 -3
  690. package/.output/public/_nuxt/oWY3I9uX.js +0 -1
  691. package/.output/public/_nuxt/q0DPzLKN.js +0 -2
  692. package/.output/public/_nuxt/r3SBLxtE.js +0 -1
  693. package/.output/public/_nuxt/riEUDnED.js +0 -1
  694. package/.output/public/_nuxt/uaqMzXqE.js +0 -5
  695. package/.output/public/_nuxt/wgcgHmRR.js +0 -1
  696. package/.output/public/sw.js +0 -1
  697. package/.output/public/workbox-2fbc6a65.js +0 -1
  698. package/.output/server/chunks/build/Alert-Bp1Wz_sq.mjs.map +0 -1
  699. package/.output/server/chunks/build/Breadcrumb-C9ZPTLym.mjs.map +0 -1
  700. package/.output/server/chunks/build/BreadcrumbNav-C3y42Vun.mjs.map +0 -1
  701. package/.output/server/chunks/build/BrowserBadge-DNCp9pF-.mjs.map +0 -1
  702. package/.output/server/chunks/build/ChartCard-Fr557IbV.mjs.map +0 -1
  703. package/.output/server/chunks/build/Checkbox-cVOSIY93.mjs.map +0 -1
  704. package/.output/server/chunks/build/CiEnvCard-DXPOhdSG.mjs.map +0 -1
  705. package/.output/server/chunks/build/CodeBlock-BGwNmJ8J.mjs.map +0 -1
  706. package/.output/server/chunks/build/DashboardNavbar-Bdp-OwTN.mjs.map +0 -1
  707. package/.output/server/chunks/build/DashboardSidebarToggle-Ji6ADuqF.mjs.map +0 -1
  708. package/.output/server/chunks/build/DataLocationCard-D6xSOrme.mjs.map +0 -1
  709. package/.output/server/chunks/build/DiagnosisPanel-DV1xwGu4.mjs.map +0 -1
  710. package/.output/server/chunks/build/EmptyState-DV3oT_xz.mjs.map +0 -1
  711. package/.output/server/chunks/build/EntityLinks-DeOP13Kr.mjs.map +0 -1
  712. package/.output/server/chunks/build/EnvManagedBadge-Qpn58Nmr.mjs.map +0 -1
  713. package/.output/server/chunks/build/FormField-B-GSn_VR.mjs.map +0 -1
  714. package/.output/server/chunks/build/HelpHint-YEMWtKu1.mjs.map +0 -1
  715. package/.output/server/chunks/build/Label-DBvbHd3A.mjs.map +0 -1
  716. package/.output/server/chunks/build/MiniRunBars-C3HG-EYm.mjs.map +0 -1
  717. package/.output/server/chunks/build/Modal-CfA78Hm1.mjs.map +0 -1
  718. package/.output/server/chunks/build/PageStateCard-Bwee6JTk.mjs.map +0 -1
  719. package/.output/server/chunks/build/ProjectTestCasesTable-9Ia825h8.mjs.map +0 -1
  720. package/.output/server/chunks/build/RovingFocusItem-CxhHdNGo.mjs.map +0 -1
  721. package/.output/server/chunks/build/RunReports-BpJqLHY9.mjs.map +0 -1
  722. package/.output/server/chunks/build/RunStatusBadge-BhmJ_RKM.mjs.map +0 -1
  723. package/.output/server/chunks/build/SectionCard-COd9TuDq.mjs.map +0 -1
  724. package/.output/server/chunks/build/Select-ppPz926C.mjs.map +0 -1
  725. package/.output/server/chunks/build/Separator-CxZdx8kw.mjs.map +0 -1
  726. package/.output/server/chunks/build/SettingsField-DDD4oqys.mjs.map +0 -1
  727. package/.output/server/chunks/build/Slideover-B95Rj237.mjs.map +0 -1
  728. package/.output/server/chunks/build/Switch-xQQ3_ME1.mjs.map +0 -1
  729. package/.output/server/chunks/build/Table-CPhhVzDv.mjs.map +0 -1
  730. package/.output/server/chunks/build/Tabs-BV9XqjoO.mjs.map +0 -1
  731. package/.output/server/chunks/build/TagBadge-BDcvvGxw.mjs +0 -47
  732. package/.output/server/chunks/build/TagBadge-BDcvvGxw.mjs.map +0 -1
  733. package/.output/server/chunks/build/TestCaseHistoryChart-DMb-xSJa.mjs.map +0 -1
  734. package/.output/server/chunks/build/TestStatusBar-CEzt76wk.mjs.map +0 -1
  735. package/.output/server/chunks/build/Textarea-DrrqQUVG.mjs.map +0 -1
  736. package/.output/server/chunks/build/Tooltip-7vwuDPrZ.mjs.map +0 -1
  737. package/.output/server/chunks/build/VisuallyHiddenInput-C9eJVpPW.mjs.map +0 -1
  738. package/.output/server/chunks/build/_id_-B2yirIuA.mjs.map +0 -1
  739. package/.output/server/chunks/build/_id_-CE0Gso6i.mjs.map +0 -1
  740. package/.output/server/chunks/build/_id_-bWcP2xFl.mjs.map +0 -1
  741. package/.output/server/chunks/build/about-CoJjvUwM.mjs.map +0 -1
  742. package/.output/server/chunks/build/account-Cn-eZqXM.mjs.map +0 -1
  743. package/.output/server/chunks/build/db.client-aHcD0wyX.mjs.map +0 -1
  744. package/.output/server/chunks/build/default-BSzdkM_L.mjs.map +0 -1
  745. package/.output/server/chunks/build/edit-C9Z7oZeu.mjs.map +0 -1
  746. package/.output/server/chunks/build/fetch-8kznMtBM.mjs.map +0 -1
  747. package/.output/server/chunks/build/forgot-password-BqPF4Rxs.mjs.map +0 -1
  748. package/.output/server/chunks/build/help-content-DmFnuhNu.mjs.map +0 -1
  749. package/.output/server/chunks/build/index-BR9hw6qk.mjs.map +0 -1
  750. package/.output/server/chunks/build/index-Ba-Fifra.mjs.map +0 -1
  751. package/.output/server/chunks/build/index-CULN3-en.mjs.map +0 -1
  752. package/.output/server/chunks/build/index-DVUtBexc.mjs.map +0 -1
  753. package/.output/server/chunks/build/isValueEqualOrExist-DBZjbD_3.mjs.map +0 -1
  754. package/.output/server/chunks/build/login-D2XZDuek.mjs.map +0 -1
  755. package/.output/server/chunks/build/mcp-_o6cMS6m.mjs.map +0 -1
  756. package/.output/server/chunks/build/notifications-Dzm9c0u_.mjs.map +0 -1
  757. package/.output/server/chunks/build/reset-password-gpFzIEDj.mjs.map +0 -1
  758. package/.output/server/chunks/build/settings-metadata-B0wo5R-W.mjs.map +0 -1
  759. package/.output/server/chunks/build/settings-pNyPBXVa.mjs.map +0 -1
  760. package/.output/server/chunks/build/storage-XelzuyPy.mjs.map +0 -1
  761. package/.output/server/chunks/build/tags-DrCQ7QSw.mjs.map +0 -1
  762. package/.output/server/chunks/build/test-cases-pmOxi-AN.mjs.map +0 -1
  763. package/.output/server/chunks/build/timeout-hygiene-CNs71Iah.mjs.map +0 -1
  764. package/.output/server/chunks/build/useAiStatus-ZO987RY7.mjs.map +0 -1
  765. package/.output/server/chunks/build/useCopy-BQQKcwlq.mjs.map +0 -1
  766. package/.output/server/chunks/build/useFormControl-BLpq1s4O.mjs.map +0 -1
  767. package/.output/server/chunks/build/useOpenInIde-kMZ7Jw5c.mjs.map +0 -1
  768. package/.output/server/chunks/build/useSettingsNav-NjI2seBy.mjs.map +0 -1
  769. package/.output/server/chunks/build/useTreeViewCookie-DVYpxW-p.mjs.map +0 -1
  770. package/.output/server/chunks/build/users-NmAUZs3i.mjs.map +0 -1
  771. package/.output/server/chunks/build/virtualizer-ZaqK4guJ.mjs.map +0 -1
  772. package/.output/server/chunks/build/wasted-time-CguAF9zc.mjs.map +0 -1
  773. /package/.output/public/_nuxt/{PageStateCard.BrM5HWjY.css → useCopyRich.BrM5HWjY.css} +0 -0
@@ -1,34 +0,0 @@
1
- import{b as se,B as V,C as be,al as ke,r as h,h as Q,am as Ce,J as qe,d as re,o as p,f as H,g as D,j as g,_ as le,m as k,i as l,q as T,l as _e,k as e,E as We,c as $,v as we,t as j,F as K,y as ie,p as Z,x as Ve,G as Je}from"./D3SYPlEB.js";import{_ as Ye}from"./C8cz5feG.js";import{_ as Ge}from"./DB3ljns7.js";import{c as Xe,m as Ke,i as Qe,e as Ze,h as et,f as tt,g as st,j as nt}from"./36cXPVrY.js";import{u as ot}from"./D3MWm6JP.js";import{_ as at}from"./DnThe2U0.js";import{f as $e,w as it,k as rt}from"./BUMZHDRC.js";import{_ as lt}from"./B6IHiVa1.js";import{u as ct}from"./BuuvTH9e.js";const ut=globalThis.setInterval,ce=Symbol("cluster-diagnosis");function dt(v){const a=se(),u=h(""),d=h(""),x=h([]),y=h([]),I=Q(()=>!!d.value),O=h(null),R=h([]),U=h(0),P=h(0),M=h(null),f=h(null),r=h(!1),t=h(null),o=h(!1);let s=null,i=null,m=!0;function S(){const c={};return u.value.trim()&&(c.baseCommit=u.value.trim()),x.value.length&&(c.selectedCommitShas=x.value),c}async function C(){r.value=!0;try{const c=await $fetch(`/api/failure-clusters/${v}/context`,{query:{...S(),format:"json"}});O.value=c.text,R.value=c.sections,U.value=c.tokenEstimate,P.value=c.imageTokenEstimate??0,M.value=c.coverage,f.value=c.scmChanges??null}catch{O.value="(failed to load context)",R.value=[],U.value=0,P.value=0,M.value=null,f.value=null}finally{r.value=!1}}async function A(c){try{await $fetch(`/api/failure-clusters/${v}/base-commit`,{method:"PATCH",body:{commit:c||null}}),d.value=c}catch{}}function z(){s&&(clearInterval(s),s=null)}function w(){if(s)return;let c=0;s=ut(async()=>{c+=3e3,await W(),(!t.value||t.value.status!=="running"||c>=12e4)&&z()},3e3)}async function W(){try{const c=await $fetch(`/api/failure-clusters/${v}/diagnosis`);t.value=c.diagnosis}catch{}}async function J(c={}){o.value=!0;try{const E=c.force?`/api/failure-clusters/${v}/diagnose?force=true`:`/api/failure-clusters/${v}/diagnose`,F={};c.additionalContext&&(F.additionalContext=c.additionalContext),u.value.trim()&&(F.baseCommit=u.value.trim()),x.value.length&&(F.selectedCommitShas=x.value),c.images?.length&&(F.images=c.images),t.value=await $fetch(E,{method:"POST",body:Object.keys(F).length?F:void 0}),t.value?.status==="running"&&w()}catch(E){E?.statusCode===409?w():a.add({title:"Diagnosis failed",description:String(E?.message??E),color:"error"})}finally{o.value=!1}}return V(u,c=>{m||(i&&clearTimeout(i),i=setTimeout(()=>C(),900),c!==d.value&&A(c))}),V(x,()=>{m||C()},{deep:!0}),V(t,c=>{c?.status==="running"?w():z()}),be(async()=>{try{const c=await $fetch(`/api/failure-clusters/${v}/diagnosis`);t.value=c.diagnosis,c.manualBaseCommit&&(d.value=c.manualBaseCommit,u.value=c.manualBaseCommit);const E=c.diagnosis?.details;E?.selectedCommitShas&&Array.isArray(E.selectedCommitShas)&&(x.value=E.selectedCommitShas),E?.autoSelectedCommits&&Array.isArray(E.autoSelectedCommits)&&(y.value=E.autoSelectedCommits)}catch{}m=!1,C(),t.value?.status==="running"&&w()}),ke(()=>{z(),i&&clearTimeout(i)}),{clusterId:v,baseCommit:u,savedBaseCommit:d,selectedCommitShas:x,autoSelectedCommits:y,baseCommitIsPinned:I,contextText:O,contextSections:R,tokenEstimate:U,imageTokenEstimate:P,coverage:M,scmChanges:f,contextLoading:r,refreshContext:C,diagnosis:t,posting:o,runDiagnosis:J}}function ft(v){const a=dt(v);return qe(ce,a),a}function Os(){const v=Ce(ce);if(!v)throw new Error("useClusterDiagnosis() must be used under a page that called provideClusterDiagnosis()");return v}function pt(v){const a=Ce(ce,null);if(a)return a;if(v==null)throw new Error("useOrProvideClusterDiagnosis() requires a clusterId when used outside provideClusterDiagnosis()");return ft(v)}const mt={class:"w-56 p-1 space-y-0.5"},gt=re({__name:"DiagnosisExportMenu",props:{contextText:{},diagnosis:{},screenshots:{},clusterSignature:{},clusterUrl:{},clusterOccurrences:{},clusterErrorType:{},sampleError:{}},setup(v){const a=v,{copy:u}=ot(),{copyRich:d}=Xe(),x=h(!1);function y(){const t=[];return a.clusterErrorType&&t.push(a.clusterErrorType),a.clusterOccurrences&&t.push(`${a.clusterOccurrences} occurrence${a.clusterOccurrences===1?"":"s"}`),t.join(" · ")}function I(){const t=a.clusterSignature??"Failure cluster",o=y(),s=a.diagnosis?.status==="completed"&&a.diagnosis.summary?`AI diagnosis (${a.diagnosis.category??"unknown"}, ${a.diagnosis.confidence??"?"}): ${a.diagnosis.summary}`:null,i=[`🔍 Investigation: ${t}`,o||null,"",...a.sampleError?["Error:",Ke(a.sampleError),""]:[],...s?[s,""]:[],a.clusterUrl?`Cluster: ${a.clusterUrl}`:null].filter(C=>C!==null).join(`
2
- `),m=C=>C.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),S=[`<p><strong>🔍 Investigation: <code>${m(t)}</code></strong></p>`,o?`<p><em>${m(o)}</em></p>`:"",a.sampleError?`<p><strong>Error:</strong></p><pre>${m(a.sampleError)}</pre>`:"",s?`<p><strong>AI diagnosis</strong> (${m(a.diagnosis?.category??"")}, ${m(a.diagnosis?.confidence??"")}):<br>${m(a.diagnosis.summary)}</p>`:"",a.clusterUrl?`<p>🔗 <a href="${a.clusterUrl}">View cluster</a></p>`:""].join("");d(i,S,{toast:"Investigation summary copied"}),x.value=!1}function O(){if(!a.contextText)return;const o=(a.screenshots?.length?`## Screenshots
3
-
4
- ${a.screenshots.map(s=>`![${s.name}](data:${s.mediaType};base64,${s.data})`).join(`
5
-
6
- `)}
7
-
8
- `:"")+"```\n"+a.contextText+"\n```";u(o,{toast:"AI context (Markdown) copied"}),x.value=!1}function R(){if(!a.contextText)return;const t=JSON.stringify({text:a.contextText,exportedAt:new Date().toISOString()},null,2);u(t,{toast:"AI context (JSON) copied"}),x.value=!1}function U(t){const o=w=>w.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),s=[];let i=!1,m="";const S=[];let C=!1;function A(){if(S.length){const w=m?` class="language-${o(m)}"`:"";s.push(`<pre><code${w}>${o(S.join(`
9
- `))}</code></pre>`),S.length=0}m=""}function z(){C&&(s.push("</ul>"),C=!1)}for(const w of t.split(`
10
- `)){if(w.startsWith("```")){z(),i?(A(),i=!1):(A(),i=!0,m=w.slice(3).trim());continue}if(i){S.push(w);continue}if(w.startsWith("- ")){C||(s.push("<ul>"),C=!0),s.push(`<li>${o(w.slice(2))}</li>`);continue}if(z(),w.startsWith("## ")){s.push(`<h2>${o(w.slice(3))}</h2>`);continue}if(w.startsWith("### ")){s.push(`<h3>${o(w.slice(4))}</h3>`);continue}if(w.startsWith("> ")){s.push(`<blockquote>${o(w.slice(2))}</blockquote>`);continue}if(w.trim()===""){s.push("<br>");continue}s.push(`<p>${o(w)}</p>`)}return z(),i&&A(),s.join(`
11
- `)}function P(){if(!a.screenshots?.length)return"";const t=s=>s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");return`<section><h2>Screenshots</h2><div style="display:flex;flex-wrap:wrap;gap:4px">${a.screenshots.map(s=>`<figure style="display:inline-block;margin:4px 4px 8px;text-align:center"><img src="data:${t(s.mediaType)};base64,${s.data}" alt="${t(s.name)}" style="max-width:320px;max-height:220px;border-radius:6px;border:1px solid #e4e4e7;display:block" /><figcaption style="font-size:0.7em;color:#71717a;margin-top:3px">${t(s.name)}</figcaption></figure>`).join("")}</div></section>`}function M(){if(!a.contextText)return;const t=a.contextText,o=U(t),i=`<!DOCTYPE html><html><head><meta charset="utf-8"><title>AI Diagnosis Context</title><style>body{font-family:system-ui,sans-serif;max-width:900px;margin:2em auto;padding:0 1em;line-height:1.6}h2{color:#1a1a2e;margin-top:1.5em}h3{color:#16213e;margin-top:1.2em}pre{background:#f4f4f5;padding:1em;border-radius:6px;overflow-x:auto;font-size:0.9em}code{font-family:ui-monospace,monospace}blockquote{border-left:3px solid #d4d4d8;padding-left:1em;color:#52525b;margin:1em 0}li{margin:0.25em 0}figure{margin:0}section+section{border-top:1px solid #e4e4e7;padding-top:1em}</style></head><body>${P()}<section>${o}</section></body></html>`;try{navigator.clipboard.write([new ClipboardItem({"text/plain":new Blob([t],{type:"text/plain"}),"text/html":new Blob([i],{type:"text/html"})})]),se().add({title:"AI context (HTML) copied",icon:"i-lucide-check",color:"success",duration:2e3})}catch{u(i,{toast:"AI context (HTML) copied"})}x.value=!1}function f(){if(!a.diagnosis||a.diagnosis.status!=="completed")return;const t=a.diagnosis,o=t.details,s=[];t.category&&s.push(`Category: ${t.category}`),t.confidence&&s.push(`Confidence: ${t.confidence}`),s.push(""),t.summary&&s.push(t.summary),t.rootCause&&s.push(`
12
- Root cause: ${t.rootCause}`);const i=o?.evidence??[];i.length&&(s.push(`
13
- Evidence:`),i.forEach(z=>s.push(`- ${z}`)));const m=o?.suggestedFix;m?.patch?s.push(`
14
- Suggested fix (patch):
15
- ${m.patch}`):m?.code&&s.push(`
16
- Suggested fix (code):
17
- ${m.code}`);const S=s.join(`
18
- `),C=z=>z.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),A=[`<dl>${t.category?`<dt>Category</dt><dd>${C(t.category)}</dd>`:""}${t.confidence?`<dt>Confidence</dt><dd>${C(t.confidence)}</dd>`:""}</dl>`,t.summary?`<p><strong>${C(t.summary)}</strong></p>`:"",t.rootCause?`<p><strong>Root cause:</strong> ${C(t.rootCause)}</p>`:""].join("");d(S,A,{toast:"Diagnosis copied"}),x.value=!1}function r(){if(!a.diagnosis)return;const o=a.diagnosis.details?.suggestedFix?.patch;o&&u(o,{toast:"Suggested patch copied"}),x.value=!1}return(t,o)=>{const s=le,i=Ge,m=We;return p(),H(m,{open:e(x),"onUpdate:open":o[0]||(o[0]=S=>_e(x)?x.value=S:null)},{content:D(()=>[l("div",mt,[o[8]||(o[8]=l("p",{class:"text-xs font-medium text-gray-500 px-2 pt-1 pb-1"},"Copy / export",-1)),g(s,{block:"",size:"sm",color:"neutral",variant:"ghost",class:"justify-start",icon:"i-lucide-clipboard-list",onClick:I},{default:D(()=>[...o[2]||(o[2]=[k(" Investigation summary ",-1)])]),_:1}),v.contextText?(p(),H(s,{key:0,block:"",size:"sm",color:"neutral",variant:"ghost",class:"justify-start",icon:"i-lucide-file-text",onClick:O},{default:D(()=>[...o[3]||(o[3]=[k(" Full context (Markdown) ",-1)])]),_:1})):T("",!0),v.contextText?(p(),H(s,{key:1,block:"",size:"sm",color:"neutral",variant:"ghost",class:"justify-start",icon:"i-lucide-file-json",onClick:R},{default:D(()=>[...o[4]||(o[4]=[k(" Full context (JSON) ",-1)])]),_:1})):T("",!0),v.contextText?(p(),H(s,{key:2,block:"",size:"sm",color:"neutral",variant:"ghost",class:"justify-start",icon:"i-lucide-file-code",onClick:M},{default:D(()=>[...o[5]||(o[5]=[k(" Full context (HTML) ",-1)])]),_:1})):T("",!0),g(i,{class:"my-1"}),v.diagnosis?.status==="completed"?(p(),H(s,{key:3,block:"",size:"sm",color:"neutral",variant:"ghost",class:"justify-start",icon:"i-lucide-sparkles",onClick:f},{default:D(()=>[...o[6]||(o[6]=[k(" Diagnosis only ",-1)])]),_:1})):T("",!0),v.diagnosis?.status==="completed"&&v.diagnosis.details?.suggestedFix?.patch?(p(),H(s,{key:4,block:"",size:"sm",color:"neutral",variant:"ghost",class:"justify-start",icon:"i-lucide-code",onClick:r},{default:D(()=>[...o[7]||(o[7]=[k(" Suggested patch ",-1)])]),_:1})):T("",!0)])]),default:D(()=>[g(s,{icon:"i-lucide-download",size:"xs",color:"neutral",variant:"outline",title:"Copy / export"},{default:D(()=>[...o[1]||(o[1]=[k(" Export ",-1)])]),_:1})]),_:1},8,["open"])}}}),vt=Object.assign(gt,{__name:"DiagnosisExportMenu"}),xt={key:0,class:"flex items-center gap-1.5 text-xs text-gray-400 py-1"},yt={key:1,class:"space-y-1.5"},ht={class:"flex items-center justify-between"},bt={class:"text-xs font-medium text-gray-500"},kt={class:"text-gray-400 font-normal"},Ct={class:"flex gap-0.5"},_t={class:"grid grid-cols-4 gap-1.5"},wt=["onClick"],$t={class:"relative"},St=["src","alt"],Tt={class:"absolute top-0.5 right-0.5"},Dt={class:"px-1 py-0.5 bg-elevated space-y-0.5"},At=["title"],Et={class:"flex items-center gap-1 flex-wrap"},zt={key:0,class:"text-[8px] text-gray-400 leading-tight"},It={key:1,class:"text-[8px] text-gray-400 leading-tight truncate"},Rt={key:2,class:"text-[8px] text-gray-400 leading-tight ml-auto"},he=8,jt=re({__name:"DiagnosisScreenshots",props:{affectedTestCases:{}},emits:["update:images"],setup(v,{emit:a}){const u=v,d=a;async function x(r){const t=(r.type||"image/webp").split(";")[0].trim();return new Promise((o,s)=>{const i=new FileReader;i.onload=()=>{const m=i.result.split(",")[1];m!=null?o({data:m,mediaType:t}):s(new Error("Failed to read blob"))},i.onerror=s,i.readAsDataURL(r)})}const y=h([]),I=h(!1);async function O(){if(!u.affectedTestCases.length)return;I.value=!0,y.value=[];const r=[];for(const t of u.affectedTestCases){if(r.length>=he)break;try{const o=await $fetch(`/api/test-run-cases/${t.recentTestRunsCaseId}`);for(const s of o.attachments??[]){if(!Qe(s.path,s.contentType))continue;if(r.length>=he)break;const i=s.name||s.path.split("/").pop()||"screenshot",m=`/api/files/${it(s.path)}?compress=1`;try{const S=await fetch(m);if(!S.ok)continue;const C=await S.blob(),{data:A,mediaType:z}=await x(C);r.push({src:`data:${z};base64,${A}`,data:A,mediaType:z,name:i,selected:!0,caseTitle:t.title,status:o.status,retries:o.retries,browser:o.browser,startTime:o.testRun?.startTime??null})}catch{}}}catch{}}y.value=r,I.value=!1,R()}function R(){d("update:images",y.value.filter(r=>r.selected).map(({name:r,mediaType:t,data:o})=>({name:r,mediaType:t,data:o})))}function U(r){y.value[r].selected=!y.value[r].selected,R()}function P(){y.value.forEach(r=>r.selected=!0),R()}function M(){y.value.forEach(r=>r.selected=!1),R()}const f=Q(()=>y.value.filter(r=>r.selected).length);return be(O),(r,t)=>{const o=we,s=le;return e(I)?(p(),$("div",xt,[g(o,{name:"i-lucide-loader-2",class:"size-3 animate-spin"}),t[0]||(t[0]=k(" Loading screenshots from test evidence… ",-1))])):e(y).length?(p(),$("div",yt,[l("div",ht,[l("span",bt,[t[1]||(t[1]=k(" Test screenshots ",-1)),l("span",kt,"("+j(e(f))+"/"+j(e(y).length)+" will be sent to AI)",1)]),l("div",Ct,[g(s,{size:"xs",color:"neutral",variant:"ghost",onClick:P},{default:D(()=>[...t[2]||(t[2]=[k("All",-1)])]),_:1}),g(s,{size:"xs",color:"neutral",variant:"ghost",onClick:M},{default:D(()=>[...t[3]||(t[3]=[k("None",-1)])]),_:1})])]),l("div",_t,[(p(!0),$(K,null,ie(e(y),(i,m)=>(p(),$("div",{key:m,class:Z(["cursor-pointer rounded overflow-hidden border-2 transition-all",i.selected?"border-primary":"border-default opacity-50"]),onClick:S=>U(m)},[l("div",$t,[l("img",{src:i.src,alt:i.name,class:"w-full h-14 object-cover object-top"},null,8,St),l("div",Tt,[g(o,{name:i.selected?"i-lucide-check-circle-2":"i-lucide-circle",class:Z(["size-3.5 drop-shadow",i.selected?"text-primary":"text-gray-300"])},null,8,["name","class"])])]),l("div",Dt,[l("p",{class:"text-[9px] text-gray-700 dark:text-gray-300 truncate font-medium leading-tight",title:i.caseTitle},j(i.caseTitle),9,At),l("div",Et,[l("span",{class:Z(["text-[8px] px-1 rounded leading-tight font-medium",i.status==="passed"?"bg-success/15 text-success":i.status==="failed"?"bg-error/15 text-error":"bg-neutral/15 text-gray-500"])},j(i.status),3),i.retries>0?(p(),$("span",zt,"retry "+j(i.retries),1)):T("",!0),i.browser?(p(),$("span",It,j(i.browser),1)):T("",!0),i.startTime?(p(),$("span",Rt,j(e($e)(i.startTime)),1)):T("",!0)])])],10,wt))),128))])])):T("",!0)}}}),Bt=Object.assign(jt,{__name:"DiagnosisScreenshots"});function Ot(v){const a=h(""),u=h(null),d=h("idle"),x=h(null),y=h(null);let I=null;function O(){I&&(I.abort(),I=null),d.value==="streaming"&&(d.value="cancelled")}function R(){O(),a.value="",u.value=null,d.value="idle",x.value=null,y.value=null}async function U(f={}){a.value="",u.value=null,y.value=null,x.value=null,d.value="streaming";const r=e(v);I=new AbortController;const t=new URLSearchParams;f.force&&t.set("force","true");const o=`/api/failure-clusters/${r}/diagnose/stream${t.toString()?"?"+t.toString():""}`;try{const s=await $fetch.raw(o,{method:"POST",body:{additionalContext:f.additionalContext,images:f.images,baseCommit:f.baseCommit,selectedCommitShas:f.selectedCommitShas,scope:f.scope,testRunsCaseId:f.testRunsCaseId},responseType:"stream",signal:I.signal,ignoreResponseError:!0}),i=s._data??s.body;if(!i)throw new Error("No response body from streaming endpoint");let m;if(i instanceof ReadableStream)m=i.getReader();else if(i instanceof Uint8Array||i instanceof ArrayBuffer){const z=new TextDecoder().decode(i instanceof ArrayBuffer?new Uint8Array(i):i);M(z),d.value==="streaming"&&(d.value="error",y.value="Stream ended without a result event");return}else if(typeof i?.getReader=="function")m=i.getReader();else if(i?.pipeThrough)m=i.getReader();else throw new Error("Unsupported stream response format");const S=new TextDecoder;let C="";for(;;){const{done:A,value:z}=await m.read();if(A)break;C+=S.decode(z,{stream:!0});const w=C.split(`
19
-
20
- `);C=w.pop()||"";let W=!1;for(const J of w){const c=P(J);if(c){if(c.event==="result")x.value=c.data,d.value="complete",W=!0;else if(c.event==="thinking"){const E=c.data;a.value+=E.text}else if(c.event==="stage")u.value=c.data.stage;else if(c.event==="error"){const E=c.data;y.value=E.message,d.value="error"}}}if(W)break}if(C.trim()){const A=P(C.trim());A&&(A.event==="result"?(x.value=A.data,d.value="complete"):A.event==="error"&&(y.value=A.data.message,d.value="error"))}d.value==="streaming"&&(y.value||(d.value="complete"))}catch(s){if(s?.name==="AbortError"){d.value="cancelled";return}y.value=String(s?.message??s),d.value="error"}finally{I=null}}function P(f){if(!f.trim())return null;const r=f.split(`
21
- `);let t="message",o="";for(const s of r)s.startsWith("event: ")?t=s.slice(7).trim():s.startsWith("data: ")?o+=s.slice(6):s.startsWith(":");if(!o)return null;try{return{event:t,data:JSON.parse(o)}}catch{return{event:t,data:o}}}function M(f){const r=f.split(`
22
-
23
- `);for(const t of r){const o=P(t);if(o)if(o.event==="result")x.value=o.data,d.value="complete";else if(o.event==="thinking"){const s=o.data;a.value+=s.text}else o.event==="stage"?u.value=o.data.stage:o.event==="error"&&(y.value=o.data.message,d.value="error")}}return ke(()=>{O()}),{thinkingText:a,stage:u,status:d,result:x,error:y,startStream:U,cancel:O,reset:R}}const Pt=200*1024,Ut=5*1024*1024,Mt=["image/jpeg","image/png","image/gif","image/webp"];function Ft(v){return new Promise((a,u)=>{const d=new FileReader;d.onload=()=>{const x=d.result.split(",")[1];x!==void 0?a(x):u(new Error("Failed to read file"))},d.onerror=u,d.readAsDataURL(v)})}function Lt(){const v=se(),a=h([]),u=h([]),d=h(!1);async function x(f){for(const r of Array.from(f))if(Mt.includes(r.type)){if(r.size>Ut){v.add({title:"Image too large",description:`${r.name} exceeds 5 MB`,color:"error"});continue}const t=await Ft(r),o=`data:${r.type};base64,${t}`;u.value.push({name:r.name,mediaType:r.type,data:t,preview:o,size:r.size})}else{if(r.size>Pt){v.add({title:"File too large",description:`${r.name} exceeds 200 KB`,color:"error"});continue}const t=await r.text();a.value.push({name:r.name,content:t,size:r.size})}}function y(f){f.preventDefault(),d.value=!0}function I(f){f.currentTarget?.contains(f.relatedTarget)||(d.value=!1)}function O(f){f.preventDefault(),d.value=!1,f.dataTransfer?.files?.length&&x(f.dataTransfer.files)}function R(f){a.value.splice(f,1)}function U(f){u.value.splice(f,1)}function P(){return a.value.length?`## Attached Files
24
-
25
- ${a.value.map(r=>`### ${r.name}
26
- \`\`\`
27
- ${r.content}
28
- \`\`\``).join(`
29
-
30
- `)}`:""}function M(){return u.value.map(f=>({name:f.name,mediaType:f.mediaType,data:f.data}))}return{files:a,images:u,dragOver:d,processFiles:x,onDragOver:y,onDragLeave:I,onDrop:O,removeFile:R,removeImage:U,filesMarkdown:P,imagesPayload:M}}const Nt={class:"space-y-4"},Ht={class:"pb-2 border-b border-default"},qt={class:"flex items-center justify-between gap-2"},Wt={class:"flex items-center gap-1.5"},Vt={class:"text-xs text-gray-400"},Jt={class:"flex items-center gap-1.5"},Yt={key:0,class:"flex items-center gap-2 px-3 py-2 rounded-lg bg-elevated/50 border border-default text-xs"},Gt={class:"text-gray-500"},Xt={key:1,class:"flex items-center gap-2 px-3 py-2 rounded-lg bg-elevated/50 border border-default text-xs"},Kt={class:"flex items-center gap-1 mb-1"},Qt={key:0,class:"text-primary"},Zt={key:0},es={class:"flex items-center gap-2 px-3 pb-2 pt-1 border-t border-default"},ts={key:0,class:"text-xs text-primary"},ss={key:1,class:"text-xs text-gray-400"},ns={key:0,class:"flex flex-wrap gap-2"},os={class:"max-w-40 truncate"},as={class:"text-gray-400"},is=["onClick"],rs={key:1,class:"flex flex-wrap gap-2"},ls=["src","alt"],cs={class:"absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity rounded-lg flex items-center justify-center"},us=["onClick"],ds={class:"text-xs text-gray-500 text-center mt-0.5 w-16 truncate"},fs={key:3,class:"pt-1"},ps={key:4,class:"rounded-lg border border-default overflow-hidden"},ms={class:"flex items-center justify-between gap-2 px-3 py-2 bg-elevated/30 border-b border-default"},gs={class:"flex items-center gap-2 text-sm text-gray-500"},vs={key:0,class:"inline-flex items-center gap-1 text-xs text-gray-400"},xs={key:1,class:"text-gray-400 italic"},ys={class:"px-3 py-1.5 border-t border-default text-xs text-gray-400 flex items-center gap-2"},hs={key:5,class:"rounded-lg border border-warning/40 bg-warning/5 p-3 space-y-2"},bs={class:"flex items-center gap-2 text-sm"},ks={class:"flex items-center gap-2 pt-1"},Cs={class:"text-xs text-gray-400"},_s={key:4,class:"flex flex-col items-center justify-center p-8 text-center text-gray-400 border border-dashed border-default rounded-lg"},ws={class:"text-sm inline-flex items-center gap-1"},$s={class:"pt-1 text-center"},Ss=re({__name:"DiagnosisPanel",props:{clusterId:{},lastSeenRunId:{},affectedTestCases:{}},setup(v){const a=v,{diagnosis:u,posting:d,contextText:x,contextSections:y,tokenEstimate:I,imageTokenEstimate:O,contextLoading:R,coverage:U,baseCommit:P,selectedCommitShas:M,refreshContext:f,runDiagnosis:r}=pt(a.clusterId),{aiStatus:t}=Ze();se();const{permission:o,active:s,requestPermission:i,toggleEnabled:m}=ct(),{thinkingText:S,stage:C,status:A,result:z,error:w,startStream:W,cancel:J}=Ot(Q(()=>a.clusterId??0)),c=Lt(),{files:E,images:F,dragOver:ue,processFiles:Se,onDragOver:de,onDragLeave:fe,onDrop:pe,removeFile:Te,removeImage:De}=c,L=h(""),me=h(null),ge=h([]),Y=Q(()=>[...ge.value,...F.value.length?c.imagesPayload():[]]),q=h(!1),G=h(!1),ne=h(null),ee=h(null);function ve(b){ne.value=b,q.value=!0}const Ae=Q(()=>{const b=u.value?.details;if(!b)return[];const n=[];if(Array.isArray(b.evidence)&&n.push(...b.evidence),Array.isArray(b.hypotheses))for(const B of b.hypotheses)Array.isArray(B?.evidence)&&n.push(...B.evidence);return nt(n)});V(S,()=>{Je(()=>{ee.value&&(ee.value.scrollTop=ee.value.scrollHeight)})}),V(z,b=>{b&&(u.value=b)}),V(()=>u.value?.details,b=>{if(!b)return;const n=b;typeof n.additionalContext=="string"&&n.additionalContext.trim()&&!L.value&&(L.value=n.additionalContext)},{immediate:!0});function Ee(b){L.value=L.value?`${L.value}
31
-
32
- ${b}`:b,G.value=!0}function xe(){const b=[];L.value.trim()&&b.push(L.value.trim());const n=c.filesMarkdown();return n&&b.push(n),b.join(`
33
-
34
- `)}async function oe(b=!1){await W({force:b,additionalContext:xe()||void 0,baseCommit:P.value.trim()||void 0,selectedCommitShas:M.value.length?[...M.value]:void 0,images:Y.value.length?Y.value:void 0})}async function ze(b=!1){await r({force:b,additionalContext:xe()||void 0,images:Y.value.length?Y.value:void 0})}function Ie(){u.value=null}function ye(b){return b.status==="running"&&Date.now()-new Date(b.updatedAt).getTime()>300*1e3}function te(){return A.value==="streaming"}function Re(){return!te()&&(!u.value||u.value.status==="failed"||ye(u.value))}function je(){return!te()&&u.value&&(u.value.status==="completed"||u.value.status==="failed")}return(b,n)=>{const B=we,ae=Ye,Be=vt,N=le,Oe=tt,Pe=et,Ue=at,Me=Bt,Fe=lt,Le=st,Ne=Ve;return p(),$("div",Nt,[l("div",Ht,[l("div",qt,[l("div",Wt,[g(B,{name:"i-lucide-sparkles",class:"size-4 text-primary shrink-0"}),n[17]||(n[17]=l("span",{class:"text-sm font-semibold"},"Diagnosis",-1)),g(ae,{topic:"cluster.diagnosis"}),l("span",Vt,[n[15]||(n[15]=k(" — ",-1)),g(B,{name:"i-lucide-triangle-alert",class:"size-3 shrink-0 inline"}),n[16]||(n[16]=k(" AI-generated, verify before applying ",-1))])]),l("div",Jt,[g(Be,{"context-text":e(x),diagnosis:e(u),screenshots:e(Y)},null,8,["context-text","diagnosis","screenshots"]),g(N,{icon:e(q)?"i-lucide-eye-off":"i-lucide-eye",size:"xs",color:"neutral",variant:"outline",loading:e(R),onClick:n[0]||(n[0]=_=>q.value=!e(q))},{default:D(()=>[k(j(e(q)?"Hide context":"Show context"),1)]),_:1},8,["icon","loading"]),e(u)&&e(u).status==="completed"?(p(),H(N,{key:0,icon:"i-lucide-refresh-cw",size:"xs",color:"primary",variant:"soft",loading:e(d),onClick:n[1]||(n[1]=_=>oe(!0))},{default:D(()=>[...n[18]||(n[18]=[k(" Re-diagnose ",-1)])]),_:1},8,["loading"])):T("",!0)])])]),e(o)==="granted"&&e(t)?.configured?(p(),$("div",Yt,[g(B,{name:"i-lucide-bell",class:Z(["size-3.5 shrink-0",e(s)?"text-primary":"text-gray-400"])},null,8,["class"]),l("span",Gt,j(e(s)?"Diagnosis notifications on":"Diagnosis notifications off"),1),g(N,{size:"xs",color:e(s)?"neutral":"primary",variant:"outline",onClick:e(m)},{default:D(()=>[k(j(e(s)?"Disable":"Enable"),1)]),_:1},8,["color","onClick"])])):e(o)==="default"&&e(t)?.configured?(p(),$("div",Xt,[g(B,{name:"i-lucide-bell",class:"size-3.5 text-gray-400 shrink-0"}),n[20]||(n[20]=l("span",{class:"text-gray-500"},"Notify when diagnosis completes?",-1)),g(N,{size:"xs",color:"neutral",variant:"outline",onClick:e(i)},{default:D(()=>[...n[19]||(n[19]=[k("Enable",-1)])]),_:1},8,["onClick"])])):T("",!0),e(t)?.configured?(p(),H(Oe,{key:2,sections:e(y),"not-applicable":e(U)?.notApplicable,"token-estimate":e(I),loading:e(R),onViewSection:ve,onOpen:n[2]||(n[2]=_=>q.value=!0)},null,8,["sections","not-applicable","token-estimate","loading"])):T("",!0),g(Pe,{open:e(q),sections:e(y),"token-estimate":e(I),"image-token-estimate":e(O),loading:e(R),"focus-section":e(ne),"cited-sections":e(Ae),"not-applicable-sections":e(U)?.notApplicable,"onUpdate:open":n[3]||(n[3]=_=>{q.value=_,_||(ne.value=null)}),onRefresh:e(f)},null,8,["open","sections","token-estimate","image-token-estimate","loading","focus-section","cited-sections","not-applicable-sections","onRefresh"]),e(t)?.configured?(p(),$(K,{key:3},[l("div",null,[l("div",Kt,[l("button",{class:"flex items-center gap-1.5 text-xs font-medium text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 text-left",onClick:n[4]||(n[4]=_=>G.value=!e(G))},[g(B,{name:e(G)?"i-lucide-chevron-down":"i-lucide-chevron-right",class:"size-3.5"},null,8,["name"]),n[21]||(n[21]=k(" Additional context ",-1)),e(E).length||e(F).length||e(L).trim()?(p(),$("span",Qt," ("+j(e(E).length+e(F).length+(e(L).trim()?1:0))+") ",1)):T("",!0)]),g(ae,{topic:"cluster.context-input"})]),e(G)?(p(),$("div",Zt,[l("div",{class:Z(["rounded-lg border-2 transition-colors",e(ue)?"border-primary bg-primary/5 border-solid":"border-dashed border-default"]),onDragover:n[8]||(n[8]=(..._)=>e(de)&&e(de)(..._)),onDragleave:n[9]||(n[9]=(..._)=>e(fe)&&e(fe)(..._)),onDrop:n[10]||(n[10]=(..._)=>e(pe)&&e(pe)(..._))},[g(Ue,{modelValue:e(L),"onUpdate:modelValue":n[5]||(n[5]=_=>_e(L)?L.value=_:null),placeholder:"e.g. We deployed a new auth middleware yesterday\\u2026",rows:3,class:"w-full text-sm border-0 bg-transparent focus:ring-0"},null,8,["modelValue"]),l("div",es,[l("input",{ref_key:"fileInputRef",ref:me,type:"file",multiple:"",class:"hidden",accept:".txt,.log,.md,.json,.ts,.js,.py,.sql,.xml,.yaml,.yml,.html,.css,.env,image/*",onChange:n[6]||(n[6]=_=>e(Se)(_.target.files))},null,544),g(N,{icon:"i-lucide-paperclip",size:"xs",color:"neutral",variant:"ghost",onClick:n[7]||(n[7]=_=>e(me)?.click())},{default:D(()=>[...n[22]||(n[22]=[k(" Attach files ",-1)])]),_:1}),e(ue)?(p(),$("span",ts,"Drop files here\\u2026")):(p(),$("span",ss,"or drag & drop text files and images"))])],34)])):T("",!0)]),e(E).length?(p(),$("div",ns,[(p(!0),$(K,null,ie(e(E),(_,X)=>(p(),$("div",{key:X,class:"flex items-center gap-1.5 bg-elevated rounded-full px-2.5 py-1 text-xs border border-default"},[g(B,{name:"i-lucide-file-text",class:"size-3 text-gray-500 shrink-0"}),l("span",os,j(_.name),1),l("span",as,j(("formatBytes"in b?b.formatBytes:e(rt))(_.size)),1),l("button",{class:"text-gray-400 hover:text-error ml-0.5",onClick:He=>e(Te)(X)},[g(B,{name:"i-lucide-x",class:"size-3"})],8,is)]))),128))])):T("",!0),e(F).length?(p(),$("div",rs,[(p(!0),$(K,null,ie(e(F),(_,X)=>(p(),$("div",{key:X,class:"relative group"},[l("img",{src:_.preview,alt:_.name,class:"h-16 w-16 object-cover rounded-lg border border-default"},null,8,ls),l("div",cs,[l("button",{class:"text-white",onClick:He=>e(De)(X)},[g(B,{name:"i-lucide-x",class:"size-4"})],8,us)]),l("p",ds,j(_.name),1)]))),128))])):T("",!0),v.affectedTestCases?.length?(p(),H(Me,{key:2,"affected-test-cases":v.affectedTestCases,"onUpdate:images":n[11]||(n[11]=_=>ge.value=_)},null,8,["affected-test-cases"])):T("",!0),Re()?(p(),$("div",fs,[g(N,{icon:"i-lucide-sparkles",size:"sm",color:"primary",variant:"solid",loading:e(d),onClick:n[12]||(n[12]=_=>oe())},{default:D(()=>[...n[23]||(n[23]=[k(" Diagnose with AI ",-1)])]),_:1},8,["loading"])])):T("",!0),te()?(p(),$("div",ps,[l("div",ms,[l("div",gs,[g(B,{name:"i-lucide-loader-2",class:"size-4 animate-spin text-primary"}),n[24]||(n[24]=l("span",null,"Analyzing failure cluster",-1)),e(C)?(p(),$("span",vs,[g(B,{name:"i-lucide-workflow",class:"size-3"}),k(" "+j(e(C)==="research"?"Researching patterns":"Diagnosing root cause"),1)])):T("",!0)]),g(N,{size:"xs",color:"neutral",variant:"ghost",icon:"i-lucide-x",title:"Cancel diagnosis",onClick:e(J)},null,8,["onClick"])]),l("div",{ref_key:"thinkingContainer",ref:ee,class:"max-h-64 overflow-y-auto p-3 text-xs font-mono leading-relaxed whitespace-pre-wrap break-words text-gray-600 dark:text-gray-400 bg-elevated/10"},[e(S)?(p(),$(K,{key:0},[k(j(e(S))+" ",1),n[25]||(n[25]=l("span",{class:"inline-block w-2 h-4 bg-primary/60 animate-pulse ml-0.5 align-text-bottom"},null,-1))],64)):(p(),$("span",xs,"Waiting for model response\\u2026"))],512),l("div",ys,[g(B,{name:"i-lucide-file-text",class:"size-3"}),l("span",null,j(e(S).length.toLocaleString())+" characters received",1)])])):T("",!0),e(u)?.status==="running"&&!ye(e(u))&&!te()?(p(),$("div",hs,[l("div",bs,[g(B,{name:"i-lucide-alert-triangle",class:"size-4 text-warning shrink-0"}),n[26]||(n[26]=l("span",{class:"font-medium text-warning-700 dark:text-warning-400"},"Diagnosis was interrupted",-1))]),n[29]||(n[29]=l("p",{class:"text-xs text-gray-500"}," A previous diagnosis started but never completed — the server may have restarted. You can restart it below. ",-1)),l("div",ks,[g(N,{icon:"i-lucide-refresh-cw",size:"xs",color:"warning",variant:"solid",loading:e(d),onClick:n[13]||(n[13]=_=>oe(!0))},{default:D(()=>[...n[27]||(n[27]=[k(" Restart diagnosis ",-1)])]),_:1},8,["loading"]),g(N,{size:"xs",color:"neutral",variant:"ghost",loading:e(d),onClick:Ie},{default:D(()=>[...n[28]||(n[28]=[k(" Dismiss ",-1)])]),_:1},8,["loading"])]),l("p",Cs,"Started "+j(e($e)(e(u).updatedAt)),1)])):T("",!0),e(w)?(p(),H(Fe,{key:6,color:"error",icon:"i-lucide-alert-circle",title:"Streaming diagnosis failed",description:e(w),class:"mt-2"},{actions:D(()=>[g(N,{size:"xs",color:"neutral",variant:"outline",onClick:n[14]||(n[14]=_=>ze(!0))},{default:D(()=>[...n[30]||(n[30]=[k(" Retry (fallback) ",-1)])]),_:1})]),_:1},8,["description"])):T("",!0),je()?(p(),H(Le,{key:7,diagnosis:e(u),"last-seen-run-id":v.lastSeenRunId,onViewSection:ve,onPrefillContext:Ee},null,8,["diagnosis","last-seen-run-id"])):T("",!0)],64)):(p(),$("div",_s,[g(B,{name:"i-lucide-sparkles",class:"size-8 mb-2 opacity-30"}),l("p",ws,[n[31]||(n[31]=k(" AI diagnosis is not configured ",-1)),g(ae,{topic:"cluster.ai-setup"})]),g(N,{to:"/settings/ai",size:"xs",color:"neutral",variant:"outline",class:"mt-3"},{default:D(()=>[...n[32]||(n[32]=[k(" Configure in Settings ",-1)])]),_:1}),n[33]||(n[33]=l("p",{class:"text-xs text-gray-400 mt-4 max-w-xs"},[k(" Use the "),l("strong",null,"Show context"),k(" button above to inspect the full diagnosis context and copy it for use with your own AI tool. ")],-1))])),l("div",$s,[g(Ne,{to:"/mcp",class:"inline-flex items-center gap-1 text-xs text-gray-400 hover:text-primary transition-colors"},{default:D(()=>[g(B,{name:"i-lucide-bot",class:"size-3"}),n[34]||(n[34]=k(" Query this cluster from your AI agent via the MCP server ",-1))]),_:1})])])}}}),Ps=Object.assign(Ss,{__name:"DiagnosisPanel"});export{Ps as _,ft as p,Os as u};
@@ -1 +0,0 @@
1
- import{_ as k}from"./B6IHiVa1.js";import{d as _,f as r,g as l,k as b,o as n,c as a,t as u,m as h,F as g,y as V,h as f,i as y,q as v,aa as x,T as p}from"./D3SYPlEB.js";import{_ as B}from"./C8cz5feG.js";import{_ as $}from"./AjuKBlzz.js";import{_ as E}from"./Db_-yjYg.js";import{h as M}from"./r3SBLxtE.js";const F={key:0},q={key:1},S={class:"font-mono text-xs"},T={key:0},A={key:2},C=_({__name:"EnvManagedAlert",props:{envVars:{},title:{},description:{}},setup(e){const t=e,c=f(()=>t.title??"Managed by environment variables");return(o,s)=>{const d=k;return n(),r(d,{icon:"i-lucide-lock",color:"neutral",variant:"subtle",title:b(c)},{description:l(()=>[e.description?(n(),a("span",F,u(e.description),1)):e.envVars?.length?(n(),a("span",q,[s[0]||(s[0]=h(" These settings are pinned by ",-1)),(n(!0),a(g,null,V(e.envVars,(i,m)=>(n(),a(g,{key:i},[y("code",S,u(i),1),m<e.envVars.length-1?(n(),a("span",T,", ")):v("",!0)],64))),128)),s[1]||(s[1]=h(" and cannot be changed here. Edit the environment and restart to change them. ",-1))])):(n(),a("span",A," These settings are pinned by environment variables and cannot be changed here. "))]),_:1},8,["title"])}}}),z=Object.assign(C,{__name:"EnvManagedAlert"}),N={class:"inline-flex items-center gap-1"},j=_({__name:"SettingsField",props:{label:{},help:{},envVars:{},envManaged:{type:Boolean},description:{},hint:{},required:{type:Boolean},name:{},disabled:{type:Boolean}},setup(e){const t=e,c=f(()=>{if(t.envVars)return t.envVars;if(t.help)return M(t.help)});return(o,s)=>{const d=B,i=$,m=E;return n(),r(m,{label:e.label,description:e.description,hint:e.hint,required:e.required,name:e.name,disabled:e.disabled||e.envManaged},x({label:l(()=>[y("span",N,[h(u(e.label)+" ",1),e.help?(n(),r(d,{key:0,topic:e.help},null,8,["topic"])):v("",!0),e.envManaged?(n(),r(i,{key:1,"env-vars":b(c)},null,8,["env-vars"])):v("",!0)])]),default:l(()=>[p(o.$slots,"default")]),_:2},[o.$slots.trailing?{name:"trailing",fn:l(()=>[p(o.$slots,"trailing")]),key:"0"}:void 0]),1032,["label","description","hint","required","name","disabled"])}}}),G=Object.assign(j,{__name:"SettingsField"});export{z as _,G as a};
@@ -1,4 +0,0 @@
1
- import{_ as Be}from"./BAaSmp8J.js";import{_ as Le}from"./Ccit_CX1.js";import{d as ee,o as s,f as S,g as p,i as t,p as Y,k as e,j as c,c as l,t as o,q as m,s as ue,m as w,v as te,x as ye,F as L,y as Q,_ as ie,z as Pe,A as De,h as P,r as x,B as ne,C as Oe,l as J,D as ke,E as He,G as qe,H as fe,I as Ge,b as Ke,u as We,w as Je,e as Ze,J as Qe}from"./D3SYPlEB.js";import{_ as be}from"./CCw3Tx4S.js";import{_ as Xe,a as Ye}from"./87SGk1nu.js";import{_ as ge}from"./C8cz5feG.js";import{_ as et}from"./HTQtMbWb.js";import{_ as tt}from"./empGC_x-.js";import{_ as $e}from"./DnThe2U0.js";import{u as st,_ as nt,a as at,i as ot,b as lt,c as rt,s as ve,d as it}from"./36cXPVrY.js";import{c as _e,f as ce,a as ct,b as Ce,s as pe,e as de,r as he,d as ut}from"./BUMZHDRC.js";import{_ as we,a as dt,b as mt,c as ft,d as pt,e as gt,f as xt,g as Se,h as vt,i as _t,j as ht,k as yt,l as kt}from"./D1ttGJfs.js";import{_ as xe}from"./Tt5LX5Y-.js";import{_ as bt}from"./Dwp3GkV-.js";import{_ as $t}from"./DaewB_zT.js";import{_ as Ct}from"./Bi3i470l.js";import{_ as wt}from"./DM_YaJgJ.js";import{_ as Te}from"./l0QnzFNM.js";import{u as St,p as Tt,_ as jt}from"./BdHdHyop.js";import{b as It}from"./wQZj69OY.js";import{u as Ut}from"./Doul3p1_.js";import{u as zt}from"./D3MWm6JP.js";import"./B6rt3IcG.js";import"./r3SBLxtE.js";import"./DoFSKAvY.js";import"./B6IHiVa1.js";import"./oFIS9u6t.js";import"./DB3ljns7.js";import"./Do6zIWQf.js";import"./Dbg8z684.js";import"./Cx65B3c3.js";import"./rm7OkgDG.js";import"./Vnfkr1pJ.js";import"./BuuvTH9e.js";const Rt={class:"flex items-center gap-3 flex-1 min-w-0 justify-between"},Et={class:"flex items-center gap-3 min-w-0"},At={class:"font-mono text-sm truncate text-gray-600 dark:text-gray-400 min-w-0"},Vt={class:"flex items-center gap-3 shrink-0 max-sm:hidden"},Mt={class:"text-xs text-gray-500 tabular-nums whitespace-nowrap"},Nt={class:"text-xs text-gray-500 tabular-nums whitespace-nowrap"},Ft={key:1,class:"text-xs text-gray-400 whitespace-nowrap"},Bt={class:"grid grid-cols-1 lg:grid-cols-12 gap-4"},Lt={class:"space-y-3"},Pt={key:0,class:"text-sm font-medium break-words text-gray-500 dark:text-gray-400"},Dt={class:"flex flex-wrap gap-2"},Ot={class:"text-sm text-gray-500"},Ht={class:"flex items-start gap-3"},qt={class:"flex flex-col gap-1 shrink-0"},Gt={class:"flex-1 min-w-0 space-y-1.5"},Kt={class:"flex justify-end"},Wt=ee({__name:"ClusterSummary",props:{cluster:{},triageStatus:{},triageNote:{},triageSaving:{type:Boolean},triageChanged:{type:Boolean}},emits:["update:triageStatus","update:triageNote","save-triage"],setup(a,{emit:U}){const u=U,{summaryColSpanClass:b}=st(()=>1),f=[{label:"Open",value:"open",color:"warning"},{label:"Resolved",value:"resolved",color:"success"},{label:"Ignored",value:"ignored",color:"neutral"}];return(g,n)=>{const d=ue,C=te,V=ge,E=ye,R=et,T=tt,h=ie,I=$e,v=nt;return s(),S(v,{"storage-key":"failure-cluster"},{folded:p(()=>[t("div",Rt,[t("div",Et,[c(d,{color:("clusterStatusColor"in g?g.clusterStatusColor:e(ct))(a.cluster.status),variant:"solid",size:"sm",class:"shrink-0 capitalize"},{default:p(()=>[w(o(a.cluster.status),1)]),_:1},8,["color"]),t("span",At,o(a.cluster.signature),1),a.cluster.errorType?(s(),S(d,{key:0,color:("clusterErrorTypeColor"in g?g.clusterErrorTypeColor:e(_e))(a.cluster.errorType),variant:"subtle",size:"sm"},{default:p(()=>[w(o(a.cluster.errorType),1)]),_:1},8,["color"])):m("",!0)]),t("div",Vt,[t("span",Mt,o(a.cluster.occurrences)+" occurrence"+o(a.cluster.occurrences===1?"":"s"),1),t("span",Nt,o(a.cluster.affectedTests)+" "+o(a.cluster.affectedTests===1?"test":"tests"),1),a.cluster.diagnosis?.status==="completed"&&a.cluster.diagnosis?.category?(s(),S(d,{key:0,color:"neutral",variant:"outline",size:"sm",class:"gap-1 whitespace-nowrap"},{default:p(()=>[c(C,{name:"i-lucide-sparkles",class:"size-3"}),w(" "+o(a.cluster.diagnosis.category),1)]),_:1})):m("",!0),a.cluster.lastSeenAt?(s(),l("span",Ft," last seen "+o(("formatRelativeTime"in g?g.formatRelativeTime:e(ce))(a.cluster.lastSeenAt)),1)):m("",!0)])])]),default:p(()=>[t("div",Bt,[t("div",{class:Y(e(b))},[c(T,{title:a.cluster.signature},{default:p(()=>[t("div",Lt,[a.cluster.title?(s(),l("p",Pt,o(a.cluster.title),1)):m("",!0),t("div",Dt,[a.cluster.errorType?(s(),S(d,{key:0,color:("clusterErrorTypeColor"in g?g.clusterErrorTypeColor:e(_e))(a.cluster.errorType),variant:"subtle"},{default:p(()=>[w(o(a.cluster.errorType),1)]),_:1},8,["color"])):m("",!0),c(d,{color:"neutral",variant:"subtle"},{default:p(()=>[w(o(a.cluster.occurrences)+" occurrence"+o(a.cluster.occurrences===1?"":"s"),1)]),_:1}),c(d,{color:"neutral",variant:"subtle"},{default:p(()=>[w(o(a.cluster.affectedTests)+" "+o(a.cluster.affectedTests===1?"test":"tests")+" affected ",1)]),_:1}),a.cluster.diagnosis?.status==="completed"&&a.cluster.diagnosis?.category?(s(),S(d,{key:1,color:"neutral",variant:"outline",class:"gap-1"},{default:p(()=>[c(C,{name:"i-lucide-sparkles",class:"size-3"}),w(" "+o(a.cluster.diagnosis.category),1)]),_:1})):m("",!0),c(V,{topic:"cluster.concept"})]),t("p",Ot,[n[2]||(n[2]=w(" First seen in ",-1)),c(E,{to:`/test-runs/${a.cluster.firstSeenRunId}`,class:"text-primary hover:underline"},{default:p(()=>[w(" run #"+o(a.cluster.firstSeenRunId),1)]),_:1},8,["to"]),a.cluster.firstSeenAt?(s(),l(L,{key:0},[w(" ("+o(("formatRelativeTime"in g?g.formatRelativeTime:e(ce))(a.cluster.firstSeenAt))+") ",1)],64)):m("",!0),n[3]||(n[3]=w(" · Last seen in ",-1)),c(E,{to:`/test-runs/${a.cluster.lastSeenRunId}`,class:"text-primary hover:underline"},{default:p(()=>[w(" run #"+o(a.cluster.lastSeenRunId),1)]),_:1},8,["to"]),a.cluster.lastSeenAt?(s(),l(L,{key:1},[w(" ("+o(("formatRelativeTime"in g?g.formatRelativeTime:e(ce))(a.cluster.lastSeenAt))+") ",1)],64)):m("",!0),a.cluster.lastSeenRunStatus?(s(),S(R,{key:2,status:a.cluster.lastSeenRunStatus,size:"sm",class:"ml-1 align-middle"},null,8,["status"])):m("",!0)])])]),_:1},8,["title"])],2),c(T,{class:"lg:col-span-3",icon:"i-lucide-triangle-alert","icon-class":"text-amber-500",title:"Triage",help:"cluster.triage"},{default:p(()=>[t("div",Ht,[t("div",qt,[(s(),l(L,null,Q(f,j=>c(h,{key:j.value,size:"xs",class:"justify-start",color:a.triageStatus===j.value?j.color:"neutral",variant:a.triageStatus===j.value?"solid":"outline",onClick:G=>u("update:triageStatus",j.value)},{default:p(()=>[w(o(j.label),1)]),_:2},1032,["color","variant","onClick"])),64))]),t("div",Gt,[c(I,{"model-value":a.triageNote,placeholder:"Optional note…",rows:3,class:"text-sm w-full","onUpdate:modelValue":n[0]||(n[0]=j=>u("update:triageNote",j))},null,8,["model-value"]),t("div",Kt,[a.triageChanged?(s(),S(h,{key:0,size:"xs",icon:"i-lucide-check",loading:a.triageSaving,onClick:n[1]||(n[1]=j=>u("save-triage"))},{default:p(()=>[...n[4]||(n[4]=[w(" Save ",-1)])]),_:1},8,["loading"])):m("",!0)])])])]),_:1})])]),_:1})}}}),Jt=Object.assign(Wt,{__name:"ClusterSummary"}),Zt={class:"divide-y divide-default"},Qt={class:"text-xs font-mono text-gray-700 dark:text-gray-300 break-all whitespace-pre-wrap"},Xt={class:"text-xs font-mono text-gray-600 dark:text-gray-400 truncate"},Yt=ee({__name:"TestEvidenceSignals",props:De({consoleLogs:{},networkRequests:{}},{open:{type:Boolean,default:!1},openModifiers:{}}),emits:["update:open"],setup(a){const U=a,u=P(()=>Array.isArray(U.consoleLogs)?U.consoleLogs.filter(d=>d.type==="error"||d.type==="warning"):[]),b=P(()=>Array.isArray(U.networkRequests)?U.networkRequests.filter(d=>d.status&&d.status>=400):[]),f=P(()=>u.value.length>0||b.value.length>0),g=P(()=>{const d=[];return u.value.length&&d.push(`${u.value.length} console`),b.value.length&&d.push(`${b.value.length} network`),d.join(", ")}),n=Pe(a,"open");return(d,C)=>{const V=te,E=ue,R=we;return e(f)?(s(),S(R,{key:0,icon:"i-lucide-triangle-alert",label:`Signals (${e(g)})`,open:n.value,"onUpdate:open":C[0]||(C[0]=T=>n.value=T)},{default:p(()=>[t("div",Zt,[e(u).length>0?(s(),l(L,{key:0},[C[1]||(C[1]=t("div",{class:"px-3 py-1 bg-gray-50 dark:bg-gray-800/40"},[t("p",{class:"text-[10px] font-semibold text-gray-400 uppercase tracking-wide"},"Console")],-1)),(s(!0),l(L,null,Q(e(u),(T,h)=>(s(),l("div",{key:"log-"+h,class:"px-3 py-1.5 flex items-start gap-2"},[c(V,{name:T.type==="error"?"i-lucide-x-circle":"i-lucide-alert-triangle",class:Y(["size-3.5 mt-0.5 shrink-0",T.type==="error"?"text-red-500":"text-yellow-500"])},null,8,["name","class"]),t("p",Qt,o(T.text),1)]))),128))],64)):m("",!0),e(b).length>0?(s(),l(L,{key:1},[C[2]||(C[2]=t("div",{class:"px-3 py-1 bg-gray-50 dark:bg-gray-800/40"},[t("p",{class:"text-[10px] font-semibold text-gray-400 uppercase tracking-wide"},"Network")],-1)),(s(!0),l(L,null,Q(e(b),(T,h)=>(s(),l("div",{key:"req-"+h,class:"px-3 py-1.5 flex items-center gap-2"},[c(E,{color:T.status>=500?"error":"warning",variant:"subtle",size:"sm",class:"shrink-0 font-mono"},{default:p(()=>[w(o(T.status),1)]),_:2},1032,["color"]),t("p",Xt,o(T.url),1)]))),128))],64)):m("",!0)])]),_:1},8,["label","open"])):m("",!0)}}}),es=Object.assign(Yt,{__name:"TestEvidenceSignals"}),ts={class:"space-y-3"},ss={key:0,class:"flex gap-0 border-b border-default overflow-x-auto"},ns=["title","onClick"],as={key:0,class:"opacity-60 ml-1"},os={key:1,class:"flex items-start justify-between gap-2 flex-wrap"},ls={class:"min-w-0"},rs={class:"text-sm font-medium break-words"},is={key:2,class:"flex items-center justify-center py-10"},cs={key:0,class:"flex flex-wrap gap-1.5"},us={class:"divide-y divide-default"},ds={class:"text-xs font-medium text-gray-700 dark:text-gray-300"},ms={key:0,class:"text-xs font-mono text-red-500 whitespace-pre-wrap break-all"},fs={class:"overflow-x-auto max-h-72"},ps={class:"max-h-64 overflow-auto"},gs=ee({__name:"ClusterTestEvidence",props:{affectedTestCases:{},projectKey:{},projectName:{}},setup(a){const U=a,u=x(U.affectedTestCases[0]?.recentTestRunsCaseId??null),b=P(()=>U.affectedTestCases.find(r=>r.recentTestRunsCaseId===u.value)),f=x(null),g=x([]),n=x(!1),d=x(!1),C=x(!1),V=x(!1),E=x(!1),R=x(!1),T=x(!1),h=new Map;function I(){C.value=!1,V.value=!1,E.value=!1,R.value=!1,T.value=!1}async function v(r){I();const $=h.get(r);if($){f.value=$.detail,g.value=$.traces,n.value=!1,d.value=!1;return}n.value=!0,d.value=!0,f.value=null,g.value=[];const[B,H]=await Promise.allSettled([$fetch(`/api/test-run-cases/${r}`),$fetch(`/api/test-run-cases/${r}/traces`)]);B.status==="fulfilled"&&(f.value=B.value),n.value=!1,H.status==="fulfilled"&&(g.value=H.value),d.value=!1,B.status==="fulfilled"&&H.status==="fulfilled"&&h.set(r,{detail:B.value,traces:H.value})}const j=new Map,G=x(null),D=x("trace"),M=P(()=>G.value?.frames??[]);async function O(r){if(G.value=j.get(r)??null,j.has(r)||g.value.length===0)return;const $=f.value?.testRun?.id;if($)try{const B=await $fetch(`/api/test-runs/${$}/cases/${r}/trace-stacks`),H=B.status==="ok"&&B.frames?.length?B:null;j.set(r,H),u.value===r&&(G.value=H)}catch{j.set(r,null)}}ne([f,g],()=>{D.value="trace",u.value&&O(u.value)}),ne(u,r=>{r&&v(r)}),Oe(()=>{u.value&&v(u.value)});const A=P(()=>{const r=f.value?.steps;return Array.isArray(r)?r.filter($=>$.error):[]}),F=P(()=>f.value?.testSource?f.value.testSource.split(`
2
- `).length:0),z=P(()=>{const r=f.value;if(!r)return[];const $=r.attachments.filter(y=>ot(y.path,y.contentType)).length,B=r.attachments.filter(y=>lt(y.path,y.contentType)).length,H=Array.isArray(r.consoleLogs)?r.consoleLogs.filter(y=>y.type==="error"||y.type==="warning").length:0,X=Array.isArray(r.networkRequests)?r.networkRequests.filter(y=>(y.status??0)>=400).length:0;return[{icon:"i-lucide-image",label:"screenshots",count:$},{icon:"i-lucide-video",label:"videos",count:B},{icon:"i-lucide-bug-play",label:"traces",count:g.value.length},{icon:"i-lucide-list-checks",label:"failing steps",count:A.value.length},{icon:"i-lucide-triangle-alert",label:"signals",count:H+X},{icon:"i-lucide-code",label:"source",count:r.testSourceFrames?.length||(r.testSource?1:0)},{icon:"i-lucide-accessibility",label:"ARIA",count:r.ariaSnapshot?1:0}].filter(y=>y.count>0)});return(r,$)=>{const B=xe,H=ie,X=te,y=ue,i=dt,k=mt,N=ft,q=we,K=es,W=bt,Z=pt,ae=gt,se=at,oe=xt;return s(),l("div",ts,[a.affectedTestCases.length>1?(s(),l("div",ss,[(s(!0),l(L,null,Q(a.affectedTestCases,_=>(s(),l("button",{key:_.recentTestRunsCaseId,class:Y(["px-3 py-1.5 text-xs whitespace-nowrap border-b-2 -mb-px transition-colors",e(u)===_.recentTestRunsCaseId?"border-primary text-primary font-medium":"border-transparent text-gray-500 hover:text-gray-700 dark:hover:text-gray-300"]),title:_.title,onClick:le=>u.value=_.recentTestRunsCaseId},[w(o(_.title.split(" › ").pop())+" ",1),_.runCount>1?(s(),l("span",as,o(_.runCount)+"×",1)):m("",!0)],10,ns))),128))])):m("",!0),e(b)?(s(),l("div",os,[t("div",ls,[t("p",rs,o(e(b).title),1),c(B,{"file-path":e(b).filePath,"project-key":a.projectKey,"project-name":a.projectName,class:"text-xs text-gray-400"},null,8,["file-path","project-key","project-name"])]),c(H,{to:`/test-run-cases/${e(b).recentTestRunsCaseId}`,size:"xs",variant:"outline",color:"neutral","trailing-icon":"i-lucide-arrow-right"},{default:p(()=>[...$[6]||($[6]=[w(" Open test run case ",-1)])]),_:1},8,["to"])])):m("",!0),e(n)?(s(),l("div",is,[c(X,{name:"i-lucide-loader-circle",class:"size-5 animate-spin text-gray-400"})])):e(f)?(s(),l(L,{key:3},[e(z).length?(s(),l("div",cs,[(s(!0),l(L,null,Q(e(z),_=>(s(),S(y,{key:_.label,color:"neutral",variant:"subtle",size:"sm",class:"gap-1"},{default:p(()=>[c(X,{name:_.icon,class:"size-3"},null,8,["name"]),w(" "+o(_.count)+" "+o(_.label),1)]),_:2},1024))),128))])):m("",!0),c(i,{attachments:e(f).attachments},null,8,["attachments"]),c(k,{attachments:e(f).attachments},null,8,["attachments"]),c(N,{traces:e(g),loading:e(d)},null,8,["traces","loading"]),e(A).length>0?(s(),S(q,{key:1,icon:"i-lucide-list-checks",label:"Failing steps",count:e(A).length,open:e(C),"onUpdate:open":$[0]||($[0]=_=>J(C)?C.value=_:null)},{default:p(()=>[t("div",us,[(s(!0),l(L,null,Q(e(A),(_,le)=>(s(),l("div",{key:le,class:"px-3 py-2 space-y-0.5"},[t("p",ds,o(le+1)+". "+o(_.title),1),_.error?.message?(s(),l("p",ms,o(_.error.message),1)):m("",!0)]))),128))])]),_:1},8,["count","open"])):m("",!0),c(K,{"console-logs":e(f).consoleLogs,"network-requests":e(f).networkRequests,open:e(V),"onUpdate:open":$[1]||($[1]=_=>J(V)?V.value=_:null)},null,8,["console-logs","network-requests","open"]),e(f).testSourceFrames?.length||e(f).testSource||e(M).length?(s(),S(q,{key:2,icon:"i-lucide-code",label:"Test source",count:e(M).length||e(f).testSourceFrames?.length||e(F),open:e(E),"onUpdate:open":$[3]||($[3]=_=>J(E)?E.value=_:null)},{default:p(()=>[e(M).length&&(e(f).testSourceFrames?.length||e(f).testSource)?(s(),S(W,{key:0,modelValue:e(D),"onUpdate:modelValue":$[2]||($[2]=_=>J(D)?D.value=_:null),items:[{label:`Full stack (${e(M).length})`,value:"trace"},{label:`Captured (${e(f).testSourceFrames?.length||1})`,value:"captured"}],size:"xs",variant:"link",class:"mb-1.5",ui:{list:"gap-2",trigger:"px-1.5"}},null,8,["modelValue","items"])):m("",!0),t("div",fs,[e(D)==="trace"&&e(M).length?(s(),S(Z,{key:0,frames:e(M),"project-key":a.projectKey,"project-name":a.projectName},null,8,["frames","project-key","project-name"])):e(f).testSourceFrames?.length?(s(),S(ae,{key:1,frames:e(f).testSourceFrames,"project-key":a.projectKey,"project-name":a.projectName},null,8,["frames","project-key","project-name"])):e(f).testSource?(s(),S(se,{key:2,text:"```typescript\n"+e(f).testSource+"\n```"},null,8,["text"])):m("",!0)])]),_:1},8,["count","open"])):m("",!0),e(f).ariaSnapshot?(s(),S(q,{key:3,icon:"i-lucide-accessibility",label:"ARIA snapshot",open:e(R),"onUpdate:open":$[4]||($[4]=_=>J(R)?R.value=_:null)},{default:p(()=>[t("div",ps,[c(se,{text:"```yaml\n"+e(f).ariaSnapshot+"\n```"},null,8,["text"])])]),_:1},8,["open"])):m("",!0),e(f).pageState?(s(),S(q,{key:4,icon:"i-lucide-database",label:"App state",open:e(T),"onUpdate:open":$[5]||($[5]=_=>J(T)?T.value=_:null)},{default:p(()=>[c(oe,{"page-state":e(f).pageState,plain:""},null,8,["page-state"])]),_:1},8,["open"])):m("",!0)],64)):m("",!0)])}}}),xs=Object.assign(gs,{__name:"ClusterTestEvidence"}),vs={key:0,class:"flex items-center gap-1.5 overflow-hidden min-w-0"},_s={class:"text-primary shrink-0"},hs={class:"text-gray-500 truncate text-xs font-sans"},ys={key:1,class:"text-primary text-xs"},ks={key:2,class:"text-gray-400 font-sans text-xs"},bs={class:"w-96 p-2 space-y-2"},$s={class:"flex items-center gap-1"},Cs={class:"flex items-center gap-1"},ws={key:0,class:"flex items-center gap-2 px-2 py-1.5 text-xs rounded-md bg-primary/5 text-gray-600 dark:text-gray-300"},Ss={class:"font-medium text-green-600 dark:text-green-400"},Ts={class:"font-medium text-red-600 dark:text-red-400"},js={class:"text-gray-400"},Is={key:1,class:"flex items-center justify-center gap-2 py-6 text-gray-400"},Us={key:2,class:"py-4 text-center text-sm text-red-500"},zs={key:3,class:"flex items-start gap-2 px-2 py-2 text-xs text-amber-700 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20 rounded-md"},Rs={key:4,class:"max-h-80 overflow-y-auto space-y-px"},Es={class:"text-xs text-primary"},As={key:1,class:"py-4 text-center text-sm text-gray-400"},Vs=["onClick"],Ms={class:"text-xs text-primary shrink-0 w-14 pt-px"},Ns={class:"flex-1 min-w-0"},Fs={class:"text-xs font-medium leading-snug truncate"},Bs={class:"text-xs text-gray-400 leading-snug truncate"},Ls=ee({__name:"CommitPicker",props:{modelValue:{},clusterId:{}},emits:["update:modelValue"],setup(a,{emit:U}){const u=a,b=U,f=x(!1),g=x(""),n=x([]),d=x(null),C=x(null),V=x(!1),E=x(!1),R=x(null),T=x(null),h=x([]),I=x(!1),v=x(void 0),j=P(()=>{if(!u.modelValue)return null;const z=u.modelValue.trim();return n.value.find($=>$.sha===z||$.sha.startsWith(z))??{sha:z,shortSha:z.slice(0,7),message:"",author:"",date:""}});async function G(){if(!h.value.length){I.value=!0;try{const z=await $fetch(`/api/failure-clusters/${u.clusterId}/branches`);h.value=z.branches}catch{}finally{I.value=!1}}}async function D(){const z=u.modelValue||"";V.value=!0,E.value=!1,T.value=null;try{const r={};z&&(r.baseline=z),v.value&&(r.branch=v.value);const $=await $fetch(`/api/failure-clusters/${u.clusterId}/commits`,{query:r});n.value=$.commits,C.value=$.aggregate,d.value=$.error??null,T.value=z}catch{E.value=!0}finally{V.value=!1}}ne(v,()=>{n.value=[],T.value=null,D()}),ne(f,async z=>{if(z){await Promise.all([G(),D()]),await qe();const r=R.value?.$el?.querySelector("input")??R.value?.$el;r instanceof HTMLElement&&r.focus()}else g.value=""});const M=P(()=>Ce(n.value,g.value)),O=P(()=>{const z=g.value.trim();return!/^[0-9a-f]{7,40}$/i.test(z)||M.value.some(r=>r.sha.startsWith(z.toLowerCase()))?null:z});function A(z){b("update:modelValue",z),f.value=!1}function F(z){z.stopPropagation(),d.value=null,C.value=null,b("update:modelValue",""),f.value=!1}return(z,r)=>{const $=ie,B=te,H=$t,X=ke,y=He;return s(),S(y,{open:e(f),"onUpdate:open":r[4]||(r[4]=i=>J(f)?f.value=i:null)},{content:p(()=>[t("div",bs,[t("div",$s,[c(B,{name:"i-lucide-git-branch",class:"size-3.5 text-gray-400 shrink-0"}),c(H,{modelValue:e(v),"onUpdate:modelValue":r[0]||(r[0]=i=>J(v)?v.value=i:null),items:e(h),placeholder:"Default branch",size:"xs",class:"flex-1",loading:e(I),disabled:e(I)},null,8,["modelValue","items","loading","disabled"])]),t("div",Cs,[c(X,{ref_key:"searchInputRef",ref:R,modelValue:e(g),"onUpdate:modelValue":r[1]||(r[1]=i=>J(g)?g.value=i:null),placeholder:"Search message, author, SHA…",size:"xs",icon:"i-lucide-search",class:"flex-1"},null,8,["modelValue"]),a.modelValue?(s(),S($,{key:0,size:"xs",color:"neutral",variant:"ghost",icon:"i-lucide-x",title:"Clear baseline",onClick:r[2]||(r[2]=i=>F(i))})):m("",!0)]),e(C)&&a.modelValue&&!e(V)?(s(),l("div",ws,[c(B,{name:"i-lucide-git-compare-arrows",class:"size-3.5 shrink-0 text-primary"}),r[5]||(r[5]=t("span",null,"Since baseline:",-1)),t("span",Ss,"+"+o(e(C).linesAdded),1),t("span",Ts,"-"+o(e(C).linesRemoved),1),t("span",js,"across "+o(e(C).filesChanged)+" file"+o(e(C).filesChanged===1?"":"s"),1)])):m("",!0),e(V)?(s(),l("div",Is,[c(B,{name:"i-lucide-loader-2",class:"size-4 animate-spin"}),r[6]||(r[6]=t("span",{class:"text-sm"},"Loading commits…",-1))])):e(E)?(s(),l("div",Us," Failed to load commits — check your SCM token in Settings → AI ")):e(d)&&!e(V)&&e(n).length===0?(s(),l("div",zs,[c(B,{name:"i-lucide-triangle-alert",class:"size-3.5 shrink-0 mt-0.5"}),t("span",null,o(e(d)),1)])):(s(),l("div",Rs,[e(O)?(s(),l("button",{key:0,class:"w-full text-left px-2 py-1.5 rounded flex items-center gap-2 hover:bg-elevated transition-colors border border-dashed border-default",onClick:r[3]||(r[3]=i=>A(e(O)))},[c(B,{name:"i-lucide-git-commit-horizontal",class:"size-3.5 text-gray-400 shrink-0"}),r[7]||(r[7]=t("span",{class:"text-xs text-gray-500"},"Use commit",-1)),t("code",Es,o(e(O).slice(0,7)),1)])):m("",!0),e(M).length===0&&!e(O)?(s(),l("div",As,o(e(g)?"No commits match":"No commits available"),1)):m("",!0),(s(!0),l(L,null,Q(e(M),i=>(s(),l("button",{key:i.sha,class:Y(["w-full text-left px-2 py-1.5 rounded flex items-start gap-2 hover:bg-elevated transition-colors",a.modelValue===i.sha?"bg-primary/10 ring-1 ring-inset ring-primary/30":""]),onClick:k=>A(i.sha)},[t("code",Ms,o(i.shortSha),1),t("div",Ns,[t("p",Fs,o(i.message),1),t("p",Bs,[w(o(i.author),1),i.date?(s(),l(L,{key:0},[w(" · "+o(e(ce)(i.date)),1)],64)):m("",!0)])]),a.modelValue===i.sha?(s(),S(B,{key:0,name:"i-lucide-check",class:"size-3.5 text-primary shrink-0 mt-0.5"})):m("",!0)],10,Vs))),128))]))])]),default:p(()=>[c($,{size:"xs",color:"neutral",variant:"outline",icon:a.modelValue?"i-lucide-git-branch-plus":"i-lucide-git-branch","trailing-icon":"i-lucide-chevron-down",class:"min-w-36 max-w-48 font-mono"},{default:p(()=>[e(j)?.message?(s(),l("span",vs,[t("code",_s,o(e(j).shortSha),1),t("span",hs,o(e(j).message),1)])):a.modelValue?(s(),l("span",ys,o(a.modelValue.slice(0,7))+"…",1)):(s(),l("span",ks,"baseline commit…"))]),_:1},8,["icon"])]),_:1},8,["open"])}}}),Ps=Object.assign(Ls,{__name:"CommitPicker"}),Ds={class:"space-y-3"},Os={key:0,class:"space-y-1"},Hs={class:"text-xs font-semibold text-gray-500 uppercase tracking-wide px-1"},qs={class:"rounded-md border border-default overflow-hidden divide-y divide-default"},Gs={class:"text-xs text-gray-400 shrink-0"},Ks={class:"text-xs text-gray-700 dark:text-gray-300 truncate"},Ws={class:"space-y-1"},Js={class:"text-xs font-semibold text-gray-500 uppercase tracking-wide px-1"},Zs={key:0,class:"text-yellow-500 font-normal normal-case"},Qs={class:"rounded-md border border-default overflow-hidden divide-y divide-default"},Xs=["onClick"],Ys={class:"text-xs font-mono flex-1 truncate text-gray-700 dark:text-gray-300"},en={class:"text-xs text-gray-400 shrink-0 tabular-nums"},tn={key:0,class:"text-green-500"},sn={key:1,class:"text-gray-300 mx-0.5"},nn={key:2,class:"text-red-500"},an={key:0,class:"border-t border-default overflow-x-auto max-h-96"},on=ee({__name:"ScmChangesView",props:{changes:{}},setup(a){const U=x(new Set);function u(b){const f=new Set(U.value);f.has(b)?f.delete(b):f.add(b),U.value=f}return(b,f)=>{const g=te,n=Se;return s(),l("div",Ds,[a.changes.commits.length>0?(s(),l("div",Os,[t("p",Hs,o(a.changes.commits.length)+" commit"+o(a.changes.commits.length===1?"":"s"),1),t("div",qs,[(s(!0),l(L,null,Q(a.changes.commits,d=>(s(),l("div",{key:d.sha,class:"flex items-center gap-2 px-3 py-1.5"},[c(g,{name:"i-lucide-git-commit-horizontal",class:"size-3.5 text-gray-400 shrink-0"}),t("code",Gs,o(d.sha.slice(0,7)),1),t("span",Ks,o(d.message),1)]))),128))])])):m("",!0),t("div",Ws,[t("p",Js,[w(o(a.changes.files.length)+" file"+o(a.changes.files.length===1?"":"s")+" changed ",1),a.changes.patchesOmitted?(s(),l("span",Zs," — diff too large, file names only ")):m("",!0)]),t("div",Qs,[(s(!0),l(L,null,Q(a.changes.files,d=>(s(),l("div",{key:d.filename},[t("button",{class:Y(["w-full flex items-center gap-2 px-3 py-1.5 text-left hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors",d.patch?"cursor-pointer":"cursor-default"]),onClick:C=>d.patch&&u(d.filename)},[c(g,{name:("scmFileStatusMeta"in b?b.scmFileStatusMeta:e(pe))(d.status).icon,class:Y(["size-3.5 shrink-0",("scmFileStatusMeta"in b?b.scmFileStatusMeta:e(pe))(d.status).color])},null,8,["name","class"]),t("span",Ys,o(d.filename),1),t("span",en,[d.additions?(s(),l("span",tn,"+"+o(d.additions),1)):m("",!0),d.additions&&d.deletions?(s(),l("span",sn,"/")):m("",!0),d.deletions?(s(),l("span",nn,"-"+o(d.deletions),1)):m("",!0)]),d.patch?(s(),S(g,{key:0,name:e(U).has(d.filename)?"i-lucide-chevron-up":"i-lucide-chevron-down",class:"size-3.5 text-gray-400 shrink-0"},null,8,["name"])):m("",!0)],10,Xs),d.patch&&e(U).has(d.filename)?(s(),l("div",an,[c(n,{patch:d.patch},null,8,["patch"])])):m("",!0)]))),128))])])])}}}),ln=Object.assign(on,{__name:"ScmChangesView"}),rn={class:"border border-default rounded-lg overflow-clip text-xs font-mono"},cn={class:"sticky top-0 z-10 flex items-center justify-between px-3 py-1.5 bg-elevated border-b border-default text-gray-600 dark:text-gray-300"},un={class:"font-medium truncate"},dn={class:"shrink-0 flex items-center gap-1.5 ml-2 text-[11px]"},mn={key:0,class:"text-green-600 dark:text-green-400"},fn={key:1,class:"text-red-600 dark:text-red-400"},pn={key:1,class:"px-3 py-2 text-gray-400 text-[11px]"},gn=ee({__name:"DiffFile",props:{file:{}},setup(a){return(U,u)=>{const b=ue,f=Se;return s(),l("div",rn,[t("div",cn,[t("span",un,o(a.file.filename),1),t("span",dn,[a.file.additions?(s(),l("span",mn,"+"+o(a.file.additions),1)):m("",!0),a.file.deletions?(s(),l("span",fn,"-"+o(a.file.deletions),1)):m("",!0),c(b,{label:a.file.status,size:"xs",variant:"subtle",color:("scmFileStatusMeta"in U?U.scmFileStatusMeta:e(pe))(a.file.status).badgeColor},null,8,["label","color"])])]),a.file.patch?(s(),S(f,{key:0,patch:a.file.patch},null,8,["patch"])):(s(),l("div",pn,"No patch available"))])}}}),xn=Object.assign(gn,{__name:"DiffFile"}),vn={class:"inline-flex items-center gap-1"},_n={class:"flex h-[72vh] overflow-hidden"},hn={class:"w-72 shrink-0 border-r border-default flex flex-col"},yn={class:"p-2 border-b border-default space-y-2 shrink-0"},kn={class:"flex items-center gap-2 text-xs text-gray-500"},bn={class:"ml-auto"},$n={key:2,class:"flex-1 overflow-y-auto flex flex-col"},Cn={key:0,class:"py-6 text-center text-sm text-gray-400 flex-1"},wn=["onClick"],Sn=["checked","onChange"],Tn={class:"flex-1 min-w-0"},jn={class:"text-xs font-medium leading-snug truncate"},In={class:"text-[10px] text-gray-400 leading-snug mt-0.5 flex items-center gap-1 min-w-0"},Un={class:"text-primary shrink-0"},zn={class:"truncate"},Rn={key:0,class:"shrink-0"},En={key:1,class:"p-2 shrink-0 space-y-1.5"},An={key:0,class:"flex items-center gap-1.5 text-xs text-red-500 px-1"},Vn={class:"flex-1 overflow-y-auto flex flex-col min-w-0"},Mn={key:0,class:"flex-1 flex items-center justify-center text-gray-400 text-sm"},Nn={key:2,class:"flex-1 p-4 space-y-3"},Fn={key:0,class:"space-y-0.5 pb-3 border-b border-default"},Bn={class:"flex items-center gap-2"},Ln={class:"text-xs font-mono text-primary"},Pn={class:"text-xs text-gray-400"},Dn={class:"text-sm font-semibold"},On={key:1,class:"text-sm text-gray-400 pt-2"},Hn={key:4,class:"flex-1 flex items-center justify-center text-sm text-gray-400"},qn={class:"flex items-center gap-3 w-full"},Gn={class:"flex-1 flex items-center gap-2 text-sm text-gray-500 min-w-0"},Kn={class:"font-medium text-gray-700 dark:text-gray-200 shrink-0"},Wn={class:"shrink-0"},Jn={class:"text-green-600 dark:text-green-400 shrink-0 font-medium"},Zn={class:"text-red-600 dark:text-red-400 shrink-0 font-medium"},Qn={key:1,class:"text-gray-400 text-xs shrink-0"},Xn={key:1},me=50,Yn=ee({__name:"CommitBrowserModal",props:{open:{type:Boolean},clusterId:{},initialSelected:{},autoSelectedShas:{}},emits:["update:open","confirm"],setup(a,{emit:U}){const u=a,b=P(()=>new Set(u.autoSelectedShas??[])),f=U,g=x(""),n=x([]),d=x(me),C=x(!1),V=x(!1),E=x(!1),R=x(null),T=x(null),h=x(new Set),I=x(null),v=Ge({}),j=x(null),G=x(!1),D=x(null),M=P(()=>n.value.find(y=>y.sha===I.value)??null),O=P(()=>Ce(n.value,g.value)),A=P(()=>{let y=0,i=0,k=0,N=0;for(const q of h.value){if(!(q in v)){N++;continue}const K=v[q];K&&(y+=K.files.length,i+=K.files.reduce((W,Z)=>W+Z.additions,0),k+=K.files.reduce((W,Z)=>W+Z.deletions,0))}return{files:y,linesAdded:i,linesRemoved:k,unreviewed:N}});async function F(y){y?(V.value=!0,R.value=null):(E.value=!0,T.value=null);try{const i=await $fetch(`/api/failure-clusters/${u.clusterId}/commits`,{query:{limit:d.value}});n.value=i.commits,C.value=i.hasMore??!1,i.error&&!i.commits.length&&(y?R.value=i.error:T.value=i.error),y&&i.commits[0]&&r(i.commits[0].sha)}catch(i){y?R.value=de(i):T.value=de(i)}finally{V.value=!1,E.value=!1}}async function z(){d.value+=me,await F(!1)}ne(()=>u.open,async y=>{if(y){if(h.value=new Set(u.initialSelected??[]),n.value.length){!I.value&&n.value[0]&&r(n.value[0].sha);return}d.value=me,await F(!0)}});async function r(y){if(I.value!==y){if(I.value=y,D.value=null,y in v){j.value=v[y],G.value=!1;return}j.value=null,G.value=!0;try{const i=await $fetch(`/api/failure-clusters/${u.clusterId}/commit-diff`,{query:{sha:y}});v[y]=i,I.value===y&&(j.value=i)}catch(i){I.value===y&&(D.value=de(i))}finally{I.value===y&&(G.value=!1)}}}function $(y){const i=new Set(h.value);i.has(y)?i.delete(y):i.add(y),h.value=i}function B(){h.value=new Set(O.value.map(y=>y.sha))}function H(){h.value=new Set}function X(){f("confirm",[...h.value]),f("update:open",!1)}return(y,i)=>{const k=ge,N=ke,q=Ct,K=ie,W=wt,Z=ue,ae=te,se=xn,oe=Te;return s(),S(oe,{open:a.open,title:"Browse commits",ui:{content:"max-w-6xl",body:"p-0 overflow-hidden"},"onUpdate:open":i[4]||(i[4]=_=>f("update:open",_))},{title:p(()=>[t("span",vn,[i[5]||(i[5]=w("Browse commits ",-1)),c(k,{topic:"cluster.commit-browser"})])]),body:p(()=>[t("div",_n,[t("div",hn,[t("div",yn,[c(N,{modelValue:e(g),"onUpdate:modelValue":i[0]||(i[0]=_=>J(g)?g.value=_:null),placeholder:"Search commits…",size:"xs",icon:"i-lucide-search"},null,8,["modelValue"]),t("div",kn,[t("button",{class:"hover:text-primary transition-colors",onClick:B},"All"),i[6]||(i[6]=t("span",null,"·",-1)),t("button",{class:"hover:text-primary transition-colors",onClick:H},"None"),t("span",bn,o(e(h).size>0?`${e(h).size} selected`:"none selected"),1)])]),e(V)?(s(),S(q,{key:0,text:"Loading…",padded:!1,class:"flex-1"})):e(R)?(s(),S(W,{key:1,text:e(R),padded:!1,class:"flex-1 p-4"},{action:p(()=>[c(K,{size:"xs",color:"neutral",variant:"outline",onClick:i[1]||(i[1]=_=>F(!0))},{default:p(()=>[...i[7]||(i[7]=[w(" Retry ",-1)])]),_:1})]),_:1},8,["text"])):(s(),l("div",$n,[e(O).length===0?(s(),l("div",Cn,o(e(g)?"No commits match":"No commits"),1)):m("",!0),(s(!0),l(L,null,Q(e(O),_=>(s(),l("button",{key:_.sha,class:Y(["w-full text-left px-2.5 py-2 flex items-start gap-2.5 hover:bg-elevated transition-colors border-b border-default/50 last:border-0 shrink-0",e(I)===_.sha?"bg-elevated":""]),onClick:le=>r(_.sha)},[t("input",{type:"checkbox",checked:e(h).has(_.sha),class:"mt-0.5 shrink-0 cursor-pointer accent-primary",onClick:i[2]||(i[2]=fe(()=>{},["stop"])),onChange:le=>$(_.sha)},null,40,Sn),t("div",Tn,[t("p",jn,o(_.message||"(no message)"),1),t("p",In,[t("code",Un,o(_.shortSha),1),t("span",zn,o(_.author),1),_.date?(s(),l("span",Rn,"· "+o(e(ce)(_.date)),1)):m("",!0),e(b).has(_.sha)?(s(),S(Z,{key:1,size:"xs",color:"info",variant:"soft",class:"shrink-0"},{default:p(()=>[...i[8]||(i[8]=[w(" auto ",-1)])]),_:1})):m("",!0)])])],10,wn))),128)),e(C)&&!e(g)?(s(),l("div",En,[e(T)?(s(),l("p",An,[c(ae,{name:"i-lucide-circle-alert",class:"size-3.5 shrink-0"}),w(" "+o(e(T)),1)])):m("",!0),c(K,{size:"xs",color:"neutral",variant:"outline",block:"",loading:e(E),onClick:z},{default:p(()=>[...i[9]||(i[9]=[w(" Load more ",-1)])]),_:1},8,["loading"])])):m("",!0)]))]),t("div",Vn,[e(I)?e(G)?(s(),S(q,{key:1,text:"Loading diff…",padded:!1,class:"flex-1"})):e(j)?(s(),l("div",Nn,[e(M)?(s(),l("div",Fn,[t("div",Bn,[t("code",Ln,o(e(M).shortSha),1),t("span",Pn,[w(o(e(M).author),1),e(M).date?(s(),l(L,{key:0},[w(" · "+o(e(ce)(e(M).date)),1)],64)):m("",!0)])]),t("p",Dn,o(e(M).message),1)])):m("",!0),e(j).files.length===0?(s(),l("div",On,"No file changes in this commit")):m("",!0),(s(!0),l(L,null,Q(e(j).files,_=>(s(),S(se,{key:_.filename,file:_},null,8,["file"]))),128))])):e(D)?(s(),S(W,{key:3,text:e(D),padded:!1,class:"flex-1 p-6"},{action:p(()=>[...i[10]||(i[10]=[t("p",{class:"text-xs text-gray-400"},"Click the commit again to retry",-1)])]),_:1},8,["text"])):(s(),l("div",Hn," Diff not available for this commit ")):(s(),l("div",Mn," Select a commit to view its diff "))])])]),footer:p(()=>[t("div",qn,[t("div",Gn,[e(h).size>0?(s(),l(L,{key:0},[t("span",Kn,o(e(h).size)+" commit"+o(e(h).size===1?"":"s"),1),e(A).files>0||e(A).linesAdded>0||e(A).linesRemoved>0?(s(),l(L,{key:0},[i[11]||(i[11]=t("span",{class:"text-gray-300 dark:text-gray-600"},"·",-1)),t("span",Wn,o(e(A).files)+" file"+o(e(A).files===1?"":"s"),1),t("span",Jn,"+"+o(e(A).linesAdded),1),t("span",Zn,"-"+o(e(A).linesRemoved),1)],64)):m("",!0),e(A).unreviewed>0?(s(),l("span",Qn," ("+o(e(A).unreviewed)+" unreviewed) ",1)):m("",!0)],64)):(s(),l("span",Xn,"No commits selected"))]),c(K,{color:"neutral",variant:"ghost",onClick:i[3]||(i[3]=_=>f("update:open",!1))},{default:p(()=>[...i[12]||(i[12]=[w(" Cancel ",-1)])]),_:1}),c(K,{color:"primary",disabled:e(h).size===0,onClick:X},{default:p(()=>[...i[13]||(i[13]=[w(" Add to context ",-1)])]),_:1},8,["disabled"])])]),_:1},8,["open"])}}}),ea=Object.assign(Yn,{__name:"CommitBrowserModal"});function je(a){return{scmStatus:P(()=>{const u=a.value?.scm;if(!u)return{color:"text-gray-400",icon:"i-lucide-git-branch",text:"Git context unavailable",detail:""};if(u.baseCommitUsed){if(u.filesCount===0)return{color:"text-yellow-500",icon:"i-lucide-git-branch-plus",text:`Manual baseline ${u.baseCommitUsed.slice(0,7)} · fetch failed`,detail:"network error or missing SCM token (check AI settings)"};const g=u.patchesOmitted?", no patches (diff too large)":u.patchesTruncated?`, ${u.patchedFilesCount} with patches (some cut)`:`, ${u.patchedFilesCount} with patches`;return{color:"text-blue-500",icon:"i-lucide-git-branch-plus",text:`Manual baseline ${u.baseCommitUsed.slice(0,7)} · ${u.filesCount} files${g}`,detail:u.hasLastGreen?"overrides last passing run baseline":"no last passing run"}}if(!u.hasLastGreen)return{color:"text-gray-400",icon:"i-lucide-git-branch",text:"No last passing run",detail:"enter a baseline commit below to enable diff"};if(!u.hasCommitRange)return{color:"text-gray-400",icon:"i-lucide-git-branch",text:"No commit range",detail:"reporter did not send SCM metadata"};if(!u.provider)return{color:"text-yellow-500",icon:"i-lucide-git-branch",text:"Unsupported SCM host",detail:"only GitHub, GitLab and Bitbucket are supported"};if(u.filesCount===0)return{color:"text-yellow-500",icon:"i-lucide-git-branch",text:`${u.provider} · fetch failed`,detail:"network error or missing SCM token (check AI settings)"};if(u.patchesOmitted)return{color:"text-yellow-500",icon:"i-lucide-git-branch",text:`${u.provider} · ${u.filesCount} files`,detail:"diff too large — file list only, no patches"};const b=u.patchesTruncated?", some patches cut (budget)":"",f=u.commitsCount>0?` · ${u.commitsCount} commit${u.commitsCount>1?"s":""}`:"";return{color:"text-green-500",icon:"i-lucide-git-branch",text:`${u.provider} · ${u.filesCount} files · ${u.patchedFilesCount} with patches${b}${f}`,detail:""}})}}const ta={class:"space-y-3"},sa={class:"pb-2 border-b border-default"},na={class:"flex items-center gap-2 flex-wrap"},aa={class:"text-xs text-gray-500 font-medium shrink-0 inline-flex items-center gap-1"},oa={class:"flex items-center gap-1.5 ml-auto"},la={key:0,class:"flex items-center gap-1 px-2 py-0.5 rounded-full bg-primary/10 text-primary text-xs font-medium"},ra={key:0,class:"flex items-start gap-1.5 text-xs px-2 py-1.5 rounded-md bg-elevated border border-default"},ia={key:0,class:"text-gray-400 ml-1"},ca={key:1,class:"flex items-center justify-center py-6"},ua={key:3,class:"text-xs text-gray-400 text-center py-4"},da=ee({__name:"ClusterInvestigation",setup(a){const{clusterId:U,baseCommit:u,selectedCommitShas:b,autoSelectedCommits:f,baseCommitIsPinned:g,coverage:n,scmChanges:d,contextLoading:C,refreshContext:V}=St(),E=x(!1),{scmStatus:R}=je(n);return(T,h)=>{const I=ge,v=Ps,j=te,G=be,D=ie,M=ln,O=ea;return s(),l(L,null,[t("div",ta,[t("div",sa,[t("div",na,[t("span",aa,[h[5]||(h[5]=w(" Baseline ",-1)),c(I,{topic:"cluster.baseline"})]),c(v,{modelValue:e(u),"onUpdate:modelValue":h[0]||(h[0]=A=>J(u)?u.value=A:null),"cluster-id":e(U)},null,8,["modelValue","cluster-id"]),e(g)?(s(),S(G,{key:0,text:"Baseline commit pinned for this cluster"},{default:p(()=>[c(j,{name:"i-lucide-pin",class:"size-3.5 text-primary shrink-0"})]),_:1})):m("",!0),t("div",oa,[e(b).length?(s(),l("div",la,[c(j,{name:"i-lucide-git-commit-horizontal",class:"size-3"}),t("span",null,o(e(b).length)+" commit"+o(e(b).length===1?"":"s"),1),t("button",{class:"ml-0.5 hover:opacity-70 transition-opacity",onClick:h[1]||(h[1]=A=>b.value=[])},[c(j,{name:"i-lucide-x",class:"size-3"})])])):m("",!0),c(D,{size:"xs",color:"neutral",variant:"ghost",icon:"i-lucide-list",onClick:h[2]||(h[2]=A=>E.value=!0)},{default:p(()=>[...h[6]||(h[6]=[w(" Browse ",-1)])]),_:1}),c(D,{icon:"i-lucide-refresh-cw",size:"xs",color:"neutral",variant:"outline",loading:e(C),onClick:e(V)},null,8,["loading","onClick"])])])]),e(n)?(s(),l("div",ra,[c(j,{name:e(R).icon,class:Y(["size-3.5 mt-0.5 shrink-0",e(R).color])},null,8,["name","class"]),t("div",null,[t("span",{class:Y(e(R).color)},o(e(R).text),3),e(R).detail?(s(),l("span",ia,"— "+o(e(R).detail),1)):m("",!0)])])):m("",!0),e(C)&&!e(d)?(s(),l("div",ca,[c(j,{name:"i-lucide-loader-circle",class:"size-4 animate-spin text-gray-400"})])):e(d)?(s(),S(M,{key:2,changes:e(d)},null,8,["changes"])):e(n)&&!e(C)&&!e(d)?(s(),l("p",ua," No changes found in this range. ")):m("",!0)]),c(O,{open:e(E),"onUpdate:open":h[3]||(h[3]=A=>J(E)?E.value=A:null),"cluster-id":e(U),"initial-selected":e(b),"auto-selected-shas":e(f),onConfirm:h[4]||(h[4]=A=>b.value=A)},null,8,["open","cluster-id","initial-selected","auto-selected-shas"])],64)}}}),ma=Object.assign(da,{__name:"ClusterInvestigation"}),fa={class:"flex flex-col h-[60vh]"},pa={class:"flex items-center gap-3 px-4 py-2.5 border-b border-default text-sm shrink-0"},ga={key:0,class:"ml-auto text-xs text-gray-500"},xa={class:"flex-1 overflow-y-auto"},va={class:"w-full text-sm"},_a=["onClick"],ha={class:"px-4 py-2.5"},ya=["checked","onChange"],ka={class:"px-2 py-2.5 min-w-0"},ba={class:"truncate font-medium text-gray-800 dark:text-gray-200 max-w-[24rem]"},$a={class:"px-2 py-2.5 text-gray-500 text-xs max-w-[16rem] hidden sm:table-cell"},Ca={class:"px-2 py-2.5 text-right text-gray-500 text-xs"},wa={key:0},Sa={class:"shrink-0 border-t border-default px-4 py-3 space-y-1.5"},Ta={key:0,class:"shrink-0 px-4 pb-3 flex items-center gap-1.5 text-xs text-red-500"},ja={class:"flex items-center gap-3 w-full"},Ia=ee({__name:"ClusterExtractCasesModal",props:{open:{type:Boolean},clusterId:{},affectedTestCases:{},projectKey:{},projectName:{}},emits:["update:open","extracted"],setup(a,{emit:U}){const u=a,b=U,f=Ke(),g=x(new Set),n=x(""),d=x(!1),C=x(null);function V(){g.value=new Set(u.affectedTestCases.map(I=>I.testCaseId))}function E(){g.value=new Set}function R(I){const v=new Set(g.value);v.has(I)?v.delete(I):v.add(I),g.value=v}ne(()=>u.open,I=>{I&&(E(),n.value="",C.value=null)});const T=P(()=>g.value.size);async function h(){if(T.value!==0){d.value=!0,C.value=null;try{await $fetch(`/api/failure-clusters/${u.clusterId}/extract-cases`,{method:"POST",body:{testCaseIds:[...g.value],triageNote:n.value.trim()||void 0}}),f.add({title:`Extracted ${T.value} test ${T.value===1?"case":"cases"}`,color:"success"}),b("extracted"),b("update:open",!1)}catch(I){C.value=de(I)}finally{d.value=!1}}}return(I,v)=>{const j=ye,G=xe,D=$e,M=te,O=ie,A=Te;return s(),S(A,{open:a.open,title:"Extract test cases",ui:{content:"max-w-4xl",body:"p-0 flex flex-col overflow-hidden"},"onUpdate:open":v[4]||(v[4]=F=>b("update:open",F))},{body:p(()=>[t("div",fa,[t("div",pa,[t("button",{class:"text-xs font-medium text-primary hover:underline",onClick:V},"Select all"),v[5]||(v[5]=t("span",{class:"text-gray-300 dark:text-gray-600"},"·",-1)),t("button",{class:"text-xs font-medium text-primary hover:underline",onClick:E},"Deselect all"),e(T)>0?(s(),l("span",ga,o(e(T))+" selected ",1)):m("",!0)]),t("div",xa,[t("table",va,[v[8]||(v[8]=t("thead",{class:"sticky top-0 bg-gray-50 dark:bg-gray-800 border-b border-default"},[t("tr",null,[t("th",{class:"w-10 px-4 py-2.5"}),t("th",{class:"text-left px-2 py-2.5 font-medium text-gray-500 text-xs uppercase tracking-wide"},"Test"),t("th",{class:"text-left px-2 py-2.5 font-medium text-gray-500 text-xs uppercase tracking-wide hidden sm:table-cell"}," File "),t("th",{class:"text-right px-2 py-2.5 font-medium text-gray-500 text-xs uppercase tracking-wide w-20"}," Occurrences ")])],-1)),t("tbody",null,[(s(!0),l(L,null,Q(a.affectedTestCases,F=>(s(),l("tr",{key:F.testCaseId,class:"border-b border-default/50 hover:bg-elevated transition-colors cursor-pointer",onClick:z=>R(F.testCaseId)},[t("td",ha,[t("input",{type:"checkbox",checked:e(g).has(F.testCaseId),class:"shrink-0 cursor-pointer accent-primary",onClick:v[0]||(v[0]=fe(()=>{},["stop"])),onChange:z=>R(F.testCaseId)},null,40,ya)]),t("td",ka,[t("p",ba,o(F.title),1),c(j,{to:`/test-cases/${F.testCaseId}`,class:"text-[10px] text-primary hover:underline mt-0.5 inline-block",onClick:v[1]||(v[1]=fe(()=>{},["stop"]))},{default:p(()=>[...v[6]||(v[6]=[w(" View details ",-1)])]),_:1},8,["to"])]),t("td",$a,[c(G,{"file-path":F.filePath,"project-key":a.projectKey,"project-name":a.projectName,class:"max-w-full"},null,8,["file-path","project-key","project-name"])]),t("td",Ca,o(F.runCount),1)],8,_a))),128)),a.affectedTestCases.length===0?(s(),l("tr",wa,[...v[7]||(v[7]=[t("td",{colspan:"4",class:"px-4 py-8 text-center text-gray-400 text-sm"},"No test cases in this cluster.",-1)])])):m("",!0)])])]),t("div",Sa,[v[9]||(v[9]=t("label",{class:"text-xs font-medium text-gray-500 uppercase tracking-wide"},"Triage note (optional)",-1)),c(D,{modelValue:e(n),"onUpdate:modelValue":v[2]||(v[2]=F=>J(n)?n.value=F:null),placeholder:"Add a note explaining why these tests were extracted…",rows:2,class:"text-sm w-full"},null,8,["modelValue"])]),e(C)?(s(),l("p",Ta,[c(M,{name:"i-lucide-circle-alert",class:"size-3.5 shrink-0"}),w(" "+o(e(C)),1)])):m("",!0)])]),footer:p(()=>[t("div",ja,[v[11]||(v[11]=t("div",{class:"flex-1"},null,-1)),c(O,{color:"neutral",variant:"ghost",disabled:e(d),onClick:v[3]||(v[3]=F=>b("update:open",!1))},{default:p(()=>[...v[10]||(v[10]=[w(" Cancel ",-1)])]),_:1},8,["disabled"]),c(O,{color:"warning",disabled:e(T)===0,loading:e(d),onClick:h},{default:p(()=>[w(" Extract"+o(e(T)>0?` ${e(T)}`:""),1)]),_:1},8,["disabled","loading"])])]),_:1},8,["open"])}}}),Ua=Object.assign(Ia,{__name:"ClusterExtractCasesModal"}),za={key:0,class:"flex flex-col h-full min-h-0 max-xl:overflow-y-auto xl:overflow-hidden"},Ra={class:"border-b border-default shrink-0"},Ea={class:"grid grid-cols-1 xl:grid-cols-[3fr_2fr] gap-4 p-1 xl:flex-1 xl:min-h-0 xl:overflow-hidden"},Aa={class:"space-y-4 xl:overflow-y-auto"},Va={class:"font-mono text-xs"},Ma=["innerHTML"],Na={class:"inline-flex items-center gap-1.5"},Fa={class:"xl:overflow-y-auto"},Ba={key:1,class:"flex items-center justify-center h-64 text-gray-500"},ko=ee({__name:"[id]",async setup(a){let U,u;const b=We(),f=parseInt(String(b.params.id)),g=Tt(f),{data:n,refresh:d}=([U,u]=Je(()=>Ut(`/api/failure-clusters/${f}`,"$y4C0kntcH9")),U=await U,u(),U);Ze(P(()=>({title:`${n.value?.signature??"Failure cluster"} — Piwi Dashboard`})));const C=x(n.value?.status??"open"),V=x(n.value?.triageNote??""),E=x(!1);ne(()=>n.value?.status,k=>{k&&(C.value=k)}),ne(()=>n.value?.triageNote,k=>{V.value=k??""});const R=P(()=>C.value!==(n.value?.status??"open")||V.value.trim()!==(n.value?.triageNote??""));async function T(){E.value=!0;try{await $fetch(`/api/failure-clusters/${f}/status`,{method:"PATCH",body:{status:C.value,triageNote:V.value.trim()||null}}),d()}finally{E.value=!1}}const h=x(!1);function I(){h.value=!1,d()}const{copyRich:v,copied:j}=rt();function G(){const k=n.value;if(!k)return;const N=window.location.href,q=se=>se.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),K=[k.errorType,`${k.occurrences} occurrence${k.occurrences===1?"":"s"}`,`${k.affectedTests} test${k.affectedTests===1?"":"s"} affected`,k.status!=="open"?k.status:null].filter(Boolean).join(" · "),W=k.diagnosis?.status==="completed"&&k.diagnosis.summary?`AI diagnosis (${k.diagnosis.category??"unknown"}, ${k.diagnosis.confidence??"?"} confidence): ${k.diagnosis.summary}`:null,Z=[`❌ Failure cluster: ${k.signature}`,K,"",...k.sampleError?["Sample error:",ve(k.sampleError),""]:[],...W?[W,""]:[],`Cluster: ${N}`].join(`
3
- `),ae=[`<p><strong>❌ Failure cluster</strong>: <code>${q(k.signature)}</code></p>`,`<p><em>${q(K)}</em></p>`,k.sampleError?`<p><strong>Sample error:</strong></p><pre>${he(k.sampleError)}</pre>`:"",W?`<p><strong>AI diagnosis</strong> (${q(k.diagnosis?.category??"unknown")}, ${q(k.diagnosis?.confidence??"?")} confidence):<br>${q(k.diagnosis.summary)}</p>`:"",`<p>🔗 <a href="${N}">View failure cluster</a></p>`].join("");v(Z,ae,{toast:"Failure cluster copied"})}const D=P(()=>{const k=n.value?.sampleError;return k?ve(k).split(`
4
- `).find(N=>N.trim())??"":""}),{scmStatus:M}=je(g.coverage),O=P(()=>It((n.value?.affectedTestCases??[]).map(k=>({filePath:k.filePath,title:k.title,line:null,projectName:null})))),{copy:A,copied:F}=zt(),z=x(null),r=x(null),$=x(null),B=x(null),H=x(null),X=x(null),y={sampleError:()=>z.value,executionError:()=>z.value,environmentDiff:()=>B.value,visualDiff:()=>H.value,domSnapshot:()=>X.value,scmInvestigation:()=>$.value,selectedCommits:()=>$.value,topSuspectedCommit:()=>$.value,failingAction:()=>$.value,affectedTests:()=>r.value,testSource:()=>r.value,sourceFiles:()=>r.value,steps:()=>r.value,failingSteps:()=>r.value,console:()=>r.value,networkRequests:()=>r.value,serverTraces:()=>r.value,ariaSnapshot:()=>r.value,screenshots:()=>r.value,tracePointers:()=>r.value,artifacts:()=>r.value};Qe(it,{canLocate:k=>k in y,open:k=>y[k]?.()?.reveal()});const i=P(()=>[{label:"Home",icon:"i-lucide-house",to:"/"},{label:"Projects",to:"/projects"},...n.value?.project?[{label:n.value.project.label||n.value.project.name||"Project",to:`/projects/${n.value.project.id}?tab=failure-clusters`}]:[{label:"Project"}],{label:`Failure cluster #${f}`}]);return(k,N)=>{const q=Be,K=Le,W=ie,Z=be,ae=Ye,se=Jt,oe=vt,_=_t,le=ht,Ie=yt,Ue=kt,ze=xe,Re=ue,Ee=xs,Ae=te,Ve=ma,Me=jt,Ne=Xe,Fe=Ua;return s(),l(L,null,[c(Ne,{id:"failure-cluster-detail"},{header:p(()=>[c(ae,null,{leading:p(()=>[c(q),c(K,{items:e(i)},null,8,["items"])]),right:p(()=>[e(n)?(s(),S(Z,{key:0,text:e(j)?"Copied!":"Copy failure cluster"},{default:p(()=>[c(W,{size:"sm",variant:"ghost",color:"neutral",icon:e(j)?"i-lucide-check":"i-lucide-clipboard",onClick:G},null,8,["icon"])]),_:1},8,["text"])):m("",!0)]),_:1})]),body:p(()=>[e(n)?(s(),l("div",za,[t("div",Ra,[c(se,{cluster:e(n),"triage-status":e(C),"triage-note":e(V),"triage-saving":e(E),"triage-changed":e(R),"onUpdate:triageStatus":N[0]||(N[0]=re=>C.value=re),"onUpdate:triageNote":N[1]||(N[1]=re=>V.value=re),onSaveTriage:T},null,8,["cluster","triage-status","triage-note","triage-saving","triage-changed"])]),t("div",Ea,[t("div",Aa,[e(n).sampleError?(s(),S(oe,{key:0,ref_key:"errorSection",ref:z,"storage-key":"cluster-error",icon:"i-lucide-circle-x","icon-class":"text-red-500",title:"Error message"},{folded:p(()=>[t("span",Va,o(e(D)),1)]),default:p(()=>[t("div",{class:"text-xs font-mono overflow-x-auto whitespace-pre-wrap",innerHTML:e(he)(e(n).sampleError)},null,8,Ma)]),_:1},512)):m("",!0),e(n).affectedTestCases?.length&&e(n).affectedTestCases[0]?.recentTestRunsCaseId?(s(),S(_,{key:1,ref:"locatorSection","storage-key":"cluster-locators","run-id":e(n).lastSeenRunId,"test-runs-case-id":e(n).affectedTestCases[0].recentTestRunsCaseId,"affected-count":e(n).affectedTestCases.length},null,8,["run-id","test-runs-case-id","affected-count"])):m("",!0),e(n).affectedTestCases?.length&&e(n).affectedTestCases[0]?.recentTestRunsCaseId?(s(),S(le,{key:2,ref_key:"envDiffSection",ref:B,"storage-key":"cluster-env-diff","run-id":e(n).lastSeenRunId,"test-runs-case-id":e(n).affectedTestCases[0].recentTestRunsCaseId},null,8,["run-id","test-runs-case-id"])):m("",!0),e(n).affectedTestCases?.length&&e(n).affectedTestCases[0]?.recentTestRunsCaseId?(s(),S(Ie,{key:3,ref_key:"visualDiffSection",ref:H,"storage-key":"cluster-visual-diff","run-id":e(n).lastSeenRunId,"test-runs-case-id":e(n).affectedTestCases[0].recentTestRunsCaseId},null,8,["run-id","test-runs-case-id"])):m("",!0),e(n).affectedTestCases?.length&&e(n).affectedTestCases[0]?.recentTestRunsCaseId?(s(),S(Ue,{key:4,ref_key:"domSnapshotSection",ref:X,"storage-key":"cluster-dom-snapshot","run-id":e(n).lastSeenRunId,"test-runs-case-id":e(n).affectedTestCases[0].recentTestRunsCaseId},null,8,["run-id","test-runs-case-id"])):m("",!0),e(n).affectedTestCases?.length?(s(),S(oe,{key:5,ref_key:"evidenceSection",ref:r,"storage-key":"cluster-evidence",icon:"i-lucide-flask-conical",title:"Test evidence",help:"cluster.evidence"},{folded:p(()=>[w(o(e(n).affectedTests)+" "+o(e(n).affectedTests===1?"test":"tests")+" · "+o(e(n).occurrences)+" occurrence"+o(e(n).occurrences===1?"":"s")+" · ",1),e(n).affectedTestCases[0]?.filePath?(s(),S(ze,{key:0,"file-path":e(n).affectedTestCases[0].filePath,"project-key":e(n).project?.id,"project-name":e(n).project?.name,class:"text-xs"},null,8,["file-path","project-key","project-name"])):m("",!0)]),actions:p(()=>[c(Re,{color:"neutral",variant:"subtle",size:"sm"},{default:p(()=>[w(o(e(n).affectedTestCases.length)+" "+o(e(n).affectedTestCases.length===1?"test":"tests"),1)]),_:1}),c(W,{size:"xs",variant:"outline",color:"neutral",icon:e(F)?"i-lucide-check":"i-lucide-play",title:e(F)?"Copied!":("copyPreview"in k?k.copyPreview:e(ut))(e(O)),onClick:N[2]||(N[2]=re=>e(A)(e(O),{toast:"Retry command copied"}))},{default:p(()=>[...N[5]||(N[5]=[w(" Copy retry command ",-1)])]),_:1},8,["icon","title"]),c(Z,{text:"Unlink incorrectly clustered test cases from this group"},{default:p(()=>[c(W,{size:"xs",color:"warning",variant:"outline",icon:"i-lucide-arrow-up-from-line",onClick:N[3]||(N[3]=re=>h.value=!0)},{default:p(()=>[...N[6]||(N[6]=[w(" Extract ",-1)])]),_:1})]),_:1})]),default:p(()=>[c(Ee,{"affected-test-cases":e(n).affectedTestCases,"project-key":e(n).project?.id,"project-name":e(n).project?.name},null,8,["affected-test-cases","project-key","project-name"])]),_:1},512)):m("",!0),c(oe,{ref_key:"scmSection",ref:$,"storage-key":"cluster-scm",icon:"i-lucide-git-compare-arrows",title:"What changed",help:"cluster.scm"},{folded:p(()=>[t("span",Na,[c(Ae,{name:e(M).icon,class:Y(["size-3.5 shrink-0",e(M).color])},null,8,["name","class"]),t("span",{class:Y(e(M).color)},o(e(M).text),3)])]),default:p(()=>[c(Ve)]),_:1},512)]),t("div",Fa,[c(Me,{"cluster-id":e(f),"last-seen-run-id":e(n)?.lastSeenRunId,"affected-test-cases":e(n)?.affectedTestCases??[]},null,8,["cluster-id","last-seen-run-id","affected-test-cases"])])])])):(s(),l("div",Ba,"Cluster not found."))]),_:1}),e(n)?(s(),S(Fe,{key:0,open:e(h),"cluster-id":e(f),"affected-test-cases":e(n).affectedTestCases??[],"project-key":e(n).project?.id,"project-name":e(n).project?.name,"onUpdate:open":N[4]||(N[4]=re=>h.value=re),onExtracted:I},null,8,["open","cluster-id","affected-test-cases","project-key","project-name"])):m("",!0)],64)}}});export{ko as default};
@@ -1,47 +0,0 @@
1
- import{_ as ke,a as Re}from"./BAaSmp8J.js";import{d as Q,o as r,c as d,f as y,g as u,i as e,j as l,v as X,p as F,t as c,l as se,k as n,q as f,m,h as g,_ as Z,x as oe,F as A,y as L,r as J,C as we,s as $e,K as Ce,e as Te,aa as Fe}from"./D3SYPlEB.js";import{_ as je}from"./DaewB_zT.js";import{_ as Se}from"./D4SFgXAf.js";import{_ as Pe,a as ze}from"./87SGk1nu.js";import{_ as Ie}from"./DM_YaJgJ.js";import{_ as Ue}from"./lowCGL2S.js";import{_ as Ne}from"./B6IHiVa1.js";import{_ as Ve}from"./ClVRQpP_.js";import{_ as Ae}from"./DraETso1.js";import{_ as ie}from"./HTQtMbWb.js";import{_ as De}from"./DOr_4nln.js";import{_ as Ee}from"./KYucVFu7.js";import{_ as le}from"./empGC_x-.js";import{f as ne,h as ue,B as M,e as Oe}from"./BUMZHDRC.js";import{a as Be,d as Le,_ as We}from"./C8cz5feG.js";import{_ as He}from"./oFIS9u6t.js";import{_ as de}from"./DoFSKAvY.js";import{u as Me}from"./CiPH-swI.js";import{u as re}from"./Doul3p1_.js";import{u as Ke}from"./DoYgYLOd.js";import{u as Ge}from"./B6rt3IcG.js";import"./Dbg8z684.js";import"./Cx65B3c3.js";import"./rm7OkgDG.js";import"./Vnfkr1pJ.js";import"./va1mwSm9.js";import"./wgcgHmRR.js";import"./Do6zIWQf.js";import"./BAkJhSAW.js";import"./r3SBLxtE.js";import"./D3MWm6JP.js";const Ye={class:"flex items-center gap-3 flex-wrap"},qe={class:"flex items-center gap-1.5"},Je={key:0,class:"text-gray-500"},Qe={key:1},Xe={key:2},Ze={class:"flex items-center gap-1.5 cursor-pointer select-none text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors"},et=Q({__name:"HomeFilters",props:{modelValue:{},availableEnvironments:{}},emits:["update:modelValue"],setup(D,{emit:$}){const C=D,v=$,I=g({get:()=>C.modelValue.environments,set:S=>v("update:modelValue",{...C.modelValue,environments:S})}),R=g({get:()=>C.modelValue.fullRunsOnly,set:S=>v("update:modelValue",{...C.modelValue,fullRunsOnly:S})}),U=g(()=>C.modelValue.environments.length>0||!C.modelValue.fullRunsOnly);function N(){v("update:modelValue",{environments:[],fullRunsOnly:!0})}return(S,_)=>{const E=X,o=je,x=Se,h=Z;return r(),d("div",Ye,[D.availableEnvironments.length>0?(r(),y(o,{key:0,modelValue:n(I),"onUpdate:modelValue":_[0]||(_[0]=t=>se(I)?I.value=t:null),items:D.availableEnvironments,multiple:"",placeholder:"All environments",size:"sm",class:"min-w-[160px]"},{default:u(({modelValue:t})=>[e("div",qe,[l(E,{name:"i-lucide-server",class:F(["size-3.5 shrink-0",t.length?"text-primary":"text-gray-400"])},null,8,["class"]),t.length?t.length===1?(r(),d("span",Qe,c(t[0]),1)):(r(),d("span",Xe,c(t.length)+" environments",1)):(r(),d("span",Je,"All environments"))])]),_:1},8,["modelValue","items"])):f("",!0),e("label",Ze,[l(x,{modelValue:n(R),"onUpdate:modelValue":_[1]||(_[1]=t=>se(R)?R.value=t:null),size:"sm"},null,8,["modelValue"]),_[2]||(_[2]=m(" Full runs only ",-1))]),n(U)?(r(),y(h,{key:1,variant:"ghost",size:"sm",color:"neutral",icon:"i-lucide-x",onClick:N},{default:u(()=>[..._[3]||(_[3]=[m(" Reset ",-1)])]),_:1})):f("",!0)])}}}),tt=Object.assign(et,{__name:"HomeFilters"}),st={class:"hidden md:block overflow-x-auto -mx-4 px-4 sm:mx-0 sm:px-0"},nt={key:0,class:"flex flex-wrap gap-1 mt-0.5"},rt={class:"w-40"},at={key:1,class:"text-gray-400 text-sm"},ot={class:"text-xs text-gray-500 dark:text-gray-400"},it={key:0},lt={key:1,class:"text-gray-400 text-sm"},ut={key:0,class:"tabular-nums text-sm text-gray-600 dark:text-gray-400"},dt={key:1,class:"text-gray-400"},ct={class:"space-y-2 md:hidden"},mt={class:"flex items-start justify-between gap-2"},pt={key:0,class:"flex flex-wrap gap-1"},gt={class:"flex items-center justify-between gap-2 text-xs"},ft={class:"text-gray-500 dark:text-gray-400 truncate"},yt={key:1,class:"text-gray-400"},xt={key:2,class:"shrink-0 tabular-nums text-gray-500 dark:text-gray-400"},_t=Q({__name:"ProjectTrendTable",props:{projects:{},limit:{default:10}},setup(D){const $=D,C={failing:0,flaky:1,passing:2,unknown:3},v=J(!1),I=g(()=>$.projects.length>$.limit),R=g(()=>{const o=[...$.projects].sort((x,h)=>{const t=C[x.tendency]-C[h.tendency];if(t!==0)return t;const T=x.latestFullRun?new Date(x.latestFullRun.startTime).getTime():0;return(h.latestFullRun?new Date(h.latestFullRun.startTime).getTime():0)-T});return v.value?o:o.slice(0,$.limit)});function U(o){return o>=90?"text-green-600 dark:text-green-400":o>=50?"text-yellow-600 dark:text-yellow-400":"text-red-600 dark:text-red-400"}function N(o){switch(o){case"failing":return"text-red-700 dark:text-red-400 bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800";case"flaky":return"text-amber-700 dark:text-amber-400 bg-amber-50 dark:bg-amber-900/20 border-amber-200 dark:border-amber-800";case"passing":return"text-green-700 dark:text-green-400 bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800";default:return"text-gray-500 dark:text-gray-400 bg-gray-50 dark:bg-gray-800 border-gray-200 dark:border-gray-700"}}function S(o){return o==="unknown"?"Unknown":o.charAt(0).toUpperCase()+o.slice(1)}function _(o){switch(o){case"failing":return"i-lucide-trending-down";case"flaky":return"i-lucide-shuffle";case"passing":return"i-lucide-trending-up";default:return"i-lucide-minus"}}const E=[{accessorKey:"name",header:"Project"},{id:"recentRuns",header:"Last 20 runs"},{accessorKey:"tendency",header:"Tendency"},{id:"passRate",header:"Pass rate"},{id:"latestRun",header:"Latest run"},{id:"tests",header:"Tests"}];return(o,x)=>{const h=Z,t=oe,T=Ve,b=Ae,V=X,P=ie,j=De,W=Ee,K=le;return r(),y(K,{icon:"i-lucide-layout-dashboard",title:"Project health",help:"home.project-health"},{actions:u(()=>[n(I)&&!n(v)?(r(),y(h,{key:0,variant:"ghost",size:"sm","trailing-icon":"i-lucide-chevron-down",onClick:x[0]||(x[0]=s=>v.value=!0)},{default:u(()=>[m(" Show all "+c($.projects.length),1)]),_:1})):n(v)?(r(),y(h,{key:1,variant:"ghost",size:"sm","trailing-icon":"i-lucide-chevron-up",onClick:x[1]||(x[1]=s=>v.value=!1)},{default:u(()=>[...x[2]||(x[2]=[m(" Show less ",-1)])]),_:1})):f("",!0),l(h,{to:"/projects",variant:"outline",size:"sm"},{default:u(()=>[...x[3]||(x[3]=[m("View all",-1)])]),_:1})]),default:u(()=>[e("div",st,[l(j,{data:n(R),columns:E,ui:{base:"min-w-[700px]",td:"py-3",th:"py-3 text-xs uppercase tracking-wide"}},{"name-cell":u(({row:s})=>[l(t,{to:`/projects/${s.original.id}`,class:"font-medium text-primary hover:underline truncate block max-w-[200px]"},{default:u(()=>[m(c(s.original.label||s.original.name),1)]),_:2},1032,["to"]),s.original.tags.length>0?(r(),d("div",nt,[(r(!0),d(A,null,L(s.original.tags,k=>(r(),y(T,{key:k.id,text:k.text,color:k.color},null,8,["text","color"]))),128))])):f("",!0)]),"recentRuns-cell":u(({row:s})=>[e("div",rt,[l(b,{runs:s.original.recentRuns,height:28},null,8,["runs"])])]),"tendency-cell":u(({row:s})=>[e("span",{class:F(["inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-medium border whitespace-nowrap",N(s.original.tendency)])},[l(V,{name:_(s.original.tendency),class:"size-3 shrink-0"},null,8,["name"]),m(" "+c(S(s.original.tendency)),1)],2)]),"passRate-cell":u(({row:s})=>[s.original.latestFullRun?(r(),d("span",{key:0,class:F(["font-semibold tabular-nums text-sm",U(("passRate"in o?o.passRate:n(M))(s.original.latestFullRun))])},c(("passRate"in o?o.passRate:n(M))(s.original.latestFullRun))+"% ",3)):(r(),d("span",at,"—"))]),"latestRun-cell":u(({row:s})=>[s.original.latestFullRun?(r(),y(t,{key:0,to:`/test-runs/${s.original.latestFullRun.id}`,class:"flex items-center gap-2 min-w-[140px] hover:opacity-80 transition-opacity"},{default:u(()=>[l(P,{status:s.original.latestFullRun.status},null,8,["status"]),e("div",ot,[e("div",null,c(("formatRelativeTime"in o?o.formatRelativeTime:n(ne))(s.original.latestFullRun.startTime)),1),s.original.latestFullRun.duration?(r(),d("div",it,c(("formatDuration"in o?o.formatDuration:n(ue))(s.original.latestFullRun.duration)),1)):f("",!0)])]),_:2},1032,["to"])):(r(),d("span",lt,"No full runs"))]),"tests-cell":u(({row:s})=>[s.original.latestFullRun?(r(),d("span",ut,c(s.original.latestFullRun.passedTests)+"/"+c(s.original.latestFullRun.totalTests),1)):(r(),d("span",dt,"—"))]),_:1},8,["data"])]),e("div",ct,[(r(!0),d(A,null,L(n(R),s=>(r(),d("div",{key:s.id,class:"rounded-lg border border-default p-3 space-y-2"},[e("div",mt,[l(t,{to:`/projects/${s.id}`,class:"font-medium text-primary hover:underline truncate"},{default:u(()=>[m(c(s.label||s.name),1)]),_:2},1032,["to"]),e("span",{class:F(["inline-flex shrink-0 items-center gap-1 rounded border px-1.5 py-0.5 text-xs font-medium whitespace-nowrap",N(s.tendency)])},[l(V,{name:_(s.tendency),class:"size-3 shrink-0"},null,8,["name"]),m(" "+c(S(s.tendency)),1)],2)]),s.tags.length>0?(r(),d("div",pt,[(r(!0),d(A,null,L(s.tags,k=>(r(),y(T,{key:k.id,text:k.text,color:k.color},null,8,["text","color"]))),128))])):f("",!0),l(b,{runs:s.recentRuns,height:24},null,8,["runs"]),e("div",gt,[s.latestFullRun?(r(),y(t,{key:0,to:`/test-runs/${s.latestFullRun.id}`,class:"flex items-center gap-1.5 min-w-0 hover:opacity-80"},{default:u(()=>[l(P,{status:s.latestFullRun.status},null,8,["status"]),e("span",ft,c(("formatRelativeTime"in o?o.formatRelativeTime:n(ne))(s.latestFullRun.startTime)),1)]),_:2},1032,["to"])):(r(),d("span",yt,"No full runs")),s.latestFullRun?(r(),d("span",xt,[e("span",{class:F(["font-semibold",U(("passRate"in o?o.passRate:n(M))(s.latestFullRun))])},c(("passRate"in o?o.passRate:n(M))(s.latestFullRun))+"% ",3),m(" · "+c(s.latestFullRun.passedTests)+"/"+c(s.latestFullRun.totalTests),1)])):f("",!0)])]))),128))]),n(R).length===0?(r(),y(W,{key:0,text:"No projects yet",padded:!1,class:"py-8"})):f("",!0)]),_:1})}}}),ht=Object.assign(_t,{__name:"ProjectTrendTable"}),vt={class:"flex items-center gap-3"},bt={class:"p-2 bg-primary/10 rounded-lg shrink-0"},kt={class:"text-xl font-semibold inline-flex items-center gap-1"},Rt={class:"text-sm text-gray-500 dark:text-gray-400"},wt={class:"flex flex-col items-center shrink-0"},$t={key:1},Ct={key:0,class:"w-px flex-1 mt-2 min-h-6 bg-gray-200 dark:bg-gray-700"},Tt={class:"flex-1 pb-6"},Ft={class:"flex items-center gap-2 mb-1"},jt={class:"font-medium"},St={class:"text-sm text-gray-600 dark:text-gray-400 mb-3"},Pt={class:"border-t border-gray-200 dark:border-gray-700 pt-4 mt-2"},zt={key:0,class:"mt-4 space-y-6"},It={class:"text-sm text-gray-600 dark:text-gray-400 mb-3"},Ut={class:"flex items-center justify-between text-sm text-gray-500 dark:text-gray-400"},Nt=`// tests/fixtures.ts
2
- import { test as base, expect } from '@playwright/test'
3
- import { piwiFixtures } from '@piwitests/reporter'
4
-
5
- export const test = base.extend(piwiFixtures)
6
- export { expect }`,Vt=`// your test file
7
- import { test, expect } from './fixtures'
8
-
9
- test('homepage loads', async ({ page }) => {
10
- await page.goto('/')
11
- // network requests, web vitals, console errors, and ARIA snapshots
12
- // are captured automatically and appear in the dashboard
13
- })`,At=`// tests/fixtures.ts
14
- import { test as base } from '@playwright/test'
15
- import { extendPiwiFixtures } from '@piwitests/reporter'
16
-
17
- export const test = extendPiwiFixtures(base)
18
- export { expect } from '@playwright/test'`,Dt=Q({__name:"GetStartedWizard",setup(D){const $=Ce(),C=g(()=>!!$.public.authEnabled),v=Me(),{data:I}=re("/api/desktop/reporter-config",{immediate:v,default:()=>null},"$1biRnknxaz"),R=J("http://localhost:3000");we(()=>{R.value=window.location.origin});const U=g(()=>v&&I.value?`
19
- apiKey: '${I.value.token}',`:C.value?`
20
- apiKey: process.env.PIWI_API_KEY,`:""),N=g(()=>`import { defineConfig } from '@playwright/test'
21
-
22
- export default defineConfig({
23
- reporter: [
24
- ['list'],
25
- ['@piwitests/reporter', {
26
- serverUrl: '${R.value}',
27
- projectName: 'my-project',${U.value}
28
- }],
29
- ],
30
- use: {
31
- trace: 'retain-on-failure',
32
- },
33
- })`),S=g(()=>`import { defineConfig } from '@playwright/test'
34
- import PiwiDashboard from '@piwitests/reporter'
35
-
36
- export default PiwiDashboard.wrapConfig(
37
- defineConfig({
38
- // your existing config
39
- use: {
40
- trace: 'retain-on-failure',
41
- },
42
- }),
43
- {
44
- serverUrl: '${R.value}',
45
- projectName: 'my-project',${U.value}
46
- },
47
- )`),_=g(()=>{const h=[{title:"Start the dashboard",description:"You're already here — the dashboard is running.",done:!0},{title:"Install the reporter",description:"Add the Piwi reporter to your Playwright project.",code:"npm install --save-dev @piwitests/reporter",lang:"bash"}];return C.value&&h.push({title:"Create an API key",description:"Authentication is enabled on this instance, so the reporter needs a key to submit results. Create one, then set it as PIWI_API_KEY in your CI secrets (used by the snippet below).",action:"create-api-key"}),h.push({title:"Configure Playwright",description:v?"Add the reporter to your playwright.config.ts. The apiKey below is this app's local access token.":"Add the reporter to your playwright.config.ts.",code:N.value,lang:"typescript"},{title:"Run your tests",description:"Results appear in the dashboard automatically. The project is created on first submit.",code:"npx playwright test",lang:"bash"}),h.map((t,T)=>({id:T+1,...t}))}),E=["zero","one","two","three","four","five","six"],o=g(()=>E[_.value.length]??String(_.value.length)),x=J(!1);return(h,t)=>{const T=X,b=We,V=$e,P=Z,j=He,W=Be,K=de;return r(),y(K,null,{header:u(()=>[e("div",vt,[e("div",bt,[l(T,{name:"i-lucide-rocket",class:"size-5 text-primary"})]),e("div",null,[e("h2",kt,[t[1]||(t[1]=m(" Get started in 60 seconds ",-1)),l(b,{topic:"home.get-started"})]),e("p",Rt,"Send your first test run in "+c(n(o))+" steps",1)])])]),footer:u(()=>[e("div",Ut,[e("span",null,[t[18]||(t[18]=m("Need more options? See the ",-1)),l(W,{to:"reporter","no-icon":"",class:"text-primary hover:underline"},{default:u(()=>[...t[17]||(t[17]=[m("full reporter docs",-1)])]),_:1}),t[19]||(t[19]=m(".",-1))]),l(P,{to:n(Le)("demo/"),target:"_blank",variant:"ghost",size:"sm",color:"neutral","trailing-icon":"i-lucide-external-link"},{default:u(()=>[...t[20]||(t[20]=[m(" View demo with sample data ",-1)])]),_:1},8,["to"])])]),default:u(()=>[e("div",null,[(r(!0),d(A,null,L(n(_),(s,k)=>(r(),d("div",{key:s.id,class:"flex gap-4"},[e("div",wt,[e("div",{class:F(["flex size-8 items-center justify-center rounded-full text-sm font-semibold",s.done?"bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400":"bg-primary/10 text-primary"])},[s.done?(r(),y(T,{key:0,name:"i-lucide-check",class:"size-4"})):(r(),d("span",$t,c(s.id),1))],2),k<n(_).length-1?(r(),d("div",Ct)):f("",!0)]),e("div",Tt,[e("div",Ft,[e("h3",jt,c(s.title),1),s.done?(r(),y(V,{key:0,color:"success",variant:"subtle",size:"xs"},{default:u(()=>[...t[2]||(t[2]=[m("Done",-1)])]),_:1})):f("",!0)]),e("p",St,c(s.description),1),s.action==="create-api-key"?(r(),y(P,{key:0,to:"/settings/users",icon:"i-lucide-key-round",size:"sm",variant:"soft"},{default:u(()=>[...t[3]||(t[3]=[m(" Create an API key ",-1)])]),_:1})):f("",!0),s.code?(r(),y(j,{key:1,code:s.code,lang:s.lang},null,8,["code","lang"])):f("",!0)])]))),128)),e("div",Pt,[e("button",{class:"flex items-center gap-2 text-sm font-medium text-gray-600 dark:text-gray-300 hover:text-primary dark:hover:text-primary transition-colors w-full text-left",onClick:t[0]||(t[0]=s=>x.value=!n(x))},[l(T,{name:"i-lucide-chevron-right",class:F(["size-4 transition-transform duration-200",n(x)?"rotate-90":""])},null,8,["class"]),t[4]||(t[4]=m(" Go further — simpler config & capture fixtures ",-1))]),n(x)?(r(),d("div",zt,[e("div",null,[t[5]||(t[5]=e("h4",{class:"font-medium text-sm mb-1"},[m(" Simpler config with "),e("code",{class:"text-primary text-xs"},"wrapConfig")],-1)),t[6]||(t[6]=e("p",{class:"text-sm text-gray-600 dark:text-gray-400 mb-3"},[m(" Instead of manually adding the reporter array entry, "),e("code",{class:"text-xs bg-gray-100 dark:bg-gray-800 px-1 py-0.5 rounded"},"wrapConfig"),m(" auto-injects the reporter and chains the global setup in one call. It also registers the run on the dashboard "),e("em",null,"before"),m(" your "),e("code",{class:"text-xs bg-gray-100 dark:bg-gray-800 px-1 py-0.5 rounded"},"globalSetup"),m(" runs, so the dashboard shows an initializing state during setup. ")],-1)),l(j,{code:n(S),lang:"typescript"},null,8,["code"])]),e("div",null,[t[14]||(t[14]=e("h4",{class:"font-medium text-sm mb-1"},[m(" Capture fixtures — network, Web Vitals, console & locator healing with "),e("code",{class:"text-primary text-xs"},"piwiFixtures")],-1)),e("p",It,[t[8]||(t[8]=m(" Extend your Playwright ",-1)),t[9]||(t[9]=e("code",{class:"text-xs bg-gray-100 dark:bg-gray-800 px-1 py-0.5 rounded"},"test",-1)),t[10]||(t[10]=m(" with ",-1)),t[11]||(t[11]=e("code",{class:"text-xs bg-gray-100 dark:bg-gray-800 px-1 py-0.5 rounded"},"piwiFixtures",-1)),t[12]||(t[12]=m(" to automatically capture network timing, browser Web Vitals, console errors, ARIA snapshots on failure, and the locator snapshots that power locator healing. See the ",-1)),l(W,{to:"capture-fixtures","no-icon":"",class:"text-primary hover:underline"},{default:u(()=>[...t[7]||(t[7]=[m("capture fixtures guide",-1)])]),_:1}),t[13]||(t[13]=m(". ",-1))]),t[15]||(t[15]=e("p",{class:"text-xs font-semibold uppercase tracking-wide text-gray-400 dark:text-gray-500 mb-2"}," Option A — extend your existing fixtures ",-1)),l(j,{code:Nt,lang:"typescript",class:"mb-3"}),l(j,{code:Vt,lang:"typescript",class:"mb-4"}),t[16]||(t[16]=e("p",{class:"text-xs font-semibold uppercase tracking-wide text-gray-400 dark:text-gray-500 mb-2"}," Option B — one-line extend ",-1)),l(j,{code:At,lang:"typescript"})])])):f("",!0)])])]),_:1})}}}),Et=Object.assign(Dt,{__name:"GetStartedWizard"}),Ot={key:0,class:"p-6"},Bt={key:1,class:"p-6 space-y-8","aria-busy":"true"},Lt={class:"grid grid-cols-1 xl:grid-cols-3 gap-6 items-start"},Wt={class:"xl:col-span-2 space-y-3"},Ht={class:"space-y-3"},Mt={key:2,class:"p-6 space-y-8"},Kt={key:1,class:"flex flex-wrap items-center gap-x-8 gap-y-3 text-sm border border-gray-200 dark:border-gray-700 rounded-xl px-6 py-4 bg-gray-50 dark:bg-gray-900/50"},Gt={class:"flex items-center gap-1.5"},Yt={class:"font-semibold tabular-nums"},qt={class:"flex items-center gap-1.5"},Jt={class:"flex items-center gap-1.5"},Qt={key:0,class:"flex items-center gap-1.5"},Xt={class:"font-semibold tabular-nums"},Zt={class:"flex items-center gap-1.5"},es={class:"font-semibold tabular-nums"},ts={key:2,class:"grid grid-cols-1 xl:grid-cols-3 gap-6 items-start"},ss={class:"xl:col-span-2"},ns={class:"divide-y divide-gray-100 dark:divide-gray-800 text-sm"},rs={class:"flex-1 min-w-0"},as={class:"font-medium truncate"},os={class:"text-xs text-gray-400"},is={class:"text-right tabular-nums shrink-0"},ls={key:0,class:"text-xs text-gray-400"},us={key:3,class:"text-center py-12 text-gray-500 dark:text-gray-400"},ds={class:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4"},cs={class:"flex flex-col gap-3 h-full"},ms={class:"p-2 bg-primary/10 rounded-lg w-fit"},ps={class:"text-xs font-semibold uppercase tracking-wide text-primary mb-1"},gs={class:"font-semibold mb-1"},fs={class:"text-sm text-gray-600 dark:text-gray-400"},ae=6,Ys=Q({__name:"index",setup(D){Te({title:"Piwi Dashboard"});const{data:$,error:C,refresh:v,status:I}=re("/api/projects/overview",{lazy:!0,default:()=>[]},"$cnA6-rHww6"),{data:R,error:U,refresh:N}=re("/api/test-runs/recent",{lazy:!0},"$LEgADC56ri");Ke(()=>Promise.all([v(),N()]));const S=g(()=>I.value==="pending"&&!$.value?.length),_=g(()=>C.value||U.value);function E(){v(),N()}const o=Ge("piwi-home-filters",{default:()=>({environments:[],fullRunsOnly:!0}),encode:i=>JSON.stringify(i),decode:i=>{try{return i?JSON.parse(i):{environments:[],fullRunsOnly:!0}}catch{return{environments:[],fullRunsOnly:!0}}}}),x=g(()=>{const i=new Set;for(const a of R.value??[])a.environment&&i.add(a.environment);for(const a of $.value??[])for(const w of a.recentRuns)w.environment&&i.add(w.environment);return[...i].sort()});function h(i){return o.value.environments.length===0?!0:!!i&&o.value.environments.includes(i)}const t=g(()=>{let i=R.value??[];return o.value.fullRunsOnly&&(i=i.filter(a=>a.isFullRun)),o.value.environments.length>0&&(i=i.filter(a=>h(a.environment))),i}),T=g(()=>{let i=$.value??[];return o.value.environments.length>0&&(i=i.map(a=>({...a,recentRuns:a.recentRuns.filter(w=>h(w.environment))})).filter(a=>a.recentRuns.length>0)),i}),b=g(()=>{const i=T.value,a=i.length,w=i.filter(z=>z.tendency==="failing").length,H=i.filter(z=>z.tendency==="flaky").length;let O=0,G=0;for(const z of i)z.latestFullRun&&(O+=z.latestFullRun.passedTests,G+=z.latestFullRun.totalTests);const Y=G>0?Math.round(O/G*100):null,te=Date.now()-1440*60*1e3,B=t.value.filter(z=>new Date(z.startTime).getTime()>te).length;return{totalProjects:a,failingNow:w,flakyNow:H,avgPassRate:Y,runs24h:B}}),V=new Set(["running","initialising","finalizing"]),P=J(!1),j=g(()=>[...t.value].sort((a,w)=>{const H=V.has(a.status)?0:1,O=V.has(w.status)?0:1;return H!==O?H-O:new Date(w.startTime).getTime()-new Date(a.startTime).getTime()})),W=g(()=>P.value?j.value:j.value.slice(0,ae)),K=g(()=>j.value.length>ae),s=g(()=>t.value.length>0),k=g(()=>($.value?.length??0)>0),ee=g(()=>o.value.fullRunsOnly?(R.value??[]).filter(w=>h(w.environment)).filter(w=>!w.isFullRun).length:0);function ce(){o.value={...o.value,fullRunsOnly:!1}}function me(i){const a=M(i);return a>=90?"text-green-600 dark:text-green-400":a>=50?"text-yellow-600 dark:text-yellow-400":"text-red-600 dark:text-red-400"}function pe(i){return V.has(i)?"border-l-blue-400":i==="passed"?"border-l-green-500":i==="failed"||i==="timedout"||i==="interrupted"?"border-l-red-500":"border-l-gray-300 dark:border-l-gray-600"}const ge=[{icon:"i-lucide-radio",tagline:"Watch your CI run live",title:"Live streaming",description:"Follow test execution in real time. Investigate failures while the suite is still running — no waiting for the CI job to finish."},{icon:"i-lucide-layers",tagline:"10 failures, 2 root causes",title:"Failure clustering",description:"Tests sharing the same error are grouped automatically. Triage one cluster instead of scrolling through unrelated failures."},{icon:"i-lucide-brain-circuit",tagline:"Diagnosis grounded in your code",title:"AI diagnosis",description:"AI analyzes failure clusters using your actual SCM diff, trace files, and run history — not a generic prompt."},{icon:"i-lucide-archive",tagline:"Every run, forever",title:"Permanent test intelligence",description:"Test results, traces, and HTML reports stored permanently. Compare runs, track flakiness trends, and never lose a CI result again."}];return(i,a)=>{const w=ke,H=Re,O=tt,G=ze,Y=Z,te=Ie,B=Ue,z=Ne,q=X,fe=ht,ye=ie,xe=oe,_e=le,he=Et,ve=de,be=Pe;return r(),y(be,{id:"home"},{header:u(()=>[l(G,null,Fe({leading:u(()=>[l(w),l(H,{items:[{label:"Home",icon:"i-lucide-house",to:"/"}]})]),_:2},[n(k)?{name:"trailing",fn:u(()=>[l(O,{modelValue:n(o),"onUpdate:modelValue":a[0]||(a[0]=p=>se(o)?o.value=p:null),"available-environments":n(x)},null,8,["modelValue","available-environments"])]),key:"0"}:void 0]),1024)]),body:u(()=>[n(_)?(r(),d("div",Ot,[l(te,{text:`Couldn't load the dashboard: ${n(Oe)(n(_))}`},{action:u(()=>[l(Y,{size:"sm",color:"neutral",variant:"outline",icon:"i-lucide-refresh-cw",onClick:E},{default:u(()=>[...a[3]||(a[3]=[m(" Retry ",-1)])]),_:1})]),_:1},8,["text"])])):n(S)?(r(),d("div",Bt,[a[4]||(a[4]=e("span",{class:"sr-only",role:"status"},"Loading dashboard…",-1)),l(B,{class:"h-14 w-full rounded-xl"}),e("div",Lt,[e("div",Wt,[l(B,{class:"h-7 w-40"}),l(B,{class:"h-72 w-full rounded-lg"})]),e("div",Ht,[l(B,{class:"h-7 w-32"}),(r(),d(A,null,L(5,p=>l(B,{key:p,class:"h-12 w-full rounded-lg"})),64))])])])):(r(),d("div",Mt,[n(ee)>0?(r(),y(z,{key:0,icon:"i-lucide-info",color:"primary",variant:"subtle",title:n(ee)===1?"1 partial run is hidden":`${n(ee)} partial runs are hidden`,description:"The “Full runs only” filter hides runs that only cover part of the suite (e.g. a single spec or --grep).",actions:[{label:"Show them",color:"primary",variant:"solid",size:"xs",onClick:ce}]},null,8,["title","actions"])):f("",!0),n(k)?(r(),d("div",Kt,[e("div",Gt,[l(q,{name:"i-lucide-folder",class:"size-4 text-primary shrink-0"}),e("span",Yt,c(n(b).totalProjects),1),a[5]||(a[5]=e("span",{class:"text-gray-500"},"projects",-1))]),e("div",qt,[e("div",{class:F(["w-2 h-2 rounded-full shrink-0",n(b).failingNow>0?"bg-red-500":"bg-green-500"])},null,2),e("span",{class:F(["font-semibold tabular-nums",n(b).failingNow>0?"text-red-600 dark:text-red-400":""])},c(n(b).failingNow),3),a[6]||(a[6]=e("span",{class:"text-gray-500"},"failing now",-1))]),e("div",Jt,[e("div",{class:F(["w-2 h-2 rounded-full shrink-0",n(b).flakyNow>0?"bg-amber-400":"bg-gray-300 dark:bg-gray-600"])},null,2),e("span",{class:F(["font-semibold tabular-nums",n(b).flakyNow>0?"text-amber-600 dark:text-amber-400":""])},c(n(b).flakyNow),3),a[7]||(a[7]=e("span",{class:"text-gray-500"},"flaky",-1))]),n(b).avgPassRate!==null?(r(),d("div",Qt,[l(q,{name:"i-lucide-check-circle",class:"size-4 text-green-500 shrink-0"}),e("span",Xt,c(n(b).avgPassRate)+"%",1),a[8]||(a[8]=e("span",{class:"text-gray-500"},"avg pass rate",-1))])):f("",!0),e("div",Zt,[l(q,{name:"i-lucide-play-circle",class:"size-4 text-primary shrink-0"}),e("span",es,c(n(b).runs24h),1),a[9]||(a[9]=e("span",{class:"text-gray-500"},"runs today",-1))])])):f("",!0),n(k)||n(s)?(r(),d("div",ts,[e("div",ss,[n(k)?(r(),y(fe,{key:0,projects:n(T)},null,8,["projects"])):f("",!0)]),n(s)?(r(),y(_e,{key:0,icon:"i-lucide-activity",title:"Recent activity"},{actions:u(()=>[n(K)&&!n(P)?(r(),y(Y,{key:0,variant:"ghost",size:"sm","trailing-icon":"i-lucide-chevron-down",onClick:a[1]||(a[1]=p=>P.value=!0)},{default:u(()=>[m(" Show all "+c(n(j).length),1)]),_:1})):n(P)?(r(),y(Y,{key:1,variant:"ghost",size:"sm","trailing-icon":"i-lucide-chevron-up",onClick:a[2]||(a[2]=p=>P.value=!1)},{default:u(()=>[...a[10]||(a[10]=[m(" Show less ",-1)])]),_:1})):f("",!0)]),default:u(()=>[e("div",ns,[(r(!0),d(A,null,L(n(W),p=>(r(),y(xe,{key:p.id,to:`/test-runs/${p.id}`,class:F(["flex items-center gap-3 py-3 pl-3 border-l-2 hover:bg-gray-50 dark:hover:bg-gray-800/60 rounded-r transition-colors",pe(p.status)])},{default:u(()=>[l(ye,{status:p.status},null,8,["status"]),e("div",rs,[e("div",as,c(p.projectLabel||p.projectName),1),e("div",os,"Run #"+c(p.id)+" · "+c(("formatRelativeTime"in i?i.formatRelativeTime:n(ne))(p.startTime)),1)]),e("div",is,[e("div",{class:F(me(p))},c(("passRate"in i?i.passRate:n(M))(p))+"%",3),p.duration?(r(),d("div",ls,c(("formatDuration"in i?i.formatDuration:n(ue))(p.duration)),1)):f("",!0)])]),_:2},1032,["to","class"]))),128))])]),_:1})):f("",!0)])):f("",!0),n(k)&&!n(s)&&n(T).length===0?(r(),d("div",us,[l(q,{name:"i-lucide-filter-x",class:"size-8 mx-auto mb-2 opacity-40"}),a[11]||(a[11]=e("p",null,"No runs match the current filters.",-1))])):f("",!0),n(k)?f("",!0):(r(),d(A,{key:4},[l(he),e("div",ds,[(r(),d(A,null,L(ge,p=>l(ve,{key:p.title,class:"flex flex-col"},{default:u(()=>[e("div",cs,[e("div",ms,[l(q,{name:p.icon,class:"size-5 text-primary"},null,8,["name"])]),e("div",null,[e("p",ps,c(p.tagline),1),e("h3",gs,c(p.title),1),e("p",fs,c(p.description),1)])])]),_:2},1024)),64))])],64))]))]),_:1})}}});export{Ys as default};
@@ -1 +0,0 @@
1
- import{d as a,o,c as n,i as l,T as s,O as i,p as m}from"./D3SYPlEB.js";const r=a({__name:"TableScroller",props:{minWidth:{},bleed:{type:Boolean,default:!0}},setup(e){return(t,c)=>(o(),n("div",{class:m(["overflow-x-auto",e.bleed?"-mx-4 px-4 sm:mx-0 sm:px-0":""])},[l("div",{style:i(e.minWidth?{minWidth:e.minWidth}:void 0)},[s(t.$slots,"default")],4)],2))}}),p=Object.assign(r,{__name:"TableScroller"});export{p as _};
@@ -1 +0,0 @@
1
- import{d as W,o as r,f as m,aJ as b,k as e,g as u,T as O,v as x,q as n,h as _,m as P,E as M,l as v,j as D,c as l,t as p,i as E,F as L,y as C,r as k,_ as N}from"./D3SYPlEB.js";import{H as U}from"./r3SBLxtE.js";import{u as H}from"./D3MWm6JP.js";const G="https://piwitests.github.io";function w(t){return`${G}/${t.replace(/^\//,"")}`}const B=W({__name:"DocLink",props:{to:{},noIcon:{type:Boolean}},setup(t){const a=t,h=_(()=>w(a.to));return(s,o)=>{const A=x,I=b;return r(),m(I,{to:e(h),target:"_blank",rel:"noopener noreferrer",class:"inline-flex items-center gap-1 text-primary hover:underline"},{default:u(()=>[O(s.$slots,"default",{},()=>[o[0]||(o[0]=P("Learn more",-1))]),t.noIcon?n("",!0):(r(),m(A,{key:0,name:"i-lucide-external-link",class:"w-3.5 h-3.5 shrink-0"}))]),_:3},8,["to"])}}}),X=Object.assign(B,{__name:"DocLink"}),y={PIWI_SITE_URL:{description:"Public base URL of the instance (e.g. https://piwi.example.com). Used to build links in emails.",category:"general",type:"url",example:"https://piwi.example.com",notes:"When unset, links in emails point to http://localhost:3000 and OAuth callback URLs are inferred from the request host — set it when running behind a reverse proxy."},PIWI_SECRET_KEY:{description:"Master key for AES-256-GCM encryption of secrets stored in the database (AI API keys, webhook/SCM secrets). Strongly recommended in production.",category:"general",secret:!0,example:"a 64-char random hex string",notes:"Falls back to an insecure built-in development key (with a startup warning in production). Generate one with `node -e \"console.log(require('node:crypto').randomBytes(32).toString('hex'))\"`."},PIWI_BUILD_DIR:{description:"Overrides the Nuxt build output directory. Used by the test harness to isolate parallel builds.",category:"build",runtimeOnly:!0,type:"path"},PIWI_BUILD_SHA:{description:"Commit SHA baked into the build for provenance. Shown on Settings → About. Set as a build-time arg.",category:"build",runtimeOnly:!0},PIWI_DESKTOP_TOKEN:{description:"Per-install access token the desktop (Tauri) app injects to gate its local server. Set automatically by the desktop shell — not user-configurable. Absent on the server build.",category:"desktop",secret:!0,runtimeOnly:!0,since:"0.16.0"},PIWI_DATABASE_PATH:{description:"Path to the SQLite database file (used when PIWI_DATABASE_URL is not set).",category:"database",type:"path",default:".data/piwi.db",relevantWhen:{PIWI_DATABASE_URL:""}},PIWI_DATABASE_URL:{description:"PostgreSQL connection string. When set, PostgreSQL is used instead of SQLite and migrations run automatically on startup.",category:"database",secret:!0,example:"postgres://piwi:piwi@db:5432/piwi",docs:"deployment#docker-compose-with-postgresql"},PIWI_RETENTION_DAYS:{description:"Days of test-run history the nightly retention sweep keeps. Unset or 0 disables automatic run pruning (the default — pruning is opt-in).",category:"database",type:"number",min:0,docs:"storage#data-retention"},PIWI_RETENTION_NOTIFICATION_DAYS:{description:"Days to keep sent/failed notification outbox rows before the nightly sweep prunes them (default 30; 0 keeps them forever).",category:"database",type:"number",default:"30",min:0},PIWI_RETENTION_DIAGNOSIS_VERSIONS:{description:"AI-diagnosis history versions kept per diagnosis by the nightly sweep (default 20; 0 disables capping).",category:"database",type:"number",default:"20",min:0},PIWI_STORAGE_TYPE:{description:'Storage backend for test artifacts (HTML reports, traces, attachments): "local" or "s3".',category:"storage",type:"enum",enum:["local","s3"],default:"local",notes:"Only the exact value `s3` selects S3; any other value falls back to local storage."},PIWI_STORAGE_PATH:{description:'Directory for local file storage (when PIWI_STORAGE_TYPE is "local").',category:"storage",type:"path",default:".data/storage",relevantWhen:{PIWI_STORAGE_TYPE:"local"}},PIWI_S3_BUCKET:{description:'S3 bucket name for artifact storage (when PIWI_STORAGE_TYPE is "s3").',category:"storage",relevantWhen:{PIWI_STORAGE_TYPE:"s3"},requiredWhen:{PIWI_STORAGE_TYPE:"s3"},docs:"storage#s3-compatible-storage"},PIWI_S3_REGION:{description:'S3 bucket region (when PIWI_STORAGE_TYPE is "s3").',category:"storage",example:"us-east-1",relevantWhen:{PIWI_STORAGE_TYPE:"s3"},requiredWhen:{PIWI_STORAGE_TYPE:"s3"}},PIWI_S3_ACCESS_KEY_ID:{description:"S3 access key id with write access to the bucket.",category:"storage",secret:!0,relevantWhen:{PIWI_STORAGE_TYPE:"s3"},requiredWhen:{PIWI_STORAGE_TYPE:"s3"}},PIWI_S3_SECRET_ACCESS_KEY:{description:"S3 secret access key.",category:"storage",secret:!0,relevantWhen:{PIWI_STORAGE_TYPE:"s3"},requiredWhen:{PIWI_STORAGE_TYPE:"s3"}},PIWI_S3_ENDPOINT:{description:"Custom endpoint for S3-compatible services (MinIO, R2, Spaces).",category:"storage",type:"url",example:"https://minio.example.com",relevantWhen:{PIWI_STORAGE_TYPE:"s3"}},PIWI_S3_FORCE_PATH_STYLE:{description:"Use path-style addressing (required by some S3-compatible services).",category:"storage",type:"boolean",relevantWhen:{PIWI_STORAGE_TYPE:"s3"},notes:"Defaults to on when a custom endpoint is set, off otherwise; only the exact value `false` turns it off explicitly."},PIWI_AUTH_ENABLED:{description:'Set to "true" to enable role-based access control and API keys. Off by default.',category:"auth",type:"boolean",default:"false"},PIWI_AUTH_SECRET:{description:"Secret used to sign/encrypt session cookies. Required when PIWI_AUTH_ENABLED is true.",category:"auth",secret:!0,relevantWhen:{PIWI_AUTH_ENABLED:"true"},requiredWhen:{PIWI_AUTH_ENABLED:"true"},notes:"The server refuses to start when auth is enabled and this is unset."},PIWI_OAUTH_GOOGLE_CLIENT_ID:{description:"Google OAuth client id (optional single sign-on).",category:"oauth",relevantWhen:{PIWI_AUTH_ENABLED:"true"},requiredWhen:{PIWI_OAUTH_GOOGLE_CLIENT_SECRET:"*"},docs:"authentication#oauth-google-github"},PIWI_OAUTH_GOOGLE_CLIENT_SECRET:{description:"Google OAuth client secret.",category:"oauth",secret:!0,relevantWhen:{PIWI_AUTH_ENABLED:"true"},requiredWhen:{PIWI_OAUTH_GOOGLE_CLIENT_ID:"*"}},PIWI_OAUTH_GITHUB_CLIENT_ID:{description:"GitHub OAuth client id (optional single sign-on).",category:"oauth",relevantWhen:{PIWI_AUTH_ENABLED:"true"},requiredWhen:{PIWI_OAUTH_GITHUB_CLIENT_SECRET:"*"},docs:"authentication#oauth-google-github"},PIWI_OAUTH_GITHUB_CLIENT_SECRET:{description:"GitHub OAuth client secret.",category:"oauth",secret:!0,relevantWhen:{PIWI_AUTH_ENABLED:"true"},requiredWhen:{PIWI_OAUTH_GITHUB_CLIENT_ID:"*"}},PIWI_OAUTH_ALLOWED_DOMAINS:{description:"Comma-separated verified email domains allowed to sign in via OAuth (all providers).",category:"oauth",type:"list",example:"example.com,corp.example.com",relevantWhen:{PIWI_AUTH_ENABLED:"true"},notes:"Only verified emails in these domains are accepted. Empty means no domain restriction."},PIWI_OAUTH_GITHUB_ALLOWED_ORGS:{description:"Comma-separated GitHub org logins a user must belong to (requests read:org scope).",category:"oauth",type:"list",relevantWhen:{PIWI_OAUTH_GITHUB_CLIENT_ID:"*"}},PIWI_AI_PROVIDER:{description:'AI provider for failure diagnosis: "anthropic" or "openai" (OpenAI-compatible).',category:"ai",type:"enum",enum:["anthropic","openai"]},PIWI_AI_API_KEY:{description:"API key for the diagnosis provider. Takes precedence over the DB-stored key.",category:"ai",secret:!0,relevantWhen:{PIWI_AI_PROVIDER:"*"},requiredWhen:{PIWI_AI_PROVIDER:"anthropic"},notes:"Optional for OpenAI-compatible providers that need no key (e.g. a local model)."},PIWI_AI_MODEL:{description:"Diagnosis model name (default: claude-opus-4-8 for Anthropic).",category:"ai",example:"claude-opus-4-8",relevantWhen:{PIWI_AI_PROVIDER:"*"},requiredWhen:{PIWI_AI_PROVIDER:"openai"}},PIWI_AI_BASE_URL:{description:"Base URL for OpenAI-compatible providers (e.g. http://localhost:11434/v1).",category:"ai",type:"url",example:"http://localhost:11434/v1",relevantWhen:{PIWI_AI_PROVIDER:"*"},requiredWhen:{PIWI_AI_PROVIDER:"openai"}},PIWI_AI_AUTO_DIAGNOSE:{description:'Set to "true" to auto-diagnose new failure clusters when a run finishes.',category:"ai",type:"boolean",default:"false",relevantWhen:{PIWI_AI_PROVIDER:"*"}},PIWI_AI_AUTO_DIAGNOSE_MAX:{description:"Max clusters auto-diagnosed per finished run (budget cap; default 3).",category:"ai",type:"number",default:"3",min:1,relevantWhen:{PIWI_AI_AUTO_DIAGNOSE:"true"}},PIWI_AI_RESEARCH_PROVIDER:{description:"Provider for the optional research (pre-analysis) stage. Falls back to PIWI_AI_PROVIDER.",category:"ai",type:"enum",enum:["anthropic","openai"],relevantWhen:{PIWI_AI_RESEARCH_MODEL:"*"}},PIWI_AI_RESEARCH_MODEL:{description:"Cheaper/faster model for the research stage. Empty disables the two-stage pipeline.",category:"ai",relevantWhen:{PIWI_AI_PROVIDER:"*"}},PIWI_AI_RESEARCH_BASE_URL:{description:"Base URL for the research-stage provider. Falls back to PIWI_AI_BASE_URL.",category:"ai",type:"url",relevantWhen:{PIWI_AI_RESEARCH_MODEL:"*"}},PIWI_AI_RESEARCH_API_KEY:{description:"API key for the research-stage provider. Falls back to PIWI_AI_API_KEY.",category:"ai",secret:!0,relevantWhen:{PIWI_AI_RESEARCH_MODEL:"*"}},PIWI_AI_EMBEDDING_PROVIDER:{description:"Provider for embeddings (semantic failure clustering). Falls back to PIWI_AI_PROVIDER.",category:"ai",type:"enum",enum:["openai"],relevantWhen:{PIWI_AI_EMBEDDING_MODEL:"*"},notes:'Must resolve to an OpenAI-compatible provider — Anthropic has no embeddings API — so the fallback only helps when the main provider is "openai".'},PIWI_AI_EMBEDDING_MODEL:{description:"Embedding model name (e.g. text-embedding-3-small).",category:"ai",example:"text-embedding-3-small",relevantWhen:{PIWI_AI_PROVIDER:"*"},notes:"Empty disables semantic clustering (and the embedding fallbacks)."},PIWI_AI_EMBEDDING_BASE_URL:{description:"Base URL for the embedding provider. Falls back to PIWI_AI_BASE_URL.",category:"ai",type:"url",relevantWhen:{PIWI_AI_EMBEDDING_MODEL:"*"}},PIWI_AI_EMBEDDING_API_KEY:{description:"API key for the embedding provider. Falls back to PIWI_AI_API_KEY.",category:"ai",secret:!0,relevantWhen:{PIWI_AI_EMBEDDING_MODEL:"*"}},PIWI_AI_MAX_SAMPLE_ERROR_CHARS:{description:"Max characters of raw error text (per error block).",category:"ai-limits",type:"number",default:"10000",min:200,max:5e4},PIWI_AI_MAX_SCM_PATCH_BUDGET:{description:"Total characters of diff patches across changed files.",category:"ai-limits",type:"number",default:"15000",min:0,max:5e4},PIWI_AI_MAX_AFFECTED_TESTS:{description:"Max affected tests listed in the diagnosis context.",category:"ai-limits",type:"number",default:"30",min:1,max:200},PIWI_AI_MAX_STEPS:{description:"Max recent test steps included.",category:"ai-limits",type:"number",default:"50",min:1,max:200},PIWI_AI_MAX_CONSOLE_ENTRIES:{description:"Max console error/warning entries included.",category:"ai-limits",type:"number",default:"30",min:0,max:200},PIWI_AI_MAX_CONSOLE_ENTRY_CHARS:{description:"Max characters per console entry.",category:"ai-limits",type:"number",default:"1000",min:50,max:5e3},PIWI_AI_MAX_NETWORK_REQUESTS:{description:"Max failed network requests included.",category:"ai-limits",type:"number",default:"25",min:0,max:200},PIWI_AI_MAX_ARIA_SNAPSHOT_CHARS:{description:"Max characters of the page ARIA snapshot.",category:"ai-limits",type:"number",default:"12000",min:0,max:5e4},PIWI_AI_MAX_TEST_SOURCE_CHARS:{description:"Max characters of the test source snippet.",category:"ai-limits",type:"number",default:"8000",min:0,max:5e4},PIWI_AI_MAX_SOURCE_FILES:{description:"Max full source files fetched from SCM to ground patches (0 disables).",category:"ai-limits",type:"number",default:"4",min:0,max:20},PIWI_AI_MAX_SOURCE_FILE_CHARS:{description:"Max characters per fetched full source file.",category:"ai-limits",type:"number",default:"12000",min:0,max:5e4},PIWI_AI_MAX_SERVER_LOG_ENTRIES:{description:"Max backend server log entries (from X-Piwi-Logs header) included.",category:"ai-limits",type:"number",default:"50",min:0,max:200},PIWI_AI_MAX_SERVER_LOG_ENTRY_CHARS:{description:"Max characters per backend server log entry.",category:"ai-limits",type:"number",default:"1000",min:50,max:5e3},PIWI_AI_MAX_SERVER_TRACE_SPANS:{description:"Max backend server spans (from X-Piwi-Trace header) included in AI diagnosis (0 disables).",category:"ai-limits",type:"number",default:"40",min:0,max:500,since:"0.16.0"},PIWI_AI_MAX_IMAGES:{description:"Max screenshots auto-included in the diagnosis context.",category:"ai-limits",type:"number",default:"5",min:0,max:20},PIWI_AI_MAX_PASSED_PEERS:{description:"Max peer tests in the same file listed when they passed.",category:"ai-limits",type:"number",default:"20",min:0,max:100},PIWI_AI_MAX_CONSOLE_WINDOW:{description:"Max console entries of any type in the window before failure.",category:"ai-limits",type:"number",default:"50",min:0,max:200},PIWI_AI_SLOW_REQUEST_MS:{description:"Network request duration (ms) threshold for flagging as slow.",category:"ai-limits",type:"number",default:"1500",min:100,max:3e4},PIWI_AI_MAX_TRACE_ACTIONS:{description:"Max actions extracted from trace ZIP for failing-action context (0 disables).",category:"ai-limits",type:"number",default:"10",min:0,max:50},PIWI_AI_TRACE_DOM_CHARS:{description:"Max characters for the trace-derived DOM/ARIA excerpt in failing-action context.",category:"ai-limits",type:"number",default:"6000",min:0,max:2e4},PIWI_AI_MAX_TRACE_STACK_FRAMES:{description:"Max call-stack frames (with source windows) from the trace call-stack section (0 disables).",category:"ai-limits",type:"number",default:"10",min:0,max:50},PIWI_AI_MAX_TRACE_NETWORK_REQUESTS:{description:"Max requests included from the trace network stream (0 disables).",category:"ai-limits",type:"number",default:"20",min:0,max:200},PIWI_AI_MAX_DOM_SNAPSHOT_CHARS:{description:"Max characters of the failure-time DOM snapshot rendered from the trace (0 disables).",category:"ai-limits",type:"number",default:"8000",min:0,max:5e4},PIWI_AI_IMAGE_MAX_EDGE:{description:"Screenshots are downscaled to at most this many pixels on the long edge before being sent.",category:"ai-limits",type:"number",default:"1920",min:512,max:8192},PIWI_INGEST_MAX_CONSOLE_ENTRIES:{description:"Max console entries stored per test execution.",category:"ingest",type:"number",default:"200",min:10,max:5e3},PIWI_INGEST_MAX_CONSOLE_ENTRY_CHARS:{description:"Max characters stored per console entry.",category:"ingest",type:"number",default:"2000",min:200,max:2e4},PIWI_INGEST_MAX_STEPS:{description:"Max test steps stored per execution.",category:"ingest",type:"number",default:"500",min:20,max:5e3},PIWI_INGEST_MAX_STEP_EVENTS:{description:"Max step events stored per execution.",category:"ingest",type:"number",default:"1000",min:20,max:1e4},PIWI_INGEST_MAX_ARIA_CHARS:{description:"Max characters of the ARIA snapshot stored per failing execution.",category:"ingest",type:"number",default:"100000",min:1e3,max:1e6},PIWI_INGEST_MAX_ERROR_CHARS:{description:"Max characters of error text stored per execution (head and tail are kept).",category:"ingest",type:"number",default:"20000",min:1e3,max:1e5},PIWI_INGEST_MAX_SAMPLE_ERROR_CHARS:{description:"Max characters of the sample error stored per failure cluster.",category:"ingest",type:"number",default:"50000",min:1e3,max:2e5},PIWI_INGEST_MAX_TEST_SOURCE_CHARS:{description:"Max characters of the test source snippet stored per failing execution.",category:"ingest",type:"number",default:"50000",min:1e3,max:2e5},PIWI_INGEST_MAX_SOURCE_FRAMES:{description:"Max source stack frames stored per failing execution.",category:"ingest",type:"number",default:"8",min:1,max:32},PIWI_INGEST_MAX_SOURCE_FRAME_CHARS:{description:"Max characters per stored source frame snippet.",category:"ingest",type:"number",default:"4000",min:500,max:2e4},PIWI_AUTO_MARKERS:{description:"Automatically create a timeline marker when a run’s environment, Playwright version, or reporter version changes from the previous run (default: enabled). Set to false to disable.",category:"markers",type:"boolean",default:"true",docs:"timeline-markers",notes:"Only the exact value `false` disables auto-markers."},PIWI_TEST_LOGS_DISABLED:{description:"Disable X-Piwi-Logs response header emission (default: auto-disabled in production, enabled in development).",category:"testing",type:"boolean",docs:"backend-logs",notes:"Unset: capture is on in development and off in production builds; `true` forces it off everywhere, `false` forces it on even in production."},PIWI_CLUSTER_SIMILARITY_THRESHOLD:{description:"Cosine similarity (0–1) above which two failure embeddings merge into one cluster.",category:"clustering",type:"number",default:"0.92",min:0,max:1,relevantWhen:{PIWI_AI_EMBEDDING_MODEL:"*"},notes:"Must be greater than 0 and at most 1; invalid values fall back to the default."},PIWI_CLUSTER_SUGGEST_THRESHOLD:{description:"Similarity at which a failure is suggested (not auto-merged) as related to a cluster.",category:"clustering",type:"number",default:"0.80",min:0,max:1,relevantWhen:{PIWI_AI_EMBEDDING_MODEL:"*"},notes:"Capped at the merge threshold."},PIWI_SMTP_HOST:{description:"SMTP server hostname for outbound email.",category:"smtp",example:"smtp.example.com"},PIWI_SMTP_PORT:{description:"SMTP port (default 587; 465 for implicit TLS).",category:"smtp",type:"number",default:"587",min:1,max:65535,relevantWhen:{PIWI_SMTP_HOST:"*"}},PIWI_SMTP_USER:{description:"SMTP username.",category:"smtp",relevantWhen:{PIWI_SMTP_HOST:"*"},requiredWhen:{PIWI_SMTP_HOST:"*"}},PIWI_SMTP_PASS:{description:"SMTP password. Never returned by the API.",category:"smtp",secret:!0,relevantWhen:{PIWI_SMTP_HOST:"*"},requiredWhen:{PIWI_SMTP_HOST:"*"}},PIWI_SMTP_FROM:{description:"From address for outbound email (e.g. noreply@example.com).",category:"smtp",example:"noreply@example.com",relevantWhen:{PIWI_SMTP_HOST:"*"},requiredWhen:{PIWI_SMTP_HOST:"*"}},PIWI_SMTP_FROM_NAME:{description:"Display name for the from address (optional).",category:"smtp",default:"Piwi Dashboard",relevantWhen:{PIWI_SMTP_HOST:"*"}},PIWI_SMTP_SECURE:{description:'Set to "true" for implicit TLS on port 465 (default false → STARTTLS/plain).',category:"smtp",type:"boolean",relevantWhen:{PIWI_SMTP_HOST:"*"},notes:"Defaults to on when the port is 465, off otherwise."},PIWI_WASTED_WAIT_PATTERNS:{description:"Glob patterns (comma or newline separated) defining which wait steps count as wasted time. Locks the UI when set.",category:"wasted-time",type:"list",default:"Wait for timeout*,*waitForTimeout*",notes:"Case-insensitive globs (`*` and `?`) matched against a wait step’s title or source location. Use `*` to count every wait."},PIWI_DEMO_MODE:{description:'Set to "true" to build the standalone client-side demo SPA (no server).',category:"demo",runtimeOnly:!0,type:"boolean"},PIWI_BASE_URL:{description:"Base URL the metadata test spec targets (defaults to http://localhost:3000).",category:"test",runtimeOnly:!0},PIWI_POSTGRES_TEST_URL:{description:"PostgreSQL connection string used by the Postgres test suite.",category:"test",runtimeOnly:!0,secret:!0},PIWI_S3_TEST_BUCKET:{description:"S3 bucket for the storage integration tests.",category:"test",runtimeOnly:!0},PIWI_S3_TEST_REGION:{description:"Region for the S3 storage integration tests.",category:"test",runtimeOnly:!0},PIWI_S3_TEST_ACCESS_KEY_ID:{description:"Access key id for the S3 storage integration tests.",category:"test",runtimeOnly:!0,secret:!0},PIWI_S3_TEST_SECRET_ACCESS_KEY:{description:"Secret access key for the S3 storage integration tests.",category:"test",runtimeOnly:!0,secret:!0},PIWI_S3_TEST_ENDPOINT:{description:"Custom endpoint for the S3 storage integration tests.",category:"test",runtimeOnly:!0},PIWI_MAILPIT_URL:{description:"Mailpit base URL; when set, the email/notification E2E tests run against it.",category:"test",runtimeOnly:!0},PIWI_MAILPIT_SMTP_PORT:{description:"SMTP port the email E2E tests send to (Mailpit).",category:"test",runtimeOnly:!0},PIWI_EMAIL_SERVER_URL:{description:"Base URL the email test spec targets.",category:"test",runtimeOnly:!0}};function f(t){return y[t]}function ie(t){return Object.keys(y).filter(a=>y[a].category===t)}const V={key:0,class:"font-medium mb-1"},Y={class:"text-muted"},q={key:1,class:"mt-2 space-y-1"},F={class:"text-muted text-xs"},K={class:"flex flex-col gap-1.5"},$=["title","onClick"],Q={class:"block font-mono text-xs bg-elevated rounded px-1.5 py-0.5 select-all cursor-pointer group-hover:ring-1 ring-default"},j={key:0,class:"block text-muted text-[11px] mt-0.5"},z={key:2,class:"mt-2 flex flex-col gap-1"},J=W({__name:"HelpHint",props:{topic:{},title:{},text:{},doc:{},envVars:{},size:{}},setup(t){const a=t,{copy:h}=H(),s=_(()=>a.topic?U[a.topic]:null),o=_(()=>a.title??s.value?.title),A=_(()=>a.text??s.value?.text??""),I=_(()=>a.doc??s.value?.doc),d=_(()=>a.envVars??s.value?.envVars),g=k(!1);return(Z,c)=>{const T=N,S=X,R=M;return r(),m(R,{open:e(g),"onUpdate:open":c[0]||(c[0]=i=>v(g)?g.value=i:null),ui:{content:"max-w-xs p-3 text-sm"}},{content:u(()=>[e(o)?(r(),l("p",V,p(e(o)),1)):n("",!0),E("p",Y,p(e(A)),1),e(d)?.length?(r(),l("div",q,[E("p",F,"Environment variable"+p(e(d).length>1?"s":"")+":",1),E("div",K,[(r(!0),l(L,null,C(e(d),i=>(r(),l("button",{key:i,type:"button",class:"group text-left",title:`Click to copy ${i}`,onClick:ee=>e(h)(i,{toast:`Copied ${i}`})},[E("code",Q,p(i),1),e(f)(i).description?(r(),l("span",j,p(e(f)(i).description),1)):n("",!0)],8,$))),128))])])):n("",!0),e(I)||e(d)?.length?(r(),l("div",z,[e(I)?(r(),m(S,{key:0,to:e(I)},{default:u(()=>[...c[1]||(c[1]=[P("Learn more",-1)])]),_:1},8,["to"])):n("",!0),e(d)?.length?(r(),m(S,{key:1,to:"configuration"},{default:u(()=>[...c[2]||(c[2]=[P("Configuration reference",-1)])]),_:1})):n("",!0)])):n("",!0)]),default:u(()=>[D(T,{size:t.size??"xs",variant:"ghost",color:"neutral",icon:"i-lucide-circle-help","aria-label":e(o)?`Help: ${e(o)}`:"Help",title:"What is this?",class:"text-muted hover:text-default align-middle"},null,8,["size","aria-label"])]),_:1},8,["open"])}}}),oe=Object.assign(J,{__name:"HelpHint"});export{oe as _,X as a,w as d,ie as e,f as g};
@@ -1 +0,0 @@
1
- import{_}from"./CCw3Tx4S.js";import{d as f,o as a,f as b,g as r,c as o,F as d,y as u,k as p,O as h,p as m,i as l,t as n,h as x}from"./D3SYPlEB.js";const g={key:0,class:"flex h-2.5 w-full min-w-30 overflow-hidden rounded-full bg-gray-200 dark:bg-gray-700"},w={key:1,class:"text-xs text-gray-400 dark:text-gray-500 italic"},v={class:"min-w-52 space-y-1.5 rounded-md bg-gray-900 px-3 py-2 text-sm shadow-lg"},B={class:"font-semibold text-white"},C={class:"text-white"},F={class:"ml-4 tabular-nums font-medium text-white"},N={class:"ml-auto tabular-nums text-gray-300 text-xs"},P=f({__name:"TestStatusBar",props:{passed:{},failed:{},skipped:{},flaky:{},total:{},didNotRun:{}},setup(i){const t=i,c=x(()=>t.total?[{key:"passed",label:"Passed",count:t.passed-t.flaky,color:"bg-green-500"},{key:"failed",label:"Failed",count:t.failed,color:"bg-red-500"},{key:"flaky",label:"Flaky",count:t.flaky,color:"bg-purple-500"},{key:"skipped",label:"Skipped",count:t.skipped,color:"bg-gray-400"},{key:"didNotRun",label:"Didn't run",count:t.didNotRun??0,color:"bg-amber-300 dark:bg-amber-700"}].filter(s=>s.count>0).map(s=>({...s,widthPct:s.count/t.total*100,displayPct:(s.count/t.total*100).toFixed(1)})):[]);return(y,s)=>{const k=_;return a(),b(k,{ui:{content:"overflow-visible !p-0"}},{content:r(()=>[l("div",v,[l("div",B,n(i.total)+" tests total",1),(a(!0),o(d,null,u(p(c),e=>(a(),o("div",{key:e.key,class:"flex items-center gap-2 whitespace-nowrap"},[l("span",{class:m([e.color,"inline-block h-2.5 w-2.5 shrink-0 rounded-sm"])},null,2),l("span",C,n(e.label),1),l("span",F,n(e.count),1),l("span",N,n(e.displayPct)+"%",1)]))),128))])]),default:r(()=>[i.total>0?(a(),o("div",g,[(a(!0),o(d,null,u(p(c),e=>(a(),o("div",{key:e.key,class:m([e.color,"h-full transition-all"]),style:h({width:e.widthPct+"%"})},null,6))),128))])):(a(),o("div",w,"No tests"))]),_:1})}}}),T=Object.assign(P,{__name:"TestStatusBar"});export{T as _};
@@ -1 +0,0 @@
1
- import{_ as Re,a as Ee}from"./BiX7c2qU.js";import{d as H,z as le,B as se,o as n,f as P,g as u,i as s,j as c,D as G,l as W,k as o,c as p,v as ne,F as U,y as F,p as ie,m as A,t as S,q as _,A as X,r as E,h as N,G as $e,_ as re,w as ae,b as Oe,aa as Le,I as z}from"./D3SYPlEB.js";import{_ as Be}from"./C8cz5feG.js";import{_ as pe}from"./n-QWmQgc.js";import{_ as fe}from"./CCsl9MOZ.js";import{_ as ve}from"./Db_-yjYg.js";import{_ as ge}from"./AjuKBlzz.js";import{_ as Fe}from"./l0QnzFNM.js";import{h as We}from"./r3SBLxtE.js";import{_ as ye}from"./empGC_x-.js";import{h as De}from"./BUMZHDRC.js";import{u as oe}from"./Doul3p1_.js";import{_ as Ne}from"./DnThe2U0.js";import{p as Xe,g as qe}from"./CPZ5wygb.js";import"./B6IHiVa1.js";import"./D3MWm6JP.js";import"./BAkJhSAW.js";import"./Cx65B3c3.js";import"./wgcgHmRR.js";import"./rm7OkgDG.js";import"./CCw3Tx4S.js";import"./DoFSKAvY.js";const je={class:"space-y-3"},Ke={key:0,class:"flex items-center justify-center gap-2 py-8 text-gray-400"},ze={key:1,class:"py-8 text-center text-sm text-gray-400"},He={key:2,class:"max-h-96 overflow-y-auto space-y-px"},Ge=["onClick"],Qe={class:"flex-1 min-w-0"},Ye={class:"text-sm font-medium leading-snug truncate"},Ze={key:0,class:"text-gray-500 font-normal"},Je={class:"text-xs text-gray-400 leading-snug mt-0.5"},et={key:3,class:"italic text-gray-500"},tt={key:0,class:"flex items-center gap-1 shrink-0 pt-0.5"},st=["title"],at=["title"],ot={key:0,class:"py-8 text-center text-sm text-gray-400"},lt=H({__name:"ModelPickerModal",props:X({models:{},selected:{},loading:{type:Boolean}},{open:{type:Boolean,required:!0},openModifiers:{}}),emits:X(["select"],["update:open"]),setup(a,{emit:I}){function T(y){return y?y>=1e6?`${(y/1e6).toFixed(1)}M`:y>=1e3?`${Math.round(y/1e3)}K`:String(y):""}const g=a,r=I,k=le(a,"open"),b=E(null),d=E("");se(k,y=>{y&&$e(()=>b.value?.focus())});const l=N(()=>{const y=d.value.toLowerCase();return y?g.models.filter(i=>i.id.toLowerCase().includes(y)||(i.label?.toLowerCase()??"").includes(y)):g.models}),x={image:{icon:"i-lucide-image",label:"Image input"},pdf:{icon:"i-lucide-file-text",label:"PDF input"},code:{icon:"i-lucide-code",label:"Code execution"},thinking:{icon:"i-lucide-brain",label:"Extended thinking"},json:{icon:"i-lucide-braces",label:"Structured output"},text:{icon:"i-lucide-type",label:"Text"},audio:{icon:"i-lucide-music",label:"Audio"}};function V(y){return y.map(i=>{const C=i.indexOf("→");if(C!==-1){const R=i.slice(0,C),O=i.slice(C+1);return{inputs:R.split("+").filter(Boolean),outputs:O.split("+").filter(Boolean)}}return{inputs:[i],outputs:[]}})}function $(y){r("select",y),k.value=!1,d.value=""}return(y,i)=>{const C=G,R=ne,O=Fe;return n(),P(O,{open:k.value,"onUpdate:open":i[1]||(i[1]=v=>k.value=v),title:"Select a model",ui:{content:"max-w-2xl"}},{body:u(()=>[s("div",je,[c(C,{ref_key:"searchInput",ref:b,modelValue:o(d),"onUpdate:modelValue":i[0]||(i[0]=v=>W(d)?d.value=v:null),placeholder:"Search models…",icon:"i-lucide-search",size:"sm"},null,8,["modelValue"]),a.models.length===0&&a.loading?(n(),p("div",Ke,[c(R,{name:"i-lucide-loader-2",class:"size-4 animate-spin"}),i[2]||(i[2]=s("span",{class:"text-sm"},"Loading models…",-1))])):a.models.length===0?(n(),p("div",ze," No models available — check your provider configuration ")):(n(),p("div",He,[(n(!0),p(U,null,F(o(l),v=>(n(),p("button",{key:v.id,class:ie(["w-full text-left px-4 py-3 rounded-lg hover:bg-elevated transition-colors border border-transparent hover:border-default flex items-start gap-4",a.selected===v.id?"bg-primary/10 ring-1 ring-inset ring-primary/30 border-primary/30":""]),onClick:h=>$(v.id)},[s("div",Qe,[s("p",Ye,[A(S(v.id)+" ",1),v.label&&v.label!==v.id?(n(),p("span",Ze," — "+S(v.label),1)):_("",!0)]),s("p",Je,[v.contextLength?(n(),p(U,{key:0},[A(S(T(v.contextLength))+" ctx",1)],64)):_("",!0),v.maxTokens?(n(),p(U,{key:1},[A(" · up to "+S(T(v.maxTokens))+" out",1)],64)):_("",!0),v.pricing?.prompt?(n(),p(U,{key:2},[A(" · $"+S(v.pricing.prompt)+" / $"+S(v.pricing.completion??"?")+" per 1M",1)],64)):_("",!0),!v.contextLength&&!v.maxTokens&&!v.pricing?.prompt?(n(),p("span",et,"No additional info")):_("",!0)])]),v.modalities?.length?(n(),p("div",tt,[(n(!0),p(U,null,F(V(v.modalities),h=>(n(),p(U,{key:h.inputs.join()+"→"+h.outputs.join()},[(n(!0),p(U,null,F(h.inputs,w=>(n(),p("span",{key:"in-"+w,title:x[w]?.label??w,class:"inline-flex items-center justify-center size-6 rounded-md bg-gray-100 dark:bg-gray-800 text-gray-500 hover:text-primary transition-colors"},[c(R,{name:x[w]?.icon??"i-lucide-cpu",class:"size-3.5"},null,8,["name"])],8,st))),128)),h.outputs.length?(n(),P(R,{key:0,name:"i-lucide-arrow-right",class:"size-3 text-gray-400 shrink-0"})):_("",!0),(n(!0),p(U,null,F(h.outputs,w=>(n(),p("span",{key:"out-"+w,title:x[w]?.label??w,class:"inline-flex items-center justify-center size-6 rounded-md bg-gray-100 dark:bg-gray-800 text-gray-500 hover:text-primary transition-colors"},[c(R,{name:x[w]?.icon??"i-lucide-cpu",class:"size-3.5"},null,8,["name"])],8,at))),128))],64))),128))])):_("",!0)],10,Ge))),128)),o(l).length===0?(n(),p("div",ot,' No models match "'+S(o(d))+'" ',1)):_("",!0)]))])]),_:1},8,["open"])}}}),nt=Object.assign(lt,{__name:"ModelPickerModal"}),it={class:"flex gap-2"},rt=H({__name:"ModelFieldInput",props:X({provider:{},providerResolved:{},reuse:{type:Boolean},models:{},loadingModels:{type:Boolean},placeholderAnthropic:{},placeholderOpenai:{}},{modelValue:{required:!0},modelModifiers:{}}),emits:X(["loadModels"],["update:modelValue"]),setup(a,{emit:I}){const T=I,g=le(a,"modelValue"),r=E(!1);return(k,b)=>{const d=G,l=re,x=nt;return n(),p(U,null,[s("div",it,[c(d,{modelValue:g.value,"onUpdate:modelValue":b[0]||(b[0]=V=>g.value=V),placeholder:a.providerResolved==="anthropic"?a.placeholderAnthropic:a.placeholderOpenai,class:"flex-1"},null,8,["modelValue","placeholder"]),a.providerResolved?(n(),P(l,{key:0,size:"sm",variant:"soft",onClick:b[1]||(b[1]=V=>{T("loadModels"),r.value=!0})},{default:u(()=>[...b[4]||(b[4]=[A(" Choose model… ",-1)])]),_:1})):_("",!0)]),c(x,{open:o(r),"onUpdate:open":b[2]||(b[2]=V=>W(r)?r.value=V:null),models:a.models,selected:g.value,loading:a.loadingModels,onSelect:b[3]||(b[3]=V=>g.value=V)},null,8,["open","models","selected","loading"])],64)}}}),dt=Object.assign(rt,{__name:"ModelFieldInput"}),ct={class:"flex items-start justify-between gap-3"},ut={class:"flex items-start gap-2"},mt={class:"font-medium inline-flex items-center gap-1"},pt={class:"text-sm text-gray-500"},ft={class:"inline-flex items-center gap-1"},vt={class:"inline-flex items-center gap-1"},gt={class:"inline-flex items-center gap-1"},yt={key:3,class:"flex justify-end"},ht=H({__name:"AiRoleConfigForm",props:X({meta:{},hasApiKey:{type:Boolean},reuseOptions:{},providerOptions:{},presetOptions:{},disabled:{type:Boolean},envManaged:{type:Boolean},models:{},loadingModels:{type:Boolean},providerResolved:{},testing:{type:Boolean}},{modelValue:{required:!0},modelModifiers:{}}),emits:X(["applyPreset","loadModels","test"],["update:modelValue"]),setup(a,{emit:I}){const T=a,g=I,r=le(a,"modelValue"),k=N({get:()=>r.value.reuse??"own",set:d=>r.value.reuse=d==="own"?null:d}),b=N(()=>We(T.meta.help));return(d,l)=>{const x=ne,V=Be,$=pe,y=fe,i=ve,C=ge,R=G,O=dt,v=re;return n(),p("div",{class:ie(["rounded-lg border border-default p-4 space-y-4",a.meta.optional&&!r.value.enabled?"opacity-80":""])},[s("div",ct,[s("div",ut,[c(x,{name:a.meta.icon,class:"size-5 mt-0.5 text-primary"},null,8,["name"]),s("div",null,[s("p",mt,[A(S(a.meta.title)+" ",1),c(V,{topic:a.meta.help},null,8,["topic"])]),s("p",pt,S(a.meta.blurb),1)])]),a.meta.optional?(n(),P($,{key:0,modelValue:r.value.enabled,"onUpdate:modelValue":l[0]||(l[0]=h=>r.value.enabled=h),disabled:a.disabled&&!a.envManaged,"aria-label":a.meta.enableLabel},null,8,["modelValue","disabled","aria-label"])):_("",!0)]),!a.meta.optional||r.value.enabled?(n(),p(U,{key:0},[a.meta.reuseTargets.length?(n(),P(i,{key:0,label:"Provider source"},{default:u(()=>[c(y,{modelValue:o(k),"onUpdate:modelValue":l[1]||(l[1]=h=>W(k)?k.value=h:null),items:a.reuseOptions,disabled:a.disabled&&!a.envManaged,class:"w-full"},null,8,["modelValue","items","disabled"])]),_:1})):_("",!0),r.value.reuse?_("",!0):(n(),p(U,{key:1},[c(i,{label:"Provider"},{label:u(()=>[s("span",ft,[l[9]||(l[9]=A(" Provider ",-1)),a.disabled?(n(),P(C,{key:0,"env-vars":o(b)},null,8,["env-vars"])):_("",!0)])]),default:u(()=>[c(y,{modelValue:r.value.provider,"onUpdate:modelValue":l[2]||(l[2]=h=>r.value.provider=h),items:a.providerOptions,disabled:a.disabled,placeholder:"Choose a provider…",class:"w-full"},null,8,["modelValue","items","disabled"])]),_:1}),r.value.provider==="openai"?(n(),P(i,{key:0,label:"Preset",description:"Pick a known provider to auto-fill the URL and model, then adjust as needed"},{default:u(()=>[c(y,{items:a.presetOptions,placeholder:"Choose a preset…",disabled:a.disabled,class:"w-full","onUpdate:modelValue":l[3]||(l[3]=h=>g("applyPreset",h))},null,8,["items","disabled"])]),_:1})):_("",!0),r.value.provider?(n(),P(i,{key:1,label:"API key",description:a.hasApiKey?"Leave empty to keep the stored key, clear and save to remove it":"Required for Anthropic; optional for local OpenAI-compatible servers"},{label:u(()=>[s("span",vt,[l[10]||(l[10]=A(" API key ",-1)),a.disabled?(n(),P(C,{key:0,"env-vars":o(b)},null,8,["env-vars"])):_("",!0)])]),default:u(()=>[c(R,{modelValue:r.value.apiKey,"onUpdate:modelValue":l[4]||(l[4]=h=>r.value.apiKey=h),type:"password",placeholder:a.hasApiKey?"•••••••• (unchanged)":"sk-…",disabled:a.disabled,class:"w-full font-mono"},null,8,["modelValue","placeholder","disabled"])]),_:1},8,["description"])):_("",!0),r.value.provider==="openai"?(n(),P(i,{key:2,label:"Base URL",description:"Required, e.g. http://localhost:11434/v1"},{label:u(()=>[s("span",gt,[l[11]||(l[11]=A(" Base URL ",-1)),a.disabled?(n(),P(C,{key:0,"env-vars":o(b)},null,8,["env-vars"])):_("",!0)])]),default:u(()=>[c(R,{modelValue:r.value.baseUrl,"onUpdate:modelValue":l[5]||(l[5]=h=>r.value.baseUrl=h),placeholder:"http://localhost:11434/v1",disabled:a.disabled,class:"w-full"},null,8,["modelValue","disabled"])]),_:1})):_("",!0)],64)),r.value.reuse||r.value.provider?(n(),P(i,{key:2,label:"Model",description:r.value.reuse?"Leave empty to use the reused role's model":void 0},{default:u(()=>[c(O,{modelValue:r.value.model,"onUpdate:modelValue":l[6]||(l[6]=h=>r.value.model=h),provider:r.value.provider,"provider-resolved":a.providerResolved,reuse:!!r.value.reuse,models:a.models,"loading-models":a.loadingModels,"placeholder-anthropic":a.meta.modelPlaceholderAnthropic,"placeholder-openai":a.meta.modelPlaceholderOpenai,onLoadModels:l[7]||(l[7]=h=>g("loadModels"))},null,8,["modelValue","provider","provider-resolved","reuse","models","loading-models","placeholder-anthropic","placeholder-openai"])]),_:1},8,["description"])):_("",!0),a.providerResolved?(n(),p("div",yt,[c(v,{size:"xs",color:"neutral",variant:"soft",icon:"i-lucide-plug",loading:a.testing,onClick:l[8]||(l[8]=h=>g("test"))},{default:u(()=>[...l[12]||(l[12]=[A(" Test connection ",-1)])]),_:1},8,["loading"])])):_("",!0)],64)):_("",!0)],2)}}}),bt=Object.assign(ht,{__name:"AiRoleConfigForm"}),_t={key:0,class:"space-y-3"},xt={class:"text-sm text-gray-500"},kt={key:0,class:"text-sm text-gray-500"},At={key:1,class:"overflow-x-auto"},It={class:"w-full text-sm"},Mt={class:"px-2 py-2"},St={class:"font-mono text-xs"},Vt={class:"text-xs text-gray-400"},wt={class:"text-right px-2 py-2"},Pt=["title"],Tt=["title"],Ut={class:"text-right px-2 py-2"},Ct={key:1,class:"flex items-center gap-2 py-4 text-muted"},Rt=H({__name:"AiUsagePanel",async setup(a){let I,T;const g=E(30),r=[{label:"Last 7 days",value:7},{label:"Last 30 days",value:30},{label:"Last 90 days",value:90}],{data:k,pending:b}=([I,T]=ae(()=>oe("/api/settings/ai/usage",{query:{days:g}},"$1ij5UlwVIK")),I=await I,T(),I);function d(l){return l>=1e6?`${(l/1e6).toFixed(1)}M`:l>=1e3?`${(l/1e3).toFixed(1)}k`:String(l)}return(l,x)=>{const V=fe,$=ne,y=ye;return n(),P(y,{icon:"i-lucide-activity",title:"AI usage"},{actions:u(()=>[c(V,{modelValue:o(g),"onUpdate:modelValue":x[0]||(x[0]=i=>W(g)?g.value=i:null),items:r,size:"sm",class:"w-36"},null,8,["modelValue"])]),default:u(()=>[o(k)?(n(),p("div",_t,[s("p",xt,S(d(o(k).totals.diagnoses))+" diagnoses · "+S(d(o(k).totals.inputTokens))+" input tokens · "+S(d(o(k).totals.outputTokens))+" output tokens ",1),o(k).byModel.length===0?(n(),p("p",kt,"No AI calls recorded in this period.")):(n(),p("div",At,[s("table",It,[x[1]||(x[1]=s("thead",null,[s("tr",{class:"text-xs text-gray-500 uppercase tracking-wider border-b border-default"},[s("th",{class:"text-left px-2 py-2 font-medium"},"Model"),s("th",{class:"text-right px-2 py-2 font-medium"},"Diagnoses"),s("th",{class:"text-right px-2 py-2 font-medium"},"Failed"),s("th",{class:"text-right px-2 py-2 font-medium"},"Input tokens"),s("th",{class:"text-right px-2 py-2 font-medium"},"Output tokens"),s("th",{class:"text-right px-2 py-2 font-medium"},"Avg duration")])],-1)),s("tbody",null,[(n(!0),p(U,null,F(o(k).byModel,i=>(n(),p("tr",{key:`${i.provider??"unknown"}/${i.model}`,class:"border-b last:border-b-0 border-default"},[s("td",Mt,[s("span",St,S(i.model),1),s("span",Vt," · "+S(i.provider??"unknown"),1)]),s("td",wt,S(i.diagnoses),1),s("td",{class:ie(["text-right px-2 py-2",i.failed>0?"text-red-600 dark:text-red-400":""])},S(i.failed),3),s("td",{class:"text-right px-2 py-2",title:i.inputTokens.toLocaleString()},S(d(i.inputTokens)),9,Pt),s("td",{class:"text-right px-2 py-2",title:i.outputTokens.toLocaleString()},S(d(i.outputTokens)),9,Tt),s("td",Ut,S(i.avgDurationMs===null?"—":("formatDuration"in l?l.formatDuration:o(De))(i.avgDurationMs)),1)]))),128))])])]))])):o(b)?(n(),p("div",Ct,[c($,{name:"i-lucide-loader-circle",class:"size-4 animate-spin"}),x[2]||(x[2]=s("span",{class:"text-sm"},"Loading usage…",-1))])):_("",!0)]),_:1})}}}),Et=Object.assign(Rt,{__name:"AiUsagePanel"}),$t=[{key:"sampleErrorChars",label:"Error text characters",envVar:"PIWI_AI_MAX_SAMPLE_ERROR_CHARS",description:"Max characters of raw error text (per error block).",min:200,max:5e4},{key:"scmPatchBudget",label:"SCM patch budget",envVar:"PIWI_AI_MAX_SCM_PATCH_BUDGET",description:"Total characters of diff patches across changed files.",min:0,max:5e4},{key:"affectedTests",label:"Affected tests",envVar:"PIWI_AI_MAX_AFFECTED_TESTS",description:"Max affected tests listed.",min:1,max:200},{key:"steps",label:"Test steps",envVar:"PIWI_AI_MAX_STEPS",description:"Max recent test steps included.",min:1,max:200},{key:"consoleEntries",label:"Console entries",envVar:"PIWI_AI_MAX_CONSOLE_ENTRIES",description:"Max console error/warning entries included.",min:0,max:200},{key:"consoleEntryChars",label:"Console entry characters",envVar:"PIWI_AI_MAX_CONSOLE_ENTRY_CHARS",description:"Max characters per console entry.",min:50,max:5e3},{key:"networkRequests",label:"Network requests",envVar:"PIWI_AI_MAX_NETWORK_REQUESTS",description:"Max failed network requests included.",min:0,max:200},{key:"ariaSnapshotChars",label:"ARIA snapshot characters",envVar:"PIWI_AI_MAX_ARIA_SNAPSHOT_CHARS",description:"Max characters of the page ARIA snapshot.",min:0,max:5e4},{key:"testSourceChars",label:"Test source characters",envVar:"PIWI_AI_MAX_TEST_SOURCE_CHARS",description:"Max characters of the test source snippet.",min:0,max:5e4},{key:"maxSourceFiles",label:"Full source files",envVar:"PIWI_AI_MAX_SOURCE_FILES",description:"Max full source files fetched from SCM to ground patches (0 disables).",min:0,max:20},{key:"sourceFileChars",label:"Source file characters",envVar:"PIWI_AI_MAX_SOURCE_FILE_CHARS",description:"Max characters per fetched full source file.",min:0,max:5e4},{key:"serverLogEntries",label:"Server log entries",envVar:"PIWI_AI_MAX_SERVER_LOG_ENTRIES",description:"Max backend server log entries (from X-Piwi-Logs header) included.",min:0,max:200},{key:"serverLogEntryChars",label:"Server log entry characters",envVar:"PIWI_AI_MAX_SERVER_LOG_ENTRY_CHARS",description:"Max characters per backend server log entry.",min:50,max:5e3},{key:"serverTraceSpans",label:"Server trace spans",envVar:"PIWI_AI_MAX_SERVER_TRACE_SPANS",description:"Max backend server spans (from X-Piwi-Trace header) included (0 disables).",min:0,max:500},{key:"maxImages",label:"Max screenshots",envVar:"PIWI_AI_MAX_IMAGES",description:"Max screenshots auto-included in the diagnosis context.",min:0,max:20},{key:"maxPassedPeers",label:"Max passed peers",envVar:"PIWI_AI_MAX_PASSED_PEERS",description:"Max peer tests in the same file listed when they passed.",min:0,max:100},{key:"maxConsoleWindow",label:"Console window entries",envVar:"PIWI_AI_MAX_CONSOLE_WINDOW",description:"Max console entries of any type in the window before failure.",min:0,max:200},{key:"slowRequestMs",label:"Slow request threshold (ms)",envVar:"PIWI_AI_SLOW_REQUEST_MS",description:"Network request duration threshold for flagging as slow.",min:100,max:3e4},{key:"maxTraceActions",label:"Trace actions",envVar:"PIWI_AI_MAX_TRACE_ACTIONS",description:"Max actions extracted from trace ZIP for failing-action context (0 disables).",min:0,max:50},{key:"traceDomChars",label:"Trace DOM excerpt characters",envVar:"PIWI_AI_TRACE_DOM_CHARS",description:"Max characters for the trace-derived DOM/ARIA excerpt in failing-action context.",min:0,max:2e4},{key:"traceStackFrames",label:"Trace stack frames",envVar:"PIWI_AI_MAX_TRACE_STACK_FRAMES",description:"Max call-stack frames (with source windows) from the trace (0 disables).",min:0,max:50},{key:"traceNetworkRequests",label:"Trace network requests",envVar:"PIWI_AI_MAX_TRACE_NETWORK_REQUESTS",description:"Max requests from the trace network stream (0 disables).",min:0,max:200},{key:"domSnapshotChars",label:"DOM snapshot characters",envVar:"PIWI_AI_MAX_DOM_SNAPSHOT_CHARS",description:"Max characters of the failure-time DOM snapshot rendered from the trace (0 disables).",min:0,max:5e4},{key:"imageMaxEdge",label:"Screenshot max edge (px)",envVar:"PIWI_AI_IMAGE_MAX_EDGE",description:"Screenshots are downscaled to at most this many pixels on the long edge before being sent.",min:512,max:8192}],Ot={class:"space-y-6"},Lt={class:"space-y-5"},Bt={class:"flex items-center gap-3"},Ft={class:"flex items-center gap-2 justify-end"},Wt={class:"flex justify-end"},Dt={class:"flex justify-end"},Nt={class:"grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-3"},Xt={class:"flex justify-end gap-2"},ms=H({__name:"ai",async setup(a){let I,T;const g=Oe(),{data:r,refresh:k}=([I,T]=ae(()=>oe("/api/settings/ai","$nV9xx-QVRl")),I=await I,T(),I);function b(){return{enabled:!1,reuse:null,provider:"",model:"",baseUrl:"",apiKey:""}}const d=z({diagnosis:b(),research:b(),embedding:b()}),l=E(!1),x=E(""),V=E(""),$=E(!1),y=E(!1),i=E(!1),C=z({diagnosis:!1,research:!1,embedding:!1}),R=z({diagnosis:[],research:[],embedding:[]}),O=z({diagnosis:!1,research:!1,embedding:!1});function v(t){const e=d[t];return e.reuse?d[e.reuse]?.provider||"":e.provider}async function h(t){const e=d[t],f=v(t),M=e.reuse?d[e.reuse]:e,ee=M.apiKey||void 0;O[t]=!0;try{const te=await $fetch("/api/settings/ai/models",{method:"POST",body:{role:t,provider:f,baseUrl:M.baseUrl||void 0,apiKey:ee}});R[t]=te.models}catch{R[t]=[]}finally{O[t]=!1}}const w=[{key:"diagnosis",title:"Diagnosis model",icon:"i-lucide-stethoscope",help:"settings.ai-provider",optional:!1,enableLabel:"",blurb:"The main model that writes the final diagnosis. Required to enable AI features.",reuseTargets:[],modelPlaceholderAnthropic:"claude-opus-4-8",modelPlaceholderOpenai:"e.g. gpt-4o, llama3.1"},{key:"research",title:"Research model",icon:"i-lucide-search",help:"settings.ai-research",optional:!0,enableLabel:"Two-stage diagnosis",blurb:"A cheaper/faster model that pre-analyzes the failure before the diagnosis model writes the final answer. Also used for cluster naming and merge adjudication.",reuseTargets:["diagnosis"],modelPlaceholderAnthropic:"e.g. claude-haiku-4-5",modelPlaceholderOpenai:"e.g. llama-3.1-8b-instant"},{key:"embedding",title:"Embedding model",icon:"i-lucide-vector-square",help:"settings.embedding-model",optional:!0,enableLabel:"Semantic clustering",blurb:"Embeds failures so semantically-similar errors group together (used by failure clustering).",reuseTargets:["diagnosis","research"],modelPlaceholderAnthropic:"— Anthropic has no embeddings API —",modelPlaceholderOpenai:"e.g. text-embedding-3-small"}],de=[{label:"Anthropic API",value:"anthropic"},{label:"OpenAI-compatible",value:"openai"}],he=de.filter(t=>t.value!=="anthropic"),be=N(()=>{const t={};for(const e of w)t[e.key]=[{label:"Configure its own provider",value:"own"},...e.reuseTargets.filter(f=>d[f].enabled||f==="diagnosis").filter(f=>e.key!=="embedding"||d[f].provider==="openai").map(f=>({label:`Reuse ${w.find(M=>M.key===f).title.toLowerCase()}`,value:f}))];return t}),D=N(()=>!!r.value?.envManaged),_e=Xe(qe("ai"));se(r,t=>{if(t){for(const e of w){const f=t.roles[e.key],M=d[e.key];M.enabled=!!f,M.reuse=f?.reuse??null,M.provider=f?.provider??"",M.model=f?.model??"",M.baseUrl=f?.baseUrl??"",M.apiKey=""}l.value=t.autoDiagnose,x.value=t.customInstructions||""}},{immediate:!0});function xe(t){return!!r.value?.roles[t]?.hasApiKey}const ce=[{label:"ollama (local)",baseUrl:"http://localhost:11434/v1",model:"llama3.1"},{label:"LM Studio (local)",baseUrl:"http://localhost:1234/v1",model:""},{label:"OpenRouter",baseUrl:"https://openrouter.ai/api/v1",model:"meta-llama/llama-3.1-8b-instruct"},{label:"Groq",baseUrl:"https://api.groq.com/openai/v1",model:"llama-3.1-8b-instant"},{label:"OpenAI",baseUrl:"https://api.openai.com/v1",model:"gpt-4o"},{label:"Mistral AI",baseUrl:"https://api.mistral.ai/v1",model:"mistral-small-latest"},{label:"Custom",baseUrl:"",model:""}],ke=ce.map(t=>({label:t.label,value:t.label}));function Ae(t,e){const f=ce.find(M=>M.label===e);!f||f.label==="Custom"||(d[t].baseUrl=f.baseUrl,d[t].model=f.model)}function Q(t){const e=d[t];if(!e.enabled)return null;if(e.reuse)return{reuse:e.reuse,model:e.model||void 0};const f={provider:e.provider,model:e.model||void 0,baseUrl:e.baseUrl||void 0};return e.apiKey!==""&&(f.apiKey=e.apiKey),f}async function Ie(){$.value=!0;try{!D&&(!d.diagnosis.enabled||!d.diagnosis.provider)?await $fetch("/api/settings/ai",{method:"PUT",body:{roles:null,autoDiagnose:l.value}}):await $fetch("/api/settings/ai",{method:"PUT",body:{roles:{diagnosis:Q("diagnosis"),research:Q("research"),embedding:Q("embedding")},autoDiagnose:l.value}}),await k();for(const t of w)d[t.key].apiKey="";g.add({title:"Settings saved",color:"success"})}catch(t){g.add({title:"Save failed",description:String(t?.message??t),color:"error"})}finally{$.value=!1}}async function Me(){i.value=!0;try{await $fetch("/api/settings/ai",{method:"PUT",body:{scmToken:V.value||null}}),await k(),V.value="",g.add({title:"SCM token saved",color:"success"})}catch(t){g.add({title:"Save failed",description:String(t?.message??t),color:"error"})}finally{i.value=!1}}async function Se(){y.value=!0;try{await $fetch("/api/settings/ai",{method:"PUT",body:{customInstructions:x.value||null}}),await k(),g.add({title:"Instructions saved",color:"success"})}catch(t){g.add({title:"Save failed",description:String(t?.message??t),color:"error"})}finally{y.value=!1}}async function Ve(t){C[t]=!0;try{const e=d[t],f=e.reuse?d[e.reuse]:e,M=await $fetch("/api/settings/ai/test",{method:"POST",body:{role:t,provider:f.provider||void 0,apiKey:f.apiKey||void 0,model:e.model||(e.reuse?f.model:"")||void 0,baseUrl:f.baseUrl||void 0}});M.success?g.add({title:"Connection successful",description:`Model: ${M.model}`,color:"success"}):g.add({title:"Connection failed",description:M.error||"Unknown error",color:"error"})}catch(e){g.add({title:"Connection failed",description:String(e?.message??e),color:"error"})}finally{C[t]=!1}}const{data:L}=([I,T]=ae(()=>oe("/api/settings/ai/limits","$cSpsteApgW")),I=await I,T(),I),Y=$t,q=z({}),Z=E(!1),J=N(()=>new Set(L.value?.envManaged??[]));se(L,t=>{if(t)for(const e of Y)q[e.key]=t.limits[e.key]},{immediate:!0});async function we(){Z.value=!0;try{L.value=await $fetch("/api/settings/ai/limits",{method:"PUT",body:{limits:q}}),g.add({title:"Context limits saved",color:"success"})}catch(t){g.add({title:"Failed to save context limits",description:String(t?.message??t),color:"error"})}finally{Z.value=!1}}function Pe(){if(L.value)for(const t of Y)J.value.has(t.key)||(q[t.key]=L.value.defaults[t.key])}return(t,e)=>{const f=Re,M=bt,ee=pe,te=Ee,j=re,K=ye,Te=Et,ue=G,me=ve,Ue=Ne,Ce=ge;return n(),p("div",Ot,[o(D)?(n(),P(f,{key:0,"env-vars":o(_e)},null,8,["env-vars"])):_("",!0),c(K,{icon:"i-lucide-sparkles",title:"Model providers",help:"settings.ai-provider"},{subtitle:u(()=>[...e[3]||(e[3]=[A(" Configure a complete provider for each model role. Optional roles can reuse another role's provider so you don't re-enter credentials. ",-1)])]),footer:u(()=>[s("div",Ft,[c(j,{color:"primary",loading:o($),icon:"i-lucide-save",onClick:Ie},{default:u(()=>[...e[5]||(e[5]=[A(" Save ",-1)])]),_:1},8,["loading"])])]),default:u(()=>[s("div",Lt,[(n(),p(U,null,F(w,m=>c(M,{key:m.key,modelValue:o(d)[m.key],"onUpdate:modelValue":B=>o(d)[m.key]=B,meta:m,"has-api-key":xe(m.key),"reuse-options":o(be)[m.key],"provider-options":m.key==="embedding"?o(he):de,"preset-options":o(ke),disabled:o(D),"env-managed":o(D),"provider-resolved":v(m.key),models:o(R)[m.key],"loading-models":o(O)[m.key],testing:o(C)[m.key],onApplyPreset:B=>Ae(m.key,B),onLoadModels:B=>h(m.key),onTest:B=>Ve(m.key)},null,8,["modelValue","onUpdate:modelValue","meta","has-api-key","reuse-options","provider-options","preset-options","disabled","env-managed","provider-resolved","models","loading-models","testing","onApplyPreset","onLoadModels","onTest"])),64)),c(te,{label:"Auto-diagnose",help:"settings.auto-diagnose","env-managed":o(D)},{default:u(()=>[s("div",Bt,[c(ee,{modelValue:o(l),"onUpdate:modelValue":e[0]||(e[0]=m=>W(l)?l.value=m:null),disabled:o(D)||!o(d).diagnosis.enabled},null,8,["modelValue","disabled"]),e[4]||(e[4]=s("span",{class:"text-sm text-gray-500"}," Automatically diagnose new failure clusters when a run finishes — up to 3 clusters per run (research + diagnosis call each), plus one batched call to title new clusters ",-1))])]),_:1},8,["env-managed"])])]),_:1}),c(Te),c(K,{title:"Repository access",help:"project.scm-token"},{subtitle:u(()=>[...e[6]||(e[6]=[A(" Optional — required for private repositories. Per-project tokens override this. ",-1)])]),footer:u(()=>[s("div",Wt,[c(j,{color:"primary",loading:o(i),icon:"i-lucide-save",onClick:Me},{default:u(()=>[...e[7]||(e[7]=[A(" Save token ",-1)])]),_:1},8,["loading"])])]),default:u(()=>[c(me,{label:"SCM token",description:o(r)?.hasScmToken?"Leave empty to keep the stored token, enter a new value to replace it, or save empty to remove it":"Personal access token with read access to repository contents. Supports GitHub (ghp_), GitLab (glpat-), and Bitbucket tokens."},{default:u(()=>[c(ue,{modelValue:o(V),"onUpdate:modelValue":e[1]||(e[1]=m=>W(V)?V.value=m:null),type:"password",placeholder:o(r)?.hasScmToken?"•••••••• (unchanged)":"ghp_..., glpat-..., or Bitbucket token",class:"w-full font-mono"},null,8,["modelValue","placeholder"])]),_:1},8,["description"])]),_:1}),c(K,{title:"Global analysis instructions",help:"settings.ai-instructions"},{footer:u(()=>[s("div",Dt,[c(j,{color:"primary",loading:o(y),icon:"i-lucide-save",onClick:Se},{default:u(()=>[...e[8]||(e[8]=[A(" Save instructions ",-1)])]),_:1},8,["loading"])])]),default:u(()=>[c(Ue,{modelValue:o(x),"onUpdate:modelValue":e[2]||(e[2]=m=>W(x)?x.value=m:null),rows:6,placeholder:"e.g. Always suggest running failing tests with --repeat-each 5 to confirm flakiness. Prefer network-level evidence over ARIA snapshots. Recommend git bisect when a commit range is available.",class:"w-full font-mono text-sm"},null,8,["modelValue"]),e[9]||(e[9]=s("p",{class:"text-xs text-gray-400 mt-2"}," These instructions are appended to the base system prompt. They shape how the AI analyzes failures but cannot override the response schema or confidence requirement. ",-1))]),_:1}),c(K,{title:"Diagnosis context limits",help:"settings.ai-limits"},{subtitle:u(()=>[...e[10]||(e[10]=[A(" Leave a field empty to use its default; env-managed fields are read-only. ",-1)])]),footer:u(()=>[s("div",Xt,[c(j,{color:"neutral",variant:"ghost",size:"sm",onClick:Pe},{default:u(()=>[...e[11]||(e[11]=[A("Reset to defaults",-1)])]),_:1}),c(j,{color:"primary",loading:o(Z),icon:"i-lucide-save",size:"sm",onClick:we},{default:u(()=>[...e[12]||(e[12]=[A(" Save limits ",-1)])]),_:1},8,["loading"])])]),default:u(()=>[s("div",Nt,[(n(!0),p(U,null,F(o(Y),m=>(n(),P(me,{key:m.key,label:m.label,description:m.description,hint:`default ${o(L)?.defaults[m.key]??""}`},{default:u(()=>[c(ue,{modelValue:o(q)[m.key],"onUpdate:modelValue":B=>o(q)[m.key]=B,modelModifiers:{number:!0},type:"number",min:m.min,max:m.max,disabled:o(J).has(m.key),placeholder:`default ${o(L)?.defaults[m.key]??""}`,class:"w-full"},Le({_:2},[o(J).has(m.key)?{name:"trailing",fn:u(()=>[c(Ce,{"env-vars":[m.envVar]},null,8,["env-vars"])]),key:"0"}:void 0]),1032,["modelValue","onUpdate:modelValue","min","max","disabled","placeholder"])]),_:2},1032,["label","description","hint"]))),128))])]),_:1}),c(K,{icon:"i-lucide-shield-check",title:"Privacy notice",help:"settings.privacy"},{default:u(()=>[...e[13]||(e[13]=[s("div",{class:"space-y-2 text-sm text-gray-600 dark:text-gray-400"},[s("p",null,"When diagnosing a failure cluster, the following data is sent to the configured LLM provider:"),s("ul",{class:"list-disc list-inside space-y-1 ml-2"},[s("li",null,"Normalized error signature and sample raw error text"),s("li",null,"Test titles and file paths for affected tests"),s("li",null,"Browser info, test steps, console error/warning entries (excerpts)"),s("li",null,"Failed network request URLs and status codes"),s("li",null,"ARIA page snapshot (if collected)"),s("li",null," Commit SHA range since last passing run, plus changed file names and diff patches fetched from GitHub/GitLab/Bitbucket (if a repository token is configured or the repo is public) ")]),s("p",{class:"mt-2"},[A(" API keys are stored encrypted in the application database (admin-only access). For stricter setups, use the "),s("code",{class:"font-mono text-xs"},"PIWI_AI_*"),A(" environment variables instead of the UI. ")])],-1)])]),_:1})])}}});export{ms as default};