@withbuddi/buddi 0.1.0-pre.28 → 0.1.0-pre.30
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 +19 -3
- package/node_modules/@buddi/cli/dist/args.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/args.js +19 -5
- package/node_modules/@buddi/cli/dist/args.js.map +1 -1
- package/node_modules/@buddi/cli/dist/commands.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/commands.js +80 -8
- 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 +11 -4
- package/node_modules/@buddi/cli/dist/doctor-probes.js.map +1 -1
- package/node_modules/@buddi/cli/dist/doctor.d.ts +1 -1
- package/node_modules/@buddi/cli/dist/doctor.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/jobs-cmd.d.ts +4 -0
- package/node_modules/@buddi/cli/dist/jobs-cmd.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/jobs-cmd.js +53 -4
- package/node_modules/@buddi/cli/dist/jobs-cmd.js.map +1 -1
- package/node_modules/@buddi/cli/dist/main.d.ts.map +1 -1
- package/node_modules/@buddi/cli/dist/main.js +27 -2
- 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 +20 -1
- 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.map +1 -1
- package/node_modules/@buddi/core/dist/agents/catalog.js +7 -6
- package/node_modules/@buddi/core/dist/agents/catalog.js.map +1 -1
- package/node_modules/@buddi/core/dist/agents/frontmatter.d.ts +12 -12
- package/node_modules/@buddi/core/dist/agents/skills.d.ts +2 -2
- 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 +23 -2
- package/node_modules/@buddi/core/dist/feedback/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/feedback/index.js +23 -3
- package/node_modules/@buddi/core/dist/feedback/index.js.map +1 -1
- 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 +122 -2
- package/node_modules/@buddi/core/dist/host/build.js.map +1 -1
- package/node_modules/@buddi/core/dist/host/types.d.ts +33 -0
- package/node_modules/@buddi/core/dist/host/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/index.d.ts +8 -0
- package/node_modules/@buddi/core/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/index.js +8 -0
- package/node_modules/@buddi/core/dist/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/lock.d.ts +82 -0
- package/node_modules/@buddi/core/dist/lock.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/lock.js +182 -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/pages.d.ts +13 -39
- package/node_modules/@buddi/core/dist/pages.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/pages.js +12 -1
- 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 +9 -2
- 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/failures.d.ts +84 -0
- package/node_modules/@buddi/core/dist/queue/failures.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/queue/failures.js +195 -0
- package/node_modules/@buddi/core/dist/queue/failures.js.map +1 -0
- package/node_modules/@buddi/core/dist/queue/index.d.ts +1 -0
- package/node_modules/@buddi/core/dist/queue/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/queue/index.js +1 -0
- package/node_modules/@buddi/core/dist/queue/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/queue/jobs.d.ts +39 -3
- package/node_modules/@buddi/core/dist/queue/jobs.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/queue/jobs.js +54 -4
- package/node_modules/@buddi/core/dist/queue/jobs.js.map +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/queue/types.d.ts +20 -0
- package/node_modules/@buddi/core/dist/queue/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/queue/types.js +17 -0
- package/node_modules/@buddi/core/dist/queue/types.js.map +1 -1
- package/node_modules/@buddi/core/dist/registry.d.ts +37 -2
- package/node_modules/@buddi/core/dist/registry.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/registry.js +137 -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/secrets/settings.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/secrets/settings.js +23 -3
- package/node_modules/@buddi/core/dist/secrets/settings.js.map +1 -1
- 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/digest.d.ts +8 -1
- package/node_modules/@buddi/core/dist/sentinels/digest.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/digest.js +10 -3
- package/node_modules/@buddi/core/dist/sentinels/digest.js.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/index.d.ts +1 -0
- package/node_modules/@buddi/core/dist/sentinels/index.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/index.js +1 -0
- package/node_modules/@buddi/core/dist/sentinels/index.js.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/mutes.d.ts +51 -0
- package/node_modules/@buddi/core/dist/sentinels/mutes.d.ts.map +1 -0
- package/node_modules/@buddi/core/dist/sentinels/mutes.js +86 -0
- package/node_modules/@buddi/core/dist/sentinels/mutes.js.map +1 -0
- package/node_modules/@buddi/core/dist/sentinels/run.d.ts +20 -5
- package/node_modules/@buddi/core/dist/sentinels/run.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/run.js +105 -42
- package/node_modules/@buddi/core/dist/sentinels/run.js.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/types.d.ts +165 -2
- package/node_modules/@buddi/core/dist/sentinels/types.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/sentinels/types.js +126 -2
- package/node_modules/@buddi/core/dist/sentinels/types.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 +3 -0
- package/node_modules/@buddi/core/dist/sources/watch.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/sources/watch.js +1 -1
- package/node_modules/@buddi/core/dist/sources/watch.js.map +1 -1
- 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 +30 -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 +164 -164
- package/node_modules/@buddi/core/dist/views.d.ts.map +1 -1
- package/node_modules/@buddi/core/dist/views.js +5 -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/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/core/migrations/066_alert_decisions.sql +45 -0
- package/node_modules/@buddi/core/migrations/067_job_acknowledged.sql +21 -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 +4 -0
- package/node_modules/@buddi/gateway/dist/agents/learning-digest.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/agents/learning-digest.js +18 -5
- 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.d.ts +24 -24
- 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/conversations.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/chat/conversations.js +8 -2
- package/node_modules/@buddi/gateway/dist/chat/conversations.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 +11 -1
- 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/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 +49 -9
- package/node_modules/@buddi/gateway/dist/missions/execute.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/goals.d.ts +12 -1
- package/node_modules/@buddi/gateway/dist/missions/goals.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/missions/goals.js +21 -1
- package/node_modules/@buddi/gateway/dist/missions/goals.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 +14 -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 +41 -2
- 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/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/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 +6 -0
- package/node_modules/@buddi/gateway/dist/plugins/stage.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins/stage.js +6 -1
- 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 +1 -1
- package/node_modules/@buddi/gateway/dist/plugins-cli.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/plugins-cli.js +6 -2
- 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 +66 -8
- package/node_modules/@buddi/gateway/dist/serve.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/surfaces/offered-actions.d.ts +17 -0
- package/node_modules/@buddi/gateway/dist/surfaces/offered-actions.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/surfaces/offered-actions.js +27 -0
- package/node_modules/@buddi/gateway/dist/surfaces/offered-actions.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/main.js +3 -3
- package/node_modules/@buddi/gateway/dist/telegram/main.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/outbound.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/outbound.js +7 -2
- package/node_modules/@buddi/gateway/dist/telegram/outbound.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/reactions.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/reactions.js +12 -2
- package/node_modules/@buddi/gateway/dist/telegram/reactions.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts +4 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/telegram/surface.js +13 -3
- 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/alerts.d.ts +179 -0
- package/node_modules/@buddi/gateway/dist/web/alerts.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/alerts.js +363 -0
- package/node_modules/@buddi/gateway/dist/web/alerts.js.map +1 -0
- 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 +1239 -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 +1 -0
- package/node_modules/@buddi/gateway/dist/web/chat.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/chat.js +4 -3
- 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 +165 -0
- package/node_modules/@buddi/gateway/dist/web/lock.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/lock.js +478 -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 +28 -0
- package/node_modules/@buddi/gateway/dist/web/plugins.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/plugins.js +83 -9
- package/node_modules/@buddi/gateway/dist/web/plugins.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/read.d.ts +52 -26
- package/node_modules/@buddi/gateway/dist/web/read.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/read.js +52 -36
- package/node_modules/@buddi/gateway/dist/web/read.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/secrets.d.ts +61 -1
- package/node_modules/@buddi/gateway/dist/web/secrets.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/secrets.js +111 -3
- package/node_modules/@buddi/gateway/dist/web/secrets.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 +531 -46
- package/node_modules/@buddi/gateway/dist/web/server.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/sessions.d.ts +43 -2
- package/node_modules/@buddi/gateway/dist/web/sessions.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/sessions.js +67 -3
- package/node_modules/@buddi/gateway/dist/web/sessions.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts +17 -18
- package/node_modules/@buddi/gateway/dist/web/signed-out.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/signed-out.js +135 -33
- package/node_modules/@buddi/gateway/dist/web/signed-out.js.map +1 -1
- 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 +33 -4
- package/node_modules/@buddi/gateway/dist/web/tailscale.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/tailscale.js +76 -16
- package/node_modules/@buddi/gateway/dist/web/tailscale.js.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/widgets.d.ts +131 -0
- package/node_modules/@buddi/gateway/dist/web/widgets.d.ts.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/widgets.js +478 -0
- package/node_modules/@buddi/gateway/dist/web/widgets.js.map +1 -0
- package/node_modules/@buddi/gateway/dist/web/write.d.ts +23 -0
- package/node_modules/@buddi/gateway/dist/web/write.d.ts.map +1 -1
- package/node_modules/@buddi/gateway/dist/web/write.js +46 -1
- package/node_modules/@buddi/gateway/dist/web/write.js.map +1 -1
- package/node_modules/@buddi/install/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/runtime/dist/.tsbuildinfo +1 -1
- package/node_modules/@buddi/runtime/dist/anthropic.d.ts +15 -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 +34 -1
- package/node_modules/@buddi/runtime/dist/openai.d.ts.map +1 -1
- package/node_modules/@buddi/runtime/dist/openai.js +85 -19
- 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.js +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 +55 -0
- package/node_modules/@buddi/tool-email/dist/imap/fake.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/imap/fake.js +163 -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 +8 -0
- package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.js +124 -4
- package/node_modules/@buddi/tool-email/dist/imap/imapflow-client.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/index.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/index.js +3 -0
- package/node_modules/@buddi/tool-email/dist/index.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mail.d.ts +48 -0
- package/node_modules/@buddi/tool-email/dist/mail.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mail.js +119 -0
- package/node_modules/@buddi/tool-email/dist/mail.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mailbox/actions.d.ts +90 -5
- package/node_modules/@buddi/tool-email/dist/mailbox/actions.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mailbox/actions.js +643 -200
- package/node_modules/@buddi/tool-email/dist/mailbox/actions.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mailbox/select.d.ts +6 -0
- package/node_modules/@buddi/tool-email/dist/mailbox/select.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/mailbox/select.js +20 -2
- package/node_modules/@buddi/tool-email/dist/mailbox/select.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/metrics.d.ts +8 -9
- package/node_modules/@buddi/tool-email/dist/metrics.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/metrics.js +8 -9
- package/node_modules/@buddi/tool-email/dist/metrics.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/needs-you.d.ts +58 -0
- package/node_modules/@buddi/tool-email/dist/needs-you.d.ts.map +1 -0
- package/node_modules/@buddi/tool-email/dist/needs-you.js +97 -0
- package/node_modules/@buddi/tool-email/dist/needs-you.js.map +1 -0
- package/node_modules/@buddi/tool-email/dist/pages/descriptors.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/pages/descriptors.js +126 -80
- 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/queries.d.ts +14 -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 +65 -7
- package/node_modules/@buddi/tool-email/dist/pages/queries.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/policies/auto.d.ts +9 -9
- package/node_modules/@buddi/tool-email/dist/policies/auto.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/policies/auto.js +79 -24
- package/node_modules/@buddi/tool-email/dist/policies/auto.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/ports.d.ts +55 -0
- package/node_modules/@buddi/tool-email/dist/ports.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/ports.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sentinels/suspicious-sender.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sentinels/suspicious-sender.js +4 -1
- package/node_modules/@buddi/tool-email/dist/sentinels/suspicious-sender.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sentinels/waiting-on-me.d.ts +19 -22
- 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 +44 -63
- 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 +10 -2
- package/node_modules/@buddi/tool-email/dist/sources/idle.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sources/idle.js +70 -3
- package/node_modules/@buddi/tool-email/dist/sources/idle.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/sources/inbox-poll.d.ts +69 -2
- 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 +143 -13
- 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/suspicions-store.d.ts +6 -0
- package/node_modules/@buddi/tool-email/dist/suspicions-store.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/suspicions-store.js +16 -1
- package/node_modules/@buddi/tool-email/dist/suspicions-store.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/threads.d.ts +19 -2
- package/node_modules/@buddi/tool-email/dist/threads.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/threads.js +47 -17
- package/node_modules/@buddi/tool-email/dist/threads.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/tools/mailbox.d.ts +3 -0
- package/node_modules/@buddi/tool-email/dist/tools/mailbox.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/tools/mailbox.js +9 -4
- package/node_modules/@buddi/tool-email/dist/tools/mailbox.js.map +1 -1
- 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 +7 -3
- package/node_modules/@buddi/tool-email/dist/tools/threads.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/tools/threads.js +18 -5
- package/node_modules/@buddi/tool-email/dist/tools/threads.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/watchers.d.ts +91 -7
- package/node_modules/@buddi/tool-email/dist/watchers.d.ts.map +1 -1
- package/node_modules/@buddi/tool-email/dist/watchers.js +164 -1
- package/node_modules/@buddi/tool-email/dist/watchers.js.map +1 -1
- package/node_modules/@buddi/tool-email/dist/widgets.d.ts +14 -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/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/migrations/023_attention.sql +100 -0
- package/node_modules/@buddi/tool-email/migrations/024_auth_domain.sql +9 -0
- package/node_modules/@buddi/tool-email/migrations/025_thread_ignore.sql +77 -0
- package/node_modules/@buddi/tool-email/package.json +1 -1
- 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/ip-address/README.md +34 -34
- package/node_modules/ip-address/dist/ipv4.js +7 -0
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/package.json +1 -1
- package/package.json +2 -2
- package/packages/cli/dist/.tsbuildinfo +1 -1
- package/packages/cli/dist/args.d.ts +19 -3
- package/packages/cli/dist/args.d.ts.map +1 -1
- package/packages/cli/dist/args.js +19 -5
- package/packages/cli/dist/args.js.map +1 -1
- package/packages/cli/dist/commands.d.ts.map +1 -1
- package/packages/cli/dist/commands.js +80 -8
- 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 +11 -4
- package/packages/cli/dist/doctor-probes.js.map +1 -1
- package/packages/cli/dist/doctor.d.ts +1 -1
- package/packages/cli/dist/doctor.d.ts.map +1 -1
- package/packages/cli/dist/jobs-cmd.d.ts +4 -0
- package/packages/cli/dist/jobs-cmd.d.ts.map +1 -1
- package/packages/cli/dist/jobs-cmd.js +53 -4
- package/packages/cli/dist/jobs-cmd.js.map +1 -1
- package/packages/cli/dist/main.d.ts.map +1 -1
- package/packages/cli/dist/main.js +27 -2
- 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 +20 -1
- 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.map +1 -1
- package/packages/core/dist/agents/catalog.js +7 -6
- package/packages/core/dist/agents/catalog.js.map +1 -1
- package/packages/core/dist/agents/frontmatter.d.ts +12 -12
- package/packages/core/dist/agents/skills.d.ts +2 -2
- 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 +23 -2
- package/packages/core/dist/feedback/index.d.ts.map +1 -1
- package/packages/core/dist/feedback/index.js +23 -3
- package/packages/core/dist/feedback/index.js.map +1 -1
- 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 +122 -2
- package/packages/core/dist/host/build.js.map +1 -1
- package/packages/core/dist/host/types.d.ts +33 -0
- package/packages/core/dist/host/types.d.ts.map +1 -1
- package/packages/core/dist/index.d.ts +8 -0
- package/packages/core/dist/index.d.ts.map +1 -1
- package/packages/core/dist/index.js +8 -0
- package/packages/core/dist/index.js.map +1 -1
- package/packages/core/dist/lock.d.ts +82 -0
- package/packages/core/dist/lock.d.ts.map +1 -0
- package/packages/core/dist/lock.js +182 -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/pages.d.ts +13 -39
- package/packages/core/dist/pages.d.ts.map +1 -1
- package/packages/core/dist/pages.js +12 -1
- 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 +9 -2
- 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/failures.d.ts +84 -0
- package/packages/core/dist/queue/failures.d.ts.map +1 -0
- package/packages/core/dist/queue/failures.js +195 -0
- package/packages/core/dist/queue/failures.js.map +1 -0
- package/packages/core/dist/queue/index.d.ts +1 -0
- package/packages/core/dist/queue/index.d.ts.map +1 -1
- package/packages/core/dist/queue/index.js +1 -0
- package/packages/core/dist/queue/index.js.map +1 -1
- package/packages/core/dist/queue/jobs.d.ts +39 -3
- package/packages/core/dist/queue/jobs.d.ts.map +1 -1
- package/packages/core/dist/queue/jobs.js +54 -4
- package/packages/core/dist/queue/jobs.js.map +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/queue/types.d.ts +20 -0
- package/packages/core/dist/queue/types.d.ts.map +1 -1
- package/packages/core/dist/queue/types.js +17 -0
- package/packages/core/dist/queue/types.js.map +1 -1
- package/packages/core/dist/registry.d.ts +37 -2
- package/packages/core/dist/registry.d.ts.map +1 -1
- package/packages/core/dist/registry.js +137 -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/secrets/settings.d.ts.map +1 -1
- package/packages/core/dist/secrets/settings.js +23 -3
- package/packages/core/dist/secrets/settings.js.map +1 -1
- 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/digest.d.ts +8 -1
- package/packages/core/dist/sentinels/digest.d.ts.map +1 -1
- package/packages/core/dist/sentinels/digest.js +10 -3
- package/packages/core/dist/sentinels/digest.js.map +1 -1
- package/packages/core/dist/sentinels/index.d.ts +1 -0
- package/packages/core/dist/sentinels/index.d.ts.map +1 -1
- package/packages/core/dist/sentinels/index.js +1 -0
- package/packages/core/dist/sentinels/index.js.map +1 -1
- package/packages/core/dist/sentinels/mutes.d.ts +51 -0
- package/packages/core/dist/sentinels/mutes.d.ts.map +1 -0
- package/packages/core/dist/sentinels/mutes.js +86 -0
- package/packages/core/dist/sentinels/mutes.js.map +1 -0
- package/packages/core/dist/sentinels/run.d.ts +20 -5
- package/packages/core/dist/sentinels/run.d.ts.map +1 -1
- package/packages/core/dist/sentinels/run.js +105 -42
- package/packages/core/dist/sentinels/run.js.map +1 -1
- package/packages/core/dist/sentinels/types.d.ts +165 -2
- package/packages/core/dist/sentinels/types.d.ts.map +1 -1
- package/packages/core/dist/sentinels/types.js +126 -2
- package/packages/core/dist/sentinels/types.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 +3 -0
- package/packages/core/dist/sources/watch.d.ts.map +1 -1
- package/packages/core/dist/sources/watch.js +1 -1
- package/packages/core/dist/sources/watch.js.map +1 -1
- 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 +30 -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 +164 -164
- package/packages/core/dist/views.d.ts.map +1 -1
- package/packages/core/dist/views.js +5 -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/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/core/migrations/066_alert_decisions.sql +45 -0
- package/packages/core/migrations/067_job_acknowledged.sql +21 -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 +4 -0
- package/packages/gateway/dist/agents/learning-digest.d.ts.map +1 -1
- package/packages/gateway/dist/agents/learning-digest.js +18 -5
- 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.d.ts +24 -24
- 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/conversations.d.ts.map +1 -1
- package/packages/gateway/dist/chat/conversations.js +8 -2
- package/packages/gateway/dist/chat/conversations.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 +11 -1
- 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/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 +49 -9
- package/packages/gateway/dist/missions/execute.js.map +1 -1
- package/packages/gateway/dist/missions/goals.d.ts +12 -1
- package/packages/gateway/dist/missions/goals.d.ts.map +1 -1
- package/packages/gateway/dist/missions/goals.js +21 -1
- package/packages/gateway/dist/missions/goals.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 +14 -0
- package/packages/gateway/dist/missions/sentinel-wake.d.ts.map +1 -1
- package/packages/gateway/dist/missions/sentinel-wake.js +41 -2
- 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/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/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 +6 -0
- package/packages/gateway/dist/plugins/stage.d.ts.map +1 -1
- package/packages/gateway/dist/plugins/stage.js +6 -1
- 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 +1 -1
- package/packages/gateway/dist/plugins-cli.d.ts.map +1 -1
- package/packages/gateway/dist/plugins-cli.js +6 -2
- 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 +66 -8
- package/packages/gateway/dist/serve.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/surfaces/offered-actions.d.ts +17 -0
- package/packages/gateway/dist/surfaces/offered-actions.d.ts.map +1 -1
- package/packages/gateway/dist/surfaces/offered-actions.js +27 -0
- package/packages/gateway/dist/surfaces/offered-actions.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/main.js +3 -3
- package/packages/gateway/dist/telegram/main.js.map +1 -1
- package/packages/gateway/dist/telegram/outbound.d.ts +1 -1
- package/packages/gateway/dist/telegram/outbound.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/outbound.js +7 -2
- package/packages/gateway/dist/telegram/outbound.js.map +1 -1
- package/packages/gateway/dist/telegram/reactions.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/reactions.js +12 -2
- package/packages/gateway/dist/telegram/reactions.js.map +1 -1
- package/packages/gateway/dist/telegram/surface.d.ts +4 -1
- package/packages/gateway/dist/telegram/surface.d.ts.map +1 -1
- package/packages/gateway/dist/telegram/surface.js +13 -3
- 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/alerts.d.ts +179 -0
- package/packages/gateway/dist/web/alerts.d.ts.map +1 -0
- package/packages/gateway/dist/web/alerts.js +363 -0
- package/packages/gateway/dist/web/alerts.js.map +1 -0
- 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 +1239 -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 +1 -0
- package/packages/gateway/dist/web/chat.d.ts.map +1 -1
- package/packages/gateway/dist/web/chat.js +4 -3
- 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 +165 -0
- package/packages/gateway/dist/web/lock.d.ts.map +1 -0
- package/packages/gateway/dist/web/lock.js +478 -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 +28 -0
- package/packages/gateway/dist/web/plugins.d.ts.map +1 -1
- package/packages/gateway/dist/web/plugins.js +83 -9
- package/packages/gateway/dist/web/plugins.js.map +1 -1
- package/packages/gateway/dist/web/read.d.ts +52 -26
- package/packages/gateway/dist/web/read.d.ts.map +1 -1
- package/packages/gateway/dist/web/read.js +52 -36
- package/packages/gateway/dist/web/read.js.map +1 -1
- package/packages/gateway/dist/web/secrets.d.ts +61 -1
- package/packages/gateway/dist/web/secrets.d.ts.map +1 -1
- package/packages/gateway/dist/web/secrets.js +111 -3
- package/packages/gateway/dist/web/secrets.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 +531 -46
- package/packages/gateway/dist/web/server.js.map +1 -1
- package/packages/gateway/dist/web/sessions.d.ts +43 -2
- package/packages/gateway/dist/web/sessions.d.ts.map +1 -1
- package/packages/gateway/dist/web/sessions.js +67 -3
- package/packages/gateway/dist/web/sessions.js.map +1 -1
- package/packages/gateway/dist/web/signed-out.d.ts +17 -18
- package/packages/gateway/dist/web/signed-out.d.ts.map +1 -1
- package/packages/gateway/dist/web/signed-out.js +135 -33
- package/packages/gateway/dist/web/signed-out.js.map +1 -1
- 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 +33 -4
- package/packages/gateway/dist/web/tailscale.d.ts.map +1 -1
- package/packages/gateway/dist/web/tailscale.js +76 -16
- package/packages/gateway/dist/web/tailscale.js.map +1 -1
- package/packages/gateway/dist/web/widgets.d.ts +131 -0
- package/packages/gateway/dist/web/widgets.d.ts.map +1 -0
- package/packages/gateway/dist/web/widgets.js +478 -0
- package/packages/gateway/dist/web/widgets.js.map +1 -0
- package/packages/gateway/dist/web/write.d.ts +23 -0
- package/packages/gateway/dist/web/write.d.ts.map +1 -1
- package/packages/gateway/dist/web/write.js +46 -1
- package/packages/gateway/dist/web/write.js.map +1 -1
- package/packages/install/dist/.tsbuildinfo +1 -1
- package/packages/runtime/dist/.tsbuildinfo +1 -1
- package/packages/runtime/dist/anthropic.d.ts +15 -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 +34 -1
- package/packages/runtime/dist/openai.d.ts.map +1 -1
- package/packages/runtime/dist/openai.js +85 -19
- 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.js +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 +55 -0
- package/packages/tools/email/dist/imap/fake.d.ts.map +1 -1
- package/packages/tools/email/dist/imap/fake.js +163 -4
- package/packages/tools/email/dist/imap/fake.js.map +1 -1
- package/packages/tools/email/dist/imap/imapflow-client.d.ts +8 -0
- package/packages/tools/email/dist/imap/imapflow-client.d.ts.map +1 -1
- package/packages/tools/email/dist/imap/imapflow-client.js +124 -4
- package/packages/tools/email/dist/imap/imapflow-client.js.map +1 -1
- package/packages/tools/email/dist/index.d.ts.map +1 -1
- package/packages/tools/email/dist/index.js +3 -0
- package/packages/tools/email/dist/index.js.map +1 -1
- package/packages/tools/email/dist/mail.d.ts +48 -0
- package/packages/tools/email/dist/mail.d.ts.map +1 -1
- package/packages/tools/email/dist/mail.js +119 -0
- package/packages/tools/email/dist/mail.js.map +1 -1
- package/packages/tools/email/dist/mailbox/actions.d.ts +90 -5
- package/packages/tools/email/dist/mailbox/actions.d.ts.map +1 -1
- package/packages/tools/email/dist/mailbox/actions.js +643 -200
- package/packages/tools/email/dist/mailbox/actions.js.map +1 -1
- package/packages/tools/email/dist/mailbox/select.d.ts +6 -0
- package/packages/tools/email/dist/mailbox/select.d.ts.map +1 -1
- package/packages/tools/email/dist/mailbox/select.js +20 -2
- package/packages/tools/email/dist/mailbox/select.js.map +1 -1
- package/packages/tools/email/dist/metrics.d.ts +8 -9
- package/packages/tools/email/dist/metrics.d.ts.map +1 -1
- package/packages/tools/email/dist/metrics.js +8 -9
- package/packages/tools/email/dist/metrics.js.map +1 -1
- package/packages/tools/email/dist/needs-you.d.ts +58 -0
- package/packages/tools/email/dist/needs-you.d.ts.map +1 -0
- package/packages/tools/email/dist/needs-you.js +97 -0
- package/packages/tools/email/dist/needs-you.js.map +1 -0
- package/packages/tools/email/dist/pages/descriptors.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/descriptors.js +126 -80
- 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/queries.d.ts +14 -0
- package/packages/tools/email/dist/pages/queries.d.ts.map +1 -1
- package/packages/tools/email/dist/pages/queries.js +65 -7
- package/packages/tools/email/dist/pages/queries.js.map +1 -1
- package/packages/tools/email/dist/policies/auto.d.ts +9 -9
- package/packages/tools/email/dist/policies/auto.d.ts.map +1 -1
- package/packages/tools/email/dist/policies/auto.js +79 -24
- package/packages/tools/email/dist/policies/auto.js.map +1 -1
- package/packages/tools/email/dist/ports.d.ts +55 -0
- package/packages/tools/email/dist/ports.d.ts.map +1 -1
- package/packages/tools/email/dist/ports.js.map +1 -1
- package/packages/tools/email/dist/sentinels/suspicious-sender.d.ts.map +1 -1
- package/packages/tools/email/dist/sentinels/suspicious-sender.js +4 -1
- package/packages/tools/email/dist/sentinels/suspicious-sender.js.map +1 -1
- package/packages/tools/email/dist/sentinels/waiting-on-me.d.ts +19 -22
- package/packages/tools/email/dist/sentinels/waiting-on-me.d.ts.map +1 -1
- package/packages/tools/email/dist/sentinels/waiting-on-me.js +44 -63
- package/packages/tools/email/dist/sentinels/waiting-on-me.js.map +1 -1
- package/packages/tools/email/dist/sources/idle.d.ts +10 -2
- package/packages/tools/email/dist/sources/idle.d.ts.map +1 -1
- package/packages/tools/email/dist/sources/idle.js +70 -3
- package/packages/tools/email/dist/sources/idle.js.map +1 -1
- package/packages/tools/email/dist/sources/inbox-poll.d.ts +69 -2
- package/packages/tools/email/dist/sources/inbox-poll.d.ts.map +1 -1
- package/packages/tools/email/dist/sources/inbox-poll.js +143 -13
- 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/suspicions-store.d.ts +6 -0
- package/packages/tools/email/dist/suspicions-store.d.ts.map +1 -1
- package/packages/tools/email/dist/suspicions-store.js +16 -1
- package/packages/tools/email/dist/suspicions-store.js.map +1 -1
- package/packages/tools/email/dist/threads.d.ts +19 -2
- package/packages/tools/email/dist/threads.d.ts.map +1 -1
- package/packages/tools/email/dist/threads.js +47 -17
- package/packages/tools/email/dist/threads.js.map +1 -1
- package/packages/tools/email/dist/tools/mailbox.d.ts +3 -0
- package/packages/tools/email/dist/tools/mailbox.d.ts.map +1 -1
- package/packages/tools/email/dist/tools/mailbox.js +9 -4
- package/packages/tools/email/dist/tools/mailbox.js.map +1 -1
- 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 +7 -3
- package/packages/tools/email/dist/tools/threads.d.ts.map +1 -1
- package/packages/tools/email/dist/tools/threads.js +18 -5
- package/packages/tools/email/dist/tools/threads.js.map +1 -1
- package/packages/tools/email/dist/watchers.d.ts +91 -7
- package/packages/tools/email/dist/watchers.d.ts.map +1 -1
- package/packages/tools/email/dist/watchers.js +164 -1
- package/packages/tools/email/dist/watchers.js.map +1 -1
- package/packages/tools/email/dist/widgets.d.ts +14 -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/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/migrations/023_attention.sql +100 -0
- package/packages/tools/email/migrations/024_auth_domain.sql +9 -0
- package/packages/tools/email/migrations/025_thread_ignore.sql +77 -0
- package/packages/tools/email/package.json +1 -1
- 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/earth-2560-Ce3xs8Cb.webp +0 -0
- package/packages/web/dist/assets/earth-phone-BqC7cDhk.webp +0 -0
- package/packages/web/dist/assets/index-WS4UjGsy.js +129 -0
- package/packages/web/dist/assets/index-Zrt_o2UG.css +1 -0
- package/packages/web/dist/assets/{lottie_light-CSeMXM8D.js → lottie_light-Ls7i1ATS.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/sw.js +3 -2
- package/packages/web/dist/assets/index-CKuhKCWw.js +0 -131
- package/packages/web/dist/assets/index-DsK8UWCJ.css +0 -1
|
@@ -12,7 +12,7 @@ export const MAILBOX_ACTION_KINDS = ['mark-read', 'mark-unread', 'archive', 'mov
|
|
|
12
12
|
export const SEEN = '\\Seen';
|
|
13
13
|
const GMAIL_CAPABILITY = 'X-GM-EXT-1';
|
|
14
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';
|
|
15
|
+
'items, changed, note, reverts, undone_at, undone_by, created_at, state, reverted_ids';
|
|
16
16
|
function iso(value) {
|
|
17
17
|
if (value === null || value === undefined)
|
|
18
18
|
return null;
|
|
@@ -38,6 +38,8 @@ export function toAction(row) {
|
|
|
38
38
|
undoneAt: iso(row.undone_at),
|
|
39
39
|
undoneBy: row.undone_by ? String(row.undone_by) : null,
|
|
40
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) : [],
|
|
41
43
|
};
|
|
42
44
|
}
|
|
43
45
|
/** A refusal whose message is the sentence the owner and the agent read. */
|
|
@@ -84,7 +86,7 @@ export async function loadTargets(db, ids) {
|
|
|
84
86
|
if (ids.length === 0)
|
|
85
87
|
return [];
|
|
86
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,
|
|
87
|
-
m.subject, m.from_addr, m.flags
|
|
89
|
+
m.subject, m.from_addr, m.flags, m.gone_at
|
|
88
90
|
from email.messages m join email.folders f on f.id = m.folder_id
|
|
89
91
|
where m.id = any($1::uuid[])`, [ids]);
|
|
90
92
|
const byId = new Map(rows.map((r) => [String(r.id), r]));
|
|
@@ -104,6 +106,7 @@ export async function loadTargets(db, ids) {
|
|
|
104
106
|
subject: r.subject ?? '',
|
|
105
107
|
from: r.from_addr ?? '',
|
|
106
108
|
flags: Array.isArray(r.flags) ? r.flags : [],
|
|
109
|
+
gone: r.gone_at !== null && r.gone_at !== undefined,
|
|
107
110
|
});
|
|
108
111
|
}
|
|
109
112
|
return out;
|
|
@@ -243,13 +246,25 @@ export function destinationFor(facts, kind, account, folder) {
|
|
|
243
246
|
/* ------------------------------------------------------------------ *
|
|
244
247
|
* Keeping buddi's rows in step
|
|
245
248
|
* ------------------------------------------------------------------ */
|
|
246
|
-
/**
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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]);
|
|
251
258
|
return String(rows[0].id);
|
|
252
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
|
+
}
|
|
253
268
|
let unknownCounter = 0;
|
|
254
269
|
/**
|
|
255
270
|
* A placeholder uid for a message whose new uid the server did not report and
|
|
@@ -261,21 +276,34 @@ function placeholderUid() {
|
|
|
261
276
|
unknownCounter = (unknownCounter + 1) % 1000;
|
|
262
277
|
return -(Date.now() * 1000 + unknownCounter);
|
|
263
278
|
}
|
|
264
|
-
/**
|
|
265
|
-
|
|
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;
|
|
266
290
|
if (uidValidity !== null && uid !== null) {
|
|
267
|
-
const result = await db.query(`update email.messages set folder_id = $2, uidvalidity = $3, uid = $4
|
|
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
|
|
268
293
|
where id = $1
|
|
269
294
|
and not exists (select 1 from email.messages o
|
|
270
|
-
where o.account_id = $5 and o.folder_id = $2 and o.uidvalidity = $3 and o.uid = $4
|
|
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]);
|
|
271
297
|
if ((result.rowCount ?? 0) > 0)
|
|
272
|
-
|
|
298
|
+
where = { uidValidity, uid };
|
|
273
299
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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]);
|
|
279
307
|
}
|
|
280
308
|
async function setSeenLocally(db, ids, seen) {
|
|
281
309
|
if (ids.length === 0)
|
|
@@ -285,6 +313,117 @@ async function setSeenLocally(db, ids, seen) {
|
|
|
285
313
|
where id = any($1::uuid[]) and not (flags @> '["\\\\Seen"]'::jsonb)`
|
|
286
314
|
: `update email.messages set flags = flags - '\\Seen' where id = any($1::uuid[])`, [ids]);
|
|
287
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
|
+
}
|
|
288
427
|
/**
|
|
289
428
|
* Find where each target is now, on the server: its folder's generation must
|
|
290
429
|
* match, and a row whose uid is unknown (UIDVALIDITY 0) is looked up by
|
|
@@ -345,34 +484,33 @@ async function landed(client, destination, moved, result) {
|
|
|
345
484
|
}
|
|
346
485
|
return { uidValidity, uids };
|
|
347
486
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
input.reverts ?? null,
|
|
369
|
-
input.now,
|
|
370
|
-
]);
|
|
371
|
-
return toAction(rows[0]);
|
|
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(', ');
|
|
372
507
|
}
|
|
373
508
|
/**
|
|
374
509
|
* Carry out one change on one account's server, keep the rows in step, and
|
|
375
|
-
* write it on the trail
|
|
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`).
|
|
376
514
|
*
|
|
377
515
|
* Messages no longer where buddi last saw them are skipped, never guessed at,
|
|
378
516
|
* and the note says how many. Nothing is recorded when nothing changed.
|
|
@@ -387,11 +525,26 @@ export async function performAction(db, client, input) {
|
|
|
387
525
|
if (n > 0)
|
|
388
526
|
reasons.set(why, (reasons.get(why) ?? 0) + n);
|
|
389
527
|
};
|
|
390
|
-
//
|
|
391
|
-
//
|
|
392
|
-
|
|
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);
|
|
393
546
|
try {
|
|
394
|
-
for (const [folder, group] of byFolder(
|
|
547
|
+
for (const [folder, group] of byFolder(live)) {
|
|
395
548
|
const here = await locate(client, folder, group);
|
|
396
549
|
skip(`no longer in ${folder}`, group.length - here.size);
|
|
397
550
|
const present = group.filter((t) => here.has(t.id));
|
|
@@ -403,16 +556,21 @@ export async function performAction(db, client, input) {
|
|
|
403
556
|
skip(seen ? 'already read' : 'already unread', present.length - change.length);
|
|
404
557
|
if (change.length === 0)
|
|
405
558
|
continue;
|
|
406
|
-
|
|
407
|
-
for (const t of change) {
|
|
559
|
+
const planned = change.map((t) => {
|
|
408
560
|
const at = here.get(t.id);
|
|
409
|
-
|
|
561
|
+
return {
|
|
410
562
|
id: t.id, subject: t.subject, from: t.from, messageId: t.messageId,
|
|
411
563
|
fromFolder: folder, fromUidValidity: t.uidValidity > 0 ? t.uidValidity : 0, fromUid: at.uid,
|
|
412
|
-
prevFlags: at.flags,
|
|
413
|
-
}
|
|
414
|
-
}
|
|
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';
|
|
415
572
|
await setSeenLocally(db, change.map((t) => t.id), seen);
|
|
573
|
+
await save();
|
|
416
574
|
continue;
|
|
417
575
|
}
|
|
418
576
|
// A move of some kind. Already there is not a change.
|
|
@@ -424,82 +582,77 @@ export async function performAction(db, client, input) {
|
|
|
424
582
|
}
|
|
425
583
|
if (movable.length === 0)
|
|
426
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);
|
|
427
592
|
const source = await client.open(folder);
|
|
428
|
-
const labels = facts.gmail && kind === 'trash'
|
|
593
|
+
const labels = facts.gmail && (kind === 'trash' || labelMove)
|
|
429
594
|
? await client.fetchLabels(folder, movable.map((t) => here.get(t.id).uid))
|
|
430
595
|
: new Map();
|
|
431
596
|
const moved = movable.map((t) => ({ target: t, uid: here.get(t.id).uid }));
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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));
|
|
448
625
|
let where;
|
|
449
626
|
try {
|
|
450
627
|
where = await landed(client, destination, moved, result);
|
|
451
628
|
}
|
|
452
629
|
catch (err) {
|
|
453
630
|
for (const m of moved)
|
|
454
|
-
await relocateRow(db, m.target, destId, null, null);
|
|
631
|
+
await relocateRow(db, m.target, destId, null, null, labelsAfter(m));
|
|
455
632
|
throw err;
|
|
456
633
|
}
|
|
457
634
|
for (const [i, m] of moved.entries()) {
|
|
458
635
|
const newUid = where.uids.get(m.target.id) ?? null;
|
|
459
|
-
await relocateRow(db, m.target, destId, newUid === null ? null : where.uidValidity, newUid);
|
|
636
|
+
await relocateRow(db, m.target, destId, newUid === null ? null : where.uidValidity, newUid, labelsAfter(m));
|
|
460
637
|
pushed[i].toUidValidity = where.uidValidity ?? 0;
|
|
461
638
|
pushed[i].toUid = newUid;
|
|
462
639
|
}
|
|
640
|
+
await save();
|
|
463
641
|
}
|
|
464
642
|
}
|
|
465
643
|
catch (err) {
|
|
466
|
-
|
|
467
|
-
const why = err instanceof Error ? err.message : String(err);
|
|
468
|
-
const skippedNote = [...reasons.entries()].map(([r, n]) => `${n} ${r}`).join(', ');
|
|
469
|
-
await recordAction(db, {
|
|
470
|
-
accountId: account.id,
|
|
471
|
-
kind,
|
|
472
|
-
destination,
|
|
473
|
-
provenance: input.provenance,
|
|
474
|
-
messageIds: items.map((i) => i.id),
|
|
475
|
-
items,
|
|
476
|
-
changed: items.length,
|
|
477
|
-
note: `Partial: stopped by an error after ${plural(items.length, 'message')}: ${why}.${skippedNote ? ` Skipped ${skippedNote}.` : ''}`,
|
|
478
|
-
now: input.now,
|
|
479
|
-
}).catch(() => { });
|
|
480
|
-
}
|
|
644
|
+
await finishTrail(db, trailId, items, { error: err, skippedNote: skippedWords(reasons) }).catch(() => { });
|
|
481
645
|
throw err;
|
|
482
646
|
}
|
|
483
647
|
const skipped = [...reasons.values()].reduce((a, b) => a + b, 0);
|
|
484
|
-
const skippedNote =
|
|
485
|
-
const
|
|
486
|
-
const
|
|
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
|
|
487
653
|
? `Nothing changed in ${account.address}${skippedNote ? ` (${skippedNote})` : ''}.`
|
|
488
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.'}`;
|
|
489
|
-
|
|
490
|
-
return { action: null, changed: 0, skipped, note };
|
|
491
|
-
const action = await recordAction(db, {
|
|
492
|
-
accountId: account.id,
|
|
493
|
-
kind,
|
|
494
|
-
destination,
|
|
495
|
-
provenance: input.provenance,
|
|
496
|
-
messageIds: items.map((i) => i.id),
|
|
497
|
-
items,
|
|
498
|
-
changed: items.length,
|
|
499
|
-
note: skippedNote ? `Skipped ${skippedNote}.` : null,
|
|
500
|
-
now: input.now,
|
|
501
|
-
});
|
|
502
|
-
return { action, changed: items.length, skipped, note };
|
|
655
|
+
return { action, changed, skipped, note };
|
|
503
656
|
}
|
|
504
657
|
/* ------------------------------------------------------------------ *
|
|
505
658
|
* Undo
|
|
@@ -512,38 +665,81 @@ export async function findAction(db, id) {
|
|
|
512
665
|
export async function lastUndoable(db, accountIds) {
|
|
513
666
|
const { rows } = await db.query(`select ${ACTION_COLUMNS} from email.mailbox_actions
|
|
514
667
|
where account_id = any($1::uuid[]) and kind <> 'undo' and undone_at is null
|
|
668
|
+
and state <> 'pending' and changed > 0
|
|
515
669
|
order by created_at desc, seq desc limit 1`, [accountIds]);
|
|
516
670
|
return rows[0] ? toAction(rows[0]) : null;
|
|
517
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
|
+
}
|
|
518
677
|
/** Why a change cannot be undone, or null when it can. */
|
|
519
678
|
export function undoRefusal(action) {
|
|
520
679
|
if (action.kind === 'undo')
|
|
521
680
|
return 'That was itself an undo; buddi does not undo an undo. Make the change again instead.';
|
|
522
681
|
if (action.undoneAt)
|
|
523
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.';
|
|
524
688
|
return null;
|
|
525
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
|
+
}
|
|
526
714
|
/** The sentence an undo's approval and the Recent changes row say. */
|
|
527
|
-
export function describeUndo(action, account) {
|
|
528
|
-
const
|
|
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
|
+
: '';
|
|
529
722
|
switch (action.kind) {
|
|
530
723
|
case 'mark-read':
|
|
531
|
-
return `Undo "${verbOf(action.kind)}" on ${n} in ${account}: they become unread again
|
|
724
|
+
return `Undo${rest} "${verbOf(action.kind)}" on ${n} in ${account}: they become unread again.${since}`;
|
|
532
725
|
case 'mark-unread':
|
|
533
|
-
return `Undo "${verbOf(action.kind)}" on ${n} in ${account}: they become read again
|
|
726
|
+
return `Undo${rest} "${verbOf(action.kind)}" on ${n} in ${account}: they become read again.${since}`;
|
|
534
727
|
case 'trash':
|
|
535
|
-
return `Undo "${verbOf(action.kind)}" on ${n} in ${account}: they move back from Trash to where they were (any already emptied from Trash cannot come back)
|
|
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}`;
|
|
536
729
|
default:
|
|
537
|
-
return `Undo "${verbOf(action.kind, action.destination)}" on ${n} in ${account}: they move back to where they were
|
|
730
|
+
return `Undo${rest} "${verbOf(action.kind, action.destination)}" on ${n} in ${account}: they move back to where they were.${since}`;
|
|
538
731
|
}
|
|
539
732
|
}
|
|
540
733
|
/**
|
|
541
734
|
* Put one change back, as far as the mailbox still allows, and record the
|
|
542
|
-
* undo as a change of its own
|
|
735
|
+
* undo as a change of its own — intent first, like `performAction`.
|
|
543
736
|
*
|
|
544
737
|
* Each message is acted on where buddi's row says it is now — the row
|
|
545
|
-
* followed it — and only if
|
|
546
|
-
*
|
|
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.
|
|
547
743
|
*/
|
|
548
744
|
export async function undoAction(db, client, input) {
|
|
549
745
|
const { account, action } = input;
|
|
@@ -551,106 +747,353 @@ export async function undoAction(db, client, input) {
|
|
|
551
747
|
if (refusal)
|
|
552
748
|
throw new MailboxRefusal(refusal);
|
|
553
749
|
const facts = await serverFacts(client);
|
|
554
|
-
const
|
|
555
|
-
const
|
|
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]));
|
|
556
753
|
const items = [];
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
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;
|
|
574
816
|
}
|
|
817
|
+
// Moves: back to each message's own original folder.
|
|
818
|
+
const back = new Map();
|
|
575
819
|
for (const t of present) {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
}
|
|
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);
|
|
581
828
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
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
|
+
}
|
|
591
877
|
}
|
|
592
|
-
const list = back.get(original) ?? [];
|
|
593
|
-
list.push(t);
|
|
594
|
-
back.set(original, list);
|
|
595
878
|
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
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';
|
|
599
1005
|
continue;
|
|
600
1006
|
}
|
|
601
|
-
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
items.push({
|
|
610
|
-
id: m.target.id, subject: m.target.subject, from: m.target.from, messageId: m.target.messageId,
|
|
611
|
-
fromFolder: folder, fromUidValidity: source.uidValidity, fromUid: m.uid,
|
|
612
|
-
toFolder: original, toUidValidity: where.uidValidity ?? 0, toUid: newUid,
|
|
613
|
-
});
|
|
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';
|
|
614
1015
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
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);
|
|
628
1043
|
}
|
|
629
1044
|
}
|
|
1045
|
+
settled += 1;
|
|
630
1046
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
]);
|
|
653
|
-
|
|
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;
|
|
654
1097
|
}
|
|
655
1098
|
/** The newest changes, for the Mail page's Recent changes. */
|
|
656
1099
|
export async function recentActions(db, accountIds, limit = 20) {
|