@polderlabs/bizar 7.0.4 → 8.1.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 (627) hide show
  1. package/.claude/agents/agent-browser.md +1 -1
  2. package/.claude/agents/baldr.md +1 -1
  3. package/.claude/agents/forseti.md +1 -1
  4. package/.claude/agents/frigg.md +1 -1
  5. package/.claude/agents/heimdall.md +1 -1
  6. package/.claude/agents/hermod.md +1 -1
  7. package/.claude/agents/mimir.md +1 -1
  8. package/.claude/agents/odin.md +1 -1
  9. package/.claude/agents/quick.md +1 -1
  10. package/.claude/agents/semble-search.md +1 -1
  11. package/.claude/agents/thor.md +1 -1
  12. package/.claude/agents/tyr.md +1 -1
  13. package/.claude/agents/vidarr.md +1 -1
  14. package/.claude/agents/vor.md +1 -1
  15. package/.claude/commands/goal.md +98 -0
  16. package/.claude/settings.local.json +7 -0
  17. package/bizar-dash/DESIGN.md +729 -969
  18. package/bizar-dash/GLYPH.md +418 -0
  19. package/bizar-dash/PLAN.md +1135 -0
  20. package/bizar-dash/dist/assets/ActivityFeed-CqF6iSDQ.js +6 -0
  21. package/bizar-dash/dist/assets/ActivityFeed-CqF6iSDQ.js.map +1 -0
  22. package/bizar-dash/dist/assets/ActivityView-qdhDjRtL.js +1 -0
  23. package/bizar-dash/dist/assets/ActivityView-qdhDjRtL.js.map +1 -0
  24. package/bizar-dash/dist/assets/AgentsView-BwXkOayl.js +28 -0
  25. package/bizar-dash/dist/assets/AgentsView-BwXkOayl.js.map +1 -0
  26. package/bizar-dash/dist/assets/Badge-BH4C3aUF.js +1 -0
  27. package/bizar-dash/dist/assets/Badge-BH4C3aUF.js.map +1 -0
  28. package/bizar-dash/dist/assets/Button-RmN1RKhE.js +6 -0
  29. package/bizar-dash/dist/assets/Button-RmN1RKhE.js.map +1 -0
  30. package/bizar-dash/dist/assets/Card-BzJeYR2D.js +1 -0
  31. package/bizar-dash/dist/assets/Card-BzJeYR2D.js.map +1 -0
  32. package/bizar-dash/dist/assets/Chip-CN2bvm7a.js +1 -0
  33. package/bizar-dash/dist/assets/Chip-CN2bvm7a.js.map +1 -0
  34. package/bizar-dash/dist/assets/EmptyState-DEiBv4-r.js +1 -0
  35. package/bizar-dash/dist/assets/EmptyState-DEiBv4-r.js.map +1 -0
  36. package/bizar-dash/dist/assets/GoalsView-CvsrzEez.js +6 -0
  37. package/bizar-dash/dist/assets/GoalsView-CvsrzEez.js.map +1 -0
  38. package/bizar-dash/dist/assets/KanbanCard-DZEaAiEr.js +21 -0
  39. package/bizar-dash/dist/assets/KanbanCard-DZEaAiEr.js.map +1 -0
  40. package/bizar-dash/dist/assets/LibrariesView-CPgKGPpM.js +67 -0
  41. package/bizar-dash/dist/assets/LibrariesView-CPgKGPpM.js.map +1 -0
  42. package/bizar-dash/dist/assets/MemoryView-Bbez5pMN.js +13 -0
  43. package/bizar-dash/dist/assets/MemoryView-Bbez5pMN.js.map +1 -0
  44. package/bizar-dash/dist/assets/OverviewView-BDegBWgg.js +1 -0
  45. package/bizar-dash/dist/assets/OverviewView-BDegBWgg.js.map +1 -0
  46. package/bizar-dash/dist/assets/Select-xwxbK8Ed.js +16 -0
  47. package/bizar-dash/dist/assets/Select-xwxbK8Ed.js.map +1 -0
  48. package/bizar-dash/dist/assets/SettingsRow-CppSgkT_.js +10 -0
  49. package/bizar-dash/dist/assets/SettingsRow-CppSgkT_.js.map +1 -0
  50. package/bizar-dash/dist/assets/SettingsView-DUc2meHV.js +43 -0
  51. package/bizar-dash/dist/assets/SettingsView-DUc2meHV.js.map +1 -0
  52. package/bizar-dash/dist/assets/Sheet-C_sIEw35.js +1 -0
  53. package/bizar-dash/dist/assets/Sheet-C_sIEw35.js.map +1 -0
  54. package/bizar-dash/dist/assets/Sparkline-D664vGWW.js +1 -0
  55. package/bizar-dash/dist/assets/Sparkline-D664vGWW.js.map +1 -0
  56. package/bizar-dash/dist/assets/StatTile-BRsUIA6P.js +16 -0
  57. package/bizar-dash/dist/assets/StatTile-BRsUIA6P.js.map +1 -0
  58. package/bizar-dash/dist/assets/TasksView-DVyX5-DY.js +1 -0
  59. package/bizar-dash/dist/assets/TasksView-DVyX5-DY.js.map +1 -0
  60. package/bizar-dash/dist/assets/Textarea-Dk97nmjO.js +1 -0
  61. package/bizar-dash/dist/assets/Textarea-Dk97nmjO.js.map +1 -0
  62. package/bizar-dash/dist/assets/ViewHeader-dPd4zAyj.js +6 -0
  63. package/bizar-dash/dist/assets/ViewHeader-dPd4zAyj.js.map +1 -0
  64. package/bizar-dash/dist/assets/brain-BajPVibR.js +6 -0
  65. package/bizar-dash/dist/assets/brain-BajPVibR.js.map +1 -0
  66. package/bizar-dash/dist/assets/calendar-CaP_Bbgc.js +6 -0
  67. package/bizar-dash/dist/assets/calendar-CaP_Bbgc.js.map +1 -0
  68. package/bizar-dash/dist/assets/cmdk-BLWIhKrV.js +80 -0
  69. package/bizar-dash/dist/assets/cmdk-BLWIhKrV.js.map +1 -0
  70. package/bizar-dash/dist/assets/dnd-kit-DU8GZk7s.js +5 -0
  71. package/bizar-dash/dist/assets/dnd-kit-DU8GZk7s.js.map +1 -0
  72. package/bizar-dash/dist/assets/git-pull-request-CFRRwdxp.js +11 -0
  73. package/bizar-dash/dist/assets/git-pull-request-CFRRwdxp.js.map +1 -0
  74. package/bizar-dash/dist/assets/index-AL3OLUfz.js +1 -0
  75. package/bizar-dash/dist/assets/index-AL3OLUfz.js.map +1 -0
  76. package/bizar-dash/dist/assets/main-CcQfRfIJ.css +1 -0
  77. package/bizar-dash/dist/assets/main-LxX9zTRk.js +109 -0
  78. package/bizar-dash/dist/assets/main-LxX9zTRk.js.map +1 -0
  79. package/bizar-dash/dist/assets/plus-CVH1JB04.js +6 -0
  80. package/bizar-dash/dist/assets/plus-CVH1JB04.js.map +1 -0
  81. package/bizar-dash/dist/assets/terminal-B2sSd5t7.js +11 -0
  82. package/bizar-dash/dist/assets/terminal-B2sSd5t7.js.map +1 -0
  83. package/bizar-dash/dist/assets/trash-2-JtYRQ79q.js +6 -0
  84. package/bizar-dash/dist/assets/trash-2-JtYRQ79q.js.map +1 -0
  85. package/bizar-dash/dist/assets/triangle-alert-Nzbrm0I2.js +6 -0
  86. package/bizar-dash/dist/assets/triangle-alert-Nzbrm0I2.js.map +1 -0
  87. package/bizar-dash/dist/assets/useFetch-CoVWwbml.js +1 -0
  88. package/bizar-dash/dist/assets/useFetch-CoVWwbml.js.map +1 -0
  89. package/bizar-dash/dist/assets/useWebSocket-CVIQB8yG.js +1 -0
  90. package/bizar-dash/dist/assets/useWebSocket-CVIQB8yG.js.map +1 -0
  91. package/bizar-dash/dist/assets/wrench-B7go551L.js +6 -0
  92. package/bizar-dash/dist/assets/wrench-B7go551L.js.map +1 -0
  93. package/bizar-dash/dist/{mobile.html → v8.html} +6 -9
  94. package/bizar-dash/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  95. package/bizar-dash/src/server/api.mjs +10 -0
  96. package/bizar-dash/src/server/bg-poller.mjs +81 -1
  97. package/bizar-dash/src/server/bg-poller.test.mjs +28 -0
  98. package/bizar-dash/src/server/progress-parser.mjs +221 -0
  99. package/bizar-dash/src/server/progress-parser.test.mjs +105 -0
  100. package/bizar-dash/src/server/routes/agents-cc.mjs +381 -0
  101. package/bizar-dash/src/server/routes/agents-cc.test.mjs +35 -0
  102. package/bizar-dash/src/server/routes/goals.mjs +307 -0
  103. package/bizar-dash/src/server/routes/tasks.mjs +11 -0
  104. package/bizar-dash/src/server/server.mjs +1 -57
  105. package/bizar-dash/src/web/v8/App.tsx +188 -0
  106. package/bizar-dash/src/web/v8/__tests__/App.test.tsx +102 -0
  107. package/bizar-dash/src/web/v8/__tests__/AppShell.test.tsx +79 -0
  108. package/bizar-dash/src/web/v8/__tests__/PageSkeleton.test.tsx +12 -0
  109. package/bizar-dash/src/web/v8/__tests__/SettingsView.test.tsx +84 -0
  110. package/bizar-dash/src/web/v8/__tests__/Sidebar.test.tsx +95 -0
  111. package/bizar-dash/src/web/v8/__tests__/activity.test.tsx +63 -0
  112. package/bizar-dash/src/web/v8/__tests__/agents.test.tsx +90 -0
  113. package/bizar-dash/src/web/v8/__tests__/control-plane.test.tsx +104 -0
  114. package/bizar-dash/src/web/v8/__tests__/controls.test.tsx +135 -0
  115. package/bizar-dash/src/web/v8/__tests__/cx.test.ts +25 -0
  116. package/bizar-dash/src/web/v8/__tests__/data.test.tsx +293 -0
  117. package/bizar-dash/src/web/v8/__tests__/feedback.test.tsx +213 -0
  118. package/bizar-dash/src/web/v8/__tests__/goals.test.tsx +105 -0
  119. package/bizar-dash/src/web/v8/__tests__/kanban.test.tsx +176 -0
  120. package/bizar-dash/src/web/v8/__tests__/libraries.test.tsx +70 -0
  121. package/bizar-dash/src/web/v8/__tests__/memory.test.tsx +60 -0
  122. package/bizar-dash/src/web/v8/__tests__/navigation.test.tsx +137 -0
  123. package/bizar-dash/src/web/v8/__tests__/settings.test.tsx +104 -0
  124. package/bizar-dash/src/web/v8/__tests__/theme.test.tsx +98 -0
  125. package/bizar-dash/src/web/v8/__tests__/useFetch.test.ts +92 -0
  126. package/bizar-dash/src/web/v8/__tests__/useWebSocket.test.ts +87 -0
  127. package/bizar-dash/src/web/v8/__tests__/views.test.tsx +182 -0
  128. package/bizar-dash/src/web/v8/data/fetcher.ts +59 -0
  129. package/bizar-dash/src/web/v8/data/types.ts +154 -0
  130. package/bizar-dash/src/web/v8/data/useFetch.ts +62 -0
  131. package/bizar-dash/src/web/v8/data/useWebSocket.ts +153 -0
  132. package/bizar-dash/src/web/v8/main.tsx +28 -0
  133. package/bizar-dash/src/web/v8/shell/AppShell.tsx +90 -0
  134. package/bizar-dash/src/web/v8/shell/PageSkeleton.tsx +29 -0
  135. package/bizar-dash/src/web/v8/shell/Sidebar.tsx +361 -0
  136. package/bizar-dash/src/web/v8/shell/StatusBar.tsx +63 -0
  137. package/bizar-dash/src/web/v8/shell/Topbar.tsx +113 -0
  138. package/bizar-dash/src/web/v8/shell/index.ts +15 -0
  139. package/bizar-dash/src/web/v8/ui/activity/ActivityFeed.tsx +137 -0
  140. package/bizar-dash/src/web/v8/ui/agents/AgentActivity.tsx +101 -0
  141. package/bizar-dash/src/web/v8/ui/agents/AgentCard.tsx +158 -0
  142. package/bizar-dash/src/web/v8/ui/agents/AgentDetail.tsx +252 -0
  143. package/bizar-dash/src/web/v8/ui/agents/AgentStreamPanel.tsx +371 -0
  144. package/bizar-dash/src/web/v8/ui/controls/Button.tsx +141 -0
  145. package/bizar-dash/src/web/v8/ui/controls/ButtonGroup.tsx +32 -0
  146. package/bizar-dash/src/web/v8/ui/controls/Checkbox.tsx +49 -0
  147. package/bizar-dash/src/web/v8/ui/controls/Field.tsx +78 -0
  148. package/bizar-dash/src/web/v8/ui/controls/Form.tsx +23 -0
  149. package/bizar-dash/src/web/v8/ui/controls/IconButton.tsx +112 -0
  150. package/bizar-dash/src/web/v8/ui/controls/Input.tsx +94 -0
  151. package/bizar-dash/src/web/v8/ui/controls/RadioGroup.tsx +74 -0
  152. package/bizar-dash/src/web/v8/ui/controls/Select.tsx +171 -0
  153. package/bizar-dash/src/web/v8/ui/controls/Slider.tsx +68 -0
  154. package/bizar-dash/src/web/v8/ui/controls/Switch.tsx +56 -0
  155. package/bizar-dash/src/web/v8/ui/controls/Textarea.tsx +64 -0
  156. package/bizar-dash/src/web/v8/ui/controls/Toggle.tsx +36 -0
  157. package/bizar-dash/src/web/v8/ui/controls/ToggleGroup.tsx +85 -0
  158. package/bizar-dash/src/web/v8/ui/data/Accordion.tsx +134 -0
  159. package/bizar-dash/src/web/v8/ui/data/Avatar.tsx +175 -0
  160. package/bizar-dash/src/web/v8/ui/data/Badge.tsx +93 -0
  161. package/bizar-dash/src/web/v8/ui/data/BarList.tsx +101 -0
  162. package/bizar-dash/src/web/v8/ui/data/Card.tsx +140 -0
  163. package/bizar-dash/src/web/v8/ui/data/Chip.tsx +96 -0
  164. package/bizar-dash/src/web/v8/ui/data/Kbd.tsx +42 -0
  165. package/bizar-dash/src/web/v8/ui/data/ProgressBar.tsx +93 -0
  166. package/bizar-dash/src/web/v8/ui/data/Sparkline.tsx +98 -0
  167. package/bizar-dash/src/web/v8/ui/data/StatTile.tsx +150 -0
  168. package/bizar-dash/src/web/v8/ui/data/Table.tsx +170 -0
  169. package/bizar-dash/src/web/v8/ui/data/Timeline.tsx +130 -0
  170. package/bizar-dash/src/web/v8/ui/data/ViewHeader.tsx +122 -0
  171. package/bizar-dash/src/web/v8/ui/feedback/Alert.tsx +95 -0
  172. package/bizar-dash/src/web/v8/ui/feedback/Banner.tsx +39 -0
  173. package/bizar-dash/src/web/v8/ui/feedback/ContextMenu.tsx +143 -0
  174. package/bizar-dash/src/web/v8/ui/feedback/Dialog.tsx +149 -0
  175. package/bizar-dash/src/web/v8/ui/feedback/Drawer.tsx +8 -0
  176. package/bizar-dash/src/web/v8/ui/feedback/DropdownMenu.tsx +231 -0
  177. package/bizar-dash/src/web/v8/ui/feedback/EmptyState.tsx +48 -0
  178. package/bizar-dash/src/web/v8/ui/feedback/Popover.tsx +56 -0
  179. package/bizar-dash/src/web/v8/ui/feedback/Sheet.tsx +103 -0
  180. package/bizar-dash/src/web/v8/ui/feedback/Skeleton.tsx +67 -0
  181. package/bizar-dash/src/web/v8/ui/feedback/Spinner.tsx +30 -0
  182. package/bizar-dash/src/web/v8/ui/feedback/Toast.tsx +66 -0
  183. package/bizar-dash/src/web/v8/ui/feedback/Tooltip.tsx +89 -0
  184. package/bizar-dash/src/web/v8/ui/goals/GoalCard.tsx +176 -0
  185. package/bizar-dash/src/web/v8/ui/goals/GoalDetail.tsx +245 -0
  186. package/bizar-dash/src/web/v8/ui/goals/KeyResult.tsx +115 -0
  187. package/bizar-dash/src/web/v8/ui/index.ts +322 -0
  188. package/bizar-dash/src/web/v8/ui/kanban/KanbanBoard.tsx +83 -0
  189. package/bizar-dash/src/web/v8/ui/kanban/KanbanCard.tsx +247 -0
  190. package/bizar-dash/src/web/v8/ui/kanban/KanbanColumn.tsx +186 -0
  191. package/bizar-dash/src/web/v8/ui/kanban/KanbanContextMenu.tsx +122 -0
  192. package/bizar-dash/src/web/v8/ui/kanban/KanbanQuickAdd.tsx +141 -0
  193. package/bizar-dash/src/web/v8/ui/libraries/LibraryGrid.tsx +30 -0
  194. package/bizar-dash/src/web/v8/ui/libraries/LibraryItem.tsx +161 -0
  195. package/bizar-dash/src/web/v8/ui/memory/MemoryVault.tsx +144 -0
  196. package/bizar-dash/src/web/v8/ui/navigation/CommandPalette.tsx +224 -0
  197. package/bizar-dash/src/web/v8/ui/navigation/NavLink.tsx +81 -0
  198. package/bizar-dash/src/web/v8/ui/navigation/Pagination.tsx +164 -0
  199. package/bizar-dash/src/web/v8/ui/navigation/Tabs.tsx +128 -0
  200. package/bizar-dash/src/web/v8/ui/navigation/useCommandPaletteHotkey.test.ts +79 -0
  201. package/bizar-dash/src/web/v8/ui/primitives/Box.tsx +144 -0
  202. package/bizar-dash/src/web/v8/ui/primitives/Center.tsx +40 -0
  203. package/bizar-dash/src/web/v8/ui/primitives/Cluster.tsx +67 -0
  204. package/bizar-dash/src/web/v8/ui/primitives/Grid.tsx +104 -0
  205. package/bizar-dash/src/web/v8/ui/primitives/Inline.tsx +77 -0
  206. package/bizar-dash/src/web/v8/ui/primitives/Portal.tsx +33 -0
  207. package/bizar-dash/src/web/v8/ui/primitives/ScrollArea.tsx +62 -0
  208. package/bizar-dash/src/web/v8/ui/primitives/Separator.tsx +42 -0
  209. package/bizar-dash/src/web/v8/ui/primitives/Stack.tsx +73 -0
  210. package/bizar-dash/src/web/v8/ui/primitives/VisuallyHidden.tsx +49 -0
  211. package/bizar-dash/src/web/v8/ui/settings/SettingsNav.tsx +91 -0
  212. package/bizar-dash/src/web/v8/ui/settings/SettingsRow.tsx +88 -0
  213. package/bizar-dash/src/web/v8/ui/settings/SettingsSection.tsx +109 -0
  214. package/bizar-dash/src/web/v8/ui/styles/globals.css +225 -0
  215. package/bizar-dash/src/web/v8/ui/styles/reset.css +57 -0
  216. package/bizar-dash/src/web/v8/ui/styles/tokens.css +217 -0
  217. package/bizar-dash/src/web/v8/ui/theme/DensityProvider.test.tsx +74 -0
  218. package/bizar-dash/src/web/v8/ui/theme/DensityProvider.tsx +66 -0
  219. package/bizar-dash/src/web/v8/ui/theme/ThemeProvider.test.tsx +86 -0
  220. package/bizar-dash/src/web/v8/ui/theme/ThemeProvider.tsx +94 -0
  221. package/bizar-dash/src/web/v8/ui/theme/ThemeToggle.tsx +88 -0
  222. package/bizar-dash/src/web/v8/ui/theme/useDensity.ts +15 -0
  223. package/bizar-dash/src/web/v8/ui/theme/useTheme.ts +16 -0
  224. package/bizar-dash/src/web/v8/ui/utils/cx.ts +19 -0
  225. package/bizar-dash/src/web/v8/views/Activity/ActivityView.tsx +71 -0
  226. package/bizar-dash/src/web/v8/views/Agents/AgentsView.tsx +172 -0
  227. package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.test.tsx +142 -0
  228. package/bizar-dash/src/web/v8/views/CommandPalette/AppCommandPalette.tsx +247 -0
  229. package/bizar-dash/src/web/v8/views/Goals/GoalsView.tsx +193 -0
  230. package/bizar-dash/src/web/v8/views/Libraries/LibrariesView.tsx +108 -0
  231. package/bizar-dash/src/web/v8/views/Memory/MemoryView.tsx +77 -0
  232. package/bizar-dash/src/web/v8/views/Overview/OverviewView.tsx +152 -0
  233. package/bizar-dash/src/web/v8/views/Router.tsx +72 -0
  234. package/bizar-dash/src/web/v8/views/Settings/SettingsView.tsx +730 -0
  235. package/bizar-dash/src/web/v8/views/Tasks/CommandPalettePlaceholder.tsx +106 -0
  236. package/bizar-dash/src/web/v8/views/Tasks/TasksKanbanPlaceholder.tsx +62 -0
  237. package/bizar-dash/src/web/v8/views/Tasks/TasksView.tsx +165 -0
  238. package/bizar-dash/src/web/v8/vite-env.d.ts +15 -0
  239. package/bizar-dash/src/web/{mobile.html → v8.html} +4 -7
  240. package/bizar-dash/tests/components/Button.test.tsx +51 -14
  241. package/bizar-dash/tests/components/Card.test.tsx +37 -20
  242. package/bizar-dash/tests/components/Dialog.test.tsx +80 -0
  243. package/bizar-dash/tests/components/Toast.test.tsx +48 -95
  244. package/bizar-dash/tests/goals-decompose.test.mjs +177 -0
  245. package/bizar-dash/tests/setup.ts +47 -0
  246. package/bizar-dash/tests/ui/primitives/VisuallyHidden.test.tsx +30 -15
  247. package/bizar-dash/vite.config.ts +41 -2
  248. package/bizar-dash/vitest.config.ts +9 -4
  249. package/cli/bin.mjs +32 -0
  250. package/cli/install.mjs +26 -1
  251. package/cli/provision-claude.mjs +86 -0
  252. package/package.json +36 -3
  253. package/scripts/run-dev.mjs +84 -0
  254. package/bizar-dash/dist/assets/EnvVarsSection-BfhAz3ax.js +0 -114
  255. package/bizar-dash/dist/assets/EnvVarsSection-BfhAz3ax.js.map +0 -1
  256. package/bizar-dash/dist/assets/MobileChat-DLWdv6tQ.js +0 -1
  257. package/bizar-dash/dist/assets/MobileChat-DLWdv6tQ.js.map +0 -1
  258. package/bizar-dash/dist/assets/MobileSettings-Bxv62uPY.js +0 -1
  259. package/bizar-dash/dist/assets/MobileSettings-Bxv62uPY.js.map +0 -1
  260. package/bizar-dash/dist/assets/Toast-ATSAmbdi.js +0 -26
  261. package/bizar-dash/dist/assets/Toast-ATSAmbdi.js.map +0 -1
  262. package/bizar-dash/dist/assets/__vite-browser-external-BIHI7g3E.js +0 -1
  263. package/bizar-dash/dist/assets/__vite-browser-external-BIHI7g3E.js.map +0 -1
  264. package/bizar-dash/dist/assets/main-CJAtrosO.css +0 -1
  265. package/bizar-dash/dist/assets/main-DKKj9dsq.js +0 -430
  266. package/bizar-dash/dist/assets/main-DKKj9dsq.js.map +0 -1
  267. package/bizar-dash/dist/assets/mobile-C_naUN91.js +0 -1
  268. package/bizar-dash/dist/assets/mobile-C_naUN91.js.map +0 -1
  269. package/bizar-dash/dist/assets/mobile-layout-BWLtwtfQ.css +0 -1
  270. package/bizar-dash/dist/assets/mobile-layout-GZ3bE8L6.js +0 -211
  271. package/bizar-dash/dist/assets/mobile-layout-GZ3bE8L6.js.map +0 -1
  272. package/bizar-dash/dist/assets/useSlashCommands-BOwD7lNb.js +0 -65
  273. package/bizar-dash/dist/assets/useSlashCommands-BOwD7lNb.js.map +0 -1
  274. package/bizar-dash/dist/index.html +0 -43
  275. package/bizar-dash/src/web/App.tsx +0 -915
  276. package/bizar-dash/src/web/MobileApp.tsx +0 -414
  277. package/bizar-dash/src/web/components/ArtifactCreateDialog.tsx +0 -95
  278. package/bizar-dash/src/web/components/ArtifactListDialog.tsx +0 -55
  279. package/bizar-dash/src/web/components/ArtifactViewer.tsx +0 -144
  280. package/bizar-dash/src/web/components/AuditDialog.tsx +0 -79
  281. package/bizar-dash/src/web/components/AutosaveField.tsx +0 -50
  282. package/bizar-dash/src/web/components/BackupRestore.tsx +0 -330
  283. package/bizar-dash/src/web/components/BgStatusBadge.tsx +0 -32
  284. package/bizar-dash/src/web/components/Button.tsx +0 -56
  285. package/bizar-dash/src/web/components/CanvasContextMenu.tsx +0 -68
  286. package/bizar-dash/src/web/components/Card.tsx +0 -40
  287. package/bizar-dash/src/web/components/CollapsibleSection.tsx +0 -72
  288. package/bizar-dash/src/web/components/CommandDialog.tsx +0 -66
  289. package/bizar-dash/src/web/components/DoctorPanel.tsx +0 -160
  290. package/bizar-dash/src/web/components/EmptyState.tsx +0 -30
  291. package/bizar-dash/src/web/components/EnvVarManager.tsx +0 -430
  292. package/bizar-dash/src/web/components/EvalDiff.tsx +0 -157
  293. package/bizar-dash/src/web/components/EvalExportButton.tsx +0 -27
  294. package/bizar-dash/src/web/components/EvalRunCard.tsx +0 -78
  295. package/bizar-dash/src/web/components/FileBrowser.tsx +0 -633
  296. package/bizar-dash/src/web/components/HeadroomSettings.tsx +0 -418
  297. package/bizar-dash/src/web/components/HeadroomStatus.tsx +0 -158
  298. package/bizar-dash/src/web/components/HelpDialog.tsx +0 -55
  299. package/bizar-dash/src/web/components/InviteDialog.tsx +0 -205
  300. package/bizar-dash/src/web/components/KillConfirmDialog.tsx +0 -88
  301. package/bizar-dash/src/web/components/MobileBottomNav.tsx +0 -38
  302. package/bizar-dash/src/web/components/MobileDrawer.tsx +0 -68
  303. package/bizar-dash/src/web/components/MobileHeader.tsx +0 -50
  304. package/bizar-dash/src/web/components/MobileLayout.tsx +0 -63
  305. package/bizar-dash/src/web/components/Modal.tsx +0 -215
  306. package/bizar-dash/src/web/components/Notifications.tsx +0 -242
  307. package/bizar-dash/src/web/components/ScheduleTemplateCard.tsx +0 -72
  308. package/bizar-dash/src/web/components/ScreenshotCapture.tsx +0 -138
  309. package/bizar-dash/src/web/components/ScreenshotOCR.tsx +0 -42
  310. package/bizar-dash/src/web/components/SearchModal.tsx +0 -227
  311. package/bizar-dash/src/web/components/SettingsNav.tsx +0 -117
  312. package/bizar-dash/src/web/components/SettingsSearch.tsx +0 -328
  313. package/bizar-dash/src/web/components/Sidebar.tsx +0 -89
  314. package/bizar-dash/src/web/components/Spinner.tsx +0 -19
  315. package/bizar-dash/src/web/components/StatusBadge.tsx +0 -56
  316. package/bizar-dash/src/web/components/Tag.tsx +0 -41
  317. package/bizar-dash/src/web/components/TailscaleSettings.tsx +0 -161
  318. package/bizar-dash/src/web/components/TaskCard.tsx +0 -69
  319. package/bizar-dash/src/web/components/TaskCreateSheet.tsx +0 -76
  320. package/bizar-dash/src/web/components/Toast.tsx +0 -150
  321. package/bizar-dash/src/web/components/Toggle.tsx +0 -31
  322. package/bizar-dash/src/web/components/Topbar.tsx +0 -455
  323. package/bizar-dash/src/web/components/UsageChart.tsx +0 -250
  324. package/bizar-dash/src/web/components/UsageTable.tsx +0 -90
  325. package/bizar-dash/src/web/components/VirtualList.tsx +0 -53
  326. package/bizar-dash/src/web/components/VisualPlanDialog.tsx +0 -58
  327. package/bizar-dash/src/web/components/VoiceNotesPanel.tsx +0 -211
  328. package/bizar-dash/src/web/components/VoiceRecorder.tsx +0 -105
  329. package/bizar-dash/src/web/components/WorkspaceSelector.tsx +0 -158
  330. package/bizar-dash/src/web/components/agents/CommunicationLog.tsx +0 -126
  331. package/bizar-dash/src/web/components/agents/DependencyGraph.tsx +0 -163
  332. package/bizar-dash/src/web/components/agents/QualityGates.tsx +0 -123
  333. package/bizar-dash/src/web/components/agents/RealTimeEventLog.tsx +0 -127
  334. package/bizar-dash/src/web/components/agents/RoutingDecisions.test.tsx +0 -148
  335. package/bizar-dash/src/web/components/agents/RoutingDecisions.tsx +0 -160
  336. package/bizar-dash/src/web/components/background/AttachButton.tsx +0 -96
  337. package/bizar-dash/src/web/components/background/TmuxAttachCard.tsx +0 -122
  338. package/bizar-dash/src/web/components/chat/AgentChip.tsx +0 -68
  339. package/bizar-dash/src/web/components/chat/AgentNode.tsx +0 -127
  340. package/bizar-dash/src/web/components/chat/AgentTree.tsx +0 -80
  341. package/bizar-dash/src/web/components/chat/ChatBubble.tsx +0 -60
  342. package/bizar-dash/src/web/components/chat/ChatComposer.tsx +0 -72
  343. package/bizar-dash/src/web/components/chat/ChatInfoPanel.tsx +0 -370
  344. package/bizar-dash/src/web/components/chat/ChatRail.tsx +0 -387
  345. package/bizar-dash/src/web/components/chat/ChatThread.tsx +0 -127
  346. package/bizar-dash/src/web/components/chat/ChatTopBar.tsx +0 -50
  347. package/bizar-dash/src/web/components/chat/Composer.tsx +0 -166
  348. package/bizar-dash/src/web/components/chat/ConfirmModal.tsx +0 -54
  349. package/bizar-dash/src/web/components/chat/EmptyState.tsx +0 -21
  350. package/bizar-dash/src/web/components/chat/FirstRunGreeting.tsx +0 -18
  351. package/bizar-dash/src/web/components/chat/FloatingComposer.tsx +0 -38
  352. package/bizar-dash/src/web/components/chat/InfoPanel.tsx +0 -184
  353. package/bizar-dash/src/web/components/chat/JumpToLatest.tsx +0 -58
  354. package/bizar-dash/src/web/components/chat/LoadingSkeleton.tsx +0 -19
  355. package/bizar-dash/src/web/components/chat/MessageBlock.tsx +0 -260
  356. package/bizar-dash/src/web/components/chat/MessageBubble.tsx +0 -60
  357. package/bizar-dash/src/web/components/chat/SessionList.tsx +0 -163
  358. package/bizar-dash/src/web/components/chat/SessionRowMenu.tsx +0 -206
  359. package/bizar-dash/src/web/components/chat/StreamingIndicator.tsx +0 -37
  360. package/bizar-dash/src/web/components/chat/SuggestionCards.tsx +0 -55
  361. package/bizar-dash/src/web/components/chat/WelcomeScreen.tsx +0 -36
  362. package/bizar-dash/src/web/components/chat/_legacy.ts +0 -30
  363. package/bizar-dash/src/web/components/chat/index.ts +0 -31
  364. package/bizar-dash/src/web/components/chat/useAutoGrowTextarea.ts +0 -18
  365. package/bizar-dash/src/web/components/chat/useChat.ts +0 -1190
  366. package/bizar-dash/src/web/components/chat/useSlashCommands.ts +0 -47
  367. package/bizar-dash/src/web/components/goals/GoalInput.tsx +0 -86
  368. package/bizar-dash/src/web/components/goals/PlanVisualization.tsx +0 -111
  369. package/bizar-dash/src/web/components/tasks/BacklogPanel.css +0 -109
  370. package/bizar-dash/src/web/components/tasks/BacklogPanel.tsx +0 -209
  371. package/bizar-dash/src/web/hooks/useAutosave.ts +0 -107
  372. package/bizar-dash/src/web/hooks/useI18n.ts +0 -13
  373. package/bizar-dash/src/web/index.html +0 -37
  374. package/bizar-dash/src/web/lib/api.ts +0 -237
  375. package/bizar-dash/src/web/lib/goapPlanner.ts +0 -614
  376. package/bizar-dash/src/web/lib/i18n.ts +0 -25
  377. package/bizar-dash/src/web/lib/logger.ts +0 -30
  378. package/bizar-dash/src/web/lib/markdown.tsx +0 -59
  379. package/bizar-dash/src/web/lib/search.ts +0 -115
  380. package/bizar-dash/src/web/lib/types.ts +0 -894
  381. package/bizar-dash/src/web/lib/utils.ts +0 -114
  382. package/bizar-dash/src/web/lib/ws.ts +0 -177
  383. package/bizar-dash/src/web/locales/en.json +0 -52
  384. package/bizar-dash/src/web/main.tsx +0 -43
  385. package/bizar-dash/src/web/mobile/MobileApp.tsx +0 -309
  386. package/bizar-dash/src/web/mobile/MobileBottomNav.tsx +0 -38
  387. package/bizar-dash/src/web/mobile/MobileChat.tsx +0 -138
  388. package/bizar-dash/src/web/mobile/MobileDoctor.tsx +0 -80
  389. package/bizar-dash/src/web/mobile/MobileEval.tsx +0 -167
  390. package/bizar-dash/src/web/mobile/MobileMemory.tsx +0 -108
  391. package/bizar-dash/src/web/mobile/MobileOverview.tsx +0 -213
  392. package/bizar-dash/src/web/mobile/MobileSettings.tsx +0 -251
  393. package/bizar-dash/src/web/mobile/MobileTasks.tsx +0 -94
  394. package/bizar-dash/src/web/mobile/MobileTopbar.tsx +0 -115
  395. package/bizar-dash/src/web/mobile/components/MobileBottomSheet.tsx +0 -182
  396. package/bizar-dash/src/web/mobile/components/MobileListItem.tsx +0 -64
  397. package/bizar-dash/src/web/mobile/components/MobileModal.tsx +0 -123
  398. package/bizar-dash/src/web/mobile/views/MobileActivity.tsx +0 -273
  399. package/bizar-dash/src/web/mobile/views/MobileAgents.tsx +0 -374
  400. package/bizar-dash/src/web/mobile/views/MobileArtifactCanvas.tsx +0 -439
  401. package/bizar-dash/src/web/mobile/views/MobileArtifacts.tsx +0 -143
  402. package/bizar-dash/src/web/mobile/views/MobileChat.tsx +0 -257
  403. package/bizar-dash/src/web/mobile/views/MobileConfig.tsx +0 -175
  404. package/bizar-dash/src/web/mobile/views/MobileHistory.tsx +0 -191
  405. package/bizar-dash/src/web/mobile/views/MobileMods.tsx +0 -149
  406. package/bizar-dash/src/web/mobile/views/MobileMore.tsx +0 -121
  407. package/bizar-dash/src/web/mobile/views/MobileNotifications.tsx +0 -137
  408. package/bizar-dash/src/web/mobile/views/MobilePlans.tsx +0 -26
  409. package/bizar-dash/src/web/mobile/views/MobileSchedules.tsx +0 -685
  410. package/bizar-dash/src/web/mobile/views/MobileSearchModal.tsx +0 -172
  411. package/bizar-dash/src/web/mobile/views/MobileSettings.tsx +0 -363
  412. package/bizar-dash/src/web/mobile/views/MobileSkills.tsx +0 -153
  413. package/bizar-dash/src/web/mobile/views/MobileTasks.tsx +0 -564
  414. package/bizar-dash/src/web/mobile/views/QrCodePanel.tsx +0 -69
  415. package/bizar-dash/src/web/mobile.tsx +0 -14
  416. package/bizar-dash/src/web/styles/agents-redesign.css +0 -311
  417. package/bizar-dash/src/web/styles/chat.css +0 -1740
  418. package/bizar-dash/src/web/styles/glyphs.css +0 -960
  419. package/bizar-dash/src/web/styles/main.css +0 -10389
  420. package/bizar-dash/src/web/styles/memory.css +0 -1177
  421. package/bizar-dash/src/web/styles/minimax-usage.css +0 -842
  422. package/bizar-dash/src/web/styles/mobile-chat.css +0 -5
  423. package/bizar-dash/src/web/styles/mobile-layout.css +0 -233
  424. package/bizar-dash/src/web/styles/mobile.css +0 -2181
  425. package/bizar-dash/src/web/styles/settings.css +0 -775
  426. package/bizar-dash/src/web/styles/skills.css +0 -302
  427. package/bizar-dash/src/web/styles/tasks-redesign.css +0 -253
  428. package/bizar-dash/src/web/styles/tasks.css +0 -605
  429. package/bizar-dash/src/web/ui/controls/Button.tsx +0 -77
  430. package/bizar-dash/src/web/ui/controls/Checkbox.tsx +0 -95
  431. package/bizar-dash/src/web/ui/controls/IconButton.tsx +0 -66
  432. package/bizar-dash/src/web/ui/controls/Kbd.tsx +0 -24
  433. package/bizar-dash/src/web/ui/controls/NumberInput.tsx +0 -77
  434. package/bizar-dash/src/web/ui/controls/RadioGroup.tsx +0 -109
  435. package/bizar-dash/src/web/ui/controls/SearchInput.tsx +0 -91
  436. package/bizar-dash/src/web/ui/controls/Select.tsx +0 -92
  437. package/bizar-dash/src/web/ui/controls/Slider.tsx +0 -70
  438. package/bizar-dash/src/web/ui/controls/TextInput.tsx +0 -67
  439. package/bizar-dash/src/web/ui/controls/Textarea.tsx +0 -56
  440. package/bizar-dash/src/web/ui/controls/Toggle.tsx +0 -79
  441. package/bizar-dash/src/web/ui/controls/controls.css +0 -476
  442. package/bizar-dash/src/web/ui/controls/index.ts +0 -35
  443. package/bizar-dash/src/web/ui/data/BarChart.tsx +0 -60
  444. package/bizar-dash/src/web/ui/data/DataTable.tsx +0 -216
  445. package/bizar-dash/src/web/ui/data/EmptyState.tsx +0 -60
  446. package/bizar-dash/src/web/ui/data/ErrorState.tsx +0 -56
  447. package/bizar-dash/src/web/ui/data/KeyValueList.tsx +0 -106
  448. package/bizar-dash/src/web/ui/data/LoadingState.tsx +0 -65
  449. package/bizar-dash/src/web/ui/data/Sparkline.tsx +0 -87
  450. package/bizar-dash/src/web/ui/data/StatTile.tsx +0 -87
  451. package/bizar-dash/src/web/ui/data/data.css +0 -540
  452. package/bizar-dash/src/web/ui/data/index.ts +0 -31
  453. package/bizar-dash/src/web/ui/feedback/Badge.tsx +0 -49
  454. package/bizar-dash/src/web/ui/feedback/Dialog.tsx +0 -209
  455. package/bizar-dash/src/web/ui/feedback/ProgressBar.tsx +0 -69
  456. package/bizar-dash/src/web/ui/feedback/StatusDot.tsx +0 -50
  457. package/bizar-dash/src/web/ui/feedback/Toast.tsx +0 -200
  458. package/bizar-dash/src/web/ui/feedback/Tooltip.tsx +0 -126
  459. package/bizar-dash/src/web/ui/feedback/feedback.css +0 -314
  460. package/bizar-dash/src/web/ui/feedback/index.ts +0 -43
  461. package/bizar-dash/src/web/ui/index.ts +0 -57
  462. package/bizar-dash/src/web/ui/layout/AppShell.tsx +0 -51
  463. package/bizar-dash/src/web/ui/layout/Breadcrumbs.tsx +0 -97
  464. package/bizar-dash/src/web/ui/layout/Panel.tsx +0 -73
  465. package/bizar-dash/src/web/ui/layout/PanelHeader.tsx +0 -39
  466. package/bizar-dash/src/web/ui/layout/Sidebar.tsx +0 -131
  467. package/bizar-dash/src/web/ui/layout/Tabs.tsx +0 -133
  468. package/bizar-dash/src/web/ui/layout/Topbar.tsx +0 -42
  469. package/bizar-dash/src/web/ui/layout/ViewHeader.tsx +0 -48
  470. package/bizar-dash/src/web/ui/layout/index.ts +0 -34
  471. package/bizar-dash/src/web/ui/layout/layout.css +0 -464
  472. package/bizar-dash/src/web/ui/navigation/CommandPalette.tsx +0 -199
  473. package/bizar-dash/src/web/ui/navigation/NavGroup.tsx +0 -95
  474. package/bizar-dash/src/web/ui/navigation/NavLink.tsx +0 -93
  475. package/bizar-dash/src/web/ui/navigation/index.ts +0 -17
  476. package/bizar-dash/src/web/ui/navigation/navigation.css +0 -343
  477. package/bizar-dash/src/web/ui/primitives/Box.tsx +0 -91
  478. package/bizar-dash/src/web/ui/primitives/Grid.tsx +0 -49
  479. package/bizar-dash/src/web/ui/primitives/Inline.tsx +0 -55
  480. package/bizar-dash/src/web/ui/primitives/Separator.tsx +0 -46
  481. package/bizar-dash/src/web/ui/primitives/Stack.tsx +0 -54
  482. package/bizar-dash/src/web/ui/primitives/VisuallyHidden.tsx +0 -26
  483. package/bizar-dash/src/web/ui/primitives/index.ts +0 -23
  484. package/bizar-dash/src/web/ui/primitives/primitives.css +0 -183
  485. package/bizar-dash/src/web/ui/styles/globals.css +0 -86
  486. package/bizar-dash/src/web/ui/styles/reset.css +0 -125
  487. package/bizar-dash/src/web/ui/styles/tokens.css +0 -208
  488. package/bizar-dash/src/web/ui/theme/ThemeProvider.tsx +0 -142
  489. package/bizar-dash/src/web/ui/theme/tokens.ts +0 -131
  490. package/bizar-dash/src/web/ui/theme/useTheme.ts +0 -22
  491. package/bizar-dash/src/web/ui/utils/cx.ts +0 -42
  492. package/bizar-dash/src/web/views/Activity.tsx +0 -1221
  493. package/bizar-dash/src/web/views/Agents.tsx +0 -964
  494. package/bizar-dash/src/web/views/Artifacts.tsx +0 -1494
  495. package/bizar-dash/src/web/views/BackgroundAgents.tsx +0 -822
  496. package/bizar-dash/src/web/views/Chat.tsx +0 -532
  497. package/bizar-dash/src/web/views/Config.tsx +0 -3
  498. package/bizar-dash/src/web/views/Doctor.tsx +0 -317
  499. package/bizar-dash/src/web/views/Eval.tsx +0 -372
  500. package/bizar-dash/src/web/views/EvalReport.tsx +0 -353
  501. package/bizar-dash/src/web/views/GoalPlanner.tsx +0 -158
  502. package/bizar-dash/src/web/views/Harness.tsx +0 -306
  503. package/bizar-dash/src/web/views/History.tsx +0 -353
  504. package/bizar-dash/src/web/views/Memory.tsx +0 -193
  505. package/bizar-dash/src/web/views/MiniMaxUsage.tsx +0 -942
  506. package/bizar-dash/src/web/views/ModView.tsx +0 -207
  507. package/bizar-dash/src/web/views/Mods.tsx +0 -706
  508. package/bizar-dash/src/web/views/Overview.tsx +0 -1343
  509. package/bizar-dash/src/web/views/Providers.tsx +0 -302
  510. package/bizar-dash/src/web/views/Schedules.tsx +0 -902
  511. package/bizar-dash/src/web/views/Settings.tsx +0 -308
  512. package/bizar-dash/src/web/views/Skills.tsx +0 -383
  513. package/bizar-dash/src/web/views/SpawnAgentModal.tsx +0 -221
  514. package/bizar-dash/src/web/views/Tasks.tsx +0 -789
  515. package/bizar-dash/src/web/views/Workspace.tsx +0 -294
  516. package/bizar-dash/src/web/views/glyphs/GlyphRenderer.tsx +0 -844
  517. package/bizar-dash/src/web/views/glyphs/components.tsx +0 -1098
  518. package/bizar-dash/src/web/views/memory/ConfigPanel.tsx +0 -426
  519. package/bizar-dash/src/web/views/memory/FromScreenshotPanel.tsx +0 -23
  520. package/bizar-dash/src/web/views/memory/GitSyncPanel.tsx +0 -220
  521. package/bizar-dash/src/web/views/memory/LightragPanel.tsx +0 -310
  522. package/bizar-dash/src/web/views/memory/MemoryGraphLegend.tsx +0 -29
  523. package/bizar-dash/src/web/views/memory/MemoryGraphPanel.tsx +0 -192
  524. package/bizar-dash/src/web/views/memory/MemoryGraphView.tsx +0 -336
  525. package/bizar-dash/src/web/views/memory/MemoryOverview.tsx +0 -367
  526. package/bizar-dash/src/web/views/memory/MemoryStatusCard.tsx +0 -160
  527. package/bizar-dash/src/web/views/memory/ObsidianPanel.tsx +0 -650
  528. package/bizar-dash/src/web/views/memory/SemanticSearchPanel.tsx +0 -197
  529. package/bizar-dash/src/web/views/memory/VaultFromClipboardPanel.tsx +0 -101
  530. package/bizar-dash/src/web/views/settings/ActivitySection.tsx +0 -205
  531. package/bizar-dash/src/web/views/settings/AgentSection.tsx +0 -305
  532. package/bizar-dash/src/web/views/settings/AuthSection.tsx +0 -159
  533. package/bizar-dash/src/web/views/settings/EnvVarsSection.tsx +0 -15
  534. package/bizar-dash/src/web/views/settings/GeneralSection.tsx +0 -128
  535. package/bizar-dash/src/web/views/settings/HeadroomSection.tsx +0 -39
  536. package/bizar-dash/src/web/views/settings/MemorySection.tsx +0 -154
  537. package/bizar-dash/src/web/views/settings/NetworkSection.tsx +0 -87
  538. package/bizar-dash/src/web/views/settings/NotificationsSection.tsx +0 -34
  539. package/bizar-dash/src/web/views/settings/SystemLlmSection.tsx +0 -81
  540. package/bizar-dash/src/web/views/settings/ThemeSection.tsx +0 -168
  541. package/bizar-dash/src/web/views/settings/UpdatesSection.tsx +0 -256
  542. package/bizar-dash/src/web/views/settings/WorkspacesSection.tsx +0 -189
  543. package/packages/sdk/.harness/agents.json +0 -17
  544. package/packages/sdk/.harness/topology.json +0 -4
  545. /package/bizar-dash/tests/{BackgroundAgents.test.tsx → v7-archive/BackgroundAgents.test.tsx} +0 -0
  546. /package/bizar-dash/tests/{a11y → v7-archive/a11y}/forms.test.tsx +0 -0
  547. /package/bizar-dash/tests/{a11y.test.tsx → v7-archive/a11y.test.tsx} +0 -0
  548. /package/bizar-dash/tests/{autosave.test.tsx → v7-archive/autosave.test.tsx} +0 -0
  549. /package/bizar-dash/tests/{backup-restore.test.tsx → v7-archive/backup-restore.test.tsx} +0 -0
  550. /package/bizar-dash/tests/{chat-composer.test.tsx → v7-archive/chat-composer.test.tsx} +0 -0
  551. /package/bizar-dash/tests/{communication-log.test.tsx → v7-archive/communication-log.test.tsx} +0 -0
  552. /package/bizar-dash/tests/{components → v7-archive/components}/Modal.test.tsx +0 -0
  553. /package/bizar-dash/tests/{components → v7-archive/components}/Spinner.test.tsx +0 -0
  554. /package/bizar-dash/tests/{components → v7-archive/components}/StatusBadge.test.tsx +0 -0
  555. /package/bizar-dash/tests/{components → v7-archive/components}/doctor-panel.test.tsx +0 -0
  556. /package/bizar-dash/tests/{components → v7-archive/components}/screenshot-ocr.test.tsx +0 -0
  557. /package/bizar-dash/tests/{components → v7-archive/components}/settings-search.test.tsx +0 -0
  558. /package/bizar-dash/tests/{components → v7-archive/components}/workspace-selector.test.tsx +0 -0
  559. /package/bizar-dash/tests/{ui → v7-archive}/controls/Button.test.tsx +0 -0
  560. /package/bizar-dash/tests/{ui → v7-archive}/controls/Checkbox.test.tsx +0 -0
  561. /package/bizar-dash/tests/{ui → v7-archive}/controls/IconButton.test.tsx +0 -0
  562. /package/bizar-dash/tests/{ui → v7-archive}/controls/Kbd.test.tsx +0 -0
  563. /package/bizar-dash/tests/{ui → v7-archive}/controls/NumberInput.test.tsx +0 -0
  564. /package/bizar-dash/tests/{ui → v7-archive}/controls/RadioGroup.test.tsx +0 -0
  565. /package/bizar-dash/tests/{ui → v7-archive}/controls/SearchInput.test.tsx +0 -0
  566. /package/bizar-dash/tests/{ui → v7-archive}/controls/Select.test.tsx +0 -0
  567. /package/bizar-dash/tests/{ui → v7-archive}/controls/Slider.test.tsx +0 -0
  568. /package/bizar-dash/tests/{ui → v7-archive}/controls/TextInput.test.tsx +0 -0
  569. /package/bizar-dash/tests/{ui → v7-archive}/controls/Textarea.test.tsx +0 -0
  570. /package/bizar-dash/tests/{ui → v7-archive}/controls/Toggle.test.tsx +0 -0
  571. /package/bizar-dash/tests/{ui → v7-archive}/data/BarChart.test.tsx +0 -0
  572. /package/bizar-dash/tests/{ui → v7-archive}/data/DataTable.test.tsx +0 -0
  573. /package/bizar-dash/tests/{ui → v7-archive}/data/EmptyState.test.tsx +0 -0
  574. /package/bizar-dash/tests/{ui → v7-archive}/data/ErrorState.test.tsx +0 -0
  575. /package/bizar-dash/tests/{ui → v7-archive}/data/KeyValueList.test.tsx +0 -0
  576. /package/bizar-dash/tests/{ui → v7-archive}/data/LoadingState.test.tsx +0 -0
  577. /package/bizar-dash/tests/{ui → v7-archive}/data/Sparkline.test.tsx +0 -0
  578. /package/bizar-dash/tests/{ui → v7-archive}/data/StatTile.test.tsx +0 -0
  579. /package/bizar-dash/tests/{dep-graph.test.tsx → v7-archive/dep-graph.test.tsx} +0 -0
  580. /package/bizar-dash/tests/{eval-web-ui.test.tsx → v7-archive/eval-web-ui.test.tsx} +0 -0
  581. /package/bizar-dash/tests/{event-log.test.tsx → v7-archive/event-log.test.tsx} +0 -0
  582. /package/bizar-dash/tests/{ui → v7-archive}/feedback/Badge.test.tsx +0 -0
  583. /package/bizar-dash/tests/{ui → v7-archive}/feedback/Dialog.test.tsx +0 -0
  584. /package/bizar-dash/tests/{ui → v7-archive}/feedback/ProgressBar.test.tsx +0 -0
  585. /package/bizar-dash/tests/{ui → v7-archive}/feedback/StatusDot.test.tsx +0 -0
  586. /package/bizar-dash/tests/{ui → v7-archive}/feedback/Toast.test.tsx +0 -0
  587. /package/bizar-dash/tests/{ui → v7-archive}/feedback/Tooltip.test.tsx +0 -0
  588. /package/bizar-dash/tests/{goal-input.test.tsx → v7-archive/goal-input.test.tsx} +0 -0
  589. /package/bizar-dash/tests/{goap-planner.test.ts → v7-archive/goap-planner.test.ts} +0 -0
  590. /package/bizar-dash/tests/{hooks → v7-archive/hooks}/useModal.test.tsx +0 -0
  591. /package/bizar-dash/tests/{hooks → v7-archive/hooks}/useToast.test.tsx +0 -0
  592. /package/bizar-dash/tests/{ui → v7-archive}/layout/AppShell.test.tsx +0 -0
  593. /package/bizar-dash/tests/{ui → v7-archive}/layout/Breadcrumbs.test.tsx +0 -0
  594. /package/bizar-dash/tests/{ui → v7-archive}/layout/Panel.test.tsx +0 -0
  595. /package/bizar-dash/tests/{ui → v7-archive}/layout/PanelHeader.test.tsx +0 -0
  596. /package/bizar-dash/tests/{ui → v7-archive}/layout/Sidebar.test.tsx +0 -0
  597. /package/bizar-dash/tests/{ui → v7-archive}/layout/Tabs.test.tsx +0 -0
  598. /package/bizar-dash/tests/{ui → v7-archive}/layout/Topbar.test.tsx +0 -0
  599. /package/bizar-dash/tests/{ui → v7-archive}/layout/ViewHeader.test.tsx +0 -0
  600. /package/bizar-dash/tests/{lib → v7-archive/lib}/i18n.test.ts +0 -0
  601. /package/bizar-dash/tests/{lib → v7-archive/lib}/search-fuzzy.test.ts +0 -0
  602. /package/bizar-dash/tests/{lib → v7-archive/lib}/utils.test.ts +0 -0
  603. /package/bizar-dash/tests/{memory-graph-view.test.tsx → v7-archive/memory-graph-view.test.tsx} +0 -0
  604. /package/bizar-dash/tests/{mobile-chat.test.tsx → v7-archive/mobile-chat.test.tsx} +0 -0
  605. /package/bizar-dash/tests/{mobile-layout.test.tsx → v7-archive/mobile-layout.test.tsx} +0 -0
  606. /package/bizar-dash/tests/{mobile-overview.test.tsx → v7-archive/mobile-overview.test.tsx} +0 -0
  607. /package/bizar-dash/tests/{mobile-settings.test.tsx → v7-archive/mobile-settings.test.tsx} +0 -0
  608. /package/bizar-dash/tests/{mobile-tasks.test.tsx → v7-archive/mobile-tasks.test.tsx} +0 -0
  609. /package/bizar-dash/tests/{ui → v7-archive}/navigation/CommandPalette.test.tsx +0 -0
  610. /package/bizar-dash/tests/{ui → v7-archive}/navigation/NavGroup.test.tsx +0 -0
  611. /package/bizar-dash/tests/{ui → v7-archive}/navigation/NavLink.test.tsx +0 -0
  612. /package/bizar-dash/tests/{quality-gates.test.tsx → v7-archive/quality-gates.test.tsx} +0 -0
  613. /package/bizar-dash/tests/{settings-layout.test.tsx → v7-archive/settings-layout.test.tsx} +0 -0
  614. /package/bizar-dash/tests/{settings-mode-wiring.test.tsx → v7-archive/settings-mode-wiring.test.tsx} +0 -0
  615. /package/bizar-dash/tests/{settings-nav.test.tsx → v7-archive/settings-nav.test.tsx} +0 -0
  616. /package/bizar-dash/tests/{ui → v7-archive/ui}/primitives/Box.test.tsx +0 -0
  617. /package/bizar-dash/tests/{ui → v7-archive/ui}/primitives/Grid.test.tsx +0 -0
  618. /package/bizar-dash/tests/{ui → v7-archive/ui}/primitives/Inline.test.tsx +0 -0
  619. /package/bizar-dash/tests/{ui → v7-archive/ui}/primitives/Separator.test.tsx +0 -0
  620. /package/bizar-dash/tests/{ui → v7-archive/ui}/primitives/Stack.test.tsx +0 -0
  621. /package/bizar-dash/tests/{views → v7-archive/views}/Agents.test.tsx +0 -0
  622. /package/bizar-dash/tests/{views → v7-archive/views}/Memory.test.tsx +0 -0
  623. /package/bizar-dash/tests/{views → v7-archive/views}/Overview.test.tsx +0 -0
  624. /package/bizar-dash/tests/{views → v7-archive/views}/Tasks.test.tsx +0 -0
  625. /package/bizar-dash/tests/{views → v7-archive/views}/sidebar.test.tsx +0 -0
  626. /package/bizar-dash/tests/{views → v7-archive/views}/topbar.test.tsx +0 -0
  627. /package/bizar-dash/tests/{voice-recorder.test.tsx → v7-archive/voice-recorder.test.tsx} +0 -0
@@ -1,1190 +0,0 @@
1
- // src/components/chat/useChat.ts — shared chat state: messages, sessions,
2
- // send, polling, SSE, session-state tracking.
3
- //
4
- // v6.3.0 — Claude Code migration. Supports two parallel message streams:
5
- // - bizar (GET /api/chat)
6
- // - claude (GET /api/claude-sessions/:id/messages + SSE)
7
- //
8
- // Changes from v4.2.5:
9
- // * Endpoint prefix changed: `/api/claude-sessions/*` → `/api/claude-sessions/*`
10
- // * SSE event type names changed to match the Claude SDK envelope
11
- // (`message.part.updated` → `delta`/`text_delta`, etc.)
12
- // * Server no longer needs the `clineErrorInfo` 503 path; the
13
- // `claudeErrorInfo` field stays for parity but the dashboard
14
- // mostly sees 502s now (claude CLI not on PATH / spawn failed).
15
- // * Optimistic send uses a stable `msg_*` ID and is deduped when
16
- // claude echoes the message back via SDK events.
17
- // * `claudeMessages` keeps server-provided IDs distinct from
18
- // optimistic IDs so the merge is unambiguous (server echo
19
- // replaces optimistic by matching messageID; otherwise both stick
20
- // around briefly until the user/session state catches up).
21
- // * `onSend` routes to `/claude-sessions/:id/send` when a
22
- // claude session is active, `/chat` otherwise. Errors surface
23
- // via toast + we always remove the optimistic placeholder.
24
- // * Sessions are managed by source:
25
- // - `bizarSessions` → local .jsonl store, POST /chat/sessions
26
- // - `claudeSessions` → Claude Code, GET /claude-sessions
27
- // The rail shows both side-by-side with a source indicator and
28
- // uses separate rename/delete endpoints per source.
29
- // * All async actions surface a single `busy: { create, send, rename, delete }`
30
- // so the rail can disable buttons properly.
31
- // * No `any` leaks — all SSE event shapes are typed via
32
- // `ClineSseEnvelope`.
33
-
34
- import { useCallback, useEffect, useRef, useState } from 'react';
35
- import type {
36
- ChatMessage,
37
- ChatResponse,
38
- ChatSession,
39
- Settings,
40
- Snapshot,
41
- } from '../../lib/types';
42
- import { api, ApiError } from '../../lib/api';
43
- import type { SessionState } from './ChatRail';
44
- import type { AgentTreeNode } from './AgentNode';
45
-
46
- export interface SessionDisplayState {
47
- /** idle / streaming / awaiting — derived from the latest SSE event. */
48
- state: SessionState;
49
- /** Number of unread (i.e. arrived while the user wasn't viewing) messages. */
50
- unread: number;
51
- /** Pinned? (cosmetic for now; pinned state lives in the parent.) */
52
- pinned: boolean;
53
- /** Sub-agent tree, if any. */
54
- tree?: { root: AgentTreeNode };
55
- }
56
-
57
- /** Per-source action busy flags. Used by rail/info-panel to disable buttons. */
58
- export interface ChatBusyState {
59
- create: boolean;
60
- send: boolean;
61
- rename: boolean;
62
- delete: boolean;
63
- }
64
-
65
- /**
66
- * Structured error envelope surfaced by `loadClineSession` when
67
- * the upstream `/api/claude-sessions/:id/messages` call fails.
68
- *
69
- * - `code` mirrors the server's `error` field (`plugin_offline`,
70
- * `directory_unknown`, `cline_error`, `bad_request`).
71
- * - `cause` is the server's structured cause (`network`, `timeout`,
72
- * `unknown`, or a raw ECONNREFUSED-style string).
73
- * - `suggestion` is the operator-friendly hint from the server
74
- * (e.g. "Run `bizar doctor` for diagnostics").
75
- * - `canRetry` is `true` whenever the failure is transient (network
76
- * error, upstream 502) — i.e. the user can fix it by trying again
77
- * after starting the plugin / waiting for cline to come back.
78
- * False for hard failures (bad_request).
79
- */
80
- export interface ClineErrorInfo {
81
- type: 'session_load_failed';
82
- code: string;
83
- message: string;
84
- cause?: string;
85
- status?: number;
86
- suggestion?: string | null;
87
- canRetry: boolean;
88
- }
89
-
90
- /** Shape of one cline SSE envelope after unwrapping. */
91
- interface ClineSseEnvelope {
92
- type: string;
93
- sessionID?: string;
94
- messageID?: string;
95
- /** Raw upstream payload (kept for forwarders that want full fidelity). */
96
- data?: unknown;
97
- }
98
-
99
- /**
100
- * The chat hook returns a stable bag of state + actions used by
101
- * both Chat.tsx (desktop) and MobileChat.tsx (mobile).
102
- *
103
- * The hook owns the lifecycle of the cline SSE stream. Callers
104
- * should never instantiate their own EventSource for the same
105
- * session — they should always go through this hook.
106
- */
107
- export function useChat(snapshot: Snapshot, settings: Settings, initialTaskId?: string | null) {
108
- // ── Bizar stream ────────────────────────────────────────────────────────────
109
- const [bizarMessages, setBizarMessages] = useState<ChatMessage[]>([]);
110
- const [sessions, setSessions] = useState<ChatSession[]>([]);
111
- const [sessionId, setSessionId] = useState('');
112
- const [loading, setLoading] = useState(true);
113
- const [busy, setBusy] = useState<ChatBusyState>({
114
- create: false,
115
- send: false,
116
- rename: false,
117
- delete: false,
118
- });
119
-
120
- // ── Cline stream ─────────────────────────────────────────────────────────
121
- const [clineSessions, setClineSessions] = useState<ChatSession[]>([]);
122
- const [clineMessages, setClineMessages] = useState<ChatMessage[]>([]);
123
- const [activeSource, setActiveSource] = useState<'bizar' | 'cline' | null>(null);
124
- const [activeClineSessionId, setActiveClineSessionId] = useState<string | null>(null);
125
- const [clineError, setClineError] = useState<string | null>(null);
126
- const [clineSuggestion, setClineSuggestion] = useState<string | null>(null);
127
- /**
128
- * Structured error info for the cline session load path. New in
129
- * v5.0.0 — `ChatInfoPanel` consumes this to render its own error
130
- * section (in addition to the chat-thread-header error already
131
- * rendered by Chat.tsx). `null` when no error.
132
- */
133
- const [clineErrorInfo, setClineErrorInfo] = useState<ClineErrorInfo | null>(null);
134
-
135
- // ── v3.22 — session-state, unread, tree per session ────────────────────────
136
- const [sessionStates, setSessionStates] = useState<Record<string, SessionDisplayState>>({});
137
- const [stickToBottom, setStickToBottom] = useState(true);
138
- const [newMessageCount, setNewMessageCount] = useState(0);
139
-
140
- // Set of messageIDs the user has already accepted (or that arrived
141
- // via SSE) — used by the cline path to dedupe optimistic + echo.
142
- const [seenClineMessages, setSeenClineMessages] = useState<Set<string>>(new Set());
143
-
144
- // Backwards-compat alias (chat.sendSession delete etc. used `pinned` historically).
145
- const [pinned, setPinned] = useState<Set<number>>(new Set());
146
-
147
- const listRef = useRef<HTMLDivElement>(null);
148
- const toastRef = useRef<
149
- | {
150
- error: (msg: string) => void;
151
- success: (msg: string) => void;
152
- info: (msg: string) => void;
153
- warning: (msg: string) => void;
154
- }
155
- | null
156
- >(null);
157
-
158
- // ── SSE lifecycle refs ──────────────────────────────────────────────────────
159
- const clineEsRef = useRef<EventSource | null>(null);
160
- const sseReconnectAttemptRef = useRef(0);
161
- const sseReconnectTimerRef = useRef<number | null>(null);
162
- // The id of the session we're CURRENTLY streaming. When the user
163
- // switches sessions, this id changes and the SSE handler short-
164
- // circuits any in-flight appends.
165
- const sseCurrentSessionIdRef = useRef<string | null>(null);
166
- // Whether the SSE connection should be auto-reconnected on error.
167
- // Set to false on explicit disconnect (session switch / unmount).
168
- const sseAutoReconnectRef = useRef(false);
169
-
170
- /** Append `msg` to `clineMessages`, replacing any prior
171
- * optimistic entry whose content matches or whose ID matches. */
172
- const appendClineMessage = useCallback((msg: ChatMessage) => {
173
- if (!msg) return;
174
- setClineMessages((cur) => {
175
- // Existing exact-ID match: skip.
176
- if (msg.id && cur.some((m) => m.id === msg.id)) return cur;
177
- // Optimistic placeholder (starts with msg_) with the same role
178
- // and content: replace it. This is how cline's echo of our
179
- // own message gets deduplicated against the optimistic copy.
180
- const idx = cur.findIndex(
181
- (m) =>
182
- typeof m.id === 'string' &&
183
- m.id.startsWith('msg_') &&
184
- m.role === msg.role &&
185
- (m.content || '') === (msg.content || ''),
186
- );
187
- if (idx >= 0) {
188
- const next = cur.slice();
189
- next[idx] = { ...msg, id: msg.id ?? cur[idx].id };
190
- return next;
191
- }
192
- return [...cur, msg];
193
- });
194
- }, []);
195
-
196
- /** Mark a messageID as seen — used to dedupe echo rounds. */
197
- const markSeen = useCallback((id: string | undefined) => {
198
- if (!id) return;
199
- setSeenClineMessages((cur) => {
200
- if (cur.has(id)) return cur;
201
- const next = new Set(cur);
202
- next.add(id);
203
- return next;
204
- });
205
- }, []);
206
-
207
- // ── Helpers to mutate per-session state ────────────────────────────────────
208
- const setSessionDisplayState = useCallback(
209
- (id: string, patch: Partial<SessionDisplayState>) => {
210
- setSessionStates((cur) => {
211
- const prev: SessionDisplayState =
212
- cur[id] ?? { state: 'idle', unread: 0, pinned: false };
213
- return { ...cur, [id]: { ...prev, ...patch } };
214
- });
215
- },
216
- [],
217
- );
218
-
219
- const markSessionStreaming = useCallback(
220
- (id: string, streaming: boolean) => {
221
- setSessionDisplayState(id, { state: streaming ? 'streaming' : 'idle' });
222
- },
223
- [setSessionDisplayState],
224
- );
225
-
226
- /** ─── Toast binding (set by the consuming view via `setToast`) ──── */
227
- const setToast = useCallback(
228
- (toast: typeof toastRef.current) => {
229
- toastRef.current = toast;
230
- },
231
- [],
232
- );
233
-
234
- // ── Load bizar chat ─────────────────────────────────────────────────────────
235
- const loadChat = useCallback(
236
- async (sid?: string) => {
237
- try {
238
- const url = sid
239
- ? `/chat?session=${encodeURIComponent(sid)}`
240
- : '/chat?limit=200';
241
- const data = await api.get<ChatResponse>(url);
242
- setBizarMessages(data.messages || []);
243
- setSessions(data.sessions || []);
244
- } catch (err) {
245
- toastRef.current?.error(
246
- `Chat load failed: ${(err as Error).message}`,
247
- );
248
- } finally {
249
- setLoading(false);
250
- }
251
- },
252
- [],
253
- );
254
-
255
- const loadTaskChat = useCallback(async (taskId: string) => {
256
- setLoading(true);
257
- try {
258
- const data = await api.get<{
259
- sessionId?: string;
260
- messages: ChatMessage[];
261
- }>(`/tasks/${encodeURIComponent(taskId)}/chat`);
262
- setBizarMessages(data.messages || []);
263
- setSessionId(data.sessionId || taskId);
264
- } catch (err) {
265
- toastRef.current?.error(
266
- `Task chat load failed: ${(err as Error).message}`,
267
- );
268
- } finally {
269
- setLoading(false);
270
- }
271
- }, []);
272
-
273
- const refreshSessions = useCallback(async () => {
274
- try {
275
- const data = await api.get<{ sessions: ChatSession[] }>('/chat/sessions');
276
- setSessions(data.sessions || []);
277
- } catch {
278
- /* best-effort */
279
- }
280
- }, []);
281
-
282
- const refreshClineSessions = useCallback(async () => {
283
- try {
284
- const data = await api.get<{ sessions: ChatSession[] }>(
285
- '/claude-sessions',
286
- );
287
- // Enrich with source marker.
288
- const enriched: ChatSession[] = (data.sessions || []).map((s) => ({
289
- ...s,
290
- source: 'cline' as const,
291
- title: s.title || s.id,
292
- }));
293
- setClineSessions(enriched);
294
- } catch {
295
- /* best-effort */
296
- }
297
- }, []);
298
-
299
- // ── Cline SSE connection ─────────────────────────────────────────────────
300
- //
301
- // Single source of truth for the EventSource lifecycle. Callers:
302
- // - `loadClineSession(id)` — close any current, open a new one.
303
- // - `closeClineSession()` — close and stop auto-reconnect.
304
- // - unmount — close and stop.
305
- //
306
- // On error / network drop, the EventSource triggers `onerror`. We
307
- // close the connection and schedule a reconnect (with exponential
308
- // backoff: 1s, 2s, 4s, …, capped at 30s) UNLESS `sseAutoReconnectRef`
309
- // is false (explicit disconnect).
310
- //
311
- const openSseForSession = useCallback(
312
- (id: string) => {
313
- // Close any existing connection first.
314
- if (clineEsRef.current) {
315
- try {
316
- clineEsRef.current.close();
317
- } catch {
318
- /* noop */
319
- }
320
- clineEsRef.current = null;
321
- }
322
- if (sseReconnectTimerRef.current !== null) {
323
- clearTimeout(sseReconnectTimerRef.current);
324
- sseReconnectTimerRef.current = null;
325
- }
326
-
327
- // Build the SSE URL. EventSource can't set headers, so we
328
- // pass the auth token as ?token= when set (loopback makes this
329
- // optional, but harmless).
330
- const tok = api.getToken();
331
- const url = tok
332
- ? `/api/claude-sessions/${encodeURIComponent(id)}/stream?token=${encodeURIComponent(tok)}`
333
- : `/api/claude-sessions/${encodeURIComponent(id)}/stream`;
334
-
335
- sseCurrentSessionIdRef.current = id;
336
- sseAutoReconnectRef.current = true;
337
- sseReconnectAttemptRef.current = 0;
338
- setClineError(null);
339
- setClineSuggestion(null);
340
- setClineErrorInfo(null);
341
-
342
- const connect = () => {
343
- if (!sseAutoReconnectRef.current) return;
344
- if (sseCurrentSessionIdRef.current !== id) return;
345
- const es = new EventSource(url);
346
- clineEsRef.current = es;
347
-
348
- // Helper: dispatch one parsed envelope to local state.
349
- const onEnvelope = (evt: ClineSseEnvelope | null) => {
350
- if (!evt || !evt.type) return;
351
- // Drop events for OTHER sessions even though the proxy
352
- // already filters — defense in depth.
353
- if (evt.sessionID && evt.sessionID !== id) return;
354
-
355
- const ts = new Date().toISOString();
356
- const sidForState = id;
357
-
358
- if (
359
- evt.type === 'message.user.created' ||
360
- evt.type === 'message.user.updated'
361
- ) {
362
- const payload = evt.data as
363
- | { messageID?: string; data?: { content?: string } }
364
- | undefined;
365
- appendClineMessage({
366
- id: payload?.messageID ?? evt.messageID,
367
- role: 'user',
368
- content: payload?.data?.content ?? '',
369
- ts,
370
- });
371
- markSeen(payload?.messageID ?? evt.messageID);
372
- return;
373
- }
374
- if (
375
- evt.type === 'message.assistant.created' ||
376
- evt.type === 'message.assistant.updated'
377
- ) {
378
- const payload = evt.data as
379
- | { messageID?: string; data?: { content?: string } }
380
- | undefined;
381
- appendClineMessage({
382
- id: payload?.messageID ?? evt.messageID,
383
- role: 'assistant',
384
- content: payload?.data?.content ?? '',
385
- ts,
386
- });
387
- markSeen(payload?.messageID ?? evt.messageID);
388
- markSessionStreaming(sidForState, true);
389
- return;
390
- }
391
- if (evt.type === 'message.part.updated') {
392
- const payload = evt.data as
393
- | {
394
- part?: { type?: string; text?: string };
395
- messageID?: string;
396
- id?: string;
397
- }
398
- | undefined;
399
- const text = payload?.part?.text ?? '';
400
- if (!text) return;
401
- appendClineMessage({
402
- id: payload?.id ?? payload?.messageID ?? evt.messageID,
403
- role: 'assistant',
404
- content: text,
405
- ts,
406
- });
407
- markSeen(payload?.id ?? payload?.messageID ?? evt.messageID);
408
- markSessionStreaming(sidForState, true);
409
- return;
410
- }
411
- if (
412
- evt.type === 'session.idle' ||
413
- evt.type === 'message.assistant.completed' ||
414
- evt.type === 'session.completed'
415
- ) {
416
- markSessionStreaming(sidForState, false);
417
- return;
418
- }
419
- if (
420
- evt.type === 'session.awaiting' ||
421
- evt.type === 'session.awaiting_input' ||
422
- evt.type === 'message.assistant.awaiting'
423
- ) {
424
- setSessionDisplayState(sidForState, { state: 'awaiting' });
425
- return;
426
- }
427
- if (evt.type === 'session.error') {
428
- setClineError(
429
- (evt.data as { message?: string } | undefined)?.message ||
430
- 'cline session error',
431
- );
432
- return;
433
- }
434
- // Other event types are intentionally ignored — the proxy
435
- // is canonical, we don't need to project every upstream
436
- // event into local state.
437
- };
438
-
439
- // Stable parser — the server may send both `{type: "x"}` and
440
- // `sync` envelopes with a `.<n>` version suffix. We accept both.
441
- const parseData = (raw: string | null | undefined):
442
- | ClineSseEnvelope
443
- | null => {
444
- if (!raw) return null;
445
- try {
446
- const parsed = JSON.parse(raw) as Record<string, unknown>;
447
- // Direct shape: {type, properties: {...}}
448
- if (typeof parsed.type === 'string') {
449
- const props = parsed.properties as
450
- | Record<string, unknown>
451
- | undefined;
452
- const data = (parsed.data as Record<string, unknown> | undefined) ?? props;
453
- const sessionID = (
454
- typeof parsed.sessionID === 'string'
455
- ? parsed.sessionID
456
- : typeof props?.sessionID === 'string'
457
- ? (props.sessionID as string)
458
- : typeof data?.sessionID === 'string'
459
- ? (data.sessionID as string)
460
- : undefined
461
- );
462
- const messageID = (
463
- typeof parsed.messageID === 'string'
464
- ? parsed.messageID
465
- : typeof props?.messageID === 'string'
466
- ? (props.messageID as string)
467
- : typeof data?.messageID === 'string'
468
- ? (data.messageID as string)
469
- : undefined
470
- );
471
- let type = parsed.type as string;
472
- const m = /\.\d+$/.exec(type);
473
- if (m) type = type.slice(0, m.index);
474
- return { type, sessionID, messageID, data: parsed };
475
- }
476
- // Sync envelope: {type: "sync", syncEvent: {...}}
477
- if (
478
- parsed.type === 'sync' &&
479
- parsed.syncEvent &&
480
- typeof parsed.syncEvent === 'object'
481
- ) {
482
- const inner = parsed.syncEvent as Record<string, unknown>;
483
- let type = (inner.type as string) || '';
484
- const m = /\.\d+$/.exec(type);
485
- if (m) type = type.slice(0, m.index);
486
- const innerData = (inner.data as Record<string, unknown>) || {};
487
- return {
488
- type,
489
- sessionID:
490
- typeof innerData.sessionID === 'string'
491
- ? innerData.sessionID
492
- : undefined,
493
- messageID:
494
- typeof innerData.messageID === 'string'
495
- ? innerData.messageID
496
- : undefined,
497
- data: inner,
498
- };
499
- }
500
- return null;
501
- } catch {
502
- return null;
503
- }
504
- };
505
-
506
- // register handlers per named event type
507
- const namedTypes = [
508
- 'message.user.created',
509
- 'message.user.updated',
510
- 'message.assistant.created',
511
- 'message.assistant.updated',
512
- 'message.part.updated',
513
- 'session.idle',
514
- 'message.assistant.completed',
515
- 'session.completed',
516
- 'session.awaiting',
517
- 'session.awaiting_input',
518
- 'message.assistant.awaiting',
519
- 'session.error',
520
- ];
521
- for (const name of namedTypes) {
522
- es.addEventListener(name, (e: MessageEvent) => {
523
- onEnvelope(parseData((e as MessageEvent).data));
524
- });
525
- }
526
-
527
- es.onerror = () => {
528
- if (sseCurrentSessionIdRef.current !== id) return;
529
- if (!sseAutoReconnectRef.current) {
530
- try {
531
- es.close();
532
- } catch {
533
- /* noop */
534
- }
535
- clineEsRef.current = null;
536
- return;
537
- }
538
- try {
539
- es.close();
540
- } catch {
541
- /* noop */
542
- }
543
- clineEsRef.current = null;
544
-
545
- const nextAttempt = sseReconnectAttemptRef.current + 1;
546
- sseReconnectAttemptRef.current = nextAttempt;
547
- // Backoff: 1s, 2s, 4s, 8s, … capped at 30s.
548
- const delayMs = Math.min(30_000, 1000 * 2 ** (nextAttempt - 1));
549
-
550
- if (sseReconnectTimerRef.current !== null) {
551
- clearTimeout(sseReconnectTimerRef.current);
552
- }
553
- sseReconnectTimerRef.current = window.setTimeout(() => {
554
- sseReconnectTimerRef.current = null;
555
- if (
556
- sseAutoReconnectRef.current &&
557
- sseCurrentSessionIdRef.current === id
558
- ) {
559
- connect();
560
- }
561
- }, delayMs);
562
- };
563
-
564
- es.onopen = () => {
565
- // Successful (re)connect — reset backoff.
566
- sseReconnectAttemptRef.current = 0;
567
- setClineError(null);
568
- setClineSuggestion(null);
569
- setClineErrorInfo(null);
570
- };
571
- };
572
-
573
- connect();
574
- },
575
- [appendClineMessage, markSeen, markSessionStreaming, setSessionDisplayState],
576
- );
577
-
578
- const closeClineSession = useCallback(() => {
579
- // Disable auto-reconnect first so the onerror handler short-circuits.
580
- sseAutoReconnectRef.current = false;
581
- sseCurrentSessionIdRef.current = null;
582
- if (sseReconnectTimerRef.current !== null) {
583
- clearTimeout(sseReconnectTimerRef.current);
584
- sseReconnectTimerRef.current = null;
585
- }
586
- if (clineEsRef.current) {
587
- try {
588
- clineEsRef.current.close();
589
- } catch {
590
- /* noop */
591
- }
592
- clineEsRef.current = null;
593
- }
594
- setClineMessages([]);
595
- setSeenClineMessages(new Set());
596
- setClineError(null);
597
- setClineSuggestion(null);
598
- setClineErrorInfo(null);
599
- setActiveClineSessionId(null);
600
- setActiveSource('bizar');
601
- }, []);
602
-
603
- const loadClineSession = useCallback(
604
- async (id: string) => {
605
- // Close any previous cline session cleanly.
606
- sseAutoReconnectRef.current = false;
607
- if (clineEsRef.current) {
608
- try {
609
- clineEsRef.current.close();
610
- } catch {
611
- /* noop */
612
- }
613
- clineEsRef.current = null;
614
- }
615
- if (sseReconnectTimerRef.current !== null) {
616
- clearTimeout(sseReconnectTimerRef.current);
617
- sseReconnectTimerRef.current = null;
618
- }
619
-
620
- setClineError(null);
621
- setClineSuggestion(null);
622
- setClineErrorInfo(null);
623
- setLoading(true);
624
-
625
- try {
626
- const data = await api.get<{ messages: ChatMessage[] }>(
627
- `/claude-sessions/${encodeURIComponent(id)}/messages`,
628
- );
629
- setClineMessages(data.messages || []);
630
- } catch (err) {
631
- const msg = (err as Error).message;
632
- // v5.0.0 — bug #4: surface the server's structured error
633
- // envelope so the UI can render a useful suggestion instead
634
- // of the raw upstream error string. The server returns
635
- // `{error, message, cause?, status?, suggestion?}` for every
636
- // non-2xx response (see serve-info.mjs + routes/cline-
637
- // session-detail.mjs).
638
- let info: ClineErrorInfo | null = null;
639
- if (err instanceof ApiError && err.data && typeof err.data === 'object') {
640
- const d = err.data as {
641
- error?: string;
642
- message?: string;
643
- cause?: string;
644
- status?: number;
645
- suggestion?: string;
646
- };
647
- // canRetry: 503/502 are transient (plugin offline /
648
- // upstream hiccup); the operator can fix the plugin and
649
- // try again. 400 is a hard bad_request — retrying with the
650
- // same payload won't help.
651
- const code = d.error || 'unknown';
652
- const canRetry =
653
- code !== 'bad_request' &&
654
- code !== 'too_many_subscribers' &&
655
- code !== 'unauthorized';
656
- info = {
657
- type: 'session_load_failed',
658
- code,
659
- message: d.message || msg,
660
- cause: d.cause,
661
- status: d.status,
662
- suggestion: d.suggestion ?? null,
663
- canRetry,
664
- };
665
- } else if (err instanceof ApiError) {
666
- info = {
667
- type: 'session_load_failed',
668
- code: 'unknown',
669
- message: msg,
670
- suggestion: null,
671
- canRetry: true,
672
- };
673
- }
674
- // Legacy fields — kept so the existing Chat.tsx thread-header
675
- // error display continues to work unchanged.
676
- setClineError(
677
- info
678
- ? `Cline session load failed (${info.code}): ${info.message}`
679
- : `Cline session load failed: ${msg}`,
680
- );
681
- setClineSuggestion(info?.suggestion ?? null);
682
- setClineErrorInfo(info);
683
- toastRef.current?.error(
684
- info
685
- ? `Cline session load failed: ${info.message}`
686
- : `Cline session load failed: ${msg}`,
687
- );
688
- setClineMessages([]);
689
- } finally {
690
- setLoading(false);
691
- }
692
-
693
- setActiveClineSessionId(id);
694
- setActiveSource('cline');
695
- markSessionStreaming(id, false);
696
- openSseForSession(id);
697
- },
698
- [markSessionStreaming, openSseForSession],
699
- );
700
-
701
- // ── Select a bizar session ──────────────────────────────────────────────────
702
- const selectBizarSession = useCallback(
703
- (sid: string) => {
704
- closeClineSession();
705
- setSessionId(sid);
706
- setActiveSource('bizar');
707
- loadChat(sid);
708
- // Reset unread for the session being opened.
709
- setSessionDisplayState(sid, { unread: 0 });
710
- },
711
- [closeClineSession, loadChat, setSessionDisplayState],
712
- );
713
-
714
- // ── Create session (cline primary; bizar fallback) ──────────────────────
715
- const onCreateSession = useCallback(async (): Promise<{
716
- ok: boolean;
717
- source?: 'bizar' | 'cline';
718
- id?: string;
719
- }> => {
720
- if (busy.create) return { ok: false };
721
- const agent = settings.defaultAgent || 'odin';
722
- setBusy((b) => ({ ...b, create: true }));
723
- try {
724
- // Try to create a real cline session first. This is the
725
- // primary create path: it gives the user a full conversation
726
- // roundtrip with SSE streaming, abort, etc.
727
- try {
728
- const created = await api.post<{
729
- id: string;
730
- title: string;
731
- agent: string;
732
- directory: string;
733
- createdAt: number;
734
- }>('/claude-sessions/new', { agent });
735
- await refreshClineSessions();
736
- // Open the newly created session right away so the user is
737
- // dropped into a fresh empty thread, not stuck on the
738
- // previous one.
739
- await loadClineSession(created.id);
740
- toastRef.current?.success(`Session ${created.id} created.`);
741
- return { ok: true, source: 'cline', id: created.id };
742
- } catch (clineErr) {
743
- // Cline plugin offline (503) — fall back to the local
744
- // per-project .jsonl session. Otherwise, surface the error.
745
- if (!(clineErr instanceof ApiError) || clineErr.status !== 503) {
746
- toastRef.current?.error(
747
- `Create failed: ${(clineErr as Error).message}`,
748
- );
749
- return { ok: false };
750
- }
751
- }
752
-
753
- // Fallback: local jsonl session.
754
- if (!snapshot.activeProject) {
755
- toastRef.current?.error(
756
- 'Pick a project in Overview to scope chat sessions.',
757
- );
758
- return { ok: false };
759
- }
760
- const created = await api.post<ChatSession>('/chat/sessions', {});
761
- setSessionId(created.id);
762
- setBizarMessages([]);
763
- setPinned(new Set());
764
- setSessionDisplayState(created.id, { state: 'idle', unread: 0 });
765
- await loadChat(created.id);
766
- refreshSessions().catch(() => {});
767
- toastRef.current?.success(`Session ${created.id} created.`);
768
- return { ok: true, source: 'bizar', id: created.id };
769
- } catch (err) {
770
- toastRef.current?.error(`Create failed: ${(err as Error).message}`);
771
- return { ok: false };
772
- } finally {
773
- setBusy((b) => ({ ...b, create: false }));
774
- }
775
- }, [
776
- busy.create,
777
- settings.defaultAgent,
778
- snapshot.activeProject,
779
- refreshClineSessions,
780
- loadClineSession,
781
- loadChat,
782
- refreshSessions,
783
- setSessionDisplayState,
784
- ]);
785
-
786
- // ── Send message ────────────────────────────────────────────────────────────
787
- const onSend = useCallback(
788
- async (
789
- message: string,
790
- agent: string,
791
- model: string,
792
- attachments?: string[],
793
- ): Promise<{ ok: boolean }> => {
794
- if (busy.send) return { ok: false };
795
- const trimmed = message.trim();
796
- if (!trimmed) return { ok: false };
797
-
798
- if (activeSource === 'cline' && activeClineSessionId) {
799
- const sid = activeClineSessionId;
800
- const optimisticId = `msg_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
801
- const optimistic: ChatMessage = {
802
- id: optimisticId,
803
- role: 'user',
804
- content: trimmed,
805
- agent,
806
- ts: new Date().toISOString(),
807
- };
808
- appendClineMessage(optimistic);
809
- markSeen(optimisticId);
810
- setBusy((b) => ({ ...b, send: true }));
811
- try {
812
- await api.post<{ ok: boolean; messageId: string }>(
813
- `/claude-sessions/${encodeURIComponent(sid)}/send`,
814
- {
815
- message: trimmed,
816
- agent,
817
- },
818
- );
819
- markSessionStreaming(sid, true);
820
- return { ok: true };
821
- } catch (err) {
822
- // Remove optimistic on failure.
823
- setClineMessages((cur) => cur.filter((m) => m.id !== optimisticId));
824
- toastRef.current?.error(
825
- `Send failed: ${(err as Error).message}`,
826
- );
827
- return { ok: false };
828
- } finally {
829
- setBusy((b) => ({ ...b, send: false }));
830
- }
831
- }
832
-
833
- // Bizar fallback.
834
- const optimistic: ChatMessage = {
835
- role: 'user',
836
- content: trimmed,
837
- agent,
838
- ts: new Date().toISOString(),
839
- };
840
- setBizarMessages((cur) => [...cur, optimistic]);
841
- setBusy((b) => ({ ...b, send: true }));
842
- markSessionStreaming(sessionId, true);
843
- try {
844
- const response = await api.post<{ messages?: ChatMessage[] }>(
845
- '/chat',
846
- {
847
- message: trimmed,
848
- agent,
849
- model,
850
- attachments: attachments || [],
851
- },
852
- );
853
- if (response?.messages) {
854
- for (const msg of response.messages) {
855
- if (msg.role === 'assistant') {
856
- setBizarMessages((cur) => {
857
- const exists = cur.some((m) => m.ts === msg.ts);
858
- return exists ? cur : [...cur, msg];
859
- });
860
- }
861
- }
862
- } else {
863
- toastRef.current?.info(
864
- 'Still processing… the response will appear shortly.',
865
- );
866
- }
867
- return { ok: true };
868
- } catch (err) {
869
- setBizarMessages((cur) => cur.filter((m) => m !== optimistic));
870
- toastRef.current?.error(
871
- `Send failed: ${(err as Error).message}`,
872
- );
873
- return { ok: false };
874
- } finally {
875
- setBusy((b) => ({ ...b, send: false }));
876
- markSessionStreaming(sessionId, false);
877
- }
878
- },
879
- [
880
- activeSource,
881
- activeClineSessionId,
882
- appendClineMessage,
883
- markSeen,
884
- markSessionStreaming,
885
- sessionId,
886
- busy.send,
887
- ],
888
- );
889
-
890
- const onRegenerate = useCallback(
891
- async (messageId: string) => {
892
- if (!sessionId) {
893
- toastRef.current?.error('No active session to regenerate.');
894
- return;
895
- }
896
- try {
897
- await api.post('/chat/regenerate', { sessionId, messageId });
898
- await loadChat(sessionId);
899
- } catch (err) {
900
- toastRef.current?.error(
901
- `Regenerate failed: ${(err as Error).message}`,
902
- );
903
- }
904
- },
905
- [sessionId, loadChat],
906
- );
907
-
908
- const deleteMessage = useCallback(
909
- (idx: number) => {
910
- if (activeSource === 'cline') {
911
- setClineMessages((cur) => cur.filter((_, i) => i !== idx));
912
- } else {
913
- setBizarMessages((cur) => cur.filter((_, i) => i !== idx));
914
- }
915
- },
916
- [activeSource],
917
- );
918
-
919
- const togglePin = useCallback((idx: number) => {
920
- setPinned((cur) => {
921
- const next = new Set(cur);
922
- if (next.has(idx)) next.delete(idx);
923
- else next.add(idx);
924
- return next;
925
- });
926
- }, []);
927
-
928
- const copyMessage = useCallback((m: ChatMessage) => {
929
- const text = m.content || m.message || '';
930
- try {
931
- navigator.clipboard?.writeText(text).then(
932
- () => toastRef.current?.success('Copied.'),
933
- () => toastRef.current?.error('Copy failed.'),
934
- );
935
- } catch {
936
- toastRef.current?.error('Copy failed.');
937
- }
938
- }, []);
939
-
940
- // ── Jump-to-latest ──────────────────────────────────────────────────────────
941
- const handleScroll = useCallback(() => {
942
- const el = listRef.current;
943
- if (!el) return;
944
- const distFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
945
- const atBottom = distFromBottom < 32;
946
- setStickToBottom(atBottom);
947
- if (atBottom) setNewMessageCount(0);
948
- }, []);
949
-
950
- const jumpToLatest = useCallback(() => {
951
- const el = listRef.current;
952
- if (!el) return;
953
- el.scrollTop = el.scrollHeight;
954
- setStickToBottom(true);
955
- setNewMessageCount(0);
956
- }, []);
957
-
958
- // ── Session rename / delete (rail row menu + info panel actions) ────────────
959
- const renameSession = useCallback(
960
- async (id: string, title: string): Promise<boolean> => {
961
- if (busy.rename) return false;
962
- setBusy((b) => ({ ...b, rename: true }));
963
- try {
964
- const trimmed = title.trim();
965
- if (!trimmed) {
966
- toastRef.current?.error('Title cannot be empty.');
967
- return false;
968
- }
969
- // Try the cline path first if this id is in the cline
970
- // session list, otherwise the local path. We dispatch by
971
- // inspecting the in-memory set (avoids a round trip).
972
- const isCline = clineSessions.some((s) => s.id === id);
973
- if (isCline) {
974
- await api.patch<{ id: string; title: string }>(
975
- `/claude-sessions/${encodeURIComponent(id)}`,
976
- { title: trimmed },
977
- );
978
- setClineSessions((cur) =>
979
- cur.map((s) => (s.id === id ? { ...s, title: trimmed } : s)),
980
- );
981
- } else {
982
- await api.post(
983
- `/chat/sessions/${encodeURIComponent(id)}/rename`,
984
- { title: trimmed },
985
- );
986
- setSessions((cur) =>
987
- cur.map((s) => (s.id === id ? { ...s, title: trimmed } : s)),
988
- );
989
- }
990
- toastRef.current?.success('Renamed.');
991
- return true;
992
- } catch (err) {
993
- toastRef.current?.error(
994
- `Rename failed: ${(err as Error).message}`,
995
- );
996
- return false;
997
- } finally {
998
- setBusy((b) => ({ ...b, rename: false }));
999
- }
1000
- },
1001
- [busy.rename, clineSessions],
1002
- );
1003
-
1004
- const deleteSession = useCallback(
1005
- async (id: string): Promise<boolean> => {
1006
- if (busy.delete) return false;
1007
- setBusy((b) => ({ ...b, delete: true }));
1008
- try {
1009
- const isCline = clineSessions.some((s) => s.id === id);
1010
- if (isCline) {
1011
- await api.del(`/claude-sessions/${encodeURIComponent(id)}`);
1012
- setClineSessions((cur) => cur.filter((s) => s.id !== id));
1013
- if (activeClineSessionId === id) {
1014
- closeClineSession();
1015
- }
1016
- } else {
1017
- await api.del(`/chat/sessions/${encodeURIComponent(id)}`);
1018
- setSessions((cur) => cur.filter((s) => s.id !== id));
1019
- if (sessionId === id) {
1020
- setSessionId('');
1021
- setBizarMessages([]);
1022
- }
1023
- }
1024
- setSessionStates((cur) => {
1025
- const next = { ...cur };
1026
- delete next[id];
1027
- return next;
1028
- });
1029
- toastRef.current?.success('Session deleted.');
1030
- return true;
1031
- } catch (err) {
1032
- toastRef.current?.error(
1033
- `Delete failed: ${(err as Error).message}`,
1034
- );
1035
- return false;
1036
- } finally {
1037
- setBusy((b) => ({ ...b, delete: false }));
1038
- }
1039
- },
1040
- [
1041
- busy.delete,
1042
- clineSessions,
1043
- activeClineSessionId,
1044
- closeClineSession,
1045
- sessionId,
1046
- ],
1047
- );
1048
-
1049
- // ── Auto-scroll on new messages ─────────────────────────────────────────────
1050
- useEffect(() => {
1051
- if (listRef.current) {
1052
- if (stickToBottom) {
1053
- listRef.current.scrollTop = listRef.current.scrollHeight;
1054
- } else {
1055
- setNewMessageCount((n) => n + 1);
1056
- }
1057
- }
1058
- // eslint-disable-next-line react-hooks/exhaustive-deps
1059
- }, [bizarMessages, clineMessages]);
1060
-
1061
- // ── Cleanup SSE on unmount ──────────────────────────────────────────────────
1062
- useEffect(() => {
1063
- return () => {
1064
- sseAutoReconnectRef.current = false;
1065
- sseCurrentSessionIdRef.current = null;
1066
- if (sseReconnectTimerRef.current !== null) {
1067
- clearTimeout(sseReconnectTimerRef.current);
1068
- sseReconnectTimerRef.current = null;
1069
- }
1070
- if (clineEsRef.current) {
1071
- try {
1072
- clineEsRef.current.close();
1073
- } catch {
1074
- /* noop */
1075
- }
1076
- clineEsRef.current = null;
1077
- }
1078
- };
1079
- }, []);
1080
-
1081
- // ── Initial load ────────────────────────────────────────────────────────────
1082
- useEffect(() => {
1083
- if (initialTaskId) {
1084
- loadTaskChat(initialTaskId);
1085
- } else {
1086
- loadChat();
1087
- }
1088
- refreshClineSessions();
1089
- // eslint-disable-next-line react-hooks/exhaustive-deps
1090
- }, []);
1091
-
1092
- // ── Listen for bizar:setChatTask events ────────────────────────────────────
1093
- useEffect(() => {
1094
- const handler = (e: Event) => {
1095
- const taskId = (e as CustomEvent<{ taskId: string }>).detail?.taskId;
1096
- if (taskId) loadTaskChat(taskId);
1097
- };
1098
- window.addEventListener('bizar:setChatTask', handler);
1099
- return () => window.removeEventListener('bizar:setChatTask', handler);
1100
- }, [loadTaskChat]);
1101
-
1102
- // ── WebSocket for live bizar updates ────────────────────────────────────────
1103
- useEffect(() => {
1104
- let closed = false;
1105
- import('../../lib/ws').then(({ Ws }) => {
1106
- if (closed) return;
1107
- const ws = new Ws();
1108
- ws.on((msg: { type: string; message?: ChatMessage }) => {
1109
- if (msg.type !== 'chat:message') return;
1110
- const next = msg.message;
1111
- if (!next) return;
1112
- setBizarMessages((cur) => {
1113
- const exists = cur.some((m) => m.ts === next.ts);
1114
- return exists ? cur : [...cur, next];
1115
- });
1116
- });
1117
- });
1118
- return () => {
1119
- closed = true;
1120
- };
1121
- }, []);
1122
-
1123
- return {
1124
- // ── State ────────────────────────────────────────────────────────────────
1125
- messages:
1126
- activeSource === 'cline' ? clineMessages : bizarMessages,
1127
- bizarMessages,
1128
- clineMessages,
1129
- sessions,
1130
- clineSessions,
1131
- sessionId,
1132
- setSessionId,
1133
- loading,
1134
- sending: busy.send,
1135
- pinned,
1136
- listRef,
1137
- // ── Cline state ──────────────────────────────────────────────────────
1138
- activeSource,
1139
- activeClineSessionId,
1140
- clineError,
1141
- clineSuggestion,
1142
- /**
1143
- * v5.0.0 — bug #4: structured error info consumed by
1144
- * `ChatInfoPanel`. `null` when no error is active.
1145
- */
1146
- clineErrorInfo,
1147
- /**
1148
- * v5.0.0 — bug #4: retry helper exposed for `ChatInfoPanel`'s
1149
- * Retry button. Calls `loadClineSession` on the currently
1150
- * active cline session (or no-op if none is active).
1151
- */
1152
- retryClineSession: () => {
1153
- if (activeClineSessionId) void loadClineSession(activeClineSessionId);
1154
- },
1155
- // ── v3.22 — per-session display state ──────────────────────────────────
1156
- sessionStates,
1157
- busy,
1158
- getSessionDisplay: (s: ChatSession) => ({
1159
- ...s,
1160
- state: sessionStates[s.id]?.state ?? 'idle',
1161
- unread: sessionStates[s.id]?.unread ?? 0,
1162
- pinned: sessionStates[s.id]?.pinned ?? false,
1163
- tree: sessionStates[s.id]?.tree,
1164
- }),
1165
- // ── Jump-to-latest ──────────────────────────────────────────────────────
1166
- stickToBottom,
1167
- newMessageCount,
1168
- handleScroll,
1169
- jumpToLatest,
1170
- // ── Toast integration ──────────────────────────────────────────────────
1171
- setToast,
1172
- // ── Actions ─────────────────────────────────────────────────────────────
1173
- loadChat,
1174
- loadTaskChat,
1175
- refreshSessions,
1176
- refreshClineSessions,
1177
- loadClineSession,
1178
- closeClineSession,
1179
- selectBizarSession,
1180
- onCreateSession,
1181
- onSend,
1182
- onRegenerate,
1183
- deleteMessage,
1184
- togglePin,
1185
- copyMessage,
1186
- renameSession,
1187
- deleteSession,
1188
- seenClineMessages,
1189
- };
1190
- }