@vellumai/assistant 0.4.46 → 0.4.49
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/ARCHITECTURE.md +7 -7
- package/README.md +2 -23
- package/docs/architecture/integrations.md +45 -41
- package/docs/architecture/keychain-broker.md +3 -3
- package/docs/architecture/security.md +5 -5
- package/docs/runbook-trusted-contacts.md +3 -8
- package/hook-templates/debug-prompt-logger/hook.json +1 -1
- package/hook-templates/debug-prompt-logger/run.sh +1 -3
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +0 -1
- package/src/__tests__/anthropic-provider.test.ts +156 -0
- package/src/__tests__/approval-cascade.test.ts +810 -0
- package/src/__tests__/approval-primitive.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +2 -0
- package/src/__tests__/assistant-attachments.test.ts +12 -34
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
- package/src/__tests__/browser-fill-credential.test.ts +5 -2
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -1
- package/src/__tests__/channel-guardian.test.ts +0 -2
- package/src/__tests__/channel-readiness-routes.test.ts +35 -25
- package/src/__tests__/channel-readiness-service.test.ts +10 -9
- package/src/__tests__/checker.test.ts +9 -29
- package/src/__tests__/cli.test.ts +23 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-tools.test.ts +2 -19
- package/src/__tests__/config-watcher.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-image-dimensions.test.ts +332 -0
- package/src/__tests__/context-token-estimator.test.ts +196 -13
- package/src/__tests__/conversation-attention-store.test.ts +0 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +144 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/credential-broker-browser-fill.test.ts +23 -22
- package/src/__tests__/credential-broker-server-use.test.ts +22 -21
- package/src/__tests__/credential-broker.test.ts +2 -1
- package/src/__tests__/credential-metadata-store.test.ts +239 -26
- package/src/__tests__/credential-resolve.test.ts +5 -4
- package/src/__tests__/credential-security-e2e.test.ts +8 -8
- package/src/__tests__/credential-security-invariants.test.ts +111 -7
- package/src/__tests__/credential-vault-unit.test.ts +287 -54
- package/src/__tests__/credential-vault.test.ts +406 -12
- package/src/__tests__/credentials-cli.test.ts +82 -6
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/ephemeral-permissions.test.ts +3 -3
- package/src/__tests__/gateway-only-enforcement.test.ts +4 -2
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/gemini-image-service.test.ts +75 -45
- package/src/__tests__/gemini-provider.test.ts +9 -6
- package/src/__tests__/guardian-action-conversation-turn.test.ts +1 -33
- package/src/__tests__/guardian-action-copy-generator.test.ts +0 -20
- package/src/__tests__/guardian-action-followup-executor.test.ts +1 -28
- package/src/__tests__/guardian-action-followup-store.test.ts +1 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
- package/src/__tests__/guardian-grant-minting.test.ts +35 -0
- package/src/__tests__/guardian-routing-invariants.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
- package/src/__tests__/heartbeat-service.test.ts +0 -1
- package/src/__tests__/host-cu-proxy.test.ts +629 -0
- package/src/__tests__/host-shell-tool.test.ts +27 -15
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/ingress-url-consistency.test.ts +14 -21
- package/src/__tests__/integration-status.test.ts +38 -25
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/invite-routes-http.test.ts +10 -9
- package/src/__tests__/keychain-broker-client.test.ts +11 -43
- package/src/__tests__/managed-proxy-context.test.ts +5 -3
- package/src/__tests__/media-generate-image.test.ts +63 -2
- package/src/__tests__/media-reuse-story.e2e.test.ts +7 -3
- package/src/__tests__/messaging-send-tool.test.ts +4 -6
- package/src/__tests__/notification-routing-intent.test.ts +0 -1
- package/src/__tests__/oauth-cli.test.ts +373 -14
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
- package/src/__tests__/oauth-scope-policy.test.ts +4 -6
- package/src/__tests__/oauth-store.test.ts +756 -0
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
- package/src/__tests__/provider-error-scenarios.test.ts +0 -1
- package/src/__tests__/provider-fail-open-selection.test.ts +3 -1
- package/src/__tests__/provider-managed-proxy-integration.test.ts +70 -6
- package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
- package/src/__tests__/public-ingress-urls.test.ts +15 -21
- package/src/__tests__/recording-handler.test.ts +3 -4
- package/src/__tests__/registry.test.ts +2 -2
- package/src/__tests__/runtime-events-sse.test.ts +55 -7
- package/src/__tests__/schedule-store.test.ts +0 -1
- package/src/__tests__/scheduler-recurrence.test.ts +0 -1
- package/src/__tests__/schema-transforms.test.ts +226 -0
- package/src/__tests__/scoped-approval-grants.test.ts +0 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
- package/src/__tests__/script-proxy-injection-runtime.test.ts +23 -13
- package/src/__tests__/script-proxy-policy-runtime.test.ts +1 -1
- package/src/__tests__/script-proxy-session-manager.test.ts +1 -1
- package/src/__tests__/secret-ingress-handler.test.ts +0 -1
- package/src/__tests__/secret-onetime-send.test.ts +5 -3
- package/src/__tests__/send-endpoint-busy.test.ts +21 -6
- package/src/__tests__/sequence-store.test.ts +0 -1
- package/src/__tests__/session-init.benchmark.test.ts +4 -5
- package/src/__tests__/session-messaging-secret-redirect.test.ts +5 -4
- package/src/__tests__/skill-include-graph.test.ts +66 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
- package/src/__tests__/skill-load-tool.test.ts +149 -1
- package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
- package/src/__tests__/skills-uninstall.test.ts +3 -3
- package/src/__tests__/skills.test.ts +3 -12
- package/src/__tests__/slack-channel-config.test.ts +76 -11
- package/src/__tests__/slack-share-routes.test.ts +17 -14
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-bot-username-resolution.test.ts +3 -0
- package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
- package/src/__tests__/terminal-tools.test.ts +4 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/tool-approval-handler.test.ts +0 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
- package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
- package/src/__tests__/trust-store.test.ts +1 -22
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +2 -1
- package/src/__tests__/twilio-provider.test.ts +4 -2
- package/src/__tests__/twilio-routes.test.ts +5 -20
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/agent/ax-tree-compaction.test.ts +235 -0
- package/src/agent/loop.ts +76 -130
- package/src/calls/call-domain.ts +8 -10
- package/src/calls/relay-server.ts +9 -13
- package/src/calls/twilio-config.ts +4 -8
- package/src/calls/twilio-provider.ts +2 -1
- package/src/calls/twilio-rest.ts +2 -1
- package/src/calls/twilio-routes.ts +1 -2
- package/src/calls/voice-ingress-preflight.ts +1 -1
- package/src/cli/commands/browser-relay.ts +46 -15
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/credentials.ts +110 -23
- package/src/cli/commands/oauth/apps.ts +255 -0
- package/src/cli/commands/oauth/connections.ts +299 -0
- package/src/cli/commands/oauth/index.ts +52 -0
- package/src/cli/commands/oauth/providers.ts +242 -0
- package/src/cli/commands/skills.ts +4 -338
- package/src/cli/program.ts +1 -5
- package/src/cli/reference.ts +1 -3
- package/src/cli.ts +3 -2
- package/src/config/assistant-feature-flags.ts +0 -3
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/claude-code/TOOLS.json +0 -4
- package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
- package/src/config/bundled-skills/computer-use/TOOLS.json +22 -4
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +29 -32
- package/src/config/bundled-skills/gmail/SKILL.md +4 -4
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +54 -61
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +25 -28
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +14 -17
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +39 -44
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +61 -58
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +50 -49
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +11 -13
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +148 -146
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +4 -7
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +175 -173
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +4 -7
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +71 -76
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +32 -38
- package/src/config/bundled-skills/google-calendar/SKILL.md +2 -2
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +90 -44
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +9 -10
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +5 -6
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +4 -5
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +14 -15
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +37 -37
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +4 -9
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +24 -3
- package/src/config/bundled-skills/messaging/SKILL.md +6 -6
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +62 -63
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +15 -16
- package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +6 -7
- package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +14 -15
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +4 -5
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +128 -128
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +33 -34
- package/src/config/bundled-skills/messaging/tools/shared.ts +12 -15
- package/src/config/bundled-skills/settings/SKILL.md +1 -1
- package/src/config/bundled-skills/settings/TOOLS.json +2 -8
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
- package/src/config/bundled-skills/slack/tools/shared.ts +4 -10
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +15 -16
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +4 -5
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +95 -92
- package/src/config/env-registry.ts +14 -83
- package/src/config/env.ts +11 -50
- package/src/config/feature-flag-registry.json +16 -16
- package/src/config/schema.ts +3 -1
- package/src/config/skills.ts +21 -2
- package/src/context/image-dimensions.ts +229 -0
- package/src/context/token-estimator.ts +75 -12
- package/src/context/window-manager.ts +49 -10
- package/src/daemon/assistant-attachments.ts +1 -13
- package/src/daemon/guardian-action-generators.ts +4 -5
- package/src/daemon/handlers/config-ingress.ts +8 -33
- package/src/daemon/handlers/config-slack-channel.ts +76 -56
- package/src/daemon/handlers/config-telegram.ts +53 -24
- package/src/daemon/handlers/sessions.ts +10 -24
- package/src/daemon/handlers/shared.ts +0 -130
- package/src/daemon/host-cu-proxy.ts +401 -0
- package/src/daemon/lifecycle.ts +39 -63
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/computer-use.ts +2 -119
- package/src/daemon/message-types/host-cu.ts +19 -0
- package/src/daemon/message-types/integrations.ts +1 -0
- package/src/daemon/message-types/messages.ts +3 -0
- package/src/daemon/server.ts +14 -21
- package/src/daemon/session-agent-loop-handlers.ts +2 -0
- package/src/daemon/session-attachments.ts +1 -2
- package/src/daemon/session-messaging.ts +3 -1
- package/src/daemon/session-slash.ts +1 -1
- package/src/daemon/session-surfaces.ts +40 -28
- package/src/daemon/session-tool-setup.ts +20 -11
- package/src/daemon/session.ts +139 -16
- package/src/daemon/tool-side-effects.ts +2 -8
- package/src/daemon/watch-handler.ts +2 -2
- package/src/email/providers/index.ts +2 -1
- package/src/events/tool-metrics-listener.ts +2 -2
- package/src/hooks/manager.ts +1 -4
- package/src/inbound/public-ingress-urls.ts +7 -7
- package/src/instrument.ts +15 -1
- package/src/logfire.ts +16 -5
- package/src/media/app-icon-generator.ts +30 -4
- package/src/media/avatar-router.ts +26 -3
- package/src/media/gemini-image-service.ts +28 -2
- package/src/memory/conversation-key-store.ts +21 -0
- package/src/memory/db-init.ts +4 -0
- package/src/memory/guardian-action-store.ts +1 -1
- package/src/memory/migrations/149-oauth-tables.ts +60 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/schema/guardian.ts +1 -1
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/oauth.ts +65 -0
- package/src/messaging/provider.ts +19 -13
- package/src/messaging/providers/gmail/adapter.ts +40 -23
- package/src/messaging/providers/gmail/client.ts +283 -122
- package/src/messaging/providers/gmail/people-client.ts +32 -24
- package/src/messaging/providers/slack/adapter.ts +29 -19
- package/src/messaging/providers/slack/client.ts +265 -78
- package/src/messaging/providers/telegram-bot/adapter.ts +19 -18
- package/src/messaging/providers/whatsapp/adapter.ts +17 -11
- package/src/messaging/registry.ts +2 -31
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/signal.ts +4 -5
- package/src/oauth/byo-connection.test.ts +537 -0
- package/src/oauth/byo-connection.ts +128 -0
- package/src/oauth/connect-orchestrator.ts +139 -56
- package/src/oauth/connect-types.ts +17 -23
- package/src/oauth/connection-resolver.ts +58 -0
- package/src/oauth/connection.ts +38 -0
- package/src/oauth/manual-token-connection.ts +104 -0
- package/src/oauth/oauth-store.ts +496 -0
- package/src/oauth/platform-connection.test.ts +192 -0
- package/src/oauth/platform-connection.ts +111 -0
- package/src/oauth/provider-behaviors.ts +124 -0
- package/src/oauth/scope-policy.ts +9 -2
- package/src/oauth/seed-providers.ts +161 -0
- package/src/oauth/token-persistence.ts +74 -78
- package/src/permissions/checker.ts +8 -4
- package/src/permissions/defaults.ts +0 -1
- package/src/permissions/prompter.ts +10 -1
- package/src/permissions/trust-store.ts +13 -0
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
- package/src/prompts/system-prompt.ts +70 -45
- package/src/providers/anthropic/client.ts +133 -24
- package/src/providers/gemini/client.ts +15 -6
- package/src/providers/managed-proxy/constants.ts +2 -2
- package/src/providers/managed-proxy/context.ts +5 -1
- package/src/providers/ratelimit.ts +17 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +1 -27
- package/src/runtime/AGENTS.md +17 -0
- package/src/runtime/auth/route-policy.ts +0 -3
- package/src/runtime/channel-invite-transports/telegram.ts +2 -1
- package/src/runtime/channel-readiness-service.ts +168 -195
- package/src/runtime/channel-readiness-types.ts +4 -0
- package/src/runtime/channel-reply-delivery.ts +0 -40
- package/src/runtime/gateway-client.ts +0 -7
- package/src/runtime/guardian-action-conversation-turn.ts +1 -3
- package/src/runtime/guardian-action-followup-executor.ts +1 -1
- package/src/runtime/guardian-action-message-composer.ts +3 -23
- package/src/runtime/http-server.ts +17 -10
- package/src/runtime/http-types.ts +2 -3
- package/src/runtime/middleware/rate-limiter.ts +74 -20
- package/src/runtime/middleware/twilio-validation.ts +1 -11
- package/src/runtime/pending-interactions.ts +14 -12
- package/src/runtime/routes/channel-delivery-routes.ts +0 -1
- package/src/runtime/routes/channel-readiness-routes.ts +2 -0
- package/src/runtime/routes/conversation-routes.ts +73 -19
- package/src/runtime/routes/diagnostics-routes.ts +11 -9
- package/src/runtime/routes/events-routes.ts +21 -11
- package/src/runtime/routes/guardian-approval-interception.ts +20 -5
- package/src/runtime/routes/host-cu-routes.ts +97 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
- package/src/runtime/routes/integrations/slack/share.ts +6 -6
- package/src/runtime/routes/integrations/twilio.ts +6 -5
- package/src/runtime/routes/log-export-routes.ts +126 -8
- package/src/runtime/routes/secret-routes.ts +3 -2
- package/src/runtime/routes/settings-routes.ts +113 -48
- package/src/runtime/routes/surface-action-routes.ts +1 -1
- package/src/runtime/routes/watch-routes.ts +128 -0
- package/src/schedule/integration-status.ts +10 -8
- package/src/security/credential-key.ts +14 -0
- package/src/security/keychain-broker-client.ts +5 -6
- package/src/security/oauth2.ts +1 -1
- package/src/security/token-manager.ts +145 -43
- package/src/skills/catalog-install.ts +358 -0
- package/src/skills/include-graph.ts +32 -0
- package/src/telegram/bot-username.ts +2 -3
- package/src/tools/apps/definitions.ts +0 -5
- package/src/tools/assets/materialize.ts +0 -5
- package/src/tools/assets/search.ts +0 -5
- package/src/tools/browser/headless-browser.ts +1 -67
- package/src/tools/browser/network-recorder.ts +1 -1
- package/src/tools/browser/network-recording-types.ts +1 -1
- package/src/tools/claude-code/claude-code.ts +0 -5
- package/src/tools/computer-use/definitions.ts +46 -11
- package/src/tools/computer-use/registry.ts +4 -5
- package/src/tools/credentials/broker.ts +5 -4
- package/src/tools/credentials/metadata-store.ts +22 -74
- package/src/tools/credentials/resolve.ts +2 -1
- package/src/tools/credentials/vault.ts +139 -151
- package/src/tools/filesystem/edit.ts +1 -6
- package/src/tools/filesystem/read.ts +0 -5
- package/src/tools/filesystem/write.ts +1 -6
- package/src/tools/host-filesystem/edit.ts +1 -6
- package/src/tools/host-filesystem/read.ts +1 -6
- package/src/tools/host-filesystem/write.ts +1 -6
- package/src/tools/mcp/mcp-tool-factory.ts +18 -1
- package/src/tools/memory/definitions.ts +0 -5
- package/src/tools/network/web-fetch.ts +0 -5
- package/src/tools/network/web-search.ts +0 -5
- package/src/tools/registry.ts +2 -7
- package/src/tools/schema-transforms.ts +99 -0
- package/src/tools/skills/load.ts +62 -8
- package/src/tools/swarm/delegate.ts +0 -5
- package/src/tools/system/avatar-generator.ts +0 -5
- package/src/tools/ui-surface/definitions.ts +0 -15
- package/src/tools/watch/screen-watch.ts +0 -5
- package/src/tools/watch/watch-state.ts +0 -12
- package/src/util/logger.ts +7 -41
- package/src/util/platform.ts +9 -28
- package/src/version.ts +10 -0
- package/src/watcher/providers/github.ts +51 -52
- package/src/watcher/providers/gmail.ts +88 -80
- package/src/watcher/providers/google-calendar.ts +94 -86
- package/src/watcher/providers/linear.ts +87 -93
- package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
- package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
- package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
- package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
- package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
- package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
- package/src/cli/commands/dev.ts +0 -129
- package/src/cli/commands/map.ts +0 -391
- package/src/cli/commands/oauth.ts +0 -77
- package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +0 -16
- package/src/daemon/computer-use-session.ts +0 -1020
- package/src/daemon/ride-shotgun-handler.ts +0 -567
- package/src/oauth/provider-profiles.ts +0 -192
- package/src/prompts/computer-use-prompt.ts +0 -98
- package/src/runtime/routes/computer-use-routes.ts +0 -641
- package/src/runtime/telegram-streaming-delivery.test.ts +0 -597
- package/src/runtime/telegram-streaming-delivery.ts +0 -383
- package/src/tools/computer-use/request-computer-control.ts +0 -61
|
@@ -2,7 +2,7 @@ import type {
|
|
|
2
2
|
ToolContext,
|
|
3
3
|
ToolExecutionResult,
|
|
4
4
|
} from "../../../../tools/types.js";
|
|
5
|
-
import { err, ok, resolveProvider
|
|
5
|
+
import { err, getProviderConnection, ok, resolveProvider } from "./shared.js";
|
|
6
6
|
|
|
7
7
|
export async function run(
|
|
8
8
|
input: Record<string, unknown>,
|
|
@@ -23,47 +23,46 @@ export async function run(
|
|
|
23
23
|
);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (result.senders.length === 0) {
|
|
34
|
-
return ok(
|
|
35
|
-
JSON.stringify({
|
|
36
|
-
senders: [],
|
|
37
|
-
total_scanned: result.totalScanned,
|
|
38
|
-
query_used: result.queryUsed,
|
|
39
|
-
...(result.truncated ? { truncated: true } : {}),
|
|
40
|
-
message:
|
|
41
|
-
"No emails found matching the query. Try broadening the search (e.g. remove category filter or extend date range).",
|
|
42
|
-
}),
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Map to snake_case output format for LLM consumption
|
|
47
|
-
const senders = result.senders.map((s) => ({
|
|
48
|
-
id: s.id,
|
|
49
|
-
display_name: s.displayName,
|
|
50
|
-
email: s.email,
|
|
51
|
-
message_count: s.messageCount,
|
|
52
|
-
has_unsubscribe: s.hasUnsubscribe,
|
|
53
|
-
newest_message_id: s.newestMessageId,
|
|
54
|
-
search_query: s.searchQuery,
|
|
55
|
-
}));
|
|
26
|
+
const conn = getProviderConnection(provider);
|
|
27
|
+
const result = await provider.senderDigest!(conn, query, {
|
|
28
|
+
maxMessages,
|
|
29
|
+
maxSenders,
|
|
30
|
+
pageToken,
|
|
31
|
+
});
|
|
56
32
|
|
|
33
|
+
if (result.senders.length === 0) {
|
|
57
34
|
return ok(
|
|
58
35
|
JSON.stringify({
|
|
59
|
-
senders,
|
|
36
|
+
senders: [],
|
|
60
37
|
total_scanned: result.totalScanned,
|
|
61
38
|
query_used: result.queryUsed,
|
|
62
39
|
...(result.truncated ? { truncated: true } : {}),
|
|
63
|
-
|
|
40
|
+
message:
|
|
41
|
+
"No emails found matching the query. Try broadening the search (e.g. remove category filter or extend date range).",
|
|
64
42
|
}),
|
|
65
43
|
);
|
|
66
|
-
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Map to snake_case output format for LLM consumption
|
|
47
|
+
const senders = result.senders.map((s) => ({
|
|
48
|
+
id: s.id,
|
|
49
|
+
display_name: s.displayName,
|
|
50
|
+
email: s.email,
|
|
51
|
+
message_count: s.messageCount,
|
|
52
|
+
has_unsubscribe: s.hasUnsubscribe,
|
|
53
|
+
newest_message_id: s.newestMessageId,
|
|
54
|
+
search_query: s.searchQuery,
|
|
55
|
+
}));
|
|
56
|
+
|
|
57
|
+
return ok(
|
|
58
|
+
JSON.stringify({
|
|
59
|
+
senders,
|
|
60
|
+
total_scanned: result.totalScanned,
|
|
61
|
+
query_used: result.queryUsed,
|
|
62
|
+
...(result.truncated ? { truncated: true } : {}),
|
|
63
|
+
note: `message_count reflects emails found per sender within the ${result.totalScanned} messages scanned. Use messaging_archive_by_sender with the sender's search_query to archive their messages.`,
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
67
66
|
} catch (e) {
|
|
68
67
|
return err(e instanceof Error ? e.message : String(e));
|
|
69
68
|
}
|
|
@@ -6,9 +6,9 @@ import type { MessagingProvider } from "../../../../messaging/provider.js";
|
|
|
6
6
|
import {
|
|
7
7
|
getConnectedProviders,
|
|
8
8
|
getMessagingProvider,
|
|
9
|
-
isPlatformEnabled,
|
|
10
9
|
} from "../../../../messaging/registry.js";
|
|
11
|
-
import {
|
|
10
|
+
import type { OAuthConnection } from "../../../../oauth/connection.js";
|
|
11
|
+
import { resolveOAuthConnection } from "../../../../oauth/connection-resolver.js";
|
|
12
12
|
import type { ToolExecutionResult } from "../../../../tools/types.js";
|
|
13
13
|
|
|
14
14
|
export function ok(content: string): ToolExecutionResult {
|
|
@@ -109,9 +109,7 @@ export function extractEmail(address: string): string {
|
|
|
109
109
|
export function resolveProvider(platformInput?: string): MessagingProvider {
|
|
110
110
|
if (platformInput) return getMessagingProvider(platformInput);
|
|
111
111
|
|
|
112
|
-
const connected = getConnectedProviders()
|
|
113
|
-
isPlatformEnabled(p.id),
|
|
114
|
-
);
|
|
112
|
+
const connected = getConnectedProviders();
|
|
115
113
|
if (connected.length === 1) return connected[0];
|
|
116
114
|
if (connected.length === 0) {
|
|
117
115
|
throw new Error(
|
|
@@ -126,16 +124,15 @@ export function resolveProvider(platformInput?: string): MessagingProvider {
|
|
|
126
124
|
}
|
|
127
125
|
|
|
128
126
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
127
|
+
* Resolve an OAuthConnection (or empty string for non-OAuth providers)
|
|
128
|
+
* for the given messaging provider.
|
|
129
|
+
*
|
|
130
|
+
* Non-OAuth providers (e.g. Telegram) use isConnected() and don't need
|
|
131
|
+
* tokens — they receive an empty string which the string overload handles.
|
|
132
132
|
*/
|
|
133
|
-
export
|
|
133
|
+
export function getProviderConnection(
|
|
134
134
|
provider: MessagingProvider,
|
|
135
|
-
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
return fn("");
|
|
139
|
-
}
|
|
140
|
-
return withValidToken(provider.credentialService, fn);
|
|
135
|
+
): OAuthConnection | string {
|
|
136
|
+
if (provider.isConnected?.()) return "";
|
|
137
|
+
return resolveOAuthConnection(provider.credentialService);
|
|
141
138
|
}
|
|
@@ -9,4 +9,4 @@ metadata:
|
|
|
9
9
|
user-invocable: true
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
Tools for managing assistant settings: voice configuration (TTS voice, PTT activation key,
|
|
12
|
+
Tools for managing assistant settings: voice configuration (TTS voice, PTT activation key, conversation timeout), avatar generation, system settings navigation, and in-app settings tab navigation.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"tools": [
|
|
4
4
|
{
|
|
5
5
|
"name": "voice_config_update",
|
|
6
|
-
"description": "Update a voice configuration setting (TTS voice ID, PTT activation key,
|
|
6
|
+
"description": "Update a voice configuration setting (TTS voice ID, PTT activation key, conversation timeout). Changes take effect immediately.",
|
|
7
7
|
"category": "system",
|
|
8
8
|
"risk": "low",
|
|
9
9
|
"input_schema": {
|
|
@@ -11,13 +11,7 @@
|
|
|
11
11
|
"properties": {
|
|
12
12
|
"setting": {
|
|
13
13
|
"type": "string",
|
|
14
|
-
"enum": [
|
|
15
|
-
"activation_key",
|
|
16
|
-
"wake_word_enabled",
|
|
17
|
-
"wake_word_keyword",
|
|
18
|
-
"wake_word_timeout",
|
|
19
|
-
"tts_voice_id"
|
|
20
|
-
],
|
|
14
|
+
"enum": ["activation_key", "conversation_timeout", "tts_voice_id"],
|
|
21
15
|
"description": "The voice setting to change"
|
|
22
16
|
},
|
|
23
17
|
"value": {
|
|
@@ -18,16 +18,8 @@ const VOICE_SETTINGS = {
|
|
|
18
18
|
userDefaultsKey: "pttActivationKey",
|
|
19
19
|
type: "string" as const,
|
|
20
20
|
},
|
|
21
|
-
|
|
22
|
-
userDefaultsKey: "
|
|
23
|
-
type: "boolean" as const,
|
|
24
|
-
},
|
|
25
|
-
wake_word_keyword: {
|
|
26
|
-
userDefaultsKey: "wakeWordKeyword",
|
|
27
|
-
type: "string" as const,
|
|
28
|
-
},
|
|
29
|
-
wake_word_timeout: {
|
|
30
|
-
userDefaultsKey: "wakeWordTimeoutSeconds",
|
|
21
|
+
conversation_timeout: {
|
|
22
|
+
userDefaultsKey: "voiceConversationTimeoutSeconds",
|
|
31
23
|
type: "number" as const,
|
|
32
24
|
},
|
|
33
25
|
tts_voice_id: { userDefaultsKey: "ttsVoiceId", type: "string" as const },
|
|
@@ -41,9 +33,7 @@ const VALID_TIMEOUTS = [5, 10, 15, 30, 60];
|
|
|
41
33
|
|
|
42
34
|
const FRIENDLY_NAMES: Record<VoiceSettingName, string> = {
|
|
43
35
|
activation_key: "PTT activation key",
|
|
44
|
-
|
|
45
|
-
wake_word_keyword: "Wake word keyword",
|
|
46
|
-
wake_word_timeout: "Wake word timeout",
|
|
36
|
+
conversation_timeout: "Conversation timeout",
|
|
47
37
|
tts_voice_id: "ElevenLabs voice",
|
|
48
38
|
};
|
|
49
39
|
|
|
@@ -76,30 +66,12 @@ function validateSetting(
|
|
|
76
66
|
}
|
|
77
67
|
return { ok: true, coerced: result.value };
|
|
78
68
|
}
|
|
79
|
-
case "
|
|
80
|
-
if (typeof value === "boolean") return { ok: true, coerced: value };
|
|
81
|
-
if (value === "true") return { ok: true, coerced: true };
|
|
82
|
-
if (value === "false") return { ok: true, coerced: false };
|
|
83
|
-
return {
|
|
84
|
-
ok: false,
|
|
85
|
-
error: 'wake_word_enabled must be a boolean (or "true"/"false" string)',
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
case "wake_word_keyword": {
|
|
89
|
-
if (typeof value !== "string" || value.trim().length === 0) {
|
|
90
|
-
return {
|
|
91
|
-
ok: false,
|
|
92
|
-
error: "wake_word_keyword must be a non-empty string",
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
return { ok: true, coerced: value.trim() };
|
|
96
|
-
}
|
|
97
|
-
case "wake_word_timeout": {
|
|
69
|
+
case "conversation_timeout": {
|
|
98
70
|
const num = typeof value === "number" ? value : Number(value);
|
|
99
71
|
if (Number.isNaN(num) || !VALID_TIMEOUTS.includes(num)) {
|
|
100
72
|
return {
|
|
101
73
|
ok: false,
|
|
102
|
-
error: `
|
|
74
|
+
error: `conversation_timeout must be one of: ${VALID_TIMEOUTS.join(
|
|
103
75
|
", ",
|
|
104
76
|
)}`,
|
|
105
77
|
};
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Shared utilities for slack skill tools.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import type { OAuthConnection } from "../../../../oauth/connection.js";
|
|
6
|
+
import { resolveOAuthConnection } from "../../../../oauth/connection-resolver.js";
|
|
7
7
|
import type { ToolExecutionResult } from "../../../../tools/types.js";
|
|
8
8
|
|
|
9
9
|
export function ok(content: string): ToolExecutionResult {
|
|
@@ -14,12 +14,6 @@ export function err(message: string): ToolExecutionResult {
|
|
|
14
14
|
return { content: message, isError: true };
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*/
|
|
20
|
-
export async function withSlackToken<T>(
|
|
21
|
-
fn: (token: string) => Promise<T>,
|
|
22
|
-
): Promise<T> {
|
|
23
|
-
const provider = getMessagingProvider("slack");
|
|
24
|
-
return withValidToken(provider.credentialService, fn);
|
|
17
|
+
export function getSlackConnection(): OAuthConnection {
|
|
18
|
+
return resolveOAuthConnection("integration:slack");
|
|
25
19
|
}
|
|
@@ -3,7 +3,7 @@ import type {
|
|
|
3
3
|
ToolContext,
|
|
4
4
|
ToolExecutionResult,
|
|
5
5
|
} from "../../../../tools/types.js";
|
|
6
|
-
import { err,
|
|
6
|
+
import { err, getSlackConnection, ok } from "./shared.js";
|
|
7
7
|
|
|
8
8
|
export async function run(
|
|
9
9
|
input: Record<string, unknown>,
|
|
@@ -18,10 +18,9 @@ export async function run(
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
try {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
21
|
+
const connection = getSlackConnection();
|
|
22
|
+
await addReaction(connection, channel, timestamp, emoji);
|
|
23
|
+
return ok(`Added :${emoji}: reaction.`);
|
|
25
24
|
} catch (e) {
|
|
26
25
|
return err(e instanceof Error ? e.message : String(e));
|
|
27
26
|
}
|
|
@@ -3,7 +3,7 @@ import type {
|
|
|
3
3
|
ToolContext,
|
|
4
4
|
ToolExecutionResult,
|
|
5
5
|
} from "../../../../tools/types.js";
|
|
6
|
-
import { err,
|
|
6
|
+
import { err, getSlackConnection, ok } from "./shared.js";
|
|
7
7
|
|
|
8
8
|
export async function run(
|
|
9
9
|
input: Record<string, unknown>,
|
|
@@ -16,23 +16,22 @@ export async function run(
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
const connection = getSlackConnection();
|
|
20
|
+
const resp = await slack.conversationInfo(connection, channelId);
|
|
21
|
+
const conv = resp.channel;
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
const result = {
|
|
24
|
+
channelId: conv.id,
|
|
25
|
+
name: conv.name ?? conv.id,
|
|
26
|
+
topic: conv.topic?.value || null,
|
|
27
|
+
purpose: conv.purpose?.value || null,
|
|
28
|
+
isPrivate: conv.is_private ?? conv.is_group ?? false,
|
|
29
|
+
isArchived: conv.is_archived ?? false,
|
|
30
|
+
memberCount: conv.num_members ?? null,
|
|
31
|
+
latestActivityTs: conv.latest?.ts ?? null,
|
|
32
|
+
};
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
});
|
|
34
|
+
return ok(JSON.stringify(result, null, 2));
|
|
36
35
|
} catch (e) {
|
|
37
36
|
return err(e instanceof Error ? e.message : String(e));
|
|
38
37
|
}
|
|
@@ -3,7 +3,7 @@ import type {
|
|
|
3
3
|
ToolContext,
|
|
4
4
|
ToolExecutionResult,
|
|
5
5
|
} from "../../../../tools/types.js";
|
|
6
|
-
import { err,
|
|
6
|
+
import { err, getSlackConnection, ok } from "./shared.js";
|
|
7
7
|
|
|
8
8
|
export async function run(
|
|
9
9
|
input: Record<string, unknown>,
|
|
@@ -17,10 +17,9 @@ export async function run(
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
try {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
});
|
|
20
|
+
const connection = getSlackConnection();
|
|
21
|
+
await deleteMessage(connection, channel, timestamp);
|
|
22
|
+
return ok(`Message deleted.`);
|
|
24
23
|
} catch (e) {
|
|
25
24
|
return err(e instanceof Error ? e.message : String(e));
|
|
26
25
|
}
|
|
@@ -3,7 +3,7 @@ import type {
|
|
|
3
3
|
ToolContext,
|
|
4
4
|
ToolExecutionResult,
|
|
5
5
|
} from "../../../../tools/types.js";
|
|
6
|
-
import { err,
|
|
6
|
+
import { err, getSlackConnection, ok } from "./shared.js";
|
|
7
7
|
|
|
8
8
|
export async function run(
|
|
9
9
|
input: Record<string, unknown>,
|
|
@@ -18,10 +18,9 @@ export async function run(
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
try {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
21
|
+
const connection = getSlackConnection();
|
|
22
|
+
await updateMessage(connection, channel, timestamp, text);
|
|
23
|
+
return ok(`Message updated.`);
|
|
25
24
|
} catch (e) {
|
|
26
25
|
return err(e instanceof Error ? e.message : String(e));
|
|
27
26
|
}
|
|
@@ -3,7 +3,7 @@ import type {
|
|
|
3
3
|
ToolContext,
|
|
4
4
|
ToolExecutionResult,
|
|
5
5
|
} from "../../../../tools/types.js";
|
|
6
|
-
import { err,
|
|
6
|
+
import { err, getSlackConnection, ok } from "./shared.js";
|
|
7
7
|
|
|
8
8
|
export async function run(
|
|
9
9
|
input: Record<string, unknown>,
|
|
@@ -16,10 +16,9 @@ export async function run(
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
});
|
|
19
|
+
const connection = getSlackConnection();
|
|
20
|
+
await leaveConversation(connection, channel);
|
|
21
|
+
return ok("Left channel.");
|
|
23
22
|
} catch (e) {
|
|
24
23
|
return err(e instanceof Error ? e.message : String(e));
|
|
25
24
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { getConfig } from "../../../../config/loader.js";
|
|
2
2
|
import * as slack from "../../../../messaging/providers/slack/client.js";
|
|
3
3
|
import type { SlackConversation } from "../../../../messaging/providers/slack/types.js";
|
|
4
|
+
import type { OAuthConnection } from "../../../../oauth/connection.js";
|
|
4
5
|
import type {
|
|
5
6
|
ToolContext,
|
|
6
7
|
ToolExecutionResult,
|
|
7
8
|
} from "../../../../tools/types.js";
|
|
8
|
-
import { err,
|
|
9
|
+
import { err, getSlackConnection, ok } from "./shared.js";
|
|
9
10
|
|
|
10
11
|
interface ThreadSummary {
|
|
11
12
|
threadTs: string;
|
|
@@ -26,13 +27,16 @@ interface ChannelDigest {
|
|
|
26
27
|
|
|
27
28
|
const userNameCache = new Map<string, string>();
|
|
28
29
|
|
|
29
|
-
async function resolveUserName(
|
|
30
|
+
async function resolveUserName(
|
|
31
|
+
connection: OAuthConnection,
|
|
32
|
+
userId: string,
|
|
33
|
+
): Promise<string> {
|
|
30
34
|
if (!userId) return "unknown";
|
|
31
35
|
const cached = userNameCache.get(userId);
|
|
32
36
|
if (cached) return cached;
|
|
33
37
|
|
|
34
38
|
try {
|
|
35
|
-
const resp = await slack.userInfo(
|
|
39
|
+
const resp = await slack.userInfo(connection, userId);
|
|
36
40
|
const name =
|
|
37
41
|
resp.user.profile?.display_name ||
|
|
38
42
|
resp.user.profile?.real_name ||
|
|
@@ -46,7 +50,7 @@ async function resolveUserName(token: string, userId: string): Promise<string> {
|
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
async function scanChannel(
|
|
49
|
-
|
|
53
|
+
connection: OAuthConnection,
|
|
50
54
|
conv: SlackConversation,
|
|
51
55
|
oldestTs: string,
|
|
52
56
|
includeThreads: boolean,
|
|
@@ -57,7 +61,7 @@ async function scanChannel(
|
|
|
57
61
|
|
|
58
62
|
try {
|
|
59
63
|
const history = await slack.conversationHistory(
|
|
60
|
-
|
|
64
|
+
connection,
|
|
61
65
|
channelId,
|
|
62
66
|
100,
|
|
63
67
|
undefined,
|
|
@@ -71,7 +75,7 @@ async function scanChannel(
|
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
const keyParticipants = await Promise.all(
|
|
74
|
-
[...participantIds].map((uid) => resolveUserName(
|
|
78
|
+
[...participantIds].map((uid) => resolveUserName(connection, uid)),
|
|
75
79
|
);
|
|
76
80
|
|
|
77
81
|
const threadMessages = messages
|
|
@@ -86,7 +90,7 @@ async function scanChannel(
|
|
|
86
90
|
if (includeThreads) {
|
|
87
91
|
try {
|
|
88
92
|
const replies = await slack.conversationReplies(
|
|
89
|
-
|
|
93
|
+
connection,
|
|
90
94
|
channelId,
|
|
91
95
|
msg.ts,
|
|
92
96
|
10,
|
|
@@ -97,11 +101,11 @@ async function scanChannel(
|
|
|
97
101
|
}
|
|
98
102
|
participants = await Promise.all(
|
|
99
103
|
[...threadParticipantIds].map((uid) =>
|
|
100
|
-
resolveUserName(
|
|
104
|
+
resolveUserName(connection, uid),
|
|
101
105
|
),
|
|
102
106
|
);
|
|
103
107
|
} catch {
|
|
104
|
-
participants = [await resolveUserName(
|
|
108
|
+
participants = [await resolveUserName(connection, msg.user ?? "")];
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
|
|
@@ -260,15 +264,34 @@ export async function run(
|
|
|
260
264
|
const format = (input.format as string) ?? "text";
|
|
261
265
|
|
|
262
266
|
try {
|
|
263
|
-
|
|
264
|
-
|
|
267
|
+
const connection = getSlackConnection();
|
|
268
|
+
const oldestTs = String((Date.now() - hoursBack * 60 * 60 * 1000) / 1000);
|
|
265
269
|
|
|
266
|
-
|
|
267
|
-
|
|
270
|
+
let channelsToScan: SlackConversation[];
|
|
271
|
+
let failedLookups = 0;
|
|
268
272
|
|
|
269
|
-
|
|
273
|
+
if (channelIds?.length) {
|
|
274
|
+
const results = await Promise.allSettled(
|
|
275
|
+
channelIds.map((id) => slack.conversationInfo(connection, id)),
|
|
276
|
+
);
|
|
277
|
+
channelsToScan = results
|
|
278
|
+
.filter(
|
|
279
|
+
(
|
|
280
|
+
r,
|
|
281
|
+
): r is PromiseFulfilledResult<
|
|
282
|
+
Awaited<ReturnType<typeof slack.conversationInfo>>
|
|
283
|
+
> => r.status === "fulfilled",
|
|
284
|
+
)
|
|
285
|
+
.map((r) => r.value.channel);
|
|
286
|
+
failedLookups = results.filter((r) => r.status === "rejected").length;
|
|
287
|
+
} else {
|
|
288
|
+
const config = getConfig();
|
|
289
|
+
const preferredIds = config.skills?.entries?.slack?.config
|
|
290
|
+
?.preferredChannels as string[] | undefined;
|
|
291
|
+
|
|
292
|
+
if (preferredIds?.length) {
|
|
270
293
|
const results = await Promise.allSettled(
|
|
271
|
-
|
|
294
|
+
preferredIds.map((id) => slack.conversationInfo(connection, id)),
|
|
272
295
|
);
|
|
273
296
|
channelsToScan = results
|
|
274
297
|
.filter(
|
|
@@ -281,89 +304,69 @@ export async function run(
|
|
|
281
304
|
.map((r) => r.value.channel);
|
|
282
305
|
failedLookups = results.filter((r) => r.status === "rejected").length;
|
|
283
306
|
} else {
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
307
|
+
const allChannels: SlackConversation[] = [];
|
|
308
|
+
let cursor: string | undefined;
|
|
309
|
+
do {
|
|
310
|
+
const resp = await slack.listConversations(
|
|
311
|
+
connection,
|
|
312
|
+
"public_channel,private_channel",
|
|
313
|
+
true,
|
|
314
|
+
200,
|
|
315
|
+
cursor,
|
|
291
316
|
);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
)
|
|
300
|
-
.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
let cursor: string | undefined;
|
|
305
|
-
do {
|
|
306
|
-
const resp = await slack.listConversations(
|
|
307
|
-
token,
|
|
308
|
-
"public_channel,private_channel",
|
|
309
|
-
true,
|
|
310
|
-
200,
|
|
311
|
-
cursor,
|
|
312
|
-
);
|
|
313
|
-
allChannels.push(...resp.channels);
|
|
314
|
-
cursor = resp.response_metadata?.next_cursor || undefined;
|
|
315
|
-
} while (cursor);
|
|
316
|
-
|
|
317
|
-
channelsToScan = allChannels
|
|
318
|
-
.filter((c) => c.is_member)
|
|
319
|
-
.sort((a, b) => {
|
|
320
|
-
const aTs = a.latest?.ts ? parseFloat(a.latest.ts) : 0;
|
|
321
|
-
const bTs = b.latest?.ts ? parseFloat(b.latest.ts) : 0;
|
|
322
|
-
return bTs - aTs;
|
|
323
|
-
})
|
|
324
|
-
.slice(0, maxChannels);
|
|
325
|
-
}
|
|
317
|
+
allChannels.push(...resp.channels);
|
|
318
|
+
cursor = resp.response_metadata?.next_cursor || undefined;
|
|
319
|
+
} while (cursor);
|
|
320
|
+
|
|
321
|
+
channelsToScan = allChannels
|
|
322
|
+
.filter((c) => c.is_member)
|
|
323
|
+
.sort((a, b) => {
|
|
324
|
+
const aTs = a.latest?.ts ? parseFloat(a.latest.ts) : 0;
|
|
325
|
+
const bTs = b.latest?.ts ? parseFloat(b.latest.ts) : 0;
|
|
326
|
+
return bTs - aTs;
|
|
327
|
+
})
|
|
328
|
+
.slice(0, maxChannels);
|
|
326
329
|
}
|
|
330
|
+
}
|
|
327
331
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const digests: ChannelDigest[] = scanResults
|
|
335
|
-
.filter(
|
|
336
|
-
(r): r is PromiseFulfilledResult<ChannelDigest> =>
|
|
337
|
-
r.status === "fulfilled",
|
|
338
|
-
)
|
|
339
|
-
.map((r) => r.value)
|
|
340
|
-
.filter((d) => d.messageCount > 0 || d.error);
|
|
341
|
-
|
|
342
|
-
const skippedCount = scanResults.filter(
|
|
343
|
-
(r) => r.status === "rejected",
|
|
344
|
-
).length;
|
|
345
|
-
|
|
346
|
-
if (format === "blocks") {
|
|
347
|
-
const blocks = buildBlockKitOutput(
|
|
348
|
-
digests,
|
|
349
|
-
hoursBack,
|
|
350
|
-
channelsToScan.length,
|
|
351
|
-
skippedCount,
|
|
352
|
-
);
|
|
353
|
-
return ok(JSON.stringify({ blocks }, null, 2));
|
|
354
|
-
}
|
|
332
|
+
const scanResults = await Promise.allSettled(
|
|
333
|
+
channelsToScan.map((conv) =>
|
|
334
|
+
scanChannel(connection, conv, oldestTs, includeThreads),
|
|
335
|
+
),
|
|
336
|
+
);
|
|
355
337
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
338
|
+
const digests: ChannelDigest[] = scanResults
|
|
339
|
+
.filter(
|
|
340
|
+
(r): r is PromiseFulfilledResult<ChannelDigest> =>
|
|
341
|
+
r.status === "fulfilled",
|
|
342
|
+
)
|
|
343
|
+
.map((r) => r.value)
|
|
344
|
+
.filter((d) => d.messageCount > 0 || d.error);
|
|
345
|
+
|
|
346
|
+
const skippedCount = scanResults.filter(
|
|
347
|
+
(r) => r.status === "rejected",
|
|
348
|
+
).length;
|
|
349
|
+
|
|
350
|
+
if (format === "blocks") {
|
|
351
|
+
const blocks = buildBlockKitOutput(
|
|
352
|
+
digests,
|
|
361
353
|
hoursBack,
|
|
362
|
-
|
|
363
|
-
|
|
354
|
+
channelsToScan.length,
|
|
355
|
+
skippedCount,
|
|
356
|
+
);
|
|
357
|
+
return ok(JSON.stringify({ blocks }, null, 2));
|
|
358
|
+
}
|
|
364
359
|
|
|
365
|
-
|
|
366
|
-
|
|
360
|
+
const result = {
|
|
361
|
+
scannedChannels: digests.length,
|
|
362
|
+
totalChannelsAttempted: channelsToScan.length,
|
|
363
|
+
skippedDueToErrors: skippedCount,
|
|
364
|
+
failedLookups,
|
|
365
|
+
hoursBack,
|
|
366
|
+
channels: digests,
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
return ok(JSON.stringify(result, null, 2));
|
|
367
370
|
} catch (e) {
|
|
368
371
|
return err(e instanceof Error ? e.message : String(e));
|
|
369
372
|
}
|