@vellumai/assistant 0.5.10 → 0.5.12
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/AGENTS.md +8 -0
- package/ARCHITECTURE.md +43 -43
- package/Dockerfile +3 -0
- package/docs/architecture/integrations.md +37 -42
- package/docs/architecture/memory.md +7 -12
- package/docs/credential-execution-service.md +9 -9
- package/docs/skills.md +1 -1
- package/node_modules/@vellumai/ces-contracts/src/__tests__/grants.test.ts +7 -7
- package/node_modules/@vellumai/ces-contracts/src/handles.ts +5 -4
- package/node_modules/@vellumai/credential-storage/src/index.ts +3 -3
- package/node_modules/@vellumai/credential-storage/src/static-credentials.ts +1 -1
- package/openapi.yaml +7208 -0
- package/package.json +2 -1
- package/scripts/generate-openapi.ts +562 -0
- package/src/__tests__/acp-session.test.ts +239 -44
- package/src/__tests__/assistant-feature-flag-guard.test.ts +8 -8
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +5 -86
- package/src/__tests__/assistant-feature-flags-integration.test.ts +7 -14
- package/src/__tests__/browser-skill-endstate.test.ts +1 -1
- package/src/__tests__/btw-routes.test.ts +8 -0
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +10 -10
- package/src/__tests__/catalog-cache.test.ts +164 -0
- package/src/__tests__/catalog-search.test.ts +61 -0
- package/src/__tests__/channel-approvals.test.ts +7 -7
- package/src/__tests__/channel-readiness-service.test.ts +41 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +181 -6
- package/src/__tests__/config-schema.test.ts +10 -2
- package/src/__tests__/context-memory-e2e.test.ts +2 -6
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +396 -0
- package/src/__tests__/conversation-error.test.ts +3 -2
- package/src/__tests__/conversation-skill-tools.test.ts +1 -3
- package/src/__tests__/conversation-title-service.test.ts +2 -15
- package/src/__tests__/credential-execution-feature-gates.test.ts +4 -8
- package/src/__tests__/credential-execution-managed-contract.test.ts +8 -8
- package/src/__tests__/credential-security-e2e.test.ts +4 -4
- package/src/__tests__/credential-security-invariants.test.ts +12 -18
- package/src/__tests__/credential-vault-unit.test.ts +32 -34
- package/src/__tests__/credential-vault.test.ts +25 -33
- package/src/__tests__/credentials-cli.test.ts +3 -3
- package/src/__tests__/daemon-credential-client.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -0
- package/src/__tests__/heartbeat-service.test.ts +35 -0
- package/src/__tests__/host-bash-proxy.test.ts +79 -0
- package/src/__tests__/host-cu-proxy.test.ts +90 -0
- package/src/__tests__/host-file-proxy.test.ts +89 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +3 -3
- package/src/__tests__/integration-status.test.ts +5 -5
- package/src/__tests__/list-messages-attachments.test.ts +171 -0
- package/src/__tests__/llm-request-log-turn-query.test.ts +64 -0
- package/src/__tests__/log-export-workspace.test.ts +1 -1
- package/src/__tests__/mcp-abort-signal.test.ts +205 -0
- package/src/__tests__/mcp-client-auth.test.ts +1 -1
- package/src/__tests__/memory-lifecycle-e2e.test.ts +2 -2
- package/src/__tests__/memory-recall-log-store.test.ts +182 -0
- package/src/__tests__/memory-recall-quality.test.ts +6 -8
- package/src/__tests__/memory-regressions.test.ts +53 -42
- package/src/__tests__/memory-retrieval.benchmark.test.ts +5 -9
- package/src/__tests__/messaging-send-tool.test.ts +5 -5
- package/src/__tests__/messaging-skill-split.test.ts +2 -17
- package/src/__tests__/notification-telegram-adapter.test.ts +125 -0
- package/src/__tests__/oauth-cli.test.ts +203 -649
- package/src/__tests__/oauth-provider-profiles.test.ts +55 -20
- package/src/__tests__/oauth-scope-policy.test.ts +4 -6
- package/src/__tests__/onboarding-template-contract.test.ts +2 -2
- package/src/__tests__/platform-callback-registration.test.ts +119 -0
- package/src/__tests__/secret-ingress-channel.test.ts +261 -0
- package/src/__tests__/secret-ingress-cli.test.ts +201 -0
- package/src/__tests__/secret-ingress-http.test.ts +312 -0
- package/src/__tests__/secret-ingress.test.ts +283 -0
- package/src/__tests__/secret-onetime-send.test.ts +4 -4
- package/src/__tests__/secret-routes-managed-proxy.test.ts +78 -0
- package/src/__tests__/secure-keys-managed-failover.test.ts +73 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +4 -4
- package/src/__tests__/skill-feature-flags.test.ts +11 -19
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -1
- package/src/__tests__/skill-load-inline-command.test.ts +3 -3
- package/src/__tests__/skill-load-inline-includes.test.ts +2 -2
- package/src/__tests__/skill-memory.test.ts +2 -4
- package/src/__tests__/skill-projection-feature-flag.test.ts +2 -4
- package/src/__tests__/skill-projection.benchmark.test.ts +1 -3
- package/src/__tests__/skills-uninstall.test.ts +2 -2
- package/src/__tests__/skills.test.ts +16 -2
- package/src/__tests__/slack-channel-config.test.ts +1 -1
- package/src/__tests__/slack-messaging-token-resolution.test.ts +22 -24
- package/src/__tests__/slack-share-routes.test.ts +5 -5
- package/src/__tests__/slack-skill.test.ts +5 -69
- package/src/__tests__/system-prompt.test.ts +39 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -1
- package/src/__tests__/workspace-migration-018-rekey-compound-credential-keys.test.ts +181 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +5 -4
- package/src/acp/client-handler.ts +113 -31
- package/src/acp/session-manager.ts +29 -27
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/cli/AGENTS.md +113 -0
- package/src/cli/commands/autonomy.ts +3 -5
- package/src/cli/commands/browser-relay.ts +2 -17
- package/src/cli/commands/contacts.ts +6 -4
- package/src/cli/commands/conversations.ts +13 -1
- package/src/cli/commands/credential-execution.ts +17 -3
- package/src/cli/commands/credentials.ts +2 -8
- package/src/cli/commands/memory.ts +2 -3
- package/src/cli/commands/oauth/__tests__/connect.test.ts +706 -0
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +686 -0
- package/src/cli/commands/oauth/__tests__/mode.test.ts +625 -0
- package/src/cli/commands/oauth/__tests__/ping.test.ts +631 -0
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +574 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +416 -0
- package/src/cli/commands/oauth/__tests__/status.test.ts +551 -0
- package/src/cli/commands/oauth/__tests__/token.test.ts +420 -0
- package/src/cli/commands/oauth/apps.ts +87 -50
- package/src/cli/commands/oauth/connect.ts +405 -0
- package/src/cli/commands/oauth/disconnect.ts +285 -0
- package/src/cli/commands/oauth/index.ts +62 -20
- package/src/cli/commands/oauth/mode.ts +251 -0
- package/src/cli/commands/oauth/ping.ts +196 -0
- package/src/cli/commands/oauth/providers.ts +589 -55
- package/src/cli/commands/oauth/request.ts +564 -0
- package/src/cli/commands/oauth/shared.ts +114 -0
- package/src/cli/commands/oauth/status.ts +191 -0
- package/src/cli/commands/oauth/token.ts +150 -0
- package/src/cli/commands/platform/connect.ts +104 -0
- package/src/cli/commands/platform/disconnect.ts +118 -0
- package/src/cli/commands/platform/index.ts +252 -0
- package/src/cli/commands/sequence.ts +5 -4
- package/src/cli/commands/shotgun.ts +16 -0
- package/src/cli/commands/skills.ts +173 -41
- package/src/cli/commands/usage.ts +5 -11
- package/src/cli/lib/daemon-credential-client.ts +22 -38
- package/src/cli/program.ts +1 -1
- package/src/cli.ts +82 -17
- package/src/config/assistant-feature-flags.ts +77 -18
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -1
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +1 -1
- package/src/config/bundled-skills/conversations/SKILL.md +20 -0
- package/src/config/bundled-skills/conversations/TOOLS.json +23 -0
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +66 -0
- package/src/config/bundled-skills/gmail/SKILL.md +13 -13
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +3 -3
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +2 -2
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +2 -2
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +1 -1
- package/src/config/bundled-skills/google-calendar/SKILL.md +10 -4
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +19 -42
- package/src/config/bundled-skills/messaging/TOOLS.json +9 -9
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +1 -1
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +5 -2
- package/src/config/bundled-skills/messaging/tools/shared.ts +5 -6
- package/src/config/bundled-skills/notifications/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/SKILL.md +2 -2
- package/src/config/bundled-skills/settings/SKILL.md +5 -3
- package/src/config/bundled-skills/settings/TOOLS.json +17 -0
- package/src/config/bundled-skills/settings/tools/avatar-get.ts +50 -0
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +7 -0
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +6 -1
- package/src/config/bundled-skills/settings/tools/identity-avatar.ts +55 -0
- package/src/config/bundled-skills/skills-catalog/SKILL.md +3 -3
- package/src/config/bundled-skills/slack/SKILL.md +58 -44
- package/src/config/bundled-tool-registry.ts +7 -19
- package/src/config/env.ts +5 -1
- package/src/config/feature-flag-registry.json +58 -42
- package/src/config/loader.ts +4 -0
- package/src/config/schemas/platform.ts +0 -8
- package/src/config/schemas/security.ts +9 -1
- package/src/config/schemas/services.ts +1 -1
- package/src/config/skill-state.ts +1 -3
- package/src/config/skills.ts +2 -4
- package/src/credential-execution/client.ts +1 -1
- package/src/credential-execution/feature-gates.ts +9 -16
- package/src/credential-execution/process-manager.ts +12 -0
- package/src/daemon/config-watcher.ts +4 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +10 -0
- package/src/daemon/conversation-agent-loop.ts +51 -2
- package/src/daemon/conversation-error.ts +36 -6
- package/src/daemon/conversation-memory.ts +0 -1
- package/src/daemon/conversation-messaging.ts +9 -0
- package/src/daemon/conversation-runtime-assembly.ts +33 -0
- package/src/daemon/conversation-surfaces.ts +120 -14
- package/src/daemon/conversation.ts +5 -0
- package/src/daemon/handlers/config-slack-channel.ts +43 -1
- package/src/daemon/handlers/conversations.ts +41 -33
- package/src/daemon/handlers/skills.ts +148 -3
- package/src/daemon/host-bash-proxy.ts +16 -0
- package/src/daemon/host-cu-proxy.ts +16 -0
- package/src/daemon/host-file-proxy.ts +16 -0
- package/src/daemon/lifecycle.ts +73 -3
- package/src/daemon/message-types/acp.ts +0 -15
- package/src/daemon/message-types/conversations.ts +1 -0
- package/src/daemon/message-types/guardian-actions.ts +2 -0
- package/src/daemon/message-types/host-bash.ts +6 -1
- package/src/daemon/message-types/host-cu.ts +6 -1
- package/src/daemon/message-types/host-file.ts +6 -1
- package/src/daemon/message-types/integrations.ts +0 -1
- package/src/daemon/message-types/memory.ts +0 -1
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/schedules.ts +9 -0
- package/src/daemon/server.ts +48 -9
- package/src/email/feature-gate.ts +3 -3
- package/src/heartbeat/heartbeat-service.ts +48 -0
- package/src/hooks/cli.ts +74 -0
- package/src/inbound/platform-callback-registration.ts +68 -19
- package/src/mcp/client.ts +6 -1
- package/src/mcp/manager.ts +2 -1
- package/src/mcp/mcp-oauth-provider.ts +3 -3
- package/src/memory/app-store.ts +3 -3
- package/src/memory/conversation-crud.ts +213 -0
- package/src/memory/conversation-key-store.ts +26 -0
- package/src/memory/conversation-title-service.ts +7 -17
- package/src/memory/db-init.ts +24 -0
- package/src/memory/embedding-local.ts +47 -2
- package/src/memory/indexer.ts +13 -10
- package/src/memory/items-extractor.ts +12 -4
- package/src/memory/job-utils.ts +5 -0
- package/src/memory/jobs-store.ts +10 -2
- package/src/memory/journal-memory.ts +6 -2
- package/src/memory/llm-request-log-store.ts +88 -21
- package/src/memory/memory-recall-log-store.ts +128 -0
- package/src/memory/migrations/194-memory-recall-logs.ts +50 -0
- package/src/memory/migrations/195-oauth-providers-ping-config.ts +23 -0
- package/src/memory/migrations/196-messages-conversation-created-at-index.ts +9 -0
- package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +186 -0
- package/src/memory/migrations/197-oauth-providers-behavior-columns.ts +29 -0
- package/src/memory/migrations/198-drop-setup-skill-id-column.ts +11 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/retriever.test.ts +4 -5
- package/src/memory/schema/infrastructure.ts +31 -0
- package/src/memory/schema/oauth.ts +14 -0
- package/src/messaging/provider.ts +13 -12
- package/src/messaging/providers/gmail/adapter.ts +44 -35
- package/src/messaging/providers/slack/adapter.ts +63 -33
- package/src/messaging/providers/telegram-bot/adapter.ts +7 -9
- package/src/messaging/providers/whatsapp/adapter.ts +6 -8
- package/src/notifications/adapters/telegram.ts +78 -2
- package/src/oauth/__tests__/identity-verifier.test.ts +464 -0
- package/src/oauth/byo-connection.test.ts +22 -24
- package/src/oauth/connect-orchestrator.ts +79 -64
- package/src/oauth/connect-types.ts +7 -65
- package/src/oauth/connection-resolver.test.ts +13 -13
- package/src/oauth/connection-resolver.ts +3 -4
- package/src/oauth/identity-verifier.ts +177 -0
- package/src/oauth/manual-token-connection.ts +5 -5
- package/src/oauth/oauth-store.ts +251 -5
- package/src/oauth/platform-connection.test.ts +56 -6
- package/src/oauth/platform-connection.ts +8 -1
- package/src/oauth/seed-providers.ts +256 -34
- package/src/permissions/checker.ts +129 -3
- package/src/permissions/trust-client.ts +2 -2
- package/src/platform/client.ts +2 -2
- package/src/prompts/journal-context.ts +6 -1
- package/src/prompts/system-prompt.ts +43 -9
- package/src/prompts/templates/BOOTSTRAP.md +16 -5
- package/src/providers/anthropic/client.ts +139 -28
- package/src/runtime/auth/__tests__/middleware.test.ts +19 -0
- package/src/runtime/auth/route-policy.ts +0 -1
- package/src/runtime/btw-sidechain.ts +7 -1
- package/src/runtime/channel-approvals.ts +2 -2
- package/src/runtime/channel-readiness-service.ts +30 -7
- package/src/runtime/guardian-action-service.ts +7 -2
- package/src/runtime/http-router.ts +31 -0
- package/src/runtime/http-server.ts +26 -7
- package/src/runtime/http-types.ts +9 -0
- package/src/runtime/pending-interactions.ts +21 -3
- package/src/runtime/routes/acp-routes.ts +46 -28
- package/src/runtime/routes/app-management-routes.ts +123 -0
- package/src/runtime/routes/app-routes.ts +31 -0
- package/src/runtime/routes/approval-routes.ts +108 -3
- package/src/runtime/routes/attachment-routes.ts +45 -0
- package/src/runtime/routes/avatar-routes.ts +16 -0
- package/src/runtime/routes/brain-graph-routes.ts +18 -0
- package/src/runtime/routes/btw-routes.ts +20 -0
- package/src/runtime/routes/call-routes.ts +81 -0
- package/src/runtime/routes/channel-readiness-routes.ts +48 -7
- package/src/runtime/routes/channel-routes.ts +18 -0
- package/src/runtime/routes/channel-verification-routes.ts +49 -1
- package/src/runtime/routes/contact-routes.ts +77 -0
- package/src/runtime/routes/conversation-attention-routes.ts +37 -0
- package/src/runtime/routes/conversation-management-routes.ts +125 -0
- package/src/runtime/routes/conversation-query-routes.ts +78 -0
- package/src/runtime/routes/conversation-routes.ts +191 -39
- package/src/runtime/routes/conversation-starter-routes.ts +29 -0
- package/src/runtime/routes/debug-routes.ts +23 -0
- package/src/runtime/routes/diagnostics-routes.ts +30 -0
- package/src/runtime/routes/documents-routes.ts +42 -0
- package/src/runtime/routes/events-routes.ts +10 -0
- package/src/runtime/routes/global-search-routes.ts +35 -0
- package/src/runtime/routes/guardian-action-routes.ts +61 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +77 -2
- package/src/runtime/routes/heartbeat-routes.ts +278 -0
- package/src/runtime/routes/host-bash-routes.ts +16 -1
- package/src/runtime/routes/host-cu-routes.ts +23 -1
- package/src/runtime/routes/host-file-routes.ts +18 -1
- package/src/runtime/routes/identity-routes.ts +35 -0
- package/src/runtime/routes/inbound-message-handler.ts +46 -25
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -8
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +30 -2
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +1 -2
- package/src/runtime/routes/integrations/slack/share.ts +1 -1
- package/src/runtime/routes/integrations/twilio.ts +32 -22
- package/src/runtime/routes/invite-routes.ts +83 -0
- package/src/runtime/routes/log-export-routes.ts +14 -0
- package/src/runtime/routes/memory-item-routes.ts +99 -1
- package/src/runtime/routes/migration-rollback-routes.ts +25 -0
- package/src/runtime/routes/migration-routes.ts +40 -0
- package/src/runtime/routes/notification-routes.ts +20 -0
- package/src/runtime/routes/oauth-apps.ts +13 -4
- package/src/runtime/routes/pairing-routes.ts +15 -0
- package/src/runtime/routes/recording-routes.ts +72 -0
- package/src/runtime/routes/schedule-routes.ts +77 -5
- package/src/runtime/routes/secret-routes.ts +99 -14
- package/src/runtime/routes/settings-routes.ts +102 -19
- package/src/runtime/routes/skills-routes.ts +141 -18
- package/src/runtime/routes/subagents-routes.ts +38 -3
- package/src/runtime/routes/surface-action-routes.ts +66 -24
- package/src/runtime/routes/surface-content-routes.ts +20 -0
- package/src/runtime/routes/telemetry-routes.ts +12 -0
- package/src/runtime/routes/trace-event-routes.ts +25 -0
- package/src/runtime/routes/trust-rules-routes.ts +46 -0
- package/src/runtime/routes/tts-routes.ts +15 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +38 -0
- package/src/runtime/routes/usage-routes.ts +59 -0
- package/src/runtime/routes/watch-routes.ts +28 -0
- package/src/runtime/routes/work-items-routes.ts +59 -0
- package/src/runtime/routes/workspace-commit-routes.ts +12 -0
- package/src/runtime/routes/workspace-routes.ts +102 -0
- package/src/schedule/integration-status.ts +2 -2
- package/src/schedule/scheduler.ts +7 -1
- package/src/security/AGENTS.md +7 -0
- package/src/security/ces-rpc-credential-backend.ts +19 -16
- package/src/security/credential-backend.ts +1 -1
- package/src/security/encrypted-store.ts +3 -3
- package/src/security/oauth-completion-page.ts +153 -0
- package/src/security/oauth2.ts +58 -17
- package/src/security/secret-ingress.ts +174 -0
- package/src/security/secret-patterns.ts +133 -0
- package/src/security/secret-scanner.ts +28 -117
- package/src/security/secure-keys.ts +207 -7
- package/src/security/token-manager.ts +3 -6
- package/src/signals/bash.ts +6 -1
- package/src/signals/confirm.ts +12 -8
- package/src/signals/user-message.ts +18 -3
- package/src/skills/catalog-cache.ts +44 -0
- package/src/skills/catalog-search.ts +18 -0
- package/src/skills/skill-memory.ts +1 -2
- package/src/tasks/task-runner.ts +7 -1
- package/src/tools/credentials/broker.ts +1 -1
- package/src/tools/credentials/metadata-store.ts +1 -1
- package/src/tools/credentials/post-connect-hooks.ts +1 -1
- package/src/tools/credentials/vault.ts +36 -48
- package/src/tools/host-terminal/host-shell.ts +16 -3
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/definitions.ts +1 -1
- package/src/tools/memory/handlers.test.ts +2 -4
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/skills/sandbox-runner.ts +16 -3
- package/src/tools/terminal/safe-env.ts +7 -0
- package/src/tools/terminal/shell.ts +16 -3
- package/src/tools/tool-manifest.ts +1 -1
- package/src/util/log-redact.ts +9 -34
- package/src/util/logger.ts +11 -1
- package/src/util/sentry-log-stream.ts +51 -0
- package/src/watcher/providers/github.ts +2 -2
- package/src/watcher/providers/gmail.ts +1 -1
- package/src/watcher/providers/google-calendar.ts +1 -1
- package/src/watcher/providers/linear.ts +2 -2
- package/src/workspace/migrations/011-backfill-installation-id.ts +5 -3
- package/src/workspace/migrations/020-rename-oauth-skill-dirs.ts +119 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/docs/architecture/keychain-broker.md +0 -68
- package/src/cli/commands/oauth/connections.ts +0 -734
- package/src/cli/commands/oauth/platform.ts +0 -525
- package/src/cli/commands/platform.ts +0 -176
- package/src/config/bundled-skills/slack/TOOLS.json +0 -272
- package/src/config/bundled-skills/slack/tools/shared.ts +0 -34
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +0 -27
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +0 -38
- package/src/config/bundled-skills/slack/tools/slack-channel-permissions.ts +0 -146
- package/src/config/bundled-skills/slack/tools/slack-configure-channels.ts +0 -105
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +0 -26
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +0 -27
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +0 -25
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +0 -372
- package/src/oauth/provider-behaviors.ts +0 -634
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
registerCallbackRoute,
|
|
5
|
+
resolvePlatformCallbackRegistrationContext,
|
|
6
|
+
} from "../../../inbound/platform-callback-registration.js";
|
|
7
|
+
import { credentialKey } from "../../../security/credential-key.js";
|
|
8
|
+
import { getSecureKeyViaDaemon } from "../../lib/daemon-credential-client.js";
|
|
9
|
+
import { log } from "../../logger.js";
|
|
10
|
+
import { shouldOutputJson, writeOutput } from "../../output.js";
|
|
11
|
+
import { CREDENTIAL_KEYS, registerPlatformConnectCommand } from "./connect.js";
|
|
12
|
+
import { registerPlatformDisconnectCommand } from "./disconnect.js";
|
|
13
|
+
|
|
14
|
+
export function registerPlatformCommand(program: Command): void {
|
|
15
|
+
const platform = program
|
|
16
|
+
.command("platform")
|
|
17
|
+
.description("Manage platform integration for containerized deployments")
|
|
18
|
+
.option("--json", "Machine-readable compact JSON output");
|
|
19
|
+
|
|
20
|
+
platform.addHelpText(
|
|
21
|
+
"after",
|
|
22
|
+
`
|
|
23
|
+
The platform subsystem manages the connection to Vellum Platform, callback
|
|
24
|
+
routing, containerized deployment context, and webhook forwarding for
|
|
25
|
+
assistants. Use 'connect', 'status', and 'disconnect' to manage platform
|
|
26
|
+
credentials. When IS_CONTAINERIZED=true with a configured VELLUM_PLATFORM_URL
|
|
27
|
+
and PLATFORM_ASSISTANT_ID, external service callbacks (Telegram webhooks,
|
|
28
|
+
Twilio webhooks, OAuth redirects) route through the platform's gateway proxy
|
|
29
|
+
instead of hitting the assistant directly.
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
$ assistant platform status --json
|
|
33
|
+
$ assistant platform connect
|
|
34
|
+
$ assistant platform disconnect
|
|
35
|
+
$ assistant platform callback-routes register --path webhooks/telegram --type telegram --json`,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// connect — store platform credentials and validate the connection
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
registerPlatformConnectCommand(platform);
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// status — deployment context and connection status combined
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
platform
|
|
49
|
+
.command("status")
|
|
50
|
+
.description(
|
|
51
|
+
"Show current platform deployment context and connection status",
|
|
52
|
+
)
|
|
53
|
+
.addHelpText(
|
|
54
|
+
"after",
|
|
55
|
+
`
|
|
56
|
+
Reads platform-related environment variables and stored credentials to report
|
|
57
|
+
the current containerized deployment context and connection state. Does not
|
|
58
|
+
require the assistant to be running.
|
|
59
|
+
|
|
60
|
+
Fields:
|
|
61
|
+
containerized Whether IS_CONTAINERIZED is set (boolean)
|
|
62
|
+
baseUrl VELLUM_PLATFORM_URL — the platform gateway base URL
|
|
63
|
+
assistantId PLATFORM_ASSISTANT_ID — this assistant's platform UUID
|
|
64
|
+
hasInternalApiKey Whether PLATFORM_INTERNAL_API_KEY is set (boolean,
|
|
65
|
+
value not disclosed)
|
|
66
|
+
hasAssistantApiKey Whether a stored assistant API key is available
|
|
67
|
+
available Whether callback registration prerequisites are satisfied
|
|
68
|
+
connected Whether platform credentials are stored (boolean)
|
|
69
|
+
organizationId The platform organization ID (from stored credentials)
|
|
70
|
+
userId The platform user ID (from stored credentials)
|
|
71
|
+
|
|
72
|
+
Examples:
|
|
73
|
+
$ assistant platform status
|
|
74
|
+
$ assistant platform status --json`,
|
|
75
|
+
)
|
|
76
|
+
.action(async (_opts: Record<string, unknown>, cmd: Command) => {
|
|
77
|
+
try {
|
|
78
|
+
const context = await resolvePlatformCallbackRegistrationContext();
|
|
79
|
+
|
|
80
|
+
const storedBaseUrl =
|
|
81
|
+
(await getSecureKeyViaDaemon(
|
|
82
|
+
credentialKey(
|
|
83
|
+
CREDENTIAL_KEYS.baseUrl.service,
|
|
84
|
+
CREDENTIAL_KEYS.baseUrl.field,
|
|
85
|
+
),
|
|
86
|
+
)) ?? "";
|
|
87
|
+
const hasStoredApiKey = !!(await getSecureKeyViaDaemon(
|
|
88
|
+
credentialKey(
|
|
89
|
+
CREDENTIAL_KEYS.apiKey.service,
|
|
90
|
+
CREDENTIAL_KEYS.apiKey.field,
|
|
91
|
+
),
|
|
92
|
+
));
|
|
93
|
+
const organizationId =
|
|
94
|
+
(
|
|
95
|
+
await getSecureKeyViaDaemon(
|
|
96
|
+
credentialKey(
|
|
97
|
+
CREDENTIAL_KEYS.organizationId.service,
|
|
98
|
+
CREDENTIAL_KEYS.organizationId.field,
|
|
99
|
+
),
|
|
100
|
+
)
|
|
101
|
+
)?.trim() ?? "";
|
|
102
|
+
const userId =
|
|
103
|
+
(
|
|
104
|
+
await getSecureKeyViaDaemon(
|
|
105
|
+
credentialKey(
|
|
106
|
+
CREDENTIAL_KEYS.userId.service,
|
|
107
|
+
CREDENTIAL_KEYS.userId.field,
|
|
108
|
+
),
|
|
109
|
+
)
|
|
110
|
+
)?.trim() ?? "";
|
|
111
|
+
|
|
112
|
+
const connected = !!storedBaseUrl && hasStoredApiKey;
|
|
113
|
+
|
|
114
|
+
const result = {
|
|
115
|
+
containerized: context.containerized,
|
|
116
|
+
baseUrl: context.platformBaseUrl,
|
|
117
|
+
assistantId: context.assistantId,
|
|
118
|
+
hasInternalApiKey: context.hasInternalApiKey,
|
|
119
|
+
hasAssistantApiKey: context.hasAssistantApiKey,
|
|
120
|
+
available: context.enabled,
|
|
121
|
+
connected,
|
|
122
|
+
organizationId: organizationId || null,
|
|
123
|
+
userId: userId || null,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
writeOutput(cmd, result);
|
|
127
|
+
|
|
128
|
+
if (!shouldOutputJson(cmd)) {
|
|
129
|
+
log.info(`Containerized: ${result.containerized}`);
|
|
130
|
+
log.info(`Base URL: ${result.baseUrl || "(not set)"}`);
|
|
131
|
+
log.info(`Assistant ID: ${result.assistantId || "(not set)"}`);
|
|
132
|
+
log.info(
|
|
133
|
+
`Internal API key: ${result.hasInternalApiKey ? "set" : "not set"}`,
|
|
134
|
+
);
|
|
135
|
+
log.info(
|
|
136
|
+
`Assistant API key: ${result.hasAssistantApiKey ? "set" : "not set"}`,
|
|
137
|
+
);
|
|
138
|
+
log.info(
|
|
139
|
+
`Callback registration available: ${result.available ? "yes" : "no"}`,
|
|
140
|
+
);
|
|
141
|
+
log.info(`Connected: ${connected}`);
|
|
142
|
+
log.info(`Organization ID: ${organizationId || "(not set)"}`);
|
|
143
|
+
log.info(`User ID: ${userId || "(not set)"}`);
|
|
144
|
+
}
|
|
145
|
+
} catch (err) {
|
|
146
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
147
|
+
writeOutput(cmd, { ok: false, error: message });
|
|
148
|
+
process.exitCode = 1;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// disconnect — remove stored platform credentials
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
|
|
156
|
+
registerPlatformDisconnectCommand(platform);
|
|
157
|
+
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
// callback-routes
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
|
|
162
|
+
const callbackRoutes = platform
|
|
163
|
+
.command("callback-routes")
|
|
164
|
+
.description("Manage platform callback route registrations");
|
|
165
|
+
|
|
166
|
+
callbackRoutes.addHelpText(
|
|
167
|
+
"after",
|
|
168
|
+
`
|
|
169
|
+
Callback routes tell the platform gateway how to forward inbound provider
|
|
170
|
+
webhooks to the correct containerized assistant instance. Each route maps a
|
|
171
|
+
callback path and type to a stable external URL that external services
|
|
172
|
+
(Telegram, Twilio, OAuth providers) should use.
|
|
173
|
+
|
|
174
|
+
Examples:
|
|
175
|
+
$ assistant platform callback-routes register --path webhooks/telegram --type telegram --json
|
|
176
|
+
$ assistant platform callback-routes register --path webhooks/twilio/voice --type twilio_voice --json`,
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// callback-routes register
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
|
|
183
|
+
callbackRoutes
|
|
184
|
+
.command("register")
|
|
185
|
+
.description("Register a callback route with the platform gateway")
|
|
186
|
+
.requiredOption(
|
|
187
|
+
"--path <path>",
|
|
188
|
+
"Callback path (e.g. webhooks/telegram, webhooks/twilio/voice)",
|
|
189
|
+
)
|
|
190
|
+
.requiredOption(
|
|
191
|
+
"--type <type>",
|
|
192
|
+
"Route type identifier (e.g. telegram, twilio_voice, twilio_status, oauth)",
|
|
193
|
+
)
|
|
194
|
+
.addHelpText(
|
|
195
|
+
"after",
|
|
196
|
+
`
|
|
197
|
+
Registers a callback route with the platform's internal gateway endpoint so
|
|
198
|
+
the platform knows how to forward inbound provider webhooks to this
|
|
199
|
+
containerized assistant instance.
|
|
200
|
+
|
|
201
|
+
Arguments:
|
|
202
|
+
--path The path portion after the ingress base URL. Leading/trailing
|
|
203
|
+
slashes are stripped by the platform.
|
|
204
|
+
--type The route type identifier used by the platform to classify and
|
|
205
|
+
route the callback.
|
|
206
|
+
|
|
207
|
+
Known callback path/type combinations:
|
|
208
|
+
--path webhooks/telegram --type telegram
|
|
209
|
+
--path webhooks/twilio/voice --type twilio_voice
|
|
210
|
+
--path webhooks/twilio/status --type twilio_status
|
|
211
|
+
--path oauth/callback --type oauth
|
|
212
|
+
|
|
213
|
+
Requires a containerized environment (IS_CONTAINERIZED=true) with
|
|
214
|
+
VELLUM_PLATFORM_URL and PLATFORM_ASSISTANT_ID configured. Returns the
|
|
215
|
+
platform-provided stable callback URL that external services should use.
|
|
216
|
+
|
|
217
|
+
Examples:
|
|
218
|
+
$ assistant platform callback-routes register --path webhooks/telegram --type telegram --json
|
|
219
|
+
$ assistant platform callback-routes register --path webhooks/twilio/voice --type twilio_voice --json`,
|
|
220
|
+
)
|
|
221
|
+
.action(async (opts: { path: string; type: string }, cmd: Command) => {
|
|
222
|
+
try {
|
|
223
|
+
const context = await resolvePlatformCallbackRegistrationContext();
|
|
224
|
+
if (!context.enabled) {
|
|
225
|
+
writeOutput(cmd, {
|
|
226
|
+
ok: false,
|
|
227
|
+
error:
|
|
228
|
+
"Platform callbacks not available — missing containerized platform registration context",
|
|
229
|
+
});
|
|
230
|
+
process.exitCode = 1;
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const callbackUrl = await registerCallbackRoute(opts.path, opts.type);
|
|
235
|
+
|
|
236
|
+
writeOutput(cmd, {
|
|
237
|
+
ok: true,
|
|
238
|
+
callbackUrl,
|
|
239
|
+
callbackPath: opts.path,
|
|
240
|
+
type: opts.type,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
if (!shouldOutputJson(cmd)) {
|
|
244
|
+
log.info(`Callback route registered: ${callbackUrl}`);
|
|
245
|
+
}
|
|
246
|
+
} catch (err) {
|
|
247
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
248
|
+
writeOutput(cmd, { ok: false, error: message });
|
|
249
|
+
process.exitCode = 1;
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
}
|
|
@@ -142,7 +142,7 @@ Examples:
|
|
|
142
142
|
"after",
|
|
143
143
|
`
|
|
144
144
|
Arguments:
|
|
145
|
-
id The sequence ID (e.g. seq_abc123)
|
|
145
|
+
id The sequence ID (e.g. seq_abc123). Run 'assistant sequence list' to find IDs.
|
|
146
146
|
|
|
147
147
|
Returns full sequence details: name, status, channel, description, exit-on-reply
|
|
148
148
|
setting, all steps with delay and approval configuration, and enrollment
|
|
@@ -215,7 +215,7 @@ Examples:
|
|
|
215
215
|
"after",
|
|
216
216
|
`
|
|
217
217
|
Arguments:
|
|
218
|
-
id The sequence ID to pause (e.g. seq_abc123)
|
|
218
|
+
id The sequence ID to pause (e.g. seq_abc123). Run 'assistant sequence list' to find IDs.
|
|
219
219
|
|
|
220
220
|
Pauses a sequence, halting all scheduled step deliveries. Existing active
|
|
221
221
|
enrollments remain in their current state but no new steps will be sent
|
|
@@ -246,7 +246,7 @@ Examples:
|
|
|
246
246
|
"after",
|
|
247
247
|
`
|
|
248
248
|
Arguments:
|
|
249
|
-
id The sequence ID to resume (e.g. seq_abc123)
|
|
249
|
+
id The sequence ID to resume (e.g. seq_abc123). Run 'assistant sequence list' to find IDs.
|
|
250
250
|
|
|
251
251
|
Resumes a paused sequence, re-enabling scheduled step deliveries for all
|
|
252
252
|
active enrollments. No-op if the sequence is already active.
|
|
@@ -276,7 +276,8 @@ Examples:
|
|
|
276
276
|
"after",
|
|
277
277
|
`
|
|
278
278
|
Arguments:
|
|
279
|
-
enrollmentId The enrollment ID to cancel (e.g. enr_xyz789)
|
|
279
|
+
enrollmentId The enrollment ID to cancel (e.g. enr_xyz789). Run 'assistant sequence get <id>'
|
|
280
|
+
to see enrollment IDs for a sequence.
|
|
280
281
|
|
|
281
282
|
Immediately cancels a specific enrollment, stopping all future step
|
|
282
283
|
deliveries for that contact in this sequence. The enrollment status
|
|
@@ -101,6 +101,19 @@ export function registerShotgunCommand(program: Command): void {
|
|
|
101
101
|
.command("shotgun")
|
|
102
102
|
.description("Start and monitor screen-watch (shotgun) sessions via IPC");
|
|
103
103
|
|
|
104
|
+
shotgun.addHelpText(
|
|
105
|
+
"after",
|
|
106
|
+
`
|
|
107
|
+
Screen-watch sessions capture periodic screenshots and feed them to the
|
|
108
|
+
assistant for observation. The CLI communicates with the running assistant
|
|
109
|
+
via IPC signal files — the assistant must be running for these commands
|
|
110
|
+
to work.
|
|
111
|
+
|
|
112
|
+
Examples:
|
|
113
|
+
$ assistant shotgun start --duration 600 --focus "browsing workflow"
|
|
114
|
+
$ assistant shotgun status <watchId>`,
|
|
115
|
+
);
|
|
116
|
+
|
|
104
117
|
shotgun
|
|
105
118
|
.command("start")
|
|
106
119
|
.description("Start a new screen-watch session")
|
|
@@ -206,6 +219,9 @@ Examples:
|
|
|
206
219
|
.addHelpText(
|
|
207
220
|
"after",
|
|
208
221
|
`
|
|
222
|
+
Arguments:
|
|
223
|
+
watchId The watch session ID returned by 'assistant shotgun start'.
|
|
224
|
+
|
|
209
225
|
Queries the status of an existing screen-watch session by watchId.
|
|
210
226
|
|
|
211
227
|
Output (JSON): { ok, watchId, conversationId, status }
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
1
4
|
import type { Command } from "commander";
|
|
2
5
|
|
|
3
6
|
import type { CatalogSkill } from "../../skills/catalog-install.js";
|
|
@@ -8,7 +11,11 @@ import {
|
|
|
8
11
|
readLocalCatalog,
|
|
9
12
|
uninstallSkillLocally,
|
|
10
13
|
} from "../../skills/catalog-install.js";
|
|
11
|
-
import
|
|
14
|
+
import { filterByQuery } from "../../skills/catalog-search.js";
|
|
15
|
+
import type {
|
|
16
|
+
AuditResponse,
|
|
17
|
+
SkillsShSearchResult,
|
|
18
|
+
} from "../../skills/skillssh-registry.js";
|
|
12
19
|
import {
|
|
13
20
|
fetchSkillAudits,
|
|
14
21
|
formatAuditBadges,
|
|
@@ -16,6 +23,7 @@ import {
|
|
|
16
23
|
resolveSkillSource,
|
|
17
24
|
searchSkillsRegistry,
|
|
18
25
|
} from "../../skills/skillssh-registry.js";
|
|
26
|
+
import { getWorkspaceSkillsDir } from "../../util/platform.js";
|
|
19
27
|
import { log } from "../logger.js";
|
|
20
28
|
|
|
21
29
|
// ---------------------------------------------------------------------------
|
|
@@ -49,6 +57,16 @@ Examples:
|
|
|
49
57
|
.command("list")
|
|
50
58
|
.description("List available catalog skills")
|
|
51
59
|
.option("--json", "Machine-readable JSON output")
|
|
60
|
+
.addHelpText(
|
|
61
|
+
"after",
|
|
62
|
+
`
|
|
63
|
+
Lists all skills available in the Vellum catalog with their ID, name,
|
|
64
|
+
description, and dependency information.
|
|
65
|
+
|
|
66
|
+
Examples:
|
|
67
|
+
$ assistant skills list
|
|
68
|
+
$ assistant skills list --json`,
|
|
69
|
+
)
|
|
52
70
|
.action(async (opts: { json?: boolean }) => {
|
|
53
71
|
try {
|
|
54
72
|
// In dev mode, use the local catalog as the source of truth
|
|
@@ -93,20 +111,20 @@ Examples:
|
|
|
93
111
|
|
|
94
112
|
skills
|
|
95
113
|
.command("search <query>")
|
|
96
|
-
.description("Search the skills.sh community registry")
|
|
97
|
-
.option("--limit <n>", "Maximum number of results", "10")
|
|
114
|
+
.description("Search the Vellum catalog and skills.sh community registry")
|
|
115
|
+
.option("--limit <n>", "Maximum number of community results", "10")
|
|
98
116
|
.option("--json", "Machine-readable JSON output")
|
|
99
117
|
.addHelpText(
|
|
100
118
|
"after",
|
|
101
119
|
`
|
|
102
120
|
Arguments:
|
|
103
121
|
query Free-text search term matched against skill names, descriptions,
|
|
104
|
-
and tags
|
|
122
|
+
and tags. Searches the Vellum catalog first, then the skills.sh
|
|
123
|
+
community registry.
|
|
105
124
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
security data.
|
|
125
|
+
Displays results from both sources with clear labels. When a skill ID
|
|
126
|
+
exists in both the Vellum catalog and the community registry, a conflict
|
|
127
|
+
note is shown with guidance on which install command to use.
|
|
110
128
|
|
|
111
129
|
Examples:
|
|
112
130
|
$ assistant skills search react
|
|
@@ -118,36 +136,80 @@ Examples:
|
|
|
118
136
|
const limit = parseInt(opts.limit, 10) || 10;
|
|
119
137
|
|
|
120
138
|
try {
|
|
121
|
-
|
|
139
|
+
// ── Vellum catalog search ────────────────────────────────────
|
|
140
|
+
const repoSkillsDir = getRepoSkillsDir();
|
|
141
|
+
let catalog: CatalogSkill[];
|
|
142
|
+
if (repoSkillsDir) {
|
|
143
|
+
catalog = readLocalCatalog(repoSkillsDir);
|
|
144
|
+
} else {
|
|
145
|
+
try {
|
|
146
|
+
catalog = await fetchCatalog();
|
|
147
|
+
} catch {
|
|
148
|
+
catalog = [];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const catalogMatches = filterByQuery(catalog, query, [
|
|
153
|
+
(s) => s.id,
|
|
154
|
+
(s) => s.name,
|
|
155
|
+
(s) => s.description,
|
|
156
|
+
]);
|
|
157
|
+
|
|
158
|
+
// ── Community registry search (non-fatal on failure) ─────────
|
|
159
|
+
let registryResults: SkillsShSearchResult[] = [];
|
|
160
|
+
let registryError: string | undefined;
|
|
161
|
+
try {
|
|
162
|
+
registryResults = await searchSkillsRegistry(query, limit);
|
|
163
|
+
} catch (err) {
|
|
164
|
+
registryError = err instanceof Error ? err.message : String(err);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ── Conflict detection ───────────────────────────────────────
|
|
168
|
+
const catalogIds = new Set(catalogMatches.map((s) => s.id));
|
|
169
|
+
const conflictIds = new Set(
|
|
170
|
+
registryResults
|
|
171
|
+
.filter((r) => catalogIds.has(r.skillId))
|
|
172
|
+
.map((r) => r.skillId),
|
|
173
|
+
);
|
|
122
174
|
|
|
123
|
-
if (
|
|
175
|
+
if (catalogMatches.length === 0 && registryResults.length === 0) {
|
|
124
176
|
if (json) {
|
|
125
|
-
console.log(
|
|
177
|
+
console.log(
|
|
178
|
+
JSON.stringify({
|
|
179
|
+
ok: true,
|
|
180
|
+
catalog: [],
|
|
181
|
+
community: [],
|
|
182
|
+
audits: {},
|
|
183
|
+
...(registryError ? { registryError } : {}),
|
|
184
|
+
}),
|
|
185
|
+
);
|
|
126
186
|
} else {
|
|
127
187
|
log.info(`No skills found for "${query}".`);
|
|
188
|
+
if (registryError) {
|
|
189
|
+
log.warn(`(skills.sh registry unavailable: ${registryError})`);
|
|
190
|
+
}
|
|
128
191
|
}
|
|
129
192
|
return;
|
|
130
193
|
}
|
|
131
194
|
|
|
132
|
-
//
|
|
133
|
-
const sourceToSlugs = new Map<string, string[]>();
|
|
134
|
-
for (const r of results) {
|
|
135
|
-
const slugs = sourceToSlugs.get(r.source) ?? [];
|
|
136
|
-
slugs.push(r.skillId);
|
|
137
|
-
sourceToSlugs.set(r.source, slugs);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Fetch audits for each unique source, keyed by source/skillId
|
|
141
|
-
// to avoid collisions when different sources share the same slug.
|
|
195
|
+
// ── Fetch audits for community results ───────────────────────
|
|
142
196
|
const allAudits: AuditResponse = {};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
197
|
+
if (registryResults.length > 0) {
|
|
198
|
+
const sourceToSlugs = new Map<string, string[]>();
|
|
199
|
+
for (const r of registryResults) {
|
|
200
|
+
const slugs = sourceToSlugs.get(r.source) ?? [];
|
|
201
|
+
slugs.push(r.skillId);
|
|
202
|
+
sourceToSlugs.set(r.source, slugs);
|
|
203
|
+
}
|
|
204
|
+
for (const [source, slugs] of sourceToSlugs) {
|
|
205
|
+
try {
|
|
206
|
+
const audits = await fetchSkillAudits(source, slugs);
|
|
207
|
+
for (const [skillId, auditData] of Object.entries(audits)) {
|
|
208
|
+
allAudits[`${source}/${skillId}`] = auditData;
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
// Audit fetch failures are non-fatal
|
|
148
212
|
}
|
|
149
|
-
} catch {
|
|
150
|
-
// Audit fetch failures are non-fatal; display results without audits
|
|
151
213
|
}
|
|
152
214
|
}
|
|
153
215
|
|
|
@@ -155,26 +217,68 @@ Examples:
|
|
|
155
217
|
console.log(
|
|
156
218
|
JSON.stringify({
|
|
157
219
|
ok: true,
|
|
158
|
-
|
|
220
|
+
catalog: catalogMatches,
|
|
221
|
+
community: registryResults,
|
|
159
222
|
audits: allAudits,
|
|
223
|
+
...(registryError ? { registryError } : {}),
|
|
160
224
|
}),
|
|
161
225
|
);
|
|
162
226
|
return;
|
|
163
227
|
}
|
|
164
228
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
229
|
+
// ── Installed-state detection ─────────────────────────────────
|
|
230
|
+
const skillsDir = getWorkspaceSkillsDir();
|
|
231
|
+
const isInstalled = (id: string) =>
|
|
232
|
+
existsSync(join(skillsDir, id, "SKILL.md"));
|
|
233
|
+
|
|
234
|
+
// ── Display catalog results ──────────────────────────────────
|
|
235
|
+
if (catalogMatches.length > 0) {
|
|
236
|
+
log.info(`Vellum catalog (${catalogMatches.length}):\n`);
|
|
237
|
+
for (const s of catalogMatches) {
|
|
238
|
+
const emoji = s.emoji ? `${s.emoji} ` : "";
|
|
239
|
+
const installed = isInstalled(s.id);
|
|
240
|
+
const badge = installed ? " [installed]" : "";
|
|
241
|
+
log.info(` ${emoji}${s.name}${badge}`);
|
|
242
|
+
if (s.name !== s.id) {
|
|
243
|
+
log.info(` ID: ${s.id}`);
|
|
244
|
+
}
|
|
245
|
+
log.info(` Description: ${s.description}`);
|
|
246
|
+
log.info(` Install: assistant skills install ${s.id}`);
|
|
247
|
+
if (conflictIds.has(s.id)) {
|
|
248
|
+
log.info(` NOTE: Also found in community registry`);
|
|
249
|
+
}
|
|
250
|
+
log.info("");
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ── Display community results ────────────────────────────────
|
|
255
|
+
if (registryResults.length > 0) {
|
|
256
|
+
log.info(`Community registry (${registryResults.length}):\n`);
|
|
257
|
+
for (const r of registryResults) {
|
|
258
|
+
const installed = isInstalled(r.skillId);
|
|
259
|
+
const badge = installed ? " [installed]" : "";
|
|
260
|
+
log.info(` ${r.name}${badge}`);
|
|
261
|
+
if (r.name !== r.skillId) {
|
|
262
|
+
log.info(` ID: ${r.skillId}`);
|
|
263
|
+
}
|
|
264
|
+
log.info(` Source: ${r.source}`);
|
|
265
|
+
log.info(` Installs: ${r.installs}`);
|
|
266
|
+
const auditData = allAudits[`${r.source}/${r.skillId}`];
|
|
267
|
+
if (auditData) {
|
|
268
|
+
log.info(` ${formatAuditBadges(auditData)}`);
|
|
269
|
+
} else {
|
|
270
|
+
log.info(" Security: no audit data");
|
|
271
|
+
}
|
|
272
|
+
log.info(
|
|
273
|
+
` Install: assistant skills add ${r.source}@${r.skillId}`,
|
|
274
|
+
);
|
|
275
|
+
if (conflictIds.has(r.skillId)) {
|
|
276
|
+
log.info(` NOTE: Conflicts with Vellum catalog skill`);
|
|
277
|
+
}
|
|
278
|
+
log.info("");
|
|
176
279
|
}
|
|
177
|
-
|
|
280
|
+
} else if (registryError) {
|
|
281
|
+
log.warn(`\n(skills.sh registry unavailable: ${registryError})`);
|
|
178
282
|
}
|
|
179
283
|
} catch (err) {
|
|
180
284
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -192,6 +296,21 @@ Examples:
|
|
|
192
296
|
.description("Install a skill from the catalog")
|
|
193
297
|
.option("--overwrite", "Replace an already installed skill")
|
|
194
298
|
.option("--json", "Machine-readable JSON output")
|
|
299
|
+
.addHelpText(
|
|
300
|
+
"after",
|
|
301
|
+
`
|
|
302
|
+
Arguments:
|
|
303
|
+
skill-id Skill identifier from the Vellum catalog. Run 'assistant skills list'
|
|
304
|
+
to see available IDs. For community skills, use 'assistant skills add'.
|
|
305
|
+
|
|
306
|
+
Downloads and installs the skill into the workspace skills directory. If the
|
|
307
|
+
skill is already installed, use --overwrite to replace it.
|
|
308
|
+
|
|
309
|
+
Examples:
|
|
310
|
+
$ assistant skills install weather
|
|
311
|
+
$ assistant skills install weather --overwrite
|
|
312
|
+
$ assistant skills install weather --json`,
|
|
313
|
+
)
|
|
195
314
|
.action(
|
|
196
315
|
async (
|
|
197
316
|
skillId: string,
|
|
@@ -244,6 +363,19 @@ Examples:
|
|
|
244
363
|
.command("uninstall <skill-id>")
|
|
245
364
|
.description("Uninstall a previously installed skill")
|
|
246
365
|
.option("--json", "Machine-readable JSON output")
|
|
366
|
+
.addHelpText(
|
|
367
|
+
"after",
|
|
368
|
+
`
|
|
369
|
+
Arguments:
|
|
370
|
+
skill-id Skill identifier to remove. Run 'assistant skills list' to see
|
|
371
|
+
installed skills.
|
|
372
|
+
|
|
373
|
+
Removes the skill directory from the workspace. This action cannot be undone.
|
|
374
|
+
|
|
375
|
+
Examples:
|
|
376
|
+
$ assistant skills uninstall weather
|
|
377
|
+
$ assistant skills uninstall weather --json`,
|
|
378
|
+
)
|
|
247
379
|
.action(async (skillId: string, opts: { json?: boolean }) => {
|
|
248
380
|
const json = opts.json ?? false;
|
|
249
381
|
|
|
@@ -178,11 +178,6 @@ Reads from the local LLM usage event ledger (llm_usage_events table) to
|
|
|
178
178
|
display token consumption and cost data. Operates on the local SQLite
|
|
179
179
|
database directly — does not require the assistant to be running.
|
|
180
180
|
|
|
181
|
-
Subcommands:
|
|
182
|
-
totals Aggregate totals for a time range (default when no subcommand given)
|
|
183
|
-
daily Per-day token and cost breakdown
|
|
184
|
-
breakdown Grouped breakdown by actor, provider, or model
|
|
185
|
-
|
|
186
181
|
Time range can be specified with --range presets (today, week, month, all)
|
|
187
182
|
or explicit --from / --to epoch-millisecond timestamps.
|
|
188
183
|
|
|
@@ -285,12 +280,11 @@ Examples:
|
|
|
285
280
|
.addHelpText(
|
|
286
281
|
"after",
|
|
287
282
|
`
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
model Groups by model name (claude-sonnet-4-20250514, etc.)
|
|
283
|
+
Grouping dimensions:
|
|
284
|
+
actor Groups by the subsystem that made the call (main_agent,
|
|
285
|
+
title_generator, etc.)
|
|
286
|
+
provider Groups by LLM provider (anthropic, openai, etc.)
|
|
287
|
+
model Groups by model name (claude-sonnet-4-20250514, etc.)
|
|
294
288
|
|
|
295
289
|
Shows one row per group with input/output tokens, estimated cost, and
|
|
296
290
|
call count. Rows are sorted by cost descending.
|