@withbuddi/buddi 0.1.0-pre.28 → 0.1.0-pre.29

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 (985) hide show
  1. package/README.md +3 -1
  2. package/extension/manifest.json +2 -2
  3. package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
  4. package/node_modules/@buddi/cli/dist/args.d.ts +13 -2
  5. package/node_modules/@buddi/cli/dist/args.d.ts.map +1 -1
  6. package/node_modules/@buddi/cli/dist/args.js +12 -3
  7. package/node_modules/@buddi/cli/dist/args.js.map +1 -1
  8. package/node_modules/@buddi/cli/dist/commands.d.ts.map +1 -1
  9. package/node_modules/@buddi/cli/dist/commands.js +67 -5
  10. package/node_modules/@buddi/cli/dist/commands.js.map +1 -1
  11. package/node_modules/@buddi/cli/dist/dashboard-cmd.d.ts +3 -0
  12. package/node_modules/@buddi/cli/dist/dashboard-cmd.d.ts.map +1 -1
  13. package/node_modules/@buddi/cli/dist/dashboard-cmd.js +63 -0
  14. package/node_modules/@buddi/cli/dist/dashboard-cmd.js.map +1 -1
  15. package/node_modules/@buddi/cli/dist/doctor-probes.d.ts.map +1 -1
  16. package/node_modules/@buddi/cli/dist/doctor-probes.js +9 -3
  17. package/node_modules/@buddi/cli/dist/doctor-probes.js.map +1 -1
  18. package/node_modules/@buddi/cli/dist/doctor.d.ts +1 -1
  19. package/node_modules/@buddi/cli/dist/doctor.d.ts.map +1 -1
  20. package/node_modules/@buddi/cli/dist/main.d.ts.map +1 -1
  21. package/node_modules/@buddi/cli/dist/main.js +22 -1
  22. package/node_modules/@buddi/cli/dist/main.js.map +1 -1
  23. package/node_modules/@buddi/cli/dist/mcp/gateway-client.d.ts +19 -17
  24. package/node_modules/@buddi/cli/dist/mcp/gateway-client.d.ts.map +1 -1
  25. package/node_modules/@buddi/cli/dist/mcp/gateway-client.js +128 -29
  26. package/node_modules/@buddi/cli/dist/mcp/gateway-client.js.map +1 -1
  27. package/node_modules/@buddi/cli/dist/mcp/tools.d.ts +6 -0
  28. package/node_modules/@buddi/cli/dist/mcp/tools.d.ts.map +1 -1
  29. package/node_modules/@buddi/cli/dist/mcp/tools.js +20 -1
  30. package/node_modules/@buddi/cli/dist/mcp/tools.js.map +1 -1
  31. package/node_modules/@buddi/cli/dist/telegram-cmd.d.ts.map +1 -1
  32. package/node_modules/@buddi/cli/dist/telegram-cmd.js +5 -4
  33. package/node_modules/@buddi/cli/dist/telegram-cmd.js.map +1 -1
  34. package/node_modules/@buddi/core/dist/.tsbuildinfo +1 -1
  35. package/node_modules/@buddi/core/dist/agents/catalog.d.ts.map +1 -1
  36. package/node_modules/@buddi/core/dist/agents/catalog.js +7 -6
  37. package/node_modules/@buddi/core/dist/agents/catalog.js.map +1 -1
  38. package/node_modules/@buddi/core/dist/agents/frontmatter.d.ts +12 -12
  39. package/node_modules/@buddi/core/dist/agents/skills.d.ts +2 -2
  40. package/node_modules/@buddi/core/dist/clock-widget.d.ts +38 -0
  41. package/node_modules/@buddi/core/dist/clock-widget.d.ts.map +1 -0
  42. package/node_modules/@buddi/core/dist/clock-widget.js +114 -0
  43. package/node_modules/@buddi/core/dist/clock-widget.js.map +1 -0
  44. package/node_modules/@buddi/core/dist/failures/owner-message.d.ts +25 -0
  45. package/node_modules/@buddi/core/dist/failures/owner-message.d.ts.map +1 -1
  46. package/node_modules/@buddi/core/dist/failures/owner-message.js +90 -0
  47. package/node_modules/@buddi/core/dist/failures/owner-message.js.map +1 -1
  48. package/node_modules/@buddi/core/dist/feedback/index.d.ts +23 -2
  49. package/node_modules/@buddi/core/dist/feedback/index.d.ts.map +1 -1
  50. package/node_modules/@buddi/core/dist/feedback/index.js +23 -3
  51. package/node_modules/@buddi/core/dist/feedback/index.js.map +1 -1
  52. package/node_modules/@buddi/core/dist/groups.d.ts +33 -0
  53. package/node_modules/@buddi/core/dist/groups.d.ts.map +1 -1
  54. package/node_modules/@buddi/core/dist/groups.js +76 -4
  55. package/node_modules/@buddi/core/dist/groups.js.map +1 -1
  56. package/node_modules/@buddi/core/dist/home.d.ts +5 -5
  57. package/node_modules/@buddi/core/dist/host/build.d.ts +19 -1
  58. package/node_modules/@buddi/core/dist/host/build.d.ts.map +1 -1
  59. package/node_modules/@buddi/core/dist/host/build.js +122 -2
  60. package/node_modules/@buddi/core/dist/host/build.js.map +1 -1
  61. package/node_modules/@buddi/core/dist/host/types.d.ts +33 -0
  62. package/node_modules/@buddi/core/dist/host/types.d.ts.map +1 -1
  63. package/node_modules/@buddi/core/dist/index.d.ts +8 -0
  64. package/node_modules/@buddi/core/dist/index.d.ts.map +1 -1
  65. package/node_modules/@buddi/core/dist/index.js +8 -0
  66. package/node_modules/@buddi/core/dist/index.js.map +1 -1
  67. package/node_modules/@buddi/core/dist/lock.d.ts +76 -0
  68. package/node_modules/@buddi/core/dist/lock.d.ts.map +1 -0
  69. package/node_modules/@buddi/core/dist/lock.js +167 -0
  70. package/node_modules/@buddi/core/dist/lock.js.map +1 -0
  71. package/node_modules/@buddi/core/dist/metrics.d.ts.map +1 -1
  72. package/node_modules/@buddi/core/dist/metrics.js +4 -2
  73. package/node_modules/@buddi/core/dist/metrics.js.map +1 -1
  74. package/node_modules/@buddi/core/dist/onboarding/store.d.ts +5 -0
  75. package/node_modules/@buddi/core/dist/onboarding/store.d.ts.map +1 -1
  76. package/node_modules/@buddi/core/dist/onboarding/store.js +35 -5
  77. package/node_modules/@buddi/core/dist/onboarding/store.js.map +1 -1
  78. package/node_modules/@buddi/core/dist/onboarding/types.d.ts +10 -0
  79. package/node_modules/@buddi/core/dist/onboarding/types.d.ts.map +1 -1
  80. package/node_modules/@buddi/core/dist/onboarding/types.js +2 -0
  81. package/node_modules/@buddi/core/dist/onboarding/types.js.map +1 -1
  82. package/node_modules/@buddi/core/dist/owner-format.d.ts +14 -0
  83. package/node_modules/@buddi/core/dist/owner-format.d.ts.map +1 -0
  84. package/node_modules/@buddi/core/dist/owner-format.js +47 -0
  85. package/node_modules/@buddi/core/dist/owner-format.js.map +1 -0
  86. package/node_modules/@buddi/core/dist/owner-timezone.d.ts +46 -0
  87. package/node_modules/@buddi/core/dist/owner-timezone.d.ts.map +1 -0
  88. package/node_modules/@buddi/core/dist/owner-timezone.js +43 -0
  89. package/node_modules/@buddi/core/dist/owner-timezone.js.map +1 -0
  90. package/node_modules/@buddi/core/dist/pages.d.ts +10 -38
  91. package/node_modules/@buddi/core/dist/pages.d.ts.map +1 -1
  92. package/node_modules/@buddi/core/dist/pages.js +6 -0
  93. package/node_modules/@buddi/core/dist/pages.js.map +1 -1
  94. package/node_modules/@buddi/core/dist/places.d.ts +110 -0
  95. package/node_modules/@buddi/core/dist/places.d.ts.map +1 -0
  96. package/node_modules/@buddi/core/dist/places.js +239 -0
  97. package/node_modules/@buddi/core/dist/places.js.map +1 -0
  98. package/node_modules/@buddi/core/dist/plugin/index.d.ts +8 -1
  99. package/node_modules/@buddi/core/dist/plugin/index.d.ts.map +1 -1
  100. package/node_modules/@buddi/core/dist/plugin/index.js +3 -0
  101. package/node_modules/@buddi/core/dist/plugin/index.js.map +1 -1
  102. package/node_modules/@buddi/core/dist/plugin/requires.d.ts +75 -0
  103. package/node_modules/@buddi/core/dist/plugin/requires.d.ts.map +1 -0
  104. package/node_modules/@buddi/core/dist/plugin/requires.js +77 -0
  105. package/node_modules/@buddi/core/dist/plugin/requires.js.map +1 -0
  106. package/node_modules/@buddi/core/dist/plugin/uses.d.ts +1 -1
  107. package/node_modules/@buddi/core/dist/plugin/uses.d.ts.map +1 -1
  108. package/node_modules/@buddi/core/dist/plugin/uses.js +2 -0
  109. package/node_modules/@buddi/core/dist/plugin/uses.js.map +1 -1
  110. package/node_modules/@buddi/core/dist/plugin/version.d.ts +1 -1
  111. package/node_modules/@buddi/core/dist/plugin/version.js +1 -1
  112. package/node_modules/@buddi/core/dist/queue/retry-policy.d.ts +5 -0
  113. package/node_modules/@buddi/core/dist/queue/retry-policy.d.ts.map +1 -1
  114. package/node_modules/@buddi/core/dist/queue/retry-policy.js +19 -2
  115. package/node_modules/@buddi/core/dist/queue/retry-policy.js.map +1 -1
  116. package/node_modules/@buddi/core/dist/registry.d.ts +37 -2
  117. package/node_modules/@buddi/core/dist/registry.d.ts.map +1 -1
  118. package/node_modules/@buddi/core/dist/registry.js +137 -3
  119. package/node_modules/@buddi/core/dist/registry.js.map +1 -1
  120. package/node_modules/@buddi/core/dist/scheduler/enqueue.d.ts +71 -0
  121. package/node_modules/@buddi/core/dist/scheduler/enqueue.d.ts.map +1 -0
  122. package/node_modules/@buddi/core/dist/scheduler/enqueue.js +116 -0
  123. package/node_modules/@buddi/core/dist/scheduler/enqueue.js.map +1 -0
  124. package/node_modules/@buddi/core/dist/scheduler/index.d.ts +1 -0
  125. package/node_modules/@buddi/core/dist/scheduler/index.d.ts.map +1 -1
  126. package/node_modules/@buddi/core/dist/scheduler/index.js +1 -0
  127. package/node_modules/@buddi/core/dist/scheduler/index.js.map +1 -1
  128. package/node_modules/@buddi/core/dist/scheduler/missions.d.ts +15 -0
  129. package/node_modules/@buddi/core/dist/scheduler/missions.d.ts.map +1 -1
  130. package/node_modules/@buddi/core/dist/scheduler/missions.js +43 -4
  131. package/node_modules/@buddi/core/dist/scheduler/missions.js.map +1 -1
  132. package/node_modules/@buddi/core/dist/scheduler/types.d.ts +10 -0
  133. package/node_modules/@buddi/core/dist/scheduler/types.d.ts.map +1 -1
  134. package/node_modules/@buddi/core/dist/scheduler/types.js +3 -0
  135. package/node_modules/@buddi/core/dist/scheduler/types.js.map +1 -1
  136. package/node_modules/@buddi/core/dist/secrets/settings.d.ts +6 -6
  137. package/node_modules/@buddi/core/dist/semver.d.ts +17 -0
  138. package/node_modules/@buddi/core/dist/semver.d.ts.map +1 -1
  139. package/node_modules/@buddi/core/dist/semver.js +130 -0
  140. package/node_modules/@buddi/core/dist/semver.js.map +1 -1
  141. package/node_modules/@buddi/core/dist/sentinels/run.d.ts +6 -1
  142. package/node_modules/@buddi/core/dist/sentinels/run.d.ts.map +1 -1
  143. package/node_modules/@buddi/core/dist/sentinels/run.js +43 -24
  144. package/node_modules/@buddi/core/dist/sentinels/run.js.map +1 -1
  145. package/node_modules/@buddi/core/dist/sentinels/types.d.ts +13 -0
  146. package/node_modules/@buddi/core/dist/sentinels/types.d.ts.map +1 -1
  147. package/node_modules/@buddi/core/dist/sentinels/types.js.map +1 -1
  148. package/node_modules/@buddi/core/dist/sources/run.d.ts +8 -0
  149. package/node_modules/@buddi/core/dist/sources/run.d.ts.map +1 -1
  150. package/node_modules/@buddi/core/dist/sources/run.js +1 -1
  151. package/node_modules/@buddi/core/dist/sources/run.js.map +1 -1
  152. package/node_modules/@buddi/core/dist/sources/watch.d.ts +3 -0
  153. package/node_modules/@buddi/core/dist/sources/watch.d.ts.map +1 -1
  154. package/node_modules/@buddi/core/dist/sources/watch.js +1 -1
  155. package/node_modules/@buddi/core/dist/sources/watch.js.map +1 -1
  156. package/node_modules/@buddi/core/dist/time.d.ts +17 -3
  157. package/node_modules/@buddi/core/dist/time.d.ts.map +1 -1
  158. package/node_modules/@buddi/core/dist/time.js +27 -3
  159. package/node_modules/@buddi/core/dist/time.js.map +1 -1
  160. package/node_modules/@buddi/core/dist/tools.d.ts +30 -1
  161. package/node_modules/@buddi/core/dist/tools.d.ts.map +1 -1
  162. package/node_modules/@buddi/core/dist/tools.js.map +1 -1
  163. package/node_modules/@buddi/core/dist/views.d.ts +68 -68
  164. package/node_modules/@buddi/core/dist/views.d.ts.map +1 -1
  165. package/node_modules/@buddi/core/dist/views.js +3 -0
  166. package/node_modules/@buddi/core/dist/views.js.map +1 -1
  167. package/node_modules/@buddi/core/dist/widget-settings.d.ts +161 -0
  168. package/node_modules/@buddi/core/dist/widget-settings.d.ts.map +1 -0
  169. package/node_modules/@buddi/core/dist/widget-settings.js +314 -0
  170. package/node_modules/@buddi/core/dist/widget-settings.js.map +1 -0
  171. package/node_modules/@buddi/core/dist/widgets.d.ts +206 -0
  172. package/node_modules/@buddi/core/dist/widgets.d.ts.map +1 -0
  173. package/node_modules/@buddi/core/dist/widgets.js +247 -0
  174. package/node_modules/@buddi/core/dist/widgets.js.map +1 -0
  175. package/node_modules/@buddi/core/migrations/059_dashboard_lock.sql +33 -0
  176. package/node_modules/@buddi/core/migrations/060_owner_places.sql +30 -0
  177. package/node_modules/@buddi/core/migrations/061_owner_formats.sql +10 -0
  178. package/node_modules/@buddi/core/migrations/062_group_deleted.sql +7 -0
  179. package/node_modules/@buddi/core/migrations/063_provider_account_limits.sql +20 -0
  180. package/node_modules/@buddi/core/migrations/064_mission_coalesce.sql +12 -0
  181. package/node_modules/@buddi/core/migrations/065_api_tokens.sql +28 -0
  182. package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
  183. package/node_modules/@buddi/gateway/dist/account-limits.d.ts +45 -0
  184. package/node_modules/@buddi/gateway/dist/account-limits.d.ts.map +1 -0
  185. package/node_modules/@buddi/gateway/dist/account-limits.js +87 -0
  186. package/node_modules/@buddi/gateway/dist/account-limits.js.map +1 -0
  187. package/node_modules/@buddi/gateway/dist/accounts-cli.d.ts +88 -0
  188. package/node_modules/@buddi/gateway/dist/accounts-cli.d.ts.map +1 -0
  189. package/node_modules/@buddi/gateway/dist/accounts-cli.js +216 -0
  190. package/node_modules/@buddi/gateway/dist/accounts-cli.js.map +1 -0
  191. package/node_modules/@buddi/gateway/dist/agents/canvas.d.ts +20 -20
  192. package/node_modules/@buddi/gateway/dist/agents/learning-digest.d.ts +4 -0
  193. package/node_modules/@buddi/gateway/dist/agents/learning-digest.d.ts.map +1 -1
  194. package/node_modules/@buddi/gateway/dist/agents/learning-digest.js +18 -5
  195. package/node_modules/@buddi/gateway/dist/agents/learning-digest.js.map +1 -1
  196. package/node_modules/@buddi/gateway/dist/agents/owner-tools.d.ts.map +1 -1
  197. package/node_modules/@buddi/gateway/dist/agents/owner-tools.js +3 -2
  198. package/node_modules/@buddi/gateway/dist/agents/owner-tools.js.map +1 -1
  199. package/node_modules/@buddi/gateway/dist/agents/platform.d.ts +24 -24
  200. package/node_modules/@buddi/gateway/dist/api-token-cli.d.ts +17 -0
  201. package/node_modules/@buddi/gateway/dist/api-token-cli.d.ts.map +1 -0
  202. package/node_modules/@buddi/gateway/dist/api-token-cli.js +108 -0
  203. package/node_modules/@buddi/gateway/dist/api-token-cli.js.map +1 -0
  204. package/node_modules/@buddi/gateway/dist/bootstrap.d.ts +6 -2
  205. package/node_modules/@buddi/gateway/dist/bootstrap.d.ts.map +1 -1
  206. package/node_modules/@buddi/gateway/dist/bootstrap.js +25 -7
  207. package/node_modules/@buddi/gateway/dist/bootstrap.js.map +1 -1
  208. package/node_modules/@buddi/gateway/dist/chat/session.d.ts +5 -0
  209. package/node_modules/@buddi/gateway/dist/chat/session.d.ts.map +1 -1
  210. package/node_modules/@buddi/gateway/dist/chat/session.js +11 -1
  211. package/node_modules/@buddi/gateway/dist/chat/session.js.map +1 -1
  212. package/node_modules/@buddi/gateway/dist/cli.d.ts.map +1 -1
  213. package/node_modules/@buddi/gateway/dist/cli.js +14 -3
  214. package/node_modules/@buddi/gateway/dist/cli.js.map +1 -1
  215. package/node_modules/@buddi/gateway/dist/index.d.ts +3 -0
  216. package/node_modules/@buddi/gateway/dist/index.d.ts.map +1 -1
  217. package/node_modules/@buddi/gateway/dist/index.js +3 -0
  218. package/node_modules/@buddi/gateway/dist/index.js.map +1 -1
  219. package/node_modules/@buddi/gateway/dist/missions/dead-letter.d.ts +2 -1
  220. package/node_modules/@buddi/gateway/dist/missions/dead-letter.d.ts.map +1 -1
  221. package/node_modules/@buddi/gateway/dist/missions/dead-letter.js +19 -5
  222. package/node_modules/@buddi/gateway/dist/missions/dead-letter.js.map +1 -1
  223. package/node_modules/@buddi/gateway/dist/missions/defaults.d.ts +6 -0
  224. package/node_modules/@buddi/gateway/dist/missions/defaults.d.ts.map +1 -1
  225. package/node_modules/@buddi/gateway/dist/missions/defaults.js +10 -2
  226. package/node_modules/@buddi/gateway/dist/missions/defaults.js.map +1 -1
  227. package/node_modules/@buddi/gateway/dist/missions/execute.d.ts.map +1 -1
  228. package/node_modules/@buddi/gateway/dist/missions/execute.js +14 -8
  229. package/node_modules/@buddi/gateway/dist/missions/execute.js.map +1 -1
  230. package/node_modules/@buddi/gateway/dist/missions/inline.js +1 -1
  231. package/node_modules/@buddi/gateway/dist/missions/inline.js.map +1 -1
  232. package/node_modules/@buddi/gateway/dist/missions/sentinel-wake.d.ts +11 -0
  233. package/node_modules/@buddi/gateway/dist/missions/sentinel-wake.d.ts.map +1 -1
  234. package/node_modules/@buddi/gateway/dist/missions/sentinel-wake.js +37 -1
  235. package/node_modules/@buddi/gateway/dist/missions/sentinel-wake.js.map +1 -1
  236. package/node_modules/@buddi/gateway/dist/missions-cli.d.ts.map +1 -1
  237. package/node_modules/@buddi/gateway/dist/missions-cli.js +5 -5
  238. package/node_modules/@buddi/gateway/dist/missions-cli.js.map +1 -1
  239. package/node_modules/@buddi/gateway/dist/nudges-cli.js +2 -2
  240. package/node_modules/@buddi/gateway/dist/nudges-cli.js.map +1 -1
  241. package/node_modules/@buddi/gateway/dist/owner-seed.js +2 -2
  242. package/node_modules/@buddi/gateway/dist/owner-seed.js.map +1 -1
  243. package/node_modules/@buddi/gateway/dist/plugins/live.d.ts +8 -1
  244. package/node_modules/@buddi/gateway/dist/plugins/live.d.ts.map +1 -1
  245. package/node_modules/@buddi/gateway/dist/plugins/live.js +25 -7
  246. package/node_modules/@buddi/gateway/dist/plugins/live.js.map +1 -1
  247. package/node_modules/@buddi/gateway/dist/plugins/load.d.ts +55 -0
  248. package/node_modules/@buddi/gateway/dist/plugins/load.d.ts.map +1 -1
  249. package/node_modules/@buddi/gateway/dist/plugins/load.js +100 -4
  250. package/node_modules/@buddi/gateway/dist/plugins/load.js.map +1 -1
  251. package/node_modules/@buddi/gateway/dist/plugins/requires.d.ts +79 -0
  252. package/node_modules/@buddi/gateway/dist/plugins/requires.d.ts.map +1 -0
  253. package/node_modules/@buddi/gateway/dist/plugins/requires.js +178 -0
  254. package/node_modules/@buddi/gateway/dist/plugins/requires.js.map +1 -0
  255. package/node_modules/@buddi/gateway/dist/plugins/stage.d.ts +6 -0
  256. package/node_modules/@buddi/gateway/dist/plugins/stage.d.ts.map +1 -1
  257. package/node_modules/@buddi/gateway/dist/plugins/stage.js +6 -1
  258. package/node_modules/@buddi/gateway/dist/plugins/stage.js.map +1 -1
  259. package/node_modules/@buddi/gateway/dist/plugins/update.d.ts +21 -0
  260. package/node_modules/@buddi/gateway/dist/plugins/update.d.ts.map +1 -1
  261. package/node_modules/@buddi/gateway/dist/plugins/update.js +16 -0
  262. package/node_modules/@buddi/gateway/dist/plugins/update.js.map +1 -1
  263. package/node_modules/@buddi/gateway/dist/plugins-cli.d.ts +1 -1
  264. package/node_modules/@buddi/gateway/dist/plugins-cli.d.ts.map +1 -1
  265. package/node_modules/@buddi/gateway/dist/plugins-cli.js +6 -2
  266. package/node_modules/@buddi/gateway/dist/plugins-cli.js.map +1 -1
  267. package/node_modules/@buddi/gateway/dist/provider-accounts.d.ts +4 -0
  268. package/node_modules/@buddi/gateway/dist/provider-accounts.d.ts.map +1 -1
  269. package/node_modules/@buddi/gateway/dist/provider-accounts.js +68 -10
  270. package/node_modules/@buddi/gateway/dist/provider-accounts.js.map +1 -1
  271. package/node_modules/@buddi/gateway/dist/provider-diagnostics.d.ts.map +1 -1
  272. package/node_modules/@buddi/gateway/dist/provider-diagnostics.js +9 -0
  273. package/node_modules/@buddi/gateway/dist/provider-diagnostics.js.map +1 -1
  274. package/node_modules/@buddi/gateway/dist/reminders-cli.js +2 -2
  275. package/node_modules/@buddi/gateway/dist/reminders-cli.js.map +1 -1
  276. package/node_modules/@buddi/gateway/dist/serve.d.ts +2 -0
  277. package/node_modules/@buddi/gateway/dist/serve.d.ts.map +1 -1
  278. package/node_modules/@buddi/gateway/dist/serve.js +66 -8
  279. package/node_modules/@buddi/gateway/dist/serve.js.map +1 -1
  280. package/node_modules/@buddi/gateway/dist/surfaces/failure.d.ts.map +1 -1
  281. package/node_modules/@buddi/gateway/dist/surfaces/failure.js +9 -1
  282. package/node_modules/@buddi/gateway/dist/surfaces/failure.js.map +1 -1
  283. package/node_modules/@buddi/gateway/dist/system-context.d.ts +18 -0
  284. package/node_modules/@buddi/gateway/dist/system-context.d.ts.map +1 -1
  285. package/node_modules/@buddi/gateway/dist/system-context.js +46 -4
  286. package/node_modules/@buddi/gateway/dist/system-context.js.map +1 -1
  287. package/node_modules/@buddi/gateway/dist/telegram/main.js +3 -3
  288. package/node_modules/@buddi/gateway/dist/telegram/main.js.map +1 -1
  289. package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts +1 -1
  290. package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts.map +1 -1
  291. package/node_modules/@buddi/gateway/dist/telegram/outbound.js +7 -2
  292. package/node_modules/@buddi/gateway/dist/telegram/outbound.js.map +1 -1
  293. package/node_modules/@buddi/gateway/dist/telegram/reactions.d.ts.map +1 -1
  294. package/node_modules/@buddi/gateway/dist/telegram/reactions.js +12 -2
  295. package/node_modules/@buddi/gateway/dist/telegram/reactions.js.map +1 -1
  296. package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts +4 -1
  297. package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts.map +1 -1
  298. package/node_modules/@buddi/gateway/dist/telegram/surface.js +13 -3
  299. package/node_modules/@buddi/gateway/dist/telegram/surface.js.map +1 -1
  300. package/node_modules/@buddi/gateway/dist/tips/engine.d.ts +2 -0
  301. package/node_modules/@buddi/gateway/dist/tips/engine.d.ts.map +1 -1
  302. package/node_modules/@buddi/gateway/dist/tips/engine.js +8 -5
  303. package/node_modules/@buddi/gateway/dist/tips/engine.js.map +1 -1
  304. package/node_modules/@buddi/gateway/dist/tips/facts.d.ts +23 -0
  305. package/node_modules/@buddi/gateway/dist/tips/facts.d.ts.map +1 -1
  306. package/node_modules/@buddi/gateway/dist/tips/facts.js +19 -0
  307. package/node_modules/@buddi/gateway/dist/tips/facts.js.map +1 -1
  308. package/node_modules/@buddi/gateway/dist/tips/route.js +2 -2
  309. package/node_modules/@buddi/gateway/dist/tips/route.js.map +1 -1
  310. package/node_modules/@buddi/gateway/dist/tips/rules.d.ts +3 -2
  311. package/node_modules/@buddi/gateway/dist/tips/rules.d.ts.map +1 -1
  312. package/node_modules/@buddi/gateway/dist/tips/rules.js +26 -0
  313. package/node_modules/@buddi/gateway/dist/tips/rules.js.map +1 -1
  314. package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts +103 -0
  315. package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts.map +1 -0
  316. package/node_modules/@buddi/gateway/dist/web/api-routes.js +1200 -0
  317. package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -0
  318. package/node_modules/@buddi/gateway/dist/web/api-scan.d.ts +17 -0
  319. package/node_modules/@buddi/gateway/dist/web/api-scan.d.ts.map +1 -0
  320. package/node_modules/@buddi/gateway/dist/web/api-scan.js +206 -0
  321. package/node_modules/@buddi/gateway/dist/web/api-scan.js.map +1 -0
  322. package/node_modules/@buddi/gateway/dist/web/api-tokens.d.ts +58 -0
  323. package/node_modules/@buddi/gateway/dist/web/api-tokens.d.ts.map +1 -0
  324. package/node_modules/@buddi/gateway/dist/web/api-tokens.js +136 -0
  325. package/node_modules/@buddi/gateway/dist/web/api-tokens.js.map +1 -0
  326. package/node_modules/@buddi/gateway/dist/web/backups.js +2 -2
  327. package/node_modules/@buddi/gateway/dist/web/backups.js.map +1 -1
  328. package/node_modules/@buddi/gateway/dist/web/group-lifecycle.d.ts +18 -0
  329. package/node_modules/@buddi/gateway/dist/web/group-lifecycle.d.ts.map +1 -0
  330. package/node_modules/@buddi/gateway/dist/web/group-lifecycle.js +46 -0
  331. package/node_modules/@buddi/gateway/dist/web/group-lifecycle.js.map +1 -0
  332. package/node_modules/@buddi/gateway/dist/web/lock-image.d.ts +37 -0
  333. package/node_modules/@buddi/gateway/dist/web/lock-image.d.ts.map +1 -0
  334. package/node_modules/@buddi/gateway/dist/web/lock-image.js +253 -0
  335. package/node_modules/@buddi/gateway/dist/web/lock-image.js.map +1 -0
  336. package/node_modules/@buddi/gateway/dist/web/lock.d.ts +162 -0
  337. package/node_modules/@buddi/gateway/dist/web/lock.d.ts.map +1 -0
  338. package/node_modules/@buddi/gateway/dist/web/lock.js +472 -0
  339. package/node_modules/@buddi/gateway/dist/web/lock.js.map +1 -0
  340. package/node_modules/@buddi/gateway/dist/web/pages.d.ts +1 -0
  341. package/node_modules/@buddi/gateway/dist/web/pages.d.ts.map +1 -1
  342. package/node_modules/@buddi/gateway/dist/web/pages.js +12 -1
  343. package/node_modules/@buddi/gateway/dist/web/pages.js.map +1 -1
  344. package/node_modules/@buddi/gateway/dist/web/places.d.ts +27 -0
  345. package/node_modules/@buddi/gateway/dist/web/places.d.ts.map +1 -0
  346. package/node_modules/@buddi/gateway/dist/web/places.js +90 -0
  347. package/node_modules/@buddi/gateway/dist/web/places.js.map +1 -0
  348. package/node_modules/@buddi/gateway/dist/web/plugins.d.ts +28 -0
  349. package/node_modules/@buddi/gateway/dist/web/plugins.d.ts.map +1 -1
  350. package/node_modules/@buddi/gateway/dist/web/plugins.js +69 -9
  351. package/node_modules/@buddi/gateway/dist/web/plugins.js.map +1 -1
  352. package/node_modules/@buddi/gateway/dist/web/server.d.ts +9 -0
  353. package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
  354. package/node_modules/@buddi/gateway/dist/web/server.js +406 -37
  355. package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
  356. package/node_modules/@buddi/gateway/dist/web/sessions.d.ts +43 -2
  357. package/node_modules/@buddi/gateway/dist/web/sessions.d.ts.map +1 -1
  358. package/node_modules/@buddi/gateway/dist/web/sessions.js +67 -3
  359. package/node_modules/@buddi/gateway/dist/web/sessions.js.map +1 -1
  360. package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts +17 -18
  361. package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts.map +1 -1
  362. package/node_modules/@buddi/gateway/dist/web/signed-out.js +135 -33
  363. package/node_modules/@buddi/gateway/dist/web/signed-out.js.map +1 -1
  364. package/node_modules/@buddi/gateway/dist/web/stream.d.ts.map +1 -1
  365. package/node_modules/@buddi/gateway/dist/web/stream.js +14 -0
  366. package/node_modules/@buddi/gateway/dist/web/stream.js.map +1 -1
  367. package/node_modules/@buddi/gateway/dist/web/tailscale.d.ts +33 -4
  368. package/node_modules/@buddi/gateway/dist/web/tailscale.d.ts.map +1 -1
  369. package/node_modules/@buddi/gateway/dist/web/tailscale.js +76 -16
  370. package/node_modules/@buddi/gateway/dist/web/tailscale.js.map +1 -1
  371. package/node_modules/@buddi/gateway/dist/web/widgets.d.ts +130 -0
  372. package/node_modules/@buddi/gateway/dist/web/widgets.d.ts.map +1 -0
  373. package/node_modules/@buddi/gateway/dist/web/widgets.js +473 -0
  374. package/node_modules/@buddi/gateway/dist/web/widgets.js.map +1 -0
  375. package/node_modules/@buddi/install/dist/.tsbuildinfo +1 -1
  376. package/node_modules/@buddi/runtime/dist/.tsbuildinfo +1 -1
  377. package/node_modules/@buddi/runtime/dist/anthropic.d.ts +9 -0
  378. package/node_modules/@buddi/runtime/dist/anthropic.d.ts.map +1 -1
  379. package/node_modules/@buddi/runtime/dist/anthropic.js +26 -9
  380. package/node_modules/@buddi/runtime/dist/anthropic.js.map +1 -1
  381. package/node_modules/@buddi/runtime/dist/codex-direct.d.ts +2 -1
  382. package/node_modules/@buddi/runtime/dist/codex-direct.d.ts.map +1 -1
  383. package/node_modules/@buddi/runtime/dist/codex-direct.js +13 -6
  384. package/node_modules/@buddi/runtime/dist/codex-direct.js.map +1 -1
  385. package/node_modules/@buddi/runtime/dist/index.d.ts +1 -0
  386. package/node_modules/@buddi/runtime/dist/index.d.ts.map +1 -1
  387. package/node_modules/@buddi/runtime/dist/index.js +1 -0
  388. package/node_modules/@buddi/runtime/dist/index.js.map +1 -1
  389. package/node_modules/@buddi/runtime/dist/loop.d.ts +2 -0
  390. package/node_modules/@buddi/runtime/dist/loop.d.ts.map +1 -1
  391. package/node_modules/@buddi/runtime/dist/loop.js +22 -0
  392. package/node_modules/@buddi/runtime/dist/loop.js.map +1 -1
  393. package/node_modules/@buddi/runtime/dist/openai.d.ts.map +1 -1
  394. package/node_modules/@buddi/runtime/dist/openai.js +19 -7
  395. package/node_modules/@buddi/runtime/dist/openai.js.map +1 -1
  396. package/node_modules/@buddi/runtime/dist/rate-limit.d.ts +91 -0
  397. package/node_modules/@buddi/runtime/dist/rate-limit.d.ts.map +1 -0
  398. package/node_modules/@buddi/runtime/dist/rate-limit.js +291 -0
  399. package/node_modules/@buddi/runtime/dist/rate-limit.js.map +1 -0
  400. package/node_modules/@buddi/runtime/dist/retry.d.ts +40 -0
  401. package/node_modules/@buddi/runtime/dist/retry.d.ts.map +1 -1
  402. package/node_modules/@buddi/runtime/dist/retry.js +42 -8
  403. package/node_modules/@buddi/runtime/dist/retry.js.map +1 -1
  404. package/node_modules/@buddi/tool-artifacts/dist/.tsbuildinfo +1 -1
  405. package/node_modules/@buddi/tool-browser/dist/.tsbuildinfo +1 -1
  406. package/node_modules/@buddi/tool-email/dist/.tsbuildinfo +1 -1
  407. package/node_modules/@buddi/tool-email/dist/folders.d.ts +14 -0
  408. package/node_modules/@buddi/tool-email/dist/folders.d.ts.map +1 -1
  409. package/node_modules/@buddi/tool-email/dist/folders.js +23 -0
  410. package/node_modules/@buddi/tool-email/dist/folders.js.map +1 -1
  411. package/node_modules/@buddi/tool-email/dist/imap/fake.d.ts +55 -0
  412. package/node_modules/@buddi/tool-email/dist/imap/fake.d.ts.map +1 -1
  413. package/node_modules/@buddi/tool-email/dist/imap/fake.js +163 -4
  414. package/node_modules/@buddi/tool-email/dist/imap/fake.js.map +1 -1
  415. package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.d.ts.map +1 -1
  416. package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.js +65 -0
  417. package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.js.map +1 -1
  418. package/node_modules/@buddi/tool-email/dist/index.d.ts.map +1 -1
  419. package/node_modules/@buddi/tool-email/dist/index.js +3 -0
  420. package/node_modules/@buddi/tool-email/dist/index.js.map +1 -1
  421. package/node_modules/@buddi/tool-email/dist/mail.d.ts +6 -0
  422. package/node_modules/@buddi/tool-email/dist/mail.d.ts.map +1 -1
  423. package/node_modules/@buddi/tool-email/dist/mail.js +3 -0
  424. package/node_modules/@buddi/tool-email/dist/mail.js.map +1 -1
  425. package/node_modules/@buddi/tool-email/dist/mailbox/actions.d.ts +90 -5
  426. package/node_modules/@buddi/tool-email/dist/mailbox/actions.d.ts.map +1 -1
  427. package/node_modules/@buddi/tool-email/dist/mailbox/actions.js +643 -200
  428. package/node_modules/@buddi/tool-email/dist/mailbox/actions.js.map +1 -1
  429. package/node_modules/@buddi/tool-email/dist/mailbox/select.d.ts.map +1 -1
  430. package/node_modules/@buddi/tool-email/dist/mailbox/select.js +9 -2
  431. package/node_modules/@buddi/tool-email/dist/mailbox/select.js.map +1 -1
  432. package/node_modules/@buddi/tool-email/dist/metrics.d.ts +3 -3
  433. package/node_modules/@buddi/tool-email/dist/metrics.js +4 -4
  434. package/node_modules/@buddi/tool-email/dist/pages/descriptors.d.ts.map +1 -1
  435. package/node_modules/@buddi/tool-email/dist/pages/descriptors.js +16 -2
  436. package/node_modules/@buddi/tool-email/dist/pages/descriptors.js.map +1 -1
  437. package/node_modules/@buddi/tool-email/dist/pages/queries.d.ts +7 -0
  438. package/node_modules/@buddi/tool-email/dist/pages/queries.d.ts.map +1 -1
  439. package/node_modules/@buddi/tool-email/dist/pages/queries.js +34 -4
  440. package/node_modules/@buddi/tool-email/dist/pages/queries.js.map +1 -1
  441. package/node_modules/@buddi/tool-email/dist/policies/auto.d.ts +9 -9
  442. package/node_modules/@buddi/tool-email/dist/policies/auto.d.ts.map +1 -1
  443. package/node_modules/@buddi/tool-email/dist/policies/auto.js +79 -24
  444. package/node_modules/@buddi/tool-email/dist/policies/auto.js.map +1 -1
  445. package/node_modules/@buddi/tool-email/dist/ports.d.ts +47 -0
  446. package/node_modules/@buddi/tool-email/dist/ports.d.ts.map +1 -1
  447. package/node_modules/@buddi/tool-email/dist/ports.js.map +1 -1
  448. package/node_modules/@buddi/tool-email/dist/sentinels/waiting-on-me.d.ts +2 -2
  449. package/node_modules/@buddi/tool-email/dist/sentinels/waiting-on-me.d.ts.map +1 -1
  450. package/node_modules/@buddi/tool-email/dist/sentinels/waiting-on-me.js +8 -3
  451. package/node_modules/@buddi/tool-email/dist/sentinels/waiting-on-me.js.map +1 -1
  452. package/node_modules/@buddi/tool-email/dist/sources/idle.d.ts +10 -2
  453. package/node_modules/@buddi/tool-email/dist/sources/idle.d.ts.map +1 -1
  454. package/node_modules/@buddi/tool-email/dist/sources/idle.js +70 -3
  455. package/node_modules/@buddi/tool-email/dist/sources/idle.js.map +1 -1
  456. package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.d.ts +69 -2
  457. package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.d.ts.map +1 -1
  458. package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.js +140 -11
  459. package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.js.map +1 -1
  460. package/node_modules/@buddi/tool-email/dist/sources/presence.d.ts +47 -0
  461. package/node_modules/@buddi/tool-email/dist/sources/presence.d.ts.map +1 -0
  462. package/node_modules/@buddi/tool-email/dist/sources/presence.js +128 -0
  463. package/node_modules/@buddi/tool-email/dist/sources/presence.js.map +1 -0
  464. package/node_modules/@buddi/tool-email/dist/threads.d.ts +2 -0
  465. package/node_modules/@buddi/tool-email/dist/threads.d.ts.map +1 -1
  466. package/node_modules/@buddi/tool-email/dist/threads.js +12 -3
  467. package/node_modules/@buddi/tool-email/dist/threads.js.map +1 -1
  468. package/node_modules/@buddi/tool-email/dist/tools/mailbox.d.ts.map +1 -1
  469. package/node_modules/@buddi/tool-email/dist/tools/mailbox.js +4 -4
  470. package/node_modules/@buddi/tool-email/dist/tools/mailbox.js.map +1 -1
  471. package/node_modules/@buddi/tool-email/dist/tools/read.d.ts.map +1 -1
  472. package/node_modules/@buddi/tool-email/dist/tools/read.js +29 -2
  473. package/node_modules/@buddi/tool-email/dist/tools/read.js.map +1 -1
  474. package/node_modules/@buddi/tool-email/dist/tools/threads.d.ts +2 -2
  475. package/node_modules/@buddi/tool-email/dist/widgets.d.ts +13 -0
  476. package/node_modules/@buddi/tool-email/dist/widgets.d.ts.map +1 -0
  477. package/node_modules/@buddi/tool-email/dist/widgets.js +51 -0
  478. package/node_modules/@buddi/tool-email/dist/widgets.js.map +1 -0
  479. package/node_modules/@buddi/tool-email/migrations/020_mailbox_presence.sql +44 -0
  480. package/node_modules/@buddi/tool-email/migrations/021_learned_line.sql +9 -0
  481. package/node_modules/@buddi/tool-email/migrations/022_bulk_checked.sql +13 -0
  482. package/node_modules/@buddi/tool-host/dist/.tsbuildinfo +1 -1
  483. package/node_modules/@buddi/tool-mcp/dist/.tsbuildinfo +1 -1
  484. package/node_modules/@buddi/tool-memory/dist/.tsbuildinfo +1 -1
  485. package/node_modules/@buddi/tool-memory/dist/admin.d.ts +9 -0
  486. package/node_modules/@buddi/tool-memory/dist/admin.d.ts.map +1 -1
  487. package/node_modules/@buddi/tool-memory/dist/admin.js +11 -0
  488. package/node_modules/@buddi/tool-memory/dist/admin.js.map +1 -1
  489. package/node_modules/@buddi/tool-web/dist/.tsbuildinfo +1 -1
  490. package/package.json +2 -2
  491. package/packages/cli/dist/.tsbuildinfo +1 -1
  492. package/packages/cli/dist/args.d.ts +13 -2
  493. package/packages/cli/dist/args.d.ts.map +1 -1
  494. package/packages/cli/dist/args.js +12 -3
  495. package/packages/cli/dist/args.js.map +1 -1
  496. package/packages/cli/dist/commands.d.ts.map +1 -1
  497. package/packages/cli/dist/commands.js +67 -5
  498. package/packages/cli/dist/commands.js.map +1 -1
  499. package/packages/cli/dist/dashboard-cmd.d.ts +3 -0
  500. package/packages/cli/dist/dashboard-cmd.d.ts.map +1 -1
  501. package/packages/cli/dist/dashboard-cmd.js +63 -0
  502. package/packages/cli/dist/dashboard-cmd.js.map +1 -1
  503. package/packages/cli/dist/doctor-probes.d.ts.map +1 -1
  504. package/packages/cli/dist/doctor-probes.js +9 -3
  505. package/packages/cli/dist/doctor-probes.js.map +1 -1
  506. package/packages/cli/dist/doctor.d.ts +1 -1
  507. package/packages/cli/dist/doctor.d.ts.map +1 -1
  508. package/packages/cli/dist/main.d.ts.map +1 -1
  509. package/packages/cli/dist/main.js +22 -1
  510. package/packages/cli/dist/main.js.map +1 -1
  511. package/packages/cli/dist/mcp/gateway-client.d.ts +19 -17
  512. package/packages/cli/dist/mcp/gateway-client.d.ts.map +1 -1
  513. package/packages/cli/dist/mcp/gateway-client.js +128 -29
  514. package/packages/cli/dist/mcp/gateway-client.js.map +1 -1
  515. package/packages/cli/dist/mcp/tools.d.ts +6 -0
  516. package/packages/cli/dist/mcp/tools.d.ts.map +1 -1
  517. package/packages/cli/dist/mcp/tools.js +20 -1
  518. package/packages/cli/dist/mcp/tools.js.map +1 -1
  519. package/packages/cli/dist/telegram-cmd.d.ts.map +1 -1
  520. package/packages/cli/dist/telegram-cmd.js +5 -4
  521. package/packages/cli/dist/telegram-cmd.js.map +1 -1
  522. package/packages/core/dist/.tsbuildinfo +1 -1
  523. package/packages/core/dist/agents/catalog.d.ts.map +1 -1
  524. package/packages/core/dist/agents/catalog.js +7 -6
  525. package/packages/core/dist/agents/catalog.js.map +1 -1
  526. package/packages/core/dist/agents/frontmatter.d.ts +12 -12
  527. package/packages/core/dist/agents/skills.d.ts +2 -2
  528. package/packages/core/dist/clock-widget.d.ts +38 -0
  529. package/packages/core/dist/clock-widget.d.ts.map +1 -0
  530. package/packages/core/dist/clock-widget.js +114 -0
  531. package/packages/core/dist/clock-widget.js.map +1 -0
  532. package/packages/core/dist/failures/owner-message.d.ts +25 -0
  533. package/packages/core/dist/failures/owner-message.d.ts.map +1 -1
  534. package/packages/core/dist/failures/owner-message.js +90 -0
  535. package/packages/core/dist/failures/owner-message.js.map +1 -1
  536. package/packages/core/dist/feedback/index.d.ts +23 -2
  537. package/packages/core/dist/feedback/index.d.ts.map +1 -1
  538. package/packages/core/dist/feedback/index.js +23 -3
  539. package/packages/core/dist/feedback/index.js.map +1 -1
  540. package/packages/core/dist/groups.d.ts +33 -0
  541. package/packages/core/dist/groups.d.ts.map +1 -1
  542. package/packages/core/dist/groups.js +76 -4
  543. package/packages/core/dist/groups.js.map +1 -1
  544. package/packages/core/dist/home.d.ts +5 -5
  545. package/packages/core/dist/host/build.d.ts +19 -1
  546. package/packages/core/dist/host/build.d.ts.map +1 -1
  547. package/packages/core/dist/host/build.js +122 -2
  548. package/packages/core/dist/host/build.js.map +1 -1
  549. package/packages/core/dist/host/types.d.ts +33 -0
  550. package/packages/core/dist/host/types.d.ts.map +1 -1
  551. package/packages/core/dist/index.d.ts +8 -0
  552. package/packages/core/dist/index.d.ts.map +1 -1
  553. package/packages/core/dist/index.js +8 -0
  554. package/packages/core/dist/index.js.map +1 -1
  555. package/packages/core/dist/lock.d.ts +76 -0
  556. package/packages/core/dist/lock.d.ts.map +1 -0
  557. package/packages/core/dist/lock.js +167 -0
  558. package/packages/core/dist/lock.js.map +1 -0
  559. package/packages/core/dist/metrics.d.ts.map +1 -1
  560. package/packages/core/dist/metrics.js +4 -2
  561. package/packages/core/dist/metrics.js.map +1 -1
  562. package/packages/core/dist/onboarding/store.d.ts +5 -0
  563. package/packages/core/dist/onboarding/store.d.ts.map +1 -1
  564. package/packages/core/dist/onboarding/store.js +35 -5
  565. package/packages/core/dist/onboarding/store.js.map +1 -1
  566. package/packages/core/dist/onboarding/types.d.ts +10 -0
  567. package/packages/core/dist/onboarding/types.d.ts.map +1 -1
  568. package/packages/core/dist/onboarding/types.js +2 -0
  569. package/packages/core/dist/onboarding/types.js.map +1 -1
  570. package/packages/core/dist/owner-format.d.ts +14 -0
  571. package/packages/core/dist/owner-format.d.ts.map +1 -0
  572. package/packages/core/dist/owner-format.js +47 -0
  573. package/packages/core/dist/owner-format.js.map +1 -0
  574. package/packages/core/dist/owner-timezone.d.ts +46 -0
  575. package/packages/core/dist/owner-timezone.d.ts.map +1 -0
  576. package/packages/core/dist/owner-timezone.js +43 -0
  577. package/packages/core/dist/owner-timezone.js.map +1 -0
  578. package/packages/core/dist/pages.d.ts +10 -38
  579. package/packages/core/dist/pages.d.ts.map +1 -1
  580. package/packages/core/dist/pages.js +6 -0
  581. package/packages/core/dist/pages.js.map +1 -1
  582. package/packages/core/dist/places.d.ts +110 -0
  583. package/packages/core/dist/places.d.ts.map +1 -0
  584. package/packages/core/dist/places.js +239 -0
  585. package/packages/core/dist/places.js.map +1 -0
  586. package/packages/core/dist/plugin/index.d.ts +8 -1
  587. package/packages/core/dist/plugin/index.d.ts.map +1 -1
  588. package/packages/core/dist/plugin/index.js +3 -0
  589. package/packages/core/dist/plugin/index.js.map +1 -1
  590. package/packages/core/dist/plugin/requires.d.ts +75 -0
  591. package/packages/core/dist/plugin/requires.d.ts.map +1 -0
  592. package/packages/core/dist/plugin/requires.js +77 -0
  593. package/packages/core/dist/plugin/requires.js.map +1 -0
  594. package/packages/core/dist/plugin/uses.d.ts +1 -1
  595. package/packages/core/dist/plugin/uses.d.ts.map +1 -1
  596. package/packages/core/dist/plugin/uses.js +2 -0
  597. package/packages/core/dist/plugin/uses.js.map +1 -1
  598. package/packages/core/dist/plugin/version.d.ts +1 -1
  599. package/packages/core/dist/plugin/version.js +1 -1
  600. package/packages/core/dist/queue/retry-policy.d.ts +5 -0
  601. package/packages/core/dist/queue/retry-policy.d.ts.map +1 -1
  602. package/packages/core/dist/queue/retry-policy.js +19 -2
  603. package/packages/core/dist/queue/retry-policy.js.map +1 -1
  604. package/packages/core/dist/registry.d.ts +37 -2
  605. package/packages/core/dist/registry.d.ts.map +1 -1
  606. package/packages/core/dist/registry.js +137 -3
  607. package/packages/core/dist/registry.js.map +1 -1
  608. package/packages/core/dist/scheduler/enqueue.d.ts +71 -0
  609. package/packages/core/dist/scheduler/enqueue.d.ts.map +1 -0
  610. package/packages/core/dist/scheduler/enqueue.js +116 -0
  611. package/packages/core/dist/scheduler/enqueue.js.map +1 -0
  612. package/packages/core/dist/scheduler/index.d.ts +1 -0
  613. package/packages/core/dist/scheduler/index.d.ts.map +1 -1
  614. package/packages/core/dist/scheduler/index.js +1 -0
  615. package/packages/core/dist/scheduler/index.js.map +1 -1
  616. package/packages/core/dist/scheduler/missions.d.ts +15 -0
  617. package/packages/core/dist/scheduler/missions.d.ts.map +1 -1
  618. package/packages/core/dist/scheduler/missions.js +43 -4
  619. package/packages/core/dist/scheduler/missions.js.map +1 -1
  620. package/packages/core/dist/scheduler/types.d.ts +10 -0
  621. package/packages/core/dist/scheduler/types.d.ts.map +1 -1
  622. package/packages/core/dist/scheduler/types.js +3 -0
  623. package/packages/core/dist/scheduler/types.js.map +1 -1
  624. package/packages/core/dist/secrets/settings.d.ts +6 -6
  625. package/packages/core/dist/semver.d.ts +17 -0
  626. package/packages/core/dist/semver.d.ts.map +1 -1
  627. package/packages/core/dist/semver.js +130 -0
  628. package/packages/core/dist/semver.js.map +1 -1
  629. package/packages/core/dist/sentinels/run.d.ts +6 -1
  630. package/packages/core/dist/sentinels/run.d.ts.map +1 -1
  631. package/packages/core/dist/sentinels/run.js +43 -24
  632. package/packages/core/dist/sentinels/run.js.map +1 -1
  633. package/packages/core/dist/sentinels/types.d.ts +13 -0
  634. package/packages/core/dist/sentinels/types.d.ts.map +1 -1
  635. package/packages/core/dist/sentinels/types.js.map +1 -1
  636. package/packages/core/dist/sources/run.d.ts +8 -0
  637. package/packages/core/dist/sources/run.d.ts.map +1 -1
  638. package/packages/core/dist/sources/run.js +1 -1
  639. package/packages/core/dist/sources/run.js.map +1 -1
  640. package/packages/core/dist/sources/watch.d.ts +3 -0
  641. package/packages/core/dist/sources/watch.d.ts.map +1 -1
  642. package/packages/core/dist/sources/watch.js +1 -1
  643. package/packages/core/dist/sources/watch.js.map +1 -1
  644. package/packages/core/dist/time.d.ts +17 -3
  645. package/packages/core/dist/time.d.ts.map +1 -1
  646. package/packages/core/dist/time.js +27 -3
  647. package/packages/core/dist/time.js.map +1 -1
  648. package/packages/core/dist/tools.d.ts +30 -1
  649. package/packages/core/dist/tools.d.ts.map +1 -1
  650. package/packages/core/dist/tools.js.map +1 -1
  651. package/packages/core/dist/views.d.ts +68 -68
  652. package/packages/core/dist/views.d.ts.map +1 -1
  653. package/packages/core/dist/views.js +3 -0
  654. package/packages/core/dist/views.js.map +1 -1
  655. package/packages/core/dist/widget-settings.d.ts +161 -0
  656. package/packages/core/dist/widget-settings.d.ts.map +1 -0
  657. package/packages/core/dist/widget-settings.js +314 -0
  658. package/packages/core/dist/widget-settings.js.map +1 -0
  659. package/packages/core/dist/widgets.d.ts +206 -0
  660. package/packages/core/dist/widgets.d.ts.map +1 -0
  661. package/packages/core/dist/widgets.js +247 -0
  662. package/packages/core/dist/widgets.js.map +1 -0
  663. package/packages/core/migrations/059_dashboard_lock.sql +33 -0
  664. package/packages/core/migrations/060_owner_places.sql +30 -0
  665. package/packages/core/migrations/061_owner_formats.sql +10 -0
  666. package/packages/core/migrations/062_group_deleted.sql +7 -0
  667. package/packages/core/migrations/063_provider_account_limits.sql +20 -0
  668. package/packages/core/migrations/064_mission_coalesce.sql +12 -0
  669. package/packages/core/migrations/065_api_tokens.sql +28 -0
  670. package/packages/gateway/dist/.tsbuildinfo +1 -1
  671. package/packages/gateway/dist/account-limits.d.ts +45 -0
  672. package/packages/gateway/dist/account-limits.d.ts.map +1 -0
  673. package/packages/gateway/dist/account-limits.js +87 -0
  674. package/packages/gateway/dist/account-limits.js.map +1 -0
  675. package/packages/gateway/dist/accounts-cli.d.ts +88 -0
  676. package/packages/gateway/dist/accounts-cli.d.ts.map +1 -0
  677. package/packages/gateway/dist/accounts-cli.js +216 -0
  678. package/packages/gateway/dist/accounts-cli.js.map +1 -0
  679. package/packages/gateway/dist/agents/canvas.d.ts +20 -20
  680. package/packages/gateway/dist/agents/learning-digest.d.ts +4 -0
  681. package/packages/gateway/dist/agents/learning-digest.d.ts.map +1 -1
  682. package/packages/gateway/dist/agents/learning-digest.js +18 -5
  683. package/packages/gateway/dist/agents/learning-digest.js.map +1 -1
  684. package/packages/gateway/dist/agents/owner-tools.d.ts.map +1 -1
  685. package/packages/gateway/dist/agents/owner-tools.js +3 -2
  686. package/packages/gateway/dist/agents/owner-tools.js.map +1 -1
  687. package/packages/gateway/dist/agents/platform.d.ts +24 -24
  688. package/packages/gateway/dist/api-token-cli.d.ts +17 -0
  689. package/packages/gateway/dist/api-token-cli.d.ts.map +1 -0
  690. package/packages/gateway/dist/api-token-cli.js +108 -0
  691. package/packages/gateway/dist/api-token-cli.js.map +1 -0
  692. package/packages/gateway/dist/bootstrap.d.ts +6 -2
  693. package/packages/gateway/dist/bootstrap.d.ts.map +1 -1
  694. package/packages/gateway/dist/bootstrap.js +25 -7
  695. package/packages/gateway/dist/bootstrap.js.map +1 -1
  696. package/packages/gateway/dist/chat/session.d.ts +5 -0
  697. package/packages/gateway/dist/chat/session.d.ts.map +1 -1
  698. package/packages/gateway/dist/chat/session.js +11 -1
  699. package/packages/gateway/dist/chat/session.js.map +1 -1
  700. package/packages/gateway/dist/cli.d.ts.map +1 -1
  701. package/packages/gateway/dist/cli.js +14 -3
  702. package/packages/gateway/dist/cli.js.map +1 -1
  703. package/packages/gateway/dist/index.d.ts +3 -0
  704. package/packages/gateway/dist/index.d.ts.map +1 -1
  705. package/packages/gateway/dist/index.js +3 -0
  706. package/packages/gateway/dist/index.js.map +1 -1
  707. package/packages/gateway/dist/missions/dead-letter.d.ts +2 -1
  708. package/packages/gateway/dist/missions/dead-letter.d.ts.map +1 -1
  709. package/packages/gateway/dist/missions/dead-letter.js +19 -5
  710. package/packages/gateway/dist/missions/dead-letter.js.map +1 -1
  711. package/packages/gateway/dist/missions/defaults.d.ts +6 -0
  712. package/packages/gateway/dist/missions/defaults.d.ts.map +1 -1
  713. package/packages/gateway/dist/missions/defaults.js +10 -2
  714. package/packages/gateway/dist/missions/defaults.js.map +1 -1
  715. package/packages/gateway/dist/missions/execute.d.ts.map +1 -1
  716. package/packages/gateway/dist/missions/execute.js +14 -8
  717. package/packages/gateway/dist/missions/execute.js.map +1 -1
  718. package/packages/gateway/dist/missions/inline.js +1 -1
  719. package/packages/gateway/dist/missions/inline.js.map +1 -1
  720. package/packages/gateway/dist/missions/sentinel-wake.d.ts +11 -0
  721. package/packages/gateway/dist/missions/sentinel-wake.d.ts.map +1 -1
  722. package/packages/gateway/dist/missions/sentinel-wake.js +37 -1
  723. package/packages/gateway/dist/missions/sentinel-wake.js.map +1 -1
  724. package/packages/gateway/dist/missions-cli.d.ts.map +1 -1
  725. package/packages/gateway/dist/missions-cli.js +5 -5
  726. package/packages/gateway/dist/missions-cli.js.map +1 -1
  727. package/packages/gateway/dist/nudges-cli.js +2 -2
  728. package/packages/gateway/dist/nudges-cli.js.map +1 -1
  729. package/packages/gateway/dist/owner-seed.js +2 -2
  730. package/packages/gateway/dist/owner-seed.js.map +1 -1
  731. package/packages/gateway/dist/plugins/live.d.ts +8 -1
  732. package/packages/gateway/dist/plugins/live.d.ts.map +1 -1
  733. package/packages/gateway/dist/plugins/live.js +25 -7
  734. package/packages/gateway/dist/plugins/live.js.map +1 -1
  735. package/packages/gateway/dist/plugins/load.d.ts +55 -0
  736. package/packages/gateway/dist/plugins/load.d.ts.map +1 -1
  737. package/packages/gateway/dist/plugins/load.js +100 -4
  738. package/packages/gateway/dist/plugins/load.js.map +1 -1
  739. package/packages/gateway/dist/plugins/requires.d.ts +79 -0
  740. package/packages/gateway/dist/plugins/requires.d.ts.map +1 -0
  741. package/packages/gateway/dist/plugins/requires.js +178 -0
  742. package/packages/gateway/dist/plugins/requires.js.map +1 -0
  743. package/packages/gateway/dist/plugins/stage.d.ts +6 -0
  744. package/packages/gateway/dist/plugins/stage.d.ts.map +1 -1
  745. package/packages/gateway/dist/plugins/stage.js +6 -1
  746. package/packages/gateway/dist/plugins/stage.js.map +1 -1
  747. package/packages/gateway/dist/plugins/update.d.ts +21 -0
  748. package/packages/gateway/dist/plugins/update.d.ts.map +1 -1
  749. package/packages/gateway/dist/plugins/update.js +16 -0
  750. package/packages/gateway/dist/plugins/update.js.map +1 -1
  751. package/packages/gateway/dist/plugins-cli.d.ts +1 -1
  752. package/packages/gateway/dist/plugins-cli.d.ts.map +1 -1
  753. package/packages/gateway/dist/plugins-cli.js +6 -2
  754. package/packages/gateway/dist/plugins-cli.js.map +1 -1
  755. package/packages/gateway/dist/provider-accounts.d.ts +4 -0
  756. package/packages/gateway/dist/provider-accounts.d.ts.map +1 -1
  757. package/packages/gateway/dist/provider-accounts.js +68 -10
  758. package/packages/gateway/dist/provider-accounts.js.map +1 -1
  759. package/packages/gateway/dist/provider-diagnostics.d.ts.map +1 -1
  760. package/packages/gateway/dist/provider-diagnostics.js +9 -0
  761. package/packages/gateway/dist/provider-diagnostics.js.map +1 -1
  762. package/packages/gateway/dist/reminders-cli.js +2 -2
  763. package/packages/gateway/dist/reminders-cli.js.map +1 -1
  764. package/packages/gateway/dist/serve.d.ts +2 -0
  765. package/packages/gateway/dist/serve.d.ts.map +1 -1
  766. package/packages/gateway/dist/serve.js +66 -8
  767. package/packages/gateway/dist/serve.js.map +1 -1
  768. package/packages/gateway/dist/surfaces/failure.d.ts.map +1 -1
  769. package/packages/gateway/dist/surfaces/failure.js +9 -1
  770. package/packages/gateway/dist/surfaces/failure.js.map +1 -1
  771. package/packages/gateway/dist/system-context.d.ts +18 -0
  772. package/packages/gateway/dist/system-context.d.ts.map +1 -1
  773. package/packages/gateway/dist/system-context.js +46 -4
  774. package/packages/gateway/dist/system-context.js.map +1 -1
  775. package/packages/gateway/dist/telegram/main.js +3 -3
  776. package/packages/gateway/dist/telegram/main.js.map +1 -1
  777. package/packages/gateway/dist/telegram/outbound.d.ts +1 -1
  778. package/packages/gateway/dist/telegram/outbound.d.ts.map +1 -1
  779. package/packages/gateway/dist/telegram/outbound.js +7 -2
  780. package/packages/gateway/dist/telegram/outbound.js.map +1 -1
  781. package/packages/gateway/dist/telegram/reactions.d.ts.map +1 -1
  782. package/packages/gateway/dist/telegram/reactions.js +12 -2
  783. package/packages/gateway/dist/telegram/reactions.js.map +1 -1
  784. package/packages/gateway/dist/telegram/surface.d.ts +4 -1
  785. package/packages/gateway/dist/telegram/surface.d.ts.map +1 -1
  786. package/packages/gateway/dist/telegram/surface.js +13 -3
  787. package/packages/gateway/dist/telegram/surface.js.map +1 -1
  788. package/packages/gateway/dist/tips/engine.d.ts +2 -0
  789. package/packages/gateway/dist/tips/engine.d.ts.map +1 -1
  790. package/packages/gateway/dist/tips/engine.js +8 -5
  791. package/packages/gateway/dist/tips/engine.js.map +1 -1
  792. package/packages/gateway/dist/tips/facts.d.ts +23 -0
  793. package/packages/gateway/dist/tips/facts.d.ts.map +1 -1
  794. package/packages/gateway/dist/tips/facts.js +19 -0
  795. package/packages/gateway/dist/tips/facts.js.map +1 -1
  796. package/packages/gateway/dist/tips/route.js +2 -2
  797. package/packages/gateway/dist/tips/route.js.map +1 -1
  798. package/packages/gateway/dist/tips/rules.d.ts +3 -2
  799. package/packages/gateway/dist/tips/rules.d.ts.map +1 -1
  800. package/packages/gateway/dist/tips/rules.js +26 -0
  801. package/packages/gateway/dist/tips/rules.js.map +1 -1
  802. package/packages/gateway/dist/web/api-routes.d.ts +103 -0
  803. package/packages/gateway/dist/web/api-routes.d.ts.map +1 -0
  804. package/packages/gateway/dist/web/api-routes.js +1200 -0
  805. package/packages/gateway/dist/web/api-routes.js.map +1 -0
  806. package/packages/gateway/dist/web/api-scan.d.ts +17 -0
  807. package/packages/gateway/dist/web/api-scan.d.ts.map +1 -0
  808. package/packages/gateway/dist/web/api-scan.js +206 -0
  809. package/packages/gateway/dist/web/api-scan.js.map +1 -0
  810. package/packages/gateway/dist/web/api-tokens.d.ts +58 -0
  811. package/packages/gateway/dist/web/api-tokens.d.ts.map +1 -0
  812. package/packages/gateway/dist/web/api-tokens.js +136 -0
  813. package/packages/gateway/dist/web/api-tokens.js.map +1 -0
  814. package/packages/gateway/dist/web/backups.js +2 -2
  815. package/packages/gateway/dist/web/backups.js.map +1 -1
  816. package/packages/gateway/dist/web/group-lifecycle.d.ts +18 -0
  817. package/packages/gateway/dist/web/group-lifecycle.d.ts.map +1 -0
  818. package/packages/gateway/dist/web/group-lifecycle.js +46 -0
  819. package/packages/gateway/dist/web/group-lifecycle.js.map +1 -0
  820. package/packages/gateway/dist/web/lock-image.d.ts +37 -0
  821. package/packages/gateway/dist/web/lock-image.d.ts.map +1 -0
  822. package/packages/gateway/dist/web/lock-image.js +253 -0
  823. package/packages/gateway/dist/web/lock-image.js.map +1 -0
  824. package/packages/gateway/dist/web/lock.d.ts +162 -0
  825. package/packages/gateway/dist/web/lock.d.ts.map +1 -0
  826. package/packages/gateway/dist/web/lock.js +472 -0
  827. package/packages/gateway/dist/web/lock.js.map +1 -0
  828. package/packages/gateway/dist/web/pages.d.ts +1 -0
  829. package/packages/gateway/dist/web/pages.d.ts.map +1 -1
  830. package/packages/gateway/dist/web/pages.js +12 -1
  831. package/packages/gateway/dist/web/pages.js.map +1 -1
  832. package/packages/gateway/dist/web/places.d.ts +27 -0
  833. package/packages/gateway/dist/web/places.d.ts.map +1 -0
  834. package/packages/gateway/dist/web/places.js +90 -0
  835. package/packages/gateway/dist/web/places.js.map +1 -0
  836. package/packages/gateway/dist/web/plugins.d.ts +28 -0
  837. package/packages/gateway/dist/web/plugins.d.ts.map +1 -1
  838. package/packages/gateway/dist/web/plugins.js +69 -9
  839. package/packages/gateway/dist/web/plugins.js.map +1 -1
  840. package/packages/gateway/dist/web/server.d.ts +9 -0
  841. package/packages/gateway/dist/web/server.d.ts.map +1 -1
  842. package/packages/gateway/dist/web/server.js +406 -37
  843. package/packages/gateway/dist/web/server.js.map +1 -1
  844. package/packages/gateway/dist/web/sessions.d.ts +43 -2
  845. package/packages/gateway/dist/web/sessions.d.ts.map +1 -1
  846. package/packages/gateway/dist/web/sessions.js +67 -3
  847. package/packages/gateway/dist/web/sessions.js.map +1 -1
  848. package/packages/gateway/dist/web/signed-out.d.ts +17 -18
  849. package/packages/gateway/dist/web/signed-out.d.ts.map +1 -1
  850. package/packages/gateway/dist/web/signed-out.js +135 -33
  851. package/packages/gateway/dist/web/signed-out.js.map +1 -1
  852. package/packages/gateway/dist/web/stream.d.ts.map +1 -1
  853. package/packages/gateway/dist/web/stream.js +14 -0
  854. package/packages/gateway/dist/web/stream.js.map +1 -1
  855. package/packages/gateway/dist/web/tailscale.d.ts +33 -4
  856. package/packages/gateway/dist/web/tailscale.d.ts.map +1 -1
  857. package/packages/gateway/dist/web/tailscale.js +76 -16
  858. package/packages/gateway/dist/web/tailscale.js.map +1 -1
  859. package/packages/gateway/dist/web/widgets.d.ts +130 -0
  860. package/packages/gateway/dist/web/widgets.d.ts.map +1 -0
  861. package/packages/gateway/dist/web/widgets.js +473 -0
  862. package/packages/gateway/dist/web/widgets.js.map +1 -0
  863. package/packages/install/dist/.tsbuildinfo +1 -1
  864. package/packages/runtime/dist/.tsbuildinfo +1 -1
  865. package/packages/runtime/dist/anthropic.d.ts +9 -0
  866. package/packages/runtime/dist/anthropic.d.ts.map +1 -1
  867. package/packages/runtime/dist/anthropic.js +26 -9
  868. package/packages/runtime/dist/anthropic.js.map +1 -1
  869. package/packages/runtime/dist/codex-direct.d.ts +2 -1
  870. package/packages/runtime/dist/codex-direct.d.ts.map +1 -1
  871. package/packages/runtime/dist/codex-direct.js +13 -6
  872. package/packages/runtime/dist/codex-direct.js.map +1 -1
  873. package/packages/runtime/dist/index.d.ts +1 -0
  874. package/packages/runtime/dist/index.d.ts.map +1 -1
  875. package/packages/runtime/dist/index.js +1 -0
  876. package/packages/runtime/dist/index.js.map +1 -1
  877. package/packages/runtime/dist/loop.d.ts +2 -0
  878. package/packages/runtime/dist/loop.d.ts.map +1 -1
  879. package/packages/runtime/dist/loop.js +22 -0
  880. package/packages/runtime/dist/loop.js.map +1 -1
  881. package/packages/runtime/dist/openai.d.ts.map +1 -1
  882. package/packages/runtime/dist/openai.js +19 -7
  883. package/packages/runtime/dist/openai.js.map +1 -1
  884. package/packages/runtime/dist/rate-limit.d.ts +91 -0
  885. package/packages/runtime/dist/rate-limit.d.ts.map +1 -0
  886. package/packages/runtime/dist/rate-limit.js +291 -0
  887. package/packages/runtime/dist/rate-limit.js.map +1 -0
  888. package/packages/runtime/dist/retry.d.ts +40 -0
  889. package/packages/runtime/dist/retry.d.ts.map +1 -1
  890. package/packages/runtime/dist/retry.js +42 -8
  891. package/packages/runtime/dist/retry.js.map +1 -1
  892. package/packages/tools/artifacts/dist/.tsbuildinfo +1 -1
  893. package/packages/tools/browser/dist/.tsbuildinfo +1 -1
  894. package/packages/tools/email/dist/.tsbuildinfo +1 -1
  895. package/packages/tools/email/dist/folders.d.ts +14 -0
  896. package/packages/tools/email/dist/folders.d.ts.map +1 -1
  897. package/packages/tools/email/dist/folders.js +23 -0
  898. package/packages/tools/email/dist/folders.js.map +1 -1
  899. package/packages/tools/email/dist/imap/fake.d.ts +55 -0
  900. package/packages/tools/email/dist/imap/fake.d.ts.map +1 -1
  901. package/packages/tools/email/dist/imap/fake.js +163 -4
  902. package/packages/tools/email/dist/imap/fake.js.map +1 -1
  903. package/packages/tools/email/dist/imap/imapflow-client.d.ts.map +1 -1
  904. package/packages/tools/email/dist/imap/imapflow-client.js +65 -0
  905. package/packages/tools/email/dist/imap/imapflow-client.js.map +1 -1
  906. package/packages/tools/email/dist/index.d.ts.map +1 -1
  907. package/packages/tools/email/dist/index.js +3 -0
  908. package/packages/tools/email/dist/index.js.map +1 -1
  909. package/packages/tools/email/dist/mail.d.ts +6 -0
  910. package/packages/tools/email/dist/mail.d.ts.map +1 -1
  911. package/packages/tools/email/dist/mail.js +3 -0
  912. package/packages/tools/email/dist/mail.js.map +1 -1
  913. package/packages/tools/email/dist/mailbox/actions.d.ts +90 -5
  914. package/packages/tools/email/dist/mailbox/actions.d.ts.map +1 -1
  915. package/packages/tools/email/dist/mailbox/actions.js +643 -200
  916. package/packages/tools/email/dist/mailbox/actions.js.map +1 -1
  917. package/packages/tools/email/dist/mailbox/select.d.ts.map +1 -1
  918. package/packages/tools/email/dist/mailbox/select.js +9 -2
  919. package/packages/tools/email/dist/mailbox/select.js.map +1 -1
  920. package/packages/tools/email/dist/metrics.d.ts +3 -3
  921. package/packages/tools/email/dist/metrics.js +4 -4
  922. package/packages/tools/email/dist/pages/descriptors.d.ts.map +1 -1
  923. package/packages/tools/email/dist/pages/descriptors.js +16 -2
  924. package/packages/tools/email/dist/pages/descriptors.js.map +1 -1
  925. package/packages/tools/email/dist/pages/queries.d.ts +7 -0
  926. package/packages/tools/email/dist/pages/queries.d.ts.map +1 -1
  927. package/packages/tools/email/dist/pages/queries.js +34 -4
  928. package/packages/tools/email/dist/pages/queries.js.map +1 -1
  929. package/packages/tools/email/dist/policies/auto.d.ts +9 -9
  930. package/packages/tools/email/dist/policies/auto.d.ts.map +1 -1
  931. package/packages/tools/email/dist/policies/auto.js +79 -24
  932. package/packages/tools/email/dist/policies/auto.js.map +1 -1
  933. package/packages/tools/email/dist/ports.d.ts +47 -0
  934. package/packages/tools/email/dist/ports.d.ts.map +1 -1
  935. package/packages/tools/email/dist/ports.js.map +1 -1
  936. package/packages/tools/email/dist/sentinels/waiting-on-me.d.ts +2 -2
  937. package/packages/tools/email/dist/sentinels/waiting-on-me.d.ts.map +1 -1
  938. package/packages/tools/email/dist/sentinels/waiting-on-me.js +8 -3
  939. package/packages/tools/email/dist/sentinels/waiting-on-me.js.map +1 -1
  940. package/packages/tools/email/dist/sources/idle.d.ts +10 -2
  941. package/packages/tools/email/dist/sources/idle.d.ts.map +1 -1
  942. package/packages/tools/email/dist/sources/idle.js +70 -3
  943. package/packages/tools/email/dist/sources/idle.js.map +1 -1
  944. package/packages/tools/email/dist/sources/inbox-poll.d.ts +69 -2
  945. package/packages/tools/email/dist/sources/inbox-poll.d.ts.map +1 -1
  946. package/packages/tools/email/dist/sources/inbox-poll.js +140 -11
  947. package/packages/tools/email/dist/sources/inbox-poll.js.map +1 -1
  948. package/packages/tools/email/dist/sources/presence.d.ts +47 -0
  949. package/packages/tools/email/dist/sources/presence.d.ts.map +1 -0
  950. package/packages/tools/email/dist/sources/presence.js +128 -0
  951. package/packages/tools/email/dist/sources/presence.js.map +1 -0
  952. package/packages/tools/email/dist/threads.d.ts +2 -0
  953. package/packages/tools/email/dist/threads.d.ts.map +1 -1
  954. package/packages/tools/email/dist/threads.js +12 -3
  955. package/packages/tools/email/dist/threads.js.map +1 -1
  956. package/packages/tools/email/dist/tools/mailbox.d.ts.map +1 -1
  957. package/packages/tools/email/dist/tools/mailbox.js +4 -4
  958. package/packages/tools/email/dist/tools/mailbox.js.map +1 -1
  959. package/packages/tools/email/dist/tools/read.d.ts.map +1 -1
  960. package/packages/tools/email/dist/tools/read.js +29 -2
  961. package/packages/tools/email/dist/tools/read.js.map +1 -1
  962. package/packages/tools/email/dist/tools/threads.d.ts +2 -2
  963. package/packages/tools/email/dist/widgets.d.ts +13 -0
  964. package/packages/tools/email/dist/widgets.d.ts.map +1 -0
  965. package/packages/tools/email/dist/widgets.js +51 -0
  966. package/packages/tools/email/dist/widgets.js.map +1 -0
  967. package/packages/tools/email/migrations/020_mailbox_presence.sql +44 -0
  968. package/packages/tools/email/migrations/021_learned_line.sql +9 -0
  969. package/packages/tools/email/migrations/022_bulk_checked.sql +13 -0
  970. package/packages/tools/host/dist/.tsbuildinfo +1 -1
  971. package/packages/tools/mcp/dist/.tsbuildinfo +1 -1
  972. package/packages/tools/memory/dist/.tsbuildinfo +1 -1
  973. package/packages/tools/memory/dist/admin.d.ts +9 -0
  974. package/packages/tools/memory/dist/admin.d.ts.map +1 -1
  975. package/packages/tools/memory/dist/admin.js +11 -0
  976. package/packages/tools/memory/dist/admin.js.map +1 -1
  977. package/packages/tools/web/dist/.tsbuildinfo +1 -1
  978. package/packages/web/dist/assets/index-D8_tmf2k.js +131 -0
  979. package/packages/web/dist/assets/index-DYQyioa6.css +1 -0
  980. package/packages/web/dist/assets/{lottie_light-CSeMXM8D.js → lottie_light-Cdn77Osu.js} +1 -1
  981. package/packages/web/dist/build.json +1 -1
  982. package/packages/web/dist/index.html +2 -2
  983. package/packages/web/dist/precache.json +4 -4
  984. package/packages/web/dist/assets/index-CKuhKCWw.js +0 -131
  985. package/packages/web/dist/assets/index-DsK8UWCJ.css +0 -1
@@ -41,6 +41,7 @@
41
41
  * No `Access-Control-*` header is ever emitted, and `OPTIONS` is refused: a
42
42
  * page on another origin gets no preflight and no permission.
43
43
  */
44
+ import { runningAgentRuns } from '@buddi/runtime';
44
45
  import { agentMuteRoute, focusRoute, listNotificationsRoute, markSeenRoute, notificationSettingsRoute, presenceRoute, testChannelRoute } from './notifications.js';
45
46
  import { catalogSkillLookup, discardProposalFromWeb, keepAllProposalsFromWeb, keepProposalFromWeb, readProposals, registryChangeLookup } from './proposals.js';
46
47
  import { latestDigest, readDigestSchedule, setDigestSchedule } from '../agents/learning-digest.js';
@@ -69,9 +70,10 @@ import { connectionsOf } from '@buddi/tool-mcp';
69
70
  import { CONNECTIONS_CALLBACK_PATH, connectionsRoute } from './connections.js';
70
71
  import { browserHost } from '../browser-host.js';
71
72
  import { hostService } from '@buddi/tool-host';
72
- import { listToolPermissions, revokeToolPermission, getArtifact, readArtifactBytes, artifactBytesExist, discardUnreferencedUpload, listLibrary, getLibraryEntry, decodeCursor, filterKey, textPreviewable, readArtifactPrefix, FILE_FAMILIES, LIBRARY_PAGE_MAX, getOwnerProfile, setOwnerProfile, isKnownTimezone, listGroups, getGroup, createGroup, updateGroup, archiveGroup, GroupRefusal, createGroupConversation, listGroupConversations, latestGroupConversation, openGroupRequest, conversationGroup } from '@buddi/core';
73
+ import { listToolPermissions, revokeToolPermission, getArtifact, readArtifactBytes, artifactBytesExist, discardUnreferencedUpload, listLibrary, getLibraryEntry, decodeCursor, filterKey, textPreviewable, readArtifactPrefix, FILE_FAMILIES, LIBRARY_PAGE_MAX, getOwnerProfile, saveOwnerProfile, isKnownTimezone, listGroups, getGroup, createGroup, updateGroup, archiveGroup, deleteGroup, restoreGroup, clearGroupHistory, groupHistorySize, GROUP_UNDO_MS, GroupRefusal, createGroupConversation, listGroupConversations, latestGroupConversation, openGroupRequest, conversationGroup } from '@buddi/core';
73
74
  import { beginOnboarding, completeOnboarding, markStepDone, setOnboardingDetails, skipOnboarding, readWebSetting, writeWebSetting } from '@buddi/core';
74
75
  import { listMemory, setPreference, forgetPreference, updateNote, forgetNote } from '@buddi/tool-memory';
76
+ import { purgeGroups, stopGroupWork } from './group-lifecycle.js';
75
77
  import { engineChangeFromBody, readAgentEngines, readDefaultAgent, readEngineOptions, setAgentEngineFromWeb, setDefaultAgentFromWeb, } from './agents.js';
76
78
  import { writeDefaultAgentRecord } from '../agents/default-agent.js';
77
79
  import { ownerEditableInput, updateAgentFromOwner, PlatformRefusal } from '../agents/platform.js';
@@ -86,7 +88,7 @@ import { ATTACHMENTS_UNAVAILABLE, CHAT_CONVERSATIONS_LIMIT, CHAT_UNAVAILABLE, WE
86
88
  import { readAgentAttention, streamAttention } from './attention.js';
87
89
  import { PreviewApp, PreviewTickets, parsePreviewApiPath } from './preview.js';
88
90
  import { allowedOrigins, isLoopback, webAssetsDir, webUrl } from './config.js';
89
- import { TAILSCALE_SETTING_KEY, daemonWhois, isLoginRefusal, plausibleLogin, proxiedThroughTailscale, sameLogin, tailscaleIdentity, tailscaleRefusalReason, tailscaleSelf, toTailscaleSetting, } from './tailscale.js';
91
+ import { TAILSCALE_SETTING_KEY, daemonWhois, isLoginRefusal, isUnansweredRefusal, plausibleLogin, proxiedThroughTailscale, sameLogin, tailscaleIdentity, tailscaleRefusalReason, tailscaleSelf, toTailscaleSetting, } from './tailscale.js';
90
92
  import { retryHref, sendSignedOut, wantsSignedOutPage } from './signed-out.js';
91
93
  import { extensionEndpoint } from './extension.js';
92
94
  import { REMOTE_HAND_SOCKET_PATH, RemoteHandEndpoint } from './remote-hand.js';
@@ -99,6 +101,10 @@ import { acceptAgentRoute, approveRoute, listPlugins, pluginJobRoute, receivePlu
99
101
  import { marketAssetRoute, marketRoute } from './market.js';
100
102
  import { pluginFoldersRoute } from './folders.js';
101
103
  import { tipsRoute } from '../tips/route.js';
104
+ import { createWidgets, widgetsRoute } from './widgets.js';
105
+ import { createRequirements } from '../plugins/requires.js';
106
+ import { placesList, placesRoute } from './places.js';
107
+ import { OWNER_DATE_FORMATS, OWNER_TIME_FORMATS } from '@buddi/core';
102
108
  import { readFacts, webSettingsStore } from '../tips/facts.js';
103
109
  import { dismissAgentOffer, isPendingAccept, raiseAgentOffers, readAgentOffers, readTeammates } from './agent-offers.js';
104
110
  import { currentVersion, upgradeJobRoute, upgradeRoute, versionCheckRoute, versionRoute, } from './version.js';
@@ -108,6 +114,10 @@ import { BUILD_MISSING, serveAsset, serveShellAtRoot } from './static.js';
108
114
  import { StreamBudget, resumeCursor, streamConversation } from './stream.js';
109
115
  import { ensureWebToken, verifyTicket } from './token.js';
110
116
  import { MAX_UPLOAD_BYTES, readUpload } from './upload.js';
117
+ import { LOCKED_BODY, LockUnavailable, allowedWhileLocked, clientOf, createLock } from './lock.js';
118
+ import { matchApiRoute, TOKEN_REFUSALS } from './api-routes.js';
119
+ import { apiTokensRoute, bearerOf, verifyApiToken } from './api-tokens.js';
120
+ import { LockImageRefusal, MAX_LOCK_IMAGE_BYTES, normaliseLockImage } from './lock-image.js';
111
121
  import { cancelJobFromWeb, cancelReminderFromWeb, decideApprovalFromWeb, retryJobFromWeb, setMissionEnabledFromWeb, setPausedFromWeb, setScheduleFromWeb, dismissOfferFromWeb, dismissOffersFromWeb, takeOfferFromWeb, } from './write.js';
112
122
  /** How often approvals past their expiry are swept, and waiting delegations told. */
113
123
  export const EXPIRY_SWEEP_MS = 60_000;
@@ -232,9 +242,16 @@ export function createWebApp(deps) {
232
242
  const session = await sessions.resolve(parseCookies(req.headers.cookie)[sessionCookieName(cookiePort(req))], scope, now);
233
243
  if (!session)
234
244
  return null;
245
+ // A locked dashboard drives nothing (docs/dashboard.md, "Lock screen").
246
+ if (await lock.locked(session))
247
+ return null;
235
248
  if (session.via === 'tailscale') {
236
- const confirmed = await identityOf(req, now);
249
+ let refusal;
250
+ const confirmed = await identityOf(req, now, (reason) => { refusal = reason; });
237
251
  if (!confirmed || !sameLogin(confirmed.login, session.tailscaleLogin)) {
252
+ // "Could not ask" is not an answer: no socket now, but the session stays.
253
+ if (!confirmed && isUnansweredRefusal(refusal))
254
+ return null;
238
255
  await sessions.destroy(session.id).catch(() => { });
239
256
  return null;
240
257
  }
@@ -273,6 +290,64 @@ export function createWebApp(deps) {
273
290
  return [own, preview].filter((port) => typeof port === 'number');
274
291
  },
275
292
  });
293
+ // Plugin readiness and requirements: serve's, or this server's own.
294
+ const requirements = deps.requirements ??
295
+ createRequirements({ registry: deps.registry, ctx: deps.ctx, env: deps.env ?? process.env, pool: deps.pool, now: deps.now, log });
296
+ // Home's widgets: one cache per server (web/widgets.ts).
297
+ const widgets = createWidgets({ pool: deps.pool, registry: deps.registry, ctx: deps.ctx, now: deps.now });
298
+ /*
299
+ * The lock screen (web/lock.ts): which sessions are locked, the PIN, the
300
+ * gate below. A session that locks has its streams closed and its remote
301
+ * hand let go on the spot, and every half minute the sessions holding a
302
+ * stream are asked again, so one left idle past the delay is locked and cut
303
+ * off even if its page never says a word.
304
+ */
305
+ const lock = createLock({ pool: deps.pool, sessions, now: deps.now, get timezone() { return deps.timezone; }, widgets, log });
306
+ const openStreams = new Map();
307
+ /*
308
+ * The session a live API token acts through: minted on its first request,
309
+ * kept in memory only, one per token (and scope), so a stream budget or a
310
+ * sign-in in progress keyed by session id holds across its requests.
311
+ */
312
+ const tokenSessions = new Map();
313
+ const tokenSession = (holder, scope, now) => {
314
+ const key = `${holder.id}:${scope}`;
315
+ const held = tokenSessions.get(key);
316
+ if (held && held.expiresAt.getTime() > now.getTime()) {
317
+ held.expiresAt = new Date(now.getTime() + held.ttlMs);
318
+ return held;
319
+ }
320
+ for (const [k, s] of tokenSessions)
321
+ if (s.expiresAt.getTime() <= now.getTime())
322
+ tokenSessions.delete(k);
323
+ const session = sessions.create(scope, now, { via: 'token', client: 'api' }, { persist: false });
324
+ tokenSessions.set(key, session);
325
+ return session;
326
+ };
327
+ const holdStream = (session, res) => {
328
+ let entry = openStreams.get(session.id);
329
+ if (!entry)
330
+ openStreams.set(session.id, (entry = { session, responses: new Set() }));
331
+ entry.responses.add(res);
332
+ return () => {
333
+ const held = openStreams.get(session.id);
334
+ if (!held)
335
+ return;
336
+ held.responses.delete(res);
337
+ if (held.responses.size === 0)
338
+ openStreams.delete(session.id);
339
+ };
340
+ };
341
+ lock.onLocked((session) => {
342
+ hand.revoke((lease) => lease === session.id);
343
+ for (const res of openStreams.get(session.id)?.responses ?? [])
344
+ res.end();
345
+ });
346
+ const idleSweep = setInterval(() => {
347
+ for (const { session } of openStreams.values())
348
+ void lock.locked(session).catch(() => { });
349
+ }, 30_000);
350
+ idleSweep.unref();
276
351
  const writeDeps = {
277
352
  pool: deps.pool,
278
353
  registry: deps.registry,
@@ -297,7 +372,7 @@ export function createWebApp(deps) {
297
372
  registry: deps.registry,
298
373
  ctx: deps.ctx,
299
374
  now: deps.now,
300
- timezone: deps.timezone,
375
+ get timezone() { return deps.timezone; },
301
376
  log,
302
377
  ...deps.chat,
303
378
  })
@@ -389,7 +464,6 @@ export function createWebApp(deps) {
389
464
  const identityOf = (req, now, onRefusal) => tailscaleIdentity(req, {
390
465
  setting: readTailscaleSetting,
391
466
  whois,
392
- mayAskDaemon: () => !limiter.blocked(remoteKey(req), now),
393
467
  log,
394
468
  now: () => now,
395
469
  onRefusal,
@@ -406,6 +480,51 @@ export function createWebApp(deps) {
406
480
  cookieHeader(csrfCookieName(cookiePort(req)), session.csrf, { httpOnly: false, maxAgeSeconds, secure: session.scope === 'remote' && !!deps.config.publicOrigin }),
407
481
  ];
408
482
  };
483
+ /**
484
+ * The same pair, expired: what a response carries when the browser presented
485
+ * a session that is gone, so it stops presenting it. A forgotten tab or a
486
+ * polling page then sends no credential at all, which counts as nothing.
487
+ */
488
+ const expiredCookies = (req) => {
489
+ const secure = requestScope(req) === 'remote' && !!deps.config.publicOrigin;
490
+ return [
491
+ cookieHeader(sessionCookieName(cookiePort(req)), '', { httpOnly: true, maxAgeSeconds: 0, secure }),
492
+ cookieHeader(csrfCookieName(cookiePort(req)), '', { httpOnly: false, maxAgeSeconds: 0, secure }),
493
+ ];
494
+ };
495
+ /**
496
+ * What the signed-out page should offer this request: how it arrived,
497
+ * whether Tailscale can sign it in, and whether a lockout is running.
498
+ */
499
+ const signedOutFor = async (req, pathname, search, now, refusal) => {
500
+ const proxied = proxiedThroughTailscale(req);
501
+ let publicHost;
502
+ try {
503
+ publicHost = deps.config.publicOrigin ? new URL(deps.config.publicOrigin).hostname : undefined;
504
+ }
505
+ catch {
506
+ publicHost = undefined;
507
+ }
508
+ let host;
509
+ try {
510
+ host = req.headers.host ? new URL(`http://${req.headers.host}`).hostname : undefined;
511
+ }
512
+ catch {
513
+ host = undefined;
514
+ }
515
+ const scope = requestScope(req);
516
+ const arrived = proxied || (publicHost !== undefined && host === publicHost) ? 'tailnet' : scope === 'local' ? 'local' : 'remote';
517
+ const setting = arrived === 'tailnet' ? await readTailscaleSetting() : null;
518
+ const lockedForMs = limiter.retryAfterMs(remoteKey(req), now);
519
+ return {
520
+ retry: retryHref(pathname, search),
521
+ arrived,
522
+ tailscaleSignIn: !!setting?.enabled && !isLoginRefusal(refusal),
523
+ ...(isLoginRefusal(refusal) ? { tailscaleRefusal: tailscaleRefusalReason(refusal) } : {}),
524
+ ...(isUnansweredRefusal(refusal) ? { tailscaleUnanswered: true } : {}),
525
+ ...(lockedForMs > 0 ? { lockedForMs } : {}),
526
+ };
527
+ };
409
528
  /**
410
529
  * The port this request's cookies are named after (http.ts says why they
411
530
  * carry one): the port the browser sees, from the request's Host, so the
@@ -434,6 +553,13 @@ export function createWebApp(deps) {
434
553
  // have to unpack.
435
554
  const server = createServer((req, res) => {
436
555
  handle(req, res).catch((err) => {
556
+ // The lock could not say whether this request may pass: refused, never let in (web/lock.ts).
557
+ if (err instanceof LockUnavailable) {
558
+ log('web: the lock screen\'s state could not be read; refusing until it can');
559
+ if (!res.headersSent)
560
+ return sendEmpty(res, 503, { 'Retry-After': '5' });
561
+ return res.end();
562
+ }
437
563
  // A defect is a 500 with nothing in it. The sentence goes to the log,
438
564
  // where only the owner can read it.
439
565
  log(`web: ${req.method} ${req.url} failed: ${err instanceof Error ? err.stack : String(err)}`);
@@ -450,7 +576,7 @@ export function createWebApp(deps) {
450
576
  // rather than in `startWebServer` so every caller, tests included, has it.
451
577
  extension.attach(server);
452
578
  extension.attachPath(REMOTE_HAND_SOCKET_PATH, (req, socket, head) => hand.upgrade(req, socket, head));
453
- server.once('close', () => { extension.shutdown(); hand.shutdown(); });
579
+ server.once('close', () => { extension.shutdown(); hand.shutdown(); clearInterval(idleSweep); });
454
580
  return server;
455
581
  async function handle(req, res) {
456
582
  const now = deps.now();
@@ -462,7 +588,9 @@ export function createWebApp(deps) {
462
588
  return sendEmpty(res, 405);
463
589
  // A port answering 401 is not evidence that this installation is ready.
464
590
  // Domain-separated challenge proof never sends the install secret to that port.
465
- if (method === 'GET' && url.pathname === '/_buddi/ready' && deps.env?.BUDDI_WEB_REQUIRE_AUTH === '1') {
591
+ // Answered on every binding: `buddi mcp` asks it before it presents a
592
+ // ticket, so a port held by some other buddi never sees one.
593
+ if (method === 'GET' && url.pathname === '/_buddi/ready') {
466
594
  const challenge = url.searchParams.get('challenge') ?? '';
467
595
  if (!/^[a-f0-9]{64}$/.test(challenge))
468
596
  return sendEmpty(res, 400);
@@ -505,7 +633,9 @@ export function createWebApp(deps) {
505
633
  return sendText(res, 401, 'This sign-in link is no longer valid: a link lasts five minutes.\nRun `buddi` again for a fresh one.\n');
506
634
  }
507
635
  limiter.reset(key);
508
- const session = sessions.create(scope, now);
636
+ // A ticket takes the installation's token, so it is the one way in that
637
+ // opens a session unlocked: what `buddi dashboard --unlock` hands out.
638
+ const session = sessions.create(scope, now, { via: scope === 'local' ? 'local' : 'ticket', client: clientOf(req.headers['x-buddi-client']) });
509
639
  const clean = new URL(url.toString());
510
640
  clean.searchParams.delete(TICKET_PARAM);
511
641
  return sendEmpty(res, 302, {
@@ -513,6 +643,43 @@ export function createWebApp(deps) {
513
643
  'Set-Cookie': sessionCookies(req, session),
514
644
  });
515
645
  }
646
+ /*
647
+ * An owner API token (docs/api.md, "Authentication"): `Authorization:
648
+ * Bearer buddi_…` on an /api request, from a script or another program.
649
+ *
650
+ * It is a credential presented, so a wrong or revoked one counts as a
651
+ * failed sign-in for this address exactly as a stale cookie does. A live
652
+ * one is the owner with no cookie and therefore no CSRF to check, and is
653
+ * answered only on a route the table lets a token call: never one that
654
+ * decides an approval, changes a grant, installs code, opens access or
655
+ * touches a secret. The lock screen does not cover it.
656
+ */
657
+ const bearer = url.pathname === '/api' || url.pathname.startsWith('/api/') ? bearerOf(req.headers.authorization) : undefined;
658
+ if (bearer !== undefined) {
659
+ if (limiter.blocked(key, now)) {
660
+ return sendEmpty(res, 429, { 'Retry-After': String(Math.max(1, Math.ceil(limiter.retryAfterMs(key, now) / 1000))) });
661
+ }
662
+ let holder;
663
+ try {
664
+ holder = await verifyApiToken(deps.pool, bearer, now);
665
+ }
666
+ catch (err) {
667
+ log(`web: checking an API token failed: ${err instanceof Error ? err.message : String(err)}`);
668
+ return sendEmpty(res, 503, { 'Retry-After': '5' });
669
+ }
670
+ if (!holder) {
671
+ limiter.failCredential(key, bearer, now);
672
+ return sendEmpty(res, 401, { 'WWW-Authenticate': 'Bearer realm="buddi"' });
673
+ }
674
+ const path = url.pathname.replace(/\/+$/, '') || '/api';
675
+ const route = matchApiRoute(method, path);
676
+ if (!route)
677
+ return method === 'GET' || method === 'HEAD' ? sendJson(res, 404, { error: 'no such endpoint' }) : sendEmpty(res, 405);
678
+ if (route.token) {
679
+ return sendJson(res, 403, { error: `An API token cannot call ${route.method} ${route.path}. ${TOKEN_REFUSALS[route.token]} Do it on the dashboard.` });
680
+ }
681
+ return api(req, res, url, method, now, tokenSession(holder, scope, now));
682
+ }
516
683
  const cookies = parseCookies(req.headers.cookie);
517
684
  const presentedSession = cookies[sessionCookieName(cookiePort(req))];
518
685
  let session = await sessions.resolve(presentedSession, scope, now);
@@ -523,18 +690,29 @@ export function createWebApp(deps) {
523
690
  */
524
691
  let refusal;
525
692
  const noteRefusal = (reason) => { refusal = reason; };
693
+ /*
694
+ * Set when the browser presented a session that is gone: the refusal then
695
+ * expires its cookies, so it stops presenting them (and stops counting).
696
+ */
697
+ let forgetCookies = false;
526
698
  /*
527
699
  * The answer to a refused request: the signed-out page for a person
528
- * opening a page, the empty 401 for everything else (docs/web.md).
700
+ * opening a page, the empty status for everything else (docs/web.md).
701
+ * 401 is "signed out", 429 "too many tries from here", 503 "Tailscale
702
+ * could not be asked; the session is still good, try again".
529
703
  */
530
- const refuse = () => {
704
+ const refuse = async (status = 401) => {
705
+ const headers = forgetCookies ? { 'Set-Cookie': expiredCookies(req) } : {};
706
+ if (status === 429)
707
+ headers['Retry-After'] = String(Math.max(1, Math.ceil(limiter.retryAfterMs(key, now) / 1000)));
708
+ if (status === 503)
709
+ headers['Retry-After'] = '5';
531
710
  if (!wantsSignedOutPage(req, method, url.pathname))
532
- return sendEmpty(res, 401);
533
- return sendSignedOut(res, {
534
- retry: retryHref(url.pathname, url.search),
535
- ...(isLoginRefusal(refusal) ? { tailscaleRefusal: tailscaleRefusalReason(refusal) } : {}),
536
- });
711
+ return sendEmpty(res, status, headers);
712
+ return sendSignedOut(res, await signedOutFor(req, url.pathname, url.search, now, refusal), headers, status);
537
713
  };
714
+ /* A Tailscale session this request ended: not a guess, so never a failed sign-in. */
715
+ let revoked = false;
538
716
  /*
539
717
  * A Tailscale session is re-confirmed on every single request.
540
718
  *
@@ -550,14 +728,23 @@ export function createWebApp(deps) {
550
728
  if (session?.via === 'tailscale') {
551
729
  const confirmed = await identityOf(req, now, noteRefusal);
552
730
  if (!confirmed || !sameLogin(confirmed.login, session.tailscaleLogin)) {
553
- const revoked = session.id;
731
+ /*
732
+ * The daemon could not be asked (busy, starting, timed out). That is
733
+ * not an answer about anyone, so the session is not ended for it —
734
+ * a restart's first burst of requests used to end every tailnet
735
+ * session this way — and nothing is counted. This request waits.
736
+ */
737
+ if (!confirmed && isUnansweredRefusal(refusal))
738
+ return refuse(503);
739
+ const ended = session.id;
554
740
  // A hand this session was holding does not outlive the session.
555
- hand.revoke((lease) => lease === revoked);
556
- await sessions.destroy(revoked);
557
- if (limiter.blocked(key, now))
558
- return sendEmpty(res, 429);
559
- limiter.failCredential(key, presentedSession ?? '', now);
560
- return refuse();
741
+ hand.revoke((lease) => lease === ended);
742
+ await sessions.destroy(ended);
743
+ session = undefined;
744
+ revoked = true;
745
+ forgetCookies = true;
746
+ // The identity on this very request may still earn a new session below.
747
+ refusal = undefined;
561
748
  }
562
749
  }
563
750
  /*
@@ -571,7 +758,14 @@ export function createWebApp(deps) {
571
758
  if (!session && openAccess && scope === 'local') {
572
759
  // Not stored: the next request mints another for free, so there is
573
760
  // nothing to keep across a restart and no row per cookie-less poll.
574
- session = sessions.create(scope, now, undefined, { persist: false });
761
+ // While a PIN is set a browser's new session starts locked: clearing the
762
+ // cookie or opening a private window is not a way past the lock screen.
763
+ //
764
+ // Always a browser's session: `x-buddi-client` is a header anybody can
765
+ // send, so here it earns nothing. Only a ticket from the installation
766
+ // token (the exchange above) names a client the lock does not cover.
767
+ const locked = await lock.startLocked('browser');
768
+ session = sessions.create(scope, now, { via: 'local', client: 'browser' }, { persist: false, ...(locked ? { locked } : {}) });
575
769
  res.setHeader('Set-Cookie', sessionCookies(req, session));
576
770
  }
577
771
  /*
@@ -589,12 +783,13 @@ export function createWebApp(deps) {
589
783
  const identity = await identityOf(req, now, noteRefusal);
590
784
  if (identity) {
591
785
  limiter.reset(key);
786
+ const locked = await lock.startLocked('browser');
592
787
  session = sessions.create('remote', now, {
593
788
  via: 'tailscale',
594
789
  tailscaleLogin: identity.login,
595
790
  tailscaleAddress: identity.address,
596
791
  tailscaleName: identity.name,
597
- });
792
+ }, locked ? { locked } : {});
598
793
  res.setHeader('Set-Cookie', sessionCookies(req, session));
599
794
  }
600
795
  }
@@ -610,8 +805,11 @@ export function createWebApp(deps) {
610
805
  // able to lock the owner out of every way in.
611
806
  if (!presentedSession)
612
807
  return refuse();
808
+ forgetCookies = true;
809
+ if (revoked)
810
+ return refuse();
613
811
  if (limiter.blocked(key, now))
614
- return sendEmpty(res, 429);
812
+ return refuse(429);
615
813
  limiter.failCredential(key, presentedSession, now);
616
814
  return refuse();
617
815
  }
@@ -641,6 +839,14 @@ export function createWebApp(deps) {
641
839
  return sendEmpty(res, 403);
642
840
  }
643
841
  if (url.pathname === '/api' || url.pathname.startsWith('/api/')) {
842
+ /*
843
+ * The lock screen's gate, after the session and its CSRF: a locked
844
+ * session gets 423 for everything but what the lock screen itself
845
+ * draws and the two ways off it (web/lock.ts).
846
+ */
847
+ const path = url.pathname.replace(/\/+$/, '') || '/api';
848
+ if (!allowedWhileLocked(method, path) && (await lock.locked(session)))
849
+ return sendJson(res, 423, LOCKED_BODY);
644
850
  return api(req, res, url, method, now, session);
645
851
  }
646
852
  if (mutating)
@@ -690,6 +896,7 @@ export function createWebApp(deps) {
690
896
  log,
691
897
  pool: deps.pool,
692
898
  registry: deps.registry,
899
+ requirements,
693
900
  ...(deps.plugins ? { engine: deps.plugins } : {}),
694
901
  });
695
902
  /** Is a mailbox connected? The email plugin's own read, the one Home's offer asks. */
@@ -764,6 +971,24 @@ export function createWebApp(deps) {
764
971
  now: deps.now,
765
972
  agents: () => deps.catalog.list(),
766
973
  plugins: () => deps.registry.manifests().map((m) => m.name),
974
+ needsSetup: async () => {
975
+ const out = [];
976
+ for (const manifest of deps.registry.manifests()) {
977
+ if (manifest.setup === undefined)
978
+ continue;
979
+ const ready = await requirements.readiness.of(manifest.name);
980
+ if (!ready || ready.ready)
981
+ continue;
982
+ const page = ready.page === undefined ? undefined : deps.registry.pages().find((p) => p.plugin === manifest.name && p.id === ready.page);
983
+ const route = page === undefined
984
+ ? undefined
985
+ : page.place === 'settings'
986
+ ? `#/settings/p.${manifest.name}${page.id === manifest.name ? '' : `.${page.id}`}`
987
+ : `#/p/${encodeURIComponent(manifest.name)}/${encodeURIComponent(page.id)}`;
988
+ out.push({ plugin: manifest.name, ...(ready.note ? { note: ready.note } : {}), ...(route ? { route } : {}) });
989
+ }
990
+ return out;
991
+ },
767
992
  mailboxSet: async () => {
768
993
  const answer = await runPageQuery(pagesDeps(), 'email', 'triage_offer', new URLSearchParams()).catch(() => null);
769
994
  return answer?.status === 200 && answer.body?.data?.wanted === true;
@@ -772,6 +997,74 @@ export function createWebApp(deps) {
772
997
  }, { method, path, body, preview: url.searchParams.get('preview') });
773
998
  return sendJson(res, answer.status, answer.body);
774
999
  }
1000
+ // The lock screen: its state and data, Lock now, Unlock, the PIN, its settings and picture (web/lock.ts).
1001
+ if (path === '/api/lock' || path.startsWith('/api/lock/')) {
1002
+ let body = {};
1003
+ const upload = method === 'POST' && path === '/api/lock/background';
1004
+ if ((method === 'POST' || method === 'PUT') && !upload) {
1005
+ try {
1006
+ body = await readJsonBody(req);
1007
+ }
1008
+ catch {
1009
+ return sendJson(res, 400, { error: 'request body must be JSON' });
1010
+ }
1011
+ }
1012
+ const answer = await lock.route({
1013
+ method,
1014
+ path,
1015
+ body,
1016
+ session,
1017
+ query: url.searchParams,
1018
+ ...(upload ? {
1019
+ upload: async () => {
1020
+ const file = await readUpload(req, MAX_LOCK_IMAGE_BYTES);
1021
+ if (!file.ok)
1022
+ return { ok: false, status: file.status, error: file.status === 413 ? 'A picture can be at most 10 MB.' : file.error };
1023
+ try {
1024
+ return { ok: true, image: normaliseLockImage(file.file.bytes, file.file.mime) };
1025
+ }
1026
+ catch (err) {
1027
+ if (err instanceof LockImageRefusal)
1028
+ return { ok: false, status: err.status, error: err.message };
1029
+ throw err;
1030
+ }
1031
+ },
1032
+ } : {}),
1033
+ });
1034
+ if (answer === null)
1035
+ return sendJson(res, 404, { error: 'no such endpoint' });
1036
+ if ('image' in answer) {
1037
+ const etag = `"${answer.image.sha256}"`;
1038
+ res.setHeader('ETag', etag);
1039
+ res.setHeader('Cache-Control', 'private, max-age=31536000, immutable');
1040
+ res.setHeader('X-Content-Type-Options', 'nosniff');
1041
+ res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
1042
+ if (req.headers['if-none-match'] === etag)
1043
+ return sendEmpty(res, 304);
1044
+ res.setHeader('Content-Type', 'image/jpeg');
1045
+ res.setHeader('Content-Length', String(answer.image.jpeg.length));
1046
+ res.statusCode = 200;
1047
+ res.end(method === 'HEAD' ? undefined : answer.image.jpeg);
1048
+ return;
1049
+ }
1050
+ if (answer.status === 204)
1051
+ return sendEmpty(res, 204);
1052
+ return sendJson(res, answer.status, answer.body);
1053
+ }
1054
+ // Home's widgets: the gallery, the owner's layout, each placed one's body (web/widgets.ts).
1055
+ if (path === '/api/widgets' || path.startsWith('/api/widgets/')) {
1056
+ let body = {};
1057
+ if (method === 'PUT' || (method === 'POST' && path === '/api/widgets/preview')) {
1058
+ try {
1059
+ body = await readJsonBody(req);
1060
+ }
1061
+ catch {
1062
+ return sendJson(res, 400, { error: 'request body must be JSON' });
1063
+ }
1064
+ }
1065
+ const answer = await widgetsRoute(widgets, { method, path, body, query: url.searchParams });
1066
+ return sendJson(res, answer.status, answer.body);
1067
+ }
775
1068
  // Settings → Connections: every method, one module (web/connections.ts).
776
1069
  if (path === '/api/connections' || path.startsWith('/api/connections/')) {
777
1070
  let body = {};
@@ -952,10 +1245,14 @@ export function createWebApp(deps) {
952
1245
  res.end(method === 'HEAD' ? undefined : bytes);
953
1246
  return;
954
1247
  }
955
- case '/api/session':
1248
+ case '/api/session': {
1249
+ // How the owner reads times and dates: every page formats with it.
1250
+ const formats = await getOwnerProfile(deps.pool).catch(() => null);
956
1251
  return sendJson(res, 200, {
957
1252
  csrf: session.csrf,
958
1253
  timezone: deps.timezone,
1254
+ timeFormat: formats?.timeFormat ?? null,
1255
+ dateFormat: formats?.dateFormat ?? null,
959
1256
  host: deps.config.host,
960
1257
  port: deps.config.port,
961
1258
  // Where buddi runs: a page opened from another machine is still
@@ -979,6 +1276,7 @@ export function createWebApp(deps) {
979
1276
  // the old one" without a second route.
980
1277
  version: await currentVersion(deps.env ?? process.env),
981
1278
  });
1279
+ }
982
1280
  /*
983
1281
  * The Tailscale panel's whole payload: what is stored, whether a
984
1282
  * daemon is here to ask, who this machine is signed in as (so the
@@ -1010,7 +1308,9 @@ export function createWebApp(deps) {
1010
1308
  timezone: deps.timezone,
1011
1309
  now,
1012
1310
  })),
1013
- running: chat?.runningCount ?? 0,
1311
+ // Every surface's runs (Telegram, the queue, the terminal), not only
1312
+ // this dashboard's; a chat send still being set up counts too.
1313
+ running: Math.max(runningAgentRuns(), chat?.runningCount ?? 0),
1014
1314
  });
1015
1315
  case '/api/events':
1016
1316
  return sendJson(res, 200, await readEvents(deps.pool, {
@@ -1113,6 +1413,8 @@ export function createWebApp(deps) {
1113
1413
  default: readDefaultAgent(deps.catalog),
1114
1414
  });
1115
1415
  case '/api/groups':
1416
+ // The list is read every few seconds, so it is also where a delete whose minute has passed is made final.
1417
+ await purgeGroups(deps.pool, deps.now(), log);
1116
1418
  return sendJson(res, 200, { groups: (await listGroups(deps.pool)).map(groupView) });
1117
1419
  /*
1118
1420
  * The supervisor, when there is one. A developer checkout has no
@@ -1237,7 +1539,7 @@ export function createWebApp(deps) {
1237
1539
  return sendJson(res, 200, await telegramDevices(telegramDeps()));
1238
1540
  case '/api/owner': {
1239
1541
  const profile = await getOwnerProfile(deps.pool);
1240
- return sendJson(res, 200, { ...profile, detectedTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone, zones: knownTimezones() });
1542
+ return sendJson(res, 200, { ...profile, places: await placesList(deps.pool), detectedTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone, zones: knownTimezones() });
1241
1543
  }
1242
1544
  case '/api/memory': {
1243
1545
  try {
@@ -1249,6 +1551,9 @@ export function createWebApp(deps) {
1249
1551
  return sendJson(res, 503, { error: `Memory is unavailable: ${err instanceof Error ? err.message : String(err)}` });
1250
1552
  }
1251
1553
  }
1554
+ // Settings → API tokens. A token is refused these by the table: it cannot list or make its kind.
1555
+ case '/api/api-tokens':
1556
+ return reply(res, await apiTokensRoute(deps.pool, { method, path, body: null, now }));
1252
1557
  case '/api/provider-accounts':
1253
1558
  if (!deps.providerAccounts)
1254
1559
  return sendJson(res, 503, { error: 'Provider accounts are unavailable in this process.' });
@@ -1420,7 +1725,13 @@ export function createWebApp(deps) {
1420
1725
  return sendJson(res, 404, { error: 'no such group' });
1421
1726
  const latest = await latestGroupConversation(deps.pool, group.id);
1422
1727
  const open = latest ? await openGroupRequest(deps.pool, latest) : null;
1423
- return sendJson(res, 200, { ...groupView(group), latestConversationId: latest, openRequest: open ? { id: open.id, state: open.state, awaitingAgentId: open.awaitingAgentId, budgetReserved: open.budgetReserved, budgetTotal: open.budgetTotal } : null });
1728
+ return sendJson(res, 200, {
1729
+ ...groupView(group),
1730
+ latestConversationId: latest,
1731
+ openRequest: open ? { id: open.id, state: open.state, awaitingAgentId: open.awaitingAgentId, budgetReserved: open.budgetReserved, budgetTotal: open.budgetTotal } : null,
1732
+ // What Clear history and Delete would take, for the sentence that asks first.
1733
+ history: await groupHistorySize(deps.pool, group.id),
1734
+ });
1424
1735
  }
1425
1736
  const chatConversations = /^\/api\/chat\/([^/]+)\/conversations$/.exec(path);
1426
1737
  if (chatConversations) {
@@ -1449,6 +1760,7 @@ export function createWebApp(deps) {
1449
1760
  const release = streams.take(session.id);
1450
1761
  if (release === null)
1451
1762
  return sendEmpty(res, 429);
1763
+ const let_go = holdStream(session, res);
1452
1764
  try {
1453
1765
  await streamAttention(req, res, {
1454
1766
  pool: deps.pool,
@@ -1457,6 +1769,7 @@ export function createWebApp(deps) {
1457
1769
  });
1458
1770
  }
1459
1771
  finally {
1772
+ let_go();
1460
1773
  release();
1461
1774
  }
1462
1775
  return;
@@ -1472,6 +1785,7 @@ export function createWebApp(deps) {
1472
1785
  const release = streams.take(session.id);
1473
1786
  if (release === null)
1474
1787
  return sendEmpty(res, 429);
1788
+ const let_go = holdStream(session, res);
1475
1789
  try {
1476
1790
  await streamConversation(req, res, {
1477
1791
  pool: deps.pool,
@@ -1482,6 +1796,7 @@ export function createWebApp(deps) {
1482
1796
  });
1483
1797
  }
1484
1798
  finally {
1799
+ let_go();
1485
1800
  release();
1486
1801
  }
1487
1802
  return;
@@ -1545,6 +1860,12 @@ export function createWebApp(deps) {
1545
1860
  const forgotten = await extension.unpair();
1546
1861
  return sendJson(res, forgotten.status, forgotten.body);
1547
1862
  }
1863
+ // Revoke an API token: the next request carrying it is a 401.
1864
+ const tokenGone = /^\/api\/api-tokens\/([0-9a-f-]{36})$/i.exec(path);
1865
+ if (tokenGone) {
1866
+ const revoked = await apiTokensRoute(deps.pool, { method, path, body: null, now });
1867
+ return revoked.status === 204 ? sendEmpty(res, 204) : sendJson(res, revoked.status, revoked.body);
1868
+ }
1548
1869
  // A phone the owner no longer wants talking to their agents. Same as
1549
1870
  // `buddi telegram unpair <id>`, and as immediate.
1550
1871
  const phoneGone = /^\/api\/telegram\/devices\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i.exec(path);
@@ -1560,14 +1881,21 @@ export function createWebApp(deps) {
1560
1881
  }
1561
1882
  }
1562
1883
  /*
1563
- * A group the owner is done with leaves the rail and takes no new
1564
- * requests — and keeps everything that was said in it. Archived, never
1565
- * deleted: the transcript is the record of work that was done, and no
1566
- * amount of tidying the roster is worth destroying it.
1884
+ * Delete a group: it leaves every list now, with whatever it was doing
1885
+ * stopped, and is removed for good — its history and what the room
1886
+ * remembered, never its agents — once GROUP_UNDO_MS has passed without
1887
+ * a restore. The answer says until when Undo works.
1567
1888
  */
1568
1889
  const groupGone = /^\/api\/groups\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i.exec(path);
1569
1890
  if (groupGone) {
1570
- return (await archiveGroup(deps.pool, groupGone[1], deps.now())) ? sendEmpty(res, 204) : sendEmpty(res, 404);
1891
+ const at = deps.now();
1892
+ if (!(await getGroup(deps.pool, groupGone[1])))
1893
+ return sendJson(res, 404, { error: 'no such group' });
1894
+ await stopGroupWork(deps.pool, chat, groupGone[1], at, deps.ctx.ownerId);
1895
+ if (!(await deleteGroup(deps.pool, groupGone[1], at)))
1896
+ return sendJson(res, 404, { error: 'no such group' });
1897
+ await purgeGroups(deps.pool, at, log);
1898
+ return sendJson(res, 200, { undoUntil: new Date(at.getTime() + GROUP_UNDO_MS).toISOString() });
1571
1899
  }
1572
1900
  /*
1573
1901
  * The owner read the note a rollover carried into this conversation and
@@ -1900,6 +2228,8 @@ export function createWebApp(deps) {
1900
2228
  }
1901
2229
  if (path === '/api/presence')
1902
2230
  return reply(res, await presenceRoute(deps.pool, body, deps.now()));
2231
+ if (path === '/api/api-tokens')
2232
+ return reply(res, await apiTokensRoute(deps.pool, { method, path, body, now }));
1903
2233
  if (path === '/api/notifications/test')
1904
2234
  return reply(res, await testChannelRoute(body, deps.now()));
1905
2235
  if (path === '/api/notifications/agent-mute')
@@ -2301,6 +2631,21 @@ export function createWebApp(deps) {
2301
2631
  if (groupArchive) {
2302
2632
  return (await archiveGroup(deps.pool, groupArchive[1], deps.now())) ? sendEmpty(res, 204) : sendEmpty(res, 404);
2303
2633
  }
2634
+ // Undo a delete, while the minute lasts. Too late: 410, and the page says so.
2635
+ const groupRestore = /^\/api\/groups\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/restore$/i.exec(path);
2636
+ if (groupRestore) {
2637
+ const back = await restoreGroup(deps.pool, groupRestore[1], deps.now());
2638
+ return back ? sendJson(res, 200, groupView(back)) : sendJson(res, 410, { error: 'Too late to undo: that group is gone for good.' });
2639
+ }
2640
+ // Clear the history, keep the group: its conversations go, its members and memory stay.
2641
+ const groupClear = /^\/api\/groups\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\/clear$/i.exec(path);
2642
+ if (groupClear) {
2643
+ const group = await getGroup(deps.pool, groupClear[1]);
2644
+ if (!group)
2645
+ return sendJson(res, 404, { error: 'no such group' });
2646
+ await stopGroupWork(deps.pool, chat, group.id, deps.now(), deps.ctx.ownerId);
2647
+ return sendJson(res, 200, { conversations: await clearGroupHistory(deps.pool, group.id) });
2648
+ }
2304
2649
  /*
2305
2650
  * First run, from the dashboard.
2306
2651
  *
@@ -2532,14 +2877,37 @@ export function createWebApp(deps) {
2532
2877
  return sendJson(res, 400, { error: `\`${key}\` must be a string or null` });
2533
2878
  patch[key] = given;
2534
2879
  }
2880
+ // How times and dates read: a known word, or null for Auto.
2881
+ if (body.timeFormat !== undefined) {
2882
+ if (body.timeFormat !== null && !OWNER_TIME_FORMATS.includes(body.timeFormat))
2883
+ return sendJson(res, 400, { error: '`timeFormat` is 12h, 24h or null (Auto).' });
2884
+ patch.timeFormat = body.timeFormat;
2885
+ }
2886
+ if (body.dateFormat !== undefined) {
2887
+ if (body.dateFormat !== null && !OWNER_DATE_FORMATS.includes(body.dateFormat))
2888
+ return sendJson(res, 400, { error: '`dateFormat` is short, long, iso or null (Auto).' });
2889
+ patch.dateFormat = body.dateFormat;
2890
+ }
2535
2891
  if (patch.timezone && !isKnownTimezone(patch.timezone))
2536
2892
  return sendJson(res, 400, { error: `"${patch.timezone}" is not a timezone this host knows.` });
2537
2893
  if (patch.preferredName && patch.preferredName.length > 80)
2538
2894
  return sendJson(res, 400, { error: 'The name is too long (80 characters at most).' });
2539
2895
  if (patch.about && patch.about.length > 1000)
2540
2896
  return sendJson(res, 400, { error: 'Keep the line about you under 1,000 characters.' });
2541
- const profile = await setOwnerProfile(deps.pool, patch);
2542
- return sendJson(res, 200, { ...profile, detectedTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone, zones: knownTimezones() });
2897
+ // The zone applies at once; schedules kept in the old one move with it.
2898
+ const { profile, zoneChange } = await saveOwnerProfile(deps.pool, patch, deps.env ?? process.env);
2899
+ if (zoneChange)
2900
+ log(`owner: timezone ${zoneChange.from} → ${zoneChange.to}${zoneChange.missions.length > 0 ? `; moved ${zoneChange.missions.join(', ')}` : ''}`);
2901
+ return sendJson(res, 200, { ...profile, places: await placesList(deps.pool), detectedTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone, zones: knownTimezones() });
2902
+ }
2903
+ /* The owner's places beside the timezone: find one, save one, remove one (web/places.ts). */
2904
+ if (path.startsWith('/api/owner/places')) {
2905
+ const answered = await placesRoute({ pool: deps.pool, log, ...(deps.placesHttp ? { http: deps.placesHttp } : {}) }, path, body);
2906
+ if (answered) {
2907
+ // Plugins that read the places answer their setup again now.
2908
+ requirements.readiness.forget();
2909
+ return sendJson(res, answered.status, answered.body);
2910
+ }
2543
2911
  }
2544
2912
  /* Memory, the owner's side: correct a preference, retire one, edit or forget a note. */
2545
2913
  if (path === '/api/memory/preferences') {
@@ -2863,7 +3231,8 @@ export function createWebApp(deps) {
2863
3231
  */
2864
3232
  export async function startWebServer(deps) {
2865
3233
  const token = deps.token ?? (await ensureWebToken()).token;
2866
- const server = createWebApp({ ...deps, token });
3234
+ // The zone stays a getter through the spread: Settings → Profile can change it.
3235
+ const server = createWebApp({ ...deps, token, get timezone() { return deps.timezone; } });
2867
3236
  await new Promise((resolve, reject) => {
2868
3237
  server.once('error', reject);
2869
3238
  server.listen(deps.config.port, deps.config.host, () => {