@polderlabs/bizar 10.4.4 → 10.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bizar-dash/dist/assets/{ActivityFeed-RQeyFifx.js → ActivityFeed-Bw4Cai7r.js} +1 -1
- package/bizar-dash/dist/assets/{ActivityFeed-RQeyFifx.js.map → ActivityFeed-Bw4Cai7r.js.map} +1 -1
- package/bizar-dash/dist/assets/{ActivityView-CibyssPM.js → ActivityView-BC0QQ_j9.js} +1 -1
- package/bizar-dash/dist/assets/{ActivityView-CibyssPM.js.map → ActivityView-BC0QQ_j9.js.map} +1 -1
- package/bizar-dash/dist/assets/{AdminView-BjczABeB.js → AdminView-CLTNKFL4.js} +1 -1
- package/bizar-dash/dist/assets/{AdminView-BjczABeB.js.map → AdminView-CLTNKFL4.js.map} +1 -1
- package/bizar-dash/dist/assets/{AgentActivity-Bywt1twv.js → AgentActivity-DBWDByjk.js} +1 -1
- package/bizar-dash/dist/assets/{AgentActivity-Bywt1twv.js.map → AgentActivity-DBWDByjk.js.map} +1 -1
- package/bizar-dash/dist/assets/{AgentsView-BnOjjM74.js → AgentsView-DD6bCIbA.js} +1 -1
- package/bizar-dash/dist/assets/{AgentsView-BnOjjM74.js.map → AgentsView-DD6bCIbA.js.map} +1 -1
- package/bizar-dash/dist/assets/{Alert-BZGk39mB.js → Alert-pzFISNtS.js} +1 -1
- package/bizar-dash/dist/assets/{Alert-BZGk39mB.js.map → Alert-pzFISNtS.js.map} +1 -1
- package/bizar-dash/dist/assets/ArtifactsView-BVU5lfo7.js +21 -0
- package/bizar-dash/dist/assets/ArtifactsView-BVU5lfo7.js.map +1 -0
- package/bizar-dash/dist/assets/{AuthView-D4frSShw.js → AuthView-BZ-bPIOM.js} +2 -2
- package/bizar-dash/dist/assets/AuthView-BZ-bPIOM.js.map +1 -0
- package/bizar-dash/dist/assets/{Avatar-BYg0rkPA.js → Avatar-CRW81ewE.js} +1 -1
- package/bizar-dash/dist/assets/{Avatar-BYg0rkPA.js.map → Avatar-CRW81ewE.js.map} +1 -1
- package/bizar-dash/dist/assets/BackgroundJobsView-w8OZtXyI.js +1 -0
- package/bizar-dash/dist/assets/BackgroundJobsView-w8OZtXyI.js.map +1 -0
- package/bizar-dash/dist/assets/{BackupView-B875KQa4.js → BackupView-u_O3j0TG.js} +1 -1
- package/bizar-dash/dist/assets/{BackupView-B875KQa4.js.map → BackupView-u_O3j0TG.js.map} +1 -1
- package/bizar-dash/dist/assets/{Banner-C8HEcT5l.js → Banner-Du-3l05O.js} +1 -1
- package/bizar-dash/dist/assets/{Banner-C8HEcT5l.js.map → Banner-Du-3l05O.js.map} +1 -1
- package/bizar-dash/dist/assets/{Card-BtsmkhJa.js → Card-Clkvh43Q.js} +1 -1
- package/bizar-dash/dist/assets/{Card-BtsmkhJa.js.map → Card-Clkvh43Q.js.map} +1 -1
- package/bizar-dash/dist/assets/{ChatView-CkNS0SD8.js → ChatView-BTjb3mIh.js} +1 -1
- package/bizar-dash/dist/assets/{ChatView-CkNS0SD8.js.map → ChatView-BTjb3mIh.js.map} +1 -1
- package/bizar-dash/dist/assets/{Chip-XPOk0d_E.js → Chip-B7ovcm01.js} +1 -1
- package/bizar-dash/dist/assets/{Chip-XPOk0d_E.js.map → Chip-B7ovcm01.js.map} +1 -1
- package/bizar-dash/dist/assets/ClaudeSessionsView-BoZS5ldi.js +1 -0
- package/bizar-dash/dist/assets/ClaudeSessionsView-BoZS5ldi.js.map +1 -0
- package/bizar-dash/dist/assets/ClipboardView-Cb6XgYZI.js +1 -0
- package/bizar-dash/dist/assets/{ClipboardView-CPlTU5VG.js.map → ClipboardView-Cb6XgYZI.js.map} +1 -1
- package/bizar-dash/dist/assets/{ConfigView-BntUrW7s.js → ConfigView-DfTJk1uL.js} +1 -1
- package/bizar-dash/dist/assets/{ConfigView-BntUrW7s.js.map → ConfigView-DfTJk1uL.js.map} +1 -1
- package/bizar-dash/dist/assets/{DiagnosticsView-4x0Zu3yP.js → DiagnosticsView-D5Wy9xlJ.js} +1 -1
- package/bizar-dash/dist/assets/{DiagnosticsView-4x0Zu3yP.js.map → DiagnosticsView-D5Wy9xlJ.js.map} +1 -1
- package/bizar-dash/dist/assets/{DialogsView-Xd02dVAX.js → DialogsView-HVyfrXpq.js} +1 -1
- package/bizar-dash/dist/assets/{DialogsView-Xd02dVAX.js.map → DialogsView-HVyfrXpq.js.map} +1 -1
- package/bizar-dash/dist/assets/{DoctorView-DepBdQGR.js → DoctorView-Dm94WI2z.js} +2 -2
- package/bizar-dash/dist/assets/{DoctorView-DepBdQGR.js.map → DoctorView-Dm94WI2z.js.map} +1 -1
- package/bizar-dash/dist/assets/{EmptyState-DjKtY1Qi.js → EmptyState-ccT__JZG.js} +1 -1
- package/bizar-dash/dist/assets/{EmptyState-DjKtY1Qi.js.map → EmptyState-ccT__JZG.js.map} +1 -1
- package/bizar-dash/dist/assets/{EnvVarsView-S4Pbm128.js → EnvVarsView-BhcIuJ6V.js} +2 -2
- package/bizar-dash/dist/assets/{EnvVarsView-S4Pbm128.js.map → EnvVarsView-BhcIuJ6V.js.map} +1 -1
- package/bizar-dash/dist/assets/{ErrorState-CBJbEQ8B.js → ErrorState-BSqf65ka.js} +1 -1
- package/bizar-dash/dist/assets/{ErrorState-CBJbEQ8B.js.map → ErrorState-BSqf65ka.js.map} +1 -1
- package/bizar-dash/dist/assets/{EvalView-BeAyMCD1.js → EvalView-2cbWVBUA.js} +1 -1
- package/bizar-dash/dist/assets/{EvalView-BeAyMCD1.js.map → EvalView-2cbWVBUA.js.map} +1 -1
- package/bizar-dash/dist/assets/{GoalsView-BZr8In4c.js → GoalsView-C3QG5p7T.js} +1 -1
- package/bizar-dash/dist/assets/{GoalsView-BZr8In4c.js.map → GoalsView-C3QG5p7T.js.map} +1 -1
- package/bizar-dash/dist/assets/{Grid--WKvqu5h.js → Grid-Bojq8Sg7.js} +1 -1
- package/bizar-dash/dist/assets/{Grid--WKvqu5h.js.map → Grid-Bojq8Sg7.js.map} +1 -1
- package/bizar-dash/dist/assets/{HistoryView-djEbzqtk.js → HistoryView-Bum2TMMw.js} +1 -1
- package/bizar-dash/dist/assets/{HistoryView-djEbzqtk.js.map → HistoryView-Bum2TMMw.js.map} +1 -1
- package/bizar-dash/dist/assets/{Input-h_nSOtwm.js → Input-DV-vdaV8.js} +1 -1
- package/bizar-dash/dist/assets/{Input-h_nSOtwm.js.map → Input-DV-vdaV8.js.map} +1 -1
- package/bizar-dash/dist/assets/{LibrariesView-Vez8CvNq.js → LibrariesView-DH2E2uNb.js} +1 -1
- package/bizar-dash/dist/assets/{LibrariesView-Vez8CvNq.js.map → LibrariesView-DH2E2uNb.js.map} +1 -1
- package/bizar-dash/dist/assets/LightRAGView-BFCcj7Tl.js +6 -0
- package/bizar-dash/dist/assets/LightRAGView-BFCcj7Tl.js.map +1 -0
- package/bizar-dash/dist/assets/{ListHeader-CM8QoIWG.js → ListHeader-CCD_nIHb.js} +1 -1
- package/bizar-dash/dist/assets/{ListHeader-CM8QoIWG.js.map → ListHeader-CCD_nIHb.js.map} +1 -1
- package/bizar-dash/dist/assets/{MemoryView-DnL8E2vI.js → MemoryView-Cr-obIQY.js} +1 -1
- package/bizar-dash/dist/assets/{MemoryView-DnL8E2vI.js.map → MemoryView-Cr-obIQY.js.map} +1 -1
- package/bizar-dash/dist/assets/{MiscView-B2YQXhZ_.js → MiscView-CDUQpYuV.js} +1 -1
- package/bizar-dash/dist/assets/{MiscView-B2YQXhZ_.js.map → MiscView-CDUQpYuV.js.map} +1 -1
- package/bizar-dash/dist/assets/{ModsView-BVM3X5xc.js → ModsView-B6OR-a4B.js} +2 -2
- package/bizar-dash/dist/assets/{ModsView-BVM3X5xc.js.map → ModsView-B6OR-a4B.js.map} +1 -1
- package/bizar-dash/dist/assets/{NotificationsView-A-Xs8BL1.js → NotificationsView-CIqtY6D0.js} +1 -1
- package/bizar-dash/dist/assets/{NotificationsView-A-Xs8BL1.js.map → NotificationsView-CIqtY6D0.js.map} +1 -1
- package/bizar-dash/dist/assets/{ObsidianView-mI3qW9OP.js → ObsidianView-Nahah8QC.js} +1 -1
- package/bizar-dash/dist/assets/{ObsidianView-mI3qW9OP.js.map → ObsidianView-Nahah8QC.js.map} +1 -1
- package/bizar-dash/dist/assets/{OverviewView-By69Cr5H.js → OverviewView-B6L_wa4M.js} +1 -1
- package/bizar-dash/dist/assets/{OverviewView-By69Cr5H.js.map → OverviewView-B6L_wa4M.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProgressBar-BnaBqv-W.js → ProgressBar-KC4VXsl_.js} +1 -1
- package/bizar-dash/dist/assets/{ProgressBar-BnaBqv-W.js.map → ProgressBar-KC4VXsl_.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProjectsView-C81WTFka.js → ProjectsView-DgxWiqHb.js} +1 -1
- package/bizar-dash/dist/assets/{ProjectsView-C81WTFka.js.map → ProjectsView-DgxWiqHb.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProvidersView-2cn-TALE.js → ProvidersView-BOqN9omv.js} +1 -1
- package/bizar-dash/dist/assets/{ProvidersView-2cn-TALE.js.map → ProvidersView-BOqN9omv.js.map} +1 -1
- package/bizar-dash/dist/assets/SchedulesView-yMaG3Dtd.js +1 -0
- package/bizar-dash/dist/assets/SchedulesView-yMaG3Dtd.js.map +1 -0
- package/bizar-dash/dist/assets/{Select-CiGWEN8I.js → Select-Bf_P0S6H.js} +1 -1
- package/bizar-dash/dist/assets/{Select-CiGWEN8I.js.map → Select-Bf_P0S6H.js.map} +1 -1
- package/bizar-dash/dist/assets/{SettingsRow-CflGJymA.js → SettingsRow-CJb-F94Y.js} +1 -1
- package/bizar-dash/dist/assets/{SettingsRow-CflGJymA.js.map → SettingsRow-CJb-F94Y.js.map} +1 -1
- package/bizar-dash/dist/assets/{SettingsView-2HSFJPPK.js → SettingsView-BvOGcgMS.js} +2 -2
- package/bizar-dash/dist/assets/SettingsView-BvOGcgMS.js.map +1 -0
- package/bizar-dash/dist/assets/{Sheet-B-CMP9-_.js → Sheet-BwMVGN-8.js} +1 -1
- package/bizar-dash/dist/assets/{Sheet-B-CMP9-_.js.map → Sheet-BwMVGN-8.js.map} +1 -1
- package/bizar-dash/dist/assets/{Slider-Z4TP_CXY.js → Slider-AjjzqI-5.js} +1 -1
- package/bizar-dash/dist/assets/{Slider-Z4TP_CXY.js.map → Slider-AjjzqI-5.js.map} +1 -1
- package/bizar-dash/dist/assets/{Sparkline-cvkv2HbU.js → Sparkline-Z4y0YUZS.js} +1 -1
- package/bizar-dash/dist/assets/{Sparkline-cvkv2HbU.js.map → Sparkline-Z4y0YUZS.js.map} +1 -1
- package/bizar-dash/dist/assets/{Switch-jcYo4lmp.js → Switch-B79a2t-G.js} +1 -1
- package/bizar-dash/dist/assets/{Switch-jcYo4lmp.js.map → Switch-B79a2t-G.js.map} +1 -1
- package/bizar-dash/dist/assets/{TasksView-CQaSFzWY.js → TasksView-G-s_pwwr.js} +1 -1
- package/bizar-dash/dist/assets/{TasksView-CQaSFzWY.js.map → TasksView-G-s_pwwr.js.map} +1 -1
- package/bizar-dash/dist/assets/{Textarea-xnAybFGd.js → Textarea-BfXGMXQ7.js} +1 -1
- package/bizar-dash/dist/assets/{Textarea-xnAybFGd.js.map → Textarea-BfXGMXQ7.js.map} +1 -1
- package/bizar-dash/dist/assets/{UpdateView-BUAEcRCX.js → UpdateView-BKx3u9X8.js} +1 -1
- package/bizar-dash/dist/assets/{UpdateView-BUAEcRCX.js.map → UpdateView-BKx3u9X8.js.map} +1 -1
- package/bizar-dash/dist/assets/{UsageView-DMFbBOfH.js → UsageView-M01G6bZQ.js} +1 -1
- package/bizar-dash/dist/assets/{UsageView-DMFbBOfH.js.map → UsageView-M01G6bZQ.js.map} +1 -1
- package/bizar-dash/dist/assets/{ViewHeader-C-t1U2cQ.js → ViewHeader-BsnaspKw.js} +1 -1
- package/bizar-dash/dist/assets/{ViewHeader-C-t1U2cQ.js.map → ViewHeader-BsnaspKw.js.map} +1 -1
- package/bizar-dash/dist/assets/VoiceView-rWE8vziD.js +1 -0
- package/bizar-dash/dist/assets/{VoiceView-aoPVT6LJ.js.map → VoiceView-rWE8vziD.js.map} +1 -1
- package/bizar-dash/dist/assets/{brain-DhAzcHUk.js → brain-D7k5s8vH.js} +1 -1
- package/bizar-dash/dist/assets/{brain-DhAzcHUk.js.map → brain-D7k5s8vH.js.map} +1 -1
- package/bizar-dash/dist/assets/{calendar-B9Wbemh7.js → calendar-CAZoDd-l.js} +1 -1
- package/bizar-dash/dist/assets/{calendar-B9Wbemh7.js.map → calendar-CAZoDd-l.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-6NJF_Xl6.js → circle-D99cZJBr.js} +1 -1
- package/bizar-dash/dist/assets/{circle-6NJF_Xl6.js.map → circle-D99cZJBr.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-alert-Dz8lGfCZ.js → circle-alert-QQTU4Quz.js} +1 -1
- package/bizar-dash/dist/assets/{circle-alert-Dz8lGfCZ.js.map → circle-alert-QQTU4Quz.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-check-DFB50ojt.js → circle-check-BMbe7Kkr.js} +1 -1
- package/bizar-dash/dist/assets/{circle-check-DFB50ojt.js.map → circle-check-BMbe7Kkr.js.map} +1 -1
- package/bizar-dash/dist/assets/{clock-ClVA6-hQ.js → clock-OtT5mvF3.js} +1 -1
- package/bizar-dash/dist/assets/{clock-ClVA6-hQ.js.map → clock-OtT5mvF3.js.map} +1 -1
- package/bizar-dash/dist/assets/{download-BvJddD8D.js → download-B-mPX5P_.js} +1 -1
- package/bizar-dash/dist/assets/{download-BvJddD8D.js.map → download-B-mPX5P_.js.map} +1 -1
- package/bizar-dash/dist/assets/{external-link-DvL89gaZ.js → external-link-DPDQM1YO.js} +1 -1
- package/bizar-dash/dist/assets/{external-link-DvL89gaZ.js.map → external-link-DPDQM1YO.js.map} +1 -1
- package/bizar-dash/dist/assets/{file-text-BOroDtZE.js → file-text-BsCrv5aP.js} +1 -1
- package/bizar-dash/dist/assets/{file-text-BOroDtZE.js.map → file-text-BsCrv5aP.js.map} +1 -1
- package/bizar-dash/dist/assets/{filter-DwPjMRQt.js → filter-Do63x17E.js} +1 -1
- package/bizar-dash/dist/assets/{filter-DwPjMRQt.js.map → filter-Do63x17E.js.map} +1 -1
- package/bizar-dash/dist/assets/{git-pull-request-TDb1inux.js → git-pull-request-CpRAmERC.js} +1 -1
- package/bizar-dash/dist/assets/{git-pull-request-TDb1inux.js.map → git-pull-request-CpRAmERC.js.map} +1 -1
- package/bizar-dash/dist/assets/main-BRmJZcHt.js +277 -0
- package/bizar-dash/dist/assets/main-BRmJZcHt.js.map +1 -0
- package/bizar-dash/dist/assets/main-D0TY0myE.css +1 -0
- package/bizar-dash/dist/assets/{network-BcCoCzIY.js → network-DJnHwHX3.js} +1 -1
- package/bizar-dash/dist/assets/{network-BcCoCzIY.js.map → network-DJnHwHX3.js.map} +1 -1
- package/bizar-dash/dist/assets/{pause-BllItT2_.js → pause-HitDUnk_.js} +1 -1
- package/bizar-dash/dist/assets/{pause-BllItT2_.js.map → pause-HitDUnk_.js.map} +1 -1
- package/bizar-dash/dist/assets/{pencil-DAwM-CC3.js → pencil-Dkks7eIC.js} +1 -1
- package/bizar-dash/dist/assets/{pencil-DAwM-CC3.js.map → pencil-Dkks7eIC.js.map} +1 -1
- package/bizar-dash/dist/assets/{play-mJh67AXo.js → play-blqh0msT.js} +1 -1
- package/bizar-dash/dist/assets/{play-mJh67AXo.js.map → play-blqh0msT.js.map} +1 -1
- package/bizar-dash/dist/assets/{plug-BjfntCMC.js → plug-DVvSSe40.js} +1 -1
- package/bizar-dash/dist/assets/{plug-BjfntCMC.js.map → plug-DVvSSe40.js.map} +1 -1
- package/bizar-dash/dist/assets/{plus-Cm6-fo14.js → plus-Cps-8lcG.js} +1 -1
- package/bizar-dash/dist/assets/{plus-Cm6-fo14.js.map → plus-Cps-8lcG.js.map} +1 -1
- package/bizar-dash/dist/assets/{power-CXN9y2KV.js → power-DEX4_Xoa.js} +1 -1
- package/bizar-dash/dist/assets/{power-CXN9y2KV.js.map → power-DEX4_Xoa.js.map} +1 -1
- package/bizar-dash/dist/assets/{power-off-DUZqwMf9.js → power-off-upZ4xjaG.js} +1 -1
- package/bizar-dash/dist/assets/{power-off-DUZqwMf9.js.map → power-off-upZ4xjaG.js.map} +1 -1
- package/bizar-dash/dist/assets/{refresh-ccw-DA8_IB9l.js → refresh-ccw-DN_zCB1h.js} +1 -1
- package/bizar-dash/dist/assets/{refresh-ccw-DA8_IB9l.js.map → refresh-ccw-DN_zCB1h.js.map} +1 -1
- package/bizar-dash/dist/assets/{refresh-cw-DwlP59en.js → refresh-cw-KGm5eQgv.js} +1 -1
- package/bizar-dash/dist/assets/{refresh-cw-DwlP59en.js.map → refresh-cw-KGm5eQgv.js.map} +1 -1
- package/bizar-dash/dist/assets/{rotate-ccw-DMTASfAn.js → rotate-ccw-D5fkDRgk.js} +1 -1
- package/bizar-dash/dist/assets/{rotate-ccw-DMTASfAn.js.map → rotate-ccw-D5fkDRgk.js.map} +1 -1
- package/bizar-dash/dist/assets/{rotate-cw-BDX5SE2s.js → rotate-cw-CClSVUaX.js} +1 -1
- package/bizar-dash/dist/assets/{rotate-cw-BDX5SE2s.js.map → rotate-cw-CClSVUaX.js.map} +1 -1
- package/bizar-dash/dist/assets/{save-Y0jPK5D6.js → save-BY4ViPku.js} +1 -1
- package/bizar-dash/dist/assets/{save-Y0jPK5D6.js.map → save-BY4ViPku.js.map} +1 -1
- package/bizar-dash/dist/assets/{send-C8wwPHhR.js → send-CaOL1yQD.js} +1 -1
- package/bizar-dash/dist/assets/{send-C8wwPHhR.js.map → send-CaOL1yQD.js.map} +1 -1
- package/bizar-dash/dist/assets/{shield-alert-DEvq9UG0.js → shield-alert-DA9K6uZO.js} +1 -1
- package/bizar-dash/dist/assets/{shield-alert-DEvq9UG0.js.map → shield-alert-DA9K6uZO.js.map} +1 -1
- package/bizar-dash/dist/assets/{trash-2-D6qePV_q.js → trash-2-B_Y6HrfN.js} +1 -1
- package/bizar-dash/dist/assets/{trash-2-D6qePV_q.js.map → trash-2-B_Y6HrfN.js.map} +1 -1
- package/bizar-dash/dist/assets/{trending-up-BZzo_1ic.js → trending-up-qKTUQKIT.js} +1 -1
- package/bizar-dash/dist/assets/{trending-up-BZzo_1ic.js.map → trending-up-qKTUQKIT.js.map} +1 -1
- package/bizar-dash/dist/assets/{triangle-alert-B2oHbmoh.js → triangle-alert-BeY8LAv6.js} +1 -1
- package/bizar-dash/dist/assets/{triangle-alert-B2oHbmoh.js.map → triangle-alert-BeY8LAv6.js.map} +1 -1
- package/bizar-dash/dist/assets/{upload-Dy59aZn6.js → upload-BZCtmqIh.js} +1 -1
- package/bizar-dash/dist/assets/{upload-Dy59aZn6.js.map → upload-BZCtmqIh.js.map} +1 -1
- package/bizar-dash/dist/assets/{zap-DENVhJnO.js → zap-Bz1Z8y1Q.js} +1 -1
- package/bizar-dash/dist/assets/{zap-DENVhJnO.js.map → zap-Bz1Z8y1Q.js.map} +1 -1
- package/bizar-dash/dist/index.html +2 -2
- package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/bizar-dash/src/web/v8/shell/Sidebar.tsx +41 -31
- package/bizar-dash/src/web/v8/shell/Topbar.tsx +63 -23
- package/bizar-dash/src/web/v8/ui/feedback/NotificationsPopover.tsx +3 -0
- package/bizar-dash/src/web/v8/ui/feedback/useFocusTrap.ts +58 -0
- package/bizar-dash/src/web/v8/ui/navigation/CommandPalette.tsx +1 -0
- package/bizar-dash/src/web/v8/ui/styles/tokens.css +21 -0
- package/bizar-dash/src/web/v8/views/Artifacts/ClaudeArtifactView.tsx +1 -1
- package/bizar-dash/src/web/v8/views/Auth/AuthView.tsx +10 -6
- package/bizar-dash/src/web/v8/views/BackgroundJobs/BackgroundJobsView.tsx +38 -13
- package/bizar-dash/src/web/v8/views/ClaudeSessions/ClaudeSessionDetail.tsx +16 -5
- package/bizar-dash/src/web/v8/views/LightRAG/LightRAGView.tsx +23 -2
- package/bizar-dash/src/web/v8/views/Schedules/SchedulesView.tsx +48 -13
- package/bizar-dash/src/web/v8/views/Settings/SettingsView.tsx +3 -3
- package/bizar-dash/tests/auth-inputs-labels.test.mjs +45 -0
- package/bizar-dash/tests/background-jobs-action-labels.test.mjs +41 -0
- package/bizar-dash/tests/background-jobs-states.test.mjs +80 -0
- package/bizar-dash/tests/banner-tones.test.mjs +50 -0
- package/bizar-dash/tests/callout-tokens.test.mjs +30 -0
- package/bizar-dash/tests/claude-session-detail-states.test.mjs +67 -0
- package/bizar-dash/tests/components/BackgroundJobsSkeleton.test.tsx +38 -0
- package/bizar-dash/tests/density-tokens.test.mjs +46 -0
- package/bizar-dash/tests/doctor-route-shape.test.mjs +67 -0
- package/bizar-dash/tests/errorstate-retry.test.mjs +42 -0
- package/bizar-dash/tests/lightrag-skeleton.test.mjs +31 -0
- package/bizar-dash/tests/lightrag-states.test.mjs +60 -0
- package/bizar-dash/tests/modal-focus-trap.test.mjs +114 -0
- package/bizar-dash/tests/orphan-tests-audit.test.mjs +80 -0
- package/bizar-dash/tests/palette-keyboard-nav.test.mjs +123 -0
- package/bizar-dash/tests/schedules-skeleton.test.mjs +25 -0
- package/bizar-dash/tests/schedules-states.test.mjs +67 -0
- package/bizar-dash/tests/sidebar-collapse-animation.test.mjs +37 -0
- package/bizar-dash/tests/sidebar-section-styles.test.mjs +55 -0
- package/bizar-dash/tests/skeleton-height.test.mjs +47 -0
- package/bizar-dash/tests/space-tokens.test.mjs +36 -0
- package/bizar-dash/tests/stattile-loading.test.mjs +28 -0
- package/bizar-dash/tests/topbar-popover-styles.test.mjs +53 -0
- package/bizar-dash/tests/update-channels.test.mjs +67 -0
- package/package.json +1 -1
- package/packages/sdk/${HOME}/.bizar_home/memory/projects/sdk/sessions/2026-07-16-e16c2f59.md +14 -0
- package/packages/sdk/.bizar/learning/instincts.jsonl +5 -0
- package/packages/sdk/package.json +1 -1
- package/scripts/loop-log.txt +29 -0
- package/scripts/loop-tasks.md +79 -0
- package/scripts/overnight-loop.mjs +60 -0
- package/bizar-dash/dist/assets/ArtifactsView-CfYB1le1.js +0 -21
- package/bizar-dash/dist/assets/ArtifactsView-CfYB1le1.js.map +0 -1
- package/bizar-dash/dist/assets/AuthView-D4frSShw.js.map +0 -1
- package/bizar-dash/dist/assets/BackgroundJobsView-DEStvILz.js +0 -1
- package/bizar-dash/dist/assets/BackgroundJobsView-DEStvILz.js.map +0 -1
- package/bizar-dash/dist/assets/ClaudeSessionsView-BprGo67K.js +0 -1
- package/bizar-dash/dist/assets/ClaudeSessionsView-BprGo67K.js.map +0 -1
- package/bizar-dash/dist/assets/ClipboardView-CPlTU5VG.js +0 -1
- package/bizar-dash/dist/assets/LightRAGView-DvqzQoBp.js +0 -6
- package/bizar-dash/dist/assets/LightRAGView-DvqzQoBp.js.map +0 -1
- package/bizar-dash/dist/assets/SchedulesView-o9AtIsH9.js +0 -1
- package/bizar-dash/dist/assets/SchedulesView-o9AtIsH9.js.map +0 -1
- package/bizar-dash/dist/assets/SettingsView-2HSFJPPK.js.map +0 -1
- package/bizar-dash/dist/assets/VoiceView-aoPVT6LJ.js +0 -1
- package/bizar-dash/dist/assets/main-B7D_IMTh.css +0 -1
- package/bizar-dash/dist/assets/main-BURAlktW.js +0 -277
- package/bizar-dash/dist/assets/main-BURAlktW.js.map +0 -1
- package/bizar-dash/tests/chat-session-create.test.mjs +0 -391
- package/bizar-dash/tests/chat-session-stream.test.mjs +0 -308
- package/bizar-dash/tests/cline-runner.test.mjs +0 -172
- package/bizar-dash/tests/cline-sessions-detail.test.mjs +0 -434
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Alert-
|
|
1
|
+
{"version":3,"file":"Alert-pzFISNtS.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/info.js","../../src/web/v8/ui/feedback/Alert.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 Info = createLucideIcon(\"Info\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 16v-4\", key: \"1dtifu\" }],\n [\"path\", { d: \"M12 8h.01\", key: \"e9boi3\" }]\n]);\n\nexport { Info as default };\n//# sourceMappingURL=info.js.map\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport React from 'react';\nimport { AlertCircle, AlertTriangle, CheckCircle2, Info } from 'lucide-react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * Alert — inline contextual message.\n *\n * Tones: info | success | warning | danger.\n *\n * Use cases: empty states, inline help text, error banners inside forms.\n * For status pulses (topbar live indicator) use a small dot, not an Alert.\n */\n\nexport type AlertTone = 'info' | 'success' | 'warning' | 'danger';\n\nconst ICON = {\n info: Info,\n success: CheckCircle2,\n warning: AlertTriangle,\n danger: AlertCircle,\n} as const;\n\nconst TONE_BG = {\n info: 'color-mix(in oklch, var(--info) 12%, var(--surface-1))',\n success: 'color-mix(in oklch, var(--success) 12%, var(--surface-1))',\n warning: 'color-mix(in oklch, var(--warning) 12%, var(--surface-1))',\n danger: 'color-mix(in oklch, var(--danger) 12%, var(--surface-1))',\n} as const;\n\nconst TONE_FG = {\n info: 'var(--info)',\n success: 'var(--success)',\n warning: 'var(--warning)',\n danger: 'var(--danger)',\n} as const;\n\nconst TONE_BORDER = {\n info: 'color-mix(in oklch, var(--info) 30%, var(--border))',\n success: 'color-mix(in oklch, var(--success) 30%, var(--border))',\n warning: 'color-mix(in oklch, var(--warning) 30%, var(--border))',\n danger: 'color-mix(in oklch, var(--danger) 30%, var(--border))',\n} as const;\n\nexport interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'title'> {\n tone?: AlertTone;\n title?: ReactNode;\n children?: ReactNode;\n /** Optional right-aligned action (button). */\n action?: ReactNode;\n /** Override the leading icon. Pass `false` to hide. */\n icon?: ReactNode | false;\n}\n\nexport const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(props, ref) {\n const { tone = 'info', title, children, action, icon, className, ...rest } = props;\n const showIcon = icon !== false;\n const IconNode = icon === false ? null : (icon ?? React.createElement(ICON[tone], { size: 16, 'aria-hidden': true }));\n return (\n <div\n ref={ref}\n role={tone === 'danger' || tone === 'warning' ? 'alert' : 'status'}\n className={cx('v8-alert', `v8-alert--${tone}`, className)}\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 'var(--space-3)',\n padding: 'var(--space-3) var(--space-4)',\n background: TONE_BG[tone],\n border: '1px solid',\n borderColor: TONE_BORDER[tone],\n borderRadius: 'var(--radius)',\n color: 'var(--fg)',\n }}\n {...rest}\n >\n {showIcon && IconNode !== null && (\n <span style={{ color: TONE_FG[tone], flexShrink: 0, marginTop: 1, display: 'inline-flex' }}>\n {IconNode}\n </span>\n )}\n <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n {title !== undefined && (\n <div style={{ fontSize: 'var(--fs-13)', fontWeight: 600 }}>{title}</div>\n )}\n {children !== undefined && (\n <div style={{ fontSize: 'var(--fs-13)', color: 'var(--fg-muted)' }}>{children}</div>\n )}\n </div>\n {action !== undefined && (\n <div style={{ flexShrink: 0, display: 'flex', alignItems: 'center' }}>{action}</div>\n )}\n </div>\n );\n});"],"names":["Info","createLucideIcon","ICON","CheckCircle2","AlertTriangle","AlertCircle","TONE_BG","TONE_FG","TONE_BORDER","Alert","forwardRef","props","ref","tone","title","children","action","icon","className","rest","showIcon","IconNode","React","jsxs","cx","jsx"],"mappings":"kPAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAOC,EAAiB,OAAQ,CACpC,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,KAAM,IAAK,SAAU,EACzD,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,EAC1C,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,CAC5C,CAAC,ECGKC,EAAO,CACX,KAAMF,EACN,QAASG,EACT,QAASC,EACT,OAAQC,CACV,EAEMC,EAAU,CACd,KAAM,yDACN,QAAS,4DACT,QAAS,4DACT,OAAQ,0DACV,EAEMC,EAAU,CACd,KAAM,cACN,QAAS,iBACT,QAAS,iBACT,OAAQ,eACV,EAEMC,EAAc,CAClB,KAAM,sDACN,QAAS,yDACT,QAAS,yDACT,OAAQ,uDACV,EAYaC,EAAQC,EAAAA,WAAuC,SAAeC,EAAOC,EAAK,CACrF,KAAM,CAAE,KAAAC,EAAO,OAAQ,MAAAC,EAAO,SAAAC,EAAU,OAAAC,EAAQ,KAAAC,EAAM,UAAAC,EAAW,GAAGC,CAAA,EAASR,EACvES,EAAWH,IAAS,GACpBI,EAAWJ,IAAS,GAAQ,KAAQA,GAAQK,EAAM,cAAcpB,EAAKW,CAAI,EAAG,CAAE,KAAM,GAAI,cAAe,GAAM,EACnH,OACEU,EAAAA,KAAC,MAAA,CACC,IAAAX,EACA,KAAMC,IAAS,UAAYA,IAAS,UAAY,QAAU,SAC1D,UAAWW,EAAG,WAAY,aAAaX,CAAI,GAAIK,CAAS,EACxD,MAAO,CACL,QAAS,OACT,WAAY,aACZ,IAAK,iBACL,QAAS,gCACT,WAAYZ,EAAQO,CAAI,EACxB,OAAQ,YACR,YAAaL,EAAYK,CAAI,EAC7B,aAAc,gBACd,MAAO,WAAA,EAER,GAAGM,EAEH,SAAA,CAAAC,GAAYC,IAAa,MACxBI,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,MAAOlB,EAAQM,CAAI,EAAG,WAAY,EAAG,UAAW,EAAG,QAAS,aAAA,EACxE,SAAAQ,EACH,EAEFE,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,KAAM,EAAG,SAAU,EAAG,QAAS,OAAQ,cAAe,SAAU,IAAK,kBAChF,SAAA,CAAAT,IAAU,QACTW,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,WAAY,GAAA,EAAQ,SAAAX,CAAA,CAAM,EAEnEC,IAAa,QACZU,MAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAsB,SAAAV,CAAA,CAAS,CAAA,EAElF,EACCC,IAAW,QACVS,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,WAAY,EAAG,QAAS,OAAQ,WAAY,QAAA,EAAa,SAAAT,CAAA,CAAO,CAAA,CAAA,CAAA,CAItF,CAAC","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import{r as l,j as e}from"./cmdk-C3F6LD6N.js";import{d as F,I as f,G as H,S as m,B as g,u as w,h as k,L as V,i as z,F as M}from"./main-BRmJZcHt.js";import{V as O}from"./ViewHeader-BsnaspKw.js";import{C as $,b as D}from"./Card-Clkvh43Q.js";import{I as C}from"./Input-DV-vdaV8.js";import{T as R}from"./Textarea-BfXGMXQ7.js";import{S as A,a as E}from"./Sheet-BwMVGN-8.js";import{E as P}from"./EmptyState-ccT__JZG.js";import{T as X}from"./triangle-alert-BeY8LAv6.js";import{E as L}from"./external-link-DPDQM1YO.js";import{R as I}from"./refresh-ccw-DN_zCB1h.js";import{P as K}from"./plus-Cps-8lcG.js";import{T as B}from"./trash-2-B_Y6HrfN.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 G=F("FileCode",[["path",{d:"M10 12.5 8 15l2 2.5",key:"1tg20x"}],["path",{d:"m14 12.5 2 2.5-2 2.5",key:"yinavb"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z",key:"1mlx9k"}]]);function N({payload:t,slug:r}){const[i,c]=l.useState(!1);return t.kind==="mdx"?e.jsx($,{variant:"default","data-testid":`claude-view-${r}`,children:e.jsx(D,{children:e.jsxs(f,{align:"center",gap:2,children:[e.jsx(H,{size:14,"aria-hidden":!0,style:{color:"var(--fg-muted)"}}),e.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:["Legacy MDX — ",Array.isArray(t.blocks)?`${t.blocks.length} blocks`:"no blocks"]})]})})}):t.html?e.jsxs(m,{gap:2,"data-testid":`claude-view-${r}`,children:[t.safeMode&&e.jsxs(f,{align:"center",gap:2,style:{padding:"var(--space-2)",background:"var(--callout-warning-bg, #fdf6e3)",border:"1px solid var(--callout-warning-border, #e0c97d)",borderRadius:"var(--radius-sm)",fontSize:"var(--fs-12)"},role:"status","data-testid":`claude-safe-${r}`,children:[e.jsx(X,{size:14,"aria-hidden":!0,style:{color:"var(--callout-warning-fg)"}}),e.jsx("span",{children:"Safe mode — the compiler stripped potentially dangerous patterns in this artifact."})]}),t.warnings&&t.warnings.length>0&&e.jsxs("details",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)",padding:"var(--space-2)",background:"var(--surface-1)",borderRadius:"var(--radius-sm)"},children:[e.jsxs("summary",{children:[t.warnings.length," warning(s)"]}),e.jsx("ul",{style:{marginTop:"var(--space-1)"},children:t.warnings.map((s,d)=>e.jsxs("li",{children:[e.jsx("code",{style:{fontFamily:"var(--font-mono)"},children:s.pattern})," ","— ",s.message]},d))})]}),e.jsxs(f,{align:"center",justify:"between",gap:2,children:[e.jsxs("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-muted)"},children:[t.kind," · compiled ",t.compiledAt?new Date(t.compiledAt).toLocaleTimeString():"now"]}),e.jsxs(f,{gap:1,children:[e.jsx(g,{variant:"ghost",onClick:()=>c(s=>!s),"data-testid":`claude-source-${r}`,children:i?"Hide source":"Show source"}),e.jsxs("a",{href:`/api/artifacts/${r}/view`,target:"_blank",rel:"noopener noreferrer","data-testid":`claude-blank-${r}`,style:{display:"inline-flex",alignItems:"center",gap:"var(--space-1)",fontSize:"var(--fs-12)",padding:"var(--space-1) var(--space-2)",color:"var(--fg)",textDecoration:"none",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",background:"var(--surface-0)"},children:[e.jsx(L,{size:12,"aria-hidden":!0})," Open in new tab"]})]})]}),e.jsx("iframe",{title:`claude-artifact-${r}`,"data-testid":`claude-iframe-${r}`,sandbox:"allow-scripts allow-same-origin",srcDoc:t.html,style:{width:"100%",height:480,border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",background:"white"}}),i&&e.jsx("pre",{"data-testid":`claude-source-text-${r}`,style:{padding:"var(--space-2)",background:"var(--surface-1)",borderRadius:"var(--radius-sm)",fontSize:"var(--fs-11)",maxHeight:320,overflow:"auto",fontFamily:"var(--font-mono)",whiteSpace:"pre-wrap"},children:t.html})]}):e.jsx($,{variant:"default","data-testid":`claude-view-${r}`,children:e.jsx(D,{children:e.jsx("span",{role:"alert",style:{color:"var(--danger)"},children:"No HTML returned by the compiler."})})})}function de(){const t=w("/api/artifacts"),[r,i]=l.useState(null),[c,s]=l.useState(!1),[d,o]=l.useState(null),[j,u]=l.useState(null),y=l.useMemo(()=>{var a;return((a=t.data)==null?void 0:a.artifacts)??[]},[t.data]),h=l.useCallback(()=>{t.refetch()},[t]),S=async a=>{u(null);try{await z(`/api/artifacts/${a}`,{method:"DELETE"}),i(null),d===a&&o(null),h()}catch(v){u((v instanceof M,v.message))}};return e.jsxs(m,{gap:4,"data-testid":"artifacts-view",children:[e.jsx(O,{title:"Artifacts",description:"Generated artifacts (plans, diagrams, canvases).",actions:e.jsxs(f,{align:"center",gap:2,children:[j!==null&&e.jsx("span",{role:"alert","data-testid":"artifacts-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:j}),e.jsxs(g,{variant:"ghost",onClick:()=>void h(),"data-testid":"artifacts-refresh",children:[e.jsx(I,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(g,{variant:"primary",onClick:()=>s(!0),"data-testid":"artifacts-add",children:[e.jsx(K,{size:14,"aria-hidden":!0})," Add"]})]})}),e.jsx($,{variant:"default",children:e.jsx(D,{children:t.loading&&y.length===0?e.jsxs(m,{gap:1,children:[e.jsx(k,{style:{height:48}}),e.jsx(k,{style:{height:48}})]}):y.length===0?e.jsx(P,{icon:e.jsx(V,{size:28,"aria-hidden":!0}),title:"No artifacts",description:"Artifacts are generated code — HTML canvases, SVG diagrams, and React components — created by the agent during task work. Add one to get started."}):e.jsx(m,{gap:1,children:y.map(a=>{const v=r===a.slug;return e.jsxs("div",{"data-testid":`artifact-row-${a.slug}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)"},children:[e.jsxs(f,{align:"center",justify:"between",gap:2,children:[e.jsxs(m,{gap:0,style:{minWidth:0,flex:1},children:[e.jsxs(f,{align:"center",gap:2,children:[e.jsx(G,{size:12,"aria-hidden":!0,style:{color:"var(--fg-muted)"}}),e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:a.title||a.slug}),e.jsx("code",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:a.slug}),a.kind&&e.jsxs("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-muted)"},children:["· ",a.kind]})]}),a.description&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:a.description})]}),e.jsxs(f,{gap:1,children:[e.jsxs(g,{variant:"ghost",onClick:()=>o(p=>p===a.slug?null:a.slug),"data-testid":`artifact-open-${a.slug}`,"aria-label":`Open ${a.slug}`,children:[e.jsx(L,{size:14,"aria-hidden":!0})," Open"]}),e.jsx(g,{variant:"ghost",onClick:()=>i(p=>p===a.slug?null:a.slug),"data-testid":`artifact-delete-${a.slug}`,"aria-label":`Delete ${a.slug}`,children:e.jsx(B,{size:14,"aria-hidden":!0})})]})]}),v&&e.jsxs(f,{gap:1,style:{marginTop:"var(--space-1)"},children:[e.jsx(g,{variant:"danger",onClick:()=>void S(a.slug),"data-testid":`artifact-confirm-delete-${a.slug}`,children:"Confirm delete"}),e.jsx(g,{variant:"ghost",onClick:()=>i(null),children:"Cancel"})]})]},a.slug)})})})}),e.jsx(A,{open:c,onOpenChange:s,children:e.jsx(E,{side:"right",title:"Add artifact",description:"Slug + kind + initial source.",children:e.jsx(J,{onSubmit:async a=>{await z("/api/artifacts",{method:"POST",body:a}),s(!1),h()},onCancel:()=>s(!1)})})}),e.jsx(A,{open:d!==null,onOpenChange:a=>{a||o(null)},children:e.jsx(E,{side:"right",title:d??"",description:"Artifact detail",children:d!==null&&e.jsx(U,{slug:d,refresh:h})})})]})}function J({onSubmit:t,onCancel:r}){const[i,c]=l.useState(""),[s,d]=l.useState(""),[o,j]=l.useState(""),[u,y]=l.useState("claude-html"),[h,S]=l.useState(T["claude-html"]),[a,v]=l.useState(!1),[p,b]=l.useState(null),x=n=>{y(n),S(T[n])};return e.jsxs(m,{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:"Slug"}),e.jsx(C,{value:i,onChange:n=>c(n.target.value),"data-testid":"artifact-form-slug"})]}),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:"Title"}),e.jsx(C,{value:s,onChange:n=>d(n.target.value),"data-testid":"artifact-form-title"})]}),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:"Description"}),e.jsx(C,{value:o,onChange:n=>j(n.target.value),"data-testid":"artifact-form-description"})]}),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:"Kind"}),e.jsxs("select",{value:u,onChange:n=>x(n.target.value),"data-testid":"artifact-form-kind",style:{fontFamily:"inherit",fontSize:"var(--fs-12)",padding:"var(--space-2)",background:"var(--surface-0)",color:"var(--fg)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)"},children:[e.jsx("option",{value:"claude-html",children:"Claude HTML"}),e.jsx("option",{value:"claude-svg",children:"Claude SVG"}),e.jsx("option",{value:"claude-react",children:"Claude React (JSX)"}),e.jsx("option",{value:"mdx",children:"Legacy MDX (glyphs)"})]})]}),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:u==="mdx"?"Plan MDX":"Source"}),e.jsx(R,{value:h,rows:u==="claude-react"?10:6,onChange:n=>S(n.target.value),"data-testid":u==="mdx"?"artifact-form-mdx":"artifact-form-source"})]}),p!==null&&e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:p}),e.jsxs(f,{justify:"end",gap:2,children:[e.jsx(g,{variant:"ghost",onClick:r,children:"Cancel"}),e.jsx(g,{variant:"primary",disabled:a||!i.trim(),"data-testid":"artifact-form-submit",onClick:async()=>{v(!0),b(null);try{const n={slug:i.trim(),title:s.trim()||void 0,description:o.trim()||void 0,kind:u};h&&(u==="mdx"?n.planMdx=h:n.source=h),await t(n)}catch(n){b((n instanceof M,n.message)),v(!1)}},children:a?"Creating…":"Create"})]})]})}const T={mdx:`# Hello
|
|
7
|
+
|
|
8
|
+
Add some MDX here.`,"claude-html":`<!doctype html>
|
|
9
|
+
<h1 style="font-family:system-ui">Hello artifact</h1>
|
|
10
|
+
<p>Edit me — click <em>Open</em> to preview.</p>`,"claude-svg":`<svg viewBox="0 0 100 100" width="200" height="200">
|
|
11
|
+
<circle cx="50" cy="50" r="40" fill="#0b66c3"/>
|
|
12
|
+
<text x="50" y="55" text-anchor="middle" fill="white" font-size="14">SVG</text>
|
|
13
|
+
</svg>`,"claude-react":`export default function App() {
|
|
14
|
+
const [n, setN] = React.useState(0);
|
|
15
|
+
return (
|
|
16
|
+
<div style={{ fontFamily: "system-ui", padding: 16 }}>
|
|
17
|
+
<h1>Hello</h1>
|
|
18
|
+
<button onClick={() => setN(n + 1)}>clicked {n}</button>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
}`};function U({slug:t,refresh:r}){var o;const i=w(`/api/artifacts/${t}`),c=w(`/api/artifacts/${t}/render`),s=((o=i.data)==null?void 0:o.kind)||"mdx",d=s==="claude-html"||s==="claude-svg"||s==="claude-react";return e.jsx(m,{gap:2,style:{padding:"var(--space-4)"},children:i.loading&&!i.data?e.jsx(k,{style:{height:80}}):i.data?e.jsxs(m,{gap:2,children:[e.jsxs(f,{align:"center",gap:2,children:[e.jsx("strong",{children:i.data.title||i.data.slug}),e.jsx("code",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:i.data.slug}),e.jsxs("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-muted)"},children:["· ",s]})]}),i.data.description&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:i.data.description}),d&&(c.data?e.jsx(N,{payload:c.data,slug:t}):e.jsx(k,{style:{height:200}})),!d&&c.data&&e.jsxs("span",{"data-testid":`artifact-render-${t}`,style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:["Render: ",Array.isArray(c.data.blocks)?`${c.data.blocks.length} blocks`:"no blocks"]}),e.jsx(_,{payload:i.data,slug:t,onSaved:()=>{i.refetch(),c.refetch(),r()}})]}):e.jsx("span",{role:"alert",style:{color:"var(--danger)"},children:"Not found"})})}function _({payload:t,slug:r,onSaved:i}){const c=t.source??t.planMdx??"",[s,d]=l.useState(t.kind||"mdx"),[o,j]=l.useState(c),[u,y]=l.useState(!1),[h,S]=l.useState(null),[a,v]=l.useState(!1);l.useEffect(()=>{d(t.kind||"mdx"),j(t.source??t.planMdx??"")},[t.slug,t.source,t.planMdx,t.kind]);const p=s!==(t.kind||"mdx")||o!==(t.source??t.planMdx??""),b=async()=>{y(!0),S(null);try{await z(`/api/artifacts/${r}`,{method:"PUT",body:{kind:s,source:s==="mdx"?void 0:o,planMdx:s==="mdx"?o:void 0}}),i()}catch(x){S((x instanceof M,x.message))}finally{y(!1)}};return e.jsxs(m,{gap:1,"data-testid":`artifact-editor-${r}`,children:[e.jsxs(f,{align:"center",justify:"between",gap:2,children:[e.jsx(g,{variant:"ghost",onClick:()=>v(x=>!x),"data-testid":`artifact-edit-toggle-${r}`,children:a?"Close editor":"Edit"}),p&&e.jsx("span",{style:{fontSize:"var(--fs-11)",color:"var(--callout-warning-fg, #b58900)"},children:"Unsaved changes"})]}),a&&e.jsxs(m,{gap:2,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:"Kind"}),e.jsxs("select",{value:s,onChange:x=>d(x.target.value),"data-testid":`artifact-edit-kind-${r}`,style:{fontFamily:"inherit",fontSize:"var(--fs-12)",padding:"var(--space-2)",background:"var(--surface-0)",color:"var(--fg)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)"},children:[e.jsx("option",{value:"claude-html",children:"Claude HTML"}),e.jsx("option",{value:"claude-svg",children:"Claude SVG"}),e.jsx("option",{value:"claude-react",children:"Claude React (JSX)"}),e.jsx("option",{value:"mdx",children:"Legacy MDX"})]})]}),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:s==="mdx"?"Plan MDX":"Source"}),e.jsx(R,{value:o,rows:s==="claude-react"?12:8,onChange:x=>j(x.target.value),"data-testid":`artifact-edit-source-${r}`})]}),h!==null&&e.jsx("span",{role:"alert","data-testid":`artifact-edit-error-${r}`,style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:h}),e.jsxs(f,{gap:1,children:[e.jsx(g,{variant:"primary",disabled:u||!p,onClick:()=>void b(),"data-testid":`artifact-edit-save-${r}`,children:u?"Saving…":"Save"}),e.jsx(g,{variant:"ghost",disabled:u||!p,onClick:()=>{d(t.kind||"mdx"),j(t.source??t.planMdx??""),S(null)},"data-testid":`artifact-edit-revert-${r}`,children:"Revert"})]})]})]})}export{de as ArtifactsView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArtifactsView-BVU5lfo7.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/file-code.js","../../src/web/v8/views/Artifacts/ClaudeArtifactView.tsx","../../src/web/v8/views/Artifacts/ArtifactsView.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 FileCode = createLucideIcon(\"FileCode\", [\n [\"path\", { d: \"M10 12.5 8 15l2 2.5\", key: \"1tg20x\" }],\n [\"path\", { d: \"m14 12.5 2 2.5-2 2.5\", key: \"yinavb\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z\", key: \"1mlx9k\" }]\n]);\n\nexport { FileCode as default };\n//# sourceMappingURL=file-code.js.map\n","/**\n * v8/views/Artifacts/ClaudeArtifactView.tsx — v10.1.0.\n *\n * Renders Claude-* kind artifacts (HTML / SVG / React) inside a\n * sandboxed iframe. The server hands us a fully-compiled HTML envelope\n * (returned from GET /api/artifacts/:slug/render) and we drop it into\n * `srcdoc`. The iframe has `sandbox` set so even if a malicious escape\n * slips past server-side filtering, the runtime is still constrained.\n *\n * Two render modes:\n * 1. <iframe srcdoc> — for full-envelope artifacts (default).\n * 2. Plain `<div>` for an `mdx` kind fallback (handled by caller).\n */\n\nimport { useState } from 'react';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { AlertTriangle, ShieldCheck, ExternalLink } from 'lucide-react';\nimport { Button } from '../../ui/controls/Button.js';\n\nexport interface ClaudeRenderPayload {\n slug: string;\n kind: 'claude-html' | 'claude-svg' | 'claude-react' | 'mdx';\n html?: string;\n blocks?: unknown[];\n frontmatter?: Record<string, unknown>;\n warnings?: Array<{ message?: string; pattern?: string }>;\n safeMode?: boolean;\n compiledAt?: string;\n}\n\nexport function ClaudeArtifactView({\n payload,\n slug,\n}: {\n payload: ClaudeRenderPayload;\n slug: string;\n}): JSX.Element {\n const [showSource, setShowSource] = useState(false);\n\n if (payload.kind === 'mdx') {\n // Legacy fallback — the server returns no `html` for mdx; just show\n // the compiled block count.\n return (\n <Card variant=\"default\" data-testid={`claude-view-${slug}`}>\n <CardBody>\n <Inline align=\"center\" gap={2}>\n <ShieldCheck size={14} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Legacy MDX — {Array.isArray(payload.blocks) ? `${payload.blocks.length} blocks` : 'no blocks'}\n </span>\n </Inline>\n </CardBody>\n </Card>\n );\n }\n\n if (!payload.html) {\n return (\n <Card variant=\"default\" data-testid={`claude-view-${slug}`}>\n <CardBody>\n <span role=\"alert\" style={{ color: 'var(--danger)' }}>\n No HTML returned by the compiler.\n </span>\n </CardBody>\n </Card>\n );\n }\n\n return (\n <Stack gap={2} data-testid={`claude-view-${slug}`}>\n {payload.safeMode && (\n <Inline\n align=\"center\"\n gap={2}\n style={{\n padding: 'var(--space-2)',\n background: 'var(--callout-warning-bg, #fdf6e3)',\n border: '1px solid var(--callout-warning-border, #e0c97d)',\n borderRadius: 'var(--radius-sm)',\n fontSize: 'var(--fs-12)',\n }}\n role=\"status\"\n data-testid={`claude-safe-${slug}`}\n >\n <AlertTriangle size={14} aria-hidden style={{ color: 'var(--callout-warning-fg)' }} />\n <span>\n Safe mode — the compiler stripped potentially dangerous\n patterns in this artifact.\n </span>\n </Inline>\n )}\n {payload.warnings && payload.warnings.length > 0 && (\n <details\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-muted)',\n padding: 'var(--space-2)',\n background: 'var(--surface-1)',\n borderRadius: 'var(--radius-sm)',\n }}\n >\n <summary>{payload.warnings.length} warning(s)</summary>\n <ul style={{ marginTop: 'var(--space-1)' }}>\n {payload.warnings.map((w, i) => (\n <li key={i}>\n <code style={{ fontFamily: 'var(--font-mono)' }}>\n {w.pattern}\n </code>{' '}\n — {w.message}\n </li>\n ))}\n </ul>\n </details>\n )}\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>\n {payload.kind} · compiled {payload.compiledAt ? new Date(payload.compiledAt).toLocaleTimeString() : 'now'}\n </span>\n <Inline gap={1}>\n <Button variant=\"ghost\" onClick={() => setShowSource((v) => !v)} data-testid={`claude-source-${slug}`}>\n {showSource ? 'Hide source' : 'Show source'}\n </Button>\n <a\n href={`/api/artifacts/${slug}/view`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-testid={`claude-blank-${slug}`}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 'var(--space-1)',\n fontSize: 'var(--fs-12)',\n padding: 'var(--space-1) var(--space-2)',\n color: 'var(--fg)',\n textDecoration: 'none',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: 'var(--surface-0)',\n }}\n >\n <ExternalLink size={12} aria-hidden /> Open in new tab\n </a>\n </Inline>\n </Inline>\n <iframe\n title={`claude-artifact-${slug}`}\n data-testid={`claude-iframe-${slug}`}\n sandbox=\"allow-scripts allow-same-origin\"\n srcDoc={payload.html}\n style={{\n width: '100%',\n height: 480,\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: 'white',\n }}\n />\n {showSource && (\n <pre\n data-testid={`claude-source-text-${slug}`}\n style={{\n padding: 'var(--space-2)',\n background: 'var(--surface-1)',\n borderRadius: 'var(--radius-sm)',\n fontSize: 'var(--fs-11)',\n maxHeight: 320,\n overflow: 'auto',\n fontFamily: 'var(--font-mono)',\n whiteSpace: 'pre-wrap',\n }}\n >\n {payload.html}\n </pre>\n )}\n </Stack>\n );\n}","/**\n * v8/views/Artifacts/ArtifactsView.tsx — Sprint S43, v9.3.0 → v10.1.0\n * (Claude Artifacts swap).\n *\n * Artifacts list (GET /api/artifacts) with per-row open-to-detail\n * (right-hand Sheet using GET /api/artifacts/:slug + /render) and\n * inline-confirm Delete (DELETE /api/artifacts/:slug). Add Sheet\n * posts a new artifact (POST /api/artifacts {slug, kind, source, ...}).\n *\n * v10.1.0 — Detail panel dispatches by `kind`:\n * - claude-html / claude-svg / claude-react → sandboxed iframe\n * via <ClaudeArtifactView>\n * - mdx → legacy block-renderer fallback\n *\n * The AddForm gains a `kind` dropdown + a textarea bound to `source`;\n * the textarea defaults to the kind-specific starting template.\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Layers, Plus, Trash2, RefreshCcw, FileCode, ExternalLink } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Textarea } from '../../ui/controls/Textarea.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport { ClaudeArtifactView, type ClaudeRenderPayload } from './ClaudeArtifactView.js';\n\ninterface Artifact {\n slug: string;\n title?: string;\n kind?: 'mdx' | 'claude-html' | 'claude-svg' | 'claude-react';\n description?: string;\n createdAt?: string | number;\n updatedAt?: string | number;\n planMdx?: string;\n source?: string;\n frontmatter?: Record<string, unknown>;\n}\n\nexport function ArtifactsView(): JSX.Element {\n const payload = useFetch<{ artifacts: Artifact[] }>('/api/artifacts');\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [adding, setAdding] = useState<boolean>(false);\n const [activeSlug, setActiveSlug] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const artifacts = useMemo<Artifact[]>(() => payload.data?.artifacts ?? [], [payload.data]);\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n\n const drop = async (slug: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/artifacts/${slug}`, { method: 'DELETE' });\n setConfirmDelete(null);\n if (activeSlug === slug) setActiveSlug(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n return (\n <Stack gap={4} data-testid=\"artifacts-view\">\n <ViewHeader\n title=\"Artifacts\"\n description=\"Generated artifacts (plans, diagrams, canvases).\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"artifacts-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"artifacts-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => setAdding(true)} data-testid=\"artifacts-add\">\n <Plus size={14} aria-hidden /> Add\n </Button>\n </Inline>\n }\n />\n\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && artifacts.length === 0 ? (\n <Stack gap={1}>\n <Skeleton style={{ height: 48 }} />\n <Skeleton style={{ height: 48 }} />\n </Stack>\n ) : artifacts.length === 0 ? (\n <EmptyState icon={<Layers size={28} aria-hidden />} title=\"No artifacts\" description=\"Artifacts are generated code — HTML canvases, SVG diagrams, and React components — created by the agent during task work. Add one to get started.\" />\n ) : (\n <Stack gap={1}>\n {artifacts.map((a) => {\n const isConfirming = confirmDelete === a.slug;\n return (\n <div\n key={a.slug}\n data-testid={`artifact-row-${a.slug}`}\n style={{ padding: 'var(--space-2)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)' }}\n >\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Stack gap={0} style={{ minWidth: 0, flex: 1 }}>\n <Inline align=\"center\" gap={2}>\n <FileCode size={12} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n <strong style={{ fontSize: 'var(--fs-13)' }}>{a.title || a.slug}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{a.slug}</code>\n {a.kind && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>· {a.kind}</span>}\n </Inline>\n {a.description && <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{a.description}</span>}\n </Stack>\n <Inline gap={1}>\n <Button variant=\"ghost\" onClick={() => setActiveSlug((cur) => (cur === a.slug ? null : a.slug))} data-testid={`artifact-open-${a.slug}`} aria-label={`Open ${a.slug}`}>\n <ExternalLink size={14} aria-hidden /> Open\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete((cur) => (cur === a.slug ? null : a.slug))} data-testid={`artifact-delete-${a.slug}`} aria-label={`Delete ${a.slug}`}>\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n </Inline>\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"danger\" onClick={() => void drop(a.slug)} data-testid={`artifact-confirm-delete-${a.slug}`}>\n Confirm delete\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete(null)}>Cancel</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 artifact\" description=\"Slug + kind + initial source.\">\n <AddForm\n onSubmit={async (body) => {\n await fetchJson('/api/artifacts', { method: 'POST', body });\n setAdding(false);\n refresh();\n }}\n onCancel={() => setAdding(false)}\n />\n </SheetContent>\n </Sheet>\n\n <Sheet open={activeSlug !== null} onOpenChange={(open) => { if (!open) setActiveSlug(null); }}>\n <SheetContent side=\"right\" title={activeSlug ?? ''} description=\"Artifact detail\">\n {activeSlug !== null && <ArtifactDetail slug={activeSlug} refresh={refresh} />}\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}\n\nfunction AddForm({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (body: { slug: string; title?: string; description?: string; kind?: string; source?: string; planMdx?: string }) => Promise<void>;\n onCancel: () => void;\n}): JSX.Element {\n const [slug, setSlug] = useState<string>('');\n const [title, setTitle] = useState<string>('');\n const [description, setDescription] = useState<string>('');\n const [kind, setKind] = useState<'mdx' | 'claude-html' | 'claude-svg' | 'claude-react'>('claude-html');\n const [source, setSource] = useState<string>(KIND_TEMPLATES['claude-html']);\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n // When the user changes kind, swap the textarea content to a starter\n // template for that kind. They can still edit further.\n const onKindChange = (next: 'mdx' | 'claude-html' | 'claude-svg' | 'claude-react'): void => {\n setKind(next);\n setSource(KIND_TEMPLATES[next]);\n };\n\n return (\n <Stack gap={3} style={{ padding: 'var(--space-4)' }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Slug</span>\n <Input value={slug} onChange={(e) => setSlug((e.target as HTMLInputElement).value)} data-testid=\"artifact-form-slug\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Title</span>\n <Input value={title} onChange={(e) => setTitle((e.target as HTMLInputElement).value)} data-testid=\"artifact-form-title\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Description</span>\n <Input value={description} onChange={(e) => setDescription((e.target as HTMLInputElement).value)} data-testid=\"artifact-form-description\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Kind</span>\n <select\n value={kind}\n onChange={(e) => onKindChange(e.target.value as typeof kind)}\n data-testid=\"artifact-form-kind\"\n style={{\n fontFamily: 'inherit',\n fontSize: 'var(--fs-12)',\n padding: 'var(--space-2)',\n background: 'var(--surface-0)',\n color: 'var(--fg)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n }}\n >\n <option value=\"claude-html\">Claude HTML</option>\n <option value=\"claude-svg\">Claude SVG</option>\n <option value=\"claude-react\">Claude React (JSX)</option>\n <option value=\"mdx\">Legacy MDX (glyphs)</option>\n </select>\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {kind === 'mdx' ? 'Plan MDX' : 'Source'}\n </span>\n <Textarea\n value={source}\n rows={kind === 'claude-react' ? 10 : 6}\n onChange={(e) => setSource((e.target as HTMLTextAreaElement).value)}\n data-testid={kind === 'mdx' ? 'artifact-form-mdx' : 'artifact-form-source'}\n />\n </label>\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Inline justify=\"end\" gap={2}>\n <Button variant=\"ghost\" onClick={onCancel}>Cancel</Button>\n <Button\n variant=\"primary\"\n disabled={busy || !slug.trim()}\n data-testid=\"artifact-form-submit\"\n onClick={async () => {\n setBusy(true);\n setError(null);\n try {\n const body: { slug: string; title?: string; description?: string; kind: typeof kind; source?: string; planMdx?: string } = {\n slug: slug.trim(),\n title: title.trim() || undefined,\n description: description.trim() || undefined,\n kind,\n };\n if (source) {\n if (kind === 'mdx') body.planMdx = source; else body.source = source;\n }\n await onSubmit(body);\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n setBusy(false);\n }\n }}\n >\n {busy ? 'Creating…' : 'Create'}\n </Button>\n </Inline>\n </Stack>\n );\n}\n\nconst KIND_TEMPLATES: Record<'mdx' | 'claude-html' | 'claude-svg' | 'claude-react', string> = {\n mdx: '# Hello\\n\\nAdd some MDX here.',\n 'claude-html': '<!doctype html>\\n<h1 style=\"font-family:system-ui\">Hello artifact</h1>\\n<p>Edit me — click <em>Open</em> to preview.</p>',\n 'claude-svg': '<svg viewBox=\"0 0 100 100\" width=\"200\" height=\"200\">\\n <circle cx=\"50\" cy=\"50\" r=\"40\" fill=\"#0b66c3\"/>\\n <text x=\"50\" y=\"55\" text-anchor=\"middle\" fill=\"white\" font-size=\"14\">SVG</text>\\n</svg>',\n 'claude-react': 'export default function App() {\\n const [n, setN] = React.useState(0);\\n return (\\n <div style={{ fontFamily: \"system-ui\", padding: 16 }}>\\n <h1>Hello</h1>\\n <button onClick={() => setN(n + 1)}>clicked {n}</button>\\n </div>\\n );\\n}',\n};\n\nfunction ArtifactDetail({ slug, refresh }: { slug: string; refresh: () => void }): JSX.Element {\n const payload = useFetch<Artifact>(`/api/artifacts/${slug}`);\n const renderPayload = useFetch<ClaudeRenderPayload>(`/api/artifacts/${slug}/render`);\n const kind = payload.data?.kind || 'mdx';\n const isClaude = kind === 'claude-html' || kind === 'claude-svg' || kind === 'claude-react';\n\n return (\n <Stack gap={2} style={{ padding: 'var(--space-4)' }}>\n {payload.loading && !payload.data ? (\n <Skeleton style={{ height: 80 }} />\n ) : payload.data ? (\n <Stack gap={2}>\n <Inline align=\"center\" gap={2}>\n <strong>{payload.data.title || payload.data.slug}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{payload.data.slug}</code>\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>· {kind}</span>\n </Inline>\n {payload.data.description && <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{payload.data.description}</span>}\n\n {/* Claude-* kinds render in a sandboxed iframe via the new\n <ClaudeArtifactView>. The server compiles the source on\n demand and returns iframe-ready HTML (srcdoc). */}\n {isClaude && (\n renderPayload.data ? (\n <ClaudeArtifactView payload={renderPayload.data} slug={slug} />\n ) : (\n <Skeleton style={{ height: 200 }} />\n )\n )}\n\n {/* Legacy MDX path keeps the original block-count summary. */}\n {!isClaude && renderPayload.data && (\n <span data-testid={`artifact-render-${slug}`} style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Render: {Array.isArray(renderPayload.data.blocks) ? `${renderPayload.data.blocks.length} blocks` : 'no blocks'}\n </span>\n )}\n\n {/* Inline editor — kind switch + textarea + save. */}\n <Editor payload={payload.data} slug={slug} onSaved={() => { void payload.refetch(); void renderPayload.refetch(); refresh(); }} />\n </Stack>\n ) : (\n <span role=\"alert\" style={{ color: 'var(--danger)' }}>Not found</span>\n )}\n </Stack>\n );\n}\n\n/**\n * Inline editor: lets the user change the kind, edit the body, and\n * save via PUT /api/artifacts/:slug. After save we re-fetch both the\n * artifact + the compiled render so the iframe updates with the new\n * source on the next paint.\n */\nfunction Editor({\n payload,\n slug,\n onSaved,\n}: {\n payload: Artifact;\n slug: string;\n onSaved: () => void;\n}): JSX.Element {\n const initial = payload.source ?? payload.planMdx ?? '';\n const [editKind, setEditKind] = useState<typeof payload.kind>(payload.kind || 'mdx');\n const [editSource, setEditSource] = useState<string>(initial);\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const [open, setOpen] = useState<boolean>(false);\n\n // Sync the textarea when the underlying artifact changes (e.g. when\n // the user opens a different slug in the same Sheet).\n useEffect(() => {\n setEditKind(payload.kind || 'mdx');\n setEditSource(payload.source ?? payload.planMdx ?? '');\n }, [payload.slug, payload.source, payload.planMdx, payload.kind]);\n\n const dirty =\n editKind !== (payload.kind || 'mdx') || editSource !== (payload.source ?? payload.planMdx ?? '');\n\n const save = async (): Promise<void> => {\n setBusy(true);\n setError(null);\n try {\n await fetchJson(`/api/artifacts/${slug}`, {\n method: 'PUT',\n body: {\n kind: editKind,\n source: editKind === 'mdx' ? undefined : editSource,\n planMdx: editKind === 'mdx' ? editSource : undefined,\n },\n });\n onSaved();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Stack gap={1} data-testid={`artifact-editor-${slug}`}>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Button variant=\"ghost\" onClick={() => setOpen((v) => !v)} data-testid={`artifact-edit-toggle-${slug}`}>\n {open ? 'Close editor' : 'Edit'}\n </Button>\n {dirty && (\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--callout-warning-fg, #b58900)' }}>\n Unsaved changes\n </span>\n )}\n </Inline>\n {open && (\n <Stack gap={2}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Kind</span>\n <select\n value={editKind}\n onChange={(e) => setEditKind(e.target.value as typeof editKind)}\n data-testid={`artifact-edit-kind-${slug}`}\n style={{\n fontFamily: 'inherit',\n fontSize: 'var(--fs-12)',\n padding: 'var(--space-2)',\n background: 'var(--surface-0)',\n color: 'var(--fg)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n }}\n >\n <option value=\"claude-html\">Claude HTML</option>\n <option value=\"claude-svg\">Claude SVG</option>\n <option value=\"claude-react\">Claude React (JSX)</option>\n <option value=\"mdx\">Legacy MDX</option>\n </select>\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {editKind === 'mdx' ? 'Plan MDX' : 'Source'}\n </span>\n <Textarea\n value={editSource}\n rows={editKind === 'claude-react' ? 12 : 8}\n onChange={(e) => setEditSource((e.target as HTMLTextAreaElement).value)}\n data-testid={`artifact-edit-source-${slug}`}\n />\n </label>\n {error !== null && (\n <span role=\"alert\" data-testid={`artifact-edit-error-${slug}`} style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Inline gap={1}>\n <Button\n variant=\"primary\"\n disabled={busy || !dirty}\n onClick={() => void save()}\n data-testid={`artifact-edit-save-${slug}`}\n >\n {busy ? 'Saving…' : 'Save'}\n </Button>\n <Button\n variant=\"ghost\"\n disabled={busy || !dirty}\n onClick={() => {\n setEditKind(payload.kind || 'mdx');\n setEditSource(payload.source ?? payload.planMdx ?? '');\n setError(null);\n }}\n data-testid={`artifact-edit-revert-${slug}`}\n >\n Revert\n </Button>\n </Inline>\n </Stack>\n )}\n </Stack>\n );\n}"],"names":["FileCode","createLucideIcon","ClaudeArtifactView","payload","slug","showSource","setShowSource","useState","jsx","Card","CardBody","jsxs","Inline","ShieldCheck","Stack","AlertTriangle","w","i","Button","v","ExternalLink","ArtifactsView","useFetch","confirmDelete","setConfirmDelete","adding","setAdding","activeSlug","setActiveSlug","error","setError","artifacts","useMemo","_a","refresh","useCallback","drop","fetchJson","err","FetchError","ViewHeader","RefreshCcw","Plus","Skeleton","EmptyState","Layers","isConfirming","cur","Trash2","Sheet","SheetContent","AddForm","body","open","ArtifactDetail","onSubmit","onCancel","setSlug","title","setTitle","description","setDescription","kind","setKind","source","setSource","KIND_TEMPLATES","busy","setBusy","onKindChange","next","Input","e","Textarea","renderPayload","isClaude","Editor","onSaved","initial","editKind","setEditKind","editSource","setEditSource","setOpen","useEffect","dirty","save"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as s,j as e}from"./cmdk-C3F6LD6N.js";import{d as x,i as h,F as u,S as o,h as T,I as l,b as f,G as F,B as r}from"./main-
|
|
1
|
+
import{r as s,j as e}from"./cmdk-C3F6LD6N.js";import{d as x,i as h,F as u,S as o,h as T,I as l,b as f,G as F,B as r}from"./main-BRmJZcHt.js";import{V as O}from"./ViewHeader-BsnaspKw.js";import{C as w,b as z}from"./Card-Clkvh43Q.js";import{I as V}from"./Input-DV-vdaV8.js";import{S as A}from"./shield-alert-DA9K6uZO.js";import{R as L}from"./rotate-cw-CClSVUaX.js";/**
|
|
2
2
|
* @license lucide-react v0.460.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -13,4 +13,4 @@ import{r as s,j as e}from"./cmdk-C3F6LD6N.js";import{d as x,i as h,F as u,S as o
|
|
|
13
13
|
*
|
|
14
14
|
* This source code is licensed under the ISC license.
|
|
15
15
|
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
-
*/const E=x("Eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);function W(){const[a,R]=s.useState(null),[d,
|
|
16
|
+
*/const E=x("Eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);function W(){const[a,R]=s.useState(null),[d,p]=s.useState(null),[n,y]=s.useState(null),[g,j]=s.useState(!1),[v,m]=s.useState(!1),[B,c]=s.useState(!1),[k,S]=s.useState(!1),[C,i]=s.useState(null),b=s.useCallback(async()=>{p(null);try{const t=await h("/api/auth/status");R(t)}catch(t){p((t instanceof u,t.message))}},[]);s.useEffect(()=>{b()},[b]);const q=async()=>{j(!0),i(null);try{const t=await h("/api/auth/reveal");y(t.token)}catch(t){i((t instanceof u,t.message))}finally{j(!1)}},I=async()=>{S(!0),i(null);try{const t=await h("/api/auth/regenerate",{method:"POST",body:{}});y(t.token),m(!0),c(!1)}catch(t){i((t instanceof u,t.message))}finally{S(!1)}},M=async()=>{if(n)try{await navigator.clipboard.writeText(n)}catch{}};return e.jsxs(o,{gap:4,"data-testid":"auth-view",children:[e.jsx(O,{title:"Auth",description:"Dashboard auth status + bearer token management."}),e.jsx(w,{variant:"default",children:e.jsx(z,{children:e.jsxs(o,{gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Status"}),a===null&&d===null?e.jsx(T,{style:{height:24,width:240}}):d!==null?e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:d}):e.jsxs(l,{gap:2,wrap:!0,children:[a!=null&&a.required?e.jsxs(f,{tone:"warning","data-testid":"auth-required",children:[e.jsx(A,{size:12,"aria-hidden":!0})," Required"]}):e.jsxs(f,{tone:"success","data-testid":"auth-required",children:[e.jsx(F,{size:12,"aria-hidden":!0})," Not required"]}),(a==null?void 0:a.loopback)&&e.jsx(f,{tone:"info",children:"Loopback"}),(a==null?void 0:a.peer)&&e.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:a.peer})]})]})})}),e.jsx(w,{variant:"default",children:e.jsx(z,{children:e.jsxs(o,{gap:3,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Bearer token"}),n===null?e.jsx(l,{gap:2,children:e.jsxs(r,{variant:"ghost",onClick:()=>void q(),disabled:g,"data-testid":"auth-reveal",children:[e.jsx(E,{size:14,"aria-hidden":!0})," ",g?"Loading…":"Reveal"]})}):e.jsxs(o,{gap:2,children:[e.jsxs(l,{gap:2,children:[e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)",flex:1},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Bearer token"}),e.jsx(V,{readOnly:!0,value:v?n:"••••••••••••••••••••••","aria-label":"Bearer token","data-testid":"auth-token-input",onFocus:t=>t.target.select()})]}),e.jsx(r,{variant:"ghost",onClick:()=>m(t=>!t),"data-testid":"auth-toggle-visibility",children:v?e.jsx(G,{size:14,"aria-hidden":!0}):e.jsx(E,{size:14,"aria-hidden":!0})}),e.jsxs(r,{variant:"ghost",onClick:()=>void M(),"data-testid":"auth-copy",children:[e.jsx(D,{size:14,"aria-hidden":!0})," Copy"]})]}),B?e.jsxs(l,{gap:1,children:[e.jsx(r,{variant:"danger",onClick:()=>void I(),disabled:k,"data-testid":"auth-confirm-regen",children:"Confirm rotate"}),e.jsx(r,{variant:"ghost",onClick:()=>c(!1),disabled:k,"data-testid":"auth-cancel-regen",children:"Cancel"})]}):e.jsxs(r,{variant:"danger",onClick:()=>c(!0),"data-testid":"auth-regen",children:[e.jsx(L,{size:14,"aria-hidden":!0})," Rotate token"]})]}),C!==null&&e.jsx("span",{role:"alert","data-testid":"auth-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:C})]})})})]})}export{W as AuthView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthView-BZ-bPIOM.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/copy.js","../../../node_modules/lucide-react/dist/esm/icons/eye-off.js","../../../node_modules/lucide-react/dist/esm/icons/eye.js","../../src/web/v8/views/Auth/AuthView.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 Copy = createLucideIcon(\"Copy\", [\n [\"rect\", { width: \"14\", height: \"14\", x: \"8\", y: \"8\", rx: \"2\", ry: \"2\", key: \"17jyea\" }],\n [\"path\", { d: \"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\", key: \"zix9uf\" }]\n]);\n\nexport { Copy as default };\n//# sourceMappingURL=copy.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 EyeOff = createLucideIcon(\"EyeOff\", [\n [\n \"path\",\n {\n d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\",\n key: \"ct8e1f\"\n }\n ],\n [\"path\", { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\", key: \"151rxh\" }],\n [\n \"path\",\n {\n d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\",\n key: \"13bj9a\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n]);\n\nexport { EyeOff as default };\n//# sourceMappingURL=eye-off.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 Eye = createLucideIcon(\"Eye\", [\n [\n \"path\",\n {\n d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\",\n key: \"1nclc0\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n]);\n\nexport { Eye as default };\n//# sourceMappingURL=eye.js.map\n","/**\n * v8/views/Auth/AuthView.tsx — Sprint S40, v9.3.0.\n *\n * Auth status + token-reveal + regenerate surface. Reads the\n * unauthed /api/auth/status on mount, then on user request hits\n * the authed /api/auth/reveal to show the current token, and\n * /api/auth/regenerate (with inline confirm) to mint a new one.\n */\n\nimport { useCallback, useEffect, useState } from 'react';\nimport { Copy, Eye, EyeOff, RotateCw, ShieldCheck, ShieldAlert } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Badge } from '../../ui/data/Badge.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\ninterface AuthStatus {\n required: boolean;\n loopback: boolean;\n peer?: string;\n}\n\nexport function AuthView(): JSX.Element {\n const [status, setStatus] = useState<AuthStatus | null>(null);\n const [statusError, setStatusError] = useState<string | null>(null);\n const [token, setToken] = useState<string | null>(null);\n const [revealing, setRevealing] = useState<boolean>(false);\n const [showToken, setShowToken] = useState<boolean>(false);\n const [confirmRegen, setConfirmRegen] = useState<boolean>(false);\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n const loadStatus = useCallback(async () => {\n setStatusError(null);\n try {\n const res = await fetchJson<AuthStatus>('/api/auth/status');\n setStatus(res);\n } catch (err) {\n setStatusError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n }, []);\n\n useEffect(() => { void loadStatus(); }, [loadStatus]);\n\n const reveal = async (): Promise<void> => {\n setRevealing(true);\n setError(null);\n try {\n const res = await fetchJson<{ token: string }>('/api/auth/reveal');\n setToken(res.token);\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setRevealing(false);\n }\n };\n\n const regenerate = async (): Promise<void> => {\n setBusy(true);\n setError(null);\n try {\n const res = await fetchJson<{ token: string }>('/api/auth/regenerate', { method: 'POST', body: {} });\n setToken(res.token);\n setShowToken(true);\n setConfirmRegen(false);\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n };\n\n const copy = async (): Promise<void> => {\n if (!token) return;\n try {\n await navigator.clipboard.writeText(token);\n } catch { /* clipboard might be blocked; the token is still on-screen */ }\n };\n\n return (\n <Stack gap={4} data-testid=\"auth-view\">\n <ViewHeader\n title=\"Auth\"\n description=\"Dashboard auth status + bearer token management.\"\n />\n\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Status</strong>\n {status === null && statusError === null ? (\n <Skeleton style={{ height: 24, width: 240 }} />\n ) : statusError !== null ? (\n <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{statusError}</span>\n ) : (\n <Inline gap={2} wrap>\n {status?.required ? (\n <Badge tone=\"warning\" data-testid=\"auth-required\">\n <ShieldAlert size={12} aria-hidden /> Required\n </Badge>\n ) : (\n <Badge tone=\"success\" data-testid=\"auth-required\">\n <ShieldCheck size={12} aria-hidden /> Not required\n </Badge>\n )}\n {status?.loopback && <Badge tone=\"info\">Loopback</Badge>}\n {status?.peer && (\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {status.peer}\n </span>\n )}\n </Inline>\n )}\n </Stack>\n </CardBody>\n </Card>\n\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={3}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Bearer token</strong>\n {token === null ? (\n <Inline gap={2}>\n <Button variant=\"ghost\" onClick={() => void reveal()} disabled={revealing} data-testid=\"auth-reveal\">\n <Eye size={14} aria-hidden /> {revealing ? 'Loading…' : 'Reveal'}\n </Button>\n </Inline>\n ) : (\n <Stack gap={2}>\n <Inline gap={2}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)', flex: 1 }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Bearer token</span>\n <Input\n readOnly\n value={showToken ? token : '••••••••••••••••••••••'}\n aria-label=\"Bearer token\"\n data-testid=\"auth-token-input\"\n onFocus={(e) => (e.target as HTMLInputElement).select()}\n />\n </label>\n <Button variant=\"ghost\" onClick={() => setShowToken((s) => !s)} data-testid=\"auth-toggle-visibility\">\n {showToken ? <EyeOff size={14} aria-hidden /> : <Eye size={14} aria-hidden />}\n </Button>\n <Button variant=\"ghost\" onClick={() => void copy()} data-testid=\"auth-copy\">\n <Copy size={14} aria-hidden /> Copy\n </Button>\n </Inline>\n {confirmRegen ? (\n <Inline gap={1}>\n <Button variant=\"danger\" onClick={() => void regenerate()} disabled={busy} data-testid=\"auth-confirm-regen\">\n Confirm rotate\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmRegen(false)} disabled={busy} data-testid=\"auth-cancel-regen\">\n Cancel\n </Button>\n </Inline>\n ) : (\n <Button variant=\"danger\" onClick={() => setConfirmRegen(true)} data-testid=\"auth-regen\">\n <RotateCw size={14} aria-hidden /> Rotate token\n </Button>\n )}\n </Stack>\n )}\n {error !== null && (\n <span role=\"alert\" data-testid=\"auth-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n </Stack>\n </CardBody>\n </Card>\n </Stack>\n );\n}"],"names":["Copy","createLucideIcon","EyeOff","Eye","AuthView","status","setStatus","useState","statusError","setStatusError","token","setToken","revealing","setRevealing","showToken","setShowToken","confirmRegen","setConfirmRegen","busy","setBusy","error","setError","loadStatus","useCallback","res","fetchJson","err","FetchError","useEffect","reveal","regenerate","copy","jsxs","Stack","jsx","ViewHeader","Card","CardBody","Skeleton","Inline","Badge","ShieldAlert","ShieldCheck","Button","Input","e","s","RotateCw"],"mappings":"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","x_google_ignoreList":[0,1,2]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{d as y,g as h}from"./main-
|
|
1
|
+
import{d as y,g as h}from"./main-BRmJZcHt.js";import{r as f,j as i}from"./cmdk-C3F6LD6N.js";/**
|
|
2
2
|
* @license lucide-react v0.460.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Avatar-
|
|
1
|
+
{"version":3,"file":"Avatar-CRW81ewE.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/git-branch.js","../../src/web/v8/ui/data/Avatar.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 GitBranch = createLucideIcon(\"GitBranch\", [\n [\"line\", { x1: \"6\", x2: \"6\", y1: \"3\", y2: \"15\", key: \"17qcm7\" }],\n [\"circle\", { cx: \"18\", cy: \"6\", r: \"3\", key: \"1h7g24\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M18 9a9 9 0 0 1-9 9\", key: \"n2h4wq\" }]\n]);\n\nexport { GitBranch as default };\n//# sourceMappingURL=git-branch.js.map\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * Avatar — user/agent representation. Falls back to initials when no image.\n *\n * Sizes: xs (20) | sm (24) | md (32) | lg (40) | xl (56).\n * Renders a <span> by default; use `asChild` to swap for a button/link.\n */\nexport type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport interface AvatarProps extends HTMLAttributes<HTMLSpanElement> {\n name: string;\n src?: string;\n size?: AvatarSize;\n /** Override the generated initials. */\n initials?: string;\n /** Optional status dot (online/offline/busy). */\n status?: 'online' | 'offline' | 'busy' | 'away';\n}\n\nconst SIZE_PX: Record<AvatarSize, number> = { xs: 20, sm: 24, md: 32, lg: 40, xl: 56 };\nconst SIZE_FS: Record<AvatarSize, string> = {\n xs: 'var(--fs-12)',\n sm: 'var(--fs-12)',\n md: 'var(--fs-13)',\n lg: 'var(--fs-14)',\n xl: 'var(--fs-18)',\n};\n\nconst STATUS_FG = {\n online: 'var(--success)',\n offline: 'var(--fg-subtle)',\n busy: 'var(--danger)',\n away: 'var(--warning)',\n} as const;\n\nfunction deriveInitials(name: string): string {\n const parts = name.trim().split(/\\s+/);\n if (parts.length === 0 || parts[0] === undefined) return '?';\n if (parts.length === 1) {\n const first = parts[0] ?? '';\n return first.slice(0, 2).toUpperCase();\n }\n const first = parts[0]?.[0] ?? '';\n const last = parts[parts.length - 1]?.[0] ?? '';\n return `${first}${last}`.toUpperCase();\n}\n\n// Deterministic color from name — used as fallback when no image.\nfunction hashName(name: string): number {\n let h = 0;\n for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) | 0;\n return Math.abs(h);\n}\n\nconst FALLBACK_PALETTE = [\n 'oklch(0.65 0.15 240)',\n 'oklch(0.65 0.15 30)',\n 'oklch(0.65 0.15 140)',\n 'oklch(0.65 0.15 320)',\n 'oklch(0.65 0.15 80)',\n 'oklch(0.65 0.15 200)',\n];\n\nexport const Avatar = forwardRef<HTMLSpanElement, AvatarProps>(function Avatar(props, ref) {\n const { name, src, size = 'md', initials, status, className, style, ...rest } = props;\n const px = SIZE_PX[size];\n const init = initials ?? deriveInitials(name);\n const fallbackBg = FALLBACK_PALETTE[hashName(name) % FALLBACK_PALETTE.length];\n\n return (\n <span\n ref={ref}\n className={cx('v8-avatar', `v8-avatar--${size}`, className)}\n style={{\n position: 'relative',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: px,\n height: px,\n borderRadius: 'var(--radius-pill)',\n overflow: 'hidden',\n background: fallbackBg,\n color: 'white',\n fontSize: SIZE_FS[size],\n fontWeight: 600,\n flexShrink: 0,\n userSelect: 'none',\n ...style,\n }}\n aria-label={name}\n {...rest}\n >\n {src !== undefined ? (\n <img\n src={src}\n alt=\"\"\n style={{ width: '100%', height: '100%', objectFit: 'cover' }}\n />\n ) : (\n init\n )}\n {status !== undefined && (\n <span\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n bottom: 0,\n right: 0,\n width: Math.max(6, Math.floor(px * 0.28)),\n height: Math.max(6, Math.floor(px * 0.28)),\n borderRadius: 'var(--radius-pill)',\n background: STATUS_FG[status],\n border: '2px solid var(--surface-0)',\n }}\n />\n )}\n </span>\n );\n});\n\n/**\n * AvatarStack — overlapping avatars. Use for \"assigned to N people\" lists.\n */\nexport interface AvatarStackProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n size?: AvatarSize;\n max?: number;\n}\n\nexport const AvatarStack = forwardRef<HTMLDivElement, AvatarStackProps>(function AvatarStack(\n props,\n ref,\n) {\n const { children, size = 'sm', className, style, ...rest } = props;\n return (\n <div\n ref={ref}\n className={cx('v8-avatar-stack', className)}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n ...style,\n }}\n {...rest}\n >\n <StackedChildren size={size}>{children}</StackedChildren>\n </div>\n );\n});\n\nfunction StackedChildren({ children, size }: { children: ReactNode; size: AvatarSize }) {\n const px = SIZE_PX[size];\n return (\n <>\n {Array.isArray(children)\n ? children.map((child, i) => (\n <span\n key={i}\n style={{\n marginLeft: i === 0 ? 0 : -Math.floor(px * 0.3),\n border: '2px solid var(--surface-0)',\n borderRadius: 'var(--radius-pill)',\n display: 'inline-flex',\n }}\n >\n {child}\n </span>\n ))\n : <span style={{ border: '2px solid var(--surface-0)', borderRadius: 'var(--radius-pill)' }}>{children}</span>}\n </>\n );\n}"],"names":["GitBranch","createLucideIcon","SIZE_PX","SIZE_FS","STATUS_FG","deriveInitials","name","parts","first","_a","last","_b","hashName","h","i","FALLBACK_PALETTE","Avatar","forwardRef","props","ref","src","size","initials","status","className","style","rest","px","init","fallbackBg","jsxs","cx","jsx","children","StackedChildren","Fragment","child"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as t,j as r}from"./cmdk-C3F6LD6N.js";import{u as Z,H as _,a as ee,i as x,S as p,I as s,b as I,h as M,j as U,B as l,x as re,F as k}from"./main-BRmJZcHt.js";import{V as ne}from"./ViewHeader-BsnaspKw.js";import{C as S,b as w}from"./Card-Clkvh43Q.js";import{E as ae}from"./EmptyState-ccT__JZG.js";import{E as te}from"./ErrorState-BSqf65ka.js";import{P as A}from"./pause-HitDUnk_.js";import{P as H}from"./play-blqh0msT.js";import{R as O}from"./rotate-cw-CClSVUaX.js";import{T as W}from"./trash-2-B_Y6HrfN.js";import{T as J}from"./triangle-alert-BeY8LAv6.js";import{C as se}from"./circle-check-BMbe7Kkr.js";import"./Alert-pzFISNtS.js";import"./circle-alert-QQTU4Quz.js";import"./refresh-ccw-DN_zCB1h.js";function F(a){switch(a){case"running":return H;case"paused":return A;case"done":return se;case"error":return J;case"killed":return W;default:return U}}function g(a){switch(a){case"running":return"info";case"paused":return"warning";case"done":return"success";case"error":return"danger";case"killed":return"neutral";default:return"neutral"}}function ie(a){if(!a)return"—";const c=Math.floor((Date.now()-a)/1e3);if(c<60)return`${c}s`;const h=Math.floor(c/60);return h<60?`${h}m ${c%60}s`:`${Math.floor(h/60)}h ${h%60}m`}function be(){const a=Z("/api/background"),[c,h]=t.useState([]),[i,C]=t.useState(null),[z,R]=t.useState([]),[V,$]=t.useState(!1),[E,T]=t.useState(!1),[P,o]=t.useState(null),[f,j]=t.useState(null),B=t.useRef(null);_(B,f!==null),t.useEffect(()=>{if(!f)return;const e=n=>{n.key==="Escape"&&j(null)};return document.addEventListener("keydown",e),()=>document.removeEventListener("keydown",e)},[f]),ee("background:change",t.useCallback(e=>{const n=e;a.refetch(),n.id&&n.id===i&&b(n.id)},[a,i]));const d=t.useMemo(()=>{var e;return[...c,...((e=a.data)==null?void 0:e.instances)||[]]},[c,a.data]),v=t.useMemo(()=>i?d.find(e=>e.instanceId===i)??null:null,[i,d]),b=async e=>{$(!0);try{const n=await x(`/api/background/${encodeURIComponent(e)}/output?lines=100`);R(n.lines??[])}catch{R([])}finally{$(!1)}},D=async e=>{C(e.instanceId),await b(e.instanceId)},m=()=>{a.refetch()},N=async e=>{o(null);try{await x(`/api/background/${encodeURIComponent(e)}/pause`,{method:"POST"}),m()}catch(n){o(n instanceof k?n.message:String(n))}},G=async e=>{o(null);try{await x(`/api/background/${encodeURIComponent(e)}/resume`,{method:"POST"}),m()}catch(n){o(n instanceof k?n.message:String(n))}},Y=async e=>{o(null);try{await x(`/api/background/${encodeURIComponent(e)}/retry`,{method:"POST"}),m()}catch(n){o(n instanceof k?n.message:String(n))}},q=async e=>{o(null),T(!0);try{await x(`/api/background/${encodeURIComponent(e)}`,{method:"DELETE"}),j(null),i===e&&C(null),m()}catch(n){o(n instanceof k?n.message:String(n))}finally{T(!1)}},Q=t.useMemo(()=>{const e={pending:0,running:0,paused:0,done:0,error:0,killed:0,unknown:0};for(const n of d){const u=n.status||"unknown";e[u]=(e[u]??0)+1}return e},[d]);return r.jsxs(p,{gap:5,"data-testid":"background-view",children:[r.jsx(ne,{title:"Background Jobs",description:"Live background agent sessions. Pause, resume, retry, or kill."}),P!==null&&r.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:P}),d.length>0&&r.jsx(s,{gap:3,wrap:!0,children:["running","paused","pending","done","error"].map(e=>{const n=Q[e];if(n===0)return null;const u=F(e);return r.jsxs(s,{align:"center",gap:2,style:{padding:"4px 10px",background:"var(--surface-1)",borderRadius:"var(--radius-pill)",border:"1px solid var(--border)"},children:[r.jsx(u,{size:12,"aria-hidden":!0,style:{color:`var(--${g(e)==="neutral"?"fg-muted":g(e)})`}}),r.jsx("span",{style:{fontSize:"var(--fs-12)"},children:e}),r.jsx(I,{tone:g(e),children:n})]},e)})}),a.loading&&d.length===0?r.jsx(p,{gap:2,children:[0,1,2].map(e=>r.jsx(M,{style:{height:64,borderRadius:"var(--radius-md)"}},e))}):a.error?r.jsx(te,{block:!0,title:"Failed to load background jobs",description:"Could not reach the background jobs endpoint.",error:a.error,onRetry:m}):d.length===0?r.jsx(ae,{icon:r.jsx(U,{size:28,"aria-hidden":!0}),title:"No background jobs",description:"Background agents appear here when spawned."}):r.jsxs(K,{style:{display:"grid",gridTemplateColumns:v?"1fr 380px":"1fr",gap:"var(--space-4)"},children:[r.jsx(p,{gap:2,children:d.map(e=>{var L;const n=e.status||"unknown",u=F(n),X=e.instanceId===i;return r.jsx(S,{"data-testid":`bg-instance-${e.instanceId}`,style:{cursor:"pointer",outline:X?"2px solid var(--accent)":void 0,outlineOffset:-2},onClick:()=>{D(e)},children:r.jsx(w,{children:r.jsxs(s,{align:"center",gap:3,children:[r.jsx(u,{size:16,"aria-hidden":!0,style:{color:`var(--${g(n)==="neutral"?"fg-muted":g(n)})`}}),r.jsxs(p,{gap:1,style:{flex:1,minWidth:0},children:[r.jsxs(s,{align:"center",gap:2,children:[r.jsx("strong",{style:{fontSize:"var(--fs-14)"},children:e.agent??e.instanceId.slice(0,8)}),r.jsx(I,{tone:g(n),children:n}),(L=e.tags)==null?void 0:L.map(y=>r.jsx(I,{tone:"neutral",children:y},y))]}),r.jsxs(s,{gap:3,children:[e.worktree&&r.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:e.worktree}),r.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:ie(e.startedAt??e.createdAt)}),e.pid&&r.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:["pid ",e.pid]})]})]}),r.jsxs(s,{gap:1,align:"center",onClick:y=>y.stopPropagation(),children:[n==="running"&&r.jsx(l,{variant:"secondary",size:"sm",onClick:()=>{N(e.instanceId)},"data-testid":`bg-pause-${e.instanceId}`,"aria-label":`Pause ${e.agent??e.instanceId}`,title:"Pause",children:r.jsx(A,{size:12,"aria-hidden":!0})}),n==="paused"&&r.jsx(l,{variant:"secondary",size:"sm",onClick:()=>{G(e.instanceId)},"data-testid":`bg-resume-${e.instanceId}`,"aria-label":`Resume ${e.agent??e.instanceId}`,title:"Resume",children:r.jsx(H,{size:12,"aria-hidden":!0})}),(n==="error"||n==="killed")&&r.jsx(l,{variant:"secondary",size:"sm",onClick:()=>{Y(e.instanceId)},"data-testid":`bg-retry-${e.instanceId}`,"aria-label":`Retry ${e.agent??e.instanceId}`,title:"Retry",children:r.jsx(O,{size:12,"aria-hidden":!0})}),r.jsx(l,{variant:"danger",size:"sm",onClick:()=>j(e.instanceId),"data-testid":`bg-kill-${e.instanceId}`,"aria-label":`Kill ${e.agent??e.instanceId}`,title:"Kill",children:r.jsx(W,{size:12,"aria-hidden":!0})})]})]})})},e.instanceId)})}),v&&r.jsx(S,{children:r.jsx(w,{children:r.jsxs(p,{gap:3,children:[r.jsxs(s,{align:"center",justify:"between",children:[r.jsxs(s,{align:"center",gap:2,children:[r.jsx(re,{size:12,"aria-hidden":!0}),r.jsx("span",{style:{fontSize:"var(--fs-13)",fontWeight:600},children:"Output"})]}),r.jsx(l,{variant:"ghost",size:"sm",onClick:()=>{v&&b(v.instanceId)},"aria-label":"Refresh output",children:r.jsx(O,{size:12,"aria-hidden":!0})})]}),V?r.jsx(M,{style:{height:160}}):z.length===0?r.jsx("span",{style:{color:"var(--fg-muted)",fontSize:"var(--fs-12)"},children:"No output captured yet."}):r.jsx(K,{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",background:"var(--surface-0)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",padding:"var(--space-3)",maxHeight:320,overflowY:"auto",whiteSpace:"pre-wrap",wordBreak:"break-word",lineHeight:1.6},children:z.map((e,n)=>r.jsx("div",{children:e},n))})]})})})]}),f&&r.jsx("div",{ref:B,role:"dialog","aria-modal":!0,style:{position:"fixed",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.4)",zIndex:100},"data-testid":"bg-kill-confirm",children:r.jsx(S,{style:{maxWidth:400},children:r.jsx(w,{children:r.jsxs(p,{gap:4,children:[r.jsxs(s,{align:"center",gap:2,children:[r.jsx(J,{size:16,"aria-hidden":!0,style:{color:"var(--danger)"}}),r.jsx("strong",{children:"Kill this background job?"})]}),r.jsx("span",{style:{color:"var(--fg-muted)",fontSize:"var(--fs-13)"},children:"This sends SIGTERM to the process. The instance will transition to “killed” status."}),r.jsxs(s,{gap:2,children:[r.jsx(l,{variant:"danger",onClick:()=>{q(f)},disabled:E,children:"Kill"}),r.jsx(l,{variant:"ghost",onClick:()=>j(null),disabled:E,children:"Cancel"})]})]})})})})]})}function K(a){return r.jsx("div",{style:a.style,children:a.children})}export{be as BackgroundJobsView};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BackgroundJobsView-w8OZtXyI.js","sources":["../../src/web/v8/views/BackgroundJobs/BackgroundJobsView.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { Play, Pause, RotateCw, Trash2, Terminal, Cpu, Bot, AlertTriangle, CheckCircle2, type LucideIcon } 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 { Badge } from '../../ui/data/Badge.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Textarea } from '../../ui/controls/Textarea.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { useFocusTrap } from '../../ui/feedback/useFocusTrap.js';\nimport type { WsMessage } from '../../data/types.js';\n\n/**\n * BackgroundJobsView — live background agent instances.\n *\n * Renders `/api/background` (list + status counts), shows per-instance\n * output panels, and exposes pause / resume / retry / kill controls.\n */\n\ntype BgStatus = 'pending' | 'running' | 'paused' | 'done' | 'error' | 'killed' | 'unknown';\n\ninterface BgAction {\n type: string;\n prompt?: string;\n agent?: string;\n command?: string;\n}\n\ninterface BgInstance {\n instanceId: string;\n agent?: string;\n status: BgStatus;\n worktree?: string;\n createdAt?: number;\n startedAt?: number;\n endedAt?: number;\n exitCode?: number;\n error?: string;\n tags?: string[];\n action?: BgAction;\n sessionId?: string;\n pid?: number;\n messageCount?: number;\n lastMessageAt?: number;\n lastError?: { ts: number; message: string };\n toolCalls?: unknown[];\n}\n\ninterface BackgroundResponse {\n instances: BgInstance[];\n status?: { running: number; paused: number; done: number; error: number };\n}\n\nfunction statusIcon(s: BgStatus): LucideIcon {\n switch (s) {\n case 'running': return Play;\n case 'paused': return Pause;\n case 'done': return CheckCircle2;\n case 'error': return AlertTriangle;\n case 'killed': return Trash2;\n default: return Cpu;\n }\n}\n\nfunction statusTone(s: BgStatus): 'neutral' | 'info' | 'success' | 'danger' | 'warning' {\n switch (s) {\n case 'running': return 'info';\n case 'paused': return 'warning';\n case 'done': return 'success';\n case 'error': return 'danger';\n case 'killed': return 'neutral';\n default: return 'neutral';\n }\n}\n\nfunction elapsed(ms?: number): string {\n if (!ms) return '—';\n const s = Math.floor((Date.now() - ms) / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ${s % 60}s`;\n const h = Math.floor(m / 60);\n return `${h}h ${m % 60}m`;\n}\n\nexport function BackgroundJobsView(): JSX.Element {\n const res = useFetch<BackgroundResponse>('/api/background');\n const [live, setLive] = useState<BgInstance[]>([]);\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [outputLines, setOutputLines] = useState<string[]>([]);\n const [outputLoading, setOutputLoading] = useState<boolean>(false);\n const [busy, setBusy] = useState<boolean>(false);\n const [actionError, setActionError] = useState<string | null>(null);\n const [killConfirm, setKillConfirm] = useState<string | null>(null);\n const killConfirmRef = useRef<HTMLDivElement | null>(null);\n useFocusTrap(killConfirmRef, killConfirm !== null);\n\n // Close kill confirm on Escape.\n useEffect(() => {\n if (!killConfirm) return;\n const onKey = (e: KeyboardEvent): void => { if (e.key === 'Escape') setKillConfirm(null); };\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n }, [killConfirm]);\n\n useWsMessage('background:change', useCallback((msg: WsMessage) => {\n const m = msg as { id?: string; status?: string };\n void res.refetch();\n if (m.id && m.id === selectedId) loadOutput(m.id);\n }, [res, selectedId]));\n\n const instances = useMemo<BgInstance[]>(() => [...live, ...(res.data?.instances || [])], [live, res.data]);\n\n const selected = useMemo<BgInstance | null>(() => {\n if (!selectedId) return null;\n return instances.find((i) => i.instanceId === selectedId) ?? null;\n }, [selectedId, instances]);\n\n const loadOutput = async (id: string): Promise<void> => {\n setOutputLoading(true);\n try {\n const data = await fetchJson<{ lines?: string[] }>(`/api/background/${encodeURIComponent(id)}/output?lines=100`);\n setOutputLines(data.lines ?? []);\n } catch {\n setOutputLines([]);\n } finally {\n setOutputLoading(false);\n }\n };\n\n const selectInstance = async (inst: BgInstance): Promise<void> => {\n setSelectedId(inst.instanceId);\n await loadOutput(inst.instanceId);\n };\n\n const refresh = (): void => { void res.refetch(); };\n\n const pauseInstance = async (id: string): Promise<void> => {\n setActionError(null);\n try {\n await fetchJson(`/api/background/${encodeURIComponent(id)}/pause`, { method: 'POST' });\n refresh();\n } catch (err) {\n setActionError(err instanceof FetchError ? err.message : String(err));\n }\n };\n\n const resumeInstance = async (id: string): Promise<void> => {\n setActionError(null);\n try {\n await fetchJson(`/api/background/${encodeURIComponent(id)}/resume`, { method: 'POST' });\n refresh();\n } catch (err) {\n setActionError(err instanceof FetchError ? err.message : String(err));\n }\n };\n\n const retryInstance = async (id: string): Promise<void> => {\n setActionError(null);\n try {\n await fetchJson(`/api/background/${encodeURIComponent(id)}/retry`, { method: 'POST' });\n refresh();\n } catch (err) {\n setActionError(err instanceof FetchError ? err.message : String(err));\n }\n };\n\n const killInstance = async (id: string): Promise<void> => {\n setActionError(null);\n setBusy(true);\n try {\n await fetchJson(`/api/background/${encodeURIComponent(id)}`, { method: 'DELETE' });\n setKillConfirm(null);\n if (selectedId === id) setSelectedId(null);\n refresh();\n } catch (err) {\n setActionError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n const statusCounts = useMemo(() => {\n const counts: Record<BgStatus, number> = { pending: 0, running: 0, paused: 0, done: 0, error: 0, killed: 0, unknown: 0 };\n for (const i of instances) {\n const s: BgStatus = i.status || 'unknown';\n counts[s] = (counts[s] ?? 0) + 1;\n }\n return counts;\n }, [instances]);\n\n return (\n <Stack gap={5} data-testid=\"background-view\">\n <ViewHeader\n title=\"Background Jobs\"\n description=\"Live background agent sessions. Pause, resume, retry, or kill.\"\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 {/* Status summary bar */}\n {instances.length > 0 && (\n <Inline gap={3} wrap>\n {(['running', 'paused', 'pending', 'done', 'error'] as BgStatus[]).map((s) => {\n const count = statusCounts[s];\n if (count === 0) return null;\n const Icon = statusIcon(s);\n return (\n <Inline key={s} align=\"center\" gap={2} style={{ padding: '4px 10px', background: 'var(--surface-1)', borderRadius: 'var(--radius-pill)', border: '1px solid var(--border)' }}>\n <Icon size={12} aria-hidden style={{ color: `var(--${statusTone(s) === 'neutral' ? 'fg-muted' : statusTone(s)})` }} />\n <span style={{ fontSize: 'var(--fs-12)' }}>{s}</span>\n <Badge tone={statusTone(s)}>{count}</Badge>\n </Inline>\n );\n })}\n </Inline>\n )}\n\n {res.loading && instances.length === 0 ? (\n <Stack gap={2}>\n {[0, 1, 2].map((i) => (\n <Skeleton key={i} style={{ height: 64, borderRadius: 'var(--radius-md)' }} />\n ))}\n </Stack>\n ) : res.error ? (\n <ErrorState\n block\n title=\"Failed to load background jobs\"\n description=\"Could not reach the background jobs endpoint.\"\n error={res.error}\n onRetry={refresh}\n />\n ) : instances.length === 0 ? (\n <EmptyState\n icon={<Cpu size={28} aria-hidden />}\n title=\"No background jobs\"\n description=\"Background agents appear here when spawned.\"\n />\n ) : (\n <Box style={{ display: 'grid', gridTemplateColumns: selected ? '1fr 380px' : '1fr', gap: 'var(--space-4)' }}>\n {/* Instance list */}\n <Stack gap={2}>\n {instances.map((inst) => {\n const s: BgStatus = inst.status || 'unknown';\n const Icon = statusIcon(s);\n const isSelected = inst.instanceId === selectedId;\n return (\n <Card\n key={inst.instanceId}\n data-testid={`bg-instance-${inst.instanceId}`}\n style={{\n cursor: 'pointer',\n outline: isSelected ? '2px solid var(--accent)' : undefined,\n outlineOffset: -2,\n }}\n onClick={() => { void selectInstance(inst); }}\n >\n <CardBody>\n <Inline align=\"center\" gap={3}>\n <Icon\n size={16}\n aria-hidden\n style={{ color: `var(--${statusTone(s) === 'neutral' ? 'fg-muted' : statusTone(s)})` }}\n />\n <Stack gap={1} style={{ flex: 1, minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-14)' }}>\n {inst.agent ?? inst.instanceId.slice(0, 8)}\n </strong>\n <Badge tone={statusTone(s)}>{s}</Badge>\n {inst.tags?.map((t) => (\n <Badge key={t} tone=\"neutral\">{t}</Badge>\n ))}\n </Inline>\n <Inline gap={3}>\n {inst.worktree && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {inst.worktree}\n </span>\n )}\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {elapsed(inst.startedAt ?? inst.createdAt)}\n </span>\n {inst.pid && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n pid {inst.pid}\n </span>\n )}\n </Inline>\n </Stack>\n {/* Action buttons — stop propagation so clicking doesn't navigate away */}\n <Inline\n gap={1}\n align=\"center\"\n onClick={(e) => e.stopPropagation()}\n >\n {s === 'running' && (\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => { void pauseInstance(inst.instanceId); }}\n data-testid={`bg-pause-${inst.instanceId}`}\n aria-label={`Pause ${inst.agent ?? inst.instanceId}`}\n title=\"Pause\"\n >\n <Pause size={12} aria-hidden />\n </Button>\n )}\n {s === 'paused' && (\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => { void resumeInstance(inst.instanceId); }}\n data-testid={`bg-resume-${inst.instanceId}`}\n aria-label={`Resume ${inst.agent ?? inst.instanceId}`}\n title=\"Resume\"\n >\n <Play size={12} aria-hidden />\n </Button>\n )}\n {(s === 'error' || s === 'killed') && (\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => { void retryInstance(inst.instanceId); }}\n data-testid={`bg-retry-${inst.instanceId}`}\n aria-label={`Retry ${inst.agent ?? inst.instanceId}`}\n title=\"Retry\"\n >\n <RotateCw size={12} aria-hidden />\n </Button>\n )}\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={() => setKillConfirm(inst.instanceId)}\n data-testid={`bg-kill-${inst.instanceId}`}\n aria-label={`Kill ${inst.agent ?? inst.instanceId}`}\n title=\"Kill\"\n >\n <Trash2 size={12} aria-hidden />\n </Button>\n </Inline>\n </Inline>\n </CardBody>\n </Card>\n );\n })}\n </Stack>\n\n {/* Output panel */}\n {selected && (\n <Card>\n <CardBody>\n <Stack gap={3}>\n <Inline align=\"center\" justify=\"between\">\n <Inline align=\"center\" gap={2}>\n <Terminal size={12} aria-hidden />\n <span style={{ fontSize: 'var(--fs-13)', fontWeight: 600 }}>Output</span>\n </Inline>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => { if (selected) void loadOutput(selected.instanceId); }}\n aria-label=\"Refresh output\"\n >\n <RotateCw size={12} aria-hidden />\n </Button>\n </Inline>\n\n {outputLoading ? (\n <Skeleton style={{ height: 160 }} />\n ) : outputLines.length === 0 ? (\n <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-12)' }}>No output captured yet.</span>\n ) : (\n <Box\n style={{\n fontFamily: 'var(--font-mono)',\n fontSize: 'var(--fs-12)',\n background: 'var(--surface-0)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n padding: 'var(--space-3)',\n maxHeight: 320,\n overflowY: 'auto',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n lineHeight: 1.6,\n }}\n >\n {outputLines.map((line, i) => (\n <div key={i}>{line}</div>\n ))}\n </Box>\n )}\n </Stack>\n </CardBody>\n </Card>\n )}\n </Box>\n )}\n\n {/* Kill confirmation inline dialog */}\n {killConfirm && (\n <div\n ref={killConfirmRef}\n role=\"dialog\"\n aria-modal\n style={{\n position: 'fixed',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'rgba(0,0,0,0.4)',\n zIndex: 100,\n }}\n data-testid=\"bg-kill-confirm\"\n >\n <Card style={{ maxWidth: 400 }}>\n <CardBody>\n <Stack gap={4}>\n <Inline align=\"center\" gap={2}>\n <AlertTriangle size={16} aria-hidden style={{ color: 'var(--danger)' }} />\n <strong>Kill this background job?</strong>\n </Inline>\n <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-13)' }}>\n This sends SIGTERM to the process. The instance will transition to “killed” status.\n </span>\n <Inline gap={2}>\n <Button\n variant=\"danger\"\n onClick={() => { void killInstance(killConfirm); }}\n disabled={busy}\n >\n Kill\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => setKillConfirm(null)}\n disabled={busy}\n >\n Cancel\n </Button>\n </Inline>\n </Stack>\n </CardBody>\n </Card>\n </div>\n )}\n </Stack>\n );\n}\n\nfunction Box(props: { children?: React.ReactNode; style?: React.CSSProperties }): JSX.Element {\n return <div style={props.style}>{props.children}</div>;\n}\n"],"names":["statusIcon","s","Play","Pause","CheckCircle2","AlertTriangle","Trash2","Cpu","statusTone","elapsed","ms","m","BackgroundJobsView","res","useFetch","live","setLive","useState","selectedId","setSelectedId","outputLines","setOutputLines","outputLoading","setOutputLoading","busy","setBusy","actionError","setActionError","killConfirm","setKillConfirm","killConfirmRef","useRef","useFocusTrap","useEffect","onKey","e","useWsMessage","useCallback","msg","loadOutput","instances","useMemo","_a","selected","i","id","data","fetchJson","selectInstance","inst","refresh","pauseInstance","err","FetchError","resumeInstance","retryInstance","killInstance","statusCounts","counts","jsxs","Stack","jsx","ViewHeader","Inline","count","Icon","Badge","Skeleton","ErrorState","EmptyState","Box","isSelected","Card","CardBody","t","Button","RotateCw","Terminal","line","props"],"mappings":"msBA2DA,SAASA,EAAWC,EAAyB,CAC3C,OAAQA,EAAA,CACN,IAAK,UAAW,OAAOC,EACvB,IAAK,SAAU,OAAOC,EACtB,IAAK,OAAQ,OAAOC,GACpB,IAAK,QAAS,OAAOC,EACrB,IAAK,SAAU,OAAOC,EACtB,QAAS,OAAOC,CAAA,CAEpB,CAEA,SAASC,EAAWP,EAAoE,CACtF,OAAQA,EAAA,CACN,IAAK,UAAW,MAAO,OACvB,IAAK,SAAU,MAAO,UACtB,IAAK,OAAQ,MAAO,UACpB,IAAK,QAAS,MAAO,SACrB,IAAK,SAAU,MAAO,UACtB,QAAS,MAAO,SAAA,CAEpB,CAEA,SAASQ,GAAQC,EAAqB,CACpC,GAAI,CAACA,EAAI,MAAO,IAChB,MAAMT,EAAI,KAAK,OAAO,KAAK,IAAA,EAAQS,GAAM,GAAI,EAC7C,GAAIT,EAAI,GAAI,MAAO,GAAGA,CAAC,IACvB,MAAMU,EAAI,KAAK,MAAMV,EAAI,EAAE,EAC3B,OAAIU,EAAI,GAAW,GAAGA,CAAC,KAAKV,EAAI,EAAE,IAE3B,GADG,KAAK,MAAMU,EAAI,EAAE,CAChB,KAAKA,EAAI,EAAE,GACxB,CAEO,SAASC,IAAkC,CAChD,MAAMC,EAAMC,EAA6B,iBAAiB,EACpD,CAACC,EAAMC,CAAO,EAAIC,EAAAA,SAAuB,CAAA,CAAE,EAC3C,CAACC,EAAYC,CAAa,EAAIF,EAAAA,SAAwB,IAAI,EAC1D,CAACG,EAAaC,CAAc,EAAIJ,EAAAA,SAAmB,CAAA,CAAE,EACrD,CAACK,EAAeC,CAAgB,EAAIN,EAAAA,SAAkB,EAAK,EAC3D,CAACO,EAAMC,CAAO,EAAIR,EAAAA,SAAkB,EAAK,EACzC,CAACS,EAAaC,CAAc,EAAIV,EAAAA,SAAwB,IAAI,EAC5D,CAACW,EAAaC,CAAc,EAAIZ,EAAAA,SAAwB,IAAI,EAC5Da,EAAiBC,EAAAA,OAA8B,IAAI,EACzDC,EAAaF,EAAgBF,IAAgB,IAAI,EAGjDK,EAAAA,UAAU,IAAM,CACd,GAAI,CAACL,EAAa,OAClB,MAAMM,EAASC,GAA2B,CAAMA,EAAE,MAAQ,UAAUN,EAAe,IAAI,CAAG,EAC1F,gBAAS,iBAAiB,UAAWK,CAAK,EACnC,IAAM,SAAS,oBAAoB,UAAWA,CAAK,CAC5D,EAAG,CAACN,CAAW,CAAC,EAEhBQ,GAAa,oBAAqBC,cAAaC,GAAmB,CAChE,MAAM3B,EAAI2B,EACLzB,EAAI,QAAA,EACLF,EAAE,IAAMA,EAAE,KAAOO,GAAYqB,EAAW5B,EAAE,EAAE,CAClD,EAAG,CAACE,EAAKK,CAAU,CAAC,CAAC,EAErB,MAAMsB,EAAYC,EAAAA,QAAsB,IAAA,OAAM,OAAC,GAAG1B,EAAM,KAAI2B,EAAA7B,EAAI,OAAJ,YAAA6B,EAAU,YAAa,CAAA,CAAG,GAAG,CAAC3B,EAAMF,EAAI,IAAI,CAAC,EAEnG8B,EAAWF,EAAAA,QAA2B,IACrCvB,EACEsB,EAAU,KAAMI,GAAMA,EAAE,aAAe1B,CAAU,GAAK,KADrC,KAEvB,CAACA,EAAYsB,CAAS,CAAC,EAEpBD,EAAa,MAAOM,GAA8B,CACtDtB,EAAiB,EAAI,EACrB,GAAI,CACF,MAAMuB,EAAO,MAAMC,EAAgC,mBAAmB,mBAAmBF,CAAE,CAAC,mBAAmB,EAC/GxB,EAAeyB,EAAK,OAAS,EAAE,CACjC,MAAQ,CACNzB,EAAe,CAAA,CAAE,CACnB,QAAA,CACEE,EAAiB,EAAK,CACxB,CACF,EAEMyB,EAAiB,MAAOC,GAAoC,CAChE9B,EAAc8B,EAAK,UAAU,EAC7B,MAAMV,EAAWU,EAAK,UAAU,CAClC,EAEMC,EAAU,IAAY,CAAOrC,EAAI,QAAA,CAAW,EAE5CsC,EAAgB,MAAON,GAA8B,CACzDlB,EAAe,IAAI,EACnB,GAAI,CACF,MAAMoB,EAAU,mBAAmB,mBAAmBF,CAAE,CAAC,SAAU,CAAE,OAAQ,OAAQ,EACrFK,EAAA,CACF,OAASE,EAAK,CACZzB,EAAeyB,aAAeC,EAAaD,EAAI,QAAU,OAAOA,CAAG,CAAC,CACtE,CACF,EAEME,EAAiB,MAAOT,GAA8B,CAC1DlB,EAAe,IAAI,EACnB,GAAI,CACF,MAAMoB,EAAU,mBAAmB,mBAAmBF,CAAE,CAAC,UAAW,CAAE,OAAQ,OAAQ,EACtFK,EAAA,CACF,OAASE,EAAK,CACZzB,EAAeyB,aAAeC,EAAaD,EAAI,QAAU,OAAOA,CAAG,CAAC,CACtE,CACF,EAEMG,EAAgB,MAAOV,GAA8B,CACzDlB,EAAe,IAAI,EACnB,GAAI,CACF,MAAMoB,EAAU,mBAAmB,mBAAmBF,CAAE,CAAC,SAAU,CAAE,OAAQ,OAAQ,EACrFK,EAAA,CACF,OAASE,EAAK,CACZzB,EAAeyB,aAAeC,EAAaD,EAAI,QAAU,OAAOA,CAAG,CAAC,CACtE,CACF,EAEMI,EAAe,MAAOX,GAA8B,CACxDlB,EAAe,IAAI,EACnBF,EAAQ,EAAI,EACZ,GAAI,CACF,MAAMsB,EAAU,mBAAmB,mBAAmBF,CAAE,CAAC,GAAI,CAAE,OAAQ,SAAU,EACjFhB,EAAe,IAAI,EACfX,IAAe2B,GAAI1B,EAAc,IAAI,EACzC+B,EAAA,CACF,OAASE,EAAK,CACZzB,EAAeyB,aAAeC,EAAaD,EAAI,QAAU,OAAOA,CAAG,CAAC,CACtE,QAAA,CACE3B,EAAQ,EAAK,CACf,CACF,EAEMgC,EAAehB,EAAAA,QAAQ,IAAM,CACjC,MAAMiB,EAAmC,CAAE,QAAS,EAAG,QAAS,EAAG,OAAQ,EAAG,KAAM,EAAG,MAAO,EAAG,OAAQ,EAAG,QAAS,CAAA,EACrH,UAAWd,KAAKJ,EAAW,CACzB,MAAMvC,EAAc2C,EAAE,QAAU,UAChCc,EAAOzD,CAAC,GAAKyD,EAAOzD,CAAC,GAAK,GAAK,CACjC,CACA,OAAOyD,CACT,EAAG,CAAClB,CAAS,CAAC,EAEd,OACEmB,EAAAA,KAACC,EAAA,CAAM,IAAK,EAAG,cAAY,kBACzB,SAAA,CAAAC,EAAAA,IAACC,GAAA,CACC,MAAM,kBACN,YAAY,gEAAA,CAAA,EAGbpC,IAAgB,MACfmC,MAAC,MAAA,CAAI,KAAK,QAAQ,MAAO,CAAE,QAAS,gCAAiC,WAAY,2DAA4D,OAAQ,0BAA2B,aAAc,mBAAoB,SAAU,eAAgB,MAAO,eAAA,EAChP,SAAAnC,CAAA,CACH,EAIDc,EAAU,OAAS,SACjBuB,EAAA,CAAO,IAAK,EAAG,KAAI,GAChB,SAAA,CAAC,UAAW,SAAU,UAAW,OAAQ,OAAO,EAAiB,IAAK9D,GAAM,CAC5E,MAAM+D,EAAQP,EAAaxD,CAAC,EAC5B,GAAI+D,IAAU,EAAG,OAAO,KACxB,MAAMC,EAAOjE,EAAWC,CAAC,EACzB,cACG8D,EAAA,CAAe,MAAM,SAAS,IAAK,EAAG,MAAO,CAAE,QAAS,WAAY,WAAY,mBAAoB,aAAc,qBAAsB,OAAQ,2BAC/I,SAAA,CAAAF,MAACI,GAAK,KAAM,GAAI,cAAW,GAAC,MAAO,CAAE,MAAO,SAASzD,EAAWP,CAAC,IAAM,UAAY,WAAaO,EAAWP,CAAC,CAAC,KAAO,QACnH,OAAA,CAAK,MAAO,CAAE,SAAU,cAAA,EAAmB,SAAAA,EAAE,QAC7CiE,EAAA,CAAM,KAAM1D,EAAWP,CAAC,EAAI,SAAA+D,CAAA,CAAM,CAAA,CAAA,EAHxB/D,CAIb,CAEJ,CAAC,CAAA,CACH,EAGDY,EAAI,SAAW2B,EAAU,SAAW,EACnCqB,EAAAA,IAACD,EAAA,CAAM,IAAK,EACT,SAAA,CAAC,EAAG,EAAG,CAAC,EAAE,IAAKhB,GACdiB,EAAAA,IAACM,EAAA,CAAiB,MAAO,CAAE,OAAQ,GAAI,aAAc,kBAAA,CAAmB,EAAzDvB,CAA4D,CAC5E,CAAA,CACH,EACE/B,EAAI,MACNgD,EAAAA,IAACO,GAAA,CACC,MAAK,GACL,MAAM,iCACN,YAAY,gDACZ,MAAOvD,EAAI,MACX,QAASqC,CAAA,CAAA,EAETV,EAAU,SAAW,EACvBqB,EAAAA,IAACQ,GAAA,CACC,KAAMR,EAAAA,IAACtD,EAAA,CAAI,KAAM,GAAI,cAAW,GAAC,EACjC,MAAM,qBACN,YAAY,6CAAA,CAAA,EAGdoD,EAAAA,KAACW,EAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,oBAAqB3B,EAAW,YAAc,MAAO,IAAK,kBAEvF,SAAA,CAAAkB,MAACD,GAAM,IAAK,EACT,SAAApB,EAAU,IAAKS,GAAS,OACvB,MAAMhD,EAAcgD,EAAK,QAAU,UAC7BgB,EAAOjE,EAAWC,CAAC,EACnBsE,EAAatB,EAAK,aAAe/B,EACvC,OACE2C,EAAAA,IAACW,EAAA,CAEC,cAAa,eAAevB,EAAK,UAAU,GAC3C,MAAO,CACL,OAAQ,UACR,QAASsB,EAAa,0BAA4B,OAClD,cAAe,EAAA,EAEjB,QAAS,IAAM,CAAOvB,EAAeC,CAAI,CAAG,EAE5C,eAACwB,EAAA,CACC,SAAAd,EAAAA,KAACI,GAAO,MAAM,SAAS,IAAK,EAC1B,SAAA,CAAAF,EAAAA,IAACI,EAAA,CACC,KAAM,GACN,cAAW,GACX,MAAO,CAAE,MAAO,SAASzD,EAAWP,CAAC,IAAM,UAAY,WAAaO,EAAWP,CAAC,CAAC,GAAA,CAAI,CAAA,EAEvF0D,EAAAA,KAACC,EAAA,CAAM,IAAK,EAAG,MAAO,CAAE,KAAM,EAAG,SAAU,CAAA,EACzC,SAAA,CAAAD,EAAAA,KAACI,EAAA,CAAO,MAAM,SAAS,IAAK,EAC1B,SAAA,CAAAF,EAAAA,IAAC,SAAA,CAAO,MAAO,CAAE,SAAU,cAAA,EACxB,SAAAZ,EAAK,OAASA,EAAK,WAAW,MAAM,EAAG,CAAC,EAC3C,QACCiB,EAAA,CAAM,KAAM1D,EAAWP,CAAC,EAAI,SAAAA,EAAE,GAC9ByC,EAAAO,EAAK,OAAL,YAAAP,EAAW,IAAKgC,GACfb,EAAAA,IAACK,EAAA,CAAc,KAAK,UAAW,SAAAQ,CAAA,EAAnBA,CAAqB,EAClC,EACH,EACAf,EAAAA,KAACI,EAAA,CAAO,IAAK,EACV,SAAA,CAAAd,EAAK,UACJY,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAC7C,SAAAZ,EAAK,QAAA,CACR,EAEFY,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAC7C,SAAApD,GAAQwC,EAAK,WAAaA,EAAK,SAAS,EAC3C,EACCA,EAAK,KACJU,OAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,CAAA,OAC9DV,EAAK,GAAA,CAAA,CACZ,CAAA,CAAA,CAEJ,CAAA,EACF,EAEAU,EAAAA,KAACI,EAAA,CACC,IAAK,EACL,MAAM,SACN,QAAU5B,GAAMA,EAAE,gBAAA,EAEjB,SAAA,CAAAlC,IAAM,WACL4D,EAAAA,IAACc,EAAA,CACC,QAAQ,YACR,KAAK,KACL,QAAS,IAAM,CAAOxB,EAAcF,EAAK,UAAU,CAAG,EACtD,cAAa,YAAYA,EAAK,UAAU,GACxC,aAAY,SAASA,EAAK,OAASA,EAAK,UAAU,GAClD,MAAM,QAEN,SAAAY,EAAAA,IAAC1D,EAAA,CAAM,KAAM,GAAI,cAAW,EAAA,CAAC,CAAA,CAAA,EAGhCF,IAAM,UACL4D,EAAAA,IAACc,EAAA,CACC,QAAQ,YACR,KAAK,KACL,QAAS,IAAM,CAAOrB,EAAeL,EAAK,UAAU,CAAG,EACvD,cAAa,aAAaA,EAAK,UAAU,GACzC,aAAY,UAAUA,EAAK,OAASA,EAAK,UAAU,GACnD,MAAM,SAEN,SAAAY,EAAAA,IAAC3D,EAAA,CAAK,KAAM,GAAI,cAAW,EAAA,CAAC,CAAA,CAAA,GAG9BD,IAAM,SAAWA,IAAM,WACvB4D,EAAAA,IAACc,EAAA,CACC,QAAQ,YACR,KAAK,KACL,QAAS,IAAM,CAAOpB,EAAcN,EAAK,UAAU,CAAG,EACtD,cAAa,YAAYA,EAAK,UAAU,GACxC,aAAY,SAASA,EAAK,OAASA,EAAK,UAAU,GAClD,MAAM,QAEN,SAAAY,EAAAA,IAACe,EAAA,CAAS,KAAM,GAAI,cAAW,EAAA,CAAC,CAAA,CAAA,EAGpCf,EAAAA,IAACc,EAAA,CACC,QAAQ,SACR,KAAK,KACL,QAAS,IAAM9C,EAAeoB,EAAK,UAAU,EAC7C,cAAa,WAAWA,EAAK,UAAU,GACvC,aAAY,QAAQA,EAAK,OAASA,EAAK,UAAU,GACjD,MAAM,OAEN,SAAAY,EAAAA,IAACvD,EAAA,CAAO,KAAM,GAAI,cAAW,EAAA,CAAC,CAAA,CAAA,CAChC,CAAA,CAAA,CACF,CAAA,CACF,CAAA,CACF,CAAA,EAhGK2C,EAAK,UAAA,CAmGhB,CAAC,CAAA,CACH,EAGCN,SACE6B,EAAA,CACC,SAAAX,EAAAA,IAACY,GACC,SAAAd,EAAAA,KAACC,EAAA,CAAM,IAAK,EACV,SAAA,CAAAD,EAAAA,KAACI,EAAA,CAAO,MAAM,SAAS,QAAQ,UAC7B,SAAA,CAAAJ,EAAAA,KAACI,EAAA,CAAO,MAAM,SAAS,IAAK,EAC1B,SAAA,CAAAF,EAAAA,IAACgB,GAAA,CAAS,KAAM,GAAI,cAAW,GAAC,EAChChB,EAAAA,IAAC,QAAK,MAAO,CAAE,SAAU,eAAgB,WAAY,GAAA,EAAO,SAAA,QAAA,CAAM,CAAA,EACpE,EACAA,EAAAA,IAACc,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAS,IAAM,CAAMhC,GAAeJ,EAAWI,EAAS,UAAU,CAAG,EACrE,aAAW,iBAEX,SAAAkB,EAAAA,IAACe,EAAA,CAAS,KAAM,GAAI,cAAW,EAAA,CAAC,CAAA,CAAA,CAClC,EACF,EAECtD,QACE6C,EAAA,CAAS,MAAO,CAAE,OAAQ,IAAI,CAAG,EAChC/C,EAAY,SAAW,EACzByC,MAAC,OAAA,CAAK,MAAO,CAAE,MAAO,kBAAmB,SAAU,gBAAkB,SAAA,yBAAA,CAAuB,EAE5FA,EAAAA,IAACS,EAAA,CACC,MAAO,CACL,WAAY,mBACZ,SAAU,eACV,WAAY,mBACZ,OAAQ,0BACR,aAAc,mBACd,QAAS,iBACT,UAAW,IACX,UAAW,OACX,WAAY,WACZ,UAAW,aACX,WAAY,GAAA,EAGb,SAAAlD,EAAY,IAAI,CAAC0D,EAAMlC,IACtBiB,MAAC,MAAA,CAAa,SAAAiB,CAAA,EAAJlC,CAAS,CACpB,CAAA,CAAA,CACH,CAAA,CAEJ,EACF,CAAA,CACF,CAAA,EAEJ,EAIDhB,GACCiC,EAAAA,IAAC,MAAA,CACC,IAAK/B,EACL,KAAK,SACL,aAAU,GACV,MAAO,CACL,SAAU,QACV,MAAO,EACP,QAAS,OACT,WAAY,SACZ,eAAgB,SAChB,WAAY,kBACZ,OAAQ,GAAA,EAEV,cAAY,kBAEZ,SAAA+B,EAAAA,IAACW,EAAA,CAAK,MAAO,CAAE,SAAU,GAAA,EACvB,SAAAX,EAAAA,IAACY,EAAA,CACC,SAAAd,EAAAA,KAACC,EAAA,CAAM,IAAK,EACV,SAAA,CAAAD,EAAAA,KAACI,EAAA,CAAO,MAAM,SAAS,IAAK,EAC1B,SAAA,CAAAF,EAAAA,IAACxD,EAAA,CAAc,KAAM,GAAI,cAAW,GAAC,MAAO,CAAE,MAAO,eAAA,CAAgB,CAAG,EACxEwD,EAAAA,IAAC,UAAO,SAAA,2BAAA,CAAyB,CAAA,EACnC,EACAA,EAAAA,IAAC,QAAK,MAAO,CAAE,MAAO,kBAAmB,SAAU,cAAA,EAAkB,SAAA,qFAAA,CAErE,EACAF,EAAAA,KAACI,EAAA,CAAO,IAAK,EACX,SAAA,CAAAF,EAAAA,IAACc,EAAA,CACC,QAAQ,SACR,QAAS,IAAM,CAAOnB,EAAa5B,CAAW,CAAG,EACjD,SAAUJ,EACX,SAAA,MAAA,CAAA,EAGDqC,EAAAA,IAACc,EAAA,CACC,QAAQ,QACR,QAAS,IAAM9C,EAAe,IAAI,EAClC,SAAUL,EACX,SAAA,QAAA,CAAA,CAED,CAAA,CACF,CAAA,CAAA,CACF,EACF,CAAA,CACF,CAAA,CAAA,CACF,EAEJ,CAEJ,CAEA,SAAS8C,EAAIS,EAAiF,CAC5F,aAAQ,MAAA,CAAI,MAAOA,EAAM,MAAQ,WAAM,SAAS,CAClD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as c,j as a}from"./cmdk-C3F6LD6N.js";import{u as P,a as I,S as o,I as d,B as p,h as b,e as v,b as F,G as R,i as u,F as f}from"./main-
|
|
1
|
+
import{r as c,j as a}from"./cmdk-C3F6LD6N.js";import{u as P,a as I,S as o,I as d,B as p,h as b,e as v,b as F,G as R,i as u,F as f}from"./main-BRmJZcHt.js";import{V as T}from"./ViewHeader-BsnaspKw.js";import{L}from"./ListHeader-CCD_nIHb.js";import{C as O,b as D}from"./Card-Clkvh43Q.js";import{I as V}from"./Input-DV-vdaV8.js";import{E as A}from"./EmptyState-ccT__JZG.js";import{S as N,a as G}from"./Sheet-BwMVGN-8.js";import{P as H}from"./plus-Cps-8lcG.js";import{R as M}from"./rotate-cw-CClSVUaX.js";import{T as W}from"./trash-2-B_Y6HrfN.js";function J(t){return!t||t<=0?"—":t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:t<1024*1024*1024?`${(t/(1024*1024)).toFixed(1)} MB`:`${(t/(1024*1024*1024)).toFixed(2)} GB`}function se(){const t=P("/api/backup/list"),[l,g]=c.useState([]),[S,h]=c.useState(!1),[m,x]=c.useState(""),[j,k]=c.useState(!1),[r,i]=c.useState(null),[y,n]=c.useState(null);c.useEffect(()=>{var e;(e=t.data)!=null&&e.backups&&g(t.data.backups)},[t.data]);const C=c.useCallback(e=>{e.type==="backups:change"&&t.refetch()},[t]);I("backups:change",C);const w=async()=>{i("create"),n(null);try{await u("/api/backup/create",{method:"POST",body:{label:m.trim()||null,includeProject:j}}),x(""),k(!1),h(!1),t.refetch()}catch(e){n((e instanceof f,e.message))}finally{i(null)}},z=async e=>{i(e),n(null);try{await u("/api/backup/verify",{method:"POST",body:{backupPath:e}})}catch(s){n((s instanceof f,s.message))}finally{i(null)}},$=async e=>{if(!(typeof window<"u"&&!window.confirm(`Restore from ${e}? This overwrites current settings + tasks.`))){i(e),n(null);try{await u("/api/backup/restore",{method:"POST",body:{backupPath:e,dryRun:!1}})}catch(s){n((s instanceof f,s.message))}finally{i(null)}}},B=async e=>{if(!(typeof window<"u"&&!window.confirm(`Delete backup ${e}?`))){i(e),n(null);try{await u(`/api/backup/${encodeURIComponent(e)}`,{method:"DELETE"}),g(s=>s.filter(E=>E.path!==e))}catch(s){n((s instanceof f,s.message))}finally{i(null)}}};return a.jsxs(o,{gap:5,"data-testid":"backup-view",children:[a.jsx(T,{title:"Backups",description:`${l.length} backup${l.length===1?"":"s"} in ~/.config/bizar/backups/. Create, restore, verify, or delete.`,actions:a.jsxs(d,{gap:2,align:"center",children:[y!==null&&a.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:y}),a.jsxs(p,{variant:"primary",onClick:()=>h(!0),"data-testid":"backup-create-open",children:[a.jsx(H,{size:14,"aria-hidden":!0})," New backup"]})]})}),a.jsx(L,{title:"Snapshots",count:l.length,testid:"backup-list-header"}),t.loading&&l.length===0?a.jsxs(o,{gap:2,children:[a.jsx(b,{style:{height:80}}),a.jsx(b,{style:{height:80}})]}):l.length===0?a.jsx(A,{icon:a.jsx(v,{size:32,"aria-hidden":!0}),title:"No backups yet",description:"Create your first snapshot before risky changes."}):a.jsx(o,{gap:2,children:l.map(e=>a.jsx(O,{variant:"default",children:a.jsx(D,{children:a.jsxs(d,{align:"center",justify:"between",gap:3,children:[a.jsxs(o,{gap:1,style:{flex:1,minWidth:0},children:[a.jsxs(d,{align:"center",gap:2,children:[a.jsx(v,{size:14,"aria-hidden":!0}),a.jsx("strong",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-13)"},children:e.label||e.path.split("/").pop()}),e.includesProject&&a.jsx(F,{tone:"info",children:"project"})]}),a.jsxs(d,{align:"center",gap:3,style:{color:"var(--fg-muted)",fontSize:"var(--fs-12)"},children:[a.jsx("span",{children:J(e.size)}),a.jsx("span",{children:e.createdAt?new Date(e.createdAt).toLocaleString():""})]})]}),a.jsxs(d,{gap:1,children:[a.jsxs(p,{variant:"ghost",onClick:()=>void z(e.path),disabled:r===e.path,"data-testid":`backup-verify-${e.path}`,children:[a.jsx(R,{size:12,"aria-hidden":!0})," Verify"]}),a.jsxs(p,{variant:"ghost",onClick:()=>void $(e.path),disabled:r===e.path,"data-testid":`backup-restore-${e.path}`,children:[a.jsx(M,{size:12,"aria-hidden":!0})," Restore"]}),a.jsxs(p,{variant:"ghost",onClick:()=>void B(e.path),disabled:r===e.path,"data-testid":`backup-delete-${e.path}`,children:[a.jsx(W,{size:12,"aria-hidden":!0})," Delete"]})]})]})})},e.path))}),a.jsx(N,{open:S,onOpenChange:e=>{e||h(!1)},children:a.jsx(G,{side:"right",title:"New backup",children:a.jsxs(o,{gap:4,style:{padding:"var(--space-4)"},children:[a.jsxs(o,{gap:2,children:[a.jsx("label",{htmlFor:"backup-label",style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Label (optional)"}),a.jsx(V,{id:"backup-label",value:m,onChange:e=>x(e.target.value),placeholder:"e.g. pre-v9.2.0",disabled:r==="create","data-testid":"backup-create-label"})]}),a.jsxs("label",{style:{display:"flex",alignItems:"center",gap:"var(--space-2)"},children:[a.jsx("input",{type:"checkbox",checked:j,onChange:e=>k(e.target.checked),disabled:r==="create","data-testid":"backup-create-include-project"}),a.jsx("span",{style:{fontSize:"var(--fs-13)"},children:"Include project files (larger snapshot)"})]}),a.jsxs(d,{gap:2,children:[a.jsx(p,{variant:"primary",onClick:()=>void w(),disabled:r==="create","data-testid":"backup-create-submit",children:r==="create"?"Creating…":"Create backup"}),a.jsx(p,{variant:"ghost",onClick:()=>h(!1),disabled:r==="create",children:"Cancel"})]})]})})})]})}export{se as BackupView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackupView-B875KQa4.js","sources":["../../src/web/v8/views/Backup/BackupView.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport { Archive, Plus, Trash2, RotateCw, ShieldCheck, FileText } 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 { Badge } from '../../ui/data/Badge.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport type { WsMessage } from '../../data/types.js';\n\n/**\n * BackupView — Sprint S35. Snapshot creation, restore, verify, delete.\n */\n\ninterface BackupEntry {\n path: string;\n label?: string;\n size?: number;\n createdAt?: string;\n includesProject?: boolean;\n}\n\nfunction fmtSize(bytes: number | undefined): string {\n if (!bytes || bytes <= 0) return '—';\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\nexport function BackupView(): JSX.Element {\n const list = useFetch<{ ok: boolean; backups: BackupEntry[] }>('/api/backup/list');\n const [items, setItems] = useState<BackupEntry[]>([]);\n const [createOpen, setCreateOpen] = useState(false);\n const [label, setLabel] = useState('');\n const [includeProject, setIncludeProject] = useState(false);\n const [busy, setBusy] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (list.data?.backups) setItems(list.data.backups);\n }, [list.data]);\n\n const onChange = useCallback((msg: WsMessage) => {\n if (msg.type === 'backups:change') void list.refetch();\n }, [list]);\n useWsMessage('backups:change', onChange);\n\n const create = async (): Promise<void> => {\n setBusy('create');\n setError(null);\n try {\n await fetchJson('/api/backup/create', { method: 'POST', body: { label: label.trim() || null, includeProject } });\n setLabel('');\n setIncludeProject(false);\n setCreateOpen(false);\n void list.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const verify = async (path: string): Promise<void> => {\n setBusy(path);\n setError(null);\n try {\n await fetchJson('/api/backup/verify', { method: 'POST', body: { backupPath: path } });\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const restore = async (path: string): Promise<void> => {\n if (typeof window !== 'undefined' && !window.confirm(`Restore from ${path}? This overwrites current settings + tasks.`)) return;\n setBusy(path);\n setError(null);\n try {\n await fetchJson('/api/backup/restore', { method: 'POST', body: { backupPath: path, dryRun: false } });\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const remove = async (path: string): Promise<void> => {\n if (typeof window !== 'undefined' && !window.confirm(`Delete backup ${path}?`)) return;\n setBusy(path);\n setError(null);\n try {\n await fetchJson(`/api/backup/${encodeURIComponent(path)}`, { method: 'DELETE' });\n setItems((prev) => prev.filter((b) => b.path !== path));\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n return (\n <Stack gap={5} data-testid=\"backup-view\">\n <ViewHeader\n title=\"Backups\"\n description={`${items.length} backup${items.length === 1 ? '' : 's'} in ~/.config/bizar/backups/. Create, restore, verify, or delete.`}\n actions={\n <Inline gap={2} align=\"center\">\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Button variant=\"primary\" onClick={() => setCreateOpen(true)} data-testid=\"backup-create-open\">\n <Plus size={14} aria-hidden /> New backup\n </Button>\n </Inline>\n }\n />\n <ListHeader title=\"Snapshots\" count={items.length} testid=\"backup-list-header\" />\n {list.loading && items.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 80 }} />\n <Skeleton style={{ height: 80 }} />\n </Stack>\n ) : items.length === 0 ? (\n <EmptyState\n icon={<Archive size={32} aria-hidden />}\n title=\"No backups yet\"\n description=\"Create your first snapshot before risky changes.\"\n />\n ) : (\n <Stack gap={2}>\n {items.map((b) => (\n <Card key={b.path} variant=\"default\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={3}>\n <Stack gap={1} style={{ flex: 1, minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <Archive size={14} aria-hidden />\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-13)' }}>{b.label || b.path.split('/').pop()}</strong>\n {b.includesProject && <Badge tone=\"info\">project</Badge>}\n </Inline>\n <Inline align=\"center\" gap={3} style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-12)' }}>\n <span>{fmtSize(b.size)}</span>\n <span>{b.createdAt ? new Date(b.createdAt).toLocaleString() : ''}</span>\n </Inline>\n </Stack>\n <Inline gap={1}>\n <Button variant=\"ghost\" onClick={() => void verify(b.path)} disabled={busy === b.path} data-testid={`backup-verify-${b.path}`}>\n <ShieldCheck size={12} aria-hidden /> Verify\n </Button>\n <Button variant=\"ghost\" onClick={() => void restore(b.path)} disabled={busy === b.path} data-testid={`backup-restore-${b.path}`}>\n <RotateCw size={12} aria-hidden /> Restore\n </Button>\n <Button variant=\"ghost\" onClick={() => void remove(b.path)} disabled={busy === b.path} data-testid={`backup-delete-${b.path}`}>\n <Trash2 size={12} aria-hidden /> Delete\n </Button>\n </Inline>\n </Inline>\n </CardBody>\n </Card>\n ))}\n </Stack>\n )}\n\n <Sheet open={createOpen} onOpenChange={(o) => { if (!o) setCreateOpen(false); }}>\n <SheetContent side=\"right\" title=\"New backup\">\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"backup-label\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Label (optional)</label>\n <Input\n id=\"backup-label\"\n value={label}\n onChange={(e) => setLabel(e.target.value)}\n placeholder=\"e.g. pre-v9.2.0\"\n disabled={busy === 'create'}\n data-testid=\"backup-create-label\"\n />\n </Stack>\n <label style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>\n <input type=\"checkbox\" checked={includeProject} onChange={(e) => setIncludeProject(e.target.checked)} disabled={busy === 'create'} data-testid=\"backup-create-include-project\" />\n <span style={{ fontSize: 'var(--fs-13)' }}>Include project files (larger snapshot)</span>\n </label>\n <Inline gap={2}>\n <Button variant=\"primary\" onClick={() => void create()} disabled={busy === 'create'} data-testid=\"backup-create-submit\">\n {busy === 'create' ? 'Creating…' : 'Create backup'}\n </Button>\n <Button variant=\"ghost\" onClick={() => setCreateOpen(false)} disabled={busy === 'create'}>\n Cancel\n </Button>\n </Inline>\n </Stack>\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}"],"names":["fmtSize","bytes","BackupView","list","useFetch","items","setItems","useState","createOpen","setCreateOpen","label","setLabel","includeProject","setIncludeProject","busy","setBusy","error","setError","useEffect","_a","onChange","useCallback","msg","useWsMessage","create","fetchJson","err","FetchError","verify","path","restore","remove","prev","b","jsxs","Stack","jsx","ViewHeader","Inline","Button","Plus","ListHeader","Skeleton","EmptyState","Archive","Card","CardBody","Badge","ShieldCheck","RotateCw","Trash2","Sheet","o","SheetContent","Input"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BackupView-u_O3j0TG.js","sources":["../../src/web/v8/views/Backup/BackupView.tsx"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport { Archive, Plus, Trash2, RotateCw, ShieldCheck, FileText } 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 { Badge } from '../../ui/data/Badge.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport type { WsMessage } from '../../data/types.js';\n\n/**\n * BackupView — Sprint S35. Snapshot creation, restore, verify, delete.\n */\n\ninterface BackupEntry {\n path: string;\n label?: string;\n size?: number;\n createdAt?: string;\n includesProject?: boolean;\n}\n\nfunction fmtSize(bytes: number | undefined): string {\n if (!bytes || bytes <= 0) return '—';\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;\n}\n\nexport function BackupView(): JSX.Element {\n const list = useFetch<{ ok: boolean; backups: BackupEntry[] }>('/api/backup/list');\n const [items, setItems] = useState<BackupEntry[]>([]);\n const [createOpen, setCreateOpen] = useState(false);\n const [label, setLabel] = useState('');\n const [includeProject, setIncludeProject] = useState(false);\n const [busy, setBusy] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (list.data?.backups) setItems(list.data.backups);\n }, [list.data]);\n\n const onChange = useCallback((msg: WsMessage) => {\n if (msg.type === 'backups:change') void list.refetch();\n }, [list]);\n useWsMessage('backups:change', onChange);\n\n const create = async (): Promise<void> => {\n setBusy('create');\n setError(null);\n try {\n await fetchJson('/api/backup/create', { method: 'POST', body: { label: label.trim() || null, includeProject } });\n setLabel('');\n setIncludeProject(false);\n setCreateOpen(false);\n void list.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const verify = async (path: string): Promise<void> => {\n setBusy(path);\n setError(null);\n try {\n await fetchJson('/api/backup/verify', { method: 'POST', body: { backupPath: path } });\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const restore = async (path: string): Promise<void> => {\n if (typeof window !== 'undefined' && !window.confirm(`Restore from ${path}? This overwrites current settings + tasks.`)) return;\n setBusy(path);\n setError(null);\n try {\n await fetchJson('/api/backup/restore', { method: 'POST', body: { backupPath: path, dryRun: false } });\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const remove = async (path: string): Promise<void> => {\n if (typeof window !== 'undefined' && !window.confirm(`Delete backup ${path}?`)) return;\n setBusy(path);\n setError(null);\n try {\n await fetchJson(`/api/backup/${encodeURIComponent(path)}`, { method: 'DELETE' });\n setItems((prev) => prev.filter((b) => b.path !== path));\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n return (\n <Stack gap={5} data-testid=\"backup-view\">\n <ViewHeader\n title=\"Backups\"\n description={`${items.length} backup${items.length === 1 ? '' : 's'} in ~/.config/bizar/backups/. Create, restore, verify, or delete.`}\n actions={\n <Inline gap={2} align=\"center\">\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Button variant=\"primary\" onClick={() => setCreateOpen(true)} data-testid=\"backup-create-open\">\n <Plus size={14} aria-hidden /> New backup\n </Button>\n </Inline>\n }\n />\n <ListHeader title=\"Snapshots\" count={items.length} testid=\"backup-list-header\" />\n {list.loading && items.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 80 }} />\n <Skeleton style={{ height: 80 }} />\n </Stack>\n ) : items.length === 0 ? (\n <EmptyState\n icon={<Archive size={32} aria-hidden />}\n title=\"No backups yet\"\n description=\"Create your first snapshot before risky changes.\"\n />\n ) : (\n <Stack gap={2}>\n {items.map((b) => (\n <Card key={b.path} variant=\"default\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={3}>\n <Stack gap={1} style={{ flex: 1, minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <Archive size={14} aria-hidden />\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-13)' }}>{b.label || b.path.split('/').pop()}</strong>\n {b.includesProject && <Badge tone=\"info\">project</Badge>}\n </Inline>\n <Inline align=\"center\" gap={3} style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-12)' }}>\n <span>{fmtSize(b.size)}</span>\n <span>{b.createdAt ? new Date(b.createdAt).toLocaleString() : ''}</span>\n </Inline>\n </Stack>\n <Inline gap={1}>\n <Button variant=\"ghost\" onClick={() => void verify(b.path)} disabled={busy === b.path} data-testid={`backup-verify-${b.path}`}>\n <ShieldCheck size={12} aria-hidden /> Verify\n </Button>\n <Button variant=\"ghost\" onClick={() => void restore(b.path)} disabled={busy === b.path} data-testid={`backup-restore-${b.path}`}>\n <RotateCw size={12} aria-hidden /> Restore\n </Button>\n <Button variant=\"ghost\" onClick={() => void remove(b.path)} disabled={busy === b.path} data-testid={`backup-delete-${b.path}`}>\n <Trash2 size={12} aria-hidden /> Delete\n </Button>\n </Inline>\n </Inline>\n </CardBody>\n </Card>\n ))}\n </Stack>\n )}\n\n <Sheet open={createOpen} onOpenChange={(o) => { if (!o) setCreateOpen(false); }}>\n <SheetContent side=\"right\" title=\"New backup\">\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"backup-label\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Label (optional)</label>\n <Input\n id=\"backup-label\"\n value={label}\n onChange={(e) => setLabel(e.target.value)}\n placeholder=\"e.g. pre-v9.2.0\"\n disabled={busy === 'create'}\n data-testid=\"backup-create-label\"\n />\n </Stack>\n <label style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>\n <input type=\"checkbox\" checked={includeProject} onChange={(e) => setIncludeProject(e.target.checked)} disabled={busy === 'create'} data-testid=\"backup-create-include-project\" />\n <span style={{ fontSize: 'var(--fs-13)' }}>Include project files (larger snapshot)</span>\n </label>\n <Inline gap={2}>\n <Button variant=\"primary\" onClick={() => void create()} disabled={busy === 'create'} data-testid=\"backup-create-submit\">\n {busy === 'create' ? 'Creating…' : 'Create backup'}\n </Button>\n <Button variant=\"ghost\" onClick={() => setCreateOpen(false)} disabled={busy === 'create'}>\n Cancel\n </Button>\n </Inline>\n </Stack>\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}"],"names":["fmtSize","bytes","BackupView","list","useFetch","items","setItems","useState","createOpen","setCreateOpen","label","setLabel","includeProject","setIncludeProject","busy","setBusy","error","setError","useEffect","_a","onChange","useCallback","msg","useWsMessage","create","fetchJson","err","FetchError","verify","path","restore","remove","prev","b","jsxs","Stack","jsx","ViewHeader","Inline","Button","Plus","ListHeader","Skeleton","EmptyState","Archive","Card","CardBody","Badge","ShieldCheck","RotateCw","Trash2","Sheet","o","SheetContent","Input"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as c,j as a}from"./cmdk-C3F6LD6N.js";import{g as l}from"./main-
|
|
1
|
+
import{r as c,j as a}from"./cmdk-C3F6LD6N.js";import{g as l}from"./main-BRmJZcHt.js";const x=c.forwardRef(function(s,n){const{tone:r="info",children:o,action:e,className:t,...i}=s;return a.jsxs("div",{ref:n,role:r==="danger"?"alert":"status",className:l("v8-banner",`v8-banner--${r}`,t),style:{display:"flex",alignItems:"center",gap:"var(--space-3)",padding:"var(--space-3) var(--space-4)",background:`color-mix(in oklch, var(--${r}) 8%, var(--surface-1))`,borderBottom:"1px solid var(--border)",fontSize:"var(--fs-13)",color:"var(--fg)"},...i,children:[a.jsx("div",{style:{flex:1,minWidth:0},children:o}),e!==void 0&&a.jsx("div",{style:{flexShrink:0},children:e})]})});export{x as B};
|