@piwitests/server 0.23.0 → 0.24.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.
- package/.output/nitro.json +1 -1
- package/.output/public/_nuxt/{Clg2Qx0r.js → -COcylA_.js} +1 -1
- package/.output/public/_nuxt/03FA4-rI.js +1 -0
- package/.output/public/_nuxt/{B7tiBVLW.js → 5a7jHE9s.js} +1 -1
- package/.output/public/_nuxt/{roaTZkYi.js → 6Z_ZwH8I.js} +1 -1
- package/.output/public/_nuxt/{xZQGtnVA.js → 7ZHq6PCI.js} +1 -1
- package/.output/public/_nuxt/{5SkLJHl8.js → 98sAB6Gu.js} +1 -1
- package/.output/public/_nuxt/{DnxrNGE_.js → B--J7VNt.js} +1 -1
- package/.output/public/_nuxt/{DJzFYrBt.js → B1LUinhp.js} +1 -1
- package/.output/public/_nuxt/{axj2iIDK.js → B33YjaHr.js} +1 -1
- package/.output/public/_nuxt/B69RP95P.js +1 -0
- package/.output/public/_nuxt/{DNKZmhbX.js → B8H4XydJ.js} +1 -1
- package/.output/public/_nuxt/{DmqCquDx.js → B8Xm4_S_.js} +1 -1
- package/.output/public/_nuxt/{Ya8ZzWuY.js → BBhrClA9.js} +1 -1
- package/.output/public/_nuxt/{BZFiz2UB.js → BCGljaM0.js} +1 -1
- package/.output/public/_nuxt/{oSLbl-p0.js → BFxvHlO9.js} +1 -1
- package/.output/public/_nuxt/{PDSNX4Te.js → BKrWWV14.js} +1 -1
- package/.output/public/_nuxt/BN1zZw5b.js +9 -0
- package/.output/public/_nuxt/{Dbf8eT28.js → BPXqL9vK.js} +1 -1
- package/.output/public/_nuxt/{DgEa6_av.js → BUnwEAjq.js} +1 -1
- package/.output/public/_nuxt/{CUOS6S13.js → BVLqydCr.js} +1 -1
- package/.output/public/_nuxt/{CvVbKrcH.js → BWMSVSNM.js} +1 -1
- package/.output/public/_nuxt/{Wk7ZKG4B.js → B_r0xHVS.js} +1 -1
- package/.output/public/_nuxt/{DAhv9aNg.js → BakMHV79.js} +1 -1
- package/.output/public/_nuxt/{BDUfBn3i.js → Bd8B-yeR.js} +1 -1
- package/.output/public/_nuxt/{sqqg4oXL.js → BevElZaK.js} +1 -1
- package/.output/public/_nuxt/{B0tmRAhY.js → BfA6lfg4.js} +1 -1
- package/.output/public/_nuxt/{D3SJGdl4.js → Bg93Rnts.js} +1 -1
- package/.output/public/_nuxt/{Ck_fTH5z.js → BgABj4Ty.js} +1 -1
- package/.output/public/_nuxt/{B2L0-Lzp.js → BkM2KXUo.js} +1 -1
- package/.output/public/_nuxt/{CBJFORiZ.js → BkxRbXIj.js} +1 -1
- package/.output/public/_nuxt/{Bsc11YIJ.js → Bme1UkOl.js} +1 -1
- package/.output/public/_nuxt/{BfcMJBTf.js → BmzxRbcg.js} +1 -1
- package/.output/public/_nuxt/{D7fxV-UA.js → Bn0jaRxI.js} +1 -1
- package/.output/public/_nuxt/{C77tM5Hz.js → BoNKdx5o.js} +1 -1
- package/.output/public/_nuxt/{Bb2mDqKr.js → Bp3FRuEm.js} +1 -1
- package/.output/public/_nuxt/{BjOFxi54.js → BrUBOQ0y.js} +1 -1
- package/.output/public/_nuxt/{DXkFgrsT.js → BtSGUY-7.js} +1 -1
- package/.output/public/_nuxt/{QZYo3ErV.js → BtbpLWDs.js} +1 -1
- package/.output/public/_nuxt/{Bag08cIY.js → BvAfKk6C.js} +1 -1
- package/.output/public/_nuxt/{BOvtXn3m.js → BwEN1fJ1.js} +1 -1
- package/.output/public/_nuxt/{DYjxDsYC.js → C-XjxjG5.js} +1 -1
- package/.output/public/_nuxt/{RkNtgoTD.js → C3W_wyr9.js} +1 -1
- package/.output/public/_nuxt/{CNu3kken.js → C5TrTuWv.js} +3 -3
- package/.output/public/_nuxt/{B4mZElvM.js → C7D5Wl7T.js} +1 -1
- package/.output/public/_nuxt/{ZLfZolDM.js → C7fq_rHE.js} +1 -1
- package/.output/public/_nuxt/{B_JSV0yG.js → C8Paf_V1.js} +1 -1
- package/.output/public/_nuxt/{C2_7XZo0.js → CD8ZzAFC.js} +1 -1
- package/.output/public/_nuxt/{CTTmX4gy.js → CDTeSrLO.js} +1 -1
- package/.output/public/_nuxt/{CLWMETf9.js → CGHV0Y2d.js} +1 -1
- package/.output/public/_nuxt/{AQ86C4c2.js → CIpF9l75.js} +1 -1
- package/.output/public/_nuxt/{jR2xm3_t.js → CJ1rmnk4.js} +1 -1
- package/.output/public/_nuxt/{7_9fts7T.js → CMuzkARi.js} +1 -1
- package/.output/public/_nuxt/{a8Z6VC7V.js → COuZu9FO.js} +1 -1
- package/.output/public/_nuxt/{D7t0Dn3h.js → CX5Q0dZ8.js} +1 -1
- package/.output/public/_nuxt/{9_aJhhcm.js → CX_G-FHC.js} +14 -14
- package/.output/public/_nuxt/{C9I1Dp3S.js → Ce5_Tq63.js} +1 -1
- package/.output/public/_nuxt/{BtZNYmZO.js → Cf4MFOuf.js} +1 -1
- package/.output/public/_nuxt/{mi22nGUC.js → CgkXEZMo.js} +1 -1
- package/.output/public/_nuxt/{Ce89VyHE.js → CjBktNrC.js} +1 -1
- package/.output/public/_nuxt/{Bj_v57Zu.js → CjtjQV60.js} +1 -1
- package/.output/public/_nuxt/{BuGAn4f7.js → CpcrljrH.js} +1 -1
- package/.output/public/_nuxt/{6vX5JdHr.js → Cq33x7yV.js} +1 -1
- package/.output/public/_nuxt/{jxc14CqP.js → CsV7pmcT.js} +1 -1
- package/.output/public/_nuxt/{DTrPCv7R.js → Cu2Q4iPh.js} +1 -1
- package/.output/public/_nuxt/{DylyATWU.js → CyLcEDg2.js} +1 -1
- package/.output/public/_nuxt/{Ce_j5NtN.js → D0Kop4bS.js} +1 -1
- package/.output/public/_nuxt/{DCE2_MKD.js → D1Y43xM1.js} +1 -1
- package/.output/public/_nuxt/{499RbBSX.js → D1vqYZsL.js} +1 -1
- package/.output/public/_nuxt/{BjMo2tKC.js → D2rZosKf.js} +1 -1
- package/.output/public/_nuxt/D7jpwkRG.js +5 -0
- package/.output/public/_nuxt/{BFYkWpPx.js → D8NAb7VE.js} +1 -1
- package/.output/public/_nuxt/{CIQeRUSy.js → D8vguZKg.js} +1 -1
- package/.output/public/_nuxt/{Bq4_kqIp.js → DEvYVl9M.js} +1 -1
- package/.output/public/_nuxt/{DBWM_xs-.js → DF6Mes5z.js} +1 -1
- package/.output/public/_nuxt/{CGDPUNcO.js → DGq4A2Pd.js} +1 -1
- package/.output/public/_nuxt/{CF_eDZHu.js → DH5H1DJh.js} +1 -1
- package/.output/public/_nuxt/{kWnH8yJq.js → DL8knjzi.js} +1 -1
- package/.output/public/_nuxt/{CC8wk-N0.js → DM3bDZC6.js} +1 -1
- package/.output/public/_nuxt/{Ce47NgZw.js → DMAiMrNr.js} +1 -1
- package/.output/public/_nuxt/{HbnAkiyK.js → DMWfVJCj.js} +1 -1
- package/.output/public/_nuxt/{B3AG2m76.js → DMsm-RGQ.js} +1 -1
- package/.output/public/_nuxt/{DeewM3Wg.js → DMtrFQqi.js} +1 -1
- package/.output/public/_nuxt/{D1Ucra3E.js → DPZBpFOX.js} +1 -1
- package/.output/public/_nuxt/{DiWxW-w3.js → DVEGfqtt.js} +1 -1
- package/.output/public/_nuxt/{DZ-KbUZi.js → D_y2VS8k.js} +1 -1
- package/.output/public/_nuxt/DaNC-xl1.js +1 -0
- package/.output/public/_nuxt/{DZECGgZm.js → DbmGeOus.js} +1 -1
- package/.output/public/_nuxt/{HIGGZ_c-.js → DcLbz6DV.js} +1 -1
- package/.output/public/_nuxt/{B_MVJP17.js → DcR0Mmdl.js} +1 -1
- package/.output/public/_nuxt/{DNqm5cWU.js → DhYznn-U.js} +1 -1
- package/.output/public/_nuxt/DhuRRlmK.js +1 -0
- package/.output/public/_nuxt/{pZbe82l5.js → Drw8yQg6.js} +1 -1
- package/.output/public/_nuxt/{CPQRQqXU.js → DuO5wfAC.js} +1 -1
- package/.output/public/_nuxt/{FJTsZ5Aa.js → DuOH5jcQ.js} +1 -1
- package/.output/public/_nuxt/{BM5BPKlc.js → DvEsAuE9.js} +1 -1
- package/.output/public/_nuxt/{dUPMBJ4f.js → Dz6g_QJT.js} +1 -1
- package/.output/public/_nuxt/{BAbrtVp3.js → DzZpIs4W.js} +1 -1
- package/.output/public/_nuxt/DzzNS-K1.js +1 -0
- package/.output/public/_nuxt/{BwwfasRt.js → Fsw2W4TA.js} +1 -1
- package/.output/public/_nuxt/{CdEzDaDI.js → LwoTUb-r.js} +1 -1
- package/.output/public/_nuxt/{DuBtaw3j.js → OfPjZaky.js} +1 -1
- package/.output/public/_nuxt/{LTMoFvEY.js → P5uOaRUZ.js} +1 -1
- package/.output/public/_nuxt/{B3G-TIoP.js → Qo6oszaF.js} +1 -1
- package/.output/public/_nuxt/{DprkT7rM.js → T5UuMUxA.js} +1 -1
- package/.output/public/_nuxt/UY8pjaZA.js +1 -0
- package/.output/public/_nuxt/{CmTzxoQt.js → V9p3z39z.js} +1 -1
- package/.output/public/_nuxt/{5QBnDbs_.js → VACXezo0.js} +1 -1
- package/.output/public/_nuxt/{6sA-GK37.js → YmCeJkZ2.js} +1 -1
- package/.output/public/_nuxt/builds/latest.json +1 -1
- package/.output/public/_nuxt/builds/meta/70224ee0-4d1f-45d2-b380-2ecb18064bf1.json +1 -0
- package/.output/public/_nuxt/entry.DzPSf_u5.css +1 -0
- package/.output/public/_nuxt/fXUwH_3d.js +1 -0
- package/.output/public/_nuxt/{CAoQUDI4.js → opwuUqHG.js} +1 -1
- package/.output/public/_nuxt/{2yLW7WU0.js → opyDpgSw.js} +1 -1
- package/.output/public/_nuxt/{B070fjS-.js → sVV8xB9f.js} +1 -1
- package/.output/public/_nuxt/{C6t4kxaa.js → xa5UHCot.js} +1 -1
- package/.output/server/chunks/_/collect.mjs +1 -1
- package/.output/server/chunks/_/markers.mjs +1 -1
- package/.output/server/chunks/_/quarantine.mjs +1 -1
- package/.output/server/chunks/_/users.mjs +1 -1
- package/.output/server/chunks/build/Checkbox-BisdHf8n.mjs +1 -1
- package/.output/server/chunks/build/CodeBlock-B8BNtZAe.mjs +1 -1
- package/.output/server/chunks/build/DashboardSidebarToggle-C3HdHvlE.mjs +1 -1
- package/.output/server/chunks/build/DiagnosisPanel-BVb2LgHu.mjs +1 -1
- package/.output/server/chunks/build/DiagnosisResult-xVgZlfKK.mjs +1 -1
- package/.output/server/chunks/build/EntityLinks-Dzn73fbq.mjs +1 -1
- package/.output/server/chunks/build/HelpHint-plioHKA0.mjs +27 -0
- package/.output/server/chunks/build/NavigationMenu-RfBOyS32.mjs +1 -1
- package/.output/server/chunks/build/OpenInIdeLink-Jp6SzEtD.mjs +1 -1
- package/.output/server/chunks/build/RunReports-nuLb-Nm3.mjs +1 -1
- package/.output/server/chunks/build/Select-CEyw7HGK.mjs +1 -1
- package/.output/server/chunks/build/SelectMenu-C02Hs2_F.mjs +1 -1
- package/.output/server/chunks/build/Table-qZdnm9t2.mjs +1 -1
- package/.output/server/chunks/build/Tooltip-BI3WQErw.mjs +1 -1
- package/.output/server/chunks/build/{_id_-D7UtAIPR.mjs → _id_-26komi8G.mjs} +15 -8
- package/.output/server/chunks/build/{_id_-D7UtAIPR.mjs.map → _id_-26komi8G.mjs.map} +1 -1
- package/.output/server/chunks/build/{_id_-CrGTZymJ.mjs → _id_-w7YCSiiy.mjs} +2 -2
- package/.output/server/chunks/build/{_id_-CrGTZymJ.mjs.map → _id_-w7YCSiiy.mjs.map} +1 -1
- package/.output/server/chunks/build/_id_-wiULjAVc.mjs +1 -1
- package/.output/server/chunks/build/ai-DYhpzbqp.mjs +1 -1
- package/.output/server/chunks/build/client.precomputed.mjs +1 -1
- package/.output/server/chunks/build/{db.client-Bdqk_eYQ.mjs → db.client-DijpEH6i.mjs} +3 -1
- package/.output/server/chunks/build/db.client-DijpEH6i.mjs.map +1 -0
- package/.output/server/chunks/build/{default-DO1izI2V.mjs → default-CQa_bmAf.mjs} +2 -2
- package/.output/server/chunks/build/{default-DO1izI2V.mjs.map → default-CQa_bmAf.mjs.map} +1 -1
- package/.output/server/chunks/build/fetch-tkz5_OA-.mjs +1 -1
- package/.output/server/chunks/build/import-B27Sv7h5.mjs +1 -1
- package/.output/server/chunks/build/{index-vRwzDXLs.mjs → index-Dq6nk6OB.mjs} +367 -87
- package/.output/server/chunks/build/index-Dq6nk6OB.mjs.map +1 -0
- package/.output/server/chunks/build/isValueEqualOrExist-D4lZ8uRY.mjs +1 -1
- package/.output/server/chunks/build/login-hxCF06JT.mjs +1 -1
- package/.output/server/chunks/build/mcp-BVW1llyW.mjs +1 -1
- package/.output/server/chunks/build/server.mjs +6 -6
- package/.output/server/chunks/build/settings-metadata-DnAK4Rzg.mjs +1 -1
- package/.output/server/chunks/build/storage-zN92cA9q.mjs +1 -1
- package/.output/server/chunks/build/test-functions-DVRJgiWo.mjs +1 -1
- package/.output/server/chunks/build/{useCopyRich-CZxJ7IY_.mjs → useCopyRich-BM9GTjJi.mjs} +64 -18
- package/.output/server/chunks/build/{useCopyRich-CZxJ7IY_.mjs.map → useCopyRich-BM9GTjJi.mjs.map} +1 -1
- package/.output/server/chunks/nitro/nitro.mjs +1037 -733
- package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
- package/.output/server/chunks/routes/__piwi/session.get.mjs +1 -1
- package/.output/server/chunks/routes/api/ai/step-resolution.post.mjs +88 -0
- package/.output/server/chunks/routes/api/ai/step-resolution.post.mjs.map +1 -0
- package/.output/server/chunks/routes/api/analytics/_widget_.get.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/change-password.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/forgot-password.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/login.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/logout.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/me.get.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/oauth/_provider/callback.get.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/oauth/_provider/login.get.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/oauth/_provider/unlink.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/reset-password.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/send-verify-email.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/setup.get.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/setup.post.mjs +1 -1
- package/.output/server/chunks/routes/api/auth/verify-email.get.mjs +1 -1
- package/.output/server/chunks/routes/api/channels/_id/test.post.mjs +1 -1
- package/.output/server/chunks/routes/api/channels/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/cluster-merge-suggestions/_id/approve.post.mjs +1 -1
- package/.output/server/chunks/routes/api/cluster-merge-suggestions/_id/reject.post.mjs +1 -1
- package/.output/server/chunks/routes/api/desktop/import-local.post.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/base-commit.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/branches.get.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/commit-diff.get.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/commits.get.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/context.get.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/diagnose/stream.post.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/diagnose.post.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/diagnoses.get.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/diagnosis.get.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/export.get.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/extract-cases.post.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/fix-plan.get.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id/status.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-clusters/_id_.get.mjs +1 -1
- package/.output/server/chunks/routes/api/failure-diagnoses/_id/feedback.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/files/_...path_.get.mjs +1 -1
- package/.output/server/chunks/routes/api/health.get.mjs +1 -1
- package/.output/server/chunks/routes/api/index.get.mjs +1 -1
- package/.output/server/chunks/routes/api/index.get2.mjs +1 -1
- package/.output/server/chunks/routes/api/index.get3.mjs +1 -1
- package/.output/server/chunks/routes/api/index.get4.mjs +1 -1
- package/.output/server/chunks/routes/api/index.get5.mjs +1 -1
- package/.output/server/chunks/routes/api/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/index.post2.mjs +1 -1
- package/.output/server/chunks/routes/api/index.post3.mjs +1 -1
- package/.output/server/chunks/routes/api/index.post4.mjs +1 -1
- package/.output/server/chunks/routes/api/index.post5.mjs +1 -1
- package/.output/server/chunks/routes/api/index.post6.mjs +1 -1
- package/.output/server/chunks/routes/api/links/_id/refresh.post.mjs +1 -1
- package/.output/server/chunks/routes/api/links/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/links/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/markers/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/markers/_id_.put.mjs +1 -1
- package/.output/server/chunks/routes/api/notifications/stream.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/ai-steps.get.mjs +63 -0
- package/.output/server/chunks/routes/api/projects/_id/ai-steps.get.mjs.map +1 -0
- package/.output/server/chunks/routes/api/projects/_id/cluster-merge-suggestions.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/failure-clusters.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/flaky-classify.post.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/flaky-tests.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/latest-run.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/markers.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/markers.post.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/members.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/members.put.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/performance.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/quarantine/_testCaseId_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/quarantine.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/quarantine.post.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/slow-tests.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/spec-health.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/test-cases.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/test-functions/extract.post.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/test-functions/validate-proposal.post.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/test-functions.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/test-functions.post.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id/timeout-opportunities.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id_.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/_id_.put.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/menu.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects/overview.get.mjs +1 -1
- package/.output/server/chunks/routes/api/projects.get.mjs +1 -1
- package/.output/server/chunks/routes/api/search.get.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/ai/limits.get.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/ai/limits.put.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/ai/test.post.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/ai/usage.get.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/ai.get.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/ai.put.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/pr-feedback.get.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/pr-feedback.put.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/smtp/test.post.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/smtp.get.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/timeout-hygiene.get.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/timeout-hygiene.put.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/wasted-waits.get.mjs +1 -1
- package/.output/server/chunks/routes/api/settings/wasted-waits.put.mjs +1 -1
- package/.output/server/chunks/routes/api/setup-status.get.mjs +1 -1
- package/.output/server/chunks/routes/api/stream.get.mjs +1 -1
- package/.output/server/chunks/routes/api/subscriptions/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/subscriptions/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/tags/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/tags/_id_.put.mjs +1 -1
- package/.output/server/chunks/routes/api/test-cases/_id/history.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-cases/_id/stability-trend.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-cases/_id_.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-functions/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/test-functions/_id_.put.mjs +1 -1
- package/.output/server/chunks/routes/api/test-run-cases/_id/diagnose.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-run-cases/_id/diagnosis-context.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-run-cases/_id/diagnosis.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-run-cases/_id/export.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-run-cases/_id/traces.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-run-cases/_id_.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/begin.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/case-files.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/dom-snapshot.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/environment-diff.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/locator-healing.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/locator-pick.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-network-body.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-network.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/trace-stacks.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/cases/_caseId/visual-diff.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/events.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/failure-groups.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/finish.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/gate.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/heartbeat.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/insights.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/network-requests.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/regression-context.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/stream.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id/summary.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id_.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/import/check.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/import.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/recent.get.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/setup.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/start.post.mjs +1 -1
- package/.output/server/chunks/routes/api/test-runs/submit.post.mjs +3 -1
- package/.output/server/chunks/routes/api/test-runs/submit.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/test-runs/upload.post.mjs +2 -1
- package/.output/server/chunks/routes/api/test-runs/upload.post.mjs.map +1 -1
- package/.output/server/chunks/routes/api/tests/cleanup.delete.mjs +2 -1
- package/.output/server/chunks/routes/api/tests/cleanup.delete.mjs.map +1 -1
- package/.output/server/chunks/routes/api/traces/check.post.mjs +1 -1
- package/.output/server/chunks/routes/api/users/_id/api-keys/_keyId_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/users/_id/index.get.mjs +1 -1
- package/.output/server/chunks/routes/api/users/_id/index.post.mjs +1 -1
- package/.output/server/chunks/routes/api/users/_id/invite.post.mjs +1 -1
- package/.output/server/chunks/routes/api/users/_id/projects.get.mjs +1 -1
- package/.output/server/chunks/routes/api/users/_id/projects.put.mjs +1 -1
- package/.output/server/chunks/routes/api/users/_id_.delete.mjs +1 -1
- package/.output/server/chunks/routes/api/users/_id_.patch.mjs +1 -1
- package/.output/server/chunks/routes/api/version.get.mjs +1 -1
- package/.output/server/chunks/routes/mcp.post.mjs +1 -1
- package/.output/server/chunks/routes/renderer.mjs +1 -1
- package/.output/server/database/migrations/0045_productive_stingray.sql +1 -0
- package/.output/server/database/migrations/meta/0045_snapshot.json +3779 -0
- package/.output/server/database/migrations/meta/_journal.json +7 -0
- package/.output/server/database/migrations-pg/0046_gorgeous_hercules.sql +1 -0
- package/.output/server/database/migrations-pg/meta/0046_snapshot.json +4486 -0
- package/.output/server/database/migrations-pg/meta/_journal.json +7 -0
- package/.output/server/index.mjs +1 -1
- package/.output/server/package.json +1 -1
- package/package.json +1 -1
- package/.output/public/_nuxt/BNyTWIad.js +0 -9
- package/.output/public/_nuxt/BVyjw9Bi.js +0 -1
- package/.output/public/_nuxt/BZOykMLD.js +0 -1
- package/.output/public/_nuxt/CEai-PWF.js +0 -1
- package/.output/public/_nuxt/CYhm2FBS.js +0 -5
- package/.output/public/_nuxt/CfhOanaF.js +0 -1
- package/.output/public/_nuxt/Cz7SCzdW.js +0 -1
- package/.output/public/_nuxt/DFfqRQxk.js +0 -1
- package/.output/public/_nuxt/builds/meta/6d1766a0-0aba-46b8-9d97-7dd174130359.json +0 -1
- package/.output/public/_nuxt/eT2oObCh.js +0 -1
- package/.output/public/_nuxt/entry.D_eWXrnD.css +0 -1
- package/.output/server/chunks/build/db.client-Bdqk_eYQ.mjs.map +0 -1
- package/.output/server/chunks/build/index-vRwzDXLs.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as Ms}from"./Cu2Q4iPh.js";import{_ as Fs}from"./Qo6oszaF.js";import{b as Ae,A as wt,d as oe,O as Ot,w as he,J as ye,k as e,o as n,f,g as t,j as a,_ as ke,c as r,i as s,m as d,t as i,v as A,F as X,y as ae,p as Le,G as Be,l as J,P as Vt,Q as Nt,q as ie,h as B,r as I,K as Ps,s as Ce,R as qt,n as Rt,D as Dt,E as Ht,M as Es,u as Ls,a as Bs,e as Vs,C as Kt,S as Ns,T as Ks}from"./C5TrTuWv.js";import{_ as Os}from"./BrUBOQ0y.js";import{_ as Xe,a as qs}from"./B69RP95P.js";import{_ as ze}from"./Ce5_Tq63.js";import{_ as Qt}from"./DH5H1DJh.js";import{u as Hs}from"./BVLqydCr.js";import{u as xe}from"./T5UuMUxA.js";import{_ as Qs}from"./Drw8yQg6.js";import{_ as Gs,a as Xs}from"./opyDpgSw.js";import{_ as Gt}from"./CjBktNrC.js";import{_ as ut}from"./DMAiMrNr.js";import{u as Js}from"./CX5Q0dZ8.js";import{_ as Xt}from"./DGq4A2Pd.js";import{_ as $e}from"./BFxvHlO9.js";import{C as St,w as Jt,O as it,a as Wt,_ as Yt,u as Zt}from"./P5uOaRUZ.js";import{N as Ws}from"./DF6Mes5z.js";import{_ as Ys}from"./BkxRbXIj.js";import{_ as Zs}from"./C-XjxjG5.js";import{_ as en}from"./Cq33x7yV.js";import{_ as es}from"./DuOH5jcQ.js";import{_ as tn}from"./98sAB6Gu.js";import{_ as sn}from"./VACXezo0.js";import{_ as nn}from"./LwoTUb-r.js";import{_ as an}from"./DL8knjzi.js";import{_ as Ue}from"./Bg93Rnts.js";import{_ as Ve}from"./C8Paf_V1.js";import{_ as Ne}from"./DbmGeOus.js";import{f as At,b as on,c as ln,d as rn,i as E,t as cn,e as ts,p as ct,j as ot}from"./DMtrFQqi.js";import{_ as ss}from"./CMuzkARi.js";import{_ as dt}from"./D0Kop4bS.js";import{_ as Je}from"./DcLbz6DV.js";import{_ as un}from"./DvEsAuE9.js";import{_ as dn}from"./Bd8B-yeR.js";import{_ as mn}from"./DcR0Mmdl.js";import{_ as pn}from"./CJ1rmnk4.js";import{_ as gn}from"./BakMHV79.js";import{_ as fn}from"./Cf4MFOuf.js";import{_ as _n}from"./BvAfKk6C.js";import{_ as vn}from"./BfA6lfg4.js";import{_ as zt}from"./6Z_ZwH8I.js";import{M as yn,D as Tt,g as jt}from"./D7W_4Sqc.js";import{_ as hn}from"./DhYznn-U.js";import{u as xn}from"./BevElZaK.js";import{u as bn}from"./Bme1UkOl.js";import"./BCGljaM0.js";import"./BjaRappk.js";import"./DaNC-xl1.js";import"./D_y2VS8k.js";import"./03FA4-rI.js";import"./DMsm-RGQ.js";import"./D-c8ZSws.js";import"./V9p3z39z.js";import"./B8H4XydJ.js";import"./BBhrClA9.js";import"./DzZpIs4W.js";import"./CpcrljrH.js";import"./DEvYVl9M.js";const kn=["run.finished","run.failed","run.failed.default_branch","cluster.new","flakiness.spike","perf.regression","diagnosis.completed"],lt=new Map,rt=new Map;function $n(U,$){const k=[{event:"run.failed",scenario:{title:`Test run failed — ${U}`,description:"3 of 12 tests failed on main — checkout › applies discount code +2 more",icon:"i-lucide-circle-x",color:"error"}},{event:"run.failed.default_branch",scenario:{title:`Test run failed on main — ${U}`,description:"2 of 12 tests failed · main — auth › logs in with valid credentials +1 more",icon:"i-lucide-circle-x",color:"error"}},{event:"cluster.new",scenario:{title:`New failure cluster — ${U}`,description:"TimeoutError: locator.click: Timeout 30000ms exceeded",icon:"i-lucide-layers",color:"warning"}},{event:"flakiness.spike",scenario:{title:`Flakiness spike — ${U}`,description:"3 tests became flaky (8.3% rate)",icon:"i-lucide-shuffle",color:"warning"}},{event:"perf.regression",scenario:{title:`Performance regression — ${U}`,description:"p90 duration increased by 42% vs last week",icon:"i-lucide-trending-down",color:"warning"}},{event:"run.finished",scenario:{title:`Test run recovered — ${U}`,description:"All 12 tests passed on main",icon:"i-lucide-circle-check",color:"success"}},{event:"diagnosis.completed",scenario:{title:`Diagnosis complete — ${U}`,description:"Root cause: test bug — confidence: high",icon:"i-lucide-sparkles",color:"info"}}],C=k.filter(_=>$.length===0||$.includes(_.event)).map(_=>_.scenario);return C.length===0?[k[0].scenario,k[k.length-1].scenario]:C}function Cn(){if(!wt().public.demoMode)return null;const $=Ae();function k(_,p,c){C(_);const F=$n(p,c);rt.set(_,0);function R(){const z=(rt.get(_)??0)%F.length;rt.set(_,z+1);const h=F[z];$.add({title:h.title,description:h.description,icon:h.icon,color:h.color,duration:7e3});const y=25e3+Math.random()*1e4;lt.set(_,setTimeout(R,y))}lt.set(_,setTimeout(R,8e3))}function C(_){const p=lt.get(_);p!==void 0&&(clearTimeout(p),lt.delete(_)),rt.delete(_)}return{scheduleFor:k,cancelFor:C}}const Tn={key:0,class:"p-3 space-y-3"},jn={key:0,class:"text-xs text-gray-500"},Sn={key:1,class:"text-xs text-gray-500"},wn={key:2,class:"text-xs text-gray-500"},Rn={class:"space-y-1"},Dn=["checked","onChange"],An={key:1,class:"p-3 space-y-3"},zn={class:"flex items-center justify-between"},Un={class:"font-medium text-sm inline-flex items-center gap-1"},In={key:0,class:"text-xs text-muted bg-primary/5 rounded px-2 py-1.5"},Mn={key:1,class:"text-xs text-muted text-center py-2"},Fn={key:2,class:"space-y-1.5"},Pn={key:0,class:"space-y-2 rounded border border-primary/30 bg-primary/5 px-2 py-2"},En={class:"space-y-1"},Ln=["value"],Bn={class:"flex gap-1.5 justify-end"},Vn={class:"flex-1 font-medium truncate"},Nn={key:3,class:"text-xs text-muted text-center py-1"},Kn={key:4,class:"space-y-2 border-t border-default pt-2"},On={class:"space-y-1"},qn=["value"],Hn={class:"flex gap-1.5 justify-end"},Qn=oe({__name:"SubscribeBell",props:{projectId:{},projectLabel:{}},async setup(U){let $,k;const C=U,_=wt(),p=_.public.demoMode,c=B(()=>_.public.authEnabled),{authState:F}=Ot(),R=B(()=>F.value.authenticated),z=Ae(),h=I(!1),y=p?Cn():null,x=!c.value&&!p?Hs():null,T=I("default"),m=B(()=>"Notification"in window);"Notification"in window&&(T.value=Notification.permission);const v=B(()=>x?.getProject(C.projectId).events??[]),M=B(()=>x?.isSubscribed(C.projectId)??!1);async function V(){!m.value||T.value!=="default"||(T.value=await Notification.requestPermission())}function j(K){return v.value.includes(K)}function g(K){x?.toggleEvent(C.projectId,K)}const S=p||c.value&&R.value,O=p?{server:!1}:{},{data:D,refresh:Q}=([$,k]=he(()=>xe(`/api/subscriptions?projectId=${C.projectId}`,{immediate:S,...O},"$APDuK86tlj")),$=await $,k(),$),N=B(()=>D.value?.subscriptions??[]),ue=B(()=>N.value.length>0),{data:ge}=([$,k]=he(()=>xe("/api/channels",{immediate:S,...O},"$uK3f0xlELn")),$=await $,k(),$),b=B(()=>ge.value?.channels??[]),w=I(!1),H=I(void 0),de=I(["run.failed"]),Ie=I(!1),me=I(null),be=I(void 0),fe=I([]),Me=I(!1);function mt(K){me.value=K,be.value=K.channel.id,fe.value=[...K.events]}function pt(){me.value=null}async function Y(){if(!(!me.value||!be.value||fe.value.length===0)){Me.value=!0;try{await $fetch(`/api/subscriptions/${me.value.id}`,{method:"PATCH",body:{channelId:be.value,events:fe.value}}),await Q(),me.value=null}catch(K){z.add({title:"Update failed",description:String(K?.message??K),color:"error"})}finally{Me.value=!1}}}const We=B(()=>b.value.map(K=>({label:K.type==="personal_email"?`${K.name} (${K.config.address})`:K.name,value:K.id}))),Ke=kn.map(K=>({label:K.replace(/\./g," › "),value:K}));ye(h,K=>{K?(S&&Q(),b.value.length>0&&!H.value&&(H.value=b.value[0].id)):(w.value=!1,me.value=null)});async function Oe(){if(!(!H.value||de.value.length===0)){Ie.value=!0;try{await $fetch("/api/subscriptions",{method:"POST",body:{channelId:H.value,projectId:C.projectId,events:de.value,mode:"realtime"}}),await Q(),w.value=!1,z.add({title:"Subscribed",color:"success"}),p&&y?.scheduleFor(C.projectId,C.projectLabel||"this project",de.value)}catch(K){z.add({title:"Subscribe failed",description:String(K?.message??K),color:"error"})}finally{Ie.value=!1}}}async function gt(K){try{await $fetch(`/api/subscriptions/${K}`,{method:"DELETE"}),await Q(),z.add({title:"Unsubscribed",color:"success"}),p&&N.value.length===0&&y?.cancelFor(C.projectId)}catch(P){z.add({title:"Failed",description:String(P?.message??P),color:"error"})}}async function ne(K){const P=K.mutedUntil&&new Date(K.mutedUntil)>new Date;try{await $fetch(`/api/subscriptions/${K.id}`,{method:"PATCH",body:{mutedUntil:P?null:new Date(Date.now()+10080*60*1e3).toISOString()}}),await Q()}catch(Z){z.add({title:"Failed",description:String(Z?.message??Z),color:"error"})}}function pe(K){return K.mutedUntil&&new Date(K.mutedUntil)>new Date}function qe(K){return K==="personal_email"?"i-lucide-user-round":K==="email"?"i-lucide-mail":K==="slack"?"i-lucide-slack":"i-lucide-webhook"}const ft=B(()=>p||c.value&&R.value||x!=null),He=B(()=>p||c.value?ue.value:M.value);return(K,P)=>{const Z=ke,_t=Os,Te=Xe,Ye=Le,Ze=Be,Fe=ze,je=Qt,vt=Ps;return e(ft)?(n(),f(vt,{key:0,open:e(h),"onUpdate:open":P[6]||(P[6]=q=>J(h)?h.value=q:null),ui:{content:"w-72"}},{content:t(()=>[e(x)?(n(),r("div",Tn,[P[9]||(P[9]=s("div",{class:"flex items-center justify-between"},[s("span",{class:"font-medium text-sm"},"Browser notifications")],-1)),e(m)&&e(T)==="default"?(n(),r("p",jn,[a(Z,{variant:"link",size:"xs",class:"p-0",onClick:V},{default:t(()=>[...P[7]||(P[7]=[d(" Allow notifications ",-1)])]),_:1}),P[8]||(P[8]=d(" "+i(" ")+"in your browser to get alerts for this project. ",-1))])):e(m)&&e(T)==="denied"?(n(),r("p",Sn," Notifications are blocked. Check your browser settings to allow them. ")):e(m)?A("",!0):(n(),r("p",wn,"Notifications are not supported in this browser.")),e(m)&&e(T)==="granted"?(n(),r(X,{key:3},[a(_t),s("div",Rn,[(n(!0),r(X,null,ae(e(Ke),q=>(n(),r("label",{key:q.value,class:"flex items-center gap-1.5 text-xs cursor-pointer"},[s("input",{type:"checkbox",checked:j(q.value),class:"accent-primary size-3",onChange:le=>g(q.value)},null,40,Dn),d(" "+i(q.label),1)]))),128))])],64)):A("",!0)])):(n(),r("div",An,[s("div",zn,[s("span",Un,[P[10]||(P[10]=d(" Notifications ",-1)),a(Te,{topic:"notifications.subscribe"})]),e(w)?A("",!0):(n(),f(Z,{key:0,size:"xs",icon:"i-lucide-plus",variant:"ghost",color:"neutral",disabled:e(b).length===0,onClick:P[0]||(P[0]=q=>w.value=!0)},{default:t(()=>[...P[11]||(P[11]=[d(" Add ",-1)])]),_:1},8,["disabled"]))]),e(p)?(n(),r("div",In,[a(Ye,{name:"i-lucide-sparkles",class:"size-3 inline-block mr-1 text-primary"}),P[12]||(P[12]=d(" Demo — notifications will appear as toasts in ~8 s. ",-1))])):e(b).length===0?(n(),r("div",Mn,[P[14]||(P[14]=d(" No channels configured.",-1)),P[15]||(P[15]=s("br",null,null,-1)),a(Ze,{to:"/settings/notifications",class:"text-primary underline"},{default:t(()=>[...P[13]||(P[13]=[d("Add one in Settings",-1)])]),_:1})])):A("",!0),e(N).length>0?(n(),r("div",Fn,[(n(!0),r(X,null,ae(e(N),q=>(n(),r(X,{key:q.id},[e(me)?.id===q.id?(n(),r("div",Pn,[a(je,{label:"Channel",size:"xs"},{default:t(()=>[a(Fe,{modelValue:e(be),"onUpdate:modelValue":P[1]||(P[1]=le=>J(be)?be.value=le:null),items:e(We),"value-key":"value",class:"w-full text-xs",size:"xs"},null,8,["modelValue","items"])]),_:1}),a(je,{label:"Events",size:"xs"},{default:t(()=>[s("div",En,[(n(!0),r(X,null,ae(e(Ke),le=>(n(),r("label",{key:le.value,class:"flex items-center gap-1.5 text-xs cursor-pointer"},[Vt(s("input",{type:"checkbox",value:le.value,"onUpdate:modelValue":P[2]||(P[2]=Qe=>J(fe)?fe.value=Qe:null),class:"accent-primary size-3"},null,8,Ln),[[Nt,e(fe)]]),d(" "+i(le.label),1)]))),128))])]),_:1}),s("div",Bn,[a(Z,{size:"xs",color:"neutral",variant:"ghost",onClick:pt},{default:t(()=>[...P[16]||(P[16]=[d("Cancel",-1)])]),_:1}),a(Z,{size:"xs",color:"primary",loading:e(Me),disabled:!e(be)||e(fe).length===0,onClick:Y},{default:t(()=>[...P[17]||(P[17]=[d(" Save ",-1)])]),_:1},8,["loading","disabled"])])])):(n(),r("div",{key:1,class:ie(["flex items-center gap-2 rounded px-2 py-1.5 text-xs",pe(q)?"opacity-60":""])},[a(Ye,{name:qe(q.channel.type),class:"size-3.5 text-muted shrink-0"},null,8,["name"]),s("span",Vn,i(q.channel.name),1),a(Z,{icon:"i-lucide-pencil",color:"neutral",variant:"ghost",size:"xs",title:"Edit subscription",onClick:le=>mt(q)},null,8,["onClick"]),a(Z,{icon:pe(q)?"i-lucide-bell":"i-lucide-bell-off",color:"neutral",variant:"ghost",size:"xs",title:pe(q)?"Unmute":"Mute 7 days",onClick:le=>ne(q)},null,8,["icon","title","onClick"]),a(Z,{icon:"i-lucide-x",color:"error",variant:"ghost",size:"xs",title:"Unsubscribe",onClick:le=>gt(q.id)},null,8,["onClick"])],2))],64))),128))])):!e(w)&&e(b).length>0?(n(),r("div",Nn," Not subscribed to this project. ")):A("",!0),e(w)?(n(),r("div",Kn,[a(je,{label:"Channel",size:"xs"},{default:t(()=>[a(Fe,{modelValue:e(H),"onUpdate:modelValue":P[3]||(P[3]=q=>J(H)?H.value=q:null),items:e(We),"value-key":"value",class:"w-full text-xs",size:"xs"},null,8,["modelValue","items"])]),_:1}),a(je,{label:"Events",size:"xs"},{default:t(()=>[s("div",On,[(n(!0),r(X,null,ae(e(Ke),q=>(n(),r("label",{key:q.value,class:"flex items-center gap-1.5 text-xs cursor-pointer"},[Vt(s("input",{type:"checkbox",value:q.value,"onUpdate:modelValue":P[4]||(P[4]=le=>J(de)?de.value=le:null),class:"accent-primary size-3"},null,8,qn),[[Nt,e(de)]]),d(" "+i(q.label),1)]))),128))])]),_:1}),s("div",Hn,[a(Z,{size:"xs",color:"neutral",variant:"ghost",onClick:P[5]||(P[5]=q=>w.value=!1)},{default:t(()=>[...P[18]||(P[18]=[d("Cancel",-1)])]),_:1}),a(Z,{size:"xs",color:"primary",loading:e(Ie),disabled:!e(H)||e(de).length===0,onClick:Oe},{default:t(()=>[...P[19]||(P[19]=[d(" Subscribe ",-1)])]),_:1},8,["loading","disabled"])])])):A("",!0)]))]),default:t(()=>[a(Z,{icon:e(He)?"i-lucide-bell-ring":"i-lucide-bell",size:"sm",color:e(He)?"primary":"neutral",variant:e(He)?"soft":"outline",title:"Notification subscriptions for this project"},null,8,["icon","color","variant"])]),_:1},8,["open"])):A("",!0)}}}),Gn=Object.assign(Qn,{__name:"SubscribeBell"}),Xn={key:0,class:"flex items-center justify-between gap-3"},Jn={class:"flex items-center gap-2 min-w-0 text-sm"},Wn={class:"text-xs break-all"},Yn={class:"flex items-center gap-1.5 shrink-0"},Zn={key:1,class:"flex items-center justify-between gap-3"},ea=oe({__name:"DesktopProjectLinkCard",props:{projectId:{}},setup(U){const $=U,{available:k,link:C,busy:_,pickAndLink:p,unlink:c}=Js(()=>$.projectId);return(F,R)=>{const z=Le,h=Ce,y=ke,x=ut;return e(k)?(n(),f(x,{key:0,icon:"i-lucide-folder-symlink",title:"Local folder"},{subtitle:t(()=>[...R[0]||(R[0]=[d(" Link this project to its checkout on this machine to retry failures from here and open files in your IDE. ",-1)])]),default:t(()=>[e(C)?(n(),r("div",Xn,[s("div",Jn,[a(z,{name:e(C).exists?"i-lucide-folder-check":"i-lucide-folder-x",class:ie(["size-4 shrink-0",e(C).exists?"text-success":"text-warning"])},null,8,["name","class"]),s("code",Wn,i(e(C).path),1),e(C).exists?A("",!0):(n(),f(h,{key:0,color:"warning",variant:"subtle",size:"sm"},{default:t(()=>[...R[1]||(R[1]=[d("missing",-1)])]),_:1}))]),s("div",Yn,[a(y,{size:"xs",color:"neutral",variant:"soft",icon:"i-lucide-folder-search",loading:e(_),onClick:e(p)},{default:t(()=>[...R[2]||(R[2]=[d(" Change ",-1)])]),_:1},8,["loading","onClick"]),a(y,{size:"xs",color:"neutral",variant:"ghost",icon:"i-lucide-unlink",disabled:e(_),onClick:e(c)},{default:t(()=>[...R[3]||(R[3]=[d(" Unlink ",-1)])]),_:1},8,["disabled","onClick"])])])):(n(),r("div",Zn,[R[5]||(R[5]=s("p",{class:"text-sm text-muted"},"No folder linked yet.",-1)),a(y,{size:"xs",icon:"i-lucide-folder-plus",loading:e(_),onClick:e(p)},{default:t(()=>[...R[4]||(R[4]=[d("Choose folder…",-1)])]),_:1},8,["loading","onClick"])]))]),_:1})):A("",!0)}}}),ta=Object.assign(ea,{__name:"DesktopProjectLinkCard"}),sa={class:"w-full relative"},na={key:0},aa={class:"p-2 text-sm text-gray-900 dark:text-gray-100"},oa={class:"font-semibold mb-1"},la={class:"capitalize mb-1"},ra={class:"space-y-0.5"},ia={class:"font-medium mt-1"},ca=oe({__name:"TestRunsChart",props:{testRuns:{},height:{default:300},markers:{default:()=>[]}},emits:["marker-click"],setup(U,{emit:$}){const k=U,C=$,_=B(()=>k.markers),p=B(()=>!k.testRuns||k.testRuns.length===0?[]:[...k.testRuns].sort((S,O)=>new Date(S.startTime).getTime()-new Date(O.startTime).getTime()).slice(-30).map(S=>({id:S.id,date:new Date(S.startTime),passed:S.passedTests||0,failed:S.failedTests||0,skipped:S.skippedTests||0,flaky:S.flakyTests||0,total:S.totalTests||0,status:S.status}))),c=g=>g.date,F=g=>g.passed,R=g=>g.failed,z=g=>g.skipped,h=g=>g.flaky,y=["rgb(34, 197, 94)","rgb(239, 68, 68)","rgb(245, 158, 11)","rgb(147, 51, 234)"],x=I(null),{tooltipData:T,tooltipPos:m,markerTooltip:v,markerTooltipPos:M,onRenderComplete:V}=Zt(x,p,{x:g=>g.date,series:[{y:g=>g.passed,color:y[0]},{y:g=>g.failed,color:y[1]},{y:g=>g.skipped,color:y[2]},{y:g=>g.flaky,color:y[3]}],onClick:g=>Rt(`/test-runs/${g.id}`),markers:_,onMarkerClick:g=>C("marker-click",g.id)}),j=[{color:y[0],label:"Passed"},{color:y[1],label:"Failed"},{color:y[2],label:"Skipped"},{color:y[3],label:"Flaky"}];return(g,S)=>{const O=Xt,D=$e,Q=Yt;return n(),r("div",sa,[e(p).length>0?(n(),r("div",na,[a(e(Wt),{ref_key:"xyContainerRef",ref:x,data:e(p),height:U.height,padding:{top:10,right:10,bottom:0,left:0},"on-render-complete":e(V)},{default:t(()=>[a(e(Ws),{x:c,y:[F,R,z,h],color:y,"curve-type":e(St).MonotoneX},null,8,["y","curve-type"]),a(e(Jt),{x:c,y:[F,R,z,h],color:y,"curve-type":e(St).MonotoneX,"line-width":2},null,8,["y","curve-type"]),a(e(it),{type:"x","tick-format":N=>new Date(N).toLocaleDateString("en-US",{month:"short",day:"numeric"})},null,8,["tick-format"]),a(e(it),{type:"y",label:"Tests","tick-format":N=>N.toString()},null,8,["tick-format"])]),_:1},8,["data","height","on-render-complete"]),e(T)?(n(),r("div",{key:0,class:"fixed z-50 pointer-events-none bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 max-w-[260px]",style:qt({left:`${e(m).x}px`,top:`${e(m).y}px`})},[s("div",aa,[s("div",oa,i(new Date(e(T).date).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})),1),s("div",la,"Status: "+i(e(T).status),1),s("div",ra,[s("div",null,[S[0]||(S[0]=s("span",{class:"text-green-500 dark:text-green-400"},"●",-1)),d(" Passed: "+i(e(T).passed),1)]),s("div",null,[S[1]||(S[1]=s("span",{class:"text-red-500 dark:text-red-400"},"●",-1)),d(" Failed: "+i(e(T).failed),1)]),s("div",null,[S[2]||(S[2]=s("span",{class:"text-orange-500 dark:text-orange-400"},"●",-1)),d(" Skipped: "+i(e(T).skipped),1)]),s("div",null,[S[3]||(S[3]=s("span",{class:"text-purple-500 dark:text-purple-400"},"●",-1)),d(" Flaky: "+i(e(T).flaky),1)]),s("div",ia,"Total: "+i(e(T).total),1)]),S[4]||(S[4]=s("div",{class:"text-gray-400 dark:text-gray-500 text-xs mt-1"},"Click to view run details",-1))])],4)):A("",!0),a(O,{marker:e(v),pos:e(M)},null,8,["marker","pos"])])):(n(),f(D,{key:1,text:"No test run data available to display chart"})),a(Q,{items:j})])}}}),ua=Object.assign(ca,{__name:"TestRunsChart"}),da={class:"space-y-3"},ma={class:"min-w-0 space-y-1"},pa={class:"flex items-center gap-2 flex-wrap text-sm"},ga={key:0,class:"text-gray-500"},fa=["title"],_a=["title"],va={key:0,class:"text-xs text-gray-500 italic"},ya={class:"flex items-center gap-2 shrink-0"},ha=oe({__name:"ClusterMergeSuggestions",props:{projectId:{}},emits:["merged"],setup(U,{emit:$}){const k=U,C=$,_=Ae(),p=I([]),c=I(null);async function F(){try{p.value=await $fetch(`/api/projects/${k.projectId}/cluster-merge-suggestions`)}catch{p.value=[]}}ye(()=>k.projectId,F,{immediate:!0});async function R(h,y){c.value=h;try{await $fetch(`/api/cluster-merge-suggestions/${h}/${y}`,{method:"POST"}),_.add({title:y==="approve"?"Clusters merged":"Suggestion dismissed",color:"success"}),await F(),y==="approve"&&C("merged")}catch(x){_.add({title:"Action failed",description:String(x?.message??x),color:"error"})}finally{c.value=null}}const z=h=>h==null?"":`${Math.round(h*100)}% similar`;return(h,y)=>{const x=Ce,T=ke,m=ut;return e(p).length?(n(),f(m,{key:0,icon:"i-lucide-git-merge",title:"Suggested merges",count:e(p).length,class:"mb-4"},{subtitle:t(()=>[...y[0]||(y[0]=[d(" Likely-duplicate clusters found by semantic analysis. Approving merges them into the older cluster. ",-1)])]),default:t(()=>[s("div",da,[(n(!0),r(X,null,ae(e(p),v=>(n(),r("div",{key:v.id,class:"rounded-lg border border-default p-3 flex items-start justify-between gap-4"},[s("div",ma,[s("div",pa,[a(x,{color:v.method==="llm"?"primary":"neutral",variant:"subtle",size:"sm"},{default:t(()=>[d(i(v.method==="llm"?`AI · ${v.llmConfidence??""}`:"similarity"),1)]),_:2},1032,["color"]),z(v.score)?(n(),r("span",ga,i(z(v.score)),1)):A("",!0)]),s("p",{class:"text-sm truncate",title:v.clusterA?.signature||""},[y[1]||(y[1]=s("span",{class:"text-gray-400"},"A:",-1)),d(" "+i(v.clusterA?.signature||`#${v.id}`),1)],8,fa),s("p",{class:"text-sm truncate",title:v.clusterB?.signature||""},[y[2]||(y[2]=s("span",{class:"text-gray-400"},"B:",-1)),d(" "+i(v.clusterB?.signature||""),1)],8,_a),v.llmReason?(n(),r("p",va,i(v.llmReason),1)):A("",!0)]),s("div",ya,[a(T,{size:"sm",color:"primary",icon:"i-lucide-git-merge",loading:e(c)===v.id,onClick:M=>R(v.id,"approve")},{default:t(()=>[...y[3]||(y[3]=[d(" Merge ",-1)])]),_:1},8,["loading","onClick"]),a(T,{size:"sm",color:"neutral",variant:"ghost",icon:"i-lucide-x",disabled:e(c)===v.id,onClick:M=>R(v.id,"reject")},{default:t(()=>[...y[4]||(y[4]=[d(" Dismiss ",-1)])]),_:1},8,["disabled","onClick"])])]))),128))])]),_:1},8,["count"])):A("",!0)}}}),xa=Object.assign(ha,{__name:"ClusterMergeSuggestions"}),ba={class:"flex items-center justify-between"},ka={class:"text-sm text-gray-500 inline-flex items-center gap-1"},$a={class:"min-w-0 space-y-0.5"},Ca={key:0,class:"text-xs text-gray-500 italic truncate"},Ta={key:1,class:"text-gray-400 text-xs"},ja={class:"space-y-1"},Sa={class:"text-sm tabular-nums"},wa={class:"text-sm tabular-nums"},Ra={key:1,class:"text-gray-400 text-xs"},Da={class:"text-sm text-gray-500 whitespace-nowrap"},Aa={key:0,class:"ml-1 text-xs text-gray-400"},za={class:"flex justify-end"},Ua=oe({__name:"FailureClustersList",props:{projectId:{}},async setup(U){let $,k;const C=U,_=I(void 0),{data:p,pending:c}=([$,k]=he(()=>xe(()=>{const z=new URLSearchParams;_.value&&z.set("status",_.value);const h=z.toString();return`/api/projects/${C.projectId}/failure-clusters${h?`?${h}`:""}`},{lazy:!0,server:!1,watch:[_]},"$fqv4nq7Mtw")),$=await $,k(),$),F=z=>rn(z.fixVerification),R=[{accessorKey:"signature",header:E("Signature")},{accessorKey:"errorType",header:E("Type")},{accessorKey:"status",header:E("Status")},{accessorKey:"affectedTests",header:E("Tests")},{accessorKey:"occurrences",header:E("Occurrences")},{accessorKey:"diagnosis",header:"AI"},{accessorKey:"lastSeenAt",header:E("Last seen")},{id:"actions",header:"Actions"}];return(z,h)=>{const y=Xe,x=ze,T=Be,m=Ce,v=Le,M=es,V=ke,j=Ue,g=Ne,S=$e,O=Ve;return n(),f(O,null,{header:t(()=>[s("div",ba,[s("p",ka,[h[1]||(h[1]=d(" Ongoing failure signatures grouped by normalized error. ",-1)),a(y,{topic:"cluster.concept"})]),a(x,{modelValue:e(_),"onUpdate:modelValue":h[0]||(h[0]=D=>J(_)?_.value=D:null),items:[{label:"All",value:void 0},{label:"Open",value:"open"},{label:"Resolved",value:"resolved"},{label:"Ignored",value:"ignored"}],size:"xs",class:"w-32"},null,8,["modelValue"])])]),default:t(()=>[a(g,{"min-width":"48rem",bleed:!1},{default:t(()=>[a(j,{data:e(p)??[],columns:R,loading:e(c)},{"actions-header":t(()=>[...h[2]||(h[2]=[s("div",{class:"text-right"},"Actions",-1)])]),"signature-cell":t(({row:D})=>[s("div",$a,[a(T,{to:`/failure-clusters/${D.original.id}`,class:ie(["text-sm text-primary hover:underline truncate block",D.original.title?"":"font-mono"]),title:D.original.signature},{default:t(()=>[d(i(D.original.title||D.original.signature),1)]),_:2},1032,["to","class","title"]),D.original.triageNote?(n(),r("p",Ca,i(D.original.triageNote),1)):A("",!0)])]),"errorType-cell":t(({row:D})=>[D.original.errorType?(n(),f(m,{key:0,color:("clusterErrorTypeColor"in z?z.clusterErrorTypeColor:e(ln))(D.original.errorType),variant:"subtle",size:"sm"},{default:t(()=>[d(i(D.original.errorType),1)]),_:2},1032,["color"])):(n(),r("span",Ta,"—"))]),"status-cell":t(({row:D})=>[s("div",ja,[a(m,{color:("clusterStatusColor"in z?z.clusterStatusColor:e(on))(D.original.status),variant:"subtle",size:"sm"},{default:t(()=>[d(i(D.original.status),1)]),_:2},1032,["color"]),F(D.original)?(n(),f(M,{key:0,text:F(D.original).hint},{default:t(()=>[a(m,{color:F(D.original).color,variant:"subtle",size:"sm",class:"gap-1"},{default:t(()=>[a(v,{name:F(D.original).icon,class:"size-3"},null,8,["name"]),d(" "+i(F(D.original).label),1)]),_:2},1032,["color"])]),_:2},1032,["text"])):A("",!0)])]),"affectedTests-cell":t(({row:D})=>[s("span",Sa,i(D.original.affectedTests),1)]),"occurrences-cell":t(({row:D})=>[s("span",wa,i(D.original.occurrences),1)]),"diagnosis-cell":t(({row:D})=>[D.original.diagnosis?.status==="completed"&&D.original.diagnosis.category?(n(),f(m,{key:0,color:"neutral",variant:"subtle",size:"sm",class:"gap-1"},{default:t(()=>[a(v,{name:"i-lucide-sparkles",class:"size-3"}),d(" "+i(D.original.diagnosis.category),1)]),_:2},1024)):(n(),r("span",Ra,"—"))]),"lastSeenAt-cell":t(({row:D})=>[s("div",Da,[a(T,{to:`/test-runs/${D.original.lastSeenRunId}`,class:"text-primary hover:underline"},{default:t(()=>[d(" run #"+i(D.original.lastSeenRunId),1)]),_:2},1032,["to"]),D.original.lastSeenAt?(n(),r("span",Aa," ("+i(("formatRelativeTime"in z?z.formatRelativeTime:e(At))(D.original.lastSeenAt))+") ",1)):A("",!0)])]),"actions-cell":t(({row:D})=>[s("div",za,[a(V,{to:`/failure-clusters/${D.original.id}`,size:"sm",variant:"outline","trailing-icon":"i-lucide-arrow-right"},{default:t(()=>[...h[3]||(h[3]=[d(" View ",-1)])]),_:1},8,["to"])])]),_:1},8,["data","loading"])]),_:1}),!e(c)&&e(p)&&e(p).length===0?(n(),f(S,{key:0,text:"No failure clusters recorded for this project.",padded:!1,class:"py-4"})):A("",!0)]),_:1})}}}),Ia=Object.assign(Ua,{__name:"FailureClustersList"}),Ma={class:"flex items-center justify-between"},Fa={class:"flex items-center gap-3"},Pa={class:"text-sm text-gray-500 inline-flex items-center gap-1"},Ea={class:"flex items-center gap-1.5"},La={class:"min-w-0 space-y-0.5"},Ba={class:"flex items-center gap-2"},Va={class:"text-sm tabular-nums"},Na={class:"text-sm tabular-nums"},Ka={key:1,class:"text-gray-400 text-xs"},Oa={key:1,class:"text-gray-400 text-xs"},qa={key:1,class:"text-gray-400 text-xs"},Ha={key:0,class:"text-sm text-gray-500"},Qa={key:1,class:"text-gray-400 text-xs"},Ga={class:"flex justify-end"},Xa={key:0,class:"text-sm text-gray-500 py-4 text-center"},Ja=oe({__name:"FlakyTestsList",props:{projectId:{},environment:{},projectName:{}},async setup(U){let $,k;const C=U,_=I(50),p=I([]),{data:c,pending:F}=([$,k]=he(()=>xe(()=>{const m=new URLSearchParams({runs:String(_.value)});return C.environment&&m.set("environment",C.environment),`/api/projects/${C.projectId}/flaky-tests?${m.toString()}`},{lazy:!0,server:!1,watch:[_,()=>C.environment]},"$BbmtLKIPAB")),$=await $,k(),$),R=B(()=>p.value.length===0?c.value??[]:(c.value??[]).filter(m=>p.value.includes(m.rootCause??"")));function z(m){return m>=60?"error":m>=30?"warning":"neutral"}function h(m){switch(m){case"timing":return"amber";case"network":return"red";case"assertion":return"blue";case"environment":return"purple";default:return"gray"}}function y(m){p.value.indexOf(m)>=0?p.value=p.value.filter(M=>M!==m):p.value=[...p.value,m]}const x=[{label:"Timing",value:"timing"},{label:"Network",value:"network"},{label:"Assertion",value:"assertion"},{label:"Environment",value:"environment"},{label:"Other",value:"other"}],T=[{accessorKey:"title",header:E("Test")},{accessorKey:"impact",header:E("Impact")},{accessorKey:"score",header:E("Score")},{accessorKey:"failureRate",header:E("Failure rate")},{accessorKey:"retryPassRuns",header:E("Retry passes")},{accessorKey:"alternations",header:E("Flips")},{accessorKey:"rootCause",header:"Root cause"},{accessorKey:"lastFlakeAt",header:E("Last flake")},{id:"actions",header:"Actions"}];return(m,v)=>{const M=Xe,V=Le,j=Ce,g=ke,S=ze,O=Be,D=ss,Q=dt,N=Gt,ue=Ue,ge=Ne,b=Ve;return n(),f(b,null,{header:t(()=>[s("div",Ma,[s("div",Fa,[s("p",Pa,[v[1]||(v[1]=d(" Tests that fail intermittently — detected by retry passes and status alternations ",-1)),a(M,{topic:"project.flaky-tests"})]),U.environment?(n(),f(j,{key:0,color:"neutral",variant:"subtle",size:"sm",class:"gap-1"},{default:t(()=>[a(V,{name:"i-lucide-layers",class:"size-3"}),d(" "+i(U.environment),1)]),_:1})):A("",!0),s("div",Ea,[(n(),r(X,null,ae(x,w=>a(g,{key:w.value,size:"xs",variant:e(p).includes(w.value)?"solid":"outline",color:(e(p).includes(w.value),"neutral"),onClick:H=>y(w.value)},{default:t(()=>[d(i(w.label),1)]),_:2},1032,["variant","color","onClick"])),64))])]),a(S,{modelValue:e(_),"onUpdate:modelValue":v[0]||(v[0]=w=>J(_)?_.value=w:null),items:[{label:"Last 20 runs",value:20},{label:"Last 50 runs",value:50},{label:"Last 100 runs",value:100}],size:"xs",class:"w-36"},null,8,["modelValue"])])]),default:t(()=>[a(ge,{"min-width":"52rem",bleed:!1},{default:t(()=>[a(ue,{data:e(R),columns:T,loading:e(F),sticky:"",class:"max-h-[32rem]"},{"actions-header":t(()=>[...v[2]||(v[2]=[s("div",{class:"text-right"},"Actions",-1)])]),"title-cell":t(({row:w})=>[s("div",La,[a(O,{to:`/test-run-cases/${w.original.latestRunsCaseId}`,class:"text-sm font-medium text-primary hover:underline truncate block",title:w.original.title},{default:t(()=>[d(i(w.original.title),1)]),_:2},1032,["to","title"]),a(D,{tags:w.original.tags,meta:{owner:w.original.owner??void 0,priority:("toTestPriority"in m?m.toTestPriority:e(cn))(w.original.priority)},"max-tags":3},null,8,["tags","meta"]),a(Q,{"file-path":w.original.filePath,"project-key":U.projectId,"project-name":U.projectName,class:"text-xs text-gray-400"},null,8,["file-path","project-key","project-name"])])]),"impact-cell":t(({row:w})=>[s("div",Ba,[s("span",{class:ie(["inline-block w-2 h-2 rounded-full shrink-0",{"bg-red-500":w.original.wastedCiMinutes>=30,"bg-amber-500":w.original.wastedCiMinutes>=5&&w.original.wastedCiMinutes<30,"bg-green-500":w.original.wastedCiMinutes>=0&&w.original.wastedCiMinutes<5}])},null,2),s("span",Va,i(Math.round(w.original.wastedCiMinutes))+" min wasted",1)])]),"score-cell":t(({row:w})=>[a(j,{color:z(w.original.score),variant:"subtle",size:"sm"},{default:t(()=>[d(i(w.original.score),1)]),_:2},1032,["color"])]),"failureRate-cell":t(({row:w})=>[s("span",Na,i(Math.round(w.original.failureRate*100))+"%",1)]),"retryPassRuns-cell":t(({row:w})=>[w.original.retryPassRuns?(n(),f(j,{key:0,color:"warning",variant:"outline",size:"sm"},{default:t(()=>[d(i(w.original.retryPassRuns)+" run"+i(w.original.retryPassRuns===1?"":"s"),1)]),_:2},1024)):(n(),r("span",Ka,"—"))]),"alternations-cell":t(({row:w})=>[w.original.alternations>=2?(n(),f(j,{key:0,color:"neutral",variant:"outline",size:"sm"},{default:t(()=>[d(i(w.original.alternations),1)]),_:2},1024)):(n(),r("span",Oa,"—"))]),"rootCause-cell":t(({row:w})=>[w.original.rootCause?(n(),f(N,{key:0,text:w.original.rootCause,color:h(w.original.rootCause)},null,8,["text","color"])):(n(),r("span",qa,"—"))]),"lastFlakeAt-cell":t(({row:w})=>[w.original.lastFlakeAt?(n(),r("span",Ha,i(("formatRelativeTime"in m?m.formatRelativeTime:e(At))(w.original.lastFlakeAt)),1)):(n(),r("span",Qa,"—"))]),"actions-cell":t(({row:w})=>[s("div",Ga,[a(g,{to:`/test-run-cases/${w.original.latestRunsCaseId}`,size:"sm",variant:"outline","trailing-icon":"i-lucide-arrow-right"},{default:t(()=>[...v[3]||(v[3]=[d(" View ",-1)])]),_:1},8,["to"])])]),_:1},8,["data","loading"])]),_:1}),!e(F)&&e(R).length===0?(n(),r("p",Xa," No flaky tests detected in the last "+i(e(_))+" runs. ",1)):A("",!0)]),_:1})}}}),Wa=Object.assign(Ja,{__name:"FlakyTestsList"}),Ya={class:"w-full relative"},Za={key:0},eo={class:"p-2 text-sm text-gray-900 dark:text-gray-100"},to={class:"font-semibold mb-1"},so={class:"capitalize mb-1"},no={class:"space-y-0.5"},ao={class:"mt-1"},oo={key:0,class:"text-gray-400 dark:text-gray-500 text-xs"},lo=oe({__name:"PerformanceTrendChart",props:{data:{},height:{default:300},markers:{default:()=>[]}},emits:["marker-click"],setup(U,{emit:$}){const k=U,C=$,_=B(()=>k.markers),p=B(()=>!k.data||k.data.length===0?[]:k.data.map(j=>({id:j.id,date:new Date(j.startTime),duration:j.duration?Math.round(j.duration/1e3):null,avgTestDuration:j.avgTestDuration?Math.round(j.avgTestDuration/1e3):null,p90TestDuration:j.p90TestDuration?Math.round(j.p90TestDuration/1e3):null,commit:j.commit?j.commit.substring(0,7):null,status:j.status,totalTests:j.totalTests}))),c=j=>j.date,F=j=>j.duration??void 0,R=j=>j.avgTestDuration??void 0,z=j=>j.p90TestDuration??void 0,h=["rgb(59, 130, 246)","rgb(34, 197, 94)","rgb(249, 115, 22)"],y=I(null),{tooltipData:x,tooltipPos:T,markerTooltip:m,markerTooltipPos:v,onRenderComplete:M}=Zt(y,p,{x:j=>j.date,series:[{y:j=>j.duration,color:h[0]},{y:j=>j.avgTestDuration,color:h[1]},{y:j=>j.p90TestDuration,color:h[2]}],onClick:j=>Rt(`/test-runs/${j.id}`),markers:_,onMarkerClick:j=>C("marker-click",j.id)}),V=[{color:h[0],label:"Total Duration"},{color:h[1],label:"Avg Test Duration"},{color:h[2],label:"P90 Test Duration"}];return(j,g)=>{const S=Xt,O=$e,D=Yt;return n(),r("div",Ya,[e(p).length>0?(n(),r("div",Za,[a(e(Wt),{ref_key:"xyContainerRef",ref:y,data:e(p),height:U.height,padding:{top:10,right:10,bottom:0,left:0},"on-render-complete":e(M)},{default:t(()=>[a(e(Jt),{x:c,y:[F,R,z],color:h,"curve-type":e(St).MonotoneX,"line-width":2},null,8,["y","curve-type"]),a(e(it),{type:"x","tick-format":Q=>new Date(Q).toLocaleDateString("en-US",{month:"short",day:"numeric"}),label:"Date"},null,8,["tick-format"]),a(e(it),{type:"y",label:"Duration (s)","tick-format":Q=>`${Q}s`},null,8,["tick-format"])]),_:1},8,["data","height","on-render-complete"]),e(x)?(n(),r("div",{key:0,class:"fixed z-50 pointer-events-none bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 max-w-[260px]",style:qt({left:`${e(T).x}px`,top:`${e(T).y}px`})},[s("div",eo,[s("div",to,i(new Date(e(x).date).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})),1),s("div",so,"Status: "+i(e(x).status),1),s("div",no,[s("div",null,[g[0]||(g[0]=s("span",{class:"text-blue-500 dark:text-blue-400"},"●",-1)),d(" Total: "+i(e(x).duration??"-")+"s ",1)]),s("div",null,[g[1]||(g[1]=s("span",{class:"text-green-500 dark:text-green-400"},"●",-1)),d(" Avg: "+i(e(x).avgTestDuration??"-")+"s ",1)]),s("div",null,[g[2]||(g[2]=s("span",{class:"text-orange-500 dark:text-orange-400"},"●",-1)),d(" P90: "+i(e(x).p90TestDuration??"-")+"s ",1)]),s("div",ao,"Tests: "+i(e(x).totalTests),1),e(x).commit?(n(),r("div",oo," Commit: "+i(e(x).commit),1)):A("",!0)]),g[3]||(g[3]=s("div",{class:"text-gray-400 dark:text-gray-500 text-xs mt-1"},"Click to view run details",-1))])],4)):A("",!0),a(S,{marker:e(m),pos:e(v)},null,8,["marker","pos"])])):(n(),f(O,{key:1,text:"No performance data available to display chart"})),a(D,{items:V})])}}}),ro=Object.assign(lo,{__name:"PerformanceTrendChart"}),io={class:"min-w-0"},co={class:"mt-1"},uo={class:"tabular-nums"},mo={key:0,class:"ml-1 text-xs text-gray-500",title:"timeout ÷ p95"},po={class:"tabular-nums text-gray-500"},go={key:0,class:"text-sm"},fo={key:1,class:"tabular-nums"},_o={class:"tabular-nums font-medium text-green-600 dark:text-green-400"},vo={class:"tabular-nums text-gray-500"},yo=oe({__name:"TimeoutOpportunitiesTable",props:{projectId:{},projectName:{}},async setup(U){let $,k;const C=U,{data:_,pending:p}=([$,k]=he(()=>xe(()=>`/api/projects/${C.projectId}/timeout-opportunities`,{lazy:!0,server:!1},"$zikJNhkkxJ")),$=await $,k(),$),c=B(()=>_.value??[]);function F(z){return z==null?"—":z<1e3?`${z}ms`:`${(z/1e3).toFixed(1)}s`}const R=[{accessorKey:"title",header:E("Test case")},{accessorKey:"kind",header:"Type"},{accessorKey:"timeout",header:E("Timeout")},{accessorKey:"p95",header:E("p95")},{accessorKey:"recommendedTimeout",header:"Recommendation"},{accessorKey:"estimatedSavingMs",header:E("Est. saving / failure")},{accessorKey:"runCount",header:E("Runs")}];return(z,h)=>{const y=Je,x=$e,T=Be,m=dt,v=Ce,M=Ue,V=Ne,j=Ve;return n(),f(j,null,{header:t(()=>[...h[0]||(h[0]=[s("h2",{class:"text-xl font-semibold"},"Timeout opportunities",-1),s("p",{class:"text-sm text-gray-600 mt-1"},[d(" Tests whose configured timeout far exceeds their real duration, or that still carry a stale "),s("code",{class:"text-xs"},"test.slow()"),d(" mark — tightening these makes failures surface sooner. ")],-1)])]),default:t(()=>[e(p)?(n(),f(y,{key:0})):e(c).length===0?(n(),f(x,{key:1,text:"No timeout opportunities",description:"No oversized timeouts or stale test.slow() marks were found for this project."})):(n(),f(V,{key:2,"min-width":"52rem",bleed:!1},{default:t(()=>[a(M,{data:e(c),columns:R,sticky:"",class:"max-h-[32rem]"},{"title-cell":t(({row:g})=>[s("div",io,[a(T,{to:`/test-cases/${g.original.testCaseId}`,class:"font-medium truncate block hover:text-primary hover:underline"},{default:t(()=>[d(i(g.original.title),1)]),_:2},1032,["to"]),s("div",co,[a(m,{"file-path":g.original.filePath,"project-key":U.projectId,"project-name":U.projectName,class:"text-xs"},null,8,["file-path","project-key","project-name"])])])]),"kind-cell":t(({row:g})=>[a(v,{color:g.original.kind==="oversized-timeout"?"warning":"info",variant:"subtle",size:"sm"},{default:t(()=>[d(i(g.original.kind==="oversized-timeout"?"Oversized timeout":"Stale test.slow()"),1)]),_:2},1032,["color"])]),"timeout-cell":t(({row:g})=>[s("span",uo,i(F(g.original.timeout)),1),g.original.headroomRatio!=null?(n(),r("span",mo," ("+i(g.original.headroomRatio)+"×) ",1)):A("",!0)]),"p95-cell":t(({row:g})=>[s("span",po,i(F(g.original.p95)),1)]),"recommendedTimeout-cell":t(({row:g})=>[g.original.kind==="stale-slow"?(n(),r("span",go,[...h[1]||(h[1]=[d("Remove ",-1),s("code",{class:"text-xs"},"test.slow()",-1)])])):(n(),r("span",fo,"Lower to ~"+i(F(g.original.recommendedTimeout)),1))]),"estimatedSavingMs-cell":t(({row:g})=>[s("span",_o,i(F(g.original.estimatedSavingMs)),1)]),"runCount-cell":t(({row:g})=>[s("span",vo,i(g.original.runCount),1)]),_:1},8,["data"])]),_:1}))]),_:1})}}}),ho=Object.assign(yo,{__name:"TimeoutOpportunitiesTable"}),xo={class:"flex items-center justify-between"},bo={class:"text-sm text-gray-500 inline-flex items-center gap-1"},ko={class:"truncate font-mono text-xs"},$o={class:"tabular-nums"},Co={class:"tabular-nums text-gray-500"},To={class:"tabular-nums text-gray-500"},jo=oe({__name:"SpecHealthTable",props:{projectId:{}},async setup(U){let $,k;const C=U,_=I(30),{data:p,pending:c}=([$,k]=he(()=>xe(()=>`/api/projects/${C.projectId}/spec-health?days=${_.value}`,{lazy:!0,server:!1,watch:[_]},"$SX5aqvhtuX")),$=await $,k(),$),F=B(()=>p.value?.specs??[]);function R(m){return m>=.9?"bg-green-500":m>=.7?"bg-amber-500":m>0?"bg-red-500":"bg-gray-300 dark:bg-gray-600"}function z(m){return m>=.9?"text-green-600 dark:text-green-400":m>=.7?"text-amber-600 dark:text-amber-400":m>0?"text-red-600 dark:text-red-400":"text-gray-500"}function h(m){return`${Math.round(m*100)}%`}function y(m){return m<1e3?`${m}ms`:`${(m/1e3).toFixed(1)}s`}const x=[{label:"Last 7 days",value:7},{label:"Last 30 days",value:30},{label:"Last 90 days",value:90}],T=[{accessorKey:"prefix",header:E("Spec prefix")},{accessorKey:"passRate",header:E("Pass rate")},{accessorKey:"flakyRate",header:E("Flaky")},{accessorKey:"failureCount",header:E("Failures")},{accessorKey:"testCount",header:E("Tests")},{accessorKey:"avgDuration",header:E("Avg time")}];return(m,v)=>{const M=Xe,V=ze,j=Je,g=$e,S=Be,O=Ue,D=Ne,Q=Ve;return n(),f(Q,null,{header:t(()=>[s("div",xo,[s("p",bo,[v[1]||(v[1]=d(" Spec-file health overview — pass rate, flaky rate, and failure count per spec prefix ",-1)),a(M,{topic:"project.spec-health"})]),a(V,{modelValue:e(_),"onUpdate:modelValue":v[0]||(v[0]=N=>J(_)?_.value=N:null),items:x,size:"xs",class:"w-32"},null,8,["modelValue"])])]),default:t(()=>[e(c)?(n(),f(j,{key:0})):e(F).length===0?(n(),f(g,{key:1,text:"No data",description:"No spec health data available for the selected period."})):(n(),f(D,{key:2,"min-width":"46rem",bleed:!1},{default:t(()=>[a(O,{data:e(F),columns:T,sticky:"",class:"max-h-[32rem]"},{"prefix-cell":t(({row:N})=>[a(S,{to:`/projects/${U.projectId}/test-cases?file=${encodeURIComponent(N.original.prefix)}`,class:"flex items-center gap-2 min-w-0 text-primary hover:underline",title:N.original.prefix},{default:t(()=>[s("span",{class:ie(["inline-block size-3 rounded shrink-0",R(N.original.passRate)])},null,2),s("span",ko,i(N.original.prefix),1)]),_:2},1032,["to","title"])]),"passRate-cell":t(({row:N})=>[s("span",{class:ie(["font-medium tabular-nums",z(N.original.passRate)])},i(h(N.original.passRate)),3)]),"flakyRate-cell":t(({row:N})=>[s("span",$o,i(Math.round(N.original.flakyRate*100))+"%",1)]),"failureCount-cell":t(({row:N})=>[s("span",{class:ie(["tabular-nums",N.original.failureCount>0?"text-red-600 dark:text-red-400":""])},i(N.original.failureCount),3)]),"testCount-cell":t(({row:N})=>[s("span",Co,i(N.original.testCount),1)]),"avgDuration-cell":t(({row:N})=>[s("span",To,i(y(N.original.avgDuration)),1)]),_:1},8,["data"])]),_:1}))]),_:1})}}}),So=Object.assign(jo,{__name:"SpecHealthTable"}),wo={class:"flex items-center justify-between"},Ro={key:2},Do={class:"grid grid-cols-3 gap-3 mb-4"},Ao={class:"rounded-lg border border-gray-200 dark:border-gray-800 p-3"},zo={class:"text-2xl font-semibold tabular-nums"},Uo={class:"rounded-lg border border-gray-200 dark:border-gray-800 p-3"},Io={class:"text-2xl font-semibold tabular-nums"},Mo={class:"rounded-lg border border-gray-200 dark:border-gray-800 p-3"},Fo={class:"text-2xl font-semibold tabular-nums"},Po=["title"],Eo={class:"tabular-nums"},Lo={class:"tabular-nums text-gray-500"},Bo=["title"],Vo=oe({__name:"AiStepCoverage",props:{projectId:{}},async setup(U){let $,k;const C=U,_=I(30),{data:p,pending:c}=([$,k]=he(()=>xe(()=>`/api/projects/${C.projectId}/ai-steps?days=${_.value}`,{lazy:!0,server:!1,watch:[_]},"$XNuZ38B1nb")),$=await $,k(),$),F=B(()=>p.value?.artifacts??[]),R=B(()=>p.value?.summary??{artifactCount:0,testCount:0,runCount:0,replayCount:0});function z(T){const m=T.split(/[\\/]/);return m[m.length-1]||T}function h(T){if(!T)return"—";const m=new Date(T).getTime();if(!Number.isFinite(m))return"—";const v=Math.max(0,Math.round((Date.now()-m)/1e3));if(v<60)return"just now";const M=Math.round(v/60);if(M<60)return`${M}m ago`;const V=Math.round(M/60);return V<24?`${V}h ago`:`${Math.round(V/24)}d ago`}const y=[{label:"Last 7 days",value:7},{label:"Last 30 days",value:30},{label:"Last 90 days",value:90}],x=[{accessorKey:"entry",header:E("Artifact")},{accessorKey:"testCount",header:E("Tests")},{accessorKey:"replayCount",header:E("Replays")},{accessorKey:"lastSeen",header:E("Last seen")}];return(T,m)=>{const v=ze,M=Je,V=$e,j=Ue,g=Ne,S=Ve;return n(),f(S,null,{header:t(()=>[s("div",wo,[m[1]||(m[1]=s("p",{class:"text-sm text-gray-500"},[d(" AI-step liveness — which committed "),s("code",{class:"text-xs"},"piwiLocator"),d(" / "),s("code",{class:"text-xs"},"piwiRun"),d(" artifacts were replayed, and when they were last seen ")],-1)),a(v,{modelValue:e(_),"onUpdate:modelValue":m[0]||(m[0]=O=>J(_)?_.value=O:null),items:y,size:"xs",class:"w-32"},null,8,["modelValue"])])]),default:t(()=>[e(c)?(n(),f(M,{key:0})):e(F).length===0?(n(),f(V,{key:1,text:"No AI steps",description:"No committed AI-step artifacts were replayed in the selected period. Author them with page.piwiLocator / page.piwiRun in resolve mode."})):(n(),r("div",Ro,[s("div",Do,[s("div",Ao,[s("div",zo,i(e(R).artifactCount),1),m[2]||(m[2]=s("div",{class:"text-xs text-gray-500"},"Artifacts replayed",-1))]),s("div",Uo,[s("div",Io,i(e(R).testCount),1),m[3]||(m[3]=s("div",{class:"text-xs text-gray-500"},"Tests using AI steps",-1))]),s("div",Mo,[s("div",Fo,i(e(R).replayCount),1),m[4]||(m[4]=s("div",{class:"text-xs text-gray-500"},"Total replays",-1))])]),a(g,{"min-width":"40rem",bleed:!1},{default:t(()=>[a(j,{data:e(F),columns:x,sticky:"",class:"max-h-[32rem]"},{"entry-cell":t(({row:O})=>[s("span",{class:"font-mono text-xs truncate block max-w-[28rem]",title:O.original.entry},i(z(O.original.entry)),9,Po)]),"testCount-cell":t(({row:O})=>[s("span",Eo,i(O.original.testCount),1)]),"replayCount-cell":t(({row:O})=>[s("span",Lo,i(O.original.replayCount),1)]),"lastSeen-cell":t(({row:O})=>[s("span",{class:"tabular-nums text-gray-500",title:O.original.lastSeen||""},i(h(O.original.lastSeen)),9,Bo)]),_:1},8,["data"])]),_:1})]))]),_:1})}}}),No=Object.assign(Vo,{__name:"AiStepCoverage"}),Ko={class:"space-y-6"},Oo={class:"w-full text-sm"},qo={class:"px-3 py-2 min-w-0"},Ho={class:"text-xs text-muted"},Qo={class:"px-3 py-2 text-muted"},Go={class:"px-3 py-2 whitespace-nowrap"},Xo={key:1,class:"text-xs text-muted"},Jo={key:2,class:"text-xs"},Wo={class:"px-3 py-2 whitespace-nowrap text-muted"},Yo={class:"px-3 py-2 text-right"},Zo={class:"w-full text-sm"},el={class:"px-3 py-2 min-w-0"},tl={class:"text-xs text-muted"},sl={class:"px-3 py-2 text-right whitespace-nowrap"},nl=oe({__name:"QuarantineTable",props:{projectId:{},projectName:{}},async setup(U){let $,k;const C=U,_=Ae(),p=I(null),{data:c,status:F,error:R,refresh:z}=([$,k]=he(()=>xe(()=>`/api/projects/${C.projectId}/quarantine`,"$BSyDdCMaDx")),$=await $,k(),$);function h(T){const m=Math.round(T/36e5);return m<48?`${Math.max(1,m)}h`:`${Math.round(m/24)}d`}async function y(T,m){p.value=T;try{await $fetch(`/api/projects/${C.projectId}/quarantine`,{method:"POST",body:{testCaseId:T,reason:m,source:"proposed"}}),_.add({title:"Quarantined",color:"success"}),await z()}catch{_.add({title:"Could not quarantine that test",color:"error"})}finally{p.value=null}}async function x(T){p.value=T;try{await $fetch(`/api/projects/${C.projectId}/quarantine/${T}`,{method:"DELETE"}),_.add({title:"Released",color:"success"}),await z()}catch{_.add({title:"Could not release that test",color:"error"})}finally{p.value=null}}return(T,m)=>{const v=Je,M=mn,V=pn,j=gn,g=$e,S=Be,O=ss,D=dt,Q=Ce,N=ke,ue=Ne,ge=ut;return n(),r("div",Ko,[a(ge,{title:"Quarantine",icon:"i-lucide-shield-alert",count:e(c)?.debt.active,help:"project.quarantine"},{subtitle:t(()=>[...m[0]||(m[0]=[d(" A quarantined test keeps running and keeps reporting — it is excluded from the CI gate's verdict and nothing else. That is what lets it earn its way back out. ",-1)])]),default:t(()=>[e(F)==="pending"?(n(),f(v,{key:0})):e(R)?(n(),f(M,{key:1,text:String(e(R))},null,8,["text"])):(n(),r(X,{key:2},[e(c)&&e(c).debt.active>0?(n(),f(j,{key:0,class:"mb-4"},{default:t(()=>[a(V,{label:"Quarantined",value:e(c).debt.active},null,8,["value"]),a(V,{label:"Ready to release",value:e(c).debt.readyToRelease,"value-class":e(c).debt.readyToRelease>0?"text-green-600 dark:text-green-400":"",hint:"earned their way out"},null,8,["value","value-class"]),a(V,{label:"Still failing",value:e(c).debt.stillFailing,hint:"no passing streak"},null,8,["value"]),a(V,{label:"Oldest",value:h(e(c).debt.oldestAgeMs),size:"sm"},null,8,["value"])]),_:1})):A("",!0),!e(c)||e(c).entries.length===0?(n(),f(g,{key:1,icon:"i-lucide-shield-check",text:"Nothing quarantined. Tests you quarantine appear here with their progress back out."})):(n(),f(ue,{key:2},{default:t(()=>[s("table",Oo,[m[2]||(m[2]=s("thead",{class:"text-left text-xs text-muted"},[s("tr",null,[s("th",{class:"px-3 py-2"},"Test"),s("th",{class:"px-3 py-2"},"Reason"),s("th",{class:"px-3 py-2 whitespace-nowrap"},"Streak"),s("th",{class:"px-3 py-2 whitespace-nowrap"},"Age"),s("th",{class:"px-3 py-2 text-right"},"Actions")])],-1)),s("tbody",null,[(n(!0),r(X,null,ae(e(c).entries,b=>(n(),r("tr",{key:b.id,class:"border-t border-default"},[s("td",qo,[a(S,{to:`/test-cases/${b.testCaseId}`,class:"text-primary hover:underline font-medium"},{default:t(()=>[d(i(b.title),1)]),_:2},1032,["to"]),a(O,{tags:b.tags,meta:{owner:b.owner??void 0},"max-tags":3,class:"ml-1"},null,8,["tags","meta"]),s("div",Ho,[a(D,{"file-path":b.filePath,"project-key":U.projectId,"project-name":U.projectName},null,8,["file-path","project-key","project-name"])])]),s("td",Qo,i(b.reason||"—"),1),s("td",Go,[b.releaseProposed?(n(),f(Q,{key:0,color:"success",variant:"soft",size:"xs"},{default:t(()=>[d(i(b.consecutivePasses)+" green — ready ",1)]),_:2},1024)):b.runsSinceQuarantine===0?(n(),r("span",Xo,"not run yet")):(n(),r("span",Jo,i(b.consecutivePasses)+" / "+i(e(c).releaseAfterConsecutivePasses),1))]),s("td",Wo,i(h(b.ageMs)),1),s("td",Yo,[a(N,{size:"xs",color:b.releaseProposed?"primary":"neutral",variant:"soft",loading:e(p)===b.testCaseId,onClick:w=>x(b.testCaseId)},{default:t(()=>[...m[1]||(m[1]=[d(" Release ",-1)])]),_:1},8,["color","loading","onClick"])])]))),128))])])]),_:1}))],64))]),_:1},8,["count"]),e(c)&&e(c).candidates.length>0?(n(),f(ge,{key:0,title:"Worth quarantining",icon:"i-lucide-lightbulb",count:e(c).candidates.length},{subtitle:t(()=>[...m[3]||(m[3]=[d(" Ranked by the CI minutes their flakiness wastes, not by how often they flake — a test that flakes constantly but finishes instantly costs nothing. ",-1)])]),default:t(()=>[a(ue,null,{default:t(()=>[s("table",Zo,[s("tbody",null,[(n(!0),r(X,null,ae(e(c).candidates,b=>(n(),r("tr",{key:b.testCaseId,class:"border-t border-default"},[s("td",el,[a(S,{to:`/test-cases/${b.testCaseId}`,class:"text-primary hover:underline font-medium"},{default:t(()=>[d(i(b.title),1)]),_:2},1032,["to"]),s("div",tl,i(b.rationale),1)]),s("td",sl,[a(N,{size:"xs",color:"neutral",variant:"soft",loading:e(p)===b.testCaseId,onClick:w=>y(b.testCaseId,b.rationale)},{default:t(()=>[...m[4]||(m[4]=[d(" Quarantine ",-1)])]),_:1},8,["loading","onClick"])])]))),128))])])]),_:1})]),_:1},8,["count"])):A("",!0)])}}}),al=Object.assign(nl,{__name:"QuarantineTable"}),ol={class:"space-y-4"},ll={class:"grid grid-cols-1 sm:grid-cols-2 gap-4"},rl={id:"marker-environments"},il=["value"],cl=oe({__name:"MarkerFormModal",props:{open:{type:Boolean},projectId:{},marker:{},environments:{}},emits:["update:open","saved"],setup(U,{emit:$}){const k=U,C=$,_=Ae(),p=yn.map(y=>({label:y.label,value:y.id,icon:y.icon})),c=Es({label:"",occurredAt:"",category:Tt,environment:"",description:""}),F=B(()=>!!k.marker),R=I(!1);function z(y){const x=new Date(y),T=m=>String(m).padStart(2,"0");return`${x.getFullYear()}-${T(x.getMonth()+1)}-${T(x.getDate())}T${T(x.getHours())}:${T(x.getMinutes())}`}ye(()=>k.open,y=>{y&&(k.marker?(c.label=k.marker.label,c.occurredAt=z(k.marker.occurredAt),c.category=k.marker.category||Tt,c.environment=k.marker.environment??"",c.description=k.marker.description??""):(c.label="",c.occurredAt=z(new Date),c.category=Tt,c.environment="",c.description=""))});async function h(){if(!c.label.trim()){_.add({title:"Label is required",color:"error"});return}if(!c.occurredAt){_.add({title:"Date is required",color:"error"});return}R.value=!0;const y={label:c.label.trim(),occurredAt:new Date(c.occurredAt).toISOString(),category:c.category,environment:c.environment.trim()||null,description:c.description.trim()||null};try{k.marker?(await $fetch(`/api/markers/${k.marker.id}`,{method:"PUT",body:y}),_.add({title:"Marker updated",color:"success"})):(await $fetch(`/api/projects/${k.projectId}/markers`,{method:"POST",body:y}),_.add({title:"Marker created",color:"success"})),C("update:open",!1),C("saved")}catch(x){_.add({title:F.value?"Failed to update marker":"Failed to create marker",description:ts(x),color:"error"})}finally{R.value=!1}}return(y,x)=>{const T=Ht,m=Qt,v=ze,M=vn,V=ke,j=zt,g=Dt;return n(),f(g,null,{default:t(()=>[a(j,{open:U.open,title:e(F)?"Edit marker":"Add marker","onUpdate:open":x[6]||(x[6]=S=>C("update:open",S))},{body:t(()=>[s("div",ol,[a(m,{label:"Label",name:"label",required:""},{default:t(()=>[a(T,{modelValue:e(c).label,"onUpdate:modelValue":x[0]||(x[0]=S=>e(c).label=S),placeholder:"e.g. Migrated CI to new runners",class:"w-full"},null,8,["modelValue"])]),_:1}),s("div",ll,[a(m,{label:"Date & time",name:"occurredAt",required:""},{default:t(()=>[a(T,{modelValue:e(c).occurredAt,"onUpdate:modelValue":x[1]||(x[1]=S=>e(c).occurredAt=S),type:"datetime-local",class:"w-full"},null,8,["modelValue"])]),_:1}),a(m,{label:"Category",name:"category"},{default:t(()=>[a(v,{modelValue:e(c).category,"onUpdate:modelValue":x[2]||(x[2]=S=>e(c).category=S),items:e(p),class:"w-full"},null,8,["modelValue","items"])]),_:1})]),a(m,{label:"Environment",name:"environment",help:"Optional. Leave empty to apply to all environments."},{default:t(()=>[a(T,{modelValue:e(c).environment,"onUpdate:modelValue":x[3]||(x[3]=S=>e(c).environment=S),list:"marker-environments",placeholder:"e.g. production",class:"w-full"},null,8,["modelValue"]),s("datalist",rl,[(n(!0),r(X,null,ae(U.environments||[],S=>(n(),r("option",{key:S,value:S},null,8,il))),128))])]),_:1}),a(m,{label:"Description",name:"description"},{default:t(()=>[a(M,{modelValue:e(c).description,"onUpdate:modelValue":x[4]||(x[4]=S=>e(c).description=S),rows:3,placeholder:"Optional details",class:"w-full"},null,8,["modelValue"])]),_:1})])]),footer:t(()=>[a(V,{color:"neutral",variant:"ghost",label:"Cancel",onClick:x[5]||(x[5]=S=>C("update:open",!1))}),a(V,{label:e(F)?"Save changes":"Add marker",icon:e(F)?"i-lucide-check":"i-lucide-plus",loading:e(R),onClick:h},null,8,["label","icon","loading"])]),_:1},8,["open","title"])]),_:1})}}}),ul=Object.assign(cl,{__name:"MarkerFormModal"}),dl={class:"md:hidden space-y-3"},ml={class:"flex items-start justify-between gap-2"},pl={key:0,class:"flex gap-1 shrink-0"},gl={class:"text-sm text-muted"},fl={key:0,class:"text-xs"},_l={key:1,class:"text-sm text-muted"},vl={class:"whitespace-nowrap"},yl={class:"text-sm"},hl={class:"text-xs text-muted"},xl={class:"font-medium flex items-center gap-1"},bl={key:0,class:"text-xs text-muted line-clamp-1"},kl={key:1,class:"text-xs text-muted"},$l={key:0,class:"flex gap-1 justify-end"},Cl=oe({__name:"ProjectTimeline",props:{projectId:{},markers:{},environments:{},canEdit:{type:Boolean},focusMarkerId:{}},emits:["changed","clear-focus"],setup(U,{emit:$}){const k=U,C=$,_=Ae(),p=B(()=>[...k.markers].sort((v,M)=>+new Date(M.occurredAt)-+new Date(v.occurredAt))),c=[{accessorKey:"occurredAt",header:"When"},{accessorKey:"category",header:"Category"},{accessorKey:"label",header:"Label"},{accessorKey:"environment",header:"Environment"},{accessorKey:"actions",header:""}],F=I(!1),R=I(null);function z(){R.value=null,F.value=!0}function h(v){R.value=v,F.value=!0}ye(()=>k.focusMarkerId,v=>{if(v==null)return;const M=k.markers.find(V=>V.id===v);M&&h(M),C("clear-focus")},{immediate:!0});const y=I(!1),x=I(null);function T(v){x.value=v,y.value=!0}async function m(){const v=x.value;if(y.value=!1,x.value=null,!!v)try{await $fetch(`/api/markers/${v.id}`,{method:"DELETE"}),_.add({title:"Marker deleted",color:"success"}),C("changed")}catch(M){_.add({title:"Failed to delete marker",description:ts(M),color:"error"})}}return(v,M)=>{const V=ke,j=$e,g=_n,S=Ce,O=Le,D=Ue,Q=ul,N=zt,ue=Dt,ge=ut;return n(),f(ge,{title:"Timeline markers",count:U.markers.length,icon:"i-lucide-milestone",help:"project.timeline",subtitle:"Dated events overlaid on the analytics charts"},{actions:t(()=>[U.canEdit?(n(),f(V,{key:0,label:"Add marker",icon:"i-lucide-plus",size:"sm",onClick:z})):A("",!0)]),default:t(()=>[U.markers.length===0?(n(),f(j,{key:0,icon:"i-lucide-milestone",text:"No markers yet. Add a deploy, config change, or incident to see it on the charts."})):(n(),r(X,{key:1},[s("div",dl,[(n(!0),r(X,null,ae(e(p),b=>(n(),r("div",{key:b.id,class:"rounded-lg border border-default p-3 space-y-2"},[s("div",ml,[a(g,{marker:b},null,8,["marker"]),U.canEdit?(n(),r("div",pl,[a(V,{icon:"i-lucide-pencil",color:"neutral",variant:"ghost",size:"xs",onClick:w=>h(b)},null,8,["onClick"]),a(V,{icon:"i-lucide-trash-2",color:"error",variant:"ghost",size:"xs",onClick:w=>T(b)},null,8,["onClick"])])):A("",!0)]),s("div",gl,i(("prettyDateFormat"in v?v.prettyDateFormat:e(ct))(b.occurredAt)),1),b.environment?(n(),r("div",fl,[a(S,{color:"neutral",variant:"subtle",size:"xs"},{default:t(()=>[d(i(b.environment),1)]),_:2},1024)])):A("",!0),b.description?(n(),r("p",_l,i(b.description),1)):A("",!0)]))),128))]),a(D,{data:e(p),columns:c,class:"hidden md:block"},{"occurredAt-cell":t(({row:b})=>[s("div",vl,[s("div",yl,i(("prettyDateFormat"in v?v.prettyDateFormat:e(ct))(b.original.occurredAt)),1),s("div",hl,i(("formatRelativeTime"in v?v.formatRelativeTime:e(At))(b.original.occurredAt)),1)])]),"category-cell":t(({row:b})=>[a(S,{color:e(jt)(b.original.category).color,variant:"subtle",size:"sm",class:"gap-1"},{default:t(()=>[a(O,{name:e(jt)(b.original.category).icon,class:"size-3"},null,8,["name"]),d(" "+i(e(jt)(b.original.category).label),1)]),_:2},1032,["color"])]),"label-cell":t(({row:b})=>[s("div",null,[s("div",xl,[d(i(b.original.label)+" ",1),b.original.source==="auto"?(n(),f(O,{key:0,name:"i-lucide-sparkles",class:"size-3 text-muted",title:"Automatically detected"})):A("",!0)]),b.original.description?(n(),r("div",bl,i(b.original.description),1)):A("",!0)])]),"environment-cell":t(({row:b})=>[b.original.environment?(n(),f(S,{key:0,color:"neutral",variant:"subtle",size:"xs"},{default:t(()=>[d(i(b.original.environment),1)]),_:2},1024)):(n(),r("span",kl,"All"))]),"actions-cell":t(({row:b})=>[U.canEdit?(n(),r("div",$l,[a(V,{icon:"i-lucide-pencil",color:"neutral",variant:"ghost",size:"sm",onClick:w=>h(b.original)},null,8,["onClick"]),a(V,{icon:"i-lucide-trash-2",color:"error",variant:"ghost",size:"sm",onClick:w=>T(b.original)},null,8,["onClick"])])):A("",!0)]),_:1},8,["data"])],64)),a(Q,{open:e(F),"onUpdate:open":M[0]||(M[0]=b=>J(F)?F.value=b:null),"project-id":U.projectId,marker:e(R),environments:U.environments,onSaved:M[1]||(M[1]=b=>C("changed"))},null,8,["open","project-id","marker","environments"]),a(ue,null,{default:t(()=>[a(N,{open:e(y),title:"Delete marker","onUpdate:open":M[3]||(M[3]=b=>y.value=b)},{body:t(()=>[s("p",null,[M[4]||(M[4]=d(" Delete marker ",-1)),e(x)?(n(),f(g,{key:0,marker:e(x),class:"inline-flex align-middle"},null,8,["marker"])):A("",!0),M[5]||(M[5]=d("? This can't be undone. ",-1))])]),footer:t(()=>[a(V,{color:"neutral",variant:"ghost",label:"Cancel",onClick:M[2]||(M[2]=b=>y.value=!1)}),a(V,{color:"error",label:"Delete",icon:"i-lucide-trash-2",onClick:m})]),_:1},8,["open"])]),_:1})]),_:1},8,["count"])}}}),Tl=Object.assign(Cl,{__name:"ProjectTimeline"}),jl={class:"flex flex-col h-full overflow-y-auto gap-4"},Sl={key:0,class:"pb-0 space-y-4"},wl={key:0,class:"text-gray-600"},Rl={key:1,class:"flex flex-wrap gap-1 mt-2"},Dl={class:"flex flex-wrap items-center gap-3 mb-4"},Al={class:"inline-flex items-center gap-1"},zl=["onClick"],Ul={key:0,class:"flex items-center gap-3 px-3 py-2 mb-3 rounded-lg bg-primary-50 dark:bg-primary-900/20 border border-primary-200 dark:border-primary-800"},Il={class:"text-sm text-primary-700 dark:text-primary-300"},Ml={key:1,class:"text-xs text-primary-500"},Fl=["checked","onClick"],Pl={class:"flex items-center gap-2"},El=["href","onClick"],Ll={key:0,class:"text-xs text-gray-500 dark:text-gray-400 truncate max-w-32"},Bl={class:"inline-flex items-center gap-1"},Vl={key:0,class:"flex items-center gap-1"},Nl={class:"text-xs text-gray-600"},Kl={key:0,class:"flex items-center gap-1 flex-wrap"},Ol={key:0,class:"text-xs font-medium bg-gray-100 dark:bg-gray-800 px-1.5 py-0.5 rounded"},ql={key:1,class:"text-xs text-gray-500"},Hl={class:"space-y-1"},Ql={class:"flex justify-end gap-2"},Gl={key:2,class:"text-center py-8 text-gray-500"},Xl={class:"text-xs text-gray-400 max-w-sm"},Jl={class:"bg-gray-100 dark:bg-gray-800 px-1 rounded"},Wl={class:"flex flex-wrap items-center gap-3"},Yl={class:"text-xl font-semibold inline-flex items-center gap-1"},Zl={class:"font-medium"},er={class:"mt-1"},tr={key:0,class:"text-red-600 font-medium"},sr={key:1,class:"text-green-600 font-medium"},nr={key:2,class:"text-gray-500"},ar={key:2,class:"text-center py-8 text-red-500"},or={key:3,class:"text-center py-8 text-gray-500"},lr={class:"flex items-center justify-between"},rr={class:"text-xl font-semibold inline-flex items-center gap-1"},ir={class:"space-y-4"},cr={class:"grid grid-cols-1 md:grid-cols-2 gap-4"},ur={key:0,class:"text-center py-4 text-gray-500"},dr={key:1,class:"space-y-4"},mr={class:"flex gap-4 text-sm"},pr={key:0,class:"text-gray-400"},gr={key:0,class:"text-gray-400"},fr={key:1,class:"text-gray-400"},_r={key:1,class:"text-gray-400"},vr={key:0,class:"text-gray-400"},yr={key:0,class:"text-gray-400"},hr={key:2,class:"text-center py-8 text-gray-500"},xr={key:3,class:"text-center py-8 text-gray-500"},br={class:"flex items-center justify-between"},kr={class:"text-sm text-gray-600 inline-flex items-center gap-1"},$r={class:"space-y-4"},Cr={class:"grid grid-cols-1 md:grid-cols-2 gap-4"},Tr={key:0,class:"text-center py-8 text-gray-500"},jr={key:1,class:"space-y-4"},Sr={class:"space-y-2"},wr={class:"flex flex-wrap gap-4 text-sm"},Rr={key:3,class:"text-sm text-gray-500"},Dr={class:"flex flex-wrap gap-4 text-sm"},Ar={key:0,class:"text-gray-400"},zr={key:0,class:"text-gray-400"},Ur={key:1,class:"text-gray-400"},Ir={key:1,class:"text-gray-400"},Mr={key:0,class:"text-gray-400"},Fr={key:0,class:"text-gray-400"},Pr={key:2,class:"text-center py-8 text-gray-500"},Er={key:3,class:"text-center py-8 text-gray-500"},Lr={class:"flex items-center justify-between"},Br={class:"text-sm text-gray-600 inline-flex items-center gap-1"},Vr={key:0,class:"space-y-2"},Nr={class:"font-medium text-sm"},Kr={class:"text-xs text-muted flex items-center gap-2"},Or={key:0,class:"italic"},qr={key:1,class:"text-xs text-muted italic"},Hr={key:1,class:"text-center py-8 text-muted text-sm"},Qr={class:"space-y-4"},Gr={class:"text-sm text-gray-600 dark:text-gray-400"},Xr={class:"block text-sm font-medium mb-1"},Jr={class:"bg-gray-100 dark:bg-gray-800 px-1 rounded"},sc=oe({__name:"index",async setup(U){let $,k;const C=Ls(),_=Bs(),p=C.params.id,{data:c,refresh:F}=([$,k]=he(()=>xe(`/api/projects/${p}`,"$F60FKvNOBL")),$=await $,k(),$);Vs(B(()=>({title:`${c.value?.label||c.value?.name||"Project"} — Piwi Dashboard`})));const R=Ae(),z=I(null),h=I(null),{isAdmin:y,isReporter:x}=Ot(),T=wt(),m=B(()=>!T.public.authEnabled||y.value),v=m,M=I(!1),V=I(""),j=I(!1),g=B(()=>V.value===c.value?.name);async function S(){if(g.value){j.value=!0;try{await $fetch(`/api/projects/${p}`,{method:"DELETE"}),R.add({title:"Project deleted",color:"success"}),await Ks(),await _.push("/")}catch(u){const o=u&&typeof u=="object"&&"data"in u?u.data?.message:void 0;R.add({title:"Delete failed",description:o||"An error occurred",color:"error"}),j.value=!1}}}bn(F);async function O(u){h.value=null,z.value=u;try{await $fetch(`/api/test-runs/${u}`,{method:"DELETE"}),R.add({title:"Test run deleted",color:"success"}),await F()}catch(o){const L=o&&typeof o=="object"&&"data"in o?o.data?.message:void 0;R.add({title:"Delete failed",description:L||"An error occurred",color:"error"})}finally{z.value=null}}const D=I([]),Q=I([]),N=I([]),ue=B(()=>{const u=new Map(D.value.map(L=>[L.id,L])),o=[];for(const L of Q.value){if(L.role==="administrator")continue;const G=u.get(L.id);o.push({id:L.id,username:L.username,name:L.name??null,role:L.role,global:G?.global??!1,hasAccess:!!G})}for(const L of D.value)L.role==="administrator"&&o.push({...L,hasAccess:!0});return o}),ge=B(()=>{const u=D.value.filter(L=>L.role!=="administrator"&&!L.global).map(L=>L.id).sort(),o=[...N.value].sort();return JSON.stringify(u)!==JSON.stringify(o)});ye(()=>c.value?.id,async u=>{if(!(!u||!y.value))try{const[o,L]=await Promise.all([$fetch(`/api/projects/${p}/members`),$fetch("/api/users")]);D.value=o.users,Q.value=L.users,N.value=o.users.filter(G=>G.role!=="administrator"&&!G.global).map(G=>G.id)}catch{D.value=[],Q.value=[],N.value=[]}},{immediate:!0});function b(u){const o=N.value.indexOf(u);o>=0?N.value.splice(o,1):N.value.push(u)}async function w(){try{await $fetch(`/api/projects/${p}/members`,{method:"PUT",body:{userIds:N.value}}),R.add({title:"Members updated",color:"success"});const u=await $fetch(`/api/projects/${p}/members`);D.value=u.users}catch(u){const o=u&&typeof u=="object"&&"data"in u?u.data?.message:void 0;R.add({title:"Update failed",description:o||"An error occurred",color:"error"})}}const H=I("test-runs"),de=I(0),Ie=["test-runs","failure-clusters","flaky-tests","performance","test-cases","compare","spec-health","ai-steps","quarantine","timeline","members"],me=C.query.tab;typeof me=="string"&&Ie.includes(me)&&(H.value=me),ye(H,u=>{C.query.tab!==u&&Ie.includes(u)&&_.replace({query:{...C.query,tab:u}})});const be=B(()=>c.value?.testRuns?.some(u=>u.failedTests>0)??!1),fe=B(()=>[{label:"Results",items:[{label:`Test runs (${K.value.length})`,icon:"i-lucide-play-circle",value:"test-runs",slot:"test-runs"},{label:`Test cases${Qe.value!=null?` (${Qe.value})`:""}`,icon:"i-lucide-list-checks",value:"test-cases",slot:"test-cases"},{label:"Compare",icon:"i-lucide-git-compare-arrows",value:"compare",slot:"compare"}]},{label:"Failures",items:[...be.value?[{label:"Failure clusters",icon:"i-lucide-layers",value:"failure-clusters",slot:"failure-clusters"}]:[],{label:"Flaky tests",icon:"i-lucide-shuffle",value:"flaky-tests",slot:"flaky-tests"},{label:"Quarantine",icon:"i-lucide-shield-alert",value:"quarantine",slot:"quarantine"}]},{label:"Health",items:[{label:"Spec health",icon:"i-lucide-table-2",value:"spec-health",slot:"spec-health"},{label:"AI steps",icon:"i-lucide-wand-sparkles",value:"ai-steps",slot:"ai-steps"},{label:"Performance",icon:"i-lucide-trending-up",value:"performance",slot:"performance"},{label:`Timeline${Te.value.length?` (${Te.value.length})`:""}`,icon:"i-lucide-milestone",value:"timeline",slot:"timeline"}]},...y.value?[{label:"Admin",items:[{label:"Members",icon:"i-lucide-users",value:"members",slot:"members"}]}]:[]]),Me=B(()=>fe.value.flatMap(u=>u.items)),mt=B(()=>fe.value.map(u=>u.items).filter(u=>u.length>0)),pt=B(()=>Me.value.find(u=>u.value===H.value)?.icon),Y=I([]),We=u=>Y.value.includes(u);function Ke(u){const o=Y.value.indexOf(u);if(o>=0)Y.value.splice(o,1);else{if(Y.value.length>=2){R.add({title:"Maximum 2 runs",description:"Select at most 2 runs to compare. Deselect one first.",color:"warning"});return}Y.value.push(u)}}const Oe=I(null);function gt(){Y.value.length===2&&(Oe.value=[Y.value[0],Y.value[1]],H.value="compare")}const ne=I([]),pe=I(!0),qe=B(()=>{const u=new Set;for(const o of c.value?.testRuns||[])o.environment&&u.add(o.environment);return[...u].sort()});function ft(u){const o=ne.value.indexOf(u);o===-1?ne.value.push(u):ne.value.splice(o,1)}function He(u){return ne.value.includes(u)}const K=B(()=>{let u=c.value?.testRuns||[];return pe.value&&(u=u.filter(o=>o.isFullRun!==!1)),ne.value.length===0?u:u.filter(o=>o.environment&&ne.value.includes(o.environment))}),P=B(()=>ne.value.length===1?ne.value[0]:void 0),{data:Z,refresh:_t}=([$,k]=he(()=>xe(`/api/projects/${p}/markers`,{default:()=>({markers:[]})},"$jubPXy8o3y")),$=await $,k(),$),Te=B(()=>Z.value?.markers??[]),Ye=B(()=>!T.public.authEnabled||y.value||x.value),Ze=B(()=>ne.value.length===0?Te.value:Te.value.filter(u=>u.environment==null||ne.value.includes(u.environment))),Fe=I(null);function je(u){Fe.value=u,H.value="timeline"}const vt=B(()=>{const u=c.value?.testRuns||[];return pe.value?u.filter(o=>o.isFullRun!==!1):u});function q(u){if(u.isFullRun!==!1)return"Full run — the complete test suite ran";const o=[],L=u.filterDetails?.grep?.trim(),G=u.filterDetails?.grepInvert?.trim(),_e=u.filterDetails?.files;return L&&L!==".*"&&o.push(`grep: ${L}`),G&&o.push(`grep-invert: ${G}`),_e?.length&&o.push(`files: ${_e.join(", ")}`),o.length?`Partial run — ${o.join(" · ")}`:"Partial run — only a filtered subset of tests ran (grep, file, or line filter)"}const le=[{accessorKey:"select",header:""},{accessorKey:"id",header:E("Run")},{accessorKey:"status",header:E("Status")},{accessorKey:"isFullRun",header:"Scope"},{id:"browsers",accessorFn:u=>u.browsers,header:""},{accessorKey:"startTime",header:E("Started")},{accessorKey:"environment",header:E("Environment")},{accessorKey:"metadata",header:"Branch / Commit"},{accessorKey:"duration",header:E("Test status / Dur.")},{accessorKey:"reports",header:"Reports"},{id:"actions",header:"Actions"}],Qe=I(null),Se=I(""),we=I(""),ns=B(()=>{const u={};return Se.value&&(u.from=Se.value),we.value&&(u.to=we.value),u}),yt=I(null),ht=I(!1),Pe=I(null),xt=I(!1),et=I(!1),as=B(()=>ht.value&&yt.value===null);ye([H,ns,pe],async([u,o])=>{if(u!=="performance")return;ht.value=!0,Pe.value||(et.value=!0);const L=new URLSearchParams(o).toString(),G=pe.value?`${L?"&":""}fullRunsOnly=true`:"",_e=L||G?`?${L}${G}`:"";yt.value=await $fetch(`/api/projects/${p}/performance${_e}`).catch(ve=>(console.warn("[PerformanceTab] Failed to fetch performance trend:",ve),null)),ht.value=!1,et.value&&(xt.value=!1,Pe.value=await $fetch(`/api/projects/${p}/slow-tests`).catch(ve=>(xt.value=!0,console.warn("[PerformanceTab] Failed to fetch slow tests:",ve),null)),et.value=!1)},{immediate:!0});const os=[{accessorKey:"title",header:E("Test case")},{accessorKey:"avgDuration",header:E("Avg duration")},{accessorKey:"maxDuration",header:E("Max")},{accessorKey:"minDuration",header:E("Min")},{accessorKey:"latestDuration",header:E("Latest")},{accessorKey:"trend",header:E("Trend")},{accessorKey:"runCount",header:E("Runs")}];function ls(u){const o=ct(u.startTime,{dateOnly:!0}),L=u.metadata?.scm?.commit?` (${u.metadata.scm.commit.substring(0,7)})`:"";return`Run #${u.id} — ${o}${L}`}const ce=B(()=>c.value?.testRuns?[...c.value.testRuns].reverse().map(u=>({label:ls(u),value:u.id})):[]),ee=I(void 0),te=I(void 0),Ut=B(()=>C.query.runA?Number(C.query.runA):null),It=B(()=>C.query.runB?Number(C.query.runB):null);ye(ce,u=>{if(Ut.value){const o=u.find(L=>L.value===Ut.value);o&&(ee.value=o)}if(It.value){const o=u.find(L=>L.value===It.value);o&&(te.value=o)}},{immediate:!0}),ye(Oe,u=>{if(u){const o=ce.value.find(G=>G.value===u[0]),L=ce.value.find(G=>G.value===u[1]);o&&(ee.value=o),L&&(te.value=L),Oe.value=null}});function Mt(){ce.value.length>=2&&(ee.value=ce.value[1],te.value=ce.value[0])}const bt=I(null),kt=I(null),tt=I(!1);async function rs(){const u=ee.value,o=te.value;if(!(!u?.value&&!o?.value)){tt.value=!0;try{const L=[];u?.value&&L.push(u.value),o?.value&&L.push(o.value);const G=await Promise.all(L.map(ve=>$fetch(`/api/test-runs/${ve}/summary`))),_e=new Map;for(const ve of G)_e.set(ve.id,ve);bt.value=u?.value?_e.get(u.value)??null:null,kt.value=o?.value?_e.get(o.value)??null:null}catch{bt.value=null,kt.value=null}finally{tt.value=!1}}}ye([ee,te],()=>{rs()});const{comparisonData:st,comparisonSummary:W}=xn(bt,kt),Ft=[{accessorKey:"title",header:E("Test case")},{accessorKey:"statusA",header:E("Status A")},{accessorKey:"statusB",header:E("Status B")},{accessorKey:"durationA",header:E("Duration A")},{accessorKey:"durationB",header:E("Duration B")},{accessorKey:"delta",header:E("Delta")},{accessorKey:"percentChange",header:E("Change")}];return(u,o)=>{const L=Ms,G=Fs,_e=Gn,ve=Qs,is=Xs,cs=Gt,us=ta,ds=ze,ms=ua,Pt=Ys,ps=Zs,Ee=Xe,re=ke,gs=en,$t=Le,fs=es,_s=tn,se=Ce,vs=sn,Re=nn,ys=an,nt=Ue,hs=qs,xs=$e,Ge=Ve,bs=xa,ks=Ia,$s=Wa,Ct=Ht,Et=Je,Cs=ro,Ts=dt,js=ho,at=un,Ss=dn,ws=So,Rs=No,Ds=al,As=fn,zs=Tl,Us=hn,Is=Gs,Lt=zt,Bt=Dt;return n(),r(X,null,[a(Is,{id:"project-detail"},{header:t(()=>[a(is,null,{leading:t(()=>[a(L),a(G,{items:[{label:"Home",icon:"i-lucide-house",to:"/"},{label:"Projects",to:"/projects"},{label:e(c)?.label||e(c)?.name||"Project"}]},null,8,["items"])]),right:t(()=>[a(ve,{size:"sm",actions:[...e(m)?[{label:"Delete",icon:"i-lucide-trash-2",color:"error",variant:"ghost",onClick:()=>{V.value="",M.value=!0}}]:[],...e(v)?[{label:"Import",icon:"i-lucide-import",variant:"outline",to:`/projects/${e(p)}/import`}]:[],{label:"Test functions",icon:"i-lucide-function-square",variant:"outline",to:`/projects/${e(p)}/test-functions`},{label:"Edit",icon:"i-lucide-pencil",variant:"outline",to:`/projects/${e(p)}/edit`},{label:"Refresh",icon:"i-lucide-refresh-cw",variant:"outline",onClick:()=>e(F)()}]},{leading:t(()=>[a(_e,{"project-id":parseInt(e(p)),"project-label":e(c)?.label||e(c)?.name},null,8,["project-id","project-label"])]),_:1},8,["actions"])]),_:1})]),body:t(()=>[s("div",jl,[e(c)?.description||e(c)?.tags&&e(c).tags.length>0?(n(),r("div",Sl,[e(c)?.description?(n(),r("p",wl,i(e(c).description),1)):A("",!0),e(c)?.tags&&e(c).tags.length>0?(n(),r("div",Rl,[(n(!0),r(X,null,ae(e(c).tags,l=>(n(),f(cs,{key:l.id,text:l.text,color:l.color},null,8,["text","color"]))),128))])):A("",!0)])):A("",!0),a(us,{"project-id":e(p)},null,8,["project-id"]),a(ds,{modelValue:e(H),"onUpdate:modelValue":o[0]||(o[0]=l=>J(H)?H.value=l:null),items:e(mt),icon:e(pt),size:"md",class:"w-full mx-1 mb-1 sm:hidden"},null,8,["modelValue","items","icon"]),a(Us,{modelValue:e(H),"onUpdate:modelValue":o[14]||(o[14]=l=>J(H)?H.value=l:null),items:e(Me),size:"sm",class:"p-1",ui:{list:"max-sm:hidden overflow-x-auto",trigger:"shrink-0"}},{"test-runs":t(()=>[e(c)?.testRuns&&e(c).testRuns.length>0?(n(),f(Pt,{key:0,title:"Run trend",subtitle:`Test run statistics over time for ${e(c)?.label||e(c)?.name}`,help:"project.runs-trend"},{default:t(()=>[a(ms,{"test-runs":e(vt),height:200,markers:e(Ze),onMarkerClick:je},null,8,["test-runs","markers"])]),_:1},8,["subtitle"])):A("",!0),a(Ge,{class:"mt-4"},{default:t(()=>[s("div",Dl,[s("div",Al,[a(ps,{modelValue:e(pe),"onUpdate:modelValue":o[1]||(o[1]=l=>J(pe)?pe.value=l:null),label:"Full runs only",ui:{label:"text-sm"}},null,8,["modelValue"]),a(Ee,{topic:"project.run-scope"})]),e(qe).length>0?(n(),r(X,{key:0},[o[21]||(o[21]=s("span",{class:"text-sm text-muted shrink-0"},"Environment:",-1)),(n(!0),r(X,null,ae(e(qe),l=>(n(),r("button",{key:l,type:"button",class:ie(["text-xs font-medium px-2 py-1 rounded border cursor-pointer focus:outline-none transition-colors",He(l)?"bg-blue-100 text-blue-700 border-blue-300 dark:bg-blue-900/40 dark:text-blue-300 dark:border-blue-700":"bg-zinc-100 text-zinc-500 border-zinc-200 hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-400 dark:border-zinc-700 dark:hover:bg-zinc-700"]),onClick:De=>ft(l)},i(l),11,zl))),128)),e(ne).length>0?(n(),f(re,{key:0,size:"xs",variant:"ghost",color:"neutral",icon:"i-lucide-x",label:"Clear filter",onClick:o[2]||(o[2]=l=>ne.value=[])})):A("",!0)],64)):A("",!0)]),e(Y).length>0?(n(),r("div",Ul,[s("span",Il,i(e(Y).length)+" run"+i(e(Y).length>1?"s":"")+" selected ",1),e(Y).length===2?(n(),f(re,{key:0,icon:"i-lucide-git-compare-arrows",size:"sm",color:"primary",label:"Compare selected runs",onClick:gt})):(n(),r("span",Ml," Select another run to compare ")),a(re,{size:"xs",variant:"ghost",color:"neutral",icon:"i-lucide-x",label:"Clear",onClick:o[3]||(o[3]=l=>Y.value=[])})])):A("",!0),e(K).length>0?(n(),f(nt,{key:1,data:e(K),columns:le,ui:{base:"table-fixed border-separate border-spacing-0",thead:"[&>tr]:bg-elevated/50 [&>tr]:after:content-none",tbody:"[&>tr]:last:[&>td]:border-b-0",th:"first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",td:"border-b border-default"}},{"select-cell":t(({row:l})=>[s("input",{type:"checkbox",checked:We(l.original.id),class:"cursor-pointer size-4 accent-primary",onClick:Kt(De=>Ke(l.original.id),["stop"])},null,8,Fl)]),"id-cell":t(({row:l})=>[s("div",Pl,[s("a",{href:`/test-runs/${l.original.id}`,class:"text-primary hover:underline font-medium",onClick:Kt(De=>("navigateTo"in u?u.navigateTo:e(Rt))(`/test-runs/${l.original.id}`),["prevent"])}," Run #"+i(l.original.id),9,El),l.original.label?(n(),r("span",Ll,i(l.original.label),1)):A("",!0)])]),"status-cell":t(({row:l})=>[a(gs,{status:l.original.status},null,8,["status"])]),"isFullRun-header":t(()=>[s("span",Bl,[o[22]||(o[22]=d("Scope ",-1)),a(Ee,{topic:"run.partial"})])]),"isFullRun-cell":t(({row:l})=>[a(fs,{text:q(l.original)},{default:t(()=>[a($t,{name:l.original.isFullRun===!1?"i-lucide-list-filter":"i-lucide-list-checks",class:ie(["size-4 shrink-0 cursor-help",l.original.isFullRun===!1?"text-amber-500":"text-green-500"])},null,8,["name","class"])]),_:2},1032,["text"])]),"browsers-cell":t(({row:l})=>[l.original.browsers?.length?(n(),r("div",Vl,[(n(!0),r(X,null,ae(l.original.browsers,De=>(n(),f(_s,{key:De,browser:{projectName:De},size:"sm"},null,8,["browser"]))),128))])):A("",!0)]),"startTime-cell":t(({row:l})=>[s("span",Nl,i(("prettyDateFormat"in u?u.prettyDateFormat:e(ct))(l.original.startTime)),1)]),"environment-cell":t(({row:l})=>[l.original.environment?(n(),f(se,{key:0,color:"info",variant:"subtle",size:"sm"},{default:t(()=>[d(i(l.original.environment),1)]),_:2},1024)):A("",!0)]),"metadata-cell":t(({row:l})=>[l.original.metadata?.scm?(n(),r("div",Kl,[l.original.metadata.scm.branch?(n(),r("span",Ol,i(l.original.metadata.scm.branch),1)):A("",!0),l.original.metadata.scm.commit?(n(),r("code",ql,i(l.original.metadata.scm.commit.substring(0,7)),1)):A("",!0)])):A("",!0)]),"duration-cell":t(({row:l})=>[s("div",Hl,[a(vs,{passed:l.original.passedTests,failed:l.original.failedTests,skipped:l.original.skippedTests,flaky:l.original.flakyTests,"did-not-run":l.original.didNotRunTests??0,total:l.original.totalTests},null,8,["passed","failed","skipped","flaky","did-not-run","total"]),a(Re,{ms:l.original.duration,class:"text-xs text-gray-500"},null,8,["ms"])])]),"reports-cell":t(({row:l})=>[a(ys,{reports:l.original.reports},null,8,["reports"])]),"actions-header":t(()=>[...o[23]||(o[23]=[s("div",{class:"text-right"},"Actions",-1)])]),"actions-cell":t(({row:l})=>[s("div",Ql,[a(re,{to:`/test-runs/${l.original.id}`,size:"sm",variant:"outline"},{default:t(()=>[...o[24]||(o[24]=[d(" View ",-1)])]),_:1},8,["to"]),a(re,{size:"sm",color:"error",variant:"soft",icon:"i-lucide-trash-2",loading:e(z)===l.original.id,onClick:De=>h.value=l.original.id},{default:t(()=>[...o[25]||(o[25]=[d(" Delete ",-1)])]),_:1},8,["loading","onClick"])])]),_:1},8,["data"])):e(c)?.testRuns&&e(c).testRuns.length>0?(n(),r("div",Gl," No test runs match the selected environment filter. ")):(n(),f(xs,{key:3,icon:"i-lucide-rocket",text:"No test runs yet for this project."},{default:t(()=>[s("p",Xl,[o[27]||(o[27]=d(" Point the reporter's ",-1)),o[28]||(o[28]=s("code",{class:"bg-gray-100 dark:bg-gray-800 px-1 rounded"},"projectName",-1)),o[29]||(o[29]=d(" at ",-1)),s("code",Jl,i(e(c)?.name),1),o[30]||(o[30]=d(" to send results here — see the ",-1)),a(hs,{to:"reporter","no-icon":"",class:"text-primary hover:underline"},{default:t(()=>[...o[26]||(o[26]=[d("reporter docs",-1)])]),_:1}),o[31]||(o[31]=d(" for setup instructions. ",-1))])]),_:1}))]),_:1})]),"failure-clusters":t(()=>[e(H)==="failure-clusters"?(n(),r(X,{key:0},[(n(),f(bs,{key:`sug-${e(de)}`,"project-id":String(e(p)),onMerged:o[4]||(o[4]=l=>de.value++)},null,8,["project-id"])),(n(),f(ks,{key:e(de),"project-id":String(e(p))},null,8,["project-id"]))],64)):A("",!0)]),"flaky-tests":t(()=>[e(H)==="flaky-tests"?(n(),f($s,{key:0,"project-id":String(e(p)),environment:e(P),"project-name":e(c)?.name},null,8,["project-id","environment","project-name"])):A("",!0)]),performance:t(()=>[s("div",Wl,[o[32]||(o[32]=s("span",{class:"text-sm text-muted shrink-0"},"Date range:",-1)),a(Ct,{modelValue:e(Se),"onUpdate:modelValue":o[5]||(o[5]=l=>J(Se)?Se.value=l:null),type:"date",size:"sm",placeholder:"From",class:"w-40"},null,8,["modelValue"]),o[33]||(o[33]=s("span",{class:"text-sm text-muted"},"to",-1)),a(Ct,{modelValue:e(we),"onUpdate:modelValue":o[6]||(o[6]=l=>J(we)?we.value=l:null),type:"date",size:"sm",placeholder:"To",class:"w-40"},null,8,["modelValue"]),e(Se)||e(we)?(n(),f(re,{key:0,size:"xs",variant:"ghost",color:"neutral",icon:"i-lucide-x",label:"Clear",onClick:o[7]||(o[7]=l=>{Se.value="",we.value=""})})):A("",!0)]),a(Pt,{title:"Performance trend",subtitle:"Duration metrics over time",help:"project.performance"},{default:t(()=>[e(as)?(n(),f(Et,{key:0,text:"Loading chart…"})):(n(),f(Cs,{key:1,data:e(yt)||[],height:350,markers:e(Ze),onMarkerClick:je},null,8,["data","markers"]))]),_:1}),a(Ge,null,{header:t(()=>[s("h2",Yl,[o[34]||(o[34]=d(" Slowest tests ",-1)),a(Ee,{topic:"project.slowest-tests"})]),o[35]||(o[35]=s("p",{class:"text-sm text-gray-600 mt-1"},"Top 20 slowest test cases across recent runs",-1))]),default:t(()=>[e(et)&&e(Pe)===null?(n(),f(Et,{key:0,text:"Loading…"})):e(Pe)&&e(Pe).length>0?(n(),f(nt,{key:1,data:e(Pe),columns:os,ui:{base:"table-fixed border-separate border-spacing-0",thead:"[&>tr]:bg-elevated/50 [&>tr]:after:content-none",tbody:"[&>tr]:last:[&>td]:border-b-0",th:"first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",td:"border-b border-default"}},{"title-cell":t(({row:l})=>[s("div",null,[s("div",Zl,i(l.original.title),1),s("div",er,[a(Ts,{"file-path":l.original.filePath,"project-key":e(p),"project-name":e(c)?.name,class:"text-xs"},null,8,["file-path","project-key","project-name"])])])]),"trend-cell":t(({row:l})=>[l.original.trend==="slower"?(n(),r("span",tr,"▲ Slower")):l.original.trend==="faster"?(n(),r("span",sr,"▼ Faster")):(n(),r("span",nr,"— Stable"))]),_:1},8,["data"])):e(xt)?(n(),r("div",ar," Couldn't load the slowest tests — try refreshing. ")):(n(),r("div",or,"No slow test data available yet."))]),_:1}),a(js,{"project-id":String(e(p)),"project-name":e(c)?.name},null,8,["project-id","project-name"]),a(Ge,null,{header:t(()=>[s("div",lr,[s("div",null,[s("h2",rr,[o[36]||(o[36]=d(" Run comparison ",-1)),a(Ee,{topic:"project.run-compare"})]),o[37]||(o[37]=s("p",{class:"text-sm text-gray-600 mt-1"},"Compare duration changes between two runs",-1))]),e(ce).length>=2?(n(),f(re,{key:0,icon:"i-lucide-git-compare-arrows",size:"sm",variant:"outline",label:"Compare latest vs previous",onClick:Mt})):A("",!0)])]),default:t(()=>[s("div",ir,[s("div",cr,[s("div",null,[o[38]||(o[38]=s("label",{class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"},"Run A (baseline)",-1)),a(at,{modelValue:e(ee),"onUpdate:modelValue":o[8]||(o[8]=l=>J(ee)?ee.value=l:null),items:e(ce),placeholder:"Select run A..."},null,8,["modelValue","items"])]),s("div",null,[o[39]||(o[39]=s("label",{class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"},"Run B (comparison)",-1)),a(at,{modelValue:e(te),"onUpdate:modelValue":o[9]||(o[9]=l=>J(te)?te.value=l:null),items:e(ce),placeholder:"Select run B..."},null,8,["modelValue","items"])])]),e(tt)?(n(),r("div",ur,[a($t,{name:"i-lucide-loader-2",class:"animate-spin mr-2"}),o[40]||(o[40]=d(" Loading run data… ",-1))])):e(ee)&&e(te)&&e(st).length>0?(n(),r("div",dr,[s("div",mr,[a(se,{color:"success",variant:"soft",size:"lg"},{default:t(()=>[d(i(e(W).improved)+" improved",1)]),_:1}),a(se,{color:"error",variant:"soft",size:"lg"},{default:t(()=>[d(i(e(W).regressed)+" regressed",1)]),_:1}),a(se,{color:"neutral",variant:"soft",size:"lg"},{default:t(()=>[d(i(e(W).unchanged)+" unchanged",1)]),_:1})]),a(nt,{data:e(st),columns:Ft,ui:{base:"table-fixed border-separate border-spacing-0",thead:"[&>tr]:bg-elevated/50 [&>tr]:after:content-none",tbody:"[&>tr]:last:[&>td]:border-b-0",th:"first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",td:"border-b border-default"}},{"statusA-cell":t(({row:l})=>[l.original.statusA?(n(),f(se,{key:1,color:("getStatusColor"in u?u.getStatusColor:e(ot))(l.original.statusA),variant:"subtle",class:"capitalize"},{default:t(()=>[d(i(l.original.statusA),1)]),_:2},1032,["color"])):(n(),r("span",pr,"—"))]),"statusB-cell":t(({row:l})=>[l.original.statusB?(n(),f(se,{key:1,color:("getStatusColor"in u?u.getStatusColor:e(ot))(l.original.statusB),variant:"subtle",class:"capitalize"},{default:t(()=>[d(i(l.original.statusB),1)]),_:2},1032,["color"])):(n(),r("span",gr,"—"))]),"durationA-cell":t(({row:l})=>[l.original.durationA!==null?(n(),f(Re,{key:0,ms:l.original.durationA},null,8,["ms"])):(n(),r("span",fr,"—"))]),"durationB-cell":t(({row:l})=>[l.original.durationB!==null?(n(),f(Re,{key:0,ms:l.original.durationB},null,8,["ms"])):(n(),r("span",_r,"—"))]),"delta-cell":t(({row:l})=>[l.original.delta===null?(n(),r("span",vr,"—")):(n(),r("span",{key:1,class:ie(l.original.delta>0?"text-red-600":l.original.delta<0?"text-green-600":"text-gray-500")},[d(i(l.original.delta>0?"+":""),1),a(Re,{ms:l.original.delta,"unit-class":"opacity-60"},null,8,["ms"])],2))]),"percentChange-cell":t(({row:l})=>[l.original.percentChange===null?(n(),r("span",yr,"—")):(n(),r("span",{key:1,class:ie(l.original.percentChange>10?"text-red-600 font-medium":l.original.percentChange<-10?"text-green-600 font-medium":"text-gray-500")},i(l.original.percentChange>0?"+":"")+i(l.original.percentChange)+"% ",3))]),_:1},8,["data"])])):!e(ee)||!e(te)?(n(),r("div",hr," Select two runs to compare their performance. ")):(n(),r("div",xr," No overlapping test cases found between the selected runs. "))])]),_:1})]),"test-cases":t(()=>[a(Ss,{"project-id":e(p),"project-name":e(c)?.name,"sync-query":"",onTotal:o[10]||(o[10]=l=>Qe.value=l)},null,8,["project-id","project-name"])]),compare:t(()=>[a(Ge,null,{header:t(()=>[s("div",br,[s("p",kr,[o[41]||(o[41]=d(" Compare two test runs side-by-side — status changes and duration deltas ",-1)),a(Ee,{topic:"project.compare"})]),e(ce).length>=2?(n(),f(re,{key:0,icon:"i-lucide-git-compare-arrows",size:"sm",variant:"outline",label:"Latest vs previous",onClick:Mt})):A("",!0)])]),default:t(()=>[s("div",$r,[s("div",Cr,[s("div",null,[o[42]||(o[42]=s("label",{class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"},"Run A (baseline)",-1)),a(at,{modelValue:e(ee),"onUpdate:modelValue":o[11]||(o[11]=l=>J(ee)?ee.value=l:null),items:e(ce),placeholder:"Select run A..."},null,8,["modelValue","items"])]),s("div",null,[o[43]||(o[43]=s("label",{class:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1"},"Run B (comparison)",-1)),a(at,{modelValue:e(te),"onUpdate:modelValue":o[12]||(o[12]=l=>J(te)?te.value=l:null),items:e(ce),placeholder:"Select run B..."},null,8,["modelValue","items"])])]),e(tt)?(n(),r("div",Tr,[a($t,{name:"i-lucide-loader-2",class:"animate-spin mr-2"}),o[44]||(o[44]=d(" Loading run data… ",-1))])):e(ee)&&e(te)&&e(st).length>0?(n(),r("div",jr,[s("div",Sr,[s("div",wr,[o[45]||(o[45]=s("span",{class:"text-xs font-semibold text-gray-500 uppercase tracking-wider mr-1"},"Status changes",-1)),e(W).newFailures>0?(n(),f(se,{key:0,color:"error",variant:"soft",size:"lg"},{default:t(()=>[d(i(e(W).newFailures)+" new failure"+i(e(W).newFailures>1?"s":""),1)]),_:1})):A("",!0),e(W).recovered>0?(n(),f(se,{key:1,color:"success",variant:"soft",size:"lg"},{default:t(()=>[d(i(e(W).recovered)+" recovered ",1)]),_:1})):A("",!0),e(W).stillFailing>0?(n(),f(se,{key:2,color:"warning",variant:"soft",size:"lg"},{default:t(()=>[d(i(e(W).stillFailing)+" still failing ",1)]),_:1})):A("",!0),e(W).newFailures===0&&e(W).recovered===0&&e(W).stillFailing===0?(n(),r("span",Rr,"No status changes")):A("",!0)]),s("div",Dr,[o[46]||(o[46]=s("span",{class:"text-xs font-semibold text-gray-500 uppercase tracking-wider mr-1"},"Duration changes",-1)),e(W).regressed>0?(n(),f(se,{key:0,color:"error",variant:"soft",size:"lg"},{default:t(()=>[d(i(e(W).regressed)+" regressed ",1)]),_:1})):A("",!0),e(W).improved>0?(n(),f(se,{key:1,color:"success",variant:"soft",size:"lg"},{default:t(()=>[d(i(e(W).improved)+" improved ",1)]),_:1})):A("",!0),a(se,{color:"neutral",variant:"soft",size:"lg"},{default:t(()=>[d(i(e(W).unchanged)+" unchanged ",1)]),_:1})])]),a(nt,{data:e(st),columns:Ft,ui:{base:"table-fixed border-separate border-spacing-0",thead:"[&>tr]:bg-elevated/50 [&>tr]:after:content-none",tbody:"[&>tr]:last:[&>td]:border-b-0",th:"first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",td:"border-b border-default"}},{"statusA-cell":t(({row:l})=>[l.original.statusA?(n(),f(se,{key:1,color:("getStatusColor"in u?u.getStatusColor:e(ot))(l.original.statusA),variant:"subtle",class:"capitalize"},{default:t(()=>[d(i(l.original.statusA),1)]),_:2},1032,["color"])):(n(),r("span",Ar,"—"))]),"statusB-cell":t(({row:l})=>[l.original.statusB?(n(),f(se,{key:1,color:("getStatusColor"in u?u.getStatusColor:e(ot))(l.original.statusB),variant:"subtle",class:"capitalize"},{default:t(()=>[d(i(l.original.statusB),1)]),_:2},1032,["color"])):(n(),r("span",zr,"—"))]),"durationA-cell":t(({row:l})=>[l.original.durationA!==null?(n(),f(Re,{key:0,ms:l.original.durationA},null,8,["ms"])):(n(),r("span",Ur,"—"))]),"durationB-cell":t(({row:l})=>[l.original.durationB!==null?(n(),f(Re,{key:0,ms:l.original.durationB},null,8,["ms"])):(n(),r("span",Ir,"—"))]),"delta-cell":t(({row:l})=>[l.original.delta===null?(n(),r("span",Mr,"—")):(n(),r("span",{key:1,class:ie(l.original.delta>0?"text-red-600":l.original.delta<0?"text-green-600":"text-gray-500")},[d(i(l.original.delta>0?"+":""),1),a(Re,{ms:l.original.delta,"unit-class":"opacity-60"},null,8,["ms"])],2))]),"percentChange-cell":t(({row:l})=>[l.original.percentChange===null?(n(),r("span",Fr,"—")):(n(),r("span",{key:1,class:ie(l.original.percentChange>10?"text-red-600 font-medium":l.original.percentChange<-10?"text-green-600 font-medium":"text-gray-500")},i(l.original.percentChange>0?"+":"")+i(l.original.percentChange)+"% ",3))]),_:1},8,["data"])])):!e(ee)||!e(te)?(n(),r("div",Pr," Select two runs to compare test results. ")):(n(),r("div",Er," No overlapping test cases found between the selected runs. "))])]),_:1})]),"spec-health":t(()=>[a(ws,{"project-id":String(e(p))},null,8,["project-id"])]),"ai-steps":t(()=>[a(Rs,{"project-id":String(e(p))},null,8,["project-id"])]),quarantine:t(()=>[a(Ds,{"project-id":String(e(p)),"project-name":e(c)?.name},null,8,["project-id","project-name"])]),members:t(()=>[a(Ge,null,{header:t(()=>[s("div",Lr,[s("p",Br,[o[47]||(o[47]=d(" Users with access to this project ",-1)),a(Ee,{topic:"project.members"})]),a(re,{label:"Save changes",icon:"i-lucide-check",size:"sm",disabled:!e(ge),onClick:w},null,8,["disabled"])])]),default:t(()=>[e(ue).length>0?(n(),r("div",Vr,[(n(!0),r(X,null,ae(e(ue),l=>(n(),r("div",{key:l.id,class:"flex items-center justify-between rounded-lg border border-default px-4 py-3"},[s("div",null,[s("div",Nr,i(l.name||l.username),1),s("div",Kr,[s("span",null,"@"+i(l.username),1),a(se,{color:l.role==="administrator"?"primary":l.role==="reporter"?"info":"neutral",variant:"subtle",size:"xs"},{default:t(()=>[d(i(l.role),1)]),_:2},1032,["color"]),l.global?(n(),r("span",Or,"Global access")):A("",!0)])]),l.role!=="administrator"?(n(),f(As,{key:0,"model-value":e(N).includes(l.id),disabled:l.global,title:l.global?"Has global access — remove global assignment first":"",onChange:De=>b(l.id)},null,8,["model-value","disabled","title","onChange"])):(n(),r("span",qr,"Admin"))]))),128))])):(n(),r("div",Hr,"Loading members…"))]),_:1})]),timeline:t(()=>[a(zs,{"project-id":Number(e(p)),markers:e(Te),environments:e(qe),"can-edit":e(Ye),"focus-marker-id":e(Fe),onChanged:e(_t),onClearFocus:o[13]||(o[13]=l=>Fe.value=null)},null,8,["project-id","markers","environments","can-edit","focus-marker-id","onChanged"])]),_:1},8,["modelValue","items"])])]),_:1}),a(Bt,null,{default:t(()=>[a(Lt,{open:e(M),title:"Delete project","onUpdate:open":o[17]||(o[17]=l=>{l||(M.value=!1)})},{body:t(()=>[s("div",Qr,[s("p",Gr,[o[48]||(o[48]=d(" This will permanently delete ",-1)),s("strong",null,i(e(c)?.label||e(c)?.name),1),o[49]||(o[49]=d(" and all its test runs, reports, traces, and failure clusters. This action cannot be undone. ",-1))]),s("div",null,[s("label",Xr,[o[50]||(o[50]=d(" Type the project key ",-1)),s("code",Jr,i(e(c)?.name),1),o[51]||(o[51]=d(" to confirm: ",-1))]),a(Ct,{modelValue:e(V),"onUpdate:modelValue":o[15]||(o[15]=l=>J(V)?V.value=l:null),placeholder:e(c)?.name,autofocus:"",onKeydown:Ns(S,["enter"])},null,8,["modelValue","placeholder"])])])]),footer:t(()=>[a(re,{color:"neutral",variant:"ghost",label:"Cancel",onClick:o[16]||(o[16]=l=>M.value=!1)}),a(re,{color:"error",label:"Delete project",icon:"i-lucide-trash-2",disabled:!e(g),loading:e(j),onClick:S},null,8,["disabled","loading"])]),_:1},8,["open"])]),_:1}),a(Bt,null,{default:t(()=>[a(Lt,{open:e(h)!==null,title:"Delete test run","onUpdate:open":o[20]||(o[20]=l=>{l||(h.value=null)})},{body:t(()=>[s("p",null,[o[52]||(o[52]=d(" Are you sure you want to delete ",-1)),s("strong",null,"Run #"+i(e(h)),1),o[53]||(o[53]=d("? This will also remove all associated test results, reports, and traces. This action cannot be undone. ",-1))])]),footer:t(()=>[a(re,{color:"neutral",variant:"ghost",label:"Cancel",onClick:o[18]||(o[18]=l=>h.value=null)}),a(re,{color:"error",label:"Delete",icon:"i-lucide-trash-2",loading:e(z)===e(h),onClick:o[19]||(o[19]=l=>O(e(h)))},null,8,["loading"])]),_:1},8,["open"])]),_:1})],64)}}});export{sc as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as Z,a as H}from"./
|
|
1
|
+
import{_ as Z,a as H}from"./Cu2Q4iPh.js";import{_ as J,a as X}from"./opyDpgSw.js";import{_ as tt}from"./B1LUinhp.js";import{_ as et}from"./BrUBOQ0y.js";import{d as U,o as n,f as m,g as l,i as t,j as c,m as o,t as v,_ as T,k as i,h as $,b as st,B as ot,c as y,p as N,r as S,ak as j,e as at,w as I,F as R,v as k,y as nt,q as it,s as rt}from"./C5TrTuWv.js";import{_ as D}from"./DMAiMrNr.js";import{a as lt,u as P}from"./T5UuMUxA.js";import{_ as ct}from"./C7D5Wl7T.js";import{_ as dt}from"./C-XjxjG5.js";import{_ as ut}from"./CDTeSrLO.js";import{_ as pt}from"./DcLbz6DV.js";import{a as mt}from"./B69RP95P.js";import{_ as _t}from"./C8Paf_V1.js";import{u as gt}from"./fXUwH_3d.js";import"./BCGljaM0.js";import"./DMtrFQqi.js";import"./D_y2VS8k.js";import"./DaNC-xl1.js";import"./03FA4-rI.js";import"./DMsm-RGQ.js";import"./BjaRappk.js";const ft={class:"space-y-4 text-sm"},ht={class:"space-y-1"},yt={class:"space-y-3"},kt={class:"space-y-1"},vt={class:"flex items-start gap-2"},bt={class:"text-xs break-all flex-1"},xt={class:"space-y-1"},wt=`reporter: [
|
|
2
2
|
['@piwitests/reporter', { projectName: 'my-project' }],
|
|
3
3
|
],`,Ct=U({__name:"DesktopReporterCard",props:{url:{},token:{}},setup(x){const r=x,{copy:p}=lt(),g=$(()=>`reporter: [
|
|
4
4
|
['@piwitests/reporter', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{G as m,a as p}from"./
|
|
1
|
+
import{G as m,a as p}from"./DMtrFQqi.js";import{d,o as n,c as o,k as t,F as r,m as i,t as l,i as f,q as _,h as c}from"./C5TrTuWv.js";const k=["title"],x=d({__name:"DurationValue",props:{ms:{default:null},fallback:{default:"—"},unitClass:{default:"text-gray-400/70 dark:text-gray-500/70"},noTitle:{type:Boolean,default:!1}},setup(e){const a=e,s=c(()=>m(a.ms)),u=c(()=>a.noTitle||a.ms===null||a.ms===void 0?void 0:p(a.ms));return(y,g)=>(n(),o("span",{class:"tabular-nums whitespace-nowrap",title:t(u)},[t(s)?(n(),o(r,{key:0},[i(l(t(s).value),1),f("span",{class:_(e.unitClass)},l(t(s).unit),3)],64)):(n(),o(r,{key:1},[i(l(e.fallback),1)],64))],8,k))}}),h=Object.assign(x,{__name:"DurationValue"});export{h as _};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as S}from"./
|
|
1
|
+
import{_ as S}from"./BBhrClA9.js";import{_ as $}from"./C-XjxjG5.js";import{_ as q}from"./DH5H1DJh.js";import{d as T,b as j,w as F,ax as N,c as y,j as n,g as r,o as m,k as e,f as O,v as P,i as c,q as B,F as E,y as I,E as M,_ as R,m as k,r as A,M as K}from"./C5TrTuWv.js";import{_ as L}from"./DMAiMrNr.js";import{u as W}from"./T5UuMUxA.js";import"./D_y2VS8k.js";import"./DaNC-xl1.js";import"./03FA4-rI.js";import"./DMsm-RGQ.js";import"./B69RP95P.js";import"./BjaRappk.js";import"./C8Paf_V1.js";const z={class:"space-y-6"},D={class:"space-y-4"},G={class:"flex items-center justify-between gap-2"},H={class:"flex items-center gap-2 shrink-0"},ce=T({__name:"pr-feedback",async setup(J){let u,p;const d=j(),{data:o,refresh:f}=([u,p]=F(()=>W("/api/settings/pr-feedback","$vSS3KCMfao")),u=await u,p(),u),l=A(!1),t=K({enabled:!1,comment:!0,status:!0,onlyOnFailure:!1,statusContext:"piwi/tests"});N(()=>{o.value&&Object.assign(t,o.value.settings)});const v=[{key:"comment",label:"Post a summary comment",description:"Creates one comment on the pull request and edits it on every later run, so a busy branch gets one comment rather than one per push."},{key:"status",label:"Set a commit status",description:"Marks the run’s commit passed or failed, so the pull request shows the result in its checks list. Still set on a green run when the comment is suppressed."},{key:"onlyOnFailure",label:"Only comment on failures",description:"Keeps green runs from adding a comment. The commit status is still set either way."}];async function g(){l.value=!0;try{const i=await $fetch("/api/settings/pr-feedback",{method:"PUT",body:{settings:{...t}}});o.value=i,Object.assign(t,i.settings),d.add({title:"Saved",color:"success"}),await f()}catch{d.add({title:"Save failed",color:"error"})}finally{l.value=!1}}async function w(){l.value=!0;try{const i=await $fetch("/api/settings/pr-feedback",{method:"PUT",body:{settings:null}});o.value=i,Object.assign(t,i.settings),d.add({title:"Reset to defaults",color:"success"}),await f()}catch{d.add({title:"Reset failed",color:"error"})}finally{l.value=!1}}return(i,s)=>{const x=S,h=$,_=q,C=M,b=R,V=L;return m(),y("div",z,[n(V,{icon:"i-lucide-git-pull-request",title:"Pull-request feedback",help:"settings.pr-feedback"},{subtitle:r(()=>[...s[2]||(s[2]=[k(" When a run finishes on a branch with an open pull request, post the result back to it — new failures separated from pre-existing ones, the failure clusters behind them, and the locator to use instead of the one that broke. ",-1)])]),footer:r(()=>[c("div",G,[s[4]||(s[4]=c("p",{class:"text-xs text-muted"}," Needs an SCM token with write access to the repository — set it globally, or per project in the project’s edit page. ",-1)),c("div",H,[n(b,{variant:"ghost",color:"neutral",disabled:e(l),label:"Reset to defaults",onClick:w},null,8,["disabled"]),n(b,{color:"primary",loading:e(l),icon:"i-lucide-save",onClick:g},{default:r(()=>[...s[3]||(s[3]=[k("Save",-1)])]),_:1},8,["loading"])])])]),default:r(()=>[e(o)&&!e(o).siteUrlConfigured?(m(),O(x,{key:0,color:"warning",variant:"soft",icon:"i-lucide-triangle-alert",title:"PIWI_SITE_URL is not set",description:"Nothing is posted until it is — every link in the comment is built from it, and a comment full of unreachable links is worse than no comment.",class:"mb-4"})):P("",!0),c("div",D,[n(h,{modelValue:e(t).enabled,"onUpdate:modelValue":s[0]||(s[0]=a=>e(t).enabled=a),label:"Post feedback to pull requests"},null,8,["modelValue"]),c("div",{class:B(["space-y-4 pl-1",!e(t).enabled&&"opacity-50 pointer-events-none"])},[(m(),y(E,null,I(v,a=>n(_,{key:a.key,label:a.label,description:a.description},{default:r(()=>[n(h,{modelValue:e(t)[a.key],"onUpdate:modelValue":U=>e(t)[a.key]=U},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1032,["label","description"])),64)),n(_,{label:"Commit status context",description:"The name shown next to the status in the pull request’s checks list.",hint:`default ${e(o)?.defaults.statusContext??""}`},{default:r(()=>[n(C,{modelValue:e(t).statusContext,"onUpdate:modelValue":s[1]||(s[1]=a=>e(t).statusContext=a),placeholder:e(o)?.defaults.statusContext,class:"w-full max-w-sm"},null,8,["modelValue","placeholder"])]),_:1},8,["hint"])],2)])]),_:1})])}}});export{ce as default};
|