@polderlabs/bizar 10.4.2 → 10.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/bizar-dash/dist/assets/{ActivityFeed-DtRtg-JN.js → ActivityFeed-DC0JiK49.js} +1 -1
  2. package/bizar-dash/dist/assets/{ActivityFeed-DtRtg-JN.js.map → ActivityFeed-DC0JiK49.js.map} +1 -1
  3. package/bizar-dash/dist/assets/{ActivityView-CoTXDyU_.js → ActivityView-ubEDAWMY.js} +1 -1
  4. package/bizar-dash/dist/assets/{ActivityView-CoTXDyU_.js.map → ActivityView-ubEDAWMY.js.map} +1 -1
  5. package/bizar-dash/dist/assets/{AdminView-DNc5Ll7L.js → AdminView-CI4zM2Qg.js} +1 -1
  6. package/bizar-dash/dist/assets/{AdminView-DNc5Ll7L.js.map → AdminView-CI4zM2Qg.js.map} +1 -1
  7. package/bizar-dash/dist/assets/{AgentActivity-CrX7LmQ6.js → AgentActivity-BLcqqkt2.js} +1 -1
  8. package/bizar-dash/dist/assets/{AgentActivity-CrX7LmQ6.js.map → AgentActivity-BLcqqkt2.js.map} +1 -1
  9. package/bizar-dash/dist/assets/AgentsView-CIQkZH8_.js +15 -0
  10. package/bizar-dash/dist/assets/AgentsView-CIQkZH8_.js.map +1 -0
  11. package/bizar-dash/dist/assets/{Alert-B6DjfRFI.js → Alert-MwVEymjy.js} +1 -1
  12. package/bizar-dash/dist/assets/{Alert-B6DjfRFI.js.map → Alert-MwVEymjy.js.map} +1 -1
  13. package/bizar-dash/dist/assets/{ArtifactsView-znhN8GTR.js → ArtifactsView-B-YUwZyb.js} +1 -1
  14. package/bizar-dash/dist/assets/{ArtifactsView-znhN8GTR.js.map → ArtifactsView-B-YUwZyb.js.map} +1 -1
  15. package/bizar-dash/dist/assets/{AuthView-Rk8eKUPr.js → AuthView-LaQuGo4u.js} +1 -1
  16. package/bizar-dash/dist/assets/{AuthView-Rk8eKUPr.js.map → AuthView-LaQuGo4u.js.map} +1 -1
  17. package/bizar-dash/dist/assets/{Avatar-B41upSD1.js → Avatar-Dg4OF4RD.js} +1 -1
  18. package/bizar-dash/dist/assets/{Avatar-B41upSD1.js.map → Avatar-Dg4OF4RD.js.map} +1 -1
  19. package/bizar-dash/dist/assets/{BackgroundJobsView-BLWuN9qz.js → BackgroundJobsView-CO3DEG8R.js} +1 -1
  20. package/bizar-dash/dist/assets/{BackgroundJobsView-BLWuN9qz.js.map → BackgroundJobsView-CO3DEG8R.js.map} +1 -1
  21. package/bizar-dash/dist/assets/{BackupView-CqbtcnuQ.js → BackupView-Cjf23ZWc.js} +1 -1
  22. package/bizar-dash/dist/assets/{BackupView-CqbtcnuQ.js.map → BackupView-Cjf23ZWc.js.map} +1 -1
  23. package/bizar-dash/dist/assets/{Card-rF59wHiO.js → Card-BmXiT4c6.js} +1 -1
  24. package/bizar-dash/dist/assets/{Card-rF59wHiO.js.map → Card-BmXiT4c6.js.map} +1 -1
  25. package/bizar-dash/dist/assets/ChatView-DXKFwvgp.js +9 -0
  26. package/bizar-dash/dist/assets/ChatView-DXKFwvgp.js.map +1 -0
  27. package/bizar-dash/dist/assets/{Chip-Dc2KmeWl.js → Chip-Dei66BLx.js} +1 -1
  28. package/bizar-dash/dist/assets/{Chip-Dc2KmeWl.js.map → Chip-Dei66BLx.js.map} +1 -1
  29. package/bizar-dash/dist/assets/{ClaudeSessionsView-CiaHQdDZ.js → ClaudeSessionsView-D-YNmzKi.js} +1 -1
  30. package/bizar-dash/dist/assets/{ClaudeSessionsView-CiaHQdDZ.js.map → ClaudeSessionsView-D-YNmzKi.js.map} +1 -1
  31. package/bizar-dash/dist/assets/{ClipboardView-DdP6aVso.js → ClipboardView-BA323V2J.js} +1 -1
  32. package/bizar-dash/dist/assets/{ClipboardView-DdP6aVso.js.map → ClipboardView-BA323V2J.js.map} +1 -1
  33. package/bizar-dash/dist/assets/{ConfigView-B2ysnTZU.js → ConfigView-BMBgifw5.js} +1 -1
  34. package/bizar-dash/dist/assets/{ConfigView-B2ysnTZU.js.map → ConfigView-BMBgifw5.js.map} +1 -1
  35. package/bizar-dash/dist/assets/DiagnosticsView-C0sdqhEl.js +2 -0
  36. package/bizar-dash/dist/assets/DiagnosticsView-C0sdqhEl.js.map +1 -0
  37. package/bizar-dash/dist/assets/{DialogsView-BcqDDCZQ.js → DialogsView-DzTnyX8K.js} +1 -1
  38. package/bizar-dash/dist/assets/{DialogsView-BcqDDCZQ.js.map → DialogsView-DzTnyX8K.js.map} +1 -1
  39. package/bizar-dash/dist/assets/{DoctorView-BQwqvMAh.js → DoctorView-CiFwRMW0.js} +1 -1
  40. package/bizar-dash/dist/assets/{DoctorView-BQwqvMAh.js.map → DoctorView-CiFwRMW0.js.map} +1 -1
  41. package/bizar-dash/dist/assets/{EmptyState-D65J5FQN.js → EmptyState-CdDQmfEL.js} +1 -1
  42. package/bizar-dash/dist/assets/{EmptyState-D65J5FQN.js.map → EmptyState-CdDQmfEL.js.map} +1 -1
  43. package/bizar-dash/dist/assets/{EnvVarsView-DX-3oGH-.js → EnvVarsView-CNO03NDJ.js} +1 -1
  44. package/bizar-dash/dist/assets/{EnvVarsView-DX-3oGH-.js.map → EnvVarsView-CNO03NDJ.js.map} +1 -1
  45. package/bizar-dash/dist/assets/{ErrorState-DULZnttJ.js → ErrorState-BRvj8qZZ.js} +1 -1
  46. package/bizar-dash/dist/assets/{ErrorState-DULZnttJ.js.map → ErrorState-BRvj8qZZ.js.map} +1 -1
  47. package/bizar-dash/dist/assets/{EvalView-CpdFu_ID.js → EvalView-lgUhlGJh.js} +1 -1
  48. package/bizar-dash/dist/assets/{EvalView-CpdFu_ID.js.map → EvalView-lgUhlGJh.js.map} +1 -1
  49. package/bizar-dash/dist/assets/{GoalsView-Br8oPPfb.js → GoalsView-DmkCCs9i.js} +1 -1
  50. package/bizar-dash/dist/assets/{GoalsView-Br8oPPfb.js.map → GoalsView-DmkCCs9i.js.map} +1 -1
  51. package/bizar-dash/dist/assets/{Grid-BSXhsCPC.js → Grid-BThCPJaV.js} +1 -1
  52. package/bizar-dash/dist/assets/{Grid-BSXhsCPC.js.map → Grid-BThCPJaV.js.map} +1 -1
  53. package/bizar-dash/dist/assets/{HistoryView-D0J3aoZF.js → HistoryView-Cn2cPiHZ.js} +1 -1
  54. package/bizar-dash/dist/assets/{HistoryView-D0J3aoZF.js.map → HistoryView-Cn2cPiHZ.js.map} +1 -1
  55. package/bizar-dash/dist/assets/{Input-CZmRw5QX.js → Input-cAQOvR8U.js} +1 -1
  56. package/bizar-dash/dist/assets/{Input-CZmRw5QX.js.map → Input-cAQOvR8U.js.map} +1 -1
  57. package/bizar-dash/dist/assets/LibrariesView-Ca_PRjUm.js +6 -0
  58. package/bizar-dash/dist/assets/{LibrariesView-B1YX9wzp.js.map → LibrariesView-Ca_PRjUm.js.map} +1 -1
  59. package/bizar-dash/dist/assets/{LightRAGView-CykR0t9y.js → LightRAGView-CMk9wOae.js} +1 -1
  60. package/bizar-dash/dist/assets/{LightRAGView-CykR0t9y.js.map → LightRAGView-CMk9wOae.js.map} +1 -1
  61. package/bizar-dash/dist/assets/{ListHeader-Dpun-r36.js → ListHeader-BLAeshe0.js} +1 -1
  62. package/bizar-dash/dist/assets/{ListHeader-Dpun-r36.js.map → ListHeader-BLAeshe0.js.map} +1 -1
  63. package/bizar-dash/dist/assets/{MemoryView-BbER5ZKt.js → MemoryView-wo2Pu7xQ.js} +1 -1
  64. package/bizar-dash/dist/assets/{MemoryView-BbER5ZKt.js.map → MemoryView-wo2Pu7xQ.js.map} +1 -1
  65. package/bizar-dash/dist/assets/{MessageBubble-5vUAquDx.js → MessageBubble-CrCJ0SYG.js} +1 -1
  66. package/bizar-dash/dist/assets/{MessageBubble-5vUAquDx.js.map → MessageBubble-CrCJ0SYG.js.map} +1 -1
  67. package/bizar-dash/dist/assets/{MiscView-DLNEGdML.js → MiscView-fBT1TOXC.js} +1 -1
  68. package/bizar-dash/dist/assets/{MiscView-DLNEGdML.js.map → MiscView-fBT1TOXC.js.map} +1 -1
  69. package/bizar-dash/dist/assets/{ModsView-P7gDeNHM.js → ModsView-CV_RxdzJ.js} +1 -1
  70. package/bizar-dash/dist/assets/{ModsView-P7gDeNHM.js.map → ModsView-CV_RxdzJ.js.map} +1 -1
  71. package/bizar-dash/dist/assets/{NotificationsView-DAm2O0yf.js → NotificationsView-BKAZLxM2.js} +1 -1
  72. package/bizar-dash/dist/assets/{NotificationsView-DAm2O0yf.js.map → NotificationsView-BKAZLxM2.js.map} +1 -1
  73. package/bizar-dash/dist/assets/{ObsidianView-Ci80gnwS.js → ObsidianView-C-AvHfpT.js} +1 -1
  74. package/bizar-dash/dist/assets/{ObsidianView-Ci80gnwS.js.map → ObsidianView-C-AvHfpT.js.map} +1 -1
  75. package/bizar-dash/dist/assets/{OverviewView-rriw1GjA.js → OverviewView-CKYzZJe3.js} +1 -1
  76. package/bizar-dash/dist/assets/{OverviewView-rriw1GjA.js.map → OverviewView-CKYzZJe3.js.map} +1 -1
  77. package/bizar-dash/dist/assets/{ProgressBar-BahmeJhP.js → ProgressBar-ya2PCj8L.js} +1 -1
  78. package/bizar-dash/dist/assets/{ProgressBar-BahmeJhP.js.map → ProgressBar-ya2PCj8L.js.map} +1 -1
  79. package/bizar-dash/dist/assets/ProjectsView-N9zqFZ_O.js +11 -0
  80. package/bizar-dash/dist/assets/ProjectsView-N9zqFZ_O.js.map +1 -0
  81. package/bizar-dash/dist/assets/{ProvidersView-BftGn8Cr.js → ProvidersView-BcL8jjwK.js} +1 -1
  82. package/bizar-dash/dist/assets/{ProvidersView-BftGn8Cr.js.map → ProvidersView-BcL8jjwK.js.map} +1 -1
  83. package/bizar-dash/dist/assets/{SchedulesView-CtNxtzN6.js → SchedulesView-8qxH3bg7.js} +1 -1
  84. package/bizar-dash/dist/assets/{SchedulesView-CtNxtzN6.js.map → SchedulesView-8qxH3bg7.js.map} +1 -1
  85. package/bizar-dash/dist/assets/{Select-0VcfTDeL.js → Select-D5AuVxxV.js} +1 -1
  86. package/bizar-dash/dist/assets/{Select-0VcfTDeL.js.map → Select-D5AuVxxV.js.map} +1 -1
  87. package/bizar-dash/dist/assets/{SettingsRow-BLic3DQl.js → SettingsRow-BBALf9dA.js} +1 -1
  88. package/bizar-dash/dist/assets/{SettingsRow-BLic3DQl.js.map → SettingsRow-BBALf9dA.js.map} +1 -1
  89. package/bizar-dash/dist/assets/{SettingsView-BjS3i4nr.js → SettingsView-UD403neY.js} +1 -1
  90. package/bizar-dash/dist/assets/{SettingsView-BjS3i4nr.js.map → SettingsView-UD403neY.js.map} +1 -1
  91. package/bizar-dash/dist/assets/{Sheet-BOProMs2.js → Sheet-CxXf6gvC.js} +1 -1
  92. package/bizar-dash/dist/assets/{Sheet-BOProMs2.js.map → Sheet-CxXf6gvC.js.map} +1 -1
  93. package/bizar-dash/dist/assets/{Slider-B0eLEEUt.js → Slider-hvaVD_SW.js} +1 -1
  94. package/bizar-dash/dist/assets/{Slider-B0eLEEUt.js.map → Slider-hvaVD_SW.js.map} +1 -1
  95. package/bizar-dash/dist/assets/{Sparkline-SSrdgyW0.js → Sparkline-DqmQzdJH.js} +1 -1
  96. package/bizar-dash/dist/assets/{Sparkline-SSrdgyW0.js.map → Sparkline-DqmQzdJH.js.map} +1 -1
  97. package/bizar-dash/dist/assets/{Switch-B3EQzb_q.js → Switch-C-_zcNdl.js} +1 -1
  98. package/bizar-dash/dist/assets/{Switch-B3EQzb_q.js.map → Switch-C-_zcNdl.js.map} +1 -1
  99. package/bizar-dash/dist/assets/{TasksView-SWjF_ZUQ.js → TasksView-DseftDlx.js} +1 -1
  100. package/bizar-dash/dist/assets/{TasksView-SWjF_ZUQ.js.map → TasksView-DseftDlx.js.map} +1 -1
  101. package/bizar-dash/dist/assets/{Textarea-QuofpMlq.js → Textarea-CcQGSgSH.js} +1 -1
  102. package/bizar-dash/dist/assets/{Textarea-QuofpMlq.js.map → Textarea-CcQGSgSH.js.map} +1 -1
  103. package/bizar-dash/dist/assets/{UpdateView-CEHW2nd6.js → UpdateView-B9Lh4svM.js} +1 -1
  104. package/bizar-dash/dist/assets/{UpdateView-CEHW2nd6.js.map → UpdateView-B9Lh4svM.js.map} +1 -1
  105. package/bizar-dash/dist/assets/{UsageView-BqOw6FBg.js → UsageView-P5_pQ68d.js} +1 -1
  106. package/bizar-dash/dist/assets/{UsageView-BqOw6FBg.js.map → UsageView-P5_pQ68d.js.map} +1 -1
  107. package/bizar-dash/dist/assets/{ViewHeader-B6P-C4GD.js → ViewHeader-BaCWNuVX.js} +1 -1
  108. package/bizar-dash/dist/assets/{ViewHeader-B6P-C4GD.js.map → ViewHeader-BaCWNuVX.js.map} +1 -1
  109. package/bizar-dash/dist/assets/{VoiceView-CwrPwWgi.js → VoiceView-BwR9gm5e.js} +1 -1
  110. package/bizar-dash/dist/assets/{VoiceView-CwrPwWgi.js.map → VoiceView-BwR9gm5e.js.map} +1 -1
  111. package/bizar-dash/dist/assets/{brain-CwZt9Kta.js → brain-D6tAeUDE.js} +1 -1
  112. package/bizar-dash/dist/assets/{brain-CwZt9Kta.js.map → brain-D6tAeUDE.js.map} +1 -1
  113. package/bizar-dash/dist/assets/{calendar-C5oK0_nM.js → calendar-BrMJf3vl.js} +1 -1
  114. package/bizar-dash/dist/assets/{calendar-C5oK0_nM.js.map → calendar-BrMJf3vl.js.map} +1 -1
  115. package/bizar-dash/dist/assets/{circle-alert-HdHe7m8K.js → circle-alert-D7jn06kH.js} +1 -1
  116. package/bizar-dash/dist/assets/{circle-alert-HdHe7m8K.js.map → circle-alert-D7jn06kH.js.map} +1 -1
  117. package/bizar-dash/dist/assets/{circle-check-Cs-xoV7R.js → circle-check-DHs37Sot.js} +1 -1
  118. package/bizar-dash/dist/assets/{circle-check-Cs-xoV7R.js.map → circle-check-DHs37Sot.js.map} +1 -1
  119. package/bizar-dash/dist/assets/{circle-D1Lc_P2a.js → circle-fPTATiOs.js} +1 -1
  120. package/bizar-dash/dist/assets/{circle-D1Lc_P2a.js.map → circle-fPTATiOs.js.map} +1 -1
  121. package/bizar-dash/dist/assets/{clock-DEIuPV60.js → clock-E-G5aGua.js} +1 -1
  122. package/bizar-dash/dist/assets/{clock-DEIuPV60.js.map → clock-E-G5aGua.js.map} +1 -1
  123. package/bizar-dash/dist/assets/{cmdk-DVxytz9i.js → cmdk-C3F6LD6N.js} +5 -5
  124. package/bizar-dash/dist/assets/{cmdk-DVxytz9i.js.map → cmdk-C3F6LD6N.js.map} +1 -1
  125. package/bizar-dash/dist/assets/{dnd-kit-DrHErSkw.js → dnd-kit-BAOLODOI.js} +1 -1
  126. package/bizar-dash/dist/assets/{dnd-kit-DrHErSkw.js.map → dnd-kit-BAOLODOI.js.map} +1 -1
  127. package/bizar-dash/dist/assets/{download-Clkq90Ct.js → download-DBkNb6oI.js} +1 -1
  128. package/bizar-dash/dist/assets/{download-Clkq90Ct.js.map → download-DBkNb6oI.js.map} +1 -1
  129. package/bizar-dash/dist/assets/{external-link-D5tq2o_I.js → external-link-C4pHGbz2.js} +1 -1
  130. package/bizar-dash/dist/assets/{external-link-D5tq2o_I.js.map → external-link-C4pHGbz2.js.map} +1 -1
  131. package/bizar-dash/dist/assets/{file-text-CQ12t7Oc.js → file-text-CEhDgLq2.js} +1 -1
  132. package/bizar-dash/dist/assets/{file-text-CQ12t7Oc.js.map → file-text-CEhDgLq2.js.map} +1 -1
  133. package/bizar-dash/dist/assets/{filter-BcbE37wP.js → filter-CEYjeWFX.js} +1 -1
  134. package/bizar-dash/dist/assets/{filter-BcbE37wP.js.map → filter-CEYjeWFX.js.map} +1 -1
  135. package/bizar-dash/dist/assets/{git-pull-request-D1qNDRia.js → git-pull-request-Bo_wBZZw.js} +1 -1
  136. package/bizar-dash/dist/assets/{git-pull-request-D1qNDRia.js.map → git-pull-request-Bo_wBZZw.js.map} +1 -1
  137. package/bizar-dash/dist/assets/{index-CASP1n-5.js → index-B1OIS316.js} +1 -1
  138. package/bizar-dash/dist/assets/{index-CASP1n-5.js.map → index-B1OIS316.js.map} +1 -1
  139. package/bizar-dash/dist/assets/{index-C4Vq_2LM.js → index-CR0TeJmc.js} +1 -1
  140. package/bizar-dash/dist/assets/{index-C4Vq_2LM.js.map → index-CR0TeJmc.js.map} +1 -1
  141. package/bizar-dash/dist/assets/main-BZMmD6a8.js +249 -0
  142. package/bizar-dash/dist/assets/main-BZMmD6a8.js.map +1 -0
  143. package/bizar-dash/dist/assets/{main-CcQfRfIJ.css → main-DDAMz_H5.css} +1 -1
  144. package/bizar-dash/dist/assets/{network-DJdvVaHx.js → network-BsfwrUA-.js} +1 -1
  145. package/bizar-dash/dist/assets/{network-DJdvVaHx.js.map → network-BsfwrUA-.js.map} +1 -1
  146. package/bizar-dash/dist/assets/{pause-DUn9L5PB.js → pause-C8PN1_yO.js} +1 -1
  147. package/bizar-dash/dist/assets/{pause-DUn9L5PB.js.map → pause-C8PN1_yO.js.map} +1 -1
  148. package/bizar-dash/dist/assets/{pencil-DVrBlYV3.js → pencil---XuvKlz.js} +1 -1
  149. package/bizar-dash/dist/assets/{pencil-DVrBlYV3.js.map → pencil---XuvKlz.js.map} +1 -1
  150. package/bizar-dash/dist/assets/{play-CZjsr3XM.js → play-fMLPTihK.js} +1 -1
  151. package/bizar-dash/dist/assets/{play-CZjsr3XM.js.map → play-fMLPTihK.js.map} +1 -1
  152. package/bizar-dash/dist/assets/{plug-BKuyIe5W.js → plug-CG8al2Kq.js} +1 -1
  153. package/bizar-dash/dist/assets/{plug-BKuyIe5W.js.map → plug-CG8al2Kq.js.map} +1 -1
  154. package/bizar-dash/dist/assets/{plus-77h62zZm.js → plus-uA5Ecuch.js} +1 -1
  155. package/bizar-dash/dist/assets/{plus-77h62zZm.js.map → plus-uA5Ecuch.js.map} +1 -1
  156. package/bizar-dash/dist/assets/{power-DLmx-gCP.js → power-DSUlNIuR.js} +1 -1
  157. package/bizar-dash/dist/assets/{power-DLmx-gCP.js.map → power-DSUlNIuR.js.map} +1 -1
  158. package/bizar-dash/dist/assets/{power-off-BFKzHXic.js → power-off-1CAQsHHy.js} +1 -1
  159. package/bizar-dash/dist/assets/{power-off-BFKzHXic.js.map → power-off-1CAQsHHy.js.map} +1 -1
  160. package/bizar-dash/dist/assets/{refresh-ccw-DenGBOcq.js → refresh-ccw-BL7B0NO1.js} +1 -1
  161. package/bizar-dash/dist/assets/{refresh-ccw-DenGBOcq.js.map → refresh-ccw-BL7B0NO1.js.map} +1 -1
  162. package/bizar-dash/dist/assets/{refresh-cw-ENBVR8hW.js → refresh-cw-CR9BzJik.js} +1 -1
  163. package/bizar-dash/dist/assets/{refresh-cw-ENBVR8hW.js.map → refresh-cw-CR9BzJik.js.map} +1 -1
  164. package/bizar-dash/dist/assets/{rotate-ccw-MxryaY7q.js → rotate-ccw-BtnitLfb.js} +1 -1
  165. package/bizar-dash/dist/assets/{rotate-ccw-MxryaY7q.js.map → rotate-ccw-BtnitLfb.js.map} +1 -1
  166. package/bizar-dash/dist/assets/{rotate-cw-CDOlRtUR.js → rotate-cw-CHgXCO7O.js} +1 -1
  167. package/bizar-dash/dist/assets/{rotate-cw-CDOlRtUR.js.map → rotate-cw-CHgXCO7O.js.map} +1 -1
  168. package/bizar-dash/dist/assets/{save-Db1b-1Uq.js → save-RcZOXR0U.js} +1 -1
  169. package/bizar-dash/dist/assets/{save-Db1b-1Uq.js.map → save-RcZOXR0U.js.map} +1 -1
  170. package/bizar-dash/dist/assets/{send-yz6HFZM5.js → send-Bg2X_ibk.js} +1 -1
  171. package/bizar-dash/dist/assets/{send-yz6HFZM5.js.map → send-Bg2X_ibk.js.map} +1 -1
  172. package/bizar-dash/dist/assets/{shield-alert-DY6RAaC8.js → shield-alert-Dm48D034.js} +1 -1
  173. package/bizar-dash/dist/assets/{shield-alert-DY6RAaC8.js.map → shield-alert-Dm48D034.js.map} +1 -1
  174. package/bizar-dash/dist/assets/{trash-2-Cv7U38jw.js → trash-2-B885GY46.js} +1 -1
  175. package/bizar-dash/dist/assets/{trash-2-Cv7U38jw.js.map → trash-2-B885GY46.js.map} +1 -1
  176. package/bizar-dash/dist/assets/{trending-up-CRPNagyX.js → trending-up-CqUBvVxw.js} +1 -1
  177. package/bizar-dash/dist/assets/{trending-up-CRPNagyX.js.map → trending-up-CqUBvVxw.js.map} +1 -1
  178. package/bizar-dash/dist/assets/{triangle-alert-tUTXbcEP.js → triangle-alert-DLmUhymD.js} +1 -1
  179. package/bizar-dash/dist/assets/{triangle-alert-tUTXbcEP.js.map → triangle-alert-DLmUhymD.js.map} +1 -1
  180. package/bizar-dash/dist/assets/{upload-Cq7uTsrT.js → upload-C-oafpyE.js} +1 -1
  181. package/bizar-dash/dist/assets/{upload-Cq7uTsrT.js.map → upload-C-oafpyE.js.map} +1 -1
  182. package/bizar-dash/dist/assets/{zap-5lAQBAPX.js → zap-O_4Ys_hh.js} +1 -1
  183. package/bizar-dash/dist/assets/{zap-5lAQBAPX.js.map → zap-O_4Ys_hh.js.map} +1 -1
  184. package/bizar-dash/dist/index.html +3 -3
  185. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  186. package/bizar-dash/src/web/v8/App.tsx +62 -2
  187. package/bizar-dash/src/web/v8/__tests__/chat-view.test.tsx +4 -4
  188. package/bizar-dash/src/web/v8/shell/AppShell.tsx +38 -2
  189. package/bizar-dash/src/web/v8/shell/Sidebar.tsx +44 -33
  190. package/bizar-dash/src/web/v8/shell/Topbar.tsx +5 -2
  191. package/bizar-dash/src/web/v8/ui/styles/globals.css +26 -0
  192. package/bizar-dash/src/web/v8/views/Agents/AgentsView.tsx +26 -1
  193. package/bizar-dash/src/web/v8/views/Chat/ChatView.tsx +13 -1
  194. package/bizar-dash/src/web/v8/views/ClaudeSessions/NewSessionModal.tsx +136 -0
  195. package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.tsx +14 -4
  196. package/bizar-dash/src/web/v8/views/Diagnostics/DiagnosticsView.tsx +50 -7
  197. package/bizar-dash/src/web/v8/views/Libraries/LibrariesView.tsx +6 -1
  198. package/bizar-dash/src/web/v8/views/Projects/ProjectsView.tsx +21 -1
  199. package/bizar-dash/tests/admin-labels.test.mjs +42 -0
  200. package/bizar-dash/tests/agents-summary-sanitize.test.ts +51 -0
  201. package/bizar-dash/tests/chat-new-session.test.mjs +63 -0
  202. package/bizar-dash/tests/kanban-empty-column.test.mjs +56 -0
  203. package/bizar-dash/tests/library-dedupe.test.mjs +62 -0
  204. package/bizar-dash/tests/projects-filter.test.mjs +48 -0
  205. package/bizar-dash/tests/settings-labels.test.mjs +80 -0
  206. package/bizar-dash/tests/sidebar-responsive.test.tsx +48 -0
  207. package/bizar-dash/tests/sidebar-section-toggle.test.tsx +63 -0
  208. package/package.json +1 -1
  209. package/packages/sdk/package.json +1 -1
  210. package/bizar-dash/dist/assets/AgentsView-Du-G_skK.js +0 -13
  211. package/bizar-dash/dist/assets/AgentsView-Du-G_skK.js.map +0 -1
  212. package/bizar-dash/dist/assets/ChatView-CUriVEgU.js +0 -9
  213. package/bizar-dash/dist/assets/ChatView-CUriVEgU.js.map +0 -1
  214. package/bizar-dash/dist/assets/DiagnosticsView-88OZ5k0f.js +0 -2
  215. package/bizar-dash/dist/assets/DiagnosticsView-88OZ5k0f.js.map +0 -1
  216. package/bizar-dash/dist/assets/LibrariesView-B1YX9wzp.js +0 -6
  217. package/bizar-dash/dist/assets/ProjectsView-ChzM12bs.js +0 -11
  218. package/bizar-dash/dist/assets/ProjectsView-ChzM12bs.js.map +0 -1
  219. package/bizar-dash/dist/assets/main-Cxeu4LhG.js +0 -244
  220. package/bizar-dash/dist/assets/main-Cxeu4LhG.js.map +0 -1
@@ -1 +1 @@
1
- import{r as s,j as e}from"./cmdk-DVxytz9i.js";import{u as k,S as h,I as f,d as n,h as y,_ as w,i as S,F as z}from"./main-Cxeu4LhG.js";import{V as E}from"./ViewHeader-B6P-C4GD.js";import{C as T,b as D}from"./Card-rF59wHiO.js";import{I as b}from"./Input-CZmRw5QX.js";import{T as C}from"./Textarea-QuofpMlq.js";import{S as R,a as $}from"./Sheet-BOProMs2.js";import{E as L}from"./EmptyState-D65J5FQN.js";import{R as F}from"./refresh-ccw-DenGBOcq.js";import{P as I}from"./plus-77h62zZm.js";import{E as P}from"./external-link-D5tq2o_I.js";import{T as U}from"./trash-2-Cv7U38jw.js";function Q(){const l=k("/api/clipboard/list"),[v,r]=s.useState(!1),[x,o]=s.useState(null),[u,d]=s.useState(null),p=s.useMemo(()=>{var t;return((t=l.data)==null?void 0:t.clips)??[]},[l.data]),c=s.useCallback(()=>{l.refetch()},[l]),g=async t=>{d(null);try{await S(`/api/clipboard/${t}`,{method:"DELETE"}),o(null),c()}catch(i){d((i instanceof z,i.message))}};return e.jsxs(h,{gap:4,"data-testid":"clipboard-view",children:[e.jsx(E,{title:"Clipboard",description:"Saved clips. Each becomes a markdown note under clips/.",actions:e.jsxs(f,{align:"center",gap:2,children:[u!==null&&e.jsx("span",{role:"alert","data-testid":"clipboard-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:u}),e.jsxs(n,{variant:"ghost",onClick:()=>void c(),"data-testid":"clipboard-refresh",children:[e.jsx(F,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(n,{variant:"primary",onClick:()=>r(!0),"data-testid":"clipboard-add",children:[e.jsx(I,{size:14,"aria-hidden":!0})," Save clip"]})]})}),e.jsx(T,{variant:"default",children:e.jsx(D,{children:l.loading&&p.length===0?e.jsxs(h,{gap:1,children:[e.jsx(y,{style:{height:60}}),e.jsx(y,{style:{height:60}})]}):p.length===0?e.jsx(L,{icon:e.jsx(w,{size:28,"aria-hidden":!0}),title:"No saved clips",description:"Save one with a URL + content."}):e.jsx(h,{gap:1,children:p.map(t=>{const i=x===t.id;return e.jsxs("div",{"data-testid":`clipboard-row-${t.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)"},children:[e.jsxs(f,{align:"center",justify:"between",gap:2,children:[e.jsxs(h,{gap:0,style:{minWidth:0,flex:1},children:[e.jsxs(f,{align:"center",gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:t.title||t.id}),t.url&&e.jsxs("a",{href:t.url,target:"_blank",rel:"noreferrer",style:{fontSize:"var(--fs-11)",color:"var(--accent)"},children:[e.jsx(P,{size:10,"aria-hidden":!0,style:{verticalAlign:"middle"}})," ",t.url]}),t.savedAt&&e.jsx("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:t.savedAt})]}),(t.selection||t.content)&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:(t.selection||t.content||"").length>200?`${(t.selection||t.content||"").slice(0,200)}…`:t.selection||t.content})]}),e.jsx(n,{variant:"ghost",onClick:()=>o(m=>m===t.id?null:t.id),"data-testid":`clipboard-delete-${t.id}`,"aria-label":`Delete ${t.id}`,children:e.jsx(U,{size:14,"aria-hidden":!0})})]}),i&&e.jsxs(f,{gap:1,style:{marginTop:"var(--space-1)"},children:[e.jsx(n,{variant:"danger",onClick:()=>void g(t.id),"data-testid":`clipboard-confirm-delete-${t.id}`,children:"Confirm delete"}),e.jsx(n,{variant:"ghost",onClick:()=>o(null),children:"Cancel"})]})]},t.id)})})})}),e.jsx(R,{open:v,onOpenChange:r,children:e.jsx($,{side:"right",title:"Save clip",description:"URL or content required.",children:e.jsx(A,{onSubmit:async t=>{await S("/api/clipboard/save",{method:"POST",body:t}),r(!1),c()},onCancel:()=>r(!1)})})})]})}function A({onSubmit:l,onCancel:v}){const[r,x]=s.useState(""),[o,u]=s.useState(""),[d,p]=s.useState(""),[c,g]=s.useState(""),[t,i]=s.useState(!1),[m,j]=s.useState(null);return e.jsxs(h,{gap:3,style:{padding:"var(--space-4)"},children:[e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"URL (optional)"}),e.jsx(b,{value:r,onChange:a=>x(a.target.value),"data-testid":"clipboard-form-url"})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Title (optional)"}),e.jsx(b,{value:o,onChange:a=>u(a.target.value),"data-testid":"clipboard-form-title"})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Content"}),e.jsx(C,{value:d,rows:6,onChange:a=>p(a.target.value),"data-testid":"clipboard-form-content"})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Selection (optional)"}),e.jsx(C,{value:c,rows:3,onChange:a=>g(a.target.value),"data-testid":"clipboard-form-selection"})]}),m!==null&&e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:m}),e.jsxs(f,{justify:"end",gap:2,children:[e.jsx(n,{variant:"ghost",onClick:v,children:"Cancel"}),e.jsx(n,{variant:"primary",disabled:t||!r.trim()&&!d.trim(),"data-testid":"clipboard-form-submit",onClick:async()=>{i(!0),j(null);try{await l({url:r.trim()||void 0,title:o.trim()||void 0,content:d.trim()||void 0,selection:c.trim()||void 0})}catch(a){j((a instanceof z,a.message)),i(!1)}},children:t?"Saving…":"Save"})]})]})}export{Q as ClipboardView};
1
+ import{r as s,j as e}from"./cmdk-C3F6LD6N.js";import{u as k,S as h,I as f,d as n,h as y,_ as w,i as S,F as z}from"./main-BZMmD6a8.js";import{V as E}from"./ViewHeader-BaCWNuVX.js";import{C as T,b as D}from"./Card-BmXiT4c6.js";import{I as b}from"./Input-cAQOvR8U.js";import{T as C}from"./Textarea-CcQGSgSH.js";import{S as R,a as $}from"./Sheet-CxXf6gvC.js";import{E as L}from"./EmptyState-CdDQmfEL.js";import{R as F}from"./refresh-ccw-BL7B0NO1.js";import{P as I}from"./plus-uA5Ecuch.js";import{E as P}from"./external-link-C4pHGbz2.js";import{T as U}from"./trash-2-B885GY46.js";function Q(){const l=k("/api/clipboard/list"),[v,r]=s.useState(!1),[x,o]=s.useState(null),[u,d]=s.useState(null),p=s.useMemo(()=>{var t;return((t=l.data)==null?void 0:t.clips)??[]},[l.data]),c=s.useCallback(()=>{l.refetch()},[l]),g=async t=>{d(null);try{await S(`/api/clipboard/${t}`,{method:"DELETE"}),o(null),c()}catch(i){d((i instanceof z,i.message))}};return e.jsxs(h,{gap:4,"data-testid":"clipboard-view",children:[e.jsx(E,{title:"Clipboard",description:"Saved clips. Each becomes a markdown note under clips/.",actions:e.jsxs(f,{align:"center",gap:2,children:[u!==null&&e.jsx("span",{role:"alert","data-testid":"clipboard-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:u}),e.jsxs(n,{variant:"ghost",onClick:()=>void c(),"data-testid":"clipboard-refresh",children:[e.jsx(F,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(n,{variant:"primary",onClick:()=>r(!0),"data-testid":"clipboard-add",children:[e.jsx(I,{size:14,"aria-hidden":!0})," Save clip"]})]})}),e.jsx(T,{variant:"default",children:e.jsx(D,{children:l.loading&&p.length===0?e.jsxs(h,{gap:1,children:[e.jsx(y,{style:{height:60}}),e.jsx(y,{style:{height:60}})]}):p.length===0?e.jsx(L,{icon:e.jsx(w,{size:28,"aria-hidden":!0}),title:"No saved clips",description:"Save one with a URL + content."}):e.jsx(h,{gap:1,children:p.map(t=>{const i=x===t.id;return e.jsxs("div",{"data-testid":`clipboard-row-${t.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)"},children:[e.jsxs(f,{align:"center",justify:"between",gap:2,children:[e.jsxs(h,{gap:0,style:{minWidth:0,flex:1},children:[e.jsxs(f,{align:"center",gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:t.title||t.id}),t.url&&e.jsxs("a",{href:t.url,target:"_blank",rel:"noreferrer",style:{fontSize:"var(--fs-11)",color:"var(--accent)"},children:[e.jsx(P,{size:10,"aria-hidden":!0,style:{verticalAlign:"middle"}})," ",t.url]}),t.savedAt&&e.jsx("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:t.savedAt})]}),(t.selection||t.content)&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:(t.selection||t.content||"").length>200?`${(t.selection||t.content||"").slice(0,200)}…`:t.selection||t.content})]}),e.jsx(n,{variant:"ghost",onClick:()=>o(m=>m===t.id?null:t.id),"data-testid":`clipboard-delete-${t.id}`,"aria-label":`Delete ${t.id}`,children:e.jsx(U,{size:14,"aria-hidden":!0})})]}),i&&e.jsxs(f,{gap:1,style:{marginTop:"var(--space-1)"},children:[e.jsx(n,{variant:"danger",onClick:()=>void g(t.id),"data-testid":`clipboard-confirm-delete-${t.id}`,children:"Confirm delete"}),e.jsx(n,{variant:"ghost",onClick:()=>o(null),children:"Cancel"})]})]},t.id)})})})}),e.jsx(R,{open:v,onOpenChange:r,children:e.jsx($,{side:"right",title:"Save clip",description:"URL or content required.",children:e.jsx(A,{onSubmit:async t=>{await S("/api/clipboard/save",{method:"POST",body:t}),r(!1),c()},onCancel:()=>r(!1)})})})]})}function A({onSubmit:l,onCancel:v}){const[r,x]=s.useState(""),[o,u]=s.useState(""),[d,p]=s.useState(""),[c,g]=s.useState(""),[t,i]=s.useState(!1),[m,j]=s.useState(null);return e.jsxs(h,{gap:3,style:{padding:"var(--space-4)"},children:[e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"URL (optional)"}),e.jsx(b,{value:r,onChange:a=>x(a.target.value),"data-testid":"clipboard-form-url"})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Title (optional)"}),e.jsx(b,{value:o,onChange:a=>u(a.target.value),"data-testid":"clipboard-form-title"})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Content"}),e.jsx(C,{value:d,rows:6,onChange:a=>p(a.target.value),"data-testid":"clipboard-form-content"})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Selection (optional)"}),e.jsx(C,{value:c,rows:3,onChange:a=>g(a.target.value),"data-testid":"clipboard-form-selection"})]}),m!==null&&e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:m}),e.jsxs(f,{justify:"end",gap:2,children:[e.jsx(n,{variant:"ghost",onClick:v,children:"Cancel"}),e.jsx(n,{variant:"primary",disabled:t||!r.trim()&&!d.trim(),"data-testid":"clipboard-form-submit",onClick:async()=>{i(!0),j(null);try{await l({url:r.trim()||void 0,title:o.trim()||void 0,content:d.trim()||void 0,selection:c.trim()||void 0})}catch(a){j((a instanceof z,a.message)),i(!1)}},children:t?"Saving…":"Save"})]})]})}export{Q as ClipboardView};
@@ -1 +1 @@
1
- {"version":3,"file":"ClipboardView-DdP6aVso.js","sources":["../../src/web/v8/views/Clipboard/ClipboardView.tsx"],"sourcesContent":["/**\n * v8/views/Clipboard/ClipboardView.tsx — Sprint S43, v9.3.0.\n *\n * Saved clip list (GET /api/clipboard/list), Save Sheet\n * (POST /api/clipboard/save with {url, title, content, selection}),\n * inline-confirm Delete (DELETE /api/clipboard/:id). Each row links\n * to the source URL when present.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { ClipboardPaste, Plus, Trash2, ExternalLink, RefreshCcw } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Textarea } from '../../ui/controls/Textarea.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\ninterface Clip {\n id: string;\n url?: string;\n title?: string;\n content?: string;\n selection?: string;\n savedAt?: string;\n}\n\nexport function ClipboardView(): JSX.Element {\n const payload = useFetch<{ clips: Clip[] }>('/api/clipboard/list');\n const [saving, setSaving] = useState<boolean>(false);\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const clips = useMemo<Clip[]>(() => payload.data?.clips ?? [], [payload.data]);\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n\n const drop = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/clipboard/${id}`, { method: 'DELETE' });\n setConfirmDelete(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n return (\n <Stack gap={4} data-testid=\"clipboard-view\">\n <ViewHeader\n title=\"Clipboard\"\n description=\"Saved clips. Each becomes a markdown note under clips/.\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"clipboard-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"clipboard-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => setSaving(true)} data-testid=\"clipboard-add\">\n <Plus size={14} aria-hidden /> Save clip\n </Button>\n </Inline>\n }\n />\n\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && clips.length === 0 ? (\n <Stack gap={1}>\n <Skeleton style={{ height: 60 }} />\n <Skeleton style={{ height: 60 }} />\n </Stack>\n ) : clips.length === 0 ? (\n <EmptyState icon={<ClipboardPaste size={28} aria-hidden />} title=\"No saved clips\" description=\"Save one with a URL + content.\" />\n ) : (\n <Stack gap={1}>\n {clips.map((c) => {\n const isConfirming = confirmDelete === c.id;\n return (\n <div\n key={c.id}\n data-testid={`clipboard-row-${c.id}`}\n style={{ padding: 'var(--space-2)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)' }}\n >\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Stack gap={0} style={{ minWidth: 0, flex: 1 }}>\n <Inline align=\"center\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>{c.title || c.id}</strong>\n {c.url && (\n <a href={c.url} target=\"_blank\" rel=\"noreferrer\" style={{ fontSize: 'var(--fs-11)', color: 'var(--accent)' }}>\n <ExternalLink size={10} aria-hidden style={{ verticalAlign: 'middle' }} /> {c.url}\n </a>\n )}\n {c.savedAt && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{c.savedAt}</span>}\n </Inline>\n {(c.selection || c.content) && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {(c.selection || c.content || '').length > 200\n ? `${(c.selection || c.content || '').slice(0, 200)}…`\n : (c.selection || c.content)}\n </span>\n )}\n </Stack>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete((cur) => (cur === c.id ? null : c.id))} data-testid={`clipboard-delete-${c.id}`} aria-label={`Delete ${c.id}`}>\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"danger\" onClick={() => void drop(c.id)} data-testid={`clipboard-confirm-delete-${c.id}`}>\n Confirm delete\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete(null)}>Cancel</Button>\n </Inline>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </CardBody>\n </Card>\n\n <Sheet open={saving} onOpenChange={setSaving}>\n <SheetContent side=\"right\" title=\"Save clip\" description=\"URL or content required.\">\n <SaveForm\n onSubmit={async (body) => {\n await fetchJson('/api/clipboard/save', { method: 'POST', body });\n setSaving(false);\n refresh();\n }}\n onCancel={() => setSaving(false)}\n />\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}\n\nfunction SaveForm({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (body: { url?: string; title?: string; content?: string; selection?: string }) => Promise<void>;\n onCancel: () => void;\n}): JSX.Element {\n const [url, setUrl] = useState<string>('');\n const [title, setTitle] = useState<string>('');\n const [content, setContent] = useState<string>('');\n const [selection, setSelection] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n return (\n <Stack gap={3} style={{ padding: 'var(--space-4)' }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>URL (optional)</span>\n <Input value={url} onChange={(e) => setUrl((e.target as HTMLInputElement).value)} data-testid=\"clipboard-form-url\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Title (optional)</span>\n <Input value={title} onChange={(e) => setTitle((e.target as HTMLInputElement).value)} data-testid=\"clipboard-form-title\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Content</span>\n <Textarea value={content} rows={6} onChange={(e) => setContent((e.target as HTMLTextAreaElement).value)} data-testid=\"clipboard-form-content\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Selection (optional)</span>\n <Textarea value={selection} rows={3} onChange={(e) => setSelection((e.target as HTMLTextAreaElement).value)} data-testid=\"clipboard-form-selection\" />\n </label>\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Inline justify=\"end\" gap={2}>\n <Button variant=\"ghost\" onClick={onCancel}>Cancel</Button>\n <Button\n variant=\"primary\"\n disabled={busy || (!url.trim() && !content.trim())}\n data-testid=\"clipboard-form-submit\"\n onClick={async () => {\n setBusy(true);\n setError(null);\n try {\n await onSubmit({\n url: url.trim() || undefined,\n title: title.trim() || undefined,\n content: content.trim() || undefined,\n selection: selection.trim() || undefined,\n });\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n setBusy(false);\n }\n }}\n >\n {busy ? 'Saving…' : 'Save'}\n </Button>\n </Inline>\n </Stack>\n );\n}"],"names":["ClipboardView","payload","useFetch","saving","setSaving","useState","confirmDelete","setConfirmDelete","error","setError","clips","useMemo","_a","refresh","useCallback","drop","id","fetchJson","err","FetchError","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCcw","Plus","Card","CardBody","Skeleton","EmptyState","ClipboardPaste","c","isConfirming","ExternalLink","cur","Trash2","Sheet","SheetContent","SaveForm","body","onSubmit","onCancel","url","setUrl","title","setTitle","content","setContent","selection","setSelection","busy","setBusy","Input","e","Textarea"],"mappings":"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"}
1
+ {"version":3,"file":"ClipboardView-BA323V2J.js","sources":["../../src/web/v8/views/Clipboard/ClipboardView.tsx"],"sourcesContent":["/**\n * v8/views/Clipboard/ClipboardView.tsx — Sprint S43, v9.3.0.\n *\n * Saved clip list (GET /api/clipboard/list), Save Sheet\n * (POST /api/clipboard/save with {url, title, content, selection}),\n * inline-confirm Delete (DELETE /api/clipboard/:id). Each row links\n * to the source URL when present.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { ClipboardPaste, Plus, Trash2, ExternalLink, RefreshCcw } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Textarea } from '../../ui/controls/Textarea.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\ninterface Clip {\n id: string;\n url?: string;\n title?: string;\n content?: string;\n selection?: string;\n savedAt?: string;\n}\n\nexport function ClipboardView(): JSX.Element {\n const payload = useFetch<{ clips: Clip[] }>('/api/clipboard/list');\n const [saving, setSaving] = useState<boolean>(false);\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const clips = useMemo<Clip[]>(() => payload.data?.clips ?? [], [payload.data]);\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n\n const drop = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/clipboard/${id}`, { method: 'DELETE' });\n setConfirmDelete(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n return (\n <Stack gap={4} data-testid=\"clipboard-view\">\n <ViewHeader\n title=\"Clipboard\"\n description=\"Saved clips. Each becomes a markdown note under clips/.\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"clipboard-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"clipboard-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => setSaving(true)} data-testid=\"clipboard-add\">\n <Plus size={14} aria-hidden /> Save clip\n </Button>\n </Inline>\n }\n />\n\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && clips.length === 0 ? (\n <Stack gap={1}>\n <Skeleton style={{ height: 60 }} />\n <Skeleton style={{ height: 60 }} />\n </Stack>\n ) : clips.length === 0 ? (\n <EmptyState icon={<ClipboardPaste size={28} aria-hidden />} title=\"No saved clips\" description=\"Save one with a URL + content.\" />\n ) : (\n <Stack gap={1}>\n {clips.map((c) => {\n const isConfirming = confirmDelete === c.id;\n return (\n <div\n key={c.id}\n data-testid={`clipboard-row-${c.id}`}\n style={{ padding: 'var(--space-2)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)' }}\n >\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Stack gap={0} style={{ minWidth: 0, flex: 1 }}>\n <Inline align=\"center\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>{c.title || c.id}</strong>\n {c.url && (\n <a href={c.url} target=\"_blank\" rel=\"noreferrer\" style={{ fontSize: 'var(--fs-11)', color: 'var(--accent)' }}>\n <ExternalLink size={10} aria-hidden style={{ verticalAlign: 'middle' }} /> {c.url}\n </a>\n )}\n {c.savedAt && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{c.savedAt}</span>}\n </Inline>\n {(c.selection || c.content) && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {(c.selection || c.content || '').length > 200\n ? `${(c.selection || c.content || '').slice(0, 200)}…`\n : (c.selection || c.content)}\n </span>\n )}\n </Stack>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete((cur) => (cur === c.id ? null : c.id))} data-testid={`clipboard-delete-${c.id}`} aria-label={`Delete ${c.id}`}>\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"danger\" onClick={() => void drop(c.id)} data-testid={`clipboard-confirm-delete-${c.id}`}>\n Confirm delete\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete(null)}>Cancel</Button>\n </Inline>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </CardBody>\n </Card>\n\n <Sheet open={saving} onOpenChange={setSaving}>\n <SheetContent side=\"right\" title=\"Save clip\" description=\"URL or content required.\">\n <SaveForm\n onSubmit={async (body) => {\n await fetchJson('/api/clipboard/save', { method: 'POST', body });\n setSaving(false);\n refresh();\n }}\n onCancel={() => setSaving(false)}\n />\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}\n\nfunction SaveForm({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (body: { url?: string; title?: string; content?: string; selection?: string }) => Promise<void>;\n onCancel: () => void;\n}): JSX.Element {\n const [url, setUrl] = useState<string>('');\n const [title, setTitle] = useState<string>('');\n const [content, setContent] = useState<string>('');\n const [selection, setSelection] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n return (\n <Stack gap={3} style={{ padding: 'var(--space-4)' }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>URL (optional)</span>\n <Input value={url} onChange={(e) => setUrl((e.target as HTMLInputElement).value)} data-testid=\"clipboard-form-url\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Title (optional)</span>\n <Input value={title} onChange={(e) => setTitle((e.target as HTMLInputElement).value)} data-testid=\"clipboard-form-title\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Content</span>\n <Textarea value={content} rows={6} onChange={(e) => setContent((e.target as HTMLTextAreaElement).value)} data-testid=\"clipboard-form-content\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Selection (optional)</span>\n <Textarea value={selection} rows={3} onChange={(e) => setSelection((e.target as HTMLTextAreaElement).value)} data-testid=\"clipboard-form-selection\" />\n </label>\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Inline justify=\"end\" gap={2}>\n <Button variant=\"ghost\" onClick={onCancel}>Cancel</Button>\n <Button\n variant=\"primary\"\n disabled={busy || (!url.trim() && !content.trim())}\n data-testid=\"clipboard-form-submit\"\n onClick={async () => {\n setBusy(true);\n setError(null);\n try {\n await onSubmit({\n url: url.trim() || undefined,\n title: title.trim() || undefined,\n content: content.trim() || undefined,\n selection: selection.trim() || undefined,\n });\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n setBusy(false);\n }\n }}\n >\n {busy ? 'Saving…' : 'Save'}\n </Button>\n </Inline>\n </Stack>\n );\n}"],"names":["ClipboardView","payload","useFetch","saving","setSaving","useState","confirmDelete","setConfirmDelete","error","setError","clips","useMemo","_a","refresh","useCallback","drop","id","fetchJson","err","FetchError","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCcw","Plus","Card","CardBody","Skeleton","EmptyState","ClipboardPaste","c","isConfirming","ExternalLink","cur","Trash2","Sheet","SheetContent","SaveForm","body","onSubmit","onCancel","url","setUrl","title","setTitle","content","setContent","selection","setSelection","busy","setBusy","Input","e","Textarea"],"mappings":"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"}
@@ -1 +1 @@
1
- import{r as t,j as e}from"./cmdk-DVxytz9i.js";import{S as v,I as o,k as I,j as w,Q as L,u as y,d as c,h as S,i as z,F as k}from"./main-Cxeu4LhG.js";import{V as D}from"./ViewHeader-B6P-C4GD.js";import{C as b,b as C}from"./Card-rF59wHiO.js";import{I as P}from"./Input-CZmRw5QX.js";import{E}from"./EmptyState-D65J5FQN.js";import{P as R}from"./plug-BKuyIe5W.js";import{R as M}from"./refresh-ccw-DenGBOcq.js";import{S as $}from"./save-Db1b-1Uq.js";import{P as T}from"./plus-77h62zZm.js";import{P as A}from"./pencil-DVrBlYV3.js";import{T as B}from"./trash-2-Cv7U38jw.js";const F=[{id:"runtime",label:"Runtime config",icon:I},{id:"providers",label:"Providers",icon:w},{id:"mcps",label:"MCPs",icon:R},{id:"system-llm",label:"System LLM",icon:L}];function se(){const[s,n]=t.useState("runtime");return e.jsxs(v,{gap:4,"data-testid":"config-view",children:[e.jsx(D,{title:"Config",description:"Runtime config + providers + MCPs + system LLM."}),e.jsx(o,{gap:1,role:"tablist",children:F.map(r=>e.jsxs("button",{type:"button",role:"tab","aria-selected":s===r.id,onClick:()=>n(r.id),"data-testid":`config-tab-${r.id}`,style:{padding:"var(--space-2) var(--space-3)",borderRadius:"var(--radius-md)",border:"1px solid var(--border)",background:s===r.id?"color-mix(in oklch, var(--accent) 14%, transparent)":"var(--surface-0)",color:s===r.id?"var(--accent)":"var(--fg-muted)",fontSize:"var(--fs-12)",cursor:"pointer"},children:[e.jsx(r.icon,{size:14,"aria-hidden":!0,style:{verticalAlign:"middle",marginRight:6}}),r.label]},r.id))}),s==="runtime"&&e.jsx(N,{}),s==="providers"&&e.jsx(V,{}),s==="mcps"&&e.jsx(U,{}),s==="system-llm"&&e.jsx(H,{})]})}function N(){var h;const s=y("/api/config"),[n,r]=t.useState(""),[i,m]=t.useState(!1),[x,l]=t.useState(!1),[f,u]=t.useState(null);t.useEffect(()=>{var a;((a=s.data)==null?void 0:a.raw)!==void 0&&r(s.data.raw)},[(h=s.data)==null?void 0:h.raw]);const j=t.useCallback(()=>{s.refetch()},[s]),g=async()=>{m(!0),u(null),l(!1);try{await z("/api/config",{method:"PUT",body:n}),l(!0),j()}catch(a){u((a instanceof k,a.message))}finally{m(!1)}};return e.jsx(b,{variant:"default",children:e.jsx(C,{children:e.jsxs(v,{gap:2,children:[e.jsxs(o,{align:"center",justify:"between",gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Runtime config"}),e.jsxs(o,{gap:1,children:[e.jsxs(c,{variant:"ghost",onClick:j,"data-testid":"config-runtime-reload",children:[e.jsx(M,{size:14,"aria-hidden":!0})," Reload"]}),e.jsxs(c,{variant:"primary",onClick:()=>void g(),disabled:i,"data-testid":"config-runtime-save",children:[e.jsx($,{size:14,"aria-hidden":!0})," ",i?"Saving…":"Save"]})]})]}),s.loading&&s.data===null?e.jsx(S,{style:{height:240}}):e.jsx("textarea",{value:n,rows:16,"data-testid":"config-runtime-raw",onChange:a=>r(a.target.value),style:{background:"var(--surface-0)",border:"1px solid var(--border)",borderRadius:"var(--radius-md)",padding:"var(--space-2)",color:"var(--fg)",fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",resize:"vertical"}}),x&&e.jsx("span",{"data-testid":"config-runtime-saved",style:{color:"var(--success)",fontSize:"var(--fs-12)"},children:"Saved"}),f!==null&&e.jsx("span",{role:"alert","data-testid":"config-runtime-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:f})]})})})}function V(){const s=y("/api/config/providers"),[n,r]=t.useState(!1),[i,m]=t.useState(null),[x,l]=t.useState(null),[f,u]=t.useState(null),j=t.useCallback(()=>{s.refetch()},[s]),g=t.useMemo(()=>{var a;return((a=s.data)==null?void 0:a.providers)??[]},[s.data]),h=async a=>{u(null);try{await z(`/api/config/providers/${a}`,{method:"DELETE"}),l(null),j()}catch(p){u((p instanceof k,p.message))}};return e.jsx(b,{variant:"default",children:e.jsx(C,{children:e.jsxs(v,{gap:2,children:[e.jsxs(o,{align:"center",justify:"between",gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Providers"}),e.jsxs(o,{gap:1,children:[f!==null&&e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:f}),e.jsxs(c,{variant:"primary",onClick:()=>r(!0),"data-testid":"config-providers-add",children:[e.jsx(T,{size:14,"aria-hidden":!0})," Add"]})]})]}),s.loading&&g.length===0?e.jsx(S,{style:{height:100}}):g.length===0?e.jsx(E,{icon:e.jsx(w,{size:28,"aria-hidden":!0}),title:"No providers",description:"Add one or use Auto-add with key."}):e.jsx(v,{gap:1,children:g.map(a=>{const p=x===a.id;return e.jsxs("div",{"data-testid":`config-provider-row-${a.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)"},children:[e.jsxs(o,{align:"center",justify:"between",gap:2,children:[e.jsxs(o,{align:"center",gap:2,children:[e.jsx("strong",{children:a.name||a.id}),a.groupId&&e.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:["group=",a.groupId]})]}),e.jsxs(o,{gap:1,children:[e.jsx(c,{variant:"ghost",onClick:()=>m(a.id),"data-testid":`config-provider-edit-${a.id}`,"aria-label":`Edit ${a.id}`,children:e.jsx(A,{size:14,"aria-hidden":!0})}),e.jsx(c,{variant:"ghost",onClick:()=>l(d=>d===a.id?null:a.id),"data-testid":`config-provider-delete-${a.id}`,"aria-label":`Delete ${a.id}`,children:e.jsx(B,{size:14,"aria-hidden":!0})})]})]}),p&&e.jsxs(o,{gap:1,style:{marginTop:"var(--space-1)"},children:[e.jsx(c,{variant:"danger",onClick:()=>void h(a.id),"data-testid":`config-provider-confirm-delete-${a.id}`,children:"Confirm delete"}),e.jsx(c,{variant:"ghost",onClick:()=>l(null),children:"Cancel"})]})]},a.id)})})]})})})}function U(){const s=y("/api/config/mcps"),n=t.useMemo(()=>{var i;return((i=s.data)==null?void 0:i.mcps)??[]},[s.data]),r=t.useCallback(()=>{s.refetch()},[s]);return e.jsx(b,{variant:"default",children:e.jsx(C,{children:e.jsxs(v,{gap:2,children:[e.jsx(o,{align:"center",justify:"between",gap:2,children:e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"MCP servers"})}),s.loading&&n.length===0?e.jsx(S,{style:{height:60}}):n.length===0?e.jsx(E,{icon:e.jsx(R,{size:28,"aria-hidden":!0}),title:"No MCPs",description:"Add one via /api/config/mcps."}):e.jsx(v,{gap:1,children:n.map(i=>e.jsxs("div",{"data-testid":`config-mcp-row-${i.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",display:"flex",justifyContent:"space-between"},children:[e.jsx("strong",{children:i.name||i.id}),i.command&&e.jsx("code",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:i.command})]},i.id))}),e.jsxs(c,{variant:"ghost",onClick:r,"data-testid":"config-mcps-refresh",children:[e.jsx(M,{size:14,"aria-hidden":!0})," Refresh"]})]})})})}function H(){const s=y("/api/llm/system-llm"),[n,r]=t.useState(!1),[i,m]=t.useState(""),[x,l]=t.useState(""),[f,u]=t.useState(!1),[j,g]=t.useState(!1),[h,a]=t.useState(null);t.useEffect(()=>{s.data&&(r(s.data.enabled),m(s.data.provider??""),l(s.data.model??""))},[s.data]);const p=async()=>{u(!0),a(null),g(!1);try{await z("/api/llm/system-llm",{method:"PUT",body:{enabled:n,provider:i,model:x}}),g(!0),s.refetch()}catch(d){a((d instanceof k,d.message))}finally{u(!1)}};return e.jsx(b,{variant:"default",children:e.jsx(C,{children:e.jsxs(v,{gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"System LLM"}),s.loading&&s.data===null?e.jsx(S,{style:{height:100}}):e.jsxs(v,{gap:2,children:[e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:"var(--space-2)"},children:[e.jsx("input",{type:"checkbox",checked:n,"data-testid":"config-system-llm-enabled",onChange:d=>r(d.target.checked)}),e.jsx("span",{style:{fontSize:"var(--fs-13)"},children:"Enabled"})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Provider"}),e.jsx(P,{value:i,"data-testid":"config-system-llm-provider",onChange:d=>m(d.target.value)})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Model"}),e.jsx(P,{value:x,"data-testid":"config-system-llm-model",onChange:d=>l(d.target.value)})]}),e.jsx(o,{justify:"end",gap:2,children:e.jsxs(c,{variant:"primary",onClick:()=>void p(),disabled:f,"data-testid":"config-system-llm-save",children:[e.jsx($,{size:14,"aria-hidden":!0})," ",f?"Saving…":"Save"]})}),j&&e.jsx("span",{"data-testid":"config-system-llm-saved",style:{color:"var(--success)",fontSize:"var(--fs-12)"},children:"Saved"}),h!==null&&e.jsx("span",{role:"alert","data-testid":"config-system-llm-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:h})]})]})})})}export{se as ConfigView};
1
+ import{r as t,j as e}from"./cmdk-C3F6LD6N.js";import{S as v,I as o,k as I,j as w,Q as L,u as y,d as c,h as S,i as z,F as k}from"./main-BZMmD6a8.js";import{V as D}from"./ViewHeader-BaCWNuVX.js";import{C as b,b as C}from"./Card-BmXiT4c6.js";import{I as P}from"./Input-cAQOvR8U.js";import{E}from"./EmptyState-CdDQmfEL.js";import{P as R}from"./plug-CG8al2Kq.js";import{R as M}from"./refresh-ccw-BL7B0NO1.js";import{S as $}from"./save-RcZOXR0U.js";import{P as T}from"./plus-uA5Ecuch.js";import{P as A}from"./pencil---XuvKlz.js";import{T as B}from"./trash-2-B885GY46.js";const F=[{id:"runtime",label:"Runtime config",icon:I},{id:"providers",label:"Providers",icon:w},{id:"mcps",label:"MCPs",icon:R},{id:"system-llm",label:"System LLM",icon:L}];function se(){const[s,n]=t.useState("runtime");return e.jsxs(v,{gap:4,"data-testid":"config-view",children:[e.jsx(D,{title:"Config",description:"Runtime config + providers + MCPs + system LLM."}),e.jsx(o,{gap:1,role:"tablist",children:F.map(r=>e.jsxs("button",{type:"button",role:"tab","aria-selected":s===r.id,onClick:()=>n(r.id),"data-testid":`config-tab-${r.id}`,style:{padding:"var(--space-2) var(--space-3)",borderRadius:"var(--radius-md)",border:"1px solid var(--border)",background:s===r.id?"color-mix(in oklch, var(--accent) 14%, transparent)":"var(--surface-0)",color:s===r.id?"var(--accent)":"var(--fg-muted)",fontSize:"var(--fs-12)",cursor:"pointer"},children:[e.jsx(r.icon,{size:14,"aria-hidden":!0,style:{verticalAlign:"middle",marginRight:6}}),r.label]},r.id))}),s==="runtime"&&e.jsx(N,{}),s==="providers"&&e.jsx(V,{}),s==="mcps"&&e.jsx(U,{}),s==="system-llm"&&e.jsx(H,{})]})}function N(){var h;const s=y("/api/config"),[n,r]=t.useState(""),[i,m]=t.useState(!1),[x,l]=t.useState(!1),[f,u]=t.useState(null);t.useEffect(()=>{var a;((a=s.data)==null?void 0:a.raw)!==void 0&&r(s.data.raw)},[(h=s.data)==null?void 0:h.raw]);const j=t.useCallback(()=>{s.refetch()},[s]),g=async()=>{m(!0),u(null),l(!1);try{await z("/api/config",{method:"PUT",body:n}),l(!0),j()}catch(a){u((a instanceof k,a.message))}finally{m(!1)}};return e.jsx(b,{variant:"default",children:e.jsx(C,{children:e.jsxs(v,{gap:2,children:[e.jsxs(o,{align:"center",justify:"between",gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Runtime config"}),e.jsxs(o,{gap:1,children:[e.jsxs(c,{variant:"ghost",onClick:j,"data-testid":"config-runtime-reload",children:[e.jsx(M,{size:14,"aria-hidden":!0})," Reload"]}),e.jsxs(c,{variant:"primary",onClick:()=>void g(),disabled:i,"data-testid":"config-runtime-save",children:[e.jsx($,{size:14,"aria-hidden":!0})," ",i?"Saving…":"Save"]})]})]}),s.loading&&s.data===null?e.jsx(S,{style:{height:240}}):e.jsx("textarea",{value:n,rows:16,"data-testid":"config-runtime-raw",onChange:a=>r(a.target.value),style:{background:"var(--surface-0)",border:"1px solid var(--border)",borderRadius:"var(--radius-md)",padding:"var(--space-2)",color:"var(--fg)",fontFamily:"var(--font-mono)",fontSize:"var(--fs-12)",resize:"vertical"}}),x&&e.jsx("span",{"data-testid":"config-runtime-saved",style:{color:"var(--success)",fontSize:"var(--fs-12)"},children:"Saved"}),f!==null&&e.jsx("span",{role:"alert","data-testid":"config-runtime-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:f})]})})})}function V(){const s=y("/api/config/providers"),[n,r]=t.useState(!1),[i,m]=t.useState(null),[x,l]=t.useState(null),[f,u]=t.useState(null),j=t.useCallback(()=>{s.refetch()},[s]),g=t.useMemo(()=>{var a;return((a=s.data)==null?void 0:a.providers)??[]},[s.data]),h=async a=>{u(null);try{await z(`/api/config/providers/${a}`,{method:"DELETE"}),l(null),j()}catch(p){u((p instanceof k,p.message))}};return e.jsx(b,{variant:"default",children:e.jsx(C,{children:e.jsxs(v,{gap:2,children:[e.jsxs(o,{align:"center",justify:"between",gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Providers"}),e.jsxs(o,{gap:1,children:[f!==null&&e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:f}),e.jsxs(c,{variant:"primary",onClick:()=>r(!0),"data-testid":"config-providers-add",children:[e.jsx(T,{size:14,"aria-hidden":!0})," Add"]})]})]}),s.loading&&g.length===0?e.jsx(S,{style:{height:100}}):g.length===0?e.jsx(E,{icon:e.jsx(w,{size:28,"aria-hidden":!0}),title:"No providers",description:"Add one or use Auto-add with key."}):e.jsx(v,{gap:1,children:g.map(a=>{const p=x===a.id;return e.jsxs("div",{"data-testid":`config-provider-row-${a.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)"},children:[e.jsxs(o,{align:"center",justify:"between",gap:2,children:[e.jsxs(o,{align:"center",gap:2,children:[e.jsx("strong",{children:a.name||a.id}),a.groupId&&e.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:["group=",a.groupId]})]}),e.jsxs(o,{gap:1,children:[e.jsx(c,{variant:"ghost",onClick:()=>m(a.id),"data-testid":`config-provider-edit-${a.id}`,"aria-label":`Edit ${a.id}`,children:e.jsx(A,{size:14,"aria-hidden":!0})}),e.jsx(c,{variant:"ghost",onClick:()=>l(d=>d===a.id?null:a.id),"data-testid":`config-provider-delete-${a.id}`,"aria-label":`Delete ${a.id}`,children:e.jsx(B,{size:14,"aria-hidden":!0})})]})]}),p&&e.jsxs(o,{gap:1,style:{marginTop:"var(--space-1)"},children:[e.jsx(c,{variant:"danger",onClick:()=>void h(a.id),"data-testid":`config-provider-confirm-delete-${a.id}`,children:"Confirm delete"}),e.jsx(c,{variant:"ghost",onClick:()=>l(null),children:"Cancel"})]})]},a.id)})})]})})})}function U(){const s=y("/api/config/mcps"),n=t.useMemo(()=>{var i;return((i=s.data)==null?void 0:i.mcps)??[]},[s.data]),r=t.useCallback(()=>{s.refetch()},[s]);return e.jsx(b,{variant:"default",children:e.jsx(C,{children:e.jsxs(v,{gap:2,children:[e.jsx(o,{align:"center",justify:"between",gap:2,children:e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"MCP servers"})}),s.loading&&n.length===0?e.jsx(S,{style:{height:60}}):n.length===0?e.jsx(E,{icon:e.jsx(R,{size:28,"aria-hidden":!0}),title:"No MCPs",description:"Add one via /api/config/mcps."}):e.jsx(v,{gap:1,children:n.map(i=>e.jsxs("div",{"data-testid":`config-mcp-row-${i.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",display:"flex",justifyContent:"space-between"},children:[e.jsx("strong",{children:i.name||i.id}),i.command&&e.jsx("code",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:i.command})]},i.id))}),e.jsxs(c,{variant:"ghost",onClick:r,"data-testid":"config-mcps-refresh",children:[e.jsx(M,{size:14,"aria-hidden":!0})," Refresh"]})]})})})}function H(){const s=y("/api/llm/system-llm"),[n,r]=t.useState(!1),[i,m]=t.useState(""),[x,l]=t.useState(""),[f,u]=t.useState(!1),[j,g]=t.useState(!1),[h,a]=t.useState(null);t.useEffect(()=>{s.data&&(r(s.data.enabled),m(s.data.provider??""),l(s.data.model??""))},[s.data]);const p=async()=>{u(!0),a(null),g(!1);try{await z("/api/llm/system-llm",{method:"PUT",body:{enabled:n,provider:i,model:x}}),g(!0),s.refetch()}catch(d){a((d instanceof k,d.message))}finally{u(!1)}};return e.jsx(b,{variant:"default",children:e.jsx(C,{children:e.jsxs(v,{gap:2,children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"System LLM"}),s.loading&&s.data===null?e.jsx(S,{style:{height:100}}):e.jsxs(v,{gap:2,children:[e.jsxs("label",{style:{display:"flex",alignItems:"center",gap:"var(--space-2)"},children:[e.jsx("input",{type:"checkbox",checked:n,"data-testid":"config-system-llm-enabled",onChange:d=>r(d.target.checked)}),e.jsx("span",{style:{fontSize:"var(--fs-13)"},children:"Enabled"})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Provider"}),e.jsx(P,{value:i,"data-testid":"config-system-llm-provider",onChange:d=>m(d.target.value)})]}),e.jsxs("label",{style:{display:"flex",flexDirection:"column",gap:"var(--space-1)"},children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Model"}),e.jsx(P,{value:x,"data-testid":"config-system-llm-model",onChange:d=>l(d.target.value)})]}),e.jsx(o,{justify:"end",gap:2,children:e.jsxs(c,{variant:"primary",onClick:()=>void p(),disabled:f,"data-testid":"config-system-llm-save",children:[e.jsx($,{size:14,"aria-hidden":!0})," ",f?"Saving…":"Save"]})}),j&&e.jsx("span",{"data-testid":"config-system-llm-saved",style:{color:"var(--success)",fontSize:"var(--fs-12)"},children:"Saved"}),h!==null&&e.jsx("span",{role:"alert","data-testid":"config-system-llm-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:h})]})]})})})}export{se as ConfigView};
@@ -1 +1 @@
1
- {"version":3,"file":"ConfigView-B2ysnTZU.js","sources":["../../src/web/v8/views/Config/ConfigView.tsx"],"sourcesContent":["/**\n * v8/views/Config/ConfigView.tsx — Sprint S41, v9.3.0.\n *\n * Three sub-sections:\n * - Runtime config: read-only viewer + Reload + Save (PUT\n * /api/config with the edited raw JSON).\n * - Providers: full CRUD via /api/config/providers + the\n * \"add with key\" auto endpoint.\n * - MCPs: full CRUD via /api/config/mcps.\n * - System LLM: read/write the cline.json#systemLlm block via\n * /api/llm/system-llm.\n *\n * Inline confirm for delete. Sheet form for Add / Edit.\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Plus, Pencil, Trash2, RefreshCcw, Save, ServerCog, Cpu, Plug, Settings as SettingsIcon } from 'lucide-react';\nimport type { LucideIcon } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Sheet, SheetClose, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\ninterface Provider {\n id: string;\n name?: string;\n groupId?: string;\n}\n\ninterface Mcp {\n id: string;\n name?: string;\n command?: string;\n}\n\ninterface SystemLlm {\n enabled: boolean;\n provider: string | null;\n model: string | null;\n}\n\ninterface RuntimeConfig {\n path: string;\n data: unknown;\n raw: string;\n exists: boolean;\n}\n\ntype SectionId = 'runtime' | 'providers' | 'mcps' | 'system-llm';\n\nconst SECTIONS: Array<{ id: SectionId; label: string; icon: LucideIcon }> = [\n { id: 'runtime', label: 'Runtime config', icon: SettingsIcon },\n { id: 'providers', label: 'Providers', icon: Cpu },\n { id: 'mcps', label: 'MCPs', icon: Plug },\n { id: 'system-llm', label: 'System LLM', icon: ServerCog },\n];\n\nexport function ConfigView(): JSX.Element {\n const [section, setSection] = useState<SectionId>('runtime');\n return (\n <Stack gap={4} data-testid=\"config-view\">\n <ViewHeader\n title=\"Config\"\n description=\"Runtime config + providers + MCPs + system LLM.\"\n />\n <Inline gap={1} role=\"tablist\">\n {SECTIONS.map((s) => (\n <button\n key={s.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={section === s.id}\n onClick={() => setSection(s.id)}\n data-testid={`config-tab-${s.id}`}\n style={{\n padding: 'var(--space-2) var(--space-3)',\n borderRadius: 'var(--radius-md)',\n border: '1px solid var(--border)',\n background: section === s.id ? 'color-mix(in oklch, var(--accent) 14%, transparent)' : 'var(--surface-0)',\n color: section === s.id ? 'var(--accent)' : 'var(--fg-muted)',\n fontSize: 'var(--fs-12)',\n cursor: 'pointer',\n }}\n >\n <s.icon size={14} aria-hidden style={{ verticalAlign: 'middle', marginRight: 6 }} />\n {s.label}\n </button>\n ))}\n </Inline>\n {section === 'runtime' && <RuntimeConfigPanel />}\n {section === 'providers' && <ProvidersPanel />}\n {section === 'mcps' && <McpsPanel />}\n {section === 'system-llm' && <SystemLlmPanel />}\n </Stack>\n );\n}\n\nfunction RuntimeConfigPanel(): JSX.Element {\n const payload = useFetch<RuntimeConfig>('/api/config');\n const [draft, setDraft] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [saved, setSaved] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (payload.data?.raw !== undefined) setDraft(payload.data.raw);\n }, [payload.data?.raw]);\n\n const reload = useCallback(() => { void payload.refetch(); }, [payload]);\n\n const save = async (): Promise<void> => {\n setBusy(true);\n setError(null);\n setSaved(false);\n try {\n await fetchJson('/api/config', { method: 'PUT', body: draft });\n setSaved(true);\n reload();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Runtime config</strong>\n <Inline gap={1}>\n <Button variant=\"ghost\" onClick={reload} data-testid=\"config-runtime-reload\">\n <RefreshCcw size={14} aria-hidden /> Reload\n </Button>\n <Button variant=\"primary\" onClick={() => void save()} disabled={busy} data-testid=\"config-runtime-save\">\n <Save size={14} aria-hidden /> {busy ? 'Saving…' : 'Save'}\n </Button>\n </Inline>\n </Inline>\n {payload.loading && payload.data === null ? (\n <Skeleton style={{ height: 240 }} />\n ) : (\n <textarea\n value={draft}\n rows={16}\n data-testid=\"config-runtime-raw\"\n onChange={(e) => setDraft((e.target as HTMLTextAreaElement).value)}\n style={{\n background: 'var(--surface-0)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-md)',\n padding: 'var(--space-2)',\n color: 'var(--fg)',\n fontFamily: 'var(--font-mono)',\n fontSize: 'var(--fs-12)',\n resize: 'vertical',\n }}\n />\n )}\n {saved && <span data-testid=\"config-runtime-saved\" style={{ color: 'var(--success)', fontSize: 'var(--fs-12)' }}>Saved</span>}\n {error !== null && (\n <span role=\"alert\" data-testid=\"config-runtime-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n </Stack>\n </CardBody>\n </Card>\n );\n}\n\nfunction ProvidersPanel(): JSX.Element {\n const payload = useFetch<{ providers: Provider[] }>('/api/config/providers');\n const [adding, setAdding] = useState<boolean>(false);\n const [editing, setEditing] = useState<string | null>(null);\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n const providers = useMemo(() => payload.data?.providers ?? [], [payload.data]);\n\n const drop = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/config/providers/${id}`, { method: 'DELETE' });\n setConfirmDelete(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n return (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Providers</strong>\n <Inline gap={1}>\n {error !== null && (\n <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Button variant=\"primary\" onClick={() => setAdding(true)} data-testid=\"config-providers-add\">\n <Plus size={14} aria-hidden /> Add\n </Button>\n </Inline>\n </Inline>\n {payload.loading && providers.length === 0 ? (\n <Skeleton style={{ height: 100 }} />\n ) : providers.length === 0 ? (\n <EmptyState icon={<Cpu size={28} aria-hidden />} title=\"No providers\" description=\"Add one or use Auto-add with key.\" />\n ) : (\n <Stack gap={1}>\n {providers.map((p) => {\n const isConfirming = confirmDelete === p.id;\n return (\n <div key={p.id} data-testid={`config-provider-row-${p.id}`} style={{ padding: 'var(--space-2)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)' }}>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Inline align=\"center\" gap={2}>\n <strong>{p.name || p.id}</strong>\n {p.groupId && <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>group={p.groupId}</span>}\n </Inline>\n <Inline gap={1}>\n <Button variant=\"ghost\" onClick={() => setEditing(p.id)} data-testid={`config-provider-edit-${p.id}`} aria-label={`Edit ${p.id}`}>\n <Pencil size={14} aria-hidden />\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete((cur) => (cur === p.id ? null : p.id))} data-testid={`config-provider-delete-${p.id}`} aria-label={`Delete ${p.id}`}>\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n </Inline>\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"danger\" onClick={() => void drop(p.id)} data-testid={`config-provider-confirm-delete-${p.id}`}>Confirm delete</Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete(null)}>Cancel</Button>\n </Inline>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </Stack>\n </CardBody>\n </Card>\n );\n}\n\nfunction McpsPanel(): JSX.Element {\n const payload = useFetch<{ mcps: Mcp[] }>('/api/config/mcps');\n const mcps = useMemo(() => payload.data?.mcps ?? [], [payload.data]);\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n return (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>MCP servers</strong>\n </Inline>\n {payload.loading && mcps.length === 0 ? (\n <Skeleton style={{ height: 60 }} />\n ) : mcps.length === 0 ? (\n <EmptyState icon={<Plug size={28} aria-hidden />} title=\"No MCPs\" description=\"Add one via /api/config/mcps.\" />\n ) : (\n <Stack gap={1}>\n {mcps.map((m) => (\n <div key={m.id} data-testid={`config-mcp-row-${m.id}`} style={{ padding: 'var(--space-2)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)', display: 'flex', justifyContent: 'space-between' }}>\n <strong>{m.name || m.id}</strong>\n {m.command && <code style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{m.command}</code>}\n </div>\n ))}\n </Stack>\n )}\n <Button variant=\"ghost\" onClick={refresh} data-testid=\"config-mcps-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n </Stack>\n </CardBody>\n </Card>\n );\n}\n\nfunction SystemLlmPanel(): JSX.Element {\n const payload = useFetch<SystemLlm>('/api/llm/system-llm');\n const [enabled, setEnabled] = useState<boolean>(false);\n const [provider, setProvider] = useState<string>('');\n const [model, setModel] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [saved, setSaved] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (payload.data) {\n setEnabled(payload.data.enabled);\n setProvider(payload.data.provider ?? '');\n setModel(payload.data.model ?? '');\n }\n }, [payload.data]);\n\n const save = async (): Promise<void> => {\n setBusy(true);\n setError(null);\n setSaved(false);\n try {\n await fetchJson('/api/llm/system-llm', {\n method: 'PUT',\n body: { enabled, provider, model },\n });\n setSaved(true);\n void payload.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>System LLM</strong>\n {payload.loading && payload.data === null ? (\n <Skeleton style={{ height: 100 }} />\n ) : (\n <Stack gap={2}>\n <label style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>\n <input\n type=\"checkbox\"\n checked={enabled}\n data-testid=\"config-system-llm-enabled\"\n onChange={(e) => setEnabled((e.target as HTMLInputElement).checked)}\n />\n <span style={{ fontSize: 'var(--fs-13)' }}>Enabled</span>\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Provider</span>\n <Input value={provider} data-testid=\"config-system-llm-provider\" onChange={(e) => setProvider((e.target as HTMLInputElement).value)} />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Model</span>\n <Input value={model} data-testid=\"config-system-llm-model\" onChange={(e) => setModel((e.target as HTMLInputElement).value)} />\n </label>\n <Inline justify=\"end\" gap={2}>\n <Button variant=\"primary\" onClick={() => void save()} disabled={busy} data-testid=\"config-system-llm-save\">\n <Save size={14} aria-hidden /> {busy ? 'Saving…' : 'Save'}\n </Button>\n </Inline>\n {saved && <span data-testid=\"config-system-llm-saved\" style={{ color: 'var(--success)', fontSize: 'var(--fs-12)' }}>Saved</span>}\n {error !== null && (\n <span role=\"alert\" data-testid=\"config-system-llm-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n </Stack>\n )}\n </Stack>\n </CardBody>\n </Card>\n );\n}"],"names":["SECTIONS","SettingsIcon","Cpu","Plug","ServerCog","ConfigView","section","setSection","useState","jsxs","Stack","jsx","ViewHeader","Inline","s","RuntimeConfigPanel","ProvidersPanel","McpsPanel","SystemLlmPanel","payload","useFetch","draft","setDraft","busy","setBusy","saved","setSaved","error","setError","useEffect","_a","reload","useCallback","save","fetchJson","err","FetchError","Card","CardBody","Button","RefreshCcw","Save","Skeleton","e","adding","setAdding","editing","setEditing","confirmDelete","setConfirmDelete","refresh","providers","useMemo","drop","id","Plus","EmptyState","p","isConfirming","Pencil","cur","Trash2","mcps","m","enabled","setEnabled","provider","setProvider","model","setModel","Input"],"mappings":"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"}
1
+ {"version":3,"file":"ConfigView-BMBgifw5.js","sources":["../../src/web/v8/views/Config/ConfigView.tsx"],"sourcesContent":["/**\n * v8/views/Config/ConfigView.tsx — Sprint S41, v9.3.0.\n *\n * Three sub-sections:\n * - Runtime config: read-only viewer + Reload + Save (PUT\n * /api/config with the edited raw JSON).\n * - Providers: full CRUD via /api/config/providers + the\n * \"add with key\" auto endpoint.\n * - MCPs: full CRUD via /api/config/mcps.\n * - System LLM: read/write the cline.json#systemLlm block via\n * /api/llm/system-llm.\n *\n * Inline confirm for delete. Sheet form for Add / Edit.\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Plus, Pencil, Trash2, RefreshCcw, Save, ServerCog, Cpu, Plug, Settings as SettingsIcon } from 'lucide-react';\nimport type { LucideIcon } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Input } from '../../ui/controls/Input.js';\nimport { Sheet, SheetClose, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\ninterface Provider {\n id: string;\n name?: string;\n groupId?: string;\n}\n\ninterface Mcp {\n id: string;\n name?: string;\n command?: string;\n}\n\ninterface SystemLlm {\n enabled: boolean;\n provider: string | null;\n model: string | null;\n}\n\ninterface RuntimeConfig {\n path: string;\n data: unknown;\n raw: string;\n exists: boolean;\n}\n\ntype SectionId = 'runtime' | 'providers' | 'mcps' | 'system-llm';\n\nconst SECTIONS: Array<{ id: SectionId; label: string; icon: LucideIcon }> = [\n { id: 'runtime', label: 'Runtime config', icon: SettingsIcon },\n { id: 'providers', label: 'Providers', icon: Cpu },\n { id: 'mcps', label: 'MCPs', icon: Plug },\n { id: 'system-llm', label: 'System LLM', icon: ServerCog },\n];\n\nexport function ConfigView(): JSX.Element {\n const [section, setSection] = useState<SectionId>('runtime');\n return (\n <Stack gap={4} data-testid=\"config-view\">\n <ViewHeader\n title=\"Config\"\n description=\"Runtime config + providers + MCPs + system LLM.\"\n />\n <Inline gap={1} role=\"tablist\">\n {SECTIONS.map((s) => (\n <button\n key={s.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={section === s.id}\n onClick={() => setSection(s.id)}\n data-testid={`config-tab-${s.id}`}\n style={{\n padding: 'var(--space-2) var(--space-3)',\n borderRadius: 'var(--radius-md)',\n border: '1px solid var(--border)',\n background: section === s.id ? 'color-mix(in oklch, var(--accent) 14%, transparent)' : 'var(--surface-0)',\n color: section === s.id ? 'var(--accent)' : 'var(--fg-muted)',\n fontSize: 'var(--fs-12)',\n cursor: 'pointer',\n }}\n >\n <s.icon size={14} aria-hidden style={{ verticalAlign: 'middle', marginRight: 6 }} />\n {s.label}\n </button>\n ))}\n </Inline>\n {section === 'runtime' && <RuntimeConfigPanel />}\n {section === 'providers' && <ProvidersPanel />}\n {section === 'mcps' && <McpsPanel />}\n {section === 'system-llm' && <SystemLlmPanel />}\n </Stack>\n );\n}\n\nfunction RuntimeConfigPanel(): JSX.Element {\n const payload = useFetch<RuntimeConfig>('/api/config');\n const [draft, setDraft] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [saved, setSaved] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (payload.data?.raw !== undefined) setDraft(payload.data.raw);\n }, [payload.data?.raw]);\n\n const reload = useCallback(() => { void payload.refetch(); }, [payload]);\n\n const save = async (): Promise<void> => {\n setBusy(true);\n setError(null);\n setSaved(false);\n try {\n await fetchJson('/api/config', { method: 'PUT', body: draft });\n setSaved(true);\n reload();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Runtime config</strong>\n <Inline gap={1}>\n <Button variant=\"ghost\" onClick={reload} data-testid=\"config-runtime-reload\">\n <RefreshCcw size={14} aria-hidden /> Reload\n </Button>\n <Button variant=\"primary\" onClick={() => void save()} disabled={busy} data-testid=\"config-runtime-save\">\n <Save size={14} aria-hidden /> {busy ? 'Saving…' : 'Save'}\n </Button>\n </Inline>\n </Inline>\n {payload.loading && payload.data === null ? (\n <Skeleton style={{ height: 240 }} />\n ) : (\n <textarea\n value={draft}\n rows={16}\n data-testid=\"config-runtime-raw\"\n onChange={(e) => setDraft((e.target as HTMLTextAreaElement).value)}\n style={{\n background: 'var(--surface-0)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-md)',\n padding: 'var(--space-2)',\n color: 'var(--fg)',\n fontFamily: 'var(--font-mono)',\n fontSize: 'var(--fs-12)',\n resize: 'vertical',\n }}\n />\n )}\n {saved && <span data-testid=\"config-runtime-saved\" style={{ color: 'var(--success)', fontSize: 'var(--fs-12)' }}>Saved</span>}\n {error !== null && (\n <span role=\"alert\" data-testid=\"config-runtime-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n </Stack>\n </CardBody>\n </Card>\n );\n}\n\nfunction ProvidersPanel(): JSX.Element {\n const payload = useFetch<{ providers: Provider[] }>('/api/config/providers');\n const [adding, setAdding] = useState<boolean>(false);\n const [editing, setEditing] = useState<string | null>(null);\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n const providers = useMemo(() => payload.data?.providers ?? [], [payload.data]);\n\n const drop = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/config/providers/${id}`, { method: 'DELETE' });\n setConfirmDelete(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n return (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Providers</strong>\n <Inline gap={1}>\n {error !== null && (\n <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Button variant=\"primary\" onClick={() => setAdding(true)} data-testid=\"config-providers-add\">\n <Plus size={14} aria-hidden /> Add\n </Button>\n </Inline>\n </Inline>\n {payload.loading && providers.length === 0 ? (\n <Skeleton style={{ height: 100 }} />\n ) : providers.length === 0 ? (\n <EmptyState icon={<Cpu size={28} aria-hidden />} title=\"No providers\" description=\"Add one or use Auto-add with key.\" />\n ) : (\n <Stack gap={1}>\n {providers.map((p) => {\n const isConfirming = confirmDelete === p.id;\n return (\n <div key={p.id} data-testid={`config-provider-row-${p.id}`} style={{ padding: 'var(--space-2)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)' }}>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <Inline align=\"center\" gap={2}>\n <strong>{p.name || p.id}</strong>\n {p.groupId && <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>group={p.groupId}</span>}\n </Inline>\n <Inline gap={1}>\n <Button variant=\"ghost\" onClick={() => setEditing(p.id)} data-testid={`config-provider-edit-${p.id}`} aria-label={`Edit ${p.id}`}>\n <Pencil size={14} aria-hidden />\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete((cur) => (cur === p.id ? null : p.id))} data-testid={`config-provider-delete-${p.id}`} aria-label={`Delete ${p.id}`}>\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n </Inline>\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"danger\" onClick={() => void drop(p.id)} data-testid={`config-provider-confirm-delete-${p.id}`}>Confirm delete</Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete(null)}>Cancel</Button>\n </Inline>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </Stack>\n </CardBody>\n </Card>\n );\n}\n\nfunction McpsPanel(): JSX.Element {\n const payload = useFetch<{ mcps: Mcp[] }>('/api/config/mcps');\n const mcps = useMemo(() => payload.data?.mcps ?? [], [payload.data]);\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n return (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>MCP servers</strong>\n </Inline>\n {payload.loading && mcps.length === 0 ? (\n <Skeleton style={{ height: 60 }} />\n ) : mcps.length === 0 ? (\n <EmptyState icon={<Plug size={28} aria-hidden />} title=\"No MCPs\" description=\"Add one via /api/config/mcps.\" />\n ) : (\n <Stack gap={1}>\n {mcps.map((m) => (\n <div key={m.id} data-testid={`config-mcp-row-${m.id}`} style={{ padding: 'var(--space-2)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)', display: 'flex', justifyContent: 'space-between' }}>\n <strong>{m.name || m.id}</strong>\n {m.command && <code style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{m.command}</code>}\n </div>\n ))}\n </Stack>\n )}\n <Button variant=\"ghost\" onClick={refresh} data-testid=\"config-mcps-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n </Stack>\n </CardBody>\n </Card>\n );\n}\n\nfunction SystemLlmPanel(): JSX.Element {\n const payload = useFetch<SystemLlm>('/api/llm/system-llm');\n const [enabled, setEnabled] = useState<boolean>(false);\n const [provider, setProvider] = useState<string>('');\n const [model, setModel] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [saved, setSaved] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (payload.data) {\n setEnabled(payload.data.enabled);\n setProvider(payload.data.provider ?? '');\n setModel(payload.data.model ?? '');\n }\n }, [payload.data]);\n\n const save = async (): Promise<void> => {\n setBusy(true);\n setError(null);\n setSaved(false);\n try {\n await fetchJson('/api/llm/system-llm', {\n method: 'PUT',\n body: { enabled, provider, model },\n });\n setSaved(true);\n void payload.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>System LLM</strong>\n {payload.loading && payload.data === null ? (\n <Skeleton style={{ height: 100 }} />\n ) : (\n <Stack gap={2}>\n <label style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>\n <input\n type=\"checkbox\"\n checked={enabled}\n data-testid=\"config-system-llm-enabled\"\n onChange={(e) => setEnabled((e.target as HTMLInputElement).checked)}\n />\n <span style={{ fontSize: 'var(--fs-13)' }}>Enabled</span>\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Provider</span>\n <Input value={provider} data-testid=\"config-system-llm-provider\" onChange={(e) => setProvider((e.target as HTMLInputElement).value)} />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Model</span>\n <Input value={model} data-testid=\"config-system-llm-model\" onChange={(e) => setModel((e.target as HTMLInputElement).value)} />\n </label>\n <Inline justify=\"end\" gap={2}>\n <Button variant=\"primary\" onClick={() => void save()} disabled={busy} data-testid=\"config-system-llm-save\">\n <Save size={14} aria-hidden /> {busy ? 'Saving…' : 'Save'}\n </Button>\n </Inline>\n {saved && <span data-testid=\"config-system-llm-saved\" style={{ color: 'var(--success)', fontSize: 'var(--fs-12)' }}>Saved</span>}\n {error !== null && (\n <span role=\"alert\" data-testid=\"config-system-llm-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n </Stack>\n )}\n </Stack>\n </CardBody>\n </Card>\n );\n}"],"names":["SECTIONS","SettingsIcon","Cpu","Plug","ServerCog","ConfigView","section","setSection","useState","jsxs","Stack","jsx","ViewHeader","Inline","s","RuntimeConfigPanel","ProvidersPanel","McpsPanel","SystemLlmPanel","payload","useFetch","draft","setDraft","busy","setBusy","saved","setSaved","error","setError","useEffect","_a","reload","useCallback","save","fetchJson","err","FetchError","Card","CardBody","Button","RefreshCcw","Save","Skeleton","e","adding","setAdding","editing","setEditing","confirmDelete","setConfirmDelete","refresh","providers","useMemo","drop","id","Plus","EmptyState","p","isConfirming","Pencil","cur","Trash2","mcps","m","enabled","setEnabled","provider","setProvider","model","setModel","Input"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{r as $,j as e}from"./cmdk-C3F6LD6N.js";import{u as k,S as a,d as F,I as d,A as C,B as I,h as V}from"./main-BZMmD6a8.js";import{G as b}from"./Grid-BThCPJaV.js";import{V as A}from"./ViewHeader-BaCWNuVX.js";import{C as n,b as i}from"./Card-BmXiT4c6.js";import{R}from"./refresh-cw-CR9BzJik.js";import{F as D}from"./file-text-CEhDgLq2.js";function E(r){if(!r||r<=0)return"—";const s=Math.floor(r/86400),l=Math.floor(r%86400/3600),o=Math.floor(r%3600/60);return s>0?`${s}d ${l}h`:l>0?`${l}h ${o}m`:`${o}m`}function N(){var g,x,j,m,u,p,v,y,S,z,w;const r=k("/api/diagnostics"),s=k("/api/diagnostics/logs?tail=200");$.useEffect(()=>{const t=setInterval(()=>{s.refetch()},1e4);return()=>clearInterval(t)},[s]);const l=(g=r.data)==null?void 0:g.uptime,o=((x=r.data)==null?void 0:x.checks)??[],h=((j=r.data)==null?void 0:j.counts)??{},c=((m=s.data)==null?void 0:m.lines)??[],f=((u=s.data)==null?void 0:u.file)??null;return e.jsxs(a,{gap:5,"data-testid":"diagnostics-view",children:[e.jsx(A,{title:"Diagnostics",description:"Live system snapshot + active log tail. Auto-refresh every 10s.",actions:e.jsxs(F,{variant:"ghost",onClick:()=>{r.refetch(),s.refetch()},"data-testid":"diagnostics-refresh",children:[e.jsx(R,{size:14,"aria-hidden":!0})," Refresh"]})}),e.jsxs(b,{cols:3,children:[e.jsx(n,{variant:"default",children:e.jsx(i,{children:e.jsxs(a,{gap:1,children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Status"}),e.jsxs(d,{align:"center",gap:2,children:[e.jsx(C,{size:14,"aria-hidden":!0}),e.jsx("strong",{style:{fontFamily:"var(--font-mono)"},children:r.loading?"…":r.error?"error":(v=(p=r.data)==null?void 0:p.service)!=null&&v.running?(((S=(y=r.data)==null?void 0:y.errors)==null?void 0:S.length)??0)>0?"warn":"ok":"stopped"})]})]})})}),e.jsx(n,{variant:"default",children:e.jsx(i,{children:e.jsxs(a,{gap:1,children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Uptime"}),e.jsx("strong",{style:{fontFamily:"var(--font-mono)"},children:r.loading?"…":E(l)})]})})}),e.jsx(n,{variant:"default",children:e.jsx(i,{children:e.jsxs(a,{gap:1,children:[e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:"Version"}),e.jsx("strong",{style:{fontFamily:"var(--font-mono)"},children:r.loading?"…":((z=r.data)==null?void 0:z.version)??"—"})]})})})]}),r.error&&e.jsx(n,{variant:"default",style:{borderColor:"var(--danger)"},children:e.jsx(i,{children:e.jsxs(a,{gap:2,children:[e.jsxs(d,{align:"center",gap:2,children:[e.jsx(C,{size:14,"aria-hidden":!0,style:{color:"var(--danger)"}}),e.jsx("strong",{style:{color:"var(--danger)"},children:"Diagnostics fetch failed"})]}),e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:r.error.message??String(r.error)}),e.jsxs(F,{variant:"secondary",size:"sm",onClick:()=>{r.refetch()},children:[e.jsx(R,{size:12,"aria-hidden":!0})," Retry"]})]})})}),Object.keys(h).length>0&&e.jsx(n,{variant:"default",children:e.jsx(i,{children:e.jsxs(a,{gap:2,children:[e.jsx("strong",{children:"Counts"}),e.jsx(b,{cols:4,children:Object.entries(h).map(([t,B])=>e.jsxs(a,{gap:0,children:[e.jsx("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-muted)",textTransform:"uppercase",letterSpacing:"0.04em"},children:t}),e.jsx("strong",{style:{fontFamily:"var(--font-mono)",fontSize:"var(--fs-13)"},children:String(B??"—")})]},t))})]})})}),o.length>0&&e.jsx(n,{variant:"default",children:e.jsx(i,{children:e.jsxs(a,{gap:2,children:[e.jsxs("strong",{children:["Checks (",o.length,")"]}),e.jsx(d,{gap:1,wrap:!0,children:o.map(t=>e.jsx(I,{tone:t.status==="ok"?"success":t.status==="warn"?"warning":"danger",children:t.name},t.name))})]})})}),e.jsx(n,{variant:"default",children:e.jsx(i,{children:e.jsxs(a,{gap:2,children:[e.jsxs(d,{align:"center",justify:"between",children:[e.jsxs(d,{align:"center",gap:2,children:[e.jsx(D,{size:14,"aria-hidden":!0}),e.jsx("strong",{children:"Log tail"}),f&&e.jsx("code",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)",fontFamily:"var(--font-mono)"},children:f})]}),e.jsxs("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:[c.length," / ",((w=s.data)==null?void 0:w.total)??0," lines"]})]}),s.loading&&c.length===0?e.jsx(V,{style:{height:240}}):c.length===0?e.jsx("span",{style:{color:"var(--fg-muted)",fontSize:"var(--fs-12)"},children:"No log lines yet."}):e.jsx("pre",{"data-testid":"diagnostics-log-tail",style:{maxHeight:320,overflowY:"auto",padding:"var(--space-3)",background:"var(--surface-1)",borderRadius:"var(--radius-sm)",fontSize:"var(--fs-12)",fontFamily:"var(--font-mono)",margin:0,whiteSpace:"pre-wrap",wordBreak:"break-all"},children:c.join(`
2
+ `)})]})})})]})}export{N as DiagnosticsView};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiagnosticsView-C0sdqhEl.js","sources":["../../src/web/v8/views/Diagnostics/DiagnosticsView.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { Activity, RefreshCw, FileText } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { Grid } from '../../ui/primitives/Grid.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Badge } from '../../ui/data/Badge.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { useFetch } from '../../data/useFetch.js';\n\n/**\n * DiagnosticsView — Sprint S35. System snapshot + active log tail.\n */\n\ninterface DiagnosticsHealth {\n status: string;\n checks?: Array<{ name: string; status: string; message?: string }>;\n}\n\ninterface DiagnosticsSnapshot {\n version?: string;\n uptime?: number;\n memory?: { rss?: number; heapUsed?: number; heapTotal?: number };\n checks?: Array<{ name: string; status: string; message?: string }>;\n counts?: Record<string, number | string | null>;\n errors?: Array<{ line: string; ts: string | null }>;\n service?: { running?: boolean; pid?: number };\n}\n\ninterface LogsResponse {\n lines: string[];\n file: string | null;\n total: number;\n}\n\nfunction fmtUptime(secs: number | undefined): string {\n if (!secs || secs <= 0) return '—';\n const days = Math.floor(secs / 86400);\n const hours = Math.floor((secs % 86400) / 3600);\n const mins = Math.floor((secs % 3600) / 60);\n if (days > 0) return `${days}d ${hours}h`;\n if (hours > 0) return `${hours}h ${mins}m`;\n return `${mins}m`;\n}\n\nexport function DiagnosticsView(): JSX.Element {\n const snap = useFetch<DiagnosticsSnapshot>('/api/diagnostics');\n const logs = useFetch<LogsResponse>('/api/diagnostics/logs?tail=200');\n\n // Auto-refresh logs every 10s while page is open.\n useEffect(() => {\n const id = setInterval(() => { void logs.refetch(); }, 10_000);\n return () => clearInterval(id);\n }, [logs]);\n\n const uptime = snap.data?.uptime;\n const checks = snap.data?.checks ?? [];\n const counts = snap.data?.counts ?? {};\n const lines = logs.data?.lines ?? [];\n const logFile = logs.data?.file ?? null;\n\n return (\n <Stack gap={5} data-testid=\"diagnostics-view\">\n <ViewHeader\n title=\"Diagnostics\"\n description=\"Live system snapshot + active log tail. Auto-refresh every 10s.\"\n actions={\n <Button variant=\"ghost\" onClick={() => { void snap.refetch(); void logs.refetch(); }} data-testid=\"diagnostics-refresh\">\n <RefreshCw size={14} aria-hidden /> Refresh\n </Button>\n }\n />\n\n <Grid cols={3}>\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Status</span>\n <Inline align=\"center\" gap={2}>\n <Activity size={14} aria-hidden />\n <strong style={{ fontFamily: 'var(--font-mono)' }}>\n {snap.loading ? '…' : (\n snap.error ? 'error' :\n !snap.data?.service?.running ? 'stopped' :\n (snap.data?.errors?.length ?? 0) > 0 ? 'warn' : 'ok'\n )}\n </strong>\n </Inline>\n </Stack>\n </CardBody>\n </Card>\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Uptime</span>\n <strong style={{ fontFamily: 'var(--font-mono)' }}>{snap.loading ? '…' : fmtUptime(uptime)}</strong>\n </Stack>\n </CardBody>\n </Card>\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={1}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Version</span>\n <strong style={{ fontFamily: 'var(--font-mono)' }}>{snap.loading ? '…' : (snap.data?.version ?? '—')}</strong>\n </Stack>\n </CardBody>\n </Card>\n </Grid>\n\n {snap.error && (\n <Card variant=\"default\" style={{ borderColor: 'var(--danger)' }}>\n <CardBody>\n <Stack gap={2}>\n <Inline align=\"center\" gap={2}>\n <Activity size={14} aria-hidden style={{ color: 'var(--danger)' }} />\n <strong style={{ color: 'var(--danger)' }}>Diagnostics fetch failed</strong>\n </Inline>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{snap.error.message ?? String(snap.error)}</span>\n <Button variant=\"secondary\" size=\"sm\" onClick={() => { void snap.refetch(); }}>\n <RefreshCw size={12} aria-hidden /> Retry\n </Button>\n </Stack>\n </CardBody>\n </Card>\n )}\n\n {Object.keys(counts).length > 0 && (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <strong>Counts</strong>\n <Grid cols={4}>\n {Object.entries(counts).map(([k, v]) => (\n <Stack key={k} gap={0}>\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)', textTransform: 'uppercase', letterSpacing: '0.04em' }}>{k}</span>\n <strong style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-13)' }}>{String(v ?? '—')}</strong>\n </Stack>\n ))}\n </Grid>\n </Stack>\n </CardBody>\n </Card>\n )}\n\n {checks.length > 0 && (\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <strong>Checks ({checks.length})</strong>\n <Inline gap={1} wrap={true}>\n {checks.map((c) => (\n <Badge key={c.name} tone={c.status === 'ok' ? 'success' : c.status === 'warn' ? 'warning' : 'danger'}>\n {c.name}\n </Badge>\n ))}\n </Inline>\n </Stack>\n </CardBody>\n </Card>\n )}\n\n <Card variant=\"default\">\n <CardBody>\n <Stack gap={2}>\n <Inline align=\"center\" justify=\"between\">\n <Inline align=\"center\" gap={2}>\n <FileText size={14} aria-hidden />\n <strong>Log tail</strong>\n {logFile && <code style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)', fontFamily: 'var(--font-mono)' }}>{logFile}</code>}\n </Inline>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{lines.length} / {logs.data?.total ?? 0} lines</span>\n </Inline>\n {logs.loading && lines.length === 0 ? (\n <Skeleton style={{ height: 240 }} />\n ) : lines.length === 0 ? (\n <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-12)' }}>No log lines yet.</span>\n ) : (\n <pre\n data-testid=\"diagnostics-log-tail\"\n style={{\n maxHeight: 320,\n overflowY: 'auto',\n padding: 'var(--space-3)',\n background: 'var(--surface-1)',\n borderRadius: 'var(--radius-sm)',\n fontSize: 'var(--fs-12)',\n fontFamily: 'var(--font-mono)',\n margin: 0,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-all',\n }}\n >\n {lines.join('\\n')}\n </pre>\n )}\n </Stack>\n </CardBody>\n </Card>\n </Stack>\n );\n}"],"names":["fmtUptime","secs","days","hours","mins","DiagnosticsView","snap","useFetch","logs","useEffect","id","uptime","_a","checks","_b","counts","_c","lines","_d","logFile","_e","jsxs","Stack","jsx","ViewHeader","Button","RefreshCw","Grid","Card","CardBody","Inline","Activity","_g","_f","_i","_h","_j","k","v","c","Badge","FileText","_k","Skeleton"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import{r as c,j as e}from"./cmdk-DVxytz9i.js";import{c as k,u as b,a as C,S as h,I as l,d as r,h as m,M as S,l as $,X as w,i as f,F as x}from"./main-Cxeu4LhG.js";import{V as z}from"./ViewHeader-B6P-C4GD.js";import{L as E}from"./ListHeader-Dpun-r36.js";import{C as D,b as R}from"./Card-rF59wHiO.js";import{E as F}from"./EmptyState-D65J5FQN.js";import{E as T}from"./ErrorState-DULZnttJ.js";import{R as q}from"./refresh-ccw-DenGBOcq.js";import{T as j}from"./trash-2-Cv7U38jw.js";import"./Alert-B6DjfRFI.js";import"./circle-alert-HdHe7m8K.js";import"./triangle-alert-tUTXbcEP.js";import"./circle-check-Cs-xoV7R.js";/**
1
+ import{r as c,j as e}from"./cmdk-C3F6LD6N.js";import{c as k,u as b,a as C,S as h,I as l,d as r,h as m,M as S,l as $,X as w,i as f,F as x}from"./main-BZMmD6a8.js";import{V as z}from"./ViewHeader-BaCWNuVX.js";import{L as E}from"./ListHeader-BLAeshe0.js";import{C as D,b as R}from"./Card-BmXiT4c6.js";import{E as F}from"./EmptyState-CdDQmfEL.js";import{E as T}from"./ErrorState-BRvj8qZZ.js";import{R as q}from"./refresh-ccw-BL7B0NO1.js";import{T as j}from"./trash-2-B885GY46.js";import"./Alert-MwVEymjy.js";import"./circle-alert-D7jn06kH.js";import"./triangle-alert-DLmUhymD.js";import"./circle-check-DHs37Sot.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":"DialogsView-BcqDDCZQ.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/skip-forward.js","../../src/web/v8/views/Dialogs/DialogsView.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 SkipForward = createLucideIcon(\"SkipForward\", [\n [\"polygon\", { points: \"5 4 15 12 5 20 5 4\", key: \"16p6eg\" }],\n [\"line\", { x1: \"19\", x2: \"19\", y1: \"5\", y2: \"19\", key: \"futhcm\" }]\n]);\n\nexport { SkipForward as default };\n//# sourceMappingURL=skip-forward.js.map\n","/**\n * v8/views/Dialogs/DialogsView.tsx — Sprint S42, v9.3.0.\n *\n * Active dialog queue pulled from /api/dialogs. Per-row: view kind,\n * title, body preview, source, age, inline-confirm Dismiss (DELETE\n * /api/dialogs/:id). Empty state + manual Refresh button. No\n * window.confirm.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { Check, MessageSquare, RefreshCcw, SkipForward, Trash2, X } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { ListHeader } from '../../ui/data/ListHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\ninterface DialogItem {\n id: string;\n kind?: string;\n title?: string;\n body?: string;\n source?: string;\n createdAt?: number | string;\n}\n\nexport function DialogsView(): JSX.Element {\n const payload = useFetch<{ dialogs: DialogItem[] }>('/api/dialogs');\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n\n // Live: server broadcasts `dialog:show` on enqueue. Refresh on it.\n useWsMessage('dialog:show', () => { refresh(); });\n\n const drop = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/dialogs/${id}`, { method: 'DELETE' });\n setConfirmDelete(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const decide = async (id: string, verdict: 'approve' | 'deny' | 'skip'): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/dialogs/${id}/${verdict}`, { method: 'POST', body: {} });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const dialogs = useMemo<DialogItem[]>(() => payload.data?.dialogs ?? [], [payload.data]);\n\n return (\n <Stack gap={4} data-testid=\"dialogs-view\">\n <ViewHeader\n title=\"Dialogs\"\n description=\"Active dialog queue (debug + manual dismiss).\"\n actions={\n <Inline gap={1}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"dialogs-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"dialogs-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n </Inline>\n }\n />\n <ListHeader title=\"Queue\" count={dialogs.length} testid=\"dialogs-list-header\" />\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && dialogs.length === 0 ? (\n <Stack gap={1}>\n <Skeleton style={{ height: 32 }} />\n <Skeleton style={{ height: 32 }} />\n </Stack>\n ) : payload.error && dialogs.length === 0 ? (\n <ErrorState\n block\n title=\"Couldn't load dialogs\"\n description=\"The dialog queue failed to fetch. Retry to refetch.\"\n error={payload.error}\n onRetry={refresh}\n testid=\"dialogs-error-state\"\n />\n ) : dialogs.length === 0 ? (\n <EmptyState\n icon={<MessageSquare size={28} aria-hidden />}\n title=\"No active dialogs\"\n description=\"Dialogs enqueued via the slash-command plugin will appear here.\"\n />\n ) : (\n <Stack gap={1}>\n {dialogs.map((d) => {\n const isConfirming = confirmDelete === d.id;\n return (\n <div\n key={d.id}\n data-testid={`dialog-row-${d.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} style={{ minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>{d.title || d.id}</strong>\n {d.kind && (\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)', fontFamily: 'var(--font-mono)' }}>\n {d.kind}\n </span>\n )}\n {d.source && (\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>\n · {d.source}\n </span>\n )}\n </Inline>\n {d.body && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {d.body.length > 160 ? `${d.body.slice(0, 160)}…` : d.body}\n </span>\n )}\n </Stack>\n <Inline gap={1}>\n <Button\n variant=\"primary\"\n onClick={() => void decide(d.id, 'approve')}\n data-testid={`dialog-approve-${d.id}`}\n aria-label={`Approve ${d.id}`}\n >\n <Check size={14} aria-hidden /> Approve\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => void decide(d.id, 'skip')}\n data-testid={`dialog-skip-${d.id}`}\n aria-label={`Skip ${d.id}`}\n >\n <SkipForward size={14} aria-hidden /> Skip\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => void decide(d.id, 'deny')}\n data-testid={`dialog-deny-${d.id}`}\n aria-label={`Deny ${d.id}`}\n >\n <X size={14} aria-hidden /> Deny\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => setConfirmDelete((cur) => (cur === d.id ? null : d.id))}\n data-testid={`dialog-dismiss-${d.id}`}\n aria-label={`Dismiss ${d.id}`}\n >\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n </Inline>\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"danger\" onClick={() => void drop(d.id)} data-testid={`dialog-confirm-dismiss-${d.id}`}>\n <Trash2 size={14} aria-hidden /> Confirm\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete(null)}>Cancel</Button>\n </Inline>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </CardBody>\n </Card>\n </Stack>\n );\n}"],"names":["SkipForward","createLucideIcon","DialogsView","payload","useFetch","confirmDelete","setConfirmDelete","useState","error","setError","refresh","useCallback","useWsMessage","drop","id","fetchJson","err","FetchError","decide","verdict","dialogs","useMemo","_a","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCcw","ListHeader","Card","CardBody","Skeleton","ErrorState","EmptyState","MessageSquare","d","isConfirming","Check","X","cur","Trash2"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"DialogsView-DzTnyX8K.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/skip-forward.js","../../src/web/v8/views/Dialogs/DialogsView.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 SkipForward = createLucideIcon(\"SkipForward\", [\n [\"polygon\", { points: \"5 4 15 12 5 20 5 4\", key: \"16p6eg\" }],\n [\"line\", { x1: \"19\", x2: \"19\", y1: \"5\", y2: \"19\", key: \"futhcm\" }]\n]);\n\nexport { SkipForward as default };\n//# sourceMappingURL=skip-forward.js.map\n","/**\n * v8/views/Dialogs/DialogsView.tsx — Sprint S42, v9.3.0.\n *\n * Active dialog queue pulled from /api/dialogs. Per-row: view kind,\n * title, body preview, source, age, inline-confirm Dismiss (DELETE\n * /api/dialogs/:id). Empty state + manual Refresh button. No\n * window.confirm.\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { Check, MessageSquare, RefreshCcw, SkipForward, Trash2, X } from 'lucide-react';\nimport { Stack } from '../../ui/primitives/Stack.js';\nimport { Inline } from '../../ui/primitives/Inline.js';\nimport { ViewHeader } from '../../ui/data/ViewHeader.js';\nimport { ListHeader } from '../../ui/data/ListHeader.js';\nimport { Card, CardBody } from '../../ui/data/Card.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\n\ninterface DialogItem {\n id: string;\n kind?: string;\n title?: string;\n body?: string;\n source?: string;\n createdAt?: number | string;\n}\n\nexport function DialogsView(): JSX.Element {\n const payload = useFetch<{ dialogs: DialogItem[] }>('/api/dialogs');\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n\n // Live: server broadcasts `dialog:show` on enqueue. Refresh on it.\n useWsMessage('dialog:show', () => { refresh(); });\n\n const drop = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/dialogs/${id}`, { method: 'DELETE' });\n setConfirmDelete(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const decide = async (id: string, verdict: 'approve' | 'deny' | 'skip'): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/dialogs/${id}/${verdict}`, { method: 'POST', body: {} });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const dialogs = useMemo<DialogItem[]>(() => payload.data?.dialogs ?? [], [payload.data]);\n\n return (\n <Stack gap={4} data-testid=\"dialogs-view\">\n <ViewHeader\n title=\"Dialogs\"\n description=\"Active dialog queue (debug + manual dismiss).\"\n actions={\n <Inline gap={1}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"dialogs-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"dialogs-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n </Inline>\n }\n />\n <ListHeader title=\"Queue\" count={dialogs.length} testid=\"dialogs-list-header\" />\n <Card variant=\"default\">\n <CardBody>\n {payload.loading && dialogs.length === 0 ? (\n <Stack gap={1}>\n <Skeleton style={{ height: 32 }} />\n <Skeleton style={{ height: 32 }} />\n </Stack>\n ) : payload.error && dialogs.length === 0 ? (\n <ErrorState\n block\n title=\"Couldn't load dialogs\"\n description=\"The dialog queue failed to fetch. Retry to refetch.\"\n error={payload.error}\n onRetry={refresh}\n testid=\"dialogs-error-state\"\n />\n ) : dialogs.length === 0 ? (\n <EmptyState\n icon={<MessageSquare size={28} aria-hidden />}\n title=\"No active dialogs\"\n description=\"Dialogs enqueued via the slash-command plugin will appear here.\"\n />\n ) : (\n <Stack gap={1}>\n {dialogs.map((d) => {\n const isConfirming = confirmDelete === d.id;\n return (\n <div\n key={d.id}\n data-testid={`dialog-row-${d.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} style={{ minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>{d.title || d.id}</strong>\n {d.kind && (\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)', fontFamily: 'var(--font-mono)' }}>\n {d.kind}\n </span>\n )}\n {d.source && (\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>\n · {d.source}\n </span>\n )}\n </Inline>\n {d.body && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {d.body.length > 160 ? `${d.body.slice(0, 160)}…` : d.body}\n </span>\n )}\n </Stack>\n <Inline gap={1}>\n <Button\n variant=\"primary\"\n onClick={() => void decide(d.id, 'approve')}\n data-testid={`dialog-approve-${d.id}`}\n aria-label={`Approve ${d.id}`}\n >\n <Check size={14} aria-hidden /> Approve\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => void decide(d.id, 'skip')}\n data-testid={`dialog-skip-${d.id}`}\n aria-label={`Skip ${d.id}`}\n >\n <SkipForward size={14} aria-hidden /> Skip\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => void decide(d.id, 'deny')}\n data-testid={`dialog-deny-${d.id}`}\n aria-label={`Deny ${d.id}`}\n >\n <X size={14} aria-hidden /> Deny\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => setConfirmDelete((cur) => (cur === d.id ? null : d.id))}\n data-testid={`dialog-dismiss-${d.id}`}\n aria-label={`Dismiss ${d.id}`}\n >\n <Trash2 size={14} aria-hidden />\n </Button>\n </Inline>\n </Inline>\n {isConfirming && (\n <Inline gap={1} style={{ marginTop: 'var(--space-1)' }}>\n <Button variant=\"danger\" onClick={() => void drop(d.id)} data-testid={`dialog-confirm-dismiss-${d.id}`}>\n <Trash2 size={14} aria-hidden /> Confirm\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete(null)}>Cancel</Button>\n </Inline>\n )}\n </div>\n );\n })}\n </Stack>\n )}\n </CardBody>\n </Card>\n </Stack>\n );\n}"],"names":["SkipForward","createLucideIcon","DialogsView","payload","useFetch","confirmDelete","setConfirmDelete","useState","error","setError","refresh","useCallback","useWsMessage","drop","id","fetchJson","err","FetchError","decide","verdict","dialogs","useMemo","_a","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCcw","ListHeader","Card","CardBody","Skeleton","ErrorState","EmptyState","MessageSquare","d","isConfirming","Check","X","cur","Trash2"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,4 +1,4 @@
1
- import{r as d,j as e}from"./cmdk-DVxytz9i.js";import{c as C,u as m,S as i,I as c,d as x,h,H as z,B as E,J as T,G as w,i as R,F as I}from"./main-Cxeu4LhG.js";import{V as b}from"./ViewHeader-B6P-C4GD.js";import{C as j,b as y}from"./Card-rF59wHiO.js";import{E as N}from"./EmptyState-D65J5FQN.js";import{E as B}from"./ErrorState-DULZnttJ.js";import{R as F}from"./refresh-cw-ENBVR8hW.js";import{T as H}from"./triangle-alert-tUTXbcEP.js";import{C as A}from"./circle-check-Cs-xoV7R.js";import"./Alert-B6DjfRFI.js";import"./circle-alert-HdHe7m8K.js";import"./refresh-ccw-DenGBOcq.js";/**
1
+ import{r as d,j as e}from"./cmdk-C3F6LD6N.js";import{c as C,u as m,S as i,I as c,d as x,h,H as z,B as E,J as T,G as w,i as R,F as I}from"./main-BZMmD6a8.js";import{V as b}from"./ViewHeader-BaCWNuVX.js";import{C as j,b as y}from"./Card-BmXiT4c6.js";import{E as N}from"./EmptyState-CdDQmfEL.js";import{E as B}from"./ErrorState-BRvj8qZZ.js";import{R as F}from"./refresh-cw-CR9BzJik.js";import{T as H}from"./triangle-alert-DLmUhymD.js";import{C as A}from"./circle-check-DHs37Sot.js";import"./Alert-MwVEymjy.js";import"./circle-alert-D7jn06kH.js";import"./refresh-ccw-BL7B0NO1.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":"DoctorView-BQwqvMAh.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/circle-x.js","../../src/web/v8/views/Doctor/DoctorView.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 CircleX = createLucideIcon(\"CircleX\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"m15 9-6 6\", key: \"1uzhvr\" }],\n [\"path\", { d: \"m9 9 6 6\", key: \"z0biqf\" }]\n]);\n\nexport { CircleX as default };\n//# sourceMappingURL=circle-x.js.map\n","import { useCallback, useEffect, useState } from 'react';\nimport { Stethoscope, RefreshCw, ShieldCheck, AlertTriangle, XCircle, CheckCircle2, 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 { Badge } from '../../ui/data/Badge.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport type { LucideIcon } from 'lucide-react';\n\n/**\n * DoctorView — Sprint S35. Health rollup + per-check triggers.\n */\n\ntype Status = 'ok' | 'warn' | 'fail';\n\ninterface CheckResult {\n name: string;\n status: Status;\n message: string;\n error?: string;\n}\n\ninterface CheckGroup {\n name?: string;\n status?: Status;\n message?: string;\n error?: string;\n}\n\ninterface HealthRollup {\n status: Status;\n issues: Array<{ name: string; status: Status; message: string }>;\n}\n\ninterface DoctorSnapshot {\n health: HealthRollup;\n checks: { system?: CheckGroup[]; config?: CheckGroup[]; services?: CheckGroup[] };\n recentErrors?: unknown[];\n}\n\nconst STATUS_ICON: Record<Status, LucideIcon> = {\n ok: CheckCircle2,\n warn: AlertTriangle,\n fail: XCircle,\n};\n\nconst STATUS_TONE = {\n ok: 'success',\n warn: 'warning',\n fail: 'danger',\n} as const;\n\nexport function DoctorView(): JSX.Element {\n const snap = useFetch<DoctorSnapshot>('/api/doctor');\n const health = useFetch<HealthRollup>('/api/doctor/health');\n const [running, setRunning] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n // Re-poll health every 30s for a live rollup.\n useEffect(() => {\n const id = setInterval(() => { void health.refetch(); }, 30_000);\n return () => clearInterval(id);\n }, [health]);\n\n const runCheck = async (name: string): Promise<void> => {\n setRunning(name);\n setError(null);\n try {\n await fetchJson('/api/doctor/check', { method: 'POST', body: { checkName: name } });\n void snap.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setRunning(null);\n }\n };\n\n const rollup = health.data ?? snap.data?.health;\n const checks: CheckResult[] = (() => {\n const g = snap.data?.checks;\n if (!g) return [];\n return [...(g.system ?? []), ...(g.config ?? []), ...(g.services ?? [])]\n .filter((c): c is CheckResult =>\n typeof c.name === 'string' && typeof c.status === 'string' && typeof c.message === 'string'\n );\n })();\n\n return (\n <Stack gap={5} data-testid=\"doctor-view\">\n <ViewHeader\n title=\"Doctor\"\n description=\"System diagnostics. Health poll every 30s; click any check to re-run.\"\n actions={\n <Inline gap={2} align=\"center\">\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Button variant=\"ghost\" onClick={() => void snap.refetch()} data-testid=\"doctor-refresh\">\n <RefreshCw size={14} aria-hidden /> Refresh\n </Button>\n </Inline>\n }\n />\n\n {rollup ? (\n <Card variant=\"elevated\">\n <CardBody>\n <Inline align=\"center\" gap={3}>\n {(() => {\n const Icon = STATUS_ICON[rollup.status];\n return <Icon size={20} aria-hidden />;\n })()}\n <Stack gap={0}>\n <strong style={{ fontSize: 'var(--fs-14)' }}>Health: {rollup.status.toUpperCase()}</strong>\n <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-12)' }}>\n {rollup.issues.length === 0 ? 'No issues detected.' : `${rollup.issues.length} issue${rollup.issues.length === 1 ? '' : 's'}`}\n </span>\n </Stack>\n </Inline>\n </CardBody>\n </Card>\n ) : (\n <Skeleton style={{ height: 64 }} />\n )}\n\n {snap.loading && checks.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 64 }} />\n <Skeleton style={{ height: 64 }} />\n </Stack>\n ) : snap.error && checks.length === 0 ? (\n <ErrorState\n block\n title=\"Couldn't run doctor\"\n description=\"The diagnostic snapshot failed. Retry to refetch.\"\n error={snap.error}\n onRetry={() => void snap.refetch()}\n testid=\"doctor-error\"\n />\n ) : checks.length === 0 ? (\n <EmptyState\n icon={<Stethoscope size={32} aria-hidden />}\n title=\"No checks yet\"\n description=\"The Doctor snapshot returned no checks.\"\n />\n ) : (\n <Stack gap={2}>\n {checks.map((c) => {\n const Icon = STATUS_ICON[c.status];\n const busy = running === c.name;\n return (\n <Card key={c.name} variant=\"default\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={3}>\n <Stack gap={1} style={{ flex: 1, minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <Icon size={14} aria-hidden />\n <strong>{c.name}</strong>\n <Badge tone={STATUS_TONE[c.status]}>{c.status}</Badge>\n </Inline>\n <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-12)' }}>{c.message}</span>\n {c.error && <span style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)', fontFamily: 'var(--font-mono)' }}>{c.error}</span>}\n </Stack>\n <Button variant=\"ghost\" onClick={() => void runCheck(c.name)} disabled={busy} data-testid={`doctor-run-${c.name}`}>\n {busy ? <Loader2 size={12} className=\"animate-spin\" aria-hidden /> : <ShieldCheck size={12} aria-hidden />}\n {busy ? 'Running…' : 'Re-run'}\n </Button>\n </Inline>\n </CardBody>\n </Card>\n );\n })}\n </Stack>\n )}\n </Stack>\n );\n}"],"names":["CircleX","createLucideIcon","STATUS_ICON","CheckCircle2","AlertTriangle","XCircle","STATUS_TONE","DoctorView","snap","useFetch","health","running","setRunning","useState","error","setError","useEffect","id","runCheck","name","fetchJson","err","FetchError","rollup","_a","checks","g","c","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCw","Card","CardBody","Icon","Skeleton","ErrorState","EmptyState","Stethoscope","busy","Badge","Loader2","ShieldCheck"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"DoctorView-CiFwRMW0.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/circle-x.js","../../src/web/v8/views/Doctor/DoctorView.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 CircleX = createLucideIcon(\"CircleX\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"m15 9-6 6\", key: \"1uzhvr\" }],\n [\"path\", { d: \"m9 9 6 6\", key: \"z0biqf\" }]\n]);\n\nexport { CircleX as default };\n//# sourceMappingURL=circle-x.js.map\n","import { useCallback, useEffect, useState } from 'react';\nimport { Stethoscope, RefreshCw, ShieldCheck, AlertTriangle, XCircle, CheckCircle2, 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 { Badge } from '../../ui/data/Badge.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { ErrorState } from '../../ui/feedback/ErrorState.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport type { LucideIcon } from 'lucide-react';\n\n/**\n * DoctorView — Sprint S35. Health rollup + per-check triggers.\n */\n\ntype Status = 'ok' | 'warn' | 'fail';\n\ninterface CheckResult {\n name: string;\n status: Status;\n message: string;\n error?: string;\n}\n\ninterface CheckGroup {\n name?: string;\n status?: Status;\n message?: string;\n error?: string;\n}\n\ninterface HealthRollup {\n status: Status;\n issues: Array<{ name: string; status: Status; message: string }>;\n}\n\ninterface DoctorSnapshot {\n health: HealthRollup;\n checks: { system?: CheckGroup[]; config?: CheckGroup[]; services?: CheckGroup[] };\n recentErrors?: unknown[];\n}\n\nconst STATUS_ICON: Record<Status, LucideIcon> = {\n ok: CheckCircle2,\n warn: AlertTriangle,\n fail: XCircle,\n};\n\nconst STATUS_TONE = {\n ok: 'success',\n warn: 'warning',\n fail: 'danger',\n} as const;\n\nexport function DoctorView(): JSX.Element {\n const snap = useFetch<DoctorSnapshot>('/api/doctor');\n const health = useFetch<HealthRollup>('/api/doctor/health');\n const [running, setRunning] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n // Re-poll health every 30s for a live rollup.\n useEffect(() => {\n const id = setInterval(() => { void health.refetch(); }, 30_000);\n return () => clearInterval(id);\n }, [health]);\n\n const runCheck = async (name: string): Promise<void> => {\n setRunning(name);\n setError(null);\n try {\n await fetchJson('/api/doctor/check', { method: 'POST', body: { checkName: name } });\n void snap.refetch();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setRunning(null);\n }\n };\n\n const rollup = health.data ?? snap.data?.health;\n const checks: CheckResult[] = (() => {\n const g = snap.data?.checks;\n if (!g) return [];\n return [...(g.system ?? []), ...(g.config ?? []), ...(g.services ?? [])]\n .filter((c): c is CheckResult =>\n typeof c.name === 'string' && typeof c.status === 'string' && typeof c.message === 'string'\n );\n })();\n\n return (\n <Stack gap={5} data-testid=\"doctor-view\">\n <ViewHeader\n title=\"Doctor\"\n description=\"System diagnostics. Health poll every 30s; click any check to re-run.\"\n actions={\n <Inline gap={2} align=\"center\">\n {error !== null && <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>}\n <Button variant=\"ghost\" onClick={() => void snap.refetch()} data-testid=\"doctor-refresh\">\n <RefreshCw size={14} aria-hidden /> Refresh\n </Button>\n </Inline>\n }\n />\n\n {rollup ? (\n <Card variant=\"elevated\">\n <CardBody>\n <Inline align=\"center\" gap={3}>\n {(() => {\n const Icon = STATUS_ICON[rollup.status];\n return <Icon size={20} aria-hidden />;\n })()}\n <Stack gap={0}>\n <strong style={{ fontSize: 'var(--fs-14)' }}>Health: {rollup.status.toUpperCase()}</strong>\n <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-12)' }}>\n {rollup.issues.length === 0 ? 'No issues detected.' : `${rollup.issues.length} issue${rollup.issues.length === 1 ? '' : 's'}`}\n </span>\n </Stack>\n </Inline>\n </CardBody>\n </Card>\n ) : (\n <Skeleton style={{ height: 64 }} />\n )}\n\n {snap.loading && checks.length === 0 ? (\n <Stack gap={2}>\n <Skeleton style={{ height: 64 }} />\n <Skeleton style={{ height: 64 }} />\n </Stack>\n ) : snap.error && checks.length === 0 ? (\n <ErrorState\n block\n title=\"Couldn't run doctor\"\n description=\"The diagnostic snapshot failed. Retry to refetch.\"\n error={snap.error}\n onRetry={() => void snap.refetch()}\n testid=\"doctor-error\"\n />\n ) : checks.length === 0 ? (\n <EmptyState\n icon={<Stethoscope size={32} aria-hidden />}\n title=\"No checks yet\"\n description=\"The Doctor snapshot returned no checks.\"\n />\n ) : (\n <Stack gap={2}>\n {checks.map((c) => {\n const Icon = STATUS_ICON[c.status];\n const busy = running === c.name;\n return (\n <Card key={c.name} variant=\"default\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={3}>\n <Stack gap={1} style={{ flex: 1, minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <Icon size={14} aria-hidden />\n <strong>{c.name}</strong>\n <Badge tone={STATUS_TONE[c.status]}>{c.status}</Badge>\n </Inline>\n <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-12)' }}>{c.message}</span>\n {c.error && <span style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)', fontFamily: 'var(--font-mono)' }}>{c.error}</span>}\n </Stack>\n <Button variant=\"ghost\" onClick={() => void runCheck(c.name)} disabled={busy} data-testid={`doctor-run-${c.name}`}>\n {busy ? <Loader2 size={12} className=\"animate-spin\" aria-hidden /> : <ShieldCheck size={12} aria-hidden />}\n {busy ? 'Running…' : 'Re-run'}\n </Button>\n </Inline>\n </CardBody>\n </Card>\n );\n })}\n </Stack>\n )}\n </Stack>\n );\n}"],"names":["CircleX","createLucideIcon","STATUS_ICON","CheckCircle2","AlertTriangle","XCircle","STATUS_TONE","DoctorView","snap","useFetch","health","running","setRunning","useState","error","setError","useEffect","id","runCheck","name","fetchJson","err","FetchError","rollup","_a","checks","g","c","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCw","Card","CardBody","Icon","Skeleton","ErrorState","EmptyState","Stethoscope","busy","Badge","Loader2","ShieldCheck"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1 +1 @@
1
- import{r as l,j as e}from"./cmdk-DVxytz9i.js";import{g as d}from"./main-Cxeu4LhG.js";const m=l.forwardRef(function(r,a){const{icon:t,title:n,description:s,action:i,className:o,...c}=r;return e.jsxs("div",{ref:a,className:d("v8-empty-state",o),style:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"var(--space-3)",padding:"var(--space-12) var(--space-6)",textAlign:"center",color:"var(--fg-muted)"},...c,children:[t!==void 0&&e.jsx("div",{style:{color:"var(--fg-subtle)",display:"inline-flex"},children:t}),e.jsx("div",{style:{fontSize:"var(--fs-16)",fontWeight:600,color:"var(--fg)"},children:n}),s!==void 0&&e.jsx("div",{style:{fontSize:"var(--fs-13)",maxWidth:480},children:s}),i!==void 0&&e.jsx("div",{style:{marginTop:"var(--space-2)"},children:i})]})});export{m as E};
1
+ import{r as l,j as e}from"./cmdk-C3F6LD6N.js";import{g as d}from"./main-BZMmD6a8.js";const m=l.forwardRef(function(r,a){const{icon:t,title:n,description:s,action:i,className:o,...c}=r;return e.jsxs("div",{ref:a,className:d("v8-empty-state",o),style:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:"var(--space-3)",padding:"var(--space-12) var(--space-6)",textAlign:"center",color:"var(--fg-muted)"},...c,children:[t!==void 0&&e.jsx("div",{style:{color:"var(--fg-subtle)",display:"inline-flex"},children:t}),e.jsx("div",{style:{fontSize:"var(--fs-16)",fontWeight:600,color:"var(--fg)"},children:n}),s!==void 0&&e.jsx("div",{style:{fontSize:"var(--fs-13)",maxWidth:480},children:s}),i!==void 0&&e.jsx("div",{style:{marginTop:"var(--space-2)"},children:i})]})});export{m as E};
@@ -1 +1 @@
1
- {"version":3,"file":"EmptyState-D65J5FQN.js","sources":["../../src/web/v8/ui/feedback/EmptyState.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * EmptyState — placeholder for empty lists / zero-data views.\n *\n * Use when a view has no rows. Never use a spinner; the data is\n * genuinely empty.\n */\nexport interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n icon?: ReactNode;\n title: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n}\n\nexport const EmptyState = forwardRef<HTMLDivElement, EmptyStateProps>(function EmptyState(\n props,\n ref,\n) {\n const { icon, title, description, action, className, ...rest } = props;\n return (\n <div\n ref={ref}\n className={cx('v8-empty-state', className)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--space-3)',\n padding: 'var(--space-12) var(--space-6)',\n textAlign: 'center',\n color: 'var(--fg-muted)',\n }}\n {...rest}\n >\n {icon !== undefined && (\n <div style={{ color: 'var(--fg-subtle)', display: 'inline-flex' }}>{icon}</div>\n )}\n <div style={{ fontSize: 'var(--fs-16)', fontWeight: 600, color: 'var(--fg)' }}>{title}</div>\n {description !== undefined && (\n <div style={{ fontSize: 'var(--fs-13)', maxWidth: 480 }}>{description}</div>\n )}\n {action !== undefined && <div style={{ marginTop: 'var(--space-2)' }}>{action}</div>}\n </div>\n );\n});"],"names":["EmptyState","forwardRef","props","ref","icon","title","description","action","className","rest","jsxs","cx","jsx"],"mappings":"qFAgBO,MAAMA,EAAaC,EAAAA,WAA4C,SACpEC,EACAC,EACA,CACA,KAAM,CAAE,KAAAC,EAAM,MAAAC,EAAO,YAAAC,EAAa,OAAAC,EAAQ,UAAAC,EAAW,GAAGC,GAASP,EACjE,OACEQ,EAAAA,KAAC,MAAA,CACC,IAAAP,EACA,UAAWQ,EAAG,iBAAkBH,CAAS,EACzC,MAAO,CACL,QAAS,OACT,cAAe,SACf,WAAY,SACZ,eAAgB,SAChB,IAAK,iBACL,QAAS,iCACT,UAAW,SACX,MAAO,iBAAA,EAER,GAAGC,EAEH,SAAA,CAAAL,IAAS,QACRQ,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,MAAO,mBAAoB,QAAS,aAAA,EAAkB,SAAAR,CAAA,CAAK,EAE3EQ,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,WAAY,IAAK,MAAO,WAAA,EAAgB,SAAAP,CAAA,CAAM,EACrFC,IAAgB,QACfM,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,SAAU,GAAA,EAAQ,SAAAN,CAAA,CAAY,EAEvEC,IAAW,QAAaK,MAAC,MAAA,CAAI,MAAO,CAAE,UAAW,gBAAA,EAAqB,SAAAL,CAAA,CAAO,CAAA,CAAA,CAAA,CAGpF,CAAC"}
1
+ {"version":3,"file":"EmptyState-CdDQmfEL.js","sources":["../../src/web/v8/ui/feedback/EmptyState.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * EmptyState — placeholder for empty lists / zero-data views.\n *\n * Use when a view has no rows. Never use a spinner; the data is\n * genuinely empty.\n */\nexport interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n icon?: ReactNode;\n title: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n}\n\nexport const EmptyState = forwardRef<HTMLDivElement, EmptyStateProps>(function EmptyState(\n props,\n ref,\n) {\n const { icon, title, description, action, className, ...rest } = props;\n return (\n <div\n ref={ref}\n className={cx('v8-empty-state', className)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'var(--space-3)',\n padding: 'var(--space-12) var(--space-6)',\n textAlign: 'center',\n color: 'var(--fg-muted)',\n }}\n {...rest}\n >\n {icon !== undefined && (\n <div style={{ color: 'var(--fg-subtle)', display: 'inline-flex' }}>{icon}</div>\n )}\n <div style={{ fontSize: 'var(--fs-16)', fontWeight: 600, color: 'var(--fg)' }}>{title}</div>\n {description !== undefined && (\n <div style={{ fontSize: 'var(--fs-13)', maxWidth: 480 }}>{description}</div>\n )}\n {action !== undefined && <div style={{ marginTop: 'var(--space-2)' }}>{action}</div>}\n </div>\n );\n});"],"names":["EmptyState","forwardRef","props","ref","icon","title","description","action","className","rest","jsxs","cx","jsx"],"mappings":"qFAgBO,MAAMA,EAAaC,EAAAA,WAA4C,SACpEC,EACAC,EACA,CACA,KAAM,CAAE,KAAAC,EAAM,MAAAC,EAAO,YAAAC,EAAa,OAAAC,EAAQ,UAAAC,EAAW,GAAGC,GAASP,EACjE,OACEQ,EAAAA,KAAC,MAAA,CACC,IAAAP,EACA,UAAWQ,EAAG,iBAAkBH,CAAS,EACzC,MAAO,CACL,QAAS,OACT,cAAe,SACf,WAAY,SACZ,eAAgB,SAChB,IAAK,iBACL,QAAS,iCACT,UAAW,SACX,MAAO,iBAAA,EAER,GAAGC,EAEH,SAAA,CAAAL,IAAS,QACRQ,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,MAAO,mBAAoB,QAAS,aAAA,EAAkB,SAAAR,CAAA,CAAK,EAE3EQ,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,WAAY,IAAK,MAAO,WAAA,EAAgB,SAAAP,CAAA,CAAM,EACrFC,IAAgB,QACfM,EAAAA,IAAC,MAAA,CAAI,MAAO,CAAE,SAAU,eAAgB,SAAU,GAAA,EAAQ,SAAAN,CAAA,CAAY,EAEvEC,IAAW,QAAaK,MAAC,MAAA,CAAI,MAAO,CAAE,UAAW,gBAAA,EAAqB,SAAAL,CAAA,CAAO,CAAA,CAAA,CAAA,CAGpF,CAAC"}
@@ -1,4 +1,4 @@
1
- import{r as s,j as e}from"./cmdk-DVxytz9i.js";import{c as O,u as V,S as p,I as f,d as n,h as I,V as P,N as D,i as y,F as k}from"./main-Cxeu4LhG.js";import{V as Z}from"./ViewHeader-B6P-C4GD.js";import{L as M}from"./ListHeader-Dpun-r36.js";import{C as N,b as _}from"./Card-rF59wHiO.js";import{I as A}from"./Input-CZmRw5QX.js";import{S as w,a as E,b as T}from"./Sheet-BOProMs2.js";import{E as L}from"./EmptyState-D65J5FQN.js";import{D as U}from"./download-Clkq90Ct.js";import{R as q}from"./refresh-ccw-DenGBOcq.js";import{P as H}from"./plus-77h62zZm.js";import{P as K}from"./pencil-DVrBlYV3.js";import{T as J}from"./trash-2-Cv7U38jw.js";/**
1
+ import{r as s,j as e}from"./cmdk-C3F6LD6N.js";import{c as O,u as V,S as p,I as f,d as n,h as I,V as P,N as D,i as y,F as k}from"./main-BZMmD6a8.js";import{V as Z}from"./ViewHeader-BaCWNuVX.js";import{L as M}from"./ListHeader-BLAeshe0.js";import{C as N,b as _}from"./Card-BmXiT4c6.js";import{I as A}from"./Input-cAQOvR8U.js";import{S as w,a as E,b as T}from"./Sheet-CxXf6gvC.js";import{E as L}from"./EmptyState-CdDQmfEL.js";import{D as U}from"./download-DBkNb6oI.js";import{R as q}from"./refresh-ccw-BL7B0NO1.js";import{P as H}from"./plus-uA5Ecuch.js";import{P as K}from"./pencil---XuvKlz.js";import{T as J}from"./trash-2-B885GY46.js";/**
2
2
  * @license lucide-react v0.460.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.