@polderlabs/bizar 10.1.0 → 10.3.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/README.md +31 -10
- package/bizar-dash/CONTROL_SURFACES.md +0 -1
- package/bizar-dash/dist/assets/{ActivityFeed-Da-JCrE6.js → ActivityFeed-xXiUCZLB.js} +1 -1
- package/bizar-dash/dist/assets/{ActivityFeed-Da-JCrE6.js.map → ActivityFeed-xXiUCZLB.js.map} +1 -1
- package/bizar-dash/dist/assets/{ActivityView-nIRsSETb.js → ActivityView-nOYhCp3h.js} +1 -1
- package/bizar-dash/dist/assets/{ActivityView-nIRsSETb.js.map → ActivityView-nOYhCp3h.js.map} +1 -1
- package/bizar-dash/dist/assets/{AdminView-DP1NMxmG.js → AdminView-Coi4V3sq.js} +1 -1
- package/bizar-dash/dist/assets/{AdminView-DP1NMxmG.js.map → AdminView-Coi4V3sq.js.map} +1 -1
- package/bizar-dash/dist/assets/{AgentActivity-lSPkOr-O.js → AgentActivity-nEri4lbx.js} +1 -1
- package/bizar-dash/dist/assets/{AgentActivity-lSPkOr-O.js.map → AgentActivity-nEri4lbx.js.map} +1 -1
- package/bizar-dash/dist/assets/{AgentsView-BIWGkz7w.js → AgentsView-ByiIJ0ej.js} +3 -3
- package/bizar-dash/dist/assets/{AgentsView-BIWGkz7w.js.map → AgentsView-ByiIJ0ej.js.map} +1 -1
- package/bizar-dash/dist/assets/{Alert-DN0UysMg.js → Alert-Dg_Vwxh5.js} +1 -1
- package/bizar-dash/dist/assets/{Alert-DN0UysMg.js.map → Alert-Dg_Vwxh5.js.map} +1 -1
- package/bizar-dash/dist/assets/ArtifactsView-CGclRNnz.js +21 -0
- package/bizar-dash/dist/assets/ArtifactsView-CGclRNnz.js.map +1 -0
- package/bizar-dash/dist/assets/{AuthView-DW5cs7ma.js → AuthView-utVm6M3D.js} +1 -1
- package/bizar-dash/dist/assets/{AuthView-DW5cs7ma.js.map → AuthView-utVm6M3D.js.map} +1 -1
- package/bizar-dash/dist/assets/{Avatar-DZPv9pvd.js → Avatar-CXDZdKy4.js} +1 -1
- package/bizar-dash/dist/assets/{Avatar-DZPv9pvd.js.map → Avatar-CXDZdKy4.js.map} +1 -1
- package/bizar-dash/dist/assets/{BackgroundJobsView-D8O-EyMD.js → BackgroundJobsView-j603pz6o.js} +1 -1
- package/bizar-dash/dist/assets/{BackgroundJobsView-D8O-EyMD.js.map → BackgroundJobsView-j603pz6o.js.map} +1 -1
- package/bizar-dash/dist/assets/{BackupView-uwXkhxOV.js → BackupView-DgvnntTE.js} +1 -1
- package/bizar-dash/dist/assets/{BackupView-uwXkhxOV.js.map → BackupView-DgvnntTE.js.map} +1 -1
- package/bizar-dash/dist/assets/{Card-Tyboihu7.js → Card-D9019JOD.js} +1 -1
- package/bizar-dash/dist/assets/{Card-Tyboihu7.js.map → Card-D9019JOD.js.map} +1 -1
- package/bizar-dash/dist/assets/{ChatView-DRBHzgay.js → ChatView-C0cTgj5d.js} +1 -1
- package/bizar-dash/dist/assets/{ChatView-DRBHzgay.js.map → ChatView-C0cTgj5d.js.map} +1 -1
- package/bizar-dash/dist/assets/{Chip-BrXIlR9w.js → Chip-DQtalZ4y.js} +1 -1
- package/bizar-dash/dist/assets/{Chip-BrXIlR9w.js.map → Chip-DQtalZ4y.js.map} +1 -1
- package/bizar-dash/dist/assets/{ClaudeSessionsView-Ck62jaOr.js → ClaudeSessionsView-H3Bqjo6b.js} +1 -1
- package/bizar-dash/dist/assets/{ClaudeSessionsView-Ck62jaOr.js.map → ClaudeSessionsView-H3Bqjo6b.js.map} +1 -1
- package/bizar-dash/dist/assets/{ClipboardView-DfND6xL6.js → ClipboardView-BAguaKbx.js} +1 -1
- package/bizar-dash/dist/assets/{ClipboardView-DfND6xL6.js.map → ClipboardView-BAguaKbx.js.map} +1 -1
- package/bizar-dash/dist/assets/{ConfigView-DjJmSrOJ.js → ConfigView-DWHJgoe8.js} +1 -1
- package/bizar-dash/dist/assets/{ConfigView-DjJmSrOJ.js.map → ConfigView-DWHJgoe8.js.map} +1 -1
- package/bizar-dash/dist/assets/{DiagnosticsView-CKgItf0J.js → DiagnosticsView-oCT624hk.js} +1 -1
- package/bizar-dash/dist/assets/{DiagnosticsView-CKgItf0J.js.map → DiagnosticsView-oCT624hk.js.map} +1 -1
- package/bizar-dash/dist/assets/{DialogsView-DHYF8dE1.js → DialogsView-CqHNals_.js} +1 -1
- package/bizar-dash/dist/assets/{DialogsView-DHYF8dE1.js.map → DialogsView-CqHNals_.js.map} +1 -1
- package/bizar-dash/dist/assets/{DoctorView-DDLHrSKk.js → DoctorView-6kfQq_Mx.js} +1 -1
- package/bizar-dash/dist/assets/{DoctorView-DDLHrSKk.js.map → DoctorView-6kfQq_Mx.js.map} +1 -1
- package/bizar-dash/dist/assets/{EmptyState-DZ2ouKwd.js → EmptyState-DLmtBX_6.js} +1 -1
- package/bizar-dash/dist/assets/{EmptyState-DZ2ouKwd.js.map → EmptyState-DLmtBX_6.js.map} +1 -1
- package/bizar-dash/dist/assets/{EnvVarsView-D1cx83mB.js → EnvVarsView-DySOXlP1.js} +2 -2
- package/bizar-dash/dist/assets/{EnvVarsView-D1cx83mB.js.map → EnvVarsView-DySOXlP1.js.map} +1 -1
- package/bizar-dash/dist/assets/{ErrorState-DwwJ2-Jq.js → ErrorState-Bump8diE.js} +1 -1
- package/bizar-dash/dist/assets/{ErrorState-DwwJ2-Jq.js.map → ErrorState-Bump8diE.js.map} +1 -1
- package/bizar-dash/dist/assets/{EvalView-C9aYixXW.js → EvalView-FnZ5d93z.js} +1 -1
- package/bizar-dash/dist/assets/{EvalView-C9aYixXW.js.map → EvalView-FnZ5d93z.js.map} +1 -1
- package/bizar-dash/dist/assets/{GoalsView-DZa_mGmh.js → GoalsView-C4m1WnVv.js} +1 -1
- package/bizar-dash/dist/assets/{GoalsView-DZa_mGmh.js.map → GoalsView-C4m1WnVv.js.map} +1 -1
- package/bizar-dash/dist/assets/{Grid-CiRyhAgR.js → Grid-dEnoGGws.js} +1 -1
- package/bizar-dash/dist/assets/{Grid-CiRyhAgR.js.map → Grid-dEnoGGws.js.map} +1 -1
- package/bizar-dash/dist/assets/{HistoryView-Dv7aPxJE.js → HistoryView-xdRybjZ2.js} +1 -1
- package/bizar-dash/dist/assets/{HistoryView-Dv7aPxJE.js.map → HistoryView-xdRybjZ2.js.map} +1 -1
- package/bizar-dash/dist/assets/{Input-BbFUDQnS.js → Input-BSa3lh_-.js} +1 -1
- package/bizar-dash/dist/assets/{Input-BbFUDQnS.js.map → Input-BSa3lh_-.js.map} +1 -1
- package/bizar-dash/dist/assets/{LibrariesView-DBQ83TNa.js → LibrariesView-1zR04Eci.js} +1 -1
- package/bizar-dash/dist/assets/{LibrariesView-DBQ83TNa.js.map → LibrariesView-1zR04Eci.js.map} +1 -1
- package/bizar-dash/dist/assets/{LightRAGView-JYpE5u9p.js → LightRAGView-PubmA9oL.js} +1 -1
- package/bizar-dash/dist/assets/{LightRAGView-JYpE5u9p.js.map → LightRAGView-PubmA9oL.js.map} +1 -1
- package/bizar-dash/dist/assets/{ListHeader-BGjm11Z0.js → ListHeader-Ak9WJd39.js} +1 -1
- package/bizar-dash/dist/assets/{ListHeader-BGjm11Z0.js.map → ListHeader-Ak9WJd39.js.map} +1 -1
- package/bizar-dash/dist/assets/{MemoryView-CnOP2MvM.js → MemoryView-DBGpuETw.js} +1 -1
- package/bizar-dash/dist/assets/{MemoryView-CnOP2MvM.js.map → MemoryView-DBGpuETw.js.map} +1 -1
- package/bizar-dash/dist/assets/MiscView-DufqBHkX.js +1 -0
- package/bizar-dash/dist/assets/{MiscView-BBcpUbZZ.js.map → MiscView-DufqBHkX.js.map} +1 -1
- package/bizar-dash/dist/assets/{ModsView-CU4cAmIz.js → ModsView-DcX6eVU2.js} +2 -2
- package/bizar-dash/dist/assets/{ModsView-CU4cAmIz.js.map → ModsView-DcX6eVU2.js.map} +1 -1
- package/bizar-dash/dist/assets/{NotificationsView-BYffvthq.js → NotificationsView-B8IhHRQC.js} +1 -1
- package/bizar-dash/dist/assets/{NotificationsView-BYffvthq.js.map → NotificationsView-B8IhHRQC.js.map} +1 -1
- package/bizar-dash/dist/assets/ObsidianView-DEuk65zS.js +1 -0
- package/bizar-dash/dist/assets/{ObsidianView-D3bI0row.js.map → ObsidianView-DEuk65zS.js.map} +1 -1
- package/bizar-dash/dist/assets/{OverviewView-0tq8f-Y0.js → OverviewView-CTI2spTd.js} +1 -1
- package/bizar-dash/dist/assets/{OverviewView-0tq8f-Y0.js.map → OverviewView-CTI2spTd.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProgressBar-B-h60LKA.js → ProgressBar-D3lkz42E.js} +1 -1
- package/bizar-dash/dist/assets/{ProgressBar-B-h60LKA.js.map → ProgressBar-D3lkz42E.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProjectsView-DhX5lzHS.js → ProjectsView-Du0LzE7A.js} +1 -1
- package/bizar-dash/dist/assets/{ProjectsView-DhX5lzHS.js.map → ProjectsView-Du0LzE7A.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProvidersView-CJMX7jm9.js → ProvidersView-5bCgXwBo.js} +1 -1
- package/bizar-dash/dist/assets/{ProvidersView-CJMX7jm9.js.map → ProvidersView-5bCgXwBo.js.map} +1 -1
- package/bizar-dash/dist/assets/{SchedulesView-CcwDQ9Nm.js → SchedulesView-DFHdIz5P.js} +1 -1
- package/bizar-dash/dist/assets/{SchedulesView-CcwDQ9Nm.js.map → SchedulesView-DFHdIz5P.js.map} +1 -1
- package/bizar-dash/dist/assets/{Select-Cw7Qtz2M.js → Select-C8EJj4NM.js} +1 -1
- package/bizar-dash/dist/assets/{Select-Cw7Qtz2M.js.map → Select-C8EJj4NM.js.map} +1 -1
- package/bizar-dash/dist/assets/{SettingsRow-DgsgbPSI.js → SettingsRow-BdOOmYMD.js} +1 -1
- package/bizar-dash/dist/assets/{SettingsRow-DgsgbPSI.js.map → SettingsRow-BdOOmYMD.js.map} +1 -1
- package/bizar-dash/dist/assets/{SettingsView-DTAFdKyK.js → SettingsView-CqwQ6Knv.js} +1 -1
- package/bizar-dash/dist/assets/{SettingsView-DTAFdKyK.js.map → SettingsView-CqwQ6Knv.js.map} +1 -1
- package/bizar-dash/dist/assets/{Sheet-DH-WNJ3Y.js → Sheet-Cztsvgse.js} +1 -1
- package/bizar-dash/dist/assets/{Sheet-DH-WNJ3Y.js.map → Sheet-Cztsvgse.js.map} +1 -1
- package/bizar-dash/dist/assets/{Slider-DXbJuQ7y.js → Slider-BexNfF6K.js} +1 -1
- package/bizar-dash/dist/assets/{Slider-DXbJuQ7y.js.map → Slider-BexNfF6K.js.map} +1 -1
- package/bizar-dash/dist/assets/{Sparkline-CYtAn82j.js → Sparkline-CLZBtvsN.js} +1 -1
- package/bizar-dash/dist/assets/{Sparkline-CYtAn82j.js.map → Sparkline-CLZBtvsN.js.map} +1 -1
- package/bizar-dash/dist/assets/{Switch-BItGrPqr.js → Switch-B1tiRwNK.js} +1 -1
- package/bizar-dash/dist/assets/{Switch-BItGrPqr.js.map → Switch-B1tiRwNK.js.map} +1 -1
- package/bizar-dash/dist/assets/{TasksView-i5tm6CkX.js → TasksView-CT0fPlos.js} +1 -1
- package/bizar-dash/dist/assets/{TasksView-i5tm6CkX.js.map → TasksView-CT0fPlos.js.map} +1 -1
- package/bizar-dash/dist/assets/{Textarea-qYDf3yds.js → Textarea-D_TPpVMy.js} +1 -1
- package/bizar-dash/dist/assets/{Textarea-qYDf3yds.js.map → Textarea-D_TPpVMy.js.map} +1 -1
- package/bizar-dash/dist/assets/{UpdateView-Xln-ej26.js → UpdateView-tD2q2OhW.js} +1 -1
- package/bizar-dash/dist/assets/{UpdateView-Xln-ej26.js.map → UpdateView-tD2q2OhW.js.map} +1 -1
- package/bizar-dash/dist/assets/{UsageView-BGuZSUZ6.js → UsageView-B4BuAFKA.js} +1 -1
- package/bizar-dash/dist/assets/{UsageView-BGuZSUZ6.js.map → UsageView-B4BuAFKA.js.map} +1 -1
- package/bizar-dash/dist/assets/{ViewHeader-BqIPVKuG.js → ViewHeader-V_SzbUpw.js} +1 -1
- package/bizar-dash/dist/assets/{ViewHeader-BqIPVKuG.js.map → ViewHeader-V_SzbUpw.js.map} +1 -1
- package/bizar-dash/dist/assets/{VoiceView-CWUOCQs_.js → VoiceView-D3vb5OM2.js} +1 -1
- package/bizar-dash/dist/assets/{VoiceView-CWUOCQs_.js.map → VoiceView-D3vb5OM2.js.map} +1 -1
- package/bizar-dash/dist/assets/{brain-fsBSDl2g.js → brain-BmfWcitQ.js} +1 -1
- package/bizar-dash/dist/assets/{brain-fsBSDl2g.js.map → brain-BmfWcitQ.js.map} +1 -1
- package/bizar-dash/dist/assets/{calendar-DsHTZoCU.js → calendar-VntJUzFB.js} +1 -1
- package/bizar-dash/dist/assets/{calendar-DsHTZoCU.js.map → calendar-VntJUzFB.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-CqSxqqeJ.js → circle-KrQQySeK.js} +1 -1
- package/bizar-dash/dist/assets/{circle-CqSxqqeJ.js.map → circle-KrQQySeK.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-alert-BsLl001l.js → circle-alert-CQ9MLygI.js} +1 -1
- package/bizar-dash/dist/assets/{circle-alert-BsLl001l.js.map → circle-alert-CQ9MLygI.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-check-rVKMQmZp.js → circle-check-COtVgsWw.js} +1 -1
- package/bizar-dash/dist/assets/{circle-check-rVKMQmZp.js.map → circle-check-COtVgsWw.js.map} +1 -1
- package/bizar-dash/dist/assets/{clock-OuficfgH.js → clock-C0GlM4qp.js} +1 -1
- package/bizar-dash/dist/assets/{clock-OuficfgH.js.map → clock-C0GlM4qp.js.map} +1 -1
- package/bizar-dash/dist/assets/{download-BdHlstUY.js → download-CW4DmtRe.js} +1 -1
- package/bizar-dash/dist/assets/{download-BdHlstUY.js.map → download-CW4DmtRe.js.map} +1 -1
- package/bizar-dash/dist/assets/{external-link-DA3_VGm-.js → external-link-CAOnh_DH.js} +1 -1
- package/bizar-dash/dist/assets/{external-link-DA3_VGm-.js.map → external-link-CAOnh_DH.js.map} +1 -1
- package/bizar-dash/dist/assets/{file-text-B-g8H227.js → file-text-CS1jB_oV.js} +1 -1
- package/bizar-dash/dist/assets/{file-text-B-g8H227.js.map → file-text-CS1jB_oV.js.map} +1 -1
- package/bizar-dash/dist/assets/{filter-D9B8s5CG.js → filter-DyQbml3L.js} +1 -1
- package/bizar-dash/dist/assets/{filter-D9B8s5CG.js.map → filter-DyQbml3L.js.map} +1 -1
- package/bizar-dash/dist/assets/{git-pull-request-ByH0YuVz.js → git-pull-request-Co6gYfba.js} +1 -1
- package/bizar-dash/dist/assets/{git-pull-request-ByH0YuVz.js.map → git-pull-request-Co6gYfba.js.map} +1 -1
- package/bizar-dash/dist/assets/{main-CdOm1Pj9.js → main-CyAIirBB.js} +28 -33
- package/bizar-dash/dist/assets/main-CyAIirBB.js.map +1 -0
- package/bizar-dash/dist/assets/network-CDn43Gsj.js +6 -0
- package/bizar-dash/dist/assets/network-CDn43Gsj.js.map +1 -0
- package/bizar-dash/dist/assets/{pause-C9hgd8wX.js → pause-CKYjSTGX.js} +1 -1
- package/bizar-dash/dist/assets/{pause-C9hgd8wX.js.map → pause-CKYjSTGX.js.map} +1 -1
- package/bizar-dash/dist/assets/{pencil-BanqaMw7.js → pencil-BUJ2DpWs.js} +1 -1
- package/bizar-dash/dist/assets/{pencil-BanqaMw7.js.map → pencil-BUJ2DpWs.js.map} +1 -1
- package/bizar-dash/dist/assets/{play-CawUZ02_.js → play-CGxZWqtW.js} +1 -1
- package/bizar-dash/dist/assets/{play-CawUZ02_.js.map → play-CGxZWqtW.js.map} +1 -1
- package/bizar-dash/dist/assets/{plug-Cmv0-T_e.js → plug-CQYGgGSy.js} +1 -1
- package/bizar-dash/dist/assets/{plug-Cmv0-T_e.js.map → plug-CQYGgGSy.js.map} +1 -1
- package/bizar-dash/dist/assets/{plus-M6LYiKX8.js → plus-fFxt-8z5.js} +1 -1
- package/bizar-dash/dist/assets/{plus-M6LYiKX8.js.map → plus-fFxt-8z5.js.map} +1 -1
- package/bizar-dash/dist/assets/{power-DP5x_SRF.js → power-Cjgy2KsI.js} +1 -1
- package/bizar-dash/dist/assets/{power-DP5x_SRF.js.map → power-Cjgy2KsI.js.map} +1 -1
- package/bizar-dash/dist/assets/{power-off-NOJRLAIs.js → power-off-B81hLRah.js} +1 -1
- package/bizar-dash/dist/assets/{power-off-NOJRLAIs.js.map → power-off-B81hLRah.js.map} +1 -1
- package/bizar-dash/dist/assets/{refresh-ccw-CHMprsm5.js → refresh-ccw-BCXx86xp.js} +1 -1
- package/bizar-dash/dist/assets/{refresh-ccw-CHMprsm5.js.map → refresh-ccw-BCXx86xp.js.map} +1 -1
- package/bizar-dash/dist/assets/{refresh-cw-1RBqDKgJ.js → refresh-cw-COTg1nZo.js} +1 -1
- package/bizar-dash/dist/assets/{refresh-cw-1RBqDKgJ.js.map → refresh-cw-COTg1nZo.js.map} +1 -1
- package/bizar-dash/dist/assets/{rotate-ccw-DJRekBbi.js → rotate-ccw-BZrEVc0Z.js} +1 -1
- package/bizar-dash/dist/assets/{rotate-ccw-DJRekBbi.js.map → rotate-ccw-BZrEVc0Z.js.map} +1 -1
- package/bizar-dash/dist/assets/{rotate-cw-DHooc0Tx.js → rotate-cw-CsTtaLV2.js} +1 -1
- package/bizar-dash/dist/assets/{rotate-cw-DHooc0Tx.js.map → rotate-cw-CsTtaLV2.js.map} +1 -1
- package/bizar-dash/dist/assets/{save-DQKCKyZK.js → save-DtMTge1F.js} +1 -1
- package/bizar-dash/dist/assets/{save-DQKCKyZK.js.map → save-DtMTge1F.js.map} +1 -1
- package/bizar-dash/dist/assets/{send-xgy3RAi7.js → send-DyBhyk8t.js} +1 -1
- package/bizar-dash/dist/assets/{send-xgy3RAi7.js.map → send-DyBhyk8t.js.map} +1 -1
- package/bizar-dash/dist/assets/{shield-alert-CWV2F5ab.js → shield-alert-BPGJlRF8.js} +1 -1
- package/bizar-dash/dist/assets/{shield-alert-CWV2F5ab.js.map → shield-alert-BPGJlRF8.js.map} +1 -1
- package/bizar-dash/dist/assets/{trash-2-CL4khSRv.js → trash-2-2NsyTU8c.js} +1 -1
- package/bizar-dash/dist/assets/{trash-2-CL4khSRv.js.map → trash-2-2NsyTU8c.js.map} +1 -1
- package/bizar-dash/dist/assets/{trending-up-CSJJhWTS.js → trending-up-BXwP23VK.js} +1 -1
- package/bizar-dash/dist/assets/{trending-up-CSJJhWTS.js.map → trending-up-BXwP23VK.js.map} +1 -1
- package/bizar-dash/dist/assets/{triangle-alert-BPLb7uLt.js → triangle-alert-DFmQ_RXN.js} +1 -1
- package/bizar-dash/dist/assets/{triangle-alert-BPLb7uLt.js.map → triangle-alert-DFmQ_RXN.js.map} +1 -1
- package/bizar-dash/dist/assets/{upload-Cww6MvFq.js → upload-Cj-HYRYV.js} +1 -1
- package/bizar-dash/dist/assets/{upload-Cww6MvFq.js.map → upload-Cj-HYRYV.js.map} +1 -1
- package/bizar-dash/dist/assets/{zap-DmhVUzRA.js → zap-BaOiybcl.js} +1 -1
- package/bizar-dash/dist/assets/{zap-DmhVUzRA.js.map → zap-BaOiybcl.js.map} +1 -1
- package/bizar-dash/dist/index.html +1 -1
- package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/bizar-dash/src/server/api.mjs +11 -0
- package/bizar-dash/src/server/artifacts-store.mjs +120 -14
- package/bizar-dash/src/server/claude-artifacts.mjs +281 -0
- package/bizar-dash/src/server/routes/artifacts.mjs +42 -6
- package/bizar-dash/src/server/routes/audit.mjs +78 -0
- package/bizar-dash/src/server/routes/decisions.mjs +78 -0
- package/bizar-dash/src/server/routes/model-router.mjs +55 -0
- package/bizar-dash/src/server/routes/model-router.test.mjs +28 -0
- package/bizar-dash/src/server/routes/sessions.mjs +80 -0
- package/bizar-dash/src/server/routes/update.mjs +48 -21
- package/bizar-dash/src/server/sprint.test.mjs +163 -0
- package/bizar-dash/src/web/v8/App.tsx +0 -4
- package/bizar-dash/src/web/v8/__tests__/new-views.test.tsx +0 -17
- package/bizar-dash/src/web/v8/shell/Sidebar.tsx +0 -1
- package/bizar-dash/src/web/v8/views/Artifacts/ArtifactsView.tsx +232 -21
- package/bizar-dash/src/web/v8/views/Artifacts/ClaudeArtifactView.tsx +179 -0
- package/bizar-dash/src/web/v8/views/Router.tsx +0 -5
- package/bizar-dash/tests/_update-test-helpers.mjs +13 -0
- package/bizar-dash/tests/update-check.test.mjs +18 -13
- package/bizar-dash/tests/update-packages.test.mjs +154 -0
- package/bizar-dash/tests/update-run.test.mjs +17 -80
- package/cli/banner.mjs +1 -1
- package/cli/bin.mjs +8 -1
- package/cli/bootstrap.mjs +1 -1
- package/cli/commands/claude-cmd.mjs +1 -1
- package/cli/commands/deploy/docker.mjs +0 -3
- package/cli/install/banner.mjs +67 -0
- package/cli/install/banner.test.mjs +39 -0
- package/cli/install/index.mjs +32 -0
- package/cli/install/index.test.mjs +61 -0
- package/cli/install/paths.mjs +80 -0
- package/cli/install/paths.test.mjs +77 -0
- package/cli/install/plugin.mjs +161 -0
- package/cli/install/postinstall.mjs +111 -0
- package/cli/install.mjs +13 -600
- package/cli/migrate.mjs +157 -0
- package/cli/migrate.test.mjs +85 -0
- package/cli/provision.mjs +615 -1918
- package/cli/provision.test.mjs +1 -1
- package/cli/service-controller.test.mjs +0 -1
- package/cli/service-env.mjs +0 -1
- package/cli/utils.mjs +0 -1
- package/install.sh +54 -466
- package/package.json +1 -1
- package/packages/sdk/dist/agent/cron.d.ts +44 -0
- package/packages/sdk/dist/agent/cron.js +79 -0
- package/packages/sdk/dist/agent/heartbeat.d.ts +43 -0
- package/packages/sdk/dist/agent/heartbeat.js +116 -0
- package/packages/sdk/dist/index.d.ts +3 -0
- package/packages/sdk/dist/index.js +5 -0
- package/packages/sdk/dist/learning/decisions.d.ts +46 -0
- package/packages/sdk/dist/learning/decisions.js +132 -0
- package/packages/sdk/dist/learning/index.d.ts +8 -0
- package/packages/sdk/dist/learning/index.js +8 -0
- package/packages/sdk/dist/learning/instincts.d.ts +38 -0
- package/packages/sdk/dist/learning/instincts.js +139 -0
- package/packages/sdk/dist/mcp/server.js +119 -1
- package/packages/sdk/dist/router/agent-model-registry.d.ts +89 -0
- package/packages/sdk/dist/router/agent-model-registry.js +144 -0
- package/packages/sdk/dist/router/index.d.ts +1 -0
- package/packages/sdk/dist/router/index.js +1 -0
- package/packages/sdk/package.json +3 -2
- package/scripts/audit.mjs +388 -0
- package/scripts/audit.test.mjs +149 -0
- package/scripts/eval-gate.mjs +134 -0
- package/scripts/eval-gate.test.mjs +138 -0
- package/scripts/feature-state-machine.mjs +178 -0
- package/scripts/feature-state-machine.test.mjs +135 -0
- package/scripts/install-curl.sh +17 -0
- package/scripts/spec-dedup.test.mjs +124 -0
- package/scripts/sprint.mjs +213 -0
- package/scripts/worktree-setup.sh +79 -0
- package/bizar-dash/dist/assets/ArtifactsView-CDIhPBAx.js +0 -6
- package/bizar-dash/dist/assets/ArtifactsView-CDIhPBAx.js.map +0 -1
- package/bizar-dash/dist/assets/HeadroomView-CNc-TI7u.js +0 -11
- package/bizar-dash/dist/assets/HeadroomView-CNc-TI7u.js.map +0 -1
- package/bizar-dash/dist/assets/MiscView-BBcpUbZZ.js +0 -1
- package/bizar-dash/dist/assets/ObsidianView-D3bI0row.js +0 -1
- package/bizar-dash/dist/assets/main-CdOm1Pj9.js.map +0 -1
- package/bizar-dash/src/web/v8/views/Headroom/HeadroomView.tsx +0 -201
- package/bizar-dash/tests/graphify-mod-spawn.node.test.mjs +0 -90
- package/bizar-dash/tests/v7-archive/mobile-overview.test.tsx +0 -214
- package/bizar-dash/tests/v7-archive/mobile-settings.test.tsx +0 -181
- package/bizar-dash/tests/v7-archive/navigation/CommandPalette.test.tsx +0 -105
- package/bizar-dash/tests/v7-archive/settings-nav.test.tsx +0 -128
- package/bizar-dash/tests/v7-archive/views/Overview.test.tsx +0 -413
- package/cli/provision-claude.mjs +0 -1176
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState-
|
|
1
|
+
{"version":3,"file":"EmptyState-DLmtBX_6.js","sources":["../../src/web/v8/ui/feedback/EmptyState.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * EmptyState — placeholder for empty lists / zero-data views.\n *\n * Use when a view has no rows. Never use a spinner; the data is\n * genuinely empty.\n */\nexport interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n icon?: ReactNode;\n title: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n}\n\nexport const EmptyState = forwardRef<HTMLDivElement, EmptyStateProps>(function EmptyState(\n props,\n ref,\n) {\n const { icon, title, description, action, className, ...rest } = props;\n return (\n <div\n ref={ref}\n className={cx('v8-empty-state', className)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--space-3)',\n padding: 'var(--space-12) var(--space-6)',\n textAlign: 'center',\n color: 'var(--fg-muted)',\n }}\n {...rest}\n >\n {icon !== undefined && (\n <div style={{ color: 'var(--fg-subtle)', display: 'inline-flex' }}>{icon}</div>\n )}\n <div style={{ fontSize: 'var(--fs-16)', fontWeight: 600, color: 'var(--fg)' }}>{title}</div>\n {description !== undefined && (\n <div style={{ fontSize: 'var(--fs-13)', maxWidth: 480 }}>{description}</div>\n )}\n {action !== undefined && <div style={{ marginTop: 'var(--space-2)' }}>{action}</div>}\n </div>\n );\n});"],"names":["EmptyState","forwardRef","props","ref","icon","title","description","action","className","rest","jsxs","cx","jsx"],"mappings":"qFAgBO,MAAMA,EAAaC,EAAAA,WAA4C,SACpEC,EACAC,EACA,CACA,KAAM,CAAE,KAAAC,EAAM,MAAAC,EAAO,YAAAC,EAAa,OAAAC,EAAQ,UAAAC,EAAW,GAAGC,GAASP,EACjE,OACEQ,EAAAA,KAAC,MAAA,CACC,IAAAP,EACA,UAAWQ,EAAG,iBAAkBH,CAAS,EACzC,MAAO,CACL,QAAS,OACT,cAAe,SACf,WAAY,SACZ,eAAgB,SAChB,IAAK,iBACL,QAAS,iCACT,UAAW,SACX,MAAO,iBAAA,EAER,GAAGC,EAEH,SAAA,CAAAL,IAAS,QACRQ,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,MAAO,mBAAoB,QAAS,aAAA,EAAkB,SAAAR,CAAA,CAAK,EAE3EQ,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,WAAY,IAAK,MAAO,WAAA,EAAgB,SAAAP,CAAA,CAAM,EACrFC,IAAgB,QACfM,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,SAAU,GAAA,EAAQ,SAAAN,CAAA,CAAY,EAEvEC,IAAW,QAAaK,MAAC,MAAA,CAAI,MAAO,CAAE,UAAW,gBAAA,EAAqB,SAAAL,CAAA,CAAO,CAAA,CAAA,CAAA,CAGpF,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{r as s,j as e}from"./cmdk-DVxytz9i.js";import{c as O,u as V,S as p,I as f,d as n,h as I,V as P,
|
|
1
|
+
import{r as s,j as e}from"./cmdk-DVxytz9i.js";import{c as O,u as V,S as p,I as f,d as n,h as I,V as P,N as D,i as y,F as k}from"./main-CyAIirBB.js";import{V as Z}from"./ViewHeader-V_SzbUpw.js";import{L as M}from"./ListHeader-Ak9WJd39.js";import{C as N,b as _}from"./Card-D9019JOD.js";import{I as A}from"./Input-BSa3lh_-.js";import{S as w,a as E,b as T}from"./Sheet-Cztsvgse.js";import{E as L}from"./EmptyState-DLmtBX_6.js";import{D as U}from"./download-CW4DmtRe.js";import{R as q}from"./refresh-ccw-BCXx86xp.js";import{P as H}from"./plus-fFxt-8z5.js";import{P as K}from"./pencil-BUJ2DpWs.js";import{T as J}from"./trash-2-2NsyTU8c.js";/**
|
|
2
2
|
* @license lucide-react v0.460.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const W=O("FileUp",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M12 12v6",key:"3ahymv"}],["path",{d:"m15 15-3-3-3 3",key:"15xj92"}]]);function ce(){const d=V("/api/env-vars"),[g,c]=s.useState(!1),[v,r]=s.useState(null),[m,i]=s.useState(!1),[u,l]=s.useState(null),[x,h]=s.useState(null),[b,C]=s.useState(null),[o,$]=s.useState(null),S=s.useMemo(()=>d.data??[],[d.data]),j=s.useCallback(()=>{d.refetch()},[d]),B=async a=>{C(a),h(null);try{const t=await y(`/api/env-vars/${encodeURIComponent(a)}/test`,{method:"POST"});$({name:a,ok:t.ok!==!1,message:t.message??(t.ok!==!1?"OK":"Failed")})}catch(t){const z=(t instanceof k,t.message);$({name:a,ok:!1,message:z})}finally{C(null)}},F=async a=>{h(null);try{await y(`/api/env-vars/${a}`,{method:"DELETE"}),l(null),j()}catch(t){h((t instanceof k,t.message))}};return e.jsxs(p,{gap:4,"data-testid":"env-vars-view",children:[e.jsx(Z,{title:"Env vars",description:"Runtime environment variables for the dashboard. Stored in ~/.config/bizar/env.json (mode 0600).",actions:e.jsxs(f,{align:"center",gap:2,children:[x!==null&&e.jsx("span",{role:"alert","data-testid":"env-vars-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:x}),e.jsxs(n,{variant:"ghost",onClick:()=>{window.open("/api/env-vars/export","_blank")},"data-testid":"env-vars-export",children:[e.jsx(U,{size:14,"aria-hidden":!0})," Export"]}),e.jsxs(n,{variant:"ghost",onClick:()=>i(!0),"data-testid":"env-vars-bulk-import",children:[e.jsx(W,{size:14,"aria-hidden":!0})," Bulk import"]}),e.jsxs(n,{variant:"ghost",onClick:()=>void j(),"data-testid":"env-vars-refresh",children:[e.jsx(q,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(n,{variant:"primary",onClick:()=>c(!0),"data-testid":"env-vars-add",children:[e.jsx(H,{size:14,"aria-hidden":!0})," Add"]})]})}),e.jsx(M,{title:"Variables",count:S.length,testid:"env-vars-list-header"}),e.jsx(
|
|
6
|
+
*/const W=O("FileUp",[["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z",key:"1rqfz7"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M12 12v6",key:"3ahymv"}],["path",{d:"m15 15-3-3-3 3",key:"15xj92"}]]);function ce(){const d=V("/api/env-vars"),[g,c]=s.useState(!1),[v,r]=s.useState(null),[m,i]=s.useState(!1),[u,l]=s.useState(null),[x,h]=s.useState(null),[b,C]=s.useState(null),[o,$]=s.useState(null),S=s.useMemo(()=>d.data??[],[d.data]),j=s.useCallback(()=>{d.refetch()},[d]),B=async a=>{C(a),h(null);try{const t=await y(`/api/env-vars/${encodeURIComponent(a)}/test`,{method:"POST"});$({name:a,ok:t.ok!==!1,message:t.message??(t.ok!==!1?"OK":"Failed")})}catch(t){const z=(t instanceof k,t.message);$({name:a,ok:!1,message:z})}finally{C(null)}},F=async a=>{h(null);try{await y(`/api/env-vars/${a}`,{method:"DELETE"}),l(null),j()}catch(t){h((t instanceof k,t.message))}};return e.jsxs(p,{gap:4,"data-testid":"env-vars-view",children:[e.jsx(Z,{title:"Env vars",description:"Runtime environment variables for the dashboard. Stored in ~/.config/bizar/env.json (mode 0600).",actions:e.jsxs(f,{align:"center",gap:2,children:[x!==null&&e.jsx("span",{role:"alert","data-testid":"env-vars-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:x}),e.jsxs(n,{variant:"ghost",onClick:()=>{window.open("/api/env-vars/export","_blank")},"data-testid":"env-vars-export",children:[e.jsx(U,{size:14,"aria-hidden":!0})," Export"]}),e.jsxs(n,{variant:"ghost",onClick:()=>i(!0),"data-testid":"env-vars-bulk-import",children:[e.jsx(W,{size:14,"aria-hidden":!0})," Bulk import"]}),e.jsxs(n,{variant:"ghost",onClick:()=>void j(),"data-testid":"env-vars-refresh",children:[e.jsx(q,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(n,{variant:"primary",onClick:()=>c(!0),"data-testid":"env-vars-add",children:[e.jsx(H,{size:14,"aria-hidden":!0})," Add"]})]})}),e.jsx(M,{title:"Variables",count:S.length,testid:"env-vars-list-header"}),e.jsx(N,{variant:"default",children:e.jsx(_,{children:d.loading&&S.length===0?e.jsxs(p,{gap:2,children:[e.jsx(I,{style:{height:36}}),e.jsx(I,{style:{height:36}})]}):S.length===0?e.jsx(L,{icon:e.jsx(P,{size:28,"aria-hidden":!0}),title:"No env vars",description:"Add one or bulk-import a .env file."}):e.jsx(p,{gap:1,children:S.map(a=>{const t=u===a.name;return e.jsxs("div",{"data-testid":`env-var-row-${a.name}`,style:{padding:"var(--space-2)",borderRadius:"var(--radius-sm)",border:"1px solid var(--border)",background:"var(--surface-0)"},children:[e.jsxs(f,{align:"center",justify:"between",gap:2,children:[e.jsxs(p,{gap:0,style:{minWidth:0},children:[e.jsx("code",{style:{fontSize:"var(--fs-12)"},children:a.name}),e.jsx("code",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:a.value}),a.source&&e.jsxs("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:["source: ",a.source," ",a.createdAt?`· ${a.createdAt}`:""]})]}),e.jsxs(f,{gap:1,children:[e.jsx(n,{variant:"ghost",onClick:()=>void B(a.name),disabled:b===a.name,"data-testid":`env-var-test-${a.name}`,"aria-label":`Test ${a.name}`,children:e.jsx(D,{size:14,"aria-hidden":!0})}),e.jsx(n,{variant:"ghost",onClick:()=>r(a.name),"data-testid":`env-var-edit-${a.name}`,"aria-label":`Edit ${a.name}`,children:e.jsx(K,{size:14,"aria-hidden":!0})}),e.jsx(n,{variant:"ghost",onClick:()=>l(z=>z===a.name?null:a.name),"data-testid":`env-var-delete-${a.name}`,"aria-label":`Delete ${a.name}`,children:e.jsx(J,{size:14,"aria-hidden":!0})})]})]}),t&&e.jsxs(f,{gap:1,style:{marginTop:"var(--space-1)"},children:[e.jsx(n,{variant:"danger",onClick:()=>void F(a.name),"data-testid":`env-var-confirm-delete-${a.name}`,children:"Confirm delete"}),e.jsx(n,{variant:"ghost",onClick:()=>l(null),"data-testid":`env-var-cancel-delete-${a.name}`,children:"Cancel"})]}),o!==null&&o.name===a.name&&e.jsxs("div",{"data-testid":`env-var-test-result-${a.name}`,style:{marginTop:"var(--space-1)",fontSize:"var(--fs-11)",color:o.ok?"var(--success)":"var(--danger)",fontFamily:"var(--font-mono)"},children:["test: ",o.message]})]},a.name)})})})}),e.jsx(w,{open:g,onOpenChange:c,children:e.jsx(E,{side:"right",title:"Add env var",description:"Must match /^BIZAR_[A-Z0-9_]+$/.",children:e.jsx(R,{mode:"add",onSubmit:async(a,t)=>{await y("/api/env-vars",{method:"POST",body:{name:a,value:t}}),c(!1),j()},onCancel:()=>c(!1)})})}),e.jsx(w,{open:v!==null,onOpenChange:a=>{a||r(null)},children:e.jsx(E,{side:"right",title:"Edit env var",description:v??"",children:v!==null&&e.jsx(R,{mode:"edit",initialName:v,onSubmit:async(a,t)=>{await y(`/api/env-vars/${a}`,{method:"PUT",body:{value:t}}),r(null),j()},onCancel:()=>r(null)})})}),e.jsx(w,{open:m,onOpenChange:i,children:e.jsx(E,{side:"right",title:"Bulk import",description:"Paste KEY=value lines (one per line, # comments ignored).",children:e.jsx(Y,{onSubmit:async a=>{await y("/api/env-vars/bulk-import",{method:"POST",body:{envContent:a}}),i(!1),j()},onCancel:()=>i(!1)})})})]})}function R({mode:d,initialName:g,onSubmit:c,onCancel:v}){const[r,m]=s.useState(g??""),[i,u]=s.useState(""),[l,x]=s.useState(!1),[h,b]=s.useState(null),C=async()=>{if(!(!r.trim()||!i||l)){x(!0),b(null);try{await c(r.trim(),i)}catch(o){b((o instanceof k,o.message))}finally{x(!1)}}};return e.jsxs(p,{gap:3,style:{padding:"var(--space-4)"},children:[e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Name"}),e.jsx(A,{value:r,readOnly:d==="edit","data-testid":"env-var-form-name",onChange:o=>m(o.target.value)})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Value"}),e.jsx(A,{type:"password",value:i,"data-testid":"env-var-form-value",onChange:o=>u(o.target.value)})]}),h!==null&&e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:h}),e.jsxs(f,{justify:"end",gap:2,children:[e.jsx(T,{asChild:!0,children:e.jsx(n,{variant:"ghost",onClick:v,"data-testid":"env-var-form-cancel",children:"Cancel"})}),e.jsx(n,{variant:"primary",onClick:()=>void C(),disabled:l||!r.trim()||!i,"data-testid":"env-var-form-submit",children:d==="add"?"Add":"Save"})]})]})}function Y({onSubmit:d,onCancel:g}){const[c,v]=s.useState(""),[r,m]=s.useState(!1),[i,u]=s.useState(null);return e.jsxs(p,{gap:3,style:{padding:"var(--space-4)"},children:[e.jsx("textarea",{value:c,placeholder:`BIZAR_FOO=bar
|
|
7
7
|
BIZAR_BAZ=qux
|
|
8
8
|
# comment`,rows:12,"data-testid":"env-vars-bulk-input",onChange:l=>v(l.target.value),style:{background:"var(--surface-0)",border:"1px solid var(--border)",borderRadius:"var(--radius-md)",padding:"var(--space-2)",color:"var(--fg)",fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",resize:"vertical"}}),i!==null&&e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:i}),e.jsxs(f,{justify:"end",gap:2,children:[e.jsx(T,{asChild:!0,children:e.jsx(n,{variant:"ghost",onClick:g,children:"Cancel"})}),e.jsx(n,{variant:"primary",onClick:async()=>{m(!0),u(null);try{await d(c)}catch(l){u((l instanceof k,l.message))}finally{m(!1)}},disabled:r||c.trim()==="","data-testid":"env-vars-bulk-submit",children:r?"Importing…":"Import"})]})]})}export{ce as EnvVarsView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EnvVarsView-D1cx83mB.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/file-up.js","../../src/web/v8/views/EnvVars/EnvVarsView.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileUp = createLucideIcon(\"FileUp\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M12 12v6\", key: \"3ahymv\" }],\n [\"path\", { d: \"m15 15-3-3-3 3\", key: \"15xj92\" }]\n]);\n\nexport { FileUp as default };\n//# sourceMappingURL=file-up.js.map\n","/**\n * v8/views/EnvVars/EnvVarsView.tsx — Sprint S41, v9.3.0.\n *\n * List of env vars (masked values) with: per-row edit (Sheet),\n * per-row delete (inline confirm), Add Sheet, Bulk Import Sheet,\n * and Export trigger. Backed by /api/env-vars + /api/env-vars/grouped\n * + /api/env-vars/export + /api/env-vars/bulk-import.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { Download, FileUp, FlaskConical, Pencil, Plus, RefreshCcw, Trash2, Variable } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { ListHeader } from '../../ui/data/ListHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Sheet, SheetClose, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\ninterface EnvRow {\n name: string;\n value: string;\n createdAt?: string;\n source?: string;\n}\n\nexport function EnvVarsView(): JSX.Element {\n const payload = useFetch<EnvRow[]>('/api/env-vars');\n const [adding, setAdding] = useState<boolean>(false);\n const [editing, setEditing] = useState<string | null>(null);\n const [bulkImporting, setBulkImporting] = useState<boolean>(false);\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [testing, setTesting] = useState<string | null>(null);\n const [testResult, setTestResult] = useState<{ name: string; ok: boolean; message: string } | null>(null);\n\n const rows = useMemo<EnvRow[]>(() => payload.data ?? [], [payload.data]);\n\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n\n const runTest = async (name: string): Promise<void> => {\n setTesting(name);\n setError(null);\n try {\n const res = await fetchJson<{ ok?: boolean; status?: string; message?: string }>(`/api/env-vars/${encodeURIComponent(name)}/test`, { method: 'POST' });\n setTestResult({ name, ok: res.ok !== false, message: res.message ?? (res.ok !== false ? 'OK' : 'Failed') });\n } catch (err) {\n const msg = err instanceof FetchError ? err.message : (err as Error).message;\n setTestResult({ name, ok: false, message: msg });\n } finally {\n setTesting(null);\n }\n };\n\n const drop = async (name: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/env-vars/${name}`, { method: 'DELETE' });\n setConfirmDelete(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n return (\n <Stack gap={4} data-testid=\"env-vars-view\">\n <ViewHeader\n title=\"Env vars\"\n description=\"Runtime environment variables for the dashboard. Stored in ~/.config/bizar/env.json (mode 0600).\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"env-vars-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => { window.open('/api/env-vars/export', '_blank'); }} data-testid=\"env-vars-export\">\n <Download size={14} aria-hidden /> Export\n </Button>\n <Button variant=\"ghost\" onClick={() => setBulkImporting(true)} data-testid=\"env-vars-bulk-import\">\n <FileUp size={14} aria-hidden /> Bulk import\n </Button>\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"env-vars-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => setAdding(true)} data-testid=\"env-vars-add\">\n <Plus size={14} aria-hidden /> Add\n </Button>\n </Inline>\n }\n />\n <ListHeader title=\"Variables\" count={rows.length} testid=\"env-vars-list-header\" />\n\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && rows.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 36 }} />\n <Skeleton style={{ height: 36 }} />\n </Stack>\n ) : rows.length === 0 ? (\n <EmptyState\n icon={<Variable size={28} aria-hidden />}\n title=\"No env vars\"\n description=\"Add one or bulk-import a .env file.\"\n />\n ) : (\n <Stack gap={1}>\n {rows.map((r) => {\n const isConfirming = confirmDelete === r.name;\n return (\n <div\n key={r.name}\n data-testid={`env-var-row-${r.name}`}\n style={{\n padding: 'var(--space-2)',\n borderRadius: 'var(--radius-sm)',\n border: '1px solid var(--border)',\n background: 'var(--surface-0)',\n }}\n >\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Stack gap={0} style={{ minWidth: 0 }}>\n <code style={{ fontSize: 'var(--fs-12)' }}>{r.name}</code>\n <code style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{r.value}</code>\n {r.source && (\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>\n source: {r.source} {r.createdAt ? `· ${r.createdAt}` : ''}\n </span>\n )}\n </Stack>\n <Inline gap={1}>\n <Button\n variant=\"ghost\"\n onClick={() => void runTest(r.name)}\n disabled={testing === r.name}\n data-testid={`env-var-test-${r.name}`}\n aria-label={`Test ${r.name}`}\n >\n <FlaskConical size={14} aria-hidden />\n </Button>\n <Button variant=\"ghost\" onClick={() => setEditing(r.name)} data-testid={`env-var-edit-${r.name}`} aria-label={`Edit ${r.name}`}>\n <Pencil size={14} aria-hidden />\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => setConfirmDelete((cur) => (cur === r.name ? null : r.name))}\n data-testid={`env-var-delete-${r.name}`}\n aria-label={`Delete ${r.name}`}\n >\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n </Inline>\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"danger\" onClick={() => void drop(r.name)} data-testid={`env-var-confirm-delete-${r.name}`}>\n Confirm delete\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete(null)} data-testid={`env-var-cancel-delete-${r.name}`}>\n Cancel\n </Button>\n </Inline>\n )}\n {testResult !== null && testResult.name === r.name && (\n <div\n data-testid={`env-var-test-result-${r.name}`}\n style={{\n marginTop: 'var(--space-1)',\n fontSize: 'var(--fs-11)',\n color: testResult.ok ? 'var(--success)' : 'var(--danger)',\n fontFamily: 'var(--font-mono)',\n }}\n >\n test: {testResult.message}\n </div>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </CardBody>\n </Card>\n\n <Sheet open={adding} onOpenChange={setAdding}>\n <SheetContent side=\"right\" title=\"Add env var\" description=\"Must match /^BIZAR_[A-Z0-9_]+$/.\">\n <AddEditForm\n mode=\"add\"\n onSubmit={async (name, value) => {\n await fetchJson('/api/env-vars', { method: 'POST', body: { name, value } });\n setAdding(false);\n refresh();\n }}\n onCancel={() => setAdding(false)}\n />\n </SheetContent>\n </Sheet>\n\n <Sheet open={editing !== null} onOpenChange={(open) => { if (!open) setEditing(null); }}>\n <SheetContent side=\"right\" title=\"Edit env var\" description={editing ?? ''}>\n {editing !== null && (\n <AddEditForm\n mode=\"edit\"\n initialName={editing}\n onSubmit={async (name, value) => {\n await fetchJson(`/api/env-vars/${name}`, { method: 'PUT', body: { value } });\n setEditing(null);\n refresh();\n }}\n onCancel={() => setEditing(null)}\n />\n )}\n </SheetContent>\n </Sheet>\n\n <Sheet open={bulkImporting} onOpenChange={setBulkImporting}>\n <SheetContent side=\"right\" title=\"Bulk import\" description=\"Paste KEY=value lines (one per line, # comments ignored).\">\n <BulkImportForm\n onSubmit={async (envContent) => {\n await fetchJson('/api/env-vars/bulk-import', {\n method: 'POST',\n body: { envContent },\n });\n setBulkImporting(false);\n refresh();\n }}\n onCancel={() => setBulkImporting(false)}\n />\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}\n\nfunction AddEditForm({\n mode,\n initialName,\n onSubmit,\n onCancel,\n}: {\n mode: 'add' | 'edit';\n initialName?: string;\n onSubmit: (name: string, value: string) => Promise<void>;\n onCancel: () => void;\n}): JSX.Element {\n const [name, setName] = useState<string>(initialName ?? '');\n const [value, setValue] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n const submit = async (): Promise<void> => {\n if (!name.trim() || !value || busy) return;\n setBusy(true);\n setError(null);\n try {\n await onSubmit(name.trim(), value);\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Stack gap={3} style={{ padding: 'var(--space-4)' }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Name</span>\n <Input\n value={name}\n readOnly={mode === 'edit'}\n data-testid=\"env-var-form-name\"\n onChange={(e) => setName((e.target as HTMLInputElement).value)}\n />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Value</span>\n <Input\n type=\"password\"\n value={value}\n data-testid=\"env-var-form-value\"\n onChange={(e) => setValue((e.target as HTMLInputElement).value)}\n />\n </label>\n {error !== null && (\n <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Inline justify=\"end\" gap={2}>\n <SheetClose asChild>\n <Button variant=\"ghost\" onClick={onCancel} data-testid=\"env-var-form-cancel\">Cancel</Button>\n </SheetClose>\n <Button\n variant=\"primary\"\n onClick={() => void submit()}\n disabled={busy || !name.trim() || !value}\n data-testid=\"env-var-form-submit\"\n >\n {mode === 'add' ? 'Add' : 'Save'}\n </Button>\n </Inline>\n </Stack>\n );\n}\n\nfunction BulkImportForm({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (envContent: string) => Promise<void>;\n onCancel: () => void;\n}): JSX.Element {\n const [content, setContent] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n return (\n <Stack gap={3} style={{ padding: 'var(--space-4)' }}>\n <textarea\n value={content}\n placeholder={'BIZAR_FOO=bar\\nBIZAR_BAZ=qux\\n# comment'}\n rows={12}\n data-testid=\"env-vars-bulk-input\"\n onChange={(e) => setContent((e.target as HTMLTextAreaElement).value)}\n style={{\n background: 'var(--surface-0)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-md)',\n padding: 'var(--space-2)',\n color: 'var(--fg)',\n fontFamily: 'var(--font-mono)',\n fontSize: 'var(--fs-12)',\n resize: 'vertical',\n }}\n />\n {error !== null && (\n <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Inline justify=\"end\" gap={2}>\n <SheetClose asChild>\n <Button variant=\"ghost\" onClick={onCancel}>Cancel</Button>\n </SheetClose>\n <Button\n variant=\"primary\"\n onClick={async () => {\n setBusy(true);\n setError(null);\n try { await onSubmit(content); }\n catch (err) { setError(err instanceof FetchError ? err.message : (err as Error).message); }\n finally { setBusy(false); }\n }}\n disabled={busy || content.trim() === ''}\n data-testid=\"env-vars-bulk-submit\"\n >\n {busy ? 'Importing…' : 'Import'}\n </Button>\n </Inline>\n </Stack>\n );\n}"],"names":["FileUp","createLucideIcon","EnvVarsView","payload","useFetch","adding","setAdding","useState","editing","setEditing","bulkImporting","setBulkImporting","confirmDelete","setConfirmDelete","error","setError","testing","setTesting","testResult","setTestResult","rows","useMemo","refresh","useCallback","runTest","name","res","fetchJson","err","msg","FetchError","drop","jsxs","Stack","jsx","ViewHeader","Inline","Button","Download","RefreshCcw","Plus","ListHeader","Card","CardBody","Skeleton","EmptyState","Variable","r","isConfirming","FlaskConical","Pencil","cur","Trash2","Sheet","SheetContent","AddEditForm","value","open","BulkImportForm","envContent","mode","initialName","onSubmit","onCancel","setName","setValue","busy","setBusy","submit","Input","e","SheetClose","content","setContent"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"EnvVarsView-DySOXlP1.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/file-up.js","../../src/web/v8/views/EnvVars/EnvVarsView.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileUp = createLucideIcon(\"FileUp\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M12 12v6\", key: \"3ahymv\" }],\n [\"path\", { d: \"m15 15-3-3-3 3\", key: \"15xj92\" }]\n]);\n\nexport { FileUp as default };\n//# sourceMappingURL=file-up.js.map\n","/**\n * v8/views/EnvVars/EnvVarsView.tsx — Sprint S41, v9.3.0.\n *\n * List of env vars (masked values) with: per-row edit (Sheet),\n * per-row delete (inline confirm), Add Sheet, Bulk Import Sheet,\n * and Export trigger. Backed by /api/env-vars + /api/env-vars/grouped\n * + /api/env-vars/export + /api/env-vars/bulk-import.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { Download, FileUp, FlaskConical, Pencil, Plus, RefreshCcw, Trash2, Variable } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { ListHeader } from '../../ui/data/ListHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Sheet, SheetClose, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\ninterface EnvRow {\n name: string;\n value: string;\n createdAt?: string;\n source?: string;\n}\n\nexport function EnvVarsView(): JSX.Element {\n const payload = useFetch<EnvRow[]>('/api/env-vars');\n const [adding, setAdding] = useState<boolean>(false);\n const [editing, setEditing] = useState<string | null>(null);\n const [bulkImporting, setBulkImporting] = useState<boolean>(false);\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [testing, setTesting] = useState<string | null>(null);\n const [testResult, setTestResult] = useState<{ name: string; ok: boolean; message: string } | null>(null);\n\n const rows = useMemo<EnvRow[]>(() => payload.data ?? [], [payload.data]);\n\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n\n const runTest = async (name: string): Promise<void> => {\n setTesting(name);\n setError(null);\n try {\n const res = await fetchJson<{ ok?: boolean; status?: string; message?: string }>(`/api/env-vars/${encodeURIComponent(name)}/test`, { method: 'POST' });\n setTestResult({ name, ok: res.ok !== false, message: res.message ?? (res.ok !== false ? 'OK' : 'Failed') });\n } catch (err) {\n const msg = err instanceof FetchError ? err.message : (err as Error).message;\n setTestResult({ name, ok: false, message: msg });\n } finally {\n setTesting(null);\n }\n };\n\n const drop = async (name: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/env-vars/${name}`, { method: 'DELETE' });\n setConfirmDelete(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n return (\n <Stack gap={4} data-testid=\"env-vars-view\">\n <ViewHeader\n title=\"Env vars\"\n description=\"Runtime environment variables for the dashboard. Stored in ~/.config/bizar/env.json (mode 0600).\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"env-vars-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => { window.open('/api/env-vars/export', '_blank'); }} data-testid=\"env-vars-export\">\n <Download size={14} aria-hidden /> Export\n </Button>\n <Button variant=\"ghost\" onClick={() => setBulkImporting(true)} data-testid=\"env-vars-bulk-import\">\n <FileUp size={14} aria-hidden /> Bulk import\n </Button>\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"env-vars-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => setAdding(true)} data-testid=\"env-vars-add\">\n <Plus size={14} aria-hidden /> Add\n </Button>\n </Inline>\n }\n />\n <ListHeader title=\"Variables\" count={rows.length} testid=\"env-vars-list-header\" />\n\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && rows.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 36 }} />\n <Skeleton style={{ height: 36 }} />\n </Stack>\n ) : rows.length === 0 ? (\n <EmptyState\n icon={<Variable size={28} aria-hidden />}\n title=\"No env vars\"\n description=\"Add one or bulk-import a .env file.\"\n />\n ) : (\n <Stack gap={1}>\n {rows.map((r) => {\n const isConfirming = confirmDelete === r.name;\n return (\n <div\n key={r.name}\n data-testid={`env-var-row-${r.name}`}\n style={{\n padding: 'var(--space-2)',\n borderRadius: 'var(--radius-sm)',\n border: '1px solid var(--border)',\n background: 'var(--surface-0)',\n }}\n >\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Stack gap={0} style={{ minWidth: 0 }}>\n <code style={{ fontSize: 'var(--fs-12)' }}>{r.name}</code>\n <code style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{r.value}</code>\n {r.source && (\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>\n source: {r.source} {r.createdAt ? `· ${r.createdAt}` : ''}\n </span>\n )}\n </Stack>\n <Inline gap={1}>\n <Button\n variant=\"ghost\"\n onClick={() => void runTest(r.name)}\n disabled={testing === r.name}\n data-testid={`env-var-test-${r.name}`}\n aria-label={`Test ${r.name}`}\n >\n <FlaskConical size={14} aria-hidden />\n </Button>\n <Button variant=\"ghost\" onClick={() => setEditing(r.name)} data-testid={`env-var-edit-${r.name}`} aria-label={`Edit ${r.name}`}>\n <Pencil size={14} aria-hidden />\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => setConfirmDelete((cur) => (cur === r.name ? null : r.name))}\n data-testid={`env-var-delete-${r.name}`}\n aria-label={`Delete ${r.name}`}\n >\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n </Inline>\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"danger\" onClick={() => void drop(r.name)} data-testid={`env-var-confirm-delete-${r.name}`}>\n Confirm delete\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete(null)} data-testid={`env-var-cancel-delete-${r.name}`}>\n Cancel\n </Button>\n </Inline>\n )}\n {testResult !== null && testResult.name === r.name && (\n <div\n data-testid={`env-var-test-result-${r.name}`}\n style={{\n marginTop: 'var(--space-1)',\n fontSize: 'var(--fs-11)',\n color: testResult.ok ? 'var(--success)' : 'var(--danger)',\n fontFamily: 'var(--font-mono)',\n }}\n >\n test: {testResult.message}\n </div>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </CardBody>\n </Card>\n\n <Sheet open={adding} onOpenChange={setAdding}>\n <SheetContent side=\"right\" title=\"Add env var\" description=\"Must match /^BIZAR_[A-Z0-9_]+$/.\">\n <AddEditForm\n mode=\"add\"\n onSubmit={async (name, value) => {\n await fetchJson('/api/env-vars', { method: 'POST', body: { name, value } });\n setAdding(false);\n refresh();\n }}\n onCancel={() => setAdding(false)}\n />\n </SheetContent>\n </Sheet>\n\n <Sheet open={editing !== null} onOpenChange={(open) => { if (!open) setEditing(null); }}>\n <SheetContent side=\"right\" title=\"Edit env var\" description={editing ?? ''}>\n {editing !== null && (\n <AddEditForm\n mode=\"edit\"\n initialName={editing}\n onSubmit={async (name, value) => {\n await fetchJson(`/api/env-vars/${name}`, { method: 'PUT', body: { value } });\n setEditing(null);\n refresh();\n }}\n onCancel={() => setEditing(null)}\n />\n )}\n </SheetContent>\n </Sheet>\n\n <Sheet open={bulkImporting} onOpenChange={setBulkImporting}>\n <SheetContent side=\"right\" title=\"Bulk import\" description=\"Paste KEY=value lines (one per line, # comments ignored).\">\n <BulkImportForm\n onSubmit={async (envContent) => {\n await fetchJson('/api/env-vars/bulk-import', {\n method: 'POST',\n body: { envContent },\n });\n setBulkImporting(false);\n refresh();\n }}\n onCancel={() => setBulkImporting(false)}\n />\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}\n\nfunction AddEditForm({\n mode,\n initialName,\n onSubmit,\n onCancel,\n}: {\n mode: 'add' | 'edit';\n initialName?: string;\n onSubmit: (name: string, value: string) => Promise<void>;\n onCancel: () => void;\n}): JSX.Element {\n const [name, setName] = useState<string>(initialName ?? '');\n const [value, setValue] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n const submit = async (): Promise<void> => {\n if (!name.trim() || !value || busy) return;\n setBusy(true);\n setError(null);\n try {\n await onSubmit(name.trim(), value);\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Stack gap={3} style={{ padding: 'var(--space-4)' }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Name</span>\n <Input\n value={name}\n readOnly={mode === 'edit'}\n data-testid=\"env-var-form-name\"\n onChange={(e) => setName((e.target as HTMLInputElement).value)}\n />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Value</span>\n <Input\n type=\"password\"\n value={value}\n data-testid=\"env-var-form-value\"\n onChange={(e) => setValue((e.target as HTMLInputElement).value)}\n />\n </label>\n {error !== null && (\n <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Inline justify=\"end\" gap={2}>\n <SheetClose asChild>\n <Button variant=\"ghost\" onClick={onCancel} data-testid=\"env-var-form-cancel\">Cancel</Button>\n </SheetClose>\n <Button\n variant=\"primary\"\n onClick={() => void submit()}\n disabled={busy || !name.trim() || !value}\n data-testid=\"env-var-form-submit\"\n >\n {mode === 'add' ? 'Add' : 'Save'}\n </Button>\n </Inline>\n </Stack>\n );\n}\n\nfunction BulkImportForm({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (envContent: string) => Promise<void>;\n onCancel: () => void;\n}): JSX.Element {\n const [content, setContent] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n return (\n <Stack gap={3} style={{ padding: 'var(--space-4)' }}>\n <textarea\n value={content}\n placeholder={'BIZAR_FOO=bar\\nBIZAR_BAZ=qux\\n# comment'}\n rows={12}\n data-testid=\"env-vars-bulk-input\"\n onChange={(e) => setContent((e.target as HTMLTextAreaElement).value)}\n style={{\n background: 'var(--surface-0)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-md)',\n padding: 'var(--space-2)',\n color: 'var(--fg)',\n fontFamily: 'var(--font-mono)',\n fontSize: 'var(--fs-12)',\n resize: 'vertical',\n }}\n />\n {error !== null && (\n <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Inline justify=\"end\" gap={2}>\n <SheetClose asChild>\n <Button variant=\"ghost\" onClick={onCancel}>Cancel</Button>\n </SheetClose>\n <Button\n variant=\"primary\"\n onClick={async () => {\n setBusy(true);\n setError(null);\n try { await onSubmit(content); }\n catch (err) { setError(err instanceof FetchError ? err.message : (err as Error).message); }\n finally { setBusy(false); }\n }}\n disabled={busy || content.trim() === ''}\n data-testid=\"env-vars-bulk-submit\"\n >\n {busy ? 'Importing…' : 'Import'}\n </Button>\n </Inline>\n </Stack>\n );\n}"],"names":["FileUp","createLucideIcon","EnvVarsView","payload","useFetch","adding","setAdding","useState","editing","setEditing","bulkImporting","setBulkImporting","confirmDelete","setConfirmDelete","error","setError","testing","setTesting","testResult","setTestResult","rows","useMemo","refresh","useCallback","runTest","name","res","fetchJson","err","msg","FetchError","drop","jsxs","Stack","jsx","ViewHeader","Inline","Button","Download","RefreshCcw","Plus","ListHeader","Card","CardBody","Skeleton","EmptyState","Variable","r","isConfirming","FlaskConical","Pencil","cur","Trash2","Sheet","SheetContent","AddEditForm","value","open","BulkImportForm","envContent","mode","initialName","onSubmit","onCancel","setName","setValue","busy","setBusy","submit","Input","e","SheetClose","content","setContent"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as h,j as e}from"./cmdk-DVxytz9i.js";import{A as y}from"./Alert-
|
|
1
|
+
import{r as h,j as e}from"./cmdk-DVxytz9i.js";import{A as y}from"./Alert-Dg_Vwxh5.js";import{d as f}from"./main-CyAIirBB.js";import{C as j}from"./circle-alert-CQ9MLygI.js";import{R as v}from"./refresh-ccw-BCXx86xp.js";function u(t){return t==null?"":typeof t=="string"?t:t.message}const b=h.forwardRef(function(m,n){const{title:o="Something went wrong",description:s,error:x,onRetry:r,retryLabel:a="Retry",block:p=!1,silent:g=!1,testid:d,className:l,...c}=m,i=g?"":u(x);return p?e.jsxs("div",{ref:n,"data-testid":d??"error-state",className:l,style:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"var(--space-3)",padding:"var(--space-12) var(--space-6)",textAlign:"center",color:"var(--fg-muted)"},...c,children:[e.jsx("div",{style:{color:"var(--danger)",display:"inline-flex"},children:e.jsx(j,{size:28,"aria-hidden":!0})}),e.jsx("div",{style:{fontSize:"var(--fs-16)",fontWeight:600,color:"var(--fg)"},children:o}),s!==void 0&&e.jsx("div",{style:{fontSize:"var(--fs-13)",maxWidth:480},children:s}),i!==""&&e.jsx("code",{style:{fontSize:"var(--fs-12)",color:"var(--fg-subtle)"},children:i}),r!==void 0&&e.jsxs(f,{variant:"primary",onClick:r,"data-testid":"error-state-retry",children:[e.jsx(v,{size:14,"aria-hidden":!0})," ",a]})]}):e.jsx("div",{ref:n,"data-testid":d??"error-state",className:l,...c,children:e.jsxs(y,{tone:"danger",title:o,action:r!==void 0?e.jsxs(f,{variant:"ghost",onClick:r,"data-testid":"error-state-retry","aria-label":a,children:[e.jsx(v,{size:14,"aria-hidden":!0})," ",a]}):void 0,children:[s,i!==""&&e.jsx("div",{style:{marginTop:"var(--space-1)",fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)"},children:i})]})})});export{b as E};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorState-
|
|
1
|
+
{"version":3,"file":"ErrorState-Bump8diE.js","sources":["../../src/web/v8/ui/feedback/ErrorState.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { AlertCircle, RefreshCcw } from 'lucide-react';\nimport { Alert } from './Alert.js';\nimport { Button } from '../controls/Button.js';\n\n/**\n * ErrorState — surfaced error with optional retry CTA.\n *\n * Use when a view's primary fetch failed and we want to recover,\n * not when the fetch succeeded with zero rows (use EmptyState).\n *\n * Two layout modes:\n * - inline (default): Alert-tone=danger banner with optional retry button\n * - block: centered icon + title + description + retry (mirrors EmptyState)\n *\n * `error` is the raw error (Error | string | null). When non-null,\n * the message is rendered below the title. Use the `silent` flag to\n * omit the message (e.g. when the parent already shows it).\n */\nexport interface ErrorStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title?: ReactNode;\n description?: ReactNode;\n error?: Error | string | null;\n onRetry?: () => void;\n retryLabel?: string;\n /** Use the centered block layout instead of the inline Alert. */\n block?: boolean;\n /** Hide the error message (parent surfaces it elsewhere). */\n silent?: boolean;\n testid?: string;\n}\n\nfunction errMessage(error: Error | string | null | undefined): string {\n if (error === null || error === undefined) return '';\n return typeof error === 'string' ? error : error.message;\n}\n\nexport const ErrorState = forwardRef<HTMLDivElement, ErrorStateProps>(function ErrorState(\n props,\n ref,\n) {\n const {\n title = 'Something went wrong',\n description,\n error,\n onRetry,\n retryLabel = 'Retry',\n block = false,\n silent = false,\n testid,\n className,\n ...rest\n } = props;\n\n const message = silent ? '' : errMessage(error);\n\n if (block) {\n return (\n <div\n ref={ref}\n data-testid={testid ?? 'error-state'}\n className={className}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--space-3)',\n padding: 'var(--space-12) var(--space-6)',\n textAlign: 'center',\n color: 'var(--fg-muted)',\n }}\n {...rest}\n >\n <div style={{ color: 'var(--danger)', display: 'inline-flex' }}>\n <AlertCircle size={28} aria-hidden />\n </div>\n <div style={{ fontSize: 'var(--fs-16)', fontWeight: 600, color: 'var(--fg)' }}>{title}</div>\n {description !== undefined && (\n <div style={{ fontSize: 'var(--fs-13)', maxWidth: 480 }}>{description}</div>\n )}\n {message !== '' && (\n <code style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>{message}</code>\n )}\n {onRetry !== undefined && (\n <Button variant=\"primary\" onClick={onRetry} data-testid=\"error-state-retry\">\n <RefreshCcw size={14} aria-hidden /> {retryLabel}\n </Button>\n )}\n </div>\n );\n }\n\n return (\n <div ref={ref} data-testid={testid ?? 'error-state'} className={className} {...rest}>\n <Alert\n tone=\"danger\"\n title={title}\n action={\n onRetry !== undefined ? (\n <Button variant=\"ghost\" onClick={onRetry} data-testid=\"error-state-retry\" aria-label={retryLabel}>\n <RefreshCcw size={14} aria-hidden /> {retryLabel}\n </Button>\n ) : undefined\n }\n >\n {description}\n {message !== '' && (\n <div style={{ marginTop: 'var(--space-1)', fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)' }}>\n {message}\n </div>\n )}\n </Alert>\n </div>\n );\n});"],"names":["errMessage","error","ErrorState","forwardRef","props","ref","title","description","onRetry","retryLabel","block","silent","testid","className","rest","message","jsxs","jsx","AlertCircle","Button","RefreshCcw","Alert"],"mappings":"0NAgCA,SAASA,EAAWC,EAAkD,CACpE,OAAIA,GAAU,KAAoC,GAC3C,OAAOA,GAAU,SAAWA,EAAQA,EAAM,OACnD,CAEO,MAAMC,EAAaC,EAAAA,WAA4C,SACpEC,EACAC,EACA,CACA,KAAM,CACJ,MAAAC,EAAQ,uBACR,YAAAC,EACA,MAAAN,EACA,QAAAO,EACA,WAAAC,EAAa,QACb,MAAAC,EAAQ,GACR,OAAAC,EAAS,GACT,OAAAC,EACA,UAAAC,EACA,GAAGC,CAAA,EACDV,EAEEW,EAAUJ,EAAS,GAAKX,EAAWC,CAAK,EAE9C,OAAIS,EAEAM,EAAAA,KAAC,MAAA,CACC,IAAAX,EACA,cAAaO,GAAU,cACvB,UAAAC,EACA,MAAO,CACL,QAAS,OACT,cAAe,SACf,WAAY,SACZ,eAAgB,SAChB,IAAK,iBACL,QAAS,iCACT,UAAW,SACX,MAAO,iBAAA,EAER,GAAGC,EAEJ,SAAA,CAAAG,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,MAAO,gBAAiB,QAAS,aAAA,EAC7C,SAAAA,EAAAA,IAACC,EAAA,CAAY,KAAM,GAAI,cAAW,GAAC,EACrC,EACAD,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,WAAY,IAAK,MAAO,WAAA,EAAgB,SAAAX,CAAA,CAAM,EACrFC,IAAgB,QACfU,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,SAAU,GAAA,EAAQ,SAAAV,CAAA,CAAY,EAEvEQ,IAAY,IACXE,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,kBAAA,EAAuB,SAAAF,CAAA,CAAQ,EAEhFP,IAAY,QACXQ,OAACG,EAAA,CAAO,QAAQ,UAAU,QAASX,EAAS,cAAY,oBACtD,SAAA,CAAAS,EAAAA,IAACG,EAAA,CAAW,KAAM,GAAI,cAAW,GAAC,EAAE,IAAEX,CAAA,CAAA,CACxC,CAAA,CAAA,CAAA,EAONQ,MAAC,OAAI,IAAAZ,EAAU,cAAaO,GAAU,cAAe,UAAAC,EAAuB,GAAGC,EAC7E,SAAAE,EAAAA,KAACK,EAAA,CACC,KAAK,SACL,MAAAf,EACA,OACEE,IAAY,OACVQ,EAAAA,KAACG,EAAA,CAAO,QAAQ,QAAQ,QAASX,EAAS,cAAY,oBAAoB,aAAYC,EACpF,SAAA,CAAAQ,EAAAA,IAACG,EAAA,CAAW,KAAM,GAAI,cAAW,GAAC,EAAE,IAAEX,CAAA,CAAA,CACxC,EACE,OAGL,SAAA,CAAAF,EACAQ,IAAY,IACXE,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,UAAW,iBAAkB,WAAY,mBAAoB,SAAU,cAAA,EAClF,SAAAF,CAAA,CACH,CAAA,CAAA,CAAA,EAGN,CAEJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,j as e}from"./cmdk-DVxytz9i.js";import{u as P,S as i,I as s,d,J as
|
|
1
|
+
import{r,j as e}from"./cmdk-DVxytz9i.js";import{u as P,S as i,I as s,d,J as N,h as T,N as q,B as f,i as j,F as y}from"./main-CyAIirBB.js";import{V as I}from"./ViewHeader-V_SzbUpw.js";import{C as R,b as $}from"./Card-D9019JOD.js";import{E as M}from"./EmptyState-DLmtBX_6.js";import{P as V}from"./play-CGxZWqtW.js";import{R as J}from"./refresh-cw-COTg1nZo.js";import{C as O}from"./calendar-VntJUzFB.js";import{P as H}from"./plus-fFxt-8z5.js";import{T as U}from"./trash-2-2NsyTU8c.js";function W(t){return t==="done"?"success":t==="failed"?"danger":t==="running"?"info":t==="queued"?"warning":"neutral"}function G(t){return!t||t<=0?"—":t<1e3?`${t}ms`:t<6e4?`${(t/1e3).toFixed(1)}s`:`${Math.floor(t/6e4)}m ${Math.round(t%6e4/1e3)}s`}function ne(){var E,F;const t=P("/api/eval/runs?limit=20"),g=P("/api/eval/schedules"),[o,b]=r.useState(!1),[v,A]=r.useState("default"),[C,l]=r.useState(null),[z,m]=r.useState(!1),[n,c]=r.useState({name:"",cron:"",suitePath:"default"}),[w,k]=r.useState(!1);r.useEffect(()=>{var a;if((a=t.data)!=null&&a.runs&&t.data.runs.some(h=>h.status==="running"||h.status==="queued")){const h=setTimeout(()=>{t.refetch()},5e3);return()=>clearTimeout(h)}},[t]);const L=async()=>{b(!0),l(null);try{await j("/api/eval/run",{method:"POST",body:{suite:v}}),t.refetch()}catch(a){l((a instanceof y,a.message))}finally{b(!1)}},p=((E=t.data)==null?void 0:E.runs)??[],B=async()=>{if(!(!n.name.trim()||!n.cron.trim())){k(!0),l(null);try{await j("/api/eval/schedules",{method:"POST",body:n}),m(!1),c({name:"",cron:"",suitePath:"default"}),g.refetch()}catch(a){l((a instanceof y,a.message))}finally{k(!1)}}},D=async a=>{l(null);try{await j(`/api/eval/schedules/${encodeURIComponent(a)}`,{method:"DELETE"}),g.refetch()}catch(u){l((u instanceof y,u.message))}},x=((F=g.data)==null?void 0:F.schedules)??[];return e.jsxs(i,{gap:5,"data-testid":"eval-view",children:[e.jsx(I,{title:"Eval framework",description:"Run evaluation suites against the agent model. Suites live under fixtures/.",actions:e.jsxs(s,{gap:2,align:"center",children:[C!==null&&e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:C}),e.jsx("input",{value:v,onChange:a=>A(a.target.value),placeholder:"suite name",disabled:o,"data-testid":"eval-suite-input",style:{padding:"6px 10px",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",background:"var(--surface-0)",color:"var(--fg)",fontSize:"var(--fs-13)",fontFamily:"var(--font-mono)"}}),e.jsxs(d,{variant:"primary",onClick:()=>void L(),disabled:o||!v.trim(),"data-testid":"eval-launch",children:[o?e.jsx(N,{size:14,className:"animate-spin","aria-hidden":!0}):e.jsx(V,{size:14,"aria-hidden":!0}),o?"Launching…":"Run suite"]}),e.jsxs(d,{variant:"ghost",onClick:()=>void t.refetch(),"data-testid":"eval-refresh",children:[e.jsx(J,{size:14,"aria-hidden":!0})," Refresh"]})]})}),t.loading&&p.length===0?e.jsxs(i,{gap:2,children:[e.jsx(T,{style:{height:80}}),e.jsx(T,{style:{height:80}})]}):p.length===0?e.jsx(M,{icon:e.jsx(q,{size:32,"aria-hidden":!0}),title:"No eval runs yet",description:"Launch a suite to begin measuring agent quality."}):e.jsx(i,{gap:2,children:p.map(a=>e.jsx(R,{variant:"default",children:e.jsx($,{children:e.jsxs(s,{align:"center",justify:"between",gap:3,children:[e.jsxs(i,{gap:1,style:{flex:1,minWidth:0},children:[e.jsxs(s,{align:"center",gap:2,children:[e.jsx("strong",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-13)"},children:a.id}),e.jsx(f,{tone:W(a.status),children:a.status??"unknown"}),a.suite&&e.jsx(f,{tone:"neutral",children:a.suite})]}),e.jsxs(s,{align:"center",gap:3,style:{color:"var(--fg-muted)",fontSize:"var(--fs-12)"},children:[e.jsx("span",{children:a.startedAt?new Date(a.startedAt).toLocaleString():""}),e.jsx("span",{children:G(a.durationMs)})]})]}),e.jsxs(i,{align:"end",gap:0,children:[e.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-14)"},children:[e.jsx("strong",{style:{color:"var(--success)"},children:a.passed??0})," pass"," / ",e.jsx("strong",{style:{color:"var(--danger)"},children:a.failed??0})," fail"]}),e.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:[a.total??0," total"]})]})]})})},a.id))}),e.jsx(R,{variant:"elevated",children:e.jsxs($,{children:[e.jsxs(s,{align:"center",justify:"between",gap:2,children:[e.jsxs(s,{align:"center",gap:2,children:[e.jsx(O,{size:16,"aria-hidden":!0}),e.jsx("strong",{style:{fontSize:"var(--fs-14)"},children:"Schedules"}),e.jsx(f,{tone:"neutral",children:x.length})]}),!z&&e.jsxs(d,{variant:"primary",onClick:()=>m(!0),"data-testid":"eval-schedule-add",children:[e.jsx(H,{size:14,"aria-hidden":!0})," Add schedule"]})]}),z&&e.jsxs(i,{gap:2,style:{marginTop:"var(--space-3)"},"data-testid":"eval-schedule-form",children:[e.jsxs(s,{gap:2,align:"center",children:[e.jsx("input",{value:n.name,onChange:a=>c({...n,name:a.target.value}),placeholder:"name","data-testid":"eval-schedule-form-name",style:S}),e.jsx("input",{value:n.cron,onChange:a=>c({...n,cron:a.target.value}),placeholder:"cron (e.g. 0 9 * * *)","data-testid":"eval-schedule-form-cron",style:S}),e.jsx("input",{value:n.suitePath,onChange:a=>c({...n,suitePath:a.target.value}),placeholder:"suite path","data-testid":"eval-schedule-form-suite",style:S})]}),e.jsxs(s,{gap:2,children:[e.jsx(d,{variant:"primary",onClick:()=>void B(),disabled:w,"data-testid":"eval-schedule-form-submit",children:w?"Saving…":"Save"}),e.jsx(d,{variant:"ghost",onClick:()=>m(!1),"data-testid":"eval-schedule-form-cancel",children:"Cancel"})]})]}),x.length===0?e.jsx("div",{style:{marginTop:"var(--space-2)",fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"No schedules yet. Add one to run suites on a cron."}):e.jsx(i,{gap:2,style:{marginTop:"var(--space-3)"},children:x.map(a=>e.jsxs(s,{align:"center",justify:"between",gap:2,"data-testid":`eval-schedule-row-${a.id}`,children:[e.jsxs(s,{align:"center",gap:2,children:[e.jsx("strong",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-13)"},children:a.name}),e.jsx("code",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:a.cron}),a.suitePath&&e.jsx(f,{tone:"neutral",children:a.suitePath})]}),e.jsx(d,{variant:"ghost",onClick:()=>void D(a.id),"data-testid":`eval-schedule-delete-${a.id}`,"aria-label":`Delete schedule ${a.name}`,children:e.jsx(U,{size:14,"aria-hidden":!0})})]},a.id))})]})})]})}const S={padding:"6px 10px",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",background:"var(--surface-0)",color:"var(--fg)",fontSize:"var(--fs-13)",fontFamily:"var(--font-mono)"};export{ne as EvalView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EvalView-C9aYixXW.js","sources":["../../src/web/v8/views/Eval/EvalView.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { Calendar, FlaskConical, Play, Plus, RefreshCw, Trash2, Loader2 } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Badge } from '../../ui/data/Badge.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\n/**\n * EvalView — Sprint S35. Eval runs list + launch new suite.\n */\n\ntype Tone = 'neutral' | 'success' | 'warning' | 'danger' | 'info';\n\ninterface EvalRun {\n id: string;\n suite?: string;\n status?: 'queued' | 'running' | 'done' | 'failed';\n passed?: number;\n failed?: number;\n total?: number;\n startedAt?: string;\n durationMs?: number;\n}\n\ninterface EvalSchedule {\n id: string;\n name: string;\n cron: string;\n suitePath?: string;\n enabled?: boolean;\n}\n\nfunction statusTone(s: EvalRun['status'] | undefined): Tone {\n if (s === 'done') return 'success';\n if (s === 'failed') return 'danger';\n if (s === 'running') return 'info';\n if (s === 'queued') return 'warning';\n return 'neutral';\n}\n\nfunction fmtDuration(ms: number | undefined): string {\n if (!ms || ms <= 0) return '—';\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n return `${Math.floor(ms / 60_000)}m ${Math.round((ms % 60_000) / 1000)}s`;\n}\n\nexport function EvalView(): JSX.Element {\n const runs = useFetch<{ runs: EvalRun[] }>('/api/eval/runs?limit=20');\n const schedules = useFetch<{ schedules: EvalSchedule[] }>('/api/eval/schedules');\n const [launching, setLaunching] = useState(false);\n const [suite, setSuite] = useState('default');\n const [error, setError] = useState<string | null>(null);\n const [addingSchedule, setAddingSchedule] = useState(false);\n const [scheduleForm, setScheduleForm] = useState({ name: '', cron: '', suitePath: 'default' });\n const [busySchedule, setBusySchedule] = useState(false);\n\n useEffect(() => {\n if (runs.data?.runs) {\n const hasActive = runs.data.runs.some((r) => r.status === 'running' || r.status === 'queued');\n if (hasActive) {\n const id = setTimeout(() => { void runs.refetch(); }, 5_000);\n return () => clearTimeout(id);\n }\n }\n }, [runs]);\n\n const launch = async (): Promise<void> => {\n setLaunching(true);\n setError(null);\n try {\n await fetchJson('/api/eval/run', { method: 'POST', body: { suite } });\n void runs.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setLaunching(false);\n }\n };\n\n const list = runs.data?.runs ?? [];\n\n const addSchedule = async (): Promise<void> => {\n if (!scheduleForm.name.trim() || !scheduleForm.cron.trim()) return;\n setBusySchedule(true);\n setError(null);\n try {\n await fetchJson<{ ok?: boolean }>('/api/eval/schedules', { method: 'POST', body: scheduleForm });\n setAddingSchedule(false);\n setScheduleForm({ name: '', cron: '', suitePath: 'default' });\n void schedules.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusySchedule(false);\n }\n };\n\n const deleteSchedule = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/eval/schedules/${encodeURIComponent(id)}`, { method: 'DELETE' });\n void schedules.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const scheduleList = schedules.data?.schedules ?? [];\n\n return (\n <Stack gap={5} data-testid=\"eval-view\">\n <ViewHeader\n title=\"Eval framework\"\n description=\"Run evaluation suites against the agent model. Suites live under fixtures/.\"\n actions={\n <Inline gap={2} align=\"center\">\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <input\n value={suite}\n onChange={(e) => setSuite(e.target.value)}\n placeholder=\"suite name\"\n disabled={launching}\n data-testid=\"eval-suite-input\"\n style={{\n padding: '6px 10px',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: 'var(--surface-0)',\n color: 'var(--fg)',\n fontSize: 'var(--fs-13)',\n fontFamily: 'var(--font-mono)',\n }}\n />\n <Button variant=\"primary\" onClick={() => void launch()} disabled={launching || !suite.trim()} data-testid=\"eval-launch\">\n {launching ? <Loader2 size={14} className=\"animate-spin\" aria-hidden /> : <Play size={14} aria-hidden />}\n {launching ? 'Launching…' : 'Run suite'}\n </Button>\n <Button variant=\"ghost\" onClick={() => void runs.refetch()} data-testid=\"eval-refresh\">\n <RefreshCw size={14} aria-hidden /> Refresh\n </Button>\n </Inline>\n }\n />\n\n {runs.loading && list.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 80 }} />\n <Skeleton style={{ height: 80 }} />\n </Stack>\n ) : list.length === 0 ? (\n <EmptyState\n icon={<FlaskConical size={32} aria-hidden />}\n title=\"No eval runs yet\"\n description=\"Launch a suite to begin measuring agent quality.\"\n />\n ) : (\n <Stack gap={2}>\n {list.map((r) => (\n <Card key={r.id} variant=\"default\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={3}>\n <Stack gap={1} style={{ flex: 1, minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-13)' }}>{r.id}</strong>\n <Badge tone={statusTone(r.status)}>{r.status ?? 'unknown'}</Badge>\n {r.suite && <Badge tone=\"neutral\">{r.suite}</Badge>}\n </Inline>\n <Inline align=\"center\" gap={3} style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-12)' }}>\n <span>{r.startedAt ? new Date(r.startedAt).toLocaleString() : ''}</span>\n <span>{fmtDuration(r.durationMs)}</span>\n </Inline>\n </Stack>\n <Stack align=\"end\" gap={0}>\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-14)' }}>\n <strong style={{ color: 'var(--success)' }}>{r.passed ?? 0}</strong> pass\n {' / '}\n <strong style={{ color: 'var(--danger)' }}>{r.failed ?? 0}</strong> fail\n </span>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{(r.total ?? 0)} total</span>\n </Stack>\n </Inline>\n </CardBody>\n </Card>\n ))}\n </Stack>\n )}\n\n <Card variant=\"elevated\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Inline align=\"center\" gap={2}>\n <Calendar size={16} aria-hidden />\n <strong style={{ fontSize: 'var(--fs-14)' }}>Schedules</strong>\n <Badge tone=\"neutral\">{scheduleList.length}</Badge>\n </Inline>\n {!addingSchedule && (\n <Button variant=\"primary\" onClick={() => setAddingSchedule(true)} data-testid=\"eval-schedule-add\">\n <Plus size={14} aria-hidden /> Add schedule\n </Button>\n )}\n </Inline>\n\n {addingSchedule && (\n <Stack gap={2} style={{ marginTop: 'var(--space-3)' }} data-testid=\"eval-schedule-form\">\n <Inline gap={2} align=\"center\">\n <input\n value={scheduleForm.name}\n onChange={(e) => setScheduleForm({ ...scheduleForm, name: e.target.value })}\n placeholder=\"name\"\n data-testid=\"eval-schedule-form-name\"\n style={inputStyle}\n />\n <input\n value={scheduleForm.cron}\n onChange={(e) => setScheduleForm({ ...scheduleForm, cron: e.target.value })}\n placeholder=\"cron (e.g. 0 9 * * *)\"\n data-testid=\"eval-schedule-form-cron\"\n style={inputStyle}\n />\n <input\n value={scheduleForm.suitePath}\n onChange={(e) => setScheduleForm({ ...scheduleForm, suitePath: e.target.value })}\n placeholder=\"suite path\"\n data-testid=\"eval-schedule-form-suite\"\n style={inputStyle}\n />\n </Inline>\n <Inline gap={2}>\n <Button variant=\"primary\" onClick={() => void addSchedule()} disabled={busySchedule} data-testid=\"eval-schedule-form-submit\">\n {busySchedule ? 'Saving…' : 'Save'}\n </Button>\n <Button variant=\"ghost\" onClick={() => setAddingSchedule(false)} data-testid=\"eval-schedule-form-cancel\">Cancel</Button>\n </Inline>\n </Stack>\n )}\n\n {scheduleList.length === 0 ? (\n <div style={{ marginTop: 'var(--space-2)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n No schedules yet. Add one to run suites on a cron.\n </div>\n ) : (\n <Stack gap={2} style={{ marginTop: 'var(--space-3)' }}>\n {scheduleList.map((s) => (\n <Inline key={s.id} align=\"center\" justify=\"between\" gap={2} data-testid={`eval-schedule-row-${s.id}`}>\n <Inline align=\"center\" gap={2}>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-13)' }}>{s.name}</strong>\n <code style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{s.cron}</code>\n {s.suitePath && <Badge tone=\"neutral\">{s.suitePath}</Badge>}\n </Inline>\n <Button variant=\"ghost\" onClick={() => void deleteSchedule(s.id)} data-testid={`eval-schedule-delete-${s.id}`} aria-label={`Delete schedule ${s.name}`}>\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n ))}\n </Stack>\n )}\n </CardBody>\n </Card>\n </Stack>\n );\n}\n\nconst inputStyle = {\n padding: '6px 10px',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: 'var(--surface-0)',\n color: 'var(--fg)',\n fontSize: 'var(--fs-13)',\n fontFamily: 'var(--font-mono)',\n} as const;"],"names":["statusTone","s","fmtDuration","ms","EvalView","runs","useFetch","schedules","launching","setLaunching","useState","suite","setSuite","error","setError","addingSchedule","setAddingSchedule","scheduleForm","setScheduleForm","busySchedule","setBusySchedule","useEffect","_a","r","id","launch","fetchJson","err","FetchError","list","addSchedule","deleteSchedule","scheduleList","_b","jsxs","Stack","jsx","ViewHeader","Inline","e","Button","Loader2","Play","RefreshCw","Skeleton","EmptyState","FlaskConical","Card","CardBody","Badge","Calendar","Plus","inputStyle","Trash2"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EvalView-FnZ5d93z.js","sources":["../../src/web/v8/views/Eval/EvalView.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { Calendar, FlaskConical, Play, Plus, RefreshCw, Trash2, Loader2 } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Badge } from '../../ui/data/Badge.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\n/**\n * EvalView — Sprint S35. Eval runs list + launch new suite.\n */\n\ntype Tone = 'neutral' | 'success' | 'warning' | 'danger' | 'info';\n\ninterface EvalRun {\n id: string;\n suite?: string;\n status?: 'queued' | 'running' | 'done' | 'failed';\n passed?: number;\n failed?: number;\n total?: number;\n startedAt?: string;\n durationMs?: number;\n}\n\ninterface EvalSchedule {\n id: string;\n name: string;\n cron: string;\n suitePath?: string;\n enabled?: boolean;\n}\n\nfunction statusTone(s: EvalRun['status'] | undefined): Tone {\n if (s === 'done') return 'success';\n if (s === 'failed') return 'danger';\n if (s === 'running') return 'info';\n if (s === 'queued') return 'warning';\n return 'neutral';\n}\n\nfunction fmtDuration(ms: number | undefined): string {\n if (!ms || ms <= 0) return '—';\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n return `${Math.floor(ms / 60_000)}m ${Math.round((ms % 60_000) / 1000)}s`;\n}\n\nexport function EvalView(): JSX.Element {\n const runs = useFetch<{ runs: EvalRun[] }>('/api/eval/runs?limit=20');\n const schedules = useFetch<{ schedules: EvalSchedule[] }>('/api/eval/schedules');\n const [launching, setLaunching] = useState(false);\n const [suite, setSuite] = useState('default');\n const [error, setError] = useState<string | null>(null);\n const [addingSchedule, setAddingSchedule] = useState(false);\n const [scheduleForm, setScheduleForm] = useState({ name: '', cron: '', suitePath: 'default' });\n const [busySchedule, setBusySchedule] = useState(false);\n\n useEffect(() => {\n if (runs.data?.runs) {\n const hasActive = runs.data.runs.some((r) => r.status === 'running' || r.status === 'queued');\n if (hasActive) {\n const id = setTimeout(() => { void runs.refetch(); }, 5_000);\n return () => clearTimeout(id);\n }\n }\n }, [runs]);\n\n const launch = async (): Promise<void> => {\n setLaunching(true);\n setError(null);\n try {\n await fetchJson('/api/eval/run', { method: 'POST', body: { suite } });\n void runs.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setLaunching(false);\n }\n };\n\n const list = runs.data?.runs ?? [];\n\n const addSchedule = async (): Promise<void> => {\n if (!scheduleForm.name.trim() || !scheduleForm.cron.trim()) return;\n setBusySchedule(true);\n setError(null);\n try {\n await fetchJson<{ ok?: boolean }>('/api/eval/schedules', { method: 'POST', body: scheduleForm });\n setAddingSchedule(false);\n setScheduleForm({ name: '', cron: '', suitePath: 'default' });\n void schedules.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusySchedule(false);\n }\n };\n\n const deleteSchedule = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/eval/schedules/${encodeURIComponent(id)}`, { method: 'DELETE' });\n void schedules.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const scheduleList = schedules.data?.schedules ?? [];\n\n return (\n <Stack gap={5} data-testid=\"eval-view\">\n <ViewHeader\n title=\"Eval framework\"\n description=\"Run evaluation suites against the agent model. Suites live under fixtures/.\"\n actions={\n <Inline gap={2} align=\"center\">\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <input\n value={suite}\n onChange={(e) => setSuite(e.target.value)}\n placeholder=\"suite name\"\n disabled={launching}\n data-testid=\"eval-suite-input\"\n style={{\n padding: '6px 10px',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: 'var(--surface-0)',\n color: 'var(--fg)',\n fontSize: 'var(--fs-13)',\n fontFamily: 'var(--font-mono)',\n }}\n />\n <Button variant=\"primary\" onClick={() => void launch()} disabled={launching || !suite.trim()} data-testid=\"eval-launch\">\n {launching ? <Loader2 size={14} className=\"animate-spin\" aria-hidden /> : <Play size={14} aria-hidden />}\n {launching ? 'Launching…' : 'Run suite'}\n </Button>\n <Button variant=\"ghost\" onClick={() => void runs.refetch()} data-testid=\"eval-refresh\">\n <RefreshCw size={14} aria-hidden /> Refresh\n </Button>\n </Inline>\n }\n />\n\n {runs.loading && list.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 80 }} />\n <Skeleton style={{ height: 80 }} />\n </Stack>\n ) : list.length === 0 ? (\n <EmptyState\n icon={<FlaskConical size={32} aria-hidden />}\n title=\"No eval runs yet\"\n description=\"Launch a suite to begin measuring agent quality.\"\n />\n ) : (\n <Stack gap={2}>\n {list.map((r) => (\n <Card key={r.id} variant=\"default\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={3}>\n <Stack gap={1} style={{ flex: 1, minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-13)' }}>{r.id}</strong>\n <Badge tone={statusTone(r.status)}>{r.status ?? 'unknown'}</Badge>\n {r.suite && <Badge tone=\"neutral\">{r.suite}</Badge>}\n </Inline>\n <Inline align=\"center\" gap={3} style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-12)' }}>\n <span>{r.startedAt ? new Date(r.startedAt).toLocaleString() : ''}</span>\n <span>{fmtDuration(r.durationMs)}</span>\n </Inline>\n </Stack>\n <Stack align=\"end\" gap={0}>\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-14)' }}>\n <strong style={{ color: 'var(--success)' }}>{r.passed ?? 0}</strong> pass\n {' / '}\n <strong style={{ color: 'var(--danger)' }}>{r.failed ?? 0}</strong> fail\n </span>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{(r.total ?? 0)} total</span>\n </Stack>\n </Inline>\n </CardBody>\n </Card>\n ))}\n </Stack>\n )}\n\n <Card variant=\"elevated\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Inline align=\"center\" gap={2}>\n <Calendar size={16} aria-hidden />\n <strong style={{ fontSize: 'var(--fs-14)' }}>Schedules</strong>\n <Badge tone=\"neutral\">{scheduleList.length}</Badge>\n </Inline>\n {!addingSchedule && (\n <Button variant=\"primary\" onClick={() => setAddingSchedule(true)} data-testid=\"eval-schedule-add\">\n <Plus size={14} aria-hidden /> Add schedule\n </Button>\n )}\n </Inline>\n\n {addingSchedule && (\n <Stack gap={2} style={{ marginTop: 'var(--space-3)' }} data-testid=\"eval-schedule-form\">\n <Inline gap={2} align=\"center\">\n <input\n value={scheduleForm.name}\n onChange={(e) => setScheduleForm({ ...scheduleForm, name: e.target.value })}\n placeholder=\"name\"\n data-testid=\"eval-schedule-form-name\"\n style={inputStyle}\n />\n <input\n value={scheduleForm.cron}\n onChange={(e) => setScheduleForm({ ...scheduleForm, cron: e.target.value })}\n placeholder=\"cron (e.g. 0 9 * * *)\"\n data-testid=\"eval-schedule-form-cron\"\n style={inputStyle}\n />\n <input\n value={scheduleForm.suitePath}\n onChange={(e) => setScheduleForm({ ...scheduleForm, suitePath: e.target.value })}\n placeholder=\"suite path\"\n data-testid=\"eval-schedule-form-suite\"\n style={inputStyle}\n />\n </Inline>\n <Inline gap={2}>\n <Button variant=\"primary\" onClick={() => void addSchedule()} disabled={busySchedule} data-testid=\"eval-schedule-form-submit\">\n {busySchedule ? 'Saving…' : 'Save'}\n </Button>\n <Button variant=\"ghost\" onClick={() => setAddingSchedule(false)} data-testid=\"eval-schedule-form-cancel\">Cancel</Button>\n </Inline>\n </Stack>\n )}\n\n {scheduleList.length === 0 ? (\n <div style={{ marginTop: 'var(--space-2)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n No schedules yet. Add one to run suites on a cron.\n </div>\n ) : (\n <Stack gap={2} style={{ marginTop: 'var(--space-3)' }}>\n {scheduleList.map((s) => (\n <Inline key={s.id} align=\"center\" justify=\"between\" gap={2} data-testid={`eval-schedule-row-${s.id}`}>\n <Inline align=\"center\" gap={2}>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-13)' }}>{s.name}</strong>\n <code style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{s.cron}</code>\n {s.suitePath && <Badge tone=\"neutral\">{s.suitePath}</Badge>}\n </Inline>\n <Button variant=\"ghost\" onClick={() => void deleteSchedule(s.id)} data-testid={`eval-schedule-delete-${s.id}`} aria-label={`Delete schedule ${s.name}`}>\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n ))}\n </Stack>\n )}\n </CardBody>\n </Card>\n </Stack>\n );\n}\n\nconst inputStyle = {\n padding: '6px 10px',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: 'var(--surface-0)',\n color: 'var(--fg)',\n fontSize: 'var(--fs-13)',\n fontFamily: 'var(--font-mono)',\n} as const;"],"names":["statusTone","s","fmtDuration","ms","EvalView","runs","useFetch","schedules","launching","setLaunching","useState","suite","setSuite","error","setError","addingSchedule","setAddingSchedule","scheduleForm","setScheduleForm","busySchedule","setBusySchedule","useEffect","_a","r","id","launch","fetchJson","err","FetchError","list","addSchedule","deleteSchedule","scheduleList","_b","jsxs","Stack","jsx","ViewHeader","Inline","e","Button","Loader2","Play","RefreshCw","Skeleton","EmptyState","FlaskConical","Card","CardBody","Badge","Calendar","Plus","inputStyle","Trash2"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as e,r}from"./cmdk-DVxytz9i.js";import{B as F,g as q,S as f,I as C,d as b,h as K,i as R,u as Q,a as V}from"./main-
|
|
1
|
+
import{j as e,r}from"./cmdk-DVxytz9i.js";import{B as F,g as q,S as f,I as C,d as b,h as K,i as R,u as Q,a as V}from"./main-CyAIirBB.js";import{G as X}from"./Grid-dEnoGGws.js";import{C as Y}from"./Chip-DQtalZ4y.js";import{C as Z,V as ee}from"./ViewHeader-V_SzbUpw.js";import{P as te}from"./ProgressBar-D3lkz42E.js";import{C as se}from"./calendar-VntJUzFB.js";import{S as _,a as M}from"./Sheet-Cztsvgse.js";import{I as P}from"./Input-BSa3lh_-.js";import{S as ae,a as le,b as re,c as ne}from"./Select-C8EJj4NM.js";import{E as ie}from"./external-link-CAOnh_DH.js";import{T as W}from"./trash-2-2NsyTU8c.js";import{P as H}from"./plus-fFxt-8z5.js";import{C as oe,b as de}from"./Card-D9019JOD.js";import{E as ce}from"./ErrorState-Bump8diE.js";import{L as ue}from"./ListHeader-Ak9WJd39.js";import{T as ge}from"./Textarea-D_TPpVMy.js";import"./index-C4Vq_2LM.js";import"./index-CASP1n-5.js";import"./Alert-Dg_Vwxh5.js";import"./circle-alert-CQ9MLygI.js";import"./triangle-alert-DFmQ_RXN.js";import"./circle-check-COtVgsWw.js";import"./refresh-ccw-BCXx86xp.js";const fe={"on-track":"On track","at-risk":"At risk","off-track":"Off track",done:"Done"},he={"on-track":"success","at-risk":"warning","off-track":"danger",done:"neutral"};function pe(i){const{title:l,description:u,status:p,progress:D,due:g,ownerName:m,ownerAvatarUrl:h,keyResultsDone:w,keyResultsTotal:I,badges:E,onOpen:z,className:j}=i;return e.jsxs("button",{type:"button",onClick:z,className:q("v8-goal-card",`v8-goal-card--${p}`,j),style:{display:"flex",flexDirection:"column",gap:"var(--space-3)",width:"100%",padding:"var(--space-4)",background:"var(--surface-1)",border:"1px solid var(--border)",borderRadius:"var(--radius-lg)",textAlign:"left",cursor:"pointer",font:"inherit",color:"inherit",transition:"border-color var(--motion-fast) var(--ease-out), background var(--motion-fast) var(--ease-out)"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"flex-start",justifyContent:"space-between",gap:"var(--space-2)"},children:[e.jsxs("div",{style:{flex:1,minWidth:0},children:[e.jsx("div",{style:{fontSize:"var(--fs-14)",fontWeight:600,color:"var(--fg)",lineHeight:"var(--lh-snug)"},children:l}),u!==void 0&&e.jsx("div",{style:{fontSize:"var(--fs-13)",color:"var(--fg-muted)",marginTop:4,display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden"},children:u})]}),e.jsx(F,{tone:he[p],dot:!0,children:fe[p]})]}),e.jsxs("div",{children:[e.jsx(te,{value:D,tone:p==="on-track"?"success":p==="at-risk"?"warning":p==="off-track"?"danger":"accent"}),e.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginTop:6,fontSize:"var(--fs-12)",color:"var(--fg-muted)",fontVariantNumeric:"tabular-nums"},children:[e.jsxs("span",{children:[Math.round(D*100),"% complete"]}),w!==void 0&&I!==void 0&&e.jsxs("span",{children:[w," / ",I," key results"]})]})]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"var(--space-2)",fontSize:"var(--fs-12)",color:"var(--fg-subtle)"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--space-3)"},children:[g!==void 0&&e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4},children:[e.jsx(se,{size:12,"aria-hidden":"true"}),g]}),m!==void 0&&e.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[e.jsx("span",{"aria-hidden":"true",style:{width:16,height:16,borderRadius:"var(--radius-pill)",background:h!==void 0?`url(${h}) center/cover`:"var(--accent)",display:"inline-block"}}),m]})]}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--space-2)"},children:[E,e.jsx(Z,{size:14,"aria-hidden":"true",style:{color:"var(--fg-subtle)"}})]})]}),e.jsx("style",{children:`
|
|
2
2
|
.v8-goal-card:hover {
|
|
3
3
|
border-color: var(--accent);
|
|
4
4
|
background: var(--surface-2);
|