@polderlabs/bizar 10.1.0 → 10.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/bizar-dash/dist/assets/{ActivityFeed-Da-JCrE6.js → ActivityFeed-JjmOY2AQ.js} +1 -1
- package/bizar-dash/dist/assets/{ActivityFeed-Da-JCrE6.js.map → ActivityFeed-JjmOY2AQ.js.map} +1 -1
- package/bizar-dash/dist/assets/{ActivityView-nIRsSETb.js → ActivityView-BIIMvGWo.js} +1 -1
- package/bizar-dash/dist/assets/{ActivityView-nIRsSETb.js.map → ActivityView-BIIMvGWo.js.map} +1 -1
- package/bizar-dash/dist/assets/{AdminView-DP1NMxmG.js → AdminView-DRidJtkq.js} +1 -1
- package/bizar-dash/dist/assets/{AdminView-DP1NMxmG.js.map → AdminView-DRidJtkq.js.map} +1 -1
- package/bizar-dash/dist/assets/{AgentActivity-lSPkOr-O.js → AgentActivity-79l4SBMC.js} +1 -1
- package/bizar-dash/dist/assets/{AgentActivity-lSPkOr-O.js.map → AgentActivity-79l4SBMC.js.map} +1 -1
- package/bizar-dash/dist/assets/{AgentsView-BIWGkz7w.js → AgentsView-0vT4uPSc.js} +1 -1
- package/bizar-dash/dist/assets/{AgentsView-BIWGkz7w.js.map → AgentsView-0vT4uPSc.js.map} +1 -1
- package/bizar-dash/dist/assets/{Alert-DN0UysMg.js → Alert-CG5q_s75.js} +1 -1
- package/bizar-dash/dist/assets/{Alert-DN0UysMg.js.map → Alert-CG5q_s75.js.map} +1 -1
- package/bizar-dash/dist/assets/ArtifactsView-DM8ZmpR9.js +21 -0
- package/bizar-dash/dist/assets/ArtifactsView-DM8ZmpR9.js.map +1 -0
- package/bizar-dash/dist/assets/{AuthView-DW5cs7ma.js → AuthView-BveN94MC.js} +1 -1
- package/bizar-dash/dist/assets/{AuthView-DW5cs7ma.js.map → AuthView-BveN94MC.js.map} +1 -1
- package/bizar-dash/dist/assets/{Avatar-DZPv9pvd.js → Avatar-ulUPIYTd.js} +1 -1
- package/bizar-dash/dist/assets/{Avatar-DZPv9pvd.js.map → Avatar-ulUPIYTd.js.map} +1 -1
- package/bizar-dash/dist/assets/{BackgroundJobsView-D8O-EyMD.js → BackgroundJobsView-BWErhqFo.js} +1 -1
- package/bizar-dash/dist/assets/{BackgroundJobsView-D8O-EyMD.js.map → BackgroundJobsView-BWErhqFo.js.map} +1 -1
- package/bizar-dash/dist/assets/{BackupView-uwXkhxOV.js → BackupView-CnBjzG9N.js} +1 -1
- package/bizar-dash/dist/assets/{BackupView-uwXkhxOV.js.map → BackupView-CnBjzG9N.js.map} +1 -1
- package/bizar-dash/dist/assets/{Card-Tyboihu7.js → Card-B0imhxMk.js} +1 -1
- package/bizar-dash/dist/assets/{Card-Tyboihu7.js.map → Card-B0imhxMk.js.map} +1 -1
- package/bizar-dash/dist/assets/{ChatView-DRBHzgay.js → ChatView-D6zGytzx.js} +1 -1
- package/bizar-dash/dist/assets/{ChatView-DRBHzgay.js.map → ChatView-D6zGytzx.js.map} +1 -1
- package/bizar-dash/dist/assets/{Chip-BrXIlR9w.js → Chip-wwZSGwLE.js} +1 -1
- package/bizar-dash/dist/assets/{Chip-BrXIlR9w.js.map → Chip-wwZSGwLE.js.map} +1 -1
- package/bizar-dash/dist/assets/{ClaudeSessionsView-Ck62jaOr.js → ClaudeSessionsView-DK1sOLhi.js} +1 -1
- package/bizar-dash/dist/assets/{ClaudeSessionsView-Ck62jaOr.js.map → ClaudeSessionsView-DK1sOLhi.js.map} +1 -1
- package/bizar-dash/dist/assets/{ClipboardView-DfND6xL6.js → ClipboardView-CZ2lYPr0.js} +1 -1
- package/bizar-dash/dist/assets/{ClipboardView-DfND6xL6.js.map → ClipboardView-CZ2lYPr0.js.map} +1 -1
- package/bizar-dash/dist/assets/{ConfigView-DjJmSrOJ.js → ConfigView-D-zT9eNA.js} +1 -1
- package/bizar-dash/dist/assets/{ConfigView-DjJmSrOJ.js.map → ConfigView-D-zT9eNA.js.map} +1 -1
- package/bizar-dash/dist/assets/{DiagnosticsView-CKgItf0J.js → DiagnosticsView-BocV68Lb.js} +1 -1
- package/bizar-dash/dist/assets/{DiagnosticsView-CKgItf0J.js.map → DiagnosticsView-BocV68Lb.js.map} +1 -1
- package/bizar-dash/dist/assets/{DialogsView-DHYF8dE1.js → DialogsView-BVjPI5x7.js} +1 -1
- package/bizar-dash/dist/assets/{DialogsView-DHYF8dE1.js.map → DialogsView-BVjPI5x7.js.map} +1 -1
- package/bizar-dash/dist/assets/{DoctorView-DDLHrSKk.js → DoctorView-84gJcZwM.js} +1 -1
- package/bizar-dash/dist/assets/{DoctorView-DDLHrSKk.js.map → DoctorView-84gJcZwM.js.map} +1 -1
- package/bizar-dash/dist/assets/{EmptyState-DZ2ouKwd.js → EmptyState-BjgVOrcO.js} +1 -1
- package/bizar-dash/dist/assets/{EmptyState-DZ2ouKwd.js.map → EmptyState-BjgVOrcO.js.map} +1 -1
- package/bizar-dash/dist/assets/{EnvVarsView-D1cx83mB.js → EnvVarsView-BJ2TEzF7.js} +1 -1
- package/bizar-dash/dist/assets/{EnvVarsView-D1cx83mB.js.map → EnvVarsView-BJ2TEzF7.js.map} +1 -1
- package/bizar-dash/dist/assets/{ErrorState-DwwJ2-Jq.js → ErrorState-BE3WBFqF.js} +1 -1
- package/bizar-dash/dist/assets/{ErrorState-DwwJ2-Jq.js.map → ErrorState-BE3WBFqF.js.map} +1 -1
- package/bizar-dash/dist/assets/{EvalView-C9aYixXW.js → EvalView-BJJ2P-kK.js} +1 -1
- package/bizar-dash/dist/assets/{EvalView-C9aYixXW.js.map → EvalView-BJJ2P-kK.js.map} +1 -1
- package/bizar-dash/dist/assets/{GoalsView-DZa_mGmh.js → GoalsView-pwROHApi.js} +1 -1
- package/bizar-dash/dist/assets/{GoalsView-DZa_mGmh.js.map → GoalsView-pwROHApi.js.map} +1 -1
- package/bizar-dash/dist/assets/{Grid-CiRyhAgR.js → Grid-qcvbhx6e.js} +1 -1
- package/bizar-dash/dist/assets/{Grid-CiRyhAgR.js.map → Grid-qcvbhx6e.js.map} +1 -1
- package/bizar-dash/dist/assets/{HeadroomView-CNc-TI7u.js → HeadroomView-D1UiTYbt.js} +1 -1
- package/bizar-dash/dist/assets/{HeadroomView-CNc-TI7u.js.map → HeadroomView-D1UiTYbt.js.map} +1 -1
- package/bizar-dash/dist/assets/{HistoryView-Dv7aPxJE.js → HistoryView-C7SSOLJA.js} +1 -1
- package/bizar-dash/dist/assets/{HistoryView-Dv7aPxJE.js.map → HistoryView-C7SSOLJA.js.map} +1 -1
- package/bizar-dash/dist/assets/{Input-BbFUDQnS.js → Input-Bgzxf_Hu.js} +1 -1
- package/bizar-dash/dist/assets/{Input-BbFUDQnS.js.map → Input-Bgzxf_Hu.js.map} +1 -1
- package/bizar-dash/dist/assets/{LibrariesView-DBQ83TNa.js → LibrariesView-CbFFksox.js} +1 -1
- package/bizar-dash/dist/assets/{LibrariesView-DBQ83TNa.js.map → LibrariesView-CbFFksox.js.map} +1 -1
- package/bizar-dash/dist/assets/{LightRAGView-JYpE5u9p.js → LightRAGView-BqDrJbRq.js} +1 -1
- package/bizar-dash/dist/assets/{LightRAGView-JYpE5u9p.js.map → LightRAGView-BqDrJbRq.js.map} +1 -1
- package/bizar-dash/dist/assets/{ListHeader-BGjm11Z0.js → ListHeader-TjPJrUfY.js} +1 -1
- package/bizar-dash/dist/assets/{ListHeader-BGjm11Z0.js.map → ListHeader-TjPJrUfY.js.map} +1 -1
- package/bizar-dash/dist/assets/{MemoryView-CnOP2MvM.js → MemoryView-BlTeHLhX.js} +1 -1
- package/bizar-dash/dist/assets/{MemoryView-CnOP2MvM.js.map → MemoryView-BlTeHLhX.js.map} +1 -1
- package/bizar-dash/dist/assets/{MiscView-BBcpUbZZ.js → MiscView-B8QY82Pm.js} +1 -1
- package/bizar-dash/dist/assets/{MiscView-BBcpUbZZ.js.map → MiscView-B8QY82Pm.js.map} +1 -1
- package/bizar-dash/dist/assets/{ModsView-CU4cAmIz.js → ModsView-CvW1OWts.js} +1 -1
- package/bizar-dash/dist/assets/{ModsView-CU4cAmIz.js.map → ModsView-CvW1OWts.js.map} +1 -1
- package/bizar-dash/dist/assets/{NotificationsView-BYffvthq.js → NotificationsView-CsBt5U7x.js} +1 -1
- package/bizar-dash/dist/assets/{NotificationsView-BYffvthq.js.map → NotificationsView-CsBt5U7x.js.map} +1 -1
- package/bizar-dash/dist/assets/{ObsidianView-D3bI0row.js → ObsidianView-BCTejEj2.js} +1 -1
- package/bizar-dash/dist/assets/{ObsidianView-D3bI0row.js.map → ObsidianView-BCTejEj2.js.map} +1 -1
- package/bizar-dash/dist/assets/{OverviewView-0tq8f-Y0.js → OverviewView-BsuPxwnB.js} +1 -1
- package/bizar-dash/dist/assets/{OverviewView-0tq8f-Y0.js.map → OverviewView-BsuPxwnB.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProgressBar-B-h60LKA.js → ProgressBar-DlZTETEn.js} +1 -1
- package/bizar-dash/dist/assets/{ProgressBar-B-h60LKA.js.map → ProgressBar-DlZTETEn.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProjectsView-DhX5lzHS.js → ProjectsView-Soxtmpet.js} +1 -1
- package/bizar-dash/dist/assets/{ProjectsView-DhX5lzHS.js.map → ProjectsView-Soxtmpet.js.map} +1 -1
- package/bizar-dash/dist/assets/{ProvidersView-CJMX7jm9.js → ProvidersView-DaCEV9pM.js} +1 -1
- package/bizar-dash/dist/assets/{ProvidersView-CJMX7jm9.js.map → ProvidersView-DaCEV9pM.js.map} +1 -1
- package/bizar-dash/dist/assets/{SchedulesView-CcwDQ9Nm.js → SchedulesView-DY2ByBj_.js} +1 -1
- package/bizar-dash/dist/assets/{SchedulesView-CcwDQ9Nm.js.map → SchedulesView-DY2ByBj_.js.map} +1 -1
- package/bizar-dash/dist/assets/{Select-Cw7Qtz2M.js → Select-Dbd88_n8.js} +1 -1
- package/bizar-dash/dist/assets/{Select-Cw7Qtz2M.js.map → Select-Dbd88_n8.js.map} +1 -1
- package/bizar-dash/dist/assets/{SettingsRow-DgsgbPSI.js → SettingsRow-CLMNd434.js} +1 -1
- package/bizar-dash/dist/assets/{SettingsRow-DgsgbPSI.js.map → SettingsRow-CLMNd434.js.map} +1 -1
- package/bizar-dash/dist/assets/{SettingsView-DTAFdKyK.js → SettingsView-b24oFq9x.js} +1 -1
- package/bizar-dash/dist/assets/{SettingsView-DTAFdKyK.js.map → SettingsView-b24oFq9x.js.map} +1 -1
- package/bizar-dash/dist/assets/{Sheet-DH-WNJ3Y.js → Sheet-DnDid58j.js} +1 -1
- package/bizar-dash/dist/assets/{Sheet-DH-WNJ3Y.js.map → Sheet-DnDid58j.js.map} +1 -1
- package/bizar-dash/dist/assets/{Slider-DXbJuQ7y.js → Slider-BJCvKI1I.js} +1 -1
- package/bizar-dash/dist/assets/{Slider-DXbJuQ7y.js.map → Slider-BJCvKI1I.js.map} +1 -1
- package/bizar-dash/dist/assets/{Sparkline-CYtAn82j.js → Sparkline-ktqQLdyb.js} +1 -1
- package/bizar-dash/dist/assets/{Sparkline-CYtAn82j.js.map → Sparkline-ktqQLdyb.js.map} +1 -1
- package/bizar-dash/dist/assets/{Switch-BItGrPqr.js → Switch-CwXfsDii.js} +1 -1
- package/bizar-dash/dist/assets/{Switch-BItGrPqr.js.map → Switch-CwXfsDii.js.map} +1 -1
- package/bizar-dash/dist/assets/{TasksView-i5tm6CkX.js → TasksView-BHmpzFCf.js} +1 -1
- package/bizar-dash/dist/assets/{TasksView-i5tm6CkX.js.map → TasksView-BHmpzFCf.js.map} +1 -1
- package/bizar-dash/dist/assets/{Textarea-qYDf3yds.js → Textarea-BzIAwSlp.js} +1 -1
- package/bizar-dash/dist/assets/{Textarea-qYDf3yds.js.map → Textarea-BzIAwSlp.js.map} +1 -1
- package/bizar-dash/dist/assets/{UpdateView-Xln-ej26.js → UpdateView-CSmX9NN0.js} +1 -1
- package/bizar-dash/dist/assets/{UpdateView-Xln-ej26.js.map → UpdateView-CSmX9NN0.js.map} +1 -1
- package/bizar-dash/dist/assets/{UsageView-BGuZSUZ6.js → UsageView-COyr_Gfi.js} +1 -1
- package/bizar-dash/dist/assets/{UsageView-BGuZSUZ6.js.map → UsageView-COyr_Gfi.js.map} +1 -1
- package/bizar-dash/dist/assets/{ViewHeader-BqIPVKuG.js → ViewHeader-BzYZ3m-e.js} +1 -1
- package/bizar-dash/dist/assets/{ViewHeader-BqIPVKuG.js.map → ViewHeader-BzYZ3m-e.js.map} +1 -1
- package/bizar-dash/dist/assets/{VoiceView-CWUOCQs_.js → VoiceView-D33_xG5t.js} +1 -1
- package/bizar-dash/dist/assets/{VoiceView-CWUOCQs_.js.map → VoiceView-D33_xG5t.js.map} +1 -1
- package/bizar-dash/dist/assets/{brain-fsBSDl2g.js → brain-CM-Vls8r.js} +1 -1
- package/bizar-dash/dist/assets/{brain-fsBSDl2g.js.map → brain-CM-Vls8r.js.map} +1 -1
- package/bizar-dash/dist/assets/{calendar-DsHTZoCU.js → calendar-C0lgZk69.js} +1 -1
- package/bizar-dash/dist/assets/{calendar-DsHTZoCU.js.map → calendar-C0lgZk69.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-CqSxqqeJ.js → circle-Bx_hQEBC.js} +1 -1
- package/bizar-dash/dist/assets/{circle-CqSxqqeJ.js.map → circle-Bx_hQEBC.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-alert-BsLl001l.js → circle-alert-DHvsqpw5.js} +1 -1
- package/bizar-dash/dist/assets/{circle-alert-BsLl001l.js.map → circle-alert-DHvsqpw5.js.map} +1 -1
- package/bizar-dash/dist/assets/{circle-check-rVKMQmZp.js → circle-check-Bx8wmXR9.js} +1 -1
- package/bizar-dash/dist/assets/{circle-check-rVKMQmZp.js.map → circle-check-Bx8wmXR9.js.map} +1 -1
- package/bizar-dash/dist/assets/{clock-OuficfgH.js → clock-CejGoecX.js} +1 -1
- package/bizar-dash/dist/assets/{clock-OuficfgH.js.map → clock-CejGoecX.js.map} +1 -1
- package/bizar-dash/dist/assets/{download-BdHlstUY.js → download-4cEUWue1.js} +1 -1
- package/bizar-dash/dist/assets/{download-BdHlstUY.js.map → download-4cEUWue1.js.map} +1 -1
- package/bizar-dash/dist/assets/{external-link-DA3_VGm-.js → external-link-0NqUhI4i.js} +1 -1
- package/bizar-dash/dist/assets/{external-link-DA3_VGm-.js.map → external-link-0NqUhI4i.js.map} +1 -1
- package/bizar-dash/dist/assets/{file-text-B-g8H227.js → file-text-yEMkrSoZ.js} +1 -1
- package/bizar-dash/dist/assets/{file-text-B-g8H227.js.map → file-text-yEMkrSoZ.js.map} +1 -1
- package/bizar-dash/dist/assets/{filter-D9B8s5CG.js → filter-BXt60zAS.js} +1 -1
- package/bizar-dash/dist/assets/{filter-D9B8s5CG.js.map → filter-BXt60zAS.js.map} +1 -1
- package/bizar-dash/dist/assets/{git-pull-request-ByH0YuVz.js → git-pull-request-BjG5lNtR.js} +1 -1
- package/bizar-dash/dist/assets/{git-pull-request-ByH0YuVz.js.map → git-pull-request-BjG5lNtR.js.map} +1 -1
- package/bizar-dash/dist/assets/{main-CdOm1Pj9.js → main-CokHAXWM.js} +2 -2
- package/bizar-dash/dist/assets/{main-CdOm1Pj9.js.map → main-CokHAXWM.js.map} +1 -1
- package/bizar-dash/dist/assets/{pause-C9hgd8wX.js → pause-CAmulU0F.js} +1 -1
- package/bizar-dash/dist/assets/{pause-C9hgd8wX.js.map → pause-CAmulU0F.js.map} +1 -1
- package/bizar-dash/dist/assets/{pencil-BanqaMw7.js → pencil-eq5IqBmU.js} +1 -1
- package/bizar-dash/dist/assets/{pencil-BanqaMw7.js.map → pencil-eq5IqBmU.js.map} +1 -1
- package/bizar-dash/dist/assets/{play-CawUZ02_.js → play-BoLrrcBA.js} +1 -1
- package/bizar-dash/dist/assets/{play-CawUZ02_.js.map → play-BoLrrcBA.js.map} +1 -1
- package/bizar-dash/dist/assets/{plug-Cmv0-T_e.js → plug-DBrVM9lK.js} +1 -1
- package/bizar-dash/dist/assets/{plug-Cmv0-T_e.js.map → plug-DBrVM9lK.js.map} +1 -1
- package/bizar-dash/dist/assets/{plus-M6LYiKX8.js → plus-DENm0hqV.js} +1 -1
- package/bizar-dash/dist/assets/{plus-M6LYiKX8.js.map → plus-DENm0hqV.js.map} +1 -1
- package/bizar-dash/dist/assets/{power-DP5x_SRF.js → power-DLjXF7zE.js} +1 -1
- package/bizar-dash/dist/assets/{power-DP5x_SRF.js.map → power-DLjXF7zE.js.map} +1 -1
- package/bizar-dash/dist/assets/{power-off-NOJRLAIs.js → power-off-D47cOnG_.js} +1 -1
- package/bizar-dash/dist/assets/{power-off-NOJRLAIs.js.map → power-off-D47cOnG_.js.map} +1 -1
- package/bizar-dash/dist/assets/{refresh-ccw-CHMprsm5.js → refresh-ccw-DNrXX9gB.js} +1 -1
- package/bizar-dash/dist/assets/{refresh-ccw-CHMprsm5.js.map → refresh-ccw-DNrXX9gB.js.map} +1 -1
- package/bizar-dash/dist/assets/{refresh-cw-1RBqDKgJ.js → refresh-cw-CoAHDpeS.js} +1 -1
- package/bizar-dash/dist/assets/{refresh-cw-1RBqDKgJ.js.map → refresh-cw-CoAHDpeS.js.map} +1 -1
- package/bizar-dash/dist/assets/{rotate-ccw-DJRekBbi.js → rotate-ccw-ObX5awaG.js} +1 -1
- package/bizar-dash/dist/assets/{rotate-ccw-DJRekBbi.js.map → rotate-ccw-ObX5awaG.js.map} +1 -1
- package/bizar-dash/dist/assets/{rotate-cw-DHooc0Tx.js → rotate-cw-xpPJw9LP.js} +1 -1
- package/bizar-dash/dist/assets/{rotate-cw-DHooc0Tx.js.map → rotate-cw-xpPJw9LP.js.map} +1 -1
- package/bizar-dash/dist/assets/{save-DQKCKyZK.js → save-D1iKiJJl.js} +1 -1
- package/bizar-dash/dist/assets/{save-DQKCKyZK.js.map → save-D1iKiJJl.js.map} +1 -1
- package/bizar-dash/dist/assets/{send-xgy3RAi7.js → send-BRcAhZUm.js} +1 -1
- package/bizar-dash/dist/assets/{send-xgy3RAi7.js.map → send-BRcAhZUm.js.map} +1 -1
- package/bizar-dash/dist/assets/{shield-alert-CWV2F5ab.js → shield-alert-C6vEcK-g.js} +1 -1
- package/bizar-dash/dist/assets/{shield-alert-CWV2F5ab.js.map → shield-alert-C6vEcK-g.js.map} +1 -1
- package/bizar-dash/dist/assets/{trash-2-CL4khSRv.js → trash-2-DZDjEnNh.js} +1 -1
- package/bizar-dash/dist/assets/{trash-2-CL4khSRv.js.map → trash-2-DZDjEnNh.js.map} +1 -1
- package/bizar-dash/dist/assets/{trending-up-CSJJhWTS.js → trending-up-DMj-AJVf.js} +1 -1
- package/bizar-dash/dist/assets/{trending-up-CSJJhWTS.js.map → trending-up-DMj-AJVf.js.map} +1 -1
- package/bizar-dash/dist/assets/{triangle-alert-BPLb7uLt.js → triangle-alert-_2xe_tl4.js} +1 -1
- package/bizar-dash/dist/assets/{triangle-alert-BPLb7uLt.js.map → triangle-alert-_2xe_tl4.js.map} +1 -1
- package/bizar-dash/dist/assets/{upload-Cww6MvFq.js → upload-DdDljAeV.js} +1 -1
- package/bizar-dash/dist/assets/{upload-Cww6MvFq.js.map → upload-DdDljAeV.js.map} +1 -1
- package/bizar-dash/dist/assets/{zap-DmhVUzRA.js → zap-mHsgh0FP.js} +1 -1
- package/bizar-dash/dist/assets/{zap-DmhVUzRA.js.map → zap-mHsgh0FP.js.map} +1 -1
- package/bizar-dash/dist/index.html +1 -1
- package/bizar-dash/skills/headroom/SKILL.md +94 -0
- package/bizar-dash/src/server/api.mjs +11 -0
- package/bizar-dash/src/server/artifacts-store.mjs +120 -14
- package/bizar-dash/src/server/claude-artifacts.mjs +281 -0
- package/bizar-dash/src/server/headroom.mjs +649 -0
- package/bizar-dash/src/server/routes/artifacts.mjs +42 -6
- package/bizar-dash/src/server/routes/audit.mjs +78 -0
- package/bizar-dash/src/server/routes/decisions.mjs +78 -0
- package/bizar-dash/src/server/routes/headroom.mjs +126 -0
- package/bizar-dash/src/server/routes/model-router.mjs +55 -0
- package/bizar-dash/src/server/routes/model-router.test.mjs +28 -0
- package/bizar-dash/src/server/routes/sessions.mjs +80 -0
- package/bizar-dash/src/server/sprint.test.mjs +163 -0
- package/bizar-dash/src/web/v8/views/Artifacts/ArtifactsView.tsx +232 -21
- package/bizar-dash/src/web/v8/views/Artifacts/ClaudeArtifactView.tsx +179 -0
- package/bizar-dash/tests/headroom-install.test.mjs +173 -0
- package/bizar-dash/tests/headroom-settings.test.mjs +126 -0
- package/bizar-dash/tests/headroom-status.test.mjs +117 -0
- package/cli/commands/headroom.mjs +204 -0
- package/package.json +1 -1
- package/packages/sdk/dist/agent/cron.d.ts +44 -0
- package/packages/sdk/dist/agent/cron.js +79 -0
- package/packages/sdk/dist/agent/heartbeat.d.ts +43 -0
- package/packages/sdk/dist/agent/heartbeat.js +116 -0
- package/packages/sdk/dist/index.d.ts +3 -0
- package/packages/sdk/dist/index.js +5 -0
- package/packages/sdk/dist/learning/decisions.d.ts +46 -0
- package/packages/sdk/dist/learning/decisions.js +132 -0
- package/packages/sdk/dist/learning/index.d.ts +8 -0
- package/packages/sdk/dist/learning/index.js +8 -0
- package/packages/sdk/dist/learning/instincts.d.ts +38 -0
- package/packages/sdk/dist/learning/instincts.js +139 -0
- package/packages/sdk/dist/mcp/server.js +119 -1
- package/packages/sdk/dist/router/agent-model-registry.d.ts +89 -0
- package/packages/sdk/dist/router/agent-model-registry.js +144 -0
- package/packages/sdk/dist/router/index.d.ts +1 -0
- package/packages/sdk/dist/router/index.js +1 -0
- package/packages/sdk/package.json +3 -2
- package/scripts/audit.mjs +388 -0
- package/scripts/audit.test.mjs +149 -0
- package/scripts/eval-gate.mjs +134 -0
- package/scripts/eval-gate.test.mjs +138 -0
- package/scripts/feature-state-machine.mjs +178 -0
- package/scripts/feature-state-machine.test.mjs +135 -0
- package/scripts/spec-dedup.test.mjs +124 -0
- package/scripts/sprint.mjs +213 -0
- package/scripts/worktree-setup.sh +79 -0
- package/bizar-dash/dist/assets/ArtifactsView-CDIhPBAx.js +0 -6
- package/bizar-dash/dist/assets/ArtifactsView-CDIhPBAx.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoalsView-DZa_mGmh.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":"0hCAuCA,MAAMA,GAA2C,CAC/C,WAAY,WACZ,UAAW,UACX,YAAa,YACb,KAAM,MACR,EAEMC,GAAgF,CACpF,WAAY,UACZ,UAAW,UACX,YAAa,SACb,KAAM,SACR,EAEO,SAASC,GAASC,EAAsB,CAC7C,KAAM,CACJ,MAAAC,EACA,YAAAC,EACA,OAAAC,EACA,SAAAC,EACA,IAAAC,EACA,UAAAC,EACA,eAAAC,EACA,eAAAC,EACA,gBAAAC,EACA,OAAAC,EACA,OAAAC,EACA,UAAAC,CAAA,EACEZ,EAEJ,OACEa,EAAAA,KAAC,SAAA,CACC,KAAK,SACL,QAASF,EACT,UAAWG,EAAG,eAAgB,iBAAiBX,CAAM,GAAIS,CAAS,EAClE,MAAO,CACL,QAAS,OACT,cAAe,SACf,IAAK,iBACL,MAAO,OACP,QAAS,iBACT,WAAY,mBACZ,OAAQ,0BACR,aAAc,mBACd,UAAW,OACX,OAAQ,UACR,KAAM,UACN,MAAO,UACP,WAAY,gGAAA,EAGd,SAAA,CAAAC,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,aAAc,eAAgB,gBAAiB,IAAK,gBAAA,EAC7F,SAAA,CAAAA,OAAC,OAAI,MAAO,CAAE,KAAM,EAAG,SAAU,GAC/B,SAAA,CAAAE,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,WAAY,IAAK,MAAO,YAAa,WAAY,gBAAA,EACtF,SAAAd,EACH,EACCC,IAAgB,QACfa,EAAAA,IAAC,MAAA,CACC,MAAO,CACL,SAAU,eACV,MAAO,kBACP,UAAW,EACX,QAAS,cACT,gBAAiB,EACjB,gBAAiB,WACjB,SAAU,QAAA,EAGX,SAAAb,CAAA,CAAA,CACH,EAEJ,EACAa,EAAAA,IAACC,EAAA,CAAM,KAAMlB,GAAYK,CAAM,EAAG,IAAG,GAClC,SAAAN,GAAaM,CAAM,CAAA,CACtB,CAAA,EACF,SACC,MAAA,CACC,SAAA,CAAAY,EAAAA,IAACE,GAAA,CACC,MAAOb,EACP,KAAMD,IAAW,WAAa,UAAYA,IAAW,UAAY,UAAYA,IAAW,YAAc,SAAW,QAAA,CAAA,SAElH,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,eAAgB,gBAAiB,UAAW,EAAG,SAAU,eAAgB,MAAO,kBAAmB,mBAAoB,gBACpJ,SAAA,CAAAU,OAAC,OAAA,CAAM,SAAA,CAAA,KAAK,MAAMT,EAAW,GAAG,EAAE,YAAA,EAAU,EAC3CI,IAAmB,QAAaC,IAAoB,eAClD,OAAA,CACE,SAAA,CAAAD,EAAe,MAAIC,EAAgB,cAAA,CAAA,CACtC,CAAA,CAAA,CAEJ,CAAA,EACF,EACAI,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,eAAgB,gBAChB,IAAK,iBACL,SAAU,eACV,MAAO,kBAAA,EAGT,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,gBAAA,EACvD,SAAA,CAAAR,IAAQ,QACPQ,EAAAA,KAAC,OAAA,CAAK,MAAO,CAAE,QAAS,cAAe,WAAY,SAAU,IAAK,CAAA,EAChE,SAAA,CAAAE,EAAAA,IAACG,GAAA,CAAS,KAAM,GAAI,cAAY,OAAO,EACtCb,CAAA,EACH,EAEDC,IAAc,QACbO,EAAAA,KAAC,OAAA,CAAK,MAAO,CAAE,QAAS,cAAe,WAAY,SAAU,IAAK,CAAA,EAChE,SAAA,CAAAE,EAAAA,IAAC,OAAA,CACC,cAAY,OACZ,MAAO,CACL,MAAO,GACP,OAAQ,GACR,aAAc,qBACd,WAAYR,IAAmB,OAAY,OAAOA,CAAc,iBAAmB,gBACnF,QAAS,cAAA,CACX,CAAA,EAEDD,CAAA,CAAA,CACH,CAAA,EAEJ,EACAO,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,gBAAA,EACvD,SAAA,CAAAH,EACDK,EAAAA,IAACI,EAAA,CAAa,KAAM,GAAI,cAAY,OAAO,MAAO,CAAE,MAAO,mBAAmB,CAAG,CAAA,CAAA,CACnF,CAAA,CAAA,CAAA,QAED,QAAA,CAAO,SAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAAA,CAKN,CAAA,CAAA,CAAA,CAGR,CCzJA,MAAMC,GAAiB,CACrB,CAAE,MAAO,WAAY,MAAO,UAAA,EAC5B,CAAE,MAAO,UAAW,MAAO,SAAA,EAC3B,CAAE,MAAO,YAAa,MAAO,WAAA,EAC7B,CAAE,MAAO,UAAW,MAAO,SAAA,EAC3B,CAAE,MAAO,SAAU,MAAO,QAAA,EAC1B,CAAE,MAAO,OAAQ,MAAO,MAAA,CAC1B,EAQO,SAASC,GAAWrB,EAAqC,CAC9D,KAAM,CAAE,KAAAsB,EAAM,KAAAC,EAAM,aAAAC,CAAA,EAAiBxB,EAC/B,CAACyB,EAAUC,CAAW,EAAIC,EAAAA,SAAkB,EAAK,EAEjDC,EAAa,SAA2B,CAI5C,GAHW,SAAO,OAAW,KAAe,OAAO,OAAO,SAAY,aAClE,OAAO,QAAQ,gBAAgBN,EAAK,KAAK,sCAAsC,EAGnF,CAAAI,EAAY,EAAI,EAChB,GAAI,CACF,MAAMG,EAAU,cAAc,mBAAmBP,EAAK,EAAE,CAAC,GAAI,CAAE,OAAQ,SAAU,EACjFE,EAAa,EAAK,CACpB,OAASM,EAAK,CACZC,EAASD,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CAC3D,QAAA,CACEJ,EAAY,EAAK,CACnB,EACF,EACM,CAACzB,EAAO+B,CAAQ,EAAIL,EAAAA,SAAiBL,EAAK,KAAK,EAC/C,CAACnB,EAAQ8B,CAAS,EAAIN,EAAAA,SAAiBL,EAAK,MAAM,EAClD,CAACY,EAAOC,CAAQ,EAAIR,EAAAA,SAAiBL,EAAK,OAAS,EAAE,EACrD,CAACjB,EAAK+B,CAAM,EAAIT,EAAAA,SAAiBL,EAAK,KAAO,EAAE,EAC/C,CAACe,EAAOC,CAAQ,EAAIX,EAAAA,SAAiB,EAAE,EACvC,CAACY,EAAMC,CAAO,EAAIb,EAAAA,SAAwB,IAAI,EAC9C,CAACc,EAASC,CAAU,EAAIf,EAAAA,SAAwB,IAAI,EACpD,CAACgB,EAAOZ,CAAQ,EAAIJ,EAAAA,SAAwB,IAAI,EAEtDiB,EAAAA,UAAU,IAAM,CACVrB,IACFS,EAASV,EAAK,KAAK,EACnBW,EAAUX,EAAK,MAAM,EACrBa,EAASb,EAAK,OAAS,EAAE,EACzBc,EAAOd,EAAK,KAAO,EAAE,EACrBoB,EAAW,IAAI,EACfX,EAAS,IAAI,EACbO,EAAS,EAAE,EAEf,EAAG,CAACf,EAAMD,CAAI,CAAC,EAEf,MAAMuB,EAAQ,MAAOC,EAA+BC,IAAiC,CACnFP,EAAQO,CAAK,EACbL,EAAW,IAAI,EACfX,EAAS,IAAI,EACb,GAAI,CACF,MAAMF,EAAU,cAAc,mBAAmBP,EAAK,EAAE,CAAC,GAAI,CAAE,OAAQ,QAAS,KAAAwB,CAAA,CAAM,EACtFJ,EAAW,GAAGK,CAAK,SAAS,CAC9B,OAASjB,EAAK,CACZC,EAASD,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CAC3D,QAAA,CACEU,EAAQ,IAAI,CACd,CACF,EAEMQ,EAAY,IAAY,CACxB/C,EAAM,KAAA,GAAUA,IAAUqB,EAAK,OAAYuB,EAAM,CAAE,MAAO5C,EAAM,KAAA,CAAK,EAAK,OAAO,CACvF,EACMgD,EAAcC,GAAoB,CACtCjB,EAAUiB,CAAC,EACPA,IAAM5B,EAAK,QAAauB,EAAM,CAAE,OAAQK,CAAA,EAAK,QAAQ,CAC3D,EACMC,EAAY,IAAY,CAC5B,MAAMD,EAAIhB,EAAM,KAAA,EACZgB,KAAO5B,EAAK,OAAS,KAAUuB,EAAM,CAAE,MAAOK,CAAA,EAAK,OAAO,CAChE,EACME,EAAU,IAAY,CAC1B,MAAMF,EAAI7C,EAAI,KAAA,EACV6C,KAAO5B,EAAK,KAAO,KAAUuB,EAAM,CAAE,IAAKK,CAAA,EAAK,KAAK,CAC1D,EAEMG,EAAW,MAAOC,EAAcC,IAAoC,CACxEf,EAAQ,MAAMc,CAAI,EAAE,EACpBvB,EAAS,IAAI,EACb,GAAI,CACF,MAAMF,EAAU,cAAc,mBAAmBP,EAAK,EAAE,CAAC,gBAAgB,mBAAmBgC,CAAI,CAAC,GAAI,CACnG,OAAQ,QACR,KAAM,CAAE,KAAM,CAACC,CAAA,CAAQ,CACxB,CACH,OAASzB,EAAK,CACZC,EAASD,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CAC3D,QAAA,CACEU,EAAQ,IAAI,CACd,CACF,EAEMgB,EAAQ,SAA2B,CACvC,MAAMN,EAAIb,EAAM,KAAA,EAChB,GAAKa,EACL,CAAAZ,EAAS,EAAE,EACXE,EAAQ,QAAQ,EAChBT,EAAS,IAAI,EACb,GAAI,CACF,MAAMF,EAAU,cAAc,mBAAmBP,EAAK,EAAE,CAAC,eAAgB,CACvE,OAAQ,OACR,KAAM,CAAE,MAAO4B,CAAA,CAAE,CAClB,CACH,OAASpB,EAAK,CACZC,EAASD,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CAC3D,QAAA,CACEU,EAAQ,IAAI,CACd,EACF,EAEMiB,EAAW,MAAOH,GAAgC,CACtDd,EAAQ,UAAUc,CAAI,EAAE,EACxBvB,EAAS,IAAI,EACb,GAAI,CACF,MAAMF,EAAU,cAAc,mBAAmBP,EAAK,EAAE,CAAC,gBAAgB,mBAAmBgC,CAAI,CAAC,GAAI,CACnG,OAAQ,QAAA,CACT,CACH,OAASxB,EAAK,CACZC,EAASD,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CAC3D,QAAA,CACEU,EAAQ,IAAI,CACd,CACF,EAEA,aACGkB,EAAA,CAAM,KAAAnC,EAAY,aAAAC,EACjB,SAAAT,EAAAA,IAAC4C,EAAA,CAAa,KAAK,QAAQ,MAAM,YACjC,SAAA9C,EAAAA,KAAC+C,GAAM,IAAK,EAAG,MAAO,CAAE,QAAS,kBAC/B,SAAA,CAAA/C,EAAAA,KAAC+C,EAAA,CAAM,IAAK,EACV,SAAA,CAAA7C,EAAAA,IAAC,QAAA,CAAM,QAAQ,aAAa,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,OAAA,CAE3F,EACAA,EAAAA,IAAC8C,EAAA,CAAO,IAAK,EACX,SAAA9C,EAAAA,IAAC+C,EAAA,CACC,GAAG,aACH,MAAO7D,EACP,SAAW8D,GAAM/B,EAAS+B,EAAE,OAAO,KAAK,EACxC,OAAQf,EACR,SAAUT,IAAS,KACnB,MAAO,CAAE,KAAM,CAAA,CAAE,CAAA,CACnB,CACF,CAAA,EACF,EAEA1B,EAAAA,KAAC+C,EAAA,CAAM,IAAK,EACV,SAAA,CAAA7C,EAAAA,IAAC,QAAA,CAAM,QAAQ,cAAc,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,QAAA,CAE5F,EACAF,EAAAA,KAACmD,GAAA,CAAO,MAAO7D,EAAQ,cAAe8C,EACpC,SAAA,CAAAlC,MAACkD,IAAc,GAAG,cAAc,KAAK,KAAK,YAAY,SAAS,QAC9DC,GAAA,CACE,SAAA9C,GAAe,IAAK+C,GACnBpD,EAAAA,IAACqD,GAAA,CAA2B,MAAOD,EAAI,MACpC,SAAAA,EAAI,OADUA,EAAI,KAErB,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EACF,EAEAtD,EAAAA,KAACgD,EAAA,CAAO,IAAK,EACX,SAAA,CAAAhD,OAAC+C,GAAM,IAAK,EAAG,MAAO,CAAE,KAAM,GAC5B,SAAA,CAAA7C,EAAAA,IAAC,QAAA,CAAM,QAAQ,aAAa,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,OAAA,CAE3F,QACC+C,EAAA,CAAM,GAAG,aAAa,MAAO5B,EAAO,SAAW6B,GAAM5B,EAAS4B,EAAE,OAAO,KAAK,EAAG,OAAQZ,EAAW,SAAUZ,IAAS,IAAA,CAAM,CAAA,EAC9H,EACA1B,OAAC+C,GAAM,IAAK,EAAG,MAAO,CAAE,KAAM,GAC5B,SAAA,CAAA7C,EAAAA,IAAC,QAAA,CAAM,QAAQ,WAAW,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,KAAA,CAEzF,EACAA,MAAC+C,GAAM,GAAG,WAAW,MAAOzD,EAAK,SAAW0D,GAAM3B,EAAO2B,EAAE,OAAO,KAAK,EAAG,OAAQX,EAAS,YAAY,aAAa,SAAUb,IAAS,IAAA,CAAM,CAAA,CAAA,CAC/I,CAAA,EACF,EAEA1B,EAAAA,KAAC+C,EAAA,CAAM,IAAK,EACV,SAAA,CAAA7C,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,aAAA,CAAW,EAC/EF,EAAAA,KAAC+C,EAAA,CAAM,IAAK,EACT,SAAA,CAAAtC,EAAK,WAAW,SAAW,GAC1BP,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,YAAS,EAE9EO,EAAK,WAAW,IAAK+C,UACnBR,EAAA,CAAmB,IAAK,EAAG,MAAM,SAChC,SAAA,CAAA9C,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,QAASsD,EAAG,KACZ,SAAU,IAAM,CAAOhB,EAASgB,EAAG,GAAIA,EAAG,IAAI,CAAG,EACjD,aAAY,UAAUA,EAAG,KAAK,GAC9B,SAAU9B,IAAS,IAAA,CAAA,EAErBxB,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,KAAM,EAAG,SAAU,eAAgB,eAAgBsD,EAAG,KAAO,eAAiB,MAAA,EAC1F,WAAG,MACN,EACCA,EAAG,UAAYtD,EAAAA,IAACC,GAAM,KAAK,UAAW,WAAG,SAAS,EAClDqD,EAAG,QACFxD,EAAAA,KAACG,EAAA,CAAM,KAAK,OAAO,MAAO,oBAAoBqD,EAAG,MAAM,GACrD,SAAA,CAAAtD,EAAAA,IAACuD,GAAA,CAAa,KAAM,GAAI,cAAW,GAAC,MAAO,CAAE,YAAa,EAAG,cAAe,aAAA,CAAc,CAAG,EAAE,MAAA,EAEjG,EAEFvD,EAAAA,IAACwD,EAAA,CACC,QAAQ,QACR,QAAS,IAAM,CAAOd,EAASY,EAAG,EAAE,CAAG,EACvC,SAAU9B,IAAS,KACnB,aAAY,UAAU8B,EAAG,KAAK,GAE9B,SAAAtD,EAAAA,IAACyD,EAAA,CAAO,KAAM,GAAI,cAAW,EAAA,CAAC,CAAA,CAAA,CAChC,CAAA,EAzBWH,EAAG,EA0BhB,CACD,CAAA,EACH,EACAxD,EAAAA,KAACgD,EAAA,CAAO,IAAK,EACX,SAAA,CAAA9C,EAAAA,IAAC+C,EAAA,CACC,MAAOzB,EACP,SAAW0B,GAAMzB,EAASyB,EAAE,OAAO,KAAK,EACxC,UAAYA,GAAM,CAAMA,EAAE,MAAQ,UAAWA,EAAE,eAAA,EAAuBP,EAAA,EAAW,EACjF,YAAY,kBACZ,SAAUjB,IAAS,KACnB,MAAO,CAAE,KAAM,CAAA,CAAE,CAAA,EAEnB1B,EAAAA,KAAC0D,EAAA,CAAO,QAAQ,YAAY,QAAS,IAAM,CAAOf,EAAA,CAAS,EAAG,SAAU,CAACnB,EAAM,KAAA,GAAUE,IAAS,KAChG,SAAA,CAAAxB,EAAAA,IAAC0D,EAAA,CAAK,KAAM,GAAI,cAAW,GAAC,EAAE,MAAA,CAAA,CAChC,CAAA,CAAA,CACF,CAAA,EACF,EAEA1D,MAAC,OAAI,MAAO,CAAE,UAAW,0BAA2B,WAAY,kBAC9D,SAAAF,EAAAA,KAAC0D,EAAA,CACC,QAAQ,SACR,QAAS,IAAM,CAAO3C,EAAA,CAAc,EACpC,SAAUH,GAAYc,IAAS,KAE/B,SAAA,CAAAxB,EAAAA,IAACyD,EAAA,CAAO,KAAM,GAAI,cAAW,GAAC,EAAE,IAAE/C,EAAW,YAAc,aAAA,CAAA,CAAA,EAE/D,EAECgB,IAAY,MACX1B,EAAAA,IAAC,MAAA,CAAI,KAAK,SAAS,MAAO,CAAE,SAAU,eAAgB,MAAO,gBAAA,EAAqB,SAAA0B,EAAQ,EAE3FE,IAAU,MACT5B,EAAAA,IAAC,MAAA,CAAI,KAAK,QAAQ,MAAO,CAAE,SAAU,eAAgB,MAAO,eAAA,EAAoB,SAAA4B,EAAM,EAEvFJ,IAAS,MAAQxB,EAAAA,IAAC2D,EAAA,CAAS,MAAO,CAAE,OAAQ,GAAG,CAAG,CAAA,CAAA,CACrD,EACF,EACA,CAEJ,CCxPA,SAASC,GAAWC,EAAwB,CAC1C,MAAO,CACL,GAAIA,EAAE,GACN,MAAOA,EAAE,MACT,YAAaA,EAAE,aAAe,GAC9B,OAAQA,EAAE,OACV,SAAUA,EAAE,SACZ,IAAKA,EAAE,IACP,UAAWA,EAAE,MACb,eAAgBA,EAAE,WAAW,OAAQC,GAAMA,EAAE,IAAI,EAAE,OACnD,gBAAiBD,EAAE,WAAW,MAAA,CAElC,CAEO,SAASE,IAAyB,CACvC,MAAMC,EAAQC,EAA6C,YAAY,EACjE,CAACC,EAAOC,CAAQ,EAAIvD,EAAAA,SAAiB,CAAA,CAAE,EACvC,CAACwD,EAAaC,CAAc,EAAIzD,EAAAA,SAAS,EAAK,EAC9C,CAAC0D,EAAYC,CAAa,EAAI3D,EAAAA,SAAwB,IAAI,EAC1D,CAAC4D,EAAUC,CAAW,EAAI7D,EAAAA,SAAkB,EAAK,EACjD,CAAC8D,EAAaC,CAAc,EAAI/D,EAAAA,SAAwB,IAAI,EAC5D,CAACgE,EAAgBC,CAAiB,EAAIjE,EAAAA,SAAwB,IAAI,EAClE,CAACkE,EAAcC,CAAe,EAAInE,EAAAA,SAAiB,KAAK,EAIxD,CAACoE,EAAaC,CAAc,EAAIrE,EAAAA,SAAwD,IAAI,EAC5F,CAACsE,EAAiBC,CAAkB,EAAIvE,EAAAA,SAAwB,IAAI,EAEpEwE,EAAgBN,IAAiB,MAAQZ,EAAQA,EAAM,OAAQL,GAAMA,EAAE,SAAWiB,CAAY,EAE9FO,EAAiB,CAAC,MAAO,SAAU,WAAY,UAAW,YAAa,UAAW,MAAM,EAE9FxD,EAAAA,UAAU,IAAM,QACVyD,EAAAtB,EAAM,OAAN,MAAAsB,EAAY,OAAS,CAAClB,IACxBC,EAAe,EAAI,EACnBF,EAASH,EAAM,KAAK,KAAK,EAE7B,EAAG,CAACA,EAAM,KAAMI,CAAW,CAAC,EAE5B,MAAMmB,EAAWC,cAAaC,GAAmB,CAC/C,GAAIA,EAAI,OAAS,eAAgB,OACjC,MAAM5B,EAAK4B,EAAqD,KAChE,GAAK5B,EAEL,IAAI,YAAaA,GAAMA,EAA4B,QAAS,CAC1DM,EAAUuB,GAASA,EAAK,OAAQC,GAAMA,EAAE,KAAO9B,EAAE,EAAE,CAAC,EAChDS,IAAeT,EAAE,IAAIU,EAAc,IAAI,EAC3C,MACF,CACAJ,EAAUuB,GAAS,CACjB,MAAME,EAAMF,EAAK,UAAWC,GAAMA,EAAE,KAAO9B,EAAE,EAAE,EAC/C,GAAI+B,IAAQ,GAAI,MAAO,CAAC,GAAGF,EAAM7B,CAAC,EAClC,MAAMgC,EAAOH,EAAK,MAAA,EAClB,OAAAG,EAAKD,CAAG,EAAI/B,EACLgC,CACT,CAAC,EACH,EAAG,CAACvB,CAAU,CAAC,EACfwB,EAAa,eAAgBP,CAAQ,EACrCO,EAAa,gBAAkBL,GAAQ,CACrC,MAAMM,EAAMN,EAAsD,GAClEtB,EAAUuB,GAASA,EAAK,OAAQC,GAAMA,EAAE,KAAOI,CAAE,CAAC,EAC9CzB,IAAeyB,GAAIxB,EAAc,IAAI,CAC3C,CAAC,EAED,MAAMyB,EAAaR,EAAAA,YAAY,SAAY,CAGzCP,EAAe,CAAE,MAAO,GAAI,YAAa,GAAI,CAC/C,EAAG,CAAA,CAAE,EAECgB,EAAaT,EAAAA,YAAY,SAAY,CACzC,GAAI,GAACR,GAAe,CAACA,EAAY,MAAM,QACvC,CAAAP,EAAY,EAAI,EAChBI,EAAkB,IAAI,EACtB,GAAI,CACF,MAAMqB,EAAM,MAAMpF,EAAwC,aAAc,CACtE,OAAQ,OACR,KAAM,CACJ,MAAOkE,EAAY,MAAM,KAAA,EACzB,YAAaA,EAAY,YAAY,KAAA,GAAU,OAC/C,OAAQ,QAAA,CACV,CACD,EACGkB,EAAI,MAAM/B,EAAUuB,GAAS,CAAC,GAAGA,EAAMQ,EAAI,IAAY,CAAC,EACxDA,EAAI,IAAI3B,EAAc2B,EAAI,EAAE,EAChCjB,EAAe,IAAI,CACrB,OAASlE,EAAK,CACZ8D,EAAkB9D,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CACpE,QAAA,CACE0D,EAAY,EAAK,CACnB,EACF,EAAG,CAACO,CAAW,CAAC,EAEVmB,EAAW7B,EAAaJ,EAAM,KAAML,GAAMA,EAAE,KAAOS,CAAU,GAAK,KAAO,KAEzE8B,EAAYZ,cAAY,MAAOa,GAAmB,CACtD1B,EAAe0B,CAAM,EACrBxB,EAAkB,IAAI,EACtB,GAAI,CACF,MAAMqB,EAAM,MAAMpF,EAChB,cAAc,mBAAmBuF,CAAM,CAAC,aACxC,CAAE,OAAQ,MAAA,CAAO,EAIf,MAAM,QAAQH,EAAI,OAAO,GAAKA,EAAI,QAAQ,OAAS,GACrD/B,EAAUuB,GAASA,EAAK,IAAK7B,GAAM,CACjC,GAAIA,EAAE,KAAOwC,EAAQ,OAAOxC,EAC5B,MAAMyC,GAAOzC,EAAE,YAAc,CAAA,GAAI,IAAKP,GAAO,CAC3C,MAAMiD,EAAOL,EAAI,QAAQ,KAAMM,GAAMA,EAAE,KAAOlD,EAAG,EAAE,EACnD,OAAOiD,EAAO,CAAE,GAAGjD,EAAI,OAAQiD,EAAK,MAASjD,CAC/C,CAAC,EACD,MAAO,CAAE,GAAGO,EAAG,WAAYyC,CAAA,CAC7B,CAAC,CAAC,CAEN,OAASvF,EAAK,CACZ8D,EAAkB9D,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CACpE,QAAA,CACE4D,EAAe,IAAI,CACrB,CACF,EAAG,CAAA,CAAE,EAEC8B,EAAajB,cAAY,MAAOa,GAAmB,CACvD,GAAI,CACF,MAAMvF,EAAU,cAAc,mBAAmBuF,CAAM,CAAC,GAAI,CAAE,OAAQ,SAAU,EAGhFlC,EAAUuB,GAASA,EAAK,OAAQC,GAAMA,EAAE,KAAOU,CAAM,CAAC,EAClD/B,IAAe+B,GAAQ9B,EAAc,IAAI,EAC7CY,EAAmB,IAAI,CACzB,OAASpE,EAAK,CACZ8D,EAAkB9D,aAAe,MAAQA,EAAI,QAAU,OAAOA,CAAG,CAAC,CACpE,CACF,EAAG,CAACuD,CAAU,CAAC,EAEf,OACExE,EAAAA,KAAC+C,EAAA,CAAM,IAAK,EAAG,cAAY,aACzB,SAAA,CAAA7C,EAAAA,IAAC0G,GAAA,CACC,MAAM,QACN,YAAY,2DACZ,QACE5G,EAAAA,KAAC0D,EAAA,CAAO,QAAQ,UAAU,QAAS,IAAM,CAAOwC,EAAA,CAAc,EAAG,SAAUxB,EACzE,SAAA,CAAAxE,EAAAA,IAAC0D,EAAA,CAAK,KAAM,GAAI,cAAW,GAAC,EAAE,WAAA,CAAA,CAChC,CAAA,CAAA,EAGJ1D,EAAAA,IAAC2G,GAAA,CACC,MAAM,YACN,MAAOzC,EAAM,OACb,OAAO,oBACP,cACGpB,EAAA,CAAO,IAAK,EAAG,KAAI,GACjB,WAAe,IAAK,GACnBhD,EAAAA,KAAC8G,EAAA,CAAa,SAAU9B,IAAiB,EAAG,QAAS,IAAMC,EAAgB,CAAC,EACzE,SAAA,CAAA,IAAM,MAAQ,MAAQ,EAAE,QAAQ,KAAM,GAAG,EACzC,IAAM,OAAS,MAAMb,EAAM,OAAQL,GAAMA,EAAE,SAAW,CAAC,EAAE,MAAM,EAAA,CAAA,EAFvD,CAGX,CACD,CAAA,CACH,CAAA,CAAA,EAGHe,IAAmB,MAClB9E,EAAAA,KAAC,OAAI,KAAK,QAAQ,MAAO,CAAE,QAAS,iBAAkB,WAAY,2DAA4D,OAAQ,0BAA2B,aAAc,mBAAoB,SAAU,gBAAkB,SAAA,CAAA,qBAC1M8E,CAAA,EACrB,EAEDZ,EAAM,SAAWE,EAAM,SAAW,EACjCpE,OAAC+C,EAAA,CAAM,IAAK,EACV,SAAA,CAAA7C,EAAAA,IAAC2D,EAAA,CAAS,MAAO,CAAE,OAAQ,KAAO,QACjCA,EAAA,CAAS,MAAO,CAAE,OAAQ,IAAI,CAAG,CAAA,CAAA,CACpC,EACEK,EAAM,OAASE,EAAM,SAAW,EAClClE,EAAAA,IAAC6G,GAAA,CACC,MAAK,GACL,MAAM,sBACN,YAAY,+CACZ,MAAO7C,EAAM,MACb,QAAS,IAAM,KAAKA,EAAM,QAAA,EAC1B,OAAO,aAAA,CAAA,EAEPoB,EAAc,SAAW,EAC3BpF,EAAAA,IAAC8G,GAAA,CACC,SAAA9G,EAAAA,IAAC+G,GAAA,CACC,SAAAjH,OAAC+C,EAAA,CAAM,IAAK,EACV,SAAA,CAAA/C,OAAC,SAAA,CAAO,SAAA,CAAA,YAAUgF,IAAiB,MAAQ,MAAQ,gBAAgBA,CAAY,IAAI,GAAA,EAAC,SACnF,OAAA,CAAK,MAAO,CAAE,MAAO,mBAAqB,SAAA,CAAA,6CACC9E,EAAAA,IAAC,QAAK,SAAA,cAAA,CAAkB,EAAO,GAAA,CAAA,CAC3E,CAAA,CAAA,CACF,CAAA,CACF,CAAA,CACF,EAEAA,EAAAA,IAACgH,EAAA,CAAK,KAAM,EACT,SAAA5B,EAAc,IAAKvB,GAAM,OACxB,MAAMoD,IAAU3B,EAAAzB,EAAE,aAAF,YAAAyB,EAAc,SAAU,EAClC4B,GAAcrD,EAAE,YAAc,CAAA,GAAI,MAAOP,GAAO,EAAQA,EAAG,MAAO,EACxE,OACEtD,EAAAA,IAAC,MAAA,CAEC,KAAK,SACL,SAAU,EACV,QAAS,IAAMuE,EAAcV,EAAE,EAAE,EACjC,UAAYb,GAAM,EAAMA,EAAE,MAAQ,SAAWA,EAAE,MAAQ,OAAOA,EAAE,eAAA,EAAkBuB,EAAcV,EAAE,EAAE,EAAK,EACzG,MAAO,CAAE,OAAQ,UAAW,QAAS,MAAA,EACrC,cAAa,aAAaA,EAAE,EAAE,GAE9B,SAAA/D,EAAAA,KAAC+C,EAAA,CAAM,IAAK,EACV,SAAA,CAAA7C,EAAAA,IAAChB,GAAA,CAAU,GAAG4E,GAAWC,CAAC,CAAA,CAAG,EAC5BqB,IAAoBrB,EAAE,GACrB/D,EAAAA,KAACgD,EAAA,CAAO,MAAM,SAAS,QAAQ,MAAM,IAAK,EACxC,SAAA,CAAA9C,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,kDAAA,CAErE,EACAA,EAAAA,IAACwD,EAAA,CACC,QAAQ,SACR,KAAK,KACL,QAAUR,GAAM,CAAEA,EAAE,gBAAA,EAAwByD,EAAW5C,EAAE,EAAE,CAAG,EAC9D,cAAa,uBAAuBA,EAAE,EAAE,GACzC,SAAA,QAAA,CAAA,EAGD7D,EAAAA,IAACwD,EAAA,CACC,QAAQ,QACR,KAAK,KACL,QAAUR,GAAM,CAAEA,EAAE,gBAAA,EAAmBmC,EAAmB,IAAI,CAAG,EAClE,SAAA,QAAA,CAAA,CAED,CAAA,CACF,QAECrC,EAAA,CAAO,MAAM,SAAS,QAAQ,MAAM,IAAK,EACxC,SAAAhD,EAAAA,KAAC0D,EAAA,CACC,QAAQ,QACR,QAAUR,GAAM,CAAEA,EAAE,gBAAA,EAAmBmC,EAAmBtB,EAAE,EAAE,CAAG,EACjE,MAAM,cACN,aAAY,eAAeA,EAAE,KAAK,GAClC,cAAa,eAAeA,EAAE,EAAE,GAEhC,SAAA,CAAA7D,EAAAA,IAACyD,EAAA,CAAO,KAAM,GAAI,cAAW,GAAC,EAAE,SAAA,CAAA,CAAA,EAEpC,EAEDwD,EAAU,GACTnH,OAACgD,EAAA,CAAO,MAAM,SAAS,QAAQ,MAAM,IAAK,EACxC,SAAA,CAAA9C,MAAC,QAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAC7C,SAAAkH,EAAa,aAAe,GAAGD,CAAO,cAAcA,IAAY,EAAI,GAAK,GAAG,oBAC/E,EACAnH,EAAAA,KAAC0D,EAAA,CACC,QAAQ,YACR,QAAUR,GAAM,CAAEA,EAAE,gBAAA,EAAwBoD,EAAUvC,EAAE,EAAE,CAAG,EAC7D,SAAUa,IAAgBb,EAAE,GAC5B,MAAOqD,EAAa,+BAAiC,iCAErD,SAAA,CAAAlH,EAAAA,IAAC0D,EAAA,CAAK,KAAM,GAAI,cAAW,GAAC,EAAE,IAAEwD,EAAa,gBAAkB,mBAAA,CAAA,CAAA,CACjE,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,EA3DKrD,EAAE,EAAA,CA8Db,CAAC,CAAA,CACH,EAGDsC,GACCnG,EAAAA,IAACM,GAAA,CACC,KAAM6F,EACN,KAAM7B,IAAe,KACrB,aAAe6C,GAAM,CAAOA,GAAG5C,EAAc,IAAI,CAAG,CAAA,CAAA,QAMvD5B,EAAA,CAAM,KAAMqC,IAAgB,KAAM,aAAemC,GAAM,CAAOA,GAAGlC,EAAe,IAAI,CAAG,EACtF,SAAAjF,EAAAA,IAAC4C,EAAA,CAAa,KAAK,QAAQ,MAAM,WAC9B,SAAAoC,IAAgB,MACflF,EAAAA,KAAC+C,GAAM,IAAK,EAAG,MAAO,CAAE,QAAS,kBAC/B,SAAA,CAAA/C,EAAAA,KAAC+C,EAAA,CAAM,IAAK,EACV,SAAA,CAAA7C,EAAAA,IAAC,QAAA,CAAM,QAAQ,oBAAoB,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,OAAA,CAAK,EACvGA,EAAAA,IAAC+C,EAAA,CACC,GAAG,oBACH,MAAOiC,EAAY,MACnB,SAAWhC,GAAMiC,EAAe,CAAE,GAAGD,EAAa,MAAOhC,EAAE,OAAO,MAAO,EACzE,YAAY,gCACZ,SAAUwB,EACV,cAAY,mBAAA,CAAA,CACd,EACF,EACA1E,EAAAA,KAAC+C,EAAA,CAAM,IAAK,EACV,SAAA,CAAA7C,EAAAA,IAAC,QAAA,CAAM,QAAQ,mBAAmB,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,wBAAA,CAAsB,EACvHA,EAAAA,IAACoH,GAAA,CACC,GAAG,mBACH,MAAOpC,EAAY,YACnB,SAAWhC,GAAMiC,EAAe,CAAE,GAAGD,EAAa,YAAahC,EAAE,OAAO,MAAO,EAC/E,KAAM,EACN,YAAY,mDACZ,SAAUwB,EACV,cAAY,kBAAA,CAAA,CACd,EACF,EACA1E,EAAAA,KAACgD,EAAA,CAAO,IAAK,EACX,SAAA,CAAA9C,EAAAA,IAACwD,EAAA,CACC,QAAQ,UACR,QAAS,IAAM,CAAOyC,EAAA,CAAc,EACpC,SAAUzB,GAAY,CAACQ,EAAY,MAAM,KAAA,EACzC,cAAY,qBACb,SAAA,aAAA,CAAA,EAGDhF,EAAAA,IAACwD,EAAA,CAAO,QAAQ,QAAQ,QAAS,IAAMyB,EAAe,IAAI,EAAG,SAAUT,EAAU,SAAA,QAAA,CAEjF,CAAA,CAAA,CACF,CAAA,CAAA,CACF,EAEJ,CAAA,CACF,CAAA,EACF,CAEJ"}
|
|
1
|
+
{"version":3,"file":"GoalsView-pwROHApi.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-DVxytz9i.js";import{g as T}from"./main-
|
|
1
|
+
import{r as w,j as A}from"./cmdk-DVxytz9i.js";import{g as T}from"./main-CokHAXWM.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-qcvbhx6e.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,4 +1,4 @@
|
|
|
1
|
-
import{r as g,j as a}from"./cmdk-DVxytz9i.js";import{c as C,u as k,S as o,I as m,d as l,h as T,N as B,B as z,i as d,F as c}from"./main-
|
|
1
|
+
import{r as g,j as a}from"./cmdk-DVxytz9i.js";import{c as C,u as k,S as o,I as m,d as l,h as T,N as B,B as z,i as d,F as c}from"./main-CokHAXWM.js";import{G as E}from"./Grid-qcvbhx6e.js";import{V as O}from"./ViewHeader-BzYZ3m-e.js";import{C as f,b as u}from"./Card-B0imhxMk.js";import{R as q}from"./refresh-cw-CoAHDpeS.js";import{P as H}from"./plug-DBrVM9lK.js";import{P as M}from"./play-BoLrrcBA.js";import{R as U}from"./rotate-cw-xpPJw9LP.js";/**
|
|
2
2
|
* @license lucide-react v0.460.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
package/bizar-dash/dist/assets/{HeadroomView-CNc-TI7u.js.map → HeadroomView-D1UiTYbt.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HeadroomView-CNc-TI7u.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/square.js","../../../node_modules/lucide-react/dist/esm/icons/unplug.js","../../src/web/v8/views/Headroom/HeadroomView.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Square = createLucideIcon(\"Square\", [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }]\n]);\n\nexport { Square as default };\n//# sourceMappingURL=square.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Unplug = createLucideIcon(\"Unplug\", [\n [\"path\", { d: \"m19 5 3-3\", key: \"yk6iyv\" }],\n [\"path\", { d: \"m2 22 3-3\", key: \"19mgm9\" }],\n [\n \"path\",\n { d: \"M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z\", key: \"goz73y\" }\n ],\n [\"path\", { d: \"M7.5 13.5 10 11\", key: \"7xgeeb\" }],\n [\"path\", { d: \"M10.5 16.5 13 14\", key: \"10btkg\" }],\n [\n \"path\",\n { d: \"m12 6 6 6 2.3-2.3a2.4 2.4 0 0 0 0-3.4l-2.6-2.6a2.4 2.4 0 0 0-3.4 0Z\", key: \"1snsnr\" }\n ]\n]);\n\nexport { Unplug as default };\n//# sourceMappingURL=unplug.js.map\n","import { useEffect, useState } from 'react';\nimport { Network, Play, Square, Plug, Unplug, RotateCw, RefreshCw } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { Grid } from '../../ui/primitives/Grid.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Badge } from '../../ui/data/Badge.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\n/**\n * HeadroomView — Sprint S35. Headroom proxy install + lifecycle.\n */\n\ntype Status = 'installed' | 'not-installed' | 'running' | 'stopped';\n\ninterface HeadroomStatus {\n status: Status;\n version?: string;\n port?: number;\n message?: string;\n}\n\ninterface HeadroomStats {\n hours?: number;\n requests?: number;\n tokensSaved?: number;\n cacheHits?: number;\n cacheMisses?: number;\n}\n\nexport function HeadroomView(): JSX.Element {\n const status = useFetch<HeadroomStatus>('/api/headroom/status');\n const stats = useFetch<HeadroomStats>('/api/headroom/stats?hours=24');\n const [busy, setBusy] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const id = setInterval(() => { void status.refetch(); }, 15_000);\n return () => clearInterval(id);\n }, [status]);\n\n const install = async (): Promise<void> => {\n setBusy('install');\n setError(null);\n try {\n await fetchJson('/api/headroom/install', { method: 'POST', body: { force: false } });\n void status.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const wrap = async (): Promise<void> => {\n setBusy('wrap');\n setError(null);\n try {\n await fetchJson('/api/headroom/wrap', { method: 'POST', body: { port: 8787 } });\n void status.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const unwrap = async (): Promise<void> => {\n setBusy('unwrap');\n setError(null);\n try {\n await fetchJson('/api/headroom/unwrap', { method: 'POST' });\n void status.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const start = async (): Promise<void> => {\n setBusy('start');\n setError(null);\n try {\n await fetchJson('/api/headroom/start', { method: 'POST' });\n void status.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const stop = async (): Promise<void> => {\n setBusy('stop');\n setError(null);\n try {\n await fetchJson('/api/headroom/stop', { method: 'POST' });\n void status.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const s = status.data;\n const isInstalled = s && s.status !== 'not-installed';\n const isRunning = s?.status === 'running';\n\n return (\n <Stack gap={5} data-testid=\"headroom-view\">\n <ViewHeader\n title=\"Headroom\"\n description=\"Local proxy that reduces token cost via caching + batching. Install, wrap Cline, start/stop.\"\n actions={\n <Inline gap={2} align=\"center\">\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Button variant=\"ghost\" onClick={() => { void status.refetch(); }} data-testid=\"headroom-refresh\">\n <RefreshCw size={14} aria-hidden /> Refresh\n </Button>\n </Inline>\n }\n />\n\n <Card variant=\"elevated\">\n <CardBody>\n {status.loading && !s ? (\n <Skeleton style={{ height: 60 }} />\n ) : (\n <Inline align=\"center\" justify=\"between\" gap={3}>\n <Stack gap={1}>\n <Inline align=\"center\" gap={2}>\n <Network size={16} aria-hidden />\n <strong>{s?.status ?? 'unknown'}</strong>\n {s?.version && <Badge tone=\"neutral\">v{s.version}</Badge>}\n {s?.port && <Badge tone=\"info\">port {s.port}</Badge>}\n </Inline>\n {s?.message && <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{s.message}</span>}\n </Stack>\n <Inline gap={1} wrap={true}>\n {!isInstalled && (\n <Button variant=\"primary\" onClick={() => void install()} disabled={busy === 'install'} data-testid=\"headroom-install\">\n <Plug size={12} aria-hidden /> {busy === 'install' ? 'Installing…' : 'Install'}\n </Button>\n )}\n {isInstalled && (\n <>\n <Button variant={isRunning ? 'secondary' : 'primary'} onClick={() => void (isRunning ? stop() : start())} disabled={busy === 'start' || busy === 'stop'} data-testid=\"headroom-toggle-running\">\n {isRunning ? <Square size={12} aria-hidden /> : <Play size={12} aria-hidden />}\n {isRunning ? (busy === 'stop' ? 'Stopping…' : 'Stop') : (busy === 'start' ? 'Starting…' : 'Start')}\n </Button>\n <Button variant=\"ghost\" onClick={() => void wrap()} disabled={busy === 'wrap'} data-testid=\"headroom-wrap\">\n <RotateCw size={12} aria-hidden /> {busy === 'wrap' ? 'Wrapping…' : 'Wrap Cline'}\n </Button>\n <Button variant=\"ghost\" onClick={() => void unwrap()} disabled={busy === 'unwrap'} data-testid=\"headroom-unwrap\">\n <Unplug size={12} aria-hidden /> {busy === 'unwrap' ? 'Unwrapping…' : 'Unwrap'}\n </Button>\n </>\n )}\n </Inline>\n </Inline>\n )}\n </CardBody>\n </Card>\n\n <Grid cols={3}>\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Requests (24h)</span>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-18)' }}>{stats.data?.requests ?? 0}</strong>\n </Stack>\n </CardBody>\n </Card>\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Tokens saved</span>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-18)' }}>{stats.data?.tokensSaved ?? 0}</strong>\n </Stack>\n </CardBody>\n </Card>\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Cache hits / misses</span>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-18)' }}>\n {stats.data?.cacheHits ?? 0} / {stats.data?.cacheMisses ?? 0}\n </strong>\n </Stack>\n </CardBody>\n </Card>\n </Grid>\n </Stack>\n );\n}"],"names":["Square","createLucideIcon","Unplug","HeadroomView","status","useFetch","stats","busy","setBusy","useState","error","setError","useEffect","id","install","fetchJson","err","FetchError","wrap","unwrap","start","stop","s","isInstalled","isRunning","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCw","Card","CardBody","Skeleton","Network","Badge","Plug","Fragment","Play","RotateCw","Grid","_a","_b","_c","_d"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
1
|
+
{"version":3,"file":"HeadroomView-D1UiTYbt.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/square.js","../../../node_modules/lucide-react/dist/esm/icons/unplug.js","../../src/web/v8/views/Headroom/HeadroomView.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Square = createLucideIcon(\"Square\", [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }]\n]);\n\nexport { Square as default };\n//# sourceMappingURL=square.js.map\n","/**\n * @license lucide-react v0.460.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Unplug = createLucideIcon(\"Unplug\", [\n [\"path\", { d: \"m19 5 3-3\", key: \"yk6iyv\" }],\n [\"path\", { d: \"m2 22 3-3\", key: \"19mgm9\" }],\n [\n \"path\",\n { d: \"M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z\", key: \"goz73y\" }\n ],\n [\"path\", { d: \"M7.5 13.5 10 11\", key: \"7xgeeb\" }],\n [\"path\", { d: \"M10.5 16.5 13 14\", key: \"10btkg\" }],\n [\n \"path\",\n { d: \"m12 6 6 6 2.3-2.3a2.4 2.4 0 0 0 0-3.4l-2.6-2.6a2.4 2.4 0 0 0-3.4 0Z\", key: \"1snsnr\" }\n ]\n]);\n\nexport { Unplug as default };\n//# sourceMappingURL=unplug.js.map\n","import { useEffect, useState } from 'react';\nimport { Network, Play, Square, Plug, Unplug, RotateCw, RefreshCw } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { Grid } from '../../ui/primitives/Grid.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Badge } from '../../ui/data/Badge.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\n/**\n * HeadroomView — Sprint S35. Headroom proxy install + lifecycle.\n */\n\ntype Status = 'installed' | 'not-installed' | 'running' | 'stopped';\n\ninterface HeadroomStatus {\n status: Status;\n version?: string;\n port?: number;\n message?: string;\n}\n\ninterface HeadroomStats {\n hours?: number;\n requests?: number;\n tokensSaved?: number;\n cacheHits?: number;\n cacheMisses?: number;\n}\n\nexport function HeadroomView(): JSX.Element {\n const status = useFetch<HeadroomStatus>('/api/headroom/status');\n const stats = useFetch<HeadroomStats>('/api/headroom/stats?hours=24');\n const [busy, setBusy] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const id = setInterval(() => { void status.refetch(); }, 15_000);\n return () => clearInterval(id);\n }, [status]);\n\n const install = async (): Promise<void> => {\n setBusy('install');\n setError(null);\n try {\n await fetchJson('/api/headroom/install', { method: 'POST', body: { force: false } });\n void status.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const wrap = async (): Promise<void> => {\n setBusy('wrap');\n setError(null);\n try {\n await fetchJson('/api/headroom/wrap', { method: 'POST', body: { port: 8787 } });\n void status.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const unwrap = async (): Promise<void> => {\n setBusy('unwrap');\n setError(null);\n try {\n await fetchJson('/api/headroom/unwrap', { method: 'POST' });\n void status.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const start = async (): Promise<void> => {\n setBusy('start');\n setError(null);\n try {\n await fetchJson('/api/headroom/start', { method: 'POST' });\n void status.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const stop = async (): Promise<void> => {\n setBusy('stop');\n setError(null);\n try {\n await fetchJson('/api/headroom/stop', { method: 'POST' });\n void status.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(null);\n }\n };\n\n const s = status.data;\n const isInstalled = s && s.status !== 'not-installed';\n const isRunning = s?.status === 'running';\n\n return (\n <Stack gap={5} data-testid=\"headroom-view\">\n <ViewHeader\n title=\"Headroom\"\n description=\"Local proxy that reduces token cost via caching + batching. Install, wrap Cline, start/stop.\"\n actions={\n <Inline gap={2} align=\"center\">\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Button variant=\"ghost\" onClick={() => { void status.refetch(); }} data-testid=\"headroom-refresh\">\n <RefreshCw size={14} aria-hidden /> Refresh\n </Button>\n </Inline>\n }\n />\n\n <Card variant=\"elevated\">\n <CardBody>\n {status.loading && !s ? (\n <Skeleton style={{ height: 60 }} />\n ) : (\n <Inline align=\"center\" justify=\"between\" gap={3}>\n <Stack gap={1}>\n <Inline align=\"center\" gap={2}>\n <Network size={16} aria-hidden />\n <strong>{s?.status ?? 'unknown'}</strong>\n {s?.version && <Badge tone=\"neutral\">v{s.version}</Badge>}\n {s?.port && <Badge tone=\"info\">port {s.port}</Badge>}\n </Inline>\n {s?.message && <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{s.message}</span>}\n </Stack>\n <Inline gap={1} wrap={true}>\n {!isInstalled && (\n <Button variant=\"primary\" onClick={() => void install()} disabled={busy === 'install'} data-testid=\"headroom-install\">\n <Plug size={12} aria-hidden /> {busy === 'install' ? 'Installing…' : 'Install'}\n </Button>\n )}\n {isInstalled && (\n <>\n <Button variant={isRunning ? 'secondary' : 'primary'} onClick={() => void (isRunning ? stop() : start())} disabled={busy === 'start' || busy === 'stop'} data-testid=\"headroom-toggle-running\">\n {isRunning ? <Square size={12} aria-hidden /> : <Play size={12} aria-hidden />}\n {isRunning ? (busy === 'stop' ? 'Stopping…' : 'Stop') : (busy === 'start' ? 'Starting…' : 'Start')}\n </Button>\n <Button variant=\"ghost\" onClick={() => void wrap()} disabled={busy === 'wrap'} data-testid=\"headroom-wrap\">\n <RotateCw size={12} aria-hidden /> {busy === 'wrap' ? 'Wrapping…' : 'Wrap Cline'}\n </Button>\n <Button variant=\"ghost\" onClick={() => void unwrap()} disabled={busy === 'unwrap'} data-testid=\"headroom-unwrap\">\n <Unplug size={12} aria-hidden /> {busy === 'unwrap' ? 'Unwrapping…' : 'Unwrap'}\n </Button>\n </>\n )}\n </Inline>\n </Inline>\n )}\n </CardBody>\n </Card>\n\n <Grid cols={3}>\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Requests (24h)</span>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-18)' }}>{stats.data?.requests ?? 0}</strong>\n </Stack>\n </CardBody>\n </Card>\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Tokens saved</span>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-18)' }}>{stats.data?.tokensSaved ?? 0}</strong>\n </Stack>\n </CardBody>\n </Card>\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Cache hits / misses</span>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-18)' }}>\n {stats.data?.cacheHits ?? 0} / {stats.data?.cacheMisses ?? 0}\n </strong>\n </Stack>\n </CardBody>\n </Card>\n </Grid>\n </Stack>\n );\n}"],"names":["Square","createLucideIcon","Unplug","HeadroomView","status","useFetch","stats","busy","setBusy","useState","error","setError","useEffect","id","install","fetchJson","err","FetchError","wrap","unwrap","start","stop","s","isInstalled","isRunning","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCw","Card","CardBody","Skeleton","Network","Badge","Plug","Fragment","Play","RotateCw","Grid","_a","_b","_c","_d"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as a,j as e}from"./cmdk-DVxytz9i.js";import{u as x,a as y,S as f,d as g,I as v,h,Q as b,B as k}from"./main-
|
|
1
|
+
import{r as a,j as e}from"./cmdk-DVxytz9i.js";import{u as x,a as y,S as f,d as g,I as v,h,Q as b,B as k}from"./main-CokHAXWM.js";import{V as w}from"./ViewHeader-BzYZ3m-e.js";import{C,b as S}from"./Card-B0imhxMk.js";import{E as F}from"./EmptyState-BjgVOrcO.js";import{E as M}from"./ErrorState-BE3WBFqF.js";import{R}from"./refresh-ccw-DNrXX9gB.js";import"./Alert-CG5q_s75.js";import"./circle-alert-DHvsqpw5.js";import"./triangle-alert-_2xe_tl4.js";import"./circle-check-Bx8wmXR9.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-Dv7aPxJE.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-C7SSOLJA.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-DVxytz9i.js";import{g as x}from"./main-
|
|
1
|
+
import{r as c,j as s}from"./cmdk-DVxytz9i.js";import{g as x}from"./main-CokHAXWM.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-Bgzxf_Hu.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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as e,r as m}from"./cmdk-DVxytz9i.js";import{B as v,g,u as f,a as x,S as b,h as k}from"./main-
|
|
1
|
+
import{j as e,r as m}from"./cmdk-DVxytz9i.js";import{B as v,g,u as f,a as x,S as b,h as k}from"./main-CokHAXWM.js";import{C as y,V as j}from"./ViewHeader-BzYZ3m-e.js";import"./Grid-qcvbhx6e.js";import"./AgentActivity-79l4SBMC.js";import"./Input-Bgzxf_Hu.js";import"./Textarea-BzIAwSlp.js";import"./Switch-CwXfsDii.js";import"./Select-Dbd88_n8.js";import"./Slider-BJCvKI1I.js";import"./Alert-CG5q_s75.js";import"./Avatar-ulUPIYTd.js";import{E as S}from"./EmptyState-BjgVOrcO.js";import"./Sheet-DnDid58j.js";import"./Card-B0imhxMk.js";import"./Chip-wwZSGwLE.js";import"./ActivityFeed-JjmOY2AQ.js";import"./Sparkline-ktqQLdyb.js";import"./ProgressBar-DlZTETEn.js";import{P as E}from"./power-DLjXF7zE.js";import"./SettingsRow-CLMNd434.js";import"./MessageBubble-5vUAquDx.js";import{E as T}from"./ErrorState-BE3WBFqF.js";import"./dnd-kit-DrHErSkw.js";import"./plus-DENm0hqV.js";import"./calendar-C0lgZk69.js";import"./index-CASP1n-5.js";import"./index-C4Vq_2LM.js";import"./circle-alert-DHvsqpw5.js";import"./triangle-alert-_2xe_tl4.js";import"./circle-check-Bx8wmXR9.js";import"./trending-up-DMj-AJVf.js";import"./refresh-ccw-DNrXX9gB.js";const C={enabled:"Enabled",disabled:"Disabled",error:"Error"},N={enabled:"success",disabled:"neutral",error:"danger"};function I(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:g("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(E,{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(v,{tone:N[r],size:"sm",children:C[r]}),p,e.jsx(y,{size:14,"aria-hidden":"true",style:{color:"var(--fg-subtle)"}})]})]})]}),e.jsx("style",{children:`
|
|
2
2
|
.v8-library-item:hover {
|
|
3
3
|
border-color: var(--accent);
|
|
4
4
|
background: var(--surface-2);
|