@agentuity/workbench 0.0.64 → 0.0.66

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 (405) hide show
  1. package/dist/components/App.d.ts +6 -0
  2. package/dist/components/App.d.ts.map +1 -0
  3. package/dist/components/App.js +13 -0
  4. package/dist/components/App.js.map +1 -0
  5. package/dist/components/ConnectionStatus.d.ts +7 -0
  6. package/dist/components/ConnectionStatus.d.ts.map +1 -0
  7. package/dist/components/ConnectionStatus.js +52 -0
  8. package/dist/components/ConnectionStatus.js.map +1 -0
  9. package/dist/components/Inline.d.ts +10 -0
  10. package/dist/components/Inline.d.ts.map +1 -0
  11. package/dist/components/Inline.js +11 -0
  12. package/dist/components/Inline.js.map +1 -0
  13. package/dist/components/ai-elements/actions.d.ts +10 -0
  14. package/dist/components/ai-elements/actions.d.ts.map +1 -0
  15. package/dist/components/ai-elements/actions.js +14 -0
  16. package/dist/components/ai-elements/actions.js.map +1 -0
  17. package/dist/components/ai-elements/artifact.d.ts +24 -0
  18. package/dist/components/ai-elements/artifact.d.ts.map +1 -0
  19. package/dist/components/ai-elements/artifact.js +21 -0
  20. package/dist/components/ai-elements/artifact.js.map +1 -0
  21. package/dist/components/ai-elements/branch.d.ts +21 -0
  22. package/dist/components/ai-elements/branch.d.ts.map +1 -0
  23. package/dist/components/ai-elements/branch.js +71 -0
  24. package/dist/components/ai-elements/branch.js.map +1 -0
  25. package/dist/components/ai-elements/canvas.d.ts +9 -0
  26. package/dist/components/ai-elements/canvas.d.ts.map +1 -0
  27. package/dist/components/ai-elements/canvas.js +6 -0
  28. package/dist/components/ai-elements/canvas.js.map +1 -0
  29. package/dist/components/ai-elements/chain-of-thought.d.ts +30 -0
  30. package/dist/components/ai-elements/chain-of-thought.d.ts.map +1 -0
  31. package/dist/components/ai-elements/chain-of-thought.js +52 -0
  32. package/dist/components/ai-elements/chain-of-thought.js.map +1 -0
  33. package/dist/components/ai-elements/code-block.d.ts +18 -0
  34. package/dist/components/ai-elements/code-block.d.ts.map +1 -0
  35. package/dist/components/ai-elements/code-block.js +89 -0
  36. package/dist/components/ai-elements/code-block.js.map +1 -0
  37. package/dist/components/ai-elements/confirmation.d.ts +27 -0
  38. package/dist/components/ai-elements/confirmation.d.ts.map +1 -0
  39. package/dist/components/ai-elements/confirmation.js +57 -0
  40. package/dist/components/ai-elements/confirmation.js.map +1 -0
  41. package/dist/components/ai-elements/connection.d.ts +3 -0
  42. package/dist/components/ai-elements/connection.d.ts.map +1 -0
  43. package/dist/components/ai-elements/connection.js +4 -0
  44. package/dist/components/ai-elements/connection.js.map +1 -0
  45. package/dist/components/ai-elements/context.d.ts +33 -0
  46. package/dist/components/ai-elements/context.d.ts.map +1 -0
  47. package/dist/components/ai-elements/context.js +167 -0
  48. package/dist/components/ai-elements/context.js.map +1 -0
  49. package/dist/components/ai-elements/controls.d.ts +5 -0
  50. package/dist/components/ai-elements/controls.d.ts.map +1 -0
  51. package/dist/components/ai-elements/controls.js +6 -0
  52. package/dist/components/ai-elements/controls.js.map +1 -0
  53. package/dist/components/ai-elements/conversation.d.ts +16 -0
  54. package/dist/components/ai-elements/conversation.d.ts.map +1 -0
  55. package/dist/components/ai-elements/conversation.js +18 -0
  56. package/dist/components/ai-elements/conversation.js.map +1 -0
  57. package/dist/components/ai-elements/edge.d.ts +6 -0
  58. package/dist/components/ai-elements/edge.d.ts.map +1 -0
  59. package/dist/components/ai-elements/edge.js +83 -0
  60. package/dist/components/ai-elements/edge.js.map +1 -0
  61. package/dist/components/ai-elements/image.d.ts +7 -0
  62. package/dist/components/ai-elements/image.d.ts.map +1 -0
  63. package/dist/components/ai-elements/image.js +4 -0
  64. package/dist/components/ai-elements/image.js.map +1 -0
  65. package/dist/components/ai-elements/inline-citation.d.ts +39 -0
  66. package/dist/components/ai-elements/inline-citation.d.ts.map +1 -0
  67. package/dist/components/ai-elements/inline-citation.js +62 -0
  68. package/dist/components/ai-elements/inline-citation.js.map +1 -0
  69. package/dist/components/ai-elements/loader.d.ts +6 -0
  70. package/dist/components/ai-elements/loader.d.ts.map +1 -0
  71. package/dist/components/ai-elements/loader.js +5 -0
  72. package/dist/components/ai-elements/loader.js.map +1 -0
  73. package/dist/components/ai-elements/message.d.ts +20 -0
  74. package/dist/components/ai-elements/message.d.ts.map +1 -0
  75. package/dist/components/ai-elements/message.js +26 -0
  76. package/dist/components/ai-elements/message.js.map +1 -0
  77. package/dist/components/ai-elements/node.d.ts +22 -0
  78. package/dist/components/ai-elements/node.d.ts.map +1 -0
  79. package/dist/components/ai-elements/node.js +12 -0
  80. package/dist/components/ai-elements/node.js.map +1 -0
  81. package/dist/components/ai-elements/open-in-chat.d.ts +29 -0
  82. package/dist/components/ai-elements/open-in-chat.d.ts.map +1 -0
  83. package/dist/components/ai-elements/open-in-chat.js +97 -0
  84. package/dist/components/ai-elements/open-in-chat.js.map +1 -0
  85. package/dist/components/ai-elements/panel.d.ts +6 -0
  86. package/dist/components/ai-elements/panel.d.ts.map +1 -0
  87. package/dist/components/ai-elements/panel.js +5 -0
  88. package/dist/components/ai-elements/panel.js.map +1 -0
  89. package/dist/components/ai-elements/plan.d.ts +26 -0
  90. package/dist/components/ai-elements/plan.d.ts.map +1 -0
  91. package/dist/components/ai-elements/plan.js +32 -0
  92. package/dist/components/ai-elements/plan.js.map +1 -0
  93. package/dist/components/ai-elements/prompt-input.d.ts +187 -0
  94. package/dist/components/ai-elements/prompt-input.d.ts.map +1 -0
  95. package/dist/components/ai-elements/prompt-input.js +544 -0
  96. package/dist/components/ai-elements/prompt-input.js.map +1 -0
  97. package/dist/components/ai-elements/queue.d.ts +62 -0
  98. package/dist/components/ai-elements/queue.d.ts.map +1 -0
  99. package/dist/components/ai-elements/queue.js +25 -0
  100. package/dist/components/ai-elements/queue.js.map +1 -0
  101. package/dist/components/ai-elements/reasoning.d.ts +17 -0
  102. package/dist/components/ai-elements/reasoning.d.ts.map +1 -0
  103. package/dist/components/ai-elements/reasoning.js +77 -0
  104. package/dist/components/ai-elements/reasoning.js.map +1 -0
  105. package/dist/components/ai-elements/response.d.ts +6 -0
  106. package/dist/components/ai-elements/response.d.ts.map +1 -0
  107. package/dist/components/ai-elements/response.js +8 -0
  108. package/dist/components/ai-elements/response.js.map +1 -0
  109. package/dist/components/ai-elements/shimmer.d.ts +10 -0
  110. package/dist/components/ai-elements/shimmer.d.ts.map +1 -0
  111. package/dist/components/ai-elements/shimmer.js +19 -0
  112. package/dist/components/ai-elements/shimmer.js.map +1 -0
  113. package/dist/components/ai-elements/sources.d.ts +13 -0
  114. package/dist/components/ai-elements/sources.d.ts.map +1 -0
  115. package/dist/components/ai-elements/sources.js +10 -0
  116. package/dist/components/ai-elements/sources.js.map +1 -0
  117. package/dist/components/ai-elements/suggestion.d.ts +11 -0
  118. package/dist/components/ai-elements/suggestion.d.ts.map +1 -0
  119. package/dist/components/ai-elements/suggestion.js +13 -0
  120. package/dist/components/ai-elements/suggestion.js.map +1 -0
  121. package/dist/components/ai-elements/task.d.ts +15 -0
  122. package/dist/components/ai-elements/task.d.ts.map +1 -0
  123. package/dist/components/ai-elements/task.js +11 -0
  124. package/dist/components/ai-elements/task.js.map +1 -0
  125. package/dist/components/ai-elements/tool.d.ts +24 -0
  126. package/dist/components/ai-elements/tool.d.ts.map +1 -0
  127. package/dist/components/ai-elements/tool.js +47 -0
  128. package/dist/components/ai-elements/tool.js.map +1 -0
  129. package/dist/components/ai-elements/toolbar.d.ts +6 -0
  130. package/dist/components/ai-elements/toolbar.d.ts.map +1 -0
  131. package/dist/components/ai-elements/toolbar.js +5 -0
  132. package/dist/components/ai-elements/toolbar.js.map +1 -0
  133. package/dist/components/ai-elements/web-preview.d.ts +35 -0
  134. package/dist/components/ai-elements/web-preview.d.ts.map +1 -0
  135. package/dist/components/ai-elements/web-preview.js +63 -0
  136. package/dist/components/ai-elements/web-preview.js.map +1 -0
  137. package/dist/components/internal/Chat.d.ts +11 -0
  138. package/dist/components/internal/Chat.d.ts.map +1 -0
  139. package/dist/components/internal/Chat.js +52 -0
  140. package/dist/components/internal/Chat.js.map +1 -0
  141. package/dist/components/internal/Header.d.ts +10 -0
  142. package/dist/components/internal/Header.d.ts.map +1 -0
  143. package/dist/components/internal/Header.js +31 -0
  144. package/dist/components/internal/Header.js.map +1 -0
  145. package/dist/components/internal/InputSection.d.ts +14 -0
  146. package/dist/components/internal/InputSection.d.ts.map +1 -0
  147. package/dist/components/internal/InputSection.js +212 -0
  148. package/dist/components/internal/InputSection.js.map +1 -0
  149. package/dist/components/internal/Schema.d.ts +7 -0
  150. package/dist/components/internal/Schema.d.ts.map +1 -0
  151. package/dist/components/internal/Schema.js +14 -0
  152. package/dist/components/internal/Schema.js.map +1 -0
  153. package/dist/components/internal/WorkbenchProvider.d.ts +11 -0
  154. package/dist/components/internal/WorkbenchProvider.d.ts.map +1 -0
  155. package/dist/components/internal/WorkbenchProvider.js +224 -0
  156. package/dist/components/internal/WorkbenchProvider.js.map +1 -0
  157. package/dist/components/internal/logo.d.ts +2 -0
  158. package/dist/components/internal/logo.d.ts.map +1 -0
  159. package/dist/components/internal/logo.js +5 -0
  160. package/dist/components/internal/logo.js.map +1 -0
  161. package/dist/components/ui/alert.d.ts +10 -0
  162. package/dist/components/ui/alert.d.ts.map +1 -0
  163. package/dist/components/ui/alert.js +25 -0
  164. package/dist/components/ui/alert.js.map +1 -0
  165. package/dist/components/ui/avatar.d.ts +7 -0
  166. package/dist/components/ui/avatar.d.ts.map +1 -0
  167. package/dist/components/ui/avatar.js +14 -0
  168. package/dist/components/ui/avatar.js.map +1 -0
  169. package/dist/components/ui/badge.d.ts +10 -0
  170. package/dist/components/ui/badge.d.ts.map +1 -0
  171. package/dist/components/ui/badge.js +23 -0
  172. package/dist/components/ui/badge.js.map +1 -0
  173. package/dist/components/ui/button.d.ts +3 -4
  174. package/dist/components/ui/button.d.ts.map +1 -1
  175. package/dist/components/ui/button.js.map +1 -1
  176. package/dist/components/ui/card.d.ts +2 -1
  177. package/dist/components/ui/card.d.ts.map +1 -1
  178. package/dist/components/ui/card.js +4 -1
  179. package/dist/components/ui/card.js.map +1 -1
  180. package/dist/components/ui/carousel.d.ts +20 -0
  181. package/dist/components/ui/carousel.d.ts.map +1 -0
  182. package/dist/components/ui/carousel.js +92 -0
  183. package/dist/components/ui/carousel.js.map +1 -0
  184. package/dist/components/ui/checkbox.d.ts +5 -0
  185. package/dist/components/ui/checkbox.d.ts.map +1 -0
  186. package/dist/components/ui/checkbox.js +9 -0
  187. package/dist/components/ui/checkbox.js.map +1 -0
  188. package/dist/components/ui/collapsible.d.ts +6 -0
  189. package/dist/components/ui/collapsible.d.ts.map +1 -0
  190. package/dist/components/ui/collapsible.js +14 -0
  191. package/dist/components/ui/collapsible.js.map +1 -0
  192. package/dist/components/ui/command.d.ts +19 -0
  193. package/dist/components/ui/command.d.ts.map +1 -0
  194. package/dist/components/ui/command.js +34 -0
  195. package/dist/components/ui/command.js.map +1 -0
  196. package/dist/components/ui/dialog.d.ts +16 -0
  197. package/dist/components/ui/dialog.d.ts.map +1 -0
  198. package/dist/components/ui/dialog.js +36 -0
  199. package/dist/components/ui/dialog.js.map +1 -0
  200. package/dist/components/ui/dropdown-menu.d.ts +26 -0
  201. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  202. package/dist/components/ui/dropdown-menu.js +52 -0
  203. package/dist/components/ui/dropdown-menu.js.map +1 -0
  204. package/dist/components/ui/field.d.ts +25 -0
  205. package/dist/components/ui/field.d.ts.map +1 -0
  206. package/dist/components/ui/field.js +74 -0
  207. package/dist/components/ui/field.js.map +1 -0
  208. package/dist/components/ui/form.d.ts +25 -0
  209. package/dist/components/ui/form.d.ts.map +1 -0
  210. package/dist/components/ui/form.js +58 -0
  211. package/dist/components/ui/form.js.map +1 -0
  212. package/dist/components/ui/hover-card.d.ts +7 -0
  213. package/dist/components/ui/hover-card.d.ts.map +1 -0
  214. package/dist/components/ui/hover-card.js +14 -0
  215. package/dist/components/ui/hover-card.js.map +1 -0
  216. package/dist/components/ui/input-group.d.ts +17 -0
  217. package/dist/components/ui/input-group.d.ts.map +1 -0
  218. package/dist/components/ui/input-group.js +64 -0
  219. package/dist/components/ui/input-group.js.map +1 -0
  220. package/dist/components/ui/input.d.ts +1 -2
  221. package/dist/components/ui/input.d.ts.map +1 -1
  222. package/dist/components/ui/input.js +3 -5
  223. package/dist/components/ui/input.js.map +1 -1
  224. package/dist/components/ui/label.d.ts +5 -0
  225. package/dist/components/ui/label.d.ts.map +1 -0
  226. package/dist/components/ui/label.js +9 -0
  227. package/dist/components/ui/label.js.map +1 -0
  228. package/dist/components/ui/popover.d.ts +8 -0
  229. package/dist/components/ui/popover.d.ts.map +1 -0
  230. package/dist/components/ui/popover.js +18 -0
  231. package/dist/components/ui/popover.js.map +1 -0
  232. package/dist/components/ui/progress.d.ts +5 -0
  233. package/dist/components/ui/progress.d.ts.map +1 -0
  234. package/dist/components/ui/progress.js +9 -0
  235. package/dist/components/ui/progress.js.map +1 -0
  236. package/dist/components/ui/resizable-provider.d.ts +15 -0
  237. package/dist/components/ui/resizable-provider.d.ts.map +1 -0
  238. package/dist/components/ui/resizable-provider.js +54 -0
  239. package/dist/components/ui/resizable-provider.js.map +1 -0
  240. package/dist/components/ui/resizable.d.ts +9 -0
  241. package/dist/components/ui/resizable.d.ts.map +1 -0
  242. package/dist/components/ui/resizable.js +16 -0
  243. package/dist/components/ui/resizable.js.map +1 -0
  244. package/dist/components/ui/scroll-area.d.ts +6 -0
  245. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  246. package/dist/components/ui/scroll-area.js +11 -0
  247. package/dist/components/ui/scroll-area.js.map +1 -0
  248. package/dist/components/ui/select.d.ts +16 -0
  249. package/dist/components/ui/select.d.ts.map +1 -0
  250. package/dist/components/ui/select.js +39 -0
  251. package/dist/components/ui/select.js.map +1 -0
  252. package/dist/components/ui/separator.d.ts +5 -0
  253. package/dist/components/ui/separator.d.ts.map +1 -0
  254. package/dist/components/ui/separator.js +9 -0
  255. package/dist/components/ui/separator.js.map +1 -0
  256. package/dist/components/ui/switch.d.ts +5 -0
  257. package/dist/components/ui/switch.d.ts.map +1 -0
  258. package/dist/components/ui/switch.js +8 -0
  259. package/dist/components/ui/switch.js.map +1 -0
  260. package/dist/components/ui/tabs.d.ts +8 -0
  261. package/dist/components/ui/tabs.d.ts.map +1 -0
  262. package/dist/components/ui/tabs.js +17 -0
  263. package/dist/components/ui/tabs.js.map +1 -0
  264. package/dist/components/ui/textarea.d.ts +4 -0
  265. package/dist/components/ui/textarea.d.ts.map +1 -0
  266. package/dist/components/ui/textarea.js +7 -0
  267. package/dist/components/ui/textarea.js.map +1 -0
  268. package/dist/components/ui/theme-provider.d.ts +14 -0
  269. package/dist/components/ui/theme-provider.d.ts.map +1 -0
  270. package/dist/components/ui/theme-provider.js +37 -0
  271. package/dist/components/ui/theme-provider.js.map +1 -0
  272. package/dist/components/ui/theme-toggle.d.ts +2 -0
  273. package/dist/components/ui/theme-toggle.d.ts.map +1 -0
  274. package/dist/components/ui/theme-toggle.js +10 -0
  275. package/dist/components/ui/theme-toggle.js.map +1 -0
  276. package/dist/components/ui/toggle.d.ts +10 -0
  277. package/dist/components/ui/toggle.d.ts.map +1 -0
  278. package/dist/components/ui/toggle.js +26 -0
  279. package/dist/components/ui/toggle.js.map +1 -0
  280. package/dist/components/ui/tooltip.d.ts +8 -0
  281. package/dist/components/ui/tooltip.d.ts.map +1 -0
  282. package/dist/components/ui/tooltip.js +17 -0
  283. package/dist/components/ui/tooltip.js.map +1 -0
  284. package/dist/components.d.ts +10 -6
  285. package/dist/components.d.ts.map +1 -1
  286. package/dist/components.js +11 -36
  287. package/dist/components.js.map +1 -1
  288. package/dist/hooks/index.d.ts +6 -0
  289. package/dist/hooks/index.d.ts.map +1 -0
  290. package/dist/hooks/index.js +4 -0
  291. package/dist/hooks/index.js.map +1 -0
  292. package/dist/hooks/useAgentSchemas.d.ts +70 -0
  293. package/dist/hooks/useAgentSchemas.d.ts.map +1 -0
  294. package/dist/hooks/useAgentSchemas.js +90 -0
  295. package/dist/hooks/useAgentSchemas.js.map +1 -0
  296. package/dist/hooks/useWorkbenchSchemas.d.ts +56 -0
  297. package/dist/hooks/useWorkbenchSchemas.d.ts.map +1 -0
  298. package/dist/hooks/useWorkbenchSchemas.js +63 -0
  299. package/dist/hooks/useWorkbenchSchemas.js.map +1 -0
  300. package/dist/hooks/useWorkbenchWebsocket.d.ts +14 -0
  301. package/dist/hooks/useWorkbenchWebsocket.d.ts.map +1 -0
  302. package/dist/hooks/useWorkbenchWebsocket.js +163 -0
  303. package/dist/hooks/useWorkbenchWebsocket.js.map +1 -0
  304. package/dist/index.d.ts +3 -3
  305. package/dist/index.d.ts.map +1 -1
  306. package/dist/index.js +4 -5
  307. package/dist/index.js.map +1 -1
  308. package/dist/server.d.ts +3 -0
  309. package/dist/server.d.ts.map +1 -0
  310. package/dist/server.js +5 -0
  311. package/dist/server.js.map +1 -0
  312. package/dist/styles.css +3423 -196
  313. package/dist/types/config.d.ts +29 -0
  314. package/dist/types/config.d.ts.map +1 -0
  315. package/dist/types/config.js +2 -0
  316. package/dist/types/config.js.map +1 -0
  317. package/dist/types.d.ts +1 -1
  318. package/dist/types.d.ts.map +1 -1
  319. package/dist/workbench.d.ts +1 -2
  320. package/dist/workbench.d.ts.map +1 -1
  321. package/dist/workbench.js +0 -2
  322. package/dist/workbench.js.map +1 -1
  323. package/package.json +50 -7
  324. package/src/components/App.tsx +29 -0
  325. package/src/components/ConnectionStatus.tsx +67 -0
  326. package/src/components/Inline.tsx +16 -0
  327. package/src/components/ai-elements/actions.tsx +60 -0
  328. package/src/components/ai-elements/artifact.tsx +118 -0
  329. package/src/components/ai-elements/branch.tsx +187 -0
  330. package/src/components/ai-elements/canvas.tsx +24 -0
  331. package/src/components/ai-elements/chain-of-thought.tsx +198 -0
  332. package/src/components/ai-elements/code-block.tsx +175 -0
  333. package/src/components/ai-elements/confirmation.tsx +119 -0
  334. package/src/components/ai-elements/connection.tsx +16 -0
  335. package/src/components/ai-elements/context.tsx +357 -0
  336. package/src/components/ai-elements/controls.tsx +18 -0
  337. package/src/components/ai-elements/conversation.tsx +90 -0
  338. package/src/components/ai-elements/edge.tsx +131 -0
  339. package/src/components/ai-elements/image.tsx +16 -0
  340. package/src/components/ai-elements/inline-citation.tsx +246 -0
  341. package/src/components/ai-elements/loader.tsx +88 -0
  342. package/src/components/ai-elements/message.tsx +63 -0
  343. package/src/components/ai-elements/node.tsx +66 -0
  344. package/src/components/ai-elements/open-in-chat.tsx +333 -0
  345. package/src/components/ai-elements/panel.tsx +12 -0
  346. package/src/components/ai-elements/plan.tsx +123 -0
  347. package/src/components/ai-elements/prompt-input.tsx +1203 -0
  348. package/src/components/ai-elements/queue.tsx +231 -0
  349. package/src/components/ai-elements/reasoning.tsx +163 -0
  350. package/src/components/ai-elements/response.tsx +19 -0
  351. package/src/components/ai-elements/shimmer.tsx +53 -0
  352. package/src/components/ai-elements/sources.tsx +53 -0
  353. package/src/components/ai-elements/suggestion.tsx +47 -0
  354. package/src/components/ai-elements/task.tsx +64 -0
  355. package/src/components/ai-elements/tool.tsx +136 -0
  356. package/src/components/ai-elements/toolbar.tsx +13 -0
  357. package/src/components/ai-elements/web-preview.tsx +238 -0
  358. package/src/components/internal/Chat.tsx +183 -0
  359. package/src/components/internal/Header.tsx +77 -0
  360. package/src/components/internal/InputSection.tsx +427 -0
  361. package/src/components/internal/Schema.tsx +111 -0
  362. package/src/components/internal/WorkbenchProvider.tsx +265 -0
  363. package/src/components/internal/logo.tsx +11 -0
  364. package/src/components/ui/alert.tsx +60 -0
  365. package/src/components/ui/avatar.tsx +42 -0
  366. package/src/components/ui/badge.tsx +40 -0
  367. package/src/components/ui/button.tsx +10 -5
  368. package/src/components/ui/card.tsx +4 -1
  369. package/src/components/ui/carousel.tsx +234 -0
  370. package/src/components/ui/checkbox.tsx +27 -0
  371. package/src/components/ui/collapsible.tsx +21 -0
  372. package/src/components/ui/command.tsx +153 -0
  373. package/src/components/ui/dialog.tsx +127 -0
  374. package/src/components/ui/dropdown-menu.tsx +228 -0
  375. package/src/components/ui/field.tsx +234 -0
  376. package/src/components/ui/form.tsx +154 -0
  377. package/src/components/ui/hover-card.tsx +36 -0
  378. package/src/components/ui/input-group.tsx +158 -0
  379. package/src/components/ui/input.tsx +16 -18
  380. package/src/components/ui/label.tsx +21 -0
  381. package/src/components/ui/popover.tsx +42 -0
  382. package/src/components/ui/progress.tsx +28 -0
  383. package/src/components/ui/resizable-provider.tsx +83 -0
  384. package/src/components/ui/resizable.tsx +54 -0
  385. package/src/components/ui/scroll-area.tsx +54 -0
  386. package/src/components/ui/select.tsx +172 -0
  387. package/src/components/ui/separator.tsx +28 -0
  388. package/src/components/ui/switch.tsx +26 -0
  389. package/src/components/ui/tabs.tsx +52 -0
  390. package/src/components/ui/textarea.tsx +18 -0
  391. package/src/components/ui/theme-provider.tsx +71 -0
  392. package/src/components/ui/theme-toggle.tsx +30 -0
  393. package/src/components/ui/toggle.tsx +44 -0
  394. package/src/components/ui/tooltip.tsx +55 -0
  395. package/src/components.tsx +28 -74
  396. package/src/hooks/index.ts +19 -0
  397. package/src/hooks/useAgentSchemas.ts +144 -0
  398. package/src/hooks/useWorkbenchSchemas.ts +69 -0
  399. package/src/hooks/useWorkbenchWebsocket.ts +220 -0
  400. package/src/index.ts +5 -11
  401. package/src/server.ts +6 -0
  402. package/src/styles.css +214 -59
  403. package/src/types/config.ts +34 -0
  404. package/src/types.ts +1 -1
  405. package/src/workbench.ts +1 -4
@@ -0,0 +1,136 @@
1
+ 'use client';
2
+
3
+ import { Badge } from '../ui/badge';
4
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../ui/collapsible';
5
+ import { cn } from '../../lib/utils';
6
+ import type { ToolUIPart } from 'ai';
7
+ import {
8
+ CheckCircleIcon,
9
+ ChevronDownIcon,
10
+ CircleIcon,
11
+ ClockIcon,
12
+ WrenchIcon,
13
+ XCircleIcon,
14
+ } from 'lucide-react';
15
+ import type { ComponentProps, ReactNode } from 'react';
16
+ import { isValidElement } from 'react';
17
+ import { CodeBlock } from './code-block';
18
+
19
+ export type ToolProps = ComponentProps<typeof Collapsible>;
20
+
21
+ export const Tool = ({ className, ...props }: ToolProps) => (
22
+ <Collapsible className={cn('not-prose mb-4 w-full rounded-md border', className)} {...props} />
23
+ );
24
+
25
+ export type ToolHeaderProps = {
26
+ title?: string;
27
+ type: ToolUIPart['type'];
28
+ state: any;
29
+ className?: string;
30
+ };
31
+
32
+ const getStatusBadge = (status: any) => {
33
+ const labels: Record<string, string> = {
34
+ 'input-streaming': 'Pending',
35
+ 'input-available': 'Running',
36
+ 'approval-requested': 'Awaiting Approval',
37
+ 'approval-responded': 'Responded',
38
+ 'output-available': 'Completed',
39
+ 'output-error': 'Error',
40
+ 'output-denied': 'Denied',
41
+ };
42
+
43
+ const icons: Record<string, ReactNode> = {
44
+ 'input-streaming': <CircleIcon className="size-4" />,
45
+ 'input-available': <ClockIcon className="size-4 animate-pulse" />,
46
+ 'approval-requested': <ClockIcon className="size-4 text-yellow-600" />,
47
+ 'approval-responded': <CheckCircleIcon className="size-4 text-blue-600" />,
48
+ 'output-available': <CheckCircleIcon className="size-4 text-green-600" />,
49
+ 'output-error': <XCircleIcon className="size-4 text-red-600" />,
50
+ 'output-denied': <XCircleIcon className="size-4 text-orange-600" />,
51
+ };
52
+
53
+ return (
54
+ <Badge className="gap-1.5 rounded-full text-xs" variant="secondary">
55
+ {icons[status]}
56
+ {labels[status]}
57
+ </Badge>
58
+ );
59
+ };
60
+
61
+ export const ToolHeader = ({ className, title, type, state, ...props }: ToolHeaderProps) => (
62
+ <CollapsibleTrigger
63
+ className={cn('flex w-full items-center justify-between gap-4 p-3', className)}
64
+ {...props}
65
+ >
66
+ <div className="flex items-center gap-2">
67
+ <WrenchIcon className="size-4 text-muted-foreground" />
68
+ <span className="font-medium text-sm">{title ?? type.split('-').slice(1).join('-')}</span>
69
+ {getStatusBadge(state)}
70
+ </div>
71
+ <ChevronDownIcon className="size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
72
+ </CollapsibleTrigger>
73
+ );
74
+
75
+ export type ToolContentProps = ComponentProps<typeof CollapsibleContent>;
76
+
77
+ export const ToolContent = ({ className, ...props }: ToolContentProps) => (
78
+ <CollapsibleContent
79
+ className={cn(
80
+ 'data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in',
81
+ className
82
+ )}
83
+ {...props}
84
+ />
85
+ );
86
+
87
+ export type ToolInputProps = ComponentProps<'div'> & {
88
+ input: ToolUIPart['input'];
89
+ };
90
+
91
+ export const ToolInput = ({ className, input, ...props }: ToolInputProps) => (
92
+ <div className={cn('space-y-2 overflow-hidden p-4', className)} {...props}>
93
+ <h4 className="font-medium text-muted-foreground text-xs uppercase tracking-wide">
94
+ Parameters
95
+ </h4>
96
+ <div className="rounded-md bg-muted/50">
97
+ <CodeBlock code={JSON.stringify(input, null, 2)} language="json" />
98
+ </div>
99
+ </div>
100
+ );
101
+
102
+ export type ToolOutputProps = ComponentProps<'div'> & {
103
+ output: ToolUIPart['output'];
104
+ errorText: ToolUIPart['errorText'];
105
+ };
106
+
107
+ export const ToolOutput = ({ className, output, errorText, ...props }: ToolOutputProps) => {
108
+ if (!(output || errorText)) {
109
+ return null;
110
+ }
111
+
112
+ let Output = <div>{output as ReactNode}</div>;
113
+
114
+ if (typeof output === 'object' && !isValidElement(output)) {
115
+ Output = <CodeBlock code={JSON.stringify(output, null, 2)} language="json" />;
116
+ } else if (typeof output === 'string') {
117
+ Output = <CodeBlock code={output} language="json" />;
118
+ }
119
+
120
+ return (
121
+ <div className={cn('space-y-2 p-4', className)} {...props}>
122
+ <h4 className="font-medium text-muted-foreground text-xs uppercase tracking-wide">
123
+ {errorText ? 'Error' : 'Result'}
124
+ </h4>
125
+ <div
126
+ className={cn(
127
+ 'overflow-x-auto rounded-md text-xs [&_table]:w-full',
128
+ errorText ? 'bg-destructive/10 text-destructive' : 'bg-muted/50 text-foreground'
129
+ )}
130
+ >
131
+ {errorText && <div>{errorText}</div>}
132
+ {Output}
133
+ </div>
134
+ </div>
135
+ );
136
+ };
@@ -0,0 +1,13 @@
1
+ import { cn } from '../../lib/utils';
2
+ import { NodeToolbar, Position } from '@xyflow/react';
3
+ import type { ComponentProps } from 'react';
4
+
5
+ type ToolbarProps = ComponentProps<typeof NodeToolbar>;
6
+
7
+ export const Toolbar = ({ className, ...props }: ToolbarProps) => (
8
+ <NodeToolbar
9
+ className={cn('flex items-center gap-1 rounded-sm border bg-background p-1.5', className)}
10
+ position={Position.Bottom}
11
+ {...props}
12
+ />
13
+ );
@@ -0,0 +1,238 @@
1
+ 'use client';
2
+
3
+ import { Button } from '../ui/button';
4
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../ui/collapsible';
5
+ import { Input } from '../ui/input';
6
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../ui/tooltip';
7
+ import { cn } from '../../lib/utils';
8
+ import { ChevronDownIcon } from 'lucide-react';
9
+ import type { ComponentProps, ReactNode } from 'react';
10
+ import { createContext, useContext, useEffect, useState } from 'react';
11
+
12
+ export type WebPreviewContextValue = {
13
+ url: string;
14
+ setUrl: (url: string) => void;
15
+ consoleOpen: boolean;
16
+ setConsoleOpen: (open: boolean) => void;
17
+ };
18
+
19
+ const WebPreviewContext = createContext<WebPreviewContextValue | null>(null);
20
+
21
+ const useWebPreview = () => {
22
+ const context = useContext(WebPreviewContext);
23
+ if (!context) {
24
+ throw new Error('WebPreview components must be used within a WebPreview');
25
+ }
26
+ return context;
27
+ };
28
+
29
+ export type WebPreviewProps = ComponentProps<'div'> & {
30
+ defaultUrl?: string;
31
+ onUrlChange?: (url: string) => void;
32
+ };
33
+
34
+ export const WebPreview = ({
35
+ className,
36
+ children,
37
+ defaultUrl = '',
38
+ onUrlChange,
39
+ ...props
40
+ }: WebPreviewProps) => {
41
+ const [url, setUrl] = useState(defaultUrl);
42
+ const [consoleOpen, setConsoleOpen] = useState(false);
43
+
44
+ const handleUrlChange = (newUrl: string) => {
45
+ setUrl(newUrl);
46
+ onUrlChange?.(newUrl);
47
+ };
48
+
49
+ const contextValue: WebPreviewContextValue = {
50
+ url,
51
+ setUrl: handleUrlChange,
52
+ consoleOpen,
53
+ setConsoleOpen,
54
+ };
55
+
56
+ return (
57
+ <WebPreviewContext.Provider value={contextValue}>
58
+ <div
59
+ className={cn('flex size-full flex-col rounded-lg border bg-card', className)}
60
+ {...props}
61
+ >
62
+ {children}
63
+ </div>
64
+ </WebPreviewContext.Provider>
65
+ );
66
+ };
67
+
68
+ export type WebPreviewNavigationProps = ComponentProps<'div'>;
69
+
70
+ export const WebPreviewNavigation = ({
71
+ className,
72
+ children,
73
+ ...props
74
+ }: WebPreviewNavigationProps) => (
75
+ <div className={cn('flex items-center gap-1 border-b p-2', className)} {...props}>
76
+ {children}
77
+ </div>
78
+ );
79
+
80
+ export type WebPreviewNavigationButtonProps = ComponentProps<typeof Button> & {
81
+ tooltip?: string;
82
+ };
83
+
84
+ export const WebPreviewNavigationButton = ({
85
+ onClick,
86
+ disabled,
87
+ tooltip,
88
+ children,
89
+ ...props
90
+ }: WebPreviewNavigationButtonProps) => (
91
+ <TooltipProvider>
92
+ <Tooltip>
93
+ <TooltipTrigger asChild>
94
+ <Button
95
+ className="h-8 w-8 p-0 hover:text-foreground"
96
+ disabled={disabled}
97
+ onClick={onClick}
98
+ size="sm"
99
+ variant="ghost"
100
+ {...props}
101
+ >
102
+ {children}
103
+ </Button>
104
+ </TooltipTrigger>
105
+ <TooltipContent>
106
+ <p>{tooltip}</p>
107
+ </TooltipContent>
108
+ </Tooltip>
109
+ </TooltipProvider>
110
+ );
111
+
112
+ export type WebPreviewUrlProps = ComponentProps<typeof Input>;
113
+
114
+ export const WebPreviewUrl = ({ value, onChange, onKeyDown, ...props }: WebPreviewUrlProps) => {
115
+ const { url, setUrl } = useWebPreview();
116
+ const [inputValue, setInputValue] = useState(url);
117
+
118
+ // Sync input value with context URL when it changes externally
119
+ useEffect(() => {
120
+ setInputValue(url);
121
+ }, [url]);
122
+
123
+ const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
124
+ setInputValue(event.target.value);
125
+ onChange?.(event);
126
+ };
127
+
128
+ const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
129
+ if (event.key === 'Enter') {
130
+ const target = event.target as HTMLInputElement;
131
+ setUrl(target.value);
132
+ }
133
+ onKeyDown?.(event);
134
+ };
135
+
136
+ return (
137
+ <Input
138
+ className="h-8 flex-1 text-sm"
139
+ onChange={onChange ?? handleChange}
140
+ onKeyDown={handleKeyDown}
141
+ placeholder="Enter URL..."
142
+ value={value ?? inputValue}
143
+ {...props}
144
+ />
145
+ );
146
+ };
147
+
148
+ export type WebPreviewBodyProps = ComponentProps<'iframe'> & {
149
+ loading?: ReactNode;
150
+ };
151
+
152
+ export const WebPreviewBody = ({ className, loading, src, ...props }: WebPreviewBodyProps) => {
153
+ const { url } = useWebPreview();
154
+
155
+ return (
156
+ <div className="flex-1">
157
+ <iframe
158
+ className={cn('size-full', className)}
159
+ sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-presentation"
160
+ src={(src ?? url) || undefined}
161
+ title="Preview"
162
+ {...props}
163
+ />
164
+ {loading}
165
+ </div>
166
+ );
167
+ };
168
+
169
+ export type WebPreviewConsoleProps = ComponentProps<'div'> & {
170
+ logs?: Array<{
171
+ level: 'log' | 'warn' | 'error';
172
+ message: string;
173
+ timestamp: Date;
174
+ }>;
175
+ };
176
+
177
+ export const WebPreviewConsole = ({
178
+ className,
179
+ logs = [],
180
+ children,
181
+ ...props
182
+ }: WebPreviewConsoleProps) => {
183
+ const { consoleOpen, setConsoleOpen } = useWebPreview();
184
+
185
+ return (
186
+ <Collapsible
187
+ className={cn('border-t bg-muted/50 font-mono text-sm', className)}
188
+ onOpenChange={setConsoleOpen}
189
+ open={consoleOpen}
190
+ {...props}
191
+ >
192
+ <CollapsibleTrigger asChild>
193
+ <Button
194
+ className="flex w-full items-center justify-between p-4 text-left font-medium hover:bg-muted/50"
195
+ variant="ghost"
196
+ >
197
+ Console
198
+ <ChevronDownIcon
199
+ className={cn(
200
+ 'h-4 w-4 transition-transform duration-200',
201
+ consoleOpen && 'rotate-180'
202
+ )}
203
+ />
204
+ </Button>
205
+ </CollapsibleTrigger>
206
+ <CollapsibleContent
207
+ className={cn(
208
+ 'px-4 pb-4',
209
+ 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in'
210
+ )}
211
+ >
212
+ <div className="max-h-48 space-y-1 overflow-y-auto">
213
+ {logs.length === 0 ? (
214
+ <p className="text-muted-foreground">No console output</p>
215
+ ) : (
216
+ logs.map((log, index) => (
217
+ <div
218
+ className={cn(
219
+ 'text-xs',
220
+ log.level === 'error' && 'text-destructive',
221
+ log.level === 'warn' && 'text-yellow-600',
222
+ log.level === 'log' && 'text-foreground'
223
+ )}
224
+ key={`${log.timestamp.getTime()}-${index}`}
225
+ >
226
+ <span className="text-muted-foreground">
227
+ {log.timestamp.toLocaleTimeString()}
228
+ </span>{' '}
229
+ {log.message}
230
+ </div>
231
+ ))
232
+ )}
233
+ {children}
234
+ </div>
235
+ </CollapsibleContent>
236
+ </Collapsible>
237
+ );
238
+ };
@@ -0,0 +1,183 @@
1
+ import '../../styles.css';
2
+ import React, { useState } from 'react';
3
+ import { ChevronRight, Copy, Loader, RefreshCcw } from 'lucide-react';
4
+ import { Action, Actions } from '../ai-elements/actions';
5
+ import {
6
+ Conversation,
7
+ ConversationContent,
8
+ ConversationScrollButton,
9
+ } from '../ai-elements/conversation';
10
+ import { Message, MessageContent } from '../ai-elements/message';
11
+ import { InputSection } from './InputSection';
12
+ import { Shimmer } from '../ai-elements/shimmer';
13
+ import { cn } from '../../lib/utils';
14
+ import { useWorkbench } from './WorkbenchProvider';
15
+ import { Schema } from './Schema';
16
+
17
+ export interface ChatProps {
18
+ className?: string;
19
+ }
20
+
21
+ /**
22
+ * Chat component - conversation and input area (everything except header)
23
+ * Must be used within WorkbenchProvider
24
+ */
25
+ export function Chat({ className: _className }: ChatProps) {
26
+ const {
27
+ agents,
28
+ suggestions,
29
+ messages,
30
+ selectedAgent,
31
+ setSelectedAgent,
32
+ isLoading,
33
+ submitMessage,
34
+ } = useWorkbench();
35
+
36
+ const [value, setValue] = useState('');
37
+ const [schemaOpen, setSchemaOpen] = useState(false);
38
+
39
+ const handleSubmit = async () => {
40
+ const selectedAgentData = agents[selectedAgent];
41
+ const hasInputSchema = selectedAgentData?.schema?.input?.json;
42
+
43
+ // If agent has no input schema, submit without requiring input
44
+ if (!hasInputSchema) {
45
+ await submitMessage('');
46
+ return;
47
+ }
48
+
49
+ // For agents with input schema, require input
50
+ if (!value.trim()) return;
51
+ await submitMessage(value);
52
+ setValue('');
53
+ };
54
+
55
+ return (
56
+ <div className="relative flex flex-1 overflow-hidden">
57
+ <div
58
+ className={cn(
59
+ 'flex flex-col flex-1 transition-all duration-300 ease-in-out min-w-0',
60
+ schemaOpen && 'mr-[600px]'
61
+ )}
62
+ >
63
+ <Conversation className="flex-1 overflow-y-auto">
64
+ <ConversationContent className="pb-0">
65
+ {messages.map(({ role, parts, id }) => {
66
+ const isStreaming = parts.some(
67
+ (part) => part.type === 'text' && part.state === 'streaming'
68
+ );
69
+
70
+ return (
71
+ <div key={id} className="mb-2">
72
+ {role === 'assistant' && (
73
+ <div
74
+ className={cn(
75
+ 'w-fit flex items-center mb-2 text-muted-foreground text-sm transition-colors',
76
+ !isStreaming && 'hover:text-foreground cursor-pointer'
77
+ )}
78
+ >
79
+ <Loader
80
+ className={cn(
81
+ 'size-4 transition-all',
82
+ isStreaming || isLoading ? 'animate-spin mr-2' : 'w-0 mr-2.5'
83
+ )}
84
+ />
85
+
86
+ {isStreaming || isLoading ? (
87
+ <Shimmer duration={1}>Running...</Shimmer>
88
+ ) : (
89
+ <>
90
+ Ran for
91
+ <span className="mx-1">2.9s</span>
92
+ and consumed
93
+ <span className="mx-1">124 tokens</span>
94
+ <ChevronRight className="size-4" />
95
+ </>
96
+ )}
97
+ </div>
98
+ )}
99
+
100
+ {!(isStreaming || isLoading) && (
101
+ <>
102
+ <Message
103
+ key={id}
104
+ from={role as 'user' | 'system' | 'assistant'}
105
+ className="p-0"
106
+ >
107
+ <MessageContent>
108
+ {parts.map((part, index) => {
109
+ switch (part.type) {
110
+ case 'text':
111
+ return (
112
+ <div key={`${id}-${part.text}-${index}`}>
113
+ {part.text || ''}
114
+ </div>
115
+ );
116
+ }
117
+ })}
118
+ </MessageContent>
119
+ </Message>
120
+
121
+ <Actions
122
+ className={cn('mt-1 gap-0', role === 'user' && 'justify-end')}
123
+ >
124
+ {role === 'user' && (
125
+ <Action
126
+ label="Retry"
127
+ className="size-8 hover:bg-transparent!"
128
+ onClick={() =>
129
+ setValue(
130
+ parts
131
+ .filter((part) => part.type === 'text')
132
+ .map((part) => part.text)
133
+ .join('')
134
+ )
135
+ }
136
+ >
137
+ <RefreshCcw className="size-4" />
138
+ </Action>
139
+ )}
140
+
141
+ <Action
142
+ onClick={() =>
143
+ navigator.clipboard.writeText(
144
+ parts
145
+ .filter((part) => part.type === 'text')
146
+ .map((part) => part.text)
147
+ .join('')
148
+ )
149
+ }
150
+ label="Copy"
151
+ className="size-8 hover:bg-transparent!"
152
+ >
153
+ <Copy className="size-4" />
154
+ </Action>
155
+ </Actions>
156
+ </>
157
+ )}
158
+ </div>
159
+ );
160
+ })}
161
+ </ConversationContent>
162
+
163
+ <ConversationScrollButton />
164
+ </Conversation>
165
+ <InputSection
166
+ value={value}
167
+ onChange={setValue}
168
+ onSubmit={handleSubmit}
169
+ isLoading={isLoading}
170
+ agents={agents}
171
+ selectedAgent={selectedAgent}
172
+ setSelectedAgent={setSelectedAgent}
173
+ suggestions={suggestions}
174
+ onSchemaOpen={() => setSchemaOpen(true)}
175
+ />
176
+ </div>
177
+
178
+ <Schema open={schemaOpen} onOpenChange={setSchemaOpen} />
179
+ </div>
180
+ );
181
+ }
182
+
183
+ export default Chat;
@@ -0,0 +1,77 @@
1
+ import React from 'react';
2
+ import { Settings } from 'lucide-react';
3
+ import Logo from './logo';
4
+ import { Button } from '../ui/button';
5
+ import { ThemeToggle } from '../ui/theme-toggle';
6
+ import { useWorkbench } from './WorkbenchProvider';
7
+ import type { ConnectionStatus } from '../../types/config';
8
+
9
+ export interface HeaderProps {
10
+ className?: string;
11
+ }
12
+
13
+ function StatusIndicator({ status }: { status: ConnectionStatus }) {
14
+ if (status === 'connected') {
15
+ return (
16
+ <div className="flex items-center gap-1.5 text-xs text-green-600 dark:text-green-400">
17
+ <div className="w-2 h-2 rounded-full bg-green-500 animate-pulse"></div>
18
+ <span>Connected</span>
19
+ </div>
20
+ );
21
+ }
22
+
23
+ if (status === 'restarting') {
24
+ return (
25
+ <div className="flex items-center gap-1.5 text-xs text-amber-600 dark:text-amber-400">
26
+ <div className="w-2 h-2 rounded-full bg-amber-500 animate-spin"></div>
27
+ <span>Restarting...</span>
28
+ </div>
29
+ );
30
+ }
31
+
32
+ if (status === 'disconnected') {
33
+ return (
34
+ <div className="flex items-center gap-1.5 text-xs text-red-600 dark:text-red-400">
35
+ <div className="w-2 h-2 rounded-full bg-red-500"></div>
36
+ <span>Disconnected</span>
37
+ </div>
38
+ );
39
+ }
40
+
41
+ return null;
42
+ }
43
+
44
+ /**
45
+ * Header component - navigation bar with logo, title, and settings
46
+ * Must be used within WorkbenchProvider
47
+ */
48
+ export function Header({ className }: HeaderProps) {
49
+ const { connectionStatus } = useWorkbench();
50
+ const LogoComponent = Logo;
51
+ const title = 'Workbench';
52
+ const showSettings = true;
53
+
54
+ return (
55
+ <nav
56
+ className={`flex items-center justify-between gap-6 py-2 px-4 border-b ${className || ''}`}
57
+ >
58
+ <div className="flex items-center gap-2.5">
59
+ <LogoComponent />
60
+ <h1 className="mt-0.5 text-sm">{title}</h1>
61
+ </div>
62
+ <div className="flex items-center gap-3">
63
+ <StatusIndicator status={connectionStatus} />
64
+ <div className="flex items-center gap-1">
65
+ <ThemeToggle />
66
+ {showSettings && (
67
+ <Button size="icon" variant="ghost">
68
+ <Settings />
69
+ </Button>
70
+ )}
71
+ </div>
72
+ </div>
73
+ </nav>
74
+ );
75
+ }
76
+
77
+ export default Header;