thursday-agent 0.1.2 → 0.3.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 (573) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +5 -1
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +5 -5
  5. package/.next/routes-manifest.json +27 -3
  6. package/.next/server/app/_global-error/page.js +2 -2
  7. package/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/server/app/_global-error.html +1 -1
  9. package/.next/server/app/_global-error.rsc +2 -2
  10. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  12. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/server/app/_not-found/page.js +2 -2
  14. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  15. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/server/app/_not-found.html +1 -1
  17. package/.next/server/app/_not-found.rsc +14 -14
  18. package/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  19. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
  20. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  21. package/.next/server/app/api/artifact/route.js +3 -3
  22. package/.next/server/app/api/artifact/route.js.nft.json +1 -1
  23. package/.next/server/app/api/bot/memory/files/route/app-paths-manifest.json +3 -0
  24. package/.next/server/app/api/bot/memory/files/route.js +10 -0
  25. package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -0
  26. package/.next/server/app/api/bot/memory/files/route_client-reference-manifest.js +3 -0
  27. package/.next/server/app/api/bot/memory/route/app-paths-manifest.json +3 -0
  28. package/.next/server/app/api/bot/memory/route/build-manifest.json +12 -0
  29. package/.next/server/app/api/bot/memory/route/server-reference-manifest.json +4 -0
  30. package/.next/server/app/api/bot/memory/route.js +14 -0
  31. package/.next/server/app/api/bot/memory/route.js.map +5 -0
  32. package/.next/server/app/api/bot/memory/route.js.nft.json +1 -0
  33. package/.next/server/app/api/bot/memory/route_client-reference-manifest.js +3 -0
  34. package/.next/server/app/api/bot/route.js +7 -7
  35. package/.next/server/app/api/bot/route.js.nft.json +1 -1
  36. package/.next/server/app/api/bot/task/[id]/route.js +9 -9
  37. package/.next/server/app/api/bot/task/[id]/route.js.nft.json +1 -1
  38. package/.next/server/app/api/bot/task/route.js +8 -8
  39. package/.next/server/app/api/bot/task/route.js.nft.json +1 -1
  40. package/.next/server/app/api/config/route.js +6 -6
  41. package/.next/server/app/api/config/route.js.nft.json +1 -1
  42. package/.next/server/app/api/events/route.js +4 -5
  43. package/.next/server/app/api/events/route.js.nft.json +1 -1
  44. package/.next/server/app/api/file/[...path]/route.js +3 -3
  45. package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
  46. package/.next/server/app/api/llm-model/catalog/route.js +10 -9
  47. package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
  48. package/.next/server/app/api/llm-model/credits/route/app-paths-manifest.json +3 -0
  49. package/.next/server/app/api/llm-model/credits/route/build-manifest.json +12 -0
  50. package/.next/server/app/api/llm-model/credits/route/server-reference-manifest.json +4 -0
  51. package/.next/server/app/api/llm-model/credits/route.js +16 -0
  52. package/.next/server/app/api/llm-model/credits/route.js.map +5 -0
  53. package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -0
  54. package/.next/server/app/api/llm-model/credits/route_client-reference-manifest.js +3 -0
  55. package/.next/server/app/api/llm-model/route.js +10 -8
  56. package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
  57. package/.next/server/app/api/llm-model/subscription/route/app-paths-manifest.json +3 -0
  58. package/.next/server/app/api/llm-model/subscription/route/build-manifest.json +12 -0
  59. package/.next/server/app/api/llm-model/subscription/route/server-reference-manifest.json +4 -0
  60. package/.next/server/app/api/llm-model/subscription/route.js +15 -0
  61. package/.next/server/app/api/llm-model/subscription/route.js.map +5 -0
  62. package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -0
  63. package/.next/server/app/api/llm-model/subscription/route_client-reference-manifest.js +3 -0
  64. package/.next/server/app/api/mcp/[name]/route.js +5 -5
  65. package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
  66. package/.next/server/app/api/mcp/oauth/callback/route.js +6 -6
  67. package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
  68. package/.next/server/app/api/mcp/route.js +5 -5
  69. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  70. package/.next/server/app/api/mcp/tools/route.js +5 -5
  71. package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
  72. package/.next/server/app/api/memory/edit/route/app-paths-manifest.json +3 -0
  73. package/.next/server/app/api/memory/edit/route/build-manifest.json +12 -0
  74. package/.next/server/app/api/memory/edit/route/server-reference-manifest.json +4 -0
  75. package/.next/server/app/api/memory/edit/route.js +24 -0
  76. package/.next/server/app/api/memory/edit/route.js.map +5 -0
  77. package/.next/server/app/api/memory/edit/route.js.nft.json +1 -0
  78. package/.next/server/app/api/memory/{tidy → edit}/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/memory/route.js +7 -8
  80. package/.next/server/app/api/memory/route.js.nft.json +1 -1
  81. package/.next/server/app/api/skills/[source]/[name]/route.js +3 -3
  82. package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
  83. package/.next/server/app/api/skills/route.js +3 -3
  84. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  85. package/.next/server/app/api/thursday/call/route.js +9 -7
  86. package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
  87. package/.next/server/app/api/thursday/skills/route.js +9 -7
  88. package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
  89. package/.next/server/app/api/thursday/tool-call/route.js +16 -15
  90. package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
  91. package/.next/server/app/api/workspace/route.js +4 -5
  92. package/.next/server/app/api/workspace/route.js.nft.json +1 -1
  93. package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +1 -1
  94. package/.next/server/app/artifact/[...path]/page.js +5 -6
  95. package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
  96. package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
  97. package/.next/server/app/favicon.ico/route.js +3 -4
  98. package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  99. package/.next/server/app/favicon.ico.body +0 -0
  100. package/.next/server/app/page/server-reference-manifest.json +66 -77
  101. package/.next/server/app/page.js +11 -11
  102. package/.next/server/app/page.js.nft.json +1 -1
  103. package/.next/server/app/page_client-reference-manifest.js +1 -1
  104. package/.next/server/app-paths-manifest.json +5 -1
  105. package/.next/server/chunks/[externals]__0dzuk6_._.js +3 -0
  106. package/.next/server/chunks/[root-of-the-server]__01dkp4a._.js +3 -0
  107. package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +3 -0
  108. package/.next/server/chunks/[root-of-the-server]__02xjoto._.js +3 -0
  109. package/.next/server/chunks/[root-of-the-server]__04q--0f._.js +8 -0
  110. package/.next/server/chunks/[root-of-the-server]__0bl-e63._.js +3 -0
  111. package/.next/server/chunks/[root-of-the-server]__0ce8nf8._.js +5 -0
  112. package/.next/server/chunks/[root-of-the-server]__0ffbg85._.js +3 -0
  113. package/.next/server/chunks/[root-of-the-server]__0j7z0r3._.js +12 -0
  114. package/.next/server/chunks/[root-of-the-server]__0jq4ohy._.js +8 -0
  115. package/.next/server/chunks/[root-of-the-server]__0ls6_8y._.js +8 -0
  116. package/.next/server/chunks/[root-of-the-server]__0ncs9uu._.js +3 -0
  117. package/.next/server/chunks/[root-of-the-server]__0pa2n68._.js +3 -0
  118. package/.next/server/chunks/[root-of-the-server]__0q0vvt2._.js +5 -0
  119. package/.next/server/chunks/[root-of-the-server]__1-ga0kh._.js +5 -0
  120. package/.next/server/chunks/[root-of-the-server]__11n256_._.js +5 -0
  121. package/.next/server/chunks/[root-of-the-server]__12cabg9._.js +3 -0
  122. package/.next/server/chunks/[root-of-the-server]__1339jnv._.js +8 -0
  123. package/.next/server/chunks/[root-of-the-server]__15bjnu5._.js +5 -0
  124. package/.next/server/chunks/[root-of-the-server]__18_teo8._.js +8 -0
  125. package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +5 -0
  126. package/.next/server/chunks/[root-of-the-server]__1anc1p9._.js +3 -0
  127. package/.next/server/chunks/[root-of-the-server]__1ccon1w._.js +10 -0
  128. package/.next/server/chunks/[root-of-the-server]__1fizn31._.js +3 -0
  129. package/.next/server/chunks/[root-of-the-server]__1llj3-b._.js +3 -0
  130. package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +11 -0
  131. package/.next/server/chunks/[root-of-the-server]__1p8m3f4._.js +3 -0
  132. package/.next/server/chunks/[root-of-the-server]__1wa1k7r._.js +8 -0
  133. package/.next/server/chunks/{_1hzrsvg._.js → _0-73of8._.js} +6 -6
  134. package/.next/server/chunks/{_1cbk7ms._.js → _0-fjql4._.js} +10 -10
  135. package/.next/server/chunks/_00xh_q0._.js +27 -0
  136. package/.next/server/chunks/{_0y8is-s._.js → _03a0897._.js} +1 -1
  137. package/.next/server/chunks/{_0pppbb5._.js → _03kp0jp._.js} +166 -35
  138. package/.next/server/chunks/_051qh8u._.js +3 -0
  139. package/.next/server/chunks/{node_modules_next_04q-o58._.js → _05dla15._.js} +2 -2
  140. package/.next/server/chunks/_05h2cii._.js +1 -1
  141. package/.next/server/chunks/_0c9j6rb._.js +49 -0
  142. package/.next/server/chunks/_0fzqt2y._.js +74 -44
  143. package/.next/server/chunks/{_0kl37zl._.js → _0ioz3nd._.js} +1 -1
  144. package/.next/server/chunks/_0iwfby5._.js +3 -0
  145. package/.next/server/chunks/{_0hin38_._.js → _0khihjk._.js} +5 -5
  146. package/.next/server/chunks/_0mecv0f._.js +26 -0
  147. package/.next/server/chunks/_0mh8j4m._.js +3 -0
  148. package/.next/server/chunks/{_1icgbi8._.js → _0n74zsf._.js} +2 -2
  149. package/.next/server/chunks/_0obojvv._.js +3 -0
  150. package/.next/server/chunks/_0recufk._.js +49 -0
  151. package/.next/server/chunks/{_1t8fv7b._.js → _0rnf-6n._.js} +2 -2
  152. package/.next/server/chunks/_0sb7tlz._.js +3 -0
  153. package/.next/server/chunks/{_0jgm3b8._.js → _0u10wmw._.js} +6 -6
  154. package/.next/server/chunks/{_12nr4xc._.js → _0u4aiy2._.js} +2 -2
  155. package/.next/server/chunks/_0wp4le3._.js +1 -1
  156. package/.next/server/chunks/_0y5fg-x._.js +1 -1
  157. package/.next/server/chunks/_1230wbx._.js +10 -0
  158. package/.next/server/chunks/_12nheja._.js +3 -0
  159. package/.next/server/chunks/_13510xh._.js +3 -0
  160. package/.next/server/chunks/_15hq89o._.js +1 -1
  161. package/.next/server/chunks/_17l5ygt._.js +49 -0
  162. package/.next/server/chunks/{_0ks6_sg._.js → _18-1wcc._.js} +6 -6
  163. package/.next/server/chunks/_1_5mnq4._.js +18 -0
  164. package/.next/server/chunks/{_0tzfesa._.js → _1_9mjx-._.js} +1 -1
  165. package/.next/server/chunks/_1d0j961._.js +6 -0
  166. package/.next/server/chunks/_1d5zmy8._.js +1 -1
  167. package/.next/server/chunks/_1drgfx4._.js +18 -0
  168. package/.next/server/chunks/{_1skgy7b._.js → _1e48czp._.js} +5 -5
  169. package/.next/server/chunks/_1f46eie._.js +3 -0
  170. package/.next/server/chunks/_1h5_8sk._.js +3 -0
  171. package/.next/server/chunks/_1hdnxb7._.js +3 -0
  172. package/.next/server/chunks/_1j8k_j5._.js +3 -0
  173. package/.next/server/chunks/{_10qam6o._.js → _1kg70wc._.js} +5 -5
  174. package/.next/server/chunks/_1krd9rf._.js +3 -0
  175. package/.next/server/chunks/_1nc0eui._.js +11 -0
  176. package/.next/server/chunks/_1nula3v._.js +3 -0
  177. package/.next/server/chunks/_1pf4qe-._.js +3 -0
  178. package/.next/server/chunks/_1php4eq._.js +1 -1
  179. package/.next/server/chunks/_1qxheoa._.js +3 -0
  180. package/.next/server/chunks/_1x6kd1r._.js +3 -0
  181. package/.next/server/chunks/_1yuv4vp._.js +1 -1
  182. package/.next/server/chunks/_1zjrdag._.js +3 -0
  183. package/.next/server/chunks/_next-internal_server_app_api_bot_memory_files_route_actions_1_xd_8f.js +3 -0
  184. package/.next/server/chunks/_next-internal_server_app_api_bot_memory_route_actions_1a8xfr7.js +3 -0
  185. package/.next/server/chunks/_next-internal_server_app_api_llm-model_credits_route_actions_0v424pb.js +3 -0
  186. package/.next/server/chunks/_next-internal_server_app_api_llm-model_subscription_route_actions_0-udcm5.js +3 -0
  187. package/.next/server/chunks/_next-internal_server_app_api_memory_edit_route_actions_02sfnmr.js +3 -0
  188. package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
  189. package/.next/server/chunks/features_0rpfxbk._.js +3 -0
  190. package/.next/server/chunks/features_1qf3cei._.js +3 -0
  191. package/.next/server/chunks/features_bot_0zt92oh._.js +3 -0
  192. package/.next/server/chunks/features_bot_bot_query_ts_12mgkl2._.js +1 -1
  193. package/.next/server/chunks/features_memory_1uqvksn._.js +6 -0
  194. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0tf290y._.js → node_modules_consola_dist_chunks_prompt_mjs_0i7cvml._.js} +1 -1
  195. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0228f43._.js → node_modules_consola_dist_chunks_prompt_mjs_0icqaqw._.js} +1 -1
  196. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0ir-vo2._.js → node_modules_consola_dist_chunks_prompt_mjs_0j61-ma._.js} +1 -1
  197. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0otw8ef._.js → node_modules_consola_dist_chunks_prompt_mjs_0r28-sm._.js} +1 -1
  198. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0v_7drq._.js +3 -0
  199. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_11zjo-1._.js +3 -0
  200. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1pycqsq._.js +3 -0
  201. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1xoq2rl._.js +3 -0
  202. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1y49572._.js +3 -0
  203. package/.next/server/chunks/ssr/[externals]__0dizgek._.js +3 -0
  204. package/.next/server/chunks/ssr/[root-of-the-server]__09q9med._.js +1 -1
  205. package/.next/server/chunks/ssr/[root-of-the-server]__0_69wqr._.js +3 -0
  206. package/.next/server/chunks/ssr/[root-of-the-server]__0hg5gib._.js +1 -1
  207. package/.next/server/chunks/ssr/[root-of-the-server]__0i8ie7f._.js +3 -0
  208. package/.next/server/chunks/ssr/{[root-of-the-server]__0jsmmb-._.js → [root-of-the-server]__0mz33a7._.js} +1 -1
  209. package/.next/server/chunks/ssr/[root-of-the-server]__0tbkdlx._.js +3 -0
  210. package/.next/server/chunks/ssr/[root-of-the-server]__0vnmv-s._.js +3 -0
  211. package/.next/server/chunks/ssr/{[root-of-the-server]__0f6s48x._.js → [root-of-the-server]__0xpcv9w._.js} +3 -3
  212. package/.next/server/chunks/ssr/[root-of-the-server]__0xtssj3._.js +1 -1
  213. package/.next/server/chunks/ssr/[root-of-the-server]__0zkv7z_._.js +3 -0
  214. package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +57 -0
  215. package/.next/server/chunks/ssr/[root-of-the-server]__15_uhip._.js +3 -0
  216. package/.next/server/chunks/ssr/[root-of-the-server]__16jc196._.js +1 -1
  217. package/.next/server/chunks/ssr/[root-of-the-server]__1cyjywu._.js +3 -0
  218. package/.next/server/chunks/ssr/[root-of-the-server]__1eh7hid._.js +3 -0
  219. package/.next/server/chunks/ssr/[root-of-the-server]__1gtlw6v._.js +43 -0
  220. package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
  221. package/.next/server/chunks/ssr/[root-of-the-server]__1ox7hbk._.js +4 -0
  222. package/.next/server/chunks/ssr/[root-of-the-server]__1pduf5n._.js +3 -0
  223. package/.next/server/chunks/ssr/{_1mznrxk._.js → _001_ms1._.js} +3 -3
  224. package/.next/server/chunks/ssr/_01_6m32._.js +3 -0
  225. package/.next/server/chunks/ssr/_01n3o0m._.js +3 -0
  226. package/.next/server/chunks/ssr/_07uchnc._.js +3 -0
  227. package/.next/server/chunks/ssr/_0ap2fzn._.js +3 -0
  228. package/.next/server/chunks/ssr/_0c-ql2m._.js +3 -0
  229. package/.next/server/chunks/ssr/_0h42fze._.js +3 -0
  230. package/.next/server/chunks/ssr/_0h7zdni._.js +1 -1
  231. package/.next/server/chunks/ssr/_0i_6q1w._.js +41 -0
  232. package/.next/server/chunks/ssr/_0kbkmar._.js +3 -0
  233. package/.next/server/chunks/ssr/_0lu1n_x._.js +3 -0
  234. package/.next/server/chunks/ssr/{_077-g6s._.js → _0mb8zc8._.js} +3 -3
  235. package/.next/server/chunks/ssr/_0mo2w06._.js +3 -0
  236. package/.next/server/chunks/ssr/{_13punpm._.js → _0q0zan6._.js} +2 -2
  237. package/.next/server/chunks/ssr/{_0gd4vaa._.js → _0u2jv_x._.js} +94 -58
  238. package/.next/server/chunks/ssr/_0y0tiht._.js +4 -0
  239. package/.next/server/chunks/ssr/_0zhoc3r._.js +3 -0
  240. package/.next/server/chunks/ssr/_1-teee5._.js +3 -3
  241. package/.next/server/chunks/ssr/_13fke0x._.js +3 -0
  242. package/.next/server/chunks/ssr/{_0q_2f2x._.js → _13z3f85._.js} +2 -2
  243. package/.next/server/chunks/ssr/_14_lw10._.js +3 -0
  244. package/.next/server/chunks/ssr/_15j2_8f._.js +3 -0
  245. package/.next/server/chunks/ssr/{_0lc_7c8._.js → _1eoqg_g._.js} +2 -2
  246. package/.next/server/chunks/ssr/_1sji22n._.js +3 -0
  247. package/.next/server/chunks/ssr/_1spzm8z._.js +3 -0
  248. package/.next/server/chunks/ssr/{_19_o9d-._.js → _1vi_uo7._.js} +2 -2
  249. package/.next/server/chunks/ssr/_1vyd1ji._.js +3 -0
  250. package/.next/server/chunks/ssr/_1xvgn77._.js +3 -0
  251. package/.next/server/chunks/ssr/_20kd_n0._.js +42 -0
  252. package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +3 -0
  253. package/.next/server/chunks/ssr/features_config_components_config-setting_tsx_0xfwqdg._.js +1 -1
  254. package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
  255. package/.next/server/chunks/ssr/lib_date-like_ts_02is0pw._.js +3 -0
  256. package/.next/server/chunks/ssr/lib_realtime_12wg_dd._.js +27 -0
  257. package/.next/server/chunks/ssr/lib_realtime_15h_v1v._.js +27 -0
  258. package/.next/server/chunks/ssr/{node_modules_1d-is1o._.js → node_modules_063xwpp._.js} +1 -1
  259. package/.next/server/chunks/ssr/{node_modules_1ub40gk._.js → node_modules_0bvraul._.js} +1 -1
  260. package/.next/server/chunks/ssr/{node_modules_1nhw9qg._.js → node_modules_0eu1va6._.js} +1 -1
  261. package/.next/server/chunks/ssr/{node_modules_0xwx4u-._.js → node_modules_0h50b8n._.js} +1 -1
  262. package/.next/server/chunks/ssr/{node_modules_043-236._.js → node_modules_0h5hnr1._.js} +1 -1
  263. package/.next/server/chunks/ssr/{node_modules_1t0y5jt._.js → node_modules_0h7u60n._.js} +1 -1
  264. package/.next/server/chunks/ssr/{node_modules_1k29j1j._.js → node_modules_0lm7_vm._.js} +1 -1
  265. package/.next/server/chunks/ssr/{node_modules_16i4o_3._.js → node_modules_0mwym0g._.js} +1 -1
  266. package/.next/server/chunks/ssr/{node_modules_1y8_3vg._.js → node_modules_0rjg6t1._.js} +1 -1
  267. package/.next/server/chunks/ssr/node_modules_0x3-ply._.js +3 -0
  268. package/.next/server/chunks/ssr/{node_modules_108wd2o._.js → node_modules_0y_cded._.js} +1 -1
  269. package/.next/server/chunks/ssr/{node_modules_1jatz7w._.js → node_modules_0z5tsu8._.js} +1 -1
  270. package/.next/server/chunks/ssr/{node_modules_0ls96je._.js → node_modules_0zp9r92._.js} +1 -1
  271. package/.next/server/chunks/ssr/{node_modules_06kvvuo._.js → node_modules_1-hc6uv._.js} +1 -1
  272. package/.next/server/chunks/ssr/{node_modules_1_588_4._.js → node_modules_113tz0l._.js} +1 -1
  273. package/.next/server/chunks/ssr/{node_modules_0ipn1ho._.js → node_modules_124bue5._.js} +1 -1
  274. package/.next/server/chunks/ssr/node_modules_17bwo43._.js +55 -0
  275. package/.next/server/chunks/ssr/{node_modules_0_j7-g4._.js → node_modules_1_n3ztw._.js} +1 -1
  276. package/.next/server/chunks/ssr/{node_modules_20ynonm._.js → node_modules_1bc7gu8._.js} +1 -1
  277. package/.next/server/chunks/ssr/{node_modules_1hn_sd5._.js → node_modules_1bgb6-f._.js} +1 -1
  278. package/.next/server/chunks/ssr/{node_modules_0bue6gy._.js → node_modules_1h4a4pp._.js} +1 -1
  279. package/.next/server/chunks/ssr/{node_modules_0fbw5-u._.js → node_modules_1i7u1ia._.js} +1 -1
  280. package/.next/server/chunks/ssr/{node_modules_1ee8gav._.js → node_modules_1juq3hs._.js} +1 -1
  281. package/.next/server/chunks/ssr/{node_modules_0_fvxnt._.js → node_modules_1l0qtdu._.js} +1 -1
  282. package/.next/server/chunks/ssr/{node_modules_13f2md6._.js → node_modules_1t9cyee._.js} +1 -1
  283. package/.next/server/chunks/ssr/{node_modules_0y2-av4._.js → node_modules_1uuj9x1._.js} +1 -1
  284. package/.next/server/chunks/ssr/{node_modules_00d6675._.js → node_modules_1vqb6po._.js} +1 -1
  285. package/.next/server/chunks/ssr/{node_modules_1v0077l._.js → node_modules_1xx28h1._.js} +1 -1
  286. 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_0d3skpl._.js} +1 -1
  287. 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_0i44kk5._.js} +1 -1
  288. package/.next/server/chunks/ssr/node_modules_@vercel_oidc_dist_0qe30a_._.js +3 -0
  289. package/.next/server/chunks/ssr/node_modules_consola_dist_chunks_prompt_mjs_05cwqv2._.js +47 -0
  290. package/.next/server/chunks/ssr/{node_modules_next_dist_0w6mzq5._.js → node_modules_next_dist_0drixxt._.js} +4 -4
  291. package/.next/server/chunks/ssr/node_modules_next_dist_1n3w9lb._.js +2 -2
  292. package/.next/server/instrumentation.js +1 -1
  293. package/.next/server/middleware-build-manifest.js +3 -3
  294. package/.next/server/pages/404.html +1 -1
  295. package/.next/server/pages/500.html +1 -1
  296. package/.next/server/server-reference-manifest.js +1 -1
  297. package/.next/server/server-reference-manifest.json +67 -78
  298. package/.next/static/chunks/{31ttnjt6g35a0.js → 0ev4hyghq0mbb.js} +1 -1
  299. package/.next/static/chunks/0r5qcctujhxli.js +1 -0
  300. package/.next/static/chunks/0tmgrnlje14-s.js +3 -0
  301. package/.next/static/chunks/0x79tx04dxbpp.js +1 -0
  302. package/.next/static/chunks/0xzgvc0fkdb6t.js +1 -0
  303. package/.next/static/chunks/10teww7wt-f6h.js +1 -0
  304. package/.next/static/chunks/14hgtsjg-kael.css +1 -0
  305. package/.next/static/chunks/17donp69y4do7.js +40 -0
  306. package/.next/static/chunks/1dkjg87pxk0n9.js +28 -0
  307. package/.next/static/chunks/1ekc7ul556kbl.js +1 -0
  308. package/.next/static/chunks/{1khakdu_iuedc.js → 1grhjo7a5a0_-.js} +1 -1
  309. package/.next/static/chunks/1kq8h8wi_e0bc.js +53 -0
  310. package/.next/static/chunks/1okqiww3pnwka.js +1 -0
  311. package/.next/static/chunks/26-pr2c9ro222.js +1 -0
  312. package/.next/static/chunks/{2ihkf6l2jowo9.js → 280t0_e99i276.js} +3 -3
  313. package/.next/static/chunks/28cizcdaabd4h.js +1 -0
  314. package/.next/static/chunks/2a0k6jlq0_v1u.js +2 -0
  315. package/.next/static/chunks/2fzs9fm8yarvq.js +1 -0
  316. package/.next/static/chunks/2h0sd2vumhb15.js +1 -0
  317. package/.next/static/chunks/2hw2f6zmt7fmt.js +1 -0
  318. package/.next/static/chunks/2t4vhi3m8ahya.js +1 -0
  319. package/.next/static/chunks/2tigdtz3dpcy8.js +1 -0
  320. package/.next/static/chunks/3111pj5wnjgos.js +1 -0
  321. package/.next/static/chunks/3786h5vayt80-.js +28 -0
  322. package/.next/static/chunks/{3aquirz5h71da.js → 3agpgkwaa321p.js} +1 -1
  323. package/.next/static/chunks/3cfi_q6d_wtci.js +1 -0
  324. package/.next/static/chunks/3ok9_x74rip3v.js +1 -0
  325. package/.next/static/chunks/3xk7yqgomx7yq.js +1 -0
  326. package/.next/static/chunks/3xpbkl66ssib5.js +38 -0
  327. package/.next/static/media/favicon.37o1pjldwi2uc.ico +0 -0
  328. package/README.md +6 -4
  329. package/app/api/bot/memory/files/route.ts +14 -0
  330. package/app/api/bot/memory/route.ts +5 -0
  331. package/app/api/events/app-event.client.ts +24 -0
  332. package/app/api/events/app-event.server.ts +45 -0
  333. package/app/api/events/app-event.ts +42 -0
  334. package/app/api/llm-model/catalog/route.ts +12 -0
  335. package/app/api/llm-model/credits/route.ts +11 -0
  336. package/app/api/llm-model/route.ts +26 -0
  337. package/app/api/llm-model/subscription/route.ts +11 -0
  338. package/app/api/memory/edit/route.ts +7 -0
  339. package/app/api/memory/route.ts +21 -0
  340. package/app/api/query-key.ts +159 -0
  341. package/app/api/thursday/tool-call/route.ts +67 -0
  342. package/bin/thursday.mjs +3 -0
  343. package/components/ui/button-group.tsx +45 -0
  344. package/components/ui/custom-icon.tsx +259 -0
  345. package/components/ui/dropdown-menu.tsx +271 -0
  346. package/components/ui/folded-text.tsx +68 -0
  347. package/components/ui/input-group.tsx +157 -0
  348. package/components/ui/json-view.tsx +240 -0
  349. package/components/ui/shiny-text.tsx +55 -0
  350. package/components/ui/text-type.tsx +213 -0
  351. package/components/ui/theme-sync.tsx +9 -0
  352. package/database/migrations/{20260908030742_rainy_marvel_zombies → 20260910173049_numerous_spirit}/migration.sql +30 -33
  353. package/database/migrations/{20260908030742_rainy_marvel_zombies → 20260910173049_numerous_spirit}/snapshot.json +124 -145
  354. package/database/migrations/20260911030320_opposite_jack_power/migration.sql +1 -0
  355. package/database/migrations/20260911030320_opposite_jack_power/snapshot.json +1158 -0
  356. package/docs/how-it-works.md +59 -0
  357. package/docs/images/keeps-going.png +0 -0
  358. package/docs/images/task-thread.png +0 -0
  359. package/docs/images/two-minds.png +0 -0
  360. package/features/ai/chatgpt.ts +617 -0
  361. package/features/ai/components/chatgpt-sign-in.tsx +66 -0
  362. package/features/ai/components/model-picker.tsx +17 -1
  363. package/features/ai/components/provider-icon.tsx +1 -0
  364. package/features/ai/load-tools.ts +105 -39
  365. package/features/ai/model.schema.ts +232 -34
  366. package/features/ai/model.ts +169 -24
  367. package/features/ai/prompts/bot.prompt.ts +245 -59
  368. package/features/ai/prompts/memory-edit.prompt.ts +33 -0
  369. package/features/ai/prompts/prompt-helper.ts +75 -30
  370. package/features/ai/prompts/thursday.prompt.ts +42 -17
  371. package/features/ai/tools/bot.tool.ts +32 -30
  372. package/features/ai/tools/connected.ts +17 -4
  373. package/features/ai/tools/mcp.tool.ts +5 -5
  374. package/features/ai/tools/memory.tool.ts +142 -74
  375. package/features/ai/tools/search.tool.ts +136 -47
  376. package/features/ai/tools/studio.tool.ts +5 -5
  377. package/features/ai/tools/tool-name.ts +2 -3
  378. package/features/ai/tools/workspace.tool.ts +33 -4
  379. package/features/bot/bot.action.ts +24 -7
  380. package/features/bot/bot.memory.ts +89 -0
  381. package/features/bot/bot.query.ts +41 -6
  382. package/features/bot/bot.run.ts +516 -210
  383. package/features/bot/bot.runner.ts +463 -93
  384. package/features/bot/bot.schema.ts +84 -7
  385. package/features/bot/bot.seed.ts +89 -16
  386. package/features/bot/components/bot-mark.tsx +122 -20
  387. package/features/bot/components/bot-room.tsx +519 -391
  388. package/features/bot/components/bot-setting.tsx +832 -341
  389. package/features/bot/components/bot-tool.tsx +2 -6
  390. package/features/bot/components/mark-palette.tsx +54 -0
  391. package/features/bot/components/path-chips.tsx +1 -1
  392. package/features/bot/components/task-badge.tsx +26 -6
  393. package/features/bot/components/task-reply.tsx +22 -33
  394. package/features/bot/components/task-setting.tsx +20 -17
  395. package/features/bot/task.query.ts +233 -33
  396. package/features/bot/task.store.ts +53 -9
  397. package/features/config/components/config-setting.tsx +265 -34
  398. package/features/config/components/models-badge.tsx +42 -0
  399. package/features/config/config.action.ts +12 -0
  400. package/features/config/config.const.ts +38 -2
  401. package/features/connectors/mcp.manager.ts +10 -2
  402. package/features/intro/components/intro.tsx +47 -46
  403. package/features/memory/components/memory-edit.tsx +338 -0
  404. package/features/memory/components/memory-setting.tsx +86 -79
  405. package/features/memory/memory.action.ts +3 -43
  406. package/features/memory/memory.edit.ts +87 -0
  407. package/features/memory/memory.query.ts +33 -44
  408. package/features/memory/memory.schema.ts +50 -97
  409. package/features/settings/components/settings.tsx +2 -0
  410. package/features/settings/settings.alert.ts +3 -1
  411. package/features/skills/components/skills-setting.tsx +9 -1
  412. package/features/thursday/components/ascii-orb.tsx +106 -90
  413. package/features/thursday/components/boot.tsx +7 -0
  414. package/features/thursday/components/call-log.tsx +219 -92
  415. package/features/thursday/components/face.tsx +6 -4
  416. package/features/thursday/components/tab-state.tsx +97 -0
  417. package/features/thursday/components/thursday-mark.tsx +4 -1
  418. package/features/thursday/components/thursday-setting.tsx +17 -47
  419. package/features/thursday/components/thursday.tsx +208 -95
  420. package/features/thursday/thursday.action.ts +12 -17
  421. package/features/thursday/thursday.query.ts +61 -70
  422. package/features/thursday/thursday.schema.ts +20 -7
  423. package/features/thursday/tool-line.ts +85 -11
  424. package/features/thursday/use-thursday.ts +86 -59
  425. package/features/workspace/components/file-view.tsx +4 -2
  426. package/features/workspace/workspace.ts +230 -13
  427. package/hooks/use-draft.ts +37 -0
  428. package/hooks/use-hotkey.ts +105 -0
  429. package/hooks/use-object-state.ts +51 -0
  430. package/hooks/use-on-visible.ts +72 -0
  431. package/hooks/use-theme.ts +106 -0
  432. package/hooks/use-wake-word.ts +262 -0
  433. package/lib/limits.ts +1 -1
  434. package/lib/oauth-page.ts +27 -0
  435. package/lib/realtime/openai.ts +2 -2
  436. package/lib/realtime/realtime.driver.ts +34 -1
  437. package/lib/realtime/realtime.protocol.ts +7 -1
  438. package/lib/realtime/realtime.tap.ts +122 -0
  439. package/lib/sandbox.ts +60 -29
  440. package/lib/tokens.ts +19 -0
  441. package/package.json +1 -1
  442. package/skills/browser/SKILL.md +55 -34
  443. package/.next/server/app/api/memory/tidy/route/app-paths-manifest.json +0 -3
  444. package/.next/server/app/api/memory/tidy/route.js +0 -23
  445. package/.next/server/app/api/memory/tidy/route.js.nft.json +0 -1
  446. package/.next/server/chunks/[root-of-the-server]__019dx9f._.js +0 -5
  447. package/.next/server/chunks/[root-of-the-server]__02_2sm-._.js +0 -5
  448. package/.next/server/chunks/[root-of-the-server]__02kt8yn._.js +0 -10
  449. package/.next/server/chunks/[root-of-the-server]__05luceg._.js +0 -3
  450. package/.next/server/chunks/[root-of-the-server]__06t77t4._.js +0 -11
  451. package/.next/server/chunks/[root-of-the-server]__0bed6hu._.js +0 -8
  452. package/.next/server/chunks/[root-of-the-server]__0dupqt7._.js +0 -5
  453. package/.next/server/chunks/[root-of-the-server]__0h59di-._.js +0 -5
  454. package/.next/server/chunks/[root-of-the-server]__0j_n5l3._.js +0 -3
  455. package/.next/server/chunks/[root-of-the-server]__0le4d-p._.js +0 -3
  456. package/.next/server/chunks/[root-of-the-server]__0m8ywyo._.js +0 -10
  457. package/.next/server/chunks/[root-of-the-server]__0nfuugi._.js +0 -5
  458. package/.next/server/chunks/[root-of-the-server]__0phdgco._.js +0 -8
  459. package/.next/server/chunks/[root-of-the-server]__0qjqtwo._.js +0 -5
  460. package/.next/server/chunks/[root-of-the-server]__0t_dqaj._.js +0 -3
  461. package/.next/server/chunks/[root-of-the-server]__0wvgrsl._.js +0 -3
  462. package/.next/server/chunks/[root-of-the-server]__0yk6s3w._.js +0 -5
  463. package/.next/server/chunks/[root-of-the-server]__0z3gelv._.js +0 -3
  464. package/.next/server/chunks/[root-of-the-server]__10qshki._.js +0 -3
  465. package/.next/server/chunks/[root-of-the-server]__113fqg5._.js +0 -12
  466. package/.next/server/chunks/[root-of-the-server]__11w_7_3._.js +0 -3
  467. package/.next/server/chunks/[root-of-the-server]__16thabu._.js +0 -3
  468. package/.next/server/chunks/[root-of-the-server]__173nhwf._.js +0 -8
  469. package/.next/server/chunks/[root-of-the-server]__1_0q_9w._.js +0 -3
  470. package/.next/server/chunks/[root-of-the-server]__1_aoyr9._.js +0 -3
  471. package/.next/server/chunks/[root-of-the-server]__1bqhuh9._.js +0 -8
  472. package/.next/server/chunks/[root-of-the-server]__1cqizfq._.js +0 -5
  473. package/.next/server/chunks/[root-of-the-server]__1dow0bz._.js +0 -3
  474. package/.next/server/chunks/[root-of-the-server]__1e-ci13._.js +0 -3
  475. package/.next/server/chunks/[root-of-the-server]__1gmn1cs._.js +0 -10
  476. package/.next/server/chunks/[root-of-the-server]__1lr7j9t._.js +0 -5
  477. package/.next/server/chunks/[root-of-the-server]__1mzp_el._.js +0 -3
  478. package/.next/server/chunks/[root-of-the-server]__1txedx6._.js +0 -8
  479. package/.next/server/chunks/[root-of-the-server]__1u_qvc7._.js +0 -3
  480. package/.next/server/chunks/[root-of-the-server]__1zgpz1w._.js +0 -3
  481. package/.next/server/chunks/_012yhfm._.js +0 -39
  482. package/.next/server/chunks/_06mxlgn._.js +0 -3
  483. package/.next/server/chunks/_07rtlxv._.js +0 -3
  484. package/.next/server/chunks/_0a351g7._.js +0 -6
  485. package/.next/server/chunks/_0kjjmag._.js +0 -3
  486. package/.next/server/chunks/_0zmestz._.js +0 -55
  487. package/.next/server/chunks/_0zuzmt_._.js +0 -39
  488. package/.next/server/chunks/_12bbv5i._.js +0 -96
  489. package/.next/server/chunks/_15q1pig._.js +0 -3
  490. package/.next/server/chunks/_1drv2et._.js +0 -36
  491. package/.next/server/chunks/_1ic3bew._.js +0 -5
  492. package/.next/server/chunks/_1mxn_lb._.js +0 -3
  493. package/.next/server/chunks/_1uj4_io._.js +0 -10
  494. package/.next/server/chunks/_1x7p319._.js +0 -6
  495. package/.next/server/chunks/_1yldgo4._.js +0 -55
  496. package/.next/server/chunks/_2050gwn._.js +0 -255
  497. package/.next/server/chunks/_next-internal_server_app_api_memory_tidy_route_actions_0_cfuom.js +0 -3
  498. package/.next/server/chunks/features_0scmr4i._.js +0 -3
  499. package/.next/server/chunks/features_bot_task_query_ts_11xuzl3._.js +0 -3
  500. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0vorg6w._.js +0 -3
  501. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0ykklj0._.js +0 -3
  502. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1ryg3wh._.js +0 -3
  503. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1vmaq9f._.js +0 -3
  504. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1vwbnq_._.js +0 -3
  505. package/.next/server/chunks/ssr/[externals]_node_crypto_1kn79-7._.js +0 -3
  506. package/.next/server/chunks/ssr/[root-of-the-server]__01id-v3._.js +0 -3
  507. package/.next/server/chunks/ssr/[root-of-the-server]__0b-0i32._.js +0 -3
  508. package/.next/server/chunks/ssr/[root-of-the-server]__0dfwvr4._.js +0 -4
  509. package/.next/server/chunks/ssr/[root-of-the-server]__0iuoa-r._.js +0 -3
  510. package/.next/server/chunks/ssr/[root-of-the-server]__1-mnhyd._.js +0 -90
  511. package/.next/server/chunks/ssr/[root-of-the-server]__185grso._.js +0 -3
  512. package/.next/server/chunks/ssr/[root-of-the-server]__1minz8_._.js +0 -3
  513. package/.next/server/chunks/ssr/_0-mc7ro._.js +0 -3
  514. package/.next/server/chunks/ssr/_01p5r6-._.js +0 -3
  515. package/.next/server/chunks/ssr/_09-0k3z._.js +0 -3
  516. package/.next/server/chunks/ssr/_0ay6b01._.js +0 -3
  517. package/.next/server/chunks/ssr/_0cvjbuz._.js +0 -3
  518. package/.next/server/chunks/ssr/_0fafgvl._.js +0 -3
  519. package/.next/server/chunks/ssr/_0j4v8of._.js +0 -3
  520. package/.next/server/chunks/ssr/_0l81bzy._.js +0 -3
  521. package/.next/server/chunks/ssr/_0nso8tp._.js +0 -3
  522. package/.next/server/chunks/ssr/_0sf1isi._.js +0 -3
  523. package/.next/server/chunks/ssr/_0ti51xc._.js +0 -3
  524. package/.next/server/chunks/ssr/_0y84qo6._.js +0 -3
  525. package/.next/server/chunks/ssr/_10uvw3l._.js +0 -3
  526. package/.next/server/chunks/ssr/_1dcxzqe._.js +0 -3
  527. package/.next/server/chunks/ssr/_1e-dgz0._.js +0 -4
  528. package/.next/server/chunks/ssr/_1fq7zgb._.js +0 -3
  529. package/.next/server/chunks/ssr/_1jbv7m1._.js +0 -3
  530. package/.next/server/chunks/ssr/features_bot_components_bot-setting_tsx_01ajft6._.js +0 -4
  531. package/.next/server/chunks/ssr/features_config_components_14jqgy4._.js +0 -3
  532. package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +0 -4
  533. package/.next/server/chunks/ssr/lib_realtime_0aetuyp._.js +0 -24
  534. package/.next/server/chunks/ssr/lib_realtime_18k_aj-._.js +0 -24
  535. package/.next/server/chunks/ssr/node_modules_zod_v4_classic_errors_05xv7vp.js +0 -3
  536. package/.next/server/chunks/ssr/node_modules_zod_v4_classic_external_15fmmz3.js +0 -55
  537. package/.next/static/chunks/0f9sq-7q_yxyl.js +0 -1
  538. package/.next/static/chunks/0tydnn2kybibk.js +0 -1
  539. package/.next/static/chunks/0yysv1gzin17t.js +0 -1
  540. package/.next/static/chunks/1fr5m75pwtyic.js +0 -1
  541. package/.next/static/chunks/1gy3bbv7usnjo.js +0 -1
  542. package/.next/static/chunks/1keib_gt066gc.js +0 -1
  543. package/.next/static/chunks/1ytnip8wdng93.js +0 -1
  544. package/.next/static/chunks/21rk8w7bda-su.js +0 -1
  545. package/.next/static/chunks/247d-r95j8xs0.js +0 -1
  546. package/.next/static/chunks/28g42tw8tsvhd.js +0 -1
  547. package/.next/static/chunks/29gyb3nubj51j.js +0 -53
  548. package/.next/static/chunks/2cwjgkt_hoyhj.js +0 -22
  549. package/.next/static/chunks/2fq_86jvq9ymq.js +0 -2
  550. package/.next/static/chunks/2rbf1fpd8n80-.js +0 -22
  551. package/.next/static/chunks/2ukj8k69y89um.js +0 -1
  552. package/.next/static/chunks/2uxum7qbyeyxd.js +0 -1
  553. package/.next/static/chunks/2wngeetfnzxkp.js +0 -2
  554. package/.next/static/chunks/388-t2v72jh39.css +0 -1
  555. package/.next/static/chunks/3fqvc0cg-atq_.js +0 -1
  556. package/.next/static/chunks/3p4egvfjxpatb.js +0 -1
  557. package/.next/static/chunks/3qe1w1ei-huhl.js +0 -1
  558. package/.next/static/chunks/3xxa2j56-f3nm.js +0 -3
  559. package/.next/static/chunks/3y40riycdip-i.js +0 -1
  560. package/.next/static/chunks/45a6zbtkelph9.js +0 -1
  561. package/.next/static/media/favicon.2vob68tjqpejf.ico +0 -0
  562. package/features/ai/prompts/memory-tidy.prompt.ts +0 -123
  563. package/features/ai/tools/tidy.tool.ts +0 -22
  564. package/features/memory/components/memory-tidy.tsx +0 -395
  565. package/features/memory/memory.tidy.ts +0 -332
  566. package/features/memory/tidy.query.ts +0 -135
  567. package/features/thursday/use-call-title.ts +0 -31
  568. /package/.next/server/app/api/{memory/tidy → bot/memory/files}/route/build-manifest.json +0 -0
  569. /package/.next/server/app/api/{memory/tidy → bot/memory/files}/route/server-reference-manifest.json +0 -0
  570. /package/.next/server/app/api/{memory/tidy → bot/memory/files}/route.js.map +0 -0
  571. /package/.next/static/{X34BUd9bfdH27ripuwwBm → x1cCqY0kWpR_VcYx_lWO5}/_buildManifest.js +0 -0
  572. /package/.next/static/{X34BUd9bfdH27ripuwwBm → x1cCqY0kWpR_VcYx_lWO5}/_clientMiddlewareManifest.js +0 -0
  573. /package/.next/static/{X34BUd9bfdH27ripuwwBm → x1cCqY0kWpR_VcYx_lWO5}/_ssgManifest.js +0 -0
@@ -12,16 +12,16 @@ import { Combobox } from "@/components/ui/combobox";
12
12
  import { Input } from "@/components/ui/input";
13
13
  import { notify } from "@/components/ui/notify";
14
14
  import { Segmented } from "@/components/ui/segmented";
15
- import { Swatch } from "@/components/ui/swatch";
16
15
  import { Textarea } from "@/components/ui/textarea";
16
+ import { ASCII_FACE } from "@/config";
17
17
  import { ProviderIcon } from "@/features/ai/components/provider-icon";
18
18
  import {
19
19
  type AiProvider,
20
20
  SPEACH_MODEL_PROVIDER_LIST,
21
21
  type SpeachModelRef,
22
22
  } from "@/features/ai/model.schema";
23
- import { MARK_PALETTE_ROWS, MARK_SHAPES } from "@/features/bot/mark.const";
24
- import { TidySetting } from "@/features/memory/components/memory-tidy";
23
+ import { MarkPalette } from "@/features/bot/components/mark-palette";
24
+ import { MARK_SHAPES } from "@/features/bot/mark.const";
25
25
  import {
26
26
  SettingChoiceRows,
27
27
  SettingError,
@@ -149,13 +149,10 @@ export function ThursdaySetting() {
149
149
  onChange={(hotkey) => patch({ hotkey })}
150
150
  />
151
151
 
152
- {/* The last two are server-side, unlike everything above them: the tool set
153
- is built where a call opens (ai/load-tools) and the pass runs without a
154
- browser (memory.tidy) */}
152
+ {/* Server-side, unlike everything above it: the tool set is built where a
153
+ call opens (ai/load-tools) */}
155
154
  <SkillsSetting />
156
155
 
157
- <TidySetting />
158
-
159
156
  <Instructions
160
157
  value={thursday.systemPrompt ?? ""}
161
158
  onSave={(systemPrompt) => patch({ systemPrompt })}
@@ -220,7 +217,7 @@ function ResetHistory() {
220
217
  okMessage: ({ calls, tasks, notes }) =>
221
218
  `Wiped ${calls} calls, ${tasks} jobs, ${notes} notes`,
222
219
  onOk: () => {
223
- // Prefix match, so the tidy log and every loaded history page go too.
220
+ // Prefix match, so every loaded history page goes too.
224
221
  revalidate(queryKey.memory);
225
222
  revalidate(queryKey.tasks);
226
223
  revalidate(queryKey.callHistory(null));
@@ -303,41 +300,14 @@ function FacePicker({
303
300
  </p>
304
301
  </div>
305
302
 
306
- {/* Only the mark takes a color; the orb follows the theme (OrbFace ignores it).
307
- Rows break where the palette breaks (MARK_PALETTE_ROWS); the theme dot stands apart. */}
303
+ {/* Only the mark takes a color; the orb follows the theme (OrbFace ignores it). */}
308
304
  {value.kind === "mark" && (
309
- // both rows center as one block and left-align inside it
310
- <div className="flex justify-center px-2">
311
- <div className="flex flex-col gap-2.5">
312
- <div className="flex flex-wrap items-center gap-2">
313
- <Swatch
314
- color={null}
315
- picked={!value.color}
316
- onPick={() => patch({ color: undefined })}
317
- />
318
- <span className="w-2" />
319
- {MARK_PALETTE_ROWS[0].map((color) => (
320
- <Swatch
321
- key={color}
322
- color={color}
323
- picked={value.color === color}
324
- onPick={() => patch({ color })}
325
- />
326
- ))}
327
- </div>
328
- {/* indent by the theme dot and its gap so the dark row lines up under the first light color */}
329
- <div className="flex flex-wrap items-center gap-2 pl-9">
330
- {MARK_PALETTE_ROWS[1].map((color) => (
331
- <Swatch
332
- key={color}
333
- color={color}
334
- picked={value.color === color}
335
- onPick={() => patch({ color })}
336
- />
337
- ))}
338
- </div>
339
- </div>
340
- </div>
305
+ <MarkPalette
306
+ color={value.color}
307
+ themePicked={!value.color}
308
+ onTheme={() => patch({ color: undefined })}
309
+ onPick={(color) => patch({ color })}
310
+ />
341
311
  )}
342
312
 
343
313
  {value.kind === "mark" && (
@@ -386,8 +356,8 @@ function FacePicker({
386
356
 
387
357
  <Row label="Size">
388
358
  <Slider
389
- min={4}
390
- max={16}
359
+ min={ASCII_FACE.fontSize.min}
360
+ max={ASCII_FACE.fontSize.max}
391
361
  step={1}
392
362
  value={value.fontSize}
393
363
  format={(n) => `${n}px`}
@@ -397,8 +367,8 @@ function FacePicker({
397
367
 
398
368
  <Row label="Density">
399
369
  <Slider
400
- min={0.6}
401
- max={2}
370
+ min={ASCII_FACE.density.min}
371
+ max={ASCII_FACE.density.max}
402
372
  step={0.1}
403
373
  value={value.density}
404
374
  format={(n) => `${n.toFixed(1)}x`}
@@ -4,7 +4,7 @@ import {
4
4
  ChevronDown,
5
5
  ChevronUp,
6
6
  Flag,
7
- Loader2,
7
+ type LucideIcon,
8
8
  Mic,
9
9
  MicOff,
10
10
  Settings2,
@@ -13,7 +13,7 @@ import { type ReactNode, useEffect, useRef, useState } from "react";
13
13
  import { queryKey } from "@/app/api/query-key";
14
14
  import { Button } from "@/components/ui/button";
15
15
  import { ButtonGroup } from "@/components/ui/button-group";
16
- import ShinyText from "@/components/ui/shiny-text";
16
+ import { ShinyText } from "@/components/ui/shiny-text";
17
17
  import TextType from "@/components/ui/text-type";
18
18
  import {
19
19
  Tooltip,
@@ -22,14 +22,13 @@ import {
22
22
  TooltipTrigger,
23
23
  } from "@/components/ui/tooltip";
24
24
  import { SPEACH_MODEL_PROVIDER_LIST } from "@/features/ai/model.schema";
25
- import { DEFAULT_BOT } from "@/features/bot/bot.schema";
25
+ import { type Bot, DEFAULT_BOT } from "@/features/bot/bot.schema";
26
26
  import { BotMark } from "@/features/bot/components/bot-mark";
27
27
  import { BotRoom } from "@/features/bot/components/bot-room";
28
28
  import { toolIcon } from "@/features/bot/components/bot-tool";
29
29
  import { installSeedBots } from "@/features/bot/seed-bots";
30
30
  import { VoiceKeys } from "@/features/config/components/voice-key";
31
31
  import { type ConfigStatus, isConfigSet } from "@/features/config/config.const";
32
- import { MemoryTidyNotice } from "@/features/memory/components/memory-tidy";
33
32
  import { MemoryView } from "@/features/memory/components/memory-view";
34
33
  import { SECTIONS, Settings } from "@/features/settings/components/settings";
35
34
  import {
@@ -47,13 +46,13 @@ import {
47
46
  type ThursdayFace,
48
47
  } from "@/features/thursday/thursday.schema";
49
48
  import { useThursdayStore } from "@/features/thursday/thursday.store";
50
- import { useCallTitle } from "@/features/thursday/use-call-title";
51
49
  import { type ToolRun, useThursday } from "@/features/thursday/use-thursday";
52
50
  import { ArtifactView } from "@/features/workspace/components/artifact-view";
53
51
  import { useHotkeyLabel } from "@/hooks/use-hotkey";
54
52
  import { useServerRoute } from "@/lib/protocol/use-server-route";
55
53
  import { cn } from "@/lib/utils";
56
54
  import { Face } from "./face";
55
+ import { TabState } from "./tab-state";
57
56
 
58
57
  /**
59
58
  * The call screen. The face is the only control; text stays beside it and is
@@ -115,6 +114,7 @@ export function CallScreen({
115
114
  const hers =
116
115
  messages.findLast((turn) => turn.role === "assistant")?.text ?? "";
117
116
  const sided = captionView === "sides" && status !== "idle";
117
+ const turns = useTurnPager(messages);
118
118
  return (
119
119
  <div className="relative flex h-full flex-col">
120
120
  <div className="absolute top-5 right-5 z-10">
@@ -122,7 +122,14 @@ export function CallScreen({
122
122
  </div>
123
123
 
124
124
  {/* Top padding in vh, like the face itself, so the face+text column sits below center */}
125
- <div className="flex min-h-0 flex-1 flex-col items-center justify-center gap-5 pt-[7vh]">
125
+ {/* The wheel winds the turns back. It is on this column rather than on the
126
+ screen: the corner holds the settings dialog and the room its own list,
127
+ and a portal's wheel bubbles up the tree it was written in, not the one
128
+ it is drawn in. */}
129
+ <div
130
+ onWheel={sided ? turns.onWheel : undefined}
131
+ className="flex min-h-0 flex-1 flex-col items-center justify-center gap-5 pt-[7vh]"
132
+ >
126
133
  {/* The face is the control. It reacts to the agent's own voice. */}
127
134
  <div className="relative w-[min(28rem,72vw,52vh)]">
128
135
  <button
@@ -151,7 +158,7 @@ export function CallScreen({
151
158
  />
152
159
  </button>
153
160
 
154
- {sided && <SideCaptions messages={messages} />}
161
+ {sided && <SideCaptions shown={turns.shown} give={turns.give} />}
155
162
  </div>
156
163
 
157
164
  {/* The column is wider than the text (40rem); the side margins hold the caption chevrons (Flow) */}
@@ -209,8 +216,6 @@ export function CallScreen({
209
216
 
210
217
  {/* Memory the model opens for reading (memory_show) */}
211
218
  <MemoryView />
212
- {/* A tidy pass ending is off-screen; it toasts (memory-tidy) */}
213
- <MemoryTidyNotice />
214
219
  {/* Documents a finished task produced; opens itself on the artifact event */}
215
220
  <ArtifactView />
216
221
 
@@ -513,8 +518,23 @@ function Step({
513
518
  );
514
519
  }
515
520
 
516
- /** Bars the mic meter draws, over the bands a voice actually sits in. */
517
- const MIC_BARS = ["a", "b", "c", "d", "e"];
521
+ /**
522
+ * Bars the mic meter draws: each over its own slice of the bands, with a gain
523
+ * that answers what a voice does to them. Speech stacks its energy in the
524
+ * fundamental and thins out with every band above it, so one gain for all five
525
+ * draws a tall bar on the left and four stubs — the gain rises to meet the
526
+ * drop, and the whole row moves instead of its first quarter.
527
+ */
528
+ const MIC_BARS = [
529
+ { id: "a", from: 0, to: 1, gain: 0.8 },
530
+ { id: "b", from: 1, to: 3, gain: 1 },
531
+ { id: "c", from: 3, to: 5, gain: 1.15 },
532
+ { id: "d", from: 5, to: 6, gain: 1.35 },
533
+ { id: "e", from: 6, to: 8, gain: 1.55 },
534
+ ];
535
+
536
+ /** Bar height in px, silent and at full. */
537
+ const MIC_BAR = { rest: 2, full: 14 };
518
538
 
519
539
  /**
520
540
  * The user's own level, read once per animation frame like the face reads
@@ -530,15 +550,28 @@ function MicMeter({
530
550
  getMicSpectrum?: () => ArrayLike<number>;
531
551
  }) {
532
552
  const bars = useRef<Record<string, HTMLSpanElement | null>>({});
553
+ // Height per bar, kept between frames so a bar can fall slower than it rises.
554
+ const held = useRef(MIC_BARS.map(() => 0));
533
555
 
534
556
  useEffect(() => {
535
557
  if (!live || !getMicSpectrum) return;
536
558
  let frame = requestAnimationFrame(function draw() {
537
559
  const bands = getMicSpectrum();
538
- MIC_BARS.forEach((id, at) => {
539
- const bar = bars.current[id];
540
- if (bar) {
541
- bar.style.height = `${2 + Math.min(1, bands[at] ?? 0) * 12}px`;
560
+ MIC_BARS.forEach((bar, at) => {
561
+ let peak = 0;
562
+ for (let k = bar.from; k < bar.to; k++) {
563
+ peak = Math.max(peak, bands[k] ?? 0);
564
+ }
565
+ // The curve is the loudness the ear hears, not the energy the mic reads:
566
+ // without it everything under half volume draws as the same short bar.
567
+ const want = Math.min(1, (peak * bar.gain) ** 0.8);
568
+ const was = held.current[at];
569
+ // Up in a frame or two to catch a syllable, down slowly enough to see.
570
+ const now = was + (want - was) * (want > was ? 0.6 : 0.16);
571
+ held.current[at] = now;
572
+ const node = bars.current[bar.id];
573
+ if (node) {
574
+ node.style.height = `${MIC_BAR.rest + now * (MIC_BAR.full - MIC_BAR.rest)}px`;
542
575
  }
543
576
  });
544
577
  frame = requestAnimationFrame(draw);
@@ -551,13 +584,13 @@ function MicMeter({
551
584
  aria-hidden
552
585
  className="flex h-3.5 w-[18px] shrink-0 items-center gap-0.5"
553
586
  >
554
- {MIC_BARS.map((id) => (
587
+ {MIC_BARS.map((bar) => (
555
588
  <span
556
- key={id}
589
+ key={bar.id}
557
590
  ref={(node) => {
558
- bars.current[id] = node;
591
+ bars.current[bar.id] = node;
559
592
  }}
560
- style={{ height: 2 }}
593
+ style={{ height: MIC_BAR.rest }}
561
594
  className="w-0.5 rounded-full bg-muted-foreground/70"
562
595
  />
563
596
  ))}
@@ -580,7 +613,7 @@ function Ear({
580
613
  getMicSpectrum?: () => ArrayLike<number>;
581
614
  }) {
582
615
  return (
583
- <span className="flex items-center gap-2 text-[13px] leading-5 text-muted-foreground">
616
+ <span className="flex items-center gap-1.5 text-[13px] leading-5 text-muted-foreground">
584
617
  <MicMeter live={live} getMicSpectrum={getMicSpectrum} />
585
618
  Listening
586
619
  </span>
@@ -592,57 +625,107 @@ function Ear({
592
625
  * motion (loader in the icon slot, shine on the text), not color; the loader
593
626
  * resolving into the tool's own glyph is what "finished" looks like.
594
627
  *
595
- * No pill. This slot cross-fades with the listening chip, which has no
596
- * container, so an outline under one of the two read as the line changing
597
- * shape rather than changing state.
628
+ * The line itself wears no pill. This slot cross-fades with the listening chip,
629
+ * which has no container either, so an outline under one of the two read as the
630
+ * line changing shape rather than changing state.
598
631
  */
599
632
  function Activity({ tool, micOff }: { tool: ToolRun; micOff: boolean }) {
600
- // a relay from a bot is a flag, like the report tool
633
+ // a relay from a bot is a flag, like the answer tool — unless it names the bot
601
634
  const relay = tool.kind === "relay";
602
635
  const Icon = relay ? Flag : toolIcon(tool.name);
636
+ // The sentence when there is one; otherwise the tool's own name is the line,
637
+ // rather than a tag repeating one.
638
+ const text = tool.line ?? tool.name;
639
+ const look = tool.line
640
+ ? "min-w-0 truncate text-[13px] leading-5 break-keep"
641
+ : "min-w-0 truncate font-mono text-xs leading-5";
642
+ // Only for the colour and silhouette the user picked; the name alone already
643
+ // draws a face, so a roster that has not arrived yet costs nothing.
644
+ const bots = useServerRoute<Bot[]>(queryKey.bot).data;
645
+ const bot = tool.bot
646
+ ? (bots?.find((one) => one.name === tool.bot) ?? null)
647
+ : null;
603
648
  return (
604
- <span className="flex max-w-full items-center gap-2">
605
- {/* 20px slot for a 14px glyph: the badge below needs the corner, and the
606
- row keeps the icon width the listening meter beside it has */}
607
- <span className="relative mr-0.5 grid size-5 shrink-0 place-items-center">
608
- {tool.done ? (
609
- <Icon className="size-3.5 text-muted-foreground" />
610
- ) : (
611
- <Loader2 className="size-3.5 animate-spin text-muted-foreground" />
612
- )}
613
- {/* The mic is closed because this is running, so the mark sits on its
614
- cause. As a row of its own it read as a warning about the mic. The
615
- padded disc is the separation the pill used to give it: on the bare
616
- page the two glyphs otherwise share strokes and read as a smudge. */}
617
- {micOff && (
618
- <MicOff className="absolute -right-1.5 -bottom-1.5 size-4 rounded-full bg-background p-[3.5px] text-muted-foreground" />
649
+ <span className="flex max-w-full items-center gap-1.5">
650
+ {/* 18px slot, the width the listening meter beside it has, so the two
651
+ faces of this slot start on the same edge */}
652
+ <span className="relative grid size-[18px] shrink-0 place-items-center">
653
+ <Mark tool={tool} bot={bot} icon={Icon} />
654
+ {/* Running is the glyph being filled in, over its own dimmed self: the
655
+ spinner that used to stand here took the glyph off the screen for as
656
+ long as it ran, which is exactly when it says the most. */}
657
+ {!tool.done && (
658
+ <span className="absolute inset-0 grid animate-ink place-items-center">
659
+ <Mark tool={tool} bot={bot} icon={Icon} running />
660
+ </span>
619
661
  )}
620
662
  </span>
621
- {/* The sentence when there is one; otherwise the tool's own name is the
622
- line, rather than a tag repeating one. */}
623
- {tool.line ? (
624
- tool.done ? (
625
- <span className="min-w-0 truncate text-[13px] leading-5 break-keep text-muted-foreground">
626
- {tool.line}
627
- </span>
628
- ) : (
629
- <ShinyText
630
- text={tool.line}
631
- speed={2.4}
632
- color="var(--muted-foreground)"
633
- shineColor="var(--foreground)"
634
- className="min-w-0 truncate text-[13px] leading-5 break-keep"
635
- />
636
- )
663
+ {/* The sweep is what says this is still running, so it is on whatever the
664
+ line turns out to be — the sentence, or the bare tool name. */}
665
+ {tool.done ? (
666
+ <span className={cn(look, "text-muted-foreground")}>{text}</span>
637
667
  ) : (
638
- <span className="min-w-0 truncate font-mono text-xs leading-5 text-muted-foreground">
639
- {tool.name}
668
+ <ShinyText text={text} speed={2.4} className={look} />
669
+ )}
670
+ {/* The mic is closed because this is running, so it travels with the line.
671
+ A chip, where the line has none: on the bare page a second glyph beside
672
+ the tool's own shares strokes with it and reads as a smudge, and the
673
+ plate is what says this is a state rather than more of the sentence. */}
674
+ {micOff && (
675
+ <span className="flex shrink-0 items-center gap-1 rounded-full bg-muted/60 py-0.5 pr-2 pl-1.5 font-mono text-[11px] leading-4 text-muted-foreground">
676
+ <MicOff className="size-3 shrink-0" />
677
+ mic off
640
678
  </span>
641
679
  )}
642
680
  </span>
643
681
  );
644
682
  }
645
683
 
684
+ /**
685
+ * What the row draws in its glyph slot: the bot's own face when the line names
686
+ * one, the tool's glyph otherwise. Who work went to, and who brought an answer
687
+ * back, is a face everywhere else in the app — the roster, the pill, the room.
688
+ *
689
+ * `running` is the copy the ink wipes in, so it is the one at full strength.
690
+ */
691
+ function Mark({
692
+ tool,
693
+ bot,
694
+ icon: Icon,
695
+ running,
696
+ }: {
697
+ tool: ToolRun;
698
+ /** The row the name resolved to, when the roster has one; its look, not its identity. */
699
+ bot: Bot | null;
700
+ icon: LucideIcon;
701
+ running?: boolean;
702
+ }) {
703
+ if (tool.bot) {
704
+ return (
705
+ <span className={cn("flex", !running && !tool.done && "opacity-40")}>
706
+ <BotMark
707
+ size={16}
708
+ seed={tool.bot}
709
+ vary={tool.bot}
710
+ color={bot?.icon?.color}
711
+ shape={bot?.icon?.shape}
712
+ outline={bot?.icon?.outline}
713
+ notify={false}
714
+ />
715
+ </span>
716
+ );
717
+ }
718
+ return (
719
+ <Icon
720
+ className={cn(
721
+ "size-3.5",
722
+ running ? "text-foreground" : "text-muted-foreground",
723
+ !running && !tool.done && "opacity-40",
724
+ )}
725
+ />
726
+ );
727
+ }
728
+
646
729
  /**
647
730
  * The activity slot: 28px, one fact at a time, two faces. Both stay mounted and
648
731
  * cross-fade, so the line leaves wearing its last words instead of blinking
@@ -729,7 +812,13 @@ function Hint({
729
812
  let key: string;
730
813
  if (busy) {
731
814
  key = status;
732
- body = status === "connecting" ? "Connecting…" : "Ending…";
815
+ // still moving, so it shines like every other line that is
816
+ body = (
817
+ <ShinyText
818
+ text={status === "connecting" ? "Connecting…" : "Ending…"}
819
+ className="text-muted-foreground/70"
820
+ />
821
+ );
733
822
  } else if (live && idleLeft !== null) {
734
823
  key = "quiet";
735
824
  body = `Quiet — ending in ${idleLeft}s. Say anything to stay.`;
@@ -865,18 +954,24 @@ function Elapsed({ since }: { since: number | null }) {
865
954
  const VISIBLE = 3;
866
955
 
867
956
  /**
868
- * Wheel delta per turn. Deliberately heavy: a casual flick barely moves,
869
- * though the few pixels of give show it is not stuck.
957
+ * Wheel delta per turn. Deliberately heavy a turn is a paragraph, and a
958
+ * trackpad flick that pages three of them reads as losing the conversation
959
+ * rather than moving through it. The give is what says it is not stuck.
870
960
  */
871
- const STEP = 200;
961
+ const STEP = 360;
962
+
963
+ /** How far the plates lean while the wheel is short of a turn, px. */
964
+ const GIVE = 10;
965
+
966
+ /** How long the wheel keeps what it has gathered. Past this the lean springs back and the count starts over, so half a turn never waits around to be completed by the next flick. */
967
+ const SETTLE_MS = 220;
872
968
 
873
969
  /**
874
- * Recent turns beside the face: yours on the right, hers on the left, each on
875
- * a fill with no edge. Anchored outside the face box (`right-full` /
876
- * `left-full`) so they never cover it. Older turns sit higher, smaller, and
877
- * their plate recedes.
970
+ * Where the wheel has wound the turns back to. Lives on the screen rather than
971
+ * in the plates: the three plates are small and sit off to the sides, so a
972
+ * wheel over the face where the cursor is used to reach nothing at all.
878
973
  */
879
- function SideCaptions({ messages }: { messages: CallMessage[] }) {
974
+ function useTurnPager(messages: CallMessage[]) {
880
975
  const [back, setBack] = useState(0);
881
976
  const [give, setGive] = useState(0);
882
977
  const drag = useRef(0);
@@ -890,13 +985,9 @@ function SideCaptions({ messages }: { messages: CallMessage[] }) {
890
985
  const grew = messages.length - seen.current;
891
986
  seen.current = messages.length;
892
987
  if (grew > 0) {
893
- setBack((was) =>
894
- was > 0
895
- ? Math.min(was + grew, Math.max(0, messages.length - VISIBLE))
896
- : 0,
897
- );
988
+ setBack((was) => (was > 0 ? Math.min(was + grew, furthest) : 0));
898
989
  }
899
- }, [messages.length]);
990
+ }, [messages.length, furthest]);
900
991
 
901
992
  useEffect(
902
993
  () => () => {
@@ -905,7 +996,9 @@ function SideCaptions({ messages }: { messages: CallMessage[] }) {
905
996
  [],
906
997
  );
907
998
 
908
- const wind = (event: React.WheelEvent) => {
999
+ const onWheel = (event: React.WheelEvent) => {
1000
+ // nothing behind the three on screen: no travel, and no lean pretending there is
1001
+ if (furthest === 0) return;
909
1002
  drag.current += event.deltaY;
910
1003
  const steps = Math.trunc(drag.current / STEP);
911
1004
  if (steps !== 0) {
@@ -919,12 +1012,31 @@ function SideCaptions({ messages }: { messages: CallMessage[] }) {
919
1012
  settle.current = setTimeout(() => {
920
1013
  drag.current = 0;
921
1014
  setGive(0);
922
- }, 160);
1015
+ }, SETTLE_MS);
923
1016
  };
924
1017
 
925
1018
  const end = messages.length - back;
926
- const shown = messages.slice(Math.max(0, end - VISIBLE), end);
1019
+ return {
1020
+ shown: messages.slice(Math.max(0, end - VISIBLE), end),
1021
+ give,
1022
+ onWheel,
1023
+ };
1024
+ }
927
1025
 
1026
+ /**
1027
+ * Recent turns beside the face: yours on the right, hers on the left, each on
1028
+ * a fill with no edge. Anchored outside the face box (`right-full` /
1029
+ * `left-full`) so they never cover it. Older turns sit higher, smaller, and
1030
+ * their plate recedes.
1031
+ */
1032
+ function SideCaptions({
1033
+ shown,
1034
+ give,
1035
+ }: {
1036
+ shown: CallMessage[];
1037
+ /** How far into the next turn the wheel is, -1..1; the plates lean by it. */
1038
+ give: number;
1039
+ }) {
928
1040
  return (
929
1041
  <>
930
1042
  {shown.map((message, index) => {
@@ -941,10 +1053,9 @@ function SideCaptions({ messages }: { messages: CallMessage[] }) {
941
1053
  return (
942
1054
  <div
943
1055
  key={message.id}
944
- onWheel={wind}
945
1056
  style={{
946
1057
  top: `${top}%`,
947
- transform: `translateY(calc(-50% + ${-give * 6}px))`,
1058
+ transform: `translateY(calc(-50% + ${-give * GIVE}px))`,
948
1059
  }}
949
1060
  className={cn(
950
1061
  // fixed-width slot, natural-width plate: short lines stay short and hug the face
@@ -1003,8 +1114,6 @@ export function Thursday() {
1003
1114
  // a preference, not a fact about the model (thursday.store)
1004
1115
  const face = useThursdayFace();
1005
1116
  const captionView = useThursdayStore((state) => state.captionView);
1006
- // the tab title shows the call state off-screen
1007
- useCallTitle(status !== "idle");
1008
1117
 
1009
1118
  /**
1010
1119
  * Same question as the server's `isCallable`, asked here because the answer
@@ -1016,21 +1125,25 @@ export function Thursday() {
1016
1125
  );
1017
1126
 
1018
1127
  return (
1019
- <CallScreen
1020
- status={status}
1021
- messages={messages}
1022
- tool={tool}
1023
- onTap={call}
1024
- wakePhrase={wakePhrase}
1025
- hotkeyLabel={hotkeyLabel}
1026
- idleLeft={idleLeft}
1027
- since={since}
1028
- micOff={micOff}
1029
- getSpectrum={getSpectrum}
1030
- getMicSpectrum={getMicSpectrum}
1031
- face={face}
1032
- captionView={captionView}
1033
- callable={callable}
1034
- />
1128
+ <>
1129
+ {/* the tab shows the call and what is owed while the app is off-screen */}
1130
+ <TabState live={status !== "idle"} />
1131
+ <CallScreen
1132
+ status={status}
1133
+ messages={messages}
1134
+ tool={tool}
1135
+ onTap={call}
1136
+ wakePhrase={wakePhrase}
1137
+ hotkeyLabel={hotkeyLabel}
1138
+ idleLeft={idleLeft}
1139
+ since={since}
1140
+ micOff={micOff}
1141
+ getSpectrum={getSpectrum}
1142
+ getMicSpectrum={getMicSpectrum}
1143
+ face={face}
1144
+ captionView={captionView}
1145
+ callable={callable}
1146
+ />
1147
+ </>
1035
1148
  );
1036
1149
  }
@@ -1,7 +1,6 @@
1
1
  "use server";
2
2
 
3
3
  import { asSchema } from "ai";
4
- import { after } from "next/server";
5
4
  import z from "zod";
6
5
  import { loadTools } from "@/features/ai/load-tools";
7
6
  import {
@@ -14,9 +13,6 @@ import { removeTask } from "@/features/bot/bot.runner";
14
13
  import { listAllTaskIds } from "@/features/bot/task.query";
15
14
  import { readConfig } from "@/features/config/config.query";
16
15
  import { deleteAllNotes } from "@/features/memory/memory.query";
17
- import { startTidy, stopTidy } from "@/features/memory/memory.tidy";
18
- import { deleteAllTidyRuns } from "@/features/memory/tidy.query";
19
- import { logger } from "@/lib/logger";
20
16
  import { serverAction } from "@/lib/protocol/server-action";
21
17
  import { publicError } from "@/lib/public-error";
22
18
  import { issueClientSecret } from "@/lib/realtime/client-secret";
@@ -141,13 +137,8 @@ export const saveTurnsAction = serverAction(
141
137
  },
142
138
  );
143
139
 
144
- /** Ending the call is what may set a read-back going (memory.tidy); it runs behind the response. */
145
140
  export const endCallAction = serverAction(async (callId: string) => {
146
- if (!(await endCall(callId))) return;
147
- after(async () => {
148
- const outcome = await startTidy();
149
- if (outcome !== "started") logger.debug(`tidy: not now (${outcome})`);
150
- });
141
+ await endCall(callId);
151
142
  });
152
143
 
153
144
  /**
@@ -160,25 +151,29 @@ export const deleteCallAction = serverAction(async (callId: string) => {
160
151
  }
161
152
  });
162
153
 
154
+ /**
155
+ * Deletes every ended call and its turns; returns how many went. A call still
156
+ * on the line stays, as it does for one (deleteCall).
157
+ */
158
+ export const deleteEndedCallsAction = serverAction(async () =>
159
+ deleteEndedCalls(),
160
+ );
161
+
163
162
  /**
164
163
  * Wipes what the app has kept of its own use: every ended call and its turns,
165
- * every job and its thread, every memory note, and the read-back log. Keys,
166
- * bots and connectors stay — the set `pnpm reset` calls History.
164
+ * every job and its thread, and every memory note. Keys, bots and connectors
165
+ * stay — the set `pnpm reset` calls History.
167
166
  *
168
167
  * History is not one domain, so this reaches into three and each clears its own
169
168
  * rows. Live work is stopped before its row goes: `removeTask` aborts a running
170
- * job and closes its shell, and a read-back in flight would otherwise write
171
- * notes back after they were deleted.
169
+ * job and closes its shell.
172
170
  */
173
171
  export const resetHistoryAction = serverAction(async () => {
174
- await stopTidy("History was reset.");
175
-
176
172
  const taskIds = await listAllTaskIds();
177
173
  for (const id of taskIds) await removeTask(id);
178
174
 
179
175
  const calls = await deleteEndedCalls();
180
176
  const notes = await deleteAllNotes();
181
- await deleteAllTidyRuns();
182
177
 
183
178
  return { calls, tasks: taskIds.length, notes };
184
179
  });