thursday-agent 0.1.2 → 0.2.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 (358) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +1 -0
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +3 -3
  5. package/.next/routes-manifest.json +6 -0
  6. package/.next/server/app/_global-error/page.js.nft.json +1 -1
  7. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/server/app/_global-error.html +1 -1
  9. package/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  14. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/server/app/_not-found.html +1 -1
  16. package/.next/server/app/_not-found.rsc +13 -13
  17. package/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
  18. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
  19. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  20. package/.next/server/app/api/artifact/route.js +1 -1
  21. package/.next/server/app/api/artifact/route.js.nft.json +1 -1
  22. package/.next/server/app/api/bot/notes/route/app-paths-manifest.json +3 -0
  23. package/.next/server/app/api/bot/notes/route/build-manifest.json +12 -0
  24. package/.next/server/app/api/bot/notes/route/server-reference-manifest.json +4 -0
  25. package/.next/server/app/api/bot/notes/route.js +14 -0
  26. package/.next/server/app/api/bot/notes/route.js.map +5 -0
  27. package/.next/server/app/api/bot/notes/route.js.nft.json +1 -0
  28. package/.next/server/app/api/bot/notes/route_client-reference-manifest.js +3 -0
  29. package/.next/server/app/api/bot/route.js +4 -4
  30. package/.next/server/app/api/bot/route.js.nft.json +1 -1
  31. package/.next/server/app/api/bot/task/[id]/route.js +6 -6
  32. package/.next/server/app/api/bot/task/[id]/route.js.nft.json +1 -1
  33. package/.next/server/app/api/bot/task/route.js +6 -6
  34. package/.next/server/app/api/bot/task/route.js.nft.json +1 -1
  35. package/.next/server/app/api/config/route.js +3 -3
  36. package/.next/server/app/api/config/route.js.nft.json +1 -1
  37. package/.next/server/app/api/events/route.js +1 -1
  38. package/.next/server/app/api/events/route.js.nft.json +1 -1
  39. package/.next/server/app/api/file/[...path]/route.js +1 -1
  40. package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
  41. package/.next/server/app/api/llm-model/catalog/route.js +6 -6
  42. package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
  43. package/.next/server/app/api/llm-model/route.js +3 -3
  44. package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
  45. package/.next/server/app/api/mcp/[name]/route.js +3 -3
  46. package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
  47. package/.next/server/app/api/mcp/oauth/callback/route.js +5 -5
  48. package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
  49. package/.next/server/app/api/mcp/route.js +3 -3
  50. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  51. package/.next/server/app/api/mcp/tools/route.js +3 -3
  52. package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
  53. package/.next/server/app/api/memory/route.js +7 -7
  54. package/.next/server/app/api/memory/route.js.nft.json +1 -1
  55. package/.next/server/app/api/memory/tidy/route.js +10 -11
  56. package/.next/server/app/api/memory/tidy/route.js.nft.json +1 -1
  57. package/.next/server/app/api/skills/[source]/[name]/route.js +1 -1
  58. package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
  59. package/.next/server/app/api/skills/route.js +1 -1
  60. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  61. package/.next/server/app/api/thursday/call/route.js +8 -8
  62. package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
  63. package/.next/server/app/api/thursday/skills/route.js +8 -8
  64. package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
  65. package/.next/server/app/api/thursday/tool-call/route.js +11 -12
  66. package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
  67. package/.next/server/app/api/workspace/route.js +1 -1
  68. package/.next/server/app/api/workspace/route.js.nft.json +1 -1
  69. package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +1 -1
  70. package/.next/server/app/artifact/[...path]/page.js +3 -3
  71. package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
  72. package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
  73. package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  74. package/.next/server/app/page/server-reference-manifest.json +63 -41
  75. package/.next/server/app/page.js +7 -7
  76. package/.next/server/app/page.js.nft.json +1 -1
  77. package/.next/server/app/page_client-reference-manifest.js +1 -1
  78. package/.next/server/app-paths-manifest.json +1 -0
  79. package/.next/server/chunks/0d-b_next_dist_server_app-render_after-task-async-storage_external_0-exn7p.js +3 -0
  80. package/.next/server/chunks/{[root-of-the-server]__0t_dqaj._.js → [root-of-the-server]__0-npkh_._.js} +1 -1
  81. package/.next/server/chunks/[root-of-the-server]__005var5._.js +3 -0
  82. package/.next/server/chunks/[root-of-the-server]__019dx9f._.js +2 -2
  83. package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +3 -0
  84. package/.next/server/chunks/{[root-of-the-server]__1mzp_el._.js → [root-of-the-server]__04_8spk._.js} +2 -2
  85. package/.next/server/chunks/[root-of-the-server]__06t77t4._.js +1 -1
  86. package/.next/server/chunks/[root-of-the-server]__0bed6hu._.js +4 -4
  87. package/.next/server/chunks/[root-of-the-server]__0cro2dz._.js +5 -0
  88. package/.next/server/chunks/[root-of-the-server]__0emr6go._.js +3 -0
  89. package/.next/server/chunks/[root-of-the-server]__0le4d-p._.js +1 -1
  90. package/.next/server/chunks/[root-of-the-server]__0m8ywyo._.js +5 -5
  91. package/.next/server/chunks/{[root-of-the-server]__113fqg5._.js → [root-of-the-server]__0p32jfz._.js} +3 -3
  92. package/.next/server/chunks/[root-of-the-server]__0phdgco._.js +4 -4
  93. package/.next/server/chunks/[root-of-the-server]__0wvgrsl._.js +1 -1
  94. package/.next/server/chunks/[root-of-the-server]__11j52t0._.js +5 -0
  95. package/.next/server/chunks/{[root-of-the-server]__0j_n5l3._.js → [root-of-the-server]__1692zrv._.js} +2 -2
  96. package/.next/server/chunks/[root-of-the-server]__16thabu._.js +1 -1
  97. package/.next/server/chunks/[root-of-the-server]__173nhwf._.js +3 -3
  98. package/.next/server/chunks/[root-of-the-server]__1bn73ih._.js +10 -0
  99. package/.next/server/chunks/[root-of-the-server]__1bqhuh9._.js +4 -4
  100. package/.next/server/chunks/[root-of-the-server]__1ccon1w._.js +10 -0
  101. package/.next/server/chunks/[root-of-the-server]__1cqizfq._.js +1 -1
  102. package/.next/server/chunks/{[root-of-the-server]__1u_qvc7._.js → [root-of-the-server]__1fboj2j._.js} +2 -2
  103. package/.next/server/chunks/{[root-of-the-server]__1dow0bz._.js → [root-of-the-server]__1oli73c._.js} +2 -2
  104. package/.next/server/chunks/[root-of-the-server]__1txedx6._.js +4 -4
  105. package/.next/server/chunks/[root-of-the-server]__1untqv8._.js +5 -0
  106. package/.next/server/chunks/_0-73of8._.js +55 -0
  107. package/.next/server/chunks/{_2050gwn._.js → _00_584r._.js} +66 -28
  108. package/.next/server/chunks/{_0y8is-s._.js → _03a0897._.js} +1 -1
  109. package/.next/server/chunks/_05h2cii._.js +1 -1
  110. package/.next/server/chunks/_06mxlgn._.js +1 -1
  111. package/.next/server/chunks/_0a351g7._.js +1 -1
  112. package/.next/server/chunks/{_0hin38_._.js → _0khihjk._.js} +5 -5
  113. package/.next/server/chunks/_0kjjmag._.js +1 -1
  114. package/.next/server/chunks/{_1t8fv7b._.js → _0n74zsf._.js} +5 -5
  115. package/.next/server/chunks/_0nn99o2._.js +3 -0
  116. package/.next/server/chunks/_0pppbb5._.js +10 -6
  117. package/.next/server/chunks/{_1icgbi8._.js → _0rnf-6n._.js} +5 -5
  118. package/.next/server/chunks/_0u10wmw._.js +55 -0
  119. package/.next/server/chunks/{_0kl37zl._.js → _0vnutv9._.js} +1 -1
  120. package/.next/server/chunks/_0wp4le3._.js +1 -1
  121. package/.next/server/chunks/_0y5fg-x._.js +1 -1
  122. package/.next/server/chunks/_106co2o._.js +3 -0
  123. package/.next/server/chunks/_12bbv5i._.js +10 -6
  124. package/.next/server/chunks/_15hq89o._.js +1 -1
  125. package/.next/server/chunks/_15q1pig._.js +1 -1
  126. package/.next/server/chunks/_18-1wcc._.js +55 -0
  127. package/.next/server/chunks/_19wg5yn._.js +138 -0
  128. package/.next/server/chunks/_1_5mnq4._.js +18 -0
  129. package/.next/server/chunks/_1bt95p9._.js +55 -0
  130. package/.next/server/chunks/_1cbk7ms._.js +9 -9
  131. package/.next/server/chunks/_1drgfx4._.js +18 -0
  132. package/.next/server/chunks/_1drv2et._.js +10 -6
  133. package/.next/server/chunks/{_10qam6o._.js → _1e48czp._.js} +5 -5
  134. package/.next/server/chunks/{_1skgy7b._.js → _1kg70wc._.js} +5 -5
  135. package/.next/server/chunks/_1php4eq._.js +1 -1
  136. package/.next/server/chunks/_1rysr-r._.js +10 -0
  137. package/.next/server/chunks/_1u3rwbr._.js +3 -0
  138. package/.next/server/chunks/_1x7p319._.js +1 -1
  139. package/.next/server/chunks/_1yuv4vp._.js +1 -1
  140. package/.next/server/chunks/_next-internal_server_app_api_bot_notes_route_actions_0qcsyu7.js +3 -0
  141. package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
  142. package/.next/server/chunks/features_bot_task_query_ts_11xuzl3._.js +1 -1
  143. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0228f43._.js → node_modules_consola_dist_chunks_prompt_mjs_02s3hjt._.js} +1 -1
  144. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0ir-vo2._.js → node_modules_consola_dist_chunks_prompt_mjs_06067w6._.js} +1 -1
  145. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0otw8ef._.js → node_modules_consola_dist_chunks_prompt_mjs_096ais_._.js} +1 -1
  146. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0tf290y._.js → node_modules_consola_dist_chunks_prompt_mjs_0a1rd09._.js} +1 -1
  147. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0gzvgfv._.js +3 -0
  148. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0j61-ma._.js +3 -0
  149. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0tvkfgh._.js +3 -0
  150. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_11zjo-1._.js +3 -0
  151. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1pycqsq._.js +3 -0
  152. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1tpvamf._.js +3 -0
  153. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1y9-wcr._.js +3 -0
  154. package/.next/server/chunks/ssr/[externals]__0dizgek._.js +3 -0
  155. package/.next/server/chunks/ssr/[root-of-the-server]__0f6s48x._.js +1 -1
  156. package/.next/server/chunks/ssr/[root-of-the-server]__0m1b5ky._.js +3 -0
  157. package/.next/server/chunks/ssr/{[root-of-the-server]__0dfwvr4._.js → [root-of-the-server]__0un-erv._.js} +2 -2
  158. package/.next/server/chunks/ssr/[root-of-the-server]__1-mnhyd._.js +5 -3
  159. package/.next/server/chunks/ssr/[root-of-the-server]__1bww500._.js +3 -0
  160. package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
  161. package/.next/server/chunks/ssr/[root-of-the-server]__1qfqvmg._.js +3 -0
  162. package/.next/server/chunks/ssr/[root-of-the-server]__1vcdast._.js +3 -0
  163. package/.next/server/chunks/ssr/[root-of-the-server]__1xwnu-h._.js +3 -0
  164. package/.next/server/chunks/ssr/_03webdr._.js +3 -0
  165. package/.next/server/chunks/ssr/{_0gd4vaa._.js → _040sk32._.js} +71 -29
  166. package/.next/server/chunks/ssr/_077-g6s._.js +1 -1
  167. package/.next/server/chunks/ssr/{_0lc_7c8._.js → _09ja_w1._.js} +2 -2
  168. package/.next/server/chunks/ssr/{_1dcxzqe._.js → _0f_b_9s._.js} +2 -2
  169. package/.next/server/chunks/ssr/_0h7zdni._.js +1 -1
  170. package/.next/server/chunks/ssr/_0lu1n_x._.js +3 -0
  171. package/.next/server/chunks/ssr/_0sf1isi._.js +1 -1
  172. package/.next/server/chunks/ssr/_0su6_08._.js +3 -0
  173. package/.next/server/chunks/ssr/{_0nso8tp._.js → _0w5bgak._.js} +2 -2
  174. package/.next/server/chunks/ssr/{_19_o9d-._.js → _0x_nu5e._.js} +2 -2
  175. package/.next/server/chunks/ssr/_1-teee5._.js +3 -3
  176. package/.next/server/chunks/ssr/_13punpm._.js +1 -1
  177. package/.next/server/chunks/ssr/{_0ay6b01._.js → _1ciyoo3._.js} +2 -2
  178. package/.next/server/chunks/ssr/_1e-dgz0._.js +1 -1
  179. package/.next/server/chunks/ssr/_1fq7zgb._.js +1 -1
  180. package/.next/server/chunks/ssr/{_0cvjbuz._.js → _1g6l4uj._.js} +2 -2
  181. package/.next/server/chunks/ssr/{_0q_2f2x._.js → _1lip4th._.js} +2 -2
  182. package/.next/server/chunks/ssr/_1m3bsfr._.js +3 -0
  183. package/.next/server/chunks/ssr/_1mznrxk._.js +1 -1
  184. package/.next/server/chunks/ssr/_1ruzehw._.js +3 -0
  185. package/.next/server/chunks/ssr/_1vyd1ji._.js +3 -0
  186. package/.next/server/chunks/ssr/features_bot_components_bot-setting_tsx_01ajft6._.js +2 -2
  187. package/.next/server/chunks/ssr/features_config_components_14jqgy4._.js +1 -1
  188. package/.next/server/chunks/ssr/features_config_components_config-setting_tsx_0xfwqdg._.js +1 -1
  189. package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
  190. package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +1 -1
  191. package/.next/server/chunks/ssr/lib_realtime_12wg_dd._.js +27 -0
  192. package/.next/server/chunks/ssr/lib_realtime_15h_v1v._.js +27 -0
  193. package/.next/server/chunks/ssr/{node_modules_108wd2o._.js → node_modules_004qlr4._.js} +1 -1
  194. package/.next/server/chunks/ssr/{node_modules_1ub40gk._.js → node_modules_01qnv-a._.js} +1 -1
  195. package/.next/server/chunks/ssr/{node_modules_1y8_3vg._.js → node_modules_04n7mjs._.js} +1 -1
  196. package/.next/server/chunks/ssr/{node_modules_0_j7-g4._.js → node_modules_08d8bke._.js} +1 -1
  197. package/.next/server/chunks/ssr/{node_modules_0y2-av4._.js → node_modules_09xhur7._.js} +1 -1
  198. package/.next/server/chunks/ssr/{node_modules_043-236._.js → node_modules_0_n241r._.js} +1 -1
  199. package/.next/server/chunks/ssr/{node_modules_0ls96je._.js → node_modules_0iz1rzd._.js} +1 -1
  200. package/.next/server/chunks/ssr/{node_modules_0xwx4u-._.js → node_modules_0kl7-tn._.js} +1 -1
  201. package/.next/server/chunks/ssr/{node_modules_1jatz7w._.js → node_modules_0kxz4gt._.js} +1 -1
  202. package/.next/server/chunks/ssr/{node_modules_1t0y5jt._.js → node_modules_0lrjk5t._.js} +1 -1
  203. package/.next/server/chunks/ssr/{node_modules_13f2md6._.js → node_modules_0m93zeg._.js} +1 -1
  204. package/.next/server/chunks/ssr/{node_modules_1nhw9qg._.js → node_modules_0n1kj4p._.js} +1 -1
  205. package/.next/server/chunks/ssr/{node_modules_1k29j1j._.js → node_modules_0ndvxub._.js} +1 -1
  206. package/.next/server/chunks/ssr/{node_modules_16i4o_3._.js → node_modules_13r44jq._.js} +1 -1
  207. package/.next/server/chunks/ssr/{node_modules_0fbw5-u._.js → node_modules_17lrt3y._.js} +1 -1
  208. package/.next/server/chunks/ssr/{node_modules_1d-is1o._.js → node_modules_18_dk7_._.js} +1 -1
  209. package/.next/server/chunks/ssr/{node_modules_1hn_sd5._.js → node_modules_19dp7ko._.js} +1 -1
  210. package/.next/server/chunks/ssr/{node_modules_20ynonm._.js → node_modules_1dwguw_._.js} +1 -1
  211. package/.next/server/chunks/ssr/{node_modules_00d6675._.js → node_modules_1hd-5tv._.js} +1 -1
  212. package/.next/server/chunks/ssr/{node_modules_1ee8gav._.js → node_modules_1hn8z1f._.js} +1 -1
  213. package/.next/server/chunks/ssr/{node_modules_0bue6gy._.js → node_modules_1n5ygqe._.js} +1 -1
  214. package/.next/server/chunks/ssr/{node_modules_1_588_4._.js → node_modules_1q0p85z._.js} +1 -1
  215. package/.next/server/chunks/ssr/{node_modules_0ipn1ho._.js → node_modules_1toafc-._.js} +1 -1
  216. package/.next/server/chunks/ssr/{node_modules_0_fvxnt._.js → node_modules_1xyd7ov._.js} +1 -1
  217. package/.next/server/chunks/ssr/{node_modules_1v0077l._.js → node_modules_1zu988w._.js} +1 -1
  218. package/.next/server/chunks/ssr/{node_modules_06kvvuo._.js → node_modules_20yebtj._.js} +1 -1
  219. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_092s8nx._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0m9a4y0._.js} +1 -1
  220. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1nvexgu._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_13w_wy9._.js} +1 -1
  221. package/.next/server/chunks/ssr/node_modules_consola_dist_chunks_prompt_mjs_05cwqv2._.js +47 -0
  222. package/.next/server/middleware-build-manifest.js +3 -3
  223. package/.next/server/pages/404.html +1 -1
  224. package/.next/server/pages/500.html +1 -1
  225. package/.next/server/server-reference-manifest.js +1 -1
  226. package/.next/server/server-reference-manifest.json +64 -42
  227. package/.next/static/chunks/05b6nx_o3_f_n.js +1 -0
  228. package/.next/static/chunks/{3aquirz5h71da.js → 07kl352c-lvcz.js} +1 -1
  229. package/.next/static/chunks/0dmns-gi0raa4.js +1 -0
  230. package/.next/static/chunks/0oc4_xoia77dg.css +1 -0
  231. package/.next/static/chunks/0pheo8m3a-rzi.js +1 -0
  232. package/.next/static/chunks/{2ihkf6l2jowo9.js → 18vhba44l1fc9.js} +3 -3
  233. package/.next/static/chunks/19i8h2t-5evjx.js +1 -0
  234. package/.next/static/chunks/{1gy3bbv7usnjo.js → 1c5fcj473025q.js} +1 -1
  235. package/.next/static/chunks/1pi_hbmjw-f-z.js +1 -0
  236. package/.next/static/chunks/{0tydnn2kybibk.js → 1twt6k09vg4np.js} +1 -1
  237. package/.next/static/chunks/{21rk8w7bda-su.js → 28gotuisldmom.js} +1 -1
  238. package/.next/static/chunks/{3xxa2j56-f3nm.js → 2998p0y7k1c8z.js} +1 -1
  239. package/.next/static/chunks/2l233xfycjpd8.js +1 -0
  240. package/.next/static/chunks/2p5n7pa3c40t-.js +2 -0
  241. package/.next/static/chunks/2ru1q132af7h7.js +1 -0
  242. package/.next/static/chunks/{2fq_86jvq9ymq.js → 2t8wqycwg3y04.js} +2 -2
  243. package/.next/static/chunks/32z_ypgtchw48.js +1 -0
  244. package/.next/static/chunks/{247d-r95j8xs0.js → 33pyjb3xd1iez.js} +1 -1
  245. package/.next/static/chunks/3786h5vayt80-.js +28 -0
  246. package/.next/static/chunks/3_h9txt3tq8t8.js +28 -0
  247. package/.next/static/chunks/{1khakdu_iuedc.js → 3ard_noqapnw1.js} +1 -1
  248. package/.next/static/chunks/{1fr5m75pwtyic.js → 3omud5xunrk1f.js} +1 -1
  249. package/.next/static/chunks/42dnrkbph9e-1.js +1 -0
  250. package/app/api/events/app-event.client.ts +24 -0
  251. package/app/api/events/app-event.server.ts +45 -0
  252. package/app/api/events/app-event.ts +44 -0
  253. package/app/api/llm-model/catalog/route.ts +12 -0
  254. package/app/api/llm-model/route.ts +21 -0
  255. package/app/api/query-key.ts +144 -0
  256. package/app/api/thursday/tool-call/route.ts +67 -0
  257. package/components/ui/button-group.tsx +45 -0
  258. package/components/ui/custom-icon.tsx +259 -0
  259. package/components/ui/dropdown-menu.tsx +271 -0
  260. package/components/ui/folded-text.tsx +68 -0
  261. package/components/ui/input-group.tsx +157 -0
  262. package/components/ui/json-view.tsx +240 -0
  263. package/components/ui/shiny-text.tsx +141 -0
  264. package/components/ui/text-type.tsx +213 -0
  265. package/components/ui/theme-sync.tsx +9 -0
  266. package/database/migrations/{20260908030742_rainy_marvel_zombies → 20260909060813_optimal_sabretooth}/migration.sql +7 -0
  267. package/database/migrations/{20260908030742_rainy_marvel_zombies → 20260909060813_optimal_sabretooth}/snapshot.json +54 -1
  268. package/database/migrations/20260909063821_bitter_tenebrous/migration.sql +1 -0
  269. package/database/migrations/20260909063821_bitter_tenebrous/snapshot.json +1285 -0
  270. package/docs/how-it-works.md +59 -0
  271. package/docs/images/keeps-going.png +0 -0
  272. package/docs/images/task-thread.png +0 -0
  273. package/docs/images/two-minds.png +0 -0
  274. package/features/ai/load-tools.ts +55 -5
  275. package/features/ai/prompts/bot.prompt.ts +121 -26
  276. package/features/ai/prompts/memory-tidy.prompt.ts +7 -1
  277. package/features/ai/prompts/prompt-helper.ts +31 -5
  278. package/features/ai/prompts/thursday.prompt.ts +2 -0
  279. package/features/ai/tools/bot.tool.ts +37 -18
  280. package/features/ai/tools/mcp.tool.ts +5 -5
  281. package/features/ai/tools/memory.tool.ts +17 -10
  282. package/features/ai/tools/studio.tool.ts +5 -5
  283. package/features/ai/tools/tool-name.ts +2 -0
  284. package/features/ai/tools/workspace.tool.ts +33 -5
  285. package/features/bot/bot.action.ts +31 -4
  286. package/features/bot/bot.notes.ts +120 -0
  287. package/features/bot/bot.query.ts +56 -1
  288. package/features/bot/bot.run.ts +43 -3
  289. package/features/bot/bot.runner.ts +94 -20
  290. package/features/bot/bot.schema.ts +17 -0
  291. package/features/bot/components/bot-room.tsx +405 -306
  292. package/features/bot/components/bot-setting.tsx +123 -20
  293. package/features/bot/task.query.ts +18 -5
  294. package/features/memory/components/memory-setting.tsx +11 -2
  295. package/features/memory/memory.query.ts +9 -2
  296. package/features/memory/memory.schema.ts +30 -0
  297. package/features/skills/components/skills-setting.tsx +9 -1
  298. package/features/workspace/workspace.ts +136 -3
  299. package/hooks/use-draft.ts +37 -0
  300. package/hooks/use-hotkey.ts +105 -0
  301. package/hooks/use-object-state.ts +51 -0
  302. package/hooks/use-on-visible.ts +72 -0
  303. package/hooks/use-theme.ts +106 -0
  304. package/hooks/use-wake-word.ts +262 -0
  305. package/lib/realtime/realtime.driver.ts +34 -1
  306. package/lib/realtime/realtime.protocol.ts +6 -0
  307. package/lib/sandbox.ts +9 -1
  308. package/lib/tokens.ts +19 -0
  309. package/package.json +1 -1
  310. package/.next/server/chunks/[root-of-the-server]__02kt8yn._.js +0 -10
  311. package/.next/server/chunks/[root-of-the-server]__0h59di-._.js +0 -5
  312. package/.next/server/chunks/[root-of-the-server]__0qjqtwo._.js +0 -5
  313. package/.next/server/chunks/[root-of-the-server]__0yk6s3w._.js +0 -5
  314. package/.next/server/chunks/[root-of-the-server]__0z3gelv._.js +0 -3
  315. package/.next/server/chunks/[root-of-the-server]__11w_7_3._.js +0 -3
  316. package/.next/server/chunks/[root-of-the-server]__1_0q_9w._.js +0 -3
  317. package/.next/server/chunks/[root-of-the-server]__1gmn1cs._.js +0 -10
  318. package/.next/server/chunks/_0fzqt2y._.js +0 -100
  319. package/.next/server/chunks/_0jgm3b8._.js +0 -55
  320. package/.next/server/chunks/_0ks6_sg._.js +0 -55
  321. package/.next/server/chunks/_0tzfesa._.js +0 -3
  322. package/.next/server/chunks/_0zmestz._.js +0 -55
  323. package/.next/server/chunks/_12nr4xc._.js +0 -3
  324. package/.next/server/chunks/_1hzrsvg._.js +0 -55
  325. package/.next/server/chunks/_1uj4_io._.js +0 -10
  326. package/.next/server/chunks/_1yldgo4._.js +0 -55
  327. package/.next/server/chunks/features_0scmr4i._.js +0 -3
  328. package/.next/server/chunks/features_bot_bot_query_ts_12mgkl2._.js +0 -3
  329. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0ykklj0._.js +0 -3
  330. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1ryg3wh._.js +0 -3
  331. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1vwbnq_._.js +0 -3
  332. package/.next/server/chunks/ssr/[root-of-the-server]__01id-v3._.js +0 -3
  333. package/.next/server/chunks/ssr/[root-of-the-server]__0b-0i32._.js +0 -3
  334. package/.next/server/chunks/ssr/[root-of-the-server]__185grso._.js +0 -3
  335. package/.next/server/chunks/ssr/[root-of-the-server]__1minz8_._.js +0 -3
  336. package/.next/server/chunks/ssr/_0j4v8of._.js +0 -3
  337. package/.next/server/chunks/ssr/_0l81bzy._.js +0 -3
  338. package/.next/server/chunks/ssr/_10uvw3l._.js +0 -3
  339. package/.next/server/chunks/ssr/_1jbv7m1._.js +0 -3
  340. package/.next/server/chunks/ssr/lib_realtime_0aetuyp._.js +0 -24
  341. package/.next/server/chunks/ssr/lib_realtime_18k_aj-._.js +0 -24
  342. package/.next/server/chunks/ssr/node_modules_zod_v4_classic_errors_05xv7vp.js +0 -3
  343. package/.next/static/chunks/0yysv1gzin17t.js +0 -1
  344. package/.next/static/chunks/1keib_gt066gc.js +0 -1
  345. package/.next/static/chunks/28g42tw8tsvhd.js +0 -1
  346. package/.next/static/chunks/2cwjgkt_hoyhj.js +0 -22
  347. package/.next/static/chunks/2rbf1fpd8n80-.js +0 -22
  348. package/.next/static/chunks/2ukj8k69y89um.js +0 -1
  349. package/.next/static/chunks/2wngeetfnzxkp.js +0 -2
  350. package/.next/static/chunks/388-t2v72jh39.css +0 -1
  351. package/.next/static/chunks/3fqvc0cg-atq_.js +0 -1
  352. package/.next/static/chunks/3p4egvfjxpatb.js +0 -1
  353. package/.next/static/chunks/3qe1w1ei-huhl.js +0 -1
  354. package/.next/static/chunks/3y40riycdip-i.js +0 -1
  355. package/.next/static/chunks/45a6zbtkelph9.js +0 -1
  356. /package/.next/static/{X34BUd9bfdH27ripuwwBm → YR4NWcDDuzwLbTTU7U7Vr}/_buildManifest.js +0 -0
  357. /package/.next/static/{X34BUd9bfdH27ripuwwBm → YR4NWcDDuzwLbTTU7U7Vr}/_clientMiddlewareManifest.js +0 -0
  358. /package/.next/static/{X34BUd9bfdH27ripuwwBm → YR4NWcDDuzwLbTTU7U7Vr}/_ssgManifest.js +0 -0
@@ -0,0 +1,24 @@
1
+ "use client";
2
+
3
+ import { useEffect } from "react";
4
+ import { queryKey } from "@/app/api/query-key";
5
+ import { createEventBus, type EventHandlers } from "@/lib/protocol/events";
6
+ import { fromEventSource, useEventFeed } from "@/lib/protocol/events.client";
7
+ import type { AppEvent } from "./app-event";
8
+
9
+ /** Browser-side bus. Only server events flow here; `emit` is not exported. */
10
+ const bus = createEventBus<AppEvent>();
11
+
12
+ /** Subscribes to server events; pass handlers for the types you care about. */
13
+ export function useAppEvent(handlers: EventHandlers<AppEvent>) {
14
+ useEventFeed(bus, handlers);
15
+ }
16
+
17
+ /**
18
+ * Opens the one connection per tab, from the root layout. EventSource
19
+ * reconnects on its own and replays the on-connect events.
20
+ */
21
+ export function AppEventSource() {
22
+ useEffect(() => fromEventSource(queryKey.events, bus), []);
23
+ return null;
24
+ }
@@ -0,0 +1,45 @@
1
+ import { BROWSER_GONE_MS } from "@/config";
2
+ import { createEventBus, type EventBus } from "@/lib/protocol/events";
3
+ import {
4
+ createEventStream,
5
+ type EventStream,
6
+ } from "@/lib/protocol/events.server";
7
+ import { createPresence, type Presence } from "@/lib/protocol/presence";
8
+ import { type AppEvent, isSignal } from "./app-event";
9
+
10
+ /**
11
+ * Server-side bus and the stream that carries it to the browser. Pinned on
12
+ * globalThis because next dev reloads this module while open streams still
13
+ * subscribe to the first bus.
14
+ */
15
+ type Pinned = {
16
+ __appEvents?: EventBus<AppEvent>;
17
+ __appEventStream?: EventStream<AppEvent>;
18
+ __presence?: Presence;
19
+ __bootId?: string;
20
+ };
21
+ const pinned = globalThis as Pinned;
22
+
23
+ export const appEvents: EventBus<AppEvent> = (pinned.__appEvents ??=
24
+ createEventBus<AppEvent>());
25
+
26
+ /**
27
+ * Whether a browser is on the stream. The app stops what it is doing when the
28
+ * last one has been gone for BROWSER_GONE_MS; who stops what is wired at boot
29
+ * (instrumentation), not here.
30
+ */
31
+ export const presence: Presence = (pinned.__presence ??=
32
+ createPresence(BROWSER_GONE_MS));
33
+
34
+ /** Signals coalesce over 150ms; data events pass through. */
35
+ export const appEventStream: EventStream<AppEvent> =
36
+ (pinned.__appEventStream ??= createEventStream(appEvents, {
37
+ coalesce: {
38
+ ms: 150,
39
+ keyOf: (event) => (isSignal(event) ? event.type : null),
40
+ },
41
+ onWatchers: presence.track,
42
+ }));
43
+
44
+ /** Identifies this server process; changes on restart. */
45
+ export const BOOT_ID: string = (pinned.__bootId ??= crypto.randomUUID());
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Every event the server sends the browser. Two kinds: a signal carries no data
3
+ * and the receiver revalidates the matching GET; a data event is the value
4
+ * itself. A new signal must also be added to `SIGNALS` below.
5
+ */
6
+ export type AppEvent =
7
+ /** Sent on connect. A changed `boot` means the server restarted; re-read everything. */
8
+ | { type: "hello"; boot: string }
9
+ /** Signal: a task changed (every write in bot.query). */
10
+ | { type: "tasks" }
11
+ /** Signal: a note or fact changed. */
12
+ | { type: "memory" }
13
+ /** Signal: a server was registered, removed, synced, or finished OAuth. */
14
+ | { type: "mcp" }
15
+ /** Signal: a read-back started or ended (memory/tidy.query). */
16
+ | { type: "memory-tidy" }
17
+ /** Data: a read-back ended on its own. `tally` is one line of what changed, or why it failed. */
18
+ | { type: "memory-tidied"; failed: boolean; tally: string }
19
+ /** Data: show this note on screen, or hide it when null (memory.tool). */
20
+ | { type: "memory-view"; path: string | null }
21
+ /** Data: a finished job produced a document; `path` is workspace-relative. */
22
+ | { type: "artifact"; taskId: string; label: string; path: string };
23
+
24
+ /** Union members carrying nothing but `type`. */
25
+ type Signal<E = AppEvent> = E extends AppEvent
26
+ ? keyof E extends "type"
27
+ ? E["type"]
28
+ : never
29
+ : never;
30
+
31
+ /**
32
+ * Signals are coalesced before sending (app-event.server). The `Record` type
33
+ * makes a signal missing here a compile error.
34
+ */
35
+ export const SIGNALS: Record<Signal, true> = {
36
+ tasks: true,
37
+ memory: true,
38
+ mcp: true,
39
+ "memory-tidy": true,
40
+ };
41
+
42
+ export const isSignal = (
43
+ event: AppEvent,
44
+ ): event is Extract<AppEvent, { type: Signal }> => event.type in SIGNALS;
@@ -0,0 +1,12 @@
1
+ import { readGatewayCatalog } from "@/features/ai/model";
2
+ import type { GatewayModel } from "@/features/ai/model.schema";
3
+ import { serverRoute } from "@/lib/protocol/server-route";
4
+
5
+ /**
6
+ * Everything the gateway carries, every modality in one listing. It answers
7
+ * unauthenticated, so the shelf reads before a key is set; only running a model
8
+ * needs one. The answer is built in ai/model, where `callableRows` reads the same list.
9
+ */
10
+ export const GET = serverRoute(
11
+ async (): Promise<GatewayModel[]> => readGatewayCatalog(),
12
+ );
@@ -0,0 +1,21 @@
1
+ import {
2
+ type AiProvider,
3
+ TEXT_MODEL_PROVIDER_LIST,
4
+ } from "@/features/ai/model.schema";
5
+ import { readConfig } from "@/features/config/config.query";
6
+ import { serverRoute } from "@/lib/protocol/server-route";
7
+
8
+ /** Callable providers and whether each one's key is set. */
9
+ export const GET = serverRoute(async () =>
10
+ Promise.all(
11
+ TEXT_MODEL_PROVIDER_LIST.map(
12
+ async (item): Promise<AiProvider> => ({
13
+ id: item.id,
14
+ label: item.label,
15
+ apiKeyName: item.apiKeyName,
16
+ suggestModels: item.suggestModels,
17
+ hasKey: Boolean(await readConfig(item.apiKeyName)),
18
+ }),
19
+ ),
20
+ ),
21
+ );
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Every endpoint the browser reads. Keys double as SWR cache keys; `revalidate`
3
+ * matches by url prefix, so invalidating `queryKey.memory` also refreshes
4
+ * `queryKey.notePath(path)`. Writes go through server actions, not here.
5
+ */
6
+ /** Encodes per segment, keeping the path's `/`. */
7
+ const encodePath = (path: string) =>
8
+ path.split("/").map(encodeURIComponent).join("/");
9
+
10
+ /**
11
+ * Inverse of encodePath for catch-all segments. No decoding: Next already
12
+ * decodes segments, and decoding again throws on names containing `%`.
13
+ */
14
+ export const decodePath = (segments: string[]) => segments.join("/");
15
+
16
+ export const queryKey = {
17
+ /** MemoryNote[] first page: pinned first, then by warmth */
18
+ memory: "/api/memory",
19
+ /** Next page; `offset` is the count received so far */
20
+ memoryPage: (offset: number) => ({
21
+ url: "/api/memory",
22
+ query: { offset: offset || null },
23
+ }),
24
+ /** One note with all facts, by path. Paths contain `/`, so it is a query, not a
25
+ * segment: pass the hook null instead of building this key when closed. */
26
+ notePath: (path: string) => ({ url: "/api/memory", query: { path } }),
27
+ /** MemoryTidyStatusView: settings, what is pending, the pass in progress and the last one. Under the memory prefix on purpose: a fact changing moves it too. */
28
+ memoryTidy: "/api/memory/tidy",
29
+
30
+ /** MCPServerSummary[] with tool counts, no tools */
31
+ mcp: "/api/mcp",
32
+ /** MCPServer, one server with its tools */
33
+ mcpServer: (name: string | null) => ({
34
+ url: "/api/mcp",
35
+ pathVariable: [name],
36
+ }),
37
+
38
+ /** Every MCP tool across servers, flat */
39
+ mcpTools: "/api/mcp/tools",
40
+
41
+ /** SkillSummary[], custom first */
42
+ skills: "/api/skills",
43
+ /**
44
+ * SkillNode: a folder listing or a file's text inside a skill.
45
+ * `path` is relative to the skill folder; "" is the skill itself.
46
+ */
47
+ skillNode: (source: string | null, dir: string | null, path: string) => ({
48
+ url: "/api/skills",
49
+ pathVariable: [source, dir],
50
+ query: { path },
51
+ }),
52
+
53
+ /**
54
+ * Bot[]. `tasks` and `taskHistory` sit under this prefix, so editing a bot
55
+ * also revalidates the inbox and loaded history pages.
56
+ */
57
+ bot: "/api/bot",
58
+
59
+ /** boolean: whether bots keep their own instructions (Settings > Bots) */
60
+ botNotes: "/api/bot/notes",
61
+
62
+ /**
63
+ * Inbox: Task[] newest first with threads, everything running or asking plus
64
+ * the most recent finished few. Read by use-thursday only; the `tasks` signal
65
+ * triggers revalidation, with a 30s poll as fallback.
66
+ */
67
+ tasks: "/api/bot/task",
68
+ /**
69
+ * History page: Task[] newest first. `before` is the last page's final
70
+ * updatedAt (ISO), null for the first page.
71
+ */
72
+ taskHistory: (before: string | null) => ({
73
+ url: "/api/bot/task",
74
+ query: { history: 1, before },
75
+ }),
76
+ /** ResultPart[]: the full result of one tool call; lists carry only a few lines. */
77
+ toolResult: (taskId: string | null, callId: string | null) => ({
78
+ url: "/api/bot/task",
79
+ pathVariable: [taskId],
80
+ query: { call: callId },
81
+ }),
82
+ /**
83
+ * WorkspaceFolder: one folder's rows, and nothing below them. The bare key
84
+ * is the root, so invalidating it refreshes every folder.
85
+ */
86
+ workspace: "/api/workspace",
87
+ workspaceFolder: (path: string, rows: number) => ({
88
+ url: "/api/workspace",
89
+ query: { path: path || null, rows },
90
+ }),
91
+
92
+ /**
93
+ * ArtifactShelf: the top of `artifacts/`, one row per artifact.
94
+ * `artifactSet` opens one of those rows. The bare key is the menu, so
95
+ * invalidating it refreshes an open set too.
96
+ */
97
+ artifacts: "/api/artifact",
98
+ artifactShelf: (rows: number) => ({
99
+ url: "/api/artifact",
100
+ query: { rows },
101
+ }),
102
+ artifactSet: (name: string, rows: number) => ({
103
+ url: "/api/artifact",
104
+ query: { set: name, rows },
105
+ }),
106
+
107
+ /** Raw workspace file, no Result envelope; for iframe, img and fetch, not SWR. */
108
+ file: (path: string) => `/api/file/${encodePath(path)}`,
109
+ /** File viewer page (new tab): md rendered, html and pdf framed */
110
+ fileView: (path: string) => `/artifact/${encodePath(path)}`,
111
+
112
+ /**
113
+ * Server-sent events, not a read; only app-event.client's `AppEventSource`
114
+ * opens it. The payloads are the AppEvent union in app/api/events/app-event.ts.
115
+ */
116
+ events: "/api/events",
117
+
118
+ /** ConfigStatus[]: which declared config keys are set; values stay on the server */
119
+ config: "/api/config",
120
+
121
+ /**
122
+ * CallRecord[] page, newest call first, turns in speaking order; pages count
123
+ * calls (CALL_HISTORY_PAGE). `before` is the oldest call's `startedAt` (ISO)
124
+ * on the previous page, null for the first. Calls with no turns are omitted.
125
+ */
126
+ callHistory: (before: string | null) => ({
127
+ url: "/api/thursday/call",
128
+ query: { before },
129
+ }),
130
+
131
+ /** boolean: whether the call may read a skill itself (Settings › Thursday) */
132
+ callSkills: "/api/thursday/skills",
133
+
134
+ /**
135
+ * POST, not a read; the one endpoint here SWR never touches. Body is
136
+ * {toolCallId, callId, name, input}; one JSON Result per call, abortable.
137
+ */
138
+ toolCall: "/api/thursday/tool-call",
139
+
140
+ /** Providers this app can call and whether each key is set */
141
+ llmModel: "/api/llm-model",
142
+ /** Models reachable with the AI Gateway key; gateway only */
143
+ modelCatalog: "/api/llm-model/catalog",
144
+ } as const;
@@ -0,0 +1,67 @@
1
+ import { asSchema } from "ai";
2
+ import z from "zod";
3
+ import { loadTools } from "@/features/ai/load-tools";
4
+ import { modelErrorToString } from "@/features/ai/model";
5
+ import { serverRoute } from "@/lib/protocol/server-route";
6
+ import { publicError } from "@/lib/public-error";
7
+
8
+ /**
9
+ * Executes a tool call from the voice session. The page forwards what the model
10
+ * asked for; bots never come through here (they call `execute` directly).
11
+ * A route rather than a server action because actions run serially per client
12
+ * and one turn may call two tools at once. One POST, one JSON, no streaming;
13
+ * hanging up aborts the fetch and the signal reaches the tool.
14
+ */
15
+
16
+ const ToolCallSchema = z.object({
17
+ toolCallId: z.string().min(1),
18
+ /** The call this came from; `delegate` attaches the job to it. */
19
+ callId: z.string().nullish(),
20
+ name: z.string().min(1),
21
+ input: z.unknown().optional(),
22
+ });
23
+
24
+ const isAsyncIterable = (value: unknown): value is AsyncIterable<unknown> =>
25
+ typeof value === "object" && value !== null && Symbol.asyncIterator in value;
26
+
27
+ /** For streaming tools the last chunk is the answer. */
28
+ async function drain(output: unknown): Promise<unknown> {
29
+ if (!isAsyncIterable(output)) return output;
30
+ let latest: unknown;
31
+ for await (const part of output) latest = part;
32
+ return latest;
33
+ }
34
+
35
+ export const POST = serverRoute(async (request) => {
36
+ const { toolCallId, callId, name, input } = ToolCallSchema.parse(
37
+ await request.json(),
38
+ );
39
+
40
+ // The set the voice runtime may run, not whatever the body names.
41
+ const tools = await loadTools({ target: "thursday", callId });
42
+ const tool = tools[name];
43
+ if (!tool) publicError(`There is no tool called "${name}".`);
44
+
45
+ // end_call has no execute by design: the page owns the call and intercepts it.
46
+ if (!tool.execute) publicError(`"${name}" is handled by the page, not here.`);
47
+
48
+ const parsed = await asSchema(tool.inputSchema).validate?.(input ?? {});
49
+ if (parsed && !parsed.success) {
50
+ publicError(
51
+ `"${name}" got arguments that do not fit: ${parsed.error.message}`,
52
+ );
53
+ }
54
+
55
+ try {
56
+ const output = await tool.execute(parsed?.value ?? input ?? {}, {
57
+ toolCallId,
58
+ messages: [],
59
+ context: undefined,
60
+ abortSignal: request.signal,
61
+ });
62
+ return { output: await drain(output) };
63
+ } catch (cause) {
64
+ // A tool failure is a line the model reads and recovers from, not a masked server error.
65
+ publicError(`"${name}" failed: ${modelErrorToString(cause)}`);
66
+ }
67
+ });
@@ -0,0 +1,45 @@
1
+ "use client";
2
+
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+ import type { ComponentProps } from "react";
5
+ import { cn } from "@/lib/utils";
6
+
7
+ /**
8
+ * Joins plain `<Button>`s into one control (outer corners only, shared 1px
9
+ * seams). Nested groups get a gap between them. For a selected value use
10
+ * `Segmented`.
11
+ */
12
+ const buttonGroupVariants = cva(
13
+ "flex w-fit items-stretch has-[>[data-slot=button-group]]:gap-1.5 [&>*]:relative [&>*]:focus-visible:z-10",
14
+ {
15
+ variants: {
16
+ orientation: {
17
+ horizontal:
18
+ "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
19
+ vertical:
20
+ "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none",
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ orientation: "horizontal",
25
+ },
26
+ },
27
+ );
28
+
29
+ function ButtonGroup({
30
+ className,
31
+ orientation = "horizontal",
32
+ ...props
33
+ }: ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants>) {
34
+ return (
35
+ <div
36
+ data-slot="button-group"
37
+ data-orientation={orientation}
38
+ role="group"
39
+ className={cn(buttonGroupVariants({ orientation }), className)}
40
+ {...props}
41
+ />
42
+ );
43
+ }
44
+
45
+ export { ButtonGroup, buttonGroupVariants };
@@ -0,0 +1,259 @@
1
+ export function MCPIcon({ className }: { className?: string }) {
2
+ return (
3
+ <svg
4
+ aria-hidden="true"
5
+ viewBox="0 0 24 24"
6
+ version="1.1"
7
+ className={className}
8
+ data-view-component="true"
9
+ >
10
+ <path
11
+ fill="currentColor"
12
+ d="M15.688 2.343a2.588 2.588 0 00-3.61 0l-9.626 9.44a.863.863 0 01-1.203 0 .823.823 0 010-1.18l9.626-9.44a4.313 4.313 0 016.016 0 4.116 4.116 0 011.204 3.54 4.3 4.3 0 013.609 1.18l.05.05a4.115 4.115 0 010 5.9l-8.706 8.537a.274.274 0 000 .393l1.788 1.754a.823.823 0 010 1.18.863.863 0 01-1.203 0l-1.788-1.753a1.92 1.92 0 010-2.754l8.706-8.538a2.47 2.47 0 000-3.54l-.05-.049a2.588 2.588 0 00-3.607-.003l-7.172 7.034-.002.002-.098.097a.863.863 0 01-1.204 0 .823.823 0 010-1.18l7.273-7.133a2.47 2.47 0 00-.003-3.537z"
13
+ ></path>
14
+ <path
15
+ fill="currentColor"
16
+ d="M14.485 4.703a.823.823 0 000-1.18.863.863 0 00-1.204 0l-7.119 6.982a4.115 4.115 0 000 5.9 4.314 4.314 0 006.016 0l7.12-6.982a.823.823 0 000-1.18.863.863 0 00-1.204 0l-7.119 6.982a2.588 2.588 0 01-3.61 0 2.47 2.47 0 010-3.54l7.12-6.982z"
17
+ ></path>
18
+ </svg>
19
+ );
20
+ }
21
+
22
+ export function DiscordIcon({ className }: { className?: string }) {
23
+ return (
24
+ <svg
25
+ xmlns="http://www.w3.org/2000/svg"
26
+ width="16"
27
+ height="16"
28
+ fill="currentColor"
29
+ className={className}
30
+ viewBox="0 0 16 16"
31
+ >
32
+ <path d="M13.545 2.907a13.2 13.2 0 0 0-3.257-1.011.05.05 0 0 0-.052.025c-.141.25-.297.577-.406.833a12.2 12.2 0 0 0-3.658 0 8 8 0 0 0-.412-.833.05.05 0 0 0-.052-.025c-1.125.194-2.22.534-3.257 1.011a.04.04 0 0 0-.021.018C.356 6.024-.213 9.047.066 12.032q.003.022.021.037a13.3 13.3 0 0 0 3.995 2.02.05.05 0 0 0 .056-.019q.463-.63.818-1.329a.05.05 0 0 0-.01-.059l-.018-.011a9 9 0 0 1-1.248-.595.05.05 0 0 1-.02-.066l.015-.019q.127-.095.248-.195a.05.05 0 0 1 .051-.007c2.619 1.196 5.454 1.196 8.041 0a.05.05 0 0 1 .053.007q.121.1.248.195a.05.05 0 0 1-.004.085 8 8 0 0 1-1.249.594.05.05 0 0 0-.03.03.05.05 0 0 0 .003.041c.24.465.515.909.817 1.329a.05.05 0 0 0 .056.019 13.2 13.2 0 0 0 4.001-2.02.05.05 0 0 0 .021-.037c.334-3.451-.559-6.449-2.366-9.106a.03.03 0 0 0-.02-.019m-8.198 7.307c-.789 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.45.73 1.438 1.613 0 .888-.637 1.612-1.438 1.612m5.316 0c-.788 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.451.73 1.438 1.613 0 .888-.631 1.612-1.438 1.612" />
33
+ </svg>
34
+ );
35
+ }
36
+
37
+ export function GoogleIcon({ className }: { className?: string }) {
38
+ return (
39
+ <svg
40
+ xmlns="http://www.w3.org/2000/svg"
41
+ height="24"
42
+ viewBox="0 0 24 24"
43
+ className={className}
44
+ width="24"
45
+ >
46
+ <path
47
+ d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
48
+ fill="#4285F4"
49
+ />
50
+ <path
51
+ d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
52
+ fill="#34A853"
53
+ />
54
+ <path
55
+ d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
56
+ fill="#FBBC05"
57
+ />
58
+ <path
59
+ d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
60
+ fill="#EA4335"
61
+ />
62
+ <path d="M1 1h22v22H1z" fill="none" />
63
+ </svg>
64
+ );
65
+ }
66
+
67
+ export function OpenAIIcon({ className }: { className?: string }) {
68
+ return (
69
+ <svg
70
+ aria-hidden="true"
71
+ className={className}
72
+ data-view-component="true"
73
+ viewBox="0 0 24 24"
74
+ role="img"
75
+ xmlns="http://www.w3.org/2000/svg"
76
+ >
77
+ <title>OpenAI icon</title>
78
+ <path
79
+ fill="currentColor"
80
+ d="M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z"
81
+ />
82
+ </svg>
83
+ );
84
+ }
85
+ export function GrokIcon({ className }: { className?: string }) {
86
+ return (
87
+ <svg
88
+ aria-hidden="true"
89
+ className={className}
90
+ data-view-component="true"
91
+ viewBox="0 0 35 33"
92
+ >
93
+ <path
94
+ d="M13.2371 21.0407L24.3186 12.8506C24.8619 12.4491 25.6384 12.6057 25.8973 13.2294C27.2597 16.5185 26.651 20.4712 23.9403 23.1851C21.2297 25.8989 17.4581 26.4941 14.0108 25.1386L10.2449 26.8843C15.6463 30.5806 22.2053 29.6665 26.304 25.5601C29.5551 22.3051 30.562 17.8683 29.6205 13.8673L29.629 13.8758C28.2637 7.99809 29.9647 5.64871 33.449 0.844576C33.5314 0.730667 33.6139 0.616757 33.6964 0.5L29.1113 5.09055V5.07631L13.2343 21.0436"
95
+ fill="currentColor"
96
+ ></path>
97
+ <path
98
+ d="M10.9503 23.0313C7.07343 19.3235 7.74185 13.5853 11.0498 10.2763C13.4959 7.82722 17.5036 6.82767 21.0021 8.2971L24.7595 6.55998C24.0826 6.07017 23.215 5.54334 22.2195 5.17313C17.7198 3.31926 12.3326 4.24192 8.67479 7.90126C5.15635 11.4239 4.0499 16.8403 5.94992 21.4622C7.36924 24.9165 5.04257 27.3598 2.69884 29.826C1.86829 30.7002 1.0349 31.5745 0.36364 32.5L10.9474 23.0341"
99
+ fill="currentColor"
100
+ ></path>
101
+ </svg>
102
+ );
103
+ }
104
+ export function ClaudeIcon({ className }: { className?: string }) {
105
+ return (
106
+ <svg
107
+ overflow="visible"
108
+ width="100%"
109
+ height="100%"
110
+ viewBox="0 0 100 101"
111
+ fill="none"
112
+ className={className}
113
+ xmlns="http://www.w3.org/2000/svg"
114
+ role="presentation"
115
+ >
116
+ <path
117
+ d="M96.0000 40.0000 L99.5002 42.0000 L99.5002 43.5000 L98.5000 47.0000 L56.0000 57.0000 L52.0040 47.0708 L96.0000 40.0000 M96.0000 40.0000 "
118
+ fill="#D97757"
119
+ style={{
120
+ transformOrigin: "50px 50px",
121
+ transform: "rotate(330deg) scaleY(1.13102) rotate(-330deg)",
122
+ }}
123
+ ></path>
124
+ <path
125
+ d="M80.1032 10.5903 L84.9968 11.6171 L86.2958 13.2179 L87.5346 17.0540 L87.0213 19.5007 L58.5000 58.5000 L49.0000 49.0000 L75.3008 14.4873 L80.1032 10.5903 M80.1032 10.5903 "
126
+ fill="#D97757"
127
+ style={{
128
+ transformOrigin: "50px 50px",
129
+ transform: "rotate(300deg) scaleY(1.04936) rotate(-300deg)",
130
+ }}
131
+ ></path>
132
+ <path
133
+ d="M55.5002 4.5000 L58.5005 2.5000 L61.0002 3.5000 L63.5002 7.0000 L56.6511 48.1620 L52.0005 45.0000 L50.0005 39.5000 L53.5003 8.5000 L55.5002 4.5000 M55.5002 4.5000 "
134
+ fill="#D97757"
135
+ style={{
136
+ transformOrigin: "50px 50px",
137
+ transform: "rotate(270deg) scaleY(1.08769) rotate(-270deg)",
138
+ }}
139
+ ></path>
140
+ <path
141
+ d="M23.4253 5.1588 L26.5075 1.2217 L28.5175 0.7632 L32.5063 1.3458 L34.4748 2.8868 L48.8202 34.6902 L54.0089 49.8008 L47.9378 53.1760 L24.8009 11.1886 L23.4253 5.1588 M23.4253 5.1588 "
142
+ fill="#D97757"
143
+ style={{
144
+ transformOrigin: "50px 50px",
145
+ transform: "rotate(240deg) scaleY(0.94) rotate(-240deg)",
146
+ }}
147
+ ></path>
148
+ <path
149
+ d="M8.4990 27.0019 L7.4999 23.0001 L10.5003 19.5001 L14.0003 20.0001 L15.0003 20.0001 L36.0000 35.5000 L42.5000 40.5000 L51.5000 47.5000 L46.5000 56.0000 L42.0002 52.5000 L39.0001 49.5000 L10.0000 29.0001 L8.4990 27.0019 M8.4990 27.0019 "
150
+ fill="#D97757"
151
+ style={{
152
+ transformOrigin: "50px 50px",
153
+ transform: "rotate(210deg) scaleY(0.925) rotate(-210deg)",
154
+ }}
155
+ ></path>
156
+ <path
157
+ d="M2.5003 53.0000 L0.2370 50.5000 L0.2373 48.2759 L2.5003 47.5000 L28.0000 49.0000 L53.0000 51.0000 L52.1885 55.9782 L4.5000 53.5000 L2.5003 53.0000 M2.5003 53.0000 "
158
+ fill="#D97757"
159
+ style={{
160
+ transformOrigin: "50px 50px",
161
+ transform: "rotate(180deg) scaleY(0.997) rotate(-180deg)",
162
+ }}
163
+ ></path>
164
+ <path
165
+ d="M17.5002 79.0264 L12.5005 79.0264 L10.5124 76.7369 L10.5124 74.0000 L19.0005 68.0000 L53.5082 46.0337 L57.0005 52.0000 L17.5002 79.0264 M17.5002 79.0264 "
166
+ fill="#D97757"
167
+ style={{
168
+ transformOrigin: "50px 50px",
169
+ transform: "rotate(150deg) scaleY(1.045) rotate(-150deg)",
170
+ }}
171
+ ></path>
172
+ <path
173
+ d="M27.0004 92.9999 L25.0003 93.4999 L22.0003 91.9999 L22.5004 89.4999 L52.0003 50.5000 L56.0004 55.9999 L34.0003 85.0000 L27.0004 92.9999 M27.0004 92.9999 "
174
+ fill="#D97757"
175
+ style={{
176
+ transformOrigin: "50px 50px",
177
+ transform: "rotate(120deg) scaleY(1.03) rotate(-120deg)",
178
+ }}
179
+ ></path>
180
+ <path
181
+ d="M51.9998 98.0000 L50.5002 100.0000 L47.5002 101.0000 L45.0001 99.0000 L43.5000 96.0000 L51.0003 55.4999 L55.5001 55.9999 L51.9998 98.0000 M51.9998 98.0000 "
182
+ fill="#D97757"
183
+ style={{
184
+ transformOrigin: "50px 50px",
185
+ transform: "rotate(90deg) scaleY(1.06) rotate(-90deg)",
186
+ }}
187
+ ></path>
188
+ <path
189
+ d="M77.5007 86.9997 L77.5007 90.9997 L77.0006 92.4997 L75.0004 93.4997 L71.5006 93.0339 L47.4669 57.2642 L56.9998 50.0002 L64.9994 64.5004 L65.7507 69.7497 L77.5007 86.9997 M77.5007 86.9997 "
190
+ fill="#D97757"
191
+ style={{
192
+ transformOrigin: "50px 50px",
193
+ transform: "rotate(60deg) scaleY(1.00898) rotate(-60deg)",
194
+ }}
195
+ ></path>
196
+ <path
197
+ d="M89.0008 80.9991 L89.5008 83.4991 L88.0008 85.4991 L86.5007 84.9991 L78.0007 78.9991 L65.0007 67.4991 L55.0007 60.4991 L58.0000 51.0000 L62.9999 54.0001 L66.0007 59.4991 L89.0008 80.9991 M89.0008 80.9991 "
198
+ fill="#D97757"
199
+ style={{
200
+ transformOrigin: "50px 50px",
201
+ transform: "rotate(30deg) scaleY(1.13564) rotate(-30deg)",
202
+ }}
203
+ ></path>
204
+ <path
205
+ d="M82.5003 55.5000 L95.0003 56.5000 L98.0003 58.5000 L100.0000 61.5000 L100.0000 63.6587 L94.5003 66.0000 L66.5005 59.0000 L55.0003 58.5000 L58.0000 48.0000 L66.0005 54.0000 L82.5003 55.5000 M82.5003 55.5000 "
206
+ fill="#D97757"
207
+ style={{
208
+ transformOrigin: "50px 50px",
209
+ transform: "rotate(0deg) scaleY(1.27731) rotate(0deg)",
210
+ }}
211
+ ></path>
212
+ </svg>
213
+ );
214
+ }
215
+
216
+ export function ThemeIcon({ className }: { className?: string }) {
217
+ return (
218
+ <svg
219
+ xmlns="http://www.w3.org/2000/svg"
220
+ width="24"
221
+ height="24"
222
+ viewBox="0 0 24 24"
223
+ fill="none"
224
+ stroke="currentColor"
225
+ strokeWidth="2"
226
+ strokeLinecap="round"
227
+ strokeLinejoin="round"
228
+ className={className}
229
+ >
230
+ <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
231
+ <path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0"></path>
232
+ <path d="M12 3l0 18"></path>
233
+ <path d="M12 9l4.65 -4.65"></path>
234
+ <path d="M12 14.3l7.37 -7.37"></path>
235
+ <path d="M12 19.6l8.85 -8.85"></path>
236
+ </svg>
237
+ );
238
+ }
239
+
240
+ export function VercelIcon({ className }: { className?: string }) {
241
+ return (
242
+ <svg
243
+ viewBox="0 0 115 100"
244
+ height="18"
245
+ width="21"
246
+ className={className}
247
+ data-slot="geist-logo-svg"
248
+ >
249
+ <g>
250
+ <path
251
+ fill="currentColor"
252
+ fillRule="evenodd"
253
+ d="M57.5 0 115 100H0z"
254
+ clipRule="evenodd"
255
+ ></path>
256
+ </g>
257
+ </svg>
258
+ );
259
+ }