@vellumai/assistant 0.5.6 → 0.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +16 -2
- package/ARCHITECTURE.md +6 -75
- package/Dockerfile +3 -2
- package/README.md +0 -2
- package/bun.lock +0 -414
- package/docker-entrypoint.sh +9 -0
- package/docs/architecture/keychain-broker.md +45 -240
- package/docs/architecture/memory.md +13 -11
- package/docs/architecture/security.md +0 -17
- package/docs/credential-execution-service.md +2 -2
- package/node_modules/@vellumai/ces-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-contracts/src/error.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/grants.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/handles.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/index.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +120 -1
- package/node_modules/@vellumai/credential-storage/package.json +1 -0
- package/node_modules/@vellumai/egress-proxy/package.json +1 -0
- package/package.json +2 -3
- package/src/__tests__/actor-token-service.test.ts +0 -114
- package/src/__tests__/approval-cascade.test.ts +0 -1
- package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/browser-skill-endstate.test.ts +6 -5
- package/src/__tests__/btw-routes.test.ts +0 -39
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/call-domain.test.ts +0 -128
- package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
- package/src/__tests__/ces-startup-timeout.test.ts +40 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -5
- package/src/__tests__/channel-readiness-service.test.ts +1 -60
- package/src/__tests__/checker.test.ts +4 -2
- package/src/__tests__/cli-command-risk-guard.test.ts +112 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -2
- package/src/__tests__/config-schema.test.ts +3 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop.test.ts +2 -4
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -1
- package/src/__tests__/conversation-error.test.ts +15 -1
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-messaging-secret-redirect.test.ts +1 -1
- package/src/__tests__/conversation-pre-run-repair.test.ts +0 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -1
- package/src/__tests__/conversation-queue.test.ts +0 -1
- package/src/__tests__/conversation-skill-tools.test.ts +0 -54
- package/src/__tests__/conversation-slash-queue.test.ts +0 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
- package/src/__tests__/conversation-title-service.test.ts +87 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
- package/src/__tests__/credential-execution-client.test.ts +5 -2
- package/src/__tests__/credential-execution-feature-gates.test.ts +59 -30
- package/src/__tests__/credential-execution-managed-contract.test.ts +35 -20
- package/src/__tests__/credential-security-e2e.test.ts +1 -67
- package/src/__tests__/credential-security-invariants.test.ts +6 -50
- package/src/__tests__/credentials-cli.test.ts +82 -3
- package/src/__tests__/daemon-credential-client.test.ts +123 -0
- package/src/__tests__/db-migration-rollback.test.ts +2015 -1
- package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +34 -143
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
- package/src/__tests__/gateway-client-managed-outbound.test.ts +79 -1
- package/src/__tests__/guardian-routing-state.test.ts +0 -5
- package/src/__tests__/host-shell-tool.test.ts +6 -7
- package/src/__tests__/http-user-message-parity.test.ts +3 -103
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -4
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -8
- package/src/__tests__/intent-routing.test.ts +0 -13
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +178 -0
- package/src/__tests__/journal-context.test.ts +335 -0
- package/src/__tests__/keychain-broker-client.test.ts +161 -22
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -3
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
- package/src/__tests__/memory-lifecycle-e2e.test.ts +70 -25
- package/src/__tests__/memory-recall-quality.test.ts +48 -17
- package/src/__tests__/memory-regressions.test.ts +408 -363
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -3
- package/src/__tests__/migration-export-http.test.ts +2 -2
- package/src/__tests__/migration-import-commit-http.test.ts +2 -2
- package/src/__tests__/migration-import-preflight-http.test.ts +2 -2
- package/src/__tests__/migration-validate-http.test.ts +2 -2
- package/src/__tests__/non-member-access-request.test.ts +2 -7
- package/src/__tests__/notification-decision-fallback.test.ts +4 -0
- package/src/__tests__/notification-decision-identity.test.ts +4 -0
- package/src/__tests__/notification-decision-strategy.test.ts +71 -0
- package/src/__tests__/oauth-cli.test.ts +5 -1
- package/src/__tests__/permission-types.test.ts +1 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -37
- package/src/__tests__/provider-error-scenarios.test.ts +0 -267
- package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
- package/src/__tests__/provider-streaming.benchmark.test.ts +2 -81
- package/src/__tests__/qdrant-manager.test.ts +28 -2
- package/src/__tests__/registry.test.ts +0 -6
- package/src/__tests__/relay-server.test.ts +1 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
- package/src/__tests__/script-proxy-injection-runtime.test.ts +1 -1
- package/src/__tests__/secret-onetime-send.test.ts +1 -1
- package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
- package/src/__tests__/secure-keys.test.ts +95 -272
- package/src/__tests__/shell-identity.test.ts +96 -6
- package/src/__tests__/skill-feature-flags-integration.test.ts +22 -14
- package/src/__tests__/skill-feature-flags.test.ts +46 -45
- package/src/__tests__/skill-load-feature-flag.test.ts +7 -10
- package/src/__tests__/skill-load-inline-command.test.ts +8 -12
- package/src/__tests__/skill-load-inline-includes.test.ts +6 -10
- package/src/__tests__/skill-load-tool.test.ts +0 -2
- package/src/__tests__/skill-memory.test.ts +17 -3
- package/src/__tests__/skill-projection-feature-flag.test.ts +33 -29
- package/src/__tests__/skills.test.ts +0 -2
- package/src/__tests__/slack-inbound-verification.test.ts +0 -4
- package/src/__tests__/stale-approval-dedup.test.ts +171 -0
- package/src/__tests__/stt-hints.test.ts +437 -0
- package/src/__tests__/suggestion-routes.test.ts +1 -32
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/task-memory-cleanup.test.ts +14 -0
- package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
- package/src/__tests__/twilio-routes-twiml.test.ts +139 -1
- package/src/__tests__/update-bulletin.test.ts +0 -2
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +6 -9
- package/src/__tests__/voice-quality.test.ts +58 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -7
- package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +252 -0
- package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +220 -0
- package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
- package/src/acp/agent-process.ts +9 -1
- package/src/agent/loop.ts +1 -1
- package/src/approvals/guardian-request-resolvers.ts +164 -38
- package/src/calls/__tests__/tts-text-sanitizer.test.ts +254 -0
- package/src/calls/audio-store.test.ts +97 -0
- package/src/calls/audio-store.ts +205 -0
- package/src/calls/call-controller.ts +90 -8
- package/src/calls/call-domain.ts +3 -0
- package/src/calls/call-store.ts +10 -3
- package/src/calls/fish-audio-client.ts +129 -0
- package/src/calls/relay-server.ts +27 -0
- package/src/calls/stt-hints.ts +189 -0
- package/src/calls/tts-text-sanitizer.ts +61 -0
- package/src/calls/twilio-routes.ts +34 -5
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-ingress-preflight.ts +0 -42
- package/src/calls/voice-quality.ts +38 -5
- package/src/calls/voice-session-bridge.ts +7 -12
- package/src/cli/commands/avatar.ts +2 -2
- package/src/cli/commands/config.ts +1 -4
- package/src/cli/commands/credentials.ts +128 -82
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/keys.ts +7 -7
- package/src/cli/commands/memory.ts +1 -1
- package/src/cli/commands/oauth/connections.ts +11 -29
- package/src/cli/commands/oauth/index.ts +7 -0
- package/src/cli/commands/oauth/platform.ts +525 -0
- package/src/cli/commands/platform.ts +3 -3
- package/src/cli/lib/daemon-credential-client.ts +284 -0
- package/src/cli.ts +1 -1
- package/src/config/assistant-feature-flags.ts +186 -5
- package/src/config/bundled-skills/AGENTS.md +34 -0
- package/src/config/bundled-skills/acp/SKILL.md +10 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +0 -4
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -2
- package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -0
- package/src/config/bundled-skills/settings/SKILL.md +15 -2
- package/src/config/bundled-skills/settings/TOOLS.json +47 -2
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +59 -0
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +80 -0
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
- package/src/config/bundled-skills/slack/SKILL.md +1 -1
- package/src/config/bundled-tool-registry.ts +5 -11
- package/src/config/defaults.ts +0 -2
- package/src/config/env-registry.ts +5 -5
- package/src/config/env.ts +21 -14
- package/src/config/feature-flag-registry.json +49 -9
- package/src/config/loader.ts +106 -42
- package/src/config/schema.ts +9 -29
- package/src/config/schemas/calls.ts +30 -0
- package/src/config/schemas/fish-audio.ts +39 -0
- package/src/config/schemas/inference.ts +2 -2
- package/src/config/schemas/journal.ts +16 -0
- package/src/config/schemas/memory-processing.ts +2 -2
- package/src/config/schemas/security.ts +0 -4
- package/src/config/types.ts +1 -1
- package/src/contacts/contact-store.ts +39 -0
- package/src/contacts/types.ts +2 -0
- package/src/credential-execution/approval-bridge.ts +1 -0
- package/src/credential-execution/executable-discovery.ts +28 -4
- package/src/credential-execution/feature-gates.ts +16 -0
- package/src/credential-execution/process-manager.ts +38 -0
- package/src/credential-execution/startup-timeout.ts +36 -0
- package/src/daemon/approval-generators.ts +3 -9
- package/src/daemon/assistant-attachments.ts +9 -0
- package/src/daemon/config-watcher.ts +5 -0
- package/src/daemon/conversation-error.ts +13 -1
- package/src/daemon/conversation-memory.ts +1 -2
- package/src/daemon/conversation-process.ts +18 -1
- package/src/daemon/conversation-surfaces.ts +30 -1
- package/src/daemon/conversation-tool-setup.ts +0 -105
- package/src/daemon/conversation.ts +21 -1
- package/src/daemon/guardian-action-generators.ts +3 -9
- package/src/daemon/handlers/config-vercel.ts +92 -0
- package/src/daemon/handlers/skills.ts +2 -15
- package/src/daemon/install-symlink.ts +195 -0
- package/src/daemon/lifecycle.ts +234 -51
- package/src/daemon/message-types/conversations.ts +4 -4
- package/src/daemon/message-types/diagnostics.ts +3 -22
- package/src/daemon/message-types/messages.ts +0 -2
- package/src/daemon/message-types/upgrades.ts +8 -0
- package/src/daemon/server.ts +32 -95
- package/src/events/domain-events.ts +2 -1
- package/src/inbound/platform-callback-registration.ts +3 -3
- package/src/instrument.ts +8 -5
- package/src/memory/app-store.ts +31 -0
- package/src/memory/conversation-title-service.ts +50 -1
- package/src/memory/db-init.ts +16 -0
- package/src/memory/indexer.ts +19 -10
- package/src/memory/items-extractor.ts +328 -321
- package/src/memory/job-handlers/conversation-starters.ts +4 -1
- package/src/memory/job-handlers/summarization.ts +26 -16
- package/src/memory/jobs-store.ts +63 -6
- package/src/memory/jobs-worker.ts +31 -7
- package/src/memory/journal-memory.ts +214 -0
- package/src/memory/migrations/001-job-deferrals.ts +19 -0
- package/src/memory/migrations/004-entity-relation-dedup.ts +10 -0
- package/src/memory/migrations/005-fingerprint-scope-unique.ts +76 -0
- package/src/memory/migrations/006-scope-salted-fingerprints.ts +50 -0
- package/src/memory/migrations/007-assistant-id-to-self.ts +10 -0
- package/src/memory/migrations/008-remove-assistant-id-columns.ts +34 -0
- package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +26 -0
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +10 -0
- package/src/memory/migrations/015-drop-active-search-index.ts +17 -0
- package/src/memory/migrations/019-notification-tables-schema-migration.ts +12 -0
- package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +121 -0
- package/src/memory/migrations/024-embedding-vector-blob.ts +74 -0
- package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +82 -0
- package/src/memory/migrations/036-normalize-phone-identities.ts +11 -0
- package/src/memory/migrations/116-messages-fts.ts +106 -1
- package/src/memory/migrations/126-backfill-guardian-principal-id.ts +52 -0
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +77 -0
- package/src/memory/migrations/134-contacts-notes-column.ts +13 -0
- package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +20 -0
- package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +13 -0
- package/src/memory/migrations/141-rename-verification-table.ts +54 -0
- package/src/memory/migrations/142-rename-verification-session-id-column.ts +25 -0
- package/src/memory/migrations/143-rename-guardian-verification-values.ts +35 -0
- package/src/memory/migrations/144-rename-voice-to-phone.ts +136 -0
- package/src/memory/migrations/145-drop-accounts-table.ts +32 -0
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +14 -1
- package/src/memory/migrations/148-drop-reminders-table.ts +35 -1
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +69 -1
- package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +290 -0
- package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +51 -1
- package/src/memory/migrations/174-rename-thread-starters-table.ts +47 -1
- package/src/memory/migrations/176-drop-capability-card-state.ts +13 -0
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +16 -0
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +28 -1
- package/src/memory/migrations/190-call-session-skip-disclosure.ts +15 -0
- package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +64 -0
- package/src/memory/migrations/192-contacts-user-file-column.ts +15 -0
- package/src/memory/migrations/193-add-source-type-columns.ts +81 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/migrations/registry.ts +98 -0
- package/src/memory/migrations/validate-migration-state.ts +137 -11
- package/src/memory/qdrant-circuit-breaker.ts +9 -0
- package/src/memory/qdrant-manager.ts +64 -7
- package/src/memory/retriever.test.ts +37 -25
- package/src/memory/retriever.ts +24 -49
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/contacts.ts +1 -0
- package/src/memory/schema/memory-core.ts +2 -0
- package/src/memory/search/formatting.ts +7 -44
- package/src/memory/search/staleness.ts +4 -0
- package/src/memory/search/tier-classifier.ts +10 -2
- package/src/memory/search/types.ts +2 -5
- package/src/memory/task-memory-cleanup.ts +4 -3
- package/src/notifications/adapters/slack.ts +168 -6
- package/src/notifications/broadcaster.ts +1 -0
- package/src/notifications/copy-composer.ts +59 -2
- package/src/notifications/decision-engine.ts +4 -1
- package/src/notifications/signal.ts +2 -0
- package/src/notifications/types.ts +2 -0
- package/src/oauth/connection-resolver.ts +6 -4
- package/src/permissions/checker.ts +0 -38
- package/src/permissions/shell-identity.ts +76 -22
- package/src/permissions/types.ts +4 -2
- package/src/platform/client.ts +35 -7
- package/src/prompts/journal-context.ts +133 -0
- package/src/prompts/persona-resolver.ts +194 -0
- package/src/prompts/system-prompt.ts +44 -4
- package/src/prompts/templates/SOUL.md +10 -0
- package/src/prompts/templates/users/default.md +1 -0
- package/src/providers/provider-send-message.ts +3 -32
- package/src/providers/registry.ts +29 -179
- package/src/providers/types.ts +1 -1
- package/src/runtime/access-request-helper.ts +4 -0
- package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
- package/src/runtime/auth/__tests__/external-assistant-id.test.ts +13 -68
- package/src/runtime/auth/__tests__/guard-tests.test.ts +9 -50
- package/src/runtime/auth/external-assistant-id.ts +13 -59
- package/src/runtime/auth/route-policy.ts +17 -1
- package/src/runtime/auth/token-service.ts +43 -138
- package/src/runtime/channel-readiness-service.ts +1 -16
- package/src/runtime/gateway-client.ts +47 -4
- package/src/runtime/guardian-decision-types.ts +45 -4
- package/src/runtime/http-server.ts +31 -3
- package/src/runtime/middleware/error-handler.ts +1 -9
- package/src/runtime/routes/access-request-decision.ts +2 -2
- package/src/runtime/routes/app-management-routes.ts +2 -1
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +219 -30
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +37 -14
- package/src/runtime/routes/audio-routes.ts +40 -0
- package/src/runtime/routes/btw-routes.ts +0 -17
- package/src/runtime/routes/channel-readiness-routes.ts +9 -4
- package/src/runtime/routes/conversation-query-routes.ts +63 -1
- package/src/runtime/routes/conversation-routes.ts +4 -44
- package/src/runtime/routes/debug-routes.ts +12 -9
- package/src/runtime/routes/diagnostics-routes.ts +1 -477
- package/src/runtime/routes/guardian-approval-interception.ts +168 -11
- package/src/runtime/routes/guardian-approval-prompt.ts +6 -1
- package/src/runtime/routes/guardian-approval-reply-helpers.ts +103 -21
- package/src/runtime/routes/identity-routes.ts +19 -30
- package/src/runtime/routes/inbound-message-handler.ts +31 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +64 -5
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +52 -40
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -33
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
- package/src/runtime/routes/integrations/twilio.ts +52 -10
- package/src/runtime/routes/integrations/vercel.ts +89 -0
- package/src/runtime/routes/log-export-routes.ts +5 -0
- package/src/runtime/routes/memory-item-routes.test.ts +3 -3
- package/src/runtime/routes/memory-item-routes.ts +46 -14
- package/src/runtime/routes/migration-rollback-routes.ts +209 -0
- package/src/runtime/routes/migration-routes.ts +17 -1
- package/src/runtime/routes/notification-routes.ts +58 -0
- package/src/runtime/routes/schedule-routes.ts +65 -0
- package/src/runtime/routes/secret-routes.ts +141 -10
- package/src/runtime/routes/settings-routes.ts +41 -1
- package/src/runtime/routes/tts-routes.ts +96 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +26 -2
- package/src/runtime/routes/workspace-commit-routes.ts +62 -0
- package/src/runtime/routes/workspace-routes.test.ts +22 -1
- package/src/runtime/routes/workspace-routes.ts +1 -1
- package/src/runtime/routes/workspace-utils.ts +86 -2
- package/src/security/ces-credential-client.ts +75 -29
- package/src/security/ces-rpc-credential-backend.ts +86 -0
- package/src/security/credential-backend.ts +22 -92
- package/src/security/keychain-broker-client.ts +10 -2
- package/src/security/secure-keys.ts +113 -115
- package/src/skills/catalog-install.ts +6 -32
- package/src/skills/skill-memory.ts +1 -0
- package/src/subagent/manager.ts +2 -5
- package/src/telemetry/usage-telemetry-reporter.ts +4 -2
- package/src/tools/acp/spawn.ts +78 -1
- package/src/tools/calls/call-start.ts +1 -0
- package/src/tools/credentials/vault.ts +5 -3
- package/src/tools/executor.ts +0 -4
- package/src/tools/memory/definitions.ts +3 -2
- package/src/tools/memory/handlers.ts +10 -7
- package/src/tools/network/script-proxy/session-manager.ts +19 -4
- package/src/tools/network/web-fetch.ts +3 -1
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/types.ts +0 -8
- package/src/util/browser.ts +15 -0
- package/src/util/errors.ts +0 -12
- package/src/util/platform.ts +4 -51
- package/src/workspace/git-service.ts +5 -2
- package/src/workspace/migrations/001-avatar-rename.ts +15 -0
- package/src/workspace/migrations/003-seed-device-id.ts +17 -1
- package/src/workspace/migrations/004-extract-collect-usage-data.ts +33 -0
- package/src/workspace/migrations/005-add-send-diagnostics.ts +3 -0
- package/src/workspace/migrations/006-services-config.ts +49 -0
- package/src/workspace/migrations/007-web-search-provider-rename.ts +27 -0
- package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +3 -0
- package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +4 -0
- package/src/workspace/migrations/010-app-dir-rename.ts +78 -0
- package/src/workspace/migrations/011-backfill-installation-id.ts +11 -0
- package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +44 -0
- package/src/workspace/migrations/013-repair-conversation-disk-view.ts +5 -0
- package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +153 -0
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +156 -0
- package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +150 -0
- package/src/workspace/migrations/017-seed-persona-dirs.ts +96 -0
- package/src/workspace/migrations/018-rekey-compound-credential-keys.ts +184 -0
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +103 -0
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +27 -5
- package/src/workspace/migrations/registry.ts +12 -0
- package/src/workspace/migrations/runner.ts +106 -2
- package/src/workspace/migrations/types.ts +4 -0
- package/src/workspace/provider-commit-message-generator.ts +12 -21
- package/src/__tests__/claude-code-skill-regression.test.ts +0 -206
- package/src/__tests__/claude-code-tool-profiles.test.ts +0 -99
- package/src/__tests__/diagnostics-export.test.ts +0 -288
- package/src/__tests__/local-gateway-health.test.ts +0 -209
- package/src/__tests__/provider-fail-open-selection.test.ts +0 -271
- package/src/__tests__/provider-failover-actual-provider.test.ts +0 -66
- package/src/__tests__/secret-ingress-handler.test.ts +0 -120
- package/src/__tests__/swarm-conversation-integration.test.ts +0 -358
- package/src/__tests__/swarm-dag-pathological.test.ts +0 -547
- package/src/__tests__/swarm-orchestrator.test.ts +0 -463
- package/src/__tests__/swarm-plan-validator.test.ts +0 -384
- package/src/__tests__/swarm-recursion.test.ts +0 -197
- package/src/__tests__/swarm-router-planner.test.ts +0 -234
- package/src/__tests__/swarm-tool.test.ts +0 -185
- package/src/__tests__/swarm-worker-backend.test.ts +0 -144
- package/src/__tests__/swarm-worker-runner.test.ts +0 -288
- package/src/commands/__tests__/cc-command-registry.test.ts +0 -396
- package/src/commands/cc-command-registry.ts +0 -248
- package/src/config/bundled-skills/claude-code/SKILL.md +0 -53
- package/src/config/bundled-skills/claude-code/TOOLS.json +0 -47
- package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -12
- package/src/config/bundled-skills/orchestration/SKILL.md +0 -33
- package/src/config/bundled-skills/orchestration/TOOLS.json +0 -35
- package/src/config/bundled-skills/orchestration/tools/swarm-delegate.ts +0 -12
- package/src/config/schemas/swarm.ts +0 -82
- package/src/logfire.ts +0 -135
- package/src/memory/search/lexical.ts +0 -48
- package/src/providers/failover.ts +0 -186
- package/src/runtime/local-gateway-health.ts +0 -275
- package/src/security/secret-ingress.ts +0 -68
- package/src/swarm/backend-claude-code.ts +0 -225
- package/src/swarm/checkpoint.ts +0 -137
- package/src/swarm/graph-utils.ts +0 -53
- package/src/swarm/index.ts +0 -55
- package/src/swarm/limits.ts +0 -66
- package/src/swarm/orchestrator.ts +0 -424
- package/src/swarm/plan-validator.ts +0 -117
- package/src/swarm/router-planner.ts +0 -162
- package/src/swarm/router-prompts.ts +0 -39
- package/src/swarm/synthesizer.ts +0 -81
- package/src/swarm/types.ts +0 -72
- package/src/swarm/worker-backend.ts +0 -131
- package/src/swarm/worker-prompts.ts +0 -80
- package/src/swarm/worker-runner.ts +0 -170
- package/src/tools/claude-code/claude-code.ts +0 -610
- package/src/tools/swarm/delegate.ts +0 -205
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Unified secure key storage — single-
|
|
2
|
+
* Unified secure key storage — single-backend routing through CredentialBackend
|
|
3
3
|
* adapters.
|
|
4
4
|
*
|
|
5
|
-
* Backend selection (`
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Backend selection (`resolveBackendAsync`) is the single async decision point:
|
|
6
|
+
* 1. CES RPC (primary) — injected via `setCesClient()`: delegates credential
|
|
7
|
+
* operations to the CES process over stdio RPC. This is the default path
|
|
8
|
+
* for all local modes (desktop app, dev, CLI).
|
|
9
|
+
* 2. CES HTTP — containerized mode (IS_CONTAINERIZED + CES_CREDENTIAL_URL):
|
|
10
|
+
* delegates to the CES sidecar over HTTP. Used in Docker/managed mode.
|
|
11
|
+
* 3. Encrypted file store (fallback) — used when CES is unavailable.
|
|
9
12
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* Deletes clean up both stores regardless of mode.
|
|
13
|
+
* All operations (reads, writes, lists, deletes) go to exactly one backend.
|
|
14
|
+
* There are no cross-backend fallbacks or merges.
|
|
13
15
|
*/
|
|
14
16
|
|
|
15
17
|
import type {
|
|
@@ -19,15 +21,21 @@ import type {
|
|
|
19
21
|
|
|
20
22
|
import providerEnvVarsRegistry from "../../../meta/provider-env-vars.json" with { type: "json" };
|
|
21
23
|
import { getIsContainerized } from "../config/env-registry.js";
|
|
24
|
+
import type { CesClient } from "../credential-execution/client.js";
|
|
22
25
|
import { getLogger } from "../util/logger.js";
|
|
23
26
|
import { createCesCredentialBackend } from "./ces-credential-client.js";
|
|
24
|
-
import
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
import { CesRpcCredentialBackend } from "./ces-rpc-credential-backend.js";
|
|
28
|
+
import type {
|
|
29
|
+
CredentialBackend,
|
|
30
|
+
CredentialListResult,
|
|
31
|
+
DeleteResult,
|
|
28
32
|
} from "./credential-backend.js";
|
|
33
|
+
import { createEncryptedStoreBackend } from "./credential-backend.js";
|
|
29
34
|
|
|
30
|
-
export type {
|
|
35
|
+
export type {
|
|
36
|
+
CredentialListResult,
|
|
37
|
+
DeleteResult,
|
|
38
|
+
} from "./credential-backend.js";
|
|
31
39
|
|
|
32
40
|
/**
|
|
33
41
|
* Re-export shared-package secure-key abstractions so downstream consumers
|
|
@@ -36,15 +44,24 @@ export type { DeleteResult } from "./credential-backend.js";
|
|
|
36
44
|
*/
|
|
37
45
|
export type { SecureKeyBackend, SecureKeyDeleteResult };
|
|
38
46
|
|
|
47
|
+
export interface SecureKeyResult {
|
|
48
|
+
value: string | undefined;
|
|
49
|
+
unreachable: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
39
52
|
const log = getLogger("secure-keys");
|
|
40
53
|
|
|
41
|
-
let
|
|
54
|
+
let _cesClient: CesClient | undefined;
|
|
42
55
|
let _encryptedStore: CredentialBackend | undefined;
|
|
43
56
|
let _resolvedBackend: CredentialBackend | undefined;
|
|
57
|
+
let _resolvePromise: Promise<CredentialBackend> | undefined;
|
|
44
58
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
59
|
+
/** Inject a CES RPC client for credential routing. Resets the resolved backend. */
|
|
60
|
+
export function setCesClient(client: CesClient | undefined): void {
|
|
61
|
+
_cesClient = client;
|
|
62
|
+
// Reset resolved backend so next call picks up CES
|
|
63
|
+
_resolvedBackend = undefined;
|
|
64
|
+
_resolvePromise = undefined;
|
|
48
65
|
}
|
|
49
66
|
|
|
50
67
|
function getEncryptedStoreBackend(): CredentialBackend {
|
|
@@ -53,101 +70,98 @@ function getEncryptedStoreBackend(): CredentialBackend {
|
|
|
53
70
|
}
|
|
54
71
|
|
|
55
72
|
/**
|
|
56
|
-
* Resolve the primary credential backend for this process.
|
|
73
|
+
* Resolve the primary credential backend for this process (async).
|
|
57
74
|
*
|
|
58
75
|
* Priority:
|
|
59
|
-
* 1.
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* 3. Dev mode (VELLUM_DEV=1) → encrypted file store always.
|
|
76
|
+
* 1. CES RPC client → primary path for all local modes.
|
|
77
|
+
* 2. Containerized + CES_CREDENTIAL_URL → CES HTTP client (Docker/managed).
|
|
78
|
+
* 3. Encrypted file store → fallback when CES is unavailable.
|
|
63
79
|
*
|
|
64
80
|
* Once resolved, the backend does not change during the process lifetime.
|
|
65
81
|
* Call `_resetBackend()` in tests to clear the cached resolution.
|
|
66
82
|
*/
|
|
67
|
-
function
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
83
|
+
async function resolveBackendAsync(): Promise<CredentialBackend> {
|
|
84
|
+
if (_resolvedBackend) return _resolvedBackend;
|
|
85
|
+
if (!_resolvePromise) {
|
|
86
|
+
_resolvePromise = doResolveBackend();
|
|
87
|
+
}
|
|
88
|
+
return _resolvePromise;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function doResolveBackend(): Promise<CredentialBackend> {
|
|
92
|
+
// 1. CES RPC — primary credential backend for all local modes
|
|
93
|
+
if (_cesClient) {
|
|
94
|
+
const cesRpc = new CesRpcCredentialBackend(_cesClient);
|
|
95
|
+
if (cesRpc.isAvailable()) {
|
|
96
|
+
_resolvedBackend = cesRpc;
|
|
97
|
+
return cesRpc;
|
|
79
98
|
}
|
|
99
|
+
log.warn(
|
|
100
|
+
"CES RPC client is set but not ready — falling back to local credential store",
|
|
101
|
+
);
|
|
102
|
+
}
|
|
80
103
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
} else {
|
|
88
|
-
_resolvedBackend = getEncryptedStoreBackend();
|
|
89
|
-
}
|
|
104
|
+
// 2. CES HTTP — containerized / Docker / managed mode
|
|
105
|
+
if (getIsContainerized() && process.env.CES_CREDENTIAL_URL) {
|
|
106
|
+
const ces = createCesCredentialBackend();
|
|
107
|
+
if (ces.isAvailable()) {
|
|
108
|
+
_resolvedBackend = ces;
|
|
109
|
+
return ces;
|
|
90
110
|
}
|
|
111
|
+
log.warn(
|
|
112
|
+
"CES_CREDENTIAL_URL is set but CES backend is not available — " +
|
|
113
|
+
"falling back to local credential store",
|
|
114
|
+
);
|
|
91
115
|
}
|
|
116
|
+
|
|
117
|
+
// 3. Encrypted file store — fallback when CES is unavailable
|
|
118
|
+
_resolvedBackend = getEncryptedStoreBackend();
|
|
92
119
|
return _resolvedBackend;
|
|
93
120
|
}
|
|
94
121
|
|
|
95
122
|
/**
|
|
96
|
-
* List all account names
|
|
123
|
+
* List all account names from the resolved backend (async).
|
|
97
124
|
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* When the primary backend is the keychain, this merges keys from the keychain
|
|
101
|
-
* and the encrypted store (for legacy keys that haven't been migrated). The
|
|
102
|
-
* result is deduplicated. When the primary backend is already the encrypted
|
|
103
|
-
* store, only that store is queried.
|
|
125
|
+
* Queries exactly one backend — no cross-store merge.
|
|
104
126
|
*/
|
|
105
|
-
export async function listSecureKeysAsync(): Promise<
|
|
106
|
-
const backend =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// CES mode — the sidecar is the single source of truth, no local merge.
|
|
110
|
-
if (backend.name === "ces-http") return primaryKeys;
|
|
111
|
-
|
|
112
|
-
// If primary backend is NOT the encrypted store, also check
|
|
113
|
-
// the encrypted store for legacy keys that haven't been migrated.
|
|
114
|
-
if (backend !== getEncryptedStoreBackend()) {
|
|
115
|
-
const encKeys = await getEncryptedStoreBackend().list();
|
|
116
|
-
const merged = new Set([...primaryKeys, ...encKeys]);
|
|
117
|
-
return Array.from(merged);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return primaryKeys;
|
|
127
|
+
export async function listSecureKeysAsync(): Promise<CredentialListResult> {
|
|
128
|
+
const backend = await resolveBackendAsync();
|
|
129
|
+
return backend.list();
|
|
121
130
|
}
|
|
122
131
|
|
|
123
132
|
// ---------------------------------------------------------------------------
|
|
124
|
-
// Async CRUD — single-
|
|
133
|
+
// Async CRUD — single-backend routing
|
|
125
134
|
// ---------------------------------------------------------------------------
|
|
126
135
|
|
|
127
136
|
/**
|
|
128
|
-
* Retrieve a secret from secure storage
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
137
|
+
* Retrieve a secret from secure storage with richer result metadata.
|
|
138
|
+
*
|
|
139
|
+
* Returns both the value (if found) and whether the backend was
|
|
140
|
+
* unreachable. Callers that need to distinguish "not found" from
|
|
141
|
+
* "backend down" should use this instead of `getSecureKeyAsync`.
|
|
142
|
+
*
|
|
143
|
+
* Reads from exactly one backend — no cross-store fallback.
|
|
133
144
|
*/
|
|
134
|
-
export async function
|
|
145
|
+
export async function getSecureKeyResultAsync(
|
|
135
146
|
account: string,
|
|
136
|
-
): Promise<
|
|
137
|
-
const backend =
|
|
147
|
+
): Promise<SecureKeyResult> {
|
|
148
|
+
const backend = await resolveBackendAsync();
|
|
138
149
|
const result = await backend.get(account);
|
|
139
|
-
if (result != null)
|
|
140
|
-
|
|
141
|
-
// CES mode — no local fallback.
|
|
142
|
-
if (backend.name === "ces-http") return undefined;
|
|
143
|
-
|
|
144
|
-
// Legacy fallback: if primary backend is NOT the encrypted store,
|
|
145
|
-
// check the encrypted store for keys that haven't been migrated.
|
|
146
|
-
if (backend !== getEncryptedStoreBackend()) {
|
|
147
|
-
return await getEncryptedStoreBackend().get(account);
|
|
150
|
+
if (result.value != null) {
|
|
151
|
+
return { value: result.value, unreachable: false };
|
|
148
152
|
}
|
|
153
|
+
return { value: undefined, unreachable: result.unreachable };
|
|
154
|
+
}
|
|
149
155
|
|
|
150
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Retrieve a secret from secure storage. Convenience wrapper over
|
|
158
|
+
* `getSecureKeyResultAsync` that returns only the value.
|
|
159
|
+
*/
|
|
160
|
+
export async function getSecureKeyAsync(
|
|
161
|
+
account: string,
|
|
162
|
+
): Promise<string | undefined> {
|
|
163
|
+
const result = await getSecureKeyResultAsync(account);
|
|
164
|
+
return result.value;
|
|
151
165
|
}
|
|
152
166
|
|
|
153
167
|
/**
|
|
@@ -158,7 +172,7 @@ export async function setSecureKeyAsync(
|
|
|
158
172
|
account: string,
|
|
159
173
|
value: string,
|
|
160
174
|
): Promise<boolean> {
|
|
161
|
-
const backend =
|
|
175
|
+
const backend = await resolveBackendAsync();
|
|
162
176
|
const ok = await backend.set(account, value);
|
|
163
177
|
if (!ok) {
|
|
164
178
|
log.warn(
|
|
@@ -172,38 +186,13 @@ export async function setSecureKeyAsync(
|
|
|
172
186
|
/**
|
|
173
187
|
* Delete a secret from secure storage.
|
|
174
188
|
*
|
|
175
|
-
*
|
|
176
|
-
* CES backend — there are no local stores to clean up.
|
|
177
|
-
*
|
|
178
|
-
* In local mode, always attempts deletion on both the keychain backend (if
|
|
179
|
-
* available) and the encrypted store backend, regardless of routing mode.
|
|
180
|
-
* This cleans up legacy data from both stores.
|
|
189
|
+
* Deletes from exactly one backend — no cross-store cleanup.
|
|
181
190
|
*/
|
|
182
191
|
export async function deleteSecureKeyAsync(
|
|
183
192
|
account: string,
|
|
184
193
|
): Promise<DeleteResult> {
|
|
185
|
-
const backend =
|
|
186
|
-
|
|
187
|
-
// In CES mode, the sidecar is the only store — no local cleanup needed.
|
|
188
|
-
if (backend.name === "ces-http") {
|
|
189
|
-
return backend.delete(account);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const keychain = getKeychainBackend();
|
|
193
|
-
const enc = getEncryptedStoreBackend();
|
|
194
|
-
|
|
195
|
-
let keychainResult: DeleteResult = "not-found";
|
|
196
|
-
if (keychain.isAvailable()) {
|
|
197
|
-
keychainResult = await keychain.delete(account);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const encResult = await enc.delete(account);
|
|
201
|
-
|
|
202
|
-
// Return "error" if either errored
|
|
203
|
-
if (keychainResult === "error" || encResult === "error") return "error";
|
|
204
|
-
// Return "deleted" if either deleted
|
|
205
|
-
if (keychainResult === "deleted" || encResult === "deleted") return "deleted";
|
|
206
|
-
return "not-found";
|
|
194
|
+
const backend = await resolveBackendAsync();
|
|
195
|
+
return backend.delete(account);
|
|
207
196
|
}
|
|
208
197
|
|
|
209
198
|
// ---------------------------------------------------------------------------
|
|
@@ -261,9 +250,18 @@ export async function getMaskedProviderKey(
|
|
|
261
250
|
// Test helpers
|
|
262
251
|
// ---------------------------------------------------------------------------
|
|
263
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Return the name of the currently resolved credential backend.
|
|
255
|
+
* Useful for diagnostic messages when credential operations fail.
|
|
256
|
+
*/
|
|
257
|
+
export function getActiveBackendName(): string {
|
|
258
|
+
return _resolvedBackend?.name ?? "none";
|
|
259
|
+
}
|
|
260
|
+
|
|
264
261
|
/** @internal Test-only: reset the cached backends so they're re-created. */
|
|
265
262
|
export function _resetBackend(): void {
|
|
266
|
-
|
|
263
|
+
_cesClient = undefined;
|
|
267
264
|
_encryptedStore = undefined;
|
|
268
265
|
_resolvedBackend = undefined;
|
|
266
|
+
_resolvePromise = undefined;
|
|
269
267
|
}
|
|
@@ -13,12 +13,9 @@ import { homedir } from "node:os";
|
|
|
13
13
|
import { dirname, join, posix, resolve, sep } from "node:path";
|
|
14
14
|
import { gunzipSync } from "node:zlib";
|
|
15
15
|
|
|
16
|
+
import { getPlatformBaseUrl } from "../config/env.js";
|
|
16
17
|
import { getLogger } from "../util/logger.js";
|
|
17
|
-
import {
|
|
18
|
-
getWorkspaceConfigPath,
|
|
19
|
-
getWorkspaceSkillsDir,
|
|
20
|
-
readPlatformToken,
|
|
21
|
-
} from "../util/platform.js";
|
|
18
|
+
import { getWorkspaceSkillsDir, readPlatformToken } from "../util/platform.js";
|
|
22
19
|
import { deleteSkillCapabilityMemory } from "./skill-memory.js";
|
|
23
20
|
|
|
24
21
|
const log = getLogger("catalog-install");
|
|
@@ -70,31 +67,6 @@ export function getRepoSkillsDir(): string | undefined {
|
|
|
70
67
|
|
|
71
68
|
// ─── Platform API ────────────────────────────────────────────────────────────
|
|
72
69
|
|
|
73
|
-
function getConfigPlatformUrl(): string | undefined {
|
|
74
|
-
try {
|
|
75
|
-
const configPath = getWorkspaceConfigPath();
|
|
76
|
-
if (!existsSync(configPath)) return undefined;
|
|
77
|
-
const raw = JSON.parse(readFileSync(configPath, "utf-8")) as Record<
|
|
78
|
-
string,
|
|
79
|
-
unknown
|
|
80
|
-
>;
|
|
81
|
-
const platform = raw.platform as Record<string, unknown> | undefined;
|
|
82
|
-
const baseUrl = platform?.baseUrl;
|
|
83
|
-
if (typeof baseUrl === "string" && baseUrl.trim()) return baseUrl.trim();
|
|
84
|
-
} catch {
|
|
85
|
-
// ignore
|
|
86
|
-
}
|
|
87
|
-
return undefined;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function getPlatformUrl(): string {
|
|
91
|
-
return (
|
|
92
|
-
process.env.VELLUM_PLATFORM_URL ??
|
|
93
|
-
getConfigPlatformUrl() ??
|
|
94
|
-
"https://platform.vellum.ai"
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
70
|
function buildHeaders(): Record<string, string> {
|
|
99
71
|
const headers: Record<string, string> = {};
|
|
100
72
|
const token = readPlatformToken();
|
|
@@ -107,7 +79,8 @@ function buildHeaders(): Record<string, string> {
|
|
|
107
79
|
// ─── Catalog operations ──────────────────────────────────────────────────────
|
|
108
80
|
|
|
109
81
|
export async function fetchCatalog(): Promise<CatalogSkill[]> {
|
|
110
|
-
const
|
|
82
|
+
const platformUrl = getPlatformBaseUrl();
|
|
83
|
+
const url = `${platformUrl}/v1/skills/`;
|
|
111
84
|
const response = await fetch(url, {
|
|
112
85
|
headers: buildHeaders(),
|
|
113
86
|
signal: AbortSignal.timeout(10000),
|
|
@@ -214,7 +187,8 @@ export async function fetchAndExtractSkill(
|
|
|
214
187
|
skillId: string,
|
|
215
188
|
destDir: string,
|
|
216
189
|
): Promise<void> {
|
|
217
|
-
const
|
|
190
|
+
const platformUrl = getPlatformBaseUrl();
|
|
191
|
+
const url = `${platformUrl}/v1/skills/${encodeURIComponent(skillId)}/`;
|
|
218
192
|
const response = await fetch(url, {
|
|
219
193
|
headers: buildHeaders(),
|
|
220
194
|
signal: AbortSignal.timeout(15000),
|
package/src/subagent/manager.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
19
19
|
import { bootstrapConversation } from "../memory/conversation-bootstrap.js";
|
|
20
20
|
import { RateLimitProvider } from "../providers/ratelimit.js";
|
|
21
|
-
import {
|
|
21
|
+
import { getProvider } from "../providers/registry.js";
|
|
22
22
|
import { getLogger } from "../util/logger.js";
|
|
23
23
|
import { getSandboxWorkingDir } from "../util/platform.js";
|
|
24
24
|
import {
|
|
@@ -129,10 +129,7 @@ export class SubagentManager {
|
|
|
129
129
|
|
|
130
130
|
// ── Build conversation dependencies ─────────────────────────────
|
|
131
131
|
const appConfig = getConfig();
|
|
132
|
-
let provider =
|
|
133
|
-
appConfig.services.inference.provider,
|
|
134
|
-
appConfig.providerOrder,
|
|
135
|
-
);
|
|
132
|
+
let provider = getProvider(appConfig.services.inference.provider);
|
|
136
133
|
const { rateLimit } = appConfig;
|
|
137
134
|
if (rateLimit.maxRequestsPerMinute > 0) {
|
|
138
135
|
provider = new RateLimitProvider(
|
|
@@ -140,7 +140,7 @@ export class UsageTelemetryReporter {
|
|
|
140
140
|
|
|
141
141
|
// Resolve auth context — skip flush when neither auth mode is viable
|
|
142
142
|
const client = await VellumPlatformClient.create();
|
|
143
|
-
if (!client && !getTelemetryAppToken()) {
|
|
143
|
+
if (!client && (!getTelemetryAppToken() || !getTelemetryPlatformUrl())) {
|
|
144
144
|
return;
|
|
145
145
|
}
|
|
146
146
|
|
|
@@ -203,7 +203,9 @@ export class UsageTelemetryReporter {
|
|
|
203
203
|
if (client) {
|
|
204
204
|
resp = await client.fetch(TELEMETRY_PATH, fetchInit);
|
|
205
205
|
} else {
|
|
206
|
-
const
|
|
206
|
+
const platformUrl = getTelemetryPlatformUrl();
|
|
207
|
+
if (!platformUrl) return;
|
|
208
|
+
const url = `${platformUrl}${TELEMETRY_PATH}`;
|
|
207
209
|
resp = await fetch(url, {
|
|
208
210
|
...fetchInit,
|
|
209
211
|
headers: {
|
package/src/tools/acp/spawn.ts
CHANGED
|
@@ -1,7 +1,68 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
|
|
1
4
|
import { getAcpSessionManager } from "../../acp/index.js";
|
|
2
5
|
import { getConfig } from "../../config/loader.js";
|
|
6
|
+
import { getLogger } from "../../util/logger.js";
|
|
3
7
|
import type { ToolContext, ToolExecutionResult } from "../types.js";
|
|
4
8
|
|
|
9
|
+
const execFileAsync = promisify(execFile);
|
|
10
|
+
const log = getLogger("acp:spawn");
|
|
11
|
+
|
|
12
|
+
/** Cache so we only check once per process lifetime. */
|
|
13
|
+
let adapterVersionChecked = false;
|
|
14
|
+
|
|
15
|
+
interface AdapterVersionInfo {
|
|
16
|
+
outdated: true;
|
|
17
|
+
installed: string;
|
|
18
|
+
latest: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Checks if the globally-installed claude-agent-acp adapter is outdated.
|
|
23
|
+
* Runs at most once per process lifetime. Does NOT auto-update — returns
|
|
24
|
+
* version info so the caller can ask the user first.
|
|
25
|
+
*/
|
|
26
|
+
async function checkAdapterVersion(
|
|
27
|
+
command: string,
|
|
28
|
+
): Promise<AdapterVersionInfo | null> {
|
|
29
|
+
if (adapterVersionChecked || command !== "claude-agent-acp") {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const { stdout: installedRaw } = await execFileAsync("npm", [
|
|
35
|
+
"ls",
|
|
36
|
+
"-g",
|
|
37
|
+
"--json",
|
|
38
|
+
"@zed-industries/claude-agent-acp",
|
|
39
|
+
]);
|
|
40
|
+
const { stdout: latestRaw } = await execFileAsync("npm", [
|
|
41
|
+
"view",
|
|
42
|
+
"@zed-industries/claude-agent-acp",
|
|
43
|
+
"version",
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
const installed =
|
|
47
|
+
JSON.parse(installedRaw)?.dependencies?.[
|
|
48
|
+
"@zed-industries/claude-agent-acp"
|
|
49
|
+
]?.version;
|
|
50
|
+
const latest = latestRaw.trim();
|
|
51
|
+
|
|
52
|
+
adapterVersionChecked = true;
|
|
53
|
+
|
|
54
|
+
if (!installed || !latest || installed === latest) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
log.info({ installed, latest }, "claude-agent-acp is outdated");
|
|
59
|
+
return { outdated: true, installed, latest };
|
|
60
|
+
} catch (err) {
|
|
61
|
+
log.warn({ err }, "Failed to check claude-agent-acp version");
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
5
66
|
export async function executeAcpSpawn(
|
|
6
67
|
input: Record<string, unknown>,
|
|
7
68
|
context: ToolContext,
|
|
@@ -37,6 +98,17 @@ export async function executeAcpSpawn(
|
|
|
37
98
|
};
|
|
38
99
|
}
|
|
39
100
|
|
|
101
|
+
// Check if the ACP adapter is outdated before spawning
|
|
102
|
+
const versionInfo = await checkAdapterVersion(agentConfig.command);
|
|
103
|
+
if (versionInfo) {
|
|
104
|
+
return {
|
|
105
|
+
content:
|
|
106
|
+
`claude-agent-acp is outdated (installed: ${versionInfo.installed}, latest: ${versionInfo.latest}). ` +
|
|
107
|
+
`Ask the user if they'd like to update. If yes, run: npm install -g @zed-industries/claude-agent-acp@${versionInfo.latest} — then retry acp_spawn.`,
|
|
108
|
+
isError: true,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
40
112
|
try {
|
|
41
113
|
const manager = getAcpSessionManager();
|
|
42
114
|
const cwd = (input.cwd as string) || context.workingDir;
|
|
@@ -64,7 +136,12 @@ export async function executeAcpSpawn(
|
|
|
64
136
|
isError: false,
|
|
65
137
|
};
|
|
66
138
|
} catch (err) {
|
|
67
|
-
const msg =
|
|
139
|
+
const msg =
|
|
140
|
+
err instanceof Error
|
|
141
|
+
? err.message
|
|
142
|
+
: typeof err === "object" && err !== undefined
|
|
143
|
+
? JSON.stringify(err)
|
|
144
|
+
: String(err);
|
|
68
145
|
return { content: `Failed to spawn ACP agent: ${msg}`, isError: true };
|
|
69
146
|
}
|
|
70
147
|
}
|
|
@@ -400,8 +400,9 @@ class CredentialStoreTool implements Tool {
|
|
|
400
400
|
const credIdSuffix = metadata
|
|
401
401
|
? ` (credential_id: ${metadata.credentialId})`
|
|
402
402
|
: "";
|
|
403
|
+
const retrieveHint = ` Retrieve with: \`assistant credentials reveal --service ${service} --field ${field}\``;
|
|
403
404
|
return {
|
|
404
|
-
content: `Stored credential for ${service}/${field}.${credIdSuffix}${
|
|
405
|
+
content: `Stored credential for ${service}/${field}.${credIdSuffix}${retrieveHint}${
|
|
405
406
|
slackChannelResult
|
|
406
407
|
? formatSlackChannelStatus(slackChannelResult)
|
|
407
408
|
: ""
|
|
@@ -428,7 +429,7 @@ class CredentialStoreTool implements Tool {
|
|
|
428
429
|
// (e.g. keychain) and the encrypted store (legacy keys).
|
|
429
430
|
let secureKeySet: Set<string> | undefined;
|
|
430
431
|
try {
|
|
431
|
-
secureKeySet = new Set(await listSecureKeysAsync());
|
|
432
|
+
secureKeySet = new Set((await listSecureKeysAsync()).accounts);
|
|
432
433
|
} catch (err) {
|
|
433
434
|
log.error(
|
|
434
435
|
{ err },
|
|
@@ -810,8 +811,9 @@ class CredentialStoreTool implements Tool {
|
|
|
810
811
|
const promptCredIdSuffix = promptMeta
|
|
811
812
|
? ` (credential_id: ${promptMeta.credentialId})`
|
|
812
813
|
: "";
|
|
814
|
+
const promptRetrieveHint = ` Retrieve with: \`assistant credentials reveal --service ${service} --field ${field}\``;
|
|
813
815
|
return {
|
|
814
|
-
content: `Credential stored for ${service}/${field}.${promptCredIdSuffix}${
|
|
816
|
+
content: `Credential stored for ${service}/${field}.${promptCredIdSuffix}${promptRetrieveHint}${
|
|
815
817
|
slackChannelResult
|
|
816
818
|
? formatSlackChannelStatus(slackChannelResult)
|
|
817
819
|
: ""
|
package/src/tools/executor.ts
CHANGED
|
@@ -183,10 +183,6 @@ export class ToolExecutor {
|
|
|
183
183
|
);
|
|
184
184
|
// Buffer so the shell's own timeout fires first and handles cleanup
|
|
185
185
|
toolTimeoutMs = (shellTimeoutSec + 5) * 1000;
|
|
186
|
-
} else if (name === "claude_code") {
|
|
187
|
-
// Claude Code spawns a subprocess that manages its own turn limits
|
|
188
|
-
// (maxTurns). Give it a generous timeout so it isn't killed mid-task.
|
|
189
|
-
toolTimeoutMs = 10 * 60 * 1000; // 10 minutes
|
|
190
186
|
} else {
|
|
191
187
|
const rawTimeoutSec = getConfig().timeouts.toolExecutionTimeoutSec;
|
|
192
188
|
toolTimeoutMs = safeTimeoutMs(rawTimeoutSec);
|
|
@@ -46,9 +46,10 @@ const memoryManageProperties = {
|
|
|
46
46
|
"decision",
|
|
47
47
|
"constraint",
|
|
48
48
|
"event",
|
|
49
|
+
"journal",
|
|
49
50
|
],
|
|
50
51
|
description:
|
|
51
|
-
'Category of the memory item (required for save). Use "constraint" for mistakes, gotchas, discoveries, and working solutions - write as advice to your future self.',
|
|
52
|
+
'Category of the memory item (required for save). Use "constraint" for mistakes, gotchas, discoveries, and working solutions - write as advice to your future self. Use "journal" for journal-style memories — experiential snapshots, upcoming events, things to carry forward.',
|
|
52
53
|
},
|
|
53
54
|
subject: {
|
|
54
55
|
type: "string" as const,
|
|
@@ -59,7 +60,7 @@ const memoryManageProperties = {
|
|
|
59
60
|
export const memoryManageDefinition: ToolDefinition = {
|
|
60
61
|
name: "memory_manage",
|
|
61
62
|
description:
|
|
62
|
-
"Save, update, or delete memory items.
|
|
63
|
+
"Save, update, or delete memory items. If you want to remember something, save it now. Use 'save' for new information worth remembering (facts, preferences, mistakes, discoveries, gotchas), 'update' to correct existing items, 'delete' to remove outdated items. When a user says 'remember this', save immediately. Be proactive: if you learn something important that may be useful in the future, always call this tool — don't just say or hope you'll remember it. This is not a substitute for updating workspace files when relevant - do both.",
|
|
63
64
|
input_schema: {
|
|
64
65
|
type: "object",
|
|
65
66
|
properties: memoryManageProperties,
|