@vellumai/assistant 0.4.48 → 0.4.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +26 -35
- package/README.md +5 -26
- package/docs/architecture/integrations.md +45 -41
- package/docs/architecture/keychain-broker.md +3 -3
- package/docs/architecture/memory.md +180 -119
- package/docs/runbook-trusted-contacts.md +3 -8
- package/hook-templates/debug-prompt-logger/hook.json +1 -1
- package/hook-templates/debug-prompt-logger/run.sh +1 -3
- package/package.json +2 -2
- package/src/__tests__/actor-token-service.test.ts +0 -1
- package/src/__tests__/agent-loop.test.ts +3 -1
- package/src/__tests__/anthropic-provider.test.ts +249 -2
- package/src/__tests__/approval-cascade.test.ts +796 -0
- package/src/__tests__/approval-primitive.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +4 -0
- package/src/__tests__/assistant-attachments.test.ts +12 -34
- package/src/__tests__/assistant-feature-flag-guard.test.ts +0 -23
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/canonical-guardian-store.test.ts +95 -0
- package/src/__tests__/channel-guardian.test.ts +0 -2
- package/src/__tests__/channel-readiness-routes.test.ts +15 -6
- package/src/__tests__/channel-readiness-service.test.ts +10 -9
- package/src/__tests__/checker.test.ts +13 -20
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-tools.test.ts +2 -19
- package/src/__tests__/config-schema.test.ts +1 -68
- package/src/__tests__/config-watcher.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-image-dimensions.test.ts +332 -0
- package/src/__tests__/context-memory-e2e.test.ts +11 -100
- package/src/__tests__/context-token-estimator.test.ts +196 -13
- package/src/__tests__/conversation-attention-store.test.ts +0 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +152 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -0
- package/src/__tests__/credential-metadata-store.test.ts +64 -73
- package/src/__tests__/credential-security-e2e.test.ts +1 -0
- package/src/__tests__/credential-security-invariants.test.ts +13 -7
- package/src/__tests__/credential-vault-unit.test.ts +284 -49
- package/src/__tests__/credential-vault.test.ts +150 -16
- package/src/__tests__/credentials-cli.test.ts +71 -0
- package/src/__tests__/cu-unified-flow.test.ts +532 -0
- package/src/__tests__/date-context.test.ts +93 -77
- package/src/__tests__/deterministic-verification-control-plane.test.ts +64 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/ephemeral-permissions.test.ts +3 -3
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +93 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
- package/src/__tests__/heartbeat-service.test.ts +0 -1
- package/src/__tests__/history-repair.test.ts +245 -0
- package/src/__tests__/host-cu-proxy.test.ts +791 -0
- package/src/__tests__/host-shell-tool.test.ts +27 -15
- package/src/__tests__/http-user-message-parity.test.ts +2 -0
- package/src/__tests__/ingress-url-consistency.test.ts +14 -21
- package/src/__tests__/integration-status.test.ts +32 -51
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/invite-redemption-service.test.ts +65 -1
- package/src/__tests__/invite-routes-http.test.ts +10 -9
- package/src/__tests__/keychain-broker-client.test.ts +14 -46
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +56 -18
- package/src/__tests__/memory-lifecycle-e2e.test.ts +244 -387
- package/src/__tests__/memory-recall-quality.test.ts +244 -407
- package/src/__tests__/memory-regressions.experimental.test.ts +126 -101
- package/src/__tests__/memory-regressions.test.ts +477 -2841
- package/src/__tests__/memory-retrieval.benchmark.test.ts +33 -150
- package/src/__tests__/memory-upsert-concurrency.test.ts +5 -244
- package/src/__tests__/mime-builder.test.ts +28 -0
- package/src/__tests__/native-web-search.test.ts +1 -0
- package/src/__tests__/notification-routing-intent.test.ts +0 -1
- package/src/__tests__/oauth-cli.test.ts +941 -15
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
- package/src/__tests__/oauth-scope-policy.test.ts +4 -6
- package/src/__tests__/oauth-store.test.ts +870 -0
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
- package/src/__tests__/provider-error-scenarios.test.ts +0 -1
- package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
- package/src/__tests__/public-ingress-urls.test.ts +15 -21
- package/src/__tests__/qdrant-collection-migration.test.ts +53 -8
- package/src/__tests__/recording-handler.test.ts +3 -4
- package/src/__tests__/registry.test.ts +2 -3
- package/src/__tests__/relay-server.test.ts +46 -1
- package/src/__tests__/runtime-events-sse.test.ts +55 -7
- package/src/__tests__/schedule-store.test.ts +0 -1
- package/src/__tests__/schedule-tools.test.ts +32 -0
- package/src/__tests__/scheduler-recurrence.test.ts +0 -1
- package/src/__tests__/scoped-approval-grants.test.ts +0 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
- package/src/__tests__/script-proxy-certs.test.ts +1 -1
- package/src/__tests__/secret-ingress-handler.test.ts +0 -1
- package/src/__tests__/secret-onetime-send.test.ts +1 -0
- package/src/__tests__/secure-keys.test.ts +7 -2
- package/src/__tests__/send-endpoint-busy.test.ts +24 -6
- package/src/__tests__/sequence-store.test.ts +0 -1
- package/src/__tests__/session-abort-tool-results.test.ts +1 -14
- package/src/__tests__/session-agent-loop-overflow.test.ts +1583 -0
- package/src/__tests__/session-agent-loop.test.ts +19 -15
- package/src/__tests__/session-confirmation-signals.test.ts +1 -15
- package/src/__tests__/session-error.test.ts +124 -2
- package/src/__tests__/session-history-web-search.test.ts +918 -0
- package/src/__tests__/session-init.benchmark.test.ts +4 -5
- package/src/__tests__/session-pre-run-repair.test.ts +1 -14
- package/src/__tests__/session-provider-retry-repair.test.ts +25 -28
- package/src/__tests__/session-queue.test.ts +37 -27
- package/src/__tests__/session-runtime-assembly.test.ts +54 -0
- package/src/__tests__/session-slash-known.test.ts +1 -15
- package/src/__tests__/session-slash-queue.test.ts +1 -15
- package/src/__tests__/session-slash-unknown.test.ts +1 -15
- package/src/__tests__/session-workspace-cache-state.test.ts +3 -33
- package/src/__tests__/session-workspace-injection.test.ts +3 -37
- package/src/__tests__/session-workspace-tool-tracking.test.ts +3 -37
- package/src/__tests__/skill-include-graph.test.ts +66 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
- package/src/__tests__/skill-load-tool.test.ts +149 -1
- package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
- package/src/__tests__/skills-install-extract.test.ts +93 -0
- package/src/__tests__/skills-uninstall.test.ts +1 -1
- package/src/__tests__/skills.test.ts +3 -3
- package/src/__tests__/skillssh-registry.test.ts +451 -0
- package/src/__tests__/slack-channel-config.test.ts +67 -3
- package/src/__tests__/slack-share-routes.test.ts +17 -19
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
- package/src/__tests__/terminal-tools.test.ts +4 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/tool-approval-handler.test.ts +0 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
- package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
- package/src/__tests__/trust-store.test.ts +7 -13
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +0 -16
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
- package/src/__tests__/voice-invite-redemption.test.ts +32 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/agent/ax-tree-compaction.test.ts +286 -0
- package/src/agent/loop.ts +104 -131
- package/src/approvals/AGENTS.md +1 -1
- package/src/approvals/guardian-request-resolvers.ts +14 -2
- package/src/bundler/compiler-tools.ts +66 -2
- package/src/calls/call-domain.ts +133 -6
- package/src/calls/call-store.ts +6 -0
- package/src/calls/relay-server.ts +52 -18
- package/src/calls/relay-setup-router.ts +17 -1
- package/src/calls/twilio-config.ts +3 -8
- package/src/calls/twilio-routes.ts +1 -2
- package/src/calls/types.ts +3 -1
- package/src/calls/voice-ingress-preflight.ts +1 -1
- package/src/cli/commands/browser-relay.ts +18 -12
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/credentials.ts +101 -15
- package/src/cli/commands/doctor.ts +4 -3
- package/src/cli/commands/mcp.ts +46 -59
- package/src/cli/commands/memory.ts +16 -165
- package/src/cli/commands/oauth/apps.ts +284 -0
- package/src/cli/commands/oauth/connections.ts +633 -0
- package/src/cli/commands/oauth/index.ts +52 -0
- package/src/cli/commands/oauth/providers.ts +256 -0
- package/src/cli/commands/sessions.ts +5 -2
- package/src/cli/commands/skills.ts +177 -339
- package/src/cli/http-client.ts +0 -20
- package/src/cli/main-screen.tsx +2 -2
- package/src/cli/program.ts +6 -11
- package/src/cli/reference.ts +1 -3
- package/src/cli.ts +4 -10
- package/src/config/assistant-feature-flags.ts +0 -3
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
- package/src/config/bundled-skills/computer-use/TOOLS.json +23 -5
- package/src/config/bundled-skills/computer-use/tools/{computer-use-request-control.ts → computer-use-observe.ts} +1 -5
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +21 -16
- package/src/config/bundled-skills/messaging/tools/shared.ts +1 -4
- package/src/config/bundled-skills/settings/SKILL.md +1 -1
- package/src/config/bundled-skills/settings/TOOLS.json +2 -8
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
- package/src/config/bundled-tool-registry.ts +2 -5
- package/src/config/env-registry.ts +14 -83
- package/src/config/env.ts +11 -50
- package/src/config/feature-flag-registry.json +16 -16
- package/src/config/loader.ts +0 -6
- package/src/config/schema.ts +4 -13
- package/src/config/schemas/memory-lifecycle.ts +0 -9
- package/src/config/schemas/memory-processing.ts +0 -180
- package/src/config/schemas/memory-retrieval.ts +32 -104
- package/src/config/schemas/memory.ts +0 -10
- package/src/config/skills.ts +21 -2
- package/src/config/types.ts +0 -4
- package/src/context/image-dimensions.ts +229 -0
- package/src/context/token-estimator.ts +75 -12
- package/src/context/window-manager.ts +53 -11
- package/src/daemon/assistant-attachments.ts +1 -13
- package/src/daemon/config-watcher.ts +61 -3
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/date-context.ts +114 -31
- package/src/daemon/handlers/config-ingress.ts +8 -33
- package/src/daemon/handlers/config-slack-channel.ts +49 -46
- package/src/daemon/handlers/config-telegram.ts +32 -16
- package/src/daemon/handlers/sessions.ts +27 -36
- package/src/daemon/handlers/shared.ts +0 -130
- package/src/daemon/handlers/skills.ts +20 -1
- package/src/daemon/history-repair.ts +72 -8
- package/src/daemon/host-cu-proxy.ts +430 -0
- package/src/daemon/lifecycle.ts +67 -71
- package/src/daemon/mcp-reload-service.ts +2 -2
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/computer-use.ts +1 -129
- package/src/daemon/message-types/host-cu.ts +19 -0
- package/src/daemon/message-types/memory.ts +4 -16
- package/src/daemon/message-types/messages.ts +4 -0
- package/src/daemon/message-types/sessions.ts +4 -0
- package/src/daemon/server.ts +25 -21
- package/src/daemon/session-agent-loop-handlers.ts +40 -0
- package/src/daemon/session-agent-loop.ts +334 -48
- package/src/daemon/session-attachments.ts +1 -2
- package/src/daemon/session-error.ts +89 -6
- package/src/daemon/session-history.ts +17 -7
- package/src/daemon/session-media-retry.ts +6 -2
- package/src/daemon/session-memory.ts +69 -149
- package/src/daemon/session-process.ts +10 -1
- package/src/daemon/session-runtime-assembly.ts +49 -19
- package/src/daemon/session-slash.ts +1 -1
- package/src/daemon/session-surfaces.ts +43 -28
- package/src/daemon/session-tool-setup.ts +9 -10
- package/src/daemon/session.ts +150 -17
- package/src/daemon/tool-side-effects.ts +2 -8
- package/src/daemon/watch-handler.ts +2 -2
- package/src/events/tool-metrics-listener.ts +2 -2
- package/src/hooks/manager.ts +1 -4
- package/src/inbound/public-ingress-urls.ts +7 -7
- package/src/instrument.ts +61 -1
- package/src/logfire.ts +16 -5
- package/src/memory/admin.ts +2 -191
- package/src/memory/canonical-guardian-store.ts +38 -2
- package/src/memory/conversation-crud.ts +0 -33
- package/src/memory/conversation-key-store.ts +21 -0
- package/src/memory/conversation-queries.ts +22 -3
- package/src/memory/db-init.ts +32 -0
- package/src/memory/embedding-backend.ts +84 -8
- package/src/memory/embedding-types.ts +9 -1
- package/src/memory/indexer.ts +7 -46
- package/src/memory/items-extractor.ts +274 -76
- package/src/memory/job-handlers/backfill.ts +2 -127
- package/src/memory/job-handlers/cleanup.ts +2 -16
- package/src/memory/job-handlers/extraction.ts +2 -138
- package/src/memory/job-handlers/index-maintenance.ts +1 -6
- package/src/memory/job-handlers/summarization.ts +3 -148
- package/src/memory/job-utils.ts +21 -59
- package/src/memory/jobs-store.ts +1 -159
- package/src/memory/jobs-worker.ts +9 -52
- package/src/memory/migrations/104-core-indexes.ts +3 -3
- package/src/memory/migrations/149-oauth-tables.ts +62 -0
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +98 -0
- package/src/memory/migrations/151-oauth-providers-ping-url.ts +11 -0
- package/src/memory/migrations/152-memory-item-supersession.ts +44 -0
- package/src/memory/migrations/153-drop-entity-tables.ts +15 -0
- package/src/memory/migrations/154-drop-fts.ts +20 -0
- package/src/memory/migrations/155-drop-conflicts.ts +7 -0
- package/src/memory/migrations/156-call-session-invite-metadata.ts +24 -0
- package/src/memory/migrations/index.ts +8 -0
- package/src/memory/qdrant-client.ts +148 -51
- package/src/memory/raw-query.ts +1 -1
- package/src/memory/retriever.test.ts +294 -273
- package/src/memory/retriever.ts +421 -645
- package/src/memory/schema/calls.ts +2 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/memory-core.ts +3 -48
- package/src/memory/schema/oauth.ts +67 -0
- package/src/memory/search/formatting.ts +263 -176
- package/src/memory/search/lexical.ts +1 -254
- package/src/memory/search/ranking.ts +0 -455
- package/src/memory/search/semantic.ts +100 -14
- package/src/memory/search/staleness.ts +47 -0
- package/src/memory/search/tier-classifier.ts +21 -0
- package/src/memory/search/types.ts +15 -77
- package/src/memory/task-memory-cleanup.ts +4 -6
- package/src/messaging/provider.ts +4 -4
- package/src/messaging/providers/gmail/client.ts +82 -2
- package/src/messaging/providers/gmail/mime-builder.ts +17 -7
- package/src/messaging/providers/gmail/people-client.ts +10 -10
- package/src/messaging/providers/telegram-bot/adapter.ts +17 -17
- package/src/messaging/providers/whatsapp/adapter.ts +11 -8
- package/src/messaging/registry.ts +2 -32
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/signal.ts +4 -5
- package/src/oauth/byo-connection.test.ts +133 -25
- package/src/oauth/byo-connection.ts +22 -6
- package/src/oauth/connect-orchestrator.ts +113 -57
- package/src/oauth/connect-types.ts +17 -23
- package/src/oauth/connection-resolver.ts +35 -11
- package/src/oauth/connection.ts +1 -1
- package/src/oauth/manual-token-connection.ts +104 -0
- package/src/oauth/oauth-store.ts +582 -0
- package/src/oauth/platform-connection.test.ts +29 -0
- package/src/oauth/platform-connection.ts +6 -5
- package/src/oauth/provider-behaviors.ts +124 -0
- package/src/oauth/scope-policy.ts +9 -2
- package/src/oauth/seed-providers.ts +167 -0
- package/src/oauth/token-persistence.ts +81 -77
- package/src/permissions/checker.ts +3 -3
- package/src/permissions/defaults.ts +1 -1
- package/src/permissions/prompter.ts +10 -1
- package/src/permissions/trust-store.ts +36 -1
- package/src/playbooks/playbook-compiler.ts +1 -1
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
- package/src/prompts/system-prompt.ts +46 -42
- package/src/providers/anthropic/client.ts +59 -20
- package/src/providers/retry.ts +1 -27
- package/src/providers/types.ts +7 -1
- package/src/runtime/AGENTS.md +9 -0
- package/src/runtime/auth/route-policy.ts +6 -6
- package/src/runtime/channel-reply-delivery.ts +0 -40
- package/src/runtime/gateway-client.ts +0 -7
- package/src/runtime/guardian-reply-router.ts +24 -22
- package/src/runtime/http-server.ts +10 -8
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/invite-redemption-service.ts +19 -1
- package/src/runtime/invite-service.ts +25 -0
- package/src/runtime/middleware/twilio-validation.ts +1 -11
- package/src/runtime/pending-interactions.ts +14 -12
- package/src/runtime/routes/brain-graph-routes.ts +10 -90
- package/src/runtime/routes/channel-delivery-routes.ts +0 -1
- package/src/runtime/routes/conversation-routes.ts +81 -19
- package/src/runtime/routes/events-routes.ts +21 -11
- package/src/runtime/routes/host-cu-routes.ts +97 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
- package/src/runtime/routes/integrations/slack/share.ts +6 -7
- package/src/runtime/routes/log-export-routes.ts +126 -8
- package/src/runtime/routes/memory-item-routes.test.ts +754 -0
- package/src/runtime/routes/memory-item-routes.ts +503 -0
- package/src/runtime/routes/session-management-routes.ts +3 -3
- package/src/runtime/routes/settings-routes.ts +55 -48
- package/src/runtime/routes/surface-action-routes.ts +1 -1
- package/src/runtime/routes/trust-rules-routes.ts +14 -0
- package/src/runtime/routes/watch-routes.ts +128 -0
- package/src/runtime/routes/workspace-routes.ts +2 -1
- package/src/schedule/integration-status.ts +10 -9
- package/src/security/credential-key.ts +0 -156
- package/src/security/keychain-broker-client.ts +22 -10
- package/src/security/oauth2.ts +1 -1
- package/src/security/secure-keys.ts +25 -3
- package/src/security/token-manager.ts +137 -64
- package/src/skills/catalog-install.ts +414 -0
- package/src/skills/include-graph.ts +32 -0
- package/src/skills/skillssh-registry.ts +503 -0
- package/src/telegram/bot-username.ts +2 -3
- package/src/tools/assets/search.ts +5 -1
- package/src/tools/browser/network-recorder.ts +1 -1
- package/src/tools/browser/network-recording-types.ts +1 -1
- package/src/tools/computer-use/definitions.ts +36 -11
- package/src/tools/computer-use/registry.ts +5 -6
- package/src/tools/credentials/broker.ts +1 -2
- package/src/tools/credentials/metadata-store.ts +17 -121
- package/src/tools/credentials/vault.ts +92 -167
- package/src/tools/memory/definitions.ts +4 -13
- package/src/tools/memory/handlers.test.ts +83 -103
- package/src/tools/memory/handlers.ts +50 -85
- package/src/tools/registry.ts +2 -7
- package/src/tools/schedule/create.ts +8 -1
- package/src/tools/schedule/update.ts +8 -1
- package/src/tools/skills/load.ts +85 -3
- package/src/tools/watch/watch-state.ts +0 -12
- package/src/util/logger.ts +7 -41
- package/src/util/platform.ts +9 -28
- package/src/watcher/providers/google-calendar.ts +2 -1
- package/src/__tests__/clarification-resolver.test.ts +0 -193
- package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
- package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
- package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
- package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
- package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
- package/src/__tests__/conflict-intent-tokenization.test.ts +0 -160
- package/src/__tests__/conflict-policy.test.ts +0 -269
- package/src/__tests__/conflict-store.test.ts +0 -372
- package/src/__tests__/contradiction-checker.test.ts +0 -361
- package/src/__tests__/entity-extractor.test.ts +0 -211
- package/src/__tests__/entity-search.test.ts +0 -1117
- package/src/__tests__/profile-compiler.test.ts +0 -392
- package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
- package/src/__tests__/session-conflict-gate.test.ts +0 -1228
- package/src/__tests__/session-profile-injection.test.ts +0 -557
- package/src/cli/commands/dev.ts +0 -129
- package/src/cli/commands/map.ts +0 -391
- package/src/cli/commands/oauth.ts +0 -77
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +0 -25
- package/src/config/bundled-skills/knowledge-graph/TOOLS.json +0 -66
- package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +0 -211
- package/src/daemon/computer-use-session.ts +0 -1026
- package/src/daemon/ride-shotgun-handler.ts +0 -569
- package/src/daemon/session-conflict-gate.ts +0 -167
- package/src/daemon/session-dynamic-profile.ts +0 -77
- package/src/memory/clarification-resolver.ts +0 -417
- package/src/memory/conflict-intent.ts +0 -205
- package/src/memory/conflict-policy.ts +0 -127
- package/src/memory/conflict-store.ts +0 -410
- package/src/memory/contradiction-checker.ts +0 -508
- package/src/memory/entity-extractor.ts +0 -535
- package/src/memory/format-recall.ts +0 -47
- package/src/memory/fts-reconciler.ts +0 -165
- package/src/memory/job-handlers/conflict.ts +0 -200
- package/src/memory/profile-compiler.ts +0 -195
- package/src/memory/recall-cache.ts +0 -117
- package/src/memory/search/entity.ts +0 -535
- package/src/memory/search/query-expansion.test.ts +0 -70
- package/src/memory/search/query-expansion.ts +0 -118
- package/src/oauth/provider-base-urls.ts +0 -21
- package/src/oauth/provider-profiles.ts +0 -192
- package/src/prompts/computer-use-prompt.ts +0 -98
- package/src/runtime/routes/computer-use-routes.ts +0 -641
- package/src/runtime/routes/mcp-routes.ts +0 -20
- package/src/runtime/telegram-streaming-delivery.test.ts +0 -729
- package/src/runtime/telegram-streaming-delivery.ts +0 -393
- package/src/tools/computer-use/request-computer-control.ts +0 -56
|
@@ -1,348 +1,22 @@
|
|
|
1
|
-
import { execSync } from "node:child_process";
|
|
2
|
-
import { randomUUID } from "node:crypto";
|
|
3
|
-
import {
|
|
4
|
-
cpSync,
|
|
5
|
-
existsSync,
|
|
6
|
-
mkdirSync,
|
|
7
|
-
readFileSync,
|
|
8
|
-
renameSync,
|
|
9
|
-
rmSync,
|
|
10
|
-
writeFileSync,
|
|
11
|
-
} from "node:fs";
|
|
12
|
-
import { homedir } from "node:os";
|
|
13
|
-
import { dirname, join } from "node:path";
|
|
14
|
-
import { gunzipSync } from "node:zlib";
|
|
15
|
-
|
|
16
1
|
import type { Command } from "commander";
|
|
17
2
|
|
|
3
|
+
import type { CatalogSkill } from "../../skills/catalog-install.js";
|
|
18
4
|
import {
|
|
19
|
-
getWorkspaceConfigPath,
|
|
20
|
-
getWorkspaceSkillsDir,
|
|
21
|
-
readPlatformToken,
|
|
22
|
-
} from "../../util/platform.js";
|
|
23
|
-
import { log } from "../logger.js";
|
|
24
|
-
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
// Path helpers
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
|
|
29
|
-
function getSkillsIndexPath(): string {
|
|
30
|
-
return join(getWorkspaceSkillsDir(), "SKILLS.md");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Resolve the repo-level skills/ directory when running in dev mode.
|
|
35
|
-
* Returns the path if VELLUM_DEV is set and the directory exists, or undefined.
|
|
36
|
-
*/
|
|
37
|
-
function getRepoSkillsDir(): string | undefined {
|
|
38
|
-
if (!process.env.VELLUM_DEV) return undefined;
|
|
39
|
-
|
|
40
|
-
// assistant/src/cli/commands/skills.ts -> ../../../../skills/
|
|
41
|
-
const candidate = join(import.meta.dir, "..", "..", "..", "..", "skills");
|
|
42
|
-
if (existsSync(join(candidate, "catalog.json"))) {
|
|
43
|
-
return candidate;
|
|
44
|
-
}
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Read skills from the repo-local catalog.json.
|
|
50
|
-
*/
|
|
51
|
-
function readLocalCatalog(repoSkillsDir: string): CatalogSkill[] {
|
|
52
|
-
try {
|
|
53
|
-
const raw = readFileSync(join(repoSkillsDir, "catalog.json"), "utf-8");
|
|
54
|
-
const manifest = JSON.parse(raw) as CatalogManifest;
|
|
55
|
-
if (!Array.isArray(manifest.skills)) return [];
|
|
56
|
-
return manifest.skills;
|
|
57
|
-
} catch {
|
|
58
|
-
return [];
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
|
-
// Platform API client
|
|
64
|
-
// ---------------------------------------------------------------------------
|
|
65
|
-
|
|
66
|
-
function getConfigPlatformUrl(): string | undefined {
|
|
67
|
-
try {
|
|
68
|
-
const configPath = getWorkspaceConfigPath();
|
|
69
|
-
if (!existsSync(configPath)) return undefined;
|
|
70
|
-
const raw = JSON.parse(readFileSync(configPath, "utf-8")) as Record<
|
|
71
|
-
string,
|
|
72
|
-
unknown
|
|
73
|
-
>;
|
|
74
|
-
const platform = raw.platform as Record<string, unknown> | undefined;
|
|
75
|
-
const baseUrl = platform?.baseUrl;
|
|
76
|
-
if (typeof baseUrl === "string" && baseUrl.trim()) return baseUrl.trim();
|
|
77
|
-
} catch {
|
|
78
|
-
// ignore
|
|
79
|
-
}
|
|
80
|
-
return undefined;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function getPlatformUrl(): string {
|
|
84
|
-
return (
|
|
85
|
-
process.env.VELLUM_ASSISTANT_PLATFORM_URL ??
|
|
86
|
-
getConfigPlatformUrl() ??
|
|
87
|
-
"https://platform.vellum.ai"
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function buildHeaders(): Record<string, string> {
|
|
92
|
-
const headers: Record<string, string> = {};
|
|
93
|
-
const token = readPlatformToken();
|
|
94
|
-
if (token) {
|
|
95
|
-
headers["X-Session-Token"] = token;
|
|
96
|
-
}
|
|
97
|
-
return headers;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// ---------------------------------------------------------------------------
|
|
101
|
-
// Types
|
|
102
|
-
// ---------------------------------------------------------------------------
|
|
103
|
-
|
|
104
|
-
interface CatalogSkill {
|
|
105
|
-
id: string;
|
|
106
|
-
name: string;
|
|
107
|
-
description: string;
|
|
108
|
-
emoji?: string;
|
|
109
|
-
includes?: string[];
|
|
110
|
-
version?: string;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
interface CatalogManifest {
|
|
114
|
-
version: number;
|
|
115
|
-
skills: CatalogSkill[];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// ---------------------------------------------------------------------------
|
|
119
|
-
// Catalog operations
|
|
120
|
-
// ---------------------------------------------------------------------------
|
|
121
|
-
|
|
122
|
-
async function fetchCatalog(): Promise<CatalogSkill[]> {
|
|
123
|
-
const url = `${getPlatformUrl()}/v1/skills/`;
|
|
124
|
-
const response = await fetch(url, {
|
|
125
|
-
headers: buildHeaders(),
|
|
126
|
-
signal: AbortSignal.timeout(10000),
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
if (!response.ok) {
|
|
130
|
-
throw new Error(
|
|
131
|
-
`Platform API error ${response.status}: ${response.statusText}`,
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const manifest = (await response.json()) as CatalogManifest;
|
|
136
|
-
if (!Array.isArray(manifest.skills)) {
|
|
137
|
-
throw new Error("Platform catalog has invalid skills array");
|
|
138
|
-
}
|
|
139
|
-
return manifest.skills;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Extract all files from a tar archive (uncompressed) into a directory.
|
|
144
|
-
* Returns true if a SKILL.md was found in the archive.
|
|
145
|
-
*/
|
|
146
|
-
function extractTarToDir(tarBuffer: Buffer, destDir: string): boolean {
|
|
147
|
-
let foundSkillMd = false;
|
|
148
|
-
let offset = 0;
|
|
149
|
-
while (offset + 512 <= tarBuffer.length) {
|
|
150
|
-
const header = tarBuffer.subarray(offset, offset + 512);
|
|
151
|
-
|
|
152
|
-
// End-of-archive (two consecutive zero blocks)
|
|
153
|
-
if (header.every((b) => b === 0)) break;
|
|
154
|
-
|
|
155
|
-
// Filename (bytes 0-99, null-terminated)
|
|
156
|
-
const nameEnd = header.indexOf(0, 0);
|
|
157
|
-
const name = header
|
|
158
|
-
.subarray(0, Math.min(nameEnd >= 0 ? nameEnd : 100, 100))
|
|
159
|
-
.toString("utf-8");
|
|
160
|
-
|
|
161
|
-
// File type (byte 156): '5' = directory, '0' or '\0' = regular file
|
|
162
|
-
const typeFlag = header[156];
|
|
163
|
-
|
|
164
|
-
// File size (bytes 124-135, octal)
|
|
165
|
-
const sizeStr = header.subarray(124, 136).toString("utf-8").trim();
|
|
166
|
-
const size = parseInt(sizeStr, 8) || 0;
|
|
167
|
-
|
|
168
|
-
offset += 512; // past header
|
|
169
|
-
|
|
170
|
-
// Skip directories and empty names
|
|
171
|
-
if (name && typeFlag !== 53 /* '5' */) {
|
|
172
|
-
// Prevent path traversal
|
|
173
|
-
const normalizedName = name.replace(/^\.\//, "");
|
|
174
|
-
if (!normalizedName.startsWith("..") && !normalizedName.includes("/..")) {
|
|
175
|
-
const destPath = join(destDir, normalizedName);
|
|
176
|
-
mkdirSync(dirname(destPath), { recursive: true });
|
|
177
|
-
writeFileSync(destPath, tarBuffer.subarray(offset, offset + size));
|
|
178
|
-
|
|
179
|
-
if (
|
|
180
|
-
normalizedName === "SKILL.md" ||
|
|
181
|
-
normalizedName.endsWith("/SKILL.md")
|
|
182
|
-
) {
|
|
183
|
-
foundSkillMd = true;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Skip to next header (data padded to 512 bytes)
|
|
189
|
-
offset += Math.ceil(size / 512) * 512;
|
|
190
|
-
}
|
|
191
|
-
return foundSkillMd;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
async function fetchAndExtractSkill(
|
|
195
|
-
skillId: string,
|
|
196
|
-
destDir: string,
|
|
197
|
-
): Promise<void> {
|
|
198
|
-
const url = `${getPlatformUrl()}/v1/skills/${encodeURIComponent(skillId)}/`;
|
|
199
|
-
const response = await fetch(url, {
|
|
200
|
-
headers: buildHeaders(),
|
|
201
|
-
signal: AbortSignal.timeout(15000),
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
if (!response.ok) {
|
|
205
|
-
throw new Error(
|
|
206
|
-
`Failed to fetch skill "${skillId}": HTTP ${response.status}`,
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const gzipBuffer = Buffer.from(await response.arrayBuffer());
|
|
211
|
-
const tarBuffer = gunzipSync(gzipBuffer);
|
|
212
|
-
const foundSkillMd = extractTarToDir(tarBuffer, destDir);
|
|
213
|
-
|
|
214
|
-
if (!foundSkillMd) {
|
|
215
|
-
throw new Error(`SKILL.md not found in archive for "${skillId}"`);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
// ---------------------------------------------------------------------------
|
|
220
|
-
// Managed skill installation
|
|
221
|
-
// ---------------------------------------------------------------------------
|
|
222
|
-
|
|
223
|
-
function atomicWriteFile(filePath: string, content: string): void {
|
|
224
|
-
const dir = dirname(filePath);
|
|
225
|
-
mkdirSync(dir, { recursive: true });
|
|
226
|
-
const tmpPath = join(dir, `.tmp-${randomUUID()}`);
|
|
227
|
-
writeFileSync(tmpPath, content, "utf-8");
|
|
228
|
-
renameSync(tmpPath, filePath);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
function upsertSkillsIndex(id: string): void {
|
|
232
|
-
const indexPath = getSkillsIndexPath();
|
|
233
|
-
let lines: string[] = [];
|
|
234
|
-
if (existsSync(indexPath)) {
|
|
235
|
-
lines = readFileSync(indexPath, "utf-8").split("\n");
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const escaped = id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
239
|
-
const pattern = new RegExp(`^[-*]\\s+(?:\`)?${escaped}(?:\`)?\\s*$`);
|
|
240
|
-
if (lines.some((line) => pattern.test(line))) return;
|
|
241
|
-
|
|
242
|
-
const nonEmpty = lines.filter((l) => l.trim());
|
|
243
|
-
nonEmpty.push(`- ${id}`);
|
|
244
|
-
const content = nonEmpty.join("\n");
|
|
245
|
-
atomicWriteFile(indexPath, content.endsWith("\n") ? content : content + "\n");
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
function removeSkillsIndexEntry(id: string): void {
|
|
249
|
-
const indexPath = getSkillsIndexPath();
|
|
250
|
-
if (!existsSync(indexPath)) return;
|
|
251
|
-
|
|
252
|
-
const lines = readFileSync(indexPath, "utf-8").split("\n");
|
|
253
|
-
const escaped = id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
254
|
-
const pattern = new RegExp(`^[-*]\\s+(?:\`)?${escaped}(?:\`)?\\s*$`);
|
|
255
|
-
const filtered = lines.filter((line) => !pattern.test(line));
|
|
256
|
-
|
|
257
|
-
// If nothing changed, skip the write
|
|
258
|
-
if (filtered.length === lines.length) return;
|
|
259
|
-
|
|
260
|
-
const content = filtered.join("\n");
|
|
261
|
-
atomicWriteFile(indexPath, content.endsWith("\n") ? content : content + "\n");
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function uninstallSkillLocally(skillId: string): void {
|
|
265
|
-
const skillDir = join(getWorkspaceSkillsDir(), skillId);
|
|
266
|
-
|
|
267
|
-
if (!existsSync(skillDir)) {
|
|
268
|
-
throw new Error(`Skill "${skillId}" is not installed.`);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
rmSync(skillDir, { recursive: true, force: true });
|
|
272
|
-
removeSkillsIndexEntry(skillId);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
async function installSkillLocally(
|
|
276
|
-
skillId: string,
|
|
277
|
-
catalogEntry: CatalogSkill,
|
|
278
|
-
overwrite: boolean,
|
|
279
|
-
): Promise<void> {
|
|
280
|
-
const skillDir = join(getWorkspaceSkillsDir(), skillId);
|
|
281
|
-
const skillFilePath = join(skillDir, "SKILL.md");
|
|
282
|
-
|
|
283
|
-
if (existsSync(skillFilePath) && !overwrite) {
|
|
284
|
-
throw new Error(
|
|
285
|
-
`Skill "${skillId}" is already installed. Use --overwrite to replace it.`,
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
mkdirSync(skillDir, { recursive: true });
|
|
290
|
-
|
|
291
|
-
// In dev mode, install from the local repo skills directory if available
|
|
292
|
-
const repoSkillsDir = getRepoSkillsDir();
|
|
293
|
-
const repoSkillSource = repoSkillsDir
|
|
294
|
-
? join(repoSkillsDir, skillId)
|
|
295
|
-
: undefined;
|
|
296
|
-
|
|
297
|
-
if (repoSkillSource && existsSync(join(repoSkillSource, "SKILL.md"))) {
|
|
298
|
-
cpSync(repoSkillSource, skillDir, { recursive: true });
|
|
299
|
-
} else {
|
|
300
|
-
await fetchAndExtractSkill(skillId, skillDir);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// Write version metadata
|
|
304
|
-
if (catalogEntry.version) {
|
|
305
|
-
const meta = {
|
|
306
|
-
version: catalogEntry.version,
|
|
307
|
-
installedAt: new Date().toISOString(),
|
|
308
|
-
};
|
|
309
|
-
atomicWriteFile(
|
|
310
|
-
join(skillDir, "version.json"),
|
|
311
|
-
JSON.stringify(meta, null, 2) + "\n",
|
|
312
|
-
);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// Install npm dependencies if the skill has a package.json
|
|
316
|
-
if (existsSync(join(skillDir, "package.json"))) {
|
|
317
|
-
const bunPath = `${homedir()}/.bun/bin`;
|
|
318
|
-
execSync("bun install", {
|
|
319
|
-
cwd: skillDir,
|
|
320
|
-
stdio: "inherit",
|
|
321
|
-
env: { ...process.env, PATH: `${bunPath}:${process.env.PATH}` },
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Register in SKILLS.md only after all steps succeed
|
|
326
|
-
upsertSkillsIndex(skillId);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// ---------------------------------------------------------------------------
|
|
330
|
-
// Exported types and functions for testing
|
|
331
|
-
// ---------------------------------------------------------------------------
|
|
332
|
-
|
|
333
|
-
export type { CatalogManifest, CatalogSkill };
|
|
334
|
-
|
|
335
|
-
export {
|
|
336
|
-
extractTarToDir,
|
|
337
|
-
fetchAndExtractSkill,
|
|
338
5
|
fetchCatalog,
|
|
339
|
-
|
|
6
|
+
getRepoSkillsDir,
|
|
340
7
|
installSkillLocally,
|
|
341
8
|
readLocalCatalog,
|
|
342
|
-
removeSkillsIndexEntry,
|
|
343
9
|
uninstallSkillLocally,
|
|
344
|
-
|
|
345
|
-
};
|
|
10
|
+
} from "../../skills/catalog-install.js";
|
|
11
|
+
import type { AuditResponse } from "../../skills/skillssh-registry.js";
|
|
12
|
+
import {
|
|
13
|
+
fetchSkillAudits,
|
|
14
|
+
formatAuditBadges,
|
|
15
|
+
installExternalSkill,
|
|
16
|
+
resolveSkillSource,
|
|
17
|
+
searchSkillsRegistry,
|
|
18
|
+
} from "../../skills/skillssh-registry.js";
|
|
19
|
+
import { log } from "../logger.js";
|
|
346
20
|
|
|
347
21
|
// ---------------------------------------------------------------------------
|
|
348
22
|
// Command registration
|
|
@@ -362,9 +36,13 @@ capabilities with pre-built workflows and tools.
|
|
|
362
36
|
Examples:
|
|
363
37
|
$ assistant skills list
|
|
364
38
|
$ assistant skills list --json
|
|
39
|
+
$ assistant skills search react
|
|
40
|
+
$ assistant skills search react --limit 5 --json
|
|
365
41
|
$ assistant skills install weather
|
|
366
42
|
$ assistant skills install weather --overwrite
|
|
367
|
-
$ assistant skills uninstall weather
|
|
43
|
+
$ assistant skills uninstall weather
|
|
44
|
+
$ assistant skills add vercel-labs/skills@find-skills
|
|
45
|
+
$ assistant skills add vercel-labs/skills/find-skills --overwrite`,
|
|
368
46
|
);
|
|
369
47
|
|
|
370
48
|
skills
|
|
@@ -413,6 +91,102 @@ Examples:
|
|
|
413
91
|
}
|
|
414
92
|
});
|
|
415
93
|
|
|
94
|
+
skills
|
|
95
|
+
.command("search <query>")
|
|
96
|
+
.description("Search the skills.sh community registry")
|
|
97
|
+
.option("--limit <n>", "Maximum number of results", "10")
|
|
98
|
+
.option("--json", "Machine-readable JSON output")
|
|
99
|
+
.addHelpText(
|
|
100
|
+
"after",
|
|
101
|
+
`
|
|
102
|
+
Arguments:
|
|
103
|
+
query Free-text search term matched against skill names, descriptions,
|
|
104
|
+
and tags in the skills.sh registry.
|
|
105
|
+
|
|
106
|
+
Searches the skills.sh community registry and displays matching skills
|
|
107
|
+
with install counts and security audit badges (ATH, Socket, Snyk).
|
|
108
|
+
Audit fetch failures are non-fatal — results are still shown without
|
|
109
|
+
security data.
|
|
110
|
+
|
|
111
|
+
Examples:
|
|
112
|
+
$ assistant skills search react
|
|
113
|
+
$ assistant skills search "file management" --limit 3
|
|
114
|
+
$ assistant skills search deploy --json`,
|
|
115
|
+
)
|
|
116
|
+
.action(async (query: string, opts: { limit: string; json?: boolean }) => {
|
|
117
|
+
const json = opts.json ?? false;
|
|
118
|
+
const limit = parseInt(opts.limit, 10) || 10;
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
const results = await searchSkillsRegistry(query, limit);
|
|
122
|
+
|
|
123
|
+
if (results.length === 0) {
|
|
124
|
+
if (json) {
|
|
125
|
+
console.log(JSON.stringify({ ok: true, results: [], audits: {} }));
|
|
126
|
+
} else {
|
|
127
|
+
log.info(`No skills found for "${query}".`);
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Group skill slugs by source for batch audit lookups
|
|
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.
|
|
142
|
+
const allAudits: AuditResponse = {};
|
|
143
|
+
for (const [source, slugs] of sourceToSlugs) {
|
|
144
|
+
try {
|
|
145
|
+
const audits = await fetchSkillAudits(source, slugs);
|
|
146
|
+
for (const [skillId, auditData] of Object.entries(audits)) {
|
|
147
|
+
allAudits[`${source}/${skillId}`] = auditData;
|
|
148
|
+
}
|
|
149
|
+
} catch {
|
|
150
|
+
// Audit fetch failures are non-fatal; display results without audits
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (json) {
|
|
155
|
+
console.log(
|
|
156
|
+
JSON.stringify({
|
|
157
|
+
ok: true,
|
|
158
|
+
results,
|
|
159
|
+
audits: allAudits,
|
|
160
|
+
}),
|
|
161
|
+
);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
log.info(`Search results for "${query}" (${results.length}):\n`);
|
|
166
|
+
for (const r of results) {
|
|
167
|
+
log.info(` ${r.name}`);
|
|
168
|
+
log.info(` ID: ${r.skillId}`);
|
|
169
|
+
log.info(` Source: ${r.source}`);
|
|
170
|
+
log.info(` Installs: ${r.installs}`);
|
|
171
|
+
const auditData = allAudits[`${r.source}/${r.skillId}`];
|
|
172
|
+
if (auditData) {
|
|
173
|
+
log.info(` ${formatAuditBadges(auditData)}`);
|
|
174
|
+
} else {
|
|
175
|
+
log.info(" Security: no audit data");
|
|
176
|
+
}
|
|
177
|
+
log.info("");
|
|
178
|
+
}
|
|
179
|
+
} catch (err) {
|
|
180
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
181
|
+
if (json) {
|
|
182
|
+
console.log(JSON.stringify({ ok: false, error: msg }));
|
|
183
|
+
} else {
|
|
184
|
+
log.error(`Error: ${msg}`);
|
|
185
|
+
}
|
|
186
|
+
process.exitCode = 1;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
|
|
416
190
|
skills
|
|
417
191
|
.command("install <skill-id>")
|
|
418
192
|
.description("Install a skill from the catalog")
|
|
@@ -491,4 +265,68 @@ Examples:
|
|
|
491
265
|
process.exitCode = 1;
|
|
492
266
|
}
|
|
493
267
|
});
|
|
268
|
+
|
|
269
|
+
skills
|
|
270
|
+
.command("add <source>")
|
|
271
|
+
.description(
|
|
272
|
+
"Install a community skill from the skills.sh registry (GitHub)",
|
|
273
|
+
)
|
|
274
|
+
.option("--overwrite", "Replace an already installed skill")
|
|
275
|
+
.option("--json", "Machine-readable JSON output")
|
|
276
|
+
.addHelpText(
|
|
277
|
+
"after",
|
|
278
|
+
`
|
|
279
|
+
Arguments:
|
|
280
|
+
source Skill source in one of these formats:
|
|
281
|
+
owner/repo@skill-name
|
|
282
|
+
owner/repo/skill-name
|
|
283
|
+
https://github.com/owner/repo/tree/<branch>/skills/skill-name
|
|
284
|
+
|
|
285
|
+
Notes:
|
|
286
|
+
Fetches the skill's SKILL.md and supporting files from the specified GitHub
|
|
287
|
+
repository and installs them into the workspace skills directory. A
|
|
288
|
+
version.json file is written with origin metadata for provenance tracking.
|
|
289
|
+
|
|
290
|
+
Examples:
|
|
291
|
+
$ assistant skills add vercel-labs/skills@find-skills
|
|
292
|
+
$ assistant skills add vercel-labs/skills/find-skills
|
|
293
|
+
$ assistant skills add vercel-labs/skills@find-skills --overwrite`,
|
|
294
|
+
)
|
|
295
|
+
.action(
|
|
296
|
+
async (source: string, opts: { overwrite?: boolean; json?: boolean }) => {
|
|
297
|
+
const json = opts.json ?? false;
|
|
298
|
+
|
|
299
|
+
try {
|
|
300
|
+
const { owner, repo, skillSlug, ref } = resolveSkillSource(source);
|
|
301
|
+
|
|
302
|
+
await installExternalSkill(
|
|
303
|
+
owner,
|
|
304
|
+
repo,
|
|
305
|
+
skillSlug,
|
|
306
|
+
opts.overwrite ?? false,
|
|
307
|
+
ref,
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
if (json) {
|
|
311
|
+
console.log(
|
|
312
|
+
JSON.stringify({
|
|
313
|
+
ok: true,
|
|
314
|
+
skillSlug,
|
|
315
|
+
source: `${owner}/${repo}`,
|
|
316
|
+
}),
|
|
317
|
+
);
|
|
318
|
+
} else {
|
|
319
|
+
log.info(`Installed skill "${skillSlug}" from ${owner}/${repo}.`);
|
|
320
|
+
}
|
|
321
|
+
} catch (err) {
|
|
322
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
323
|
+
if (json) {
|
|
324
|
+
console.log(JSON.stringify({ ok: false, error: msg }));
|
|
325
|
+
} else {
|
|
326
|
+
log.error(`Error: ${msg}`);
|
|
327
|
+
}
|
|
328
|
+
process.exitCode = 1;
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
);
|
|
494
332
|
}
|
package/src/cli/http-client.ts
CHANGED
|
@@ -64,23 +64,3 @@ export async function httpSend(
|
|
|
64
64
|
}
|
|
65
65
|
return fetch(url, { ...init, headers });
|
|
66
66
|
}
|
|
67
|
-
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
|
-
// Health check
|
|
70
|
-
// ---------------------------------------------------------------------------
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Perform an HTTP health check against the daemon's `/healthz` endpoint.
|
|
74
|
-
* Returns true if the daemon responds with HTTP 200, false otherwise.
|
|
75
|
-
*/
|
|
76
|
-
export async function httpHealthCheck(timeoutMs = 2000): Promise<boolean> {
|
|
77
|
-
try {
|
|
78
|
-
const url = `${getHttpBaseUrl()}/healthz`;
|
|
79
|
-
const response = await fetch(url, {
|
|
80
|
-
signal: AbortSignal.timeout(timeoutMs),
|
|
81
|
-
});
|
|
82
|
-
return response.ok;
|
|
83
|
-
} catch {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
}
|
package/src/cli/main-screen.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
|
|
4
|
+
import { getGatewayInternalBaseUrl } from "../config/env.js";
|
|
4
5
|
import { getWorkspaceDir } from "../util/platform.js";
|
|
5
|
-
import { getHttpBaseUrl } from "./http-client.js";
|
|
6
6
|
|
|
7
7
|
const LEFT_PANEL_WIDTH = 36;
|
|
8
8
|
const RIGHT_LINE_COUNT = 11;
|
|
@@ -14,7 +14,7 @@ export interface MainScreenLayout {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export function renderMainScreen(): MainScreenLayout {
|
|
17
|
-
const httpUrl =
|
|
17
|
+
const httpUrl = getGatewayInternalBaseUrl();
|
|
18
18
|
const workspace = getWorkspaceDir();
|
|
19
19
|
const assistantId = workspace.split("/").pop() ?? "vellum";
|
|
20
20
|
|
package/src/cli/program.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
|
|
3
1
|
import { Command } from "commander";
|
|
4
2
|
|
|
5
3
|
import { registerHooksCommand } from "../hooks/cli.js";
|
|
4
|
+
import { APP_VERSION } from "../version.js";
|
|
6
5
|
import { registerAuditCommand } from "./commands/audit.js";
|
|
7
6
|
import { registerAutonomyCommand } from "./commands/autonomy.js";
|
|
8
7
|
import { registerBrowserRelayCommand } from "./commands/browser-relay.js";
|
|
@@ -12,31 +11,28 @@ import { registerConfigCommand } from "./commands/config.js";
|
|
|
12
11
|
import { registerContactsCommand } from "./commands/contacts.js";
|
|
13
12
|
import { registerCredentialsCommand } from "./commands/credentials.js";
|
|
14
13
|
import { registerDefaultAction } from "./commands/default-action.js";
|
|
15
|
-
import { registerDevCommand } from "./commands/dev.js";
|
|
16
14
|
import { registerDoctorCommand } from "./commands/doctor.js";
|
|
17
15
|
import { registerEmailCommand } from "./commands/email.js";
|
|
18
16
|
import { registerKeysCommand } from "./commands/keys.js";
|
|
19
|
-
import { registerMapCommand } from "./commands/map.js";
|
|
20
17
|
import { registerMcpCommand } from "./commands/mcp.js";
|
|
21
18
|
import { registerMemoryCommand } from "./commands/memory.js";
|
|
22
19
|
import { registerNotificationsCommand } from "./commands/notifications.js";
|
|
23
|
-
import { registerOAuthCommand } from "./commands/oauth.js";
|
|
20
|
+
import { registerOAuthCommand } from "./commands/oauth/index.js";
|
|
24
21
|
import { registerPlatformCommand } from "./commands/platform.js";
|
|
25
22
|
import { registerSequenceCommand } from "./commands/sequence.js";
|
|
26
23
|
import { registerSessionsCommand } from "./commands/sessions.js";
|
|
27
24
|
import { registerSkillsCommand } from "./commands/skills.js";
|
|
28
25
|
import { registerTrustCommand } from "./commands/trust.js";
|
|
29
26
|
|
|
30
|
-
const require = createRequire(import.meta.url);
|
|
31
|
-
const { version } = require("../../package.json") as { version: string };
|
|
32
|
-
|
|
33
27
|
export function buildCliProgram(): Command {
|
|
34
28
|
const program = new Command();
|
|
35
29
|
|
|
36
|
-
program
|
|
30
|
+
program
|
|
31
|
+
.name("assistant")
|
|
32
|
+
.description("Local AI assistant")
|
|
33
|
+
.version(APP_VERSION);
|
|
37
34
|
|
|
38
35
|
registerDefaultAction(program);
|
|
39
|
-
registerDevCommand(program);
|
|
40
36
|
registerSessionsCommand(program);
|
|
41
37
|
registerConfigCommand(program);
|
|
42
38
|
registerKeysCommand(program);
|
|
@@ -58,7 +54,6 @@ export function buildCliProgram(): Command {
|
|
|
58
54
|
registerSkillsCommand(program);
|
|
59
55
|
registerBrowserRelayCommand(program);
|
|
60
56
|
|
|
61
|
-
registerMapCommand(program);
|
|
62
57
|
registerSequenceCommand(program);
|
|
63
58
|
|
|
64
59
|
return program;
|
package/src/cli/reference.ts
CHANGED
|
@@ -10,7 +10,6 @@ Options:
|
|
|
10
10
|
-h, --help display help for command
|
|
11
11
|
|
|
12
12
|
Commands:
|
|
13
|
-
dev [options] Run the assistant in dev mode
|
|
14
13
|
sessions Manage sessions
|
|
15
14
|
config Manage configuration
|
|
16
15
|
keys Manage API keys in secure storage
|
|
@@ -28,9 +27,8 @@ Commands:
|
|
|
28
27
|
completions <shell> Generate shell completion script (e.g. assistant completions bash >> ~/.bashrc)
|
|
29
28
|
notifications [options] Send and inspect notifications through the unified notification router
|
|
30
29
|
platform [options] Manage platform integration for containerized deployments
|
|
31
|
-
oauth [options] Manage OAuth
|
|
30
|
+
oauth [options] Manage OAuth providers, apps, connections, and tokens
|
|
32
31
|
skills Browse and install skills from the Vellum catalog
|
|
33
32
|
browser Browser automation, extension relay, and Chrome CDP management
|
|
34
|
-
map [options] <domain> Auto-navigate a domain and produce a deduplicated API map. Launches Chrome with CDP, starts a Ride Shotgun learn session, then analyzes captured network traffic.
|
|
35
33
|
sequence [options] Manage email sequences
|
|
36
34
|
`;
|