@polderlabs/bizar 10.4.2 → 10.4.4

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.
Files changed (262) hide show
  1. package/bizar-dash/dist/assets/{ActivityFeed-DtRtg-JN.js → ActivityFeed-RQeyFifx.js} +1 -1
  2. package/bizar-dash/dist/assets/{ActivityFeed-DtRtg-JN.js.map → ActivityFeed-RQeyFifx.js.map} +1 -1
  3. package/bizar-dash/dist/assets/{ActivityView-CoTXDyU_.js → ActivityView-CibyssPM.js} +1 -1
  4. package/bizar-dash/dist/assets/{ActivityView-CoTXDyU_.js.map → ActivityView-CibyssPM.js.map} +1 -1
  5. package/bizar-dash/dist/assets/AdminView-BjczABeB.js +11 -0
  6. package/bizar-dash/dist/assets/AdminView-BjczABeB.js.map +1 -0
  7. package/bizar-dash/dist/assets/{AgentActivity-CrX7LmQ6.js → AgentActivity-Bywt1twv.js} +1 -1
  8. package/bizar-dash/dist/assets/{AgentActivity-CrX7LmQ6.js.map → AgentActivity-Bywt1twv.js.map} +1 -1
  9. package/bizar-dash/dist/assets/AgentsView-BnOjjM74.js +15 -0
  10. package/bizar-dash/dist/assets/AgentsView-BnOjjM74.js.map +1 -0
  11. package/bizar-dash/dist/assets/{Alert-B6DjfRFI.js → Alert-BZGk39mB.js} +1 -1
  12. package/bizar-dash/dist/assets/{Alert-B6DjfRFI.js.map → Alert-BZGk39mB.js.map} +1 -1
  13. package/bizar-dash/dist/assets/{ArtifactsView-znhN8GTR.js → ArtifactsView-CfYB1le1.js} +3 -3
  14. package/bizar-dash/dist/assets/ArtifactsView-CfYB1le1.js.map +1 -0
  15. package/bizar-dash/dist/assets/{AuthView-Rk8eKUPr.js → AuthView-D4frSShw.js} +1 -1
  16. package/bizar-dash/dist/assets/{AuthView-Rk8eKUPr.js.map → AuthView-D4frSShw.js.map} +1 -1
  17. package/bizar-dash/dist/assets/Avatar-BYg0rkPA.js +6 -0
  18. package/bizar-dash/dist/assets/Avatar-BYg0rkPA.js.map +1 -0
  19. package/bizar-dash/dist/assets/{BackgroundJobsView-BLWuN9qz.js → BackgroundJobsView-DEStvILz.js} +1 -1
  20. package/bizar-dash/dist/assets/{BackgroundJobsView-BLWuN9qz.js.map → BackgroundJobsView-DEStvILz.js.map} +1 -1
  21. package/bizar-dash/dist/assets/{BackupView-CqbtcnuQ.js → BackupView-B875KQa4.js} +1 -1
  22. package/bizar-dash/dist/assets/{BackupView-CqbtcnuQ.js.map → BackupView-B875KQa4.js.map} +1 -1
  23. package/bizar-dash/dist/assets/Banner-C8HEcT5l.js +1 -0
  24. package/bizar-dash/dist/assets/Banner-C8HEcT5l.js.map +1 -0
  25. package/bizar-dash/dist/assets/{Card-rF59wHiO.js → Card-BtsmkhJa.js} +1 -1
  26. package/bizar-dash/dist/assets/{Card-rF59wHiO.js.map → Card-BtsmkhJa.js.map} +1 -1
  27. package/bizar-dash/dist/assets/ChatView-CkNS0SD8.js +9 -0
  28. package/bizar-dash/dist/assets/ChatView-CkNS0SD8.js.map +1 -0
  29. package/bizar-dash/dist/assets/{Chip-Dc2KmeWl.js → Chip-XPOk0d_E.js} +1 -1
  30. package/bizar-dash/dist/assets/{Chip-Dc2KmeWl.js.map → Chip-XPOk0d_E.js.map} +1 -1
  31. package/bizar-dash/dist/assets/{ClaudeSessionsView-CiaHQdDZ.js → ClaudeSessionsView-BprGo67K.js} +1 -1
  32. package/bizar-dash/dist/assets/{ClaudeSessionsView-CiaHQdDZ.js.map → ClaudeSessionsView-BprGo67K.js.map} +1 -1
  33. package/bizar-dash/dist/assets/ClipboardView-CPlTU5VG.js +1 -0
  34. package/bizar-dash/dist/assets/ClipboardView-CPlTU5VG.js.map +1 -0
  35. package/bizar-dash/dist/assets/{ConfigView-B2ysnTZU.js → ConfigView-BntUrW7s.js} +1 -1
  36. package/bizar-dash/dist/assets/{ConfigView-B2ysnTZU.js.map → ConfigView-BntUrW7s.js.map} +1 -1
  37. package/bizar-dash/dist/assets/DiagnosticsView-4x0Zu3yP.js +2 -0
  38. package/bizar-dash/dist/assets/DiagnosticsView-4x0Zu3yP.js.map +1 -0
  39. package/bizar-dash/dist/assets/DialogsView-Xd02dVAX.js +6 -0
  40. package/bizar-dash/dist/assets/DialogsView-Xd02dVAX.js.map +1 -0
  41. package/bizar-dash/dist/assets/{DoctorView-BQwqvMAh.js → DoctorView-DepBdQGR.js} +2 -2
  42. package/bizar-dash/dist/assets/{DoctorView-BQwqvMAh.js.map → DoctorView-DepBdQGR.js.map} +1 -1
  43. package/bizar-dash/dist/assets/{EmptyState-D65J5FQN.js → EmptyState-DjKtY1Qi.js} +1 -1
  44. package/bizar-dash/dist/assets/{EmptyState-D65J5FQN.js.map → EmptyState-DjKtY1Qi.js.map} +1 -1
  45. package/bizar-dash/dist/assets/{EnvVarsView-DX-3oGH-.js → EnvVarsView-S4Pbm128.js} +3 -3
  46. package/bizar-dash/dist/assets/{EnvVarsView-DX-3oGH-.js.map → EnvVarsView-S4Pbm128.js.map} +1 -1
  47. package/bizar-dash/dist/assets/{ErrorState-DULZnttJ.js → ErrorState-CBJbEQ8B.js} +1 -1
  48. package/bizar-dash/dist/assets/{ErrorState-DULZnttJ.js.map → ErrorState-CBJbEQ8B.js.map} +1 -1
  49. package/bizar-dash/dist/assets/EvalView-BeAyMCD1.js +1 -0
  50. package/bizar-dash/dist/assets/{EvalView-CpdFu_ID.js.map → EvalView-BeAyMCD1.js.map} +1 -1
  51. package/bizar-dash/dist/assets/{GoalsView-Br8oPPfb.js → GoalsView-BZr8In4c.js} +1 -1
  52. package/bizar-dash/dist/assets/{GoalsView-Br8oPPfb.js.map → GoalsView-BZr8In4c.js.map} +1 -1
  53. package/bizar-dash/dist/assets/{Grid-BSXhsCPC.js → Grid--WKvqu5h.js} +1 -1
  54. package/bizar-dash/dist/assets/{Grid-BSXhsCPC.js.map → Grid--WKvqu5h.js.map} +1 -1
  55. package/bizar-dash/dist/assets/{HistoryView-D0J3aoZF.js → HistoryView-djEbzqtk.js} +1 -1
  56. package/bizar-dash/dist/assets/{HistoryView-D0J3aoZF.js.map → HistoryView-djEbzqtk.js.map} +1 -1
  57. package/bizar-dash/dist/assets/{Input-CZmRw5QX.js → Input-h_nSOtwm.js} +1 -1
  58. package/bizar-dash/dist/assets/{Input-CZmRw5QX.js.map → Input-h_nSOtwm.js.map} +1 -1
  59. package/bizar-dash/dist/assets/LibrariesView-Vez8CvNq.js +6 -0
  60. package/bizar-dash/dist/assets/{LibrariesView-B1YX9wzp.js.map → LibrariesView-Vez8CvNq.js.map} +1 -1
  61. package/bizar-dash/dist/assets/{LightRAGView-CykR0t9y.js → LightRAGView-DvqzQoBp.js} +1 -1
  62. package/bizar-dash/dist/assets/{LightRAGView-CykR0t9y.js.map → LightRAGView-DvqzQoBp.js.map} +1 -1
  63. package/bizar-dash/dist/assets/{ListHeader-Dpun-r36.js → ListHeader-CM8QoIWG.js} +1 -1
  64. package/bizar-dash/dist/assets/{ListHeader-Dpun-r36.js.map → ListHeader-CM8QoIWG.js.map} +1 -1
  65. package/bizar-dash/dist/assets/{MemoryView-BbER5ZKt.js → MemoryView-DnL8E2vI.js} +1 -1
  66. package/bizar-dash/dist/assets/{MemoryView-BbER5ZKt.js.map → MemoryView-DnL8E2vI.js.map} +1 -1
  67. package/bizar-dash/dist/assets/{MessageBubble-5vUAquDx.js → MessageBubble-CrCJ0SYG.js} +1 -1
  68. package/bizar-dash/dist/assets/{MessageBubble-5vUAquDx.js.map → MessageBubble-CrCJ0SYG.js.map} +1 -1
  69. package/bizar-dash/dist/assets/MiscView-B2YQXhZ_.js +1 -0
  70. package/bizar-dash/dist/assets/MiscView-B2YQXhZ_.js.map +1 -0
  71. package/bizar-dash/dist/assets/{ModsView-P7gDeNHM.js → ModsView-BVM3X5xc.js} +1 -1
  72. package/bizar-dash/dist/assets/{ModsView-P7gDeNHM.js.map → ModsView-BVM3X5xc.js.map} +1 -1
  73. package/bizar-dash/dist/assets/NotificationsView-A-Xs8BL1.js +6 -0
  74. package/bizar-dash/dist/assets/NotificationsView-A-Xs8BL1.js.map +1 -0
  75. package/bizar-dash/dist/assets/ObsidianView-mI3qW9OP.js +1 -0
  76. package/bizar-dash/dist/assets/{ObsidianView-Ci80gnwS.js.map → ObsidianView-mI3qW9OP.js.map} +1 -1
  77. package/bizar-dash/dist/assets/OverviewView-By69Cr5H.js +1 -0
  78. package/bizar-dash/dist/assets/OverviewView-By69Cr5H.js.map +1 -0
  79. package/bizar-dash/dist/assets/{ProgressBar-BahmeJhP.js → ProgressBar-BnaBqv-W.js} +1 -1
  80. package/bizar-dash/dist/assets/{ProgressBar-BahmeJhP.js.map → ProgressBar-BnaBqv-W.js.map} +1 -1
  81. package/bizar-dash/dist/assets/ProjectsView-C81WTFka.js +11 -0
  82. package/bizar-dash/dist/assets/ProjectsView-C81WTFka.js.map +1 -0
  83. package/bizar-dash/dist/assets/{ProvidersView-BftGn8Cr.js → ProvidersView-2cn-TALE.js} +2 -2
  84. package/bizar-dash/dist/assets/{ProvidersView-BftGn8Cr.js.map → ProvidersView-2cn-TALE.js.map} +1 -1
  85. package/bizar-dash/dist/assets/{SchedulesView-CtNxtzN6.js → SchedulesView-o9AtIsH9.js} +1 -1
  86. package/bizar-dash/dist/assets/{SchedulesView-CtNxtzN6.js.map → SchedulesView-o9AtIsH9.js.map} +1 -1
  87. package/bizar-dash/dist/assets/{Select-0VcfTDeL.js → Select-CiGWEN8I.js} +1 -1
  88. package/bizar-dash/dist/assets/{Select-0VcfTDeL.js.map → Select-CiGWEN8I.js.map} +1 -1
  89. package/bizar-dash/dist/assets/{SettingsRow-BLic3DQl.js → SettingsRow-CflGJymA.js} +1 -1
  90. package/bizar-dash/dist/assets/{SettingsRow-BLic3DQl.js.map → SettingsRow-CflGJymA.js.map} +1 -1
  91. package/bizar-dash/dist/assets/{SettingsView-BjS3i4nr.js → SettingsView-2HSFJPPK.js} +1 -1
  92. package/bizar-dash/dist/assets/{SettingsView-BjS3i4nr.js.map → SettingsView-2HSFJPPK.js.map} +1 -1
  93. package/bizar-dash/dist/assets/{Sheet-BOProMs2.js → Sheet-B-CMP9-_.js} +1 -1
  94. package/bizar-dash/dist/assets/{Sheet-BOProMs2.js.map → Sheet-B-CMP9-_.js.map} +1 -1
  95. package/bizar-dash/dist/assets/{Slider-B0eLEEUt.js → Slider-Z4TP_CXY.js} +1 -1
  96. package/bizar-dash/dist/assets/{Slider-B0eLEEUt.js.map → Slider-Z4TP_CXY.js.map} +1 -1
  97. package/bizar-dash/dist/assets/{Sparkline-SSrdgyW0.js → Sparkline-cvkv2HbU.js} +1 -1
  98. package/bizar-dash/dist/assets/{Sparkline-SSrdgyW0.js.map → Sparkline-cvkv2HbU.js.map} +1 -1
  99. package/bizar-dash/dist/assets/{Switch-B3EQzb_q.js → Switch-jcYo4lmp.js} +1 -1
  100. package/bizar-dash/dist/assets/{Switch-B3EQzb_q.js.map → Switch-jcYo4lmp.js.map} +1 -1
  101. package/bizar-dash/dist/assets/{TasksView-SWjF_ZUQ.js → TasksView-CQaSFzWY.js} +2 -2
  102. package/bizar-dash/dist/assets/{TasksView-SWjF_ZUQ.js.map → TasksView-CQaSFzWY.js.map} +1 -1
  103. package/bizar-dash/dist/assets/{Textarea-QuofpMlq.js → Textarea-xnAybFGd.js} +1 -1
  104. package/bizar-dash/dist/assets/{Textarea-QuofpMlq.js.map → Textarea-xnAybFGd.js.map} +1 -1
  105. package/bizar-dash/dist/assets/UpdateView-BUAEcRCX.js +1 -0
  106. package/bizar-dash/dist/assets/UpdateView-BUAEcRCX.js.map +1 -0
  107. package/bizar-dash/dist/assets/{UsageView-BqOw6FBg.js → UsageView-DMFbBOfH.js} +1 -1
  108. package/bizar-dash/dist/assets/{UsageView-BqOw6FBg.js.map → UsageView-DMFbBOfH.js.map} +1 -1
  109. package/bizar-dash/dist/assets/{ViewHeader-B6P-C4GD.js → ViewHeader-C-t1U2cQ.js} +1 -1
  110. package/bizar-dash/dist/assets/{ViewHeader-B6P-C4GD.js.map → ViewHeader-C-t1U2cQ.js.map} +1 -1
  111. package/bizar-dash/dist/assets/VoiceView-aoPVT6LJ.js +1 -0
  112. package/bizar-dash/dist/assets/VoiceView-aoPVT6LJ.js.map +1 -0
  113. package/bizar-dash/dist/assets/{brain-CwZt9Kta.js → brain-DhAzcHUk.js} +1 -1
  114. package/bizar-dash/dist/assets/{brain-CwZt9Kta.js.map → brain-DhAzcHUk.js.map} +1 -1
  115. package/bizar-dash/dist/assets/{calendar-C5oK0_nM.js → calendar-B9Wbemh7.js} +1 -1
  116. package/bizar-dash/dist/assets/{calendar-C5oK0_nM.js.map → calendar-B9Wbemh7.js.map} +1 -1
  117. package/bizar-dash/dist/assets/{circle-D1Lc_P2a.js → circle-6NJF_Xl6.js} +1 -1
  118. package/bizar-dash/dist/assets/{circle-D1Lc_P2a.js.map → circle-6NJF_Xl6.js.map} +1 -1
  119. package/bizar-dash/dist/assets/{circle-alert-HdHe7m8K.js → circle-alert-Dz8lGfCZ.js} +1 -1
  120. package/bizar-dash/dist/assets/{circle-alert-HdHe7m8K.js.map → circle-alert-Dz8lGfCZ.js.map} +1 -1
  121. package/bizar-dash/dist/assets/{circle-check-Cs-xoV7R.js → circle-check-DFB50ojt.js} +1 -1
  122. package/bizar-dash/dist/assets/{circle-check-Cs-xoV7R.js.map → circle-check-DFB50ojt.js.map} +1 -1
  123. package/bizar-dash/dist/assets/{clock-DEIuPV60.js → clock-ClVA6-hQ.js} +1 -1
  124. package/bizar-dash/dist/assets/{clock-DEIuPV60.js.map → clock-ClVA6-hQ.js.map} +1 -1
  125. package/bizar-dash/dist/assets/{cmdk-DVxytz9i.js → cmdk-C3F6LD6N.js} +5 -5
  126. package/bizar-dash/dist/assets/{cmdk-DVxytz9i.js.map → cmdk-C3F6LD6N.js.map} +1 -1
  127. package/bizar-dash/dist/assets/{dnd-kit-DrHErSkw.js → dnd-kit-BAOLODOI.js} +1 -1
  128. package/bizar-dash/dist/assets/{dnd-kit-DrHErSkw.js.map → dnd-kit-BAOLODOI.js.map} +1 -1
  129. package/bizar-dash/dist/assets/{download-Clkq90Ct.js → download-BvJddD8D.js} +1 -1
  130. package/bizar-dash/dist/assets/{download-Clkq90Ct.js.map → download-BvJddD8D.js.map} +1 -1
  131. package/bizar-dash/dist/assets/{external-link-D5tq2o_I.js → external-link-DvL89gaZ.js} +1 -1
  132. package/bizar-dash/dist/assets/{external-link-D5tq2o_I.js.map → external-link-DvL89gaZ.js.map} +1 -1
  133. package/bizar-dash/dist/assets/{file-text-CQ12t7Oc.js → file-text-BOroDtZE.js} +1 -1
  134. package/bizar-dash/dist/assets/{file-text-CQ12t7Oc.js.map → file-text-BOroDtZE.js.map} +1 -1
  135. package/bizar-dash/dist/assets/{filter-BcbE37wP.js → filter-DwPjMRQt.js} +1 -1
  136. package/bizar-dash/dist/assets/{filter-BcbE37wP.js.map → filter-DwPjMRQt.js.map} +1 -1
  137. package/bizar-dash/dist/assets/{git-pull-request-D1qNDRia.js → git-pull-request-TDb1inux.js} +1 -1
  138. package/bizar-dash/dist/assets/{git-pull-request-D1qNDRia.js.map → git-pull-request-TDb1inux.js.map} +1 -1
  139. package/bizar-dash/dist/assets/{index-CASP1n-5.js → index-B1OIS316.js} +1 -1
  140. package/bizar-dash/dist/assets/{index-CASP1n-5.js.map → index-B1OIS316.js.map} +1 -1
  141. package/bizar-dash/dist/assets/{index-C4Vq_2LM.js → index-CR0TeJmc.js} +1 -1
  142. package/bizar-dash/dist/assets/{index-C4Vq_2LM.js.map → index-CR0TeJmc.js.map} +1 -1
  143. package/bizar-dash/dist/assets/{main-CcQfRfIJ.css → main-B7D_IMTh.css} +1 -1
  144. package/bizar-dash/dist/assets/main-BURAlktW.js +277 -0
  145. package/bizar-dash/dist/assets/main-BURAlktW.js.map +1 -0
  146. package/bizar-dash/dist/assets/{network-DJdvVaHx.js → network-BcCoCzIY.js} +1 -1
  147. package/bizar-dash/dist/assets/{network-DJdvVaHx.js.map → network-BcCoCzIY.js.map} +1 -1
  148. package/bizar-dash/dist/assets/{pause-DUn9L5PB.js → pause-BllItT2_.js} +1 -1
  149. package/bizar-dash/dist/assets/{pause-DUn9L5PB.js.map → pause-BllItT2_.js.map} +1 -1
  150. package/bizar-dash/dist/assets/{pencil-DVrBlYV3.js → pencil-DAwM-CC3.js} +1 -1
  151. package/bizar-dash/dist/assets/{pencil-DVrBlYV3.js.map → pencil-DAwM-CC3.js.map} +1 -1
  152. package/bizar-dash/dist/assets/{play-CZjsr3XM.js → play-mJh67AXo.js} +2 -2
  153. package/bizar-dash/dist/assets/{play-CZjsr3XM.js.map → play-mJh67AXo.js.map} +1 -1
  154. package/bizar-dash/dist/assets/{plug-BKuyIe5W.js → plug-BjfntCMC.js} +1 -1
  155. package/bizar-dash/dist/assets/{plug-BKuyIe5W.js.map → plug-BjfntCMC.js.map} +1 -1
  156. package/bizar-dash/dist/assets/{plus-77h62zZm.js → plus-Cm6-fo14.js} +1 -1
  157. package/bizar-dash/dist/assets/{plus-77h62zZm.js.map → plus-Cm6-fo14.js.map} +1 -1
  158. package/bizar-dash/dist/assets/{power-DLmx-gCP.js → power-CXN9y2KV.js} +1 -1
  159. package/bizar-dash/dist/assets/{power-DLmx-gCP.js.map → power-CXN9y2KV.js.map} +1 -1
  160. package/bizar-dash/dist/assets/{power-off-BFKzHXic.js → power-off-DUZqwMf9.js} +1 -1
  161. package/bizar-dash/dist/assets/{power-off-BFKzHXic.js.map → power-off-DUZqwMf9.js.map} +1 -1
  162. package/bizar-dash/dist/assets/{refresh-ccw-DenGBOcq.js → refresh-ccw-DA8_IB9l.js} +1 -1
  163. package/bizar-dash/dist/assets/{refresh-ccw-DenGBOcq.js.map → refresh-ccw-DA8_IB9l.js.map} +1 -1
  164. package/bizar-dash/dist/assets/{refresh-cw-ENBVR8hW.js → refresh-cw-DwlP59en.js} +1 -1
  165. package/bizar-dash/dist/assets/{refresh-cw-ENBVR8hW.js.map → refresh-cw-DwlP59en.js.map} +1 -1
  166. package/bizar-dash/dist/assets/{rotate-ccw-MxryaY7q.js → rotate-ccw-DMTASfAn.js} +1 -1
  167. package/bizar-dash/dist/assets/{rotate-ccw-MxryaY7q.js.map → rotate-ccw-DMTASfAn.js.map} +1 -1
  168. package/bizar-dash/dist/assets/{rotate-cw-CDOlRtUR.js → rotate-cw-BDX5SE2s.js} +1 -1
  169. package/bizar-dash/dist/assets/{rotate-cw-CDOlRtUR.js.map → rotate-cw-BDX5SE2s.js.map} +1 -1
  170. package/bizar-dash/dist/assets/{save-Db1b-1Uq.js → save-Y0jPK5D6.js} +1 -1
  171. package/bizar-dash/dist/assets/{save-Db1b-1Uq.js.map → save-Y0jPK5D6.js.map} +1 -1
  172. package/bizar-dash/dist/assets/{send-yz6HFZM5.js → send-C8wwPHhR.js} +2 -2
  173. package/bizar-dash/dist/assets/{send-yz6HFZM5.js.map → send-C8wwPHhR.js.map} +1 -1
  174. package/bizar-dash/dist/assets/{shield-alert-DY6RAaC8.js → shield-alert-DEvq9UG0.js} +1 -1
  175. package/bizar-dash/dist/assets/{shield-alert-DY6RAaC8.js.map → shield-alert-DEvq9UG0.js.map} +1 -1
  176. package/bizar-dash/dist/assets/{trash-2-Cv7U38jw.js → trash-2-D6qePV_q.js} +2 -2
  177. package/bizar-dash/dist/assets/{trash-2-Cv7U38jw.js.map → trash-2-D6qePV_q.js.map} +1 -1
  178. package/bizar-dash/dist/assets/{trending-up-CRPNagyX.js → trending-up-BZzo_1ic.js} +1 -1
  179. package/bizar-dash/dist/assets/{trending-up-CRPNagyX.js.map → trending-up-BZzo_1ic.js.map} +1 -1
  180. package/bizar-dash/dist/assets/{triangle-alert-tUTXbcEP.js → triangle-alert-B2oHbmoh.js} +1 -1
  181. package/bizar-dash/dist/assets/{triangle-alert-tUTXbcEP.js.map → triangle-alert-B2oHbmoh.js.map} +1 -1
  182. package/bizar-dash/dist/assets/{upload-Cq7uTsrT.js → upload-Dy59aZn6.js} +1 -1
  183. package/bizar-dash/dist/assets/{upload-Cq7uTsrT.js.map → upload-Dy59aZn6.js.map} +1 -1
  184. package/bizar-dash/dist/assets/{zap-5lAQBAPX.js → zap-DENVhJnO.js} +2 -2
  185. package/bizar-dash/dist/assets/{zap-5lAQBAPX.js.map → zap-DENVhJnO.js.map} +1 -1
  186. package/bizar-dash/dist/index.html +3 -3
  187. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  188. package/bizar-dash/src/web/v8/App.tsx +87 -6
  189. package/bizar-dash/src/web/v8/__tests__/chat-view.test.tsx +4 -4
  190. package/bizar-dash/src/web/v8/shell/AppShell.tsx +38 -2
  191. package/bizar-dash/src/web/v8/shell/Sidebar.tsx +52 -38
  192. package/bizar-dash/src/web/v8/shell/Topbar.tsx +62 -3
  193. package/bizar-dash/src/web/v8/ui/styles/globals.css +40 -0
  194. package/bizar-dash/src/web/v8/ui/theme/ThemeToggle.tsx +11 -6
  195. package/bizar-dash/src/web/v8/views/Admin/AdminView.tsx +32 -5
  196. package/bizar-dash/src/web/v8/views/Agents/AgentsView.tsx +36 -4
  197. package/bizar-dash/src/web/v8/views/Artifacts/ArtifactsView.tsx +1 -1
  198. package/bizar-dash/src/web/v8/views/Chat/ChatView.tsx +13 -1
  199. package/bizar-dash/src/web/v8/views/ClaudeSessions/NewSessionModal.tsx +136 -0
  200. package/bizar-dash/src/web/v8/views/Clipboard/ClipboardView.tsx +1 -1
  201. package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.tsx +14 -4
  202. package/bizar-dash/src/web/v8/views/Diagnostics/DiagnosticsView.tsx +50 -7
  203. package/bizar-dash/src/web/v8/views/Dialogs/DialogsView.tsx +1 -1
  204. package/bizar-dash/src/web/v8/views/Libraries/LibrariesView.tsx +6 -1
  205. package/bizar-dash/src/web/v8/views/Misc/MiscView.tsx +1 -1
  206. package/bizar-dash/src/web/v8/views/Notifications/NotificationsView.tsx +82 -13
  207. package/bizar-dash/src/web/v8/views/Overview/OverviewView.tsx +19 -0
  208. package/bizar-dash/src/web/v8/views/Projects/ProjectsView.tsx +21 -1
  209. package/bizar-dash/src/web/v8/views/Voice/VoiceView.tsx +1 -1
  210. package/bizar-dash/tests/admin-labels.test.mjs +42 -0
  211. package/bizar-dash/tests/admin-run-grouping.test.mjs +42 -0
  212. package/bizar-dash/tests/agents-preview-truncate.test.mjs +35 -0
  213. package/bizar-dash/tests/agents-summary-sanitize.test.ts +51 -0
  214. package/bizar-dash/tests/chat-new-session.test.mjs +63 -0
  215. package/bizar-dash/tests/empty-state-docs.test.mjs +55 -0
  216. package/bizar-dash/tests/focus-visible.test.mjs +30 -0
  217. package/bizar-dash/tests/kanban-empty-column.test.mjs +56 -0
  218. package/bizar-dash/tests/library-dedupe.test.mjs +62 -0
  219. package/bizar-dash/tests/notifications-dismiss-restore.test.mjs +85 -0
  220. package/bizar-dash/tests/palette-shortcut-hint.test.mjs +58 -0
  221. package/bizar-dash/tests/projects-filter.test.mjs +48 -0
  222. package/bizar-dash/tests/settings-labels.test.mjs +80 -0
  223. package/bizar-dash/tests/sidebar-distinct-icons.test.mjs +28 -0
  224. package/bizar-dash/tests/sidebar-responsive.test.tsx +48 -0
  225. package/bizar-dash/tests/sidebar-section-toggle.test.tsx +63 -0
  226. package/bizar-dash/tests/theme-toggle-icon.test.mjs +28 -0
  227. package/bizar-dash/tests/topbar-design-system.test.mjs +56 -0
  228. package/bizar-dash/vite.config.ts +8 -0
  229. package/package.json +1 -1
  230. package/packages/sdk/package.json +1 -1
  231. package/bizar-dash/dist/assets/AdminView-DNc5Ll7L.js +0 -11
  232. package/bizar-dash/dist/assets/AdminView-DNc5Ll7L.js.map +0 -1
  233. package/bizar-dash/dist/assets/AgentsView-Du-G_skK.js +0 -13
  234. package/bizar-dash/dist/assets/AgentsView-Du-G_skK.js.map +0 -1
  235. package/bizar-dash/dist/assets/ArtifactsView-znhN8GTR.js.map +0 -1
  236. package/bizar-dash/dist/assets/Avatar-B41upSD1.js +0 -6
  237. package/bizar-dash/dist/assets/Avatar-B41upSD1.js.map +0 -1
  238. package/bizar-dash/dist/assets/ChatView-CUriVEgU.js +0 -9
  239. package/bizar-dash/dist/assets/ChatView-CUriVEgU.js.map +0 -1
  240. package/bizar-dash/dist/assets/ClipboardView-DdP6aVso.js +0 -1
  241. package/bizar-dash/dist/assets/ClipboardView-DdP6aVso.js.map +0 -1
  242. package/bizar-dash/dist/assets/DiagnosticsView-88OZ5k0f.js +0 -2
  243. package/bizar-dash/dist/assets/DiagnosticsView-88OZ5k0f.js.map +0 -1
  244. package/bizar-dash/dist/assets/DialogsView-BcqDDCZQ.js +0 -6
  245. package/bizar-dash/dist/assets/DialogsView-BcqDDCZQ.js.map +0 -1
  246. package/bizar-dash/dist/assets/EvalView-CpdFu_ID.js +0 -1
  247. package/bizar-dash/dist/assets/LibrariesView-B1YX9wzp.js +0 -6
  248. package/bizar-dash/dist/assets/MiscView-DLNEGdML.js +0 -1
  249. package/bizar-dash/dist/assets/MiscView-DLNEGdML.js.map +0 -1
  250. package/bizar-dash/dist/assets/NotificationsView-DAm2O0yf.js +0 -6
  251. package/bizar-dash/dist/assets/NotificationsView-DAm2O0yf.js.map +0 -1
  252. package/bizar-dash/dist/assets/ObsidianView-Ci80gnwS.js +0 -1
  253. package/bizar-dash/dist/assets/OverviewView-rriw1GjA.js +0 -1
  254. package/bizar-dash/dist/assets/OverviewView-rriw1GjA.js.map +0 -1
  255. package/bizar-dash/dist/assets/ProjectsView-ChzM12bs.js +0 -11
  256. package/bizar-dash/dist/assets/ProjectsView-ChzM12bs.js.map +0 -1
  257. package/bizar-dash/dist/assets/UpdateView-CEHW2nd6.js +0 -6
  258. package/bizar-dash/dist/assets/UpdateView-CEHW2nd6.js.map +0 -1
  259. package/bizar-dash/dist/assets/VoiceView-CwrPwWgi.js +0 -1
  260. package/bizar-dash/dist/assets/VoiceView-CwrPwWgi.js.map +0 -1
  261. package/bizar-dash/dist/assets/main-Cxeu4LhG.js +0 -244
  262. package/bizar-dash/dist/assets/main-Cxeu4LhG.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TasksView-SWjF_ZUQ.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/arrow-right.js","../../src/web/v8/ui/kanban/KanbanToolbar.tsx","../../src/web/v8/ui/kanban/useKanbanSelection.ts","../../src/web/v8/ui/tasks/TaskDetail.tsx","../../src/web/v8/views/Tasks/TasksView.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 ArrowRight = createLucideIcon(\"ArrowRight\", [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"m12 5 7 7-7 7\", key: \"xquz4c\" }]\n]);\n\nexport { ArrowRight as default };\n//# sourceMappingURL=arrow-right.js.map\n","import { useState, type ChangeEvent, type ReactNode } from 'react';\nimport { Plus, Search, Trash2, Archive, ArrowRight, X, Filter } from 'lucide-react';\nimport { Button } from '../controls/Button.js';\nimport { IconButton } from '../controls/IconButton.js';\nimport { cx } from '../utils/cx.js';\n\n/**\n * KanbanToolbar — top-of-board toolbar.\n *\n * Three modes:\n * - normal: search input + filter chips + \"New task\" button.\n * - selecting: replaces the action row with N-selected count +\n * bulk-actions (Move / Archive / Delete).\n * - filtered: shows a \"Clear filters\" pill next to the search.\n *\n * Consumers control query state via callbacks. The toolbar keeps no\n * internal search/filter state of its own — that lives in the view\n * so the board can re-derive visible cards.\n */\n\nexport interface KanbanFilter {\n /** Stable filter id; used as the chip key + for clearing. */\n id: string;\n /** Visible chip label (e.g. \"High priority\"). */\n label: ReactNode;\n /** Optional tone for the chip. */\n tone?: 'neutral' | 'info' | 'success' | 'warning' | 'danger' | 'accent';\n}\n\nexport interface KanbanToolbarProps {\n /** Total number of cards on the board (for \"showing X of Y\"). */\n totalCount: number;\n /** Number of cards currently visible after filtering. */\n visibleCount: number;\n /** Number of selected cards. When >0, the toolbar swaps to bulk mode. */\n selectedCount: number;\n\n /** Free-text search. */\n query: string;\n onQueryChange: (value: string) => void;\n\n /** Active filters. */\n filters: readonly KanbanFilter[];\n onFilterToggle: (filterId: string) => void;\n onClearFilters: () => void;\n\n /** New-task action. Hidden when the toolbar is in bulk mode. */\n onNewTask?: () => void;\n\n /** Bulk actions, shown only when selectedCount > 0. */\n onBulkMove?: (selectedIds: ReadonlySet<string>) => void;\n onBulkArchive?: (selectedIds: ReadonlySet<string>) => void;\n onBulkDelete?: (selectedIds: ReadonlySet<string>) => void;\n onClearSelection?: () => void;\n\n className?: string;\n}\n\nexport function KanbanToolbar(props: KanbanToolbarProps): JSX.Element {\n const {\n totalCount,\n visibleCount,\n selectedCount,\n query,\n onQueryChange,\n filters,\n onFilterToggle,\n onClearFilters,\n onNewTask,\n onBulkMove,\n onBulkArchive,\n onBulkDelete,\n onClearSelection,\n className,\n } = props;\n\n const [searchFocused, setSearchFocused] = useState(false);\n const isBulk = selectedCount > 0;\n\n return (\n <div\n className={cx('v8-kanban-toolbar', className)}\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: 'var(--space-2)',\n padding: 'var(--space-2) var(--space-3)',\n background: 'var(--surface-0)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius)',\n }}\n >\n {isBulk ? (\n <>\n <span\n style={{\n fontSize: 'var(--fs-13)',\n fontWeight: 600,\n color: 'var(--fg)',\n }}\n >\n {selectedCount} selected\n </span>\n <span style={{ flex: 1 }} />\n {onBulkMove !== undefined && (\n <Button size=\"sm\" variant=\"secondary\" leftIcon={<ArrowRight size={14} aria-hidden=\"true\" />} onClick={() => onBulkMove(new Set())}>\n Move…\n </Button>\n )}\n {onBulkArchive !== undefined && (\n <Button\n size=\"sm\"\n variant=\"secondary\"\n leftIcon={<Archive size={14} aria-hidden=\"true\" />}\n onClick={() => onBulkArchive(new Set())}\n >\n Archive\n </Button>\n )}\n {onBulkDelete !== undefined && (\n <Button\n size=\"sm\"\n variant=\"danger\"\n leftIcon={<Trash2 size={14} aria-hidden=\"true\" />}\n onClick={() => onBulkDelete(new Set())}\n >\n Delete\n </Button>\n )}\n {onClearSelection !== undefined && (\n <IconButton aria-label=\"Clear selection\" onClick={onClearSelection} size=\"sm\">\n <X size={14} aria-hidden=\"true\" />\n </IconButton>\n )}\n </>\n ) : (\n <>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '0 var(--space-2)',\n height: 32,\n background: 'var(--input-bg)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n minWidth: 220,\n flex: '1 1 220px',\n maxWidth: 360,\n }}\n >\n <Search size={14} aria-hidden=\"true\" style={{ color: 'var(--fg-muted)', flexShrink: 0 }} />\n <input\n type=\"search\"\n value={query}\n placeholder=\"Filter tasks…\"\n onChange={(e: ChangeEvent<HTMLInputElement>) => onQueryChange(e.target.value)}\n onFocus={() => setSearchFocused(true)}\n onBlur={() => setSearchFocused(false)}\n aria-label=\"Filter tasks\"\n style={{\n flex: 1,\n minWidth: 0,\n border: 0,\n outline: 0,\n background: 'transparent',\n color: 'var(--fg)',\n fontSize: 'var(--fs-13)',\n fontFamily: 'inherit',\n }}\n />\n {query !== '' && (\n <button\n type=\"button\"\n onClick={() => onQueryChange('')}\n aria-label=\"Clear search\"\n style={{\n background: 'transparent',\n border: 0,\n padding: 2,\n color: 'var(--fg-muted)',\n cursor: 'pointer',\n display: 'inline-flex',\n }}\n >\n <X size={12} aria-hidden=\"true\" />\n </button>\n )}\n </div>\n {filters.length > 0 && (\n <div\n role=\"toolbar\"\n aria-label=\"Task filters\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n flexWrap: 'wrap',\n }}\n >\n <Filter\n size={12}\n aria-hidden=\"true\"\n style={{ color: 'var(--fg-muted)', marginRight: 2 }}\n />\n {filters.map((f) => {\n const tone = f.tone ?? 'neutral';\n const isActive = f.id.startsWith('active:');\n // Display rule: callers prepend \"active:\" when toggled on.\n const actualId = isActive ? f.id.slice('active:'.length) : f.id;\n const active = isActive;\n return (\n <button\n key={f.id}\n type=\"button\"\n onClick={() => onFilterToggle(actualId)}\n aria-pressed={active}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n height: 26,\n padding: '0 var(--space-2)',\n borderRadius: 'var(--radius-pill)',\n border: `1px solid var(--${active ? 'accent' : 'border'})`,\n background: active ? 'color-mix(in oklch, var(--accent) 14%, transparent)' : 'transparent',\n color: 'var(--fg-muted)',\n fontSize: 'var(--fs-12)',\n fontWeight: 500,\n cursor: 'pointer',\n }}\n >\n <span\n aria-hidden=\"true\"\n style={{\n width: 6,\n height: 6,\n borderRadius: 'var(--radius-pill)',\n background:\n tone === 'neutral'\n ? 'var(--fg-muted)'\n : `var(--${tone})`,\n }}\n />\n {f.label}\n </button>\n );\n })}\n {filters.some((f) => f.id.startsWith('active:')) && (\n <button\n type=\"button\"\n onClick={onClearFilters}\n style={{\n background: 'transparent',\n border: 0,\n color: 'var(--fg-muted)',\n fontSize: 'var(--fs-12)',\n cursor: 'pointer',\n padding: '0 var(--space-2)',\n height: 26,\n }}\n >\n Clear\n </button>\n )}\n </div>\n )}\n <span style={{ flex: 1 }} />\n <span\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-muted)',\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {visibleCount === totalCount\n ? `${totalCount} task${totalCount === 1 ? '' : 's'}`\n : `${visibleCount} of ${totalCount}`}\n </span>\n {onNewTask !== undefined && (\n <Button size=\"sm\" variant=\"primary\" leftIcon={<Plus size={14} aria-hidden=\"true\" />} onClick={onNewTask}>\n New task\n </Button>\n )}\n </>\n )}\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\n\n/**\n * useKanbanSelection — track a Set<string> of selected card ids with\n * a small set of helpers, plus an Esc-to-clear keyboard shortcut.\n *\n * Designed for the kanban board's multi-select toolbar. Selection is\n * kept in component state so the board can hand it to the toolbar +\n * card checkbox without prop-drilling.\n */\n\nexport interface UseKanbanSelectionApi {\n /** Current selection. Use `.size` for the count. */\n selected: ReadonlySet<string>;\n /** True iff `id` is in the selection. */\n has: (id: string) => boolean;\n /** Add or remove a single id. */\n toggle: (id: string) => void;\n /** Add ids (no-op if already present). */\n add: (ids: readonly string[]) => void;\n /** Remove ids. */\n remove: (ids: readonly string[]) => void;\n /** Replace the whole selection. */\n set: (ids: readonly string[]) => void;\n /** Drop everything. */\n clear: () => void;\n}\n\nexport function useKanbanSelection(): UseKanbanSelectionApi {\n const [selected, setSelected] = useState<ReadonlySet<string>>(() => new Set());\n\n const toggle = useCallback((id: string) => {\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }, []);\n\n const add = useCallback((ids: readonly string[]) => {\n if (ids.length === 0) return;\n setSelected((prev) => {\n const next = new Set(prev);\n for (const id of ids) next.add(id);\n return next;\n });\n }, []);\n\n const remove = useCallback((ids: readonly string[]) => {\n if (ids.length === 0) return;\n setSelected((prev) => {\n const next = new Set(prev);\n for (const id of ids) next.delete(id);\n return next;\n });\n }, []);\n\n const set = useCallback((ids: readonly string[]) => {\n setSelected(new Set(ids));\n }, []);\n\n const clear = useCallback(() => {\n setSelected((prev) => (prev.size === 0 ? prev : new Set()));\n }, []);\n\n // Esc clears selection, but only when focus is not inside a text\n // input/textarea/contenteditable (so the user can still press Esc\n // inside an editor).\n useEffect(() => {\n const onKey = (ev: KeyboardEvent) => {\n if (ev.key !== 'Escape') return;\n const target = ev.target as HTMLElement | null;\n if (target) {\n const tag = target.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || target.isContentEditable) return;\n }\n clear();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [clear]);\n\n const has = useCallback((id: string) => selected.has(id), [selected]);\n\n return useMemo(\n () => ({ selected, has, toggle, add, remove, set, clear }),\n [selected, has, toggle, add, remove, set, clear],\n );\n}\n","import { useEffect, useState } from 'react';\nimport { Plus, Trash2 } 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 { Textarea } from '../controls/Textarea.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 { Task } from '../../data/types.js';\n\n/**\n * TaskDetail — right-side Drawer for editing a single task. Sprint S17.\n *\n * Source-of-truth lives on the backend (tasks-store). Each edit PATCHes\n * `/api/tasks/:id` and the server re-broadcasts the canonical state via\n * `tasks:change`. The Drawer stays open while the WS round-trip resolves\n * so optimistic UI + canonical merge feels seamless.\n */\n\nconst PRIORITY_OPTIONS = [\n { value: 'low', label: 'Low' },\n { value: 'medium', label: 'Medium' },\n { value: 'high', label: 'High' },\n { value: 'urgent', label: 'Urgent' },\n];\n\nconst STATUS_OPTIONS = [\n { value: 'queued', label: 'Backlog' },\n { value: 'doing', label: 'In progress' },\n { value: 'blocked', label: 'In review' },\n { value: 'done', label: 'Done' },\n { value: 'archived', label: 'Archived' },\n];\n\nexport interface TaskDetailProps {\n task: Task;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onDeleted?: () => void;\n}\n\nexport function TaskDetail(props: TaskDetailProps): JSX.Element {\n const { task, open, onOpenChange, onDeleted } = props;\n const [title, setTitle] = useState<string>(task.title);\n const [description, setDescription] = useState<string>(task.description || '');\n const [priority, setPriority] = useState<string>(task.priority || 'medium');\n const [status, setStatus] = useState<string>(task.status || 'queued');\n const [assignee, setAssignee] = useState<string>(task.assignee || '');\n const [due, setDue] = useState<string>(task.due || '');\n const [branch, setBranch] = useState<string>(task.branch || '');\n const [comment, setComment] = 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 const [deleting, setDeleting] = useState<boolean>(false);\n\n useEffect(() => {\n if (open) {\n setTitle(task.title);\n setDescription(task.description || '');\n setPriority(task.priority || 'medium');\n setStatus(task.status || 'queued');\n setAssignee(task.assignee || '');\n setDue(task.due || '');\n setBranch(task.branch || '');\n setComment('');\n setMessage(null);\n setError(null);\n }\n }, [open, task]);\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/tasks/${encodeURIComponent(task.id)}`, {\n method: 'PATCH',\n body,\n });\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 !== task.title) void patch({ title: title.trim() }, 'Title');\n };\n const saveDescription = (): void => {\n if (description !== (task.description || '')) void patch({ description }, 'Description');\n };\n const savePriority = (v: string): void => {\n setPriority(v);\n if (v !== task.priority) void patch({ priority: v }, 'Priority');\n };\n const saveStatus = (v: string): void => {\n setStatus(v);\n if (v !== task.status) void patch({ status: v }, 'Status');\n };\n const saveAssignee = (): void => {\n const v = assignee.trim();\n if (v !== (task.assignee || '')) void patch({ assignee: v }, 'Assignee');\n };\n const saveDue = (): void => {\n const v = due.trim();\n if (v !== (task.due || '')) void patch({ due: v }, 'Due');\n };\n const saveBranch = (): void => {\n const v = branch.trim();\n if (v !== (task.branch || '')) void patch({ branch: v }, 'Branch');\n };\n\n const addComment = async (): Promise<void> => {\n const v = comment.trim();\n if (!v) return;\n setBusy('comment');\n setError(null);\n try {\n await fetchJson(`/api/tasks/${encodeURIComponent(task.id)}/comments`, {\n method: 'POST',\n body: { text: v },\n });\n setComment('');\n setMessage('Comment added.');\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n const removeTask = async (): Promise<void> => {\n const ok = typeof window !== 'undefined' && typeof window.confirm === 'function'\n ? window.confirm(`Delete task \"${task.title}\"? This is irreversible.`)\n : true;\n if (!ok) return;\n setDeleting(true);\n try {\n await fetchJson(`/api/tasks/${encodeURIComponent(task.id)}`, { method: 'DELETE' });\n onDeleted?.();\n onOpenChange(false);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setDeleting(false);\n }\n };\n\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent side=\"right\" title=\"Edit task\">\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"task-title\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Title\n </label>\n <Input\n id=\"task-title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n onBlur={saveTitle}\n disabled={busy !== null}\n />\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"task-status\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Status\n </label>\n <Select value={status} onValueChange={saveStatus}>\n <SelectTrigger id=\"task-status\" size=\"sm\" placeholder=\"Status\" />\n <SelectContent>\n {STATUS_OPTIONS.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Stack>\n\n <Inline gap={2}>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"task-priority\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Priority\n </label>\n <Select value={priority} onValueChange={savePriority}>\n <SelectTrigger id=\"task-priority\" size=\"sm\" placeholder=\"Priority\" />\n <SelectContent>\n {PRIORITY_OPTIONS.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Stack>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"task-due\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Due\n </label>\n <Input\n id=\"task-due\"\n type=\"date\"\n value={due ? due.slice(0, 10) : ''}\n onChange={(e) => setDue(e.target.value)}\n onBlur={saveDue}\n disabled={busy !== null}\n />\n </Stack>\n </Inline>\n\n <Inline gap={2}>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"task-assignee\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Assignee\n </label>\n <Input\n id=\"task-assignee\"\n value={assignee}\n onChange={(e) => setAssignee(e.target.value)}\n onBlur={saveAssignee}\n placeholder=\"agent name (blank = unassigned)\"\n disabled={busy !== null}\n />\n </Stack>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"task-branch\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Branch\n </label>\n <Input\n id=\"task-branch\"\n value={branch}\n onChange={(e) => setBranch(e.target.value)}\n onBlur={saveBranch}\n placeholder=\"feature/foo\"\n disabled={busy !== null}\n />\n </Stack>\n </Inline>\n\n <Stack gap={2}>\n <label htmlFor=\"task-description\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Description\n </label>\n <Textarea\n id=\"task-description\"\n rows={5}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n onBlur={saveDescription}\n disabled={busy !== null}\n placeholder=\"What's the work, why, how to verify…\"\n />\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"task-comment\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Add comment\n </label>\n <Inline gap={2} align=\"start\">\n <Textarea\n id=\"task-comment\"\n rows={2}\n value={comment}\n onChange={(e) => setComment(e.target.value)}\n placeholder=\"Leave a progress note…\"\n disabled={busy !== null}\n style={{ flex: 1 }}\n />\n <Button variant=\"secondary\" onClick={() => { void addComment(); }} disabled={!comment.trim() || busy !== null}>\n <Plus size={14} aria-hidden /> Comment\n </Button>\n </Inline>\n </Stack>\n\n <Stack gap={2}>\n <div style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Metadata</div>\n <Inline gap={1} wrap>\n {task.metadata?.goalId !== undefined && typeof task.metadata.goalId === 'string' && (\n <Badge tone=\"info\" title={`Linked to goal ${String(task.metadata.goalId)}`}>\n goal: {String(task.metadata.goalId)}\n </Badge>\n )}\n {task.metadata?.krId !== undefined && typeof task.metadata.krId === 'string' && (\n <Badge tone=\"info\" title={`Linked to KR ${String(task.metadata.krId)}`}>\n kr: {String(task.metadata.krId)}\n </Badge>\n )}\n {task.id && <Badge tone=\"neutral\" title={task.id}>id: {task.id}</Badge>}\n </Inline>\n </Stack>\n\n <div style={{ borderTop: '1px solid var(--border)', paddingTop: 'var(--space-3)' }}>\n <Button variant=\"danger\" onClick={() => { void removeTask(); }} disabled={deleting || busy !== null}>\n <Trash2 size={14} aria-hidden /> {deleting ? 'Deleting…' : 'Delete task'}\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}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Plus } 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 { KanbanBoard } from '../../ui/kanban/KanbanBoard.js';\nimport { KanbanColumn, type KanbanColumnData } from '../../ui/kanban/KanbanColumn.js';\nimport { KanbanCard, useKanbanCardSortable, type KanbanCardData } from '../../ui/kanban/KanbanCard.js';\nimport { KanbanToolbar, useKanbanSelection, type KanbanFilter } from '../../ui/index.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { TaskDetail } from '../../ui/tasks/TaskDetail.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Textarea } from '../../ui/controls/Textarea.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport type { Task, WsMessage } from '../../data/types.js';\n\ntype TaskStatus = NonNullable<Task['status']>;\n\n/**\n * TasksView — Sprint S10. Pulls `/api/tasks` and maps server statuses\n * to v8 kanban columns. Drag a card between columns → PATCH\n * /api/tasks/:id/status. Live updates via `tasks:change`.\n *\n * v10.0.6 — adds KanbanToolbar (search + priority filter chips +\n * bulk-actions row), useKanbanSelection hook (Esc-to-clear), and a\n * 6th \"Backlog\" column from PR #14.\n */\n\nconst COLUMNS: KanbanColumnData[] = [\n { id: 'backlog', title: 'Backlog', accentTone: 'neutral' },\n { id: 'queued', title: 'Queued', accentTone: 'info' },\n { id: 'doing', title: 'In progress', accentTone: 'accent', wipLimit: 5 },\n { id: 'blocked', title: 'In review', accentTone: 'warning' },\n { id: 'done', title: 'Done', accentTone: 'success' },\n { id: 'archived', title: 'Archived', accentTone: 'neutral' },\n];\n\nconst PRIORITY_MAP: Record<string, KanbanCardData['priority']> = {\n low: 'low',\n medium: 'medium',\n high: 'high',\n urgent: 'urgent',\n};\n\ninterface Card extends KanbanCardData {\n taskId: string;\n columnId: TaskStatus;\n}\n\nfunction taskToCard(t: Task): Card {\n return {\n id: t.id,\n taskId: t.id,\n columnId: statusToColumn(t.status),\n title: t.title,\n priority: PRIORITY_MAP[t.priority || 'medium'] || 'medium',\n branch: t.branch,\n due: t.due,\n comments: t.comments,\n attachments: t.attachments,\n };\n}\n\nfunction statusToColumn(status?: TaskStatus): TaskStatus {\n switch (status) {\n case 'backlog':\n case 'queued':\n case 'doing':\n case 'blocked':\n case 'done':\n case 'archived':\n return status;\n default:\n return 'backlog';\n }\n}\n\n/**\n * SortableCard — wraps a single KanbanCard with dnd-kit's useSortable\n * so KanbanBoard.onDragEnd can fire.\n */\nfunction SortableCard({ card }: { card: Card }): JSX.Element {\n const sortable = useKanbanCardSortable(card.id);\n return (\n <KanbanCard\n card={card}\n isDragging={sortable.isDragging}\n dragHandleProps={{ ...sortable.attributes, ...sortable.listeners, ref: sortable.setNodeRef, style: sortable.style }}\n />\n );\n}\n\nexport function TasksView(): JSX.Element {\n const tasks = useFetch<{ tasks?: Task[]; count?: number }>('/api/tasks');\n const [cards, setCards] = useState<Card[]>([]);\n const [error, setError] = useState<string | null>(null);\n const [openTaskId, setOpenTaskId] = useState<string | null>(null);\n const selection = useKanbanSelection();\n const [query, setQuery] = useState<string>('');\n const [activeFilters, setActiveFilters] = useState<ReadonlySet<string>>(new Set());\n const [createDraft, setCreateDraft] = useState<{ title: string; description: string; priority: 'low' | 'medium' | 'high' | 'urgent' } | null>(null);\n const [creating, setCreating] = useState(false);\n\n const saveCreate = async (): Promise<void> => {\n if (createDraft === null || !createDraft.title.trim()) return;\n setCreating(true);\n try {\n await fetchJson('/api/tasks', { method: 'POST', body: { title: createDraft.title.trim(), description: createDraft.description, priority: createDraft.priority, status: 'queued' } });\n setCreateDraft(null);\n tasks.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setCreating(false);\n }\n };\n\n const onWsRemove = useCallback((msg: WsMessage) => {\n const m = msg as { type?: string; id?: string };\n if (m.type !== 'tasks:removed' && m.type !== 'task:removed') return;\n if (!m.id) return;\n setCards((prev) => prev.filter((c) => c.taskId !== m.id));\n selection.remove([m.id]);\n if (openTaskId === m.id) setOpenTaskId(null);\n }, [openTaskId, selection]);\n useWsMessage('tasks:removed', onWsRemove);\n useWsMessage('task:removed', onWsRemove);\n\n const toggleSelect = (taskId: string): void => {\n selection.toggle(taskId);\n };\n\n const bulkMove = async (toStatus: TaskStatus): Promise<void> => {\n const ids = Array.from(selection.selected);\n if (ids.length === 0) return;\n setCards((prev) => prev.map((c) => (selection.has(c.taskId) ? { ...c, columnId: toStatus } : c)));\n try {\n await fetchJson('/api/tasks/bulk-status', {\n method: 'PATCH',\n body: { ids, status: toStatus },\n });\n selection.clear();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n\n // Sync fetched list → local state. Effect-driven so we don't setState\n // during render (which React warns about under StrictMode and which\n // can double-render the cards).\n useEffect(() => {\n if (tasks.data?.tasks) {\n setCards(tasks.data.tasks.map(taskToCard));\n }\n }, [tasks.data]);\n\n const onWsChange = useCallback((msg: WsMessage) => {\n if (msg.type !== 'tasks:change') return;\n const t = msg.task as Task | undefined;\n if (!t) return;\n setCards((prev) => {\n const idx = prev.findIndex((c) => c.taskId === t.id);\n const card = taskToCard({ ...t, status: statusToColumn(t.status) });\n if (idx === -1) return [...prev, card];\n const copy = prev.slice();\n copy[idx] = { ...copy[idx], ...card };\n return copy;\n });\n }, []);\n useWsMessage('tasks:change', onWsChange);\n\n const onCardMove = useCallback(async (cardId: string, _from: string, to: string) => {\n const card = cards.find((c) => c.taskId === cardId || c.id === cardId);\n if (!card) return;\n const nextStatus = statusToColumn(to as TaskStatus);\n setCards((prev) =>\n prev.map((c) => (c.taskId === cardId ? { ...c, columnId: nextStatus } : c)),\n );\n try {\n await fetchJson(`/api/tasks/${encodeURIComponent(card.taskId)}/status`, {\n method: 'PATCH',\n body: { status: nextStatus },\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n // Roll back on failure.\n setCards((prev) =>\n prev.map((c) => (c.taskId === cardId ? { ...c, columnId: card.columnId } : c)),\n );\n }\n }, [cards]);\n\n const counts: Record<string, number> = {};\n for (const c of cards) counts[c.columnId] = (counts[c.columnId] || 0) + 1;\n\n const openTask = openTaskId ? tasks.data?.tasks?.find((t) => t.id === openTaskId) ?? null : null;\n const selectedCount = selection.selected.size;\n\n // ── v10.0.6 — search + filter chips (PR #14 toolbar wiring) ──\n const filteredCards = useMemo<Card[]>(() => {\n const q = query.trim().toLowerCase();\n return cards.filter((c) => {\n if (activeFilters.size > 0) {\n if (activeFilters.has(`status:${c.columnId}`) === false) {\n const hasPriority = c.priority !== undefined && activeFilters.has(`priority:${c.priority}`);\n const hasStatus = activeFilters.has(`status:${c.columnId}`);\n if (!hasPriority && !hasStatus) return false;\n }\n }\n if (q !== '') {\n const hay = `${c.title} ${c.description ?? ''}`.toLowerCase();\n if (hay.includes(q) === false) return false;\n }\n return true;\n });\n }, [cards, query, activeFilters]);\n\n const priorityFilters: KanbanFilter[] = [\n { id: 'priority:low', label: 'Low', tone: 'neutral' },\n { id: 'priority:medium', label: 'Medium', tone: 'info' },\n { id: 'priority:high', label: 'High', tone: 'warning' },\n { id: 'priority:urgent', label: 'Urgent', tone: 'danger' },\n ];\n const statusFilters: KanbanFilter[] = COLUMNS.map((c) => ({ id: `status:${c.id}`, label: c.title as string }));\n const allFilters: KanbanFilter[] = [...priorityFilters, ...statusFilters];\n\n const onFilterToggle = useCallback((id: string) => {\n setActiveFilters((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }, []);\n const onClearFilters = useCallback(() => setActiveFilters(new Set()), []);\n\n return (\n <Stack gap={4} data-testid=\"tasks-view\">\n <ViewHeader\n title=\"Tasks\"\n description=\"Drag cards across columns. Click a card to edit. Use the checkbox to select multiple.\"\n actions={\n <Inline gap={2} align=\"center\">\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Button variant=\"primary\" onClick={() => setCreateDraft({ title: '', description: '', priority: 'medium' })} data-testid=\"task-create-open\">\n <Plus size={14} aria-hidden /> New task\n </Button>\n </Inline>\n }\n />\n {selectedCount > 0 && (\n <KanbanToolbar\n totalCount={cards.length}\n visibleCount={filteredCards.length}\n selectedCount={selectedCount}\n query={query}\n onQueryChange={setQuery}\n filters={allFilters}\n onFilterToggle={onFilterToggle}\n onClearFilters={onClearFilters}\n onNewTask={() => setCreateDraft({ title: '', description: '', priority: 'medium' })}\n onBulkMove={() => void bulkMove('doing')}\n onBulkArchive={() => void bulkMove('archived')}\n onBulkDelete={async () => {\n const ids = Array.from(selection.selected);\n if (ids.length === 0) return;\n if (!window.confirm(`Delete ${ids.length} task${ids.length === 1 ? '' : 's'}? This cannot be undone.`)) return;\n try {\n await fetchJson('/api/tasks/bulk-status', { method: 'PATCH', body: { ids, status: 'archived' } });\n selection.clear();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n }}\n onClearSelection={() => selection.clear()}\n />\n )}\n {tasks.loading && cards.length === 0 ? (\n <Stack gap={3}>\n <Skeleton style={{ height: 120 }} />\n <Skeleton style={{ height: 120 }} />\n </Stack>\n ) : (\n <KanbanBoard columns={COLUMNS} onCardMove={onCardMove}>\n {COLUMNS.map((col) => {\n const inColumn = filteredCards.filter((c) => c.columnId === col.id);\n return (\n <KanbanColumn\n key={col.id}\n column={{ ...col, count: counts[col.id] || 0 }}\n >\n {inColumn.map((card) => (\n <div key={card.id} style={{ position: 'relative' }}>\n <input\n type=\"checkbox\"\n checked={selection.has(card.taskId)}\n onChange={() => toggleSelect(card.taskId)}\n onClick={(e) => e.stopPropagation()}\n aria-label={`Select ${card.title}`}\n style={{ position: 'absolute', top: 8, left: 8, zIndex: 2 }}\n />\n <div onClick={() => setOpenTaskId(card.taskId)} role=\"button\" tabIndex={0} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setOpenTaskId(card.taskId); } }} style={{ cursor: 'pointer' }}>\n <SortableCard card={card} />\n </div>\n </div>\n ))}\n </KanbanColumn>\n );\n })}\n </KanbanBoard>\n )}\n {openTask && (\n <TaskDetail\n task={openTask}\n open={openTaskId !== null}\n onOpenChange={(o) => { if (!o) setOpenTaskId(null); }}\n onDeleted={() => {\n setCards((prev) => prev.filter((c) => c.taskId !== openTask.id));\n setOpenTaskId(null);\n }}\n />\n )}\n\n {/* v9.2.0 — create-task Sheet. Replaces the missing \"new task\"\n action that the audit flagged as a HIGH gap. */}\n <Sheet open={createDraft !== null} onOpenChange={(o) => { if (!o) setCreateDraft(null); }}>\n <SheetContent side=\"right\" title=\"New task\">\n {createDraft !== null && (\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"task-create-title\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Title</label>\n <Input\n id=\"task-create-title\"\n value={createDraft.title}\n onChange={(e) => setCreateDraft({ ...createDraft, title: e.target.value })}\n placeholder=\"What needs doing?\"\n disabled={creating}\n data-testid=\"task-create-title\"\n />\n </Stack>\n <Stack gap={2}>\n <label htmlFor=\"task-create-desc\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Description (optional)</label>\n <Textarea\n id=\"task-create-desc\"\n value={createDraft.description}\n onChange={(e) => setCreateDraft({ ...createDraft, description: e.target.value })}\n rows={4}\n disabled={creating}\n data-testid=\"task-create-desc\"\n />\n </Stack>\n <Stack gap={2}>\n <label htmlFor=\"task-create-priority\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Priority</label>\n <select\n id=\"task-create-priority\"\n value={createDraft.priority}\n onChange={(e) => setCreateDraft({ ...createDraft, priority: e.target.value as typeof createDraft.priority })}\n disabled={creating}\n data-testid=\"task-create-priority\"\n style={{ height: 32, padding: '0 var(--space-2)', borderRadius: 'var(--radius-sm)', border: '1px solid var(--border)', background: 'var(--surface-0)', color: 'var(--fg)', fontSize: 'var(--fs-13)' }}\n >\n <option value=\"low\">Low</option>\n <option value=\"medium\">Medium</option>\n <option value=\"high\">High</option>\n <option value=\"urgent\">Urgent</option>\n </select>\n </Stack>\n <Inline gap={2}>\n <Button variant=\"primary\" onClick={() => { void saveCreate(); }} disabled={creating || !createDraft.title.trim()} data-testid=\"task-create-submit\">\n Create task\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":["ArrowRight","createLucideIcon","KanbanToolbar","props","totalCount","visibleCount","selectedCount","query","onQueryChange","filters","onFilterToggle","onClearFilters","onNewTask","onBulkMove","onBulkArchive","onBulkDelete","onClearSelection","className","searchFocused","setSearchFocused","useState","isBulk","jsx","cx","jsxs","Fragment","Button","Archive","Trash2","IconButton","X","Search","e","Filter","f","tone","isActive","actualId","active","Plus","useKanbanSelection","selected","setSelected","toggle","useCallback","id","prev","next","add","ids","remove","set","clear","useEffect","onKey","ev","target","tag","has","useMemo","PRIORITY_OPTIONS","STATUS_OPTIONS","TaskDetail","task","open","onOpenChange","onDeleted","title","setTitle","description","setDescription","priority","setPriority","status","setStatus","assignee","setAssignee","due","setDue","branch","setBranch","comment","setComment","busy","setBusy","message","setMessage","error","setError","deleting","setDeleting","patch","body","label","fetchJson","err","saveTitle","saveDescription","savePriority","v","saveStatus","saveAssignee","saveDue","saveBranch","addComment","removeTask","Sheet","SheetContent","Stack","Input","Select","SelectTrigger","SelectContent","opt","SelectItem","Inline","Textarea","_a","Badge","_b","Skeleton","COLUMNS","PRIORITY_MAP","taskToCard","t","statusToColumn","SortableCard","card","sortable","useKanbanCardSortable","KanbanCard","TasksView","tasks","useFetch","cards","setCards","openTaskId","setOpenTaskId","selection","setQuery","activeFilters","setActiveFilters","createDraft","setCreateDraft","creating","setCreating","saveCreate","FetchError","onWsRemove","msg","m","useWsMessage","toggleSelect","taskId","bulkMove","toStatus","onWsChange","idx","c","copy","onCardMove","cardId","_from","to","nextStatus","counts","openTask","filteredCards","q","hasPriority","hasStatus","priorityFilters","statusFilters","allFilters","ViewHeader","KanbanBoard","col","inColumn","KanbanColumn","o"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"TasksView-CQaSFzWY.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/arrow-right.js","../../src/web/v8/ui/kanban/KanbanToolbar.tsx","../../src/web/v8/ui/kanban/useKanbanSelection.ts","../../src/web/v8/ui/tasks/TaskDetail.tsx","../../src/web/v8/views/Tasks/TasksView.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 ArrowRight = createLucideIcon(\"ArrowRight\", [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"m12 5 7 7-7 7\", key: \"xquz4c\" }]\n]);\n\nexport { ArrowRight as default };\n//# sourceMappingURL=arrow-right.js.map\n","import { useState, type ChangeEvent, type ReactNode } from 'react';\nimport { Plus, Search, Trash2, Archive, ArrowRight, X, Filter } from 'lucide-react';\nimport { Button } from '../controls/Button.js';\nimport { IconButton } from '../controls/IconButton.js';\nimport { cx } from '../utils/cx.js';\n\n/**\n * KanbanToolbar — top-of-board toolbar.\n *\n * Three modes:\n * - normal: search input + filter chips + \"New task\" button.\n * - selecting: replaces the action row with N-selected count +\n * bulk-actions (Move / Archive / Delete).\n * - filtered: shows a \"Clear filters\" pill next to the search.\n *\n * Consumers control query state via callbacks. The toolbar keeps no\n * internal search/filter state of its own — that lives in the view\n * so the board can re-derive visible cards.\n */\n\nexport interface KanbanFilter {\n /** Stable filter id; used as the chip key + for clearing. */\n id: string;\n /** Visible chip label (e.g. \"High priority\"). */\n label: ReactNode;\n /** Optional tone for the chip. */\n tone?: 'neutral' | 'info' | 'success' | 'warning' | 'danger' | 'accent';\n}\n\nexport interface KanbanToolbarProps {\n /** Total number of cards on the board (for \"showing X of Y\"). */\n totalCount: number;\n /** Number of cards currently visible after filtering. */\n visibleCount: number;\n /** Number of selected cards. When >0, the toolbar swaps to bulk mode. */\n selectedCount: number;\n\n /** Free-text search. */\n query: string;\n onQueryChange: (value: string) => void;\n\n /** Active filters. */\n filters: readonly KanbanFilter[];\n onFilterToggle: (filterId: string) => void;\n onClearFilters: () => void;\n\n /** New-task action. Hidden when the toolbar is in bulk mode. */\n onNewTask?: () => void;\n\n /** Bulk actions, shown only when selectedCount > 0. */\n onBulkMove?: (selectedIds: ReadonlySet<string>) => void;\n onBulkArchive?: (selectedIds: ReadonlySet<string>) => void;\n onBulkDelete?: (selectedIds: ReadonlySet<string>) => void;\n onClearSelection?: () => void;\n\n className?: string;\n}\n\nexport function KanbanToolbar(props: KanbanToolbarProps): JSX.Element {\n const {\n totalCount,\n visibleCount,\n selectedCount,\n query,\n onQueryChange,\n filters,\n onFilterToggle,\n onClearFilters,\n onNewTask,\n onBulkMove,\n onBulkArchive,\n onBulkDelete,\n onClearSelection,\n className,\n } = props;\n\n const [searchFocused, setSearchFocused] = useState(false);\n const isBulk = selectedCount > 0;\n\n return (\n <div\n className={cx('v8-kanban-toolbar', className)}\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: 'var(--space-2)',\n padding: 'var(--space-2) var(--space-3)',\n background: 'var(--surface-0)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius)',\n }}\n >\n {isBulk ? (\n <>\n <span\n style={{\n fontSize: 'var(--fs-13)',\n fontWeight: 600,\n color: 'var(--fg)',\n }}\n >\n {selectedCount} selected\n </span>\n <span style={{ flex: 1 }} />\n {onBulkMove !== undefined && (\n <Button size=\"sm\" variant=\"secondary\" leftIcon={<ArrowRight size={14} aria-hidden=\"true\" />} onClick={() => onBulkMove(new Set())}>\n Move…\n </Button>\n )}\n {onBulkArchive !== undefined && (\n <Button\n size=\"sm\"\n variant=\"secondary\"\n leftIcon={<Archive size={14} aria-hidden=\"true\" />}\n onClick={() => onBulkArchive(new Set())}\n >\n Archive\n </Button>\n )}\n {onBulkDelete !== undefined && (\n <Button\n size=\"sm\"\n variant=\"danger\"\n leftIcon={<Trash2 size={14} aria-hidden=\"true\" />}\n onClick={() => onBulkDelete(new Set())}\n >\n Delete\n </Button>\n )}\n {onClearSelection !== undefined && (\n <IconButton aria-label=\"Clear selection\" onClick={onClearSelection} size=\"sm\">\n <X size={14} aria-hidden=\"true\" />\n </IconButton>\n )}\n </>\n ) : (\n <>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '0 var(--space-2)',\n height: 32,\n background: 'var(--input-bg)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n minWidth: 220,\n flex: '1 1 220px',\n maxWidth: 360,\n }}\n >\n <Search size={14} aria-hidden=\"true\" style={{ color: 'var(--fg-muted)', flexShrink: 0 }} />\n <input\n type=\"search\"\n value={query}\n placeholder=\"Filter tasks…\"\n onChange={(e: ChangeEvent<HTMLInputElement>) => onQueryChange(e.target.value)}\n onFocus={() => setSearchFocused(true)}\n onBlur={() => setSearchFocused(false)}\n aria-label=\"Filter tasks\"\n style={{\n flex: 1,\n minWidth: 0,\n border: 0,\n outline: 0,\n background: 'transparent',\n color: 'var(--fg)',\n fontSize: 'var(--fs-13)',\n fontFamily: 'inherit',\n }}\n />\n {query !== '' && (\n <button\n type=\"button\"\n onClick={() => onQueryChange('')}\n aria-label=\"Clear search\"\n style={{\n background: 'transparent',\n border: 0,\n padding: 2,\n color: 'var(--fg-muted)',\n cursor: 'pointer',\n display: 'inline-flex',\n }}\n >\n <X size={12} aria-hidden=\"true\" />\n </button>\n )}\n </div>\n {filters.length > 0 && (\n <div\n role=\"toolbar\"\n aria-label=\"Task filters\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n flexWrap: 'wrap',\n }}\n >\n <Filter\n size={12}\n aria-hidden=\"true\"\n style={{ color: 'var(--fg-muted)', marginRight: 2 }}\n />\n {filters.map((f) => {\n const tone = f.tone ?? 'neutral';\n const isActive = f.id.startsWith('active:');\n // Display rule: callers prepend \"active:\" when toggled on.\n const actualId = isActive ? f.id.slice('active:'.length) : f.id;\n const active = isActive;\n return (\n <button\n key={f.id}\n type=\"button\"\n onClick={() => onFilterToggle(actualId)}\n aria-pressed={active}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n height: 26,\n padding: '0 var(--space-2)',\n borderRadius: 'var(--radius-pill)',\n border: `1px solid var(--${active ? 'accent' : 'border'})`,\n background: active ? 'color-mix(in oklch, var(--accent) 14%, transparent)' : 'transparent',\n color: 'var(--fg-muted)',\n fontSize: 'var(--fs-12)',\n fontWeight: 500,\n cursor: 'pointer',\n }}\n >\n <span\n aria-hidden=\"true\"\n style={{\n width: 6,\n height: 6,\n borderRadius: 'var(--radius-pill)',\n background:\n tone === 'neutral'\n ? 'var(--fg-muted)'\n : `var(--${tone})`,\n }}\n />\n {f.label}\n </button>\n );\n })}\n {filters.some((f) => f.id.startsWith('active:')) && (\n <button\n type=\"button\"\n onClick={onClearFilters}\n style={{\n background: 'transparent',\n border: 0,\n color: 'var(--fg-muted)',\n fontSize: 'var(--fs-12)',\n cursor: 'pointer',\n padding: '0 var(--space-2)',\n height: 26,\n }}\n >\n Clear\n </button>\n )}\n </div>\n )}\n <span style={{ flex: 1 }} />\n <span\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-muted)',\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {visibleCount === totalCount\n ? `${totalCount} task${totalCount === 1 ? '' : 's'}`\n : `${visibleCount} of ${totalCount}`}\n </span>\n {onNewTask !== undefined && (\n <Button size=\"sm\" variant=\"primary\" leftIcon={<Plus size={14} aria-hidden=\"true\" />} onClick={onNewTask}>\n New task\n </Button>\n )}\n </>\n )}\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\n\n/**\n * useKanbanSelection — track a Set<string> of selected card ids with\n * a small set of helpers, plus an Esc-to-clear keyboard shortcut.\n *\n * Designed for the kanban board's multi-select toolbar. Selection is\n * kept in component state so the board can hand it to the toolbar +\n * card checkbox without prop-drilling.\n */\n\nexport interface UseKanbanSelectionApi {\n /** Current selection. Use `.size` for the count. */\n selected: ReadonlySet<string>;\n /** True iff `id` is in the selection. */\n has: (id: string) => boolean;\n /** Add or remove a single id. */\n toggle: (id: string) => void;\n /** Add ids (no-op if already present). */\n add: (ids: readonly string[]) => void;\n /** Remove ids. */\n remove: (ids: readonly string[]) => void;\n /** Replace the whole selection. */\n set: (ids: readonly string[]) => void;\n /** Drop everything. */\n clear: () => void;\n}\n\nexport function useKanbanSelection(): UseKanbanSelectionApi {\n const [selected, setSelected] = useState<ReadonlySet<string>>(() => new Set());\n\n const toggle = useCallback((id: string) => {\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }, []);\n\n const add = useCallback((ids: readonly string[]) => {\n if (ids.length === 0) return;\n setSelected((prev) => {\n const next = new Set(prev);\n for (const id of ids) next.add(id);\n return next;\n });\n }, []);\n\n const remove = useCallback((ids: readonly string[]) => {\n if (ids.length === 0) return;\n setSelected((prev) => {\n const next = new Set(prev);\n for (const id of ids) next.delete(id);\n return next;\n });\n }, []);\n\n const set = useCallback((ids: readonly string[]) => {\n setSelected(new Set(ids));\n }, []);\n\n const clear = useCallback(() => {\n setSelected((prev) => (prev.size === 0 ? prev : new Set()));\n }, []);\n\n // Esc clears selection, but only when focus is not inside a text\n // input/textarea/contenteditable (so the user can still press Esc\n // inside an editor).\n useEffect(() => {\n const onKey = (ev: KeyboardEvent) => {\n if (ev.key !== 'Escape') return;\n const target = ev.target as HTMLElement | null;\n if (target) {\n const tag = target.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || target.isContentEditable) return;\n }\n clear();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [clear]);\n\n const has = useCallback((id: string) => selected.has(id), [selected]);\n\n return useMemo(\n () => ({ selected, has, toggle, add, remove, set, clear }),\n [selected, has, toggle, add, remove, set, clear],\n );\n}\n","import { useEffect, useState } from 'react';\nimport { Plus, Trash2 } 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 { Textarea } from '../controls/Textarea.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 { Task } from '../../data/types.js';\n\n/**\n * TaskDetail — right-side Drawer for editing a single task. Sprint S17.\n *\n * Source-of-truth lives on the backend (tasks-store). Each edit PATCHes\n * `/api/tasks/:id` and the server re-broadcasts the canonical state via\n * `tasks:change`. The Drawer stays open while the WS round-trip resolves\n * so optimistic UI + canonical merge feels seamless.\n */\n\nconst PRIORITY_OPTIONS = [\n { value: 'low', label: 'Low' },\n { value: 'medium', label: 'Medium' },\n { value: 'high', label: 'High' },\n { value: 'urgent', label: 'Urgent' },\n];\n\nconst STATUS_OPTIONS = [\n { value: 'queued', label: 'Backlog' },\n { value: 'doing', label: 'In progress' },\n { value: 'blocked', label: 'In review' },\n { value: 'done', label: 'Done' },\n { value: 'archived', label: 'Archived' },\n];\n\nexport interface TaskDetailProps {\n task: Task;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onDeleted?: () => void;\n}\n\nexport function TaskDetail(props: TaskDetailProps): JSX.Element {\n const { task, open, onOpenChange, onDeleted } = props;\n const [title, setTitle] = useState<string>(task.title);\n const [description, setDescription] = useState<string>(task.description || '');\n const [priority, setPriority] = useState<string>(task.priority || 'medium');\n const [status, setStatus] = useState<string>(task.status || 'queued');\n const [assignee, setAssignee] = useState<string>(task.assignee || '');\n const [due, setDue] = useState<string>(task.due || '');\n const [branch, setBranch] = useState<string>(task.branch || '');\n const [comment, setComment] = 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 const [deleting, setDeleting] = useState<boolean>(false);\n\n useEffect(() => {\n if (open) {\n setTitle(task.title);\n setDescription(task.description || '');\n setPriority(task.priority || 'medium');\n setStatus(task.status || 'queued');\n setAssignee(task.assignee || '');\n setDue(task.due || '');\n setBranch(task.branch || '');\n setComment('');\n setMessage(null);\n setError(null);\n }\n }, [open, task]);\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/tasks/${encodeURIComponent(task.id)}`, {\n method: 'PATCH',\n body,\n });\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 !== task.title) void patch({ title: title.trim() }, 'Title');\n };\n const saveDescription = (): void => {\n if (description !== (task.description || '')) void patch({ description }, 'Description');\n };\n const savePriority = (v: string): void => {\n setPriority(v);\n if (v !== task.priority) void patch({ priority: v }, 'Priority');\n };\n const saveStatus = (v: string): void => {\n setStatus(v);\n if (v !== task.status) void patch({ status: v }, 'Status');\n };\n const saveAssignee = (): void => {\n const v = assignee.trim();\n if (v !== (task.assignee || '')) void patch({ assignee: v }, 'Assignee');\n };\n const saveDue = (): void => {\n const v = due.trim();\n if (v !== (task.due || '')) void patch({ due: v }, 'Due');\n };\n const saveBranch = (): void => {\n const v = branch.trim();\n if (v !== (task.branch || '')) void patch({ branch: v }, 'Branch');\n };\n\n const addComment = async (): Promise<void> => {\n const v = comment.trim();\n if (!v) return;\n setBusy('comment');\n setError(null);\n try {\n await fetchJson(`/api/tasks/${encodeURIComponent(task.id)}/comments`, {\n method: 'POST',\n body: { text: v },\n });\n setComment('');\n setMessage('Comment added.');\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(null);\n }\n };\n\n const removeTask = async (): Promise<void> => {\n const ok = typeof window !== 'undefined' && typeof window.confirm === 'function'\n ? window.confirm(`Delete task \"${task.title}\"? This is irreversible.`)\n : true;\n if (!ok) return;\n setDeleting(true);\n try {\n await fetchJson(`/api/tasks/${encodeURIComponent(task.id)}`, { method: 'DELETE' });\n onDeleted?.();\n onOpenChange(false);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n setDeleting(false);\n }\n };\n\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent side=\"right\" title=\"Edit task\">\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"task-title\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Title\n </label>\n <Input\n id=\"task-title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n onBlur={saveTitle}\n disabled={busy !== null}\n />\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"task-status\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Status\n </label>\n <Select value={status} onValueChange={saveStatus}>\n <SelectTrigger id=\"task-status\" size=\"sm\" placeholder=\"Status\" />\n <SelectContent>\n {STATUS_OPTIONS.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Stack>\n\n <Inline gap={2}>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"task-priority\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Priority\n </label>\n <Select value={priority} onValueChange={savePriority}>\n <SelectTrigger id=\"task-priority\" size=\"sm\" placeholder=\"Priority\" />\n <SelectContent>\n {PRIORITY_OPTIONS.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Stack>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"task-due\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Due\n </label>\n <Input\n id=\"task-due\"\n type=\"date\"\n value={due ? due.slice(0, 10) : ''}\n onChange={(e) => setDue(e.target.value)}\n onBlur={saveDue}\n disabled={busy !== null}\n />\n </Stack>\n </Inline>\n\n <Inline gap={2}>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"task-assignee\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Assignee\n </label>\n <Input\n id=\"task-assignee\"\n value={assignee}\n onChange={(e) => setAssignee(e.target.value)}\n onBlur={saveAssignee}\n placeholder=\"agent name (blank = unassigned)\"\n disabled={busy !== null}\n />\n </Stack>\n <Stack gap={2} style={{ flex: 1 }}>\n <label htmlFor=\"task-branch\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Branch\n </label>\n <Input\n id=\"task-branch\"\n value={branch}\n onChange={(e) => setBranch(e.target.value)}\n onBlur={saveBranch}\n placeholder=\"feature/foo\"\n disabled={busy !== null}\n />\n </Stack>\n </Inline>\n\n <Stack gap={2}>\n <label htmlFor=\"task-description\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Description\n </label>\n <Textarea\n id=\"task-description\"\n rows={5}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n onBlur={saveDescription}\n disabled={busy !== null}\n placeholder=\"What's the work, why, how to verify…\"\n />\n </Stack>\n\n <Stack gap={2}>\n <label htmlFor=\"task-comment\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n Add comment\n </label>\n <Inline gap={2} align=\"start\">\n <Textarea\n id=\"task-comment\"\n rows={2}\n value={comment}\n onChange={(e) => setComment(e.target.value)}\n placeholder=\"Leave a progress note…\"\n disabled={busy !== null}\n style={{ flex: 1 }}\n />\n <Button variant=\"secondary\" onClick={() => { void addComment(); }} disabled={!comment.trim() || busy !== null}>\n <Plus size={14} aria-hidden /> Comment\n </Button>\n </Inline>\n </Stack>\n\n <Stack gap={2}>\n <div style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Metadata</div>\n <Inline gap={1} wrap>\n {task.metadata?.goalId !== undefined && typeof task.metadata.goalId === 'string' && (\n <Badge tone=\"info\" title={`Linked to goal ${String(task.metadata.goalId)}`}>\n goal: {String(task.metadata.goalId)}\n </Badge>\n )}\n {task.metadata?.krId !== undefined && typeof task.metadata.krId === 'string' && (\n <Badge tone=\"info\" title={`Linked to KR ${String(task.metadata.krId)}`}>\n kr: {String(task.metadata.krId)}\n </Badge>\n )}\n {task.id && <Badge tone=\"neutral\" title={task.id}>id: {task.id}</Badge>}\n </Inline>\n </Stack>\n\n <div style={{ borderTop: '1px solid var(--border)', paddingTop: 'var(--space-3)' }}>\n <Button variant=\"danger\" onClick={() => { void removeTask(); }} disabled={deleting || busy !== null}>\n <Trash2 size={14} aria-hidden /> {deleting ? 'Deleting…' : 'Delete task'}\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}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Plus } 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 { KanbanBoard } from '../../ui/kanban/KanbanBoard.js';\nimport { KanbanColumn, type KanbanColumnData } from '../../ui/kanban/KanbanColumn.js';\nimport { KanbanCard, useKanbanCardSortable, type KanbanCardData } from '../../ui/kanban/KanbanCard.js';\nimport { KanbanToolbar, useKanbanSelection, type KanbanFilter } from '../../ui/index.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { TaskDetail } from '../../ui/tasks/TaskDetail.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Textarea } from '../../ui/controls/Textarea.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport type { Task, WsMessage } from '../../data/types.js';\n\ntype TaskStatus = NonNullable<Task['status']>;\n\n/**\n * TasksView — Sprint S10. Pulls `/api/tasks` and maps server statuses\n * to v8 kanban columns. Drag a card between columns → PATCH\n * /api/tasks/:id/status. Live updates via `tasks:change`.\n *\n * v10.0.6 — adds KanbanToolbar (search + priority filter chips +\n * bulk-actions row), useKanbanSelection hook (Esc-to-clear), and a\n * 6th \"Backlog\" column from PR #14.\n */\n\nconst COLUMNS: KanbanColumnData[] = [\n { id: 'backlog', title: 'Backlog', accentTone: 'neutral' },\n { id: 'queued', title: 'Queued', accentTone: 'info' },\n { id: 'doing', title: 'In progress', accentTone: 'accent', wipLimit: 5 },\n { id: 'blocked', title: 'In review', accentTone: 'warning' },\n { id: 'done', title: 'Done', accentTone: 'success' },\n { id: 'archived', title: 'Archived', accentTone: 'neutral' },\n];\n\nconst PRIORITY_MAP: Record<string, KanbanCardData['priority']> = {\n low: 'low',\n medium: 'medium',\n high: 'high',\n urgent: 'urgent',\n};\n\ninterface Card extends KanbanCardData {\n taskId: string;\n columnId: TaskStatus;\n}\n\nfunction taskToCard(t: Task): Card {\n return {\n id: t.id,\n taskId: t.id,\n columnId: statusToColumn(t.status),\n title: t.title,\n priority: PRIORITY_MAP[t.priority || 'medium'] || 'medium',\n branch: t.branch,\n due: t.due,\n comments: t.comments,\n attachments: t.attachments,\n };\n}\n\nfunction statusToColumn(status?: TaskStatus): TaskStatus {\n switch (status) {\n case 'backlog':\n case 'queued':\n case 'doing':\n case 'blocked':\n case 'done':\n case 'archived':\n return status;\n default:\n return 'backlog';\n }\n}\n\n/**\n * SortableCard — wraps a single KanbanCard with dnd-kit's useSortable\n * so KanbanBoard.onDragEnd can fire.\n */\nfunction SortableCard({ card }: { card: Card }): JSX.Element {\n const sortable = useKanbanCardSortable(card.id);\n return (\n <KanbanCard\n card={card}\n isDragging={sortable.isDragging}\n dragHandleProps={{ ...sortable.attributes, ...sortable.listeners, ref: sortable.setNodeRef, style: sortable.style }}\n />\n );\n}\n\nexport function TasksView(): JSX.Element {\n const tasks = useFetch<{ tasks?: Task[]; count?: number }>('/api/tasks');\n const [cards, setCards] = useState<Card[]>([]);\n const [error, setError] = useState<string | null>(null);\n const [openTaskId, setOpenTaskId] = useState<string | null>(null);\n const selection = useKanbanSelection();\n const [query, setQuery] = useState<string>('');\n const [activeFilters, setActiveFilters] = useState<ReadonlySet<string>>(new Set());\n const [createDraft, setCreateDraft] = useState<{ title: string; description: string; priority: 'low' | 'medium' | 'high' | 'urgent' } | null>(null);\n const [creating, setCreating] = useState(false);\n\n const saveCreate = async (): Promise<void> => {\n if (createDraft === null || !createDraft.title.trim()) return;\n setCreating(true);\n try {\n await fetchJson('/api/tasks', { method: 'POST', body: { title: createDraft.title.trim(), description: createDraft.description, priority: createDraft.priority, status: 'queued' } });\n setCreateDraft(null);\n tasks.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setCreating(false);\n }\n };\n\n const onWsRemove = useCallback((msg: WsMessage) => {\n const m = msg as { type?: string; id?: string };\n if (m.type !== 'tasks:removed' && m.type !== 'task:removed') return;\n if (!m.id) return;\n setCards((prev) => prev.filter((c) => c.taskId !== m.id));\n selection.remove([m.id]);\n if (openTaskId === m.id) setOpenTaskId(null);\n }, [openTaskId, selection]);\n useWsMessage('tasks:removed', onWsRemove);\n useWsMessage('task:removed', onWsRemove);\n\n const toggleSelect = (taskId: string): void => {\n selection.toggle(taskId);\n };\n\n const bulkMove = async (toStatus: TaskStatus): Promise<void> => {\n const ids = Array.from(selection.selected);\n if (ids.length === 0) return;\n setCards((prev) => prev.map((c) => (selection.has(c.taskId) ? { ...c, columnId: toStatus } : c)));\n try {\n await fetchJson('/api/tasks/bulk-status', {\n method: 'PATCH',\n body: { ids, status: toStatus },\n });\n selection.clear();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n\n // Sync fetched list → local state. Effect-driven so we don't setState\n // during render (which React warns about under StrictMode and which\n // can double-render the cards).\n useEffect(() => {\n if (tasks.data?.tasks) {\n setCards(tasks.data.tasks.map(taskToCard));\n }\n }, [tasks.data]);\n\n const onWsChange = useCallback((msg: WsMessage) => {\n if (msg.type !== 'tasks:change') return;\n const t = msg.task as Task | undefined;\n if (!t) return;\n setCards((prev) => {\n const idx = prev.findIndex((c) => c.taskId === t.id);\n const card = taskToCard({ ...t, status: statusToColumn(t.status) });\n if (idx === -1) return [...prev, card];\n const copy = prev.slice();\n copy[idx] = { ...copy[idx], ...card };\n return copy;\n });\n }, []);\n useWsMessage('tasks:change', onWsChange);\n\n const onCardMove = useCallback(async (cardId: string, _from: string, to: string) => {\n const card = cards.find((c) => c.taskId === cardId || c.id === cardId);\n if (!card) return;\n const nextStatus = statusToColumn(to as TaskStatus);\n setCards((prev) =>\n prev.map((c) => (c.taskId === cardId ? { ...c, columnId: nextStatus } : c)),\n );\n try {\n await fetchJson(`/api/tasks/${encodeURIComponent(card.taskId)}/status`, {\n method: 'PATCH',\n body: { status: nextStatus },\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n // Roll back on failure.\n setCards((prev) =>\n prev.map((c) => (c.taskId === cardId ? { ...c, columnId: card.columnId } : c)),\n );\n }\n }, [cards]);\n\n const counts: Record<string, number> = {};\n for (const c of cards) counts[c.columnId] = (counts[c.columnId] || 0) + 1;\n\n const openTask = openTaskId ? tasks.data?.tasks?.find((t) => t.id === openTaskId) ?? null : null;\n const selectedCount = selection.selected.size;\n\n // ── v10.0.6 — search + filter chips (PR #14 toolbar wiring) ──\n const filteredCards = useMemo<Card[]>(() => {\n const q = query.trim().toLowerCase();\n return cards.filter((c) => {\n if (activeFilters.size > 0) {\n if (activeFilters.has(`status:${c.columnId}`) === false) {\n const hasPriority = c.priority !== undefined && activeFilters.has(`priority:${c.priority}`);\n const hasStatus = activeFilters.has(`status:${c.columnId}`);\n if (!hasPriority && !hasStatus) return false;\n }\n }\n if (q !== '') {\n const hay = `${c.title} ${c.description ?? ''}`.toLowerCase();\n if (hay.includes(q) === false) return false;\n }\n return true;\n });\n }, [cards, query, activeFilters]);\n\n const priorityFilters: KanbanFilter[] = [\n { id: 'priority:low', label: 'Low', tone: 'neutral' },\n { id: 'priority:medium', label: 'Medium', tone: 'info' },\n { id: 'priority:high', label: 'High', tone: 'warning' },\n { id: 'priority:urgent', label: 'Urgent', tone: 'danger' },\n ];\n const statusFilters: KanbanFilter[] = COLUMNS.map((c) => ({ id: `status:${c.id}`, label: c.title as string }));\n const allFilters: KanbanFilter[] = [...priorityFilters, ...statusFilters];\n\n const onFilterToggle = useCallback((id: string) => {\n setActiveFilters((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }, []);\n const onClearFilters = useCallback(() => setActiveFilters(new Set()), []);\n\n return (\n <Stack gap={4} data-testid=\"tasks-view\">\n <ViewHeader\n title=\"Tasks\"\n description=\"Drag cards across columns. Click a card to edit. Use the checkbox to select multiple.\"\n actions={\n <Inline gap={2} align=\"center\">\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Button variant=\"primary\" onClick={() => setCreateDraft({ title: '', description: '', priority: 'medium' })} data-testid=\"task-create-open\">\n <Plus size={14} aria-hidden /> New task\n </Button>\n </Inline>\n }\n />\n {selectedCount > 0 && (\n <KanbanToolbar\n totalCount={cards.length}\n visibleCount={filteredCards.length}\n selectedCount={selectedCount}\n query={query}\n onQueryChange={setQuery}\n filters={allFilters}\n onFilterToggle={onFilterToggle}\n onClearFilters={onClearFilters}\n onNewTask={() => setCreateDraft({ title: '', description: '', priority: 'medium' })}\n onBulkMove={() => void bulkMove('doing')}\n onBulkArchive={() => void bulkMove('archived')}\n onBulkDelete={async () => {\n const ids = Array.from(selection.selected);\n if (ids.length === 0) return;\n if (!window.confirm(`Delete ${ids.length} task${ids.length === 1 ? '' : 's'}? This cannot be undone.`)) return;\n try {\n await fetchJson('/api/tasks/bulk-status', { method: 'PATCH', body: { ids, status: 'archived' } });\n selection.clear();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n }}\n onClearSelection={() => selection.clear()}\n />\n )}\n {tasks.loading && cards.length === 0 ? (\n <Stack gap={3}>\n <Skeleton style={{ height: 120 }} />\n <Skeleton style={{ height: 120 }} />\n </Stack>\n ) : (\n <KanbanBoard columns={COLUMNS} onCardMove={onCardMove}>\n {COLUMNS.map((col) => {\n const inColumn = filteredCards.filter((c) => c.columnId === col.id);\n return (\n <KanbanColumn\n key={col.id}\n column={{ ...col, count: counts[col.id] || 0 }}\n >\n {inColumn.map((card) => (\n <div key={card.id} style={{ position: 'relative' }}>\n <input\n type=\"checkbox\"\n checked={selection.has(card.taskId)}\n onChange={() => toggleSelect(card.taskId)}\n onClick={(e) => e.stopPropagation()}\n aria-label={`Select ${card.title}`}\n style={{ position: 'absolute', top: 8, left: 8, zIndex: 2 }}\n />\n <div onClick={() => setOpenTaskId(card.taskId)} role=\"button\" tabIndex={0} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setOpenTaskId(card.taskId); } }} style={{ cursor: 'pointer' }}>\n <SortableCard card={card} />\n </div>\n </div>\n ))}\n </KanbanColumn>\n );\n })}\n </KanbanBoard>\n )}\n {openTask && (\n <TaskDetail\n task={openTask}\n open={openTaskId !== null}\n onOpenChange={(o) => { if (!o) setOpenTaskId(null); }}\n onDeleted={() => {\n setCards((prev) => prev.filter((c) => c.taskId !== openTask.id));\n setOpenTaskId(null);\n }}\n />\n )}\n\n {/* v9.2.0 — create-task Sheet. Replaces the missing \"new task\"\n action that the audit flagged as a HIGH gap. */}\n <Sheet open={createDraft !== null} onOpenChange={(o) => { if (!o) setCreateDraft(null); }}>\n <SheetContent side=\"right\" title=\"New task\">\n {createDraft !== null && (\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label htmlFor=\"task-create-title\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Title</label>\n <Input\n id=\"task-create-title\"\n value={createDraft.title}\n onChange={(e) => setCreateDraft({ ...createDraft, title: e.target.value })}\n placeholder=\"What needs doing?\"\n disabled={creating}\n data-testid=\"task-create-title\"\n />\n </Stack>\n <Stack gap={2}>\n <label htmlFor=\"task-create-desc\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Description (optional)</label>\n <Textarea\n id=\"task-create-desc\"\n value={createDraft.description}\n onChange={(e) => setCreateDraft({ ...createDraft, description: e.target.value })}\n rows={4}\n disabled={creating}\n data-testid=\"task-create-desc\"\n />\n </Stack>\n <Stack gap={2}>\n <label htmlFor=\"task-create-priority\" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Priority</label>\n <select\n id=\"task-create-priority\"\n value={createDraft.priority}\n onChange={(e) => setCreateDraft({ ...createDraft, priority: e.target.value as typeof createDraft.priority })}\n disabled={creating}\n data-testid=\"task-create-priority\"\n style={{ height: 32, padding: '0 var(--space-2)', borderRadius: 'var(--radius-sm)', border: '1px solid var(--border)', background: 'var(--surface-0)', color: 'var(--fg)', fontSize: 'var(--fs-13)' }}\n >\n <option value=\"low\">Low</option>\n <option value=\"medium\">Medium</option>\n <option value=\"high\">High</option>\n <option value=\"urgent\">Urgent</option>\n </select>\n </Stack>\n <Inline gap={2}>\n <Button variant=\"primary\" onClick={() => { void saveCreate(); }} disabled={creating || !createDraft.title.trim()} data-testid=\"task-create-submit\">\n Create task\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":["ArrowRight","createLucideIcon","KanbanToolbar","props","totalCount","visibleCount","selectedCount","query","onQueryChange","filters","onFilterToggle","onClearFilters","onNewTask","onBulkMove","onBulkArchive","onBulkDelete","onClearSelection","className","searchFocused","setSearchFocused","useState","isBulk","jsx","cx","jsxs","Fragment","Button","Archive","Trash2","IconButton","X","Search","e","Filter","f","tone","isActive","actualId","active","Plus","useKanbanSelection","selected","setSelected","toggle","useCallback","id","prev","next","add","ids","remove","set","clear","useEffect","onKey","ev","target","tag","has","useMemo","PRIORITY_OPTIONS","STATUS_OPTIONS","TaskDetail","task","open","onOpenChange","onDeleted","title","setTitle","description","setDescription","priority","setPriority","status","setStatus","assignee","setAssignee","due","setDue","branch","setBranch","comment","setComment","busy","setBusy","message","setMessage","error","setError","deleting","setDeleting","patch","body","label","fetchJson","err","saveTitle","saveDescription","savePriority","v","saveStatus","saveAssignee","saveDue","saveBranch","addComment","removeTask","Sheet","SheetContent","Stack","Input","Select","SelectTrigger","SelectContent","opt","SelectItem","Inline","Textarea","_a","Badge","_b","Skeleton","COLUMNS","PRIORITY_MAP","taskToCard","t","statusToColumn","SortableCard","card","sortable","useKanbanCardSortable","KanbanCard","TasksView","tasks","useFetch","cards","setCards","openTaskId","setOpenTaskId","selection","setQuery","activeFilters","setActiveFilters","createDraft","setCreateDraft","creating","setCreating","saveCreate","FetchError","onWsRemove","msg","m","useWsMessage","toggleSelect","taskId","bulkMove","toStatus","onWsChange","idx","c","copy","onCardMove","cardId","_from","to","nextStatus","counts","openTask","filteredCards","q","hasPriority","hasStatus","priorityFilters","statusFilters","allFilters","ViewHeader","KanbanBoard","col","inColumn","KanbanColumn","o"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1 +1 @@
1
- import{r as g,j as p}from"./cmdk-DVxytz9i.js";import{g as x}from"./main-Cxeu4LhG.js";const b=g.forwardRef(function(s,n){const{invalid:t,autoResize:a,disabled:i,rows:l=4,className:d,style:u,onInput:r,...c}=s,v={width:"100%",minHeight:64,padding:"var(--space-3)",fontSize:"var(--fs-13)",lineHeight:"var(--lh-base)",color:"var(--fg)",background:"var(--input-bg)",border:"1px solid",borderColor:t===!0?"var(--danger)":"var(--border)",borderRadius:"var(--radius-sm)",outline:0,resize:a===!0?"none":"vertical",opacity:i===!0?.55:1,fontFamily:"inherit",...u};return p.jsx("textarea",{ref:n,rows:l,disabled:i,"aria-invalid":t===!0?"true":void 0,className:x("v8-textarea",d),style:v,onInput:o=>{if(a===!0){const e=o.currentTarget;e.style.height="auto",e.style.height=`${e.scrollHeight}px`}r==null||r(o)},...c})});export{b as T};
1
+ import{r as g,j as p}from"./cmdk-C3F6LD6N.js";import{g as x}from"./main-BURAlktW.js";const b=g.forwardRef(function(s,n){const{invalid:t,autoResize:a,disabled:i,rows:l=4,className:d,style:u,onInput:r,...c}=s,v={width:"100%",minHeight:64,padding:"var(--space-3)",fontSize:"var(--fs-13)",lineHeight:"var(--lh-base)",color:"var(--fg)",background:"var(--input-bg)",border:"1px solid",borderColor:t===!0?"var(--danger)":"var(--border)",borderRadius:"var(--radius-sm)",outline:0,resize:a===!0?"none":"vertical",opacity:i===!0?.55:1,fontFamily:"inherit",...u};return p.jsx("textarea",{ref:n,rows:l,disabled:i,"aria-invalid":t===!0?"true":void 0,className:x("v8-textarea",d),style:v,onInput:o=>{if(a===!0){const e=o.currentTarget;e.style.height="auto",e.style.height=`${e.scrollHeight}px`}r==null||r(o)},...c})});export{b as T};
@@ -1 +1 @@
1
- {"version":3,"file":"Textarea-QuofpMlq.js","sources":["../../src/web/v8/ui/controls/Textarea.tsx"],"sourcesContent":["import { forwardRef, type TextareaHTMLAttributes } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * Textarea — multi-line input.\n *\n * Use for: descriptions, comments, chat input.\n * Pair with <Field> for label + hint + error.\n */\nexport interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n invalid?: boolean;\n autoResize?: boolean;\n}\n\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(props, ref) {\n const {\n invalid,\n autoResize,\n disabled,\n rows = 4,\n className,\n style,\n onInput,\n ...rest\n } = props;\n\n const computedStyle = {\n width: '100%',\n minHeight: 64,\n padding: 'var(--space-3)',\n fontSize: 'var(--fs-13)',\n lineHeight: 'var(--lh-base)',\n color: 'var(--fg)',\n background: 'var(--input-bg)',\n border: '1px solid',\n borderColor: invalid === true ? 'var(--danger)' : 'var(--border)',\n borderRadius: 'var(--radius-sm)',\n outline: 0,\n resize: autoResize === true ? 'none' : 'vertical',\n opacity: disabled === true ? 0.55 : 1,\n fontFamily: 'inherit',\n ...style,\n } as const;\n\n return (\n <textarea\n ref={ref}\n rows={rows}\n disabled={disabled}\n aria-invalid={invalid === true ? 'true' : undefined}\n className={cx('v8-textarea', className)}\n style={computedStyle}\n onInput={(e) => {\n if (autoResize === true) {\n const el = e.currentTarget;\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n }\n onInput?.(e);\n }}\n {...rest}\n />\n );\n});"],"names":["Textarea","forwardRef","props","ref","invalid","autoResize","disabled","rows","className","style","onInput","rest","computedStyle","jsx","cx","e","el"],"mappings":"qFAcO,MAAMA,EAAWC,EAAAA,WAA+C,SAAkBC,EAAOC,EAAK,CACnG,KAAM,CACJ,QAAAC,EACA,WAAAC,EACA,SAAAC,EACA,KAAAC,EAAO,EACP,UAAAC,EACA,MAAAC,EACA,QAAAC,EACA,GAAGC,CAAA,EACDT,EAEEU,EAAgB,CACpB,MAAO,OACP,UAAW,GACX,QAAS,iBACT,SAAU,eACV,WAAY,iBACZ,MAAO,YACP,WAAY,kBACZ,OAAQ,YACR,YAAaR,IAAY,GAAO,gBAAkB,gBAClD,aAAc,mBACd,QAAS,EACT,OAAQC,IAAe,GAAO,OAAS,WACvC,QAASC,IAAa,GAAO,IAAO,EACpC,WAAY,UACZ,GAAGG,CAAA,EAGL,OACEI,EAAAA,IAAC,WAAA,CACC,IAAAV,EACA,KAAAI,EACA,SAAAD,EACA,eAAcF,IAAY,GAAO,OAAS,OAC1C,UAAWU,EAAG,cAAeN,CAAS,EACtC,MAAOI,EACP,QAAUG,GAAM,CACd,GAAIV,IAAe,GAAM,CACvB,MAAMW,EAAKD,EAAE,cACbC,EAAG,MAAM,OAAS,OAClBA,EAAG,MAAM,OAAS,GAAGA,EAAG,YAAY,IACtC,CACAN,GAAA,MAAAA,EAAUK,EACZ,EACC,GAAGJ,CAAA,CAAA,CAGV,CAAC"}
1
+ {"version":3,"file":"Textarea-xnAybFGd.js","sources":["../../src/web/v8/ui/controls/Textarea.tsx"],"sourcesContent":["import { forwardRef, type TextareaHTMLAttributes } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * Textarea — multi-line input.\n *\n * Use for: descriptions, comments, chat input.\n * Pair with <Field> for label + hint + error.\n */\nexport interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n invalid?: boolean;\n autoResize?: boolean;\n}\n\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(props, ref) {\n const {\n invalid,\n autoResize,\n disabled,\n rows = 4,\n className,\n style,\n onInput,\n ...rest\n } = props;\n\n const computedStyle = {\n width: '100%',\n minHeight: 64,\n padding: 'var(--space-3)',\n fontSize: 'var(--fs-13)',\n lineHeight: 'var(--lh-base)',\n color: 'var(--fg)',\n background: 'var(--input-bg)',\n border: '1px solid',\n borderColor: invalid === true ? 'var(--danger)' : 'var(--border)',\n borderRadius: 'var(--radius-sm)',\n outline: 0,\n resize: autoResize === true ? 'none' : 'vertical',\n opacity: disabled === true ? 0.55 : 1,\n fontFamily: 'inherit',\n ...style,\n } as const;\n\n return (\n <textarea\n ref={ref}\n rows={rows}\n disabled={disabled}\n aria-invalid={invalid === true ? 'true' : undefined}\n className={cx('v8-textarea', className)}\n style={computedStyle}\n onInput={(e) => {\n if (autoResize === true) {\n const el = e.currentTarget;\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n }\n onInput?.(e);\n }}\n {...rest}\n />\n );\n});"],"names":["Textarea","forwardRef","props","ref","invalid","autoResize","disabled","rows","className","style","onInput","rest","computedStyle","jsx","cx","e","el"],"mappings":"qFAcO,MAAMA,EAAWC,EAAAA,WAA+C,SAAkBC,EAAOC,EAAK,CACnG,KAAM,CACJ,QAAAC,EACA,WAAAC,EACA,SAAAC,EACA,KAAAC,EAAO,EACP,UAAAC,EACA,MAAAC,EACA,QAAAC,EACA,GAAGC,CAAA,EACDT,EAEEU,EAAgB,CACpB,MAAO,OACP,UAAW,GACX,QAAS,iBACT,SAAU,eACV,WAAY,iBACZ,MAAO,YACP,WAAY,kBACZ,OAAQ,YACR,YAAaR,IAAY,GAAO,gBAAkB,gBAClD,aAAc,mBACd,QAAS,EACT,OAAQC,IAAe,GAAO,OAAS,WACvC,QAASC,IAAa,GAAO,IAAO,EACpC,WAAY,UACZ,GAAGG,CAAA,EAGL,OACEI,EAAAA,IAAC,WAAA,CACC,IAAAV,EACA,KAAAI,EACA,SAAAD,EACA,eAAcF,IAAY,GAAO,OAAS,OAC1C,UAAWU,EAAG,cAAeN,CAAS,EACtC,MAAOI,EACP,QAAUG,GAAM,CACd,GAAIV,IAAe,GAAM,CACvB,MAAMW,EAAKD,EAAE,cACbC,EAAG,MAAM,OAAS,OAClBA,EAAG,MAAM,OAAS,GAAGA,EAAG,YAAY,IACtC,CACAN,GAAA,MAAAA,EAAUK,EACZ,EACC,GAAGJ,CAAA,CAAA,CAGV,CAAC"}
@@ -0,0 +1 @@
1
+ import{r,j as e}from"./cmdk-C3F6LD6N.js";import{u as F,a as g,S as c,I as t,B as i,Z as w,h as f,J as L,i as A,F as U}from"./main-BURAlktW.js";import{V as T}from"./ViewHeader-C-t1U2cQ.js";import{C as x,b as j}from"./Card-BtsmkhJa.js";import{E as V}from"./EmptyState-DjKtY1Qi.js";import{R as $}from"./refresh-ccw-DA8_IB9l.js";import{D}from"./download-BvJddD8D.js";import{C as I}from"./circle-check-DFB50ojt.js";import{C as H}from"./circle-alert-Dz8lGfCZ.js";function Q(){const l=F("/api/updates/status"),[n,E]=r.useState(null),[m,v]=r.useState(!1),[y,h]=r.useState(!1),[C,d]=r.useState(null),[k,u]=r.useState([]),[S,p]=r.useState(null),R=r.useMemo(()=>{var a;return((a=l.data)==null?void 0:a.packages)??[]},[l.data]),b=r.useCallback(()=>{l.refetch()},[l]);g("update:progress",a=>{u(s=>[...s,{...a,type:"update:progress"}])}),g("update:log",a=>{u(s=>[...s,{...a,type:"update:log"}])}),g("update:complete",a=>{u(s=>[...s,{...a,type:"update:complete"}]),h(!1),b()});const B=async()=>{v(!0),p(null);try{const a=await A("/api/updates/check");E(a)}catch(a){p((a instanceof U,a.message))}finally{v(!1)}},z=async a=>{h(!0),p(null),d(null);try{await A("/api/updates/apply",{method:"POST",body:{packages:a}})}catch(s){p((s instanceof U,s.message)),h(!1)}},o=(n==null?void 0:n.packages)??R.map(a=>({...a,hasUpdate:!1}));return e.jsxs(c,{gap:4,"data-testid":"update-view",children:[e.jsx(T,{title:"Update",description:"Bizar package updates. Apply restarts on next launch.",actions:e.jsxs(t,{align:"center",gap:2,children:[S!==null&&e.jsx("span",{role:"alert","data-testid":"update-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:S}),e.jsxs(i,{variant:"ghost",onClick:()=>void b(),"data-testid":"update-refresh",children:[e.jsx($,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(i,{variant:"ghost",onClick:()=>void B(),disabled:m,"data-testid":"update-check",children:[e.jsx(D,{size:14,"aria-hidden":!0})," ",m?"Checking…":"Check"]}),e.jsxs(i,{variant:"primary",onClick:()=>d("all"),disabled:y||!((n==null?void 0:n.hasUpdates)??!1),"data-testid":"update-apply-all",children:[e.jsx(w,{size:14,"aria-hidden":!0})," Apply all"]})]})}),e.jsx(x,{variant:"default",children:e.jsx(j,{children:l.loading&&o.length===0?e.jsxs(c,{gap:1,children:[e.jsx(f,{style:{height:40}}),e.jsx(f,{style:{height:40}}),e.jsx(f,{style:{height:40}})]}):o.length===0?e.jsx(V,{icon:e.jsx(w,{size:28,"aria-hidden":!0}),title:"No packages",description:"Update status endpoint returned no packages."}):e.jsx(c,{gap:1,children:o.map(a=>{const s=C===a.id;return e.jsxs("div",{"data-testid":`update-row-${a.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",background:"var(--surface-0)"},children:[e.jsxs(t,{align:"center",justify:"between",gap:2,children:[e.jsxs(c,{gap:0,children:[e.jsxs(t,{align:"center",gap:2,children:[e.jsx("strong",{children:a.label||a.id}),e.jsx("code",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:a.id})]}),e.jsxs(t,{align:"center",gap:2,children:[e.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:["installed: ",e.jsx("code",{children:a.installed??"?"})]}),a.latest!==void 0&&a.latest!==null&&e.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:["latest: ",e.jsx("code",{children:a.latest})]}),a.hasUpdate&&e.jsx("span",{"data-testid":`update-available-${a.id}`,style:{fontSize:"var(--fs-11)",color:"var(--accent)",fontWeight:600},children:"UPDATE AVAILABLE"})]})]}),e.jsx(t,{gap:1,children:a.hasUpdate&&e.jsx(i,{variant:"ghost",onClick:()=>d(P=>P===a.id?null:a.id),"data-testid":`update-apply-${a.id}`,disabled:y,children:"Apply"})})]}),s&&e.jsxs(t,{gap:1,style:{marginTop:"var(--space-1)"},children:[e.jsx(i,{variant:"primary",onClick:()=>void z([a.id]),"data-testid":`update-confirm-apply-${a.id}`,children:"Confirm apply"}),e.jsx(i,{variant:"ghost",onClick:()=>d(null),children:"Cancel"})]})]},a.id)})})})}),C==="all"&&e.jsx(x,{variant:"default",children:e.jsx(j,{children:e.jsxs(c,{gap:2,children:[e.jsx("strong",{children:"Apply all updates?"}),e.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:[o.filter(a=>a.hasUpdate).length," package(s) will update on next launch."]}),e.jsxs(t,{gap:1,children:[e.jsx(i,{variant:"primary",onClick:()=>void z(o.filter(a=>a.hasUpdate).map(a=>a.id)),"data-testid":"update-confirm-apply-all",children:"Confirm apply all"}),e.jsx(i,{variant:"ghost",onClick:()=>d(null),children:"Cancel"})]})]})})}),k.length>0&&e.jsx(x,{variant:"default",children:e.jsxs(j,{children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Progress"}),e.jsx("div",{"data-testid":"update-log",style:{marginTop:"var(--space-2)",padding:"var(--space-2)",background:"var(--surface-1)",borderRadius:"var(--radius-sm)",fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",maxHeight:240,overflow:"auto"},children:k.slice(-100).map((a,s)=>e.jsx("div",{style:{color:a.error?"var(--danger)":a.status==="done"?"var(--success)":"var(--fg)"},children:a.type==="update:complete"?e.jsxs(t,{align:"center",gap:1,children:[e.jsx(I,{size:12,"aria-hidden":!0,style:{color:"var(--success)"}})," complete"]}):a.error?e.jsxs(t,{align:"center",gap:1,children:[e.jsx(H,{size:12,"aria-hidden":!0,style:{color:"var(--danger)"}})," ",a.pkg??"?"," · ",a.error]}):e.jsxs(t,{align:"center",gap:1,children:[a.status==="installing"?e.jsx(L,{size:12,"aria-hidden":!0,style:{animation:"spin 1s linear infinite"}}):null,a.pkg??"?"," · ",a.status??a.line??""]})},s))})]})})]})}export{Q as UpdateView};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpdateView-BUAEcRCX.js","sources":["../../src/web/v8/views/Update/UpdateView.tsx"],"sourcesContent":["/**\n * v8/views/Update/UpdateView.tsx — Sprint S42, v9.3.0.\n *\n * Package update status + Check + Apply:\n * - GET /api/updates/status — installed versions\n * - GET /api/updates/check — installed + latest + hasUpdates\n * - POST /api/updates/apply — kick install, streams via\n * `update:progress` / `update:log` / `update:complete` WS events.\n *\n * Per-package Apply (inline-confirm) + global Apply All button. Live\n * progress list rendered from a useWsMessage subscription.\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Package, RefreshCcw, Download, CheckCircle2, AlertCircle, Loader2 } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\ninterface UpdateEntry {\n id: string;\n installed?: string;\n latest?: string | null;\n hasUpdate?: boolean;\n label?: string;\n}\n\ninterface StatusResponse {\n packages: UpdateEntry[];\n}\n\ninterface CheckResponse {\n packages: UpdateEntry[];\n hasUpdates?: boolean;\n}\n\ninterface ProgressEvent {\n type: 'update:progress' | 'update:log' | 'update:complete';\n pkg?: string;\n status?: string;\n line?: string;\n newVersion?: string;\n error?: string;\n}\n\nexport function UpdateView(): JSX.Element {\n const statusPayload = useFetch<StatusResponse>('/api/updates/status');\n const [check, setCheck] = useState<CheckResponse | null>(null);\n const [checking, setChecking] = useState<boolean>(false);\n const [applying, setApplying] = useState<boolean>(false);\n const [confirmApply, setConfirmApply] = useState<string | null>(null);\n const [log, setLog] = useState<ProgressEvent[]>([]);\n const [error, setError] = useState<string | null>(null);\n\n const installed = useMemo<UpdateEntry[]>(() => statusPayload.data?.packages ?? [], [statusPayload.data]);\n const refresh = useCallback(() => { void statusPayload.refetch(); }, [statusPayload]);\n\n // Subscribe to live progress events. `msg.type` is the discriminator\n // (e.g. 'update:progress'); spreading first then narrowing via the\n // cast avoids the TS2783 duplicate-key error we'd hit if we tried to\n // also set `type: 'update:progress'` literally.\n useWsMessage('update:progress', (msg) => {\n setLog((l) => [...l, { ...msg, type: 'update:progress' } as ProgressEvent]);\n });\n useWsMessage('update:log', (msg) => {\n setLog((l) => [...l, { ...msg, type: 'update:log' } as ProgressEvent]);\n });\n useWsMessage('update:complete', (msg) => {\n setLog((l) => [...l, { ...msg, type: 'update:complete' } as ProgressEvent]);\n setApplying(false);\n refresh();\n });\n\n const runCheck = async (): Promise<void> => {\n setChecking(true);\n setError(null);\n try {\n const r = await fetchJson<CheckResponse>('/api/updates/check');\n setCheck(r);\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setChecking(false);\n }\n };\n\n const apply = async (ids: string[]): Promise<void> => {\n setApplying(true);\n setError(null);\n setConfirmApply(null);\n try {\n await fetchJson('/api/updates/apply', { method: 'POST', body: { packages: ids } });\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n setApplying(false);\n }\n };\n\n const rows: UpdateEntry[] = check?.packages ?? installed.map((p) => ({ ...p, hasUpdate: false }));\n\n return (\n <Stack gap={4} data-testid=\"update-view\">\n <ViewHeader\n title=\"Update\"\n description=\"Bizar package updates. Apply restarts on next launch.\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"update-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"update-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"ghost\" onClick={() => void runCheck()} disabled={checking} data-testid=\"update-check\">\n <Download size={14} aria-hidden /> {checking ? 'Checking…' : 'Check'}\n </Button>\n <Button\n variant=\"primary\"\n onClick={() => setConfirmApply('all')}\n disabled={applying || !(check?.hasUpdates ?? false)}\n data-testid=\"update-apply-all\"\n >\n <Package size={14} aria-hidden /> Apply all\n </Button>\n </Inline>\n }\n />\n\n <Card variant=\"default\">\n <CardBody>\n {statusPayload.loading && rows.length === 0 ? (\n <Stack gap={1}>\n <Skeleton style={{ height: 40 }} />\n <Skeleton style={{ height: 40 }} />\n <Skeleton style={{ height: 40 }} />\n </Stack>\n ) : rows.length === 0 ? (\n <EmptyState icon={<Package size={28} aria-hidden />} title=\"No packages\" description=\"Update status endpoint returned no packages.\" />\n ) : (\n <Stack gap={1}>\n {rows.map((p) => {\n const isConfirming = confirmApply === p.id;\n return (\n <div\n key={p.id}\n data-testid={`update-row-${p.id}`}\n style={{\n padding: 'var(--space-2)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: 'var(--surface-0)',\n }}\n >\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Stack gap={0}>\n <Inline align=\"center\" gap={2}>\n <strong>{p.label || p.id}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{p.id}</code>\n </Inline>\n <Inline align=\"center\" gap={2}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n installed: <code>{p.installed ?? '?'}</code>\n </span>\n {p.latest !== undefined && p.latest !== null && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n latest: <code>{p.latest}</code>\n </span>\n )}\n {p.hasUpdate && (\n <span data-testid={`update-available-${p.id}`} style={{ fontSize: 'var(--fs-11)', color: 'var(--accent)', fontWeight: 600 }}>\n UPDATE AVAILABLE\n </span>\n )}\n </Inline>\n </Stack>\n <Inline gap={1}>\n {p.hasUpdate && (\n <Button\n variant=\"ghost\"\n onClick={() => setConfirmApply((cur) => (cur === p.id ? null : p.id))}\n data-testid={`update-apply-${p.id}`}\n disabled={applying}\n >\n Apply\n </Button>\n )}\n </Inline>\n </Inline>\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"primary\" onClick={() => void apply([p.id])} data-testid={`update-confirm-apply-${p.id}`}>\n Confirm apply\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmApply(null)}>Cancel</Button>\n </Inline>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </CardBody>\n </Card>\n\n {confirmApply === 'all' && (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <strong>Apply all updates?</strong>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {rows.filter((p) => p.hasUpdate).length} package(s) will update on next launch.\n </span>\n <Inline gap={1}>\n <Button variant=\"primary\" onClick={() => void apply(rows.filter((p) => p.hasUpdate).map((p) => p.id))} data-testid=\"update-confirm-apply-all\">\n Confirm apply all\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmApply(null)}>Cancel</Button>\n </Inline>\n </Stack>\n </CardBody>\n </Card>\n )}\n\n {log.length > 0 && (\n <Card variant=\"default\">\n <CardBody>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Progress</strong>\n <div\n data-testid=\"update-log\"\n style={{\n marginTop: 'var(--space-2)',\n padding: 'var(--space-2)',\n background: 'var(--surface-1)',\n borderRadius: 'var(--radius-sm)',\n fontFamily: 'var(--font-mono)',\n fontSize: 'var(--fs-12)',\n maxHeight: 240,\n overflow: 'auto',\n }}\n >\n {log.slice(-100).map((l, i) => (\n <div key={i} style={{ color: l.error ? 'var(--danger)' : l.status === 'done' ? 'var(--success)' : 'var(--fg)' }}>\n {l.type === 'update:complete' ? (\n <Inline align=\"center\" gap={1}><CheckCircle2 size={12} aria-hidden style={{ color: 'var(--success)' }} /> complete</Inline>\n ) : l.error ? (\n <Inline align=\"center\" gap={1}><AlertCircle size={12} aria-hidden style={{ color: 'var(--danger)' }} /> {l.pkg ?? '?'} · {l.error}</Inline>\n ) : (\n <Inline align=\"center\" gap={1}>\n {l.status === 'installing' ? <Loader2 size={12} aria-hidden style={{ animation: 'spin 1s linear infinite' }} /> : null}\n {l.pkg ?? '?'} · {l.status ?? l.line ?? ''}\n </Inline>\n )}\n </div>\n ))}\n </div>\n </CardBody>\n </Card>\n )}\n </Stack>\n );\n}"],"names":["UpdateView","statusPayload","useFetch","check","setCheck","useState","checking","setChecking","applying","setApplying","confirmApply","setConfirmApply","log","setLog","error","setError","installed","useMemo","_a","refresh","useCallback","useWsMessage","msg","l","runCheck","r","fetchJson","err","FetchError","apply","ids","rows","p","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCcw","Download","Package","Card","CardBody","Skeleton","EmptyState","isConfirming","cur","i","CheckCircle2","AlertCircle","Loader2"],"mappings":"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"}
@@ -1 +1 @@
1
- import{r as b,j as e}from"./cmdk-DVxytz9i.js";import{u as k,S as a,I as l,K as z,h as C}from"./main-Cxeu4LhG.js";import{G as T}from"./Grid-BSXhsCPC.js";import{V as w}from"./ViewHeader-B6P-C4GD.js";import{C as g,b as h}from"./Card-rF59wHiO.js";import{E as F}from"./ErrorState-DULZnttJ.js";import{T as I}from"./trending-up-CRPNagyX.js";import{Z as R}from"./zap-5lAQBAPX.js";import{C as q}from"./clock-DEIuPV60.js";import"./Alert-B6DjfRFI.js";import"./circle-alert-HdHe7m8K.js";import"./triangle-alert-tUTXbcEP.js";import"./circle-check-Cs-xoV7R.js";import"./refresh-ccw-DenGBOcq.js";const E=[{id:"24h",label:"24 hours"},{id:"7d",label:"7 days"},{id:"30d",label:"30 days"}];function u(s){return s<1e3?String(s):s<1e6?`${(s/1e3).toFixed(1)}k`:`${(s/1e6).toFixed(2)}M`}function f({label:s,value:d,sub:t,icon:n}){return e.jsx(g,{variant:"default",children:e.jsx(h,{children:e.jsxs(a,{gap:1,children:[e.jsxs(l,{align:"center",gap:2,children:[e.jsx(n,{size:14,"aria-hidden":!0}),e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:s})]}),e.jsx("strong",{style:{fontSize:"var(--fs-18)",fontFamily:"var(--font-mono)"},children:d}),t&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:t})]})})})}function J(){var p,x,v,j,y;const[s,d]=b.useState("24h"),t=k(`/api/usage?range=${s}`),n=k("/api/usage/limits");b.useEffect(()=>{},[s]);const i=(p=t.data)==null?void 0:p.totals,o=((x=t.data)==null?void 0:x.byProvider)??[],m=((v=t.data)==null?void 0:v.byModel)??[],c=o.reduce((r,S)=>Math.max(r,S.tokens),0);return e.jsxs(a,{gap:5,"data-testid":"usage-view",children:[e.jsx(w,{title:"Usage",description:"Token consumption + quota limits from the rolling JSONL log.",actions:e.jsx(l,{gap:1,children:E.map(r=>e.jsx("button",{type:"button",onClick:()=>d(r.id),"aria-pressed":s===r.id,"data-testid":`usage-range-${r.id}`,style:{padding:"4px 10px",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",background:s===r.id?"var(--accent)":"var(--surface-1)",color:s===r.id?"var(--accent-fg)":"var(--fg)",fontSize:"var(--fs-12)",cursor:"pointer"},children:r.label},r.id))})}),e.jsxs(T,{cols:3,children:[e.jsx(f,{label:"Total tokens",icon:z,value:t.loading?"…":u((i==null?void 0:i.tokens)??0),sub:i?`${i.requests} requests`:""}),e.jsx(f,{label:"Distinct providers",icon:I,value:t.loading?"…":String(o.length)}),e.jsx(f,{label:"Live limits",icon:R,value:n.loading?"…":String(((y=(j=n.data)==null?void 0:j.models)==null?void 0:y.length)??0),sub:"active quotas"})]}),t.loading?e.jsx(C,{style:{height:200}}):t.error&&o.length===0?e.jsx(F,{block:!0,title:"Couldn't load usage",description:"Token analytics failed to fetch. Retry to refetch.",error:t.error,onRetry:()=>void t.refetch(),testid:"usage-error"}):o.length===0?e.jsx(g,{variant:"default",children:e.jsx(h,{children:e.jsxs(a,{gap:1,align:"center",style:{padding:"var(--space-4)"},children:[e.jsx(q,{size:24,"aria-hidden":!0}),e.jsxs("span",{style:{color:"var(--fg-muted)"},children:["No usage records for the last ",s,"."]})]})})}):e.jsx(g,{variant:"default",children:e.jsx(h,{children:e.jsxs(a,{gap:3,children:[e.jsx("strong",{children:"By provider"}),e.jsx(a,{gap:2,children:o.map(r=>e.jsxs(a,{gap:1,children:[e.jsxs(l,{align:"center",justify:"between",children:[e.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)"},children:r.providerId}),e.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:[u(r.tokens)," · ",r.requests," req"]})]}),e.jsx("div",{role:"progressbar","aria-valuemin":0,"aria-valuemax":c||1,"aria-valuenow":r.tokens,style:{height:6,background:"var(--surface-1)",borderRadius:"var(--radius-pill)",overflow:"hidden"},children:e.jsx("div",{style:{width:`${c>0?r.tokens/c*100:0}%`,height:"100%",background:"var(--accent)"}})})]},r.providerId))}),m.length>0&&e.jsxs(a,{gap:2,children:[e.jsx("strong",{children:"Top models"}),m.slice(0,5).map(r=>e.jsxs(l,{align:"center",justify:"between",style:{fontSize:"var(--fs-12)"},children:[e.jsx("code",{style:{fontFamily:"var(--font-mono)"},children:r.modelId}),e.jsx("span",{style:{color:"var(--fg-muted)"},children:u(r.tokens)})]},r.modelId))]})]})})})]})}export{J as UsageView};
1
+ import{r as b,j as e}from"./cmdk-C3F6LD6N.js";import{u as k,S as a,I as l,K as z,h as C}from"./main-BURAlktW.js";import{G as T}from"./Grid--WKvqu5h.js";import{V as w}from"./ViewHeader-C-t1U2cQ.js";import{C as g,b as h}from"./Card-BtsmkhJa.js";import{E as F}from"./ErrorState-CBJbEQ8B.js";import{T as I}from"./trending-up-BZzo_1ic.js";import{Z as R}from"./zap-DENVhJnO.js";import{C as q}from"./clock-ClVA6-hQ.js";import"./Alert-BZGk39mB.js";import"./circle-alert-Dz8lGfCZ.js";import"./triangle-alert-B2oHbmoh.js";import"./circle-check-DFB50ojt.js";import"./refresh-ccw-DA8_IB9l.js";const E=[{id:"24h",label:"24 hours"},{id:"7d",label:"7 days"},{id:"30d",label:"30 days"}];function u(s){return s<1e3?String(s):s<1e6?`${(s/1e3).toFixed(1)}k`:`${(s/1e6).toFixed(2)}M`}function f({label:s,value:d,sub:t,icon:n}){return e.jsx(g,{variant:"default",children:e.jsx(h,{children:e.jsxs(a,{gap:1,children:[e.jsxs(l,{align:"center",gap:2,children:[e.jsx(n,{size:14,"aria-hidden":!0}),e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:s})]}),e.jsx("strong",{style:{fontSize:"var(--fs-18)",fontFamily:"var(--font-mono)"},children:d}),t&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:t})]})})})}function J(){var p,x,v,j,y;const[s,d]=b.useState("24h"),t=k(`/api/usage?range=${s}`),n=k("/api/usage/limits");b.useEffect(()=>{},[s]);const i=(p=t.data)==null?void 0:p.totals,o=((x=t.data)==null?void 0:x.byProvider)??[],m=((v=t.data)==null?void 0:v.byModel)??[],c=o.reduce((r,S)=>Math.max(r,S.tokens),0);return e.jsxs(a,{gap:5,"data-testid":"usage-view",children:[e.jsx(w,{title:"Usage",description:"Token consumption + quota limits from the rolling JSONL log.",actions:e.jsx(l,{gap:1,children:E.map(r=>e.jsx("button",{type:"button",onClick:()=>d(r.id),"aria-pressed":s===r.id,"data-testid":`usage-range-${r.id}`,style:{padding:"4px 10px",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",background:s===r.id?"var(--accent)":"var(--surface-1)",color:s===r.id?"var(--accent-fg)":"var(--fg)",fontSize:"var(--fs-12)",cursor:"pointer"},children:r.label},r.id))})}),e.jsxs(T,{cols:3,children:[e.jsx(f,{label:"Total tokens",icon:z,value:t.loading?"…":u((i==null?void 0:i.tokens)??0),sub:i?`${i.requests} requests`:""}),e.jsx(f,{label:"Distinct providers",icon:I,value:t.loading?"…":String(o.length)}),e.jsx(f,{label:"Live limits",icon:R,value:n.loading?"…":String(((y=(j=n.data)==null?void 0:j.models)==null?void 0:y.length)??0),sub:"active quotas"})]}),t.loading?e.jsx(C,{style:{height:200}}):t.error&&o.length===0?e.jsx(F,{block:!0,title:"Couldn't load usage",description:"Token analytics failed to fetch. Retry to refetch.",error:t.error,onRetry:()=>void t.refetch(),testid:"usage-error"}):o.length===0?e.jsx(g,{variant:"default",children:e.jsx(h,{children:e.jsxs(a,{gap:1,align:"center",style:{padding:"var(--space-4)"},children:[e.jsx(q,{size:24,"aria-hidden":!0}),e.jsxs("span",{style:{color:"var(--fg-muted)"},children:["No usage records for the last ",s,"."]})]})})}):e.jsx(g,{variant:"default",children:e.jsx(h,{children:e.jsxs(a,{gap:3,children:[e.jsx("strong",{children:"By provider"}),e.jsx(a,{gap:2,children:o.map(r=>e.jsxs(a,{gap:1,children:[e.jsxs(l,{align:"center",justify:"between",children:[e.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)"},children:r.providerId}),e.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:[u(r.tokens)," · ",r.requests," req"]})]}),e.jsx("div",{role:"progressbar","aria-valuemin":0,"aria-valuemax":c||1,"aria-valuenow":r.tokens,style:{height:6,background:"var(--surface-1)",borderRadius:"var(--radius-pill)",overflow:"hidden"},children:e.jsx("div",{style:{width:`${c>0?r.tokens/c*100:0}%`,height:"100%",background:"var(--accent)"}})})]},r.providerId))}),m.length>0&&e.jsxs(a,{gap:2,children:[e.jsx("strong",{children:"Top models"}),m.slice(0,5).map(r=>e.jsxs(l,{align:"center",justify:"between",style:{fontSize:"var(--fs-12)"},children:[e.jsx("code",{style:{fontFamily:"var(--font-mono)"},children:r.modelId}),e.jsx("span",{style:{color:"var(--fg-muted)"},children:u(r.tokens)})]},r.modelId))]})]})})})]})}export{J as UsageView};
@@ -1 +1 @@
1
- {"version":3,"file":"UsageView-BqOw6FBg.js","sources":["../../src/web/v8/views/Usage/UsageView.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { BarChart3, TrendingUp, Clock, Zap } 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 { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { useFetch } from '../../data/useFetch.js';\n\n/**\n * UsageView — Sprint S35. Token usage analytics from JSONL logs.\n */\n\ntype Range = '24h' | '7d' | '30d';\n\ninterface UsageTotals {\n tokens: number;\n cost?: number;\n requests: number;\n}\n\ninterface UsageByProvider {\n providerId: string;\n tokens: number;\n requests: number;\n}\n\ninterface UsageResponse {\n totals: UsageTotals;\n byProvider?: UsageByProvider[];\n byModel?: Array<{ modelId: string; tokens: number; requests: number }>;\n series?: Array<{ ts: number; tokens: number }>;\n}\n\ninterface LimitEntry {\n providerId?: string;\n modelId?: string;\n remaining?: number;\n limit?: number;\n}\n\ninterface LimitsResponse {\n models: LimitEntry[];\n}\n\nconst RANGE_OPTIONS: Array<{ id: Range; label: string }> = [\n { id: '24h', label: '24 hours' },\n { id: '7d', label: '7 days' },\n { id: '30d', label: '30 days' },\n];\n\nfunction fmtTokens(n: number): string {\n if (n < 1000) return String(n);\n if (n < 1_000_000) return `${(n / 1000).toFixed(1)}k`;\n return `${(n / 1_000_000).toFixed(2)}M`;\n}\n\nfunction StatTile({ label, value, sub, icon: Icon }: { label: string; value: string; sub?: string; icon: typeof BarChart3 }): JSX.Element {\n return (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <Inline align=\"center\" gap={2}>\n <Icon size={14} aria-hidden />\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{label}</span>\n </Inline>\n <strong style={{ fontSize: 'var(--fs-18)', fontFamily: 'var(--font-mono)' }}>{value}</strong>\n {sub && <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{sub}</span>}\n </Stack>\n </CardBody>\n </Card>\n );\n}\n\nexport function UsageView(): JSX.Element {\n const [range, setRange] = useState<Range>('24h');\n const res = useFetch<UsageResponse>(`/api/usage?range=${range}`);\n const limits = useFetch<LimitsResponse>('/api/usage/limits');\n\n useEffect(() => {\n // refetch on range change is implicit (useFetch re-keys on URL change).\n }, [range]);\n\n const totals = res.data?.totals;\n const byProvider = res.data?.byProvider ?? [];\n const byModel = res.data?.byModel ?? [];\n const maxProvider = byProvider.reduce((m, p) => Math.max(m, p.tokens), 0);\n\n return (\n <Stack gap={5} data-testid=\"usage-view\">\n <ViewHeader\n title=\"Usage\"\n description=\"Token consumption + quota limits from the rolling JSONL log.\"\n actions={\n <Inline gap={1}>\n {RANGE_OPTIONS.map((r) => (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => setRange(r.id)}\n aria-pressed={range === r.id}\n data-testid={`usage-range-${r.id}`}\n style={{\n padding: '4px 10px',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: range === r.id ? 'var(--accent)' : 'var(--surface-1)',\n color: range === r.id ? 'var(--accent-fg)' : 'var(--fg)',\n fontSize: 'var(--fs-12)',\n cursor: 'pointer',\n }}\n >\n {r.label}\n </button>\n ))}\n </Inline>\n }\n />\n\n <Grid cols={3}>\n <StatTile\n label=\"Total tokens\"\n icon={BarChart3}\n value={res.loading ? '…' : fmtTokens(totals?.tokens ?? 0)}\n sub={totals ? `${totals.requests} requests` : ''}\n />\n <StatTile\n label=\"Distinct providers\"\n icon={TrendingUp}\n value={res.loading ? '…' : String(byProvider.length)}\n />\n <StatTile\n label=\"Live limits\"\n icon={Zap}\n value={limits.loading ? '…' : String(limits.data?.models?.length ?? 0)}\n sub=\"active quotas\"\n />\n </Grid>\n\n {res.loading ? (\n <Skeleton style={{ height: 200 }} />\n ) : res.error && byProvider.length === 0 ? (\n <ErrorState\n block\n title=\"Couldn't load usage\"\n description=\"Token analytics failed to fetch. Retry to refetch.\"\n error={res.error}\n onRetry={() => void res.refetch()}\n testid=\"usage-error\"\n />\n ) : byProvider.length === 0 ? (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1} align=\"center\" style={{ padding: 'var(--space-4)' }}>\n <Clock size={24} aria-hidden />\n <span style={{ color: 'var(--fg-muted)' }}>No usage records for the last {range}.</span>\n </Stack>\n </CardBody>\n </Card>\n ) : (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={3}>\n <strong>By provider</strong>\n <Stack gap={2}>\n {byProvider.map((p) => (\n <Stack key={p.providerId} gap={1}>\n <Inline align=\"center\" justify=\"between\">\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)' }}>{p.providerId}</span>\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {fmtTokens(p.tokens)} · {p.requests} req\n </span>\n </Inline>\n <div\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={maxProvider || 1}\n aria-valuenow={p.tokens}\n style={{\n height: 6,\n background: 'var(--surface-1)',\n borderRadius: 'var(--radius-pill)',\n overflow: 'hidden',\n }}\n >\n <div style={{ width: `${maxProvider > 0 ? (p.tokens / maxProvider) * 100 : 0}%`, height: '100%', background: 'var(--accent)' }} />\n </div>\n </Stack>\n ))}\n </Stack>\n {byModel.length > 0 && (\n <Stack gap={2}>\n <strong>Top models</strong>\n {byModel.slice(0, 5).map((m) => (\n <Inline key={m.modelId} align=\"center\" justify=\"between\" style={{ fontSize: 'var(--fs-12)' }}>\n <code style={{ fontFamily: 'var(--font-mono)' }}>{m.modelId}</code>\n <span style={{ color: 'var(--fg-muted)' }}>{fmtTokens(m.tokens)}</span>\n </Inline>\n ))}\n </Stack>\n )}\n </Stack>\n </CardBody>\n </Card>\n )}\n </Stack>\n );\n}"],"names":["RANGE_OPTIONS","fmtTokens","n","StatTile","label","value","sub","Icon","jsx","Card","CardBody","jsxs","Stack","Inline","UsageView","range","setRange","useState","res","useFetch","limits","useEffect","totals","_a","byProvider","_b","byModel","_c","maxProvider","m","p","ViewHeader","Grid","BarChart3","TrendingUp","Zap","_e","_d","Skeleton","ErrorState","Clock"],"mappings":"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"}
1
+ {"version":3,"file":"UsageView-DMFbBOfH.js","sources":["../../src/web/v8/views/Usage/UsageView.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { BarChart3, TrendingUp, Clock, Zap } 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 { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { useFetch } from '../../data/useFetch.js';\n\n/**\n * UsageView — Sprint S35. Token usage analytics from JSONL logs.\n */\n\ntype Range = '24h' | '7d' | '30d';\n\ninterface UsageTotals {\n tokens: number;\n cost?: number;\n requests: number;\n}\n\ninterface UsageByProvider {\n providerId: string;\n tokens: number;\n requests: number;\n}\n\ninterface UsageResponse {\n totals: UsageTotals;\n byProvider?: UsageByProvider[];\n byModel?: Array<{ modelId: string; tokens: number; requests: number }>;\n series?: Array<{ ts: number; tokens: number }>;\n}\n\ninterface LimitEntry {\n providerId?: string;\n modelId?: string;\n remaining?: number;\n limit?: number;\n}\n\ninterface LimitsResponse {\n models: LimitEntry[];\n}\n\nconst RANGE_OPTIONS: Array<{ id: Range; label: string }> = [\n { id: '24h', label: '24 hours' },\n { id: '7d', label: '7 days' },\n { id: '30d', label: '30 days' },\n];\n\nfunction fmtTokens(n: number): string {\n if (n < 1000) return String(n);\n if (n < 1_000_000) return `${(n / 1000).toFixed(1)}k`;\n return `${(n / 1_000_000).toFixed(2)}M`;\n}\n\nfunction StatTile({ label, value, sub, icon: Icon }: { label: string; value: string; sub?: string; icon: typeof BarChart3 }): JSX.Element {\n return (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <Inline align=\"center\" gap={2}>\n <Icon size={14} aria-hidden />\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{label}</span>\n </Inline>\n <strong style={{ fontSize: 'var(--fs-18)', fontFamily: 'var(--font-mono)' }}>{value}</strong>\n {sub && <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{sub}</span>}\n </Stack>\n </CardBody>\n </Card>\n );\n}\n\nexport function UsageView(): JSX.Element {\n const [range, setRange] = useState<Range>('24h');\n const res = useFetch<UsageResponse>(`/api/usage?range=${range}`);\n const limits = useFetch<LimitsResponse>('/api/usage/limits');\n\n useEffect(() => {\n // refetch on range change is implicit (useFetch re-keys on URL change).\n }, [range]);\n\n const totals = res.data?.totals;\n const byProvider = res.data?.byProvider ?? [];\n const byModel = res.data?.byModel ?? [];\n const maxProvider = byProvider.reduce((m, p) => Math.max(m, p.tokens), 0);\n\n return (\n <Stack gap={5} data-testid=\"usage-view\">\n <ViewHeader\n title=\"Usage\"\n description=\"Token consumption + quota limits from the rolling JSONL log.\"\n actions={\n <Inline gap={1}>\n {RANGE_OPTIONS.map((r) => (\n <button\n key={r.id}\n type=\"button\"\n onClick={() => setRange(r.id)}\n aria-pressed={range === r.id}\n data-testid={`usage-range-${r.id}`}\n style={{\n padding: '4px 10px',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n background: range === r.id ? 'var(--accent)' : 'var(--surface-1)',\n color: range === r.id ? 'var(--accent-fg)' : 'var(--fg)',\n fontSize: 'var(--fs-12)',\n cursor: 'pointer',\n }}\n >\n {r.label}\n </button>\n ))}\n </Inline>\n }\n />\n\n <Grid cols={3}>\n <StatTile\n label=\"Total tokens\"\n icon={BarChart3}\n value={res.loading ? '…' : fmtTokens(totals?.tokens ?? 0)}\n sub={totals ? `${totals.requests} requests` : ''}\n />\n <StatTile\n label=\"Distinct providers\"\n icon={TrendingUp}\n value={res.loading ? '…' : String(byProvider.length)}\n />\n <StatTile\n label=\"Live limits\"\n icon={Zap}\n value={limits.loading ? '…' : String(limits.data?.models?.length ?? 0)}\n sub=\"active quotas\"\n />\n </Grid>\n\n {res.loading ? (\n <Skeleton style={{ height: 200 }} />\n ) : res.error && byProvider.length === 0 ? (\n <ErrorState\n block\n title=\"Couldn't load usage\"\n description=\"Token analytics failed to fetch. Retry to refetch.\"\n error={res.error}\n onRetry={() => void res.refetch()}\n testid=\"usage-error\"\n />\n ) : byProvider.length === 0 ? (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1} align=\"center\" style={{ padding: 'var(--space-4)' }}>\n <Clock size={24} aria-hidden />\n <span style={{ color: 'var(--fg-muted)' }}>No usage records for the last {range}.</span>\n </Stack>\n </CardBody>\n </Card>\n ) : (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={3}>\n <strong>By provider</strong>\n <Stack gap={2}>\n {byProvider.map((p) => (\n <Stack key={p.providerId} gap={1}>\n <Inline align=\"center\" justify=\"between\">\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)' }}>{p.providerId}</span>\n <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {fmtTokens(p.tokens)} · {p.requests} req\n </span>\n </Inline>\n <div\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={maxProvider || 1}\n aria-valuenow={p.tokens}\n style={{\n height: 6,\n background: 'var(--surface-1)',\n borderRadius: 'var(--radius-pill)',\n overflow: 'hidden',\n }}\n >\n <div style={{ width: `${maxProvider > 0 ? (p.tokens / maxProvider) * 100 : 0}%`, height: '100%', background: 'var(--accent)' }} />\n </div>\n </Stack>\n ))}\n </Stack>\n {byModel.length > 0 && (\n <Stack gap={2}>\n <strong>Top models</strong>\n {byModel.slice(0, 5).map((m) => (\n <Inline key={m.modelId} align=\"center\" justify=\"between\" style={{ fontSize: 'var(--fs-12)' }}>\n <code style={{ fontFamily: 'var(--font-mono)' }}>{m.modelId}</code>\n <span style={{ color: 'var(--fg-muted)' }}>{fmtTokens(m.tokens)}</span>\n </Inline>\n ))}\n </Stack>\n )}\n </Stack>\n </CardBody>\n </Card>\n )}\n </Stack>\n );\n}"],"names":["RANGE_OPTIONS","fmtTokens","n","StatTile","label","value","sub","Icon","jsx","Card","CardBody","jsxs","Stack","Inline","UsageView","range","setRange","useState","res","useFetch","limits","useEffect","totals","_a","byProvider","_b","byModel","_c","maxProvider","m","p","ViewHeader","Grid","BarChart3","TrendingUp","Zap","_e","_d","Skeleton","ErrorState","Clock"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import{r as f,j as e}from"./cmdk-DVxytz9i.js";import{c as x,g as m}from"./main-Cxeu4LhG.js";/**
1
+ import{r as f,j as e}from"./cmdk-C3F6LD6N.js";import{d as x,g as m}from"./main-BURAlktW.js";/**
2
2
  * @license lucide-react v0.460.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -1 +1 @@
1
- {"version":3,"file":"ViewHeader-B6P-C4GD.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/chevron-right.js","../../src/web/v8/ui/data/ViewHeader.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 ChevronRight = createLucideIcon(\"ChevronRight\", [\n [\"path\", { d: \"m9 18 6-6-6-6\", key: \"mthhwq\" }]\n]);\n\nexport { ChevronRight as default };\n//# sourceMappingURL=chevron-right.js.map\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { ChevronRight } from 'lucide-react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * ViewHeader — page-level header pattern (title, description, breadcrumb, actions).\n *\n * Layout:\n * [Breadcrumb]\n * [Title] [Primary action]\n * [Description] [Secondary actions...]\n *\n * Use at the top of every view: Overview, Tasks, Goals, Agents, etc.\n */\n\nexport interface BreadcrumbItem {\n label: ReactNode;\n href?: string;\n onClick?: () => void;\n}\n\nexport interface ViewHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title: ReactNode;\n description?: ReactNode;\n /** Optional breadcrumb trail rendered above the title. */\n breadcrumb?: readonly BreadcrumbItem[];\n /** Primary action (e.g. \"New task\"). */\n action?: ReactNode;\n /** Secondary actions (e.g. filter, export). */\n actions?: ReactNode;\n /** Optional metadata row below the description (e.g. status pills, counts). */\n meta?: ReactNode;\n}\n\nexport const ViewHeader = forwardRef<HTMLDivElement, ViewHeaderProps>(function ViewHeader(\n props,\n ref,\n) {\n const { title, description, breadcrumb, action, actions, meta, className, style, ...rest } = props;\n return (\n <header\n ref={ref}\n className={cx('v8-view-header', className)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-2)',\n padding: 'var(--space-4) 0 var(--space-5)',\n borderBottom: '1px solid var(--border)',\n marginBottom: 'var(--space-5)',\n ...style,\n }}\n {...rest}\n >\n {breadcrumb !== undefined && breadcrumb.length > 0 && (\n <nav\n aria-label=\"Breadcrumb\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-subtle)',\n marginBottom: 'var(--space-1)',\n }}\n >\n {breadcrumb.map((item, i) => {\n const isLast = i === breadcrumb.length - 1;\n return (\n <span\n key={i}\n style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}\n >\n {item.onClick !== undefined ? (\n <button\n onClick={item.onClick}\n style={{\n background: 'transparent',\n border: 0,\n padding: 0,\n font: 'inherit',\n color: 'inherit',\n cursor: 'pointer',\n }}\n >\n {item.label}\n </button>\n ) : (\n <span style={{ color: isLast ? 'var(--fg)' : 'inherit' }}>{item.label}</span>\n )}\n {!isLast && (\n <ChevronRight size={12} aria-hidden=\"true\" style={{ color: 'var(--fg-subtle)' }} />\n )}\n </span>\n );\n })}\n </nav>\n )}\n <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 'var(--space-4)' }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <h1 style={{ fontSize: 'var(--fs-24)', lineHeight: 'var(--lh-tight)', fontWeight: 600, margin: 0, color: 'var(--fg)' }}>\n {title}\n </h1>\n {description !== undefined && (\n <div style={{ fontSize: 'var(--fs-13)', color: 'var(--fg-muted)', marginTop: 4 }}>\n {description}\n </div>\n )}\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)', flexShrink: 0 }}>\n {actions}\n {action}\n </div>\n </div>\n {meta !== undefined && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)', flexWrap: 'wrap' }}>\n {meta}\n </div>\n )}\n </header>\n );\n});"],"names":["ChevronRight","createLucideIcon","ViewHeader","forwardRef","props","ref","title","description","breadcrumb","action","actions","meta","className","style","rest","jsxs","cx","jsx","item","isLast"],"mappings":"4FAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAeC,EAAiB,eAAgB,CACpD,CAAC,OAAQ,CAAE,EAAG,gBAAiB,IAAK,QAAQ,CAAE,CAChD,CAAC,ECuBYC,EAAaC,EAAAA,WAA4C,SACpEC,EACAC,EACA,CACA,KAAM,CAAE,MAAAC,EAAO,YAAAC,EAAa,WAAAC,EAAY,OAAAC,EAAQ,QAAAC,EAAS,KAAAC,EAAM,UAAAC,EAAW,MAAAC,EAAO,GAAGC,CAAA,EAASV,EAC7F,OACEW,EAAAA,KAAC,SAAA,CACC,IAAAV,EACA,UAAWW,EAAG,iBAAkBJ,CAAS,EACzC,MAAO,CACL,QAAS,OACT,cAAe,SACf,IAAK,iBACL,QAAS,kCACT,aAAc,0BACd,aAAc,iBACd,GAAGC,CAAA,EAEJ,GAAGC,EAEH,SAAA,CAAAN,IAAe,QAAaA,EAAW,OAAS,GAC/CS,EAAAA,IAAC,MAAA,CACC,aAAW,aACX,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,EACL,SAAU,eACV,MAAO,mBACP,aAAc,gBAAA,EAGf,SAAAT,EAAW,IAAI,CAACU,EAAM,IAAM,CAC3B,MAAMC,EAAS,IAAMX,EAAW,OAAS,EACzC,OACEO,EAAAA,KAAC,OAAA,CAEC,MAAO,CAAE,QAAS,cAAe,WAAY,SAAU,IAAK,CAAA,EAE3D,SAAA,CAAAG,EAAK,UAAY,OAChBD,EAAAA,IAAC,SAAA,CACC,QAASC,EAAK,QACd,MAAO,CACL,WAAY,cACZ,OAAQ,EACR,QAAS,EACT,KAAM,UACN,MAAO,UACP,OAAQ,SAAA,EAGT,SAAAA,EAAK,KAAA,CAAA,EAGRD,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,MAAOE,EAAS,YAAc,SAAA,EAAc,SAAAD,EAAK,KAAA,CAAM,EAEvE,CAACC,GACAF,EAAAA,IAACjB,EAAA,CAAa,KAAM,GAAI,cAAY,OAAO,MAAO,CAAE,MAAO,kBAAA,CAAmB,CAAG,CAAA,CAAA,EArB9E,CAAA,CAyBX,CAAC,CAAA,CAAA,EAGLe,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,KAAA,CAAG,MAAO,CAAE,SAAU,eAAgB,WAAY,kBAAmB,WAAY,IAAK,OAAQ,EAAG,MAAO,aACtG,SAAAX,EACH,EACCC,IAAgB,QACfU,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,MAAO,kBAAmB,UAAW,CAAA,EAC1E,SAAAV,CAAA,CACH,CAAA,EAEJ,EACAQ,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,iBAAkB,WAAY,CAAA,EACrF,SAAA,CAAAL,EACAD,CAAA,CAAA,CACH,CAAA,EACF,EACCE,IAAS,QACRM,MAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,iBAAkB,SAAU,MAAA,EACnF,SAAAN,CAAA,CACH,CAAA,CAAA,CAAA,CAIR,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"ViewHeader-C-t1U2cQ.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/chevron-right.js","../../src/web/v8/ui/data/ViewHeader.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 ChevronRight = createLucideIcon(\"ChevronRight\", [\n [\"path\", { d: \"m9 18 6-6-6-6\", key: \"mthhwq\" }]\n]);\n\nexport { ChevronRight as default };\n//# sourceMappingURL=chevron-right.js.map\n","import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { ChevronRight } from 'lucide-react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * ViewHeader — page-level header pattern (title, description, breadcrumb, actions).\n *\n * Layout:\n * [Breadcrumb]\n * [Title] [Primary action]\n * [Description] [Secondary actions...]\n *\n * Use at the top of every view: Overview, Tasks, Goals, Agents, etc.\n */\n\nexport interface BreadcrumbItem {\n label: ReactNode;\n href?: string;\n onClick?: () => void;\n}\n\nexport interface ViewHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title: ReactNode;\n description?: ReactNode;\n /** Optional breadcrumb trail rendered above the title. */\n breadcrumb?: readonly BreadcrumbItem[];\n /** Primary action (e.g. \"New task\"). */\n action?: ReactNode;\n /** Secondary actions (e.g. filter, export). */\n actions?: ReactNode;\n /** Optional metadata row below the description (e.g. status pills, counts). */\n meta?: ReactNode;\n}\n\nexport const ViewHeader = forwardRef<HTMLDivElement, ViewHeaderProps>(function ViewHeader(\n props,\n ref,\n) {\n const { title, description, breadcrumb, action, actions, meta, className, style, ...rest } = props;\n return (\n <header\n ref={ref}\n className={cx('v8-view-header', className)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-2)',\n padding: 'var(--space-4) 0 var(--space-5)',\n borderBottom: '1px solid var(--border)',\n marginBottom: 'var(--space-5)',\n ...style,\n }}\n {...rest}\n >\n {breadcrumb !== undefined && breadcrumb.length > 0 && (\n <nav\n aria-label=\"Breadcrumb\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-subtle)',\n marginBottom: 'var(--space-1)',\n }}\n >\n {breadcrumb.map((item, i) => {\n const isLast = i === breadcrumb.length - 1;\n return (\n <span\n key={i}\n style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}\n >\n {item.onClick !== undefined ? (\n <button\n onClick={item.onClick}\n style={{\n background: 'transparent',\n border: 0,\n padding: 0,\n font: 'inherit',\n color: 'inherit',\n cursor: 'pointer',\n }}\n >\n {item.label}\n </button>\n ) : (\n <span style={{ color: isLast ? 'var(--fg)' : 'inherit' }}>{item.label}</span>\n )}\n {!isLast && (\n <ChevronRight size={12} aria-hidden=\"true\" style={{ color: 'var(--fg-subtle)' }} />\n )}\n </span>\n );\n })}\n </nav>\n )}\n <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 'var(--space-4)' }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <h1 style={{ fontSize: 'var(--fs-24)', lineHeight: 'var(--lh-tight)', fontWeight: 600, margin: 0, color: 'var(--fg)' }}>\n {title}\n </h1>\n {description !== undefined && (\n <div style={{ fontSize: 'var(--fs-13)', color: 'var(--fg-muted)', marginTop: 4 }}>\n {description}\n </div>\n )}\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)', flexShrink: 0 }}>\n {actions}\n {action}\n </div>\n </div>\n {meta !== undefined && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)', flexWrap: 'wrap' }}>\n {meta}\n </div>\n )}\n </header>\n );\n});"],"names":["ChevronRight","createLucideIcon","ViewHeader","forwardRef","props","ref","title","description","breadcrumb","action","actions","meta","className","style","rest","jsxs","cx","jsx","item","isLast"],"mappings":"4FAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAeC,EAAiB,eAAgB,CACpD,CAAC,OAAQ,CAAE,EAAG,gBAAiB,IAAK,QAAQ,CAAE,CAChD,CAAC,ECuBYC,EAAaC,EAAAA,WAA4C,SACpEC,EACAC,EACA,CACA,KAAM,CAAE,MAAAC,EAAO,YAAAC,EAAa,WAAAC,EAAY,OAAAC,EAAQ,QAAAC,EAAS,KAAAC,EAAM,UAAAC,EAAW,MAAAC,EAAO,GAAGC,CAAA,EAASV,EAC7F,OACEW,EAAAA,KAAC,SAAA,CACC,IAAAV,EACA,UAAWW,EAAG,iBAAkBJ,CAAS,EACzC,MAAO,CACL,QAAS,OACT,cAAe,SACf,IAAK,iBACL,QAAS,kCACT,aAAc,0BACd,aAAc,iBACd,GAAGC,CAAA,EAEJ,GAAGC,EAEH,SAAA,CAAAN,IAAe,QAAaA,EAAW,OAAS,GAC/CS,EAAAA,IAAC,MAAA,CACC,aAAW,aACX,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,EACL,SAAU,eACV,MAAO,mBACP,aAAc,gBAAA,EAGf,SAAAT,EAAW,IAAI,CAACU,EAAM,IAAM,CAC3B,MAAMC,EAAS,IAAMX,EAAW,OAAS,EACzC,OACEO,EAAAA,KAAC,OAAA,CAEC,MAAO,CAAE,QAAS,cAAe,WAAY,SAAU,IAAK,CAAA,EAE3D,SAAA,CAAAG,EAAK,UAAY,OAChBD,EAAAA,IAAC,SAAA,CACC,QAASC,EAAK,QACd,MAAO,CACL,WAAY,cACZ,OAAQ,EACR,QAAS,EACT,KAAM,UACN,MAAO,UACP,OAAQ,SAAA,EAGT,SAAAA,EAAK,KAAA,CAAA,EAGRD,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,MAAOE,EAAS,YAAc,SAAA,EAAc,SAAAD,EAAK,KAAA,CAAM,EAEvE,CAACC,GACAF,EAAAA,IAACjB,EAAA,CAAa,KAAM,GAAI,cAAY,OAAO,MAAO,CAAE,MAAO,kBAAA,CAAmB,CAAG,CAAA,CAAA,EArB9E,CAAA,CAyBX,CAAC,CAAA,CAAA,EAGLe,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,KAAA,CAAG,MAAO,CAAE,SAAU,eAAgB,WAAY,kBAAmB,WAAY,IAAK,OAAQ,EAAG,MAAO,aACtG,SAAAX,EACH,EACCC,IAAgB,QACfU,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,MAAO,kBAAmB,UAAW,CAAA,EAC1E,SAAAV,CAAA,CACH,CAAA,EAEJ,EACAQ,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,iBAAkB,WAAY,CAAA,EACrF,SAAA,CAAAL,EACAD,CAAA,CAAA,CACH,CAAA,EACF,EACCE,IAAS,QACRM,MAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,iBAAkB,SAAU,MAAA,EACnF,SAAAN,CAAA,CACH,CAAA,CAAA,CAAA,CAIR,CAAC","x_google_ignoreList":[0]}