@withbuddi/buddi 0.1.0-pre.27 → 0.1.0-pre.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/extension/manifest.json +2 -2
- package/node_modules/@buddi/cli/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/cli/dist/args.d.ts +13 -2
- package/node_modules/@buddi/cli/dist/args.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/args.js +12 -3
- package/node_modules/@buddi/cli/dist/args.js.map +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 +301 -20
- package/node_modules/@buddi/cli/dist/commands.js.map +1 -1
- package/node_modules/@buddi/cli/dist/dashboard-cmd.d.ts +3 -0
- package/node_modules/@buddi/cli/dist/dashboard-cmd.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/dashboard-cmd.js +63 -0
- package/node_modules/@buddi/cli/dist/dashboard-cmd.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 +12 -10
- package/node_modules/@buddi/cli/dist/doctor-probes.js.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor.d.ts +14 -1
- 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/main.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/main.js +22 -1
- package/node_modules/@buddi/cli/dist/main.js.map +1 -1
- package/node_modules/@buddi/cli/dist/mcp/gateway-client.d.ts +19 -17
- package/node_modules/@buddi/cli/dist/mcp/gateway-client.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/mcp/gateway-client.js +128 -29
- package/node_modules/@buddi/cli/dist/mcp/gateway-client.js.map +1 -1
- package/node_modules/@buddi/cli/dist/mcp/tools.d.ts +6 -0
- package/node_modules/@buddi/cli/dist/mcp/tools.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/mcp/tools.js +23 -3
- package/node_modules/@buddi/cli/dist/mcp/tools.js.map +1 -1
- package/node_modules/@buddi/cli/dist/telegram-cmd.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/telegram-cmd.js +5 -4
- package/node_modules/@buddi/cli/dist/telegram-cmd.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 +8 -6
- 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 +22 -12
- 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/agents/skills.d.ts +2 -2
- 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/clock-widget.d.ts +38 -0
- package/node_modules/@buddi/core/dist/clock-widget.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/clock-widget.js +114 -0
- package/node_modules/@buddi/core/dist/clock-widget.js.map +1 -0
- package/node_modules/@buddi/core/dist/failures/owner-message.d.ts +25 -0
- package/node_modules/@buddi/core/dist/failures/owner-message.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/failures/owner-message.js +90 -0
- package/node_modules/@buddi/core/dist/failures/owner-message.js.map +1 -1
- package/node_modules/@buddi/core/dist/feedback/index.d.ts +129 -0
- package/node_modules/@buddi/core/dist/feedback/index.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/feedback/index.js +180 -0
- package/node_modules/@buddi/core/dist/feedback/index.js.map +1 -0
- package/node_modules/@buddi/core/dist/groups.d.ts +33 -0
- package/node_modules/@buddi/core/dist/groups.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/groups.js +76 -4
- package/node_modules/@buddi/core/dist/groups.js.map +1 -1
- package/node_modules/@buddi/core/dist/home.d.ts +5 -5
- package/node_modules/@buddi/core/dist/host/build.d.ts +19 -1
- package/node_modules/@buddi/core/dist/host/build.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/host/build.js +150 -3
- package/node_modules/@buddi/core/dist/host/build.js.map +1 -1
- package/node_modules/@buddi/core/dist/host/types.d.ts +62 -2
- package/node_modules/@buddi/core/dist/host/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/index.d.ts +9 -0
- package/node_modules/@buddi/core/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/index.js +9 -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/lock.d.ts +76 -0
- package/node_modules/@buddi/core/dist/lock.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/lock.js +167 -0
- package/node_modules/@buddi/core/dist/lock.js.map +1 -0
- package/node_modules/@buddi/core/dist/metrics.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/metrics.js +4 -2
- package/node_modules/@buddi/core/dist/metrics.js.map +1 -1
- package/node_modules/@buddi/core/dist/onboarding/store.d.ts +5 -0
- package/node_modules/@buddi/core/dist/onboarding/store.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/onboarding/store.js +35 -5
- package/node_modules/@buddi/core/dist/onboarding/store.js.map +1 -1
- package/node_modules/@buddi/core/dist/onboarding/types.d.ts +10 -0
- package/node_modules/@buddi/core/dist/onboarding/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/onboarding/types.js +2 -0
- package/node_modules/@buddi/core/dist/onboarding/types.js.map +1 -1
- package/node_modules/@buddi/core/dist/owner-format.d.ts +14 -0
- package/node_modules/@buddi/core/dist/owner-format.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/owner-format.js +47 -0
- package/node_modules/@buddi/core/dist/owner-format.js.map +1 -0
- package/node_modules/@buddi/core/dist/owner-timezone.d.ts +46 -0
- package/node_modules/@buddi/core/dist/owner-timezone.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/owner-timezone.js +43 -0
- package/node_modules/@buddi/core/dist/owner-timezone.js.map +1 -0
- 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 +37 -38
- package/node_modules/@buddi/core/dist/pages.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/pages.js +30 -3
- package/node_modules/@buddi/core/dist/pages.js.map +1 -1
- package/node_modules/@buddi/core/dist/places.d.ts +110 -0
- package/node_modules/@buddi/core/dist/places.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/places.js +239 -0
- package/node_modules/@buddi/core/dist/places.js.map +1 -0
- package/node_modules/@buddi/core/dist/plugin/index.d.ts +13 -5
- package/node_modules/@buddi/core/dist/plugin/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/index.js +3 -0
- package/node_modules/@buddi/core/dist/plugin/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/requires.d.ts +75 -0
- package/node_modules/@buddi/core/dist/plugin/requires.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/plugin/requires.js +77 -0
- package/node_modules/@buddi/core/dist/plugin/requires.js.map +1 -0
- package/node_modules/@buddi/core/dist/plugin/uses.d.ts +1 -1
- package/node_modules/@buddi/core/dist/plugin/uses.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/plugin/uses.js +2 -0
- package/node_modules/@buddi/core/dist/plugin/uses.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/queue/retry-policy.d.ts +5 -0
- package/node_modules/@buddi/core/dist/queue/retry-policy.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/queue/retry-policy.js +19 -2
- package/node_modules/@buddi/core/dist/queue/retry-policy.js.map +1 -1
- package/node_modules/@buddi/core/dist/registry.d.ts +47 -3
- package/node_modules/@buddi/core/dist/registry.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/registry.js +150 -3
- package/node_modules/@buddi/core/dist/registry.js.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/enqueue.d.ts +71 -0
- package/node_modules/@buddi/core/dist/scheduler/enqueue.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/scheduler/enqueue.js +116 -0
- package/node_modules/@buddi/core/dist/scheduler/enqueue.js.map +1 -0
- package/node_modules/@buddi/core/dist/scheduler/index.d.ts +1 -0
- package/node_modules/@buddi/core/dist/scheduler/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/index.js +1 -0
- package/node_modules/@buddi/core/dist/scheduler/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/missions.d.ts +15 -0
- package/node_modules/@buddi/core/dist/scheduler/missions.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/missions.js +43 -4
- package/node_modules/@buddi/core/dist/scheduler/missions.js.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/types.d.ts +10 -0
- package/node_modules/@buddi/core/dist/scheduler/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/scheduler/types.js +3 -0
- package/node_modules/@buddi/core/dist/scheduler/types.js.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/settings.d.ts +6 -6
- package/node_modules/@buddi/core/dist/semver.d.ts +17 -0
- package/node_modules/@buddi/core/dist/semver.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/semver.js +130 -0
- package/node_modules/@buddi/core/dist/semver.js.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/run.d.ts +6 -1
- package/node_modules/@buddi/core/dist/sentinels/run.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/run.js +43 -24
- package/node_modules/@buddi/core/dist/sentinels/run.js.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/types.d.ts +13 -0
- package/node_modules/@buddi/core/dist/sentinels/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/types.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/run.d.ts +8 -0
- package/node_modules/@buddi/core/dist/sources/run.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/sources/run.js +1 -1
- package/node_modules/@buddi/core/dist/sources/run.js.map +1 -1
- package/node_modules/@buddi/core/dist/sources/watch.d.ts +40 -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/time.d.ts +17 -3
- package/node_modules/@buddi/core/dist/time.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/time.js +27 -3
- package/node_modules/@buddi/core/dist/time.js.map +1 -1
- package/node_modules/@buddi/core/dist/tools.d.ts +77 -1
- 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/dist/views.d.ts +68 -68
- package/node_modules/@buddi/core/dist/views.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/views.js +3 -0
- package/node_modules/@buddi/core/dist/views.js.map +1 -1
- package/node_modules/@buddi/core/dist/widget-settings.d.ts +161 -0
- package/node_modules/@buddi/core/dist/widget-settings.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/widget-settings.js +314 -0
- package/node_modules/@buddi/core/dist/widget-settings.js.map +1 -0
- package/node_modules/@buddi/core/dist/widgets.d.ts +206 -0
- package/node_modules/@buddi/core/dist/widgets.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/widgets.js +247 -0
- package/node_modules/@buddi/core/dist/widgets.js.map +1 -0
- 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/core/migrations/059_dashboard_lock.sql +33 -0
- package/node_modules/@buddi/core/migrations/060_owner_places.sql +30 -0
- package/node_modules/@buddi/core/migrations/061_owner_formats.sql +10 -0
- package/node_modules/@buddi/core/migrations/062_group_deleted.sql +7 -0
- package/node_modules/@buddi/core/migrations/063_provider_account_limits.sql +20 -0
- package/node_modules/@buddi/core/migrations/064_mission_coalesce.sql +12 -0
- package/node_modules/@buddi/core/migrations/065_api_tokens.sql +28 -0
- package/node_modules/@buddi/gateway/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/gateway/dist/account-limits.d.ts +45 -0
- package/node_modules/@buddi/gateway/dist/account-limits.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/account-limits.js +87 -0
- package/node_modules/@buddi/gateway/dist/account-limits.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/accounts-cli.d.ts +88 -0
- package/node_modules/@buddi/gateway/dist/accounts-cli.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/accounts-cli.js +216 -0
- package/node_modules/@buddi/gateway/dist/accounts-cli.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/agents/canvas.d.ts +20 -20
- package/node_modules/@buddi/gateway/dist/agents/learning-digest.d.ts +11 -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 +43 -4
- package/node_modules/@buddi/gateway/dist/agents/learning-digest.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/owner-tools.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/owner-tools.js +3 -2
- package/node_modules/@buddi/gateway/dist/agents/owner-tools.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 +40 -20
- 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/api-token-cli.d.ts +17 -0
- package/node_modules/@buddi/gateway/dist/api-token-cli.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/api-token-cli.js +108 -0
- package/node_modules/@buddi/gateway/dist/api-token-cli.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/bootstrap.d.ts +6 -2
- package/node_modules/@buddi/gateway/dist/bootstrap.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/bootstrap.js +25 -7
- package/node_modules/@buddi/gateway/dist/bootstrap.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/chat/session.d.ts +5 -0
- package/node_modules/@buddi/gateway/dist/chat/session.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/chat/session.js +13 -2
- package/node_modules/@buddi/gateway/dist/chat/session.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/cli.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/cli.js +14 -3
- package/node_modules/@buddi/gateway/dist/cli.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/index.d.ts +3 -0
- package/node_modules/@buddi/gateway/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/index.js +3 -0
- package/node_modules/@buddi/gateway/dist/index.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/missions/dead-letter.d.ts +2 -1
- package/node_modules/@buddi/gateway/dist/missions/dead-letter.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/dead-letter.js +19 -5
- package/node_modules/@buddi/gateway/dist/missions/dead-letter.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/defaults.d.ts +6 -0
- package/node_modules/@buddi/gateway/dist/missions/defaults.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/defaults.js +10 -2
- package/node_modules/@buddi/gateway/dist/missions/defaults.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/execute.js +14 -8
- package/node_modules/@buddi/gateway/dist/missions/execute.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/inline.js +1 -1
- package/node_modules/@buddi/gateway/dist/missions/inline.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/sentinel-wake.d.ts +11 -0
- package/node_modules/@buddi/gateway/dist/missions/sentinel-wake.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/sentinel-wake.js +37 -1
- package/node_modules/@buddi/gateway/dist/missions/sentinel-wake.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions-cli.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions-cli.js +5 -5
- package/node_modules/@buddi/gateway/dist/missions-cli.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/nudges-cli.js +2 -2
- package/node_modules/@buddi/gateway/dist/nudges-cli.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/owner-seed.js +2 -2
- package/node_modules/@buddi/gateway/dist/owner-seed.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/live.d.ts +8 -1
- package/node_modules/@buddi/gateway/dist/plugins/live.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/live.js +25 -7
- package/node_modules/@buddi/gateway/dist/plugins/live.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/load.d.ts +55 -0
- package/node_modules/@buddi/gateway/dist/plugins/load.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/load.js +100 -4
- package/node_modules/@buddi/gateway/dist/plugins/load.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/requires.d.ts +79 -0
- package/node_modules/@buddi/gateway/dist/plugins/requires.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/plugins/requires.js +178 -0
- package/node_modules/@buddi/gateway/dist/plugins/requires.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/plugins/stage.d.ts +33 -3
- package/node_modules/@buddi/gateway/dist/plugins/stage.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/stage.js +41 -6
- package/node_modules/@buddi/gateway/dist/plugins/stage.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/update.d.ts +21 -0
- package/node_modules/@buddi/gateway/dist/plugins/update.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/update.js +16 -0
- package/node_modules/@buddi/gateway/dist/plugins/update.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins-cli.d.ts +5 -1
- package/node_modules/@buddi/gateway/dist/plugins-cli.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins-cli.js +48 -11
- package/node_modules/@buddi/gateway/dist/plugins-cli.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/provider-accounts.d.ts +4 -0
- package/node_modules/@buddi/gateway/dist/provider-accounts.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/provider-accounts.js +68 -10
- package/node_modules/@buddi/gateway/dist/provider-accounts.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/provider-diagnostics.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/provider-diagnostics.js +9 -0
- package/node_modules/@buddi/gateway/dist/provider-diagnostics.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/reminders-cli.js +2 -2
- package/node_modules/@buddi/gateway/dist/reminders-cli.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.d.ts +2 -0
- package/node_modules/@buddi/gateway/dist/serve.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/serve.js +78 -8
- 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/surfaces/failure.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/failure.js +9 -1
- package/node_modules/@buddi/gateway/dist/surfaces/failure.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/system-context.d.ts +18 -0
- package/node_modules/@buddi/gateway/dist/system-context.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/system-context.js +46 -4
- package/node_modules/@buddi/gateway/dist/system-context.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 +21 -28
- 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 +3 -3
- package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/outbound.js +19 -5
- 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 +107 -0
- package/node_modules/@buddi/gateway/dist/telegram/reactions.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts +5 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.js +93 -12
- package/node_modules/@buddi/gateway/dist/telegram/surface.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/engine.d.ts +2 -0
- package/node_modules/@buddi/gateway/dist/tips/engine.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/engine.js +8 -5
- package/node_modules/@buddi/gateway/dist/tips/engine.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/facts.d.ts +23 -0
- package/node_modules/@buddi/gateway/dist/tips/facts.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/facts.js +19 -0
- package/node_modules/@buddi/gateway/dist/tips/facts.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/route.js +2 -2
- package/node_modules/@buddi/gateway/dist/tips/route.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/rules.d.ts +3 -2
- package/node_modules/@buddi/gateway/dist/tips/rules.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/tips/rules.js +26 -0
- package/node_modules/@buddi/gateway/dist/tips/rules.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/api-routes.d.ts +103 -0
- package/node_modules/@buddi/gateway/dist/web/api-routes.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/api-routes.js +1200 -0
- package/node_modules/@buddi/gateway/dist/web/api-routes.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/api-scan.d.ts +17 -0
- package/node_modules/@buddi/gateway/dist/web/api-scan.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/api-scan.js +206 -0
- package/node_modules/@buddi/gateway/dist/web/api-scan.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/api-tokens.d.ts +58 -0
- package/node_modules/@buddi/gateway/dist/web/api-tokens.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/api-tokens.js +136 -0
- package/node_modules/@buddi/gateway/dist/web/api-tokens.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/backups.js +2 -2
- package/node_modules/@buddi/gateway/dist/web/backups.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/group-lifecycle.d.ts +18 -0
- package/node_modules/@buddi/gateway/dist/web/group-lifecycle.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/group-lifecycle.js +46 -0
- package/node_modules/@buddi/gateway/dist/web/group-lifecycle.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/lock-image.d.ts +37 -0
- package/node_modules/@buddi/gateway/dist/web/lock-image.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/lock-image.js +253 -0
- package/node_modules/@buddi/gateway/dist/web/lock-image.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/lock.d.ts +162 -0
- package/node_modules/@buddi/gateway/dist/web/lock.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/lock.js +472 -0
- package/node_modules/@buddi/gateway/dist/web/lock.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/pages.d.ts +1 -0
- package/node_modules/@buddi/gateway/dist/web/pages.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/pages.js +12 -1
- package/node_modules/@buddi/gateway/dist/web/pages.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/places.d.ts +27 -0
- package/node_modules/@buddi/gateway/dist/web/places.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/places.js +90 -0
- package/node_modules/@buddi/gateway/dist/web/places.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/plugins.d.ts +34 -1
- package/node_modules/@buddi/gateway/dist/web/plugins.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/plugins.js +99 -10
- 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 +9 -0
- package/node_modules/@buddi/gateway/dist/web/server.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/server.js +479 -52
- package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/sessions.d.ts +124 -9
- package/node_modules/@buddi/gateway/dist/web/sessions.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/sessions.js +306 -24
- package/node_modules/@buddi/gateway/dist/web/sessions.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts +45 -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 +201 -0
- package/node_modules/@buddi/gateway/dist/web/signed-out.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/stream.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/stream.js +14 -0
- package/node_modules/@buddi/gateway/dist/web/stream.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/tailscale.d.ts +46 -4
- package/node_modules/@buddi/gateway/dist/web/tailscale.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/tailscale.js +88 -16
- package/node_modules/@buddi/gateway/dist/web/tailscale.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/widgets.d.ts +130 -0
- package/node_modules/@buddi/gateway/dist/web/widgets.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/widgets.js +473 -0
- package/node_modules/@buddi/gateway/dist/web/widgets.js.map +1 -0
- 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/runtime/dist/anthropic.d.ts +9 -0
- package/node_modules/@buddi/runtime/dist/anthropic.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/anthropic.js +26 -9
- package/node_modules/@buddi/runtime/dist/anthropic.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/codex-direct.d.ts +2 -1
- package/node_modules/@buddi/runtime/dist/codex-direct.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/codex-direct.js +13 -6
- package/node_modules/@buddi/runtime/dist/codex-direct.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/index.d.ts +1 -0
- package/node_modules/@buddi/runtime/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/index.js +1 -0
- package/node_modules/@buddi/runtime/dist/index.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/loop.d.ts +2 -0
- package/node_modules/@buddi/runtime/dist/loop.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/loop.js +22 -0
- package/node_modules/@buddi/runtime/dist/loop.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/openai.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/openai.js +19 -7
- package/node_modules/@buddi/runtime/dist/openai.js.map +1 -1
- package/node_modules/@buddi/runtime/dist/rate-limit.d.ts +91 -0
- package/node_modules/@buddi/runtime/dist/rate-limit.d.ts.map +1 -0
- package/node_modules/@buddi/runtime/dist/rate-limit.js +291 -0
- package/node_modules/@buddi/runtime/dist/rate-limit.js.map +1 -0
- package/node_modules/@buddi/runtime/dist/retry.d.ts +40 -0
- package/node_modules/@buddi/runtime/dist/retry.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/retry.js +42 -8
- package/node_modules/@buddi/runtime/dist/retry.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/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/folders.d.ts +14 -0
- package/node_modules/@buddi/tool-email/dist/folders.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/folders.js +23 -0
- package/node_modules/@buddi/tool-email/dist/folders.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/imap/fake.d.ts +144 -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 +393 -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 +222 -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 +26 -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 +20 -0
- package/node_modules/@buddi/tool-email/dist/mail.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mail.js +26 -0
- package/node_modules/@buddi/tool-email/dist/mail.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mailbox/actions.d.ts +290 -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 +1105 -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 +124 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/select.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/metrics.d.ts +3 -3
- package/node_modules/@buddi/tool-email/dist/metrics.js +4 -4
- 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 +156 -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 +23 -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 +185 -4
- 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 +296 -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 +126 -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/sentinels/waiting-on-me.d.ts +2 -2
- package/node_modules/@buddi/tool-email/dist/sentinels/waiting-on-me.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sentinels/waiting-on-me.js +8 -3
- package/node_modules/@buddi/tool-email/dist/sentinels/waiting-on-me.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sources/idle.d.ts +98 -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 +317 -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 +79 -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 +420 -145
- package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sources/presence.d.ts +47 -0
- package/node_modules/@buddi/tool-email/dist/sources/presence.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/sources/presence.js +128 -0
- package/node_modules/@buddi/tool-email/dist/sources/presence.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/threads.d.ts +2 -0
- package/node_modules/@buddi/tool-email/dist/threads.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/threads.js +12 -3
- package/node_modules/@buddi/tool-email/dist/threads.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/read.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/tools/read.js +29 -2
- package/node_modules/@buddi/tool-email/dist/tools/read.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/tools/threads.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/dist/widgets.d.ts +13 -0
- package/node_modules/@buddi/tool-email/dist/widgets.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/widgets.js +51 -0
- package/node_modules/@buddi/tool-email/dist/widgets.js.map +1 -0
- 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/migrations/020_mailbox_presence.sql +44 -0
- package/node_modules/@buddi/tool-email/migrations/021_learned_line.sql +9 -0
- package/node_modules/@buddi/tool-email/migrations/022_bulk_checked.sql +13 -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-memory/dist/admin.d.ts +9 -0
- package/node_modules/@buddi/tool-memory/dist/admin.d.ts.map +1 -1
- package/node_modules/@buddi/tool-memory/dist/admin.js +11 -0
- package/node_modules/@buddi/tool-memory/dist/admin.js.map +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/args.d.ts +13 -2
- package/packages/cli/dist/args.d.ts.map +1 -1
- package/packages/cli/dist/args.js +12 -3
- package/packages/cli/dist/args.js.map +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 +301 -20
- package/packages/cli/dist/commands.js.map +1 -1
- package/packages/cli/dist/dashboard-cmd.d.ts +3 -0
- package/packages/cli/dist/dashboard-cmd.d.ts.map +1 -1
- package/packages/cli/dist/dashboard-cmd.js +63 -0
- package/packages/cli/dist/dashboard-cmd.js.map +1 -1
- package/packages/cli/dist/doctor-probes.d.ts.map +1 -1
- package/packages/cli/dist/doctor-probes.js +12 -10
- package/packages/cli/dist/doctor-probes.js.map +1 -1
- package/packages/cli/dist/doctor.d.ts +14 -1
- 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/main.d.ts.map +1 -1
- package/packages/cli/dist/main.js +22 -1
- package/packages/cli/dist/main.js.map +1 -1
- package/packages/cli/dist/mcp/gateway-client.d.ts +19 -17
- package/packages/cli/dist/mcp/gateway-client.d.ts.map +1 -1
- package/packages/cli/dist/mcp/gateway-client.js +128 -29
- package/packages/cli/dist/mcp/gateway-client.js.map +1 -1
- package/packages/cli/dist/mcp/tools.d.ts +6 -0
- package/packages/cli/dist/mcp/tools.d.ts.map +1 -1
- package/packages/cli/dist/mcp/tools.js +23 -3
- package/packages/cli/dist/mcp/tools.js.map +1 -1
- package/packages/cli/dist/telegram-cmd.d.ts.map +1 -1
- package/packages/cli/dist/telegram-cmd.js +5 -4
- package/packages/cli/dist/telegram-cmd.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 +8 -6
- 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 +22 -12
- 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/agents/skills.d.ts +2 -2
- 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/clock-widget.d.ts +38 -0
- package/packages/core/dist/clock-widget.d.ts.map +1 -0
- package/packages/core/dist/clock-widget.js +114 -0
- package/packages/core/dist/clock-widget.js.map +1 -0
- package/packages/core/dist/failures/owner-message.d.ts +25 -0
- package/packages/core/dist/failures/owner-message.d.ts.map +1 -1
- package/packages/core/dist/failures/owner-message.js +90 -0
- package/packages/core/dist/failures/owner-message.js.map +1 -1
- package/packages/core/dist/feedback/index.d.ts +129 -0
- package/packages/core/dist/feedback/index.d.ts.map +1 -0
- package/packages/core/dist/feedback/index.js +180 -0
- package/packages/core/dist/feedback/index.js.map +1 -0
- package/packages/core/dist/groups.d.ts +33 -0
- package/packages/core/dist/groups.d.ts.map +1 -1
- package/packages/core/dist/groups.js +76 -4
- package/packages/core/dist/groups.js.map +1 -1
- package/packages/core/dist/home.d.ts +5 -5
- package/packages/core/dist/host/build.d.ts +19 -1
- package/packages/core/dist/host/build.d.ts.map +1 -1
- package/packages/core/dist/host/build.js +150 -3
- package/packages/core/dist/host/build.js.map +1 -1
- package/packages/core/dist/host/types.d.ts +62 -2
- package/packages/core/dist/host/types.d.ts.map +1 -1
- package/packages/core/dist/index.d.ts +9 -0
- package/packages/core/dist/index.d.ts.map +1 -1
- package/packages/core/dist/index.js +9 -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/lock.d.ts +76 -0
- package/packages/core/dist/lock.d.ts.map +1 -0
- package/packages/core/dist/lock.js +167 -0
- package/packages/core/dist/lock.js.map +1 -0
- package/packages/core/dist/metrics.d.ts.map +1 -1
- package/packages/core/dist/metrics.js +4 -2
- package/packages/core/dist/metrics.js.map +1 -1
- package/packages/core/dist/onboarding/store.d.ts +5 -0
- package/packages/core/dist/onboarding/store.d.ts.map +1 -1
- package/packages/core/dist/onboarding/store.js +35 -5
- package/packages/core/dist/onboarding/store.js.map +1 -1
- package/packages/core/dist/onboarding/types.d.ts +10 -0
- package/packages/core/dist/onboarding/types.d.ts.map +1 -1
- package/packages/core/dist/onboarding/types.js +2 -0
- package/packages/core/dist/onboarding/types.js.map +1 -1
- package/packages/core/dist/owner-format.d.ts +14 -0
- package/packages/core/dist/owner-format.d.ts.map +1 -0
- package/packages/core/dist/owner-format.js +47 -0
- package/packages/core/dist/owner-format.js.map +1 -0
- package/packages/core/dist/owner-timezone.d.ts +46 -0
- package/packages/core/dist/owner-timezone.d.ts.map +1 -0
- package/packages/core/dist/owner-timezone.js +43 -0
- package/packages/core/dist/owner-timezone.js.map +1 -0
- 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 +37 -38
- package/packages/core/dist/pages.d.ts.map +1 -1
- package/packages/core/dist/pages.js +30 -3
- package/packages/core/dist/pages.js.map +1 -1
- package/packages/core/dist/places.d.ts +110 -0
- package/packages/core/dist/places.d.ts.map +1 -0
- package/packages/core/dist/places.js +239 -0
- package/packages/core/dist/places.js.map +1 -0
- package/packages/core/dist/plugin/index.d.ts +13 -5
- package/packages/core/dist/plugin/index.d.ts.map +1 -1
- package/packages/core/dist/plugin/index.js +3 -0
- package/packages/core/dist/plugin/index.js.map +1 -1
- package/packages/core/dist/plugin/requires.d.ts +75 -0
- package/packages/core/dist/plugin/requires.d.ts.map +1 -0
- package/packages/core/dist/plugin/requires.js +77 -0
- package/packages/core/dist/plugin/requires.js.map +1 -0
- package/packages/core/dist/plugin/uses.d.ts +1 -1
- package/packages/core/dist/plugin/uses.d.ts.map +1 -1
- package/packages/core/dist/plugin/uses.js +2 -0
- package/packages/core/dist/plugin/uses.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/queue/retry-policy.d.ts +5 -0
- package/packages/core/dist/queue/retry-policy.d.ts.map +1 -1
- package/packages/core/dist/queue/retry-policy.js +19 -2
- package/packages/core/dist/queue/retry-policy.js.map +1 -1
- package/packages/core/dist/registry.d.ts +47 -3
- package/packages/core/dist/registry.d.ts.map +1 -1
- package/packages/core/dist/registry.js +150 -3
- package/packages/core/dist/registry.js.map +1 -1
- package/packages/core/dist/scheduler/enqueue.d.ts +71 -0
- package/packages/core/dist/scheduler/enqueue.d.ts.map +1 -0
- package/packages/core/dist/scheduler/enqueue.js +116 -0
- package/packages/core/dist/scheduler/enqueue.js.map +1 -0
- package/packages/core/dist/scheduler/index.d.ts +1 -0
- package/packages/core/dist/scheduler/index.d.ts.map +1 -1
- package/packages/core/dist/scheduler/index.js +1 -0
- package/packages/core/dist/scheduler/index.js.map +1 -1
- package/packages/core/dist/scheduler/missions.d.ts +15 -0
- package/packages/core/dist/scheduler/missions.d.ts.map +1 -1
- package/packages/core/dist/scheduler/missions.js +43 -4
- package/packages/core/dist/scheduler/missions.js.map +1 -1
- package/packages/core/dist/scheduler/types.d.ts +10 -0
- package/packages/core/dist/scheduler/types.d.ts.map +1 -1
- package/packages/core/dist/scheduler/types.js +3 -0
- package/packages/core/dist/scheduler/types.js.map +1 -1
- package/packages/core/dist/secrets/settings.d.ts +6 -6
- package/packages/core/dist/semver.d.ts +17 -0
- package/packages/core/dist/semver.d.ts.map +1 -1
- package/packages/core/dist/semver.js +130 -0
- package/packages/core/dist/semver.js.map +1 -1
- package/packages/core/dist/sentinels/run.d.ts +6 -1
- package/packages/core/dist/sentinels/run.d.ts.map +1 -1
- package/packages/core/dist/sentinels/run.js +43 -24
- package/packages/core/dist/sentinels/run.js.map +1 -1
- package/packages/core/dist/sentinels/types.d.ts +13 -0
- package/packages/core/dist/sentinels/types.d.ts.map +1 -1
- package/packages/core/dist/sentinels/types.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/run.d.ts +8 -0
- package/packages/core/dist/sources/run.d.ts.map +1 -1
- package/packages/core/dist/sources/run.js +1 -1
- package/packages/core/dist/sources/run.js.map +1 -1
- package/packages/core/dist/sources/watch.d.ts +40 -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/time.d.ts +17 -3
- package/packages/core/dist/time.d.ts.map +1 -1
- package/packages/core/dist/time.js +27 -3
- package/packages/core/dist/time.js.map +1 -1
- package/packages/core/dist/tools.d.ts +77 -1
- package/packages/core/dist/tools.d.ts.map +1 -1
- package/packages/core/dist/tools.js.map +1 -1
- package/packages/core/dist/views.d.ts +68 -68
- package/packages/core/dist/views.d.ts.map +1 -1
- package/packages/core/dist/views.js +3 -0
- package/packages/core/dist/views.js.map +1 -1
- package/packages/core/dist/widget-settings.d.ts +161 -0
- package/packages/core/dist/widget-settings.d.ts.map +1 -0
- package/packages/core/dist/widget-settings.js +314 -0
- package/packages/core/dist/widget-settings.js.map +1 -0
- package/packages/core/dist/widgets.d.ts +206 -0
- package/packages/core/dist/widgets.d.ts.map +1 -0
- package/packages/core/dist/widgets.js +247 -0
- package/packages/core/dist/widgets.js.map +1 -0
- 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/core/migrations/059_dashboard_lock.sql +33 -0
- package/packages/core/migrations/060_owner_places.sql +30 -0
- package/packages/core/migrations/061_owner_formats.sql +10 -0
- package/packages/core/migrations/062_group_deleted.sql +7 -0
- package/packages/core/migrations/063_provider_account_limits.sql +20 -0
- package/packages/core/migrations/064_mission_coalesce.sql +12 -0
- package/packages/core/migrations/065_api_tokens.sql +28 -0
- package/packages/gateway/dist/.tsbuildinfo +1 -1
- package/packages/gateway/dist/account-limits.d.ts +45 -0
- package/packages/gateway/dist/account-limits.d.ts.map +1 -0
- package/packages/gateway/dist/account-limits.js +87 -0
- package/packages/gateway/dist/account-limits.js.map +1 -0
- package/packages/gateway/dist/accounts-cli.d.ts +88 -0
- package/packages/gateway/dist/accounts-cli.d.ts.map +1 -0
- package/packages/gateway/dist/accounts-cli.js +216 -0
- package/packages/gateway/dist/accounts-cli.js.map +1 -0
- package/packages/gateway/dist/agents/canvas.d.ts +20 -20
- package/packages/gateway/dist/agents/learning-digest.d.ts +11 -1
- package/packages/gateway/dist/agents/learning-digest.d.ts.map +1 -1
- package/packages/gateway/dist/agents/learning-digest.js +43 -4
- package/packages/gateway/dist/agents/learning-digest.js.map +1 -1
- package/packages/gateway/dist/agents/owner-tools.d.ts.map +1 -1
- package/packages/gateway/dist/agents/owner-tools.js +3 -2
- package/packages/gateway/dist/agents/owner-tools.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 +40 -20
- 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/api-token-cli.d.ts +17 -0
- package/packages/gateway/dist/api-token-cli.d.ts.map +1 -0
- package/packages/gateway/dist/api-token-cli.js +108 -0
- package/packages/gateway/dist/api-token-cli.js.map +1 -0
- package/packages/gateway/dist/bootstrap.d.ts +6 -2
- package/packages/gateway/dist/bootstrap.d.ts.map +1 -1
- package/packages/gateway/dist/bootstrap.js +25 -7
- package/packages/gateway/dist/bootstrap.js.map +1 -1
- package/packages/gateway/dist/chat/session.d.ts +5 -0
- package/packages/gateway/dist/chat/session.d.ts.map +1 -1
- package/packages/gateway/dist/chat/session.js +13 -2
- package/packages/gateway/dist/chat/session.js.map +1 -1
- package/packages/gateway/dist/cli.d.ts.map +1 -1
- package/packages/gateway/dist/cli.js +14 -3
- package/packages/gateway/dist/cli.js.map +1 -1
- package/packages/gateway/dist/index.d.ts +3 -0
- package/packages/gateway/dist/index.d.ts.map +1 -1
- package/packages/gateway/dist/index.js +3 -0
- package/packages/gateway/dist/index.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/missions/dead-letter.d.ts +2 -1
- package/packages/gateway/dist/missions/dead-letter.d.ts.map +1 -1
- package/packages/gateway/dist/missions/dead-letter.js +19 -5
- package/packages/gateway/dist/missions/dead-letter.js.map +1 -1
- package/packages/gateway/dist/missions/defaults.d.ts +6 -0
- package/packages/gateway/dist/missions/defaults.d.ts.map +1 -1
- package/packages/gateway/dist/missions/defaults.js +10 -2
- package/packages/gateway/dist/missions/defaults.js.map +1 -1
- package/packages/gateway/dist/missions/execute.d.ts.map +1 -1
- package/packages/gateway/dist/missions/execute.js +14 -8
- package/packages/gateway/dist/missions/execute.js.map +1 -1
- package/packages/gateway/dist/missions/inline.js +1 -1
- package/packages/gateway/dist/missions/inline.js.map +1 -1
- package/packages/gateway/dist/missions/sentinel-wake.d.ts +11 -0
- package/packages/gateway/dist/missions/sentinel-wake.d.ts.map +1 -1
- package/packages/gateway/dist/missions/sentinel-wake.js +37 -1
- package/packages/gateway/dist/missions/sentinel-wake.js.map +1 -1
- package/packages/gateway/dist/missions-cli.d.ts.map +1 -1
- package/packages/gateway/dist/missions-cli.js +5 -5
- package/packages/gateway/dist/missions-cli.js.map +1 -1
- package/packages/gateway/dist/nudges-cli.js +2 -2
- package/packages/gateway/dist/nudges-cli.js.map +1 -1
- package/packages/gateway/dist/owner-seed.js +2 -2
- package/packages/gateway/dist/owner-seed.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/live.d.ts +8 -1
- package/packages/gateway/dist/plugins/live.d.ts.map +1 -1
- package/packages/gateway/dist/plugins/live.js +25 -7
- package/packages/gateway/dist/plugins/live.js.map +1 -1
- package/packages/gateway/dist/plugins/load.d.ts +55 -0
- package/packages/gateway/dist/plugins/load.d.ts.map +1 -1
- package/packages/gateway/dist/plugins/load.js +100 -4
- package/packages/gateway/dist/plugins/load.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/requires.d.ts +79 -0
- package/packages/gateway/dist/plugins/requires.d.ts.map +1 -0
- package/packages/gateway/dist/plugins/requires.js +178 -0
- package/packages/gateway/dist/plugins/requires.js.map +1 -0
- package/packages/gateway/dist/plugins/stage.d.ts +33 -3
- package/packages/gateway/dist/plugins/stage.d.ts.map +1 -1
- package/packages/gateway/dist/plugins/stage.js +41 -6
- package/packages/gateway/dist/plugins/stage.js.map +1 -1
- package/packages/gateway/dist/plugins/update.d.ts +21 -0
- package/packages/gateway/dist/plugins/update.d.ts.map +1 -1
- package/packages/gateway/dist/plugins/update.js +16 -0
- package/packages/gateway/dist/plugins/update.js.map +1 -1
- package/packages/gateway/dist/plugins-cli.d.ts +5 -1
- package/packages/gateway/dist/plugins-cli.d.ts.map +1 -1
- package/packages/gateway/dist/plugins-cli.js +48 -11
- package/packages/gateway/dist/plugins-cli.js.map +1 -1
- package/packages/gateway/dist/provider-accounts.d.ts +4 -0
- package/packages/gateway/dist/provider-accounts.d.ts.map +1 -1
- package/packages/gateway/dist/provider-accounts.js +68 -10
- package/packages/gateway/dist/provider-accounts.js.map +1 -1
- package/packages/gateway/dist/provider-diagnostics.d.ts.map +1 -1
- package/packages/gateway/dist/provider-diagnostics.js +9 -0
- package/packages/gateway/dist/provider-diagnostics.js.map +1 -1
- package/packages/gateway/dist/reminders-cli.js +2 -2
- package/packages/gateway/dist/reminders-cli.js.map +1 -1
- package/packages/gateway/dist/serve.d.ts +2 -0
- package/packages/gateway/dist/serve.d.ts.map +1 -1
- package/packages/gateway/dist/serve.js +78 -8
- 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/surfaces/failure.d.ts.map +1 -1
- package/packages/gateway/dist/surfaces/failure.js +9 -1
- package/packages/gateway/dist/surfaces/failure.js.map +1 -1
- package/packages/gateway/dist/system-context.d.ts +18 -0
- package/packages/gateway/dist/system-context.d.ts.map +1 -1
- package/packages/gateway/dist/system-context.js +46 -4
- package/packages/gateway/dist/system-context.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 +21 -28
- 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 +3 -3
- package/packages/gateway/dist/telegram/outbound.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/outbound.js +19 -5
- 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 +107 -0
- package/packages/gateway/dist/telegram/reactions.js.map +1 -0
- package/packages/gateway/dist/telegram/surface.d.ts +5 -1
- package/packages/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/surface.js +93 -12
- package/packages/gateway/dist/telegram/surface.js.map +1 -1
- package/packages/gateway/dist/tips/engine.d.ts +2 -0
- package/packages/gateway/dist/tips/engine.d.ts.map +1 -1
- package/packages/gateway/dist/tips/engine.js +8 -5
- package/packages/gateway/dist/tips/engine.js.map +1 -1
- package/packages/gateway/dist/tips/facts.d.ts +23 -0
- package/packages/gateway/dist/tips/facts.d.ts.map +1 -1
- package/packages/gateway/dist/tips/facts.js +19 -0
- package/packages/gateway/dist/tips/facts.js.map +1 -1
- package/packages/gateway/dist/tips/route.js +2 -2
- package/packages/gateway/dist/tips/route.js.map +1 -1
- package/packages/gateway/dist/tips/rules.d.ts +3 -2
- package/packages/gateway/dist/tips/rules.d.ts.map +1 -1
- package/packages/gateway/dist/tips/rules.js +26 -0
- package/packages/gateway/dist/tips/rules.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/api-routes.d.ts +103 -0
- package/packages/gateway/dist/web/api-routes.d.ts.map +1 -0
- package/packages/gateway/dist/web/api-routes.js +1200 -0
- package/packages/gateway/dist/web/api-routes.js.map +1 -0
- package/packages/gateway/dist/web/api-scan.d.ts +17 -0
- package/packages/gateway/dist/web/api-scan.d.ts.map +1 -0
- package/packages/gateway/dist/web/api-scan.js +206 -0
- package/packages/gateway/dist/web/api-scan.js.map +1 -0
- package/packages/gateway/dist/web/api-tokens.d.ts +58 -0
- package/packages/gateway/dist/web/api-tokens.d.ts.map +1 -0
- package/packages/gateway/dist/web/api-tokens.js +136 -0
- package/packages/gateway/dist/web/api-tokens.js.map +1 -0
- package/packages/gateway/dist/web/backups.js +2 -2
- package/packages/gateway/dist/web/backups.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/group-lifecycle.d.ts +18 -0
- package/packages/gateway/dist/web/group-lifecycle.d.ts.map +1 -0
- package/packages/gateway/dist/web/group-lifecycle.js +46 -0
- package/packages/gateway/dist/web/group-lifecycle.js.map +1 -0
- package/packages/gateway/dist/web/lock-image.d.ts +37 -0
- package/packages/gateway/dist/web/lock-image.d.ts.map +1 -0
- package/packages/gateway/dist/web/lock-image.js +253 -0
- package/packages/gateway/dist/web/lock-image.js.map +1 -0
- package/packages/gateway/dist/web/lock.d.ts +162 -0
- package/packages/gateway/dist/web/lock.d.ts.map +1 -0
- package/packages/gateway/dist/web/lock.js +472 -0
- package/packages/gateway/dist/web/lock.js.map +1 -0
- package/packages/gateway/dist/web/pages.d.ts +1 -0
- package/packages/gateway/dist/web/pages.d.ts.map +1 -1
- package/packages/gateway/dist/web/pages.js +12 -1
- package/packages/gateway/dist/web/pages.js.map +1 -1
- package/packages/gateway/dist/web/places.d.ts +27 -0
- package/packages/gateway/dist/web/places.d.ts.map +1 -0
- package/packages/gateway/dist/web/places.js +90 -0
- package/packages/gateway/dist/web/places.js.map +1 -0
- package/packages/gateway/dist/web/plugins.d.ts +34 -1
- package/packages/gateway/dist/web/plugins.d.ts.map +1 -1
- package/packages/gateway/dist/web/plugins.js +99 -10
- 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 +9 -0
- package/packages/gateway/dist/web/server.d.ts.map +1 -1
- package/packages/gateway/dist/web/server.js +479 -52
- package/packages/gateway/dist/web/server.js.map +1 -1
- package/packages/gateway/dist/web/sessions.d.ts +124 -9
- package/packages/gateway/dist/web/sessions.d.ts.map +1 -1
- package/packages/gateway/dist/web/sessions.js +306 -24
- package/packages/gateway/dist/web/sessions.js.map +1 -1
- package/packages/gateway/dist/web/signed-out.d.ts +45 -0
- package/packages/gateway/dist/web/signed-out.d.ts.map +1 -0
- package/packages/gateway/dist/web/signed-out.js +201 -0
- package/packages/gateway/dist/web/signed-out.js.map +1 -0
- package/packages/gateway/dist/web/stream.d.ts.map +1 -1
- package/packages/gateway/dist/web/stream.js +14 -0
- package/packages/gateway/dist/web/stream.js.map +1 -1
- package/packages/gateway/dist/web/tailscale.d.ts +46 -4
- package/packages/gateway/dist/web/tailscale.d.ts.map +1 -1
- package/packages/gateway/dist/web/tailscale.js +88 -16
- package/packages/gateway/dist/web/tailscale.js.map +1 -1
- package/packages/gateway/dist/web/widgets.d.ts +130 -0
- package/packages/gateway/dist/web/widgets.d.ts.map +1 -0
- package/packages/gateway/dist/web/widgets.js +473 -0
- package/packages/gateway/dist/web/widgets.js.map +1 -0
- 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/runtime/dist/anthropic.d.ts +9 -0
- package/packages/runtime/dist/anthropic.d.ts.map +1 -1
- package/packages/runtime/dist/anthropic.js +26 -9
- package/packages/runtime/dist/anthropic.js.map +1 -1
- package/packages/runtime/dist/codex-direct.d.ts +2 -1
- package/packages/runtime/dist/codex-direct.d.ts.map +1 -1
- package/packages/runtime/dist/codex-direct.js +13 -6
- package/packages/runtime/dist/codex-direct.js.map +1 -1
- package/packages/runtime/dist/index.d.ts +1 -0
- package/packages/runtime/dist/index.d.ts.map +1 -1
- package/packages/runtime/dist/index.js +1 -0
- package/packages/runtime/dist/index.js.map +1 -1
- package/packages/runtime/dist/loop.d.ts +2 -0
- package/packages/runtime/dist/loop.d.ts.map +1 -1
- package/packages/runtime/dist/loop.js +22 -0
- package/packages/runtime/dist/loop.js.map +1 -1
- package/packages/runtime/dist/openai.d.ts.map +1 -1
- package/packages/runtime/dist/openai.js +19 -7
- package/packages/runtime/dist/openai.js.map +1 -1
- package/packages/runtime/dist/rate-limit.d.ts +91 -0
- package/packages/runtime/dist/rate-limit.d.ts.map +1 -0
- package/packages/runtime/dist/rate-limit.js +291 -0
- package/packages/runtime/dist/rate-limit.js.map +1 -0
- package/packages/runtime/dist/retry.d.ts +40 -0
- package/packages/runtime/dist/retry.d.ts.map +1 -1
- package/packages/runtime/dist/retry.js +42 -8
- package/packages/runtime/dist/retry.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/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/folders.d.ts +14 -0
- package/packages/tools/email/dist/folders.d.ts.map +1 -1
- package/packages/tools/email/dist/folders.js +23 -0
- package/packages/tools/email/dist/folders.js.map +1 -1
- package/packages/tools/email/dist/imap/fake.d.ts +144 -3
- package/packages/tools/email/dist/imap/fake.d.ts.map +1 -1
- package/packages/tools/email/dist/imap/fake.js +393 -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 +222 -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 +26 -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 +20 -0
- package/packages/tools/email/dist/mail.d.ts.map +1 -1
- package/packages/tools/email/dist/mail.js +26 -0
- package/packages/tools/email/dist/mail.js.map +1 -1
- package/packages/tools/email/dist/mailbox/actions.d.ts +290 -0
- package/packages/tools/email/dist/mailbox/actions.d.ts.map +1 -0
- package/packages/tools/email/dist/mailbox/actions.js +1105 -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 +124 -0
- package/packages/tools/email/dist/mailbox/select.js.map +1 -0
- package/packages/tools/email/dist/metrics.d.ts +3 -3
- package/packages/tools/email/dist/metrics.js +4 -4
- 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 +156 -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 +23 -0
- package/packages/tools/email/dist/pages/queries.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/queries.js +185 -4
- 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 +296 -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 +126 -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/sentinels/waiting-on-me.d.ts +2 -2
- package/packages/tools/email/dist/sentinels/waiting-on-me.d.ts.map +1 -1
- package/packages/tools/email/dist/sentinels/waiting-on-me.js +8 -3
- package/packages/tools/email/dist/sentinels/waiting-on-me.js.map +1 -1
- package/packages/tools/email/dist/sources/idle.d.ts +98 -0
- package/packages/tools/email/dist/sources/idle.d.ts.map +1 -0
- package/packages/tools/email/dist/sources/idle.js +317 -0
- package/packages/tools/email/dist/sources/idle.js.map +1 -0
- package/packages/tools/email/dist/sources/inbox-poll.d.ts +79 -1
- package/packages/tools/email/dist/sources/inbox-poll.d.ts.map +1 -1
- package/packages/tools/email/dist/sources/inbox-poll.js +420 -145
- package/packages/tools/email/dist/sources/inbox-poll.js.map +1 -1
- package/packages/tools/email/dist/sources/presence.d.ts +47 -0
- package/packages/tools/email/dist/sources/presence.d.ts.map +1 -0
- package/packages/tools/email/dist/sources/presence.js +128 -0
- package/packages/tools/email/dist/sources/presence.js.map +1 -0
- package/packages/tools/email/dist/threads.d.ts +2 -0
- package/packages/tools/email/dist/threads.d.ts.map +1 -1
- package/packages/tools/email/dist/threads.js +12 -3
- package/packages/tools/email/dist/threads.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/read.d.ts.map +1 -1
- package/packages/tools/email/dist/tools/read.js +29 -2
- package/packages/tools/email/dist/tools/read.js.map +1 -1
- package/packages/tools/email/dist/tools/threads.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/dist/widgets.d.ts +13 -0
- package/packages/tools/email/dist/widgets.d.ts.map +1 -0
- package/packages/tools/email/dist/widgets.js +51 -0
- package/packages/tools/email/dist/widgets.js.map +1 -0
- 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/migrations/020_mailbox_presence.sql +44 -0
- package/packages/tools/email/migrations/021_learned_line.sql +9 -0
- package/packages/tools/email/migrations/022_bulk_checked.sql +13 -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/memory/dist/admin.d.ts +9 -0
- package/packages/tools/memory/dist/admin.d.ts.map +1 -1
- package/packages/tools/memory/dist/admin.js +11 -0
- package/packages/tools/memory/dist/admin.js.map +1 -1
- package/packages/tools/web/dist/.tsbuildinfo +1 -1
- package/packages/web/dist/assets/index-D8_tmf2k.js +131 -0
- package/packages/web/dist/assets/index-DYQyioa6.css +1 -0
- package/packages/web/dist/assets/{lottie_light-DmJaDM4A.js → lottie_light-Cdn77Osu.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,1105 @@
|
|
|
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, state, reverted_ids';
|
|
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
|
+
state: ['pending', 'done', 'partial', 'unknown'].includes(row.state) ? row.state : 'done',
|
|
42
|
+
revertedIds: Array.isArray(row.reverted_ids) ? row.reverted_ids.map(String) : [],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/** A refusal whose message is the sentence the owner and the agent read. */
|
|
46
|
+
export class MailboxRefusal extends ToolRefusal {
|
|
47
|
+
}
|
|
48
|
+
/** The mailbox could not be opened at all: no password, or the provider refused it. Nothing was tried. */
|
|
49
|
+
export class MailboxLoginRefusal extends MailboxRefusal {
|
|
50
|
+
}
|
|
51
|
+
/* ------------------------------------------------------------------ *
|
|
52
|
+
* Words
|
|
53
|
+
* ------------------------------------------------------------------ */
|
|
54
|
+
export function plural(n, one, many = `${one}s`) {
|
|
55
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
56
|
+
}
|
|
57
|
+
/** "Mark as read", "Archive", … — the verb a card and a trail row lead with. */
|
|
58
|
+
export function verbOf(kind, destination) {
|
|
59
|
+
switch (kind) {
|
|
60
|
+
case 'mark-read':
|
|
61
|
+
return 'Mark as read';
|
|
62
|
+
case 'mark-unread':
|
|
63
|
+
return 'Mark as unread';
|
|
64
|
+
case 'archive':
|
|
65
|
+
return 'Archive';
|
|
66
|
+
case 'move':
|
|
67
|
+
return `Move to ${destination ?? 'a folder'}`;
|
|
68
|
+
case 'trash':
|
|
69
|
+
return 'Move to Trash';
|
|
70
|
+
case 'undo':
|
|
71
|
+
return 'Undo';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** The sample lines a card shows: sender — subject. */
|
|
75
|
+
export function sampleLines(targets) {
|
|
76
|
+
const lines = targets.slice(0, SAMPLE_SIZE).map((t) => `- ${t.from || '(unknown sender)'} — ${t.subject || '(no subject)'}`);
|
|
77
|
+
if (targets.length > SAMPLE_SIZE)
|
|
78
|
+
lines.push(`…and ${targets.length - SAMPLE_SIZE} more.`);
|
|
79
|
+
return lines;
|
|
80
|
+
}
|
|
81
|
+
/* ------------------------------------------------------------------ *
|
|
82
|
+
* Reading what a change is about
|
|
83
|
+
* ------------------------------------------------------------------ */
|
|
84
|
+
/** The rows for these ids, with their folder names, in the order asked. */
|
|
85
|
+
export async function loadTargets(db, ids) {
|
|
86
|
+
if (ids.length === 0)
|
|
87
|
+
return [];
|
|
88
|
+
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,
|
|
89
|
+
m.subject, m.from_addr, m.flags, m.gone_at
|
|
90
|
+
from email.messages m join email.folders f on f.id = m.folder_id
|
|
91
|
+
where m.id = any($1::uuid[])`, [ids]);
|
|
92
|
+
const byId = new Map(rows.map((r) => [String(r.id), r]));
|
|
93
|
+
const out = [];
|
|
94
|
+
for (const id of ids) {
|
|
95
|
+
const r = byId.get(id);
|
|
96
|
+
if (!r)
|
|
97
|
+
continue;
|
|
98
|
+
out.push({
|
|
99
|
+
id,
|
|
100
|
+
accountId: String(r.account_id),
|
|
101
|
+
folderId: String(r.folder_id),
|
|
102
|
+
folder: r.folder,
|
|
103
|
+
uidValidity: Number(r.uidvalidity),
|
|
104
|
+
uid: Number(r.uid),
|
|
105
|
+
messageId: r.message_id ?? null,
|
|
106
|
+
subject: r.subject ?? '',
|
|
107
|
+
from: r.from_addr ?? '',
|
|
108
|
+
flags: Array.isArray(r.flags) ? r.flags : [],
|
|
109
|
+
gone: r.gone_at !== null && r.gone_at !== undefined,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The targets of one call, checked: every id known, at most `MAX_PER_CALL`,
|
|
116
|
+
* all in one mailbox the owner has. Refusals are sentences.
|
|
117
|
+
*/
|
|
118
|
+
export async function requireTargets(db, ids, accounts) {
|
|
119
|
+
const unique = [...new Set(ids)];
|
|
120
|
+
if (unique.length === 0)
|
|
121
|
+
throw new MailboxRefusal('No messages were named. Use email.select_messages to find them first.');
|
|
122
|
+
if (unique.length > MAX_PER_CALL) {
|
|
123
|
+
throw new MailboxRefusal(`That is ${unique.length} messages; one change covers at most ${MAX_PER_CALL}. Split it.`);
|
|
124
|
+
}
|
|
125
|
+
const targets = await loadTargets(db, unique);
|
|
126
|
+
const missing = unique.length - targets.length;
|
|
127
|
+
if (missing > 0) {
|
|
128
|
+
throw new MailboxRefusal(`${plural(missing, 'of those ids is', 'of those ids are')} not a message buddi has. Select them again.`);
|
|
129
|
+
}
|
|
130
|
+
const accountIds = [...new Set(targets.map((t) => t.accountId))];
|
|
131
|
+
if (accountIds.length > 1) {
|
|
132
|
+
throw new MailboxRefusal('Those messages are in more than one mailbox. One change covers one mailbox; make one call per mailbox.');
|
|
133
|
+
}
|
|
134
|
+
const account = accounts.find((a) => a.id === accountIds[0]);
|
|
135
|
+
if (!account)
|
|
136
|
+
throw new MailboxRefusal('Those messages are in a mailbox that is turned off or no longer here.');
|
|
137
|
+
return { account, targets };
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Open a writing connection to one mailbox, run `work`, and close it.
|
|
141
|
+
*
|
|
142
|
+
* A login the provider refuses is written on the account row, as the poll
|
|
143
|
+
* writes it, so the settings row says "Password needed".
|
|
144
|
+
*/
|
|
145
|
+
export async function withWriter(ctx, account, opts, work) {
|
|
146
|
+
const db = ctx.buddi.db;
|
|
147
|
+
const auth = await mailboxAuth(ctx, account, opts.env);
|
|
148
|
+
if (!auth.ok)
|
|
149
|
+
throw new MailboxLoginRefusal(`${account.address} cannot be opened: ${auth.problem.message}`);
|
|
150
|
+
let client;
|
|
151
|
+
try {
|
|
152
|
+
client = await opts.connect(account, auth.value);
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
if (isAuthFailure(err)) {
|
|
156
|
+
await recordLoginFailure(db, account.id, err, ctx.buddi.clock.now()).catch(() => { });
|
|
157
|
+
throw new MailboxLoginRefusal(`${account.address} refused its stored password. Set a new one under Settings → Email.`);
|
|
158
|
+
}
|
|
159
|
+
throw err;
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
await clearLoginFailure(db, account.id);
|
|
163
|
+
if (!isImapWriter(client)) {
|
|
164
|
+
throw new MailboxRefusal(`The connection to ${account.address} can only read mail here, so nothing was changed.`);
|
|
165
|
+
}
|
|
166
|
+
return await work(client);
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
await client.close().catch(() => { });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
export async function serverFacts(client) {
|
|
173
|
+
const caps = await client.capabilities();
|
|
174
|
+
const listing = await client.listMailboxes();
|
|
175
|
+
return { gmail: caps.includes(GMAIL_CAPABILITY), move: caps.includes('MOVE'), listing };
|
|
176
|
+
}
|
|
177
|
+
function single(list) {
|
|
178
|
+
return list.length === 1 ? list[0] : undefined;
|
|
179
|
+
}
|
|
180
|
+
function attributesOf(info) {
|
|
181
|
+
return [info.specialUse ?? '', ...info.flags].map((f) => f.trim().toLowerCase()).filter((f) => f !== '');
|
|
182
|
+
}
|
|
183
|
+
function specialFolder(listing, use) {
|
|
184
|
+
const wanted = use.toLowerCase();
|
|
185
|
+
return listing.find((info) => attributesOf(info).includes(wanted))?.name ?? null;
|
|
186
|
+
}
|
|
187
|
+
/** Folders a message can be moved into: selectable, and not the Gmail namespace root. */
|
|
188
|
+
function selectable(listing) {
|
|
189
|
+
return listing.filter((info) => !attributesOf(info).includes('\\noselect') && !attributesOf(info).includes('\\nonexistent'));
|
|
190
|
+
}
|
|
191
|
+
/** "INBOX, Archive, Receipts, …" — the list a refusal names. */
|
|
192
|
+
export function folderList(listing) {
|
|
193
|
+
const names = selectable(listing).map((info) => info.name);
|
|
194
|
+
return names.length > 0 ? names.join(', ') : '(none listed)';
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Where a kind of change sends messages on this server, or a refusal.
|
|
198
|
+
*
|
|
199
|
+
* Nothing is created: a folder that does not exist is refused, naming the
|
|
200
|
+
* ones that do.
|
|
201
|
+
*/
|
|
202
|
+
export function destinationFor(facts, kind, account, folder) {
|
|
203
|
+
if (kind === 'mark-read' || kind === 'mark-unread')
|
|
204
|
+
return null;
|
|
205
|
+
if (!facts.move) {
|
|
206
|
+
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.`);
|
|
207
|
+
}
|
|
208
|
+
if (kind === 'archive') {
|
|
209
|
+
const found = facts.gmail ? specialFolder(facts.listing, '\\All') : specialFolder(facts.listing, '\\Archive');
|
|
210
|
+
if (!found) {
|
|
211
|
+
throw new MailboxRefusal(facts.gmail
|
|
212
|
+
? `${account} lists no All Mail folder, so there is nowhere to archive to. Nothing was changed.`
|
|
213
|
+
: `${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)}.`);
|
|
214
|
+
}
|
|
215
|
+
return found;
|
|
216
|
+
}
|
|
217
|
+
if (kind === 'trash') {
|
|
218
|
+
const found = specialFolder(facts.listing, '\\Trash');
|
|
219
|
+
if (!found) {
|
|
220
|
+
throw new MailboxRefusal(`${account} has no Trash folder (its server marks none), and buddi never deletes mail outright. Nothing was changed.`);
|
|
221
|
+
}
|
|
222
|
+
return found;
|
|
223
|
+
}
|
|
224
|
+
// move
|
|
225
|
+
const wanted = (folder ?? '').trim();
|
|
226
|
+
if (wanted === '')
|
|
227
|
+
throw new MailboxRefusal('Name the folder to move them to.');
|
|
228
|
+
const candidates = selectable(facts.listing);
|
|
229
|
+
const found = candidates.find((c) => c.name === wanted) ??
|
|
230
|
+
single(candidates.filter((c) => c.name.toLowerCase() === wanted.toLowerCase())) ??
|
|
231
|
+
single(candidates.filter((c) => leafOf(c.name) === wanted.toLowerCase()));
|
|
232
|
+
if (found) {
|
|
233
|
+
/*
|
|
234
|
+
* Trash and Junk are emptied by the provider. A move there is a trash in
|
|
235
|
+
* all but name, and `email.move` may be remembered where `email.trash`
|
|
236
|
+
* never is — so it is refused here, and the owner is asked every time.
|
|
237
|
+
*/
|
|
238
|
+
const attributes = attributesOf(found);
|
|
239
|
+
if (attributes.includes('\\trash') || attributes.includes('\\junk')) {
|
|
240
|
+
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.`);
|
|
241
|
+
}
|
|
242
|
+
return found.name;
|
|
243
|
+
}
|
|
244
|
+
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)}.`);
|
|
245
|
+
}
|
|
246
|
+
/* ------------------------------------------------------------------ *
|
|
247
|
+
* Keeping buddi's rows in step
|
|
248
|
+
* ------------------------------------------------------------------ */
|
|
249
|
+
/**
|
|
250
|
+
* The folder row for a server name, created (unsynced, kind other) if new.
|
|
251
|
+
* Never changes an existing row's kind or cursor; records what the server
|
|
252
|
+
* says the folder is for (`special_use`) when the caller knows it.
|
|
253
|
+
*/
|
|
254
|
+
export async function folderRow(db, accountId, name, specialUse) {
|
|
255
|
+
const { rows } = await db.query(`insert into email.folders (account_id, name, kind, synced, special_use) values ($1, $2, 'other', false, $3)
|
|
256
|
+
on conflict (account_id, name) do update set special_use = coalesce(excluded.special_use, email.folders.special_use)
|
|
257
|
+
returning id`, [accountId, name, specialUse ?? null]);
|
|
258
|
+
return String(rows[0].id);
|
|
259
|
+
}
|
|
260
|
+
/** The SPECIAL-USE attribute the listing gives a folder, or null. */
|
|
261
|
+
export function specialUseOf(listing, name) {
|
|
262
|
+
const info = listing.find((f) => f.name === name);
|
|
263
|
+
if (!info)
|
|
264
|
+
return null;
|
|
265
|
+
const known = ['\\all', '\\archive', '\\trash', '\\junk', '\\sent', '\\drafts'];
|
|
266
|
+
return attributesOf(info).find((a) => known.includes(a)) ?? null;
|
|
267
|
+
}
|
|
268
|
+
let unknownCounter = 0;
|
|
269
|
+
/**
|
|
270
|
+
* A placeholder uid for a message whose new uid the server did not report and
|
|
271
|
+
* a Message-ID search could not find: negative, so it can never be a real uid,
|
|
272
|
+
* and unique. Its UIDVALIDITY is 0, which is what tells the next change (or
|
|
273
|
+
* undo) to find it by Message-ID first.
|
|
274
|
+
*/
|
|
275
|
+
function placeholderUid() {
|
|
276
|
+
unknownCounter = (unknownCounter + 1) % 1000;
|
|
277
|
+
return -(Date.now() * 1000 + unknownCounter);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Point a row at where its message is now: folder, UIDVALIDITY, uid — and,
|
|
281
|
+
* on Gmail, its labels when they are known. The row is no longer "gone"
|
|
282
|
+
* (buddi knows where it is), and a thread whose newest message this is keeps
|
|
283
|
+
* its tie-break fields (`last_folder_id`, `last_uidvalidity`, `last_uid`)
|
|
284
|
+
* pointing at the same place. Falls back to "uid unknown" if the poll got
|
|
285
|
+
* there first.
|
|
286
|
+
*/
|
|
287
|
+
export async function relocateRow(db, target, folderId, uidValidity, uid, labels) {
|
|
288
|
+
const labelJson = labels === undefined ? null : JSON.stringify(labels ?? []);
|
|
289
|
+
let where = null;
|
|
290
|
+
if (uidValidity !== null && uid !== null) {
|
|
291
|
+
const result = await db.query(`update email.messages set folder_id = $2, uidvalidity = $3, uid = $4, gone_at = null,
|
|
292
|
+
labels = case when $6::jsonb is null then labels else $6::jsonb end
|
|
293
|
+
where id = $1
|
|
294
|
+
and not exists (select 1 from email.messages o
|
|
295
|
+
where o.account_id = $5 and o.folder_id = $2 and o.uidvalidity = $3 and o.uid = $4
|
|
296
|
+
and o.id <> $1)`, [target.id, folderId, uidValidity, uid, target.accountId, labelJson]);
|
|
297
|
+
if ((result.rowCount ?? 0) > 0)
|
|
298
|
+
where = { uidValidity, uid };
|
|
299
|
+
}
|
|
300
|
+
if (where === null) {
|
|
301
|
+
where = { uidValidity: 0, uid: placeholderUid() };
|
|
302
|
+
await db.query(`update email.messages set folder_id = $2, uidvalidity = 0, uid = $3, gone_at = null,
|
|
303
|
+
labels = case when $4::jsonb is null then labels else $4::jsonb end
|
|
304
|
+
where id = $1`, [target.id, folderId, where.uid, labelJson]);
|
|
305
|
+
}
|
|
306
|
+
await db.query(`update email.threads set last_folder_id = $2, last_uidvalidity = $3, last_uid = $4 where last_message_id = $1`, [target.id, folderId, where.uidValidity, where.uid]);
|
|
307
|
+
}
|
|
308
|
+
async function setSeenLocally(db, ids, seen) {
|
|
309
|
+
if (ids.length === 0)
|
|
310
|
+
return;
|
|
311
|
+
await db.query(seen
|
|
312
|
+
? `update email.messages set flags = flags || '["\\\\Seen"]'::jsonb
|
|
313
|
+
where id = any($1::uuid[]) and not (flags @> '["\\\\Seen"]'::jsonb)`
|
|
314
|
+
: `update email.messages set flags = flags - '\\Seen' where id = any($1::uuid[])`, [ids]);
|
|
315
|
+
}
|
|
316
|
+
/* ------------------------------------------------------------------ *
|
|
317
|
+
* The trail, written before the server is touched
|
|
318
|
+
* ------------------------------------------------------------------ */
|
|
319
|
+
/**
|
|
320
|
+
* Trail rows of changes running in this process right now. A `pending` row
|
|
321
|
+
* not in here was left by a process that stopped mid-change, and the next
|
|
322
|
+
* poll reconciles it (`reconcileTrail`). One process per installation, so
|
|
323
|
+
* this set is the whole truth about what is in flight.
|
|
324
|
+
*/
|
|
325
|
+
const inFlightTrail = new Set();
|
|
326
|
+
/** The trail rows a change in this process is still writing. */
|
|
327
|
+
export function trailInFlight() {
|
|
328
|
+
return [...inFlightTrail];
|
|
329
|
+
}
|
|
330
|
+
/** An item from before intent-first has no status: it was written after the change, so it happened. */
|
|
331
|
+
export function statusOf(item) {
|
|
332
|
+
return item.status ?? 'done';
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* The trail row, written before the first server command: `pending`, with
|
|
336
|
+
* the messages it is about and no items yet. Each folder's items are added
|
|
337
|
+
* as `planned` right before that folder's command and become `done` once the
|
|
338
|
+
* server answered, so a crash anywhere leaves a row that says what may have
|
|
339
|
+
* happened.
|
|
340
|
+
*/
|
|
341
|
+
async function beginTrail(db, input) {
|
|
342
|
+
const p = input.provenance;
|
|
343
|
+
const { rows } = await db.query(`insert into email.mailbox_actions
|
|
344
|
+
(account_id, kind, destination, criteria, origin, actor, policy_id, run_id, action_id, message_ids,
|
|
345
|
+
items, changed, note, reverts, created_at, state)
|
|
346
|
+
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10::uuid[], '[]'::jsonb, 0, null, $11, $12, 'pending')
|
|
347
|
+
returning id`, [
|
|
348
|
+
input.accountId,
|
|
349
|
+
input.kind,
|
|
350
|
+
input.destination,
|
|
351
|
+
p.criteria ?? null,
|
|
352
|
+
p.origin,
|
|
353
|
+
p.actor,
|
|
354
|
+
p.policyId ?? null,
|
|
355
|
+
p.runId ?? null,
|
|
356
|
+
p.actionId ?? null,
|
|
357
|
+
input.messageIds,
|
|
358
|
+
input.reverts ?? null,
|
|
359
|
+
input.now,
|
|
360
|
+
]);
|
|
361
|
+
const id = String(rows[0].id);
|
|
362
|
+
inFlightTrail.add(id);
|
|
363
|
+
return id;
|
|
364
|
+
}
|
|
365
|
+
/** The items as they stand, on the row. */
|
|
366
|
+
async function saveTrail(db, id, items) {
|
|
367
|
+
const kept = items.filter((i) => statusOf(i) !== 'dropped');
|
|
368
|
+
await db.query(`update email.mailbox_actions set items = $2::jsonb, changed = $3 where id = $1`, [id, JSON.stringify(kept), kept.filter((i) => statusOf(i) === 'done').length]);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Close a trail row. Without an error: `done`, or deleted when nothing
|
|
372
|
+
* changed. With one: `partial` when what was done is all known; still
|
|
373
|
+
* `pending` when a command was sent and its answer never came (the next poll
|
|
374
|
+
* asks the server); deleted when nothing reached the server.
|
|
375
|
+
*/
|
|
376
|
+
async function finishTrail(db, id, items, outcome) {
|
|
377
|
+
inFlightTrail.delete(id);
|
|
378
|
+
const kept = items.filter((i) => statusOf(i) !== 'dropped');
|
|
379
|
+
const done = kept.filter((i) => statusOf(i) === 'done');
|
|
380
|
+
const uncertain = kept.filter((i) => statusOf(i) === 'planned');
|
|
381
|
+
const skipped = outcome.skippedNote ? ` Skipped ${outcome.skippedNote}.` : '';
|
|
382
|
+
let state;
|
|
383
|
+
let note;
|
|
384
|
+
if (outcome.error !== undefined) {
|
|
385
|
+
const why = outcome.error instanceof Error ? outcome.error.message : String(outcome.error);
|
|
386
|
+
if (uncertain.length > 0) {
|
|
387
|
+
state = 'pending';
|
|
388
|
+
note = `Interrupted after ${plural(done.length, 'message')}: ${why}. ${plural(uncertain.length, 'more was', 'more were')} sent to the server without an answer; buddi checks ${uncertain.length === 1 ? 'it' : 'them'} on its next poll.${skipped}`;
|
|
389
|
+
}
|
|
390
|
+
else if (done.length > 0) {
|
|
391
|
+
state = 'partial';
|
|
392
|
+
note = `Partial: stopped by an error after ${plural(done.length, 'message')}: ${why}.${skipped}`;
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
await db.query(`delete from email.mailbox_actions where id = $1`, [id]);
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
if (done.length === 0) {
|
|
401
|
+
await db.query(`delete from email.mailbox_actions where id = $1`, [id]);
|
|
402
|
+
return null;
|
|
403
|
+
}
|
|
404
|
+
state = 'done';
|
|
405
|
+
note = skipped ? skipped.trim() : null;
|
|
406
|
+
}
|
|
407
|
+
const { rows } = await db.query(`update email.mailbox_actions set state = $2, note = $3, items = $4::jsonb, message_ids = $5::uuid[], changed = $6
|
|
408
|
+
where id = $1 returning ${ACTION_COLUMNS}`, [id, state, note, JSON.stringify(kept), kept.map((i) => i.id), done.length]);
|
|
409
|
+
return rows[0] ? toAction(rows[0]) : null;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* After an undo (or its reconcile): the messages it put back join the
|
|
413
|
+
* original's `reverted_ids`, and the original is stamped undone once the undo
|
|
414
|
+
* finished without an error or nothing of it is left to put back. A partial
|
|
415
|
+
* undo leaves it undoable, for the rest.
|
|
416
|
+
*/
|
|
417
|
+
async function markReverted(db, original, doneIds, finished, undoId, now) {
|
|
418
|
+
const reverted = new Set([...original.revertedIds, ...doneIds]);
|
|
419
|
+
const remaining = original.items.filter((i) => statusOf(i) === 'done' && !reverted.has(i.id));
|
|
420
|
+
const complete = (finished && undoId !== null) || remaining.length === 0;
|
|
421
|
+
await db.query(`update email.mailbox_actions
|
|
422
|
+
set reverted_ids = $2::uuid[],
|
|
423
|
+
undone_at = case when $3 then $4 else undone_at end,
|
|
424
|
+
undone_by = case when $3 then $5::uuid else undone_by end
|
|
425
|
+
where id = $1`, [original.id, [...reverted], complete, now, undoId]);
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Find where each target is now, on the server: its folder's generation must
|
|
429
|
+
* match, and a row whose uid is unknown (UIDVALIDITY 0) is looked up by
|
|
430
|
+
* Message-ID. Returns the uid per target, or null for one that is not there.
|
|
431
|
+
*/
|
|
432
|
+
async function locate(client, folder, targets) {
|
|
433
|
+
const status = await client.open(folder);
|
|
434
|
+
const uids = new Map();
|
|
435
|
+
for (const t of targets) {
|
|
436
|
+
if (t.uidValidity === status.uidValidity && t.uid > 0) {
|
|
437
|
+
uids.set(t.id, t.uid);
|
|
438
|
+
}
|
|
439
|
+
else if (t.messageId) {
|
|
440
|
+
const found = await client.findByMessageId(folder, t.messageId);
|
|
441
|
+
if (found !== null)
|
|
442
|
+
uids.set(t.id, found);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const out = new Map();
|
|
446
|
+
if (uids.size === 0)
|
|
447
|
+
return out;
|
|
448
|
+
const states = await client.fetchFlags(folder, [...uids.values()]);
|
|
449
|
+
const flagsOf = new Map(states.map((s) => [s.uid, s.flags]));
|
|
450
|
+
for (const [id, uid] of uids) {
|
|
451
|
+
const flags = flagsOf.get(uid);
|
|
452
|
+
if (flags)
|
|
453
|
+
out.set(id, { uid, flags });
|
|
454
|
+
}
|
|
455
|
+
return out;
|
|
456
|
+
}
|
|
457
|
+
function byFolder(targets) {
|
|
458
|
+
const groups = new Map();
|
|
459
|
+
for (const t of targets) {
|
|
460
|
+
const list = groups.get(t.folder) ?? [];
|
|
461
|
+
list.push(t);
|
|
462
|
+
groups.set(t.folder, list);
|
|
463
|
+
}
|
|
464
|
+
return groups;
|
|
465
|
+
}
|
|
466
|
+
/** Where the moved messages landed: COPYUID first, a Message-ID search for the rest. */
|
|
467
|
+
async function landed(client, destination, moved, result) {
|
|
468
|
+
const uids = new Map();
|
|
469
|
+
const unknown = [];
|
|
470
|
+
for (const m of moved) {
|
|
471
|
+
const to = result.uidMap.get(m.uid);
|
|
472
|
+
if (to !== undefined)
|
|
473
|
+
uids.set(m.target.id, to);
|
|
474
|
+
else
|
|
475
|
+
unknown.push(m);
|
|
476
|
+
}
|
|
477
|
+
let uidValidity = result.uidValidity;
|
|
478
|
+
if (unknown.length > 0 || uidValidity === null) {
|
|
479
|
+
const status = await client.open(destination);
|
|
480
|
+
uidValidity = uidValidity ?? status.uidValidity;
|
|
481
|
+
for (const m of unknown) {
|
|
482
|
+
uids.set(m.target.id, m.target.messageId ? await client.findByMessageId(destination, m.target.messageId) : null);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return { uidValidity, uids };
|
|
486
|
+
}
|
|
487
|
+
/** Gmail's own name for inbox membership, as X-GM-LABELS spells it. */
|
|
488
|
+
export const GMAIL_INBOX_LABEL = '\\Inbox';
|
|
489
|
+
/**
|
|
490
|
+
* On Gmail, a folder that is a label the owner made: not INBOX and not one
|
|
491
|
+
* of Gmail's own (All Mail, Trash, Spam, Sent, Drafts, Starred, Important).
|
|
492
|
+
*/
|
|
493
|
+
export function isUserLabel(facts, name) {
|
|
494
|
+
if (!facts.gmail || name.toUpperCase() === INBOX)
|
|
495
|
+
return false;
|
|
496
|
+
const info = facts.listing.find((f) => f.name === name);
|
|
497
|
+
if (!info)
|
|
498
|
+
return false;
|
|
499
|
+
return !attributesOf(info).some((a) => a.startsWith('\\') && a !== '\\hasnochildren' && a !== '\\haschildren');
|
|
500
|
+
}
|
|
501
|
+
/** Labels without Gmail's inbox marker, deduplicated, in a stable order. */
|
|
502
|
+
function plainLabels(labels) {
|
|
503
|
+
return [...new Set((labels ?? []).filter((l) => l !== GMAIL_INBOX_LABEL))].sort();
|
|
504
|
+
}
|
|
505
|
+
function skippedWords(reasons) {
|
|
506
|
+
return [...reasons.entries()].map(([why, n]) => `${n} ${why}`).join(', ');
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Carry out one change on one account's server, keep the rows in step, and
|
|
510
|
+
* write it on the trail — intent first: the row exists, `pending`, before the
|
|
511
|
+
* first command, each folder's messages are on it as `planned` before that
|
|
512
|
+
* folder's command and `done` after it, so a crash between the server change
|
|
513
|
+
* and the record leaves a row the next poll reconciles (`reconcileTrail`).
|
|
514
|
+
*
|
|
515
|
+
* Messages no longer where buddi last saw them are skipped, never guessed at,
|
|
516
|
+
* and the note says how many. Nothing is recorded when nothing changed.
|
|
517
|
+
*/
|
|
518
|
+
export async function performAction(db, client, input) {
|
|
519
|
+
const { account, kind, targets } = input;
|
|
520
|
+
const facts = input.facts ?? (await serverFacts(client));
|
|
521
|
+
const destination = destinationFor(facts, kind, account.address, input.folder);
|
|
522
|
+
const items = [];
|
|
523
|
+
const reasons = new Map();
|
|
524
|
+
const skip = (why, n = 1) => {
|
|
525
|
+
if (n > 0)
|
|
526
|
+
reasons.set(why, (reasons.get(why) ?? 0) + n);
|
|
527
|
+
};
|
|
528
|
+
// A message the poll found gone from its folder has no place on the server
|
|
529
|
+
// buddi knows: it was moved or deleted in another app.
|
|
530
|
+
const live = targets.filter((t) => !t.gone);
|
|
531
|
+
for (const t of targets)
|
|
532
|
+
if (t.gone)
|
|
533
|
+
skip('moved or deleted in another mail app');
|
|
534
|
+
if (live.length === 0) {
|
|
535
|
+
return { action: null, changed: 0, skipped: targets.length, note: `Nothing changed in ${account.address} (${skippedWords(reasons)}).` };
|
|
536
|
+
}
|
|
537
|
+
const trailId = await beginTrail(db, {
|
|
538
|
+
accountId: account.id,
|
|
539
|
+
kind,
|
|
540
|
+
destination,
|
|
541
|
+
provenance: input.provenance,
|
|
542
|
+
messageIds: live.map((t) => t.id),
|
|
543
|
+
now: input.now,
|
|
544
|
+
});
|
|
545
|
+
const save = () => saveTrail(db, trailId, items);
|
|
546
|
+
try {
|
|
547
|
+
for (const [folder, group] of byFolder(live)) {
|
|
548
|
+
const here = await locate(client, folder, group);
|
|
549
|
+
skip(`no longer in ${folder}`, group.length - here.size);
|
|
550
|
+
const present = group.filter((t) => here.has(t.id));
|
|
551
|
+
if (present.length === 0)
|
|
552
|
+
continue;
|
|
553
|
+
if (kind === 'mark-read' || kind === 'mark-unread') {
|
|
554
|
+
const seen = kind === 'mark-read';
|
|
555
|
+
const change = present.filter((t) => here.get(t.id).flags.includes(SEEN) !== seen);
|
|
556
|
+
skip(seen ? 'already read' : 'already unread', present.length - change.length);
|
|
557
|
+
if (change.length === 0)
|
|
558
|
+
continue;
|
|
559
|
+
const planned = change.map((t) => {
|
|
560
|
+
const at = here.get(t.id);
|
|
561
|
+
return {
|
|
562
|
+
id: t.id, subject: t.subject, from: t.from, messageId: t.messageId,
|
|
563
|
+
fromFolder: folder, fromUidValidity: t.uidValidity > 0 ? t.uidValidity : 0, fromUid: at.uid,
|
|
564
|
+
prevFlags: at.flags, wantSeen: seen, status: 'planned',
|
|
565
|
+
};
|
|
566
|
+
});
|
|
567
|
+
items.push(...planned);
|
|
568
|
+
await save();
|
|
569
|
+
await client.storeFlags(folder, change.map((t) => here.get(t.id).uid), [SEEN], seen ? 'add' : 'remove');
|
|
570
|
+
for (const p of planned)
|
|
571
|
+
p.status = 'done';
|
|
572
|
+
await setSeenLocally(db, change.map((t) => t.id), seen);
|
|
573
|
+
await save();
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
// A move of some kind. Already there is not a change.
|
|
577
|
+
let movable = present.filter((t) => folder !== destination);
|
|
578
|
+
skip(kind === 'trash' ? 'already in Trash' : `already in ${destination}`, present.length - movable.length);
|
|
579
|
+
if (kind === 'archive' && facts.gmail && folder !== INBOX) {
|
|
580
|
+
skip('not in the inbox', movable.length);
|
|
581
|
+
movable = [];
|
|
582
|
+
}
|
|
583
|
+
if (movable.length === 0)
|
|
584
|
+
continue;
|
|
585
|
+
/*
|
|
586
|
+
* Gmail, from the inbox to a label: the label goes on and Inbox comes
|
|
587
|
+
* off (X-GM-LABELS), so every other label stays exactly as it was.
|
|
588
|
+
* Anywhere else a MOVE (from another label it swaps that label for the
|
|
589
|
+
* new one, which is what moving between labels means).
|
|
590
|
+
*/
|
|
591
|
+
const labelMove = kind === 'move' && facts.gmail && folder.toUpperCase() === INBOX && isUserLabel(facts, destination);
|
|
592
|
+
const source = await client.open(folder);
|
|
593
|
+
const labels = facts.gmail && (kind === 'trash' || labelMove)
|
|
594
|
+
? await client.fetchLabels(folder, movable.map((t) => here.get(t.id).uid))
|
|
595
|
+
: new Map();
|
|
596
|
+
const moved = movable.map((t) => ({ target: t, uid: here.get(t.id).uid }));
|
|
597
|
+
const pushed = moved.map((m) => ({
|
|
598
|
+
id: m.target.id, subject: m.target.subject, from: m.target.from, messageId: m.target.messageId,
|
|
599
|
+
fromFolder: folder, fromUidValidity: source.uidValidity, fromUid: m.uid,
|
|
600
|
+
toFolder: destination, toUidValidity: 0, toUid: null,
|
|
601
|
+
prevFlags: here.get(m.target.id).flags,
|
|
602
|
+
...(labels.has(m.uid) ? { prevLabels: plainLabels(labels.get(m.uid)) } : {}),
|
|
603
|
+
...(labelMove ? { via: 'labels' } : {}),
|
|
604
|
+
status: 'planned',
|
|
605
|
+
}));
|
|
606
|
+
items.push(...pushed);
|
|
607
|
+
await save();
|
|
608
|
+
let result;
|
|
609
|
+
const uids = moved.map((m) => m.uid);
|
|
610
|
+
if (labelMove) {
|
|
611
|
+
await client.storeLabels(folder, uids, [destination], 'add');
|
|
612
|
+
await client.storeLabels(folder, uids, [GMAIL_INBOX_LABEL], 'remove');
|
|
613
|
+
result = { uidValidity: null, uidMap: new Map() };
|
|
614
|
+
}
|
|
615
|
+
else {
|
|
616
|
+
result = await client.move(folder, uids, destination);
|
|
617
|
+
}
|
|
618
|
+
// The server has moved them: done, refined below. Should the landing
|
|
619
|
+
// lookup fail, each row still follows to the destination with its uid
|
|
620
|
+
// unknown (found by Message-ID next time), so undo can find it.
|
|
621
|
+
for (const p of pushed)
|
|
622
|
+
p.status = 'done';
|
|
623
|
+
const labelsAfter = (m) => labelMove ? plainLabels([...(labels.get(m.uid) ?? []), destination]) : facts.gmail && kind === 'trash' ? [] : undefined;
|
|
624
|
+
const destId = await folderRow(db, account.id, destination, specialUseOf(facts.listing, destination));
|
|
625
|
+
let where;
|
|
626
|
+
try {
|
|
627
|
+
where = await landed(client, destination, moved, result);
|
|
628
|
+
}
|
|
629
|
+
catch (err) {
|
|
630
|
+
for (const m of moved)
|
|
631
|
+
await relocateRow(db, m.target, destId, null, null, labelsAfter(m));
|
|
632
|
+
throw err;
|
|
633
|
+
}
|
|
634
|
+
for (const [i, m] of moved.entries()) {
|
|
635
|
+
const newUid = where.uids.get(m.target.id) ?? null;
|
|
636
|
+
await relocateRow(db, m.target, destId, newUid === null ? null : where.uidValidity, newUid, labelsAfter(m));
|
|
637
|
+
pushed[i].toUidValidity = where.uidValidity ?? 0;
|
|
638
|
+
pushed[i].toUid = newUid;
|
|
639
|
+
}
|
|
640
|
+
await save();
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
catch (err) {
|
|
644
|
+
await finishTrail(db, trailId, items, { error: err, skippedNote: skippedWords(reasons) }).catch(() => { });
|
|
645
|
+
throw err;
|
|
646
|
+
}
|
|
647
|
+
const skipped = [...reasons.values()].reduce((a, b) => a + b, 0);
|
|
648
|
+
const skippedNote = skippedWords(reasons);
|
|
649
|
+
const action = await finishTrail(db, trailId, items, { skippedNote });
|
|
650
|
+
const changed = action?.changed ?? 0;
|
|
651
|
+
const done = `${verbOf(kind, destination)}: ${plural(changed, 'message')} in ${account.address}`;
|
|
652
|
+
const note = changed === 0
|
|
653
|
+
? `Nothing changed in ${account.address}${skippedNote ? ` (${skippedNote})` : ''}.`
|
|
654
|
+
: `${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.'}`;
|
|
655
|
+
return { action, changed, skipped, note };
|
|
656
|
+
}
|
|
657
|
+
/* ------------------------------------------------------------------ *
|
|
658
|
+
* Undo
|
|
659
|
+
* ------------------------------------------------------------------ */
|
|
660
|
+
export async function findAction(db, id) {
|
|
661
|
+
const { rows } = await db.query(`select ${ACTION_COLUMNS} from email.mailbox_actions where id = $1::uuid`, [id]);
|
|
662
|
+
return rows[0] ? toAction(rows[0]) : null;
|
|
663
|
+
}
|
|
664
|
+
/** The newest change that can still be undone, in these accounts. */
|
|
665
|
+
export async function lastUndoable(db, accountIds) {
|
|
666
|
+
const { rows } = await db.query(`select ${ACTION_COLUMNS} from email.mailbox_actions
|
|
667
|
+
where account_id = any($1::uuid[]) and kind <> 'undo' and undone_at is null
|
|
668
|
+
and state <> 'pending' and changed > 0
|
|
669
|
+
order by created_at desc, seq desc limit 1`, [accountIds]);
|
|
670
|
+
return rows[0] ? toAction(rows[0]) : null;
|
|
671
|
+
}
|
|
672
|
+
/** The messages of a change an undo can still put back: done, and not put back already. */
|
|
673
|
+
export function undoableItems(action) {
|
|
674
|
+
const reverted = new Set(action.revertedIds);
|
|
675
|
+
return action.items.filter((i) => statusOf(i) === 'done' && !reverted.has(i.id));
|
|
676
|
+
}
|
|
677
|
+
/** Why a change cannot be undone, or null when it can. */
|
|
678
|
+
export function undoRefusal(action) {
|
|
679
|
+
if (action.kind === 'undo')
|
|
680
|
+
return 'That was itself an undo; buddi does not undo an undo. Make the change again instead.';
|
|
681
|
+
if (action.undoneAt)
|
|
682
|
+
return `That change was already undone (${action.undoneAt}).`;
|
|
683
|
+
if (action.state === 'pending') {
|
|
684
|
+
return 'buddi stopped while making that change, and has not yet checked with the server how far it got. It does on its next poll; undo it after that.';
|
|
685
|
+
}
|
|
686
|
+
if (undoableItems(action).length === 0)
|
|
687
|
+
return 'Nothing of that change is left to put back.';
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* How many of a change's messages buddi has seen move since, in another mail
|
|
692
|
+
* app: gone from the folder the change left them in, or now somewhere else.
|
|
693
|
+
* An undo leaves those where the owner put them.
|
|
694
|
+
*/
|
|
695
|
+
export async function movedSince(db, action) {
|
|
696
|
+
const items = undoableItems(action);
|
|
697
|
+
if (items.length === 0)
|
|
698
|
+
return 0;
|
|
699
|
+
const { rows } = await db.query(`select m.id, f.name as folder, m.gone_at from email.messages m join email.folders f on f.id = m.folder_id
|
|
700
|
+
where m.id = any($1::uuid[])`, [items.map((i) => i.id)]);
|
|
701
|
+
const byId = new Map(rows.map((r) => [String(r.id), r]));
|
|
702
|
+
let n = 0;
|
|
703
|
+
for (const item of items) {
|
|
704
|
+
const row = byId.get(item.id);
|
|
705
|
+
if (!row)
|
|
706
|
+
continue;
|
|
707
|
+
if (row.gone_at !== null && row.gone_at !== undefined)
|
|
708
|
+
n += 1;
|
|
709
|
+
else if (item.toFolder && row.folder !== item.toFolder)
|
|
710
|
+
n += 1;
|
|
711
|
+
}
|
|
712
|
+
return n;
|
|
713
|
+
}
|
|
714
|
+
/** The sentence an undo's approval and the Recent changes row say. */
|
|
715
|
+
export function describeUndo(action, account, moved = 0) {
|
|
716
|
+
const left = undoableItems(action).length;
|
|
717
|
+
const n = plural(left, 'message');
|
|
718
|
+
const rest = action.revertedIds.length > 0 ? ' the rest of' : '';
|
|
719
|
+
const since = moved > 0
|
|
720
|
+
? ` ${plural(moved, 'of them has', 'of them have')} since been moved in another mail app and will stay where ${moved === 1 ? 'it is' : 'they are'}.`
|
|
721
|
+
: '';
|
|
722
|
+
switch (action.kind) {
|
|
723
|
+
case 'mark-read':
|
|
724
|
+
return `Undo${rest} "${verbOf(action.kind)}" on ${n} in ${account}: they become unread again.${since}`;
|
|
725
|
+
case 'mark-unread':
|
|
726
|
+
return `Undo${rest} "${verbOf(action.kind)}" on ${n} in ${account}: they become read again.${since}`;
|
|
727
|
+
case 'trash':
|
|
728
|
+
return `Undo${rest} "${verbOf(action.kind)}" on ${n} in ${account}: they move back from Trash to where they were (any already emptied from Trash cannot come back).${since}`;
|
|
729
|
+
default:
|
|
730
|
+
return `Undo${rest} "${verbOf(action.kind, action.destination)}" on ${n} in ${account}: they move back to where they were.${since}`;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Put one change back, as far as the mailbox still allows, and record the
|
|
735
|
+
* undo as a change of its own — intent first, like `performAction`.
|
|
736
|
+
*
|
|
737
|
+
* Each message is acted on where buddi's row says it is now — the row
|
|
738
|
+
* followed it — and only if that is still where the change left it: one the
|
|
739
|
+
* poll saw moved in another mail app is left where the owner put it, and one
|
|
740
|
+
* emptied from Trash is skipped; the note says which. An undo stopped by an
|
|
741
|
+
* error records what it put back, is marked partial, and leaves the change
|
|
742
|
+
* undoable for the rest.
|
|
743
|
+
*/
|
|
744
|
+
export async function undoAction(db, client, input) {
|
|
745
|
+
const { account, action } = input;
|
|
746
|
+
const refusal = undoRefusal(action);
|
|
747
|
+
if (refusal)
|
|
748
|
+
throw new MailboxRefusal(refusal);
|
|
749
|
+
const facts = await serverFacts(client);
|
|
750
|
+
const wanted = undoableItems(action);
|
|
751
|
+
const current = await loadTargets(db, wanted.map((i) => i.id));
|
|
752
|
+
const itemOf = new Map(wanted.map((i) => [i.id, i]));
|
|
753
|
+
const items = [];
|
|
754
|
+
const reasons = new Map();
|
|
755
|
+
const skip = (why, n = 1) => {
|
|
756
|
+
if (n > 0)
|
|
757
|
+
reasons.set(why, (reasons.get(why) ?? 0) + n);
|
|
758
|
+
};
|
|
759
|
+
skip('no longer known to buddi', wanted.length - current.length);
|
|
760
|
+
const isMove = action.kind !== 'mark-read' && action.kind !== 'mark-unread';
|
|
761
|
+
const eligible = current.filter((t) => {
|
|
762
|
+
const item = itemOf.get(t.id);
|
|
763
|
+
if (t.gone || (isMove && item.toFolder && t.folder !== item.toFolder)) {
|
|
764
|
+
skip('moved in another mail app since, so left where you put it');
|
|
765
|
+
return false;
|
|
766
|
+
}
|
|
767
|
+
return true;
|
|
768
|
+
});
|
|
769
|
+
const summary = (changed) => {
|
|
770
|
+
const skipped = [...reasons.values()].reduce((a, b) => a + b, 0);
|
|
771
|
+
const why = skippedWords(reasons);
|
|
772
|
+
return changed === 0
|
|
773
|
+
? `Nothing could be put back in ${account.address}${skipped > 0 ? ` (${why})` : ''}.`
|
|
774
|
+
: `Undid "${verbOf(action.kind, action.destination)}" on ${plural(changed, 'message')} in ${account.address}.${skipped > 0 ? ` ${plural(skipped, 'message')} could not be put back: ${why}.` : ''}`;
|
|
775
|
+
};
|
|
776
|
+
if (eligible.length === 0) {
|
|
777
|
+
return { action: null, changed: 0, skipped: [...reasons.values()].reduce((a, b) => a + b, 0), note: summary(0) };
|
|
778
|
+
}
|
|
779
|
+
const trailId = await beginTrail(db, {
|
|
780
|
+
accountId: account.id,
|
|
781
|
+
kind: 'undo',
|
|
782
|
+
destination: null,
|
|
783
|
+
provenance: input.provenance,
|
|
784
|
+
messageIds: eligible.map((t) => t.id),
|
|
785
|
+
reverts: action.id,
|
|
786
|
+
now: input.now,
|
|
787
|
+
});
|
|
788
|
+
const save = () => saveTrail(db, trailId, items);
|
|
789
|
+
const doneIds = () => items.filter((i) => statusOf(i) === 'done').map((i) => i.id);
|
|
790
|
+
try {
|
|
791
|
+
for (const [folder, group] of byFolder(eligible)) {
|
|
792
|
+
const here = await locate(client, folder, group);
|
|
793
|
+
skip('no longer where the change left it', group.length - here.size);
|
|
794
|
+
const present = group.filter((t) => here.has(t.id));
|
|
795
|
+
if (present.length === 0)
|
|
796
|
+
continue;
|
|
797
|
+
if (!isMove) {
|
|
798
|
+
for (const seen of [true, false]) {
|
|
799
|
+
const list = present.filter((t) => (itemOf.get(t.id).prevFlags ?? []).includes(SEEN) === seen);
|
|
800
|
+
if (list.length === 0)
|
|
801
|
+
continue;
|
|
802
|
+
const planned = list.map((t) => ({
|
|
803
|
+
id: t.id, subject: t.subject, from: t.from, messageId: t.messageId,
|
|
804
|
+
fromFolder: folder, fromUidValidity: t.uidValidity, fromUid: here.get(t.id).uid,
|
|
805
|
+
prevFlags: here.get(t.id).flags, wantSeen: seen, status: 'planned',
|
|
806
|
+
}));
|
|
807
|
+
items.push(...planned);
|
|
808
|
+
await save();
|
|
809
|
+
await client.storeFlags(folder, list.map((t) => here.get(t.id).uid), [SEEN], seen ? 'add' : 'remove');
|
|
810
|
+
for (const p of planned)
|
|
811
|
+
p.status = 'done';
|
|
812
|
+
await setSeenLocally(db, list.map((t) => t.id), seen);
|
|
813
|
+
await save();
|
|
814
|
+
}
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
// Moves: back to each message's own original folder.
|
|
818
|
+
const back = new Map();
|
|
819
|
+
for (const t of present) {
|
|
820
|
+
const original = itemOf.get(t.id).fromFolder;
|
|
821
|
+
if (original === folder) {
|
|
822
|
+
skip('already back where it was');
|
|
823
|
+
continue;
|
|
824
|
+
}
|
|
825
|
+
const list = back.get(original) ?? [];
|
|
826
|
+
list.push(t);
|
|
827
|
+
back.set(original, list);
|
|
828
|
+
}
|
|
829
|
+
for (const [original, list] of back) {
|
|
830
|
+
if (!facts.listing.some((f) => f.name === original)) {
|
|
831
|
+
skip(`its old folder ${original} is gone`, list.length);
|
|
832
|
+
continue;
|
|
833
|
+
}
|
|
834
|
+
const source = await client.open(folder);
|
|
835
|
+
const viaLabels = list.filter((t) => facts.gmail && itemOf.get(t.id).via === 'labels' && original.toUpperCase() === INBOX);
|
|
836
|
+
const viaMove = list.filter((t) => !viaLabels.includes(t));
|
|
837
|
+
const destId = await folderRow(db, account.id, original, specialUseOf(facts.listing, original));
|
|
838
|
+
if (viaMove.length > 0) {
|
|
839
|
+
const moved = viaMove.map((t) => ({ target: t, uid: here.get(t.id).uid }));
|
|
840
|
+
const pushed = moved.map((m) => ({
|
|
841
|
+
id: m.target.id, subject: m.target.subject, from: m.target.from, messageId: m.target.messageId,
|
|
842
|
+
fromFolder: folder, fromUidValidity: source.uidValidity, fromUid: m.uid,
|
|
843
|
+
toFolder: original, toUidValidity: 0, toUid: null, status: 'planned',
|
|
844
|
+
}));
|
|
845
|
+
items.push(...pushed);
|
|
846
|
+
await save();
|
|
847
|
+
const result = await client.move(folder, moved.map((m) => m.uid), original);
|
|
848
|
+
for (const p of pushed)
|
|
849
|
+
p.status = 'done';
|
|
850
|
+
const where = await landed(client, original, moved, result);
|
|
851
|
+
for (const [i, m] of moved.entries()) {
|
|
852
|
+
const newUid = where.uids.get(m.target.id) ?? null;
|
|
853
|
+
const prev = itemOf.get(m.target.id).prevLabels;
|
|
854
|
+
await relocateRow(db, m.target, destId, newUid === null ? null : where.uidValidity, newUid, facts.gmail && prev ? plainLabels(prev) : undefined);
|
|
855
|
+
pushed[i].toUidValidity = where.uidValidity ?? 0;
|
|
856
|
+
pushed[i].toUid = newUid;
|
|
857
|
+
}
|
|
858
|
+
// Gmail drops a message's labels in Trash: give back the ones it had.
|
|
859
|
+
if (facts.gmail) {
|
|
860
|
+
const byLabels = new Map();
|
|
861
|
+
for (const m of moved) {
|
|
862
|
+
const prev = plainLabels(itemOf.get(m.target.id).prevLabels);
|
|
863
|
+
const uid = where.uids.get(m.target.id);
|
|
864
|
+
if (prev.length === 0 || uid === null || uid === undefined)
|
|
865
|
+
continue;
|
|
866
|
+
const key = JSON.stringify(prev);
|
|
867
|
+
byLabels.set(key, [...(byLabels.get(key) ?? []), uid]);
|
|
868
|
+
}
|
|
869
|
+
for (const [key, uids] of byLabels)
|
|
870
|
+
await client.addLabels(original, uids, JSON.parse(key));
|
|
871
|
+
}
|
|
872
|
+
await save();
|
|
873
|
+
}
|
|
874
|
+
if (viaLabels.length > 0) {
|
|
875
|
+
await undoLabelMove(db, client, { folder, original, destId, source, list: viaLabels, here, itemOf, items, save });
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
catch (err) {
|
|
881
|
+
const undo = await finishTrail(db, trailId, items, { error: err, skippedNote: skippedWords(reasons) }).catch(() => null);
|
|
882
|
+
await markReverted(db, action, doneIds(), false, undo?.id ?? null, input.now).catch(() => { });
|
|
883
|
+
throw err;
|
|
884
|
+
}
|
|
885
|
+
const undo = await finishTrail(db, trailId, items, { skippedNote: skippedWords(reasons) });
|
|
886
|
+
const changed = undo?.changed ?? 0;
|
|
887
|
+
if (undo)
|
|
888
|
+
await markReverted(db, action, doneIds(), true, undo.id, input.now);
|
|
889
|
+
return { action: undo, changed, skipped: [...reasons.values()].reduce((a, b) => a + b, 0), note: summary(changed) };
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Undo a Gmail label move exactly: the labels the message had before come
|
|
893
|
+
* back, any added since go, and Inbox goes back on — over X-GM-LABELS, so the
|
|
894
|
+
* message never passes through a MOVE that would drop one. The label it was
|
|
895
|
+
* moved to comes off last, from the inbox copy, so the message is never
|
|
896
|
+
* without a home in between.
|
|
897
|
+
*/
|
|
898
|
+
async function undoLabelMove(db, client, input) {
|
|
899
|
+
const { folder, original, list, here, itemOf, items, save } = input;
|
|
900
|
+
const uidOf = (t) => here.get(t.id).uid;
|
|
901
|
+
const now = await client.fetchLabels(folder, list.map(uidOf));
|
|
902
|
+
// One set of commands per distinct (before, now): usually all of them.
|
|
903
|
+
const groups = new Map();
|
|
904
|
+
for (const t of list) {
|
|
905
|
+
const prev = plainLabels(itemOf.get(t.id).prevLabels);
|
|
906
|
+
const current = plainLabels(now.get(uidOf(t)));
|
|
907
|
+
const key = JSON.stringify([prev, current]);
|
|
908
|
+
const g = groups.get(key) ?? { prev, current, targets: [] };
|
|
909
|
+
g.targets.push(t);
|
|
910
|
+
groups.set(key, g);
|
|
911
|
+
}
|
|
912
|
+
for (const { prev, current, targets } of groups.values()) {
|
|
913
|
+
const pushed = targets.map((t) => ({
|
|
914
|
+
id: t.id, subject: t.subject, from: t.from, messageId: t.messageId,
|
|
915
|
+
fromFolder: folder, fromUidValidity: input.source.uidValidity, fromUid: uidOf(t),
|
|
916
|
+
toFolder: original, toUidValidity: 0, toUid: null, prevLabels: current, via: 'labels', status: 'planned',
|
|
917
|
+
}));
|
|
918
|
+
items.push(...pushed);
|
|
919
|
+
await save();
|
|
920
|
+
const uids = targets.map(uidOf);
|
|
921
|
+
const add = prev.filter((l) => !current.includes(l));
|
|
922
|
+
const remove = current.filter((l) => !prev.includes(l) && l !== folder);
|
|
923
|
+
if (add.length > 0)
|
|
924
|
+
await client.storeLabels(folder, uids, add, 'add');
|
|
925
|
+
if (remove.length > 0)
|
|
926
|
+
await client.storeLabels(folder, uids, remove, 'remove');
|
|
927
|
+
await client.storeLabels(folder, uids, [GMAIL_INBOX_LABEL], 'add');
|
|
928
|
+
for (const p of pushed)
|
|
929
|
+
p.status = 'done';
|
|
930
|
+
// Back in the inbox; now find each one there and take the moved-to label off.
|
|
931
|
+
const status = await client.open(original);
|
|
932
|
+
for (const [i, t] of targets.entries()) {
|
|
933
|
+
const uid = t.messageId ? await client.findByMessageId(original, t.messageId) : null;
|
|
934
|
+
if (uid !== null && !prev.includes(folder))
|
|
935
|
+
await client.storeLabels(original, [uid], [folder], 'remove');
|
|
936
|
+
await relocateRow(db, t, input.destId, uid === null ? null : status.uidValidity, uid, prev);
|
|
937
|
+
pushed[i].toUidValidity = uid === null ? 0 : status.uidValidity;
|
|
938
|
+
pushed[i].toUid = uid;
|
|
939
|
+
}
|
|
940
|
+
await save();
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
/* ------------------------------------------------------------------ *
|
|
944
|
+
* After a crash: what the server says happened
|
|
945
|
+
* ------------------------------------------------------------------ */
|
|
946
|
+
/**
|
|
947
|
+
* Settle the `pending` trail rows a stopped process left for this account:
|
|
948
|
+
* for each message planned and never confirmed, ask the server by Message-ID
|
|
949
|
+
* where it is. Still where it was: it did not happen — the item goes. In
|
|
950
|
+
* the destination: it happened — the row follows and the item is done.
|
|
951
|
+
* Neither, or no Message-ID to ask with: unknown. The row becomes `done`, `partial`
|
|
952
|
+
* (something did not happen) or `unknown`, or goes when nothing happened. An
|
|
953
|
+
* interrupted undo puts what it did on its change's `reverted_ids`.
|
|
954
|
+
*/
|
|
955
|
+
export async function reconcileTrail(db, client, input) {
|
|
956
|
+
const { rows } = await db.query(`select ${ACTION_COLUMNS} from email.mailbox_actions
|
|
957
|
+
where account_id = $1 and state = 'pending' and not (id = any($2::uuid[]))
|
|
958
|
+
order by created_at, seq`, [input.account.id, trailInFlight()]);
|
|
959
|
+
if (rows.length === 0)
|
|
960
|
+
return { settled: 0 };
|
|
961
|
+
const facts = await serverFacts(client);
|
|
962
|
+
let settled = 0;
|
|
963
|
+
for (const action of rows.map(toAction)) {
|
|
964
|
+
const items = action.items.map((i) => ({ ...i }));
|
|
965
|
+
let dropped = 0;
|
|
966
|
+
for (const item of items) {
|
|
967
|
+
if (statusOf(item) !== 'planned')
|
|
968
|
+
continue;
|
|
969
|
+
const target = (await loadTargets(db, [item.id]))[0];
|
|
970
|
+
if (item.toFolder) {
|
|
971
|
+
/*
|
|
972
|
+
* Gmail's label move is two commands — the label on, then Inbox off
|
|
973
|
+
* (an undo: the labels back, Inbox on, then the label off) — and a
|
|
974
|
+
* crash between them leaves the message where it was *and* changed.
|
|
975
|
+
* The Inbox step is the move itself, so a half-done one is finished
|
|
976
|
+
* here: its second command is sent, and the item goes on as done.
|
|
977
|
+
*/
|
|
978
|
+
if (facts.gmail && item.via === 'labels' && item.messageId) {
|
|
979
|
+
await finishLabelMove(db, client, action, item);
|
|
980
|
+
}
|
|
981
|
+
// Where it was first: on Gmail, All Mail also holds what is still
|
|
982
|
+
// in the inbox, so "found in the destination" alone proves nothing.
|
|
983
|
+
const stayed = item.messageId ? await client.findByMessageId(item.fromFolder, item.messageId) : null;
|
|
984
|
+
if (stayed !== null) {
|
|
985
|
+
item.status = 'dropped';
|
|
986
|
+
dropped += 1;
|
|
987
|
+
continue;
|
|
988
|
+
}
|
|
989
|
+
const there = item.messageId ? await client.findByMessageId(item.toFolder, item.messageId) : null;
|
|
990
|
+
if (there !== null) {
|
|
991
|
+
const status = await client.open(item.toFolder);
|
|
992
|
+
item.status = 'done';
|
|
993
|
+
item.toUidValidity = status.uidValidity;
|
|
994
|
+
item.toUid = there;
|
|
995
|
+
if (target) {
|
|
996
|
+
const destId = await folderRow(db, input.account.id, item.toFolder, specialUseOf(facts.listing, item.toFolder));
|
|
997
|
+
let labels;
|
|
998
|
+
if (facts.gmail)
|
|
999
|
+
labels = plainLabels((await client.fetchLabels(item.toFolder, [there])).get(there));
|
|
1000
|
+
await relocateRow(db, target, destId, status.uidValidity, there, labels);
|
|
1001
|
+
}
|
|
1002
|
+
continue;
|
|
1003
|
+
}
|
|
1004
|
+
item.status = 'unknown';
|
|
1005
|
+
continue;
|
|
1006
|
+
}
|
|
1007
|
+
// A flag change: is the read mark what the change wanted?
|
|
1008
|
+
const status = await client.open(item.fromFolder);
|
|
1009
|
+
let uid = item.fromUidValidity === status.uidValidity && item.fromUid > 0 ? item.fromUid : null;
|
|
1010
|
+
if (uid === null && item.messageId)
|
|
1011
|
+
uid = await client.findByMessageId(item.fromFolder, item.messageId);
|
|
1012
|
+
const flags = uid === null ? undefined : (await client.fetchFlags(item.fromFolder, [uid]))[0]?.flags;
|
|
1013
|
+
if (!flags) {
|
|
1014
|
+
item.status = 'unknown';
|
|
1015
|
+
}
|
|
1016
|
+
else if (flags.includes(SEEN) === (item.wantSeen ?? action.kind === 'mark-read')) {
|
|
1017
|
+
item.status = 'done';
|
|
1018
|
+
if (target)
|
|
1019
|
+
await setSeenLocally(db, [target.id], flags.includes(SEEN));
|
|
1020
|
+
}
|
|
1021
|
+
else {
|
|
1022
|
+
item.status = 'dropped';
|
|
1023
|
+
dropped += 1;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
const kept = items.filter((i) => statusOf(i) !== 'dropped');
|
|
1027
|
+
const done = kept.filter((i) => statusOf(i) === 'done');
|
|
1028
|
+
const unknown = kept.filter((i) => statusOf(i) === 'unknown');
|
|
1029
|
+
if (done.length === 0 && unknown.length === 0) {
|
|
1030
|
+
await db.query(`delete from email.mailbox_actions where id = $1`, [action.id]);
|
|
1031
|
+
}
|
|
1032
|
+
else {
|
|
1033
|
+
const state = unknown.length > 0 ? 'unknown' : dropped > 0 ? 'partial' : 'done';
|
|
1034
|
+
const note = `buddi stopped while making this change; checked with the server afterwards: ${plural(done.length, 'message')} changed` +
|
|
1035
|
+
(dropped > 0 ? `, ${dropped} not` : '') +
|
|
1036
|
+
(unknown.length > 0 ? `, ${unknown.length} could not be confirmed (not found where it was or where it was going)` : '') +
|
|
1037
|
+
'.';
|
|
1038
|
+
await db.query(`update email.mailbox_actions set state = $2, note = $3, items = $4::jsonb, message_ids = $5::uuid[], changed = $6 where id = $1`, [action.id, state, note, JSON.stringify(kept), kept.map((i) => i.id), done.length]);
|
|
1039
|
+
if (action.kind === 'undo' && action.reverts) {
|
|
1040
|
+
const original = await findAction(db, action.reverts);
|
|
1041
|
+
if (original)
|
|
1042
|
+
await markReverted(db, original, done.map((i) => i.id), false, null, input.now);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
settled += 1;
|
|
1046
|
+
}
|
|
1047
|
+
return { settled };
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* A Gmail label move (or its undo) a stopped process left between its two
|
|
1051
|
+
* commands, finished from what the server says (X-GM-LABELS):
|
|
1052
|
+
*
|
|
1053
|
+
* - a move (Inbox → label): still in the inbox but already carrying the
|
|
1054
|
+
* label it did not have before — Inbox comes off;
|
|
1055
|
+
* - an undo (label → Inbox): already back in the inbox but still carrying
|
|
1056
|
+
* the label it was moved to — the label comes off, unless the message
|
|
1057
|
+
* had it before the original move.
|
|
1058
|
+
*
|
|
1059
|
+
* Anything else is left for the ordinary check (never happened, happened,
|
|
1060
|
+
* or unknown). A message the owner touched since cannot be told apart, so
|
|
1061
|
+
* only the exact half-done shape is finished.
|
|
1062
|
+
*/
|
|
1063
|
+
async function finishLabelMove(db, client, action, item) {
|
|
1064
|
+
const toInbox = item.toFolder.toUpperCase() === INBOX;
|
|
1065
|
+
const uid = await client.findByMessageId(INBOX, item.messageId);
|
|
1066
|
+
if (uid === null)
|
|
1067
|
+
return;
|
|
1068
|
+
const labels = plainLabels((await client.fetchLabels(INBOX, [uid])).get(uid));
|
|
1069
|
+
if (!toInbox) {
|
|
1070
|
+
const before = plainLabels(item.prevLabels);
|
|
1071
|
+
if (labels.includes(item.toFolder) && !before.includes(item.toFolder)) {
|
|
1072
|
+
await client.storeLabels(INBOX, [uid], [GMAIL_INBOX_LABEL], 'remove');
|
|
1073
|
+
}
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
if (!labels.includes(item.fromFolder))
|
|
1077
|
+
return;
|
|
1078
|
+
const original = action.reverts ? await findAction(db, action.reverts) : null;
|
|
1079
|
+
const before = original?.items.find((i) => i.id === item.id)?.prevLabels;
|
|
1080
|
+
if (before === undefined || plainLabels(before).includes(item.fromFolder))
|
|
1081
|
+
return;
|
|
1082
|
+
await client.storeLabels(INBOX, [uid], [item.fromFolder], 'remove');
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* The poll's half of intent-first: when this account has `pending` trail rows
|
|
1086
|
+
* no change in this process is writing, open a writer and settle them
|
|
1087
|
+
* (`reconcileTrail`). One cheap query when there are none.
|
|
1088
|
+
*/
|
|
1089
|
+
export async function reconcilePendingChanges(ctx, account, opts) {
|
|
1090
|
+
const db = ctx.buddi.db;
|
|
1091
|
+
const { rows } = await db.query(`select 1 from email.mailbox_actions
|
|
1092
|
+
where account_id = $1 and state = 'pending' and not (id = any($2::uuid[])) limit 1`, [account.id, trailInFlight()]);
|
|
1093
|
+
if (rows.length === 0)
|
|
1094
|
+
return 0;
|
|
1095
|
+
const { settled } = await withWriter(ctx, account, opts, (client) => reconcileTrail(db, client, { account, now: ctx.buddi.clock.now() }));
|
|
1096
|
+
return settled;
|
|
1097
|
+
}
|
|
1098
|
+
/** The newest changes, for the Mail page's Recent changes. */
|
|
1099
|
+
export async function recentActions(db, accountIds, limit = 20) {
|
|
1100
|
+
const { rows } = await db.query(`select ${ACTION_COLUMNS} from email.mailbox_actions
|
|
1101
|
+
where account_id = any($1::uuid[])
|
|
1102
|
+
order by created_at desc, seq desc limit $2`, [accountIds, limit]);
|
|
1103
|
+
return rows.map(toAction);
|
|
1104
|
+
}
|
|
1105
|
+
//# sourceMappingURL=actions.js.map
|