@polderlabs/bizar 10.4.2 → 10.4.3
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/bizar-dash/dist/assets/{ActivityFeed-DtRtg-JN.js → ActivityFeed-DC0JiK49.js} +1 -1
- package/bizar-dash/dist/assets/{ActivityFeed-DtRtg-JN.js.map → ActivityFeed-DC0JiK49.js.map} +1 -1
- package/bizar-dash/dist/assets/{ActivityView-CoTXDyU_.js → ActivityView-ubEDAWMY.js} +1 -1
- package/bizar-dash/dist/assets/{ActivityView-CoTXDyU_.js.map → ActivityView-ubEDAWMY.js.map} +1 -1
- package/bizar-dash/dist/assets/{AdminView-DNc5Ll7L.js → AdminView-CI4zM2Qg.js} +1 -1
- package/bizar-dash/dist/assets/{AdminView-DNc5Ll7L.js.map → AdminView-CI4zM2Qg.js.map} +1 -1
- package/bizar-dash/dist/assets/{AgentActivity-CrX7LmQ6.js → AgentActivity-BLcqqkt2.js} +1 -1
- package/bizar-dash/dist/assets/{AgentActivity-CrX7LmQ6.js.map → AgentActivity-BLcqqkt2.js.map} +1 -1
- package/bizar-dash/dist/assets/AgentsView-CIQkZH8_.js +15 -0
- package/bizar-dash/dist/assets/AgentsView-CIQkZH8_.js.map +1 -0
- package/bizar-dash/dist/assets/{Alert-B6DjfRFI.js → Alert-MwVEymjy.js} +1 -1
- package/bizar-dash/dist/assets/{Alert-B6DjfRFI.js.map → Alert-MwVEymjy.js.map} +1 -1
- package/bizar-dash/dist/assets/{ArtifactsView-znhN8GTR.js → ArtifactsView-B-YUwZyb.js} +1 -1
- package/bizar-dash/dist/assets/{ArtifactsView-znhN8GTR.js.map → ArtifactsView-B-YUwZyb.js.map} +1 -1
- package/bizar-dash/dist/assets/{AuthView-Rk8eKUPr.js → AuthView-LaQuGo4u.js} +1 -1
- package/bizar-dash/dist/assets/{AuthView-Rk8eKUPr.js.map → AuthView-LaQuGo4u.js.map} +1 -1
- package/bizar-dash/dist/assets/{Avatar-B41upSD1.js → Avatar-Dg4OF4RD.js} +1 -1
- package/bizar-dash/dist/assets/{Avatar-B41upSD1.js.map → Avatar-Dg4OF4RD.js.map} +1 -1
- package/bizar-dash/dist/assets/{BackgroundJobsView-BLWuN9qz.js → BackgroundJobsView-CO3DEG8R.js} +1 -1
- package/bizar-dash/dist/assets/{BackgroundJobsView-BLWuN9qz.js.map → BackgroundJobsView-CO3DEG8R.js.map} +1 -1
- package/bizar-dash/dist/assets/{BackupView-CqbtcnuQ.js → BackupView-Cjf23ZWc.js} +1 -1
- package/bizar-dash/dist/assets/{BackupView-CqbtcnuQ.js.map → BackupView-Cjf23ZWc.js.map} +1 -1
- package/bizar-dash/dist/assets/{Card-rF59wHiO.js → Card-BmXiT4c6.js} +1 -1
- package/bizar-dash/dist/assets/{Card-rF59wHiO.js.map → Card-BmXiT4c6.js.map} +1 -1
- package/bizar-dash/dist/assets/ChatView-DXKFwvgp.js +9 -0
- package/bizar-dash/dist/assets/ChatView-DXKFwvgp.js.map +1 -0
- package/bizar-dash/dist/assets/{Chip-Dc2KmeWl.js → Chip-Dei66BLx.js} +1 -1
- package/bizar-dash/dist/assets/{Chip-Dc2KmeWl.js.map → Chip-Dei66BLx.js.map} +1 -1
- package/bizar-dash/dist/assets/{ClaudeSessionsView-CiaHQdDZ.js → ClaudeSessionsView-D-YNmzKi.js} +1 -1
- package/bizar-dash/dist/assets/{ClaudeSessionsView-CiaHQdDZ.js.map → ClaudeSessionsView-D-YNmzKi.js.map} +1 -1
- package/bizar-dash/dist/assets/{ClipboardView-DdP6aVso.js → ClipboardView-BA323V2J.js} +1 -1
- package/bizar-dash/dist/assets/{ClipboardView-DdP6aVso.js.map → ClipboardView-BA323V2J.js.map} +1 -1
- package/bizar-dash/dist/assets/{ConfigView-B2ysnTZU.js → ConfigView-BMBgifw5.js} +1 -1
- package/bizar-dash/dist/assets/{ConfigView-B2ysnTZU.js.map → ConfigView-BMBgifw5.js.map} +1 -1
- package/bizar-dash/dist/assets/DiagnosticsView-C0sdqhEl.js +2 -0
- package/bizar-dash/dist/assets/DiagnosticsView-C0sdqhEl.js.map +1 -0
- package/bizar-dash/dist/assets/{DialogsView-BcqDDCZQ.js → DialogsView-DzTnyX8K.js} +1 -1
- package/bizar-dash/dist/assets/{DialogsView-BcqDDCZQ.js.map → DialogsView-DzTnyX8K.js.map} +1 -1
- package/bizar-dash/dist/assets/{DoctorView-BQwqvMAh.js → DoctorView-CiFwRMW0.js} +1 -1
- package/bizar-dash/dist/assets/{DoctorView-BQwqvMAh.js.map → DoctorView-CiFwRMW0.js.map} +1 -1
- package/bizar-dash/dist/assets/{EmptyState-D65J5FQN.js → EmptyState-CdDQmfEL.js} +1 -1
- package/bizar-dash/dist/assets/{EmptyState-D65J5FQN.js.map → EmptyState-CdDQmfEL.js.map} +1 -1
- package/bizar-dash/dist/assets/{EnvVarsView-DX-3oGH-.js → EnvVarsView-CNO03NDJ.js} +1 -1
- package/bizar-dash/dist/assets/{EnvVarsView-DX-3oGH-.js.map → EnvVarsView-CNO03NDJ.js.map} +1 -1
- package/bizar-dash/dist/assets/{ErrorState-DULZnttJ.js → ErrorState-BRvj8qZZ.js} +1 -1
- package/bizar-dash/dist/assets/{ErrorState-DULZnttJ.js.map → ErrorState-BRvj8qZZ.js.map} +1 -1
- package/bizar-dash/dist/assets/{EvalView-CpdFu_ID.js → EvalView-lgUhlGJh.js} +1 -1
- package/bizar-dash/dist/assets/{EvalView-CpdFu_ID.js.map → EvalView-lgUhlGJh.js.map} +1 -1
- package/bizar-dash/dist/assets/{GoalsView-Br8oPPfb.js → GoalsView-DmkCCs9i.js} +1 -1
- package/bizar-dash/dist/assets/{GoalsView-Br8oPPfb.js.map → GoalsView-DmkCCs9i.js.map} +1 -1
- package/bizar-dash/dist/assets/{Grid-BSXhsCPC.js → Grid-BThCPJaV.js} +1 -1
- package/bizar-dash/dist/assets/{Grid-BSXhsCPC.js.map → Grid-BThCPJaV.js.map} +1 -1
- package/bizar-dash/dist/assets/{HistoryView-D0J3aoZF.js → HistoryView-Cn2cPiHZ.js} +1 -1
- package/bizar-dash/dist/assets/{HistoryView-D0J3aoZF.js.map → HistoryView-Cn2cPiHZ.js.map} +1 -1
- package/bizar-dash/dist/assets/{Input-CZmRw5QX.js → Input-cAQOvR8U.js} +1 -1
- package/bizar-dash/dist/assets/{Input-CZmRw5QX.js.map → Input-cAQOvR8U.js.map} +1 -1
- package/bizar-dash/dist/assets/LibrariesView-Ca_PRjUm.js +6 -0
- package/bizar-dash/dist/assets/{LibrariesView-B1YX9wzp.js.map → LibrariesView-Ca_PRjUm.js.map} +1 -1
- package/bizar-dash/dist/assets/{LightRAGView-CykR0t9y.js → LightRAGView-CMk9wOae.js} +1 -1
- package/bizar-dash/dist/assets/{LightRAGView-CykR0t9y.js.map → LightRAGView-CMk9wOae.js.map} +1 -1
- package/bizar-dash/dist/assets/{ListHeader-Dpun-r36.js → ListHeader-BLAeshe0.js} +1 -1
- package/bizar-dash/dist/assets/{ListHeader-Dpun-r36.js.map → ListHeader-BLAeshe0.js.map} +1 -1
- package/bizar-dash/dist/assets/{MemoryView-BbER5ZKt.js → MemoryView-wo2Pu7xQ.js} +1 -1
- package/bizar-dash/dist/assets/{MemoryView-BbER5ZKt.js.map → MemoryView-wo2Pu7xQ.js.map} +1 -1
- package/bizar-dash/dist/assets/{MessageBubble-5vUAquDx.js → MessageBubble-CrCJ0SYG.js} +1 -1
- package/bizar-dash/dist/assets/{MessageBubble-5vUAquDx.js.map → MessageBubble-CrCJ0SYG.js.map} +1 -1
- package/bizar-dash/dist/assets/{MiscView-DLNEGdML.js → MiscView-fBT1TOXC.js} +1 -1
- package/bizar-dash/dist/assets/{MiscView-DLNEGdML.js.map → MiscView-fBT1TOXC.js.map} +1 -1
- package/bizar-dash/dist/assets/{ModsView-P7gDeNHM.js → ModsView-CV_RxdzJ.js} +1 -1
- package/bizar-dash/dist/assets/{ModsView-P7gDeNHM.js.map → ModsView-CV_RxdzJ.js.map} +1 -1
- package/bizar-dash/dist/assets/{NotificationsView-DAm2O0yf.js → NotificationsView-BKAZLxM2.js} +1 -1
- package/bizar-dash/dist/assets/{NotificationsView-DAm2O0yf.js.map → NotificationsView-BKAZLxM2.js.map} +1 -1
- package/bizar-dash/dist/assets/{ObsidianView-Ci80gnwS.js → ObsidianView-C-AvHfpT.js} +1 -1
- package/bizar-dash/dist/assets/{ObsidianView-Ci80gnwS.js.map → ObsidianView-C-AvHfpT.js.map} +1 -1
- package/bizar-dash/dist/assets/{OverviewView-rriw1GjA.js → OverviewView-CKYzZJe3.js} +1 -1
- package/bizar-dash/dist/assets/{OverviewView-rriw1GjA.js.map → OverviewView-CKYzZJe3.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProgressBar-BahmeJhP.js → ProgressBar-ya2PCj8L.js} +1 -1
- package/bizar-dash/dist/assets/{ProgressBar-BahmeJhP.js.map → ProgressBar-ya2PCj8L.js.map} +1 -1
- package/bizar-dash/dist/assets/ProjectsView-N9zqFZ_O.js +11 -0
- package/bizar-dash/dist/assets/ProjectsView-N9zqFZ_O.js.map +1 -0
- package/bizar-dash/dist/assets/{ProvidersView-BftGn8Cr.js → ProvidersView-BcL8jjwK.js} +1 -1
- package/bizar-dash/dist/assets/{ProvidersView-BftGn8Cr.js.map → ProvidersView-BcL8jjwK.js.map} +1 -1
- package/bizar-dash/dist/assets/{SchedulesView-CtNxtzN6.js → SchedulesView-8qxH3bg7.js} +1 -1
- package/bizar-dash/dist/assets/{SchedulesView-CtNxtzN6.js.map → SchedulesView-8qxH3bg7.js.map} +1 -1
- package/bizar-dash/dist/assets/{Select-0VcfTDeL.js → Select-D5AuVxxV.js} +1 -1
- package/bizar-dash/dist/assets/{Select-0VcfTDeL.js.map → Select-D5AuVxxV.js.map} +1 -1
- package/bizar-dash/dist/assets/{SettingsRow-BLic3DQl.js → SettingsRow-BBALf9dA.js} +1 -1
- package/bizar-dash/dist/assets/{SettingsRow-BLic3DQl.js.map → SettingsRow-BBALf9dA.js.map} +1 -1
- package/bizar-dash/dist/assets/{SettingsView-BjS3i4nr.js → SettingsView-UD403neY.js} +1 -1
- package/bizar-dash/dist/assets/{SettingsView-BjS3i4nr.js.map → SettingsView-UD403neY.js.map} +1 -1
- package/bizar-dash/dist/assets/{Sheet-BOProMs2.js → Sheet-CxXf6gvC.js} +1 -1
- package/bizar-dash/dist/assets/{Sheet-BOProMs2.js.map → Sheet-CxXf6gvC.js.map} +1 -1
- package/bizar-dash/dist/assets/{Slider-B0eLEEUt.js → Slider-hvaVD_SW.js} +1 -1
- package/bizar-dash/dist/assets/{Slider-B0eLEEUt.js.map → Slider-hvaVD_SW.js.map} +1 -1
- package/bizar-dash/dist/assets/{Sparkline-SSrdgyW0.js → Sparkline-DqmQzdJH.js} +1 -1
- package/bizar-dash/dist/assets/{Sparkline-SSrdgyW0.js.map → Sparkline-DqmQzdJH.js.map} +1 -1
- package/bizar-dash/dist/assets/{Switch-B3EQzb_q.js → Switch-C-_zcNdl.js} +1 -1
- package/bizar-dash/dist/assets/{Switch-B3EQzb_q.js.map → Switch-C-_zcNdl.js.map} +1 -1
- package/bizar-dash/dist/assets/{TasksView-SWjF_ZUQ.js → TasksView-DseftDlx.js} +1 -1
- package/bizar-dash/dist/assets/{TasksView-SWjF_ZUQ.js.map → TasksView-DseftDlx.js.map} +1 -1
- package/bizar-dash/dist/assets/{Textarea-QuofpMlq.js → Textarea-CcQGSgSH.js} +1 -1
- package/bizar-dash/dist/assets/{Textarea-QuofpMlq.js.map → Textarea-CcQGSgSH.js.map} +1 -1
- package/bizar-dash/dist/assets/{UpdateView-CEHW2nd6.js → UpdateView-B9Lh4svM.js} +1 -1
- package/bizar-dash/dist/assets/{UpdateView-CEHW2nd6.js.map → UpdateView-B9Lh4svM.js.map} +1 -1
- package/bizar-dash/dist/assets/{UsageView-BqOw6FBg.js → UsageView-P5_pQ68d.js} +1 -1
- package/bizar-dash/dist/assets/{UsageView-BqOw6FBg.js.map → UsageView-P5_pQ68d.js.map} +1 -1
- package/bizar-dash/dist/assets/{ViewHeader-B6P-C4GD.js → ViewHeader-BaCWNuVX.js} +1 -1
- package/bizar-dash/dist/assets/{ViewHeader-B6P-C4GD.js.map → ViewHeader-BaCWNuVX.js.map} +1 -1
- package/bizar-dash/dist/assets/{VoiceView-CwrPwWgi.js → VoiceView-BwR9gm5e.js} +1 -1
- package/bizar-dash/dist/assets/{VoiceView-CwrPwWgi.js.map → VoiceView-BwR9gm5e.js.map} +1 -1
- package/bizar-dash/dist/assets/{brain-CwZt9Kta.js → brain-D6tAeUDE.js} +1 -1
- package/bizar-dash/dist/assets/{brain-CwZt9Kta.js.map → brain-D6tAeUDE.js.map} +1 -1
- package/bizar-dash/dist/assets/{calendar-C5oK0_nM.js → calendar-BrMJf3vl.js} +1 -1
- package/bizar-dash/dist/assets/{calendar-C5oK0_nM.js.map → calendar-BrMJf3vl.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-alert-HdHe7m8K.js → circle-alert-D7jn06kH.js} +1 -1
- package/bizar-dash/dist/assets/{circle-alert-HdHe7m8K.js.map → circle-alert-D7jn06kH.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-check-Cs-xoV7R.js → circle-check-DHs37Sot.js} +1 -1
- package/bizar-dash/dist/assets/{circle-check-Cs-xoV7R.js.map → circle-check-DHs37Sot.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-D1Lc_P2a.js → circle-fPTATiOs.js} +1 -1
- package/bizar-dash/dist/assets/{circle-D1Lc_P2a.js.map → circle-fPTATiOs.js.map} +1 -1
- package/bizar-dash/dist/assets/{clock-DEIuPV60.js → clock-E-G5aGua.js} +1 -1
- package/bizar-dash/dist/assets/{clock-DEIuPV60.js.map → clock-E-G5aGua.js.map} +1 -1
- package/bizar-dash/dist/assets/{cmdk-DVxytz9i.js → cmdk-C3F6LD6N.js} +5 -5
- package/bizar-dash/dist/assets/{cmdk-DVxytz9i.js.map → cmdk-C3F6LD6N.js.map} +1 -1
- package/bizar-dash/dist/assets/{dnd-kit-DrHErSkw.js → dnd-kit-BAOLODOI.js} +1 -1
- package/bizar-dash/dist/assets/{dnd-kit-DrHErSkw.js.map → dnd-kit-BAOLODOI.js.map} +1 -1
- package/bizar-dash/dist/assets/{download-Clkq90Ct.js → download-DBkNb6oI.js} +1 -1
- package/bizar-dash/dist/assets/{download-Clkq90Ct.js.map → download-DBkNb6oI.js.map} +1 -1
- package/bizar-dash/dist/assets/{external-link-D5tq2o_I.js → external-link-C4pHGbz2.js} +1 -1
- package/bizar-dash/dist/assets/{external-link-D5tq2o_I.js.map → external-link-C4pHGbz2.js.map} +1 -1
- package/bizar-dash/dist/assets/{file-text-CQ12t7Oc.js → file-text-CEhDgLq2.js} +1 -1
- package/bizar-dash/dist/assets/{file-text-CQ12t7Oc.js.map → file-text-CEhDgLq2.js.map} +1 -1
- package/bizar-dash/dist/assets/{filter-BcbE37wP.js → filter-CEYjeWFX.js} +1 -1
- package/bizar-dash/dist/assets/{filter-BcbE37wP.js.map → filter-CEYjeWFX.js.map} +1 -1
- package/bizar-dash/dist/assets/{git-pull-request-D1qNDRia.js → git-pull-request-Bo_wBZZw.js} +1 -1
- package/bizar-dash/dist/assets/{git-pull-request-D1qNDRia.js.map → git-pull-request-Bo_wBZZw.js.map} +1 -1
- package/bizar-dash/dist/assets/{index-CASP1n-5.js → index-B1OIS316.js} +1 -1
- package/bizar-dash/dist/assets/{index-CASP1n-5.js.map → index-B1OIS316.js.map} +1 -1
- package/bizar-dash/dist/assets/{index-C4Vq_2LM.js → index-CR0TeJmc.js} +1 -1
- package/bizar-dash/dist/assets/{index-C4Vq_2LM.js.map → index-CR0TeJmc.js.map} +1 -1
- package/bizar-dash/dist/assets/main-BZMmD6a8.js +249 -0
- package/bizar-dash/dist/assets/main-BZMmD6a8.js.map +1 -0
- package/bizar-dash/dist/assets/{main-CcQfRfIJ.css → main-DDAMz_H5.css} +1 -1
- package/bizar-dash/dist/assets/{network-DJdvVaHx.js → network-BsfwrUA-.js} +1 -1
- package/bizar-dash/dist/assets/{network-DJdvVaHx.js.map → network-BsfwrUA-.js.map} +1 -1
- package/bizar-dash/dist/assets/{pause-DUn9L5PB.js → pause-C8PN1_yO.js} +1 -1
- package/bizar-dash/dist/assets/{pause-DUn9L5PB.js.map → pause-C8PN1_yO.js.map} +1 -1
- package/bizar-dash/dist/assets/{pencil-DVrBlYV3.js → pencil---XuvKlz.js} +1 -1
- package/bizar-dash/dist/assets/{pencil-DVrBlYV3.js.map → pencil---XuvKlz.js.map} +1 -1
- package/bizar-dash/dist/assets/{play-CZjsr3XM.js → play-fMLPTihK.js} +1 -1
- package/bizar-dash/dist/assets/{play-CZjsr3XM.js.map → play-fMLPTihK.js.map} +1 -1
- package/bizar-dash/dist/assets/{plug-BKuyIe5W.js → plug-CG8al2Kq.js} +1 -1
- package/bizar-dash/dist/assets/{plug-BKuyIe5W.js.map → plug-CG8al2Kq.js.map} +1 -1
- package/bizar-dash/dist/assets/{plus-77h62zZm.js → plus-uA5Ecuch.js} +1 -1
- package/bizar-dash/dist/assets/{plus-77h62zZm.js.map → plus-uA5Ecuch.js.map} +1 -1
- package/bizar-dash/dist/assets/{power-DLmx-gCP.js → power-DSUlNIuR.js} +1 -1
- package/bizar-dash/dist/assets/{power-DLmx-gCP.js.map → power-DSUlNIuR.js.map} +1 -1
- package/bizar-dash/dist/assets/{power-off-BFKzHXic.js → power-off-1CAQsHHy.js} +1 -1
- package/bizar-dash/dist/assets/{power-off-BFKzHXic.js.map → power-off-1CAQsHHy.js.map} +1 -1
- package/bizar-dash/dist/assets/{refresh-ccw-DenGBOcq.js → refresh-ccw-BL7B0NO1.js} +1 -1
- package/bizar-dash/dist/assets/{refresh-ccw-DenGBOcq.js.map → refresh-ccw-BL7B0NO1.js.map} +1 -1
- package/bizar-dash/dist/assets/{refresh-cw-ENBVR8hW.js → refresh-cw-CR9BzJik.js} +1 -1
- package/bizar-dash/dist/assets/{refresh-cw-ENBVR8hW.js.map → refresh-cw-CR9BzJik.js.map} +1 -1
- package/bizar-dash/dist/assets/{rotate-ccw-MxryaY7q.js → rotate-ccw-BtnitLfb.js} +1 -1
- package/bizar-dash/dist/assets/{rotate-ccw-MxryaY7q.js.map → rotate-ccw-BtnitLfb.js.map} +1 -1
- package/bizar-dash/dist/assets/{rotate-cw-CDOlRtUR.js → rotate-cw-CHgXCO7O.js} +1 -1
- package/bizar-dash/dist/assets/{rotate-cw-CDOlRtUR.js.map → rotate-cw-CHgXCO7O.js.map} +1 -1
- package/bizar-dash/dist/assets/{save-Db1b-1Uq.js → save-RcZOXR0U.js} +1 -1
- package/bizar-dash/dist/assets/{save-Db1b-1Uq.js.map → save-RcZOXR0U.js.map} +1 -1
- package/bizar-dash/dist/assets/{send-yz6HFZM5.js → send-Bg2X_ibk.js} +1 -1
- package/bizar-dash/dist/assets/{send-yz6HFZM5.js.map → send-Bg2X_ibk.js.map} +1 -1
- package/bizar-dash/dist/assets/{shield-alert-DY6RAaC8.js → shield-alert-Dm48D034.js} +1 -1
- package/bizar-dash/dist/assets/{shield-alert-DY6RAaC8.js.map → shield-alert-Dm48D034.js.map} +1 -1
- package/bizar-dash/dist/assets/{trash-2-Cv7U38jw.js → trash-2-B885GY46.js} +1 -1
- package/bizar-dash/dist/assets/{trash-2-Cv7U38jw.js.map → trash-2-B885GY46.js.map} +1 -1
- package/bizar-dash/dist/assets/{trending-up-CRPNagyX.js → trending-up-CqUBvVxw.js} +1 -1
- package/bizar-dash/dist/assets/{trending-up-CRPNagyX.js.map → trending-up-CqUBvVxw.js.map} +1 -1
- package/bizar-dash/dist/assets/{triangle-alert-tUTXbcEP.js → triangle-alert-DLmUhymD.js} +1 -1
- package/bizar-dash/dist/assets/{triangle-alert-tUTXbcEP.js.map → triangle-alert-DLmUhymD.js.map} +1 -1
- package/bizar-dash/dist/assets/{upload-Cq7uTsrT.js → upload-C-oafpyE.js} +1 -1
- package/bizar-dash/dist/assets/{upload-Cq7uTsrT.js.map → upload-C-oafpyE.js.map} +1 -1
- package/bizar-dash/dist/assets/{zap-5lAQBAPX.js → zap-O_4Ys_hh.js} +1 -1
- package/bizar-dash/dist/assets/{zap-5lAQBAPX.js.map → zap-O_4Ys_hh.js.map} +1 -1
- package/bizar-dash/dist/index.html +3 -3
- package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/bizar-dash/src/web/v8/App.tsx +62 -2
- package/bizar-dash/src/web/v8/__tests__/chat-view.test.tsx +4 -4
- package/bizar-dash/src/web/v8/shell/AppShell.tsx +38 -2
- package/bizar-dash/src/web/v8/shell/Sidebar.tsx +44 -33
- package/bizar-dash/src/web/v8/shell/Topbar.tsx +5 -2
- package/bizar-dash/src/web/v8/ui/styles/globals.css +26 -0
- package/bizar-dash/src/web/v8/views/Agents/AgentsView.tsx +26 -1
- package/bizar-dash/src/web/v8/views/Chat/ChatView.tsx +13 -1
- package/bizar-dash/src/web/v8/views/ClaudeSessions/NewSessionModal.tsx +136 -0
- package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.tsx +14 -4
- package/bizar-dash/src/web/v8/views/Diagnostics/DiagnosticsView.tsx +50 -7
- package/bizar-dash/src/web/v8/views/Libraries/LibrariesView.tsx +6 -1
- package/bizar-dash/src/web/v8/views/Projects/ProjectsView.tsx +21 -1
- package/bizar-dash/tests/admin-labels.test.mjs +42 -0
- package/bizar-dash/tests/agents-summary-sanitize.test.ts +51 -0
- package/bizar-dash/tests/chat-new-session.test.mjs +63 -0
- package/bizar-dash/tests/kanban-empty-column.test.mjs +56 -0
- package/bizar-dash/tests/library-dedupe.test.mjs +62 -0
- package/bizar-dash/tests/projects-filter.test.mjs +48 -0
- package/bizar-dash/tests/settings-labels.test.mjs +80 -0
- package/bizar-dash/tests/sidebar-responsive.test.tsx +48 -0
- package/bizar-dash/tests/sidebar-section-toggle.test.tsx +63 -0
- package/package.json +1 -1
- package/packages/sdk/package.json +1 -1
- package/bizar-dash/dist/assets/AgentsView-Du-G_skK.js +0 -13
- package/bizar-dash/dist/assets/AgentsView-Du-G_skK.js.map +0 -1
- package/bizar-dash/dist/assets/ChatView-CUriVEgU.js +0 -9
- package/bizar-dash/dist/assets/ChatView-CUriVEgU.js.map +0 -1
- package/bizar-dash/dist/assets/DiagnosticsView-88OZ5k0f.js +0 -2
- package/bizar-dash/dist/assets/DiagnosticsView-88OZ5k0f.js.map +0 -1
- package/bizar-dash/dist/assets/LibrariesView-B1YX9wzp.js +0 -6
- package/bizar-dash/dist/assets/ProjectsView-ChzM12bs.js +0 -11
- package/bizar-dash/dist/assets/ProjectsView-ChzM12bs.js.map +0 -1
- package/bizar-dash/dist/assets/main-Cxeu4LhG.js +0 -244
- package/bizar-dash/dist/assets/main-Cxeu4LhG.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as v,j as r}from"./cmdk-
|
|
1
|
+
import{r as v,j as r}from"./cmdk-C3F6LD6N.js";import{g}from"./main-BZMmD6a8.js";const h={accent:"var(--accent)",info:"var(--info)",success:"var(--success)",warning:"var(--warning)",danger:"var(--danger)"},x=v.forwardRef(function(s,e){const{value:t,max:i=1,tone:n="accent",showLabel:o,height:c=6,className:d,style:l,...u}=s,a=Math.min(100,Math.max(0,t/i*100));return r.jsxs("div",{ref:e,className:g("v8-progress",d),style:{position:"relative",display:"flex",alignItems:"center",gap:"var(--space-2)",...l},...u,children:[r.jsx("div",{style:{flex:1,height:c,background:"var(--surface-2)",borderRadius:"var(--radius-pill)",overflow:"hidden"},children:r.jsx("div",{style:{width:`${a}%`,height:"100%",background:h[n],borderRadius:"var(--radius-pill)",transition:"width var(--motion-base) var(--ease-out)"}})}),o===!0&&r.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)",fontVariantNumeric:"tabular-nums",minWidth:32,textAlign:"right"},children:[Math.round(a),"%"]})]})});export{x as P};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgressBar-
|
|
1
|
+
{"version":3,"file":"ProgressBar-ya2PCj8L.js","sources":["../../src/web/v8/ui/data/ProgressBar.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * ProgressBar — linear progress indicator.\n *\n * Use cases: Goal progress, task completion, capacity usage.\n * For circular progress use the inline circle ring (S9) or a third-party.\n */\n\nexport interface ProgressBarProps extends HTMLAttributes<HTMLDivElement> {\n /** 0..1 (or 0..100 if `max` is 100). */\n value: number;\n max?: number;\n /** Tone color for the filled portion. */\n tone?: 'accent' | 'info' | 'success' | 'warning' | 'danger';\n /** Render the value as a percentage label on the right. */\n showLabel?: boolean;\n /** Bar height in px. */\n height?: number;\n}\n\nconst TONE_BG: Record<NonNullable<ProgressBarProps['tone']>, string> = {\n accent: 'var(--accent)',\n info: 'var(--info)',\n success: 'var(--success)',\n warning: 'var(--warning)',\n danger: 'var(--danger)',\n};\n\nexport const ProgressBar = forwardRef<HTMLDivElement, ProgressBarProps>(function ProgressBar(\n props,\n ref,\n) {\n const {\n value,\n max = 1,\n tone = 'accent',\n showLabel,\n height = 6,\n className,\n style,\n ...rest\n } = props;\n const pct = Math.min(100, Math.max(0, (value / max) * 100));\n return (\n <div\n ref={ref}\n className={cx('v8-progress', className)}\n style={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-2)',\n ...style,\n }}\n {...rest}\n >\n <div\n style={{\n flex: 1,\n height,\n background: 'var(--surface-2)',\n borderRadius: 'var(--radius-pill)',\n overflow: 'hidden',\n }}\n >\n <div\n style={{\n width: `${pct}%`,\n height: '100%',\n background: TONE_BG[tone],\n borderRadius: 'var(--radius-pill)',\n transition: 'width var(--motion-base) var(--ease-out)',\n }}\n />\n </div>\n {showLabel === true && (\n <span\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-muted)',\n fontVariantNumeric: 'tabular-nums',\n minWidth: 32,\n textAlign: 'right',\n }}\n >\n {Math.round(pct)}%\n </span>\n )}\n </div>\n );\n});"],"names":["TONE_BG","ProgressBar","forwardRef","props","ref","value","max","tone","showLabel","height","className","style","rest","pct","jsxs","cx","jsx"],"mappings":"gFAsBA,MAAMA,EAAiE,CACrE,OAAQ,gBACR,KAAM,cACN,QAAS,iBACT,QAAS,iBACT,OAAQ,eACV,EAEaC,EAAcC,EAAAA,WAA6C,SACtEC,EACAC,EACA,CACA,KAAM,CACJ,MAAAC,EACA,IAAAC,EAAM,EACN,KAAAC,EAAO,SACP,UAAAC,EACA,OAAAC,EAAS,EACT,UAAAC,EACA,MAAAC,EACA,GAAGC,CAAA,EACDT,EACEU,EAAM,KAAK,IAAI,IAAK,KAAK,IAAI,EAAIR,EAAQC,EAAO,GAAG,CAAC,EAC1D,OACEQ,EAAAA,KAAC,MAAA,CACC,IAAAV,EACA,UAAWW,EAAG,cAAeL,CAAS,EACtC,MAAO,CACL,SAAU,WACV,QAAS,OACT,WAAY,SACZ,IAAK,iBACL,GAAGC,CAAA,EAEJ,GAAGC,EAEJ,SAAA,CAAAI,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,KAAM,EACN,OAAAP,EACA,WAAY,mBACZ,aAAc,qBACd,SAAU,QAAA,EAGZ,SAAAO,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,MAAO,GAAGH,CAAG,IACb,OAAQ,OACR,WAAYb,EAAQO,CAAI,EACxB,aAAc,qBACd,WAAY,0CAAA,CACd,CAAA,CACF,CAAA,EAEDC,IAAc,IACbM,EAAAA,KAAC,OAAA,CACC,MAAO,CACL,SAAU,eACV,MAAO,kBACP,mBAAoB,eACpB,SAAU,GACV,UAAW,OAAA,EAGZ,SAAA,CAAA,KAAK,MAAMD,CAAG,EAAE,GAAA,CAAA,CAAA,CACnB,CAAA,CAAA,CAIR,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import{r as o,j as e}from"./cmdk-C3F6LD6N.js";import{c as R,u as V,a as q,S as l,I as c,d as s,w as W,h as z,B as J,i as h,F as p}from"./main-BZMmD6a8.js";import{V as Z}from"./ViewHeader-BaCWNuVX.js";import{L as G}from"./ListHeader-BLAeshe0.js";import{C as K,b as Q}from"./Card-BmXiT4c6.js";import{I as P}from"./Input-cAQOvR8U.js";import{S as U,a as X,b as Y}from"./Sheet-CxXf6gvC.js";import{E as _}from"./EmptyState-CdDQmfEL.js";import{R as ee}from"./refresh-ccw-BL7B0NO1.js";import{T as te}from"./trash-2-B885GY46.js";/**
|
|
2
|
+
* @license lucide-react v0.460.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const T=R("FolderPlus",[["path",{d:"M12 10v6",key:"1bos4e"}],["path",{d:"M9 13h6",key:"1uhe8q"}],["path",{d:"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",key:"1kt360"}]]);/**
|
|
7
|
+
* @license lucide-react v0.460.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const ae=R("ScanSearch",[["path",{d:"M3 7V5a2 2 0 0 1 2-2h2",key:"aa7l1z"}],["path",{d:"M17 3h2a2 2 0 0 1 2 2v2",key:"4qcy5o"}],["path",{d:"M21 17v2a2 2 0 0 1-2 2h-2",key:"6vwrx8"}],["path",{d:"M7 21H5a2 2 0 0 1-2-2v-2",key:"ioqczr"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}],["path",{d:"m16 16-1.9-1.9",key:"1dq9hf"}]]);function A(i){return/^(bizar-(e2e|real-env|admin)|bh-(cold-boot|walk-proj))/.test(i.id)||i.name!=null&&i.name===i.id}function je(){var w,b;const i=V("/api/projects"),[E,j]=o.useState(!1),[m,f]=o.useState(""),[x,y]=o.useState(""),[S,k]=o.useState(!1),[C,r]=o.useState(null),[M,u]=o.useState(null),[v,D]=o.useState(!1),g=((w=i.data)==null?void 0:w.projects)??[],d=v?g:g.filter(t=>!A(t)),I=((b=d.find(t=>t.active))==null?void 0:b.id)??null,n=o.useCallback(()=>{i.refetch()},[i]);q("project:change",n);const $=async()=>{const t=m.trim();if(!(!t||S)){k(!0),r(null);try{await h("/api/projects",{method:"POST",body:{path:t,name:x.trim()||null}}),f(""),y(""),j(!1),n()}catch(a){r((a instanceof p,a.message))}finally{k(!1)}}},F=async t=>{r(null);try{await h(`/api/projects/${t}/activate`,{method:"POST",body:{}}),n()}catch(a){r((a instanceof p,a.message))}},O=async t=>{r(null);try{await h(`/api/projects/${t}`,{method:"DELETE"}),u(null),n()}catch(a){r((a instanceof p,a.message))}},B=async()=>{r(null);try{await h("/api/projects/auto-detect",{method:"POST",body:{}}),n()}catch(t){r((t instanceof p,t.message))}},H=async()=>{r(null);try{await h("/api/projects/scan",{method:"POST",body:{}}),n()}catch(t){r((t instanceof p,t.message))}};return e.jsxs(l,{gap:4,"data-testid":"projects-view",children:[e.jsx(Z,{title:"Projects",description:"Registered project roots. One is active at a time — every active-project endpoint scopes to it.",actions:e.jsxs(c,{align:"center",gap:2,children:[C!==null&&e.jsx("span",{role:"alert","data-testid":"projects-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:C}),g.some(t=>A(t))&&e.jsx(s,{variant:v?"primary":"ghost",size:"sm",onClick:()=>D(t=>!t),"data-testid":"projects-toggle-test",children:v?"Hide test projects":"Show test projects"}),e.jsxs(s,{variant:"ghost",onClick:()=>void H(),"data-testid":"projects-scan",children:[e.jsx(ae,{size:14,"aria-hidden":!0})," Scan configured dir"]}),e.jsxs(s,{variant:"ghost",onClick:()=>void B(),"data-testid":"projects-auto-detect",children:[e.jsx(W,{size:14,"aria-hidden":!0})," Auto-detect cwd"]}),e.jsxs(s,{variant:"ghost",onClick:()=>void n(),"data-testid":"projects-refresh",children:[e.jsx(ee,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(s,{variant:"primary",onClick:()=>j(!0),"data-testid":"projects-add",children:[e.jsx(T,{size:14,"aria-hidden":!0})," Add project"]})]})}),e.jsx(G,{title:"Registered",count:d.length,testid:"projects-list-header"}),e.jsx(K,{variant:"default",children:e.jsx(Q,{children:i.loading&&d.length===0?e.jsxs(l,{gap:2,children:[e.jsx(z,{style:{height:36}}),e.jsx(z,{style:{height:36}})]}):d.length===0?e.jsx(_,{icon:e.jsx(T,{size:28,"aria-hidden":!0}),title:"No projects yet",description:"Add a path, auto-detect the server cwd, or scan the configured projects directory."}):e.jsx(l,{gap:2,children:d.map(t=>{const a=t.id===I,L=M===t.id;return e.jsxs("div",{"data-testid":`project-row-${t.id}`,style:{padding:"var(--space-3)",borderRadius:"var(--radius-md)",border:a?"1px solid var(--accent)":"1px solid var(--border)",background:a?"color-mix(in oklch, var(--accent) 12%, transparent)":"var(--surface-0)"},children:[e.jsxs(c,{align:"center",justify:"between",gap:3,children:[e.jsxs(l,{gap:1,style:{minWidth:0},children:[e.jsxs(c,{align:"center",gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:t.name||t.path.split("/").pop()||t.id}),a&&e.jsx(J,{tone:"success",children:"Active"})]}),e.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",color:"var(--fg-muted)",overflowWrap:"anywhere"},children:t.path})]}),e.jsxs(c,{gap:1,children:[!a&&e.jsx(s,{variant:"primary",onClick:()=>void F(t.id),"data-testid":`project-activate-${t.id}`,children:"Activate"}),e.jsxs(s,{variant:"ghost",onClick:()=>u(N=>N===t.id?null:t.id),"data-testid":`project-delete-${t.id}`,"aria-label":`Remove project ${t.id}`,children:[e.jsx(te,{size:14,"aria-hidden":!0})," Remove"]})]})]}),L&&e.jsxs(c,{gap:1,style:{marginTop:"var(--space-2)"},children:[e.jsx(s,{variant:"danger",onClick:()=>void O(t.id),"data-testid":`project-confirm-delete-${t.id}`,children:"Confirm remove"}),e.jsx(s,{variant:"ghost",onClick:()=>u(null),"data-testid":`project-cancel-delete-${t.id}`,children:"Cancel"})]})]},t.id)})})})}),e.jsx(U,{open:E,onOpenChange:j,children:e.jsx(X,{side:"right",title:"Add project",description:"Register an existing directory as a project root.",children:e.jsxs(l,{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:"Path"}),e.jsx(P,{placeholder:"/absolute/path/to/project",value:m,"data-testid":"projects-add-path",onChange:t=>f(t.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:"Display name (optional)"}),e.jsx(P,{placeholder:"My project",value:x,"data-testid":"projects-add-name",onChange:t=>y(t.target.value)})]}),e.jsxs(c,{justify:"end",gap:2,children:[e.jsx(Y,{asChild:!0,children:e.jsx(s,{variant:"ghost","data-testid":"projects-add-cancel",children:"Cancel"})}),e.jsx(s,{variant:"primary",onClick:()=>void $(),disabled:S||m.trim()==="","data-testid":"projects-add-submit",children:"Add"})]})]})})})]})}export{je as ProjectsView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectsView-N9zqFZ_O.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/folder-plus.js","../../../node_modules/lucide-react/dist/esm/icons/scan-search.js","../../src/web/v8/views/Projects/ProjectsView.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 FolderPlus = createLucideIcon(\"FolderPlus\", [\n [\"path\", { d: \"M12 10v6\", key: \"1bos4e\" }],\n [\"path\", { d: \"M9 13h6\", key: \"1uhe8q\" }],\n [\n \"path\",\n {\n d: \"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z\",\n key: \"1kt360\"\n }\n ]\n]);\n\nexport { FolderPlus as default };\n//# sourceMappingURL=folder-plus.js.map\n","/**\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 ScanSearch = createLucideIcon(\"ScanSearch\", [\n [\"path\", { d: \"M3 7V5a2 2 0 0 1 2-2h2\", key: \"aa7l1z\" }],\n [\"path\", { d: \"M17 3h2a2 2 0 0 1 2 2v2\", key: \"4qcy5o\" }],\n [\"path\", { d: \"M21 17v2a2 2 0 0 1-2 2h-2\", key: \"6vwrx8\" }],\n [\"path\", { d: \"M7 21H5a2 2 0 0 1-2-2v-2\", key: \"ioqczr\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }],\n [\"path\", { d: \"m16 16-1.9-1.9\", key: \"1dq9hf\" }]\n]);\n\nexport { ScanSearch as default };\n//# sourceMappingURL=scan-search.js.map\n","/**\n * v8/views/Projects/ProjectsView.tsx — Sprint S39, v9.3.0.\n *\n * The project registry surface. Shows every registered project,\n * lets the user mark one active, add by path (Sheet form), and\n * remove (inline confirm). Two utility actions sit in the header:\n * - Auto-detect: POST /api/projects/auto-detect (adds cwd)\n * - Scan: POST /api/projects/scan (walks the configured\n * dashboard.projectsDirectory and adds any new\n * roots it finds).\n *\n * Live refresh on the `project:change` WS event the server already\n * broadcasts from routes/projects.mjs.\n */\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { FolderPlus, RefreshCcw, ScanSearch, Sparkles, Trash2 } 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 { Badge } from '../../ui/data/Badge.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport type { Project, WsMessage } from '../../data/types.js';\n\ninterface ProjectsPayload {\n projects: Project[];\n}\n\n/** Returns true for internal harness/CI test project IDs. */\nfunction isTestProject(p: Project): boolean {\n return (\n /^(bizar-(e2e|real-env|admin)|bh-(cold-boot|walk-proj))/.test(p.id) ||\n (p.name != null && p.name === p.id)\n );\n}\n\nexport function ProjectsView(): JSX.Element {\n const payload = useFetch<ProjectsPayload>('/api/projects');\n const [adding, setAdding] = useState<boolean>(false);\n const [newPath, setNewPath] = useState<string>('');\n const [newName, setNewName] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);\n const [showTestProjects, setShowTestProjects] = useState<boolean>(false);\n\n const allProjects = payload.data?.projects ?? [];\n const projects = showTestProjects ? allProjects : allProjects.filter((p) => !isTestProject(p));\n const activeId = projects.find((p) => p.active)?.id ?? null;\n\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n useWsMessage('project:change', refresh);\n\n const add = async (): Promise<void> => {\n const path = newPath.trim();\n if (!path || busy) return;\n setBusy(true);\n setError(null);\n try {\n await fetchJson<Project>('/api/projects', {\n method: 'POST',\n body: { path, name: newName.trim() || null },\n });\n setNewPath('');\n setNewName('');\n setAdding(false);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n };\n\n const activate = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/projects/${id}/activate`, { method: 'POST', body: {} });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const remove = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/projects/${id}`, { method: 'DELETE' });\n setConfirmDeleteId(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const autoDetect = async (): Promise<void> => {\n setError(null);\n try {\n await fetchJson('/api/projects/auto-detect', { method: 'POST', body: {} });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const scan = async (): Promise<void> => {\n setError(null);\n try {\n await fetchJson('/api/projects/scan', { method: 'POST', body: {} });\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=\"projects-view\">\n <ViewHeader\n title=\"Projects\"\n description=\"Registered project roots. One is active at a time — every active-project endpoint scopes to it.\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"projects-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n {allProjects.some((p) => isTestProject(p)) && (\n <Button\n variant={showTestProjects ? 'primary' : 'ghost'}\n size=\"sm\"\n onClick={() => setShowTestProjects((v) => !v)}\n data-testid=\"projects-toggle-test\"\n >\n {showTestProjects ? 'Hide test projects' : 'Show test projects'}\n </Button>\n )}\n <Button variant=\"ghost\" onClick={() => void scan()} data-testid=\"projects-scan\">\n <ScanSearch size={14} aria-hidden /> Scan configured dir\n </Button>\n <Button variant=\"ghost\" onClick={() => void autoDetect()} data-testid=\"projects-auto-detect\">\n <Sparkles size={14} aria-hidden /> Auto-detect cwd\n </Button>\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"projects-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => setAdding(true)} data-testid=\"projects-add\">\n <FolderPlus size={14} aria-hidden /> Add project\n </Button>\n </Inline>\n }\n />\n <ListHeader title=\"Registered\" count={projects.length} testid=\"projects-list-header\" />\n\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && projects.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 36 }} />\n <Skeleton style={{ height: 36 }} />\n </Stack>\n ) : projects.length === 0 ? (\n <EmptyState\n icon={<FolderPlus size={28} aria-hidden />}\n title=\"No projects yet\"\n description=\"Add a path, auto-detect the server cwd, or scan the configured projects directory.\"\n />\n ) : (\n <Stack gap={2}>\n {projects.map((p) => {\n const isActive = p.id === activeId;\n const isConfirmingDelete = confirmDeleteId === p.id;\n return (\n <div\n key={p.id}\n data-testid={`project-row-${p.id}`}\n style={{\n padding: 'var(--space-3)',\n borderRadius: 'var(--radius-md)',\n border: isActive ? '1px solid var(--accent)' : '1px solid var(--border)',\n background: isActive ? 'color-mix(in oklch, var(--accent) 12%, transparent)' : 'var(--surface-0)',\n }}\n >\n <Inline align=\"center\" justify=\"between\" gap={3}>\n <Stack gap={1} style={{ minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>\n {p.name || p.path.split('/').pop() || p.id}\n </strong>\n {isActive && <Badge tone=\"success\">Active</Badge>}\n </Inline>\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)', overflowWrap: 'anywhere' }}>\n {p.path}\n </span>\n </Stack>\n <Inline gap={1}>\n {!isActive && (\n <Button variant=\"primary\" onClick={() => void activate(p.id)} data-testid={`project-activate-${p.id}`}>\n Activate\n </Button>\n )}\n <Button\n variant=\"ghost\"\n onClick={() => setConfirmDeleteId((cur) => (cur === p.id ? null : p.id))}\n data-testid={`project-delete-${p.id}`}\n aria-label={`Remove project ${p.id}`}\n >\n <Trash2 size={14} aria-hidden /> Remove\n </Button>\n </Inline>\n </Inline>\n {isConfirmingDelete && (\n <Inline gap={1} style={{ marginTop: 'var(--space-2)' }}>\n <Button variant=\"danger\" onClick={() => void remove(p.id)} data-testid={`project-confirm-delete-${p.id}`}>\n Confirm remove\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDeleteId(null)} data-testid={`project-cancel-delete-${p.id}`}>\n Cancel\n </Button>\n </Inline>\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 project\" description=\"Register an existing directory as a project root.\">\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)' }}>Path</span>\n <Input\n placeholder=\"/absolute/path/to/project\"\n value={newPath}\n data-testid=\"projects-add-path\"\n onChange={(e) => setNewPath((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)' }}>Display name (optional)</span>\n <Input\n placeholder=\"My project\"\n value={newName}\n data-testid=\"projects-add-name\"\n onChange={(e) => setNewName((e.target as HTMLInputElement).value)}\n />\n </label>\n <Inline justify=\"end\" gap={2}>\n <SheetClose asChild>\n <Button variant=\"ghost\" data-testid=\"projects-add-cancel\">Cancel</Button>\n </SheetClose>\n <Button variant=\"primary\" onClick={() => void add()} disabled={busy || newPath.trim() === ''} data-testid=\"projects-add-submit\">\n Add\n </Button>\n </Inline>\n </Stack>\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}"],"names":["FolderPlus","createLucideIcon","ScanSearch","isTestProject","p","ProjectsView","payload","useFetch","adding","setAdding","useState","newPath","setNewPath","newName","setNewName","busy","setBusy","error","setError","confirmDeleteId","setConfirmDeleteId","showTestProjects","setShowTestProjects","allProjects","_a","projects","activeId","_b","refresh","useCallback","useWsMessage","add","path","fetchJson","err","FetchError","activate","id","remove","autoDetect","scan","jsxs","Stack","jsx","ViewHeader","Inline","Button","v","Sparkles","RefreshCcw","ListHeader","Card","CardBody","Skeleton","EmptyState","isActive","isConfirmingDelete","Badge","cur","Trash2","Sheet","SheetContent","Input","e","SheetClose"],"mappings":"wgBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAaC,EAAiB,aAAc,CAChD,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,EACzC,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CACE,OACA,CACE,EAAG,yHACH,IAAK,QACX,CACA,CACA,CAAC,ECnBD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMC,GAAaD,EAAiB,aAAc,CAChD,CAAC,OAAQ,CAAE,EAAG,yBAA0B,IAAK,QAAQ,CAAE,EACvD,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAQ,CAAE,EACxD,CAAC,OAAQ,CAAE,EAAG,4BAA6B,IAAK,QAAQ,CAAE,EAC1D,CAAC,OAAQ,CAAE,EAAG,2BAA4B,IAAK,QAAQ,CAAE,EACzD,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,SAAU,EACxD,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAQ,CAAE,CACjD,CAAC,ECsBD,SAASE,EAAcC,EAAqB,CAC1C,MACE,yDAAyD,KAAKA,EAAE,EAAE,GACjEA,EAAE,MAAQ,MAAQA,EAAE,OAASA,EAAE,EAEpC,CAEO,SAASC,IAA4B,SAC1C,MAAMC,EAAUC,EAA0B,eAAe,EACnD,CAACC,EAAQC,CAAS,EAAIC,EAAAA,SAAkB,EAAK,EAC7C,CAACC,EAASC,CAAU,EAAIF,EAAAA,SAAiB,EAAE,EAC3C,CAACG,EAASC,CAAU,EAAIJ,EAAAA,SAAiB,EAAE,EAC3C,CAACK,EAAMC,CAAO,EAAIN,EAAAA,SAAkB,EAAK,EACzC,CAACO,EAAOC,CAAQ,EAAIR,EAAAA,SAAwB,IAAI,EAChD,CAACS,EAAiBC,CAAkB,EAAIV,EAAAA,SAAwB,IAAI,EACpE,CAACW,EAAkBC,CAAmB,EAAIZ,EAAAA,SAAkB,EAAK,EAEjEa,IAAcC,EAAAlB,EAAQ,OAAR,YAAAkB,EAAc,WAAY,CAAA,EACxCC,EAAWJ,EAAmBE,EAAcA,EAAY,OAAQnB,GAAM,CAACD,EAAcC,CAAC,CAAC,EACvFsB,IAAWC,EAAAF,EAAS,KAAMrB,GAAMA,EAAE,MAAM,IAA7B,YAAAuB,EAAgC,KAAM,KAEjDC,EAAUC,EAAAA,YAAY,IAAM,CAAOvB,EAAQ,QAAA,CAAW,EAAG,CAACA,CAAO,CAAC,EACxEwB,EAAa,iBAAkBF,CAAO,EAEtC,MAAMG,EAAM,SAA2B,CACrC,MAAMC,EAAOrB,EAAQ,KAAA,EACrB,GAAI,GAACqB,GAAQjB,GACb,CAAAC,EAAQ,EAAI,EACZE,EAAS,IAAI,EACb,GAAI,CACF,MAAMe,EAAmB,gBAAiB,CACxC,OAAQ,OACR,KAAM,CAAE,KAAAD,EAAM,KAAMnB,EAAQ,KAAA,GAAU,IAAA,CAAK,CAC5C,EACDD,EAAW,EAAE,EACbE,EAAW,EAAE,EACbL,EAAU,EAAK,EACfmB,EAAA,CACF,OAASM,EAAK,CACZhB,GAASgB,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,QAAA,CACElB,EAAQ,EAAK,CACf,EACF,EAEMoB,EAAW,MAAOC,GAA8B,CACpDnB,EAAS,IAAI,EACb,GAAI,CACF,MAAMe,EAAU,iBAAiBI,CAAE,YAAa,CAAE,OAAQ,OAAQ,KAAM,CAAA,EAAI,EAC5ET,EAAA,CACF,OAASM,EAAK,CACZhB,GAASgB,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,CACF,EAEMI,EAAS,MAAOD,GAA8B,CAClDnB,EAAS,IAAI,EACb,GAAI,CACF,MAAMe,EAAU,iBAAiBI,CAAE,GAAI,CAAE,OAAQ,SAAU,EAC3DjB,EAAmB,IAAI,EACvBQ,EAAA,CACF,OAASM,EAAK,CACZhB,GAASgB,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,CACF,EAEMK,EAAa,SAA2B,CAC5CrB,EAAS,IAAI,EACb,GAAI,CACF,MAAMe,EAAU,4BAA6B,CAAE,OAAQ,OAAQ,KAAM,CAAA,EAAI,EACzEL,EAAA,CACF,OAASM,EAAK,CACZhB,GAASgB,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,CACF,EAEMM,EAAO,SAA2B,CACtCtB,EAAS,IAAI,EACb,GAAI,CACF,MAAMe,EAAU,qBAAsB,CAAE,OAAQ,OAAQ,KAAM,CAAA,EAAI,EAClEL,EAAA,CACF,OAASM,EAAK,CACZhB,GAASgB,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,CACF,EAEA,OACEO,EAAAA,KAACC,EAAA,CAAM,IAAK,EAAG,cAAY,gBACzB,SAAA,CAAAC,EAAAA,IAACC,EAAA,CACC,MAAM,WACN,YAAY,kGACZ,QACEH,EAAAA,KAACI,EAAA,CAAO,MAAM,SAAS,IAAK,EACzB,SAAA,CAAA5B,IAAU,MACT0B,MAAC,OAAA,CAAK,KAAK,QAAQ,cAAY,iBAAiB,MAAO,CAAE,MAAO,gBAAiB,SAAU,gBACxF,SAAA1B,EACH,EAEDM,EAAY,KAAMnB,GAAMD,EAAcC,CAAC,CAAC,GACvCuC,EAAAA,IAACG,EAAA,CACC,QAASzB,EAAmB,UAAY,QACxC,KAAK,KACL,QAAS,IAAMC,EAAqByB,GAAM,CAACA,CAAC,EAC5C,cAAY,uBAEX,WAAmB,qBAAuB,oBAAA,CAAA,EAG/CN,EAAAA,KAACK,EAAA,CAAO,QAAQ,QAAQ,QAAS,IAAM,KAAKN,EAAA,EAAQ,cAAY,gBAC9D,SAAA,CAAAG,EAAAA,IAACzC,GAAA,CAAW,KAAM,GAAI,cAAW,GAAC,EAAE,sBAAA,EACtC,EACAuC,EAAAA,KAACK,EAAA,CAAO,QAAQ,QAAQ,QAAS,IAAM,KAAKP,EAAA,EAAc,cAAY,uBACpE,SAAA,CAAAI,EAAAA,IAACK,EAAA,CAAS,KAAM,GAAI,cAAW,GAAC,EAAE,kBAAA,EACpC,EACAP,EAAAA,KAACK,EAAA,CAAO,QAAQ,QAAQ,QAAS,IAAM,KAAKlB,EAAA,EAAW,cAAY,mBACjE,SAAA,CAAAe,EAAAA,IAACM,GAAA,CAAW,KAAM,GAAI,cAAW,GAAC,EAAE,UAAA,EACtC,EACAR,EAAAA,KAACK,EAAA,CAAO,QAAQ,UAAU,QAAS,IAAMrC,EAAU,EAAI,EAAG,cAAY,eACpE,SAAA,CAAAkC,EAAAA,IAAC3C,EAAA,CAAW,KAAM,GAAI,cAAW,GAAC,EAAE,cAAA,CAAA,CACtC,CAAA,CAAA,CACF,CAAA,CAAA,EAGJ2C,MAACO,GAAW,MAAM,aAAa,MAAOzB,EAAS,OAAQ,OAAO,uBAAuB,EAErFkB,MAACQ,EAAA,CAAK,QAAQ,UACZ,eAACC,EAAA,CACE,SAAA9C,EAAQ,SAAWmB,EAAS,SAAW,EACtCgB,EAAAA,KAACC,EAAA,CAAM,IAAK,EACV,SAAA,CAAAC,EAAAA,IAACU,EAAA,CAAS,MAAO,CAAE,OAAQ,IAAM,QAChCA,EAAA,CAAS,MAAO,CAAE,OAAQ,GAAG,CAAG,CAAA,CAAA,CACnC,EACE5B,EAAS,SAAW,EACtBkB,EAAAA,IAACW,EAAA,CACC,KAAMX,EAAAA,IAAC3C,EAAA,CAAW,KAAM,GAAI,cAAW,GAAC,EACxC,MAAM,kBACN,YAAY,oFAAA,CAAA,QAGb0C,EAAA,CAAM,IAAK,EACT,SAAAjB,EAAS,IAAKrB,GAAM,CACnB,MAAMmD,EAAWnD,EAAE,KAAOsB,EACpB8B,EAAqBrC,IAAoBf,EAAE,GACjD,OACEqC,EAAAA,KAAC,MAAA,CAEC,cAAa,eAAerC,EAAE,EAAE,GAChC,MAAO,CACL,QAAS,iBACT,aAAc,mBACd,OAAQmD,EAAW,0BAA4B,0BAC/C,WAAYA,EAAW,sDAAwD,kBAAA,EAGjF,SAAA,CAAAd,OAACI,GAAO,MAAM,SAAS,QAAQ,UAAU,IAAK,EAC5C,SAAA,CAAAJ,OAACC,GAAM,IAAK,EAAG,MAAO,CAAE,SAAU,GAChC,SAAA,CAAAD,EAAAA,KAACI,EAAA,CAAO,MAAM,SAAS,IAAK,EAC1B,SAAA,CAAAF,EAAAA,IAAC,UAAO,MAAO,CAAE,SAAU,cAAA,EACxB,SAAAvC,EAAE,MAAQA,EAAE,KAAK,MAAM,GAAG,EAAE,OAASA,EAAE,GAC1C,EACCmD,GAAYZ,EAAAA,IAACc,EAAA,CAAM,KAAK,UAAU,SAAA,QAAA,CAAM,CAAA,EAC3C,EACAd,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,WAAY,mBAAoB,SAAU,eAAgB,MAAO,kBAAmB,aAAc,UAAA,EAC9G,WAAE,IAAA,CACL,CAAA,EACF,EACAF,EAAAA,KAACI,EAAA,CAAO,IAAK,EACV,SAAA,CAAA,CAACU,GACAZ,EAAAA,IAACG,EAAA,CAAO,QAAQ,UAAU,QAAS,IAAM,KAAKV,EAAShC,EAAE,EAAE,EAAG,cAAa,oBAAoBA,EAAE,EAAE,GAAI,SAAA,WAEvG,EAEFqC,EAAAA,KAACK,EAAA,CACC,QAAQ,QACR,QAAS,IAAM1B,EAAoBsC,GAASA,IAAQtD,EAAE,GAAK,KAAOA,EAAE,EAAG,EACvE,cAAa,kBAAkBA,EAAE,EAAE,GACnC,aAAY,kBAAkBA,EAAE,EAAE,GAElC,SAAA,CAAAuC,EAAAA,IAACgB,GAAA,CAAO,KAAM,GAAI,cAAW,GAAC,EAAE,SAAA,CAAA,CAAA,CAClC,CAAA,CACF,CAAA,EACF,EACCH,UACEX,EAAA,CAAO,IAAK,EAAG,MAAO,CAAE,UAAW,gBAAA,EAClC,SAAA,CAAAF,EAAAA,IAACG,EAAA,CAAO,QAAQ,SAAS,QAAS,IAAM,KAAKR,EAAOlC,EAAE,EAAE,EAAG,cAAa,0BAA0BA,EAAE,EAAE,GAAI,SAAA,iBAE1G,EACAuC,EAAAA,IAACG,EAAA,CAAO,QAAQ,QAAQ,QAAS,IAAM1B,EAAmB,IAAI,EAAG,cAAa,yBAAyBhB,EAAE,EAAE,GAAI,SAAA,QAAA,CAE/G,CAAA,CAAA,CACF,CAAA,CAAA,EA7CGA,EAAE,EAAA,CAiDb,CAAC,CAAA,CACH,CAAA,CAEJ,EACF,EAEAuC,EAAAA,IAACiB,GAAM,KAAMpD,EAAQ,aAAcC,EACjC,SAAAkC,EAAAA,IAACkB,EAAA,CAAa,KAAK,QAAQ,MAAM,cAAc,YAAY,oDACzD,gBAACnB,EAAA,CAAM,IAAK,EAAG,MAAO,CAAE,QAAS,gBAAA,EAC/B,SAAA,CAAAD,EAAAA,KAAC,QAAA,CAAM,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,gBAAA,EAC7D,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,MAAA,CAAI,EACzEA,EAAAA,IAACmB,EAAA,CACC,YAAY,4BACZ,MAAOnD,EACP,cAAY,oBACZ,SAAWoD,GAAMnD,EAAYmD,EAAE,OAA4B,KAAK,CAAA,CAAA,CAClE,EACF,EACAtB,EAAAA,KAAC,QAAA,CAAM,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,gBAAA,EAC7D,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,yBAAA,CAAuB,EAC5FA,EAAAA,IAACmB,EAAA,CACC,YAAY,aACZ,MAAOjD,EACP,cAAY,oBACZ,SAAWkD,GAAMjD,EAAYiD,EAAE,OAA4B,KAAK,CAAA,CAAA,CAClE,EACF,EACAtB,EAAAA,KAACI,EAAA,CAAO,QAAQ,MAAM,IAAK,EACzB,SAAA,CAAAF,EAAAA,IAACqB,EAAA,CAAW,QAAO,GACjB,SAAArB,EAAAA,IAACG,EAAA,CAAO,QAAQ,QAAQ,cAAY,sBAAsB,SAAA,QAAA,CAAM,EAClE,QACCA,EAAA,CAAO,QAAQ,UAAU,QAAS,IAAM,KAAKf,IAAO,SAAUhB,GAAQJ,EAAQ,SAAW,GAAI,cAAY,sBAAsB,SAAA,KAAA,CAEhI,CAAA,CAAA,CACF,CAAA,CAAA,CACF,EACF,CAAA,CACF,CAAA,EACF,CAEJ","x_google_ignoreList":[0,1]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as c,j as r}from"./cmdk-
|
|
1
|
+
import{r as c,j as r}from"./cmdk-C3F6LD6N.js";import{c as P,u as R,i as n,S as m,I as l,d,w as B,h as z,j as M,F as u}from"./main-BZMmD6a8.js";import{V as N}from"./ViewHeader-BaCWNuVX.js";import{L as F}from"./ListHeader-BLAeshe0.js";import{C as x,b as j}from"./Card-BmXiT4c6.js";import{E as H}from"./EmptyState-CdDQmfEL.js";import{R as _}from"./refresh-ccw-BL7B0NO1.js";import{P as J}from"./plus-uA5Ecuch.js";import{R as W}from"./rotate-cw-CHgXCO7O.js";import{P as Y}from"./pencil---XuvKlz.js";import{P as q}from"./power-off-1CAQsHHy.js";import{P as G}from"./power-DSUlNIuR.js";import{T as Q}from"./trash-2-B885GY46.js";/**
|
|
2
2
|
* @license lucide-react v0.460.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
package/bizar-dash/dist/assets/{ProvidersView-BftGn8Cr.js.map → ProvidersView-BcL8jjwK.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProvidersView-BftGn8Cr.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/key-round.js","../../../node_modules/lucide-react/dist/esm/icons/star.js","../../src/web/v8/views/Providers/ProvidersView.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 KeyRound = createLucideIcon(\"KeyRound\", [\n [\n \"path\",\n {\n d: \"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z\",\n key: \"1s6t7t\"\n }\n ],\n [\"circle\", { cx: \"16.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"w0ekpg\" }]\n]);\n\nexport { KeyRound as default };\n//# sourceMappingURL=key-round.js.map\n","/**\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 Star = createLucideIcon(\"Star\", [\n [\n \"path\",\n {\n d: \"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\",\n key: \"r04s7s\"\n }\n ]\n]);\n\nexport { Star as default };\n//# sourceMappingURL=star.js.map\n","/**\n * v8/views/Providers/ProvidersView.tsx — Sprint S42, v9.3.0.\n *\n * Provider list pulled from /api/providers (aggregated). Per-row:\n * - active-key card (GET /api/providers/:id/active-key) with masked\n * key preview + label + status\n * - rotate button (POST /api/providers/:id/rotate) with inline confirm\n *\n * Header actions:\n * - Active default card (GET /api/providers/active)\n * - Auto-detect (GET /api/providers/auto-detect)\n *\n * Inline confirm row pattern; no window.confirm.\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { KeyRound, Pencil, Plus, Power, PowerOff, RotateCw, Sparkles, Star, Trash2, RefreshCcw, Cpu } 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 { 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 Provider {\n id: string;\n name?: string;\n source?: string;\n baseURL?: string;\n models?: string[];\n keys?: ProviderKey[];\n active?: boolean;\n enabled?: boolean;\n}\n\ninterface ProviderKey {\n envVar?: string;\n label?: string;\n status?: string;\n}\n\ninterface ActiveKey {\n envVar: string;\n label?: string;\n status?: string;\n keyPreview: string;\n keySet: boolean;\n}\n\ninterface ActiveDefault {\n providerId: string | null;\n modelId: string | null;\n source?: string | null;\n}\n\nexport function ProvidersView(): JSX.Element {\n const payload = useFetch<{ providers: Provider[]; count: number }>('/api/providers');\n const activePayload = useFetch<ActiveDefault>('/api/providers/active');\n const [confirmRotate, setConfirmRotate] = useState<string | null>(null);\n const [activeKeys, setActiveKeys] = useState<Record<string, ActiveKey | null>>({});\n const [error, setError] = useState<string | null>(null);\n const [autoDetect, setAutoDetect] = useState<{ providers: Provider[] } | null>(null);\n const [probing, setProbing] = useState<boolean>(false);\n\n const providers = useMemo<Provider[]>(() => payload.data?.providers ?? [], [payload.data]);\n const refresh = useCallback(() => { void payload.refetch(); void activePayload.refetch(); }, [payload, activePayload]);\n\n // Fetch the active key for each provider (lazy, in parallel).\n useEffect(() => {\n if (!providers.length) return;\n let cancelled = false;\n (async () => {\n const results = await Promise.all(\n providers.map(async (p) => {\n try {\n const r = await fetchJson<{ ok: boolean; active: ActiveKey } | { ok: false; error: string }>(`/api/providers/${p.id}/active-key`);\n return [p.id, ('active' in r ? r.active : null)] as const;\n } catch {\n return [p.id, null] as const;\n }\n }),\n );\n if (!cancelled) {\n const map: Record<string, ActiveKey | null> = {};\n for (const [id, ak] of results) map[id] = ak;\n setActiveKeys(map);\n }\n })();\n return () => { cancelled = true; };\n }, [providers]);\n\n const rotate = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/providers/${id}/rotate`, { method: 'POST' });\n setConfirmRotate(null);\n refresh();\n // Re-fetch the new active key for this row.\n try {\n const r = await fetchJson<{ ok: boolean; active: ActiveKey }>(`/api/providers/${id}/active-key`);\n setActiveKeys((m) => ({ ...m, [id]: r.active }));\n } catch { /* ignore */ }\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const addKey = async (id: string): Promise<void> => {\n const envVar = window.prompt(`Env var name to add to ${id} (e.g. ${id.toUpperCase()}_KEY_2)`);\n if (!envVar?.trim()) return;\n const label = window.prompt('Label (optional)') || undefined;\n setError(null);\n try {\n await fetchJson(`/api/providers/${id}/keys`, { method: 'POST', body: { envVar, label } });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const runAutoDetect = async (): Promise<void> => {\n setProbing(true);\n setError(null);\n try {\n const r = await fetchJson<{ providers: Provider[] }>('/api/providers/auto-detect');\n setAutoDetect({ providers: r.providers });\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setProbing(false);\n }\n };\n\n const createProvider = async (): Promise<void> => {\n const id = window.prompt('Provider id (lowercase, e.g. openai)');\n if (!id?.trim()) return;\n const name = window.prompt('Display name') || id;\n const baseURL = window.prompt('Base URL (optional)') || '';\n const apiKey = window.prompt('API key or env:VAR marker') || '';\n setError(null);\n try {\n await fetchJson('/api/providers', { method: 'POST', body: { id, name, baseURL, apiKey } });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const editProvider = async (p: Provider): Promise<void> => {\n const name = window.prompt(`Rename ${p.id}`, p.name || p.id);\n if (!name?.trim()) return;\n const baseURL = window.prompt('Base URL', p.baseURL || '');\n setError(null);\n try {\n await fetchJson(`/api/providers/${encodeURIComponent(p.id)}`, {\n method: 'PUT',\n body: { name, baseURL: baseURL ?? '' },\n });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const deleteProvider = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/providers/${encodeURIComponent(id)}`, { method: 'DELETE' });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const toggleEnabled = async (id: string, currentlyEnabled: boolean): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/providers/${encodeURIComponent(id)}/${currentlyEnabled ? 'disable' : 'enable'}`, { method: 'POST' });\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=\"providers-view\">\n <ViewHeader\n title=\"Providers\"\n description=\"Configured LLM providers + active key rotation.\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"providers-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"providers-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => void runAutoDetect()} disabled={probing} data-testid=\"providers-auto-detect\">\n <Sparkles size={14} aria-hidden /> {probing ? 'Probing…' : 'Auto-detect'}\n </Button>\n <Button variant=\"primary\" onClick={() => void createProvider()} data-testid=\"providers-create\">\n <Plus size={14} aria-hidden /> New provider\n </Button>\n </Inline>\n }\n />\n <ListHeader\n title=\"Configured\"\n count={providers.length}\n description={activePayload.data?.providerId ? `active: ${activePayload.data.providerId}` : undefined}\n testid=\"providers-list-header\"\n />\n\n {activePayload.data && (activePayload.data.providerId !== null || activePayload.data.modelId !== null) && (\n <Card variant=\"default\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Inline align=\"center\" gap={2}>\n <Star size={14} aria-hidden style={{ color: 'var(--accent)' }} />\n <strong>Active default:</strong>\n <code data-testid=\"providers-active-provider\">{activePayload.data.providerId ?? '—'}</code>\n <span style={{ color: 'var(--fg-muted)' }}>·</span>\n <code data-testid=\"providers-active-model\">{activePayload.data.modelId ?? '—'}</code>\n {activePayload.data.source && (\n <span style={{ color: 'var(--fg-subtle)', fontSize: 'var(--fs-12)' }}>({activePayload.data.source})</span>\n )}\n </Inline>\n </Inline>\n </CardBody>\n </Card>\n )}\n\n {autoDetect !== null && (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Auto-detect result</strong>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {autoDetect.providers.length} candidate{autoDetect.providers.length === 1 ? '' : 's'} from env + config.\n </span>\n </Stack>\n </CardBody>\n </Card>\n )}\n\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && providers.length === 0 ? (\n <Stack gap={1}>\n <Skeleton style={{ height: 56 }} />\n <Skeleton style={{ height: 56 }} />\n </Stack>\n ) : providers.length === 0 ? (\n <EmptyState icon={<Cpu size={28} aria-hidden />} title=\"No providers\" description=\"Run Auto-detect or add via Config → Providers.\" />\n ) : (\n <Stack gap={1}>\n {providers.map((p) => {\n const isConfirming = confirmRotate === p.id;\n const ak = activeKeys[p.id];\n return (\n <div\n key={p.id}\n data-testid={`provider-row-${p.id}`}\n style={{\n padding: 'var(--space-3)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: 'var(--surface-0)',\n }}\n >\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Stack gap={0}>\n <Inline align=\"center\" gap={2}>\n <strong>{p.name || p.id}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{p.id}</code>\n {p.source && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>· {p.source}</span>}\n {p.active && (\n <span data-testid={`provider-active-${p.id}`} style={{ fontSize: 'var(--fs-11)', color: 'var(--success)', fontWeight: 600 }}>ACTIVE</span>\n )}\n </Inline>\n {p.baseURL && <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{p.baseURL}</code>}\n </Stack>\n <Inline gap={1}>\n <Button\n variant=\"ghost\"\n onClick={() => setConfirmRotate((cur) => (cur === p.id ? null : p.id))}\n data-testid={`provider-rotate-${p.id}`}\n aria-label={`Rotate ${p.id}`}\n disabled={!p.keys || p.keys.length < 2}\n title={!p.keys || p.keys.length < 2 ? 'Need ≥2 keys to rotate' : 'Rotate active key'}\n >\n <RotateCw size={14} aria-hidden /> Rotate\n </Button>\n <Button\n variant=\"primary\"\n onClick={() => void addKey(p.id)}\n data-testid={`provider-add-key-${p.id}`}\n aria-label={`Add key to ${p.id}`}\n >\n <KeyRound size={14} aria-hidden /> Add key\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => void editProvider(p)}\n data-testid={`provider-edit-${p.id}`}\n aria-label={`Edit ${p.id}`}\n >\n <Pencil size={14} aria-hidden />\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => void toggleEnabled(p.id, p.enabled ?? true)}\n data-testid={`provider-toggle-${p.id}`}\n aria-label={(p.enabled ?? true) ? `Disable ${p.id}` : `Enable ${p.id}`}\n >\n {(p.enabled ?? true) ? <PowerOff size={14} aria-hidden /> : <Power size={14} aria-hidden />}\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => void deleteProvider(p.id)}\n data-testid={`provider-delete-${p.id}`}\n aria-label={`Delete ${p.id}`}\n >\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n </Inline>\n\n {/* Active-key sub-row */}\n <div data-testid={`provider-active-key-${p.id}`} style={{ marginTop: 'var(--space-2)', padding: 'var(--space-2)', background: 'var(--surface-1)', borderRadius: 'var(--radius-sm)' }}>\n <Inline align=\"center\" gap={2}>\n <KeyRound size={12} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n {ak === undefined ? (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>Probing active key…</span>\n ) : ak === null ? (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>No active key</span>\n ) : (\n <Inline align=\"center\" gap={2} data-testid={`provider-active-key-detail-${p.id}`}>\n <code style={{ fontSize: 'var(--fs-12)' }}>{ak.envVar}</code>\n {ak.label && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>· {ak.label}</span>}\n {ak.status && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>· {ak.status}</span>}\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{ak.keyPreview}</code>\n </Inline>\n )}\n </Inline>\n </div>\n\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"primary\" onClick={() => void rotate(p.id)} data-testid={`provider-confirm-rotate-${p.id}`}>\n Confirm rotate\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmRotate(null)}>Cancel</Button>\n </Inline>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </CardBody>\n </Card>\n </Stack>\n );\n}"],"names":["KeyRound","createLucideIcon","Star","ProvidersView","payload","useFetch","activePayload","confirmRotate","setConfirmRotate","useState","activeKeys","setActiveKeys","error","setError","autoDetect","setAutoDetect","probing","setProbing","providers","useMemo","_a","refresh","useCallback","useEffect","cancelled","results","p","r","fetchJson","map","id","ak","rotate","m","err","FetchError","addKey","envVar","label","runAutoDetect","createProvider","name","baseURL","apiKey","editProvider","deleteProvider","toggleEnabled","currentlyEnabled","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCcw","Sparkles","Plus","ListHeader","Card","CardBody","Skeleton","EmptyState","Cpu","isConfirming","cur","RotateCw","Pencil","PowerOff","Power","Trash2"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
1
|
+
{"version":3,"file":"ProvidersView-BcL8jjwK.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/key-round.js","../../../node_modules/lucide-react/dist/esm/icons/star.js","../../src/web/v8/views/Providers/ProvidersView.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 KeyRound = createLucideIcon(\"KeyRound\", [\n [\n \"path\",\n {\n d: \"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z\",\n key: \"1s6t7t\"\n }\n ],\n [\"circle\", { cx: \"16.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"w0ekpg\" }]\n]);\n\nexport { KeyRound as default };\n//# sourceMappingURL=key-round.js.map\n","/**\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 Star = createLucideIcon(\"Star\", [\n [\n \"path\",\n {\n d: \"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z\",\n key: \"r04s7s\"\n }\n ]\n]);\n\nexport { Star as default };\n//# sourceMappingURL=star.js.map\n","/**\n * v8/views/Providers/ProvidersView.tsx — Sprint S42, v9.3.0.\n *\n * Provider list pulled from /api/providers (aggregated). Per-row:\n * - active-key card (GET /api/providers/:id/active-key) with masked\n * key preview + label + status\n * - rotate button (POST /api/providers/:id/rotate) with inline confirm\n *\n * Header actions:\n * - Active default card (GET /api/providers/active)\n * - Auto-detect (GET /api/providers/auto-detect)\n *\n * Inline confirm row pattern; no window.confirm.\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { KeyRound, Pencil, Plus, Power, PowerOff, RotateCw, Sparkles, Star, Trash2, RefreshCcw, Cpu } 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 { 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 Provider {\n id: string;\n name?: string;\n source?: string;\n baseURL?: string;\n models?: string[];\n keys?: ProviderKey[];\n active?: boolean;\n enabled?: boolean;\n}\n\ninterface ProviderKey {\n envVar?: string;\n label?: string;\n status?: string;\n}\n\ninterface ActiveKey {\n envVar: string;\n label?: string;\n status?: string;\n keyPreview: string;\n keySet: boolean;\n}\n\ninterface ActiveDefault {\n providerId: string | null;\n modelId: string | null;\n source?: string | null;\n}\n\nexport function ProvidersView(): JSX.Element {\n const payload = useFetch<{ providers: Provider[]; count: number }>('/api/providers');\n const activePayload = useFetch<ActiveDefault>('/api/providers/active');\n const [confirmRotate, setConfirmRotate] = useState<string | null>(null);\n const [activeKeys, setActiveKeys] = useState<Record<string, ActiveKey | null>>({});\n const [error, setError] = useState<string | null>(null);\n const [autoDetect, setAutoDetect] = useState<{ providers: Provider[] } | null>(null);\n const [probing, setProbing] = useState<boolean>(false);\n\n const providers = useMemo<Provider[]>(() => payload.data?.providers ?? [], [payload.data]);\n const refresh = useCallback(() => { void payload.refetch(); void activePayload.refetch(); }, [payload, activePayload]);\n\n // Fetch the active key for each provider (lazy, in parallel).\n useEffect(() => {\n if (!providers.length) return;\n let cancelled = false;\n (async () => {\n const results = await Promise.all(\n providers.map(async (p) => {\n try {\n const r = await fetchJson<{ ok: boolean; active: ActiveKey } | { ok: false; error: string }>(`/api/providers/${p.id}/active-key`);\n return [p.id, ('active' in r ? r.active : null)] as const;\n } catch {\n return [p.id, null] as const;\n }\n }),\n );\n if (!cancelled) {\n const map: Record<string, ActiveKey | null> = {};\n for (const [id, ak] of results) map[id] = ak;\n setActiveKeys(map);\n }\n })();\n return () => { cancelled = true; };\n }, [providers]);\n\n const rotate = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/providers/${id}/rotate`, { method: 'POST' });\n setConfirmRotate(null);\n refresh();\n // Re-fetch the new active key for this row.\n try {\n const r = await fetchJson<{ ok: boolean; active: ActiveKey }>(`/api/providers/${id}/active-key`);\n setActiveKeys((m) => ({ ...m, [id]: r.active }));\n } catch { /* ignore */ }\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const addKey = async (id: string): Promise<void> => {\n const envVar = window.prompt(`Env var name to add to ${id} (e.g. ${id.toUpperCase()}_KEY_2)`);\n if (!envVar?.trim()) return;\n const label = window.prompt('Label (optional)') || undefined;\n setError(null);\n try {\n await fetchJson(`/api/providers/${id}/keys`, { method: 'POST', body: { envVar, label } });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const runAutoDetect = async (): Promise<void> => {\n setProbing(true);\n setError(null);\n try {\n const r = await fetchJson<{ providers: Provider[] }>('/api/providers/auto-detect');\n setAutoDetect({ providers: r.providers });\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setProbing(false);\n }\n };\n\n const createProvider = async (): Promise<void> => {\n const id = window.prompt('Provider id (lowercase, e.g. openai)');\n if (!id?.trim()) return;\n const name = window.prompt('Display name') || id;\n const baseURL = window.prompt('Base URL (optional)') || '';\n const apiKey = window.prompt('API key or env:VAR marker') || '';\n setError(null);\n try {\n await fetchJson('/api/providers', { method: 'POST', body: { id, name, baseURL, apiKey } });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const editProvider = async (p: Provider): Promise<void> => {\n const name = window.prompt(`Rename ${p.id}`, p.name || p.id);\n if (!name?.trim()) return;\n const baseURL = window.prompt('Base URL', p.baseURL || '');\n setError(null);\n try {\n await fetchJson(`/api/providers/${encodeURIComponent(p.id)}`, {\n method: 'PUT',\n body: { name, baseURL: baseURL ?? '' },\n });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const deleteProvider = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/providers/${encodeURIComponent(id)}`, { method: 'DELETE' });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const toggleEnabled = async (id: string, currentlyEnabled: boolean): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/providers/${encodeURIComponent(id)}/${currentlyEnabled ? 'disable' : 'enable'}`, { method: 'POST' });\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=\"providers-view\">\n <ViewHeader\n title=\"Providers\"\n description=\"Configured LLM providers + active key rotation.\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"providers-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"providers-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => void runAutoDetect()} disabled={probing} data-testid=\"providers-auto-detect\">\n <Sparkles size={14} aria-hidden /> {probing ? 'Probing…' : 'Auto-detect'}\n </Button>\n <Button variant=\"primary\" onClick={() => void createProvider()} data-testid=\"providers-create\">\n <Plus size={14} aria-hidden /> New provider\n </Button>\n </Inline>\n }\n />\n <ListHeader\n title=\"Configured\"\n count={providers.length}\n description={activePayload.data?.providerId ? `active: ${activePayload.data.providerId}` : undefined}\n testid=\"providers-list-header\"\n />\n\n {activePayload.data && (activePayload.data.providerId !== null || activePayload.data.modelId !== null) && (\n <Card variant=\"default\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Inline align=\"center\" gap={2}>\n <Star size={14} aria-hidden style={{ color: 'var(--accent)' }} />\n <strong>Active default:</strong>\n <code data-testid=\"providers-active-provider\">{activePayload.data.providerId ?? '—'}</code>\n <span style={{ color: 'var(--fg-muted)' }}>·</span>\n <code data-testid=\"providers-active-model\">{activePayload.data.modelId ?? '—'}</code>\n {activePayload.data.source && (\n <span style={{ color: 'var(--fg-subtle)', fontSize: 'var(--fs-12)' }}>({activePayload.data.source})</span>\n )}\n </Inline>\n </Inline>\n </CardBody>\n </Card>\n )}\n\n {autoDetect !== null && (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Auto-detect result</strong>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {autoDetect.providers.length} candidate{autoDetect.providers.length === 1 ? '' : 's'} from env + config.\n </span>\n </Stack>\n </CardBody>\n </Card>\n )}\n\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && providers.length === 0 ? (\n <Stack gap={1}>\n <Skeleton style={{ height: 56 }} />\n <Skeleton style={{ height: 56 }} />\n </Stack>\n ) : providers.length === 0 ? (\n <EmptyState icon={<Cpu size={28} aria-hidden />} title=\"No providers\" description=\"Run Auto-detect or add via Config → Providers.\" />\n ) : (\n <Stack gap={1}>\n {providers.map((p) => {\n const isConfirming = confirmRotate === p.id;\n const ak = activeKeys[p.id];\n return (\n <div\n key={p.id}\n data-testid={`provider-row-${p.id}`}\n style={{\n padding: 'var(--space-3)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: 'var(--surface-0)',\n }}\n >\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Stack gap={0}>\n <Inline align=\"center\" gap={2}>\n <strong>{p.name || p.id}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{p.id}</code>\n {p.source && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>· {p.source}</span>}\n {p.active && (\n <span data-testid={`provider-active-${p.id}`} style={{ fontSize: 'var(--fs-11)', color: 'var(--success)', fontWeight: 600 }}>ACTIVE</span>\n )}\n </Inline>\n {p.baseURL && <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{p.baseURL}</code>}\n </Stack>\n <Inline gap={1}>\n <Button\n variant=\"ghost\"\n onClick={() => setConfirmRotate((cur) => (cur === p.id ? null : p.id))}\n data-testid={`provider-rotate-${p.id}`}\n aria-label={`Rotate ${p.id}`}\n disabled={!p.keys || p.keys.length < 2}\n title={!p.keys || p.keys.length < 2 ? 'Need ≥2 keys to rotate' : 'Rotate active key'}\n >\n <RotateCw size={14} aria-hidden /> Rotate\n </Button>\n <Button\n variant=\"primary\"\n onClick={() => void addKey(p.id)}\n data-testid={`provider-add-key-${p.id}`}\n aria-label={`Add key to ${p.id}`}\n >\n <KeyRound size={14} aria-hidden /> Add key\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => void editProvider(p)}\n data-testid={`provider-edit-${p.id}`}\n aria-label={`Edit ${p.id}`}\n >\n <Pencil size={14} aria-hidden />\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => void toggleEnabled(p.id, p.enabled ?? true)}\n data-testid={`provider-toggle-${p.id}`}\n aria-label={(p.enabled ?? true) ? `Disable ${p.id}` : `Enable ${p.id}`}\n >\n {(p.enabled ?? true) ? <PowerOff size={14} aria-hidden /> : <Power size={14} aria-hidden />}\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => void deleteProvider(p.id)}\n data-testid={`provider-delete-${p.id}`}\n aria-label={`Delete ${p.id}`}\n >\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n </Inline>\n\n {/* Active-key sub-row */}\n <div data-testid={`provider-active-key-${p.id}`} style={{ marginTop: 'var(--space-2)', padding: 'var(--space-2)', background: 'var(--surface-1)', borderRadius: 'var(--radius-sm)' }}>\n <Inline align=\"center\" gap={2}>\n <KeyRound size={12} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n {ak === undefined ? (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>Probing active key…</span>\n ) : ak === null ? (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>No active key</span>\n ) : (\n <Inline align=\"center\" gap={2} data-testid={`provider-active-key-detail-${p.id}`}>\n <code style={{ fontSize: 'var(--fs-12)' }}>{ak.envVar}</code>\n {ak.label && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>· {ak.label}</span>}\n {ak.status && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>· {ak.status}</span>}\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{ak.keyPreview}</code>\n </Inline>\n )}\n </Inline>\n </div>\n\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"primary\" onClick={() => void rotate(p.id)} data-testid={`provider-confirm-rotate-${p.id}`}>\n Confirm rotate\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmRotate(null)}>Cancel</Button>\n </Inline>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </CardBody>\n </Card>\n </Stack>\n );\n}"],"names":["KeyRound","createLucideIcon","Star","ProvidersView","payload","useFetch","activePayload","confirmRotate","setConfirmRotate","useState","activeKeys","setActiveKeys","error","setError","autoDetect","setAutoDetect","probing","setProbing","providers","useMemo","_a","refresh","useCallback","useEffect","cancelled","results","p","r","fetchJson","map","id","ak","rotate","m","err","FetchError","addKey","envVar","label","runAutoDetect","createProvider","name","baseURL","apiKey","editProvider","deleteProvider","toggleEnabled","currentlyEnabled","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCcw","Sparkles","Plus","ListHeader","Card","CardBody","Skeleton","EmptyState","Cpu","isConfirming","cur","RotateCw","Pencil","PowerOff","Power","Trash2"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as d,j as e}from"./cmdk-
|
|
1
|
+
import{r as d,j as e}from"./cmdk-C3F6LD6N.js";import{u as P,a as U,S as r,d as l,h as $,I as m,B as u,i as p,F as f}from"./main-BZMmD6a8.js";import{G as A}from"./Grid-BThCPJaV.js";import{V as B}from"./ViewHeader-BaCWNuVX.js";import{C as b,b as T}from"./Card-BmXiT4c6.js";import{S as D}from"./Switch-C-_zcNdl.js";import{T as L}from"./Textarea-CcQGSgSH.js";import{S as N,a as O}from"./Sheet-CxXf6gvC.js";import{I as x}from"./Input-cAQOvR8U.js";import{P as H}from"./plus-uA5Ecuch.js";import{C as y}from"./clock-E-G5aGua.js";import{P as k}from"./play-fMLPTihK.js";import{R as V}from"./refresh-cw-CR9BzJik.js";import{T as G}from"./trash-2-B885GY46.js";import"./index-B1OIS316.js";const w={interval:"Interval",cron:"Cron",once:"One-time"},M={interval:V,cron:y,once:k};function Y({sched:i}){return i.enabled?i.lastError?e.jsx(u,{tone:"danger",children:"error"}):i.lastRun===null?e.jsx(u,{tone:"info",children:"never run"}):e.jsx(u,{tone:"success",children:"active"}):e.jsx(u,{tone:"neutral",children:"disabled"})}function oe(){const i=P("/api/schedules"),[j,_]=d.useState([]),[a,s]=d.useState(null),[o,c]=d.useState(!1),[S,z]=d.useState(null),[C,h]=d.useState(null);U("schedules:change",d.useCallback(()=>{i.refetch()},[i]));const v=d.useMemo(()=>[...j,...i.data||[]],[j,i.data]),g=()=>{i.refetch()},E=async t=>{h(null);try{await p(`/api/schedules/${encodeURIComponent(t.id)}`,{method:"PATCH",body:{enabled:!t.enabled}}),g()}catch(n){h(n instanceof f?n.message:String(n))}},R=async t=>{h(null),c(!0);try{await p(`/api/schedules/${encodeURIComponent(t.id)}/run`,{method:"POST"}),g()}catch(n){h(n instanceof f?n.message:String(n))}finally{c(!1)}},I=async t=>{h(null),c(!0);try{await p(`/api/schedules/${encodeURIComponent(t)}`,{method:"DELETE"}),g()}catch(n){h(n instanceof f?n.message:String(n))}finally{c(!1)}},F=async()=>{if(!(!a||!a.name.trim()||!a.schedule.trim())){c(!0),z(null);try{const t={type:a.actionType};a.actionType==="agent"&&(t.prompt=a.prompt),a.actionType==="command"&&(t.command=a.prompt),a.id?await p(`/api/schedules/${encodeURIComponent(a.id)}`,{method:"PATCH",body:{name:a.name,type:a.type,schedule:a.schedule,timezone:a.timezone||"UTC",action:t}}):await p("/api/schedules",{method:"POST",body:{name:a.name,type:a.type,schedule:a.schedule,timezone:a.timezone||"UTC",action:t,enabled:!0}}),s(null),g()}catch(t){z(t instanceof f?t.message:String(t))}finally{c(!1)}}};return e.jsxs(r,{gap:5,"data-testid":"schedules-view",children:[e.jsx(B,{title:"Schedules",description:"Recurring and one-time jobs. Toggle enabled, run on demand, or create new.",actions:e.jsxs(l,{variant:"primary",size:"sm",onClick:()=>s({name:"",type:"interval",schedule:"1h",timezone:"UTC",actionType:"agent",prompt:""}),"data-testid":"schedules-new",children:[e.jsx(H,{size:14,"aria-hidden":!0})," New schedule"]})}),C!==null&&e.jsx("div",{role:"alert",style:{padding:"var(--space-2) var(--space-3)",background:"color-mix(in oklch, var(--danger) 12%, var(--surface-0))",border:"1px solid var(--danger)",borderRadius:"var(--radius-md)",fontSize:"var(--fs-12)",color:"var(--danger)"},children:C}),i.loading&&v.length===0?e.jsx($,{style:{height:240}}):v.length===0?e.jsx(b,{children:e.jsx(T,{children:e.jsxs(r,{gap:1,align:"center",children:[e.jsx(y,{size:32,"aria-hidden":!0,style:{color:"var(--fg-muted)"}}),e.jsx("strong",{children:"No schedules yet"}),e.jsx("span",{style:{color:"var(--fg-muted)",fontSize:"var(--fs-13)"},children:"Create one with the button above."})]})})}):e.jsx(r,{gap:3,children:v.map(t=>{const n=M[t.type]??y;return e.jsx(b,{"data-testid":`schedule-${t.id}`,children:e.jsx(T,{children:e.jsxs(A,{cols:4,gap:3,style:{alignItems:"center"},children:[e.jsxs(r,{gap:1,children:[e.jsxs(m,{align:"center",gap:2,children:[e.jsx(n,{size:12,"aria-hidden":!0,style:{color:"var(--fg-muted)"}}),e.jsx("strong",{style:{fontSize:"var(--fs-14)"},children:t.name})]}),e.jsxs(m,{gap:2,children:[e.jsx(u,{tone:"neutral",children:w[t.type]}),e.jsx(Y,{sched:t})]})]}),e.jsxs(r,{gap:1,children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Schedule"}),e.jsx("code",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)"},children:t.schedule}),e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:t.timezone})]}),e.jsxs(r,{gap:1,children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Next run"}),t.nextRun?e.jsx("code",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)"},children:new Date(t.nextRun).toLocaleString()}):e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"—"}),t.lastRun&&e.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:["Last: ",new Date(t.lastRun).toLocaleDateString()]})]}),e.jsxs(m,{align:"center",gap:2,justify:"end",children:[e.jsx(l,{variant:"ghost",size:"sm",onClick:()=>s({id:t.id,name:t.name,type:t.type,schedule:t.schedule,timezone:t.timezone||"UTC",actionType:"agent",prompt:t.action&&t.action.prompt||""}),"data-testid":`schedule-edit-${t.id}`,title:"Edit",children:"Edit"}),e.jsx(l,{variant:"secondary",size:"sm",onClick:()=>{R(t)},disabled:o,"data-testid":`schedule-run-${t.id}`,title:"Run now",children:e.jsx(k,{size:12,"aria-hidden":!0})}),e.jsx(D,{checked:t.enabled,onCheckedChange:()=>{E(t)},"aria-label":`Toggle ${t.name} enabled`}),e.jsx(l,{variant:"danger",size:"sm",onClick:()=>{I(t.id)},disabled:o,"data-testid":`schedule-delete-${t.id}`,title:"Delete",children:e.jsx(G,{size:12,"aria-hidden":!0})})]})]})})},t.id)})}),e.jsx(N,{open:a!==null,onOpenChange:t=>{t||s(null)},children:e.jsx(O,{side:"right",title:a!=null&&a.id?"Edit schedule":"New schedule",children:a!==null&&e.jsxs(r,{gap:4,style:{padding:"var(--space-4)"},children:[e.jsxs(r,{gap:2,children:[e.jsx("label",{htmlFor:"sched-name",style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Name"}),e.jsx(x,{id:"sched-name",value:a.name,onChange:t=>s({...a,name:t.target.value}),placeholder:"Daily digest",disabled:o})]}),e.jsxs(r,{gap:2,children:[e.jsx("label",{htmlFor:"sched-type",style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Type"}),e.jsx(m,{gap:2,children:["interval","cron","once"].map(t=>e.jsx(l,{variant:a.type===t?"primary":"ghost",size:"sm",onClick:()=>s({...a,type:t}),children:w[t]},t))})]}),e.jsxs(r,{gap:2,children:[e.jsx("label",{htmlFor:"sched-expr",style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:a.type==="interval"?"Interval (e.g. 1h, 30m)":a.type==="cron"?"Cron expr":"ISO timestamp"}),e.jsx(x,{id:"sched-expr",value:a.schedule,onChange:t=>s({...a,schedule:t.target.value}),placeholder:a.type==="interval"?"1h":a.type==="cron"?"0 9 * * *":"2026-07-14T09:00:00Z",disabled:o,"data-testid":"sched-expr"})]}),e.jsxs(r,{gap:2,children:[e.jsx("label",{htmlFor:"sched-tz",style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Timezone"}),e.jsx(x,{id:"sched-tz",value:a.timezone,onChange:t=>s({...a,timezone:t.target.value}),placeholder:"UTC",disabled:o})]}),e.jsxs(r,{gap:2,children:[e.jsx("label",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Action type"}),e.jsxs(m,{gap:2,children:[e.jsx(l,{variant:a.actionType==="agent"?"primary":"ghost",size:"sm",onClick:()=>s({...a,actionType:"agent"}),children:"Agent prompt"}),e.jsx(l,{variant:a.actionType==="command"?"primary":"ghost",size:"sm",onClick:()=>s({...a,actionType:"command"}),children:"Shell command"})]})]}),e.jsxs(r,{gap:2,children:[e.jsx("label",{htmlFor:"sched-prompt",style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:a.actionType==="agent"?"Agent prompt":"Command"}),e.jsx(L,{id:"sched-prompt",value:a.prompt,onChange:t=>s({...a,prompt:t.target.value}),placeholder:a.actionType==="agent"?"Run the daily digest report…":'echo "hello from cron"',rows:4,disabled:o})]}),S!==null&&e.jsx("div",{role:"alert",style:{padding:"var(--space-2)",background:"color-mix(in oklch, var(--danger) 12%, var(--surface-0))",border:"1px solid var(--danger)",borderRadius:"var(--radius-sm)",fontSize:"var(--fs-12)",color:"var(--danger)"},children:S}),e.jsxs(m,{gap:2,children:[e.jsx(l,{variant:"primary",onClick:()=>{F()},disabled:o||!a.name.trim()||!a.schedule.trim(),children:a!=null&&a.id?"Save":"Create"}),e.jsx(l,{variant:"ghost",onClick:()=>s(null),disabled:o,children:"Cancel"})]})]})})})]})}export{oe as SchedulesView};
|
package/bizar-dash/dist/assets/{SchedulesView-CtNxtzN6.js.map → SchedulesView-8qxH3bg7.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchedulesView-CtNxtzN6.js","sources":["../../src/web/v8/views/Schedules/SchedulesView.tsx"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react';\nimport { Plus, Play, Power, Trash2, RefreshCw, Clock, type LucideIcon } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { Grid } from '../../ui/primitives/Grid.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Badge } from '../../ui/data/Badge.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Switch } from '../../ui/controls/Switch.js';\nimport { Textarea } from '../../ui/controls/Textarea.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\n\n/**\n * SchedulesView — recurring / one-time job management.\n *\n * Renders `/api/schedules` (list), lets users toggle enabled, run on\n * demand, create new schedules (interval / cron / once), and delete.\n */\n\ntype ScheduleType = 'interval' | 'cron' | 'once';\n\ninterface ScheduleAction {\n type: string;\n prompt?: string;\n agent?: string;\n command?: string;\n [key: string]: unknown;\n}\n\ninterface Schedule {\n id: string;\n name: string;\n type: ScheduleType;\n schedule: string;\n timezone: string;\n enabled: boolean;\n createdAt: string;\n updatedAt: string;\n lastRun: string | null;\n lastResult: unknown;\n lastError: unknown;\n nextRun: string | null;\n action: ScheduleAction;\n budgetCheck?: { maxConcurrent: number; skipIfBudgetLow: boolean };\n}\n\ninterface SchedulesResponse extends Array<Schedule> {}\n\ninterface CreateDraft {\n id?: string;\n name: string;\n type: ScheduleType;\n schedule: string;\n timezone: string;\n actionType: string;\n prompt: string;\n}\n\nconst TYPE_LABEL: Record<ScheduleType, string> = {\n interval: 'Interval',\n cron: 'Cron',\n once: 'One-time',\n};\n\nconst TYPE_ICON: Record<ScheduleType, LucideIcon> = {\n interval: RefreshCw,\n cron: Clock,\n once: Play,\n};\n\nfunction StatusBadge({ sched }: { sched: Schedule }): JSX.Element {\n if (!sched.enabled) return <Badge tone=\"neutral\">disabled</Badge>;\n if (sched.lastError) return <Badge tone=\"danger\">error</Badge>;\n if (sched.lastRun === null) return <Badge tone=\"info\">never run</Badge>;\n return <Badge tone=\"success\">active</Badge>;\n}\n\nfunction Box(props: { children?: React.ReactNode; style?: React.CSSProperties }): JSX.Element {\n return <div style={props.style}>{props.children}</div>;\n}\n\nexport function SchedulesView(): JSX.Element {\n const res = useFetch<SchedulesResponse>('/api/schedules');\n const [live, setLive] = useState<Schedule[]>([]);\n const [draft, setDraft] = useState<CreateDraft | null>(null);\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n\n useWsMessage('schedules:change', useCallback(() => { void res.refetch(); }, [res]));\n\n const schedules = useMemo<Schedule[]>(() => [...live, ...(res.data || [])], [live, res.data]);\n\n const refresh = (): void => { void res.refetch(); };\n\n const toggleEnabled = async (s: Schedule): Promise<void> => {\n setActionError(null);\n try {\n await fetchJson(`/api/schedules/${encodeURIComponent(s.id)}`, {\n method: 'PATCH',\n body: { enabled: !s.enabled },\n });\n refresh();\n } catch (err) {\n setActionError(err instanceof FetchError ? err.message : String(err));\n }\n };\n\n const runNow = async (s: Schedule): Promise<void> => {\n setActionError(null);\n setBusy(true);\n try {\n await fetchJson(`/api/schedules/${encodeURIComponent(s.id)}/run`, { method: 'POST' });\n refresh();\n } catch (err) {\n setActionError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n const deleteSchedule = async (id: string): Promise<void> => {\n setActionError(null);\n setBusy(true);\n try {\n await fetchJson(`/api/schedules/${encodeURIComponent(id)}`, { method: 'DELETE' });\n refresh();\n } catch (err) {\n setActionError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n const createSchedule = async (): Promise<void> => {\n if (!draft || !draft.name.trim() || !draft.schedule.trim()) return;\n setBusy(true);\n setError(null);\n try {\n const action: ScheduleAction = { type: draft.actionType };\n if (draft.actionType === 'agent') action.prompt = draft.prompt;\n if (draft.actionType === 'command') action.command = draft.prompt;\n if (draft.id) {\n // Edit path — PATCH the existing schedule.\n await fetchJson(`/api/schedules/${encodeURIComponent(draft.id)}`, {\n method: 'PATCH',\n body: {\n name: draft.name,\n type: draft.type,\n schedule: draft.schedule,\n timezone: draft.timezone || 'UTC',\n action,\n },\n });\n } else {\n await fetchJson('/api/schedules', {\n method: 'POST',\n body: {\n name: draft.name,\n type: draft.type,\n schedule: draft.schedule,\n timezone: draft.timezone || 'UTC',\n action,\n enabled: true,\n },\n });\n }\n setDraft(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Stack gap={5} data-testid=\"schedules-view\">\n <ViewHeader\n title=\"Schedules\"\n description=\"Recurring and one-time jobs. Toggle enabled, run on demand, or create new.\"\n actions={\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => setDraft({ name: '', type: 'interval', schedule: '1h', timezone: 'UTC', actionType: 'agent', prompt: '' })}\n data-testid=\"schedules-new\"\n >\n <Plus size={14} aria-hidden /> New schedule\n </Button>\n }\n />\n\n {actionError !== null && (\n <div role=\"alert\" style={{ padding: 'var(--space-2) var(--space-3)', background: 'color-mix(in oklch, var(--danger) 12%, var(--surface-0))', border: '1px solid var(--danger)', borderRadius: 'var(--radius-md)', fontSize: 'var(--fs-12)', color: 'var(--danger)' }}>\n {actionError}\n </div>\n )}\n\n {res.loading && schedules.length === 0 ? (\n <Skeleton style={{ height: 240 }} />\n ) : schedules.length === 0 ? (\n <Card>\n <CardBody>\n <Stack gap={1} align=\"center\">\n <Clock size={32} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n <strong>No schedules yet</strong>\n <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-13)' }}>\n Create one with the button above.\n </span>\n </Stack>\n </CardBody>\n </Card>\n ) : (\n <Stack gap={3}>\n {schedules.map((s) => {\n const TypeIcon = TYPE_ICON[s.type] ?? Clock;\n return (\n <Card key={s.id} data-testid={`schedule-${s.id}`}>\n <CardBody>\n <Grid cols={4} gap={3} style={{ alignItems: 'center' }}>\n <Stack gap={1}>\n <Inline align=\"center\" gap={2}>\n <TypeIcon size={12} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n <strong style={{ fontSize: 'var(--fs-14)' }}>{s.name}</strong>\n </Inline>\n <Inline gap={2}>\n <Badge tone=\"neutral\">{TYPE_LABEL[s.type]}</Badge>\n <StatusBadge sched={s} />\n </Inline>\n </Stack>\n\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Schedule</span>\n <code style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)' }}>{s.schedule}</code>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{s.timezone}</span>\n </Stack>\n\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Next run</span>\n {s.nextRun ? (\n <code style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)' }}>\n {new Date(s.nextRun).toLocaleString()}\n </code>\n ) : (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>—</span>\n )}\n {s.lastRun && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Last: {new Date(s.lastRun).toLocaleDateString()}\n </span>\n )}\n </Stack>\n\n <Inline align=\"center\" gap={2} justify=\"end\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setDraft({\n id: s.id,\n name: s.name,\n type: s.type,\n schedule: s.schedule,\n timezone: s.timezone || 'UTC',\n actionType: 'agent',\n prompt: (s.action && (s.action as { prompt?: string }).prompt) || '',\n })}\n data-testid={`schedule-edit-${s.id}`}\n title=\"Edit\"\n >\n Edit\n </Button>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => { void runNow(s); }}\n disabled={busy}\n data-testid={`schedule-run-${s.id}`}\n title=\"Run now\"\n >\n <Play size={12} aria-hidden />\n </Button>\n <Switch\n checked={s.enabled}\n onCheckedChange={() => { void toggleEnabled(s); }}\n aria-label={`Toggle ${s.name} enabled`}\n />\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={() => { void deleteSchedule(s.id); }}\n disabled={busy}\n data-testid={`schedule-delete-${s.id}`}\n title=\"Delete\"\n >\n <Trash2 size={12} aria-hidden />\n </Button>\n </Inline>\n </Grid>\n </CardBody>\n </Card>\n );\n })}\n </Stack>\n )}\n\n <Sheet open={draft !== null} onOpenChange={(o) => { if (!o) setDraft(null); }}>\n <SheetContent side=\"right\" title={draft?.id ? 'Edit schedule' : 'New schedule'}>\n {draft !== null && (\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"sched-name\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Name</label>\n <Input\n id=\"sched-name\"\n value={draft.name}\n onChange={(e) => setDraft({ ...draft, name: e.target.value })}\n placeholder=\"Daily digest\"\n disabled={busy}\n />\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"sched-type\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Type</label>\n <Inline gap={2}>\n {(['interval', 'cron', 'once'] as const).map((t) => (\n <Button\n key={t}\n variant={draft.type === t ? 'primary' : 'ghost'}\n size=\"sm\"\n onClick={() => setDraft({ ...draft, type: t })}\n >\n {TYPE_LABEL[t]}\n </Button>\n ))}\n </Inline>\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"sched-expr\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {draft.type === 'interval' ? 'Interval (e.g. 1h, 30m)' : draft.type === 'cron' ? 'Cron expr' : 'ISO timestamp'}\n </label>\n <Input\n id=\"sched-expr\"\n value={draft.schedule}\n onChange={(e) => setDraft({ ...draft, schedule: e.target.value })}\n placeholder={draft.type === 'interval' ? '1h' : draft.type === 'cron' ? '0 9 * * *' : '2026-07-14T09:00:00Z'}\n disabled={busy}\n data-testid=\"sched-expr\"\n />\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"sched-tz\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Timezone</label>\n <Input\n id=\"sched-tz\"\n value={draft.timezone}\n onChange={(e) => setDraft({ ...draft, timezone: e.target.value })}\n placeholder=\"UTC\"\n disabled={busy}\n />\n </Stack>\n\n <Stack gap={2}>\n <label style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Action type</label>\n <Inline gap={2}>\n <Button\n variant={draft.actionType === 'agent' ? 'primary' : 'ghost'}\n size=\"sm\"\n onClick={() => setDraft({ ...draft, actionType: 'agent' })}\n >\n Agent prompt\n </Button>\n <Button\n variant={draft.actionType === 'command' ? 'primary' : 'ghost'}\n size=\"sm\"\n onClick={() => setDraft({ ...draft, actionType: 'command' })}\n >\n Shell command\n </Button>\n </Inline>\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"sched-prompt\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {draft.actionType === 'agent' ? 'Agent prompt' : 'Command'}\n </label>\n <Textarea\n id=\"sched-prompt\"\n value={draft.prompt}\n onChange={(e) => setDraft({ ...draft, prompt: e.target.value })}\n placeholder={draft.actionType === 'agent' ? 'Run the daily digest report…' : 'echo \"hello from cron\"'}\n rows={4}\n disabled={busy}\n />\n </Stack>\n\n {error !== null && (\n <div role=\"alert\" style={{ padding: 'var(--space-2)', background: 'color-mix(in oklch, var(--danger) 12%, var(--surface-0))', border: '1px solid var(--danger)', borderRadius: 'var(--radius-sm)', fontSize: 'var(--fs-12)', color: 'var(--danger)' }}>\n {error}\n </div>\n )}\n\n <Inline gap={2}>\n <Button\n variant=\"primary\"\n onClick={() => { void createSchedule(); }}\n disabled={busy || !draft.name.trim() || !draft.schedule.trim()}\n >\n {draft?.id ? 'Save' : 'Create'}\n </Button>\n <Button variant=\"ghost\" onClick={() => setDraft(null)} disabled={busy}>\n Cancel\n </Button>\n </Inline>\n </Stack>\n )}\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}\n"],"names":["TYPE_LABEL","TYPE_ICON","RefreshCw","Clock","Play","StatusBadge","sched","Badge","jsx","SchedulesView","res","useFetch","live","setLive","useState","draft","setDraft","busy","setBusy","error","setError","actionError","setActionError","useWsMessage","useCallback","schedules","useMemo","refresh","toggleEnabled","s","fetchJson","err","FetchError","runNow","deleteSchedule","id","createSchedule","action","jsxs","Stack","ViewHeader","Button","Plus","Skeleton","Card","CardBody","TypeIcon","Grid","Inline","Switch","Trash2","Sheet","o","SheetContent","Input","e","Textarea"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SchedulesView-8qxH3bg7.js","sources":["../../src/web/v8/views/Schedules/SchedulesView.tsx"],"sourcesContent":["import { useCallback, useMemo, useState } from 'react';\nimport { Plus, Play, Power, Trash2, RefreshCw, Clock, type LucideIcon } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { Grid } from '../../ui/primitives/Grid.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Badge } from '../../ui/data/Badge.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Switch } from '../../ui/controls/Switch.js';\nimport { Textarea } from '../../ui/controls/Textarea.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\n\n/**\n * SchedulesView — recurring / one-time job management.\n *\n * Renders `/api/schedules` (list), lets users toggle enabled, run on\n * demand, create new schedules (interval / cron / once), and delete.\n */\n\ntype ScheduleType = 'interval' | 'cron' | 'once';\n\ninterface ScheduleAction {\n type: string;\n prompt?: string;\n agent?: string;\n command?: string;\n [key: string]: unknown;\n}\n\ninterface Schedule {\n id: string;\n name: string;\n type: ScheduleType;\n schedule: string;\n timezone: string;\n enabled: boolean;\n createdAt: string;\n updatedAt: string;\n lastRun: string | null;\n lastResult: unknown;\n lastError: unknown;\n nextRun: string | null;\n action: ScheduleAction;\n budgetCheck?: { maxConcurrent: number; skipIfBudgetLow: boolean };\n}\n\ninterface SchedulesResponse extends Array<Schedule> {}\n\ninterface CreateDraft {\n id?: string;\n name: string;\n type: ScheduleType;\n schedule: string;\n timezone: string;\n actionType: string;\n prompt: string;\n}\n\nconst TYPE_LABEL: Record<ScheduleType, string> = {\n interval: 'Interval',\n cron: 'Cron',\n once: 'One-time',\n};\n\nconst TYPE_ICON: Record<ScheduleType, LucideIcon> = {\n interval: RefreshCw,\n cron: Clock,\n once: Play,\n};\n\nfunction StatusBadge({ sched }: { sched: Schedule }): JSX.Element {\n if (!sched.enabled) return <Badge tone=\"neutral\">disabled</Badge>;\n if (sched.lastError) return <Badge tone=\"danger\">error</Badge>;\n if (sched.lastRun === null) return <Badge tone=\"info\">never run</Badge>;\n return <Badge tone=\"success\">active</Badge>;\n}\n\nfunction Box(props: { children?: React.ReactNode; style?: React.CSSProperties }): JSX.Element {\n return <div style={props.style}>{props.children}</div>;\n}\n\nexport function SchedulesView(): JSX.Element {\n const res = useFetch<SchedulesResponse>('/api/schedules');\n const [live, setLive] = useState<Schedule[]>([]);\n const [draft, setDraft] = useState<CreateDraft | null>(null);\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const [actionError, setActionError] = useState<string | null>(null);\n\n useWsMessage('schedules:change', useCallback(() => { void res.refetch(); }, [res]));\n\n const schedules = useMemo<Schedule[]>(() => [...live, ...(res.data || [])], [live, res.data]);\n\n const refresh = (): void => { void res.refetch(); };\n\n const toggleEnabled = async (s: Schedule): Promise<void> => {\n setActionError(null);\n try {\n await fetchJson(`/api/schedules/${encodeURIComponent(s.id)}`, {\n method: 'PATCH',\n body: { enabled: !s.enabled },\n });\n refresh();\n } catch (err) {\n setActionError(err instanceof FetchError ? err.message : String(err));\n }\n };\n\n const runNow = async (s: Schedule): Promise<void> => {\n setActionError(null);\n setBusy(true);\n try {\n await fetchJson(`/api/schedules/${encodeURIComponent(s.id)}/run`, { method: 'POST' });\n refresh();\n } catch (err) {\n setActionError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n const deleteSchedule = async (id: string): Promise<void> => {\n setActionError(null);\n setBusy(true);\n try {\n await fetchJson(`/api/schedules/${encodeURIComponent(id)}`, { method: 'DELETE' });\n refresh();\n } catch (err) {\n setActionError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n const createSchedule = async (): Promise<void> => {\n if (!draft || !draft.name.trim() || !draft.schedule.trim()) return;\n setBusy(true);\n setError(null);\n try {\n const action: ScheduleAction = { type: draft.actionType };\n if (draft.actionType === 'agent') action.prompt = draft.prompt;\n if (draft.actionType === 'command') action.command = draft.prompt;\n if (draft.id) {\n // Edit path — PATCH the existing schedule.\n await fetchJson(`/api/schedules/${encodeURIComponent(draft.id)}`, {\n method: 'PATCH',\n body: {\n name: draft.name,\n type: draft.type,\n schedule: draft.schedule,\n timezone: draft.timezone || 'UTC',\n action,\n },\n });\n } else {\n await fetchJson('/api/schedules', {\n method: 'POST',\n body: {\n name: draft.name,\n type: draft.type,\n schedule: draft.schedule,\n timezone: draft.timezone || 'UTC',\n action,\n enabled: true,\n },\n });\n }\n setDraft(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Stack gap={5} data-testid=\"schedules-view\">\n <ViewHeader\n title=\"Schedules\"\n description=\"Recurring and one-time jobs. Toggle enabled, run on demand, or create new.\"\n actions={\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => setDraft({ name: '', type: 'interval', schedule: '1h', timezone: 'UTC', actionType: 'agent', prompt: '' })}\n data-testid=\"schedules-new\"\n >\n <Plus size={14} aria-hidden /> New schedule\n </Button>\n }\n />\n\n {actionError !== null && (\n <div role=\"alert\" style={{ padding: 'var(--space-2) var(--space-3)', background: 'color-mix(in oklch, var(--danger) 12%, var(--surface-0))', border: '1px solid var(--danger)', borderRadius: 'var(--radius-md)', fontSize: 'var(--fs-12)', color: 'var(--danger)' }}>\n {actionError}\n </div>\n )}\n\n {res.loading && schedules.length === 0 ? (\n <Skeleton style={{ height: 240 }} />\n ) : schedules.length === 0 ? (\n <Card>\n <CardBody>\n <Stack gap={1} align=\"center\">\n <Clock size={32} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n <strong>No schedules yet</strong>\n <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-13)' }}>\n Create one with the button above.\n </span>\n </Stack>\n </CardBody>\n </Card>\n ) : (\n <Stack gap={3}>\n {schedules.map((s) => {\n const TypeIcon = TYPE_ICON[s.type] ?? Clock;\n return (\n <Card key={s.id} data-testid={`schedule-${s.id}`}>\n <CardBody>\n <Grid cols={4} gap={3} style={{ alignItems: 'center' }}>\n <Stack gap={1}>\n <Inline align=\"center\" gap={2}>\n <TypeIcon size={12} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n <strong style={{ fontSize: 'var(--fs-14)' }}>{s.name}</strong>\n </Inline>\n <Inline gap={2}>\n <Badge tone=\"neutral\">{TYPE_LABEL[s.type]}</Badge>\n <StatusBadge sched={s} />\n </Inline>\n </Stack>\n\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Schedule</span>\n <code style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)' }}>{s.schedule}</code>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{s.timezone}</span>\n </Stack>\n\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Next run</span>\n {s.nextRun ? (\n <code style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)' }}>\n {new Date(s.nextRun).toLocaleString()}\n </code>\n ) : (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>—</span>\n )}\n {s.lastRun && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Last: {new Date(s.lastRun).toLocaleDateString()}\n </span>\n )}\n </Stack>\n\n <Inline align=\"center\" gap={2} justify=\"end\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setDraft({\n id: s.id,\n name: s.name,\n type: s.type,\n schedule: s.schedule,\n timezone: s.timezone || 'UTC',\n actionType: 'agent',\n prompt: (s.action && (s.action as { prompt?: string }).prompt) || '',\n })}\n data-testid={`schedule-edit-${s.id}`}\n title=\"Edit\"\n >\n Edit\n </Button>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => { void runNow(s); }}\n disabled={busy}\n data-testid={`schedule-run-${s.id}`}\n title=\"Run now\"\n >\n <Play size={12} aria-hidden />\n </Button>\n <Switch\n checked={s.enabled}\n onCheckedChange={() => { void toggleEnabled(s); }}\n aria-label={`Toggle ${s.name} enabled`}\n />\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={() => { void deleteSchedule(s.id); }}\n disabled={busy}\n data-testid={`schedule-delete-${s.id}`}\n title=\"Delete\"\n >\n <Trash2 size={12} aria-hidden />\n </Button>\n </Inline>\n </Grid>\n </CardBody>\n </Card>\n );\n })}\n </Stack>\n )}\n\n <Sheet open={draft !== null} onOpenChange={(o) => { if (!o) setDraft(null); }}>\n <SheetContent side=\"right\" title={draft?.id ? 'Edit schedule' : 'New schedule'}>\n {draft !== null && (\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"sched-name\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Name</label>\n <Input\n id=\"sched-name\"\n value={draft.name}\n onChange={(e) => setDraft({ ...draft, name: e.target.value })}\n placeholder=\"Daily digest\"\n disabled={busy}\n />\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"sched-type\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Type</label>\n <Inline gap={2}>\n {(['interval', 'cron', 'once'] as const).map((t) => (\n <Button\n key={t}\n variant={draft.type === t ? 'primary' : 'ghost'}\n size=\"sm\"\n onClick={() => setDraft({ ...draft, type: t })}\n >\n {TYPE_LABEL[t]}\n </Button>\n ))}\n </Inline>\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"sched-expr\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {draft.type === 'interval' ? 'Interval (e.g. 1h, 30m)' : draft.type === 'cron' ? 'Cron expr' : 'ISO timestamp'}\n </label>\n <Input\n id=\"sched-expr\"\n value={draft.schedule}\n onChange={(e) => setDraft({ ...draft, schedule: e.target.value })}\n placeholder={draft.type === 'interval' ? '1h' : draft.type === 'cron' ? '0 9 * * *' : '2026-07-14T09:00:00Z'}\n disabled={busy}\n data-testid=\"sched-expr\"\n />\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"sched-tz\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Timezone</label>\n <Input\n id=\"sched-tz\"\n value={draft.timezone}\n onChange={(e) => setDraft({ ...draft, timezone: e.target.value })}\n placeholder=\"UTC\"\n disabled={busy}\n />\n </Stack>\n\n <Stack gap={2}>\n <label style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Action type</label>\n <Inline gap={2}>\n <Button\n variant={draft.actionType === 'agent' ? 'primary' : 'ghost'}\n size=\"sm\"\n onClick={() => setDraft({ ...draft, actionType: 'agent' })}\n >\n Agent prompt\n </Button>\n <Button\n variant={draft.actionType === 'command' ? 'primary' : 'ghost'}\n size=\"sm\"\n onClick={() => setDraft({ ...draft, actionType: 'command' })}\n >\n Shell command\n </Button>\n </Inline>\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"sched-prompt\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {draft.actionType === 'agent' ? 'Agent prompt' : 'Command'}\n </label>\n <Textarea\n id=\"sched-prompt\"\n value={draft.prompt}\n onChange={(e) => setDraft({ ...draft, prompt: e.target.value })}\n placeholder={draft.actionType === 'agent' ? 'Run the daily digest report…' : 'echo \"hello from cron\"'}\n rows={4}\n disabled={busy}\n />\n </Stack>\n\n {error !== null && (\n <div role=\"alert\" style={{ padding: 'var(--space-2)', background: 'color-mix(in oklch, var(--danger) 12%, var(--surface-0))', border: '1px solid var(--danger)', borderRadius: 'var(--radius-sm)', fontSize: 'var(--fs-12)', color: 'var(--danger)' }}>\n {error}\n </div>\n )}\n\n <Inline gap={2}>\n <Button\n variant=\"primary\"\n onClick={() => { void createSchedule(); }}\n disabled={busy || !draft.name.trim() || !draft.schedule.trim()}\n >\n {draft?.id ? 'Save' : 'Create'}\n </Button>\n <Button variant=\"ghost\" onClick={() => setDraft(null)} disabled={busy}>\n Cancel\n </Button>\n </Inline>\n </Stack>\n )}\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}\n"],"names":["TYPE_LABEL","TYPE_ICON","RefreshCw","Clock","Play","StatusBadge","sched","Badge","jsx","SchedulesView","res","useFetch","live","setLive","useState","draft","setDraft","busy","setBusy","error","setError","actionError","setActionError","useWsMessage","useCallback","schedules","useMemo","refresh","toggleEnabled","s","fetchJson","err","FetchError","runNow","deleteSchedule","id","createSchedule","action","jsxs","Stack","ViewHeader","Button","Plus","Skeleton","Card","CardBody","TypeIcon","Grid","Inline","Switch","Trash2","Sheet","o","SheetContent","Input","e","Textarea"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as t,j as r,P as N,b as B,i as E,u as Y,f as it,e as dt,d as Ce,n as Ie,a as Ee,m as be,h as ut,l as pt,g as ft,F as ht,D as mt,c as vt,k as gt}from"./cmdk-
|
|
1
|
+
import{r as t,j as r,P as N,b as B,i as E,u as Y,f as it,e as dt,d as Ce,n as Ie,a as Ee,m as be,h as ut,l as pt,g as ft,F as ht,D as mt,c as vt,k as gt}from"./cmdk-C3F6LD6N.js";import{u as St,c as xt,a as _e}from"./index-CR0TeJmc.js";import{c as wt,n as yt,R as Ct,p as Ne,q as It,o as Tt,C as je,g as Te,l as Pt}from"./main-BZMmD6a8.js";import{u as Rt}from"./index-B1OIS316.js";/**
|
|
2
2
|
* @license lucide-react v0.460.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|