thursday-agent 0.17.2 → 0.19.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 (444) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +4 -2
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +3 -3
  5. package/.next/routes-manifest.json +28 -12
  6. package/.next/server/app/_global-error/page.js.nft.json +1 -1
  7. package/.next/server/app/_global-error.html +1 -1
  8. package/.next/server/app/_global-error.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  12. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  13. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/.next/server/app/_not-found.html +1 -1
  15. package/.next/server/app/_not-found.rsc +12 -12
  16. package/.next/server/app/_not-found.segments/_full.segment.rsc +12 -12
  17. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +11 -11
  18. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  19. package/.next/server/app/api/artifact/route.js +7 -7
  20. package/.next/server/app/api/artifact/route.js.nft.json +1 -1
  21. package/.next/server/app/api/bot/memory/files/route.js +4 -4
  22. package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -1
  23. package/.next/server/app/api/bot/memory/route.js +4 -4
  24. package/.next/server/app/api/bot/memory/route.js.nft.json +1 -1
  25. package/.next/server/app/api/bot/route.js +4 -4
  26. package/.next/server/app/api/bot/route.js.nft.json +1 -1
  27. package/.next/server/app/api/bot/thread/[id]/route.js +1 -1
  28. package/.next/server/app/api/bot/thread/[id]/route.js.nft.json +1 -1
  29. package/.next/server/app/api/bot/thread/file/route/app-paths-manifest.json +3 -0
  30. package/.next/server/app/api/bot/thread/file/route.js +29 -0
  31. package/.next/server/app/api/bot/thread/file/route.js.nft.json +1 -0
  32. package/.next/server/app/api/bot/thread/file/route_client-reference-manifest.js +3 -0
  33. package/.next/server/app/api/bot/thread/route.js +1 -1
  34. package/.next/server/app/api/bot/thread/route.js.nft.json +1 -1
  35. package/.next/server/app/api/config/route.js +1 -1
  36. package/.next/server/app/api/config/route.js.nft.json +1 -1
  37. package/.next/server/app/api/events/route.js +2 -2
  38. package/.next/server/app/api/events/route.js.nft.json +1 -1
  39. package/.next/server/app/api/favicon/[host]/route.js.nft.json +1 -1
  40. package/.next/server/app/api/file/[...path]/route.js +4 -4
  41. package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
  42. package/.next/server/app/api/llm-model/automatic/route.js +3 -3
  43. package/.next/server/app/api/llm-model/automatic/route.js.nft.json +1 -1
  44. package/.next/server/app/api/llm-model/catalog/[provider]/route/app-paths-manifest.json +3 -0
  45. package/.next/server/app/api/llm-model/catalog/{route.js → [provider]/route.js} +8 -8
  46. package/.next/server/app/api/llm-model/catalog/[provider]/route.js.nft.json +1 -0
  47. package/.next/server/app/api/llm-model/catalog/[provider]/route_client-reference-manifest.js +3 -0
  48. package/.next/server/app/api/llm-model/credits/[provider]/route/app-paths-manifest.json +3 -0
  49. package/.next/server/app/api/llm-model/credits/[provider]/route/build-manifest.json +12 -0
  50. package/.next/server/app/api/llm-model/credits/[provider]/route/server-reference-manifest.json +4 -0
  51. package/.next/server/app/api/llm-model/credits/{route.js → [provider]/route.js} +8 -8
  52. package/.next/server/app/api/llm-model/credits/[provider]/route.js.map +5 -0
  53. package/.next/server/app/api/llm-model/credits/[provider]/route.js.nft.json +1 -0
  54. package/.next/server/app/api/llm-model/credits/[provider]/route_client-reference-manifest.js +3 -0
  55. package/.next/server/app/api/llm-model/route.js +1 -1
  56. package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
  57. package/.next/server/app/api/llm-model/subscription/route.js +1 -1
  58. package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -1
  59. package/.next/server/app/api/mcp/[name]/route.js +1 -1
  60. package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
  61. package/.next/server/app/api/mcp/oauth/callback/route.js +2 -2
  62. package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
  63. package/.next/server/app/api/mcp/route.js +1 -1
  64. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  65. package/.next/server/app/api/mcp/tools/route.js +1 -1
  66. package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
  67. package/.next/server/app/api/memory/edit/route.js +12 -12
  68. package/.next/server/app/api/memory/edit/route.js.nft.json +1 -1
  69. package/.next/server/app/api/memory/route.js +1 -1
  70. package/.next/server/app/api/memory/route.js.nft.json +1 -1
  71. package/.next/server/app/api/reach/route.js +17 -17
  72. package/.next/server/app/api/reach/route.js.nft.json +1 -1
  73. package/.next/server/app/api/routine/route.js +6 -6
  74. package/.next/server/app/api/routine/route.js.nft.json +1 -1
  75. package/.next/server/app/api/running/route/app-paths-manifest.json +3 -0
  76. package/.next/server/app/api/running/route/build-manifest.json +12 -0
  77. package/.next/server/app/api/running/route/server-reference-manifest.json +4 -0
  78. package/.next/server/app/api/running/route.js +10 -0
  79. package/.next/server/app/api/running/route.js.map +5 -0
  80. package/.next/server/app/api/running/route.js.nft.json +1 -0
  81. package/.next/server/app/api/running/route_client-reference-manifest.js +3 -0
  82. package/.next/server/app/api/signins/route.js +4 -4
  83. package/.next/server/app/api/signins/route.js.nft.json +1 -1
  84. package/.next/server/app/api/skills/[source]/[name]/route.js +7 -7
  85. package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
  86. package/.next/server/app/api/skills/route.js +6 -6
  87. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  88. package/.next/server/app/api/thursday/call/end/route.js +1 -1
  89. package/.next/server/app/api/thursday/call/end/route.js.nft.json +1 -1
  90. package/.next/server/app/api/thursday/call/route.js +1 -1
  91. package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
  92. package/.next/server/app/api/thursday/settings/route.js +1 -1
  93. package/.next/server/app/api/thursday/settings/route.js.nft.json +1 -1
  94. package/.next/server/app/api/thursday/text/route.js +12 -12
  95. package/.next/server/app/api/thursday/text/route.js.nft.json +1 -1
  96. package/.next/server/app/api/thursday/tool-call/route.js +13 -13
  97. package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
  98. package/.next/server/app/api/workspace/files/route.js +7 -7
  99. package/.next/server/app/api/workspace/files/route.js.nft.json +1 -1
  100. package/.next/server/app/api/workspace/route.js +6 -6
  101. package/.next/server/app/api/workspace/route.js.nft.json +1 -1
  102. package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +94 -6
  103. package/.next/server/app/artifact/[...path]/page.js +9 -5
  104. package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
  105. package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
  106. package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  107. package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -1
  108. package/.next/server/app/page/server-reference-manifest.json +161 -128
  109. package/.next/server/app/page.js +10 -9
  110. package/.next/server/app/page.js.nft.json +1 -1
  111. package/.next/server/app/page_client-reference-manifest.js +1 -1
  112. package/.next/server/app-paths-manifest.json +4 -2
  113. package/.next/server/chunks/[root-of-the-server]__00qyw01._.js +1 -1
  114. package/.next/server/chunks/[root-of-the-server]__02ra64t._.js +5 -0
  115. package/.next/server/chunks/{[root-of-the-server]__05dp5tr._.js → [root-of-the-server]__06ky9of._.js} +2 -2
  116. package/.next/server/chunks/[root-of-the-server]__0b565-x._.js +7 -0
  117. package/.next/server/chunks/[root-of-the-server]__0bmtib_._.js +7 -0
  118. package/.next/server/chunks/[root-of-the-server]__0bqveex._.js +1 -1
  119. package/.next/server/chunks/[root-of-the-server]__0brmiv2._.js +7 -0
  120. package/.next/server/chunks/[root-of-the-server]__0eivkvk._.js +2 -2
  121. package/.next/server/chunks/[root-of-the-server]__0f7m79q._.js +1 -1
  122. package/.next/server/chunks/[root-of-the-server]__0g38-aj._.js +2 -2
  123. package/.next/server/chunks/[root-of-the-server]__0gvdr2h._.js +5 -0
  124. package/.next/server/chunks/[root-of-the-server]__0h656y-._.js +2 -2
  125. package/.next/server/chunks/[root-of-the-server]__0hm3tiq._.js +2 -2
  126. package/.next/server/chunks/[root-of-the-server]__0hzdqnv._.js +2 -2
  127. package/.next/server/chunks/[root-of-the-server]__0kzmxpg._.js +3 -0
  128. package/.next/server/chunks/[root-of-the-server]__0mgyt8p._.js +2 -2
  129. package/.next/server/chunks/[root-of-the-server]__0mrk2it._.js +1 -1
  130. package/.next/server/chunks/[root-of-the-server]__0o5s5-o._.js +5 -0
  131. package/.next/server/chunks/[root-of-the-server]__0p80i1n._.js +1 -1
  132. package/.next/server/chunks/[root-of-the-server]__0qdoc_9._.js +5 -0
  133. package/.next/server/chunks/[root-of-the-server]__0qzho69._.js +1 -1
  134. package/.next/server/chunks/[root-of-the-server]__0sm5xvm._.js +1 -1
  135. package/.next/server/chunks/[root-of-the-server]__0v_kuor._.js +5 -0
  136. package/.next/server/chunks/{[root-of-the-server]__061o2_x._.js → [root-of-the-server]__0ypkfbu._.js} +1 -1
  137. package/.next/server/chunks/[root-of-the-server]__1-18_pz._.js +1 -1
  138. package/.next/server/chunks/[root-of-the-server]__13hng6h._.js +1 -1
  139. package/.next/server/chunks/{[root-of-the-server]__01k3vi3._.js → [root-of-the-server]__14iga7p._.js} +1 -1
  140. package/.next/server/chunks/[root-of-the-server]__16gn7zn._.js +3 -0
  141. package/.next/server/chunks/[root-of-the-server]__18e65_-._.js +3 -0
  142. package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +2 -2
  143. package/.next/server/chunks/[root-of-the-server]__1_cgawk._.js +5 -0
  144. package/.next/server/chunks/[root-of-the-server]__1ceammd._.js +1 -1
  145. package/.next/server/chunks/[root-of-the-server]__1ckt1yj._.js +1 -1
  146. package/.next/server/chunks/[root-of-the-server]__1cu5f3z._.js +1 -1
  147. package/.next/server/chunks/[root-of-the-server]__1dth047._.js +5 -0
  148. package/.next/server/chunks/{[root-of-the-server]__1k2qs1m._.js → [root-of-the-server]__1fc6v12._.js} +1 -1
  149. package/.next/server/chunks/[root-of-the-server]__1hviq62._.js +2 -2
  150. package/.next/server/chunks/[root-of-the-server]__1ksm9m-._.js +12 -0
  151. package/.next/server/chunks/[root-of-the-server]__1m1q6u5._.js +3 -0
  152. package/.next/server/chunks/[root-of-the-server]__1m_dmf6._.js +5 -0
  153. package/.next/server/chunks/[root-of-the-server]__1mys2c3._.js +5 -0
  154. package/.next/server/chunks/[root-of-the-server]__1ndi14y._.js +1 -1
  155. package/.next/server/chunks/[root-of-the-server]__1p0njle._.js +5 -0
  156. package/.next/server/chunks/[root-of-the-server]__1p47fbb._.js +2 -2
  157. package/.next/server/chunks/[root-of-the-server]__1pugoq0._.js +1 -1
  158. package/.next/server/chunks/{[root-of-the-server]__0ts7ai0._.js → [root-of-the-server]__1trns9g._.js} +1 -1
  159. package/.next/server/chunks/[root-of-the-server]__1ygplx1._.js +1 -1
  160. package/.next/server/chunks/[root-of-the-server]__1zn039k._.js +1 -1
  161. package/.next/server/chunks/[root-of-the-server]__20w_g71._.js +3 -0
  162. package/.next/server/chunks/_01c32w9._.js +1 -1
  163. package/.next/server/chunks/_02bov6_._.js +1 -1
  164. package/.next/server/chunks/_06hnfi8._.js +2 -2
  165. package/.next/server/chunks/_06u9yo-._.js +1 -1
  166. package/.next/server/chunks/_08354bn._.js +12 -11
  167. package/.next/server/chunks/_08_-9ay._.js +7 -0
  168. package/.next/server/chunks/_08s4vft._.js +1 -1
  169. package/.next/server/chunks/_0bgjf07._.js +5 -0
  170. package/.next/server/chunks/_0c49lmw._.js +1 -1
  171. package/.next/server/chunks/_0fb6dvr._.js +1 -1
  172. package/.next/server/chunks/_0hgvg55._.js +1 -1
  173. package/.next/server/chunks/_0iw19ig._.js +1 -1
  174. package/.next/server/chunks/_0poi1t2._.js +1 -1
  175. package/.next/server/chunks/_0s8ao8z._.js +1 -1
  176. package/.next/server/chunks/_0t_7gji._.js +1 -1
  177. package/.next/server/chunks/_0ucx1jv._.js +1 -1
  178. package/.next/server/chunks/_0uzj57i._.js +1 -1
  179. package/.next/server/chunks/_0wyh244._.js +112 -0
  180. package/.next/server/chunks/_1-sk_q4._.js +1 -1
  181. package/.next/server/chunks/_108gsm8._.js +2 -2
  182. package/.next/server/chunks/_136j09a._.js +5 -5
  183. package/.next/server/chunks/_15negpy._.js +2 -2
  184. package/.next/server/chunks/_1d7og_q._.js +1 -1
  185. package/.next/server/chunks/_1dxq827._.js +2 -2
  186. package/.next/server/chunks/_1e54wxa._.js +1 -1
  187. package/.next/server/chunks/_1frcwj1._.js +1 -1
  188. package/.next/server/chunks/_1gn2r2q._.js +8 -6
  189. package/.next/server/chunks/_1gxankq._.js +2 -2
  190. package/.next/server/chunks/_1i3uucm._.js +1 -1
  191. package/.next/server/chunks/_1jvy78-._.js +5 -0
  192. package/.next/server/chunks/_1lg0lsu._.js +53 -0
  193. package/.next/server/chunks/_1njolhx._.js +294 -0
  194. package/.next/server/chunks/_1q6e56i._.js +8 -6
  195. package/.next/server/chunks/_1qgix-j._.js +1 -1
  196. package/.next/server/chunks/_1wtb-77._.js +294 -0
  197. package/.next/server/chunks/_1wwl_7o._.js +1 -1
  198. package/.next/server/chunks/_1y8w80a._.js +5 -5
  199. package/.next/server/chunks/_1yx285_._.js +3 -0
  200. package/.next/server/chunks/_20qn224._.js +3 -0
  201. package/.next/server/chunks/_211dn2c._.js +1 -1
  202. package/.next/server/chunks/_next-internal_server_app_api_bot_thread_file_route_actions_0q3be0o.js +3 -0
  203. package/.next/server/chunks/_next-internal_server_app_api_llm-model_catalog_[provider]_route_actions_1i0449q.js +3 -0
  204. package/.next/server/chunks/_next-internal_server_app_api_llm-model_credits_[provider]_route_actions_0iui9hz.js +3 -0
  205. package/.next/server/chunks/_next-internal_server_app_api_running_route_actions_0o1g-aw.js +3 -0
  206. package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
  207. package/.next/server/chunks/features_bot_08z387_._.js +3 -3
  208. package/.next/server/chunks/features_bot_0zy_q8y._.js +7 -7
  209. package/.next/server/chunks/features_bot_1dfrdsb._.js +7 -7
  210. package/.next/server/chunks/features_workspace_workspace_ts_13h82gv._.js +3 -3
  211. package/.next/server/chunks/features_workspace_workspace_ts_1iyjroj._.js +3 -3
  212. package/.next/server/chunks/{node_modules_1rosz79._.js → node_modules_035o7ku._.js} +1 -1
  213. package/.next/server/chunks/{node_modules_1er1u8w._.js → node_modules_0tn5t13._.js} +1 -1
  214. package/.next/server/chunks/{node_modules_103lpef._.js → node_modules_12oq3hr._.js} +1 -1
  215. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0g87zst._.js → node_modules_consola_dist_chunks_prompt_mjs_0yd5xa0._.js} +1 -1
  216. package/.next/server/chunks/ssr/[root-of-the-server]__04upd5v._.js +1 -1
  217. package/.next/server/chunks/ssr/[root-of-the-server]__0p0mv2u._.js +3 -0
  218. package/.next/server/chunks/ssr/[root-of-the-server]__0sk5enu._.js +3 -0
  219. package/.next/server/chunks/ssr/[root-of-the-server]__0xyaud4._.js +3 -0
  220. package/.next/server/chunks/ssr/[root-of-the-server]__1-gi9sm._.js +3 -0
  221. package/.next/server/chunks/ssr/[root-of-the-server]__16nn3pe._.js +3 -0
  222. package/.next/server/chunks/ssr/[root-of-the-server]__1867koj._.js +1 -1
  223. package/.next/server/chunks/ssr/[root-of-the-server]__1c8-7cw._.js +3 -0
  224. package/.next/server/chunks/ssr/{[root-of-the-server]__1d7usu0._.js → [root-of-the-server]__1qn0axo._.js} +2 -2
  225. package/.next/server/chunks/ssr/[root-of-the-server]__1tb5vve._.js +47 -0
  226. package/.next/server/chunks/ssr/_02cm0fr._.js +5 -0
  227. package/.next/server/chunks/ssr/{features_bot_1knyan7._.js → _07nmtxo._.js} +2 -2
  228. package/.next/server/chunks/ssr/_088vzgn._.js +1 -1
  229. package/.next/server/chunks/ssr/{_1dfv66y._.js → _0bg1u1j._.js} +2 -2
  230. package/.next/server/chunks/ssr/_0cv9tmv._.js +1 -1
  231. package/.next/server/chunks/ssr/{_10-_awu._.js → _0f9hx5p._.js} +2 -2
  232. package/.next/server/chunks/ssr/_0g9ula_._.js +3 -0
  233. package/.next/server/chunks/ssr/{_1aqjk-1._.js → _0irozu9._.js} +2 -2
  234. package/.next/server/chunks/ssr/{_123y-ah._.js → _0is8m6y._.js} +2 -2
  235. package/.next/server/chunks/ssr/_0iwsdp7._.js +3 -0
  236. package/.next/server/chunks/ssr/_0l7rjg5._.js +1 -1
  237. package/.next/server/chunks/ssr/{lib_logger_ts_0-olsze._.js → _0mfgsk-._.js} +4 -2
  238. package/.next/server/chunks/ssr/{_0fo4552._.js → _0nk80t6._.js} +53 -13
  239. package/.next/server/chunks/ssr/_0p6w0ef._.js +3 -0
  240. package/.next/server/chunks/ssr/_0pbav_w._.js +3 -0
  241. package/.next/server/chunks/ssr/{_0vo_oym._.js → _0q-mdwv._.js} +8 -8
  242. package/.next/server/chunks/ssr/_0s5_ahb._.js +3 -0
  243. package/.next/server/chunks/ssr/{_0e2fnvg._.js → _0t5f2c3._.js} +2 -2
  244. package/.next/server/chunks/ssr/_0v9r8g2._.js +1 -1
  245. package/.next/server/chunks/ssr/_0x8ophf._.js +1 -1
  246. package/.next/server/chunks/ssr/_0x9f717._.js +60 -0
  247. package/.next/server/chunks/ssr/_107vtdk._.js +162 -0
  248. package/.next/server/chunks/ssr/{_17a4qyk._.js → _12lql1x._.js} +3 -3
  249. package/.next/server/chunks/ssr/{_163dr78._.js → _165wnr4._.js} +2 -2
  250. package/.next/server/chunks/ssr/_16_7zeo._.js +3 -0
  251. package/.next/server/chunks/ssr/_17komoi._.js +3 -0
  252. package/.next/server/chunks/ssr/_190hjys._.js +3 -0
  253. package/.next/server/chunks/ssr/_1bfrntd._.js +6 -0
  254. package/.next/server/chunks/ssr/{_01al00i._.js → _1booff4._.js} +2 -2
  255. package/.next/server/chunks/ssr/{_0xfafez._.js → _1ew1j7l._.js} +2 -2
  256. package/.next/server/chunks/ssr/_1i2swyr._.js +3 -0
  257. package/.next/server/chunks/ssr/_1neoj22._.js +1 -1
  258. package/.next/server/chunks/ssr/_1qsa25k._.js +3 -0
  259. package/.next/server/chunks/ssr/_1soynbw._.js +6 -0
  260. package/.next/server/chunks/ssr/_1vc2xmu._.js +3 -0
  261. package/.next/server/chunks/ssr/{_14oirtb._.js → _1wq90j8._.js} +2 -2
  262. package/.next/server/chunks/ssr/_1xwtbdz._.js +3 -0
  263. package/.next/server/chunks/ssr/_1zrhkf0._.js +310 -0
  264. package/.next/server/chunks/ssr/_21awrs2._.js +5 -0
  265. package/.next/server/chunks/ssr/features_0796o8r._.js +1 -1
  266. package/.next/server/chunks/ssr/features_bot_0tb4ui-._.js +2 -2
  267. package/.next/server/chunks/ssr/features_bot_1c56lew._.js +37 -0
  268. package/.next/server/chunks/ssr/features_bot_1fn_grf._.js +3 -0
  269. package/.next/server/chunks/ssr/{features_config_09n-q9q._.js → features_config_05zi68v._.js} +3 -3
  270. package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
  271. package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +1 -1
  272. package/.next/server/chunks/ssr/features_routine_components_routine-setting_tsx_055fknz._.js +1 -1
  273. package/.next/server/chunks/ssr/features_workspace_workspace_ts_1wc7_u_._.js +4 -4
  274. package/.next/server/chunks/ssr/{node_modules_1k5i-_9._.js → node_modules_0-sux1a._.js} +1 -1
  275. package/.next/server/chunks/ssr/{node_modules_0msrhxf._.js → node_modules_01oezhb._.js} +1 -1
  276. package/.next/server/chunks/ssr/{node_modules_1gq3ght._.js → node_modules_04m6ebg._.js} +1 -1
  277. package/.next/server/chunks/ssr/{node_modules_0nmkv-v._.js → node_modules_067jfov._.js} +1 -1
  278. package/.next/server/chunks/ssr/{node_modules_0gd9hbz._.js → node_modules_06ugby3._.js} +1 -1
  279. package/.next/server/chunks/ssr/{node_modules_0d6j33x._.js → node_modules_07p51j3._.js} +1 -1
  280. package/.next/server/chunks/ssr/{node_modules_10_fv2a._.js → node_modules_0995xyq._.js} +1 -1
  281. package/.next/server/chunks/ssr/{node_modules_1lmyts8._.js → node_modules_0_uecwx._.js} +1 -1
  282. package/.next/server/chunks/ssr/{node_modules_04x5wyv._.js → node_modules_0dsyc90._.js} +1 -1
  283. package/.next/server/chunks/ssr/{node_modules_0__0tvm._.js → node_modules_0hli6s2._.js} +1 -1
  284. package/.next/server/chunks/ssr/{node_modules_0k8-y89._.js → node_modules_0m-bde_._.js} +1 -1
  285. package/.next/server/chunks/ssr/{node_modules_1p_6sq7._.js → node_modules_0oqfdbr._.js} +1 -1
  286. package/.next/server/chunks/ssr/node_modules_0qd7p5f._.js +3 -0
  287. package/.next/server/chunks/ssr/{node_modules_13g-d25._.js → node_modules_0tgy5s5._.js} +1 -1
  288. package/.next/server/chunks/ssr/{node_modules_1_8-jcj._.js → node_modules_1-kjmls._.js} +1 -1
  289. package/.next/server/chunks/ssr/{node_modules_0m73b88._.js → node_modules_1-l3ka5._.js} +1 -1
  290. package/.next/server/chunks/ssr/{node_modules_113l3e5._.js → node_modules_1-w3ayh._.js} +1 -1
  291. package/.next/server/chunks/ssr/{node_modules_0q-klni._.js → node_modules_133exgm._.js} +1 -1
  292. package/.next/server/chunks/ssr/{node_modules_1xb-ndg._.js → node_modules_17xc5_k._.js} +1 -1
  293. package/.next/server/chunks/ssr/{node_modules_021lid9._.js → node_modules_1_i_w30._.js} +1 -1
  294. package/.next/server/chunks/ssr/{node_modules_1ri_eip._.js → node_modules_1a2cjfk._.js} +1 -1
  295. package/.next/server/chunks/ssr/{node_modules_13bqv6i._.js → node_modules_1k752fe._.js} +1 -1
  296. package/.next/server/chunks/ssr/{node_modules_1qstb1x._.js → node_modules_1lie7z8._.js} +1 -1
  297. package/.next/server/chunks/ssr/{node_modules_096up6a._.js → node_modules_1mv70-y._.js} +1 -1
  298. package/.next/server/chunks/ssr/{node_modules_156kv_t._.js → node_modules_1r611t2._.js} +1 -1
  299. package/.next/server/chunks/ssr/node_modules_1vfd8dz._.js +3 -0
  300. package/.next/server/chunks/ssr/{node_modules_0cjnmzp._.js → node_modules_1yaowd7._.js} +1 -1
  301. package/.next/server/chunks/ssr/{node_modules_0nw5jz7._.js → node_modules_20a1wpo._.js} +1 -1
  302. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0amkw0b._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1r8pxbe._.js} +1 -1
  303. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0zq3l45._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1siiu4h._.js} +1 -1
  304. package/.next/server/middleware-build-manifest.js +3 -3
  305. package/.next/server/pages/404.html +1 -1
  306. package/.next/server/pages/500.html +1 -1
  307. package/.next/server/server-reference-manifest.js +1 -1
  308. package/.next/server/server-reference-manifest.json +205 -132
  309. package/.next/static/chunks/{0obogzscwwekj.js → 088d3w5qxu19g.js} +2 -2
  310. package/.next/static/chunks/0_s4z70lx1tgs.js +1 -0
  311. package/.next/static/chunks/0bxekp4hnuk1g.js +1 -0
  312. package/.next/static/chunks/{1cglo3a2mbeou.js → 0fw4u_s974j24.js} +1 -1
  313. package/.next/static/chunks/0hy2x7qhk8wgx.css +1 -0
  314. package/.next/static/chunks/{2zbl41hed17g3.js → 0n_eshmn_7wfn.js} +2 -2
  315. package/.next/static/chunks/0q9b2n6l4flqb.js +1 -0
  316. package/.next/static/chunks/0ulcp_u_y1u0b.js +15 -0
  317. package/.next/static/chunks/0vj93zo0yvix9.js +35 -0
  318. package/.next/static/chunks/{166smhw8v-s3j.js → 10f98bh4hdmhe.js} +1 -1
  319. package/.next/static/chunks/1b8bce_z_act0.js +1 -0
  320. package/.next/static/chunks/1c32d2azsjaj_.js +1 -0
  321. package/.next/static/chunks/{1xv4g10m-cl1s.js → 1fs829mz69pxz.js} +1 -1
  322. package/.next/static/chunks/1lwlh4mo_vv8d.js +1 -0
  323. package/.next/static/chunks/{0p2f6uv4xytfm.js → 1po8fkg40peu-.js} +1 -1
  324. package/.next/static/chunks/{0uxq_vs6uxi-b.js → 1rg6b9l5fm1hj.js} +1 -1
  325. package/.next/static/chunks/{3b96xy59nl_gd.js → 26g3iwfuad-7p.js} +1 -1
  326. package/.next/static/chunks/2bjnmtke_q43c.js +1 -0
  327. package/.next/static/chunks/2c86k0o-1p9_w.js +1 -0
  328. package/.next/static/chunks/2gf4t0d76bvyv.js +1 -0
  329. package/.next/static/chunks/2rj3q_ahctv19.js +1 -0
  330. package/.next/static/chunks/{2lhc74urf3acr.js → 2x6-fpctvucte.js} +1 -1
  331. package/.next/static/chunks/2yicf7bky866n.js +3 -0
  332. package/.next/static/chunks/337g9g_ux2gj-.js +1 -0
  333. package/.next/static/chunks/350ws7svim7ij.js +58 -0
  334. package/.next/static/chunks/{0o7o0eb7ihxi6.js → 396enq-m0sss5.js} +1 -1
  335. package/.next/static/chunks/3e1w_nwfb39j-.js +1 -0
  336. package/.next/static/chunks/3v3ooretb54ag.js +1 -0
  337. package/.next/static/chunks/40re_3ukjulg9.js +1 -0
  338. package/.next/static/chunks/{3gsxnqqqphh-1.js → 44bcbnmup71so.js} +1 -1
  339. package/.next/static/chunks/{2qgkbdshzpq1c.js → 458dtbsemx996.js} +1 -1
  340. package/README.md +5 -5
  341. package/bin/background.mjs +995 -0
  342. package/bin/lock.mjs +121 -5
  343. package/bin/thursday.mjs +126 -30
  344. package/bin/tools.mjs +72 -1
  345. package/database/migrations/20260926021847_thread_cache_tokens/migration.sql +2 -0
  346. package/database/migrations/20260926021847_thread_cache_tokens/snapshot.json +1949 -0
  347. package/guide/bots.md +173 -317
  348. package/guide/calls.md +106 -146
  349. package/guide/index.md +2 -2
  350. package/guide/memory.md +14 -18
  351. package/guide/phone.md +86 -133
  352. package/guide/setup.md +141 -172
  353. package/guide/trouble.md +42 -65
  354. package/package.json +1 -1
  355. package/seed-skills/concierge/travel/references/itinerary.md +1 -1
  356. package/seed-skills/concierge/travel/scripts/itinerary.mjs +8 -3
  357. package/skills/artifact/references/book.md +3 -3
  358. package/skills/artifact/runtime/shell/shell.js +32 -3
  359. package/.next/server/app/api/llm-model/catalog/route/app-paths-manifest.json +0 -3
  360. package/.next/server/app/api/llm-model/catalog/route.js.nft.json +0 -1
  361. package/.next/server/app/api/llm-model/catalog/route_client-reference-manifest.js +0 -3
  362. package/.next/server/app/api/llm-model/credits/route/app-paths-manifest.json +0 -3
  363. package/.next/server/app/api/llm-model/credits/route.js.nft.json +0 -1
  364. package/.next/server/app/api/llm-model/credits/route_client-reference-manifest.js +0 -3
  365. package/.next/server/chunks/[root-of-the-server]__01ypm_z._.js +0 -3
  366. package/.next/server/chunks/[root-of-the-server]__021dkui._.js +0 -3
  367. package/.next/server/chunks/[root-of-the-server]__03xamry._.js +0 -3
  368. package/.next/server/chunks/[root-of-the-server]__09gdscj._.js +0 -7
  369. package/.next/server/chunks/[root-of-the-server]__0ljizgj._.js +0 -5
  370. package/.next/server/chunks/[root-of-the-server]__0nmust6._.js +0 -5
  371. package/.next/server/chunks/[root-of-the-server]__0svzjwa._.js +0 -7
  372. package/.next/server/chunks/[root-of-the-server]__1-rmal0._.js +0 -5
  373. package/.next/server/chunks/[root-of-the-server]__10xnb7e._.js +0 -3
  374. package/.next/server/chunks/[root-of-the-server]__1_h4hf9._.js +0 -7
  375. package/.next/server/chunks/[root-of-the-server]__1c2kwku._.js +0 -12
  376. package/.next/server/chunks/[root-of-the-server]__1t02-1p._.js +0 -3
  377. package/.next/server/chunks/[root-of-the-server]__1t0jj1j._.js +0 -5
  378. package/.next/server/chunks/[root-of-the-server]__1v7x5ym._.js +0 -3
  379. package/.next/server/chunks/[root-of-the-server]__1vlxv19._.js +0 -5
  380. package/.next/server/chunks/_07nxi75._.js +0 -254
  381. package/.next/server/chunks/_08btiir._.js +0 -7
  382. package/.next/server/chunks/_0j0-gq6._.js +0 -5
  383. package/.next/server/chunks/_0p6v1fr._.js +0 -5
  384. package/.next/server/chunks/_0srlnvd._.js +0 -16
  385. package/.next/server/chunks/_0xygcxs._.js +0 -254
  386. package/.next/server/chunks/_1ic3bew._.js +0 -5
  387. package/.next/server/chunks/_next-internal_server_app_api_llm-model_catalog_route_actions_1eu2y41.js +0 -3
  388. package/.next/server/chunks/_next-internal_server_app_api_llm-model_credits_route_actions_0v424pb.js +0 -3
  389. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_04oxl25._.js +0 -3
  390. package/.next/server/chunks/ssr/[root-of-the-server]__0-af_o7._.js +0 -3
  391. package/.next/server/chunks/ssr/[root-of-the-server]__09f39cp._.js +0 -4
  392. package/.next/server/chunks/ssr/[root-of-the-server]__0ouu4qp._.js +0 -3
  393. package/.next/server/chunks/ssr/[root-of-the-server]__0q9g9ea._.js +0 -5
  394. package/.next/server/chunks/ssr/[root-of-the-server]__17h1ggo._.js +0 -46
  395. package/.next/server/chunks/ssr/[root-of-the-server]__1jyeu61._.js +0 -5
  396. package/.next/server/chunks/ssr/_0afrpci._.js +0 -3
  397. package/.next/server/chunks/ssr/_0bgse1c._.js +0 -162
  398. package/.next/server/chunks/ssr/_0jstvlg._.js +0 -39
  399. package/.next/server/chunks/ssr/_0qsmpcu._.js +0 -3
  400. package/.next/server/chunks/ssr/_0z38nha._.js +0 -3
  401. package/.next/server/chunks/ssr/_1-41lck._.js +0 -3
  402. package/.next/server/chunks/ssr/_10_ph1t._.js +0 -3
  403. package/.next/server/chunks/ssr/_116lfdc._.js +0 -3
  404. package/.next/server/chunks/ssr/_14dfh7a._.js +0 -4
  405. package/.next/server/chunks/ssr/_17qtuv7._.js +0 -3
  406. package/.next/server/chunks/ssr/_19jez1a._.js +0 -3
  407. package/.next/server/chunks/ssr/_1_5xof_._.js +0 -3
  408. package/.next/server/chunks/ssr/_1alxym6._.js +0 -3
  409. package/.next/server/chunks/ssr/_1ou5sj0._.js +0 -3
  410. package/.next/server/chunks/ssr/_1tmw842._.js +0 -5
  411. package/.next/server/chunks/ssr/_1uij_rj._.js +0 -3
  412. package/.next/server/chunks/ssr/_1w9w1ok._.js +0 -3
  413. package/.next/server/chunks/ssr/_20gq_24._.js +0 -3
  414. package/.next/server/chunks/ssr/features_bot_0ouemw8._.js +0 -3
  415. package/.next/server/chunks/ssr/node_modules_@base-ui_react_1j9i1ho._.js +0 -3
  416. package/.next/static/chunks/01l7kw74vfp32.js +0 -1
  417. package/.next/static/chunks/0a5_-jqhaktjj.js +0 -1
  418. package/.next/static/chunks/0npvak0wpgagb.js +0 -1
  419. package/.next/static/chunks/19l81deo_pyoc.js +0 -1
  420. package/.next/static/chunks/1bnhw-5fj7aiz.js +0 -1
  421. package/.next/static/chunks/1in6nxpu33iab.js +0 -1
  422. package/.next/static/chunks/1u7kg91f9qy3g.js +0 -1
  423. package/.next/static/chunks/2ajs12-fcdwzm.js +0 -1
  424. package/.next/static/chunks/2i7qtmxc1kuqg.js +0 -1
  425. package/.next/static/chunks/2kz1f6r59nky0.js +0 -3
  426. package/.next/static/chunks/31kn4_h2rvf6k.css +0 -1
  427. package/.next/static/chunks/35jj-5u4te56r.js +0 -1
  428. package/.next/static/chunks/37ixzapa06xlo.js +0 -1
  429. package/.next/static/chunks/3jtcieuk1l6tw.js +0 -1
  430. package/.next/static/chunks/3k1d8y03t5nax.js +0 -58
  431. package/.next/static/chunks/3sla-dm1puqd1.js +0 -35
  432. package/.next/static/chunks/3t2c76awm9k_p.js +0 -1
  433. package/.next/static/chunks/3vrmcm31ih7gb.js +0 -1
  434. package/.next/static/chunks/3yiqr95d7ybeq.js +0 -15
  435. package/bin/autostart.mjs +0 -162
  436. /package/.next/server/app/api/{llm-model/catalog → bot/thread/file}/route/build-manifest.json +0 -0
  437. /package/.next/server/app/api/{llm-model/catalog → bot/thread/file}/route/server-reference-manifest.json +0 -0
  438. /package/.next/server/app/api/{llm-model/catalog → bot/thread/file}/route.js.map +0 -0
  439. /package/.next/server/app/api/llm-model/{credits → catalog/[provider]}/route/build-manifest.json +0 -0
  440. /package/.next/server/app/api/llm-model/{credits → catalog/[provider]}/route/server-reference-manifest.json +0 -0
  441. /package/.next/server/app/api/llm-model/{credits → catalog/[provider]}/route.js.map +0 -0
  442. /package/.next/static/{8I2hKtciyA9LXvd8txuOz → YhaRHJqObuAcXZe5VLFs0}/_buildManifest.js +0 -0
  443. /package/.next/static/{8I2hKtciyA9LXvd8txuOz → YhaRHJqObuAcXZe5VLFs0}/_clientMiddlewareManifest.js +0 -0
  444. /package/.next/static/{8I2hKtciyA9LXvd8txuOz → YhaRHJqObuAcXZe5VLFs0}/_ssgManifest.js +0 -0
package/bin/lock.mjs CHANGED
@@ -3,8 +3,11 @@
3
3
  // the phone a second time, so every message was answered twice. The second is refused, and
4
4
  // told where the first one is.
5
5
 
6
+ import { spawnSync } from "node:child_process";
6
7
  import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
7
8
  import { join } from "node:path";
9
+ import { backgroundJob } from "./background.mjs";
10
+ import { thursdayCommand } from "./tools.mjs";
8
11
 
9
12
  /** Beside the database, and named so a checkout never commits it (`*.local.*`). */
10
13
  const LOCK_FILE = "server.local.lock";
@@ -18,14 +21,110 @@ export function runningOn(home) {
18
21
  return null;
19
22
  }
20
23
  if (!Number.isInteger(held?.pid) || held.pid === process.pid) return null;
24
+ if (!stillRuns(held)) return null;
25
+ return {
26
+ pid: held.pid,
27
+ url: String(held.url ?? ""),
28
+ // Null from `pnpm dev`, and from a server started before the lock said
29
+ version: typeof held.version === "string" ? held.version : null,
30
+ background: held.background === true,
31
+ };
32
+ }
33
+
34
+ /**
35
+ * Whether the process a lock names is still the one that wrote it. A lock left by a process
36
+ * that died without its exit (a kill -9, a power cut) names a pid another process may hold
37
+ * after a restart, which would refuse every start until the file was deleted by hand: the pid
38
+ * is the writer only if it started when the lock says. Where `ps` cannot say (Windows), or the
39
+ * lock predates its start time, the live pid is all there is.
40
+ */
41
+ export function stillRuns(held) {
21
42
  try {
22
43
  // Signal 0 asks whether the process exists and sends nothing
23
44
  process.kill(held.pid, 0);
24
45
  } catch (error) {
25
46
  // Someone else's process by that id is still a live one
26
- if (error?.code !== "EPERM") return null;
47
+ if (error?.code !== "EPERM") return false;
27
48
  }
28
- return { pid: held.pid, url: String(held.url ?? "") };
49
+ // Compared in UTC: `ps` writes the reader's zone, and a server under launchd (no TZ), a
50
+ // terminal that exports one, or a Mac that moved zones since it started spelled one start
51
+ // two ways — the server read as gone, and a second one opened the same database. A lock
52
+ // written before `startedUtc` has `started` alone, in its writer's zone.
53
+ const [said, zone] =
54
+ typeof held.startedUtc === "string"
55
+ ? [held.startedUtc, "UTC"]
56
+ : [held.started, undefined];
57
+ if (typeof said !== "string") return true;
58
+ const started = startedAt(held.pid, zone);
59
+ return !started || started === said;
60
+ }
61
+
62
+ /**
63
+ * Whether the server holding this folder is `pid`, or runs under it: launchd knows a job by the
64
+ * process it started, and a version manager's shim (Volta's) starts node as its child rather
65
+ * than becoming it.
66
+ */
67
+ export function heldBy(running, pid) {
68
+ if (!running || !pid) return false;
69
+ return (
70
+ running.pid === pid ||
71
+ Number(ps(["-o", "ppid=", "-p", String(running.pid)])) === pid
72
+ );
73
+ }
74
+
75
+ // LC_ALL=C: a start time is compared as `ps` wrote it, so both reads spell it alike
76
+ const ps = (args, zone) =>
77
+ spawnSync("ps", args, {
78
+ encoding: "utf8",
79
+ env: { ...process.env, LC_ALL: "C", ...(zone ? { TZ: zone } : {}) },
80
+ }).stdout?.trim() ?? "";
81
+
82
+ /**
83
+ * When a process started, to the second, as `ps` has it in `zone` (the reader's own when none).
84
+ * Empty where it cannot say.
85
+ */
86
+ export const startedAt = (pid, zone) =>
87
+ ps(["-o", "lstart=", "-p", String(pid)], zone);
88
+
89
+ /**
90
+ * Where a process runs, as `ps` has it: the terminal it is attached to (null when none), when
91
+ * it started, and what was typed there — the leader of its process group, `pnpm dev` or
92
+ * `npx thursday-agent`, not the Node process under it. Null where `ps` cannot say (Windows).
93
+ */
94
+ function whereRuns(pid) {
95
+ const [tty, group, ...started] = ps([
96
+ "-o",
97
+ "tty=,pgid=,lstart=",
98
+ "-p",
99
+ String(pid),
100
+ ]).split(/\s+/);
101
+ if (!tty || !group) return null;
102
+ return {
103
+ terminal: tty === "??" || tty === "?" ? null : tty,
104
+ group,
105
+ // "Fri Sep 25 20:55:51 2026" to the minute, in the reader's zone: it is read, not compared
106
+ since: started.join(" ").replace(/:\d\d \d{4}$/, ""),
107
+ typed: ps(["-o", "command=", "-p", group]),
108
+ };
109
+ }
110
+
111
+ /**
112
+ * How to stop the server with this pid, said where it can be done. A person told only "stop
113
+ * it" looked for a terminal they could not find: the one it runs in is named, with a command
114
+ * that does the same from any terminal. One that runs in the background is started again by
115
+ * launchd, so it is stopped by stopping that. Lines to print, without indent.
116
+ */
117
+ export function stopLines(pid, home) {
118
+ const where = whereRuns(pid);
119
+ if (where?.terminal)
120
+ return [
121
+ `It runs in a terminal (${where.terminal}${where.typed ? `, ${where.typed}` : ""}, since ${where.since}).`,
122
+ `Ctrl+C there, or from any terminal: kill -INT -${where.group}`,
123
+ ];
124
+ if (backgroundJob()?.home === home)
125
+ return [`It runs in the background. To stop it: ${thursdayCommand()} stop`];
126
+ if (where) return [`It runs in the background. To stop it: kill ${pid}`];
127
+ return ["Ctrl+C where it runs."];
29
128
  }
30
129
 
31
130
  /** Exits with where the running one is, when this folder already has a server. */
@@ -33,17 +132,34 @@ export function refuseSecond(home) {
33
132
  const running = runningOn(home);
34
133
  if (!running) return;
35
134
  console.error(
36
- `\n Thursday is already running on this data folder${running.url ? `: ${running.url}` : ""}\n Open that one, or stop it first (Ctrl+C where it runs; one that starts with the\n computer stops with: thursday autostart --off).\n`,
135
+ `\n Thursday is already running on this data folder${running.url ? `: ${running.url}` : ""}\n Open that one, or stop it first.\n${stopLines(
136
+ running.pid,
137
+ home,
138
+ )
139
+ .map((line) => ` ${line}\n`)
140
+ .join("")}`,
37
141
  );
38
142
  process.exit(1);
39
143
  }
40
144
 
41
145
  /** Marks this folder as served from here until this process ends. */
42
- export function holdFolder(home, url) {
146
+ export function holdFolder(home, url, version) {
43
147
  const file = join(home, LOCK_FILE);
44
148
  try {
45
149
  mkdirSync(home, { recursive: true });
46
- writeFileSync(file, `${JSON.stringify({ pid: process.pid, url })}\n`);
150
+ writeFileSync(
151
+ file,
152
+ `${JSON.stringify({
153
+ pid: process.pid,
154
+ startedUtc: startedAt(process.pid, "UTC") || undefined,
155
+ // What a starter from before `startedUtc` reads, in this process's zone
156
+ started: startedAt(process.pid) || undefined,
157
+ url,
158
+ version,
159
+ // Which one launchd started, so a stop can end it when launchd did not (background.mjs)
160
+ background: process.env.THURSDAY_BACKGROUND ? true : undefined,
161
+ })}\n`,
162
+ );
47
163
  } catch {
48
164
  // A folder that cannot be written is not a reason not to serve
49
165
  return;
package/bin/thursday.mjs CHANGED
@@ -14,12 +14,19 @@ import {
14
14
  symlinkSync,
15
15
  } from "node:fs";
16
16
  import { readFile } from "node:fs/promises";
17
- import { homedir } from "node:os";
18
17
  import { join, resolve } from "node:path";
18
+ import { backgroundJob, keepLogShort, offerBackground } from "./background.mjs";
19
19
  import { askToSetDatabaseAside, MIGRATION_FAILED_EXIT } from "./database.mjs";
20
- import { holdFolder, refuseSecond } from "./lock.mjs";
20
+ import { holdFolder, runningOn, stopLines } from "./lock.mjs";
21
21
  import { freePort } from "./port.mjs";
22
- import { ROOT, toolPath } from "./tools.mjs";
22
+ import {
23
+ commandFor,
24
+ DEFAULT_HOME,
25
+ openBrowser,
26
+ ROOT,
27
+ thursdayCommand,
28
+ toolPath,
29
+ } from "./tools.mjs";
23
30
 
24
31
  const { version, name } = JSON.parse(
25
32
  await readFile(join(ROOT, "package.json"), "utf8"),
@@ -34,12 +41,16 @@ const flag = (name) => {
34
41
  };
35
42
 
36
43
  if (has("-h", "--help")) {
44
+ const command = thursdayCommand();
37
45
  console.log(`
38
46
  ${name} ${version}
39
47
 
40
48
  Usage
41
- $ thursday [options]
42
- $ thursday autostart [--off] Start with the computer, macOS only
49
+ $ ${command} [options] Start it here, in this terminal
50
+ $ ${command} start [options] Keep it running in the background, and start it
51
+ when you log in (macOS)
52
+ $ ${command} stop Stop it in the background
53
+ $ ${command} status Whether it runs, where, and how to reach it
43
54
 
44
55
  Options
45
56
  --port <n> Port to serve on (default 4747, or the next free one)
@@ -71,30 +82,112 @@ if (!APP) {
71
82
  process.exit(1);
72
83
  }
73
84
 
85
+ // An exported `PORT=` with nothing in it asks for no port
86
+ const asked = flag("port") ?? (process.env.PORT?.trim() || undefined);
87
+ const home = resolve(flag("home") || process.env.THURSDAY_HOME || DEFAULT_HOME);
88
+
89
+ // The background (background.mjs): each is the whole command, and never goes on to serve.
90
+ // `autostart` and `autostart --off` are what earlier versions called start and stop.
91
+ const said =
92
+ argv[0] === "autostart" ? (has("--off") ? "stop" : "start") : argv[0];
93
+ const background = ["start", "stop", "status"].includes(said) ? said : null;
94
+ /** A start that could not run it in the background, and serves in this terminal instead. */
95
+ let fellBack = false;
96
+ if (background) {
97
+ const { printStatus, startInBackground, stopBackground } = await import(
98
+ "./background.mjs"
99
+ );
100
+ if (background === "status") {
101
+ printStatus({ home });
102
+ process.exit(0);
103
+ }
104
+ if (background === "stop")
105
+ process.exit((await stopBackground({ home })) ? 0 : 1);
106
+ const started = await startInBackground({
107
+ root: ROOT,
108
+ home,
109
+ port: asked,
110
+ open: !has("--no-open"),
111
+ version,
112
+ });
113
+ if (started === true) process.exit(0);
114
+ // A person at a terminal still gets it running, there, for as long as it stays open, as the
115
+ // first run's question does. "held" is a folder something else serves already; a script
116
+ // gets the failure
117
+ if (started === "held" || !process.stdin.isTTY || !process.stdout.isTTY)
118
+ process.exit(1);
119
+ fellBack = true;
120
+ }
121
+
74
122
  /**
75
- * The user's files: database, workspace, installed skills. An installed package
76
- * keeps them in the home folder, never inside the package — an upgrade replaces
77
- * that. A checkout keeps them in the checkout, which is where `pnpm dev` already
78
- * writes them (config.ts DATA_DIR): a build started here opens the data it was
79
- * developed against, not a second, empty one beside it.
123
+ * Leaves when this folder already has a server: a second one would take the next port, and
124
+ * serve the same calls, jobs and phone twice (lock.mjs). Run again, it is usually the app they
125
+ * came for — a second `npx` once its tab is closed — so that one opens instead. One of another
126
+ * version does not: they ran this one to have this one.
80
127
  */
81
- const DEFAULT_HOME = APP === ROOT ? join(homedir(), ".thursday") : ROOT;
128
+ function leaveToRunning() {
129
+ const running = runningOn(home);
130
+ if (!running) return;
131
+ const other =
132
+ running.version && running.version !== version ? running.version : null;
133
+ const opens = Boolean(running.url) && !other && !has("--no-open");
134
+ // The copy in the background moves to this version by starting it from this one: through
135
+ // npx pinned, since a bare `npx thursday-agent` is whichever version npm resolves that day
136
+ const command = thursdayCommand();
137
+ const moves =
138
+ other && backgroundJob()?.home === home
139
+ ? ` To move it to ${version}: ${commandFor(
140
+ "start",
141
+ home,
142
+ command === "npx thursday-agent"
143
+ ? `npx thursday-agent@${version}`
144
+ : command,
145
+ )}\n`
146
+ : null;
147
+ console.log(
148
+ `\n Thursday${other ? ` ${other}` : ""} is already running on this data folder${running.url ? `: ${running.url}` : ""}\n${
149
+ opens
150
+ ? " Opened it in your browser.\n"
151
+ : (moves ??
152
+ (other
153
+ ? ` To run ${version} instead, stop that one and run this again.\n`
154
+ : ""))
155
+ }${
156
+ moves
157
+ ? ""
158
+ : stopLines(running.pid, home)
159
+ .map((line) => ` ${line}\n`)
160
+ .join("")
161
+ }`,
162
+ );
163
+ if (opens) openBrowser(running.url);
164
+ process.exit(other ? 1 : 0);
165
+ }
82
166
 
83
- const asked = flag("port") ?? process.env.PORT;
84
- const home = resolve(flag("home") || process.env.THURSDAY_HOME || DEFAULT_HOME);
167
+ // Before a port is picked
168
+ leaveToRunning();
85
169
 
86
- // Turning it on or off is the whole command; it never goes on to serve.
87
- if (argv[0] === "autostart") {
88
- const { autostart } = await import("./autostart.mjs");
89
- await autostart({ root: ROOT, home, off: has("--off") });
90
- process.exit(0);
170
+ if (fellBack) console.log(" Running it in this terminal instead.");
171
+ else {
172
+ // A first run in a terminal asks once whether to keep it running in the background; said
173
+ // yes, the background serves and this run is done
174
+ const chose = await offerBackground({
175
+ root: ROOT,
176
+ home,
177
+ port: asked,
178
+ open: !has("--no-open"),
179
+ version,
180
+ });
181
+ if (chose !== "terminal") process.exit(chose === "background" ? 0 : 1);
91
182
  }
92
-
93
- // Before a port is picked: a second server on this folder would take the next one
94
- refuseSecond(home);
183
+ // The question waits as long as the person does, and a start takes a minute: a server another
184
+ // terminal started on this folder meanwhile is the one to use, not a second beside it
185
+ leaveToRunning();
95
186
  const port = String(await freePort(asked, home));
96
187
  const url = `http://localhost:${port}`;
97
- holdFolder(home, url);
188
+ holdFolder(home, url, version);
189
+ // launchd writes the background's output to a log that nothing else trims
190
+ if (process.env.THURSDAY_BACKGROUND) keepLogShort(home);
98
191
  /** Where config.ts DB_PATH puts the database under the home. */
99
192
  const database = join(home, "local.db");
100
193
 
@@ -140,6 +233,15 @@ function start() {
140
233
  THURSDAY_URL: url,
141
234
  // Where a bot's shell finds playwright-cli (workspace.ts TOOL_PATH)
142
235
  THURSDAY_TOOL_PATH: toolPath().join(":"),
236
+ // How it was started and what the person types to run it, for Settings to say where it
237
+ // runs and how to stop or keep it (features/settings/running.ts)
238
+ THURSDAY_RUNS: process.env.THURSDAY_BACKGROUND
239
+ ? "background"
240
+ : process.stdin.isTTY
241
+ ? "terminal"
242
+ : "elsewhere",
243
+ THURSDAY_COMMAND: thursdayCommand(),
244
+ THURSDAY_START: commandFor("start", home),
143
245
  PORT: port,
144
246
  // This machine only. A voice agent with a shell is not a thing to expose.
145
247
  // Never inherited: Docker exports HOSTNAME as the container and some
@@ -162,18 +264,12 @@ function start() {
162
264
  });
163
265
 
164
266
  if (opened) return;
165
- const open =
166
- process.platform === "darwin"
167
- ? ["open", [url]]
168
- : process.platform === "win32"
169
- ? ["cmd", ["/c", "start", "", url]]
170
- : ["xdg-open", [url]];
171
267
  // After the port is listening, and only on a server still up: one that could
172
- // not migrate is asking in the terminal. A browser that will not open is not a failure
268
+ // not migrate is asking in the terminal
173
269
  setTimeout(() => {
174
270
  if (opened || server.exitCode !== null) return;
175
271
  opened = true;
176
- spawn(open[0], open[1], { stdio: "ignore" }).on("error", () => {});
272
+ openBrowser(url);
177
273
  }, 1500).unref();
178
274
  }
179
275
  start();
package/bin/tools.mjs CHANGED
@@ -2,14 +2,85 @@
2
2
  // imports: this runs from the published `bin`, on a machine that has neither a
3
3
  // build nor a TypeScript loader.
4
4
 
5
+ import { spawn } from "node:child_process";
6
+ import { existsSync } from "node:fs";
5
7
  import { createRequire } from "node:module";
6
- import { dirname, join, resolve } from "node:path";
8
+ import { homedir } from "node:os";
9
+ import { dirname, join, resolve, sep } from "node:path";
7
10
 
8
11
  const require = createRequire(import.meta.url);
9
12
 
10
13
  /** The checkout, or the installed package. */
11
14
  export const ROOT = resolve(import.meta.dirname, "..");
12
15
 
16
+ /**
17
+ * Where the copy that runs in the background is installed (background.mjs). Beside the
18
+ * default data folder, so everything the app keeps on the computer is under one folder.
19
+ */
20
+ export const PROGRAM = join(homedir(), ".thursday", "app");
21
+
22
+ /** The one copy with the dev script beside it; the package ships no `scripts`. */
23
+ export const isCheckout = (root) =>
24
+ existsSync(join(root, "scripts", "dev.mts"));
25
+
26
+ /**
27
+ * The user's files when no `--home` is given: database, workspace, installed skills. An
28
+ * installed package keeps them in the home folder, never inside the package — an upgrade
29
+ * replaces that. A checkout keeps them in the checkout, which is where `pnpm dev` already
30
+ * writes them (config.ts DATA_DIR): a build started here opens the data it was developed
31
+ * against, not a second, empty one beside it.
32
+ */
33
+ export const DEFAULT_HOME = isCheckout(ROOT)
34
+ ? ROOT
35
+ : join(homedir(), ".thursday");
36
+
37
+ /**
38
+ * What this person types to run the app, for a line that tells them to run it again. Only a
39
+ * global install puts `thursday` on the PATH: said to someone who ran `npx`, it is a command
40
+ * they do not have. npx names itself in npm_lifecycle_event and unpacks into its `_npx` cache,
41
+ * and the copy that runs in the background was put there from one.
42
+ */
43
+ export function thursdayCommand() {
44
+ // Written into the background job by the command that started it, which knew
45
+ if (process.env.THURSDAY_COMMAND?.trim())
46
+ return process.env.THURSDAY_COMMAND.trim();
47
+ if (
48
+ process.env.npm_lifecycle_event === "npx" ||
49
+ ROOT.includes(`${sep}_npx${sep}`) ||
50
+ ROOT.startsWith(`${PROGRAM}${sep}`)
51
+ )
52
+ return "npx thursday-agent";
53
+ if (isCheckout(ROOT)) return "pnpm start";
54
+ return "thursday";
55
+ }
56
+
57
+ /**
58
+ * The line to type for `sub` — start, stop, status, or "" to run it in a terminal — on this
59
+ * data folder: `--home` is said when it is not the one the command finds by itself. Followed
60
+ * as printed without it, a line served another folder, an empty app or a checkout's own data.
61
+ */
62
+ export function commandFor(sub, home, command = thursdayCommand()) {
63
+ const line = sub ? `${command} ${sub}` : command;
64
+ return home && resolve(home) !== DEFAULT_HOME
65
+ ? `${line} --home ${shellWord(home)}`
66
+ : line;
67
+ }
68
+
69
+ /** A path a shell reads back as it is: quoted once it holds more than plain characters. */
70
+ const shellWord = (path) =>
71
+ /^[\w@%+=:,./-]+$/.test(path) ? path : `'${path.replaceAll("'", `'\\''`)}'`;
72
+
73
+ /** A browser that will not open is not a failure. */
74
+ export function openBrowser(url) {
75
+ const [command, args] =
76
+ process.platform === "darwin"
77
+ ? ["open", [url]]
78
+ : process.platform === "win32"
79
+ ? ["cmd", ["/c", "start", "", url]]
80
+ : ["xdg-open", [url]];
81
+ spawn(command, args, { stdio: "ignore" }).on("error", () => {});
82
+ }
83
+
13
84
  /**
14
85
  * The `playwright-cli` entry, resolved rather than guessed: pnpm keeps it under
15
86
  * `.pnpm`, npm hoists it, npx puts it in a temp tree. Null when it is not
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `thread` ADD `cache_read_tokens` integer DEFAULT 0 NOT NULL;--> statement-breakpoint
2
+ ALTER TABLE `thread` ADD `cache_write_tokens` integer DEFAULT 0 NOT NULL;