@vellumai/assistant 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +273 -10
- package/Dockerfile +2 -3
- package/bun.lock +5 -13
- package/docs/backup-troubleshooting.md +52 -0
- package/docs/browser-use-architecture-phase2.md +174 -0
- package/docs/stt-provider-onboarding.md +120 -0
- package/knip.json +12 -2
- package/node_modules/@vellumai/ces-contracts/bun.lock +8 -6
- package/node_modules/@vellumai/ces-contracts/package.json +3 -3
- package/openapi.yaml +982 -72
- package/package.json +4 -6
- package/scripts/generate-openapi.ts +0 -1
- package/scripts/test.sh +73 -18
- package/src/__tests__/agent-image-optimize.test.ts +28 -0
- package/src/__tests__/agent-loop.test.ts +123 -0
- package/src/__tests__/anthropic-provider.test.ts +263 -10
- package/src/__tests__/auto-analysis-end-to-end.test.ts +550 -0
- package/src/__tests__/auto-analysis-prompt.test.ts +50 -0
- package/src/__tests__/browser-fill-credential.test.ts +11 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/browser-skill-endstate.test.ts +31 -7
- package/src/__tests__/btw-routes.test.ts +7 -0
- package/src/__tests__/call-controller.test.ts +581 -20
- package/src/__tests__/catalog-files.test.ts +138 -0
- package/src/__tests__/channel-invite-transport.test.ts +2 -2
- package/src/__tests__/channel-readiness-routes.test.ts +16 -20
- package/src/__tests__/channel-readiness-service.test.ts +12 -7
- package/src/__tests__/checker.test.ts +157 -10
- package/src/__tests__/clawhub-files.test.ts +347 -0
- package/src/__tests__/commit-message-enrichment-service.test.ts +36 -19
- package/src/__tests__/config-analysis.test.ts +100 -0
- package/src/__tests__/config-schema.test.ts +1013 -66
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +43 -8
- package/src/__tests__/contact-store-user-file.test.ts +512 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-window-manager.test.ts +88 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +98 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +135 -0
- package/src/__tests__/conversation-error.test.ts +70 -0
- package/src/__tests__/conversation-history-web-search.test.ts +11 -4
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
- package/src/__tests__/conversation-launcher-skill-regression.test.ts +51 -0
- package/src/__tests__/conversation-list-source.test.ts +145 -0
- package/src/__tests__/conversation-pre-run-repair.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +901 -60
- package/src/__tests__/conversation-routes-disk-view.test.ts +270 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +55 -0
- package/src/__tests__/conversation-skill-tools.test.ts +7 -4
- package/src/__tests__/conversation-slash-commands.test.ts +33 -0
- package/src/__tests__/conversation-slash-queue.test.ts +89 -18
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +5 -3
- package/src/__tests__/credential-vault-unit.test.ts +379 -3
- package/src/__tests__/credentials-cli.test.ts +40 -16
- package/src/__tests__/cross-provider-web-search.test.ts +146 -35
- package/src/__tests__/deterministic-verification-control-plane.test.ts +10 -1
- package/src/__tests__/device-id.test.ts +112 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +167 -4
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -3
- package/src/__tests__/email-html-renderer.test.ts +71 -0
- package/src/__tests__/email-invite-adapter.test.ts +36 -32
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +75 -8
- package/src/__tests__/fixtures/mock-chrome-extension.ts +11 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/gemini-provider.test.ts +64 -0
- package/src/__tests__/get-skill-detail-audit.test.ts +325 -0
- package/src/__tests__/gmail-archive-fallback.test.ts +193 -0
- package/src/__tests__/gmail-archive-gate.test.ts +246 -0
- package/src/__tests__/gmail-preferences.test.ts +117 -0
- package/src/__tests__/headless-browser-interactions.test.ts +43 -0
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +142 -5
- package/src/__tests__/headless-browser-read-tools.test.ts +11 -0
- package/src/__tests__/headless-browser-snapshot.test.ts +10 -0
- package/src/__tests__/heartbeat-service.test.ts +70 -17
- package/src/__tests__/home-state-routes.test.ts +162 -0
- package/src/__tests__/host-bash-proxy.test.ts +0 -5
- package/src/__tests__/host-browser-e2e-cloud.test.ts +138 -4
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +4 -4
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +103 -0
- package/src/__tests__/host-cu-proxy.test.ts +0 -5
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/llm-context-normalization.test.ts +488 -0
- package/src/__tests__/llm-context-route-provider.test.ts +86 -5
- package/src/__tests__/llm-usage-store.test.ts +363 -0
- package/src/__tests__/media-stream-output.test.ts +555 -0
- package/src/__tests__/media-stream-parser.test.ts +374 -0
- package/src/__tests__/media-stream-server-integration.test.ts +1234 -0
- package/src/__tests__/media-stream-stt-session.test.ts +588 -0
- package/src/__tests__/media-turn-detector.test.ts +440 -0
- package/src/__tests__/message-queue.test.ts +125 -0
- package/src/__tests__/migration-export-http.test.ts +6 -6
- package/src/__tests__/migration-import-commit-http.test.ts +8 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +6 -5
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +151 -0
- package/src/__tests__/model-intents.test.ts +2 -2
- package/src/__tests__/oauth-apps-routes.test.ts +1 -0
- package/src/__tests__/oauth-cli.test.ts +2 -0
- package/src/__tests__/oauth-connect-orchestrator.test.ts +2 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +1 -0
- package/src/__tests__/oauth-providers-routes.test.ts +2 -0
- package/src/__tests__/oauth-store.test.ts +85 -0
- package/src/__tests__/oauth2-gateway-transport.test.ts +249 -6
- package/src/__tests__/onboarding-template-contract.test.ts +6 -13
- package/src/__tests__/openai-provider.test.ts +176 -0
- package/src/__tests__/openai-responses-cutover-guard.test.ts +184 -0
- package/src/__tests__/openai-responses-provider.test.ts +1105 -0
- package/src/__tests__/openrouter-token-estimation.test.ts +100 -0
- package/src/__tests__/outlook-unsubscribe.test.ts +31 -2
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +174 -0
- package/src/__tests__/qdrant-manager.test.ts +29 -8
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +194 -0
- package/src/__tests__/relationship-state-contract.test.ts +175 -0
- package/src/__tests__/relay-server.test.ts +423 -5
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-scanner-executor.test.ts +4 -0
- package/src/__tests__/secure-keys.test.ts +107 -0
- package/src/__tests__/send-endpoint-busy.test.ts +5 -1
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +49 -0
- package/src/__tests__/settings-routes.test.ts +201 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +276 -145
- package/src/__tests__/skills-files-catalog-fallback.test.ts +381 -93
- package/src/__tests__/skills.test.ts +5 -2
- package/src/__tests__/skillssh-files.test.ts +446 -0
- package/src/__tests__/slack-block-formatting.test.ts +110 -0
- package/src/__tests__/slack-channel-config.test.ts +564 -1
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/system-prompt.test.ts +112 -26
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +18 -7
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +9 -5
- package/src/__tests__/tool-executor-shell-integration.test.ts +4 -0
- package/src/__tests__/tool-executor.test.ts +33 -24
- package/src/__tests__/tool-result-truncation.test.ts +36 -0
- package/src/__tests__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +345 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +512 -114
- package/src/__tests__/twilio-routes.test.ts +376 -0
- package/src/__tests__/unicode.test.ts +293 -0
- package/src/__tests__/update-bulletin-format.test.ts +59 -0
- package/src/__tests__/update-bulletin.test.ts +206 -5
- package/src/__tests__/usage-routes.test.ts +25 -4
- package/src/__tests__/user-reference.test.ts +46 -61
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -0
- package/src/__tests__/voice-config-update.test.ts +403 -0
- package/src/__tests__/voice-quality.test.ts +434 -19
- package/src/__tests__/workspace-heartbeat-service.test.ts +7 -0
- package/src/__tests__/workspace-migration-033-stt-service-explicit-config.test.ts +547 -0
- package/src/__tests__/workspace-migration-034-remove-calls-voice-transcription-provider.test.ts +596 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +368 -0
- package/src/__tests__/workspace-migration-meets.test.ts +244 -0
- package/src/__tests__/workspace-migration-seed-device-id.test.ts +14 -20
- package/src/__tests__/workspace-policy.test.ts +2 -0
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +43 -3
- package/src/backup/__tests__/backup-key.test.ts +152 -0
- package/src/backup/__tests__/backup-worker.test.ts +767 -0
- package/src/backup/__tests__/list-snapshots.test.ts +87 -0
- package/src/backup/__tests__/local-writer.test.ts +218 -0
- package/src/backup/__tests__/offsite-writer.test.ts +641 -0
- package/src/backup/__tests__/paths.test.ts +300 -0
- package/src/backup/__tests__/restore.test.ts +498 -0
- package/src/backup/__tests__/snapshot-lock.test.ts +352 -0
- package/src/backup/__tests__/stream-crypt.test.ts +228 -0
- package/src/backup/backup-key.ts +137 -0
- package/src/backup/backup-worker.ts +459 -0
- package/src/backup/list-snapshots.ts +147 -0
- package/src/backup/local-writer.ts +133 -0
- package/src/backup/offsite-writer.ts +222 -0
- package/src/backup/paths.ts +226 -0
- package/src/backup/restore.ts +322 -0
- package/src/backup/snapshot-lock.ts +431 -0
- package/src/backup/stream-crypt.ts +263 -0
- package/src/bundler/package-resolver.ts +4 -0
- package/src/calls/audio-store.ts +11 -5
- package/src/calls/call-controller.ts +226 -71
- package/src/calls/call-domain.ts +9 -0
- package/src/calls/call-speech-output.ts +190 -0
- package/src/calls/call-transport.ts +77 -0
- package/src/calls/media-stream-audio-transcode.ts +173 -0
- package/src/calls/media-stream-output.ts +660 -0
- package/src/calls/media-stream-parser.ts +300 -0
- package/src/calls/media-stream-protocol.ts +166 -0
- package/src/calls/media-stream-server.ts +592 -0
- package/src/calls/media-stream-stt-session.ts +460 -0
- package/src/calls/media-turn-detector.ts +230 -0
- package/src/calls/relay-server.ts +90 -75
- package/src/calls/resolve-call-tts-provider.ts +136 -0
- package/src/calls/telephony-stt-routing.ts +145 -0
- package/src/calls/tts-call-strategy.ts +161 -0
- package/src/calls/tts-text-sanitizer.ts +32 -16
- package/src/calls/twilio-routes.ts +281 -17
- package/src/calls/voice-quality.ts +78 -35
- package/src/calls/voice-session-bridge.ts +8 -1
- package/src/channels/types.ts +16 -0
- package/src/cli/__tests__/run-assistant-command.ts +11 -1
- package/src/cli/commands/__tests__/backup.test.ts +1165 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +234 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +132 -0
- package/src/cli/commands/__tests__/email-attachment.test.ts +422 -0
- package/src/cli/commands/__tests__/email-download.test.ts +16 -1
- package/src/cli/commands/__tests__/email-list.test.ts +22 -4
- package/src/cli/commands/__tests__/email-register.test.ts +4 -4
- package/src/cli/commands/__tests__/email-send.test.ts +37 -4
- package/src/cli/commands/__tests__/email-status.test.ts +5 -1
- package/src/cli/commands/__tests__/email-unregister.test.ts +34 -5
- package/src/cli/commands/backup.ts +993 -0
- package/src/cli/commands/conversations.ts +77 -0
- package/src/cli/commands/credentials.ts +0 -1
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +255 -3
- package/src/cli/commands/oauth/__tests__/connect.test.ts +12 -0
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +1 -0
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -0
- package/src/cli/commands/oauth/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +15 -0
- package/src/cli/commands/oauth/shared.ts +2 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +4 -9
- package/src/cli/commands/platform/__tests__/connect.test.ts +6 -0
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +6 -0
- package/src/cli/program.ts +30 -4
- package/src/config/__tests__/backup-schema.test.ts +134 -0
- package/src/config/assistant-feature-flags.ts +61 -62
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +37 -1
- package/src/config/bundled-skills/browser/SKILL.md +30 -5
- package/src/config/bundled-skills/browser/TOOLS.json +123 -0
- package/src/config/bundled-skills/browser/tools/browser-attach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-detach.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-status.ts +12 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +17 -0
- package/src/config/bundled-skills/contacts/SKILL.md +2 -2
- package/src/config/bundled-skills/gmail/SKILL.md +53 -7
- package/src/config/bundled-skills/gmail/TOOLS.json +33 -3
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +116 -9
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +138 -11
- package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +59 -0
- package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +82 -0
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +113 -17
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -9
- package/src/config/bundled-skills/media-processing/TOOLS.json +1 -6
- package/src/config/bundled-skills/media-processing/__tests__/audio-transcribe.test.ts +125 -0
- package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +181 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +141 -0
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +32 -87
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +8 -4
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +0 -10
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +2 -2
- package/src/config/bundled-skills/outlook/SKILL.md +2 -2
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +2 -2
- package/src/config/bundled-skills/phone-calls/SKILL.md +2 -2
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +27 -18
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +3 -3
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +26 -22
- package/src/config/bundled-skills/slack/SKILL.md +1 -0
- package/src/config/bundled-skills/transcribe/SKILL.md +9 -14
- package/src/config/bundled-skills/transcribe/TOOLS.json +2 -7
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +256 -0
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +38 -188
- package/src/config/bundled-tool-registry.ts +8 -0
- package/src/config/env-registry.ts +24 -0
- package/src/config/env.ts +34 -10
- package/src/config/feature-flag-registry.json +46 -14
- package/src/config/loader.ts +26 -12
- package/src/config/schema.ts +35 -10
- package/src/config/schemas/__tests__/stt.test.ts +43 -0
- package/src/config/schemas/analysis.ts +51 -0
- package/src/config/schemas/backup.ts +72 -0
- package/src/config/schemas/calls.ts +1 -26
- package/src/config/schemas/elevenlabs.ts +0 -59
- package/src/config/schemas/filing.ts +47 -7
- package/src/config/schemas/heartbeat.ts +27 -5
- package/src/config/schemas/host-browser.ts +47 -1
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/services.ts +44 -0
- package/src/config/schemas/stt.ts +59 -0
- package/src/config/schemas/tts.ts +230 -0
- package/src/config/schemas/updates.ts +14 -0
- package/src/config/skills.ts +4 -0
- package/src/config/types.ts +4 -0
- package/src/contacts/contact-store.ts +56 -11
- package/src/contacts/contacts-write.ts +38 -1
- package/src/context/post-turn-tool-result-truncation.ts +3 -2
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +45 -12
- package/src/credential-execution/executable-discovery.ts +12 -2
- package/src/credential-execution/process-manager.ts +33 -2
- package/src/credential-health/credential-health-service.ts +366 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +324 -0
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +497 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +17 -8
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/config-watcher.ts +99 -5
- package/src/daemon/conversation-agent-loop-handlers.ts +6 -0
- package/src/daemon/conversation-agent-loop.ts +101 -24
- package/src/daemon/conversation-error.ts +11 -0
- package/src/daemon/conversation-history.ts +40 -6
- package/src/daemon/conversation-launch.ts +220 -0
- package/src/daemon/conversation-lifecycle.ts +59 -9
- package/src/daemon/conversation-messaging.ts +37 -3
- package/src/daemon/conversation-notifiers.ts +5 -0
- package/src/daemon/conversation-process.ts +581 -19
- package/src/daemon/conversation-queue-manager.ts +24 -0
- package/src/daemon/conversation-runtime-assembly.ts +11 -1
- package/src/daemon/conversation-slash.ts +36 -0
- package/src/daemon/conversation-surfaces.ts +94 -4
- package/src/daemon/conversation-tool-setup.ts +25 -0
- package/src/daemon/conversation-usage.ts +7 -4
- package/src/daemon/conversation.ts +86 -28
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +4 -1
- package/src/daemon/handlers/shared.ts +22 -0
- package/src/daemon/handlers/skills.ts +321 -77
- package/src/daemon/host-browser-proxy.ts +2 -1
- package/src/daemon/lifecycle.ts +122 -25
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/conversations.ts +34 -1
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +14 -0
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +16 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/server.ts +347 -2
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +9 -0
- package/src/email/html-renderer.ts +76 -0
- package/src/heartbeat/heartbeat-service.ts +93 -7
- package/src/home/__tests__/assistant-feed-authoring.test.ts +156 -0
- package/src/home/__tests__/emit-feed-event.test.ts +169 -0
- package/src/home/__tests__/feed-scheduler.test.ts +194 -0
- package/src/home/__tests__/feed-types.test.ts +275 -0
- package/src/home/__tests__/feed-writer.test.ts +688 -0
- package/src/home/__tests__/phase5-exit-criteria.test.ts +212 -0
- package/src/home/__tests__/platform-gmail-digest.test.ts +222 -0
- package/src/home/__tests__/progress-formula.test.ts +213 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +740 -0
- package/src/home/__tests__/rollup-producer.test.ts +398 -0
- package/src/home/assistant-feed-authoring.ts +124 -0
- package/src/home/emit-feed-event.ts +158 -0
- package/src/home/feed-scheduler.ts +247 -0
- package/src/home/feed-types.ts +181 -0
- package/src/home/feed-writer.ts +469 -0
- package/src/home/platform-gmail-digest.ts +163 -0
- package/src/home/progress-formula.ts +86 -0
- package/src/home/relationship-state-writer.ts +824 -0
- package/src/home/relationship-state.ts +143 -0
- package/src/home/rollup-producer.ts +384 -0
- package/src/hooks/runner.ts +7 -0
- package/src/inbound/platform-callback-registration.ts +12 -3
- package/src/inbound/public-ingress-urls.ts +12 -0
- package/src/instrument.ts +1 -1
- package/src/ipc/__tests__/cli-ipc.test.ts +200 -0
- package/src/ipc/cli-client.ts +151 -0
- package/src/ipc/cli-server.ts +234 -0
- package/src/ipc/gateway-client.ts +180 -0
- package/src/ipc/routes/index.ts +5 -0
- package/src/ipc/routes/wake-conversation.ts +19 -0
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +356 -0
- package/src/memory/__tests__/auto-analysis-guard.test.ts +57 -0
- package/src/memory/__tests__/conversation-analyze-job.test.ts +232 -0
- package/src/memory/__tests__/find-analysis-conversation.test.ts +196 -0
- package/src/memory/app-store.ts +1 -1
- package/src/memory/attachments-store.ts +70 -0
- package/src/memory/auto-analysis-enqueue.ts +127 -0
- package/src/memory/auto-analysis-guard.ts +27 -0
- package/src/memory/cleanup-schedule-state.ts +37 -0
- package/src/memory/conversation-analyze-job.ts +73 -0
- package/src/memory/conversation-crud.ts +99 -0
- package/src/memory/conversation-disk-view.ts +7 -0
- package/src/memory/conversation-group-migration.ts +34 -2
- package/src/memory/conversation-queries.ts +6 -5
- package/src/memory/db-init.ts +6 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/graph/conversation-graph-memory.ts +15 -0
- package/src/memory/graph/extraction.test.ts +23 -0
- package/src/memory/graph/extraction.ts +8 -0
- package/src/memory/graph/retriever.ts +27 -18
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/group-crud.ts +6 -1
- package/src/memory/indexer.ts +95 -16
- package/src/memory/job-handlers/cleanup.ts +11 -8
- package/src/memory/job-handlers/conversation-starters.ts +16 -10
- package/src/memory/jobs-store.ts +64 -4
- package/src/memory/jobs-worker.ts +22 -9
- package/src/memory/llm-usage-store.ts +92 -56
- package/src/memory/migrations/219-oauth-providers-token-exchange-body-format.ts +15 -0
- package/src/memory/migrations/220-normalize-user-file-by-principal.ts +190 -0
- package/src/memory/migrations/221-conversations-archived-at.ts +16 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/oauth.ts +3 -0
- package/src/memory/usage-buckets.ts +396 -0
- package/src/messaging/providers/gmail/client.ts +57 -6
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +282 -0
- package/src/messaging/providers/slack/adapter.ts +143 -38
- package/src/messaging/providers/slack/client.ts +16 -0
- package/src/messaging/providers/slack/types.ts +4 -0
- package/src/notifications/decision-engine.ts +3 -3
- package/src/notifications/signal.ts +5 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +1 -0
- package/src/oauth/byo-connection.test.ts +18 -1
- package/src/oauth/byo-connection.ts +3 -1
- package/src/oauth/connect-orchestrator.ts +2 -0
- package/src/oauth/connection-resolver.ts +6 -2
- package/src/oauth/connection.ts +2 -0
- package/src/oauth/oauth-store.ts +9 -0
- package/src/oauth/platform-connection.test.ts +98 -0
- package/src/oauth/platform-connection.ts +52 -31
- package/src/oauth/seed-providers.ts +7 -0
- package/src/permissions/checker.ts +16 -6
- package/src/permissions/defaults.ts +49 -1
- package/src/permissions/trust-store.ts +3 -3
- package/src/permissions/workspace-policy.ts +3 -0
- package/src/platform/client.test.ts +10 -0
- package/src/platform/sync-identity.ts +129 -0
- package/src/prompts/persona-resolver.ts +126 -2
- package/src/prompts/system-prompt.ts +59 -18
- package/src/prompts/templates/BOOTSTRAP.md +5 -5
- package/src/prompts/templates/SOUL.md +3 -1
- package/src/prompts/templates/UPDATES.md +12 -0
- package/src/prompts/templates/channels/slack.md +20 -0
- package/src/prompts/update-bulletin-format.ts +26 -9
- package/src/prompts/update-bulletin.ts +34 -23
- package/src/prompts/user-reference.ts +20 -17
- package/src/providers/__tests__/provider-secret-catalog.test.ts +42 -0
- package/src/providers/anthropic/client.ts +157 -61
- package/src/providers/fireworks/client.ts +2 -2
- package/src/providers/gemini/client.ts +9 -1
- package/src/providers/model-catalog.ts +6 -0
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/ollama/client.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +474 -0
- package/src/providers/openai/client.ts +25 -440
- package/src/providers/openai/responses-provider.ts +502 -0
- package/src/providers/openrouter/client.ts +101 -4
- package/src/providers/provider-secret-catalog.ts +139 -0
- package/src/providers/registry.ts +2 -2
- package/src/providers/retry.ts +14 -3
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +251 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +828 -0
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +980 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +767 -0
- package/src/providers/speech-to-text/deepgram.test.ts +332 -0
- package/src/providers/speech-to-text/deepgram.ts +115 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.test.ts +743 -0
- package/src/providers/speech-to-text/google-gemini-live-stream.ts +625 -0
- package/src/providers/speech-to-text/google-gemini.test.ts +226 -0
- package/src/providers/speech-to-text/google-gemini.ts +101 -0
- package/src/providers/speech-to-text/openai-whisper-stream.test.ts +564 -0
- package/src/providers/speech-to-text/openai-whisper-stream.ts +381 -0
- package/src/providers/speech-to-text/openai-whisper.test.ts +1 -37
- package/src/providers/speech-to-text/openai-whisper.ts +63 -33
- package/src/providers/speech-to-text/provider-catalog.ts +306 -0
- package/src/providers/speech-to-text/resolve.ts +386 -6
- package/src/providers/types.ts +9 -0
- package/src/runtime/AGENTS.md +43 -1
- package/src/runtime/__tests__/agent-wake.test.ts +831 -0
- package/src/runtime/__tests__/runtime-mode.test.ts +62 -0
- package/src/runtime/__tests__/slack-block-formatting.test.ts +481 -0
- package/src/runtime/agent-wake.ts +512 -0
- package/src/runtime/auth/__tests__/route-policy.test.ts +40 -0
- package/src/runtime/auth/route-policy.ts +30 -5
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/capability-tokens.ts +10 -10
- package/src/runtime/channel-invite-transport.ts +1 -1
- package/src/runtime/channel-invite-transports/email.ts +14 -6
- package/src/runtime/channel-readiness-service.ts +12 -22
- package/src/runtime/chrome-extension-registry.ts +38 -2
- package/src/runtime/http-server.ts +395 -10
- package/src/runtime/http-types.ts +6 -2
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +36 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/migration-transport.ts +1 -0
- package/src/runtime/migrations/migration-wizard.ts +1 -0
- package/src/runtime/migrations/vbundle-import-analyzer.ts +77 -1
- package/src/runtime/migrations/vbundle-importer.ts +34 -0
- package/src/runtime/pending-interactions.ts +0 -11
- package/src/runtime/routes/__tests__/backup-routes.test.ts +967 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +507 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +208 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +474 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +148 -17
- package/src/runtime/routes/app-management-routes.ts +12 -18
- package/src/runtime/routes/attachment-routes.test.ts +9 -3
- package/src/runtime/routes/attachment-routes.ts +216 -17
- package/src/runtime/routes/backup-routes.ts +519 -0
- package/src/runtime/routes/browser-extension-pair-routes.ts +82 -23
- package/src/runtime/routes/btw-routes.ts +8 -6
- package/src/runtime/routes/contact-routes.test.ts +298 -0
- package/src/runtime/routes/contact-routes.ts +132 -5
- package/src/runtime/routes/conversation-analysis-routes.ts +22 -142
- package/src/runtime/routes/conversation-management-routes.ts +115 -0
- package/src/runtime/routes/conversation-routes.ts +367 -146
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/home-feed-routes.ts +334 -0
- package/src/runtime/routes/home-state-routes.ts +138 -0
- package/src/runtime/routes/host-browser-routes.ts +3 -14
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +3 -17
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +46 -39
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +15 -15
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +137 -0
- package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +179 -0
- package/src/runtime/routes/integrations/slack/channel.ts +11 -3
- package/src/runtime/routes/integrations/slack/share.ts +45 -7
- package/src/runtime/routes/llm-context-normalization.ts +303 -0
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/migration-routes.ts +40 -5
- package/src/runtime/routes/settings-routes.ts +22 -5
- package/src/runtime/routes/skills-routes.ts +76 -7
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/surface-action-routes.ts +41 -2
- package/src/runtime/routes/tts-routes.ts +108 -24
- package/src/runtime/routes/usage-routes.ts +30 -2
- package/src/runtime/routes/user-route-dispatcher.ts +50 -5
- package/src/runtime/routes/user-routes.ts +13 -1
- package/src/runtime/routes/work-items-routes.ts +8 -1
- package/src/runtime/runtime-mode.ts +33 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +444 -0
- package/src/runtime/services/__tests__/analyze-deps-singleton.test.ts +67 -0
- package/src/runtime/services/__tests__/auto-analysis-prompt.test.ts +53 -0
- package/src/runtime/services/__tests__/manual-analysis-prompt.test.ts +41 -0
- package/src/runtime/services/analyze-conversation.ts +344 -0
- package/src/runtime/services/analyze-deps-singleton.ts +32 -0
- package/src/runtime/services/auto-analysis-prompt.ts +55 -0
- package/src/runtime/skill-route-registry.ts +49 -0
- package/src/runtime/slack-block-formatting.ts +437 -10
- package/src/schedule/scheduler.ts +50 -0
- package/src/security/oauth2.ts +26 -4
- package/src/security/secure-keys.ts +25 -2
- package/src/security/token-manager.ts +8 -0
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-files.ts +64 -2
- package/src/skills/category-inference.ts +122 -0
- package/src/skills/clawhub-files.ts +213 -0
- package/src/skills/clawhub.ts +84 -23
- package/src/skills/skill-file-provider.ts +40 -0
- package/src/skills/skillssh-files.ts +395 -0
- package/src/skills/skillssh-registry.ts +4 -4
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +392 -0
- package/src/stt/__tests__/types.test.ts +89 -0
- package/src/stt/daemon-batch-transcriber.ts +195 -0
- package/src/stt/stt-stream-session.ts +499 -0
- package/src/stt/types.ts +330 -0
- package/src/stt/wav-encoder.test.ts +373 -0
- package/src/stt/wav-encoder.ts +175 -0
- package/src/subagent/manager.ts +38 -14
- package/src/tools/browser/__tests__/browser-mode.test.ts +119 -0
- package/src/tools/browser/__tests__/browser-status.test.ts +123 -0
- package/src/tools/browser/browser-execution.ts +1163 -23
- package/src/tools/browser/browser-manager.ts +45 -0
- package/src/tools/browser/browser-mode-constants.ts +12 -0
- package/src/tools/browser/browser-mode.ts +92 -0
- package/src/tools/browser/browser-status-constants.ts +33 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +393 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +29 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1648 -32
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +264 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +183 -17
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +254 -21
- package/src/tools/browser/cdp-client/errors.ts +15 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +39 -16
- package/src/tools/browser/cdp-client/factory.ts +797 -87
- package/src/tools/browser/cdp-client/index.ts +16 -2
- package/src/tools/browser/cdp-client/types.ts +68 -0
- package/src/tools/credentials/vault.ts +35 -6
- package/src/tools/network/web-fetch.ts +5 -2
- package/src/tools/network/web-search.ts +5 -2
- package/src/tools/shared/shell-output.ts +3 -1
- package/src/tools/side-effects.ts +2 -0
- package/src/tools/skills/sandbox-runner.ts +3 -2
- package/src/tools/terminal/safe-env.ts +10 -2
- package/src/tools/terminal/shell.ts +15 -4
- package/src/tools/tool-manifest.ts +21 -0
- package/src/tools/types.ts +17 -0
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tts/__tests__/provider-adapters.test.ts +834 -0
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +196 -0
- package/src/tts/__tests__/provider-catalog.test.ts +183 -0
- package/src/tts/__tests__/provider-registry.test.ts +90 -0
- package/src/tts/provider-catalog.ts +201 -0
- package/src/tts/provider-registry.ts +73 -0
- package/src/tts/providers/deepgram-provider.ts +219 -0
- package/src/tts/providers/elevenlabs-provider.ts +211 -0
- package/src/tts/providers/fish-audio-provider.ts +183 -0
- package/src/tts/providers/index.ts +42 -0
- package/src/tts/providers/register-builtins.ts +130 -0
- package/src/tts/synthesize-text.ts +110 -0
- package/src/tts/tts-config-resolver.ts +78 -0
- package/src/tts/types.ts +153 -0
- package/src/types/onboarding-context.ts +7 -0
- package/src/util/abort-reasons.ts +58 -0
- package/src/util/device-id.ts +32 -16
- package/src/util/errors.ts +9 -1
- package/src/util/platform.ts +54 -10
- package/src/util/pricing.ts +66 -3
- package/src/util/spawn.ts +1 -1
- package/src/util/truncate.ts +4 -2
- package/src/util/unicode.ts +201 -0
- package/src/version.ts +19 -24
- package/src/watcher/engine.ts +23 -0
- package/src/watcher/watcher-store.ts +31 -0
- package/src/workspace/migrations/003-seed-device-id.ts +9 -3
- package/src/workspace/migrations/017-seed-persona-dirs.ts +68 -4
- package/src/workspace/migrations/029-seed-pkb.ts +1 -1
- package/src/workspace/migrations/031-drop-user-md.ts +317 -0
- package/src/workspace/migrations/031-llm-log-retention-zero-to-null.ts +73 -0
- package/src/workspace/migrations/032-tts-provider-unification.ts +227 -0
- package/src/workspace/migrations/033-stt-service-explicit-config.ts +122 -0
- package/src/workspace/migrations/034-remove-calls-voice-transcription-provider.ts +215 -0
- package/src/workspace/migrations/035-seed-slack-channel-persona.ts +50 -0
- package/src/workspace/migrations/036-update-pkb-index-bar.ts +37 -0
- package/src/workspace/migrations/037-create-meets-dir.ts +61 -0
- package/src/workspace/migrations/registry.ts +16 -0
- package/src/workspace/top-level-renderer.ts +13 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- package/src/cli/commands/browser-relay.ts +0 -466
- package/src/email/guardrails.ts +0 -221
- package/src/email/provider.ts +0 -117
- package/src/email/providers/agentmail.ts +0 -361
- package/src/email/providers/index.ts +0 -65
- package/src/email/service.ts +0 -384
- package/src/email/types.ts +0 -126
- package/src/prompts/templates/USER.md +0 -13
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/runtime/routes/browser-cdp-routes.ts +0 -229
|
@@ -37,9 +37,9 @@ import {
|
|
|
37
37
|
} from "../../runtime/routes/workspace-utils.js";
|
|
38
38
|
import { getCatalog } from "../../skills/catalog-cache.js";
|
|
39
39
|
import {
|
|
40
|
+
catalogSkillToSlim,
|
|
41
|
+
createVellumCatalogProvider,
|
|
40
42
|
hasHiddenOrSkippedSegment,
|
|
41
|
-
readCatalogSkillFileContent,
|
|
42
|
-
readCatalogSkillFiles,
|
|
43
43
|
sanitizeRelativePath,
|
|
44
44
|
type SkillFileEntry,
|
|
45
45
|
SKIP_DIRS,
|
|
@@ -50,6 +50,8 @@ import {
|
|
|
50
50
|
upsertSkillsIndex,
|
|
51
51
|
} from "../../skills/catalog-install.js";
|
|
52
52
|
import { filterByQuery } from "../../skills/catalog-search.js";
|
|
53
|
+
import type { SkillCategory } from "../../skills/category-inference.js";
|
|
54
|
+
import { inferCategory } from "../../skills/category-inference.js";
|
|
53
55
|
import {
|
|
54
56
|
clawhubCheckUpdates,
|
|
55
57
|
clawhubInspect,
|
|
@@ -58,6 +60,7 @@ import {
|
|
|
58
60
|
clawhubSearch,
|
|
59
61
|
clawhubUpdate,
|
|
60
62
|
} from "../../skills/clawhub.js";
|
|
63
|
+
import { createClawhubProvider } from "../../skills/clawhub-files.js";
|
|
61
64
|
import {
|
|
62
65
|
readInstallMeta,
|
|
63
66
|
type SkillInstallMeta,
|
|
@@ -68,10 +71,14 @@ import {
|
|
|
68
71
|
removeSkillsIndexEntry,
|
|
69
72
|
validateManagedSkillId,
|
|
70
73
|
} from "../../skills/managed-store.js";
|
|
74
|
+
import type { SkillFileProvider } from "../../skills/skill-file-provider.js";
|
|
75
|
+
import { createSkillsShProvider } from "../../skills/skillssh-files.js";
|
|
71
76
|
import {
|
|
77
|
+
fetchSkillAudits,
|
|
72
78
|
installExternalSkill,
|
|
73
79
|
resolveSkillSource,
|
|
74
80
|
searchSkillsRegistry,
|
|
81
|
+
type SkillAuditData,
|
|
75
82
|
} from "../../skills/skillssh-registry.js";
|
|
76
83
|
import { getWorkspaceSkillsDir } from "../../util/platform.js";
|
|
77
84
|
import type {
|
|
@@ -79,6 +86,10 @@ import type {
|
|
|
79
86
|
SkillFileContentResponse,
|
|
80
87
|
SlimSkillResponse,
|
|
81
88
|
} from "../message-types/skills.js";
|
|
89
|
+
|
|
90
|
+
// Re-export for use by route layer and future consumers.
|
|
91
|
+
export type { SkillCategory };
|
|
92
|
+
export { inferCategory };
|
|
82
93
|
import {
|
|
83
94
|
CONFIG_RELOAD_DEBOUNCE_MS,
|
|
84
95
|
ensureSkillEntry,
|
|
@@ -100,6 +111,62 @@ export interface SkillOperationContext {
|
|
|
100
111
|
broadcast: HandlerContext["broadcast"];
|
|
101
112
|
}
|
|
102
113
|
|
|
114
|
+
// ─── Provider chain for uninstalled skill file preview ───────────────────────
|
|
115
|
+
// Ordered by priority: vellum first (most common and cheapest to check),
|
|
116
|
+
// then skills.sh, then clawhub.
|
|
117
|
+
//
|
|
118
|
+
// Lazy-initialized on first access so that mock modules (in tests) can
|
|
119
|
+
// replace the factory functions before providers are constructed.
|
|
120
|
+
|
|
121
|
+
let _fileProviders: SkillFileProvider[] | null = null;
|
|
122
|
+
|
|
123
|
+
function getFileProviders(): SkillFileProvider[] {
|
|
124
|
+
if (!_fileProviders) {
|
|
125
|
+
_fileProviders = [
|
|
126
|
+
createVellumCatalogProvider(),
|
|
127
|
+
createSkillsShProvider(),
|
|
128
|
+
createClawhubProvider(),
|
|
129
|
+
];
|
|
130
|
+
}
|
|
131
|
+
return _fileProviders;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** @internal Exported for test use only — forces re-creation of providers. */
|
|
135
|
+
export function _resetFileProvidersForTest(): void {
|
|
136
|
+
_fileProviders = null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function resolveSkillFiles(skillId: string): Promise<{
|
|
140
|
+
handled: boolean;
|
|
141
|
+
skill: SlimSkillResponse | null;
|
|
142
|
+
files: SkillFileEntry[] | null;
|
|
143
|
+
}> {
|
|
144
|
+
for (const provider of getFileProviders()) {
|
|
145
|
+
if (!provider.canHandle(skillId)) continue;
|
|
146
|
+
// Commit to this provider — don't fall through to subsequent providers.
|
|
147
|
+
const files = await provider.listFiles(skillId);
|
|
148
|
+
if (files === null) return { handled: true, skill: null, files: null };
|
|
149
|
+
const skill = await provider.toSlimSkill(skillId);
|
|
150
|
+
if (skill === null) return { handled: true, skill: null, files: null };
|
|
151
|
+
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
152
|
+
return { handled: true, skill, files };
|
|
153
|
+
}
|
|
154
|
+
return { handled: false, skill: null, files: null };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async function resolveSkillFileContent(
|
|
158
|
+
skillId: string,
|
|
159
|
+
sanitizedPath: string,
|
|
160
|
+
): Promise<{ handled: boolean; result: SkillFileEntry | null }> {
|
|
161
|
+
for (const provider of getFileProviders()) {
|
|
162
|
+
if (!provider.canHandle(skillId)) continue;
|
|
163
|
+
// Commit to this provider — don't fall through to subsequent providers.
|
|
164
|
+
const result = await provider.readFileContent(skillId, sanitizedPath);
|
|
165
|
+
return { handled: true, result };
|
|
166
|
+
}
|
|
167
|
+
return { handled: false, result: null };
|
|
168
|
+
}
|
|
169
|
+
|
|
103
170
|
// ─── Frontmatter parsing ─────────────────────────────────────────────────────
|
|
104
171
|
|
|
105
172
|
const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
@@ -326,6 +393,7 @@ function toSlimSkillResponse(
|
|
|
326
393
|
stars: 0,
|
|
327
394
|
installs: 0,
|
|
328
395
|
reports: 0,
|
|
396
|
+
version: "",
|
|
329
397
|
};
|
|
330
398
|
}
|
|
331
399
|
case "skillssh": {
|
|
@@ -399,6 +467,138 @@ export async function listSkillsWithCatalog(
|
|
|
399
467
|
return merged;
|
|
400
468
|
}
|
|
401
469
|
|
|
470
|
+
// ─── Filtered skill listing ──────────────────────────────────────────────────
|
|
471
|
+
|
|
472
|
+
export interface SkillListFilter {
|
|
473
|
+
origin?: string;
|
|
474
|
+
kind?: string;
|
|
475
|
+
q?: string;
|
|
476
|
+
category?: string;
|
|
477
|
+
includeCatalog?: boolean;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/** Human-readable labels matching Swift's `sourceLabel`. */
|
|
481
|
+
export function originDisplayLabel(origin: string): string {
|
|
482
|
+
switch (origin) {
|
|
483
|
+
case "vellum":
|
|
484
|
+
return "Vellum";
|
|
485
|
+
case "clawhub":
|
|
486
|
+
return "Clawhub";
|
|
487
|
+
case "skillssh":
|
|
488
|
+
return "skills.sh";
|
|
489
|
+
case "custom":
|
|
490
|
+
return "Custom";
|
|
491
|
+
default:
|
|
492
|
+
return origin;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/** Check if a skill's origin matches a text query (matching Swift logic). */
|
|
497
|
+
export function originMatchesQuery(origin: string, query: string): boolean {
|
|
498
|
+
const label = originDisplayLabel(origin).toLowerCase();
|
|
499
|
+
if (label.includes(query)) return true;
|
|
500
|
+
// "community" umbrella matches clawhub and skillssh
|
|
501
|
+
if (
|
|
502
|
+
(origin === "clawhub" || origin === "skillssh") &&
|
|
503
|
+
"community".includes(query)
|
|
504
|
+
) {
|
|
505
|
+
return true;
|
|
506
|
+
}
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* List skills with filtering, category counts, and sorting.
|
|
512
|
+
* Calls listSkillsWithCatalog for the full merged list, then applies filters.
|
|
513
|
+
*/
|
|
514
|
+
export async function listSkillsFiltered(
|
|
515
|
+
filter: SkillListFilter,
|
|
516
|
+
ctx: SkillOperationContext,
|
|
517
|
+
): Promise<{
|
|
518
|
+
skills: SlimSkillResponse[];
|
|
519
|
+
categoryCounts: Record<string, number>;
|
|
520
|
+
totalCount: number;
|
|
521
|
+
}> {
|
|
522
|
+
let skills =
|
|
523
|
+
filter.includeCatalog !== false
|
|
524
|
+
? await listSkillsWithCatalog(ctx)
|
|
525
|
+
: listSkills(ctx);
|
|
526
|
+
|
|
527
|
+
// Apply origin filter
|
|
528
|
+
if (filter.origin) {
|
|
529
|
+
skills = skills.filter((s) => s.origin === filter.origin);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Apply kind/status filter
|
|
533
|
+
if (filter.kind) {
|
|
534
|
+
switch (filter.kind) {
|
|
535
|
+
case "installed":
|
|
536
|
+
skills = skills.filter(
|
|
537
|
+
(s) => s.kind === "installed" || s.kind === "bundled",
|
|
538
|
+
);
|
|
539
|
+
break;
|
|
540
|
+
case "available":
|
|
541
|
+
skills = skills.filter((s) => s.status === "available");
|
|
542
|
+
break;
|
|
543
|
+
default:
|
|
544
|
+
skills = skills.filter((s) => s.kind === filter.kind);
|
|
545
|
+
break;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Apply text search
|
|
550
|
+
if (filter.q) {
|
|
551
|
+
const query = filter.q.trim().toLowerCase();
|
|
552
|
+
if (query) {
|
|
553
|
+
skills = skills.filter((s) => {
|
|
554
|
+
if (s.name.toLowerCase().includes(query)) return true;
|
|
555
|
+
if (s.description.toLowerCase().includes(query)) return true;
|
|
556
|
+
if (s.id.toLowerCase().includes(query)) return true;
|
|
557
|
+
if (originMatchesQuery(s.origin, query)) return true;
|
|
558
|
+
return false;
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Compute category counts BEFORE applying the category filter
|
|
564
|
+
const categoryCounts: Record<string, number> = {};
|
|
565
|
+
for (const s of skills) {
|
|
566
|
+
const cat = inferCategory(s.name, s.description);
|
|
567
|
+
categoryCounts[cat] = (categoryCounts[cat] ?? 0) + 1;
|
|
568
|
+
}
|
|
569
|
+
const totalCount = skills.length;
|
|
570
|
+
|
|
571
|
+
// Apply category filter
|
|
572
|
+
if (filter.category) {
|
|
573
|
+
skills = skills.filter(
|
|
574
|
+
(s) => inferCategory(s.name, s.description) === filter.category,
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Sort: installed first, community origins before core within installed,
|
|
579
|
+
// then alphabetical by name (matching Swift sorting logic)
|
|
580
|
+
skills.sort((a, b) => {
|
|
581
|
+
// Installed (bundled + installed) before catalog (available)
|
|
582
|
+
const aInstalled = a.kind === "installed" || a.kind === "bundled" ? 0 : 1;
|
|
583
|
+
const bInstalled = b.kind === "installed" || b.kind === "bundled" ? 0 : 1;
|
|
584
|
+
if (aInstalled !== bInstalled) return aInstalled - bInstalled;
|
|
585
|
+
|
|
586
|
+
// Within installed, community origins (clawhub, skillssh) before core (vellum)
|
|
587
|
+
if (aInstalled === 0 && bInstalled === 0) {
|
|
588
|
+
const aCommunity =
|
|
589
|
+
a.origin === "clawhub" || a.origin === "skillssh" ? 0 : 1;
|
|
590
|
+
const bCommunity =
|
|
591
|
+
b.origin === "clawhub" || b.origin === "skillssh" ? 0 : 1;
|
|
592
|
+
if (aCommunity !== bCommunity) return aCommunity - bCommunity;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// Alphabetical by name
|
|
596
|
+
return a.name.localeCompare(b.name);
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
return { skills, categoryCounts, totalCount };
|
|
600
|
+
}
|
|
601
|
+
|
|
402
602
|
/** Look up a single skill by ID from the resolved catalog, returning its SlimSkillResponse. */
|
|
403
603
|
function findSkillById(
|
|
404
604
|
skillId: string,
|
|
@@ -420,6 +620,32 @@ export async function getSkill(
|
|
|
420
620
|
): Promise<{ skill: SkillDetailResponse } | { error: string; status: number }> {
|
|
421
621
|
const found = findSkillById(skillId);
|
|
422
622
|
if (!found) {
|
|
623
|
+
// Fallback: skill is not installed. Try all file providers.
|
|
624
|
+
for (const provider of getFileProviders()) {
|
|
625
|
+
if (!provider.canHandle(skillId)) continue;
|
|
626
|
+
// Commit to this provider — don't fall through to subsequent providers.
|
|
627
|
+
const slim = await provider.toSlimSkill(skillId);
|
|
628
|
+
if (slim) {
|
|
629
|
+
// Enrich uninstalled skills.sh skills with audit data (non-fatal)
|
|
630
|
+
if (slim.origin === "skillssh") {
|
|
631
|
+
try {
|
|
632
|
+
const sourceRepo = slim.sourceRepo;
|
|
633
|
+
const skillSlug = slim.slug.split("/").pop() ?? slim.slug;
|
|
634
|
+
const audits = await fetchSkillAudits(sourceRepo, [skillSlug]);
|
|
635
|
+
if (audits[skillSlug]) {
|
|
636
|
+
(slim as { audit?: SkillAuditData }).audit = audits[skillSlug];
|
|
637
|
+
}
|
|
638
|
+
} catch (err) {
|
|
639
|
+
log.warn(
|
|
640
|
+
{ err, skillId },
|
|
641
|
+
"Failed to enrich uninstalled skillssh skill with audit data",
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
return { skill: slim as SkillDetailResponse };
|
|
646
|
+
}
|
|
647
|
+
return { error: `Skill "${skillId}" not found`, status: 404 };
|
|
648
|
+
}
|
|
423
649
|
return { error: `Skill "${skillId}" not found`, status: 404 };
|
|
424
650
|
}
|
|
425
651
|
|
|
@@ -443,6 +669,7 @@ export async function getSkill(
|
|
|
443
669
|
installs: slim.installs,
|
|
444
670
|
reports: slim.reports,
|
|
445
671
|
publishedAt: slim.publishedAt,
|
|
672
|
+
version: slim.version,
|
|
446
673
|
};
|
|
447
674
|
try {
|
|
448
675
|
const inspectResult = await clawhubInspect(slim.slug);
|
|
@@ -477,6 +704,20 @@ export async function getSkill(
|
|
|
477
704
|
sourceRepo: slim.sourceRepo,
|
|
478
705
|
installs: slim.installs,
|
|
479
706
|
};
|
|
707
|
+
// Enrich with audit data (non-fatal on failure)
|
|
708
|
+
try {
|
|
709
|
+
const sourceRepo = slim.sourceRepo;
|
|
710
|
+
const skillSlug = slim.slug.split("/").pop() ?? slim.slug;
|
|
711
|
+
const audits = await fetchSkillAudits(sourceRepo, [skillSlug]);
|
|
712
|
+
if (audits[skillSlug]) {
|
|
713
|
+
(detail as { audit?: SkillAuditData }).audit = audits[skillSlug];
|
|
714
|
+
}
|
|
715
|
+
} catch (err) {
|
|
716
|
+
log.warn(
|
|
717
|
+
{ err, skillId },
|
|
718
|
+
"Failed to enrich skillssh skill detail with audit data",
|
|
719
|
+
);
|
|
720
|
+
}
|
|
480
721
|
return { skill: detail };
|
|
481
722
|
}
|
|
482
723
|
|
|
@@ -566,35 +807,15 @@ function readDirRecursive(dir: string, rootDir: string): SkillFileEntry[] {
|
|
|
566
807
|
}
|
|
567
808
|
|
|
568
809
|
/**
|
|
569
|
-
*
|
|
570
|
-
* shaped for the "available catalog skill" case. Shared between
|
|
571
|
-
* `listSkillsWithCatalog` (merging catalog entries into the installed list)
|
|
572
|
-
* and `getSkillFiles` (catalog fallback for preview listings). Keeping the
|
|
573
|
-
* mapping in one place avoids divergence between the list and detail paths.
|
|
574
|
-
*/
|
|
575
|
-
function catalogSkillToSlim(cs: CatalogSkill): SlimSkillResponse {
|
|
576
|
-
return {
|
|
577
|
-
id: cs.id,
|
|
578
|
-
name: cs.metadata?.vellum?.["display-name"] ?? cs.name,
|
|
579
|
-
description: cs.description,
|
|
580
|
-
emoji: cs.emoji,
|
|
581
|
-
kind: "catalog",
|
|
582
|
-
origin: "vellum",
|
|
583
|
-
status: "available",
|
|
584
|
-
};
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
* Read a single file's content from an installed or catalog skill.
|
|
810
|
+
* Read a single file's content from an installed or uninstalled skill.
|
|
589
811
|
*
|
|
590
812
|
* Installed-skill path (eager): reads the file directly from the skill's
|
|
591
813
|
* on-disk directory. Applies lexical containment, symlink rejection, and
|
|
592
814
|
* realpath containment checks for defense in depth.
|
|
593
815
|
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
*
|
|
597
|
-
* checkout path and the platform preview API path internally.
|
|
816
|
+
* Provider chain fallback: when the skill id is not backed by a local
|
|
817
|
+
* directory, iterates the file-provider chain (vellum catalog,
|
|
818
|
+
* skills.sh, clawhub) until one returns content.
|
|
598
819
|
*/
|
|
599
820
|
export async function getSkillFileContent(
|
|
600
821
|
skillId: string,
|
|
@@ -701,32 +922,23 @@ export async function getSkillFileContent(
|
|
|
701
922
|
};
|
|
702
923
|
}
|
|
703
924
|
|
|
704
|
-
//
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
return { error: "Skill not found", status: 404 };
|
|
925
|
+
// Fallback: skill is not installed. Try all file providers.
|
|
926
|
+
const { handled, result } = await resolveSkillFileContent(skillId, sanitized);
|
|
927
|
+
if (handled && result) {
|
|
928
|
+
return {
|
|
929
|
+
path: result.path,
|
|
930
|
+
name: result.name,
|
|
931
|
+
size: result.size,
|
|
932
|
+
mimeType: result.mimeType,
|
|
933
|
+
isBinary: result.isBinary,
|
|
934
|
+
content: result.content,
|
|
935
|
+
};
|
|
716
936
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
if (!result) {
|
|
937
|
+
if (handled) {
|
|
938
|
+
// A provider claimed this skill but the specific file wasn't found.
|
|
720
939
|
return { error: "File not found", status: 404 };
|
|
721
940
|
}
|
|
722
|
-
return {
|
|
723
|
-
path: result.path,
|
|
724
|
-
name: result.name,
|
|
725
|
-
size: result.size,
|
|
726
|
-
mimeType: result.mimeType,
|
|
727
|
-
isBinary: result.isBinary,
|
|
728
|
-
content: result.content,
|
|
729
|
-
};
|
|
941
|
+
return { error: "Skill not found", status: 404 };
|
|
730
942
|
}
|
|
731
943
|
|
|
732
944
|
export async function getSkillFiles(
|
|
@@ -758,31 +970,16 @@ export async function getSkillFiles(
|
|
|
758
970
|
};
|
|
759
971
|
}
|
|
760
972
|
|
|
761
|
-
// Fallback: skill is not installed. Try
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
try {
|
|
766
|
-
catalog = await getCatalog();
|
|
767
|
-
} catch {
|
|
768
|
-
return { error: `Skill "${skillId}" not found`, status: 404 };
|
|
769
|
-
}
|
|
770
|
-
const cs = catalog.find((c) => c.id === skillId);
|
|
771
|
-
if (!cs) {
|
|
772
|
-
return { error: `Skill "${skillId}" not found`, status: 404 };
|
|
973
|
+
// Fallback: skill is not installed. Try all file providers.
|
|
974
|
+
const resolved = await resolveSkillFiles(skillId);
|
|
975
|
+
if (resolved.handled && resolved.skill && resolved.files) {
|
|
976
|
+
return { skill: resolved.skill, files: resolved.files };
|
|
773
977
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
return {
|
|
778
|
-
error: `Skill files unavailable for "${skillId}"`,
|
|
779
|
-
status: 404,
|
|
780
|
-
};
|
|
978
|
+
if (resolved.handled) {
|
|
979
|
+
// A provider claimed this skill but couldn't produce files/metadata.
|
|
980
|
+
return { error: `Skill files unavailable for "${skillId}"`, status: 404 };
|
|
781
981
|
}
|
|
782
|
-
|
|
783
|
-
const skill = catalogSkillToSlim(cs);
|
|
784
|
-
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
785
|
-
return { skill, files };
|
|
982
|
+
return { error: `Skill "${skillId}" not found`, status: 404 };
|
|
786
983
|
}
|
|
787
984
|
|
|
788
985
|
export function enableSkill(
|
|
@@ -871,7 +1068,9 @@ export async function installSkill(
|
|
|
871
1068
|
contactId?: string;
|
|
872
1069
|
},
|
|
873
1070
|
ctx: SkillOperationContext,
|
|
874
|
-
): Promise<
|
|
1071
|
+
): Promise<
|
|
1072
|
+
{ success: true; skillId: string } | { success: false; error: string }
|
|
1073
|
+
> {
|
|
875
1074
|
try {
|
|
876
1075
|
// Bundled skills are already available — no install needed
|
|
877
1076
|
const catalog = loadSkillCatalog();
|
|
@@ -916,7 +1115,7 @@ export async function installSkill(
|
|
|
916
1115
|
}
|
|
917
1116
|
seedSkillGraphNodes();
|
|
918
1117
|
void seedUninstalledCatalogSkillMemories().catch(() => {});
|
|
919
|
-
return { success: true };
|
|
1118
|
+
return { success: true, skillId: spec.slug };
|
|
920
1119
|
}
|
|
921
1120
|
|
|
922
1121
|
// Check the Vellum catalog (first-party skills hosted on the platform).
|
|
@@ -937,7 +1136,7 @@ export async function installSkill(
|
|
|
937
1136
|
|
|
938
1137
|
const skillDir = join(getWorkspaceSkillsDir(), spec.slug);
|
|
939
1138
|
postInstallSkill(spec.slug, skillDir, ctx);
|
|
940
|
-
return { success: true };
|
|
1139
|
+
return { success: true, skillId: spec.slug };
|
|
941
1140
|
}
|
|
942
1141
|
} catch (err) {
|
|
943
1142
|
// If catalog lookup/install fails, fall through to community registries
|
|
@@ -965,7 +1164,7 @@ export async function installSkill(
|
|
|
965
1164
|
|
|
966
1165
|
const skillDir = join(getWorkspaceSkillsDir(), resolved.skillSlug);
|
|
967
1166
|
postInstallSkill(resolved.skillSlug, skillDir, ctx);
|
|
968
|
-
return { success: true };
|
|
1167
|
+
return { success: true, skillId: resolved.skillSlug };
|
|
969
1168
|
}
|
|
970
1169
|
|
|
971
1170
|
// Install from clawhub (community)
|
|
@@ -993,7 +1192,7 @@ export async function installSkill(
|
|
|
993
1192
|
upsertSkillsIndex(skillId);
|
|
994
1193
|
|
|
995
1194
|
postInstallSkill(skillId, skillDir, ctx);
|
|
996
|
-
return { success: true };
|
|
1195
|
+
return { success: true, skillId };
|
|
997
1196
|
} catch (err) {
|
|
998
1197
|
const message = err instanceof Error ? err.message : String(err);
|
|
999
1198
|
log.error({ err }, "Failed to install skill");
|
|
@@ -1166,6 +1365,7 @@ export async function searchSkills(
|
|
|
1166
1365
|
publishedAt: s.createdAt
|
|
1167
1366
|
? new Date(s.createdAt * 1000).toISOString()
|
|
1168
1367
|
: undefined,
|
|
1368
|
+
version: s.version,
|
|
1169
1369
|
}));
|
|
1170
1370
|
} else {
|
|
1171
1371
|
log.warn(
|
|
@@ -1187,6 +1387,50 @@ export async function searchSkills(
|
|
|
1187
1387
|
sourceRepo: r.source,
|
|
1188
1388
|
installs: r.installs,
|
|
1189
1389
|
}));
|
|
1390
|
+
|
|
1391
|
+
// Batch-fetch audit data for skills.sh results, grouped by source repo.
|
|
1392
|
+
try {
|
|
1393
|
+
if (skillsshResult.value.length > 0) {
|
|
1394
|
+
const sourceToSlugs = new Map<string, string[]>();
|
|
1395
|
+
for (const r of skillsshResult.value) {
|
|
1396
|
+
const slugs = sourceToSlugs.get(r.source) ?? [];
|
|
1397
|
+
slugs.push(r.skillId);
|
|
1398
|
+
sourceToSlugs.set(r.source, slugs);
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
const auditResults = await Promise.allSettled(
|
|
1402
|
+
[...sourceToSlugs.entries()].map(([source, slugs]) =>
|
|
1403
|
+
fetchSkillAudits(source, slugs).then((audits) => ({
|
|
1404
|
+
source,
|
|
1405
|
+
audits,
|
|
1406
|
+
})),
|
|
1407
|
+
),
|
|
1408
|
+
);
|
|
1409
|
+
|
|
1410
|
+
// Build a lookup map keyed by full skill ID (e.g. "owner/repo/skill-name")
|
|
1411
|
+
const auditMap = new Map<string, SkillAuditData>();
|
|
1412
|
+
for (const result of auditResults) {
|
|
1413
|
+
if (result.status !== "fulfilled") continue;
|
|
1414
|
+
const { source, audits } = result.value;
|
|
1415
|
+
for (const [skillSlug, auditData] of Object.entries(audits)) {
|
|
1416
|
+
auditMap.set(`${source}/${skillSlug}`, auditData);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
// Enrich each skills.sh skill with audit data
|
|
1421
|
+
skillsshSkills = skillsshSkills.map((skill) => {
|
|
1422
|
+
if (skill.origin !== "skillssh") return skill;
|
|
1423
|
+
const audit = auditMap.get(skill.id);
|
|
1424
|
+
if (!audit) return skill;
|
|
1425
|
+
return { ...skill, audit };
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1428
|
+
} catch (err) {
|
|
1429
|
+
log.warn(
|
|
1430
|
+
{ err },
|
|
1431
|
+
"Audit fetch failed for skills.sh results, continuing without audit data",
|
|
1432
|
+
);
|
|
1433
|
+
}
|
|
1190
1434
|
} else {
|
|
1191
1435
|
log.warn(
|
|
1192
1436
|
{ err: skillsshResult.reason },
|
|
@@ -77,7 +77,8 @@ export class HostBrowserProxy {
|
|
|
77
77
|
"Host browser proxy request timed out",
|
|
78
78
|
);
|
|
79
79
|
resolve({
|
|
80
|
-
content:
|
|
80
|
+
content:
|
|
81
|
+
"Host browser proxy timed out waiting for extension response (check browser-relay connectivity and /v1/host-browser-result callback failures such as 404/401).",
|
|
81
82
|
isError: true,
|
|
82
83
|
});
|
|
83
84
|
}, timeoutSec * 1000);
|