@vellumai/assistant 0.6.2 → 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 +41 -49
- package/bunfig.toml +3 -0
- package/docs/architecture/memory.md +1 -1
- 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/node_modules/@vellumai/ces-contracts/src/rpc.ts +42 -0
- package/openapi.yaml +1111 -86
- package/package.json +40 -42
- package/scripts/generate-openapi.ts +0 -2
- package/scripts/test.sh +73 -18
- package/src/__tests__/acp-session.test.ts +43 -0
- 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__/app-builder-tool-scripts.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +1 -0
- package/src/__tests__/app-source-watcher.test.ts +37 -11
- package/src/__tests__/approval-routes-http.test.ts +178 -1
- 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 +240 -94
- package/src/__tests__/browser-manager.test.ts +40 -27
- 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 +1000 -0
- package/src/__tests__/channel-approvals.test.ts +53 -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-managed-gemini-defaults.test.ts +326 -0
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +1248 -224
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +339 -0
- package/src/__tests__/config-watcher.test.ts +43 -8
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +23 -0
- package/src/__tests__/contact-store-user-file.test.ts +512 -0
- package/src/__tests__/contacts-write.test.ts +197 -0
- package/src/__tests__/context-overflow-approval.test.ts +16 -1
- 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 +2 -1
- package/src/__tests__/conversation-agent-loop.test.ts +99 -3
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -2
- package/src/__tests__/conversation-attachments.test.ts +80 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +290 -0
- package/src/__tests__/conversation-error.test.ts +70 -0
- package/src/__tests__/conversation-fork-crud.test.ts +17 -0
- package/src/__tests__/conversation-history-web-search.test.ts +12 -4
- package/src/__tests__/conversation-host-access-routes.test.ts +229 -0
- package/src/__tests__/conversation-init.benchmark.test.ts +6 -1
- package/src/__tests__/conversation-inject-context.test.ts +103 -0
- 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 +946 -62
- package/src/__tests__/conversation-routes-disk-view.test.ts +275 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +16 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +324 -46
- 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-starter-routes.test.ts +126 -0
- package/src/__tests__/conversation-starters-cadence.test.ts +161 -0
- package/src/__tests__/conversation-store.test.ts +195 -0
- package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +226 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +193 -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-execution-approval-bridge.test.ts +32 -1
- package/src/__tests__/credential-health-service.test.ts +352 -0
- package/src/__tests__/credential-security-invariants.test.ts +6 -3
- package/src/__tests__/credential-vault-unit.test.ts +383 -7
- package/src/__tests__/credential-vault.test.ts +152 -13
- package/src/__tests__/credentials-cli.test.ts +42 -18
- package/src/__tests__/cross-provider-web-search.test.ts +146 -35
- package/src/__tests__/date-context.test.ts +4 -4
- 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__/embedding-managed-proxy-selection.test.ts +256 -0
- package/src/__tests__/emit-event-signal.test.ts +71 -0
- package/src/__tests__/extension-id-sync-guard.test.ts +222 -0
- package/src/__tests__/fixtures/mock-chrome-extension.ts +386 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +206 -1
- package/src/__tests__/gateway-only-guard.test.ts +2 -0
- package/src/__tests__/gemini-provider.test.ts +66 -2
- 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__/guardian-routing-invariants.test.ts +70 -2
- package/src/__tests__/headless-browser-interactions.test.ts +738 -359
- package/src/__tests__/headless-browser-mode.test.ts +614 -0
- package/src/__tests__/headless-browser-navigate.test.ts +528 -49
- package/src/__tests__/headless-browser-read-tools.test.ts +274 -100
- package/src/__tests__/headless-browser-snapshot.test.ts +250 -77
- 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 +145 -1
- package/src/__tests__/host-browser-e2e-cloud.test.ts +596 -0
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +286 -0
- package/src/__tests__/host-browser-e2e-self-hosted.test.ts +374 -0
- package/src/__tests__/host-browser-event-routes.test.ts +350 -0
- package/src/__tests__/host-browser-proxy.test.ts +444 -0
- package/src/__tests__/host-browser-routes.test.ts +198 -0
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +423 -0
- package/src/__tests__/host-cu-proxy.test.ts +166 -1
- package/src/__tests__/host-file-proxy.test.ts +185 -1
- package/src/__tests__/host-file-read-tool.test.ts +52 -0
- package/src/__tests__/host-proxy-interface.test.ts +165 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -11
- package/src/__tests__/http-user-message-parity.test.ts +1 -0
- package/src/__tests__/identity-intro-cache.test.ts +40 -10
- package/src/__tests__/init-feature-flag-overrides.test.ts +38 -112
- package/src/__tests__/integration-status.test.ts +6 -7
- package/src/__tests__/jobs-store-upsert-debounced.test.ts +141 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +37 -12
- 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__/mcp-client-auth.test.ts +40 -4
- package/src/__tests__/mcp-health-check.test.ts +10 -3
- 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-cross-version-compatibility.test.ts +3 -1
- package/src/__tests__/migration-export-http.test.ts +67 -8
- package/src/__tests__/migration-export-streaming.test.ts +66 -0
- package/src/__tests__/migration-import-commit-http.test.ts +109 -7
- 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__/native-host-marker-sync-guard.test.ts +157 -0
- package/src/__tests__/oauth-apps-routes.test.ts +18 -12
- package/src/__tests__/oauth-cli.test.ts +709 -60
- package/src/__tests__/oauth-connect-orchestrator.test.ts +118 -24
- package/src/__tests__/oauth-provider-seed-logos.test.ts +23 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +147 -10
- package/src/__tests__/oauth-provider-visibility.test.ts +19 -21
- package/src/__tests__/oauth-providers-routes.test.ts +52 -14
- package/src/__tests__/oauth-store.test.ts +1465 -176
- package/src/__tests__/oauth2-gateway-transport.test.ts +460 -26
- package/src/__tests__/onboarding-template-contract.test.ts +81 -70
- package/src/__tests__/openai-provider.test.ts +178 -2
- 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-categories.test.ts +1 -1
- package/src/__tests__/outlook-client-automation.test.ts +1 -1
- package/src/__tests__/outlook-compose-tools.test.ts +1 -1
- package/src/__tests__/outlook-email-watcher.test.ts +1 -1
- package/src/__tests__/outlook-follow-up.test.ts +1 -1
- package/src/__tests__/outlook-messaging-provider.test.ts +2 -2
- package/src/__tests__/outlook-trash.test.ts +1 -1
- package/src/__tests__/outlook-unsubscribe.test.ts +32 -3
- package/src/__tests__/permission-checker-host-gate.test.ts +74 -14
- package/src/__tests__/permission-mode.test.ts +28 -56
- package/src/__tests__/persona-resolver.test.ts +251 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +4 -0
- package/src/__tests__/platform-callback-registration.test.ts +19 -0
- package/src/__tests__/platform.test.ts +92 -1
- package/src/__tests__/post-turn-tool-result-truncation.test.ts +343 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +267 -0
- package/src/__tests__/pricing.test.ts +174 -0
- package/src/__tests__/proxy-approval-callback.test.ts +18 -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__/require-fresh-approval.test.ts +40 -1
- package/src/__tests__/sanitize-config-for-transfer.test.ts +132 -0
- package/src/__tests__/schedule-routes.test.ts +162 -0
- package/src/__tests__/search-skills-unified.test.ts +118 -0
- package/src/__tests__/secret-detection-handler.test.ts +84 -0
- package/src/__tests__/secret-ingress-http.test.ts +1 -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 +8 -1
- package/src/__tests__/sequence-store.test.ts +1 -1
- package/src/__tests__/server-history-render.test.ts +49 -0
- package/src/__tests__/set-permission-mode.test.ts +13 -250
- 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 +801 -0
- package/src/__tests__/skills-files-catalog-fallback.test.ts +738 -0
- 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 +576 -16
- package/src/__tests__/stt-catalog-parity.test.ts +282 -0
- package/src/__tests__/stt-stream-session.test.ts +535 -0
- package/src/__tests__/subagent-detail.test.ts +44 -2
- package/src/__tests__/subagent-disposal.test.ts +1 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +291 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +384 -0
- package/src/__tests__/subagent-manager-notify.test.ts +1 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +411 -0
- package/src/__tests__/subagent-tools.test.ts +1 -0
- package/src/__tests__/subagent-types.test.ts +1 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +27 -71
- package/src/__tests__/system-prompt.test.ts +184 -27
- package/src/__tests__/task-scheduler.test.ts +32 -6
- package/src/__tests__/telegram-config.test.ts +10 -13
- package/src/__tests__/telephony-stt-routing.test.ts +329 -0
- package/src/__tests__/terminal-tools.test.ts +25 -5
- package/src/__tests__/test-preload.ts +18 -0
- package/src/__tests__/test-support/browser-skill-harness.ts +4 -1
- package/src/__tests__/tool-approval-handler.test.ts +73 -0
- 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__/tool-side-effects-slack-dm.test.ts +22 -0
- package/src/__tests__/top-level-renderer.test.ts +73 -1
- package/src/__tests__/transport-hints-queue.test.ts +14 -29
- package/src/__tests__/trust-store.test.ts +7 -1
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +109 -0
- 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__/v2-consent-policy.test.ts +103 -0
- 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/acp/client-handler.ts +30 -4
- package/src/agent/image-optimize.ts +24 -12
- package/src/agent/loop.ts +55 -9
- package/src/approvals/guardian-request-resolvers.ts +21 -15
- 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/browser-session/__tests__/manager.test.ts +297 -0
- package/src/browser-session/backends/cdp-inspect.ts +30 -0
- package/src/browser-session/backends/extension.ts +26 -0
- package/src/browser-session/backends/local.ts +24 -0
- package/src/browser-session/events.ts +164 -0
- package/src/browser-session/index.ts +27 -0
- package/src/browser-session/manager.ts +159 -0
- package/src/browser-session/types.ts +28 -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/__tests__/types.test.ts +134 -0
- package/src/channels/types.ts +69 -3
- 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 +3 -4
- package/src/cli/commands/domain.ts +210 -0
- package/src/cli/commands/email.ts +273 -16
- package/src/cli/commands/mcp.ts +16 -4
- package/src/cli/commands/oauth/__tests__/connect.test.ts +56 -44
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +21 -21
- package/src/cli/commands/oauth/__tests__/mode.test.ts +17 -17
- package/src/cli/commands/oauth/__tests__/ping.test.ts +16 -16
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +32 -33
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +330 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +117 -12
- package/src/cli/commands/oauth/__tests__/status.test.ts +10 -10
- package/src/cli/commands/oauth/__tests__/token.test.ts +7 -7
- package/src/cli/commands/oauth/apps.ts +7 -4
- package/src/cli/commands/oauth/connect.ts +6 -3
- package/src/cli/commands/oauth/disconnect.ts +1 -1
- package/src/cli/commands/oauth/mode.ts +12 -3
- package/src/cli/commands/oauth/providers.ts +215 -36
- package/src/cli/commands/oauth/shared.ts +7 -6
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +254 -0
- 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/commands/platform/index.ts +107 -10
- package/src/cli/commands/usage.ts +10 -9
- package/src/cli/lib/daemon-credential-client.ts +4 -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/SKILL.md +26 -249
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +141 -0
- package/src/config/bundled-skills/app-builder/references/INTERACTION_HOOKS.md +56 -0
- package/src/config/bundled-skills/app-builder/references/WIDGETS.md +125 -0
- 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 +5 -2
- package/src/config/bundled-skills/document/SKILL.md +4 -0
- package/src/config/bundled-skills/gmail/SKILL.md +54 -8
- 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 +9 -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/subagent/SKILL.md +21 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +8 -4
- package/src/config/bundled-skills/tasks/SKILL.md +5 -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 +38 -0
- package/src/config/env.ts +49 -4
- package/src/config/feature-flag-registry.json +85 -14
- package/src/config/loader.ts +82 -13
- package/src/config/sanitize-for-transfer.ts +47 -0
- package/src/config/schema.ts +81 -15
- 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 +112 -0
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/memory-lifecycle.ts +14 -2
- package/src/config/schemas/memory-retrieval.ts +103 -0
- package/src/config/schemas/security.ts +0 -6
- package/src/config/schemas/services.ts +52 -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 -1
- 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 +177 -0
- package/src/context/tool-result-truncation.ts +2 -1
- package/src/context/window-manager.ts +61 -10
- package/src/credential-execution/approval-bridge.ts +49 -15
- 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 +195 -0
- package/src/daemon/__tests__/lifecycle-startup-ordering.test.ts +127 -0
- package/src/daemon/app-source-watcher.ts +35 -0
- package/src/daemon/config-watcher.ts +99 -5
- package/src/daemon/context-overflow-approval.ts +5 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +23 -2
- package/src/daemon/conversation-agent-loop.ts +153 -42
- package/src/daemon/conversation-attachments.ts +40 -0
- 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 +622 -13
- package/src/daemon/conversation-queue-manager.ts +24 -0
- package/src/daemon/conversation-runtime-assembly.ts +128 -36
- package/src/daemon/conversation-slash.ts +36 -0
- package/src/daemon/conversation-surfaces.ts +131 -40
- package/src/daemon/conversation-tool-setup.ts +99 -8
- package/src/daemon/conversation-usage.ts +7 -4
- package/src/daemon/conversation-workspace.ts +12 -0
- package/src/daemon/conversation.ts +292 -16
- package/src/daemon/date-context.ts +10 -10
- package/src/daemon/first-greeting.ts +3 -2
- package/src/daemon/handlers/config-slack-channel.ts +269 -94
- package/src/daemon/handlers/conversations.ts +13 -141
- package/src/daemon/handlers/shared.ts +80 -0
- package/src/daemon/handlers/skills.ts +483 -44
- package/src/daemon/host-bash-proxy.ts +48 -13
- package/src/daemon/host-browser-proxy.ts +192 -0
- package/src/daemon/host-cu-proxy.ts +36 -11
- package/src/daemon/host-file-proxy.ts +57 -9
- package/src/daemon/lifecycle.ts +179 -28
- package/src/daemon/message-protocol.ts +13 -0
- package/src/daemon/message-types/conversations.ts +89 -14
- package/src/daemon/message-types/home.ts +40 -0
- package/src/daemon/message-types/host-browser.ts +100 -0
- package/src/daemon/message-types/meet.ts +143 -0
- package/src/daemon/message-types/messages.ts +19 -5
- package/src/daemon/message-types/schedules.ts +34 -2
- package/src/daemon/message-types/skills.ts +26 -0
- package/src/daemon/message-types/subagents.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/server.ts +439 -14
- package/src/daemon/shutdown-handlers.ts +32 -4
- package/src/daemon/shutdown-registry.ts +40 -0
- package/src/daemon/tool-side-effects.ts +15 -0
- package/src/daemon/transport-hints.ts +5 -24
- 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 +30 -20
- 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/mcp/client.ts +59 -24
- 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 +31 -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 +122 -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/conversation-starters-cadence.ts +76 -0
- package/src/memory/conversation-title-service.ts +5 -2
- package/src/memory/db-init.ts +18 -0
- package/src/memory/db-maintenance.ts +108 -0
- package/src/memory/db.ts +1 -0
- package/src/memory/embedding-backend.test.ts +75 -0
- package/src/memory/embedding-backend.ts +131 -5
- package/src/memory/embedding-gemini.test.ts +54 -0
- package/src/memory/embedding-gemini.ts +20 -9
- package/src/memory/embedding-local.ts +176 -17
- package/src/memory/graph/consolidation.ts +10 -23
- package/src/memory/graph/conversation-graph-memory.ts +15 -0
- package/src/memory/graph/extraction-job.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 +67 -40
- package/src/memory/graph/scoring.test.ts +186 -0
- package/src/memory/graph/scoring.ts +31 -1
- package/src/memory/graph/store.test.ts +7 -3
- package/src/memory/graph/store.ts +47 -12
- 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 +137 -60
- package/src/memory/migrations/213-oauth-providers-scope-separator.ts +13 -0
- package/src/memory/migrations/214-oauth-providers-refresh-url.ts +11 -0
- package/src/memory/migrations/215-oauth-providers-revoke.ts +14 -0
- package/src/memory/migrations/216-oauth-providers-token-auth-method.ts +30 -0
- package/src/memory/migrations/217-conversation-host-access.ts +40 -0
- package/src/memory/migrations/218-oauth-providers-logo-url.ts +11 -0
- 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 +12 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/qdrant-manager.ts +43 -16
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/oauth.ts +21 -13
- 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/AGENTS.md +76 -0
- package/src/oauth/__tests__/identity-verifier.test.ts +25 -19
- package/src/oauth/__tests__/seed-providers-managed.test.ts +32 -0
- package/src/oauth/byo-connection.test.ts +26 -9
- package/src/oauth/byo-connection.ts +10 -8
- package/src/oauth/connect-orchestrator.ts +25 -21
- package/src/oauth/connect-types.ts +3 -3
- package/src/oauth/connection-resolver.test.ts +17 -4
- package/src/oauth/connection-resolver.ts +22 -18
- package/src/oauth/connection.ts +3 -1
- package/src/oauth/manual-token-connection.ts +13 -13
- package/src/oauth/oauth-store.ts +223 -100
- package/src/oauth/platform-connection.test.ts +101 -3
- package/src/oauth/platform-connection.ts +56 -35
- package/src/oauth/provider-serializer.ts +31 -5
- package/src/oauth/revoke.ts +76 -0
- package/src/oauth/seed-providers.ts +133 -87
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +16 -6
- package/src/permissions/defaults.ts +49 -1
- package/src/permissions/permission-mode.ts +4 -11
- package/src/permissions/prompter.ts +13 -1
- package/src/permissions/trust-store.ts +3 -3
- package/src/permissions/v2-consent-policy.ts +87 -0
- 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 +76 -38
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +3 -65
- package/src/prompts/templates/BOOTSTRAP.md +59 -105
- 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 -60
- 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 +10 -1
- package/src/runtime/AGENTS.md +65 -0
- package/src/runtime/__tests__/agent-wake.test.ts +831 -0
- package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +715 -0
- package/src/runtime/__tests__/capability-tokens.test.ts +258 -0
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +518 -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/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
- package/src/runtime/auth/__tests__/middleware.test.ts +116 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +48 -0
- package/src/runtime/auth/middleware.ts +98 -0
- package/src/runtime/auth/route-policy.ts +33 -9
- package/src/runtime/auth/token-service.ts +56 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/capability-tokens.ts +414 -0
- package/src/runtime/channel-approvals.ts +18 -5
- 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 +368 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +6 -0
- package/src/runtime/guardian-decision-types.ts +7 -0
- package/src/runtime/http-server.ts +815 -75
- package/src/runtime/http-types.ts +6 -2
- package/src/runtime/migrations/__tests__/rebind-secrets-credentials.test.ts +172 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +276 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +198 -0
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +360 -0
- package/src/runtime/migrations/migration-transport.ts +7 -0
- package/src/runtime/migrations/migration-wizard.ts +23 -2
- package/src/runtime/migrations/rebind-secrets-screen.ts +76 -15
- package/src/runtime/migrations/vbundle-builder.ts +145 -38
- package/src/runtime/migrations/vbundle-import-analyzer.ts +96 -1
- package/src/runtime/migrations/vbundle-importer.ts +89 -5
- package/src/runtime/pending-interactions.ts +18 -13
- 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/approval-routes.ts +90 -16
- 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 +556 -0
- 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 -141
- package/src/runtime/routes/conversation-management-routes.ts +223 -0
- package/src/runtime/routes/conversation-routes.ts +598 -103
- package/src/runtime/routes/conversation-starter-routes.ts +78 -16
- package/src/runtime/routes/filing-routes.ts +93 -0
- package/src/runtime/routes/guardian-action-routes.ts +24 -13
- 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 +268 -0
- package/src/runtime/routes/host-file-routes.ts +9 -1
- package/src/runtime/routes/identity-intro-cache.ts +7 -3
- package/src/runtime/routes/identity-routes.ts +262 -33
- 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/log-export-routes.ts +42 -22
- package/src/runtime/routes/memory-item-routes.test.ts +3 -2
- package/src/runtime/routes/memory-item-routes.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +122 -2
- package/src/runtime/routes/oauth-apps.ts +15 -17
- package/src/runtime/routes/oauth-providers.ts +4 -0
- package/src/runtime/routes/schedule-routes.ts +24 -11
- package/src/runtime/routes/settings-routes.ts +31 -102
- package/src/runtime/routes/skills-routes.ts +128 -9
- package/src/runtime/routes/stt-routes.ts +233 -0
- package/src/runtime/routes/subagents-routes.ts +14 -10
- 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 +38 -9
- 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/routes/workspace-routes.test.ts +22 -0
- package/src/runtime/routes/workspace-routes.ts +8 -1
- package/src/runtime/routes/workspace-utils.ts +2 -0
- 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 +57 -5
- package/src/security/ces-credential-client.ts +20 -0
- package/src/security/ces-rpc-credential-backend.ts +17 -0
- package/src/security/credential-backend.ts +5 -0
- package/src/security/oauth2.ts +68 -29
- package/src/security/secure-keys.ts +143 -27
- package/src/security/token-manager.ts +31 -10
- package/src/sequence/engine.ts +23 -0
- package/src/sequence/types.ts +1 -1
- package/src/skills/catalog-files.ts +554 -0
- 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 +169 -40
- package/src/subagent/types.ts +19 -0
- package/src/tools/apps/executors.ts +11 -2
- package/src/tools/browser/__tests__/auth-detector.test.ts +202 -108
- 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/auth-detector.ts +43 -12
- package/src/tools/browser/browser-execution.ts +1787 -342
- package/src/tools/browser/browser-manager.ts +81 -12
- 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__/accessibility-snapshot.test.ts +318 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +1175 -0
- package/src/tools/browser/cdp-client/__tests__/cdp-inspect-client.test.ts +1263 -0
- package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +359 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +1993 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-nested-frames.json +64 -0
- package/src/tools/browser/cdp-client/__tests__/fixtures/ax-tree-simple.json +69 -0
- package/src/tools/browser/cdp-client/__tests__/local-cdp-client.test.ts +310 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +96 -0
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +387 -0
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +695 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +1007 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +580 -0
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +744 -0
- package/src/tools/browser/cdp-client/cdp-inspect/ws-transport.ts +579 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +868 -0
- package/src/tools/browser/cdp-client/errors.ts +49 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +148 -0
- package/src/tools/browser/cdp-client/factory.ts +914 -0
- package/src/tools/browser/cdp-client/index.ts +28 -0
- package/src/tools/browser/cdp-client/local-cdp-client.ts +187 -0
- package/src/tools/browser/cdp-client/types.ts +120 -0
- package/src/tools/credentials/vault.ts +35 -6
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +1 -1
- package/src/tools/host-filesystem/read.ts +12 -15
- package/src/tools/host-filesystem/write.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +21 -16
- package/src/tools/network/web-fetch.ts +5 -2
- package/src/tools/network/web-search.ts +5 -2
- package/src/tools/permission-checker.ts +77 -82
- package/src/tools/registry.ts +0 -2
- package/src/tools/secret-detection-handler.ts +34 -0
- package/src/tools/shared/filesystem/image-read.ts +61 -40
- 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/subagent/spawn.ts +47 -3
- package/src/tools/subagent/status.ts +2 -0
- package/src/tools/system/register.ts +2 -16
- package/src/tools/terminal/safe-env.ts +15 -0
- package/src/tools/terminal/shell.ts +36 -20
- package/src/tools/tool-approval-handler.ts +48 -2
- package/src/tools/tool-manifest.ts +21 -0
- package/src/tools/types.ts +19 -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 +63 -24
- 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 +31 -1
- package/src/workspace/turn-commit.ts +31 -0
- package/src/__tests__/chrome-cdp.test.ts +0 -419
- package/src/__tests__/email-cli.test.ts +0 -297
- package/src/__tests__/email-service-config-fallback.test.ts +0 -102
- package/src/__tests__/permission-mode-sse.test.ts +0 -418
- package/src/__tests__/permission-mode-store.test.ts +0 -277
- package/src/browser-extension-relay/protocol.ts +0 -63
- package/src/browser-extension-relay/server.ts +0 -203
- package/src/cli/commands/browser-relay.ts +0 -536
- package/src/config/schemas/sandbox.ts +0 -14
- 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/permissions/permission-mode-store.ts +0 -180
- package/src/prompts/templates/USER.md +0 -13
- package/src/providers/speech-to-text/types.ts +0 -17
- package/src/tools/browser/chrome-cdp.ts +0 -239
- package/src/tools/system/set-permission-mode.ts +0 -103
|
@@ -28,6 +28,7 @@ import { Readable } from "node:stream";
|
|
|
28
28
|
import { pipeline } from "node:stream/promises";
|
|
29
29
|
import { createGzip, gzipSync } from "node:zlib";
|
|
30
30
|
|
|
31
|
+
import { sanitizeConfigForTransfer } from "../../config/sanitize-for-transfer.js";
|
|
31
32
|
import type {
|
|
32
33
|
ManifestFileEntryType,
|
|
33
34
|
ManifestType,
|
|
@@ -66,6 +67,20 @@ interface FileMetadata {
|
|
|
66
67
|
size: number;
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
/** In-memory entry for data not backed by a file on disk (e.g. credentials). */
|
|
71
|
+
interface InMemoryEntry {
|
|
72
|
+
archivePath: string;
|
|
73
|
+
data: Uint8Array;
|
|
74
|
+
size: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Union of disk-backed and in-memory tar stream entries. */
|
|
78
|
+
type TarStreamEntry = FileMetadata | InMemoryEntry;
|
|
79
|
+
|
|
80
|
+
function isInMemoryEntry(entry: TarStreamEntry): entry is InMemoryEntry {
|
|
81
|
+
return "data" in entry;
|
|
82
|
+
}
|
|
83
|
+
|
|
69
84
|
// ---------------------------------------------------------------------------
|
|
70
85
|
// Hash helpers
|
|
71
86
|
// ---------------------------------------------------------------------------
|
|
@@ -439,6 +454,8 @@ export interface BuildExportVBundleOptions {
|
|
|
439
454
|
* Called before the workspace walk so the DB file is up to date.
|
|
440
455
|
*/
|
|
441
456
|
checkpoint?: () => void;
|
|
457
|
+
/** Optional credential entries to include in the archive under credentials/ prefix. */
|
|
458
|
+
credentials?: Array<{ account: string; value: string }>;
|
|
442
459
|
}
|
|
443
460
|
|
|
444
461
|
/**
|
|
@@ -456,8 +473,15 @@ export interface BuildExportVBundleOptions {
|
|
|
456
473
|
export function buildExportVBundle(
|
|
457
474
|
options: BuildExportVBundleOptions,
|
|
458
475
|
): BuildVBundleResult {
|
|
459
|
-
const {
|
|
460
|
-
|
|
476
|
+
const {
|
|
477
|
+
source,
|
|
478
|
+
description,
|
|
479
|
+
checkpoint,
|
|
480
|
+
trustPath,
|
|
481
|
+
workspaceDir,
|
|
482
|
+
hooksDir,
|
|
483
|
+
credentials,
|
|
484
|
+
} = options;
|
|
461
485
|
|
|
462
486
|
// Flush WAL to the main database file before reading so the export
|
|
463
487
|
// captures all committed rows (SQLite WAL mode keeps recent writes
|
|
@@ -483,6 +507,14 @@ export function buildExportVBundle(
|
|
|
483
507
|
);
|
|
484
508
|
}
|
|
485
509
|
|
|
510
|
+
// Sanitize workspace/config.json to strip environment-specific fields
|
|
511
|
+
const configEntry = files.find((f) => f.path === "workspace/config.json");
|
|
512
|
+
if (configEntry) {
|
|
513
|
+
const configJson = new TextDecoder().decode(configEntry.data);
|
|
514
|
+
const sanitized = sanitizeConfigForTransfer(configJson);
|
|
515
|
+
configEntry.data = new TextEncoder().encode(sanitized);
|
|
516
|
+
}
|
|
517
|
+
|
|
486
518
|
// Include hooks directory if it exists (lives at ~/.vellum/hooks/, outside workspace).
|
|
487
519
|
if (hooksDir && existsSync(hooksDir) && lstatSync(hooksDir).isDirectory()) {
|
|
488
520
|
files.push(...walkDirectory(hooksDir, "hooks"));
|
|
@@ -494,6 +526,14 @@ export function buildExportVBundle(
|
|
|
494
526
|
files.push({ path: "trust/trust.json", data: trustData });
|
|
495
527
|
}
|
|
496
528
|
|
|
529
|
+
// Include credential entries if provided
|
|
530
|
+
if (credentials?.length) {
|
|
531
|
+
for (const { account, value } of credentials) {
|
|
532
|
+
const data = new TextEncoder().encode(value);
|
|
533
|
+
files.push({ path: `credentials/${account}`, data });
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
497
537
|
return buildVBundle({
|
|
498
538
|
files,
|
|
499
539
|
source: source ?? "runtime-export",
|
|
@@ -688,7 +728,7 @@ function tarPaddingBytes(dataSize: number): Uint8Array {
|
|
|
688
728
|
*/
|
|
689
729
|
async function* generateTarStream(
|
|
690
730
|
manifestJson: Uint8Array,
|
|
691
|
-
files:
|
|
731
|
+
files: TarStreamEntry[],
|
|
692
732
|
): AsyncGenerator<Uint8Array> {
|
|
693
733
|
// Manifest entry
|
|
694
734
|
yield createPaxAndHeaderBlocks("manifest.json", manifestJson.length);
|
|
@@ -697,43 +737,52 @@ async function* generateTarStream(
|
|
|
697
737
|
|
|
698
738
|
// File entries
|
|
699
739
|
for (const file of files) {
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
740
|
+
const entrySize = isInMemoryEntry(file) ? file.size : file.size;
|
|
741
|
+
yield createPaxAndHeaderBlocks(file.archivePath, entrySize);
|
|
742
|
+
|
|
743
|
+
if (isInMemoryEntry(file)) {
|
|
744
|
+
// In-memory entry — yield data directly
|
|
745
|
+
if (file.size > 0) {
|
|
746
|
+
yield file.data;
|
|
747
|
+
}
|
|
748
|
+
} else {
|
|
749
|
+
// Disk-backed entry — stream from disk
|
|
750
|
+
// Stream exactly file.size bytes from disk. Capping the read at the
|
|
751
|
+
// declared size keeps the tar structure valid even if the file grows
|
|
752
|
+
// between passes (common for log files on active assistants). If the
|
|
753
|
+
// file shrinks below the declared size, zero-pad to maintain block
|
|
754
|
+
// alignment. The WAL checkpoint before export is the primary
|
|
755
|
+
// consistency mechanism for the database.
|
|
756
|
+
let bytesWritten = 0;
|
|
757
|
+
if (file.size > 0) {
|
|
758
|
+
try {
|
|
759
|
+
const stream = createReadStream(file.diskPath, {
|
|
760
|
+
start: 0,
|
|
761
|
+
end: file.size - 1,
|
|
762
|
+
});
|
|
763
|
+
for await (const chunk of stream) {
|
|
764
|
+
const data =
|
|
765
|
+
chunk instanceof Uint8Array ? chunk : new Uint8Array(chunk);
|
|
766
|
+
bytesWritten += data.length;
|
|
767
|
+
yield data;
|
|
768
|
+
}
|
|
769
|
+
} catch {
|
|
770
|
+
// File was deleted or rotated between passes — emit zeros for
|
|
771
|
+
// the full declared size so the tar structure stays valid
|
|
720
772
|
}
|
|
721
|
-
} catch {
|
|
722
|
-
// File was deleted or rotated between passes — emit zeros for
|
|
723
|
-
// the full declared size so the tar structure stays valid
|
|
724
773
|
}
|
|
725
|
-
}
|
|
726
774
|
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
775
|
+
// If the file shrank, pad with zeros in bounded chunks to reach
|
|
776
|
+
// the declared size without a large single allocation
|
|
777
|
+
let remaining = file.size - bytesWritten;
|
|
778
|
+
while (remaining > 0) {
|
|
779
|
+
const chunkSize = Math.min(remaining, 65536);
|
|
780
|
+
yield new Uint8Array(chunkSize);
|
|
781
|
+
remaining -= chunkSize;
|
|
782
|
+
}
|
|
734
783
|
}
|
|
735
784
|
|
|
736
|
-
yield tarPaddingBytes(
|
|
785
|
+
yield tarPaddingBytes(entrySize);
|
|
737
786
|
}
|
|
738
787
|
|
|
739
788
|
// End-of-archive: two zero blocks
|
|
@@ -765,8 +814,15 @@ export interface StreamExportVBundleResult {
|
|
|
765
814
|
export async function streamExportVBundle(
|
|
766
815
|
options: BuildExportVBundleOptions,
|
|
767
816
|
): Promise<StreamExportVBundleResult> {
|
|
768
|
-
const {
|
|
769
|
-
|
|
817
|
+
const {
|
|
818
|
+
source,
|
|
819
|
+
description,
|
|
820
|
+
checkpoint,
|
|
821
|
+
trustPath,
|
|
822
|
+
workspaceDir,
|
|
823
|
+
hooksDir,
|
|
824
|
+
credentials,
|
|
825
|
+
} = options;
|
|
770
826
|
|
|
771
827
|
// Flush WAL to the main database file before reading
|
|
772
828
|
if (checkpoint) {
|
|
@@ -806,6 +862,42 @@ export async function streamExportVBundle(
|
|
|
806
862
|
}
|
|
807
863
|
}
|
|
808
864
|
|
|
865
|
+
// Sanitize workspace/config.json: read from disk, sanitize, and replace the
|
|
866
|
+
// disk-backed metadata entry with an in-memory entry so the streaming tar
|
|
867
|
+
// writes sanitized content instead of the raw file.
|
|
868
|
+
const configMetadataIdx = allFileMetadata.findIndex(
|
|
869
|
+
(f) => f.archivePath === "workspace/config.json",
|
|
870
|
+
);
|
|
871
|
+
|
|
872
|
+
const sanitizedConfigEntries: InMemoryEntry[] = [];
|
|
873
|
+
if (configMetadataIdx !== -1) {
|
|
874
|
+
const configMeta = allFileMetadata[configMetadataIdx];
|
|
875
|
+
const rawConfigData = readFileSync(configMeta.diskPath, "utf8");
|
|
876
|
+
const sanitized = sanitizeConfigForTransfer(rawConfigData);
|
|
877
|
+
const sanitizedData = new TextEncoder().encode(sanitized);
|
|
878
|
+
|
|
879
|
+
// Remove the disk-backed entry and replace with an in-memory entry
|
|
880
|
+
allFileMetadata.splice(configMetadataIdx, 1);
|
|
881
|
+
sanitizedConfigEntries.push({
|
|
882
|
+
archivePath: "workspace/config.json",
|
|
883
|
+
data: sanitizedData,
|
|
884
|
+
size: sanitizedData.length,
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// Build in-memory entries for credentials (not disk-backed)
|
|
889
|
+
const inMemoryEntries: InMemoryEntry[] = [];
|
|
890
|
+
if (credentials?.length) {
|
|
891
|
+
for (const { account, value } of credentials) {
|
|
892
|
+
const data = new TextEncoder().encode(value);
|
|
893
|
+
inMemoryEntries.push({
|
|
894
|
+
archivePath: `credentials/${account}`,
|
|
895
|
+
data,
|
|
896
|
+
size: data.length,
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
809
901
|
// ------------------------------------------------------------------
|
|
810
902
|
// Pass 1: Compute SHA-256 checksums to build the manifest
|
|
811
903
|
// ------------------------------------------------------------------
|
|
@@ -820,6 +912,16 @@ export async function streamExportVBundle(
|
|
|
820
912
|
});
|
|
821
913
|
}
|
|
822
914
|
|
|
915
|
+
// Add in-memory entries (sanitized config, credentials) to the manifest
|
|
916
|
+
for (const entry of [...sanitizedConfigEntries, ...inMemoryEntries]) {
|
|
917
|
+
const sha256 = sha256Hex(entry.data);
|
|
918
|
+
fileEntries.push({
|
|
919
|
+
path: entry.archivePath,
|
|
920
|
+
sha256,
|
|
921
|
+
size: entry.size,
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
|
|
823
925
|
const manifestWithoutChecksum = {
|
|
824
926
|
schema_version: "1.0",
|
|
825
927
|
created_at: new Date().toISOString(),
|
|
@@ -842,7 +944,12 @@ export async function streamExportVBundle(
|
|
|
842
944
|
|
|
843
945
|
const tempPath = join(tmpdir(), `vbundle-export-${randomUUID()}.tmp`);
|
|
844
946
|
|
|
845
|
-
const
|
|
947
|
+
const allEntries: TarStreamEntry[] = [
|
|
948
|
+
...allFileMetadata,
|
|
949
|
+
...sanitizedConfigEntries,
|
|
950
|
+
...inMemoryEntries,
|
|
951
|
+
];
|
|
952
|
+
const tarGenerator = generateTarStream(manifestData, allEntries);
|
|
846
953
|
const tarReadable = Readable.from(tarGenerator);
|
|
847
954
|
const gzipStream = createGzip();
|
|
848
955
|
const writeStream = createWriteStream(tempPath, { mode: 0o600 });
|
|
@@ -17,9 +17,19 @@ import { createHash } from "node:crypto";
|
|
|
17
17
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
18
18
|
import { join, resolve } from "node:path";
|
|
19
19
|
|
|
20
|
+
import { resolveGuardianPersonaPath } from "../../prompts/persona-resolver.js";
|
|
21
|
+
import { getLogger } from "../../util/logger.js";
|
|
20
22
|
import type { ManifestType } from "./vbundle-validator.js";
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
const log = getLogger("vbundle-import-analyzer");
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Only these prompt filenames are accepted during import.
|
|
28
|
+
*
|
|
29
|
+
* `USER.md` is retained for backward compatibility with legacy bundles —
|
|
30
|
+
* on import, its content is translated to `users/<slug>.md` at the
|
|
31
|
+
* current guardian's location (see `DefaultPathResolver.resolve`).
|
|
32
|
+
*/
|
|
23
33
|
const ALLOWED_PROMPT_FILENAMES = new Set([
|
|
24
34
|
"IDENTITY.md",
|
|
25
35
|
"SOUL.md",
|
|
@@ -27,6 +37,9 @@ const ALLOWED_PROMPT_FILENAMES = new Set([
|
|
|
27
37
|
"UPDATES.md",
|
|
28
38
|
]);
|
|
29
39
|
|
|
40
|
+
/** Archive path for the legacy guardian user persona file. */
|
|
41
|
+
const LEGACY_USER_MD_ARCHIVE_PATH = "prompts/USER.md";
|
|
42
|
+
|
|
30
43
|
// ---------------------------------------------------------------------------
|
|
31
44
|
// Public types
|
|
32
45
|
// ---------------------------------------------------------------------------
|
|
@@ -87,12 +100,27 @@ export interface PathResolver {
|
|
|
87
100
|
}
|
|
88
101
|
|
|
89
102
|
export class DefaultPathResolver implements PathResolver {
|
|
103
|
+
/**
|
|
104
|
+
* @param workspaceDir absolute path to the workspace directory.
|
|
105
|
+
* @param hooksDir absolute path to the hooks directory.
|
|
106
|
+
* @param guardianPersonaPathResolver function that returns the
|
|
107
|
+
* current guardian's persona path (`users/<slug>.md`) or `null`
|
|
108
|
+
* when no guardian exists. Defaults to the production
|
|
109
|
+
* `resolveGuardianPersonaPath` helper; tests inject a stub so they
|
|
110
|
+
* don't need to mock the contact store.
|
|
111
|
+
*/
|
|
90
112
|
constructor(
|
|
91
113
|
private workspaceDir?: string,
|
|
92
114
|
private hooksDir?: string,
|
|
115
|
+
private guardianPersonaPathResolver: () => string | null = resolveGuardianPersonaPath,
|
|
93
116
|
) {}
|
|
94
117
|
|
|
95
118
|
resolve(archivePath: string): string | null {
|
|
119
|
+
// Skip credential entries — handled separately by the credential import step
|
|
120
|
+
if (archivePath.startsWith("credentials/")) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
|
|
96
124
|
// New format: workspace/ prefix — maps directly into the workspace dir
|
|
97
125
|
if (archivePath.startsWith("workspace/") && this.workspaceDir) {
|
|
98
126
|
const relPath = archivePath.slice("workspace/".length);
|
|
@@ -134,6 +162,38 @@ export class DefaultPathResolver implements PathResolver {
|
|
|
134
162
|
if (!ALLOWED_PROMPT_FILENAMES.has(filename)) {
|
|
135
163
|
return null;
|
|
136
164
|
}
|
|
165
|
+
|
|
166
|
+
// Legacy USER.md translation: rewrite the destination to the
|
|
167
|
+
// current guardian's per-user persona file `users/<slug>.md`.
|
|
168
|
+
// Guardian-less workspaces return null → importer skips with a
|
|
169
|
+
// warning (see vbundle-importer.ts). This lookup runs against
|
|
170
|
+
// whatever DB state is live at the time of resolve — typically
|
|
171
|
+
// the pre-import workspace, which is the common upgrade case.
|
|
172
|
+
if (archivePath === LEGACY_USER_MD_ARCHIVE_PATH) {
|
|
173
|
+
const guardianPath = this.guardianPersonaPathResolver();
|
|
174
|
+
if (!guardianPath) {
|
|
175
|
+
log.warn(
|
|
176
|
+
{ path: archivePath },
|
|
177
|
+
"Legacy prompts/USER.md has no guardian target — will be skipped on import",
|
|
178
|
+
);
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
// Containment check: guardian path must live under the workspace.
|
|
182
|
+
const wsRoot = resolve(this.workspaceDir);
|
|
183
|
+
const guardianResolved = resolve(guardianPath);
|
|
184
|
+
if (
|
|
185
|
+
guardianResolved !== wsRoot &&
|
|
186
|
+
!guardianResolved.startsWith(wsRoot + "/")
|
|
187
|
+
) {
|
|
188
|
+
log.warn(
|
|
189
|
+
{ path: archivePath, guardianPath },
|
|
190
|
+
"Guardian persona path falls outside workspace — refusing to write",
|
|
191
|
+
);
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
return guardianResolved;
|
|
195
|
+
}
|
|
196
|
+
|
|
137
197
|
const resolved = resolve(this.workspaceDir, filename);
|
|
138
198
|
const wsRoot = resolve(this.workspaceDir);
|
|
139
199
|
if (resolved !== wsRoot && !resolved.startsWith(wsRoot + "/")) {
|
|
@@ -190,7 +250,42 @@ export function analyzeImport(
|
|
|
190
250
|
for (const fileEntry of manifest.files) {
|
|
191
251
|
const diskPath = pathResolver.resolve(fileEntry.path);
|
|
192
252
|
|
|
253
|
+
// Credential entries are handled separately by the credential import
|
|
254
|
+
// step — skip them without flagging as unknown/conflict.
|
|
255
|
+
if (fileEntry.path.startsWith("credentials/")) {
|
|
256
|
+
files.push({
|
|
257
|
+
path: fileEntry.path,
|
|
258
|
+
action: "skip",
|
|
259
|
+
bundle_size: fileEntry.size,
|
|
260
|
+
bundle_sha256: fileEntry.sha256,
|
|
261
|
+
current_size: null,
|
|
262
|
+
current_sha256: null,
|
|
263
|
+
});
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
|
|
193
267
|
if (!diskPath) {
|
|
268
|
+
// Legacy `prompts/USER.md` in a guardian-less workspace has no
|
|
269
|
+
// destination to translate to. The commit-time path skips this
|
|
270
|
+
// entry with a warning rather than failing, so preflight mirrors
|
|
271
|
+
// that: emit a non-blocking skip so `can_import` stays true and
|
|
272
|
+
// upgrade paths proceed. No conflict is registered.
|
|
273
|
+
if (fileEntry.path === LEGACY_USER_MD_ARCHIVE_PATH) {
|
|
274
|
+
log.warn(
|
|
275
|
+
{ path: fileEntry.path },
|
|
276
|
+
"Legacy prompts/USER.md has no guardian target — will be skipped on import",
|
|
277
|
+
);
|
|
278
|
+
files.push({
|
|
279
|
+
path: fileEntry.path,
|
|
280
|
+
action: "skip",
|
|
281
|
+
bundle_size: fileEntry.size,
|
|
282
|
+
bundle_sha256: fileEntry.sha256,
|
|
283
|
+
current_size: null,
|
|
284
|
+
current_sha256: null,
|
|
285
|
+
});
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
|
|
194
289
|
// Unknown archive path — would have nowhere to write
|
|
195
290
|
conflicts.push({
|
|
196
291
|
code: "UNKNOWN_ARCHIVE_PATH",
|
|
@@ -24,10 +24,18 @@ import {
|
|
|
24
24
|
} from "node:fs";
|
|
25
25
|
import { dirname, join } from "node:path";
|
|
26
26
|
|
|
27
|
+
import { sanitizeConfigForTransfer } from "../../config/sanitize-for-transfer.js";
|
|
28
|
+
import { isGuardianPersonaCustomized } from "../../prompts/persona-resolver.js";
|
|
29
|
+
import { getLogger } from "../../util/logger.js";
|
|
27
30
|
import type { PathResolver } from "./vbundle-import-analyzer.js";
|
|
28
31
|
import type { ManifestType, VBundleTarEntry } from "./vbundle-validator.js";
|
|
29
32
|
import { validateVBundle } from "./vbundle-validator.js";
|
|
30
33
|
|
|
34
|
+
const log = getLogger("vbundle-importer");
|
|
35
|
+
|
|
36
|
+
/** Archive path for the legacy guardian user persona file. */
|
|
37
|
+
const LEGACY_USER_MD_ARCHIVE_PATH = "prompts/USER.md";
|
|
38
|
+
|
|
31
39
|
// ---------------------------------------------------------------------------
|
|
32
40
|
// Public types
|
|
33
41
|
// ---------------------------------------------------------------------------
|
|
@@ -227,6 +235,12 @@ export function commitImport(options: ImportCommitOptions): ImportCommitResult {
|
|
|
227
235
|
let backupsCreated = 0;
|
|
228
236
|
|
|
229
237
|
for (const fileEntry of manifest.files) {
|
|
238
|
+
// Credential entries are handled separately by extractCredentialsFromBundle()
|
|
239
|
+
// in migration-routes.ts — skip them silently without warnings or skip counts.
|
|
240
|
+
if (fileEntry.path.startsWith("credentials/")) {
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
|
|
230
244
|
const diskPath = pathResolver.resolve(fileEntry.path);
|
|
231
245
|
|
|
232
246
|
if (!diskPath) {
|
|
@@ -263,6 +277,33 @@ export function commitImport(options: ImportCommitOptions): ImportCommitResult {
|
|
|
263
277
|
continue;
|
|
264
278
|
}
|
|
265
279
|
|
|
280
|
+
// Legacy guardian persona (prompts/USER.md) is translated to the
|
|
281
|
+
// current guardian's users/<slug>.md by DefaultPathResolver. If
|
|
282
|
+
// that target already holds user-authored content, skip rather
|
|
283
|
+
// than clobber — the user has curated their persona since the
|
|
284
|
+
// bundle was exported.
|
|
285
|
+
if (
|
|
286
|
+
fileEntry.path === LEGACY_USER_MD_ARCHIVE_PATH &&
|
|
287
|
+
isGuardianPersonaCustomized(diskPath)
|
|
288
|
+
) {
|
|
289
|
+
log.warn(
|
|
290
|
+
{ archivePath: fileEntry.path, diskPath },
|
|
291
|
+
"Skipping legacy prompts/USER.md import: guardian persona is already customized",
|
|
292
|
+
);
|
|
293
|
+
warnings.push(
|
|
294
|
+
`Skipped "${fileEntry.path}": guardian persona at "${diskPath}" is already customized`,
|
|
295
|
+
);
|
|
296
|
+
importedFiles.push({
|
|
297
|
+
path: fileEntry.path,
|
|
298
|
+
disk_path: diskPath,
|
|
299
|
+
action: "skipped",
|
|
300
|
+
size: fileEntry.size,
|
|
301
|
+
sha256: fileEntry.sha256,
|
|
302
|
+
backup_path: null,
|
|
303
|
+
});
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
|
|
266
307
|
// Determine action and create backup if needed
|
|
267
308
|
let backupPath: string | null = null;
|
|
268
309
|
let action: ImportFileAction;
|
|
@@ -315,9 +356,20 @@ export function commitImport(options: ImportCommitOptions): ImportCommitResult {
|
|
|
315
356
|
}
|
|
316
357
|
}
|
|
317
358
|
|
|
359
|
+
// Sanitize config files to strip environment-specific fields (defense-in-depth)
|
|
360
|
+
let dataToWrite: Uint8Array = archiveEntry.data;
|
|
361
|
+
if (
|
|
362
|
+
fileEntry.path === "workspace/config.json" ||
|
|
363
|
+
fileEntry.path === "config/settings.json"
|
|
364
|
+
) {
|
|
365
|
+
const configJson = new TextDecoder().decode(archiveEntry.data);
|
|
366
|
+
const sanitized = sanitizeConfigForTransfer(configJson);
|
|
367
|
+
dataToWrite = new TextEncoder().encode(sanitized);
|
|
368
|
+
}
|
|
369
|
+
|
|
318
370
|
// Write the file
|
|
319
371
|
try {
|
|
320
|
-
writeFileSync(diskPath,
|
|
372
|
+
writeFileSync(diskPath, dataToWrite);
|
|
321
373
|
} catch (err) {
|
|
322
374
|
return {
|
|
323
375
|
ok: false,
|
|
@@ -335,14 +387,17 @@ export function commitImport(options: ImportCommitOptions): ImportCommitResult {
|
|
|
335
387
|
}
|
|
336
388
|
|
|
337
389
|
// Step 3: Post-write integrity check — verify the written file
|
|
390
|
+
// Use the SHA of the data we actually wrote (which may differ from the
|
|
391
|
+
// manifest SHA if the config was sanitized during import).
|
|
392
|
+
const expectedSha256 = sha256Hex(dataToWrite);
|
|
338
393
|
try {
|
|
339
394
|
const writtenData = new Uint8Array(readFileSync(diskPath));
|
|
340
395
|
const writtenSha256 = sha256Hex(writtenData);
|
|
341
396
|
|
|
342
|
-
if (writtenSha256 !==
|
|
397
|
+
if (writtenSha256 !== expectedSha256) {
|
|
343
398
|
warnings.push(
|
|
344
399
|
`Post-write integrity warning for "${fileEntry.path}": ` +
|
|
345
|
-
`expected SHA-256 ${
|
|
400
|
+
`expected SHA-256 ${expectedSha256}, got ${writtenSha256}`,
|
|
346
401
|
);
|
|
347
402
|
}
|
|
348
403
|
} catch {
|
|
@@ -355,8 +410,8 @@ export function commitImport(options: ImportCommitOptions): ImportCommitResult {
|
|
|
355
410
|
path: fileEntry.path,
|
|
356
411
|
disk_path: diskPath,
|
|
357
412
|
action,
|
|
358
|
-
size:
|
|
359
|
-
sha256:
|
|
413
|
+
size: dataToWrite.length,
|
|
414
|
+
sha256: expectedSha256,
|
|
360
415
|
backup_path: backupPath,
|
|
361
416
|
});
|
|
362
417
|
}
|
|
@@ -380,6 +435,35 @@ export function commitImport(options: ImportCommitOptions): ImportCommitResult {
|
|
|
380
435
|
return { ok: true, report };
|
|
381
436
|
}
|
|
382
437
|
|
|
438
|
+
// ---------------------------------------------------------------------------
|
|
439
|
+
// Credential extraction
|
|
440
|
+
// ---------------------------------------------------------------------------
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Extract credential entries from a validated vbundle tar entries map.
|
|
444
|
+
*
|
|
445
|
+
* Credentials are stored under the `credentials/` prefix in the archive,
|
|
446
|
+
* where the remainder of the path is the account name and the entry data
|
|
447
|
+
* is the credential value.
|
|
448
|
+
*/
|
|
449
|
+
export function extractCredentialsFromBundle(
|
|
450
|
+
entries: Map<string, VBundleTarEntry>,
|
|
451
|
+
manifest: ManifestType,
|
|
452
|
+
): Array<{ account: string; value: string }> {
|
|
453
|
+
const manifestPaths = new Set(manifest.files.map((f) => f.path));
|
|
454
|
+
const credentials: Array<{ account: string; value: string }> = [];
|
|
455
|
+
for (const [path, entry] of entries) {
|
|
456
|
+
if (path.startsWith("credentials/") && manifestPaths.has(path)) {
|
|
457
|
+
const account = path.slice("credentials/".length);
|
|
458
|
+
if (account) {
|
|
459
|
+
const value = new TextDecoder().decode(entry.data);
|
|
460
|
+
credentials.push({ account, value });
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return credentials;
|
|
465
|
+
}
|
|
466
|
+
|
|
383
467
|
// ---------------------------------------------------------------------------
|
|
384
468
|
// Helpers
|
|
385
469
|
// ---------------------------------------------------------------------------
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* In-memory tracker that maps requestId to conversation info for pending
|
|
3
|
-
* confirmation, secret, host_bash, host_file, and
|
|
3
|
+
* confirmation, secret, host_bash, host_file, host_cu, and host_browser
|
|
4
|
+
* interactions.
|
|
4
5
|
*
|
|
5
6
|
* When the agent loop emits a confirmation_request, secret_request,
|
|
6
|
-
* host_bash_request, host_file_request,
|
|
7
|
-
* callback registers the interaction here.
|
|
8
|
-
* (/v1/confirm, /v1/secret, /v1/trust-rules,
|
|
9
|
-
* /v1/host-file-result, /v1/host-cu-result
|
|
10
|
-
*
|
|
7
|
+
* host_bash_request, host_file_request, host_cu_request, or
|
|
8
|
+
* host_browser_request, the onEvent callback registers the interaction here.
|
|
9
|
+
* Standalone HTTP endpoints (/v1/confirm, /v1/secret, /v1/trust-rules,
|
|
10
|
+
* /v1/host-bash-result, /v1/host-file-result, /v1/host-cu-result,
|
|
11
|
+
* /v1/host-browser-result) look up the conversation from this tracker to
|
|
12
|
+
* resolve the interaction.
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
15
|
import type { Conversation } from "../daemon/conversation.js";
|
|
@@ -45,6 +47,7 @@ export interface PendingInteraction {
|
|
|
45
47
|
| "host_bash"
|
|
46
48
|
| "host_file"
|
|
47
49
|
| "host_cu"
|
|
50
|
+
| "host_browser"
|
|
48
51
|
| "acp_confirmation";
|
|
49
52
|
confirmationDetails?: ConfirmationDetails;
|
|
50
53
|
/** For ACP permissions: resolves directly without a Conversation object. */
|
|
@@ -82,7 +85,7 @@ export function get(requestId: string): PendingInteraction | undefined {
|
|
|
82
85
|
|
|
83
86
|
/**
|
|
84
87
|
* Return all pending interactions for a given conversation.
|
|
85
|
-
* Needed by channel approval migration
|
|
88
|
+
* Needed by channel approval migration.
|
|
86
89
|
*/
|
|
87
90
|
export function getByConversation(
|
|
88
91
|
conversationId: string,
|
|
@@ -100,12 +103,13 @@ export function getByConversation(
|
|
|
100
103
|
* Remove pending confirmation and secret interactions for a given conversation.
|
|
101
104
|
* Used when auto-denying all pending interactions (e.g. new user message).
|
|
102
105
|
*
|
|
103
|
-
* host_bash, host_file, and
|
|
104
|
-
* — they represent in-flight tool executions proxied to
|
|
105
|
-
* confirmations to auto-deny. Removing them would orphan the
|
|
106
|
-
* client would POST to /v1/host-bash-result,
|
|
107
|
-
* /v1/host-cu-result
|
|
108
|
-
* proxy timer would fire with a
|
|
106
|
+
* host_bash, host_file, host_cu, and host_browser interactions are
|
|
107
|
+
* intentionally skipped — they represent in-flight tool executions proxied to
|
|
108
|
+
* the client, not confirmations to auto-deny. Removing them would orphan the
|
|
109
|
+
* request: the client would POST to /v1/host-bash-result,
|
|
110
|
+
* /v1/host-file-result, /v1/host-cu-result, or /v1/host-browser-result after
|
|
111
|
+
* completing the operation, get a 404, and the proxy timer would fire with a
|
|
112
|
+
* spurious timeout error.
|
|
109
113
|
*/
|
|
110
114
|
export function removeByConversation(conversation: Conversation): void {
|
|
111
115
|
for (const [requestId, interaction] of pending) {
|
|
@@ -114,6 +118,7 @@ export function removeByConversation(conversation: Conversation): void {
|
|
|
114
118
|
interaction.kind !== "host_bash" &&
|
|
115
119
|
interaction.kind !== "host_file" &&
|
|
116
120
|
interaction.kind !== "host_cu" &&
|
|
121
|
+
interaction.kind !== "host_browser" &&
|
|
117
122
|
interaction.kind !== "acp_confirmation"
|
|
118
123
|
) {
|
|
119
124
|
pending.delete(requestId);
|