@polderlabs/bizar 10.4.3 → 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-DC0JiK49.js → ActivityFeed-Bw4Cai7r.js} +1 -1
- package/bizar-dash/dist/assets/{ActivityFeed-DC0JiK49.js.map → ActivityFeed-Bw4Cai7r.js.map} +1 -1
- package/bizar-dash/dist/assets/{ActivityView-ubEDAWMY.js → ActivityView-BC0QQ_j9.js} +1 -1
- package/bizar-dash/dist/assets/{ActivityView-ubEDAWMY.js.map → ActivityView-BC0QQ_j9.js.map} +1 -1
- package/bizar-dash/dist/assets/AdminView-CLTNKFL4.js +11 -0
- package/bizar-dash/dist/assets/AdminView-CLTNKFL4.js.map +1 -0
- package/bizar-dash/dist/assets/{AgentActivity-BLcqqkt2.js → AgentActivity-DBWDByjk.js} +1 -1
- package/bizar-dash/dist/assets/{AgentActivity-BLcqqkt2.js.map → AgentActivity-DBWDByjk.js.map} +1 -1
- package/bizar-dash/dist/assets/{AgentsView-CIQkZH8_.js → AgentsView-DD6bCIbA.js} +4 -4
- package/bizar-dash/dist/assets/AgentsView-DD6bCIbA.js.map +1 -0
- package/bizar-dash/dist/assets/{Alert-MwVEymjy.js → Alert-pzFISNtS.js} +1 -1
- package/bizar-dash/dist/assets/{Alert-MwVEymjy.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-LaQuGo4u.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-CRW81ewE.js +6 -0
- package/bizar-dash/dist/assets/Avatar-CRW81ewE.js.map +1 -0
- 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-Cjf23ZWc.js → BackupView-u_O3j0TG.js} +1 -1
- package/bizar-dash/dist/assets/{BackupView-Cjf23ZWc.js.map → BackupView-u_O3j0TG.js.map} +1 -1
- package/bizar-dash/dist/assets/Banner-Du-3l05O.js +1 -0
- package/bizar-dash/dist/assets/Banner-Du-3l05O.js.map +1 -0
- package/bizar-dash/dist/assets/{Card-BmXiT4c6.js → Card-Clkvh43Q.js} +1 -1
- package/bizar-dash/dist/assets/{Card-BmXiT4c6.js.map → Card-Clkvh43Q.js.map} +1 -1
- package/bizar-dash/dist/assets/{ChatView-DXKFwvgp.js → ChatView-BTjb3mIh.js} +3 -3
- package/bizar-dash/dist/assets/{ChatView-DXKFwvgp.js.map → ChatView-BTjb3mIh.js.map} +1 -1
- package/bizar-dash/dist/assets/{Chip-Dei66BLx.js → Chip-B7ovcm01.js} +1 -1
- package/bizar-dash/dist/assets/{Chip-Dei66BLx.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-Cb6XgYZI.js.map +1 -0
- package/bizar-dash/dist/assets/{ConfigView-BMBgifw5.js → ConfigView-DfTJk1uL.js} +1 -1
- package/bizar-dash/dist/assets/{ConfigView-BMBgifw5.js.map → ConfigView-DfTJk1uL.js.map} +1 -1
- package/bizar-dash/dist/assets/{DiagnosticsView-C0sdqhEl.js → DiagnosticsView-D5Wy9xlJ.js} +1 -1
- package/bizar-dash/dist/assets/{DiagnosticsView-C0sdqhEl.js.map → DiagnosticsView-D5Wy9xlJ.js.map} +1 -1
- package/bizar-dash/dist/assets/DialogsView-HVyfrXpq.js +6 -0
- package/bizar-dash/dist/assets/DialogsView-HVyfrXpq.js.map +1 -0
- package/bizar-dash/dist/assets/{DoctorView-CiFwRMW0.js → DoctorView-Dm94WI2z.js} +2 -2
- package/bizar-dash/dist/assets/{DoctorView-CiFwRMW0.js.map → DoctorView-Dm94WI2z.js.map} +1 -1
- package/bizar-dash/dist/assets/{EmptyState-CdDQmfEL.js → EmptyState-ccT__JZG.js} +1 -1
- package/bizar-dash/dist/assets/{EmptyState-CdDQmfEL.js.map → EmptyState-ccT__JZG.js.map} +1 -1
- package/bizar-dash/dist/assets/{EnvVarsView-CNO03NDJ.js → EnvVarsView-BhcIuJ6V.js} +3 -3
- package/bizar-dash/dist/assets/{EnvVarsView-CNO03NDJ.js.map → EnvVarsView-BhcIuJ6V.js.map} +1 -1
- package/bizar-dash/dist/assets/{ErrorState-BRvj8qZZ.js → ErrorState-BSqf65ka.js} +1 -1
- package/bizar-dash/dist/assets/{ErrorState-BRvj8qZZ.js.map → ErrorState-BSqf65ka.js.map} +1 -1
- package/bizar-dash/dist/assets/EvalView-2cbWVBUA.js +1 -0
- package/bizar-dash/dist/assets/{EvalView-lgUhlGJh.js.map → EvalView-2cbWVBUA.js.map} +1 -1
- package/bizar-dash/dist/assets/{GoalsView-DmkCCs9i.js → GoalsView-C3QG5p7T.js} +1 -1
- package/bizar-dash/dist/assets/{GoalsView-DmkCCs9i.js.map → GoalsView-C3QG5p7T.js.map} +1 -1
- package/bizar-dash/dist/assets/{Grid-BThCPJaV.js → Grid-Bojq8Sg7.js} +1 -1
- package/bizar-dash/dist/assets/{Grid-BThCPJaV.js.map → Grid-Bojq8Sg7.js.map} +1 -1
- package/bizar-dash/dist/assets/{HistoryView-Cn2cPiHZ.js → HistoryView-Bum2TMMw.js} +1 -1
- package/bizar-dash/dist/assets/{HistoryView-Cn2cPiHZ.js.map → HistoryView-Bum2TMMw.js.map} +1 -1
- package/bizar-dash/dist/assets/{Input-cAQOvR8U.js → Input-DV-vdaV8.js} +1 -1
- package/bizar-dash/dist/assets/{Input-cAQOvR8U.js.map → Input-DV-vdaV8.js.map} +1 -1
- package/bizar-dash/dist/assets/LibrariesView-DH2E2uNb.js +6 -0
- package/bizar-dash/dist/assets/{LibrariesView-Ca_PRjUm.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-BLAeshe0.js → ListHeader-CCD_nIHb.js} +1 -1
- package/bizar-dash/dist/assets/{ListHeader-BLAeshe0.js.map → ListHeader-CCD_nIHb.js.map} +1 -1
- package/bizar-dash/dist/assets/{MemoryView-wo2Pu7xQ.js → MemoryView-Cr-obIQY.js} +1 -1
- package/bizar-dash/dist/assets/{MemoryView-wo2Pu7xQ.js.map → MemoryView-Cr-obIQY.js.map} +1 -1
- package/bizar-dash/dist/assets/MiscView-CDUQpYuV.js +1 -0
- package/bizar-dash/dist/assets/MiscView-CDUQpYuV.js.map +1 -0
- package/bizar-dash/dist/assets/{ModsView-CV_RxdzJ.js → ModsView-B6OR-a4B.js} +2 -2
- package/bizar-dash/dist/assets/{ModsView-CV_RxdzJ.js.map → ModsView-B6OR-a4B.js.map} +1 -1
- package/bizar-dash/dist/assets/NotificationsView-CIqtY6D0.js +6 -0
- package/bizar-dash/dist/assets/NotificationsView-CIqtY6D0.js.map +1 -0
- package/bizar-dash/dist/assets/ObsidianView-Nahah8QC.js +1 -0
- package/bizar-dash/dist/assets/{ObsidianView-C-AvHfpT.js.map → ObsidianView-Nahah8QC.js.map} +1 -1
- package/bizar-dash/dist/assets/OverviewView-B6L_wa4M.js +1 -0
- package/bizar-dash/dist/assets/OverviewView-B6L_wa4M.js.map +1 -0
- package/bizar-dash/dist/assets/{ProgressBar-ya2PCj8L.js → ProgressBar-KC4VXsl_.js} +1 -1
- package/bizar-dash/dist/assets/{ProgressBar-ya2PCj8L.js.map → ProgressBar-KC4VXsl_.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProjectsView-N9zqFZ_O.js → ProjectsView-DgxWiqHb.js} +1 -1
- package/bizar-dash/dist/assets/{ProjectsView-N9zqFZ_O.js.map → ProjectsView-DgxWiqHb.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProvidersView-BcL8jjwK.js → ProvidersView-BOqN9omv.js} +2 -2
- package/bizar-dash/dist/assets/{ProvidersView-BcL8jjwK.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-D5AuVxxV.js → Select-Bf_P0S6H.js} +1 -1
- package/bizar-dash/dist/assets/{Select-D5AuVxxV.js.map → Select-Bf_P0S6H.js.map} +1 -1
- package/bizar-dash/dist/assets/{SettingsRow-BBALf9dA.js → SettingsRow-CJb-F94Y.js} +1 -1
- package/bizar-dash/dist/assets/{SettingsRow-BBALf9dA.js.map → SettingsRow-CJb-F94Y.js.map} +1 -1
- package/bizar-dash/dist/assets/{SettingsView-UD403neY.js → SettingsView-BvOGcgMS.js} +2 -2
- package/bizar-dash/dist/assets/SettingsView-BvOGcgMS.js.map +1 -0
- package/bizar-dash/dist/assets/{Sheet-CxXf6gvC.js → Sheet-BwMVGN-8.js} +1 -1
- package/bizar-dash/dist/assets/{Sheet-CxXf6gvC.js.map → Sheet-BwMVGN-8.js.map} +1 -1
- package/bizar-dash/dist/assets/{Slider-hvaVD_SW.js → Slider-AjjzqI-5.js} +1 -1
- package/bizar-dash/dist/assets/{Slider-hvaVD_SW.js.map → Slider-AjjzqI-5.js.map} +1 -1
- package/bizar-dash/dist/assets/{Sparkline-DqmQzdJH.js → Sparkline-Z4y0YUZS.js} +1 -1
- package/bizar-dash/dist/assets/{Sparkline-DqmQzdJH.js.map → Sparkline-Z4y0YUZS.js.map} +1 -1
- package/bizar-dash/dist/assets/{Switch-C-_zcNdl.js → Switch-B79a2t-G.js} +1 -1
- package/bizar-dash/dist/assets/{Switch-C-_zcNdl.js.map → Switch-B79a2t-G.js.map} +1 -1
- package/bizar-dash/dist/assets/{TasksView-DseftDlx.js → TasksView-G-s_pwwr.js} +2 -2
- package/bizar-dash/dist/assets/{TasksView-DseftDlx.js.map → TasksView-G-s_pwwr.js.map} +1 -1
- package/bizar-dash/dist/assets/{Textarea-CcQGSgSH.js → Textarea-BfXGMXQ7.js} +1 -1
- package/bizar-dash/dist/assets/{Textarea-CcQGSgSH.js.map → Textarea-BfXGMXQ7.js.map} +1 -1
- package/bizar-dash/dist/assets/UpdateView-BKx3u9X8.js +1 -0
- package/bizar-dash/dist/assets/UpdateView-BKx3u9X8.js.map +1 -0
- package/bizar-dash/dist/assets/{UsageView-P5_pQ68d.js → UsageView-M01G6bZQ.js} +1 -1
- package/bizar-dash/dist/assets/{UsageView-P5_pQ68d.js.map → UsageView-M01G6bZQ.js.map} +1 -1
- package/bizar-dash/dist/assets/{ViewHeader-BaCWNuVX.js → ViewHeader-BsnaspKw.js} +1 -1
- package/bizar-dash/dist/assets/{ViewHeader-BaCWNuVX.js.map → ViewHeader-BsnaspKw.js.map} +1 -1
- package/bizar-dash/dist/assets/VoiceView-rWE8vziD.js +1 -0
- package/bizar-dash/dist/assets/VoiceView-rWE8vziD.js.map +1 -0
- package/bizar-dash/dist/assets/{brain-D6tAeUDE.js → brain-D7k5s8vH.js} +1 -1
- package/bizar-dash/dist/assets/{brain-D6tAeUDE.js.map → brain-D7k5s8vH.js.map} +1 -1
- package/bizar-dash/dist/assets/{calendar-BrMJf3vl.js → calendar-CAZoDd-l.js} +1 -1
- package/bizar-dash/dist/assets/{calendar-BrMJf3vl.js.map → calendar-CAZoDd-l.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-fPTATiOs.js → circle-D99cZJBr.js} +1 -1
- package/bizar-dash/dist/assets/{circle-fPTATiOs.js.map → circle-D99cZJBr.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-alert-D7jn06kH.js → circle-alert-QQTU4Quz.js} +1 -1
- package/bizar-dash/dist/assets/{circle-alert-D7jn06kH.js.map → circle-alert-QQTU4Quz.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-check-DHs37Sot.js → circle-check-BMbe7Kkr.js} +1 -1
- package/bizar-dash/dist/assets/{circle-check-DHs37Sot.js.map → circle-check-BMbe7Kkr.js.map} +1 -1
- package/bizar-dash/dist/assets/{clock-E-G5aGua.js → clock-OtT5mvF3.js} +1 -1
- package/bizar-dash/dist/assets/{clock-E-G5aGua.js.map → clock-OtT5mvF3.js.map} +1 -1
- package/bizar-dash/dist/assets/{download-DBkNb6oI.js → download-B-mPX5P_.js} +1 -1
- package/bizar-dash/dist/assets/{download-DBkNb6oI.js.map → download-B-mPX5P_.js.map} +1 -1
- package/bizar-dash/dist/assets/{external-link-C4pHGbz2.js → external-link-DPDQM1YO.js} +1 -1
- package/bizar-dash/dist/assets/{external-link-C4pHGbz2.js.map → external-link-DPDQM1YO.js.map} +1 -1
- package/bizar-dash/dist/assets/{file-text-CEhDgLq2.js → file-text-BsCrv5aP.js} +1 -1
- package/bizar-dash/dist/assets/{file-text-CEhDgLq2.js.map → file-text-BsCrv5aP.js.map} +1 -1
- package/bizar-dash/dist/assets/{filter-CEYjeWFX.js → filter-Do63x17E.js} +1 -1
- package/bizar-dash/dist/assets/{filter-CEYjeWFX.js.map → filter-Do63x17E.js.map} +1 -1
- package/bizar-dash/dist/assets/{git-pull-request-Bo_wBZZw.js → git-pull-request-CpRAmERC.js} +1 -1
- package/bizar-dash/dist/assets/{git-pull-request-Bo_wBZZw.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-BsfwrUA-.js → network-DJnHwHX3.js} +1 -1
- package/bizar-dash/dist/assets/{network-BsfwrUA-.js.map → network-DJnHwHX3.js.map} +1 -1
- package/bizar-dash/dist/assets/{pause-C8PN1_yO.js → pause-HitDUnk_.js} +1 -1
- package/bizar-dash/dist/assets/{pause-C8PN1_yO.js.map → pause-HitDUnk_.js.map} +1 -1
- package/bizar-dash/dist/assets/{pencil---XuvKlz.js → pencil-Dkks7eIC.js} +1 -1
- package/bizar-dash/dist/assets/{pencil---XuvKlz.js.map → pencil-Dkks7eIC.js.map} +1 -1
- package/bizar-dash/dist/assets/{play-fMLPTihK.js → play-blqh0msT.js} +2 -2
- package/bizar-dash/dist/assets/{play-fMLPTihK.js.map → play-blqh0msT.js.map} +1 -1
- package/bizar-dash/dist/assets/{plug-CG8al2Kq.js → plug-DVvSSe40.js} +1 -1
- package/bizar-dash/dist/assets/{plug-CG8al2Kq.js.map → plug-DVvSSe40.js.map} +1 -1
- package/bizar-dash/dist/assets/{plus-uA5Ecuch.js → plus-Cps-8lcG.js} +1 -1
- package/bizar-dash/dist/assets/{plus-uA5Ecuch.js.map → plus-Cps-8lcG.js.map} +1 -1
- package/bizar-dash/dist/assets/{power-DSUlNIuR.js → power-DEX4_Xoa.js} +1 -1
- package/bizar-dash/dist/assets/{power-DSUlNIuR.js.map → power-DEX4_Xoa.js.map} +1 -1
- package/bizar-dash/dist/assets/{power-off-1CAQsHHy.js → power-off-upZ4xjaG.js} +1 -1
- package/bizar-dash/dist/assets/{power-off-1CAQsHHy.js.map → power-off-upZ4xjaG.js.map} +1 -1
- package/bizar-dash/dist/assets/{refresh-ccw-BL7B0NO1.js → refresh-ccw-DN_zCB1h.js} +1 -1
- package/bizar-dash/dist/assets/{refresh-ccw-BL7B0NO1.js.map → refresh-ccw-DN_zCB1h.js.map} +1 -1
- package/bizar-dash/dist/assets/{refresh-cw-CR9BzJik.js → refresh-cw-KGm5eQgv.js} +1 -1
- package/bizar-dash/dist/assets/{refresh-cw-CR9BzJik.js.map → refresh-cw-KGm5eQgv.js.map} +1 -1
- package/bizar-dash/dist/assets/{rotate-ccw-BtnitLfb.js → rotate-ccw-D5fkDRgk.js} +1 -1
- package/bizar-dash/dist/assets/{rotate-ccw-BtnitLfb.js.map → rotate-ccw-D5fkDRgk.js.map} +1 -1
- package/bizar-dash/dist/assets/{rotate-cw-CHgXCO7O.js → rotate-cw-CClSVUaX.js} +1 -1
- package/bizar-dash/dist/assets/{rotate-cw-CHgXCO7O.js.map → rotate-cw-CClSVUaX.js.map} +1 -1
- package/bizar-dash/dist/assets/{save-RcZOXR0U.js → save-BY4ViPku.js} +1 -1
- package/bizar-dash/dist/assets/{save-RcZOXR0U.js.map → save-BY4ViPku.js.map} +1 -1
- package/bizar-dash/dist/assets/{send-Bg2X_ibk.js → send-CaOL1yQD.js} +2 -2
- package/bizar-dash/dist/assets/{send-Bg2X_ibk.js.map → send-CaOL1yQD.js.map} +1 -1
- package/bizar-dash/dist/assets/{shield-alert-Dm48D034.js → shield-alert-DA9K6uZO.js} +1 -1
- package/bizar-dash/dist/assets/{shield-alert-Dm48D034.js.map → shield-alert-DA9K6uZO.js.map} +1 -1
- package/bizar-dash/dist/assets/{trash-2-B885GY46.js → trash-2-B_Y6HrfN.js} +2 -2
- package/bizar-dash/dist/assets/{trash-2-B885GY46.js.map → trash-2-B_Y6HrfN.js.map} +1 -1
- package/bizar-dash/dist/assets/{trending-up-CqUBvVxw.js → trending-up-qKTUQKIT.js} +1 -1
- package/bizar-dash/dist/assets/{trending-up-CqUBvVxw.js.map → trending-up-qKTUQKIT.js.map} +1 -1
- package/bizar-dash/dist/assets/{triangle-alert-DLmUhymD.js → triangle-alert-BeY8LAv6.js} +1 -1
- package/bizar-dash/dist/assets/{triangle-alert-DLmUhymD.js.map → triangle-alert-BeY8LAv6.js.map} +1 -1
- package/bizar-dash/dist/assets/{upload-C-oafpyE.js → upload-BZCtmqIh.js} +1 -1
- package/bizar-dash/dist/assets/{upload-C-oafpyE.js.map → upload-BZCtmqIh.js.map} +1 -1
- package/bizar-dash/dist/assets/{zap-O_4Ys_hh.js → zap-Bz1Z8y1Q.js} +2 -2
- package/bizar-dash/dist/assets/{zap-O_4Ys_hh.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/App.tsx +25 -4
- package/bizar-dash/src/web/v8/shell/Sidebar.tsx +49 -36
- package/bizar-dash/src/web/v8/shell/Topbar.tsx +120 -24
- 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/globals.css +14 -0
- package/bizar-dash/src/web/v8/ui/styles/tokens.css +21 -0
- package/bizar-dash/src/web/v8/ui/theme/ThemeToggle.tsx +11 -6
- package/bizar-dash/src/web/v8/views/Admin/AdminView.tsx +32 -5
- package/bizar-dash/src/web/v8/views/Agents/AgentsView.tsx +11 -4
- package/bizar-dash/src/web/v8/views/Artifacts/ArtifactsView.tsx +1 -1
- 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/Clipboard/ClipboardView.tsx +1 -1
- package/bizar-dash/src/web/v8/views/Dialogs/DialogsView.tsx +1 -1
- package/bizar-dash/src/web/v8/views/LightRAG/LightRAGView.tsx +23 -2
- package/bizar-dash/src/web/v8/views/Misc/MiscView.tsx +1 -1
- package/bizar-dash/src/web/v8/views/Notifications/NotificationsView.tsx +82 -13
- package/bizar-dash/src/web/v8/views/Overview/OverviewView.tsx +19 -0
- 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/src/web/v8/views/Voice/VoiceView.tsx +1 -1
- package/bizar-dash/tests/admin-run-grouping.test.mjs +42 -0
- package/bizar-dash/tests/agents-preview-truncate.test.mjs +35 -0
- 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/empty-state-docs.test.mjs +55 -0
- package/bizar-dash/tests/errorstate-retry.test.mjs +42 -0
- package/bizar-dash/tests/focus-visible.test.mjs +30 -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/notifications-dismiss-restore.test.mjs +85 -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/palette-shortcut-hint.test.mjs +58 -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-distinct-icons.test.mjs +28 -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/theme-toggle-icon.test.mjs +28 -0
- package/bizar-dash/tests/topbar-design-system.test.mjs +56 -0
- package/bizar-dash/tests/topbar-popover-styles.test.mjs +53 -0
- package/bizar-dash/tests/update-channels.test.mjs +67 -0
- package/bizar-dash/vite.config.ts +8 -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/AdminView-CI4zM2Qg.js +0 -11
- package/bizar-dash/dist/assets/AdminView-CI4zM2Qg.js.map +0 -1
- package/bizar-dash/dist/assets/AgentsView-CIQkZH8_.js.map +0 -1
- package/bizar-dash/dist/assets/ArtifactsView-B-YUwZyb.js +0 -21
- package/bizar-dash/dist/assets/ArtifactsView-B-YUwZyb.js.map +0 -1
- package/bizar-dash/dist/assets/AuthView-LaQuGo4u.js.map +0 -1
- package/bizar-dash/dist/assets/Avatar-Dg4OF4RD.js +0 -6
- package/bizar-dash/dist/assets/Avatar-Dg4OF4RD.js.map +0 -1
- package/bizar-dash/dist/assets/BackgroundJobsView-CO3DEG8R.js +0 -1
- package/bizar-dash/dist/assets/BackgroundJobsView-CO3DEG8R.js.map +0 -1
- package/bizar-dash/dist/assets/ClaudeSessionsView-D-YNmzKi.js +0 -1
- package/bizar-dash/dist/assets/ClaudeSessionsView-D-YNmzKi.js.map +0 -1
- package/bizar-dash/dist/assets/ClipboardView-BA323V2J.js +0 -1
- package/bizar-dash/dist/assets/ClipboardView-BA323V2J.js.map +0 -1
- package/bizar-dash/dist/assets/DialogsView-DzTnyX8K.js +0 -6
- package/bizar-dash/dist/assets/DialogsView-DzTnyX8K.js.map +0 -1
- package/bizar-dash/dist/assets/EvalView-lgUhlGJh.js +0 -1
- package/bizar-dash/dist/assets/LibrariesView-Ca_PRjUm.js +0 -6
- package/bizar-dash/dist/assets/LightRAGView-CMk9wOae.js +0 -6
- package/bizar-dash/dist/assets/LightRAGView-CMk9wOae.js.map +0 -1
- package/bizar-dash/dist/assets/MiscView-fBT1TOXC.js +0 -1
- package/bizar-dash/dist/assets/MiscView-fBT1TOXC.js.map +0 -1
- package/bizar-dash/dist/assets/NotificationsView-BKAZLxM2.js +0 -6
- package/bizar-dash/dist/assets/NotificationsView-BKAZLxM2.js.map +0 -1
- package/bizar-dash/dist/assets/ObsidianView-C-AvHfpT.js +0 -1
- package/bizar-dash/dist/assets/OverviewView-CKYzZJe3.js +0 -1
- package/bizar-dash/dist/assets/OverviewView-CKYzZJe3.js.map +0 -1
- package/bizar-dash/dist/assets/SchedulesView-8qxH3bg7.js +0 -1
- package/bizar-dash/dist/assets/SchedulesView-8qxH3bg7.js.map +0 -1
- package/bizar-dash/dist/assets/SettingsView-UD403neY.js.map +0 -1
- package/bizar-dash/dist/assets/UpdateView-B9Lh4svM.js +0 -6
- package/bizar-dash/dist/assets/UpdateView-B9Lh4svM.js.map +0 -1
- package/bizar-dash/dist/assets/VoiceView-BwR9gm5e.js +0 -1
- package/bizar-dash/dist/assets/VoiceView-BwR9gm5e.js.map +0 -1
- package/bizar-dash/dist/assets/main-BZMmD6a8.js +0 -249
- package/bizar-dash/dist/assets/main-BZMmD6a8.js.map +0 -1
- package/bizar-dash/dist/assets/main-DDAMz_H5.css +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":"GoalsView-DmkCCs9i.js","sources":["../../src/web/v8/ui/goals/GoalCard.tsx","../../src/web/v8/ui/goals/GoalDetail.tsx","../../src/web/v8/views/Goals/GoalsView.tsx"],"sourcesContent":["import { type ReactNode } from 'react';\nimport { Calendar, ChevronRight } from 'lucide-react';\nimport { cx } from '../utils/cx.js';\nimport { ProgressBar } from '../data/ProgressBar.js';\nimport { Badge } from '../data/Badge.js';\n\n/**\n * GoalCard — long-horizon goal surface (PLAN.md: \"Goals page\").\n *\n * Goals are NOT kanban cards. They are intentional commitments tracked\n * over weeks/months. Each card shows: title, why (description), status,\n * progress, due, owner, key results count.\n */\n\nexport type GoalStatus = 'on-track' | 'at-risk' | 'off-track' | 'done';\n\nexport interface GoalCardProps {\n id: string;\n title: string;\n /** Why this goal matters (the \"because\"). */\n description?: string;\n status: GoalStatus;\n /** 0..1 fractional progress. */\n progress: number;\n /** Due date label (e.g. \"Q3 2026\", \"Mar 31\"). */\n due?: string;\n /** Owner name (renders as Avatar when paired with avatarUrl). */\n ownerName?: string;\n ownerAvatarUrl?: string;\n /** Key results count + done count (e.g. \"3 / 5 key results\"). */\n keyResultsDone?: number;\n keyResultsTotal?: number;\n /** Optional badges row (priority, tags). */\n badges?: ReactNode;\n /** Click handler — opens the goal detail. */\n onOpen?: () => void;\n className?: string;\n}\n\nconst STATUS_LABEL: Record<GoalStatus, string> = {\n 'on-track': 'On track',\n 'at-risk': 'At risk',\n 'off-track': 'Off track',\n done: 'Done',\n};\n\nconst STATUS_TONE: Record<GoalStatus, 'success' | 'warning' | 'danger' | 'neutral'> = {\n 'on-track': 'success',\n 'at-risk': 'warning',\n 'off-track': 'danger',\n done: 'neutral',\n};\n\nexport function GoalCard(props: GoalCardProps) {\n const {\n title,\n description,\n status,\n progress,\n due,\n ownerName,\n ownerAvatarUrl,\n keyResultsDone,\n keyResultsTotal,\n badges,\n onOpen,\n className,\n } = props;\n\n return (\n <button\n type=\"button\"\n onClick={onOpen}\n className={cx('v8-goal-card', `v8-goal-card--${status}`, className)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-3)',\n width: '100%',\n padding: 'var(--space-4)',\n background: 'var(--surface-1)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-lg)',\n textAlign: 'left',\n cursor: 'pointer',\n font: 'inherit',\n color: 'inherit',\n transition: 'border-color var(--motion-fast) var(--ease-out), background var(--motion-fast) var(--ease-out)',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 'var(--space-2)' }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 'var(--fs-14)', fontWeight: 600, color: 'var(--fg)', lineHeight: 'var(--lh-snug)' }}>\n {title}\n </div>\n {description !== undefined && (\n <div\n style={{\n fontSize: 'var(--fs-13)',\n color: 'var(--fg-muted)',\n marginTop: 4,\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {description}\n </div>\n )}\n </div>\n <Badge tone={STATUS_TONE[status]} dot>\n {STATUS_LABEL[status]}\n </Badge>\n </div>\n <div>\n <ProgressBar\n value={progress}\n tone={status === 'on-track' ? 'success' : status === 'at-risk' ? 'warning' : status === 'off-track' ? 'danger' : 'accent'}\n />\n <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 6, fontSize: 'var(--fs-12)', color: 'var(--fg-muted)', fontVariantNumeric: 'tabular-nums' }}>\n <span>{Math.round(progress * 100)}% complete</span>\n {keyResultsDone !== undefined && keyResultsTotal !== undefined && (\n <span>\n {keyResultsDone} / {keyResultsTotal} key results\n </span>\n )}\n </div>\n </div>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 'var(--space-2)',\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-subtle)',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-3)' }}>\n {due !== undefined && (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>\n <Calendar size={12} aria-hidden=\"true\" />\n {due}\n </span>\n )}\n {ownerName !== undefined && (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>\n <span\n aria-hidden=\"true\"\n style={{\n width: 16,\n height: 16,\n borderRadius: 'var(--radius-pill)',\n background: ownerAvatarUrl !== undefined ? `url(${ownerAvatarUrl}) center/cover` : 'var(--accent)',\n display: 'inline-block',\n }}\n />\n {ownerName}\n </span>\n )}\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>\n {badges}\n <ChevronRight size={14} aria-hidden=\"true\" style={{ color: 'var(--fg-subtle)' }} />\n </div>\n </div>\n <style>{`\n .v8-goal-card:hover {\n border-color: var(--accent);\n background: var(--surface-2);\n }\n `}</style>\n </button>\n );\n}","import { useEffect, useState } from 'react';\nimport { Plus, Trash2, ExternalLink } from 'lucide-react';\nimport { Sheet, SheetContent } from '../feedback/Sheet.js';\nimport { Stack } from '../primitives/Stack.js';\nimport { Inline } from '../primitives/Inline.js';\nimport { Button } from '../controls/Button.js';\nimport { Input } from '../controls/Input.js';\nimport { Select, SelectContent, SelectItem, SelectTrigger } from '../controls/Select.js';\nimport { Skeleton } from '../feedback/Skeleton.js';\nimport { Badge } from '../data/Badge.js';\nimport { fetchJson } from '../../data/fetcher.js';\nimport type { Goal } from '../../data/types.js';\n\n/**\n * GoalDetail — Sprint S12. Right-side Drawer with editable\n * title / status / due / owner / key-results.\n *\n * Source-of-truth = `.bizar/PROGRESS.md` (per user direction). Each\n * edit PATCHes `/api/goals/:id` and the server re-broadcasts the\n * canonical state via `goals:change`.\n */\n\nconst STATUS_OPTIONS = [\n { value: 'on-track', label: 'On track' },\n { value: 'at-risk', label: 'At risk' },\n { value: 'off-track', label: 'Off track' },\n { value: 'blocked', label: 'Blocked' },\n { value: 'active', label: 'Active' },\n { value: 'done', label: 'Done' },\n];\n\nexport interface GoalDetailProps {\n goal: Goal;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport function GoalDetail(props: GoalDetailProps): JSX.Element {\n const { goal, open, onOpenChange } = props;\n const [deleting, setDeleting] = useState<boolean>(false);\n\n const removeGoal = async (): Promise<void> => {\n const ok = typeof window !== 'undefined' && typeof window.confirm === 'function'\n ? window.confirm(`Delete goal \"${goal.title}\"? This removes it from PROGRESS.md.`)\n : true;\n if (!ok) return;\n setDeleting(true);\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goal.id)}`, { method: 'DELETE' });\n onOpenChange(false);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setDeleting(false);\n }\n };\n const [title, setTitle] = useState<string>(goal.title);\n const [status, setStatus] = useState<string>(goal.status);\n const [owner, setOwner] = useState<string>(goal.owner || '');\n const [due, setDue] = useState<string>(goal.due || '');\n const [newKr, setNewKr] = useState<string>('');\n const [busy, setBusy] = useState<string | null>(null);\n const [message, setMessage] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (open) {\n setTitle(goal.title);\n setStatus(goal.status);\n setOwner(goal.owner || '');\n setDue(goal.due || '');\n setMessage(null);\n setError(null);\n setNewKr('');\n }\n }, [open, goal]);\n\n const patch = async (body: Record<string, unknown>, label: string): Promise<void> => {\n setBusy(label);\n setMessage(null);\n setError(null);\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goal.id)}`, { method: 'PATCH', body });\n setMessage(`${label} saved.`);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n const saveTitle = (): void => {\n if (title.trim() && title !== goal.title) void patch({ title: title.trim() }, 'Title');\n };\n const saveStatus = (v: string): void => {\n setStatus(v);\n if (v !== goal.status) void patch({ status: v }, 'Status');\n };\n const saveOwner = (): void => {\n const v = owner.trim();\n if (v !== (goal.owner || '')) void patch({ owner: v }, 'Owner');\n };\n const saveDue = (): void => {\n const v = due.trim();\n if (v !== (goal.due || '')) void patch({ due: v }, 'Due');\n };\n\n const toggleKr = async (krId: string, current: boolean): Promise<void> => {\n setBusy(`kr-${krId}`);\n setError(null);\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goal.id)}/key-results/${encodeURIComponent(krId)}`, {\n method: 'PATCH',\n body: { done: !current },\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n const addKr = async (): Promise<void> => {\n const v = newKr.trim();\n if (!v) return;\n setNewKr('');\n setBusy('add-kr');\n setError(null);\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goal.id)}/key-results`, {\n method: 'POST',\n body: { title: v },\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n const removeKr = async (krId: string): Promise<void> => {\n setBusy(`remove-${krId}`);\n setError(null);\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goal.id)}/key-results/${encodeURIComponent(krId)}`, {\n method: 'DELETE',\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent side=\"right\" title=\"Edit goal\">\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"goal-title\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Title\n </label>\n <Inline gap={2}>\n <Input\n id=\"goal-title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n onBlur={saveTitle}\n disabled={busy !== null}\n style={{ flex: 1 }}\n />\n </Inline>\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"goal-status\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Status\n </label>\n <Select value={status} onValueChange={saveStatus}>\n <SelectTrigger id=\"goal-status\" size=\"sm\" placeholder=\"Status\" />\n <SelectContent>\n {STATUS_OPTIONS.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Stack>\n\n <Inline gap={2}>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"goal-owner\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Owner\n </label>\n <Input id=\"goal-owner\" value={owner} onChange={(e) => setOwner(e.target.value)} onBlur={saveOwner} disabled={busy !== null} />\n </Stack>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"goal-due\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Due\n </label>\n <Input id=\"goal-due\" value={due} onChange={(e) => setDue(e.target.value)} onBlur={saveDue} placeholder=\"2026-09-30\" disabled={busy !== null} />\n </Stack>\n </Inline>\n\n <Stack gap={2}>\n <div style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Key results</div>\n <Stack gap={1}>\n {goal.keyResults.length === 0 && (\n <div style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>None yet.</div>\n )}\n {goal.keyResults.map((kr) => (\n <Inline key={kr.id} gap={2} align=\"center\">\n <input\n type=\"checkbox\"\n checked={kr.done}\n onChange={() => { void toggleKr(kr.id, kr.done); }}\n aria-label={`Toggle ${kr.title}`}\n disabled={busy !== null}\n />\n <span style={{ flex: 1, fontSize: 'var(--fs-13)', textDecoration: kr.done ? 'line-through' : 'none' }}>\n {kr.title}\n </span>\n {kr.assignee && <Badge tone=\"neutral\">{kr.assignee}</Badge>}\n {kr.taskId && (\n <Badge tone=\"info\" title={`Decomposed task: ${kr.taskId}`}>\n <ExternalLink size={10} aria-hidden style={{ marginRight: 4, verticalAlign: 'text-bottom' }} />\n task\n </Badge>\n )}\n <Button\n variant=\"ghost\"\n onClick={() => { void removeKr(kr.id); }}\n disabled={busy !== null}\n aria-label={`Remove ${kr.title}`}\n >\n <Trash2 size={12} aria-hidden />\n </Button>\n </Inline>\n ))}\n </Stack>\n <Inline gap={2}>\n <Input\n value={newKr}\n onChange={(e) => setNewKr(e.target.value)}\n onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); void addKr(); } }}\n placeholder=\"Add key result…\"\n disabled={busy !== null}\n style={{ flex: 1 }}\n />\n <Button variant=\"secondary\" onClick={() => { void addKr(); }} disabled={!newKr.trim() || busy !== null}>\n <Plus size={14} aria-hidden /> Add\n </Button>\n </Inline>\n </Stack>\n\n <div style={{ borderTop: '1px solid var(--border)', paddingTop: 'var(--space-3)' }}>\n <Button\n variant=\"danger\"\n onClick={() => { void removeGoal(); }}\n disabled={deleting || busy !== null}\n >\n <Trash2 size={14} aria-hidden /> {deleting ? 'Deleting…' : 'Delete goal'}\n </Button>\n </div>\n\n {message !== null && (\n <div role=\"status\" style={{ fontSize: 'var(--fs-12)', color: 'var(--success)' }}>{message}</div>\n )}\n {error !== null && (\n <div role=\"alert\" style={{ fontSize: 'var(--fs-12)', color: 'var(--danger)' }}>{error}</div>\n )}\n {busy !== null && <Skeleton style={{ height: 12 }} />}\n </Stack>\n </SheetContent>\n </Sheet>\n );\n}","import { useCallback, useEffect, useState } from 'react';\nimport { Plus, Trash2 } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Grid } from '../../ui/primitives/Grid.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { Chip } from '../../ui/data/Chip.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { GoalCard, type GoalCardProps, type GoalStatus } from '../../ui/goals/GoalCard.js';\nimport { GoalDetail } from '../../ui/goals/GoalDetail.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { ListHeader } from '../../ui/data/ListHeader.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 { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson } from '../../data/fetcher.js';\nimport type { Goal, WsMessage } from '../../data/types.js';\n\n/**\n * GoalsView — Sprint S10/S12. Pulls `/api/goals` (parsed PROGRESS.md).\n * Card click → `GoalDetail` Drawer (editable title / status / due /\n * owner / KR add/toggle/remove). \"+ New goal\" button creates a fresh\n * goal via `POST /api/goals`. Live updates via `goals:change`.\n */\n\nfunction goalToCard(g: Goal): GoalCardProps {\n return {\n id: g.id,\n title: g.title,\n description: g.description || '',\n status: g.status as GoalStatus,\n progress: g.progress,\n due: g.due,\n ownerName: g.owner,\n keyResultsDone: g.keyResults.filter((k) => k.done).length,\n keyResultsTotal: g.keyResults.length,\n };\n}\n\nexport function GoalsView(): JSX.Element {\n const goals = useFetch<{ goals?: Goal[]; count?: number }>('/api/goals');\n const [local, setLocal] = useState<Goal[]>([]);\n const [initialized, setInitialized] = useState(false);\n const [openGoalId, setOpenGoalId] = useState<string | null>(null);\n const [creating, setCreating] = useState<boolean>(false);\n const [decomposing, setDecomposing] = useState<string | null>(null);\n const [decomposeError, setDecomposeError] = useState<string | null>(null);\n const [statusFilter, setStatusFilter] = useState<string>('all');\n // v9.1.1 — replace window.prompt/window.confirm with an inline Sheet\n // form for create + a per-card confirm row for delete. Same data\n // contract; better UX, accessible, no popup blockers.\n const [createDraft, setCreateDraft] = useState<{ title: string; description: string } | null>(null);\n const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);\n\n const filteredGoals = statusFilter === 'all' ? local : local.filter((g) => g.status === statusFilter);\n\n const STATUS_FILTERS = ['all', 'active', 'on-track', 'at-risk', 'off-track', 'blocked', 'done'] as const;\n\n useEffect(() => {\n if (goals.data?.goals && !initialized) {\n setInitialized(true);\n setLocal(goals.data.goals);\n }\n }, [goals.data, initialized]);\n\n const onChange = useCallback((msg: WsMessage) => {\n if (msg.type !== 'goals:change') return;\n const g = (msg as Extract<WsMessage, { type: 'goals:change' }>).goal;\n if (!g) return;\n // Tombstone broadcast from the server after a DELETE — drop the card.\n if ('removed' in g && (g as { removed?: boolean }).removed) {\n setLocal((prev) => prev.filter((x) => x.id !== g.id));\n if (openGoalId === g.id) setOpenGoalId(null);\n return;\n }\n setLocal((prev) => {\n const idx = prev.findIndex((x) => x.id === g.id);\n if (idx === -1) return [...prev, g];\n const copy = prev.slice();\n copy[idx] = g;\n return copy;\n });\n }, [openGoalId]);\n useWsMessage('goals:change', onChange);\n useWsMessage('goals:removed', (msg) => {\n const id = (msg as Extract<WsMessage, { type: 'goals:removed' }>).id;\n setLocal((prev) => prev.filter((x) => x.id !== id));\n if (openGoalId === id) setOpenGoalId(null);\n });\n\n const createGoal = useCallback(async () => {\n // v9.1.1 — open the Sheet form. POST happens when the user clicks\n // Create inside the Sheet (see saveCreate below).\n setCreateDraft({ title: '', description: '' });\n }, []);\n\n const saveCreate = useCallback(async () => {\n if (!createDraft || !createDraft.title.trim()) return;\n setCreating(true);\n setDecomposeError(null);\n try {\n const res = await fetchJson<{ goal?: Goal; id?: string }>('/api/goals', {\n method: 'POST',\n body: {\n title: createDraft.title.trim(),\n description: createDraft.description.trim() || undefined,\n status: 'active',\n },\n });\n if (res.goal) setLocal((prev) => [...prev, res.goal as Goal]);\n if (res.id) setOpenGoalId(res.id);\n setCreateDraft(null);\n } catch (err) {\n setDecomposeError(err instanceof Error ? err.message : String(err));\n } finally {\n setCreating(false);\n }\n }, [createDraft]);\n\n const openGoal = openGoalId ? local.find((g) => g.id === openGoalId) ?? null : null;\n\n const decompose = useCallback(async (goalId: string) => {\n setDecomposing(goalId);\n setDecomposeError(null);\n try {\n const res = await fetchJson<{ goalId: string; created: { kr: string; task: string }[] }>(\n `/api/goals/${encodeURIComponent(goalId)}/decompose`,\n { method: 'POST' },\n );\n // Patch local state with the new taskIds so the button reflects\n // \"Decomposed\" without waiting for the WS roundtrip.\n if (Array.isArray(res.created) && res.created.length > 0) {\n setLocal((prev) => prev.map((g) => {\n if (g.id !== goalId) return g;\n const krs = (g.keyResults ?? []).map((kr) => {\n const link = res.created.find((c) => c.kr === kr.id);\n return link ? { ...kr, taskId: link.task } : kr;\n });\n return { ...g, keyResults: krs };\n }));\n }\n } catch (err) {\n setDecomposeError(err instanceof Error ? err.message : String(err));\n } finally {\n setDecomposing(null);\n }\n }, []);\n\n const deleteGoal = useCallback(async (goalId: string) => {\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goalId)}`, { method: 'DELETE' });\n // Server broadcasts goals:removed + goals:change tombstone; the\n // WS handler drops the card. Close the drawer if it was open.\n setLocal((prev) => prev.filter((x) => x.id !== goalId));\n if (openGoalId === goalId) setOpenGoalId(null);\n setConfirmDeleteId(null);\n } catch (err) {\n setDecomposeError(err instanceof Error ? err.message : String(err));\n }\n }, [openGoalId]);\n\n return (\n <Stack gap={5} data-testid=\"goals-view\">\n <ViewHeader\n title=\"Goals\"\n description=\"Long-horizon commitments parsed from .bizar/PROGRESS.md.\"\n actions={\n <Button variant=\"primary\" onClick={() => { void createGoal(); }} disabled={creating}>\n <Plus size={14} aria-hidden /> New goal\n </Button>\n }\n />\n <ListHeader\n title=\"All goals\"\n count={local.length}\n testid=\"goals-list-header\"\n filters={\n <Inline gap={1} wrap>\n {STATUS_FILTERS.map((s) => (\n <Chip key={s} selected={statusFilter === s} onClick={() => setStatusFilter(s)}>\n {s === 'all' ? 'All' : s.replace(/-/g, ' ')}\n {s !== 'all' && ` · ${local.filter((g) => g.status === s).length}`}\n </Chip>\n ))}\n </Inline>\n }\n />\n {decomposeError !== null && (\n <div role=\"alert\" style={{ padding: '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)' }}>\n Decompose failed: {decomposeError}\n </div>\n )}\n {goals.loading && local.length === 0 ? (\n <Stack gap={3}>\n <Skeleton style={{ height: 160 }} />\n <Skeleton style={{ height: 160 }} />\n </Stack>\n ) : goals.error && local.length === 0 ? (\n <ErrorState\n block\n title=\"Couldn't load goals\"\n description=\"The goals endpoint failed. Retry to refetch.\"\n error={goals.error}\n onRetry={() => void goals.refetch()}\n testid=\"goals-error\"\n />\n ) : filteredGoals.length === 0 ? (\n <Card>\n <CardBody>\n <Stack gap={2}>\n <strong>No goals {statusFilter === 'all' ? 'yet' : `with status “${statusFilter}”`}.</strong>\n <span style={{ color: 'var(--fg-muted)' }}>\n Create one with the dashboard or via CC's <code>/goal <text></code>.\n </span>\n </Stack>\n </CardBody>\n </Card>\n ) : (\n <Grid cols={2}>\n {filteredGoals.map((g) => {\n const krCount = g.keyResults?.length ?? 0;\n const decomposed = (g.keyResults ?? []).every((kr) => Boolean(kr.taskId));\n return (\n <div\n key={g.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => setOpenGoalId(g.id)}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setOpenGoalId(g.id); } }}\n style={{ cursor: 'pointer', outline: 'none' }}\n data-testid={`goal-card-${g.id}`}\n >\n <Stack gap={2}>\n <GoalCard {...goalToCard(g)} />\n {confirmDeleteId === g.id ? (\n <Inline align=\"center\" justify=\"end\" gap={2}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Delete this goal and remove it from PROGRESS.md?\n </span>\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={(e) => { e.stopPropagation(); void deleteGoal(g.id); }}\n data-testid={`goal-confirm-delete-${g.id}`}\n >\n Delete\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => { e.stopPropagation(); setConfirmDeleteId(null); }}\n >\n Cancel\n </Button>\n </Inline>\n ) : (\n <Inline align=\"center\" justify=\"end\" gap={1}>\n <Button\n variant=\"ghost\"\n onClick={(e) => { e.stopPropagation(); setConfirmDeleteId(g.id); }}\n title=\"Delete goal\"\n aria-label={`Delete goal ${g.title}`}\n data-testid={`goal-delete-${g.id}`}\n >\n <Trash2 size={12} aria-hidden /> Delete\n </Button>\n </Inline>\n )}\n {krCount > 0 && (\n <Inline align=\"center\" justify=\"end\" gap={2}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {decomposed ? 'Decomposed' : `${krCount} key result${krCount === 1 ? '' : 's'} · not yet linked`}\n </span>\n <Button\n variant=\"secondary\"\n onClick={(e) => { e.stopPropagation(); void decompose(g.id); }}\n disabled={decomposing === g.id}\n title={decomposed ? 'Re-create missing task links' : 'Create one task per key result'}\n >\n <Plus size={12} aria-hidden /> {decomposed ? 'Re-link tasks' : 'Decompose → Tasks'}\n </Button>\n </Inline>\n )}\n </Stack>\n </div>\n );\n })}\n </Grid>\n )}\n\n {openGoal && (\n <GoalDetail\n goal={openGoal}\n open={openGoalId !== null}\n onOpenChange={(o) => { if (!o) setOpenGoalId(null); }}\n />\n )}\n\n {/* v9.1.1 — create-goal Sheet form. Replaces window.prompt which\n blocked the user's \"professional and data-driven\" ask. */}\n <Sheet open={createDraft !== null} onOpenChange={(o) => { if (!o) setCreateDraft(null); }}>\n <SheetContent side=\"right\" title=\"New goal\">\n {createDraft !== null && (\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"goal-create-title\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Title</label>\n <Input\n id=\"goal-create-title\"\n value={createDraft.title}\n onChange={(e) => setCreateDraft({ ...createDraft, title: e.target.value })}\n placeholder=\"Ship the orchestration center\"\n disabled={creating}\n data-testid=\"goal-create-title\"\n />\n </Stack>\n <Stack gap={2}>\n <label htmlFor=\"goal-create-desc\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Description (optional)</label>\n <Textarea\n id=\"goal-create-desc\"\n value={createDraft.description}\n onChange={(e) => setCreateDraft({ ...createDraft, description: e.target.value })}\n rows={4}\n placeholder=\"Why this goal exists and what 'done' looks like.\"\n disabled={creating}\n data-testid=\"goal-create-desc\"\n />\n </Stack>\n <Inline gap={2}>\n <Button\n variant=\"primary\"\n onClick={() => { void saveCreate(); }}\n disabled={creating || !createDraft.title.trim()}\n data-testid=\"goal-create-submit\"\n >\n Create goal\n </Button>\n <Button variant=\"ghost\" onClick={() => setCreateDraft(null)} disabled={creating}>\n Cancel\n </Button>\n </Inline>\n </Stack>\n )}\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}"],"names":["STATUS_LABEL","STATUS_TONE","GoalCard","props","title","description","status","progress","due","ownerName","ownerAvatarUrl","keyResultsDone","keyResultsTotal","badges","onOpen","className","jsxs","cx","jsx","Badge","ProgressBar","Calendar","ChevronRight","STATUS_OPTIONS","GoalDetail","goal","open","onOpenChange","deleting","setDeleting","useState","removeGoal","fetchJson","err","setError","setTitle","setStatus","owner","setOwner","setDue","newKr","setNewKr","busy","setBusy","message","setMessage","error","useEffect","patch","body","label","saveTitle","saveStatus","v","saveOwner","saveDue","toggleKr","krId","current","addKr","removeKr","Sheet","SheetContent","Stack","Inline","Input","e","Select","SelectTrigger","SelectContent","opt","SelectItem","kr","ExternalLink","Button","Trash2","Plus","Skeleton","goalToCard","g","k","GoalsView","goals","useFetch","local","setLocal","initialized","setInitialized","openGoalId","setOpenGoalId","creating","setCreating","decomposing","setDecomposing","decomposeError","setDecomposeError","statusFilter","setStatusFilter","createDraft","setCreateDraft","confirmDeleteId","setConfirmDeleteId","filteredGoals","STATUS_FILTERS","_a","onChange","useCallback","msg","prev","x","idx","copy","useWsMessage","id","createGoal","saveCreate","res","openGoal","decompose","goalId","krs","link","c","deleteGoal","ViewHeader","ListHeader","Chip","ErrorState","Card","CardBody","Grid","krCount","decomposed","o","Textarea"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"GoalsView-C3QG5p7T.js","sources":["../../src/web/v8/ui/goals/GoalCard.tsx","../../src/web/v8/ui/goals/GoalDetail.tsx","../../src/web/v8/views/Goals/GoalsView.tsx"],"sourcesContent":["import { type ReactNode } from 'react';\nimport { Calendar, ChevronRight } from 'lucide-react';\nimport { cx } from '../utils/cx.js';\nimport { ProgressBar } from '../data/ProgressBar.js';\nimport { Badge } from '../data/Badge.js';\n\n/**\n * GoalCard — long-horizon goal surface (PLAN.md: \"Goals page\").\n *\n * Goals are NOT kanban cards. They are intentional commitments tracked\n * over weeks/months. Each card shows: title, why (description), status,\n * progress, due, owner, key results count.\n */\n\nexport type GoalStatus = 'on-track' | 'at-risk' | 'off-track' | 'done';\n\nexport interface GoalCardProps {\n id: string;\n title: string;\n /** Why this goal matters (the \"because\"). */\n description?: string;\n status: GoalStatus;\n /** 0..1 fractional progress. */\n progress: number;\n /** Due date label (e.g. \"Q3 2026\", \"Mar 31\"). */\n due?: string;\n /** Owner name (renders as Avatar when paired with avatarUrl). */\n ownerName?: string;\n ownerAvatarUrl?: string;\n /** Key results count + done count (e.g. \"3 / 5 key results\"). */\n keyResultsDone?: number;\n keyResultsTotal?: number;\n /** Optional badges row (priority, tags). */\n badges?: ReactNode;\n /** Click handler — opens the goal detail. */\n onOpen?: () => void;\n className?: string;\n}\n\nconst STATUS_LABEL: Record<GoalStatus, string> = {\n 'on-track': 'On track',\n 'at-risk': 'At risk',\n 'off-track': 'Off track',\n done: 'Done',\n};\n\nconst STATUS_TONE: Record<GoalStatus, 'success' | 'warning' | 'danger' | 'neutral'> = {\n 'on-track': 'success',\n 'at-risk': 'warning',\n 'off-track': 'danger',\n done: 'neutral',\n};\n\nexport function GoalCard(props: GoalCardProps) {\n const {\n title,\n description,\n status,\n progress,\n due,\n ownerName,\n ownerAvatarUrl,\n keyResultsDone,\n keyResultsTotal,\n badges,\n onOpen,\n className,\n } = props;\n\n return (\n <button\n type=\"button\"\n onClick={onOpen}\n className={cx('v8-goal-card', `v8-goal-card--${status}`, className)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-3)',\n width: '100%',\n padding: 'var(--space-4)',\n background: 'var(--surface-1)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-lg)',\n textAlign: 'left',\n cursor: 'pointer',\n font: 'inherit',\n color: 'inherit',\n transition: 'border-color var(--motion-fast) var(--ease-out), background var(--motion-fast) var(--ease-out)',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 'var(--space-2)' }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontSize: 'var(--fs-14)', fontWeight: 600, color: 'var(--fg)', lineHeight: 'var(--lh-snug)' }}>\n {title}\n </div>\n {description !== undefined && (\n <div\n style={{\n fontSize: 'var(--fs-13)',\n color: 'var(--fg-muted)',\n marginTop: 4,\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {description}\n </div>\n )}\n </div>\n <Badge tone={STATUS_TONE[status]} dot>\n {STATUS_LABEL[status]}\n </Badge>\n </div>\n <div>\n <ProgressBar\n value={progress}\n tone={status === 'on-track' ? 'success' : status === 'at-risk' ? 'warning' : status === 'off-track' ? 'danger' : 'accent'}\n />\n <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 6, fontSize: 'var(--fs-12)', color: 'var(--fg-muted)', fontVariantNumeric: 'tabular-nums' }}>\n <span>{Math.round(progress * 100)}% complete</span>\n {keyResultsDone !== undefined && keyResultsTotal !== undefined && (\n <span>\n {keyResultsDone} / {keyResultsTotal} key results\n </span>\n )}\n </div>\n </div>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 'var(--space-2)',\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-subtle)',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-3)' }}>\n {due !== undefined && (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>\n <Calendar size={12} aria-hidden=\"true\" />\n {due}\n </span>\n )}\n {ownerName !== undefined && (\n <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>\n <span\n aria-hidden=\"true\"\n style={{\n width: 16,\n height: 16,\n borderRadius: 'var(--radius-pill)',\n background: ownerAvatarUrl !== undefined ? `url(${ownerAvatarUrl}) center/cover` : 'var(--accent)',\n display: 'inline-block',\n }}\n />\n {ownerName}\n </span>\n )}\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>\n {badges}\n <ChevronRight size={14} aria-hidden=\"true\" style={{ color: 'var(--fg-subtle)' }} />\n </div>\n </div>\n <style>{`\n .v8-goal-card:hover {\n border-color: var(--accent);\n background: var(--surface-2);\n }\n `}</style>\n </button>\n );\n}","import { useEffect, useState } from 'react';\nimport { Plus, Trash2, ExternalLink } from 'lucide-react';\nimport { Sheet, SheetContent } from '../feedback/Sheet.js';\nimport { Stack } from '../primitives/Stack.js';\nimport { Inline } from '../primitives/Inline.js';\nimport { Button } from '../controls/Button.js';\nimport { Input } from '../controls/Input.js';\nimport { Select, SelectContent, SelectItem, SelectTrigger } from '../controls/Select.js';\nimport { Skeleton } from '../feedback/Skeleton.js';\nimport { Badge } from '../data/Badge.js';\nimport { fetchJson } from '../../data/fetcher.js';\nimport type { Goal } from '../../data/types.js';\n\n/**\n * GoalDetail — Sprint S12. Right-side Drawer with editable\n * title / status / due / owner / key-results.\n *\n * Source-of-truth = `.bizar/PROGRESS.md` (per user direction). Each\n * edit PATCHes `/api/goals/:id` and the server re-broadcasts the\n * canonical state via `goals:change`.\n */\n\nconst STATUS_OPTIONS = [\n { value: 'on-track', label: 'On track' },\n { value: 'at-risk', label: 'At risk' },\n { value: 'off-track', label: 'Off track' },\n { value: 'blocked', label: 'Blocked' },\n { value: 'active', label: 'Active' },\n { value: 'done', label: 'Done' },\n];\n\nexport interface GoalDetailProps {\n goal: Goal;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport function GoalDetail(props: GoalDetailProps): JSX.Element {\n const { goal, open, onOpenChange } = props;\n const [deleting, setDeleting] = useState<boolean>(false);\n\n const removeGoal = async (): Promise<void> => {\n const ok = typeof window !== 'undefined' && typeof window.confirm === 'function'\n ? window.confirm(`Delete goal \"${goal.title}\"? This removes it from PROGRESS.md.`)\n : true;\n if (!ok) return;\n setDeleting(true);\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goal.id)}`, { method: 'DELETE' });\n onOpenChange(false);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setDeleting(false);\n }\n };\n const [title, setTitle] = useState<string>(goal.title);\n const [status, setStatus] = useState<string>(goal.status);\n const [owner, setOwner] = useState<string>(goal.owner || '');\n const [due, setDue] = useState<string>(goal.due || '');\n const [newKr, setNewKr] = useState<string>('');\n const [busy, setBusy] = useState<string | null>(null);\n const [message, setMessage] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (open) {\n setTitle(goal.title);\n setStatus(goal.status);\n setOwner(goal.owner || '');\n setDue(goal.due || '');\n setMessage(null);\n setError(null);\n setNewKr('');\n }\n }, [open, goal]);\n\n const patch = async (body: Record<string, unknown>, label: string): Promise<void> => {\n setBusy(label);\n setMessage(null);\n setError(null);\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goal.id)}`, { method: 'PATCH', body });\n setMessage(`${label} saved.`);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n const saveTitle = (): void => {\n if (title.trim() && title !== goal.title) void patch({ title: title.trim() }, 'Title');\n };\n const saveStatus = (v: string): void => {\n setStatus(v);\n if (v !== goal.status) void patch({ status: v }, 'Status');\n };\n const saveOwner = (): void => {\n const v = owner.trim();\n if (v !== (goal.owner || '')) void patch({ owner: v }, 'Owner');\n };\n const saveDue = (): void => {\n const v = due.trim();\n if (v !== (goal.due || '')) void patch({ due: v }, 'Due');\n };\n\n const toggleKr = async (krId: string, current: boolean): Promise<void> => {\n setBusy(`kr-${krId}`);\n setError(null);\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goal.id)}/key-results/${encodeURIComponent(krId)}`, {\n method: 'PATCH',\n body: { done: !current },\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n const addKr = async (): Promise<void> => {\n const v = newKr.trim();\n if (!v) return;\n setNewKr('');\n setBusy('add-kr');\n setError(null);\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goal.id)}/key-results`, {\n method: 'POST',\n body: { title: v },\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n const removeKr = async (krId: string): Promise<void> => {\n setBusy(`remove-${krId}`);\n setError(null);\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goal.id)}/key-results/${encodeURIComponent(krId)}`, {\n method: 'DELETE',\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent side=\"right\" title=\"Edit goal\">\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"goal-title\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Title\n </label>\n <Inline gap={2}>\n <Input\n id=\"goal-title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n onBlur={saveTitle}\n disabled={busy !== null}\n style={{ flex: 1 }}\n />\n </Inline>\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"goal-status\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Status\n </label>\n <Select value={status} onValueChange={saveStatus}>\n <SelectTrigger id=\"goal-status\" size=\"sm\" placeholder=\"Status\" />\n <SelectContent>\n {STATUS_OPTIONS.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Stack>\n\n <Inline gap={2}>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"goal-owner\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Owner\n </label>\n <Input id=\"goal-owner\" value={owner} onChange={(e) => setOwner(e.target.value)} onBlur={saveOwner} disabled={busy !== null} />\n </Stack>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"goal-due\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Due\n </label>\n <Input id=\"goal-due\" value={due} onChange={(e) => setDue(e.target.value)} onBlur={saveDue} placeholder=\"2026-09-30\" disabled={busy !== null} />\n </Stack>\n </Inline>\n\n <Stack gap={2}>\n <div style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Key results</div>\n <Stack gap={1}>\n {goal.keyResults.length === 0 && (\n <div style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>None yet.</div>\n )}\n {goal.keyResults.map((kr) => (\n <Inline key={kr.id} gap={2} align=\"center\">\n <input\n type=\"checkbox\"\n checked={kr.done}\n onChange={() => { void toggleKr(kr.id, kr.done); }}\n aria-label={`Toggle ${kr.title}`}\n disabled={busy !== null}\n />\n <span style={{ flex: 1, fontSize: 'var(--fs-13)', textDecoration: kr.done ? 'line-through' : 'none' }}>\n {kr.title}\n </span>\n {kr.assignee && <Badge tone=\"neutral\">{kr.assignee}</Badge>}\n {kr.taskId && (\n <Badge tone=\"info\" title={`Decomposed task: ${kr.taskId}`}>\n <ExternalLink size={10} aria-hidden style={{ marginRight: 4, verticalAlign: 'text-bottom' }} />\n task\n </Badge>\n )}\n <Button\n variant=\"ghost\"\n onClick={() => { void removeKr(kr.id); }}\n disabled={busy !== null}\n aria-label={`Remove ${kr.title}`}\n >\n <Trash2 size={12} aria-hidden />\n </Button>\n </Inline>\n ))}\n </Stack>\n <Inline gap={2}>\n <Input\n value={newKr}\n onChange={(e) => setNewKr(e.target.value)}\n onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); void addKr(); } }}\n placeholder=\"Add key result…\"\n disabled={busy !== null}\n style={{ flex: 1 }}\n />\n <Button variant=\"secondary\" onClick={() => { void addKr(); }} disabled={!newKr.trim() || busy !== null}>\n <Plus size={14} aria-hidden /> Add\n </Button>\n </Inline>\n </Stack>\n\n <div style={{ borderTop: '1px solid var(--border)', paddingTop: 'var(--space-3)' }}>\n <Button\n variant=\"danger\"\n onClick={() => { void removeGoal(); }}\n disabled={deleting || busy !== null}\n >\n <Trash2 size={14} aria-hidden /> {deleting ? 'Deleting…' : 'Delete goal'}\n </Button>\n </div>\n\n {message !== null && (\n <div role=\"status\" style={{ fontSize: 'var(--fs-12)', color: 'var(--success)' }}>{message}</div>\n )}\n {error !== null && (\n <div role=\"alert\" style={{ fontSize: 'var(--fs-12)', color: 'var(--danger)' }}>{error}</div>\n )}\n {busy !== null && <Skeleton style={{ height: 12 }} />}\n </Stack>\n </SheetContent>\n </Sheet>\n );\n}","import { useCallback, useEffect, useState } from 'react';\nimport { Plus, Trash2 } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Grid } from '../../ui/primitives/Grid.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { Chip } from '../../ui/data/Chip.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { GoalCard, type GoalCardProps, type GoalStatus } from '../../ui/goals/GoalCard.js';\nimport { GoalDetail } from '../../ui/goals/GoalDetail.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { ListHeader } from '../../ui/data/ListHeader.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 { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson } from '../../data/fetcher.js';\nimport type { Goal, WsMessage } from '../../data/types.js';\n\n/**\n * GoalsView — Sprint S10/S12. Pulls `/api/goals` (parsed PROGRESS.md).\n * Card click → `GoalDetail` Drawer (editable title / status / due /\n * owner / KR add/toggle/remove). \"+ New goal\" button creates a fresh\n * goal via `POST /api/goals`. Live updates via `goals:change`.\n */\n\nfunction goalToCard(g: Goal): GoalCardProps {\n return {\n id: g.id,\n title: g.title,\n description: g.description || '',\n status: g.status as GoalStatus,\n progress: g.progress,\n due: g.due,\n ownerName: g.owner,\n keyResultsDone: g.keyResults.filter((k) => k.done).length,\n keyResultsTotal: g.keyResults.length,\n };\n}\n\nexport function GoalsView(): JSX.Element {\n const goals = useFetch<{ goals?: Goal[]; count?: number }>('/api/goals');\n const [local, setLocal] = useState<Goal[]>([]);\n const [initialized, setInitialized] = useState(false);\n const [openGoalId, setOpenGoalId] = useState<string | null>(null);\n const [creating, setCreating] = useState<boolean>(false);\n const [decomposing, setDecomposing] = useState<string | null>(null);\n const [decomposeError, setDecomposeError] = useState<string | null>(null);\n const [statusFilter, setStatusFilter] = useState<string>('all');\n // v9.1.1 — replace window.prompt/window.confirm with an inline Sheet\n // form for create + a per-card confirm row for delete. Same data\n // contract; better UX, accessible, no popup blockers.\n const [createDraft, setCreateDraft] = useState<{ title: string; description: string } | null>(null);\n const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);\n\n const filteredGoals = statusFilter === 'all' ? local : local.filter((g) => g.status === statusFilter);\n\n const STATUS_FILTERS = ['all', 'active', 'on-track', 'at-risk', 'off-track', 'blocked', 'done'] as const;\n\n useEffect(() => {\n if (goals.data?.goals && !initialized) {\n setInitialized(true);\n setLocal(goals.data.goals);\n }\n }, [goals.data, initialized]);\n\n const onChange = useCallback((msg: WsMessage) => {\n if (msg.type !== 'goals:change') return;\n const g = (msg as Extract<WsMessage, { type: 'goals:change' }>).goal;\n if (!g) return;\n // Tombstone broadcast from the server after a DELETE — drop the card.\n if ('removed' in g && (g as { removed?: boolean }).removed) {\n setLocal((prev) => prev.filter((x) => x.id !== g.id));\n if (openGoalId === g.id) setOpenGoalId(null);\n return;\n }\n setLocal((prev) => {\n const idx = prev.findIndex((x) => x.id === g.id);\n if (idx === -1) return [...prev, g];\n const copy = prev.slice();\n copy[idx] = g;\n return copy;\n });\n }, [openGoalId]);\n useWsMessage('goals:change', onChange);\n useWsMessage('goals:removed', (msg) => {\n const id = (msg as Extract<WsMessage, { type: 'goals:removed' }>).id;\n setLocal((prev) => prev.filter((x) => x.id !== id));\n if (openGoalId === id) setOpenGoalId(null);\n });\n\n const createGoal = useCallback(async () => {\n // v9.1.1 — open the Sheet form. POST happens when the user clicks\n // Create inside the Sheet (see saveCreate below).\n setCreateDraft({ title: '', description: '' });\n }, []);\n\n const saveCreate = useCallback(async () => {\n if (!createDraft || !createDraft.title.trim()) return;\n setCreating(true);\n setDecomposeError(null);\n try {\n const res = await fetchJson<{ goal?: Goal; id?: string }>('/api/goals', {\n method: 'POST',\n body: {\n title: createDraft.title.trim(),\n description: createDraft.description.trim() || undefined,\n status: 'active',\n },\n });\n if (res.goal) setLocal((prev) => [...prev, res.goal as Goal]);\n if (res.id) setOpenGoalId(res.id);\n setCreateDraft(null);\n } catch (err) {\n setDecomposeError(err instanceof Error ? err.message : String(err));\n } finally {\n setCreating(false);\n }\n }, [createDraft]);\n\n const openGoal = openGoalId ? local.find((g) => g.id === openGoalId) ?? null : null;\n\n const decompose = useCallback(async (goalId: string) => {\n setDecomposing(goalId);\n setDecomposeError(null);\n try {\n const res = await fetchJson<{ goalId: string; created: { kr: string; task: string }[] }>(\n `/api/goals/${encodeURIComponent(goalId)}/decompose`,\n { method: 'POST' },\n );\n // Patch local state with the new taskIds so the button reflects\n // \"Decomposed\" without waiting for the WS roundtrip.\n if (Array.isArray(res.created) && res.created.length > 0) {\n setLocal((prev) => prev.map((g) => {\n if (g.id !== goalId) return g;\n const krs = (g.keyResults ?? []).map((kr) => {\n const link = res.created.find((c) => c.kr === kr.id);\n return link ? { ...kr, taskId: link.task } : kr;\n });\n return { ...g, keyResults: krs };\n }));\n }\n } catch (err) {\n setDecomposeError(err instanceof Error ? err.message : String(err));\n } finally {\n setDecomposing(null);\n }\n }, []);\n\n const deleteGoal = useCallback(async (goalId: string) => {\n try {\n await fetchJson(`/api/goals/${encodeURIComponent(goalId)}`, { method: 'DELETE' });\n // Server broadcasts goals:removed + goals:change tombstone; the\n // WS handler drops the card. Close the drawer if it was open.\n setLocal((prev) => prev.filter((x) => x.id !== goalId));\n if (openGoalId === goalId) setOpenGoalId(null);\n setConfirmDeleteId(null);\n } catch (err) {\n setDecomposeError(err instanceof Error ? err.message : String(err));\n }\n }, [openGoalId]);\n\n return (\n <Stack gap={5} data-testid=\"goals-view\">\n <ViewHeader\n title=\"Goals\"\n description=\"Long-horizon commitments parsed from .bizar/PROGRESS.md.\"\n actions={\n <Button variant=\"primary\" onClick={() => { void createGoal(); }} disabled={creating}>\n <Plus size={14} aria-hidden /> New goal\n </Button>\n }\n />\n <ListHeader\n title=\"All goals\"\n count={local.length}\n testid=\"goals-list-header\"\n filters={\n <Inline gap={1} wrap>\n {STATUS_FILTERS.map((s) => (\n <Chip key={s} selected={statusFilter === s} onClick={() => setStatusFilter(s)}>\n {s === 'all' ? 'All' : s.replace(/-/g, ' ')}\n {s !== 'all' && ` · ${local.filter((g) => g.status === s).length}`}\n </Chip>\n ))}\n </Inline>\n }\n />\n {decomposeError !== null && (\n <div role=\"alert\" style={{ padding: '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)' }}>\n Decompose failed: {decomposeError}\n </div>\n )}\n {goals.loading && local.length === 0 ? (\n <Stack gap={3}>\n <Skeleton style={{ height: 160 }} />\n <Skeleton style={{ height: 160 }} />\n </Stack>\n ) : goals.error && local.length === 0 ? (\n <ErrorState\n block\n title=\"Couldn't load goals\"\n description=\"The goals endpoint failed. Retry to refetch.\"\n error={goals.error}\n onRetry={() => void goals.refetch()}\n testid=\"goals-error\"\n />\n ) : filteredGoals.length === 0 ? (\n <Card>\n <CardBody>\n <Stack gap={2}>\n <strong>No goals {statusFilter === 'all' ? 'yet' : `with status “${statusFilter}”`}.</strong>\n <span style={{ color: 'var(--fg-muted)' }}>\n Create one with the dashboard or via CC's <code>/goal <text></code>.\n </span>\n </Stack>\n </CardBody>\n </Card>\n ) : (\n <Grid cols={2}>\n {filteredGoals.map((g) => {\n const krCount = g.keyResults?.length ?? 0;\n const decomposed = (g.keyResults ?? []).every((kr) => Boolean(kr.taskId));\n return (\n <div\n key={g.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => setOpenGoalId(g.id)}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setOpenGoalId(g.id); } }}\n style={{ cursor: 'pointer', outline: 'none' }}\n data-testid={`goal-card-${g.id}`}\n >\n <Stack gap={2}>\n <GoalCard {...goalToCard(g)} />\n {confirmDeleteId === g.id ? (\n <Inline align=\"center\" justify=\"end\" gap={2}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Delete this goal and remove it from PROGRESS.md?\n </span>\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={(e) => { e.stopPropagation(); void deleteGoal(g.id); }}\n data-testid={`goal-confirm-delete-${g.id}`}\n >\n Delete\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => { e.stopPropagation(); setConfirmDeleteId(null); }}\n >\n Cancel\n </Button>\n </Inline>\n ) : (\n <Inline align=\"center\" justify=\"end\" gap={1}>\n <Button\n variant=\"ghost\"\n onClick={(e) => { e.stopPropagation(); setConfirmDeleteId(g.id); }}\n title=\"Delete goal\"\n aria-label={`Delete goal ${g.title}`}\n data-testid={`goal-delete-${g.id}`}\n >\n <Trash2 size={12} aria-hidden /> Delete\n </Button>\n </Inline>\n )}\n {krCount > 0 && (\n <Inline align=\"center\" justify=\"end\" gap={2}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {decomposed ? 'Decomposed' : `${krCount} key result${krCount === 1 ? '' : 's'} · not yet linked`}\n </span>\n <Button\n variant=\"secondary\"\n onClick={(e) => { e.stopPropagation(); void decompose(g.id); }}\n disabled={decomposing === g.id}\n title={decomposed ? 'Re-create missing task links' : 'Create one task per key result'}\n >\n <Plus size={12} aria-hidden /> {decomposed ? 'Re-link tasks' : 'Decompose → Tasks'}\n </Button>\n </Inline>\n )}\n </Stack>\n </div>\n );\n })}\n </Grid>\n )}\n\n {openGoal && (\n <GoalDetail\n goal={openGoal}\n open={openGoalId !== null}\n onOpenChange={(o) => { if (!o) setOpenGoalId(null); }}\n />\n )}\n\n {/* v9.1.1 — create-goal Sheet form. Replaces window.prompt which\n blocked the user's \"professional and data-driven\" ask. */}\n <Sheet open={createDraft !== null} onOpenChange={(o) => { if (!o) setCreateDraft(null); }}>\n <SheetContent side=\"right\" title=\"New goal\">\n {createDraft !== null && (\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"goal-create-title\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Title</label>\n <Input\n id=\"goal-create-title\"\n value={createDraft.title}\n onChange={(e) => setCreateDraft({ ...createDraft, title: e.target.value })}\n placeholder=\"Ship the orchestration center\"\n disabled={creating}\n data-testid=\"goal-create-title\"\n />\n </Stack>\n <Stack gap={2}>\n <label htmlFor=\"goal-create-desc\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Description (optional)</label>\n <Textarea\n id=\"goal-create-desc\"\n value={createDraft.description}\n onChange={(e) => setCreateDraft({ ...createDraft, description: e.target.value })}\n rows={4}\n placeholder=\"Why this goal exists and what 'done' looks like.\"\n disabled={creating}\n data-testid=\"goal-create-desc\"\n />\n </Stack>\n <Inline gap={2}>\n <Button\n variant=\"primary\"\n onClick={() => { void saveCreate(); }}\n disabled={creating || !createDraft.title.trim()}\n data-testid=\"goal-create-submit\"\n >\n Create goal\n </Button>\n <Button variant=\"ghost\" onClick={() => setCreateDraft(null)} disabled={creating}>\n Cancel\n </Button>\n </Inline>\n </Stack>\n )}\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}"],"names":["STATUS_LABEL","STATUS_TONE","GoalCard","props","title","description","status","progress","due","ownerName","ownerAvatarUrl","keyResultsDone","keyResultsTotal","badges","onOpen","className","jsxs","cx","jsx","Badge","ProgressBar","Calendar","ChevronRight","STATUS_OPTIONS","GoalDetail","goal","open","onOpenChange","deleting","setDeleting","useState","removeGoal","fetchJson","err","setError","setTitle","setStatus","owner","setOwner","setDue","newKr","setNewKr","busy","setBusy","message","setMessage","error","useEffect","patch","body","label","saveTitle","saveStatus","v","saveOwner","saveDue","toggleKr","krId","current","addKr","removeKr","Sheet","SheetContent","Stack","Inline","Input","e","Select","SelectTrigger","SelectContent","opt","SelectItem","kr","ExternalLink","Button","Trash2","Plus","Skeleton","goalToCard","g","k","GoalsView","goals","useFetch","local","setLocal","initialized","setInitialized","openGoalId","setOpenGoalId","creating","setCreating","decomposing","setDecomposing","decomposeError","setDecomposeError","statusFilter","setStatusFilter","createDraft","setCreateDraft","confirmDeleteId","setConfirmDeleteId","filteredGoals","STATUS_FILTERS","_a","onChange","useCallback","msg","prev","x","idx","copy","useWsMessage","id","createGoal","saveCreate","res","openGoal","decompose","goalId","krs","link","c","deleteGoal","ViewHeader","ListHeader","Chip","ErrorState","Card","CardBody","Grid","krCount","decomposed","o","Textarea"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as w,j as A}from"./cmdk-C3F6LD6N.js";import{g as T}from"./main-
|
|
1
|
+
import{r as w,j as A}from"./cmdk-C3F6LD6N.js";import{g as T}from"./main-BRmJZcHt.js";const a={0:"0",1:"var(--space-1)",2:"var(--space-2)",3:"var(--space-3)",4:"var(--space-4)",5:"var(--space-5)",6:"var(--space-6)",8:"var(--space-8)",10:"var(--space-10)",12:"var(--space-12)",16:"var(--space-16)"},p={1:"repeat(1, minmax(0, 1fr))",2:"repeat(2, minmax(0, 1fr))",3:"repeat(3, minmax(0, 1fr))",4:"repeat(4, minmax(0, 1fr))",5:"repeat(5, minmax(0, 1fr))",6:"repeat(6, minmax(0, 1fr))",8:"repeat(8, minmax(0, 1fr))",12:"repeat(12, minmax(0, 1fr))"};function h(e){if(e===void 0)return{};if(typeof e=="number")return{gridTemplateColumns:p[e]};const r=e.base??1;return{gridTemplateColumns:p[r]}}const j={start:"start",center:"center",end:"end",stretch:"stretch"},R={start:"start",center:"center",end:"end",stretch:"stretch"},I=w.forwardRef(function(r,m){const{as:d,gap:f=4,rowGap:t,colGap:s,cols:v,rows:n,autoFlow:o,align:i,justify:c,children:l,className:u,style:x,...g}=r,y=d??"div",G={display:"grid",gap:a[f],...t!==void 0&&{rowGap:a[t]},...s!==void 0&&{columnGap:a[s]},...h(v),...n!==void 0&&{gridTemplateRows:`repeat(${n}, minmax(0, 1fr))`},...o!==void 0&&{gridAutoFlow:o},...i!==void 0&&{alignItems:j[i]},...c!==void 0&&{justifyItems:R[c]},...x};return A.jsx(y,{ref:m,className:T("v8-grid",u),style:G,...g,children:l})});export{I as G};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Grid-
|
|
1
|
+
{"version":3,"file":"Grid-Bojq8Sg7.js","sources":["../../src/web/v8/ui/primitives/Grid.tsx"],"sourcesContent":["import { forwardRef, type CSSProperties, type ElementType, type HTMLAttributes, type ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * Grid — CSS grid wrapper with token-driven gap and template columns.\n *\n * For responsive grids: pass `cols` as an object { base, sm, md, lg }.\n * Otherwise pass a single number (1..12) for a uniform grid.\n */\nexport type GridCols =\n | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 12\n | { base?: number; sm?: number; md?: number; lg?: number; xl?: number };\n\nexport interface GridProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {\n as?: ElementType;\n gap?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16;\n rowGap?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16;\n colGap?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16;\n cols?: GridCols;\n rows?: 1 | 2 | 3 | 4;\n autoFlow?: 'row' | 'column' | 'dense';\n align?: 'start' | 'center' | 'end' | 'stretch';\n justify?: 'start' | 'center' | 'end' | 'stretch';\n children?: ReactNode;\n className?: string;\n style?: CSSProperties;\n}\n\nconst SPACE_VAR: Record<NonNullable<GridProps['gap']>, string> = {\n 0: '0',\n 1: 'var(--space-1)',\n 2: 'var(--space-2)',\n 3: 'var(--space-3)',\n 4: 'var(--space-4)',\n 5: 'var(--space-5)',\n 6: 'var(--space-6)',\n 8: 'var(--space-8)',\n 10: 'var(--space-10)',\n 12: 'var(--space-12)',\n 16: 'var(--space-16)',\n};\n\nconst COLS_VAR: Record<number, string> = {\n 1: 'repeat(1, minmax(0, 1fr))',\n 2: 'repeat(2, minmax(0, 1fr))',\n 3: 'repeat(3, minmax(0, 1fr))',\n 4: 'repeat(4, minmax(0, 1fr))',\n 5: 'repeat(5, minmax(0, 1fr))',\n 6: 'repeat(6, minmax(0, 1fr))',\n 8: 'repeat(8, minmax(0, 1fr))',\n 12: 'repeat(12, minmax(0, 1fr))',\n};\n\nfunction colsToStyle(cols: GridCols | undefined): CSSProperties {\n if (cols === undefined) return {};\n if (typeof cols === 'number') return { gridTemplateColumns: COLS_VAR[cols] };\n // Responsive object — apply base as the default gridTemplateColumns; the\n // breakpoint variants should be handled by the parent component or a\n // generated class. We export the base here; responsive overrides can\n // compose via additional style overrides at the call site.\n const base = cols.base ?? 1;\n return { gridTemplateColumns: COLS_VAR[base] };\n}\n\nconst ALIGN_MAP = { start: 'start', center: 'center', end: 'end', stretch: 'stretch' } as const;\nconst JUSTIFY_MAP = { start: 'start', center: 'center', end: 'end', stretch: 'stretch' } as const;\n\nexport const Grid = forwardRef<HTMLElement, GridProps>(function Grid(props, ref) {\n const {\n as,\n gap = 4,\n rowGap,\n colGap,\n cols,\n rows,\n autoFlow,\n align,\n justify,\n children,\n className,\n style,\n ...rest\n } = props;\n\n const Tag = (as ?? 'div') as ElementType;\n const computedStyle: CSSProperties = {\n display: 'grid',\n gap: SPACE_VAR[gap],\n ...(rowGap !== undefined && { rowGap: SPACE_VAR[rowGap] }),\n ...(colGap !== undefined && { columnGap: SPACE_VAR[colGap] }),\n ...colsToStyle(cols),\n ...(rows !== undefined && { gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))` }),\n ...(autoFlow !== undefined && { gridAutoFlow: autoFlow }),\n ...(align !== undefined && { alignItems: ALIGN_MAP[align] }),\n ...(justify !== undefined && { justifyItems: JUSTIFY_MAP[justify] }),\n ...style,\n };\n\n return (\n <Tag ref={ref} className={cx('v8-grid', className)} style={computedStyle} {...rest}>\n {children}\n </Tag>\n );\n});"],"names":["SPACE_VAR","COLS_VAR","colsToStyle","cols","base","ALIGN_MAP","JUSTIFY_MAP","Grid","forwardRef","props","ref","as","gap","rowGap","colGap","rows","autoFlow","align","justify","children","className","style","rest","Tag","computedStyle","jsx","cx"],"mappings":"qFA4BA,MAAMA,EAA2D,CAC/D,EAAG,IACH,EAAG,iBACH,EAAG,iBACH,EAAG,iBACH,EAAG,iBACH,EAAG,iBACH,EAAG,iBACH,EAAG,iBACH,GAAI,kBACJ,GAAI,kBACJ,GAAI,iBACN,EAEMC,EAAmC,CACvC,EAAG,4BACH,EAAG,4BACH,EAAG,4BACH,EAAG,4BACH,EAAG,4BACH,EAAG,4BACH,EAAG,4BACH,GAAI,4BACN,EAEA,SAASC,EAAYC,EAA2C,CAC9D,GAAIA,IAAS,OAAW,MAAO,CAAA,EAC/B,GAAI,OAAOA,GAAS,SAAU,MAAO,CAAE,oBAAqBF,EAASE,CAAI,CAAA,EAKzE,MAAMC,EAAOD,EAAK,MAAQ,EAC1B,MAAO,CAAE,oBAAqBF,EAASG,CAAI,CAAA,CAC7C,CAEA,MAAMC,EAAY,CAAE,MAAO,QAAS,OAAQ,SAAU,IAAK,MAAO,QAAS,SAAA,EACrEC,EAAc,CAAE,MAAO,QAAS,OAAQ,SAAU,IAAK,MAAO,QAAS,SAAA,EAEhEC,EAAOC,EAAAA,WAAmC,SAAcC,EAAOC,EAAK,CAC/E,KAAM,CACJ,GAAAC,EACA,IAAAC,EAAM,EACN,OAAAC,EACA,OAAAC,EACA,KAAAX,EACA,KAAAY,EACA,SAAAC,EACA,MAAAC,EACA,QAAAC,EACA,SAAAC,EACA,UAAAC,EACA,MAAAC,EACA,GAAGC,CAAA,EACDb,EAEEc,EAAOZ,GAAM,MACba,EAA+B,CACnC,QAAS,OACT,IAAKxB,EAAUY,CAAG,EAClB,GAAIC,IAAW,QAAa,CAAE,OAAQb,EAAUa,CAAM,CAAA,EACtD,GAAIC,IAAW,QAAa,CAAE,UAAWd,EAAUc,CAAM,CAAA,EACzD,GAAGZ,EAAYC,CAAI,EACnB,GAAIY,IAAS,QAAa,CAAE,iBAAkB,UAAUA,CAAI,mBAAA,EAC5D,GAAIC,IAAa,QAAa,CAAE,aAAcA,CAAA,EAC9C,GAAIC,IAAU,QAAa,CAAE,WAAYZ,EAAUY,CAAK,CAAA,EACxD,GAAIC,IAAY,QAAa,CAAE,aAAcZ,EAAYY,CAAO,CAAA,EAChE,GAAGG,CAAA,EAGL,OACEI,EAAAA,IAACF,EAAA,CAAI,IAAAb,EAAU,UAAWgB,EAAG,UAAWN,CAAS,EAAG,MAAOI,EAAgB,GAAGF,EAC3E,SAAAH,CAAA,CACH,CAEJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as a,j as e}from"./cmdk-C3F6LD6N.js";import{u as x,a as y,S as f,
|
|
1
|
+
import{r as a,j as e}from"./cmdk-C3F6LD6N.js";import{u as x,a as y,S as f,B as g,I as v,h,Q as b,b as k}from"./main-BRmJZcHt.js";import{V as w}from"./ViewHeader-BsnaspKw.js";import{C,b as S}from"./Card-Clkvh43Q.js";import{E as F}from"./EmptyState-ccT__JZG.js";import{E as M}from"./ErrorState-BSqf65ka.js";import{R}from"./refresh-ccw-DN_zCB1h.js";import"./Alert-pzFISNtS.js";import"./circle-alert-QQTU4Quz.js";import"./triangle-alert-BeY8LAv6.js";import"./circle-check-BMbe7Kkr.js";function E(i){if(!i)return"";const r=new Date(i).getTime();if(!Number.isFinite(r))return"";const s=Math.max(0,Date.now()-r);return s<6e4?"just now":s<36e5?`${Math.round(s/6e4)}m ago`:s<864e5?`${Math.round(s/36e5)}h ago`:new Date(r).toLocaleString()}function K(){const i=x("/api/history"),[r,s]=a.useState(null),[o,p]=a.useState(null),c=a.useCallback(()=>{i.refetch()},[i]);y("history:new",c);const l=a.useMemo(()=>{var t;return((t=i.data)==null?void 0:t.events)??[]},[i.data]),m=a.useMemo(()=>{var t;return((t=i.data)==null?void 0:t.projects)??[]},[i.data]),u=a.useMemo(()=>{const t=new Set;for(const n of l)n.kind&&t.add(n.kind);return Array.from(t).sort()},[l]);a.useEffect(()=>{r!==null&&!u.includes(r)&&s(null)},[u,r]);const j=a.useMemo(()=>l.filter(t=>!(r!==null&&t.kind!==r||o!==null&&t.project!==o)),[l,r,o]);return e.jsxs(f,{gap:4,"data-testid":"history-view",children:[e.jsx(w,{title:"History",description:"Cross-project activity timeline. Filter by kind or project. Live updates on new events.",actions:e.jsxs(g,{variant:"ghost",onClick:()=>void c(),"data-testid":"history-refresh",children:[e.jsx(R,{size:14,"aria-hidden":!0})," Refresh"]})}),e.jsxs(v,{gap:2,wrap:!0,children:[e.jsx(d,{label:"All kinds",active:r===null,onClick:()=>s(null),testid:"history-filter-kind-all"}),u.map(t=>e.jsx(d,{label:t,active:r===t,onClick:()=>s(n=>n===t?null:t),testid:`history-filter-kind-${t}`},t)),m.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{style:{width:1,alignSelf:"stretch",background:"var(--border)"},"aria-hidden":!0}),e.jsx(d,{label:"All projects",active:o===null,onClick:()=>p(null),testid:"history-filter-project-all"}),m.map(t=>e.jsx(d,{label:t.name||t.id,active:o===t.id,onClick:()=>p(n=>n===t.id?null:t.id),testid:`history-filter-project-${t.id}`},t.id))]})]}),e.jsx(C,{variant:"default",children:e.jsx(S,{children:i.loading&&l.length===0?e.jsxs(f,{gap:2,children:[e.jsx(h,{style:{height:36}}),e.jsx(h,{style:{height:36}}),e.jsx(h,{style:{height:36}})]}):i.error&&l.length===0?e.jsx(M,{block:!0,title:"Couldn't load history",description:"The timeline endpoint failed. Retry to refetch.",error:i.error,onRetry:c,testid:"history-error"}):j.length===0?e.jsx(F,{icon:e.jsx(b,{size:28,"aria-hidden":!0}),title:"No events",description:r||o?"No events match the current filter.":"No activity yet."}):e.jsx(f,{gap:1,children:j.map((t,n)=>e.jsxs("div",{"data-testid":`history-row-${n}`,style:{display:"grid",gridTemplateColumns:"120px 1fr",gap:"var(--space-3)",padding:"var(--space-2)",borderBottom:"1px solid var(--border)"},children:[e.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:E(t.ts)}),e.jsxs(v,{align:"center",gap:2,wrap:!0,children:[t.kind&&e.jsx(k,{tone:"info",size:"sm",children:t.kind}),e.jsx("span",{children:t.title||t.description||t.id||"event"}),t.project&&e.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:["· ",t.project]})]})]},t.id??`${t.ts}-${n}`))})})})]})}function d({label:i,active:r,onClick:s,testid:o}){return e.jsx("button",{type:"button",onClick:s,"data-testid":o,style:{padding:"var(--space-1) var(--space-3)",borderRadius:"var(--radius-pill)",border:"1px solid var(--border)",background:r?"color-mix(in oklch, var(--accent) 18%, transparent)":"var(--surface-0)",color:r?"var(--accent)":"var(--fg-muted)",fontSize:"var(--fs-12)",cursor:"pointer"},children:i})}export{K as HistoryView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HistoryView-Cn2cPiHZ.js","sources":["../../src/web/v8/views/History/HistoryView.tsx"],"sourcesContent":["/**\n * v8/views/History/HistoryView.tsx — Sprint S40, v9.3.0.\n *\n * Cross-project timeline surface. Pulls from /api/history and shows\n * a list of recent events grouped per project. Filter chips along\n * the top let the user narrow by kind. Live updates on the\n * `history:new` WS event the server broadcasts.\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { History, RefreshCcw } 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 { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { Badge } from '../../ui/data/Badge.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\n\ninterface HistoryProject {\n id: string;\n name?: string;\n path?: string;\n active?: boolean;\n tasks?: { total: number; done: number; doing: number; blocked: number; queued: number };\n plans?: number;\n}\n\ninterface HistoryEventRow {\n id?: string;\n ts?: string;\n kind?: string;\n project?: string;\n agent?: string;\n title?: string;\n description?: string;\n}\n\ninterface HistoryPayload {\n events: HistoryEventRow[];\n projects: HistoryProject[];\n stats?: Record<string, unknown>;\n generatedAt?: string;\n}\n\nfunction fmtRel(ts: string | undefined): string {\n if (!ts) return '';\n const t = new Date(ts).getTime();\n if (!Number.isFinite(t)) return '';\n const delta = Math.max(0, Date.now() - t);\n if (delta < 60_000) return 'just now';\n if (delta < 3_600_000) return `${Math.round(delta / 60_000)}m ago`;\n if (delta < 86_400_000) return `${Math.round(delta / 3_600_000)}h ago`;\n return new Date(t).toLocaleString();\n}\n\nexport function HistoryView(): JSX.Element {\n const payload = useFetch<HistoryPayload>('/api/history');\n const [kindFilter, setKindFilter] = useState<string | null>(null);\n const [projectFilter, setProjectFilter] = useState<string | null>(null);\n\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n useWsMessage('history:new', refresh);\n\n const events = useMemo(() => payload.data?.events ?? [], [payload.data]);\n const projects = useMemo(() => payload.data?.projects ?? [], [payload.data]);\n const kinds = useMemo(() => {\n const set = new Set<string>();\n for (const e of events) if (e.kind) set.add(e.kind);\n return Array.from(set).sort();\n }, [events]);\n\n useEffect(() => {\n if (kindFilter !== null && !kinds.includes(kindFilter)) setKindFilter(null);\n }, [kinds, kindFilter]);\n\n const filtered = useMemo(() => {\n return events.filter((e) => {\n if (kindFilter !== null && e.kind !== kindFilter) return false;\n if (projectFilter !== null && e.project !== projectFilter) return false;\n return true;\n });\n }, [events, kindFilter, projectFilter]);\n\n return (\n <Stack gap={4} data-testid=\"history-view\">\n <ViewHeader\n title=\"History\"\n description=\"Cross-project activity timeline. Filter by kind or project. Live updates on new events.\"\n actions={\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"history-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n }\n />\n\n <Inline gap={2} wrap>\n <FilterChip\n label=\"All kinds\"\n active={kindFilter === null}\n onClick={() => setKindFilter(null)}\n testid=\"history-filter-kind-all\"\n />\n {kinds.map((k) => (\n <FilterChip\n key={k}\n label={k}\n active={kindFilter === k}\n onClick={() => setKindFilter((cur) => (cur === k ? null : k))}\n testid={`history-filter-kind-${k}`}\n />\n ))}\n {projects.length > 0 && (\n <>\n <span style={{ width: 1, alignSelf: 'stretch', background: 'var(--border)' }} aria-hidden />\n <FilterChip\n label=\"All projects\"\n active={projectFilter === null}\n onClick={() => setProjectFilter(null)}\n testid=\"history-filter-project-all\"\n />\n {projects.map((p) => (\n <FilterChip\n key={p.id}\n label={p.name || p.id}\n active={projectFilter === p.id}\n onClick={() => setProjectFilter((cur) => (cur === p.id ? null : p.id))}\n testid={`history-filter-project-${p.id}`}\n />\n ))}\n </>\n )}\n </Inline>\n\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && events.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 36 }} />\n <Skeleton style={{ height: 36 }} />\n <Skeleton style={{ height: 36 }} />\n </Stack>\n ) : payload.error && events.length === 0 ? (\n <ErrorState\n block\n title=\"Couldn't load history\"\n description=\"The timeline endpoint failed. Retry to refetch.\"\n error={payload.error}\n onRetry={refresh}\n testid=\"history-error\"\n />\n ) : filtered.length === 0 ? (\n <EmptyState\n icon={<History size={28} aria-hidden />}\n title=\"No events\"\n description={kindFilter || projectFilter ? 'No events match the current filter.' : 'No activity yet.'}\n />\n ) : (\n <Stack gap={1}>\n {filtered.map((e, idx) => (\n <div\n key={e.id ?? `${e.ts}-${idx}`}\n data-testid={`history-row-${idx}`}\n style={{\n display: 'grid',\n gridTemplateColumns: '120px 1fr',\n gap: 'var(--space-3)',\n padding: 'var(--space-2)',\n borderBottom: '1px solid var(--border)',\n }}\n >\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {fmtRel(e.ts)}\n </span>\n <Inline align=\"center\" gap={2} wrap>\n {e.kind && <Badge tone=\"info\" size=\"sm\">{e.kind}</Badge>}\n <span>{e.title || e.description || e.id || 'event'}</span>\n {e.project && (\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n · {e.project}\n </span>\n )}\n </Inline>\n </div>\n ))}\n </Stack>\n )}\n </CardBody>\n </Card>\n </Stack>\n );\n}\n\nfunction FilterChip({\n label,\n active,\n onClick,\n testid,\n}: {\n label: string;\n active: boolean;\n onClick: () => void;\n testid: string;\n}): JSX.Element {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n data-testid={testid}\n style={{\n padding: 'var(--space-1) var(--space-3)',\n borderRadius: 'var(--radius-pill)',\n border: '1px solid var(--border)',\n background: active ? 'color-mix(in oklch, var(--accent) 18%, transparent)' : 'var(--surface-0)',\n color: active ? 'var(--accent)' : 'var(--fg-muted)',\n fontSize: 'var(--fs-12)',\n cursor: 'pointer',\n }}\n >\n {label}\n </button>\n );\n}"],"names":["fmtRel","ts","t","delta","HistoryView","payload","useFetch","kindFilter","setKindFilter","useState","projectFilter","setProjectFilter","refresh","useCallback","useWsMessage","events","useMemo","_a","projects","kinds","set","e","useEffect","filtered","jsxs","Stack","jsx","ViewHeader","Button","RefreshCcw","Inline","FilterChip","k","cur","Fragment","p","Card","CardBody","Skeleton","ErrorState","EmptyState","History","idx","Badge","label","active","onClick","testid"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HistoryView-Bum2TMMw.js","sources":["../../src/web/v8/views/History/HistoryView.tsx"],"sourcesContent":["/**\n * v8/views/History/HistoryView.tsx — Sprint S40, v9.3.0.\n *\n * Cross-project timeline surface. Pulls from /api/history and shows\n * a list of recent events grouped per project. Filter chips along\n * the top let the user narrow by kind. Live updates on the\n * `history:new` WS event the server broadcasts.\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { History, RefreshCcw } 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 { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { Badge } from '../../ui/data/Badge.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\n\ninterface HistoryProject {\n id: string;\n name?: string;\n path?: string;\n active?: boolean;\n tasks?: { total: number; done: number; doing: number; blocked: number; queued: number };\n plans?: number;\n}\n\ninterface HistoryEventRow {\n id?: string;\n ts?: string;\n kind?: string;\n project?: string;\n agent?: string;\n title?: string;\n description?: string;\n}\n\ninterface HistoryPayload {\n events: HistoryEventRow[];\n projects: HistoryProject[];\n stats?: Record<string, unknown>;\n generatedAt?: string;\n}\n\nfunction fmtRel(ts: string | undefined): string {\n if (!ts) return '';\n const t = new Date(ts).getTime();\n if (!Number.isFinite(t)) return '';\n const delta = Math.max(0, Date.now() - t);\n if (delta < 60_000) return 'just now';\n if (delta < 3_600_000) return `${Math.round(delta / 60_000)}m ago`;\n if (delta < 86_400_000) return `${Math.round(delta / 3_600_000)}h ago`;\n return new Date(t).toLocaleString();\n}\n\nexport function HistoryView(): JSX.Element {\n const payload = useFetch<HistoryPayload>('/api/history');\n const [kindFilter, setKindFilter] = useState<string | null>(null);\n const [projectFilter, setProjectFilter] = useState<string | null>(null);\n\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n useWsMessage('history:new', refresh);\n\n const events = useMemo(() => payload.data?.events ?? [], [payload.data]);\n const projects = useMemo(() => payload.data?.projects ?? [], [payload.data]);\n const kinds = useMemo(() => {\n const set = new Set<string>();\n for (const e of events) if (e.kind) set.add(e.kind);\n return Array.from(set).sort();\n }, [events]);\n\n useEffect(() => {\n if (kindFilter !== null && !kinds.includes(kindFilter)) setKindFilter(null);\n }, [kinds, kindFilter]);\n\n const filtered = useMemo(() => {\n return events.filter((e) => {\n if (kindFilter !== null && e.kind !== kindFilter) return false;\n if (projectFilter !== null && e.project !== projectFilter) return false;\n return true;\n });\n }, [events, kindFilter, projectFilter]);\n\n return (\n <Stack gap={4} data-testid=\"history-view\">\n <ViewHeader\n title=\"History\"\n description=\"Cross-project activity timeline. Filter by kind or project. Live updates on new events.\"\n actions={\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"history-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n }\n />\n\n <Inline gap={2} wrap>\n <FilterChip\n label=\"All kinds\"\n active={kindFilter === null}\n onClick={() => setKindFilter(null)}\n testid=\"history-filter-kind-all\"\n />\n {kinds.map((k) => (\n <FilterChip\n key={k}\n label={k}\n active={kindFilter === k}\n onClick={() => setKindFilter((cur) => (cur === k ? null : k))}\n testid={`history-filter-kind-${k}`}\n />\n ))}\n {projects.length > 0 && (\n <>\n <span style={{ width: 1, alignSelf: 'stretch', background: 'var(--border)' }} aria-hidden />\n <FilterChip\n label=\"All projects\"\n active={projectFilter === null}\n onClick={() => setProjectFilter(null)}\n testid=\"history-filter-project-all\"\n />\n {projects.map((p) => (\n <FilterChip\n key={p.id}\n label={p.name || p.id}\n active={projectFilter === p.id}\n onClick={() => setProjectFilter((cur) => (cur === p.id ? null : p.id))}\n testid={`history-filter-project-${p.id}`}\n />\n ))}\n </>\n )}\n </Inline>\n\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && events.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 36 }} />\n <Skeleton style={{ height: 36 }} />\n <Skeleton style={{ height: 36 }} />\n </Stack>\n ) : payload.error && events.length === 0 ? (\n <ErrorState\n block\n title=\"Couldn't load history\"\n description=\"The timeline endpoint failed. Retry to refetch.\"\n error={payload.error}\n onRetry={refresh}\n testid=\"history-error\"\n />\n ) : filtered.length === 0 ? (\n <EmptyState\n icon={<History size={28} aria-hidden />}\n title=\"No events\"\n description={kindFilter || projectFilter ? 'No events match the current filter.' : 'No activity yet.'}\n />\n ) : (\n <Stack gap={1}>\n {filtered.map((e, idx) => (\n <div\n key={e.id ?? `${e.ts}-${idx}`}\n data-testid={`history-row-${idx}`}\n style={{\n display: 'grid',\n gridTemplateColumns: '120px 1fr',\n gap: 'var(--space-3)',\n padding: 'var(--space-2)',\n borderBottom: '1px solid var(--border)',\n }}\n >\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {fmtRel(e.ts)}\n </span>\n <Inline align=\"center\" gap={2} wrap>\n {e.kind && <Badge tone=\"info\" size=\"sm\">{e.kind}</Badge>}\n <span>{e.title || e.description || e.id || 'event'}</span>\n {e.project && (\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n · {e.project}\n </span>\n )}\n </Inline>\n </div>\n ))}\n </Stack>\n )}\n </CardBody>\n </Card>\n </Stack>\n );\n}\n\nfunction FilterChip({\n label,\n active,\n onClick,\n testid,\n}: {\n label: string;\n active: boolean;\n onClick: () => void;\n testid: string;\n}): JSX.Element {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n data-testid={testid}\n style={{\n padding: 'var(--space-1) var(--space-3)',\n borderRadius: 'var(--radius-pill)',\n border: '1px solid var(--border)',\n background: active ? 'color-mix(in oklch, var(--accent) 18%, transparent)' : 'var(--surface-0)',\n color: active ? 'var(--accent)' : 'var(--fg-muted)',\n fontSize: 'var(--fs-12)',\n cursor: 'pointer',\n }}\n >\n {label}\n </button>\n );\n}"],"names":["fmtRel","ts","t","delta","HistoryView","payload","useFetch","kindFilter","setKindFilter","useState","projectFilter","setProjectFilter","refresh","useCallback","useWsMessage","events","useMemo","_a","projects","kinds","set","e","useEffect","filtered","jsxs","Stack","jsx","ViewHeader","Button","RefreshCcw","Inline","FilterChip","k","cur","Fragment","p","Card","CardBody","Skeleton","ErrorState","EmptyState","History","idx","Badge","label","active","onClick","testid"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as c,j as s}from"./cmdk-C3F6LD6N.js";import{g as x}from"./main-
|
|
1
|
+
import{r as c,j as s}from"./cmdk-C3F6LD6N.js";import{g as x}from"./main-BRmJZcHt.js";const h={sm:{h:28,fs:"var(--fs-12)",px:10},md:{h:32,fs:"var(--fs-13)",px:12},lg:{h:40,fs:"var(--fs-14)",px:14}},y=c.forwardRef(function(o,n){const{size:l="md",variant:r="default",invalid:a,leftAddon:t,rightAddon:d,disabled:i,className:p,style:f,...u}=o,e=h[l],v={display:"inline-flex",alignItems:"center",gap:"var(--space-2)",width:"100%",height:e.h,paddingLeft:r==="flushed"?0:e.px,paddingRight:r==="flushed"?0:e.px,background:r==="filled"?"var(--surface-2)":r==="flushed"?"transparent":"var(--input-bg)",border:r==="flushed"?"none":"1px solid",borderBottom:r==="flushed"?"1px solid var(--border)":void 0,borderColor:a===!0?"var(--danger)":"var(--border)",borderRadius:r==="flushed"?0:"var(--radius-sm)",opacity:i===!0?.55:1,transition:"border-color var(--motion-fast) var(--ease-out)",...f};return s.jsxs("div",{className:x("v8-input-wrap",p),style:v,children:[t!==void 0&&s.jsx("span",{style:{color:"var(--fg-muted)",display:"inline-flex"},children:t}),s.jsx("input",{ref:n,disabled:i,"aria-invalid":a===!0?"true":void 0,className:"v8-input",style:{flex:1,minWidth:0,background:"transparent",border:0,outline:0,fontSize:e.fs,color:"var(--fg)"},...u}),d!==void 0&&s.jsx("span",{style:{color:"var(--fg-muted)",display:"inline-flex"},children:d})]})});export{y as I};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input-
|
|
1
|
+
{"version":3,"file":"Input-DV-vdaV8.js","sources":["../../src/web/v8/ui/controls/Input.tsx"],"sourcesContent":["import { forwardRef, type InputHTMLAttributes, type ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * Input — single-line text input.\n *\n * Variants:\n * - default: bordered, surface-1 background\n * - filled: surface-2 background, no visible border until focus\n * - flushed: no border except a bottom rule (used inside cards/forms)\n *\n * Pair with <Field> for label + hint + error.\n */\nexport type InputSize = 'sm' | 'md' | 'lg';\nexport type InputVariant = 'default' | 'filled' | 'flushed';\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\n size?: InputSize;\n variant?: InputVariant;\n invalid?: boolean;\n leftAddon?: ReactNode;\n rightAddon?: ReactNode;\n}\n\nconst SIZE: Record<InputSize, { h: number; fs: string; px: number }> = {\n sm: { h: 28, fs: 'var(--fs-12)', px: 10 },\n md: { h: 32, fs: 'var(--fs-13)', px: 12 },\n lg: { h: 40, fs: 'var(--fs-14)', px: 14 },\n};\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(props, ref) {\n const {\n size = 'md',\n variant = 'default',\n invalid,\n leftAddon,\n rightAddon,\n disabled,\n className,\n style,\n ...rest\n } = props;\n const sz = SIZE[size];\n\n const wrapperStyle = {\n display: 'inline-flex',\n alignItems: 'center',\n gap: 'var(--space-2)',\n width: '100%',\n height: sz.h,\n paddingLeft: variant === 'flushed' ? 0 : sz.px,\n paddingRight: variant === 'flushed' ? 0 : sz.px,\n background:\n variant === 'filled'\n ? 'var(--surface-2)'\n : variant === 'flushed'\n ? 'transparent'\n : 'var(--input-bg)',\n border: variant === 'flushed' ? 'none' : '1px solid',\n borderBottom: variant === 'flushed' ? '1px solid var(--border)' : undefined,\n borderColor: invalid === true ? 'var(--danger)' : 'var(--border)',\n borderRadius: variant === 'flushed' ? 0 : 'var(--radius-sm)',\n opacity: disabled === true ? 0.55 : 1,\n transition: 'border-color var(--motion-fast) var(--ease-out)',\n ...style,\n } as const;\n\n return (\n <div className={cx('v8-input-wrap', className)} style={wrapperStyle}>\n {leftAddon !== undefined && (\n <span style={{ color: 'var(--fg-muted)', display: 'inline-flex' }}>{leftAddon}</span>\n )}\n <input\n ref={ref}\n disabled={disabled}\n aria-invalid={invalid === true ? 'true' : undefined}\n className=\"v8-input\"\n style={{\n flex: 1,\n minWidth: 0,\n background: 'transparent',\n border: 0,\n outline: 0,\n fontSize: sz.fs,\n color: 'var(--fg)',\n }}\n {...rest}\n />\n {rightAddon !== undefined && (\n <span style={{ color: 'var(--fg-muted)', display: 'inline-flex' }}>{rightAddon}</span>\n )}\n </div>\n );\n});"],"names":["SIZE","Input","forwardRef","props","ref","size","variant","invalid","leftAddon","rightAddon","disabled","className","style","rest","sz","wrapperStyle","jsxs","cx","jsx"],"mappings":"qFAwBA,MAAMA,EAAiE,CACrE,GAAI,CAAE,EAAG,GAAI,GAAI,eAAgB,GAAI,EAAA,EACrC,GAAI,CAAE,EAAG,GAAI,GAAI,eAAgB,GAAI,EAAA,EACrC,GAAI,CAAE,EAAG,GAAI,GAAI,eAAgB,GAAI,EAAA,CACvC,EAEaC,EAAQC,EAAAA,WAAyC,SAAeC,EAAOC,EAAK,CACvF,KAAM,CACJ,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,QAAAC,EACA,UAAAC,EACA,WAAAC,EACA,SAAAC,EACA,UAAAC,EACA,MAAAC,EACA,GAAGC,CAAA,EACDV,EACEW,EAAKd,EAAKK,CAAI,EAEdU,EAAe,CACnB,QAAS,cACT,WAAY,SACZ,IAAK,iBACL,MAAO,OACP,OAAQD,EAAG,EACX,YAAaR,IAAY,UAAY,EAAIQ,EAAG,GAC5C,aAAcR,IAAY,UAAY,EAAIQ,EAAG,GAC7C,WACER,IAAY,SACR,mBACAA,IAAY,UACV,cACA,kBACR,OAAQA,IAAY,UAAY,OAAS,YACzC,aAAcA,IAAY,UAAY,0BAA4B,OAClE,YAAaC,IAAY,GAAO,gBAAkB,gBAClD,aAAcD,IAAY,UAAY,EAAI,mBAC1C,QAASI,IAAa,GAAO,IAAO,EACpC,WAAY,kDACZ,GAAGE,CAAA,EAGL,OACEI,OAAC,OAAI,UAAWC,EAAG,gBAAiBN,CAAS,EAAG,MAAOI,EACpD,SAAA,CAAAP,IAAc,QACbU,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,MAAO,kBAAmB,QAAS,aAAA,EAAkB,SAAAV,CAAA,CAAU,EAEhFU,EAAAA,IAAC,QAAA,CACC,IAAAd,EACA,SAAAM,EACA,eAAcH,IAAY,GAAO,OAAS,OAC1C,UAAU,WACV,MAAO,CACL,KAAM,EACN,SAAU,EACV,WAAY,cACZ,OAAQ,EACR,QAAS,EACT,SAAUO,EAAG,GACb,MAAO,WAAA,EAER,GAAGD,CAAA,CAAA,EAELJ,IAAe,QACdS,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,MAAO,kBAAmB,QAAS,eAAkB,SAAAT,CAAA,CAAW,CAAA,EAEnF,CAEJ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{j as e,r as m}from"./cmdk-C3F6LD6N.js";import{b,g as f,u as x,a as k,S as y,h as j}from"./main-BRmJZcHt.js";import{C as S,V as E}from"./ViewHeader-BsnaspKw.js";import"./Grid-Bojq8Sg7.js";import"./AgentActivity-DBWDByjk.js";import"./Input-DV-vdaV8.js";import"./Textarea-BfXGMXQ7.js";import"./Switch-B79a2t-G.js";import"./Select-Bf_P0S6H.js";import"./Slider-AjjzqI-5.js";import"./Alert-pzFISNtS.js";import"./Banner-Du-3l05O.js";import{E as T}from"./EmptyState-ccT__JZG.js";import"./Sheet-BwMVGN-8.js";import"./Card-Clkvh43Q.js";import"./Chip-B7ovcm01.js";import"./Avatar-CRW81ewE.js";import"./ActivityFeed-Bw4Cai7r.js";import"./Sparkline-Z4y0YUZS.js";import"./ProgressBar-KC4VXsl_.js";import{P as C}from"./power-DEX4_Xoa.js";import"./SettingsRow-CJb-F94Y.js";import"./MessageBubble-CrCJ0SYG.js";import{E as N}from"./ErrorState-BSqf65ka.js";import"./dnd-kit-BAOLODOI.js";import"./plus-Cps-8lcG.js";import"./calendar-CAZoDd-l.js";import"./index-B1OIS316.js";import"./index-CR0TeJmc.js";import"./circle-alert-QQTU4Quz.js";import"./triangle-alert-BeY8LAv6.js";import"./circle-check-BMbe7Kkr.js";import"./trending-up-qKTUQKIT.js";import"./refresh-ccw-DN_zCB1h.js";const I={enabled:"Enabled",disabled:"Disabled",error:"Error"},L={enabled:"success",disabled:"neutral",error:"danger"};function w(s){const{name:t,slug:i,status:r,description:o,meta:l,actions:p,onOpen:c,className:n}=s;return e.jsxs("button",{type:"button",onClick:c,className:f("v8-library-item",`v8-library-item--${r}`,n),style:{display:"flex",alignItems:"flex-start",gap:"var(--space-3)",width:"100%",padding:"var(--space-3) var(--space-4)",background:"var(--surface-1)",border:"1px solid var(--border)",borderRadius:"var(--radius)",textAlign:"left",cursor:c!==void 0?"pointer":"default",font:"inherit",color:"inherit",transition:"border-color var(--motion-fast) var(--ease-out), background var(--motion-fast) var(--ease-out)"},children:[e.jsx("span",{"aria-hidden":"true",style:{display:"inline-flex",alignItems:"center",justifyContent:"center",width:28,height:28,marginTop:2,borderRadius:"var(--radius-sm)",background:r==="enabled"?"color-mix(in oklch, var(--success) 14%, transparent)":r==="error"?"color-mix(in oklch, var(--danger) 14%, transparent)":"var(--surface-2)",color:r==="enabled"?"var(--success)":r==="error"?"var(--danger)":"var(--fg-muted)",flexShrink:0},children:e.jsx(C,{size:14,"aria-hidden":"true"})}),e.jsxs("div",{style:{flex:1,minWidth:0},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--space-2)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-13)",fontWeight:600,color:"var(--fg)",lineHeight:"var(--lh-snug)"},children:t}),e.jsx("code",{style:{fontSize:"var(--fs-12)",color:"var(--fg-subtle)",fontFamily:"var(--font-mono, ui-monospace, monospace)"},children:i})]}),o!==void 0&&e.jsx("div",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)",marginTop:2,display:"-webkit-box",WebkitLineClamp:2,WebkitBoxOrient:"vertical",overflow:"hidden"},children:o}),e.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"var(--space-2)",marginTop:6},children:[l!==void 0?e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-subtle)"},children:l}):e.jsx("span",{}),e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--space-2)"},children:[e.jsx(b,{tone:L[r],size:"sm",children:I[r]}),p,e.jsx(S,{size:14,"aria-hidden":"true",style:{color:"var(--fg-subtle)"}})]})]})]}),e.jsx("style",{children:`
|
|
2
|
+
.v8-library-item:hover {
|
|
3
|
+
border-color: var(--accent);
|
|
4
|
+
background: var(--surface-2);
|
|
5
|
+
}
|
|
6
|
+
`})]})}function z(s){const{children:t,className:i}=s;return e.jsx("div",{className:f("v8-library-grid",i),style:{display:"grid",gridTemplateColumns:"repeat(auto-fill, minmax(min(100%, 320px), 1fr))",gap:"var(--space-3)"},children:t})}const d={skills:"Skills",mcps:"MCPs",hooks:"Hooks"},A={skills:"Bizar skill packs. Auto-loaded by name or dispatched via the Skill tool.",mcps:"MCP server registrations under `.claude/settings.json` → `mcpServers`.",hooks:"Executable hook scripts (PreToolUse / PostToolUse / SessionStart / SessionEnd)."},P={skills:"/api/skills",mcps:"/api/skills?kind=mcps",hooks:"/api/skills?kind=hooks"},R={skills:["skills:change","agents:change"],mcps:["mcps:change","agents:change"],hooks:["hooks:change","agents:change"]},B=["skills:change","mcps:change","hooks:change","agents:change"];function _(s){const t=s.status==="enabled"||s.status==="disabled"||s.status==="error"?s.status:"disabled";return{id:s.id,name:s.name,slug:s.slug??s.id,status:t,description:s.description,meta:s.meta}}function ve(s){var u,h;const{kind:t}=s,i=P[t],r=x(i),[o,l]=m.useState(0),p=R[t],c=m.useCallback(()=>l(a=>a+1),[]);for(const a of B)k(a,p.includes(a)?c:()=>{});m.useEffect(()=>{o>0&&r.refetch()},[o,r]);const n=(((u=r.data)==null?void 0:u.skills)||((h=r.data)==null?void 0:h.items)||[]).map(_).reduce((a,g)=>(a.some(v=>v.name===g.name)||a.push(g),a),[]);return e.jsxs(y,{gap:5,"data-testid":`${t}-view`,children:[e.jsx(E,{title:d[t],description:A[t]}),r.loading?e.jsx(j,{style:{height:240}}):r.error&&n.length===0?e.jsx(N,{block:!0,title:`Couldn't load ${d[t].toLowerCase()}`,description:"The library endpoint failed. Retry to refetch.",error:r.error,onRetry:()=>void r.refetch(),testid:`libraries-${t}-error`}):n.length===0?e.jsx(T,{icon:e.jsx("span",{children:"📚"}),title:`No ${d[t].toLowerCase()} installed`,description:`${d[t]} appear here as soon as they are registered.`}):e.jsx(z,{children:n.map(a=>e.jsx(w,{...a},a.id))})]})}export{ve as LibrariesView};
|
package/bizar-dash/dist/assets/{LibrariesView-Ca_PRjUm.js.map → LibrariesView-DH2E2uNb.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LibrariesView-Ca_PRjUm.js","sources":["../../src/web/v8/ui/libraries/LibraryItem.tsx","../../src/web/v8/ui/libraries/LibraryGrid.tsx","../../src/web/v8/views/Libraries/LibrariesView.tsx"],"sourcesContent":["import { type ReactNode } from 'react';\nimport { ChevronRight, Power } from 'lucide-react';\nimport { cx } from '../utils/cx.js';\nimport { Badge, type BadgeTone } from '../data/Badge.js';\n\n/**\n * LibraryItem — generic inventory card used by the Skill/MCP/Hook libraries.\n *\n * PLAN.md: each \"library\" lists the same three facts about an installable\n * resource: identity (name + slug), status (enabled/disabled/error), and\n * provenance (description, version, last-used, owner). LibraryItem renders\n * those facts consistently so all three libraries feel like one product.\n */\n\nexport type LibraryStatus = 'enabled' | 'disabled' | 'error';\n\nexport interface LibraryItemProps {\n id: string;\n /** Display name (e.g. \"Frigg — Codebase Q&A\"). */\n name: string;\n /** Identifier (e.g. \"frigg\", \"semble\", \"PreToolUse:check-arch\"). */\n slug: string;\n status: LibraryStatus;\n description?: string;\n /** One-line metadata row (e.g. \"v1.2.0 · used 14× today · @anthropic\"). */\n meta?: string;\n /** Optional trailing action area (toggle, menu trigger, etc). */\n actions?: ReactNode;\n /** Click handler — opens detail. */\n onOpen?: () => void;\n className?: string;\n}\n\nconst STATUS_LABEL: Record<LibraryStatus, string> = {\n enabled: 'Enabled',\n disabled: 'Disabled',\n error: 'Error',\n};\n\nconst STATUS_TONE: Record<LibraryStatus, BadgeTone> = {\n enabled: 'success',\n disabled: 'neutral',\n error: 'danger',\n};\n\nexport function LibraryItem(props: LibraryItemProps) {\n const { name, slug, status, description, meta, actions, onOpen, className } = props;\n\n return (\n <button\n type=\"button\"\n onClick={onOpen}\n className={cx('v8-library-item', `v8-library-item--${status}`, className)}\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 'var(--space-3)',\n width: '100%',\n padding: 'var(--space-3) var(--space-4)',\n background: 'var(--surface-1)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius)',\n textAlign: 'left',\n cursor: onOpen !== undefined ? 'pointer' : 'default',\n font: 'inherit',\n color: 'inherit',\n transition: 'border-color var(--motion-fast) var(--ease-out), background var(--motion-fast) var(--ease-out)',\n }}\n >\n <span\n aria-hidden=\"true\"\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 28,\n height: 28,\n marginTop: 2,\n borderRadius: 'var(--radius-sm)',\n background:\n status === 'enabled'\n ? 'color-mix(in oklch, var(--success) 14%, transparent)'\n : status === 'error'\n ? 'color-mix(in oklch, var(--danger) 14%, transparent)'\n : 'var(--surface-2)',\n color:\n status === 'enabled' ? 'var(--success)' : status === 'error' ? 'var(--danger)' : 'var(--fg-muted)',\n flexShrink: 0,\n }}\n >\n <Power size={14} aria-hidden=\"true\" />\n </span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>\n <span\n style={{\n fontSize: 'var(--fs-13)',\n fontWeight: 600,\n color: 'var(--fg)',\n lineHeight: 'var(--lh-snug)',\n }}\n >\n {name}\n </span>\n <code\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-subtle)',\n fontFamily: 'var(--font-mono, ui-monospace, monospace)',\n }}\n >\n {slug}\n </code>\n </div>\n {description !== undefined && (\n <div\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-muted)',\n marginTop: 2,\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {description}\n </div>\n )}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 'var(--space-2)',\n marginTop: 6,\n }}\n >\n {meta !== undefined ? (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>{meta}</span>\n ) : (\n <span />\n )}\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>\n <Badge tone={STATUS_TONE[status]} size=\"sm\">\n {STATUS_LABEL[status]}\n </Badge>\n {actions}\n <ChevronRight size={14} aria-hidden=\"true\" style={{ color: 'var(--fg-subtle)' }} />\n </div>\n </div>\n </div>\n <style>{`\n .v8-library-item:hover {\n border-color: var(--accent);\n background: var(--surface-2);\n }\n `}</style>\n </button>\n );\n}","import { type ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * LibraryGrid — responsive grid for LibraryItem lists.\n *\n * Renders 1 column on narrow viewports, 2 columns on md, 3 columns on lg.\n * Uses CSS grid + auto-fit; items auto-size to fill available space.\n */\n\nexport interface LibraryGridProps {\n children: ReactNode;\n className?: string;\n}\n\nexport function LibraryGrid(props: LibraryGridProps) {\n const { children, className } = props;\n return (\n <div\n className={cx('v8-library-grid', className)}\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(min(100%, 320px), 1fr))',\n gap: 'var(--space-3)',\n }}\n >\n {children}\n </div>\n );\n}","import { useEffect, useState, useCallback } from 'react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { LibraryGrid, LibraryItem, type LibraryItemProps, type LibraryStatus } from '../../ui/index.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport type { LibraryItem as LibItem } from '../../data/types.js';\n\n/**\n * LibrariesView — Sprint S10. Generic Skills / MCPs / Hooks surface.\n *\n * The parent (`Router.tsx`) picks the data source per kind. This\n * view pulls live data from `/api/skills`, `/api/mcps`,\n * `/api/hooks` instead of seeded arrays.\n */\n\nexport type LibraryKind = 'skills' | 'mcps' | 'hooks';\n\nconst KIND_LABEL: Record<LibraryKind, string> = {\n skills: 'Skills',\n mcps: 'MCPs',\n hooks: 'Hooks',\n};\n\nconst KIND_DESCRIPTION: Record<LibraryKind, string> = {\n skills: 'Bizar skill packs. Auto-loaded by name or dispatched via the Skill tool.',\n mcps: 'MCP server registrations under `.claude/settings.json` → `mcpServers`.',\n hooks: 'Executable hook scripts (PreToolUse / PostToolUse / SessionStart / SessionEnd).',\n};\n\nconst ENDPOINT: Record<LibraryKind, string> = {\n skills: '/api/skills',\n mcps: '/api/skills?kind=mcps',\n hooks: '/api/skills?kind=hooks',\n};\n\nconst CHANGE_EVENTS: Record<LibraryKind, readonly string[]> = {\n skills: ['skills:change', 'agents:change'] as const,\n mcps: ['mcps:change', 'agents:change'] as const,\n hooks: ['hooks:change', 'agents:change'] as const,\n};\n// Stable hook count: always register listeners for all possible events,\n// filter inside the handler so kind navigation never changes hook order.\nconst ALL_EVENTS = ['skills:change', 'mcps:change', 'hooks:change', 'agents:change'] as const;\n\nfunction mapItem(it: LibItem): LibraryItemProps {\n const status: LibraryStatus =\n it.status === 'enabled' || it.status === 'disabled' || it.status === 'error'\n ? it.status\n : 'disabled';\n return {\n id: it.id,\n name: it.name,\n slug: it.slug ?? it.id,\n status,\n description: it.description,\n meta: it.meta,\n };\n}\n\nexport interface LibrariesViewProps {\n kind: LibraryKind;\n}\n\nexport function LibrariesView(props: LibrariesViewProps): JSX.Element {\n const { kind } = props;\n const url = ENDPOINT[kind];\n const res = useFetch<{ skills?: LibItem[]; items?: LibItem[]; count?: number }>(url);\n const [bust, setBust] = useState(0);\n\n // Force a re-fetch when the matching change event fires. Hook count\n // is fixed (ALL_EVENTS.length) so navigating between kinds can't trip\n // React's \"Rendered fewer hooks than expected\" runtime guard.\n const events = CHANGE_EVENTS[kind];\n const handler = useCallback((): void => setBust((n) => n + 1), []);\n for (const evt of ALL_EVENTS) {\n useWsMessage(evt, events.includes(evt) ? handler : () => {});\n }\n\n useEffect(() => {\n if (bust > 0) res.refetch();\n }, [bust, res]);\n\n const items: LibraryItemProps[] = (res.data?.skills || res.data?.items || [])\n .map(mapItem)\n .reduce<LibraryItemProps[]>((acc, item) => {\n if (!acc.some((existing) => existing.name === item.name)) acc.push(item);\n return acc;\n }, []);\n\n return (\n <Stack gap={5} data-testid={`${kind}-view`}>\n <ViewHeader title={KIND_LABEL[kind]} description={KIND_DESCRIPTION[kind]} />\n {res.loading ? (\n <Skeleton style={{ height: 240 }} />\n ) : res.error && items.length === 0 ? (\n <ErrorState\n block\n title={`Couldn't load ${KIND_LABEL[kind].toLowerCase()}`}\n description=\"The library endpoint failed. Retry to refetch.\"\n error={res.error}\n onRetry={() => void res.refetch()}\n testid={`libraries-${kind}-error`}\n />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<span>📚</span>}\n title={`No ${KIND_LABEL[kind].toLowerCase()} installed`}\n description={`${KIND_LABEL[kind]} appear here as soon as they are registered.`}\n />\n ) : (\n <LibraryGrid>\n {items.map((item) => (\n <LibraryItem key={item.id} {...item} />\n ))}\n </LibraryGrid>\n )}\n </Stack>\n );\n}"],"names":["STATUS_LABEL","STATUS_TONE","LibraryItem","props","name","slug","status","description","meta","actions","onOpen","className","jsxs","cx","jsx","Power","Badge","ChevronRight","LibraryGrid","children","KIND_LABEL","KIND_DESCRIPTION","ENDPOINT","CHANGE_EVENTS","ALL_EVENTS","mapItem","it","LibrariesView","kind","url","res","useFetch","bust","setBust","useState","events","handler","useCallback","n","evt","useWsMessage","useEffect","items","_a","_b","acc","item","existing","Stack","ViewHeader","Skeleton","ErrorState","EmptyState"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LibrariesView-DH2E2uNb.js","sources":["../../src/web/v8/ui/libraries/LibraryItem.tsx","../../src/web/v8/ui/libraries/LibraryGrid.tsx","../../src/web/v8/views/Libraries/LibrariesView.tsx"],"sourcesContent":["import { type ReactNode } from 'react';\nimport { ChevronRight, Power } from 'lucide-react';\nimport { cx } from '../utils/cx.js';\nimport { Badge, type BadgeTone } from '../data/Badge.js';\n\n/**\n * LibraryItem — generic inventory card used by the Skill/MCP/Hook libraries.\n *\n * PLAN.md: each \"library\" lists the same three facts about an installable\n * resource: identity (name + slug), status (enabled/disabled/error), and\n * provenance (description, version, last-used, owner). LibraryItem renders\n * those facts consistently so all three libraries feel like one product.\n */\n\nexport type LibraryStatus = 'enabled' | 'disabled' | 'error';\n\nexport interface LibraryItemProps {\n id: string;\n /** Display name (e.g. \"Frigg — Codebase Q&A\"). */\n name: string;\n /** Identifier (e.g. \"frigg\", \"semble\", \"PreToolUse:check-arch\"). */\n slug: string;\n status: LibraryStatus;\n description?: string;\n /** One-line metadata row (e.g. \"v1.2.0 · used 14× today · @anthropic\"). */\n meta?: string;\n /** Optional trailing action area (toggle, menu trigger, etc). */\n actions?: ReactNode;\n /** Click handler — opens detail. */\n onOpen?: () => void;\n className?: string;\n}\n\nconst STATUS_LABEL: Record<LibraryStatus, string> = {\n enabled: 'Enabled',\n disabled: 'Disabled',\n error: 'Error',\n};\n\nconst STATUS_TONE: Record<LibraryStatus, BadgeTone> = {\n enabled: 'success',\n disabled: 'neutral',\n error: 'danger',\n};\n\nexport function LibraryItem(props: LibraryItemProps) {\n const { name, slug, status, description, meta, actions, onOpen, className } = props;\n\n return (\n <button\n type=\"button\"\n onClick={onOpen}\n className={cx('v8-library-item', `v8-library-item--${status}`, className)}\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 'var(--space-3)',\n width: '100%',\n padding: 'var(--space-3) var(--space-4)',\n background: 'var(--surface-1)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius)',\n textAlign: 'left',\n cursor: onOpen !== undefined ? 'pointer' : 'default',\n font: 'inherit',\n color: 'inherit',\n transition: 'border-color var(--motion-fast) var(--ease-out), background var(--motion-fast) var(--ease-out)',\n }}\n >\n <span\n aria-hidden=\"true\"\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 28,\n height: 28,\n marginTop: 2,\n borderRadius: 'var(--radius-sm)',\n background:\n status === 'enabled'\n ? 'color-mix(in oklch, var(--success) 14%, transparent)'\n : status === 'error'\n ? 'color-mix(in oklch, var(--danger) 14%, transparent)'\n : 'var(--surface-2)',\n color:\n status === 'enabled' ? 'var(--success)' : status === 'error' ? 'var(--danger)' : 'var(--fg-muted)',\n flexShrink: 0,\n }}\n >\n <Power size={14} aria-hidden=\"true\" />\n </span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>\n <span\n style={{\n fontSize: 'var(--fs-13)',\n fontWeight: 600,\n color: 'var(--fg)',\n lineHeight: 'var(--lh-snug)',\n }}\n >\n {name}\n </span>\n <code\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-subtle)',\n fontFamily: 'var(--font-mono, ui-monospace, monospace)',\n }}\n >\n {slug}\n </code>\n </div>\n {description !== undefined && (\n <div\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-muted)',\n marginTop: 2,\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {description}\n </div>\n )}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 'var(--space-2)',\n marginTop: 6,\n }}\n >\n {meta !== undefined ? (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>{meta}</span>\n ) : (\n <span />\n )}\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>\n <Badge tone={STATUS_TONE[status]} size=\"sm\">\n {STATUS_LABEL[status]}\n </Badge>\n {actions}\n <ChevronRight size={14} aria-hidden=\"true\" style={{ color: 'var(--fg-subtle)' }} />\n </div>\n </div>\n </div>\n <style>{`\n .v8-library-item:hover {\n border-color: var(--accent);\n background: var(--surface-2);\n }\n `}</style>\n </button>\n );\n}","import { type ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * LibraryGrid — responsive grid for LibraryItem lists.\n *\n * Renders 1 column on narrow viewports, 2 columns on md, 3 columns on lg.\n * Uses CSS grid + auto-fit; items auto-size to fill available space.\n */\n\nexport interface LibraryGridProps {\n children: ReactNode;\n className?: string;\n}\n\nexport function LibraryGrid(props: LibraryGridProps) {\n const { children, className } = props;\n return (\n <div\n className={cx('v8-library-grid', className)}\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(min(100%, 320px), 1fr))',\n gap: 'var(--space-3)',\n }}\n >\n {children}\n </div>\n );\n}","import { useEffect, useState, useCallback } from 'react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { LibraryGrid, LibraryItem, type LibraryItemProps, type LibraryStatus } from '../../ui/index.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport type { LibraryItem as LibItem } from '../../data/types.js';\n\n/**\n * LibrariesView — Sprint S10. Generic Skills / MCPs / Hooks surface.\n *\n * The parent (`Router.tsx`) picks the data source per kind. This\n * view pulls live data from `/api/skills`, `/api/mcps`,\n * `/api/hooks` instead of seeded arrays.\n */\n\nexport type LibraryKind = 'skills' | 'mcps' | 'hooks';\n\nconst KIND_LABEL: Record<LibraryKind, string> = {\n skills: 'Skills',\n mcps: 'MCPs',\n hooks: 'Hooks',\n};\n\nconst KIND_DESCRIPTION: Record<LibraryKind, string> = {\n skills: 'Bizar skill packs. Auto-loaded by name or dispatched via the Skill tool.',\n mcps: 'MCP server registrations under `.claude/settings.json` → `mcpServers`.',\n hooks: 'Executable hook scripts (PreToolUse / PostToolUse / SessionStart / SessionEnd).',\n};\n\nconst ENDPOINT: Record<LibraryKind, string> = {\n skills: '/api/skills',\n mcps: '/api/skills?kind=mcps',\n hooks: '/api/skills?kind=hooks',\n};\n\nconst CHANGE_EVENTS: Record<LibraryKind, readonly string[]> = {\n skills: ['skills:change', 'agents:change'] as const,\n mcps: ['mcps:change', 'agents:change'] as const,\n hooks: ['hooks:change', 'agents:change'] as const,\n};\n// Stable hook count: always register listeners for all possible events,\n// filter inside the handler so kind navigation never changes hook order.\nconst ALL_EVENTS = ['skills:change', 'mcps:change', 'hooks:change', 'agents:change'] as const;\n\nfunction mapItem(it: LibItem): LibraryItemProps {\n const status: LibraryStatus =\n it.status === 'enabled' || it.status === 'disabled' || it.status === 'error'\n ? it.status\n : 'disabled';\n return {\n id: it.id,\n name: it.name,\n slug: it.slug ?? it.id,\n status,\n description: it.description,\n meta: it.meta,\n };\n}\n\nexport interface LibrariesViewProps {\n kind: LibraryKind;\n}\n\nexport function LibrariesView(props: LibrariesViewProps): JSX.Element {\n const { kind } = props;\n const url = ENDPOINT[kind];\n const res = useFetch<{ skills?: LibItem[]; items?: LibItem[]; count?: number }>(url);\n const [bust, setBust] = useState(0);\n\n // Force a re-fetch when the matching change event fires. Hook count\n // is fixed (ALL_EVENTS.length) so navigating between kinds can't trip\n // React's \"Rendered fewer hooks than expected\" runtime guard.\n const events = CHANGE_EVENTS[kind];\n const handler = useCallback((): void => setBust((n) => n + 1), []);\n for (const evt of ALL_EVENTS) {\n useWsMessage(evt, events.includes(evt) ? handler : () => {});\n }\n\n useEffect(() => {\n if (bust > 0) res.refetch();\n }, [bust, res]);\n\n const items: LibraryItemProps[] = (res.data?.skills || res.data?.items || [])\n .map(mapItem)\n .reduce<LibraryItemProps[]>((acc, item) => {\n if (!acc.some((existing) => existing.name === item.name)) acc.push(item);\n return acc;\n }, []);\n\n return (\n <Stack gap={5} data-testid={`${kind}-view`}>\n <ViewHeader title={KIND_LABEL[kind]} description={KIND_DESCRIPTION[kind]} />\n {res.loading ? (\n <Skeleton style={{ height: 240 }} />\n ) : res.error && items.length === 0 ? (\n <ErrorState\n block\n title={`Couldn't load ${KIND_LABEL[kind].toLowerCase()}`}\n description=\"The library endpoint failed. Retry to refetch.\"\n error={res.error}\n onRetry={() => void res.refetch()}\n testid={`libraries-${kind}-error`}\n />\n ) : items.length === 0 ? (\n <EmptyState\n icon={<span>📚</span>}\n title={`No ${KIND_LABEL[kind].toLowerCase()} installed`}\n description={`${KIND_LABEL[kind]} appear here as soon as they are registered.`}\n />\n ) : (\n <LibraryGrid>\n {items.map((item) => (\n <LibraryItem key={item.id} {...item} />\n ))}\n </LibraryGrid>\n )}\n </Stack>\n );\n}"],"names":["STATUS_LABEL","STATUS_TONE","LibraryItem","props","name","slug","status","description","meta","actions","onOpen","className","jsxs","cx","jsx","Power","Badge","ChevronRight","LibraryGrid","children","KIND_LABEL","KIND_DESCRIPTION","ENDPOINT","CHANGE_EVENTS","ALL_EVENTS","mapItem","it","LibrariesView","kind","url","res","useFetch","bust","setBust","useState","events","handler","useCallback","n","evt","useWsMessage","useEffect","items","_a","_b","acc","item","existing","Stack","ViewHeader","Skeleton","ErrorState","EmptyState"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{r as i,j as e}from"./cmdk-C3F6LD6N.js";import{d as I,u as z,S as c,I as r,B as g,h as C,D as E,$ as F,i as R,F as k}from"./main-BRmJZcHt.js";import{V}from"./ViewHeader-BsnaspKw.js";import{C as L,b as w}from"./Card-Clkvh43Q.js";import{I as B}from"./Input-DV-vdaV8.js";import{E as H}from"./EmptyState-ccT__JZG.js";import{E as J}from"./ErrorState-BSqf65ka.js";import{R as M}from"./refresh-ccw-DN_zCB1h.js";import{S as N}from"./save-BY4ViPku.js";import{C as T}from"./circle-D99cZJBr.js";import"./Alert-pzFISNtS.js";import"./circle-alert-QQTU4Quz.js";import"./triangle-alert-BeY8LAv6.js";import"./circle-check-BMbe7Kkr.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 O=I("CirclePlay",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polygon",{points:"10 8 16 12 10 16 10 8",key:"1cimsy"}]]);function ie(){var b;const s=z("/api/lightrag/defaults"),l=z("/api/lightrag/status"),[h,u]=i.useState(""),[f,m]=i.useState(""),[p,v]=i.useState(!1),[A,x]=i.useState(!1),[j,y]=i.useState(!1),[S,n]=i.useState(null);i.useEffect(()=>{s.data&&(u(s.data.llm??""),m(s.data.embedding??""))},[s.data]);const d=i.useCallback(()=>{s.refetch(),l.refetch()},[s,l]),P=async()=>{v(!0),n(null),x(!1);try{await R("/api/lightrag/defaults",{method:"PUT",body:{llm:h,embedding:f}}),x(!0),d()}catch(a){n((a instanceof k,a.message))}finally{v(!1)}},D=async()=>{y(!0),n(null);try{await R("/api/lightrag/autostart",{method:"POST"}),d()}catch(a){n((a instanceof k,a.message))}finally{y(!1)}},t=l.data,o=s.error??l.error;return e.jsxs(c,{gap:4,"data-testid":"lightrag-view",children:[e.jsx(V,{title:"LightRAG",description:"LightRAG defaults + runtime status + autostart.",actions:e.jsxs(r,{align:"center",gap:2,children:[S!==null&&e.jsx("span",{role:"alert","data-testid":"lightrag-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:S}),e.jsxs(g,{variant:"ghost",onClick:()=>void d(),"data-testid":"lightrag-refresh",children:[e.jsx(M,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(g,{variant:"primary",onClick:()=>void P(),disabled:p,"data-testid":"lightrag-save",children:[e.jsx(N,{size:14,"aria-hidden":!0})," ",p?"Saving…":"Save"]})]})}),o&&e.jsx(J,{title:"LightRAG unavailable",description:o.message||String(o),onRetry:()=>void d(),"data-testid":"lightrag-fetch-error"}),e.jsx(L,{variant:"default",children:e.jsxs(w,{children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Defaults"}),s.loading&&s.data===null?e.jsx(C,{style:{height:100,marginTop:"var(--space-2)"}}):e.jsxs(c,{gap:2,style:{marginTop:"var(--space-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:"LLM binding"}),e.jsx(B,{value:h,onChange:a=>u(a.target.value),"data-testid":"lightrag-llm"})]}),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:"Embedding binding"}),e.jsx(B,{value:f,onChange:a=>m(a.target.value),"data-testid":"lightrag-embedding"})]}),((b=s.data)==null?void 0:b.builtin)&&e.jsxs(r,{gap:2,style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:[e.jsx("span",{children:"built-in:"}),e.jsx("code",{children:s.data.builtin.llm})," /",e.jsx("code",{children:s.data.builtin.embedding})]}),A&&e.jsx("span",{"data-testid":"lightrag-saved",style:{color:"var(--success)",fontSize:"var(--fs-12)"},children:"Saved"})]})]})}),e.jsx(L,{variant:"default",children:e.jsxs(w,{children:[e.jsxs(r,{align:"center",justify:"between",gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Status"}),e.jsxs(r,{align:"center",gap:2,children:[t==null?e.jsx(C,{style:{width:80,height:14}}):t.running?e.jsxs(r,{align:"center",gap:1,"data-testid":"lightrag-running",children:[e.jsx(T,{size:10,"aria-hidden":!0,style:{color:"var(--success)",fill:"var(--success)"}}),e.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--success)"},children:["running · pid ",t.pid]})]}):e.jsxs(r,{align:"center",gap:1,"data-testid":"lightrag-stopped",children:[e.jsx(T,{size:10,"aria-hidden":!0,style:{color:"var(--fg-muted)",fill:"var(--fg-muted)"}}),e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"stopped"})]}),e.jsxs(g,{variant:"ghost",onClick:()=>void D(),disabled:j,"data-testid":"lightrag-autostart",children:[e.jsx(O,{size:14,"aria-hidden":!0})," ",j?"Starting…":"Autostart"]})]})]}),t&&e.jsxs(c,{gap:1,style:{marginTop:"var(--space-2)",fontSize:"var(--fs-12)"},children:[e.jsxs(r,{gap:2,children:[e.jsx(E,{size:12,"aria-hidden":!0,style:{color:"var(--fg-muted)"}}),e.jsxs("code",{children:[t.host,":",t.port]}),t.llmBinding&&e.jsxs("span",{style:{color:"var(--fg-muted)"},children:["· llm: ",e.jsx("code",{children:t.llmBinding})]}),t.embeddingBinding&&e.jsxs("span",{style:{color:"var(--fg-muted)"},children:["· embedding: ",e.jsx("code",{children:t.embeddingBinding})]})]}),t.logTail&&t.logTail.length>0?e.jsx("div",{"data-testid":"lightrag-log",style:{background:"var(--surface-1)",borderRadius:"var(--radius-sm)",padding:"var(--space-2)",fontFamily:"var(--font-mono)",fontSize:"var(--fs-11)",maxHeight:160,overflow:"auto"},children:t.logTail.filter(Boolean).slice(-10).map((a,G)=>e.jsx("div",{children:a},G))}):l.loading?e.jsx(F,{lines:4,lastLineWidth:"75%"}):e.jsx(H,{icon:e.jsx(E,{size:20,"aria-hidden":!0}),title:"No log output yet",description:"LightRAG has not emitted any log lines. Autostart a run to populate.","data-testid":"lightrag-log-empty"})]})]})})]})}export{ie as LightRAGView};
|