@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
|
@@ -60,7 +60,6 @@ mock.module("../util/logger.js", () => ({
|
|
|
60
60
|
...realLogger,
|
|
61
61
|
getLogger: () => noopLogger,
|
|
62
62
|
getCliLogger: () => noopLogger,
|
|
63
|
-
isDebug: () => false,
|
|
64
63
|
truncateForLog: (v: string) => v,
|
|
65
64
|
initLogger: () => {},
|
|
66
65
|
pruneOldLogFiles: () => 0,
|
|
@@ -675,15 +674,6 @@ describe("ingress-dependent setup skills declare public-ingress", () => {
|
|
|
675
674
|
expect(includes).toContain("public-ingress");
|
|
676
675
|
});
|
|
677
676
|
|
|
678
|
-
test("google-oauth-setup includes public-ingress", () => {
|
|
679
|
-
const includes = readSkillIncludes(
|
|
680
|
-
FIRST_PARTY_SKILLS_DIR,
|
|
681
|
-
"google-oauth-setup",
|
|
682
|
-
);
|
|
683
|
-
expect(includes).toBeDefined();
|
|
684
|
-
expect(includes).toContain("public-ingress");
|
|
685
|
-
});
|
|
686
|
-
|
|
687
677
|
test("slack-oauth-setup includes browser", () => {
|
|
688
678
|
const includes = readSkillIncludes(
|
|
689
679
|
FIRST_PARTY_SKILLS_DIR,
|
|
@@ -728,15 +718,16 @@ describe("bundled computer-use skill", () => {
|
|
|
728
718
|
expect(cuSkill!.disableModelInvocation).toBe(true);
|
|
729
719
|
});
|
|
730
720
|
|
|
731
|
-
test("computer-use skill has a valid tool manifest with
|
|
721
|
+
test("computer-use skill has a valid tool manifest with 11 tools", () => {
|
|
732
722
|
const catalog = loadSkillCatalog();
|
|
733
723
|
const cuSkill = catalog.find((s) => s.id === "computer-use");
|
|
734
724
|
expect(cuSkill).toBeDefined();
|
|
735
725
|
expect(cuSkill!.toolManifest).toBeDefined();
|
|
736
726
|
expect(cuSkill!.toolManifest!.present).toBe(true);
|
|
737
727
|
expect(cuSkill!.toolManifest!.valid).toBe(true);
|
|
738
|
-
expect(cuSkill!.toolManifest!.toolCount).toBe(
|
|
728
|
+
expect(cuSkill!.toolManifest!.toolCount).toBe(11);
|
|
739
729
|
expect(cuSkill!.toolManifest!.toolNames).toEqual([
|
|
730
|
+
"computer_use_observe",
|
|
740
731
|
"computer_use_click",
|
|
741
732
|
"computer_use_type_text",
|
|
742
733
|
"computer_use_key",
|
|
@@ -75,13 +75,11 @@ mock.module("../util/logger.js", () => ({
|
|
|
75
75
|
debug: () => {},
|
|
76
76
|
trace: () => {},
|
|
77
77
|
fatal: () => {},
|
|
78
|
-
isDebug: () => false,
|
|
79
78
|
child: () => ({
|
|
80
79
|
info: () => {},
|
|
81
80
|
warn: () => {},
|
|
82
81
|
error: () => {},
|
|
83
82
|
debug: () => {},
|
|
84
|
-
isDebug: () => false,
|
|
85
83
|
}),
|
|
86
84
|
}),
|
|
87
85
|
}));
|
|
@@ -116,6 +114,46 @@ mock.module("../security/secure-keys.js", () => {
|
|
|
116
114
|
};
|
|
117
115
|
});
|
|
118
116
|
|
|
117
|
+
// Mock oauth-store (getConnectionByProvider)
|
|
118
|
+
let oauthConnectionStore: Record<
|
|
119
|
+
string,
|
|
120
|
+
{ id: string; status: string; accountInfo?: string | null }
|
|
121
|
+
> = {};
|
|
122
|
+
|
|
123
|
+
mock.module("../oauth/oauth-store.js", () => ({
|
|
124
|
+
getConnectionByProvider: (providerKey: string) =>
|
|
125
|
+
oauthConnectionStore[providerKey] ?? undefined,
|
|
126
|
+
createConnection: () => ({ id: "test-conn-id" }),
|
|
127
|
+
updateConnection: () => true,
|
|
128
|
+
deleteConnection: (id: string) => {
|
|
129
|
+
for (const [key, conn] of Object.entries(oauthConnectionStore)) {
|
|
130
|
+
if (conn.id === id) {
|
|
131
|
+
delete oauthConnectionStore[key];
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
},
|
|
137
|
+
upsertApp: async () => ({ id: "test-app-id" }),
|
|
138
|
+
}));
|
|
139
|
+
|
|
140
|
+
// Mock manual-token-connection
|
|
141
|
+
mock.module("../oauth/manual-token-connection.js", () => ({
|
|
142
|
+
ensureManualTokenConnection: async (
|
|
143
|
+
providerKey: string,
|
|
144
|
+
accountInfo?: string,
|
|
145
|
+
) => {
|
|
146
|
+
oauthConnectionStore[providerKey] = {
|
|
147
|
+
id: `conn-${providerKey}`,
|
|
148
|
+
status: "active",
|
|
149
|
+
accountInfo: accountInfo ?? null,
|
|
150
|
+
};
|
|
151
|
+
},
|
|
152
|
+
removeManualTokenConnection: (providerKey: string) => {
|
|
153
|
+
delete oauthConnectionStore[providerKey];
|
|
154
|
+
},
|
|
155
|
+
}));
|
|
156
|
+
|
|
119
157
|
// Mock credential metadata store
|
|
120
158
|
let credentialMetadataStore: Array<{
|
|
121
159
|
service: string;
|
|
@@ -172,6 +210,7 @@ import {
|
|
|
172
210
|
getSlackChannelConfig,
|
|
173
211
|
setSlackChannelConfig,
|
|
174
212
|
} from "../daemon/handlers/config-slack-channel.js";
|
|
213
|
+
import { credentialKey } from "../security/credential-key.js";
|
|
175
214
|
|
|
176
215
|
afterAll(() => {
|
|
177
216
|
globalThis.fetch = originalFetch;
|
|
@@ -186,6 +225,7 @@ describe("Slack channel config handler", () => {
|
|
|
186
225
|
beforeEach(() => {
|
|
187
226
|
secureKeyStore = {};
|
|
188
227
|
credentialMetadataStore = [];
|
|
228
|
+
oauthConnectionStore = {};
|
|
189
229
|
configStore = {};
|
|
190
230
|
globalThis.fetch = originalFetch;
|
|
191
231
|
});
|
|
@@ -198,9 +238,13 @@ describe("Slack channel config handler", () => {
|
|
|
198
238
|
expect(result.connected).toBe(false);
|
|
199
239
|
});
|
|
200
240
|
|
|
201
|
-
test("GET returns connected: true when both
|
|
202
|
-
|
|
203
|
-
|
|
241
|
+
test("GET returns connected: true when oauth_connection is active and both keys exist", () => {
|
|
242
|
+
oauthConnectionStore["slack_channel"] = {
|
|
243
|
+
id: "conn-slack",
|
|
244
|
+
status: "active",
|
|
245
|
+
};
|
|
246
|
+
secureKeyStore[credentialKey("slack_channel", "bot_token")] = "xoxb-test";
|
|
247
|
+
secureKeyStore[credentialKey("slack_channel", "app_token")] = "xapp-test";
|
|
204
248
|
|
|
205
249
|
const result = getSlackChannelConfig();
|
|
206
250
|
expect(result.success).toBe(true);
|
|
@@ -209,8 +253,29 @@ describe("Slack channel config handler", () => {
|
|
|
209
253
|
expect(result.connected).toBe(true);
|
|
210
254
|
});
|
|
211
255
|
|
|
256
|
+
test("GET reports per-field token presence independently of connection row", () => {
|
|
257
|
+
// Only bot_token in keychain, no app_token, but connection row exists
|
|
258
|
+
oauthConnectionStore["slack_channel"] = {
|
|
259
|
+
id: "conn-slack",
|
|
260
|
+
status: "active",
|
|
261
|
+
};
|
|
262
|
+
secureKeyStore[credentialKey("slack_channel", "bot_token")] = "xoxb-test";
|
|
263
|
+
|
|
264
|
+
const result = getSlackChannelConfig();
|
|
265
|
+
expect(result.success).toBe(true);
|
|
266
|
+
expect(result.hasBotToken).toBe(true);
|
|
267
|
+
expect(result.hasAppToken).toBe(false);
|
|
268
|
+
// connected requires both keys AND connection row
|
|
269
|
+
expect(result.connected).toBe(false);
|
|
270
|
+
});
|
|
271
|
+
|
|
212
272
|
test("GET returns metadata from config when available", () => {
|
|
213
|
-
|
|
273
|
+
oauthConnectionStore["slack_channel"] = {
|
|
274
|
+
id: "conn-slack",
|
|
275
|
+
status: "active",
|
|
276
|
+
};
|
|
277
|
+
secureKeyStore[credentialKey("slack_channel", "bot_token")] = "xoxb-test";
|
|
278
|
+
secureKeyStore[credentialKey("slack_channel", "app_token")] = "xapp-test";
|
|
214
279
|
configStore = {
|
|
215
280
|
slack: {
|
|
216
281
|
teamId: "T123",
|
|
@@ -240,7 +305,7 @@ describe("Slack channel config handler", () => {
|
|
|
240
305
|
);
|
|
241
306
|
expect(result.success).toBe(true);
|
|
242
307
|
expect(result.hasAppToken).toBe(true);
|
|
243
|
-
expect(secureKeyStore["
|
|
308
|
+
expect(secureKeyStore[credentialKey("slack_channel", "app_token")]).toBe(
|
|
244
309
|
"xapp-valid-token-123",
|
|
245
310
|
);
|
|
246
311
|
});
|
|
@@ -296,8 +361,8 @@ describe("Slack channel config handler", () => {
|
|
|
296
361
|
});
|
|
297
362
|
|
|
298
363
|
test("DELETE clears credentials and config", async () => {
|
|
299
|
-
secureKeyStore["
|
|
300
|
-
secureKeyStore["
|
|
364
|
+
secureKeyStore[credentialKey("slack_channel", "bot_token")] = "xoxb-test";
|
|
365
|
+
secureKeyStore[credentialKey("slack_channel", "app_token")] = "xapp-test";
|
|
301
366
|
credentialMetadataStore.push({
|
|
302
367
|
service: "slack_channel",
|
|
303
368
|
field: "bot_token",
|
|
@@ -322,10 +387,10 @@ describe("Slack channel config handler", () => {
|
|
|
322
387
|
expect(result.connected).toBe(false);
|
|
323
388
|
|
|
324
389
|
expect(
|
|
325
|
-
secureKeyStore["
|
|
390
|
+
secureKeyStore[credentialKey("slack_channel", "bot_token")],
|
|
326
391
|
).toBeUndefined();
|
|
327
392
|
expect(
|
|
328
|
-
secureKeyStore["
|
|
393
|
+
secureKeyStore[credentialKey("slack_channel", "app_token")],
|
|
329
394
|
).toBeUndefined();
|
|
330
395
|
expect(credentialMetadataStore).toHaveLength(0);
|
|
331
396
|
|
|
@@ -10,6 +10,12 @@ mock.module("../security/secure-keys.js", () => ({
|
|
|
10
10
|
setSecureKeyAsync: async () => {},
|
|
11
11
|
}));
|
|
12
12
|
|
|
13
|
+
let connectionByProvider: Record<string, unknown> = {};
|
|
14
|
+
mock.module("../oauth/oauth-store.js", () => ({
|
|
15
|
+
getConnectionByProvider: (key: string) =>
|
|
16
|
+
connectionByProvider[key] ?? undefined,
|
|
17
|
+
}));
|
|
18
|
+
|
|
13
19
|
let listConversationsResult: unknown = { ok: true, channels: [] };
|
|
14
20
|
let postMessageResult: unknown = {
|
|
15
21
|
ok: true,
|
|
@@ -84,6 +90,7 @@ function makeRequest(body: unknown): Request {
|
|
|
84
90
|
|
|
85
91
|
beforeEach(() => {
|
|
86
92
|
secureKeyValues.clear();
|
|
93
|
+
connectionByProvider = {};
|
|
87
94
|
listConversationsResult = { ok: true, channels: [] };
|
|
88
95
|
userInfoResults = new Map();
|
|
89
96
|
appStoreResult = null;
|
|
@@ -104,8 +111,9 @@ describe("handleListSlackChannels", () => {
|
|
|
104
111
|
});
|
|
105
112
|
|
|
106
113
|
test("returns channels sorted by type then name", async () => {
|
|
114
|
+
connectionByProvider["integration:slack"] = { id: "conn-slack-1" };
|
|
107
115
|
secureKeyValues.set(
|
|
108
|
-
"
|
|
116
|
+
"oauth_connection/conn-slack-1/access_token",
|
|
109
117
|
"xoxb-test",
|
|
110
118
|
);
|
|
111
119
|
|
|
@@ -174,15 +182,6 @@ describe("handleListSlackChannels", () => {
|
|
|
174
182
|
isPrivate: true,
|
|
175
183
|
});
|
|
176
184
|
});
|
|
177
|
-
|
|
178
|
-
test("falls back to legacy bot token", async () => {
|
|
179
|
-
secureKeyValues.set("credential:slack_channel:bot_token", "xoxb-legacy");
|
|
180
|
-
|
|
181
|
-
listConversationsResult = { ok: true, channels: [] };
|
|
182
|
-
|
|
183
|
-
const res = await handleListSlackChannels();
|
|
184
|
-
expect(res.status).toBe(200);
|
|
185
|
-
});
|
|
186
185
|
});
|
|
187
186
|
|
|
188
187
|
describe("handleShareToSlackChannel", () => {
|
|
@@ -193,8 +192,9 @@ describe("handleShareToSlackChannel", () => {
|
|
|
193
192
|
});
|
|
194
193
|
|
|
195
194
|
test("returns 400 for malformed JSON", async () => {
|
|
195
|
+
connectionByProvider["integration:slack"] = { id: "conn-slack-1" };
|
|
196
196
|
secureKeyValues.set(
|
|
197
|
-
"
|
|
197
|
+
"oauth_connection/conn-slack-1/access_token",
|
|
198
198
|
"xoxb-test",
|
|
199
199
|
);
|
|
200
200
|
const req = new Request("http://localhost/v1/slack/share", {
|
|
@@ -207,8 +207,9 @@ describe("handleShareToSlackChannel", () => {
|
|
|
207
207
|
});
|
|
208
208
|
|
|
209
209
|
test("returns 400 when missing required fields", async () => {
|
|
210
|
+
connectionByProvider["integration:slack"] = { id: "conn-slack-1" };
|
|
210
211
|
secureKeyValues.set(
|
|
211
|
-
"
|
|
212
|
+
"oauth_connection/conn-slack-1/access_token",
|
|
212
213
|
"xoxb-test",
|
|
213
214
|
);
|
|
214
215
|
const req = makeRequest({ appId: "app1" });
|
|
@@ -219,8 +220,9 @@ describe("handleShareToSlackChannel", () => {
|
|
|
219
220
|
});
|
|
220
221
|
|
|
221
222
|
test("returns 404 when app not found", async () => {
|
|
223
|
+
connectionByProvider["integration:slack"] = { id: "conn-slack-1" };
|
|
222
224
|
secureKeyValues.set(
|
|
223
|
-
"
|
|
225
|
+
"oauth_connection/conn-slack-1/access_token",
|
|
224
226
|
"xoxb-test",
|
|
225
227
|
);
|
|
226
228
|
appStoreResult = null;
|
|
@@ -230,8 +232,9 @@ describe("handleShareToSlackChannel", () => {
|
|
|
230
232
|
});
|
|
231
233
|
|
|
232
234
|
test("posts message and returns success", async () => {
|
|
235
|
+
connectionByProvider["integration:slack"] = { id: "conn-slack-1" };
|
|
233
236
|
secureKeyValues.set(
|
|
234
|
-
"
|
|
237
|
+
"oauth_connection/conn-slack-1/access_token",
|
|
235
238
|
"xoxb-test",
|
|
236
239
|
);
|
|
237
240
|
appStoreResult = {
|
|
@@ -38,6 +38,9 @@ mock.module("../config/loader.js", () => ({
|
|
|
38
38
|
|
|
39
39
|
mock.module("../security/secure-keys.js", () => ({
|
|
40
40
|
getSecureKey: (_keyId: string) => mockSecureKey,
|
|
41
|
+
setSecureKey: (_account: string, _value: string) => true,
|
|
42
|
+
deleteSecureKey: (_account: string) => "deleted" as const,
|
|
43
|
+
listSecureKeys: () => [] as string[],
|
|
41
44
|
}));
|
|
42
45
|
|
|
43
46
|
// Suppress logger output during tests
|
|
@@ -7,44 +7,42 @@
|
|
|
7
7
|
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
8
8
|
|
|
9
9
|
import type { ChannelId } from "../channels/types.js";
|
|
10
|
-
import { telegramInviteAdapter } from "../runtime/channel-invite-transports/telegram.js";
|
|
11
10
|
|
|
12
11
|
// Mock credential metadata so tests don't depend on local persisted state.
|
|
13
12
|
mock.module("../tools/credentials/metadata-store.js", () => ({
|
|
14
13
|
getCredentialMetadata: () => undefined,
|
|
15
14
|
}));
|
|
16
15
|
|
|
16
|
+
// Mock getTelegramBotUsername — the env var fallback was removed so we
|
|
17
|
+
// control the return value directly via a mutable variable.
|
|
18
|
+
let mockBotUsername: string | undefined;
|
|
19
|
+
mock.module("../telegram/bot-username.js", () => ({
|
|
20
|
+
getTelegramBotUsername: () => mockBotUsername,
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
import { telegramInviteAdapter } from "../runtime/channel-invite-transports/telegram.js";
|
|
24
|
+
|
|
17
25
|
// ---------------------------------------------------------------------------
|
|
18
26
|
// Helpers
|
|
19
27
|
// ---------------------------------------------------------------------------
|
|
20
28
|
|
|
21
29
|
const CHANNEL: ChannelId = "telegram" as ChannelId;
|
|
22
30
|
|
|
23
|
-
function setEnv(key: string, value: string | undefined) {
|
|
24
|
-
if (value === undefined) {
|
|
25
|
-
delete process.env[key];
|
|
26
|
-
} else {
|
|
27
|
-
process.env[key] = value;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
31
|
// ---------------------------------------------------------------------------
|
|
32
32
|
// buildShareLink
|
|
33
33
|
// ---------------------------------------------------------------------------
|
|
34
34
|
|
|
35
35
|
describe("telegramInviteAdapter.buildShareLink", () => {
|
|
36
|
-
let originalBotUsername: string | undefined;
|
|
37
|
-
|
|
38
36
|
beforeEach(() => {
|
|
39
|
-
|
|
37
|
+
mockBotUsername = undefined;
|
|
40
38
|
});
|
|
41
39
|
|
|
42
40
|
afterEach(() => {
|
|
43
|
-
|
|
41
|
+
mockBotUsername = undefined;
|
|
44
42
|
});
|
|
45
43
|
|
|
46
44
|
test("builds a deep link with iv_ prefix", () => {
|
|
47
|
-
|
|
45
|
+
mockBotUsername = "TestBot";
|
|
48
46
|
|
|
49
47
|
const link = telegramInviteAdapter.buildShareLink!({
|
|
50
48
|
rawToken: "abc123",
|
|
@@ -56,7 +54,7 @@ describe("telegramInviteAdapter.buildShareLink", () => {
|
|
|
56
54
|
});
|
|
57
55
|
|
|
58
56
|
test("throws when bot username is not configured", () => {
|
|
59
|
-
|
|
57
|
+
mockBotUsername = undefined;
|
|
60
58
|
|
|
61
59
|
expect(() =>
|
|
62
60
|
telegramInviteAdapter.buildShareLink!({
|
|
@@ -138,25 +136,23 @@ describe("telegramInviteAdapter.extractInboundToken", () => {
|
|
|
138
136
|
// ---------------------------------------------------------------------------
|
|
139
137
|
|
|
140
138
|
describe("telegramInviteAdapter.resolveChannelHandle", () => {
|
|
141
|
-
let originalBotUsername: string | undefined;
|
|
142
|
-
|
|
143
139
|
beforeEach(() => {
|
|
144
|
-
|
|
140
|
+
mockBotUsername = undefined;
|
|
145
141
|
});
|
|
146
142
|
|
|
147
143
|
afterEach(() => {
|
|
148
|
-
|
|
144
|
+
mockBotUsername = undefined;
|
|
149
145
|
});
|
|
150
146
|
|
|
151
|
-
test("returns @-prefixed bot username from
|
|
152
|
-
|
|
147
|
+
test("returns @-prefixed bot username from config", () => {
|
|
148
|
+
mockBotUsername = "MyBot";
|
|
153
149
|
|
|
154
150
|
const handle = telegramInviteAdapter.resolveChannelHandle!();
|
|
155
151
|
expect(handle).toBe("@MyBot");
|
|
156
152
|
});
|
|
157
153
|
|
|
158
154
|
test("returns undefined when bot username is not configured", () => {
|
|
159
|
-
|
|
155
|
+
mockBotUsername = undefined;
|
|
160
156
|
|
|
161
157
|
const handle = telegramInviteAdapter.resolveChannelHandle!();
|
|
162
158
|
expect(handle).toBeUndefined();
|
|
@@ -457,10 +457,10 @@ describe("buildSanitizedEnv", () => {
|
|
|
457
457
|
});
|
|
458
458
|
|
|
459
459
|
test("injects INTERNAL_GATEWAY_BASE_URL from gateway config", () => {
|
|
460
|
-
process.env.
|
|
460
|
+
process.env.GATEWAY_PORT = "9000";
|
|
461
461
|
const env = buildSanitizedEnv();
|
|
462
|
-
expect(env.INTERNAL_GATEWAY_BASE_URL).toBe("http://
|
|
463
|
-
delete process.env.
|
|
462
|
+
expect(env.INTERNAL_GATEWAY_BASE_URL).toBe("http://127.0.0.1:9000");
|
|
463
|
+
delete process.env.GATEWAY_PORT;
|
|
464
464
|
});
|
|
465
465
|
|
|
466
466
|
test("result is a plain object with no prototype-inherited secrets", () => {
|
|
@@ -485,6 +485,7 @@ describe("buildSanitizedEnv", () => {
|
|
|
485
485
|
"SSH_AGENT_PID",
|
|
486
486
|
"GPG_TTY",
|
|
487
487
|
"GNUPGHOME",
|
|
488
|
+
"VELLUM_DEV",
|
|
488
489
|
"INTERNAL_GATEWAY_BASE_URL",
|
|
489
490
|
"VELLUM_DATA_DIR",
|
|
490
491
|
];
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Reusable constants and helpers for the computer-use skill migration test suite.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
/** The
|
|
5
|
+
/** The 11 computer_use_* action tool names provided by the bundled computer-use skill. */
|
|
6
6
|
export const COMPUTER_USE_TOOL_NAMES = [
|
|
7
|
+
"computer_use_observe",
|
|
7
8
|
"computer_use_click",
|
|
8
9
|
"computer_use_type_text",
|
|
9
10
|
"computer_use_key",
|
|
@@ -20,7 +21,7 @@ export const COMPUTER_USE_TOOL_NAMES = [
|
|
|
20
21
|
export const COMPUTER_USE_SKILL_ID = "computer-use";
|
|
21
22
|
|
|
22
23
|
/** Number of computer_use_* tools. */
|
|
23
|
-
export const COMPUTER_USE_TOOL_COUNT = COMPUTER_USE_TOOL_NAMES.length; //
|
|
24
|
+
export const COMPUTER_USE_TOOL_COUNT = COMPUTER_USE_TOOL_NAMES.length; // 11
|
|
24
25
|
|
|
25
26
|
import { expect } from "bun:test";
|
|
26
27
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { patternMatchesCandidate } from "../permissions/trust-store.js";
|
|
4
|
+
|
|
5
|
+
describe("patternMatchesCandidate", () => {
|
|
6
|
+
test("exact match", () => {
|
|
7
|
+
expect(patternMatchesCandidate("bash:git commit", "bash:git commit")).toBe(
|
|
8
|
+
true,
|
|
9
|
+
);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("glob match", () => {
|
|
13
|
+
expect(patternMatchesCandidate("bash:git *", "bash:git commit")).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("no match", () => {
|
|
17
|
+
expect(patternMatchesCandidate("bash:git *", "file_write:/foo")).toBe(
|
|
18
|
+
false,
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("globstar matches anything", () => {
|
|
23
|
+
expect(patternMatchesCandidate("**", "bash:anything")).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test("invalid pattern returns false", () => {
|
|
27
|
+
expect(patternMatchesCandidate("[", "bash:anything")).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -778,7 +778,6 @@ describe("Trust Store", () => {
|
|
|
778
778
|
"computer_use_drag",
|
|
779
779
|
"computer_use_key",
|
|
780
780
|
"computer_use_open_app",
|
|
781
|
-
"computer_use_request_control",
|
|
782
781
|
"computer_use_run_applescript",
|
|
783
782
|
"computer_use_scroll",
|
|
784
783
|
"computer_use_type_text",
|
|
@@ -901,22 +900,6 @@ describe("Trust Store", () => {
|
|
|
901
900
|
);
|
|
902
901
|
});
|
|
903
902
|
|
|
904
|
-
test("findHighestPriorityRule matches default ask for computer_use_request_control", () => {
|
|
905
|
-
const match = findHighestPriorityRule(
|
|
906
|
-
"computer_use_request_control",
|
|
907
|
-
["computer_use_request_control:"],
|
|
908
|
-
"/tmp",
|
|
909
|
-
);
|
|
910
|
-
expect(match).not.toBeNull();
|
|
911
|
-
expect(match!.id).toBe("default:ask-computer_use_request_control-global");
|
|
912
|
-
expect(match!.decision).toBe("ask");
|
|
913
|
-
expect(match!.priority).toBe(
|
|
914
|
-
DEFAULT_PRIORITY_BY_ID.get(
|
|
915
|
-
"default:ask-computer_use_request_control-global",
|
|
916
|
-
)!,
|
|
917
|
-
);
|
|
918
|
-
});
|
|
919
|
-
|
|
920
903
|
test("bootstrap delete rule matches only when workingDir is the workspace dir", () => {
|
|
921
904
|
const workspaceDir = join(testDir, "workspace");
|
|
922
905
|
// Should match when workingDir is the workspace directory — the bootstrap
|
|
@@ -1755,11 +1738,7 @@ describe("computer-use tool trust rule matching", () => {
|
|
|
1755
1738
|
test("actionable CU tools have default ask trust rules", () => {
|
|
1756
1739
|
// Actionable CU tools (those that perform screen interactions) should
|
|
1757
1740
|
// have default "ask" rules so strict mode prompts before use.
|
|
1758
|
-
const actionableCuTools = [
|
|
1759
|
-
"computer_use_click",
|
|
1760
|
-
"computer_use_type_text",
|
|
1761
|
-
"computer_use_request_control",
|
|
1762
|
-
];
|
|
1741
|
+
const actionableCuTools = ["computer_use_click", "computer_use_type_text"];
|
|
1763
1742
|
|
|
1764
1743
|
for (const name of actionableCuTools) {
|
|
1765
1744
|
const rule = findHighestPriorityRule(name, [name], "/tmp/test");
|
|
@@ -26,11 +26,12 @@ mock.module("../inbound/public-ingress-urls.js", () => ({
|
|
|
26
26
|
}));
|
|
27
27
|
|
|
28
28
|
import { getTwilioConfig } from "../calls/twilio-config.js";
|
|
29
|
+
import { credentialKey } from "../security/credential-key.js";
|
|
29
30
|
|
|
30
31
|
describe("twilio-config", () => {
|
|
31
32
|
beforeEach(() => {
|
|
32
33
|
mockSecureKeys = {
|
|
33
|
-
"
|
|
34
|
+
[credentialKey("twilio", "auth_token")]: "test_auth_token",
|
|
34
35
|
};
|
|
35
36
|
mockLoadConfigResult = {
|
|
36
37
|
twilio: {
|
|
@@ -8,6 +8,8 @@ import { tmpdir } from "node:os";
|
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
10
10
|
|
|
11
|
+
import { credentialKey } from "../security/credential-key.js";
|
|
12
|
+
|
|
11
13
|
const testDir = mkdtempSync(join(tmpdir(), "twilio-provider-test-"));
|
|
12
14
|
|
|
13
15
|
mock.module("../util/platform.js", () => ({
|
|
@@ -40,8 +42,8 @@ mock.module("../config/loader.js", () => ({
|
|
|
40
42
|
|
|
41
43
|
mock.module("../security/secure-keys.js", () => ({
|
|
42
44
|
getSecureKey: (key: string) => {
|
|
43
|
-
if (key === "
|
|
44
|
-
if (key === "
|
|
45
|
+
if (key === credentialKey("twilio", "auth_token")) return mockAuthToken;
|
|
46
|
+
if (key === credentialKey("twilio", "account_sid")) return mockAccountSid;
|
|
45
47
|
return undefined;
|
|
46
48
|
},
|
|
47
49
|
}));
|