@polderlabs/bizar 8.1.0 → 10.0.5

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 (546) hide show
  1. package/bizar-dash/BROWSER_VERIFICATION.md +190 -0
  2. package/bizar-dash/CHANGELOG.md +452 -0
  3. package/bizar-dash/CONTROL_SURFACES.md +157 -0
  4. package/bizar-dash/SETTINGS_AUDIT.md +225 -0
  5. package/bizar-dash/dist/assets/ActivityFeed-DbZT1TnN.js +11 -0
  6. package/bizar-dash/dist/assets/ActivityFeed-DbZT1TnN.js.map +1 -0
  7. package/bizar-dash/dist/assets/ActivityView-DfrBu-ED.js +7 -0
  8. package/bizar-dash/dist/assets/ActivityView-DfrBu-ED.js.map +1 -0
  9. package/bizar-dash/dist/assets/AdminView-DSbzp67e.js +11 -0
  10. package/bizar-dash/dist/assets/AdminView-DSbzp67e.js.map +1 -0
  11. package/bizar-dash/dist/assets/AgentsView-BaR-e4UO.js +13 -0
  12. package/bizar-dash/dist/assets/AgentsView-BaR-e4UO.js.map +1 -0
  13. package/bizar-dash/dist/assets/ArtifactsView-Dddh5NWn.js +6 -0
  14. package/bizar-dash/dist/assets/ArtifactsView-Dddh5NWn.js.map +1 -0
  15. package/bizar-dash/dist/assets/AuthView-CcTxahxz.js +16 -0
  16. package/bizar-dash/dist/assets/AuthView-CcTxahxz.js.map +1 -0
  17. package/bizar-dash/dist/assets/BackgroundJobsView-DxiSs69H.js +1 -0
  18. package/bizar-dash/dist/assets/BackgroundJobsView-DxiSs69H.js.map +1 -0
  19. package/bizar-dash/dist/assets/BackupView-BPS8REBD.js +1 -0
  20. package/bizar-dash/dist/assets/BackupView-BPS8REBD.js.map +1 -0
  21. package/bizar-dash/dist/assets/Banner-Bx1hIUM9.js +1 -0
  22. package/bizar-dash/dist/assets/Banner-Bx1hIUM9.js.map +1 -0
  23. package/bizar-dash/dist/assets/{Card-BzJeYR2D.js → Card-ZAdgpn3-.js} +1 -1
  24. package/bizar-dash/dist/assets/{Card-BzJeYR2D.js.map → Card-ZAdgpn3-.js.map} +1 -1
  25. package/bizar-dash/dist/assets/ChatView-CM_mrwom.js +9 -0
  26. package/bizar-dash/dist/assets/ChatView-CM_mrwom.js.map +1 -0
  27. package/bizar-dash/dist/assets/{Chip-CN2bvm7a.js → Chip-k5K9DYAf.js} +1 -1
  28. package/bizar-dash/dist/assets/{Chip-CN2bvm7a.js.map → Chip-k5K9DYAf.js.map} +1 -1
  29. package/bizar-dash/dist/assets/ClaudeSessionsView-Dq40JNVC.js +1 -0
  30. package/bizar-dash/dist/assets/ClaudeSessionsView-Dq40JNVC.js.map +1 -0
  31. package/bizar-dash/dist/assets/ClipboardView-B-TwPtaC.js +1 -0
  32. package/bizar-dash/dist/assets/ClipboardView-B-TwPtaC.js.map +1 -0
  33. package/bizar-dash/dist/assets/ConfigView-C_eZMscY.js +1 -0
  34. package/bizar-dash/dist/assets/ConfigView-C_eZMscY.js.map +1 -0
  35. package/bizar-dash/dist/assets/DiagnosticsView-Cex6UdD8.js +2 -0
  36. package/bizar-dash/dist/assets/DiagnosticsView-Cex6UdD8.js.map +1 -0
  37. package/bizar-dash/dist/assets/DialogsView-DTMRJd0K.js +6 -0
  38. package/bizar-dash/dist/assets/DialogsView-DTMRJd0K.js.map +1 -0
  39. package/bizar-dash/dist/assets/DoctorView-BTCUpzXT.js +6 -0
  40. package/bizar-dash/dist/assets/DoctorView-BTCUpzXT.js.map +1 -0
  41. package/bizar-dash/dist/assets/{EmptyState-DEiBv4-r.js → EmptyState-DQzo47a_.js} +1 -1
  42. package/bizar-dash/dist/assets/{EmptyState-DEiBv4-r.js.map → EmptyState-DQzo47a_.js.map} +1 -1
  43. package/bizar-dash/dist/assets/EnvVarsView-Dnap-pmQ.js +8 -0
  44. package/bizar-dash/dist/assets/EnvVarsView-Dnap-pmQ.js.map +1 -0
  45. package/bizar-dash/dist/assets/ErrorState-DZYn3VL_.js +6 -0
  46. package/bizar-dash/dist/assets/ErrorState-DZYn3VL_.js.map +1 -0
  47. package/bizar-dash/dist/assets/EvalView-B0YgoXpm.js +1 -0
  48. package/bizar-dash/dist/assets/EvalView-B0YgoXpm.js.map +1 -0
  49. package/bizar-dash/dist/assets/GoalsView-YEbgpx2i.js +6 -0
  50. package/bizar-dash/dist/assets/GoalsView-YEbgpx2i.js.map +1 -0
  51. package/bizar-dash/dist/assets/Grid-CN6IV8NB.js +1 -0
  52. package/bizar-dash/dist/assets/Grid-CN6IV8NB.js.map +1 -0
  53. package/bizar-dash/dist/assets/HeadroomView-C_-l8ojG.js +11 -0
  54. package/bizar-dash/dist/assets/HeadroomView-C_-l8ojG.js.map +1 -0
  55. package/bizar-dash/dist/assets/HistoryView-BICvR96Y.js +1 -0
  56. package/bizar-dash/dist/assets/HistoryView-BICvR96Y.js.map +1 -0
  57. package/bizar-dash/dist/assets/Input-BRHotaQu.js +1 -0
  58. package/bizar-dash/dist/assets/Input-BRHotaQu.js.map +1 -0
  59. package/bizar-dash/dist/assets/{KanbanCard-DZEaAiEr.js → KanbanCard-BvkJ9Xwg.js} +3 -13
  60. package/bizar-dash/dist/assets/KanbanCard-BvkJ9Xwg.js.map +1 -0
  61. package/bizar-dash/dist/assets/LibrariesView-BXjfXc-o.js +52 -0
  62. package/bizar-dash/dist/assets/LibrariesView-BXjfXc-o.js.map +1 -0
  63. package/bizar-dash/dist/assets/LightRAGView-DKfQd0lo.js +6 -0
  64. package/bizar-dash/dist/assets/LightRAGView-DKfQd0lo.js.map +1 -0
  65. package/bizar-dash/dist/assets/ListHeader-DRqP1u_I.js +1 -0
  66. package/bizar-dash/dist/assets/ListHeader-DRqP1u_I.js.map +1 -0
  67. package/bizar-dash/dist/assets/MemoryView-DouzHGXp.js +8 -0
  68. package/bizar-dash/dist/assets/MemoryView-DouzHGXp.js.map +1 -0
  69. package/bizar-dash/dist/assets/MessageBubble-CIapZ4YY.js +29 -0
  70. package/bizar-dash/dist/assets/MessageBubble-CIapZ4YY.js.map +1 -0
  71. package/bizar-dash/dist/assets/MiscView-BqxBRW9r.js +1 -0
  72. package/bizar-dash/dist/assets/MiscView-BqxBRW9r.js.map +1 -0
  73. package/bizar-dash/dist/assets/ModsView-B9apzm7l.js +6 -0
  74. package/bizar-dash/dist/assets/ModsView-B9apzm7l.js.map +1 -0
  75. package/bizar-dash/dist/assets/NotificationsView-O1BrGRRZ.js +6 -0
  76. package/bizar-dash/dist/assets/NotificationsView-O1BrGRRZ.js.map +1 -0
  77. package/bizar-dash/dist/assets/ObsidianView-0_Nc0IwJ.js +1 -0
  78. package/bizar-dash/dist/assets/ObsidianView-0_Nc0IwJ.js.map +1 -0
  79. package/bizar-dash/dist/assets/OverviewView-D6WmCxyc.js +1 -0
  80. package/bizar-dash/dist/assets/OverviewView-D6WmCxyc.js.map +1 -0
  81. package/bizar-dash/dist/assets/ProgressBar-BXqAmiA8.js +1 -0
  82. package/bizar-dash/dist/assets/ProgressBar-BXqAmiA8.js.map +1 -0
  83. package/bizar-dash/dist/assets/ProjectsView-BbHq_OF3.js +11 -0
  84. package/bizar-dash/dist/assets/ProjectsView-BbHq_OF3.js.map +1 -0
  85. package/bizar-dash/dist/assets/ProvidersView-dQOPha2i.js +11 -0
  86. package/bizar-dash/dist/assets/ProvidersView-dQOPha2i.js.map +1 -0
  87. package/bizar-dash/dist/assets/SchedulesView-DllGEgon.js +1 -0
  88. package/bizar-dash/dist/assets/SchedulesView-DllGEgon.js.map +1 -0
  89. package/bizar-dash/dist/assets/Select-xrQ0htmD.js +6 -0
  90. package/bizar-dash/dist/assets/Select-xrQ0htmD.js.map +1 -0
  91. package/bizar-dash/dist/assets/SettingsRow-BNSh_paj.js +1 -0
  92. package/bizar-dash/dist/assets/SettingsRow-BNSh_paj.js.map +1 -0
  93. package/bizar-dash/dist/assets/SettingsView-B2LyDoxB.js +18 -0
  94. package/bizar-dash/dist/assets/SettingsView-B2LyDoxB.js.map +1 -0
  95. package/bizar-dash/dist/assets/Sheet-C-djzbtS.js +1 -0
  96. package/bizar-dash/dist/assets/{Sheet-C_sIEw35.js.map → Sheet-C-djzbtS.js.map} +1 -1
  97. package/bizar-dash/dist/assets/Slider-DmOSInmR.js +1 -0
  98. package/bizar-dash/dist/assets/Slider-DmOSInmR.js.map +1 -0
  99. package/bizar-dash/dist/assets/Sparkline-fGhOoGf0.js +1 -0
  100. package/bizar-dash/dist/assets/Sparkline-fGhOoGf0.js.map +1 -0
  101. package/bizar-dash/dist/assets/Switch-D5gPfsKd.js +10 -0
  102. package/bizar-dash/dist/assets/Switch-D5gPfsKd.js.map +1 -0
  103. package/bizar-dash/dist/assets/TasksView-Dw4YtwQB.js +1 -0
  104. package/bizar-dash/dist/assets/TasksView-Dw4YtwQB.js.map +1 -0
  105. package/bizar-dash/dist/assets/{Textarea-Dk97nmjO.js → Textarea-Cv1HX9p1.js} +1 -1
  106. package/bizar-dash/dist/assets/{Textarea-Dk97nmjO.js.map → Textarea-Cv1HX9p1.js.map} +1 -1
  107. package/bizar-dash/dist/assets/UpdateView-Bj0LzpMs.js +6 -0
  108. package/bizar-dash/dist/assets/UpdateView-Bj0LzpMs.js.map +1 -0
  109. package/bizar-dash/dist/assets/UsageView-CE-23yYu.js +1 -0
  110. package/bizar-dash/dist/assets/UsageView-CE-23yYu.js.map +1 -0
  111. package/bizar-dash/dist/assets/{ViewHeader-dPd4zAyj.js → ViewHeader-2Oyjj9Yt.js} +2 -2
  112. package/bizar-dash/dist/assets/{ViewHeader-dPd4zAyj.js.map → ViewHeader-2Oyjj9Yt.js.map} +1 -1
  113. package/bizar-dash/dist/assets/VoiceView-C3S92MfP.js +1 -0
  114. package/bizar-dash/dist/assets/VoiceView-C3S92MfP.js.map +1 -0
  115. package/bizar-dash/dist/assets/{brain-BajPVibR.js → brain-B8oDQ4kM.js} +1 -1
  116. package/bizar-dash/dist/assets/{brain-BajPVibR.js.map → brain-B8oDQ4kM.js.map} +1 -1
  117. package/bizar-dash/dist/assets/{calendar-CaP_Bbgc.js → calendar-C1WTDPNZ.js} +1 -1
  118. package/bizar-dash/dist/assets/{calendar-CaP_Bbgc.js.map → calendar-C1WTDPNZ.js.map} +1 -1
  119. package/bizar-dash/dist/assets/chevron-down-DjgW4FtB.js +6 -0
  120. package/bizar-dash/dist/assets/chevron-down-DjgW4FtB.js.map +1 -0
  121. package/bizar-dash/dist/assets/circle-COwUk6Jw.js +6 -0
  122. package/bizar-dash/dist/assets/circle-COwUk6Jw.js.map +1 -0
  123. package/bizar-dash/dist/assets/circle-alert-D_fRRCnG.js +6 -0
  124. package/bizar-dash/dist/assets/circle-alert-D_fRRCnG.js.map +1 -0
  125. package/bizar-dash/dist/assets/circle-check-CYpMZPTO.js +6 -0
  126. package/bizar-dash/dist/assets/circle-check-CYpMZPTO.js.map +1 -0
  127. package/bizar-dash/dist/assets/clock-BsVbT1kp.js +6 -0
  128. package/bizar-dash/dist/assets/clock-BsVbT1kp.js.map +1 -0
  129. package/bizar-dash/dist/assets/{cmdk-BLWIhKrV.js → cmdk-DMW_3pWz.js} +3 -3
  130. package/bizar-dash/dist/assets/{cmdk-BLWIhKrV.js.map → cmdk-DMW_3pWz.js.map} +1 -1
  131. package/bizar-dash/dist/assets/{dnd-kit-DU8GZk7s.js → dnd-kit-DWBZ6HFE.js} +1 -1
  132. package/bizar-dash/dist/assets/{dnd-kit-DU8GZk7s.js.map → dnd-kit-DWBZ6HFE.js.map} +1 -1
  133. package/bizar-dash/dist/assets/download-Cct5qHWG.js +6 -0
  134. package/bizar-dash/dist/assets/download-Cct5qHWG.js.map +1 -0
  135. package/bizar-dash/dist/assets/external-link-CKZQsK9X.js +6 -0
  136. package/bizar-dash/dist/assets/external-link-CKZQsK9X.js.map +1 -0
  137. package/bizar-dash/dist/assets/file-text-DNFl94X6.js +6 -0
  138. package/bizar-dash/dist/assets/file-text-DNFl94X6.js.map +1 -0
  139. package/bizar-dash/dist/assets/git-branch-qmhKTtT0.js +6 -0
  140. package/bizar-dash/dist/assets/git-branch-qmhKTtT0.js.map +1 -0
  141. package/bizar-dash/dist/assets/{git-pull-request-CFRRwdxp.js → git-pull-request-o7G3ez_L.js} +1 -1
  142. package/bizar-dash/dist/assets/{git-pull-request-CFRRwdxp.js.map → git-pull-request-o7G3ez_L.js.map} +1 -1
  143. package/bizar-dash/dist/assets/index-CRPdftkz.js +1 -0
  144. package/bizar-dash/dist/assets/index-CRPdftkz.js.map +1 -0
  145. package/bizar-dash/dist/assets/index-VI2tohpo.js +1 -0
  146. package/bizar-dash/dist/assets/index-VI2tohpo.js.map +1 -0
  147. package/bizar-dash/dist/assets/main-zDgXFFYt.js +244 -0
  148. package/bizar-dash/dist/assets/main-zDgXFFYt.js.map +1 -0
  149. package/bizar-dash/dist/assets/pause-B_hjj388.js +6 -0
  150. package/bizar-dash/dist/assets/pause-B_hjj388.js.map +1 -0
  151. package/bizar-dash/dist/assets/pencil-BQXiRgKu.js +6 -0
  152. package/bizar-dash/dist/assets/pencil-BQXiRgKu.js.map +1 -0
  153. package/bizar-dash/dist/assets/play-DF3wgBsQ.js +6 -0
  154. package/bizar-dash/dist/assets/play-DF3wgBsQ.js.map +1 -0
  155. package/bizar-dash/dist/assets/plug-DpD127rq.js +6 -0
  156. package/bizar-dash/dist/assets/plug-DpD127rq.js.map +1 -0
  157. package/bizar-dash/dist/assets/{plus-CVH1JB04.js → plus-CbojvfqK.js} +1 -1
  158. package/bizar-dash/dist/assets/{plus-CVH1JB04.js.map → plus-CbojvfqK.js.map} +1 -1
  159. package/bizar-dash/dist/assets/power-off-EnQo8iQy.js +6 -0
  160. package/bizar-dash/dist/assets/power-off-EnQo8iQy.js.map +1 -0
  161. package/bizar-dash/dist/assets/power-uH0f5Ihr.js +6 -0
  162. package/bizar-dash/dist/assets/power-uH0f5Ihr.js.map +1 -0
  163. package/bizar-dash/dist/assets/refresh-ccw-BQ_hQs-U.js +6 -0
  164. package/bizar-dash/dist/assets/refresh-ccw-BQ_hQs-U.js.map +1 -0
  165. package/bizar-dash/dist/assets/refresh-cw-CYS8luDH.js +6 -0
  166. package/bizar-dash/dist/assets/refresh-cw-CYS8luDH.js.map +1 -0
  167. package/bizar-dash/dist/assets/rotate-ccw-CTVANG1v.js +6 -0
  168. package/bizar-dash/dist/assets/rotate-ccw-CTVANG1v.js.map +1 -0
  169. package/bizar-dash/dist/assets/rotate-cw-BSsC5XrT.js +6 -0
  170. package/bizar-dash/dist/assets/rotate-cw-BSsC5XrT.js.map +1 -0
  171. package/bizar-dash/dist/assets/save-kxSwq3AI.js +6 -0
  172. package/bizar-dash/dist/assets/save-kxSwq3AI.js.map +1 -0
  173. package/bizar-dash/dist/assets/send-DkuyD_Sf.js +6 -0
  174. package/bizar-dash/dist/assets/send-DkuyD_Sf.js.map +1 -0
  175. package/bizar-dash/dist/assets/shield-alert-COajyBNI.js +6 -0
  176. package/bizar-dash/dist/assets/shield-alert-COajyBNI.js.map +1 -0
  177. package/bizar-dash/dist/assets/{trash-2-JtYRQ79q.js → trash-2-BzH_id_0.js} +1 -1
  178. package/bizar-dash/dist/assets/{trash-2-JtYRQ79q.js.map → trash-2-BzH_id_0.js.map} +1 -1
  179. package/bizar-dash/dist/assets/trending-up-DWgBlnxO.js +6 -0
  180. package/bizar-dash/dist/assets/trending-up-DWgBlnxO.js.map +1 -0
  181. package/bizar-dash/dist/assets/{triangle-alert-Nzbrm0I2.js → triangle-alert-D3wjJjjj.js} +1 -1
  182. package/bizar-dash/dist/assets/{triangle-alert-Nzbrm0I2.js.map → triangle-alert-D3wjJjjj.js.map} +1 -1
  183. package/bizar-dash/dist/assets/upload--yQe-28C.js +6 -0
  184. package/bizar-dash/dist/assets/upload--yQe-28C.js.map +1 -0
  185. package/bizar-dash/dist/assets/zap-BVpFD6-i.js +6 -0
  186. package/bizar-dash/dist/assets/zap-BVpFD6-i.js.map +1 -0
  187. package/bizar-dash/dist/{v8.html → index.html} +2 -2
  188. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  189. package/bizar-dash/src/server/agents-store.mjs +1 -0
  190. package/bizar-dash/src/server/api.mjs +10 -0
  191. package/bizar-dash/src/server/claude-runner.mjs +5 -0
  192. package/bizar-dash/src/server/dialog-store.mjs +84 -2
  193. package/bizar-dash/src/server/memory-lightrag.mjs +14 -9
  194. package/bizar-dash/src/server/progress-parser.mjs +33 -5
  195. package/bizar-dash/src/server/progress-parser.test.mjs +24 -0
  196. package/bizar-dash/src/server/routes/admin.mjs +163 -0
  197. package/bizar-dash/src/server/routes/agents-cc.mjs +171 -24
  198. package/bizar-dash/src/server/routes/agents.mjs +20 -5
  199. package/bizar-dash/src/server/routes/claude-session-detail.mjs +38 -0
  200. package/bizar-dash/src/server/routes/dialogs.mjs +31 -0
  201. package/bizar-dash/src/server/routes/goals.mjs +117 -13
  202. package/bizar-dash/src/server/routes/overview.mjs +131 -4
  203. package/bizar-dash/src/server/routes/overview.test.mjs +65 -0
  204. package/bizar-dash/src/server/routes/providers.mjs +53 -0
  205. package/bizar-dash/src/server/routes/spawn.mjs +59 -0
  206. package/bizar-dash/src/server/routes/tasks.mjs +51 -1
  207. package/bizar-dash/src/server/server.mjs +21 -10
  208. package/bizar-dash/src/web/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  209. package/bizar-dash/src/web/v8/App.tsx +158 -8
  210. package/bizar-dash/src/web/v8/__tests__/BackgroundJobsView.test.tsx +172 -0
  211. package/bizar-dash/src/web/v8/__tests__/MemoryView.test.tsx +91 -0
  212. package/bizar-dash/src/web/v8/__tests__/NotificationsPopover.test.tsx +91 -0
  213. package/bizar-dash/src/web/v8/__tests__/SchedulesView.test.tsx +157 -0
  214. package/bizar-dash/src/web/v8/__tests__/Topbar.test.tsx +86 -0
  215. package/bizar-dash/src/web/v8/__tests__/admin-view.test.tsx +105 -0
  216. package/bizar-dash/src/web/v8/__tests__/agent-card-metrics.test.tsx +54 -0
  217. package/bizar-dash/src/web/v8/__tests__/agent-detail-tasks.test.tsx +68 -0
  218. package/bizar-dash/src/web/v8/__tests__/agent-hierarchy.test.tsx +79 -0
  219. package/bizar-dash/src/web/v8/__tests__/agents-stuck-banner.test.tsx +142 -0
  220. package/bizar-dash/src/web/v8/__tests__/artifacts-view.test.tsx +102 -0
  221. package/bizar-dash/src/web/v8/__tests__/audit-fixes.test.tsx +139 -0
  222. package/bizar-dash/src/web/v8/__tests__/auth-view.test.tsx +94 -0
  223. package/bizar-dash/src/web/v8/__tests__/changelog.test.tsx +79 -0
  224. package/bizar-dash/src/web/v8/__tests__/chat-types.test.ts +55 -0
  225. package/bizar-dash/src/web/v8/__tests__/chat-view.test.tsx +142 -0
  226. package/bizar-dash/src/web/v8/__tests__/claude-sessions-view.test.tsx +159 -0
  227. package/bizar-dash/src/web/v8/__tests__/clipboard-view.test.tsx +90 -0
  228. package/bizar-dash/src/web/v8/__tests__/config-view.test.tsx +111 -0
  229. package/bizar-dash/src/web/v8/__tests__/dialogs-view.test.tsx +81 -0
  230. package/bizar-dash/src/web/v8/__tests__/env-vars-view.test.tsx +123 -0
  231. package/bizar-dash/src/web/v8/__tests__/goals-cc-roundtrip.test.tsx +94 -0
  232. package/bizar-dash/src/web/v8/__tests__/history-view.test.tsx +96 -0
  233. package/bizar-dash/src/web/v8/__tests__/lightrag-view.test.tsx +90 -0
  234. package/bizar-dash/src/web/v8/__tests__/misc-view.test.tsx +79 -0
  235. package/bizar-dash/src/web/v8/__tests__/mods-view.test.tsx +123 -0
  236. package/bizar-dash/src/web/v8/__tests__/new-views.test.tsx +177 -0
  237. package/bizar-dash/src/web/v8/__tests__/obsidian-view.test.tsx +82 -0
  238. package/bizar-dash/src/web/v8/__tests__/overview-trends.test.tsx +87 -0
  239. package/bizar-dash/src/web/v8/__tests__/projects-view.test.tsx +134 -0
  240. package/bizar-dash/src/web/v8/__tests__/providers-view.test.tsx +100 -0
  241. package/bizar-dash/src/web/v8/__tests__/theme.test.tsx +10 -4
  242. package/bizar-dash/src/web/v8/__tests__/update-view.test.tsx +89 -0
  243. package/bizar-dash/src/web/v8/__tests__/views.test.tsx +6 -0
  244. package/bizar-dash/src/web/v8/__tests__/voice-view.test.tsx +80 -0
  245. package/bizar-dash/src/web/v8/data/types.ts +75 -2
  246. package/bizar-dash/src/web/v8/data/useWebSocket.ts +54 -1
  247. package/bizar-dash/src/web/v8/shell/Sidebar.tsx +98 -13
  248. package/bizar-dash/src/web/v8/shell/Topbar.tsx +30 -4
  249. package/bizar-dash/src/web/v8/ui/agents/AgentCard.tsx +96 -15
  250. package/bizar-dash/src/web/v8/ui/agents/AgentDetail.tsx +202 -15
  251. package/bizar-dash/src/web/v8/ui/agents/AgentLiveOutput.tsx +252 -0
  252. package/bizar-dash/src/web/v8/ui/agents/AgentStreamPanel.tsx +1 -1
  253. package/bizar-dash/src/web/v8/ui/chat/ChatDrawer.tsx +208 -0
  254. package/bizar-dash/src/web/v8/ui/chat/EventStream.tsx +83 -0
  255. package/bizar-dash/src/web/v8/ui/chat/MessageBubble.tsx +174 -0
  256. package/bizar-dash/src/web/v8/ui/data/ListHeader.tsx +94 -0
  257. package/bizar-dash/src/web/v8/ui/feedback/ErrorState.tsx +116 -0
  258. package/bizar-dash/src/web/v8/ui/feedback/NotificationsPopover.tsx +239 -0
  259. package/bizar-dash/src/web/v8/ui/goals/GoalDetail.tsx +34 -1
  260. package/bizar-dash/src/web/v8/ui/index.ts +7 -1
  261. package/bizar-dash/src/web/v8/ui/tasks/TaskDetail.tsx +313 -0
  262. package/bizar-dash/src/web/v8/views/Activity/ActivityView.tsx +465 -33
  263. package/bizar-dash/src/web/v8/views/Admin/AdminView.tsx +210 -0
  264. package/bizar-dash/src/web/v8/views/Agents/AgentHierarchy.tsx +212 -0
  265. package/bizar-dash/src/web/v8/views/Agents/AgentsView.tsx +328 -21
  266. package/bizar-dash/src/web/v8/views/Artifacts/ArtifactsView.tsx +241 -0
  267. package/bizar-dash/src/web/v8/views/Auth/AuthView.tsx +175 -0
  268. package/bizar-dash/src/web/v8/views/BackgroundJobs/BackgroundJobsView.tsx +442 -0
  269. package/bizar-dash/src/web/v8/views/Backup/BackupView.tsx +204 -0
  270. package/bizar-dash/src/web/v8/views/Chat/ChatView.tsx +356 -0
  271. package/bizar-dash/src/web/v8/views/ClaudeSessions/ClaudeSessionDetail.tsx +133 -0
  272. package/bizar-dash/src/web/v8/views/ClaudeSessions/ClaudeSessionsView.tsx +331 -0
  273. package/bizar-dash/src/web/v8/views/Clipboard/ClipboardView.tsx +210 -0
  274. package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.tsx +22 -7
  275. package/bizar-dash/src/web/v8/views/Config/ConfigView.tsx +364 -0
  276. package/bizar-dash/src/web/v8/views/Diagnostics/DiagnosticsView.tsx +160 -0
  277. package/bizar-dash/src/web/v8/views/Dialogs/DialogsView.tsx +196 -0
  278. package/bizar-dash/src/web/v8/views/Doctor/DoctorView.tsx +181 -0
  279. package/bizar-dash/src/web/v8/views/EnvVars/EnvVarsView.tsx +365 -0
  280. package/bizar-dash/src/web/v8/views/Eval/EvalView.tsx +278 -0
  281. package/bizar-dash/src/web/v8/views/Goals/GoalsView.tsx +169 -11
  282. package/bizar-dash/src/web/v8/views/Headroom/HeadroomView.tsx +201 -0
  283. package/bizar-dash/src/web/v8/views/History/HistoryView.tsx +227 -0
  284. package/bizar-dash/src/web/v8/views/Libraries/LibrariesView.tsx +13 -3
  285. package/bizar-dash/src/web/v8/views/LightRAG/LightRAGView.tsx +183 -0
  286. package/bizar-dash/src/web/v8/views/Memory/MemoryView.tsx +203 -22
  287. package/bizar-dash/src/web/v8/views/Misc/MiscView.tsx +159 -0
  288. package/bizar-dash/src/web/v8/views/Mods/ModsView.tsx +348 -0
  289. package/bizar-dash/src/web/v8/views/Notifications/NotificationsView.tsx +178 -0
  290. package/bizar-dash/src/web/v8/views/Obsidian/ObsidianView.tsx +193 -0
  291. package/bizar-dash/src/web/v8/views/Overview/OverviewView.tsx +114 -11
  292. package/bizar-dash/src/web/v8/views/Projects/ProjectsView.tsx +253 -0
  293. package/bizar-dash/src/web/v8/views/Providers/ProvidersView.tsx +371 -0
  294. package/bizar-dash/src/web/v8/views/Router.tsx +135 -0
  295. package/bizar-dash/src/web/v8/views/Schedules/SchedulesView.tsx +427 -0
  296. package/bizar-dash/src/web/v8/views/Settings/SettingsView.tsx +343 -34
  297. package/bizar-dash/src/web/v8/views/Tasks/TasksView.tsx +177 -12
  298. package/bizar-dash/src/web/v8/views/Update/UpdateView.tsx +270 -0
  299. package/bizar-dash/src/web/v8/views/Usage/UsageView.tsx +210 -0
  300. package/bizar-dash/src/web/v8/views/Voice/VoiceView.tsx +192 -0
  301. package/bizar-dash/tests/goals-decompose.test.mjs +5 -3
  302. package/bizar-dash/tests/tasks-patch-routes.test.mjs +194 -0
  303. package/bizar-dash/vite.config.ts +11 -3
  304. package/cli/__tests__/esm-no-require.test.mjs +97 -0
  305. package/cli/commands/tailscale.mjs +1 -3
  306. package/cli/commands/voice.mjs +2 -2
  307. package/cli/service-env.mjs +4 -5
  308. package/package.json +12 -3
  309. package/packages/sdk/dist/agent-registry.d.ts +134 -0
  310. package/packages/sdk/dist/agent-registry.js +228 -0
  311. package/packages/sdk/dist/consensus/byzantine.d.ts +159 -0
  312. package/packages/sdk/dist/consensus/byzantine.js +507 -0
  313. package/packages/sdk/dist/consensus/index.d.ts +60 -0
  314. package/packages/sdk/dist/consensus/index.js +76 -0
  315. package/packages/sdk/dist/consensus/queen.d.ts +86 -0
  316. package/packages/sdk/dist/consensus/queen.js +158 -0
  317. package/packages/sdk/dist/consensus/types.d.ts +155 -0
  318. package/packages/sdk/dist/consensus/types.js +29 -0
  319. package/packages/sdk/dist/dangerous-patterns.d.ts +27 -0
  320. package/packages/sdk/dist/dangerous-patterns.js +107 -0
  321. package/packages/sdk/dist/federation/audit.d.ts +71 -0
  322. package/packages/sdk/dist/federation/audit.js +133 -0
  323. package/packages/sdk/dist/federation/budget.d.ts +111 -0
  324. package/packages/sdk/dist/federation/budget.js +227 -0
  325. package/packages/sdk/dist/federation/envelope.d.ts +83 -0
  326. package/packages/sdk/dist/federation/envelope.js +92 -0
  327. package/packages/sdk/dist/federation/hmac.d.ts +61 -0
  328. package/packages/sdk/dist/federation/hmac.js +120 -0
  329. package/packages/sdk/dist/federation/index.d.ts +108 -0
  330. package/packages/sdk/dist/federation/index.js +275 -0
  331. package/packages/sdk/dist/federation/pii.d.ts +72 -0
  332. package/packages/sdk/dist/federation/pii.js +178 -0
  333. package/packages/sdk/dist/federation/policy.d.ts +50 -0
  334. package/packages/sdk/dist/federation/policy.js +76 -0
  335. package/packages/sdk/dist/federation/trust.d.ts +80 -0
  336. package/packages/sdk/dist/federation/trust.js +126 -0
  337. package/packages/sdk/dist/fingerprint.d.ts +18 -0
  338. package/packages/sdk/dist/fingerprint.js +0 -0
  339. package/packages/sdk/dist/index.d.ts +25 -0
  340. package/packages/sdk/dist/index.js +25 -0
  341. package/packages/sdk/dist/mcp/bin.d.ts +16 -0
  342. package/packages/sdk/dist/mcp/bin.js +46 -0
  343. package/packages/sdk/dist/mcp/server.d.ts +105 -0
  344. package/packages/sdk/dist/mcp/server.js +682 -0
  345. package/packages/sdk/dist/memory/index.d.ts +43 -0
  346. package/packages/sdk/dist/memory/index.js +159 -0
  347. package/packages/sdk/dist/router/codemod-intent.d.ts +68 -0
  348. package/packages/sdk/{src/router/codemod-intent.ts → dist/router/codemod-intent.js} +53 -66
  349. package/packages/sdk/dist/router/index.d.ts +100 -0
  350. package/packages/sdk/dist/router/index.js +149 -0
  351. package/packages/sdk/dist/router/memory-distillation.d.ts +58 -0
  352. package/packages/sdk/dist/router/memory-distillation.js +195 -0
  353. package/packages/sdk/dist/router/model-router.d.ts +83 -0
  354. package/packages/sdk/dist/router/model-router.js +207 -0
  355. package/packages/sdk/dist/router/q-learning-router.d.ts +85 -0
  356. package/packages/sdk/dist/router/q-learning-router.js +273 -0
  357. package/packages/sdk/dist/swarm-topology.d.ts +87 -0
  358. package/packages/sdk/dist/swarm-topology.js +219 -0
  359. package/packages/sdk/dist/version.d.ts +5 -0
  360. package/packages/sdk/dist/version.js +5 -0
  361. package/packages/sdk/package.json +1 -1
  362. package/plugins/bizar/LICENSE +21 -0
  363. package/plugins/bizar/dist/index.d.ts +25 -0
  364. package/plugins/bizar/dist/index.js +32 -0
  365. package/plugins/bizar/package.json +18 -0
  366. package/.claude/CLAUDE.md +0 -15
  367. package/.claude/agents/_shared/AGENT_BASELINE.md +0 -168
  368. package/.claude/agents/_shared/CLAUDE_TOOLS.md +0 -412
  369. package/.claude/agents/_shared/SKILLS.md +0 -109
  370. package/.claude/agents/agent-browser.md +0 -80
  371. package/.claude/agents/baldr.md +0 -49
  372. package/.claude/agents/forseti.md +0 -51
  373. package/.claude/agents/frigg.md +0 -42
  374. package/.claude/agents/heimdall.md +0 -33
  375. package/.claude/agents/hermod.md +0 -53
  376. package/.claude/agents/mimir.md +0 -49
  377. package/.claude/agents/odin.md +0 -287
  378. package/.claude/agents/quick.md +0 -34
  379. package/.claude/agents/semble-search.md +0 -50
  380. package/.claude/agents/thor.md +0 -53
  381. package/.claude/agents/tyr.md +0 -56
  382. package/.claude/agents/vidarr.md +0 -54
  383. package/.claude/agents/vor.md +0 -53
  384. package/.claude/commands/audit.md +0 -25
  385. package/.claude/commands/bizar.md +0 -22
  386. package/.claude/commands/explain.md +0 -17
  387. package/.claude/commands/goal.md +0 -98
  388. package/.claude/commands/init.md +0 -29
  389. package/.claude/commands/learn.md +0 -44
  390. package/.claude/commands/plan.md +0 -35
  391. package/.claude/commands/plow-through.md +0 -50
  392. package/.claude/commands/pr-review.md +0 -49
  393. package/.claude/commands/setup-provider.md +0 -96
  394. package/.claude/commands/tailscale-serve.md +0 -100
  395. package/.claude/commands/team.md +0 -132
  396. package/.claude/commands/test.md +0 -62
  397. package/.claude/commands/validate.md +0 -68
  398. package/.claude/commands/visual-plan.md +0 -24
  399. package/.claude/hooks/README.md +0 -92
  400. package/.claude/hooks/posttooluse-editwrite.mjs +0 -91
  401. package/.claude/hooks/pretooluse-bash.mjs +0 -81
  402. package/.claude/hooks/pretooluse-editwrite.mjs +0 -139
  403. package/.claude/hooks/sessionend-recall.mjs +0 -74
  404. package/.claude/hooks/sessionstart-prime.mjs +0 -80
  405. package/.claude/hooks/userpromptsubmit-tag.mjs +0 -80
  406. package/.claude/hooks/worker-suggest.mjs +0 -110
  407. package/.claude/settings.json +0 -125
  408. package/.claude/settings.local.json +0 -7
  409. package/.claude/skills/9router/SKILL.md +0 -80
  410. package/.claude/skills/9router-chat/SKILL.md +0 -73
  411. package/.claude/skills/9router-embeddings/SKILL.md +0 -69
  412. package/.claude/skills/9router-image/SKILL.md +0 -86
  413. package/.claude/skills/9router-stt/SKILL.md +0 -79
  414. package/.claude/skills/9router-tts/SKILL.md +0 -80
  415. package/.claude/skills/9router-web-fetch/SKILL.md +0 -99
  416. package/.claude/skills/9router-web-search/SKILL.md +0 -91
  417. package/.claude/skills/bizar/README.md +0 -9
  418. package/.claude/skills/bizar/SKILL.md +0 -450
  419. package/.claude/skills/cpp-coding-standards/README.md +0 -28
  420. package/.claude/skills/cpp-coding-standards/SKILL.md +0 -634
  421. package/.claude/skills/cpp-coding-standards/references/concurrency.md +0 -320
  422. package/.claude/skills/cpp-coding-standards/references/error-handling.md +0 -229
  423. package/.claude/skills/cpp-coding-standards/references/memory-safety.md +0 -216
  424. package/.claude/skills/cpp-coding-standards/references/modern-idioms.md +0 -282
  425. package/.claude/skills/cpp-coding-standards/references/review-checklist.md +0 -96
  426. package/.claude/skills/cpp-testing/README.md +0 -28
  427. package/.claude/skills/cpp-testing/SKILL.md +0 -304
  428. package/.claude/skills/cpp-testing/references/coverage.md +0 -370
  429. package/.claude/skills/cpp-testing/references/framework-compare.md +0 -175
  430. package/.claude/skills/cpp-testing/references/host-test-for-embedded.md +0 -499
  431. package/.claude/skills/cpp-testing/references/mocking.md +0 -364
  432. package/.claude/skills/cpp-testing/references/tdd-workflow.md +0 -308
  433. package/.claude/skills/cubesandbox/SKILL.md +0 -148
  434. package/.claude/skills/embedded-esp-idf/README.md +0 -41
  435. package/.claude/skills/embedded-esp-idf/SKILL.md +0 -439
  436. package/.claude/skills/embedded-esp-idf/references/freertos-patterns.md +0 -214
  437. package/.claude/skills/embedded-esp-idf/references/host-tests.md +0 -164
  438. package/.claude/skills/embedded-esp-idf/references/idf-py-commands.md +0 -157
  439. package/.claude/skills/embedded-esp-idf/references/kconfig.md +0 -159
  440. package/.claude/skills/embedded-esp-idf/references/logging-discipline.md +0 -118
  441. package/.claude/skills/embedded-esp-idf/references/memory-and-iram.md +0 -137
  442. package/.claude/skills/embedded-esp-idf/references/nvs.md +0 -121
  443. package/.claude/skills/embedded-esp-idf/references/packed-structs.md +0 -192
  444. package/.claude/skills/embedded-esp-idf/scripts/idf_env.sh +0 -47
  445. package/.claude/skills/embedded-esp-idf/scripts/size_check.sh +0 -77
  446. package/.claude/skills/glyph/SKILL.md +0 -163
  447. package/.claude/skills/harness-engineering/SKILL.md +0 -143
  448. package/.claude/skills/lightrag/SKILL.md +0 -81
  449. package/.claude/skills/memory-protocol/SKILL.md +0 -105
  450. package/.claude/skills/obsidian/SKILL.md +0 -306
  451. package/.claude/skills/read-the-damn-docs/SKILL.md +0 -113
  452. package/.claude/skills/self-improvement/SKILL.md +0 -64
  453. package/bizar-dash/dist/assets/ActivityFeed-CqF6iSDQ.js +0 -6
  454. package/bizar-dash/dist/assets/ActivityFeed-CqF6iSDQ.js.map +0 -1
  455. package/bizar-dash/dist/assets/ActivityView-qdhDjRtL.js +0 -1
  456. package/bizar-dash/dist/assets/ActivityView-qdhDjRtL.js.map +0 -1
  457. package/bizar-dash/dist/assets/AgentsView-BwXkOayl.js +0 -28
  458. package/bizar-dash/dist/assets/AgentsView-BwXkOayl.js.map +0 -1
  459. package/bizar-dash/dist/assets/Badge-BH4C3aUF.js +0 -1
  460. package/bizar-dash/dist/assets/Badge-BH4C3aUF.js.map +0 -1
  461. package/bizar-dash/dist/assets/Button-RmN1RKhE.js +0 -6
  462. package/bizar-dash/dist/assets/Button-RmN1RKhE.js.map +0 -1
  463. package/bizar-dash/dist/assets/GoalsView-CvsrzEez.js +0 -6
  464. package/bizar-dash/dist/assets/GoalsView-CvsrzEez.js.map +0 -1
  465. package/bizar-dash/dist/assets/KanbanCard-DZEaAiEr.js.map +0 -1
  466. package/bizar-dash/dist/assets/LibrariesView-CPgKGPpM.js +0 -67
  467. package/bizar-dash/dist/assets/LibrariesView-CPgKGPpM.js.map +0 -1
  468. package/bizar-dash/dist/assets/MemoryView-Bbez5pMN.js +0 -13
  469. package/bizar-dash/dist/assets/MemoryView-Bbez5pMN.js.map +0 -1
  470. package/bizar-dash/dist/assets/OverviewView-BDegBWgg.js +0 -1
  471. package/bizar-dash/dist/assets/OverviewView-BDegBWgg.js.map +0 -1
  472. package/bizar-dash/dist/assets/Select-xwxbK8Ed.js +0 -16
  473. package/bizar-dash/dist/assets/Select-xwxbK8Ed.js.map +0 -1
  474. package/bizar-dash/dist/assets/SettingsRow-CppSgkT_.js +0 -10
  475. package/bizar-dash/dist/assets/SettingsRow-CppSgkT_.js.map +0 -1
  476. package/bizar-dash/dist/assets/SettingsView-DUc2meHV.js +0 -43
  477. package/bizar-dash/dist/assets/SettingsView-DUc2meHV.js.map +0 -1
  478. package/bizar-dash/dist/assets/Sheet-C_sIEw35.js +0 -1
  479. package/bizar-dash/dist/assets/Sparkline-D664vGWW.js +0 -1
  480. package/bizar-dash/dist/assets/Sparkline-D664vGWW.js.map +0 -1
  481. package/bizar-dash/dist/assets/StatTile-BRsUIA6P.js +0 -16
  482. package/bizar-dash/dist/assets/StatTile-BRsUIA6P.js.map +0 -1
  483. package/bizar-dash/dist/assets/TasksView-DVyX5-DY.js +0 -1
  484. package/bizar-dash/dist/assets/TasksView-DVyX5-DY.js.map +0 -1
  485. package/bizar-dash/dist/assets/index-AL3OLUfz.js +0 -1
  486. package/bizar-dash/dist/assets/index-AL3OLUfz.js.map +0 -1
  487. package/bizar-dash/dist/assets/main-LxX9zTRk.js +0 -109
  488. package/bizar-dash/dist/assets/main-LxX9zTRk.js.map +0 -1
  489. package/bizar-dash/dist/assets/terminal-B2sSd5t7.js +0 -11
  490. package/bizar-dash/dist/assets/terminal-B2sSd5t7.js.map +0 -1
  491. package/bizar-dash/dist/assets/useFetch-CoVWwbml.js +0 -1
  492. package/bizar-dash/dist/assets/useFetch-CoVWwbml.js.map +0 -1
  493. package/bizar-dash/dist/assets/useWebSocket-CVIQB8yG.js +0 -1
  494. package/bizar-dash/dist/assets/useWebSocket-CVIQB8yG.js.map +0 -1
  495. package/bizar-dash/dist/assets/wrench-B7go551L.js +0 -6
  496. package/bizar-dash/dist/assets/wrench-B7go551L.js.map +0 -1
  497. package/bizar-dash/src/web/v8/views/Tasks/CommandPalettePlaceholder.tsx +0 -106
  498. package/bizar-dash/src/web/v8/views/Tasks/TasksKanbanPlaceholder.tsx +0 -62
  499. package/packages/sdk/ARCHITECTURE.md +0 -70
  500. package/packages/sdk/README.md +0 -80
  501. package/packages/sdk/src/agent-registry.ts +0 -304
  502. package/packages/sdk/src/consensus/byzantine.ts +0 -587
  503. package/packages/sdk/src/consensus/index.ts +0 -147
  504. package/packages/sdk/src/consensus/queen.ts +0 -173
  505. package/packages/sdk/src/consensus/types.ts +0 -199
  506. package/packages/sdk/src/dangerous-patterns.ts +0 -127
  507. package/packages/sdk/src/federation/audit.ts +0 -156
  508. package/packages/sdk/src/federation/budget.ts +0 -269
  509. package/packages/sdk/src/federation/envelope.ts +0 -144
  510. package/packages/sdk/src/federation/hmac.ts +0 -160
  511. package/packages/sdk/src/federation/index.ts +0 -443
  512. package/packages/sdk/src/federation/pii.ts +0 -241
  513. package/packages/sdk/src/federation/policy.ts +0 -112
  514. package/packages/sdk/src/federation/trust.ts +0 -146
  515. package/packages/sdk/src/fingerprint.ts +0 -0
  516. package/packages/sdk/src/index.ts +0 -114
  517. package/packages/sdk/src/mcp/bin.ts +0 -51
  518. package/packages/sdk/src/mcp/server.ts +0 -848
  519. package/packages/sdk/src/memory/index.ts +0 -160
  520. package/packages/sdk/src/router/index.ts +0 -247
  521. package/packages/sdk/src/router/memory-distillation-shim.mjs +0 -18
  522. package/packages/sdk/src/router/memory-distillation.ts +0 -249
  523. package/packages/sdk/src/router/model-router.ts +0 -235
  524. package/packages/sdk/src/router/q-learning-router.ts +0 -304
  525. package/packages/sdk/src/swarm-topology.ts +0 -279
  526. package/packages/sdk/src/version.ts +0 -4
  527. package/packages/sdk/tests/agent-registry.test.ts +0 -285
  528. package/packages/sdk/tests/consensus.test.ts +0 -376
  529. package/packages/sdk/tests/federation/audit.test.ts +0 -164
  530. package/packages/sdk/tests/federation/budget.test.ts +0 -189
  531. package/packages/sdk/tests/federation/envelope.test.ts +0 -120
  532. package/packages/sdk/tests/federation/hmac.test.ts +0 -194
  533. package/packages/sdk/tests/federation/orchestrator.test.ts +0 -176
  534. package/packages/sdk/tests/federation/pii.test.ts +0 -106
  535. package/packages/sdk/tests/federation/policy.test.ts +0 -140
  536. package/packages/sdk/tests/federation/trust.test.ts +0 -124
  537. package/packages/sdk/tests/mcp-tools.test.ts +0 -204
  538. package/packages/sdk/tests/memory-distillation.test.mjs +0 -186
  539. package/packages/sdk/tests/model-router.test.mjs +0 -108
  540. package/packages/sdk/tests/q-learning-router.test.mjs +0 -100
  541. package/packages/sdk/tests/router-orchestrator.test.mjs +0 -172
  542. package/packages/sdk/tests/router.test.mjs +0 -91
  543. package/packages/sdk/tests/sdk.test.mjs +0 -172
  544. package/packages/sdk/tests/swarm-topology.test.ts +0 -258
  545. package/packages/sdk/tsconfig.json +0 -25
  546. /package/bizar-dash/src/web/{v8.html → index.html} +0 -0
@@ -1,71 +1,503 @@
1
1
  import { useCallback, useMemo, useState } from 'react';
2
- import { GitMerge, GitPullRequest, AlertTriangle, CheckCircle2, Bot, Wrench, Activity as ActivityIcon, type LucideIcon } from 'lucide-react';
2
+ import {
3
+ GitMerge,
4
+ GitPullRequest,
5
+ AlertTriangle,
6
+ CheckCircle2,
7
+ Bot,
8
+ Wrench,
9
+ Activity as ActivityIcon,
10
+ Layers,
11
+ Target,
12
+ Settings as SettingsIcon,
13
+ Cpu,
14
+ Filter,
15
+ Clock,
16
+ Circle,
17
+ type LucideIcon,
18
+ } from 'lucide-react';
3
19
  import { Stack } from '../../ui/primitives/Stack.js';
20
+ import { Inline } from '../../ui/primitives/Inline.js';
21
+ import { Grid } from '../../ui/primitives/Grid.js';
4
22
  import { ViewHeader } from '../../ui/data/ViewHeader.js';
5
- import { ActivityFeed, type ActivityItem } from '../../ui/activity/ActivityFeed.js';
23
+ import { ListHeader } from '../../ui/data/ListHeader.js';
24
+ import { Sparkline } from '../../ui/data/Sparkline.js';
25
+ import { Badge } from '../../ui/data/Badge.js';
26
+ import { Card, CardBody } from '../../ui/data/Card.js';
6
27
  import { Skeleton } from '../../ui/feedback/Skeleton.js';
28
+ import { ErrorState } from '../../ui/feedback/ErrorState.js';
29
+ import { Button } from '../../ui/controls/Button.js';
30
+ import { Switch } from '../../ui/controls/Switch.js';
31
+ import { Slider } from '../../ui/controls/Slider.js';
32
+ import { cx } from '../../ui/utils/cx.js';
33
+ import { fetchJson, FetchError } from '../../data/fetcher.js';
7
34
  import { useFetch } from '../../data/useFetch.js';
8
35
  import { useWsMessage } from '../../data/useWebSocket.js';
9
36
  import type { ActivityEvent } from '../../data/types.js';
10
37
 
11
38
  /**
12
- * ActivityView — Sprint S10. Full activity stream from `/api/activity`.
13
- * Live-tail via `activity:new` WS messages.
39
+ * ActivityView — Sprint S15 visual changelog.
40
+ *
41
+ * Renders an explicit day-grouped changelog ("Today", "Yesterday", "Mar 14")
42
+ * with source badges and per-event highlights. Diff payloads (`meta.diff`)
43
+ * render as expanded preview blocks. Filter chips narrow by source. The
44
+ * topbar lives above the list so screen-magnifier users see context.
14
45
  */
15
46
 
16
- const ICON_MAP: Record<string, LucideIcon> = {
17
- 'git.merge': GitMerge,
18
- 'git.pull-request': GitPullRequest,
19
- 'task.completed': CheckCircle2,
20
- 'task.failed': AlertTriangle,
21
- 'agent.run': Bot,
22
- 'agent.tool': Wrench,
23
- 'agent.message': ActivityIcon,
47
+ type Source = 'task' | 'agent' | 'goal' | 'settings' | 'system' | 'git' | 'all';
48
+
49
+ const SOURCE_META: Record<Exclude<Source, 'all'>, { label: string; icon: LucideIcon; tone: 'neutral' | 'info' | 'accent' | 'success' | 'warning' | 'danger' }> = {
50
+ task: { label: 'Tasks', icon: Layers, tone: 'neutral' },
51
+ agent: { label: 'Agents', icon: Bot, tone: 'info' },
52
+ goal: { label: 'Goals', icon: Target, tone: 'accent' },
53
+ settings: { label: 'Settings', icon: SettingsIcon, tone: 'neutral' },
54
+ system: { label: 'System', icon: Cpu, tone: 'warning' },
55
+ git: { label: 'Git', icon: GitMerge, tone: 'neutral' },
56
+ };
57
+
58
+ const EVENT_TONE_MAP: Record<string, { icon: LucideIcon; tone: 'neutral' | 'info' | 'success' | 'warning' | 'danger'; source: Source }> = {
59
+ 'git.merge': { icon: GitMerge, tone: 'success', source: 'git' },
60
+ 'git.pull-request': { icon: GitPullRequest, tone: 'info', source: 'git' },
61
+ 'task.completed': { icon: CheckCircle2, tone: 'success', source: 'task' },
62
+ 'task.failed': { icon: AlertTriangle, tone: 'danger', source: 'task' },
63
+ 'task.created': { icon: Layers, tone: 'info', source: 'task' },
64
+ 'task.moved': { icon: Layers, tone: 'neutral', source: 'task' },
65
+ 'agent.run': { icon: Bot, tone: 'info', source: 'agent' },
66
+ 'agent.tool': { icon: Wrench, tone: 'neutral', source: 'agent' },
67
+ 'agent.killed': { icon: AlertTriangle, tone: 'warning', source: 'agent' },
68
+ 'goal.created': { icon: Target, tone: 'info', source: 'goal' },
69
+ 'goal.status': { icon: Target, tone: 'info', source: 'goal' },
70
+ 'goal.decomposed': { icon: Target, tone: 'success', source: 'goal' },
71
+ 'settings.changed': { icon: SettingsIcon, tone: 'neutral', source: 'settings' },
72
+ 'system.error': { icon: AlertTriangle, tone: 'danger', source: 'system' },
73
+ 'system.note': { icon: ActivityIcon, tone: 'neutral', source: 'system' },
74
+ 'agent.message': { icon: ActivityIcon, tone: 'info', source: 'agent' },
24
75
  };
25
76
 
26
- function iconFor(key: string | undefined): JSX.Element {
27
- const Icon = ICON_MAP[key || ''] || ActivityIcon;
28
- return <Icon size={14} aria-hidden="true" />;
77
+ function inferSource(e: ActivityEvent): Source {
78
+ const hint = (e.kind || e.iconKey || '').toLowerCase();
79
+ if (hint.startsWith('task')) return 'task';
80
+ if (hint.startsWith('agent')) return 'agent';
81
+ if (hint.startsWith('goal')) return 'goal';
82
+ if (hint.startsWith('settings')) return 'settings';
83
+ if (hint.startsWith('git')) return 'git';
84
+ if (hint.startsWith('system')) return 'system';
85
+ if (e.title && /goal/i.test(e.title)) return 'goal';
86
+ if (e.title && /(agent|claude|cc)/i.test(e.title)) return 'agent';
87
+ return 'system';
29
88
  }
30
89
 
31
- function toItem(e: ActivityEvent, idx: number): ActivityItem {
32
- return {
33
- id: e.id || `${e.ts || idx}-${idx}`,
34
- icon: iconFor(e.iconKey || e.kind),
35
- title: e.title || e.description || e.kind || 'event',
36
- description: e.description,
37
- meta: e.meta || (e.ts ? new Date(e.ts).toLocaleString() : ''),
38
- tone: e.tone,
39
- };
90
+ function eventVisual(e: ActivityEvent): { icon: LucideIcon; tone: 'neutral' | 'info' | 'success' | 'warning' | 'danger'; source: Source } {
91
+ const m = EVENT_TONE_MAP[e.kind || e.iconKey || ''] || EVENT_TONE_MAP['system.note'];
92
+ const inferred = inferSource(e);
93
+ return { icon: m.icon, tone: m.tone, source: inferred };
94
+ }
95
+
96
+ function dayKey(ts: number): string {
97
+ const d = new Date(ts);
98
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
99
+ }
100
+
101
+ function dayLabel(ts: number): string {
102
+ const now = new Date();
103
+ const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
104
+ const d = new Date(ts);
105
+ const start = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
106
+ const diffDays = Math.round((today - start) / 86_400_000);
107
+ if (diffDays === 0) return 'Today';
108
+ if (diffDays === 1) return 'Yesterday';
109
+ if (diffDays < 7) return `${diffDays} days ago`;
110
+ return d.toLocaleDateString(undefined, { weekday: 'long', month: 'short', day: 'numeric' });
111
+ }
112
+
113
+ function timeShort(ts: number): string {
114
+ return new Date(ts).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
40
115
  }
41
116
 
117
+ interface DiffPayload { before?: string; after?: string; lines?: { kind: '+' | '-' | ' '; text: string }[] }
118
+
119
+ function renderDiff(meta: unknown): JSX.Element | null {
120
+ if (!meta || typeof meta !== 'object') return null;
121
+ const d = meta as DiffPayload;
122
+ if (Array.isArray(d.lines) && d.lines.length > 0) {
123
+ return (
124
+ <Box style={{ marginTop: 6, fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', background: 'var(--surface-0)', border: '1px solid var(--border)', borderRadius: 'var(--radius-sm)', padding: 8 }}>
125
+ {d.lines.slice(0, 40).map((l, i) => (
126
+ <div key={i} style={{ color: l.kind === '+' ? 'var(--success)' : l.kind === '-' ? 'var(--danger)' : 'var(--fg-muted)', whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
127
+ <span style={{ display: 'inline-block', width: 12 }}>{l.kind === ' ' ? '' : l.kind}</span>
128
+ {l.text}
129
+ </div>
130
+ ))}
131
+ </Box>
132
+ );
133
+ }
134
+ if (d.before !== undefined || d.after !== undefined) {
135
+ return (
136
+ <Box style={{ marginTop: 6, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
137
+ {d.before !== undefined && (
138
+ <Box style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', background: 'color-mix(in oklch, var(--danger) 12%, var(--surface-0))', border: '1px solid color-mix(in oklch, var(--danger) 30%, var(--border))', borderRadius: 'var(--radius-sm)', padding: 8, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
139
+ <strong style={{ color: 'var(--danger)' }}>before</strong>
140
+ <div>{String(d.before)}</div>
141
+ </Box>
142
+ )}
143
+ {d.after !== undefined && (
144
+ <Box style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', background: 'color-mix(in oklch, var(--success) 12%, var(--surface-0))', border: '1px solid color-mix(in oklch, var(--success) 30%, var(--border))', borderRadius: 'var(--radius-sm)', padding: 8, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
145
+ <strong style={{ color: 'var(--success)' }}>after</strong>
146
+ <div>{String(d.after)}</div>
147
+ </Box>
148
+ )}
149
+ </Box>
150
+ );
151
+ }
152
+ return null;
153
+ }
154
+
155
+ function Box(props: { children?: React.ReactNode; style?: React.CSSProperties; className?: string }): JSX.Element {
156
+ return <div className={cx('v8-cl-box', props.className)} style={props.style}>{props.children}</div>;
157
+ }
158
+
159
+ interface ExtendedEvent extends ActivityEvent { __source?: Source }
160
+
42
161
  export function ActivityView(): JSX.Element {
43
162
  const events = useFetch<{ events?: ActivityEvent[] }>('/api/activity?limit=200');
44
163
  const [live, setLive] = useState<ActivityEvent[]>([]);
164
+ const [source, setSource] = useState<Source>('all');
165
+ const [autoRefresh, setAutoRefresh] = useState<boolean>(true);
166
+ const [compact, setCompact] = useState<boolean>(false);
167
+ const [maxDays, setMaxDays] = useState<number>(14);
168
+ const [exportError, setExportError] = useState<string | null>(null);
169
+ const [search, setSearch] = useState<string>('');
45
170
 
46
171
  const onEvent = useCallback((msg: { event?: ActivityEvent } & Record<string, unknown>) => {
172
+ if (!autoRefresh) return;
47
173
  const ev = msg.event;
48
174
  if (!ev) return;
49
- setLive((prev) => [ev, ...prev].slice(0, 200));
50
- }, []);
175
+ setLive((prev) => [ev, ...prev].slice(0, 500));
176
+ }, [autoRefresh]);
51
177
  useWsMessage('activity:new', onEvent);
52
178
 
53
- const items = useMemo<ActivityItem[]>(() => {
54
- const merged = [...live, ...(events.data?.events || [])];
55
- return merged.map(toItem);
179
+ const merged = useMemo<ExtendedEvent[]>(() => {
180
+ return [...live, ...(events.data?.events || [])];
56
181
  }, [live, events.data]);
57
182
 
183
+ const filtered = useMemo<ExtendedEvent[]>(() => {
184
+ let list = source === 'all' ? merged : merged.filter((e) => inferSource(e) === source);
185
+ if (search.trim()) {
186
+ const needle = search.trim().toLowerCase();
187
+ list = list.filter((e) => {
188
+ const hay = [
189
+ e.title || '',
190
+ e.description || '',
191
+ e.kind || '',
192
+ e.agent || '',
193
+ e.actor || '',
194
+ ].join(' ').toLowerCase();
195
+ return hay.includes(needle);
196
+ });
197
+ }
198
+ return list;
199
+ }, [merged, source, search]);
200
+
201
+ // Time-windowed set (older events clipped).
202
+ const cutoff = Date.now() - maxDays * 86_400_000;
203
+ const windowed = useMemo<ExtendedEvent[]>(
204
+ () => filtered.filter((e) => (e.ts || 0) >= cutoff || e.ts === undefined),
205
+ [filtered, cutoff],
206
+ );
207
+
208
+ const grouped = useMemo<{ key: string; label: string; events: ExtendedEvent[] }[]>(() => {
209
+ const map = new Map<string, ExtendedEvent[]>();
210
+ for (const e of windowed) {
211
+ const ts = e.ts || Date.now();
212
+ const k = dayKey(ts);
213
+ if (!map.has(k)) map.set(k, []);
214
+ map.get(k)!.push(e);
215
+ }
216
+ const out: { key: string; label: string; events: ExtendedEvent[] }[] = [];
217
+ for (const [k, evs] of map) {
218
+ const first = evs.find((x) => x.ts);
219
+ const ts = first?.ts ?? Date.now();
220
+ out.push({ key: k, label: dayLabel(ts), events: evs });
221
+ }
222
+ return out.sort((a, b) => (a.key < b.key ? 1 : -1));
223
+ }, [windowed]);
224
+
225
+ const counts = useMemo(() => {
226
+ const acc: Record<Source, number> = { all: 0, task: 0, agent: 0, goal: 0, settings: 0, system: 0, git: 0 };
227
+ for (const e of merged) {
228
+ const s = inferSource(e);
229
+ acc.all += 1;
230
+ acc[s] += 1;
231
+ }
232
+ return acc;
233
+ }, [merged]);
234
+
235
+ const sparklineData = useMemo<number[]>(() => {
236
+ // Chronological order (grouped is desc), so reverse to oldest-first.
237
+ return [...grouped].reverse().map((g) => g.events.length);
238
+ }, [grouped]);
239
+
240
+ const exportNdjson = async (): Promise<void> => {
241
+ setExportError(null);
242
+ try {
243
+ const res = await fetchJson<{ events?: ActivityEvent[] }>('/api/activity?limit=10000');
244
+ const text = (res.events || []).map((e) => JSON.stringify(e)).join('\n');
245
+ const blob = new Blob([text], { type: 'application/x-ndjson' });
246
+ const url = URL.createObjectURL(blob);
247
+ const a = document.createElement('a');
248
+ a.href = url;
249
+ a.download = `bizar-activity-${new Date().toISOString().slice(0, 10)}.ndjson`;
250
+ document.body.appendChild(a);
251
+ a.click();
252
+ a.remove();
253
+ URL.revokeObjectURL(url);
254
+ } catch (err) {
255
+ setExportError(err instanceof FetchError ? err.message : (err as Error).message);
256
+ }
257
+ };
258
+
58
259
  return (
59
- <Stack gap={5}>
260
+ <Stack gap={5} data-testid="activity-view">
60
261
  <ViewHeader
61
262
  title="Activity"
62
- description="Full event history across the harness."
263
+ description="Day-grouped changelog across tasks, agents, goals, settings, and git."
264
+ actions={
265
+ <Inline align="center" gap={2}>
266
+ <input
267
+ type="search"
268
+ placeholder="Search…"
269
+ value={search}
270
+ onChange={(e) => setSearch(e.target.value)}
271
+ aria-label="Search activity"
272
+ style={{
273
+ height: 28,
274
+ padding: '0 var(--space-2)',
275
+ border: '1px solid var(--border)',
276
+ borderRadius: 'var(--radius-sm)',
277
+ background: 'var(--surface-0)',
278
+ color: 'var(--fg)',
279
+ fontFamily: 'var(--font-sans)',
280
+ fontSize: 'var(--fs-12)',
281
+ width: 200,
282
+ outline: 'none',
283
+ }}
284
+ />
285
+ <Inline align="center" gap={1}>
286
+ <Circle
287
+ size={8}
288
+ aria-hidden
289
+ style={{ color: autoRefresh ? 'var(--success)' : 'var(--fg-muted)' }}
290
+ fill="currentColor"
291
+ />
292
+ <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>
293
+ {autoRefresh ? 'Live' : 'Paused'}
294
+ </span>
295
+ <Button variant="ghost" onClick={() => setAutoRefresh((v) => !v)} aria-label={autoRefresh ? 'Pause stream' : 'Resume stream'}>
296
+ {autoRefresh ? 'Pause' : 'Resume'}
297
+ </Button>
298
+ </Inline>
299
+ <Button variant="secondary" onClick={() => { void exportNdjson(); }}>
300
+ <Filter size={12} aria-hidden /> Export NDJSON
301
+ </Button>
302
+ </Inline>
303
+ }
63
304
  />
64
- {events.loading && items.length === 0 ? (
305
+ <ListHeader
306
+ title="Feed"
307
+ count={windowed.length}
308
+ sparkline={sparklineData.length >= 2 ? <Sparkline data={sparklineData} width={120} height={28} /> : undefined}
309
+ description={`${counts.task} task · ${counts.agent} agent · ${counts.goal} goal`}
310
+ testid="activity-list-header"
311
+ />
312
+
313
+ {exportError !== null && (
314
+ <div role="alert" style={{ padding: 'var(--space-3)', background: 'color-mix(in oklch, var(--danger) 12%, var(--surface-0))', border: '1px solid var(--danger)', borderRadius: 'var(--radius-md)', fontSize: 'var(--fs-12)' }}>
315
+ {exportError}
316
+ </div>
317
+ )}
318
+
319
+ {/* Source filter chips */}
320
+ <Inline align="center" gap={2} wrap>
321
+ <FilterChip label={`All (${counts.all})`} active={source === 'all'} onClick={() => setSource('all')} icon={<ActivityIcon size={12} aria-hidden />} />
322
+ {(Object.keys(SOURCE_META) as Array<Exclude<Source, 'all'>>).map((s) => {
323
+ const meta = SOURCE_META[s];
324
+ const Icon = meta.icon;
325
+ return (
326
+ <FilterChip
327
+ key={s}
328
+ label={`${meta.label} (${counts[s]})`}
329
+ active={source === s}
330
+ onClick={() => setSource(s)}
331
+ icon={<Icon size={12} aria-hidden />}
332
+ />
333
+ );
334
+ })}
335
+ </Inline>
336
+
337
+ {/* Display prefs */}
338
+ <Card>
339
+ <CardBody>
340
+ <Grid cols={3} gap={4}>
341
+ <Stack gap={1}>
342
+ <label htmlFor="cl-auto" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Live tail</label>
343
+ <Inline align="center" gap={2}>
344
+ <Switch id="cl-auto" checked={autoRefresh} onCheckedChange={setAutoRefresh} />
345
+ <span style={{ fontSize: 'var(--fs-12)', color: autoRefresh ? 'var(--success)' : 'var(--fg-muted)' }}>
346
+ {autoRefresh ? 'on' : 'paused'}
347
+ </span>
348
+ </Inline>
349
+ </Stack>
350
+ <Stack gap={1}>
351
+ <label htmlFor="cl-compact" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Compact rows</label>
352
+ <Inline align="center" gap={2}>
353
+ <Switch id="cl-compact" checked={compact} onCheckedChange={setCompact} />
354
+ <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{compact ? 'compact' : 'comfortable'}</span>
355
+ </Inline>
356
+ </Stack>
357
+ <Stack gap={1}>
358
+ <label htmlFor="cl-days" style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>Look back</label>
359
+ <Inline align="center" gap={2}>
360
+ <Slider id="cl-days" value={[maxDays]} onValueChange={(v) => setMaxDays(v[0] ?? 14)} min={1} max={90} step={1} />
361
+ <code style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)' }}>{maxDays}d</code>
362
+ </Inline>
363
+ </Stack>
364
+ </Grid>
365
+ </CardBody>
366
+ </Card>
367
+
368
+ {/* Empty state */}
369
+ {!events.loading && windowed.length === 0 && (
370
+ <Card>
371
+ <CardBody>
372
+ <Stack gap={1}>
373
+ <strong>No activity matching filters.</strong>
374
+ <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-13)' }}>
375
+ Clear the source filter or extend the look-back window.
376
+ </span>
377
+ </Stack>
378
+ </CardBody>
379
+ </Card>
380
+ )}
381
+
382
+ {events.loading && windowed.length === 0 ? (
65
383
  <Skeleton style={{ height: 320 }} />
384
+ ) : events.error && windowed.length === 0 ? (
385
+ <ErrorState
386
+ block
387
+ title="Couldn't load activity"
388
+ description="The activity feed failed to fetch. Retry to refetch."
389
+ error={events.error}
390
+ onRetry={() => void events.refetch()}
391
+ testid="activity-error"
392
+ />
66
393
  ) : (
67
- <ActivityFeed items={items} />
394
+ <Stack gap={5}>
395
+ {grouped.map((group) => (
396
+ <Stack key={group.key} gap={3}>
397
+ <Inline
398
+ align="center"
399
+ gap={2}
400
+ style={{ position: 'sticky', top: 0, padding: 'var(--space-2) var(--space-3)', background: 'color-mix(in oklch, var(--surface-0) 88%, transparent)', backdropFilter: 'blur(8px)', borderRadius: 'var(--radius-md)', border: '1px solid var(--border)', zIndex: 1 }}
401
+ >
402
+ <h2 style={{ margin: 0, fontSize: 'var(--fs-16)', fontWeight: 600 }}>{group.label}</h2>
403
+ <Badge tone="neutral">{group.events.length}</Badge>
404
+ <Clock size={12} aria-hidden style={{ color: 'var(--fg-muted)' }} />
405
+ <span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>
406
+ {group.events.filter((e) => e.ts === undefined).length > 0
407
+ ? 'live + historical'
408
+ : 'historical only'}
409
+ </span>
410
+ </Inline>
411
+
412
+ <Stack gap={1}>
413
+ {group.events.map((e, i) => {
414
+ const v = eventVisual(e);
415
+ const SourceIcon = SOURCE_META[v.source as Exclude<Source, 'all'>]?.icon || Cpu;
416
+ const ts = e.ts ?? Date.now();
417
+ return (
418
+ <Box
419
+ key={`${e.id ?? `${ts}-${i}`}`}
420
+ style={{
421
+ display: 'grid',
422
+ gridTemplateColumns: 'auto 1fr auto',
423
+ gap: 12,
424
+ padding: compact ? '6px 10px' : 'var(--space-3) var(--space-4)',
425
+ background: 'var(--surface-1)',
426
+ border: '1px solid var(--border)',
427
+ borderRadius: 'var(--radius-md)',
428
+ alignItems: 'center',
429
+ }}
430
+ >
431
+ {/* Icon column */}
432
+ <Box
433
+ style={{
434
+ width: 32,
435
+ height: 32,
436
+ display: 'inline-flex',
437
+ alignItems: 'center',
438
+ justifyContent: 'center',
439
+ borderRadius: 'var(--radius-pill)',
440
+ background: `color-mix(in oklch, var(--${v.tone === 'neutral' ? 'fg-muted' : v.tone}) 18%, var(--surface-0))`,
441
+ color: `var(--${v.tone === 'neutral' ? 'fg-muted' : v.tone})`,
442
+ }}
443
+ >
444
+ <v.icon size={14} aria-hidden />
445
+ </Box>
446
+ {/* Body */}
447
+ <Stack gap={1}>
448
+ <Inline align="center" gap={2}>
449
+ <strong style={{ fontSize: 'var(--fs-14)' }}>{e.title ?? e.description ?? e.kind ?? 'event'}</strong>
450
+ <Badge tone={SOURCE_META[v.source as Exclude<Source, 'all'>]?.tone ?? 'neutral'}>
451
+ <Inline align="center" gap={1}><SourceIcon size={10} aria-hidden /> {SOURCE_META[v.source as Exclude<Source, 'all'>]?.label ?? v.source}</Inline>
452
+ </Badge>
453
+ {e.kind && <Badge tone="neutral">{e.kind}</Badge>}
454
+ </Inline>
455
+ {e.description && e.description !== e.title && (
456
+ <span style={{ color: 'var(--fg-muted)', fontSize: 'var(--fs-13)' }}>{e.description}</span>
457
+ )}
458
+ {renderDiff(e.meta)}
459
+ </Stack>
460
+ {/* Meta column */}
461
+ <Stack align="end" gap={1}>
462
+ <code style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{timeShort(ts)}</code>
463
+ {typeof e.actor === 'string' && (
464
+ <Inline align="center" gap={1}><Circle size={8} aria-hidden style={{ color: 'var(--accent)' }} /><span style={{ fontSize: 'var(--fs-12)', color: 'var(--fg-muted)' }}>{e.actor}</span></Inline>
465
+ )}
466
+ </Stack>
467
+ </Box>
468
+ );
469
+ })}
470
+ </Stack>
471
+ </Stack>
472
+ ))}
473
+ </Stack>
68
474
  )}
69
475
  </Stack>
70
476
  );
477
+ }
478
+
479
+ function FilterChip({ label, active, onClick, icon }: { label: string; active: boolean; onClick: () => void; icon?: React.ReactNode }): JSX.Element {
480
+ return (
481
+ <button
482
+ type="button"
483
+ onClick={onClick}
484
+ aria-pressed={active}
485
+ style={{
486
+ display: 'inline-flex',
487
+ alignItems: 'center',
488
+ gap: 6,
489
+ padding: '4px 10px',
490
+ borderRadius: 'var(--radius-pill)',
491
+ border: `1px solid ${active ? 'var(--accent)' : 'var(--border)'}`,
492
+ background: active ? 'color-mix(in oklch, var(--accent) 14%, var(--surface-1))' : 'var(--surface-1)',
493
+ color: active ? 'var(--accent)' : 'var(--fg)',
494
+ fontSize: 'var(--fs-12)',
495
+ cursor: 'pointer',
496
+ fontWeight: active ? 600 : 500,
497
+ }}
498
+ >
499
+ {icon}
500
+ {label}
501
+ </button>
502
+ );
71
503
  }