@vellumai/assistant 0.11.4 → 0.11.5-staging.1
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 +2 -2
- package/ARCHITECTURE.md +29 -4
- package/README.md +1 -1
- package/docs/architecture/memory.md +17 -5
- package/docs/architecture/security.md +96 -152
- package/docs/guardian-request-flow.md +13 -2
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +166 -1
- package/node_modules/@vellumai/gateway-client/src/http-delivery.ts +7 -14
- package/node_modules/@vellumai/gateway-client/src/index.ts +2 -0
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +29 -31
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/openapi.yaml +193 -3
- package/package.json +1 -1
- package/src/__tests__/anthropic-provider.test.ts +10 -3
- package/src/__tests__/approval-interception-trust-gates.test.ts +40 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +4 -0
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -6
- package/src/__tests__/channel-reply-delivery.test.ts +26 -13
- package/src/__tests__/checker.test.ts +20 -314
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +6 -2
- package/src/__tests__/client-os-metadata-persistence.test.ts +16 -0
- package/src/__tests__/compactor-retained-image-validation.test.ts +142 -0
- package/src/__tests__/container-cpu-sampler.test.ts +153 -0
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
- package/src/__tests__/conversation-attachments.test.ts +0 -1
- package/src/__tests__/conversation-error.test.ts +17 -0
- package/src/__tests__/conversation-lifecycle.test.ts +20 -26
- package/src/__tests__/conversation-pairing.test.ts +186 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +21 -2
- package/src/__tests__/credential-broker-server-use.test.ts +24 -5
- package/src/__tests__/credential-routes.test.ts +22 -3
- package/src/__tests__/credential-security-invariants.test.ts +2 -1
- package/src/__tests__/daemon-credential-client.test.ts +88 -0
- package/src/__tests__/default-plugin-names-guard.test.ts +12 -1
- package/src/__tests__/dm-backfill.test.ts +63 -0
- package/src/__tests__/dynamic-skill-background-guard.test.ts +0 -2
- package/src/__tests__/edit-propagation.test.ts +107 -4
- package/src/__tests__/events-client-registration.test.ts +28 -0
- package/src/__tests__/file-write-tool.test.ts +4 -2
- package/src/__tests__/guardian-prompt-notice-privacy.test.ts +133 -0
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +143 -97
- package/src/__tests__/helpers/gateway-classify-mock.ts +27 -6
- package/src/__tests__/host-proxy-interface.test.ts +11 -1
- package/src/__tests__/host-shell-tool.test.ts +23 -4
- package/src/__tests__/image-conversion.test.ts +143 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +47 -36
- package/src/__tests__/input-repairs.test.ts +207 -0
- package/src/__tests__/live-workspace-guard.test.ts +75 -0
- package/src/__tests__/mcp-abort-signal.test.ts +1 -1
- package/src/__tests__/mcp-client-auth.test.ts +1 -1
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +1 -1
- package/src/__tests__/media-resolve-image-validation.test.ts +310 -0
- package/src/__tests__/mtime-cache.test.ts +2 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +124 -1
- package/src/__tests__/openai-provider.test.ts +22 -0
- package/src/__tests__/personal-memory-auth-bypass.test.ts +22 -6
- package/src/__tests__/platform-bash-auto-approve.test.ts +0 -4
- package/src/__tests__/platform.test.ts +16 -1
- package/src/__tests__/plugin-api-resolve-credential.test.ts +22 -13
- package/src/__tests__/plugin-api-shim.test.ts +5 -0
- package/src/__tests__/plugin-api-store-credential.test.ts +268 -0
- package/src/__tests__/plugin-config-data-migration.test.ts +8 -1
- package/src/__tests__/plugin-disabled-state.test.ts +2 -0
- package/src/__tests__/plugin-effective-enabled-set.test.ts +55 -3
- package/src/__tests__/plugin-execution-context.test.ts +73 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +0 -1
- package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +0 -1
- package/src/__tests__/reaction-persistence.test.ts +200 -7
- package/src/__tests__/require-fresh-approval.test.ts +0 -4
- package/src/__tests__/resource-pressure-guard.test.ts +428 -0
- package/src/__tests__/resource-pressure-routes.test.ts +113 -0
- package/src/__tests__/risk-classification-boundary-guard.test.ts +115 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +27 -1
- package/src/__tests__/secret-routes-platform-proxy.test.ts +7 -0
- package/src/__tests__/skill-tool-factory.test.ts +161 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +132 -5
- package/src/__tests__/tool-executor.test.ts +63 -38
- package/src/__tests__/tool-policy.test.ts +97 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +7 -4
- package/src/__tests__/user-plugin-loader.test.ts +2 -0
- package/src/__tests__/validate-input.test.ts +243 -7
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/acp/__tests__/acp-claude-oauth.test.ts +97 -29
- package/src/acp/__tests__/prepare-agent-env.test.ts +376 -153
- package/src/acp/acp-claude-oauth.ts +38 -21
- package/src/acp/prepare-agent-env.ts +146 -55
- package/src/agent/loop-tool-dedup.test.ts +161 -0
- package/src/agent/loop.ts +68 -22
- package/src/api/constants/app-tools.ts +34 -0
- package/src/api/events/resource-pressure-status-changed.ts +53 -0
- package/src/api/index.ts +19 -0
- package/src/api/responses/resource-pressure-status.ts +25 -0
- package/src/approvals/guardian-channel-delivery.ts +70 -6
- package/src/approvals/guardian-request-resolvers.ts +32 -66
- package/src/channels/__tests__/message-audience.test.ts +49 -0
- package/src/channels/__tests__/types.test.ts +17 -3
- package/src/channels/message-audience.ts +40 -0
- package/src/channels/types.ts +16 -12
- package/src/cli/__tests__/catalog-search-help.test.ts +50 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +31 -0
- package/src/cli/commands/__tests__/conversations-search.test.ts +289 -0
- package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -0
- package/src/cli/commands/__tests__/inference-providers.test.ts +68 -0
- package/src/cli/commands/__tests__/keys.test.ts +89 -8
- package/src/cli/commands/__tests__/plugins.test.ts +57 -1
- package/src/cli/commands/channel-verification-sessions.help.ts +11 -9
- package/src/cli/commands/channel-verification-sessions.ts +11 -21
- package/src/cli/commands/conversations.help.ts +34 -0
- package/src/cli/commands/conversations.ts +125 -0
- package/src/cli/commands/inference-providers.ts +9 -4
- package/src/cli/commands/inference.help.ts +9 -4
- package/src/cli/commands/keys.help.ts +13 -1
- package/src/cli/commands/keys.ts +26 -15
- package/src/cli/commands/memory/__tests__/memory-v2.test.ts +57 -7
- package/src/cli/commands/memory/index.help.ts +41 -27
- package/src/cli/commands/memory/index.ts +2 -0
- package/src/cli/commands/memory/memory-v2.ts +58 -54
- package/src/cli/commands/memory/memory-validate.ts +18 -0
- package/src/cli/commands/monitoring.ts +1 -0
- package/src/cli/commands/plugins.help.ts +28 -31
- package/src/cli/commands/plugins.ts +10 -0
- package/src/cli/commands/skills.help.ts +13 -16
- package/src/cli/commands/trust.ts +3 -14
- package/src/cli/lib/__tests__/install-from-github.test.ts +38 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +34 -0
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +32 -1
- package/src/cli/lib/__tests__/toggle-plugin.test.ts +2 -1
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +64 -0
- package/src/cli/lib/bundled-marketplace.json +13 -0
- package/src/cli/lib/daemon-credential-client.ts +25 -3
- package/src/cli/lib/install-from-github.ts +35 -24
- package/src/cli/lib/merge-plugin-tree.ts +22 -4
- package/src/cli/lib/plugin-surfaces.ts +27 -0
- package/src/config/feature-flag-registry.json +35 -19
- package/src/config/webhook-routing.ts +8 -0
- package/src/context/compactor.ts +31 -2
- package/src/daemon/__tests__/provider-rejection-log-fields.test.ts +272 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +4 -1
- package/src/daemon/conversation-error.ts +13 -0
- package/src/daemon/conversation-messaging.ts +22 -2
- package/src/daemon/conversation-process.ts +11 -0
- package/src/daemon/conversation-store.ts +10 -0
- package/src/daemon/conversation-surfaces.ts +21 -8
- package/src/daemon/conversation.ts +12 -10
- package/src/daemon/lifecycle.ts +6 -2
- package/src/daemon/message-types/conversations.ts +5 -7
- package/src/daemon/provider-rejection-log-fields.ts +124 -0
- package/src/daemon/resource-pressure-guard-lifecycle.ts +66 -0
- package/src/daemon/resource-pressure-guard.ts +387 -0
- package/src/daemon/shutdown-handlers.ts +2 -0
- package/src/daemon/startup-error.ts +16 -0
- package/src/daemon/trust-context.ts +14 -10
- package/src/daemon/unsendable-image-notice.ts +76 -0
- package/src/hooks/registry.ts +65 -51
- package/src/ipc/__tests__/socket-path.test.ts +15 -7
- package/src/ipc/gateway-client.test.ts +1 -1
- package/src/ipc/gateway-client.ts +14 -21
- package/src/ipc/socket-cleanup.ts +2 -11
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +1 -1
- package/src/messaging/provider-message-metadata.ts +128 -0
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +116 -68
- package/src/messaging/providers/channel-transport.ts +90 -13
- package/src/messaging/providers/discord/send.ts +16 -0
- package/src/messaging/providers/discord/transport.ts +11 -1
- package/src/messaging/providers/index.ts +109 -16
- package/src/messaging/providers/slack/message-metadata.ts +45 -0
- package/src/messaging/providers/slack/render-transcript.ts +1 -4
- package/src/messaging/providers/slack/send.test.ts +6 -9
- package/src/messaging/providers/slack/send.ts +40 -28
- package/src/messaging/providers/slack/transport.ts +22 -26
- package/src/messaging/providers/telegram-bot/send.test.ts +2 -8
- package/src/messaging/providers/telegram-bot/transport.ts +3 -6
- package/src/messaging/read-provider-metadata.test.ts +157 -0
- package/src/messaging/read-provider-metadata.ts +51 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +94 -0
- package/src/notifications/__tests__/edit-notification.test.ts +174 -2
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +536 -4
- package/src/notifications/adapters/macos.ts +55 -0
- package/src/notifications/adapters/slack.ts +10 -5
- package/src/notifications/assistant-reply-producer.ts +37 -4
- package/src/notifications/conversation-pairing.ts +111 -21
- package/src/notifications/edit-notification.ts +38 -8
- package/src/notifications/emit-signal.ts +12 -14
- package/src/notifications/home-feed-side-effect.ts +218 -15
- package/src/notifications/types.ts +5 -0
- package/src/permissions/AGENTS.md +16 -0
- package/src/permissions/checker.test.ts +75 -122
- package/src/permissions/checker.ts +44 -560
- package/src/permissions/confirmation-guardian-request.test.ts +28 -3
- package/src/permissions/confirmation-guardian-request.ts +5 -1
- package/src/persistence/conversation-crud.ts +23 -20
- package/src/persistence/conversation-queries.ts +14 -1
- package/src/persistence/conversation-types.ts +22 -0
- package/src/persistence/delivery-crud.ts +122 -15
- package/src/plugin-api/__tests__/import-graph-partial-mock.test.ts +67 -0
- package/src/plugin-api/conversation-turn.ts +27 -0
- package/src/plugin-api/credential-scope.test.ts +15 -0
- package/src/plugin-api/credential-scope.ts +14 -0
- package/src/plugin-api/index.ts +19 -1
- package/src/plugin-api/resolve-credential.ts +15 -10
- package/src/plugin-api/store-credential.ts +148 -0
- package/src/plugin-api/system-card.ts +36 -0
- package/src/plugin-api/vision-support.test.ts +82 -0
- package/src/plugin-api/vision-support.ts +14 -2
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +361 -110
- package/src/plugins/defaults/image-fallback/__tests__/vision-recovery.test.ts +4 -0
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +58 -0
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +64 -23
- package/src/plugins/defaults/image-recovery/detect.ts +24 -1
- package/src/plugins/defaults/main.ts +15 -0
- package/src/plugins/defaults/memory/AGENTS.md +11 -3
- package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +0 -1
- package/src/plugins/defaults/memory/graph-topology/pending-buffer.ts +9 -12
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +1 -1
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +12 -10
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +114 -0
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +8 -0
- package/src/plugins/defaults/memory/substrate/__tests__/edge-index.test.ts +0 -30
- package/src/plugins/defaults/memory/substrate/__tests__/ingest.test.ts +73 -1
- package/src/plugins/defaults/memory/substrate/__tests__/page-index.test.ts +37 -0
- package/src/plugins/defaults/memory/substrate/__tests__/page-links.test.ts +208 -0
- package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +158 -1
- package/src/plugins/defaults/memory/substrate/__tests__/static-context.test.ts +1 -61
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +68 -6
- package/src/plugins/defaults/memory/substrate/edge-index.ts +0 -31
- package/src/plugins/defaults/memory/substrate/ingest.ts +59 -0
- package/src/plugins/defaults/memory/substrate/page-index.ts +35 -8
- package/src/plugins/defaults/memory/substrate/page-links.ts +133 -0
- package/src/plugins/defaults/memory/substrate/page-store.ts +10 -0
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +124 -34
- package/src/plugins/defaults/memory/substrate/static-context.ts +0 -29
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +3 -1
- package/src/plugins/defaults/memory/v3/card.ts +9 -9
- package/src/plugins/defaults/memory/v3/core-set.test.ts +7 -0
- package/src/plugins/defaults/memory/v3/core-set.ts +5 -1
- package/src/plugins/defaults/memory/v3/edge.ts +13 -57
- package/src/plugins/mtime-cache.ts +1 -1
- package/src/plugins/pipeline.ts +14 -7
- package/src/plugins/plugin-execution-context.ts +35 -11
- package/src/plugins/plugin-tree-walk.ts +63 -4
- package/src/providers/anthropic/__tests__/pause-turn-continuation.test.ts +170 -0
- package/src/providers/anthropic/client.ts +332 -241
- package/src/providers/connection-resolution.ts +2 -1
- package/src/providers/content-blocks.ts +22 -0
- package/src/providers/gemini/client.ts +5 -2
- package/src/providers/inference/__tests__/adapter-factory-litellm.test.ts +47 -1
- package/src/providers/inference/__tests__/adapter-factory-ollama.test.ts +83 -0
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +98 -1
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +38 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +10 -0
- package/src/providers/inference/__tests__/connections-ollama.test.ts +90 -0
- package/src/providers/inference/__tests__/missing-credential-guard.test.ts +117 -0
- package/src/providers/inference/adapter-factory.ts +33 -2
- package/src/providers/inference/auth.ts +13 -2
- package/src/providers/inference/credential-usage.ts +37 -0
- package/src/providers/inference/missing-credential-guard.ts +110 -0
- package/src/providers/inference/resolve-auth.ts +7 -7
- package/src/providers/media-resolve.ts +176 -15
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +576 -46
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +125 -2
- package/src/providers/openai/chat-completions-provider.ts +322 -42
- package/src/routes/route-host-protocol.ts +7 -0
- package/src/routes/worker.ts +31 -10
- package/src/runtime/AGENTS.md +35 -0
- package/src/runtime/__tests__/runtime-http-port-collision.test.ts +131 -0
- package/src/runtime/__tests__/web-presence.test.ts +234 -0
- package/src/runtime/assistant-event-hub.ts +38 -0
- package/src/runtime/channel-reply-delivery.ts +54 -31
- package/src/runtime/channel-retry-sweep.ts +6 -4
- package/src/runtime/effective-capabilities.test.ts +19 -0
- package/src/runtime/effective-capabilities.ts +25 -0
- package/src/runtime/guardian-reply-router.ts +6 -2
- package/src/runtime/http-errors.ts +1 -0
- package/src/runtime/http-server.ts +20 -5
- package/src/runtime/routes/__tests__/client-routes.test.ts +150 -0
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +133 -0
- package/src/runtime/routes/__tests__/credential-delete-in-use.test.ts +155 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +52 -1
- package/src/runtime/routes/__tests__/monitoring-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/pending-interactions-route.test.ts +175 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +88 -35
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +55 -6
- package/src/runtime/routes/__tests__/system-card-turn-termination.test.ts +107 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher-host.test.ts +52 -1
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +75 -4
- package/src/runtime/routes/approval-routes.ts +37 -4
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +16 -22
- package/src/runtime/routes/canned-message-complete.ts +68 -29
- package/src/runtime/routes/client-routes.ts +113 -0
- package/src/runtime/routes/conversation-list-routes.ts +22 -7
- package/src/runtime/routes/conversation-management-routes.ts +15 -9
- package/src/runtime/routes/conversation-routes.ts +36 -22
- package/src/runtime/routes/credential-in-use.ts +85 -0
- package/src/runtime/routes/credential-routes.ts +55 -85
- package/src/runtime/routes/guardian-approval-interception.ts +22 -22
- package/src/runtime/routes/guardian-approval-reply-helpers.ts +14 -12
- package/src/runtime/routes/identity-routes.ts +5 -121
- package/src/runtime/routes/inbound-message-handler.ts +71 -27
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +16 -17
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +77 -50
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -97
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +101 -77
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +17 -8
- package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +91 -7
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +72 -70
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +9 -7
- package/src/runtime/routes/monitoring-routes.ts +9 -1
- package/src/runtime/routes/plugins-routes.ts +17 -5
- package/src/runtime/routes/resource-pressure-routes.ts +22 -0
- package/src/runtime/routes/secret-routes.ts +39 -8
- package/src/runtime/routes/settings-routes.ts +6 -6
- package/src/runtime/routes/surface-action-routes.ts +20 -19
- package/src/runtime/routes/user-route-dispatcher.ts +31 -2
- package/src/runtime/routes/user-route-resolution.ts +18 -1
- package/src/runtime/slack-reply-session.test.ts +23 -13
- package/src/runtime/slack-reply-session.ts +38 -55
- package/src/runtime/web-presence.ts +90 -0
- package/src/skills/validate-input.ts +177 -40
- package/src/subagent/__tests__/consult-context-gating.test.ts +6 -10
- package/src/subagent/consult-context.ts +7 -23
- package/src/tools/credentials/broker.ts +24 -79
- package/src/tools/credentials/ref-parse.ts +35 -0
- package/src/tools/credentials/resolve.ts +4 -10
- package/src/tools/credentials/store.ts +168 -0
- package/src/tools/credentials/tool-policy.ts +67 -0
- package/src/tools/executor.ts +53 -15
- package/src/tools/network/__tests__/web-search.test.ts +41 -1
- package/src/tools/network/url-safety.ts +9 -16
- package/src/tools/network/web-search.ts +21 -3
- package/src/tools/permission-checker.ts +43 -52
- package/src/tools/schema-transforms.ts +40 -5
- package/src/tools/shared/input-repairs.ts +160 -0
- package/src/tools/skills/skill-tool-factory.ts +18 -4
- package/src/tools/subagent/spawn.ts +0 -1
- package/src/tools/tool-approval-handler.ts +16 -10
- package/src/tools/tool-types.ts +26 -13
- package/src/tools/types.ts +6 -6
- package/src/util/__tests__/cgroup-memory.test.ts +3 -0
- package/src/util/cgroup-memory.ts +3 -0
- package/src/util/container-cpu-sampler.ts +250 -0
- package/src/util/image-conversion.ts +178 -14
- package/src/util/platform.ts +93 -10
- package/src/permissions/ipc-risk-types.ts +0 -143
- package/src/permissions/risk-types.ts +0 -76
|
@@ -69,6 +69,7 @@ mock.module("../../../../util/logger.js", () => ({
|
|
|
69
69
|
// ---------------------------------------------------------------------------
|
|
70
70
|
|
|
71
71
|
const { registerMemoryV2Command } = await import("../memory-v2.js");
|
|
72
|
+
const { registerMemoryValidateCommand } = await import("../memory-validate.js");
|
|
72
73
|
|
|
73
74
|
// ---------------------------------------------------------------------------
|
|
74
75
|
// Test helpers
|
|
@@ -88,6 +89,7 @@ function buildProgram(): Command {
|
|
|
88
89
|
const memory = program.command("memory");
|
|
89
90
|
applyCommandHelp(memory, memoryHelp);
|
|
90
91
|
registerMemoryV2Command(memory);
|
|
92
|
+
registerMemoryValidateCommand(memory);
|
|
91
93
|
return program;
|
|
92
94
|
}
|
|
93
95
|
|
|
@@ -287,7 +289,7 @@ describe("memory v2 validate", () => {
|
|
|
287
289
|
result: {
|
|
288
290
|
pageCount: 0,
|
|
289
291
|
edgeCount: 0,
|
|
290
|
-
|
|
292
|
+
danglingLinks: [],
|
|
291
293
|
oversizedPages: [],
|
|
292
294
|
parseFailures: [],
|
|
293
295
|
},
|
|
@@ -306,7 +308,7 @@ describe("memory v2 validate", () => {
|
|
|
306
308
|
result: {
|
|
307
309
|
pageCount: 49,
|
|
308
310
|
edgeCount: 166,
|
|
309
|
-
|
|
311
|
+
danglingLinks: [],
|
|
310
312
|
oversizedPages: [],
|
|
311
313
|
parseFailures: [],
|
|
312
314
|
},
|
|
@@ -318,7 +320,7 @@ describe("memory v2 validate", () => {
|
|
|
318
320
|
expect(logOutput.some((line) => line.includes("Pages: 49"))).toBe(true);
|
|
319
321
|
expect(logOutput.some((line) => line.includes("Edges: 166"))).toBe(true);
|
|
320
322
|
expect(
|
|
321
|
-
logOutput.some((line) => line.includes("
|
|
323
|
+
logOutput.some((line) => line.includes("Dangling links: none")),
|
|
322
324
|
).toBe(true);
|
|
323
325
|
expect(
|
|
324
326
|
logOutput.some((line) => line.includes("Oversized pages: none")),
|
|
@@ -334,7 +336,9 @@ describe("memory v2 validate", () => {
|
|
|
334
336
|
result: {
|
|
335
337
|
pageCount: 10,
|
|
336
338
|
edgeCount: 20,
|
|
337
|
-
|
|
339
|
+
danglingLinks: [
|
|
340
|
+
{ from: "people/alice", to: "people/missing", kind: "links" },
|
|
341
|
+
],
|
|
338
342
|
oversizedPages: [{ slug: "arcs/big-day", chars: 12345 }],
|
|
339
343
|
parseFailures: [
|
|
340
344
|
{ slug: "people/broken", error: "missing frontmatter" },
|
|
@@ -345,9 +349,11 @@ describe("memory v2 validate", () => {
|
|
|
345
349
|
const { exitCode } = await runCommand(["memory", "v2", "validate"]);
|
|
346
350
|
|
|
347
351
|
expect(exitCode).toBe(1);
|
|
348
|
-
expect(
|
|
349
|
-
|
|
350
|
-
|
|
352
|
+
expect(
|
|
353
|
+
logOutput.some((line) =>
|
|
354
|
+
line.includes("people/alice → people/missing (links)"),
|
|
355
|
+
),
|
|
356
|
+
).toBe(true);
|
|
351
357
|
expect(logOutput.some((line) => line.includes("arcs/big-day"))).toBe(true);
|
|
352
358
|
expect(logOutput.some((line) => line.includes("people/broken"))).toBe(true);
|
|
353
359
|
});
|
|
@@ -360,3 +366,47 @@ describe("memory v2 validate", () => {
|
|
|
360
366
|
expect(exitCode).toBe(1);
|
|
361
367
|
});
|
|
362
368
|
});
|
|
369
|
+
|
|
370
|
+
describe("memory validate (top-level, same report)", () => {
|
|
371
|
+
test("sends memory_v2_validate and prints the report", async () => {
|
|
372
|
+
mockIpcResult = {
|
|
373
|
+
ok: true,
|
|
374
|
+
result: {
|
|
375
|
+
pageCount: 49,
|
|
376
|
+
edgeCount: 166,
|
|
377
|
+
danglingLinks: [],
|
|
378
|
+
oversizedPages: [],
|
|
379
|
+
parseFailures: [],
|
|
380
|
+
},
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const { exitCode } = await runCommand(["memory", "validate"]);
|
|
384
|
+
|
|
385
|
+
expect(exitCode).toBe(0);
|
|
386
|
+
expect(lastIpcCall!.method).toBe("memory_v2_validate");
|
|
387
|
+
expect(logOutput.some((line) => line.includes("Pages: 49"))).toBe(true);
|
|
388
|
+
expect(
|
|
389
|
+
logOutput.some((line) => line.includes("Dangling links: none")),
|
|
390
|
+
).toBe(true);
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
test("exits non-zero on violations, like the v2 spelling", async () => {
|
|
394
|
+
mockIpcResult = {
|
|
395
|
+
ok: true,
|
|
396
|
+
result: {
|
|
397
|
+
pageCount: 1,
|
|
398
|
+
edgeCount: 0,
|
|
399
|
+
danglingLinks: [{ from: "a", to: "missing", kind: "wikilink" }],
|
|
400
|
+
oversizedPages: [],
|
|
401
|
+
parseFailures: [],
|
|
402
|
+
},
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
const { exitCode } = await runCommand(["memory", "validate"]);
|
|
406
|
+
|
|
407
|
+
expect(exitCode).toBe(1);
|
|
408
|
+
expect(
|
|
409
|
+
logOutput.some((line) => line.includes("a → missing (wikilink)")),
|
|
410
|
+
).toBe(true);
|
|
411
|
+
});
|
|
412
|
+
});
|
|
@@ -23,7 +23,7 @@ The 'items' subgroup exposes full CRUD over individual memory items
|
|
|
23
23
|
|
|
24
24
|
The memory subsystem retrieves concept pages two ways: the v2 concept-page
|
|
25
25
|
activation model (prose pages with directed edges) and the v3 section-lane
|
|
26
|
-
model (section-grain lanes
|
|
26
|
+
model (section-grain lanes held in memory inside the assistant). Each subgroup exposes
|
|
27
27
|
operator-facing maintenance verbs — reindexing, backfills, validation, and evals.
|
|
28
28
|
|
|
29
29
|
Examples:
|
|
@@ -34,7 +34,7 @@ Examples:
|
|
|
34
34
|
$ assistant memory items list --search "coffee"
|
|
35
35
|
$ assistant memory items update 9f2c4f3a-3f1a-41e4-88e7-abc123 --statement "Prefers tea"
|
|
36
36
|
$ assistant memory items delete 9f2c4f3a-3f1a-41e4-88e7-abc123
|
|
37
|
-
$ assistant memory
|
|
37
|
+
$ assistant memory validate
|
|
38
38
|
$ assistant memory v3 rebuild-index
|
|
39
39
|
$ assistant memory ingest --dir .mv3/staging --dry-run`,
|
|
40
40
|
subcommands: [
|
|
@@ -43,8 +43,9 @@ Examples:
|
|
|
43
43
|
description:
|
|
44
44
|
"Content-based list, delete, and update of memory graph nodes",
|
|
45
45
|
helpText: `
|
|
46
|
-
Memory nodes are raw graph records (content, type, fidelity)
|
|
47
|
-
memory
|
|
46
|
+
Memory nodes are raw graph records (content, type, fidelity) in the memory
|
|
47
|
+
graph store, which every memory tier writes to. Unlike 'memory items', which
|
|
48
|
+
addresses nodes by UUID, these
|
|
48
49
|
commands address nodes by content text — matching the way an operator refers to
|
|
49
50
|
a remembered fact without first looking up its ID.
|
|
50
51
|
|
|
@@ -390,7 +391,6 @@ except reembed-skills which runs synchronously inside the assistant.
|
|
|
390
391
|
Read-only subcommands print diagnostic reports without mutating state.
|
|
391
392
|
|
|
392
393
|
Examples:
|
|
393
|
-
$ assistant memory v2 validate
|
|
394
394
|
$ assistant memory v2 reembed
|
|
395
395
|
$ assistant memory v2 reembed-skills
|
|
396
396
|
$ assistant memory v2 activation`,
|
|
@@ -400,9 +400,10 @@ Examples:
|
|
|
400
400
|
description:
|
|
401
401
|
"Refresh dense + sparse vectors for every concept page in Qdrant",
|
|
402
402
|
helpText: `
|
|
403
|
-
Fans out an embed_concept_page job per concept page slug
|
|
404
|
-
|
|
405
|
-
|
|
403
|
+
Fans out an embed_concept_page job per concept page slug so each page's
|
|
404
|
+
dense and sparse vectors get recomputed against the current embedding
|
|
405
|
+
backend (the direct-injected memory/*.md meta files are not embedded and are
|
|
406
|
+
not enqueued). Useful after upgrading
|
|
406
407
|
the embedding model or recovering a corrupted Qdrant collection.
|
|
407
408
|
|
|
408
409
|
The fan-out runs on the background memory worker — this command returns
|
|
@@ -449,20 +450,13 @@ Examples:
|
|
|
449
450
|
{
|
|
450
451
|
name: "validate",
|
|
451
452
|
description:
|
|
452
|
-
"
|
|
453
|
+
"Same report as 'memory validate' (read-only concept-page check)",
|
|
453
454
|
helpText: `
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
- Edge count (total and unique outgoing targets)
|
|
457
|
-
- Missing outgoing edge targets (orphan edges)
|
|
458
|
-
- Oversized pages (over the per-folder size cap)
|
|
459
|
-
- Parse failures (missing or malformed frontmatter)
|
|
460
|
-
|
|
461
|
-
Read-only — does not mutate the workspace. Exits non-zero if any
|
|
462
|
-
violations are reported.
|
|
455
|
+
Identical to 'assistant memory validate'; prefer that spelling. The report
|
|
456
|
+
covers the concept-page store, which is the same under memory v2 and v3.
|
|
463
457
|
|
|
464
458
|
Examples:
|
|
465
|
-
$ assistant memory
|
|
459
|
+
$ assistant memory validate`,
|
|
466
460
|
},
|
|
467
461
|
{
|
|
468
462
|
name: "ema",
|
|
@@ -600,9 +594,9 @@ Examples:
|
|
|
600
594
|
name: "v3",
|
|
601
595
|
description: "Memory v3 live-lane maintenance (section-lane model)",
|
|
602
596
|
helpText: `
|
|
603
|
-
The v3 memory subsystem retrieves concept pages over section-grain lanes
|
|
604
|
-
|
|
605
|
-
|
|
597
|
+
The v3 memory subsystem retrieves concept pages over section-grain lanes held
|
|
598
|
+
in memory inside the assistant. These commands maintain that live state
|
|
599
|
+
safely.
|
|
606
600
|
|
|
607
601
|
Examples:
|
|
608
602
|
$ assistant memory v3 rebuild-index
|
|
@@ -614,7 +608,7 @@ Examples:
|
|
|
614
608
|
name: "rebuild-index",
|
|
615
609
|
description: "Invalidate the v3 lanes so the next turn rebuilds",
|
|
616
610
|
helpText: `
|
|
617
|
-
Drops the assistant's
|
|
611
|
+
Drops the assistant's in-memory v3 lanes so the section index is rebuilt
|
|
618
612
|
from the current on-disk state on the next turn. Useful after editing concept
|
|
619
613
|
pages out-of-band.
|
|
620
614
|
|
|
@@ -635,10 +629,10 @@ Examples:
|
|
|
635
629
|
Embeds EVERY concept page's sections — including synthetic skill and CLI
|
|
636
630
|
capability rows — into the section dense store in one pass, then advances
|
|
637
631
|
the maintain checkpoint so the next incremental pass only re-embeds future
|
|
638
|
-
edits. Use this once on an
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
632
|
+
edits. Use this once on an install whose section dense store is empty or
|
|
633
|
+
predates v3: the periodic maintenance pass only re-embeds pages edited since
|
|
634
|
+
its last run (and never the synthetic rows), so most of the corpus would
|
|
635
|
+
otherwise never be embedded.
|
|
642
636
|
|
|
643
637
|
Idempotent and safe to re-run. Runs inside the assistant so it uses the live
|
|
644
638
|
configuration and advances the checkpoint the assistant reads.
|
|
@@ -804,6 +798,26 @@ Example:
|
|
|
804
798
|
},
|
|
805
799
|
],
|
|
806
800
|
},
|
|
801
|
+
{
|
|
802
|
+
name: "validate",
|
|
803
|
+
description:
|
|
804
|
+
"Check the concept-page store for dangling links, oversized pages, and parse failures (read-only)",
|
|
805
|
+
helpText: `
|
|
806
|
+
Walks memory/concepts/ on disk and reports:
|
|
807
|
+
- Page count and edge count
|
|
808
|
+
- Dangling links: an edges: entry, a links: entry, or an inline
|
|
809
|
+
[[wikilink]] whose target page does not exist (targets under skills/
|
|
810
|
+
and cli-commands/ resolve against the registered capability catalog)
|
|
811
|
+
- Oversized pages (over the configured per-page character cap)
|
|
812
|
+
- Parse failures (malformed frontmatter)
|
|
813
|
+
|
|
814
|
+
Read-only. Exits non-zero if anything is reported. Works on every memory
|
|
815
|
+
tier, including before memory.v3.live or memory.v2.enabled is set, so it
|
|
816
|
+
doubles as the pre-flip check for a migration.
|
|
817
|
+
|
|
818
|
+
Examples:
|
|
819
|
+
$ assistant memory validate`,
|
|
820
|
+
},
|
|
807
821
|
{
|
|
808
822
|
name: "ingest",
|
|
809
823
|
description:
|
|
@@ -8,6 +8,7 @@ import { registerMemoryIngestCommand } from "./memory-ingest.js";
|
|
|
8
8
|
import { registerMemoryRetrospectiveCommand } from "./memory-retrospective.js";
|
|
9
9
|
import { registerMemoryV2Command } from "./memory-v2.js";
|
|
10
10
|
import { registerMemoryV3Command } from "./memory-v3.js";
|
|
11
|
+
import { registerMemoryValidateCommand } from "./memory-validate.js";
|
|
11
12
|
import { registerMemoryNodesCommand } from "./nodes.js";
|
|
12
13
|
import { registerMemoryWorkerCommand } from "./worker.js";
|
|
13
14
|
|
|
@@ -24,6 +25,7 @@ export function registerMemoryCommand(program: Command): void {
|
|
|
24
25
|
registerMemoryV2Command(memory);
|
|
25
26
|
registerMemoryV3Command(memory);
|
|
26
27
|
registerMemoryIngestCommand(memory);
|
|
28
|
+
registerMemoryValidateCommand(memory);
|
|
27
29
|
registerMemoryRetrospectiveCommand(memory);
|
|
28
30
|
registerMemoryWorkerCommand(memory);
|
|
29
31
|
},
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
* from the current skill set.
|
|
13
13
|
* - `activation` — refresh persisted activation state for every
|
|
14
14
|
* conversation that has a stored row.
|
|
15
|
-
* - `validate
|
|
16
|
-
*
|
|
15
|
+
* - `validate`: {@link runMemoryValidate}, also registered as the top-level
|
|
16
|
+
* `memory validate` (`memory-validate.ts`); kept here while this
|
|
17
|
+
* namespace exists.
|
|
17
18
|
*/
|
|
18
19
|
|
|
19
20
|
import type { Command } from "commander";
|
|
@@ -59,6 +60,60 @@ async function runBackfillOp(op: MemoryV2BackfillOp): Promise<void> {
|
|
|
59
60
|
log.info(`Queued ${op} job: ${result.result!.jobId}`);
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Print the validate report; sets a non-zero exit code on any violation.
|
|
65
|
+
* Registered as `memory validate` (`memory-validate.ts`) and `memory v2
|
|
66
|
+
* validate`.
|
|
67
|
+
*/
|
|
68
|
+
export async function runMemoryValidate(): Promise<void> {
|
|
69
|
+
const result = await cliIpcCall<MemoryV2ValidateResult>(
|
|
70
|
+
"memory_v2_validate",
|
|
71
|
+
{ body: {} },
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (!result.ok) {
|
|
75
|
+
log.error(result.error ?? "Failed to validate memory state");
|
|
76
|
+
process.exitCode = 1;
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const report = result.result!;
|
|
81
|
+
log.info(`Pages: ${report.pageCount}`);
|
|
82
|
+
log.info(`Edges: ${report.edgeCount}`);
|
|
83
|
+
log.info(
|
|
84
|
+
`Dangling links: ${
|
|
85
|
+
report.danglingLinks.length === 0 ? "none" : report.danglingLinks.length
|
|
86
|
+
}`,
|
|
87
|
+
);
|
|
88
|
+
for (const d of report.danglingLinks) {
|
|
89
|
+
log.info(` - ${d.from} → ${d.to} (${d.kind})`);
|
|
90
|
+
}
|
|
91
|
+
log.info(
|
|
92
|
+
`Oversized pages: ${
|
|
93
|
+
report.oversizedPages.length === 0 ? "none" : report.oversizedPages.length
|
|
94
|
+
}`,
|
|
95
|
+
);
|
|
96
|
+
for (const p of report.oversizedPages) {
|
|
97
|
+
log.info(` - ${p.slug}: ${p.chars} chars`);
|
|
98
|
+
}
|
|
99
|
+
log.info(
|
|
100
|
+
`Parse failures: ${
|
|
101
|
+
report.parseFailures.length === 0 ? "none" : report.parseFailures.length
|
|
102
|
+
}`,
|
|
103
|
+
);
|
|
104
|
+
for (const p of report.parseFailures) {
|
|
105
|
+
log.info(` - ${p.slug}: ${p.error}`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (
|
|
109
|
+
report.danglingLinks.length > 0 ||
|
|
110
|
+
report.oversizedPages.length > 0 ||
|
|
111
|
+
report.parseFailures.length > 0
|
|
112
|
+
) {
|
|
113
|
+
process.exitCode = 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
62
117
|
// ---------------------------------------------------------------------------
|
|
63
118
|
// Registration
|
|
64
119
|
// ---------------------------------------------------------------------------
|
|
@@ -97,58 +152,7 @@ export function registerMemoryV2Command(memory: Command): void {
|
|
|
97
152
|
|
|
98
153
|
// ── validate ──────────────────────────────────────────────────────────
|
|
99
154
|
|
|
100
|
-
subcommand(v2, "validate").action(
|
|
101
|
-
const result = await cliIpcCall<MemoryV2ValidateResult>(
|
|
102
|
-
"memory_v2_validate",
|
|
103
|
-
{ body: {} },
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
if (!result.ok) {
|
|
107
|
-
log.error(result.error ?? "Failed to validate memory v2 state");
|
|
108
|
-
process.exitCode = 1;
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const report = result.result!;
|
|
113
|
-
log.info(`Pages: ${report.pageCount}`);
|
|
114
|
-
log.info(`Edges: ${report.edgeCount}`);
|
|
115
|
-
log.info(
|
|
116
|
-
`Missing edge endpoints: ${
|
|
117
|
-
report.missingEdgeEndpoints.length === 0
|
|
118
|
-
? "none"
|
|
119
|
-
: report.missingEdgeEndpoints.length
|
|
120
|
-
}`,
|
|
121
|
-
);
|
|
122
|
-
for (const m of report.missingEdgeEndpoints) {
|
|
123
|
-
log.info(` - ${m.from} → ${m.to}`);
|
|
124
|
-
}
|
|
125
|
-
log.info(
|
|
126
|
-
`Oversized pages: ${
|
|
127
|
-
report.oversizedPages.length === 0
|
|
128
|
-
? "none"
|
|
129
|
-
: report.oversizedPages.length
|
|
130
|
-
}`,
|
|
131
|
-
);
|
|
132
|
-
for (const p of report.oversizedPages) {
|
|
133
|
-
log.info(` - ${p.slug}: ${p.chars} chars`);
|
|
134
|
-
}
|
|
135
|
-
log.info(
|
|
136
|
-
`Parse failures: ${
|
|
137
|
-
report.parseFailures.length === 0 ? "none" : report.parseFailures.length
|
|
138
|
-
}`,
|
|
139
|
-
);
|
|
140
|
-
for (const p of report.parseFailures) {
|
|
141
|
-
log.info(` - ${p.slug}: ${p.error}`);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (
|
|
145
|
-
report.missingEdgeEndpoints.length > 0 ||
|
|
146
|
-
report.oversizedPages.length > 0 ||
|
|
147
|
-
report.parseFailures.length > 0
|
|
148
|
-
) {
|
|
149
|
-
process.exitCode = 1;
|
|
150
|
-
}
|
|
151
|
-
});
|
|
155
|
+
subcommand(v2, "validate").action(runMemoryValidate);
|
|
152
156
|
|
|
153
157
|
// ── ema ───────────────────────────────────────────────────────────────
|
|
154
158
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `assistant memory validate`: the read-only concept-page diagnostic.
|
|
3
|
+
*
|
|
4
|
+
* The report covers the concept-page substrate, which is the same store
|
|
5
|
+
* under memory v2 and v3, so the command is tier-agnostic. The report
|
|
6
|
+
* function lives in `memory-v2.ts` (the host file already allowed to read
|
|
7
|
+
* the memory plugin's route types) and is also registered there as
|
|
8
|
+
* `assistant memory v2 validate` for as long as that namespace exists.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { Command } from "commander";
|
|
12
|
+
|
|
13
|
+
import { subcommand } from "../../lib/cli-command-help.js";
|
|
14
|
+
import { runMemoryValidate } from "./memory-v2.js";
|
|
15
|
+
|
|
16
|
+
export function registerMemoryValidateCommand(memory: Command): void {
|
|
17
|
+
subcommand(memory, "validate").action(runMemoryValidate);
|
|
18
|
+
}
|
|
@@ -10,37 +10,12 @@ import {
|
|
|
10
10
|
|
|
11
11
|
export const pluginsHelp: CliCommandHelp = {
|
|
12
12
|
name: "plugins",
|
|
13
|
-
description:
|
|
14
|
-
"List, search, install, and manage external plugins (`list` shows what is installed, `search` queries the marketplace)",
|
|
13
|
+
description: "List, search, install, and manage plugins.",
|
|
15
14
|
helpText: `
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
$ assistant plugins install https://github.com/owner/repo/tree/main/sub/path --name my-plugin
|
|
21
|
-
$ assistant plugins install example --ref my-feature-branch
|
|
22
|
-
$ assistant plugins versions example
|
|
23
|
-
$ assistant plugins versions example --json
|
|
24
|
-
$ assistant plugins install example --pin <sha> --force
|
|
25
|
-
$ assistant plugins list
|
|
26
|
-
$ assistant plugins list --json
|
|
27
|
-
$ assistant plugins list --all
|
|
28
|
-
$ assistant plugins list --all --json
|
|
29
|
-
$ assistant plugins inspect example
|
|
30
|
-
$ assistant plugins inspect example --json
|
|
31
|
-
$ assistant plugins diff example
|
|
32
|
-
$ assistant plugins diff example --json
|
|
33
|
-
$ assistant plugins upgrade example
|
|
34
|
-
$ assistant plugins upgrade example --dry-run
|
|
35
|
-
$ assistant plugins upgrade example --strategy ours
|
|
36
|
-
$ assistant plugins upgrade example --strategy theirs
|
|
37
|
-
$ assistant plugins upgrade example --strategy assistant
|
|
38
|
-
$ assistant plugins search example
|
|
39
|
-
$ assistant plugins search "^example"
|
|
40
|
-
$ assistant plugins search example --json
|
|
41
|
-
$ assistant plugins uninstall example
|
|
42
|
-
$ assistant plugins enable example
|
|
43
|
-
$ assistant plugins disable example`,
|
|
15
|
+
Plugins are superpowers: installable extensions that add skills, tools, integrations,
|
|
16
|
+
and so much more from the Vellum Community. When the user asks to set up,
|
|
17
|
+
install, connect, or integrate a product, service, or app, run
|
|
18
|
+
'assistant plugins search <name>' first before searching the web.`,
|
|
44
19
|
subcommands: [
|
|
45
20
|
{
|
|
46
21
|
name: "install",
|
|
@@ -79,6 +54,10 @@ during the install, and the install asks for confirmation before finalizing:
|
|
|
79
54
|
schedules run automatically in the background once the plugin is installed.
|
|
80
55
|
Pass --force to skip the prompt (required for non-interactive installs).
|
|
81
56
|
|
|
57
|
+
A plugin that ships a setup skill (skills/setup/ or
|
|
58
|
+
skills/<name>-setup/) prints a line after install telling the user to
|
|
59
|
+
load that skill to finish setup.
|
|
60
|
+
|
|
82
61
|
A GitHub URL (anything containing a slash) installs directly from that repo,
|
|
83
62
|
bypassing the marketplace whitelist. Such a plugin is UNTRUSTED — it has not
|
|
84
63
|
been reviewed and its hooks/tools run with full assistant access — so the
|
|
@@ -168,13 +147,31 @@ Examples:
|
|
|
168
147
|
name: "search",
|
|
169
148
|
args: "<query>",
|
|
170
149
|
description:
|
|
171
|
-
"Search the
|
|
150
|
+
"Search the plugin marketplace. Query is a case-insensitive regex against plugin names",
|
|
172
151
|
options: [
|
|
173
152
|
{
|
|
174
153
|
flags: "--json",
|
|
175
154
|
description: "Emit machine-readable JSON instead of a table",
|
|
176
155
|
},
|
|
177
156
|
],
|
|
157
|
+
helpText: `
|
|
158
|
+
When to use:
|
|
159
|
+
First stop when the user asks to set up, install, connect, or integrate a
|
|
160
|
+
product, service, or app (for example "Setup <app> for me",
|
|
161
|
+
"connect this service"). Search here before searching the web.
|
|
162
|
+
|
|
163
|
+
Arguments:
|
|
164
|
+
query Case-insensitive regex matched against plugin names, not the full
|
|
165
|
+
user sentence. Use the product or plugin name. Anchors like
|
|
166
|
+
^example work.
|
|
167
|
+
|
|
168
|
+
If a match is found, install it with 'assistant plugins install <name>'.
|
|
169
|
+
If nothing matches, try 'assistant skills search <query>', then web search.
|
|
170
|
+
|
|
171
|
+
Examples:
|
|
172
|
+
$ assistant plugins search example
|
|
173
|
+
$ assistant plugins search "^example"
|
|
174
|
+
$ assistant plugins search example --json`,
|
|
178
175
|
},
|
|
179
176
|
{
|
|
180
177
|
name: "publish",
|
|
@@ -301,6 +301,16 @@ export function registerPluginsCommand(program: Command): void {
|
|
|
301
301
|
console.log(
|
|
302
302
|
`Installed ${label} "${result.name}" (${result.fileCount} file${result.fileCount === 1 ? "" : "s"})${pinned} → ${result.target}`,
|
|
303
303
|
);
|
|
304
|
+
const { skills } = libs.surfaces.detectPluginSurfaces(
|
|
305
|
+
result.target,
|
|
306
|
+
);
|
|
307
|
+
const setupSkill = libs.surfaces.findPluginSetupSkill(
|
|
308
|
+
result.name,
|
|
309
|
+
skills,
|
|
310
|
+
);
|
|
311
|
+
if (setupSkill !== undefined) {
|
|
312
|
+
console.log(libs.surfaces.formatPluginSetupHint(setupSkill));
|
|
313
|
+
}
|
|
304
314
|
} catch (err) {
|
|
305
315
|
if (err instanceof libs.installGitHub.PluginInstallDeclinedError) {
|
|
306
316
|
// The consent gate already printed the outcome and set the exit
|
|
@@ -6,21 +6,8 @@ export const skillsHelp: CliCommandHelp = {
|
|
|
6
6
|
name: "skills",
|
|
7
7
|
description: "Browse and install skills from the Vellum catalog",
|
|
8
8
|
helpText: `
|
|
9
|
-
Manage skills from the Vellum catalog. Skills
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
Examples:
|
|
13
|
-
$ assistant skills list
|
|
14
|
-
$ assistant skills list --json
|
|
15
|
-
$ assistant skills inspect slack
|
|
16
|
-
$ assistant skills inspect resend-setup --json
|
|
17
|
-
$ assistant skills search react
|
|
18
|
-
$ assistant skills search react --limit 5 --json
|
|
19
|
-
$ assistant skills install weather
|
|
20
|
-
$ assistant skills install weather --overwrite
|
|
21
|
-
$ assistant skills uninstall weather
|
|
22
|
-
$ assistant skills add vercel-labs/skills@find-skills
|
|
23
|
-
$ assistant skills add vercel-labs/skills/find-skills --overwrite`,
|
|
9
|
+
Manage skills from the Vellum catalog. Skills are instructions of
|
|
10
|
+
workflows and tools that teach the assistant when dynamically relevant.`,
|
|
24
11
|
subcommands: [
|
|
25
12
|
{
|
|
26
13
|
name: "list",
|
|
@@ -70,15 +57,25 @@ Examples:
|
|
|
70
57
|
{ flags: "--json", description: "Machine-readable JSON output" },
|
|
71
58
|
],
|
|
72
59
|
helpText: `
|
|
60
|
+
When to use:
|
|
61
|
+
Second stop after plugin search when the user asks to set up, install, or
|
|
62
|
+
add a capability (for example "Setup <app> for me", "add a skill for file management").
|
|
63
|
+
Search here before searching the web.
|
|
64
|
+
|
|
73
65
|
Arguments:
|
|
74
66
|
query Free-text search term matched against skill names, descriptions,
|
|
75
|
-
and tags.
|
|
67
|
+
and tags. Use the product or capability name, not the full user
|
|
68
|
+
sentence. Searches the Vellum catalog, the skills.sh community
|
|
76
69
|
registry, and the clawhub registry.
|
|
77
70
|
|
|
78
71
|
Displays results from all sources with clear labels. When a skill ID
|
|
79
72
|
exists in both the Vellum catalog and a community registry, a conflict
|
|
80
73
|
note is shown with guidance on which install command to use.
|
|
81
74
|
|
|
75
|
+
If a catalog match is found, install it with 'assistant skills install <id>'.
|
|
76
|
+
If a community match is found, add it with 'assistant skills add <source>'.
|
|
77
|
+
If nothing matches, try web search.
|
|
78
|
+
|
|
82
79
|
Examples:
|
|
83
80
|
$ assistant skills search react
|
|
84
81
|
$ assistant skills search "file management" --limit 3
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* IPC route (`trust_rules_list`).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import type { TrustRulesListIpcResponse } from "@vellumai/gateway-client";
|
|
8
9
|
import type { Command } from "commander";
|
|
9
10
|
|
|
10
11
|
import { cliIpcCall } from "../../ipc/cli-client.js";
|
|
@@ -13,18 +14,6 @@ import { registerCommand } from "../lib/register-command.js";
|
|
|
13
14
|
import { log } from "../logger.js";
|
|
14
15
|
import { trustHelp } from "./trust.help.js";
|
|
15
16
|
|
|
16
|
-
// -- Types --------------------------------------------------------------------
|
|
17
|
-
|
|
18
|
-
interface TrustRule {
|
|
19
|
-
id: string;
|
|
20
|
-
tool: string;
|
|
21
|
-
pattern: string;
|
|
22
|
-
risk: string;
|
|
23
|
-
origin: string;
|
|
24
|
-
userModified: boolean;
|
|
25
|
-
updatedAt: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
17
|
// -- Registration -------------------------------------------------------------
|
|
29
18
|
|
|
30
19
|
export function registerTrustCommand(program: Command): void {
|
|
@@ -44,7 +33,7 @@ export function registerTrustCommand(program: Command): void {
|
|
|
44
33
|
...(opts.tool ? { tool: opts.tool } : {}),
|
|
45
34
|
};
|
|
46
35
|
|
|
47
|
-
const result = await cliIpcCall<
|
|
36
|
+
const result = await cliIpcCall<TrustRulesListIpcResponse>(
|
|
48
37
|
"trust_rules_list",
|
|
49
38
|
{ body: params },
|
|
50
39
|
);
|
|
@@ -86,7 +75,7 @@ export function registerTrustCommand(program: Command): void {
|
|
|
86
75
|
"MODIFIED",
|
|
87
76
|
];
|
|
88
77
|
|
|
89
|
-
const rows: string[][] = rules.map((r
|
|
78
|
+
const rows: string[][] = rules.map((r) => [
|
|
90
79
|
r.id.slice(0, 16),
|
|
91
80
|
r.tool,
|
|
92
81
|
r.pattern,
|
|
@@ -303,6 +303,44 @@ describe("installPlugin — install lifecycle", () => {
|
|
|
303
303
|
expect(existsSync(join(target, "README.md"))).toBe(true);
|
|
304
304
|
});
|
|
305
305
|
|
|
306
|
+
test("--force keeps live config.json instead of a pin-shipped default", async () => {
|
|
307
|
+
// GIVEN an install with user config, and a clone that materializes a default
|
|
308
|
+
const target = join(pluginsDir, "caveman");
|
|
309
|
+
mkdirSync(target, { recursive: true });
|
|
310
|
+
writeFileSync(join(target, "package.json"), '{"name":"caveman"}');
|
|
311
|
+
writeFileSync(
|
|
312
|
+
join(target, "config.json"),
|
|
313
|
+
'{"provider":"photon","ingressMode":"live"}\n',
|
|
314
|
+
);
|
|
315
|
+
mkdirSync(join(target, "data"), { recursive: true });
|
|
316
|
+
writeFileSync(join(target, "data", "cursor.json"), '{"n":1}\n');
|
|
317
|
+
|
|
318
|
+
const fetch = makeContentsFetch({ tree: {}, manifest: CAVEMAN_MANIFEST });
|
|
319
|
+
const runGit = fakeGitRunner({
|
|
320
|
+
tree: {
|
|
321
|
+
"package.json": '{"name":"caveman"}',
|
|
322
|
+
"README.md": "# caveman",
|
|
323
|
+
"config.json": '{"provider":"comms","ingressMode":"webhook"}\n',
|
|
324
|
+
},
|
|
325
|
+
commit: CAVEMAN_SHA,
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// WHEN we reinstall with --force
|
|
329
|
+
await installPlugin(
|
|
330
|
+
{ name: "caveman", force: true, ref: "main" },
|
|
331
|
+
{ fetch, runGit, workspacePluginsDir: pluginsDir },
|
|
332
|
+
);
|
|
333
|
+
|
|
334
|
+
// THEN user-owned state survives and the pin's default config does not win
|
|
335
|
+
expect(readFileSync(join(target, "config.json"), "utf-8")).toBe(
|
|
336
|
+
'{"provider":"photon","ingressMode":"live"}\n',
|
|
337
|
+
);
|
|
338
|
+
expect(readFileSync(join(target, "data", "cursor.json"), "utf-8")).toBe(
|
|
339
|
+
'{"n":1}\n',
|
|
340
|
+
);
|
|
341
|
+
expect(existsSync(join(target, "README.md"))).toBe(true);
|
|
342
|
+
});
|
|
343
|
+
|
|
306
344
|
test("commitOverride materializes a specific commit, keeping repo from the manifest", async () => {
|
|
307
345
|
// GIVEN a manifest pinning the current SHA, but an override to an older one
|
|
308
346
|
const OLD_SHA = "1".repeat(40);
|