@vellumai/assistant 0.4.26 → 0.4.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +2 -2
- package/AGENTS.md +5 -0
- package/ARCHITECTURE.md +169 -69
- package/Dockerfile +1 -1
- package/README.md +111 -112
- package/bun.lock +0 -3
- package/docs/architecture/integrations.md +0 -1
- package/docs/architecture/memory.md +100 -63
- package/docs/error-handling.md +71 -0
- package/docs/runbook-trusted-contacts.md +10 -9
- package/docs/trusted-contact-access.md +48 -46
- package/package.json +3 -3
- package/scripts/compare-benchmarks.sh +12 -5
- package/scripts/ipc/check-swift-decoder-drift.ts +3 -0
- package/scripts/test.sh +89 -5
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +46 -0
- package/src/__tests__/access-request-decision.test.ts +0 -1
- package/src/__tests__/account-registry.test.ts +1 -1
- package/src/__tests__/actor-token-service.test.ts +36 -23
- package/src/__tests__/agent-loop-thinking.test.ts +29 -13
- package/src/__tests__/agent-loop.test.ts +2 -1
- package/src/__tests__/app-builder-tool-scripts.test.ts +1 -1
- package/src/__tests__/approval-routes-http.test.ts +2 -2
- package/src/__tests__/asset-materialize-tool.test.ts +7 -7
- package/src/__tests__/asset-search-tool.test.ts +7 -7
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +217 -0
- package/src/__tests__/call-controller.test.ts +99 -69
- package/src/__tests__/call-start-guardian-guard.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +113 -70
- package/src/__tests__/channel-guardian.test.ts +173 -282
- package/src/__tests__/channel-readiness-service.test.ts +6 -2
- package/src/__tests__/channel-reply-delivery.test.ts +2 -2
- package/src/__tests__/channel-retry-sweep.test.ts +14 -14
- package/src/__tests__/checker.test.ts +12 -31
- package/src/__tests__/claude-code-tool-profiles.test.ts +1 -1
- package/src/__tests__/commit-message-enrichment-service.test.ts +67 -59
- package/src/__tests__/compaction.benchmark.test.ts +6 -2
- package/src/__tests__/computer-use-tools.test.ts +1 -1
- package/src/__tests__/config-schema.test.ts +66 -7
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +29 -29
- package/src/__tests__/contacts-tools.test.ts +63 -2
- package/src/__tests__/context-overflow-approval.test.ts +141 -0
- package/src/__tests__/context-overflow-policy.test.ts +171 -0
- package/src/__tests__/context-overflow-reducer.test.ts +533 -0
- package/src/__tests__/context-window-manager.test.ts +97 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +38 -46
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +214 -10
- package/src/__tests__/conversation-routes.test.ts +4 -7
- package/src/__tests__/credential-broker-browser-fill.test.ts +13 -2
- package/src/__tests__/credential-security-e2e.test.ts +1 -1
- package/src/__tests__/credential-security-invariants.test.ts +1 -1
- package/src/__tests__/credential-vault-unit.test.ts +1 -1
- package/src/__tests__/credential-vault.test.ts +11 -8
- package/src/__tests__/daemon-lifecycle.test.ts +2 -2
- package/src/__tests__/daemon-server-session-init.test.ts +6 -6
- package/src/__tests__/delete-managed-skill-tool.test.ts +1 -1
- package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -2
- package/src/__tests__/emit-signal-routing-intent.test.ts +4 -0
- package/src/__tests__/encrypted-store.test.ts +10 -7
- package/src/__tests__/ephemeral-permissions.test.ts +3 -3
- package/src/__tests__/file-edit-tool.test.ts +1 -1
- package/src/__tests__/file-read-tool.test.ts +1 -1
- package/src/__tests__/file-write-tool.test.ts +1 -1
- package/src/__tests__/fixtures/credential-security-fixtures.ts +87 -64
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +37 -31
- package/src/__tests__/fixtures/mock-signup-server.ts +171 -115
- package/src/__tests__/fixtures/proxy-fixtures.ts +39 -39
- package/src/__tests__/followup-tools.test.ts +1 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -0
- package/src/__tests__/guardian-actions-endpoint.test.ts +543 -1
- package/src/__tests__/guardian-control-plane-policy.test.ts +15 -15
- package/src/__tests__/guardian-dispatch.test.ts +79 -1
- package/src/__tests__/guardian-grant-minting.test.ts +14 -14
- package/src/__tests__/guardian-outbound-http.test.ts +1 -2
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -41
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -5
- package/src/__tests__/guardian-routing-state.test.ts +36 -52
- package/src/__tests__/guardian-verification-intent-routing.test.ts +4 -6
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +2 -2
- package/src/__tests__/handle-user-message-secret-resume.test.ts +39 -1
- package/src/__tests__/handlers-cu-observation-blob.test.ts +21 -10
- package/src/__tests__/handlers-telegram-config.test.ts +14 -14
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +23 -2
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +1 -1
- package/src/__tests__/headless-browser-read-tools.test.ts +1 -1
- package/src/__tests__/headless-browser-snapshot.test.ts +1 -1
- package/src/__tests__/heartbeat-service.test.ts +45 -2
- package/src/__tests__/host-file-edit-tool.test.ts +1 -1
- package/src/__tests__/host-file-read-tool.test.ts +1 -1
- package/src/__tests__/host-file-write-tool.test.ts +1 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/inbound-invite-redemption.test.ts +16 -18
- package/src/__tests__/ingress-reconcile.test.ts +2 -2
- package/src/__tests__/ingress-routes-http.test.ts +2 -1
- package/src/__tests__/integrations-cli.test.ts +256 -0
- package/src/__tests__/intent-routing.test.ts +4 -5
- package/src/__tests__/invite-redemption-service.test.ts +4 -3
- package/src/__tests__/ipc-snapshot.test.ts +28 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -1
- package/src/__tests__/mcp-cli.test.ts +136 -57
- package/src/__tests__/mcp-client-auth.test.ts +95 -0
- package/src/__tests__/media-generate-image.test.ts +2 -2
- package/src/__tests__/media-reuse-story.e2e.test.ts +8 -8
- package/src/__tests__/memory-regressions.test.ts +6 -6
- package/src/__tests__/messaging-send-tool.test.ts +1 -1
- package/src/__tests__/migration-cross-version-compatibility.test.ts +1855 -0
- package/src/__tests__/migration-export-http.test.ts +540 -0
- package/src/__tests__/migration-import-commit-http.test.ts +823 -0
- package/src/__tests__/migration-import-preflight-http.test.ts +755 -0
- package/src/__tests__/migration-parity-persistence.test.ts +1854 -0
- package/src/__tests__/migration-transport.test.ts +904 -0
- package/src/__tests__/migration-validate-http.test.ts +698 -0
- package/src/__tests__/migration-wizard.test.ts +1289 -0
- package/src/__tests__/non-member-access-request.test.ts +17 -17
- package/src/__tests__/notification-decision-strategy.test.ts +110 -2
- package/src/__tests__/notification-deep-link.test.ts +18 -0
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/oauth2-gateway-transport.test.ts +1 -1
- package/src/__tests__/playbook-execution.test.ts +1 -1
- package/src/__tests__/playbook-tools.test.ts +1 -1
- package/src/__tests__/provider-streaming.benchmark.test.ts +3 -1
- package/src/__tests__/proxy-approval-callback.test.ts +1 -1
- package/src/__tests__/qdrant-manager.test.ts +40 -11
- package/src/__tests__/rebind-secrets-screen.test.ts +839 -0
- package/src/__tests__/recording-handler.test.ts +2 -2
- package/src/__tests__/recording-intent-handler.test.ts +3 -3
- package/src/__tests__/recording-state-machine.test.ts +2 -2
- package/src/__tests__/relay-server.test.ts +506 -227
- package/src/__tests__/reminder-store.test.ts +8 -0
- package/src/__tests__/reminder.test.ts +8 -0
- package/src/__tests__/{resolve-guardian-trust-class.test.ts → resolve-trust-class.test.ts} +11 -17
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +1 -1
- package/src/__tests__/schedule-tools.test.ts +1 -1
- package/src/__tests__/script-proxy-certs.test.ts +1 -1
- package/src/__tests__/script-proxy-connect-tunnel.test.ts +2 -3
- package/src/__tests__/script-proxy-decision-trace.test.ts +2 -2
- package/src/__tests__/script-proxy-http-forwarder.test.ts +1 -1
- package/src/__tests__/script-proxy-injection-runtime.test.ts +5 -5
- package/src/__tests__/script-proxy-mitm-handler.test.ts +4 -4
- package/src/__tests__/script-proxy-policy-runtime.test.ts +2 -2
- package/src/__tests__/script-proxy-policy.test.ts +2 -2
- package/src/__tests__/script-proxy-session-manager.test.ts +4 -7
- package/src/__tests__/script-proxy-session-runtime.test.ts +1 -6
- package/src/__tests__/secret-onetime-send.test.ts +4 -4
- package/src/__tests__/secret-scanner-executor.test.ts +2 -2
- package/src/__tests__/send-endpoint-busy.test.ts +11 -9
- package/src/__tests__/send-notification-tool.test.ts +2 -2
- package/src/__tests__/session-abort-tool-results.test.ts +17 -2
- package/src/__tests__/session-agent-loop.test.ts +456 -35
- package/src/__tests__/session-confirmation-signals.test.ts +3 -2
- package/src/__tests__/session-conflict-gate.test.ts +20 -3
- package/src/__tests__/session-init.benchmark.test.ts +2 -2
- package/src/__tests__/session-load-history-repair.test.ts +7 -7
- package/src/__tests__/session-pre-run-repair.test.ts +17 -2
- package/src/__tests__/session-profile-injection.test.ts +20 -3
- package/src/__tests__/session-provider-retry-repair.test.ts +86 -6
- package/src/__tests__/session-queue.test.ts +33 -18
- package/src/__tests__/session-runtime-assembly.test.ts +147 -1
- package/src/__tests__/session-runtime-workspace.test.ts +40 -0
- package/src/__tests__/session-slash-known.test.ts +21 -3
- package/src/__tests__/session-slash-queue.test.ts +17 -2
- package/src/__tests__/session-slash-unknown.test.ts +17 -2
- package/src/__tests__/session-surfaces-deselection.test.ts +208 -0
- package/src/__tests__/session-workspace-cache-state.test.ts +2 -2
- package/src/__tests__/session-workspace-injection.test.ts +17 -2
- package/src/__tests__/session-workspace-tool-tracking.test.ts +17 -2
- package/src/__tests__/shell-credential-ref.test.ts +1 -1
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -1
- package/src/__tests__/skill-load-tool.test.ts +1 -1
- package/src/__tests__/skill-script-runner-host.test.ts +1 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +1 -1
- package/src/__tests__/skill-script-runner.test.ts +1 -1
- package/src/__tests__/skill-tool-factory.test.ts +1 -1
- package/src/__tests__/slack-skill.test.ts +3 -2
- package/src/__tests__/subagent-tools.test.ts +3 -3
- package/src/__tests__/swarm-recursion.test.ts +1 -1
- package/src/__tests__/swarm-session-integration.test.ts +1 -1
- package/src/__tests__/swarm-tool.test.ts +1 -1
- package/src/__tests__/task-management-tools.test.ts +1 -1
- package/src/__tests__/task-tools.test.ts +1 -1
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-support/browser-skill-harness.ts +39 -27
- package/src/__tests__/test-support/computer-use-skill-harness.ts +14 -14
- package/src/__tests__/tool-approval-handler.test.ts +15 -15
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +1 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
- package/src/__tests__/tool-executor-shell-integration.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +23 -182
- package/src/__tests__/tool-grant-request-escalation.test.ts +11 -11
- package/src/__tests__/tool-permission-simulate-handler.test.ts +4 -4
- package/src/__tests__/transfer-progress-screen.test.ts +1180 -0
- package/src/__tests__/trust-context-guards.test.ts +25 -29
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +23 -21
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +37 -40
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +29 -25
- package/src/__tests__/trusted-contact-multichannel.test.ts +25 -24
- package/src/__tests__/trusted-contact-verification.test.ts +63 -77
- package/src/__tests__/turn-commit.test.ts +18 -18
- package/src/__tests__/twilio-provider.test.ts +7 -7
- package/src/__tests__/validation-results-screen.test.ts +1107 -0
- package/src/__tests__/view-image-tool.test.ts +1 -1
- package/src/__tests__/voice-invite-redemption.test.ts +3 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +12 -12
- package/src/__tests__/voice-session-bridge.test.ts +24 -24
- package/src/agent/attachments.ts +3 -1
- package/src/agent/loop.ts +13 -13
- package/src/agent/message-types.ts +13 -7
- package/src/amazon/cart.ts +59 -32
- package/src/amazon/checkout.ts +25 -14
- package/src/amazon/client.ts +68 -48
- package/src/amazon/product-details.ts +3 -3
- package/src/amazon/request-extractor.ts +46 -31
- package/src/amazon/search.ts +6 -4
- package/src/amazon/session.ts +33 -24
- package/src/approvals/AGENTS.md +26 -0
- package/src/approvals/approval-primitive.ts +87 -64
- package/src/approvals/guardian-decision-primitive.ts +172 -81
- package/src/approvals/guardian-request-resolvers.ts +262 -155
- package/src/autonomy/autonomy-resolver.ts +7 -5
- package/src/autonomy/autonomy-store.ts +34 -19
- package/src/autonomy/disposition-mapper.ts +5 -5
- package/src/autonomy/index.ts +6 -6
- package/src/autonomy/types.ts +7 -3
- package/src/browser-extension-relay/client.ts +50 -19
- package/src/browser-extension-relay/protocol.ts +11 -11
- package/src/browser-extension-relay/server.ts +45 -20
- package/src/bundler/app-bundler.ts +75 -50
- package/src/bundler/bundle-scanner.ts +145 -41
- package/src/bundler/bundle-signer.ts +16 -14
- package/src/bundler/signature-verifier.ts +36 -33
- package/src/calls/call-constants.ts +10 -3
- package/src/calls/call-controller.ts +473 -214
- package/src/calls/call-conversation-messages.ts +25 -15
- package/src/calls/call-domain.ts +401 -148
- package/src/calls/call-pointer-message-composer.ts +26 -21
- package/src/calls/call-pointer-messages.ts +52 -28
- package/src/calls/call-recovery.ts +53 -37
- package/src/calls/call-state-machine.ts +37 -7
- package/src/calls/call-state.ts +35 -13
- package/src/calls/call-store.ts +165 -77
- package/src/calls/elevenlabs-client.ts +39 -20
- package/src/calls/guardian-action-sweep.ts +42 -24
- package/src/calls/guardian-dispatch.ts +79 -56
- package/src/calls/guardian-question-copy.ts +28 -23
- package/src/calls/relay-server.ts +1121 -532
- package/src/calls/speaker-identification.ts +21 -15
- package/src/calls/twilio-config.ts +34 -17
- package/src/calls/twilio-provider.ts +108 -55
- package/src/calls/twilio-rest.ts +212 -100
- package/src/calls/twilio-routes.ts +165 -92
- package/src/calls/types.ts +55 -7
- package/src/calls/voice-quality.ts +6 -4
- package/src/calls/voice-session-bridge.ts +181 -133
- package/src/channels/config.ts +17 -13
- package/src/channels/types.ts +38 -10
- package/src/cli/amazon.ts +333 -227
- package/src/cli/config-commands.ts +236 -146
- package/src/cli/core-commands.ts +403 -329
- package/src/cli/email-guardrails.ts +38 -19
- package/src/cli/email.ts +207 -153
- package/src/cli/influencer.ts +58 -56
- package/src/cli/integrations.ts +362 -0
- package/src/cli/ipc-client.ts +24 -19
- package/src/cli/map.ts +176 -129
- package/src/cli/mcp.ts +260 -152
- package/src/cli/sequence.ts +165 -107
- package/src/cli/twitter.ts +302 -218
- package/src/cli.ts +418 -279
- package/src/commands/cc-command-registry.ts +52 -27
- package/src/config/agent-schema.ts +217 -134
- package/src/config/assistant-feature-flags.ts +23 -18
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +19 -0
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +7 -4
- package/src/config/bundled-skills/app-builder/tools/app-delete.ts +6 -3
- package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +7 -4
- package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +6 -3
- package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +6 -3
- package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +7 -4
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +6 -3
- package/src/config/bundled-skills/app-builder/tools/app-query.ts +6 -3
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +6 -3
- package/src/config/bundled-skills/browser/tools/browser-click.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-close.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-extract.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-hover.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-navigate.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-press-key.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-scroll.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-select-option.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-type.ts +5 -2
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +13 -6
- package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +5 -2
- package/src/config/bundled-skills/claude-code/TOOLS.json +4 -0
- package/src/config/bundled-skills/claude-code/tools/claude-code.ts +5 -2
- package/src/config/bundled-skills/computer-use/SKILL.md +2 -2
- package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-done.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-double-click.ts +10 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-drag.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-key.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-open-app.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +10 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-respond.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-right-click.ts +10 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-run-applescript.ts +10 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-scroll.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-type-text.ts +6 -3
- package/src/config/bundled-skills/computer-use/tools/computer-use-wait.ts +6 -3
- package/src/config/bundled-skills/configure-settings/SKILL.md +28 -14
- package/src/config/bundled-skills/contacts/SKILL.md +446 -15
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +99 -20
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +74 -17
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +89 -26
- package/src/config/bundled-skills/document/tools/document-create.ts +5 -2
- package/src/config/bundled-skills/document/tools/document-update.ts +5 -2
- package/src/config/bundled-skills/doordash/doordash-cli.ts +17 -7
- package/src/config/bundled-skills/email-setup/SKILL.md +9 -9
- package/src/config/bundled-skills/followups/tools/followup-create.ts +5 -2
- package/src/config/bundled-skills/followups/tools/followup-list.ts +5 -2
- package/src/config/bundled-skills/followups/tools/followup-resolve.ts +5 -2
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +44 -32
- package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +11 -5
- package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +13 -7
- package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +11 -5
- package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +13 -7
- package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +28 -12
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +6 -4
- package/src/config/bundled-skills/google-calendar/types.ts +3 -3
- package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +46 -24
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +36 -19
- package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +60 -35
- package/src/config/bundled-skills/mcp-setup/SKILL.md +75 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +55 -15
- package/src/config/bundled-skills/media-processing/TOOLS.json +20 -2
- package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +12 -10
- package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +34 -19
- package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +82 -66
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +148 -0
- package/src/config/bundled-skills/media-processing/services/concurrency-pool.ts +1 -1
- package/src/config/bundled-skills/media-processing/services/cost-tracker.ts +8 -3
- package/src/config/bundled-skills/media-processing/services/gemini-map.ts +117 -53
- package/src/config/bundled-skills/media-processing/services/gemini-video.ts +273 -0
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +185 -97
- package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +32 -27
- package/src/config/bundled-skills/media-processing/services/reduce.ts +101 -24
- package/src/config/bundled-skills/media-processing/tools/analyze-keyframes.ts +121 -55
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +58 -24
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +177 -91
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +98 -70
- package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +59 -19
- package/src/config/bundled-skills/media-processing/tools/media-status.ts +26 -10
- package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +29 -14
- package/src/config/bundled-skills/messaging/SKILL.md +7 -5
- package/src/config/bundled-skills/messaging/TOOLS.json +7 -7
- package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +31 -13
- package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +16 -10
- package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +18 -9
- package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +23 -16
- package/src/config/bundled-skills/messaging/tools/gmail-draft.ts +28 -12
- package/src/config/bundled-skills/messaging/tools/gmail-filters.ts +41 -21
- package/src/config/bundled-skills/messaging/tools/gmail-follow-up.ts +44 -23
- package/src/config/bundled-skills/messaging/tools/gmail-forward.ts +73 -33
- package/src/config/bundled-skills/messaging/tools/gmail-label.ts +15 -9
- package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +22 -14
- package/src/config/bundled-skills/messaging/tools/gmail-outreach-scan.ts +99 -50
- package/src/config/bundled-skills/messaging/tools/gmail-send-draft.ts +14 -8
- package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +63 -44
- package/src/config/bundled-skills/messaging/tools/gmail-sender-digest.ts +90 -46
- package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +43 -22
- package/src/config/bundled-skills/messaging/tools/gmail-trash.ts +15 -9
- package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +51 -22
- package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +62 -26
- package/src/config/bundled-skills/messaging/tools/gmail-vacation.ts +34 -19
- package/src/config/bundled-skills/messaging/tools/google-contacts.ts +32 -16
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +10 -4
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +91 -47
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +21 -9
- package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +9 -3
- package/src/config/bundled-skills/messaging/tools/messaging-draft.ts +30 -17
- package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +10 -4
- package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +14 -6
- package/src/config/bundled-skills/messaging/tools/messaging-read.ts +16 -5
- package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +63 -36
- package/src/config/bundled-skills/messaging/tools/messaging-search.ts +10 -4
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +30 -12
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +48 -29
- package/src/config/bundled-skills/messaging/tools/scan-result-store.ts +20 -6
- package/src/config/bundled-skills/messaging/tools/send-notification.ts +1 -1
- package/src/config/bundled-skills/messaging/tools/sequence-analytics.ts +59 -22
- package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +13 -7
- package/src/config/bundled-skills/messaging/tools/sequence-create.ts +27 -12
- package/src/config/bundled-skills/messaging/tools/sequence-delete.ts +14 -6
- package/src/config/bundled-skills/messaging/tools/sequence-enroll.ts +30 -11
- package/src/config/bundled-skills/messaging/tools/sequence-enrollment-list.ts +16 -8
- package/src/config/bundled-skills/messaging/tools/sequence-get.ts +31 -13
- package/src/config/bundled-skills/messaging/tools/sequence-import.ts +38 -22
- package/src/config/bundled-skills/messaging/tools/sequence-list.ts +16 -7
- package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +29 -10
- package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +16 -8
- package/src/config/bundled-skills/messaging/tools/sequence-update.ts +35 -16
- package/src/config/bundled-skills/messaging/tools/shared.ts +26 -12
- package/src/config/bundled-skills/notifications/tools/send-notification.ts +69 -34
- package/src/config/bundled-skills/notifications/tools/shared.ts +1 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +46 -48
- package/src/config/bundled-skills/phone-calls/tools/call-end.ts +1 -1
- package/src/config/bundled-skills/phone-calls/tools/call-start.ts +1 -1
- package/src/config/bundled-skills/phone-calls/tools/call-status.ts +1 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +91 -51
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +30 -16
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +66 -27
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +89 -42
- package/src/config/bundled-skills/public-ingress/SKILL.md +26 -19
- package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +5 -2
- package/src/config/bundled-skills/reminder/tools/reminder-create.ts +5 -2
- package/src/config/bundled-skills/reminder/tools/reminder-list.ts +5 -2
- package/src/config/bundled-skills/schedule/tools/schedule-create.ts +5 -2
- package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +5 -2
- package/src/config/bundled-skills/schedule/tools/schedule-list.ts +5 -2
- package/src/config/bundled-skills/schedule/tools/schedule-update.ts +5 -2
- package/src/config/bundled-skills/screen-recording/SKILL.md +11 -3
- package/src/config/bundled-skills/self-upgrade/SKILL.md +9 -8
- package/src/config/bundled-skills/slack/TOOLS.json +33 -15
- package/src/config/bundled-skills/slack/tools/shared.ts +7 -5
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +11 -5
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +11 -5
- package/src/config/bundled-skills/slack/tools/slack-configure-channels.ts +46 -16
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +11 -5
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +28 -0
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +12 -6
- package/src/config/bundled-skills/sms-setup/SKILL.md +5 -8
- package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +5 -2
- package/src/config/bundled-skills/subagent/tools/subagent-message.ts +5 -2
- package/src/config/bundled-skills/subagent/tools/subagent-read.ts +5 -2
- package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +5 -2
- package/src/config/bundled-skills/subagent/tools/subagent-status.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-list.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-run.ts +5 -2
- package/src/config/bundled-skills/tasks/tools/task-save.ts +5 -2
- package/src/config/bundled-skills/telegram-setup/SKILL.md +7 -8
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +232 -127
- package/src/config/bundled-skills/twilio-setup/SKILL.md +7 -12
- package/src/config/bundled-skills/twitter/SKILL.md +19 -2
- package/src/config/bundled-skills/voice-setup/SKILL.md +5 -5
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +5 -2
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +5 -2
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +5 -2
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +5 -2
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +5 -2
- package/src/config/bundled-skills/weather/tools/get-weather.ts +5 -2
- package/src/config/calls-schema.ts +108 -63
- package/src/config/computer-use-prompt.ts +7 -7
- package/src/config/core-schema.ts +239 -155
- package/src/config/defaults.ts +2 -2
- package/src/config/elevenlabs-schema.ts +15 -15
- package/src/config/env-registry.ts +33 -33
- package/src/config/feature-flag-registry.json +31 -7
- package/src/config/loader.ts +118 -58
- package/src/config/mcp-schema.ts +29 -15
- package/src/config/memory-schema.ts +434 -229
- package/src/config/notifications-schema.ts +4 -4
- package/src/config/sandbox-schema.ts +2 -2
- package/src/config/schema.ts +12 -2
- package/src/config/skill-state.ts +27 -15
- package/src/config/skills-schema.ts +72 -23
- package/src/config/skills.ts +303 -143
- package/src/config/system-prompt.ts +25 -6
- package/src/config/types.ts +1 -1
- package/src/config/update-bulletin-format.ts +3 -3
- package/src/config/update-bulletin-state.ts +15 -6
- package/src/config/update-bulletin-template-path.ts +8 -4
- package/src/config/update-bulletin.ts +33 -14
- package/src/config/user-reference.ts +8 -8
- package/src/contacts/contact-events.ts +21 -0
- package/src/contacts/contact-store.ts +622 -100
- package/src/contacts/contacts-write.ts +287 -0
- package/src/contacts/index.ts +13 -4
- package/src/contacts/startup-migration.ts +21 -0
- package/src/contacts/types.ts +47 -2
- package/src/context/token-estimator.ts +54 -31
- package/src/context/tool-result-truncation.ts +41 -7
- package/src/context/window-manager.ts +225 -120
- package/src/daemon/approval-generators.ts +83 -55
- package/src/daemon/approved-devices-store.ts +33 -20
- package/src/daemon/assistant-attachments.ts +134 -98
- package/src/daemon/auth-manager.ts +17 -15
- package/src/daemon/classifier.ts +117 -46
- package/src/daemon/computer-use-session.ts +316 -187
- package/src/daemon/config-watcher.ts +91 -44
- package/src/daemon/connection-policy.ts +18 -10
- package/src/daemon/context-overflow-approval.ts +48 -0
- package/src/daemon/context-overflow-policy.ts +50 -0
- package/src/daemon/context-overflow-reducer.ts +300 -0
- package/src/daemon/daemon-control.ts +79 -51
- package/src/daemon/date-context.ts +119 -69
- package/src/daemon/dictation-profile-store.ts +94 -48
- package/src/daemon/dictation-text-processing.ts +33 -12
- package/src/daemon/doordash-steps.ts +92 -49
- package/src/daemon/guardian-action-generators.ts +62 -46
- package/src/daemon/guardian-verification-intent.ts +31 -18
- package/src/daemon/handlers/apps.ts +257 -111
- package/src/daemon/handlers/avatar.ts +20 -15
- package/src/daemon/handlers/computer-use.ts +82 -39
- package/src/daemon/handlers/config-channels.ts +146 -69
- package/src/daemon/handlers/config-heartbeat.ts +114 -59
- package/src/daemon/handlers/config-inbox.ts +277 -106
- package/src/daemon/handlers/config-ingress.ts +127 -55
- package/src/daemon/handlers/config-integrations.ts +145 -88
- package/src/daemon/handlers/config-model.ts +58 -22
- package/src/daemon/handlers/config-platform.ts +40 -16
- package/src/daemon/handlers/config-scheduling.ts +109 -48
- package/src/daemon/handlers/config-slack-channel.ts +67 -35
- package/src/daemon/handlers/config-slack.ts +21 -20
- package/src/daemon/handlers/config-telegram.ts +100 -70
- package/src/daemon/handlers/config-tools.ts +103 -55
- package/src/daemon/handlers/config-trust.ts +50 -20
- package/src/daemon/handlers/config.ts +72 -24
- package/src/daemon/handlers/contacts.ts +163 -0
- package/src/daemon/handlers/diagnostics.ts +90 -48
- package/src/daemon/handlers/documents.ts +74 -46
- package/src/daemon/handlers/guardian-actions.ts +118 -71
- package/src/daemon/handlers/home-base.ts +19 -16
- package/src/daemon/handlers/identity.ts +65 -45
- package/src/daemon/handlers/index.ts +78 -54
- package/src/daemon/handlers/misc.ts +664 -234
- package/src/daemon/handlers/navigate-settings.ts +14 -11
- package/src/daemon/handlers/oauth-connect.ts +48 -35
- package/src/daemon/handlers/open-bundle-handler.ts +31 -24
- package/src/daemon/handlers/pairing.ts +51 -25
- package/src/daemon/handlers/publish.ts +55 -33
- package/src/daemon/handlers/recording.ts +378 -162
- package/src/daemon/handlers/sessions.ts +923 -423
- package/src/daemon/handlers/shared.ts +202 -117
- package/src/daemon/handlers/signing.ts +25 -6
- package/src/daemon/handlers/subagents.ts +117 -56
- package/src/daemon/handlers/twitter-auth.ts +70 -49
- package/src/daemon/handlers/work-items.ts +264 -112
- package/src/daemon/handlers/workspace-files.ts +27 -20
- package/src/daemon/handlers.ts +2 -2
- package/src/daemon/history-repair.ts +16 -15
- package/src/daemon/identity-helpers.ts +4 -4
- package/src/daemon/install-cli-launchers.ts +33 -22
- package/src/daemon/ipc-blob-store.ts +38 -24
- package/src/daemon/ipc-contract/apps.ts +61 -49
- package/src/daemon/ipc-contract/computer-use.ts +47 -37
- package/src/daemon/ipc-contract/contacts.ts +69 -0
- package/src/daemon/ipc-contract/diagnostics.ts +14 -14
- package/src/daemon/ipc-contract/documents.ts +8 -8
- package/src/daemon/ipc-contract/guardian-actions.ts +4 -4
- package/src/daemon/ipc-contract/inbox.ts +16 -16
- package/src/daemon/ipc-contract/integrations.ts +57 -44
- package/src/daemon/ipc-contract/memory.ts +3 -5
- package/src/daemon/ipc-contract/messages.ts +95 -69
- package/src/daemon/ipc-contract/notifications.ts +10 -6
- package/src/daemon/ipc-contract/pairing.ts +8 -8
- package/src/daemon/ipc-contract/schedules.ts +20 -20
- package/src/daemon/ipc-contract/sessions.ts +88 -57
- package/src/daemon/ipc-contract/settings.ts +12 -7
- package/src/daemon/ipc-contract/shared.ts +9 -7
- package/src/daemon/ipc-contract/skills.ts +46 -26
- package/src/daemon/ipc-contract/subagents.ts +9 -9
- package/src/daemon/ipc-contract/trust.ts +11 -11
- package/src/daemon/ipc-contract/work-items.ts +33 -28
- package/src/daemon/ipc-contract/workspace.ts +28 -21
- package/src/daemon/ipc-contract-inventory.json +8 -0
- package/src/daemon/ipc-contract-inventory.ts +29 -26
- package/src/daemon/ipc-contract.ts +111 -44
- package/src/daemon/ipc-handler.ts +27 -19
- package/src/daemon/ipc-protocol.ts +22 -12
- package/src/daemon/ipc-validate.ts +91 -46
- package/src/daemon/lifecycle.ts +25 -1
- package/src/daemon/main.ts +10 -8
- package/src/daemon/media-visibility-policy.ts +3 -1
- package/src/daemon/pairing-store.ts +72 -40
- package/src/daemon/providers-setup.ts +35 -25
- package/src/daemon/recording-executor.ts +37 -30
- package/src/daemon/recording-intent-fallback.ts +58 -28
- package/src/daemon/recording-intent.ts +71 -61
- package/src/daemon/ride-shotgun-handler.ts +201 -121
- package/src/daemon/seed-files.ts +28 -17
- package/src/daemon/server.ts +23 -14
- package/src/daemon/session-agent-loop-handlers.ts +261 -135
- package/src/daemon/session-agent-loop.ts +795 -253
- package/src/daemon/session-attachments.ts +104 -39
- package/src/daemon/session-conflict-gate.ts +72 -28
- package/src/daemon/session-dynamic-profile.ts +36 -22
- package/src/daemon/session-error.ts +50 -45
- package/src/daemon/session-evictor.ts +17 -10
- package/src/daemon/session-history.ts +201 -89
- package/src/daemon/session-lifecycle.ts +79 -42
- package/src/daemon/session-media-retry.ts +89 -41
- package/src/daemon/session-memory.ts +77 -55
- package/src/daemon/session-messaging.ts +261 -111
- package/src/daemon/session-notifiers.ts +57 -45
- package/src/daemon/session-process.ts +370 -154
- package/src/daemon/session-queue-manager.ts +30 -13
- package/src/daemon/session-runtime-assembly.ts +61 -15
- package/src/daemon/session-skill-tools.ts +84 -36
- package/src/daemon/session-slash.ts +178 -113
- package/src/daemon/session-surfaces.ts +498 -211
- package/src/daemon/session-tool-setup.ts +22 -17
- package/src/daemon/session-usage.ts +26 -13
- package/src/daemon/session-workspace.ts +7 -4
- package/src/daemon/session.ts +18 -19
- package/src/daemon/shutdown-handlers.ts +36 -33
- package/src/daemon/tls-certs.ts +90 -57
- package/src/daemon/tool-side-effects.ts +97 -65
- package/src/daemon/trace-emitter.ts +8 -7
- package/src/daemon/video-thumbnail.ts +55 -25
- package/src/daemon/watch-handler.ts +164 -86
- package/src/email/provider.ts +1 -1
- package/src/email/providers/agentmail.ts +87 -45
- package/src/email/providers/index.ts +19 -14
- package/src/email/service.ts +52 -24
- package/src/email/types.ts +2 -2
- package/src/errors.ts +1 -1
- package/src/events/bus.ts +30 -10
- package/src/events/domain-events.ts +19 -13
- package/src/events/index.ts +6 -6
- package/src/events/tool-audit-listener.ts +34 -20
- package/src/events/tool-domain-event-publisher.ts +22 -20
- package/src/events/tool-metrics-listener.ts +26 -21
- package/src/events/tool-notification-listener.ts +5 -5
- package/src/events/tool-profiling-listener.ts +33 -23
- package/src/events/tool-trace-listener.ts +70 -46
- package/src/export/formatter.ts +38 -32
- package/src/followups/followup-store.ts +43 -36
- package/src/followups/index.ts +2 -2
- package/src/followups/types.ts +1 -1
- package/src/gallery/default-gallery.ts +37 -34
- package/src/gallery/gallery-manifest.ts +9 -9
- package/src/heartbeat/heartbeat-service.ts +59 -37
- package/src/home-base/app-link-store.ts +14 -12
- package/src/home-base/bootstrap.ts +14 -8
- package/src/home-base/prebuilt/seed.ts +35 -26
- package/src/home-base/prebuilt-home-base-updater.ts +14 -8
- package/src/hooks/cli.ts +56 -43
- package/src/hooks/config.ts +27 -14
- package/src/hooks/discovery.ts +53 -33
- package/src/hooks/manager.ts +50 -26
- package/src/hooks/runner.ts +35 -29
- package/src/hooks/templates.ts +38 -15
- package/src/hooks/types.ts +13 -13
- package/src/inbound/platform-callback-registration.ts +21 -15
- package/src/inbound/public-ingress-urls.ts +9 -6
- package/src/index.ts +20 -19
- package/src/influencer/client.ts +269 -108
- package/src/instrument.ts +3 -1
- package/src/logfire.ts +64 -39
- package/src/mcp/client.ts +107 -55
- package/src/mcp/manager.ts +45 -18
- package/src/mcp/mcp-oauth-provider.ts +114 -62
- package/src/media/gemini-image-service.ts +28 -21
- package/src/memory/account-store.ts +16 -9
- package/src/memory/admin.ts +87 -57
- package/src/memory/app-git-service.ts +77 -47
- package/src/memory/app-store.ts +151 -77
- package/src/memory/attachments-store.ts +123 -53
- package/src/memory/canonical-guardian-store.ts +190 -48
- package/src/memory/channel-delivery-store.ts +5 -5
- package/src/memory/channel-guardian-store.ts +31 -16
- package/src/memory/checkpoints.ts +14 -7
- package/src/memory/clarification-resolver.ts +219 -104
- package/src/memory/conflict-intent.ts +74 -23
- package/src/memory/conflict-policy.ts +20 -7
- package/src/memory/conflict-store.ts +144 -94
- package/src/memory/contradiction-checker.ts +257 -132
- package/src/memory/conversation-attention-store.ts +72 -32
- package/src/memory/conversation-bootstrap.ts +28 -0
- package/src/memory/conversation-crud.ts +12 -5
- package/src/memory/conversation-display-order-migration.ts +7 -7
- package/src/memory/conversation-key-store.ts +18 -13
- package/src/memory/conversation-queries.ts +130 -52
- package/src/memory/conversation-store.ts +43 -26
- package/src/memory/conversation-title-service.ts +89 -66
- package/src/memory/db-init.ts +90 -2
- package/src/memory/db.ts +10 -3
- package/src/memory/delivery-channels.ts +12 -6
- package/src/memory/delivery-crud.ts +26 -12
- package/src/memory/delivery-status.ts +19 -16
- package/src/memory/embedding-backend.ts +205 -77
- package/src/memory/embedding-gemini.ts +23 -10
- package/src/memory/embedding-local.ts +89 -44
- package/src/memory/embedding-ollama.ts +25 -13
- package/src/memory/embedding-openai.ts +20 -11
- package/src/memory/embedding-runtime-manager.ts +163 -90
- package/src/memory/entity-extractor.ts +185 -123
- package/src/memory/external-conversation-store.ts +30 -12
- package/src/memory/fingerprint.ts +2 -2
- package/src/memory/fts-reconciler.ts +57 -28
- package/src/memory/guardian-action-store.ts +162 -100
- package/src/memory/guardian-approvals.ts +63 -129
- package/src/memory/guardian-rate-limits.ts +20 -9
- package/src/memory/guardian-verification.ts +82 -35
- package/src/memory/indexer.ts +96 -55
- package/src/memory/ingress-invite-store.ts +28 -169
- package/src/memory/items-extractor.ts +313 -157
- package/src/memory/job-handlers/backfill.ts +116 -63
- package/src/memory/job-handlers/cleanup.ts +64 -41
- package/src/memory/job-handlers/conflict.ts +90 -49
- package/src/memory/job-handlers/embedding.ts +32 -17
- package/src/memory/job-handlers/extraction.ts +58 -33
- package/src/memory/job-handlers/index-maintenance.ts +31 -17
- package/src/memory/job-handlers/media-processing.ts +65 -24
- package/src/memory/job-handlers/summarization.ts +186 -128
- package/src/memory/job-utils.ts +100 -57
- package/src/memory/jobs-store.ts +235 -142
- package/src/memory/jobs-worker.ts +167 -83
- package/src/memory/llm-request-log-store.ts +13 -11
- package/src/memory/llm-usage-store.ts +35 -26
- package/src/memory/media-store.ts +151 -44
- package/src/memory/message-content.ts +28 -18
- package/src/memory/migrations/001-job-deferrals.ts +11 -5
- package/src/memory/migrations/002-tool-invocations-fk.ts +14 -6
- package/src/memory/migrations/003-memory-fts-backfill.ts +11 -5
- package/src/memory/migrations/004-entity-relation-dedup.ts +17 -11
- package/src/memory/migrations/005-fingerprint-scope-unique.ts +36 -21
- package/src/memory/migrations/006-scope-salted-fingerprints.ts +35 -20
- package/src/memory/migrations/007-assistant-id-to-self.ts +40 -27
- package/src/memory/migrations/008-remove-assistant-id-columns.ts +58 -36
- package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +36 -22
- package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +21 -11
- package/src/memory/migrations/011-call-sessions-provider-sid-dedup.ts +30 -15
- package/src/memory/migrations/012-call-sessions-add-initiated-from.ts +4 -2
- package/src/memory/migrations/013-guardian-action-tables.ts +29 -11
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +35 -21
- package/src/memory/migrations/015-drop-active-search-index.ts +17 -11
- package/src/memory/migrations/016-memory-segments-indexes.ts +7 -3
- package/src/memory/migrations/017-memory-items-indexes.ts +4 -2
- package/src/memory/migrations/018-remaining-table-indexes.ts +13 -5
- package/src/memory/migrations/019-notification-tables-schema-migration.ts +34 -20
- package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +87 -53
- package/src/memory/migrations/021-conversation-status-indexes.ts +7 -3
- package/src/memory/migrations/022-add-origin-interface.ts +4 -2
- package/src/memory/migrations/023-memory-item-sources-indexes.ts +4 -2
- package/src/memory/migrations/024-embedding-vector-blob.ts +34 -18
- package/src/memory/migrations/025-messages-fts-backfill.ts +11 -5
- package/src/memory/migrations/026-guardian-verification-sessions.ts +80 -14
- package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +42 -26
- package/src/memory/migrations/027-notification-delivery-pairing-columns.ts +22 -8
- package/src/memory/migrations/027a-guardian-bootstrap-token.ts +11 -3
- package/src/memory/migrations/028-call-session-mode.ts +13 -3
- package/src/memory/migrations/028-notification-delivery-client-ack.ts +22 -8
- package/src/memory/migrations/029-channel-inbound-delivered-segments.ts +7 -3
- package/src/memory/migrations/030-guardian-action-followup.ts +46 -8
- package/src/memory/migrations/030-guardian-verification-purpose.ts +4 -2
- package/src/memory/migrations/031-conversations-thread-type-index.ts +4 -2
- package/src/memory/migrations/032-guardian-delivery-conversation-index.ts +4 -2
- package/src/memory/migrations/032-notification-delivery-thread-decision.ts +22 -8
- package/src/memory/migrations/033-scoped-approval-grants.ts +1 -1
- package/src/memory/migrations/034-guardian-action-tool-metadata.ts +15 -3
- package/src/memory/migrations/035-guardian-action-supersession.ts +15 -3
- package/src/memory/migrations/036-normalize-phone-identities.ts +101 -87
- package/src/memory/migrations/037-voice-invite-columns.ts +22 -4
- package/src/memory/migrations/038-actor-token-records.ts +5 -9
- package/src/memory/migrations/039-actor-refresh-token-records.ts +7 -13
- package/src/memory/migrations/100-core-tables.ts +1 -1
- package/src/memory/migrations/101-watchers-and-logs.ts +1 -1
- package/src/memory/migrations/103-complex-migrations.ts +9 -9
- package/src/memory/migrations/104-core-indexes.ts +188 -64
- package/src/memory/migrations/105-contacts-and-triage.ts +28 -10
- package/src/memory/migrations/106-call-sessions.ts +58 -16
- package/src/memory/migrations/107-followups.ts +16 -6
- package/src/memory/migrations/108-tasks-and-work-items.ts +43 -11
- package/src/memory/migrations/109-external-conversation-bindings.ts +11 -5
- package/src/memory/migrations/110-channel-guardian.ts +48 -10
- package/src/memory/migrations/111-media-assets.ts +52 -18
- package/src/memory/migrations/112-assistant-inbox.ts +32 -12
- package/src/memory/migrations/113-late-migrations.ts +12 -12
- package/src/memory/migrations/114-notifications.ts +28 -12
- package/src/memory/migrations/115-sequences.ts +10 -4
- package/src/memory/migrations/116-messages-fts.ts +1 -1
- package/src/memory/migrations/117-conversation-attention.ts +16 -6
- package/src/memory/migrations/118-reminder-routing-intent.ts +7 -3
- package/src/memory/migrations/119-schema-indexes-and-columns.ts +35 -15
- package/src/memory/migrations/120-fk-cascade-rebuilds.ts +36 -17
- package/src/memory/migrations/121-canonical-guardian-requests.ts +25 -9
- package/src/memory/migrations/122-canonical-guardian-requester-chat-id.ts +11 -3
- package/src/memory/migrations/123-canonical-guardian-deliveries-destination-index.ts +4 -2
- package/src/memory/migrations/124-voice-invite-display-metadata.ts +15 -3
- package/src/memory/migrations/125-guardian-principal-id-columns.ts +22 -4
- package/src/memory/migrations/126-backfill-guardian-principal-id.ts +174 -126
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +58 -42
- package/src/memory/migrations/128-contacts-role-principal.ts +26 -0
- package/src/memory/migrations/129-contact-channels-access-fields.ts +105 -0
- package/src/memory/migrations/130-contact-channels-type-ext-chat-id-index.ts +15 -0
- package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +134 -0
- package/src/memory/migrations/132-contacts-assistant-id.ts +21 -0
- package/src/memory/migrations/index.ts +82 -73
- package/src/memory/migrations/registry.ts +53 -37
- package/src/memory/migrations/validate-migration-state.ts +73 -46
- package/src/memory/profile-compiler.ts +58 -24
- package/src/memory/published-pages-store.ts +12 -16
- package/src/memory/qdrant-circuit-breaker.ts +28 -20
- package/src/memory/qdrant-client.ts +99 -63
- package/src/memory/qdrant-manager.ts +89 -57
- package/src/memory/query-builder.ts +9 -7
- package/src/memory/raw-query.ts +63 -14
- package/src/memory/recall-cache.ts +15 -8
- package/src/memory/retrieval-budget.ts +0 -1
- package/src/memory/retriever.ts +385 -192
- package/src/memory/schema-migration.ts +1 -1
- package/src/memory/schema.ts +44 -56
- package/src/memory/scoped-approval-grants.ts +99 -45
- package/src/memory/search/entity.ts +102 -40
- package/src/memory/search/formatting.ts +70 -52
- package/src/memory/search/lexical.ts +82 -43
- package/src/memory/search/ranking.ts +103 -39
- package/src/memory/search/semantic.ts +59 -35
- package/src/memory/search/types.ts +8 -8
- package/src/memory/segmenter.ts +20 -12
- package/src/memory/shared-app-links-store.ts +21 -16
- package/src/memory/task-memory-cleanup.ts +18 -8
- package/src/memory/tool-usage-store.ts +27 -19
- package/src/memory/validation.ts +4 -2
- package/src/messaging/activity-analyzer.ts +7 -7
- package/src/messaging/draft-store.ts +13 -10
- package/src/messaging/email-classifier.ts +73 -37
- package/src/messaging/index.ts +3 -3
- package/src/messaging/outreach-classifier.ts +76 -38
- package/src/messaging/provider-types.ts +2 -4
- package/src/messaging/provider.ts +37 -8
- package/src/messaging/providers/gmail/adapter.ts +183 -66
- package/src/messaging/providers/gmail/client.ts +3 -1
- package/src/messaging/providers/gmail/mime-builder.ts +21 -19
- package/src/messaging/providers/gmail/people-client.ts +22 -9
- package/src/messaging/providers/gmail/types.ts +6 -6
- package/src/messaging/providers/slack/adapter.ts +93 -43
- package/src/messaging/providers/slack/client.ts +100 -41
- package/src/messaging/providers/slack/types.ts +6 -0
- package/src/messaging/providers/sms/adapter.ts +76 -40
- package/src/messaging/providers/sms/client.ts +4 -4
- package/src/messaging/providers/telegram-bot/adapter.ts +52 -30
- package/src/messaging/providers/telegram-bot/client.ts +7 -7
- package/src/messaging/providers/whatsapp/adapter.ts +58 -31
- package/src/messaging/providers/whatsapp/client.ts +4 -4
- package/src/messaging/registry.ts +9 -5
- package/src/messaging/style-analyzer.ts +69 -39
- package/src/messaging/thread-summarizer.ts +101 -53
- package/src/messaging/triage-engine.ts +111 -82
- package/src/messaging/types.ts +10 -10
- package/src/migrations/config-merge.ts +18 -10
- package/src/migrations/data-layout.ts +35 -22
- package/src/migrations/data-merge.ts +17 -7
- package/src/migrations/hooks-merge.ts +43 -16
- package/src/migrations/index.ts +6 -6
- package/src/migrations/log.ts +9 -5
- package/src/migrations/skills-merge.ts +17 -7
- package/src/migrations/workspace-layout.ts +39 -25
- package/src/notifications/AGENTS.md +5 -0
- package/src/notifications/adapters/macos.ts +21 -14
- package/src/notifications/adapters/sms.ts +28 -15
- package/src/notifications/adapters/telegram.ts +24 -15
- package/src/notifications/broadcaster.ts +108 -52
- package/src/notifications/conversation-pairing.ts +64 -29
- package/src/notifications/copy-composer.ts +165 -95
- package/src/notifications/decision-engine.ts +353 -147
- package/src/notifications/decisions-store.ts +26 -10
- package/src/notifications/deliveries-store.ts +23 -13
- package/src/notifications/destination-resolver.ts +42 -24
- package/src/notifications/deterministic-checks.ts +78 -27
- package/src/notifications/emit-signal.ts +83 -45
- package/src/notifications/events-store.ts +13 -7
- package/src/notifications/guardian-question-mode.ts +125 -75
- package/src/notifications/preference-extractor.ts +85 -53
- package/src/notifications/preference-summary.ts +31 -18
- package/src/notifications/preferences-store.ts +29 -18
- package/src/notifications/runtime-dispatch.ts +22 -12
- package/src/notifications/signal.ts +4 -4
- package/src/notifications/thread-candidates.ts +59 -23
- package/src/notifications/thread-seed-composer.ts +45 -27
- package/src/notifications/types.ts +19 -10
- package/src/oauth/connect-orchestrator.ts +105 -54
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/provider-profiles.ts +80 -59
- package/src/oauth/scope-policy.ts +5 -2
- package/src/oauth/token-persistence.ts +58 -24
- package/src/outbound-proxy/certs.ts +284 -0
- package/src/outbound-proxy/config.ts +94 -0
- package/src/outbound-proxy/connect-tunnel.ts +84 -0
- package/src/outbound-proxy/health.ts +62 -0
- package/src/outbound-proxy/host-pattern-match.ts +67 -0
- package/src/outbound-proxy/http-forwarder.ts +162 -0
- package/src/outbound-proxy/index.ts +80 -0
- package/src/outbound-proxy/logging.ts +193 -0
- package/src/outbound-proxy/mitm-handler.ts +292 -0
- package/src/outbound-proxy/policy.ts +172 -0
- package/src/outbound-proxy/router.ts +64 -0
- package/src/outbound-proxy/server.ts +145 -0
- package/src/outbound-proxy/types.ts +150 -0
- package/src/permissions/checker.ts +481 -189
- package/src/permissions/defaults.ts +135 -108
- package/src/permissions/prompter.ts +53 -27
- package/src/permissions/secret-prompter.ts +21 -15
- package/src/permissions/shell-identity.ts +47 -16
- package/src/permissions/trust-store.ts +185 -73
- package/src/permissions/types.ts +22 -12
- package/src/permissions/workspace-policy.ts +47 -38
- package/src/playbooks/index.ts +10 -2
- package/src/playbooks/playbook-compiler.ts +30 -24
- package/src/playbooks/types.ts +11 -8
- package/src/providers/anthropic/client.ts +325 -168
- package/src/providers/failover.ts +57 -22
- package/src/providers/fireworks/client.ts +9 -5
- package/src/providers/gemini/client.ts +61 -39
- package/src/providers/model-intents.ts +40 -33
- package/src/providers/ollama/client.ts +7 -7
- package/src/providers/openai/client.ts +106 -68
- package/src/providers/openrouter/client.ts +9 -5
- package/src/providers/provider-send-message.ts +59 -27
- package/src/providers/ratelimit.ts +25 -8
- package/src/providers/registry.ts +86 -38
- package/src/providers/retry.ts +84 -36
- package/src/providers/stream-timeout.ts +5 -3
- package/src/providers/types.ts +7 -6
- package/src/runtime/AGENTS.md +42 -0
- package/src/runtime/access-request-helper.ts +118 -68
- package/src/runtime/actor-refresh-token-store.ts +21 -16
- package/src/runtime/actor-token-store.ts +25 -18
- package/src/runtime/actor-trust-resolver.ts +183 -80
- package/src/runtime/approval-conversation-turn.ts +39 -26
- package/src/runtime/approval-message-composer.ts +116 -84
- package/src/runtime/assistant-event-hub.ts +25 -6
- package/src/runtime/assistant-event.ts +4 -4
- package/src/runtime/assistant-scope.ts +1 -1
- package/src/runtime/auth/__tests__/guard-tests.test.ts +36 -14
- package/src/runtime/auth/context.ts +8 -7
- package/src/runtime/auth/credential-service.ts +60 -38
- package/src/runtime/auth/external-assistant-id.ts +16 -8
- package/src/runtime/auth/index.ts +23 -16
- package/src/runtime/auth/route-policy.ts +170 -104
- package/src/runtime/auth/scopes.ts +22 -29
- package/src/runtime/auth/subject.ts +19 -13
- package/src/runtime/auth/token-service.ts +3 -3
- package/src/runtime/auth/types.ts +23 -23
- package/src/runtime/channel-approval-parser.ts +37 -14
- package/src/runtime/channel-approval-types.ts +12 -4
- package/src/runtime/channel-approvals.ts +41 -23
- package/src/runtime/channel-guardian-service.ts +144 -103
- package/src/runtime/channel-invite-transport.ts +4 -2
- package/src/runtime/channel-invite-transports/telegram.ts +16 -10
- package/src/runtime/channel-invite-transports/voice.ts +7 -7
- package/src/runtime/channel-readiness-service.ts +139 -90
- package/src/runtime/channel-readiness-types.ts +4 -2
- package/src/runtime/channel-reply-delivery.ts +21 -11
- package/src/runtime/channel-retry-sweep.ts +111 -62
- package/src/runtime/confirmation-request-guardian-bridge.ts +73 -54
- package/src/runtime/gateway-client.ts +86 -53
- package/src/runtime/guardian-action-conversation-turn.ts +34 -18
- package/src/runtime/guardian-action-followup-executor.ts +115 -45
- package/src/runtime/guardian-action-grant-minter.ts +40 -24
- package/src/runtime/guardian-action-message-composer.ts +105 -84
- package/src/runtime/guardian-decision-types.ts +28 -13
- package/src/runtime/guardian-outbound-actions.ts +9 -0
- package/src/runtime/guardian-reply-router.ts +274 -145
- package/src/runtime/guardian-vellum-migration.ts +38 -24
- package/src/runtime/guardian-verification-templates.ts +8 -11
- package/src/runtime/http-router.ts +175 -0
- package/src/runtime/http-server.ts +931 -669
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/ingress-service.ts +182 -89
- package/src/runtime/invite-redemption-service.ts +211 -134
- package/src/runtime/invite-redemption-templates.ts +18 -11
- package/src/runtime/local-actor-identity.ts +73 -55
- package/src/runtime/middleware/auth.ts +25 -14
- package/src/runtime/middleware/error-handler.ts +15 -11
- package/src/runtime/middleware/rate-limiter.ts +23 -17
- package/src/runtime/middleware/request-logger.ts +4 -4
- package/src/runtime/middleware/twilio-validation.ts +29 -20
- package/src/runtime/migrations/migration-transport.ts +575 -0
- package/src/runtime/migrations/migration-wizard.ts +715 -0
- package/src/runtime/migrations/rebind-secrets-screen.ts +351 -0
- package/src/runtime/migrations/transfer-progress-screen.ts +321 -0
- package/src/runtime/migrations/validation-results-screen.ts +467 -0
- package/src/runtime/migrations/vbundle-builder.ts +295 -0
- package/src/runtime/migrations/vbundle-import-analyzer.ts +212 -0
- package/src/runtime/migrations/vbundle-importer.ts +339 -0
- package/src/runtime/migrations/vbundle-validator.ts +356 -0
- package/src/runtime/pending-interactions.ts +16 -7
- package/src/runtime/routes/access-request-decision.ts +73 -52
- package/src/runtime/routes/app-routes.ts +56 -38
- package/src/runtime/routes/approval-routes.ts +165 -74
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +930 -0
- package/src/runtime/routes/approval-strategies/guardian-legacy-fallback-strategy.ts +82 -0
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +151 -0
- package/src/runtime/routes/attachment-routes.ts +59 -48
- package/src/runtime/routes/brain-graph-routes.ts +85 -69
- package/src/runtime/routes/call-routes.ts +79 -38
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +10 -10
- package/src/runtime/routes/channel-delivery-routes.ts +19 -14
- package/src/runtime/routes/channel-guardian-routes.ts +3 -3
- package/src/runtime/routes/channel-inbound-routes.ts +2 -2
- package/src/runtime/routes/channel-readiness-routes.ts +12 -6
- package/src/runtime/routes/channel-route-shared.ts +33 -25
- package/src/runtime/routes/channel-routes.ts +4 -6
- package/src/runtime/routes/contact-routes.ts +205 -16
- package/src/runtime/routes/conversation-attention-routes.ts +57 -28
- package/src/runtime/routes/conversation-routes.ts +321 -174
- package/src/runtime/routes/debug-routes.ts +14 -10
- package/src/runtime/routes/events-routes.ts +90 -57
- package/src/runtime/routes/global-search-routes.ts +266 -0
- package/src/runtime/routes/guardian-action-routes.ts +147 -56
- package/src/runtime/routes/guardian-approval-interception.ts +255 -880
- package/src/runtime/routes/guardian-approval-prompt.ts +40 -24
- package/src/runtime/routes/guardian-approval-reply-helpers.ts +135 -0
- package/src/runtime/routes/guardian-bootstrap-routes.ts +55 -36
- package/src/runtime/routes/guardian-expiry-sweep.ts +63 -37
- package/src/runtime/routes/guardian-refresh-routes.ts +40 -19
- package/src/runtime/routes/identity-routes.ts +71 -42
- package/src/runtime/routes/inbound-conversation.ts +17 -11
- package/src/runtime/routes/inbound-message-handler.ts +278 -1460
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +658 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +492 -0
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +214 -0
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +116 -0
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +167 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +185 -0
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +132 -0
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +340 -0
- package/src/runtime/routes/ingress-routes.ts +34 -23
- package/src/runtime/routes/integration-routes.ts +60 -21
- package/src/runtime/routes/migration-routes.ts +434 -0
- package/src/runtime/routes/pairing-routes.ts +157 -79
- package/src/runtime/routes/secret-routes.ts +6 -2
- package/src/runtime/routes/twilio-routes.ts +443 -249
- package/src/runtime/tool-grant-request-helper.ts +36 -27
- package/src/runtime/{guardian-context-resolver.ts → trust-context-resolver.ts} +29 -41
- package/src/schedule/integration-status.ts +44 -9
- package/src/schedule/recurrence-engine.ts +47 -24
- package/src/schedule/recurrence-types.ts +12 -7
- package/src/schedule/schedule-store.ts +166 -83
- package/src/schedule/scheduler.ts +26 -22
- package/src/security/encrypted-store.ts +68 -38
- package/src/security/keychain.ts +183 -120
- package/src/security/oauth-callback-registry.ts +3 -3
- package/src/security/oauth2.ts +226 -138
- package/src/security/redaction.ts +24 -24
- package/src/security/secret-allowlist.ts +46 -21
- package/src/security/secret-ingress.ts +15 -7
- package/src/security/secret-scanner.ts +193 -104
- package/src/security/secure-keys.ts +9 -3
- package/src/security/token-manager.ts +99 -40
- package/src/security/tool-approval-digest.ts +3 -3
- package/src/sequence/analytics.ts +52 -27
- package/src/sequence/engine.ts +135 -72
- package/src/sequence/guardrails.ts +32 -20
- package/src/sequence/importer.ts +75 -37
- package/src/sequence/reply-matcher.ts +36 -18
- package/src/sequence/store.ts +137 -75
- package/src/sequence/types.ts +30 -16
- package/src/services/published-app-updater.ts +26 -16
- package/src/services/vercel-deploy.ts +19 -15
- package/src/skills/active-skill-tools.ts +3 -3
- package/src/skills/clawhub.ts +178 -90
- package/src/skills/include-graph.ts +24 -17
- package/src/skills/managed-store.ts +89 -42
- package/src/skills/path-classifier.ts +10 -10
- package/src/skills/remote-skill-policy.ts +31 -22
- package/src/skills/slash-commands.ts +36 -30
- package/src/skills/tool-manifest.ts +60 -31
- package/src/skills/version-hash.ts +25 -15
- package/src/slack/slack-webhook.ts +19 -15
- package/src/subagent/index.ts +4 -8
- package/src/subagent/manager.ts +119 -69
- package/src/subagent/types.ts +9 -12
- package/src/swarm/backend-claude-code.ts +124 -45
- package/src/swarm/checkpoint.ts +36 -16
- package/src/swarm/graph-utils.ts +1 -3
- package/src/swarm/index.ts +38 -19
- package/src/swarm/limits.ts +13 -4
- package/src/swarm/orchestrator.ts +108 -57
- package/src/swarm/plan-validator.ts +23 -17
- package/src/swarm/router-planner.ts +51 -22
- package/src/swarm/router-prompts.ts +4 -1
- package/src/swarm/synthesizer.ts +26 -18
- package/src/swarm/types.ts +14 -4
- package/src/swarm/worker-backend.ts +36 -26
- package/src/swarm/worker-prompts.ts +13 -9
- package/src/swarm/worker-runner.ts +40 -34
- package/src/tasks/candidate-store.ts +14 -6
- package/src/tasks/ephemeral-permissions.ts +9 -5
- package/src/tasks/task-compiler.ts +41 -38
- package/src/tasks/task-runner.ts +54 -26
- package/src/tasks/task-scheduler.ts +1 -1
- package/src/tasks/task-store.ts +20 -7
- package/src/tasks/tool-sanitizer.ts +3 -3
- package/src/tools/apps/definitions.ts +23 -15
- package/src/tools/apps/executors.ts +118 -37
- package/src/tools/apps/open-proxy.ts +5 -5
- package/src/tools/apps/registry.ts +2 -2
- package/src/tools/assets/materialize.ts +59 -41
- package/src/tools/assets/search.ts +86 -48
- package/src/tools/browser/api-map.ts +52 -36
- package/src/tools/browser/auth-cache.ts +21 -18
- package/src/tools/browser/auth-detector.ts +43 -28
- package/src/tools/browser/auto-navigate.ts +149 -68
- package/src/tools/browser/browser-execution.ts +9 -3
- package/src/tools/browser/headless-browser.ts +287 -150
- package/src/tools/browser/jit-auth.ts +37 -21
- package/src/tools/browser/network-recorder.ts +138 -56
- package/src/tools/browser/recording-store.ts +22 -15
- package/src/tools/browser/runtime-check.ts +8 -5
- package/src/tools/browser/x-auto-navigate.ts +88 -47
- package/src/tools/calls/call-end.ts +9 -6
- package/src/tools/calls/call-start.ts +30 -20
- package/src/tools/calls/call-status.ts +8 -5
- package/src/tools/claude-code/claude-code.ts +301 -165
- package/src/tools/computer-use/definitions.ts +159 -130
- package/src/tools/computer-use/registry.ts +2 -2
- package/src/tools/computer-use/request-computer-control.ts +21 -13
- package/src/tools/computer-use/skill-proxy-bridge.ts +1 -1
- package/src/tools/credentials/account-registry.ts +52 -35
- package/src/tools/credentials/broker-types.ts +1 -1
- package/src/tools/credentials/broker.ts +97 -55
- package/src/tools/credentials/domain-policy.ts +5 -2
- package/src/tools/credentials/host-pattern-match.ts +15 -8
- package/src/tools/credentials/metadata-store.ts +93 -43
- package/src/tools/credentials/policy-types.ts +5 -2
- package/src/tools/credentials/policy-validate.ts +21 -14
- package/src/tools/credentials/post-connect-hooks.ts +18 -7
- package/src/tools/credentials/resolve.ts +11 -10
- package/src/tools/credentials/selection.ts +30 -25
- package/src/tools/credentials/tool-policy.ts +5 -2
- package/src/tools/credentials/vault.ts +452 -183
- package/src/tools/document/document-tool.ts +23 -17
- package/src/tools/document/editor-template.ts +12 -7
- package/src/tools/execution-target.ts +13 -10
- package/src/tools/execution-timeout.ts +6 -5
- package/src/tools/executor.ts +141 -74
- package/src/tools/filesystem/edit.ts +82 -45
- package/src/tools/filesystem/fuzzy-match.ts +70 -32
- package/src/tools/filesystem/read.ts +46 -28
- package/src/tools/filesystem/view-image.ts +86 -42
- package/src/tools/filesystem/write.ts +53 -32
- package/src/tools/followups/followup_create.ts +43 -17
- package/src/tools/followups/followup_list.ts +28 -13
- package/src/tools/followups/followup_resolve.ts +9 -6
- package/src/tools/guardian-control-plane-policy.ts +15 -14
- package/src/tools/host-filesystem/edit.ts +77 -42
- package/src/tools/host-filesystem/read.ts +52 -33
- package/src/tools/host-filesystem/write.ts +50 -29
- package/src/tools/host-terminal/host-shell.ts +97 -61
- package/src/tools/mcp/mcp-tool-factory.ts +21 -14
- package/src/tools/memory/definitions.ts +60 -28
- package/src/tools/memory/handlers.ts +149 -77
- package/src/tools/memory/register.ts +39 -16
- package/src/tools/network/__tests__/web-search.test.ts +236 -177
- package/src/tools/network/domain-normalize.ts +13 -9
- package/src/tools/network/script-proxy/__tests__/logging.test.ts +193 -123
- package/src/tools/network/script-proxy/__tests__/policy.test.ts +225 -127
- package/src/tools/network/script-proxy/index.ts +1 -17
- package/src/tools/network/script-proxy/session-manager.ts +151 -84
- package/src/tools/network/url-safety.ts +56 -34
- package/src/tools/network/web-fetch.ts +273 -155
- package/src/tools/network/web-search.ts +166 -81
- package/src/tools/permission-checker.ts +6 -25
- package/src/tools/policy-context.ts +8 -5
- package/src/tools/registry.ts +73 -46
- package/src/tools/reminder/reminder-store.ts +65 -44
- package/src/tools/reminder/reminder.ts +76 -35
- package/src/tools/schedule/create.ts +44 -21
- package/src/tools/schedule/delete.ts +8 -5
- package/src/tools/schedule/list.ts +39 -19
- package/src/tools/schedule/update.ts +49 -26
- package/src/tools/secret-detection-handler.ts +130 -49
- package/src/tools/sensitive-output-placeholders.ts +15 -8
- package/src/tools/shared/filesystem/edit-engine.ts +45 -14
- package/src/tools/shared/filesystem/errors.ts +18 -18
- package/src/tools/shared/filesystem/file-ops-service.ts +59 -32
- package/src/tools/shared/filesystem/format-diff.ts +21 -11
- package/src/tools/shared/filesystem/path-policy.ts +17 -13
- package/src/tools/shared/filesystem/size-guard.ts +8 -4
- package/src/tools/shared/filesystem/types.ts +2 -2
- package/src/tools/shared/shell-output.ts +4 -3
- package/src/tools/side-effects.ts +36 -28
- package/src/tools/skills/delete-managed.ts +30 -17
- package/src/tools/skills/load.ts +88 -46
- package/src/tools/skills/sandbox-runner.ts +62 -46
- package/src/tools/skills/scaffold-managed.ts +98 -48
- package/src/tools/skills/script-contract.ts +5 -2
- package/src/tools/skills/skill-script-runner.ts +29 -13
- package/src/tools/skills/skill-tool-factory.ts +20 -10
- package/src/tools/subagent/abort.ts +10 -4
- package/src/tools/subagent/message.ts +14 -8
- package/src/tools/subagent/read.ts +20 -11
- package/src/tools/subagent/spawn.ts +14 -6
- package/src/tools/subagent/status.ts +7 -4
- package/src/tools/swarm/delegate.ts +75 -49
- package/src/tools/system/avatar-generator.ts +46 -33
- package/src/tools/system/navigate-settings.ts +29 -19
- package/src/tools/system/open-system-settings.ts +30 -20
- package/src/tools/system/request-permission.ts +59 -44
- package/src/tools/system/version.ts +27 -16
- package/src/tools/system/voice-config.ts +116 -53
- package/src/tools/tasks/index.ts +8 -8
- package/src/tools/tasks/task-delete.ts +61 -22
- package/src/tools/tasks/task-list.ts +23 -11
- package/src/tools/tasks/task-run.ts +41 -16
- package/src/tools/tasks/task-save.ts +27 -10
- package/src/tools/tasks/work-item-enqueue.ts +114 -48
- package/src/tools/tasks/work-item-list.ts +20 -10
- package/src/tools/tasks/work-item-remove.ts +49 -15
- package/src/tools/tasks/work-item-run.ts +34 -13
- package/src/tools/tasks/work-item-update.ts +84 -31
- package/src/tools/terminal/backends/native.ts +64 -35
- package/src/tools/terminal/backends/types.ts +6 -2
- package/src/tools/terminal/parser.ts +200 -125
- package/src/tools/terminal/safe-env.ts +27 -21
- package/src/tools/terminal/sandbox-diagnostics.ts +31 -13
- package/src/tools/terminal/sandbox.ts +10 -6
- package/src/tools/terminal/shell.ts +124 -68
- package/src/tools/tool-approval-handler.ts +193 -138
- package/src/tools/types.ts +43 -23
- package/src/tools/ui-surface/definitions.ts +124 -89
- package/src/tools/ui-surface/registry.ts +2 -2
- package/src/tools/watch/screen-watch.ts +50 -32
- package/src/tools/watch/watch-state.ts +41 -15
- package/src/tools/watcher/create.ts +37 -15
- package/src/tools/watcher/delete.ts +9 -6
- package/src/tools/watcher/digest.ts +10 -6
- package/src/tools/watcher/list.ts +37 -14
- package/src/tools/watcher/update.ts +33 -18
- package/src/tools/weather/service.ts +331 -174
- package/src/twitter/client.ts +261 -138
- package/src/twitter/oauth-client.ts +17 -13
- package/src/twitter/router.ts +51 -23
- package/src/twitter/session.ts +27 -18
- package/src/types/qrcode.d.ts +6 -3
- package/src/usage/actors.ts +16 -16
- package/src/usage/types.ts +3 -3
- package/src/util/bundled-asset.ts +10 -6
- package/src/util/canonicalize-identity.ts +11 -4
- package/src/util/clipboard.ts +7 -7
- package/src/util/content-id.ts +3 -3
- package/src/util/debounce.ts +3 -2
- package/src/util/diff.ts +55 -33
- package/src/util/errors.ts +26 -26
- package/src/util/fs.ts +8 -2
- package/src/util/log-redact.ts +12 -12
- package/src/util/logger.ts +112 -51
- package/src/util/network-info.ts +13 -5
- package/src/util/object.ts +4 -2
- package/src/util/phone.ts +4 -4
- package/src/util/platform.ts +80 -58
- package/src/util/pricing.ts +49 -31
- package/src/util/retry.ts +18 -7
- package/src/util/row-mapper.ts +7 -4
- package/src/util/silently.ts +7 -4
- package/src/util/spawn.ts +48 -0
- package/src/util/spinner.ts +9 -7
- package/src/util/time.ts +16 -3
- package/src/util/truncate.ts +1 -1
- package/src/util/voice-code.ts +6 -4
- package/src/util/xml.ts +5 -1
- package/src/version.ts +12 -8
- package/src/watcher/engine.ts +71 -44
- package/src/watcher/provider-registry.ts +1 -1
- package/src/watcher/providers/github.ts +40 -23
- package/src/watcher/providers/gmail.ts +59 -38
- package/src/watcher/providers/google-calendar.ts +62 -48
- package/src/watcher/providers/linear.ts +219 -150
- package/src/watcher/providers/slack.ts +93 -27
- package/src/watcher/watcher-store.ts +75 -55
- package/src/work-items/work-item-runner.ts +62 -29
- package/src/work-items/work-item-store.ts +137 -47
- package/src/workspace/commit-message-enrichment-service.ts +65 -25
- package/src/workspace/commit-message-provider.ts +14 -12
- package/src/workspace/git-service.ts +355 -239
- package/src/workspace/heartbeat-service.ts +74 -37
- package/src/workspace/provider-commit-message-generator.ts +95 -70
- package/src/workspace/top-level-renderer.ts +10 -8
- package/src/workspace/top-level-scanner.ts +9 -3
- package/src/workspace/turn-commit.ts +63 -36
- package/src/__tests__/ingress-member-store.test.ts +0 -294
- package/src/__tests__/script-proxy-router.test.ts +0 -215
- package/src/config/bundled-skills/trusted-contacts/SKILL.md +0 -372
- package/src/memory/guardian-bindings.ts +0 -158
- package/src/memory/ingress-member-store.ts +0 -352
- package/src/tools/network/script-proxy/__tests__/router.test.ts +0 -77
- package/src/tools/network/script-proxy/certs.ts +0 -7
- package/src/tools/network/script-proxy/connect-tunnel.ts +0 -1
- package/src/tools/network/script-proxy/http-forwarder.ts +0 -2
- package/src/tools/network/script-proxy/logging.ts +0 -12
- package/src/tools/network/script-proxy/mitm-handler.ts +0 -2
- package/src/tools/network/script-proxy/policy.ts +0 -4
- package/src/tools/network/script-proxy/router.ts +0 -2
- package/src/tools/network/script-proxy/server.ts +0 -5
- package/src/tools/network/script-proxy/types.ts +0 -19
|
@@ -30,71 +30,88 @@ import {
|
|
|
30
30
|
submitTollFreeVerification,
|
|
31
31
|
type TollFreeVerificationSubmitParams,
|
|
32
32
|
updateTollFreeVerification,
|
|
33
|
-
} from
|
|
34
|
-
import { getGatewayInternalBaseUrl } from
|
|
35
|
-
import { loadRawConfig, saveRawConfig } from
|
|
36
|
-
import { getReadinessService } from
|
|
37
|
-
import { syncTwilioWebhooks } from
|
|
38
|
-
import type { IngressConfig } from
|
|
39
|
-
import {
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
} from "../../calls/twilio-rest.js";
|
|
34
|
+
import { getGatewayInternalBaseUrl } from "../../config/env.js";
|
|
35
|
+
import { loadRawConfig, saveRawConfig } from "../../config/loader.js";
|
|
36
|
+
import { getReadinessService } from "../../daemon/handlers/config-channels.js";
|
|
37
|
+
import { syncTwilioWebhooks } from "../../daemon/handlers/config-ingress.js";
|
|
38
|
+
import type { IngressConfig } from "../../inbound/public-ingress-urls.js";
|
|
39
|
+
import {
|
|
40
|
+
deleteSecureKey,
|
|
41
|
+
getSecureKey,
|
|
42
|
+
setSecureKey,
|
|
43
|
+
} from "../../security/secure-keys.js";
|
|
44
|
+
import {
|
|
45
|
+
deleteCredentialMetadata,
|
|
46
|
+
upsertCredentialMetadata,
|
|
47
|
+
} from "../../tools/credentials/metadata-store.js";
|
|
48
|
+
import { mintDaemonDeliveryToken } from "../auth/token-service.js";
|
|
42
49
|
|
|
43
50
|
// ---------------------------------------------------------------------------
|
|
44
51
|
// Shared helpers
|
|
45
52
|
// ---------------------------------------------------------------------------
|
|
46
53
|
|
|
47
54
|
/** In-memory store for the last SMS send test result. Shared between sms_send_test and sms_doctor. */
|
|
48
|
-
let _lastTestResult:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
let _lastTestResult:
|
|
56
|
+
| {
|
|
57
|
+
messageSid: string;
|
|
58
|
+
to: string;
|
|
59
|
+
initialStatus: string;
|
|
60
|
+
finalStatus: string;
|
|
61
|
+
errorCode?: string;
|
|
62
|
+
errorMessage?: string;
|
|
63
|
+
timestamp: number;
|
|
64
|
+
}
|
|
65
|
+
| undefined;
|
|
66
|
+
|
|
67
|
+
function mapTwilioErrorRemediation(
|
|
68
|
+
errorCode: string | undefined,
|
|
69
|
+
): string | undefined {
|
|
59
70
|
if (!errorCode) return undefined;
|
|
60
71
|
const map: Record<string, string> = {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
"30003":
|
|
73
|
+
"Unreachable destination. The handset may be off or out of service.",
|
|
74
|
+
"30004": "Message blocked by carrier or recipient.",
|
|
75
|
+
"30005": "Unknown destination phone number. Verify the number is valid.",
|
|
76
|
+
"30006":
|
|
77
|
+
"Landline or unreachable carrier. SMS cannot be delivered to this number.",
|
|
78
|
+
"30007":
|
|
79
|
+
"Message flagged as spam by carrier. Adjust content or register for A2P.",
|
|
80
|
+
"30008": "Unknown error from the carrier network.",
|
|
81
|
+
"21610":
|
|
82
|
+
"Recipient has opted out (STOP). Cannot send until they opt back in.",
|
|
68
83
|
};
|
|
69
84
|
return map[errorCode];
|
|
70
85
|
}
|
|
71
86
|
|
|
72
87
|
const TWILIO_USE_CASE_ALIASES: Record<string, string> = {
|
|
73
|
-
ACCOUNT_NOTIFICATION:
|
|
74
|
-
DELIVERY_NOTIFICATION:
|
|
75
|
-
FRAUD_ALERT:
|
|
76
|
-
POLLING_AND_VOTING:
|
|
88
|
+
ACCOUNT_NOTIFICATION: "ACCOUNT_NOTIFICATIONS",
|
|
89
|
+
DELIVERY_NOTIFICATION: "DELIVERY_NOTIFICATIONS",
|
|
90
|
+
FRAUD_ALERT: "FRAUD_ALERT_MESSAGING",
|
|
91
|
+
POLLING_AND_VOTING: "POLLING_AND_VOTING_NON_POLITICAL",
|
|
77
92
|
};
|
|
78
93
|
|
|
79
94
|
const TWILIO_VALID_USE_CASE_CATEGORIES = [
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
"TWO_FACTOR_AUTHENTICATION",
|
|
96
|
+
"ACCOUNT_NOTIFICATIONS",
|
|
97
|
+
"CUSTOMER_CARE",
|
|
98
|
+
"CHARITY_NONPROFIT",
|
|
99
|
+
"DELIVERY_NOTIFICATIONS",
|
|
100
|
+
"FRAUD_ALERT_MESSAGING",
|
|
101
|
+
"EVENTS",
|
|
102
|
+
"HIGHER_EDUCATION",
|
|
103
|
+
"K12",
|
|
104
|
+
"MARKETING",
|
|
105
|
+
"POLLING_AND_VOTING_NON_POLITICAL",
|
|
106
|
+
"POLITICAL_ELECTION_CAMPAIGNS",
|
|
107
|
+
"PUBLIC_SERVICE_ANNOUNCEMENT",
|
|
108
|
+
"SECURITY_ALERT",
|
|
94
109
|
] as const;
|
|
95
110
|
|
|
96
111
|
function normalizeUseCaseCategories(rawCategories: string[]): string[] {
|
|
97
|
-
const normalized = rawCategories.map(
|
|
112
|
+
const normalized = rawCategories.map(
|
|
113
|
+
(value) => TWILIO_USE_CASE_ALIASES[value] ?? value,
|
|
114
|
+
);
|
|
98
115
|
return Array.from(new Set(normalized));
|
|
99
116
|
}
|
|
100
117
|
|
|
@@ -102,12 +119,15 @@ function normalizeUseCaseCategories(rawCategories: string[]): string[] {
|
|
|
102
119
|
function pruneAssistantPhoneNumbers(
|
|
103
120
|
sms: Record<string, unknown>,
|
|
104
121
|
keepNumber: string,
|
|
105
|
-
mode:
|
|
122
|
+
mode: "keep" | "remove",
|
|
106
123
|
): void {
|
|
107
|
-
const mappings = sms.assistantPhoneNumbers as
|
|
108
|
-
|
|
124
|
+
const mappings = sms.assistantPhoneNumbers as
|
|
125
|
+
| Record<string, string>
|
|
126
|
+
| undefined;
|
|
127
|
+
if (mappings && typeof mappings === "object") {
|
|
109
128
|
for (const [key, value] of Object.entries(mappings)) {
|
|
110
|
-
const shouldDelete =
|
|
129
|
+
const shouldDelete =
|
|
130
|
+
mode === "keep" ? value !== keepNumber : value === keepNumber;
|
|
111
131
|
if (shouldDelete) {
|
|
112
132
|
delete mappings[key];
|
|
113
133
|
}
|
|
@@ -129,7 +149,7 @@ export function handleGetTwilioConfig(): Response {
|
|
|
129
149
|
const hasCredentials = hasTwilioCredentials();
|
|
130
150
|
const raw = loadRawConfig();
|
|
131
151
|
const sms = (raw?.sms ?? {}) as Record<string, unknown>;
|
|
132
|
-
const phoneNumber = (sms.phoneNumber as string) ??
|
|
152
|
+
const phoneNumber = (sms.phoneNumber as string) ?? "";
|
|
133
153
|
|
|
134
154
|
return Response.json({
|
|
135
155
|
success: true,
|
|
@@ -143,23 +163,33 @@ export function handleGetTwilioConfig(): Response {
|
|
|
143
163
|
*
|
|
144
164
|
* Body: { accountSid: string, authToken: string }
|
|
145
165
|
*/
|
|
146
|
-
export async function handleSetTwilioCredentials(
|
|
147
|
-
|
|
166
|
+
export async function handleSetTwilioCredentials(
|
|
167
|
+
req: Request,
|
|
168
|
+
): Promise<Response> {
|
|
169
|
+
const body = (await req.json().catch(() => ({}))) as {
|
|
170
|
+
accountSid?: string;
|
|
171
|
+
authToken?: string;
|
|
172
|
+
};
|
|
148
173
|
|
|
149
174
|
if (!body.accountSid || !body.authToken) {
|
|
150
|
-
return Response.json(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
175
|
+
return Response.json(
|
|
176
|
+
{
|
|
177
|
+
success: false,
|
|
178
|
+
hasCredentials: hasTwilioCredentials(),
|
|
179
|
+
error: "accountSid and authToken are required",
|
|
180
|
+
},
|
|
181
|
+
{ status: 400 },
|
|
182
|
+
);
|
|
155
183
|
}
|
|
156
184
|
|
|
157
185
|
// Validate credentials against Twilio API
|
|
158
|
-
const authHeader =
|
|
186
|
+
const authHeader =
|
|
187
|
+
"Basic " +
|
|
188
|
+
Buffer.from(`${body.accountSid}:${body.authToken}`).toString("base64");
|
|
159
189
|
try {
|
|
160
190
|
const res = await fetch(
|
|
161
191
|
`https://api.twilio.com/2010-04-01/Accounts/${body.accountSid}.json`,
|
|
162
|
-
{ method:
|
|
192
|
+
{ method: "GET", headers: { Authorization: authHeader } },
|
|
163
193
|
);
|
|
164
194
|
if (!res.ok) {
|
|
165
195
|
const errBody = await res.text();
|
|
@@ -179,27 +209,33 @@ export async function handleSetTwilioCredentials(req: Request): Promise<Response
|
|
|
179
209
|
}
|
|
180
210
|
|
|
181
211
|
// Store credentials securely
|
|
182
|
-
const sidStored = setSecureKey(
|
|
212
|
+
const sidStored = setSecureKey(
|
|
213
|
+
"credential:twilio:account_sid",
|
|
214
|
+
body.accountSid,
|
|
215
|
+
);
|
|
183
216
|
if (!sidStored) {
|
|
184
217
|
return Response.json({
|
|
185
218
|
success: false,
|
|
186
219
|
hasCredentials: false,
|
|
187
|
-
error:
|
|
220
|
+
error: "Failed to store Account SID in secure storage",
|
|
188
221
|
});
|
|
189
222
|
}
|
|
190
223
|
|
|
191
|
-
const tokenStored = setSecureKey(
|
|
224
|
+
const tokenStored = setSecureKey(
|
|
225
|
+
"credential:twilio:auth_token",
|
|
226
|
+
body.authToken,
|
|
227
|
+
);
|
|
192
228
|
if (!tokenStored) {
|
|
193
|
-
deleteSecureKey(
|
|
229
|
+
deleteSecureKey("credential:twilio:account_sid");
|
|
194
230
|
return Response.json({
|
|
195
231
|
success: false,
|
|
196
232
|
hasCredentials: false,
|
|
197
|
-
error:
|
|
233
|
+
error: "Failed to store Auth Token in secure storage",
|
|
198
234
|
});
|
|
199
235
|
}
|
|
200
236
|
|
|
201
|
-
upsertCredentialMetadata(
|
|
202
|
-
upsertCredentialMetadata(
|
|
237
|
+
upsertCredentialMetadata("twilio", "account_sid", {});
|
|
238
|
+
upsertCredentialMetadata("twilio", "auth_token", {});
|
|
203
239
|
|
|
204
240
|
return Response.json({ success: true, hasCredentials: true });
|
|
205
241
|
}
|
|
@@ -208,10 +244,10 @@ export async function handleSetTwilioCredentials(req: Request): Promise<Response
|
|
|
208
244
|
* DELETE /v1/integrations/twilio/credentials
|
|
209
245
|
*/
|
|
210
246
|
export function handleClearTwilioCredentials(): Response {
|
|
211
|
-
deleteSecureKey(
|
|
212
|
-
deleteSecureKey(
|
|
213
|
-
deleteCredentialMetadata(
|
|
214
|
-
deleteCredentialMetadata(
|
|
247
|
+
deleteSecureKey("credential:twilio:account_sid");
|
|
248
|
+
deleteSecureKey("credential:twilio:auth_token");
|
|
249
|
+
deleteCredentialMetadata("twilio", "account_sid");
|
|
250
|
+
deleteCredentialMetadata("twilio", "auth_token");
|
|
215
251
|
|
|
216
252
|
return Response.json({ success: true, hasCredentials: false });
|
|
217
253
|
}
|
|
@@ -224,12 +260,12 @@ export async function handleListTwilioNumbers(): Promise<Response> {
|
|
|
224
260
|
return Response.json({
|
|
225
261
|
success: false,
|
|
226
262
|
hasCredentials: false,
|
|
227
|
-
error:
|
|
263
|
+
error: "Twilio credentials not configured. Set credentials first.",
|
|
228
264
|
});
|
|
229
265
|
}
|
|
230
266
|
|
|
231
|
-
const accountSid = getSecureKey(
|
|
232
|
-
const authToken = getSecureKey(
|
|
267
|
+
const accountSid = getSecureKey("credential:twilio:account_sid")!;
|
|
268
|
+
const authToken = getSecureKey("credential:twilio:auth_token")!;
|
|
233
269
|
const numbers = await listIncomingPhoneNumbers(accountSid, authToken);
|
|
234
270
|
|
|
235
271
|
return Response.json({ success: true, hasCredentials: true, numbers });
|
|
@@ -240,32 +276,49 @@ export async function handleListTwilioNumbers(): Promise<Response> {
|
|
|
240
276
|
*
|
|
241
277
|
* Body: { country?: string, areaCode?: string }
|
|
242
278
|
*/
|
|
243
|
-
export async function handleProvisionTwilioNumber(
|
|
279
|
+
export async function handleProvisionTwilioNumber(
|
|
280
|
+
req: Request,
|
|
281
|
+
): Promise<Response> {
|
|
244
282
|
if (!hasTwilioCredentials()) {
|
|
245
283
|
return Response.json({
|
|
246
284
|
success: false,
|
|
247
285
|
hasCredentials: false,
|
|
248
|
-
error:
|
|
286
|
+
error: "Twilio credentials not configured. Set credentials first.",
|
|
249
287
|
});
|
|
250
288
|
}
|
|
251
289
|
|
|
252
|
-
const body = (await req.json().catch(() => ({}))) as {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
290
|
+
const body = (await req.json().catch(() => ({}))) as {
|
|
291
|
+
country?: string;
|
|
292
|
+
areaCode?: string;
|
|
293
|
+
};
|
|
294
|
+
const accountSid = getSecureKey("credential:twilio:account_sid")!;
|
|
295
|
+
const authToken = getSecureKey("credential:twilio:auth_token")!;
|
|
296
|
+
const country = body.country ?? "US";
|
|
256
297
|
|
|
257
|
-
const available = await searchAvailableNumbers(
|
|
298
|
+
const available = await searchAvailableNumbers(
|
|
299
|
+
accountSid,
|
|
300
|
+
authToken,
|
|
301
|
+
country,
|
|
302
|
+
body.areaCode,
|
|
303
|
+
);
|
|
258
304
|
if (available.length === 0) {
|
|
259
305
|
return Response.json({
|
|
260
306
|
success: false,
|
|
261
307
|
hasCredentials: true,
|
|
262
|
-
error: `No available phone numbers found for country=${country}${body.areaCode ? ` areaCode=${body.areaCode}` :
|
|
308
|
+
error: `No available phone numbers found for country=${country}${body.areaCode ? ` areaCode=${body.areaCode}` : ""}`,
|
|
263
309
|
});
|
|
264
310
|
}
|
|
265
311
|
|
|
266
|
-
const purchased = await provisionPhoneNumber(
|
|
312
|
+
const purchased = await provisionPhoneNumber(
|
|
313
|
+
accountSid,
|
|
314
|
+
authToken,
|
|
315
|
+
available[0].phoneNumber,
|
|
316
|
+
);
|
|
267
317
|
|
|
268
|
-
const phoneStored = setSecureKey(
|
|
318
|
+
const phoneStored = setSecureKey(
|
|
319
|
+
"credential:twilio:phone_number",
|
|
320
|
+
purchased.phoneNumber,
|
|
321
|
+
);
|
|
269
322
|
if (!phoneStored) {
|
|
270
323
|
return Response.json({
|
|
271
324
|
success: false,
|
|
@@ -278,7 +331,7 @@ export async function handleProvisionTwilioNumber(req: Request): Promise<Respons
|
|
|
278
331
|
const raw = loadRawConfig();
|
|
279
332
|
const sms = (raw?.sms ?? {}) as Record<string, unknown>;
|
|
280
333
|
sms.phoneNumber = purchased.phoneNumber;
|
|
281
|
-
pruneAssistantPhoneNumbers(sms, purchased.phoneNumber,
|
|
334
|
+
pruneAssistantPhoneNumbers(sms, purchased.phoneNumber, "keep");
|
|
282
335
|
saveRawConfig({ ...raw, sms });
|
|
283
336
|
|
|
284
337
|
// Best-effort webhook configuration
|
|
@@ -302,37 +355,45 @@ export async function handleProvisionTwilioNumber(req: Request): Promise<Respons
|
|
|
302
355
|
*
|
|
303
356
|
* Body: { phoneNumber: string }
|
|
304
357
|
*/
|
|
305
|
-
export async function handleAssignTwilioNumber(
|
|
358
|
+
export async function handleAssignTwilioNumber(
|
|
359
|
+
req: Request,
|
|
360
|
+
): Promise<Response> {
|
|
306
361
|
const body = (await req.json().catch(() => ({}))) as { phoneNumber?: string };
|
|
307
362
|
|
|
308
363
|
if (!body.phoneNumber) {
|
|
309
|
-
return Response.json(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
364
|
+
return Response.json(
|
|
365
|
+
{
|
|
366
|
+
success: false,
|
|
367
|
+
hasCredentials: hasTwilioCredentials(),
|
|
368
|
+
error: "phoneNumber is required",
|
|
369
|
+
},
|
|
370
|
+
{ status: 400 },
|
|
371
|
+
);
|
|
314
372
|
}
|
|
315
373
|
|
|
316
|
-
const phoneStored = setSecureKey(
|
|
374
|
+
const phoneStored = setSecureKey(
|
|
375
|
+
"credential:twilio:phone_number",
|
|
376
|
+
body.phoneNumber,
|
|
377
|
+
);
|
|
317
378
|
if (!phoneStored) {
|
|
318
379
|
return Response.json({
|
|
319
380
|
success: false,
|
|
320
381
|
hasCredentials: hasTwilioCredentials(),
|
|
321
|
-
error:
|
|
382
|
+
error: "Failed to store phone number in secure storage",
|
|
322
383
|
});
|
|
323
384
|
}
|
|
324
385
|
|
|
325
386
|
const raw = loadRawConfig();
|
|
326
387
|
const sms = (raw?.sms ?? {}) as Record<string, unknown>;
|
|
327
388
|
sms.phoneNumber = body.phoneNumber;
|
|
328
|
-
pruneAssistantPhoneNumbers(sms, body.phoneNumber,
|
|
389
|
+
pruneAssistantPhoneNumbers(sms, body.phoneNumber, "keep");
|
|
329
390
|
saveRawConfig({ ...raw, sms });
|
|
330
391
|
|
|
331
392
|
// Best-effort webhook configuration when credentials are available
|
|
332
393
|
let webhookWarning: string | undefined;
|
|
333
394
|
if (hasTwilioCredentials()) {
|
|
334
|
-
const acctSid = getSecureKey(
|
|
335
|
-
const acctToken = getSecureKey(
|
|
395
|
+
const acctSid = getSecureKey("credential:twilio:account_sid")!;
|
|
396
|
+
const acctToken = getSecureKey("credential:twilio:auth_token")!;
|
|
336
397
|
const webhookResult = await syncTwilioWebhooks(
|
|
337
398
|
body.phoneNumber,
|
|
338
399
|
acctSid,
|
|
@@ -355,48 +416,52 @@ export async function handleAssignTwilioNumber(req: Request): Promise<Response>
|
|
|
355
416
|
*
|
|
356
417
|
* Body: { phoneNumber?: string }
|
|
357
418
|
*/
|
|
358
|
-
export async function handleReleaseTwilioNumber(
|
|
419
|
+
export async function handleReleaseTwilioNumber(
|
|
420
|
+
req: Request,
|
|
421
|
+
): Promise<Response> {
|
|
359
422
|
if (!hasTwilioCredentials()) {
|
|
360
423
|
return Response.json({
|
|
361
424
|
success: false,
|
|
362
425
|
hasCredentials: false,
|
|
363
|
-
error:
|
|
426
|
+
error: "Twilio credentials not configured. Set credentials first.",
|
|
364
427
|
});
|
|
365
428
|
}
|
|
366
429
|
|
|
367
430
|
const body = (await req.json().catch(() => ({}))) as { phoneNumber?: string };
|
|
368
431
|
const raw = loadRawConfig();
|
|
369
432
|
const sms = (raw?.sms ?? {}) as Record<string, unknown>;
|
|
370
|
-
const phoneNumber = body.phoneNumber || (sms.phoneNumber as string) ||
|
|
433
|
+
const phoneNumber = body.phoneNumber || (sms.phoneNumber as string) || "";
|
|
371
434
|
|
|
372
435
|
if (!phoneNumber) {
|
|
373
436
|
return Response.json({
|
|
374
437
|
success: false,
|
|
375
438
|
hasCredentials: true,
|
|
376
|
-
error:
|
|
439
|
+
error:
|
|
440
|
+
"No phone number to release. Specify phoneNumber or ensure one is assigned.",
|
|
377
441
|
});
|
|
378
442
|
}
|
|
379
443
|
|
|
380
|
-
const accountSid = getSecureKey(
|
|
381
|
-
const authToken = getSecureKey(
|
|
444
|
+
const accountSid = getSecureKey("credential:twilio:account_sid")!;
|
|
445
|
+
const authToken = getSecureKey("credential:twilio:auth_token")!;
|
|
382
446
|
|
|
383
447
|
await releasePhoneNumber(accountSid, authToken, phoneNumber);
|
|
384
448
|
|
|
385
449
|
if (sms.phoneNumber === phoneNumber) {
|
|
386
450
|
delete sms.phoneNumber;
|
|
387
451
|
}
|
|
388
|
-
pruneAssistantPhoneNumbers(sms, phoneNumber,
|
|
452
|
+
pruneAssistantPhoneNumbers(sms, phoneNumber, "remove");
|
|
389
453
|
saveRawConfig({ ...raw, sms });
|
|
390
454
|
|
|
391
|
-
const storedPhone = getSecureKey(
|
|
455
|
+
const storedPhone = getSecureKey("credential:twilio:phone_number");
|
|
392
456
|
if (storedPhone === phoneNumber) {
|
|
393
|
-
deleteSecureKey(
|
|
457
|
+
deleteSecureKey("credential:twilio:phone_number");
|
|
394
458
|
}
|
|
395
459
|
|
|
396
460
|
return Response.json({
|
|
397
461
|
success: true,
|
|
398
462
|
hasCredentials: true,
|
|
399
|
-
warning:
|
|
463
|
+
warning:
|
|
464
|
+
"Phone number released from Twilio. Any associated toll-free verification context is lost.",
|
|
400
465
|
});
|
|
401
466
|
}
|
|
402
467
|
|
|
@@ -408,28 +473,38 @@ export async function handleGetSmsCompliance(): Promise<Response> {
|
|
|
408
473
|
return Response.json({
|
|
409
474
|
success: false,
|
|
410
475
|
hasCredentials: false,
|
|
411
|
-
error:
|
|
476
|
+
error: "Twilio credentials not configured. Set credentials first.",
|
|
412
477
|
});
|
|
413
478
|
}
|
|
414
479
|
|
|
415
480
|
const raw = loadRawConfig();
|
|
416
481
|
const sms = (raw?.sms ?? {}) as Record<string, unknown>;
|
|
417
|
-
const phoneNumber = (sms.phoneNumber as string) ??
|
|
482
|
+
const phoneNumber = (sms.phoneNumber as string) ?? "";
|
|
418
483
|
|
|
419
484
|
if (!phoneNumber) {
|
|
420
485
|
return Response.json({
|
|
421
486
|
success: false,
|
|
422
487
|
hasCredentials: true,
|
|
423
|
-
error:
|
|
488
|
+
error: "No phone number assigned. Assign a number first.",
|
|
424
489
|
});
|
|
425
490
|
}
|
|
426
491
|
|
|
427
|
-
const accountSid = getSecureKey(
|
|
428
|
-
const authToken = getSecureKey(
|
|
429
|
-
|
|
430
|
-
const tollFreePrefixes = [
|
|
431
|
-
|
|
432
|
-
|
|
492
|
+
const accountSid = getSecureKey("credential:twilio:account_sid")!;
|
|
493
|
+
const authToken = getSecureKey("credential:twilio:auth_token")!;
|
|
494
|
+
|
|
495
|
+
const tollFreePrefixes = [
|
|
496
|
+
"+1800",
|
|
497
|
+
"+1833",
|
|
498
|
+
"+1844",
|
|
499
|
+
"+1855",
|
|
500
|
+
"+1866",
|
|
501
|
+
"+1877",
|
|
502
|
+
"+1888",
|
|
503
|
+
];
|
|
504
|
+
const isTollFree = tollFreePrefixes.some((prefix) =>
|
|
505
|
+
phoneNumber.startsWith(prefix),
|
|
506
|
+
);
|
|
507
|
+
const numberType = isTollFree ? "toll_free" : "local_10dlc";
|
|
433
508
|
|
|
434
509
|
if (!isTollFree) {
|
|
435
510
|
return Response.json({
|
|
@@ -450,7 +525,11 @@ export async function handleGetSmsCompliance(): Promise<Response> {
|
|
|
450
525
|
});
|
|
451
526
|
}
|
|
452
527
|
|
|
453
|
-
const verification = await getTollFreeVerificationStatus(
|
|
528
|
+
const verification = await getTollFreeVerificationStatus(
|
|
529
|
+
accountSid,
|
|
530
|
+
authToken,
|
|
531
|
+
phoneSid,
|
|
532
|
+
);
|
|
454
533
|
|
|
455
534
|
return Response.json({
|
|
456
535
|
success: true,
|
|
@@ -475,77 +554,113 @@ export async function handleGetSmsCompliance(): Promise<Response> {
|
|
|
475
554
|
*
|
|
476
555
|
* Body: TollFreeVerificationSubmitParams
|
|
477
556
|
*/
|
|
478
|
-
export async function handleSubmitTollfreeVerification(
|
|
557
|
+
export async function handleSubmitTollfreeVerification(
|
|
558
|
+
req: Request,
|
|
559
|
+
): Promise<Response> {
|
|
479
560
|
if (!hasTwilioCredentials()) {
|
|
480
561
|
return Response.json({
|
|
481
562
|
success: false,
|
|
482
563
|
hasCredentials: false,
|
|
483
|
-
error:
|
|
564
|
+
error: "Twilio credentials not configured. Set credentials first.",
|
|
484
565
|
});
|
|
485
566
|
}
|
|
486
567
|
|
|
487
568
|
const vp = (await req.json().catch(() => ({}))) as Record<string, unknown>;
|
|
488
569
|
|
|
489
570
|
const requiredFields: Array<[string, unknown]> = [
|
|
490
|
-
[
|
|
491
|
-
[
|
|
492
|
-
[
|
|
493
|
-
[
|
|
494
|
-
[
|
|
495
|
-
[
|
|
496
|
-
[
|
|
497
|
-
[
|
|
498
|
-
[
|
|
499
|
-
[
|
|
571
|
+
["tollfreePhoneNumberSid", vp.tollfreePhoneNumberSid],
|
|
572
|
+
["businessName", vp.businessName],
|
|
573
|
+
["businessWebsite", vp.businessWebsite],
|
|
574
|
+
["notificationEmail", vp.notificationEmail],
|
|
575
|
+
["useCaseCategories", vp.useCaseCategories],
|
|
576
|
+
["useCaseSummary", vp.useCaseSummary],
|
|
577
|
+
["productionMessageSample", vp.productionMessageSample],
|
|
578
|
+
["optInImageUrls", vp.optInImageUrls],
|
|
579
|
+
["optInType", vp.optInType],
|
|
580
|
+
["messageVolume", vp.messageVolume],
|
|
500
581
|
];
|
|
501
582
|
|
|
502
583
|
const missing = requiredFields
|
|
503
|
-
.filter(
|
|
584
|
+
.filter(
|
|
585
|
+
([, v]) => v == null || v === "" || (Array.isArray(v) && v.length === 0),
|
|
586
|
+
)
|
|
504
587
|
.map(([name]) => name);
|
|
505
588
|
|
|
506
589
|
if (missing.length > 0) {
|
|
507
|
-
return Response.json(
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
590
|
+
return Response.json(
|
|
591
|
+
{
|
|
592
|
+
success: false,
|
|
593
|
+
hasCredentials: true,
|
|
594
|
+
error: `Missing required verification fields: ${missing.join(", ")}`,
|
|
595
|
+
},
|
|
596
|
+
{ status: 400 },
|
|
597
|
+
);
|
|
512
598
|
}
|
|
513
599
|
|
|
514
|
-
const normalizedUseCaseCategories = normalizeUseCaseCategories(
|
|
600
|
+
const normalizedUseCaseCategories = normalizeUseCaseCategories(
|
|
601
|
+
vp.useCaseCategories as string[],
|
|
602
|
+
);
|
|
515
603
|
const invalidCategories = normalizedUseCaseCategories.filter(
|
|
516
|
-
(c) =>
|
|
604
|
+
(c) =>
|
|
605
|
+
!TWILIO_VALID_USE_CASE_CATEGORIES.includes(
|
|
606
|
+
c as (typeof TWILIO_VALID_USE_CASE_CATEGORIES)[number],
|
|
607
|
+
),
|
|
517
608
|
);
|
|
518
609
|
if (invalidCategories.length > 0) {
|
|
519
|
-
return Response.json(
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
610
|
+
return Response.json(
|
|
611
|
+
{
|
|
612
|
+
success: false,
|
|
613
|
+
hasCredentials: true,
|
|
614
|
+
error: `Invalid useCaseCategories: ${invalidCategories.join(", ")}. Valid values: ${TWILIO_VALID_USE_CASE_CATEGORIES.join(", ")}`,
|
|
615
|
+
},
|
|
616
|
+
{ status: 400 },
|
|
617
|
+
);
|
|
524
618
|
}
|
|
525
619
|
|
|
526
|
-
const validOptInTypes = [
|
|
620
|
+
const validOptInTypes = [
|
|
621
|
+
"VERBAL",
|
|
622
|
+
"WEB_FORM",
|
|
623
|
+
"PAPER_FORM",
|
|
624
|
+
"VIA_TEXT",
|
|
625
|
+
"MOBILE_QR_CODE",
|
|
626
|
+
];
|
|
527
627
|
if (!validOptInTypes.includes(vp.optInType as string)) {
|
|
528
|
-
return Response.json(
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
628
|
+
return Response.json(
|
|
629
|
+
{
|
|
630
|
+
success: false,
|
|
631
|
+
hasCredentials: true,
|
|
632
|
+
error: `Invalid optInType: ${vp.optInType}. Valid values: ${validOptInTypes.join(", ")}`,
|
|
633
|
+
},
|
|
634
|
+
{ status: 400 },
|
|
635
|
+
);
|
|
533
636
|
}
|
|
534
637
|
|
|
535
638
|
const validMessageVolumes = [
|
|
536
|
-
|
|
537
|
-
|
|
639
|
+
"10",
|
|
640
|
+
"100",
|
|
641
|
+
"1,000",
|
|
642
|
+
"10,000",
|
|
643
|
+
"100,000",
|
|
644
|
+
"250,000",
|
|
645
|
+
"500,000",
|
|
646
|
+
"750,000",
|
|
647
|
+
"1,000,000",
|
|
648
|
+
"5,000,000",
|
|
649
|
+
"10,000,000+",
|
|
538
650
|
];
|
|
539
651
|
if (!validMessageVolumes.includes(vp.messageVolume as string)) {
|
|
540
|
-
return Response.json(
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
652
|
+
return Response.json(
|
|
653
|
+
{
|
|
654
|
+
success: false,
|
|
655
|
+
hasCredentials: true,
|
|
656
|
+
error: `Invalid messageVolume: ${vp.messageVolume}. Valid values: ${validMessageVolumes.join(", ")}`,
|
|
657
|
+
},
|
|
658
|
+
{ status: 400 },
|
|
659
|
+
);
|
|
545
660
|
}
|
|
546
661
|
|
|
547
|
-
const accountSid = getSecureKey(
|
|
548
|
-
const authToken = getSecureKey(
|
|
662
|
+
const accountSid = getSecureKey("credential:twilio:account_sid")!;
|
|
663
|
+
const authToken = getSecureKey("credential:twilio:auth_token")!;
|
|
549
664
|
|
|
550
665
|
const submitParams: TollFreeVerificationSubmitParams = {
|
|
551
666
|
tollfreePhoneNumberSid: vp.tollfreePhoneNumberSid as string,
|
|
@@ -558,17 +673,21 @@ export async function handleSubmitTollfreeVerification(req: Request): Promise<Re
|
|
|
558
673
|
optInImageUrls: vp.optInImageUrls as string[],
|
|
559
674
|
optInType: vp.optInType as string,
|
|
560
675
|
messageVolume: vp.messageVolume as string,
|
|
561
|
-
businessType: (vp.businessType as string) ??
|
|
676
|
+
businessType: (vp.businessType as string) ?? "SOLE_PROPRIETOR",
|
|
562
677
|
customerProfileSid: vp.customerProfileSid as string | undefined,
|
|
563
678
|
};
|
|
564
679
|
|
|
565
|
-
const verification = await submitTollFreeVerification(
|
|
680
|
+
const verification = await submitTollFreeVerification(
|
|
681
|
+
accountSid,
|
|
682
|
+
authToken,
|
|
683
|
+
submitParams,
|
|
684
|
+
);
|
|
566
685
|
|
|
567
686
|
return Response.json({
|
|
568
687
|
success: true,
|
|
569
688
|
hasCredentials: true,
|
|
570
689
|
compliance: {
|
|
571
|
-
numberType:
|
|
690
|
+
numberType: "toll_free",
|
|
572
691
|
verificationSid: verification.sid,
|
|
573
692
|
verificationStatus: verification.status,
|
|
574
693
|
},
|
|
@@ -580,19 +699,26 @@ export async function handleSubmitTollfreeVerification(req: Request): Promise<Re
|
|
|
580
699
|
*
|
|
581
700
|
* Body: partial verification params to update
|
|
582
701
|
*/
|
|
583
|
-
export async function handleUpdateTollfreeVerification(
|
|
702
|
+
export async function handleUpdateTollfreeVerification(
|
|
703
|
+
req: Request,
|
|
704
|
+
verificationSid: string,
|
|
705
|
+
): Promise<Response> {
|
|
584
706
|
if (!hasTwilioCredentials()) {
|
|
585
707
|
return Response.json({
|
|
586
708
|
success: false,
|
|
587
709
|
hasCredentials: false,
|
|
588
|
-
error:
|
|
710
|
+
error: "Twilio credentials not configured. Set credentials first.",
|
|
589
711
|
});
|
|
590
712
|
}
|
|
591
713
|
|
|
592
|
-
const accountSid = getSecureKey(
|
|
593
|
-
const authToken = getSecureKey(
|
|
714
|
+
const accountSid = getSecureKey("credential:twilio:account_sid")!;
|
|
715
|
+
const authToken = getSecureKey("credential:twilio:auth_token")!;
|
|
594
716
|
|
|
595
|
-
const currentVerification = await getTollFreeVerificationBySid(
|
|
717
|
+
const currentVerification = await getTollFreeVerificationBySid(
|
|
718
|
+
accountSid,
|
|
719
|
+
authToken,
|
|
720
|
+
verificationSid,
|
|
721
|
+
);
|
|
596
722
|
if (!currentVerification) {
|
|
597
723
|
return Response.json({
|
|
598
724
|
success: false,
|
|
@@ -601,21 +727,22 @@ export async function handleUpdateTollfreeVerification(req: Request, verificatio
|
|
|
601
727
|
});
|
|
602
728
|
}
|
|
603
729
|
|
|
604
|
-
if (currentVerification.status ===
|
|
730
|
+
if (currentVerification.status === "TWILIO_REJECTED") {
|
|
605
731
|
const expirationMillis = currentVerification.editExpiration
|
|
606
732
|
? Date.parse(currentVerification.editExpiration)
|
|
607
733
|
: Number.NaN;
|
|
608
|
-
const editExpired =
|
|
734
|
+
const editExpired =
|
|
735
|
+
Number.isFinite(expirationMillis) && Date.now() > expirationMillis;
|
|
609
736
|
if (currentVerification.editAllowed === false || editExpired) {
|
|
610
737
|
const detail = editExpired
|
|
611
738
|
? `edit_expiration=${currentVerification.editExpiration}`
|
|
612
|
-
:
|
|
739
|
+
: "edit_allowed=false";
|
|
613
740
|
return Response.json({
|
|
614
741
|
success: false,
|
|
615
742
|
hasCredentials: true,
|
|
616
743
|
error: `Verification ${verificationSid} cannot be updated (${detail}). Delete and resubmit instead.`,
|
|
617
744
|
compliance: {
|
|
618
|
-
numberType:
|
|
745
|
+
numberType: "toll_free",
|
|
619
746
|
verificationSid: currentVerification.sid,
|
|
620
747
|
verificationStatus: currentVerification.status,
|
|
621
748
|
editAllowed: currentVerification.editAllowed,
|
|
@@ -625,9 +752,13 @@ export async function handleUpdateTollfreeVerification(req: Request, verificatio
|
|
|
625
752
|
}
|
|
626
753
|
}
|
|
627
754
|
|
|
628
|
-
const updateParams = {
|
|
755
|
+
const updateParams = {
|
|
756
|
+
...((await req.json().catch(() => ({}))) as Record<string, unknown>),
|
|
757
|
+
};
|
|
629
758
|
if (updateParams.useCaseCategories) {
|
|
630
|
-
updateParams.useCaseCategories = normalizeUseCaseCategories(
|
|
759
|
+
updateParams.useCaseCategories = normalizeUseCaseCategories(
|
|
760
|
+
updateParams.useCaseCategories as string[],
|
|
761
|
+
);
|
|
631
762
|
}
|
|
632
763
|
|
|
633
764
|
const verification = await updateTollFreeVerification(
|
|
@@ -641,7 +772,7 @@ export async function handleUpdateTollfreeVerification(req: Request, verificatio
|
|
|
641
772
|
success: true,
|
|
642
773
|
hasCredentials: true,
|
|
643
774
|
compliance: {
|
|
644
|
-
numberType:
|
|
775
|
+
numberType: "toll_free",
|
|
645
776
|
verificationSid: verification.sid,
|
|
646
777
|
verificationStatus: verification.status,
|
|
647
778
|
editAllowed: verification.editAllowed,
|
|
@@ -653,24 +784,27 @@ export async function handleUpdateTollfreeVerification(req: Request, verificatio
|
|
|
653
784
|
/**
|
|
654
785
|
* DELETE /v1/integrations/twilio/sms/compliance/tollfree/:verificationSid
|
|
655
786
|
*/
|
|
656
|
-
export async function handleDeleteTollfreeVerification(
|
|
787
|
+
export async function handleDeleteTollfreeVerification(
|
|
788
|
+
verificationSid: string,
|
|
789
|
+
): Promise<Response> {
|
|
657
790
|
if (!hasTwilioCredentials()) {
|
|
658
791
|
return Response.json({
|
|
659
792
|
success: false,
|
|
660
793
|
hasCredentials: false,
|
|
661
|
-
error:
|
|
794
|
+
error: "Twilio credentials not configured. Set credentials first.",
|
|
662
795
|
});
|
|
663
796
|
}
|
|
664
797
|
|
|
665
|
-
const accountSid = getSecureKey(
|
|
666
|
-
const authToken = getSecureKey(
|
|
798
|
+
const accountSid = getSecureKey("credential:twilio:account_sid")!;
|
|
799
|
+
const authToken = getSecureKey("credential:twilio:auth_token")!;
|
|
667
800
|
|
|
668
801
|
await deleteTollFreeVerification(accountSid, authToken, verificationSid);
|
|
669
802
|
|
|
670
803
|
return Response.json({
|
|
671
804
|
success: true,
|
|
672
805
|
hasCredentials: true,
|
|
673
|
-
warning:
|
|
806
|
+
warning:
|
|
807
|
+
"Toll-free verification deleted. Re-submitting may reset your position in the review queue.",
|
|
674
808
|
});
|
|
675
809
|
}
|
|
676
810
|
|
|
@@ -684,45 +818,53 @@ export async function handleSmsSendTest(req: Request): Promise<Response> {
|
|
|
684
818
|
return Response.json({
|
|
685
819
|
success: false,
|
|
686
820
|
hasCredentials: false,
|
|
687
|
-
error:
|
|
821
|
+
error: "Twilio credentials not configured. Set credentials first.",
|
|
688
822
|
});
|
|
689
823
|
}
|
|
690
824
|
|
|
691
|
-
const body = (await req.json().catch(() => ({}))) as {
|
|
825
|
+
const body = (await req.json().catch(() => ({}))) as {
|
|
826
|
+
phoneNumber?: string;
|
|
827
|
+
text?: string;
|
|
828
|
+
};
|
|
692
829
|
const to = body.phoneNumber;
|
|
693
830
|
if (!to) {
|
|
694
|
-
return Response.json(
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
831
|
+
return Response.json(
|
|
832
|
+
{
|
|
833
|
+
success: false,
|
|
834
|
+
hasCredentials: true,
|
|
835
|
+
error: "phoneNumber is required for SMS send test.",
|
|
836
|
+
},
|
|
837
|
+
{ status: 400 },
|
|
838
|
+
);
|
|
699
839
|
}
|
|
700
840
|
|
|
701
841
|
const raw = loadRawConfig();
|
|
702
842
|
const smsSection = (raw?.sms ?? {}) as Record<string, unknown>;
|
|
703
|
-
const from =
|
|
704
|
-
|
|
705
|
-
||
|
|
843
|
+
const from =
|
|
844
|
+
(smsSection.phoneNumber as string | undefined) ||
|
|
845
|
+
getSecureKey("credential:twilio:phone_number") ||
|
|
846
|
+
"";
|
|
706
847
|
if (!from) {
|
|
707
848
|
return Response.json({
|
|
708
849
|
success: false,
|
|
709
850
|
hasCredentials: true,
|
|
710
|
-
error:
|
|
851
|
+
error:
|
|
852
|
+
"No phone number assigned. Run the twilio-setup skill to assign a number.",
|
|
711
853
|
});
|
|
712
854
|
}
|
|
713
855
|
|
|
714
|
-
const accountSid = getSecureKey(
|
|
715
|
-
const authToken = getSecureKey(
|
|
716
|
-
const text = body.text ||
|
|
856
|
+
const accountSid = getSecureKey("credential:twilio:account_sid")!;
|
|
857
|
+
const authToken = getSecureKey("credential:twilio:auth_token")!;
|
|
858
|
+
const text = body.text || "Test SMS from your Vellum assistant";
|
|
717
859
|
|
|
718
860
|
// Send via gateway's /deliver/sms endpoint
|
|
719
861
|
const bearerToken = mintDaemonDeliveryToken();
|
|
720
862
|
const gatewayUrl = getGatewayInternalBaseUrl();
|
|
721
863
|
|
|
722
864
|
const sendResp = await fetch(`${gatewayUrl}/deliver/sms`, {
|
|
723
|
-
method:
|
|
865
|
+
method: "POST",
|
|
724
866
|
headers: {
|
|
725
|
-
|
|
867
|
+
"Content-Type": "application/json",
|
|
726
868
|
Authorization: `Bearer ${bearerToken}`,
|
|
727
869
|
},
|
|
728
870
|
body: JSON.stringify({ to, text }),
|
|
@@ -730,7 +872,7 @@ export async function handleSmsSendTest(req: Request): Promise<Response> {
|
|
|
730
872
|
});
|
|
731
873
|
|
|
732
874
|
if (!sendResp.ok) {
|
|
733
|
-
const errBody = await sendResp.text().catch(() =>
|
|
875
|
+
const errBody = await sendResp.text().catch(() => "<unreadable>");
|
|
734
876
|
return Response.json({
|
|
735
877
|
success: false,
|
|
736
878
|
hasCredentials: true,
|
|
@@ -738,12 +880,12 @@ export async function handleSmsSendTest(req: Request): Promise<Response> {
|
|
|
738
880
|
});
|
|
739
881
|
}
|
|
740
882
|
|
|
741
|
-
const sendData = await sendResp.json().catch(() => ({})) as {
|
|
883
|
+
const sendData = (await sendResp.json().catch(() => ({}))) as {
|
|
742
884
|
messageSid?: string;
|
|
743
885
|
status?: string;
|
|
744
886
|
};
|
|
745
|
-
const messageSid = sendData.messageSid ||
|
|
746
|
-
const initialStatus = sendData.status ||
|
|
887
|
+
const messageSid = sendData.messageSid || "";
|
|
888
|
+
const initialStatus = sendData.status || "unknown";
|
|
747
889
|
|
|
748
890
|
// Poll Twilio for final status (up to 3 times, 2s apart)
|
|
749
891
|
let finalStatus = initialStatus;
|
|
@@ -754,11 +896,15 @@ export async function handleSmsSendTest(req: Request): Promise<Response> {
|
|
|
754
896
|
for (let i = 0; i < 3; i++) {
|
|
755
897
|
await new Promise((r) => setTimeout(r, 2000));
|
|
756
898
|
try {
|
|
757
|
-
const pollResult = await fetchMessageStatus(
|
|
899
|
+
const pollResult = await fetchMessageStatus(
|
|
900
|
+
accountSid,
|
|
901
|
+
authToken,
|
|
902
|
+
messageSid,
|
|
903
|
+
);
|
|
758
904
|
finalStatus = pollResult.status;
|
|
759
905
|
errorCode = pollResult.errorCode;
|
|
760
906
|
errorMessage = pollResult.errorMessage;
|
|
761
|
-
if ([
|
|
907
|
+
if (["delivered", "undelivered", "failed"].includes(finalStatus)) break;
|
|
762
908
|
} catch {
|
|
763
909
|
break;
|
|
764
910
|
}
|
|
@@ -794,7 +940,7 @@ export async function handleSmsDoctor(): Promise<Response> {
|
|
|
794
940
|
const readinessIssues: string[] = [];
|
|
795
941
|
try {
|
|
796
942
|
const readinessService = getReadinessService();
|
|
797
|
-
const snapshots = await readinessService.getReadiness(
|
|
943
|
+
const snapshots = await readinessService.getReadiness("sms", false);
|
|
798
944
|
const snapshot = snapshots[0];
|
|
799
945
|
if (snapshot) {
|
|
800
946
|
readinessReady = snapshot.ready;
|
|
@@ -802,118 +948,164 @@ export async function handleSmsDoctor(): Promise<Response> {
|
|
|
802
948
|
readinessIssues.push(r.text);
|
|
803
949
|
}
|
|
804
950
|
} else {
|
|
805
|
-
readinessIssues.push(
|
|
951
|
+
readinessIssues.push("No readiness snapshot returned for SMS channel");
|
|
806
952
|
}
|
|
807
953
|
} catch (err) {
|
|
808
|
-
readinessIssues.push(
|
|
954
|
+
readinessIssues.push(
|
|
955
|
+
`Readiness check failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
956
|
+
);
|
|
809
957
|
}
|
|
810
958
|
|
|
811
959
|
// 2. Compliance status
|
|
812
|
-
let complianceStatus =
|
|
960
|
+
let complianceStatus = "unknown";
|
|
813
961
|
let complianceDetail: string | undefined;
|
|
814
962
|
let complianceRemediation: string | undefined;
|
|
815
963
|
if (hasCredentials) {
|
|
816
964
|
try {
|
|
817
965
|
const raw = loadRawConfig();
|
|
818
966
|
const smsSection = (raw?.sms ?? {}) as Record<string, unknown>;
|
|
819
|
-
const phoneNumber =
|
|
967
|
+
const phoneNumber =
|
|
968
|
+
(smsSection.phoneNumber as string | undefined) ||
|
|
969
|
+
getSecureKey("credential:twilio:phone_number") ||
|
|
970
|
+
"";
|
|
820
971
|
if (phoneNumber) {
|
|
821
|
-
const accountSid = getSecureKey(
|
|
822
|
-
const authToken = getSecureKey(
|
|
823
|
-
const isTollFree =
|
|
824
|
-
|
|
825
|
-
|
|
972
|
+
const accountSid = getSecureKey("credential:twilio:account_sid")!;
|
|
973
|
+
const authToken = getSecureKey("credential:twilio:auth_token")!;
|
|
974
|
+
const isTollFree =
|
|
975
|
+
phoneNumber.startsWith("+1") &&
|
|
976
|
+
["800", "888", "877", "866", "855", "844", "833"].some((p) =>
|
|
977
|
+
phoneNumber.startsWith(`+1${p}`),
|
|
978
|
+
);
|
|
826
979
|
if (isTollFree) {
|
|
827
980
|
try {
|
|
828
|
-
const phoneSid = await getPhoneNumberSid(
|
|
981
|
+
const phoneSid = await getPhoneNumberSid(
|
|
982
|
+
accountSid,
|
|
983
|
+
authToken,
|
|
984
|
+
phoneNumber,
|
|
985
|
+
);
|
|
829
986
|
if (!phoneSid) {
|
|
830
|
-
complianceStatus =
|
|
987
|
+
complianceStatus = "check_failed";
|
|
831
988
|
complianceDetail = `Assigned number ${phoneNumber} was not found on the Twilio account`;
|
|
832
|
-
complianceRemediation =
|
|
989
|
+
complianceRemediation =
|
|
990
|
+
"Reassign the number in twilio-setup or update credentials to the matching account.";
|
|
833
991
|
} else {
|
|
834
|
-
const verification = await getTollFreeVerificationStatus(
|
|
992
|
+
const verification = await getTollFreeVerificationStatus(
|
|
993
|
+
accountSid,
|
|
994
|
+
authToken,
|
|
995
|
+
phoneSid,
|
|
996
|
+
);
|
|
835
997
|
if (verification) {
|
|
836
998
|
const status = verification.status;
|
|
837
999
|
complianceStatus = status;
|
|
838
1000
|
complianceDetail = `Toll-free verification: ${status}`;
|
|
839
|
-
if (status ===
|
|
1001
|
+
if (status === "TWILIO_APPROVED") {
|
|
840
1002
|
complianceRemediation = undefined;
|
|
841
|
-
} else if (
|
|
842
|
-
|
|
843
|
-
|
|
1003
|
+
} else if (
|
|
1004
|
+
status === "PENDING_REVIEW" ||
|
|
1005
|
+
status === "IN_REVIEW"
|
|
1006
|
+
) {
|
|
1007
|
+
complianceRemediation =
|
|
1008
|
+
"Toll-free verification is pending. Messaging may have limited throughput until approved.";
|
|
1009
|
+
} else if (status === "TWILIO_REJECTED") {
|
|
844
1010
|
if (verification.editAllowed) {
|
|
845
1011
|
complianceRemediation = verification.editExpiration
|
|
846
1012
|
? `Toll-free verification was rejected but can still be edited until ${verification.editExpiration}. Update and resubmit it.`
|
|
847
|
-
:
|
|
1013
|
+
: "Toll-free verification was rejected but can still be edited. Update and resubmit it.";
|
|
848
1014
|
} else {
|
|
849
|
-
complianceRemediation =
|
|
1015
|
+
complianceRemediation =
|
|
1016
|
+
"Toll-free verification was rejected and is no longer editable. Delete and resubmit it.";
|
|
850
1017
|
}
|
|
851
1018
|
} else {
|
|
852
|
-
complianceRemediation =
|
|
1019
|
+
complianceRemediation =
|
|
1020
|
+
"Submit a toll-free verification to enable full messaging throughput.";
|
|
853
1021
|
}
|
|
854
1022
|
} else {
|
|
855
|
-
complianceStatus =
|
|
856
|
-
complianceDetail =
|
|
857
|
-
complianceRemediation =
|
|
1023
|
+
complianceStatus = "unverified";
|
|
1024
|
+
complianceDetail = "Toll-free number without verification";
|
|
1025
|
+
complianceRemediation =
|
|
1026
|
+
"Submit a toll-free verification request to avoid filtering.";
|
|
858
1027
|
}
|
|
859
1028
|
}
|
|
860
1029
|
} catch {
|
|
861
|
-
complianceStatus =
|
|
862
|
-
complianceDetail =
|
|
1030
|
+
complianceStatus = "check_failed";
|
|
1031
|
+
complianceDetail =
|
|
1032
|
+
"Could not retrieve toll-free verification status";
|
|
863
1033
|
}
|
|
864
1034
|
} else {
|
|
865
|
-
complianceStatus =
|
|
866
|
-
complianceDetail =
|
|
1035
|
+
complianceStatus = "local_10dlc";
|
|
1036
|
+
complianceDetail =
|
|
1037
|
+
"Local/10DLC number — carrier registration handled externally";
|
|
867
1038
|
}
|
|
868
1039
|
} else {
|
|
869
|
-
complianceStatus =
|
|
870
|
-
complianceDetail =
|
|
871
|
-
complianceRemediation =
|
|
1040
|
+
complianceStatus = "no_number";
|
|
1041
|
+
complianceDetail = "No phone number assigned";
|
|
1042
|
+
complianceRemediation =
|
|
1043
|
+
"Assign a phone number via the twilio-setup skill.";
|
|
872
1044
|
}
|
|
873
1045
|
} catch {
|
|
874
|
-
complianceStatus =
|
|
875
|
-
complianceDetail =
|
|
1046
|
+
complianceStatus = "check_failed";
|
|
1047
|
+
complianceDetail = "Could not determine compliance status";
|
|
876
1048
|
}
|
|
877
1049
|
} else {
|
|
878
|
-
complianceStatus =
|
|
879
|
-
complianceDetail =
|
|
880
|
-
complianceRemediation =
|
|
1050
|
+
complianceStatus = "no_credentials";
|
|
1051
|
+
complianceDetail = "Twilio credentials are not configured";
|
|
1052
|
+
complianceRemediation =
|
|
1053
|
+
"Set Twilio credentials via the twilio-setup skill.";
|
|
881
1054
|
}
|
|
882
1055
|
|
|
883
1056
|
// 3. Last send test result
|
|
884
|
-
let lastSend:
|
|
1057
|
+
let lastSend:
|
|
1058
|
+
| { status: string; errorCode?: string; remediation?: string }
|
|
1059
|
+
| undefined;
|
|
885
1060
|
if (_lastTestResult) {
|
|
886
1061
|
lastSend = {
|
|
887
1062
|
status: _lastTestResult.finalStatus,
|
|
888
|
-
...(
|
|
889
|
-
|
|
1063
|
+
...(_lastTestResult.errorCode
|
|
1064
|
+
? { errorCode: _lastTestResult.errorCode }
|
|
1065
|
+
: {}),
|
|
1066
|
+
...(_lastTestResult.errorCode
|
|
1067
|
+
? { remediation: mapTwilioErrorRemediation(_lastTestResult.errorCode) }
|
|
1068
|
+
: {}),
|
|
890
1069
|
};
|
|
891
1070
|
}
|
|
892
1071
|
|
|
893
1072
|
// 4. Overall status
|
|
894
1073
|
const actionItems: string[] = [];
|
|
895
|
-
let overallStatus:
|
|
1074
|
+
let overallStatus: "healthy" | "degraded" | "broken" = "healthy";
|
|
896
1075
|
|
|
897
1076
|
if (!hasCredentials) {
|
|
898
|
-
overallStatus =
|
|
899
|
-
actionItems.push(
|
|
1077
|
+
overallStatus = "broken";
|
|
1078
|
+
actionItems.push("Configure Twilio credentials.");
|
|
900
1079
|
}
|
|
901
1080
|
if (!readinessReady) {
|
|
902
|
-
overallStatus =
|
|
1081
|
+
overallStatus = "broken";
|
|
903
1082
|
for (const issue of readinessIssues) actionItems.push(issue);
|
|
904
1083
|
}
|
|
905
|
-
if (
|
|
906
|
-
|
|
1084
|
+
if (
|
|
1085
|
+
complianceStatus === "unverified" ||
|
|
1086
|
+
complianceStatus === "PENDING_REVIEW" ||
|
|
1087
|
+
complianceStatus === "IN_REVIEW"
|
|
1088
|
+
) {
|
|
1089
|
+
if (overallStatus === "healthy") overallStatus = "degraded";
|
|
907
1090
|
if (complianceRemediation) actionItems.push(complianceRemediation);
|
|
908
1091
|
}
|
|
909
|
-
if (
|
|
910
|
-
|
|
1092
|
+
if (
|
|
1093
|
+
complianceStatus === "TWILIO_REJECTED" ||
|
|
1094
|
+
complianceStatus === "no_number"
|
|
1095
|
+
) {
|
|
1096
|
+
overallStatus = "broken";
|
|
911
1097
|
if (complianceRemediation) actionItems.push(complianceRemediation);
|
|
912
1098
|
}
|
|
913
|
-
if (
|
|
914
|
-
|
|
1099
|
+
if (
|
|
1100
|
+
_lastTestResult &&
|
|
1101
|
+
["failed", "undelivered"].includes(_lastTestResult.finalStatus)
|
|
1102
|
+
) {
|
|
1103
|
+
if (overallStatus === "healthy") overallStatus = "degraded";
|
|
915
1104
|
const remediation = mapTwilioErrorRemediation(_lastTestResult.errorCode);
|
|
916
|
-
actionItems.push(
|
|
1105
|
+
actionItems.push(
|
|
1106
|
+
remediation ||
|
|
1107
|
+
`Last test SMS ${_lastTestResult.finalStatus}. Check Twilio logs for details.`,
|
|
1108
|
+
);
|
|
917
1109
|
}
|
|
918
1110
|
|
|
919
1111
|
return Response.json({
|
|
@@ -924,7 +1116,9 @@ export async function handleSmsDoctor(): Promise<Response> {
|
|
|
924
1116
|
compliance: {
|
|
925
1117
|
status: complianceStatus,
|
|
926
1118
|
...(complianceDetail ? { detail: complianceDetail } : {}),
|
|
927
|
-
...(complianceRemediation
|
|
1119
|
+
...(complianceRemediation
|
|
1120
|
+
? { remediation: complianceRemediation }
|
|
1121
|
+
: {}),
|
|
928
1122
|
},
|
|
929
1123
|
...(lastSend ? { lastSend } : {}),
|
|
930
1124
|
overallStatus,
|