@withbuddi/buddi 0.1.0-pre.42 → 0.1.0-pre.44
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.
- package/examples/agents/agent-father/agent.md +12 -5
- package/examples/agents/concierge/agent.md +11 -3
- package/extension/icons/128.png +0 -0
- package/extension/icons/16.png +0 -0
- package/extension/icons/32.png +0 -0
- package/extension/icons/48.png +0 -0
- package/extension/manifest.json +7 -3
- package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/cli/dist/access-cmd.d.ts +2 -1
- package/node_modules/@buddi/cli/dist/access-cmd.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/access-cmd.js +40 -7
- package/node_modules/@buddi/cli/dist/access-cmd.js.map +1 -1
- package/node_modules/@buddi/cli/dist/args.d.ts +2 -1
- package/node_modules/@buddi/cli/dist/args.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/args.js +7 -3
- package/node_modules/@buddi/cli/dist/args.js.map +1 -1
- package/node_modules/@buddi/cli/dist/commands.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/commands.js +3 -2
- package/node_modules/@buddi/cli/dist/commands.js.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor-probes.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor-probes.js +10 -1
- package/node_modules/@buddi/cli/dist/doctor-probes.js.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor.d.ts +9 -0
- package/node_modules/@buddi/cli/dist/doctor.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor.js +21 -3
- package/node_modules/@buddi/cli/dist/doctor.js.map +1 -1
- package/node_modules/@buddi/cli/dist/main.js +1 -1
- package/node_modules/@buddi/cli/dist/main.js.map +1 -1
- package/node_modules/@buddi/cli/dist/mcp/server.js +1 -1
- package/node_modules/@buddi/cli/dist/mcp/server.js.map +1 -1
- package/node_modules/@buddi/cli/dist/mcp/tools.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/mcp/tools.js +60 -0
- package/node_modules/@buddi/cli/dist/mcp/tools.js.map +1 -1
- package/node_modules/@buddi/core/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/core/dist/agents/catalog.js +1 -1
- package/node_modules/@buddi/core/dist/agents/catalog.js.map +1 -1
- package/node_modules/@buddi/core/dist/lock.d.ts +15 -1
- package/node_modules/@buddi/core/dist/lock.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/lock.js +15 -1
- package/node_modules/@buddi/core/dist/lock.js.map +1 -1
- package/node_modules/@buddi/core/dist/pages.d.ts +75 -0
- package/node_modules/@buddi/core/dist/pages.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/pages.js +14 -0
- package/node_modules/@buddi/core/dist/pages.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.d.ts +2 -2
- package/node_modules/@buddi/core/dist/plugin/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/version.d.ts +1 -1
- package/node_modules/@buddi/core/dist/plugin/version.js +1 -1
- package/node_modules/@buddi/core/dist/provider-accounts.d.ts +32 -0
- package/node_modules/@buddi/core/dist/provider-accounts.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/provider-accounts.js +22 -0
- package/node_modules/@buddi/core/dist/provider-accounts.js.map +1 -1
- package/node_modules/@buddi/core/dist/testing/database-url.d.ts +13 -0
- package/node_modules/@buddi/core/dist/testing/database-url.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/testing/database-url.js +34 -0
- package/node_modules/@buddi/core/dist/testing/database-url.js.map +1 -1
- package/node_modules/@buddi/core/dist/testing/isolated-global-setup.d.ts +2 -0
- package/node_modules/@buddi/core/dist/testing/isolated-global-setup.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/testing/isolated-global-setup.js +20 -0
- package/node_modules/@buddi/core/dist/testing/isolated-global-setup.js.map +1 -0
- package/node_modules/@buddi/core/migrations/077_lock_background_portrait.sql +5 -0
- package/node_modules/@buddi/core/package.json +4 -0
- package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/gateway/dist/agents/owner-tools.d.ts +21 -8
- package/node_modules/@buddi/gateway/dist/agents/owner-tools.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/owner-tools.js +201 -36
- package/node_modules/@buddi/gateway/dist/agents/owner-tools.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform.d.ts +8 -0
- package/node_modules/@buddi/gateway/dist/agents/platform.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform.js +48 -22
- package/node_modules/@buddi/gateway/dist/agents/platform.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/evals/golden.d.ts +5 -0
- package/node_modules/@buddi/gateway/dist/evals/golden.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/evals/golden.js +48 -0
- package/node_modules/@buddi/gateway/dist/evals/golden.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/mcp/requests.d.ts +8 -2
- package/node_modules/@buddi/gateway/dist/mcp/requests.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/mcp/requests.js +74 -1
- package/node_modules/@buddi/gateway/dist/mcp/requests.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/owner-profile-edit.d.ts +160 -0
- package/node_modules/@buddi/gateway/dist/owner-profile-edit.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/owner-profile-edit.js +296 -0
- package/node_modules/@buddi/gateway/dist/owner-profile-edit.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/plugins/index.d.ts +1 -0
- package/node_modules/@buddi/gateway/dist/plugins/index.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/index.js +1 -0
- package/node_modules/@buddi/gateway/dist/plugins/index.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/pages-state.d.ts +37 -0
- package/node_modules/@buddi/gateway/dist/plugins/pages-state.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/plugins/pages-state.js +98 -0
- package/node_modules/@buddi/gateway/dist/plugins/pages-state.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/provider-accounts.d.ts +33 -4
- package/node_modules/@buddi/gateway/dist/provider-accounts.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/provider-accounts.js +82 -18
- package/node_modules/@buddi/gateway/dist/provider-accounts.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/provider-diagnostics.d.ts +5 -0
- package/node_modules/@buddi/gateway/dist/provider-diagnostics.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/provider-diagnostics.js +6 -1
- package/node_modules/@buddi/gateway/dist/provider-diagnostics.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.js +5 -2
- package/node_modules/@buddi/gateway/dist/serve.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-connector.d.ts +63 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-connector.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-connector.js +87 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-connector.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.d.ts +39 -4
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.js +99 -11
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-setup.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.js +1 -1
- package/node_modules/@buddi/gateway/dist/web/access/cloudflare-token.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/access/index.d.ts +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/index.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/access/index.js +1 -0
- package/node_modules/@buddi/gateway/dist/web/access/index.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/agent-offers.d.ts +6 -0
- package/node_modules/@buddi/gateway/dist/web/agent-offers.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/agent-offers.js +6 -0
- package/node_modules/@buddi/gateway/dist/web/agent-offers.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/api-routes.js +24 -3
- package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/attention.d.ts +11 -1
- package/node_modules/@buddi/gateway/dist/web/attention.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/attention.js +22 -2
- package/node_modules/@buddi/gateway/dist/web/attention.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts +0 -2
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.js +15 -4
- package/node_modules/@buddi/gateway/dist/web/chat.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/lock-backgrounds.d.ts +9 -0
- package/node_modules/@buddi/gateway/dist/web/lock-backgrounds.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/lock-backgrounds.js +60 -0
- package/node_modules/@buddi/gateway/dist/web/lock-backgrounds.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/lock.d.ts +22 -1
- package/node_modules/@buddi/gateway/dist/web/lock.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/lock.js +87 -24
- package/node_modules/@buddi/gateway/dist/web/lock.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/places.d.ts +5 -0
- package/node_modules/@buddi/gateway/dist/web/places.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/places.js +11 -4
- package/node_modules/@buddi/gateway/dist/web/places.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/plugins.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/plugins.js +4 -0
- package/node_modules/@buddi/gateway/dist/web/plugins.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.d.ts +3 -0
- package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.js +48 -49
- package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/take-on.d.ts +3 -1
- package/node_modules/@buddi/gateway/dist/web/take-on.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/take-on.js +14 -3
- package/node_modules/@buddi/gateway/dist/web/take-on.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/telegram.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/telegram.js +4 -2
- package/node_modules/@buddi/gateway/dist/web/telegram.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/version.d.ts +10 -0
- package/node_modules/@buddi/gateway/dist/web/version.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/version.js +12 -0
- package/node_modules/@buddi/gateway/dist/web/version.js.map +1 -1
- package/node_modules/@buddi/install/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/install/dist/backup.d.ts +12 -0
- package/node_modules/@buddi/install/dist/backup.d.ts.map +1 -1
- package/node_modules/@buddi/install/dist/backup.js +26 -8
- package/node_modules/@buddi/install/dist/backup.js.map +1 -1
- package/node_modules/@buddi/install/dist/cloudflared.d.ts +121 -0
- package/node_modules/@buddi/install/dist/cloudflared.d.ts.map +1 -0
- package/node_modules/@buddi/install/dist/cloudflared.js +451 -0
- package/node_modules/@buddi/install/dist/cloudflared.js.map +1 -0
- package/node_modules/@buddi/install/dist/index.d.ts +1 -0
- package/node_modules/@buddi/install/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/install/dist/index.js +1 -0
- package/node_modules/@buddi/install/dist/index.js.map +1 -1
- package/node_modules/@buddi/install/dist/supervisor.d.ts +6 -1
- package/node_modules/@buddi/install/dist/supervisor.d.ts.map +1 -1
- package/node_modules/@buddi/install/dist/supervisor.js +51 -5
- package/node_modules/@buddi/install/dist/supervisor.js.map +1 -1
- package/node_modules/@buddi/install/dist/upgrade.d.ts +2 -0
- package/node_modules/@buddi/install/dist/upgrade.d.ts.map +1 -1
- package/node_modules/@buddi/install/dist/upgrade.js +3 -2
- package/node_modules/@buddi/install/dist/upgrade.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/runtime/dist/codex-direct.d.ts +12 -1
- package/node_modules/@buddi/runtime/dist/codex-direct.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/codex-direct.js +15 -6
- package/node_modules/@buddi/runtime/dist/codex-direct.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/groups.d.ts +5 -4
- package/node_modules/@buddi/runtime/dist/groups.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/groups.js +7 -6
- package/node_modules/@buddi/runtime/dist/groups.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/provider-models.d.ts +4 -0
- package/node_modules/@buddi/runtime/dist/provider-models.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/provider-models.js.map +1 -1
- package/node_modules/@buddi/tool-artifacts/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-browser/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-email/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-email/dist/html.d.ts +16 -0
- package/node_modules/@buddi/tool-email/dist/html.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/html.js +273 -0
- package/node_modules/@buddi/tool-email/dist/html.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.d.ts +7 -0
- package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.js +53 -0
- package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mail.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mail.js +4 -0
- package/node_modules/@buddi/tool-email/dist/mail.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/descriptors.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/descriptors.js +250 -176
- package/node_modules/@buddi/tool-email/dist/pages/descriptors.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/index.d.ts +1 -0
- package/node_modules/@buddi/tool-email/dist/pages/index.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/index.js +3 -0
- package/node_modules/@buddi/tool-email/dist/pages/index.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/queries.d.ts +28 -1
- package/node_modules/@buddi/tool-email/dist/pages/queries.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/queries.js +362 -66
- package/node_modules/@buddi/tool-email/dist/pages/queries.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/thread-tools.d.ts +25 -0
- package/node_modules/@buddi/tool-email/dist/pages/thread-tools.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/pages/thread-tools.js +33 -0
- package/node_modules/@buddi/tool-email/dist/pages/thread-tools.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/ports.d.ts +10 -0
- package/node_modules/@buddi/tool-email/dist/ports.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/ports.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/retention.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/retention.js +1 -0
- package/node_modules/@buddi/tool-email/dist/retention.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.js +9 -2
- package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.js.map +1 -1
- package/node_modules/@buddi/tool-email/migrations/027_first_contact.sql +13 -0
- package/node_modules/@buddi/tool-email/migrations/028_reading.sql +20 -0
- package/node_modules/@buddi/tool-email/package.json +1 -0
- package/node_modules/@buddi/tool-host/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-mcp/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-memory/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/tool-web/dist/.tsbuildinfo +1 -1
- package/node_modules/entities/LICENSE +11 -0
- package/node_modules/entities/decode.d.ts +1 -0
- package/node_modules/entities/decode.js +3 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts +19 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.js +77 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.js.map +1 -0
- package/node_modules/entities/dist/commonjs/decode.d.ts +209 -0
- package/node_modules/entities/dist/commonjs/decode.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/decode.js +511 -0
- package/node_modules/entities/dist/commonjs/decode.js.map +1 -0
- package/node_modules/entities/dist/commonjs/encode.d.ts +22 -0
- package/node_modules/entities/dist/commonjs/encode.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/encode.js +73 -0
- package/node_modules/entities/dist/commonjs/encode.js.map +1 -0
- package/node_modules/entities/dist/commonjs/escape.d.ts +43 -0
- package/node_modules/entities/dist/commonjs/escape.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/escape.js +121 -0
- package/node_modules/entities/dist/commonjs/escape.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts +2 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.js +10 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts +2 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js +10 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts +8 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.js +13 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.js.map +1 -0
- package/node_modules/entities/dist/commonjs/index.d.ts +96 -0
- package/node_modules/entities/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/index.js +131 -0
- package/node_modules/entities/dist/commonjs/index.js.map +1 -0
- package/node_modules/entities/dist/commonjs/package.json +3 -0
- package/node_modules/entities/dist/esm/decode-codepoint.d.ts +19 -0
- package/node_modules/entities/dist/esm/decode-codepoint.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/decode-codepoint.js +72 -0
- package/node_modules/entities/dist/esm/decode-codepoint.js.map +1 -0
- package/node_modules/entities/dist/esm/decode.d.ts +209 -0
- package/node_modules/entities/dist/esm/decode.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/decode.js +497 -0
- package/node_modules/entities/dist/esm/decode.js.map +1 -0
- package/node_modules/entities/dist/esm/encode.d.ts +22 -0
- package/node_modules/entities/dist/esm/encode.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/encode.js +69 -0
- package/node_modules/entities/dist/esm/encode.js.map +1 -0
- package/node_modules/entities/dist/esm/escape.d.ts +43 -0
- package/node_modules/entities/dist/esm/escape.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/escape.js +117 -0
- package/node_modules/entities/dist/esm/escape.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts +2 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.js +7 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts +2 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.js +7 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/encode-html.d.ts +8 -0
- package/node_modules/entities/dist/esm/generated/encode-html.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/encode-html.js +10 -0
- package/node_modules/entities/dist/esm/generated/encode-html.js.map +1 -0
- package/node_modules/entities/dist/esm/index.d.ts +96 -0
- package/node_modules/entities/dist/esm/index.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/index.js +107 -0
- package/node_modules/entities/dist/esm/index.js.map +1 -0
- package/node_modules/entities/dist/esm/package.json +3 -0
- package/node_modules/entities/escape.d.ts +1 -0
- package/node_modules/entities/escape.js +3 -0
- package/node_modules/entities/package.json +118 -0
- package/node_modules/entities/readme.md +122 -0
- package/node_modules/entities/src/decode-codepoint.ts +81 -0
- package/node_modules/entities/src/decode.spec.ts +320 -0
- package/node_modules/entities/src/decode.ts +620 -0
- package/node_modules/entities/src/encode.spec.ts +78 -0
- package/node_modules/entities/src/encode.ts +77 -0
- package/node_modules/entities/src/escape.spec.ts +14 -0
- package/node_modules/entities/src/escape.ts +148 -0
- package/node_modules/entities/src/generated/.eslintrc.json +10 -0
- package/node_modules/entities/src/generated/decode-data-html.ts +8 -0
- package/node_modules/entities/src/generated/decode-data-xml.ts +8 -0
- package/node_modules/entities/src/generated/encode-html.ts +17 -0
- package/node_modules/entities/src/index.spec.ts +125 -0
- package/node_modules/entities/src/index.ts +188 -0
- package/node_modules/parse5/LICENSE +19 -0
- package/node_modules/parse5/README.md +38 -0
- package/node_modules/parse5/dist/cjs/common/doctype.d.ts +4 -0
- package/node_modules/parse5/dist/cjs/common/doctype.js +118 -0
- package/node_modules/parse5/dist/cjs/common/error-codes.d.ts +67 -0
- package/node_modules/parse5/dist/cjs/common/error-codes.js +66 -0
- package/node_modules/parse5/dist/cjs/common/foreign-content.d.ts +9 -0
- package/node_modules/parse5/dist/cjs/common/foreign-content.js +237 -0
- package/node_modules/parse5/dist/cjs/common/html.d.ts +289 -0
- package/node_modules/parse5/dist/cjs/common/html.js +528 -0
- package/node_modules/parse5/dist/cjs/common/token.d.ts +84 -0
- package/node_modules/parse5/dist/cjs/common/token.js +24 -0
- package/node_modules/parse5/dist/cjs/common/unicode.d.ts +42 -0
- package/node_modules/parse5/dist/cjs/common/unicode.js +70 -0
- package/node_modules/parse5/dist/cjs/index.d.ts +71 -0
- package/node_modules/parse5/dist/cjs/index.js +54 -0
- package/node_modules/parse5/dist/cjs/package.json +1 -0
- package/node_modules/parse5/dist/cjs/parser/formatting-element-list.d.ts +36 -0
- package/node_modules/parse5/dist/cjs/parser/formatting-element-list.js +114 -0
- package/node_modules/parse5/dist/cjs/parser/index.d.ts +221 -0
- package/node_modules/parse5/dist/cjs/parser/index.js +3240 -0
- package/node_modules/parse5/dist/cjs/parser/open-element-stack.d.ts +53 -0
- package/node_modules/parse5/dist/cjs/parser/open-element-stack.js +328 -0
- package/node_modules/parse5/dist/cjs/serializer/index.d.ts +60 -0
- package/node_modules/parse5/dist/cjs/serializer/index.js +172 -0
- package/node_modules/parse5/dist/cjs/tokenizer/index.d.ts +247 -0
- package/node_modules/parse5/dist/cjs/tokenizer/index.js +2714 -0
- package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.d.ts +36 -0
- package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.js +200 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/default.d.ts +84 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/default.js +176 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/interface.d.ts +255 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/interface.js +2 -0
- package/node_modules/parse5/dist/common/doctype.d.ts +4 -0
- package/node_modules/parse5/dist/common/doctype.js +114 -0
- package/node_modules/parse5/dist/common/error-codes.d.ts +67 -0
- package/node_modules/parse5/dist/common/error-codes.js +63 -0
- package/node_modules/parse5/dist/common/foreign-content.d.ts +9 -0
- package/node_modules/parse5/dist/common/foreign-content.js +228 -0
- package/node_modules/parse5/dist/common/html.d.ts +289 -0
- package/node_modules/parse5/dist/common/html.js +523 -0
- package/node_modules/parse5/dist/common/token.d.ts +84 -0
- package/node_modules/parse5/dist/common/token.js +20 -0
- package/node_modules/parse5/dist/common/unicode.d.ts +42 -0
- package/node_modules/parse5/dist/common/unicode.js +62 -0
- package/node_modules/parse5/dist/index.d.ts +71 -0
- package/node_modules/parse5/dist/index.js +42 -0
- package/node_modules/parse5/dist/parser/formatting-element-list.d.ts +36 -0
- package/node_modules/parse5/dist/parser/formatting-element-list.js +110 -0
- package/node_modules/parse5/dist/parser/index.d.ts +221 -0
- package/node_modules/parse5/dist/parser/index.js +3245 -0
- package/node_modules/parse5/dist/parser/open-element-stack.d.ts +53 -0
- package/node_modules/parse5/dist/parser/open-element-stack.js +324 -0
- package/node_modules/parse5/dist/serializer/index.d.ts +60 -0
- package/node_modules/parse5/dist/serializer/index.js +168 -0
- package/node_modules/parse5/dist/tokenizer/index.d.ts +247 -0
- package/node_modules/parse5/dist/tokenizer/index.js +2710 -0
- package/node_modules/parse5/dist/tokenizer/preprocessor.d.ts +36 -0
- package/node_modules/parse5/dist/tokenizer/preprocessor.js +196 -0
- package/node_modules/parse5/dist/tree-adapters/default.d.ts +84 -0
- package/node_modules/parse5/dist/tree-adapters/default.js +173 -0
- package/node_modules/parse5/dist/tree-adapters/interface.d.ts +255 -0
- package/node_modules/parse5/dist/tree-adapters/interface.js +1 -0
- package/node_modules/parse5/package.json +50 -0
- package/package.json +2 -2
- package/packages/cli/dist/.tsbuildinfo +1 -1
- package/packages/cli/dist/access-cmd.d.ts +2 -1
- package/packages/cli/dist/access-cmd.d.ts.map +1 -1
- package/packages/cli/dist/access-cmd.js +40 -7
- package/packages/cli/dist/access-cmd.js.map +1 -1
- package/packages/cli/dist/args.d.ts +2 -1
- package/packages/cli/dist/args.d.ts.map +1 -1
- package/packages/cli/dist/args.js +7 -3
- package/packages/cli/dist/args.js.map +1 -1
- package/packages/cli/dist/commands.d.ts.map +1 -1
- package/packages/cli/dist/commands.js +3 -2
- package/packages/cli/dist/commands.js.map +1 -1
- package/packages/cli/dist/doctor-probes.d.ts.map +1 -1
- package/packages/cli/dist/doctor-probes.js +10 -1
- package/packages/cli/dist/doctor-probes.js.map +1 -1
- package/packages/cli/dist/doctor.d.ts +9 -0
- package/packages/cli/dist/doctor.d.ts.map +1 -1
- package/packages/cli/dist/doctor.js +21 -3
- package/packages/cli/dist/doctor.js.map +1 -1
- package/packages/cli/dist/main.js +1 -1
- package/packages/cli/dist/main.js.map +1 -1
- package/packages/cli/dist/mcp/server.js +1 -1
- package/packages/cli/dist/mcp/server.js.map +1 -1
- package/packages/cli/dist/mcp/tools.d.ts.map +1 -1
- package/packages/cli/dist/mcp/tools.js +60 -0
- package/packages/cli/dist/mcp/tools.js.map +1 -1
- package/packages/core/dist/.tsbuildinfo +1 -1
- package/packages/core/dist/agents/catalog.js +1 -1
- package/packages/core/dist/agents/catalog.js.map +1 -1
- package/packages/core/dist/lock.d.ts +15 -1
- package/packages/core/dist/lock.d.ts.map +1 -1
- package/packages/core/dist/lock.js +15 -1
- package/packages/core/dist/lock.js.map +1 -1
- package/packages/core/dist/pages.d.ts +75 -0
- package/packages/core/dist/pages.d.ts.map +1 -1
- package/packages/core/dist/pages.js +14 -0
- package/packages/core/dist/pages.js.map +1 -1
- package/packages/core/dist/plugin/index.d.ts +2 -2
- package/packages/core/dist/plugin/index.d.ts.map +1 -1
- package/packages/core/dist/plugin/index.js.map +1 -1
- package/packages/core/dist/plugin/version.d.ts +1 -1
- package/packages/core/dist/plugin/version.js +1 -1
- package/packages/core/dist/provider-accounts.d.ts +32 -0
- package/packages/core/dist/provider-accounts.d.ts.map +1 -1
- package/packages/core/dist/provider-accounts.js +22 -0
- package/packages/core/dist/provider-accounts.js.map +1 -1
- package/packages/core/dist/testing/database-url.d.ts +13 -0
- package/packages/core/dist/testing/database-url.d.ts.map +1 -1
- package/packages/core/dist/testing/database-url.js +34 -0
- package/packages/core/dist/testing/database-url.js.map +1 -1
- package/packages/core/dist/testing/isolated-global-setup.d.ts +2 -0
- package/packages/core/dist/testing/isolated-global-setup.d.ts.map +1 -0
- package/packages/core/dist/testing/isolated-global-setup.js +20 -0
- package/packages/core/dist/testing/isolated-global-setup.js.map +1 -0
- package/packages/core/migrations/077_lock_background_portrait.sql +5 -0
- package/packages/core/package.json +4 -0
- package/packages/gateway/dist/.tsbuildinfo +1 -1
- package/packages/gateway/dist/agents/owner-tools.d.ts +21 -8
- package/packages/gateway/dist/agents/owner-tools.d.ts.map +1 -1
- package/packages/gateway/dist/agents/owner-tools.js +201 -36
- package/packages/gateway/dist/agents/owner-tools.js.map +1 -1
- package/packages/gateway/dist/agents/platform.d.ts +8 -0
- package/packages/gateway/dist/agents/platform.d.ts.map +1 -1
- package/packages/gateway/dist/agents/platform.js +48 -22
- package/packages/gateway/dist/agents/platform.js.map +1 -1
- package/packages/gateway/dist/evals/golden.d.ts +5 -0
- package/packages/gateway/dist/evals/golden.d.ts.map +1 -1
- package/packages/gateway/dist/evals/golden.js +48 -0
- package/packages/gateway/dist/evals/golden.js.map +1 -1
- package/packages/gateway/dist/mcp/requests.d.ts +8 -2
- package/packages/gateway/dist/mcp/requests.d.ts.map +1 -1
- package/packages/gateway/dist/mcp/requests.js +74 -1
- package/packages/gateway/dist/mcp/requests.js.map +1 -1
- package/packages/gateway/dist/owner-profile-edit.d.ts +160 -0
- package/packages/gateway/dist/owner-profile-edit.d.ts.map +1 -0
- package/packages/gateway/dist/owner-profile-edit.js +296 -0
- package/packages/gateway/dist/owner-profile-edit.js.map +1 -0
- package/packages/gateway/dist/plugins/index.d.ts +1 -0
- package/packages/gateway/dist/plugins/index.d.ts.map +1 -1
- package/packages/gateway/dist/plugins/index.js +1 -0
- package/packages/gateway/dist/plugins/index.js.map +1 -1
- package/packages/gateway/dist/plugins/pages-state.d.ts +37 -0
- package/packages/gateway/dist/plugins/pages-state.d.ts.map +1 -0
- package/packages/gateway/dist/plugins/pages-state.js +98 -0
- package/packages/gateway/dist/plugins/pages-state.js.map +1 -0
- package/packages/gateway/dist/provider-accounts.d.ts +33 -4
- package/packages/gateway/dist/provider-accounts.d.ts.map +1 -1
- package/packages/gateway/dist/provider-accounts.js +82 -18
- package/packages/gateway/dist/provider-accounts.js.map +1 -1
- package/packages/gateway/dist/provider-diagnostics.d.ts +5 -0
- package/packages/gateway/dist/provider-diagnostics.d.ts.map +1 -1
- package/packages/gateway/dist/provider-diagnostics.js +6 -1
- package/packages/gateway/dist/provider-diagnostics.js.map +1 -1
- package/packages/gateway/dist/serve.d.ts.map +1 -1
- package/packages/gateway/dist/serve.js +5 -2
- package/packages/gateway/dist/serve.js.map +1 -1
- package/packages/gateway/dist/web/access/cloudflare-connector.d.ts +63 -0
- package/packages/gateway/dist/web/access/cloudflare-connector.d.ts.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-connector.js +87 -0
- package/packages/gateway/dist/web/access/cloudflare-connector.js.map +1 -0
- package/packages/gateway/dist/web/access/cloudflare-setup.d.ts +39 -4
- package/packages/gateway/dist/web/access/cloudflare-setup.d.ts.map +1 -1
- package/packages/gateway/dist/web/access/cloudflare-setup.js +99 -11
- package/packages/gateway/dist/web/access/cloudflare-setup.js.map +1 -1
- package/packages/gateway/dist/web/access/cloudflare-token.js +1 -1
- package/packages/gateway/dist/web/access/cloudflare-token.js.map +1 -1
- package/packages/gateway/dist/web/access/index.d.ts +1 -0
- package/packages/gateway/dist/web/access/index.d.ts.map +1 -1
- package/packages/gateway/dist/web/access/index.js +1 -0
- package/packages/gateway/dist/web/access/index.js.map +1 -1
- package/packages/gateway/dist/web/agent-offers.d.ts +6 -0
- package/packages/gateway/dist/web/agent-offers.d.ts.map +1 -1
- package/packages/gateway/dist/web/agent-offers.js +6 -0
- package/packages/gateway/dist/web/agent-offers.js.map +1 -1
- package/packages/gateway/dist/web/api-routes.d.ts.map +1 -1
- package/packages/gateway/dist/web/api-routes.js +24 -3
- package/packages/gateway/dist/web/api-routes.js.map +1 -1
- package/packages/gateway/dist/web/attention.d.ts +11 -1
- package/packages/gateway/dist/web/attention.d.ts.map +1 -1
- package/packages/gateway/dist/web/attention.js +22 -2
- package/packages/gateway/dist/web/attention.js.map +1 -1
- package/packages/gateway/dist/web/chat.d.ts +0 -2
- package/packages/gateway/dist/web/chat.d.ts.map +1 -1
- package/packages/gateway/dist/web/chat.js +15 -4
- package/packages/gateway/dist/web/chat.js.map +1 -1
- package/packages/gateway/dist/web/lock-backgrounds.d.ts +9 -0
- package/packages/gateway/dist/web/lock-backgrounds.d.ts.map +1 -0
- package/packages/gateway/dist/web/lock-backgrounds.js +60 -0
- package/packages/gateway/dist/web/lock-backgrounds.js.map +1 -0
- package/packages/gateway/dist/web/lock.d.ts +22 -1
- package/packages/gateway/dist/web/lock.d.ts.map +1 -1
- package/packages/gateway/dist/web/lock.js +87 -24
- package/packages/gateway/dist/web/lock.js.map +1 -1
- package/packages/gateway/dist/web/places.d.ts +5 -0
- package/packages/gateway/dist/web/places.d.ts.map +1 -1
- package/packages/gateway/dist/web/places.js +11 -4
- package/packages/gateway/dist/web/places.js.map +1 -1
- package/packages/gateway/dist/web/plugins.d.ts.map +1 -1
- package/packages/gateway/dist/web/plugins.js +4 -0
- package/packages/gateway/dist/web/plugins.js.map +1 -1
- package/packages/gateway/dist/web/server.d.ts +3 -0
- package/packages/gateway/dist/web/server.d.ts.map +1 -1
- package/packages/gateway/dist/web/server.js +48 -49
- package/packages/gateway/dist/web/server.js.map +1 -1
- package/packages/gateway/dist/web/take-on.d.ts +3 -1
- package/packages/gateway/dist/web/take-on.d.ts.map +1 -1
- package/packages/gateway/dist/web/take-on.js +14 -3
- package/packages/gateway/dist/web/take-on.js.map +1 -1
- package/packages/gateway/dist/web/telegram.d.ts.map +1 -1
- package/packages/gateway/dist/web/telegram.js +4 -2
- package/packages/gateway/dist/web/telegram.js.map +1 -1
- package/packages/gateway/dist/web/version.d.ts +10 -0
- package/packages/gateway/dist/web/version.d.ts.map +1 -1
- package/packages/gateway/dist/web/version.js +12 -0
- package/packages/gateway/dist/web/version.js.map +1 -1
- package/packages/install/dist/.tsbuildinfo +1 -1
- package/packages/install/dist/backup.d.ts +12 -0
- package/packages/install/dist/backup.d.ts.map +1 -1
- package/packages/install/dist/backup.js +26 -8
- package/packages/install/dist/backup.js.map +1 -1
- package/packages/install/dist/cloudflared.d.ts +121 -0
- package/packages/install/dist/cloudflared.d.ts.map +1 -0
- package/packages/install/dist/cloudflared.js +451 -0
- package/packages/install/dist/cloudflared.js.map +1 -0
- package/packages/install/dist/index.d.ts +1 -0
- package/packages/install/dist/index.d.ts.map +1 -1
- package/packages/install/dist/index.js +1 -0
- package/packages/install/dist/index.js.map +1 -1
- package/packages/install/dist/supervisor.d.ts +6 -1
- package/packages/install/dist/supervisor.d.ts.map +1 -1
- package/packages/install/dist/supervisor.js +51 -5
- package/packages/install/dist/supervisor.js.map +1 -1
- package/packages/install/dist/upgrade.d.ts +2 -0
- package/packages/install/dist/upgrade.d.ts.map +1 -1
- package/packages/install/dist/upgrade.js +3 -2
- package/packages/install/dist/upgrade.js.map +1 -1
- package/packages/runtime/dist/.tsbuildinfo +1 -1
- package/packages/runtime/dist/codex-direct.d.ts +12 -1
- package/packages/runtime/dist/codex-direct.d.ts.map +1 -1
- package/packages/runtime/dist/codex-direct.js +15 -6
- package/packages/runtime/dist/codex-direct.js.map +1 -1
- package/packages/runtime/dist/groups.d.ts +5 -4
- package/packages/runtime/dist/groups.d.ts.map +1 -1
- package/packages/runtime/dist/groups.js +7 -6
- package/packages/runtime/dist/groups.js.map +1 -1
- package/packages/runtime/dist/provider-models.d.ts +4 -0
- package/packages/runtime/dist/provider-models.d.ts.map +1 -1
- package/packages/runtime/dist/provider-models.js.map +1 -1
- package/packages/tools/artifacts/dist/.tsbuildinfo +1 -1
- package/packages/tools/browser/dist/.tsbuildinfo +1 -1
- package/packages/tools/email/dist/.tsbuildinfo +1 -1
- package/packages/tools/email/dist/html.d.ts +16 -0
- package/packages/tools/email/dist/html.d.ts.map +1 -0
- package/packages/tools/email/dist/html.js +273 -0
- package/packages/tools/email/dist/html.js.map +1 -0
- package/packages/tools/email/dist/imap/imapflow-client.d.ts +7 -0
- package/packages/tools/email/dist/imap/imapflow-client.d.ts.map +1 -1
- package/packages/tools/email/dist/imap/imapflow-client.js +53 -0
- package/packages/tools/email/dist/imap/imapflow-client.js.map +1 -1
- package/packages/tools/email/dist/mail.d.ts.map +1 -1
- package/packages/tools/email/dist/mail.js +4 -0
- package/packages/tools/email/dist/mail.js.map +1 -1
- package/packages/tools/email/dist/pages/descriptors.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/descriptors.js +250 -176
- package/packages/tools/email/dist/pages/descriptors.js.map +1 -1
- package/packages/tools/email/dist/pages/index.d.ts +1 -0
- package/packages/tools/email/dist/pages/index.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/index.js +3 -0
- package/packages/tools/email/dist/pages/index.js.map +1 -1
- package/packages/tools/email/dist/pages/queries.d.ts +28 -1
- package/packages/tools/email/dist/pages/queries.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/queries.js +362 -66
- package/packages/tools/email/dist/pages/queries.js.map +1 -1
- package/packages/tools/email/dist/pages/thread-tools.d.ts +25 -0
- package/packages/tools/email/dist/pages/thread-tools.d.ts.map +1 -0
- package/packages/tools/email/dist/pages/thread-tools.js +33 -0
- package/packages/tools/email/dist/pages/thread-tools.js.map +1 -0
- package/packages/tools/email/dist/ports.d.ts +10 -0
- package/packages/tools/email/dist/ports.d.ts.map +1 -1
- package/packages/tools/email/dist/ports.js.map +1 -1
- package/packages/tools/email/dist/retention.d.ts.map +1 -1
- package/packages/tools/email/dist/retention.js +1 -0
- package/packages/tools/email/dist/retention.js.map +1 -1
- package/packages/tools/email/dist/sources/inbox-poll.d.ts.map +1 -1
- package/packages/tools/email/dist/sources/inbox-poll.js +9 -2
- package/packages/tools/email/dist/sources/inbox-poll.js.map +1 -1
- package/packages/tools/email/migrations/027_first_contact.sql +13 -0
- package/packages/tools/email/migrations/028_reading.sql +20 -0
- package/packages/tools/email/package.json +1 -0
- package/packages/tools/host/dist/.tsbuildinfo +1 -1
- package/packages/tools/mcp/dist/.tsbuildinfo +1 -1
- package/packages/tools/memory/dist/.tsbuildinfo +1 -1
- package/packages/tools/web/dist/.tsbuildinfo +1 -1
- package/packages/web/dist/apple-touch-icon.png +0 -0
- package/packages/web/dist/assets/index-C1sRt7zd.js +149 -0
- package/packages/web/dist/assets/index-CdZpSJ4_.css +1 -0
- package/packages/web/dist/assets/{lottie_light-CQmEj1as.js → lottie_light-DnYl9yaP.js} +1 -1
- package/packages/web/dist/backgrounds/golden-streak-portrait.jpg +0 -0
- package/packages/web/dist/backgrounds/golden-streak-thumb.jpg +0 -0
- package/packages/web/dist/backgrounds/manifest.json +18 -0
- package/packages/web/dist/backgrounds/peoria-autumn-waterfront-thumb.jpg +0 -0
- package/packages/web/dist/backgrounds/peoria-autumn-waterfront.jpg +0 -0
- package/packages/web/dist/build.json +1 -1
- package/packages/web/dist/favicon-16.png +0 -0
- package/packages/web/dist/favicon-32.png +0 -0
- package/packages/web/dist/favicon.ico +0 -0
- package/packages/web/dist/icon-192.png +0 -0
- package/packages/web/dist/icon-512.png +0 -0
- package/packages/web/dist/index.html +6 -3
- package/packages/web/dist/manifest.webmanifest +1 -1
- package/packages/web/dist/maskable-512.png +0 -0
- package/packages/web/dist/precache.json +7 -5
- package/packages/web/dist/assets/index-BrA8nWN-.css +0 -1
- package/packages/web/dist/assets/index-lmUTDd2T.js +0 -146
- package/packages/web/dist/favicon.png +0 -0
- package/packages/web/dist/icon-maskable-512.png +0 -0
|
@@ -23,7 +23,7 @@ import { QueryRefusal } from '@buddi/core/plugin';
|
|
|
23
23
|
import { POLL_EVERY_SECONDS, TRIAGE_AGENT_ID } from '../sources/inbox-poll.js';
|
|
24
24
|
import { idleLive } from '../sources/idle.js';
|
|
25
25
|
import { booleanFilter, buildSearch, narrows, toSearchRow, validateFilters, windowNote, } from '../search.js';
|
|
26
|
-
import {
|
|
26
|
+
import { lastSyncedByAccount, listAccounts } from '../config.js';
|
|
27
27
|
import { ACCOUNT_KIND } from '../credentials.js';
|
|
28
28
|
import { attentionReasons, findThread, listThreadRows, threadMessages } from '../threads.js';
|
|
29
29
|
import { attentionLine, reasonOf, viewOf } from '../needs-you.js';
|
|
@@ -34,6 +34,7 @@ import { loadWatcherSettings, DEFAULT_WATCHER_SETTINGS } from '../watchers.js';
|
|
|
34
34
|
import { draftStatusLine, isoOf, policyLine, relative } from './format.js';
|
|
35
35
|
import { describeUndo, movedSince, plural, recentActions, undoRefusal, verbOf } from '../mailbox/actions.js';
|
|
36
36
|
import { learnedRules } from '../policies/auto.js';
|
|
37
|
+
import { ACTION_COLUMNS, SEEN, toAction } from '../mailbox/actions.js';
|
|
37
38
|
/** How many conversations the list shows before the owner narrows it. */
|
|
38
39
|
export const THREAD_LIST_LIMIT = 30;
|
|
39
40
|
/** How many messages of a conversation the page draws. The newest ones. */
|
|
@@ -80,6 +81,11 @@ export function attachmentRows(messageId, raw) {
|
|
|
80
81
|
line: `${filename} — ${detail}`,
|
|
81
82
|
artifactId: a.artifactId ?? null,
|
|
82
83
|
held: a.artifactId ? 'in your files' : 'not fetched',
|
|
84
|
+
// The `message` component's own words for the same file (host API 1.30).
|
|
85
|
+
name: filename,
|
|
86
|
+
size: Number.isFinite(size) ? size : 0,
|
|
87
|
+
mime: a.mime ?? 'application/octet-stream',
|
|
88
|
+
contentId: typeof a.contentId === 'string' && a.contentId !== '' ? a.contentId : null,
|
|
83
89
|
};
|
|
84
90
|
});
|
|
85
91
|
}
|
|
@@ -109,8 +115,14 @@ export function formatBytes(bytes) {
|
|
|
109
115
|
export const MAX_BODY_BYTES = 512 * 1024;
|
|
110
116
|
/** The sentence a cut body ends with. Said once, so a test can name it. */
|
|
111
117
|
export const TRUNCATED_NOTE = '… this message is too long to show in full; the rest is in your mailbox.';
|
|
112
|
-
|
|
113
|
-
|
|
118
|
+
/**
|
|
119
|
+
* How much of the plain text rides along when there is an HTML body too: the
|
|
120
|
+
* text is then only the fallback, and the answer must stay under the
|
|
121
|
+
* engine's megabyte with both in it.
|
|
122
|
+
*/
|
|
123
|
+
export const TEXT_WITH_HTML_BYTES = 64 * 1024;
|
|
124
|
+
export function truncateBody(text, max = MAX_BODY_BYTES) {
|
|
125
|
+
if (Buffer.byteLength(text, 'utf8') <= max)
|
|
114
126
|
return text;
|
|
115
127
|
/*
|
|
116
128
|
* Cut on a character boundary: slicing bytes can land in the middle of a
|
|
@@ -118,12 +130,12 @@ export function truncateBody(text) {
|
|
|
118
130
|
* end of every long message. Decoding the slice leaves that partial
|
|
119
131
|
* character as U+FFFD, which is exactly what is trimmed off here.
|
|
120
132
|
*/
|
|
121
|
-
const bytes = Buffer.from(text, 'utf8').subarray(0,
|
|
133
|
+
const bytes = Buffer.from(text, 'utf8').subarray(0, max);
|
|
122
134
|
const whole = new TextDecoder('utf-8').decode(bytes).replace(/\uFFFD+$/, '');
|
|
123
135
|
return `${whole}\n\n${TRUNCATED_NOTE}`;
|
|
124
136
|
}
|
|
125
137
|
/** A draft as the editor and the draft list read it. Never a patch: all of it. */
|
|
126
|
-
function draftRow(draft, now) {
|
|
138
|
+
function draftRow(draft, now, fromAddress) {
|
|
127
139
|
const live = LIVE_DRAFT_STATUSES.includes(draft.status) && draft.sentActionId === null;
|
|
128
140
|
// Dispatched, never confirmed: the one state where nothing may be done to it
|
|
129
141
|
// until somebody has looked in the mailbox.
|
|
@@ -153,6 +165,17 @@ function draftRow(draft, now) {
|
|
|
153
165
|
notLiveLine: `This draft is ${draft.status} and cannot be edited or sent. It is kept so you can read what was proposed.`,
|
|
154
166
|
unresolvedLine: unresolvedLine(draft.sendError),
|
|
155
167
|
sendError: draft.sendError,
|
|
168
|
+
/*
|
|
169
|
+
* The reply as the reading pane shows it before anyone edits it: drawn
|
|
170
|
+
* the way a message is (host API 1.30), from the mailbox it will leave.
|
|
171
|
+
*/
|
|
172
|
+
preview: {
|
|
173
|
+
from: { name: 'Your reply', address: fromAddress ?? draft.to[0] ?? 'you' },
|
|
174
|
+
to: draft.to.map((address) => ({ address })),
|
|
175
|
+
cc: draft.cc.map((address) => ({ address })),
|
|
176
|
+
at: draft.updatedAt,
|
|
177
|
+
text: draft.bodyText,
|
|
178
|
+
},
|
|
156
179
|
};
|
|
157
180
|
}
|
|
158
181
|
/** What a dispatch that never came back says, with the server's own words. */
|
|
@@ -199,6 +222,7 @@ export function threadsQuery() {
|
|
|
199
222
|
const { rows } = await ctx.buddi.db.query(`select distinct thread_id from email.drafts
|
|
200
223
|
where thread_id = any($1::uuid[]) and status = any($2::text[])`, [threads.map((t) => t.id), [...LIVE_DRAFT_STATUSES]]);
|
|
201
224
|
const withDraft = new Set(rows.map((r) => String(r.thread_id)));
|
|
225
|
+
const reading = await listReading(ctx.buddi.db, threads.map((t) => t.id));
|
|
202
226
|
/*
|
|
203
227
|
* Who the conversation is *with*: the first participant who is not one
|
|
204
228
|
* of the owner's own addresses. The owner is on every thread, so the
|
|
@@ -206,34 +230,159 @@ export function threadsQuery() {
|
|
|
206
230
|
*/
|
|
207
231
|
const own = new Set(accounts.flatMap((account) => [account.address, ...account.aliases]).map((address) => address.toLowerCase()));
|
|
208
232
|
return {
|
|
209
|
-
threads: threads.map((thread) =>
|
|
210
|
-
|
|
211
|
-
subject: thread.subject === '' ? '(no subject)' : thread.subject,
|
|
212
|
-
sender: thread.participants.find((address) => !own.has(address.toLowerCase())) ??
|
|
233
|
+
threads: threads.map((thread) => {
|
|
234
|
+
const sender = thread.participants.find((address) => !own.has(address.toLowerCase())) ??
|
|
213
235
|
thread.participants[0] ??
|
|
214
|
-
'(nobody)'
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
236
|
+
'(nobody)';
|
|
237
|
+
const read = reading.get(thread.id);
|
|
238
|
+
return {
|
|
239
|
+
id: thread.id,
|
|
240
|
+
subject: thread.subject === '' ? '(no subject)' : thread.subject,
|
|
241
|
+
sender,
|
|
242
|
+
/*
|
|
243
|
+
* The person, not the address: the display name on their latest
|
|
244
|
+
* message when they gave one (host API 1.30's reading pane), the
|
|
245
|
+
* address otherwise.
|
|
246
|
+
*/
|
|
247
|
+
senderName: read?.senderName && read.senderAddress?.toLowerCase() === sender.toLowerCase() ? read.senderName : sender,
|
|
248
|
+
// What the conversation last said, on one line; the owner's own words say so.
|
|
249
|
+
preview: read ? (read.lastOut ? `You: ${read.snippet}` : read.snippet) : '',
|
|
250
|
+
unread: read?.unread ?? false,
|
|
251
|
+
// Mail Triage's word for the latest message, as a chip: "Bill", "Receipt".
|
|
252
|
+
tag: read?.category && read.category !== 'other' ? tagLabel(read.category) : '',
|
|
253
|
+
participants: thread.participants.join(', '),
|
|
254
|
+
state: thread.state,
|
|
255
|
+
/*
|
|
256
|
+
* The state as the owner reads it (`needs-you.ts`): "Waiting on you"
|
|
257
|
+
* only when the one rule says so. A notification and a message
|
|
258
|
+
* nobody expects an answer to carry no pill at all — a word on every
|
|
259
|
+
* row is how forty "Waiting on you" pills came to mean nothing.
|
|
260
|
+
*/
|
|
261
|
+
attention: viewOf(reasons.get(thread.id) ?? reasonOf(null, thread.state)),
|
|
262
|
+
pill: listPillOf(viewOf(reasons.get(thread.id) ?? reasonOf(null, thread.state))),
|
|
263
|
+
// The "draft" pill sits *beside* the state, never in place of it: a
|
|
264
|
+
// conversation that is waiting on the owner and has a reply written
|
|
265
|
+
// for it is two facts, and the old page showed both.
|
|
266
|
+
draftPill: withDraft.has(thread.id) ? 'draft' : '',
|
|
267
|
+
when: relative(thread.lastAt, now),
|
|
268
|
+
messageCount: thread.messageCount,
|
|
269
|
+
};
|
|
270
|
+
}),
|
|
232
271
|
...hits,
|
|
233
272
|
};
|
|
234
273
|
},
|
|
235
274
|
};
|
|
236
275
|
}
|
|
276
|
+
/** Triage's categories as a chip says them. Anything else reads as itself, capitalised. */
|
|
277
|
+
const TAG_WORDS = {
|
|
278
|
+
'reply-needed': 'Reply needed',
|
|
279
|
+
'payment-failed': 'Payment failed',
|
|
280
|
+
'bank-notice': 'Bank',
|
|
281
|
+
'service-notice': 'Service',
|
|
282
|
+
promo: 'Promotion',
|
|
283
|
+
};
|
|
284
|
+
export function tagLabel(category) {
|
|
285
|
+
const known = TAG_WORDS[category];
|
|
286
|
+
if (known)
|
|
287
|
+
return known;
|
|
288
|
+
const words = category.replace(/-/g, ' ').trim();
|
|
289
|
+
return words === '' ? '' : words[0].toUpperCase() + words.slice(1);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* What the list draws beside each conversation, in one read: how its last
|
|
293
|
+
* message opens, the name on the latest message they sent, whether anything
|
|
294
|
+
* they sent is still unread on the server (no `\Seen`, as the flag sync last
|
|
295
|
+
* saw it), and Mail Triage's latest category.
|
|
296
|
+
*/
|
|
297
|
+
async function listReading(db, ids) {
|
|
298
|
+
const out = new Map();
|
|
299
|
+
if (ids.length === 0)
|
|
300
|
+
return out;
|
|
301
|
+
const { rows } = await db.query(`select t.id,
|
|
302
|
+
lm.snippet, lm.direction as last_direction,
|
|
303
|
+
li.from_name, li.from_addr,
|
|
304
|
+
exists (select 1 from email.messages u
|
|
305
|
+
where u.thread_id = t.id and u.direction = 'in'
|
|
306
|
+
and not (coalesce(u.flags, '[]'::jsonb) ? $2)) as unread,
|
|
307
|
+
(select tr.category from email.triage tr
|
|
308
|
+
where tr.message_id = li.id
|
|
309
|
+
order by tr.decided_at desc, tr.processing_version desc limit 1) as category
|
|
310
|
+
from email.threads t
|
|
311
|
+
left join email.messages lm on lm.id = t.last_message_id
|
|
312
|
+
left join lateral (
|
|
313
|
+
select m.id, m.from_name, m.from_addr from email.messages m
|
|
314
|
+
where m.thread_id = t.id and m.direction = 'in'
|
|
315
|
+
order by coalesce(m.internal_date, m.fetched_at) desc, m.id desc limit 1
|
|
316
|
+
) li on true
|
|
317
|
+
where t.id = any($1::uuid[])`, [ids, SEEN]);
|
|
318
|
+
for (const row of rows) {
|
|
319
|
+
out.set(String(row.id), {
|
|
320
|
+
snippet: String(row.snippet ?? ''),
|
|
321
|
+
lastOut: row.last_direction === 'out',
|
|
322
|
+
senderName: typeof row.from_name === 'string' && row.from_name.trim() !== '' ? row.from_name.trim() : null,
|
|
323
|
+
senderAddress: typeof row.from_addr === 'string' ? row.from_addr : null,
|
|
324
|
+
unread: row.unread === true,
|
|
325
|
+
category: typeof row.category === 'string' ? row.category : null,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
return out;
|
|
329
|
+
}
|
|
330
|
+
/** One address as the `message` component reads it. */
|
|
331
|
+
function addressRow(address, name) {
|
|
332
|
+
return name ? { address, name } : { address };
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* The parts of a conversation's reading pane that are buddi's rather than the
|
|
336
|
+
* mail's: Mail Triage's verdict on the latest message they sent, and what
|
|
337
|
+
* buddi changed in the mailbox about this conversation, newest first, with
|
|
338
|
+
* Undo where it still applies (the same rows and words as Recent changes).
|
|
339
|
+
*/
|
|
340
|
+
async function threadLayer(db, threadId, accountAddress, now) {
|
|
341
|
+
const verdict = await db.query(`select tr.category, tr.urgency, tr.summary, tr.action_needed, tr.decided_at
|
|
342
|
+
from email.triage tr
|
|
343
|
+
join lateral (
|
|
344
|
+
select m.id from email.messages m
|
|
345
|
+
where m.thread_id = $1::uuid and m.direction = 'in'
|
|
346
|
+
order by coalesce(m.internal_date, m.fetched_at) desc, m.id desc limit 1
|
|
347
|
+
) li on li.id = tr.message_id
|
|
348
|
+
order by tr.decided_at desc, tr.processing_version desc limit 1`, [threadId]);
|
|
349
|
+
const v = verdict.rows[0];
|
|
350
|
+
const triage = v
|
|
351
|
+
? {
|
|
352
|
+
category: String(v.category),
|
|
353
|
+
tag: tagLabel(String(v.category)),
|
|
354
|
+
urgency: String(v.urgency),
|
|
355
|
+
// "Bill · normal — The October invoice from Studio North, €1,240. To do: pay by 14 Oct."
|
|
356
|
+
line: [
|
|
357
|
+
`${tagLabel(String(v.category))} · ${v.urgency === 'urgent' ? 'urgent' : v.urgency === 'low' ? 'low' : 'this week'}`,
|
|
358
|
+
'—',
|
|
359
|
+
String(v.summary ?? '').trim(),
|
|
360
|
+
v.action_needed ? `To do: ${String(v.action_needed).trim()}` : '',
|
|
361
|
+
]
|
|
362
|
+
.filter((part) => part !== '')
|
|
363
|
+
.join(' '),
|
|
364
|
+
when: relative(isoOf(v.decided_at), now),
|
|
365
|
+
}
|
|
366
|
+
: null;
|
|
367
|
+
const { rows } = await db.query(`select ${ACTION_COLUMNS_SQL} from email.mailbox_actions a
|
|
368
|
+
where a.message_ids && (select coalesce(array_agg(m.id), '{}') from email.messages m where m.thread_id = $1::uuid)
|
|
369
|
+
order by a.created_at desc, a.seq desc limit $2`, [threadId, THREAD_CHANGES]);
|
|
370
|
+
const changes = [];
|
|
371
|
+
for (const c of rows.map(toAction)) {
|
|
372
|
+
const undoable = undoRefusal(c) === null;
|
|
373
|
+
const moved = undoable ? await movedSince(db, c) : 0;
|
|
374
|
+
const who = c.origin === 'policy' ? `by ${c.actor}` : c.origin === 'owner' ? 'by you' : c.actor === TRIAGE_AGENT_ID ? 'by Mail Triage' : `by @${c.actor}`;
|
|
375
|
+
changes.push({
|
|
376
|
+
id: c.id,
|
|
377
|
+
// The words Recent changes uses: "Mark as read · by Mail Triage · yesterday".
|
|
378
|
+
line: [verbOf(c.kind, c.destination), who, relative(c.createdAt, now), c.note ?? ''].filter((p) => p !== '').join(' · '),
|
|
379
|
+
state: changeState(c),
|
|
380
|
+
undoable,
|
|
381
|
+
undoLine: describeUndo(c, accountAddress, moved),
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
return { triage, changes };
|
|
385
|
+
}
|
|
237
386
|
/**
|
|
238
387
|
* The list's pill for a conversation: the views that are worth a word.
|
|
239
388
|
* A notification and "they wrote" are the inbox's ordinary weather and say
|
|
@@ -302,6 +451,26 @@ async function searchHits(ctx, input, ids) {
|
|
|
302
451
|
...(built.windowed && built.windowFrom ? { window: windowNote(built.windowFrom) } : {}),
|
|
303
452
|
};
|
|
304
453
|
}
|
|
454
|
+
/** How many of buddi's changes a reading pane lists for one conversation. */
|
|
455
|
+
export const THREAD_CHANGES = 3;
|
|
456
|
+
const ACTION_COLUMNS_SQL = ACTION_COLUMNS.split(',').map((c) => `a.${c.trim()}`).join(', ');
|
|
457
|
+
/** The display name, the server's own arrival time and the read mark of each message, by id. */
|
|
458
|
+
async function messageExtras(db, ids) {
|
|
459
|
+
const out = new Map();
|
|
460
|
+
if (ids.length === 0)
|
|
461
|
+
return out;
|
|
462
|
+
const { rows } = await db.query(`select id, from_name, coalesce(internal_date, fetched_at) as at, direction,
|
|
463
|
+
coalesce(flags, '[]'::jsonb) ? $2 as seen
|
|
464
|
+
from email.messages where id = any($1::uuid[])`, [ids, SEEN]);
|
|
465
|
+
for (const row of rows) {
|
|
466
|
+
out.set(String(row.id), {
|
|
467
|
+
fromName: typeof row.from_name === 'string' && row.from_name.trim() !== '' ? row.from_name.trim() : null,
|
|
468
|
+
at: isoOf(row.at),
|
|
469
|
+
unread: row.direction === 'in' && row.seen !== true,
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
return out;
|
|
473
|
+
}
|
|
305
474
|
/**
|
|
306
475
|
* One conversation: its messages' snippets, then the drafts under them.
|
|
307
476
|
*
|
|
@@ -327,8 +496,23 @@ export function threadQuery() {
|
|
|
327
496
|
const live = drafts.filter((d) => LIVE_DRAFT_STATUSES.includes(d.status));
|
|
328
497
|
const older = drafts.filter((d) => !LIVE_DRAFT_STATUSES.includes(d.status));
|
|
329
498
|
const latest = messages[messages.length - 1] ?? null;
|
|
499
|
+
const accounts = await listAccounts(ctx.buddi.db, { enabledOnly: false });
|
|
500
|
+
const account = accounts.find((a) => a.id === thread.accountId);
|
|
501
|
+
const layer = await threadLayer(ctx.buddi.db, thread.id, account?.address ?? 'your mailbox', now);
|
|
502
|
+
const extra = await messageExtras(ctx.buddi.db, messages.map((m) => m.id));
|
|
503
|
+
const view = viewOf(reason);
|
|
330
504
|
return {
|
|
331
505
|
id: thread.id,
|
|
506
|
+
/*
|
|
507
|
+
* buddi's layer above the thread (host API 1.30's reading pane): the
|
|
508
|
+
* verdict, what was changed and Undo, and "Needs a reply" with Done.
|
|
509
|
+
*/
|
|
510
|
+
hasTriage: layer.triage !== null,
|
|
511
|
+
triage: layer.triage,
|
|
512
|
+
triageLine: layer.triage ? String(layer.triage.line) : '',
|
|
513
|
+
changes: layer.changes,
|
|
514
|
+
hasChanges: layer.changes.length > 0,
|
|
515
|
+
needsReply: view === 'needs-you',
|
|
332
516
|
subject: thread.subject === '' ? '(no subject)' : thread.subject,
|
|
333
517
|
state: thread.state,
|
|
334
518
|
attention: viewOf(reason),
|
|
@@ -337,32 +521,41 @@ export function threadQuery() {
|
|
|
337
521
|
participants: thread.participants.join(', '),
|
|
338
522
|
lastAt: thread.lastAt,
|
|
339
523
|
messageCount: thread.messageCount,
|
|
340
|
-
messages: messages.map((message) =>
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
message.
|
|
353
|
-
message.
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
524
|
+
messages: messages.map((message, index) => {
|
|
525
|
+
const more = extra.get(message.id);
|
|
526
|
+
return {
|
|
527
|
+
id: message.id,
|
|
528
|
+
// The header the reading pane draws before the body arrives (`message`).
|
|
529
|
+
from: addressRow(message.from, more?.fromName),
|
|
530
|
+
to: message.to.map((address) => addressRow(address)),
|
|
531
|
+
at: more?.at ?? message.date,
|
|
532
|
+
// Every message but the newest is one line until it is opened, unless the owner has not read it.
|
|
533
|
+
folded: index < messages.length - 1 && !(more?.unread ?? false),
|
|
534
|
+
fromAddress: message.from,
|
|
535
|
+
snippet: message.snippet,
|
|
536
|
+
who: message.direction === 'out' ? 'you wrote' : 'they wrote',
|
|
537
|
+
when: relative(message.date, now),
|
|
538
|
+
// Where it is now when that is not the inbox: archived, in Trash,
|
|
539
|
+
// in a label, or no longer in the inbox (moved in another app).
|
|
540
|
+
place: message.place,
|
|
541
|
+
// One line, because a repeated component draws text and formats
|
|
542
|
+
// nothing: who wrote it, when, where it is now, and what it opens with.
|
|
543
|
+
summary: [
|
|
544
|
+
message.from,
|
|
545
|
+
message.direction === 'out' ? 'you wrote' : 'they wrote',
|
|
546
|
+
relative(message.date, now),
|
|
547
|
+
message.place,
|
|
548
|
+
]
|
|
549
|
+
.filter((part) => part !== '')
|
|
550
|
+
.join(' · ') + (message.snippet ? ` — ${message.snippet}` : ''),
|
|
551
|
+
};
|
|
552
|
+
}),
|
|
360
553
|
latestMessageId: latest?.id ?? null,
|
|
361
554
|
hasMessages: messages.length > 0,
|
|
362
555
|
hasDraft: live.length > 0,
|
|
363
556
|
// Every live draft: the page draws an editor per row, so each row is
|
|
364
557
|
// the whole envelope rather than a line about one.
|
|
365
|
-
drafts: live.map((draft) => draftRow(draft, now)),
|
|
558
|
+
drafts: live.map((draft) => draftRow(draft, now, account?.address)),
|
|
366
559
|
hasOlder: older.length > 0,
|
|
367
560
|
older: older.map((draft) => ({
|
|
368
561
|
id: draft.id,
|
|
@@ -401,8 +594,9 @@ export function messageQuery() {
|
|
|
401
594
|
params: byId,
|
|
402
595
|
async produce(params, ctx) {
|
|
403
596
|
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
|
|
597
|
+
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,
|
|
598
|
+
m.body_text, m.body_html, m.body_purged_at, m.attachments, m.snippet,
|
|
599
|
+
coalesce(m.internal_date, m.fetched_at) as at
|
|
406
600
|
from email.messages m
|
|
407
601
|
join email.accounts a on a.id = m.account_id
|
|
408
602
|
where m.id = $1::uuid`, [id]);
|
|
@@ -411,20 +605,35 @@ export function messageQuery() {
|
|
|
411
605
|
throw new QueryRefusal('No message here has that id.');
|
|
412
606
|
const messageId = String(row.id);
|
|
413
607
|
const purged = row.body_purged_at !== null;
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
608
|
+
const purgedNote = 'The body of this message has been purged under your retention setting. Its headers are kept.';
|
|
609
|
+
const html = !purged && typeof row.body_html === 'string' && row.body_html !== '' ? row.body_html : null;
|
|
610
|
+
const text = purged ? '' : truncateBody(String(row.body_text ?? ''), html ? TEXT_WITH_HTML_BYTES : MAX_BODY_BYTES);
|
|
611
|
+
const toList = Array.isArray(row.to_addrs) ? row.to_addrs : [];
|
|
612
|
+
const ccList = Array.isArray(row.cc) ? row.cc : [];
|
|
417
613
|
return {
|
|
418
614
|
id: messageId,
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
615
|
+
/*
|
|
616
|
+
* The `message` component's shape (host API 1.30): who, to whom,
|
|
617
|
+
* when (the server's arrival time, as the thread orders by), the
|
|
618
|
+
* stored HTML — sanitised at ingest, and again by the dashboard — and
|
|
619
|
+
* the text it falls back to. Never anything fetched now.
|
|
620
|
+
*/
|
|
621
|
+
from: addressRow(String(row.from_addr), typeof row.from_name === 'string' ? row.from_name : null),
|
|
622
|
+
to: toList.map((address) => addressRow(address)),
|
|
623
|
+
cc: ccList.map((address) => addressRow(address)),
|
|
624
|
+
at: isoOf(row.at) ?? isoOf(row.date),
|
|
625
|
+
html,
|
|
626
|
+
text: purged ? null : text,
|
|
627
|
+
snippet: row.snippet ?? '',
|
|
628
|
+
note: purged ? purgedNote : null,
|
|
629
|
+
toText: toList.join(', '),
|
|
630
|
+
ccText: ccList.join(', '),
|
|
422
631
|
subject: row.subject ?? '',
|
|
423
632
|
date: isoOf(row.date),
|
|
424
633
|
who: row.direction === 'out' ? 'you wrote' : 'they wrote',
|
|
425
|
-
//
|
|
426
|
-
//
|
|
427
|
-
|
|
634
|
+
// The body rides once, as `text` (null once retention purged it, with
|
|
635
|
+
// `note` saying so): a second copy would put a long message over the
|
|
636
|
+
// gateway's megabyte per answer.
|
|
428
637
|
purged,
|
|
429
638
|
attachments: attachmentRows(messageId, row.attachments),
|
|
430
639
|
};
|
|
@@ -483,10 +692,18 @@ export function accountsQuery() {
|
|
|
483
692
|
async produce(_params, ctx) {
|
|
484
693
|
const now = ctx.buddi.clock.now();
|
|
485
694
|
const accounts = await listAccounts(ctx.buddi.db, { enabledOnly: false });
|
|
486
|
-
|
|
695
|
+
// When each mailbox last *finished* a poll: "connected, synced 3 min
|
|
696
|
+
// ago" is true of a quiet mailbox too, where "when mail last landed"
|
|
697
|
+
// read "no mail has arrived yet" on the day it was connected.
|
|
698
|
+
const synced = await lastSyncedByAccount(ctx.buddi.db);
|
|
487
699
|
const waiting = await triageWaitingByAccount(ctx.buddi.db);
|
|
488
700
|
const needed = await passwordsNeeded(accounts, ctx);
|
|
701
|
+
const { rows: storedRows } = await ctx.buddi.db.query(`select a.id from email.accounts a where exists (select 1 from email.messages m where m.account_id = a.id)`);
|
|
702
|
+
const stored = new Set(storedRows.map((row) => String(row.id)));
|
|
489
703
|
return {
|
|
704
|
+
// A connected mailbox with nothing stored yet: the Mail page's "Read
|
|
705
|
+
// the last 7 days" lands here, and the note it lands on reads this.
|
|
706
|
+
anyFresh: accounts.some((account) => account.enabled && !stored.has(account.id)),
|
|
490
707
|
/*
|
|
491
708
|
* Whether new mail has anybody to triage it. `needs-agent` is what
|
|
492
709
|
* the page's offer line is drawn against: a mailbox, and no agent
|
|
@@ -522,9 +739,11 @@ export function accountsQuery() {
|
|
|
522
739
|
: idleLive(account.id)
|
|
523
740
|
? 'Instant'
|
|
524
741
|
: `Checking every ${Math.round(POLL_EVERY_SECONDS / 60)} min`,
|
|
525
|
-
lastSync:
|
|
526
|
-
?
|
|
527
|
-
:
|
|
742
|
+
lastSync: !account.enabled
|
|
743
|
+
? '—'
|
|
744
|
+
: synced.get(account.id)
|
|
745
|
+
? relative(synced.get(account.id).toISOString(), now)
|
|
746
|
+
: 'not yet',
|
|
528
747
|
/*
|
|
529
748
|
* Facts about a mailbox, not one sentence to be parsed: whether
|
|
530
749
|
* buddi is reading it, and whether it is a mailbox `.env` used to
|
|
@@ -534,9 +753,13 @@ export function accountsQuery() {
|
|
|
534
753
|
* carry the tone.
|
|
535
754
|
*/
|
|
536
755
|
state: [
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
756
|
+
// Connected once a poll has finished with the password it has;
|
|
757
|
+
// until the first one, "connecting".
|
|
758
|
+
!account.enabled
|
|
759
|
+
? { value: 'off', tone: 'warning' }
|
|
760
|
+
: synced.get(account.id) && !needed.has(account.id)
|
|
761
|
+
? { value: 'connected', tone: 'neutral' }
|
|
762
|
+
: { value: needed.has(account.id) ? 'on' : 'connecting', tone: 'neutral' },
|
|
540
763
|
// A mailbox `.env` used to name that could not be adopted is a
|
|
541
764
|
// password nobody can read here: Set password brings it back.
|
|
542
765
|
...(account.addedVia === 'env' ? [{ value: 'password needed', tone: 'neutral' }] : []),
|
|
@@ -548,6 +771,78 @@ export function accountsQuery() {
|
|
|
548
771
|
},
|
|
549
772
|
};
|
|
550
773
|
}
|
|
774
|
+
/**
|
|
775
|
+
* The Mail page's own read: which mailboxes are connected, and which of them
|
|
776
|
+
* are fresh — connected, a first poll finished, and nothing stored yet. A
|
|
777
|
+
* fresh mailbox gets a first state instead of an empty list ("Connected to
|
|
778
|
+
* you@example.com. Reading new mail from now on; 412 older messages left
|
|
779
|
+
* alone."), because "No conversations here" on the day you connect reads as a
|
|
780
|
+
* fault. Until that first poll has finished nothing is known about what was
|
|
781
|
+
* left alone, so the page says "Connecting to you@example.com…" instead.
|
|
782
|
+
*/
|
|
783
|
+
export function mailStatusQuery() {
|
|
784
|
+
return {
|
|
785
|
+
name: 'mail_status',
|
|
786
|
+
params: noParams,
|
|
787
|
+
async produce(_params, ctx) {
|
|
788
|
+
const accounts = await listAccounts(ctx.buddi.db, { enabledOnly: true });
|
|
789
|
+
// The conversation list reads every mailbox, a disabled one's retained
|
|
790
|
+
// conversations included; whether there is mail to list asks the same.
|
|
791
|
+
const everyId = (await listAccounts(ctx.buddi.db, { enabledOnly: false })).map((account) => account.id);
|
|
792
|
+
const { rows } = await ctx.buddi.db.query(`select a.id,
|
|
793
|
+
exists (select 1 from email.messages m where m.account_id = a.id) as stored,
|
|
794
|
+
(a.last_synced_at is not null
|
|
795
|
+
or exists (select 1 from email.folders f
|
|
796
|
+
where f.account_id = a.id and f.first_contact_at is not null)) as polled,
|
|
797
|
+
(select f.left_alone from email.folders f
|
|
798
|
+
where f.account_id = a.id and f.kind = 'inbox' order by f.first_contact_at nulls last limit 1) as left_alone
|
|
799
|
+
from email.accounts a where a.enabled`);
|
|
800
|
+
const facts = new Map(rows.map((row) => [String(row.id), row]));
|
|
801
|
+
const empty = accounts.filter((account) => facts.get(account.id)?.stored !== true);
|
|
802
|
+
const fresh = empty.filter((account) => facts.get(account.id)?.polled === true);
|
|
803
|
+
const connecting = empty.filter((account) => facts.get(account.id)?.polled !== true);
|
|
804
|
+
const mail = everyId.length === 0
|
|
805
|
+
? { rows: [] }
|
|
806
|
+
: await ctx.buddi.db.query(`select exists (select 1 from email.messages where account_id = any($1::uuid[])) as has_mail`, [everyId]);
|
|
807
|
+
const hasMail = mail.rows[0]?.has_mail === true;
|
|
808
|
+
return {
|
|
809
|
+
connected: accounts.length
|
|
810
|
+
? `Connected: ${accounts.map((account) => account.address).join(' · ')}`
|
|
811
|
+
: '',
|
|
812
|
+
hasAccounts: accounts.length > 0,
|
|
813
|
+
anyFresh: fresh.length > 0,
|
|
814
|
+
anyConnecting: connecting.length > 0,
|
|
815
|
+
connecting: connecting.length > 0 ? connectingLine(connecting.map((account) => account.address)) : '',
|
|
816
|
+
hasMail,
|
|
817
|
+
// The list is drawn when there is mail to list, or nothing connected
|
|
818
|
+
// at all (its empty sentence is then the honest one).
|
|
819
|
+
showList: hasMail || accounts.length === 0,
|
|
820
|
+
fresh: fresh.map((account) => ({
|
|
821
|
+
id: account.id,
|
|
822
|
+
address: account.address,
|
|
823
|
+
line: freshLine(account.address, facts.get(account.id)?.left_alone),
|
|
824
|
+
})),
|
|
825
|
+
};
|
|
826
|
+
},
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
/** What the page says while a mailbox's first poll has not finished. */
|
|
830
|
+
export function connectingLine(addresses) {
|
|
831
|
+
const list = addresses.length <= 1
|
|
832
|
+
? (addresses[0] ?? '')
|
|
833
|
+
: `${addresses.slice(0, -1).join(', ')} and ${addresses[addresses.length - 1]}`;
|
|
834
|
+
return `Connecting to ${list}…`;
|
|
835
|
+
}
|
|
836
|
+
/** The first-state sentence for one fresh mailbox. */
|
|
837
|
+
export function freshLine(address, leftAlone) {
|
|
838
|
+
const older = leftAlone === null || leftAlone === undefined ? null : Number(leftAlone);
|
|
839
|
+
const head = `Connected to ${address}. Reading new mail from now on`;
|
|
840
|
+
if (older === null || !Number.isFinite(older))
|
|
841
|
+
return `${head}; older messages left alone.`;
|
|
842
|
+
if (older === 0)
|
|
843
|
+
return `${head}.`;
|
|
844
|
+
return `${head}; ${older.toLocaleString('en-US')} older ${older === 1 ? 'message' : 'messages'} left alone.`;
|
|
845
|
+
}
|
|
551
846
|
/**
|
|
552
847
|
* How many of this plugin's rules wait on Settings → Proposals. Zero on an
|
|
553
848
|
* installation whose core has no proposals table yet.
|
|
@@ -846,6 +1141,7 @@ export function emailPageQueries() {
|
|
|
846
1141
|
draftQuery(),
|
|
847
1142
|
messageQuery(),
|
|
848
1143
|
accountsQuery(),
|
|
1144
|
+
mailStatusQuery(),
|
|
849
1145
|
policiesQuery(),
|
|
850
1146
|
ruleThreadsQuery(),
|
|
851
1147
|
watcherSettingsQuery(),
|