@withbuddi/buddi 0.1.0-pre.27 → 0.1.0-pre.28
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/extension/manifest.json +2 -2
- package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/cli/dist/commands.d.ts +10 -0
- package/node_modules/@buddi/cli/dist/commands.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/commands.js +237 -18
- 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 +3 -7
- package/node_modules/@buddi/cli/dist/doctor-probes.js.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor.d.ts +13 -0
- package/node_modules/@buddi/cli/dist/doctor.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor.js +18 -0
- package/node_modules/@buddi/cli/dist/doctor.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 +3 -2
- 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.d.ts +3 -0
- package/node_modules/@buddi/core/dist/agents/catalog.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/agents/catalog.js +1 -0
- package/node_modules/@buddi/core/dist/agents/catalog.js.map +1 -1
- package/node_modules/@buddi/core/dist/agents/edit.d.ts +3 -0
- package/node_modules/@buddi/core/dist/agents/edit.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/agents/edit.js +3 -1
- package/node_modules/@buddi/core/dist/agents/edit.js.map +1 -1
- package/node_modules/@buddi/core/dist/agents/frontmatter.d.ts +10 -0
- package/node_modules/@buddi/core/dist/agents/frontmatter.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/agents/frontmatter.js +7 -0
- package/node_modules/@buddi/core/dist/agents/frontmatter.js.map +1 -1
- package/node_modules/@buddi/core/dist/agents/idle-rollover.d.ts +20 -0
- package/node_modules/@buddi/core/dist/agents/idle-rollover.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/agents/idle-rollover.js +30 -0
- package/node_modules/@buddi/core/dist/agents/idle-rollover.js.map +1 -0
- package/node_modules/@buddi/core/dist/agents/index.d.ts +1 -0
- package/node_modules/@buddi/core/dist/agents/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/agents/index.js +1 -0
- package/node_modules/@buddi/core/dist/agents/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/backup/dump.d.ts +9 -0
- package/node_modules/@buddi/core/dist/backup/dump.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/backup/dump.js +10 -1
- package/node_modules/@buddi/core/dist/backup/dump.js.map +1 -1
- package/node_modules/@buddi/core/dist/backup/pending.d.ts +13 -0
- package/node_modules/@buddi/core/dist/backup/pending.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/backup/pending.js +56 -4
- package/node_modules/@buddi/core/dist/backup/pending.js.map +1 -1
- package/node_modules/@buddi/core/dist/backup/restore.d.ts +3 -1
- package/node_modules/@buddi/core/dist/backup/restore.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/backup/restore.js +1 -1
- package/node_modules/@buddi/core/dist/backup/restore.js.map +1 -1
- package/node_modules/@buddi/core/dist/feedback/index.d.ts +108 -0
- package/node_modules/@buddi/core/dist/feedback/index.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/feedback/index.js +160 -0
- package/node_modules/@buddi/core/dist/feedback/index.js.map +1 -0
- package/node_modules/@buddi/core/dist/host/build.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/host/build.js +28 -1
- package/node_modules/@buddi/core/dist/host/build.js.map +1 -1
- package/node_modules/@buddi/core/dist/host/types.d.ts +29 -2
- package/node_modules/@buddi/core/dist/host/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/index.d.ts +1 -0
- package/node_modules/@buddi/core/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/index.js +1 -0
- package/node_modules/@buddi/core/dist/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/learning/policies.d.ts +7 -1
- package/node_modules/@buddi/core/dist/learning/policies.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/learning/policies.js +4 -1
- package/node_modules/@buddi/core/dist/learning/policies.js.map +1 -1
- package/node_modules/@buddi/core/dist/learning/store.d.ts +29 -1
- package/node_modules/@buddi/core/dist/learning/store.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/learning/store.js +33 -8
- package/node_modules/@buddi/core/dist/learning/store.js.map +1 -1
- package/node_modules/@buddi/core/dist/learning/types.d.ts +24 -1
- package/node_modules/@buddi/core/dist/learning/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/learning/types.js +6 -0
- package/node_modules/@buddi/core/dist/learning/types.js.map +1 -1
- package/node_modules/@buddi/core/dist/owner.d.ts +2 -1
- package/node_modules/@buddi/core/dist/owner.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/owner.js.map +1 -1
- package/node_modules/@buddi/core/dist/pages.d.ts +27 -0
- package/node_modules/@buddi/core/dist/pages.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/pages.js +24 -3
- package/node_modules/@buddi/core/dist/pages.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.d.ts +5 -4
- 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/registry.d.ts +10 -1
- package/node_modules/@buddi/core/dist/registry.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/registry.js +13 -0
- package/node_modules/@buddi/core/dist/registry.js.map +1 -1
- package/node_modules/@buddi/core/dist/sources/index.d.ts +1 -0
- package/node_modules/@buddi/core/dist/sources/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/sources/index.js +1 -0
- package/node_modules/@buddi/core/dist/sources/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/sources/watch.d.ts +37 -0
- package/node_modules/@buddi/core/dist/sources/watch.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/sources/watch.js +81 -0
- package/node_modules/@buddi/core/dist/sources/watch.js.map +1 -0
- package/node_modules/@buddi/core/dist/tools.d.ts +47 -0
- package/node_modules/@buddi/core/dist/tools.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/tools.js.map +1 -1
- package/node_modules/@buddi/core/migrations/056_dashboard_sessions.sql +37 -0
- package/node_modules/@buddi/core/migrations/057_proposal_decided_by.sql +34 -0
- package/node_modules/@buddi/core/migrations/058_message_feedback.sql +50 -0
- package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/gateway/dist/agents/learning-digest.d.ts +7 -1
- package/node_modules/@buddi/gateway/dist/agents/learning-digest.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/learning-digest.js +29 -3
- package/node_modules/@buddi/gateway/dist/agents/learning-digest.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform-files.d.ts +2 -0
- package/node_modules/@buddi/gateway/dist/agents/platform-files.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform-files.js +2 -0
- package/node_modules/@buddi/gateway/dist/agents/platform-files.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform.d.ts +20 -0
- package/node_modules/@buddi/gateway/dist/agents/platform.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/platform.js +46 -3
- package/node_modules/@buddi/gateway/dist/agents/platform.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents-cli.d.ts +1 -1
- package/node_modules/@buddi/gateway/dist/agents-cli.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents-cli.js +12 -2
- package/node_modules/@buddi/gateway/dist/agents-cli.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/chat/session.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/chat/session.js +2 -1
- package/node_modules/@buddi/gateway/dist/chat/session.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/mcp/requests.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/mcp/requests.js +1 -0
- package/node_modules/@buddi/gateway/dist/mcp/requests.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/approve.js +4 -1
- package/node_modules/@buddi/gateway/dist/plugins/approve.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/paths.d.ts +14 -0
- package/node_modules/@buddi/gateway/dist/plugins/paths.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/paths.js +27 -1
- package/node_modules/@buddi/gateway/dist/plugins/paths.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/stage.d.ts +27 -3
- package/node_modules/@buddi/gateway/dist/plugins/stage.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/stage.js +35 -5
- package/node_modules/@buddi/gateway/dist/plugins/stage.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins-cli.d.ts +4 -0
- package/node_modules/@buddi/gateway/dist/plugins-cli.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins-cli.js +42 -9
- package/node_modules/@buddi/gateway/dist/plugins-cli.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.js +14 -2
- package/node_modules/@buddi/gateway/dist/serve.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-continuation.d.ts +2 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-continuation.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-continuation.js +8 -5
- package/node_modules/@buddi/gateway/dist/surfaces/browser-continuation.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-handoff.d.ts +27 -4
- package/node_modules/@buddi/gateway/dist/surfaces/browser-handoff.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/browser-handoff.js +57 -7
- package/node_modules/@buddi/gateway/dist/surfaces/browser-handoff.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/carry-over.d.ts +89 -0
- package/node_modules/@buddi/gateway/dist/surfaces/carry-over.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/surfaces/carry-over.js +172 -0
- package/node_modules/@buddi/gateway/dist/surfaces/carry-over.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/surfaces/conversation-lifetime.d.ts +5 -2
- package/node_modules/@buddi/gateway/dist/surfaces/conversation-lifetime.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/conversation-lifetime.js +5 -2
- package/node_modules/@buddi/gateway/dist/surfaces/conversation-lifetime.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/api.d.ts +34 -2
- package/node_modules/@buddi/gateway/dist/telegram/api.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/api.js +15 -2
- package/node_modules/@buddi/gateway/dist/telegram/api.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/env-owner.d.ts +30 -0
- package/node_modules/@buddi/gateway/dist/telegram/env-owner.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/telegram/env-owner.js +45 -0
- package/node_modules/@buddi/gateway/dist/telegram/env-owner.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/telegram/main.d.ts +0 -2
- package/node_modules/@buddi/gateway/dist/telegram/main.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/main.js +18 -25
- package/node_modules/@buddi/gateway/dist/telegram/main.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/notify.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/notify.js +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/notify.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts +2 -2
- package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/outbound.js +12 -3
- package/node_modules/@buddi/gateway/dist/telegram/outbound.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/reactions.d.ts +45 -0
- package/node_modules/@buddi/gateway/dist/telegram/reactions.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/telegram/reactions.js +97 -0
- package/node_modules/@buddi/gateway/dist/telegram/reactions.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts +1 -0
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.js +80 -9
- package/node_modules/@buddi/gateway/dist/telegram/surface.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/agents.d.ts +3 -1
- package/node_modules/@buddi/gateway/dist/web/agents.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/agents.js +20 -2
- package/node_modules/@buddi/gateway/dist/web/agents.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts +10 -3
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.js +18 -5
- package/node_modules/@buddi/gateway/dist/web/chat.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/plugins.d.ts +6 -1
- package/node_modules/@buddi/gateway/dist/web/plugins.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/plugins.js +31 -2
- package/node_modules/@buddi/gateway/dist/web/plugins.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/proposals.d.ts +21 -0
- package/node_modules/@buddi/gateway/dist/web/proposals.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/proposals.js +50 -1
- package/node_modules/@buddi/gateway/dist/web/proposals.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/read.d.ts +6 -0
- package/node_modules/@buddi/gateway/dist/web/read.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/read.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/recovery.d.ts +19 -2
- package/node_modules/@buddi/gateway/dist/web/recovery.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/recovery.js +148 -7
- package/node_modules/@buddi/gateway/dist/web/recovery.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.js +87 -29
- package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/sessions.d.ts +81 -7
- package/node_modules/@buddi/gateway/dist/web/sessions.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/sessions.js +242 -24
- package/node_modules/@buddi/gateway/dist/web/sessions.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts +46 -0
- package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/signed-out.js +99 -0
- package/node_modules/@buddi/gateway/dist/web/signed-out.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/tailscale.d.ts +13 -0
- package/node_modules/@buddi/gateway/dist/web/tailscale.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/tailscale.js +12 -0
- package/node_modules/@buddi/gateway/dist/web/tailscale.js.map +1 -1
- package/node_modules/@buddi/install/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/install/dist/backup.d.ts +18 -0
- package/node_modules/@buddi/install/dist/backup.d.ts.map +1 -1
- package/node_modules/@buddi/install/dist/backup.js +39 -2
- package/node_modules/@buddi/install/dist/backup.js.map +1 -1
- package/node_modules/@buddi/install/dist/kept-data.d.ts +20 -0
- package/node_modules/@buddi/install/dist/kept-data.d.ts.map +1 -0
- package/node_modules/@buddi/install/dist/kept-data.js +34 -0
- package/node_modules/@buddi/install/dist/kept-data.js.map +1 -0
- package/node_modules/@buddi/install/dist/launcher.d.ts.map +1 -1
- package/node_modules/@buddi/install/dist/launcher.js +17 -3
- package/node_modules/@buddi/install/dist/launcher.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/.tsbuildinfo +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/agent.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/agent.js +11 -0
- package/node_modules/@buddi/tool-email/dist/agent.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/imap/fake.d.ts +89 -3
- package/node_modules/@buddi/tool-email/dist/imap/fake.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/imap/fake.js +234 -4
- package/node_modules/@buddi/tool-email/dist/imap/fake.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.d.ts +14 -1
- 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 +157 -2
- package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/index.d.ts +14 -2
- package/node_modules/@buddi/tool-email/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/index.js +23 -4
- package/node_modules/@buddi/tool-email/dist/index.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/logins.d.ts +24 -0
- package/node_modules/@buddi/tool-email/dist/logins.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/logins.js +35 -0
- package/node_modules/@buddi/tool-email/dist/logins.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/mail.d.ts +14 -0
- package/node_modules/@buddi/tool-email/dist/mail.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mail.js +23 -0
- package/node_modules/@buddi/tool-email/dist/mail.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mailbox/actions.d.ts +205 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/actions.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/actions.js +662 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/actions.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/arrival.d.ts +61 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/arrival.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/arrival.js +153 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/arrival.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/select.d.ts +53 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/select.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/select.js +117 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/select.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/pages/accounts.d.ts +37 -1
- package/node_modules/@buddi/tool-email/dist/pages/accounts.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/accounts.js +104 -2
- package/node_modules/@buddi/tool-email/dist/pages/accounts.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 +142 -0
- package/node_modules/@buddi/tool-email/dist/pages/descriptors.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/drafts-tools.d.ts +2 -2
- package/node_modules/@buddi/tool-email/dist/pages/format.d.ts +1 -12
- package/node_modules/@buddi/tool-email/dist/pages/format.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/format.js +17 -0
- package/node_modules/@buddi/tool-email/dist/pages/format.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/index.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/index.js +5 -1
- package/node_modules/@buddi/tool-email/dist/pages/index.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/policies-tools.d.ts +7 -0
- package/node_modules/@buddi/tool-email/dist/pages/policies-tools.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/policies-tools.js +11 -2
- package/node_modules/@buddi/tool-email/dist/pages/policies-tools.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/queries.d.ts +16 -0
- package/node_modules/@buddi/tool-email/dist/pages/queries.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/queries.js +154 -3
- package/node_modules/@buddi/tool-email/dist/pages/queries.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/policies/auto.d.ts +133 -0
- package/node_modules/@buddi/tool-email/dist/policies/auto.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/policies/auto.js +241 -0
- package/node_modules/@buddi/tool-email/dist/policies/auto.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/policies/gate.d.ts +34 -10
- package/node_modules/@buddi/tool-email/dist/policies/gate.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/policies/gate.js +27 -12
- package/node_modules/@buddi/tool-email/dist/policies/gate.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/policies/learn.d.ts +26 -18
- package/node_modules/@buddi/tool-email/dist/policies/learn.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/policies/learn.js +36 -10
- package/node_modules/@buddi/tool-email/dist/policies/learn.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/policies/learned.d.ts +25 -2
- package/node_modules/@buddi/tool-email/dist/policies/learned.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/policies/learned.js +47 -5
- package/node_modules/@buddi/tool-email/dist/policies/learned.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/policies/store.d.ts +8 -2
- package/node_modules/@buddi/tool-email/dist/policies/store.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/policies/store.js +19 -5
- package/node_modules/@buddi/tool-email/dist/policies/store.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/ports.d.ts +79 -0
- package/node_modules/@buddi/tool-email/dist/ports.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/ports.js +6 -0
- package/node_modules/@buddi/tool-email/dist/ports.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/rows.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/rows.js +3 -1
- package/node_modules/@buddi/tool-email/dist/rows.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sources/idle.d.ts +90 -0
- package/node_modules/@buddi/tool-email/dist/sources/idle.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/sources/idle.js +250 -0
- package/node_modules/@buddi/tool-email/dist/sources/idle.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.d.ts +12 -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 +280 -134
- package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/tools/mailbox.d.ts +108 -0
- package/node_modules/@buddi/tool-email/dist/tools/mailbox.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/tools/mailbox.js +359 -0
- package/node_modules/@buddi/tool-email/dist/tools/mailbox.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/tools/policies.d.ts +8 -2
- package/node_modules/@buddi/tool-email/dist/tools/policies.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/tools/policies.js +43 -3
- package/node_modules/@buddi/tool-email/dist/tools/policies.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/tools/read.d.ts +2 -2
- package/node_modules/@buddi/tool-email/dist/tools/triage.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/tools/triage.js +10 -4
- package/node_modules/@buddi/tool-email/dist/tools/triage.js.map +1 -1
- package/node_modules/@buddi/tool-email/migrations/017_mailbox_actions.sql +60 -0
- package/node_modules/@buddi/tool-email/migrations/018_learned_auto.sql +30 -0
- package/node_modules/@buddi/tool-email/migrations/019_arrival_pending.sql +26 -0
- package/node_modules/@buddi/tool-email/package.json +3 -2
- 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/imapflow/CHANGELOG.md +14 -0
- package/node_modules/imapflow/dist/cjs/commands/fetch.js +1 -1
- package/node_modules/imapflow/dist/cjs/imap-flow.d.ts +2 -0
- package/node_modules/imapflow/dist/cjs/imap-flow.js +14 -1
- package/node_modules/imapflow/dist/cjs/package-info.d.ts +1 -1
- package/node_modules/imapflow/dist/cjs/package-info.js +1 -1
- package/node_modules/imapflow/dist/cjs/tools.d.ts +2 -1
- package/node_modules/imapflow/dist/cjs/tools.js +8 -6
- package/node_modules/imapflow/dist/cjs/types.d.ts +9 -1
- package/node_modules/imapflow/dist/esm/commands/fetch.js +1 -1
- package/node_modules/imapflow/dist/esm/imap-flow.d.ts +2 -0
- package/node_modules/imapflow/dist/esm/imap-flow.js +14 -1
- package/node_modules/imapflow/dist/esm/package-info.d.ts +1 -1
- package/node_modules/imapflow/dist/esm/package-info.js +1 -1
- package/node_modules/imapflow/dist/esm/tools.d.ts +2 -1
- package/node_modules/imapflow/dist/esm/tools.js +8 -6
- package/node_modules/imapflow/dist/esm/types.d.ts +9 -1
- package/node_modules/imapflow/package.json +4 -4
- package/package.json +2 -2
- package/packages/cli/dist/.tsbuildinfo +1 -1
- package/packages/cli/dist/commands.d.ts +10 -0
- package/packages/cli/dist/commands.d.ts.map +1 -1
- package/packages/cli/dist/commands.js +237 -18
- 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 +3 -7
- package/packages/cli/dist/doctor-probes.js.map +1 -1
- package/packages/cli/dist/doctor.d.ts +13 -0
- package/packages/cli/dist/doctor.d.ts.map +1 -1
- package/packages/cli/dist/doctor.js +18 -0
- package/packages/cli/dist/doctor.js.map +1 -1
- package/packages/cli/dist/mcp/tools.d.ts.map +1 -1
- package/packages/cli/dist/mcp/tools.js +3 -2
- package/packages/cli/dist/mcp/tools.js.map +1 -1
- package/packages/core/dist/.tsbuildinfo +1 -1
- package/packages/core/dist/agents/catalog.d.ts +3 -0
- package/packages/core/dist/agents/catalog.d.ts.map +1 -1
- package/packages/core/dist/agents/catalog.js +1 -0
- package/packages/core/dist/agents/catalog.js.map +1 -1
- package/packages/core/dist/agents/edit.d.ts +3 -0
- package/packages/core/dist/agents/edit.d.ts.map +1 -1
- package/packages/core/dist/agents/edit.js +3 -1
- package/packages/core/dist/agents/edit.js.map +1 -1
- package/packages/core/dist/agents/frontmatter.d.ts +10 -0
- package/packages/core/dist/agents/frontmatter.d.ts.map +1 -1
- package/packages/core/dist/agents/frontmatter.js +7 -0
- package/packages/core/dist/agents/frontmatter.js.map +1 -1
- package/packages/core/dist/agents/idle-rollover.d.ts +20 -0
- package/packages/core/dist/agents/idle-rollover.d.ts.map +1 -0
- package/packages/core/dist/agents/idle-rollover.js +30 -0
- package/packages/core/dist/agents/idle-rollover.js.map +1 -0
- package/packages/core/dist/agents/index.d.ts +1 -0
- package/packages/core/dist/agents/index.d.ts.map +1 -1
- package/packages/core/dist/agents/index.js +1 -0
- package/packages/core/dist/agents/index.js.map +1 -1
- package/packages/core/dist/backup/dump.d.ts +9 -0
- package/packages/core/dist/backup/dump.d.ts.map +1 -1
- package/packages/core/dist/backup/dump.js +10 -1
- package/packages/core/dist/backup/dump.js.map +1 -1
- package/packages/core/dist/backup/pending.d.ts +13 -0
- package/packages/core/dist/backup/pending.d.ts.map +1 -1
- package/packages/core/dist/backup/pending.js +56 -4
- package/packages/core/dist/backup/pending.js.map +1 -1
- package/packages/core/dist/backup/restore.d.ts +3 -1
- package/packages/core/dist/backup/restore.d.ts.map +1 -1
- package/packages/core/dist/backup/restore.js +1 -1
- package/packages/core/dist/backup/restore.js.map +1 -1
- package/packages/core/dist/feedback/index.d.ts +108 -0
- package/packages/core/dist/feedback/index.d.ts.map +1 -0
- package/packages/core/dist/feedback/index.js +160 -0
- package/packages/core/dist/feedback/index.js.map +1 -0
- package/packages/core/dist/host/build.d.ts.map +1 -1
- package/packages/core/dist/host/build.js +28 -1
- package/packages/core/dist/host/build.js.map +1 -1
- package/packages/core/dist/host/types.d.ts +29 -2
- package/packages/core/dist/host/types.d.ts.map +1 -1
- package/packages/core/dist/index.d.ts +1 -0
- package/packages/core/dist/index.d.ts.map +1 -1
- package/packages/core/dist/index.js +1 -0
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/learning/policies.d.ts +7 -1
- package/packages/core/dist/learning/policies.d.ts.map +1 -1
- package/packages/core/dist/learning/policies.js +4 -1
- package/packages/core/dist/learning/policies.js.map +1 -1
- package/packages/core/dist/learning/store.d.ts +29 -1
- package/packages/core/dist/learning/store.d.ts.map +1 -1
- package/packages/core/dist/learning/store.js +33 -8
- package/packages/core/dist/learning/store.js.map +1 -1
- package/packages/core/dist/learning/types.d.ts +24 -1
- package/packages/core/dist/learning/types.d.ts.map +1 -1
- package/packages/core/dist/learning/types.js +6 -0
- package/packages/core/dist/learning/types.js.map +1 -1
- package/packages/core/dist/owner.d.ts +2 -1
- package/packages/core/dist/owner.d.ts.map +1 -1
- package/packages/core/dist/owner.js.map +1 -1
- package/packages/core/dist/pages.d.ts +27 -0
- package/packages/core/dist/pages.d.ts.map +1 -1
- package/packages/core/dist/pages.js +24 -3
- package/packages/core/dist/pages.js.map +1 -1
- package/packages/core/dist/plugin/index.d.ts +5 -4
- 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/registry.d.ts +10 -1
- package/packages/core/dist/registry.d.ts.map +1 -1
- package/packages/core/dist/registry.js +13 -0
- package/packages/core/dist/registry.js.map +1 -1
- package/packages/core/dist/sources/index.d.ts +1 -0
- package/packages/core/dist/sources/index.d.ts.map +1 -1
- package/packages/core/dist/sources/index.js +1 -0
- package/packages/core/dist/sources/index.js.map +1 -1
- package/packages/core/dist/sources/watch.d.ts +37 -0
- package/packages/core/dist/sources/watch.d.ts.map +1 -0
- package/packages/core/dist/sources/watch.js +81 -0
- package/packages/core/dist/sources/watch.js.map +1 -0
- package/packages/core/dist/tools.d.ts +47 -0
- package/packages/core/dist/tools.d.ts.map +1 -1
- package/packages/core/dist/tools.js.map +1 -1
- package/packages/core/migrations/056_dashboard_sessions.sql +37 -0
- package/packages/core/migrations/057_proposal_decided_by.sql +34 -0
- package/packages/core/migrations/058_message_feedback.sql +50 -0
- package/packages/gateway/dist/.tsbuildinfo +1 -1
- package/packages/gateway/dist/agents/learning-digest.d.ts +7 -1
- package/packages/gateway/dist/agents/learning-digest.d.ts.map +1 -1
- package/packages/gateway/dist/agents/learning-digest.js +29 -3
- package/packages/gateway/dist/agents/learning-digest.js.map +1 -1
- package/packages/gateway/dist/agents/platform-files.d.ts +2 -0
- package/packages/gateway/dist/agents/platform-files.d.ts.map +1 -1
- package/packages/gateway/dist/agents/platform-files.js +2 -0
- package/packages/gateway/dist/agents/platform-files.js.map +1 -1
- package/packages/gateway/dist/agents/platform.d.ts +20 -0
- package/packages/gateway/dist/agents/platform.d.ts.map +1 -1
- package/packages/gateway/dist/agents/platform.js +46 -3
- package/packages/gateway/dist/agents/platform.js.map +1 -1
- package/packages/gateway/dist/agents-cli.d.ts +1 -1
- package/packages/gateway/dist/agents-cli.d.ts.map +1 -1
- package/packages/gateway/dist/agents-cli.js +12 -2
- package/packages/gateway/dist/agents-cli.js.map +1 -1
- package/packages/gateway/dist/chat/session.d.ts.map +1 -1
- package/packages/gateway/dist/chat/session.js +2 -1
- package/packages/gateway/dist/chat/session.js.map +1 -1
- package/packages/gateway/dist/mcp/requests.d.ts.map +1 -1
- package/packages/gateway/dist/mcp/requests.js +1 -0
- package/packages/gateway/dist/mcp/requests.js.map +1 -1
- package/packages/gateway/dist/plugins/approve.js +4 -1
- package/packages/gateway/dist/plugins/approve.js.map +1 -1
- package/packages/gateway/dist/plugins/paths.d.ts +14 -0
- package/packages/gateway/dist/plugins/paths.d.ts.map +1 -1
- package/packages/gateway/dist/plugins/paths.js +27 -1
- package/packages/gateway/dist/plugins/paths.js.map +1 -1
- package/packages/gateway/dist/plugins/stage.d.ts +27 -3
- package/packages/gateway/dist/plugins/stage.d.ts.map +1 -1
- package/packages/gateway/dist/plugins/stage.js +35 -5
- package/packages/gateway/dist/plugins/stage.js.map +1 -1
- package/packages/gateway/dist/plugins-cli.d.ts +4 -0
- package/packages/gateway/dist/plugins-cli.d.ts.map +1 -1
- package/packages/gateway/dist/plugins-cli.js +42 -9
- package/packages/gateway/dist/plugins-cli.js.map +1 -1
- package/packages/gateway/dist/serve.d.ts.map +1 -1
- package/packages/gateway/dist/serve.js +14 -2
- package/packages/gateway/dist/serve.js.map +1 -1
- package/packages/gateway/dist/surfaces/browser-continuation.d.ts +2 -1
- package/packages/gateway/dist/surfaces/browser-continuation.d.ts.map +1 -1
- package/packages/gateway/dist/surfaces/browser-continuation.js +8 -5
- package/packages/gateway/dist/surfaces/browser-continuation.js.map +1 -1
- package/packages/gateway/dist/surfaces/browser-handoff.d.ts +27 -4
- package/packages/gateway/dist/surfaces/browser-handoff.d.ts.map +1 -1
- package/packages/gateway/dist/surfaces/browser-handoff.js +57 -7
- package/packages/gateway/dist/surfaces/browser-handoff.js.map +1 -1
- package/packages/gateway/dist/surfaces/carry-over.d.ts +89 -0
- package/packages/gateway/dist/surfaces/carry-over.d.ts.map +1 -0
- package/packages/gateway/dist/surfaces/carry-over.js +172 -0
- package/packages/gateway/dist/surfaces/carry-over.js.map +1 -0
- package/packages/gateway/dist/surfaces/conversation-lifetime.d.ts +5 -2
- package/packages/gateway/dist/surfaces/conversation-lifetime.d.ts.map +1 -1
- package/packages/gateway/dist/surfaces/conversation-lifetime.js +5 -2
- package/packages/gateway/dist/surfaces/conversation-lifetime.js.map +1 -1
- package/packages/gateway/dist/telegram/api.d.ts +34 -2
- package/packages/gateway/dist/telegram/api.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/api.js +15 -2
- package/packages/gateway/dist/telegram/api.js.map +1 -1
- package/packages/gateway/dist/telegram/env-owner.d.ts +30 -0
- package/packages/gateway/dist/telegram/env-owner.d.ts.map +1 -0
- package/packages/gateway/dist/telegram/env-owner.js +45 -0
- package/packages/gateway/dist/telegram/env-owner.js.map +1 -0
- package/packages/gateway/dist/telegram/main.d.ts +0 -2
- package/packages/gateway/dist/telegram/main.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/main.js +18 -25
- package/packages/gateway/dist/telegram/main.js.map +1 -1
- package/packages/gateway/dist/telegram/notify.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/notify.js +1 -1
- package/packages/gateway/dist/telegram/notify.js.map +1 -1
- package/packages/gateway/dist/telegram/outbound.d.ts +2 -2
- package/packages/gateway/dist/telegram/outbound.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/outbound.js +12 -3
- package/packages/gateway/dist/telegram/outbound.js.map +1 -1
- package/packages/gateway/dist/telegram/reactions.d.ts +45 -0
- package/packages/gateway/dist/telegram/reactions.d.ts.map +1 -0
- package/packages/gateway/dist/telegram/reactions.js +97 -0
- package/packages/gateway/dist/telegram/reactions.js.map +1 -0
- package/packages/gateway/dist/telegram/surface.d.ts +1 -0
- package/packages/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/surface.js +80 -9
- package/packages/gateway/dist/telegram/surface.js.map +1 -1
- package/packages/gateway/dist/web/agents.d.ts +3 -1
- package/packages/gateway/dist/web/agents.d.ts.map +1 -1
- package/packages/gateway/dist/web/agents.js +20 -2
- package/packages/gateway/dist/web/agents.js.map +1 -1
- package/packages/gateway/dist/web/chat.d.ts +10 -3
- package/packages/gateway/dist/web/chat.d.ts.map +1 -1
- package/packages/gateway/dist/web/chat.js +18 -5
- package/packages/gateway/dist/web/chat.js.map +1 -1
- package/packages/gateway/dist/web/plugins.d.ts +6 -1
- package/packages/gateway/dist/web/plugins.d.ts.map +1 -1
- package/packages/gateway/dist/web/plugins.js +31 -2
- package/packages/gateway/dist/web/plugins.js.map +1 -1
- package/packages/gateway/dist/web/proposals.d.ts +21 -0
- package/packages/gateway/dist/web/proposals.d.ts.map +1 -1
- package/packages/gateway/dist/web/proposals.js +50 -1
- package/packages/gateway/dist/web/proposals.js.map +1 -1
- package/packages/gateway/dist/web/read.d.ts +6 -0
- package/packages/gateway/dist/web/read.d.ts.map +1 -1
- package/packages/gateway/dist/web/read.js.map +1 -1
- package/packages/gateway/dist/web/recovery.d.ts +19 -2
- package/packages/gateway/dist/web/recovery.d.ts.map +1 -1
- package/packages/gateway/dist/web/recovery.js +148 -7
- package/packages/gateway/dist/web/recovery.js.map +1 -1
- package/packages/gateway/dist/web/server.d.ts.map +1 -1
- package/packages/gateway/dist/web/server.js +87 -29
- package/packages/gateway/dist/web/server.js.map +1 -1
- package/packages/gateway/dist/web/sessions.d.ts +81 -7
- package/packages/gateway/dist/web/sessions.d.ts.map +1 -1
- package/packages/gateway/dist/web/sessions.js +242 -24
- package/packages/gateway/dist/web/sessions.js.map +1 -1
- package/packages/gateway/dist/web/signed-out.d.ts +46 -0
- package/packages/gateway/dist/web/signed-out.d.ts.map +1 -0
- package/packages/gateway/dist/web/signed-out.js +99 -0
- package/packages/gateway/dist/web/signed-out.js.map +1 -0
- package/packages/gateway/dist/web/tailscale.d.ts +13 -0
- package/packages/gateway/dist/web/tailscale.d.ts.map +1 -1
- package/packages/gateway/dist/web/tailscale.js +12 -0
- package/packages/gateway/dist/web/tailscale.js.map +1 -1
- package/packages/install/dist/.tsbuildinfo +1 -1
- package/packages/install/dist/backup.d.ts +18 -0
- package/packages/install/dist/backup.d.ts.map +1 -1
- package/packages/install/dist/backup.js +39 -2
- package/packages/install/dist/backup.js.map +1 -1
- package/packages/install/dist/kept-data.d.ts +20 -0
- package/packages/install/dist/kept-data.d.ts.map +1 -0
- package/packages/install/dist/kept-data.js +34 -0
- package/packages/install/dist/kept-data.js.map +1 -0
- package/packages/install/dist/launcher.d.ts.map +1 -1
- package/packages/install/dist/launcher.js +17 -3
- package/packages/install/dist/launcher.js.map +1 -1
- package/packages/runtime/dist/.tsbuildinfo +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/agent.d.ts.map +1 -1
- package/packages/tools/email/dist/agent.js +11 -0
- package/packages/tools/email/dist/agent.js.map +1 -1
- package/packages/tools/email/dist/imap/fake.d.ts +89 -3
- package/packages/tools/email/dist/imap/fake.d.ts.map +1 -1
- package/packages/tools/email/dist/imap/fake.js +234 -4
- package/packages/tools/email/dist/imap/fake.js.map +1 -1
- package/packages/tools/email/dist/imap/imapflow-client.d.ts +14 -1
- package/packages/tools/email/dist/imap/imapflow-client.d.ts.map +1 -1
- package/packages/tools/email/dist/imap/imapflow-client.js +157 -2
- package/packages/tools/email/dist/imap/imapflow-client.js.map +1 -1
- package/packages/tools/email/dist/index.d.ts +14 -2
- package/packages/tools/email/dist/index.d.ts.map +1 -1
- package/packages/tools/email/dist/index.js +23 -4
- package/packages/tools/email/dist/index.js.map +1 -1
- package/packages/tools/email/dist/logins.d.ts +24 -0
- package/packages/tools/email/dist/logins.d.ts.map +1 -0
- package/packages/tools/email/dist/logins.js +35 -0
- package/packages/tools/email/dist/logins.js.map +1 -0
- package/packages/tools/email/dist/mail.d.ts +14 -0
- package/packages/tools/email/dist/mail.d.ts.map +1 -1
- package/packages/tools/email/dist/mail.js +23 -0
- package/packages/tools/email/dist/mail.js.map +1 -1
- package/packages/tools/email/dist/mailbox/actions.d.ts +205 -0
- package/packages/tools/email/dist/mailbox/actions.d.ts.map +1 -0
- package/packages/tools/email/dist/mailbox/actions.js +662 -0
- package/packages/tools/email/dist/mailbox/actions.js.map +1 -0
- package/packages/tools/email/dist/mailbox/arrival.d.ts +61 -0
- package/packages/tools/email/dist/mailbox/arrival.d.ts.map +1 -0
- package/packages/tools/email/dist/mailbox/arrival.js +153 -0
- package/packages/tools/email/dist/mailbox/arrival.js.map +1 -0
- package/packages/tools/email/dist/mailbox/select.d.ts +53 -0
- package/packages/tools/email/dist/mailbox/select.d.ts.map +1 -0
- package/packages/tools/email/dist/mailbox/select.js +117 -0
- package/packages/tools/email/dist/mailbox/select.js.map +1 -0
- package/packages/tools/email/dist/pages/accounts.d.ts +37 -1
- package/packages/tools/email/dist/pages/accounts.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/accounts.js +104 -2
- package/packages/tools/email/dist/pages/accounts.js.map +1 -1
- package/packages/tools/email/dist/pages/descriptors.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/descriptors.js +142 -0
- package/packages/tools/email/dist/pages/descriptors.js.map +1 -1
- package/packages/tools/email/dist/pages/drafts-tools.d.ts +2 -2
- package/packages/tools/email/dist/pages/format.d.ts +1 -12
- package/packages/tools/email/dist/pages/format.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/format.js +17 -0
- package/packages/tools/email/dist/pages/format.js.map +1 -1
- package/packages/tools/email/dist/pages/index.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/index.js +5 -1
- package/packages/tools/email/dist/pages/index.js.map +1 -1
- package/packages/tools/email/dist/pages/policies-tools.d.ts +7 -0
- package/packages/tools/email/dist/pages/policies-tools.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/policies-tools.js +11 -2
- package/packages/tools/email/dist/pages/policies-tools.js.map +1 -1
- package/packages/tools/email/dist/pages/queries.d.ts +16 -0
- package/packages/tools/email/dist/pages/queries.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/queries.js +154 -3
- package/packages/tools/email/dist/pages/queries.js.map +1 -1
- package/packages/tools/email/dist/policies/auto.d.ts +133 -0
- package/packages/tools/email/dist/policies/auto.d.ts.map +1 -0
- package/packages/tools/email/dist/policies/auto.js +241 -0
- package/packages/tools/email/dist/policies/auto.js.map +1 -0
- package/packages/tools/email/dist/policies/gate.d.ts +34 -10
- package/packages/tools/email/dist/policies/gate.d.ts.map +1 -1
- package/packages/tools/email/dist/policies/gate.js +27 -12
- package/packages/tools/email/dist/policies/gate.js.map +1 -1
- package/packages/tools/email/dist/policies/learn.d.ts +26 -18
- package/packages/tools/email/dist/policies/learn.d.ts.map +1 -1
- package/packages/tools/email/dist/policies/learn.js +36 -10
- package/packages/tools/email/dist/policies/learn.js.map +1 -1
- package/packages/tools/email/dist/policies/learned.d.ts +25 -2
- package/packages/tools/email/dist/policies/learned.d.ts.map +1 -1
- package/packages/tools/email/dist/policies/learned.js +47 -5
- package/packages/tools/email/dist/policies/learned.js.map +1 -1
- package/packages/tools/email/dist/policies/store.d.ts +8 -2
- package/packages/tools/email/dist/policies/store.d.ts.map +1 -1
- package/packages/tools/email/dist/policies/store.js +19 -5
- package/packages/tools/email/dist/policies/store.js.map +1 -1
- package/packages/tools/email/dist/ports.d.ts +79 -0
- package/packages/tools/email/dist/ports.d.ts.map +1 -1
- package/packages/tools/email/dist/ports.js +6 -0
- package/packages/tools/email/dist/ports.js.map +1 -1
- package/packages/tools/email/dist/rows.d.ts.map +1 -1
- package/packages/tools/email/dist/rows.js +3 -1
- package/packages/tools/email/dist/rows.js.map +1 -1
- package/packages/tools/email/dist/sources/idle.d.ts +90 -0
- package/packages/tools/email/dist/sources/idle.d.ts.map +1 -0
- package/packages/tools/email/dist/sources/idle.js +250 -0
- package/packages/tools/email/dist/sources/idle.js.map +1 -0
- package/packages/tools/email/dist/sources/inbox-poll.d.ts +12 -1
- package/packages/tools/email/dist/sources/inbox-poll.d.ts.map +1 -1
- package/packages/tools/email/dist/sources/inbox-poll.js +280 -134
- package/packages/tools/email/dist/sources/inbox-poll.js.map +1 -1
- package/packages/tools/email/dist/tools/mailbox.d.ts +108 -0
- package/packages/tools/email/dist/tools/mailbox.d.ts.map +1 -0
- package/packages/tools/email/dist/tools/mailbox.js +359 -0
- package/packages/tools/email/dist/tools/mailbox.js.map +1 -0
- package/packages/tools/email/dist/tools/policies.d.ts +8 -2
- package/packages/tools/email/dist/tools/policies.d.ts.map +1 -1
- package/packages/tools/email/dist/tools/policies.js +43 -3
- package/packages/tools/email/dist/tools/policies.js.map +1 -1
- package/packages/tools/email/dist/tools/read.d.ts +2 -2
- package/packages/tools/email/dist/tools/triage.d.ts.map +1 -1
- package/packages/tools/email/dist/tools/triage.js +10 -4
- package/packages/tools/email/dist/tools/triage.js.map +1 -1
- package/packages/tools/email/migrations/017_mailbox_actions.sql +60 -0
- package/packages/tools/email/migrations/018_learned_auto.sql +30 -0
- package/packages/tools/email/migrations/019_arrival_pending.sql +26 -0
- package/packages/tools/email/package.json +3 -2
- 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/assets/index-CKuhKCWw.js +131 -0
- package/packages/web/dist/assets/index-DsK8UWCJ.css +1 -0
- package/packages/web/dist/assets/{lottie_light-DmJaDM4A.js → lottie_light-CSeMXM8D.js} +1 -1
- package/packages/web/dist/build.json +1 -1
- package/packages/web/dist/index.html +2 -2
- package/packages/web/dist/precache.json +4 -4
- package/packages/web/dist/assets/index-Cn-3X1OI.js +0 -130
- package/packages/web/dist/assets/index-bdj791NB.css +0 -1
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
import { ToolRefusal } from '@buddi/core/plugin';
|
|
2
|
+
import { mailboxAuth } from '../credentials.js';
|
|
3
|
+
import { leafOf } from '../folders.js';
|
|
4
|
+
import { clearLoginFailure, isAuthFailure, recordLoginFailure } from '../logins.js';
|
|
5
|
+
import { isImapWriter, } from '../ports.js';
|
|
6
|
+
import { INBOX } from '../config.js';
|
|
7
|
+
/** The most messages one call may change. One approval, one card, 500 rows. */
|
|
8
|
+
export const MAX_PER_CALL = 500;
|
|
9
|
+
/** How many messages an approval card names before "and N more". */
|
|
10
|
+
export const SAMPLE_SIZE = 5;
|
|
11
|
+
export const MAILBOX_ACTION_KINDS = ['mark-read', 'mark-unread', 'archive', 'move', 'trash'];
|
|
12
|
+
export const SEEN = '\\Seen';
|
|
13
|
+
const GMAIL_CAPABILITY = 'X-GM-EXT-1';
|
|
14
|
+
export const ACTION_COLUMNS = 'id, account_id, kind, destination, criteria, origin, actor, policy_id, run_id, action_id, message_ids, ' +
|
|
15
|
+
'items, changed, note, reverts, undone_at, undone_by, created_at';
|
|
16
|
+
function iso(value) {
|
|
17
|
+
if (value === null || value === undefined)
|
|
18
|
+
return null;
|
|
19
|
+
return value instanceof Date ? value.toISOString() : String(value);
|
|
20
|
+
}
|
|
21
|
+
export function toAction(row) {
|
|
22
|
+
return {
|
|
23
|
+
id: String(row.id),
|
|
24
|
+
accountId: String(row.account_id),
|
|
25
|
+
kind: row.kind,
|
|
26
|
+
destination: row.destination ?? null,
|
|
27
|
+
criteria: row.criteria ?? null,
|
|
28
|
+
origin: row.origin,
|
|
29
|
+
actor: row.actor ?? '',
|
|
30
|
+
policyId: row.policy_id ? String(row.policy_id) : null,
|
|
31
|
+
runId: row.run_id ?? null,
|
|
32
|
+
actionId: row.action_id ? String(row.action_id) : null,
|
|
33
|
+
messageIds: Array.isArray(row.message_ids) ? row.message_ids.map(String) : [],
|
|
34
|
+
items: Array.isArray(row.items) ? row.items : [],
|
|
35
|
+
changed: Number(row.changed ?? 0),
|
|
36
|
+
note: row.note ?? null,
|
|
37
|
+
reverts: row.reverts ? String(row.reverts) : null,
|
|
38
|
+
undoneAt: iso(row.undone_at),
|
|
39
|
+
undoneBy: row.undone_by ? String(row.undone_by) : null,
|
|
40
|
+
createdAt: iso(row.created_at),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** A refusal whose message is the sentence the owner and the agent read. */
|
|
44
|
+
export class MailboxRefusal extends ToolRefusal {
|
|
45
|
+
}
|
|
46
|
+
/** The mailbox could not be opened at all: no password, or the provider refused it. Nothing was tried. */
|
|
47
|
+
export class MailboxLoginRefusal extends MailboxRefusal {
|
|
48
|
+
}
|
|
49
|
+
/* ------------------------------------------------------------------ *
|
|
50
|
+
* Words
|
|
51
|
+
* ------------------------------------------------------------------ */
|
|
52
|
+
export function plural(n, one, many = `${one}s`) {
|
|
53
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
54
|
+
}
|
|
55
|
+
/** "Mark as read", "Archive", … — the verb a card and a trail row lead with. */
|
|
56
|
+
export function verbOf(kind, destination) {
|
|
57
|
+
switch (kind) {
|
|
58
|
+
case 'mark-read':
|
|
59
|
+
return 'Mark as read';
|
|
60
|
+
case 'mark-unread':
|
|
61
|
+
return 'Mark as unread';
|
|
62
|
+
case 'archive':
|
|
63
|
+
return 'Archive';
|
|
64
|
+
case 'move':
|
|
65
|
+
return `Move to ${destination ?? 'a folder'}`;
|
|
66
|
+
case 'trash':
|
|
67
|
+
return 'Move to Trash';
|
|
68
|
+
case 'undo':
|
|
69
|
+
return 'Undo';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** The sample lines a card shows: sender — subject. */
|
|
73
|
+
export function sampleLines(targets) {
|
|
74
|
+
const lines = targets.slice(0, SAMPLE_SIZE).map((t) => `- ${t.from || '(unknown sender)'} — ${t.subject || '(no subject)'}`);
|
|
75
|
+
if (targets.length > SAMPLE_SIZE)
|
|
76
|
+
lines.push(`…and ${targets.length - SAMPLE_SIZE} more.`);
|
|
77
|
+
return lines;
|
|
78
|
+
}
|
|
79
|
+
/* ------------------------------------------------------------------ *
|
|
80
|
+
* Reading what a change is about
|
|
81
|
+
* ------------------------------------------------------------------ */
|
|
82
|
+
/** The rows for these ids, with their folder names, in the order asked. */
|
|
83
|
+
export async function loadTargets(db, ids) {
|
|
84
|
+
if (ids.length === 0)
|
|
85
|
+
return [];
|
|
86
|
+
const { rows } = await db.query(`select m.id, m.account_id, m.folder_id, f.name as folder, m.uidvalidity, m.uid, m.message_id,
|
|
87
|
+
m.subject, m.from_addr, m.flags
|
|
88
|
+
from email.messages m join email.folders f on f.id = m.folder_id
|
|
89
|
+
where m.id = any($1::uuid[])`, [ids]);
|
|
90
|
+
const byId = new Map(rows.map((r) => [String(r.id), r]));
|
|
91
|
+
const out = [];
|
|
92
|
+
for (const id of ids) {
|
|
93
|
+
const r = byId.get(id);
|
|
94
|
+
if (!r)
|
|
95
|
+
continue;
|
|
96
|
+
out.push({
|
|
97
|
+
id,
|
|
98
|
+
accountId: String(r.account_id),
|
|
99
|
+
folderId: String(r.folder_id),
|
|
100
|
+
folder: r.folder,
|
|
101
|
+
uidValidity: Number(r.uidvalidity),
|
|
102
|
+
uid: Number(r.uid),
|
|
103
|
+
messageId: r.message_id ?? null,
|
|
104
|
+
subject: r.subject ?? '',
|
|
105
|
+
from: r.from_addr ?? '',
|
|
106
|
+
flags: Array.isArray(r.flags) ? r.flags : [],
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The targets of one call, checked: every id known, at most `MAX_PER_CALL`,
|
|
113
|
+
* all in one mailbox the owner has. Refusals are sentences.
|
|
114
|
+
*/
|
|
115
|
+
export async function requireTargets(db, ids, accounts) {
|
|
116
|
+
const unique = [...new Set(ids)];
|
|
117
|
+
if (unique.length === 0)
|
|
118
|
+
throw new MailboxRefusal('No messages were named. Use email.select_messages to find them first.');
|
|
119
|
+
if (unique.length > MAX_PER_CALL) {
|
|
120
|
+
throw new MailboxRefusal(`That is ${unique.length} messages; one change covers at most ${MAX_PER_CALL}. Split it.`);
|
|
121
|
+
}
|
|
122
|
+
const targets = await loadTargets(db, unique);
|
|
123
|
+
const missing = unique.length - targets.length;
|
|
124
|
+
if (missing > 0) {
|
|
125
|
+
throw new MailboxRefusal(`${plural(missing, 'of those ids is', 'of those ids are')} not a message buddi has. Select them again.`);
|
|
126
|
+
}
|
|
127
|
+
const accountIds = [...new Set(targets.map((t) => t.accountId))];
|
|
128
|
+
if (accountIds.length > 1) {
|
|
129
|
+
throw new MailboxRefusal('Those messages are in more than one mailbox. One change covers one mailbox; make one call per mailbox.');
|
|
130
|
+
}
|
|
131
|
+
const account = accounts.find((a) => a.id === accountIds[0]);
|
|
132
|
+
if (!account)
|
|
133
|
+
throw new MailboxRefusal('Those messages are in a mailbox that is turned off or no longer here.');
|
|
134
|
+
return { account, targets };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Open a writing connection to one mailbox, run `work`, and close it.
|
|
138
|
+
*
|
|
139
|
+
* A login the provider refuses is written on the account row, as the poll
|
|
140
|
+
* writes it, so the settings row says "Password needed".
|
|
141
|
+
*/
|
|
142
|
+
export async function withWriter(ctx, account, opts, work) {
|
|
143
|
+
const db = ctx.buddi.db;
|
|
144
|
+
const auth = await mailboxAuth(ctx, account, opts.env);
|
|
145
|
+
if (!auth.ok)
|
|
146
|
+
throw new MailboxLoginRefusal(`${account.address} cannot be opened: ${auth.problem.message}`);
|
|
147
|
+
let client;
|
|
148
|
+
try {
|
|
149
|
+
client = await opts.connect(account, auth.value);
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
if (isAuthFailure(err)) {
|
|
153
|
+
await recordLoginFailure(db, account.id, err, ctx.buddi.clock.now()).catch(() => { });
|
|
154
|
+
throw new MailboxLoginRefusal(`${account.address} refused its stored password. Set a new one under Settings → Email.`);
|
|
155
|
+
}
|
|
156
|
+
throw err;
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
await clearLoginFailure(db, account.id);
|
|
160
|
+
if (!isImapWriter(client)) {
|
|
161
|
+
throw new MailboxRefusal(`The connection to ${account.address} can only read mail here, so nothing was changed.`);
|
|
162
|
+
}
|
|
163
|
+
return await work(client);
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
await client.close().catch(() => { });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
export async function serverFacts(client) {
|
|
170
|
+
const caps = await client.capabilities();
|
|
171
|
+
const listing = await client.listMailboxes();
|
|
172
|
+
return { gmail: caps.includes(GMAIL_CAPABILITY), move: caps.includes('MOVE'), listing };
|
|
173
|
+
}
|
|
174
|
+
function single(list) {
|
|
175
|
+
return list.length === 1 ? list[0] : undefined;
|
|
176
|
+
}
|
|
177
|
+
function attributesOf(info) {
|
|
178
|
+
return [info.specialUse ?? '', ...info.flags].map((f) => f.trim().toLowerCase()).filter((f) => f !== '');
|
|
179
|
+
}
|
|
180
|
+
function specialFolder(listing, use) {
|
|
181
|
+
const wanted = use.toLowerCase();
|
|
182
|
+
return listing.find((info) => attributesOf(info).includes(wanted))?.name ?? null;
|
|
183
|
+
}
|
|
184
|
+
/** Folders a message can be moved into: selectable, and not the Gmail namespace root. */
|
|
185
|
+
function selectable(listing) {
|
|
186
|
+
return listing.filter((info) => !attributesOf(info).includes('\\noselect') && !attributesOf(info).includes('\\nonexistent'));
|
|
187
|
+
}
|
|
188
|
+
/** "INBOX, Archive, Receipts, …" — the list a refusal names. */
|
|
189
|
+
export function folderList(listing) {
|
|
190
|
+
const names = selectable(listing).map((info) => info.name);
|
|
191
|
+
return names.length > 0 ? names.join(', ') : '(none listed)';
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Where a kind of change sends messages on this server, or a refusal.
|
|
195
|
+
*
|
|
196
|
+
* Nothing is created: a folder that does not exist is refused, naming the
|
|
197
|
+
* ones that do.
|
|
198
|
+
*/
|
|
199
|
+
export function destinationFor(facts, kind, account, folder) {
|
|
200
|
+
if (kind === 'mark-read' || kind === 'mark-unread')
|
|
201
|
+
return null;
|
|
202
|
+
if (!facts.move) {
|
|
203
|
+
throw new MailboxRefusal(`${account}'s server cannot move messages (it does not offer IMAP MOVE), and buddi never copies and deletes to fake it. Nothing was changed.`);
|
|
204
|
+
}
|
|
205
|
+
if (kind === 'archive') {
|
|
206
|
+
const found = facts.gmail ? specialFolder(facts.listing, '\\All') : specialFolder(facts.listing, '\\Archive');
|
|
207
|
+
if (!found) {
|
|
208
|
+
throw new MailboxRefusal(facts.gmail
|
|
209
|
+
? `${account} lists no All Mail folder, so there is nowhere to archive to. Nothing was changed.`
|
|
210
|
+
: `${account} has no Archive folder (its server marks none), so buddi cannot archive there. Move them to a folder by name instead — its folders are: ${folderList(facts.listing)}.`);
|
|
211
|
+
}
|
|
212
|
+
return found;
|
|
213
|
+
}
|
|
214
|
+
if (kind === 'trash') {
|
|
215
|
+
const found = specialFolder(facts.listing, '\\Trash');
|
|
216
|
+
if (!found) {
|
|
217
|
+
throw new MailboxRefusal(`${account} has no Trash folder (its server marks none), and buddi never deletes mail outright. Nothing was changed.`);
|
|
218
|
+
}
|
|
219
|
+
return found;
|
|
220
|
+
}
|
|
221
|
+
// move
|
|
222
|
+
const wanted = (folder ?? '').trim();
|
|
223
|
+
if (wanted === '')
|
|
224
|
+
throw new MailboxRefusal('Name the folder to move them to.');
|
|
225
|
+
const candidates = selectable(facts.listing);
|
|
226
|
+
const found = candidates.find((c) => c.name === wanted) ??
|
|
227
|
+
single(candidates.filter((c) => c.name.toLowerCase() === wanted.toLowerCase())) ??
|
|
228
|
+
single(candidates.filter((c) => leafOf(c.name) === wanted.toLowerCase()));
|
|
229
|
+
if (found) {
|
|
230
|
+
/*
|
|
231
|
+
* Trash and Junk are emptied by the provider. A move there is a trash in
|
|
232
|
+
* all but name, and `email.move` may be remembered where `email.trash`
|
|
233
|
+
* never is — so it is refused here, and the owner is asked every time.
|
|
234
|
+
*/
|
|
235
|
+
const attributes = attributesOf(found);
|
|
236
|
+
if (attributes.includes('\\trash') || attributes.includes('\\junk')) {
|
|
237
|
+
throw new MailboxRefusal(`${found.name} is ${attributes.includes('\\trash') ? 'the Trash' : 'the Junk folder'}, which your provider empties on its own. Use email.trash for that; it asks every time.`);
|
|
238
|
+
}
|
|
239
|
+
return found.name;
|
|
240
|
+
}
|
|
241
|
+
throw new MailboxRefusal(`${account} has no ${facts.gmail ? 'folder or label' : 'folder'} called "${wanted}", and buddi creates none. Its ${facts.gmail ? 'folders and labels' : 'folders'} are: ${folderList(facts.listing)}.`);
|
|
242
|
+
}
|
|
243
|
+
/* ------------------------------------------------------------------ *
|
|
244
|
+
* Keeping buddi's rows in step
|
|
245
|
+
* ------------------------------------------------------------------ */
|
|
246
|
+
/** The folder row for a server name, created (unsynced, kind other) if new. Never changes an existing one. */
|
|
247
|
+
async function folderRow(db, accountId, name) {
|
|
248
|
+
const { rows } = await db.query(`insert into email.folders (account_id, name, kind, synced) values ($1, $2, 'other', false)
|
|
249
|
+
on conflict (account_id, name) do update set name = email.folders.name
|
|
250
|
+
returning id`, [accountId, name]);
|
|
251
|
+
return String(rows[0].id);
|
|
252
|
+
}
|
|
253
|
+
let unknownCounter = 0;
|
|
254
|
+
/**
|
|
255
|
+
* A placeholder uid for a message whose new uid the server did not report and
|
|
256
|
+
* a Message-ID search could not find: negative, so it can never be a real uid,
|
|
257
|
+
* and unique. Its UIDVALIDITY is 0, which is what tells the next change (or
|
|
258
|
+
* undo) to find it by Message-ID first.
|
|
259
|
+
*/
|
|
260
|
+
function placeholderUid() {
|
|
261
|
+
unknownCounter = (unknownCounter + 1) % 1000;
|
|
262
|
+
return -(Date.now() * 1000 + unknownCounter);
|
|
263
|
+
}
|
|
264
|
+
/** Point a row at where its message is now. Falls back to "uid unknown" if the poll got there first. */
|
|
265
|
+
async function relocateRow(db, target, folderId, uidValidity, uid) {
|
|
266
|
+
if (uidValidity !== null && uid !== null) {
|
|
267
|
+
const result = await db.query(`update email.messages set folder_id = $2, uidvalidity = $3, uid = $4
|
|
268
|
+
where id = $1
|
|
269
|
+
and not exists (select 1 from email.messages o
|
|
270
|
+
where o.account_id = $5 and o.folder_id = $2 and o.uidvalidity = $3 and o.uid = $4)`, [target.id, folderId, uidValidity, uid, target.accountId]);
|
|
271
|
+
if ((result.rowCount ?? 0) > 0)
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
await db.query(`update email.messages set folder_id = $2, uidvalidity = 0, uid = $3 where id = $1`, [
|
|
275
|
+
target.id,
|
|
276
|
+
folderId,
|
|
277
|
+
placeholderUid(),
|
|
278
|
+
]);
|
|
279
|
+
}
|
|
280
|
+
async function setSeenLocally(db, ids, seen) {
|
|
281
|
+
if (ids.length === 0)
|
|
282
|
+
return;
|
|
283
|
+
await db.query(seen
|
|
284
|
+
? `update email.messages set flags = flags || '["\\\\Seen"]'::jsonb
|
|
285
|
+
where id = any($1::uuid[]) and not (flags @> '["\\\\Seen"]'::jsonb)`
|
|
286
|
+
: `update email.messages set flags = flags - '\\Seen' where id = any($1::uuid[])`, [ids]);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Find where each target is now, on the server: its folder's generation must
|
|
290
|
+
* match, and a row whose uid is unknown (UIDVALIDITY 0) is looked up by
|
|
291
|
+
* Message-ID. Returns the uid per target, or null for one that is not there.
|
|
292
|
+
*/
|
|
293
|
+
async function locate(client, folder, targets) {
|
|
294
|
+
const status = await client.open(folder);
|
|
295
|
+
const uids = new Map();
|
|
296
|
+
for (const t of targets) {
|
|
297
|
+
if (t.uidValidity === status.uidValidity && t.uid > 0) {
|
|
298
|
+
uids.set(t.id, t.uid);
|
|
299
|
+
}
|
|
300
|
+
else if (t.messageId) {
|
|
301
|
+
const found = await client.findByMessageId(folder, t.messageId);
|
|
302
|
+
if (found !== null)
|
|
303
|
+
uids.set(t.id, found);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
const out = new Map();
|
|
307
|
+
if (uids.size === 0)
|
|
308
|
+
return out;
|
|
309
|
+
const states = await client.fetchFlags(folder, [...uids.values()]);
|
|
310
|
+
const flagsOf = new Map(states.map((s) => [s.uid, s.flags]));
|
|
311
|
+
for (const [id, uid] of uids) {
|
|
312
|
+
const flags = flagsOf.get(uid);
|
|
313
|
+
if (flags)
|
|
314
|
+
out.set(id, { uid, flags });
|
|
315
|
+
}
|
|
316
|
+
return out;
|
|
317
|
+
}
|
|
318
|
+
function byFolder(targets) {
|
|
319
|
+
const groups = new Map();
|
|
320
|
+
for (const t of targets) {
|
|
321
|
+
const list = groups.get(t.folder) ?? [];
|
|
322
|
+
list.push(t);
|
|
323
|
+
groups.set(t.folder, list);
|
|
324
|
+
}
|
|
325
|
+
return groups;
|
|
326
|
+
}
|
|
327
|
+
/** Where the moved messages landed: COPYUID first, a Message-ID search for the rest. */
|
|
328
|
+
async function landed(client, destination, moved, result) {
|
|
329
|
+
const uids = new Map();
|
|
330
|
+
const unknown = [];
|
|
331
|
+
for (const m of moved) {
|
|
332
|
+
const to = result.uidMap.get(m.uid);
|
|
333
|
+
if (to !== undefined)
|
|
334
|
+
uids.set(m.target.id, to);
|
|
335
|
+
else
|
|
336
|
+
unknown.push(m);
|
|
337
|
+
}
|
|
338
|
+
let uidValidity = result.uidValidity;
|
|
339
|
+
if (unknown.length > 0 || uidValidity === null) {
|
|
340
|
+
const status = await client.open(destination);
|
|
341
|
+
uidValidity = uidValidity ?? status.uidValidity;
|
|
342
|
+
for (const m of unknown) {
|
|
343
|
+
uids.set(m.target.id, m.target.messageId ? await client.findByMessageId(destination, m.target.messageId) : null);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return { uidValidity, uids };
|
|
347
|
+
}
|
|
348
|
+
async function recordAction(db, input) {
|
|
349
|
+
const p = input.provenance;
|
|
350
|
+
const { rows } = await db.query(`insert into email.mailbox_actions
|
|
351
|
+
(account_id, kind, destination, criteria, origin, actor, policy_id, run_id, action_id, message_ids,
|
|
352
|
+
items, changed, note, reverts, created_at)
|
|
353
|
+
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10::uuid[], $11::jsonb, $12, $13, $14, $15)
|
|
354
|
+
returning ${ACTION_COLUMNS}`, [
|
|
355
|
+
input.accountId,
|
|
356
|
+
input.kind,
|
|
357
|
+
input.destination,
|
|
358
|
+
p.criteria ?? null,
|
|
359
|
+
p.origin,
|
|
360
|
+
p.actor,
|
|
361
|
+
p.policyId ?? null,
|
|
362
|
+
p.runId ?? null,
|
|
363
|
+
p.actionId ?? null,
|
|
364
|
+
input.messageIds,
|
|
365
|
+
JSON.stringify(input.items),
|
|
366
|
+
input.changed,
|
|
367
|
+
input.note,
|
|
368
|
+
input.reverts ?? null,
|
|
369
|
+
input.now,
|
|
370
|
+
]);
|
|
371
|
+
return toAction(rows[0]);
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Carry out one change on one account's server, keep the rows in step, and
|
|
375
|
+
* write it on the trail.
|
|
376
|
+
*
|
|
377
|
+
* Messages no longer where buddi last saw them are skipped, never guessed at,
|
|
378
|
+
* and the note says how many. Nothing is recorded when nothing changed.
|
|
379
|
+
*/
|
|
380
|
+
export async function performAction(db, client, input) {
|
|
381
|
+
const { account, kind, targets } = input;
|
|
382
|
+
const facts = input.facts ?? (await serverFacts(client));
|
|
383
|
+
const destination = destinationFor(facts, kind, account.address, input.folder);
|
|
384
|
+
const items = [];
|
|
385
|
+
const reasons = new Map();
|
|
386
|
+
const skip = (why, n = 1) => {
|
|
387
|
+
if (n > 0)
|
|
388
|
+
reasons.set(why, (reasons.get(why) ?? 0) + n);
|
|
389
|
+
};
|
|
390
|
+
// Whatever the server already did stays on the trail even if a later
|
|
391
|
+
// folder fails (a dropped connection, a lookup): the change is recorded as
|
|
392
|
+
// partial, with the error, and the error is thrown on.
|
|
393
|
+
try {
|
|
394
|
+
for (const [folder, group] of byFolder(targets)) {
|
|
395
|
+
const here = await locate(client, folder, group);
|
|
396
|
+
skip(`no longer in ${folder}`, group.length - here.size);
|
|
397
|
+
const present = group.filter((t) => here.has(t.id));
|
|
398
|
+
if (present.length === 0)
|
|
399
|
+
continue;
|
|
400
|
+
if (kind === 'mark-read' || kind === 'mark-unread') {
|
|
401
|
+
const seen = kind === 'mark-read';
|
|
402
|
+
const change = present.filter((t) => here.get(t.id).flags.includes(SEEN) !== seen);
|
|
403
|
+
skip(seen ? 'already read' : 'already unread', present.length - change.length);
|
|
404
|
+
if (change.length === 0)
|
|
405
|
+
continue;
|
|
406
|
+
await client.storeFlags(folder, change.map((t) => here.get(t.id).uid), [SEEN], seen ? 'add' : 'remove');
|
|
407
|
+
for (const t of change) {
|
|
408
|
+
const at = here.get(t.id);
|
|
409
|
+
items.push({
|
|
410
|
+
id: t.id, subject: t.subject, from: t.from, messageId: t.messageId,
|
|
411
|
+
fromFolder: folder, fromUidValidity: t.uidValidity > 0 ? t.uidValidity : 0, fromUid: at.uid,
|
|
412
|
+
prevFlags: at.flags,
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
await setSeenLocally(db, change.map((t) => t.id), seen);
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
// A move of some kind. Already there is not a change.
|
|
419
|
+
let movable = present.filter((t) => folder !== destination);
|
|
420
|
+
skip(kind === 'trash' ? 'already in Trash' : `already in ${destination}`, present.length - movable.length);
|
|
421
|
+
if (kind === 'archive' && facts.gmail && folder !== INBOX) {
|
|
422
|
+
skip('not in the inbox', movable.length);
|
|
423
|
+
movable = [];
|
|
424
|
+
}
|
|
425
|
+
if (movable.length === 0)
|
|
426
|
+
continue;
|
|
427
|
+
const source = await client.open(folder);
|
|
428
|
+
const labels = facts.gmail && kind === 'trash'
|
|
429
|
+
? await client.fetchLabels(folder, movable.map((t) => here.get(t.id).uid))
|
|
430
|
+
: new Map();
|
|
431
|
+
const moved = movable.map((t) => ({ target: t, uid: here.get(t.id).uid }));
|
|
432
|
+
const result = await client.move(folder, moved.map((m) => m.uid), destination);
|
|
433
|
+
// The server has moved them: on the trail now, refined below. Should the
|
|
434
|
+
// landing lookup fail, each row still follows to the destination with its
|
|
435
|
+
// uid unknown (found by Message-ID next time), so undo can find it.
|
|
436
|
+
const pushed = moved.map((m) => {
|
|
437
|
+
const item = {
|
|
438
|
+
id: m.target.id, subject: m.target.subject, from: m.target.from, messageId: m.target.messageId,
|
|
439
|
+
fromFolder: folder, fromUidValidity: source.uidValidity, fromUid: m.uid,
|
|
440
|
+
toFolder: destination, toUidValidity: 0, toUid: null,
|
|
441
|
+
prevFlags: here.get(m.target.id).flags,
|
|
442
|
+
...(labels.has(m.uid) ? { prevLabels: labels.get(m.uid) } : {}),
|
|
443
|
+
};
|
|
444
|
+
items.push(item);
|
|
445
|
+
return item;
|
|
446
|
+
});
|
|
447
|
+
const destId = await folderRow(db, account.id, destination);
|
|
448
|
+
let where;
|
|
449
|
+
try {
|
|
450
|
+
where = await landed(client, destination, moved, result);
|
|
451
|
+
}
|
|
452
|
+
catch (err) {
|
|
453
|
+
for (const m of moved)
|
|
454
|
+
await relocateRow(db, m.target, destId, null, null);
|
|
455
|
+
throw err;
|
|
456
|
+
}
|
|
457
|
+
for (const [i, m] of moved.entries()) {
|
|
458
|
+
const newUid = where.uids.get(m.target.id) ?? null;
|
|
459
|
+
await relocateRow(db, m.target, destId, newUid === null ? null : where.uidValidity, newUid);
|
|
460
|
+
pushed[i].toUidValidity = where.uidValidity ?? 0;
|
|
461
|
+
pushed[i].toUid = newUid;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
catch (err) {
|
|
466
|
+
if (items.length > 0) {
|
|
467
|
+
const why = err instanceof Error ? err.message : String(err);
|
|
468
|
+
const skippedNote = [...reasons.entries()].map(([r, n]) => `${n} ${r}`).join(', ');
|
|
469
|
+
await recordAction(db, {
|
|
470
|
+
accountId: account.id,
|
|
471
|
+
kind,
|
|
472
|
+
destination,
|
|
473
|
+
provenance: input.provenance,
|
|
474
|
+
messageIds: items.map((i) => i.id),
|
|
475
|
+
items,
|
|
476
|
+
changed: items.length,
|
|
477
|
+
note: `Partial: stopped by an error after ${plural(items.length, 'message')}: ${why}.${skippedNote ? ` Skipped ${skippedNote}.` : ''}`,
|
|
478
|
+
now: input.now,
|
|
479
|
+
}).catch(() => { });
|
|
480
|
+
}
|
|
481
|
+
throw err;
|
|
482
|
+
}
|
|
483
|
+
const skipped = [...reasons.values()].reduce((a, b) => a + b, 0);
|
|
484
|
+
const skippedNote = [...reasons.entries()].map(([why, n]) => `${n} ${why}`).join(', ');
|
|
485
|
+
const done = `${verbOf(kind, destination)}: ${plural(items.length, 'message')} in ${account.address}`;
|
|
486
|
+
const note = items.length === 0
|
|
487
|
+
? `Nothing changed in ${account.address}${skippedNote ? ` (${skippedNote})` : ''}.`
|
|
488
|
+
: `${done}.${skippedNote ? ` Skipped ${skippedNote}.` : ''}${kind === 'trash' ? ' They are in Trash, not deleted; undo puts them back while they are still there.' : ' Undo puts them back.'}`;
|
|
489
|
+
if (items.length === 0)
|
|
490
|
+
return { action: null, changed: 0, skipped, note };
|
|
491
|
+
const action = await recordAction(db, {
|
|
492
|
+
accountId: account.id,
|
|
493
|
+
kind,
|
|
494
|
+
destination,
|
|
495
|
+
provenance: input.provenance,
|
|
496
|
+
messageIds: items.map((i) => i.id),
|
|
497
|
+
items,
|
|
498
|
+
changed: items.length,
|
|
499
|
+
note: skippedNote ? `Skipped ${skippedNote}.` : null,
|
|
500
|
+
now: input.now,
|
|
501
|
+
});
|
|
502
|
+
return { action, changed: items.length, skipped, note };
|
|
503
|
+
}
|
|
504
|
+
/* ------------------------------------------------------------------ *
|
|
505
|
+
* Undo
|
|
506
|
+
* ------------------------------------------------------------------ */
|
|
507
|
+
export async function findAction(db, id) {
|
|
508
|
+
const { rows } = await db.query(`select ${ACTION_COLUMNS} from email.mailbox_actions where id = $1::uuid`, [id]);
|
|
509
|
+
return rows[0] ? toAction(rows[0]) : null;
|
|
510
|
+
}
|
|
511
|
+
/** The newest change that can still be undone, in these accounts. */
|
|
512
|
+
export async function lastUndoable(db, accountIds) {
|
|
513
|
+
const { rows } = await db.query(`select ${ACTION_COLUMNS} from email.mailbox_actions
|
|
514
|
+
where account_id = any($1::uuid[]) and kind <> 'undo' and undone_at is null
|
|
515
|
+
order by created_at desc, seq desc limit 1`, [accountIds]);
|
|
516
|
+
return rows[0] ? toAction(rows[0]) : null;
|
|
517
|
+
}
|
|
518
|
+
/** Why a change cannot be undone, or null when it can. */
|
|
519
|
+
export function undoRefusal(action) {
|
|
520
|
+
if (action.kind === 'undo')
|
|
521
|
+
return 'That was itself an undo; buddi does not undo an undo. Make the change again instead.';
|
|
522
|
+
if (action.undoneAt)
|
|
523
|
+
return `That change was already undone (${action.undoneAt}).`;
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
/** The sentence an undo's approval and the Recent changes row say. */
|
|
527
|
+
export function describeUndo(action, account) {
|
|
528
|
+
const n = plural(action.changed, 'message');
|
|
529
|
+
switch (action.kind) {
|
|
530
|
+
case 'mark-read':
|
|
531
|
+
return `Undo "${verbOf(action.kind)}" on ${n} in ${account}: they become unread again.`;
|
|
532
|
+
case 'mark-unread':
|
|
533
|
+
return `Undo "${verbOf(action.kind)}" on ${n} in ${account}: they become read again.`;
|
|
534
|
+
case 'trash':
|
|
535
|
+
return `Undo "${verbOf(action.kind)}" on ${n} in ${account}: they move back from Trash to where they were (any already emptied from Trash cannot come back).`;
|
|
536
|
+
default:
|
|
537
|
+
return `Undo "${verbOf(action.kind, action.destination)}" on ${n} in ${account}: they move back to where they were.`;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Put one change back, as far as the mailbox still allows, and record the
|
|
542
|
+
* undo as a change of its own.
|
|
543
|
+
*
|
|
544
|
+
* Each message is acted on where buddi's row says it is now — the row
|
|
545
|
+
* followed it — and only if the server still has it there: a message emptied
|
|
546
|
+
* from Trash, or moved again in another client, is skipped and counted.
|
|
547
|
+
*/
|
|
548
|
+
export async function undoAction(db, client, input) {
|
|
549
|
+
const { account, action } = input;
|
|
550
|
+
const refusal = undoRefusal(action);
|
|
551
|
+
if (refusal)
|
|
552
|
+
throw new MailboxRefusal(refusal);
|
|
553
|
+
const facts = await serverFacts(client);
|
|
554
|
+
const current = await loadTargets(db, action.items.map((i) => i.id));
|
|
555
|
+
const itemOf = new Map(action.items.map((i) => [i.id, i]));
|
|
556
|
+
const items = [];
|
|
557
|
+
let skipped = action.items.length - current.length;
|
|
558
|
+
for (const [folder, group] of byFolder(current)) {
|
|
559
|
+
const here = await locate(client, folder, group);
|
|
560
|
+
skipped += group.length - here.size;
|
|
561
|
+
const present = group.filter((t) => here.has(t.id));
|
|
562
|
+
if (present.length === 0)
|
|
563
|
+
continue;
|
|
564
|
+
if (action.kind === 'mark-read' || action.kind === 'mark-unread') {
|
|
565
|
+
const restoreSeen = present.filter((t) => (itemOf.get(t.id).prevFlags ?? []).includes(SEEN));
|
|
566
|
+
const restoreUnseen = present.filter((t) => !(itemOf.get(t.id).prevFlags ?? []).includes(SEEN));
|
|
567
|
+
if (restoreSeen.length > 0) {
|
|
568
|
+
await client.storeFlags(folder, restoreSeen.map((t) => here.get(t.id).uid), [SEEN], 'add');
|
|
569
|
+
await setSeenLocally(db, restoreSeen.map((t) => t.id), true);
|
|
570
|
+
}
|
|
571
|
+
if (restoreUnseen.length > 0) {
|
|
572
|
+
await client.storeFlags(folder, restoreUnseen.map((t) => here.get(t.id).uid), [SEEN], 'remove');
|
|
573
|
+
await setSeenLocally(db, restoreUnseen.map((t) => t.id), false);
|
|
574
|
+
}
|
|
575
|
+
for (const t of present) {
|
|
576
|
+
items.push({
|
|
577
|
+
id: t.id, subject: t.subject, from: t.from, messageId: t.messageId,
|
|
578
|
+
fromFolder: folder, fromUidValidity: t.uidValidity, fromUid: here.get(t.id).uid,
|
|
579
|
+
prevFlags: here.get(t.id).flags,
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
continue;
|
|
583
|
+
}
|
|
584
|
+
// Moves: back to each message's own original folder.
|
|
585
|
+
const back = new Map();
|
|
586
|
+
for (const t of present) {
|
|
587
|
+
const original = itemOf.get(t.id).fromFolder;
|
|
588
|
+
if (original === folder) {
|
|
589
|
+
skipped += 1;
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const list = back.get(original) ?? [];
|
|
593
|
+
list.push(t);
|
|
594
|
+
back.set(original, list);
|
|
595
|
+
}
|
|
596
|
+
for (const [original, list] of back) {
|
|
597
|
+
if (!facts.listing.some((f) => f.name === original)) {
|
|
598
|
+
skipped += list.length;
|
|
599
|
+
continue;
|
|
600
|
+
}
|
|
601
|
+
const source = await client.open(folder);
|
|
602
|
+
const moved = list.map((t) => ({ target: t, uid: here.get(t.id).uid }));
|
|
603
|
+
const result = await client.move(folder, moved.map((m) => m.uid), original);
|
|
604
|
+
const where = await landed(client, original, moved, result);
|
|
605
|
+
const destId = await folderRow(db, account.id, original);
|
|
606
|
+
for (const m of moved) {
|
|
607
|
+
const newUid = where.uids.get(m.target.id) ?? null;
|
|
608
|
+
await relocateRow(db, m.target, destId, newUid === null ? null : where.uidValidity, newUid);
|
|
609
|
+
items.push({
|
|
610
|
+
id: m.target.id, subject: m.target.subject, from: m.target.from, messageId: m.target.messageId,
|
|
611
|
+
fromFolder: folder, fromUidValidity: source.uidValidity, fromUid: m.uid,
|
|
612
|
+
toFolder: original, toUidValidity: where.uidValidity ?? 0, toUid: newUid,
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
// Gmail drops a message's labels in Trash: give back the ones it had.
|
|
616
|
+
if (facts.gmail) {
|
|
617
|
+
const byLabels = new Map();
|
|
618
|
+
for (const m of moved) {
|
|
619
|
+
const prev = itemOf.get(m.target.id).prevLabels ?? [];
|
|
620
|
+
const uid = where.uids.get(m.target.id);
|
|
621
|
+
if (prev.length === 0 || uid === null || uid === undefined)
|
|
622
|
+
continue;
|
|
623
|
+
const key = JSON.stringify([...prev].sort());
|
|
624
|
+
byLabels.set(key, [...(byLabels.get(key) ?? []), uid]);
|
|
625
|
+
}
|
|
626
|
+
for (const [key, uids] of byLabels)
|
|
627
|
+
await client.addLabels(original, uids, JSON.parse(key));
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
const note = items.length === 0
|
|
632
|
+
? `Nothing could be put back in ${account.address}${skipped > 0 ? ` (${plural(skipped, 'message')} no longer where the change left ${skipped === 1 ? 'it' : 'them'})` : ''}.`
|
|
633
|
+
: `Undid "${verbOf(action.kind, action.destination)}" on ${plural(items.length, 'message')} in ${account.address}.${skipped > 0 ? ` ${plural(skipped, 'message')} could not be put back: no longer where the change left ${skipped === 1 ? 'it' : 'them'}.` : ''}`;
|
|
634
|
+
if (items.length === 0)
|
|
635
|
+
return { action: null, changed: 0, skipped, note };
|
|
636
|
+
const undo = await recordAction(db, {
|
|
637
|
+
accountId: account.id,
|
|
638
|
+
kind: 'undo',
|
|
639
|
+
destination: null,
|
|
640
|
+
provenance: input.provenance,
|
|
641
|
+
messageIds: items.map((i) => i.id),
|
|
642
|
+
items,
|
|
643
|
+
changed: items.length,
|
|
644
|
+
note: skipped > 0 ? `${plural(skipped, 'message')} could not be put back.` : null,
|
|
645
|
+
reverts: action.id,
|
|
646
|
+
now: input.now,
|
|
647
|
+
});
|
|
648
|
+
await db.query(`update email.mailbox_actions set undone_at = $2, undone_by = $3 where id = $1`, [
|
|
649
|
+
action.id,
|
|
650
|
+
input.now,
|
|
651
|
+
undo.id,
|
|
652
|
+
]);
|
|
653
|
+
return { action: undo, changed: items.length, skipped, note };
|
|
654
|
+
}
|
|
655
|
+
/** The newest changes, for the Mail page's Recent changes. */
|
|
656
|
+
export async function recentActions(db, accountIds, limit = 20) {
|
|
657
|
+
const { rows } = await db.query(`select ${ACTION_COLUMNS} from email.mailbox_actions
|
|
658
|
+
where account_id = any($1::uuid[])
|
|
659
|
+
order by created_at desc, seq desc limit $2`, [accountIds, limit]);
|
|
660
|
+
return rows.map(toAction);
|
|
661
|
+
}
|
|
662
|
+
//# sourceMappingURL=actions.js.map
|