@withbuddi/buddi 0.1.0-pre.43 → 0.1.0-pre.45

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 (695) hide show
  1. package/examples/agents/agent-father/agent.md +12 -5
  2. package/examples/agents/concierge/agent.md +11 -3
  3. package/extension/icons/128.png +0 -0
  4. package/extension/icons/16.png +0 -0
  5. package/extension/icons/32.png +0 -0
  6. package/extension/icons/48.png +0 -0
  7. package/extension/manifest.json +7 -3
  8. package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
  9. package/node_modules/@buddi/cli/dist/access-cmd.d.ts +2 -1
  10. package/node_modules/@buddi/cli/dist/access-cmd.d.ts.map +1 -1
  11. package/node_modules/@buddi/cli/dist/access-cmd.js +40 -7
  12. package/node_modules/@buddi/cli/dist/access-cmd.js.map +1 -1
  13. package/node_modules/@buddi/cli/dist/args.d.ts +2 -1
  14. package/node_modules/@buddi/cli/dist/args.d.ts.map +1 -1
  15. package/node_modules/@buddi/cli/dist/args.js +7 -3
  16. package/node_modules/@buddi/cli/dist/args.js.map +1 -1
  17. package/node_modules/@buddi/cli/dist/commands.d.ts.map +1 -1
  18. package/node_modules/@buddi/cli/dist/commands.js +3 -2
  19. package/node_modules/@buddi/cli/dist/commands.js.map +1 -1
  20. package/node_modules/@buddi/cli/dist/main.js +1 -1
  21. package/node_modules/@buddi/cli/dist/main.js.map +1 -1
  22. package/node_modules/@buddi/cli/dist/mcp/server.js +1 -1
  23. package/node_modules/@buddi/cli/dist/mcp/server.js.map +1 -1
  24. package/node_modules/@buddi/cli/dist/mcp/tools.d.ts.map +1 -1
  25. package/node_modules/@buddi/cli/dist/mcp/tools.js +60 -0
  26. package/node_modules/@buddi/cli/dist/mcp/tools.js.map +1 -1
  27. package/node_modules/@buddi/core/dist/.tsbuildinfo +1 -1
  28. package/node_modules/@buddi/core/dist/lock.d.ts +15 -1
  29. package/node_modules/@buddi/core/dist/lock.d.ts.map +1 -1
  30. package/node_modules/@buddi/core/dist/lock.js +15 -1
  31. package/node_modules/@buddi/core/dist/lock.js.map +1 -1
  32. package/node_modules/@buddi/core/dist/pages.d.ts +75 -0
  33. package/node_modules/@buddi/core/dist/pages.d.ts.map +1 -1
  34. package/node_modules/@buddi/core/dist/pages.js +14 -0
  35. package/node_modules/@buddi/core/dist/pages.js.map +1 -1
  36. package/node_modules/@buddi/core/dist/plugin/index.d.ts +2 -2
  37. package/node_modules/@buddi/core/dist/plugin/index.d.ts.map +1 -1
  38. package/node_modules/@buddi/core/dist/plugin/index.js.map +1 -1
  39. package/node_modules/@buddi/core/dist/plugin/version.d.ts +1 -1
  40. package/node_modules/@buddi/core/dist/plugin/version.js +1 -1
  41. package/node_modules/@buddi/core/dist/provider-accounts.d.ts +32 -0
  42. package/node_modules/@buddi/core/dist/provider-accounts.d.ts.map +1 -1
  43. package/node_modules/@buddi/core/dist/provider-accounts.js +22 -0
  44. package/node_modules/@buddi/core/dist/provider-accounts.js.map +1 -1
  45. package/node_modules/@buddi/core/dist/tools.d.ts +6 -1
  46. package/node_modules/@buddi/core/dist/tools.d.ts.map +1 -1
  47. package/node_modules/@buddi/core/dist/tools.js.map +1 -1
  48. package/node_modules/@buddi/core/migrations/077_lock_background_portrait.sql +5 -0
  49. package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
  50. package/node_modules/@buddi/gateway/dist/agents/agent-intro.d.ts +31 -0
  51. package/node_modules/@buddi/gateway/dist/agents/agent-intro.d.ts.map +1 -0
  52. package/node_modules/@buddi/gateway/dist/agents/agent-intro.js +116 -0
  53. package/node_modules/@buddi/gateway/dist/agents/agent-intro.js.map +1 -0
  54. package/node_modules/@buddi/gateway/dist/agents/delegation.d.ts +10 -0
  55. package/node_modules/@buddi/gateway/dist/agents/delegation.d.ts.map +1 -1
  56. package/node_modules/@buddi/gateway/dist/agents/delegation.js +18 -1
  57. package/node_modules/@buddi/gateway/dist/agents/delegation.js.map +1 -1
  58. package/node_modules/@buddi/gateway/dist/agents/owner-tools.d.ts +21 -8
  59. package/node_modules/@buddi/gateway/dist/agents/owner-tools.d.ts.map +1 -1
  60. package/node_modules/@buddi/gateway/dist/agents/owner-tools.js +201 -36
  61. package/node_modules/@buddi/gateway/dist/agents/owner-tools.js.map +1 -1
  62. package/node_modules/@buddi/gateway/dist/agents/platform.d.ts +14 -1
  63. package/node_modules/@buddi/gateway/dist/agents/platform.d.ts.map +1 -1
  64. package/node_modules/@buddi/gateway/dist/agents/platform.js +44 -11
  65. package/node_modules/@buddi/gateway/dist/agents/platform.js.map +1 -1
  66. package/node_modules/@buddi/gateway/dist/bootstrap.d.ts.map +1 -1
  67. package/node_modules/@buddi/gateway/dist/bootstrap.js +2 -0
  68. package/node_modules/@buddi/gateway/dist/bootstrap.js.map +1 -1
  69. package/node_modules/@buddi/gateway/dist/edition-origin.d.ts +57 -0
  70. package/node_modules/@buddi/gateway/dist/edition-origin.d.ts.map +1 -0
  71. package/node_modules/@buddi/gateway/dist/edition-origin.js +156 -0
  72. package/node_modules/@buddi/gateway/dist/edition-origin.js.map +1 -0
  73. package/node_modules/@buddi/gateway/dist/evals/golden.d.ts +5 -0
  74. package/node_modules/@buddi/gateway/dist/evals/golden.d.ts.map +1 -1
  75. package/node_modules/@buddi/gateway/dist/evals/golden.js +48 -0
  76. package/node_modules/@buddi/gateway/dist/evals/golden.js.map +1 -1
  77. package/node_modules/@buddi/gateway/dist/mcp/requests.d.ts +8 -2
  78. package/node_modules/@buddi/gateway/dist/mcp/requests.d.ts.map +1 -1
  79. package/node_modules/@buddi/gateway/dist/mcp/requests.js +74 -1
  80. package/node_modules/@buddi/gateway/dist/mcp/requests.js.map +1 -1
  81. package/node_modules/@buddi/gateway/dist/owner-profile-edit.d.ts +160 -0
  82. package/node_modules/@buddi/gateway/dist/owner-profile-edit.d.ts.map +1 -0
  83. package/node_modules/@buddi/gateway/dist/owner-profile-edit.js +296 -0
  84. package/node_modules/@buddi/gateway/dist/owner-profile-edit.js.map +1 -0
  85. package/node_modules/@buddi/gateway/dist/provider-accounts.d.ts.map +1 -1
  86. package/node_modules/@buddi/gateway/dist/provider-accounts.js +2 -1
  87. package/node_modules/@buddi/gateway/dist/provider-accounts.js.map +1 -1
  88. package/node_modules/@buddi/gateway/dist/system-context.d.ts +9 -0
  89. package/node_modules/@buddi/gateway/dist/system-context.d.ts.map +1 -1
  90. package/node_modules/@buddi/gateway/dist/system-context.js +28 -2
  91. package/node_modules/@buddi/gateway/dist/system-context.js.map +1 -1
  92. package/node_modules/@buddi/gateway/dist/telegram/approvals.d.ts +6 -0
  93. package/node_modules/@buddi/gateway/dist/telegram/approvals.d.ts.map +1 -1
  94. package/node_modules/@buddi/gateway/dist/telegram/approvals.js +10 -2
  95. package/node_modules/@buddi/gateway/dist/telegram/approvals.js.map +1 -1
  96. package/node_modules/@buddi/gateway/dist/telegram/main.d.ts.map +1 -1
  97. package/node_modules/@buddi/gateway/dist/telegram/main.js +10 -3
  98. package/node_modules/@buddi/gateway/dist/telegram/main.js.map +1 -1
  99. package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts +9 -0
  100. package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts.map +1 -1
  101. package/node_modules/@buddi/gateway/dist/telegram/outbound.js +43 -0
  102. package/node_modules/@buddi/gateway/dist/telegram/outbound.js.map +1 -1
  103. package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts +2 -0
  104. package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts.map +1 -1
  105. package/node_modules/@buddi/gateway/dist/telegram/surface.js +2 -1
  106. package/node_modules/@buddi/gateway/dist/telegram/surface.js.map +1 -1
  107. package/node_modules/@buddi/gateway/dist/tips/engine.d.ts +32 -0
  108. package/node_modules/@buddi/gateway/dist/tips/engine.d.ts.map +1 -1
  109. package/node_modules/@buddi/gateway/dist/tips/engine.js +69 -0
  110. package/node_modules/@buddi/gateway/dist/tips/engine.js.map +1 -1
  111. package/node_modules/@buddi/gateway/dist/tips/route.d.ts +1 -3
  112. package/node_modules/@buddi/gateway/dist/tips/route.d.ts.map +1 -1
  113. package/node_modules/@buddi/gateway/dist/tips/route.js +54 -30
  114. package/node_modules/@buddi/gateway/dist/tips/route.js.map +1 -1
  115. package/node_modules/@buddi/gateway/dist/web/access/cloudflare-connector.d.ts +63 -0
  116. package/node_modules/@buddi/gateway/dist/web/access/cloudflare-connector.d.ts.map +1 -0
  117. package/node_modules/@buddi/gateway/dist/web/access/cloudflare-connector.js +87 -0
  118. package/node_modules/@buddi/gateway/dist/web/access/cloudflare-connector.js.map +1 -0
  119. package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.d.ts +39 -4
  120. package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.d.ts.map +1 -1
  121. package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.js +99 -11
  122. package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.js.map +1 -1
  123. package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.js +1 -1
  124. package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.js.map +1 -1
  125. package/node_modules/@buddi/gateway/dist/web/access/index.d.ts +1 -0
  126. package/node_modules/@buddi/gateway/dist/web/access/index.d.ts.map +1 -1
  127. package/node_modules/@buddi/gateway/dist/web/access/index.js +1 -0
  128. package/node_modules/@buddi/gateway/dist/web/access/index.js.map +1 -1
  129. package/node_modules/@buddi/gateway/dist/web/agent-offers.d.ts +10 -1
  130. package/node_modules/@buddi/gateway/dist/web/agent-offers.d.ts.map +1 -1
  131. package/node_modules/@buddi/gateway/dist/web/agent-offers.js +14 -1
  132. package/node_modules/@buddi/gateway/dist/web/agent-offers.js.map +1 -1
  133. package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts.map +1 -1
  134. package/node_modules/@buddi/gateway/dist/web/api-routes.js +37 -8
  135. package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -1
  136. package/node_modules/@buddi/gateway/dist/web/approval-ask.d.ts +16 -0
  137. package/node_modules/@buddi/gateway/dist/web/approval-ask.d.ts.map +1 -0
  138. package/node_modules/@buddi/gateway/dist/web/approval-ask.js +51 -0
  139. package/node_modules/@buddi/gateway/dist/web/approval-ask.js.map +1 -0
  140. package/node_modules/@buddi/gateway/dist/web/chat.d.ts +6 -0
  141. package/node_modules/@buddi/gateway/dist/web/chat.d.ts.map +1 -1
  142. package/node_modules/@buddi/gateway/dist/web/chat.js +4 -0
  143. package/node_modules/@buddi/gateway/dist/web/chat.js.map +1 -1
  144. package/node_modules/@buddi/gateway/dist/web/live.d.ts +7 -0
  145. package/node_modules/@buddi/gateway/dist/web/live.d.ts.map +1 -1
  146. package/node_modules/@buddi/gateway/dist/web/live.js +12 -0
  147. package/node_modules/@buddi/gateway/dist/web/live.js.map +1 -1
  148. package/node_modules/@buddi/gateway/dist/web/lock-backgrounds.d.ts +9 -0
  149. package/node_modules/@buddi/gateway/dist/web/lock-backgrounds.d.ts.map +1 -0
  150. package/node_modules/@buddi/gateway/dist/web/lock-backgrounds.js +60 -0
  151. package/node_modules/@buddi/gateway/dist/web/lock-backgrounds.js.map +1 -0
  152. package/node_modules/@buddi/gateway/dist/web/lock.d.ts +13 -1
  153. package/node_modules/@buddi/gateway/dist/web/lock.d.ts.map +1 -1
  154. package/node_modules/@buddi/gateway/dist/web/lock.js +84 -23
  155. package/node_modules/@buddi/gateway/dist/web/lock.js.map +1 -1
  156. package/node_modules/@buddi/gateway/dist/web/places.d.ts +5 -0
  157. package/node_modules/@buddi/gateway/dist/web/places.d.ts.map +1 -1
  158. package/node_modules/@buddi/gateway/dist/web/places.js +11 -4
  159. package/node_modules/@buddi/gateway/dist/web/places.js.map +1 -1
  160. package/node_modules/@buddi/gateway/dist/web/server.d.ts +3 -0
  161. package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
  162. package/node_modules/@buddi/gateway/dist/web/server.js +63 -50
  163. package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
  164. package/node_modules/@buddi/install/dist/.tsbuildinfo +1 -1
  165. package/node_modules/@buddi/install/dist/cloudflared.d.ts +121 -0
  166. package/node_modules/@buddi/install/dist/cloudflared.d.ts.map +1 -0
  167. package/node_modules/@buddi/install/dist/cloudflared.js +451 -0
  168. package/node_modules/@buddi/install/dist/cloudflared.js.map +1 -0
  169. package/node_modules/@buddi/install/dist/index.d.ts +1 -0
  170. package/node_modules/@buddi/install/dist/index.d.ts.map +1 -1
  171. package/node_modules/@buddi/install/dist/index.js +1 -0
  172. package/node_modules/@buddi/install/dist/index.js.map +1 -1
  173. package/node_modules/@buddi/install/dist/supervisor.d.ts +6 -1
  174. package/node_modules/@buddi/install/dist/supervisor.d.ts.map +1 -1
  175. package/node_modules/@buddi/install/dist/supervisor.js +51 -5
  176. package/node_modules/@buddi/install/dist/supervisor.js.map +1 -1
  177. package/node_modules/@buddi/runtime/dist/.tsbuildinfo +1 -1
  178. package/node_modules/@buddi/runtime/dist/codex-direct.d.ts +1 -1
  179. package/node_modules/@buddi/runtime/dist/codex-direct.js +1 -1
  180. package/node_modules/@buddi/runtime/dist/grounding.d.ts +54 -0
  181. package/node_modules/@buddi/runtime/dist/grounding.d.ts.map +1 -0
  182. package/node_modules/@buddi/runtime/dist/grounding.js +158 -0
  183. package/node_modules/@buddi/runtime/dist/grounding.js.map +1 -0
  184. package/node_modules/@buddi/runtime/dist/index.d.ts +1 -0
  185. package/node_modules/@buddi/runtime/dist/index.d.ts.map +1 -1
  186. package/node_modules/@buddi/runtime/dist/index.js +1 -0
  187. package/node_modules/@buddi/runtime/dist/index.js.map +1 -1
  188. package/node_modules/@buddi/runtime/dist/loop.d.ts +13 -0
  189. package/node_modules/@buddi/runtime/dist/loop.d.ts.map +1 -1
  190. package/node_modules/@buddi/runtime/dist/loop.js +98 -3
  191. package/node_modules/@buddi/runtime/dist/loop.js.map +1 -1
  192. package/node_modules/@buddi/tool-artifacts/dist/.tsbuildinfo +1 -1
  193. package/node_modules/@buddi/tool-browser/dist/.tsbuildinfo +1 -1
  194. package/node_modules/@buddi/tool-email/dist/.tsbuildinfo +1 -1
  195. package/node_modules/@buddi/tool-email/dist/agent.d.ts +6 -1
  196. package/node_modules/@buddi/tool-email/dist/agent.d.ts.map +1 -1
  197. package/node_modules/@buddi/tool-email/dist/agent.js +6 -1
  198. package/node_modules/@buddi/tool-email/dist/agent.js.map +1 -1
  199. package/node_modules/@buddi/tool-email/dist/html.d.ts +16 -0
  200. package/node_modules/@buddi/tool-email/dist/html.d.ts.map +1 -0
  201. package/node_modules/@buddi/tool-email/dist/html.js +273 -0
  202. package/node_modules/@buddi/tool-email/dist/html.js.map +1 -0
  203. package/node_modules/@buddi/tool-email/dist/imap/fake.d.ts +8 -0
  204. package/node_modules/@buddi/tool-email/dist/imap/fake.d.ts.map +1 -1
  205. package/node_modules/@buddi/tool-email/dist/imap/fake.js +15 -0
  206. package/node_modules/@buddi/tool-email/dist/imap/fake.js.map +1 -1
  207. package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.d.ts +7 -0
  208. package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.d.ts.map +1 -1
  209. package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.js +79 -17
  210. package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.js.map +1 -1
  211. package/node_modules/@buddi/tool-email/dist/index.d.ts +5 -1
  212. package/node_modules/@buddi/tool-email/dist/index.d.ts.map +1 -1
  213. package/node_modules/@buddi/tool-email/dist/index.js +11 -3
  214. package/node_modules/@buddi/tool-email/dist/index.js.map +1 -1
  215. package/node_modules/@buddi/tool-email/dist/mail.d.ts.map +1 -1
  216. package/node_modules/@buddi/tool-email/dist/mail.js +7 -0
  217. package/node_modules/@buddi/tool-email/dist/mail.js.map +1 -1
  218. package/node_modules/@buddi/tool-email/dist/pages/descriptors.d.ts.map +1 -1
  219. package/node_modules/@buddi/tool-email/dist/pages/descriptors.js +208 -176
  220. package/node_modules/@buddi/tool-email/dist/pages/descriptors.js.map +1 -1
  221. package/node_modules/@buddi/tool-email/dist/pages/index.d.ts +3 -1
  222. package/node_modules/@buddi/tool-email/dist/pages/index.d.ts.map +1 -1
  223. package/node_modules/@buddi/tool-email/dist/pages/index.js +5 -2
  224. package/node_modules/@buddi/tool-email/dist/pages/index.js.map +1 -1
  225. package/node_modules/@buddi/tool-email/dist/pages/queries.d.ts +17 -3
  226. package/node_modules/@buddi/tool-email/dist/pages/queries.d.ts.map +1 -1
  227. package/node_modules/@buddi/tool-email/dist/pages/queries.js +283 -62
  228. package/node_modules/@buddi/tool-email/dist/pages/queries.js.map +1 -1
  229. package/node_modules/@buddi/tool-email/dist/pages/thread-tools.d.ts +25 -0
  230. package/node_modules/@buddi/tool-email/dist/pages/thread-tools.d.ts.map +1 -0
  231. package/node_modules/@buddi/tool-email/dist/pages/thread-tools.js +33 -0
  232. package/node_modules/@buddi/tool-email/dist/pages/thread-tools.js.map +1 -0
  233. package/node_modules/@buddi/tool-email/dist/ports.d.ts +25 -0
  234. package/node_modules/@buddi/tool-email/dist/ports.d.ts.map +1 -1
  235. package/node_modules/@buddi/tool-email/dist/ports.js.map +1 -1
  236. package/node_modules/@buddi/tool-email/dist/retention.d.ts.map +1 -1
  237. package/node_modules/@buddi/tool-email/dist/retention.js +1 -0
  238. package/node_modules/@buddi/tool-email/dist/retention.js.map +1 -1
  239. package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.d.ts +9 -1
  240. package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.d.ts.map +1 -1
  241. package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.js +5 -2
  242. package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.js.map +1 -1
  243. package/node_modules/@buddi/tool-email/dist/text-cleanup.d.ts +69 -0
  244. package/node_modules/@buddi/tool-email/dist/text-cleanup.d.ts.map +1 -0
  245. package/node_modules/@buddi/tool-email/dist/text-cleanup.js +96 -0
  246. package/node_modules/@buddi/tool-email/dist/text-cleanup.js.map +1 -0
  247. package/node_modules/@buddi/tool-email/dist/text.d.ts +29 -0
  248. package/node_modules/@buddi/tool-email/dist/text.d.ts.map +1 -0
  249. package/node_modules/@buddi/tool-email/dist/text.js +153 -0
  250. package/node_modules/@buddi/tool-email/dist/text.js.map +1 -0
  251. package/node_modules/@buddi/tool-email/dist/worker.d.ts +64 -0
  252. package/node_modules/@buddi/tool-email/dist/worker.d.ts.map +1 -0
  253. package/node_modules/@buddi/tool-email/dist/worker.js +123 -0
  254. package/node_modules/@buddi/tool-email/dist/worker.js.map +1 -0
  255. package/node_modules/@buddi/tool-email/migrations/028_reading.sql +23 -0
  256. package/node_modules/@buddi/tool-email/package.json +1 -0
  257. package/node_modules/@buddi/tool-host/dist/.tsbuildinfo +1 -1
  258. package/node_modules/@buddi/tool-mcp/dist/.tsbuildinfo +1 -1
  259. package/node_modules/@buddi/tool-memory/dist/.tsbuildinfo +1 -1
  260. package/node_modules/@buddi/tool-web/dist/.tsbuildinfo +1 -1
  261. package/node_modules/entities/LICENSE +11 -0
  262. package/node_modules/entities/decode.d.ts +1 -0
  263. package/node_modules/entities/decode.js +3 -0
  264. package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts +19 -0
  265. package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts.map +1 -0
  266. package/node_modules/entities/dist/commonjs/decode-codepoint.js +77 -0
  267. package/node_modules/entities/dist/commonjs/decode-codepoint.js.map +1 -0
  268. package/node_modules/entities/dist/commonjs/decode.d.ts +209 -0
  269. package/node_modules/entities/dist/commonjs/decode.d.ts.map +1 -0
  270. package/node_modules/entities/dist/commonjs/decode.js +511 -0
  271. package/node_modules/entities/dist/commonjs/decode.js.map +1 -0
  272. package/node_modules/entities/dist/commonjs/encode.d.ts +22 -0
  273. package/node_modules/entities/dist/commonjs/encode.d.ts.map +1 -0
  274. package/node_modules/entities/dist/commonjs/encode.js +73 -0
  275. package/node_modules/entities/dist/commonjs/encode.js.map +1 -0
  276. package/node_modules/entities/dist/commonjs/escape.d.ts +43 -0
  277. package/node_modules/entities/dist/commonjs/escape.d.ts.map +1 -0
  278. package/node_modules/entities/dist/commonjs/escape.js +121 -0
  279. package/node_modules/entities/dist/commonjs/escape.js.map +1 -0
  280. package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts +2 -0
  281. package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts.map +1 -0
  282. package/node_modules/entities/dist/commonjs/generated/decode-data-html.js +10 -0
  283. package/node_modules/entities/dist/commonjs/generated/decode-data-html.js.map +1 -0
  284. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts +2 -0
  285. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts.map +1 -0
  286. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js +10 -0
  287. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js.map +1 -0
  288. package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts +8 -0
  289. package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts.map +1 -0
  290. package/node_modules/entities/dist/commonjs/generated/encode-html.js +13 -0
  291. package/node_modules/entities/dist/commonjs/generated/encode-html.js.map +1 -0
  292. package/node_modules/entities/dist/commonjs/index.d.ts +96 -0
  293. package/node_modules/entities/dist/commonjs/index.d.ts.map +1 -0
  294. package/node_modules/entities/dist/commonjs/index.js +131 -0
  295. package/node_modules/entities/dist/commonjs/index.js.map +1 -0
  296. package/node_modules/entities/dist/commonjs/package.json +3 -0
  297. package/node_modules/entities/dist/esm/decode-codepoint.d.ts +19 -0
  298. package/node_modules/entities/dist/esm/decode-codepoint.d.ts.map +1 -0
  299. package/node_modules/entities/dist/esm/decode-codepoint.js +72 -0
  300. package/node_modules/entities/dist/esm/decode-codepoint.js.map +1 -0
  301. package/node_modules/entities/dist/esm/decode.d.ts +209 -0
  302. package/node_modules/entities/dist/esm/decode.d.ts.map +1 -0
  303. package/node_modules/entities/dist/esm/decode.js +497 -0
  304. package/node_modules/entities/dist/esm/decode.js.map +1 -0
  305. package/node_modules/entities/dist/esm/encode.d.ts +22 -0
  306. package/node_modules/entities/dist/esm/encode.d.ts.map +1 -0
  307. package/node_modules/entities/dist/esm/encode.js +69 -0
  308. package/node_modules/entities/dist/esm/encode.js.map +1 -0
  309. package/node_modules/entities/dist/esm/escape.d.ts +43 -0
  310. package/node_modules/entities/dist/esm/escape.d.ts.map +1 -0
  311. package/node_modules/entities/dist/esm/escape.js +117 -0
  312. package/node_modules/entities/dist/esm/escape.js.map +1 -0
  313. package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts +2 -0
  314. package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts.map +1 -0
  315. package/node_modules/entities/dist/esm/generated/decode-data-html.js +7 -0
  316. package/node_modules/entities/dist/esm/generated/decode-data-html.js.map +1 -0
  317. package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts +2 -0
  318. package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts.map +1 -0
  319. package/node_modules/entities/dist/esm/generated/decode-data-xml.js +7 -0
  320. package/node_modules/entities/dist/esm/generated/decode-data-xml.js.map +1 -0
  321. package/node_modules/entities/dist/esm/generated/encode-html.d.ts +8 -0
  322. package/node_modules/entities/dist/esm/generated/encode-html.d.ts.map +1 -0
  323. package/node_modules/entities/dist/esm/generated/encode-html.js +10 -0
  324. package/node_modules/entities/dist/esm/generated/encode-html.js.map +1 -0
  325. package/node_modules/entities/dist/esm/index.d.ts +96 -0
  326. package/node_modules/entities/dist/esm/index.d.ts.map +1 -0
  327. package/node_modules/entities/dist/esm/index.js +107 -0
  328. package/node_modules/entities/dist/esm/index.js.map +1 -0
  329. package/node_modules/entities/dist/esm/package.json +3 -0
  330. package/node_modules/entities/escape.d.ts +1 -0
  331. package/node_modules/entities/escape.js +3 -0
  332. package/node_modules/entities/package.json +118 -0
  333. package/node_modules/entities/readme.md +122 -0
  334. package/node_modules/entities/src/decode-codepoint.ts +81 -0
  335. package/node_modules/entities/src/decode.spec.ts +320 -0
  336. package/node_modules/entities/src/decode.ts +620 -0
  337. package/node_modules/entities/src/encode.spec.ts +78 -0
  338. package/node_modules/entities/src/encode.ts +77 -0
  339. package/node_modules/entities/src/escape.spec.ts +14 -0
  340. package/node_modules/entities/src/escape.ts +148 -0
  341. package/node_modules/entities/src/generated/.eslintrc.json +10 -0
  342. package/node_modules/entities/src/generated/decode-data-html.ts +8 -0
  343. package/node_modules/entities/src/generated/decode-data-xml.ts +8 -0
  344. package/node_modules/entities/src/generated/encode-html.ts +17 -0
  345. package/node_modules/entities/src/index.spec.ts +125 -0
  346. package/node_modules/entities/src/index.ts +188 -0
  347. package/node_modules/marked/bin/main.js +1 -1
  348. package/node_modules/marked/lib/marked.d.ts +7 -0
  349. package/node_modules/marked/lib/marked.esm.js +14 -14
  350. package/node_modules/marked/lib/marked.esm.js.map +3 -3
  351. package/node_modules/marked/lib/marked.umd.js +19 -19
  352. package/node_modules/marked/lib/marked.umd.js.map +3 -3
  353. package/node_modules/marked/man/marked.1 +1 -1
  354. package/node_modules/marked/package.json +1 -1
  355. package/node_modules/parse5/LICENSE +19 -0
  356. package/node_modules/parse5/README.md +38 -0
  357. package/node_modules/parse5/dist/cjs/common/doctype.d.ts +4 -0
  358. package/node_modules/parse5/dist/cjs/common/doctype.js +118 -0
  359. package/node_modules/parse5/dist/cjs/common/error-codes.d.ts +67 -0
  360. package/node_modules/parse5/dist/cjs/common/error-codes.js +66 -0
  361. package/node_modules/parse5/dist/cjs/common/foreign-content.d.ts +9 -0
  362. package/node_modules/parse5/dist/cjs/common/foreign-content.js +237 -0
  363. package/node_modules/parse5/dist/cjs/common/html.d.ts +289 -0
  364. package/node_modules/parse5/dist/cjs/common/html.js +528 -0
  365. package/node_modules/parse5/dist/cjs/common/token.d.ts +84 -0
  366. package/node_modules/parse5/dist/cjs/common/token.js +24 -0
  367. package/node_modules/parse5/dist/cjs/common/unicode.d.ts +42 -0
  368. package/node_modules/parse5/dist/cjs/common/unicode.js +70 -0
  369. package/node_modules/parse5/dist/cjs/index.d.ts +71 -0
  370. package/node_modules/parse5/dist/cjs/index.js +54 -0
  371. package/node_modules/parse5/dist/cjs/package.json +1 -0
  372. package/node_modules/parse5/dist/cjs/parser/formatting-element-list.d.ts +36 -0
  373. package/node_modules/parse5/dist/cjs/parser/formatting-element-list.js +114 -0
  374. package/node_modules/parse5/dist/cjs/parser/index.d.ts +221 -0
  375. package/node_modules/parse5/dist/cjs/parser/index.js +3240 -0
  376. package/node_modules/parse5/dist/cjs/parser/open-element-stack.d.ts +53 -0
  377. package/node_modules/parse5/dist/cjs/parser/open-element-stack.js +328 -0
  378. package/node_modules/parse5/dist/cjs/serializer/index.d.ts +60 -0
  379. package/node_modules/parse5/dist/cjs/serializer/index.js +172 -0
  380. package/node_modules/parse5/dist/cjs/tokenizer/index.d.ts +247 -0
  381. package/node_modules/parse5/dist/cjs/tokenizer/index.js +2714 -0
  382. package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.d.ts +36 -0
  383. package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.js +200 -0
  384. package/node_modules/parse5/dist/cjs/tree-adapters/default.d.ts +84 -0
  385. package/node_modules/parse5/dist/cjs/tree-adapters/default.js +176 -0
  386. package/node_modules/parse5/dist/cjs/tree-adapters/interface.d.ts +255 -0
  387. package/node_modules/parse5/dist/cjs/tree-adapters/interface.js +2 -0
  388. package/node_modules/parse5/dist/common/doctype.d.ts +4 -0
  389. package/node_modules/parse5/dist/common/doctype.js +114 -0
  390. package/node_modules/parse5/dist/common/error-codes.d.ts +67 -0
  391. package/node_modules/parse5/dist/common/error-codes.js +63 -0
  392. package/node_modules/parse5/dist/common/foreign-content.d.ts +9 -0
  393. package/node_modules/parse5/dist/common/foreign-content.js +228 -0
  394. package/node_modules/parse5/dist/common/html.d.ts +289 -0
  395. package/node_modules/parse5/dist/common/html.js +523 -0
  396. package/node_modules/parse5/dist/common/token.d.ts +84 -0
  397. package/node_modules/parse5/dist/common/token.js +20 -0
  398. package/node_modules/parse5/dist/common/unicode.d.ts +42 -0
  399. package/node_modules/parse5/dist/common/unicode.js +62 -0
  400. package/node_modules/parse5/dist/index.d.ts +71 -0
  401. package/node_modules/parse5/dist/index.js +42 -0
  402. package/node_modules/parse5/dist/parser/formatting-element-list.d.ts +36 -0
  403. package/node_modules/parse5/dist/parser/formatting-element-list.js +110 -0
  404. package/node_modules/parse5/dist/parser/index.d.ts +221 -0
  405. package/node_modules/parse5/dist/parser/index.js +3245 -0
  406. package/node_modules/parse5/dist/parser/open-element-stack.d.ts +53 -0
  407. package/node_modules/parse5/dist/parser/open-element-stack.js +324 -0
  408. package/node_modules/parse5/dist/serializer/index.d.ts +60 -0
  409. package/node_modules/parse5/dist/serializer/index.js +168 -0
  410. package/node_modules/parse5/dist/tokenizer/index.d.ts +247 -0
  411. package/node_modules/parse5/dist/tokenizer/index.js +2710 -0
  412. package/node_modules/parse5/dist/tokenizer/preprocessor.d.ts +36 -0
  413. package/node_modules/parse5/dist/tokenizer/preprocessor.js +196 -0
  414. package/node_modules/parse5/dist/tree-adapters/default.d.ts +84 -0
  415. package/node_modules/parse5/dist/tree-adapters/default.js +173 -0
  416. package/node_modules/parse5/dist/tree-adapters/interface.d.ts +255 -0
  417. package/node_modules/parse5/dist/tree-adapters/interface.js +1 -0
  418. package/node_modules/parse5/package.json +50 -0
  419. package/package.json +2 -2
  420. package/packages/cli/dist/.tsbuildinfo +1 -1
  421. package/packages/cli/dist/access-cmd.d.ts +2 -1
  422. package/packages/cli/dist/access-cmd.d.ts.map +1 -1
  423. package/packages/cli/dist/access-cmd.js +40 -7
  424. package/packages/cli/dist/access-cmd.js.map +1 -1
  425. package/packages/cli/dist/args.d.ts +2 -1
  426. package/packages/cli/dist/args.d.ts.map +1 -1
  427. package/packages/cli/dist/args.js +7 -3
  428. package/packages/cli/dist/args.js.map +1 -1
  429. package/packages/cli/dist/commands.d.ts.map +1 -1
  430. package/packages/cli/dist/commands.js +3 -2
  431. package/packages/cli/dist/commands.js.map +1 -1
  432. package/packages/cli/dist/main.js +1 -1
  433. package/packages/cli/dist/main.js.map +1 -1
  434. package/packages/cli/dist/mcp/server.js +1 -1
  435. package/packages/cli/dist/mcp/server.js.map +1 -1
  436. package/packages/cli/dist/mcp/tools.d.ts.map +1 -1
  437. package/packages/cli/dist/mcp/tools.js +60 -0
  438. package/packages/cli/dist/mcp/tools.js.map +1 -1
  439. package/packages/core/dist/.tsbuildinfo +1 -1
  440. package/packages/core/dist/lock.d.ts +15 -1
  441. package/packages/core/dist/lock.d.ts.map +1 -1
  442. package/packages/core/dist/lock.js +15 -1
  443. package/packages/core/dist/lock.js.map +1 -1
  444. package/packages/core/dist/pages.d.ts +75 -0
  445. package/packages/core/dist/pages.d.ts.map +1 -1
  446. package/packages/core/dist/pages.js +14 -0
  447. package/packages/core/dist/pages.js.map +1 -1
  448. package/packages/core/dist/plugin/index.d.ts +2 -2
  449. package/packages/core/dist/plugin/index.d.ts.map +1 -1
  450. package/packages/core/dist/plugin/index.js.map +1 -1
  451. package/packages/core/dist/plugin/version.d.ts +1 -1
  452. package/packages/core/dist/plugin/version.js +1 -1
  453. package/packages/core/dist/provider-accounts.d.ts +32 -0
  454. package/packages/core/dist/provider-accounts.d.ts.map +1 -1
  455. package/packages/core/dist/provider-accounts.js +22 -0
  456. package/packages/core/dist/provider-accounts.js.map +1 -1
  457. package/packages/core/dist/tools.d.ts +6 -1
  458. package/packages/core/dist/tools.d.ts.map +1 -1
  459. package/packages/core/dist/tools.js.map +1 -1
  460. package/packages/core/migrations/077_lock_background_portrait.sql +5 -0
  461. package/packages/gateway/dist/.tsbuildinfo +1 -1
  462. package/packages/gateway/dist/agents/agent-intro.d.ts +31 -0
  463. package/packages/gateway/dist/agents/agent-intro.d.ts.map +1 -0
  464. package/packages/gateway/dist/agents/agent-intro.js +116 -0
  465. package/packages/gateway/dist/agents/agent-intro.js.map +1 -0
  466. package/packages/gateway/dist/agents/delegation.d.ts +10 -0
  467. package/packages/gateway/dist/agents/delegation.d.ts.map +1 -1
  468. package/packages/gateway/dist/agents/delegation.js +18 -1
  469. package/packages/gateway/dist/agents/delegation.js.map +1 -1
  470. package/packages/gateway/dist/agents/owner-tools.d.ts +21 -8
  471. package/packages/gateway/dist/agents/owner-tools.d.ts.map +1 -1
  472. package/packages/gateway/dist/agents/owner-tools.js +201 -36
  473. package/packages/gateway/dist/agents/owner-tools.js.map +1 -1
  474. package/packages/gateway/dist/agents/platform.d.ts +14 -1
  475. package/packages/gateway/dist/agents/platform.d.ts.map +1 -1
  476. package/packages/gateway/dist/agents/platform.js +44 -11
  477. package/packages/gateway/dist/agents/platform.js.map +1 -1
  478. package/packages/gateway/dist/bootstrap.d.ts.map +1 -1
  479. package/packages/gateway/dist/bootstrap.js +2 -0
  480. package/packages/gateway/dist/bootstrap.js.map +1 -1
  481. package/packages/gateway/dist/edition-origin.d.ts +57 -0
  482. package/packages/gateway/dist/edition-origin.d.ts.map +1 -0
  483. package/packages/gateway/dist/edition-origin.js +156 -0
  484. package/packages/gateway/dist/edition-origin.js.map +1 -0
  485. package/packages/gateway/dist/evals/golden.d.ts +5 -0
  486. package/packages/gateway/dist/evals/golden.d.ts.map +1 -1
  487. package/packages/gateway/dist/evals/golden.js +48 -0
  488. package/packages/gateway/dist/evals/golden.js.map +1 -1
  489. package/packages/gateway/dist/mcp/requests.d.ts +8 -2
  490. package/packages/gateway/dist/mcp/requests.d.ts.map +1 -1
  491. package/packages/gateway/dist/mcp/requests.js +74 -1
  492. package/packages/gateway/dist/mcp/requests.js.map +1 -1
  493. package/packages/gateway/dist/owner-profile-edit.d.ts +160 -0
  494. package/packages/gateway/dist/owner-profile-edit.d.ts.map +1 -0
  495. package/packages/gateway/dist/owner-profile-edit.js +296 -0
  496. package/packages/gateway/dist/owner-profile-edit.js.map +1 -0
  497. package/packages/gateway/dist/provider-accounts.d.ts.map +1 -1
  498. package/packages/gateway/dist/provider-accounts.js +2 -1
  499. package/packages/gateway/dist/provider-accounts.js.map +1 -1
  500. package/packages/gateway/dist/system-context.d.ts +9 -0
  501. package/packages/gateway/dist/system-context.d.ts.map +1 -1
  502. package/packages/gateway/dist/system-context.js +28 -2
  503. package/packages/gateway/dist/system-context.js.map +1 -1
  504. package/packages/gateway/dist/telegram/approvals.d.ts +6 -0
  505. package/packages/gateway/dist/telegram/approvals.d.ts.map +1 -1
  506. package/packages/gateway/dist/telegram/approvals.js +10 -2
  507. package/packages/gateway/dist/telegram/approvals.js.map +1 -1
  508. package/packages/gateway/dist/telegram/main.d.ts.map +1 -1
  509. package/packages/gateway/dist/telegram/main.js +10 -3
  510. package/packages/gateway/dist/telegram/main.js.map +1 -1
  511. package/packages/gateway/dist/telegram/outbound.d.ts +9 -0
  512. package/packages/gateway/dist/telegram/outbound.d.ts.map +1 -1
  513. package/packages/gateway/dist/telegram/outbound.js +43 -0
  514. package/packages/gateway/dist/telegram/outbound.js.map +1 -1
  515. package/packages/gateway/dist/telegram/surface.d.ts +2 -0
  516. package/packages/gateway/dist/telegram/surface.d.ts.map +1 -1
  517. package/packages/gateway/dist/telegram/surface.js +2 -1
  518. package/packages/gateway/dist/telegram/surface.js.map +1 -1
  519. package/packages/gateway/dist/tips/engine.d.ts +32 -0
  520. package/packages/gateway/dist/tips/engine.d.ts.map +1 -1
  521. package/packages/gateway/dist/tips/engine.js +69 -0
  522. package/packages/gateway/dist/tips/engine.js.map +1 -1
  523. package/packages/gateway/dist/tips/route.d.ts +1 -3
  524. package/packages/gateway/dist/tips/route.d.ts.map +1 -1
  525. package/packages/gateway/dist/tips/route.js +54 -30
  526. package/packages/gateway/dist/tips/route.js.map +1 -1
  527. package/packages/gateway/dist/web/access/cloudflare-connector.d.ts +63 -0
  528. package/packages/gateway/dist/web/access/cloudflare-connector.d.ts.map +1 -0
  529. package/packages/gateway/dist/web/access/cloudflare-connector.js +87 -0
  530. package/packages/gateway/dist/web/access/cloudflare-connector.js.map +1 -0
  531. package/packages/gateway/dist/web/access/cloudflare-setup.d.ts +39 -4
  532. package/packages/gateway/dist/web/access/cloudflare-setup.d.ts.map +1 -1
  533. package/packages/gateway/dist/web/access/cloudflare-setup.js +99 -11
  534. package/packages/gateway/dist/web/access/cloudflare-setup.js.map +1 -1
  535. package/packages/gateway/dist/web/access/cloudflare-token.js +1 -1
  536. package/packages/gateway/dist/web/access/cloudflare-token.js.map +1 -1
  537. package/packages/gateway/dist/web/access/index.d.ts +1 -0
  538. package/packages/gateway/dist/web/access/index.d.ts.map +1 -1
  539. package/packages/gateway/dist/web/access/index.js +1 -0
  540. package/packages/gateway/dist/web/access/index.js.map +1 -1
  541. package/packages/gateway/dist/web/agent-offers.d.ts +10 -1
  542. package/packages/gateway/dist/web/agent-offers.d.ts.map +1 -1
  543. package/packages/gateway/dist/web/agent-offers.js +14 -1
  544. package/packages/gateway/dist/web/agent-offers.js.map +1 -1
  545. package/packages/gateway/dist/web/api-routes.d.ts.map +1 -1
  546. package/packages/gateway/dist/web/api-routes.js +37 -8
  547. package/packages/gateway/dist/web/api-routes.js.map +1 -1
  548. package/packages/gateway/dist/web/approval-ask.d.ts +16 -0
  549. package/packages/gateway/dist/web/approval-ask.d.ts.map +1 -0
  550. package/packages/gateway/dist/web/approval-ask.js +51 -0
  551. package/packages/gateway/dist/web/approval-ask.js.map +1 -0
  552. package/packages/gateway/dist/web/chat.d.ts +6 -0
  553. package/packages/gateway/dist/web/chat.d.ts.map +1 -1
  554. package/packages/gateway/dist/web/chat.js +4 -0
  555. package/packages/gateway/dist/web/chat.js.map +1 -1
  556. package/packages/gateway/dist/web/live.d.ts +7 -0
  557. package/packages/gateway/dist/web/live.d.ts.map +1 -1
  558. package/packages/gateway/dist/web/live.js +12 -0
  559. package/packages/gateway/dist/web/live.js.map +1 -1
  560. package/packages/gateway/dist/web/lock-backgrounds.d.ts +9 -0
  561. package/packages/gateway/dist/web/lock-backgrounds.d.ts.map +1 -0
  562. package/packages/gateway/dist/web/lock-backgrounds.js +60 -0
  563. package/packages/gateway/dist/web/lock-backgrounds.js.map +1 -0
  564. package/packages/gateway/dist/web/lock.d.ts +13 -1
  565. package/packages/gateway/dist/web/lock.d.ts.map +1 -1
  566. package/packages/gateway/dist/web/lock.js +84 -23
  567. package/packages/gateway/dist/web/lock.js.map +1 -1
  568. package/packages/gateway/dist/web/places.d.ts +5 -0
  569. package/packages/gateway/dist/web/places.d.ts.map +1 -1
  570. package/packages/gateway/dist/web/places.js +11 -4
  571. package/packages/gateway/dist/web/places.js.map +1 -1
  572. package/packages/gateway/dist/web/server.d.ts +3 -0
  573. package/packages/gateway/dist/web/server.d.ts.map +1 -1
  574. package/packages/gateway/dist/web/server.js +63 -50
  575. package/packages/gateway/dist/web/server.js.map +1 -1
  576. package/packages/install/dist/.tsbuildinfo +1 -1
  577. package/packages/install/dist/cloudflared.d.ts +121 -0
  578. package/packages/install/dist/cloudflared.d.ts.map +1 -0
  579. package/packages/install/dist/cloudflared.js +451 -0
  580. package/packages/install/dist/cloudflared.js.map +1 -0
  581. package/packages/install/dist/index.d.ts +1 -0
  582. package/packages/install/dist/index.d.ts.map +1 -1
  583. package/packages/install/dist/index.js +1 -0
  584. package/packages/install/dist/index.js.map +1 -1
  585. package/packages/install/dist/supervisor.d.ts +6 -1
  586. package/packages/install/dist/supervisor.d.ts.map +1 -1
  587. package/packages/install/dist/supervisor.js +51 -5
  588. package/packages/install/dist/supervisor.js.map +1 -1
  589. package/packages/runtime/dist/.tsbuildinfo +1 -1
  590. package/packages/runtime/dist/codex-direct.d.ts +1 -1
  591. package/packages/runtime/dist/codex-direct.js +1 -1
  592. package/packages/runtime/dist/grounding.d.ts +54 -0
  593. package/packages/runtime/dist/grounding.d.ts.map +1 -0
  594. package/packages/runtime/dist/grounding.js +158 -0
  595. package/packages/runtime/dist/grounding.js.map +1 -0
  596. package/packages/runtime/dist/index.d.ts +1 -0
  597. package/packages/runtime/dist/index.d.ts.map +1 -1
  598. package/packages/runtime/dist/index.js +1 -0
  599. package/packages/runtime/dist/index.js.map +1 -1
  600. package/packages/runtime/dist/loop.d.ts +13 -0
  601. package/packages/runtime/dist/loop.d.ts.map +1 -1
  602. package/packages/runtime/dist/loop.js +98 -3
  603. package/packages/runtime/dist/loop.js.map +1 -1
  604. package/packages/tools/artifacts/dist/.tsbuildinfo +1 -1
  605. package/packages/tools/browser/dist/.tsbuildinfo +1 -1
  606. package/packages/tools/email/dist/.tsbuildinfo +1 -1
  607. package/packages/tools/email/dist/agent.d.ts +6 -1
  608. package/packages/tools/email/dist/agent.d.ts.map +1 -1
  609. package/packages/tools/email/dist/agent.js +6 -1
  610. package/packages/tools/email/dist/agent.js.map +1 -1
  611. package/packages/tools/email/dist/html.d.ts +16 -0
  612. package/packages/tools/email/dist/html.d.ts.map +1 -0
  613. package/packages/tools/email/dist/html.js +273 -0
  614. package/packages/tools/email/dist/html.js.map +1 -0
  615. package/packages/tools/email/dist/imap/fake.d.ts +8 -0
  616. package/packages/tools/email/dist/imap/fake.d.ts.map +1 -1
  617. package/packages/tools/email/dist/imap/fake.js +15 -0
  618. package/packages/tools/email/dist/imap/fake.js.map +1 -1
  619. package/packages/tools/email/dist/imap/imapflow-client.d.ts +7 -0
  620. package/packages/tools/email/dist/imap/imapflow-client.d.ts.map +1 -1
  621. package/packages/tools/email/dist/imap/imapflow-client.js +79 -17
  622. package/packages/tools/email/dist/imap/imapflow-client.js.map +1 -1
  623. package/packages/tools/email/dist/index.d.ts +5 -1
  624. package/packages/tools/email/dist/index.d.ts.map +1 -1
  625. package/packages/tools/email/dist/index.js +11 -3
  626. package/packages/tools/email/dist/index.js.map +1 -1
  627. package/packages/tools/email/dist/mail.d.ts.map +1 -1
  628. package/packages/tools/email/dist/mail.js +7 -0
  629. package/packages/tools/email/dist/mail.js.map +1 -1
  630. package/packages/tools/email/dist/pages/descriptors.d.ts.map +1 -1
  631. package/packages/tools/email/dist/pages/descriptors.js +208 -176
  632. package/packages/tools/email/dist/pages/descriptors.js.map +1 -1
  633. package/packages/tools/email/dist/pages/index.d.ts +3 -1
  634. package/packages/tools/email/dist/pages/index.d.ts.map +1 -1
  635. package/packages/tools/email/dist/pages/index.js +5 -2
  636. package/packages/tools/email/dist/pages/index.js.map +1 -1
  637. package/packages/tools/email/dist/pages/queries.d.ts +17 -3
  638. package/packages/tools/email/dist/pages/queries.d.ts.map +1 -1
  639. package/packages/tools/email/dist/pages/queries.js +283 -62
  640. package/packages/tools/email/dist/pages/queries.js.map +1 -1
  641. package/packages/tools/email/dist/pages/thread-tools.d.ts +25 -0
  642. package/packages/tools/email/dist/pages/thread-tools.d.ts.map +1 -0
  643. package/packages/tools/email/dist/pages/thread-tools.js +33 -0
  644. package/packages/tools/email/dist/pages/thread-tools.js.map +1 -0
  645. package/packages/tools/email/dist/ports.d.ts +25 -0
  646. package/packages/tools/email/dist/ports.d.ts.map +1 -1
  647. package/packages/tools/email/dist/ports.js.map +1 -1
  648. package/packages/tools/email/dist/retention.d.ts.map +1 -1
  649. package/packages/tools/email/dist/retention.js +1 -0
  650. package/packages/tools/email/dist/retention.js.map +1 -1
  651. package/packages/tools/email/dist/sources/inbox-poll.d.ts +9 -1
  652. package/packages/tools/email/dist/sources/inbox-poll.d.ts.map +1 -1
  653. package/packages/tools/email/dist/sources/inbox-poll.js +5 -2
  654. package/packages/tools/email/dist/sources/inbox-poll.js.map +1 -1
  655. package/packages/tools/email/dist/text-cleanup.d.ts +69 -0
  656. package/packages/tools/email/dist/text-cleanup.d.ts.map +1 -0
  657. package/packages/tools/email/dist/text-cleanup.js +96 -0
  658. package/packages/tools/email/dist/text-cleanup.js.map +1 -0
  659. package/packages/tools/email/dist/text.d.ts +29 -0
  660. package/packages/tools/email/dist/text.d.ts.map +1 -0
  661. package/packages/tools/email/dist/text.js +153 -0
  662. package/packages/tools/email/dist/text.js.map +1 -0
  663. package/packages/tools/email/dist/worker.d.ts +64 -0
  664. package/packages/tools/email/dist/worker.d.ts.map +1 -0
  665. package/packages/tools/email/dist/worker.js +123 -0
  666. package/packages/tools/email/dist/worker.js.map +1 -0
  667. package/packages/tools/email/migrations/028_reading.sql +23 -0
  668. package/packages/tools/email/package.json +1 -0
  669. package/packages/tools/host/dist/.tsbuildinfo +1 -1
  670. package/packages/tools/mcp/dist/.tsbuildinfo +1 -1
  671. package/packages/tools/memory/dist/.tsbuildinfo +1 -1
  672. package/packages/tools/web/dist/.tsbuildinfo +1 -1
  673. package/packages/web/dist/apple-touch-icon.png +0 -0
  674. package/packages/web/dist/assets/index-CPFSREcP.css +1 -0
  675. package/packages/web/dist/assets/index-DYUn1V0x.js +150 -0
  676. package/packages/web/dist/assets/{lottie_light-CHWAvOde.js → lottie_light-DxWeiVDC.js} +1 -1
  677. package/packages/web/dist/backgrounds/golden-streak-portrait.jpg +0 -0
  678. package/packages/web/dist/backgrounds/golden-streak-thumb.jpg +0 -0
  679. package/packages/web/dist/backgrounds/manifest.json +18 -0
  680. package/packages/web/dist/backgrounds/peoria-autumn-waterfront-thumb.jpg +0 -0
  681. package/packages/web/dist/backgrounds/peoria-autumn-waterfront.jpg +0 -0
  682. package/packages/web/dist/build.json +1 -1
  683. package/packages/web/dist/favicon-16.png +0 -0
  684. package/packages/web/dist/favicon-32.png +0 -0
  685. package/packages/web/dist/favicon.ico +0 -0
  686. package/packages/web/dist/icon-192.png +0 -0
  687. package/packages/web/dist/icon-512.png +0 -0
  688. package/packages/web/dist/index.html +6 -3
  689. package/packages/web/dist/manifest.webmanifest +1 -1
  690. package/packages/web/dist/maskable-512.png +0 -0
  691. package/packages/web/dist/precache.json +7 -5
  692. package/packages/web/dist/assets/index-BB52n8Fa.js +0 -146
  693. package/packages/web/dist/assets/index-CY4cPN4I.css +0 -1
  694. package/packages/web/dist/favicon.png +0 -0
  695. package/packages/web/dist/icon-maskable-512.png +0 -0
@@ -1,6 +1,7 @@
1
1
  import { createAddAccountTool, createRemoveAccountTool, createSetPasswordTool } from './accounts.js';
2
2
  import { createAddRuleTool, createRevokePoliciesTool, } from './policies-tools.js';
3
3
  import { createDiscardDraftTool, createSaveDraftTool } from './drafts-tools.js';
4
+ import { createThreadDoneTool } from './thread-tools.js';
4
5
  import { emailPageDescriptors } from './descriptors.js';
5
6
  import { createUndoChangeTool, createUndoLearnedTool } from '../tools/mailbox.js';
6
7
  import { emailPageQueries } from './queries.js';
@@ -10,6 +11,7 @@ export * from './drafts-tools.js';
10
11
  export * from './format.js';
11
12
  export * from './policies-tools.js';
12
13
  export * from './queries.js';
14
+ export * from './thread-tools.js';
13
15
  /** Everything the two pages write through, and nothing a model may see. */
14
16
  export function emailPageTools(opts) {
15
17
  return [
@@ -20,13 +22,14 @@ export function emailPageTools(opts) {
20
22
  createRevokePoliciesTool(),
21
23
  createSaveDraftTool(),
22
24
  createDiscardDraftTool(),
25
+ createThreadDoneTool(),
23
26
  createUndoChangeTool(opts),
24
27
  createUndoLearnedTool(opts),
25
28
  ];
26
29
  }
27
30
  /** Every read the two pages make. */
28
- export function emailQueries() {
29
- return emailPageQueries();
31
+ export function emailQueries(worker) {
32
+ return emailPageQueries(worker);
30
33
  }
31
34
  /** The two screens: the Mail place, and the Email settings tab. */
32
35
  export function emailPages() {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pages/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,qBAAqB,EAA2B,MAAM,eAAe,CAAC;AAC9H,OAAO,EACL,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAE7B,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAAC,IAAwB;IACrD,OAAO;QACL,oBAAoB,CAAC,IAAI,CAAC;QAC1B,uBAAuB,CAAC,IAAI,CAAC;QAC7B,qBAAqB,CAAC,IAAI,CAAC;QAC3B,iBAAiB,EAAE;QACnB,wBAAwB,EAAE;QAC1B,mBAAmB,EAAE;QACrB,sBAAsB,EAAE;QACxB,oBAAoB,CAAC,IAAI,CAAC;QAC1B,qBAAqB,CAAC,IAAI,CAAC;KACmB,CAAC;AACnD,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,YAAY;IAC1B,OAAO,gBAAgB,EAAE,CAAC;AAC5B,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,UAAU;IACxB,OAAO,oBAAoB,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pages/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,qBAAqB,EAA2B,MAAM,eAAe,CAAC;AAC9H,OAAO,EACL,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAElC,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAAC,IAAwB;IACrD,OAAO;QACL,oBAAoB,CAAC,IAAI,CAAC;QAC1B,uBAAuB,CAAC,IAAI,CAAC;QAC7B,qBAAqB,CAAC,IAAI,CAAC;QAC3B,iBAAiB,EAAE;QACnB,wBAAwB,EAAE;QAC1B,mBAAmB,EAAE;QACrB,sBAAsB,EAAE;QACxB,oBAAoB,EAAE;QACtB,oBAAoB,CAAC,IAAI,CAAC;QAC1B,qBAAqB,CAAC,IAAI,CAAC;KACmB,CAAC;AACnD,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,UAAU;IACxB,OAAO,oBAAoB,CAAC;AAC9B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { type PageQuery, type ToolContext } from '@buddi/core/plugin';
2
2
  import { type AttentionView } from '../needs-you.js';
3
+ import type { HtmlFetcher } from '../worker.js';
3
4
  import { type ActionRecord } from '../mailbox/actions.js';
4
5
  /** How many conversations the list shows before the owner narrows it. */
5
6
  export declare const THREAD_LIST_LIMIT = 30;
@@ -16,6 +17,10 @@ export declare function attachmentRows(messageId: string, raw: unknown): Array<{
16
17
  line: string;
17
18
  artifactId: string | null;
18
19
  held: string;
20
+ name: string;
21
+ size: number;
22
+ mime: string;
23
+ contentId: string | null;
19
24
  }>;
20
25
  /** `1.2 MB`. The same steps the dashboard drew before. */
21
26
  export declare function formatBytes(bytes: number): string;
@@ -32,7 +37,13 @@ export declare function formatBytes(bytes: number): string;
32
37
  export declare const MAX_BODY_BYTES: number;
33
38
  /** The sentence a cut body ends with. Said once, so a test can name it. */
34
39
  export declare const TRUNCATED_NOTE = "\u2026 this message is too long to show in full; the rest is in your mailbox.";
35
- export declare function truncateBody(text: string): string;
40
+ /**
41
+ * How much of the plain text rides along when there is an HTML body too: the
42
+ * text is then only the fallback, and the answer must stay under the
43
+ * engine's megabyte with both in it.
44
+ */
45
+ export declare const TEXT_WITH_HTML_BYTES: number;
46
+ export declare function truncateBody(text: string, max?: number): string;
36
47
  /** What a dispatch that never came back says, with the server's own words. */
37
48
  export declare function unresolvedLine(sendError: string | null): string;
38
49
  /**
@@ -44,12 +55,15 @@ export declare function unresolvedLine(sendError: string | null): string;
44
55
  * search route made, from the same `validateFilters`).
45
56
  */
46
57
  export declare function threadsQuery(): PageQuery;
58
+ export declare function tagLabel(category: string): string;
47
59
  /**
48
60
  * The list's pill for a conversation: the views that are worth a word.
49
61
  * A notification and "they wrote" are the inbox's ordinary weather and say
50
62
  * nothing; the detail's State row still names them.
51
63
  */
52
64
  export declare function listPillOf(view: AttentionView): string;
65
+ /** How many of buddi's changes a reading pane lists for one conversation. */
66
+ export declare const THREAD_CHANGES = 3;
53
67
  /**
54
68
  * One conversation: its messages' snippets, then the drafts under them.
55
69
  *
@@ -67,7 +81,7 @@ export declare function threadQuery(): PageQuery;
67
81
  */
68
82
  export declare function draftQuery(): PageQuery;
69
83
  /** One message's body, on request, with its attachments' listing. */
70
- export declare function messageQuery(): PageQuery;
84
+ export declare function messageQuery(worker?: HtmlFetcher): PageQuery;
71
85
  /** Every mailbox, disabled ones included: a row you cannot see cannot be fixed. */
72
86
  export declare function accountsQuery(): PageQuery;
73
87
  /**
@@ -135,5 +149,5 @@ export declare function autoReasonLine(reason: string | null): string;
135
149
  * Mail page's Learned list: whom, why, when, and Undo while it still decides.
136
150
  */
137
151
  export declare function learnedRulesQuery(): PageQuery;
138
- export declare function emailPageQueries(): PageQuery[];
152
+ export declare function emailPageQueries(worker?: HtmlFetcher): PageQuery[];
139
153
  //# sourceMappingURL=queries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/pages/queries.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/pages/queries.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,10 @@
6
6
  * one difference that is the whole point of the port: a query is handed a pool
7
7
  * that refuses anything but a `select`, so the page's data cannot come from
8
8
  * something that also wrote. Nothing here opens a transaction, calls IMAP or
9
- * touches the vault; every write the pages make is a tool (`tools.ts`).
9
+ * touches the vault; every write the pages make is a tool (`tools.ts`). The
10
+ * one exception is not made here: `message` asks the plugin's worker for an
11
+ * older message's HTML, and the worker fetches and stores it with the poll's
12
+ * own context (`worker.ts`).
10
13
  *
11
14
  * Two smaller rules shape what a query returns:
12
15
  *
@@ -34,6 +37,7 @@ import { loadWatcherSettings, DEFAULT_WATCHER_SETTINGS } from '../watchers.js';
34
37
  import { draftStatusLine, isoOf, policyLine, relative } from './format.js';
35
38
  import { describeUndo, movedSince, plural, recentActions, undoRefusal, verbOf } from '../mailbox/actions.js';
36
39
  import { learnedRules } from '../policies/auto.js';
40
+ import { ACTION_COLUMNS, SEEN, toAction } from '../mailbox/actions.js';
37
41
  /** How many conversations the list shows before the owner narrows it. */
38
42
  export const THREAD_LIST_LIMIT = 30;
39
43
  /** How many messages of a conversation the page draws. The newest ones. */
@@ -80,6 +84,11 @@ export function attachmentRows(messageId, raw) {
80
84
  line: `${filename} — ${detail}`,
81
85
  artifactId: a.artifactId ?? null,
82
86
  held: a.artifactId ? 'in your files' : 'not fetched',
87
+ // The `message` component's own words for the same file (host API 1.30).
88
+ name: filename,
89
+ size: Number.isFinite(size) ? size : 0,
90
+ mime: a.mime ?? 'application/octet-stream',
91
+ contentId: typeof a.contentId === 'string' && a.contentId !== '' ? a.contentId : null,
83
92
  };
84
93
  });
85
94
  }
@@ -109,8 +118,14 @@ export function formatBytes(bytes) {
109
118
  export const MAX_BODY_BYTES = 512 * 1024;
110
119
  /** The sentence a cut body ends with. Said once, so a test can name it. */
111
120
  export const TRUNCATED_NOTE = '… this message is too long to show in full; the rest is in your mailbox.';
112
- export function truncateBody(text) {
113
- if (Buffer.byteLength(text, 'utf8') <= MAX_BODY_BYTES)
121
+ /**
122
+ * How much of the plain text rides along when there is an HTML body too: the
123
+ * text is then only the fallback, and the answer must stay under the
124
+ * engine's megabyte with both in it.
125
+ */
126
+ export const TEXT_WITH_HTML_BYTES = 64 * 1024;
127
+ export function truncateBody(text, max = MAX_BODY_BYTES) {
128
+ if (Buffer.byteLength(text, 'utf8') <= max)
114
129
  return text;
115
130
  /*
116
131
  * Cut on a character boundary: slicing bytes can land in the middle of a
@@ -118,12 +133,12 @@ export function truncateBody(text) {
118
133
  * end of every long message. Decoding the slice leaves that partial
119
134
  * character as U+FFFD, which is exactly what is trimmed off here.
120
135
  */
121
- const bytes = Buffer.from(text, 'utf8').subarray(0, MAX_BODY_BYTES);
136
+ const bytes = Buffer.from(text, 'utf8').subarray(0, max);
122
137
  const whole = new TextDecoder('utf-8').decode(bytes).replace(/\uFFFD+$/, '');
123
138
  return `${whole}\n\n${TRUNCATED_NOTE}`;
124
139
  }
125
140
  /** A draft as the editor and the draft list read it. Never a patch: all of it. */
126
- function draftRow(draft, now) {
141
+ function draftRow(draft, now, fromAddress) {
127
142
  const live = LIVE_DRAFT_STATUSES.includes(draft.status) && draft.sentActionId === null;
128
143
  // Dispatched, never confirmed: the one state where nothing may be done to it
129
144
  // until somebody has looked in the mailbox.
@@ -153,6 +168,17 @@ function draftRow(draft, now) {
153
168
  notLiveLine: `This draft is ${draft.status} and cannot be edited or sent. It is kept so you can read what was proposed.`,
154
169
  unresolvedLine: unresolvedLine(draft.sendError),
155
170
  sendError: draft.sendError,
171
+ /*
172
+ * The reply as the reading pane shows it before anyone edits it: drawn
173
+ * the way a message is (host API 1.30), from the mailbox it will leave.
174
+ */
175
+ preview: {
176
+ from: { name: 'Your reply', address: fromAddress ?? draft.to[0] ?? 'you' },
177
+ to: draft.to.map((address) => ({ address })),
178
+ cc: draft.cc.map((address) => ({ address })),
179
+ at: draft.updatedAt,
180
+ text: draft.bodyText,
181
+ },
156
182
  };
157
183
  }
158
184
  /** What a dispatch that never came back says, with the server's own words. */
@@ -199,6 +225,7 @@ export function threadsQuery() {
199
225
  const { rows } = await ctx.buddi.db.query(`select distinct thread_id from email.drafts
200
226
  where thread_id = any($1::uuid[]) and status = any($2::text[])`, [threads.map((t) => t.id), [...LIVE_DRAFT_STATUSES]]);
201
227
  const withDraft = new Set(rows.map((r) => String(r.thread_id)));
228
+ const reading = await listReading(ctx.buddi.db, threads.map((t) => t.id));
202
229
  /*
203
230
  * Who the conversation is *with*: the first participant who is not one
204
231
  * of the owner's own addresses. The owner is on every thread, so the
@@ -206,34 +233,159 @@ export function threadsQuery() {
206
233
  */
207
234
  const own = new Set(accounts.flatMap((account) => [account.address, ...account.aliases]).map((address) => address.toLowerCase()));
208
235
  return {
209
- threads: threads.map((thread) => ({
210
- id: thread.id,
211
- subject: thread.subject === '' ? '(no subject)' : thread.subject,
212
- sender: thread.participants.find((address) => !own.has(address.toLowerCase())) ??
236
+ threads: threads.map((thread) => {
237
+ const sender = thread.participants.find((address) => !own.has(address.toLowerCase())) ??
213
238
  thread.participants[0] ??
214
- '(nobody)',
215
- participants: thread.participants.join(', '),
216
- state: thread.state,
217
- /*
218
- * The state as the owner reads it (`needs-you.ts`): "Waiting on you"
219
- * only when the one rule says so. A notification and a message
220
- * nobody expects an answer to carry no pill at all — a word on every
221
- * row is how forty "Waiting on you" pills came to mean nothing.
222
- */
223
- attention: viewOf(reasons.get(thread.id) ?? reasonOf(null, thread.state)),
224
- pill: listPillOf(viewOf(reasons.get(thread.id) ?? reasonOf(null, thread.state))),
225
- // The "draft" pill sits *beside* the state, never in place of it: a
226
- // conversation that is waiting on the owner and has a reply written
227
- // for it is two facts, and the old page showed both.
228
- draftPill: withDraft.has(thread.id) ? 'draft' : '',
229
- when: relative(thread.lastAt, now),
230
- messageCount: thread.messageCount,
231
- })),
239
+ '(nobody)';
240
+ const read = reading.get(thread.id);
241
+ return {
242
+ id: thread.id,
243
+ subject: thread.subject === '' ? '(no subject)' : thread.subject,
244
+ sender,
245
+ /*
246
+ * The person, not the address: the display name on their latest
247
+ * message when they gave one (host API 1.30's reading pane), the
248
+ * address otherwise.
249
+ */
250
+ senderName: read?.senderName && read.senderAddress?.toLowerCase() === sender.toLowerCase() ? read.senderName : sender,
251
+ // What the conversation last said, on one line; the owner's own words say so.
252
+ preview: read ? (read.lastOut ? `You: ${read.snippet}` : read.snippet) : '',
253
+ unread: read?.unread ?? false,
254
+ // Mail Triage's word for the latest message, as a chip: "Bill", "Receipt".
255
+ tag: read?.category && read.category !== 'other' ? tagLabel(read.category) : '',
256
+ participants: thread.participants.join(', '),
257
+ state: thread.state,
258
+ /*
259
+ * The state as the owner reads it (`needs-you.ts`): "Waiting on you"
260
+ * only when the one rule says so. A notification and a message
261
+ * nobody expects an answer to carry no pill at all — a word on every
262
+ * row is how forty "Waiting on you" pills came to mean nothing.
263
+ */
264
+ attention: viewOf(reasons.get(thread.id) ?? reasonOf(null, thread.state)),
265
+ pill: listPillOf(viewOf(reasons.get(thread.id) ?? reasonOf(null, thread.state))),
266
+ // The "draft" pill sits *beside* the state, never in place of it: a
267
+ // conversation that is waiting on the owner and has a reply written
268
+ // for it is two facts, and the old page showed both.
269
+ draftPill: withDraft.has(thread.id) ? 'draft' : '',
270
+ when: relative(thread.lastAt, now),
271
+ messageCount: thread.messageCount,
272
+ };
273
+ }),
232
274
  ...hits,
233
275
  };
234
276
  },
235
277
  };
236
278
  }
279
+ /** Triage's categories as a chip says them. Anything else reads as itself, capitalised. */
280
+ const TAG_WORDS = {
281
+ 'reply-needed': 'Reply needed',
282
+ 'payment-failed': 'Payment failed',
283
+ 'bank-notice': 'Bank',
284
+ 'service-notice': 'Service',
285
+ promo: 'Promotion',
286
+ };
287
+ export function tagLabel(category) {
288
+ const known = TAG_WORDS[category];
289
+ if (known)
290
+ return known;
291
+ const words = category.replace(/-/g, ' ').trim();
292
+ return words === '' ? '' : words[0].toUpperCase() + words.slice(1);
293
+ }
294
+ /**
295
+ * What the list draws beside each conversation, in one read: how its last
296
+ * message opens, the name on the latest message they sent, whether anything
297
+ * they sent is still unread on the server (no `\Seen`, as the flag sync last
298
+ * saw it), and Mail Triage's latest category.
299
+ */
300
+ async function listReading(db, ids) {
301
+ const out = new Map();
302
+ if (ids.length === 0)
303
+ return out;
304
+ const { rows } = await db.query(`select t.id,
305
+ lm.snippet, lm.direction as last_direction,
306
+ li.from_name, li.from_addr,
307
+ exists (select 1 from email.messages u
308
+ where u.thread_id = t.id and u.direction = 'in'
309
+ and not (coalesce(u.flags, '[]'::jsonb) ? $2)) as unread,
310
+ (select tr.category from email.triage tr
311
+ where tr.message_id = li.id
312
+ order by tr.decided_at desc, tr.processing_version desc limit 1) as category
313
+ from email.threads t
314
+ left join email.messages lm on lm.id = t.last_message_id
315
+ left join lateral (
316
+ select m.id, m.from_name, m.from_addr from email.messages m
317
+ where m.thread_id = t.id and m.direction = 'in'
318
+ order by coalesce(m.internal_date, m.fetched_at) desc, m.id desc limit 1
319
+ ) li on true
320
+ where t.id = any($1::uuid[])`, [ids, SEEN]);
321
+ for (const row of rows) {
322
+ out.set(String(row.id), {
323
+ snippet: String(row.snippet ?? ''),
324
+ lastOut: row.last_direction === 'out',
325
+ senderName: typeof row.from_name === 'string' && row.from_name.trim() !== '' ? row.from_name.trim() : null,
326
+ senderAddress: typeof row.from_addr === 'string' ? row.from_addr : null,
327
+ unread: row.unread === true,
328
+ category: typeof row.category === 'string' ? row.category : null,
329
+ });
330
+ }
331
+ return out;
332
+ }
333
+ /** One address as the `message` component reads it. */
334
+ function addressRow(address, name) {
335
+ return name ? { address, name } : { address };
336
+ }
337
+ /**
338
+ * The parts of a conversation's reading pane that are buddi's rather than the
339
+ * mail's: Mail Triage's verdict on the latest message they sent, and what
340
+ * buddi changed in the mailbox about this conversation, newest first, with
341
+ * Undo where it still applies (the same rows and words as Recent changes).
342
+ */
343
+ async function threadLayer(db, threadId, accountAddress, now) {
344
+ const verdict = await db.query(`select tr.category, tr.urgency, tr.summary, tr.action_needed, tr.decided_at
345
+ from email.triage tr
346
+ join lateral (
347
+ select m.id from email.messages m
348
+ where m.thread_id = $1::uuid and m.direction = 'in'
349
+ order by coalesce(m.internal_date, m.fetched_at) desc, m.id desc limit 1
350
+ ) li on li.id = tr.message_id
351
+ order by tr.decided_at desc, tr.processing_version desc limit 1`, [threadId]);
352
+ const v = verdict.rows[0];
353
+ const triage = v
354
+ ? {
355
+ category: String(v.category),
356
+ tag: tagLabel(String(v.category)),
357
+ urgency: String(v.urgency),
358
+ // "Bill · normal — The October invoice from Studio North, €1,240. To do: pay by 14 Oct."
359
+ line: [
360
+ `${tagLabel(String(v.category))} · ${v.urgency === 'urgent' ? 'urgent' : v.urgency === 'low' ? 'low' : 'this week'}`,
361
+ '—',
362
+ String(v.summary ?? '').trim(),
363
+ v.action_needed ? `To do: ${String(v.action_needed).trim()}` : '',
364
+ ]
365
+ .filter((part) => part !== '')
366
+ .join(' '),
367
+ when: relative(isoOf(v.decided_at), now),
368
+ }
369
+ : null;
370
+ const { rows } = await db.query(`select ${ACTION_COLUMNS_SQL} from email.mailbox_actions a
371
+ where a.message_ids && (select coalesce(array_agg(m.id), '{}') from email.messages m where m.thread_id = $1::uuid)
372
+ order by a.created_at desc, a.seq desc limit $2`, [threadId, THREAD_CHANGES]);
373
+ const changes = [];
374
+ for (const c of rows.map(toAction)) {
375
+ const undoable = undoRefusal(c) === null;
376
+ const moved = undoable ? await movedSince(db, c) : 0;
377
+ const who = c.origin === 'policy' ? `by ${c.actor}` : c.origin === 'owner' ? 'by you' : c.actor === TRIAGE_AGENT_ID ? 'by Mail Triage' : `by @${c.actor}`;
378
+ changes.push({
379
+ id: c.id,
380
+ // The words Recent changes uses: "Mark as read · by Mail Triage · yesterday".
381
+ line: [verbOf(c.kind, c.destination), who, relative(c.createdAt, now), c.note ?? ''].filter((p) => p !== '').join(' · '),
382
+ state: changeState(c),
383
+ undoable,
384
+ undoLine: describeUndo(c, accountAddress, moved),
385
+ });
386
+ }
387
+ return { triage, changes };
388
+ }
237
389
  /**
238
390
  * The list's pill for a conversation: the views that are worth a word.
239
391
  * A notification and "they wrote" are the inbox's ordinary weather and say
@@ -302,6 +454,26 @@ async function searchHits(ctx, input, ids) {
302
454
  ...(built.windowed && built.windowFrom ? { window: windowNote(built.windowFrom) } : {}),
303
455
  };
304
456
  }
457
+ /** How many of buddi's changes a reading pane lists for one conversation. */
458
+ export const THREAD_CHANGES = 3;
459
+ const ACTION_COLUMNS_SQL = ACTION_COLUMNS.split(',').map((c) => `a.${c.trim()}`).join(', ');
460
+ /** The display name, the server's own arrival time and the read mark of each message, by id. */
461
+ async function messageExtras(db, ids) {
462
+ const out = new Map();
463
+ if (ids.length === 0)
464
+ return out;
465
+ const { rows } = await db.query(`select id, from_name, coalesce(internal_date, fetched_at) as at, direction,
466
+ coalesce(flags, '[]'::jsonb) ? $2 as seen
467
+ from email.messages where id = any($1::uuid[])`, [ids, SEEN]);
468
+ for (const row of rows) {
469
+ out.set(String(row.id), {
470
+ fromName: typeof row.from_name === 'string' && row.from_name.trim() !== '' ? row.from_name.trim() : null,
471
+ at: isoOf(row.at),
472
+ unread: row.direction === 'in' && row.seen !== true,
473
+ });
474
+ }
475
+ return out;
476
+ }
305
477
  /**
306
478
  * One conversation: its messages' snippets, then the drafts under them.
307
479
  *
@@ -327,8 +499,23 @@ export function threadQuery() {
327
499
  const live = drafts.filter((d) => LIVE_DRAFT_STATUSES.includes(d.status));
328
500
  const older = drafts.filter((d) => !LIVE_DRAFT_STATUSES.includes(d.status));
329
501
  const latest = messages[messages.length - 1] ?? null;
502
+ const accounts = await listAccounts(ctx.buddi.db, { enabledOnly: false });
503
+ const account = accounts.find((a) => a.id === thread.accountId);
504
+ const layer = await threadLayer(ctx.buddi.db, thread.id, account?.address ?? 'your mailbox', now);
505
+ const extra = await messageExtras(ctx.buddi.db, messages.map((m) => m.id));
506
+ const view = viewOf(reason);
330
507
  return {
331
508
  id: thread.id,
509
+ /*
510
+ * buddi's layer above the thread (host API 1.30's reading pane): the
511
+ * verdict, what was changed and Undo, and "Needs a reply" with Done.
512
+ */
513
+ hasTriage: layer.triage !== null,
514
+ triage: layer.triage,
515
+ triageLine: layer.triage ? String(layer.triage.line) : '',
516
+ changes: layer.changes,
517
+ hasChanges: layer.changes.length > 0,
518
+ needsReply: view === 'needs-you',
332
519
  subject: thread.subject === '' ? '(no subject)' : thread.subject,
333
520
  state: thread.state,
334
521
  attention: viewOf(reason),
@@ -337,32 +524,41 @@ export function threadQuery() {
337
524
  participants: thread.participants.join(', '),
338
525
  lastAt: thread.lastAt,
339
526
  messageCount: thread.messageCount,
340
- messages: messages.map((message) => ({
341
- id: message.id,
342
- from: message.from,
343
- snippet: message.snippet,
344
- who: message.direction === 'out' ? 'you wrote' : 'they wrote',
345
- when: relative(message.date, now),
346
- // Where it is now when that is not the inbox: archived, in Trash,
347
- // in a label, or no longer in the inbox (moved in another app).
348
- place: message.place,
349
- // One line, because a repeated component draws text and formats
350
- // nothing: who wrote it, when, where it is now, and what it opens with.
351
- summary: [
352
- message.from,
353
- message.direction === 'out' ? 'you wrote' : 'they wrote',
354
- relative(message.date, now),
355
- message.place,
356
- ]
357
- .filter((part) => part !== '')
358
- .join(' · ') + (message.snippet ? ` — ${message.snippet}` : ''),
359
- })),
527
+ messages: messages.map((message, index) => {
528
+ const more = extra.get(message.id);
529
+ return {
530
+ id: message.id,
531
+ // The header the reading pane draws before the body arrives (`message`).
532
+ from: addressRow(message.from, more?.fromName),
533
+ to: message.to.map((address) => addressRow(address)),
534
+ at: more?.at ?? message.date,
535
+ // Every message but the newest is one line until it is opened, unless the owner has not read it.
536
+ folded: index < messages.length - 1 && !(more?.unread ?? false),
537
+ fromAddress: message.from,
538
+ snippet: message.snippet,
539
+ who: message.direction === 'out' ? 'you wrote' : 'they wrote',
540
+ when: relative(message.date, now),
541
+ // Where it is now when that is not the inbox: archived, in Trash,
542
+ // in a label, or no longer in the inbox (moved in another app).
543
+ place: message.place,
544
+ // One line, because a repeated component draws text and formats
545
+ // nothing: who wrote it, when, where it is now, and what it opens with.
546
+ summary: [
547
+ message.from,
548
+ message.direction === 'out' ? 'you wrote' : 'they wrote',
549
+ relative(message.date, now),
550
+ message.place,
551
+ ]
552
+ .filter((part) => part !== '')
553
+ .join(' · ') + (message.snippet ? ` — ${message.snippet}` : ''),
554
+ };
555
+ }),
360
556
  latestMessageId: latest?.id ?? null,
361
557
  hasMessages: messages.length > 0,
362
558
  hasDraft: live.length > 0,
363
559
  // Every live draft: the page draws an editor per row, so each row is
364
560
  // the whole envelope rather than a line about one.
365
- drafts: live.map((draft) => draftRow(draft, now)),
561
+ drafts: live.map((draft) => draftRow(draft, now, account?.address)),
366
562
  hasOlder: older.length > 0,
367
563
  older: older.map((draft) => ({
368
564
  id: draft.id,
@@ -395,14 +591,15 @@ export function draftQuery() {
395
591
  };
396
592
  }
397
593
  /** One message's body, on request, with its attachments' listing. */
398
- export function messageQuery() {
594
+ export function messageQuery(worker) {
399
595
  return {
400
596
  name: 'message',
401
597
  params: byId,
402
598
  async produce(params, ctx) {
403
599
  const { id } = params;
404
- const { rows } = await ctx.buddi.db.query(`select m.id, m.from_addr, m.to_addrs, m.cc, m.subject, m.date, m.direction,
405
- m.body_text, m.body_purged_at, m.attachments
600
+ const { rows } = await ctx.buddi.db.query(`select m.id, m.from_addr, m.from_name, m.to_addrs, m.cc, m.subject, m.date, m.direction,
601
+ m.body_text, m.body_html, m.body_purged_at, m.attachments, m.snippet,
602
+ coalesce(m.internal_date, m.fetched_at) as at
406
603
  from email.messages m
407
604
  join email.accounts a on a.id = m.account_id
408
605
  where m.id = $1::uuid`, [id]);
@@ -411,20 +608,44 @@ export function messageQuery() {
411
608
  throw new QueryRefusal('No message here has that id.');
412
609
  const messageId = String(row.id);
413
610
  const purged = row.body_purged_at !== null;
414
- const body = purged
415
- ? 'The body of this message has been purged under your retention setting. Its headers are kept.'
416
- : truncateBody(String(row.body_text ?? ''));
611
+ const purgedNote = 'The body of this message has been purged under your retention setting. Its headers are kept.';
612
+ let html = !purged && typeof row.body_html === 'string' && row.body_html !== '' ? row.body_html : null;
613
+ /*
614
+ * A message synced before pre.44 has no HTML kept. The plugin's worker
615
+ * fetches it once, stores it and hands it back, within a bounded wait
616
+ * (`worker.ts`); the query itself still only reads. Without it, the
617
+ * text is drawn, as before.
618
+ */
619
+ if (html === null && !purged && row.body_html === null && worker)
620
+ html = await worker.htmlFor(messageId);
621
+ const text = purged ? '' : truncateBody(String(row.body_text ?? ''), html ? TEXT_WITH_HTML_BYTES : MAX_BODY_BYTES);
622
+ const toList = Array.isArray(row.to_addrs) ? row.to_addrs : [];
623
+ const ccList = Array.isArray(row.cc) ? row.cc : [];
417
624
  return {
418
625
  id: messageId,
419
- from: row.from_addr,
420
- to: (Array.isArray(row.to_addrs) ? row.to_addrs : []).join(', '),
421
- cc: (Array.isArray(row.cc) ? row.cc : []).join(', '),
626
+ /*
627
+ * The `message` component's shape (host API 1.30): who, to whom,
628
+ * when (the server's arrival time, as the thread orders by), the
629
+ * stored HTML — sanitised at ingest (or at the one fetch an older
630
+ * message gets, above), and again by the dashboard — and the text it
631
+ * falls back to.
632
+ */
633
+ from: addressRow(String(row.from_addr), typeof row.from_name === 'string' ? row.from_name : null),
634
+ to: toList.map((address) => addressRow(address)),
635
+ cc: ccList.map((address) => addressRow(address)),
636
+ at: isoOf(row.at) ?? isoOf(row.date),
637
+ html,
638
+ text: purged ? null : text,
639
+ snippet: row.snippet ?? '',
640
+ note: purged ? purgedNote : null,
641
+ toText: toList.join(', '),
642
+ ccText: ccList.join(', '),
422
643
  subject: row.subject ?? '',
423
644
  date: isoOf(row.date),
424
645
  who: row.direction === 'out' ? 'you wrote' : 'they wrote',
425
- // Null once retention has purged it: the headers stay, the body does
426
- // not, and the page says so rather than drawing an empty message.
427
- bodyText: body,
646
+ // The body rides once, as `text` (null once retention purged it, with
647
+ // `note` saying so): a second copy would put a long message over the
648
+ // gateway's megabyte per answer.
428
649
  purged,
429
650
  attachments: attachmentRows(messageId, row.attachments),
430
651
  };
@@ -924,13 +1145,13 @@ export function learnedRulesQuery() {
924
1145
  },
925
1146
  };
926
1147
  }
927
- export function emailPageQueries() {
1148
+ export function emailPageQueries(worker) {
928
1149
  return [
929
1150
  triageOfferQuery(),
930
1151
  threadsQuery(),
931
1152
  threadQuery(),
932
1153
  draftQuery(),
933
- messageQuery(),
1154
+ messageQuery(worker),
934
1155
  accountsQuery(),
935
1156
  mailStatusQuery(),
936
1157
  policiesQuery(),