@polderlabs/bizar 10.4.4 → 10.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/bizar-dash/dist/assets/{ActivityFeed-RQeyFifx.js → ActivityFeed-Bw4Cai7r.js} +1 -1
  2. package/bizar-dash/dist/assets/{ActivityFeed-RQeyFifx.js.map → ActivityFeed-Bw4Cai7r.js.map} +1 -1
  3. package/bizar-dash/dist/assets/{ActivityView-CibyssPM.js → ActivityView-BC0QQ_j9.js} +1 -1
  4. package/bizar-dash/dist/assets/{ActivityView-CibyssPM.js.map → ActivityView-BC0QQ_j9.js.map} +1 -1
  5. package/bizar-dash/dist/assets/{AdminView-BjczABeB.js → AdminView-CLTNKFL4.js} +1 -1
  6. package/bizar-dash/dist/assets/{AdminView-BjczABeB.js.map → AdminView-CLTNKFL4.js.map} +1 -1
  7. package/bizar-dash/dist/assets/{AgentActivity-Bywt1twv.js → AgentActivity-DBWDByjk.js} +1 -1
  8. package/bizar-dash/dist/assets/{AgentActivity-Bywt1twv.js.map → AgentActivity-DBWDByjk.js.map} +1 -1
  9. package/bizar-dash/dist/assets/{AgentsView-BnOjjM74.js → AgentsView-DD6bCIbA.js} +1 -1
  10. package/bizar-dash/dist/assets/{AgentsView-BnOjjM74.js.map → AgentsView-DD6bCIbA.js.map} +1 -1
  11. package/bizar-dash/dist/assets/{Alert-BZGk39mB.js → Alert-pzFISNtS.js} +1 -1
  12. package/bizar-dash/dist/assets/{Alert-BZGk39mB.js.map → Alert-pzFISNtS.js.map} +1 -1
  13. package/bizar-dash/dist/assets/ArtifactsView-BVU5lfo7.js +21 -0
  14. package/bizar-dash/dist/assets/ArtifactsView-BVU5lfo7.js.map +1 -0
  15. package/bizar-dash/dist/assets/{AuthView-D4frSShw.js → AuthView-BZ-bPIOM.js} +2 -2
  16. package/bizar-dash/dist/assets/AuthView-BZ-bPIOM.js.map +1 -0
  17. package/bizar-dash/dist/assets/{Avatar-BYg0rkPA.js → Avatar-CRW81ewE.js} +1 -1
  18. package/bizar-dash/dist/assets/{Avatar-BYg0rkPA.js.map → Avatar-CRW81ewE.js.map} +1 -1
  19. package/bizar-dash/dist/assets/BackgroundJobsView-w8OZtXyI.js +1 -0
  20. package/bizar-dash/dist/assets/BackgroundJobsView-w8OZtXyI.js.map +1 -0
  21. package/bizar-dash/dist/assets/{BackupView-B875KQa4.js → BackupView-u_O3j0TG.js} +1 -1
  22. package/bizar-dash/dist/assets/{BackupView-B875KQa4.js.map → BackupView-u_O3j0TG.js.map} +1 -1
  23. package/bizar-dash/dist/assets/{Banner-C8HEcT5l.js → Banner-Du-3l05O.js} +1 -1
  24. package/bizar-dash/dist/assets/{Banner-C8HEcT5l.js.map → Banner-Du-3l05O.js.map} +1 -1
  25. package/bizar-dash/dist/assets/{Card-BtsmkhJa.js → Card-Clkvh43Q.js} +1 -1
  26. package/bizar-dash/dist/assets/{Card-BtsmkhJa.js.map → Card-Clkvh43Q.js.map} +1 -1
  27. package/bizar-dash/dist/assets/{ChatView-CkNS0SD8.js → ChatView-BTjb3mIh.js} +1 -1
  28. package/bizar-dash/dist/assets/{ChatView-CkNS0SD8.js.map → ChatView-BTjb3mIh.js.map} +1 -1
  29. package/bizar-dash/dist/assets/{Chip-XPOk0d_E.js → Chip-B7ovcm01.js} +1 -1
  30. package/bizar-dash/dist/assets/{Chip-XPOk0d_E.js.map → Chip-B7ovcm01.js.map} +1 -1
  31. package/bizar-dash/dist/assets/ClaudeSessionsView-BoZS5ldi.js +1 -0
  32. package/bizar-dash/dist/assets/ClaudeSessionsView-BoZS5ldi.js.map +1 -0
  33. package/bizar-dash/dist/assets/ClipboardView-Cb6XgYZI.js +1 -0
  34. package/bizar-dash/dist/assets/{ClipboardView-CPlTU5VG.js.map → ClipboardView-Cb6XgYZI.js.map} +1 -1
  35. package/bizar-dash/dist/assets/{ConfigView-BntUrW7s.js → ConfigView-DfTJk1uL.js} +1 -1
  36. package/bizar-dash/dist/assets/{ConfigView-BntUrW7s.js.map → ConfigView-DfTJk1uL.js.map} +1 -1
  37. package/bizar-dash/dist/assets/{DiagnosticsView-4x0Zu3yP.js → DiagnosticsView-D5Wy9xlJ.js} +1 -1
  38. package/bizar-dash/dist/assets/{DiagnosticsView-4x0Zu3yP.js.map → DiagnosticsView-D5Wy9xlJ.js.map} +1 -1
  39. package/bizar-dash/dist/assets/{DialogsView-Xd02dVAX.js → DialogsView-HVyfrXpq.js} +1 -1
  40. package/bizar-dash/dist/assets/{DialogsView-Xd02dVAX.js.map → DialogsView-HVyfrXpq.js.map} +1 -1
  41. package/bizar-dash/dist/assets/{DoctorView-DepBdQGR.js → DoctorView-Dm94WI2z.js} +2 -2
  42. package/bizar-dash/dist/assets/{DoctorView-DepBdQGR.js.map → DoctorView-Dm94WI2z.js.map} +1 -1
  43. package/bizar-dash/dist/assets/{EmptyState-DjKtY1Qi.js → EmptyState-ccT__JZG.js} +1 -1
  44. package/bizar-dash/dist/assets/{EmptyState-DjKtY1Qi.js.map → EmptyState-ccT__JZG.js.map} +1 -1
  45. package/bizar-dash/dist/assets/{EnvVarsView-S4Pbm128.js → EnvVarsView-BhcIuJ6V.js} +2 -2
  46. package/bizar-dash/dist/assets/{EnvVarsView-S4Pbm128.js.map → EnvVarsView-BhcIuJ6V.js.map} +1 -1
  47. package/bizar-dash/dist/assets/{ErrorState-CBJbEQ8B.js → ErrorState-BSqf65ka.js} +1 -1
  48. package/bizar-dash/dist/assets/{ErrorState-CBJbEQ8B.js.map → ErrorState-BSqf65ka.js.map} +1 -1
  49. package/bizar-dash/dist/assets/{EvalView-BeAyMCD1.js → EvalView-2cbWVBUA.js} +1 -1
  50. package/bizar-dash/dist/assets/{EvalView-BeAyMCD1.js.map → EvalView-2cbWVBUA.js.map} +1 -1
  51. package/bizar-dash/dist/assets/{GoalsView-BZr8In4c.js → GoalsView-C3QG5p7T.js} +1 -1
  52. package/bizar-dash/dist/assets/{GoalsView-BZr8In4c.js.map → GoalsView-C3QG5p7T.js.map} +1 -1
  53. package/bizar-dash/dist/assets/{Grid--WKvqu5h.js → Grid-Bojq8Sg7.js} +1 -1
  54. package/bizar-dash/dist/assets/{Grid--WKvqu5h.js.map → Grid-Bojq8Sg7.js.map} +1 -1
  55. package/bizar-dash/dist/assets/{HistoryView-djEbzqtk.js → HistoryView-Bum2TMMw.js} +1 -1
  56. package/bizar-dash/dist/assets/{HistoryView-djEbzqtk.js.map → HistoryView-Bum2TMMw.js.map} +1 -1
  57. package/bizar-dash/dist/assets/{Input-h_nSOtwm.js → Input-DV-vdaV8.js} +1 -1
  58. package/bizar-dash/dist/assets/{Input-h_nSOtwm.js.map → Input-DV-vdaV8.js.map} +1 -1
  59. package/bizar-dash/dist/assets/{LibrariesView-Vez8CvNq.js → LibrariesView-DH2E2uNb.js} +1 -1
  60. package/bizar-dash/dist/assets/{LibrariesView-Vez8CvNq.js.map → LibrariesView-DH2E2uNb.js.map} +1 -1
  61. package/bizar-dash/dist/assets/LightRAGView-BFCcj7Tl.js +6 -0
  62. package/bizar-dash/dist/assets/LightRAGView-BFCcj7Tl.js.map +1 -0
  63. package/bizar-dash/dist/assets/{ListHeader-CM8QoIWG.js → ListHeader-CCD_nIHb.js} +1 -1
  64. package/bizar-dash/dist/assets/{ListHeader-CM8QoIWG.js.map → ListHeader-CCD_nIHb.js.map} +1 -1
  65. package/bizar-dash/dist/assets/{MemoryView-DnL8E2vI.js → MemoryView-Cr-obIQY.js} +1 -1
  66. package/bizar-dash/dist/assets/{MemoryView-DnL8E2vI.js.map → MemoryView-Cr-obIQY.js.map} +1 -1
  67. package/bizar-dash/dist/assets/{MiscView-B2YQXhZ_.js → MiscView-CDUQpYuV.js} +1 -1
  68. package/bizar-dash/dist/assets/{MiscView-B2YQXhZ_.js.map → MiscView-CDUQpYuV.js.map} +1 -1
  69. package/bizar-dash/dist/assets/{ModsView-BVM3X5xc.js → ModsView-B6OR-a4B.js} +2 -2
  70. package/bizar-dash/dist/assets/{ModsView-BVM3X5xc.js.map → ModsView-B6OR-a4B.js.map} +1 -1
  71. package/bizar-dash/dist/assets/{NotificationsView-A-Xs8BL1.js → NotificationsView-CIqtY6D0.js} +1 -1
  72. package/bizar-dash/dist/assets/{NotificationsView-A-Xs8BL1.js.map → NotificationsView-CIqtY6D0.js.map} +1 -1
  73. package/bizar-dash/dist/assets/{ObsidianView-mI3qW9OP.js → ObsidianView-Nahah8QC.js} +1 -1
  74. package/bizar-dash/dist/assets/{ObsidianView-mI3qW9OP.js.map → ObsidianView-Nahah8QC.js.map} +1 -1
  75. package/bizar-dash/dist/assets/{OverviewView-By69Cr5H.js → OverviewView-B6L_wa4M.js} +1 -1
  76. package/bizar-dash/dist/assets/{OverviewView-By69Cr5H.js.map → OverviewView-B6L_wa4M.js.map} +1 -1
  77. package/bizar-dash/dist/assets/{ProgressBar-BnaBqv-W.js → ProgressBar-KC4VXsl_.js} +1 -1
  78. package/bizar-dash/dist/assets/{ProgressBar-BnaBqv-W.js.map → ProgressBar-KC4VXsl_.js.map} +1 -1
  79. package/bizar-dash/dist/assets/{ProjectsView-C81WTFka.js → ProjectsView-DgxWiqHb.js} +1 -1
  80. package/bizar-dash/dist/assets/{ProjectsView-C81WTFka.js.map → ProjectsView-DgxWiqHb.js.map} +1 -1
  81. package/bizar-dash/dist/assets/{ProvidersView-2cn-TALE.js → ProvidersView-BOqN9omv.js} +1 -1
  82. package/bizar-dash/dist/assets/{ProvidersView-2cn-TALE.js.map → ProvidersView-BOqN9omv.js.map} +1 -1
  83. package/bizar-dash/dist/assets/SchedulesView-yMaG3Dtd.js +1 -0
  84. package/bizar-dash/dist/assets/SchedulesView-yMaG3Dtd.js.map +1 -0
  85. package/bizar-dash/dist/assets/{Select-CiGWEN8I.js → Select-Bf_P0S6H.js} +1 -1
  86. package/bizar-dash/dist/assets/{Select-CiGWEN8I.js.map → Select-Bf_P0S6H.js.map} +1 -1
  87. package/bizar-dash/dist/assets/{SettingsRow-CflGJymA.js → SettingsRow-CJb-F94Y.js} +1 -1
  88. package/bizar-dash/dist/assets/{SettingsRow-CflGJymA.js.map → SettingsRow-CJb-F94Y.js.map} +1 -1
  89. package/bizar-dash/dist/assets/{SettingsView-2HSFJPPK.js → SettingsView-BvOGcgMS.js} +2 -2
  90. package/bizar-dash/dist/assets/SettingsView-BvOGcgMS.js.map +1 -0
  91. package/bizar-dash/dist/assets/{Sheet-B-CMP9-_.js → Sheet-BwMVGN-8.js} +1 -1
  92. package/bizar-dash/dist/assets/{Sheet-B-CMP9-_.js.map → Sheet-BwMVGN-8.js.map} +1 -1
  93. package/bizar-dash/dist/assets/{Slider-Z4TP_CXY.js → Slider-AjjzqI-5.js} +1 -1
  94. package/bizar-dash/dist/assets/{Slider-Z4TP_CXY.js.map → Slider-AjjzqI-5.js.map} +1 -1
  95. package/bizar-dash/dist/assets/{Sparkline-cvkv2HbU.js → Sparkline-Z4y0YUZS.js} +1 -1
  96. package/bizar-dash/dist/assets/{Sparkline-cvkv2HbU.js.map → Sparkline-Z4y0YUZS.js.map} +1 -1
  97. package/bizar-dash/dist/assets/{Switch-jcYo4lmp.js → Switch-B79a2t-G.js} +1 -1
  98. package/bizar-dash/dist/assets/{Switch-jcYo4lmp.js.map → Switch-B79a2t-G.js.map} +1 -1
  99. package/bizar-dash/dist/assets/{TasksView-CQaSFzWY.js → TasksView-G-s_pwwr.js} +1 -1
  100. package/bizar-dash/dist/assets/{TasksView-CQaSFzWY.js.map → TasksView-G-s_pwwr.js.map} +1 -1
  101. package/bizar-dash/dist/assets/{Textarea-xnAybFGd.js → Textarea-BfXGMXQ7.js} +1 -1
  102. package/bizar-dash/dist/assets/{Textarea-xnAybFGd.js.map → Textarea-BfXGMXQ7.js.map} +1 -1
  103. package/bizar-dash/dist/assets/{UpdateView-BUAEcRCX.js → UpdateView-BKx3u9X8.js} +1 -1
  104. package/bizar-dash/dist/assets/{UpdateView-BUAEcRCX.js.map → UpdateView-BKx3u9X8.js.map} +1 -1
  105. package/bizar-dash/dist/assets/{UsageView-DMFbBOfH.js → UsageView-M01G6bZQ.js} +1 -1
  106. package/bizar-dash/dist/assets/{UsageView-DMFbBOfH.js.map → UsageView-M01G6bZQ.js.map} +1 -1
  107. package/bizar-dash/dist/assets/{ViewHeader-C-t1U2cQ.js → ViewHeader-BsnaspKw.js} +1 -1
  108. package/bizar-dash/dist/assets/{ViewHeader-C-t1U2cQ.js.map → ViewHeader-BsnaspKw.js.map} +1 -1
  109. package/bizar-dash/dist/assets/VoiceView-rWE8vziD.js +1 -0
  110. package/bizar-dash/dist/assets/{VoiceView-aoPVT6LJ.js.map → VoiceView-rWE8vziD.js.map} +1 -1
  111. package/bizar-dash/dist/assets/{brain-DhAzcHUk.js → brain-D7k5s8vH.js} +1 -1
  112. package/bizar-dash/dist/assets/{brain-DhAzcHUk.js.map → brain-D7k5s8vH.js.map} +1 -1
  113. package/bizar-dash/dist/assets/{calendar-B9Wbemh7.js → calendar-CAZoDd-l.js} +1 -1
  114. package/bizar-dash/dist/assets/{calendar-B9Wbemh7.js.map → calendar-CAZoDd-l.js.map} +1 -1
  115. package/bizar-dash/dist/assets/{circle-6NJF_Xl6.js → circle-D99cZJBr.js} +1 -1
  116. package/bizar-dash/dist/assets/{circle-6NJF_Xl6.js.map → circle-D99cZJBr.js.map} +1 -1
  117. package/bizar-dash/dist/assets/{circle-alert-Dz8lGfCZ.js → circle-alert-QQTU4Quz.js} +1 -1
  118. package/bizar-dash/dist/assets/{circle-alert-Dz8lGfCZ.js.map → circle-alert-QQTU4Quz.js.map} +1 -1
  119. package/bizar-dash/dist/assets/{circle-check-DFB50ojt.js → circle-check-BMbe7Kkr.js} +1 -1
  120. package/bizar-dash/dist/assets/{circle-check-DFB50ojt.js.map → circle-check-BMbe7Kkr.js.map} +1 -1
  121. package/bizar-dash/dist/assets/{clock-ClVA6-hQ.js → clock-OtT5mvF3.js} +1 -1
  122. package/bizar-dash/dist/assets/{clock-ClVA6-hQ.js.map → clock-OtT5mvF3.js.map} +1 -1
  123. package/bizar-dash/dist/assets/{download-BvJddD8D.js → download-B-mPX5P_.js} +1 -1
  124. package/bizar-dash/dist/assets/{download-BvJddD8D.js.map → download-B-mPX5P_.js.map} +1 -1
  125. package/bizar-dash/dist/assets/{external-link-DvL89gaZ.js → external-link-DPDQM1YO.js} +1 -1
  126. package/bizar-dash/dist/assets/{external-link-DvL89gaZ.js.map → external-link-DPDQM1YO.js.map} +1 -1
  127. package/bizar-dash/dist/assets/{file-text-BOroDtZE.js → file-text-BsCrv5aP.js} +1 -1
  128. package/bizar-dash/dist/assets/{file-text-BOroDtZE.js.map → file-text-BsCrv5aP.js.map} +1 -1
  129. package/bizar-dash/dist/assets/{filter-DwPjMRQt.js → filter-Do63x17E.js} +1 -1
  130. package/bizar-dash/dist/assets/{filter-DwPjMRQt.js.map → filter-Do63x17E.js.map} +1 -1
  131. package/bizar-dash/dist/assets/{git-pull-request-TDb1inux.js → git-pull-request-CpRAmERC.js} +1 -1
  132. package/bizar-dash/dist/assets/{git-pull-request-TDb1inux.js.map → git-pull-request-CpRAmERC.js.map} +1 -1
  133. package/bizar-dash/dist/assets/main-BRmJZcHt.js +277 -0
  134. package/bizar-dash/dist/assets/main-BRmJZcHt.js.map +1 -0
  135. package/bizar-dash/dist/assets/main-D0TY0myE.css +1 -0
  136. package/bizar-dash/dist/assets/{network-BcCoCzIY.js → network-DJnHwHX3.js} +1 -1
  137. package/bizar-dash/dist/assets/{network-BcCoCzIY.js.map → network-DJnHwHX3.js.map} +1 -1
  138. package/bizar-dash/dist/assets/{pause-BllItT2_.js → pause-HitDUnk_.js} +1 -1
  139. package/bizar-dash/dist/assets/{pause-BllItT2_.js.map → pause-HitDUnk_.js.map} +1 -1
  140. package/bizar-dash/dist/assets/{pencil-DAwM-CC3.js → pencil-Dkks7eIC.js} +1 -1
  141. package/bizar-dash/dist/assets/{pencil-DAwM-CC3.js.map → pencil-Dkks7eIC.js.map} +1 -1
  142. package/bizar-dash/dist/assets/{play-mJh67AXo.js → play-blqh0msT.js} +1 -1
  143. package/bizar-dash/dist/assets/{play-mJh67AXo.js.map → play-blqh0msT.js.map} +1 -1
  144. package/bizar-dash/dist/assets/{plug-BjfntCMC.js → plug-DVvSSe40.js} +1 -1
  145. package/bizar-dash/dist/assets/{plug-BjfntCMC.js.map → plug-DVvSSe40.js.map} +1 -1
  146. package/bizar-dash/dist/assets/{plus-Cm6-fo14.js → plus-Cps-8lcG.js} +1 -1
  147. package/bizar-dash/dist/assets/{plus-Cm6-fo14.js.map → plus-Cps-8lcG.js.map} +1 -1
  148. package/bizar-dash/dist/assets/{power-CXN9y2KV.js → power-DEX4_Xoa.js} +1 -1
  149. package/bizar-dash/dist/assets/{power-CXN9y2KV.js.map → power-DEX4_Xoa.js.map} +1 -1
  150. package/bizar-dash/dist/assets/{power-off-DUZqwMf9.js → power-off-upZ4xjaG.js} +1 -1
  151. package/bizar-dash/dist/assets/{power-off-DUZqwMf9.js.map → power-off-upZ4xjaG.js.map} +1 -1
  152. package/bizar-dash/dist/assets/{refresh-ccw-DA8_IB9l.js → refresh-ccw-DN_zCB1h.js} +1 -1
  153. package/bizar-dash/dist/assets/{refresh-ccw-DA8_IB9l.js.map → refresh-ccw-DN_zCB1h.js.map} +1 -1
  154. package/bizar-dash/dist/assets/{refresh-cw-DwlP59en.js → refresh-cw-KGm5eQgv.js} +1 -1
  155. package/bizar-dash/dist/assets/{refresh-cw-DwlP59en.js.map → refresh-cw-KGm5eQgv.js.map} +1 -1
  156. package/bizar-dash/dist/assets/{rotate-ccw-DMTASfAn.js → rotate-ccw-D5fkDRgk.js} +1 -1
  157. package/bizar-dash/dist/assets/{rotate-ccw-DMTASfAn.js.map → rotate-ccw-D5fkDRgk.js.map} +1 -1
  158. package/bizar-dash/dist/assets/{rotate-cw-BDX5SE2s.js → rotate-cw-CClSVUaX.js} +1 -1
  159. package/bizar-dash/dist/assets/{rotate-cw-BDX5SE2s.js.map → rotate-cw-CClSVUaX.js.map} +1 -1
  160. package/bizar-dash/dist/assets/{save-Y0jPK5D6.js → save-BY4ViPku.js} +1 -1
  161. package/bizar-dash/dist/assets/{save-Y0jPK5D6.js.map → save-BY4ViPku.js.map} +1 -1
  162. package/bizar-dash/dist/assets/{send-C8wwPHhR.js → send-CaOL1yQD.js} +1 -1
  163. package/bizar-dash/dist/assets/{send-C8wwPHhR.js.map → send-CaOL1yQD.js.map} +1 -1
  164. package/bizar-dash/dist/assets/{shield-alert-DEvq9UG0.js → shield-alert-DA9K6uZO.js} +1 -1
  165. package/bizar-dash/dist/assets/{shield-alert-DEvq9UG0.js.map → shield-alert-DA9K6uZO.js.map} +1 -1
  166. package/bizar-dash/dist/assets/{trash-2-D6qePV_q.js → trash-2-B_Y6HrfN.js} +1 -1
  167. package/bizar-dash/dist/assets/{trash-2-D6qePV_q.js.map → trash-2-B_Y6HrfN.js.map} +1 -1
  168. package/bizar-dash/dist/assets/{trending-up-BZzo_1ic.js → trending-up-qKTUQKIT.js} +1 -1
  169. package/bizar-dash/dist/assets/{trending-up-BZzo_1ic.js.map → trending-up-qKTUQKIT.js.map} +1 -1
  170. package/bizar-dash/dist/assets/{triangle-alert-B2oHbmoh.js → triangle-alert-BeY8LAv6.js} +1 -1
  171. package/bizar-dash/dist/assets/{triangle-alert-B2oHbmoh.js.map → triangle-alert-BeY8LAv6.js.map} +1 -1
  172. package/bizar-dash/dist/assets/{upload-Dy59aZn6.js → upload-BZCtmqIh.js} +1 -1
  173. package/bizar-dash/dist/assets/{upload-Dy59aZn6.js.map → upload-BZCtmqIh.js.map} +1 -1
  174. package/bizar-dash/dist/assets/{zap-DENVhJnO.js → zap-Bz1Z8y1Q.js} +1 -1
  175. package/bizar-dash/dist/assets/{zap-DENVhJnO.js.map → zap-Bz1Z8y1Q.js.map} +1 -1
  176. package/bizar-dash/dist/index.html +2 -2
  177. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  178. package/bizar-dash/src/web/v8/shell/Sidebar.tsx +41 -31
  179. package/bizar-dash/src/web/v8/shell/Topbar.tsx +63 -23
  180. package/bizar-dash/src/web/v8/ui/feedback/NotificationsPopover.tsx +3 -0
  181. package/bizar-dash/src/web/v8/ui/feedback/useFocusTrap.ts +58 -0
  182. package/bizar-dash/src/web/v8/ui/navigation/CommandPalette.tsx +1 -0
  183. package/bizar-dash/src/web/v8/ui/styles/tokens.css +21 -0
  184. package/bizar-dash/src/web/v8/views/Artifacts/ClaudeArtifactView.tsx +1 -1
  185. package/bizar-dash/src/web/v8/views/Auth/AuthView.tsx +10 -6
  186. package/bizar-dash/src/web/v8/views/BackgroundJobs/BackgroundJobsView.tsx +38 -13
  187. package/bizar-dash/src/web/v8/views/ClaudeSessions/ClaudeSessionDetail.tsx +16 -5
  188. package/bizar-dash/src/web/v8/views/LightRAG/LightRAGView.tsx +23 -2
  189. package/bizar-dash/src/web/v8/views/Schedules/SchedulesView.tsx +48 -13
  190. package/bizar-dash/src/web/v8/views/Settings/SettingsView.tsx +3 -3
  191. package/bizar-dash/tests/auth-inputs-labels.test.mjs +45 -0
  192. package/bizar-dash/tests/background-jobs-action-labels.test.mjs +41 -0
  193. package/bizar-dash/tests/background-jobs-states.test.mjs +80 -0
  194. package/bizar-dash/tests/banner-tones.test.mjs +50 -0
  195. package/bizar-dash/tests/callout-tokens.test.mjs +30 -0
  196. package/bizar-dash/tests/claude-session-detail-states.test.mjs +67 -0
  197. package/bizar-dash/tests/components/BackgroundJobsSkeleton.test.tsx +38 -0
  198. package/bizar-dash/tests/density-tokens.test.mjs +46 -0
  199. package/bizar-dash/tests/doctor-route-shape.test.mjs +67 -0
  200. package/bizar-dash/tests/errorstate-retry.test.mjs +42 -0
  201. package/bizar-dash/tests/lightrag-skeleton.test.mjs +31 -0
  202. package/bizar-dash/tests/lightrag-states.test.mjs +60 -0
  203. package/bizar-dash/tests/modal-focus-trap.test.mjs +114 -0
  204. package/bizar-dash/tests/orphan-tests-audit.test.mjs +80 -0
  205. package/bizar-dash/tests/palette-keyboard-nav.test.mjs +123 -0
  206. package/bizar-dash/tests/schedules-skeleton.test.mjs +25 -0
  207. package/bizar-dash/tests/schedules-states.test.mjs +67 -0
  208. package/bizar-dash/tests/sidebar-collapse-animation.test.mjs +37 -0
  209. package/bizar-dash/tests/sidebar-section-styles.test.mjs +55 -0
  210. package/bizar-dash/tests/skeleton-height.test.mjs +47 -0
  211. package/bizar-dash/tests/space-tokens.test.mjs +36 -0
  212. package/bizar-dash/tests/stattile-loading.test.mjs +28 -0
  213. package/bizar-dash/tests/topbar-popover-styles.test.mjs +53 -0
  214. package/bizar-dash/tests/update-channels.test.mjs +67 -0
  215. package/package.json +1 -1
  216. package/packages/sdk/${HOME}/.bizar_home/memory/projects/sdk/sessions/2026-07-16-e16c2f59.md +14 -0
  217. package/packages/sdk/.bizar/learning/instincts.jsonl +5 -0
  218. package/packages/sdk/package.json +1 -1
  219. package/scripts/loop-log.txt +29 -0
  220. package/scripts/loop-tasks.md +79 -0
  221. package/scripts/overnight-loop.mjs +60 -0
  222. package/bizar-dash/dist/assets/ArtifactsView-CfYB1le1.js +0 -21
  223. package/bizar-dash/dist/assets/ArtifactsView-CfYB1le1.js.map +0 -1
  224. package/bizar-dash/dist/assets/AuthView-D4frSShw.js.map +0 -1
  225. package/bizar-dash/dist/assets/BackgroundJobsView-DEStvILz.js +0 -1
  226. package/bizar-dash/dist/assets/BackgroundJobsView-DEStvILz.js.map +0 -1
  227. package/bizar-dash/dist/assets/ClaudeSessionsView-BprGo67K.js +0 -1
  228. package/bizar-dash/dist/assets/ClaudeSessionsView-BprGo67K.js.map +0 -1
  229. package/bizar-dash/dist/assets/ClipboardView-CPlTU5VG.js +0 -1
  230. package/bizar-dash/dist/assets/LightRAGView-DvqzQoBp.js +0 -6
  231. package/bizar-dash/dist/assets/LightRAGView-DvqzQoBp.js.map +0 -1
  232. package/bizar-dash/dist/assets/SchedulesView-o9AtIsH9.js +0 -1
  233. package/bizar-dash/dist/assets/SchedulesView-o9AtIsH9.js.map +0 -1
  234. package/bizar-dash/dist/assets/SettingsView-2HSFJPPK.js.map +0 -1
  235. package/bizar-dash/dist/assets/VoiceView-aoPVT6LJ.js +0 -1
  236. package/bizar-dash/dist/assets/main-B7D_IMTh.css +0 -1
  237. package/bizar-dash/dist/assets/main-BURAlktW.js +0 -277
  238. package/bizar-dash/dist/assets/main-BURAlktW.js.map +0 -1
  239. package/bizar-dash/tests/chat-session-create.test.mjs +0 -391
  240. package/bizar-dash/tests/chat-session-stream.test.mjs +0 -308
  241. package/bizar-dash/tests/cline-runner.test.mjs +0 -172
  242. package/bizar-dash/tests/cline-sessions-detail.test.mjs +0 -434
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LightRAGView-BFCcj7Tl.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/circle-play.js","../../src/web/v8/views/LightRAG/LightRAGView.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 CirclePlay = createLucideIcon(\"CirclePlay\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"polygon\", { points: \"10 8 16 12 10 16 10 8\", key: \"1cimsy\" }]\n]);\n\nexport { CirclePlay as default };\n//# sourceMappingURL=circle-play.js.map\n","/**\n * v8/views/LightRAG/LightRAGView.tsx — Sprint S43, v9.3.0.\n *\n * Defaults override form (GET/PUT /api/lightrag/defaults), runtime\n * status (GET /api/lightrag/status: running, pid, host:port, log\n * tail), and an Autostart trigger (POST /api/lightrag/autostart).\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Database, RefreshCcw, Save, PlayCircle, Circle } 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 { Skeleton, SkeletonText } 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';\n\ninterface Defaults {\n llm: string;\n embedding: string;\n source?: string;\n llmSource?: string;\n embeddingSource?: string;\n builtin?: { llm: string; embedding: string };\n envVars?: { BIZAR_LIGHTRAG_LLM: string | null; BIZAR_LIGHTRAG_EMBEDDING: string | null };\n}\n\ninterface Status {\n running: boolean;\n pid: number | null;\n host?: string;\n port?: number;\n llmBinding?: string;\n embeddingBinding?: string;\n llmModel?: string;\n embeddingModel?: string;\n logSize?: number;\n logTail?: string[];\n}\n\nexport function LightRAGView(): JSX.Element {\n const defaultsPayload = useFetch<Defaults>('/api/lightrag/defaults');\n const statusPayload = useFetch<Status>('/api/lightrag/status');\n const [llm, setLlm] = useState<string>('');\n const [embedding, setEmbedding] = useState<string>('');\n const [busy, setBusy] = useState<boolean>(false);\n const [saved, setSaved] = useState<boolean>(false);\n const [autostarting, setAutostarting] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (defaultsPayload.data) {\n setLlm(defaultsPayload.data.llm ?? '');\n setEmbedding(defaultsPayload.data.embedding ?? '');\n }\n }, [defaultsPayload.data]);\n\n const refresh = useCallback(() => { void defaultsPayload.refetch(); void statusPayload.refetch(); }, [defaultsPayload, statusPayload]);\n\n const save = async (): Promise<void> => {\n setBusy(true);\n setError(null);\n setSaved(false);\n try {\n await fetchJson('/api/lightrag/defaults', { method: 'PUT', body: { llm, embedding } });\n setSaved(true);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n };\n\n const autostart = async (): Promise<void> => {\n setAutostarting(true);\n setError(null);\n try {\n await fetchJson('/api/lightrag/autostart', { method: 'POST' });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setAutostarting(false);\n }\n };\n\n const status = statusPayload.data;\n const fetchError = defaultsPayload.error ?? statusPayload.error;\n\n return (\n <Stack gap={4} data-testid=\"lightrag-view\">\n <ViewHeader\n title=\"LightRAG\"\n description=\"LightRAG defaults + runtime status + autostart.\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"lightrag-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"lightrag-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => void save()} disabled={busy} data-testid=\"lightrag-save\">\n <Save size={14} aria-hidden /> {busy ? 'Saving…' : 'Save'}\n </Button>\n </Inline>\n }\n />\n\n {fetchError && (\n <ErrorState\n title=\"LightRAG unavailable\"\n description={fetchError.message || String(fetchError)}\n onRetry={() => void refresh()}\n data-testid=\"lightrag-fetch-error\"\n />\n )}\n\n <Card variant=\"default\">\n <CardBody>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Defaults</strong>\n {defaultsPayload.loading && defaultsPayload.data === null ? (\n <Skeleton style={{ height: 100, marginTop: 'var(--space-2)' }} />\n ) : (\n <Stack gap={2} style={{ marginTop: 'var(--space-2)' }}>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>LLM binding</span>\n <Input value={llm} onChange={(e) => setLlm((e.target as HTMLInputElement).value)} data-testid=\"lightrag-llm\" />\n </label>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Embedding binding</span>\n <Input value={embedding} onChange={(e) => setEmbedding((e.target as HTMLInputElement).value)} data-testid=\"lightrag-embedding\" />\n </label>\n {defaultsPayload.data?.builtin && (\n <Inline gap={2} style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>\n <span>built-in:</span>\n <code>{defaultsPayload.data.builtin.llm}</code> /\n <code>{defaultsPayload.data.builtin.embedding}</code>\n </Inline>\n )}\n {saved && <span data-testid=\"lightrag-saved\" style={{ color: 'var(--success)', fontSize: 'var(--fs-12)' }}>Saved</span>}\n </Stack>\n )}\n </CardBody>\n </Card>\n\n <Card variant=\"default\">\n <CardBody>\n <Inline align=\"center\" justify=\"between\" gap={2}>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Status</strong>\n <Inline align=\"center\" gap={2}>\n {status === null || status === undefined ? (\n <Skeleton style={{ width: 80, height: 14 }} />\n ) : status.running ? (\n <Inline align=\"center\" gap={1} data-testid=\"lightrag-running\">\n <Circle size={10} aria-hidden style={{ color: 'var(--success)', fill: 'var(--success)' }} />\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--success)' }}>running · pid {status.pid}</span>\n </Inline>\n ) : (\n <Inline align=\"center\" gap={1} data-testid=\"lightrag-stopped\">\n <Circle size={10} aria-hidden style={{ color: 'var(--fg-muted)', fill: 'var(--fg-muted)' }} />\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>stopped</span>\n </Inline>\n )}\n <Button variant=\"ghost\" onClick={() => void autostart()} disabled={autostarting} data-testid=\"lightrag-autostart\">\n <PlayCircle size={14} aria-hidden /> {autostarting ? 'Starting…' : 'Autostart'}\n </Button>\n </Inline>\n </Inline>\n {status && (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)', fontSize: 'var(--fs-12)' }}>\n <Inline gap={2}>\n <Database size={12} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n <code>{status.host}:{status.port}</code>\n {status.llmBinding && <span style={{ color: 'var(--fg-muted)' }}>· llm: <code>{status.llmBinding}</code></span>}\n {status.embeddingBinding && <span style={{ color: 'var(--fg-muted)' }}>· embedding: <code>{status.embeddingBinding}</code></span>}\n </Inline>\n {status.logTail && status.logTail.length > 0 ? (\n <div data-testid=\"lightrag-log\" style={{ background: 'var(--surface-1)', borderRadius: 'var(--radius-sm)', padding: 'var(--space-2)', fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-11)', maxHeight: 160, overflow: 'auto' }}>\n {status.logTail.filter(Boolean).slice(-10).map((l, i) => (<div key={i}>{l}</div>))}\n </div>\n ) : statusPayload.loading ? (\n <SkeletonText lines={4} lastLineWidth=\"75%\" />\n ) : (\n <EmptyState\n icon={<Database size={20} aria-hidden />}\n title=\"No log output yet\"\n description=\"LightRAG has not emitted any log lines. Autostart a run to populate.\"\n data-testid=\"lightrag-log-empty\"\n />\n )}\n </Stack>\n )}\n </CardBody>\n </Card>\n </Stack>\n );\n}"],"names":["CirclePlay","createLucideIcon","LightRAGView","defaultsPayload","useFetch","statusPayload","llm","setLlm","useState","embedding","setEmbedding","busy","setBusy","saved","setSaved","autostarting","setAutostarting","error","setError","useEffect","refresh","useCallback","save","fetchJson","err","FetchError","autostart","status","fetchError","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCcw","Save","ErrorState","Card","CardBody","Skeleton","Input","e","_a","Circle","PlayCircle","Database","l","i","SkeletonText","EmptyState"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1 +1 @@
1
- import{r as f,j as e}from"./cmdk-C3F6LD6N.js";import{g as x}from"./main-BURAlktW.js";const g=f.forwardRef(function(l,d){const{title:n,count:a,sparkline:s,filters:r,actions:t,description:i,testid:o,className:c,...p}=l;return e.jsxs("div",{ref:d,"data-testid":o??"list-header",className:x("v8-list-header",c),style:{display:"flex",flexDirection:"column",gap:"var(--space-2)",marginBottom:"var(--space-2)"},...p,children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--space-3)",flexWrap:"wrap"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--space-2)",flex:1,minWidth:0},children:[e.jsx("h2",{style:{margin:0,fontSize:"var(--fs-16)",fontWeight:600},children:n}),a!=null&&e.jsx("span",{"data-testid":"list-header-count",style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)",fontVariantNumeric:"tabular-nums",background:"var(--surface-1)",padding:"2px 8px",borderRadius:"var(--radius-pill)",border:"1px solid var(--border)"},children:a}),s!==void 0&&e.jsx("span",{"data-testid":"list-header-sparkline",children:s}),i!==void 0&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-subtle)"},children:i})]}),t!==void 0&&e.jsx("div",{style:{display:"flex",alignItems:"center",gap:"var(--space-1)",flexShrink:0},children:t})]}),r!==void 0&&e.jsx("div",{"data-testid":"list-header-filters",style:{display:"flex",alignItems:"center",gap:"var(--space-1)",flexWrap:"wrap"},children:r})]})});export{g as L};
1
+ import{r as f,j as e}from"./cmdk-C3F6LD6N.js";import{g as x}from"./main-BRmJZcHt.js";const g=f.forwardRef(function(l,d){const{title:n,count:a,sparkline:s,filters:r,actions:t,description:i,testid:o,className:c,...p}=l;return e.jsxs("div",{ref:d,"data-testid":o??"list-header",className:x("v8-list-header",c),style:{display:"flex",flexDirection:"column",gap:"var(--space-2)",marginBottom:"var(--space-2)"},...p,children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--space-3)",flexWrap:"wrap"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"var(--space-2)",flex:1,minWidth:0},children:[e.jsx("h2",{style:{margin:0,fontSize:"var(--fs-16)",fontWeight:600},children:n}),a!=null&&e.jsx("span",{"data-testid":"list-header-count",style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)",fontVariantNumeric:"tabular-nums",background:"var(--surface-1)",padding:"2px 8px",borderRadius:"var(--radius-pill)",border:"1px solid var(--border)"},children:a}),s!==void 0&&e.jsx("span",{"data-testid":"list-header-sparkline",children:s}),i!==void 0&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-subtle)"},children:i})]}),t!==void 0&&e.jsx("div",{style:{display:"flex",alignItems:"center",gap:"var(--space-1)",flexShrink:0},children:t})]}),r!==void 0&&e.jsx("div",{"data-testid":"list-header-filters",style:{display:"flex",alignItems:"center",gap:"var(--space-1)",flexWrap:"wrap"},children:r})]})});export{g as L};
@@ -1 +1 @@
1
- {"version":3,"file":"ListHeader-CM8QoIWG.js","sources":["../../src/web/v8/ui/data/ListHeader.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * ListHeader — section header for list/grid views.\n *\n * Composes a label + count badge + optional sparkline + optional\n * filter chips + right-aligned actions. Use at the top of a Card\n * or as a standalone section divider.\n *\n * Two patterns supported:\n * - Minimal: `<title> <count?> <actions?>`\n * - Data-driven: `<title> <sparkline?> <chips?> <actions?>`\n */\nexport interface ListHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title: ReactNode;\n /** Optional numeric badge — e.g. `42` rendered as `42 items`. */\n count?: number | null;\n /** Inline sparkline (pass a Sparkline node, not raw data). */\n sparkline?: ReactNode;\n /** Inline filter chips — rendered as a wrapping row. */\n filters?: ReactNode;\n /** Right-aligned action area (buttons, refresh, etc). */\n actions?: ReactNode;\n /** Optional helper text under the title. */\n description?: ReactNode;\n testid?: string;\n}\n\nexport const ListHeader = forwardRef<HTMLDivElement, ListHeaderProps>(function ListHeader(props, ref) {\n const { title, count, sparkline, filters, actions, description, testid, className, ...rest } = props;\n return (\n <div\n ref={ref}\n data-testid={testid ?? 'list-header'}\n className={cx('v8-list-header', className)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-2)',\n marginBottom: 'var(--space-2)',\n }}\n {...rest}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-3)',\n flexWrap: 'wrap',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)', flex: 1, minWidth: 0 }}>\n <h2 style={{ margin: 0, fontSize: 'var(--fs-16)', fontWeight: 600 }}>{title}</h2>\n {count !== undefined && count !== null && (\n <span\n data-testid=\"list-header-count\"\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-muted)',\n fontVariantNumeric: 'tabular-nums',\n background: 'var(--surface-1)',\n padding: '2px 8px',\n borderRadius: 'var(--radius-pill)',\n border: '1px solid var(--border)',\n }}\n >\n {count}\n </span>\n )}\n {sparkline !== undefined && (\n <span data-testid=\"list-header-sparkline\">{sparkline}</span>\n )}\n {description !== undefined && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>{description}</span>\n )}\n </div>\n {actions !== undefined && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-1)', flexShrink: 0 }}>\n {actions}\n </div>\n )}\n </div>\n {filters !== undefined && (\n <div\n data-testid=\"list-header-filters\"\n style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-1)', flexWrap: 'wrap' }}\n >\n {filters}\n </div>\n )}\n </div>\n );\n});"],"names":["ListHeader","forwardRef","props","ref","title","count","sparkline","filters","actions","description","testid","className","rest","jsxs","cx","jsx"],"mappings":"qFA6BO,MAAMA,EAAaC,EAAAA,WAA4C,SAAoBC,EAAOC,EAAK,CACpG,KAAM,CAAE,MAAAC,EAAO,MAAAC,EAAO,UAAAC,EAAW,QAAAC,EAAS,QAAAC,EAAS,YAAAC,EAAa,OAAAC,EAAQ,UAAAC,EAAW,GAAGC,CAAA,EAASV,EAC/F,OACEW,EAAAA,KAAC,MAAA,CACC,IAAAV,EACA,cAAaO,GAAU,cACvB,UAAWI,EAAG,iBAAkBH,CAAS,EACzC,MAAO,CACL,QAAS,OACT,cAAe,SACf,IAAK,iBACL,aAAc,gBAAA,EAEf,GAAGC,EAEJ,SAAA,CAAAC,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,iBACL,SAAU,MAAA,EAGZ,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,iBAAkB,KAAM,EAAG,SAAU,GAC7F,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,MAAO,CAAE,OAAQ,EAAG,SAAU,eAAgB,WAAY,GAAA,EAAQ,SAAAX,CAAA,CAAM,EACpDC,GAAU,MAChCU,EAAAA,IAAC,OAAA,CACC,cAAY,oBACZ,MAAO,CACL,SAAU,eACV,MAAO,kBACP,mBAAoB,eACpB,WAAY,mBACZ,QAAS,UACT,aAAc,qBACd,OAAQ,yBAAA,EAGT,SAAAV,CAAA,CAAA,EAGJC,IAAc,QACbS,EAAAA,IAAC,OAAA,CAAK,cAAY,wBAAyB,SAAAT,EAAU,EAEtDG,IAAgB,QACfM,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,oBAAuB,SAAAN,CAAA,CAAY,CAAA,EAEvF,EACCD,IAAY,QACXO,MAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,iBAAkB,WAAY,CAAA,EACrF,SAAAP,CAAA,CACH,CAAA,CAAA,CAAA,EAGHD,IAAY,QACXQ,EAAAA,IAAC,MAAA,CACC,cAAY,sBACZ,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,iBAAkB,SAAU,MAAA,EAEhF,SAAAR,CAAA,CAAA,CACH,CAAA,CAAA,CAIR,CAAC"}
1
+ {"version":3,"file":"ListHeader-CCD_nIHb.js","sources":["../../src/web/v8/ui/data/ListHeader.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cx } from '../utils/cx.js';\n\n/**\n * ListHeader — section header for list/grid views.\n *\n * Composes a label + count badge + optional sparkline + optional\n * filter chips + right-aligned actions. Use at the top of a Card\n * or as a standalone section divider.\n *\n * Two patterns supported:\n * - Minimal: `<title> <count?> <actions?>`\n * - Data-driven: `<title> <sparkline?> <chips?> <actions?>`\n */\nexport interface ListHeaderProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n title: ReactNode;\n /** Optional numeric badge — e.g. `42` rendered as `42 items`. */\n count?: number | null;\n /** Inline sparkline (pass a Sparkline node, not raw data). */\n sparkline?: ReactNode;\n /** Inline filter chips — rendered as a wrapping row. */\n filters?: ReactNode;\n /** Right-aligned action area (buttons, refresh, etc). */\n actions?: ReactNode;\n /** Optional helper text under the title. */\n description?: ReactNode;\n testid?: string;\n}\n\nexport const ListHeader = forwardRef<HTMLDivElement, ListHeaderProps>(function ListHeader(props, ref) {\n const { title, count, sparkline, filters, actions, description, testid, className, ...rest } = props;\n return (\n <div\n ref={ref}\n data-testid={testid ?? 'list-header'}\n className={cx('v8-list-header', className)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--space-2)',\n marginBottom: 'var(--space-2)',\n }}\n {...rest}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 'var(--space-3)',\n flexWrap: 'wrap',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)', flex: 1, minWidth: 0 }}>\n <h2 style={{ margin: 0, fontSize: 'var(--fs-16)', fontWeight: 600 }}>{title}</h2>\n {count !== undefined && count !== null && (\n <span\n data-testid=\"list-header-count\"\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-muted)',\n fontVariantNumeric: 'tabular-nums',\n background: 'var(--surface-1)',\n padding: '2px 8px',\n borderRadius: 'var(--radius-pill)',\n border: '1px solid var(--border)',\n }}\n >\n {count}\n </span>\n )}\n {sparkline !== undefined && (\n <span data-testid=\"list-header-sparkline\">{sparkline}</span>\n )}\n {description !== undefined && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>{description}</span>\n )}\n </div>\n {actions !== undefined && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-1)', flexShrink: 0 }}>\n {actions}\n </div>\n )}\n </div>\n {filters !== undefined && (\n <div\n data-testid=\"list-header-filters\"\n style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-1)', flexWrap: 'wrap' }}\n >\n {filters}\n </div>\n )}\n </div>\n );\n});"],"names":["ListHeader","forwardRef","props","ref","title","count","sparkline","filters","actions","description","testid","className","rest","jsxs","cx","jsx"],"mappings":"qFA6BO,MAAMA,EAAaC,EAAAA,WAA4C,SAAoBC,EAAOC,EAAK,CACpG,KAAM,CAAE,MAAAC,EAAO,MAAAC,EAAO,UAAAC,EAAW,QAAAC,EAAS,QAAAC,EAAS,YAAAC,EAAa,OAAAC,EAAQ,UAAAC,EAAW,GAAGC,CAAA,EAASV,EAC/F,OACEW,EAAAA,KAAC,MAAA,CACC,IAAAV,EACA,cAAaO,GAAU,cACvB,UAAWI,EAAG,iBAAkBH,CAAS,EACzC,MAAO,CACL,QAAS,OACT,cAAe,SACf,IAAK,iBACL,aAAc,gBAAA,EAEf,GAAGC,EAEJ,SAAA,CAAAC,EAAAA,KAAC,MAAA,CACC,MAAO,CACL,QAAS,OACT,WAAY,SACZ,IAAK,iBACL,SAAU,MAAA,EAGZ,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,iBAAkB,KAAM,EAAG,SAAU,GAC7F,SAAA,CAAAE,EAAAA,IAAC,KAAA,CAAG,MAAO,CAAE,OAAQ,EAAG,SAAU,eAAgB,WAAY,GAAA,EAAQ,SAAAX,CAAA,CAAM,EACpDC,GAAU,MAChCU,EAAAA,IAAC,OAAA,CACC,cAAY,oBACZ,MAAO,CACL,SAAU,eACV,MAAO,kBACP,mBAAoB,eACpB,WAAY,mBACZ,QAAS,UACT,aAAc,qBACd,OAAQ,yBAAA,EAGT,SAAAV,CAAA,CAAA,EAGJC,IAAc,QACbS,EAAAA,IAAC,OAAA,CAAK,cAAY,wBAAyB,SAAAT,EAAU,EAEtDG,IAAgB,QACfM,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,oBAAuB,SAAAN,CAAA,CAAY,CAAA,EAEvF,EACCD,IAAY,QACXO,MAAC,MAAA,CAAI,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,iBAAkB,WAAY,CAAA,EACrF,SAAAP,CAAA,CACH,CAAA,CAAA,CAAA,EAGHD,IAAY,QACXQ,EAAAA,IAAC,MAAA,CACC,cAAY,sBACZ,MAAO,CAAE,QAAS,OAAQ,WAAY,SAAU,IAAK,iBAAkB,SAAU,MAAA,EAEhF,SAAAR,CAAA,CAAA,CACH,CAAA,CAAA,CAIR,CAAC"}
@@ -1,4 +1,4 @@
1
- import{j as e,r as m}from"./cmdk-C3F6LD6N.js";import{d as N,b as B,g as j,u as L,a as O,S as y,B as p,I as g,h as P,i as x,F as b}from"./main-BURAlktW.js";import{V as A}from"./ViewHeader-C-t1U2cQ.js";import{F as I}from"./file-text-BOroDtZE.js";import{E as R}from"./EmptyState-DjKtY1Qi.js";import{C as S}from"./Chip-XPOk0d_E.js";import{S as D,a as T}from"./Sheet-B-CMP9-_.js";import{T as _}from"./Textarea-xnAybFGd.js";import{D as F}from"./download-BvJddD8D.js";import{P as w}from"./plus-Cm6-fo14.js";import{B as M}from"./brain-DhAzcHUk.js";/**
1
+ import{j as e,r as m}from"./cmdk-C3F6LD6N.js";import{d as N,b as B,g as j,u as L,a as O,S as y,B as p,I as g,h as P,i as x,F as b}from"./main-BRmJZcHt.js";import{V as A}from"./ViewHeader-BsnaspKw.js";import{F as I}from"./file-text-BsCrv5aP.js";import{E as R}from"./EmptyState-ccT__JZG.js";import{C as S}from"./Chip-B7ovcm01.js";import{S as D,a as T}from"./Sheet-BwMVGN-8.js";import{T as _}from"./Textarea-BfXGMXQ7.js";import{D as F}from"./download-B-mPX5P_.js";import{P as w}from"./plus-Cps-8lcG.js";import{B as M}from"./brain-D7k5s8vH.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":"MemoryView-DnL8E2vI.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/hash.js","../../src/web/v8/ui/memory/MemoryVault.tsx","../../src/web/v8/views/Memory/MemoryView.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 Hash = createLucideIcon(\"Hash\", [\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"9\", y2: \"9\", key: \"4lhtct\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"15\", y2: \"15\", key: \"vyu0kd\" }],\n [\"line\", { x1: \"10\", x2: \"8\", y1: \"3\", y2: \"21\", key: \"1ggp8o\" }],\n [\"line\", { x1: \"16\", x2: \"14\", y1: \"3\", y2: \"21\", key: \"weycgp\" }]\n]);\n\nexport { Hash as default };\n//# sourceMappingURL=hash.js.map\n","import { type ReactNode } from 'react';\nimport { FileText, Hash } from 'lucide-react';\nimport { cx } from '../utils/cx.js';\nimport { Badge } from '../data/Badge.js';\n\n/**\n * MemoryVault — list of memory entries (memos) grouped by scope.\n *\n * PLAN.md: memos are the durable cross-session notes the harness writes\n * down. Scopes: `project` (committed to repo) vs `global` (user-wide).\n * Each entry: content (truncated to 3 lines), tags, last-updated time,\n * scope badge.\n */\n\nexport type MemoryScope = 'project' | 'global';\n\nexport interface MemoryEntry {\n id: string;\n content: string;\n tags?: readonly string[];\n scope: MemoryScope;\n /** Relative time label (\"3 days ago\", \"Just now\"). */\n updatedAt: string;\n}\n\nexport interface MemoryVaultProps {\n entries: readonly MemoryEntry[];\n /** Optional click handler — opens memo detail. */\n onOpen?: (entry: MemoryEntry) => void;\n /** Optional empty state. */\n empty?: ReactNode;\n className?: string;\n}\n\nconst SCOPE_LABEL: Record<MemoryScope, string> = {\n project: 'Project',\n global: 'Global',\n};\n\nconst SCOPE_TONE: Record<MemoryScope, 'accent' | 'info'> = {\n project: 'accent',\n global: 'info',\n};\n\nexport function MemoryVault(props: MemoryVaultProps) {\n const { entries, onOpen, empty, className } = props;\n\n if (entries.length === 0 && empty !== undefined) {\n return <>{empty}</>;\n }\n\n return (\n <div className={cx('v8-memory-vault', className)}>\n {entries.map((entry) => (\n <button\n type=\"button\"\n key={entry.id}\n onClick={() => onOpen?.(entry)}\n className={cx('v8-memory-vault__item', `v8-memory-vault__item--${entry.scope}`)}\n style={{\n display: 'block',\n width: '100%',\n padding: 'var(--space-3) var(--space-4)',\n background: 'var(--surface-1)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius)',\n textAlign: 'left',\n cursor: onOpen !== undefined ? 'pointer' : 'default',\n font: 'inherit',\n color: 'inherit',\n marginBottom: 'var(--space-2)',\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 'var(--space-2)',\n marginBottom: 6,\n }}\n >\n <Badge tone={SCOPE_TONE[entry.scope]} size=\"sm\">\n {SCOPE_LABEL[entry.scope]}\n </Badge>\n <span\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-subtle)',\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n <FileText size={12} aria-hidden=\"true\" />\n {entry.updatedAt}\n </span>\n </div>\n <div\n style={{\n fontSize: 'var(--fs-13)',\n color: 'var(--fg)',\n lineHeight: 'var(--lh-snug)',\n display: '-webkit-box',\n WebkitLineClamp: 3,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {entry.content}\n </div>\n {entry.tags !== undefined && entry.tags.length > 0 && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n marginTop: 'var(--space-2)',\n flexWrap: 'wrap',\n }}\n >\n <Hash size={11} aria-hidden=\"true\" style={{ color: 'var(--fg-subtle)' }} />\n {entry.tags.map((tag) => (\n <span\n key={tag}\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-muted)',\n }}\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n </button>\n ))}\n <style>{`\n .v8-memory-vault__item:hover { border-color: var(--accent); }\n `}</style>\n </div>\n );\n}","import { useMemo, useState, useCallback } from 'react';\nimport { Plus, Download } 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 { MemoryVault, type MemoryEntry, type MemoryScope } from '../../ui/memory/MemoryVault.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { Brain } from 'lucide-react';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { Chip } from '../../ui/data/Chip.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Textarea } from '../../ui/controls/Textarea.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport type { WsMessage } from '../../data/types.js';\n\n/**\n * MemoryView — Sprint S10 + S15b. Pulls `/api/memory`, lets the user\n * create / edit / delete notes via the dashboard's control surface.\n *\n * Notes are stored via `/api/memory/notes` (POST create, PUT/DELETE\n * per-note). Scope is `project` (in the repo) vs `global` (user-wide).\n */\n\ninterface RawMemoryEntry {\n id?: string;\n content?: string;\n tags?: string[];\n scope?: 'project' | 'global';\n updatedAt?: string | number;\n}\n\ninterface MemoryResponse {\n notes?: RawMemoryEntry[];\n count?: number;\n}\n\nfunction toEntry(e: RawMemoryEntry): MemoryEntry {\n return {\n id: e.id || '',\n content: e.content || '',\n tags: e.tags || [],\n scope: (e.scope || 'project') as MemoryScope,\n updatedAt:\n typeof e.updatedAt === 'number'\n ? new Date(e.updatedAt).toLocaleString()\n : e.updatedAt || '',\n };\n}\n\ninterface NoteDraft {\n id?: string;\n content: string;\n scope: MemoryScope;\n}\n\nexport function MemoryView(): JSX.Element {\n const mem = useFetch<MemoryResponse>('/api/memory/notes');\n const [scope, setScope] = useState<MemoryScope | 'all'>('all');\n const [draft, setDraft] = useState<NoteDraft | null>(null);\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n const entries = useMemo<MemoryEntry[]>(() => {\n const list = (mem.data?.notes || []).map(toEntry);\n if (scope === 'all') return list;\n return list.filter((e) => e.scope === scope);\n }, [mem.data, scope]);\n\n const refresh = (): void => { void mem.refetch(); };\n\n const onMemoryChange = useCallback((msg: WsMessage) => {\n const m = msg as { type?: string };\n if (m.type === 'memory:change' || m.type === 'memory:new' || m.type === 'memory:removed') {\n refresh();\n }\n }, [mem]);\n useWsMessage(['memory:change', 'memory:new', 'memory:removed'], onMemoryChange);\n\n const exportNotes = (): void => {\n const blob = new Blob([JSON.stringify(entries, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `bizar-memory-${new Date().toISOString().slice(0, 10)}.json`;\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(url);\n };\n\n const saveDraft = async (): Promise<void> => {\n if (!draft || !draft.content.trim()) return;\n setBusy(true);\n setError(null);\n try {\n if (draft.id) {\n // Edit\n await fetchJson(`/api/memory/notes/${encodeURIComponent(draft.id)}`, {\n method: 'PUT',\n body: { content: draft.content, scope: draft.scope },\n });\n } else {\n await fetchJson('/api/memory/notes', {\n method: 'POST',\n body: { content: draft.content, scope: draft.scope },\n });\n }\n setDraft(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n const deleteEntry = async (id: string): Promise<void> => {\n setBusy(true);\n setError(null);\n try {\n await fetchJson(`/api/memory/notes/${encodeURIComponent(id)}`, { method: 'DELETE' });\n setDraft(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Stack gap={5} data-testid=\"memory-view\">\n <ViewHeader\n title=\"Memory\"\n description=\"Cross-session notes. Project memos live in the repo; global memos live on the user.\"\n actions={\n <Button variant=\"secondary\" onClick={exportNotes} disabled={entries.length === 0}>\n <Download size={12} aria-hidden /> Export JSON\n </Button>\n }\n />\n <Inline align=\"center\" justify=\"between\" gap={2} wrap>\n <Inline gap={2}>\n {(['all', 'project', 'global'] as const).map((s) => (\n <Chip key={s} selected={scope === s} onClick={() => setScope(s)}>\n {s === 'all' ? 'All' : s === 'project' ? 'Project' : 'Global'}\n </Chip>\n ))}\n </Inline>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => setDraft({ content: '', scope: 'project' })}\n data-testid=\"memory-new\"\n >\n <Plus size={14} aria-hidden /> New note\n </Button>\n </Inline>\n {error !== null && (\n <div\n role=\"alert\"\n style={{\n padding: 'var(--space-2) var(--space-3)',\n background: 'color-mix(in oklch, var(--danger) 12%, var(--surface-0))',\n border: '1px solid color-mix(in oklch, var(--danger) 40%, var(--border))',\n borderRadius: 'var(--radius-md)',\n fontSize: 'var(--fs-12)',\n color: 'var(--danger)',\n }}\n >\n {error}\n </div>\n )}\n {mem.loading ? (\n <Skeleton style={{ height: 240 }} />\n ) : entries.length === 0 ? (\n <EmptyState\n icon={<Brain size={32} aria-hidden />}\n title=\"No memory entries\"\n description=\"Memos land here once they are written via the memory tools. Add one with the button above.\"\n action={\n <Button variant=\"primary\" size=\"sm\" onClick={() => setDraft({ content: '', scope: 'project' })}>\n <Plus size={14} aria-hidden /> New note\n </Button>\n }\n />\n ) : (\n <MemoryVault\n entries={entries}\n onOpen={(e) => setDraft({ id: e.id, content: e.content, scope: e.scope })}\n />\n )}\n <Sheet open={draft !== null} onOpenChange={(o) => { if (!o) setDraft(null); }}>\n <SheetContent side=\"right\" title={draft?.id ? 'Edit note' : 'New note'}>\n {draft !== null && (\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label\n htmlFor=\"memory-content\"\n style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}\n >\n Content\n </label>\n <Textarea\n id=\"memory-content\"\n value={draft.content}\n onChange={(e) => setDraft({ ...draft, content: e.target.value })}\n rows={10}\n disabled={busy}\n data-testid=\"memory-content\"\n />\n </Stack>\n <Stack gap={2}>\n <label style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Scope</label>\n <Inline gap={2}>\n {(['project', 'global'] as const).map((s) => (\n <Chip\n key={s}\n selected={draft.scope === s}\n onClick={() => setDraft({ ...draft, scope: s })}\n >\n {s === 'project' ? 'Project (in-repo)' : 'Global (user-wide)'}\n </Chip>\n ))}\n </Inline>\n </Stack>\n <Inline gap={2}>\n <Button\n variant=\"primary\"\n onClick={() => { void saveDraft(); }}\n disabled={busy || !draft.content.trim()}\n >\n {draft.id ? 'Save' : 'Create'}\n </Button>\n <Button variant=\"ghost\" onClick={() => setDraft(null)} disabled={busy}>\n Cancel\n </Button>\n {draft.id !== undefined && (\n <Button\n variant=\"danger\"\n onClick={() => { void deleteEntry(draft.id!); }}\n disabled={busy}\n style={{ marginLeft: 'auto' }}\n >\n Delete\n </Button>\n )}\n </Inline>\n </Stack>\n )}\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}"],"names":["Hash","createLucideIcon","SCOPE_LABEL","SCOPE_TONE","MemoryVault","props","entries","onOpen","empty","className","cx","entry","jsxs","jsx","Badge","FileText","tag","toEntry","e","MemoryView","mem","useFetch","scope","setScope","useState","draft","setDraft","busy","setBusy","error","setError","useMemo","list","_a","refresh","onMemoryChange","useCallback","msg","m","useWsMessage","exportNotes","blob","url","a","saveDraft","fetchJson","err","FetchError","deleteEntry","id","Stack","ViewHeader","Button","Download","Inline","s","Chip","Plus","Skeleton","EmptyState","Brain","Sheet","o","SheetContent","Textarea"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"MemoryView-Cr-obIQY.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/hash.js","../../src/web/v8/ui/memory/MemoryVault.tsx","../../src/web/v8/views/Memory/MemoryView.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 Hash = createLucideIcon(\"Hash\", [\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"9\", y2: \"9\", key: \"4lhtct\" }],\n [\"line\", { x1: \"4\", x2: \"20\", y1: \"15\", y2: \"15\", key: \"vyu0kd\" }],\n [\"line\", { x1: \"10\", x2: \"8\", y1: \"3\", y2: \"21\", key: \"1ggp8o\" }],\n [\"line\", { x1: \"16\", x2: \"14\", y1: \"3\", y2: \"21\", key: \"weycgp\" }]\n]);\n\nexport { Hash as default };\n//# sourceMappingURL=hash.js.map\n","import { type ReactNode } from 'react';\nimport { FileText, Hash } from 'lucide-react';\nimport { cx } from '../utils/cx.js';\nimport { Badge } from '../data/Badge.js';\n\n/**\n * MemoryVault — list of memory entries (memos) grouped by scope.\n *\n * PLAN.md: memos are the durable cross-session notes the harness writes\n * down. Scopes: `project` (committed to repo) vs `global` (user-wide).\n * Each entry: content (truncated to 3 lines), tags, last-updated time,\n * scope badge.\n */\n\nexport type MemoryScope = 'project' | 'global';\n\nexport interface MemoryEntry {\n id: string;\n content: string;\n tags?: readonly string[];\n scope: MemoryScope;\n /** Relative time label (\"3 days ago\", \"Just now\"). */\n updatedAt: string;\n}\n\nexport interface MemoryVaultProps {\n entries: readonly MemoryEntry[];\n /** Optional click handler — opens memo detail. */\n onOpen?: (entry: MemoryEntry) => void;\n /** Optional empty state. */\n empty?: ReactNode;\n className?: string;\n}\n\nconst SCOPE_LABEL: Record<MemoryScope, string> = {\n project: 'Project',\n global: 'Global',\n};\n\nconst SCOPE_TONE: Record<MemoryScope, 'accent' | 'info'> = {\n project: 'accent',\n global: 'info',\n};\n\nexport function MemoryVault(props: MemoryVaultProps) {\n const { entries, onOpen, empty, className } = props;\n\n if (entries.length === 0 && empty !== undefined) {\n return <>{empty}</>;\n }\n\n return (\n <div className={cx('v8-memory-vault', className)}>\n {entries.map((entry) => (\n <button\n type=\"button\"\n key={entry.id}\n onClick={() => onOpen?.(entry)}\n className={cx('v8-memory-vault__item', `v8-memory-vault__item--${entry.scope}`)}\n style={{\n display: 'block',\n width: '100%',\n padding: 'var(--space-3) var(--space-4)',\n background: 'var(--surface-1)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius)',\n textAlign: 'left',\n cursor: onOpen !== undefined ? 'pointer' : 'default',\n font: 'inherit',\n color: 'inherit',\n marginBottom: 'var(--space-2)',\n }}\n >\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 'var(--space-2)',\n marginBottom: 6,\n }}\n >\n <Badge tone={SCOPE_TONE[entry.scope]} size=\"sm\">\n {SCOPE_LABEL[entry.scope]}\n </Badge>\n <span\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 4,\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-subtle)',\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n <FileText size={12} aria-hidden=\"true\" />\n {entry.updatedAt}\n </span>\n </div>\n <div\n style={{\n fontSize: 'var(--fs-13)',\n color: 'var(--fg)',\n lineHeight: 'var(--lh-snug)',\n display: '-webkit-box',\n WebkitLineClamp: 3,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {entry.content}\n </div>\n {entry.tags !== undefined && entry.tags.length > 0 && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n marginTop: 'var(--space-2)',\n flexWrap: 'wrap',\n }}\n >\n <Hash size={11} aria-hidden=\"true\" style={{ color: 'var(--fg-subtle)' }} />\n {entry.tags.map((tag) => (\n <span\n key={tag}\n style={{\n fontSize: 'var(--fs-12)',\n color: 'var(--fg-muted)',\n }}\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n </button>\n ))}\n <style>{`\n .v8-memory-vault__item:hover { border-color: var(--accent); }\n `}</style>\n </div>\n );\n}","import { useMemo, useState, useCallback } from 'react';\nimport { Plus, Download } 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 { MemoryVault, type MemoryEntry, type MemoryScope } from '../../ui/memory/MemoryVault.js';\nimport { EmptyState } from '../../ui/feedback/EmptyState.js';\nimport { Brain } from 'lucide-react';\nimport { Skeleton } from '../../ui/feedback/Skeleton.js';\nimport { Chip } from '../../ui/data/Chip.js';\nimport { Button } from '../../ui/controls/Button.js';\nimport { Sheet, SheetContent } from '../../ui/feedback/Sheet.js';\nimport { Textarea } from '../../ui/controls/Textarea.js';\nimport { useFetch } from '../../data/useFetch.js';\nimport { useWsMessage } from '../../data/useWebSocket.js';\nimport { fetchJson, FetchError } from '../../data/fetcher.js';\nimport type { WsMessage } from '../../data/types.js';\n\n/**\n * MemoryView — Sprint S10 + S15b. Pulls `/api/memory`, lets the user\n * create / edit / delete notes via the dashboard's control surface.\n *\n * Notes are stored via `/api/memory/notes` (POST create, PUT/DELETE\n * per-note). Scope is `project` (in the repo) vs `global` (user-wide).\n */\n\ninterface RawMemoryEntry {\n id?: string;\n content?: string;\n tags?: string[];\n scope?: 'project' | 'global';\n updatedAt?: string | number;\n}\n\ninterface MemoryResponse {\n notes?: RawMemoryEntry[];\n count?: number;\n}\n\nfunction toEntry(e: RawMemoryEntry): MemoryEntry {\n return {\n id: e.id || '',\n content: e.content || '',\n tags: e.tags || [],\n scope: (e.scope || 'project') as MemoryScope,\n updatedAt:\n typeof e.updatedAt === 'number'\n ? new Date(e.updatedAt).toLocaleString()\n : e.updatedAt || '',\n };\n}\n\ninterface NoteDraft {\n id?: string;\n content: string;\n scope: MemoryScope;\n}\n\nexport function MemoryView(): JSX.Element {\n const mem = useFetch<MemoryResponse>('/api/memory/notes');\n const [scope, setScope] = useState<MemoryScope | 'all'>('all');\n const [draft, setDraft] = useState<NoteDraft | null>(null);\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n const entries = useMemo<MemoryEntry[]>(() => {\n const list = (mem.data?.notes || []).map(toEntry);\n if (scope === 'all') return list;\n return list.filter((e) => e.scope === scope);\n }, [mem.data, scope]);\n\n const refresh = (): void => { void mem.refetch(); };\n\n const onMemoryChange = useCallback((msg: WsMessage) => {\n const m = msg as { type?: string };\n if (m.type === 'memory:change' || m.type === 'memory:new' || m.type === 'memory:removed') {\n refresh();\n }\n }, [mem]);\n useWsMessage(['memory:change', 'memory:new', 'memory:removed'], onMemoryChange);\n\n const exportNotes = (): void => {\n const blob = new Blob([JSON.stringify(entries, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = `bizar-memory-${new Date().toISOString().slice(0, 10)}.json`;\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(url);\n };\n\n const saveDraft = async (): Promise<void> => {\n if (!draft || !draft.content.trim()) return;\n setBusy(true);\n setError(null);\n try {\n if (draft.id) {\n // Edit\n await fetchJson(`/api/memory/notes/${encodeURIComponent(draft.id)}`, {\n method: 'PUT',\n body: { content: draft.content, scope: draft.scope },\n });\n } else {\n await fetchJson('/api/memory/notes', {\n method: 'POST',\n body: { content: draft.content, scope: draft.scope },\n });\n }\n setDraft(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n const deleteEntry = async (id: string): Promise<void> => {\n setBusy(true);\n setError(null);\n try {\n await fetchJson(`/api/memory/notes/${encodeURIComponent(id)}`, { method: 'DELETE' });\n setDraft(null);\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Stack gap={5} data-testid=\"memory-view\">\n <ViewHeader\n title=\"Memory\"\n description=\"Cross-session notes. Project memos live in the repo; global memos live on the user.\"\n actions={\n <Button variant=\"secondary\" onClick={exportNotes} disabled={entries.length === 0}>\n <Download size={12} aria-hidden /> Export JSON\n </Button>\n }\n />\n <Inline align=\"center\" justify=\"between\" gap={2} wrap>\n <Inline gap={2}>\n {(['all', 'project', 'global'] as const).map((s) => (\n <Chip key={s} selected={scope === s} onClick={() => setScope(s)}>\n {s === 'all' ? 'All' : s === 'project' ? 'Project' : 'Global'}\n </Chip>\n ))}\n </Inline>\n <Button\n variant=\"primary\"\n size=\"sm\"\n onClick={() => setDraft({ content: '', scope: 'project' })}\n data-testid=\"memory-new\"\n >\n <Plus size={14} aria-hidden /> New note\n </Button>\n </Inline>\n {error !== null && (\n <div\n role=\"alert\"\n style={{\n padding: 'var(--space-2) var(--space-3)',\n background: 'color-mix(in oklch, var(--danger) 12%, var(--surface-0))',\n border: '1px solid color-mix(in oklch, var(--danger) 40%, var(--border))',\n borderRadius: 'var(--radius-md)',\n fontSize: 'var(--fs-12)',\n color: 'var(--danger)',\n }}\n >\n {error}\n </div>\n )}\n {mem.loading ? (\n <Skeleton style={{ height: 240 }} />\n ) : entries.length === 0 ? (\n <EmptyState\n icon={<Brain size={32} aria-hidden />}\n title=\"No memory entries\"\n description=\"Memos land here once they are written via the memory tools. Add one with the button above.\"\n action={\n <Button variant=\"primary\" size=\"sm\" onClick={() => setDraft({ content: '', scope: 'project' })}>\n <Plus size={14} aria-hidden /> New note\n </Button>\n }\n />\n ) : (\n <MemoryVault\n entries={entries}\n onOpen={(e) => setDraft({ id: e.id, content: e.content, scope: e.scope })}\n />\n )}\n <Sheet open={draft !== null} onOpenChange={(o) => { if (!o) setDraft(null); }}>\n <SheetContent side=\"right\" title={draft?.id ? 'Edit note' : 'New note'}>\n {draft !== null && (\n <Stack gap={4} style={{ padding: 'var(--space-4)' }}>\n <Stack gap={2}>\n <label\n htmlFor=\"memory-content\"\n style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}\n >\n Content\n </label>\n <Textarea\n id=\"memory-content\"\n value={draft.content}\n onChange={(e) => setDraft({ ...draft, content: e.target.value })}\n rows={10}\n disabled={busy}\n data-testid=\"memory-content\"\n />\n </Stack>\n <Stack gap={2}>\n <label style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Scope</label>\n <Inline gap={2}>\n {(['project', 'global'] as const).map((s) => (\n <Chip\n key={s}\n selected={draft.scope === s}\n onClick={() => setDraft({ ...draft, scope: s })}\n >\n {s === 'project' ? 'Project (in-repo)' : 'Global (user-wide)'}\n </Chip>\n ))}\n </Inline>\n </Stack>\n <Inline gap={2}>\n <Button\n variant=\"primary\"\n onClick={() => { void saveDraft(); }}\n disabled={busy || !draft.content.trim()}\n >\n {draft.id ? 'Save' : 'Create'}\n </Button>\n <Button variant=\"ghost\" onClick={() => setDraft(null)} disabled={busy}>\n Cancel\n </Button>\n {draft.id !== undefined && (\n <Button\n variant=\"danger\"\n onClick={() => { void deleteEntry(draft.id!); }}\n disabled={busy}\n style={{ marginLeft: 'auto' }}\n >\n Delete\n </Button>\n )}\n </Inline>\n </Stack>\n )}\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}"],"names":["Hash","createLucideIcon","SCOPE_LABEL","SCOPE_TONE","MemoryVault","props","entries","onOpen","empty","className","cx","entry","jsxs","jsx","Badge","FileText","tag","toEntry","e","MemoryView","mem","useFetch","scope","setScope","useState","draft","setDraft","busy","setBusy","error","setError","useMemo","list","_a","refresh","onMemoryChange","useCallback","msg","m","useWsMessage","exportNotes","blob","url","a","saveDraft","fetchJson","err","FetchError","deleteEntry","id","Stack","ViewHeader","Button","Download","Inline","s","Chip","Plus","Skeleton","EmptyState","Brain","Sheet","o","SheetContent","Textarea"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1 +1 @@
1
- import{j as e,r as d}from"./cmdk-C3F6LD6N.js";import{S as p,u as j,I as c,f as y,h as g,B as f,E as S,c as b,a1 as z,i as k,F as C}from"./main-BURAlktW.js";import{V as T}from"./ViewHeader-C-t1U2cQ.js";import{C as x,b as m}from"./Card-BtsmkhJa.js";import{I as w}from"./Input-h_nSOtwm.js";import{N as I}from"./network-BcCoCzIY.js";import{R as P}from"./refresh-ccw-DA8_IB9l.js";import{P as B}from"./power-CXN9y2KV.js";import{P as E}from"./power-off-DUZqwMf9.js";import{F}from"./file-text-BOroDtZE.js";function U(){return e.jsxs(p,{gap:4,"data-testid":"misc-view",children:[e.jsx(T,{title:"Misc",description:"Global fuzzy search across projects, tasks, and agents — plus Tailscale VPN control."}),e.jsx(R,{}),e.jsx(N,{})]})}function R(){var i,l,n;const[a,t]=d.useState(""),r=j(`/api/search?q=${encodeURIComponent(a)}`);return e.jsx(x,{variant:"default",children:e.jsxs(m,{children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Search"}),e.jsxs(c,{gap:2,align:"center",style:{marginTop:"var(--space-2)"},children:[e.jsx(y,{size:14,"aria-hidden":!0,style:{color:"var(--fg-muted)"}}),e.jsx(w,{value:a,onChange:s=>t(s.target.value),placeholder:"Search projects / tasks / artifacts / agents…","data-testid":"misc-search-input"})]}),a.trim()===""?e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-subtle)"},children:"Type a query to search."}):r.loading&&!r.data?e.jsxs(p,{gap:1,style:{marginTop:"var(--space-2)"},children:[e.jsx(g,{style:{height:24}}),e.jsx(g,{style:{height:24}})]}):(((l=(i=r.data)==null?void 0:i.results)==null?void 0:l.length)??0)===0?e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-subtle)"},children:"No results."}):e.jsx(p,{gap:1,style:{marginTop:"var(--space-2)"},children:(((n=r.data)==null?void 0:n.results)??[]).slice(0,30).map((s,o)=>e.jsxs("div",{"data-testid":`misc-search-result-${o}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)"},children:[e.jsxs(c,{align:"center",gap:2,children:[e.jsx(q,{kind:s.kind}),e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:s.title||s.id}),e.jsx("code",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:s.kind}),s.projectId&&e.jsxs("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-muted)"},children:["· ",s.projectId]})]}),s.snippet&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:s.snippet})]},o))})]})})}function q({kind:a}){const t=a==="task"?S:a==="agent"?b:a==="project"?z:F;return e.jsx(t,{size:12,"aria-hidden":!0,style:{color:"var(--fg-muted)"}})}function N(){var o,u;const a=j("/api/tailscale/status"),[t,r]=d.useState(!1),[i,l]=d.useState(null),n=d.useCallback(()=>{a.refetch()},[a]),s=async v=>{r(!0),l(null);try{await k(v?"/api/tailscale/enable":"/api/tailscale/disable",{method:"POST"}),n()}catch(h){l((h instanceof C,h.message))}finally{r(!1)}};return e.jsx(x,{variant:"default",children:e.jsxs(m,{children:[e.jsxs(c,{align:"center",justify:"between",gap:2,children:[e.jsxs(c,{align:"center",gap:2,children:[e.jsx(I,{size:16,"aria-hidden":!0,style:{color:"var(--accent)"}}),e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Tailscale"}),a.data&&e.jsx("span",{"data-testid":"misc-tailscale-state",style:{fontSize:"var(--fs-12)",color:a.data.running?"var(--success)":"var(--fg-muted)"},children:a.data.running?`running · ${a.data.hostname??"?"}`:"stopped"})]}),e.jsxs(c,{gap:1,children:[i!==null&&e.jsx("span",{role:"alert","data-testid":"misc-tailscale-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:i}),e.jsxs(f,{variant:"ghost",onClick:()=>void n(),"data-testid":"misc-tailscale-refresh",children:[e.jsx(P,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(f,{variant:"ghost",onClick:()=>void s(!0),disabled:t,"data-testid":"misc-tailscale-enable",children:[e.jsx(B,{size:14,"aria-hidden":!0})," Enable"]}),e.jsxs(f,{variant:"ghost",onClick:()=>void s(!1),disabled:t,"data-testid":"misc-tailscale-disable",children:[e.jsx(E,{size:14,"aria-hidden":!0})," Disable"]})]})]}),((o=a.data)==null?void 0:o.url)&&e.jsx("div",{style:{marginTop:"var(--space-2)"},children:e.jsx("a",{href:a.data.url,target:"_blank",rel:"noreferrer",style:{fontSize:"var(--fs-12)",color:"var(--accent)"},children:a.data.url})}),((u=a.data)==null?void 0:u.error)&&e.jsx("span",{role:"alert",style:{fontSize:"var(--fs-12)",color:"var(--danger)"},children:a.data.error})]})})}export{U as MiscView};
1
+ import{j as e,r as d}from"./cmdk-C3F6LD6N.js";import{S as p,u as j,I as c,f as y,h as g,B as f,E as S,c as b,a3 as z,i as k,F as C}from"./main-BRmJZcHt.js";import{V as T}from"./ViewHeader-BsnaspKw.js";import{C as x,b as m}from"./Card-Clkvh43Q.js";import{I as w}from"./Input-DV-vdaV8.js";import{N as I}from"./network-DJnHwHX3.js";import{R as P}from"./refresh-ccw-DN_zCB1h.js";import{P as B}from"./power-DEX4_Xoa.js";import{P as E}from"./power-off-upZ4xjaG.js";import{F}from"./file-text-BsCrv5aP.js";function U(){return e.jsxs(p,{gap:4,"data-testid":"misc-view",children:[e.jsx(T,{title:"Misc",description:"Global fuzzy search across projects, tasks, and agents — plus Tailscale VPN control."}),e.jsx(R,{}),e.jsx(N,{})]})}function R(){var i,l,n;const[a,t]=d.useState(""),r=j(`/api/search?q=${encodeURIComponent(a)}`);return e.jsx(x,{variant:"default",children:e.jsxs(m,{children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Search"}),e.jsxs(c,{gap:2,align:"center",style:{marginTop:"var(--space-2)"},children:[e.jsx(y,{size:14,"aria-hidden":!0,style:{color:"var(--fg-muted)"}}),e.jsx(w,{value:a,onChange:s=>t(s.target.value),placeholder:"Search projects / tasks / artifacts / agents…","data-testid":"misc-search-input"})]}),a.trim()===""?e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-subtle)"},children:"Type a query to search."}):r.loading&&!r.data?e.jsxs(p,{gap:1,style:{marginTop:"var(--space-2)"},children:[e.jsx(g,{style:{height:24}}),e.jsx(g,{style:{height:24}})]}):(((l=(i=r.data)==null?void 0:i.results)==null?void 0:l.length)??0)===0?e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-subtle)"},children:"No results."}):e.jsx(p,{gap:1,style:{marginTop:"var(--space-2)"},children:(((n=r.data)==null?void 0:n.results)??[]).slice(0,30).map((s,o)=>e.jsxs("div",{"data-testid":`misc-search-result-${o}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)"},children:[e.jsxs(c,{align:"center",gap:2,children:[e.jsx(q,{kind:s.kind}),e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:s.title||s.id}),e.jsx("code",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:s.kind}),s.projectId&&e.jsxs("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-muted)"},children:["· ",s.projectId]})]}),s.snippet&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:s.snippet})]},o))})]})})}function q({kind:a}){const t=a==="task"?S:a==="agent"?b:a==="project"?z:F;return e.jsx(t,{size:12,"aria-hidden":!0,style:{color:"var(--fg-muted)"}})}function N(){var o,u;const a=j("/api/tailscale/status"),[t,r]=d.useState(!1),[i,l]=d.useState(null),n=d.useCallback(()=>{a.refetch()},[a]),s=async v=>{r(!0),l(null);try{await k(v?"/api/tailscale/enable":"/api/tailscale/disable",{method:"POST"}),n()}catch(h){l((h instanceof C,h.message))}finally{r(!1)}};return e.jsx(x,{variant:"default",children:e.jsxs(m,{children:[e.jsxs(c,{align:"center",justify:"between",gap:2,children:[e.jsxs(c,{align:"center",gap:2,children:[e.jsx(I,{size:16,"aria-hidden":!0,style:{color:"var(--accent)"}}),e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Tailscale"}),a.data&&e.jsx("span",{"data-testid":"misc-tailscale-state",style:{fontSize:"var(--fs-12)",color:a.data.running?"var(--success)":"var(--fg-muted)"},children:a.data.running?`running · ${a.data.hostname??"?"}`:"stopped"})]}),e.jsxs(c,{gap:1,children:[i!==null&&e.jsx("span",{role:"alert","data-testid":"misc-tailscale-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:i}),e.jsxs(f,{variant:"ghost",onClick:()=>void n(),"data-testid":"misc-tailscale-refresh",children:[e.jsx(P,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(f,{variant:"ghost",onClick:()=>void s(!0),disabled:t,"data-testid":"misc-tailscale-enable",children:[e.jsx(B,{size:14,"aria-hidden":!0})," Enable"]}),e.jsxs(f,{variant:"ghost",onClick:()=>void s(!1),disabled:t,"data-testid":"misc-tailscale-disable",children:[e.jsx(E,{size:14,"aria-hidden":!0})," Disable"]})]})]}),((o=a.data)==null?void 0:o.url)&&e.jsx("div",{style:{marginTop:"var(--space-2)"},children:e.jsx("a",{href:a.data.url,target:"_blank",rel:"noreferrer",style:{fontSize:"var(--fs-12)",color:"var(--accent)"},children:a.data.url})}),((u=a.data)==null?void 0:u.error)&&e.jsx("span",{role:"alert",style:{fontSize:"var(--fs-12)",color:"var(--danger)"},children:a.data.error})]})})}export{U as MiscView};
@@ -1 +1 @@
1
- {"version":3,"file":"MiscView-B2YQXhZ_.js","sources":["../../src/web/v8/views/Misc/MiscView.tsx"],"sourcesContent":["/**\n * v8/views/Misc/MiscView.tsx — Sprint S43, v9.3.0.\n *\n * The \"doesn't fit anywhere else\" surface: global fuzzy search\n * (GET /api/search) + Tailscale card (GET /api/tailscale/status,\n * POST /api/tailscale/{enable,disable}).\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { Search, Network, Power, PowerOff, RefreshCcw, FileText, CheckSquare, Bot, Folder } 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 { 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 SearchResult {\n kind?: string;\n id?: string;\n title?: string;\n projectId?: string;\n score?: number;\n snippet?: string;\n}\n\ninterface SearchResponse {\n query?: string;\n results?: SearchResult[];\n total?: number;\n}\n\ninterface TailscaleStatus {\n enabled?: boolean;\n running?: boolean;\n hostname?: string;\n url?: string;\n error?: string;\n}\n\nexport function MiscView(): JSX.Element {\n return (\n <Stack gap={4} data-testid=\"misc-view\">\n <ViewHeader title=\"Misc\" description=\"Global fuzzy search across projects, tasks, and agents — plus Tailscale VPN control.\" />\n <SearchPanel />\n <TailscalePanel />\n </Stack>\n );\n}\n\nfunction SearchPanel(): JSX.Element {\n const [q, setQ] = useState<string>('');\n const payload = useFetch<SearchResponse>(`/api/search?q=${encodeURIComponent(q)}`);\n\n return (\n <Card variant=\"default\">\n <CardBody>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Search</strong>\n <Inline gap={2} align=\"center\" style={{ marginTop: 'var(--space-2)' }}>\n <Search size={14} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n <Input value={q} onChange={(e) => setQ((e.target as HTMLInputElement).value)} placeholder=\"Search projects / tasks / artifacts / agents…\" data-testid=\"misc-search-input\" />\n </Inline>\n {q.trim() === '' ? (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>Type a query to search.</span>\n ) : payload.loading && !payload.data ? (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n <Skeleton style={{ height: 24 }} />\n <Skeleton style={{ height: 24 }} />\n </Stack>\n ) : (payload.data?.results?.length ?? 0) === 0 ? (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>No results.</span>\n ) : (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n {(payload.data?.results ?? []).slice(0, 30).map((r, i) => (\n <div key={i} data-testid={`misc-search-result-${i}`} style={{ padding: 'var(--space-2)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)' }}>\n <Inline align=\"center\" gap={2}>\n <KindIcon kind={r.kind} />\n <strong style={{ fontSize: 'var(--fs-13)' }}>{r.title || r.id}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{r.kind}</code>\n {r.projectId && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>· {r.projectId}</span>}\n </Inline>\n {r.snippet && <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{r.snippet}</span>}\n </div>\n ))}\n </Stack>\n )}\n </CardBody>\n </Card>\n );\n}\n\nfunction KindIcon({ kind }: { kind?: string }): JSX.Element {\n const Icon = (kind === 'task' ? CheckSquare : kind === 'agent' ? Bot : kind === 'project' ? Folder : FileText) as typeof Folder;\n return <Icon size={12} aria-hidden style={{ color: 'var(--fg-muted)' }} />;\n}\n\nfunction TailscalePanel(): JSX.Element {\n const payload = useFetch<TailscaleStatus>('/api/tailscale/status');\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n\n const toggle = async (enable: boolean): Promise<void> => {\n setBusy(true);\n setError(null);\n try {\n await fetchJson(enable ? '/api/tailscale/enable' : '/api/tailscale/disable', { method: 'POST' });\n refresh();\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 <Inline align=\"center\" justify=\"between\" gap={2}>\n <Inline align=\"center\" gap={2}>\n <Network size={16} aria-hidden style={{ color: 'var(--accent)' }} />\n <strong style={{ fontSize: 'var(--fs-13)' }}>Tailscale</strong>\n {payload.data && (\n <span data-testid=\"misc-tailscale-state\" style={{ fontSize: 'var(--fs-12)', color: payload.data.running ? 'var(--success)' : 'var(--fg-muted)' }}>\n {payload.data.running ? `running · ${payload.data.hostname ?? '?'}` : 'stopped'}\n </span>\n )}\n </Inline>\n <Inline gap={1}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"misc-tailscale-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"misc-tailscale-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"ghost\" onClick={() => void toggle(true)} disabled={busy} data-testid=\"misc-tailscale-enable\">\n <Power size={14} aria-hidden /> Enable\n </Button>\n <Button variant=\"ghost\" onClick={() => void toggle(false)} disabled={busy} data-testid=\"misc-tailscale-disable\">\n <PowerOff size={14} aria-hidden /> Disable\n </Button>\n </Inline>\n </Inline>\n {payload.data?.url && (\n <div style={{ marginTop: 'var(--space-2)' }}>\n <a href={payload.data.url} target=\"_blank\" rel=\"noreferrer\" style={{ fontSize: 'var(--fs-12)', color: 'var(--accent)' }}>{payload.data.url}</a>\n </div>\n )}\n {payload.data?.error && (\n <span role=\"alert\" style={{ fontSize: 'var(--fs-12)', color: 'var(--danger)' }}>{payload.data.error}</span>\n )}\n </CardBody>\n </Card>\n );\n}"],"names":["MiscView","jsxs","Stack","jsx","ViewHeader","SearchPanel","TailscalePanel","q","setQ","useState","payload","useFetch","Card","CardBody","Inline","Search","Input","e","Skeleton","_b","_a","r","i","KindIcon","kind","Icon","CheckSquare","Bot","Folder","FileText","busy","setBusy","error","setError","refresh","useCallback","toggle","enable","fetchJson","err","FetchError","Network","Button","RefreshCcw","Power","PowerOff"],"mappings":"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"}
1
+ {"version":3,"file":"MiscView-CDUQpYuV.js","sources":["../../src/web/v8/views/Misc/MiscView.tsx"],"sourcesContent":["/**\n * v8/views/Misc/MiscView.tsx — Sprint S43, v9.3.0.\n *\n * The \"doesn't fit anywhere else\" surface: global fuzzy search\n * (GET /api/search) + Tailscale card (GET /api/tailscale/status,\n * POST /api/tailscale/{enable,disable}).\n */\n\nimport { useCallback, useMemo, useState } from 'react';\nimport { Search, Network, Power, PowerOff, RefreshCcw, FileText, CheckSquare, Bot, Folder } 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 { 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 SearchResult {\n kind?: string;\n id?: string;\n title?: string;\n projectId?: string;\n score?: number;\n snippet?: string;\n}\n\ninterface SearchResponse {\n query?: string;\n results?: SearchResult[];\n total?: number;\n}\n\ninterface TailscaleStatus {\n enabled?: boolean;\n running?: boolean;\n hostname?: string;\n url?: string;\n error?: string;\n}\n\nexport function MiscView(): JSX.Element {\n return (\n <Stack gap={4} data-testid=\"misc-view\">\n <ViewHeader title=\"Misc\" description=\"Global fuzzy search across projects, tasks, and agents — plus Tailscale VPN control.\" />\n <SearchPanel />\n <TailscalePanel />\n </Stack>\n );\n}\n\nfunction SearchPanel(): JSX.Element {\n const [q, setQ] = useState<string>('');\n const payload = useFetch<SearchResponse>(`/api/search?q=${encodeURIComponent(q)}`);\n\n return (\n <Card variant=\"default\">\n <CardBody>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Search</strong>\n <Inline gap={2} align=\"center\" style={{ marginTop: 'var(--space-2)' }}>\n <Search size={14} aria-hidden style={{ color: 'var(--fg-muted)' }} />\n <Input value={q} onChange={(e) => setQ((e.target as HTMLInputElement).value)} placeholder=\"Search projects / tasks / artifacts / agents…\" data-testid=\"misc-search-input\" />\n </Inline>\n {q.trim() === '' ? (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>Type a query to search.</span>\n ) : payload.loading && !payload.data ? (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n <Skeleton style={{ height: 24 }} />\n <Skeleton style={{ height: 24 }} />\n </Stack>\n ) : (payload.data?.results?.length ?? 0) === 0 ? (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-subtle)' }}>No results.</span>\n ) : (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n {(payload.data?.results ?? []).slice(0, 30).map((r, i) => (\n <div key={i} data-testid={`misc-search-result-${i}`} style={{ padding: 'var(--space-2)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)' }}>\n <Inline align=\"center\" gap={2}>\n <KindIcon kind={r.kind} />\n <strong style={{ fontSize: 'var(--fs-13)' }}>{r.title || r.id}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{r.kind}</code>\n {r.projectId && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>· {r.projectId}</span>}\n </Inline>\n {r.snippet && <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{r.snippet}</span>}\n </div>\n ))}\n </Stack>\n )}\n </CardBody>\n </Card>\n );\n}\n\nfunction KindIcon({ kind }: { kind?: string }): JSX.Element {\n const Icon = (kind === 'task' ? CheckSquare : kind === 'agent' ? Bot : kind === 'project' ? Folder : FileText) as typeof Folder;\n return <Icon size={12} aria-hidden style={{ color: 'var(--fg-muted)' }} />;\n}\n\nfunction TailscalePanel(): JSX.Element {\n const payload = useFetch<TailscaleStatus>('/api/tailscale/status');\n const [busy, setBusy] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const refresh = useCallback(() => { void payload.refetch(); }, [payload]);\n\n const toggle = async (enable: boolean): Promise<void> => {\n setBusy(true);\n setError(null);\n try {\n await fetchJson(enable ? '/api/tailscale/enable' : '/api/tailscale/disable', { method: 'POST' });\n refresh();\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 <Inline align=\"center\" justify=\"between\" gap={2}>\n <Inline align=\"center\" gap={2}>\n <Network size={16} aria-hidden style={{ color: 'var(--accent)' }} />\n <strong style={{ fontSize: 'var(--fs-13)' }}>Tailscale</strong>\n {payload.data && (\n <span data-testid=\"misc-tailscale-state\" style={{ fontSize: 'var(--fs-12)', color: payload.data.running ? 'var(--success)' : 'var(--fg-muted)' }}>\n {payload.data.running ? `running · ${payload.data.hostname ?? '?'}` : 'stopped'}\n </span>\n )}\n </Inline>\n <Inline gap={1}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"misc-tailscale-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"misc-tailscale-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"ghost\" onClick={() => void toggle(true)} disabled={busy} data-testid=\"misc-tailscale-enable\">\n <Power size={14} aria-hidden /> Enable\n </Button>\n <Button variant=\"ghost\" onClick={() => void toggle(false)} disabled={busy} data-testid=\"misc-tailscale-disable\">\n <PowerOff size={14} aria-hidden /> Disable\n </Button>\n </Inline>\n </Inline>\n {payload.data?.url && (\n <div style={{ marginTop: 'var(--space-2)' }}>\n <a href={payload.data.url} target=\"_blank\" rel=\"noreferrer\" style={{ fontSize: 'var(--fs-12)', color: 'var(--accent)' }}>{payload.data.url}</a>\n </div>\n )}\n {payload.data?.error && (\n <span role=\"alert\" style={{ fontSize: 'var(--fs-12)', color: 'var(--danger)' }}>{payload.data.error}</span>\n )}\n </CardBody>\n </Card>\n );\n}"],"names":["MiscView","jsxs","Stack","jsx","ViewHeader","SearchPanel","TailscalePanel","q","setQ","useState","payload","useFetch","Card","CardBody","Inline","Search","Input","e","Skeleton","_b","_a","r","i","KindIcon","kind","Icon","CheckSquare","Bot","Folder","FileText","busy","setBusy","error","setError","refresh","useCallback","toggle","enable","fetchJson","err","FetchError","Network","Button","RefreshCcw","Power","PowerOff"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import{r as o,j as e}from"./cmdk-C3F6LD6N.js";import{d as U,u as C,S as c,I as h,B as i,h as z,U as D,Y as F,i as f,F as m}from"./main-BURAlktW.js";import{V as L}from"./ViewHeader-C-t1U2cQ.js";import{L as O}from"./ListHeader-CM8QoIWG.js";import{C as w,b as k}from"./Card-BtsmkhJa.js";import{I as B}from"./Input-h_nSOtwm.js";import{S as V,a as A}from"./Sheet-B-CMP9-_.js";import{E as $}from"./EmptyState-DjKtY1Qi.js";import{R as H}from"./refresh-ccw-DA8_IB9l.js";import{P as W}from"./plus-Cm6-fo14.js";import{P as q}from"./power-CXN9y2KV.js";import{P as J}from"./power-off-DUZqwMf9.js";import{R as N}from"./rotate-ccw-DMTASfAn.js";import{T as Y}from"./trash-2-D6qePV_q.js";import{D as I}from"./download-BvJddD8D.js";import{U as G}from"./upload-Dy59aZn6.js";/**
1
+ import{r as o,j as e}from"./cmdk-C3F6LD6N.js";import{d as D,u as C,S as c,I as h,B as i,h as z,Y as U,Z as F,i as f,F as m}from"./main-BRmJZcHt.js";import{V as L}from"./ViewHeader-BsnaspKw.js";import{L as O}from"./ListHeader-CCD_nIHb.js";import{C as w,b as k}from"./Card-Clkvh43Q.js";import{I as B}from"./Input-DV-vdaV8.js";import{S as V,a as A}from"./Sheet-BwMVGN-8.js";import{E as $}from"./EmptyState-ccT__JZG.js";import{R as H}from"./refresh-ccw-DN_zCB1h.js";import{P as W}from"./plus-Cps-8lcG.js";import{P as q}from"./power-DEX4_Xoa.js";import{P as J}from"./power-off-upZ4xjaG.js";import{R as N}from"./rotate-ccw-D5fkDRgk.js";import{T as Y}from"./trash-2-B_Y6HrfN.js";import{D as I}from"./download-B-mPX5P_.js";import{U as Z}from"./upload-BZCtmqIh.js";/**
2
2
  * @license lucide-react v0.460.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
- */const K=U("FilePen",[["path",{d:"M12.5 22H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v9.5",key:"1couwa"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M13.378 15.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z",key:"1y4qbx"}]]);function ge(){const p=C("/api/mods"),g=C("/api/mods/registry"),[n,v]=o.useState(null),[y,x]=o.useState(!1),[j,r]=o.useState(null),l=o.useMemo(()=>{var a;return((a=p.data)==null?void 0:a.mods)??[]},[p.data]),u=o.useMemo(()=>{var a;return((a=g.data)==null?void 0:a.mods)??[]},[g.data]),t=o.useCallback(()=>{p.refetch(),g.refetch()},[p,g]),E=async a=>{r(null);try{await f(`/api/mods/${a}`,{method:"DELETE"}),v(null),t()}catch(s){r((s instanceof m,s.message))}},P=async(a,s)=>{r(null);try{await f(`/api/mods/${a}`,{method:"PUT",body:{enabled:s}}),t()}catch(d){r((d instanceof m,d.message))}},R=async a=>{r(null);try{await f(`/api/mods/${a}/upgrade`,{method:"POST"}),t()}catch(s){r((s instanceof m,s.message))}},T=async a=>{r(null);try{await f(`/api/mods/${a}/instructions/reinstall`,{method:"POST"}),t()}catch(s){r((s instanceof m,s.message))}},M=async a=>{const s=window.prompt(`Edit mod file content for ${a} (JSON or YAML)`);if(s!==null){r(null);try{await f(`/api/mods/${a}/mod-file/content`,{method:"PUT",body:{content:s}}),t()}catch(d){r((d instanceof m,d.message))}}};return e.jsxs(c,{gap:4,"data-testid":"mods-view",children:[e.jsx(L,{title:"Mods",description:"Installed + registry-installed mods. Each mod ships its own UI view(s).",actions:e.jsxs(h,{align:"center",gap:2,children:[j!==null&&e.jsx("span",{role:"alert","data-testid":"mods-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:j}),e.jsxs(i,{variant:"ghost",onClick:()=>void t(),"data-testid":"mods-refresh",children:[e.jsx(H,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(i,{variant:"primary",onClick:()=>x(!0),"data-testid":"mods-install",children:[e.jsx(W,{size:14,"aria-hidden":!0})," Install"]})]})}),e.jsx(O,{title:"Installed",count:l.length,testid:"mods-list-header"}),e.jsx(w,{variant:"default",children:e.jsxs(k,{children:[e.jsxs("strong",{style:{fontSize:"var(--fs-13)"},children:["Installed (",l.length,")"]}),p.loading&&l.length===0?e.jsx(c,{gap:1,style:{marginTop:"var(--space-2)"},children:e.jsx(z,{style:{height:40}})}):l.length===0?e.jsx($,{icon:e.jsx(D,{size:28,"aria-hidden":!0}),title:"No mods installed",description:"Install one from the registry or a local path."}):e.jsx(c,{gap:1,style:{marginTop:"var(--space-2)"},children:l.map(a=>{const s=n===a.id,d=u.find(S=>S.id===a.id),b=(d==null?void 0:d.upgradeAvailable)??null;return e.jsxs("div",{"data-testid":`mod-row-${a.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",background:"var(--surface-0)"},children:[e.jsxs(h,{align:"center",justify:"between",gap:2,children:[e.jsxs(c,{gap:0,style:{minWidth:0},children:[e.jsxs(h,{align:"center",gap:2,children:[e.jsx("strong",{children:a.name||a.id}),e.jsx("code",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:a.id}),a.version&&e.jsxs("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-muted)"},children:["v",a.version]}),a.enabled===!1&&e.jsx("span",{style:{fontSize:"var(--fs-11)",color:"var(--warning)",fontWeight:600},children:"DISABLED"}),b&&e.jsxs("span",{"data-testid":`mod-upgrade-available-${a.id}`,style:{fontSize:"var(--fs-11)",color:"var(--accent)",fontWeight:600},children:["↑ v",b," available"]})]}),a.description&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:a.description})]}),e.jsxs(h,{gap:1,children:[b&&e.jsxs(i,{variant:"ghost",onClick:()=>void R(a.id),"data-testid":`mod-upgrade-${a.id}`,"aria-label":`Upgrade ${a.id}`,children:[e.jsx(F,{size:14,"aria-hidden":!0})," Upgrade"]}),e.jsx(i,{variant:"ghost",onClick:()=>void P(a.id,!(a.enabled??!0)),"data-testid":`mod-toggle-${a.id}`,"aria-label":a.enabled===!1?`Enable ${a.id}`:`Disable ${a.id}`,children:a.enabled===!1?e.jsx(q,{size:14,"aria-hidden":!0}):e.jsx(J,{size:14,"aria-hidden":!0})}),e.jsx(i,{variant:"ghost",onClick:()=>void T(a.id),"data-testid":`mod-reinstall-instructions-${a.id}`,"aria-label":`Reinstall instructions ${a.id}`,children:e.jsx(N,{size:14,"aria-hidden":!0})}),e.jsx(i,{variant:"ghost",onClick:()=>void M(a.id),"data-testid":`mod-edit-${a.id}`,"aria-label":`Edit mod file ${a.id}`,children:e.jsx(K,{size:14,"aria-hidden":!0})}),e.jsx(i,{variant:"ghost",onClick:()=>v(S=>S===a.id?null:a.id),"data-testid":`mod-uninstall-${a.id}`,"aria-label":`Uninstall ${a.id}`,children:e.jsx(Y,{size:14,"aria-hidden":!0})})]})]}),s&&e.jsxs(h,{gap:1,style:{marginTop:"var(--space-1)"},children:[e.jsx(i,{variant:"danger",onClick:()=>void E(a.id),"data-testid":`mod-confirm-uninstall-${a.id}`,children:"Confirm uninstall"}),e.jsx(i,{variant:"ghost",onClick:()=>v(null),children:"Cancel"})]})]},a.id)})})]})}),e.jsx(w,{variant:"default",children:e.jsxs(k,{children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Registry"}),g.loading&&u.length===0?e.jsx(c,{gap:1,style:{marginTop:"var(--space-2)"},children:e.jsx(z,{style:{height:40}})}):u.length===0?e.jsx($,{icon:e.jsx(I,{size:28,"aria-hidden":!0}),title:"Registry unreachable",description:"Cannot reach the public mod registry right now."}):e.jsx(c,{gap:1,style:{marginTop:"var(--space-2)"},children:u.slice(0,30).map(a=>e.jsxs("div",{"data-testid":`mod-registry-row-${a.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",display:"flex",justifyContent:"space-between",gap:"var(--space-2)"},children:[e.jsxs(c,{gap:0,style:{minWidth:0},children:[e.jsxs(h,{align:"center",gap:2,children:[e.jsx("strong",{children:a.name||a.id}),e.jsx("code",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:a.id}),e.jsxs("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-muted)"},children:["v",a.latest]}),a.installed&&e.jsx("span",{style:{fontSize:"var(--fs-11)",color:"var(--success)"},children:"installed"})]}),a.description&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:a.description})]}),!a.installed&&e.jsxs(i,{variant:"ghost",onClick:async()=>{r(null);try{await f("/api/mods",{method:"POST",body:{id:a.id}}),t()}catch(s){r((s instanceof m,s.message))}},"data-testid":`mod-registry-install-${a.id}`,children:[e.jsx(I,{size:14,"aria-hidden":!0})," Install"]})]},a.id))})]})}),e.jsx(V,{open:y,onOpenChange:x,children:e.jsx(A,{side:"right",title:"Install mod",description:"From registry id or local path.",children:e.jsx(Q,{onSubmit:async a=>{await f("/api/mods",{method:"POST",body:a}),x(!1),t()},onCancel:()=>x(!1)})})})]})}function Q({onSubmit:p,onCancel:g}){const[n,v]=o.useState("registry"),[y,x]=o.useState(""),[j,r]=o.useState(!1),[l,u]=o.useState(null);return e.jsxs(c,{gap:3,style:{padding:"var(--space-4)"},children:[e.jsxs(h,{gap:1,role:"tablist",children:[e.jsx("button",{type:"button",role:"tab","aria-selected":n==="registry",onClick:()=>v("registry"),"data-testid":"mod-install-mode-registry",style:{padding:"var(--space-1) var(--space-3)",borderRadius:"var(--radius-md)",border:"1px solid var(--border)",background:n==="registry"?"var(--accent-soft)":"var(--surface-0)",color:n==="registry"?"var(--accent)":"var(--fg-muted)",fontSize:"var(--fs-12)",cursor:"pointer"},children:"Registry id"}),e.jsx("button",{type:"button",role:"tab","aria-selected":n==="path",onClick:()=>v("path"),"data-testid":"mod-install-mode-path",style:{padding:"var(--space-1) var(--space-3)",borderRadius:"var(--radius-md)",border:"1px solid var(--border)",background:n==="path"?"var(--accent-soft)":"var(--surface-0)",color:n==="path"?"var(--accent)":"var(--fg-muted)",fontSize:"var(--fs-12)",cursor:"pointer"},children:"Local path"})]}),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:n==="registry"?"Registry id (e.g. @bizar/mod-foo)":"Local path (e.g. /abs/path/to/mod)"}),e.jsx(B,{value:y,onChange:t=>x(t.target.value),placeholder:n==="registry"?"@org/mod-name":"/abs/path/to/mod","data-testid":"mod-install-input"})]}),l!==null&&e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:l}),e.jsxs(h,{justify:"end",gap:2,children:[e.jsx(i,{variant:"ghost",onClick:g,children:"Cancel"}),e.jsxs(i,{variant:"primary",disabled:j||!y.trim(),"data-testid":"mod-install-submit",onClick:async()=>{r(!0),u(null);try{const t=n==="registry"?{id:y.trim()}:{path:y.trim()};await p(t)}catch(t){u((t instanceof m,t.message))}finally{r(!1)}},children:[e.jsx(G,{size:14,"aria-hidden":!0})," ",j?"Installing…":"Install"]})]})]})}export{ge as ModsView};
6
+ */const G=D("FilePen",[["path",{d:"M12.5 22H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v9.5",key:"1couwa"}],["path",{d:"M14 2v4a2 2 0 0 0 2 2h4",key:"tnqrlb"}],["path",{d:"M13.378 15.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z",key:"1y4qbx"}]]);function ge(){const p=C("/api/mods"),g=C("/api/mods/registry"),[n,v]=o.useState(null),[y,x]=o.useState(!1),[j,r]=o.useState(null),l=o.useMemo(()=>{var a;return((a=p.data)==null?void 0:a.mods)??[]},[p.data]),u=o.useMemo(()=>{var a;return((a=g.data)==null?void 0:a.mods)??[]},[g.data]),t=o.useCallback(()=>{p.refetch(),g.refetch()},[p,g]),E=async a=>{r(null);try{await f(`/api/mods/${a}`,{method:"DELETE"}),v(null),t()}catch(s){r((s instanceof m,s.message))}},P=async(a,s)=>{r(null);try{await f(`/api/mods/${a}`,{method:"PUT",body:{enabled:s}}),t()}catch(d){r((d instanceof m,d.message))}},R=async a=>{r(null);try{await f(`/api/mods/${a}/upgrade`,{method:"POST"}),t()}catch(s){r((s instanceof m,s.message))}},T=async a=>{r(null);try{await f(`/api/mods/${a}/instructions/reinstall`,{method:"POST"}),t()}catch(s){r((s instanceof m,s.message))}},M=async a=>{const s=window.prompt(`Edit mod file content for ${a} (JSON or YAML)`);if(s!==null){r(null);try{await f(`/api/mods/${a}/mod-file/content`,{method:"PUT",body:{content:s}}),t()}catch(d){r((d instanceof m,d.message))}}};return e.jsxs(c,{gap:4,"data-testid":"mods-view",children:[e.jsx(L,{title:"Mods",description:"Installed + registry-installed mods. Each mod ships its own UI view(s).",actions:e.jsxs(h,{align:"center",gap:2,children:[j!==null&&e.jsx("span",{role:"alert","data-testid":"mods-error",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:j}),e.jsxs(i,{variant:"ghost",onClick:()=>void t(),"data-testid":"mods-refresh",children:[e.jsx(H,{size:14,"aria-hidden":!0})," Refresh"]}),e.jsxs(i,{variant:"primary",onClick:()=>x(!0),"data-testid":"mods-install",children:[e.jsx(W,{size:14,"aria-hidden":!0})," Install"]})]})}),e.jsx(O,{title:"Installed",count:l.length,testid:"mods-list-header"}),e.jsx(w,{variant:"default",children:e.jsxs(k,{children:[e.jsxs("strong",{style:{fontSize:"var(--fs-13)"},children:["Installed (",l.length,")"]}),p.loading&&l.length===0?e.jsx(c,{gap:1,style:{marginTop:"var(--space-2)"},children:e.jsx(z,{style:{height:40}})}):l.length===0?e.jsx($,{icon:e.jsx(U,{size:28,"aria-hidden":!0}),title:"No mods installed",description:"Install one from the registry or a local path."}):e.jsx(c,{gap:1,style:{marginTop:"var(--space-2)"},children:l.map(a=>{const s=n===a.id,d=u.find(S=>S.id===a.id),b=(d==null?void 0:d.upgradeAvailable)??null;return e.jsxs("div",{"data-testid":`mod-row-${a.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",background:"var(--surface-0)"},children:[e.jsxs(h,{align:"center",justify:"between",gap:2,children:[e.jsxs(c,{gap:0,style:{minWidth:0},children:[e.jsxs(h,{align:"center",gap:2,children:[e.jsx("strong",{children:a.name||a.id}),e.jsx("code",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:a.id}),a.version&&e.jsxs("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-muted)"},children:["v",a.version]}),a.enabled===!1&&e.jsx("span",{style:{fontSize:"var(--fs-11)",color:"var(--warning)",fontWeight:600},children:"DISABLED"}),b&&e.jsxs("span",{"data-testid":`mod-upgrade-available-${a.id}`,style:{fontSize:"var(--fs-11)",color:"var(--accent)",fontWeight:600},children:["↑ v",b," available"]})]}),a.description&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:a.description})]}),e.jsxs(h,{gap:1,children:[b&&e.jsxs(i,{variant:"ghost",onClick:()=>void R(a.id),"data-testid":`mod-upgrade-${a.id}`,"aria-label":`Upgrade ${a.id}`,children:[e.jsx(F,{size:14,"aria-hidden":!0})," Upgrade"]}),e.jsx(i,{variant:"ghost",onClick:()=>void P(a.id,!(a.enabled??!0)),"data-testid":`mod-toggle-${a.id}`,"aria-label":a.enabled===!1?`Enable ${a.id}`:`Disable ${a.id}`,children:a.enabled===!1?e.jsx(q,{size:14,"aria-hidden":!0}):e.jsx(J,{size:14,"aria-hidden":!0})}),e.jsx(i,{variant:"ghost",onClick:()=>void T(a.id),"data-testid":`mod-reinstall-instructions-${a.id}`,"aria-label":`Reinstall instructions ${a.id}`,children:e.jsx(N,{size:14,"aria-hidden":!0})}),e.jsx(i,{variant:"ghost",onClick:()=>void M(a.id),"data-testid":`mod-edit-${a.id}`,"aria-label":`Edit mod file ${a.id}`,children:e.jsx(G,{size:14,"aria-hidden":!0})}),e.jsx(i,{variant:"ghost",onClick:()=>v(S=>S===a.id?null:a.id),"data-testid":`mod-uninstall-${a.id}`,"aria-label":`Uninstall ${a.id}`,children:e.jsx(Y,{size:14,"aria-hidden":!0})})]})]}),s&&e.jsxs(h,{gap:1,style:{marginTop:"var(--space-1)"},children:[e.jsx(i,{variant:"danger",onClick:()=>void E(a.id),"data-testid":`mod-confirm-uninstall-${a.id}`,children:"Confirm uninstall"}),e.jsx(i,{variant:"ghost",onClick:()=>v(null),children:"Cancel"})]})]},a.id)})})]})}),e.jsx(w,{variant:"default",children:e.jsxs(k,{children:[e.jsx("strong",{style:{fontSize:"var(--fs-13)"},children:"Registry"}),g.loading&&u.length===0?e.jsx(c,{gap:1,style:{marginTop:"var(--space-2)"},children:e.jsx(z,{style:{height:40}})}):u.length===0?e.jsx($,{icon:e.jsx(I,{size:28,"aria-hidden":!0}),title:"Registry unreachable",description:"Cannot reach the public mod registry right now."}):e.jsx(c,{gap:1,style:{marginTop:"var(--space-2)"},children:u.slice(0,30).map(a=>e.jsxs("div",{"data-testid":`mod-registry-row-${a.id}`,style:{padding:"var(--space-2)",border:"1px solid var(--border)",borderRadius:"var(--radius-sm)",display:"flex",justifyContent:"space-between",gap:"var(--space-2)"},children:[e.jsxs(c,{gap:0,style:{minWidth:0},children:[e.jsxs(h,{align:"center",gap:2,children:[e.jsx("strong",{children:a.name||a.id}),e.jsx("code",{style:{fontSize:"var(--fs-11)",color:"var(--fg-subtle)"},children:a.id}),e.jsxs("span",{style:{fontSize:"var(--fs-11)",color:"var(--fg-muted)"},children:["v",a.latest]}),a.installed&&e.jsx("span",{style:{fontSize:"var(--fs-11)",color:"var(--success)"},children:"installed"})]}),a.description&&e.jsx("span",{style:{fontSize:"var(--fs-12)",color:"var(--fg-muted)"},children:a.description})]}),!a.installed&&e.jsxs(i,{variant:"ghost",onClick:async()=>{r(null);try{await f("/api/mods",{method:"POST",body:{id:a.id}}),t()}catch(s){r((s instanceof m,s.message))}},"data-testid":`mod-registry-install-${a.id}`,children:[e.jsx(I,{size:14,"aria-hidden":!0})," Install"]})]},a.id))})]})}),e.jsx(V,{open:y,onOpenChange:x,children:e.jsx(A,{side:"right",title:"Install mod",description:"From registry id or local path.",children:e.jsx(K,{onSubmit:async a=>{await f("/api/mods",{method:"POST",body:a}),x(!1),t()},onCancel:()=>x(!1)})})})]})}function K({onSubmit:p,onCancel:g}){const[n,v]=o.useState("registry"),[y,x]=o.useState(""),[j,r]=o.useState(!1),[l,u]=o.useState(null);return e.jsxs(c,{gap:3,style:{padding:"var(--space-4)"},children:[e.jsxs(h,{gap:1,role:"tablist",children:[e.jsx("button",{type:"button",role:"tab","aria-selected":n==="registry",onClick:()=>v("registry"),"data-testid":"mod-install-mode-registry",style:{padding:"var(--space-1) var(--space-3)",borderRadius:"var(--radius-md)",border:"1px solid var(--border)",background:n==="registry"?"var(--accent-soft)":"var(--surface-0)",color:n==="registry"?"var(--accent)":"var(--fg-muted)",fontSize:"var(--fs-12)",cursor:"pointer"},children:"Registry id"}),e.jsx("button",{type:"button",role:"tab","aria-selected":n==="path",onClick:()=>v("path"),"data-testid":"mod-install-mode-path",style:{padding:"var(--space-1) var(--space-3)",borderRadius:"var(--radius-md)",border:"1px solid var(--border)",background:n==="path"?"var(--accent-soft)":"var(--surface-0)",color:n==="path"?"var(--accent)":"var(--fg-muted)",fontSize:"var(--fs-12)",cursor:"pointer"},children:"Local path"})]}),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:n==="registry"?"Registry id (e.g. @bizar/mod-foo)":"Local path (e.g. /abs/path/to/mod)"}),e.jsx(B,{value:y,onChange:t=>x(t.target.value),placeholder:n==="registry"?"@org/mod-name":"/abs/path/to/mod","data-testid":"mod-install-input"})]}),l!==null&&e.jsx("span",{role:"alert",style:{color:"var(--danger)",fontSize:"var(--fs-12)"},children:l}),e.jsxs(h,{justify:"end",gap:2,children:[e.jsx(i,{variant:"ghost",onClick:g,children:"Cancel"}),e.jsxs(i,{variant:"primary",disabled:j||!y.trim(),"data-testid":"mod-install-submit",onClick:async()=>{r(!0),u(null);try{const t=n==="registry"?{id:y.trim()}:{path:y.trim()};await p(t)}catch(t){u((t instanceof m,t.message))}finally{r(!1)}},children:[e.jsx(Z,{size:14,"aria-hidden":!0})," ",j?"Installing…":"Install"]})]})]})}export{ge as ModsView};
@@ -1 +1 @@
1
- {"version":3,"file":"ModsView-BVM3X5xc.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/file-pen.js","../../src/web/v8/views/Mods/ModsView.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 FilePen = createLucideIcon(\"FilePen\", [\n [\"path\", { d: \"M12.5 22H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v9.5\", key: \"1couwa\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\n \"path\",\n {\n d: \"M13.378 15.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z\",\n key: \"1y4qbx\"\n }\n ]\n]);\n\nexport { FilePen as default };\n//# sourceMappingURL=file-pen.js.map\n","/**\n * v8/views/Mods/ModsView.tsx — Sprint S42, v9.3.0.\n *\n * Two-section mod manager:\n * - Installed (GET /api/mods): list with enable toggle (PUT\n * /api/mods/:id {enabled}) and inline-confirm Uninstall (DELETE\n * /api/mods/:id). Upgrade button if registry reports a newer\n * version (POST /api/mods/:id/upgrade).\n * - Registry (GET /api/mods/registry): list of available mods from\n * the public registry, with Install button for un-installed ones.\n *\n * Install Sheet accepts either `path` (local) or `id` (registry).\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Boxes, Download, FileEdit, Plus, Power, PowerOff, RefreshCcw, RotateCcw, Trash2, Upload, ArrowUpCircle } 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 { Input } from '../../ui/controls/Input.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 Mod {\n id: string;\n name?: string;\n version?: string;\n enabled?: boolean;\n description?: string;\n installed?: boolean;\n installedVersion?: string | null;\n upgradeAvailable?: string | null;\n latest?: string;\n}\n\ninterface RegistryResponse {\n registry?: { version?: number; updatedAt?: string; source?: string };\n mods?: Mod[];\n}\n\nexport function ModsView(): JSX.Element {\n const payload = useFetch<{ mods: Mod[] }>('/api/mods');\n const registryPayload = useFetch<RegistryResponse>('/api/mods/registry');\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [installing, setInstalling] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n const mods = useMemo<Mod[]>(() => payload.data?.mods ?? [], [payload.data]);\n const registryMods = useMemo<Mod[]>(() => registryPayload.data?.mods ?? [], [registryPayload.data]);\n const refresh = useCallback(() => { void payload.refetch(); void registryPayload.refetch(); }, [payload, registryPayload]);\n\n const drop = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/mods/${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 toggle = async (id: string, enabled: boolean): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/mods/${id}`, { method: 'PUT', body: { enabled } });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const upgrade = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/mods/${id}/upgrade`, { method: 'POST' });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const reinstallInstructions = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/mods/${id}/instructions/reinstall`, { method: 'POST' });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const editModFile = async (id: string): Promise<void> => {\n const content = window.prompt(`Edit mod file content for ${id} (JSON or YAML)`);\n if (content === null) return;\n setError(null);\n try {\n await fetchJson(`/api/mods/${id}/mod-file/content`, { method: 'PUT', body: { content } });\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=\"mods-view\">\n <ViewHeader\n title=\"Mods\"\n description=\"Installed + registry-installed mods. Each mod ships its own UI view(s).\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"mods-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"mods-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => setInstalling(true)} data-testid=\"mods-install\">\n <Plus size={14} aria-hidden /> Install\n </Button>\n </Inline>\n }\n />\n <ListHeader title=\"Installed\" count={mods.length} testid=\"mods-list-header\" />\n\n <Card variant=\"default\">\n <CardBody>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Installed ({mods.length})</strong>\n {payload.loading && mods.length === 0 ? (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n <Skeleton style={{ height: 40 }} />\n </Stack>\n ) : mods.length === 0 ? (\n <EmptyState icon={<Boxes size={28} aria-hidden />} title=\"No mods installed\" description=\"Install one from the registry or a local path.\" />\n ) : (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n {mods.map((m) => {\n const isConfirming = confirmDelete === m.id;\n const registryMatch = registryMods.find((r) => r.id === m.id);\n const upgradeTarget = registryMatch?.upgradeAvailable ?? null;\n return (\n <div\n key={m.id}\n data-testid={`mod-row-${m.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>{m.name || m.id}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{m.id}</code>\n {m.version && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>v{m.version}</span>}\n {m.enabled === false && (\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--warning)', fontWeight: 600 }}>DISABLED</span>\n )}\n {upgradeTarget && (\n <span data-testid={`mod-upgrade-available-${m.id}`} style={{ fontSize: 'var(--fs-11)', color: 'var(--accent)', fontWeight: 600 }}>\n ↑ v{upgradeTarget} available\n </span>\n )}\n </Inline>\n {m.description && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{m.description}</span>\n )}\n </Stack>\n <Inline gap={1}>\n {upgradeTarget && (\n <Button variant=\"ghost\" onClick={() => void upgrade(m.id)} data-testid={`mod-upgrade-${m.id}`} aria-label={`Upgrade ${m.id}`}>\n <ArrowUpCircle size={14} aria-hidden /> Upgrade\n </Button>\n )}\n <Button variant=\"ghost\" onClick={() => void toggle(m.id, !(m.enabled ?? true))} data-testid={`mod-toggle-${m.id}`} aria-label={m.enabled === false ? `Enable ${m.id}` : `Disable ${m.id}`}>\n {m.enabled === false ? <Power size={14} aria-hidden /> : <PowerOff size={14} aria-hidden />}\n </Button>\n <Button variant=\"ghost\" onClick={() => void reinstallInstructions(m.id)} data-testid={`mod-reinstall-instructions-${m.id}`} aria-label={`Reinstall instructions ${m.id}`}>\n <RotateCcw size={14} aria-hidden />\n </Button>\n <Button variant=\"ghost\" onClick={() => void editModFile(m.id)} data-testid={`mod-edit-${m.id}`} aria-label={`Edit mod file ${m.id}`}>\n <FileEdit size={14} aria-hidden />\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete((cur) => (cur === m.id ? null : m.id))} data-testid={`mod-uninstall-${m.id}`} aria-label={`Uninstall ${m.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(m.id)} data-testid={`mod-confirm-uninstall-${m.id}`}>\n Confirm uninstall\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 <Card variant=\"default\">\n <CardBody>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Registry</strong>\n {registryPayload.loading && registryMods.length === 0 ? (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n <Skeleton style={{ height: 40 }} />\n </Stack>\n ) : registryMods.length === 0 ? (\n <EmptyState icon={<Download size={28} aria-hidden />} title=\"Registry unreachable\" description=\"Cannot reach the public mod registry right now.\" />\n ) : (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n {registryMods.slice(0, 30).map((m) => (\n <div\n key={m.id}\n data-testid={`mod-registry-row-${m.id}`}\n style={{\n padding: 'var(--space-2)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n display: 'flex',\n justifyContent: 'space-between',\n gap: 'var(--space-2)',\n }}\n >\n <Stack gap={0} style={{ minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <strong>{m.name || m.id}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{m.id}</code>\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>v{m.latest}</span>\n {m.installed && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--success)' }}>installed</span>}\n </Inline>\n {m.description && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{m.description}</span>\n )}\n </Stack>\n {!m.installed && (\n <Button variant=\"ghost\" onClick={async () => {\n setError(null);\n try {\n await fetchJson('/api/mods', { method: 'POST', body: { id: m.id } });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n }} data-testid={`mod-registry-install-${m.id}`}>\n <Download size={14} aria-hidden /> Install\n </Button>\n )}\n </div>\n ))}\n </Stack>\n )}\n </CardBody>\n </Card>\n\n <Sheet open={installing} onOpenChange={setInstalling}>\n <SheetContent side=\"right\" title=\"Install mod\" description=\"From registry id or local path.\">\n <InstallForm\n onSubmit={async (body) => {\n await fetchJson('/api/mods', { method: 'POST', body });\n setInstalling(false);\n refresh();\n }}\n onCancel={() => setInstalling(false)}\n />\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}\n\nfunction InstallForm({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (body: { id?: string; path?: string }) => Promise<void>;\n onCancel: () => void;\n}): JSX.Element {\n const [mode, setMode] = useState<'registry' | 'path'>('registry');\n const [value, setValue] = 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 <Inline gap={1} role=\"tablist\">\n <button type=\"button\" role=\"tab\" aria-selected={mode === 'registry'} onClick={() => setMode('registry')} data-testid=\"mod-install-mode-registry\"\n style={{ padding: 'var(--space-1) var(--space-3)', borderRadius: 'var(--radius-md)', border: '1px solid var(--border)', background: mode === 'registry' ? 'var(--accent-soft)' : 'var(--surface-0)', color: mode === 'registry' ? 'var(--accent)' : 'var(--fg-muted)', fontSize: 'var(--fs-12)', cursor: 'pointer' }}>\n Registry id\n </button>\n <button type=\"button\" role=\"tab\" aria-selected={mode === 'path'} onClick={() => setMode('path')} data-testid=\"mod-install-mode-path\"\n style={{ padding: 'var(--space-1) var(--space-3)', borderRadius: 'var(--radius-md)', border: '1px solid var(--border)', background: mode === 'path' ? 'var(--accent-soft)' : 'var(--surface-0)', color: mode === 'path' ? 'var(--accent)' : 'var(--fg-muted)', fontSize: 'var(--fs-12)', cursor: 'pointer' }}>\n Local path\n </button>\n </Inline>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {mode === 'registry' ? 'Registry id (e.g. @bizar/mod-foo)' : 'Local path (e.g. /abs/path/to/mod)'}\n </span>\n <Input\n value={value}\n onChange={(e) => setValue((e.target as HTMLInputElement).value)}\n placeholder={mode === 'registry' ? '@org/mod-name' : '/abs/path/to/mod'}\n data-testid=\"mod-install-input\"\n />\n </label>\n {error !== null && (\n <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Inline justify=\"end\" gap={2}>\n <Button variant=\"ghost\" onClick={onCancel}>Cancel</Button>\n <Button\n variant=\"primary\"\n disabled={busy || !value.trim()}\n data-testid=\"mod-install-submit\"\n onClick={async () => {\n setBusy(true);\n setError(null);\n try {\n const body = mode === 'registry' ? { id: value.trim() } : { path: value.trim() };\n await onSubmit(body);\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n }}\n >\n <Upload size={14} aria-hidden /> {busy ? 'Installing…' : 'Install'}\n </Button>\n </Inline>\n </Stack>\n );\n}"],"names":["FilePen","createLucideIcon","ModsView","payload","useFetch","registryPayload","confirmDelete","setConfirmDelete","useState","installing","setInstalling","error","setError","mods","useMemo","_a","registryMods","refresh","useCallback","drop","id","fetchJson","err","FetchError","toggle","enabled","upgrade","reinstallInstructions","editModFile","content","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCcw","Plus","ListHeader","Card","CardBody","Skeleton","EmptyState","Boxes","m","isConfirming","registryMatch","r","upgradeTarget","ArrowUpCircle","Power","PowerOff","RotateCcw","FileEdit","cur","Trash2","Download","Sheet","SheetContent","InstallForm","body","onSubmit","onCancel","mode","setMode","value","setValue","busy","setBusy","Input","e","Upload"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"ModsView-B6OR-a4B.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/file-pen.js","../../src/web/v8/views/Mods/ModsView.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 FilePen = createLucideIcon(\"FilePen\", [\n [\"path\", { d: \"M12.5 22H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v9.5\", key: \"1couwa\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\n \"path\",\n {\n d: \"M13.378 15.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z\",\n key: \"1y4qbx\"\n }\n ]\n]);\n\nexport { FilePen as default };\n//# sourceMappingURL=file-pen.js.map\n","/**\n * v8/views/Mods/ModsView.tsx — Sprint S42, v9.3.0.\n *\n * Two-section mod manager:\n * - Installed (GET /api/mods): list with enable toggle (PUT\n * /api/mods/:id {enabled}) and inline-confirm Uninstall (DELETE\n * /api/mods/:id). Upgrade button if registry reports a newer\n * version (POST /api/mods/:id/upgrade).\n * - Registry (GET /api/mods/registry): list of available mods from\n * the public registry, with Install button for un-installed ones.\n *\n * Install Sheet accepts either `path` (local) or `id` (registry).\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Boxes, Download, FileEdit, Plus, Power, PowerOff, RefreshCcw, RotateCcw, Trash2, Upload, ArrowUpCircle } 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 { Input } from '../../ui/controls/Input.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 Mod {\n id: string;\n name?: string;\n version?: string;\n enabled?: boolean;\n description?: string;\n installed?: boolean;\n installedVersion?: string | null;\n upgradeAvailable?: string | null;\n latest?: string;\n}\n\ninterface RegistryResponse {\n registry?: { version?: number; updatedAt?: string; source?: string };\n mods?: Mod[];\n}\n\nexport function ModsView(): JSX.Element {\n const payload = useFetch<{ mods: Mod[] }>('/api/mods');\n const registryPayload = useFetch<RegistryResponse>('/api/mods/registry');\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n const [installing, setInstalling] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n\n const mods = useMemo<Mod[]>(() => payload.data?.mods ?? [], [payload.data]);\n const registryMods = useMemo<Mod[]>(() => registryPayload.data?.mods ?? [], [registryPayload.data]);\n const refresh = useCallback(() => { void payload.refetch(); void registryPayload.refetch(); }, [payload, registryPayload]);\n\n const drop = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/mods/${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 toggle = async (id: string, enabled: boolean): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/mods/${id}`, { method: 'PUT', body: { enabled } });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const upgrade = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/mods/${id}/upgrade`, { method: 'POST' });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const reinstallInstructions = async (id: string): Promise<void> => {\n setError(null);\n try {\n await fetchJson(`/api/mods/${id}/instructions/reinstall`, { method: 'POST' });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n };\n\n const editModFile = async (id: string): Promise<void> => {\n const content = window.prompt(`Edit mod file content for ${id} (JSON or YAML)`);\n if (content === null) return;\n setError(null);\n try {\n await fetchJson(`/api/mods/${id}/mod-file/content`, { method: 'PUT', body: { content } });\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=\"mods-view\">\n <ViewHeader\n title=\"Mods\"\n description=\"Installed + registry-installed mods. Each mod ships its own UI view(s).\"\n actions={\n <Inline align=\"center\" gap={2}>\n {error !== null && (\n <span role=\"alert\" data-testid=\"mods-error\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>\n {error}\n </span>\n )}\n <Button variant=\"ghost\" onClick={() => void refresh()} data-testid=\"mods-refresh\">\n <RefreshCcw size={14} aria-hidden /> Refresh\n </Button>\n <Button variant=\"primary\" onClick={() => setInstalling(true)} data-testid=\"mods-install\">\n <Plus size={14} aria-hidden /> Install\n </Button>\n </Inline>\n }\n />\n <ListHeader title=\"Installed\" count={mods.length} testid=\"mods-list-header\" />\n\n <Card variant=\"default\">\n <CardBody>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Installed ({mods.length})</strong>\n {payload.loading && mods.length === 0 ? (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n <Skeleton style={{ height: 40 }} />\n </Stack>\n ) : mods.length === 0 ? (\n <EmptyState icon={<Boxes size={28} aria-hidden />} title=\"No mods installed\" description=\"Install one from the registry or a local path.\" />\n ) : (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n {mods.map((m) => {\n const isConfirming = confirmDelete === m.id;\n const registryMatch = registryMods.find((r) => r.id === m.id);\n const upgradeTarget = registryMatch?.upgradeAvailable ?? null;\n return (\n <div\n key={m.id}\n data-testid={`mod-row-${m.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>{m.name || m.id}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{m.id}</code>\n {m.version && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>v{m.version}</span>}\n {m.enabled === false && (\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--warning)', fontWeight: 600 }}>DISABLED</span>\n )}\n {upgradeTarget && (\n <span data-testid={`mod-upgrade-available-${m.id}`} style={{ fontSize: 'var(--fs-11)', color: 'var(--accent)', fontWeight: 600 }}>\n ↑ v{upgradeTarget} available\n </span>\n )}\n </Inline>\n {m.description && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{m.description}</span>\n )}\n </Stack>\n <Inline gap={1}>\n {upgradeTarget && (\n <Button variant=\"ghost\" onClick={() => void upgrade(m.id)} data-testid={`mod-upgrade-${m.id}`} aria-label={`Upgrade ${m.id}`}>\n <ArrowUpCircle size={14} aria-hidden /> Upgrade\n </Button>\n )}\n <Button variant=\"ghost\" onClick={() => void toggle(m.id, !(m.enabled ?? true))} data-testid={`mod-toggle-${m.id}`} aria-label={m.enabled === false ? `Enable ${m.id}` : `Disable ${m.id}`}>\n {m.enabled === false ? <Power size={14} aria-hidden /> : <PowerOff size={14} aria-hidden />}\n </Button>\n <Button variant=\"ghost\" onClick={() => void reinstallInstructions(m.id)} data-testid={`mod-reinstall-instructions-${m.id}`} aria-label={`Reinstall instructions ${m.id}`}>\n <RotateCcw size={14} aria-hidden />\n </Button>\n <Button variant=\"ghost\" onClick={() => void editModFile(m.id)} data-testid={`mod-edit-${m.id}`} aria-label={`Edit mod file ${m.id}`}>\n <FileEdit size={14} aria-hidden />\n </Button>\n <Button variant=\"ghost\" onClick={() => setConfirmDelete((cur) => (cur === m.id ? null : m.id))} data-testid={`mod-uninstall-${m.id}`} aria-label={`Uninstall ${m.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(m.id)} data-testid={`mod-confirm-uninstall-${m.id}`}>\n Confirm uninstall\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 <Card variant=\"default\">\n <CardBody>\n <strong style={{ fontSize: 'var(--fs-13)' }}>Registry</strong>\n {registryPayload.loading && registryMods.length === 0 ? (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n <Skeleton style={{ height: 40 }} />\n </Stack>\n ) : registryMods.length === 0 ? (\n <EmptyState icon={<Download size={28} aria-hidden />} title=\"Registry unreachable\" description=\"Cannot reach the public mod registry right now.\" />\n ) : (\n <Stack gap={1} style={{ marginTop: 'var(--space-2)' }}>\n {registryMods.slice(0, 30).map((m) => (\n <div\n key={m.id}\n data-testid={`mod-registry-row-${m.id}`}\n style={{\n padding: 'var(--space-2)',\n border: '1px solid var(--border)',\n borderRadius: 'var(--radius-sm)',\n display: 'flex',\n justifyContent: 'space-between',\n gap: 'var(--space-2)',\n }}\n >\n <Stack gap={0} style={{ minWidth: 0 }}>\n <Inline align=\"center\" gap={2}>\n <strong>{m.name || m.id}</strong>\n <code style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-subtle)' }}>{m.id}</code>\n <span style={{ fontSize: 'var(--fs-11)', color: 'var(--fg-muted)' }}>v{m.latest}</span>\n {m.installed && <span style={{ fontSize: 'var(--fs-11)', color: 'var(--success)' }}>installed</span>}\n </Inline>\n {m.description && (\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{m.description}</span>\n )}\n </Stack>\n {!m.installed && (\n <Button variant=\"ghost\" onClick={async () => {\n setError(null);\n try {\n await fetchJson('/api/mods', { method: 'POST', body: { id: m.id } });\n refresh();\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n }\n }} data-testid={`mod-registry-install-${m.id}`}>\n <Download size={14} aria-hidden /> Install\n </Button>\n )}\n </div>\n ))}\n </Stack>\n )}\n </CardBody>\n </Card>\n\n <Sheet open={installing} onOpenChange={setInstalling}>\n <SheetContent side=\"right\" title=\"Install mod\" description=\"From registry id or local path.\">\n <InstallForm\n onSubmit={async (body) => {\n await fetchJson('/api/mods', { method: 'POST', body });\n setInstalling(false);\n refresh();\n }}\n onCancel={() => setInstalling(false)}\n />\n </SheetContent>\n </Sheet>\n </Stack>\n );\n}\n\nfunction InstallForm({\n onSubmit,\n onCancel,\n}: {\n onSubmit: (body: { id?: string; path?: string }) => Promise<void>;\n onCancel: () => void;\n}): JSX.Element {\n const [mode, setMode] = useState<'registry' | 'path'>('registry');\n const [value, setValue] = 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 <Inline gap={1} role=\"tablist\">\n <button type=\"button\" role=\"tab\" aria-selected={mode === 'registry'} onClick={() => setMode('registry')} data-testid=\"mod-install-mode-registry\"\n style={{ padding: 'var(--space-1) var(--space-3)', borderRadius: 'var(--radius-md)', border: '1px solid var(--border)', background: mode === 'registry' ? 'var(--accent-soft)' : 'var(--surface-0)', color: mode === 'registry' ? 'var(--accent)' : 'var(--fg-muted)', fontSize: 'var(--fs-12)', cursor: 'pointer' }}>\n Registry id\n </button>\n <button type=\"button\" role=\"tab\" aria-selected={mode === 'path'} onClick={() => setMode('path')} data-testid=\"mod-install-mode-path\"\n style={{ padding: 'var(--space-1) var(--space-3)', borderRadius: 'var(--radius-md)', border: '1px solid var(--border)', background: mode === 'path' ? 'var(--accent-soft)' : 'var(--surface-0)', color: mode === 'path' ? 'var(--accent)' : 'var(--fg-muted)', fontSize: 'var(--fs-12)', cursor: 'pointer' }}>\n Local path\n </button>\n </Inline>\n <label style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>\n <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>\n {mode === 'registry' ? 'Registry id (e.g. @bizar/mod-foo)' : 'Local path (e.g. /abs/path/to/mod)'}\n </span>\n <Input\n value={value}\n onChange={(e) => setValue((e.target as HTMLInputElement).value)}\n placeholder={mode === 'registry' ? '@org/mod-name' : '/abs/path/to/mod'}\n data-testid=\"mod-install-input\"\n />\n </label>\n {error !== null && (\n <span role=\"alert\" style={{ color: 'var(--danger)', fontSize: 'var(--fs-12)' }}>{error}</span>\n )}\n <Inline justify=\"end\" gap={2}>\n <Button variant=\"ghost\" onClick={onCancel}>Cancel</Button>\n <Button\n variant=\"primary\"\n disabled={busy || !value.trim()}\n data-testid=\"mod-install-submit\"\n onClick={async () => {\n setBusy(true);\n setError(null);\n try {\n const body = mode === 'registry' ? { id: value.trim() } : { path: value.trim() };\n await onSubmit(body);\n } catch (err) {\n setError(err instanceof FetchError ? err.message : (err as Error).message);\n } finally {\n setBusy(false);\n }\n }}\n >\n <Upload size={14} aria-hidden /> {busy ? 'Installing…' : 'Install'}\n </Button>\n </Inline>\n </Stack>\n );\n}"],"names":["FilePen","createLucideIcon","ModsView","payload","useFetch","registryPayload","confirmDelete","setConfirmDelete","useState","installing","setInstalling","error","setError","mods","useMemo","_a","registryMods","refresh","useCallback","drop","id","fetchJson","err","FetchError","toggle","enabled","upgrade","reinstallInstructions","editModFile","content","jsxs","Stack","jsx","ViewHeader","Inline","Button","RefreshCcw","Plus","ListHeader","Card","CardBody","Skeleton","EmptyState","Boxes","m","isConfirming","registryMatch","r","upgradeTarget","ArrowUpCircle","Power","PowerOff","RotateCcw","FileEdit","cur","Trash2","Download","Sheet","SheetContent","InstallForm","body","onSubmit","onCancel","mode","setMode","value","setValue","busy","setBusy","Input","e","Upload"],"mappings":"ovBAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAUC,EAAiB,UAAW,CAC1C,CAAC,OAAQ,CAAE,EAAG,uDAAwD,IAAK,QAAQ,CAAE,EACrF,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAQ,CAAE,EACxD,CACE,OACA,CACE,EAAG,kIACH,IAAK,QACX,CACA,CACA,CAAC,EC2BM,SAASC,IAAwB,CACtC,MAAMC,EAAUC,EAA0B,WAAW,EAC/CC,EAAkBD,EAA2B,oBAAoB,EACjE,CAACE,EAAeC,CAAgB,EAAIC,EAAAA,SAAwB,IAAI,EAChE,CAACC,EAAYC,CAAa,EAAIF,EAAAA,SAAkB,EAAK,EACrD,CAACG,EAAOC,CAAQ,EAAIJ,EAAAA,SAAwB,IAAI,EAEhDK,EAAOC,UAAe,IAAA,OAAM,QAAAC,EAAAZ,EAAQ,OAAR,YAAAY,EAAc,OAAQ,IAAI,CAACZ,EAAQ,IAAI,CAAC,EACpEa,EAAeF,UAAe,IAAA,OAAM,QAAAC,EAAAV,EAAgB,OAAhB,YAAAU,EAAsB,OAAQ,IAAI,CAACV,EAAgB,IAAI,CAAC,EAC5FY,EAAUC,EAAAA,YAAY,IAAM,CAAOf,EAAQ,QAAA,EAAgBE,EAAgB,QAAA,CAAW,EAAG,CAACF,EAASE,CAAe,CAAC,EAEnHc,EAAO,MAAOC,GAA8B,CAChDR,EAAS,IAAI,EACb,GAAI,CACF,MAAMS,EAAU,aAAaD,CAAE,GAAI,CAAE,OAAQ,SAAU,EACvDb,EAAiB,IAAI,EACrBU,EAAA,CACF,OAASK,EAAK,CACZV,GAASU,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,CACF,EAEME,EAAS,MAAOJ,EAAYK,IAAoC,CACpEb,EAAS,IAAI,EACb,GAAI,CACF,MAAMS,EAAU,aAAaD,CAAE,GAAI,CAAE,OAAQ,MAAO,KAAM,CAAE,QAAAK,CAAA,CAAQ,CAAG,EACvER,EAAA,CACF,OAASK,EAAK,CACZV,GAASU,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,CACF,EAEMI,EAAU,MAAON,GAA8B,CACnDR,EAAS,IAAI,EACb,GAAI,CACF,MAAMS,EAAU,aAAaD,CAAE,WAAY,CAAE,OAAQ,OAAQ,EAC7DH,EAAA,CACF,OAASK,EAAK,CACZV,GAASU,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,CACF,EAEMK,EAAwB,MAAOP,GAA8B,CACjER,EAAS,IAAI,EACb,GAAI,CACF,MAAMS,EAAU,aAAaD,CAAE,0BAA2B,CAAE,OAAQ,OAAQ,EAC5EH,EAAA,CACF,OAASK,EAAK,CACZV,GAASU,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,CACF,EAEMM,EAAc,MAAOR,GAA8B,CACvD,MAAMS,EAAU,OAAO,OAAO,6BAA6BT,CAAE,iBAAiB,EAC9E,GAAIS,IAAY,KAChB,CAAAjB,EAAS,IAAI,EACb,GAAI,CACF,MAAMS,EAAU,aAAaD,CAAE,oBAAqB,CAAE,OAAQ,MAAO,KAAM,CAAE,QAAAS,CAAA,CAAQ,CAAG,EACxFZ,EAAA,CACF,OAASK,EAAK,CACZV,GAASU,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,EACF,EAEA,OACEQ,EAAAA,KAACC,EAAA,CAAM,IAAK,EAAG,cAAY,YACzB,SAAA,CAAAC,EAAAA,IAACC,EAAA,CACC,MAAM,OACN,YAAY,0EACZ,QACEH,EAAAA,KAACI,EAAA,CAAO,MAAM,SAAS,IAAK,EACzB,SAAA,CAAAvB,IAAU,MACTqB,MAAC,OAAA,CAAK,KAAK,QAAQ,cAAY,aAAa,MAAO,CAAE,MAAO,gBAAiB,SAAU,gBACpF,SAAArB,EACH,EAEFmB,EAAAA,KAACK,EAAA,CAAO,QAAQ,QAAQ,QAAS,IAAM,KAAKlB,EAAA,EAAW,cAAY,eACjE,SAAA,CAAAe,EAAAA,IAACI,EAAA,CAAW,KAAM,GAAI,cAAW,GAAC,EAAE,UAAA,EACtC,EACAN,EAAAA,KAACK,EAAA,CAAO,QAAQ,UAAU,QAAS,IAAMzB,EAAc,EAAI,EAAG,cAAY,eACxE,SAAA,CAAAsB,EAAAA,IAACK,EAAA,CAAK,KAAM,GAAI,cAAW,GAAC,EAAE,UAAA,CAAA,CAChC,CAAA,CAAA,CACF,CAAA,CAAA,EAGJL,MAACM,GAAW,MAAM,YAAY,MAAOzB,EAAK,OAAQ,OAAO,mBAAmB,EAE5EmB,MAACO,EAAA,CAAK,QAAQ,UACZ,gBAACC,EAAA,CACC,SAAA,CAAAV,EAAAA,KAAC,SAAA,CAAO,MAAO,CAAE,SAAU,gBAAkB,SAAA,CAAA,cAAYjB,EAAK,OAAO,GAAA,EAAC,EACrEV,EAAQ,SAAWU,EAAK,SAAW,QACjCkB,EAAA,CAAM,IAAK,EAAG,MAAO,CAAE,UAAW,kBACjC,SAAAC,EAAAA,IAACS,EAAA,CAAS,MAAO,CAAE,OAAQ,GAAG,CAAG,CAAA,CACnC,EACE5B,EAAK,SAAW,QACjB6B,EAAA,CAAW,KAAMV,EAAAA,IAACW,EAAA,CAAM,KAAM,GAAI,cAAW,EAAA,CAAC,EAAI,MAAM,oBAAoB,YAAY,gDAAA,CAAiD,EAE1IX,EAAAA,IAACD,EAAA,CAAM,IAAK,EAAG,MAAO,CAAE,UAAW,gBAAA,EAChC,SAAAlB,EAAK,IAAK+B,GAAM,CACf,MAAMC,EAAevC,IAAkBsC,EAAE,GACnCE,EAAgB9B,EAAa,KAAM+B,GAAMA,EAAE,KAAOH,EAAE,EAAE,EACtDI,GAAgBF,GAAA,YAAAA,EAAe,mBAAoB,KACzD,OACEhB,EAAAA,KAAC,MAAA,CAEC,cAAa,WAAWc,EAAE,EAAE,GAC5B,MAAO,CACL,QAAS,iBACT,OAAQ,0BACR,aAAc,mBACd,WAAY,kBAAA,EAGd,SAAA,CAAAd,OAACI,GAAO,MAAM,SAAS,QAAQ,UAAU,IAAK,EAC5C,SAAA,CAAAJ,OAACC,GAAM,IAAK,EAAG,MAAO,CAAE,SAAU,GAChC,SAAA,CAAAD,EAAAA,KAACI,EAAA,CAAO,MAAM,SAAS,IAAK,EAC1B,SAAA,CAAAF,EAAAA,IAAC,SAAA,CAAQ,SAAAY,EAAE,MAAQA,EAAE,GAAG,EACxBZ,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,kBAAA,EAAuB,SAAAY,EAAE,EAAA,CAAG,EAC3EA,EAAE,SAAWd,OAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAqB,SAAA,CAAA,IAAEc,EAAE,OAAA,EAAQ,EAC9FA,EAAE,UAAY,IACbZ,EAAAA,IAAC,QAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAkB,WAAY,GAAA,EAAO,SAAA,WAAQ,EAE9FgB,GACClB,EAAAA,KAAC,OAAA,CAAK,cAAa,yBAAyBc,EAAE,EAAE,GAAI,MAAO,CAAE,SAAU,eAAgB,MAAO,gBAAiB,WAAY,KAAO,SAAA,CAAA,MAC5HI,EAAc,YAAA,CAAA,CACpB,CAAA,EAEJ,EACCJ,EAAE,aACDZ,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAsB,SAAAY,EAAE,WAAA,CAAY,CAAA,EAExF,EACAd,EAAAA,KAACI,EAAA,CAAO,IAAK,EACV,SAAA,CAAAc,GACClB,EAAAA,KAACK,GAAO,QAAQ,QAAQ,QAAS,IAAM,KAAKT,EAAQkB,EAAE,EAAE,EAAG,cAAa,eAAeA,EAAE,EAAE,GAAI,aAAY,WAAWA,EAAE,EAAE,GACxH,SAAA,CAAAZ,EAAAA,IAACiB,EAAA,CAAc,KAAM,GAAI,cAAW,GAAC,EAAE,UAAA,EACzC,EAEFjB,EAAAA,IAACG,GAAO,QAAQ,QAAQ,QAAS,IAAM,KAAKX,EAAOoB,EAAE,GAAI,EAAEA,EAAE,SAAW,GAAK,EAAG,cAAa,cAAcA,EAAE,EAAE,GAAI,aAAYA,EAAE,UAAY,GAAQ,UAAUA,EAAE,EAAE,GAAK,WAAWA,EAAE,EAAE,GACpL,SAAAA,EAAE,UAAY,GAAQZ,EAAAA,IAACkB,EAAA,CAAM,KAAM,GAAI,cAAW,GAAC,EAAKlB,EAAAA,IAACmB,GAAS,KAAM,GAAI,cAAW,EAAA,CAAC,CAAA,CAC3F,EACAnB,EAAAA,IAACG,EAAA,CAAO,QAAQ,QAAQ,QAAS,IAAM,KAAKR,EAAsBiB,EAAE,EAAE,EAAG,cAAa,8BAA8BA,EAAE,EAAE,GAAI,aAAY,0BAA0BA,EAAE,EAAE,GACpK,SAAAZ,EAAAA,IAACoB,EAAA,CAAU,KAAM,GAAI,cAAW,EAAA,CAAC,CAAA,CACnC,EACApB,EAAAA,IAACG,EAAA,CAAO,QAAQ,QAAQ,QAAS,IAAM,KAAKP,EAAYgB,EAAE,EAAE,EAAG,cAAa,YAAYA,EAAE,EAAE,GAAI,aAAY,iBAAiBA,EAAE,EAAE,GAC/H,SAAAZ,EAAAA,IAACqB,EAAA,CAAS,KAAM,GAAI,cAAW,EAAA,CAAC,CAAA,CAClC,EACArB,EAAAA,IAACG,EAAA,CAAO,QAAQ,QAAQ,QAAS,IAAM5B,EAAkB+C,GAASA,IAAQV,EAAE,GAAK,KAAOA,EAAE,EAAG,EAAG,cAAa,iBAAiBA,EAAE,EAAE,GAAI,aAAY,aAAaA,EAAE,EAAE,GACjK,SAAAZ,EAAAA,IAACuB,EAAA,CAAO,KAAM,GAAI,cAAW,GAAC,CAAA,CAChC,CAAA,CAAA,CACF,CAAA,EACF,EACCV,UACEX,EAAA,CAAO,IAAK,EAAG,MAAO,CAAE,UAAW,gBAAA,EAClC,SAAA,CAAAF,EAAAA,IAACG,EAAA,CAAO,QAAQ,SAAS,QAAS,IAAM,KAAKhB,EAAKyB,EAAE,EAAE,EAAG,cAAa,yBAAyBA,EAAE,EAAE,GAAI,SAAA,oBAEvG,EACAZ,EAAAA,IAACG,GAAO,QAAQ,QAAQ,QAAS,IAAM5B,EAAiB,IAAI,EAAG,SAAA,QAAA,CAAM,CAAA,CAAA,CACvE,CAAA,CAAA,EAtDGqC,EAAE,EAAA,CA0Db,CAAC,CAAA,CACH,CAAA,CAAA,CAEJ,CAAA,CACF,EAEAZ,MAACO,EAAA,CAAK,QAAQ,UACZ,gBAACC,EAAA,CACC,SAAA,CAAAR,MAAC,UAAO,MAAO,CAAE,SAAU,cAAA,EAAkB,SAAA,WAAQ,EACpD3B,EAAgB,SAAWW,EAAa,SAAW,EAClDgB,EAAAA,IAACD,EAAA,CAAM,IAAK,EAAG,MAAO,CAAE,UAAW,gBAAA,EACjC,SAAAC,EAAAA,IAACS,EAAA,CAAS,MAAO,CAAE,OAAQ,EAAA,CAAG,CAAG,EACnC,EACEzB,EAAa,SAAW,EAC1BgB,EAAAA,IAACU,EAAA,CAAW,KAAMV,EAAAA,IAACwB,EAAA,CAAS,KAAM,GAAI,cAAW,EAAA,CAAC,EAAI,MAAM,uBAAuB,YAAY,iDAAA,CAAkD,EAEjJxB,EAAAA,IAACD,EAAA,CAAM,IAAK,EAAG,MAAO,CAAE,UAAW,gBAAA,EAChC,SAAAf,EAAa,MAAM,EAAG,EAAE,EAAE,IAAK4B,GAC9Bd,EAAAA,KAAC,MAAA,CAEC,cAAa,oBAAoBc,EAAE,EAAE,GACrC,MAAO,CACL,QAAS,iBACT,OAAQ,0BACR,aAAc,mBACd,QAAS,OACT,eAAgB,gBAChB,IAAK,gBAAA,EAGP,SAAA,CAAAd,OAACC,GAAM,IAAK,EAAG,MAAO,CAAE,SAAU,GAChC,SAAA,CAAAD,EAAAA,KAACI,EAAA,CAAO,MAAM,SAAS,IAAK,EAC1B,SAAA,CAAAF,EAAAA,IAAC,SAAA,CAAQ,SAAAY,EAAE,MAAQA,EAAE,GAAG,EACxBZ,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,kBAAA,EAAuB,SAAAY,EAAE,EAAA,CAAG,EAC5Ed,OAAC,QAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,mBAAqB,SAAA,CAAA,IAAEc,EAAE,MAAA,EAAO,EAC/EA,EAAE,WAAaZ,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,kBAAoB,SAAA,WAAA,CAAS,CAAA,EAC/F,EACCY,EAAE,aACDZ,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAAsB,SAAAY,EAAE,WAAA,CAAY,CAAA,EAExF,EACC,CAACA,EAAE,WACFd,OAACK,GAAO,QAAQ,QAAQ,QAAS,SAAY,CAC3CvB,EAAS,IAAI,EACb,GAAI,CACF,MAAMS,EAAU,YAAa,CAAE,OAAQ,OAAQ,KAAM,CAAE,GAAIuB,EAAE,EAAA,EAAM,EACnE3B,EAAA,CACF,OAASK,EAAK,CACZV,GAASU,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,CACF,EAAG,cAAa,wBAAwBsB,EAAE,EAAE,GAC1C,SAAA,CAAAZ,EAAAA,IAACwB,EAAA,CAAS,KAAM,GAAI,cAAW,GAAC,EAAE,UAAA,CAAA,CACpC,CAAA,CAAA,EAjCGZ,EAAE,EAAA,CAoCV,CAAA,CACH,CAAA,CAAA,CAEJ,CAAA,CACF,EAEAZ,EAAAA,IAACyB,EAAA,CAAM,KAAMhD,EAAY,aAAcC,EACrC,SAAAsB,EAAAA,IAAC0B,EAAA,CAAa,KAAK,QAAQ,MAAM,cAAc,YAAY,kCACzD,SAAA1B,EAAAA,IAAC2B,EAAA,CACC,SAAU,MAAOC,GAAS,CACxB,MAAMvC,EAAU,YAAa,CAAE,OAAQ,OAAQ,KAAAuC,EAAM,EACrDlD,EAAc,EAAK,EACnBO,EAAA,CACF,EACA,SAAU,IAAMP,EAAc,EAAK,CAAA,CAAA,EAEvC,CAAA,CACF,CAAA,EACF,CAEJ,CAEA,SAASiD,EAAY,CACnB,SAAAE,EACA,SAAAC,CACF,EAGgB,CACd,KAAM,CAACC,EAAMC,CAAO,EAAIxD,EAAAA,SAA8B,UAAU,EAC1D,CAACyD,EAAOC,CAAQ,EAAI1D,EAAAA,SAAiB,EAAE,EACvC,CAAC2D,EAAMC,CAAO,EAAI5D,EAAAA,SAAkB,EAAK,EACzC,CAACG,EAAOC,CAAQ,EAAIJ,EAAAA,SAAwB,IAAI,EAEtD,OACEsB,EAAAA,KAACC,GAAM,IAAK,EAAG,MAAO,CAAE,QAAS,kBAC/B,SAAA,CAAAD,EAAAA,KAACI,EAAA,CAAO,IAAK,EAAG,KAAK,UACnB,SAAA,CAAAF,EAAAA,IAAC,SAAA,CAAO,KAAK,SAAS,KAAK,MAAM,gBAAe+B,IAAS,WAAY,QAAS,IAAMC,EAAQ,UAAU,EAAG,cAAY,4BACnH,MAAO,CAAE,QAAS,gCAAiC,aAAc,mBAAoB,OAAQ,0BAA2B,WAAYD,IAAS,WAAa,qBAAuB,mBAAoB,MAAOA,IAAS,WAAa,gBAAkB,kBAAmB,SAAU,eAAgB,OAAQ,SAAA,EAAa,SAAA,aAAA,CAAA,EAGxT/B,EAAAA,IAAC,SAAA,CAAO,KAAK,SAAS,KAAK,MAAM,gBAAe+B,IAAS,OAAQ,QAAS,IAAMC,EAAQ,MAAM,EAAG,cAAY,wBAC3G,MAAO,CAAE,QAAS,gCAAiC,aAAc,mBAAoB,OAAQ,0BAA2B,WAAYD,IAAS,OAAS,qBAAuB,mBAAoB,MAAOA,IAAS,OAAS,gBAAkB,kBAAmB,SAAU,eAAgB,OAAQ,SAAA,EAAa,SAAA,YAAA,CAAA,CAEhT,EACF,EACAjC,EAAAA,KAAC,QAAA,CAAM,MAAO,CAAE,QAAS,OAAQ,cAAe,SAAU,IAAK,gBAAA,EAC7D,SAAA,CAAAE,EAAAA,IAAC,OAAA,CAAK,MAAO,CAAE,SAAU,eAAgB,MAAO,iBAAA,EAC7C,SAAA+B,IAAS,WAAa,oCAAsC,oCAAA,CAC/D,EACA/B,EAAAA,IAACqC,EAAA,CACC,MAAAJ,EACA,SAAWK,GAAMJ,EAAUI,EAAE,OAA4B,KAAK,EAC9D,YAAaP,IAAS,WAAa,gBAAkB,mBACrD,cAAY,mBAAA,CAAA,CACd,EACF,EACCpD,IAAU,MACTqB,EAAAA,IAAC,OAAA,CAAK,KAAK,QAAQ,MAAO,CAAE,MAAO,gBAAiB,SAAU,cAAA,EAAmB,SAAArB,EAAM,EAEzFmB,EAAAA,KAACI,EAAA,CAAO,QAAQ,MAAM,IAAK,EACzB,SAAA,CAAAF,MAACG,EAAA,CAAO,QAAQ,QAAQ,QAAS2B,EAAU,SAAA,SAAM,EACjDhC,EAAAA,KAACK,EAAA,CACC,QAAQ,UACR,SAAUgC,GAAQ,CAACF,EAAM,KAAA,EACzB,cAAY,qBACZ,QAAS,SAAY,CACnBG,EAAQ,EAAI,EACZxD,EAAS,IAAI,EACb,GAAI,CACF,MAAMgD,EAAOG,IAAS,WAAa,CAAE,GAAIE,EAAM,KAAA,CAAK,EAAM,CAAE,KAAMA,EAAM,MAAK,EAC7E,MAAMJ,EAASD,CAAI,CACrB,OAAStC,EAAK,CACZV,GAASU,aAAeC,EAAaD,EAAI,QAAgC,CAC3E,QAAA,CACE8C,EAAQ,EAAK,CACf,CACF,EAEA,SAAA,CAAApC,EAAAA,IAACuC,EAAA,CAAO,KAAM,GAAI,cAAW,GAAC,EAAE,IAAEJ,EAAO,cAAgB,SAAA,CAAA,CAAA,CAC3D,CAAA,CACF,CAAA,EACF,CAEJ","x_google_ignoreList":[0]}
@@ -1,4 +1,4 @@
1
- import{r as d,j as t}from"./cmdk-C3F6LD6N.js";import{d as N,u as F,a as U,S as x,I as g,B as h,h as v,y as L,b as A,i as k,F as b}from"./main-BURAlktW.js";import{V}from"./ViewHeader-C-t1U2cQ.js";import{C as $,b as R}from"./Card-BtsmkhJa.js";import{E as q}from"./EmptyState-DjKtY1Qi.js";import{R as H}from"./refresh-cw-DwlP59en.js";import{R as O}from"./rotate-ccw-DMTASfAn.js";import{T as P}from"./trash-2-D6qePV_q.js";/**
1
+ import{r as d,j as t}from"./cmdk-C3F6LD6N.js";import{d as N,u as F,a as U,S as x,I as g,B as h,h as v,y as L,b as A,i as k,F as b}from"./main-BRmJZcHt.js";import{V}from"./ViewHeader-BsnaspKw.js";import{C as $,b as R}from"./Card-Clkvh43Q.js";import{E as q}from"./EmptyState-ccT__JZG.js";import{R as H}from"./refresh-cw-KGm5eQgv.js";import{R as O}from"./rotate-ccw-D5fkDRgk.js";import{T as P}from"./trash-2-B_Y6HrfN.js";/**
2
2
  * @license lucide-react v0.460.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.